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:
Fri Dec 14 14:41:38 2018 -0800
Revision:
4:f272bf72893a
Parent:
3:a78a70af3403
Child:
5:62c9ddaa5ea6
move analog read from isr to main loop

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