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,68 @@ 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+ k_timer_start (& data -> txbcf_timer , TXBCF_TIMER_TIMEOUT , TXBCF_TIMER_TIMEOUT );
334+ }
335+
325336 data -> common .started = true;
326337 pm_device_busy_set (dev );
327338
328339 return err ;
329340}
330341
342+ static int can_mcan_read_txbcf (const struct device * dev )
343+ {
344+ const struct can_mcan_config * config = dev -> config ;
345+ const struct can_mcan_callbacks * cbs = config -> callbacks ;
346+ struct can_mcan_data * data = dev -> data ;
347+ uint32_t txbcfs ;
348+ int err ;
349+ can_tx_callback_t tx_cb ;
350+ void * user_data ;
351+
352+ err = can_mcan_read_reg (dev , CAN_MCAN_TXBCF , & txbcfs );
353+ if (err != 0 ) {
354+ LOG_ERR ("failed to read tx cancellation finished (err %d)" , err );
355+ return err ;
356+ }
357+
358+ if (txbcfs == 0 ) {
359+ return 0 ;
360+ }
361+
362+ for (size_t tx_idx = 0 ; tx_idx < cbs -> num_tx ; tx_idx ++ ) {
363+ if ((txbcfs & BIT (tx_idx )) == 0 ) {
364+ continue ;
365+ }
366+
367+ if (cbs -> tx [tx_idx ].function == NULL ) {
368+ continue ;
369+ }
370+
371+ tx_cb = cbs -> tx [tx_idx ].function ;
372+ user_data = cbs -> tx [tx_idx ].user_data ;
373+ cbs -> tx [tx_idx ].function = NULL ;
374+ LOG_DBG ("tx buffer cancellation finished (idx %u)" , tx_idx );
375+ k_sem_give (& data -> tx_sem );
376+ tx_cb (dev , - EIO , user_data );
377+ }
378+
379+ return 0 ;
380+ }
381+
382+ static void can_mcan_txbcf_timer_handler (struct k_timer * timer_id )
383+ {
384+ const struct device * dev = k_timer_user_data_get (timer_id );
385+
386+ can_mcan_read_txbcf (dev );
387+ }
388+
331389static bool can_mcan_rx_filters_exist (const struct device * dev )
332390{
333391 const struct can_mcan_config * config = dev -> config ;
@@ -362,6 +420,8 @@ int can_mcan_stop(const struct device *dev)
362420 return - EALREADY ;
363421 }
364422
423+ k_timer_stop (& data -> txbcf_timer );
424+
365425 /* CAN transmissions are automatically stopped when entering init mode */
366426 err = can_mcan_enter_init_mode (dev , K_MSEC (CAN_INIT_TIMEOUT_MS ));
367427 if (err != 0 ) {
@@ -402,7 +462,7 @@ int can_mcan_stop(const struct device *dev)
402462
403463int can_mcan_set_mode (const struct device * dev , can_mode_t mode )
404464{
405- can_mode_t supported = CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY ;
465+ can_mode_t supported = CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY | CAN_MODE_ONE_SHOT ;
406466 struct can_mcan_data * data = dev -> data ;
407467 uint32_t cccr ;
408468 uint32_t test ;
@@ -460,6 +520,13 @@ int can_mcan_set_mode(const struct device *dev, can_mode_t mode)
460520 }
461521#endif /* CONFIG_CAN_FD_MODE */
462522
523+ if ((mode & CAN_MODE_ONE_SHOT ) != 0 ) {
524+ /* Disable Automatic Retransmission */
525+ cccr |= CAN_MCAN_CCCR_DAR ;
526+ } else {
527+ cccr &= ~CAN_MCAN_CCCR_DAR ;
528+ }
529+
463530 err = can_mcan_write_reg (dev , CAN_MCAN_CCCR , cccr );
464531 if (err != 0 ) {
465532 goto unlock ;
@@ -694,6 +761,7 @@ void can_mcan_line_0_isr(const struct device *dev)
694761#ifdef CONFIG_CAN_STATS
695762 if ((ir & (CAN_MCAN_IR_PEA | CAN_MCAN_IR_PED )) != 0U ) {
696763 uint32_t reg ;
764+
697765 /* This function automatically updates protocol error stats */
698766 can_mcan_read_psr (dev , & reg );
699767 }
@@ -1424,6 +1492,8 @@ int can_mcan_init(const struct device *dev)
14241492 k_mutex_init (& data -> lock );
14251493 k_mutex_init (& data -> tx_mtx );
14261494 k_sem_init (& data -> tx_sem , cbs -> num_tx , cbs -> num_tx );
1495+ k_timer_init (& data -> txbcf_timer , can_mcan_txbcf_timer_handler , NULL );
1496+ k_timer_user_data_set (& data -> txbcf_timer , (void * )dev );
14271497
14281498 if (config -> common .phy != NULL && !device_is_ready (config -> common .phy )) {
14291499 LOG_ERR ("CAN transceiver not ready" );
@@ -1565,5 +1635,14 @@ int can_mcan_init(const struct device *dev)
15651635 return err ;
15661636 }
15671637
1638+ /*
1639+ * Interrupt on every TX buffer cancellation finished event.
1640+ */
1641+ reg = CAN_MCAN_TXBCIE_CFIE ;
1642+ err = can_mcan_write_reg (dev , CAN_MCAN_TXBCIE , reg );
1643+ if (err != 0 ) {
1644+ return err ;
1645+ }
1646+
15681647 return can_mcan_clear_mram (dev , 0 , config -> mram_size );
15691648}
0 commit comments