@@ -89,6 +89,9 @@ typedef struct _pyb_can_obj_t {
8989 bool extframe : 1 ;
9090 byte rx_state0 ;
9191 byte rx_state1 ;
92+ uint16_t num_error_warning ;
93+ uint16_t num_error_passive ;
94+ uint16_t num_bus_off ;
9295 CAN_HandleTypeDef can ;
9396} pyb_can_obj_t ;
9497
@@ -103,6 +106,7 @@ STATIC bool can_init(pyb_can_obj_t *can_obj) {
103106 uint32_t GPIO_Pin = 0 ;
104107 uint8_t GPIO_AF_CANx = 0 ;
105108 GPIO_TypeDef * GPIO_Port = NULL ;
109+ uint32_t sce_irq = 0 ;
106110
107111 switch (can_obj -> can_id ) {
108112 // CAN1 is on RX,TX = Y3,Y4 = PB9,PB9
@@ -111,6 +115,7 @@ STATIC bool can_init(pyb_can_obj_t *can_obj) {
111115 GPIO_AF_CANx = GPIO_AF9_CAN1 ;
112116 GPIO_Port = GPIOB ;
113117 GPIO_Pin = GPIO_PIN_8 | GPIO_PIN_9 ;
118+ sce_irq = CAN1_SCE_IRQn ;
114119 __CAN1_CLK_ENABLE ();
115120 break ;
116121
@@ -121,6 +126,7 @@ STATIC bool can_init(pyb_can_obj_t *can_obj) {
121126 GPIO_AF_CANx = GPIO_AF9_CAN2 ;
122127 GPIO_Port = GPIOB ;
123128 GPIO_Pin = GPIO_PIN_12 | GPIO_PIN_13 ;
129+ sce_irq = CAN2_SCE_IRQn ;
124130 __CAN1_CLK_ENABLE (); // CAN2 is a "slave" and needs CAN1 enabled as well
125131 __CAN2_CLK_ENABLE ();
126132 break ;
@@ -144,6 +150,14 @@ STATIC bool can_init(pyb_can_obj_t *can_obj) {
144150 HAL_CAN_Init (& can_obj -> can );
145151
146152 can_obj -> is_enabled = true;
153+ can_obj -> num_error_warning = 0 ;
154+ can_obj -> num_error_passive = 0 ;
155+ can_obj -> num_bus_off = 0 ;
156+
157+ __HAL_CAN_ENABLE_IT (& can_obj -> can , CAN_IT_ERR | CAN_IT_BOF | CAN_IT_EPV | CAN_IT_EWG );
158+
159+ HAL_NVIC_SetPriority (sce_irq , IRQ_PRI_CAN , IRQ_SUBPRI_CAN );
160+ HAL_NVIC_EnableIRQ (sce_irq );
147161
148162 return true;
149163}
@@ -459,13 +473,15 @@ STATIC mp_obj_t pyb_can_deinit(mp_obj_t self_in) {
459473 if (self -> can .Instance == CAN1 ) {
460474 HAL_NVIC_DisableIRQ (CAN1_RX0_IRQn );
461475 HAL_NVIC_DisableIRQ (CAN1_RX1_IRQn );
476+ HAL_NVIC_DisableIRQ (CAN1_SCE_IRQn );
462477 __CAN1_FORCE_RESET ();
463478 __CAN1_RELEASE_RESET ();
464479 __CAN1_CLK_DISABLE ();
465480 #if defined(CAN2 )
466481 } else if (self -> can .Instance == CAN2 ) {
467482 HAL_NVIC_DisableIRQ (CAN2_RX0_IRQn );
468483 HAL_NVIC_DisableIRQ (CAN2_RX1_IRQn );
484+ HAL_NVIC_DisableIRQ (CAN2_SCE_IRQn );
469485 __CAN2_FORCE_RESET ();
470486 __CAN2_RELEASE_RESET ();
471487 __CAN2_CLK_DISABLE ();
@@ -512,6 +528,36 @@ STATIC mp_obj_t pyb_can_state(mp_obj_t self_in) {
512528}
513529STATIC MP_DEFINE_CONST_FUN_OBJ_1 (pyb_can_state_obj , pyb_can_state );
514530
531+ // Get info about error states and TX/RX buffers
532+ STATIC mp_obj_t pyb_can_info (size_t n_args , const mp_obj_t * args ) {
533+ pyb_can_obj_t * self = MP_OBJ_TO_PTR (args [0 ]);
534+ mp_obj_list_t * list ;
535+ if (n_args == 1 ) {
536+ list = MP_OBJ_TO_PTR (mp_obj_new_list (8 , NULL ));
537+ } else {
538+ if (!MP_OBJ_IS_TYPE (args [1 ], & mp_type_list )) {
539+ mp_raise_TypeError (NULL );
540+ }
541+ list = MP_OBJ_TO_PTR (args [1 ]);
542+ if (list -> len < 8 ) {
543+ mp_raise_ValueError (NULL );
544+ }
545+ }
546+ CAN_TypeDef * can = self -> can .Instance ;
547+ uint32_t esr = can -> ESR ;
548+ list -> items [0 ] = MP_OBJ_NEW_SMALL_INT (esr >> CAN_ESR_TEC_Pos & 0xff );
549+ list -> items [1 ] = MP_OBJ_NEW_SMALL_INT (esr >> CAN_ESR_REC_Pos & 0xff );
550+ list -> items [2 ] = MP_OBJ_NEW_SMALL_INT (self -> num_error_warning );
551+ list -> items [3 ] = MP_OBJ_NEW_SMALL_INT (self -> num_error_passive );
552+ list -> items [4 ] = MP_OBJ_NEW_SMALL_INT (self -> num_bus_off );
553+ int n_tx_pending = 0x01121223 >> ((can -> TSR >> CAN_TSR_TME_Pos & 7 ) << 2 ) & 0xf ;
554+ list -> items [5 ] = MP_OBJ_NEW_SMALL_INT (n_tx_pending );
555+ list -> items [6 ] = MP_OBJ_NEW_SMALL_INT (can -> RF0R >> CAN_RF0R_FMP0_Pos & 3 );
556+ list -> items [7 ] = MP_OBJ_NEW_SMALL_INT (can -> RF1R >> CAN_RF1R_FMP1_Pos & 3 );
557+ return MP_OBJ_FROM_PTR (list );
558+ }
559+ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (pyb_can_info_obj , 1 , 2 , pyb_can_info );
560+
515561/// \method any(fifo)
516562/// Return `True` if any message waiting on the FIFO, else `False`.
517563STATIC mp_obj_t pyb_can_any (mp_obj_t self_in , mp_obj_t fifo_in ) {
@@ -871,6 +917,7 @@ STATIC const mp_rom_map_elem_t pyb_can_locals_dict_table[] = {
871917 { MP_ROM_QSTR (MP_QSTR_deinit ), MP_ROM_PTR (& pyb_can_deinit_obj ) },
872918 { MP_ROM_QSTR (MP_QSTR_restart ), MP_ROM_PTR (& pyb_can_restart_obj ) },
873919 { MP_ROM_QSTR (MP_QSTR_state ), MP_ROM_PTR (& pyb_can_state_obj ) },
920+ { MP_ROM_QSTR (MP_QSTR_info ), MP_ROM_PTR (& pyb_can_info_obj ) },
874921 { MP_ROM_QSTR (MP_QSTR_any ), MP_ROM_PTR (& pyb_can_any_obj ) },
875922 { MP_ROM_QSTR (MP_QSTR_send ), MP_ROM_PTR (& pyb_can_send_obj ) },
876923 { MP_ROM_QSTR (MP_QSTR_recv ), MP_ROM_PTR (& pyb_can_recv_obj ) },
@@ -979,6 +1026,21 @@ void can_rx_irq_handler(uint can_id, uint fifo_id) {
9791026 }
9801027}
9811028
1029+ void can_sce_irq_handler (uint can_id ) {
1030+ pyb_can_obj_t * self = MP_STATE_PORT (pyb_can_obj_all )[can_id - 1 ];
1031+ if (self ) {
1032+ self -> can .Instance -> MSR = CAN_MSR_ERRI ;
1033+ uint32_t esr = self -> can .Instance -> ESR ;
1034+ if (esr & CAN_ESR_BOFF ) {
1035+ ++ self -> num_bus_off ;
1036+ } else if (esr & CAN_ESR_EPVF ) {
1037+ ++ self -> num_error_passive ;
1038+ } else if (esr & CAN_ESR_EWGF ) {
1039+ ++ self -> num_error_warning ;
1040+ }
1041+ }
1042+ }
1043+
9821044STATIC const mp_stream_p_t can_stream_p = {
9831045 //.read = can_read, // is read sensible for CAN?
9841046 //.write = can_write, // is write sensible for CAN?
0 commit comments