Skip to content

Commit 5deceb8

Browse files
peterhinchdpgeorge
authored andcommitted
drivers, nrf24: Add nonblocking send option etc.
1 parent b66a31c commit 5deceb8

1 file changed

Lines changed: 56 additions & 40 deletions

File tree

drivers/nrf24l01/nrf24l01.py

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
"""NRF24L01 driver for Micro Python"""
1+
"""NRF24L01 driver for Micro Python
2+
3+
Support for nonblocking send added. Minor fixes:
4+
Timeout now uses pyb.elapsed_millis().
5+
Channel numbers constrained to 125 as per datasheet.
6+
Status register read with reg_read() - reg_read_ret_status() removed.
7+
Default speed 250K for improved range/error rate.
8+
"""
29

310
import pyb
411

@@ -69,8 +76,10 @@ def __init__(self, spi, cs, ce, channel=46, payload_size=16):
6976
self.pipe0_read_addr = None
7077
pyb.delay(5)
7178

72-
# set address width to 5 bytes
79+
# set address width to 5 bytes and check for device present
7380
self.reg_write(SETUP_AW, 0b11)
81+
if self.reg_read(SETUP_AW) != 0b11:
82+
raise OSError("nRF24l01+ Hardware not responding")
7483

7584
# disable dynamic payloads
7685
self.reg_write(DYNPD, 0)
@@ -80,7 +89,7 @@ def __init__(self, spi, cs, ce, channel=46, payload_size=16):
8089
self.reg_write(SETUP_RETR, (6 << 4) | 8)
8190

8291
# set rf power and speed
83-
self.set_power_speed(POWER_3, SPEED_1M)
92+
self.set_power_speed(POWER_3, SPEED_250K) # Best for point to point links
8493

8594
# init CRC
8695
self.set_crc(2)
@@ -102,13 +111,6 @@ def reg_read(self, reg):
102111
self.cs.high()
103112
return buf[0]
104113

105-
def reg_read_ret_status(self, reg):
106-
self.cs.low()
107-
status = self.spi.send_recv(reg)[0]
108-
buf = self.spi.recv(1)
109-
self.cs.high()
110-
return status
111-
112114
def reg_write(self, reg, buf):
113115
self.cs.low()
114116
status = self.spi.send_recv(0x20 | reg)[0]
@@ -143,7 +145,7 @@ def set_crc(self, length):
143145
self.reg_write(CONFIG, config)
144146

145147
def set_channel(self, channel):
146-
self.reg_write(RF_CH, min(channel, 127))
148+
self.reg_write(RF_CH, min(channel, 125)) # Changed from 127
147149

148150
# address should be a bytes object 5 bytes long
149151
def open_tx_pipe(self, address):
@@ -194,41 +196,55 @@ def recv(self):
194196
self.spi.send(R_RX_PAYLOAD)
195197
buf = self.spi.recv(self.payload_size)
196198
self.cs.high()
197-
198199
# clear RX ready flag
199200
self.reg_write(STATUS, RX_DR)
200201

201202
return buf
202203

203-
def send(self, buf, timeout=500):
204-
# power up
205-
self.reg_write(CONFIG, (self.reg_read(CONFIG) | PWR_UP) & ~PRIM_RX)
206-
pyb.udelay(150)
207-
208-
# send the data
209-
self.cs.low()
210-
self.spi.send(W_TX_PAYLOAD)
211-
self.spi.send(buf)
212-
if len(buf) < self.payload_size:
213-
self.spi.send(b'\x00' * (self.payload_size - len(buf))) # pad out data
214-
self.cs.high()
215-
216-
# enable the chip so it can send the data
217-
self.ce.high()
218-
pyb.udelay(15) # needs to be >10us
219-
self.ce.low()
220-
221204
# blocking wait for tx complete
205+
def send(self, buf, timeout=500):
206+
send_nonblock = self.send_nonblocking(buf)
222207
start = pyb.millis()
223-
while pyb.millis() - start < timeout:
224-
status = self.reg_read_ret_status(OBSERVE_TX)
225-
if status & (TX_DS | MAX_RT):
226-
break
227-
228-
# get and clear all status flags
229-
status = self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT)
230-
if not (status & TX_DS):
208+
result = None
209+
while result is None and (pyb.elapsed_millis(start) < timeout):
210+
result = send_nonblock() # 1 == success 2 == fail
211+
if result == 2:
231212
raise OSError("send failed")
232213

233-
# power down
234-
self.reg_write(CONFIG, self.reg_read(CONFIG) & ~PWR_UP)
214+
def send_nonblocking(self, buf):
215+
'''
216+
Support for nonblocking transmission. Returns a function instance.
217+
The first call to a function instance sends the data and returns None.
218+
Subsequent calls test TX status returning not ready None, ready 1, error 2.
219+
'''
220+
init = True
221+
def make_snb():
222+
nonlocal init
223+
if init:
224+
# power up
225+
self.reg_write(CONFIG, (self.reg_read(CONFIG) | PWR_UP) & ~PRIM_RX)
226+
pyb.udelay(150)
227+
228+
# send the data
229+
self.cs.low()
230+
self.spi.send(W_TX_PAYLOAD)
231+
self.spi.send(buf)
232+
if len(buf) < self.payload_size:
233+
self.spi.send(b'\x00' * (self.payload_size - len(buf))) # pad out data
234+
self.cs.high()
235+
236+
# enable the chip so it can send the data
237+
self.ce.high()
238+
pyb.udelay(15) # needs to be >10us
239+
self.ce.low()
240+
init = False
241+
return None # Not ready
242+
243+
if not (self.reg_read(STATUS) & (TX_DS | MAX_RT)):
244+
return None # Not ready
245+
# Either ready or failed: get and clear status flags, power down
246+
status = self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT)
247+
self.reg_write(CONFIG, self.reg_read(CONFIG) & ~PWR_UP)
248+
return 1 if status & TX_DS else 2
249+
return make_snb
250+

0 commit comments

Comments
 (0)