diff --git a/applications/applications.c b/applications/applications.c index 9a9b4e50..98e6e039 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -16,7 +16,6 @@ int32_t gui_task(void* p); int32_t backlight_control(void* p); int32_t irda(void* p); int32_t app_loader(void* p); -int32_t cc1101_workaround(void* p); int32_t lf_rfid_workaround(void* p); int32_t nfc_task(void* p); int32_t dolphin_task(void* p); @@ -31,7 +30,7 @@ int32_t music_player(void* p); int32_t sdnfc(void* p); int32_t floopper_bloopper(void* p); int32_t sd_filesystem(void* p); -int32_t app_subghz(void* p); +int32_t subghz_app(void* p); int32_t gui_test(void* p); int32_t keypad_test(void* p); @@ -82,13 +81,6 @@ const FlipperApplication FLIPPER_SERVICES[] = { {.app = bt_task, .name = "bt_task", .stack_size = 1024, .icon = A_Plugins_14}, #endif -#ifdef APP_CC1101 - {.app = cc1101_workaround, - .name = "cc1101 workaround", - .stack_size = 1024, - .icon = A_Plugins_14}, -#endif - #ifdef APP_LF_RFID {.app = lf_rfid_workaround, .name = "lf rfid workaround", @@ -151,10 +143,6 @@ const FlipperApplication FLIPPER_SERVICES[] = { {.app = gui_test, .name = "gui_test", .stack_size = 1024, .icon = A_Plugins_14}, #endif -#ifdef APP_SUBGHZ - {.app = app_subghz, .name = "app_subghz", .stack_size = 1024, .icon = A_Plugins_14}, -#endif - #ifdef APP_KEYPAD_TEST {.app = keypad_test, .name = "keypad_test", .icon = A_Plugins_14}, #endif @@ -164,8 +152,8 @@ const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperA // Main menu APP const FlipperApplication FLIPPER_APPS[] = { -#ifdef BUILD_CC1101 - {.app = cc1101_workaround, .name = "Sub-1 GHz", .stack_size = 1024, .icon = A_Sub1ghz_14}, +#ifdef BUILD_SUBGHZ + {.app = subghz_app, .name = "Sub-1 GHz", .stack_size = 1024, .icon = A_Sub1ghz_14}, #endif #ifdef BUILD_LF_RFID @@ -228,10 +216,6 @@ const FlipperApplication FLIPPER_PLUGINS[] = { {.app = gui_test, .name = "gui_test", .stack_size = 1024, .icon = A_Plugins_14}, #endif -#ifdef BUILD_SUBGHZ - {.app = app_subghz, .name = "app_subghz", .stack_size = 1024, .icon = A_Plugins_14}, -#endif - #ifdef BUILD_KEYPAD_TEST {.app = keypad_test, .name = "keypad_test", .icon = A_Plugins_14}, #endif diff --git a/applications/applications.mk b/applications/applications.mk index 02fd3fc2..9d0ef667 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -20,7 +20,7 @@ APP_DOLPHIN = 1 BUILD_EXAMPLE_BLINK = 1 BUILD_EXAMPLE_UART_WRITE = 1 BUILD_EXAMPLE_INPUT_DUMP = 1 -BUILD_CC1101 = 1 +BUILD_SUBGHZ = 1 BUILD_LF_RFID = 1 BUILD_SPEAKER_DEMO = 1 BUILD_VIBRO_DEMO = 1 @@ -31,7 +31,6 @@ BUILD_FLOOPPER_BLOOPPER = 1 BUILD_IBUTTON = 1 BUILD_GUI_TEST = 1 BUILD_KEYPAD_TEST = 1 -BUILD_SUBGHZ = 1 endif APP_NFC ?= 0 @@ -146,16 +145,9 @@ C_SOURCES += $(APP_DIR)/examples/u8g2_qrcode.c C_SOURCES += $(LIB_DIR)/qrcode/qrcode.c endif -APP_CC1101 ?= 0 -ifeq ($(APP_CC1101), 1) -CFLAGS += -DAPP_CC1101 -BUILD_CC1101 = 1 -endif -BUILD_CC1101 ?= 0 -ifeq ($(BUILD_CC1101), 1) -CFLAGS += -DBUILD_CC1101 -C_SOURCES += $(wildcard $(APP_DIR)/cc1101-workaround/*.c) -CPP_SOURCES += $(wildcard $(APP_DIR)/cc1101-workaround/*.cpp) +ifeq ($(BUILD_SUBGHZ), 1) +CFLAGS += -DBUILD_SUBGHZ +C_SOURCES += $(wildcard $(APP_DIR)/subghz/*.c) APP_INPUT = 1 APP_GUI = 1 APP_CLI = 1 @@ -292,18 +284,6 @@ CFLAGS += -DBUILD_GUI_TEST C_SOURCES += $(wildcard $(APP_DIR)/gui-test/*.c) endif -APP_SUBGHZ ?= 0 -ifeq ($(APP_SUBGHZ), 1) -CFLAGS += -DAPP_SUBGHZ -BUILD_SUBGHZ = 1 -endif -BUILD_SUBGHZ ?= 0 -ifeq ($(BUILD_SUBGHZ), 1) -CFLAGS += -DBUILD_SUBGHZ -CPP_SOURCES += $(wildcard $(APP_DIR)/subghz/*.cpp) -CPP_SOURCES += $(wildcard $(APP_DIR)/subghz/*/*.cpp) -endif - APP_SDNFC ?= 0 ifeq ($(APP_SDNFC), 1) CFLAGS += -DAPP_SDNFC diff --git a/applications/cc1101-workaround/cc1101-workaround.cpp b/applications/cc1101-workaround/cc1101-workaround.cpp deleted file mode 100644 index 5f849836..00000000 --- a/applications/cc1101-workaround/cc1101-workaround.cpp +++ /dev/null @@ -1,614 +0,0 @@ -#include "cc1101.h" -#include -#include -#include -#include - -#define RSSI_DELAY 5000 //rssi delay in micro second -#define CHAN_SPA 0.05 // channel spacing - -int16_t rssi_to_dbm(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; -} - -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; - -typedef struct { - const Band* band; - uint16_t channel; -} FreqConfig; - -void setup_freq(CC1101* cc1101, 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 - - uint32_t freq_reg = freq * 1e6 / (F_OSC / 65536); - cc1101->SetFreq((freq_reg >> 16) & 0xFF, (freq_reg >> 8) & 0xFF, (freq_reg)&0xFF); - cc1101->SetChannel(0); - - /* - //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); - */ -} - -static GpioPin debug_0 = {GPIOB, GPIO_PIN_2}; - -int16_t rx_rssi(CC1101* cc1101, const FreqConfig* config) { - // cc1101->SpiStrobe(CC1101_SFRX); - // cc1101->SetReceive(); - - // uint8_t begin_size = cc1101->SpiReadStatus(CC1101_RXBYTES); - // uint8_t rx_status = cc1101->SpiReadStatus(CC1101_MARCSTATE); - - // delay_us(RSSI_DELAY); - // osDelay(15); - - // uint8_t end_size = cc1101->SpiReadStatus(CC1101_RXBYTES); - - // 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); - - /* - char buf[256]; - sprintf(buf, "status: %d -> %d, rssi: %d\n", rx_status, cc1101->SpiReadStatus(CC1101_MARCSTATE), rssi_dBm); - printf(buf); - sprintf(buf, "begin: %d, end: %d\n", begin_size, end_size); - printf(buf); - */ - - // uint8_t rx_data[64]; - // uint8_t fifo_length = end_size - begin_size; - - /* - if(fifo_length < 64) { - // cc1101->SpiReadBurstReg(CC1101_RXFIFO, rx_data, fifo_length); - - * - printf("FIFO:"); - for(uint8_t i = 0; i < fifo_length; i++) { - for(uint8_t bit = 0; bit < 8; bit++) { - printf("%s", (rx_data[i] & (1 << bit)) > 0 ? "1" : "0"); - } - printf(" "); - } - printf("\r\n"); - * - - for(uint8_t i = 0; i < fifo_length; i++) { - for(uint8_t bit = 0; bit < 8; bit++) { - gpio_write((GpioPin*)&debug_0, (rx_data[i] & (1 << bit)) > 0); - delay_us(5); - } - } - } else { - printf("fifo size over\r\n"); - } - */ - - return rssi_dBm; -} - -/* -void flp_config(CC1101* cc1101) { - cc1101->SpiWriteReg( - CC1101_MCSM0, 0x18); // calibrate when going from IDLE to RX or TX ; 149 - 155 μs timeout - // MCSM0.FS_AUTOCAL[1:0] = 1 - - cc1101->SpiWriteReg(CC1101_AGCCTRL2, 0x43); - cc1101->SpiWriteReg(CC1101_AGCCTRL1, 0x49); - cc1101->SpiWriteReg(CC1101_AGCCTRL0, 0x91); - - //freq synthesizer calibration - cc1101->SpiWriteReg(CC1101_FSCAL3, 0xEA); - cc1101->SpiWriteReg(CC1101_FSCAL2, 0x2A); - cc1101->SpiWriteReg(CC1101_FSCAL1, 0x00); - cc1101->SpiWriteReg(CC1101_FSCAL0, 0x1F); - - // async data out - cc1101->SpiSetRegValue(CC1101_IOCFG0, 13, 5, 0); // GDO0 Output Pin Configuration - cc1101->SpiSetRegValue(CC1101_IOCFG0, 13, 5, 0); // WAT - - // FIFOTHR.ADC_RETENTION = 1 - cc1101->SpiSetRegValue(CC1101_FIFOTHR, 1, 6, 6); - - // PKTCTRL1.APPEND_STATUS = 0 - cc1101->SpiSetRegValue(CC1101_PKTCTRL1, 0, 2, 2); - - // PKTCTRL0.WHITE_DATA = 0 - cc1101->SpiSetRegValue(CC1101_PKTCTRL0, 0, 6, 6); - - // PKTCTRL0.LENGTH_CONFIG = 2 // Infinite packet length mode - cc1101->SpiSetRegValue(CC1101_PKTCTRL0, 2, 1, 0); - - // PKTCTRL0.CRC_EN = 0 - cc1101->SpiSetRegValue(CC1101_PKTCTRL0, 0, 2, 2); - - // PKTCTRL0.PKT_FORMAT = 3 - cc1101->SpiSetRegValue(CC1101_PKTCTRL0, 3, 5, 4); - - // bandwidth 50-100 kHz - if(!cc1101->setRxBandwidth(75.0)) { - printf("wrong rx bw\r\n"); - } - - // datarate ~30 kbps - if(!cc1101->setBitRate(100.)) { - printf("wrong bitrate\r\n"); - } - - // mod - // MDMCFG2.MOD_FORMAT = 3 (3: OOK, 0: 2-FSK) - cc1101->SpiSetRegValue(CC1101_MDMCFG2, 3, 6, 4); - // MDMCFG2.SYNC_MODE = 0 - cc1101->SpiSetRegValue(CC1101_MDMCFG2, 0, 2, 0); -} -*/ - -void tx_config(CC1101* cc1101) { - // cc1101->SpiWriteReg(CC1101_IOCFG2,0x0B); //GDO2 Output Pin Configuration - // cc1101->SpiWriteReg(CC1101_IOCFG0,0x0C); //GDO0 Output Pin Configuration - cc1101->SpiSetRegValue(CC1101_IOCFG0, 13, 5, 0); // GDO0 Output Pin Configuration - - cc1101->SpiWriteReg(CC1101_FIFOTHR, 0x47); //RX FIFO and TX FIFO Thresholds - cc1101->SpiWriteReg(CC1101_PKTCTRL0, 0x32); //Packet Automation Control - cc1101->SpiWriteReg(CC1101_FSCTRL1, 0x06); //Frequency Synthesizer Control - cc1101->SpiWriteReg(CC1101_FREQ2, 0x10); //Frequency Control Word, High Byte - cc1101->SpiWriteReg(CC1101_FREQ1, 0xB0); //Frequency Control Word, Middle Byte - cc1101->SpiWriteReg(CC1101_FREQ0, 0x71); //Frequency Control Word, Low Byte - cc1101->SpiWriteReg(CC1101_MDMCFG4, 0x6A); //Modem Configuration - cc1101->SpiWriteReg(CC1101_MDMCFG3, 0x2E); //Modem Configuration - cc1101->SpiWriteReg(CC1101_MDMCFG2, 0x30); //Modem Configuration - cc1101->SpiWriteReg(CC1101_DEVIATN, 0x15); //Modem Deviation Setting - cc1101->SpiWriteReg(CC1101_MCSM0, 0x18); //Main Radio Control State Machine Configuration - cc1101->SpiWriteReg(CC1101_FOCCFG, 0x16); //Frequency Offset Compensation Configuration - cc1101->SpiWriteReg(CC1101_WORCTRL, 0xFB); //Wake On Radio Control - cc1101->SpiWriteReg(CC1101_FREND0, 0x11); //Front End TX Configuration - cc1101->SpiWriteReg(CC1101_FSCAL3, 0xE9); //Frequency Synthesizer Calibration - cc1101->SpiWriteReg(CC1101_FSCAL2, 0x2A); //Frequency Synthesizer Calibration - cc1101->SpiWriteReg(CC1101_FSCAL1, 0x00); //Frequency Synthesizer Calibration - cc1101->SpiWriteReg(CC1101_FSCAL0, 0x1F); //Frequency Synthesizer Calibration - - /* - cc1101->SpiWriteReg(CC1101_TEST2, 0x81); //Various Test Settings - cc1101->SpiWriteReg(CC1101_TEST1, 0x35); //Various Test Settings - cc1101->SpiWriteReg(CC1101_TEST0, 0x09); //Various Test Settings - */ -} - -// f = (f_osc/65536) * (FREQ + CHAN * (256 + CH_SP_M) * 2^(CH_SP_E - 2)) -// FREQ = f / (f_osc/65536) -// CHAN = 0 -// TODO: CHAN number not implemented! -// TODO: reg values not affetcts - -const Band bands[] = { - {301., {0x00, 0x00, 0x00}, 0, 255, 74}, - {315., {0x00, 0x00, 0x00}, 0, 255, 74}, - {346., {0x00, 0x00, 0x00}, 0, 255, 74}, - {385., {0x00, 0x00, 0x00}, 0, 255, 74}, - {433.92, {0x00, 0x00, 0x00}, 0, 255, 74}, - {438.9, {0x00, 0x00, 0x00}, 0, 255, 74}, - {463., {0x00, 0x00, 0x00}, 0, 255, 74}, - {781., {0x00, 0x00, 0x00}, 0, 255, 74}, - {868., {0x00, 0x00, 0x00}, 0, 255, 74}, - {915., {0x00, 0x00, 0x00}, 0, 255, 74}, - {925., {0x00, 0x00, 0x00}, 0, 255, 74}, -}; - -const FreqConfig FREQ_LIST[] = { - {&bands[0], 0}, - {&bands[1], 0}, - {&bands[2], 0}, - {&bands[3], 0}, - {&bands[4], 0}, - {&bands[5], 0}, - {&bands[6], 0}, - {&bands[7], 0}, - {&bands[8], 0}, - {&bands[9], 0}, - {&bands[10], 0}, -}; - -extern "C" void cc1101_isr(void* _pin, void* _ctx) { - uint32_t pin = (uint32_t)_pin; - if(pin == CC1101_G0_Pin) { - gpio_write((GpioPin*)&debug_0, gpio_read(&cc1101_g0_gpio)); - } -} - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - union { - InputEvent input; - } value; - EventType type; -} AppEvent; - -typedef enum { ModeRx, 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_idx; - float active_freq; - int16_t last_rssi; - size_t tx_level; - bool need_cc1101_conf; - RfBand rf_band; -} State; - -static void render_callback(Canvas* canvas, void* ctx) { - State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); - - if(!state) return; - - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 2, 12, "cc1101 workaround"); - - { - char buf[24]; - sprintf( - buf, - "freq: %ld.%02ld MHz", - (uint32_t)state->active_freq, - (uint32_t)(state->active_freq * 100.) % 100); - - canvas_set_font(canvas, FontSecondary); - 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); - } - } - - { - char buf[24]; - // sprintf(buf, "tx level: %d dBm", TX_LEVELS[state->tx_level].dbm); - sprintf(buf, "RF band: %d", (uint8_t)state->rf_band); - - canvas_set_font(canvas, FontSecondary); - if(state->rf_band == RfBandIsolation) { - canvas_draw_str(canvas, 2, 63, "RF band: isolation"); - } else { - canvas_draw_str(canvas, 2, 63, buf); - } - } - - release_mutex((ValueMutex*)ctx, state); -} - -static void input_callback(InputEvent* input_event, void* ctx) { - osMessageQueueId_t event_queue = ctx; - - AppEvent event; - event.type = EventTypeKey; - event.value.input = *input_event; - osMessageQueuePut(event_queue, &event, 0, 0); -} - -extern "C" int32_t cc1101_workaround(void* p) { - osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(AppEvent), NULL); - furi_check(event_queue); - - State _state; - _state.mode = ModeRx; - _state.active_freq_idx = 4; - - FreqConfig conf = FREQ_LIST[_state.active_freq_idx]; - _state.active_freq = conf.band->base_freq + CHAN_SPA * conf.channel; - - _state.need_cc1101_conf = true; - _state.last_rssi = 0; - _state.tx_level = 0; - _state.rf_band = RfBand1; - - ValueMutex state_mutex; - if(!init_mutex(&state_mutex, &_state, sizeof(State))) { - printf("[cc1101] cannot create mutex\r\n"); - return 255; - } - - ViewPort* view_port = view_port_alloc(); - - view_port_draw_callback_set(view_port, render_callback, &state_mutex); - view_port_input_callback_set(view_port, input_callback, event_queue); - - // Open GUI and register view_port - Gui* gui = (Gui*)furi_record_open("gui"); - if(gui == NULL) { - printf("[cc1101] gui is not available\r\n"); - return 255; - } - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - gpio_init(&debug_0, GpioModeOutputPushPull); - gpio_write((GpioPin*)&debug_0, false); - - printf("[cc1101] creating device\r\n"); - GpioPin cs_pin = {CC1101_CS_GPIO_Port, CC1101_CS_Pin}; - - gpio_init(&cc1101_g0_gpio, GpioModeInput); - api_interrupt_add(cc1101_isr, InterruptTypeExternalInterrupt, NULL); - // TODO open record - GpioPin* cs_pin_record = &cs_pin; - CC1101 cc1101(cs_pin_record); - printf("[cc1101] init device\r\n"); - - uint8_t address = cc1101.Init(); - if(address > 0) { - printf("[cc1101] init done: %d\r\n", address); - } else { - printf("[cc1101] init fail\r\n"); - return 255; - } - - cc1101.SpiStrobe(CC1101_SIDLE); - - // flp_config(&cc1101); - tx_config(&cc1101); - // setup_freq(&cc1101, &FREQ_LIST[4]); - // enable_cc1101_irq(); - - printf("init ok\r\n"); - - const int16_t RSSI_THRESHOLD = -60; - - // setup_freq(&cc1101, &FREQ_LIST[1]); - - cc1101.SetReceive(); - - AppEvent event; - while(1) { - osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 100); - State* state = (State*)acquire_mutex_block(&state_mutex); - - if(event_status == osOK) { - if(event.type == EventTypeKey) { - if(event.value.input.type == InputTypeShort && - event.value.input.key == InputKeyBack) { - printf("[cc1101] bye!\r\n"); - - cc1101.SpiStrobe(CC1101_SIDLE); - cc1101.SpiStrobe(CC1101_SPWD); - - printf("[cc1101] go to power down\r\n"); - - // TODO remove all view_ports create by app - view_port_enabled_set(view_port, false); - return 255; - } - - if(event.value.input.type == InputTypeShort && - event.value.input.key == InputKeyDown) { - if(state->active_freq_idx > 0) { - state->active_freq_idx--; - } - - FreqConfig conf = FREQ_LIST[state->active_freq_idx]; - state->active_freq = conf.band->base_freq + CHAN_SPA * conf.channel; - state->need_cc1101_conf = true; - } - - if(event.value.input.type == InputTypeShort && - event.value.input.key == InputKeyUp) { - if(state->active_freq_idx < (sizeof(FREQ_LIST) / sizeof(FREQ_LIST[0]) - 1)) { - state->active_freq_idx++; - } - - FreqConfig conf = FREQ_LIST[state->active_freq_idx]; - state->active_freq = conf.band->base_freq + CHAN_SPA * conf.channel; - state->need_cc1101_conf = true; - } - - if(event.value.input.type == InputTypeShort && - event.value.input.key == InputKeyRight) { - /* - if(state->tx_level < (sizeof(TX_LEVELS) / sizeof(TX_LEVELS[0]) - 1)) { - state->tx_level++; - } else { - state->tx_level = 0; - } - */ - - if(state->rf_band < RfBand3) { - state->rf_band = (RfBand)((uint8_t)state->rf_band + 1); - } else { - state->active_freq += 0.25; - } - state->need_cc1101_conf = true; - } - - if(event.value.input.type == InputTypeShort && - event.value.input.key == InputKeyLeft) { - /* - if(state->tx_level < (sizeof(TX_LEVELS) / sizeof(TX_LEVELS[0]) - 1)) { - state->tx_level++; - } else { - state->tx_level = 0; - } - */ - - if(state->rf_band > RfBandIsolation) { - state->rf_band = (RfBand)((uint8_t)state->rf_band - 1); - } else { - state->active_freq -= 0.25; - } - state->need_cc1101_conf = true; - } - - if(event.value.input.key == InputKeyOk) { - if(event.value.input.type == InputTypePress) { - state->mode = ModeTx; - state->need_cc1101_conf = true; - } else if(event.value.input.type == InputTypeRelease) { - state->mode = ModeRx; - state->need_cc1101_conf = true; - } - } - } - } else { - } - - if(state->need_cc1101_conf) { - if(state->mode == ModeRx) { - cc1101.SpiStrobe(CC1101_SIDLE); - gpio_init(&cc1101_g0_gpio, GpioModeInput); - - setup_freq(&cc1101, state->active_freq); - cc1101.SetReceive(); - - state->last_rssi = rx_rssi(&cc1101, &FREQ_LIST[state->active_freq_idx]); - } else if(state->mode == ModeTx) { - cc1101.SpiStrobe(CC1101_SIDLE); - - setup_freq(&cc1101, state->active_freq); - cc1101.SetTransmit(); - gpio_init(&cc1101_g0_gpio, GpioModeOutputPushPull); - gpio_write(&cc1101_g0_gpio, false); - } - - api_hal_rf_band_set(state->rf_band); - - state->need_cc1101_conf = false; - } - - if(!state->need_cc1101_conf && state->mode == ModeRx) { - // TOOD what about rssi offset - state->last_rssi = rx_rssi(&cc1101, &FREQ_LIST[state->active_freq_idx]); - - api_hal_light_set(LightGreen, state->last_rssi > RSSI_THRESHOLD ? 0xFF : 0x00); - } else if(!state->need_cc1101_conf && state->mode == ModeTx) { - /* - const uint8_t data = 0xA5; - - for(uint8_t i = 0; i < 8; i++) { - gpio_write(&cc1101_g0_gpio, (data & (1 << i)) > 0); - osDelay(1); - } - gpio_write(&cc1101_g0_gpio, false); - */ - - /* - // BELL UDB-Q022-0000 - const uint16_t HALF_PERIOD = 500; - - for(uint8_t n = 0; n < 4; n++) { - for(uint8_t i = 0; i < 4; i++) { - gpio_write(&cc1101_g0_gpio, true); - delay_us(3 * HALF_PERIOD); - gpio_write(&cc1101_g0_gpio, false); - delay_us(HALF_PERIOD); - } - - for(uint8_t i = 0; i < 40; i++) { - gpio_write(&cc1101_g0_gpio, true); - delay_us(HALF_PERIOD); - gpio_write(&cc1101_g0_gpio, false); - delay_us(HALF_PERIOD); - } - } - */ - - // BELL ERA C61, static code - const uint16_t ONE_ON = 150; - const uint16_t ONE_OFF = 400; - const uint16_t ZERO_ON = 420; - const uint16_t ZERO_OFF = 130; - - const bool SEQ[] = {true, true, false, false, true, false, true, false, true, - false, true, true, true, false, true, false, true, true, - true, true, true, false, true, false, true}; - - for(uint8_t n = 0; n < 10; n++) { - for(uint8_t i = 0; i < sizeof(SEQ) / sizeof(SEQ[0]); i++) { - if(SEQ[i]) { - gpio_write(&cc1101_g0_gpio, false); - delay_us(ONE_ON); - gpio_write(&cc1101_g0_gpio, true); - delay_us(ONE_OFF); - } else { - gpio_write(&cc1101_g0_gpio, false); - delay_us(ZERO_ON); - gpio_write(&cc1101_g0_gpio, true); - delay_us(ZERO_OFF); - } - } - - osDelay(4); - } - - gpio_write(&cc1101_g0_gpio, false); - } - - release_mutex(&state_mutex, state); - view_port_update(view_port); - } - - return 0; -} \ No newline at end of file diff --git a/applications/cc1101-workaround/cc1101.cpp b/applications/cc1101-workaround/cc1101.cpp deleted file mode 100644 index 955193f9..00000000 --- a/applications/cc1101-workaround/cc1101.cpp +++ /dev/null @@ -1,485 +0,0 @@ -#include -#include - -#include "cc1101-workaround/cc1101.h" -#include "spi.h" -#include - -// ****************************************************************************** -#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 - */ - gpio_init(ss_pin, GpioModeOutputPushPull); - this->ss_pin = ss_pin; - - // TODO open record - this->miso_pin = MISO_PIN; - this->miso_pin_record = &this->miso_pin; -} -//****************************************************************************** -//SpiInit -/******************************************************************************/ -extern SPI_HandleTypeDef SPI_R; -void CC1101::SpiInit(void) { - //initialize spi pins - - //Enable spi master, MSB, SPI mode 0, FOSC/4 - SpiMode(0); - - CC1101_SPI_Reconfigure(); -} - -void CC1101::SpiEnd(void) { - /* - SPCR = ((0<miso_pin_record)) - ; - - last_status = SpiTransfer(addr); - last_status = SpiTransfer(value); - gpio_write(ss_pin, true); -} - -/**************************************************************** -*FUNCTION NAME:SpiWriteBurstReg -*FUNCTION :CC1101 write burst data to register -*INPUT :addr: register address; buffer:register value array; num:number to write -*OUTPUT :none -****************************************************************/ -void CC1101::SpiWriteBurstReg(uint8_t addr, uint8_t* buffer, uint8_t num) { - gpio_write(ss_pin, false); - while(gpio_read(this->miso_pin_record)) - ; - last_status = SpiTransfer(addr | WRITE_BURST); - for(uint8_t i = 0; i < num; i++) { - last_status = SpiTransfer(buffer[i]); - } - gpio_write(ss_pin, true); -} - -/**************************************************************** -*FUNCTION NAME:SpiStrobe -*FUNCTION :CC1101 Strobe -*INPUT :strobe: command; //refer define in CC1101.h// -*OUTPUT :none -****************************************************************/ -void CC1101::SpiStrobe(uint8_t strobe) { - gpio_write(ss_pin, false); - while(gpio_read(this->miso_pin_record)) - ; - last_status = SpiTransfer(strobe); - gpio_write(ss_pin, true); -} - -/**************************************************************** -*FUNCTION NAME:SpiReadReg -*FUNCTION :CC1101 read data from register -*INPUT :addr: register address -*OUTPUT :register value -****************************************************************/ -uint8_t CC1101::SpiReadReg(uint8_t addr) { - gpio_write(ss_pin, false); - while(gpio_read(this->miso_pin_record)) - ; - last_status = SpiTransfer(addr | READ_SINGLE); - uint8_t value = SpiTransfer(0); - gpio_write(ss_pin, true); - - return value; -} - -/**************************************************************** -*FUNCTION NAME:SpiReadBurstReg -*FUNCTION :CC1101 read burst data from register -*INPUT :addr: register address; buffer:array to store register value; num: number to read -*OUTPUT :none -****************************************************************/ -void CC1101::SpiReadBurstReg(uint8_t addr, uint8_t* buffer, uint8_t num) { - gpio_write(ss_pin, false); - while(gpio_read(this->miso_pin_record)) - ; - last_status = SpiTransfer(addr | READ_BURST); - for(uint8_t i = 0; i < num; i++) { - buffer[i] = SpiTransfer(0); - } - gpio_write(ss_pin, true); -} - -/**************************************************************** -*FUNCTION NAME:SpiReadStatus -*FUNCTION :CC1101 read status register -*INPUT :addr: register address -*OUTPUT :status value -****************************************************************/ -uint8_t CC1101::SpiReadStatus(uint8_t addr) { - gpio_write(ss_pin, false); - while(gpio_read(this->miso_pin_record)) - ; - last_status = SpiTransfer(addr | READ_BURST); - uint8_t value = SpiTransfer(0); - gpio_write(ss_pin, true); - - return value; -} - -/**************************************************************** -*FUNCTION NAME:Reset -*FUNCTION :CC1101 reset //details refer datasheet of CC1101/CC1100// -*INPUT :none -*OUTPUT :none -****************************************************************/ -void CC1101::Reset(void) { - gpio_write(ss_pin, false); - delay(1); - gpio_write(ss_pin, true); - delay(1); - gpio_write(ss_pin, false); - while(gpio_read(this->miso_pin_record)) - ; - last_status = SpiTransfer(CC1101_SRES); - while(gpio_read(this->miso_pin_record)) - ; - gpio_write(ss_pin, true); -} - -bool CC1101::SpiSetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t lsb) { - if((msb > 7) || (lsb > 7) || (lsb > msb)) { - return false; - } - - uint8_t current_value = SpiReadReg(reg); - uint8_t mask = ~((0b11111111 << (msb + 1)) | (0b11111111 >> (8 - lsb))); - uint8_t new_value = (current_value & ~mask) | (value & mask); - SpiWriteReg(reg, new_value); - - return true; -} - -/**************************************************************** -*FUNCTION NAME:Init -*FUNCTION :CC1101 initialization -*INPUT :none -*OUTPUT :none -****************************************************************/ -uint8_t CC1101::Init(void) { -#ifdef CC1101_DEBUG - printf("Init SPI...\r\n"); -#endif - SpiInit(); //spi initialization - gpio_write(ss_pin, true); -// gpio_write(SCK_PIN, true); -// gpio_write(MOSI_PIN, false); -#ifdef CC1101_DEBUG - printf("Reset CC1101...\r\n"); -#endif - Reset(); // CC1101 reset - - osDelay(150); - - uint8_t partnum __attribute__((unused)); - uint8_t version; - partnum = SpiReadStatus(CC1101_PARTNUM); - version = SpiReadStatus(CC1101_VERSION); - -#ifdef CC1101_DEBUG - - printf("Partnum:0x%02X, Version:0x%02X\n", partnum, version); -#endif - -#ifdef CC1101_DEBUG - printf("Init CC1101..."); -#endif - // RegConfigSettings(); //CC1101 register config - -#ifdef CC1101_DEBUG - printf("Done!\r\n"); -#endif - - return version; -} -/**************************************************************** -*FUNCTION NAME:SetMod -*FUNCTION :CC1101 modulation type -*INPUT :byte mode -*OUTPUT :none -****************************************************************/ -void CC1101::SetMod(uint8_t mode) { - SpiWriteReg(CC1101_MDMCFG2, mode); //no sync/preamble; ASK/OOK only support up to -1dbm - if((mode | 0x30) == ASK) { - SpiWriteReg(CC1101_FREND0, 0x11); //use first up to PATABLE(0) - uint8_t PaTabel[8] = {0x00, POWER, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - SpiWriteBurstReg(CC1101_PATABLE, PaTabel, 8); //CC1101 PATABLE config - } else { - SpiWriteReg(CC1101_FREND0, 0x10); //use first up to PATABLE(0) - uint8_t PaTabel[8] = {POWER, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - SpiWriteBurstReg(CC1101_PATABLE, PaTabel, 8); //CC1101 PATABLE config - } - -#ifdef CC1101_DEBUG - switch(mode | 0x30) { - case GFSK: { - printf("CC1101 Modulation: GFSK"); - break; - } - case MSK: { - printf("CC1101 Modulation: MSK"); - break; - } - case ASK: { - printf("CC1101 Modulation: ASK/OOK"); - break; - } - case FSK2: { - printf("CC1101 Modulation: 2-FSK"); - break; - } - case FSK4: { - printf("CC1101 Modulation: 4-FSK"); - break; - } - default: //default to GFSK - { - printf("Modulation mode not supported"); - break; - } - } - - printf("\r\n"); -#endif -} -/**************************************************************** -*FUNCTION NAME:RegConfigSettings -*FUNCTION :CC1101 register config //details refer datasheet of CC1101/CC1100// -*INPUT :none -*OUTPUT :none -****************************************************************/ -void CC1101::RegConfigSettings(void) { - SpiWriteReg(CC1101_FSCTRL1, 0x06); //IF frequency - SpiWriteReg(CC1101_FSCTRL0, 0x00); //frequency offset before synthesizer - - SpiWriteReg(CC1101_MDMCFG4, 0xCC); // RX filter bandwidth 100k(0xcc) - SpiWriteReg( - CC1101_MDMCFG3, 0x43); //datarate config 512kBaud for the purpose of fast rssi measurement - SpiWriteReg(CC1101_MDMCFG1, 0x21); //FEC preamble etc. last 2 bits for channel spacing - SpiWriteReg(CC1101_MDMCFG0, 0xF8); //100khz channel spacing - //CC1101_CHANNR moved to SetChannel func - - //SpiWriteReg(CC1101_DEVIATN, 0x47); - SpiWriteReg( - CC1101_MCSM0, 0x18); // calibrate when going from IDLE to RX or TX ; 149 - 155 μs timeout - SpiWriteReg(CC1101_FOCCFG, 0x16); //frequency compensation - //SpiWriteReg(CC1101_BSCFG, 0x1C); //bit synchronization config - SpiWriteReg(CC1101_AGCCTRL2, 0x43); - SpiWriteReg(CC1101_AGCCTRL1, 0x49); - SpiWriteReg(CC1101_AGCCTRL0, 0x91); - //freq synthesizer calibration - SpiWriteReg(CC1101_FSCAL3, 0xEA); - SpiWriteReg(CC1101_FSCAL2, 0x2A); - SpiWriteReg(CC1101_FSCAL1, 0x00); - SpiWriteReg(CC1101_FSCAL0, 0x1F); - SpiWriteReg(CC1101_TEST2, 0x81); - SpiWriteReg(CC1101_TEST1, 0x35); - SpiWriteReg(CC1101_TEST0, 0x0B); //should be 0x0B for lower than 430.6MHz and 0x09 for higher - - //SpiWriteReg(CC1101_FREND1, 0x56); - - //SpiWriteReg(CC1101_IOCFG2, 0x0B); //serial clock.synchronous to the data in synchronous serial mode - //SpiWriteReg(CC1101_IOCFG0, 0x06); //asserts when sync word has been sent/received, and de-asserts at the end of the packet - SpiWriteReg(CC1101_IOCFG2, 0x0D); //data output pin for asynchronous mode - SpiWriteReg( - CC1101_IOCFG0, - 0x2E); //High impedance (3-state), GDO0 configed as data input for asynchronous mode - //SpiWriteReg(CC1101_PKTCTRL0, 0x05); //whitening off;CRC Enable;variable length packets, packet length configured by the first byte after sync word - SpiWriteReg( - CC1101_PKTCTRL0, 0x33); //whitening off; asynchronous serial mode; CRC diable;reserved - //SpiWriteReg(CC1101_PKTLEN, 0x3D); //61 bytes max length - SpiWriteReg( - CC1101_FIFOTHR, - 0x47); //Adc_retention enabled for RX filter bandwidth less than 325KHz; defalut fifo threthold. -} -/**************************************************************** - *FUNCTION NAME:SetFreq - *FUNCTION :SetFreq - *INPUT :Freq2, Freq1, Freq0 - *OUTPUT :none - ****************************************************************/ -void CC1101::SetFreq(uint8_t freq2, uint8_t freq1, uint8_t freq0) { - SpiWriteReg(CC1101_FREQ2, freq2); - SpiWriteReg(CC1101_FREQ1, freq1); - SpiWriteReg(CC1101_FREQ0, freq0); -} -/**************************************************************** - *FUNCTION NAME:SetChannel - *FUNCTION :SetChannel - *INPUT :int channel - *OUTPUT :none - ****************************************************************/ -void CC1101::SetChannel(int channel) { -#ifdef CC1101_DEBUG - printf("Set CC1101 channel to: %d \n", channel); -#endif - SpiWriteReg(CC1101_CHANNR, (uint8_t)channel); //related to channel numbers -} -/**************************************************************** - *FUNCTION NAME:SetReceive - *FUNCTION :SetReceive - *INPUT :none - *OUTPUT :none - ****************************************************************/ -void CC1101::SetReceive(void) { - SpiStrobe(CC1101_SRX); - while(SpiReadStatus(CC1101_MARCSTATE) ^ CC1101_STATUS_RX) { - // delay(1); - // printf("wait status\r\n"); - } -} -/**************************************************************** - *FUNCTION NAME:SetTransmit - *FUNCTION : - *INPUT :none - *OUTPUT :none - ****************************************************************/ -void CC1101::SetTransmit(void) { - SpiStrobe(CC1101_STX); - while(SpiReadStatus(CC1101_MARCSTATE) ^ CC1101_STATUS_TX) - ; -} -//cc1101 cc1101; - -bool CC1101::setRxBandwidth(float bandwidth) { - if(bandwidth < 58.0 || bandwidth > 821.0) return false; - - // set mode to standby - SpiStrobe(CC1101_SIDLE); - - // calculate exponent and mantissa values - for(int8_t e = 3; e >= 0; e--) { - for(int8_t m = 3; m >= 0; m--) { - float point = (F_OSC) / (8 * (m + 4) * ((uint32_t)1 << e)); - if(fabs((bandwidth * 1000.0) - point) <= 1000) { - // set Rx channel filter bandwidth - SpiSetRegValue(CC1101_MDMCFG4, (e << 6) | (m << 4), 7, 4); - - return true; - } - } - } - - return false; -} - -static void getExpMant( - float target, - uint16_t mantOffset, - uint8_t divExp, - uint8_t expMax, - uint8_t& exp, - uint8_t& mant) { - // get table origin point (exp = 0, mant = 0) - float origin = (mantOffset * F_OSC) / ((uint32_t)1 << divExp); - - // iterate over possible exponent values - for(int8_t e = expMax; e >= 0; e--) { - // get table column start value (exp = e, mant = 0); - float intervalStart = ((uint32_t)1 << e) * origin; - - // check if target value is in this column - if(target >= intervalStart) { - // save exponent value - exp = e; - - // calculate size of step between table rows - float stepSize = intervalStart / (float)mantOffset; - - // get target point position (exp = e, mant = m) - mant = ((target - intervalStart) / stepSize); - - // we only need the first match, terminate - return; - } - } -} - -bool CC1101::setBitRate(float bitrate) { - if(bitrate < 0.6 || bitrate > 500.0) return false; - - // set mode to standby - SpiStrobe(CC1101_SIDLE); - - // calculate exponent and mantissa values - uint8_t e = 0; - uint8_t m = 0; - getExpMant(bitrate * 1000.0, 256, 28, 14, e, m); - - // set bit rate value - SpiSetRegValue(CC1101_MDMCFG4, e, 3, 0); - SpiSetRegValue(CC1101_MDMCFG3, m, 7, 0); - - return true; -} diff --git a/applications/cc1101-workaround/cc1101.h b/applications/cc1101-workaround/cc1101.h deleted file mode 100644 index 236b899d..00000000 --- a/applications/cc1101-workaround/cc1101.h +++ /dev/null @@ -1,174 +0,0 @@ -#pragma once - -#include - -#define F_OSC 26e6 - -/*******************************debug mode*************************************/ -// #define CC1101_DEBUG 1 - -//******************************CC1101 defines ******************************** -//******************************config registers ***************************** -#define CC1101_IOCFG2 0x00 //GDO2 output pin configration -#define CC1101_IOCFG1 0x01 // GDO1 output pin configuration -#define CC1101_IOCFG0 0x02 // GDO0 output pin configuration -#define CC1101_FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds -#define CC1101_SYNC1 0x04 // Sync word, high INT8U -#define CC1101_SYNC0 0x05 // Sync word, low INT8U -#define CC1101_PKTLEN 0x06 // Packet length -#define CC1101_PKTCTRL1 0x07 // Packet automation control -#define CC1101_PKTCTRL0 0x08 // Packet automation control -#define CC1101_ADDR 0x09 // Device address -#define CC1101_CHANNR 0x0A // Channel number -#define CC1101_FSCTRL1 0x0B // Frequency synthesizer control -#define CC1101_FSCTRL0 0x0C // Frequency synthesizer control -#define CC1101_FREQ2 0x0D // Frequency control word, high INT8U -#define CC1101_FREQ1 0x0E // Frequency control word, middle INT8U -#define CC1101_FREQ0 0x0F // Frequency control word, low INT8U -#define CC1101_MDMCFG4 0x10 // Modem configuration -#define CC1101_MDMCFG3 0x11 // Modem configuration -#define CC1101_MDMCFG2 0x12 // Modem configuration -#define CC1101_MDMCFG1 0x13 // Modem configuration -#define CC1101_MDMCFG0 0x14 // Modem configuration -#define CC1101_DEVIATN 0x15 // Modem deviation setting -#define CC1101_MCSM2 0x16 // Main Radio Control State Machine configuration -#define CC1101_MCSM1 0x17 // Main Radio Control State Machine configuration -#define CC1101_MCSM0 0x18 // Main Radio Control State Machine configuration -#define CC1101_FOCCFG 0x19 // Frequency Offset Compensation configuration -#define CC1101_BSCFG 0x1A // Bit Synchronization configuration -#define CC1101_AGCCTRL2 0x1B // AGC control -#define CC1101_AGCCTRL1 0x1C // AGC control -#define CC1101_AGCCTRL0 0x1D // AGC control -#define CC1101_WOREVT1 0x1E // High INT8U Event 0 timeout -#define CC1101_WOREVT0 0x1F // Low INT8U Event 0 timeout -#define CC1101_WORCTRL 0x20 // Wake On Radio control -#define CC1101_FREND1 0x21 // Front end RX configuration -#define CC1101_FREND0 0x22 // Front end TX configuration -#define CC1101_FSCAL3 0x23 // Frequency synthesizer calibration -#define CC1101_FSCAL2 0x24 // Frequency synthesizer calibration -#define CC1101_FSCAL1 0x25 // Frequency synthesizer calibration -#define CC1101_FSCAL0 0x26 // Frequency synthesizer calibration -#define CC1101_RCCTRL1 0x27 // RC oscillator configuration -#define CC1101_RCCTRL0 0x28 // RC oscillator configuration -#define CC1101_FSTEST 0x29 // Frequency synthesizer calibration control -#define CC1101_PTEST 0x2A // Production test -#define CC1101_AGCTEST 0x2B // AGC test -#define CC1101_TEST2 0x2C // Various test settings -#define CC1101_TEST1 0x2D // Various test settings -#define CC1101_TEST0 0x2E // Various test settings - -//*********************CC1101 Strobe commands ********************************* -#define CC1101_SRES 0x30 // Reset chip. - -// Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1). -// If in RX/TX: Go to a wait state where only the synthesizer is -// running (for quick RX / TX turnaround). -#define CC1101_SFSTXON 0x31 - -#define CC1101_SXOFF 0x32 // Turn off crystal oscillator. - -// Calibrate frequency synthesizer and turn it off -// (enables quick start). -#define CC1101_SCAL 0x33 - -// Enable RX. Perform calibration first if coming from IDLE and -// MCSM0.FS_AUTOCAL=1. -#define CC1101_SRX 0x34 - -// In IDLE state: Enable TX. Perform calibration first if -// MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled: -// Only go to TX if channel is clear. -#define CC1101_STX 0x35 - -// Exit RX / TX, turn off frequency synthesizer and exit -// Wake-On-Radio mode if applicable. -#define CC1101_SIDLE 0x36 - -#define CC1101_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer -#define CC1101_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio) -#define CC1101_SPWD 0x39 // Enter power down mode when CSn goes high. -#define CC1101_SFRX 0x3A // Flush the RX FIFO buffer. -#define CC1101_SFTX 0x3B // Flush the TX FIFO buffer. -#define CC1101_SWORRST 0x3C // Reset real time clock. - -// No operation. May be used to pad strobe commands to two -// INT8Us for simpler software. -#define CC1101_SNOP 0x3D - -//**************************CC1101 STATUS REGSITER **************************** -//use burst read to access -#define CC1101_PARTNUM 0x30 -#define CC1101_VERSION 0x31 -#define CC1101_FREQEST 0x32 -#define CC1101_LQI 0x33 -#define CC1101_RSSI 0x34 -#define CC1101_MARCSTATE 0x35 -#define CC1101_WORTIME1 0x36 -#define CC1101_WORTIME0 0x37 -#define CC1101_PKTSTATUS 0x38 -#define CC1101_VCO_VC_DAC 0x39 -#define CC1101_TXBYTES 0x3A -#define CC1101_RXBYTES 0x3B -#define CC1101_RCCTRL1_STATUS 0x3C -#define CC1101_RCCTRL_STATUS 0x3D -/****************************cc1101 status ***********************************/ -#define CC1101_STATUS_RX 0x0D -#define CC1101_STATUS_TX 0x13 - -//***********************CC1101 PATABLE,TXFIFO,RXFIFO************************** -#define CC1101_PATABLE 0x3E -#define CC1101_TXFIFO 0x3F -#define CC1101_RXFIFO 0x3F - -//******************************* pins **************************************** -// #define SCK_PIN 13 -// #define MISO_PIN 12 -// #define MOSI_PIN 11 -// #define SS_PIN 10 -// #define GDO0 8 //pin assignment -// #define GDO2 9 -//*****************************CC1101 Config********************************** -//no pa ramping, output power to 10dBm -#define POWER 0xC0 //output power to maximum -//modulation -#define FSK2 0x00 -#define GFSK 0x10 -#define ASK 0x30 -#define FSK4 0x40 -#define MSK 0x70 -//******************************** class **************************************// -class CC1101 { -private: - GpioPin* ss_pin; - GpioPin miso_pin; - GpioPin* miso_pin_record; - GpioPin* gdo0_pin; - GpioPin* gdo2_pin; - -private: - void SpiMode(uint8_t config); - uint8_t SpiTransfer(uint8_t value); - void Reset(void); - void SpiWriteBurstReg(uint8_t addr, uint8_t* buffer, uint8_t num); - uint8_t SpiReadReg(uint8_t addr); - void RegConfigSettings(void); - -public: - CC1101(GpioPin* ss_pin); - - void SpiWriteReg(uint8_t addr, uint8_t value); - bool SpiSetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t lsb); - void SpiReadBurstReg(uint8_t addr, uint8_t* buffer, uint8_t num); - void SpiInit(void); - void SpiEnd(void); - void SetMod(uint8_t mode); - void SetFreq(uint8_t Freq2, uint8_t Freq1, uint8_t Freq0); - uint8_t Init(void); - void SpiStrobe(uint8_t strobe); - uint8_t SpiReadStatus(uint8_t addr); - void SetReceive(void); - void SetTransmit(void); - void SetChannel(int channel); - bool setRxBandwidth(float bandwidth); - bool setBitRate(float bitrate); -}; diff --git a/applications/gui/canvas.c b/applications/gui/canvas.c index 9927993c..0bb61b19 100644 --- a/applications/gui/canvas.c +++ b/applications/gui/canvas.c @@ -34,6 +34,7 @@ void canvas_free(Canvas* canvas) { void canvas_reset(Canvas* canvas) { furi_assert(canvas); + canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontSecondary); } diff --git a/applications/gui/u8g2_periphery.c b/applications/gui/u8g2_periphery.c index 0d681189..e738ec18 100644 --- a/applications/gui/u8g2_periphery.c +++ b/applications/gui/u8g2_periphery.c @@ -1,122 +1,66 @@ #include "u8g2/u8g2.h" -#include #include +#include -#include - -extern SPI_HandleTypeDef SPI_D; - -// TODO: fix log -#ifdef DEBUG -#undef DEBUG -#endif +static ApiHalSpiDevice* u8g2_periphery_display = NULL; uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { switch(msg) { - //Initialize SPI peripheral case U8X8_MSG_GPIO_AND_DELAY_INIT: /* HAL initialization contains all what we need so we can skip this part. */ break; - //Function which implements a delay, arg_int contains the amount of ms case U8X8_MSG_DELAY_MILLI: osDelay(arg_int); break; - //Function which delays 10us case U8X8_MSG_DELAY_10MICRO: delay_us(10); break; - //Function which delays 100ns case U8X8_MSG_DELAY_100NANO: asm("nop"); break; - // Function to define the logic level of the RESET line case U8X8_MSG_GPIO_RESET: -#ifdef DEBUG - printf("[u8g2] rst %d\n", arg_int); -#endif - - // TODO change it to FuriRecord pin - HAL_GPIO_WritePin( - DISPLAY_RST_GPIO_Port, DISPLAY_RST_Pin, arg_int ? GPIO_PIN_SET : GPIO_PIN_RESET); + hal_gpio_write(&gpio_display_rst, arg_int); + break; + + default: + return 0; + } + + return 1; +} + +uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { + switch(msg) { + case U8X8_MSG_BYTE_SEND: + api_hal_spi_bus_tx(u8g2_periphery_display->bus, (uint8_t*)arg_ptr, arg_int, 10000); + break; + + case U8X8_MSG_BYTE_SET_DC: + hal_gpio_write(&gpio_display_di, arg_int); + break; + + case U8X8_MSG_BYTE_INIT: + break; + + case U8X8_MSG_BYTE_START_TRANSFER: + furi_assert(u8g2_periphery_display == NULL); + u8g2_periphery_display = + (ApiHalSpiDevice*)api_hal_spi_device_get(ApiHalSpiDeviceIdDisplay); + hal_gpio_write(u8g2_periphery_display->chip_select, false); + break; + + case U8X8_MSG_BYTE_END_TRANSFER: + furi_assert(u8g2_periphery_display); + hal_gpio_write(u8g2_periphery_display->chip_select, true); + api_hal_spi_device_return(u8g2_periphery_display); + u8g2_periphery_display = NULL; break; default: -#ifdef DEBUG - printf("[u8g2] unknown io %d\n", msg); -#endif - - return 0; //A message was received which is not implemented, return 0 to indicate an error - } - - return 1; // command processed successfully. -} - -uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { - switch(msg) { - case U8X8_MSG_BYTE_SEND: -#ifdef DEBUG - printf("[u8g2] send %d bytes %02X\n", arg_int, ((uint8_t*)arg_ptr)[0]); -#endif - - // TODO change it to FuriRecord SPI - HAL_SPI_Transmit(&SPI_D, (uint8_t*)arg_ptr, arg_int, 10000); - break; - - case U8X8_MSG_BYTE_SET_DC: -#ifdef DEBUG - printf("[u8g2] dc %d\n", arg_int); -#endif - - // TODO change it to FuriRecord pin - HAL_GPIO_WritePin( - DISPLAY_DI_GPIO_Port, DISPLAY_DI_Pin, arg_int ? GPIO_PIN_SET : GPIO_PIN_RESET); - break; - - case U8X8_MSG_BYTE_INIT: -#ifdef DEBUG - printf("[u8g2] init\r\n"); -#endif - - // TODO change it to FuriRecord pin - HAL_GPIO_WritePin(DISPLAY_CS_GPIO_Port, DISPLAY_CS_Pin, GPIO_PIN_RESET); - break; - - case U8X8_MSG_BYTE_START_TRANSFER: -#ifdef DEBUG - printf("[u8g2] start\r\n"); -#endif - - // TODO: SPI manager - api_hal_spi_lock_device(&display_spi); - - // TODO change it to FuriRecord pin - HAL_GPIO_WritePin(DISPLAY_CS_GPIO_Port, DISPLAY_CS_Pin, GPIO_PIN_RESET); - asm("nop"); - break; - - case U8X8_MSG_BYTE_END_TRANSFER: -#ifdef DEBUG - printf("[u8g2] end\r\n"); -#endif - - asm("nop"); - // TODO change it to FuriRecord pin - HAL_GPIO_WritePin(DISPLAY_CS_GPIO_Port, DISPLAY_CS_Pin, GPIO_PIN_SET); - - // TODO: SPI manager - api_hal_spi_unlock_device(&display_spi); - - break; - - default: -#ifdef DEBUG - printf("[u8g2] unknown xfer %d\n", msg); -#endif - return 0; } diff --git a/applications/lf-rfid/lf-rfid.c b/applications/lf-rfid/lf-rfid.c index 3997c631..45ce4513 100644 --- a/applications/lf-rfid/lf-rfid.c +++ b/applications/lf-rfid/lf-rfid.c @@ -37,12 +37,12 @@ static void render_callback(Canvas* canvas, void* ctx) { canvas_draw_str(canvas, 2, 24, state->on ? "Reading" : "Emulating"); - char buf[14]; + char buf[30]; - sprintf(buf, "%d kHz", (int)state->freq_khz); + snprintf(buf, sizeof(buf), "%d kHz", (int)state->freq_khz); canvas_draw_str(canvas, 2, 36, buf); - sprintf(buf, "%02d:%010ld", state->customer_id, state->em_data); + snprintf(buf, sizeof(buf), "%02d:%010ld", state->customer_id, state->em_data); canvas_draw_str(canvas, 2, 45, buf); release_mutex((ValueMutex*)ctx, state); diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index 657cf009..11296bf2 100644 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -244,7 +244,7 @@ ReturnCode nfc_worker_trx( } void nfc_worker_exchange(NfcWorker* nfc_worker, rfalNfcDevice* nfc_device) { - ReturnCode err; + ReturnCode err = ERR_NONE; uint8_t* rxData; uint16_t* rcvLen; uint8_t txBuf[100]; diff --git a/applications/sd-filesystem/sd-filesystem.c b/applications/sd-filesystem/sd-filesystem.c index a1dbd0c8..af468e03 100644 --- a/applications/sd-filesystem/sd-filesystem.c +++ b/applications/sd-filesystem/sd-filesystem.c @@ -849,4 +849,4 @@ int32_t sd_filesystem(void* p) { } return 0; -} \ No newline at end of file +} diff --git a/applications/subghz/scene/subghz-scene-generic.h b/applications/subghz/scene/subghz-scene-generic.h deleted file mode 100644 index 52fbdc50..00000000 --- a/applications/subghz/scene/subghz-scene-generic.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "../subghz-event.h" - -class SubghzApp; - -class SubghzScene { -public: - virtual void on_enter(SubghzApp* app) = 0; - virtual bool on_event(SubghzApp* app, SubghzEvent* event) = 0; - virtual void on_exit(SubghzApp* app) = 0; - -private: -}; \ No newline at end of file diff --git a/applications/subghz/scene/subghz-scene-spectrum-settings.cpp b/applications/subghz/scene/subghz-scene-spectrum-settings.cpp deleted file mode 100644 index c15d2553..00000000 --- a/applications/subghz/scene/subghz-scene-spectrum-settings.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "subghz-scene-spectrum-settings.h" -#include "../subghz-app.h" -#include "../subghz-view-manager.h" -#include "../subghz-event.h" -#include - -void SubghzSceneSpectrumSettings::on_enter(SubghzApp* app) { - SubghzAppViewManager* view_manager = app->get_view_manager(); - SubghzViewSpectrumSettings* spectrum_settings = view_manager->get_spectrum_settings(); - - auto callback = cbc::obtain_connector(this, &SubghzSceneSpectrumSettings::ok_callback); - spectrum_settings->set_ok_callback(callback, app); - spectrum_settings->set_start_freq(433); - - view_manager->switch_to(SubghzAppViewManager::ViewType::SpectrumSettings); -} - -bool SubghzSceneSpectrumSettings::on_event(SubghzApp* app, SubghzEvent* event) { - bool consumed = false; - - if(event->type == SubghzEvent::Type::NextScene) { - // save data - // uint32_t start_freq = app->get_view_manager()->get_spectrum_settings()->get_start_freq(); - // app->get_spectrum_analyzer()->set_start_freq(start_freq); - - // switch to next scene - // app->switch_to_next_scene(SubghzApp::Scene::SceneSpectrumAnalyze); - consumed = true; - } - - return consumed; -} - -void SubghzSceneSpectrumSettings::on_exit(SubghzApp* app) { - SubghzAppViewManager* view_manager = app->get_view_manager(); - SubghzViewSpectrumSettings* spectrum_settings = view_manager->get_spectrum_settings(); - - spectrum_settings->set_ok_callback(nullptr, nullptr); - spectrum_settings->set_start_freq(0); -} - -void SubghzSceneSpectrumSettings::ok_callback(void* context) { - SubghzApp* app = static_cast(context); - SubghzEvent event; - - event.type = SubghzEvent::Type::NextScene; - app->get_view_manager()->send_event(&event); -} \ No newline at end of file diff --git a/applications/subghz/scene/subghz-scene-spectrum-settings.h b/applications/subghz/scene/subghz-scene-spectrum-settings.h deleted file mode 100644 index 24e68c14..00000000 --- a/applications/subghz/scene/subghz-scene-spectrum-settings.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "subghz-scene-generic.h" - -class SubghzSceneSpectrumSettings : public SubghzScene { -public: - void on_enter(SubghzApp* app) final; - bool on_event(SubghzApp* app, SubghzEvent* event) final; - void on_exit(SubghzApp* app) final; - -private: - void ok_callback(void* context); -}; \ No newline at end of file diff --git a/applications/subghz/scene/subghz-scene-start.cpp b/applications/subghz/scene/subghz-scene-start.cpp deleted file mode 100644 index 868c39dd..00000000 --- a/applications/subghz/scene/subghz-scene-start.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "subghz-scene-start.h" -#include "../subghz-app.h" -#include "../subghz-view-manager.h" -#include "../subghz-event.h" -#include - -typedef enum { - SubmenuIndexSpectrumAnalyzer, - SubmenuIndexFrequencyScanner, - SubmenuIndexSignalAnalyzer, - SubmenuIndexSignalTransmitter, - SubmenuIndexApplications, -} SubmenuIndex; - -void SubghzSceneStart::on_enter(SubghzApp* app) { - SubghzAppViewManager* view_manager = app->get_view_manager(); - Submenu* submenu = view_manager->get_submenu(); - auto callback = cbc::obtain_connector(this, &SubghzSceneStart::submenu_callback); - - submenu_add_item(submenu, "Spectrum Analyzer", SubmenuIndexSpectrumAnalyzer, callback, app); - submenu_add_item(submenu, "Frequency Scanner", SubmenuIndexFrequencyScanner, callback, app); - submenu_add_item(submenu, "Signal Analyzer", SubmenuIndexSignalAnalyzer, callback, app); - submenu_add_item(submenu, "Signal Transmitter", SubmenuIndexSignalTransmitter, callback, app); - submenu_add_item(submenu, "Applications", SubmenuIndexApplications, callback, app); - - view_manager->switch_to(SubghzAppViewManager::ViewType::Submenu); -} - -bool SubghzSceneStart::on_event(SubghzApp* app, SubghzEvent* event) { - bool consumed = false; - - if(event->type == SubghzEvent::Type::MenuSelected) { - switch(event->payload.menu_index) { - case SubmenuIndexSpectrumAnalyzer: - app->switch_to_next_scene(SubghzApp::Scene::SceneSpectrumSettings); - break; - case SubmenuIndexFrequencyScanner: - break; - case SubmenuIndexSignalAnalyzer: - break; - case SubmenuIndexSignalTransmitter: - break; - case SubmenuIndexApplications: - break; - } - consumed = true; - } - - return consumed; -} - -void SubghzSceneStart::on_exit(SubghzApp* app) { - SubghzAppViewManager* view_manager = app->get_view_manager(); - Submenu* submenu = view_manager->get_submenu(); - - submenu_clean(submenu); -} - -void SubghzSceneStart::submenu_callback(void* context, uint32_t index) { - SubghzApp* app = static_cast(context); - SubghzEvent event; - - event.type = SubghzEvent::Type::MenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} \ No newline at end of file diff --git a/applications/subghz/scene/subghz-scene-start.h b/applications/subghz/scene/subghz-scene-start.h deleted file mode 100644 index 517973c1..00000000 --- a/applications/subghz/scene/subghz-scene-start.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "subghz-scene-generic.h" - -class SubghzSceneStart : public SubghzScene { -public: - void on_enter(SubghzApp* app) final; - bool on_event(SubghzApp* app, SubghzEvent* event) final; - void on_exit(SubghzApp* app) final; - -private: - void submenu_callback(void* context, uint32_t index); -}; \ No newline at end of file diff --git a/applications/subghz/subghz-app.cpp b/applications/subghz/subghz-app.cpp deleted file mode 100644 index 42078b21..00000000 --- a/applications/subghz/subghz-app.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "subghz-app.h" -#include -#include - -void SubghzApp::run(void) { - SubghzEvent event; - bool consumed; - bool exit = false; - - scenes[current_scene]->on_enter(this); - - while(!exit) { - view.receive_event(&event); - - consumed = scenes[current_scene]->on_event(this, &event); - - if(!consumed) { - if(event.type == SubghzEvent::Type::Back) { - exit = switch_to_previous_scene(); - } - } - }; - - scenes[current_scene]->on_exit(this); -} - -SubghzApp::SubghzApp() { - api_hal_power_insomnia_enter(); -} - -SubghzApp::~SubghzApp() { - api_hal_power_insomnia_exit(); -} - -SubghzAppViewManager* SubghzApp::get_view_manager() { - return &view; -} - -void SubghzApp::switch_to_next_scene(Scene next_scene) { - previous_scenes_list.push_front(current_scene); - - if(next_scene != Scene::SceneExit) { - scenes[current_scene]->on_exit(this); - current_scene = next_scene; - scenes[current_scene]->on_enter(this); - } -} - -void SubghzApp::search_and_switch_to_previous_scene(std::initializer_list scenes_list) { - Scene previous_scene = Scene::SceneStart; - bool scene_found = false; - - while(!scene_found) { - previous_scene = get_previous_scene(); - for(Scene element : scenes_list) { - if(previous_scene == element || previous_scene == Scene::SceneStart) { - scene_found = true; - break; - } - } - } - - scenes[current_scene]->on_exit(this); - current_scene = previous_scene; - scenes[current_scene]->on_enter(this); -} - -bool SubghzApp::switch_to_previous_scene(uint8_t count) { - Scene previous_scene = Scene::SceneStart; - - for(uint8_t i = 0; i < count; i++) { - previous_scene = get_previous_scene(); - if(previous_scene == Scene::SceneExit) break; - } - - if(previous_scene == Scene::SceneExit) { - return true; - } else { - scenes[current_scene]->on_exit(this); - current_scene = previous_scene; - scenes[current_scene]->on_enter(this); - return false; - } -} - -SubghzApp::Scene SubghzApp::get_previous_scene() { - Scene scene = previous_scenes_list.front(); - previous_scenes_list.pop_front(); - return scene; -} \ No newline at end of file diff --git a/applications/subghz/subghz-app.h b/applications/subghz/subghz-app.h deleted file mode 100644 index 1cea4b35..00000000 --- a/applications/subghz/subghz-app.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include -#include -#include "subghz-view-manager.h" - -#include "scene/subghz-scene-start.h" -#include "scene/subghz-scene-spectrum-settings.h" - -class SubghzApp { -public: - void run(void); - - SubghzApp(); - ~SubghzApp(); - - enum class Scene : uint8_t { - SceneExit, - SceneStart, - SceneSpectrumSettings, - }; - - SubghzAppViewManager* get_view_manager(); - void switch_to_next_scene(Scene index); - void search_and_switch_to_previous_scene(std::initializer_list scenes_list); - bool switch_to_previous_scene(uint8_t count = 1); - Scene get_previous_scene(); - -private: - std::list previous_scenes_list = {Scene::SceneExit}; - Scene current_scene = Scene::SceneStart; - SubghzAppViewManager view; - - std::map scenes = { - {Scene::SceneStart, new SubghzSceneStart()}, - {Scene::SceneSpectrumSettings, new SubghzSceneSpectrumSettings()}, - }; -}; \ No newline at end of file diff --git a/applications/subghz/subghz-event.h b/applications/subghz/subghz-event.h deleted file mode 100644 index 4f216a02..00000000 --- a/applications/subghz/subghz-event.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include - -class SubghzEvent { -public: - // events enum - enum class Type : uint8_t { - Tick, - Back, - MenuSelected, - NextScene, - }; - - // payload - union { - uint32_t menu_index; - } payload; - - // event type - Type type; -}; diff --git a/applications/subghz/subghz-view-manager.cpp b/applications/subghz/subghz-view-manager.cpp deleted file mode 100644 index 810376d2..00000000 --- a/applications/subghz/subghz-view-manager.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "subghz-view-manager.h" -#include "subghz-event.h" -#include - -SubghzAppViewManager::SubghzAppViewManager() { - event_queue = osMessageQueueNew(10, sizeof(SubghzEvent), NULL); - - view_dispatcher = view_dispatcher_alloc(); - auto callback = cbc::obtain_connector(this, &SubghzAppViewManager::previous_view_callback); - - // allocate views - submenu = submenu_alloc(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(SubghzAppViewManager::ViewType::Submenu), - submenu_get_view(submenu)); - - spectrum_settings = new SubghzViewSpectrumSettings(); - view_dispatcher_add_view( - view_dispatcher, - static_cast(SubghzAppViewManager::ViewType::SpectrumSettings), - spectrum_settings->get_view()); - - gui = static_cast(furi_record_open("gui")); - view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen); - - // set previous view callback for all views - view_set_previous_callback(submenu_get_view(submenu), callback); - view_set_previous_callback(spectrum_settings->get_view(), callback); -} - -SubghzAppViewManager::~SubghzAppViewManager() { - // remove views - view_dispatcher_remove_view( - view_dispatcher, static_cast(SubghzAppViewManager::ViewType::Submenu)); - view_dispatcher_remove_view( - view_dispatcher, static_cast(SubghzAppViewManager::ViewType::SpectrumSettings)); - - // free view modules - submenu_free(submenu); - free(spectrum_settings); - - // free dispatcher - view_dispatcher_free(view_dispatcher); - - // free event queue - osMessageQueueDelete(event_queue); -} - -void SubghzAppViewManager::switch_to(ViewType type) { - view_dispatcher_switch_to_view(view_dispatcher, static_cast(type)); -} - -Submenu* SubghzAppViewManager::get_submenu() { - return submenu; -} - -SubghzViewSpectrumSettings* SubghzAppViewManager::get_spectrum_settings() { - return spectrum_settings; -} - -void SubghzAppViewManager::receive_event(SubghzEvent* event) { - if(osMessageQueueGet(event_queue, event, NULL, 100) != osOK) { - event->type = SubghzEvent::Type::Tick; - } -} - -void SubghzAppViewManager::send_event(SubghzEvent* event) { - osStatus_t result = osMessageQueuePut(event_queue, event, 0, 0); - furi_check(result == osOK); -} - -uint32_t SubghzAppViewManager::previous_view_callback(void* context) { - if(event_queue != NULL) { - SubghzEvent event; - event.type = SubghzEvent::Type::Back; - send_event(&event); - } - - return VIEW_IGNORE; -} \ No newline at end of file diff --git a/applications/subghz/subghz-view-manager.h b/applications/subghz/subghz-view-manager.h deleted file mode 100644 index 733a8356..00000000 --- a/applications/subghz/subghz-view-manager.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include -#include -#include -#include "subghz-event.h" -#include "view/subghz-view-spectrum-settings.h" - -class SubghzAppViewManager { -public: - enum class ViewType : uint8_t { - Submenu, - SpectrumSettings, - }; - - osMessageQueueId_t event_queue; - - SubghzAppViewManager(); - ~SubghzAppViewManager(); - - void switch_to(ViewType type); - - void receive_event(SubghzEvent* event); - void send_event(SubghzEvent* event); - - Submenu* get_submenu(); - SubghzViewSpectrumSettings* get_spectrum_settings(); - -private: - ViewDispatcher* view_dispatcher; - Gui* gui; - - uint32_t previous_view_callback(void* context); - - // view elements - Submenu* submenu; - SubghzViewSpectrumSettings* spectrum_settings; -}; \ No newline at end of file diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c new file mode 100644 index 00000000..723e7026 --- /dev/null +++ b/applications/subghz/subghz.c @@ -0,0 +1,98 @@ +#include "subghz_i.h" + +osThreadId subghz_thread_id = NULL; + +void subghz_menu_callback(void* context, uint32_t index) { + furi_assert(context); + + SubGhz* subghz = context; + + if(index == 0) { + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTestBasic); + } else if(index == 1) { + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewTestPacket); + } +} + +uint32_t subghz_exit(void* context) { + osThreadResume(subghz_thread_id); + return VIEW_NONE; +} + +SubGhz* subghz_alloc() { + SubGhz* subghz = furi_alloc(sizeof(SubGhz)); + + // Thread id + subghz_thread_id = osThreadGetId(); + + // GUI + subghz->gui = furi_record_open("gui"); + + // View Dispatcher + subghz->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_attach_to_gui( + subghz->view_dispatcher, subghz->gui, ViewDispatcherTypeFullscreen); + + // Menu + subghz->submenu = submenu_alloc(); + submenu_add_item(subghz->submenu, "Basic Test", 0, subghz_menu_callback, subghz); + submenu_add_item(subghz->submenu, "Packet Test", 1, subghz_menu_callback, subghz); + View* submenu_view = submenu_get_view(subghz->submenu); + view_set_previous_callback(submenu_view, subghz_exit); + view_dispatcher_add_view(subghz->view_dispatcher, SubGhzViewMenu, submenu_view); + + // Basic Test Module + subghz->subghz_test_basic = subghz_test_basic_alloc(); + view_dispatcher_add_view( + subghz->view_dispatcher, + SubGhzViewTestBasic, + subghz_test_basic_get_view(subghz->subghz_test_basic)); + + // Packet Test + subghz->subghz_test_packet = subghz_test_packet_alloc(); + view_dispatcher_add_view( + subghz->view_dispatcher, + SubGhzViewTestPacket, + subghz_test_packet_get_view(subghz->subghz_test_packet)); + + // Switch to menu + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewMenu); + + return subghz; +} + +void subghz_free(SubGhz* subghz) { + furi_assert(subghz); + + // Packet Test + view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewTestPacket); + subghz_test_packet_free(subghz->subghz_test_packet); + + // Basic Test + view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewTestBasic); + subghz_test_basic_free(subghz->subghz_test_basic); + + // Submenu + view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewMenu); + submenu_free(subghz->submenu); + + // View Dispatcher + view_dispatcher_free(subghz->view_dispatcher); + + // GUI + furi_record_close("gui"); + subghz->gui = NULL; + + // The rest + free(subghz); +} + +int32_t subghz_app(void* context) { + SubGhz* subghz = subghz_alloc(); + + osThreadSuspend(subghz_thread_id); + + subghz_free(subghz); + + return 0; +} \ No newline at end of file diff --git a/applications/subghz/subghz.cpp b/applications/subghz/subghz.cpp deleted file mode 100644 index 52540a6e..00000000 --- a/applications/subghz/subghz.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "subghz-app.h" - -// app enter function -extern "C" int32_t app_subghz(void* p) { - SubghzApp* app = new SubghzApp(); - app->run(); - delete app; - - return 255; -} \ No newline at end of file diff --git a/applications/subghz/subghz.h b/applications/subghz/subghz.h new file mode 100644 index 00000000..16e1e857 --- /dev/null +++ b/applications/subghz/subghz.h @@ -0,0 +1,3 @@ +#pragma once + +typedef struct SubGhz SubGhz; \ No newline at end of file diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h new file mode 100644 index 00000000..424afe8b --- /dev/null +++ b/applications/subghz/subghz_i.h @@ -0,0 +1,44 @@ +#pragma once + +#include "subghz.h" +#include "subghz_test_basic.h" +#include "subghz_test_packet.h" + +#include +#include +#include +#include + +static const uint32_t subghz_frequencies[] = { + 301000000, + 315000000, + 346000000, + 385000000, + 433920000, + 438900000, + 463000000, + 781000000, + 868000000, + 915000000, + 925000000, +}; + +static const uint32_t subghz_frequencies_count = sizeof(subghz_frequencies) / sizeof(uint32_t); + +struct SubGhz { + Gui* gui; + + ViewDispatcher* view_dispatcher; + + Submenu* submenu; + + SubghzTestBasic* subghz_test_basic; + + SubghzTestPacket* subghz_test_packet; +}; + +typedef enum { + SubGhzViewMenu, + SubGhzViewTestBasic, + SubGhzViewTestPacket, +} SubGhzView; diff --git a/applications/subghz/subghz_test_basic.c b/applications/subghz/subghz_test_basic.c new file mode 100644 index 00000000..af61e2c1 --- /dev/null +++ b/applications/subghz/subghz_test_basic.c @@ -0,0 +1,203 @@ +#include "subghz_test_basic.h" +#include "subghz_i.h" + +#include +#include +#include +#include + +struct SubghzTestBasic { + View* view; + osTimerId timer; +}; + +typedef enum { + SubghzTestBasicModelStatusRx, + SubghzTestBasicModelStatusTx, +} SubghzTestBasicModelStatus; + +typedef struct { + uint8_t frequency; + uint32_t real_frequency; + ApiHalSubGhzPath path; + float rssi; + SubghzTestBasicModelStatus status; +} SubghzTestBasicModel; + +void subghz_test_basic_draw(Canvas* canvas, SubghzTestBasicModel* model) { + char buffer[64]; + + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 2, 12, "CC1101 Basic Test"); + + canvas_set_font(canvas, FontSecondary); + // Frequency + snprintf( + buffer, + sizeof(buffer), + "Freq: %03ld.%03ld.%03ld Hz", + model->real_frequency / 1000000 % 1000, + model->real_frequency / 1000 % 1000, + model->real_frequency % 1000); + canvas_draw_str(canvas, 2, 24, buffer); + // Path + char* path_name = "Unknown"; + if(model->path == ApiHalSubGhzPathIsolate) { + path_name = "isolate"; + } else if(model->path == ApiHalSubGhzPath1) { + path_name = "433MHz"; + } else if(model->path == ApiHalSubGhzPath2) { + path_name = "315MHz"; + } else if(model->path == ApiHalSubGhzPath3) { + path_name = "868MHz"; + } + snprintf(buffer, sizeof(buffer), "Path: %d - %s", model->path, path_name); + canvas_draw_str(canvas, 2, 36, buffer); + if(model->status == SubghzTestBasicModelStatusRx) { + snprintf( + buffer, + sizeof(buffer), + "RSSI: %ld.%ld dBm", + (int32_t)(model->rssi), + (int32_t)fabs(model->rssi * 10) % 10); + canvas_draw_str(canvas, 2, 48, buffer); + } else { + canvas_draw_str(canvas, 2, 48, "TX"); + } +} + +bool subghz_test_basic_input(InputEvent* event, void* context) { + furi_assert(context); + SubghzTestBasic* subghz_test_basic = context; + + if(event->key == InputKeyBack) { + return false; + } + + with_view_model( + subghz_test_basic->view, (SubghzTestBasicModel * model) { + osTimerStop(subghz_test_basic->timer); + api_hal_subghz_idle(); + + if(event->type == InputTypeShort) { + if(event->key == InputKeyLeft) { + if(model->frequency > 0) model->frequency--; + } else if(event->key == InputKeyRight) { + if(model->frequency < subghz_frequencies_count - 1) model->frequency++; + } else if(event->key == InputKeyDown) { + if(model->path > 0) model->path--; + } else if(event->key == InputKeyUp) { + if(model->path < ApiHalSubGhzPath3) model->path++; + } + + model->real_frequency = + api_hal_subghz_set_frequency(subghz_frequencies[model->frequency]); + api_hal_subghz_set_path(model->path); + } + + if(event->key == InputKeyOk) { + if(event->type == InputTypePress) { + model->status = SubghzTestBasicModelStatusTx; + } else if(event->type == InputTypeRelease) { + model->status = SubghzTestBasicModelStatusRx; + } + } + + if(model->status == SubghzTestBasicModelStatusRx) { + gpio_init(&cc1101_g0_gpio, GpioModeInput); + api_hal_subghz_rx(); + osTimerStart(subghz_test_basic->timer, 1024 / 4); + } else { + gpio_init(&cc1101_g0_gpio, GpioModeOutputPushPull); + gpio_write(&cc1101_g0_gpio, false); + api_hal_subghz_tx(); + } + + return true; + }); + + return true; +} + +void subghz_test_basic_enter(void* context) { + furi_assert(context); + SubghzTestBasic* subghz_test_basic = context; + + api_hal_subghz_reset(); + api_hal_subghz_load_preset(ApiHalSubGhzPresetOokAsync); + + gpio_init(&cc1101_g0_gpio, GpioModeInput); + + with_view_model( + subghz_test_basic->view, (SubghzTestBasicModel * model) { + model->frequency = 4; // 433 + model->real_frequency = + api_hal_subghz_set_frequency(subghz_frequencies[model->frequency]); + model->path = ApiHalSubGhzPathIsolate; // isolate + model->rssi = 0.0f; + model->status = SubghzTestBasicModelStatusRx; + return true; + }); + + api_hal_subghz_rx(); + + osTimerStart(subghz_test_basic->timer, 1024 / 4); +} + +void subghz_test_basic_exit(void* context) { + furi_assert(context); + SubghzTestBasic* subghz_test_basic = context; + + osTimerStop(subghz_test_basic->timer); + + // Reinitialize IC to default state + api_hal_subghz_init(); +} + +void subghz_test_basic_rssi_timer_callback(void* context) { + furi_assert(context); + SubghzTestBasic* subghz_test_basic = context; + + with_view_model( + subghz_test_basic->view, (SubghzTestBasicModel * model) { + model->rssi = api_hal_subghz_get_rssi(); + return true; + }); +} + +uint32_t subghz_test_basic_back(void* context) { + return SubGhzViewMenu; +} + +SubghzTestBasic* subghz_test_basic_alloc() { + SubghzTestBasic* subghz_test_basic = furi_alloc(sizeof(SubghzTestBasic)); + + // View allocation and configuration + subghz_test_basic->view = view_alloc(); + view_allocate_model( + subghz_test_basic->view, ViewModelTypeLockFree, sizeof(SubghzTestBasicModel)); + view_set_context(subghz_test_basic->view, subghz_test_basic); + view_set_draw_callback(subghz_test_basic->view, (ViewDrawCallback)subghz_test_basic_draw); + view_set_input_callback(subghz_test_basic->view, subghz_test_basic_input); + view_set_enter_callback(subghz_test_basic->view, subghz_test_basic_enter); + view_set_exit_callback(subghz_test_basic->view, subghz_test_basic_exit); + view_set_previous_callback(subghz_test_basic->view, subghz_test_basic_back); + + subghz_test_basic->timer = osTimerNew( + subghz_test_basic_rssi_timer_callback, osTimerPeriodic, subghz_test_basic, NULL); + + return subghz_test_basic; +} + +void subghz_test_basic_free(SubghzTestBasic* subghz_test_basic) { + furi_assert(subghz_test_basic); + osTimerDelete(subghz_test_basic->timer); + view_free(subghz_test_basic->view); + free(subghz_test_basic); +} + +View* subghz_test_basic_get_view(SubghzTestBasic* subghz_test_basic) { + furi_assert(subghz_test_basic); + return subghz_test_basic->view; +} diff --git a/applications/subghz/subghz_test_basic.h b/applications/subghz/subghz_test_basic.h new file mode 100644 index 00000000..5229c7c6 --- /dev/null +++ b/applications/subghz/subghz_test_basic.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +typedef struct SubghzTestBasic SubghzTestBasic; + +SubghzTestBasic* subghz_test_basic_alloc(); + +void subghz_test_basic_free(SubghzTestBasic* subghz_test_basic); + +View* subghz_test_basic_get_view(SubghzTestBasic* subghz_test_basic); diff --git a/applications/subghz/subghz_test_packet.c b/applications/subghz/subghz_test_packet.c new file mode 100644 index 00000000..2b695818 --- /dev/null +++ b/applications/subghz/subghz_test_packet.c @@ -0,0 +1,210 @@ +#include "subghz_test_packet.h" +#include "subghz_i.h" + +#include +#include +#include +#include + +static const uint8_t subghz_test_packet_data[] = { + 0x30, // 48bytes to transmit + 'F', 'L', 'I', 'P', 'P', 'E', 'R', ' ', 'T', 'E', 'S', 'T', ' ', 'P', 'A', 'C', + 'K', 'E', 'T', ' ', 'D', 'A', 'T', 'A', ' ', 'A', 'N', 'D', ' ', 'P', 'A', 'D', + 'F', 'L', 'I', 'P', 'P', 'E', 'R', ' ', 'T', 'E', 'S', 'T', ' ', 'P', 'A', 'C', + +}; + +struct SubghzTestPacket { + View* view; + osTimerId timer; +}; + +typedef enum { + SubghzTestPacketModelStatusRx, + SubghzTestPacketModelStatusTx, +} SubghzTestPacketModelStatus; + +typedef struct { + uint8_t frequency; + uint32_t real_frequency; + ApiHalSubGhzPath path; + float rssi; + SubghzTestPacketModelStatus status; +} SubghzTestPacketModel; + +void subghz_test_packet_draw(Canvas* canvas, SubghzTestPacketModel* model) { + char buffer[64]; + + canvas_set_color(canvas, ColorBlack); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 2, 12, "CC1101 Packet Test"); + + canvas_set_font(canvas, FontSecondary); + // Frequency + snprintf( + buffer, + sizeof(buffer), + "Freq: %03ld.%03ld.%03ld Hz", + model->real_frequency / 1000000 % 1000, + model->real_frequency / 1000 % 1000, + model->real_frequency % 1000); + canvas_draw_str(canvas, 2, 24, buffer); + // Path + char* path_name = "Unknown"; + if(model->path == ApiHalSubGhzPathIsolate) { + path_name = "isolate"; + } else if(model->path == ApiHalSubGhzPath1) { + path_name = "433MHz"; + } else if(model->path == ApiHalSubGhzPath2) { + path_name = "315MHz"; + } else if(model->path == ApiHalSubGhzPath3) { + path_name = "868MHz"; + } + snprintf(buffer, sizeof(buffer), "Path: %d - %s", model->path, path_name); + canvas_draw_str(canvas, 2, 36, buffer); + if(model->status == SubghzTestPacketModelStatusRx) { + snprintf( + buffer, + sizeof(buffer), + "RSSI: %ld.%ld dBm", + (int32_t)(model->rssi), + (int32_t)fabs(model->rssi * 10) % 10); + canvas_draw_str(canvas, 2, 48, buffer); + } else { + canvas_draw_str(canvas, 2, 48, "TX"); + } +} + +bool subghz_test_packet_input(InputEvent* event, void* context) { + furi_assert(context); + SubghzTestPacket* subghz_test_packet = context; + + if(event->key == InputKeyBack) { + return false; + } + + with_view_model( + subghz_test_packet->view, (SubghzTestPacketModel * model) { + osTimerStop(subghz_test_packet->timer); + api_hal_subghz_idle(); + + if(event->type == InputTypeShort) { + if(event->key == InputKeyLeft) { + if(model->frequency > 0) model->frequency--; + } else if(event->key == InputKeyRight) { + if(model->frequency < subghz_frequencies_count - 1) model->frequency++; + } else if(event->key == InputKeyDown) { + if(model->path > 0) model->path--; + } else if(event->key == InputKeyUp) { + if(model->path < ApiHalSubGhzPath3) model->path++; + } + + model->real_frequency = + api_hal_subghz_set_frequency(subghz_frequencies[model->frequency]); + api_hal_subghz_set_path(model->path); + } + + if(event->key == InputKeyOk) { + if(event->type == InputTypePress) { + model->status = SubghzTestPacketModelStatusTx; + } else if(event->type == InputTypeRelease) { + model->status = SubghzTestPacketModelStatusRx; + } + } + + if(model->status == SubghzTestPacketModelStatusRx) { + api_hal_subghz_rx(); + osTimerStart(subghz_test_packet->timer, 1024 / 4); + } else { + api_hal_subghz_write_packet( + subghz_test_packet_data, sizeof(subghz_test_packet_data)); + api_hal_subghz_tx(); + } + + return true; + }); + + return true; +} + +void subghz_test_packet_enter(void* context) { + furi_assert(context); + SubghzTestPacket* subghz_test_packet = context; + + api_hal_subghz_reset(); + api_hal_subghz_load_preset(ApiHalSubGhzPreset2FskPacket); + + gpio_init(&cc1101_g0_gpio, GpioModeInput); + + with_view_model( + subghz_test_packet->view, (SubghzTestPacketModel * model) { + model->frequency = 4; // 433 + model->real_frequency = + api_hal_subghz_set_frequency(subghz_frequencies[model->frequency]); + model->path = ApiHalSubGhzPathIsolate; // isolate + model->rssi = 0.0f; + model->status = SubghzTestPacketModelStatusRx; + return true; + }); + + api_hal_subghz_rx(); + + osTimerStart(subghz_test_packet->timer, 1024 / 4); +} + +void subghz_test_packet_exit(void* context) { + furi_assert(context); + SubghzTestPacket* subghz_test_packet = context; + + osTimerStop(subghz_test_packet->timer); + + // Reinitialize IC to default state + api_hal_subghz_init(); +} + +void subghz_test_packet_rssi_timer_callback(void* context) { + furi_assert(context); + SubghzTestPacket* subghz_test_packet = context; + + with_view_model( + subghz_test_packet->view, (SubghzTestPacketModel * model) { + model->rssi = api_hal_subghz_get_rssi(); + return true; + }); +} + +uint32_t subghz_test_packet_back(void* context) { + return SubGhzViewMenu; +} + +SubghzTestPacket* subghz_test_packet_alloc() { + SubghzTestPacket* subghz_test_packet = furi_alloc(sizeof(SubghzTestPacket)); + + // View allocation and configuration + subghz_test_packet->view = view_alloc(); + view_allocate_model( + subghz_test_packet->view, ViewModelTypeLockFree, sizeof(SubghzTestPacketModel)); + view_set_context(subghz_test_packet->view, subghz_test_packet); + view_set_draw_callback(subghz_test_packet->view, (ViewDrawCallback)subghz_test_packet_draw); + view_set_input_callback(subghz_test_packet->view, subghz_test_packet_input); + view_set_enter_callback(subghz_test_packet->view, subghz_test_packet_enter); + view_set_exit_callback(subghz_test_packet->view, subghz_test_packet_exit); + view_set_previous_callback(subghz_test_packet->view, subghz_test_packet_back); + + subghz_test_packet->timer = osTimerNew( + subghz_test_packet_rssi_timer_callback, osTimerPeriodic, subghz_test_packet, NULL); + + return subghz_test_packet; +} + +void subghz_test_packet_free(SubghzTestPacket* subghz_test_packet) { + furi_assert(subghz_test_packet); + osTimerDelete(subghz_test_packet->timer); + view_free(subghz_test_packet->view); + free(subghz_test_packet); +} + +View* subghz_test_packet_get_view(SubghzTestPacket* subghz_test_packet) { + furi_assert(subghz_test_packet); + return subghz_test_packet->view; +} diff --git a/applications/subghz/subghz_test_packet.h b/applications/subghz/subghz_test_packet.h new file mode 100644 index 00000000..00fae10e --- /dev/null +++ b/applications/subghz/subghz_test_packet.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +typedef struct SubghzTestPacket SubghzTestPacket; + +SubghzTestPacket* subghz_test_packet_alloc(); + +void subghz_test_packet_free(SubghzTestPacket* subghz_test_packet); + +View* subghz_test_packet_get_view(SubghzTestPacket* subghz_test_packet); diff --git a/applications/subghz/view/subghz-view-spectrum-settings.cpp b/applications/subghz/view/subghz-view-spectrum-settings.cpp deleted file mode 100644 index 715c2a01..00000000 --- a/applications/subghz/view/subghz-view-spectrum-settings.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "subghz-view-spectrum-settings.h" -#include - -struct SpectrumSettingsModel { - uint32_t start_freq; -}; - -/***************************************************************************************/ - -static void draw_callback(Canvas* canvas, void* _model) { - SpectrumSettingsModel* model = static_cast(_model); - const uint8_t str_size = 64; - char str_buffer[str_size]; - - canvas_clear(canvas); - snprintf(str_buffer, str_size, "Start freq < %ld > MHz", model->start_freq); - canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, str_buffer); -} - -static bool input_callback(InputEvent* event, void* context) { - SubghzViewSpectrumSettings* _this = static_cast(context); - - bool consumed = false; - - // Process key presses only - if(event->type == InputTypeShort) { - if(event->key == InputKeyOk) { - _this->call_ok_callback(); - consumed = true; - } else if(event->key == InputKeyLeft) { - with_view_model_cpp(_this->get_view(), SpectrumSettingsModel, model, { - model->start_freq--; - return true; - }); - consumed = true; - } else if(event->key == InputKeyRight) { - with_view_model_cpp(_this->get_view(), SpectrumSettingsModel, model, { - model->start_freq++; - return true; - }); - consumed = true; - } - } - - return consumed; -} - -/***************************************************************************************/ - -View* SubghzViewSpectrumSettings::get_view() { - return view; -} - -void SubghzViewSpectrumSettings::set_ok_callback(OkCallback callback, void* context) { - ok_callback = callback; - ok_callback_context = context; -} - -void SubghzViewSpectrumSettings::call_ok_callback() { - if(ok_callback != nullptr) { - ok_callback(ok_callback_context); - } -} - -void SubghzViewSpectrumSettings::set_start_freq(uint32_t start_freq) { - with_view_model_cpp(view, SpectrumSettingsModel, model, { - model->start_freq = start_freq; - return true; - }); -} - -uint32_t SubghzViewSpectrumSettings::get_start_freq() { - uint32_t result; - - with_view_model_cpp(view, SpectrumSettingsModel, model, { - result = model->start_freq; - return false; - }); - - return result; -} - -SubghzViewSpectrumSettings::SubghzViewSpectrumSettings() { - view = view_alloc(); - view_set_context(view, this); - view_allocate_model(view, ViewModelTypeLocking, sizeof(SpectrumSettingsModel)); - - view_set_draw_callback(view, draw_callback); - - view_set_input_callback(view, input_callback); -} - -SubghzViewSpectrumSettings::~SubghzViewSpectrumSettings() { - view_free(view); -} \ No newline at end of file diff --git a/applications/subghz/view/subghz-view-spectrum-settings.h b/applications/subghz/view/subghz-view-spectrum-settings.h deleted file mode 100644 index 6eb47e4f..00000000 --- a/applications/subghz/view/subghz-view-spectrum-settings.h +++ /dev/null @@ -1,25 +0,0 @@ -#include - -class SubghzViewSpectrumSettings { -public: - SubghzViewSpectrumSettings(); - ~SubghzViewSpectrumSettings(); - - View* get_view(); - - // ok callback methods - typedef void (*OkCallback)(void* context); - void set_ok_callback(OkCallback callback, void* context); - void call_ok_callback(); - - // model data getters/setters - void set_start_freq(uint32_t start_freq); - uint32_t get_start_freq(); - -private: - View* view; - - // ok callback data - OkCallback ok_callback = nullptr; - void* ok_callback_context = nullptr; -}; diff --git a/debug/stm32wbx.cfg b/debug/stm32wbx.cfg index 3f190c18..f100c3cc 100644 --- a/debug/stm32wbx.cfg +++ b/debug/stm32wbx.cfg @@ -55,7 +55,7 @@ flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME # # Note that there is a pretty wide band where things are # more or less stable, see http://openocd.zylin.com/#/c/3366/ -adapter speed 8000 +adapter speed 24000 adapter srst delay 100 if {[using_jtag]} { @@ -77,12 +77,12 @@ $_TARGETNAME configure -event reset-init { mmw 0x58004000 0x00000102 0 ;# FLASH_ACR |= PRFTBE | 2(Latency) mmw 0x58000000 0x00000091 0 ;# RCC_CR = MSI_ON | MSI Range 24 MHz # Boost JTAG frequency - adapter speed 8000 + adapter speed 24000 } $_TARGETNAME configure -event reset-start { # Reset clock is MSI (4 MHz) - adapter speed 8000 + adapter speed 24000 } $_TARGETNAME configure -event examine-end { diff --git a/firmware/targets/api-hal-include/api-hal-subghz.h b/firmware/targets/api-hal-include/api-hal-subghz.h index 650374ad..2cb2efd9 100644 --- a/firmware/targets/api-hal-include/api-hal-subghz.h +++ b/firmware/targets/api-hal-include/api-hal-subghz.h @@ -1,23 +1,98 @@ #pragma once +#include +#include + #ifdef __cplusplus extern "C" { #endif -/** Sub-GHz band type */ +/** Radio Presets */ typedef enum { - RfBandIsolation = 0, - RfBand1 = 1, - RfBand2 = 2, - RfBand3 = 3 -} RfBand; + ApiHalSubGhzPresetOokAsync, /** OOK, asynchronous */ + ApiHalSubGhzPreset2FskPacket, /** 2FSK, 115kBaud, variable packet length */ +} ApiHalSubGhzPreset; -/** - * Set Sub-GHz band - * @param band RfBand +/** Switchable Radio Paths */ +typedef enum { + ApiHalSubGhzPathIsolate, /** Isolate Radio from antenna */ + ApiHalSubGhzPath1, /** Path 1: SW1RF1-SW2RF2, LCLCL */ + ApiHalSubGhzPath2, /** Path 2: SW1RF2-SW2RF1, LCLCLCL */ + ApiHalSubGhzPath3, /** Path 3: SW1RF3-SW2RF3, LCLC */ +} ApiHalSubGhzPath; + +/** Initialize and switch to power save mode + * Used by internal API-HAL initalization routine + * Can be used to reinitialize device to safe state and send it to sleep */ -void api_hal_rf_band_set(RfBand band); +void api_hal_subghz_init(); + +/** Dump info to stdout */ +void api_hal_subghz_dump_state(); + +/** Load registers from preset by preset name + * @param preset to load + */ +void api_hal_subghz_load_preset(ApiHalSubGhzPreset preset); + +/** Load registers + * @param register-value pairs array, terminated with {0,0} + */ +void api_hal_subghz_load_registers(const uint8_t data[][2]); + +/** Load PATABLE + * @param data, 8 uint8_t values + */ +void api_hal_subghz_load_patable(const uint8_t data[8]); + +/** Write packet to FIFO + * @param data, bytes array + * @param size, size + */ +void api_hal_subghz_write_packet(const uint8_t* data, uint8_t size); + +/** Read packet from FIFO + * @param data, pointer + * @param size, size + */ +void api_hal_subghz_read_packet(uint8_t* data, uint8_t size); + +/** Shutdown + * Issue spwd command + * @warning registers content will be lost + */ +void api_hal_subghz_shutdown(); + +/** Reset + * Issue reset command + * @warning registers content will be lost + */ +void api_hal_subghz_reset(); + +/** Switch to Idle */ +void api_hal_subghz_idle(); + +/** Switch to Recieve */ +void api_hal_subghz_rx(); + +/** Switch to Transmit */ +void api_hal_subghz_tx(); + +/** Get RSSI value in dBm */ +float api_hal_subghz_get_rssi(); + +/** Set frequency + * @param frequency in herz + * @return real frequency in herz + */ +uint32_t api_hal_subghz_set_frequency(uint32_t value); + +/** Set path + * @param radio path to use + */ +void api_hal_subghz_set_path(ApiHalSubGhzPath path); + #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/firmware/targets/f4/Inc/main.h b/firmware/targets/f4/Inc/main.h index d5ec149f..62cba8db 100644 --- a/firmware/targets/f4/Inc/main.h +++ b/firmware/targets/f4/Inc/main.h @@ -1,153 +1,103 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : main.h - * @brief : Header for main.c file. - * This file contains the common defines of the application. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __MAIN_H -#define __MAIN_H +#pragma once #ifdef __cplusplus extern "C" { #endif -/* Includes ------------------------------------------------------------------*/ #include "stm32wbxx_hal.h" -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Exported types ------------------------------------------------------------*/ -/* USER CODE BEGIN ET */ - -/* USER CODE END ET */ - -/* Exported constants --------------------------------------------------------*/ -/* USER CODE BEGIN EC */ - -/* USER CODE END EC */ - -/* Exported macro ------------------------------------------------------------*/ -/* USER CODE BEGIN EM */ - -/* USER CODE END EM */ - -/* Exported functions prototypes ---------------------------------------------*/ void Error_Handler(void); -/* USER CODE BEGIN EFP */ - -/* USER CODE END EFP */ - -/* Private defines -----------------------------------------------------------*/ -#define BUTTON_BACK_Pin GPIO_PIN_13 -#define BUTTON_BACK_GPIO_Port GPIOC #define BUTTON_BACK_EXTI_IRQn EXTI15_10_IRQn -#define QUARTZ_32MHZ_IN_Pin GPIO_PIN_14 -#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC -#define QUARTZ_32MHZ_OUT_Pin GPIO_PIN_15 -#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC -#define BUTTON_OK_Pin GPIO_PIN_3 -#define BUTTON_OK_GPIO_Port GPIOH -#define BUTTON_OK_EXTI_IRQn EXTI3_IRQn -#define SPEAKER_Pin GPIO_PIN_8 -#define SPEAKER_GPIO_Port GPIOB -#define IR_TX_Pin GPIO_PIN_9 -#define IR_TX_GPIO_Port GPIOB -#define PC0_Pin GPIO_PIN_0 -#define PC0_GPIO_Port GPIOC -#define PC1_Pin GPIO_PIN_1 -#define PC1_GPIO_Port GPIOC -#define PC3_Pin GPIO_PIN_3 -#define PC3_GPIO_Port GPIOC -#define IR_RX_Pin GPIO_PIN_0 -#define IR_RX_GPIO_Port GPIOA -#define LED_RED_Pin GPIO_PIN_1 -#define LED_RED_GPIO_Port GPIOA -#define LED_GREEN_Pin GPIO_PIN_2 -#define LED_GREEN_GPIO_Port GPIOA -#define LED_BLUE_Pin GPIO_PIN_3 -#define LED_BLUE_GPIO_Port GPIOA -#define PA4_Pin GPIO_PIN_4 -#define PA4_GPIO_Port GPIOA -#define SPI_R_SCK_Pin GPIO_PIN_5 -#define SPI_R_SCK_GPIO_Port GPIOA -#define PA6_Pin GPIO_PIN_6 -#define PA6_GPIO_Port GPIOA -#define PA7_Pin GPIO_PIN_7 -#define PA7_GPIO_Port GPIOA -#define RFID_PULL_Pin GPIO_PIN_8 -#define RFID_PULL_GPIO_Port GPIOA -#define RFID_PULL_EXTI_IRQn EXTI9_5_IRQn -#define CC1101_G0_Pin GPIO_PIN_4 -#define CC1101_G0_GPIO_Port GPIOC -#define RFID_RF_IN_Pin GPIO_PIN_5 -#define RFID_RF_IN_GPIO_Port GPIOC -#define PB2_Pin GPIO_PIN_2 -#define PB2_GPIO_Port GPIOB -#define BUTTON_UP_Pin GPIO_PIN_10 -#define BUTTON_UP_GPIO_Port GPIOB -#define BUTTON_UP_EXTI_IRQn EXTI15_10_IRQn -#define BUTTON_LEFT_Pin GPIO_PIN_11 -#define BUTTON_LEFT_GPIO_Port GPIOB -#define BUTTON_LEFT_EXTI_IRQn EXTI15_10_IRQn -#define DISPLAY_RST_Pin GPIO_PIN_0 -#define DISPLAY_RST_GPIO_Port GPIOB -#define BUTTON_DOWN_Pin GPIO_PIN_1 -#define BUTTON_DOWN_GPIO_Port GPIOB +#define BUTTON_BACK_GPIO_Port GPIOC +#define BUTTON_BACK_Pin GPIO_PIN_13 #define BUTTON_DOWN_EXTI_IRQn EXTI1_IRQn -#define NFC_CS_Pin GPIO_PIN_4 -#define NFC_CS_GPIO_Port GPIOE -#define BUTTON_RIGHT_Pin GPIO_PIN_12 -#define BUTTON_RIGHT_GPIO_Port GPIOB +#define BUTTON_DOWN_GPIO_Port GPIOB +#define BUTTON_DOWN_Pin GPIO_PIN_1 +#define BUTTON_LEFT_EXTI_IRQn EXTI15_10_IRQn +#define BUTTON_LEFT_GPIO_Port GPIOB +#define BUTTON_LEFT_Pin GPIO_PIN_11 +#define BUTTON_OK_EXTI_IRQn EXTI3_IRQn +#define BUTTON_OK_GPIO_Port GPIOH +#define BUTTON_OK_Pin GPIO_PIN_3 #define BUTTON_RIGHT_EXTI_IRQn EXTI15_10_IRQn -#define RFID_OUT_Pin GPIO_PIN_13 -#define RFID_OUT_GPIO_Port GPIOB -#define iBTN_Pin GPIO_PIN_14 -#define iBTN_GPIO_Port GPIOB -#define SPI_D_MOSI_Pin GPIO_PIN_15 -#define SPI_D_MOSI_GPIO_Port GPIOB -#define DISPLAY_DI_Pin GPIO_PIN_6 -#define DISPLAY_DI_GPIO_Port GPIOC -#define DISPLAY_BACKLIGHT_Pin GPIO_PIN_15 -#define DISPLAY_BACKLIGHT_GPIO_Port GPIOA -#define PC10_Pin GPIO_PIN_10 -#define PC10_GPIO_Port GPIOC -#define DISPLAY_CS_Pin GPIO_PIN_11 -#define DISPLAY_CS_GPIO_Port GPIOC -#define SD_CS_Pin GPIO_PIN_12 -#define SD_CS_GPIO_Port GPIOC -#define CC1101_CS_Pin GPIO_PIN_0 +#define BUTTON_RIGHT_GPIO_Port GPIOB +#define BUTTON_RIGHT_Pin GPIO_PIN_12 +#define BUTTON_UP_EXTI_IRQn EXTI15_10_IRQn +#define BUTTON_UP_GPIO_Port GPIOB +#define BUTTON_UP_Pin GPIO_PIN_10 #define CC1101_CS_GPIO_Port GPIOD -#define SPI_D_SCK_Pin GPIO_PIN_1 -#define SPI_D_SCK_GPIO_Port GPIOD -#define PB3_Pin GPIO_PIN_3 +#define CC1101_CS_Pin GPIO_PIN_0 +#define CC1101_G0_GPIO_Port GPIOC +#define CC1101_G0_Pin GPIO_PIN_4 +#define DISPLAY_BACKLIGHT_GPIO_Port GPIOA +#define DISPLAY_BACKLIGHT_Pin GPIO_PIN_15 +#define DISPLAY_CS_GPIO_Port GPIOC +#define DISPLAY_CS_Pin GPIO_PIN_11 +#define DISPLAY_DI_GPIO_Port GPIOC +#define DISPLAY_DI_Pin GPIO_PIN_6 +#define DISPLAY_RST_GPIO_Port GPIOB +#define DISPLAY_RST_Pin GPIO_PIN_0 +#define IR_RX_GPIO_Port GPIOA +#define IR_RX_Pin GPIO_PIN_0 +#define IR_TX_GPIO_Port GPIOB +#define IR_TX_Pin GPIO_PIN_9 +#define LED_BLUE_GPIO_Port GPIOA +#define LED_BLUE_Pin GPIO_PIN_3 +#define LED_GREEN_GPIO_Port GPIOA +#define LED_GREEN_Pin GPIO_PIN_2 +#define LED_RED_GPIO_Port GPIOA +#define LED_RED_Pin GPIO_PIN_1 +#define NFC_CS_GPIO_Port GPIOE +#define NFC_CS_Pin GPIO_PIN_4 +#define PA4_GPIO_Port GPIOA +#define PA4_Pin GPIO_PIN_4 +#define PA6_GPIO_Port GPIOA +#define PA6_Pin GPIO_PIN_6 +#define PA7_GPIO_Port GPIOA +#define PA7_Pin GPIO_PIN_7 +#define PB2_GPIO_Port GPIOB +#define PB2_Pin GPIO_PIN_2 #define PB3_GPIO_Port GPIOB -#define SPI_R_MISO_Pin GPIO_PIN_4 -#define SPI_R_MISO_GPIO_Port GPIOB -#define SPI_R_MOSI_Pin GPIO_PIN_5 -#define SPI_R_MOSI_GPIO_Port GPIOB -/* USER CODE BEGIN Private defines */ +#define PB3_Pin GPIO_PIN_3 +#define PC0_GPIO_Port GPIOC +#define PC0_Pin GPIO_PIN_0 +#define PC10_GPIO_Port GPIOC +#define PC10_Pin GPIO_PIN_10 +#define PC1_GPIO_Port GPIOC +#define PC1_Pin GPIO_PIN_1 +#define PC3_GPIO_Port GPIOC +#define PC3_Pin GPIO_PIN_3 +#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC +#define QUARTZ_32MHZ_IN_Pin GPIO_PIN_14 +#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC +#define QUARTZ_32MHZ_OUT_Pin GPIO_PIN_15 +#define RFID_OUT_GPIO_Port GPIOB +#define RFID_OUT_Pin GPIO_PIN_13 +#define RFID_PULL_EXTI_IRQn EXTI9_5_IRQn +#define RFID_PULL_GPIO_Port GPIOA +#define RFID_PULL_Pin GPIO_PIN_8 +#define RFID_RF_IN_GPIO_Port GPIOC +#define RFID_RF_IN_Pin GPIO_PIN_5 +#define SD_CS_GPIO_Port GPIOC +#define SD_CS_Pin GPIO_PIN_12 +#define SPEAKER_GPIO_Port GPIOB +#define SPEAKER_Pin GPIO_PIN_8 +#define iBTN_GPIO_Port GPIOB +#define iBTN_Pin GPIO_PIN_14 -#define MISO_PIN GpioPin{.port = SPI_R_MISO_GPIO_Port, .pin = SPI_R_MISO_Pin} +#define SPI_D_MISO_GPIO_Port GPIOC +#define SPI_D_MISO_Pin GPIO_PIN_2 +#define SPI_D_MOSI_GPIO_Port GPIOB +#define SPI_D_MOSI_Pin GPIO_PIN_15 +#define SPI_D_SCK_GPIO_Port GPIOD +#define SPI_D_SCK_Pin GPIO_PIN_1 +#define SPI_R_MISO_GPIO_Port GPIOB +#define SPI_R_MISO_Pin GPIO_PIN_4 +#define SPI_R_MOSI_GPIO_Port GPIOB +#define SPI_R_MOSI_Pin GPIO_PIN_5 +#define SPI_R_SCK_GPIO_Port GPIOA +#define SPI_R_SCK_Pin GPIO_PIN_5 #define SPI_R hspi1 #define SPI_D hspi2 @@ -183,12 +133,6 @@ extern TIM_HandleTypeDef htim16; #define VIBRO_Pin GPIO_PIN_10 #define VIBRO_GPIO_Port GPIOC -/* USER CODE END Private defines */ - #ifdef __cplusplus } #endif - -#endif /* __MAIN_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f4/api-hal/api-hal-delay.c b/firmware/targets/f4/api-hal/api-hal-delay.c index 07e0b2cc..bd7241a3 100644 --- a/firmware/targets/f4/api-hal/api-hal-delay.c +++ b/firmware/targets/f4/api-hal/api-hal-delay.c @@ -23,5 +23,6 @@ void delay_us(float microseconds) { void delay(float milliseconds) { uint32_t ticks = milliseconds / (1000.0f / osKernelGetTickFreq()); osStatus_t result = osDelay(ticks); + (void)result; assert(result == osOK); } \ No newline at end of file diff --git a/firmware/targets/f4/api-hal/api-hal-resources.c b/firmware/targets/f4/api-hal/api-hal-resources.c index eb7d8068..5b53e29c 100644 --- a/firmware/targets/f4/api-hal/api-hal-resources.c +++ b/firmware/targets/f4/api-hal/api-hal-resources.c @@ -4,35 +4,41 @@ const InputPin input_pins[] = { {.port = BUTTON_UP_GPIO_Port, .pin = BUTTON_UP_Pin, .key = InputKeyUp, .inverted = true}, - {.port = BUTTON_DOWN_GPIO_Port, .pin = BUTTON_DOWN_Pin, .key = InputKeyDown, .inverted = true}, + {.port = BUTTON_DOWN_GPIO_Port, + .pin = BUTTON_DOWN_Pin, + .key = InputKeyDown, + .inverted = true}, {.port = BUTTON_RIGHT_GPIO_Port, .pin = BUTTON_RIGHT_Pin, .key = InputKeyRight, .inverted = true}, - {.port = BUTTON_LEFT_GPIO_Port, .pin = BUTTON_LEFT_Pin, .key = InputKeyLeft, .inverted = true}, + {.port = BUTTON_LEFT_GPIO_Port, + .pin = BUTTON_LEFT_Pin, + .key = InputKeyLeft, + .inverted = true}, {.port = BUTTON_OK_GPIO_Port, .pin = BUTTON_OK_Pin, .key = InputKeyOk, .inverted = false}, - {.port = BUTTON_BACK_GPIO_Port, .pin = BUTTON_BACK_Pin, .key = InputKeyBack, .inverted = true}, + {.port = BUTTON_BACK_GPIO_Port, + .pin = BUTTON_BACK_Pin, + .key = InputKeyBack, + .inverted = true}, }; const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin); -const GpioPin led_gpio[3] = { - {LED_RED_GPIO_Port, LED_RED_Pin}, - {LED_GREEN_GPIO_Port, LED_GREEN_Pin}, - {LED_BLUE_GPIO_Port, LED_BLUE_Pin}}; - -const GpioPin backlight_gpio = {DISPLAY_BACKLIGHT_GPIO_Port, DISPLAY_BACKLIGHT_Pin}; -const GpioPin sd_cs_gpio = {SD_CS_GPIO_Port, SD_CS_Pin}; const GpioPin vibro_gpio = {VIBRO_GPIO_Port, VIBRO_Pin}; const GpioPin ibutton_gpio = {iBTN_GPIO_Port, iBTN_Pin}; const GpioPin cc1101_g0_gpio = {CC1101_G0_GPIO_Port, CC1101_G0_Pin}; -// external gpio's -const GpioPin ext_pc0_gpio = {GPIOC, GPIO_PIN_0}; -const GpioPin ext_pc1_gpio = {GPIOC, GPIO_PIN_1}; -const GpioPin ext_pc3_gpio = {GPIOC, GPIO_PIN_3}; -const GpioPin ext_pb2_gpio = {GPIOB, GPIO_PIN_2}; -const GpioPin ext_pb3_gpio = {GPIOB, GPIO_PIN_3}; -const GpioPin ext_pa4_gpio = {GPIOA, GPIO_PIN_4}; -const GpioPin ext_pa6_gpio = {GPIOA, GPIO_PIN_6}; -const GpioPin ext_pa7_gpio = {GPIOA, GPIO_PIN_7}; \ No newline at end of file +const GpioPin gpio_subghz_cs = { .port=CC1101_CS_GPIO_Port, .pin=CC1101_CS_Pin }; +const GpioPin gpio_display_cs = { .port=DISPLAY_CS_GPIO_Port, .pin=DISPLAY_CS_Pin }; +const GpioPin gpio_display_rst = { .port=DISPLAY_RST_GPIO_Port, .pin=DISPLAY_RST_Pin }; +const GpioPin gpio_display_di = { .port=DISPLAY_DI_GPIO_Port, .pin=DISPLAY_DI_Pin }; +const GpioPin gpio_sdcard_cs = { .port=SD_CS_GPIO_Port, .pin=SD_CS_Pin }; +const GpioPin gpio_nfc_cs = { .port=NFC_CS_GPIO_Port, .pin=NFC_CS_Pin }; + +const GpioPin gpio_spi_d_miso = { .port=SPI_D_MISO_GPIO_Port, .pin=SPI_D_MISO_Pin }; +const GpioPin gpio_spi_d_mosi = { .port=SPI_D_MOSI_GPIO_Port, .pin=SPI_D_MOSI_Pin }; +const GpioPin gpio_spi_d_sck = { .port=SPI_D_SCK_GPIO_Port, .pin=SPI_D_SCK_Pin }; +const GpioPin gpio_spi_r_miso = { .port=SPI_R_MISO_GPIO_Port, .pin=SPI_R_MISO_Pin }; +const GpioPin gpio_spi_r_mosi = { .port=SPI_R_MOSI_GPIO_Port, .pin=SPI_R_MOSI_Pin }; +const GpioPin gpio_spi_r_sck = { .port=SPI_R_SCK_GPIO_Port, .pin=SPI_R_SCK_Pin }; diff --git a/firmware/targets/f4/api-hal/api-hal-resources.h b/firmware/targets/f4/api-hal/api-hal-resources.h index 584e3d08..297a79a4 100644 --- a/firmware/targets/f4/api-hal/api-hal-resources.h +++ b/firmware/targets/f4/api-hal/api-hal-resources.h @@ -16,7 +16,7 @@ extern "C" { #define POWER_I2C_SDA_GPIO_Port GPIOA #define POWER_I2C I2C1 -/* Timing register value is computed with the STM32CubeMX Tool, +/** Timing register value is computed with the STM32CubeMX Tool, * Fast Mode @100kHz with I2CCLK = 64 MHz, * rise time = 0ns, fall time = 0ns */ @@ -53,20 +53,27 @@ typedef struct { extern const InputPin input_pins[]; extern const size_t input_pins_count; -extern const GpioPin sd_cs_gpio; extern const GpioPin vibro_gpio; extern const GpioPin ibutton_gpio; extern const GpioPin cc1101_g0_gpio; -// external gpio's -extern const GpioPin ext_pc0_gpio; -extern const GpioPin ext_pc1_gpio; -extern const GpioPin ext_pc3_gpio; -extern const GpioPin ext_pb2_gpio; -extern const GpioPin ext_pb3_gpio; -extern const GpioPin ext_pa4_gpio; -extern const GpioPin ext_pa6_gpio; -extern const GpioPin ext_pa7_gpio; +extern const GpioPin gpio_subghz_cs; +extern const GpioPin gpio_display_cs; + +extern const GpioPin gpio_subghz_cs; +extern const GpioPin gpio_display_cs; +extern const GpioPin gpio_display_rst; +extern const GpioPin gpio_display_di; +extern const GpioPin gpio_sdcard_cs; +extern const GpioPin gpio_nfc_cs; + +extern const GpioPin gpio_spi_d_miso; +extern const GpioPin gpio_spi_d_mosi; +extern const GpioPin gpio_spi_d_sck; +extern const GpioPin gpio_spi_r_miso; +extern const GpioPin gpio_spi_r_mosi; +extern const GpioPin gpio_spi_r_sck; + #ifdef __cplusplus } diff --git a/firmware/targets/f4/api-hal/api-hal-sd.c b/firmware/targets/f4/api-hal/api-hal-sd.c index 7e1e2ebe..46c1dff3 100644 --- a/firmware/targets/f4/api-hal/api-hal-sd.c +++ b/firmware/targets/f4/api-hal/api-hal-sd.c @@ -16,25 +16,21 @@ bool hal_sd_detect(void) { bool result = false; // TODO open record - const GpioPin* sd_cs_record = &sd_cs_gpio; - - // TODO: SPI manager - api_hal_spi_lock(sd_fast_spi.spi); + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSdCard); // configure pin as input - gpio_init_ex(sd_cs_record, GpioModeInput, GpioPullUp, GpioSpeedVeryHigh); + gpio_init_ex(device->chip_select, GpioModeInput, GpioPullUp, GpioSpeedVeryHigh); delay(1); // if gpio_read == 0 return true else return false - result = !gpio_read(sd_cs_record); + result = !gpio_read(device->chip_select); // configure pin back - gpio_init_ex(sd_cs_record, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); - gpio_write(sd_cs_record, 1); + gpio_init_ex(device->chip_select, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + gpio_write(device->chip_select, 1); delay(1); - // TODO: SPI manager - api_hal_spi_unlock(sd_fast_spi.spi); + api_hal_spi_device_return(device); return result; } \ No newline at end of file diff --git a/firmware/targets/f4/api-hal/api-hal-spi-config.c b/firmware/targets/f4/api-hal/api-hal-spi-config.c index 7751b2a1..bf006ef0 100644 --- a/firmware/targets/f4/api-hal/api-hal-spi-config.c +++ b/firmware/targets/f4/api-hal/api-hal-spi-config.c @@ -1,14 +1,89 @@ -#include "main.h" -#include "api-hal-spi-config.h" +#include +#include extern SPI_HandleTypeDef SPI_R; extern SPI_HandleTypeDef SPI_D; +const SPI_InitTypeDef api_hal_spi_config_nfc = { + .Mode = SPI_MODE_MASTER, + .Direction = SPI_DIRECTION_2LINES, + .DataSize = SPI_DATASIZE_8BIT, + .CLKPolarity = SPI_POLARITY_LOW, + .CLKPhase = SPI_PHASE_2EDGE, + .NSS = SPI_NSS_SOFT, + .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8, + .FirstBit = SPI_FIRSTBIT_MSB, + .TIMode = SPI_TIMODE_DISABLE, + .CRCCalculation = SPI_CRCCALCULATION_DISABLE, + .CRCPolynomial = 7, + .CRCLength = SPI_CRC_LENGTH_DATASIZE, + .NSSPMode = SPI_NSS_PULSE_DISABLE, +}; + +const SPI_InitTypeDef api_hal_spi_config_subghz = { + .Mode = SPI_MODE_MASTER, + .Direction = SPI_DIRECTION_2LINES, + .DataSize = SPI_DATASIZE_8BIT, + .CLKPolarity = SPI_POLARITY_LOW, + .CLKPhase = SPI_PHASE_1EDGE, + .NSS = SPI_NSS_SOFT, + .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64, + .FirstBit = SPI_FIRSTBIT_MSB, + .TIMode = SPI_TIMODE_DISABLE, + .CRCCalculation = SPI_CRCCALCULATION_DISABLE, + .CRCPolynomial = 7, + .CRCLength = SPI_CRC_LENGTH_DATASIZE, + .NSSPMode = SPI_NSS_PULSE_DISABLE, +}; + +const SPI_InitTypeDef api_hal_spi_config_display = { + .Mode = SPI_MODE_MASTER, + .Direction = SPI_DIRECTION_2LINES, + .DataSize = SPI_DATASIZE_8BIT, + .CLKPolarity = SPI_POLARITY_LOW, + .CLKPhase = SPI_PHASE_1EDGE, + .NSS = SPI_NSS_SOFT, + .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16, + .FirstBit = SPI_FIRSTBIT_MSB, + .TIMode = SPI_TIMODE_DISABLE, + .CRCCalculation = SPI_CRCCALCULATION_DISABLE, + .CRCPolynomial = 7, + .CRCLength = SPI_CRC_LENGTH_DATASIZE, + .NSSPMode = SPI_NSS_PULSE_ENABLE, +}; + +osMutexId_t spi_mutex_d = NULL; +osMutexId_t spi_mutex_r = NULL; + +const ApiHalSpiBus spi_r = { + .spi=&SPI_R, + .mutex=&spi_mutex_r, + .miso=&gpio_spi_r_miso, + .mosi=&gpio_spi_r_mosi, + .clk=&gpio_spi_r_sck, +}; + +const ApiHalSpiBus spi_d = { + .spi=&SPI_D, + .mutex=&spi_mutex_d, + .miso=&gpio_spi_d_miso, + .mosi=&gpio_spi_d_mosi, + .clk=&gpio_spi_d_sck, +}; + +const ApiHalSpiDevice api_hal_spi_devices[ApiHalSpiDeviceIdMax] = { + { .bus=&spi_r, .config=&api_hal_spi_config_subghz, .chip_select=&gpio_subghz_cs, }, + { .bus=&spi_d, .config=&api_hal_spi_config_display, .chip_select=&gpio_display_cs, }, + { .bus=&spi_d, .config=NULL, .chip_select=&gpio_sdcard_cs, }, + { .bus=&spi_r, .config=&api_hal_spi_config_nfc, .chip_select=&gpio_nfc_cs }, +}; + + /** * SD Card in fast mode (after init) */ const SPIDevice sd_fast_spi = { - .spi = &SPI_D, + .bus= &spi_d, .config = { .Mode = SPI_MODE_MASTER, .Direction = SPI_DIRECTION_2LINES, @@ -29,7 +104,7 @@ const SPIDevice sd_fast_spi = { * SD Card in slow mode (before init) */ const SPIDevice sd_slow_spi = { - .spi = &SPI_D, + .bus= &spi_d, .config = { .Mode = SPI_MODE_MASTER, .Direction = SPI_DIRECTION_2LINES, @@ -45,24 +120,3 @@ const SPIDevice sd_slow_spi = { .CRCLength = SPI_CRC_LENGTH_DATASIZE, .NSSPMode = SPI_NSS_PULSE_ENABLE, }}; - -/** - * Display - */ -const SPIDevice display_spi = { - .spi = &SPI_D, - .config = { - .Mode = SPI_MODE_MASTER, - .Direction = SPI_DIRECTION_2LINES, - .DataSize = SPI_DATASIZE_8BIT, - .CLKPolarity = SPI_POLARITY_LOW, - .CLKPhase = SPI_PHASE_1EDGE, - .NSS = SPI_NSS_SOFT, - .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16, - .FirstBit = SPI_FIRSTBIT_MSB, - .TIMode = SPI_TIMODE_DISABLE, - .CRCCalculation = SPI_CRCCALCULATION_DISABLE, - .CRCPolynomial = 7, - .CRCLength = SPI_CRC_LENGTH_DATASIZE, - .NSSPMode = SPI_NSS_PULSE_ENABLE, - }}; diff --git a/firmware/targets/f4/api-hal/api-hal-spi-config.h b/firmware/targets/f4/api-hal/api-hal-spi-config.h index 01e9be9a..dd0b2215 100644 --- a/firmware/targets/f4/api-hal/api-hal-spi-config.h +++ b/firmware/targets/f4/api-hal/api-hal-spi-config.h @@ -1,17 +1,66 @@ #pragma once +#include +#include + #ifdef __cplusplus extern "C" { #endif +extern const SPI_InitTypeDef api_hal_spi_config_nfc; +extern const SPI_InitTypeDef api_hal_spi_config_subghz; +extern const SPI_InitTypeDef api_hal_spi_config_display; + +/** API HAL SPI BUS handler + * Structure content may change at some point + */ typedef struct { - SPI_HandleTypeDef* spi; + const SPI_HandleTypeDef* spi; + const osMutexId_t* mutex; + const GpioPin* miso; + const GpioPin* mosi; + const GpioPin* clk; +} ApiHalSpiBus; + +/** API HAL SPI Device handler + * Structure content may change at some point + */ +typedef struct { + const ApiHalSpiBus* bus; + const SPI_InitTypeDef* config; + const GpioPin* chip_select; +} ApiHalSpiDevice; + +/** API HAL SPI Standard Device IDs */ +typedef enum { + ApiHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ + ApiHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ + ApiHalSpiDeviceIdSdCard, /** SDCARD: no default bus config, bus must explicitly be configured */ + ApiHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ + + ApiHalSpiDeviceIdMax, /** Service Value, do not use */ +} ApiHalSpiDeviceId; + +/** Api Hal Spi Bus R + * CC1101, Nfc + */ +extern const ApiHalSpiBus spi_r; + +/** Api Hal Spi Bus D + * Display, SdCard + */ +extern const ApiHalSpiBus spi_d; + +/** Api Hal Spi devices */ +extern const ApiHalSpiDevice api_hal_spi_devices[ApiHalSpiDeviceIdMax]; + +typedef struct { + const ApiHalSpiBus* bus; const SPI_InitTypeDef config; } SPIDevice; extern const SPIDevice sd_fast_spi; extern const SPIDevice sd_slow_spi; -extern const SPIDevice display_spi; #ifdef __cplusplus } diff --git a/firmware/targets/f4/api-hal/api-hal-spi.c b/firmware/targets/f4/api-hal/api-hal-spi.c index e0ddc99f..754e109c 100644 --- a/firmware/targets/f4/api-hal/api-hal-spi.c +++ b/firmware/targets/f4/api-hal/api-hal-spi.c @@ -1,36 +1,167 @@ #include "api-hal-spi.h" -#include +#include #include #include +#include +#include -osMutexId_t spi_mutex_r; -osMutexId_t spi_mutex_d; -extern SPI_HandleTypeDef SPI_R; -extern SPI_HandleTypeDef SPI_D; extern void Enable_SPI(SPI_HandleTypeDef* spi); void api_hal_spi_init() { - spi_mutex_r = osMutexNew(NULL); - spi_mutex_d = osMutexNew(NULL); + // Spi structure is const, but mutex is not + // Need some hell-ish casting to make it work + *(osMutexId_t*)spi_r.mutex = osMutexNew(NULL); + *(osMutexId_t*)spi_d.mutex = osMutexNew(NULL); + // + for (size_t i=0; imutex) { + osMutexAcquire(*bus->mutex, osWaitForever); + } +} + +void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus) { + furi_assert(bus); + if (bus->mutex) { + osMutexRelease(*bus->mutex); + } +} + +bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(bus); + furi_assert(buffer); + furi_assert(size > 0); + + HAL_StatusTypeDef ret = HAL_SPI_Receive((SPI_HandleTypeDef *)bus->spi, buffer, size, HAL_MAX_DELAY); + + return ret == HAL_OK; +} + +bool api_hal_spi_bus_tx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(bus); + furi_assert(buffer); + furi_assert(size > 0); + + HAL_StatusTypeDef ret = HAL_SPI_Transmit((SPI_HandleTypeDef *)bus->spi, buffer, size, HAL_MAX_DELAY); + + return ret == HAL_OK; +} + +bool api_hal_spi_bus_trx(const ApiHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { + furi_assert(bus); + furi_assert(tx_buffer); + furi_assert(rx_buffer); + furi_assert(size > 0); + + HAL_StatusTypeDef ret = HAL_SPI_TransmitReceive((SPI_HandleTypeDef *)bus->spi, tx_buffer, rx_buffer, size, HAL_MAX_DELAY); + + return ret == HAL_OK; +} + +const ApiHalSpiDevice* api_hal_spi_device_get(ApiHalSpiDeviceId device_id) { + furi_assert(device_id < ApiHalSpiDeviceIdMax); + + const ApiHalSpiDevice* device = &api_hal_spi_devices[device_id]; + assert(device); + api_hal_spi_bus_lock(device->bus); + + if (device->config) { + memcpy((SPI_InitTypeDef*)&device->bus->spi->Init, device->config, sizeof(SPI_InitTypeDef)); + if(HAL_SPI_Init((SPI_HandleTypeDef *)device->bus->spi) != HAL_OK) { + Error_Handler(); + } + Enable_SPI((SPI_HandleTypeDef *)device->bus->spi); + } + + return device; +} + +void api_hal_spi_device_return(const ApiHalSpiDevice* device) { + api_hal_spi_bus_unlock(device->bus); +} + +bool api_hal_spi_device_rx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(device); + furi_assert(buffer); + furi_assert(size > 0); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = api_hal_spi_bus_rx(device->bus, buffer, size, HAL_MAX_DELAY); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} + +bool api_hal_spi_device_tx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(device); + furi_assert(buffer); + furi_assert(size > 0); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = api_hal_spi_bus_tx(device->bus, buffer, size, HAL_MAX_DELAY); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} + +bool api_hal_spi_device_trx(const ApiHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { + furi_assert(device); + furi_assert(tx_buffer); + furi_assert(rx_buffer); + furi_assert(size > 0); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = api_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, HAL_MAX_DELAY); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; } void api_hal_spi_apply_config(const SPIDevice* device) { osKernelLock(); - memcpy(&device->spi->Init, &device->config, sizeof(SPI_InitTypeDef)); + memcpy((SPI_InitTypeDef*)&device->bus->spi->Init, &device->config, sizeof(SPI_InitTypeDef)); - if(HAL_SPI_Init(device->spi) != HAL_OK) { + if(HAL_SPI_Init((SPI_HandleTypeDef*)device->bus->spi) != HAL_OK) { Error_Handler(); } - Enable_SPI(device->spi); + Enable_SPI((SPI_HandleTypeDef*)device->bus->spi); osKernelUnlock(); } bool api_hal_spi_config_are_actual(const SPIDevice* device) { - return (memcmp(&device->config, &device->spi->Init, sizeof(SPI_InitTypeDef)) == 0); + return (memcmp(&device->config, &device->bus->spi->Init, sizeof(SPI_InitTypeDef)) == 0); } void api_hal_spi_config_device(const SPIDevice* device) { @@ -39,31 +170,11 @@ void api_hal_spi_config_device(const SPIDevice* device) { } } -void api_hal_spi_lock(SPI_HandleTypeDef* spi) { - if(spi == &SPI_D) { - osMutexAcquire(spi_mutex_d, osWaitForever); - } else if(spi == &SPI_R) { - osMutexAcquire(spi_mutex_r, osWaitForever); - } else { - Error_Handler(); - } -} - -void api_hal_spi_unlock(SPI_HandleTypeDef* spi) { - if(spi == &SPI_D) { - osMutexRelease(spi_mutex_d); - } else if(spi == &SPI_R) { - osMutexRelease(spi_mutex_r); - } else { - Error_Handler(); - } -} - void api_hal_spi_lock_device(const SPIDevice* device) { - api_hal_spi_lock(device->spi); + api_hal_spi_bus_lock(device->bus); api_hal_spi_config_device(device); } void api_hal_spi_unlock_device(const SPIDevice* device) { - api_hal_spi_unlock(device->spi); -} \ No newline at end of file + api_hal_spi_bus_unlock(device->bus); +} diff --git a/firmware/targets/f4/api-hal/api-hal-spi.h b/firmware/targets/f4/api-hal/api-hal-spi.h index 5c437feb..21d319bb 100644 --- a/firmware/targets/f4/api-hal/api-hal-spi.h +++ b/firmware/targets/f4/api-hal/api-hal-spi.h @@ -1,6 +1,8 @@ #pragma once #include "main.h" #include "api-hal-spi-config.h" +#include +#include #ifdef __cplusplus extern "C" { @@ -11,15 +13,83 @@ extern "C" { */ void api_hal_spi_init(); -/** - * Lock SPI bus - */ -void api_hal_spi_lock(SPI_HandleTypeDef* spi); +/* Bus Level API */ -/** - * Unlock SPI bus +/** Lock SPI bus + * Takes bus mutex, if used */ -void api_hal_spi_unlock(SPI_HandleTypeDef* spi); +void api_hal_spi_bus_lock(const ApiHalSpiBus* bus); + +/** Unlock SPI bus + * Releases BUS mutex, if used + */ +void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus); + +/** SPI Receive + * @param bus - spi bus handler + * @param buffer - receive buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); + +/** SPI Transmit + * @param bus - spi bus handler + * @param buffer - transmit buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool api_hal_spi_bus_tx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); + +/** SPI Transmit and Receive + * @param bus - spi bus handlere + * @param tx_buffer - device handle + * @param rx_buffer - device handle + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool api_hal_spi_bus_trx(const ApiHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); + +/* Device Level API */ + +/** Get Device handle + * And lock access to the corresponding SPI BUS + * @param device_id - device identifier + * @return device handle + */ +const ApiHalSpiDevice* api_hal_spi_device_get(ApiHalSpiDeviceId device_id); + +/** Return Device handle + * And unlock access to the corresponding SPI BUS + * @param device - device handle + */ +void api_hal_spi_device_return(const ApiHalSpiDevice* device); + +/** SPI Recieve + * @param device - device handle + * @param buffer - receive buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool api_hal_spi_device_rx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); + +/** SPI Transmit + * @param device - device handle + * @param buffer - transmit buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool api_hal_spi_device_tx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); + +/** SPI Transmit and Receive + * @param device - device handle + * @param tx_buffer - device handle + * @param rx_buffer - device handle + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool api_hal_spi_device_trx(const ApiHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); + /** * Lock SPI device bus and apply config if needed diff --git a/firmware/targets/f4/api-hal/api-hal-subghz.c b/firmware/targets/f4/api-hal/api-hal-subghz.c index 3474bdf7..a3a326ee 100644 --- a/firmware/targets/f4/api-hal/api-hal-subghz.c +++ b/firmware/targets/f4/api-hal/api-hal-subghz.c @@ -1,5 +1,11 @@ #include "api-hal-subghz.h" +#include +#include -void api_hal_rf_band_set(RfBand band) { - -} \ No newline at end of file +void api_hal_subghz_init() { + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + cc1101_init(device); + api_hal_spi_device_return(device); +} + +void api_hal_subghz_band_set(RfBand band) {} \ No newline at end of file diff --git a/firmware/targets/f4/api-hal/api-hal.c b/firmware/targets/f4/api-hal/api-hal.c index 6d24afcf..61dac551 100644 --- a/firmware/targets/f4/api-hal/api-hal.c +++ b/firmware/targets/f4/api-hal/api-hal.c @@ -8,4 +8,5 @@ void api_hal_init() { api_hal_power_init(); api_hal_light_init(); api_hal_vibro_init(); + api_hal_subghz_init(); } \ No newline at end of file diff --git a/firmware/targets/f5/Inc/main.h b/firmware/targets/f5/Inc/main.h index d4a8c537..cfd29113 100644 --- a/firmware/targets/f5/Inc/main.h +++ b/firmware/targets/f5/Inc/main.h @@ -1,155 +1,103 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file : main.h - * @brief : Header for main.c file. - * This file contains the common defines of the application. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __MAIN_H -#define __MAIN_H +#pragma once #ifdef __cplusplus extern "C" { #endif -/* Includes ------------------------------------------------------------------*/ #include "stm32wbxx_hal.h" -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Exported types ------------------------------------------------------------*/ -/* USER CODE BEGIN ET */ - -/* USER CODE END ET */ - -/* Exported constants --------------------------------------------------------*/ -/* USER CODE BEGIN EC */ - -/* USER CODE END EC */ - -/* Exported macro ------------------------------------------------------------*/ -/* USER CODE BEGIN EM */ - -/* USER CODE END EM */ - -/* Exported functions prototypes ---------------------------------------------*/ void Error_Handler(void); -/* USER CODE BEGIN EFP */ - -/* USER CODE END EFP */ - -/* Private defines -----------------------------------------------------------*/ -#define BUTTON_BACK_Pin GPIO_PIN_13 -#define BUTTON_BACK_GPIO_Port GPIOC #define BUTTON_BACK_EXTI_IRQn EXTI15_10_IRQn -#define QUARTZ_32MHZ_IN_Pin GPIO_PIN_14 -#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC -#define QUARTZ_32MHZ_OUT_Pin GPIO_PIN_15 -#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC -#define BUTTON_OK_Pin GPIO_PIN_3 -#define BUTTON_OK_GPIO_Port GPIOH -#define BUTTON_OK_EXTI_IRQn EXTI3_IRQn -#define SPEAKER_Pin GPIO_PIN_8 -#define SPEAKER_GPIO_Port GPIOB -#define IR_TX_Pin GPIO_PIN_9 -#define IR_TX_GPIO_Port GPIOB -#define PC0_Pin GPIO_PIN_0 -#define PC0_GPIO_Port GPIOC -#define PC1_Pin GPIO_PIN_1 -#define PC1_GPIO_Port GPIOC -#define SPI_D_MISO_Pin GPIO_PIN_2 -#define SPI_D_MISO_GPIO_Port GPIOC -#define PC3_Pin GPIO_PIN_3 -#define PC3_GPIO_Port GPIOC -#define IR_RX_Pin GPIO_PIN_0 -#define IR_RX_GPIO_Port GPIOA -#define RF_SW_0_Pin GPIO_PIN_1 -#define RF_SW_0_GPIO_Port GPIOA -#define RF_SW_1_Pin GPIO_PIN_2 -#define RF_SW_1_GPIO_Port GPIOA -#define PERIPH_POWER_Pin GPIO_PIN_3 -#define PERIPH_POWER_GPIO_Port GPIOA -#define PA4_Pin GPIO_PIN_4 -#define PA4_GPIO_Port GPIOA -#define SPI_R_SCK_Pin GPIO_PIN_5 -#define SPI_R_SCK_GPIO_Port GPIOA -#define PA6_Pin GPIO_PIN_6 -#define PA6_GPIO_Port GPIOA -#define PA7_Pin GPIO_PIN_7 -#define PA7_GPIO_Port GPIOA -#define RFID_PULL_Pin GPIO_PIN_8 -#define RFID_PULL_GPIO_Port GPIOA -#define RFID_PULL_EXTI_IRQn EXTI9_5_IRQn -#define CC1101_G0_Pin GPIO_PIN_4 -#define CC1101_G0_GPIO_Port GPIOC -#define RFID_RF_IN_Pin GPIO_PIN_5 -#define RFID_RF_IN_GPIO_Port GPIOC -#define PB2_Pin GPIO_PIN_2 -#define PB2_GPIO_Port GPIOB -#define BUTTON_UP_Pin GPIO_PIN_10 -#define BUTTON_UP_GPIO_Port GPIOB -#define BUTTON_UP_EXTI_IRQn EXTI15_10_IRQn -#define BUTTON_LEFT_Pin GPIO_PIN_11 -#define BUTTON_LEFT_GPIO_Port GPIOB -#define BUTTON_LEFT_EXTI_IRQn EXTI15_10_IRQn -#define DISPLAY_RST_Pin GPIO_PIN_0 -#define DISPLAY_RST_GPIO_Port GPIOB -#define BUTTON_DOWN_Pin GPIO_PIN_1 -#define BUTTON_DOWN_GPIO_Port GPIOB +#define BUTTON_BACK_GPIO_Port GPIOC +#define BUTTON_BACK_Pin GPIO_PIN_13 #define BUTTON_DOWN_EXTI_IRQn EXTI1_IRQn -#define NFC_CS_Pin GPIO_PIN_4 -#define NFC_CS_GPIO_Port GPIOE -#define BUTTON_RIGHT_Pin GPIO_PIN_12 -#define BUTTON_RIGHT_GPIO_Port GPIOB +#define BUTTON_DOWN_GPIO_Port GPIOB +#define BUTTON_DOWN_Pin GPIO_PIN_1 +#define BUTTON_LEFT_EXTI_IRQn EXTI15_10_IRQn +#define BUTTON_LEFT_GPIO_Port GPIOB +#define BUTTON_LEFT_Pin GPIO_PIN_11 +#define BUTTON_OK_EXTI_IRQn EXTI3_IRQn +#define BUTTON_OK_GPIO_Port GPIOH +#define BUTTON_OK_Pin GPIO_PIN_3 #define BUTTON_RIGHT_EXTI_IRQn EXTI15_10_IRQn -#define RFID_OUT_Pin GPIO_PIN_13 -#define RFID_OUT_GPIO_Port GPIOB -#define iBTN_Pin GPIO_PIN_14 -#define iBTN_GPIO_Port GPIOB -#define SPI_D_MOSI_Pin GPIO_PIN_15 -#define SPI_D_MOSI_GPIO_Port GPIOB -#define DISPLAY_DI_Pin GPIO_PIN_6 -#define DISPLAY_DI_GPIO_Port GPIOC -#define SD_CD_Pin GPIO_PIN_15 -#define SD_CD_GPIO_Port GPIOA -#define VIBRO_Pin GPIO_PIN_10 -#define VIBRO_GPIO_Port GPIOC -#define DISPLAY_CS_Pin GPIO_PIN_11 -#define DISPLAY_CS_GPIO_Port GPIOC -#define SD_CS_Pin GPIO_PIN_12 -#define SD_CS_GPIO_Port GPIOC -#define CC1101_CS_Pin GPIO_PIN_0 +#define BUTTON_RIGHT_GPIO_Port GPIOB +#define BUTTON_RIGHT_Pin GPIO_PIN_12 +#define BUTTON_UP_EXTI_IRQn EXTI15_10_IRQn +#define BUTTON_UP_GPIO_Port GPIOB +#define BUTTON_UP_Pin GPIO_PIN_10 #define CC1101_CS_GPIO_Port GPIOD -#define SPI_D_SCK_Pin GPIO_PIN_1 -#define SPI_D_SCK_GPIO_Port GPIOD -#define PB3_Pin GPIO_PIN_3 +#define CC1101_CS_Pin GPIO_PIN_0 +#define CC1101_G0_GPIO_Port GPIOC +#define CC1101_G0_Pin GPIO_PIN_4 +#define DISPLAY_CS_GPIO_Port GPIOC +#define DISPLAY_CS_Pin GPIO_PIN_11 +#define DISPLAY_DI_GPIO_Port GPIOC +#define DISPLAY_DI_Pin GPIO_PIN_6 +#define DISPLAY_RST_GPIO_Port GPIOB +#define DISPLAY_RST_Pin GPIO_PIN_0 +#define IR_RX_GPIO_Port GPIOA +#define IR_RX_Pin GPIO_PIN_0 +#define IR_TX_GPIO_Port GPIOB +#define IR_TX_Pin GPIO_PIN_9 +#define NFC_CS_GPIO_Port GPIOE +#define NFC_CS_Pin GPIO_PIN_4 +#define PA4_GPIO_Port GPIOA +#define PA4_Pin GPIO_PIN_4 +#define PA6_GPIO_Port GPIOA +#define PA6_Pin GPIO_PIN_6 +#define PA7_GPIO_Port GPIOA +#define PA7_Pin GPIO_PIN_7 +#define PB2_GPIO_Port GPIOB +#define PB2_Pin GPIO_PIN_2 #define PB3_GPIO_Port GPIOB -#define SPI_R_MISO_Pin GPIO_PIN_4 -#define SPI_R_MISO_GPIO_Port GPIOB -#define SPI_R_MOSI_Pin GPIO_PIN_5 -#define SPI_R_MOSI_GPIO_Port GPIOB -/* USER CODE BEGIN Private defines */ +#define PB3_Pin GPIO_PIN_3 +#define PC0_GPIO_Port GPIOC +#define PC0_Pin GPIO_PIN_0 +#define PC1_GPIO_Port GPIOC +#define PC1_Pin GPIO_PIN_1 +#define PC3_GPIO_Port GPIOC +#define PC3_Pin GPIO_PIN_3 +#define PERIPH_POWER_GPIO_Port GPIOA +#define PERIPH_POWER_Pin GPIO_PIN_3 +#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC +#define QUARTZ_32MHZ_IN_Pin GPIO_PIN_14 +#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC +#define QUARTZ_32MHZ_OUT_Pin GPIO_PIN_15 +#define RFID_OUT_GPIO_Port GPIOB +#define RFID_OUT_Pin GPIO_PIN_13 +#define RFID_PULL_EXTI_IRQn EXTI9_5_IRQn +#define RFID_PULL_GPIO_Port GPIOA +#define RFID_PULL_Pin GPIO_PIN_8 +#define RFID_RF_IN_GPIO_Port GPIOC +#define RFID_RF_IN_Pin GPIO_PIN_5 +#define RF_SW_0_GPIO_Port GPIOA +#define RF_SW_0_Pin GPIO_PIN_1 +#define RF_SW_1_GPIO_Port GPIOA +#define RF_SW_1_Pin GPIO_PIN_2 +#define SD_CD_GPIO_Port GPIOA +#define SD_CD_Pin GPIO_PIN_15 +#define SD_CS_GPIO_Port GPIOC +#define SD_CS_Pin GPIO_PIN_12 +#define SPEAKER_GPIO_Port GPIOB +#define SPEAKER_Pin GPIO_PIN_8 +#define VIBRO_GPIO_Port GPIOC +#define VIBRO_Pin GPIO_PIN_10 +#define iBTN_GPIO_Port GPIOB +#define iBTN_Pin GPIO_PIN_14 -#define MISO_PIN GpioPin{.port = SPI_R_MISO_GPIO_Port, .pin = SPI_R_MISO_Pin} +#define SPI_D_MISO_GPIO_Port GPIOC +#define SPI_D_MISO_Pin GPIO_PIN_2 +#define SPI_D_MOSI_GPIO_Port GPIOB +#define SPI_D_MOSI_Pin GPIO_PIN_15 +#define SPI_D_SCK_GPIO_Port GPIOD +#define SPI_D_SCK_Pin GPIO_PIN_1 +#define SPI_R_MISO_GPIO_Port GPIOB +#define SPI_R_MISO_Pin GPIO_PIN_4 +#define SPI_R_MOSI_GPIO_Port GPIOB +#define SPI_R_MOSI_Pin GPIO_PIN_5 +#define SPI_R_SCK_GPIO_Port GPIOA +#define SPI_R_SCK_Pin GPIO_PIN_5 #define SPI_R hspi1 #define SPI_D hspi2 @@ -182,12 +130,6 @@ extern TIM_HandleTypeDef htim16; #define NFC_IRQ_Pin RFID_PULL_Pin #define NFC_IRQ_GPIO_Port RFID_PULL_GPIO_Port -/* USER CODE END Private defines */ - #ifdef __cplusplus } #endif - -#endif /* __MAIN_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f5/api-hal/api-hal-delay.c b/firmware/targets/f5/api-hal/api-hal-delay.c index 07e0b2cc..bd7241a3 100644 --- a/firmware/targets/f5/api-hal/api-hal-delay.c +++ b/firmware/targets/f5/api-hal/api-hal-delay.c @@ -23,5 +23,6 @@ void delay_us(float microseconds) { void delay(float milliseconds) { uint32_t ticks = milliseconds / (1000.0f / osKernelGetTickFreq()); osStatus_t result = osDelay(ticks); + (void)result; assert(result == osOK); } \ No newline at end of file diff --git a/firmware/targets/f5/api-hal/api-hal-gpio.c b/firmware/targets/f5/api-hal/api-hal-gpio.c index 30c439ea..797a928f 100644 --- a/firmware/targets/f5/api-hal/api-hal-gpio.c +++ b/firmware/targets/f5/api-hal/api-hal-gpio.c @@ -20,11 +20,6 @@ void hal_gpio_init( HAL_GPIO_Init(gpio->port, &GPIO_InitStruct); } -void enable_cc1101_irq() { - HAL_NVIC_SetPriority(EXTI4_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(EXTI4_IRQn); -} - extern COMP_HandleTypeDef hcomp1; bool get_rfid_in_level() { diff --git a/firmware/targets/f5/api-hal/api-hal-gpio.h b/firmware/targets/f5/api-hal/api-hal-gpio.h index af3c8735..9aee3140 100644 --- a/firmware/targets/f5/api-hal/api-hal-gpio.h +++ b/firmware/targets/f5/api-hal/api-hal-gpio.h @@ -24,6 +24,12 @@ typedef enum { GpioModeEventRiseFall = GPIO_MODE_EVT_RISING_FALLING, } GpioMode; +typedef enum { + GpioPullNo = GPIO_NOPULL, + GpioPullUp = GPIO_PULLUP, + GpioPullDown = GPIO_PULLDOWN, +} GpioPull; + typedef enum { GpioSpeedLow = GPIO_SPEED_FREQ_LOW, GpioSpeedMedium = GPIO_SPEED_FREQ_MEDIUM, @@ -31,12 +37,6 @@ typedef enum { GpioSpeedVeryHigh = GPIO_SPEED_FREQ_VERY_HIGH, } GpioSpeed; -typedef enum { - GpioPullNo = GPIO_NOPULL, - GpioPullUp = GPIO_PULLUP, - GpioPullDown = GPIO_PULLDOWN, -} GpioPull; - typedef struct { GPIO_TypeDef* port; uint16_t pin; diff --git a/firmware/targets/f5/api-hal/api-hal-resources.c b/firmware/targets/f5/api-hal/api-hal-resources.c index 1ee91516..5b53e29c 100644 --- a/firmware/targets/f5/api-hal/api-hal-resources.c +++ b/firmware/targets/f5/api-hal/api-hal-resources.c @@ -28,3 +28,17 @@ const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin); const GpioPin vibro_gpio = {VIBRO_GPIO_Port, VIBRO_Pin}; const GpioPin ibutton_gpio = {iBTN_GPIO_Port, iBTN_Pin}; const GpioPin cc1101_g0_gpio = {CC1101_G0_GPIO_Port, CC1101_G0_Pin}; + +const GpioPin gpio_subghz_cs = { .port=CC1101_CS_GPIO_Port, .pin=CC1101_CS_Pin }; +const GpioPin gpio_display_cs = { .port=DISPLAY_CS_GPIO_Port, .pin=DISPLAY_CS_Pin }; +const GpioPin gpio_display_rst = { .port=DISPLAY_RST_GPIO_Port, .pin=DISPLAY_RST_Pin }; +const GpioPin gpio_display_di = { .port=DISPLAY_DI_GPIO_Port, .pin=DISPLAY_DI_Pin }; +const GpioPin gpio_sdcard_cs = { .port=SD_CS_GPIO_Port, .pin=SD_CS_Pin }; +const GpioPin gpio_nfc_cs = { .port=NFC_CS_GPIO_Port, .pin=NFC_CS_Pin }; + +const GpioPin gpio_spi_d_miso = { .port=SPI_D_MISO_GPIO_Port, .pin=SPI_D_MISO_Pin }; +const GpioPin gpio_spi_d_mosi = { .port=SPI_D_MOSI_GPIO_Port, .pin=SPI_D_MOSI_Pin }; +const GpioPin gpio_spi_d_sck = { .port=SPI_D_SCK_GPIO_Port, .pin=SPI_D_SCK_Pin }; +const GpioPin gpio_spi_r_miso = { .port=SPI_R_MISO_GPIO_Port, .pin=SPI_R_MISO_Pin }; +const GpioPin gpio_spi_r_mosi = { .port=SPI_R_MOSI_GPIO_Port, .pin=SPI_R_MOSI_Pin }; +const GpioPin gpio_spi_r_sck = { .port=SPI_R_SCK_GPIO_Port, .pin=SPI_R_SCK_Pin }; diff --git a/firmware/targets/f5/api-hal/api-hal-resources.h b/firmware/targets/f5/api-hal/api-hal-resources.h index b205efb5..297a79a4 100644 --- a/firmware/targets/f5/api-hal/api-hal-resources.h +++ b/firmware/targets/f5/api-hal/api-hal-resources.h @@ -16,7 +16,7 @@ extern "C" { #define POWER_I2C_SDA_GPIO_Port GPIOA #define POWER_I2C I2C1 -/* Timing register value is computed with the STM32CubeMX Tool, +/** Timing register value is computed with the STM32CubeMX Tool, * Fast Mode @100kHz with I2CCLK = 64 MHz, * rise time = 0ns, fall time = 0ns */ @@ -57,6 +57,24 @@ extern const GpioPin vibro_gpio; extern const GpioPin ibutton_gpio; extern const GpioPin cc1101_g0_gpio; +extern const GpioPin gpio_subghz_cs; +extern const GpioPin gpio_display_cs; + +extern const GpioPin gpio_subghz_cs; +extern const GpioPin gpio_display_cs; +extern const GpioPin gpio_display_rst; +extern const GpioPin gpio_display_di; +extern const GpioPin gpio_sdcard_cs; +extern const GpioPin gpio_nfc_cs; + +extern const GpioPin gpio_spi_d_miso; +extern const GpioPin gpio_spi_d_mosi; +extern const GpioPin gpio_spi_d_sck; +extern const GpioPin gpio_spi_r_miso; +extern const GpioPin gpio_spi_r_mosi; +extern const GpioPin gpio_spi_r_sck; + + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f5/api-hal/api-hal-spi-config.c b/firmware/targets/f5/api-hal/api-hal-spi-config.c index 7751b2a1..f9f795f7 100644 --- a/firmware/targets/f5/api-hal/api-hal-spi-config.c +++ b/firmware/targets/f5/api-hal/api-hal-spi-config.c @@ -1,14 +1,89 @@ -#include "main.h" -#include "api-hal-spi-config.h" +#include +#include extern SPI_HandleTypeDef SPI_R; extern SPI_HandleTypeDef SPI_D; +const SPI_InitTypeDef api_hal_spi_config_nfc = { + .Mode = SPI_MODE_MASTER, + .Direction = SPI_DIRECTION_2LINES, + .DataSize = SPI_DATASIZE_8BIT, + .CLKPolarity = SPI_POLARITY_LOW, + .CLKPhase = SPI_PHASE_2EDGE, + .NSS = SPI_NSS_SOFT, + .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8, + .FirstBit = SPI_FIRSTBIT_MSB, + .TIMode = SPI_TIMODE_DISABLE, + .CRCCalculation = SPI_CRCCALCULATION_DISABLE, + .CRCPolynomial = 7, + .CRCLength = SPI_CRC_LENGTH_DATASIZE, + .NSSPMode = SPI_NSS_PULSE_DISABLE, +}; + +const SPI_InitTypeDef api_hal_spi_config_subghz = { + .Mode = SPI_MODE_MASTER, + .Direction = SPI_DIRECTION_2LINES, + .DataSize = SPI_DATASIZE_8BIT, + .CLKPolarity = SPI_POLARITY_LOW, + .CLKPhase = SPI_PHASE_1EDGE, + .NSS = SPI_NSS_SOFT, + .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8, + .FirstBit = SPI_FIRSTBIT_MSB, + .TIMode = SPI_TIMODE_DISABLE, + .CRCCalculation = SPI_CRCCALCULATION_DISABLE, + .CRCPolynomial = 7, + .CRCLength = SPI_CRC_LENGTH_DATASIZE, + .NSSPMode = SPI_NSS_PULSE_DISABLE, +}; + +const SPI_InitTypeDef api_hal_spi_config_display = { + .Mode = SPI_MODE_MASTER, + .Direction = SPI_DIRECTION_2LINES, + .DataSize = SPI_DATASIZE_8BIT, + .CLKPolarity = SPI_POLARITY_LOW, + .CLKPhase = SPI_PHASE_1EDGE, + .NSS = SPI_NSS_SOFT, + .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16, + .FirstBit = SPI_FIRSTBIT_MSB, + .TIMode = SPI_TIMODE_DISABLE, + .CRCCalculation = SPI_CRCCALCULATION_DISABLE, + .CRCPolynomial = 7, + .CRCLength = SPI_CRC_LENGTH_DATASIZE, + .NSSPMode = SPI_NSS_PULSE_ENABLE, +}; + +osMutexId_t spi_mutex_d = NULL; +osMutexId_t spi_mutex_r = NULL; + +const ApiHalSpiBus spi_r = { + .spi=&SPI_R, + .mutex=&spi_mutex_r, + .miso=&gpio_spi_r_miso, + .mosi=&gpio_spi_r_mosi, + .clk=&gpio_spi_r_sck, +}; + +const ApiHalSpiBus spi_d = { + .spi=&SPI_D, + .mutex=&spi_mutex_d, + .miso=&gpio_spi_d_miso, + .mosi=&gpio_spi_d_mosi, + .clk=&gpio_spi_d_sck, +}; + +const ApiHalSpiDevice api_hal_spi_devices[ApiHalSpiDeviceIdMax] = { + { .bus=&spi_r, .config=&api_hal_spi_config_subghz, .chip_select=&gpio_subghz_cs, }, + { .bus=&spi_d, .config=&api_hal_spi_config_display, .chip_select=&gpio_display_cs, }, + { .bus=&spi_d, .config=NULL, .chip_select=&gpio_sdcard_cs, }, + { .bus=&spi_r, .config=&api_hal_spi_config_nfc, .chip_select=&gpio_nfc_cs }, +}; + + /** * SD Card in fast mode (after init) */ const SPIDevice sd_fast_spi = { - .spi = &SPI_D, + .bus= &spi_d, .config = { .Mode = SPI_MODE_MASTER, .Direction = SPI_DIRECTION_2LINES, @@ -29,7 +104,7 @@ const SPIDevice sd_fast_spi = { * SD Card in slow mode (before init) */ const SPIDevice sd_slow_spi = { - .spi = &SPI_D, + .bus= &spi_d, .config = { .Mode = SPI_MODE_MASTER, .Direction = SPI_DIRECTION_2LINES, @@ -45,24 +120,3 @@ const SPIDevice sd_slow_spi = { .CRCLength = SPI_CRC_LENGTH_DATASIZE, .NSSPMode = SPI_NSS_PULSE_ENABLE, }}; - -/** - * Display - */ -const SPIDevice display_spi = { - .spi = &SPI_D, - .config = { - .Mode = SPI_MODE_MASTER, - .Direction = SPI_DIRECTION_2LINES, - .DataSize = SPI_DATASIZE_8BIT, - .CLKPolarity = SPI_POLARITY_LOW, - .CLKPhase = SPI_PHASE_1EDGE, - .NSS = SPI_NSS_SOFT, - .BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16, - .FirstBit = SPI_FIRSTBIT_MSB, - .TIMode = SPI_TIMODE_DISABLE, - .CRCCalculation = SPI_CRCCALCULATION_DISABLE, - .CRCPolynomial = 7, - .CRCLength = SPI_CRC_LENGTH_DATASIZE, - .NSSPMode = SPI_NSS_PULSE_ENABLE, - }}; diff --git a/firmware/targets/f5/api-hal/api-hal-spi-config.h b/firmware/targets/f5/api-hal/api-hal-spi-config.h index 01e9be9a..dd0b2215 100644 --- a/firmware/targets/f5/api-hal/api-hal-spi-config.h +++ b/firmware/targets/f5/api-hal/api-hal-spi-config.h @@ -1,17 +1,66 @@ #pragma once +#include +#include + #ifdef __cplusplus extern "C" { #endif +extern const SPI_InitTypeDef api_hal_spi_config_nfc; +extern const SPI_InitTypeDef api_hal_spi_config_subghz; +extern const SPI_InitTypeDef api_hal_spi_config_display; + +/** API HAL SPI BUS handler + * Structure content may change at some point + */ typedef struct { - SPI_HandleTypeDef* spi; + const SPI_HandleTypeDef* spi; + const osMutexId_t* mutex; + const GpioPin* miso; + const GpioPin* mosi; + const GpioPin* clk; +} ApiHalSpiBus; + +/** API HAL SPI Device handler + * Structure content may change at some point + */ +typedef struct { + const ApiHalSpiBus* bus; + const SPI_InitTypeDef* config; + const GpioPin* chip_select; +} ApiHalSpiDevice; + +/** API HAL SPI Standard Device IDs */ +typedef enum { + ApiHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ + ApiHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ + ApiHalSpiDeviceIdSdCard, /** SDCARD: no default bus config, bus must explicitly be configured */ + ApiHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ + + ApiHalSpiDeviceIdMax, /** Service Value, do not use */ +} ApiHalSpiDeviceId; + +/** Api Hal Spi Bus R + * CC1101, Nfc + */ +extern const ApiHalSpiBus spi_r; + +/** Api Hal Spi Bus D + * Display, SdCard + */ +extern const ApiHalSpiBus spi_d; + +/** Api Hal Spi devices */ +extern const ApiHalSpiDevice api_hal_spi_devices[ApiHalSpiDeviceIdMax]; + +typedef struct { + const ApiHalSpiBus* bus; const SPI_InitTypeDef config; } SPIDevice; extern const SPIDevice sd_fast_spi; extern const SPIDevice sd_slow_spi; -extern const SPIDevice display_spi; #ifdef __cplusplus } diff --git a/firmware/targets/f5/api-hal/api-hal-spi.c b/firmware/targets/f5/api-hal/api-hal-spi.c index e0ddc99f..754e109c 100644 --- a/firmware/targets/f5/api-hal/api-hal-spi.c +++ b/firmware/targets/f5/api-hal/api-hal-spi.c @@ -1,36 +1,167 @@ #include "api-hal-spi.h" -#include +#include #include #include +#include +#include -osMutexId_t spi_mutex_r; -osMutexId_t spi_mutex_d; -extern SPI_HandleTypeDef SPI_R; -extern SPI_HandleTypeDef SPI_D; extern void Enable_SPI(SPI_HandleTypeDef* spi); void api_hal_spi_init() { - spi_mutex_r = osMutexNew(NULL); - spi_mutex_d = osMutexNew(NULL); + // Spi structure is const, but mutex is not + // Need some hell-ish casting to make it work + *(osMutexId_t*)spi_r.mutex = osMutexNew(NULL); + *(osMutexId_t*)spi_d.mutex = osMutexNew(NULL); + // + for (size_t i=0; imutex) { + osMutexAcquire(*bus->mutex, osWaitForever); + } +} + +void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus) { + furi_assert(bus); + if (bus->mutex) { + osMutexRelease(*bus->mutex); + } +} + +bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(bus); + furi_assert(buffer); + furi_assert(size > 0); + + HAL_StatusTypeDef ret = HAL_SPI_Receive((SPI_HandleTypeDef *)bus->spi, buffer, size, HAL_MAX_DELAY); + + return ret == HAL_OK; +} + +bool api_hal_spi_bus_tx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(bus); + furi_assert(buffer); + furi_assert(size > 0); + + HAL_StatusTypeDef ret = HAL_SPI_Transmit((SPI_HandleTypeDef *)bus->spi, buffer, size, HAL_MAX_DELAY); + + return ret == HAL_OK; +} + +bool api_hal_spi_bus_trx(const ApiHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { + furi_assert(bus); + furi_assert(tx_buffer); + furi_assert(rx_buffer); + furi_assert(size > 0); + + HAL_StatusTypeDef ret = HAL_SPI_TransmitReceive((SPI_HandleTypeDef *)bus->spi, tx_buffer, rx_buffer, size, HAL_MAX_DELAY); + + return ret == HAL_OK; +} + +const ApiHalSpiDevice* api_hal_spi_device_get(ApiHalSpiDeviceId device_id) { + furi_assert(device_id < ApiHalSpiDeviceIdMax); + + const ApiHalSpiDevice* device = &api_hal_spi_devices[device_id]; + assert(device); + api_hal_spi_bus_lock(device->bus); + + if (device->config) { + memcpy((SPI_InitTypeDef*)&device->bus->spi->Init, device->config, sizeof(SPI_InitTypeDef)); + if(HAL_SPI_Init((SPI_HandleTypeDef *)device->bus->spi) != HAL_OK) { + Error_Handler(); + } + Enable_SPI((SPI_HandleTypeDef *)device->bus->spi); + } + + return device; +} + +void api_hal_spi_device_return(const ApiHalSpiDevice* device) { + api_hal_spi_bus_unlock(device->bus); +} + +bool api_hal_spi_device_rx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(device); + furi_assert(buffer); + furi_assert(size > 0); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = api_hal_spi_bus_rx(device->bus, buffer, size, HAL_MAX_DELAY); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} + +bool api_hal_spi_device_tx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(device); + furi_assert(buffer); + furi_assert(size > 0); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = api_hal_spi_bus_tx(device->bus, buffer, size, HAL_MAX_DELAY); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; +} + +bool api_hal_spi_device_trx(const ApiHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { + furi_assert(device); + furi_assert(tx_buffer); + furi_assert(rx_buffer); + furi_assert(size > 0); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, false); + } + + bool ret = api_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, HAL_MAX_DELAY); + + if (device->chip_select) { + hal_gpio_write(device->chip_select, true); + } + + return ret; } void api_hal_spi_apply_config(const SPIDevice* device) { osKernelLock(); - memcpy(&device->spi->Init, &device->config, sizeof(SPI_InitTypeDef)); + memcpy((SPI_InitTypeDef*)&device->bus->spi->Init, &device->config, sizeof(SPI_InitTypeDef)); - if(HAL_SPI_Init(device->spi) != HAL_OK) { + if(HAL_SPI_Init((SPI_HandleTypeDef*)device->bus->spi) != HAL_OK) { Error_Handler(); } - Enable_SPI(device->spi); + Enable_SPI((SPI_HandleTypeDef*)device->bus->spi); osKernelUnlock(); } bool api_hal_spi_config_are_actual(const SPIDevice* device) { - return (memcmp(&device->config, &device->spi->Init, sizeof(SPI_InitTypeDef)) == 0); + return (memcmp(&device->config, &device->bus->spi->Init, sizeof(SPI_InitTypeDef)) == 0); } void api_hal_spi_config_device(const SPIDevice* device) { @@ -39,31 +170,11 @@ void api_hal_spi_config_device(const SPIDevice* device) { } } -void api_hal_spi_lock(SPI_HandleTypeDef* spi) { - if(spi == &SPI_D) { - osMutexAcquire(spi_mutex_d, osWaitForever); - } else if(spi == &SPI_R) { - osMutexAcquire(spi_mutex_r, osWaitForever); - } else { - Error_Handler(); - } -} - -void api_hal_spi_unlock(SPI_HandleTypeDef* spi) { - if(spi == &SPI_D) { - osMutexRelease(spi_mutex_d); - } else if(spi == &SPI_R) { - osMutexRelease(spi_mutex_r); - } else { - Error_Handler(); - } -} - void api_hal_spi_lock_device(const SPIDevice* device) { - api_hal_spi_lock(device->spi); + api_hal_spi_bus_lock(device->bus); api_hal_spi_config_device(device); } void api_hal_spi_unlock_device(const SPIDevice* device) { - api_hal_spi_unlock(device->spi); -} \ No newline at end of file + api_hal_spi_bus_unlock(device->bus); +} diff --git a/firmware/targets/f5/api-hal/api-hal-spi.h b/firmware/targets/f5/api-hal/api-hal-spi.h index 5c437feb..21d319bb 100644 --- a/firmware/targets/f5/api-hal/api-hal-spi.h +++ b/firmware/targets/f5/api-hal/api-hal-spi.h @@ -1,6 +1,8 @@ #pragma once #include "main.h" #include "api-hal-spi-config.h" +#include +#include #ifdef __cplusplus extern "C" { @@ -11,15 +13,83 @@ extern "C" { */ void api_hal_spi_init(); -/** - * Lock SPI bus - */ -void api_hal_spi_lock(SPI_HandleTypeDef* spi); +/* Bus Level API */ -/** - * Unlock SPI bus +/** Lock SPI bus + * Takes bus mutex, if used */ -void api_hal_spi_unlock(SPI_HandleTypeDef* spi); +void api_hal_spi_bus_lock(const ApiHalSpiBus* bus); + +/** Unlock SPI bus + * Releases BUS mutex, if used + */ +void api_hal_spi_bus_unlock(const ApiHalSpiBus* bus); + +/** SPI Receive + * @param bus - spi bus handler + * @param buffer - receive buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool api_hal_spi_bus_rx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); + +/** SPI Transmit + * @param bus - spi bus handler + * @param buffer - transmit buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool api_hal_spi_bus_tx(const ApiHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); + +/** SPI Transmit and Receive + * @param bus - spi bus handlere + * @param tx_buffer - device handle + * @param rx_buffer - device handle + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool api_hal_spi_bus_trx(const ApiHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); + +/* Device Level API */ + +/** Get Device handle + * And lock access to the corresponding SPI BUS + * @param device_id - device identifier + * @return device handle + */ +const ApiHalSpiDevice* api_hal_spi_device_get(ApiHalSpiDeviceId device_id); + +/** Return Device handle + * And unlock access to the corresponding SPI BUS + * @param device - device handle + */ +void api_hal_spi_device_return(const ApiHalSpiDevice* device); + +/** SPI Recieve + * @param device - device handle + * @param buffer - receive buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool api_hal_spi_device_rx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); + +/** SPI Transmit + * @param device - device handle + * @param buffer - transmit buffer + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool api_hal_spi_device_tx(const ApiHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); + +/** SPI Transmit and Receive + * @param device - device handle + * @param tx_buffer - device handle + * @param rx_buffer - device handle + * @param size - transaction size + * @param timeout - bus operation timeout in ms + */ +bool api_hal_spi_device_trx(const ApiHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); + /** * Lock SPI device bus and apply config if needed diff --git a/firmware/targets/f5/api-hal/api-hal-subghz.c b/firmware/targets/f5/api-hal/api-hal-subghz.c index 0cb09973..833015f9 100644 --- a/firmware/targets/f5/api-hal/api-hal-subghz.c +++ b/firmware/targets/f5/api-hal/api-hal-subghz.c @@ -1,19 +1,181 @@ #include "api-hal-subghz.h" #include +#include +#include +#include +#include #include "main.h" -void api_hal_rf_band_set(RfBand band) { - if (band == RfBand1) { - LL_GPIO_ResetOutputPin(RF_SW_0_GPIO_Port, RF_SW_0_Pin); - LL_GPIO_SetOutputPin(RF_SW_1_GPIO_Port, RF_SW_1_Pin); - } else if (band == RfBand2) { - LL_GPIO_SetOutputPin(RF_SW_0_GPIO_Port, RF_SW_0_Pin); - LL_GPIO_ResetOutputPin(RF_SW_1_GPIO_Port, RF_SW_1_Pin); - } else if (band == RfBand3) { - LL_GPIO_SetOutputPin(RF_SW_0_GPIO_Port, RF_SW_0_Pin); - LL_GPIO_SetOutputPin(RF_SW_1_GPIO_Port, RF_SW_1_Pin); - } else if (band == RfBandIsolation) { - LL_GPIO_ResetOutputPin(RF_SW_0_GPIO_Port, RF_SW_0_Pin); - LL_GPIO_ResetOutputPin(RF_SW_1_GPIO_Port, RF_SW_1_Pin); +static const uint8_t api_hal_subghz_preset_ook_async_regs[][2] = { + /* Base setting */ + { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input + { CC1101_FSCTRL1, 0x06 }, // Set IF 26m/2^10*2=2.2MHz + { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle to TRX, ~150us OSC guard time + /* Async OOK Specific things */ + { CC1101_MDMCFG2, 0x30 }, // ASK/OOK, No preamble/sync + { CC1101_PKTCTRL0, 0x32 }, // Async, no CRC, Infinite + { CC1101_FREND0, 0x01 }, // OOK/ASK PATABLE + /* End */ + { 0, 0 }, +}; + +static const uint8_t api_hal_subghz_preset_ook_async_patable[8] = { + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint8_t api_hal_subghz_preset_2fsk_packet_regs[][2] = { + /* Base setting */ + { CC1101_IOCFG0, 0x06 }, // GD0 as async serial data output/input + { CC1101_FSCTRL1, 0x06 }, // Set IF 26m/2^10*2=2.2MHz + { CC1101_MCSM0, 0x18 }, // Autocalibrate on idle to TRX, ~150us OSC guard time + /* End */ + { 0, 0 }, +}; + +static const uint8_t api_hal_subghz_preset_2fsk_packet_patable[8] = { + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +void api_hal_subghz_init() { + LL_GPIO_SetPinMode(RF_SW_0_GPIO_Port, RF_SW_0_Pin, LL_GPIO_MODE_OUTPUT); + LL_GPIO_SetPinSpeed(RF_SW_0_GPIO_Port, RF_SW_0_Pin, LL_GPIO_SPEED_FREQ_LOW); + LL_GPIO_SetPinOutputType(RF_SW_0_GPIO_Port, RF_SW_0_Pin, LL_GPIO_OUTPUT_PUSHPULL); + LL_GPIO_SetPinMode(RF_SW_1_GPIO_Port, RF_SW_1_Pin, LL_GPIO_MODE_OUTPUT); + LL_GPIO_SetPinSpeed(RF_SW_1_GPIO_Port, RF_SW_1_Pin, LL_GPIO_SPEED_FREQ_LOW); + LL_GPIO_SetPinOutputType(RF_SW_1_GPIO_Port, RF_SW_1_Pin, LL_GPIO_OUTPUT_PUSHPULL); + + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + // Reset and shutdown + cc1101_reset(device); + cc1101_write_reg(device, CC1101_IOCFG0, 0x2E); // High impedance 3-state + cc1101_shutdown(device); + api_hal_spi_device_return(device); +} + +void api_hal_subghz_dump_state() { + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + printf( + "[api_hal_subghz] cc1101 chip %d, version %d\r\n", + cc1101_get_partnumber(device), + cc1101_get_version(device) + ); + api_hal_spi_device_return(device); +} + +void api_hal_subghz_load_preset(ApiHalSubGhzPreset preset) { + if(preset == ApiHalSubGhzPresetOokAsync) { + api_hal_subghz_load_registers(api_hal_subghz_preset_ook_async_regs); + api_hal_subghz_load_patable(api_hal_subghz_preset_ook_async_patable); + } else if(preset == ApiHalSubGhzPreset2FskPacket) { + api_hal_subghz_load_registers(api_hal_subghz_preset_2fsk_packet_regs); + api_hal_subghz_load_patable(api_hal_subghz_preset_2fsk_packet_patable); + } +} + +void api_hal_subghz_load_registers(const uint8_t data[][2]) { + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + cc1101_reset(device); + uint32_t i = 0; + while (data[i][0]) { + cc1101_write_reg(device, data[i][0], data[i][1]); + i++; + } + api_hal_spi_device_return(device); +} + +void api_hal_subghz_load_patable(const uint8_t data[8]) { + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + cc1101_set_pa_table(device, data); + api_hal_spi_device_return(device); +} + +void api_hal_subghz_write_packet(const uint8_t* data, uint8_t size) { + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + cc1101_flush_tx(device); + cc1101_write_fifo(device, data, size); + api_hal_spi_device_return(device); +} + +void api_hal_subghz_read_packet(uint8_t* data, uint8_t size) { + +} + +void api_hal_subghz_shutdown() { + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + // Reset and shutdown + cc1101_shutdown(device); + api_hal_spi_device_return(device); +} + +void api_hal_subghz_reset() { + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + cc1101_reset(device); + api_hal_spi_device_return(device); +} + +void api_hal_subghz_idle() { + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + cc1101_switch_to_idle(device); + api_hal_spi_device_return(device); +} + +void api_hal_subghz_rx() { + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + cc1101_switch_to_rx(device); + api_hal_spi_device_return(device); +} + +void api_hal_subghz_tx() { + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + cc1101_switch_to_tx(device); + api_hal_spi_device_return(device); +} + +float api_hal_subghz_get_rssi() { + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + int32_t rssi_dec = cc1101_get_rssi(device); + api_hal_spi_device_return(device); + + float rssi = rssi_dec; + if(rssi_dec >= 128) { + rssi = ((rssi - 256.0f) / 2.0f) - 74.0f; + } else { + rssi = (rssi / 2.0f) - 74.0f; + } + + return rssi; +} + +uint32_t api_hal_subghz_set_frequency(uint32_t value) { + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + + // Compensate rounding + if (value % cc1101_get_frequency_step(device) > (cc1101_get_frequency_step(device) / 2)) { + value += cc1101_get_frequency_step(device); + } + + uint32_t real_frequency = cc1101_set_frequency(device, value); + cc1101_calibrate(device); + + api_hal_spi_device_return(device); + + return real_frequency; +} + +void api_hal_subghz_set_path(ApiHalSubGhzPath path) { + if (path == ApiHalSubGhzPath1) { + LL_GPIO_ResetOutputPin(RF_SW_0_GPIO_Port, RF_SW_0_Pin); + LL_GPIO_SetOutputPin(RF_SW_1_GPIO_Port, RF_SW_1_Pin); + } else if (path == ApiHalSubGhzPath2) { + LL_GPIO_SetOutputPin(RF_SW_0_GPIO_Port, RF_SW_0_Pin); + LL_GPIO_ResetOutputPin(RF_SW_1_GPIO_Port, RF_SW_1_Pin); + } else if (path == ApiHalSubGhzPath3) { + LL_GPIO_SetOutputPin(RF_SW_0_GPIO_Port, RF_SW_0_Pin); + LL_GPIO_SetOutputPin(RF_SW_1_GPIO_Port, RF_SW_1_Pin); + } else if (path == ApiHalSubGhzPathIsolate) { + LL_GPIO_ResetOutputPin(RF_SW_0_GPIO_Port, RF_SW_0_Pin); + LL_GPIO_ResetOutputPin(RF_SW_1_GPIO_Port, RF_SW_1_Pin); + } else { + } } diff --git a/firmware/targets/f5/api-hal/api-hal.c b/firmware/targets/f5/api-hal/api-hal.c index c2da1754..81cc5d40 100644 --- a/firmware/targets/f5/api-hal/api-hal.c +++ b/firmware/targets/f5/api-hal/api-hal.c @@ -8,4 +8,5 @@ void api_hal_init() { api_hal_power_init(); api_hal_light_init(); api_hal_vibro_init(); + api_hal_subghz_init(); } diff --git a/lib/ST25RFAL002/platform.c b/lib/ST25RFAL002/platform.c index 165fa49d..c7c61636 100644 --- a/lib/ST25RFAL002/platform.c +++ b/lib/ST25RFAL002/platform.c @@ -7,6 +7,7 @@ static osThreadAttr_t platform_irq_thread_attr; static volatile osThreadId_t platform_irq_thread_id = NULL; static volatile PlatformIrqCallback platform_irq_callback = NULL; +static ApiHalSpiDevice* platform_st25r3916 = NULL; void nfc_isr(void* _pin, void* _ctx) { uint32_t pin = (uint32_t)_pin; @@ -36,27 +37,30 @@ void platformSetIrqCallback(PlatformIrqCallback callback) { } HAL_StatusTypeDef platformSpiTxRx(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t len) { - HAL_StatusTypeDef ret; + bool ret = false; if (txBuf && rxBuf) { - ret = HAL_SPI_TransmitReceive(&SPI_R, (uint8_t*)txBuf, rxBuf, len, HAL_MAX_DELAY); + ret = api_hal_spi_bus_trx(platform_st25r3916->bus, (uint8_t*)txBuf, rxBuf, len, 1000); } else if (txBuf) { - ret = HAL_SPI_Transmit(&SPI_R, (uint8_t*)txBuf, len, HAL_MAX_DELAY); + ret = api_hal_spi_bus_tx(platform_st25r3916->bus, (uint8_t*)txBuf, len, 1000); } else if (rxBuf) { - ret = HAL_SPI_Receive(&SPI_R, (uint8_t*)rxBuf, len, HAL_MAX_DELAY); + ret = api_hal_spi_bus_rx(platform_st25r3916->bus, (uint8_t*)rxBuf, len, 1000); } - - if(ret != HAL_OK) { + + if(!ret) { asm("bkpt 1"); - exit(255); + return HAL_ERROR; + } else { + return HAL_OK; } - return ret; } void platformProtectST25RComm() { - api_hal_spi_lock(&SPI_R); - NFC_SPI_Reconfigure(); + furi_assert(platform_st25r3916 == NULL); + platform_st25r3916 = (ApiHalSpiDevice*)api_hal_spi_device_get(ApiHalSpiDeviceIdNfc); } void platformUnprotectST25RComm() { - api_hal_spi_unlock(&SPI_R); + furi_assert(platform_st25r3916); + api_hal_spi_device_return(platform_st25r3916); + platform_st25r3916 = NULL; } diff --git a/lib/ST25RFAL002/platform.h b/lib/ST25RFAL002/platform.h index e183a09e..9c01ccfc 100644 --- a/lib/ST25RFAL002/platform.h +++ b/lib/ST25RFAL002/platform.h @@ -58,40 +58,40 @@ void platformUnprotectST25RComm(); #define platformIrqST25RSetCallback( cb ) platformSetIrqCallback(cb) -#define platformProtectST25RIrqStatus() platformProtectST25RComm() /*!< Protect unique access to IRQ status var - IRQ disable on single thread environment (MCU) ; Mutex lock on a multi thread environment */ -#define platformUnprotectST25RIrqStatus() platformUnprotectST25RComm() /*!< Unprotect the IRQ status var - IRQ enable on a single thread environment (MCU) ; Mutex unlock on a multi thread environment */ +#define platformProtectST25RIrqStatus() platformProtectST25RComm() /*!< Protect unique access to IRQ status var - IRQ disable on single thread environment (MCU) ; Mutex lock on a multi thread environment */ +#define platformUnprotectST25RIrqStatus() platformUnprotectST25RComm() /*!< Unprotect the IRQ status var - IRQ enable on a single thread environment (MCU) ; Mutex unlock on a multi thread environment */ -#define platformLedOff( port, pin ) api_hal_light_set(pin, 0x00) -#define platformLedOn( port, pin ) api_hal_light_set(pin, 0xFF) +#define platformLedOff( port, pin ) api_hal_light_set(pin, 0x00) +#define platformLedOn( port, pin ) api_hal_light_set(pin, 0xFF) -#define platformGpioSet( port, pin ) HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET) /*!< Turns the given GPIO High */ -#define platformGpioClear( port, pin ) HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET) /*!< Turns the given GPIO Low */ -#define platformGpioToogle( port, pin ) HAL_GPIO_TogglePin(port, pin) /*!< Toogles the given GPIO */ -#define platformGpioIsHigh( port, pin ) (HAL_GPIO_ReadPin(port, pin) == GPIO_PIN_SET) /*!< Checks if the given LED is High */ -#define platformGpioIsLow( port, pin ) (!platformGpioIsHigh(port, pin)) /*!< Checks if the given LED is Low */ +#define platformGpioSet( port, pin ) HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET) /*!< Turns the given GPIO High */ +#define platformGpioClear( port, pin ) HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET) /*!< Turns the given GPIO Low */ +#define platformGpioToogle( port, pin ) HAL_GPIO_TogglePin(port, pin) /*!< Toogles the given GPIO */ +#define platformGpioIsHigh( port, pin ) (HAL_GPIO_ReadPin(port, pin) == GPIO_PIN_SET) /*!< Checks if the given LED is High */ +#define platformGpioIsLow( port, pin ) (!platformGpioIsHigh(port, pin)) /*!< Checks if the given LED is Low */ -#define platformTimerCreate( t ) timerCalculateTimer(t) /*!< Create a timer with the given time (ms) */ -#define platformTimerIsExpired( timer ) timerIsExpired(timer) /*!< Checks if the given timer is expired */ -#define platformDelay( t ) osDelay( t ) /*!< Performs a delay for the given time (ms) */ +#define platformTimerCreate( t ) timerCalculateTimer(t) /*!< Create a timer with the given time (ms) */ +#define platformTimerIsExpired( timer ) timerIsExpired(timer) /*!< Checks if the given timer is expired */ +#define platformDelay( t ) osDelay( t ) /*!< Performs a delay for the given time (ms) */ -#define platformGetSysTick() osKernelGetTickCount() /*!< Get System Tick (1 tick = 1 ms) */ +#define platformGetSysTick() osKernelGetTickCount() /*!< Get System Tick (1 tick = 1 ms) */ -#define platformAssert( exp ) assert_param( exp ) /*!< Asserts whether the given expression is true*/ -// #define platformErrorHandle() Error_Handler() /*!< Global error handle\trap */ +#define platformAssert( exp ) assert_param( exp ) /*!< Asserts whether the given expression is true*/ +#define platformErrorHandle() Error_Handler() /*!< Global error handle\trap */ -#define platformSpiSelect() platformGpioClear( ST25R_SS_PORT, ST25R_SS_PIN ) /*!< SPI SS\CS: Chip|Slave Select */ -#define platformSpiDeselect() platformGpioSet( ST25R_SS_PORT, ST25R_SS_PIN ) /*!< SPI SS\CS: Chip|Slave Deselect */ +#define platformSpiSelect() platformGpioClear( ST25R_SS_PORT, ST25R_SS_PIN ) /*!< SPI SS\CS: Chip|Slave Select */ +#define platformSpiDeselect() platformGpioSet( ST25R_SS_PORT, ST25R_SS_PIN ) /*!< SPI SS\CS: Chip|Slave Deselect */ -#define platformI2CTx( txBuf, len, last, txOnly ) /*!< I2C Transmit */ -#define platformI2CRx( txBuf, len ) /*!< I2C Receive */ -#define platformI2CStart() /*!< I2C Start condition */ -#define platformI2CStop() /*!< I2C Stop condition */ -#define platformI2CRepeatStart() /*!< I2C Repeat Start */ -#define platformI2CSlaveAddrWR(add) /*!< I2C Slave address for Write operation */ -#define platformI2CSlaveAddrRD(add) /*!< I2C Slave address for Read operation */ +#define platformI2CTx( txBuf, len, last, txOnly ) /*!< I2C Transmit */ +#define platformI2CRx( txBuf, len ) /*!< I2C Receive */ +#define platformI2CStart() /*!< I2C Start condition */ +#define platformI2CStop() /*!< I2C Stop condition */ +#define platformI2CRepeatStart() /*!< I2C Repeat Start */ +#define platformI2CSlaveAddrWR(add) /*!< I2C Slave address for Write operation */ +#define platformI2CSlaveAddrRD(add) /*!< I2C Slave address for Read operation */ -#define platformLog(...) /*!< Log method */ +#define platformLog(...) /*!< Log method */ /* ****************************************************************************** diff --git a/lib/drivers/cc1101.c b/lib/drivers/cc1101.c new file mode 100644 index 00000000..d104ca7e --- /dev/null +++ b/lib/drivers/cc1101.c @@ -0,0 +1,171 @@ +#include "cc1101.h" +#include +#include +#include +#include + +CC1101Status cc1101_strobe(const ApiHalSpiDevice* device, uint8_t strobe) { + uint8_t tx[1] = { strobe }; + CC1101Status rx[1] = { 0 }; + + hal_gpio_write(device->chip_select, false); + while(hal_gpio_read(device->bus->miso)); + api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 1, CC1101_TIMEOUT); + hal_gpio_write(device->chip_select, true); + + assert(rx[0].CHIP_RDYn == 0); + return rx[0]; +} + +CC1101Status cc1101_write_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t data) { + uint8_t tx[2] = { reg, data }; + CC1101Status rx[2] = { 0 }; + + hal_gpio_write(device->chip_select, false); + while(hal_gpio_read(device->bus->miso)); + api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); + hal_gpio_write(device->chip_select, true); + + assert((rx[0].CHIP_RDYn|rx[1].CHIP_RDYn) == 0); + return rx[1]; +} + +CC1101Status cc1101_read_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t* data) { + assert(sizeof(CC1101Status) == 1); + uint8_t tx[2] = { reg|CC1101_READ, 0}; + CC1101Status rx[2] = { 0 }; + + hal_gpio_write(device->chip_select, false); + while(hal_gpio_read(device->bus->miso)); + api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); + hal_gpio_write(device->chip_select, true); + + assert((rx[0].CHIP_RDYn) == 0); + *data = *(uint8_t*)&rx[1]; + return rx[0]; +} + +uint8_t cc1101_get_partnumber(const ApiHalSpiDevice* device) { + uint8_t partnumber=0; + cc1101_read_reg(device, CC1101_STATUS_PARTNUM|CC1101_BURST, &partnumber); + return partnumber; +} + +uint8_t cc1101_get_version(const ApiHalSpiDevice* device) { + uint8_t version=0; + cc1101_read_reg(device, CC1101_STATUS_VERSION|CC1101_BURST, &version); + return version; +} + +uint8_t cc1101_get_rssi(const ApiHalSpiDevice* device) { + uint8_t rssi=0; + cc1101_read_reg(device, CC1101_STATUS_RSSI|CC1101_BURST, &rssi); + return rssi; +} + +void cc1101_reset(const ApiHalSpiDevice* device) { + hal_gpio_write(device->chip_select, false); + delay_us(1000); + hal_gpio_write(device->chip_select, true); + delay_us(1000); + cc1101_strobe(device, CC1101_STROBE_SRES); +} + +void cc1101_shutdown(const ApiHalSpiDevice* device) { + cc1101_strobe(device, CC1101_STROBE_SPWD); +} + +void cc1101_calibrate(const ApiHalSpiDevice* device) { + cc1101_strobe(device, CC1101_STROBE_SCAL); +} + +void cc1101_switch_to_idle(const ApiHalSpiDevice* device) { + cc1101_strobe(device, CC1101_STROBE_SIDLE); +} + +void cc1101_switch_to_rx(const ApiHalSpiDevice* device) { + cc1101_strobe(device, CC1101_STROBE_SRX); +} + +void cc1101_switch_to_tx(const ApiHalSpiDevice* device) { + cc1101_strobe(device, CC1101_STROBE_STX); +} + +void cc1101_flush_rx(const ApiHalSpiDevice* device) { + cc1101_strobe(device, CC1101_STROBE_SFRX); +} + +void cc1101_flush_tx(const ApiHalSpiDevice* device) { + cc1101_strobe(device, CC1101_STROBE_SFTX); +} + +uint32_t cc1101_set_frequency(const ApiHalSpiDevice* device, uint32_t value) { + uint64_t real_value = (uint64_t)value * 0xFFFF / CC1101_QUARTZ; + + // Sanity check + assert((real_value & 0xFFFFFF) == real_value); + + cc1101_write_reg(device, CC1101_FREQ2, (real_value >> 16) & 0xFF); + cc1101_write_reg(device, CC1101_FREQ1, (real_value >> 8 ) & 0xFF); + cc1101_write_reg(device, CC1101_FREQ0, (real_value >> 0 ) & 0xFF); + + uint64_t real_frequency = real_value * CC1101_QUARTZ / 0xFFFF; + + return (uint32_t)real_frequency; +} + +uint32_t cc1101_get_frequency_step(const ApiHalSpiDevice* device) { + return CC1101_QUARTZ / 0xFFFF; +} + +uint32_t cc1101_set_frequency_offset(const ApiHalSpiDevice* device, uint32_t value) { + uint64_t real_value = value * 0x4000 / CC1101_QUARTZ; + assert((real_value & 0xFF) == real_value); + + cc1101_write_reg(device, CC1101_FSCTRL0, (real_value >> 0 ) & 0xFF); + + uint64_t real_frequency = real_value * CC1101_QUARTZ / 0x4000; + + return (uint32_t)real_frequency; +} + +uint32_t cc1101_get_frequency_offset_step(const ApiHalSpiDevice* device) { + return CC1101_QUARTZ / 0x4000; +} + +void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[8]) { + uint8_t tx[9] = { CC1101_PATABLE | CC1101_BURST }; + CC1101Status rx[9] = { 0 }; + + memcpy(&tx[1], &value[0], 8); + + hal_gpio_write(device->chip_select, false); + while(hal_gpio_read(device->bus->miso)); + api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); + hal_gpio_write(device->chip_select, true); + + assert((rx[0].CHIP_RDYn|rx[8].CHIP_RDYn) == 0); +} + +uint8_t cc1101_write_fifo(const ApiHalSpiDevice* device, const uint8_t* data, uint8_t size) { + uint8_t tx = CC1101_FIFO | CC1101_BURST; + CC1101Status rx = { 0 }; + + // Start transaction + hal_gpio_write(device->chip_select, false); + // Wait IC to become ready + while(hal_gpio_read(device->bus->miso)); + // Tell IC what we want + api_hal_spi_bus_trx(device->bus, &tx, (uint8_t*)&rx, 1, CC1101_TIMEOUT); + assert((rx.CHIP_RDYn) == 0); + // Transmit data + api_hal_spi_bus_tx(device->bus, (uint8_t*)data, size, CC1101_TIMEOUT); + // Finish transaction + hal_gpio_write(device->chip_select, true); + + return size; +} + +uint8_t cc1101_read_fifo(const ApiHalSpiDevice* device, uint8_t* data, uint8_t size) { + return size; +} diff --git a/lib/drivers/cc1101.h b/lib/drivers/cc1101.h new file mode 100644 index 00000000..567faa83 --- /dev/null +++ b/lib/drivers/cc1101.h @@ -0,0 +1,153 @@ +#pragma once + +#include "cc1101_regs.h" + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Low level API */ + +/** Strobe command to the device + * @param device - pointer to ApiHalSpiDevice + * @param strobe - command to execute + * @return device status + */ +CC1101Status cc1101_strobe(const ApiHalSpiDevice* device, uint8_t strobe); + +/** Write device register + * @param device - pointer to ApiHalSpiDevice + * @param reg - register + * @param data - data to write + * @return device status + */ +CC1101Status cc1101_write_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t data); + +/** Read device register + * @param device - pointer to ApiHalSpiDevice + * @param reg - register + * @param[out] data - pointer to data + * @return device status + */ +CC1101Status cc1101_read_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t* data); + +/* High level API */ + +/** Reset + * @param device - pointer to ApiHalSpiDevice + */ +void cc1101_reset(const ApiHalSpiDevice* device); + +/** Enable shutdown mode + * @param device - pointer to ApiHalSpiDevice + */ +void cc1101_shutdown(const ApiHalSpiDevice* device); + +/** Get Partnumber + * @param device - pointer to ApiHalSpiDevice + */ +uint8_t cc1101_get_partnumber(const ApiHalSpiDevice* device); + +/** Get Version + * @param device - pointer to ApiHalSpiDevice + */ +uint8_t cc1101_get_version(const ApiHalSpiDevice* device); + +/** Get raw RSSI value + * @param device - pointer to ApiHalSpiDevice + */ +uint8_t cc1101_get_rssi(const ApiHalSpiDevice* device); + +/** Calibrate oscillator + * @param device - pointer to ApiHalSpiDevice + */ +void cc1101_calibrate(const ApiHalSpiDevice* device); + +/** Switch to idle + * @param device - pointer to ApiHalSpiDevice + */ +void cc1101_switch_to_idle(const ApiHalSpiDevice* device); + +/** Switch to RX + * @param device - pointer to ApiHalSpiDevice + */ +void cc1101_switch_to_rx(const ApiHalSpiDevice* device); + +/** Switch to TX + * @param device - pointer to ApiHalSpiDevice + */ +void cc1101_switch_to_tx(const ApiHalSpiDevice* device); + +/** Flush RX FIFO + * @param device - pointer to ApiHalSpiDevice + */ +void cc1101_flush_rx(const ApiHalSpiDevice* device); + +/** Flush TX FIFO + * @param device - pointer to ApiHalSpiDevice + */ +void cc1101_flush_tx(const ApiHalSpiDevice* device); + +/** Set Frequency + * Is not 100% precise, depends on quartz used + * @param device - pointer to ApiHalSpiDevice + * @param value - frequency in herz + * @return real frequency that were set + */ +uint32_t cc1101_set_frequency(const ApiHalSpiDevice* device, uint32_t value); + +/** Get Frequency Step + * @param device - pointer to ApiHalSpiDevice + * @return frequency step + */ +uint32_t cc1101_get_frequency_step(const ApiHalSpiDevice* device); + +/** Set Frequency Offset + * Is not 100% precise, depends on quartz used + * @param device - pointer to ApiHalSpiDevice + * @param value - frequency offset in herz + * @return real frequency that were set + */ +uint32_t cc1101_set_frequency_offset(const ApiHalSpiDevice* device, uint32_t value); + +/** Get Frequency Offset Step + * @param device - pointer to ApiHalSpiDevice + * @return frequency offset step + */ +uint32_t cc1101_get_frequency_offset_step(const ApiHalSpiDevice* device); + +/** Set Power Amplifier level table, ramp + * @param device - pointer to ApiHalSpiDevice + * @param value - array of power level values + */ +void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[8]); + +/** Set Power Amplifier level table, ramp + * @param device - pointer to ApiHalSpiDevice + * @param value - array of power level values + */ +void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[8]); + +/** Write FIFO + * @param device - pointer to ApiHalSpiDevice + * @param data, pointer to byte array + * @param size, write bytes count + * @return size, written bytes count + */ +uint8_t cc1101_write_fifo(const ApiHalSpiDevice* device, const uint8_t* data, uint8_t size); + +/** Read FIFO + * @param device - pointer to ApiHalSpiDevice + * @param data, pointer to byte array + * @param size, bytes to read from fifo + * @return size, read bytes count + */ +uint8_t cc1101_read_fifo(const ApiHalSpiDevice* device, uint8_t* data, uint8_t size); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/drivers/cc1101_regs.h b/lib/drivers/cc1101_regs.h new file mode 100644 index 00000000..81b07f85 --- /dev/null +++ b/lib/drivers/cc1101_regs.h @@ -0,0 +1,131 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define CC1101_QUARTZ 26000000 + +#define CC1101_TIMEOUT 500 + +#define CC1101_READ (1<<7) /** Read Bit */ +#define CC1101_BURST (1<<6) /** Burst Bit */ + +/* Common registers, CC1101_BURST and CC1101_WRITE behaves as expected */ +#define CC1101_IOCFG2 0x00 /** GDO2 output pin configuration */ +#define CC1101_IOCFG1 0x01 /** GDO1 output pin configuration */ +#define CC1101_IOCFG0 0x02 /** GDO0 output pin configuration */ +#define CC1101_FIFOTHR 0x03 /** RX FIFO and TX FIFO thresholds */ +#define CC1101_SYNC1 0x04 /** Sync word, high byte */ +#define CC1101_SYNC0 0x05 /** Sync word, low byte */ +#define CC1101_PKTLEN 0x06 /** Packet length */ +#define CC1101_PKTCTRL1 0x07 /** Packet automation control */ +#define CC1101_PKTCTRL0 0x08 /** Packet automation control */ +#define CC1101_ADDR 0x09 /** Device address */ +#define CC1101_CHANNR 0x0A /** Channel number */ +#define CC1101_FSCTRL1 0x0B /** Frequency synthesizer control */ +#define CC1101_FSCTRL0 0x0C /** Frequency synthesizer control */ +#define CC1101_FREQ2 0x0D /** Frequency control word, high byte */ +#define CC1101_FREQ1 0x0E /** Frequency control word, middle byte */ +#define CC1101_FREQ0 0x0F /** Frequency control word, low byte */ +#define CC1101_MDMCFG4 0x10 /** Modem configuration */ +#define CC1101_MDMCFG3 0x11 /** Modem configuration */ +#define CC1101_MDMCFG2 0x12 /** Modem configuration */ +#define CC1101_MDMCFG1 0x13 /** Modem configuration */ +#define CC1101_MDMCFG0 0x14 /** Modem configuration */ +#define CC1101_DEVIATN 0x15 /** Modem deviation setting */ +#define CC1101_MCSM2 0x16 /** Main Radio Control State Machine configuration */ +#define CC1101_MCSM1 0x17 /** Main Radio Control State Machine configuration */ +#define CC1101_MCSM0 0x18 /** Main Radio Control State Machine configuration */ +#define CC1101_FOCCFG 0x19 /** Frequency Offset Compensation configuration */ +#define CC1101_BSCFG 0x1A /** Bit Synchronization configuration */ +#define CC1101_AGCTRL2 0x1B /** AGC control */ +#define CC1101_AGCTRL1 0x1C /** AGC control */ +#define CC1101_AGCTRL0 0x1D /** AGC control */ +#define CC1101_WOREVT1 0x1E /** High byte Event 0 timeout */ +#define CC1101_WOREVT0 0x1F /** Low byte Event 0 timeout */ +#define CC1101_WORCTRL 0x20 /** Wake On Radio control */ +#define CC1101_FREND1 0x21 /** Front end RX configuration */ +#define CC1101_FREND0 0x22 /** Front end TX configuration */ +#define CC1101_FSCAL3 0x23 /** Frequency synthesizer calibration */ +#define CC1101_FSCAL2 0x24 /** Frequency synthesizer calibration */ +#define CC1101_FSCAL1 0x25 /** Frequency synthesizer calibration */ +#define CC1101_FSCAL0 0x26 /** Frequency synthesizer calibration */ +#define CC1101_RCCTRL1 0x27 /** RC oscillator configuration */ +#define CC1101_RCCTRL0 0x28 /** RC oscillator configuration */ +#define CC1101_FSTEST 0x29 /** Frequency synthesizer calibration control */ +#define CC1101_PTEST 0x2A /** Production test */ +#define CC1101_AGCTEST 0x2B /** AGC test */ +#define CC1101_TEST2 0x2C /** Various test settings */ +#define CC1101_TEST1 0x2D /** Various test settings */ +#define CC1101_TEST0 0x2E /** Various test settings */ + +/* Strobe registers, CC1101_BURST is not available, CC1101_WRITE ignored */ +#define CC1101_STROBE_SRES 0x30 /** Reset chip. */ +#define CC1101_STROBE_SFSTXON 0x31 /** Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1). If in RX (with CCA): Go to a wait state where only the synthesizer is running (for quick RX / TX turnaround). */ +#define CC1101_STROBE_SXOFF 0x32 /** Turn off crystal oscillator. */ +#define CC1101_STROBE_SCAL 0x33 /** Calibrate frequency synthesizer and turn it off. SCAL can be strobed from IDLE mode without setting manual calibration mode (MCSM0.FS_AUTOCAL=0) */ +#define CC1101_STROBE_SRX 0x34 /** Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL=1. */ +#define CC1101_STROBE_STX 0x35 /** In IDLE state: Enable TX. Perform calibration first if MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled: Only go to TX if channel is clear. */ +#define CC1101_STROBE_SIDLE 0x36 /** Exit RX / TX, turn off frequency synthesizer and exit Wake-On-Radio mode if applicable. */ +#define CC1101_STROBE_SWOR 0x38 /** Start automatic RX polling sequence (Wake-on-Radio) as described in Section 19.5 if WORCTRL.RC_PD=0. */ +/* 0x37 is unused */ +#define CC1101_STROBE_SPWD 0x39 /** Enter power down mode when CSn goes high. */ +#define CC1101_STROBE_SFRX 0x3A /** Flush the RX FIFO buffer. Only issue SFRX in IDLE or RXFIFO_OVERFLOW states. */ +#define CC1101_STROBE_SFTX 0x3B /** Flush the TX FIFO buffer. Only issue SFTX in IDLE or TXFIFO_UNDERFLOW states. */ +#define CC1101_STROBE_SWORRST 0x3C /** Reset real time clock to Event1 value. */ +#define CC1101_STROBE_SNOP 0x3D /** No operation. May be used to get access to the chip status byte.*/ + +/* Status registers, must be accessed with CC1101_BURST, but one by one */ +#define CC1101_STATUS_PARTNUM 0x30 /** Chip ID Part Number */ +#define CC1101_STATUS_VERSION 0x31 /** Chip ID Version */ +#define CC1101_STATUS_FREQEST 0x32 /** Frequency Offset Estimate from Demodulator */ +#define CC1101_STATUS_LQI 0x33 /** Demodulator Estimate for Link Quality */ +#define CC1101_STATUS_RSSI 0x34 /** Received Signal Strength Indication */ +#define CC1101_STATUS_MARCSTATE 0x35 /** Main Radio Control State Machine State */ +#define CC1101_STATUS_WORTIME1 0x36 /** High Byte of WOR Time */ +#define CC1101_STATUS_WORTIME0 0x37 /** Low Byte of WOR Time */ +#define CC1101_STATUS_PKTSTATUS 0x38 /** Current GDOx Status and Packet Status */ +#define CC1101_STATUS_VCO_VC_DAC 0x39 /** Current Setting from PLL Calibration Module */ +#define CC1101_STATUS_TXBYTES 0x3A /** Underflow and Number of Bytes */ +#define CC1101_STATUS_RXBYTES 0x3B /** Overflow and Number of Bytes */ +#define CC1101_STATUS_RCCTRL1_STATUS 0x3C /** Last RC Oscillator Calibration Result */ +#define CC1101_STATUS_RCCTRL0_STATUS 0x3D /** Last RC Oscillator Calibration Result */ + +/* Some special registers, use CC1101_BURST to read/write data */ +#define CC1101_PATABLE 0x3E /** PATABLE register number, an 8-byte table that defines the PA control settings */ +#define CC1101_FIFO 0x3F /** FIFO register nunmber, can be combined with CC1101_WRITE and/or CC1101_BURST */ + +typedef enum { + CC1101StateIDLE=0b000, /** IDLE state */ + CC1101StateRX=0b001, /** Receive mode */ + CC1101StateTX=0b010, /** Transmit mode */ + CC1101StateFSTXON=0b011, /** Fast TX ready */ + CC1101StateCALIBRATE=0b100, /** Frequency synthesizer calibration is running */ + CC1101StateSETTLING=0b101, /** PLL is settling */ + CC1101StateRXFIFO_OVERFLOW=0b110, /** RX FIFO has overflowed. Read out any useful data, then flush the FIFO with SFRX */ + CC1101StateTXFIFO_UNDERFLOW=0b111, /** TX FIFO has underflowed. Acknowledge with SFTX */ +} CC1101State; + +typedef struct { + uint8_t FIFO_BYTES_AVAILABLE:4; + CC1101State STATE:3; + bool CHIP_RDYn:1; +} CC1101Status; + +typedef struct { + uint8_t NUM_TXBYTES:7; + bool TXFIFO_UNDERFLOW:1; +} CC1101TxBytes; + +typedef struct { + uint8_t NUM_RXBYTES:7; + bool RXFIFO_OVERFLOW:1; +} CC1101RxBytes; + +#ifdef __cplusplus +} +#endif \ No newline at end of file