summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2018-03-16 17:10:41 +1100
committerDamien George <damien.p.george@gmail.com>2018-03-16 17:10:41 +1100
commitd7e67fb1b40c40ba24e3a17e73e5f1b5b96f3914 (patch)
tree2483ccd9fce62341023cbbbeb9e36d82b7e71a09
parent1272c3c65d895e4694e0c707a98a739706667d23 (diff)
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.
-rw-r--r--docs/library/pyb.CAN.rst22
-rw-r--r--ports/stm32/can.c36
2 files changed, 58 insertions, 0 deletions
diff --git a/docs/library/pyb.CAN.rst b/docs/library/pyb.CAN.rst
index f90e7a8a7..484a00f36 100644
--- a/docs/library/pyb.CAN.rst
+++ b/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
diff --git a/ports/stm32/can.c b/ports/stm32/can.c
index d5702f6d1..563d15dab 100644
--- a/ports/stm32/can.c
+++ b/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);