Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp@0:df5ce1bc5036, 2021-09-14 (annotated)
- Committer:
- dudmuck
- Date:
- Tue Sep 14 22:19:57 2021 +0000
- Revision:
- 0:df5ce1bc5036
commit initial
Who changed what in which revision?
| User | Revision | Line number | New 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 | } |