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.
main.cpp
00001 #include "radio.h" 00002 00003 #define UNIT_ID 0x00 /* 0x00: first unit */ 00004 //#define UNIT_LAST 00005 00006 // test large sample, large pkt size #define N_SMP 10 00007 typedef struct __attribute__((__packed__)) msg { 00008 uint8_t unit_id; 00009 uint8_t flags; 00010 uint16_t sample; 00011 00012 #ifdef N_SMP 00013 uint16_t samples[N_SMP]; 00014 #endif 00015 } message_t; 00016 00017 #define TX_INTERVAL_US 5000000 00018 #define MAX_TX_LENGTH 64 00019 #define TXRX_PADDING_US 10000 00020 #define MAX_TX_ATTEMPTS 4 00021 #define SPREADING_FACTOR 9 00022 #ifdef SX128x_H 00023 #define CF_MHZ 2487.0 00024 #define BW_KHZ 200 00025 #define TX_DBM 12 00026 #else 00027 #define CF_MHZ 917.6 00028 #define BW_KHZ 500 00029 #define TX_DBM 17 00030 #endif 00031 00032 #define EXPECTED_LENGTH (UNIT_ID * sizeof(message_t)) 00033 //#define MEASURED_MAX_ERR (TX_INTERVAL_US / 4000) // +/-100ppm allowance 00034 #define MEASURED_MAX_ERR (TX_INTERVAL_US / 300) // +/-Xppm allowance 00035 00036 #if defined(SX127x_H) 00037 #define RX_STARTUP_US 1500 00038 #elif defined(SX126x_H) 00039 #define RX_STARTUP_US 1000 00040 #elif defined(SX128x_H) 00041 #define RX_STARTUP_US 1000 00042 #endif 00043 unsigned rxStartup_us = RX_STARTUP_US; 00044 00045 RawSerial pc(USBTX, USBRX); 00046 DigitalIn button(USER_BUTTON); 00047 00048 #ifdef TARGET_DISCO_L072CZ_LRWAN1 00049 AnalogIn ain(A0); 00050 #elif defined(TARGET_MOTE_L152RC) 00051 AnalogIn ain(A0); 00052 #else 00053 #ifdef TARGET_FF_MORPHO 00054 AnalogIn ain(PC_4); // pin unused by arduino shields 00055 #endif /* TARGET_FF_MORPHO */ 00056 #endif /* !TARGET_DISCO_L072CZ_LRWAN1 */ 00057 00058 uint8_t forward_buf[255]; 00059 uint8_t forwardLen; 00060 uint8_t forwardLenTransmitted; 00061 uint8_t forwardLenAckd; 00062 int prevFrag; 00063 volatile us_timestamp_t forwardedAt; 00064 00065 volatile us_timestamp_t lastRxIrqAt; 00066 volatile us_timestamp_t measuredInterval, measuredIntervalSaved; 00067 00068 00069 enum _state_ { 00070 /* 0 */ STATE_NONE = 0, 00071 #if (UNIT_ID != 0x00) 00072 /* 1 */ STATE_GET_REQ, 00073 #endif /* UNIT_ID != 0x00 */ 00074 #ifndef UNIT_LAST 00075 /* 2 */ STATE_ACK_WAITING, 00076 /* 3 */ STATE_TX_FORWARD, 00077 #endif /* UNIT_LAST */ 00078 } state; 00079 00080 void stateToString(enum _state_ s, char* out) 00081 { 00082 const char* str; 00083 00084 switch (s) { 00085 case STATE_NONE: str = "NONE"; break; 00086 #if (UNIT_ID != 0x00) 00087 case STATE_GET_REQ: str = "GET_REQ"; break; 00088 #endif /* UNIT_ID != 0x00 */ 00089 #ifndef UNIT_LAST 00090 case STATE_ACK_WAITING: str = "ACK_WAITING"; break; 00091 case STATE_TX_FORWARD: str = "TX_FORWARD"; break; 00092 #endif /* UNIT_LAST */ 00093 default: 00094 sprintf(out, "??%u??", s); 00095 return; 00096 } 00097 00098 strcpy(out, str); 00099 } 00100 00101 typedef union { 00102 struct { 00103 uint8_t attempt : 3; // 0,1,2 00104 uint8_t fragNum : 4; // 3,4,5,6 00105 uint8_t fragLast : 1; // 7 00106 } bits; 00107 uint8_t octet; 00108 } pkt_flags_t; 00109 00110 volatile struct _f_ { 00111 uint8_t unused : 1; // 0 00112 uint8_t mbedTImeout_forwarderStarted: 1; // 1 00113 uint8_t run : 1; // 2 00114 uint8_t svc : 1; // 3 00115 #ifndef UNIT_LAST 00116 uint8_t sample : 1; // 4 00117 uint8_t fwd : 1; // 5 00118 #endif /* UNIT_LAST */ 00119 } flags; 00120 00121 00122 static uint16_t crc16( uint8_t *buffer, uint16_t length ) 00123 { 00124 uint16_t i; 00125 // The CRC calculation follows CCITT 00126 const uint16_t polynom = 0x1021; 00127 // CRC initial value 00128 uint16_t crc = 0x0000; 00129 00130 if( buffer == NULL ) 00131 { 00132 return 0; 00133 } 00134 00135 for( i = 0; i < length; ++i ) 00136 { 00137 uint16_t j; 00138 crc ^= ( uint16_t ) buffer[i] << 8; 00139 for( j = 0; j < 8; ++j ) 00140 { 00141 crc = ( crc & 0x8000 ) ? ( crc << 1 ) ^ polynom : ( crc << 1 ); 00142 } 00143 } 00144 00145 return crc; 00146 } 00147 00148 #ifdef UNIT_LAST 00149 void print_payload() 00150 { 00151 unsigned n; 00152 00153 for (n = 0; n < forwardLen; n += sizeof(message_t)) { 00154 const message_t* m = (message_t*)&forward_buf[n]; 00155 00156 pc.printf("unit %02x: %02x, %u\r\n", m->unit_id, m->flags, m->sample); 00157 } 00158 00159 } 00160 #endif /* UNIT_LAST */ 00161 00162 LowPowerTimeout mbedTimeout_nextRx; 00163 volatile unsigned retryInterval_us; 00164 volatile us_timestamp_t rxStartAt; 00165 00166 #if (UNIT_ID != 0x00) 00167 void setupNext() 00168 { 00169 state = STATE_GET_REQ; 00170 forwardLen = 0; 00171 prevFrag = -1; 00172 pc.printf("->GET_REQ "); 00173 00174 if (measuredInterval > 0) { 00175 Radio::Sleep(); 00176 pc.printf("SLEEP mi:%llu ", measuredInterval); 00177 measuredInterval = 0; // single use 00178 } else { 00179 Radio::Rx(0); 00180 00181 rxStartAt = 0; // starting of continuous rx not used 00182 00183 #ifndef UNIT_LAST 00184 flags.sample = 1; 00185 #endif /* UNIT_LAST */ 00186 pc.printf("RX "); 00187 } 00188 00189 memset(forward_buf, 0xff, EXPECTED_LENGTH); 00190 } 00191 #endif /* UNIT_ID != 0x00 */ 00192 00193 LowPowerTimeout mbedTImeout_forwarder; 00194 00195 00196 #ifndef UNIT_LAST 00197 volatile uint8_t txCurs; 00198 00199 LowPowerTicker tickerRetry; 00200 volatile us_timestamp_t txStartAt; 00201 00202 void retry_cb() 00203 { 00204 unsigned c; 00205 pkt_flags_t f; 00206 00207 Radio::Standby(); 00208 00209 f.octet = Radio::radio.tx_buf[1]; 00210 pc.printf("attempt%u", f.bits.attempt); 00211 if (++f.bits.attempt >= MAX_TX_ATTEMPTS) { 00212 pc.printf(" lastTry"); 00213 tickerRetry.detach(); 00214 #if (UNIT_ID != 0x00) 00215 setupNext(); 00216 #endif /* UNIT_ID != 0x00 */ 00217 pc.printf("\r\n"); 00218 return; 00219 } 00220 pc.printf("->%u\r\n", f.bits.attempt); 00221 Radio::radio.tx_buf[1] = f.octet; 00222 00223 c = crc16(Radio::radio.tx_buf, txCurs-2); 00224 Radio::radio.tx_buf[txCurs-2] = c >> 8; 00225 Radio::radio.tx_buf[txCurs-1] = c; 00226 00227 txStartAt = Radio::lpt.read_us(); 00228 Radio::Send(txCurs, 0, 0, 0); 00229 state = STATE_ACK_WAITING; 00230 } 00231 00232 volatile uint16_t sample; 00233 00234 #ifdef N_SMP 00235 volatile uint16_t samples[N_SMP]; 00236 #endif 00237 00238 #if (UNIT_ID != 0x00) 00239 uint8_t _tx_forward() 00240 { 00241 unsigned fwdLen; 00242 unsigned c; 00243 uint8_t added, avail, toSendLen, stop = MAX_TX_LENGTH-2; 00244 pkt_flags_t f; 00245 00246 tickerRetry.attach_us(retry_cb, retryInterval_us); 00247 00248 if (forwardLen < EXPECTED_LENGTH) { 00249 pc.printf("\e[31mmissing %u bytes\e[0m ", EXPECTED_LENGTH - forwardLen); 00250 fwdLen = EXPECTED_LENGTH; 00251 } 00252 fwdLen = forwardLen; 00253 00254 f.octet = Radio::radio.tx_buf[1]; 00255 00256 txCurs = 0; 00257 Radio::radio.tx_buf[txCurs++] = UNIT_ID; 00258 txCurs++; // placeholder for flags to be added at end 00259 00260 toSendLen = fwdLen - forwardLenAckd; 00261 forwardLenTransmitted = forwardLenAckd; 00262 added = 0; 00263 while ((txCurs + sizeof(message_t)) < stop && added < toSendLen) { 00264 memcpy(Radio::radio.tx_buf + txCurs, forward_buf + forwardLenTransmitted, sizeof(message_t)); 00265 forwardLenTransmitted += sizeof(message_t); 00266 txCurs += sizeof(message_t); 00267 added += sizeof(message_t); 00268 } 00269 00270 avail = stop - txCurs; 00271 if (avail >= sizeof(message_t)) { 00272 message_t* mptr = (message_t*)(Radio::radio.tx_buf + txCurs); 00273 mptr->unit_id = UNIT_ID; 00274 mptr->flags = 0x00; 00275 mptr->sample = sample; // taken from main loop 00276 #ifdef N_SMP 00277 for (c = 0; c < N_SMP; c++) 00278 mptr->samples[c] = samples[c]; // taken from main loop 00279 #endif 00280 txCurs += sizeof(message_t); 00281 00282 f.bits.fragLast = 1; 00283 } 00284 00285 Radio::radio.tx_buf[1] = f.octet; 00286 00287 c = crc16(Radio::radio.tx_buf, txCurs); 00288 Radio::radio.tx_buf[txCurs++] = c >> 8; 00289 Radio::radio.tx_buf[txCurs++] = c; 00290 00291 Radio::Send(txCurs, 0, 0, 0); 00292 state = STATE_ACK_WAITING; 00293 00294 return txCurs; 00295 } // .._tx_forward() 00296 00297 volatile us_timestamp_t prevFwdStart; 00298 00299 void tx_forward_cb() 00300 { 00301 unsigned dur; 00302 uint8_t txlen; 00303 us_timestamp_t now; 00304 00305 now = Radio::lpt.read_us(); 00306 00307 if (measuredIntervalSaved != 0) // in case nothing received 00308 mbedTImeout_forwarder.attach_us(tx_forward_cb, measuredIntervalSaved); 00309 00310 Radio::radio.tx_buf[1] = 0; //initialize flags 00311 forwardLenAckd = 0; 00312 00313 txlen = _tx_forward(); 00314 00315 flags.mbedTImeout_forwarderStarted = 0; 00316 00317 dur = Radio::lora_toa_us(txlen); 00318 pc.printf("\e[7mtx_forward_cb %lld", now - prevFwdStart - TX_INTERVAL_US); 00319 pc.printf(" dur%u\e[0m\r\n", dur); 00320 prevFwdStart = now; 00321 } 00322 #endif /* UNIT_ID != 0x00 */ 00323 00324 void sample_ticker_cb() 00325 { 00326 flags.sample = 1; 00327 } 00328 00329 #else // ..UNIT_LAST: 00330 void uart_forward_cb() 00331 { 00332 if (measuredIntervalSaved != 0) // in case nothing received 00333 mbedTImeout_forwarder.attach_us(uart_forward_cb, measuredIntervalSaved); 00334 00335 forwardLenAckd = 0; 00336 print_payload(); 00337 00338 setupNext(); 00339 00340 flags.mbedTImeout_forwarderStarted = 0; 00341 } 00342 #endif /* UNIT_LAST */ 00343 00344 void nextRxStartCB() 00345 { 00346 unsigned us; 00347 00348 Radio::Rx(0); 00349 rxStartAt = Radio::lpt.read_us(); 00350 00351 us = (MAX_TX_ATTEMPTS * retryInterval_us) + (MAX_TX_ATTEMPTS * TXRX_PADDING_US); 00352 00353 pc.printf("nextRxStartCB for %uus\r\n", us); 00354 00355 #ifndef UNIT_LAST 00356 flags.sample = 1; 00357 #endif /* UNIT_LAST */ 00358 } 00359 00360 00361 void txDoneCB() 00362 { 00363 char str[32]; 00364 00365 Radio::Rx(0); // receive ack 00366 stateToString(state, str); 00367 pc.printf("%s:txDone->Rx\r\n", str); 00368 } 00369 00370 void rxDoneCB(uint8_t size, float rssi, float snr) 00371 { 00372 #if (UNIT_ID != 0x00) 00373 pkt_flags_t f; 00374 us_timestamp_t rxIrqAt = Radio::irqAt; 00375 #endif /* UNIT_ID != 0x00 */ 00376 char str[32]; 00377 00378 stateToString(state, str); 00379 pc.printf("\e[33mrxDoneCB() %u rssi:%.1fdBm snr:%.1fdB %s ID:%02x\e[0m ", size, rssi, snr, str, Radio::radio.rx_buf[0]); 00380 #if (UNIT_ID != 0x00) 00381 if (state == STATE_GET_REQ) { 00382 uint8_t len; 00383 unsigned c, rxc; 00384 if (Radio::radio.rx_buf[0] != UNIT_ID-1) { 00385 pc.printf(" (not %02x)\r\n", UNIT_ID-1); 00386 return; 00387 } 00388 if (size < 4) { 00389 /* minimum: header + crc */ 00390 pc.printf(" (size<4)\r\n"); 00391 return; 00392 } 00393 f.octet = Radio::radio.rx_buf[1]; 00394 00395 c = crc16(Radio::radio.rx_buf, size-2); 00396 rxc = Radio::radio.rx_buf[size-2]; 00397 rxc <<= 8; 00398 rxc |= Radio::radio.rx_buf[size-1]; 00399 if (c != rxc) { 00400 pc.printf("\e[31mfrom%02x c:%04x rxc:%04x\e[0m\r\n", Radio::radio.rx_buf[0], c, rxc); 00401 for (unsigned n = 0; n < size; n++) 00402 pc.printf("%02x ", Radio::radio.rx_buf[n]); 00403 pc.printf("\r\n"); 00404 return; 00405 } 00406 //noRxTimeout.detach(); 00407 00408 pc.printf(" attempt%u frag%u fragLast%u ", f.bits.attempt, f.bits.fragNum, f.bits.fragLast); 00409 if (state == STATE_GET_REQ && flags.mbedTImeout_forwarderStarted == 0 && f.bits.fragLast) { 00410 us_timestamp_t now; 00411 unsigned sinceRxDone, us; 00412 mbedTImeout_forwarder.detach(); 00413 now = Radio::lpt.read_us(); 00414 sinceRxDone = now - rxIrqAt; 00415 us = retryInterval_us * (MAX_TX_ATTEMPTS - f.bits.attempt); 00416 int target_us = us - sinceRxDone; 00417 // tx to occur after time given for all potential retries 00418 #ifndef UNIT_LAST 00419 flags.sample = 1; // sample from main loop, to be ready for tx_forward 00420 mbedTImeout_forwarder.attach_us(tx_forward_cb, target_us); 00421 #else 00422 mbedTImeout_forwarder.attach_us(uart_forward_cb, target_us); 00423 #endif /* UNIT_LAST */ 00424 pc.printf("schedule forward %u, forwarding in %dus. sinceRxDone:%u\r\n", MAX_TX_ATTEMPTS - f.bits.attempt, target_us, sinceRxDone); 00425 flags.mbedTImeout_forwarderStarted = 1; 00426 forwardedAt = now + target_us; 00427 } 00428 00429 Radio::radio.tx_buf[0] = UNIT_ID; // OK, send ACK 00430 Radio::Send(1, 0, 0, 0); 00431 00432 00433 if (prevFrag != f.bits.fragNum) { 00434 len = size - 4; // -4: header ... crc 00435 memcpy(forward_buf + forwardLen, Radio::radio.rx_buf+2, len); 00436 forwardLen += len; 00437 00438 prevFrag = f.bits.fragNum; 00439 } 00440 00441 if (f.bits.fragNum == 0) { 00442 unsigned attemptOffset = retryInterval_us * f.bits.attempt; 00443 if (rxStartAt == 0) { 00444 pc.printf("\e[7m"); 00445 } 00446 pc.printf("lastRxIrqAt:%llu measuredInterval:%llu ", lastRxIrqAt, measuredInterval); 00447 if (lastRxIrqAt != 0) { 00448 us_timestamp_t thisMeas; 00449 int err_; 00450 unsigned abserr; 00451 thisMeas = (rxIrqAt - attemptOffset) - lastRxIrqAt; 00452 err_ = thisMeas - TX_INTERVAL_US; 00453 if (TX_INTERVAL_US > thisMeas) 00454 abserr = TX_INTERVAL_US - thisMeas; 00455 else 00456 abserr = thisMeas - TX_INTERVAL_US; 00457 00458 pc.printf(" this:%llu AO:%u, err_:%d ", thisMeas, attemptOffset, err_); 00459 if (abserr < MEASURED_MAX_ERR) { 00460 int rxPrecedency = 0; 00461 unsigned sinceRxDone, _us_; 00462 unsigned pktDur = Radio::lora_toa_us(size); 00463 us_timestamp_t firstAttemptStartedAt = (rxIrqAt - attemptOffset) - pktDur; 00464 00465 measuredInterval = thisMeas; 00466 _us_ = measuredInterval; 00467 pc.printf("->%llu ", measuredInterval); 00468 00469 if (rxStartAt != 0) { 00470 rxPrecedency = firstAttemptStartedAt - rxStartAt; 00471 if (rxPrecedency > 0) 00472 _us_ += rxPrecedency / 2; 00473 else 00474 _us_ += rxPrecedency; 00475 } 00476 00477 _us_ -= rxStartup_us; 00478 _us_ -= retryInterval_us; // TODO 00479 mbedTimeout_nextRx.detach(); 00480 sinceRxDone = Radio::lpt.read_us() - rxIrqAt; 00481 mbedTimeout_nextRx.attach_us(nextRxStartCB, _us_ - sinceRxDone); 00482 pc.printf("nextRx:%u ao%u rxPrecedency:%d pktDur%u ri%u sinceRxDone%u ", _us_ - sinceRxDone, attemptOffset, rxPrecedency, pktDur, retryInterval_us, sinceRxDone); 00483 00484 if (measuredIntervalSaved == 0) 00485 measuredIntervalSaved = measuredInterval; 00486 else { 00487 measuredIntervalSaved += measuredInterval; 00488 measuredIntervalSaved /= 2; 00489 } 00490 00491 rxStartAt = 0; 00492 } else 00493 pc.printf("\e[31mtoo-much-err\e[0m\r\n"); 00494 00495 pc.printf("\r\n"); 00496 } // ..if (lastRxIrqAt != 0) 00497 00498 lastRxIrqAt = rxIrqAt - attemptOffset; 00499 00500 pc.printf("\e[0m"); 00501 } // ..if (f.bits.fragNum == 0) 00502 00503 } // ..if (state == STATE_GET_REQ) 00504 else 00505 #endif /* UNIT_ID != 0x00 */ 00506 #ifndef UNIT_LAST 00507 if (state == STATE_ACK_WAITING) { 00508 00509 if (Radio::radio.rx_buf[0] == UNIT_ID+1) { 00510 pkt_flags_t f; 00511 f.octet = Radio::radio.tx_buf[1]; 00512 00513 tickerRetry.detach(); 00514 forwardLenAckd = forwardLenTransmitted; 00515 if (f.bits.fragLast) { 00516 pc.printf("ackOk-last "); 00517 #if (UNIT_ID == 0x00) 00518 pc.printf("->SLEEP "); 00519 Radio::Sleep(); 00520 #else 00521 setupNext(); 00522 #endif /* UNIT_ID != 0x00 */ 00523 } else { 00524 f.bits.fragNum++; 00525 f.bits.attempt = 0; 00526 Radio::radio.tx_buf[1] = f.octet; 00527 flags.sample = 1; 00528 flags.fwd = 1; // tx_forward from main loop 00529 pc.printf("ackOk->%u ", f.bits.fragNum); 00530 } 00531 } else 00532 pc.printf("ack from different ID %02x\r\n", Radio::radio.rx_buf[0]); 00533 } 00534 #endif /* UNIT_LAST */ 00535 00536 { 00537 mbed_stats_cpu_t stats; 00538 mbed_stats_cpu_get(&stats); 00539 printf("canDeep:%u ", sleep_manager_can_deep_sleep()); 00540 printf("Uptime: %llu ", stats.uptime / 1000); 00541 printf("Sleep time: %llu ", stats.sleep_time / 1000); 00542 printf("Deep Sleep: %llu\r\n", stats.deep_sleep_time / 1000); 00543 } 00544 00545 pc.printf("\r\n"); 00546 } // ..rxDoneCB() 00547 00548 #if (UNIT_ID == 0x00) && !defined(UNIT_LAST) 00549 LowPowerTicker sampleTicker, txTicker; 00550 00551 void tx_ticker_cb(void) { 00552 unsigned c; 00553 pkt_flags_t f; 00554 message_t* mptr; 00555 00556 tickerRetry.attach_us(retry_cb, retryInterval_us); 00557 00558 f.bits.attempt = 0; 00559 f.bits.fragNum = 0; 00560 f.bits.fragLast = 1; 00561 00562 Radio::Standby(); 00563 00564 txCurs = 0; 00565 Radio::radio.tx_buf[txCurs++] = UNIT_ID; 00566 Radio::radio.tx_buf[txCurs++] = f.octet; 00567 00568 mptr = (message_t*)(Radio::radio.tx_buf + txCurs); 00569 mptr->unit_id = UNIT_ID; 00570 mptr->flags = 0x00; 00571 mptr->sample = sample; 00572 #ifdef N_SMP 00573 for (c = 0; c < N_SMP; c++) 00574 mptr->samples[c] = samples[c]; 00575 #endif 00576 txCurs += sizeof(message_t); 00577 00578 c = crc16(Radio::radio.tx_buf, txCurs); 00579 Radio::radio.tx_buf[txCurs++] = c >> 8; 00580 Radio::radio.tx_buf[txCurs++] = c; 00581 00582 Radio::Send(txCurs, 0, 0, 0); 00583 txStartAt = Radio::lpt.read_us(); 00584 state = STATE_ACK_WAITING; 00585 00586 { 00587 mbed_stats_cpu_t stats; 00588 mbed_stats_cpu_get(&stats); 00589 pc.printf("canDeep:%u ", sleep_manager_can_deep_sleep()); 00590 pc.printf("Uptime: %llu ", stats.uptime / 1000); 00591 pc.printf("Sleep time: %llu ", stats.sleep_time / 1000); 00592 pc.printf("Deep Sleep: %llu ", stats.deep_sleep_time / 1000); 00593 } 00594 00595 pc.printf("tx_ticker_cb:%u\r\n", mptr->sample); 00596 } 00597 #endif /* UNIT_ID == 0x00 */ 00598 00599 #ifdef SX128x_H 00600 void 00601 print_radio_chip() 00602 { 00603 uint8_t buf[6]; 00604 unsigned khz = 0; 00605 LoRaPktPar0_t LoRaPktPar0; 00606 LoRaPktPar1_t LoRaPktPar1; 00607 status_t st; 00608 00609 Radio::radio.xfer(OPCODE_GET_IRQ_STATUS, 0, 3, buf); 00610 st.octet = buf[0]; 00611 printf("mode:%u cmdStatus:%u irq:%02x %02x ", st.bits.chipMode, st.bits.cmdStatus, buf[1], buf[2]); 00612 00613 LoRaPktPar0.octet = Radio::radio.readReg(REG_ADDR_LORA_PKTPAR0, 1); 00614 switch (LoRaPktPar0.bits.modem_bw) { 00615 case 2: khz = 200; break; 00616 case 3: khz = 400; break; 00617 case 4: khz = 800; break; 00618 case 5: khz = 1600; break; 00619 } 00620 printf("read:%uKHz sf%u\r\n", khz, LoRaPktPar0.bits.modem_sf); 00621 00622 printf("paylen%u ", (uint8_t)Radio::radio.readReg(REG_ADDR_LORA_TX_PAYLOAD_LENGTH, 1)); 00623 LoRaPktPar1.octet = Radio::radio.readReg(REG_ADDR_LORA_PKTPAR1, 1); 00624 printf("cr%u ", LoRaPktPar1.bits.coding_rate); 00625 if (LoRaPktPar1.bits.rxinvert_iq) 00626 printf("std "); 00627 else 00628 printf("inv "); 00629 if (LoRaPktPar1.bits.implicit_header) 00630 printf("im"); 00631 else 00632 printf("ex"); 00633 printf("plicit\r\n"); 00634 } 00635 #elif defined(SX127x_H) /* ...SX128x_H */ 00636 00637 void 00638 print_radio_chip() 00639 { 00640 } 00641 #elif defined(SX126x_H) /* ...SX127x_H */ 00642 00643 void 00644 print_radio_chip() 00645 { 00646 } 00647 #endif 00648 00649 void uart_rx() 00650 { 00651 char str[32]; 00652 00653 char ch = pc.getc(); 00654 switch (ch) { 00655 case '+': 00656 rxStartup_us += 500; 00657 pc.printf("rxStartup_us:%u\r\n", rxStartup_us); 00658 break; 00659 case '-': 00660 if (rxStartup_us > 500) 00661 rxStartup_us -= 500; 00662 pc.printf("rxStartup_us:%u\r\n", rxStartup_us); 00663 break; 00664 case '.': 00665 //Radio::PrintStatus(); 00666 printf("UNIT_ID:%02x ", UNIT_ID); 00667 printf(" measuredInterval:%llu\r\n", measuredInterval); 00668 stateToString(state, str); 00669 printf(" %s\r\n", str); 00670 break; 00671 case 'r': 00672 flags.run ^= 1; 00673 printf("\r\nrun %u\r\n", flags.run); 00674 if (flags.run == 0) { 00675 #ifndef UNIT_LAST 00676 tickerRetry.detach(); 00677 #endif /* !UNIT_LAST */ 00678 mbedTImeout_forwarder.detach(); 00679 mbedTimeout_nextRx.detach(); 00680 00681 Radio::Sleep(); 00682 } 00683 break; 00684 } // ..switch (ch) 00685 } 00686 00687 void radio_irq_topHalf() 00688 { 00689 flags.svc = 1; 00690 } 00691 00692 const RadioEvents_t rev = { 00693 /* DioPin_top_half */ radio_irq_topHalf, 00694 /* TxDone_topHalf */ NULL,//txDoneCBth, 00695 /* TxDone_botHalf */ txDoneCB, 00696 /* TxTimeout */ NULL, 00697 /* RxDone */ rxDoneCB, 00698 /* RxTimeout */ NULL, 00699 /* RxError */ NULL, 00700 /* FhssChangeChannel */NULL, 00701 /* CadDone */ NULL 00702 }; 00703 00704 int main() 00705 { 00706 flags.run = 1; 00707 pc.baud(115200); 00708 pc.printf("\r\nreset\r\n"); 00709 00710 Radio::Init(&rev); 00711 00712 Radio::Standby(); 00713 Radio::LoRaModemConfig(BW_KHZ, SPREADING_FACTOR, 1); 00714 Radio::LoRaPacketConfig(8, false, true, false); // preambleLen, fixLen, crcOn, invIQ 00715 Radio::SetChannel(CF_MHZ * 1000000); 00716 00717 printf("user_button:%u\r\n", button.read()); 00718 if (button.read()) { 00719 Radio::set_tx_dbm(TX_DBM); 00720 printf("PA to %ddBm\r\n", TX_DBM); 00721 } else { 00722 Radio::set_tx_dbm(PA_OFF_DBM); 00723 printf("PA off\r\n"); 00724 } 00725 00726 /* max TX length + turnaround + ACK length */ 00727 retryInterval_us = Radio::lora_toa_us(MAX_TX_LENGTH) + TXRX_PADDING_US + Radio::lora_toa_us(1); 00728 #ifdef UNIT_LAST 00729 pc.printf("LAST "); 00730 #endif 00731 pc.printf("UNIT_ID:%02x retryInterval_us:%u\r\n", UNIT_ID, retryInterval_us); 00732 00733 state = STATE_NONE; 00734 00735 #if (UNIT_ID == 0x00) && !defined(UNIT_LAST) 00736 sampleTicker.attach_us(sample_ticker_cb, TX_INTERVAL_US); 00737 wait_us(50000); 00738 txTicker.attach_us(tx_ticker_cb, TX_INTERVAL_US); 00739 #else 00740 //Radio::PrintStatus(); 00741 00742 setupNext(); 00743 00744 measuredInterval = 0; 00745 lastRxIrqAt = 0; 00746 measuredIntervalSaved = 0; 00747 #endif /* UNIT_ID != 0x00 */ 00748 00749 /* 00750 if (sleep_manager_can_deep_sleep()) 00751 sleep_manager_lock_deep_sleep(); // prevent deep sleep 00752 */ 00753 00754 for (;;) { 00755 if (pc.readable()) { 00756 uart_rx(); 00757 } 00758 00759 #ifndef UNIT_LAST 00760 if (flags.sample) { 00761 sample = ain.read_u16(); 00762 #ifdef N_SMP 00763 for (c = 0; c < N_SMP; c++) 00764 samples[c] = ain.read_u16(); 00765 #endif 00766 print_radio_chip(); 00767 if (flags.fwd) { 00768 #if (UNIT_ID == 0x00) 00769 pc.printf("\e[31mID00-fwd\e[0m\r\n"); 00770 #else 00771 _tx_forward(); 00772 #endif /* UNIT_ID != 0x00 */ 00773 flags.fwd = 0; 00774 } 00775 00776 flags.sample = 0; 00777 } 00778 #endif /* UNIT_LAST */ 00779 00780 sleep_manager_sleep_auto();; 00781 00782 if (flags.svc) { 00783 Radio::service(); 00784 flags.svc = 0; 00785 } 00786 00787 } // ..for (;;) 00788 } 00789
Generated on Thu Jul 21 2022 12:35:15 by
1.7.2