repeat message down a chain, adding to the payload at each repeating device

Dependencies:   sx12xx_hal

radio chip selection

Radio chip driver is not included, because options are available.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
if you're using SX1280, then import sx1280 driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.

/media/uploads/dudmuck/chain.png

network architecture

  • UNIT 0x00 transmitting only device: mandatory.
  • UNIT 0x01: repeating device
  • Uni-directional network: Each unit can only receive message from UNIT_ID - 1 (previous unit)
  • UINT n receiving only device LAST_UNIT: mandatory; prints payload onto UART.

configuration

Each device in the network is uniquely identified by:

  • UNIT_ID: ID byte designating address of this device.
  • UNIT_LAST: If defined, this device prints payload onto serial port instead of re-transmitting payload.

All devices in network must be configured identically with the following:

  • TX_INTERVAL_US: how often to take measurement and send to UNIT_ID+1 (time of complete cycle).
  • MAX_TX_LENGTH: Maximum size of payload, in bytes. Payload is sent in fragments when exceeds this value; aka size of each fragment.
  • TXRX_PADDING_US : Time allotted for RX-TX turnaround and CPU overhead
  • MAX_TX_ATTEMPTS: Count of transmit retries permitted
  • SPREADING_FACTOR LoRa configuration of datarate
  • CF_MHZ : Operating radio frequency


Duration of retry interval is auto-calculated from LoRa modem configuration (bandwidth/sf) and MAX_TX_LENGTH.
Take care that TX_INTERVAL_US value is appropriate relative to total retry interval (interval * MAX_TX_ATTEMPTS)

Committer:
Wayne Roberts
Date:
Thu Jul 05 17:43:35 2018 -0700
Revision:
1:7dbf0926e146
Parent:
0:d88677306896
Child:
2:534be88a25dc
use sx12xx_hal

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 0:d88677306896 1 #include "radio.h"
Wayne Roberts 0:d88677306896 2
Wayne Roberts 1:7dbf0926e146 3 #define UNIT_ID 0x03 /* 0x00: first unit */
Wayne Roberts 0:d88677306896 4 //#define UNIT_LAST
Wayne Roberts 0:d88677306896 5
Wayne Roberts 0:d88677306896 6 // test large sample, large pkt size #define N_SMP 10
Wayne Roberts 0:d88677306896 7 typedef struct __attribute__((__packed__)) msg {
Wayne Roberts 0:d88677306896 8 uint8_t unit_id;
Wayne Roberts 0:d88677306896 9 uint8_t flags;
Wayne Roberts 0:d88677306896 10 uint16_t sample;
Wayne Roberts 0:d88677306896 11
Wayne Roberts 0:d88677306896 12 #ifdef N_SMP
Wayne Roberts 0:d88677306896 13 uint16_t samples[N_SMP];
Wayne Roberts 0:d88677306896 14 #endif
Wayne Roberts 0:d88677306896 15 } message_t;
Wayne Roberts 0:d88677306896 16
Wayne Roberts 0:d88677306896 17 #define TX_INTERVAL_US 5000000
Wayne Roberts 0:d88677306896 18 #define MAX_TX_LENGTH 64
Wayne Roberts 0:d88677306896 19 #define TXRX_PADDING_US 10000
Wayne Roberts 0:d88677306896 20 #define MAX_TX_ATTEMPTS 4
Wayne Roberts 0:d88677306896 21 #define SPREADING_FACTOR 9
Wayne Roberts 0:d88677306896 22 #define CF_MHZ 917.6
Wayne Roberts 0:d88677306896 23
Wayne Roberts 0:d88677306896 24 #define EXPECTED_LENGTH (UNIT_ID * sizeof(message_t))
Wayne Roberts 0:d88677306896 25 //#define MEASURED_MAX_ERR (TX_INTERVAL_US / 4000) // +/-100ppm allowance
Wayne Roberts 0:d88677306896 26 #define MEASURED_MAX_ERR (TX_INTERVAL_US / 300) // +/-Xppm allowance
Wayne Roberts 0:d88677306896 27
Wayne Roberts 0:d88677306896 28 #if defined(SX127x_H)
Wayne Roberts 0:d88677306896 29 #define RX_STARTUP_US 1500
Wayne Roberts 0:d88677306896 30 #elif defined(SX126x_H)
Wayne Roberts 0:d88677306896 31 #define RX_STARTUP_US 1000
Wayne Roberts 1:7dbf0926e146 32 #elif defined(SX128x_H)
Wayne Roberts 1:7dbf0926e146 33 #define RX_STARTUP_US 1000
Wayne Roberts 0:d88677306896 34 #endif
Wayne Roberts 0:d88677306896 35 unsigned rxStartup_us = RX_STARTUP_US;
Wayne Roberts 0:d88677306896 36
Wayne Roberts 0:d88677306896 37 RawSerial pc(USBTX, USBRX);
Wayne Roberts 0:d88677306896 38
Wayne Roberts 0:d88677306896 39 #ifdef TARGET_DISCO_L072CZ_LRWAN1
Wayne Roberts 0:d88677306896 40 AnalogIn ain(A0);
Wayne Roberts 1:7dbf0926e146 41 #elif defined(TARGET_MOTE_L152RC)
Wayne Roberts 1:7dbf0926e146 42 AnalogIn ain(A0);
Wayne Roberts 0:d88677306896 43 #else
Wayne Roberts 0:d88677306896 44 #ifdef TARGET_FF_MORPHO
Wayne Roberts 0:d88677306896 45 AnalogIn ain(PC_4); // pin unused by arduino shields
Wayne Roberts 0:d88677306896 46 #endif /* TARGET_FF_MORPHO */
Wayne Roberts 0:d88677306896 47 #endif /* !TARGET_DISCO_L072CZ_LRWAN1 */
Wayne Roberts 0:d88677306896 48
Wayne Roberts 0:d88677306896 49 uint8_t forward[255];
Wayne Roberts 0:d88677306896 50 uint8_t forwardLen;
Wayne Roberts 0:d88677306896 51 uint8_t forwardLenTransmitted;
Wayne Roberts 0:d88677306896 52 uint8_t forwardLenAckd;
Wayne Roberts 0:d88677306896 53 int prevFrag;
Wayne Roberts 0:d88677306896 54 volatile us_timestamp_t forwardedAt;
Wayne Roberts 0:d88677306896 55
Wayne Roberts 0:d88677306896 56 volatile us_timestamp_t lastRxIrqAt;
Wayne Roberts 0:d88677306896 57 volatile us_timestamp_t measuredInterval, measuredIntervalSaved;
Wayne Roberts 0:d88677306896 58
Wayne Roberts 0:d88677306896 59
Wayne Roberts 0:d88677306896 60 enum _state_ {
Wayne Roberts 0:d88677306896 61 /* 0 */ STATE_NONE = 0,
Wayne Roberts 0:d88677306896 62 /* 1 */ STATE_GET_REQ,
Wayne Roberts 0:d88677306896 63 #ifndef UNIT_LAST
Wayne Roberts 0:d88677306896 64 /* 2 */ STATE_ACK_WAITING,
Wayne Roberts 0:d88677306896 65 /* 3 */ STATE_TX_FORWARD,
Wayne Roberts 0:d88677306896 66 #endif /* UNIT_LAST */
Wayne Roberts 0:d88677306896 67 } state;
Wayne Roberts 0:d88677306896 68
Wayne Roberts 0:d88677306896 69 void stateToString(enum _state_ s, char* out)
Wayne Roberts 0:d88677306896 70 {
Wayne Roberts 0:d88677306896 71 const char* str;
Wayne Roberts 0:d88677306896 72
Wayne Roberts 0:d88677306896 73 switch (s) {
Wayne Roberts 0:d88677306896 74 case STATE_NONE: str = "NONE"; break;
Wayne Roberts 0:d88677306896 75 case STATE_GET_REQ: str = "GET_REQ"; break;
Wayne Roberts 0:d88677306896 76 #ifndef UNIT_LAST
Wayne Roberts 0:d88677306896 77 case STATE_ACK_WAITING: str = "ACK_WAITING"; break;
Wayne Roberts 0:d88677306896 78 case STATE_TX_FORWARD: str = "TX_FORWARD"; break;
Wayne Roberts 0:d88677306896 79 #endif /* UNIT_LAST */
Wayne Roberts 0:d88677306896 80 default:
Wayne Roberts 0:d88677306896 81 sprintf(out, "??%u??", s);
Wayne Roberts 0:d88677306896 82 return;
Wayne Roberts 0:d88677306896 83 }
Wayne Roberts 0:d88677306896 84
Wayne Roberts 0:d88677306896 85 strcpy(out, str);
Wayne Roberts 0:d88677306896 86 }
Wayne Roberts 0:d88677306896 87
Wayne Roberts 0:d88677306896 88 typedef union {
Wayne Roberts 0:d88677306896 89 struct {
Wayne Roberts 0:d88677306896 90 uint8_t attempt : 3; // 0,1,2
Wayne Roberts 0:d88677306896 91 uint8_t fragNum : 4; // 3,4,5,6
Wayne Roberts 0:d88677306896 92 uint8_t fragLast : 1; // 7
Wayne Roberts 0:d88677306896 93 } bits;
Wayne Roberts 0:d88677306896 94 uint8_t octet;
Wayne Roberts 0:d88677306896 95 } pkt_flags_t;
Wayne Roberts 0:d88677306896 96
Wayne Roberts 0:d88677306896 97 volatile struct _f_ {
Wayne Roberts 0:d88677306896 98 uint8_t _sleep_ : 1; // 0
Wayne Roberts 0:d88677306896 99 uint8_t mbedTImeout_forwarderStarted: 1; // 1
Wayne Roberts 0:d88677306896 100 uint8_t run : 1; // 2
Wayne Roberts 0:d88677306896 101 } flags;
Wayne Roberts 0:d88677306896 102
Wayne Roberts 0:d88677306896 103
Wayne Roberts 0:d88677306896 104 static uint16_t crc16( uint8_t *buffer, uint16_t length )
Wayne Roberts 0:d88677306896 105 {
Wayne Roberts 0:d88677306896 106 uint16_t i;
Wayne Roberts 0:d88677306896 107 // The CRC calculation follows CCITT
Wayne Roberts 0:d88677306896 108 const uint16_t polynom = 0x1021;
Wayne Roberts 0:d88677306896 109 // CRC initial value
Wayne Roberts 0:d88677306896 110 uint16_t crc = 0x0000;
Wayne Roberts 0:d88677306896 111
Wayne Roberts 0:d88677306896 112 if( buffer == NULL )
Wayne Roberts 0:d88677306896 113 {
Wayne Roberts 0:d88677306896 114 return 0;
Wayne Roberts 0:d88677306896 115 }
Wayne Roberts 0:d88677306896 116
Wayne Roberts 0:d88677306896 117 for( i = 0; i < length; ++i )
Wayne Roberts 0:d88677306896 118 {
Wayne Roberts 0:d88677306896 119 uint16_t j;
Wayne Roberts 0:d88677306896 120 crc ^= ( uint16_t ) buffer[i] << 8;
Wayne Roberts 0:d88677306896 121 for( j = 0; j < 8; ++j )
Wayne Roberts 0:d88677306896 122 {
Wayne Roberts 0:d88677306896 123 crc = ( crc & 0x8000 ) ? ( crc << 1 ) ^ polynom : ( crc << 1 );
Wayne Roberts 0:d88677306896 124 }
Wayne Roberts 0:d88677306896 125 }
Wayne Roberts 0:d88677306896 126
Wayne Roberts 0:d88677306896 127 return crc;
Wayne Roberts 0:d88677306896 128 }
Wayne Roberts 0:d88677306896 129
Wayne Roberts 0:d88677306896 130 #ifdef UNIT_LAST
Wayne Roberts 0:d88677306896 131 void print_payload()
Wayne Roberts 0:d88677306896 132 {
Wayne Roberts 0:d88677306896 133 unsigned n;
Wayne Roberts 0:d88677306896 134
Wayne Roberts 0:d88677306896 135 for (n = 0; n < forwardLen; n += sizeof(message_t)) {
Wayne Roberts 0:d88677306896 136 const message_t* m = (message_t*)&forward[n];
Wayne Roberts 0:d88677306896 137
Wayne Roberts 0:d88677306896 138 pc.printf("unit %02x: %02x, %u\r\n", m->unit_id, m->flags, m->sample);
Wayne Roberts 0:d88677306896 139 }
Wayne Roberts 0:d88677306896 140
Wayne Roberts 0:d88677306896 141 }
Wayne Roberts 0:d88677306896 142 #endif /* UNIT_LAST */
Wayne Roberts 0:d88677306896 143
Wayne Roberts 0:d88677306896 144 LowPowerTimeout mbedTimeout_nextRx;
Wayne Roberts 0:d88677306896 145 volatile unsigned retryInterval_us;
Wayne Roberts 0:d88677306896 146 volatile us_timestamp_t rxStartAt;
Wayne Roberts 0:d88677306896 147
Wayne Roberts 0:d88677306896 148
Wayne Roberts 0:d88677306896 149 void setupNext()
Wayne Roberts 0:d88677306896 150 {
Wayne Roberts 0:d88677306896 151 state = STATE_GET_REQ;
Wayne Roberts 0:d88677306896 152 forwardLen = 0;
Wayne Roberts 0:d88677306896 153 prevFrag = -1;
Wayne Roberts 0:d88677306896 154 pc.printf("->GET_REQ ");
Wayne Roberts 0:d88677306896 155 if (measuredInterval > 0) {
Wayne Roberts 0:d88677306896 156 flags._sleep_ = 1;
Wayne Roberts 0:d88677306896 157 Radio::Sleep();
Wayne Roberts 0:d88677306896 158 pc.printf("SLEEP mi:%llu ", measuredInterval);
Wayne Roberts 0:d88677306896 159 measuredInterval = 0; // single use
Wayne Roberts 0:d88677306896 160 } else {
Wayne Roberts 0:d88677306896 161 flags._sleep_ = 0;
Wayne Roberts 1:7dbf0926e146 162 Radio::Rx(0);
Wayne Roberts 0:d88677306896 163
Wayne Roberts 0:d88677306896 164 rxStartAt = 0; // starting of continuous rx not used
Wayne Roberts 0:d88677306896 165
Wayne Roberts 0:d88677306896 166 pc.printf("RX ");
Wayne Roberts 0:d88677306896 167 }
Wayne Roberts 0:d88677306896 168
Wayne Roberts 0:d88677306896 169 memset(forward, 0xff, EXPECTED_LENGTH);
Wayne Roberts 0:d88677306896 170 }
Wayne Roberts 0:d88677306896 171
Wayne Roberts 0:d88677306896 172 LowPowerTimeout mbedTImeout_forwarder;
Wayne Roberts 0:d88677306896 173
Wayne Roberts 1:7dbf0926e146 174
Wayne Roberts 0:d88677306896 175 #ifndef UNIT_LAST
Wayne Roberts 0:d88677306896 176 volatile uint8_t txCurs;
Wayne Roberts 0:d88677306896 177
Wayne Roberts 0:d88677306896 178 LowPowerTicker tickerRetry;
Wayne Roberts 1:7dbf0926e146 179 volatile us_timestamp_t txStartAt;
Wayne Roberts 0:d88677306896 180
Wayne Roberts 0:d88677306896 181 void retry_cb()
Wayne Roberts 0:d88677306896 182 {
Wayne Roberts 0:d88677306896 183 unsigned c;
Wayne Roberts 0:d88677306896 184 pkt_flags_t f;
Wayne Roberts 0:d88677306896 185
Wayne Roberts 1:7dbf0926e146 186 Radio::Standby();
Wayne Roberts 1:7dbf0926e146 187
Wayne Roberts 0:d88677306896 188 f.octet = Radio::radio.tx_buf[1];
Wayne Roberts 0:d88677306896 189 pc.printf("attempt%u", f.bits.attempt);
Wayne Roberts 0:d88677306896 190 if (++f.bits.attempt >= MAX_TX_ATTEMPTS) {
Wayne Roberts 0:d88677306896 191 pc.printf(" lastTry");
Wayne Roberts 0:d88677306896 192 tickerRetry.detach();
Wayne Roberts 1:7dbf0926e146 193 #if (UNIT_ID == 0x00)
Wayne Roberts 1:7dbf0926e146 194 flags._sleep_ = 1;
Wayne Roberts 1:7dbf0926e146 195 #else
Wayne Roberts 0:d88677306896 196 setupNext();
Wayne Roberts 0:d88677306896 197 #endif /* UNIT_ID != 0x00 */
Wayne Roberts 0:d88677306896 198 pc.printf("\r\n");
Wayne Roberts 0:d88677306896 199 return;
Wayne Roberts 0:d88677306896 200 }
Wayne Roberts 0:d88677306896 201 pc.printf("->%u\r\n", f.bits.attempt);
Wayne Roberts 0:d88677306896 202 Radio::radio.tx_buf[1] = f.octet;
Wayne Roberts 0:d88677306896 203
Wayne Roberts 0:d88677306896 204 c = crc16(Radio::radio.tx_buf, txCurs-2);
Wayne Roberts 0:d88677306896 205 Radio::radio.tx_buf[txCurs-2] = c >> 8;
Wayne Roberts 0:d88677306896 206 Radio::radio.tx_buf[txCurs-1] = c;
Wayne Roberts 0:d88677306896 207
Wayne Roberts 1:7dbf0926e146 208 txStartAt = Radio::lpt.read_us();
Wayne Roberts 0:d88677306896 209 Radio::Send(txCurs, 0, 0, 0);
Wayne Roberts 0:d88677306896 210 state = STATE_ACK_WAITING;
Wayne Roberts 0:d88677306896 211 }
Wayne Roberts 0:d88677306896 212
Wayne Roberts 0:d88677306896 213 uint8_t _tx_forward()
Wayne Roberts 0:d88677306896 214 {
Wayne Roberts 0:d88677306896 215 unsigned fwdLen;
Wayne Roberts 0:d88677306896 216 unsigned c;
Wayne Roberts 0:d88677306896 217 uint8_t added, avail, toSendLen, stop = MAX_TX_LENGTH-2;
Wayne Roberts 0:d88677306896 218 pkt_flags_t f;
Wayne Roberts 0:d88677306896 219
Wayne Roberts 0:d88677306896 220 tickerRetry.attach_us(retry_cb, retryInterval_us);
Wayne Roberts 0:d88677306896 221
Wayne Roberts 0:d88677306896 222 if (forwardLen < EXPECTED_LENGTH) {
Wayne Roberts 0:d88677306896 223 pc.printf("\e[31mmissing %u bytes\e[0m ", EXPECTED_LENGTH - forwardLen);
Wayne Roberts 0:d88677306896 224 fwdLen = EXPECTED_LENGTH;
Wayne Roberts 0:d88677306896 225 }
Wayne Roberts 0:d88677306896 226 fwdLen = forwardLen;
Wayne Roberts 0:d88677306896 227
Wayne Roberts 0:d88677306896 228 f.octet = Radio::radio.tx_buf[1];
Wayne Roberts 0:d88677306896 229
Wayne Roberts 0:d88677306896 230 txCurs = 0;
Wayne Roberts 0:d88677306896 231 Radio::radio.tx_buf[txCurs++] = UNIT_ID;
Wayne Roberts 0:d88677306896 232 txCurs++; // placeholder for flags to be added at end
Wayne Roberts 0:d88677306896 233
Wayne Roberts 0:d88677306896 234 toSendLen = fwdLen - forwardLenAckd;
Wayne Roberts 0:d88677306896 235 forwardLenTransmitted = forwardLenAckd;
Wayne Roberts 0:d88677306896 236 added = 0;
Wayne Roberts 0:d88677306896 237 while ((txCurs + sizeof(message_t)) < stop && added < toSendLen) {
Wayne Roberts 0:d88677306896 238 memcpy(Radio::radio.tx_buf + txCurs, forward + forwardLenTransmitted, sizeof(message_t));
Wayne Roberts 0:d88677306896 239 forwardLenTransmitted += sizeof(message_t);
Wayne Roberts 0:d88677306896 240 txCurs += sizeof(message_t);
Wayne Roberts 0:d88677306896 241 added += sizeof(message_t);
Wayne Roberts 0:d88677306896 242 }
Wayne Roberts 0:d88677306896 243
Wayne Roberts 0:d88677306896 244 avail = stop - txCurs;
Wayne Roberts 0:d88677306896 245 if (avail >= sizeof(message_t)) {
Wayne Roberts 0:d88677306896 246 message_t* mptr = (message_t*)(Radio::radio.tx_buf + txCurs);
Wayne Roberts 0:d88677306896 247 mptr->unit_id = UNIT_ID;
Wayne Roberts 0:d88677306896 248 mptr->flags = 0x00;
Wayne Roberts 0:d88677306896 249 mptr->sample = ain.read_u16();
Wayne Roberts 0:d88677306896 250 #ifdef N_SMP
Wayne Roberts 0:d88677306896 251 for (c = 0; c < N_SMP; c++)
Wayne Roberts 0:d88677306896 252 mptr->samples[c] = ain.read_u16();
Wayne Roberts 0:d88677306896 253 #endif
Wayne Roberts 0:d88677306896 254 txCurs += sizeof(message_t);
Wayne Roberts 0:d88677306896 255
Wayne Roberts 0:d88677306896 256 f.bits.fragLast = 1;
Wayne Roberts 0:d88677306896 257 }
Wayne Roberts 0:d88677306896 258
Wayne Roberts 0:d88677306896 259 Radio::radio.tx_buf[1] = f.octet;
Wayne Roberts 0:d88677306896 260
Wayne Roberts 0:d88677306896 261 c = crc16(Radio::radio.tx_buf, txCurs);
Wayne Roberts 0:d88677306896 262 Radio::radio.tx_buf[txCurs++] = c >> 8;
Wayne Roberts 0:d88677306896 263 Radio::radio.tx_buf[txCurs++] = c;
Wayne Roberts 0:d88677306896 264
Wayne Roberts 1:7dbf0926e146 265 /*Radio::set_tx_dbm(17);
Wayne Roberts 1:7dbf0926e146 266 Radio::PrintStatus();*/
Wayne Roberts 0:d88677306896 267 Radio::Send(txCurs, 0, 0, 0);
Wayne Roberts 0:d88677306896 268 state = STATE_ACK_WAITING;
Wayne Roberts 0:d88677306896 269 flags._sleep_ = 0;
Wayne Roberts 0:d88677306896 270
Wayne Roberts 0:d88677306896 271 return txCurs;
Wayne Roberts 0:d88677306896 272 } // .._tx_forward()
Wayne Roberts 0:d88677306896 273
Wayne Roberts 0:d88677306896 274 volatile us_timestamp_t prevFwdStart;
Wayne Roberts 0:d88677306896 275
Wayne Roberts 0:d88677306896 276 void tx_forward_cb()
Wayne Roberts 0:d88677306896 277 {
Wayne Roberts 0:d88677306896 278 unsigned dur;
Wayne Roberts 0:d88677306896 279 uint8_t txlen;
Wayne Roberts 0:d88677306896 280 us_timestamp_t now;
Wayne Roberts 0:d88677306896 281
Wayne Roberts 0:d88677306896 282 now = Radio::lpt.read_us();
Wayne Roberts 0:d88677306896 283
Wayne Roberts 0:d88677306896 284 if (measuredIntervalSaved != 0) // in case nothing received
Wayne Roberts 0:d88677306896 285 mbedTImeout_forwarder.attach_us(tx_forward_cb, measuredIntervalSaved);
Wayne Roberts 0:d88677306896 286
Wayne Roberts 0:d88677306896 287 Radio::radio.tx_buf[1] = 0; //initialize flags
Wayne Roberts 0:d88677306896 288 forwardLenAckd = 0;
Wayne Roberts 0:d88677306896 289
Wayne Roberts 0:d88677306896 290 txlen = _tx_forward();
Wayne Roberts 0:d88677306896 291
Wayne Roberts 0:d88677306896 292 flags.mbedTImeout_forwarderStarted = 0;
Wayne Roberts 0:d88677306896 293
Wayne Roberts 0:d88677306896 294 dur = Radio::lora_toa_us(txlen);
Wayne Roberts 0:d88677306896 295 pc.printf("\e[7mtx_forward_cb %d", now - prevFwdStart - TX_INTERVAL_US);
Wayne Roberts 0:d88677306896 296 pc.printf(" dur%u\e[0m\r\n", dur);
Wayne Roberts 0:d88677306896 297 prevFwdStart = now;
Wayne Roberts 0:d88677306896 298 }
Wayne Roberts 0:d88677306896 299 #else // ..UNIT_LAST:
Wayne Roberts 0:d88677306896 300 void uart_forward_cb()
Wayne Roberts 0:d88677306896 301 {
Wayne Roberts 0:d88677306896 302 if (measuredIntervalSaved != 0) // in case nothing received
Wayne Roberts 0:d88677306896 303 mbedTImeout_forwarder.attach_us(uart_forward_cb, measuredIntervalSaved);
Wayne Roberts 0:d88677306896 304
Wayne Roberts 0:d88677306896 305 forwardLenAckd = 0;
Wayne Roberts 0:d88677306896 306 print_payload();
Wayne Roberts 0:d88677306896 307
Wayne Roberts 0:d88677306896 308 setupNext();
Wayne Roberts 0:d88677306896 309
Wayne Roberts 0:d88677306896 310 flags.mbedTImeout_forwarderStarted = 0;
Wayne Roberts 0:d88677306896 311 }
Wayne Roberts 0:d88677306896 312 #endif /* UNIT_LAST */
Wayne Roberts 0:d88677306896 313
Wayne Roberts 0:d88677306896 314 void nextRxStartCB()
Wayne Roberts 0:d88677306896 315 {
Wayne Roberts 0:d88677306896 316 unsigned us;
Wayne Roberts 0:d88677306896 317
Wayne Roberts 1:7dbf0926e146 318 Radio::Rx(0);
Wayne Roberts 0:d88677306896 319 rxStartAt = Radio::lpt.read_us();
Wayne Roberts 0:d88677306896 320 flags._sleep_ = 0;
Wayne Roberts 0:d88677306896 321
Wayne Roberts 0:d88677306896 322 us = (MAX_TX_ATTEMPTS * retryInterval_us) + (MAX_TX_ATTEMPTS * TXRX_PADDING_US);
Wayne Roberts 0:d88677306896 323
Wayne Roberts 0:d88677306896 324 pc.printf("nextRxStartCB for %uus\r\n", us);
Wayne Roberts 0:d88677306896 325 }
Wayne Roberts 0:d88677306896 326
Wayne Roberts 0:d88677306896 327
Wayne Roberts 0:d88677306896 328 void txDoneCB()
Wayne Roberts 0:d88677306896 329 {
Wayne Roberts 0:d88677306896 330 char str[32];
Wayne Roberts 0:d88677306896 331
Wayne Roberts 1:7dbf0926e146 332 Radio::Rx(0);
Wayne Roberts 0:d88677306896 333 stateToString(state, str);
Wayne Roberts 0:d88677306896 334 pc.printf("%s:txDone->Rx\r\n", str);
Wayne Roberts 0:d88677306896 335 }
Wayne Roberts 0:d88677306896 336
Wayne Roberts 0:d88677306896 337 void rxDoneCB(uint8_t size, float rssi, float snr)
Wayne Roberts 0:d88677306896 338 {
Wayne Roberts 0:d88677306896 339 pkt_flags_t f;
Wayne Roberts 0:d88677306896 340 char str[32];
Wayne Roberts 0:d88677306896 341 us_timestamp_t rxIrqAt = Radio::irqAt;
Wayne Roberts 0:d88677306896 342
Wayne Roberts 0:d88677306896 343 stateToString(state, str);
Wayne Roberts 0:d88677306896 344 pc.printf("\e[33mrxDoneCB() %u rssi:%.1fdBm snr:%.1fdB %s ID:%02x\e[0m ", size, rssi, snr, str, Radio::radio.rx_buf[0]);
Wayne Roberts 0:d88677306896 345 if (state == STATE_GET_REQ) {
Wayne Roberts 0:d88677306896 346 uint8_t len;
Wayne Roberts 0:d88677306896 347 unsigned c, rxc;
Wayne Roberts 0:d88677306896 348 if (Radio::radio.rx_buf[0] != UNIT_ID-1) {
Wayne Roberts 0:d88677306896 349 pc.printf("\r\n");
Wayne Roberts 0:d88677306896 350 return;
Wayne Roberts 0:d88677306896 351 }
Wayne Roberts 0:d88677306896 352 if (size < 4) {
Wayne Roberts 0:d88677306896 353 /* minimum: header + crc */
Wayne Roberts 0:d88677306896 354 pc.printf("\r\n");
Wayne Roberts 0:d88677306896 355 return;
Wayne Roberts 0:d88677306896 356 }
Wayne Roberts 0:d88677306896 357 f.octet = Radio::radio.rx_buf[1];
Wayne Roberts 0:d88677306896 358
Wayne Roberts 0:d88677306896 359 c = crc16(Radio::radio.rx_buf, size-2);
Wayne Roberts 0:d88677306896 360 rxc = Radio::radio.rx_buf[size-2];
Wayne Roberts 0:d88677306896 361 rxc <<= 8;
Wayne Roberts 0:d88677306896 362 rxc |= Radio::radio.rx_buf[size-1];
Wayne Roberts 0:d88677306896 363 if (c != rxc) {
Wayne Roberts 0:d88677306896 364 pc.printf("\e[31mfrom%02x c:%04x rxc:%04x\e[0m\r\n", Radio::radio.rx_buf[0], c, rxc);
Wayne Roberts 0:d88677306896 365 for (unsigned n = 0; n < size; n++)
Wayne Roberts 0:d88677306896 366 pc.printf("%02x ", Radio::radio.rx_buf[n]);
Wayne Roberts 0:d88677306896 367 pc.printf("\r\n");
Wayne Roberts 0:d88677306896 368 return;
Wayne Roberts 0:d88677306896 369 }
Wayne Roberts 0:d88677306896 370 //noRxTimeout.detach();
Wayne Roberts 0:d88677306896 371
Wayne Roberts 0:d88677306896 372 pc.printf(" attempt%u frag%u fragLast%u ", f.bits.attempt, f.bits.fragNum, f.bits.fragLast);
Wayne Roberts 0:d88677306896 373 if (state == STATE_GET_REQ && flags.mbedTImeout_forwarderStarted == 0 && f.bits.fragLast) {
Wayne Roberts 0:d88677306896 374 us_timestamp_t now;
Wayne Roberts 0:d88677306896 375 unsigned sinceRxDone, us;
Wayne Roberts 0:d88677306896 376 mbedTImeout_forwarder.detach();
Wayne Roberts 0:d88677306896 377 now = Radio::lpt.read_us();
Wayne Roberts 0:d88677306896 378 sinceRxDone = now - rxIrqAt;
Wayne Roberts 0:d88677306896 379 us = retryInterval_us * (MAX_TX_ATTEMPTS - f.bits.attempt);
Wayne Roberts 0:d88677306896 380 int target_us = us - sinceRxDone;
Wayne Roberts 0:d88677306896 381 // tx to occur after time given for all potential retries
Wayne Roberts 0:d88677306896 382 #ifndef UNIT_LAST
Wayne Roberts 0:d88677306896 383 mbedTImeout_forwarder.attach_us(tx_forward_cb, target_us);
Wayne Roberts 0:d88677306896 384 #else
Wayne Roberts 0:d88677306896 385 mbedTImeout_forwarder.attach_us(uart_forward_cb, target_us);
Wayne Roberts 0:d88677306896 386 #endif /* UNIT_LAST */
Wayne Roberts 0:d88677306896 387 pc.printf("schedule forward %u, forwarding in %dus. sinceRxDone:%u\r\n", MAX_TX_ATTEMPTS - f.bits.attempt, target_us, sinceRxDone);
Wayne Roberts 0:d88677306896 388 flags.mbedTImeout_forwarderStarted = 1;
Wayne Roberts 0:d88677306896 389 forwardedAt = now + target_us;
Wayne Roberts 0:d88677306896 390 }
Wayne Roberts 0:d88677306896 391
Wayne Roberts 0:d88677306896 392 Radio::radio.tx_buf[0] = UNIT_ID; // OK, send ACK
Wayne Roberts 1:7dbf0926e146 393 /*YYY Radio::set_tx_dbm(17);
Wayne Roberts 1:7dbf0926e146 394 Radio::PrintStatus();*/
Wayne Roberts 0:d88677306896 395 Radio::Send(1, 0, 0, 0);
Wayne Roberts 0:d88677306896 396
Wayne Roberts 0:d88677306896 397
Wayne Roberts 0:d88677306896 398 if (prevFrag != f.bits.fragNum) {
Wayne Roberts 0:d88677306896 399 len = size - 4; // -4: header ... crc
Wayne Roberts 0:d88677306896 400 memcpy(forward + forwardLen, Radio::radio.rx_buf+2, len);
Wayne Roberts 0:d88677306896 401 forwardLen += len;
Wayne Roberts 0:d88677306896 402
Wayne Roberts 0:d88677306896 403 prevFrag = f.bits.fragNum;
Wayne Roberts 0:d88677306896 404 }
Wayne Roberts 0:d88677306896 405
Wayne Roberts 0:d88677306896 406 if (f.bits.fragNum == 0) {
Wayne Roberts 0:d88677306896 407 unsigned attemptOffset = retryInterval_us * f.bits.attempt;
Wayne Roberts 0:d88677306896 408 if (rxStartAt == 0) {
Wayne Roberts 0:d88677306896 409 pc.printf("\e[7m");
Wayne Roberts 0:d88677306896 410 }
Wayne Roberts 0:d88677306896 411 pc.printf("lastRxIrqAt:%u measuredInterval:%llu ", lastRxIrqAt, measuredInterval);
Wayne Roberts 0:d88677306896 412 if (lastRxIrqAt != 0) {
Wayne Roberts 0:d88677306896 413 us_timestamp_t thisMeas;
Wayne Roberts 0:d88677306896 414 int err_;
Wayne Roberts 0:d88677306896 415 unsigned abserr;
Wayne Roberts 0:d88677306896 416 thisMeas = (rxIrqAt - attemptOffset) - lastRxIrqAt;
Wayne Roberts 0:d88677306896 417 err_ = thisMeas - TX_INTERVAL_US;
Wayne Roberts 0:d88677306896 418 if (TX_INTERVAL_US > thisMeas)
Wayne Roberts 0:d88677306896 419 abserr = TX_INTERVAL_US - thisMeas;
Wayne Roberts 0:d88677306896 420 else
Wayne Roberts 0:d88677306896 421 abserr = thisMeas - TX_INTERVAL_US;
Wayne Roberts 0:d88677306896 422
Wayne Roberts 0:d88677306896 423 pc.printf(" this:%llu err_:%d ", thisMeas, err_);
Wayne Roberts 0:d88677306896 424 if (abserr < MEASURED_MAX_ERR) {
Wayne Roberts 0:d88677306896 425 int rxPrecedency = 0;
Wayne Roberts 0:d88677306896 426 unsigned sinceRxDone, _us_;
Wayne Roberts 0:d88677306896 427 unsigned pktDur = Radio::lora_toa_us(size);
Wayne Roberts 0:d88677306896 428 us_timestamp_t firstAttemptStartedAt = (rxIrqAt - attemptOffset) - pktDur;
Wayne Roberts 0:d88677306896 429
Wayne Roberts 0:d88677306896 430 measuredInterval = thisMeas;
Wayne Roberts 0:d88677306896 431 _us_ = measuredInterval;
Wayne Roberts 0:d88677306896 432 pc.printf("->%llu ", measuredInterval);
Wayne Roberts 0:d88677306896 433
Wayne Roberts 0:d88677306896 434 if (rxStartAt != 0) {
Wayne Roberts 0:d88677306896 435 rxPrecedency = firstAttemptStartedAt - rxStartAt;
Wayne Roberts 0:d88677306896 436 if (rxPrecedency > 0)
Wayne Roberts 0:d88677306896 437 _us_ += rxPrecedency / 2;
Wayne Roberts 0:d88677306896 438 else
Wayne Roberts 0:d88677306896 439 _us_ += rxPrecedency;
Wayne Roberts 0:d88677306896 440 }
Wayne Roberts 0:d88677306896 441
Wayne Roberts 0:d88677306896 442 _us_ -= rxStartup_us;
Wayne Roberts 0:d88677306896 443 _us_ -= retryInterval_us; // TODO
Wayne Roberts 0:d88677306896 444 mbedTimeout_nextRx.detach();
Wayne Roberts 0:d88677306896 445 sinceRxDone = Radio::lpt.read_us() - rxIrqAt;
Wayne Roberts 0:d88677306896 446 mbedTimeout_nextRx.attach_us(nextRxStartCB, _us_ - sinceRxDone);
Wayne Roberts 0:d88677306896 447 pc.printf("nextRx:%u ao%u rxPrecedency:%d pktDur%u ri%u sinceRxDone%u ", _us_ - sinceRxDone, attemptOffset, rxPrecedency, pktDur, retryInterval_us, sinceRxDone);
Wayne Roberts 0:d88677306896 448
Wayne Roberts 0:d88677306896 449 if (measuredIntervalSaved == 0)
Wayne Roberts 0:d88677306896 450 measuredIntervalSaved = measuredInterval;
Wayne Roberts 0:d88677306896 451 else {
Wayne Roberts 0:d88677306896 452 measuredIntervalSaved += measuredInterval;
Wayne Roberts 0:d88677306896 453 measuredIntervalSaved /= 2;
Wayne Roberts 0:d88677306896 454 }
Wayne Roberts 0:d88677306896 455
Wayne Roberts 0:d88677306896 456 rxStartAt = 0;
Wayne Roberts 0:d88677306896 457 } else
Wayne Roberts 0:d88677306896 458 pc.printf("\e[31mtoo-much-err\e[0m\r\n");
Wayne Roberts 0:d88677306896 459
Wayne Roberts 0:d88677306896 460 pc.printf("\r\n");
Wayne Roberts 0:d88677306896 461 } // ..if (lastRxIrqAt != 0)
Wayne Roberts 0:d88677306896 462
Wayne Roberts 0:d88677306896 463 lastRxIrqAt = rxIrqAt - attemptOffset;
Wayne Roberts 0:d88677306896 464
Wayne Roberts 0:d88677306896 465 pc.printf("\e[0m");
Wayne Roberts 0:d88677306896 466 } // ..if (f.bits.fragNum == 0)
Wayne Roberts 0:d88677306896 467
Wayne Roberts 0:d88677306896 468 } // ..if (state == STATE_GET_REQ)
Wayne Roberts 0:d88677306896 469 #ifndef UNIT_LAST
Wayne Roberts 0:d88677306896 470 else if (state == STATE_ACK_WAITING) {
Wayne Roberts 0:d88677306896 471
Wayne Roberts 0:d88677306896 472 if (Radio::radio.rx_buf[0] == UNIT_ID+1) {
Wayne Roberts 0:d88677306896 473 pkt_flags_t f;
Wayne Roberts 0:d88677306896 474 f.octet = Radio::radio.tx_buf[1];
Wayne Roberts 0:d88677306896 475
Wayne Roberts 0:d88677306896 476 tickerRetry.detach();
Wayne Roberts 0:d88677306896 477 forwardLenAckd = forwardLenTransmitted;
Wayne Roberts 0:d88677306896 478 if (f.bits.fragLast) {
Wayne Roberts 0:d88677306896 479 pc.printf("ackOk-last ");
Wayne Roberts 0:d88677306896 480 #if (UNIT_ID == 0x00)
Wayne Roberts 0:d88677306896 481 pc.printf("->SLEEP ");
Wayne Roberts 0:d88677306896 482 flags._sleep_ = 1;
Wayne Roberts 0:d88677306896 483 Radio::Sleep();
Wayne Roberts 0:d88677306896 484 #else
Wayne Roberts 0:d88677306896 485 setupNext();
Wayne Roberts 0:d88677306896 486 #endif /* UNIT_ID != 0x00 */
Wayne Roberts 0:d88677306896 487 } else {
Wayne Roberts 0:d88677306896 488 f.bits.fragNum++;
Wayne Roberts 0:d88677306896 489 f.bits.attempt = 0;
Wayne Roberts 0:d88677306896 490 Radio::radio.tx_buf[1] = f.octet;
Wayne Roberts 0:d88677306896 491 _tx_forward();
Wayne Roberts 0:d88677306896 492 pc.printf("ackOk->%u ", f.bits.fragNum);
Wayne Roberts 0:d88677306896 493 }
Wayne Roberts 0:d88677306896 494 } else
Wayne Roberts 0:d88677306896 495 pc.printf("ack from different ID %02x\r\n", Radio::radio.rx_buf[0]);
Wayne Roberts 0:d88677306896 496 }
Wayne Roberts 0:d88677306896 497 #endif /* UNIT_LAST */
Wayne Roberts 0:d88677306896 498
Wayne Roberts 0:d88677306896 499 pc.printf("\r\n");
Wayne Roberts 0:d88677306896 500 } // ..rxDoneCB()
Wayne Roberts 0:d88677306896 501
Wayne Roberts 0:d88677306896 502 #if (UNIT_ID == 0x00) && !defined(UNIT_LAST)
Wayne Roberts 0:d88677306896 503 LowPowerTicker lpTicker;
Wayne Roberts 0:d88677306896 504
Wayne Roberts 0:d88677306896 505 void tx_ticker_cb(void) {
Wayne Roberts 0:d88677306896 506 unsigned c;
Wayne Roberts 0:d88677306896 507 pkt_flags_t f;
Wayne Roberts 0:d88677306896 508 message_t* mptr;
Wayne Roberts 0:d88677306896 509
Wayne Roberts 0:d88677306896 510 tickerRetry.attach_us(retry_cb, retryInterval_us);
Wayne Roberts 0:d88677306896 511
Wayne Roberts 0:d88677306896 512 f.bits.attempt = 0;
Wayne Roberts 0:d88677306896 513 f.bits.fragNum = 0;
Wayne Roberts 0:d88677306896 514 f.bits.fragLast = 1;
Wayne Roberts 0:d88677306896 515
Wayne Roberts 1:7dbf0926e146 516 Radio::Standby();
Wayne Roberts 1:7dbf0926e146 517
Wayne Roberts 0:d88677306896 518 txCurs = 0;
Wayne Roberts 0:d88677306896 519 Radio::radio.tx_buf[txCurs++] = UNIT_ID;
Wayne Roberts 0:d88677306896 520 Radio::radio.tx_buf[txCurs++] = f.octet;
Wayne Roberts 0:d88677306896 521
Wayne Roberts 0:d88677306896 522 mptr = (message_t*)(Radio::radio.tx_buf + txCurs);
Wayne Roberts 0:d88677306896 523 mptr->unit_id = UNIT_ID;
Wayne Roberts 0:d88677306896 524 mptr->flags = 0x00;
Wayne Roberts 0:d88677306896 525 mptr->sample = ain.read_u16();
Wayne Roberts 0:d88677306896 526 #ifdef N_SMP
Wayne Roberts 0:d88677306896 527 for (c = 0; c < N_SMP; c++)
Wayne Roberts 0:d88677306896 528 mptr->samples[c] = ain.read_u16();
Wayne Roberts 0:d88677306896 529 #endif
Wayne Roberts 0:d88677306896 530 txCurs += sizeof(message_t);
Wayne Roberts 0:d88677306896 531
Wayne Roberts 0:d88677306896 532 c = crc16(Radio::radio.tx_buf, txCurs);
Wayne Roberts 0:d88677306896 533 Radio::radio.tx_buf[txCurs++] = c >> 8;
Wayne Roberts 0:d88677306896 534 Radio::radio.tx_buf[txCurs++] = c;
Wayne Roberts 0:d88677306896 535
Wayne Roberts 0:d88677306896 536 Radio::Send(txCurs, 0, 0, 0);
Wayne Roberts 1:7dbf0926e146 537 txStartAt = Radio::lpt.read_us();
Wayne Roberts 0:d88677306896 538 state = STATE_ACK_WAITING;
Wayne Roberts 1:7dbf0926e146 539 pc.printf("tx_ticker_cb:%u\r\n", mptr->sample);
Wayne Roberts 0:d88677306896 540 flags._sleep_ = 0;
Wayne Roberts 0:d88677306896 541 }
Wayne Roberts 0:d88677306896 542 #endif /* UNIT_ID == 0x00 */
Wayne Roberts 0:d88677306896 543
Wayne Roberts 1:7dbf0926e146 544
Wayne Roberts 0:d88677306896 545 void uart_rx()
Wayne Roberts 0:d88677306896 546 {
Wayne Roberts 0:d88677306896 547 char str[32];
Wayne Roberts 0:d88677306896 548
Wayne Roberts 0:d88677306896 549 char ch = pc.getc();
Wayne Roberts 0:d88677306896 550 switch (ch) {
Wayne Roberts 0:d88677306896 551 case '+':
Wayne Roberts 0:d88677306896 552 rxStartup_us += 500;
Wayne Roberts 0:d88677306896 553 pc.printf("rxStartup_us:%u\r\n", rxStartup_us);
Wayne Roberts 0:d88677306896 554 break;
Wayne Roberts 0:d88677306896 555 case '-':
Wayne Roberts 0:d88677306896 556 if (rxStartup_us > 500)
Wayne Roberts 0:d88677306896 557 rxStartup_us -= 500;
Wayne Roberts 0:d88677306896 558 pc.printf("rxStartup_us:%u\r\n", rxStartup_us);
Wayne Roberts 0:d88677306896 559 break;
Wayne Roberts 0:d88677306896 560 case '.':
Wayne Roberts 1:7dbf0926e146 561 //Radio::PrintStatus();
Wayne Roberts 0:d88677306896 562 printf("UNIT_ID:%02x ", UNIT_ID);
Wayne Roberts 0:d88677306896 563 printf(" measuredInterval:%llu\r\n", measuredInterval);
Wayne Roberts 0:d88677306896 564 stateToString(state, str);
Wayne Roberts 0:d88677306896 565 printf("_sleep_:%u %s\r\n", flags._sleep_, str);
Wayne Roberts 0:d88677306896 566 break;
Wayne Roberts 0:d88677306896 567 case 'r':
Wayne Roberts 0:d88677306896 568 flags.run ^= 1;
Wayne Roberts 0:d88677306896 569 printf("\r\nrun %u\r\n", flags.run);
Wayne Roberts 0:d88677306896 570 if (flags.run == 0) {
Wayne Roberts 0:d88677306896 571 #ifndef UNIT_LAST
Wayne Roberts 0:d88677306896 572 tickerRetry.detach();
Wayne Roberts 0:d88677306896 573 #endif /* !UNIT_LAST */
Wayne Roberts 0:d88677306896 574 mbedTImeout_forwarder.detach();
Wayne Roberts 0:d88677306896 575 mbedTimeout_nextRx.detach();
Wayne Roberts 0:d88677306896 576
Wayne Roberts 0:d88677306896 577 flags._sleep_ = 1;
Wayne Roberts 0:d88677306896 578 Radio::Sleep();
Wayne Roberts 0:d88677306896 579 }
Wayne Roberts 0:d88677306896 580 break;
Wayne Roberts 0:d88677306896 581 } // ..switch (ch)
Wayne Roberts 0:d88677306896 582 }
Wayne Roberts 0:d88677306896 583
Wayne Roberts 1:7dbf0926e146 584 RadioEvents_t rev = { 0 };
Wayne Roberts 1:7dbf0926e146 585
Wayne Roberts 0:d88677306896 586 int main()
Wayne Roberts 0:d88677306896 587 {
Wayne Roberts 0:d88677306896 588 flags.run = 1;
Wayne Roberts 0:d88677306896 589 pc.baud(115200);
Wayne Roberts 0:d88677306896 590 pc.printf("\r\nreset\r\n");
Wayne Roberts 1:7dbf0926e146 591
Wayne Roberts 1:7dbf0926e146 592 rev.TxDone_botHalf = txDoneCB;
Wayne Roberts 1:7dbf0926e146 593 rev.RxDone = rxDoneCB;
Wayne Roberts 1:7dbf0926e146 594 Radio::Init(&rev);
Wayne Roberts 0:d88677306896 595
Wayne Roberts 1:7dbf0926e146 596 Radio::SetChannel(CF_MHZ * 1000000);
Wayne Roberts 1:7dbf0926e146 597 Radio::LoRaModemConfig(500, SPREADING_FACTOR, 1);
Wayne Roberts 1:7dbf0926e146 598 Radio::LoRaPacketConfig(8, false, true, false); // preambleLen, fixLen, crcOn, invIQ
Wayne Roberts 1:7dbf0926e146 599
Wayne Roberts 1:7dbf0926e146 600 Radio::set_tx_dbm(17);
Wayne Roberts 0:d88677306896 601
Wayne Roberts 0:d88677306896 602 /* max TX length + turnaround + ACK length */
Wayne Roberts 0:d88677306896 603 retryInterval_us = Radio::lora_toa_us(MAX_TX_LENGTH) + TXRX_PADDING_US + Radio::lora_toa_us(1);
Wayne Roberts 0:d88677306896 604 #ifdef UNIT_LAST
Wayne Roberts 0:d88677306896 605 pc.printf("LAST ");
Wayne Roberts 0:d88677306896 606 #endif
Wayne Roberts 0:d88677306896 607 pc.printf("UNIT_ID:%02x retryInterval_us:%u\r\n", UNIT_ID, retryInterval_us);
Wayne Roberts 0:d88677306896 608
Wayne Roberts 0:d88677306896 609 flags._sleep_ = 0;
Wayne Roberts 0:d88677306896 610 state = STATE_NONE;
Wayne Roberts 0:d88677306896 611
Wayne Roberts 0:d88677306896 612 #if (UNIT_ID == 0x00) && !defined(UNIT_LAST)
Wayne Roberts 0:d88677306896 613 lpTicker.attach_us(tx_ticker_cb, TX_INTERVAL_US);
Wayne Roberts 0:d88677306896 614 #else
Wayne Roberts 1:7dbf0926e146 615 //Radio::PrintStatus();
Wayne Roberts 0:d88677306896 616
Wayne Roberts 0:d88677306896 617 setupNext();
Wayne Roberts 0:d88677306896 618
Wayne Roberts 0:d88677306896 619 measuredInterval = 0;
Wayne Roberts 0:d88677306896 620 lastRxIrqAt = 0;
Wayne Roberts 0:d88677306896 621 measuredIntervalSaved = 0;
Wayne Roberts 0:d88677306896 622 #endif /* UNIT_ID != 0x00 */
Wayne Roberts 0:d88677306896 623
Wayne Roberts 0:d88677306896 624 if (sleep_manager_can_deep_sleep())
Wayne Roberts 0:d88677306896 625 sleep_manager_lock_deep_sleep(); // prevent deep sleep
Wayne Roberts 0:d88677306896 626
Wayne Roberts 0:d88677306896 627 for (;;) {
Wayne Roberts 0:d88677306896 628 if (pc.readable()) {
Wayne Roberts 0:d88677306896 629 uart_rx();
Wayne Roberts 0:d88677306896 630 }
Wayne Roberts 0:d88677306896 631
Wayne Roberts 0:d88677306896 632 if (flags._sleep_ == 0) {
Wayne Roberts 0:d88677306896 633 Radio::service();
Wayne Roberts 0:d88677306896 634 } else
Wayne Roberts 0:d88677306896 635 sleep_manager_sleep_auto();;
Wayne Roberts 0:d88677306896 636
Wayne Roberts 0:d88677306896 637 } // ..for (;;)
Wayne Roberts 0:d88677306896 638 }
Wayne Roberts 0:d88677306896 639