From 06b8b9bf1e80b725a778c8dfd008773ec88d7e0d Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 12 Jul 2023 13:41:46 +0400 Subject: [PATCH] SubGhz: fix check connect cc1101_ext (#2857) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: fix check connect cc1101_ext * SubGhz: fix syntax * SubGhz: enable interface pin pullups * SubGhz: fix syntax * SubGhz: fix CLI check connect CC1101_ext * SubGhz: fix CLI display of the selected device Co-authored-by: あく --- .../drivers/subghz/cc1101_ext/cc1101_ext.c | 55 +++++++++--- applications/main/subghz/subghz_cli.c | 34 +++++--- .../targets/f7/furi_hal/furi_hal_spi_config.c | 49 ++++++++++- lib/drivers/cc1101.c | 83 ++++++++++--------- lib/drivers/cc1101.h | 28 +++++-- lib/drivers/cc1101_regs.h | 2 +- 6 files changed, 178 insertions(+), 73 deletions(-) diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c index 896b9bd2..594a74a0 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c @@ -87,6 +87,7 @@ static bool subghz_device_cc1101_ext_check_init() { subghz_device_cc1101_ext->state = SubGhzDeviceCC1101ExtStateIdle; bool ret = false; + CC1101Status cc1101_status = {0}; furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle); FuriHalCortexTimer timer = furi_hal_cortex_timer_get(100 * 1000); @@ -94,16 +95,34 @@ static bool subghz_device_cc1101_ext_check_init() { // Reset furi_hal_gpio_init( subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_reset(subghz_device_cc1101_ext->spi_bus_handle); - cc1101_write_reg( - subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHighImpedance); + furi_hal_gpio_init( + subghz_device_cc1101_ext->spi_bus_handle->miso, + GpioModeInput, + GpioPullUp, + GpioSpeedLow); + cc1101_status = cc1101_reset(subghz_device_cc1101_ext->spi_bus_handle); + if(cc1101_status.CHIP_RDYn != 0) { + //timeout or error + break; + } + cc1101_status = cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHighImpedance); + if(cc1101_status.CHIP_RDYn != 0) { + //timeout or error + break; + } // Prepare GD0 for power on self test furi_hal_gpio_init( - subghz_device_cc1101_ext->g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow); + subghz_device_cc1101_ext->g0_pin, GpioModeInput, GpioPullUp, GpioSpeedLow); // GD0 low - cc1101_write_reg(subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHW); + cc1101_status = cc1101_write_reg( + subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHW); + if(cc1101_status.CHIP_RDYn != 0) { + //timeout or error + break; + } while(furi_hal_gpio_read(subghz_device_cc1101_ext->g0_pin) != false) { if(furi_hal_cortex_timer_is_expired(timer)) { //timeout @@ -116,10 +135,16 @@ static bool subghz_device_cc1101_ext_check_init() { } // GD0 high - cc1101_write_reg( + furi_hal_gpio_init( + subghz_device_cc1101_ext->g0_pin, GpioModeInput, GpioPullDown, GpioSpeedLow); + cc1101_status = cc1101_write_reg( subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); + if(cc1101_status.CHIP_RDYn != 0) { + //timeout or error + break; + } while(furi_hal_gpio_read(subghz_device_cc1101_ext->g0_pin) != true) { if(furi_hal_cortex_timer_is_expired(timer)) { //timeout @@ -132,17 +157,21 @@ static bool subghz_device_cc1101_ext_check_init() { } // Reset GD0 to floating state - cc1101_write_reg( + cc1101_status = cc1101_write_reg( subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHighImpedance); + if(cc1101_status.CHIP_RDYn != 0) { + //timeout or error + break; + } furi_hal_gpio_init( subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - // RF switches - furi_hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - cc1101_write_reg(subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHW); - // Go to sleep - cc1101_shutdown(subghz_device_cc1101_ext->spi_bus_handle); + cc1101_status = cc1101_shutdown(subghz_device_cc1101_ext->spi_bus_handle); + if(cc1101_status.CHIP_RDYn != 0) { + //timeout or error + break; + } ret = true; } while(false); @@ -152,6 +181,8 @@ static bool subghz_device_cc1101_ext_check_init() { FURI_LOG_I(TAG, "Init OK"); } else { FURI_LOG_E(TAG, "Init failed"); + furi_hal_gpio_init( + subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } return ret; } diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index bc7be507..fe97c8a0 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -28,12 +28,20 @@ #define SUBGHZ_REGION_FILENAME "/int/.region_data" +#define TAG "SubGhz CLI" + static void subghz_cli_radio_device_power_on() { - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - //CC1101 power-up time - furi_delay_ms(10); + uint8_t attempts = 5; + while(--attempts > 0) { + if(furi_hal_power_enable_otg()) break; + } + if(attempts == 0) { + if(furi_hal_power_get_usb_voltage() < 4.5f) { + FURI_LOG_E( + "TAG", + "Error power otg enable. BQ2589 check otg fault = %d", + furi_hal_power_check_otg_fault() ? 1 : 0); + } } } @@ -126,9 +134,9 @@ void subghz_cli_command_rx_carrier(Cli* cli, FuriString* args, void* context) { furi_hal_subghz_sleep(); } -static const SubGhzDevice* subghz_cli_command_get_device(uint32_t device_ind) { +static const SubGhzDevice* subghz_cli_command_get_device(uint32_t* device_ind) { const SubGhzDevice* device = NULL; - switch(device_ind) { + switch(*device_ind) { case 1: subghz_cli_radio_device_power_on(); device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME); @@ -138,6 +146,12 @@ static const SubGhzDevice* subghz_cli_command_get_device(uint32_t device_ind) { device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); break; } + //check if the device is connected + if(!subghz_devices_is_connect(device)) { + subghz_cli_radio_device_power_off(); + device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); + *device_ind = 0; + } return device; } @@ -175,7 +189,7 @@ void subghz_cli_command_tx(Cli* cli, FuriString* args, void* context) { } } subghz_devices_init(); - const SubGhzDevice* device = subghz_cli_command_get_device(device_ind); + const SubGhzDevice* device = subghz_cli_command_get_device(&device_ind); if(!subghz_devices_is_frequency_valid(device, frequency)) { printf( "Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n", frequency); @@ -295,7 +309,7 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) { } } subghz_devices_init(); - const SubGhzDevice* device = subghz_cli_command_get_device(device_ind); + const SubGhzDevice* device = subghz_cli_command_get_device(&device_ind); if(!subghz_devices_is_frequency_valid(device, frequency)) { printf( "Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n", frequency); @@ -688,7 +702,7 @@ static void subghz_cli_command_chat(Cli* cli, FuriString* args) { } } subghz_devices_init(); - const SubGhzDevice* device = subghz_cli_command_get_device(device_ind); + const SubGhzDevice* device = subghz_cli_command_get_device(&device_ind); if(!subghz_devices_is_frequency_valid(device, frequency)) { printf( "Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n", frequency); diff --git a/firmware/targets/f7/furi_hal/furi_hal_spi_config.c b/firmware/targets/f7/furi_hal/furi_hal_spi_config.c index 09ac79d2..757ac236 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_spi_config.c +++ b/firmware/targets/f7/furi_hal/furi_hal_spi_config.c @@ -192,6 +192,52 @@ inline static void furi_hal_spi_bus_r_handle_event_callback( } } +inline static void furi_hal_spi_bus_external_handle_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event, + const LL_SPI_InitTypeDef* preset) { + if(event == FuriHalSpiBusHandleEventInit) { + furi_hal_gpio_write(handle->cs, true); + furi_hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); + } else if(event == FuriHalSpiBusHandleEventDeinit) { + furi_hal_gpio_write(handle->cs, true); + furi_hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } else if(event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + + furi_hal_gpio_init_ex( + handle->miso, + GpioModeAltFunctionPushPull, + GpioPullDown, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + furi_hal_gpio_init_ex( + handle->mosi, + GpioModeAltFunctionPushPull, + GpioPullDown, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + furi_hal_gpio_init_ex( + handle->sck, + GpioModeAltFunctionPushPull, + GpioPullDown, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + + furi_hal_gpio_write(handle->cs, false); + } else if(event == FuriHalSpiBusHandleEventDeactivate) { + furi_hal_gpio_write(handle->cs, true); + + furi_hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + LL_SPI_Disable(handle->bus->spi); + } +} + inline static void furi_hal_spi_bus_nfc_handle_event_callback( FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event, @@ -291,7 +337,8 @@ FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc = { static void furi_hal_spi_bus_handle_external_event_callback( FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { - furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); + furi_hal_spi_bus_external_handle_event_callback( + handle, event, &furi_hal_spi_preset_1edge_low_2m); } FuriHalSpiBusHandle furi_hal_spi_bus_handle_external = { diff --git a/lib/drivers/cc1101.c b/lib/drivers/cc1101.c index d0feb021..85d915ac 100644 --- a/lib/drivers/cc1101.c +++ b/lib/drivers/cc1101.c @@ -1,14 +1,27 @@ #include "cc1101.h" #include #include +#include + +static bool cc1101_spi_trx(FuriHalSpiBusHandle* handle, uint8_t* tx, uint8_t* rx, uint8_t size) { + FuriHalCortexTimer timer = furi_hal_cortex_timer_get(CC1101_TIMEOUT * 1000); + + while(furi_hal_gpio_read(handle->miso)) { + if(furi_hal_cortex_timer_is_expired(timer)) { + //timeout + return false; + } + } + if(!furi_hal_spi_bus_trx(handle, tx, rx, size, CC1101_TIMEOUT)) return false; + return true; +} CC1101Status cc1101_strobe(FuriHalSpiBusHandle* handle, uint8_t strobe) { uint8_t tx[1] = {strobe}; CC1101Status rx[1] = {0}; + rx[0].CHIP_RDYn = 1; - while(furi_hal_gpio_read(handle->miso)) - ; - furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 1, CC1101_TIMEOUT); + cc1101_spi_trx(handle, tx, (uint8_t*)rx, 1); assert(rx[0].CHIP_RDYn == 0); return rx[0]; @@ -17,10 +30,10 @@ CC1101Status cc1101_strobe(FuriHalSpiBusHandle* handle, uint8_t strobe) { CC1101Status cc1101_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) { uint8_t tx[2] = {reg, data}; CC1101Status rx[2] = {0}; + rx[0].CHIP_RDYn = 1; + rx[1].CHIP_RDYn = 1; - while(furi_hal_gpio_read(handle->miso)) - ; - furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); + cc1101_spi_trx(handle, tx, (uint8_t*)rx, 2); assert((rx[0].CHIP_RDYn | rx[1].CHIP_RDYn) == 0); return rx[1]; @@ -30,10 +43,9 @@ CC1101Status cc1101_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* assert(sizeof(CC1101Status) == 1); uint8_t tx[2] = {reg | CC1101_READ, 0}; CC1101Status rx[2] = {0}; + rx[0].CHIP_RDYn = 1; - while(furi_hal_gpio_read(handle->miso)) - ; - furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); + cc1101_spi_trx(handle, tx, (uint8_t*)rx, 2); assert((rx[0].CHIP_RDYn) == 0); *data = *(uint8_t*)&rx[1]; @@ -58,40 +70,40 @@ uint8_t cc1101_get_rssi(FuriHalSpiBusHandle* handle) { return rssi; } -void cc1101_reset(FuriHalSpiBusHandle* handle) { - cc1101_strobe(handle, CC1101_STROBE_SRES); +CC1101Status cc1101_reset(FuriHalSpiBusHandle* handle) { + return cc1101_strobe(handle, CC1101_STROBE_SRES); } CC1101Status cc1101_get_status(FuriHalSpiBusHandle* handle) { return cc1101_strobe(handle, CC1101_STROBE_SNOP); } -void cc1101_shutdown(FuriHalSpiBusHandle* handle) { - cc1101_strobe(handle, CC1101_STROBE_SPWD); +CC1101Status cc1101_shutdown(FuriHalSpiBusHandle* handle) { + return cc1101_strobe(handle, CC1101_STROBE_SPWD); } -void cc1101_calibrate(FuriHalSpiBusHandle* handle) { - cc1101_strobe(handle, CC1101_STROBE_SCAL); +CC1101Status cc1101_calibrate(FuriHalSpiBusHandle* handle) { + return cc1101_strobe(handle, CC1101_STROBE_SCAL); } -void cc1101_switch_to_idle(FuriHalSpiBusHandle* handle) { - cc1101_strobe(handle, CC1101_STROBE_SIDLE); +CC1101Status cc1101_switch_to_idle(FuriHalSpiBusHandle* handle) { + return cc1101_strobe(handle, CC1101_STROBE_SIDLE); } -void cc1101_switch_to_rx(FuriHalSpiBusHandle* handle) { - cc1101_strobe(handle, CC1101_STROBE_SRX); +CC1101Status cc1101_switch_to_rx(FuriHalSpiBusHandle* handle) { + return cc1101_strobe(handle, CC1101_STROBE_SRX); } -void cc1101_switch_to_tx(FuriHalSpiBusHandle* handle) { - cc1101_strobe(handle, CC1101_STROBE_STX); +CC1101Status cc1101_switch_to_tx(FuriHalSpiBusHandle* handle) { + return cc1101_strobe(handle, CC1101_STROBE_STX); } -void cc1101_flush_rx(FuriHalSpiBusHandle* handle) { - cc1101_strobe(handle, CC1101_STROBE_SFRX); +CC1101Status cc1101_flush_rx(FuriHalSpiBusHandle* handle) { + return cc1101_strobe(handle, CC1101_STROBE_SFRX); } -void cc1101_flush_tx(FuriHalSpiBusHandle* handle) { - cc1101_strobe(handle, CC1101_STROBE_SFTX); +CC1101Status cc1101_flush_tx(FuriHalSpiBusHandle* handle) { + return cc1101_strobe(handle, CC1101_STROBE_SFTX); } uint32_t cc1101_set_frequency(FuriHalSpiBusHandle* handle, uint32_t value) { @@ -123,12 +135,12 @@ uint32_t cc1101_set_intermediate_frequency(FuriHalSpiBusHandle* handle, uint32_t void cc1101_set_pa_table(FuriHalSpiBusHandle* handle, const uint8_t value[8]) { uint8_t tx[9] = {CC1101_PATABLE | CC1101_BURST}; //-V1009 CC1101Status rx[9] = {0}; + rx[0].CHIP_RDYn = 1; + rx[8].CHIP_RDYn = 1; memcpy(&tx[1], &value[0], 8); - while(furi_hal_gpio_read(handle->miso)) - ; - furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, sizeof(rx), CC1101_TIMEOUT); + cc1101_spi_trx(handle, tx, (uint8_t*)rx, sizeof(rx)); assert((rx[0].CHIP_RDYn | rx[8].CHIP_RDYn) == 0); } @@ -139,12 +151,7 @@ uint8_t cc1101_write_fifo(FuriHalSpiBusHandle* handle, const uint8_t* data, uint buff_tx[0] = CC1101_FIFO | CC1101_BURST; memcpy(&buff_tx[1], data, size); - // Start transaction - // Wait IC to become ready - while(furi_hal_gpio_read(handle->miso)) - ; - // Tell IC what we want - furi_hal_spi_bus_trx(handle, buff_tx, (uint8_t*)buff_rx, size + 1, CC1101_TIMEOUT); + cc1101_spi_trx(handle, buff_tx, (uint8_t*)buff_rx, size + 1); return size; } @@ -153,13 +160,7 @@ uint8_t cc1101_read_fifo(FuriHalSpiBusHandle* handle, uint8_t* data, uint8_t* si uint8_t buff_trx[2]; buff_trx[0] = CC1101_FIFO | CC1101_READ | CC1101_BURST; - // Start transaction - // Wait IC to become ready - while(furi_hal_gpio_read(handle->miso)) - ; - - // First byte - packet length - furi_hal_spi_bus_trx(handle, buff_trx, buff_trx, 2, CC1101_TIMEOUT); + cc1101_spi_trx(handle, buff_trx, buff_trx, 2); // Check that the packet is placed in the receive buffer if(buff_trx[1] > 64) { diff --git a/lib/drivers/cc1101.h b/lib/drivers/cc1101.h index af1f1556..d8ee05d5 100644 --- a/lib/drivers/cc1101.h +++ b/lib/drivers/cc1101.h @@ -46,8 +46,10 @@ CC1101Status cc1101_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* /** Reset * * @param handle - pointer to FuriHalSpiHandle + * + * @return CC1101Status structure */ -void cc1101_reset(FuriHalSpiBusHandle* handle); +CC1101Status cc1101_reset(FuriHalSpiBusHandle* handle); /** Get status * @@ -60,8 +62,10 @@ CC1101Status cc1101_get_status(FuriHalSpiBusHandle* handle); /** Enable shutdown mode * * @param handle - pointer to FuriHalSpiHandle + * + * @return CC1101Status structure */ -void cc1101_shutdown(FuriHalSpiBusHandle* handle); +CC1101Status cc1101_shutdown(FuriHalSpiBusHandle* handle); /** Get Partnumber * @@ -90,38 +94,46 @@ uint8_t cc1101_get_rssi(FuriHalSpiBusHandle* handle); /** Calibrate oscillator * * @param handle - pointer to FuriHalSpiHandle + * + * @return CC1101Status structure */ -void cc1101_calibrate(FuriHalSpiBusHandle* handle); +CC1101Status cc1101_calibrate(FuriHalSpiBusHandle* handle); /** Switch to idle * * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_switch_to_idle(FuriHalSpiBusHandle* handle); +CC1101Status cc1101_switch_to_idle(FuriHalSpiBusHandle* handle); /** Switch to RX * * @param handle - pointer to FuriHalSpiHandle + * + * @return CC1101Status structure */ -void cc1101_switch_to_rx(FuriHalSpiBusHandle* handle); +CC1101Status cc1101_switch_to_rx(FuriHalSpiBusHandle* handle); /** Switch to TX * * @param handle - pointer to FuriHalSpiHandle + * + * @return CC1101Status structure */ -void cc1101_switch_to_tx(FuriHalSpiBusHandle* handle); +CC1101Status cc1101_switch_to_tx(FuriHalSpiBusHandle* handle); /** Flush RX FIFO * * @param handle - pointer to FuriHalSpiHandle + * + * @return CC1101Status structure */ -void cc1101_flush_rx(FuriHalSpiBusHandle* handle); +CC1101Status cc1101_flush_rx(FuriHalSpiBusHandle* handle); /** Flush TX FIFO * * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_flush_tx(FuriHalSpiBusHandle* handle); +CC1101Status cc1101_flush_tx(FuriHalSpiBusHandle* handle); /** Set Frequency * diff --git a/lib/drivers/cc1101_regs.h b/lib/drivers/cc1101_regs.h index a326dc92..e0aed6bd 100644 --- a/lib/drivers/cc1101_regs.h +++ b/lib/drivers/cc1101_regs.h @@ -14,7 +14,7 @@ extern "C" { #define CC1101_IFDIV 0x400 /* IO Bus constants */ -#define CC1101_TIMEOUT 500 +#define CC1101_TIMEOUT 250 /* Bits and pieces */ #define CC1101_READ (1 << 7) /** Read Bit */