Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: lr1110 sx12xx_hal
Revision 1:416ed16806fc, committed 2021-02-09
- Comitter:
- Wayne Roberts
- Date:
- Tue Feb 09 10:47:25 2021 -0800
- Parent:
- 0:d8a6a7dfa435
- Commit message:
- add source file
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r d8a6a7dfa435 -r 416ed16806fc main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Feb 09 10:47:25 2021 -0800 @@ -0,0 +1,323 @@ +#include "radio.h" + +#define TX_DBM 20 +#define BW_KHZ 500 +#define SPREADING_FACTOR 11 +#define CF_HZ 919000000 + +#define HEADER_LENGTH 10 /* for chipEUI and extra reserved */ +#define WIFI_MAX_RESULTS 20 +#define LORA_RX_TIME_MS 20000 /* how long for cloud to reply with resolved location? */ + +/**********************************************************************/ +bool wifiResultFormatBasic; /* false, TODO get basic results functional */ +EventQueue queue(4 * EVENTS_EVENT_SIZE); + +unsigned packet_len; +uint8_t chip_eui[8]; + +InterruptIn ub(USER_BUTTON); /* released = hi, pressed = lo */ +void button_released(void); +int wifi_scan_id, long_press_id; +bool long_pressed; + +uint64_t wifi_start_at, wifi_scan_dur; + +static void cfg_lora() +{ + /* after wifi scan, lora is gone */ + Radio::LoRaModemConfig(BW_KHZ, SPREADING_FACTOR, 1); + Radio::SetChannel(CF_HZ); + + Radio::set_tx_dbm(TX_DBM); + + // preambleLen, fixLen, crcOn, invIQ + Radio::LoRaPacketConfig(8, false, true, false); +} + +void wifi_scan() +{ + uint8_t wifiScan_buf[9]; + + { /* wifi scan defaults, see LR1110 user manual section 10.2 */ + unsigned chanmask = 0x0421; // ch1, ch6, ch11 + unsigned timeout = 105; // in milliseconds, 100 wifi TUs (beacon interval) + + wifiScan_buf[0] = 0x01; // wifi type + wifiScan_buf[2] = chanmask; // chanmask-lo + chanmask >>= 8; + wifiScan_buf[1] = chanmask; // chanmask-hi + wifiScan_buf[3] = 0x02; // acqMode + wifiScan_buf[4] = WIFI_MAX_RESULTS; // NbMaxRes + wifiScan_buf[5] = 0x10; // NbScanPerChan + wifiScan_buf[7] = timeout; // Timeout-lo + timeout >>= 8; + wifiScan_buf[6] = timeout; // Timeout-hi + wifiScan_buf[8] = 0x00; // AbortOnTimeout + } + + Radio::radio.xfer(OPCODE_WIFI_SCAN, 9, 0, wifiScan_buf); + wifi_start_at = Kernel::get_ms_count(); + printf("wifiScan...\r\n"); +} + +void long_press() +{ + long_pressed = true; + wifi_scan(); +} + +void button_pressed() +{ + ub.rise(button_released); + queue.cancel(wifi_scan_id); + long_pressed = false; + long_press_id = queue.call_in(500, long_press); +} + +void button_released() +{ + ub.fall(button_pressed); + if (!long_pressed) { + wifi_scan_id = queue.call_in(20, wifi_scan); + queue.cancel(long_press_id); + } +} + +void txDoneCB() +{ + Radio::Rx(0); + queue.call_in(LORA_RX_TIME_MS, Radio::Standby); +} + +void rxDoneCB(uint8_t size, float rssi, float snr) +{ + unsigned i; + printf("%.1fdBm snr:%.1fdB\t", rssi, snr); + + /* + for (i = 0; i < size; i++) { + printf("%02x ", Radio::radio.rx_buf[i]); + } + printf("\r\n");*/ + + if (memcmp(Radio::radio.rx_buf, chip_eui, 8) == 0) { + /* print resolved coordinates from cloud */ + printf(">> %s\r\n", Radio::radio.rx_buf + HEADER_LENGTH); + } +} + +struct wifidr { + const char *txt; + float Mbps; +}; + +const struct wifidr wifiDatarates[] = { + /* 0 */ { NULL, 0}, + /* 1 */ { "DBPSK", 1}, + /* 2 */ { "DQPSK", 2}, + /* 3 */ { "BPSK", 6}, + /* 4 */ { "BPSK", 9}, + /* 5 */ { "QPSK", 12}, + /* 6 */ { "QPSK", 18}, + /* 7 */ { "16-QAM", 24}, + /* 8 */ { "16-QAM", 36}, + /* 9 */ { "(9)", 0}, + /* 10 */ { "(10)", 0}, + /* 11 */ { "BPSK", 6.5}, + /* 12 */ { "QPSK", 13}, + /* 13 */ { "QPSK", 19.5}, + /* 14 */ { "16-QAM", 26}, + /* 15 */ { "16-QAM", 39}, + /* 16 */ { "(16)", 0}, + /* 17 */ { "(17)", 0}, + /* 18 */ { "(18)", 0}, + /* 19 */ { "BPSK", 7.2}, + /* 20 */ { "QPSK", 14.4}, + /* 21 */ { "QPSK", 21.7}, + /* 22 */ { "16-QAM", 28.9}, + /* 23 */ { "16-QAM", 43.3}, +}; + +void print_wifi_result(const uint8_t *result) +{ + char out[96]; + char str[24]; + unsigned n, macStart; + wifiType_t wt; + wifiChanInfo_t ci; + wt.octet = result[0]; + ci.octet = result[1]; + out[0] = 0; + strcat(out, "802.11"); + switch (wt.bits.signal) { + case 1: strcat(out, "b"); break; + case 2: strcat(out, "g"); break; + case 3: strcat(out, "n"); break; + } + sprintf(str, " %s %.1fMbps", wifiDatarates[wt.bits.datarate].txt, wifiDatarates[wt.bits.datarate].Mbps); + strcat(out, str); + strcat(out, " "); + + sprintf(str, "ch%u ", ci.bits.channelID); + strcat(out, str); + switch (ci.bits.channelID) { + // table 10-5 + } + strcat(out, " "); + sprintf(str, "mv:%u ", ci.bits.macValidationID); + strcat(out, str); + switch (ci.bits.macValidationID) { + case 1: strcat(out, "gateway"); break; + case 2: strcat(out, "phone"); break; + case 3: strcat(out, "?"); break; + // table 10.8 + } + + strcat(out, " "); + + if (wifiResultFormatBasic) { + macStart = 3; + } else { + macStart = 4; + } + for (n = 0; n < 6; n++) { + sprintf(str, "%02x", result[n+macStart]); + strcat(out, str); + if (n < 5) + strcat(out, ":"); + } + + sprintf(str, " rssi:%d ", (int8_t)result[2]); + strcat(out, str); + + if (!wifiResultFormatBasic) { + sprintf(str, "frameCtrl:%02x ", result[3]); + strcat(out, str); + } + printf("%s\r\n", out); +} + +static void service() +{ + irq_t irq; + irq.dword = Radio::radio.service(); + if (irq.bits.WifiDone) { + unsigned n; + stat_t stat; + uint8_t nbResults; + stat.word = Radio::radio.xfer(OPCODE_GET_WIFI_NB_RESULTS, 0, 0, NULL); + stat.word = Radio::radio.xfer(0x0000, 0, 1, &nbResults); + if (stat.bits.cmdStatus != CMD_DAT) { + printf("get-nbResult-fail\r\n"); + return; + } + packet_len = HEADER_LENGTH; + printf("%ums nbResults:%u\r\n", (unsigned)wifi_scan_dur, nbResults); + for (n = 0; n < nbResults; n++) { + uint8_t buf[3]; + uint8_t resultBuf[22]; + buf[0] = n; + buf[1] = 1; // number of results in this read + buf[2] = wifiResultFormatBasic ? 4 : 1; + stat.word = Radio::radio.xfer(OPCODE_WIFI_READ_RESULTS, 3, 0, buf); + // basic = 9byte length + // full = 22byte length + stat.word = Radio::radio.xfer(0x0000, 0, wifiResultFormatBasic ? 9 : 22, resultBuf); + + if (stat.bits.cmdStatus == CMD_DAT) { + unsigned n, macStart; + wifiChanInfo_t ci; + ci.octet = resultBuf[1]; + if (ci.bits.macValidationID == 1) { // gateway (AP) + macStart = wifiResultFormatBasic ? 3 : 4; + for (n = 0; n < 6; n++) { + Radio::radio.tx_buf[packet_len++] = resultBuf[n+macStart]; + printf("%02x", resultBuf[n+macStart]); + if (n < 5) + printf(":"); + } + printf(" rssi:%d\r\n", (int8_t)resultBuf[2]); + Radio::radio.tx_buf[packet_len++] = resultBuf[2]; + } + } else + printf("readResult:%s\r\n", Radio::radio.cmdStatus_toString(stat.bits.cmdStatus)); + } + + if (!long_pressed) { + unsigned n; + cfg_lora(); + for (n = 0; n < 8; n++) + Radio::radio.tx_buf[n] = chip_eui[n]; + + Radio::radio.tx_buf[n++] = 0; // rfu + Radio::radio.tx_buf[n++] = 0; // rfu + printf("pktLen:%u\r\n", packet_len); + Radio::Send(packet_len, 0, 0, 0); /* begin transmission */ + } + } // ..if (irq.bits.WifiDone) + + if (irq.bits.TxDone) { + printf("main-TxDone\r\n"); + } +} + +void radio_irq_callback() +{ + wifi_scan_dur = Kernel::get_ms_count() - wifi_start_at; + queue.call(service); +} + +const RadioEvents_t rev = { + /* DioPin_top_half */ radio_irq_callback, + /* TxDone_topHalf */ NULL, + /* TxDone_botHalf */ txDoneCB, + /* TxTimeout */ NULL, + /* RxDone */ rxDoneCB, + /* RxTimeout */ NULL, + /* RxError */ NULL, + /* FhssChangeChannel */NULL, + /* CadDone */ NULL +}; + +int main() +{ + Radio::Init(&rev); + + Radio::Standby(); + cfg_lora(); + + { + uint8_t buf[9]; + stat_t stat; + stat.word = Radio::radio.xfer(OPCODE_GET_VERSION, 0, 0, NULL); + stat.word = Radio::radio.xfer(0x0000, 0, 4, buf); + if (stat.bits.cmdStatus == CMD_DAT) { + printf("LR1110 chip:%02x use:%02x fw-v%u.%u\r\n", + buf[0], /* silicon rev */ + buf[1], /* use case */ + buf[2], /* firmware major */ + buf[3] /* firmware minor */ + ); + } + + stat.word = Radio::radio.xfer(OPCODE_GET_DEVEUI, 0, 0, NULL); + stat.word = Radio::radio.xfer(0x0000, 0, 9, buf); + memcpy(chip_eui, buf+1, 8); + for (unsigned i = 0; i < 9; i++) + printf("%02x ", buf[i]); + printf("\r\n"); + } + +#ifdef AUTO_TX + queue.call_in(500, tx_test); +#endif /* AUTO_TX */ + + if (ub.read()) + ub.fall(button_pressed); + else + ub.rise(button_released); + + queue.dispatch(); +} +