1717LOG_MODULE_REGISTER (can_mcan , CONFIG_CAN_LOG_LEVEL );
1818
1919#define CAN_INIT_TIMEOUT_MS 100
20+ #define TX_ABORTED_TIMEOUT_MS 100
2021
2122int can_mcan_read_reg (const struct device * dev , uint16_t reg , uint32_t * val )
2223{
@@ -286,6 +287,10 @@ int can_mcan_get_capabilities(const struct device *dev, can_mode_t *cap)
286287 * cap |= CAN_MODE_FD ;
287288 }
288289
290+ if (IS_ENABLED (CONFIG_CAN_STATS )) {
291+ * cap |= CAN_MODE_ONE_SHOT ;
292+ }
293+
289294 return 0 ;
290295}
291296
@@ -328,6 +333,70 @@ int can_mcan_start(const struct device *dev)
328333 return err ;
329334}
330335
336+ static int can_mcan_check_txbcf (const struct device * dev , uint32_t psr , enum can_mcan_psr_lec lec )
337+ {
338+ const struct can_mcan_config * config = dev -> config ;
339+ const struct can_mcan_callbacks * cbs = config -> callbacks ;
340+ struct can_mcan_data * data = dev -> data ;
341+ uint32_t txbcfs ;
342+ int err ;
343+ can_tx_callback_t tx_cb ;
344+ void * user_data ;
345+ int tx_err ;
346+
347+ err = can_mcan_read_reg (dev , CAN_MCAN_TXBCF , & txbcfs );
348+ if (err != 0 ) {
349+ LOG_ERR ("failed to read tx cancellation finished (err %d)" , err );
350+ return err ;
351+ }
352+
353+ if (txbcfs == 0 ) {
354+ return 0 ;
355+ }
356+
357+ if (psr & CAN_MCAN_PSR_BO ) {
358+ /* In bus-off state */
359+ tx_err = - ENETUNREACH ;
360+ } else {
361+ switch (lec ) {
362+ case CAN_MCAN_PSR_LEC_NO_ERROR :
363+ case CAN_MCAN_PSR_LEC_NO_CHANGE :
364+ /* Manually cancelled using TXBCR when MCAN is moved to stopped state */
365+ tx_err = - ENETDOWN ;
366+ break ;
367+ default :
368+ /* Bundle remaining errors as -EIO as there is no error specifically for
369+ * arbitration lost.
370+ */
371+ tx_err = - EIO ;
372+ break ;
373+ }
374+ }
375+
376+ for (size_t tx_idx = 0 ; tx_idx < cbs -> num_tx ; tx_idx ++ ) {
377+ if ((txbcfs & BIT (tx_idx )) == 0 ) {
378+ continue ;
379+ }
380+
381+ if (cbs -> tx [tx_idx ].function == NULL ) {
382+ continue ;
383+ }
384+
385+ tx_cb = cbs -> tx [tx_idx ].function ;
386+ user_data = cbs -> tx [tx_idx ].user_data ;
387+ cbs -> tx [tx_idx ].function = NULL ;
388+ LOG_DBG ("tx buffer cancellation finished (idx %u)" , tx_idx );
389+ k_sem_give (& data -> tx_sem );
390+ tx_cb (dev , tx_err , user_data );
391+ }
392+
393+ if (k_sem_count_get (& data -> tx_sem ) == cbs -> num_tx ) {
394+ k_sem_give (& data -> stopped_sem );
395+ }
396+
397+ return 0 ;
398+ }
399+
331400static bool can_mcan_rx_filters_exist (const struct device * dev )
332401{
333402 const struct can_mcan_config * config = dev -> config ;
@@ -352,17 +421,27 @@ static bool can_mcan_rx_filters_exist(const struct device *dev)
352421int can_mcan_stop (const struct device * dev )
353422{
354423 const struct can_mcan_config * config = dev -> config ;
355- const struct can_mcan_callbacks * cbs = config -> callbacks ;
356424 struct can_mcan_data * data = dev -> data ;
357- can_tx_callback_t tx_cb ;
358- uint32_t tx_idx ;
359425 int err ;
360426
361427 if (!data -> common .started ) {
362428 return - EALREADY ;
363429 }
364430
365- /* CAN transmissions are automatically stopped when entering init mode */
431+ /* Request all TX buffers to be cancelled */
432+ k_sem_reset (& data -> stopped_sem );
433+ err = can_mcan_write_reg (dev , CAN_MCAN_TXBCR , CAN_MCAN_TXBCR_CR );
434+ if (err != 0 ) {
435+ return err ;
436+ }
437+
438+ /* Wait for all TX buffers to be cancelled */
439+ err = k_sem_take (& data -> stopped_sem , K_MSEC (TX_ABORTED_TIMEOUT_MS ));
440+ if (err != 0 ) {
441+ LOG_ERR ("Timed out waiting for all TX buffers to be cancelled" );
442+ return err ;
443+ }
444+
366445 err = can_mcan_enter_init_mode (dev , K_MSEC (CAN_INIT_TIMEOUT_MS ));
367446 if (err != 0 ) {
368447 LOG_ERR ("Failed to enter init mode" );
@@ -381,16 +460,6 @@ int can_mcan_stop(const struct device *dev)
381460
382461 data -> common .started = false;
383462
384- for (tx_idx = 0U ; tx_idx < cbs -> num_tx ; tx_idx ++ ) {
385- tx_cb = cbs -> tx [tx_idx ].function ;
386-
387- if (tx_cb != NULL ) {
388- cbs -> tx [tx_idx ].function = NULL ;
389- tx_cb (dev , - ENETDOWN , cbs -> tx [tx_idx ].user_data );
390- k_sem_give (& data -> tx_sem );
391- }
392- }
393-
394463 k_mutex_lock (& data -> lock , K_FOREVER );
395464 if (!can_mcan_rx_filters_exist (dev )) {
396465 pm_device_busy_clear (dev );
@@ -416,6 +485,10 @@ int can_mcan_set_mode(const struct device *dev, can_mode_t mode)
416485 supported |= CAN_MODE_FD ;
417486 }
418487
488+ if (IS_ENABLED (CONFIG_CAN_STATS )) {
489+ supported |= CAN_MODE_ONE_SHOT ;
490+ }
491+
419492 if ((mode & ~(supported )) != 0U ) {
420493 LOG_ERR ("unsupported mode: 0x%08x" , mode );
421494 return - ENOTSUP ;
@@ -460,6 +533,13 @@ int can_mcan_set_mode(const struct device *dev, can_mode_t mode)
460533 }
461534#endif /* CONFIG_CAN_FD_MODE */
462535
536+ if ((mode & CAN_MODE_ONE_SHOT ) != 0 ) {
537+ /* Disable Automatic Retransmission */
538+ cccr |= CAN_MCAN_CCCR_DAR ;
539+ } else {
540+ cccr &= ~CAN_MCAN_CCCR_DAR ;
541+ }
542+
463543 err = can_mcan_write_reg (dev , CAN_MCAN_CCCR , cccr );
464544 if (err != 0 ) {
465545 goto unlock ;
@@ -480,12 +560,9 @@ int can_mcan_set_mode(const struct device *dev, can_mode_t mode)
480560
481561static void can_mcan_state_change_handler (const struct device * dev )
482562{
483- const struct can_mcan_config * config = dev -> config ;
484563 struct can_mcan_data * data = dev -> data ;
485564 const can_state_change_callback_t state_cb = data -> common .state_change_cb ;
486565 void * state_cb_data = data -> common .state_change_cb_user_data ;
487- const struct can_mcan_callbacks * cbs = config -> callbacks ;
488- can_tx_callback_t tx_cb ;
489566 struct can_bus_err_cnt err_cnt ;
490567 enum can_state state ;
491568 uint32_t cccr ;
@@ -507,17 +584,6 @@ static void can_mcan_state_change_handler(const struct device *dev)
507584 return ;
508585 }
509586
510- /* Call all TX queue callbacks with -ENETUNREACH */
511- for (uint32_t tx_idx = 0U ; tx_idx < cbs -> num_tx ; tx_idx ++ ) {
512- tx_cb = cbs -> tx [tx_idx ].function ;
513-
514- if (tx_cb != NULL ) {
515- cbs -> tx [tx_idx ].function = NULL ;
516- tx_cb (dev , - ENETUNREACH , cbs -> tx [tx_idx ].user_data );
517- k_sem_give (& data -> tx_sem );
518- }
519- }
520-
521587 if (!IS_ENABLED (CONFIG_CAN_MANUAL_RECOVERY_MODE ) ||
522588 (data -> common .mode & CAN_MODE_MANUAL_RECOVERY ) == 0U ) {
523589 /*
@@ -623,7 +689,7 @@ static void can_mcan_lec_update_stats(const struct device *dev, enum can_mcan_ps
623689}
624690#endif /* CONFIG_CAN_STATS */
625691
626- static int can_mcan_read_psr (const struct device * dev , uint32_t * val )
692+ static int can_mcan_read_psr (const struct device * dev , uint32_t * val , enum can_mcan_psr_lec * lec )
627693{
628694 /* Reading the lower byte of the PSR register clears the protocol last
629695 * error codes (LEC). To avoid missing errors, this function should be
@@ -636,14 +702,15 @@ static int can_mcan_read_psr(const struct device *dev, uint32_t *val)
636702 }
637703
638704#ifdef CONFIG_CAN_STATS
639- enum can_mcan_psr_lec lec ;
705+ * lec = FIELD_GET ( CAN_MCAN_PSR_LEC , * val ) ;
640706
641- lec = FIELD_GET (CAN_MCAN_PSR_LEC , * val );
642- can_mcan_lec_update_stats (dev , lec );
643707#ifdef CONFIG_CAN_FD_MODE
644- lec = FIELD_GET (CAN_MCAN_PSR_DLEC , * val );
645- can_mcan_lec_update_stats (dev , lec );
646- #endif
708+ if (* lec == CAN_MCAN_PSR_LEC_NO_CHANGE ) {
709+ * lec = FIELD_GET (CAN_MCAN_PSR_DLEC , * val );
710+ }
711+ #endif /* CONFIG_CAN_FD_MODE */
712+
713+ can_mcan_lec_update_stats (dev , * lec );
647714#endif /* CONFIG_CAN_STATS */
648715
649716 return 0 ;
@@ -653,7 +720,8 @@ void can_mcan_line_0_isr(const struct device *dev)
653720{
654721 const uint32_t events = CAN_MCAN_IR_BO | CAN_MCAN_IR_EP | CAN_MCAN_IR_EW |
655722 CAN_MCAN_IR_TEFN | CAN_MCAN_IR_TEFL | CAN_MCAN_IR_ARA |
656- CAN_MCAN_IR_MRAF | CAN_MCAN_IR_PEA | CAN_MCAN_IR_PED ;
723+ CAN_MCAN_IR_MRAF | CAN_MCAN_IR_PEA | CAN_MCAN_IR_PED |
724+ CAN_MCAN_IR_TCF ;
657725 struct can_mcan_data * data = dev -> data ;
658726 uint32_t ir ;
659727 int err ;
@@ -694,11 +762,22 @@ void can_mcan_line_0_isr(const struct device *dev)
694762#ifdef CONFIG_CAN_STATS
695763 if ((ir & (CAN_MCAN_IR_PEA | CAN_MCAN_IR_PED )) != 0U ) {
696764 uint32_t reg ;
765+ enum can_mcan_psr_lec lec ;
766+
697767 /* This function automatically updates protocol error stats */
698- can_mcan_read_psr (dev , & reg );
768+ can_mcan_read_psr (dev , & reg , & lec );
769+
770+ /* TCF will not be set if TX failed with DAR mode enabled, but
771+ * PEA or PED will be set, so check if TX was set.
772+ */
773+ can_mcan_check_txbcf (dev , reg , lec );
699774 }
700775#endif
701776
777+ if ((ir & CAN_MCAN_IR_TCF ) != 0U ) {
778+ can_mcan_check_txbcf (dev , 0 , CAN_MCAN_PSR_LEC_NO_ERROR );
779+ }
780+
702781 err = can_mcan_read_reg (dev , CAN_MCAN_IR , & ir );
703782 if (err != 0 ) {
704783 return ;
@@ -878,10 +957,11 @@ int can_mcan_get_state(const struct device *dev, enum can_state *state,
878957{
879958 struct can_mcan_data * data = dev -> data ;
880959 uint32_t reg ;
960+ enum can_mcan_psr_lec lec ;
881961 int err ;
882962
883963 if (state != NULL ) {
884- err = can_mcan_read_psr (dev , & reg );
964+ err = can_mcan_read_psr (dev , & reg , & lec );
885965 if (err != 0 ) {
886966 return err ;
887967 }
@@ -952,6 +1032,7 @@ int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_tim
9521032 };
9531033 uint32_t put_idx = -1 ;
9541034 uint32_t reg ;
1035+ enum can_mcan_psr_lec lec ;
9551036 int err ;
9561037
9571038 LOG_DBG ("Sending %zu bytes. Id: 0x%x, ID type: %s %s %s %s" , data_length , frame -> id ,
@@ -1001,7 +1082,7 @@ int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_tim
10011082 return - ENETDOWN ;
10021083 }
10031084
1004- err = can_mcan_read_psr (dev , & reg );
1085+ err = can_mcan_read_psr (dev , & reg , & lec );
10051086 if (err != 0 ) {
10061087 return err ;
10071088 }
@@ -1424,6 +1505,7 @@ int can_mcan_init(const struct device *dev)
14241505 k_mutex_init (& data -> lock );
14251506 k_mutex_init (& data -> tx_mtx );
14261507 k_sem_init (& data -> tx_sem , cbs -> num_tx , cbs -> num_tx );
1508+ k_sem_init (& data -> stopped_sem , 0 , 1 );
14271509
14281510 if (config -> common .phy != NULL && !device_is_ready (config -> common .phy )) {
14291511 LOG_ERR ("CAN transceiver not ready" );
@@ -1533,7 +1615,7 @@ int can_mcan_init(const struct device *dev)
15331615
15341616 reg = CAN_MCAN_IE_BOE | CAN_MCAN_IE_EWE | CAN_MCAN_IE_EPE | CAN_MCAN_IE_MRAFE |
15351617 CAN_MCAN_IE_TEFLE | CAN_MCAN_IE_TEFNE | CAN_MCAN_IE_RF0NE | CAN_MCAN_IE_RF1NE |
1536- CAN_MCAN_IE_RF0LE | CAN_MCAN_IE_RF1LE ;
1618+ CAN_MCAN_IE_RF0LE | CAN_MCAN_IE_RF1LE | CAN_MCAN_IE_TCFE ;
15371619#ifdef CONFIG_CAN_STATS
15381620 /* These ISRs are only enabled/used for statistics, they are otherwise
15391621 * disabled as they may produce a significant amount of frequent ISRs.
@@ -1565,5 +1647,14 @@ int can_mcan_init(const struct device *dev)
15651647 return err ;
15661648 }
15671649
1650+ /*
1651+ * Interrupt on every TX buffer cancellation finished event.
1652+ */
1653+ reg = CAN_MCAN_TXBCIE_CFIE ;
1654+ err = can_mcan_write_reg (dev , CAN_MCAN_TXBCIE , reg );
1655+ if (err != 0 ) {
1656+ return err ;
1657+ }
1658+
15681659 return can_mcan_clear_mram (dev , 0 , config -> mram_size );
15691660}
0 commit comments