
simple example of wifi AP scanning, sending scan-results over radio link
Dependencies: lr1110 sx12xx_hal
main.cpp
00001 #include "radio.h" 00002 00003 #define TX_DBM 20 00004 #define BW_KHZ 500 00005 #define SPREADING_FACTOR 11 00006 #define CF_HZ 919000000 00007 00008 #define HEADER_LENGTH 10 /* for chipEUI and extra reserved */ 00009 #define WIFI_MAX_RESULTS 20 00010 #define LORA_RX_TIME_MS 20000 /* how long for cloud to reply with resolved location? */ 00011 00012 /**********************************************************************/ 00013 bool wifiResultFormatBasic; /* false, TODO get basic results functional */ 00014 EventQueue queue(4 * EVENTS_EVENT_SIZE); 00015 00016 unsigned packet_len; 00017 uint8_t chip_eui[8]; 00018 00019 InterruptIn ub(USER_BUTTON); /* released = hi, pressed = lo */ 00020 void button_released(void); 00021 int wifi_scan_id, long_press_id; 00022 bool long_pressed; 00023 00024 uint64_t wifi_start_at, wifi_scan_dur; 00025 00026 static void cfg_lora() 00027 { 00028 /* after wifi scan, lora is gone */ 00029 Radio::LoRaModemConfig(BW_KHZ, SPREADING_FACTOR, 1); 00030 Radio::SetChannel(CF_HZ); 00031 00032 Radio::set_tx_dbm(TX_DBM); 00033 00034 // preambleLen, fixLen, crcOn, invIQ 00035 Radio::LoRaPacketConfig(8, false, true, false); 00036 } 00037 00038 void wifi_scan() 00039 { 00040 uint8_t wifiScan_buf[9]; 00041 00042 { /* wifi scan defaults, see LR1110 user manual section 10.2 */ 00043 unsigned chanmask = 0x0421; // ch1, ch6, ch11 00044 unsigned timeout = 105; // in milliseconds, 100 wifi TUs (beacon interval) 00045 00046 wifiScan_buf[0] = 0x01; // wifi type 00047 wifiScan_buf[2] = chanmask; // chanmask-lo 00048 chanmask >>= 8; 00049 wifiScan_buf[1] = chanmask; // chanmask-hi 00050 wifiScan_buf[3] = 0x02; // acqMode 00051 wifiScan_buf[4] = WIFI_MAX_RESULTS; // NbMaxRes 00052 wifiScan_buf[5] = 0x10; // NbScanPerChan 00053 wifiScan_buf[7] = timeout; // Timeout-lo 00054 timeout >>= 8; 00055 wifiScan_buf[6] = timeout; // Timeout-hi 00056 wifiScan_buf[8] = 0x00; // AbortOnTimeout 00057 } 00058 00059 Radio::radio.xfer(OPCODE_WIFI_SCAN, 9, 0, wifiScan_buf); 00060 wifi_start_at = Kernel::get_ms_count(); 00061 printf("wifiScan...\r\n"); 00062 } 00063 00064 void long_press() 00065 { 00066 long_pressed = true; 00067 wifi_scan(); 00068 } 00069 00070 void button_pressed() 00071 { 00072 ub.rise(button_released); 00073 queue.cancel(wifi_scan_id); 00074 long_pressed = false; 00075 long_press_id = queue.call_in(500, long_press); 00076 } 00077 00078 void button_released() 00079 { 00080 ub.fall(button_pressed); 00081 if (!long_pressed) { 00082 wifi_scan_id = queue.call_in(20, wifi_scan); 00083 queue.cancel(long_press_id); 00084 } 00085 } 00086 00087 void txDoneCB() 00088 { 00089 Radio::Rx(0); 00090 queue.call_in(LORA_RX_TIME_MS, Radio::Standby); 00091 } 00092 00093 void rxDoneCB(uint8_t size, float rssi, float snr) 00094 { 00095 unsigned i; 00096 printf("%.1fdBm snr:%.1fdB\t", rssi, snr); 00097 00098 /* 00099 for (i = 0; i < size; i++) { 00100 printf("%02x ", Radio::radio.rx_buf[i]); 00101 } 00102 printf("\r\n");*/ 00103 00104 if (memcmp(Radio::radio.rx_buf, chip_eui, 8) == 0) { 00105 /* print resolved coordinates from cloud */ 00106 printf(">> %s\r\n", Radio::radio.rx_buf + HEADER_LENGTH); 00107 } 00108 } 00109 00110 struct wifidr { 00111 const char *txt; 00112 float Mbps; 00113 }; 00114 00115 const struct wifidr wifiDatarates[] = { 00116 /* 0 */ { NULL, 0}, 00117 /* 1 */ { "DBPSK", 1}, 00118 /* 2 */ { "DQPSK", 2}, 00119 /* 3 */ { "BPSK", 6}, 00120 /* 4 */ { "BPSK", 9}, 00121 /* 5 */ { "QPSK", 12}, 00122 /* 6 */ { "QPSK", 18}, 00123 /* 7 */ { "16-QAM", 24}, 00124 /* 8 */ { "16-QAM", 36}, 00125 /* 9 */ { "(9)", 0}, 00126 /* 10 */ { "(10)", 0}, 00127 /* 11 */ { "BPSK", 6.5}, 00128 /* 12 */ { "QPSK", 13}, 00129 /* 13 */ { "QPSK", 19.5}, 00130 /* 14 */ { "16-QAM", 26}, 00131 /* 15 */ { "16-QAM", 39}, 00132 /* 16 */ { "(16)", 0}, 00133 /* 17 */ { "(17)", 0}, 00134 /* 18 */ { "(18)", 0}, 00135 /* 19 */ { "BPSK", 7.2}, 00136 /* 20 */ { "QPSK", 14.4}, 00137 /* 21 */ { "QPSK", 21.7}, 00138 /* 22 */ { "16-QAM", 28.9}, 00139 /* 23 */ { "16-QAM", 43.3}, 00140 }; 00141 00142 void print_wifi_result(const uint8_t *result) 00143 { 00144 char out[96]; 00145 char str[24]; 00146 unsigned n, macStart; 00147 wifiType_t wt; 00148 wifiChanInfo_t ci; 00149 wt.octet = result[0]; 00150 ci.octet = result[1]; 00151 out[0] = 0; 00152 strcat(out, "802.11"); 00153 switch (wt.bits.signal) { 00154 case 1: strcat(out, "b"); break; 00155 case 2: strcat(out, "g"); break; 00156 case 3: strcat(out, "n"); break; 00157 } 00158 sprintf(str, " %s %.1fMbps", wifiDatarates[wt.bits.datarate].txt, wifiDatarates[wt.bits.datarate].Mbps); 00159 strcat(out, str); 00160 strcat(out, " "); 00161 00162 sprintf(str, "ch%u ", ci.bits.channelID); 00163 strcat(out, str); 00164 switch (ci.bits.channelID) { 00165 // table 10-5 00166 } 00167 strcat(out, " "); 00168 sprintf(str, "mv:%u ", ci.bits.macValidationID); 00169 strcat(out, str); 00170 switch (ci.bits.macValidationID) { 00171 case 1: strcat(out, "gateway"); break; 00172 case 2: strcat(out, "phone"); break; 00173 case 3: strcat(out, "?"); break; 00174 // table 10.8 00175 } 00176 00177 strcat(out, " "); 00178 00179 if (wifiResultFormatBasic) { 00180 macStart = 3; 00181 } else { 00182 macStart = 4; 00183 } 00184 for (n = 0; n < 6; n++) { 00185 sprintf(str, "%02x", result[n+macStart]); 00186 strcat(out, str); 00187 if (n < 5) 00188 strcat(out, ":"); 00189 } 00190 00191 sprintf(str, " rssi:%d ", (int8_t)result[2]); 00192 strcat(out, str); 00193 00194 if (!wifiResultFormatBasic) { 00195 sprintf(str, "frameCtrl:%02x ", result[3]); 00196 strcat(out, str); 00197 } 00198 printf("%s\r\n", out); 00199 } 00200 00201 static void service() 00202 { 00203 irq_t irq; 00204 irq.dword = Radio::radio.service(); 00205 if (irq.bits.WifiDone) { 00206 unsigned n; 00207 stat_t stat; 00208 uint8_t nbResults; 00209 stat.word = Radio::radio.xfer(OPCODE_GET_WIFI_NB_RESULTS, 0, 0, NULL); 00210 stat.word = Radio::radio.xfer(0x0000, 0, 1, &nbResults); 00211 if (stat.bits.cmdStatus != CMD_DAT) { 00212 printf("get-nbResult-fail\r\n"); 00213 return; 00214 } 00215 packet_len = HEADER_LENGTH; 00216 printf("%ums nbResults:%u\r\n", (unsigned)wifi_scan_dur, nbResults); 00217 for (n = 0; n < nbResults; n++) { 00218 uint8_t buf[3]; 00219 uint8_t resultBuf[22]; 00220 buf[0] = n; 00221 buf[1] = 1; // number of results in this read 00222 buf[2] = wifiResultFormatBasic ? 4 : 1; 00223 stat.word = Radio::radio.xfer(OPCODE_WIFI_READ_RESULTS, 3, 0, buf); 00224 // basic = 9byte length 00225 // full = 22byte length 00226 stat.word = Radio::radio.xfer(0x0000, 0, wifiResultFormatBasic ? 9 : 22, resultBuf); 00227 00228 if (stat.bits.cmdStatus == CMD_DAT) { 00229 unsigned n, macStart; 00230 wifiChanInfo_t ci; 00231 ci.octet = resultBuf[1]; 00232 if (ci.bits.macValidationID == 1) { // gateway (AP) 00233 macStart = wifiResultFormatBasic ? 3 : 4; 00234 for (n = 0; n < 6; n++) { 00235 Radio::radio.tx_buf[packet_len++] = resultBuf[n+macStart]; 00236 printf("%02x", resultBuf[n+macStart]); 00237 if (n < 5) 00238 printf(":"); 00239 } 00240 printf(" rssi:%d\r\n", (int8_t)resultBuf[2]); 00241 Radio::radio.tx_buf[packet_len++] = resultBuf[2]; 00242 } 00243 } else 00244 printf("readResult:%s\r\n", Radio::radio.cmdStatus_toString(stat.bits.cmdStatus)); 00245 } 00246 00247 if (!long_pressed) { 00248 unsigned n; 00249 cfg_lora(); 00250 for (n = 0; n < 8; n++) 00251 Radio::radio.tx_buf[n] = chip_eui[n]; 00252 00253 Radio::radio.tx_buf[n++] = 0; // rfu 00254 Radio::radio.tx_buf[n++] = 0; // rfu 00255 printf("pktLen:%u\r\n", packet_len); 00256 Radio::Send(packet_len, 0, 0, 0); /* begin transmission */ 00257 } 00258 } // ..if (irq.bits.WifiDone) 00259 00260 if (irq.bits.TxDone) { 00261 printf("main-TxDone\r\n"); 00262 } 00263 } 00264 00265 void radio_irq_callback() 00266 { 00267 wifi_scan_dur = Kernel::get_ms_count() - wifi_start_at; 00268 queue.call(service); 00269 } 00270 00271 const RadioEvents_t rev = { 00272 /* DioPin_top_half */ radio_irq_callback, 00273 /* TxDone_topHalf */ NULL, 00274 /* TxDone_botHalf */ txDoneCB, 00275 /* TxTimeout */ NULL, 00276 /* RxDone */ rxDoneCB, 00277 /* RxTimeout */ NULL, 00278 /* RxError */ NULL, 00279 /* FhssChangeChannel */NULL, 00280 /* CadDone */ NULL 00281 }; 00282 00283 int main() 00284 { 00285 Radio::Init(&rev); 00286 00287 Radio::Standby(); 00288 cfg_lora(); 00289 00290 { 00291 uint8_t buf[9]; 00292 stat_t stat; 00293 stat.word = Radio::radio.xfer(OPCODE_GET_VERSION, 0, 0, NULL); 00294 stat.word = Radio::radio.xfer(0x0000, 0, 4, buf); 00295 if (stat.bits.cmdStatus == CMD_DAT) { 00296 printf("LR1110 chip:%02x use:%02x fw-v%u.%u\r\n", 00297 buf[0], /* silicon rev */ 00298 buf[1], /* use case */ 00299 buf[2], /* firmware major */ 00300 buf[3] /* firmware minor */ 00301 ); 00302 } 00303 00304 stat.word = Radio::radio.xfer(OPCODE_GET_DEVEUI, 0, 0, NULL); 00305 stat.word = Radio::radio.xfer(0x0000, 0, 9, buf); 00306 memcpy(chip_eui, buf+1, 8); 00307 for (unsigned i = 0; i < 9; i++) 00308 printf("%02x ", buf[i]); 00309 printf("\r\n"); 00310 } 00311 00312 #ifdef AUTO_TX 00313 queue.call_in(500, tx_test); 00314 #endif /* AUTO_TX */ 00315 00316 if (ub.read()) 00317 ub.fall(button_pressed); 00318 else 00319 ub.rise(button_released); 00320 00321 queue.dispatch(); 00322 } 00323
Generated on Thu Jul 21 2022 14:54:14 by
