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
00001 #include "mbed.h" 00002 #include "sx127x_fsk.h" 00003 00004 using namespace std::chrono; 00005 00006 #define FSK_BIT_RATE 10000 00007 #define TX_FREQ_DEVIATION_HZ 20000 00008 #define RX_BW 30000 00009 #define RX_BW_AFC 30000 00010 #define START_OF_FRAME 0xd42d 00011 #define RADIO_FREQUENCY_MHZ 915.0 00012 //#define ENABLE_AFC 00013 00014 SPI spi(D11, D12, D13); // mosi, miso, sclk 00015 // dio0, dio1, nss, spi, rst 00016 SX127x radio( D2, D3, D10, spi, A0); // sx127[62] arduino shield 00017 SX127x_fsk fsk(radio); 00018 DigitalInOut rfsw(A4); 00019 00020 DigitalIn dio1(D3); // for FifoLevel 00021 InterruptIn dio2(D4); // for syncAddress 00022 DigitalIn dio3(D5); // for FifoEmpty 00023 00024 DigitalIn button(/*USER_BUTTON*/ BUTTON1); 00025 bool button_pressed; 00026 #define BUTTON_DEBOUNCE_MS 10 00027 bool txing; 00028 bool end_tx; 00029 bool rxSync; 00030 00031 typedef enum { 00032 SHIELD_TYPE_NONE = 0, 00033 SHIELD_TYPE_LAS, 00034 SHIELD_TYPE_MAS, 00035 } shield_type_e; 00036 shield_type_e shield_type; 00037 00038 void rfsw_callback() 00039 { 00040 if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) 00041 rfsw = 1; 00042 else 00043 rfsw = 0; 00044 } 00045 00046 void get_rf_board_type() 00047 { 00048 rfsw.input(); 00049 if (rfsw.read()) { 00050 shield_type = SHIELD_TYPE_LAS; 00051 printf("LAS\r\n"); 00052 } else { 00053 shield_type = SHIELD_TYPE_MAS; 00054 printf("MAS\r\n"); 00055 } 00056 00057 rfsw.output(); 00058 } 00059 00060 void ocp(uint8_t ma) 00061 { 00062 if (ma < 130) 00063 radio.RegOcp.bits.OcpTrim = (ma - 45) / 5; 00064 else 00065 radio.RegOcp.bits.OcpTrim = (ma + 30) / 10; 00066 radio.write_reg(REG_OCP, radio.RegOcp.octet); 00067 00068 radio.RegOcp.octet = radio.read_reg(REG_OCP); 00069 if (radio.RegOcp.bits.OcpTrim < 16) 00070 ma = 45 + (5 * radio.RegOcp.bits.OcpTrim); 00071 else if (radio.RegOcp.bits.OcpTrim < 28) 00072 ma = (10 * radio.RegOcp.bits.OcpTrim) - 30; 00073 else 00074 ma = 240; 00075 } 00076 00077 void 00078 set_tx_dbm(int8_t dbm) 00079 { 00080 RegPdsTrim1_t pds_trim; 00081 uint8_t v, adr, pa_test_adr; 00082 00083 if (radio.type == SX1276) { 00084 adr = REG_PDSTRIM1_SX1276; 00085 pa_test_adr = REG_PATEST_SX1276; 00086 } else { 00087 adr = REG_PDSTRIM1_SX1272; 00088 pa_test_adr = REG_PATEST_SX1272; 00089 } 00090 00091 v = radio.read_reg(pa_test_adr); 00092 /*if (dbm == PA_OFF_DBM) { 00093 // for bench testing: prevent overloading receiving station (very low TX power) 00094 v &= ~0x20; // turn off pu_regpa_n: disable PA 00095 radio.write_reg(pa_test_adr, v); 00096 return; 00097 } else if ((v & 0x20) == 0) { 00098 v |= 0x20; // turn on pu_regpa_n: enable PA 00099 radio.write_reg(pa_test_adr, v); 00100 }*/ 00101 00102 pds_trim.octet = radio.read_reg(adr); 00103 00104 if (shield_type == SHIELD_TYPE_LAS) 00105 radio.RegPaConfig.bits.PaSelect = 1; 00106 else 00107 radio.RegPaConfig.bits.PaSelect = 0; 00108 00109 if (radio.RegPaConfig.bits.PaSelect) { 00110 /* PABOOST used: +2dbm to +17, or +20 */ 00111 if (dbm > 17) { 00112 if (dbm > 20) 00113 dbm = 20; 00114 dbm -= 3; 00115 pds_trim.bits.prog_txdac = 7; 00116 radio.write_reg(adr, pds_trim.octet); 00117 ocp(150); 00118 } else 00119 ocp(120); 00120 00121 if (dbm > 1) 00122 radio.RegPaConfig.bits.OutputPower = dbm - 2; 00123 } else { 00124 /* RFO used: -1 to +14dbm */ 00125 ocp(80); 00126 if (dbm < 15) 00127 radio.RegPaConfig.bits.OutputPower = dbm + 1; 00128 } 00129 radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet); 00130 00131 radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG); 00132 if (radio.RegPaConfig.bits.PaSelect) { 00133 dbm = radio.RegPaConfig.bits.OutputPower + pds_trim.bits.prog_txdac - 2; 00134 } else { 00135 dbm = radio.RegPaConfig.bits.OutputPower - 1; 00136 } 00137 } 00138 00139 void start_receive() 00140 { 00141 fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG); 00142 fsk.RegRxConfig.bits.RxTrigger = 6; // trigger receiver on preamble detect 00143 fsk.RegRxConfig.bits.AgcAutoOn = 1; // radio controls its LNA 00144 #ifdef ENABLE_AFC 00145 fsk.RegRxConfig.bits.AfcAutoOn = 1; 00146 fsk.RegRxConfig.bits.RestartRxWithPllLock = 1; 00147 #endif /* ENABLE_AFC */ 00148 radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet); 00149 00150 #ifdef ENABLE_AFC 00151 fsk.RegAfcFei.octet = radio.read_reg(REG_FSK_AFCFEI); 00152 fsk.RegAfcFei.bits.AfcAutoClearOn = 1; 00153 fsk.RegAfcFei.bits.AfcClear = 1; 00154 radio.write_reg(REG_FSK_AFCFEI, fsk.RegAfcFei.octet); 00155 #endif /* ENABLE_AFC */ 00156 00157 radio.set_opmode(RF_OPMODE_RECEIVER); 00158 } 00159 00160 #define FIRST_PAYLOAD_BYTE 0 00161 uint8_t expected_rx; 00162 uint8_t rx_err_cnt; 00163 unsigned rx_bytes_ok; 00164 00165 void dio2_callback() 00166 { 00167 if (!txing) { 00168 expected_rx = FIRST_PAYLOAD_BYTE; 00169 rxSync = true; 00170 rx_err_cnt = 0; 00171 rx_bytes_ok = 0; 00172 } else { 00173 // fifoFull in TX 00174 } 00175 00176 } 00177 00178 /* return non-zero at end of packet detection */ 00179 int take_rx_byte(uint8_t in) 00180 { 00181 int ret; 00182 00183 if (in != expected_rx) { 00184 printf("(got %02x, wanted %02x)\r\n", in, expected_rx); 00185 if (++rx_err_cnt == 4) 00186 ret = -1; // too much consecutive noise 00187 else 00188 ret = 0; 00189 } else { 00190 rx_bytes_ok++; 00191 rx_err_cnt = 0; 00192 ret = 0; 00193 } 00194 00195 expected_rx++; 00196 00197 return ret; 00198 } 00199 00200 uint8_t tx_byte_cnt; 00201 uint8_t get_tx_byte() 00202 { 00203 return tx_byte_cnt++; 00204 } 00205 00206 void start_transmit() 00207 { 00208 fsk.RegFifoThreshold.octet = radio.read_reg(REG_FSK_FIFOTHRESH); 00209 fsk.RegFifoThreshold.bits.FifoThreshold = 48; 00210 radio.write_reg(REG_FSK_FIFOTHRESH, fsk.RegFifoThreshold.octet); 00211 00212 tx_byte_cnt = FIRST_PAYLOAD_BYTE; 00213 radio.set_opmode(RF_OPMODE_TRANSMITTER); 00214 } 00215 00216 void end_transmit() 00217 { 00218 printf("wait fifoEmpty...\r\n"); 00219 while (dio3.read() == 0) 00220 ; 00221 00222 radio.set_opmode(RF_OPMODE_STANDBY); 00223 printf("tx-end\r\n"); 00224 } 00225 00226 int main() 00227 { 00228 long button_release_start = -1; 00229 00230 00231 radio.rf_switch = rfsw_callback; 00232 get_rf_board_type(); 00233 ThisThread::sleep_for(30ms); // from cold power-up, both radio and mcu started 00234 00235 radio.hw_reset(); 00236 00237 if (shield_type == SHIELD_TYPE_LAS) 00238 set_tx_dbm(13); 00239 else 00240 set_tx_dbm(17); 00241 00242 radio.set_frf_MHz(RADIO_FREQUENCY_MHZ); 00243 00244 fsk.enable(true); 00245 fsk.set_tx_fdev_hz(TX_FREQ_DEVIATION_HZ); 00246 00247 fsk.set_bitrate(FSK_BIT_RATE); 00248 00249 fsk.set_rx_dcc_bw_hz(RX_BW, 0); 00250 fsk.set_rx_dcc_bw_hz(RX_BW_AFC, 1); 00251 00252 fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG); 00253 fsk.RegSyncConfig.bits.SyncSize = 2 - 1; 00254 radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet); 00255 radio.write_reg(REG_FSK_SYNCVALUE1, 0xd4); 00256 radio.write_reg(REG_FSK_SYNCVALUE1, 0x2d); 00257 00258 // dio3 to FifoEmpty 00259 // dio2 to syncAddress 00260 // dio1 to FifoLevel 00261 radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1); 00262 radio.RegDioMapping1.bits.Dio3Mapping = 3; // 00263 radio.RegDioMapping1.bits.Dio2Mapping = 3; // 00264 radio.RegDioMapping1.bits.Dio1Mapping = 0; // 00265 radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet); 00266 dio2.rise(dio2_callback); 00267 00268 fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1); 00269 fsk.RegPktConfig1.bits.PacketFormatVariable = 0; 00270 radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet); 00271 00272 // unlimited payload-length operation 00273 fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2); 00274 fsk.RegPktConfig2.bits.PayloadLength = 0; 00275 radio.write_u16(REG_FSK_PACKETCONFIG2, fsk.RegPktConfig2.word); 00276 00277 fsk.RegPreambleDetect.octet = radio.read_reg(REG_FSK_PREAMBLEDETECT); 00278 fsk.RegPreambleDetect.bits.PreambleDetectorTol = 10; 00279 fsk.RegPreambleDetect.bits.PreambleDetectorSize = 1; 00280 fsk.RegPreambleDetect.bits.PreambleDetectorOn = 1; 00281 radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet); 00282 00283 //printf("preamblesize: %02x ", radio.read_reg(REG_FSK_PREAMBLEMSB)); 00284 //printf("%02x\r\n", radio.read_reg(REG_FSK_PREAMBLELSB)); 00285 start_receive(); 00286 00287 while (true) { 00288 if (button_pressed) { 00289 if (button.read()) { 00290 // button released 00291 button_pressed = false; 00292 auto now_tp = time_point_cast<milliseconds>(Kernel::Clock::now()); 00293 button_release_start = now_tp.time_since_epoch().count(); 00294 } 00295 } else { 00296 if (!button.read()) { 00297 // button pressed 00298 button_pressed = true; 00299 button_release_start = -1; 00300 } 00301 } 00302 00303 if (button_release_start != -1) { 00304 // debounce button 00305 auto now_tp = time_point_cast<milliseconds>(Kernel::Clock::now()); 00306 long now_ms = now_tp.time_since_epoch().count(); 00307 if ((now_ms - button_release_start) > BUTTON_DEBOUNCE_MS) { 00308 // button released sufficiently long enough 00309 button_release_start = -1; 00310 if (txing) { 00311 printf("toRX\r\n"); 00312 end_tx = true; 00313 } else { 00314 printf("toTX\r\n"); 00315 start_transmit(); 00316 txing = true; 00317 } 00318 } 00319 } 00320 00321 if (txing) { 00322 /* transmitting */ 00323 if (dio1) { 00324 /* fifo above threshold, let the radio send it */ 00325 /* alternately, send until FifoFull */ 00326 } else { 00327 /* fifo below threshold */ 00328 radio.m_cs = 0; 00329 radio.m_spi.write(REG_FIFO | 0x80); // bit7 is high for writing to radio 00330 while (dio1.read() == 0) { 00331 if (end_tx) { 00332 // something to send at end : radio.m_spi.write(<end-of-tx>); 00333 break; 00334 } else 00335 radio.m_spi.write(get_tx_byte()); 00336 } 00337 00338 radio.m_cs = 1; 00339 00340 if (end_tx) { 00341 end_transmit(); 00342 txing = false; 00343 end_tx = false; 00344 start_receive(); 00345 } 00346 } 00347 } else { 00348 /* receving */ 00349 if (!dio3) { 00350 bool restart_rx = false; 00351 radio.m_cs = 0; 00352 radio.m_spi.write(REG_FIFO); // bit7 is low for reading from radio 00353 while (dio3.read() == 0) { 00354 if (take_rx_byte(radio.m_spi.write(0)) != 0) { 00355 restart_rx = true; 00356 break; 00357 } 00358 00359 } 00360 radio.m_cs = 1; 00361 00362 if (restart_rx) { 00363 printf("rxRestart %u\r\n", rx_bytes_ok); 00364 fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG); 00365 #ifdef ENABLE_AFC 00366 fsk.RegRxConfig.bits.AfcAutoOn = 1; 00367 fsk.RegRxConfig.bits.RestartRxWithPllLock = 1; 00368 #else 00369 fsk.RegRxConfig.bits.RestartRxWithoutPllLock = 1; 00370 #endif 00371 radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet); 00372 00373 if (!dio3) { 00374 /* dump whatever is remaining in fifo */ 00375 radio.m_cs = 0; 00376 while (dio3.read() == 0) { 00377 radio.m_spi.write(0); 00378 } 00379 radio.m_cs = 1; 00380 } 00381 00382 /* 00383 fsk.RegAfcFei.octet = radio.read_reg(REG_FSK_AFCFEI); 00384 fsk.RegAfcFei.bits.AfcAutoClearOn = 1; 00385 fsk.RegAfcFei.bits.AfcClear = 1; 00386 radio.write_reg(REG_FSK_AFCFEI, fsk.RegAfcFei.octet); 00387 */ 00388 } 00389 } 00390 00391 if (rxSync) { 00392 rxSync = false; 00393 printf("rxSync\r\n"); 00394 } 00395 } // ..rxing 00396 00397 00398 } // .. while(true) 00399 }
Generated on Wed Jul 13 2022 16:53:10 by
1.7.2