unlimited packet length example for sx1272 or sx1276

Dependencies:   SX127x

operating

user button on MCU board toggles between receive operation on radio and transmit. (Latching PTT). Look at serial terminal at 9600 to see operation. User button is pressed once to start transmit, and again to end transmit: it doesnt need to be held down during TX.

example payload

The example payload is a continuously incrementing byte, with zero at start of packet.
End of packet is detected by four consecutive bytes which dont increment with expected value: background noise, this indicates transmitter has finished. This serves only as an example, because some other method would likely be needed in an application, such as unique data indicating end, or the length sent at begin of packet.

flow control

FifoThreshold is used for transmit flow control. With fifo is below threshold, bytes are send to the radio's fifo. While fifo is above threshold, nothing is sent until the fifo threshold pin returns low. AKA FifoLevel pin.

On receive, the packet reception is initialized by SyncAddress pin going high, indicating start of packet. Bytes are read from FIFO when the FifoEmpty pin is low.

The packet buffer (AKA FIFO) in sx127x is only 64 bytes, meaning the maximum time between FifoFull and FifoEmpty would be 512 bit periods. This needs to be considered: the MCU latency of servicing FifoLevel, FifoEmpty pins during packet, otherwise empty byte would be sent on transmit or byte missed on receiver.

FSK reception

The rxTrigger is used on preamble to enable start-of-frame detection, aka sync word. When end of packet is detected, the receiver is restarted. In this case, restarted with PLL when AFC is used, or without PLL when AFC not enabled.

The serial terminal will show when packet reception starts, and when there are incorrect bytes received over the air. This will always happen and end of packet for this example.

Committer:
dudmuck
Date:
Tue Sep 14 22:19:57 2021 +0000
Revision:
0:df5ce1bc5036
commit initial

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dudmuck 0:df5ce1bc5036 1 #include "mbed.h"
dudmuck 0:df5ce1bc5036 2 #include "sx127x_fsk.h"
dudmuck 0:df5ce1bc5036 3
dudmuck 0:df5ce1bc5036 4 using namespace std::chrono;
dudmuck 0:df5ce1bc5036 5
dudmuck 0:df5ce1bc5036 6 #define FSK_BIT_RATE 10000
dudmuck 0:df5ce1bc5036 7 #define TX_FREQ_DEVIATION_HZ 20000
dudmuck 0:df5ce1bc5036 8 #define RX_BW 30000
dudmuck 0:df5ce1bc5036 9 #define RX_BW_AFC 30000
dudmuck 0:df5ce1bc5036 10 #define START_OF_FRAME 0xd42d
dudmuck 0:df5ce1bc5036 11 #define RADIO_FREQUENCY_MHZ 915.0
dudmuck 0:df5ce1bc5036 12 //#define ENABLE_AFC
dudmuck 0:df5ce1bc5036 13
dudmuck 0:df5ce1bc5036 14 SPI spi(D11, D12, D13); // mosi, miso, sclk
dudmuck 0:df5ce1bc5036 15 // dio0, dio1, nss, spi, rst
dudmuck 0:df5ce1bc5036 16 SX127x radio( D2, D3, D10, spi, A0); // sx127[62] arduino shield
dudmuck 0:df5ce1bc5036 17 SX127x_fsk fsk(radio);
dudmuck 0:df5ce1bc5036 18 DigitalInOut rfsw(A4);
dudmuck 0:df5ce1bc5036 19
dudmuck 0:df5ce1bc5036 20 DigitalIn dio1(D3); // for FifoLevel
dudmuck 0:df5ce1bc5036 21 InterruptIn dio2(D4); // for syncAddress
dudmuck 0:df5ce1bc5036 22 DigitalIn dio3(D5); // for FifoEmpty
dudmuck 0:df5ce1bc5036 23
dudmuck 0:df5ce1bc5036 24 DigitalIn button(/*USER_BUTTON*/ BUTTON1);
dudmuck 0:df5ce1bc5036 25 bool button_pressed;
dudmuck 0:df5ce1bc5036 26 #define BUTTON_DEBOUNCE_MS 10
dudmuck 0:df5ce1bc5036 27 bool txing;
dudmuck 0:df5ce1bc5036 28 bool end_tx;
dudmuck 0:df5ce1bc5036 29 bool rxSync;
dudmuck 0:df5ce1bc5036 30
dudmuck 0:df5ce1bc5036 31 typedef enum {
dudmuck 0:df5ce1bc5036 32 SHIELD_TYPE_NONE = 0,
dudmuck 0:df5ce1bc5036 33 SHIELD_TYPE_LAS,
dudmuck 0:df5ce1bc5036 34 SHIELD_TYPE_MAS,
dudmuck 0:df5ce1bc5036 35 } shield_type_e;
dudmuck 0:df5ce1bc5036 36 shield_type_e shield_type;
dudmuck 0:df5ce1bc5036 37
dudmuck 0:df5ce1bc5036 38 void rfsw_callback()
dudmuck 0:df5ce1bc5036 39 {
dudmuck 0:df5ce1bc5036 40 if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER)
dudmuck 0:df5ce1bc5036 41 rfsw = 1;
dudmuck 0:df5ce1bc5036 42 else
dudmuck 0:df5ce1bc5036 43 rfsw = 0;
dudmuck 0:df5ce1bc5036 44 }
dudmuck 0:df5ce1bc5036 45
dudmuck 0:df5ce1bc5036 46 void get_rf_board_type()
dudmuck 0:df5ce1bc5036 47 {
dudmuck 0:df5ce1bc5036 48 rfsw.input();
dudmuck 0:df5ce1bc5036 49 if (rfsw.read()) {
dudmuck 0:df5ce1bc5036 50 shield_type = SHIELD_TYPE_LAS;
dudmuck 0:df5ce1bc5036 51 printf("LAS\r\n");
dudmuck 0:df5ce1bc5036 52 } else {
dudmuck 0:df5ce1bc5036 53 shield_type = SHIELD_TYPE_MAS;
dudmuck 0:df5ce1bc5036 54 printf("MAS\r\n");
dudmuck 0:df5ce1bc5036 55 }
dudmuck 0:df5ce1bc5036 56
dudmuck 0:df5ce1bc5036 57 rfsw.output();
dudmuck 0:df5ce1bc5036 58 }
dudmuck 0:df5ce1bc5036 59
dudmuck 0:df5ce1bc5036 60 void ocp(uint8_t ma)
dudmuck 0:df5ce1bc5036 61 {
dudmuck 0:df5ce1bc5036 62 if (ma < 130)
dudmuck 0:df5ce1bc5036 63 radio.RegOcp.bits.OcpTrim = (ma - 45) / 5;
dudmuck 0:df5ce1bc5036 64 else
dudmuck 0:df5ce1bc5036 65 radio.RegOcp.bits.OcpTrim = (ma + 30) / 10;
dudmuck 0:df5ce1bc5036 66 radio.write_reg(REG_OCP, radio.RegOcp.octet);
dudmuck 0:df5ce1bc5036 67
dudmuck 0:df5ce1bc5036 68 radio.RegOcp.octet = radio.read_reg(REG_OCP);
dudmuck 0:df5ce1bc5036 69 if (radio.RegOcp.bits.OcpTrim < 16)
dudmuck 0:df5ce1bc5036 70 ma = 45 + (5 * radio.RegOcp.bits.OcpTrim);
dudmuck 0:df5ce1bc5036 71 else if (radio.RegOcp.bits.OcpTrim < 28)
dudmuck 0:df5ce1bc5036 72 ma = (10 * radio.RegOcp.bits.OcpTrim) - 30;
dudmuck 0:df5ce1bc5036 73 else
dudmuck 0:df5ce1bc5036 74 ma = 240;
dudmuck 0:df5ce1bc5036 75 }
dudmuck 0:df5ce1bc5036 76
dudmuck 0:df5ce1bc5036 77 void
dudmuck 0:df5ce1bc5036 78 set_tx_dbm(int8_t dbm)
dudmuck 0:df5ce1bc5036 79 {
dudmuck 0:df5ce1bc5036 80 RegPdsTrim1_t pds_trim;
dudmuck 0:df5ce1bc5036 81 uint8_t v, adr, pa_test_adr;
dudmuck 0:df5ce1bc5036 82
dudmuck 0:df5ce1bc5036 83 if (radio.type == SX1276) {
dudmuck 0:df5ce1bc5036 84 adr = REG_PDSTRIM1_SX1276;
dudmuck 0:df5ce1bc5036 85 pa_test_adr = REG_PATEST_SX1276;
dudmuck 0:df5ce1bc5036 86 } else {
dudmuck 0:df5ce1bc5036 87 adr = REG_PDSTRIM1_SX1272;
dudmuck 0:df5ce1bc5036 88 pa_test_adr = REG_PATEST_SX1272;
dudmuck 0:df5ce1bc5036 89 }
dudmuck 0:df5ce1bc5036 90
dudmuck 0:df5ce1bc5036 91 v = radio.read_reg(pa_test_adr);
dudmuck 0:df5ce1bc5036 92 /*if (dbm == PA_OFF_DBM) {
dudmuck 0:df5ce1bc5036 93 // for bench testing: prevent overloading receiving station (very low TX power)
dudmuck 0:df5ce1bc5036 94 v &= ~0x20; // turn off pu_regpa_n: disable PA
dudmuck 0:df5ce1bc5036 95 radio.write_reg(pa_test_adr, v);
dudmuck 0:df5ce1bc5036 96 return;
dudmuck 0:df5ce1bc5036 97 } else if ((v & 0x20) == 0) {
dudmuck 0:df5ce1bc5036 98 v |= 0x20; // turn on pu_regpa_n: enable PA
dudmuck 0:df5ce1bc5036 99 radio.write_reg(pa_test_adr, v);
dudmuck 0:df5ce1bc5036 100 }*/
dudmuck 0:df5ce1bc5036 101
dudmuck 0:df5ce1bc5036 102 pds_trim.octet = radio.read_reg(adr);
dudmuck 0:df5ce1bc5036 103
dudmuck 0:df5ce1bc5036 104 if (shield_type == SHIELD_TYPE_LAS)
dudmuck 0:df5ce1bc5036 105 radio.RegPaConfig.bits.PaSelect = 1;
dudmuck 0:df5ce1bc5036 106 else
dudmuck 0:df5ce1bc5036 107 radio.RegPaConfig.bits.PaSelect = 0;
dudmuck 0:df5ce1bc5036 108
dudmuck 0:df5ce1bc5036 109 if (radio.RegPaConfig.bits.PaSelect) {
dudmuck 0:df5ce1bc5036 110 /* PABOOST used: +2dbm to +17, or +20 */
dudmuck 0:df5ce1bc5036 111 if (dbm > 17) {
dudmuck 0:df5ce1bc5036 112 if (dbm > 20)
dudmuck 0:df5ce1bc5036 113 dbm = 20;
dudmuck 0:df5ce1bc5036 114 dbm -= 3;
dudmuck 0:df5ce1bc5036 115 pds_trim.bits.prog_txdac = 7;
dudmuck 0:df5ce1bc5036 116 radio.write_reg(adr, pds_trim.octet);
dudmuck 0:df5ce1bc5036 117 ocp(150);
dudmuck 0:df5ce1bc5036 118 } else
dudmuck 0:df5ce1bc5036 119 ocp(120);
dudmuck 0:df5ce1bc5036 120
dudmuck 0:df5ce1bc5036 121 if (dbm > 1)
dudmuck 0:df5ce1bc5036 122 radio.RegPaConfig.bits.OutputPower = dbm - 2;
dudmuck 0:df5ce1bc5036 123 } else {
dudmuck 0:df5ce1bc5036 124 /* RFO used: -1 to +14dbm */
dudmuck 0:df5ce1bc5036 125 ocp(80);
dudmuck 0:df5ce1bc5036 126 if (dbm < 15)
dudmuck 0:df5ce1bc5036 127 radio.RegPaConfig.bits.OutputPower = dbm + 1;
dudmuck 0:df5ce1bc5036 128 }
dudmuck 0:df5ce1bc5036 129 radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
dudmuck 0:df5ce1bc5036 130
dudmuck 0:df5ce1bc5036 131 radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
dudmuck 0:df5ce1bc5036 132 if (radio.RegPaConfig.bits.PaSelect) {
dudmuck 0:df5ce1bc5036 133 dbm = radio.RegPaConfig.bits.OutputPower + pds_trim.bits.prog_txdac - 2;
dudmuck 0:df5ce1bc5036 134 } else {
dudmuck 0:df5ce1bc5036 135 dbm = radio.RegPaConfig.bits.OutputPower - 1;
dudmuck 0:df5ce1bc5036 136 }
dudmuck 0:df5ce1bc5036 137 }
dudmuck 0:df5ce1bc5036 138
dudmuck 0:df5ce1bc5036 139 void start_receive()
dudmuck 0:df5ce1bc5036 140 {
dudmuck 0:df5ce1bc5036 141 fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);
dudmuck 0:df5ce1bc5036 142 fsk.RegRxConfig.bits.RxTrigger = 6; // trigger receiver on preamble detect
dudmuck 0:df5ce1bc5036 143 fsk.RegRxConfig.bits.AgcAutoOn = 1; // radio controls its LNA
dudmuck 0:df5ce1bc5036 144 #ifdef ENABLE_AFC
dudmuck 0:df5ce1bc5036 145 fsk.RegRxConfig.bits.AfcAutoOn = 1;
dudmuck 0:df5ce1bc5036 146 fsk.RegRxConfig.bits.RestartRxWithPllLock = 1;
dudmuck 0:df5ce1bc5036 147 #endif /* ENABLE_AFC */
dudmuck 0:df5ce1bc5036 148 radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
dudmuck 0:df5ce1bc5036 149
dudmuck 0:df5ce1bc5036 150 #ifdef ENABLE_AFC
dudmuck 0:df5ce1bc5036 151 fsk.RegAfcFei.octet = radio.read_reg(REG_FSK_AFCFEI);
dudmuck 0:df5ce1bc5036 152 fsk.RegAfcFei.bits.AfcAutoClearOn = 1;
dudmuck 0:df5ce1bc5036 153 fsk.RegAfcFei.bits.AfcClear = 1;
dudmuck 0:df5ce1bc5036 154 radio.write_reg(REG_FSK_AFCFEI, fsk.RegAfcFei.octet);
dudmuck 0:df5ce1bc5036 155 #endif /* ENABLE_AFC */
dudmuck 0:df5ce1bc5036 156
dudmuck 0:df5ce1bc5036 157 radio.set_opmode(RF_OPMODE_RECEIVER);
dudmuck 0:df5ce1bc5036 158 }
dudmuck 0:df5ce1bc5036 159
dudmuck 0:df5ce1bc5036 160 #define FIRST_PAYLOAD_BYTE 0
dudmuck 0:df5ce1bc5036 161 uint8_t expected_rx;
dudmuck 0:df5ce1bc5036 162 uint8_t rx_err_cnt;
dudmuck 0:df5ce1bc5036 163 unsigned rx_bytes_ok;
dudmuck 0:df5ce1bc5036 164
dudmuck 0:df5ce1bc5036 165 void dio2_callback()
dudmuck 0:df5ce1bc5036 166 {
dudmuck 0:df5ce1bc5036 167 if (!txing) {
dudmuck 0:df5ce1bc5036 168 expected_rx = FIRST_PAYLOAD_BYTE;
dudmuck 0:df5ce1bc5036 169 rxSync = true;
dudmuck 0:df5ce1bc5036 170 rx_err_cnt = 0;
dudmuck 0:df5ce1bc5036 171 rx_bytes_ok = 0;
dudmuck 0:df5ce1bc5036 172 } else {
dudmuck 0:df5ce1bc5036 173 // fifoFull in TX
dudmuck 0:df5ce1bc5036 174 }
dudmuck 0:df5ce1bc5036 175
dudmuck 0:df5ce1bc5036 176 }
dudmuck 0:df5ce1bc5036 177
dudmuck 0:df5ce1bc5036 178 /* return non-zero at end of packet detection */
dudmuck 0:df5ce1bc5036 179 int take_rx_byte(uint8_t in)
dudmuck 0:df5ce1bc5036 180 {
dudmuck 0:df5ce1bc5036 181 int ret;
dudmuck 0:df5ce1bc5036 182
dudmuck 0:df5ce1bc5036 183 if (in != expected_rx) {
dudmuck 0:df5ce1bc5036 184 printf("(got %02x, wanted %02x)\r\n", in, expected_rx);
dudmuck 0:df5ce1bc5036 185 if (++rx_err_cnt == 4)
dudmuck 0:df5ce1bc5036 186 ret = -1; // too much consecutive noise
dudmuck 0:df5ce1bc5036 187 else
dudmuck 0:df5ce1bc5036 188 ret = 0;
dudmuck 0:df5ce1bc5036 189 } else {
dudmuck 0:df5ce1bc5036 190 rx_bytes_ok++;
dudmuck 0:df5ce1bc5036 191 rx_err_cnt = 0;
dudmuck 0:df5ce1bc5036 192 ret = 0;
dudmuck 0:df5ce1bc5036 193 }
dudmuck 0:df5ce1bc5036 194
dudmuck 0:df5ce1bc5036 195 expected_rx++;
dudmuck 0:df5ce1bc5036 196
dudmuck 0:df5ce1bc5036 197 return ret;
dudmuck 0:df5ce1bc5036 198 }
dudmuck 0:df5ce1bc5036 199
dudmuck 0:df5ce1bc5036 200 uint8_t tx_byte_cnt;
dudmuck 0:df5ce1bc5036 201 uint8_t get_tx_byte()
dudmuck 0:df5ce1bc5036 202 {
dudmuck 0:df5ce1bc5036 203 return tx_byte_cnt++;
dudmuck 0:df5ce1bc5036 204 }
dudmuck 0:df5ce1bc5036 205
dudmuck 0:df5ce1bc5036 206 void start_transmit()
dudmuck 0:df5ce1bc5036 207 {
dudmuck 0:df5ce1bc5036 208 fsk.RegFifoThreshold.octet = radio.read_reg(REG_FSK_FIFOTHRESH);
dudmuck 0:df5ce1bc5036 209 fsk.RegFifoThreshold.bits.FifoThreshold = 48;
dudmuck 0:df5ce1bc5036 210 radio.write_reg(REG_FSK_FIFOTHRESH, fsk.RegFifoThreshold.octet);
dudmuck 0:df5ce1bc5036 211
dudmuck 0:df5ce1bc5036 212 tx_byte_cnt = FIRST_PAYLOAD_BYTE;
dudmuck 0:df5ce1bc5036 213 radio.set_opmode(RF_OPMODE_TRANSMITTER);
dudmuck 0:df5ce1bc5036 214 }
dudmuck 0:df5ce1bc5036 215
dudmuck 0:df5ce1bc5036 216 void end_transmit()
dudmuck 0:df5ce1bc5036 217 {
dudmuck 0:df5ce1bc5036 218 printf("wait fifoEmpty...\r\n");
dudmuck 0:df5ce1bc5036 219 while (dio3.read() == 0)
dudmuck 0:df5ce1bc5036 220 ;
dudmuck 0:df5ce1bc5036 221
dudmuck 0:df5ce1bc5036 222 radio.set_opmode(RF_OPMODE_STANDBY);
dudmuck 0:df5ce1bc5036 223 printf("tx-end\r\n");
dudmuck 0:df5ce1bc5036 224 }
dudmuck 0:df5ce1bc5036 225
dudmuck 0:df5ce1bc5036 226 int main()
dudmuck 0:df5ce1bc5036 227 {
dudmuck 0:df5ce1bc5036 228 long button_release_start = -1;
dudmuck 0:df5ce1bc5036 229
dudmuck 0:df5ce1bc5036 230
dudmuck 0:df5ce1bc5036 231 radio.rf_switch = rfsw_callback;
dudmuck 0:df5ce1bc5036 232 get_rf_board_type();
dudmuck 0:df5ce1bc5036 233 ThisThread::sleep_for(30ms); // from cold power-up, both radio and mcu started
dudmuck 0:df5ce1bc5036 234
dudmuck 0:df5ce1bc5036 235 radio.hw_reset();
dudmuck 0:df5ce1bc5036 236
dudmuck 0:df5ce1bc5036 237 if (shield_type == SHIELD_TYPE_LAS)
dudmuck 0:df5ce1bc5036 238 set_tx_dbm(13);
dudmuck 0:df5ce1bc5036 239 else
dudmuck 0:df5ce1bc5036 240 set_tx_dbm(17);
dudmuck 0:df5ce1bc5036 241
dudmuck 0:df5ce1bc5036 242 radio.set_frf_MHz(RADIO_FREQUENCY_MHZ);
dudmuck 0:df5ce1bc5036 243
dudmuck 0:df5ce1bc5036 244 fsk.enable(true);
dudmuck 0:df5ce1bc5036 245 fsk.set_tx_fdev_hz(TX_FREQ_DEVIATION_HZ);
dudmuck 0:df5ce1bc5036 246
dudmuck 0:df5ce1bc5036 247 fsk.set_bitrate(FSK_BIT_RATE);
dudmuck 0:df5ce1bc5036 248
dudmuck 0:df5ce1bc5036 249 fsk.set_rx_dcc_bw_hz(RX_BW, 0);
dudmuck 0:df5ce1bc5036 250 fsk.set_rx_dcc_bw_hz(RX_BW_AFC, 1);
dudmuck 0:df5ce1bc5036 251
dudmuck 0:df5ce1bc5036 252 fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
dudmuck 0:df5ce1bc5036 253 fsk.RegSyncConfig.bits.SyncSize = 2 - 1;
dudmuck 0:df5ce1bc5036 254 radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
dudmuck 0:df5ce1bc5036 255 radio.write_reg(REG_FSK_SYNCVALUE1, 0xd4);
dudmuck 0:df5ce1bc5036 256 radio.write_reg(REG_FSK_SYNCVALUE1, 0x2d);
dudmuck 0:df5ce1bc5036 257
dudmuck 0:df5ce1bc5036 258 // dio3 to FifoEmpty
dudmuck 0:df5ce1bc5036 259 // dio2 to syncAddress
dudmuck 0:df5ce1bc5036 260 // dio1 to FifoLevel
dudmuck 0:df5ce1bc5036 261 radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
dudmuck 0:df5ce1bc5036 262 radio.RegDioMapping1.bits.Dio3Mapping = 3; //
dudmuck 0:df5ce1bc5036 263 radio.RegDioMapping1.bits.Dio2Mapping = 3; //
dudmuck 0:df5ce1bc5036 264 radio.RegDioMapping1.bits.Dio1Mapping = 0; //
dudmuck 0:df5ce1bc5036 265 radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
dudmuck 0:df5ce1bc5036 266 dio2.rise(dio2_callback);
dudmuck 0:df5ce1bc5036 267
dudmuck 0:df5ce1bc5036 268 fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);
dudmuck 0:df5ce1bc5036 269 fsk.RegPktConfig1.bits.PacketFormatVariable = 0;
dudmuck 0:df5ce1bc5036 270 radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
dudmuck 0:df5ce1bc5036 271
dudmuck 0:df5ce1bc5036 272 // unlimited payload-length operation
dudmuck 0:df5ce1bc5036 273 fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
dudmuck 0:df5ce1bc5036 274 fsk.RegPktConfig2.bits.PayloadLength = 0;
dudmuck 0:df5ce1bc5036 275 radio.write_u16(REG_FSK_PACKETCONFIG2, fsk.RegPktConfig2.word);
dudmuck 0:df5ce1bc5036 276
dudmuck 0:df5ce1bc5036 277 fsk.RegPreambleDetect.octet = radio.read_reg(REG_FSK_PREAMBLEDETECT);
dudmuck 0:df5ce1bc5036 278 fsk.RegPreambleDetect.bits.PreambleDetectorTol = 10;
dudmuck 0:df5ce1bc5036 279 fsk.RegPreambleDetect.bits.PreambleDetectorSize = 1;
dudmuck 0:df5ce1bc5036 280 fsk.RegPreambleDetect.bits.PreambleDetectorOn = 1;
dudmuck 0:df5ce1bc5036 281 radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet);
dudmuck 0:df5ce1bc5036 282
dudmuck 0:df5ce1bc5036 283 //printf("preamblesize: %02x ", radio.read_reg(REG_FSK_PREAMBLEMSB));
dudmuck 0:df5ce1bc5036 284 //printf("%02x\r\n", radio.read_reg(REG_FSK_PREAMBLELSB));
dudmuck 0:df5ce1bc5036 285 start_receive();
dudmuck 0:df5ce1bc5036 286
dudmuck 0:df5ce1bc5036 287 while (true) {
dudmuck 0:df5ce1bc5036 288 if (button_pressed) {
dudmuck 0:df5ce1bc5036 289 if (button.read()) {
dudmuck 0:df5ce1bc5036 290 // button released
dudmuck 0:df5ce1bc5036 291 button_pressed = false;
dudmuck 0:df5ce1bc5036 292 auto now_tp = time_point_cast<milliseconds>(Kernel::Clock::now());
dudmuck 0:df5ce1bc5036 293 button_release_start = now_tp.time_since_epoch().count();
dudmuck 0:df5ce1bc5036 294 }
dudmuck 0:df5ce1bc5036 295 } else {
dudmuck 0:df5ce1bc5036 296 if (!button.read()) {
dudmuck 0:df5ce1bc5036 297 // button pressed
dudmuck 0:df5ce1bc5036 298 button_pressed = true;
dudmuck 0:df5ce1bc5036 299 button_release_start = -1;
dudmuck 0:df5ce1bc5036 300 }
dudmuck 0:df5ce1bc5036 301 }
dudmuck 0:df5ce1bc5036 302
dudmuck 0:df5ce1bc5036 303 if (button_release_start != -1) {
dudmuck 0:df5ce1bc5036 304 // debounce button
dudmuck 0:df5ce1bc5036 305 auto now_tp = time_point_cast<milliseconds>(Kernel::Clock::now());
dudmuck 0:df5ce1bc5036 306 long now_ms = now_tp.time_since_epoch().count();
dudmuck 0:df5ce1bc5036 307 if ((now_ms - button_release_start) > BUTTON_DEBOUNCE_MS) {
dudmuck 0:df5ce1bc5036 308 // button released sufficiently long enough
dudmuck 0:df5ce1bc5036 309 button_release_start = -1;
dudmuck 0:df5ce1bc5036 310 if (txing) {
dudmuck 0:df5ce1bc5036 311 printf("toRX\r\n");
dudmuck 0:df5ce1bc5036 312 end_tx = true;
dudmuck 0:df5ce1bc5036 313 } else {
dudmuck 0:df5ce1bc5036 314 printf("toTX\r\n");
dudmuck 0:df5ce1bc5036 315 start_transmit();
dudmuck 0:df5ce1bc5036 316 txing = true;
dudmuck 0:df5ce1bc5036 317 }
dudmuck 0:df5ce1bc5036 318 }
dudmuck 0:df5ce1bc5036 319 }
dudmuck 0:df5ce1bc5036 320
dudmuck 0:df5ce1bc5036 321 if (txing) {
dudmuck 0:df5ce1bc5036 322 /* transmitting */
dudmuck 0:df5ce1bc5036 323 if (dio1) {
dudmuck 0:df5ce1bc5036 324 /* fifo above threshold, let the radio send it */
dudmuck 0:df5ce1bc5036 325 /* alternately, send until FifoFull */
dudmuck 0:df5ce1bc5036 326 } else {
dudmuck 0:df5ce1bc5036 327 /* fifo below threshold */
dudmuck 0:df5ce1bc5036 328 radio.m_cs = 0;
dudmuck 0:df5ce1bc5036 329 radio.m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio
dudmuck 0:df5ce1bc5036 330 while (dio1.read() == 0) {
dudmuck 0:df5ce1bc5036 331 if (end_tx) {
dudmuck 0:df5ce1bc5036 332 // something to send at end : radio.m_spi.write(<end-of-tx>);
dudmuck 0:df5ce1bc5036 333 break;
dudmuck 0:df5ce1bc5036 334 } else
dudmuck 0:df5ce1bc5036 335 radio.m_spi.write(get_tx_byte());
dudmuck 0:df5ce1bc5036 336 }
dudmuck 0:df5ce1bc5036 337
dudmuck 0:df5ce1bc5036 338 radio.m_cs = 1;
dudmuck 0:df5ce1bc5036 339
dudmuck 0:df5ce1bc5036 340 if (end_tx) {
dudmuck 0:df5ce1bc5036 341 end_transmit();
dudmuck 0:df5ce1bc5036 342 txing = false;
dudmuck 0:df5ce1bc5036 343 end_tx = false;
dudmuck 0:df5ce1bc5036 344 start_receive();
dudmuck 0:df5ce1bc5036 345 }
dudmuck 0:df5ce1bc5036 346 }
dudmuck 0:df5ce1bc5036 347 } else {
dudmuck 0:df5ce1bc5036 348 /* receving */
dudmuck 0:df5ce1bc5036 349 if (!dio3) {
dudmuck 0:df5ce1bc5036 350 bool restart_rx = false;
dudmuck 0:df5ce1bc5036 351 radio.m_cs = 0;
dudmuck 0:df5ce1bc5036 352 radio.m_spi.write(REG_FIFO); // bit7 is low for reading from radio
dudmuck 0:df5ce1bc5036 353 while (dio3.read() == 0) {
dudmuck 0:df5ce1bc5036 354 if (take_rx_byte(radio.m_spi.write(0)) != 0) {
dudmuck 0:df5ce1bc5036 355 restart_rx = true;
dudmuck 0:df5ce1bc5036 356 break;
dudmuck 0:df5ce1bc5036 357 }
dudmuck 0:df5ce1bc5036 358
dudmuck 0:df5ce1bc5036 359 }
dudmuck 0:df5ce1bc5036 360 radio.m_cs = 1;
dudmuck 0:df5ce1bc5036 361
dudmuck 0:df5ce1bc5036 362 if (restart_rx) {
dudmuck 0:df5ce1bc5036 363 printf("rxRestart %u\r\n", rx_bytes_ok);
dudmuck 0:df5ce1bc5036 364 fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);
dudmuck 0:df5ce1bc5036 365 #ifdef ENABLE_AFC
dudmuck 0:df5ce1bc5036 366 fsk.RegRxConfig.bits.AfcAutoOn = 1;
dudmuck 0:df5ce1bc5036 367 fsk.RegRxConfig.bits.RestartRxWithPllLock = 1;
dudmuck 0:df5ce1bc5036 368 #else
dudmuck 0:df5ce1bc5036 369 fsk.RegRxConfig.bits.RestartRxWithoutPllLock = 1;
dudmuck 0:df5ce1bc5036 370 #endif
dudmuck 0:df5ce1bc5036 371 radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
dudmuck 0:df5ce1bc5036 372
dudmuck 0:df5ce1bc5036 373 if (!dio3) {
dudmuck 0:df5ce1bc5036 374 /* dump whatever is remaining in fifo */
dudmuck 0:df5ce1bc5036 375 radio.m_cs = 0;
dudmuck 0:df5ce1bc5036 376 while (dio3.read() == 0) {
dudmuck 0:df5ce1bc5036 377 radio.m_spi.write(0);
dudmuck 0:df5ce1bc5036 378 }
dudmuck 0:df5ce1bc5036 379 radio.m_cs = 1;
dudmuck 0:df5ce1bc5036 380 }
dudmuck 0:df5ce1bc5036 381
dudmuck 0:df5ce1bc5036 382 /*
dudmuck 0:df5ce1bc5036 383 fsk.RegAfcFei.octet = radio.read_reg(REG_FSK_AFCFEI);
dudmuck 0:df5ce1bc5036 384 fsk.RegAfcFei.bits.AfcAutoClearOn = 1;
dudmuck 0:df5ce1bc5036 385 fsk.RegAfcFei.bits.AfcClear = 1;
dudmuck 0:df5ce1bc5036 386 radio.write_reg(REG_FSK_AFCFEI, fsk.RegAfcFei.octet);
dudmuck 0:df5ce1bc5036 387 */
dudmuck 0:df5ce1bc5036 388 }
dudmuck 0:df5ce1bc5036 389 }
dudmuck 0:df5ce1bc5036 390
dudmuck 0:df5ce1bc5036 391 if (rxSync) {
dudmuck 0:df5ce1bc5036 392 rxSync = false;
dudmuck 0:df5ce1bc5036 393 printf("rxSync\r\n");
dudmuck 0:df5ce1bc5036 394 }
dudmuck 0:df5ce1bc5036 395 } // ..rxing
dudmuck 0:df5ce1bc5036 396
dudmuck 0:df5ce1bc5036 397
dudmuck 0:df5ce1bc5036 398 } // .. while(true)
dudmuck 0:df5ce1bc5036 399 }