From 59ff8a458526ae218f1af4c2b95805fd61267024 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Fri, 6 Jan 2023 14:13:08 +0100 Subject: [PATCH] examples: further work on at-lora Signed-off-by: deadprogram --- examples/lora/atcmd/commands.go | 277 +++++++++++++++++--------------- examples/lora/atcmd/main.go | 18 +++ examples/lora/atcmd/radio.go | 13 ++ examples/lora/atcmd/sim.go | 26 ++- examples/lora/atcmd/sx126x.go | 4 +- examples/lora/atcmd/sx127x.go | 4 +- 6 files changed, 209 insertions(+), 133 deletions(-) create mode 100644 examples/lora/atcmd/radio.go diff --git a/examples/lora/atcmd/commands.go b/examples/lora/atcmd/commands.go index 3cb4ad9..20f6a0b 100644 --- a/examples/lora/atcmd/commands.go +++ b/examples/lora/atcmd/commands.go @@ -4,42 +4,31 @@ import ( "strings" ) -func crlf() { - uart.Write([]byte("\r\n")) -} - -// Use to test if connection of module is OK. +// Use to test if connection to module is OK. func quicktest() { - uart.Write([]byte("+AT: OK")) - crlf() + writeCommandOutput("AT", "OK") } // Check firmware version. func version() { - uart.Write([]byte("+VER: ")) - uart.Write([]byte(currentVersion())) - crlf() + writeCommandOutput("VER", currentVersion()) } // Use to check the ID of the LoRaWAN module, or change the ID. func id(args string) error { + cmd := "ID" + // look for comma in args param, val, hasComma := strings.Cut(args, ",") if hasComma { // set switch param { case "DevAddr": - uart.Write([]byte("+ID: DevAddr, ")) - uart.Write([]byte(val)) - crlf() + writeCommandOutput(cmd, "DevAddr, "+val) case "DevEui": - uart.Write([]byte("+ID: DevEui, ")) - uart.Write([]byte(val)) - crlf() + writeCommandOutput(cmd, "DevEui, "+val) case "AppEui": - uart.Write([]byte("+ID: AppEui, ")) - uart.Write([]byte(val)) - crlf() + writeCommandOutput(cmd, "AppEui, "+val) default: return errInvalidCommand } @@ -50,84 +39,94 @@ func id(args string) error { // get switch param { case "DevAddr": - uart.Write([]byte("+ID: DevAddr, xx:xx:xx:xx")) - crlf() + writeCommandOutput(cmd, "DevAddr, xx:xx:xx:xx") case "DevEui": - uart.Write([]byte("+ID: DevEui, xx:xx:xx:xx:xx:xx:xx:xx")) - crlf() + writeCommandOutput(cmd, "DevEui, xx:xx:xx:xx:xx:xx:xx:xx") case "AppEui": - uart.Write([]byte("+ID: AppEui, xx:xx:xx:xx:xx:xx:xx:xx")) - crlf() + writeCommandOutput(cmd, "AppEui, xx:xx:xx:xx:xx:xx:xx:xx") default: - uart.Write([]byte("+ID: DevAddr, xx:xx:xx:xx")) - crlf() - uart.Write([]byte("+ID: DevEui, xx:xx:xx:xx:xx:xx:xx:xx")) - crlf() - uart.Write([]byte("+ID: AppEui, xx:xx:xx:xx:xx:xx:xx:xx")) - crlf() + writeCommandOutput(cmd, "DevAddr, xx:xx:xx:xx") + writeCommandOutput(cmd, "DevEui, xx:xx:xx:xx:xx:xx:xx:xx") + writeCommandOutput(cmd, "AppEui, xx:xx:xx:xx:xx:xx:xx:xx") } return nil } // Use to reset the module. If module returns error, then reset function is invalid. -func reset() error { - uart.Write([]byte("+RESET: OK")) - crlf() +func reset() error { + radio.Reset() + + writeCommandOutput("RESET", "OK") return nil } // Use to send string format frame which is no need to be confirmed by the server. func msg(data string) error { - uart.Write([]byte("+MSG: Start")) - crlf() - uart.Write([]byte("+MSG: Done")) - crlf() + cmd := "MSG" + writeCommandOutput(cmd, "Start") + + if err := radio.LoraTx([]byte(data), defaultTimeout); err != nil { + writeCommandOutput(cmd, err.Error()) + + return err + } + + writeCommandOutput(cmd, "Done") return nil } // Use to send string format frame which must be confirmed by the server func cmsg(data string) error { - uart.Write([]byte("+CMSG: Start")) - crlf() - uart.Write([]byte("+CMSG: Done")) - crlf() + cmd := "CMSG" + writeCommandOutput(cmd, "Start") + + if err := radio.LoraTx([]byte(data), defaultTimeout); err != nil { + writeCommandOutput(cmd, err.Error()) + + return err + } + + // TODO: confirmation + + writeCommandOutput(cmd, "Done") return nil } // Use to send hex format frame which is no need to be confirmed by the server func msghex(data string) error { - uart.Write([]byte("+MSGHEX: Start")) - crlf() - uart.Write([]byte("+MSGHEX: Done")) - crlf() + cmd := "MSGHEX" + writeCommandOutput(cmd, "Start") + + writeCommandOutput(cmd, "Done") return nil } // Use to send hex format frame which must be confirmed by the server. func cmsghex(data string) error { - uart.Write([]byte("+CMSGHEX: Start")) - crlf() - uart.Write([]byte("+CMSGHEX: Done")) - crlf() + cmd := "CMSGHEX" + writeCommandOutput(cmd, "Start") + + writeCommandOutput(cmd, "Done") return nil } // Use to send string format LoRaWAN proprietary frames func pmsg(data string) error { - uart.Write([]byte("+PMSG: Start")) - crlf() - uart.Write([]byte("+PMSG: Done")) - crlf() + cmd := "PMSG" + writeCommandOutput(cmd, "Start") + + writeCommandOutput(cmd, "Done") return nil } // Use to send hex format LoRaWAN proprietary frames. func pmsghex(data string) error { - uart.Write([]byte("+PMSGHEX: Start")) - crlf() - uart.Write([]byte("+PMSGHEX: Done")) - crlf() + cmd := "PMSGHEX" + writeCommandOutput(cmd, "Start") + + writeCommandOutput(cmd, "Done") + return nil } @@ -135,49 +134,49 @@ func pmsghex(data string) error { // message, port number should range from 1 to 255. User should refer to LoRaWAN // specification to choose port. func port(p string) error { - uart.Write([]byte("+PORT: ")) - uart.Write([]byte(p)) - crlf() + cmd := "PMSG" + writeCommandOutput(cmd, p) + return nil } // Set ADR function of LoRaWAN module func adr(state string) error { - uart.Write([]byte("+ADR: ")) - uart.Write([]byte(state)) - crlf() + cmd := "ADR" + writeCommandOutput(cmd, state) + return nil } // Use LoRaWAN defined DRx to set datarate of LoRaWAN AT modem. func dr(rate string) error { - uart.Write([]byte("+ADR: ")) - uart.Write([]byte(rate)) - crlf() + cmd := "DR" + writeCommandOutput(cmd, rate) + return nil } // Channel Configuration func ch(channel string) error { - uart.Write([]byte("+CH: ")) - uart.Write([]byte(channel)) - crlf() + cmd := "CH" + writeCommandOutput(cmd, channel) + return nil } // Set and Check Power func power(setting string) error { - uart.Write([]byte("+POWER: ")) - uart.Write([]byte(setting)) - crlf() + cmd := "POWER" + writeCommandOutput(cmd, setting) + return nil } // Unconfirmed message repeats times. func rept(setting string) error { - uart.Write([]byte("+REPT: ")) - uart.Write([]byte(setting)) - crlf() + cmd := "REPT" + writeCommandOutput(cmd, setting) + return nil } @@ -186,132 +185,156 @@ func rept(setting string) error { // be sent. Random delay 3 - 10s between each retry // (band duty cycle limitation has the priority) func retry(setting string) error { - uart.Write([]byte("+RETRY: ")) - uart.Write([]byte(setting)) - crlf() + cmd := "RETRY" + writeCommandOutput(cmd, setting) + return nil } func rxwin2(setting string) error { - uart.Write([]byte("+RXWIN2: ")) - uart.Write([]byte(setting)) - crlf() + cmd := "RXWIN2" + writeCommandOutput(cmd, setting) + return nil } func rxwin1(setting string) error { - uart.Write([]byte("+RXWIN1: ")) - uart.Write([]byte(setting)) - crlf() + cmd := "RXWIN1" + writeCommandOutput(cmd, setting) + return nil } func key(setting string) error { - uart.Write([]byte("+RETRY: ")) - uart.Write([]byte(setting)) - crlf() + cmd := "KEY" + writeCommandOutput(cmd, setting) + return nil } func fdefault(setting string) error { - uart.Write([]byte("+FDEFAULT: OK")) - crlf() + cmd := "FDEFAULT" + writeCommandOutput(cmd, "OK") + return nil } func mode(setting string) error { - uart.Write([]byte("+MODE: ")) - uart.Write([]byte(setting)) - crlf() + cmd := "MODE" + writeCommandOutput(cmd, setting) + return nil } func join(setting string) error { - uart.Write([]byte("+JOIN: Starting")) - crlf() - uart.Write([]byte("+JOIN: Done")) - crlf() + cmd := "JOIN" + writeCommandOutput(cmd, "Starting") + + writeCommandOutput(cmd, "Done") return nil } func beacon(setting string) error { - uart.Write([]byte("+BEACON: Starting")) - crlf() - uart.Write([]byte("+BEACON: Done")) - crlf() + cmd := "BEACON" + writeCommandOutput(cmd, "Starting") + + writeCommandOutput(cmd, "Done") + return nil } func class(setting string) error { - uart.Write([]byte("+CLASS: Starting")) - crlf() - uart.Write([]byte("+CLASS: Done")) - crlf() + cmd := "CLASS" + writeCommandOutput(cmd, "Starting") + + writeCommandOutput(cmd, "Done") + return nil } func delay(setting string) error { - uart.Write([]byte("+DELAY: Starting")) - crlf() + cmd := "DELAY" + writeCommandOutput(cmd, setting) + return nil } func lw(setting string) error { - uart.Write([]byte("+LW: Starting")) - crlf() + cmd := "LW" + writeCommandOutput(cmd, setting) + return nil } func wdt(setting string) error { - uart.Write([]byte("+WDT: Not implemented")) - crlf() + cmd := "WDT" + writeCommandOutput(cmd, "Not implemented") + return nil } func lowpower(setting string) error { - uart.Write([]byte("+LOWPOWER: Not implemented")) - crlf() + cmd := "LOWPOWER" + writeCommandOutput(cmd, "Not implemented") + return nil } func vdd(setting string) error { - uart.Write([]byte("+VDD: Not implemented")) - crlf() + cmd := "VDD" + writeCommandOutput(cmd, "Not implemented") + return nil } func temp(setting string) error { - uart.Write([]byte("+TEMP: Not implemented")) - crlf() + cmd := "TEMP" + writeCommandOutput(cmd, "Not implemented") + return nil } func rtc(setting string) error { - uart.Write([]byte("+RTC: Not implemented")) - crlf() + cmd := "RTC" + writeCommandOutput(cmd, "Not implemented") + return nil } func eeprom(setting string) error { - uart.Write([]byte("+EEPROM: Not implemented")) - crlf() + cmd := "EEPROM" + writeCommandOutput(cmd, "Not implemented") + return nil } func uartcmd(setting string) error { - uart.Write([]byte("+UART: Not implemented")) - crlf() + cmd := "UART" + writeCommandOutput(cmd, "Not implemented") + return nil } func test(setting string) error { - uart.Write([]byte("+TEST: Not implemented")) - crlf() + cmd := "TEST" + writeCommandOutput(cmd, "Not implemented") + return nil } func log(setting string) error { - uart.Write([]byte("+LOG: Not implemented")) - crlf() + cmd := "LOG" + writeCommandOutput(cmd, "Not implemented") + return nil } + +func crlf() { + uart.Write([]byte("\r\n")) +} + +func writeCommandOutput(cmd, data string) { + uart.Write([]byte("+"+cmd+": ")) + uart.Write([]byte(data)) + crlf() +} diff --git a/examples/lora/atcmd/main.go b/examples/lora/atcmd/main.go index f10f9e3..a817e03 100644 --- a/examples/lora/atcmd/main.go +++ b/examples/lora/atcmd/main.go @@ -19,11 +19,20 @@ var ( tx = machine.UART_TX_PIN rx = machine.UART_RX_PIN input = make([]byte, 0, 64) + + radio LoraRadio + defaultTimeout uint32 = 1000 ) func main() { uart.Configure(machine.UARTConfig{TX: tx, RX: rx}) + var err error + radio, err = setupLora() + if err != nil { + fail(err.Error()) + } + for { if uart.Buffered() > 0 { data, _ := uart.ReadByte() @@ -45,3 +54,12 @@ func main() { time.Sleep(10 * time.Millisecond) } } + +func fail(msg string) { + for { + uart.Write([]byte(msg)) + crlf() + + time.Sleep(time.Minute) + } +} \ No newline at end of file diff --git a/examples/lora/atcmd/radio.go b/examples/lora/atcmd/radio.go new file mode 100644 index 0000000..6cf1248 --- /dev/null +++ b/examples/lora/atcmd/radio.go @@ -0,0 +1,13 @@ +package main + +type LoraRadio interface { + Reset() error + LoraTx(pkt []uint8, timeoutMs uint32) error + LoraRx(timeoutMs uint32) ([]uint8, error) + SetLoraFrequency(freq uint32) + SetLoraIqMode(mode uint8) + SetLoraCodingRate(cr uint8) + SetLoraBandwidth(bw uint8) + SetLoraCrc(enable bool) + SetLoraSpreadingFactor(sf uint8) +} diff --git a/examples/lora/atcmd/sim.go b/examples/lora/atcmd/sim.go index d3076b8..1af9173 100644 --- a/examples/lora/atcmd/sim.go +++ b/examples/lora/atcmd/sim.go @@ -3,6 +3,28 @@ package main // do simulator setup here -func setup() error { - return nil +func setupLora() (LoraRadio, error) { + return &SimLoraRadio{}, nil } + +type SimLoraRadio struct { +} + +func (sr *SimLoraRadio) Reset() error { + return nil +} + +func (sr *SimLoraRadio) LoraTx(pkt []uint8, timeoutMs uint32) error { + return nil +} + +func (sr *SimLoraRadio) LoraRx(timeoutMs uint32) ([]uint8, error) { + return nil, nil +} + +func (sr *SimLoraRadio) SetLoraFrequency(freq uint32) {} +func (sr *SimLoraRadio) SetLoraIqMode(mode uint8) {} +func (sr *SimLoraRadio) SetLoraCodingRate(cr uint8) {} +func (sr *SimLoraRadio) SetLoraBandwidth(bw uint8) {} +func (sr *SimLoraRadio) SetLoraCrc(enable bool) {} +func (sr *SimLoraRadio) SetLoraSpreadingFactor(sf uint8) {} diff --git a/examples/lora/atcmd/sx126x.go b/examples/lora/atcmd/sx126x.go index f3ea872..fa2df2c 100644 --- a/examples/lora/atcmd/sx126x.go +++ b/examples/lora/atcmd/sx126x.go @@ -3,6 +3,6 @@ package main // do sx126x setup here -func setup() error { - return nil +func setupLora() (LoraRadio, error) { + return nil, nil } diff --git a/examples/lora/atcmd/sx127x.go b/examples/lora/atcmd/sx127x.go index 1c83274..e620763 100644 --- a/examples/lora/atcmd/sx127x.go +++ b/examples/lora/atcmd/sx127x.go @@ -3,6 +3,6 @@ package main // do sx127x setup here -func setup() error { - return nil +func setupLora() (LoraRadio, error) { + return nil, nil }