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 }