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