run clang-format

This commit is contained in:
Jeff Epler 2020-10-07 14:31:34 -05:00
parent 648fdba3a1
commit 99f5886fd1
2 changed files with 210 additions and 212 deletions

View file

@ -29,13 +29,13 @@
#include "Adafruit_ZeroCAN.h"
#include "wiring_private.h"
#include "same51.h"
#define hw (reinterpret_cast<Can*>(this->_hw))
#define hw (reinterpret_cast<Can *>(this->_hw))
#define DIV_ROUND(a, b) (((a) + (b)/2) / (b))
#define DIV_ROUND_UP(a, b) (((a) + (b) - 1) / (b))
#define DIV_ROUND(a, b) (((a) + (b) / 2) / (b))
#define DIV_ROUND_UP(a, b) (((a) + (b)-1) / (b))
#define GCLK_CAN1 GCLK_PCHCTRL_GEN_GCLK1_Val
#define ADAFRUIT_ZEROCAN_TX_BUFFER_SIZE (1)
@ -52,53 +52,52 @@ typedef CanMramXifde CanMramXidfe;
typedef uint32_t can_filter_t;
struct _adafruit_ZeroCAN_tx_buf {
CAN_TXBE_0_Type txb0;
CAN_TXBE_1_Type txb1;
__attribute__((aligned(4)))
uint8_t data[8];
CAN_TXBE_0_Type txb0;
CAN_TXBE_1_Type txb1;
__attribute__((aligned(4))) uint8_t data[8];
};
struct _adafruit_ZeroCAN_rx_fifo {
CAN_RXF0E_0_Type rxf0;
CAN_RXF0E_1_Type rxf1;
__attribute((aligned(4)))
uint8_t data[ADAFRUIT_ZEROCAN_MAX_MESSAGE_LENGTH];
CAN_RXF0E_0_Type rxf0;
CAN_RXF0E_1_Type rxf1;
__attribute((aligned(4))) uint8_t data[ADAFRUIT_ZEROCAN_MAX_MESSAGE_LENGTH];
} can_rx_fifo_t;
struct _adafruit_ZeroCAN_state {
_adafruit_ZeroCAN_tx_buf tx_buffer[ADAFRUIT_ZEROCAN_TX_BUFFER_SIZE];
_adafruit_ZeroCAN_rx_fifo rx0_fifo[ADAFRUIT_ZEROCAN_RX_FIFO_SIZE];
_adafruit_ZeroCAN_rx_fifo rx1_fifo[ADAFRUIT_ZEROCAN_RX_FIFO_SIZE];
CanMramSidfe standard_rx_filter[ADAFRUIT_ZEROCAN_RX_FILTER_SIZE];
CanMramXifde extended_rx_filter[ADAFRUIT_ZEROCAN_RX_FILTER_SIZE];
_adafruit_ZeroCAN_tx_buf tx_buffer[ADAFRUIT_ZEROCAN_TX_BUFFER_SIZE];
_adafruit_ZeroCAN_rx_fifo rx0_fifo[ADAFRUIT_ZEROCAN_RX_FIFO_SIZE];
_adafruit_ZeroCAN_rx_fifo rx1_fifo[ADAFRUIT_ZEROCAN_RX_FIFO_SIZE];
CanMramSidfe standard_rx_filter[ADAFRUIT_ZEROCAN_RX_FILTER_SIZE];
CanMramXifde extended_rx_filter[ADAFRUIT_ZEROCAN_RX_FILTER_SIZE];
};
namespace {
// This data must be in the first 64kB of RAM. The "canram" section
// receives special support from the linker file in the Feather M4 CAN's
// board support package.
// TODO support CAN0 and CAN1 simultaneously (state would be an array of 2)
__attribute__((section("canram")))
_adafruit_ZeroCAN_state can_state;
// This data must be in the first 64kB of RAM. The "canram" section
// receives special support from the linker file in the Feather M4 CAN's
// board support package.
// TODO support CAN0 and CAN1 simultaneously (state would be an array of 2)
__attribute__((section("canram"))) _adafruit_ZeroCAN_state can_state;
constexpr uint32_t can_frequency = VARIANT_GCLK1_FREQ;
bool compute_nbtp(uint32_t baudrate, CAN_NBTP_Type &result) {
uint32_t clocks_per_bit = DIV_ROUND(can_frequency, baudrate);
uint32_t clocks_to_sample = DIV_ROUND(clocks_per_bit * 7, 8);
uint32_t clocks_after_sample = clocks_per_bit - clocks_to_sample;
uint32_t divisor = std::max(DIV_ROUND_UP(clocks_to_sample, 256), DIV_ROUND_UP(clocks_after_sample, 128));
if (divisor > 32) {
return false;
}
result.bit.NTSEG1 = DIV_ROUND(clocks_to_sample, divisor) - 2;
result.bit.NTSEG2 = DIV_ROUND(clocks_after_sample, divisor) - 2;
result.bit.NBRP = divisor - 1;
result.bit.NSJW = DIV_ROUND(clocks_after_sample, divisor * 4);
return true;
}
constexpr uint32_t can_frequency = VARIANT_GCLK1_FREQ;
bool compute_nbtp(uint32_t baudrate, CAN_NBTP_Type &result) {
uint32_t clocks_per_bit = DIV_ROUND(can_frequency, baudrate);
uint32_t clocks_to_sample = DIV_ROUND(clocks_per_bit * 7, 8);
uint32_t clocks_after_sample = clocks_per_bit - clocks_to_sample;
uint32_t divisor = std::max(DIV_ROUND_UP(clocks_to_sample, 256),
DIV_ROUND_UP(clocks_after_sample, 128));
if (divisor > 32) {
return false;
}
result.bit.NTSEG1 = DIV_ROUND(clocks_to_sample, divisor) - 2;
result.bit.NTSEG2 = DIV_ROUND(clocks_after_sample, divisor) - 2;
result.bit.NBRP = divisor - 1;
result.bit.NSJW = DIV_ROUND(clocks_after_sample, divisor * 4);
return true;
}
} // namespace
Adafruit_ZeroCAN::Adafruit_ZeroCAN(uint8_t TX_PIN, uint8_t RX_PIN) : _tx(TX_PIN), _rx(RX_PIN) {}
Adafruit_ZeroCAN::Adafruit_ZeroCAN(uint8_t TX_PIN, uint8_t RX_PIN)
: _tx(TX_PIN), _rx(RX_PIN) {}
#ifdef PIN_CAN_TX
Adafruit_ZeroCAN::Adafruit_ZeroCAN() : _tx(PIN_CAN_TX), _rx(PIN_CAN_RX) {}
#else
@ -106,168 +105,170 @@ Adafruit_ZeroCAN::Adafruit_ZeroCAN() : _tx(-1) {}
#endif
bool Adafruit_ZeroCAN::begin(int baudrate, bool loopback, bool silent) {
if (_tx == -1) {
return false;
}
CAN_NBTP_Type nbtp;
if (!compute_nbtp(baudrate, nbtp)) {
return false;
}
if (_tx == -1) {
return false;
}
// TODO: Support the CAN0 peripheral, which uses pinmux 8
_hw = reinterpret_cast<void*>(CAN1);
state = &can_state;
memset(state, 0, sizeof(*state));
CAN_NBTP_Type nbtp;
if (!compute_nbtp(baudrate, nbtp)) {
return false;
}
pinPeripheral(_tx, CAN1_FUNCTION);
pinPeripheral(_rx, CAN1_FUNCTION);
// TODO: Support the CAN0 peripheral, which uses pinmux 8
_hw = reinterpret_cast<void *>(CAN1);
state = &can_state;
memset(state, 0, sizeof(*state));
GCLK->PCHCTRL[CAN1_GCLK_ID].reg = GCLK_CAN1 | (1 << GCLK_PCHCTRL_CHEN_Pos);
pinPeripheral(_tx, CAN1_FUNCTION);
pinPeripheral(_rx, CAN1_FUNCTION);
// reset and allow configuration change
hw->CCCR.bit.INIT = 1;
while (!hw->CCCR.bit.INIT) {
}
hw->CCCR.bit.CCE = 1;
// set loopback and silent modes
hw->CCCR.bit.MON = silent;
hw->CCCR.bit.TEST = loopback;
hw->TEST.bit.LBCK = loopback;
GCLK->PCHCTRL[CAN1_GCLK_ID].reg = GCLK_CAN1 | (1 << GCLK_PCHCTRL_CHEN_Pos);
// All TX data has an 8 byte payload (max)
{
CAN_TXESC_Type esc = {};
esc.bit.TBDS = CAN_TXESC_TBDS_DATA8_Val;
CAN1->TXESC.reg = esc.reg;
}
// reset and allow configuration change
hw->CCCR.bit.INIT = 1;
while (!hw->CCCR.bit.INIT) {
}
hw->CCCR.bit.CCE = 1;
// Set up TX buffer
{
CAN_TXBC_Type bc = {};
bc.bit.TBSA = (uint32_t)state->tx_buffer;
bc.bit.NDTB = ADAFRUIT_ZEROCAN_TX_BUFFER_SIZE;
bc.bit.TFQM = 0; // Messages are transmitted in the order submitted
CAN1->TXBC.reg = bc.reg;
}
// set loopback and silent modes
hw->CCCR.bit.MON = silent;
hw->CCCR.bit.TEST = loopback;
hw->TEST.bit.LBCK = loopback;
// All RX data has an 8 byte payload (max)
{
CAN_RXESC_Type esc = {};
esc.bit.F0DS = CAN_RXESC_F0DS_DATA8_Val;
esc.bit.F1DS = CAN_RXESC_F1DS_DATA8_Val;
esc.bit.RBDS = CAN_RXESC_RBDS_DATA8_Val;
hw->RXESC.reg = esc.reg;
}
// All TX data has an 8 byte payload (max)
{
CAN_TXESC_Type esc = {};
esc.bit.TBDS = CAN_TXESC_TBDS_DATA8_Val;
CAN1->TXESC.reg = esc.reg;
}
// Set up RX fifo 0
{
CAN_RXF0C_Type rxf = {};
rxf.bit.F0SA = (uint32_t)state->rx0_fifo;
rxf.bit.F0S = ADAFRUIT_ZEROCAN_RX_FIFO_SIZE;
hw->RXF0C.reg = rxf.reg;
}
// Set up TX buffer
{
CAN_TXBC_Type bc = {};
bc.bit.TBSA = (uint32_t)state->tx_buffer;
bc.bit.NDTB = ADAFRUIT_ZEROCAN_TX_BUFFER_SIZE;
bc.bit.TFQM = 0; // Messages are transmitted in the order submitted
CAN1->TXBC.reg = bc.reg;
}
// Set up RX fifo 1
{
CAN_RXF1C_Type rxf = {};
rxf.bit.F1SA = (uint32_t)state->rx1_fifo;
rxf.bit.F1S = ADAFRUIT_ZEROCAN_RX_FIFO_SIZE;
hw->RXF1C.reg = rxf.reg;
}
// All RX data has an 8 byte payload (max)
{
CAN_RXESC_Type esc = {};
esc.bit.F0DS = CAN_RXESC_F0DS_DATA8_Val;
esc.bit.F1DS = CAN_RXESC_F1DS_DATA8_Val;
esc.bit.RBDS = CAN_RXESC_RBDS_DATA8_Val;
hw->RXESC.reg = esc.reg;
}
// Reject all packets not explicitly requested
{
CAN_GFC_Type gfc = {};
gfc.bit.RRFE = 0;
gfc.bit.ANFS = CAN_GFC_ANFS_REJECT_Val;
gfc.bit.ANFE = CAN_GFC_ANFE_REJECT_Val;
hw->GFC.reg = gfc.reg;
}
// Set up RX fifo 0
{
CAN_RXF0C_Type rxf = {};
rxf.bit.F0SA = (uint32_t)state->rx0_fifo;
rxf.bit.F0S = ADAFRUIT_ZEROCAN_RX_FIFO_SIZE;
hw->RXF0C.reg = rxf.reg;
}
// Set up standard RX filters
{
CAN_SIDFC_Type dfc = {};
dfc.bit.LSS = ADAFRUIT_ZEROCAN_RX_FILTER_SIZE;
dfc.bit.FLSSA = (uint32_t)state->standard_rx_filter;
hw->SIDFC.reg = dfc.reg;
}
// Set up RX fifo 1
{
CAN_RXF1C_Type rxf = {};
rxf.bit.F1SA = (uint32_t)state->rx1_fifo;
rxf.bit.F1S = ADAFRUIT_ZEROCAN_RX_FIFO_SIZE;
hw->RXF1C.reg = rxf.reg;
}
// Set up extended RX filters
{
CAN_XIDFC_Type dfc = {};
dfc.bit.LSE = ADAFRUIT_ZEROCAN_RX_FILTER_SIZE;
dfc.bit.FLESA = (uint32_t)state->extended_rx_filter;
hw->XIDFC.reg = dfc.reg;
}
// Reject all packets not explicitly requested
{
CAN_GFC_Type gfc = {};
gfc.bit.RRFE = 0;
gfc.bit.ANFS = CAN_GFC_ANFS_REJECT_Val;
gfc.bit.ANFE = CAN_GFC_ANFE_REJECT_Val;
hw->GFC.reg = gfc.reg;
}
// Set nominal baud rate
hw->NBTP.reg = nbtp.reg;
// Set up standard RX filters
{
CAN_SIDFC_Type dfc = {};
dfc.bit.LSS = ADAFRUIT_ZEROCAN_RX_FILTER_SIZE;
dfc.bit.FLSSA = (uint32_t)state->standard_rx_filter;
hw->SIDFC.reg = dfc.reg;
}
// hardware is ready for use
CAN1->CCCR.bit.CCE = 0;
CAN1->CCCR.bit.INIT = 0;
while(CAN1->CCCR.bit.INIT) {
}
// Set up extended RX filters
{
CAN_XIDFC_Type dfc = {};
dfc.bit.LSE = ADAFRUIT_ZEROCAN_RX_FILTER_SIZE;
dfc.bit.FLESA = (uint32_t)state->extended_rx_filter;
hw->XIDFC.reg = dfc.reg;
}
return true;
// Set nominal baud rate
hw->NBTP.reg = nbtp.reg;
// hardware is ready for use
CAN1->CCCR.bit.CCE = 0;
CAN1->CCCR.bit.INIT = 0;
while (CAN1->CCCR.bit.INIT) {
}
return true;
}
int Adafruit_ZeroCAN::transmitErrorCount() const {
return hw->ECR.bit.TEC;
}
int Adafruit_ZeroCAN::transmitErrorCount() const { return hw->ECR.bit.TEC; }
int Adafruit_ZeroCAN::receiveErrorCount() const {
return hw->ECR.bit.REC;
}
int Adafruit_ZeroCAN::receiveErrorCount() const { return hw->ECR.bit.REC; }
Adafruit_ZeroCAN::BusState Adafruit_ZeroCAN::busState() const {
CAN_PSR_Type psr;
psr.reg = hw->PSR.reg;
CAN_PSR_Type psr;
psr.reg = hw->PSR.reg;
if (psr.bit.BO) { return BUS_OFF; }
if (psr.bit.EP) { return ERROR_PASSIVE; }
if (psr.bit.EW) { return ERROR_WARNING; }
return ERROR_ACTIVE;
if (psr.bit.BO) {
return BUS_OFF;
}
if (psr.bit.EP) {
return ERROR_PASSIVE;
}
if (psr.bit.EW) {
return ERROR_WARNING;
}
return ERROR_ACTIVE;
}
bool Adafruit_ZeroCAN::send(const Message &m) {
_adafruit_ZeroCAN_tx_buf &buf = state->tx_buffer[0];
buf.txb0.bit.ESI = false;
buf.txb0.bit.XTD = m.extended;
buf.txb0.bit.RTR = m.rtr;
if(m.extended) {
buf.txb0.bit.ID = m.id;
} else {
buf.txb0.bit.ID = m.id << 18;
_adafruit_ZeroCAN_tx_buf &buf = state->tx_buffer[0];
buf.txb0.bit.ESI = false;
buf.txb0.bit.XTD = m.extended;
buf.txb0.bit.RTR = m.rtr;
if (m.extended) {
buf.txb0.bit.ID = m.id;
} else {
buf.txb0.bit.ID = m.id << 18;
}
buf.txb1.bit.MM = 0;
buf.txb1.bit.EFC = 0;
buf.txb1.bit.FDF = 0;
buf.txb1.bit.BRS = 0;
buf.txb1.bit.DLC = m.size;
if (!m.rtr) {
memcpy(buf.data, m.data, sizeof(m.data));
}
// TX buffer add request
hw->TXBAR.reg = 1;
// wait 8ms (hard coded for now) for TX to occur
for (int i = 0; i < 8000; i++) {
if (hw->TXBTO.reg & 1) {
return true;
}
buf.txb1.bit.MM = 0;
buf.txb1.bit.EFC = 0;
buf.txb1.bit.FDF = 0;
buf.txb1.bit.BRS = 0;
buf.txb1.bit.DLC = m.size;
delayMicroseconds(1);
}
if (!m.rtr) {
memcpy(buf.data, m.data, sizeof(m.data));
}
// TX buffer add request
hw->TXBAR.reg = 1;
// wait 8ms (hard coded for now) for TX to occur
for (int i=0; i<8000; i++) {
if(hw->TXBTO.reg & 1) {
return true;
}
delayMicroseconds(1);
}
return false;
return false;
}
void Adafruit_ZeroCAN::restart() {
hw->CCCR.bit.INIT = 0;
while(hw->CCCR.bit.INIT) {
}
hw->CCCR.bit.INIT = 0;
while (hw->CCCR.bit.INIT) {
}
}

View file

@ -21,50 +21,47 @@ struct _adafruit_ZeroCAN_state;
class Adafruit_ZeroCAN {
public:
enum BusState {
ERROR_ACTIVE, ERROR_WARNING, ERROR_PASSIVE, BUS_OFF
};
enum BusState { ERROR_ACTIVE, ERROR_WARNING, ERROR_PASSIVE, BUS_OFF };
struct Message {
uint32_t id;
bool extended;
bool rtr;
uint8_t size;
uint8_t data[8];
};
struct Message {
uint32_t id;
bool extended;
bool rtr;
uint8_t size;
uint8_t data[8];
};
struct Match {
uint32_t id;
uint32_t mask;
bool extended;
};
struct Match {
uint32_t id;
uint32_t mask;
bool extended;
};
class Listener {
public:
Listener();
bool begin(Adafruit_ZeroCAN &can, Match *matches, size_t nmatch);
~Listener();
bool in_waiting() const;
bool read(Message &);
};
class Listener {
public:
Listener();
bool begin(Adafruit_ZeroCAN &can, Match *matches, size_t nmatch);
~Listener();
bool in_waiting() const;
bool read(Message &);
};
Adafruit_ZeroCAN(uint8_t TX_PIN, uint8_t RX_PIN);
Adafruit_ZeroCAN();
~Adafruit_ZeroCAN() {}
bool begin(int baudrate, bool loopback, bool silent);
Adafruit_ZeroCAN(uint8_t TX_PIN, uint8_t RX_PIN);
Adafruit_ZeroCAN();
~Adafruit_ZeroCAN() {}
int transmitErrorCount() const;
int receiveErrorCount() const;
BusState busState() const;
bool begin(int baudrate, bool loopback, bool silent);
bool send(const Message &m);
void restart();
int transmitErrorCount() const;
int receiveErrorCount() const;
BusState busState() const;
bool send(const Message &m);
void restart();
private:
struct State;
int8_t _tx, _rx;
void *_hw;
_adafruit_ZeroCAN_state *state;
struct State;
int8_t _tx, _rx;
void *_hw;
_adafruit_ZeroCAN_state *state;
};