wayne roberts / Mbed OS FSK_unlimited

Dependencies:   SX127x

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }