4747#define LIST32 (3)
4848
4949#if MICROPY_HW_ENABLE_FDCAN
50+ // Interface compatibility for the classic CAN controller HAL
5051#define CAN_TypeDef FDCAN_GlobalTypeDef
5152#define CAN_HandleTypeDef FDCAN_HandleTypeDef
5253#define CanTxMsgTypeDef FDCAN_TxHeaderTypeDef
5354#define CanRxMsgTypeDef FDCAN_RxHeaderTypeDef
55+
56+ #define CAN_MODE_NORMAL FDCAN_MODE_NORMAL
57+ #define CAN_MODE_LOOPBACK FDCAN_MODE_EXTERNAL_LOOPBACK
58+ #define CAN_MODE_SILENT FDCAN_MODE_BUS_MONITORING
59+ #define CAN_MODE_SILENT_LOOPBACK FDCAN_MODE_INTERNAL_LOOPBACK
60+
61+ // FDCAN peripheral has independent indexes for standard id vs extended id filters
62+ #if defined(STM32G4 )
63+ #define CAN_HW_MAX_STD_FILTER 28
64+ #define CAN_HW_MAX_EXT_FILTER 8
65+ #elif defined(STM32H7 )
66+ // The RAM filtering section is configured for 64 x 1 word elements for 11-bit standard
67+ // identifiers, and 31 x 2 words elements for 29-bit extended identifiers.
68+ // The total number of words reserved for the filtering per FDCAN instance is 126 words.
69+ #define CAN_HW_MAX_STD_FILTER 64
70+ #define CAN_HW_MAX_EXT_FILTER 31
5471#endif
5572
56- enum {
73+ // Value reported via machine.CAN.FILTER_MAX, somewhat optimistic as requires using
74+ // the exact numbers of each type of filter.
75+ #define CAN_HW_MAX_FILTER (CAN_HW_MAX_STD_FILTER + CAN_HW_MAX_EXT_FILTER)
76+
77+ #else
78+
79+ // CAN1 & CAN2 have 28 filters which can be arbitrarily split, but machine.CAN
80+ // implementation hard-codes to 14/14. CAN3 has 14 independent filters.
81+ #define CAN_HW_MAX_FILTER 14
82+
83+ #endif
84+
85+ typedef enum {
5786 CAN_STATE_STOPPED ,
5887 CAN_STATE_ERROR_ACTIVE ,
5988 CAN_STATE_ERROR_WARNING ,
6089 CAN_STATE_ERROR_PASSIVE ,
6190 CAN_STATE_BUS_OFF ,
62- };
91+ } can_state_t ;
6392
6493typedef enum _rx_state_t {
6594 RX_STATE_FIFO_EMPTY = 0 ,
@@ -76,8 +105,31 @@ typedef enum {
76105 CAN_INT_ERR_BUS_OFF ,
77106 CAN_INT_ERR_PASSIVE ,
78107 CAN_INT_ERR_WARNING ,
108+
109+ CAN_INT_TX_COMPLETE ,
79110} can_int_t ;
80111
112+ typedef enum {
113+ CAN_TX_FIFO ,
114+ CAN_TX_QUEUE ,
115+ } can_tx_mode_t ;
116+
117+ // Counter data as used by pyb.CAN.info() and machine.CAN.get_counters()
118+ typedef struct {
119+ unsigned tec ;
120+ unsigned rec ;
121+ unsigned tx_pending ;
122+ unsigned rx_fifo0_pending ;
123+ unsigned rx_fifo1_pending ;
124+ } can_counters_t ;
125+
126+ #if defined(STM32H7 )
127+ #define CAN_TX_QUEUE_LEN 16
128+ #else
129+ // FDCAN STM32G4, bxCAN
130+ #define CAN_TX_QUEUE_LEN 3
131+ #endif
132+
81133// RX FIFO numbering
82134//
83135// Note: For traditional CAN peripheral, the values of CAN_FIFO0 and CAN_FIFO1 are the same
@@ -87,12 +139,29 @@ typedef enum {
87139 CAN_RX_FIFO1 ,
88140} can_rx_fifo_t ;
89141
90- bool can_init (CAN_HandleTypeDef * can , int can_id , uint32_t mode , uint32_t prescaler , uint32_t sjw , uint32_t bs1 , uint32_t bs2 , bool auto_restart );
142+ bool can_init (CAN_HandleTypeDef * can , int can_id , can_tx_mode_t tx_mode , uint32_t mode , uint32_t prescaler , uint32_t sjw , uint32_t bs1 , uint32_t bs2 , bool auto_restart );
91143void can_deinit (CAN_HandleTypeDef * can );
92144
145+ uint32_t can_get_source_freq (void );
146+
93147int can_receive (CAN_HandleTypeDef * can , can_rx_fifo_t fifo , CanRxMsgTypeDef * msg , uint8_t * data , uint32_t timeout_ms );
148+
149+ // Transmit a CAN frame (callee to choose the transmit slot). Used by pyb.CAN only, does not enable TX interrupt
150+ // On FDCAN this function invalidates the 'txmsg' structure if successful.
94151HAL_StatusTypeDef can_transmit (CAN_HandleTypeDef * hcan , CanTxMsgTypeDef * txmsg , uint8_t * data , uint32_t Timeout );
95152
153+ // Tell the controller to copy a CAN frame copied to 'index' and start transmitting
154+ // On FDCAN this function invalidates the 'txmsg' structure if successful.
155+ HAL_StatusTypeDef can_transmit_buf_index (CAN_HandleTypeDef * hcan , int index , CanTxMsgTypeDef * txmsg , const uint8_t * data );
156+
157+ // Cancel the pending transmission in the specified buffer index. Returns after buffer stops transmitting.
158+ // Result is true if buffer was transmitting, false if not transmitting (or finished transmitting before cancellation)
159+ bool can_cancel_transmit (CAN_HandleTypeDef * hcan , int index );
160+
161+ // Get the lowest index of a buffer in FAILED or SUCCEEDED state, or -1 if none exists
162+ // Calling this function also re-enables the TX done IRQ for this peripheral
163+ int can_get_transmit_finished (CAN_HandleTypeDef * hcan , bool * is_success );
164+
96165// Disable all CAN receive interrupts for a FIFO
97166void can_disable_rx_interrupts (CAN_HandleTypeDef * can , can_rx_fifo_t fifo );
98167
@@ -101,22 +170,33 @@ void can_disable_rx_interrupts(CAN_HandleTypeDef *can, can_rx_fifo_t fifo);
101170// Interrupt for CAN_INT_MESSAGE_RECEIVED is only enabled if enable_msg_received is set.
102171void can_enable_rx_interrupts (CAN_HandleTypeDef * can , can_rx_fifo_t fifo , bool enable_msg_received );
103172
173+ // Disable all pending TX interrupts (ahead of restart or deinit). Will re-enable n next transmit
174+ void can_disable_tx_interrupts (CAN_HandleTypeDef * can );
175+
104176can_state_t can_get_state (CAN_HandleTypeDef * can );
105177
178+ void can_get_counters (CAN_HandleTypeDef * can , can_counters_t * counters );
179+
180+ // Restart controller (clears error states). Caller expected to check controller initialised already.
181+ void can_restart (CAN_HandleTypeDef * can );
182+
106183// Implemented in pyb_can.c, called from lower layer
107- extern void can_irq_handler (uint can_id , can_int_t interrupt , can_rx_fifo_t fifo );
184+ extern void pyb_can_irq_handler (uint can_id , can_int_t interrupt , can_rx_fifo_t fifo );
185+
186+ // Implemented in machine_can.c, called from lower layer
187+ extern void machine_can_irq_handler (uint can_id , can_int_t interrupt );
108188
109189#if MICROPY_HW_ENABLE_FDCAN
110190
111- static inline unsigned can_rx_pending (CAN_HandleTypeDef * can , can_rx_fifo_t fifo ) {
191+ static inline unsigned can_is_rx_pending (CAN_HandleTypeDef * can , can_rx_fifo_t fifo ) {
112192 return HAL_FDCAN_GetRxFifoFillLevel (can , fifo == CAN_RX_FIFO0 ? FDCAN_RX_FIFO0 : FDCAN_RX_FIFO1 );
113193}
114194
115195void can_clearfilter (CAN_HandleTypeDef * can , uint32_t filter_num , bool is_extid );
116196
117197#else
118198
119- static inline unsigned can_rx_pending (CAN_HandleTypeDef * can , can_rx_fifo_t fifo ) {
199+ static inline unsigned can_is_rx_pending (CAN_HandleTypeDef * can , can_rx_fifo_t fifo ) {
120200 return __HAL_CAN_MSG_PENDING (can , fifo == CAN_RX_FIFO0 ? CAN_FIFO0 : CAN_FIFO1 );
121201}
122202
0 commit comments