1616
1717#include "hal/twai_types.h"
1818
19- static bool reserved_can ;
19+ static byte reserved_can_instance ; /* Bit assigned instances 0x01 (CAN0) or 0x02 (CAN1) 0x00-NoneAssigned 0x03-Both Assigned*/
20+
21+ #define TWAI0 REG_TWAI_BASE(0) /**< \brief (CAN0) APB Base Address */
22+ #define TWAI1 REG_TWAI_BASE(1) /**< \brief (CAN1) APB Base Address */
23+ #define TWAI_INST_NUM 2 /**< \brief (CAN) Number of instances */
24+
25+ static twai_handle_t twai_bus_0 ;
26+ static twai_handle_t twai_bus_1 ;
27+ static twai_handle_t * const twai_insts [TWAI_INST_NUM ] = { & twai_bus_0 , & twai_bus_1 };
2028
2129static twai_timing_config_t get_t_config (int baudrate ) {
2230 switch (baudrate ) {
@@ -100,18 +108,36 @@ static twai_timing_config_t get_t_config(int baudrate) {
100108void common_hal_canio_can_construct (canio_can_obj_t * self , const mcu_pin_obj_t * tx , const mcu_pin_obj_t * rx , int baudrate , bool loopback , bool silent ) {
101109#define DIV_ROUND (a , b ) (((a) + (b) / 2) / (b))
102110#define DIV_ROUND_UP (a , b ) (((a) + (b) - 1) / (b))
103- if (reserved_can ) {
111+ if (reserved_can_instance == 3 ) {
104112 mp_raise_ValueError (MP_ERROR_TEXT ("All CAN peripherals are in use" ));
105113 }
106114
107115 if (loopback && silent ) {
108116 mp_raise_ValueError (MP_ERROR_TEXT ("loopback + silent mode not supported by peripheral" ));
109117 }
110118
119+ byte this_can_instance = 0 ;
120+ if (reserved_can_instance == 0x00 ){ /* None assigned */
121+ reserved_can_instance = 0x01 ; /* First instance is assigned*/
122+ this_can_instance = 0 ; /* Idx of selected instance */
123+ }
124+ else if (reserved_can_instance == 0x01 ) /* First instance allready assigned */
125+ {
126+ reserved_can_instance = 0x03 ; /* Second instance also assigned */
127+ this_can_instance = 1 ; /* Idx of selected instance */
128+
129+ }else if (reserved_can_instance == 0x02 ) /* Second instance is assigned */
130+ {
131+ reserved_can_instance = 0x03 ; /* first instance also assigned*/
132+ this_can_instance = 0 ; /* Idx of selected instance */
133+ }
134+
111135 twai_timing_config_t t_config = get_t_config (baudrate );
112- twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT ( -1 , -1 , TWAI_MODE_NORMAL );
136+ twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT_V2 ( this_can_instance , -1 , -1 , TWAI_MODE_NORMAL );
113137 g_config .tx_io = tx -> number ;
114138 g_config .rx_io = rx -> number ;
139+ g_config .controller_id = this_can_instance ; /* To ease later de-initing of proper instance */
140+
115141 if (loopback ) {
116142 g_config .mode = TWAI_MODE_NO_ACK ;
117143 }
@@ -120,17 +146,16 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, const mcu_pin_obj_t *
120146 }
121147
122148 twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL ();
123-
124- esp_err_t result = twai_driver_install (& g_config , & t_config , & f_config );
149+ esp_err_t result = twai_driver_install_v2 (& g_config , & t_config , & f_config , twai_insts [this_can_instance ]);
125150 if (result == ESP_ERR_NO_MEM ) {
126151 mp_raise_msg (& mp_type_MemoryError , MP_ERROR_TEXT ("ESP-IDF memory allocation failed" ));
127152 } else if (result == ESP_ERR_INVALID_ARG ) {
128153 raise_ValueError_invalid_pins ();
129154 } else if (result != ESP_OK ) {
130155 mp_raise_OSError_msg_varg (MP_ERROR_TEXT ("twai_driver_install returned esp-idf error #%d" ), (int )result );
131156 }
132-
133- result = twai_start ( );
157+
158+ result = twai_start_v2 ( * twai_insts [ this_can_instance ] );
134159 if (result != ESP_OK ) {
135160 mp_raise_OSError_msg_varg (MP_ERROR_TEXT ("twai_start returned esp-idf error #%d" ), (int )result );
136161 }
@@ -144,9 +169,15 @@ void common_hal_canio_can_construct(canio_can_obj_t *self, const mcu_pin_obj_t *
144169 claim_pin (tx );
145170 claim_pin (rx );
146171
147- reserved_can = true;
172+ self -> twai_driver_handle = twai_insts [this_can_instance ];
173+ self -> instance = this_can_instance ;
174+
175+
148176}
149177
178+
179+
180+
150181bool common_hal_canio_can_loopback_get (canio_can_obj_t * self ) {
151182 return self -> loopback ;
152183}
@@ -157,19 +188,21 @@ int common_hal_canio_can_baudrate_get(canio_can_obj_t *self) {
157188
158189int common_hal_canio_can_transmit_error_count_get (canio_can_obj_t * self ) {
159190 twai_status_info_t info ;
160- twai_get_status_info ( & info );
191+ twai_get_status_info_v2 ( * self -> twai_driver_handle , & info );
161192 return info .tx_error_counter ;
162193}
163194
164195int common_hal_canio_can_receive_error_count_get (canio_can_obj_t * self ) {
165196 twai_status_info_t info ;
166- twai_get_status_info ( & info );
197+ twai_get_status_info_v2 ( * self -> twai_driver_handle , & info );
167198 return info .rx_error_counter ;
168199}
169200
201+
170202canio_bus_state_t common_hal_canio_can_state_get (canio_can_obj_t * self ) {
171203 twai_status_info_t info ;
172- twai_get_status_info (& info );
204+
205+ twai_get_status_info_v2 ( * self -> twai_driver_handle ,& info );
173206 if (info .state == TWAI_STATE_BUS_OFF || info .state == TWAI_STATE_RECOVERING ) {
174207 return BUS_STATE_OFF ;
175208 }
@@ -182,29 +215,30 @@ canio_bus_state_t common_hal_canio_can_state_get(canio_can_obj_t *self) {
182215 return BUS_STATE_ERROR_ACTIVE ;
183216}
184217
185- static void can_restart (void ) {
218+
219+ static void can_restart (canio_can_obj_t * self ) {
186220 twai_status_info_t info ;
187- twai_get_status_info ( & info );
221+ twai_get_status_info_v2 ( * self -> twai_driver_handle , & info );
188222 if (info .state != TWAI_STATE_BUS_OFF ) {
189223 return ;
190224 }
191- twai_initiate_recovery ( );
225+ twai_initiate_recovery_v2 ( * self -> twai_driver_handle );
192226 // wait 100ms (hard coded for now) for bus to recover
193227 uint64_t deadline = port_get_raw_ticks (NULL ) + 100 ;
194228 do {
195- twai_get_status_info ( & info );
229+ twai_get_status_info_v2 ( * self -> twai_driver_handle , & info );
196230 } while (port_get_raw_ticks (NULL ) < deadline && (info .state == TWAI_STATE_BUS_OFF || info .state == TWAI_STATE_RECOVERING ));
197231}
198232
199233static void canio_maybe_auto_restart (canio_can_obj_t * self ) {
200234 if (self -> auto_restart ) {
201- can_restart ();
235+ can_restart (self );
202236 }
203237}
204238
205239void common_hal_canio_can_restart (canio_can_obj_t * self ) {
206240 if (!common_hal_canio_can_auto_restart_get (self )) {
207- can_restart ();
241+ can_restart (self );
208242 }
209243}
210244
@@ -217,6 +251,9 @@ void common_hal_canio_can_auto_restart_set(canio_can_obj_t *self, bool value) {
217251 canio_maybe_auto_restart (self );
218252}
219253
254+
255+
256+
220257void common_hal_canio_can_send (canio_can_obj_t * self , mp_obj_t message_in ) {
221258 canio_maybe_auto_restart (self );
222259 canio_message_obj_t * message = message_in ;
@@ -232,7 +269,7 @@ void common_hal_canio_can_send(canio_can_obj_t *self, mp_obj_t message_in) {
232269 memcpy (message_out .data , message -> data , message -> size );
233270 }
234271 // Allow transmission to occur in background
235- twai_transmit ( & message_out , 0 );
272+ twai_transmit_v2 ( * self -> twai_driver_handle , & message_out , 0 );
236273}
237274
238275bool common_hal_canio_can_silent_get (canio_can_obj_t * self ) {
@@ -251,18 +288,26 @@ void common_hal_canio_can_check_for_deinit(canio_can_obj_t *self) {
251288
252289void common_hal_canio_can_deinit (canio_can_obj_t * self ) {
253290 if (self -> tx_pin ) {
254- (void )twai_stop ( );
255- (void )twai_driver_uninstall ( );
291+ (void )twai_stop_v2 ( * self -> twai_driver_handle );
292+ (void )twai_driver_uninstall_v2 ( * self -> twai_driver_handle );
256293 reset_pin_number (self -> tx_pin -> number );
257294 reset_pin_number (self -> rx_pin -> number );
258- reserved_can = false;
295+
296+ if (self -> instance == 0 ){
297+ reserved_can_instance &=0x02 ; /* free first instance - clear 1st bit */
298+ }else if (self -> instance == 1 ){
299+ reserved_can_instance &=0x01 ; /* free second instance - clear 2nd bit */
300+ }
301+
259302 }
260303 self -> tx_pin = NULL ;
261304 self -> rx_pin = NULL ;
262305}
263306
264307void common_hal_canio_reset (void ) {
265- (void )twai_stop ();
266- (void )twai_driver_uninstall ();
267- reserved_can = false;
308+ (void )twai_stop_v2 (* twai_insts [0 ]);
309+ (void )twai_driver_uninstall_v2 (* twai_insts [0 ]);
310+ (void )twai_stop_v2 (* twai_insts [1 ]);
311+ (void )twai_driver_uninstall_v2 (* twai_insts [1 ]);
312+ reserved_can_instance = 0 ; /* unassign both bits */
268313}
0 commit comments