5
5
`adafruit_mcp2515`
6
6
================================================================================
7
7
8
- A CircuitPython library for working with the MCP2515 CAN bus controller
8
+ A CircuitPython library for working with the MCP2515 CAN bus controller using the
9
+ CircuitPython `canio` API
9
10
10
11
11
12
* Author(s): Bryan Siepert
20
21
* Adafruit CircuitPython firmware for the supported boards:
21
22
https://github.com/adafruit/circuitpython/releases
22
23
23
- # * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
24
- # * Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
24
+ * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
25
25
"""
26
26
27
27
from collections import namedtuple
30
30
from micropython import const
31
31
import adafruit_bus_device .spi_device as spi_device
32
32
from .canio import *
33
+ from .timer import Timer
33
34
34
35
__version__ = "0.0.0-auto.0"
35
36
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_MCP2515.git"
162
163
"TransmitBuffer" ,
163
164
["CTRL_REG" , "STD_ID_REG" , "INT_FLAG_MASK" , "LOAD_CMD" , "SEND_CMD" ],
164
165
)
165
- # perhaps this will be stateful later? #TODO : dedup with above
166
- FilterMask = namedtuple (
167
- "FilterMask" , ["CTRL_REG" , "STD_ID_REG" , "INT_FLAG_MASK" , "LOAD_CMD" , "SEND_CMD" ],
168
- )
169
166
167
+ # This is magic, don't disturb the dragon
168
+ # expects a 16Mhz crystal
170
169
_BAUD_RATES = {
170
+ # CNF1, CNF2, CNF3
171
171
1000000 : (0x00 , 0xD0 , 0x82 ),
172
172
500000 : (0x00 , 0xF0 , 0x86 ),
173
173
250000 : (0x41 , 0xF1 , 0x85 ),
@@ -209,7 +209,24 @@ def _tx_buffer_status_decode(status_byte):
209
209
210
210
211
211
class MCP2515 : # pylint:disable=too-many-instance-attributes
212
- """Library for the MCP2515 CANbus controller"""
212
+ """
213
+ A common shared-bus protocol.
214
+
215
+ :param ~busio.SPI spi: The SPI bus used to communicate with the MCP2515
216
+ :param ~digitalio.DigitalInOut cs_pin: SPI bus enable pin
217
+ :param int baudrate: The bit rate of the bus in Hz, using a 16Mhz crystal. All devices on\
218
+ the bus must agree on this value. Defaults to 250000.
219
+ :param bool loopback: Receive only packets sent from this device, and send only to\
220
+ this device. Requires that `silent` is also set to `False`, but only prevents\
221
+ transimssion to other devices. Otherwise the send/receive behavior is normal.
222
+ :param bool silent:When `True` the controller does not transmit and all messages\
223
+ are received, ignoring errors and filters. This mode can be used to “sniff” a CAN\
224
+ bus without interfering. Defaults to `False`.
225
+ :param bool auto_restart: **Not supported by hardware. An `AttributeError`
226
+ will be raised if `auto_restart` is set to `True`** If `True`, will restart\
227
+ communications after entering bus-off state. Defaults to `False`.
228
+ :param bool debug: If `True`, will enable printing debug information. Defaults to `False`.
229
+ """
213
230
214
231
def __init__ (
215
232
self ,
@@ -222,24 +239,12 @@ def __init__(
222
239
auto_restart : bool = False ,
223
240
debug : bool = False
224
241
):
225
- """[summary]
226
242
227
- Args:
228
- spi_bus (busio.SPI): The SPI bus used to communicate with the MCP2515
229
- cs_pin (digitalio.DigitalInOut): SPI bus enable pin
230
- baudrate (int, optional): The bit rate of the bus in Hz. All devices on the bus must \
231
- agree on this value. Defaults to 250000.
232
- loopback (bool, optional): When True the rx pin’s value is ignored, and the device \
233
- receives the packets it sends. Defaults to False.
234
- silent (bool, optional): When True the tx pin is always driven to the high logic level.\
235
- This mode can be used to “sniff” a CAN bus without interfering.. Defaults to False.
236
- auto_restart (bool, optional): If True, will restart communications after entering \
237
- bus-off state. Defaults to False.
238
- debug (bool, optional): If True, will enable printing debug information. Defaults to \
239
- False.
240
- """
241
- if loopback and silent :
242
- raise AttributeError ("only loopback or silent mode can bet set, not both" )
243
+ if loopback and not silent :
244
+ raise AttributeError ("Loopback mode requires silent to be set" )
245
+ if auto_restart :
246
+ raise AttributeError ("`auto-restart` is not supported by hardware" )
247
+
243
248
self ._auto_restart = auto_restart
244
249
self ._debug = debug
245
250
self ._bus_device_obj = spi_device .SPIDevice (spi_bus , cs_pin )
@@ -331,6 +336,7 @@ def send(self, message_obj, wait_sent=True):
331
336
Args:
332
337
message (canio.Message): The message to send. Must be a valid `canio.Message`
333
338
"""
339
+
334
340
# TODO: Timeout
335
341
tx_buff = self ._get_tx_buffer () # info = addr.
336
342
@@ -350,7 +356,7 @@ def send(self, message_obj, wait_sent=True):
350
356
if send_confirmed :
351
357
return True
352
358
353
- raise RuntimeError ("Timeout occoured waiting for transmit confirmation" )
359
+ raise RuntimeError ("Timeout occurred waiting for transmit confirmation" )
354
360
355
361
@property
356
362
def unread_message_count (self ):
@@ -830,7 +836,7 @@ def listen(self, matches=None, *, timeout: float = 10):
830
836
831
837
An empty filter list causes all messages to be accepted.
832
838
833
- Timeout dictates how long ``receive()`` and ``next()`` will block.
839
+ Timeout dictates how long ``receive()`` will block.
834
840
835
841
Args:
836
842
match (Optional[Sequence[Match]], optional): [description]. Defaults to None.
@@ -841,6 +847,11 @@ def listen(self, matches=None, *, timeout: float = 10):
841
847
"""
842
848
if matches is None :
843
849
matches = []
850
+ elif self .silent and not self .loopback :
851
+ raise AttributeError (
852
+ "Hardware does not support setting `matches` in when\
853
+ `silent`==`True` and `loopback` == `False`"
854
+ )
844
855
845
856
for match in matches :
846
857
self ._dbg ("match:" , match )
0 commit comments