57 else if (
base == LPC_CAN2)
67 NVIC_DisableIRQ(CAN_IRQn);
72 NVIC_SetPriority(CAN_IRQn, configKERNEL_INTERRUPT_PRIORITY);
79 Chip_CAN_Init(
base, LPC_CANAF, LPC_CANAF_RAM);
82 Chip_CAN_SetBitRate(
base, config_nmranet_can_bitrate());
84 else if (
base == LPC_CAN1)
86 Chip_CAN_SetBitRate(
base, config_can2_bitrate());
90 DIE(
"Unknown CAN base address.");
92 Chip_CAN_SetAFMode(LPC_CANAF, CAN_AF_BYBASS_MODE);
93 Chip_CAN_EnableInt(
base, CAN_IER_BITMASK &
94 ~(CAN_IER_TIE2 | CAN_IER_TIE3 | CAN_ICR_IDI));
98 NVIC_EnableIRQ(CAN_IRQn);
108 NVIC_DisableIRQ(CAN_IRQn);
110 Chip_CAN_DisableInt(
base, CAN_IER_BITMASK &
111 ~(CAN_IER_TIE2 | CAN_IER_TIE3 | CAN_ICR_IDI));
112 Chip_CAN_DeInit(
base);
119 if (Chip_CAN_GetStatus(
base) & CAN_SR_TBS(0))
121 struct can_frame *can_frame;
132 if (can_frame->can_eff)
134 base->TX[0].TFI |= CAN_TFI_FF;
135 base->TX[0].TID = CAN_TID_ID29(can_frame->can_id);
139 base->TX[0].TID = CAN_TID_ID11(can_frame->can_id);
141 if (can_frame->can_rtr)
143 base->TX[0].TFI |= CAN_TFI_RTR;
147 base->TX[0].TFI |= CAN_TFI_DLC(can_frame->can_dlc);
148 for (
unsigned i = 0; i < (CAN_MSG_MAX_DATA_LEN + 3) / 4; ++i)
150 base->TX[0].TD[i] = (can_frame->data[4 * i + 0] << 0) |
151 (can_frame->data[4 * i + 1] << 8) |
152 (can_frame->data[4 * i + 2] << 16) |
153 (can_frame->data[4 * i + 3] << 24);
157 Chip_CAN_SetCmd(
base, CAN_CMR_STB(0) | CAN_CMR_TR);
169 if (status & CAN_ICR_EI)
173 Chip_CAN_SetCmd(
base, CAN_CMR_TR);
177 if (status & CAN_ICR_DOI)
182 if (status & CAN_ICR_WUI)
186 if (status & CAN_ICR_EPI)
190 if (status & CAN_ICR_ALI)
194 if (status & CAN_ICR_BEI)
199 Chip_CAN_SetCmd(
base, CAN_CMR_TR);
203 Chip_CAN_SetMode(
base, CAN_RESET_MODE, DISABLE);
205 if (status & CAN_ICR_IDI)
209 if (status & CAN_ICR_RI)
212 struct can_frame *can_frame;
215 if (
base->SR & CAN_SR_RBS(0))
217 can_frame->can_id = (
base->RX.RFS & CAN_RFS_FF) ?
218 CAN_RID_ID_29(
base->RX.RID) :
219 CAN_RID_ID_11(
base->RX.RID);
220 can_frame->can_rtr = (
base->RX.RFS & CAN_RFS_RTR) ? 1 : 0;
221 can_frame->can_err = 0;
222 if (
base->RX.RFS & CAN_RFS_FF)
224 can_frame->can_eff = 1;
225 can_frame->can_id = CAN_RID_ID_29(
base->RX.RID);
229 can_frame->can_eff = 0;
230 can_frame->can_id = CAN_RID_ID_11(
base->RX.RID);
232 can_frame->can_dlc = CAN_RFS_DLC(
base->RX.RFS);
233 if (
base->RX.RFS & CAN_RFS_RTR)
235 can_frame->can_rtr = 1;
239 can_frame->can_rtr = 0;
240 can_frame->data[0] = (
base->RX.RD[0] >> 0) & 0xFF;
241 can_frame->data[1] = (
base->RX.RD[0] >> 8) & 0xFF;
242 can_frame->data[2] = (
base->RX.RD[0] >> 16) & 0xFF;
243 can_frame->data[3] = (
base->RX.RD[0] >> 24) & 0xFF;
244 can_frame->data[4] = (
base->RX.RD[1] >> 0) & 0xFF;
245 can_frame->data[5] = (
base->RX.RD[1] >> 8) & 0xFF;
246 can_frame->data[6] = (
base->RX.RD[1] >> 16) & 0xFF;
247 can_frame->data[7] = (
base->RX.RD[1] >> 24) & 0xFF;
249 Chip_CAN_SetCmd(
base, CAN_CMR_RRB);
267 Chip_CAN_SetCmd(
base, CAN_CMR_RRB);
270 if (status & CAN_ICR_TI1)
272 struct can_frame *can_frame;
283 if (can_frame->can_eff)
285 base->TX[0].TFI |= CAN_TFI_FF;
286 base->TX[0].TID = CAN_TID_ID29(can_frame->can_id);
290 base->TX[0].TID = CAN_TID_ID11(can_frame->can_id);
292 if (can_frame->can_rtr)
294 base->TX[0].TFI |= CAN_TFI_RTR;
298 base->TX[0].TFI |= CAN_TFI_DLC(can_frame->can_dlc);
299 for (
unsigned i = 0; i < (CAN_MSG_MAX_DATA_LEN + 3) / 4; ++i)
301 base->TX[0].TD[i] = (can_frame->data[4 * i + 0] << 0) |
302 (can_frame->data[4 * i + 1] << 8) |
303 (can_frame->data[4 * i + 2] << 16) |
304 (can_frame->data[4 * i + 3] << 24);
308 Chip_CAN_SetCmd(
base, CAN_CMR_STB(0) | CAN_CMR_TR);
void can_interrupt_handler(void)
This is the interrupt handler for the can device(s).
Base class for a CAN device for the Arduino environment.
unsigned int overrunCount
overrun count
unsigned int softErrorCount
soft error count
DeviceBuffer< struct can_frame > * txBuf
transmit buffer
unsigned int busOffCount
bus-off count
DeviceBuffer< struct can_frame > * rxBuf
receive buffer
void flush()
flush all the data out of the buffer and reset the buffer.
size_t advance(size_t items)
Add a number of items to the buffer by advancing the writeIndex.
void signal_condition()
Signal the wakeup condition.
size_t consume(size_t items)
Remove a number of items from the buffer by advancing the readIndex.
void signal_condition_from_isr()
Signal the wakeup condition from an ISR context.
size_t data_write_pointer(T **buf)
Get a reference to the current location in the buffer for write.
size_t data_read_pointer(T **buf)
Get a reference to the current location in the buffer for read.
Specialization of CAN driver for LPC17xx and LPC40xx CAN.
void enable() override
function to enable device
void disable() override
function to disable device
static unsigned int intCount
one interrupt vector is shared between two CAN controllers, so we need to keep track of the number of...
static void interrupt_handler()
Translate an interrupt handler into C++ object context.
void tx_msg() override
function to try and transmit a message
static LpcCan * instances[2]
Instance pointers help us get context from the interrupt handler(s)
LPC_CAN_T * base
base address of this device
LpcCan()
Default constructor.
Notifiable * readableNotify_
This will be notified if the device has data avilable for read.
Notifiable * writableNotify_
This will be notified if the device has buffer avilable for write.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
#define DIE(MSG)
Unconditionally terminates the current process with a message.