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 Sep 16 11:19:32 2019 -0700
Revision:
6:63981d2f88a7
Parent:
5:62c9ddaa5ea6
remove radio driver

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