diff --git a/lilygo-t3s3-sx128x/main.go b/lilygo-t3s3-sx128x/main.go index 87544ec..84bc30b 100644 --- a/lilygo-t3s3-sx128x/main.go +++ b/lilygo-t3s3-sx128x/main.go @@ -7,10 +7,24 @@ import ( "time" "github.com/jwetzell/osc-go" - "tinygo.org/x/drivers/lora" "tinygo.org/x/drivers/sx128x" ) +type LoRaConfig struct { + Frequency uint32 + Power int8 + RadioRamp sx128x.RadioRampTime + RegulatorMode sx128x.RegulatorMode + SpreadingFactor sx128x.LoRaSpreadingFactor + Bandwidth sx128x.LoRaBandwidth + CodingRate sx128x.LoRaCodingRate + PreambleLength uint32 + HeaderType sx128x.LoRaHeaderType + CrcType sx128x.LoRaCrcType + IqType sx128x.LoRaIqType + SyncWord uint16 +} + func main() { time.Sleep(3 * time.Second) @@ -65,42 +79,30 @@ func main() { timeout := atomic.Bool{} timeout.Store(true) - dio1Pin.SetInterrupt(machine.PinRising, func(machine.Pin) { - irqStatus, _ := radio.GetIrqStatus() + dio1Interrupt := atomic.Bool{} + dio1Interrupt.Store(false) - if irqStatus&sx128x.IRQ_TX_DONE_MASK != 0 { - txDone.Store(true) - timeout.Store(false) - led.Set(false) - println("tx done") - } - if irqStatus&sx128x.IRQ_RX_DONE_MASK != 0 { - rxDone.Store(true) - timeout.Store(false) - led.Set(true) - } - if irqStatus&sx128x.IRQ_RX_TX_TIMEOUT_MASK != 0 { - timeout.Store(true) - txDone.Store(true) - rxDone.Store(true) - } + dio1Pin.SetInterrupt(machine.PinRising, func(machine.Pin) { + dio1Interrupt.Store(true) }) - loraConfig := lora.Config{ - Freq: 2400000000, - Bw: lora.Bandwidth_1625_0, - Sf: lora.SpreadingFactor9, - Cr: lora.CodingRate4_7, - HeaderType: sx128x.LORA_EXPLICIT_HEADER, - Preamble: 12, - Ldr: lora.LowDataRateOptimizeOff, - Iq: sx128x.LORA_IQ_STD, - Crc: sx128x.LORA_CRC_DISABLE, - SyncWord: 0x1424, - LoraTxPowerDBm: 13, + loraConfig := LoRaConfig{ + Frequency: 2400000000, // 2.4Ghz + Power: 13, // dBm + RadioRamp: sx128x.RADIO_RAMP_02_US, // 2 microsecond ramp time + RegulatorMode: sx128x.REGULATOR_DC_DC, + + SpreadingFactor: sx128x.LORA_SF_9, + Bandwidth: sx128x.LORA_BW_1600, + CodingRate: sx128x.LORA_CR_4_7, + PreambleLength: 12, + HeaderType: sx128x.LORA_HEADER_EXPLICIT, + CrcType: sx128x.LORA_CRC_DISABLE, + IqType: sx128x.LORA_IQ_STD, + SyncWord: 0x1424, // the default private sync word } - radio.WaitWhileBusy() + radio.WaitWhileBusy(time.Second) SetupLora(radio, loraConfig) oscMessage := osc.OSCMessage{ @@ -109,6 +111,27 @@ func main() { } for { + if dio1Interrupt.Load() { + irqStatus, _ := radio.GetIrqStatus() + + if irqStatus&sx128x.IRQ_TX_DONE_MASK != 0 { + txDone.Store(true) + timeout.Store(false) + led.Set(false) + println("tx done") + } + if irqStatus&sx128x.IRQ_RX_DONE_MASK != 0 { + rxDone.Store(true) + timeout.Store(false) + led.Set(true) + } + if irqStatus&sx128x.IRQ_RX_TX_TIMEOUT_MASK != 0 { + timeout.Store(true) + txDone.Store(true) + rxDone.Store(true) + } + dio1Interrupt.Store(false) + } if txDone.Load() && buttonPressed.Load() { txDone.Store(false) buttonPressed.Store(false) @@ -155,7 +178,7 @@ func main() { } } -func SetupLora(radio *sx128x.Device, config lora.Config) { +func SetupLora(radio *sx128x.Device, config LoRaConfig) { // Switch to standby prior to configuration changes circuitMode, _, _ := radio.GetStatus() @@ -164,16 +187,16 @@ func SetupLora(radio *sx128x.Device, config lora.Config) { } // Clear errors, disable radio interrupts for the moment radio.SetPacketType(sx128x.PACKET_TYPE_LORA) - radio.SetCadParams(sx128x.LORA_CAD_08_SYMBOLS) + radio.SetCadParams(uint8(sx128x.LORA_CAD_08_SYMBOLS)) radio.SetRegulatorMode(sx128x.REGULATOR_DC_DC) - radio.SetRfFrequency(config.Freq) - radio.SetModulationParams(spreadingFactor(config.Sf), bandwidth(config.Bw), codingRate(config.Cr)) + radio.SetRfFrequency(config.Frequency) + radio.SetModulationParamsLoRa(config.SpreadingFactor, config.Bandwidth, config.CodingRate) data := [1]uint8{} - if config.Sf == lora.SpreadingFactor5 || config.Sf == lora.SpreadingFactor6 { + if config.SpreadingFactor == sx128x.LORA_SF_5 || config.SpreadingFactor == sx128x.LORA_SF_6 { data[0] = 0x1E - } else if config.Sf == lora.SpreadingFactor7 || config.Sf == lora.SpreadingFactor8 { + } else if config.SpreadingFactor == sx128x.LORA_SF_7 || config.SpreadingFactor == sx128x.LORA_SF_8 { data[0] = 0x37 } else { data[0] = 0x32 @@ -183,8 +206,8 @@ func SetupLora(radio *sx128x.Device, config lora.Config) { data[0] = existing | 0x01 radio.WriteRegister(0x93C, data[:]) - radio.SetTxParams(config.LoraTxPowerDBm, sx128x.RADIO_RAMP_02_US) - radio.SetPacketParamsLoRa(uint32(config.Preamble), config.HeaderType, 0xFF, config.Crc, config.Iq) + radio.SetTxParams(config.Power, sx128x.RADIO_RAMP_02_US) + radio.SetPacketParamsLoRa(config.PreambleLength, config.HeaderType, 0xFF, config.CrcType, config.IqType) var syncWord [2]uint8 syncWord[0] = uint8(config.SyncWord >> 8) syncWord[1] = uint8(config.SyncWord & 0x00FF) @@ -203,12 +226,12 @@ func checkStatus(radio *sx128x.Device, operation string) { } } -func Tx(radio *sx128x.Device, loraConfig lora.Config, data []byte) error { +func Tx(radio *sx128x.Device, loraConfig LoRaConfig, data []byte) error { if len(data) > 255 { return errors.New("data length exceeds maximum of 255 bytes") } radio.SetStandby(sx128x.STANDBY_RC) - radio.SetPacketParamsLoRa(uint32(loraConfig.Preamble), loraConfig.HeaderType, uint8(len(data)&0xFF), loraConfig.Crc, loraConfig.Iq) + radio.SetPacketParamsLoRa(loraConfig.PreambleLength, loraConfig.HeaderType, uint8(len(data)&0xFF), loraConfig.CrcType, loraConfig.IqType) radio.SetBufferBaseAddress(0, 0) radio.WriteBuffer(0, data) radio.SetDioIrqParams(sx128x.IRQ_TX_DONE_MASK|sx128x.IRQ_RX_TX_TIMEOUT_MASK, sx128x.IRQ_TX_DONE_MASK|sx128x.IRQ_RX_TX_TIMEOUT_MASK, 0x00, 0x00) @@ -217,64 +240,11 @@ func Tx(radio *sx128x.Device, loraConfig lora.Config, data []byte) error { return nil } -func Rx(radio *sx128x.Device, loraConfig lora.Config) { +func Rx(radio *sx128x.Device, loraConfig LoRaConfig) { radio.SetStandby(sx128x.STANDBY_RC) radio.SetDioIrqParams(sx128x.IRQ_RX_DONE_MASK|sx128x.IRQ_RX_TX_TIMEOUT_MASK, sx128x.IRQ_RX_DONE_MASK|sx128x.IRQ_RX_TX_TIMEOUT_MASK, 0x00, 0x00) radio.SetBufferBaseAddress(0, 0) radio.ClearIrqStatus(sx128x.IRQ_ALL_MASK) - radio.SetRfFrequency(loraConfig.Freq) + radio.SetRfFrequency(loraConfig.Frequency) radio.SetRx(sx128x.PERIOD_BASE_4_MS, 250) } - -func codingRate(cr uint8) uint8 { - switch cr { - case lora.CodingRate4_5: - return sx128x.LORA_CR_4_5 - case lora.CodingRate4_6: - return sx128x.LORA_CR_4_6 - case lora.CodingRate4_7: - return sx128x.LORA_CR_4_7 - case lora.CodingRate4_8: - return sx128x.LORA_CR_4_8 - default: - return 0 - } -} - -func spreadingFactor(sf uint8) uint8 { - switch sf { - case lora.SpreadingFactor5: - return sx128x.LORA_SF_5 - case lora.SpreadingFactor6: - return sx128x.LORA_SF_6 - case lora.SpreadingFactor7: - return sx128x.LORA_SF_7 - case lora.SpreadingFactor8: - return sx128x.LORA_SF_8 - case lora.SpreadingFactor9: - return sx128x.LORA_SF_9 - case lora.SpreadingFactor10: - return sx128x.LORA_SF_10 - case lora.SpreadingFactor11: - return sx128x.LORA_SF_11 - case lora.SpreadingFactor12: - return sx128x.LORA_SF_12 - default: - return 0 - } -} - -func bandwidth(bw uint8) uint8 { - switch bw { - case lora.Bandwidth_1625_0: - return sx128x.LORA_BW_1600 - case lora.Bandwidth_812_5: - return sx128x.LORA_BW_800 - case lora.Bandwidth_406_25: - return sx128x.LORA_BW_400 - case lora.Bandwidth_203_125: - return sx128x.LORA_BW_200 - default: - return 0 - } -}