22import digitalio
33from 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-
125import adafruit_bus_device .spi_device as spidev
136
147# Radio Commands
@@ -58,7 +51,9 @@ def warn(msg, **kwargs):
5851
5952
6053class 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 ('\t Mode:' ,self ._status_mode [mode ])
113- print ('\t Cmd 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 ('\t Setting 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