@@ -506,6 +506,7 @@ int CanIface::init(const uavcan::uint32_t bitrate, const OperatingMode mode)
506506 if (!waitMsrINakBitStateChange (true ))
507507 {
508508 UAVCAN_STM32_LOG (" MSR INAK not set" );
509+ can_->MCR = bxcan::MCR_RESET;
509510 return -ErrMsrInakNotSet;
510511 }
511512
@@ -527,6 +528,7 @@ int CanIface::init(const uavcan::uint32_t bitrate, const OperatingMode mode)
527528 const int timings_res = computeTimings (bitrate, timings);
528529 if (timings_res < 0 )
529530 {
531+ can_->MCR = bxcan::MCR_RESET;
530532 return timings_res;
531533 }
532534 UAVCAN_STM32_LOG (" Timings: presc=%u sjw=%u bs1=%u bs2=%u" ,
@@ -549,11 +551,12 @@ int CanIface::init(const uavcan::uint32_t bitrate, const OperatingMode mode)
549551 bxcan::IER_ERRIE | // General error IRQ
550552 bxcan::IER_LECIE; // Last error code change
551553
552- can_->MCR &= ~bxcan::MCR_INRQ; // Leave init mode
554+ can_->MCR &= ~bxcan::MCR_INRQ; // Leave init mode
553555
554556 if (!waitMsrINakBitStateChange (false ))
555557 {
556558 UAVCAN_STM32_LOG (" MSR INAK not cleared" );
559+ can_->MCR = bxcan::MCR_RESET;
557560 return -ErrMsrInakNotCleared;
558561 }
559562
@@ -971,26 +974,28 @@ int CanDriver::init(const uavcan::uint32_t bitrate, const CanIface::OperatingMod
971974 * CAN1
972975 */
973976 UAVCAN_STM32_LOG (" Initing iface 0..." );
974- res = if0_.init (bitrate, mode);
975- if (res < 0 )
977+ ifaces[0 ] = &if0_; // This link must be initialized first,
978+ res = if0_.init (bitrate, mode); // otherwise an IRQ may fire while the interface is not linked yet;
979+ if (res < 0 ) // a typical race condition.
976980 {
977981 UAVCAN_STM32_LOG (" Iface 0 init failed %i" , res);
982+ ifaces[0 ] = NULL ;
978983 goto fail;
979984 }
980- ifaces[0 ] = &if0_;
981985
982986 /*
983987 * CAN2
984988 */
985989#if UAVCAN_STM32_NUM_IFACES > 1
986990 UAVCAN_STM32_LOG (" Initing iface 1..." );
991+ ifaces[1 ] = &if1_; // Same thing here.
987992 res = if1_.init (bitrate, mode);
988993 if (res < 0 )
989994 {
990995 UAVCAN_STM32_LOG (" Iface 1 init failed %i" , res);
996+ ifaces[1 ] = NULL ;
991997 goto fail;
992998 }
993- ifaces[1 ] = &if1_;
994999#endif
9951000
9961001 UAVCAN_STM32_LOG (" CAN drv init OK" );
0 commit comments