aanper 5 лет назад
Родитель
Сommit
6b5797bbf4
1 измененных файлов с 116 добавлено и 147 удалено
  1. 116 147
      applications/cc1101-workaround/cc1101-workaround.cpp

+ 116 - 147
applications/cc1101-workaround/cc1101-workaround.cpp

@@ -2,37 +2,11 @@
 
 #include "cc1101-workaround/cc1101.h"
 
-#define MIN_DBM -120
-#define STEP_DBM 10
-#define RSSI_DELAY 600 //rssi delay in micro second
-
-#define RSSI_THRESHOLD -60
-
-#define START_SUB_BAND 3
-#define STOP_SUB_BAND 3
+#define RSSI_DELAY 5000 //rssi delay in micro second
 #define NUM_OF_SUB_BANDS 7
-#define CAL_INT 20 // cal every 10 channels(every 1MHz)
-
-// variables used to calculate rssi
-uint8_t rssi_dec;
-int16_t rssi_dBm;
-uint8_t rssi_offset[NUM_OF_SUB_BANDS] = {74, 74, 74, 74, 74, 74, 74};
-
 #define CHAN_SPA 0.05 // channel spacing
 
-// no change in TEST0 WHERE (>430.5MHz) one should change from TEST0=0x0B to 0x09
-uint16_t limitTest0Reg[NUM_OF_SUB_BANDS] = {256, 256, 256, 103, 0, 0, 0};
-
-/* setting to use 50khz channel spacing whole band*****************************************/
-
-int16_t rssiTable[256];
-uint16_t channelNumber[256];
-
-// counter used to keep track on how many CS has been asserted
-uint8_t carrierSenseCounter = 0;
-
-
-int16_t calRSSI(uint8_t rssi_dec, uint8_t rssiOffset) {
+int16_t rssi_to_dbm(uint8_t rssi_dec, uint8_t rssiOffset) {
     int16_t rssi;
 
     if(rssi_dec >= 128) {
@@ -44,146 +18,78 @@ int16_t calRSSI(uint8_t rssi_dec, uint8_t rssiOffset) {
     return rssi;
 }
 
-/*
-void scanFreq(CC1101* cc1101) {
-    uint8_t calCounter; // to determine when to calibrate
-    uint8_t subBand;
-    uint16_t channel;
-    uint16_t i;
+typedef struct {
+    float base_freq;
+    uint8_t reg[3]; // FREQ2, FREQ1, FREQ0
+    uint8_t first_channel;
+    uint8_t last_channel;
+    uint8_t rssi_offset;
+} Band;
 
-    float freq;
+typedef struct {
+    Band* band;
+    uint16_t channel;
+} FreqConfig;
 
+void setup_freq(CC1101* cc1101, FreqConfig* config) {
     cc1101->SpiWriteReg(CC1101_MCSM0, 0x08); // disalbe FS_AUTOCAL
     cc1101->SpiWriteReg(CC1101_AGCCTRL2, 0x43 | 0x0C); // MAX_DVGA_GAIN to 11 for fast rssi
     cc1101->SpiWriteReg(CC1101_AGCCTRL0, 0xB0); // max AGC WAIT_TIME; 0 filter_length
     cc1101->SetMod(GFSK); // set to GFSK for fast rssi measurement | +8 is dcfilter off
 
-    // 1) loop through all sub bands
-    for(subBand = START_SUB_BAND; subBand < STOP_SUB_BAND + 1; subBand++) {
-        // 1.1) set subBands freq by FREQ2, FREQ1, FREQ0
-        cc1101->SetFreq(
-            freqSettings[subBand][0], freqSettings[subBand][1], freqSettings[subBand][2]);
-        // 1.2) set TEST0--maybe!
-        // 1.3) reset calibration counter
-        calCounter = 0;
-        // 1.4) loop throuhg all channels
-        for(channel = firstChannel[subBand]; channel <= lastChannel[subBand]; channel++) {
-            uint8_t pktStatus;
-            // 1.4.1) set channel register
-            cc1101->SetChannel(channel);
-
-            // 1.4.2)  set TEST0
-            if(channel == limitTest0Reg[subBand]) {
-                //set test0 to 0x09
-                cc1101->SpiWriteReg(CC1101_TEST0, 0x09);
-                //set FSCAL2 to 0x2A to force VCO HIGH
-                cc1101->SpiWriteReg(CC1101_FSCAL2, 0x2A);
-                //clear calCounter to invoke mannual calibration
-                calCounter = 0;
-            }
-            // 1.4.3) calibrate every 1MHz
-            if(calCounter++ == 0) {
-                // perform a manual calibration by issuing SCAL command
-                cc1101->SpiStrobe(CC1101_SCAL);
-            }
-            // 1.4.4) reset calCounter when 1MHz reached
-            if(calCounter == CAL_INT) {
-                calCounter = 0;
-            }
-            // 1.4.5-6 enter rx mode
-            cc1101->SetReceive();
-            // 1.4.7 wait for RSSI to be valid: less than 1.5ms
-            delayMicroseconds(RSSI_DELAY);
-            // 1.4.8) read PKTSTATUS register while the radio is in RX state
-            pktStatus = cc1101->SpiReadStatus(CC1101_PKTSTATUS);
-            // 1.4.9) enter IDLE state by issuing a SIDLE command
-            cc1101->SpiStrobe(CC1101_SIDLE);
-            // 1.4.10) check if CS is assearted
-            // //read rssi value and converto to dBm form
-            rssi_dec = (uint8_t)cc1101->SpiReadStatus(CC1101_RSSI);
-            rssi_dBm = calRSSI(rssi_dec, rssi_offset[subBand]);
-
-            // rssiData[subBand][channel]=rssi_dBm;
-            if(pktStatus & 0x40) { //CS assearted
-                // store rssi value and corresponding channel number
-                rssiTable[carrierSenseCounter] = rssi_dBm;
-                channelNumber[carrierSenseCounter] = channel;
-                carrierSenseCounter++;
-            }
-
-#ifdef CC1101_DEBUG
-            printf("rssi_dBm: %d\n", rssi_dBm);
-#endif
-        } // end channel lop
-
-        // 1.5)before moving to next sub band,
-        // scan through rssiTable to find highest rssi value
-        for(i = 0; i < carrierSenseCounter; i++) {
-            if(rssiTable[i] > highRSSI[subBand]) {
-                highRSSI[subBand] = rssiTable[i];
-                selectedChannel[subBand] = channelNumber[i];
-            }
-        }
+    cc1101->SetFreq(config->band->reg[0], config->band->reg[1], config->band->reg[2]);
+    cc1101->SetChannel(config->channel);
 
-        // printf("subBand:------------------>");
-        // Serial.println(subBand);
-        // Serial.print("selectedChannel:");
-        // Serial.println(selectedChannel[subBand]);
-        // Serial.print("highRSSI:");
-        // Serial.println(highRSSI[subBand]);
-
-        // 1.6) reset carrierSenseCounter
-        carrierSenseCounter = 0;
-    } // end band loop
-
-    // 2) when all sub bands has been scanned , find best subband and channel
-    int16_t tempRssi = MIN_DBM;
-    for(subBand = 0; subBand < NUM_OF_SUB_BANDS; subBand++) {
-        if(highRSSI[subBand] > tempRssi) {
-            tempRssi = highRSSI[subBand];
-            activeChannel = selectedChannel[subBand];
-            activeBand = subBand;
-        }
-    }
+    //set test0 to 0x09
+    cc1101->SpiWriteReg(CC1101_TEST0, 0x09);
+    //set FSCAL2 to 0x2A to force VCO HIGH
+    cc1101->SpiWriteReg(CC1101_FSCAL2, 0x2A);
 
-    // printf("activeBand:**********> %d, activeChannel %d,\n", activeBand, activeChannel);
+    // perform a manual calibration by issuing SCAL command
+    cc1101->SpiStrobe(CC1101_SCAL);
 
+    /*
+    // Cleanup:
     cc1101->SpiWriteReg(CC1101_MCSM0, 0x18); //enable FS_AUTOCAL
     cc1101->SpiWriteReg(CC1101_AGCCTRL2, 0x43); //back to recommended config
     cc1101->SpiWriteReg(CC1101_AGCCTRL0, 0x91); //back to recommended config
+    */
 }
 
-void tx(CC1101* cc1101, uint8_t band, uint16_t channel, uint16_t miniSec) {
-    cc1101->SetFreq(freqSettings[band][0], freqSettings[band][1], freqSettings[band][2]);
-    cc1101->SetChannel(channel);
-    // digitalWrite(19,0);
-    cc1101->SetTransmit();
-    delay(miniSec);
+int16_t rx_rssi(CC1101* cc1101, FreqConfig* config) {
+    cc1101->SetReceive();
 
+    delayMicroseconds(RSSI_DELAY);
+    
+    // 1.4.8) read PKTSTATUS register while the radio is in RX state
+    uint8_t _pkt_status = cc1101->SpiReadStatus(CC1101_PKTSTATUS);
+    
+    // 1.4.9) enter IDLE state by issuing a SIDLE command
     cc1101->SpiStrobe(CC1101_SIDLE);
+
+    // //read rssi value and converto to dBm form
+    uint8_t rssi_dec = (uint8_t)cc1101->SpiReadStatus(CC1101_RSSI);
+    int16_t rssi_dBm = rssi_to_dbm(rssi_dec, config->band->rssi_offset);
+
+    return rssi_dBm;
 }
-*/
 
-typedef struct {
-    float base_freq;
-    uint8_t settings[3]; // FREQ2, FREQ1, FREQ0
-    uint8_t first_channel;
-    uint8_t last_channel;
-} Band;
+void tx(CC1101* cc1101) {
+    cc1101->SetTransmit();
+}
 
-typedef struct {
-    Band* band;
-    uint16_t channel;
-} FreqConfig;
+void idle(CC1101* cc1101) {
+    cc1101->SpiStrobe(CC1101_SIDLE);
+}
 
 Band bands[NUM_OF_SUB_BANDS] = {
-    {387, {0x0E, 0xE2, 0x76}, 0, 255},
-    {399.8, {0x0F, 0x60, 0x76}, 0, 255},
-    {412.6, {0x0F, 0xDE, 0x76}, 0, 255},
-    {425.4, {0x10, 0x5C, 0x76}, 160, 180},
-    {438.2, {0x10, 0xDA, 0x76}, 0, 255},
-    {451, {0x11, 0x58, 0x8F}, 0, 255},
-    {463.8, {0x11, 0xD6, 0x8F}, 0, 4},
+    {387, {0x0E, 0xE2, 0x76}, 0, 255, 74},
+    {399.8, {0x0F, 0x60, 0x76}, 0, 255, 74},
+    {412.6, {0x0F, 0xDE, 0x76}, 0, 255, 74},
+    {425.4, {0x10, 0x5C, 0x76}, 160, 180, 74},
+    {438.2, {0x10, 0xDA, 0x76}, 0, 255, 74},
+    {451, {0x11, 0x58, 0x8F}, 0, 255, 74},
+    {463.8, {0x11, 0xD6, 0x8F}, 0, 4, 74},
 };
 
 FreqConfig FREQ_LIST[] = {
@@ -237,6 +143,8 @@ typedef enum {
 typedef struct {
     Mode mode;
     size_t active_freq;
+    int16_t last_rssi;
+    bool need_cc1101_conf;
 } State;
 
 static void render_callback(CanvasApi* canvas, void* ctx) {
@@ -257,6 +165,30 @@ static void render_callback(CanvasApi* canvas, void* ctx) {
         canvas->draw_str(canvas, 2, 25, buf);
     }
 
+    {
+        canvas->set_font(canvas, FontSecondary);
+
+        if(state->need_cc1101_conf) {
+            canvas->draw_str(canvas, 2, 36, "mode: configuring...");
+        } else if(state->mode == ModeRx) {
+            canvas->draw_str(canvas, 2, 36, "mode: RX");
+        } else if(state->mode == ModeTx) {
+            canvas->draw_str(canvas, 2, 36, "mode: TX");
+        } else {
+            canvas->draw_str(canvas, 2, 36, "mode: unknown");
+        }
+    }
+
+    {
+        if(!state->need_cc1101_conf && state->mode == ModeRx) {
+            char buf[24];
+            sprintf(buf, "RSSI: %d dBm", state->last_rssi);
+
+            canvas->set_font(canvas, FontSecondary);
+            canvas->draw_str(canvas, 2, 48, buf);
+        }
+    }
+
     release_mutex((ValueMutex*)ctx, state);
 }
 
@@ -277,6 +209,8 @@ extern "C" void cc1101_workaround(void* p) {
     State _state;
     _state.mode = ModeRx;
     _state.active_freq = 0;
+    _state.need_cc1101_conf = true;
+    _state.last_rssi = 0;
 
     ValueMutex state_mutex;
     if(!init_mutex(&state_mutex, &_state, sizeof(State))) {
@@ -318,9 +252,17 @@ extern "C" void cc1101_workaround(void* p) {
     // 50khz channel spacing
     cc1101.SpiWriteReg(CC1101_MDMCFG0, 0xF8);
 
+    // create pin
+    GpioPin led = {GPIOA, GPIO_PIN_8};
+
+    // configure pin
+    pinMode(led, GpioModeOpenDrain);
+
+    const int16_t RSSI_THRESHOLD = -89;
+
     Event event;
     while(1) {
-        if(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) {
+        if(osMessageQueueGet(event_queue, &event, NULL, 150) == osOK) {
             State* state = (State*)acquire_mutex_block(&state_mutex);
 
             if(event.type == EventTypeKey) {
@@ -334,16 +276,43 @@ extern "C" void cc1101_workaround(void* p) {
                 if(event.value.input.state && event.value.input.input == InputUp) {
                     if(state->active_freq > 0) {
                         state->active_freq--;
+                        state->need_cc1101_conf = true;
                     }
                 }
 
                 if(event.value.input.state && event.value.input.input == InputDown) {
                     if(state->active_freq < (sizeof(FREQ_LIST)/sizeof(FREQ_LIST[0]) - 1)) {
                         state->active_freq++;
+                        state->need_cc1101_conf = true;
                     }
                 }
             }
 
+            if(state->need_cc1101_conf) {
+                setup_freq(&cc1101, &FREQ_LIST[state->active_freq]);
+
+                if(state->mode == ModeRx) {
+                    state->last_rssi = rx_rssi(&cc1101, &FREQ_LIST[state->active_freq]);
+                } else if(state->mode == ModeTx) {
+                    tx(&cc1101);
+                }
+
+                state->need_cc1101_conf = false;
+            }
+
+            digitalWrite(led, state->last_rssi > RSSI_THRESHOLD ? LOW : HIGH);
+
+            release_mutex(&state_mutex, state);
+            widget_update(widget);
+        } else {
+            State* state = (State*)acquire_mutex_block(&state_mutex);
+
+            if(!state->need_cc1101_conf && state->mode == ModeRx) {
+                state->last_rssi = rx_rssi(&cc1101, &FREQ_LIST[state->active_freq]);
+            }
+
+            digitalWrite(led, state->last_rssi > RSSI_THRESHOLD ? LOW : HIGH);
+
             release_mutex(&state_mutex, state);
             widget_update(widget);
         }