Skip to content

Commit 52e3a87

Browse files
author
Thomas Preston
committed
Added uart
1 parent 4f898f4 commit 52e3a87

File tree

5 files changed

+180
-9
lines changed

5 files changed

+180
-9
lines changed

CHANGELOG

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
Change Log
22
==========
33

4+
v0.6.0
5+
------
6+
- Added UART support.
7+
48
v0.5.0
59
------
610
- Updated packet layer, better support for bulk commands and AND/OR masks.

codebug_tether/core.py

Lines changed: 125 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,38 @@
2020
CHANNEL_INDEX_I2C_ADDR = 14
2121
CHANNEL_INDEX_I2C_LENGTH = 15
2222
CHANNEL_INDEX_I2C_CONTROL = 16
23-
CHANNEL_INDEX_COLOURTAIL_LENGTH = 17
24-
CHANNEL_INDEX_COLOURTAIL_CONTROL = 18
23+
CHANNEL_INDEX_UART_RX_OFFSET = 17
24+
CHANNEL_INDEX_UART_RX_LENGTH = 18
25+
CHANNEL_INDEX_UART_TX_OFFSET = 19
26+
CHANNEL_INDEX_UART_TX_LENGTH = 20
27+
CHANNEL_INDEX_UART_CONTROL = 21
28+
CHANNEL_INDEX_COLOURTAIL_LENGTH = 22
29+
CHANNEL_INDEX_COLOURTAIL_CONTROL = 23
2530

26-
EXTENSION_CONF_IO = 0
27-
EXTENSION_CONF_SPI = 1
28-
EXTENSION_CONF_I2C = 2
31+
EXTENSION_CONF_IO = 0x01
32+
EXTENSION_CONF_SPI = 0x02
33+
EXTENSION_CONF_I2C = 0x04
34+
EXTENSION_CONF_UART = 0x08
35+
36+
UART_TX_BUFFER_INDEX = 0
37+
UART_RX_BUFFER_INDEX = 1
38+
39+
UART_TX_GO_BUSY_MASK = 0x01
40+
UART_RX_GO_BUSY_MASK = 0x02
41+
UART_BAUD_300 = 0 << 2
42+
UART_BAUD_1200 = 1 << 2
43+
UART_BAUD_2400 = 2 << 2
44+
UART_BAUD_9600 = 3 << 2
45+
UART_BAUD_10417 = 4 << 2
46+
UART_BAUD_19200 = 5 << 2
47+
UART_BAUD_57600 = 6 << 2
48+
UART_BAUD_115200 = 7 << 2
49+
50+
UART_DEFAULT_BAUD = 9600
51+
52+
53+
class InvalidBaud(Exception):
54+
pass
2955

3056

3157
class CodeBug(SerialChannelDevice):
@@ -197,6 +223,9 @@ def config_extension_spi(self):
197223
def config_extension_i2c(self):
198224
self.set(CHANNEL_INDEX_EXT_CONF, EXTENSION_CONF_I2C)
199225

226+
def config_extension_uart(self):
227+
self.set(CHANNEL_INDEX_EXT_CONF, EXTENSION_CONF_UART)
228+
200229
def spi_transaction(self,
201230
data,
202231
cs_idle_high=1,
@@ -318,3 +347,94 @@ def send_msg(msg):
318347
send_msg(message)
319348

320349
return tuple(rx_buffer)
350+
351+
def _get_uart_control_baud(self, baud):
352+
"""Returns UART control value for given baud rate. Will raise
353+
InvalidBaud exception if baud is invalid.
354+
"""
355+
baud_control = {300: 0 << 2,
356+
1200: 1 << 2,
357+
2400: 2 << 2,
358+
9600: 3 << 2,
359+
10417: 4 << 2,
360+
19200: 5 << 2,
361+
57600: 6 << 2,
362+
115200: 7 << 2}
363+
if baud not in baud_control:
364+
raise InvalidBaud('{} is not a valid baud rate (valid baud '
365+
'rates: {}).'.format(baud, tuple(baud_control.keys())))
366+
else:
367+
return baud_control[baud]
368+
369+
def uart_set_baud(self, baud):
370+
self.set(CHANNEL_INDEX_UART_CONTROL, self._get_uart_control_baud(baud))
371+
372+
def uart_tx(self, data_bytes, baud=UART_DEFAULT_BAUD):
373+
"""Transmits data bytes over UART. Use this if you just want to
374+
send X amount of data. Be sure to configure the extension pins
375+
first. For example:
376+
377+
>>> from codebug_tether import CodeBug
378+
>>> codebug = CodeBug()
379+
>>> codebug.config_extension_uart()
380+
>>> # send 0xAA, 0xBB over UART
381+
>>> codebug.uart_tx(bytes((0xAA, 0xBB)))
382+
>>> # send 0xAA, 0xBB over UART at 300 baud
383+
>>> codebug.uart_tx(bytes((0xAA, 0xBB)), baud=300)
384+
385+
"""
386+
self.uart_tx_set_buffer(data_bytes)
387+
self.uart_tx_start(len(data_bytes))
388+
389+
def uart_tx_start(self, length, offset=0, baud=UART_DEFAULT_BAUD):
390+
"""Transmits 'length' data bytes from UART buffer starting at
391+
'offset' over UART. Be sure to configure the extension pins
392+
first. For example, you might want to fill the buffer with two
393+
commands (0xAA and 0xBB) which are sent over UART and only send
394+
one at a time:
395+
396+
>>> from codebug_tether import CodeBug
397+
>>> codebug = CodeBug()
398+
>>> codebug.config_extension_uart()
399+
>>> codebug.uart_tx_set_buffer(bytes((0xAA, 0xBB)))
400+
>>> codebug.uart_tx_start(1, offset=0) # send 0xAA over UART
401+
>>> codebug.uart_tx_start(1, offset=1) # send 0xBB over UART
402+
>>> # send 0xAA over UART at 300 baud
403+
>>> codebug.uart_tx_start(1, offset=0, baud=300)
404+
405+
"""
406+
control = self._get_uart_control_baud(baud) | UART_TX_GO_BUSY_MASK
407+
self.set_bulk(CHANNEL_INDEX_UART_TX_OFFSET,
408+
bytes((offset, length, control)))
409+
410+
def uart_tx_set_buffer(self, data_bytes, offset=0):
411+
"""Add data_bytes to the UART buffer at offset."""
412+
self.set_buffer(UART_TX_BUFFER_INDEX, data_bytes, offset)
413+
414+
def uart_rx_start(self, length, baud=UART_DEFAULT_BAUD, offset=0):
415+
"""Begins receiving on the UART. RX will stop when length data is
416+
reached. Be sure to configure the extension pins first. For example
417+
418+
>>> from codebug_tether import CodeBug
419+
>>> codebug = CodeBug()
420+
>>> codebug.config_extension_uart()
421+
>>> codebug.uart_rx_start(2) # ready to receive 2B over UART
422+
>>> # wait until data ready (alternatively, sleep X seconds)
423+
>>> while not codebug.uart_rx_is_ready():
424+
... pass
425+
...
426+
>>> codebug.uart_rx_get_buffer(2) # read out the two bytes
427+
428+
"""
429+
self.set_bulk(CHANNEL_INDEX_UART_RX_OFFSET, bytes((offset, length)))
430+
self.set(CHANNEL_INDEX_UART_CONTROL,
431+
self._get_uart_control_baud(baud) | UART_RX_GO_BUSY_MASK)
432+
433+
def uart_rx_is_ready(self):
434+
"""Returns True if the UART has finished receiving data."""
435+
uart_control = self.get(CHANNEL_INDEX_UART_CONTROL)[0]
436+
return uart_control & UART_RX_GO_BUSY_MASK == 0
437+
438+
def uart_rx_get_buffer(self, length, offset=0):
439+
"""Returns data bytes from UART buffer."""
440+
return self.get_buffer(UART_RX_BUFFER_INDEX, length, offset)

codebug_tether/i2c.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ class CodeBugI2CMaster():
2525
2626
For example:
2727
28+
import codebug_tether
2829
from codebug_tether.i2c import (I2CMaster, writing)
2930
30-
with I2CMaster() as i2c:
31-
i2c.transaction(
32-
writing(0x20, bytes([0x01, 0xFF])))
31+
codebug = codebug_tether.CodeBug()
32+
33+
with I2CMaster(codebug) as i2c:
34+
i2c.transaction(writing(0x20, bytes([0x01, 0xFF])))
3335
3436
"""
3537
def __init__(self, codebug):

codebug_tether/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.5.0'
1+
__version__ = '0.6.0'

docs/example.rst

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ You can configure the extension header mode with the following methods::
146146

147147
>>> codebug.config_extension_spi() # configure extension as SPI
148148
>>> codebug.config_extension_i2c() # configure extension as I2C
149+
>>> codebug.config_extension_uart() # configure extension as UART
149150
>>> codebug.config_extension_io() # reset extension as normal I/O
150151

151152
SPI
@@ -196,3 +197,47 @@ Multiple byte write transaction (write values 0x34, 0x56, 0x78 to reg 0x12)::
196197

197198
>>> codebug.i2c_transaction(
198199
writing(i2c_addr, 0x12, 0x34, 0x56, 0x78))
200+
201+
202+
UART
203+
----
204+
Sending data::
205+
206+
>>> import codebug_tether
207+
>>> codebug = codebug_tether.CodeBug()
208+
>>> codebug.config_extension_uart()
209+
>>>
210+
>>> # send 0xAA, 0xBB over UART
211+
>>> codebug.uart_tx(bytes((0xAA, 0xBB)))
212+
>>>
213+
>>> # send 0xAA, 0xBB over UART at 300 baud
214+
>>> codebug.uart_tx(bytes((0xAA, 0xBB)), baud=300)
215+
216+
You can also write to the buffer first and then send data from within
217+
it::
218+
219+
>>> import codebug_tether
220+
>>> codebug = codebug_tether.CodeBug()
221+
>>> codebug.config_extension_uart()
222+
>>>
223+
>>> codebug.uart_tx_set_buffer(bytes((0xAA, 0xBB)))
224+
>>>
225+
>>> codebug.uart_tx_start(1, offset=0) # send 0xAA over UART
226+
>>> codebug.uart_tx_start(1, offset=1) # send 0xBB over UART
227+
>>>
228+
>>> # send 0xAA over UART at 300 baud
229+
>>> codebug.uart_tx_start(1, offset=0, baud=300)
230+
231+
Receiving data::
232+
233+
>>> import codebug_tether
234+
>>> codebug = codebug_tether.CodeBug()
235+
>>> codebug.config_extension_uart()
236+
>>>
237+
>>> codebug.uart_rx_start(2) # ready to receive 2B over UART
238+
>>>
239+
>>> # wait until data ready (alternatively, sleep X seconds)
240+
>>> while not codebug.uart_rx_is_ready():
241+
... pass
242+
...
243+
>>> codebug.uart_rx_get_buffer(2) # read out the two bytes

0 commit comments

Comments
 (0)