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
310import 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