Skip to content
Snippets Groups Projects
Commit 5deceb84 authored by Peter Hinch's avatar Peter Hinch Committed by Damien George
Browse files

drivers, nrf24: Add nonblocking send option etc.

parent b66a31c4
Branches
Tags
No related merge requests found
"""NRF24L01 driver for Micro Python""" """NRF24L01 driver for Micro Python
Support for nonblocking send added. Minor fixes:
Timeout now uses pyb.elapsed_millis().
Channel numbers constrained to 125 as per datasheet.
Status register read with reg_read() - reg_read_ret_status() removed.
Default speed 250K for improved range/error rate.
"""
import pyb import pyb
...@@ -69,8 +76,10 @@ class NRF24L01: ...@@ -69,8 +76,10 @@ class NRF24L01:
self.pipe0_read_addr = None self.pipe0_read_addr = None
pyb.delay(5) pyb.delay(5)
# set address width to 5 bytes # set address width to 5 bytes and check for device present
self.reg_write(SETUP_AW, 0b11) self.reg_write(SETUP_AW, 0b11)
if self.reg_read(SETUP_AW) != 0b11:
raise OSError("nRF24l01+ Hardware not responding")
# disable dynamic payloads # disable dynamic payloads
self.reg_write(DYNPD, 0) self.reg_write(DYNPD, 0)
...@@ -80,7 +89,7 @@ class NRF24L01: ...@@ -80,7 +89,7 @@ class NRF24L01:
self.reg_write(SETUP_RETR, (6 << 4) | 8) self.reg_write(SETUP_RETR, (6 << 4) | 8)
# set rf power and speed # set rf power and speed
self.set_power_speed(POWER_3, SPEED_1M) self.set_power_speed(POWER_3, SPEED_250K) # Best for point to point links
# init CRC # init CRC
self.set_crc(2) self.set_crc(2)
...@@ -102,13 +111,6 @@ class NRF24L01: ...@@ -102,13 +111,6 @@ class NRF24L01:
self.cs.high() self.cs.high()
return buf[0] return buf[0]
def reg_read_ret_status(self, reg):
self.cs.low()
status = self.spi.send_recv(reg)[0]
buf = self.spi.recv(1)
self.cs.high()
return status
def reg_write(self, reg, buf): def reg_write(self, reg, buf):
self.cs.low() self.cs.low()
status = self.spi.send_recv(0x20 | reg)[0] status = self.spi.send_recv(0x20 | reg)[0]
...@@ -143,7 +145,7 @@ class NRF24L01: ...@@ -143,7 +145,7 @@ class NRF24L01:
self.reg_write(CONFIG, config) self.reg_write(CONFIG, config)
def set_channel(self, channel): def set_channel(self, channel):
self.reg_write(RF_CH, min(channel, 127)) self.reg_write(RF_CH, min(channel, 125)) # Changed from 127
# address should be a bytes object 5 bytes long # address should be a bytes object 5 bytes long
def open_tx_pipe(self, address): def open_tx_pipe(self, address):
...@@ -194,13 +196,31 @@ class NRF24L01: ...@@ -194,13 +196,31 @@ class NRF24L01:
self.spi.send(R_RX_PAYLOAD) self.spi.send(R_RX_PAYLOAD)
buf = self.spi.recv(self.payload_size) buf = self.spi.recv(self.payload_size)
self.cs.high() self.cs.high()
# clear RX ready flag # clear RX ready flag
self.reg_write(STATUS, RX_DR) self.reg_write(STATUS, RX_DR)
return buf return buf
# blocking wait for tx complete
def send(self, buf, timeout=500): def send(self, buf, timeout=500):
send_nonblock = self.send_nonblocking(buf)
start = pyb.millis()
result = None
while result is None and (pyb.elapsed_millis(start) < timeout):
result = send_nonblock() # 1 == success 2 == fail
if result == 2:
raise OSError("send failed")
def send_nonblocking(self, buf):
'''
Support for nonblocking transmission. Returns a function instance.
The first call to a function instance sends the data and returns None.
Subsequent calls test TX status returning not ready None, ready 1, error 2.
'''
init = True
def make_snb():
nonlocal init
if init:
# power up # power up
self.reg_write(CONFIG, (self.reg_read(CONFIG) | PWR_UP) & ~PRIM_RX) self.reg_write(CONFIG, (self.reg_read(CONFIG) | PWR_UP) & ~PRIM_RX)
pyb.udelay(150) pyb.udelay(150)
...@@ -217,18 +237,14 @@ class NRF24L01: ...@@ -217,18 +237,14 @@ class NRF24L01:
self.ce.high() self.ce.high()
pyb.udelay(15) # needs to be >10us pyb.udelay(15) # needs to be >10us
self.ce.low() self.ce.low()
init = False
return None # Not ready
# blocking wait for tx complete if not (self.reg_read(STATUS) & (TX_DS | MAX_RT)):
start = pyb.millis() return None # Not ready
while pyb.millis() - start < timeout: # Either ready or failed: get and clear status flags, power down
status = self.reg_read_ret_status(OBSERVE_TX)
if status & (TX_DS | MAX_RT):
break
# get and clear all status flags
status = self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT) status = self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT)
if not (status & TX_DS):
raise OSError("send failed")
# power down
self.reg_write(CONFIG, self.reg_read(CONFIG) & ~PWR_UP) self.reg_write(CONFIG, self.reg_read(CONFIG) & ~PWR_UP)
return 1 if status & TX_DS else 2
return make_snb
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment