|
| 1 | +.. currentmodule:: machine |
| 2 | +.. _machine.CAN: |
| 3 | + |
| 4 | +class CAN -- controller area network communication bus |
| 5 | +====================================================== |
| 6 | + |
| 7 | +CAN implements the standard CAN communications protocol. At |
| 8 | +the physical level it consists of 2 lines: RX and TX. Note that |
| 9 | +to connect the microcontroller to a CAN bus you must use a CAN transceiver |
| 10 | +to convert the CAN logic signals from the microcontroller to the correct |
| 11 | +voltage levels on the bus. |
| 12 | + |
| 13 | +Example usage (works without anything connected):: |
| 14 | + |
| 15 | + from machine import CAN |
| 16 | + BAUDRATE_500k = 500 |
| 17 | + can = CAN(0, extframe=True, mode=CAN.LOOPBACK, baudrate=BAUDRATE_500k) |
| 18 | + dev.setfilter(0, CAN.FILTER_ADDRESS, [0x102, 0]) # set a filter to receive messages with id = 0x102 |
| 19 | + can.send([1,2,3], 0x102) # send a message with id 123 |
| 20 | + can.recv() # receive message |
| 21 | + |
| 22 | + |
| 23 | +Constructors |
| 24 | +------------ |
| 25 | + |
| 26 | +.. class:: machine.CAN(bus, ...) |
| 27 | + |
| 28 | + Construct a CAN object on the given bus(controller). *bus* can be 0 or 1 for STM32 and 0 for ESP32. |
| 29 | + With no additional parameters, the CAN object is created but not |
| 30 | + initialised (it has the settings from the last initialisation of |
| 31 | + the bus, if any). If extra arguments are given, the bus is initialised. |
| 32 | + See :meth:`CAN.init` for parameters of initialisation. |
| 33 | + |
| 34 | + The physical pins of the CAN bus can be assigned during init. |
| 35 | + |
| 36 | +Methods |
| 37 | +------- |
| 38 | + |
| 39 | +.. method:: CAN.init(mode, extframe=False, baudrate, prescaler, \*, sjw=1, bs1=6, bs2=8, auto_restart=False) |
| 40 | + |
| 41 | + Initialise the CAN bus with the given parameters: |
| 42 | + |
| 43 | + - *mode* is one of: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK |
| 44 | + - if *extframe* is True then the bus uses extended identifiers in the frames |
| 45 | + (29 bits); otherwise it uses standard 11 bit identifiers |
| 46 | + - *baudrate* is used to define a standard speed. If it is defined, the *prescaler*, *sjw*, *bs1*, *bs2* |
| 47 | + will be ignored. Standard speeds are 25, 50, 100, 125, 250, 500, 1000 |
| 48 | + - *prescaler* is used to set the duration of 1 time quanta; the time quanta |
| 49 | + will be the input clock divided by the prescaler |
| 50 | + - *sjw* is the resynchronisation jump width in units of the time quanta; |
| 51 | + it can be 1, 2, 3, 4 |
| 52 | + - *bs1* defines the location of the sample point in units of the time quanta; |
| 53 | + it can be between 1 and 1024 inclusive |
| 54 | + - *bs2* defines the location of the transmit point in units of the time quanta; |
| 55 | + it can be between 1 and 16 inclusive |
| 56 | + - *tx* defines the gpio used for transmission |
| 57 | + - *rx* defines the gpio used for receiving |
| 58 | + - *bus_off* defines the gpio used for BUS-OFF signal line(optional) |
| 59 | + - *clkout* defines the gpio used for CLKOUT signal line(optional) |
| 60 | + - *tx_queue* defines the number of waiting tx messages can be stored |
| 61 | + - *rx_queue* defines the number of received messages can be stored |
| 62 | + - *auto_restart* sets whether the controller will automatically try and restart |
| 63 | + communications after entering the bus-off state; if this is disabled then |
| 64 | + :meth:`~CAN.restart()` can be used to leave the bus-off state. |
| 65 | + This parameter is currently not implemented and it must be set to False |
| 66 | + |
| 67 | + |
| 68 | +.. method:: CAN.deinit() |
| 69 | + |
| 70 | + Turn off the CAN bus. |
| 71 | + |
| 72 | +.. method:: CAN.restart() |
| 73 | + |
| 74 | + Force a software restart of the CAN controller without resetting its |
| 75 | + configuration. |
| 76 | + |
| 77 | + If the controller enters the bus-off state then it will no longer participate |
| 78 | + in bus activity. If the controller is not configured to automatically restart |
| 79 | + (see :meth:`~CAN.init()`) then this method can be used to trigger a restart, |
| 80 | + and the controller will follow the CAN protocol to leave the bus-off state and |
| 81 | + go into the error active state. |
| 82 | + |
| 83 | +.. method:: CAN.state() |
| 84 | + |
| 85 | + Return the state of the controller. The return value can be one of: |
| 86 | + |
| 87 | + - ``CAN.STOPPED`` -- the controller is completely off and reset; |
| 88 | + - ``CAN.ERROR_ACTIVE`` -- the controller is on and in the Error Active state |
| 89 | + (both TEC and REC are less than 96); |
| 90 | + - ``CAN.BUS_OFF`` -- the controller is on but not participating in bus activity |
| 91 | + (TEC overflowed beyond 255). |
| 92 | + - ``CAN.RECOVERING`` -- the controller is under recover from bus-off state; |
| 93 | + |
| 94 | + |
| 95 | +.. method:: CAN.info([list]) |
| 96 | + |
| 97 | + Get information about the controller's error states and TX and RX buffers. |
| 98 | + If *list* is provided then it should be a list object with at least 8 entries, |
| 99 | + which will be filled in with the information. Otherwise a new list will be |
| 100 | + created and filled in. In both cases the return value of the method is the |
| 101 | + populated list. |
| 102 | + |
| 103 | + The values in the list are: |
| 104 | + |
| 105 | + - TEC value |
| 106 | + - REC value |
| 107 | + - number of times the controller enterted the Error Warning state (wrapped |
| 108 | + around to 0 after 65535) - CURRENTLY NOT IMPLEMENTED |
| 109 | + - number of times the controller enterted the Error Passive state (wrapped |
| 110 | + around to 0 after 65535) - CURRENTLY NOT IMPLEMENTED |
| 111 | + - number of times the controller enterted the Bus Off state (wrapped |
| 112 | + around to 0 after 65535) - CURRENTLY NOT IMPLEMENTED |
| 113 | + - number of pending TX messages |
| 114 | + - number of pending RX messages |
| 115 | + - Reserved |
| 116 | + |
| 117 | +.. method:: CAN.setfilter(bank, mode, fifo, params, \*, rtr) |
| 118 | + |
| 119 | + Configure a filter bank: |
| 120 | + |
| 121 | + - *bank* is the filter bank that is to be configured (0 for extended, 0 or 1 for standard msg) |
| 122 | + - *mode* is the mode the filter should operate in. |
| 123 | + - *params* is an array of two values that defines the filter. |
| 124 | + The first element will be the id to filter and the second element will be the mask to apply. |
| 125 | + mask bit implementation considers 1 as a don't care state and 0 as a check state. |
| 126 | + |
| 127 | + +-----------------------+----------------------------------------------+ |
| 128 | + | *mode* | contents of *params* array | |
| 129 | + +=======================+==============================================+ |
| 130 | + | CAN.FILTER_RAW_SINGLE | *params* will be copied in hardware variable | |
| 131 | + | | and single_filter_mode will be selected | |
| 132 | + | | In this mode, *bank* will be ignored | |
| 133 | + +-----------------------+----------------------------------------------+ |
| 134 | + | CAN.FILTER_RAW_DUAL | *params* will be copied in hardware variable | |
| 135 | + | | and single_filter_mode will be cleared | |
| 136 | + | | In this mode, *bank* will be ignored | |
| 137 | + +-----------------------+----------------------------------------------+ |
| 138 | + | CAN.FILTER_ADDRESS | *params* will be set in hardware registers | |
| 139 | + | | according to *bank* selection | |
| 140 | + +-----------------------+----------------------------------------------+ |
| 141 | + |
| 142 | + - *rtr* is bool that states if a filter should accept a remote transmission request message. |
| 143 | + If this argument is not given then it defaults to ``False``. |
| 144 | + |
| 145 | +.. method:: CAN.clearfilter(bank) |
| 146 | + |
| 147 | + Clear and disables all filters |
| 148 | + |
| 149 | +.. method:: CAN.any(fifo) |
| 150 | + |
| 151 | + Return ``True`` if any message waiting on the FIFO, else ``False``. |
| 152 | + |
| 153 | +.. method:: CAN.recv(list=None, \*, timeout=5000) |
| 154 | + |
| 155 | + Receive data on the bus: |
| 156 | + |
| 157 | + - *list* is an optional list object to be used as the return value |
| 158 | + - *timeout* is the timeout in milliseconds to wait for the receive. |
| 159 | + |
| 160 | + Return value: A tuple containing four values. |
| 161 | + |
| 162 | + - The id of the message. |
| 163 | + - A boolean that indicates if the message is an RTR message. |
| 164 | + - Reserved. |
| 165 | + - An array containing the data. |
| 166 | + |
| 167 | + If *list* is ``None`` then a new tuple will be allocated, as well as a new |
| 168 | + bytes object to contain the data (as the fourth element in the tuple). |
| 169 | + |
| 170 | + If *list* is not ``None`` then it should be a list object with a least four |
| 171 | + elements. The fourth element should be a memoryview object which is created |
| 172 | + from either a bytearray or an array of type 'B' or 'b', and this array must |
| 173 | + have enough room for at least 8 bytes. The list object will then be |
| 174 | + populated with the first three return values above, and the memoryview object |
| 175 | + will be resized inplace to the size of the data and filled in with that data. |
| 176 | + The same list and memoryview objects can be reused in subsequent calls to |
| 177 | + this method, providing a way of receiving data without using the heap. |
| 178 | + For example:: |
| 179 | + |
| 180 | + buf = bytearray(8) |
| 181 | + lst = [0, 0, 0, memoryview(buf)] |
| 182 | + # No heap memory is allocated in the following call |
| 183 | + can.recv(lst, timeout=0) |
| 184 | + |
| 185 | +.. method:: CAN.send(data, id, \*, timeout=0, rtr=False) |
| 186 | + |
| 187 | + Send a message on the bus: |
| 188 | + |
| 189 | + - *data* is the data to send (an integer to send, or a buffer object). |
| 190 | + - *id* is the id of the message to be sent. |
| 191 | + - *timeout* is the timeout in milliseconds to wait for the send. |
| 192 | + - *rtr* is a boolean that specifies if the message shall be sent as |
| 193 | + a remote transmission request. If *rtr* is True then only the length |
| 194 | + of *data* is used to fill in the DLC slot of the frame; the actual |
| 195 | + bytes in *data* are unused. |
| 196 | + |
| 197 | + If timeout is 0 the message is placed in a buffer and the method returns |
| 198 | + immediately. If all three buffers are in use an exception is thrown. |
| 199 | + If timeout is not 0, the method waits until the message is transmitted. |
| 200 | + If the message can't be transmitted within the specified time an exception |
| 201 | + is thrown. |
| 202 | + |
| 203 | + Return value: ``None``. |
| 204 | + |
| 205 | +.. method:: CAN.clear_tx_queue() |
| 206 | + |
| 207 | + Clear all messages from transmitting queue. |
| 208 | + |
| 209 | +.. method:: CAN.clear_rx_queue() |
| 210 | + |
| 211 | + Clear all messages from receiving queue. |
| 212 | + |
| 213 | +.. method:: CAN.get_alerts() |
| 214 | + |
| 215 | + Read the alert status word directly from hardware. |
| 216 | + In order to save space in the firmware, the constants for the result decoding are not included on the :mod:`machine.CAN` module. Add the ones that you need from the list below to your program. |
| 217 | + |
| 218 | + The event codes are:: |
| 219 | + |
| 220 | + from micropython import const |
| 221 | + CAN_ALERT_TX_IDLE = const(0x0001) |
| 222 | + CAN_ALERT_TX_SUCCESS = const(0x0002) |
| 223 | + CAN_ALERT_BELOW_ERR_WARN = const(0x0004) |
| 224 | + CAN_ALERT_ERR_ACTIVE = const(0x0008) |
| 225 | + CAN_ALERT_RECOVERY_IN_PROGRESS = const(0x0010) |
| 226 | + CAN_ALERT_BUS_RECOVERED = const(0x0020) |
| 227 | + CAN_ALERT_ARB_LOST = const(0x0040) |
| 228 | + CAN_ALERT_ABOVE_ERR_WARN = const(0x0080) |
| 229 | + CAN_ALERT_BUS_ERROR = const(0x0100) |
| 230 | + CAN_ALERT_TX_FAILED = const(0x0200) |
| 231 | + CAN_ALERT_RX_QUEUE_FULL = const(0x0400) |
| 232 | + CAN_ALERT_ERR_PASS = const(0x0800) |
| 233 | + CAN_ALERT_BUS_OFF = const(0x1000) |
| 234 | + |
| 235 | + |
| 236 | +Constants |
| 237 | +--------- |
| 238 | + |
| 239 | +.. data:: CAN.NORMAL |
| 240 | + CAN.LOOPBACK |
| 241 | + CAN.SILENT |
| 242 | + CAN.SILENT_LOOPBACK |
| 243 | + CAN.LISTEN_ONLY |
| 244 | + |
| 245 | + |
| 246 | + The mode of the CAN bus used in :meth:`~CAN.init()`. |
| 247 | + |
| 248 | + +---------------------+---------------------------------------------+-------+-------+ |
| 249 | + | *mode* | \ | STM32 | ESP32 | |
| 250 | + +=====================+=============================================+=======+=======+ |
| 251 | + | CAN.NORMAL | .. image:: img/can_mode_normal.png | + | + | |
| 252 | + +---------------------+---------------------------------------------+-------+-------+ |
| 253 | + | CAN.LOOPBACK | .. image:: img/can_mode_loopback.png | + | + | |
| 254 | + +---------------------+---------------------------------------------+-------+-------+ |
| 255 | + | CAN.SILENT | .. image:: img/can_mode_silent.png | + | + | |
| 256 | + +---------------------+---------------------------------------------+-------+-------+ |
| 257 | + | CAN.SILENT_LOOPBACK | .. image:: img/can_mode_silent_loopback.png | + | | |
| 258 | + +---------------------+---------------------------------------------+-------+-------+ |
| 259 | + | CAN.LISTEN_ONLY | .. image:: img/can_mode_listen_only.png | | + | |
| 260 | + +---------------------+---------------------------------------------+-------+-------+ |
| 261 | + |
| 262 | + |
| 263 | +.. data:: CAN.STOPPED |
| 264 | + CAN.ERROR_ACTIVE |
| 265 | + CAN.BUS_OFF |
| 266 | + CAN.RECOVERING |
| 267 | + |
| 268 | + Possible states of the CAN controller returned from :meth:`~CAN.state()`. |
| 269 | + |
| 270 | +.. data:: CAN.FILTER_RAW_SINGLE |
| 271 | + CAN.FILTER_RAW_DUAL |
| 272 | + CAN.FILTER_ADDRESS |
| 273 | + |
| 274 | + The operation mode of a filter used in :meth:`~CAN.setfilter()`. |
| 275 | + |
0 commit comments