run clang-format
This commit is contained in:
parent
648fdba3a1
commit
99f5886fd1
2 changed files with 210 additions and 212 deletions
|
|
@ -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) {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue