Browse Source

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.
pull/3663/head
Damien George 7 years ago
parent
commit
d7e67fb1b4
  1. 22
      docs/library/pyb.CAN.rst
  2. 36
      ports/stm32/can.c

22
docs/library/pyb.CAN.rst

@ -99,6 +99,20 @@ Methods
and the controller will follow the CAN protocol to leave the bus-off state and
go into the error active state.
.. method:: CAN.state()
Return the state of the controller. The return value can be one of:
- ``CAN.STOPPED`` -- the controller is completely off and reset;
- ``CAN.ERROR_ACTIVE`` -- the controller is on and in the Error Active state
(both TEC and REC are less than 96);
- ``CAN.ERROR_WARNING`` -- the controller is on and in the Error Warning state
(at least one of TEC or REC is 96 or greater);
- ``CAN.ERROR_PASSIVE`` -- the controller is on and in the Error Passive state
(at least one of TEC or REC is 128 or greater);
- ``CAN.BUS_OFF`` -- the controller is on but not participating in bus activity
(TEC overflowed beyond 255).
.. method:: CAN.setfilter(bank, mode, fifo, params, \*, rtr)
Configure a filter bank:
@ -229,6 +243,14 @@ Constants
the mode of the CAN bus
.. data:: CAN.STOPPED
CAN.ERROR_ACTIVE
CAN.ERROR_WARNING
CAN.ERROR_PASSIVE
CAN.BUS_OFF
Possible states of the CAN controller.
.. data:: CAN.LIST16
.. data:: CAN.MASK16
.. data:: CAN.LIST32

36
ports/stm32/can.c

@ -45,6 +45,14 @@
#define MASK32 (2)
#define LIST32 (3)
enum {
CAN_STATE_STOPPED,
CAN_STATE_ERROR_ACTIVE,
CAN_STATE_ERROR_WARNING,
CAN_STATE_ERROR_PASSIVE,
CAN_STATE_BUS_OFF,
};
/// \moduleref pyb
/// \class CAN - controller area network communication bus
///
@ -484,6 +492,26 @@ STATIC mp_obj_t pyb_can_restart(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_can_restart_obj, pyb_can_restart);
// Get the state of the controller
STATIC mp_obj_t pyb_can_state(mp_obj_t self_in) {
pyb_can_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_int_t state = CAN_STATE_STOPPED;
if (self->is_enabled) {
CAN_TypeDef *can = self->can.Instance;
if (can->ESR & CAN_ESR_BOFF) {
state = CAN_STATE_BUS_OFF;
} else if (can->ESR & CAN_ESR_EPVF) {
state = CAN_STATE_ERROR_PASSIVE;
} else if (can->ESR & CAN_ESR_EWGF) {
state = CAN_STATE_ERROR_WARNING;
} else {
state = CAN_STATE_ERROR_ACTIVE;
}
}
return MP_OBJ_NEW_SMALL_INT(state);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_can_state_obj, pyb_can_state);
/// \method any(fifo)
/// Return `True` if any message waiting on the FIFO, else `False`.
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[] = {
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_can_init_obj) },
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_can_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&pyb_can_restart_obj) },
{ MP_ROM_QSTR(MP_QSTR_state), MP_ROM_PTR(&pyb_can_state_obj) },
{ MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_can_any_obj) },
{ MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pyb_can_send_obj) },
{ 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[] = {
{ MP_ROM_QSTR(MP_QSTR_LIST16), MP_ROM_INT(LIST16) },
{ MP_ROM_QSTR(MP_QSTR_MASK32), MP_ROM_INT(MASK32) },
{ MP_ROM_QSTR(MP_QSTR_LIST32), MP_ROM_INT(LIST32) },
// values for CAN.state()
{ MP_ROM_QSTR(MP_QSTR_STOPPED), MP_ROM_INT(CAN_STATE_STOPPED) },
{ MP_ROM_QSTR(MP_QSTR_ERROR_ACTIVE), MP_ROM_INT(CAN_STATE_ERROR_ACTIVE) },
{ MP_ROM_QSTR(MP_QSTR_ERROR_WARNING), MP_ROM_INT(CAN_STATE_ERROR_WARNING) },
{ MP_ROM_QSTR(MP_QSTR_ERROR_PASSIVE), MP_ROM_INT(CAN_STATE_ERROR_PASSIVE) },
{ MP_ROM_QSTR(MP_QSTR_BUS_OFF), MP_ROM_INT(CAN_STATE_BUS_OFF) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_can_locals_dict, pyb_can_locals_dict_table);

Loading…
Cancel
Save