1717LOG_MODULE_REGISTER (can_mcan , CONFIG_CAN_LOG_LEVEL );
1818
1919#define CAN_INIT_TIMEOUT_MS 100
20+ #define TXBCF_TIMER_TIMEOUT K_MSEC(CONFIG_CAN_MCAN_TXBCF_POLL_INTERVAL_MS)
2021
2122int can_mcan_read_reg (const struct device * dev , uint16_t reg , uint32_t * val )
2223{
@@ -276,7 +277,7 @@ int can_mcan_get_capabilities(const struct device *dev, can_mode_t *cap)
276277{
277278 ARG_UNUSED (dev );
278279
279- * cap = CAN_MODE_NORMAL | CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY ;
280+ * cap = CAN_MODE_NORMAL | CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY | CAN_MODE_ONE_SHOT ;
280281
281282 if (IS_ENABLED (CONFIG_CAN_MANUAL_RECOVERY_MODE )) {
282283 * cap |= CAN_MODE_MANUAL_RECOVERY ;
@@ -294,6 +295,7 @@ int can_mcan_start(const struct device *dev)
294295 const struct can_mcan_config * config = dev -> config ;
295296 struct can_mcan_data * data = dev -> data ;
296297 int err = 0 ;
298+ uint32_t cccr ;
297299
298300 if (data -> common .started ) {
299301 return - EALREADY ;
@@ -322,12 +324,76 @@ int can_mcan_start(const struct device *dev)
322324 return err ;
323325 }
324326
327+ err = can_mcan_read_reg (dev , CAN_MCAN_CCCR , & cccr );
328+ if (err != 0 ) {
329+ return err ;
330+ }
331+
332+ if (cccr & CAN_MCAN_CCCR_DAR ) {
333+ /*
334+ * When DAR (Disable Automatic Retransmission), used for CAN_MODE_ONE_SHOT,
335+ * is enabled, and a transmission fails, a bug in the MCAN IP prevents the
336+ * TCF (Transmission Cancellation Finalized) interrupt from triggering,
337+ * despite the correct bit being set in the TXBCF register. It is thus
338+ * neccesary to poll TXBCF register to detect when a transmission failed if
339+ * DAR is enabled.
340+ */
341+ k_timer_start (& data -> txbcf_timer , TXBCF_TIMER_TIMEOUT , TXBCF_TIMER_TIMEOUT );
342+ }
343+
325344 data -> common .started = true;
326345 pm_device_busy_set (dev );
327346
328347 return err ;
329348}
330349
350+ static int can_mcan_read_txbcf (const struct device * dev )
351+ {
352+ const struct can_mcan_config * config = dev -> config ;
353+ const struct can_mcan_callbacks * cbs = config -> callbacks ;
354+ struct can_mcan_data * data = dev -> data ;
355+ uint32_t txbcfs ;
356+ int err ;
357+ can_tx_callback_t tx_cb ;
358+ void * user_data ;
359+
360+ err = can_mcan_read_reg (dev , CAN_MCAN_TXBCF , & txbcfs );
361+ if (err != 0 ) {
362+ LOG_ERR ("failed to read tx cancellation finished (err %d)" , err );
363+ return err ;
364+ }
365+
366+ if (txbcfs == 0 ) {
367+ return 0 ;
368+ }
369+
370+ for (size_t tx_idx = 0 ; tx_idx < cbs -> num_tx ; tx_idx ++ ) {
371+ if ((txbcfs & BIT (tx_idx )) == 0 ) {
372+ continue ;
373+ }
374+
375+ if (cbs -> tx [tx_idx ].function == NULL ) {
376+ continue ;
377+ }
378+
379+ tx_cb = cbs -> tx [tx_idx ].function ;
380+ user_data = cbs -> tx [tx_idx ].user_data ;
381+ cbs -> tx [tx_idx ].function = NULL ;
382+ LOG_DBG ("tx buffer cancellation finished (idx %u)" , tx_idx );
383+ k_sem_give (& data -> tx_sem );
384+ tx_cb (dev , - EIO , user_data );
385+ }
386+
387+ return 0 ;
388+ }
389+
390+ static void can_mcan_txbcf_timer_handler (struct k_timer * timer_id )
391+ {
392+ const struct device * dev = k_timer_user_data_get (timer_id );
393+
394+ can_mcan_read_txbcf (dev );
395+ }
396+
331397static bool can_mcan_rx_filters_exist (const struct device * dev )
332398{
333399 const struct can_mcan_config * config = dev -> config ;
@@ -362,6 +428,8 @@ int can_mcan_stop(const struct device *dev)
362428 return - EALREADY ;
363429 }
364430
431+ k_timer_stop (& data -> txbcf_timer );
432+
365433 /* CAN transmissions are automatically stopped when entering init mode */
366434 err = can_mcan_enter_init_mode (dev , K_MSEC (CAN_INIT_TIMEOUT_MS ));
367435 if (err != 0 ) {
@@ -402,7 +470,7 @@ int can_mcan_stop(const struct device *dev)
402470
403471int can_mcan_set_mode (const struct device * dev , can_mode_t mode )
404472{
405- can_mode_t supported = CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY ;
473+ can_mode_t supported = CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY | CAN_MODE_ONE_SHOT ;
406474 struct can_mcan_data * data = dev -> data ;
407475 uint32_t cccr ;
408476 uint32_t test ;
@@ -460,6 +528,13 @@ int can_mcan_set_mode(const struct device *dev, can_mode_t mode)
460528 }
461529#endif /* CONFIG_CAN_FD_MODE */
462530
531+ if ((mode & CAN_MODE_ONE_SHOT ) != 0 ) {
532+ /* Disable Automatic Retransmission */
533+ cccr |= CAN_MCAN_CCCR_DAR ;
534+ } else {
535+ cccr &= ~CAN_MCAN_CCCR_DAR ;
536+ }
537+
463538 err = can_mcan_write_reg (dev , CAN_MCAN_CCCR , cccr );
464539 if (err != 0 ) {
465540 goto unlock ;
@@ -1424,6 +1499,8 @@ int can_mcan_init(const struct device *dev)
14241499 k_mutex_init (& data -> lock );
14251500 k_mutex_init (& data -> tx_mtx );
14261501 k_sem_init (& data -> tx_sem , cbs -> num_tx , cbs -> num_tx );
1502+ k_timer_init (& data -> txbcf_timer , can_mcan_txbcf_timer_handler , NULL );
1503+ k_timer_user_data_set (& data -> txbcf_timer , (void * )dev );
14271504
14281505 if (config -> common .phy != NULL && !device_is_ready (config -> common .phy )) {
14291506 LOG_ERR ("CAN transceiver not ready" );
@@ -1565,5 +1642,14 @@ int can_mcan_init(const struct device *dev)
15651642 return err ;
15661643 }
15671644
1645+ /*
1646+ * Interrupt on every TX buffer cancellation finished event.
1647+ */
1648+ reg = CAN_MCAN_TXBCIE_CFIE ;
1649+ err = can_mcan_write_reg (dev , CAN_MCAN_TXBCIE , reg );
1650+ if (err != 0 ) {
1651+ return err ;
1652+ }
1653+
15681654 return can_mcan_clear_mram (dev , 0 , config -> mram_size );
15691655}
0 commit comments