
repeat message down a chain, adding to the payload at each repeating device
Embed:
(wiki syntax)
Show/hide line numbers
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
