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:
Sun Nov 25 17:13:06 2018 -0800
Revision:
3:a78a70af3403
Parent:
2:534be88a25dc
Child:
4:f272bf72893a
add PA disable option from user-button

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