Skip to content

Commit d7e67fb

Browse files
committed
stm32/can: Add CAN.state() method to get the state of the controller.
This is useful for monitoring errors on the bus and knowing when a restart is needed.
1 parent 1272c3c commit d7e67fb

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

docs/library/pyb.CAN.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,20 @@ Methods
9999
and the controller will follow the CAN protocol to leave the bus-off state and
100100
go into the error active state.
101101

102+
.. method:: CAN.state()
103+
104+
Return the state of the controller. The return value can be one of:
105+
106+
- ``CAN.STOPPED`` -- the controller is completely off and reset;
107+
- ``CAN.ERROR_ACTIVE`` -- the controller is on and in the Error Active state
108+
(both TEC and REC are less than 96);
109+
- ``CAN.ERROR_WARNING`` -- the controller is on and in the Error Warning state
110+
(at least one of TEC or REC is 96 or greater);
111+
- ``CAN.ERROR_PASSIVE`` -- the controller is on and in the Error Passive state
112+
(at least one of TEC or REC is 128 or greater);
113+
- ``CAN.BUS_OFF`` -- the controller is on but not participating in bus activity
114+
(TEC overflowed beyond 255).
115+
102116
.. method:: CAN.setfilter(bank, mode, fifo, params, \*, rtr)
103117

104118
Configure a filter bank:
@@ -229,6 +243,14 @@ Constants
229243

230244
the mode of the CAN bus
231245

246+
.. data:: CAN.STOPPED
247+
CAN.ERROR_ACTIVE
248+
CAN.ERROR_WARNING
249+
CAN.ERROR_PASSIVE
250+
CAN.BUS_OFF
251+
252+
Possible states of the CAN controller.
253+
232254
.. data:: CAN.LIST16
233255
.. data:: CAN.MASK16
234256
.. data:: CAN.LIST32

ports/stm32/can.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@
4545
#define MASK32 (2)
4646
#define LIST32 (3)
4747

48+
enum {
49+
CAN_STATE_STOPPED,
50+
CAN_STATE_ERROR_ACTIVE,
51+
CAN_STATE_ERROR_WARNING,
52+
CAN_STATE_ERROR_PASSIVE,
53+
CAN_STATE_BUS_OFF,
54+
};
55+
4856
/// \moduleref pyb
4957
/// \class CAN - controller area network communication bus
5058
///
@@ -484,6 +492,26 @@ STATIC mp_obj_t pyb_can_restart(mp_obj_t self_in) {
484492
}
485493
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_can_restart_obj, pyb_can_restart);
486494

495+
// Get the state of the controller
496+
STATIC mp_obj_t pyb_can_state(mp_obj_t self_in) {
497+
pyb_can_obj_t *self = MP_OBJ_TO_PTR(self_in);
498+
mp_int_t state = CAN_STATE_STOPPED;
499+
if (self->is_enabled) {
500+
CAN_TypeDef *can = self->can.Instance;
501+
if (can->ESR & CAN_ESR_BOFF) {
502+
state = CAN_STATE_BUS_OFF;
503+
} else if (can->ESR & CAN_ESR_EPVF) {
504+
state = CAN_STATE_ERROR_PASSIVE;
505+
} else if (can->ESR & CAN_ESR_EWGF) {
506+
state = CAN_STATE_ERROR_WARNING;
507+
} else {
508+
state = CAN_STATE_ERROR_ACTIVE;
509+
}
510+
}
511+
return MP_OBJ_NEW_SMALL_INT(state);
512+
}
513+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_can_state_obj, pyb_can_state);
514+
487515
/// \method any(fifo)
488516
/// Return `True` if any message waiting on the FIFO, else `False`.
489517
STATIC mp_obj_t pyb_can_any(mp_obj_t self_in, mp_obj_t fifo_in) {
@@ -842,6 +870,7 @@ STATIC const mp_rom_map_elem_t pyb_can_locals_dict_table[] = {
842870
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_can_init_obj) },
843871
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_can_deinit_obj) },
844872
{ MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&pyb_can_restart_obj) },
873+
{ MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&pyb_can_state_obj) },
845874
{ MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_can_any_obj) },
846875
{ MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pyb_can_send_obj) },
847876
{ MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&pyb_can_recv_obj) },
@@ -861,6 +890,13 @@ STATIC const mp_rom_map_elem_t pyb_can_locals_dict_table[] = {
861890
{ MP_ROM_QSTR(MP_QSTR_LIST16), MP_ROM_INT(LIST16) },
862891
{ MP_ROM_QSTR(MP_QSTR_MASK32), MP_ROM_INT(MASK32) },
863892
{ MP_ROM_QSTR(MP_QSTR_LIST32), MP_ROM_INT(LIST32) },
893+
894+
// values for CAN.state()
895+
{ MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) },
896+
{ MP_ROM_QSTR(MP_QSTR_ERROR_ACTIVE), MP_ROM_INT(CAN_STATE_ERROR_ACTIVE) },
897+
{ MP_ROM_QSTR(MP_QSTR_ERROR_WARNING), MP_ROM_INT(CAN_STATE_ERROR_WARNING) },
898+
{ MP_ROM_QSTR(MP_QSTR_ERROR_PASSIVE), MP_ROM_INT(CAN_STATE_ERROR_PASSIVE) },
899+
{ MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) },
864900
};
865901

866902
STATIC MP_DEFINE_CONST_DICT(pyb_can_locals_dict, pyb_can_locals_dict_table);

0 commit comments

Comments
 (0)