29 #ifndef UAVCAN_NODE_ID
30 #define UAVCAN_NODE_ID 100
33 #ifndef UAVCAN_BAUDRATE
34 #define UAVCAN_BAUDRATE 1000000
40 #ifndef UAVCAN_CAN1_NODE_ID
41 #define UAVCAN_CAN1_NODE_ID UAVCAN_NODE_ID
44 #ifndef UAVCAN_CAN1_BAUDRATE
45 #define UAVCAN_CAN1_BAUDRATE UAVCAN_BAUDRATE
53 .can_baudrate = UAVCAN_CAN1_BAUDRATE,
55 .thread_rx_wa = uavcan1_rx_wa,
56 .thread_rx_wa_size =
sizeof(uavcan1_rx_wa),
59 .node_id = UAVCAN_CAN1_NODE_ID,
66 #ifndef UAVCAN_CAN2_NODE_ID
67 #define UAVCAN_CAN2_NODE_ID UAVCAN_NODE_ID
70 #ifndef UAVCAN_CAN2_BAUDRATE
71 #define UAVCAN_CAN2_BAUDRATE UAVCAN_BAUDRATE
79 .can_baudrate = UAVCAN_CAN2_BAUDRATE,
81 .thread_rx_wa = uavcan2_rx_wa,
82 .thread_rx_wa_size =
sizeof(uavcan2_rx_wa),
85 .node_id = UAVCAN_CAN2_NODE_ID,
98 CanardCANFrame rx_frame;
101 chRegSetThreadName(
"uavcan_rx");
102 chEvtRegister(&iface->
can_driver->rxfull_event, &el, EVENT_MASK(0));
104 if (chEvtWaitAnyTimeout(ALL_EVENTS, TIME_MS2I(100)) == 0) {
107 chMtxLock(&iface->
mutex);
110 while (canReceive(iface->
can_driver, CAN_ANY_MAILBOX, &rx_msg, TIME_IMMEDIATE) == MSG_OK) {
112 const uint32_t timestamp = TIME_I2US(chVTGetSystemTimeX());
113 memcpy(rx_frame.data, rx_msg.data8, 8);
114 rx_frame.data_len = rx_msg.DLC;
115 #if defined(STM32_CAN_USE_FDCAN1) || defined(STM32_CAN_USE_FDCAN2)
116 if (rx_msg.common.XTD) {
117 rx_frame.id = CANARD_CAN_FRAME_EFF | rx_msg.ext.EID;
119 rx_frame.id = rx_msg.std.SID;
123 rx_frame.id = CANARD_CAN_FRAME_EFF | rx_msg.EID;
125 rx_frame.id = rx_msg.SID;
130 canardHandleRxFrame(&iface->
canard, &rx_frame, timestamp);
132 chMtxUnlock(&iface->
mutex);
134 chEvtUnregister(&iface->
can_driver->rxfull_event, &el);
142 event_listener_t txc, txe, txr;
146 chRegSetThreadName(
"uavcan_tx");
147 chEvtRegister(&iface->
can_driver->txempty_event, &txc, EVENT_MASK(0));
148 chEvtRegister(&iface->
can_driver->error_event, &txe, EVENT_MASK(1));
149 chEvtRegister(&iface->
tx_request, &txr, EVENT_MASK(2));
152 eventmask_t evts = chEvtWaitAnyTimeout(ALL_EVENTS, TIME_MS2I(100));
159 if (evts & EVENT_MASK(1)) {
160 chEvtGetAndClearFlags(&txe);
164 chMtxLock(&iface->
mutex);
165 for (
const CanardCANFrame *txf = NULL; (txf = canardPeekTxQueue(&iface->
canard)) != NULL;) {
167 memcpy(tx_msg.data8, txf->data, 8);
168 #if defined(STM32_CAN_USE_FDCAN1) || defined(STM32_CAN_USE_FDCAN2)
169 tx_msg.DLC = txf->data_len;
170 tx_msg.ext.EID = txf->id & CANARD_CAN_EXT_ID_MASK;
171 tx_msg.common.XTD = 1;
172 tx_msg.common.RTR = 0;
174 tx_msg.DLC = txf->data_len;
175 tx_msg.EID = txf->id & CANARD_CAN_EXT_ID_MASK;
176 tx_msg.IDE = CAN_IDE_EXT;
177 tx_msg.RTR = CAN_RTR_DATA;
179 if (!canTryTransmitI(iface->
can_driver, CAN_ANY_MAILBOX, &tx_msg)) {
181 canardPopTxQueue(&iface->
canard);
186 while (canardPeekTxQueue(&iface->
canard)) { canardPopTxQueue(&iface->
canard); }
191 chMtxUnlock(&iface->
mutex);
192 chThdSleepMilliseconds(++err_cnt);
193 chMtxLock(&iface->
mutex);
197 chMtxUnlock(&iface->
mutex);
210 if (
transfer->data_type_id ==
ev->data_type_id) {
222 CanardTransferType transfer_type __attribute__((unused)),
223 uint8_t source_node_id __attribute__((unused)))
228 if (data_type_id ==
ev->data_type_id) {
229 *out_data_type_signature =
ev->data_type_signature;
247 #if defined(STM32_CAN_USE_FDCAN1) || defined(STM32_CAN_USE_FDCAN2)
248 const uint32_t pclk = STM32_FDCANCLK;
252 static const int MaxBS1 = 16;
253 static const int MaxBS2 = 8;
266 const int max_quanta_per_bit = (iface->
can_baudrate >= 1000000) ? 10 : 17;
267 static const int MaxSamplePointLocation = 900;
282 uint8_t bs1_bs2_sum = max_quanta_per_bit - 1;
283 while ((prescaler_bs % (1 + bs1_bs2_sum)) != 0) {
284 if (bs1_bs2_sum <= 2) {
290 const uint32_t prescaler = prescaler_bs / (1 + bs1_bs2_sum);
291 if ((prescaler < 1U) || (prescaler > 1024U)) {
314 uint8_t bs1 = ((7 * bs1_bs2_sum - 1) + 4) / 8;
315 uint8_t bs2 = bs1_bs2_sum - bs1;
316 uint16_t sample_point_permill = 1000 * (1 + bs1) / (1 + bs1 + bs2);
319 if (sample_point_permill > MaxSamplePointLocation) {
320 bs1 = (7 * bs1_bs2_sum - 1) / 8;
321 bs2 = bs1_bs2_sum - bs1;
322 sample_point_permill = 1000 * (1 + bs1) / (1 + bs1 + bs2);
334 if ((iface->
can_baudrate != (pclk / (prescaler * (1 + bs1 + bs2)))) || (bs1 < 1) || (bs1 > MaxBS1) || (bs2 < 1)
340 #if defined(STM32_CAN_USE_FDCAN1) || defined(STM32_CAN_USE_FDCAN2)
341 iface->
can_cfg.NBTP = (0 << FDCAN_NBTP_NSJW_Pos) | ((bs1 - 1) << FDCAN_NBTP_NTSEG1_Pos) | ((
342 bs2 - 1) << FDCAN_NBTP_NTSEG2_Pos) | ((prescaler - 1) << FDCAN_NBTP_NBRP_Pos);
343 iface->
can_cfg.CCCR = FDCAN_CCCR_FDOE | FDCAN_CCCR_BRSE;
345 iface->
can_cfg.mcr = CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP;
346 iface->
can_cfg.btr = CAN_BTR_SJW(0) | CAN_BTR_TS1(bs1 - 1) | CAN_BTR_TS2(bs2 - 1) | CAN_BTR_BRP(prescaler - 1);
362 chMtxObjectInit(&iface->
mutex);
386 #if defined(STM32_CAN_USE_FDCAN1) || defined(STM32_CAN_USE_FDCAN2)
388 uavcan1.
can_cfg.RXF0C = (32 << FDCAN_RXF0C_F0S_Pos) | (0 << FDCAN_RXF0C_F0SA_Pos);
389 uavcan1.
can_cfg.RXF1C = (32 << FDCAN_RXF1C_F1S_Pos) | (128 << FDCAN_RXF1C_F1SA_Pos);
390 uavcan1.
can_cfg.TXBC = (32 << FDCAN_TXBC_TFQS_Pos) | (256 << FDCAN_TXBC_TBSA_Pos);
397 #if defined(STM32_CAN_USE_FDCAN1) || defined(STM32_CAN_USE_FDCAN2)
399 uavcan2.
can_cfg.RXF0C = (32 << FDCAN_RXF0C_F0S_Pos) | (384 << FDCAN_RXF0C_F0SA_Pos);
400 uavcan2.
can_cfg.RXF1C = (32 << FDCAN_RXF1C_F1S_Pos) | (512 << FDCAN_RXF1C_F1SA_Pos);
401 uavcan2.
can_cfg.TXBC = (32 << FDCAN_TXBC_TFQS_Pos) | (640 << FDCAN_TXBC_TBSA_Pos);
415 ev->data_type_id = data_type_id;
416 ev->data_type_signature = data_type_signature;
428 uint8_t priority,
const void *payload,
433 chMtxLock(&iface->
mutex);
434 canardBroadcast(&iface->
canard,
437 priority, payload, payload_len);
438 chMtxUnlock(&iface->
mutex);
void(* uavcan_callback)(struct uavcan_iface_t *iface, CanardRxTransfer *transfer)
Generic uavcan callback definition.
Main uavcan event structure for registering/calling callbacks.
THD_WORKING_AREA(wa_thd_ap, THD_WORKING_AREA_MAIN)
event_source_t tx_request
uint8_t canard_memory_pool[1024 *2]
uavcan interface structure
static THD_FUNCTION(uavcan_rx, p)
void uavcan_init(void)
Initialize all uavcan interfaces.
static bool shouldAcceptTransfer(const CanardInstance *ins, uint64_t *out_data_type_signature, uint16_t data_type_id, CanardTransferType transfer_type, uint8_t source_node_id)
If we should accept this transfer.
static void uavcanInitIface(struct uavcan_iface_t *iface)
Initialize uavcan interface.
static bool uavcanConfigureIface(struct uavcan_iface_t *iface)
Try to compute the timing registers for the can interface and set the configuration.
void uavcan_broadcast(struct uavcan_iface_t *iface, uint64_t data_type_signature, uint16_t data_type_id, uint8_t priority, const void *payload, uint16_t payload_len)
Broadcast an uavcan message to a specific interface.
static uavcan_event * uavcan_event_hd
void uavcan_bind(uint16_t data_type_id, uint64_t data_type_signature, uavcan_event *ev, uavcan_callback cb)
Bind to a receiving message from uavcan.
static void onTransferReceived(CanardInstance *ins, CanardRxTransfer *transfer)
Whenever a valid and 'accepted' transfer is received.
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned long long uint64_t
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
int transfer(const Mat *from, const image_t *to)