tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/sx127x/sx127x.go (about)

     1  // Package sx127x provides a driver for SX127x LoRa transceivers.
     2  // References:
     3  // https://electronics.stackexchange.com/questions/394296/can-t-get-simple-lora-receiver-to-work
     4  // https://www.st.com/resource/en/user_manual/dm00300436-stm32-lora-expansion-package-for-stm32cube-stmicroelectronics.pdf
     5  package sx127x
     6  
     7  import (
     8  	"errors"
     9  	"machine"
    10  	"time"
    11  
    12  	"tinygo.org/x/drivers"
    13  	"tinygo.org/x/drivers/lora"
    14  )
    15  
    16  // So we can keep track of the origin of interruption
    17  const (
    18  	RADIOEVENTCHAN_SIZE = 1
    19  	SPI_BUFFER_SIZE     = 5
    20  )
    21  
    22  // Device wraps an SPI connection to a SX127x device.
    23  type Device struct {
    24  	spi            drivers.SPI          // SPI bus for module communication
    25  	rstPin         machine.Pin          // GPIO for reset
    26  	radioEventChan chan lora.RadioEvent // Channel for Receiving events
    27  	loraConf       lora.Config          // Current Lora configuration
    28  	controller     RadioController      // to manage interactions with the radio
    29  	deepSleep      bool                 // Internal Sleep state
    30  	deviceType     int                  // sx1261,sx1262,sx1268 (defaults sx1261)
    31  	spiTxBuf       []byte               // global Tx buffer to avoid heap allocations in interrupt
    32  	spiRxBuf       []byte               // global Rx buffer to avoid heap allocations in interrupt
    33  }
    34  
    35  // --------------------------------------------------
    36  //
    37  //	Channel and events
    38  //
    39  // --------------------------------------------------
    40  // Get the RadioEvent channel of the device
    41  func (d *Device) GetRadioEventChan() chan lora.RadioEvent {
    42  	return d.radioEventChan
    43  }
    44  
    45  // New creates a new SX127x connection. The SPI bus must already be configured.
    46  func New(spi machine.SPI, rstPin machine.Pin) *Device {
    47  	k := Device{
    48  		spi:            spi,
    49  		rstPin:         rstPin,
    50  		radioEventChan: make(chan lora.RadioEvent, RADIOEVENTCHAN_SIZE),
    51  		spiTxBuf:       make([]byte, SPI_BUFFER_SIZE),
    52  		spiRxBuf:       make([]byte, SPI_BUFFER_SIZE),
    53  	}
    54  	return &k
    55  }
    56  
    57  // SetRadioControl let you define the RadioController
    58  func (d *Device) SetRadioController(rc RadioController) error {
    59  	d.controller = rc
    60  	if err := d.controller.Init(); err != nil {
    61  		return err
    62  	}
    63  	d.controller.SetupInterrupts(d.HandleInterrupt)
    64  
    65  	return nil
    66  }
    67  
    68  // Reset re-initialize the sx127x device
    69  func (d *Device) Reset() {
    70  	d.rstPin.Low()
    71  	time.Sleep(100 * time.Millisecond)
    72  	d.rstPin.High()
    73  	time.Sleep(100 * time.Millisecond)
    74  }
    75  
    76  // DetectDevice checks if device responds on the SPI bus
    77  func (d *Device) DetectDevice() bool {
    78  	id := d.GetVersion()
    79  	return (id == 0x12)
    80  }
    81  
    82  // ReadRegister reads register value
    83  func (d *Device) ReadRegister(reg uint8) uint8 {
    84  	d.controller.SetNss(false)
    85  	// Send register
    86  	//d.spiTxBuf = []byte{reg & 0x7f}
    87  	d.spiTxBuf = d.spiTxBuf[:0]
    88  	d.spiTxBuf = append(d.spiTxBuf, byte(reg&0x7f))
    89  	d.spi.Tx(d.spiTxBuf, nil)
    90  	// Read value
    91  	d.spiRxBuf = d.spiRxBuf[:0]
    92  	d.spiRxBuf = append(d.spiRxBuf, 0)
    93  	d.spi.Tx(nil, d.spiRxBuf)
    94  	d.controller.SetNss(true)
    95  	return d.spiRxBuf[0]
    96  }
    97  
    98  // WriteRegister writes value to register
    99  func (d *Device) WriteRegister(reg uint8, value uint8) uint8 {
   100  	d.controller.SetNss(false)
   101  	// Send register
   102  	d.spiTxBuf = d.spiTxBuf[:0]
   103  	d.spiTxBuf = append(d.spiTxBuf, byte(reg|0x80))
   104  	d.spi.Tx(d.spiTxBuf, nil)
   105  	// Send value
   106  	d.spiTxBuf = d.spiTxBuf[:0]
   107  	d.spiTxBuf = append(d.spiTxBuf, byte(value))
   108  	d.spiRxBuf = d.spiRxBuf[:0]
   109  	d.spiRxBuf = append(d.spiRxBuf, 0)
   110  	d.spi.Tx(d.spiTxBuf, d.spiRxBuf)
   111  	d.controller.SetNss(true)
   112  	return d.spiRxBuf[0]
   113  }
   114  
   115  // SetOpMode changes the sx1276 mode
   116  func (d *Device) SetOpMode(mode uint8) {
   117  	cur := d.ReadRegister(SX127X_REG_OP_MODE)
   118  	new := (cur & (^SX127X_OPMODE_MASK)) | mode
   119  	d.WriteRegister(SX127X_REG_OP_MODE, new)
   120  }
   121  
   122  // SetOpMode changes the sx1276 mode
   123  func (d *Device) SetOpModeLora() {
   124  	d.WriteRegister(SX127X_REG_OP_MODE, SX127X_OPMODE_LORA)
   125  }
   126  
   127  // GetVersion returns hardware version of sx1276 chipset
   128  func (d *Device) GetVersion() uint8 {
   129  	return (d.ReadRegister(SX127X_REG_VERSION))
   130  }
   131  
   132  // IsTransmitting tests if a packet transmission is in progress
   133  func (d *Device) IsTransmitting() bool {
   134  	return (d.ReadRegister(SX127X_REG_OP_MODE) & SX127X_OPMODE_TX) == SX127X_OPMODE_TX
   135  }
   136  
   137  // LastPacketRSSI gives the RSSI of the last packet received
   138  func (d *Device) LastPacketRSSI() uint8 {
   139  	// section 5.5.5
   140  	var adjustValue uint8 = 157
   141  	if d.loraConf.Freq < 868000000 {
   142  		adjustValue = 164
   143  	}
   144  	return d.ReadRegister(SX127X_REG_PKT_RSSI_VALUE) - adjustValue
   145  }
   146  
   147  // LastPacketSNR gives the SNR of the last packet received
   148  func (d *Device) LastPacketSNR() uint8 {
   149  	return uint8(d.ReadRegister(SX127X_REG_PKT_SNR_VALUE) / 4)
   150  }
   151  
   152  // GetRSSI returns current RSSI
   153  func (d *Device) GetRSSI() uint8 {
   154  	return d.ReadRegister(SX127X_REG_RSSI_VALUE)
   155  }
   156  
   157  /*
   158  // GetBandwidth returns the bandwidth the LoRa module is using
   159  func (d *Device) GetBandwidth() int32 {
   160  	return int32(d.loraConf.Bw)
   161  }
   162  */
   163  
   164  // SetTxPowerWithPaBoost sets the transmitter output power and may activate paBoost
   165  func (d *Device) SetTxPowerWithPaBoost(txPower int8, paBoost bool) {
   166  	if !paBoost {
   167  		// RFO
   168  		if txPower < 0 {
   169  			txPower = 0
   170  		} else if txPower > 14 {
   171  			txPower = 14
   172  		}
   173  		d.WriteRegister(SX127X_REG_PA_CONFIG, uint8(0x70)|uint8(txPower))
   174  
   175  	} else {
   176  		//PA_BOOST
   177  		if txPower > 17 {
   178  			if txPower > 20 {
   179  				txPower = 20
   180  			}
   181  
   182  			txPower -= 3
   183  
   184  			// High Power +20 dBm Operation (Semtech SX1276/77/78/79 5.4.3.)
   185  			d.WriteRegister(SX127X_REG_PA_DAC, 0x87)
   186  			d.SetOCP(140)
   187  		} else {
   188  			if txPower < 2 {
   189  				txPower = 2
   190  			}
   191  
   192  			d.WriteRegister(SX127X_REG_PA_DAC, 0x84)
   193  			d.SetOCP(100)
   194  
   195  		}
   196  
   197  		d.WriteRegister(SX127X_REG_PA_CONFIG, uint8(SX127X_PA_BOOST)|uint8(txPower-2))
   198  
   199  	}
   200  }
   201  
   202  // ---------------
   203  // Internal functions
   204  // ---------------
   205  
   206  // SetRxTimeout defines RX Timeout expressed as number of symbols
   207  // Default timeout is 64 * Ts
   208  func (d *Device) SetRxTimeout(tmoutSymb uint8) {
   209  	d.WriteRegister(SX127X_REG_SYMB_TIMEOUT_LSB, tmoutSymb)
   210  }
   211  
   212  // SetOCP defines Overload Current Protection configuration
   213  func (d *Device) SetOCP(mA uint8) {
   214  	ocpTrim := uint8(27)
   215  	if mA < 45 {
   216  		mA = 45
   217  	}
   218  	if mA <= 120 {
   219  		ocpTrim = (mA - 45) / 5
   220  	} else if mA <= 240 {
   221  		ocpTrim = (mA + 30) / 10
   222  	}
   223  	d.WriteRegister(SX127X_REG_OCP, 0x20|(0x1F&ocpTrim))
   224  }
   225  
   226  // SetAgcAutoOn enables Automatic Gain Control
   227  func (d *Device) SetAgcAuto(val uint8) {
   228  	if val == SX127X_AGC_AUTO_ON {
   229  		d.WriteRegister(SX127X_REG_MODEM_CONFIG_3, d.ReadRegister(SX127X_REG_MODEM_CONFIG_3)|0x04)
   230  	} else {
   231  		d.WriteRegister(SX127X_REG_MODEM_CONFIG_3, d.ReadRegister(SX127X_REG_MODEM_CONFIG_3)&0xfb)
   232  	}
   233  }
   234  
   235  // SetLowDataRateOptimize enables Low Data Rate Optimization
   236  func (d *Device) SetLowDataRateOptim(val uint8) {
   237  	if val == lora.LowDataRateOptimizeOn {
   238  		d.WriteRegister(SX127X_REG_MODEM_CONFIG_3, d.ReadRegister(SX127X_REG_MODEM_CONFIG_3)|0x08)
   239  	} else {
   240  		d.WriteRegister(SX127X_REG_MODEM_CONFIG_3, d.ReadRegister(SX127X_REG_MODEM_CONFIG_3)&0xf7)
   241  	}
   242  }
   243  
   244  // SetLowFrequencyModeOn enables Low Data Rate Optimization
   245  func (d *Device) SetLowFrequencyModeOn(val bool) {
   246  	if val {
   247  		d.WriteRegister(SX127X_REG_OP_MODE, d.ReadRegister(SX127X_REG_OP_MODE)|0x04)
   248  	} else {
   249  		d.WriteRegister(SX127X_REG_OP_MODE, d.ReadRegister(SX127X_REG_OP_MODE)&0xfb)
   250  	}
   251  }
   252  
   253  // SetHopPeriod sets number of symbol periods between frequency hops. (0 = disabled).
   254  func (d *Device) SetHopPeriod(val uint8) {
   255  	d.WriteRegister(SX127X_REG_HOP_PERIOD, val)
   256  }
   257  
   258  //
   259  // LORA FUNCTIONS
   260  //
   261  
   262  // LoraConfig() defines Lora configuration for next Lora operations
   263  func (d *Device) LoraConfig(cnf lora.Config) {
   264  	// Save given configuration
   265  	d.loraConf = cnf
   266  	d.loraConf.SyncWord = syncword(int(cnf.SyncWord))
   267  }
   268  
   269  // SetFrequency updates the frequency the LoRa module is using
   270  func (d *Device) SetFrequency(frequency uint32) {
   271  	d.loraConf.Freq = frequency
   272  	var frf = (uint64(frequency) << 19) / 32000000
   273  	d.WriteRegister(SX127X_REG_FRF_MSB, uint8(frf>>16))
   274  	d.WriteRegister(SX127X_REG_FRF_MID, uint8(frf>>8))
   275  	d.WriteRegister(SX127X_REG_FRF_LSB, uint8(frf>>0))
   276  }
   277  
   278  // SetBandwidth updates the bandwidth the LoRa module is using
   279  func (d *Device) SetBandwidth(bw uint8) {
   280  	d.loraConf.Bw = bandwidth(bw)
   281  	d.WriteRegister(SX127X_REG_MODEM_CONFIG_1, (d.ReadRegister(SX127X_REG_MODEM_CONFIG_1)&0x0f)|(bw<<4))
   282  }
   283  
   284  // SetCodingRate updates the coding rate the LoRa module is using
   285  func (d *Device) SetCodingRate(cr uint8) {
   286  	d.loraConf.Cr = cr
   287  	d.WriteRegister(SX127X_REG_MODEM_CONFIG_1, (d.ReadRegister(SX127X_REG_MODEM_CONFIG_1)&0xf1)|(cr<<1))
   288  }
   289  
   290  // SetHeaderType set implicit or explicit mode
   291  func (d *Device) SetHeaderType(headerType uint8) {
   292  	d.loraConf.HeaderType = headerType
   293  	if headerType == lora.HeaderImplicit {
   294  		d.WriteRegister(SX127X_REG_MODEM_CONFIG_1, d.ReadRegister(SX127X_REG_MODEM_CONFIG_1)|0x01)
   295  	} else {
   296  		d.WriteRegister(SX127X_REG_MODEM_CONFIG_1, d.ReadRegister(SX127X_REG_MODEM_CONFIG_1)&0xfe)
   297  	}
   298  }
   299  
   300  // SetSpreadingFactor changes spreading factor
   301  func (d *Device) SetSpreadingFactor(sf uint8) {
   302  	d.loraConf.Sf = sf
   303  	if sf == lora.SpreadingFactor6 {
   304  		d.WriteRegister(SX127X_REG_DETECTION_OPTIMIZE, 0xc5)
   305  		d.WriteRegister(SX127X_REG_DETECTION_THRESHOLD, 0x0c)
   306  	} else {
   307  		d.WriteRegister(SX127X_REG_DETECTION_OPTIMIZE, 0xc3)
   308  		d.WriteRegister(SX127X_REG_DETECTION_THRESHOLD, 0x0a)
   309  	}
   310  	var newValue = (d.ReadRegister(SX127X_REG_MODEM_CONFIG_2) & 0x0f) | ((sf << 4) & 0xf0)
   311  	d.WriteRegister(SX127X_REG_MODEM_CONFIG_2, newValue)
   312  }
   313  
   314  // SetTxPower sets the transmitter output (with paBoost ON)
   315  func (d *Device) SetTxPower(txPower int8) {
   316  	d.loraConf.LoraTxPowerDBm = txPower
   317  	d.SetTxPowerWithPaBoost(txPower, true)
   318  }
   319  
   320  // SetCrc Enable CRC generation and check on payload
   321  func (d *Device) SetCrc(enable bool) {
   322  	if enable {
   323  		d.loraConf.Crc = lora.CRCOn
   324  		d.WriteRegister(SX127X_REG_MODEM_CONFIG_2, d.ReadRegister(SX127X_REG_MODEM_CONFIG_2)|0x04)
   325  	} else {
   326  		d.loraConf.Crc = lora.CRCOff
   327  		d.WriteRegister(SX127X_REG_MODEM_CONFIG_2, d.ReadRegister(SX127X_REG_MODEM_CONFIG_2)&0xfb)
   328  	}
   329  }
   330  
   331  // SetPreambleLength defines number of preamble
   332  func (d *Device) SetPreambleLength(pLen uint16) {
   333  	d.loraConf.Preamble = pLen
   334  	d.WriteRegister(SX127X_REG_PREAMBLE_MSB, uint8((pLen>>8)&0xFF))
   335  	d.WriteRegister(SX127X_REG_PREAMBLE_LSB, uint8(pLen&0xFF))
   336  }
   337  
   338  // SetSyncWord defines sync word
   339  func (d *Device) SetSyncWord(syncWord uint16) {
   340  	d.loraConf.SyncWord = syncWord
   341  	sw := uint8(syncWord & 0xFF)
   342  	d.WriteRegister(SX127X_REG_SYNC_WORD, sw)
   343  }
   344  
   345  // SetIQMode Sets I/Q polarity configuration
   346  func (d *Device) SetIqMode(val uint8) {
   347  	d.loraConf.Iq = val
   348  	if val == lora.IQStandard {
   349  		//Set IQ to normal values
   350  		d.WriteRegister(SX127X_REG_INVERTIQ, 0x27)
   351  		d.WriteRegister(SX127X_REG_INVERTIQ2, 0x1D)
   352  	} else {
   353  		//Invert IQ Back
   354  		d.WriteRegister(SX127X_REG_INVERTIQ, 0x66)
   355  		d.WriteRegister(SX127X_REG_INVERTIQ2, 0x19)
   356  	}
   357  }
   358  
   359  // SetPublicNetwork changes Sync Word to match network type
   360  func (d *Device) SetPublicNetwork(enabled bool) {
   361  	if enabled {
   362  		d.SetSyncWord(SX127X_LORA_MAC_PUBLIC_SYNCWORD)
   363  	} else {
   364  		d.SetSyncWord(SX127X_LORA_MAC_PRIVATE_SYNCWORD)
   365  	}
   366  }
   367  
   368  // Tx sends a lora packet, (with timeout)
   369  func (d *Device) Tx(pkt []uint8, timeoutMs uint32) error {
   370  	d.SetOpModeLora()
   371  	d.SetOpMode(SX127X_OPMODE_SLEEP)
   372  
   373  	d.SetHopPeriod(0x00)
   374  	d.SetLowFrequencyModeOn(false)                                                      // High freq mode
   375  	d.WriteRegister(SX127X_REG_PA_RAMP, (d.ReadRegister(SX127X_REG_PA_RAMP)&0xF0)|0x08) // set PA ramp-up time 50 uSec
   376  	d.WriteRegister(SX127X_REG_LNA, SX127X_LNA_MAX_GAIN)                                // Set Low Noise Amplifier to MAX
   377  
   378  	d.SetFrequency(d.loraConf.Freq)
   379  	d.SetPreambleLength(d.loraConf.Preamble)
   380  	d.SetSyncWord(d.loraConf.SyncWord)
   381  	d.SetBandwidth(d.loraConf.Bw)
   382  	d.SetSpreadingFactor(d.loraConf.Sf)
   383  	d.SetIqMode(d.loraConf.Iq)
   384  	d.SetCodingRate(d.loraConf.Cr)
   385  	d.SetCrc(d.loraConf.Crc == lora.CRCOn)
   386  	d.SetTxPower(d.loraConf.LoraTxPowerDBm)
   387  	d.SetHeaderType(d.loraConf.HeaderType)
   388  	d.SetAgcAuto(SX127X_AGC_AUTO_ON)
   389  
   390  	// set the IRQ mapping DIO0=TxDone DIO1=NOP DIO2=NOP
   391  	d.WriteRegister(SX127X_REG_DIO_MAPPING_1, SX127X_MAP_DIO0_LORA_TXDONE|SX127X_MAP_DIO1_LORA_NOP|SX127X_MAP_DIO2_LORA_NOP)
   392  	// Clear all radio IRQ Flags
   393  	d.WriteRegister(SX127X_REG_IRQ_FLAGS, 0xFF)
   394  	// Mask all but TxDone
   395  	d.WriteRegister(SX127X_REG_IRQ_FLAGS_MASK, ^SX127X_IRQ_LORA_TXDONE_MASK)
   396  
   397  	// initialize the payload size and address pointers
   398  	d.WriteRegister(SX127X_REG_PAYLOAD_LENGTH, uint8(len(pkt)))
   399  	d.WriteRegister(SX127X_REG_FIFO_TX_BASE_ADDR, 0)
   400  	d.WriteRegister(SX127X_REG_FIFO_ADDR_PTR, 0)
   401  
   402  	// FIFO OPs cannot take place in Sleep mode !!!
   403  	d.SetOpMode(SX127X_OPMODE_STANDBY)
   404  	time.Sleep(time.Millisecond)
   405  	// Copy payload to FIFO // TODO: Bulk
   406  	for i := 0; i < len(pkt); i++ {
   407  		d.WriteRegister(SX127X_REG_FIFO, pkt[i])
   408  	}
   409  
   410  	// Enable TX
   411  	d.SetOpMode(SX127X_OPMODE_TX)
   412  
   413  	msg := <-d.GetRadioEventChan()
   414  	if msg.EventType != lora.RadioEventTxDone {
   415  		return errors.New("Unexpected Radio Event while TX " + string(0x30+msg.EventType))
   416  	}
   417  	return nil
   418  }
   419  
   420  // Rx tries to receive a Lora packet (with timeout in milliseconds)
   421  func (d *Device) Rx(timeoutMs uint32) ([]uint8, error) {
   422  	if d.loraConf.Freq == 0 {
   423  		return nil, lora.ErrUndefinedLoraConf
   424  	}
   425  
   426  	d.SetOpModeLora()
   427  	d.SetOpMode(SX127X_OPMODE_SLEEP)
   428  
   429  	d.SetHopPeriod(0x00)
   430  	d.SetLowFrequencyModeOn(false)                                                      // High freq mode
   431  	d.WriteRegister(SX127X_REG_PA_RAMP, (d.ReadRegister(SX127X_REG_PA_RAMP)&0xF0)|0x08) // set PA ramp-up time 50 uSec
   432  	d.WriteRegister(SX127X_REG_LNA, SX127X_LNA_MAX_GAIN)                                // Set Low Noise Amplifier to MAX
   433  
   434  	d.SetFrequency(d.loraConf.Freq)
   435  	d.SetPreambleLength(d.loraConf.Preamble)
   436  	d.SetSyncWord(d.loraConf.SyncWord)
   437  	d.SetBandwidth(d.loraConf.Bw)
   438  	d.SetSpreadingFactor(d.loraConf.Sf)
   439  	d.SetIqMode(d.loraConf.Iq)
   440  	d.SetCodingRate(d.loraConf.Cr)
   441  	d.SetCrc(d.loraConf.Crc == lora.CRCOn)
   442  	d.SetTxPower(d.loraConf.LoraTxPowerDBm)
   443  	d.SetHeaderType(d.loraConf.HeaderType)
   444  	d.SetAgcAuto(SX127X_AGC_AUTO_ON)
   445  
   446  	// set the IRQ mapping DIO0=RxDone DIO1=RxTimeout DIO2=NOP
   447  	d.WriteRegister(SX127X_REG_DIO_MAPPING_1, SX127X_MAP_DIO0_LORA_RXDONE|SX127X_MAP_DIO1_LORA_RXTOUT|SX127X_MAP_DIO2_LORA_NOP)
   448  	// Clear all radio IRQ Flags
   449  	d.WriteRegister(SX127X_REG_IRQ_FLAGS, 0xFF)
   450  	// Mask all but RxDone
   451  	d.WriteRegister(SX127X_REG_IRQ_FLAGS_MASK, ^(SX127X_IRQ_LORA_RXDONE_MASK | SX127X_IRQ_LORA_RXTOUT_MASK))
   452  
   453  	// Single RX mode don't properly handle Timeouts on sx127x, so we use Continuous RX
   454  	// Go routine is a workaround to stop the Continuous RX and fire a timeout Event
   455  	d.SetOpMode(SX127X_OPMODE_RX)
   456  
   457  	var msg lora.RadioEvent
   458  	select {
   459  	case msg = <-d.radioEventChan:
   460  		if msg.EventType != lora.RadioEventRxDone {
   461  			return nil, errors.New("Unexpected Radio Event while RX " + string(0x30+msg.EventType))
   462  		}
   463  	case <-time.After(time.Millisecond * time.Duration(timeoutMs)):
   464  		d.SetOpMode(SX127X_OPMODE_STANDBY)
   465  		return nil, nil
   466  	}
   467  
   468  	// Get the received payload
   469  	d.WriteRegister(SX127X_REG_FIFO_RX_BASE_ADDR, 0)
   470  	d.WriteRegister(SX127X_REG_FIFO_ADDR_PTR, 0)
   471  
   472  	pLen := d.ReadRegister(SX127X_REG_RX_NB_BYTES)
   473  	d.WriteRegister(SX127X_REG_FIFO_ADDR_PTR, d.ReadRegister(SX127X_REG_FIFO_RX_CURRENT_ADDR))
   474  
   475  	rxData := []uint8{}
   476  	for i := uint8(0); i < pLen; i++ {
   477  		rxData = append(rxData, d.ReadRegister(SX127X_REG_FIFO))
   478  	}
   479  	return rxData, nil
   480  }
   481  
   482  // SetTxContinuousMode enable Continuous Tx mode
   483  func (d *Device) SetTxContinuousMode(val bool) {
   484  	if val {
   485  		d.WriteRegister(SX127X_REG_MODEM_CONFIG_2, d.ReadRegister(SX127X_REG_MODEM_CONFIG_2)|0x08)
   486  	} else {
   487  		d.WriteRegister(SX127X_REG_MODEM_CONFIG_2, d.ReadRegister(SX127X_REG_MODEM_CONFIG_2)&0xf7)
   488  	}
   489  }
   490  
   491  //
   492  // HELPER FUNCTIONS
   493  //
   494  
   495  // PrintRegisters outputs the sx127x transceiver registers
   496  func (d *Device) PrintRegisters(compact bool) {
   497  	for i := uint8(0); i < 128; i++ {
   498  		v := d.ReadRegister(i)
   499  		print(v, " ")
   500  	}
   501  	println()
   502  }
   503  
   504  // PrintRegisters outputs the sx127x transceiver registers
   505  func (d *Device) RandomU32() uint32 {
   506  	// Disable ALL irqs
   507  	d.WriteRegister(SX127X_REG_IRQ_FLAGS, 0xFF)
   508  	d.SetOpModeLora()
   509  	d.SetOpMode(SX127X_OPMODE_SLEEP)
   510  	d.SetFrequency(d.loraConf.Freq)
   511  	d.SetOpMode(SX127X_OPMODE_RX)
   512  	rnd := uint32(0)
   513  	for i := 0; i < 32; i++ {
   514  		time.Sleep(time.Millisecond * 10)
   515  		// Unfiltered RSSI value reading. Only takes the LSB value
   516  		rnd |= (uint32(d.ReadRegister(SX127X_REG_RSSI_WIDEBAND)) & 0x01) << i
   517  	}
   518  	return rnd
   519  }
   520  
   521  // HandleInterrupt must be called by main code on DIO state change.
   522  func (d *Device) HandleInterrupt() {
   523  
   524  	// Get IRQ and clear
   525  	st := d.ReadRegister(SX127X_REG_IRQ_FLAGS)
   526  	d.WriteRegister(SX127X_REG_IRQ_FLAGS, 0xFF)
   527  
   528  	if (st & SX127X_IRQ_LORA_RXDONE_MASK) > 0 {
   529  		select {
   530  		case d.radioEventChan <- lora.RadioEvent{lora.RadioEventRxDone, uint16(st), nil}:
   531  		default:
   532  		}
   533  	}
   534  
   535  	if (st & SX127X_IRQ_LORA_TXDONE_MASK) > 0 {
   536  		select {
   537  		case d.radioEventChan <- lora.RadioEvent{lora.RadioEventTxDone, uint16(st), nil}:
   538  		default:
   539  		}
   540  	}
   541  
   542  	if (st & SX127X_IRQ_LORA_RXTOUT_MASK) > 0 {
   543  		select {
   544  		case d.radioEventChan <- lora.RadioEvent{lora.RadioEventTimeout, uint16(st), nil}:
   545  		default:
   546  		}
   547  	}
   548  
   549  	if (st & SX127X_IRQ_LORA_CRCERR_MASK) > 0 {
   550  		select {
   551  		case d.radioEventChan <- lora.RadioEvent{lora.RadioEventCrcError, uint16(st), nil}:
   552  		default:
   553  		}
   554  	}
   555  }
   556  
   557  func bandwidth(bw uint8) uint8 {
   558  	switch bw {
   559  	case lora.Bandwidth_7_8:
   560  		return SX127X_LORA_BW_7_8
   561  	case lora.Bandwidth_10_4:
   562  		return SX127X_LORA_BW_10_4
   563  	case lora.Bandwidth_15_6:
   564  		return SX127X_LORA_BW_15_6
   565  	case lora.Bandwidth_20_8:
   566  		return SX127X_LORA_BW_20_8
   567  	case lora.Bandwidth_31_25:
   568  		return SX127X_LORA_BW_31_25
   569  	case lora.Bandwidth_41_7:
   570  		return SX127X_LORA_BW_41_7
   571  	case lora.Bandwidth_62_5:
   572  		return SX127X_LORA_BW_62_5
   573  	case lora.Bandwidth_125_0:
   574  		return SX127X_LORA_BW_125_0
   575  	case lora.Bandwidth_250_0:
   576  		return SX127X_LORA_BW_250_0
   577  	case lora.Bandwidth_500_0:
   578  		return SX127X_LORA_BW_500_0
   579  	default:
   580  		return 0
   581  	}
   582  }
   583  
   584  func syncword(sw int) uint16 {
   585  	if sw == lora.SyncPublic {
   586  		return SX127X_LORA_MAC_PUBLIC_SYNCWORD
   587  	}
   588  	return SX127X_LORA_MAC_PRIVATE_SYNCWORD
   589  }