@@ -43,14 +43,14 @@ extern uint32_t SystemCoreClock;
4343
4444/// Error trackers, one for each possible CAN interface.
4545/// As the bxCANReapError() function only returns a bool, we can keep this as a simple flag.
46- static bool g_error [2 ] = {false};
46+ static bool g_error [2 ] = {false}; // NOLINT mutable global
4747
4848/// Time stamps for TX time-out management. There are three TX mailboxes for each CAN interface.
4949/// An UINT64_MAX value means the time stamp is not set (mailbox is not in use). Zero initialization
5050/// will work, as the value will be re-set to UINT64_MAX in abortExpiredTxMailboxes() and set to the
5151/// required value in bxCANPush(). This way, any inadvertently busy mailboxes will still be aborted
5252/// automatically, making this more robust than initializing to UINT64_MAX from the onset.
53- static uint64_t g_tx_deadline [(1 + BXCAN_MAX_IFACE_INDEX ) * 3 ] = {0 };
53+ static uint64_t g_tx_deadline [(1 + BXCAN_MAX_IFACE_INDEX ) * 3 ] = {0 }; // NOLINT mutable global
5454
5555/// Converts an extended-ID frame format into the bxCAN TX ID register format.
5656static uint32_t convertFrameIDToRegister (const uint32_t id )
@@ -103,8 +103,7 @@ static bool waitMSRINAKBitStateChange(volatile const BxCANType* const bxcan_base
103103 // The counter variable is declared volatile to prevent the compiler from optimizing it away.
104104 volatile size_t nticks = BXCAN_BUSYWAIT_DELAY_SYSTEM_CORE_CLOCK / 7000U ;
105105 while (-- nticks )
106- {
107- }
106+ {}
108107 }
109108
110109 return out_status ;
@@ -171,7 +170,7 @@ static void processErrorStatus(volatile BxCANType* const bxcan_base, //
171170 BXCAN_ASSERT ((error_iface == & g_error [0 ]) || (error_iface == & g_error [1 ])); // Valid g_error address.
172171
173172 // Updating error flag.
174- const uint8_t lec = (uint8_t )((bxcan_base -> ESR & BXCAN_ESR_LEC_MASK ) >> BXCAN_ESR_LEC_SHIFT );
173+ const uint8_t lec = (uint8_t ) ((bxcan_base -> ESR & BXCAN_ESR_LEC_MASK ) >> BXCAN_ESR_LEC_SHIFT );
175174
176175 if (lec != 0U )
177176 {
@@ -204,19 +203,16 @@ bool bxCANConfigure(const uint8_t iface_index, //
204203
205204 // Select the appropriate CAN interface base address and zero the error flags for it.
206205 // If the interface number is invalid, return with an error.
207- volatile BxCANType * bxcan_base = NULL ; // Selected CAN interface base address.
208- uint8_t filter_index = 0U ;
206+ volatile BxCANType * bxcan_base = NULL ; // Selected CAN interface base address.
209207 if (iface_index == 0U )
210208 {
211- bxcan_base = BXCAN1 ;
212- g_error [0 ] = false;
213- filter_index = 0U ; // First filter slot for CAN1.
209+ bxcan_base = BXCAN1 ;
210+ g_error [0 ] = false;
214211 }
215212 else if ((iface_index == 1U ) && (BXCAN_MAX_IFACE_INDEX == 1U ))
216213 {
217- bxcan_base = BXCAN2 ;
218- g_error [1 ] = false;
219- filter_index = (uint8_t ) BXCAN_NUM_ACCEPTANCE_FILTERS ; // First filter slot for CAN2.
214+ bxcan_base = BXCAN2 ;
215+ g_error [1 ] = false;
220216 }
221217 else
222218 {
@@ -279,8 +275,6 @@ bool bxCANConfigure(const uint8_t iface_index, //
279275 ((timings .bit_rate_prescaler - 1U ) & 1023U ) | //
280276 (silent ? BXCAN_BTR_SILM : 0U );
281277
282- BXCAN_ASSERT (bxcan_base -> IER == 0U ); // Make sure the interrupts are indeed disabled.
283-
284278 bxcan_base -> MCR &= ~BXCAN_MCR_INRQ ; // Leave init mode.
285279
286280 if (!waitMSRINAKBitStateChange (bxcan_base , false))
@@ -302,44 +296,51 @@ bool bxCANConfigure(const uint8_t iface_index, //
302296 // This will cause occasional priority inversion and frame reordering on reception,
303297 // but that is acceptable for UAVCAN, and a majority of other protocols will tolerate
304298 // this too, since there will be no reordering within the same CAN ID.
305- if (BXCAN_MAX_IFACE_INDEX > 0 )
299+ if (iface_index == 0U )
306300 {
307- // MCU with two bxCAN interfaces: configure the filter start banks for each interface.
308- // Example MCU: STM32F446.
309- // Note: block statement is introduced to contain the scope of fmr (defensive programming).
301+ if (BXCAN_MAX_IFACE_INDEX > 0 )
310302 {
311- uint32_t fmr = BXCAN1 -> FMR & 0xFFFFC0FEU ;
312- fmr |= BXCAN_NUM_ACCEPTANCE_FILTERS << 8U ; // CAN2 start bank = 14 (if CAN2 is present)
313- BXCAN1 -> FMR = fmr | BXCAN_FMR_FINIT ; // Set the configuration, enter filter initialization mode.
314- }
303+ // MCU with two bxCAN interfaces: configure the filter start banks for each interface.
304+ // Example MCU: STM32F446.
305+ {
306+ uint32_t fmr = BXCAN1 -> FMR & 0xFFFFC0FEU ;
307+ fmr |= BXCAN_NUM_ACCEPTANCE_FILTERS << 8U ; // CAN2 start bank = 14 (if CAN2 is present)
308+ BXCAN1 -> FMR = fmr | BXCAN_FMR_FINIT ; // Set the configuration, enter filter initialization mode.
309+ }
315310
316- BXCAN_ASSERT (((BXCAN1 -> FMR >> 8U ) & 0x3FU ) == BXCAN_NUM_ACCEPTANCE_FILTERS );
311+ BXCAN_ASSERT (((BXCAN1 -> FMR >> 8U ) & 0x3FU ) == BXCAN_NUM_ACCEPTANCE_FILTERS );
317312
318- BXCAN1 -> FM1R &= 0xF0000000U ; // Identifier Mask mode. (4 MSB are reserved.)
319- BXCAN1 -> FS1R |= 0x0FFFFFFFU ; // All 32-bit filters. (4 MSB are reserved.)
313+ BXCAN1 -> FM1R &= 0xF0000000U ; // Identifier Mask mode. (4 MSB are reserved.)
314+ BXCAN1 -> FS1R |= 0x0FFFFFFFU ; // All 32-bit filters. (4 MSB are reserved.)
320315
321- BXCAN1 -> FFA1R =
322- (BXCAN1 -> FFA1R & 0xF0000000U ) | 0x0AAAAAAAU ; // Alternate the filters between FIFO0 & FIFO1.
323- }
324- else
325- {
326- // MCU with single bxCAN interface has no filter start bank configuration in FMR.
327- // Example MCU: STM32L431.
328- BXCAN1 -> FMR |= BXCAN_FMR_FINIT ; // Enter filter initialization mode.
316+ BXCAN1 -> FFA1R =
317+ (BXCAN1 -> FFA1R & 0xF0000000U ) | 0x0AAAAAAAU ; // Alternate the filters between FIFO0 & FIFO1.
329318
330- BXCAN1 -> FM1R &= 0xFFFFC000U ; // Identifier Mask mode. (18 MSB are reserved.)
331- BXCAN1 -> FS1R |= 0x00003FFFU ; // All 32-bit filters. (18 MSB are reserved.)
319+ // Configure one "accept all" filter and enable it.
320+ BXCAN1 -> FilterRegister [BXCAN_NUM_ACCEPTANCE_FILTERS ].FR1 = 0U ;
321+ BXCAN1 -> FilterRegister [BXCAN_NUM_ACCEPTANCE_FILTERS ].FR2 = 0U ;
322+ BXCAN1 -> FA1R |= (1U << BXCAN_NUM_ACCEPTANCE_FILTERS );
323+ }
324+ else
325+ {
326+ // MCU with single bxCAN interface has no filter start bank configuration in FMR.
327+ // Example MCU: STM32L431.
328+ BXCAN1 -> FMR |= BXCAN_FMR_FINIT ; // Enter filter initialization mode.
332329
333- BXCAN1 -> FFA1R =
334- (BXCAN1 -> FFA1R & 0xFFFFC000U ) | 0x00002AAAU ; // Alternate the filters between FIFO0 & FIFO1.
335- }
330+ BXCAN1 -> FM1R &= 0xFFFFC000U ; // Identifier Mask mode. (18 MSB are reserved.)
331+ BXCAN1 -> FS1R |= 0x00003FFFU ; // All 32-bit filters. (18 MSB are reserved.)
332+
333+ BXCAN1 -> FFA1R =
334+ (BXCAN1 -> FFA1R & 0xFFFFC000U ) | 0x00002AAAU ; // Alternate the filters between FIFO0 & FIFO1.
335+ }
336336
337- // Configure one "accept all" filter and enable it.
338- BXCAN1 -> FilterRegister [filter_index ].FR1 = 0U ; // Accept all.
339- BXCAN1 -> FilterRegister [filter_index ].FR2 = 0U ; // Accept all.
340- BXCAN1 -> FA1R |= (1U << filter_index ); // One filter enabled
337+ // Configure one "accept all" filter and enable it.
338+ BXCAN1 -> FilterRegister [0 ].FR1 = 0U ;
339+ BXCAN1 -> FilterRegister [0 ].FR2 = 0U ;
340+ BXCAN1 -> FA1R |= (1U << 0U );
341341
342- bxcan_base -> FMR &= ~BXCAN_FMR_FINIT ; // Leave initialization mode.
342+ BXCAN1 -> FMR &= ~BXCAN_FMR_FINIT ; // Leave initialization mode.
343+ }
343344 out_status = true;
344345 }
345346
@@ -360,7 +361,7 @@ void bxCANConfigureFilters(const uint8_t iface_index, //
360361 }
361362 else if ((iface_index == 1U ) && (BXCAN_MAX_IFACE_INDEX == 1U ))
362363 {
363- filter_index_offset = (uint8_t )(BXCAN_NUM_ACCEPTANCE_FILTERS );
364+ filter_index_offset = (uint8_t ) (BXCAN_NUM_ACCEPTANCE_FILTERS );
364365 }
365366 else
366367 {
@@ -370,23 +371,17 @@ void bxCANConfigureFilters(const uint8_t iface_index, //
370371 // Only modify the registers if the filter register index offset is valid.
371372 if (filter_index_offset != 0xFF )
372373 {
373- // First we disable all filters. This may cause momentary RX frame losses, but the application
374- // should be able to tolerate that. The number of reserved bits is different for devices with
375- // one or two bxCAN interfaces.
376- if (BXCAN_MAX_IFACE_INDEX > 0 )
377- {
378- BXCAN1 -> FA1R &= 0xF0000000U ; // Dual CAN: 28 filter banks, 4 MSB reserved.
379- }
380- else
381- {
382- BXCAN1 -> FA1R &= 0xFFFFC000U ; // Single CAN: 14 filter banks, 18 MSB reserved.
383- }
384-
374+ BXCAN1 -> FMR |= BXCAN_FMR_FINIT ; // This is required for disabling filters.
385375 // Having filters disabled we can update the configuration.
386376 // Register mapping: FR1 - ID, FR2 - Mask
387377 for (uint8_t i = 0U ; i < (uint8_t ) BXCAN_NUM_ACCEPTANCE_FILTERS ; i ++ )
388378 {
389- // Converting the ID and the Mask into the representation that can be chewed by the hardware.
379+ const BxCANFilterParams * const cfg = params + i ;
380+ const uint8_t filter_index = i + filter_index_offset ;
381+
382+ BXCAN1 -> FA1R &= ~(1U << filter_index ); // Disable the filter first. Only re-enable later if needed.
383+
384+ // Convert the filter to the register format.
390385 //
391386 // The logic of the hardware acceptance filters can be described as follows:
392387 //
@@ -420,33 +415,25 @@ void bxCANConfigureFilters(const uint8_t iface_index, //
420415 // 1 1 0 0
421416 // 1 0 1 0
422417 // 1 1 1 1
423- uint32_t id = 0 ;
424- uint32_t mask = 0 ;
425-
426- const BxCANFilterParams * const cfg = params + i ;
427-
428- // Convert the filter to the register format.
418+ //
429419 // The special case of a filter entry set to {0, 0} (all bits zero) signifies that the filter should block
430420 // all traffic. This is done to improve the API, avoiding a magic number. Detect this, and leave that filter
431421 // disabled to block all traffic as there is no set of filter values that achieves this. Eg: {0, 0x1FFFFFFF}
432422 // will still allow data with ID = 0 to pass. (Setting a {0, 0} filter in the registers as-such would
433423 // actually pass all traffic.)
434- if ((cfg -> extended_id != 0U ) ||
435- (cfg -> extended_mask != 0U )) // Only configure and enable non-{0, 0} filters.
424+ if ((cfg -> extended_id != 0U ) || (cfg -> extended_mask != 0U ))
436425 {
437- id = (cfg -> extended_id & BXCAN_FRAME_EXT_ID_MASK ) << 3U ;
438- mask = (cfg -> extended_mask & BXCAN_FRAME_EXT_ID_MASK ) << 3U ;
439- id |=
440- BXCAN_RIR_IDE ; // Must be set to accept extended-ID frames. (The mask bit for IDE is already zero.)
426+ const uint32_t id = ((cfg -> extended_id & BXCAN_FRAME_EXT_ID_MASK ) << 3U ) | BXCAN_RIR_IDE ;
427+ const uint32_t mask =
428+ ((cfg -> extended_mask & BXCAN_FRAME_EXT_ID_MASK ) << 3U ) | BXCAN_RIR_IDE | BXCAN_RIR_RTR ;
441429
442- // Applying the converted representation to the registers.
443- const uint8_t filter_index = i + filter_index_offset ;
444430 BXCAN1 -> FilterRegister [filter_index ].FR1 = id ;
445431 BXCAN1 -> FilterRegister [filter_index ].FR2 = mask ;
446432
447433 BXCAN1 -> FA1R |= (1U << filter_index ); // Enable the filter.
448434 }
449435 }
436+ BXCAN1 -> FMR &= ~BXCAN_FMR_FINIT ;
450437 }
451438}
452439
@@ -698,21 +685,21 @@ bool bxCANPop(const uint8_t iface_index, //
698685
699686 * out_extended_can_id = convertRegisterToFrameID (mb -> RIR );
700687
701- * out_payload_size = (uint8_t )(mb -> RDTR & BXCAN_RDTR_DLC_MASK );
688+ * out_payload_size = (uint8_t ) (mb -> RDTR & BXCAN_RDTR_DLC_MASK );
702689
703690 // Caching to regular (non volatile) memory for faster reads
704691 const uint32_t rdlr = mb -> RDLR ;
705692 const uint32_t rdhr = mb -> RDHR ;
706693
707694 uint8_t * out_ptr = (uint8_t * ) out_payload ;
708- * out_ptr ++ = (uint8_t )(0xFFU & (rdlr >> 0U ));
709- * out_ptr ++ = (uint8_t )(0xFFU & (rdlr >> 8U ));
710- * out_ptr ++ = (uint8_t )(0xFFU & (rdlr >> 16U ));
711- * out_ptr ++ = (uint8_t )(0xFFU & (rdlr >> 24U ));
712- * out_ptr ++ = (uint8_t )(0xFFU & (rdhr >> 0U ));
713- * out_ptr ++ = (uint8_t )(0xFFU & (rdhr >> 8U ));
714- * out_ptr ++ = (uint8_t )(0xFFU & (rdhr >> 16U ));
715- * out_ptr ++ = (uint8_t )(0xFFU & (rdhr >> 24U ));
695+ * out_ptr ++ = (uint8_t ) (0xFFU & (rdlr >> 0U ));
696+ * out_ptr ++ = (uint8_t ) (0xFFU & (rdlr >> 8U ));
697+ * out_ptr ++ = (uint8_t ) (0xFFU & (rdlr >> 16U ));
698+ * out_ptr ++ = (uint8_t ) (0xFFU & (rdlr >> 24U ));
699+ * out_ptr ++ = (uint8_t ) (0xFFU & (rdhr >> 0U ));
700+ * out_ptr ++ = (uint8_t ) (0xFFU & (rdhr >> 8U ));
701+ * out_ptr ++ = (uint8_t ) (0xFFU & (rdhr >> 16U ));
702+ * out_ptr ++ = (uint8_t ) (0xFFU & (rdhr >> 24U ));
716703
717704 // Release FIFO entry we just read
718705 * RFxR [i ] |= BXCAN_RFR_RFOM | BXCAN_RFR_FOVR | BXCAN_RFR_FULL ;
@@ -762,7 +749,7 @@ bool bxCANComputeTimings(const uint32_t peripheral_clock_rate, //
762749 // 500 kbps 16 17
763750 // 250 kbps 16 17
764751 // 125 kbps 16 17
765- const uint8_t max_quanta_per_bit = (uint8_t )((target_bitrate >= 1000000 ) ? 10U : 17U );
752+ const uint8_t max_quanta_per_bit = (uint8_t ) ((target_bitrate >= 1000000 ) ? 10U : 17U );
766753 BXCAN_ASSERT (max_quanta_per_bit <= (MaxBS1 + MaxBS2 ));
767754
768755 static const uint16_t MaxSamplePointLocationPermill = 900U ;
@@ -778,7 +765,7 @@ bool bxCANComputeTimings(const uint32_t peripheral_clock_rate, //
778765 const uint32_t prescaler_bs = peripheral_clock_rate / target_bitrate ;
779766
780767 // Searching for such prescaler value so that the number of quanta per bit is highest.
781- uint8_t bs1_bs2_sum = (uint8_t )(max_quanta_per_bit - 1U );
768+ uint8_t bs1_bs2_sum = (uint8_t ) (max_quanta_per_bit - 1U );
782769
783770 while ((prescaler_bs % (1U + bs1_bs2_sum )) != 0U )
784771 {
@@ -812,17 +799,17 @@ bool bxCANComputeTimings(const uint32_t peripheral_clock_rate, //
812799 // Since the optimal solution is so close to the maximum, we prepare two solutions, and then pick the best one:
813800 // - With rounding to nearest
814801 // - With rounding to zero
815- uint8_t bs1 = (uint8_t )(((7U * bs1_bs2_sum - 1U ) + 4U ) / 8U ); // Trying rounding to nearest first
816- uint8_t bs2 = (uint8_t )(bs1_bs2_sum - bs1 );
802+ uint8_t bs1 = (uint8_t ) (((7U * bs1_bs2_sum - 1U ) + 4U ) / 8U ); // Trying rounding to nearest first
803+ uint8_t bs2 = (uint8_t ) (bs1_bs2_sum - bs1 );
817804 BXCAN_ASSERT (bs1_bs2_sum > bs1 );
818805
819806 {
820- const uint16_t sample_point_permill = (uint16_t )(1000U * (1U + bs1 ) / (1U + bs1 + bs2 ));
807+ const uint16_t sample_point_permill = (uint16_t ) (1000U * (1U + bs1 ) / (1U + bs1 + bs2 ));
821808
822809 if (sample_point_permill > MaxSamplePointLocationPermill ) // Strictly more!
823810 {
824- bs1 = (uint8_t )((7U * bs1_bs2_sum - 1U ) / 8U ); // Nope, too far; now rounding to zero
825- bs2 = (uint8_t )(bs1_bs2_sum - bs1 );
811+ bs1 = (uint8_t ) ((7U * bs1_bs2_sum - 1U ) / 8U ); // Nope, too far; now rounding to zero
812+ bs2 = (uint8_t ) (bs1_bs2_sum - bs1 );
826813 }
827814 }
828815
0 commit comments