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 |
--- /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();
+}
+