From f69667370061fe87299be5e456b34583cf40cacb Mon Sep 17 00:00:00 2001 From: aanper Date: Tue, 13 Oct 2020 13:39:59 +0300 Subject: [PATCH 01/12] add workaround app --- applications/applications.mk | 8 +++++++ .../cc1101-workaround/cc1101-workaround.c | 24 +++++++++++++++++++ applications/startup.h | 5 ++++ 3 files changed, 37 insertions(+) create mode 100644 applications/cc1101-workaround/cc1101-workaround.c diff --git a/applications/applications.mk b/applications/applications.mk index 71db1d39..2856dc08 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -67,6 +67,14 @@ APP_INPUT = 1 APP_DISPLAY = 1 endif +APP_CC1101 ?= 0 +ifeq ($(APP_CC1101), 1) +CFLAGS += -DAPP_CC1101 +C_SOURCES += $(APP_DIR)/cc1101-workaround/cc1101-workaround.c +APP_INPUT = 1 +APP_DISPLAY = 1 +endif + # device drivers ifeq ($(APP_DISPLAY), 1) diff --git a/applications/cc1101-workaround/cc1101-workaround.c b/applications/cc1101-workaround/cc1101-workaround.c new file mode 100644 index 00000000..7709e121 --- /dev/null +++ b/applications/cc1101-workaround/cc1101-workaround.c @@ -0,0 +1,24 @@ +#include "flipper.h" +#include "u8g2.h" + +void cc1101_workaround(void* p) { + FuriRecordSubscriber* fb_record = furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); + + if(fb_record == NULL) { + printf("[cc1101] cannot create fb record\n"); + furiac_exit(NULL); + } + + while(1) { + u8g2_t* fb = furi_take(fb_record); + if(fb != NULL) { + u8g2_SetFont(fb, u8g2_font_6x10_mf); + u8g2_SetDrawColor(fb, 1); + u8g2_SetFontMode(fb, 1); + u8g2_DrawStr(fb, 2, 12, "cc1101 workaround"); + } + furi_commit(fb_record); + + delay(1000); + } +} \ No newline at end of file diff --git a/applications/startup.h b/applications/startup.h index d5c00d48..6b177638 100644 --- a/applications/startup.h +++ b/applications/startup.h @@ -22,6 +22,7 @@ void input_task(void* p); void menu_task(void* p); void coreglitch_demo_0(void* p); +void cc1101_workaround(void* p); void u8g2_qrcode(void* p); void fatfs_list(void* p); @@ -70,4 +71,8 @@ const FlipperStartupApp FLIPPER_STARTUP[] = { {.app = u8g2_example, .name = "u8g2_example", .libs = {1, FURI_LIB{"display_u8g2"}}}, #endif +#ifdef APP_CC1101 + {.app = cc1101_workaround, .name = "cc1101_workaround", .libs = {2, FURI_LIB{"display_u8g2", "input_task"}}}, +#endif + }; From b007b9cb6067bb7656c412039059c1d9eaf43883 Mon Sep 17 00:00:00 2001 From: aanper Date: Tue, 13 Oct 2020 20:59:39 +0300 Subject: [PATCH 02/12] lint code --- .../cc1101-workaround/cc1101-workaround.c | 250 +++++++++++++++++- applications/examples/fatfs_list.c | 3 +- applications/examples/u8g2_example.c | 3 +- applications/examples/u8g2_qrcode.c | 3 +- applications/startup.h | 4 +- applications/tests/furi_valuemutex_test.c | 1 - applications/tests/minunit_test.c | 1 - core/api-basic/value-expanders.h | 12 +- core/api-hal/api-spi.h | 17 +- 9 files changed, 271 insertions(+), 23 deletions(-) diff --git a/applications/cc1101-workaround/cc1101-workaround.c b/applications/cc1101-workaround/cc1101-workaround.c index 7709e121..f3f3e366 100644 --- a/applications/cc1101-workaround/cc1101-workaround.c +++ b/applications/cc1101-workaround/cc1101-workaround.c @@ -1,8 +1,256 @@ #include "flipper.h" #include "u8g2.h" +#include + +#include "cc1101/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 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 + +float base_freq[NUM_OF_SUB_BANDS] = {387, 399.8, 412.6, 425.4, 438.2, 451, 463.8}; +//FREQ2,FREQ1,FREQ0 +uint8_t freqSettings[NUM_OF_SUB_BANDS][3] = { + {0x0E, 0xE2, 0x76}, //band0 + {0x0F, 0x60, 0x76}, + {0x0F, 0xDE, 0x76}, //band1 + {0x10, 0x5C, 0x76}, + {0x10, 0xDA, 0x76}, + {0x11, 0x58, 0x8F}, + {0x11, 0xD6, 0x8F}}; //band2 +//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 rssiData[NUM_OF_SUB_BANDS][256]; +int16_t rssiTable[256]; +uint16_t channelNumber[256]; +uint8_t carrierSenseCounter = 0; //counter used to keep track on how many CS has been asserted + +uint8_t firstChannel[NUM_OF_SUB_BANDS] = {0, 0, 0, 160, 0, 0, 0}; +//stop channel in each subband +uint8_t lastChannel[NUM_OF_SUB_BANDS] = {255, 255, 255, 180, 255, 255, 4}; +//initialized to a value lower than the rssi threshold/ higher than channel number +int16_t highRSSI[NUM_OF_SUB_BANDS] = + {MIN_DBM, MIN_DBM, MIN_DBM, MIN_DBM, MIN_DBM, MIN_DBM, MIN_DBM}; +uint16_t selectedChannel[NUM_OF_SUB_BANDS] = {300, 300, 300, 300, 300, 300, 300}; + +int8_t activeBand; //store subband that contains strongest signal +uint16_t activeChannel; // + +int16_t calRSSI(uint8_t rssi_dec, uint8_t rssiOffset) { + int16_t rssi; + + if(rssi_dec >= 128) { + rssi = (int16_t)((int16_t)(rssi_dec - 256) / 2) - rssiOffset; + } else { + rssi = (rssi_dec / 2) - rssiOffset; + } + + return rssi; +} + +void scanFreq(CC1101* cc1101) { + uint8_t calCounter; //to deterin when to calibrate + uint8_t subBand; + uint16_t channel; + uint16_t i; + + float freq; + + 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]; + } + } + // Serial.print("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; + } + } + + // printf("activeBand:**********> %d, activeChannel %d,\n", activeBand, activeChannel); + + 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 jamming(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); + + cc1101->SpiStrobe(CC1101_SIDLE); +} + +extern QueueHandle_t event_queue; + +bool jamm_on = false; + +void set_jam(bool state) { + jamm_on = state; +} + +extern "C" void radio() { + CC1101 cc1101(SS_PIN, GDO0, GDO2); + + uint8_t address = cc1101.Init(); + + if(address > 0) { + printf("CC1101 init done: %d\n", address); + } else { + printf("CC1101 init fail\n"); + } + + /* setting to use 50khz channel spacing**************************************/ + cc1101.SpiWriteReg( + CC1101_MDMCFG4, 0xCD); // RX filter bandwidth 58.035714(0xFD) 100k(0xCD) 200k(0x8D) + cc1101.SpiWriteReg( + CC1101_MDMCFG3, 0x3B); //datarate config 250kBaud for the purpose of fast rssi measurement + cc1101.SpiWriteReg(CC1101_MDMCFG1, 0x20); //FEC preamble etc. last 2 bits for channel spacing + cc1101.SpiWriteReg(CC1101_MDMCFG0, 0xF8); //50khz channel spacing + + Event event; + event.type = EventTypeRadio; + + while(1) { + for(uint8_t i = 0; i <= NUM_OF_SUB_BANDS; i++) { + highRSSI[i] = MIN_DBM; + } + + activeChannel = 300; + + scanFreq(&cc1101); + + if(activeChannel < 256 && highRSSI[activeBand] > RSSI_THRESHOLD) { + float freq = base_freq[activeBand] + CHAN_SPA * activeChannel; + + /* + printf( + "channel: %d, freq: %d, RSSI: %d\n", + activeChannel, + (uint32_t)(freq * 1000), + highRSSI[activeBand] + ); + */ + + event.value.radio.freq = freq; + event.value.radio.rssi_db = highRSSI[activeBand]; + xQueueSend(event_queue, (void*)&event, 0); + + if(jamm_on) { + jamming(&cc1101, activeBand, activeChannel, 500); + } else { + osDelay(1000); + } + } else { + // printf("0 carrier sensed\n"); + } + + osDelay(1); + } +} void cc1101_workaround(void* p) { - FuriRecordSubscriber* fb_record = furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); + FuriRecordSubscriber* fb_record = + furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); if(fb_record == NULL) { printf("[cc1101] cannot create fb record\n"); diff --git a/applications/examples/fatfs_list.c b/applications/examples/fatfs_list.c index b15db514..58e6730c 100644 --- a/applications/examples/fatfs_list.c +++ b/applications/examples/fatfs_list.c @@ -49,7 +49,8 @@ void fatfs_list(void* p) { furi_log = get_default_log(); - FuriRecordSubscriber* fb_record = furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); + FuriRecordSubscriber* fb_record = + furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); if(fb_record == NULL) { fuprintf(furi_log, "[widget][fatfs_list] cannot create fb record\n"); furiac_exit(NULL); diff --git a/applications/examples/u8g2_example.c b/applications/examples/u8g2_example.c index 02f35ecb..e77012d4 100644 --- a/applications/examples/u8g2_example.c +++ b/applications/examples/u8g2_example.c @@ -5,7 +5,8 @@ void u8g2_example(void* p) { FuriRecordSubscriber* log = get_default_log(); // open record - FuriRecordSubscriber* fb_record = furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); + FuriRecordSubscriber* fb_record = + furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); if(fb_record == NULL) { fuprintf(log, "[widget] cannot create fb record\n"); diff --git a/applications/examples/u8g2_qrcode.c b/applications/examples/u8g2_qrcode.c index 630199c1..2799df33 100644 --- a/applications/examples/u8g2_qrcode.c +++ b/applications/examples/u8g2_qrcode.c @@ -14,7 +14,8 @@ void u8g2_qrcode(void* p) { FuriRecordSubscriber* log = get_default_log(); // open record - FuriRecordSubscriber* fb_record = furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); + FuriRecordSubscriber* fb_record = + furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); // Allocate a chunk of memory to store the QR code // https://github.com/ricmoo/QRCode diff --git a/applications/startup.h b/applications/startup.h index 6b177638..47ebf9f5 100644 --- a/applications/startup.h +++ b/applications/startup.h @@ -72,7 +72,9 @@ const FlipperStartupApp FLIPPER_STARTUP[] = { #endif #ifdef APP_CC1101 - {.app = cc1101_workaround, .name = "cc1101_workaround", .libs = {2, FURI_LIB{"display_u8g2", "input_task"}}}, + {.app = cc1101_workaround, + .name = "cc1101_workaround", + .libs = {2, FURI_LIB{"display_u8g2", "input_task"}}}, #endif }; diff --git a/applications/tests/furi_valuemutex_test.c b/applications/tests/furi_valuemutex_test.c index 960d1543..6279d188 100644 --- a/applications/tests/furi_valuemutex_test.c +++ b/applications/tests/furi_valuemutex_test.c @@ -39,7 +39,6 @@ void test_furi_valuemutex() { //read mutex blocking case } - /* TEST: concurrent access diff --git a/applications/tests/minunit_test.c b/applications/tests/minunit_test.c index f99b6204..37cc6b77 100644 --- a/applications/tests/minunit_test.c +++ b/applications/tests/minunit_test.c @@ -67,7 +67,6 @@ MU_TEST_SUITE(test_suite) { MU_RUN_TEST(mu_test_furi_create_open); MU_RUN_TEST(mu_test_furi_valuemutex); MU_RUN_TEST(mu_test_furi_concurrent_access); - } int run_minunit() { diff --git a/core/api-basic/value-expanders.h b/core/api-basic/value-expanders.h index cec0e75c..70adf856 100644 --- a/core/api-basic/value-expanders.h +++ b/core/api-basic/value-expanders.h @@ -12,15 +12,10 @@ void COPY_COMPOSE(void* ctx, void* state) { read_mutex((ValueMutex*)ctx, state, 0); } -typedef enum { - UiLayerBelowNotify - UiLayerNotify, - UiLayerAboveNotify -} UiLayer; +typedef enum { UiLayerBelowNotify UiLayerNotify, UiLayerAboveNotify } UiLayer; -ValueComposerHandle* add_compose_layer( - ValueComposer* composer, ValueComposerCallback cb, void* ctx, uint32_t layer -); +ValueComposerHandle* +add_compose_layer(ValueComposer* composer, ValueComposerCallback cb, void* ctx, uint32_t layer); bool remove_compose_layer(ValueComposerHandle* handle); @@ -44,7 +39,6 @@ typedef struct { PubSub pubsub; } ValueManager; - /* acquire value, changes it and send notify with current value. */ diff --git a/core/api-hal/api-spi.h b/core/api-hal/api-spi.h index b3bfe674..74559c54 100644 --- a/core/api-hal/api-spi.h +++ b/core/api-hal/api-spi.h @@ -17,13 +17,17 @@ For transmit/receive data use `spi_xfer` function. */ bool spi_xfer( SPI_HandleTypeDef* spi, - uint8_t* tx_data, uint8_t* rx_data, size_t len, - PubSubCallback cb, void* ctx); + uint8_t* tx_data, + uint8_t* rx_data, + size_t len, + PubSubCallback cb, + void* ctx); /* Blocking verison: */ -static inline bool spi_xfer_block(SPI_HandleTypeDef* spi, uint8_t* tx_data, uint8_t* rx_data, size_t len) { +static inline bool +spi_xfer_block(SPI_HandleTypeDef* spi, uint8_t* tx_data, uint8_t* rx_data, size_t len) { semaphoreInfo s; osSemaphore block = createSemaphoreStatic(s); if(!spi_xfer(spi, tx_data, rx_data, len, RELEASE_SEMAPHORE, (void*)block)) { @@ -52,15 +56,15 @@ typedef struct { ValueMutex* bus; ///< } SpiDevice; -## SPI IRQ device +##SPI IRQ device -/* + /* Many devices (like CC1101 and NFC) present as SPI bus and IRQ line. For work with it there is special entity `SpiIrqDevice`. Use `subscribe_pubsub` for subscribinq to irq events. */ -typedef struct { + typedef struct { ValueMutex* bus; ///< PubSub* irq; } SpiIrqDevice; @@ -75,7 +79,6 @@ typedef struct { ValueMutex* spi; ///< } DisplayBus; - typedef struct { ValueMutex* bus; ///< } DisplayDevice; From 3020a2a6b9e04ca8e8a860b100e2ff8fb8c89212 Mon Sep 17 00:00:00 2001 From: aanper Date: Wed, 14 Oct 2020 10:26:23 +0300 Subject: [PATCH 03/12] wip cc1101 work --- applications/applications.mk | 3 +- ...101-workaround.c => cc1101-workaround.cpp} | 211 +++++++++--------- applications/display-u8g2/display-u8g2.c | 2 +- firmware/targets/f2/Inc/main.h | 2 + 4 files changed, 115 insertions(+), 103 deletions(-) rename applications/cc1101-workaround/{cc1101-workaround.c => cc1101-workaround.cpp} (68%) diff --git a/applications/applications.mk b/applications/applications.mk index 2856dc08..f9c153da 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -70,7 +70,8 @@ endif APP_CC1101 ?= 0 ifeq ($(APP_CC1101), 1) CFLAGS += -DAPP_CC1101 -C_SOURCES += $(APP_DIR)/cc1101-workaround/cc1101-workaround.c +CPP_SOURCES += $(APP_DIR)/cc1101-workaround/cc1101-workaround.cpp +CPP_SOURCES += $(APP_DIR)/cc1101-workaround/cc1101.cpp APP_INPUT = 1 APP_DISPLAY = 1 endif diff --git a/applications/cc1101-workaround/cc1101-workaround.c b/applications/cc1101-workaround/cc1101-workaround.cpp similarity index 68% rename from applications/cc1101-workaround/cc1101-workaround.c rename to applications/cc1101-workaround/cc1101-workaround.cpp index f3f3e366..e9b7c4fb 100644 --- a/applications/cc1101-workaround/cc1101-workaround.c +++ b/applications/cc1101-workaround/cc1101-workaround.cpp @@ -2,7 +2,7 @@ #include "u8g2.h" #include -#include "cc1101/cc1101.h" +#include "cc1101-workaround/cc1101.h" #define MIN_DBM -120 #define STEP_DBM 10 @@ -13,44 +13,51 @@ #define START_SUB_BAND 3 #define STOP_SUB_BAND 3 #define NUM_OF_SUB_BANDS 7 -#define CAL_INT 20 //cal every 10 channels(every 1MHz) +#define CAL_INT 20 // cal every 10 channels(every 1MHz) -//variables used to calculate rssi +// 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 +#define CHAN_SPA 0.05 // channel spacing float base_freq[NUM_OF_SUB_BANDS] = {387, 399.8, 412.6, 425.4, 438.2, 451, 463.8}; -//FREQ2,FREQ1,FREQ0 + +// FREQ2,FREQ1,FREQ0 uint8_t freqSettings[NUM_OF_SUB_BANDS][3] = { - {0x0E, 0xE2, 0x76}, //band0 + {0x0E, 0xE2, 0x76}, // band0 {0x0F, 0x60, 0x76}, - {0x0F, 0xDE, 0x76}, //band1 + {0x0F, 0xDE, 0x76}, // band1 {0x10, 0x5C, 0x76}, {0x10, 0xDA, 0x76}, {0x11, 0x58, 0x8F}, - {0x11, 0xD6, 0x8F}}; //band2 -//no change in TEST0 WHERE (>430.5MHz) one should change from TEST0=0x0B to 0x09 + {0x11, 0xD6, 0x8F}}; // band2 + +// 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 rssiData[NUM_OF_SUB_BANDS][256]; int16_t rssiTable[256]; uint16_t channelNumber[256]; -uint8_t carrierSenseCounter = 0; //counter used to keep track on how many CS has been asserted + +// counter used to keep track on how many CS has been asserted +uint8_t carrierSenseCounter = 0; uint8_t firstChannel[NUM_OF_SUB_BANDS] = {0, 0, 0, 160, 0, 0, 0}; -//stop channel in each subband + +// stop channel in each subband uint8_t lastChannel[NUM_OF_SUB_BANDS] = {255, 255, 255, 180, 255, 255, 4}; -//initialized to a value lower than the rssi threshold/ higher than channel number + +// initialized to a value lower than the rssi threshold/ higher than channel number int16_t highRSSI[NUM_OF_SUB_BANDS] = {MIN_DBM, MIN_DBM, MIN_DBM, MIN_DBM, MIN_DBM, MIN_DBM, MIN_DBM}; + uint16_t selectedChannel[NUM_OF_SUB_BANDS] = {300, 300, 300, 300, 300, 300, 300}; -int8_t activeBand; //store subband that contains strongest signal -uint16_t activeChannel; // +int8_t activeBand; // store subband that contains strongest signal +uint16_t activeChannel; int16_t calRSSI(uint8_t rssi_dec, uint8_t rssiOffset) { int16_t rssi; @@ -65,33 +72,33 @@ int16_t calRSSI(uint8_t rssi_dec, uint8_t rssiOffset) { } void scanFreq(CC1101* cc1101) { - uint8_t calCounter; //to deterin when to calibrate + uint8_t calCounter; // to determine when to calibrate uint8_t subBand; uint16_t channel; uint16_t i; float freq; - 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 + 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 + // 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 + // 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 + // 1.4.1) set channel register cc1101->SetChannel(channel); - //1.4.2) set TEST0 + // 1.4.2) set TEST0 if(channel == limitTest0Reg[subBand]) { //set test0 to 0x09 cc1101->SpiWriteReg(CC1101_TEST0, 0x09); @@ -100,18 +107,18 @@ void scanFreq(CC1101* cc1101) { //clear calCounter to invoke mannual calibration calCounter = 0; } - //1.4.3) calibrate every 1MHz + // 1.4.3) calibrate every 1MHz if(calCounter++ == 0) { - //perform a manual calibration by issuing SCAL command + // perform a manual calibration by issuing SCAL command cc1101->SpiStrobe(CC1101_SCAL); } - //1.4.4) reset calCounter when 1MHz reached + // 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 + // 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); @@ -122,9 +129,9 @@ void scanFreq(CC1101* cc1101) { rssi_dec = (uint8_t)cc1101->SpiReadStatus(CC1101_RSSI); rssi_dBm = calRSSI(rssi_dec, rssi_offset[subBand]); - //rssiData[subBand][channel]=rssi_dBm; + // rssiData[subBand][channel]=rssi_dBm; if(pktStatus & 0x40) { //CS assearted - //store rssi value and corresponding channel number + // store rssi value and corresponding channel number rssiTable[carrierSenseCounter] = rssi_dBm; channelNumber[carrierSenseCounter] = channel; carrierSenseCounter++; @@ -133,27 +140,29 @@ void scanFreq(CC1101* cc1101) { #ifdef CC1101_DEBUG printf("rssi_dBm: %d\n", rssi_dBm); #endif - } //end channel lop + } // end channel lop - //1.5)before moving to next sub band, scan through rssiTable to find highest rssi value + // 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]; } } - // Serial.print("subBand:------------------>"); + + // printf("subBand:------------------>"); // Serial.println(subBand); // Serial.print("selectedChannel:"); // Serial.println(selectedChannel[subBand]); // Serial.print("highRSSI:"); // Serial.println(highRSSI[subBand]); - //1.6) reset carrierSenseCounter + // 1.6) reset carrierSenseCounter carrierSenseCounter = 0; } // end band loop - //2) when all sub bands has been scanned , find best subband and channel + // 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) { @@ -180,16 +189,20 @@ void jamming(CC1101* cc1101, uint8_t band, uint16_t channel, uint16_t miniSec) { cc1101->SpiStrobe(CC1101_SIDLE); } -extern QueueHandle_t event_queue; +extern "C" void cc1101_workaround(void* p) { + FuriRecordSubscriber* fb_record = + furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); -bool jamm_on = false; + if(fb_record == NULL) { + printf("[cc1101] cannot create fb record\n"); + furiac_exit(NULL); + } -void set_jam(bool state) { - jamm_on = state; -} + printf("[cc1101] creating device\n"); -extern "C" void radio() { - CC1101 cc1101(SS_PIN, GDO0, GDO2); + CC1101 cc1101(GpioPin{CC1101_CS_GPIO_Port, CC1101_CS_Pin}); + + printf("[cc1101] init device\n"); uint8_t address = cc1101.Init(); @@ -199,66 +212,17 @@ extern "C" void radio() { printf("CC1101 init fail\n"); } - /* setting to use 50khz channel spacing**************************************/ - cc1101.SpiWriteReg( - CC1101_MDMCFG4, 0xCD); // RX filter bandwidth 58.035714(0xFD) 100k(0xCD) 200k(0x8D) - cc1101.SpiWriteReg( - CC1101_MDMCFG3, 0x3B); //datarate config 250kBaud for the purpose of fast rssi measurement - cc1101.SpiWriteReg(CC1101_MDMCFG1, 0x20); //FEC preamble etc. last 2 bits for channel spacing - cc1101.SpiWriteReg(CC1101_MDMCFG0, 0xF8); //50khz channel spacing - - Event event; - event.type = EventTypeRadio; + // RX filter bandwidth 58.035714(0xFD) 100k(0xCD) 200k(0x8D) + cc1101.SpiWriteReg(CC1101_MDMCFG4, 0xCD); + // datarate config 250kBaud for the purpose of fast rssi measurement + cc1101.SpiWriteReg(CC1101_MDMCFG3, 0x3B); + // FEC preamble etc. last 2 bits for channel spacing + cc1101.SpiWriteReg(CC1101_MDMCFG1, 0x20); + // 50khz channel spacing + cc1101.SpiWriteReg(CC1101_MDMCFG0, 0xF8); while(1) { - for(uint8_t i = 0; i <= NUM_OF_SUB_BANDS; i++) { - highRSSI[i] = MIN_DBM; - } - - activeChannel = 300; - - scanFreq(&cc1101); - - if(activeChannel < 256 && highRSSI[activeBand] > RSSI_THRESHOLD) { - float freq = base_freq[activeBand] + CHAN_SPA * activeChannel; - - /* - printf( - "channel: %d, freq: %d, RSSI: %d\n", - activeChannel, - (uint32_t)(freq * 1000), - highRSSI[activeBand] - ); - */ - - event.value.radio.freq = freq; - event.value.radio.rssi_db = highRSSI[activeBand]; - xQueueSend(event_queue, (void*)&event, 0); - - if(jamm_on) { - jamming(&cc1101, activeBand, activeChannel, 500); - } else { - osDelay(1000); - } - } else { - // printf("0 carrier sensed\n"); - } - - osDelay(1); - } -} - -void cc1101_workaround(void* p) { - FuriRecordSubscriber* fb_record = - furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); - - if(fb_record == NULL) { - printf("[cc1101] cannot create fb record\n"); - furiac_exit(NULL); - } - - while(1) { - u8g2_t* fb = furi_take(fb_record); + u8g2_t* fb = (u8g2_t*)furi_take(fb_record); if(fb != NULL) { u8g2_SetFont(fb, u8g2_font_6x10_mf); u8g2_SetDrawColor(fb, 1); @@ -267,6 +231,51 @@ void cc1101_workaround(void* p) { } furi_commit(fb_record); + /* + for(uint8_t i = 0; i <= NUM_OF_SUB_BANDS; i++) { + highRSSI[i] = MIN_DBM; + } + + activeChannel = 300; + + jamming(&cc1101, activeBand, activeChannel, 500); + + scanFreq(&cc1101); + + if(activeChannel < 256 && highRSSI[activeBand] > RSSI_THRESHOLD) { + float freq = base_freq[activeBand] + CHAN_SPA * activeChannel; + + printf( + "channel: %d, freq: %d, RSSI: %d\n", + activeChannel, + (uint32_t)(freq * 1000), + highRSSI[activeBand] + ); + + /* + if(jamm_on) { + jamming(&cc1101, activeBand, activeChannel, 500); + } else { + osDelay(1000); + } + * + } else { + // printf("0 carrier sensed\n"); + } + */ + + uint8_t band = 4; // 438.2 MHz + + /* + cc1101.SetFreq(freqSettings[band][0], freqSettings[band][1], freqSettings[band][2]); + cc1101.SetChannel(0); + cc1101.SetTransmit(); + + delay(5000); + + cc1101.SpiStrobe(CC1101_SIDLE); + */ + delay(1000); } } \ No newline at end of file diff --git a/applications/display-u8g2/display-u8g2.c b/applications/display-u8g2/display-u8g2.c index e2d0454c..c5f38aea 100644 --- a/applications/display-u8g2/display-u8g2.c +++ b/applications/display-u8g2/display-u8g2.c @@ -124,7 +124,7 @@ typedef struct { static void handle_fb_change(const void* fb, size_t fb_size, void* raw_ctx) { DisplayCtx* ctx = (DisplayCtx*)raw_ctx; // make right type - fuprintf(ctx->log, "[display_u8g2] change fb\n"); + // fuprintf(ctx->log, "[display_u8g2] change fb\n"); // send update to app thread xSemaphoreGive(ctx->update); diff --git a/firmware/targets/f2/Inc/main.h b/firmware/targets/f2/Inc/main.h index 6a96ec46..95b397fd 100644 --- a/firmware/targets/f2/Inc/main.h +++ b/firmware/targets/f2/Inc/main.h @@ -125,6 +125,8 @@ void Error_Handler(void); #define BUTTON_OK_EXTI_IRQn EXTI9_5_IRQn /* USER CODE BEGIN Private defines */ +#define MISO_PIN GpioPin{.port = GPIOC, .pin = GPIO_PIN_11} + /* USER CODE END Private defines */ #ifdef __cplusplus From 7c03ce179c197f6e22147114c9f8007e9408ed17 Mon Sep 17 00:00:00 2001 From: aanper Date: Sun, 18 Oct 2020 05:43:09 +0300 Subject: [PATCH 04/12] add cc1101 to build/menu --- applications/app-loader/app-loader.c | 2 + applications/applications.mk | 1 + .../cc1101-workaround/cc1101-workaround.cpp | 37 ++++++++++--------- applications/startup.h | 8 ---- core/flipper_v2.h | 10 +++++ 5 files changed, 32 insertions(+), 26 deletions(-) diff --git a/applications/app-loader/app-loader.c b/applications/app-loader/app-loader.c index 81a9d84c..0ebfcb37 100644 --- a/applications/app-loader/app-loader.c +++ b/applications/app-loader/app-loader.c @@ -49,11 +49,13 @@ void handle_menu(void* _ctx) { void application_blink(void* p); void application_uart_write(void* p); void application_input_dump(void* p); +void cc1101_workaround(void* p); const FlipperStartupApp FLIPPER_APPS[] = { {.app = application_blink, .name = "blink", .libs = {0}}, {.app = application_uart_write, .name = "uart write", .libs = {0}}, {.app = application_input_dump, .name = "input dump", .libs = {1, FURI_LIB{"input_task"}}}, + {.app = cc1101_workaround, .name = "cc1101 workaround", .libs = {1, FURI_LIB{"gui_task"}}}, }; void app_loader(void* p) { diff --git a/applications/applications.mk b/applications/applications.mk index 34c8e36e..911cccc8 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -21,6 +21,7 @@ C_SOURCES += $(wildcard $(APP_DIR)/app-loader/*.c) APP_EXAMPLE_BLINK = 1 APP_EXAMPLE_UART_WRITE = 1 APP_EXAMPLE_INPUT_DUMP = 1 +APP_CC1101 = 1 endif APP_TEST ?= 0 diff --git a/applications/cc1101-workaround/cc1101-workaround.cpp b/applications/cc1101-workaround/cc1101-workaround.cpp index e9b7c4fb..1e8158cc 100644 --- a/applications/cc1101-workaround/cc1101-workaround.cpp +++ b/applications/cc1101-workaround/cc1101-workaround.cpp @@ -1,6 +1,4 @@ #include "flipper.h" -#include "u8g2.h" -#include #include "cc1101-workaround/cc1101.h" @@ -189,14 +187,25 @@ void jamming(CC1101* cc1101, uint8_t band, uint16_t channel, uint16_t miniSec) { cc1101->SpiStrobe(CC1101_SIDLE); } -extern "C" void cc1101_workaround(void* p) { - FuriRecordSubscriber* fb_record = - furi_open_deprecated("u8g2_fb", false, false, NULL, NULL, NULL); +void render_callback(CanvasApi* canvas, void* _ctx) { + canvas->clear(canvas); + canvas->set_color(canvas, ColorBlack); + canvas->set_font(canvas, FontPrimary); + canvas->draw_str(canvas, 2, 12, "cc1101 workaround"); +} - if(fb_record == NULL) { - printf("[cc1101] cannot create fb record\n"); +extern "C" void cc1101_workaround(void* p) { + Widget* widget = widget_alloc(); + + widget_draw_callback_set(widget, render_callback, NULL); + + // Open GUI and register widget + GuiApi* gui = furi_open("gui"); + if(gui == NULL) { + printf("gui is not available\n"); furiac_exit(NULL); } + gui->add_widget(gui, state.widget, WidgetLayerFullscreen); printf("[cc1101] creating device\n"); @@ -207,9 +216,10 @@ extern "C" void cc1101_workaround(void* p) { uint8_t address = cc1101.Init(); if(address > 0) { - printf("CC1101 init done: %d\n", address); + printf("[cc1101] init done: %d\n", address); } else { - printf("CC1101 init fail\n"); + printf("[cc1101] init fail\n"); + furiac_exit(NULL); } // RX filter bandwidth 58.035714(0xFD) 100k(0xCD) 200k(0x8D) @@ -222,15 +232,6 @@ extern "C" void cc1101_workaround(void* p) { cc1101.SpiWriteReg(CC1101_MDMCFG0, 0xF8); while(1) { - u8g2_t* fb = (u8g2_t*)furi_take(fb_record); - if(fb != NULL) { - u8g2_SetFont(fb, u8g2_font_6x10_mf); - u8g2_SetDrawColor(fb, 1); - u8g2_SetFontMode(fb, 1); - u8g2_DrawStr(fb, 2, 12, "cc1101 workaround"); - } - furi_commit(fb_record); - /* for(uint8_t i = 0; i <= NUM_OF_SUB_BANDS; i++) { highRSSI[i] = MIN_DBM; diff --git a/applications/startup.h b/applications/startup.h index d9c0e438..ff8000a0 100644 --- a/applications/startup.h +++ b/applications/startup.h @@ -20,7 +20,6 @@ void input_task(void* p); void menu_task(void* p); void coreglitch_demo_0(void* p); -void cc1101_workaround(void* p); void u8g2_qrcode(void* p); void fatfs_list(void* p); @@ -69,11 +68,4 @@ const FlipperStartupApp FLIPPER_STARTUP[] = { #ifdef APP_EXAMPLE_DISPLAY {.app = u8g2_example, .name = "u8g2_example", .libs = {1, FURI_LIB{"display_u8g2"}}}, #endif - -#ifdef APP_CC1101 - {.app = cc1101_workaround, - .name = "cc1101_workaround", - .libs = {2, FURI_LIB{"display_u8g2", "input_task"}}}, -#endif - }; diff --git a/core/flipper_v2.h b/core/flipper_v2.h index 6d3fa47f..ca362468 100644 --- a/core/flipper_v2.h +++ b/core/flipper_v2.h @@ -2,6 +2,10 @@ #include "flipper.h" +#ifdef __cplusplus +extern "C" { +#endif + #include "api-basic/furi.h" //#include "api-basic/flapp.h" #include "cmsis_os2.h" @@ -9,3 +13,9 @@ #include "api-basic/pubsub.h" #include "api-basic/memmgr.h" + +#include "gui/gui.h" + +#ifdef __cplusplus +} +#endif \ No newline at end of file From 568143537ddb35739f29acc2cdf743cd30952c7a Mon Sep 17 00:00:00 2001 From: aanper Date: Sun, 18 Oct 2020 05:52:11 +0300 Subject: [PATCH 05/12] build ok, issue with display --- applications/applications.mk | 4 +- .../cc1101-workaround/cc1101-workaround.cpp | 6 +- applications/cc1101-workaround/cc1101.cpp | 396 ++++++++++++++++++ applications/cc1101-workaround/cc1101.h | 166 ++++++++ 4 files changed, 567 insertions(+), 5 deletions(-) create mode 100644 applications/cc1101-workaround/cc1101.cpp create mode 100644 applications/cc1101-workaround/cc1101.h diff --git a/applications/applications.mk b/applications/applications.mk index 911cccc8..bb237f3b 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -87,8 +87,8 @@ endif APP_CC1101 ?= 0 ifeq ($(APP_CC1101), 1) CFLAGS += -DAPP_CC1101 -CPP_SOURCES += $(APP_DIR)/cc1101-workaround/cc1101-workaround.cpp -CPP_SOURCES += $(APP_DIR)/cc1101-workaround/cc1101.cpp +C_SOURCES += $(wildcard $(APP_DIR)/cc1101-workaround/*.c) +CPP_SOURCES += $(wildcard $(APP_DIR)/cc1101-workaround/*.cpp) APP_INPUT = 1 APP_DISPLAY = 1 endif diff --git a/applications/cc1101-workaround/cc1101-workaround.cpp b/applications/cc1101-workaround/cc1101-workaround.cpp index 1e8158cc..f0334731 100644 --- a/applications/cc1101-workaround/cc1101-workaround.cpp +++ b/applications/cc1101-workaround/cc1101-workaround.cpp @@ -200,12 +200,12 @@ extern "C" void cc1101_workaround(void* p) { widget_draw_callback_set(widget, render_callback, NULL); // Open GUI and register widget - GuiApi* gui = furi_open("gui"); + GuiApi* gui = (GuiApi*)furi_open("gui"); if(gui == NULL) { printf("gui is not available\n"); furiac_exit(NULL); } - gui->add_widget(gui, state.widget, WidgetLayerFullscreen); + gui->add_widget(gui, widget, WidgetLayerFullscreen); printf("[cc1101] creating device\n"); @@ -253,7 +253,7 @@ extern "C" void cc1101_workaround(void* p) { highRSSI[activeBand] ); - /* + * if(jamm_on) { jamming(&cc1101, activeBand, activeChannel, 500); } else { diff --git a/applications/cc1101-workaround/cc1101.cpp b/applications/cc1101-workaround/cc1101.cpp new file mode 100644 index 00000000..9baef3f7 --- /dev/null +++ b/applications/cc1101-workaround/cc1101.cpp @@ -0,0 +1,396 @@ +#include "flipper_v2.h" +#include "cc1101-workaround/cc1101.h" + +// ****************************************************************************** +#define WRITE_BURST 0x40 +#define READ_SINGLE 0x80 +#define READ_BURST 0xC0 +#define BYTES_IN_FIFO 0x7F //used to detect FIFO underflow or overflow + +/*********************ss_pin as global variable****************************** */ +/* cc1101 */ +/******************************************************************************/ +GpioPin ss_pin; + +CC1101::CC1101(GpioPin ss_pin) { + /* + pinMode(gdo0_pin, OUTPUT); //GDO0 as asynchronous serial mode input + pinMode(gdo2_pin, INPUT); //GDO2 as asynchronous serial mode output + */ + pinMode(ss_pin, OUTPUT); + this->ss_pin = ss_pin; +} +//****************************************************************************** +//SpiInit +/******************************************************************************/ +void CC1101::SpiInit(void) { + //initialize spi pins + + //Enable spi master, MSB, SPI mode 0, FOSC/4 + SpiMode(0); +} + +void CC1101::SpiEnd(void) { + /* + SPCR = ((0< Date: Sun, 18 Oct 2020 07:10:15 +0300 Subject: [PATCH 06/12] gui, navigate over freqs --- applications/app-loader/app-loader.c | 8 +- applications/applications.mk | 2 +- .../cc1101-workaround/cc1101-workaround.cpp | 197 ++++++++++++++---- 3 files changed, 164 insertions(+), 43 deletions(-) diff --git a/applications/app-loader/app-loader.c b/applications/app-loader/app-loader.c index 0ebfcb37..11aed885 100644 --- a/applications/app-loader/app-loader.c +++ b/applications/app-loader/app-loader.c @@ -13,7 +13,9 @@ typedef struct { FlipperStartupApp* app; } AppLoaderContext; -void render_callback(CanvasApi* canvas, void* _ctx) { +// TODO add mutex for contex + +static void render_callback(CanvasApi* canvas, void* _ctx) { AppLoaderState* ctx = (AppLoaderState*)_ctx; canvas->clear(canvas); @@ -25,7 +27,7 @@ void render_callback(CanvasApi* canvas, void* _ctx) { canvas->draw_str(canvas, 2, 44, "press back to exit"); } -void input_callback(InputEvent* input_event, void* _ctx) { +static void input_callback(InputEvent* input_event, void* _ctx) { AppLoaderState* ctx = (AppLoaderState*)_ctx; if(input_event->state && input_event->input == InputBack) { @@ -34,7 +36,7 @@ void input_callback(InputEvent* input_event, void* _ctx) { } } -void handle_menu(void* _ctx) { +static void handle_menu(void* _ctx) { AppLoaderContext* ctx = (AppLoaderContext*)_ctx; widget_enabled_set(ctx->state->widget, true); diff --git a/applications/applications.mk b/applications/applications.mk index bb237f3b..869666c0 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -90,7 +90,7 @@ CFLAGS += -DAPP_CC1101 C_SOURCES += $(wildcard $(APP_DIR)/cc1101-workaround/*.c) CPP_SOURCES += $(wildcard $(APP_DIR)/cc1101-workaround/*.cpp) APP_INPUT = 1 -APP_DISPLAY = 1 +APP_GUI = 1 endif # device drivers diff --git a/applications/cc1101-workaround/cc1101-workaround.cpp b/applications/cc1101-workaround/cc1101-workaround.cpp index f0334731..79b06f0a 100644 --- a/applications/cc1101-workaround/cc1101-workaround.cpp +++ b/applications/cc1101-workaround/cc1101-workaround.cpp @@ -20,18 +20,6 @@ uint8_t rssi_offset[NUM_OF_SUB_BANDS] = {74, 74, 74, 74, 74, 74, 74}; #define CHAN_SPA 0.05 // channel spacing -float base_freq[NUM_OF_SUB_BANDS] = {387, 399.8, 412.6, 425.4, 438.2, 451, 463.8}; - -// FREQ2,FREQ1,FREQ0 -uint8_t freqSettings[NUM_OF_SUB_BANDS][3] = { - {0x0E, 0xE2, 0x76}, // band0 - {0x0F, 0x60, 0x76}, - {0x0F, 0xDE, 0x76}, // band1 - {0x10, 0x5C, 0x76}, - {0x10, 0xDA, 0x76}, - {0x11, 0x58, 0x8F}, - {0x11, 0xD6, 0x8F}}; // band2 - // 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}; @@ -43,19 +31,6 @@ uint16_t channelNumber[256]; // counter used to keep track on how many CS has been asserted uint8_t carrierSenseCounter = 0; -uint8_t firstChannel[NUM_OF_SUB_BANDS] = {0, 0, 0, 160, 0, 0, 0}; - -// stop channel in each subband -uint8_t lastChannel[NUM_OF_SUB_BANDS] = {255, 255, 255, 180, 255, 255, 4}; - -// initialized to a value lower than the rssi threshold/ higher than channel number -int16_t highRSSI[NUM_OF_SUB_BANDS] = - {MIN_DBM, MIN_DBM, MIN_DBM, MIN_DBM, MIN_DBM, MIN_DBM, MIN_DBM}; - -uint16_t selectedChannel[NUM_OF_SUB_BANDS] = {300, 300, 300, 300, 300, 300, 300}; - -int8_t activeBand; // store subband that contains strongest signal -uint16_t activeChannel; int16_t calRSSI(uint8_t rssi_dec, uint8_t rssiOffset) { int16_t rssi; @@ -69,6 +44,7 @@ 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; @@ -177,7 +153,7 @@ void scanFreq(CC1101* cc1101) { cc1101->SpiWriteReg(CC1101_AGCCTRL0, 0x91); //back to recommended config } -void jamming(CC1101* cc1101, uint8_t band, uint16_t channel, uint16_t miniSec) { +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); @@ -186,35 +162,146 @@ void jamming(CC1101* cc1101, uint8_t band, uint16_t channel, uint16_t miniSec) { cc1101->SpiStrobe(CC1101_SIDLE); } +*/ + +typedef struct { + float base_freq; + uint8_t settings[3]; // FREQ2, FREQ1, FREQ0 + uint8_t first_channel; + uint8_t last_channel; +} Band; + +typedef struct { + Band* band; + uint16_t channel; +} FreqConfig; + +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}, +}; + +FreqConfig FREQ_LIST[] = { + {&bands[0], 0}, + {&bands[0], 50}, + {&bands[0], 100}, + {&bands[0], 150}, + {&bands[0], 200}, + {&bands[1], 0}, + {&bands[1], 50}, + {&bands[1], 100}, + {&bands[1], 150}, + {&bands[1], 200}, + {&bands[2], 0}, + {&bands[2], 50}, + {&bands[2], 100}, + {&bands[2], 150}, + {&bands[2], 200}, + {&bands[3], 160}, + {&bands[3], 170}, + {&bands[4], 0}, + {&bands[4], 50}, + {&bands[4], 100}, + {&bands[4], 150}, + {&bands[4], 200}, + {&bands[5], 0}, + {&bands[5], 50}, + {&bands[5], 100}, + {&bands[5], 150}, + {&bands[5], 200}, + {&bands[6], 0}, +}; + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + union { + InputEvent input; + } value; + EventType type; +} Event; + +typedef enum { + ModeRx, + ModeTx +} Mode; + +typedef struct { + Mode mode; + size_t active_freq; +} State; + +static void render_callback(CanvasApi* canvas, void* ctx) { + State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); -void render_callback(CanvasApi* canvas, void* _ctx) { canvas->clear(canvas); canvas->set_color(canvas, ColorBlack); canvas->set_font(canvas, FontPrimary); canvas->draw_str(canvas, 2, 12, "cc1101 workaround"); + + { + char buf[24]; + FreqConfig conf = FREQ_LIST[state->active_freq]; + float freq = conf.band->base_freq + CHAN_SPA * conf.channel; + sprintf(buf, "freq: %ld.%02ld MHz", (uint32_t)freq, (uint32_t)(freq * 100.) % 100); + + canvas->set_font(canvas, FontSecondary); + canvas->draw_str(canvas, 2, 25, buf); + } + + release_mutex((ValueMutex*)ctx, state); +} + +static void input_callback(InputEvent* input_event, void* ctx) { + osMessageQueueId_t event_queue = (QueueHandle_t)ctx; + + Event event; + event.type = EventTypeKey; + event.value.input = *input_event; + osMessageQueuePut(event_queue, &event, 0, 0); } extern "C" void cc1101_workaround(void* p) { + osMessageQueueId_t event_queue = + osMessageQueueNew(1, sizeof(Event), NULL); + assert(event_queue); + + State _state; + _state.mode = ModeRx; + _state.active_freq = 0; + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, &_state, sizeof(State))) { + printf("[cc1101] cannot create mutex\n"); + furiac_exit(NULL); + } + Widget* widget = widget_alloc(); - widget_draw_callback_set(widget, render_callback, NULL); + widget_draw_callback_set(widget, render_callback, &state_mutex); + widget_input_callback_set(widget, input_callback, event_queue); // Open GUI and register widget GuiApi* gui = (GuiApi*)furi_open("gui"); if(gui == NULL) { - printf("gui is not available\n"); + printf("[cc1101] gui is not available\n"); furiac_exit(NULL); } gui->add_widget(gui, widget, WidgetLayerFullscreen); printf("[cc1101] creating device\n"); - CC1101 cc1101(GpioPin{CC1101_CS_GPIO_Port, CC1101_CS_Pin}); - printf("[cc1101] init device\n"); uint8_t address = cc1101.Init(); - if(address > 0) { printf("[cc1101] init done: %d\n", address); } else { @@ -231,15 +318,46 @@ extern "C" void cc1101_workaround(void* p) { // 50khz channel spacing cc1101.SpiWriteReg(CC1101_MDMCFG0, 0xF8); + Event event; + while(1) { + if(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) { + State* state = (State*)acquire_mutex_block(&state_mutex); + + if(event.type == EventTypeKey) { + if(event.value.input.state && event.value.input.input == InputBack) { + printf("[cc1101] bye!\n"); + // TODO remove all widgets create by app + widget_enabled_set(widget, false); + furiac_exit(NULL); + } + + if(event.value.input.state && event.value.input.input == InputUp) { + if(state->active_freq > 0) { + state->active_freq--; + } + } + + 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++; + } + } + } + + release_mutex(&state_mutex, state); + widget_update(widget); + } + } + + /* while(1) { - /* for(uint8_t i = 0; i <= NUM_OF_SUB_BANDS; i++) { highRSSI[i] = MIN_DBM; } activeChannel = 300; - jamming(&cc1101, activeBand, activeChannel, 500); + tx(&cc1101, activeBand, activeChannel, 500); scanFreq(&cc1101); @@ -254,8 +372,8 @@ extern "C" void cc1101_workaround(void* p) { ); * - if(jamm_on) { - jamming(&cc1101, activeBand, activeChannel, 500); + if(tx_on) { + tx(&cc1101, activeBand, activeChannel, 500); } else { osDelay(1000); } @@ -263,11 +381,11 @@ extern "C" void cc1101_workaround(void* p) { } else { // printf("0 carrier sensed\n"); } - */ + * uint8_t band = 4; // 438.2 MHz - /* + * cc1101.SetFreq(freqSettings[band][0], freqSettings[band][1], freqSettings[band][2]); cc1101.SetChannel(0); cc1101.SetTransmit(); @@ -275,8 +393,9 @@ extern "C" void cc1101_workaround(void* p) { delay(5000); cc1101.SpiStrobe(CC1101_SIDLE); - */ + * delay(1000); } + */ } \ No newline at end of file From 6b5797bbf49fe704d563a3b01b9320dd51dac8d9 Mon Sep 17 00:00:00 2001 From: aanper Date: Sun, 18 Oct 2020 07:47:49 +0300 Subject: [PATCH 07/12] rx example --- .../cc1101-workaround/cc1101-workaround.cpp | 283 ++++++++---------- 1 file changed, 126 insertions(+), 157 deletions(-) diff --git a/applications/cc1101-workaround/cc1101-workaround.cpp b/applications/cc1101-workaround/cc1101-workaround.cpp index 79b06f0a..f149c0bc 100644 --- a/applications/cc1101-workaround/cc1101-workaround.cpp +++ b/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,131 +18,12 @@ 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; - - float freq; - - 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]; - } - } - - // 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; - } - } - - // printf("activeBand:**********> %d, activeChannel %d,\n", activeBand, activeChannel); - - 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); - - cc1101->SpiStrobe(CC1101_SIDLE); -} -*/ - typedef struct { float base_freq; - uint8_t settings[3]; // FREQ2, FREQ1, FREQ0 + uint8_t reg[3]; // FREQ2, FREQ1, FREQ0 uint8_t first_channel; uint8_t last_channel; + uint8_t rssi_offset; } Band; typedef struct { @@ -176,14 +31,65 @@ typedef struct { 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 + + cc1101->SetFreq(config->band->reg[0], config->band->reg[1], config->band->reg[2]); + cc1101->SetChannel(config->channel); + + //set test0 to 0x09 + cc1101->SpiWriteReg(CC1101_TEST0, 0x09); + //set FSCAL2 to 0x2A to force VCO HIGH + cc1101->SpiWriteReg(CC1101_FSCAL2, 0x2A); + + // 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 + */ +} + +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; +} + +void tx(CC1101* cc1101) { + cc1101->SetTransmit(); +} + +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); } From e217029fcc85e2c72b9171a1ad660d1c3cee9752 Mon Sep 17 00:00:00 2001 From: aanper Date: Sun, 18 Oct 2020 10:47:38 +0300 Subject: [PATCH 08/12] tx not work properly --- .../cc1101-workaround/cc1101-workaround.cpp | 80 ++++++++++++++----- 1 file changed, 62 insertions(+), 18 deletions(-) diff --git a/applications/cc1101-workaround/cc1101-workaround.cpp b/applications/cc1101-workaround/cc1101-workaround.cpp index f149c0bc..5f235aa8 100644 --- a/applications/cc1101-workaround/cc1101-workaround.cpp +++ b/applications/cc1101-workaround/cc1101-workaround.cpp @@ -27,11 +27,11 @@ typedef struct { } Band; typedef struct { - Band* band; + const Band* band; uint16_t channel; } FreqConfig; -void setup_freq(CC1101* cc1101, FreqConfig* config) { +void setup_freq(CC1101* cc1101, const 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 @@ -47,16 +47,9 @@ void setup_freq(CC1101* cc1101, FreqConfig* config) { // 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 - */ } -int16_t rx_rssi(CC1101* cc1101, FreqConfig* config) { +int16_t rx_rssi(CC1101* cc1101, const FreqConfig* config) { cc1101->SetReceive(); delayMicroseconds(RSSI_DELAY); @@ -74,7 +67,14 @@ int16_t rx_rssi(CC1101* cc1101, FreqConfig* config) { return rssi_dBm; } -void tx(CC1101* cc1101) { +void tx(CC1101* cc1101, const FreqConfig* config) { + 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 + + cc1101->SetFreq(config->band->reg[0], config->band->reg[1], config->band->reg[2]); + cc1101->SetChannel(config->channel); + cc1101->SetTransmit(); } @@ -82,7 +82,7 @@ void idle(CC1101* cc1101) { cc1101->SpiStrobe(CC1101_SIDLE); } -Band bands[NUM_OF_SUB_BANDS] = { +const Band bands[NUM_OF_SUB_BANDS] = { {387, {0x0E, 0xE2, 0x76}, 0, 255, 74}, {399.8, {0x0F, 0x60, 0x76}, 0, 255, 74}, {412.6, {0x0F, 0xDE, 0x76}, 0, 255, 74}, @@ -92,7 +92,7 @@ Band bands[NUM_OF_SUB_BANDS] = { {463.8, {0x11, 0xD6, 0x8F}, 0, 4, 74}, }; -FreqConfig FREQ_LIST[] = { +const FreqConfig FREQ_LIST[] = { {&bands[0], 0}, {&bands[0], 50}, {&bands[0], 100}, @@ -140,10 +140,23 @@ typedef enum { ModeTx } Mode; +typedef struct { + int16_t dbm; + uint8_t reg; +} TxLevel; + +const TxLevel TX_LEVELS[] = { + {-10, 0}, + {-5, 0}, + {0, 0}, + {5, 0}, +}; + typedef struct { Mode mode; size_t active_freq; int16_t last_rssi; + size_t tx_level; bool need_cc1101_conf; } State; @@ -189,6 +202,16 @@ static void render_callback(CanvasApi* canvas, void* ctx) { } } + { + char buf[24]; + sprintf(buf, "tx level: %d dBm", TX_LEVELS[state->tx_level].dbm); + + canvas->set_font(canvas, FontSecondary); + canvas->draw_str(canvas, 2, 63, buf); + } + + + release_mutex((ValueMutex*)ctx, state); } @@ -211,6 +234,7 @@ extern "C" void cc1101_workaround(void* p) { _state.active_freq = 0; _state.need_cc1101_conf = true; _state.last_rssi = 0; + _state.tx_level = 0; ValueMutex state_mutex; if(!init_mutex(&state_mutex, &_state, sizeof(State))) { @@ -286,21 +310,38 @@ extern "C" void cc1101_workaround(void* p) { state->need_cc1101_conf = true; } } + + if(event.value.input.state && event.value.input.input == InputLeft) { + if(state->tx_level < (sizeof(TX_LEVELS)/sizeof(TX_LEVELS[0]) - 1)) { + state->tx_level++; + } else { + state->tx_level = 0; + } + + state->need_cc1101_conf = true; + } + + if(event.value.input.input == InputOk) { + state->mode = event.value.input.state ? ModeTx : ModeRx; + state->need_cc1101_conf = true; + } } if(state->need_cc1101_conf) { - setup_freq(&cc1101, &FREQ_LIST[state->active_freq]); - if(state->mode == ModeRx) { + setup_freq(&cc1101, &FREQ_LIST[state->active_freq]); state->last_rssi = rx_rssi(&cc1101, &FREQ_LIST[state->active_freq]); } else if(state->mode == ModeTx) { - tx(&cc1101); + tx(&cc1101, &FREQ_LIST[state->active_freq]); } state->need_cc1101_conf = false; } - digitalWrite(led, state->last_rssi > RSSI_THRESHOLD ? LOW : HIGH); + digitalWrite( + led, + (state->last_rssi > RSSI_THRESHOLD && !state->need_cc1101_conf) ? LOW : HIGH + ); release_mutex(&state_mutex, state); widget_update(widget); @@ -311,7 +352,10 @@ extern "C" void cc1101_workaround(void* p) { state->last_rssi = rx_rssi(&cc1101, &FREQ_LIST[state->active_freq]); } - digitalWrite(led, state->last_rssi > RSSI_THRESHOLD ? LOW : HIGH); + digitalWrite( + led, + (state->last_rssi > RSSI_THRESHOLD && !state->need_cc1101_conf) ? LOW : HIGH + ); release_mutex(&state_mutex, state); widget_update(widget); From 3b993578f48f7f444795c4f55315a108b71d456f Mon Sep 17 00:00:00 2001 From: aanper Date: Mon, 19 Oct 2020 09:22:38 +0300 Subject: [PATCH 09/12] release/cc1101 debug build --- applications/applications.mk | 10 ++++++++-- applications/startup.h | 5 +++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/applications/applications.mk b/applications/applications.mk index 869666c0..aff66448 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -3,7 +3,7 @@ LIB_DIR = $(PROJECT_ROOT)/lib CFLAGS += -I$(APP_DIR) -APP_RELEASE ?= 0 +APP_RELEASE ?= 1 ifeq ($(APP_RELEASE), 1) APP_GUI = 1 APP_INPUT = 1 @@ -21,7 +21,6 @@ C_SOURCES += $(wildcard $(APP_DIR)/app-loader/*.c) APP_EXAMPLE_BLINK = 1 APP_EXAMPLE_UART_WRITE = 1 APP_EXAMPLE_INPUT_DUMP = 1 -APP_CC1101 = 1 endif APP_TEST ?= 0 @@ -93,6 +92,13 @@ APP_INPUT = 1 APP_GUI = 1 endif +ifeq ($(APP_RELEASE), 1) +C_SOURCES += $(wildcard $(APP_DIR)/cc1101-workaround/*.c) +CPP_SOURCES += $(wildcard $(APP_DIR)/cc1101-workaround/*.cpp) +APP_INPUT = 1 +APP_GUI = 1 +endif + # device drivers APP_GUI ?= 0 ifeq ($(APP_GUI), 1) diff --git a/applications/startup.h b/applications/startup.h index ff8000a0..aaf55c64 100644 --- a/applications/startup.h +++ b/applications/startup.h @@ -26,6 +26,7 @@ void fatfs_list(void* p); void gui_task(void* p); void backlight_control(void* p); void app_loader(void* p); +void cc1101_workaround(void* p); const FlipperStartupApp FLIPPER_STARTUP[] = { #ifdef APP_DISPLAY @@ -46,6 +47,10 @@ const FlipperStartupApp FLIPPER_STARTUP[] = { {.app = app_loader, .name = "app_loader", .libs = {1, FURI_LIB{"menu_task"}}}, #endif +#ifdef APP_CC1101 + {.app = cc1101_workaround, .name = "cc1101 workaround", .libs = {1, FURI_LIB{"gui_task"}}}, +#endif + // {.app = coreglitch_demo_0, .name = "coreglitch_demo_0", .libs = ""}, #ifdef APP_TEST From 6a647f0fa374e985d13a7db7e45cccc2dfdf3a5c Mon Sep 17 00:00:00 2001 From: aanper Date: Mon, 19 Oct 2020 09:22:56 +0300 Subject: [PATCH 10/12] fix tx mode (disable manual calibration) --- .../cc1101-workaround/cc1101-workaround.cpp | 62 +++++++++---------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/applications/cc1101-workaround/cc1101-workaround.cpp b/applications/cc1101-workaround/cc1101-workaround.cpp index 5f235aa8..61ba58d1 100644 --- a/applications/cc1101-workaround/cc1101-workaround.cpp +++ b/applications/cc1101-workaround/cc1101-workaround.cpp @@ -32,7 +32,7 @@ typedef struct { } FreqConfig; void setup_freq(CC1101* cc1101, const FreqConfig* config) { - cc1101->SpiWriteReg(CC1101_MCSM0, 0x08); // disalbe FS_AUTOCAL + // 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 @@ -40,6 +40,7 @@ void setup_freq(CC1101* cc1101, const FreqConfig* config) { cc1101->SetFreq(config->band->reg[0], config->band->reg[1], config->band->reg[2]); cc1101->SetChannel(config->channel); + /* //set test0 to 0x09 cc1101->SpiWriteReg(CC1101_TEST0, 0x09); //set FSCAL2 to 0x2A to force VCO HIGH @@ -47,6 +48,7 @@ void setup_freq(CC1101* cc1101, const FreqConfig* config) { // perform a manual calibration by issuing SCAL command cc1101->SpiStrobe(CC1101_SCAL); + */ } int16_t rx_rssi(CC1101* cc1101, const FreqConfig* config) { @@ -55,7 +57,7 @@ int16_t rx_rssi(CC1101* cc1101, const FreqConfig* config) { delayMicroseconds(RSSI_DELAY); // 1.4.8) read PKTSTATUS register while the radio is in RX state - uint8_t _pkt_status = cc1101->SpiReadStatus(CC1101_PKTSTATUS); + /*uint8_t _pkt_status = */ cc1101->SpiReadStatus(CC1101_PKTSTATUS); // 1.4.9) enter IDLE state by issuing a SIDLE command cc1101->SpiStrobe(CC1101_SIDLE); @@ -68,9 +70,11 @@ int16_t rx_rssi(CC1101* cc1101, const FreqConfig* config) { } void tx(CC1101* cc1101, const FreqConfig* config) { + /* 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 + */ cc1101->SetFreq(config->band->reg[0], config->band->reg[1], config->band->reg[2]); cc1101->SetChannel(config->channel); @@ -286,9 +290,10 @@ extern "C" void cc1101_workaround(void* p) { Event event; while(1) { - if(osMessageQueueGet(event_queue, &event, NULL, 150) == osOK) { - State* state = (State*)acquire_mutex_block(&state_mutex); + osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 150); + State* state = (State*)acquire_mutex_block(&state_mutex); + if(event_status == osOK) { if(event.type == EventTypeKey) { if(event.value.input.state && event.value.input.input == InputBack) { printf("[cc1101] bye!\n"); @@ -326,40 +331,31 @@ extern "C" void cc1101_workaround(void* p) { state->need_cc1101_conf = true; } } - - if(state->need_cc1101_conf) { - if(state->mode == ModeRx) { - setup_freq(&cc1101, &FREQ_LIST[state->active_freq]); - state->last_rssi = rx_rssi(&cc1101, &FREQ_LIST[state->active_freq]); - } else if(state->mode == ModeTx) { - tx(&cc1101, &FREQ_LIST[state->active_freq]); - } - - state->need_cc1101_conf = false; - } - - digitalWrite( - led, - (state->last_rssi > RSSI_THRESHOLD && !state->need_cc1101_conf) ? 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 && !state->need_cc1101_conf) ? LOW : HIGH - ); - - release_mutex(&state_mutex, state); - widget_update(widget); } + + if(state->need_cc1101_conf) { + if(state->mode == ModeRx) { + setup_freq(&cc1101, &FREQ_LIST[state->active_freq]); + state->last_rssi = rx_rssi(&cc1101, &FREQ_LIST[state->active_freq]); + // idle(&cc1101); + } else if(state->mode == ModeTx) { + tx(&cc1101, &FREQ_LIST[state->active_freq]); + } + + state->need_cc1101_conf = false; + } + + digitalWrite( + led, + (state->last_rssi > RSSI_THRESHOLD && !state->need_cc1101_conf) ? LOW : HIGH + ); + + release_mutex(&state_mutex, state); + widget_update(widget); } /* From 5bd5136972d5b22ffb24dc465da662bc7a8f9467 Mon Sep 17 00:00:00 2001 From: aanper Date: Mon, 19 Oct 2020 09:23:49 +0300 Subject: [PATCH 11/12] syntax check --- .../cc1101-workaround/cc1101-workaround.cpp | 58 +++++-------------- 1 file changed, 14 insertions(+), 44 deletions(-) diff --git a/applications/cc1101-workaround/cc1101-workaround.cpp b/applications/cc1101-workaround/cc1101-workaround.cpp index 61ba58d1..3f09a816 100644 --- a/applications/cc1101-workaround/cc1101-workaround.cpp +++ b/applications/cc1101-workaround/cc1101-workaround.cpp @@ -55,10 +55,10 @@ int16_t rx_rssi(CC1101* cc1101, const 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); @@ -97,34 +97,12 @@ const Band bands[NUM_OF_SUB_BANDS] = { }; const FreqConfig FREQ_LIST[] = { - {&bands[0], 0}, - {&bands[0], 50}, - {&bands[0], 100}, - {&bands[0], 150}, - {&bands[0], 200}, - {&bands[1], 0}, - {&bands[1], 50}, - {&bands[1], 100}, - {&bands[1], 150}, - {&bands[1], 200}, - {&bands[2], 0}, - {&bands[2], 50}, - {&bands[2], 100}, - {&bands[2], 150}, - {&bands[2], 200}, - {&bands[3], 160}, - {&bands[3], 170}, - {&bands[4], 0}, - {&bands[4], 50}, - {&bands[4], 100}, - {&bands[4], 150}, - {&bands[4], 200}, - {&bands[5], 0}, - {&bands[5], 50}, - {&bands[5], 100}, - {&bands[5], 150}, - {&bands[5], 200}, - {&bands[6], 0}, + {&bands[0], 0}, {&bands[0], 50}, {&bands[0], 100}, {&bands[0], 150}, {&bands[0], 200}, + {&bands[1], 0}, {&bands[1], 50}, {&bands[1], 100}, {&bands[1], 150}, {&bands[1], 200}, + {&bands[2], 0}, {&bands[2], 50}, {&bands[2], 100}, {&bands[2], 150}, {&bands[2], 200}, + {&bands[3], 160}, {&bands[3], 170}, {&bands[4], 0}, {&bands[4], 50}, {&bands[4], 100}, + {&bands[4], 150}, {&bands[4], 200}, {&bands[5], 0}, {&bands[5], 50}, {&bands[5], 100}, + {&bands[5], 150}, {&bands[5], 200}, {&bands[6], 0}, }; typedef enum { @@ -139,10 +117,7 @@ typedef struct { EventType type; } Event; -typedef enum { - ModeRx, - ModeTx -} Mode; +typedef enum { ModeRx, ModeTx } Mode; typedef struct { int16_t dbm; @@ -175,7 +150,7 @@ static void render_callback(CanvasApi* canvas, void* ctx) { { char buf[24]; FreqConfig conf = FREQ_LIST[state->active_freq]; - float freq = conf.band->base_freq + CHAN_SPA * conf.channel; + float freq = conf.band->base_freq + CHAN_SPA * conf.channel; sprintf(buf, "freq: %ld.%02ld MHz", (uint32_t)freq, (uint32_t)(freq * 100.) % 100); canvas->set_font(canvas, FontSecondary); @@ -214,8 +189,6 @@ static void render_callback(CanvasApi* canvas, void* ctx) { canvas->draw_str(canvas, 2, 63, buf); } - - release_mutex((ValueMutex*)ctx, state); } @@ -229,8 +202,7 @@ static void input_callback(InputEvent* input_event, void* ctx) { } extern "C" void cc1101_workaround(void* p) { - osMessageQueueId_t event_queue = - osMessageQueueNew(1, sizeof(Event), NULL); + osMessageQueueId_t event_queue = osMessageQueueNew(1, sizeof(Event), NULL); assert(event_queue); State _state; @@ -310,14 +282,14 @@ extern "C" void cc1101_workaround(void* p) { } if(event.value.input.state && event.value.input.input == InputDown) { - if(state->active_freq < (sizeof(FREQ_LIST)/sizeof(FREQ_LIST[0]) - 1)) { + if(state->active_freq < (sizeof(FREQ_LIST) / sizeof(FREQ_LIST[0]) - 1)) { state->active_freq++; state->need_cc1101_conf = true; } } if(event.value.input.state && event.value.input.input == InputLeft) { - if(state->tx_level < (sizeof(TX_LEVELS)/sizeof(TX_LEVELS[0]) - 1)) { + if(state->tx_level < (sizeof(TX_LEVELS) / sizeof(TX_LEVELS[0]) - 1)) { state->tx_level++; } else { state->tx_level = 0; @@ -350,9 +322,7 @@ extern "C" void cc1101_workaround(void* p) { } digitalWrite( - led, - (state->last_rssi > RSSI_THRESHOLD && !state->need_cc1101_conf) ? LOW : HIGH - ); + led, (state->last_rssi > RSSI_THRESHOLD && !state->need_cc1101_conf) ? LOW : HIGH); release_mutex(&state_mutex, state); widget_update(widget); From dc39be505bde22ce5663bf1202c515c38272c8c9 Mon Sep 17 00:00:00 2001 From: aanper Date: Mon, 19 Oct 2020 09:56:12 +0300 Subject: [PATCH 12/12] not build cc1101 in local build, app_release default in CI build --- .github/workflows/ci.yml | 2 +- applications/applications.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index acb79084..fa08c9d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,7 @@ jobs: - name: Build F2 firmware in docker uses: ./.github/actions/docker with: - run: make -C firmware TARGET=f2 + run: make -C firmware TARGET=f2 APP_RELEASE=1 - name: Publish F2 firmware artifacts uses: actions/upload-artifact@v2 diff --git a/applications/applications.mk b/applications/applications.mk index aff66448..001f812f 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -3,7 +3,7 @@ LIB_DIR = $(PROJECT_ROOT)/lib CFLAGS += -I$(APP_DIR) -APP_RELEASE ?= 1 +APP_RELEASE ?= 0 ifeq ($(APP_RELEASE), 1) APP_GUI = 1 APP_INPUT = 1