drivers/nrf24l01: Update to work on newer ports, using machine, utime.
Changes made are: - Use the time module in place of the pyb module for delays. - Use spi.read/spi.write instead of spi.send/spi.receive. - Drop some non-portable parameters to spi and pin initialization. Thanks to @deshipu for the original patch.
This commit is contained in:
parent
3e1310d6e2
commit
d7310fabc2
@ -2,7 +2,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from micropython import const
|
from micropython import const
|
||||||
import pyb
|
import utime
|
||||||
|
|
||||||
# nRF24L01+ registers
|
# nRF24L01+ registers
|
||||||
CONFIG = const(0x00)
|
CONFIG = const(0x00)
|
||||||
@ -53,22 +53,24 @@ class NRF24L01:
|
|||||||
def __init__(self, spi, cs, ce, channel=46, payload_size=16):
|
def __init__(self, spi, cs, ce, channel=46, payload_size=16):
|
||||||
assert payload_size <= 32
|
assert payload_size <= 32
|
||||||
|
|
||||||
# init the SPI bus and pins
|
self.buf = bytearray(1)
|
||||||
spi.init(spi.MASTER, baudrate=4000000, polarity=0, phase=0, firstbit=spi.MSB)
|
|
||||||
cs.init(cs.OUT_PP, cs.PULL_NONE)
|
|
||||||
ce.init(ce.OUT_PP, ce.PULL_NONE)
|
|
||||||
|
|
||||||
# store the pins
|
# store the pins
|
||||||
self.spi = spi
|
self.spi = spi
|
||||||
self.cs = cs
|
self.cs = cs
|
||||||
self.ce = ce
|
self.ce = ce
|
||||||
|
|
||||||
|
# init the SPI bus and pins
|
||||||
|
self.init_spi(4000000)
|
||||||
|
cs.init(cs.OUT, value=1)
|
||||||
|
ce.init(ce.OUT, value=0)
|
||||||
|
|
||||||
# reset everything
|
# reset everything
|
||||||
self.ce.low()
|
self.ce.low()
|
||||||
self.cs.high()
|
self.cs.high()
|
||||||
self.payload_size = payload_size
|
self.payload_size = payload_size
|
||||||
self.pipe0_read_addr = None
|
self.pipe0_read_addr = None
|
||||||
pyb.delay(5)
|
utime.sleep_ms(5)
|
||||||
|
|
||||||
# set address width to 5 bytes and check for device present
|
# set address width to 5 bytes and check for device present
|
||||||
self.reg_write(SETUP_AW, 0b11)
|
self.reg_write(SETUP_AW, 0b11)
|
||||||
@ -98,28 +100,44 @@ class NRF24L01:
|
|||||||
self.flush_rx()
|
self.flush_rx()
|
||||||
self.flush_tx()
|
self.flush_tx()
|
||||||
|
|
||||||
|
def init_spi(self, baudrate):
|
||||||
|
try:
|
||||||
|
master = self.spi.MASTER
|
||||||
|
except AttributeError:
|
||||||
|
self.spi.init(baudrate=baudrate, polarity=0, phase=0)
|
||||||
|
else:
|
||||||
|
self.spi.init(master, baudrate=baudrate, polarity=0, phase=0)
|
||||||
|
|
||||||
def reg_read(self, reg):
|
def reg_read(self, reg):
|
||||||
self.cs.low()
|
self.cs.low()
|
||||||
self.spi.send_recv(reg)
|
self.spi.readinto(self.buf, reg)
|
||||||
buf = self.spi.recv(1)
|
self.spi.readinto(self.buf)
|
||||||
self.cs.high()
|
self.cs.high()
|
||||||
return buf[0]
|
return self.buf[0]
|
||||||
|
|
||||||
def reg_write(self, reg, buf):
|
def reg_write_bytes(self, reg, buf):
|
||||||
self.cs.low()
|
self.cs.low()
|
||||||
status = self.spi.send_recv(0x20 | reg)[0]
|
self.spi.readinto(self.buf, 0x20 | reg)
|
||||||
self.spi.send(buf)
|
self.spi.write(buf)
|
||||||
self.cs.high()
|
self.cs.high()
|
||||||
return status
|
return self.buf[0]
|
||||||
|
|
||||||
|
def reg_write(self, reg, value):
|
||||||
|
self.cs.low()
|
||||||
|
self.spi.readinto(self.buf, 0x20 | reg)
|
||||||
|
ret = self.buf[0]
|
||||||
|
self.spi.readinto(self.buf, value)
|
||||||
|
self.cs.high()
|
||||||
|
return ret
|
||||||
|
|
||||||
def flush_rx(self):
|
def flush_rx(self):
|
||||||
self.cs.low()
|
self.cs.low()
|
||||||
self.spi.send(FLUSH_RX)
|
self.spi.readinto(self.buf, FLUSH_RX)
|
||||||
self.cs.high()
|
self.cs.high()
|
||||||
|
|
||||||
def flush_tx(self):
|
def flush_tx(self):
|
||||||
self.cs.low()
|
self.cs.low()
|
||||||
self.spi.send(FLUSH_TX)
|
self.spi.readinto(self.buf, FLUSH_TX)
|
||||||
self.cs.high()
|
self.cs.high()
|
||||||
|
|
||||||
# power is one of POWER_x defines; speed is one of SPEED_x defines
|
# power is one of POWER_x defines; speed is one of SPEED_x defines
|
||||||
@ -144,8 +162,8 @@ class NRF24L01:
|
|||||||
# 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):
|
||||||
assert len(address) == 5
|
assert len(address) == 5
|
||||||
self.reg_write(RX_ADDR_P0, address)
|
self.reg_write_bytes(RX_ADDR_P0, address)
|
||||||
self.reg_write(TX_ADDR, address)
|
self.reg_write_bytes(TX_ADDR, address)
|
||||||
self.reg_write(RX_PW_P0, self.payload_size)
|
self.reg_write(RX_PW_P0, self.payload_size)
|
||||||
|
|
||||||
# address should be a bytes object 5 bytes long
|
# address should be a bytes object 5 bytes long
|
||||||
@ -157,7 +175,7 @@ class NRF24L01:
|
|||||||
if pipe_id == 0:
|
if pipe_id == 0:
|
||||||
self.pipe0_read_addr = address
|
self.pipe0_read_addr = address
|
||||||
if pipe_id < 2:
|
if pipe_id < 2:
|
||||||
self.reg_write(RX_ADDR_P0 + pipe_id, address)
|
self.reg_write_bytes(RX_ADDR_P0 + pipe_id, address)
|
||||||
else:
|
else:
|
||||||
self.reg_write(RX_ADDR_P0 + pipe_id, address[0])
|
self.reg_write(RX_ADDR_P0 + pipe_id, address[0])
|
||||||
self.reg_write(RX_PW_P0 + pipe_id, self.payload_size)
|
self.reg_write(RX_PW_P0 + pipe_id, self.payload_size)
|
||||||
@ -168,12 +186,12 @@ class NRF24L01:
|
|||||||
self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT)
|
self.reg_write(STATUS, RX_DR | TX_DS | MAX_RT)
|
||||||
|
|
||||||
if self.pipe0_read_addr is not None:
|
if self.pipe0_read_addr is not None:
|
||||||
self.reg_write(RX_ADDR_P0, self.pipe0_read_addr)
|
self.reg_write_bytes(RX_ADDR_P0, self.pipe0_read_addr)
|
||||||
|
|
||||||
self.flush_rx()
|
self.flush_rx()
|
||||||
self.flush_tx()
|
self.flush_tx()
|
||||||
self.ce.high()
|
self.ce.high()
|
||||||
pyb.udelay(130)
|
utime.sleep_us(130)
|
||||||
|
|
||||||
def stop_listening(self):
|
def stop_listening(self):
|
||||||
self.ce.low()
|
self.ce.low()
|
||||||
@ -187,8 +205,8 @@ class NRF24L01:
|
|||||||
def recv(self):
|
def recv(self):
|
||||||
# get the data
|
# get the data
|
||||||
self.cs.low()
|
self.cs.low()
|
||||||
self.spi.send(R_RX_PAYLOAD)
|
self.spi.readinto(self.buf, R_RX_PAYLOAD)
|
||||||
buf = self.spi.recv(self.payload_size)
|
buf = self.spi.read(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)
|
||||||
@ -198,9 +216,9 @@ class NRF24L01:
|
|||||||
# blocking wait for tx complete
|
# blocking wait for tx complete
|
||||||
def send(self, buf, timeout=500):
|
def send(self, buf, timeout=500):
|
||||||
send_nonblock = self.send_start(buf)
|
send_nonblock = self.send_start(buf)
|
||||||
start = pyb.millis()
|
start = utime.ticks_ms()
|
||||||
result = None
|
result = None
|
||||||
while result is None and pyb.elapsed_millis(start) < timeout:
|
while result is None and utime.ticks_diff(utime.ticks_ms(), start) < timeout:
|
||||||
result = self.send_done() # 1 == success, 2 == fail
|
result = self.send_done() # 1 == success, 2 == fail
|
||||||
if result == 2:
|
if result == 2:
|
||||||
raise OSError("send failed")
|
raise OSError("send failed")
|
||||||
@ -209,18 +227,18 @@ class NRF24L01:
|
|||||||
def send_start(self, buf):
|
def send_start(self, buf):
|
||||||
# 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)
|
utime.sleep_us(150)
|
||||||
# send the data
|
# send the data
|
||||||
self.cs.low()
|
self.cs.low()
|
||||||
self.spi.send(W_TX_PAYLOAD)
|
self.spi.readinto(self.buf, W_TX_PAYLOAD)
|
||||||
self.spi.send(buf)
|
self.spi.write(buf)
|
||||||
if len(buf) < self.payload_size:
|
if len(buf) < self.payload_size:
|
||||||
self.spi.send(b'\x00' * (self.payload_size - len(buf))) # pad out data
|
self.spi.write(b'\x00' * (self.payload_size - len(buf))) # pad out data
|
||||||
self.cs.high()
|
self.cs.high()
|
||||||
|
|
||||||
# enable the chip so it can send the data
|
# enable the chip so it can send the data
|
||||||
self.ce.high()
|
self.ce.high()
|
||||||
pyb.udelay(15) # needs to be >10us
|
utime.sleep_us(15) # needs to be >10us
|
||||||
self.ce.low()
|
self.ce.low()
|
||||||
|
|
||||||
# returns None if send still in progress, 1 for success, 2 for fail
|
# returns None if send still in progress, 1 for success, 2 for fail
|
||||||
|
Loading…
x
Reference in New Issue
Block a user