Skip to content

Commit ed6dd9f

Browse files
committed
library improvements
1 parent 0660088 commit ed6dd9f

File tree

1 file changed

+86
-66
lines changed

1 file changed

+86
-66
lines changed

sx1280.py

Lines changed: 86 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,6 @@
22
import digitalio
33
from micropython import const
44

5-
try:
6-
from warnings import warn
7-
except ImportError:
8-
def warn(msg, **kwargs):
9-
"Issue a warning to stdout."
10-
print("%s: %s" % ("Warning" if kwargs.get("cat") is None else kwargs["cat"].__name__, msg))
11-
125
import adafruit_bus_device.spi_device as spidev
136

147
# Radio Commands
@@ -58,7 +51,9 @@ def warn(msg, **kwargs):
5851

5952

6053
class SX1280:
54+
_BIGBUFFER=bytearray(257)
6155
_status=bytearray(1)
56+
_status_msg={'mode':'','cmd':'','busy':False}
6257
_status_mode={0:'N/A',
6358
1:'N/A',
6459
2:'STDBY_RC',
@@ -73,58 +68,60 @@ class SX1280:
7368
4:'Cmd Error',
7469
5:'Failure to Execute Cmd',
7570
6:'Tx Done'}
76-
71+
_mode_mask = const(0xE0)
72+
_cmd_stat_mask = const(0x1C)
7773
_BUFFER = bytearray(10)
7874
def __init__(self, spi, cs, reset, busy, *, preamble_length=8, baudrate=1500000, debug=False):
7975
# self._device = spidev.SPIDevice(spi, cs, baudrate=baudrate, polarity=0, phase=0)
8076
self._device = spidev.SPIDevice(spi, cs, polarity=0, phase=0)
8177
self._reset = reset
8278
self._reset.switch_to_input(pull=digitalio.Pull.UP)
8379
self._busy = busy
84-
self._busy.switch_to_input()
80+
self._busy.switch_to_input()
8581
self.packet_type = _PACKET_TYPE_GFSK # default
8682
self._debug = debug
83+
self._debug2 = True
8784
self._set_ranging = False
8885
self._ranging=False
8986
self._status = 0
87+
self._autoFS=False
9088

9189
self.reset()
9290
self._busywait()
91+
self._listen=False
9392

9493
self.clear_Irq_Status()
9594
self.set_Regulator_Mode()
96-
self.set_Packet_Type() # default LoRa
95+
self.set_Packet_Type() # set to LoRa
9796
self.set_Standby('STDBY_RC')
9897
self.set_Modulation_Params()
9998
self.set_Packet_Params(pktParam3=0x05)
10099
self.set_RF_Freq() # 2.4GHz
101100
self.set_Buffer_Base_Address()
102101
self.set_Tx_Param() # power=13dBm,rampTime=20us
103-
print('Radio Initialized')
104-
# print(self.status)
105-
106-
def _convert_status(self,status):
107-
mode = (status >> 5)
108-
cmdstat = (status & 0x1C)>>2
109-
busy = 1 & status
110-
try:
111-
print('\t',hex(status))
112-
print('\tMode:',self._status_mode[mode])
113-
print('\tCmd Status:',self._status_cmd[cmdstat])
114-
except:
115-
pass
102+
if self._debug: print('Radio Initialized')
116103

104+
def _convert_status(self,status):
105+
mode = (status & _mode_mask)>>5
106+
cmdstat = (status & _cmd_stat_mask)>>2
107+
if mode in self._status_mode:
108+
self._status_msg['mode']=self._status_mode[mode]
109+
if cmdstat in self._status_cmd:
110+
self._status_msg['cmd']=self._status_cmd[cmdstat]
111+
self._status_msg['busy'] = not bool(status & 0x1)
112+
return self._status_msg
117113

118114
def _send_command(self,command):
119115
_size=len(command)
120116
self._busywait()
121117
with self._device as device:
122118
device.write_readinto(command,self._BUFFER,out_end=_size,in_end=_size)
123-
if self._debug:
124-
[print(hex(i),' ',end='') for i in command]
125-
print('')
119+
if self._debug2:
120+
# print('Command',end=': ')
121+
# [print(hex(i),end=' ') for i in self._BUFFER]
122+
# print('')
126123
self._status = self._BUFFER[0]
127-
self._convert_status(self._status)
124+
print(self._convert_status(self._status))
128125
return self._BUFFER[:_size]
129126

130127
def _writeRegister(self,address1,address2,data):
@@ -138,7 +135,7 @@ def _readRegister(self,address1,address2,_length=1):
138135
with self._device as device:
139136
device.write(bytes([_RADIO_READ_REGISTER,address1,address2]), end=3)
140137
device.readinto(self._BUFFER, end=_length+1)
141-
if self._debug:
138+
if self._debug:
142139
[print(hex(i),' ',end='')for i in self._BUFFER]
143140
print('')
144141
return self._BUFFER[1]
@@ -184,7 +181,7 @@ def set_Cad_Params(self,symbol=0x80):
184181
print('Setting CAD Parameters')
185182
self._send_command(bytes([_RADIO_SET_CADPARAMS, symbol]))
186183

187-
def set_Cad(self,symbol=0x80):
184+
def set_Cad(self):
188185
if self._debug:
189186
print('Setting CAD Search')
190187
self._send_command(bytes([_RADIO_SET_CAD]))
@@ -206,7 +203,7 @@ def set_Buffer_Base_Address(self,txBaseAddress=0x00,rxBaseAddress=0x00):
206203

207204
def set_Modulation_Params(self,modParam1=0x70,modParam2=0x26,modParam3=0x01):
208205
# LoRa: modParam1=SpreadingFactor, modParam2=Bandwidth, modParam3=CodingRate
209-
# LoRa with SF7, (BW1600=0x0A -> changed to BW400=0x26), CR 4/5
206+
# LoRa with SF7, (BW1600=0x0A -> changed to BW400=0x26), CR 4/5
210207
# Must set PacketType first! - See Table 13-48,49,50
211208
if self._debug:
212209
print('Setting Modulation parameters')
@@ -218,21 +215,21 @@ def set_Modulation_Params(self,modParam1=0x70,modParam2=0x26,modParam3=0x01):
218215
# If the Spreading Factor is SF7 or SF-8
219216
elif modParam1 in (0x70,0x80):
220217
self._writeRegister(0x09,0x25,0x37)
221-
# If the Spreading Factor is SF9, SF10, SF11 or SF12
218+
# If the Spreading Factor is SF9, SF10, SF11 or SF12
222219
elif modParam1 in (0x90,0xA0,0xB0,0xC0):
223220
self._writeRegister(0x09,0x25,0x32)
224221
else:
225222
print('Invalid Spreading Factor')
226223

227224
def set_Packet_Params(self,pktParam1=0x08, # PreamLen
228-
pktParam2=0x00,pktParam3=0x0F, # HeadType, PayloadLen
229-
pktParam4=0x20,pktParam5=0x00, # CRC, InvertIQ
230-
pktParam6=0x00,pktParam7=0x00): # unused
225+
pktParam2=0x00,pktParam3=0x0F, # HeadType, PayloadLen
226+
pktParam4=0x00,pktParam5=0x00, # CRC, InvertIQ
227+
pktParam6=0x00,pktParam7=0x00): # unused
231228
'''
232229
16 preamble symbols (0x0C) -> changed to 0x08
233230
variable length (0x00)
234231
128-byte payload (0x80)->changed to 15 (0x0F)
235-
CRC enabled (0x20)
232+
CRC disabled (0x00)
236233
standard IQ (0x40) -> changed to inverted (0x00)
237234
'''
238235
if self._debug:
@@ -247,49 +244,68 @@ def set_Tx_Param(self,power=0x1F,rampTime=0xE0):
247244

248245
def write_Buffer(self,data):
249246
#Offset will correspond to txBaseAddress in normal operation.
250-
251-
if self._debug:
252-
print('Writing Buffer')
253-
print('TX base address:',self._txBaseAddress)
254-
print('RX base address:',self._rxBaseAddress)
247+
# if self._debug:
248+
# print('Writing Buffer')
249+
# print('TX base address:',self._txBaseAddress)
250+
# print('RX base address:',self._rxBaseAddress)
255251
_offset = self._txBaseAddress
256252
_len = len(data)
257253
assert 0 < _len <= 252
258254
self._busywait()
259255
with self._device as device:
260256
device.write(bytes([_RADIO_WRITE_BUFFER,_offset])+data,end=_len+2)
261257
# device.write(data,end=_len)
262-
258+
263259
def read_Buffer(self,offset,payloadLen):
264260
_payload = bytearray(payloadLen)
265261
with self._device as device:
266262
device.write(bytes([_RADIO_READ_BUFFER,offset]), end=2)
267263
device.readinto(_payload, end=payloadLen)
268264
return _payload
269265

266+
def dump_buffer(self):
267+
buffer_out=bytes([_RADIO_READ_BUFFER,0x00])
268+
with self._device as device:
269+
device.write(bytes([_RADIO_READ_BUFFER,0x00]), end=2)
270+
device.readinto(self._BIGBUFFER, end=257)
271+
print('Status:',self._convert_status(self._BIGBUFFER[0]))
272+
[print(hex(i),end=',') for i in self._BIGBUFFER[1:]]
273+
print('')
274+
270275
def set_Dio_IRQ_Params(self,irqMask=[0x40,0x23],dio1Mask=[0x00,0x01],dio2Mask=[0x00,0x02],dio3Mask=[0x40,0x20]):
271-
# TxDone IRQ on DIO1, RxDone IRQ on DIO2, HeaderError and RxTxTimeout IRQ on DIO3
276+
'''
277+
TxDone IRQ on DIO1, RxDone IRQ on DIO2, HeaderError and RxTxTimeout IRQ on DIO3
278+
IRQmask (bit[0]=TxDone, bit[1]=RxDone)
279+
0x43: 0x23
280+
0100 0011 0010 0011
281+
DIO1mask
282+
0000 0000 0000 0001
283+
DIO2mask
284+
0000 0000 0000 0010
285+
'''
272286
if self._debug:
273287
print('Setting DIO IRQ Parameters')
274288
self._send_command(bytes([_RADIO_SET_DIOIRQPARAMS]+irqMask+dio1Mask+dio2Mask+dio3Mask))
275-
276-
def clear_Irq_Status(self):
289+
290+
def clear_Irq_Status(self, val=[0xFF,0xFF]):
277291
if self._debug:
278292
print('Clearing IRQ Status')
279-
self._send_command(bytes([_RADIO_CLR_IRQSTATUS, 0xFF, 0xFF]))
280-
281-
def get_Irq_Status(self):
293+
self._send_command(bytes([_RADIO_CLR_IRQSTATUS]+val))
294+
295+
def get_Irq_Status(self,clear=True):
282296
if self._debug:
283297
print('Getting IRQ Status')
284298
_stat = self._send_command(bytes([_RADIO_GET_IRQSTATUS,0x00,0x00,0x00]))
285-
self._send_command(bytes([_RADIO_CLR_IRQSTATUS, 0xFF, 0xFF])) # clear IRQ status
299+
if clear:
300+
self._send_command(bytes([_RADIO_CLR_IRQSTATUS, 0xFF, 0xFF])) # clear IRQ status
286301
return _stat
287302

288303
def set_Tx(self,pBase=0x02,pBaseCount=[0x00,0x00]):
289304
#Activate transmit mode with no timeout. Tx mode will stop after first packet sent.
290305
if self._debug:
291306
print('Setting Tx')
292307
self.clear_Irq_Status()
308+
# self.clear_Irq_Status([0x00,0x01])
293309
self._send_command(bytes([_RADIO_SET_TX, pBase, pBaseCount[0], pBaseCount[1]]))
294310

295311
def set_Rx(self,pBase=0x02,pBaseCount=[0xFF,0xFF]):
@@ -299,10 +315,14 @@ def set_Rx(self,pBase=0x02,pBaseCount=[0xFF,0xFF]):
299315
Time-out duration = pBase * periodBaseCount
300316
'''
301317
if self._debug:
302-
print('Setting Rx')
318+
print('\tSetting Rx')
303319
self.clear_Irq_Status()
304320
self._send_command(bytes([_RADIO_SET_RX, pBase]+pBaseCount))
305321

322+
def set_autoFS(self,value):
323+
self._send_command(bytes([_RADIO_SET_AUTOFS, bool(value)]))
324+
self._autoFS=value
325+
306326
def set_Ranging_Params(self,range_addr=[0x01,0x02,0x03,0x04], master=False, slave=False):
307327
self.set_Regulator_Mode()
308328
self.set_Packet_Type('RANGING') # default LoRa
@@ -330,15 +350,15 @@ def set_Ranging_Params(self,range_addr=[0x01,0x02,0x03,0x04], master=False, slav
330350
print('Select Master or Slave Only')
331351
return False
332352
# Ranging address length
333-
self._writeRegister(0x9,0x31,0x3)
353+
self._writeRegister(0x9,0x31,0x3)
334354
# Ranging Calibration-SF7/BW1600=13528=0x34D8 per Section 3.3 of SemTech AN1200.29
335355
self._writeRegister(0x9,0x2D,0x04)
336356
self._writeRegister(0x9,0x2C,0x28)
337357
# Set Ranging Role
338358
self._send_command(bytes([_RADIO_SET_RANGING_ROLE, self._rangingRole]))
339359
if slave:
340360
# Header Valid -> DIO1, Slave Response Done -> DIO2, Slave Request Discard -> DIO3
341-
self.set_Dio_IRQ_Params(irqMask=[0x01,0x90],dio1Mask=[0x00,0x10],dio2Mask=[0x00,0x80],dio3Mask=[0x00,0x01])
361+
self.set_Dio_IRQ_Params(irqMask=[0x01,0x90],dio1Mask=[0x00,0x10],dio2Mask=[0x00,0x80],dio3Mask=[0x00,0x01])
342362
elif master:
343363
# Header Valid -> DIO1, Master Result Valid -> DIO2, Master Timeout -> DIO3
344364
self.set_Dio_IRQ_Params(irqMask=[0x0E,0x10],dio1Mask=[0x00,0x10],dio2Mask=[0x02,0x00],dio3Mask=[0x04,0x00])
@@ -348,7 +368,7 @@ def set_Ranging_Params(self,range_addr=[0x01,0x02,0x03,0x04], master=False, slav
348368
def range(self):
349369
if not self._set_ranging:
350370
print('Configure ranging parameters first')
351-
return False
371+
return False
352372
if self._rangingRole == 0x00: # slave
353373
self.set_Rx(pBase=0x02,pBaseCount=[0xFF,0xFF])
354374
elif self._rangingRole == 0x01: #master
@@ -377,7 +397,7 @@ def read_range(self,raw=False):
377397
_val = 0 | (self._readRegister(0x9,0x61)<< 16)
378398
_val |= (self._readRegister(0x9,0x62)<< 8)
379399
_val |= (self._readRegister(0x9,0x62))
380-
400+
381401
if raw:
382402
_valLSB = _val
383403
# Handle twos-complement stuff
@@ -398,7 +418,7 @@ def get_Packet_Status(self):
398418
# [print(hex(i)+' ',end='') for i in self._BUFFER[:6]]
399419
self.rssiSync = (-1*int(p_stat[2])/2)
400420
self.snr = (int(p_stat[3])/4)
401-
421+
402422

403423
def get_Rx_Buffer_Status(self):
404424
self._send_command(bytes([_RADIO_GET_RXBUFFERSTATUS,0x00,0x00,0x00]))
@@ -423,18 +443,20 @@ def packet_status(self):
423443
@property
424444
def listen(self):
425445
return self._listen
426-
446+
427447
@listen.setter
428448
def listen(self, enable):
429449
if enable:
430-
self.set_Dio_IRQ_Params(irqMask=[0x40,0x23],dio1Mask=[0x00,0x01],dio2Mask=[0x00,0x02],dio3Mask=[0x40,0x20]) # DEFAULT:TxDone IRQ on DIO1, RxDone IRQ on DIO2, HeaderError and RxTxTimeout IRQ on DIO3
450+
# self.set_Dio_IRQ_Params()
431451
self.set_Rx()
432452
self._listen = True
433453
else:
434454
self.set_Standby('STDBY_RC')
435455
self._listen = False
436456

437-
def receive(self, continuous=True):
457+
def receive(self, continuous=True, keep_listening=True):
458+
if not self._listen:
459+
self.listen = True
438460
if continuous:
439461
self._buf_status = self.get_Rx_Buffer_Status()
440462
self._packet_len = self._buf_status[2]
@@ -443,23 +465,21 @@ def receive(self, continuous=True):
443465
if self._debug:
444466
print('Offset:',self._packet_pointer,'Length:',self._packet_len)
445467
packet = self.read_Buffer(offset=self._packet_pointer,payloadLen=self._packet_len+1)
468+
if not keep_listening:
469+
self.listen = False
446470
return packet[1:]
447-
471+
448472
@property
449473
def packet_info(self):
450474
return (self._packet_len,self._packet_pointer)
451475

452476
@property
453477
def RSSI(self):
454478
self._rssi = self._send_command(bytes([_RADIO_GET_RSSIINST, 0x00,0x00]))
455-
return self._rssi
479+
return self._rssi
456480

457481
@property
458482
def status(self):
459-
_status = bin(self._send_command(bytes([_RADIO_GET_STATUS]))[0])
460-
try:
461-
# print('{0:08b} Mode:{1}, Cmd Status:{2}'.format(int(_status),self._status_mode[int(_status[:3])],self._status_cmd[int(_status[3:6])]))
462-
# return (_status,self._status_mode[int(_status[:4])],self._status_cmd[int(_status[4:7])])
463-
return _status
464-
except Exception as e:
465-
print(e)
483+
a = self._send_command(bytes([_RADIO_GET_STATUS]))[0]
484+
if a:
485+
return self._convert_status(a)

0 commit comments

Comments
 (0)