37#include "11CXX_rom_driver_CAN.h"
45 const unsigned p_usbd;
46 const unsigned p_clib;
51const ROM *
const *
const rom = (ROM **)0x1fff1ff8;
57#define FIRST_RX_OBJ 16
63CanPipeMember *g_tx_instance =
nullptr;
64CanRxFlow *g_rx_instance =
nullptr;
72 , freeTxBuffers_(0xFFFFFFFF)
73 , frameToWrite_(nullptr)
82 frameToWrite_ = message()->data()->mutable_frame();
83 return call_immediately(
STATE(try_send));
89 const struct can_frame *frame =
nullptr;
90 uint8_t buf_num = FIRST_TX_OBJ;
95 while (buf_num < FIRST_RX_OBJ &&
96 (!(freeTxBuffers_ & (1 << buf_num))))
100 if (buf_num >= FIRST_RX_OBJ)
107 freeTxBuffers_ &= ~(1 << buf_num);
110 frame = frameToWrite_;
111 frameToWrite_ =
nullptr;
115 msg_obj.
mode_id = frame->can_id |
116 (frame->can_rtr ? CAN_MSGOBJ_RTR : 0) |
117 (frame->can_eff ? CAN_MSGOBJ_EXT : 0);
119 msg_obj.
dlc = frame->can_dlc;
120 memcpy(msg_obj.
data, frame->data, frame->can_dlc);
121 (*rom)->pCAND->can_transmit(&msg_obj);
124 return release_and_exit();
127 void TxFinishedFromIsr(uint8_t buf_num)
129 HASSERT(!(freeTxBuffers_ & (1 << buf_num)));
130 freeTxBuffers_ |= (1 << buf_num);
131 if (frameToWrite_ && bufferFull_)
134 service()->executor()->add_from_isr(
this, priority());
139 uint32_t freeTxBuffers_;
140 const struct can_frame *frameToWrite_;
142 unsigned bufferFull_ : 1;
156 msg_obj.
msgobj = FIRST_RX_OBJ;
157 msg_obj.
mode_id = 0x000 | CAN_MSGOBJ_EXT;
158 msg_obj.
mask = 0x000;
160 (*rom)->pCAND->config_rxmsgobj(&msg_obj);
161 start_flow(
STATE(wait_or_copy));
166 void isr(uint8_t buf_num)
182 service()->executor()->add_from_isr(
this, 0);
186 Action wait_or_copy()
196 return allocate_and_call(g_pipe,
STATE(allocation_complete));
200 Action allocation_complete()
203 auto *b = get_allocation_result(g_pipe);
206 copy_hardware_frame(FIRST_RX_OBJ, b->data()->mutable_frame());
208 b->data()->skipMember_ = g_tx_instance;
210 return call_immediately(
STATE(wait_or_copy));
216 void copy_hardware_frame(uint8_t buf_num,
struct can_frame* frame)
224 (*rom)->pCAND->can_receive(&msg_obj);
231 frame->can_id = msg_obj.
mode_id & ((1 << 29) - 1);
234 frame->can_rtr = (msg_obj.
mode_id & CAN_MSGOBJ_RTR) ? 1 : 0;
235 frame->can_eff = (msg_obj.
mode_id & CAN_MSGOBJ_EXT) ? 1 : 0;
237 frame->can_dlc = msg_obj.
dlc;
238 memcpy(frame->data, msg_obj.
data, msg_obj.
dlc);
242 unsigned bufFull_ : 1;
245 unsigned rxPending_ : 1;
247 unsigned frameLost_ : 1;
253void CAN_rx(uint8_t msg_obj_num)
256 g_rx_instance->isr(msg_obj_num);
264void CAN_tx(uint8_t msg_obj_num)
267 g_tx_instance->TxFinishedFromIsr(msg_obj_num);
275void CAN_error(uint32_t error_info)
281static const CAN_CALLBACKS callbacks = {CAN_rx, CAN_tx, CAN_error, NULL,
282 NULL, NULL, NULL, NULL, };
285static const uint32_t ClkInitTable125[2] = {0x00000000UL,
290static const uint32_t ClkInitTable250[2] = {0x00000000UL,
296 if (config_nmranet_can_bitrate() == 250000) {
298 (*rom)->pCAND->init_can((uint32_t *)&ClkInitTable250[0], 1);
299 }
else if ((config_nmranet_can_bitrate() == 125000)) {
301 (*rom)->pCAND->init_can((uint32_t *)&ClkInitTable125[0], 1);
303 DIE(
"Unknown can bitrate.");
309 g_rx_instance =
new CanRxFlow(parent->
service());
310 g_tx_instance =
new CanPipeMember(parent->
service());
314 NVIC_SetPriority(CAN_IRQn, 1);
315 NVIC_EnableIRQ(CAN_IRQn);
323void CAN_IRQHandler(
void)
325 (*rom)->pCAND->isr();
330#error You need to define TARGET_LPC11Cxx if you want to compiple its rom driver.
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
See OSMutexLock in os/OS.hxx.
Lightweight locking class for protecting small critical sections.
void register_port(port_type *port)
Adds a new port.
Collection of related state machines that pend on incoming messages.
Base class for state machines.
Service * service()
Return a pointer to the service I am bound to.
State flow with a given typed input queue.
void send(MessageType *msg, unsigned priority=UINT_MAX) OVERRIDE
Sends a message to the state flow for processing.
#define OVERRIDE
Function attribute for virtual functions declaring that this funciton is overriding a funciton that s...
#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.
All API functions of the ROM can driver.
Specifies the callbacks from the CAN stack to the application.