Skip to content

Commit 6768325

Browse files
committed
stm32: Add can_get_state() function, use from pyb.CAN.
This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
1 parent cda49be commit 6768325

4 files changed

Lines changed: 48 additions & 25 deletions

File tree

ports/stm32/can.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,25 @@ HAL_StatusTypeDef can_transmit(CAN_HandleTypeDef *hcan, CanTxMsgTypeDef *txmsg,
307307
}
308308
}
309309

310+
can_state_t can_get_state(CAN_HandleTypeDef *can) {
311+
uint32_t esr;
312+
313+
if (can->State == HAL_CAN_STATE_RESET) {
314+
return CAN_STATE_STOPPED;
315+
}
316+
317+
esr = can->Instance->ESR;
318+
if (esr & CAN_ESR_BOFF) {
319+
return CAN_STATE_BUS_OFF;
320+
} else if (esr & CAN_ESR_EPVF) {
321+
return CAN_STATE_ERROR_PASSIVE;
322+
} else if (esr & CAN_ESR_EWGF) {
323+
return CAN_STATE_ERROR_WARNING;
324+
} else {
325+
return CAN_STATE_ERROR_ACTIVE;
326+
}
327+
}
328+
310329
// Workaround for the __HAL_CAN macros expecting a CAN_HandleTypeDef which we
311330
// don't have in the ISR. Using this "fake" struct instead of CAN_HandleTypeDef
312331
// so it's not possible to accidentally call an API that uses one of the other

ports/stm32/can.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ void can_disable_rx_interrupts(CAN_HandleTypeDef *can, can_rx_fifo_t fifo);
101101
// Interrupt for CAN_INT_MESSAGE_RECEIVED is only enabled if enable_msg_received is set.
102102
void can_enable_rx_interrupts(CAN_HandleTypeDef *can, can_rx_fifo_t fifo, bool enable_msg_received);
103103

104+
can_state_t can_get_state(CAN_HandleTypeDef *can);
105+
104106
// Implemented in pyb_can.c, called from lower layer
105107
extern void can_irq_handler(uint can_id, can_int_t interrupt, can_rx_fifo_t fifo);
106108

ports/stm32/fdcan.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,30 @@ int can_receive(FDCAN_HandleTypeDef *can, can_rx_fifo_t fifo, FDCAN_RxHeaderType
359359
return 0; // success
360360
}
361361

362+
can_state_t can_get_state(CAN_HandleTypeDef *can) {
363+
uint32_t psr;
364+
365+
if (can->State != HAL_FDCAN_STATE_BUSY) {
366+
// The HAL states which map to "stopped" are:
367+
// HAL_FDCAN_STATE_RESET - peripheral never initialised
368+
// HAL_FDCAN_STATE_READY - CAN is stopped (i.e. HAL_FDCAN_CAN_Stop() called)
369+
// HAL_FDCAN_STATE_ERROR - Internal transition timeout, mostly relates to
370+
// low-power states we currently don't use
371+
return CAN_STATE_STOPPED;
372+
}
373+
374+
psr = can->Instance->PSR;
375+
if (psr & FDCAN_PSR_BO) {
376+
return CAN_STATE_BUS_OFF;
377+
} else if (psr & FDCAN_PSR_EP) {
378+
return CAN_STATE_ERROR_PASSIVE;
379+
} else if (psr & FDCAN_PSR_EW) {
380+
return CAN_STATE_ERROR_WARNING;
381+
} else {
382+
return CAN_STATE_ERROR_ACTIVE;
383+
}
384+
}
385+
362386
static void can_rx_irq_handler(uint can_id, CAN_TypeDef *instance, can_rx_fifo_t fifo) {
363387
uint32_t ints, rx_fifo_ints, error_ints;
364388

ports/stm32/pyb_can.c

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -408,33 +408,11 @@ static MP_DEFINE_CONST_FUN_OBJ_1(pyb_can_restart_obj, pyb_can_restart);
408408
// Get the state of the controller
409409
static mp_obj_t pyb_can_state(mp_obj_t self_in) {
410410
pyb_can_obj_t *self = MP_OBJ_TO_PTR(self_in);
411-
mp_int_t state = CAN_STATE_STOPPED;
412411
if (self->is_enabled) {
413-
CAN_TypeDef *can = self->can.Instance;
414-
#if MICROPY_HW_ENABLE_FDCAN
415-
uint32_t psr = can->PSR;
416-
if (psr & FDCAN_PSR_BO) {
417-
state = CAN_STATE_BUS_OFF;
418-
} else if (psr & FDCAN_PSR_EP) {
419-
state = CAN_STATE_ERROR_PASSIVE;
420-
} else if (psr & FDCAN_PSR_EW) {
421-
state = CAN_STATE_ERROR_WARNING;
422-
} else {
423-
state = CAN_STATE_ERROR_ACTIVE;
424-
}
425-
#else
426-
if (can->ESR & CAN_ESR_BOFF) {
427-
state = CAN_STATE_BUS_OFF;
428-
} else if (can->ESR & CAN_ESR_EPVF) {
429-
state = CAN_STATE_ERROR_PASSIVE;
430-
} else if (can->ESR & CAN_ESR_EWGF) {
431-
state = CAN_STATE_ERROR_WARNING;
432-
} else {
433-
state = CAN_STATE_ERROR_ACTIVE;
434-
}
435-
#endif
412+
return MP_OBJ_NEW_SMALL_INT(can_get_state(&self->can));
413+
} else {
414+
return MP_OBJ_NEW_SMALL_INT(CAN_STATE_STOPPED);
436415
}
437-
return MP_OBJ_NEW_SMALL_INT(state);
438416
}
439417
static MP_DEFINE_CONST_FUN_OBJ_1(pyb_can_state_obj, pyb_can_state);
440418

0 commit comments

Comments
 (0)