From 851a44dc59ea614a767ea4e031752e9537a1f9ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 15 Jul 2021 16:54:11 +0300 Subject: [PATCH] [FL-1528] SubGhz: dma send (#579) * Gui: input injection in screen stream * Cli: expose ASCII table in public header * SubGhz: dma output draft * SubGhz: output initialization cleanup * SubGhz: update dma send routine, add subghz_tx cli command. * SubGhz: proper register address for DMA * SubGhz: proper, fully working dma+tim2 configuration * SubGhz: transmit PT with cli. * Drivers: fix invalid size in CC1101 PA_TABLE loading routine. * Interrupts: configurable DMA isrs. * F5: backport fixes. * SubGhz: free buffer after use * SubGhz: use sleep instead of reset at the end * SubGhz: async tx repeat with circular DMA * SubGhz: disable dma channel on complete, adjust PT send timings * SubGhz: backport function singature change to F5 * SubGhz: add tx debug gpio --- applications/subghz/subghz_cli.c | 96 +++++++-- applications/subghz/views/subghz_capture.c | 8 +- applications/subghz/views/subghz_static.c | 12 +- applications/subghz/views/subghz_test_basic.c | 4 +- .../subghz/views/subghz_test_packet.c | 2 +- .../targets/api-hal-include/api-hal-subghz.h | 41 +++- firmware/targets/api-hal-include/api-hal.h | 2 + .../targets/f5/api-hal/api-hal-interrupt.h | 0 firmware/targets/f5/api-hal/api-hal-subghz.c | 59 +++++- firmware/targets/f6/api-hal/api-hal-clock.c | 9 + firmware/targets/f6/api-hal/api-hal-clock.h | 7 +- .../targets/f6/api-hal/api-hal-interrupt.c | 104 ++++++++- .../targets/f6/api-hal/api-hal-interrupt.h | 15 +- firmware/targets/f6/api-hal/api-hal-subghz.c | 197 ++++++++++++++++-- firmware/targets/f6/api-hal/api-hal.c | 4 + firmware/targets/f6/target.mk | 8 +- lib/drivers/cc1101.c | 2 +- 17 files changed, 485 insertions(+), 85 deletions(-) create mode 100644 firmware/targets/f5/api-hal/api-hal-interrupt.h diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index ac9d439b..92693e0e 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -66,9 +66,8 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { osDelay(250); } - api_hal_subghz_reset(); api_hal_subghz_set_path(ApiHalSubGhzPathIsolate); - hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + api_hal_subghz_sleep(); } void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { @@ -92,8 +91,6 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { printf("Receiving at frequency %lu Hz\r\n", frequency); printf("Press CTRL+C to stop\r\n"); - hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - api_hal_subghz_rx(); while(!cli_cmd_interrupt_received(cli)) { @@ -102,8 +99,8 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { fflush(stdout); } - api_hal_subghz_reset(); api_hal_subghz_set_path(ApiHalSubGhzPathIsolate); + api_hal_subghz_sleep(); } void subghz_cli_command_tx_pt(Cli* cli, string_t args, void* context) { @@ -148,16 +145,13 @@ void subghz_cli_command_tx_pt(Cli* cli, string_t args, void* context) { api_hal_subghz_idle(); api_hal_subghz_write_packet(subghz_test_packet_data, sizeof(subghz_test_packet_data)); api_hal_subghz_tx(); - while(!hal_gpio_read(&gpio_cc1101_g0)) - ; // Wait for sync - while(hal_gpio_read(&gpio_cc1101_g0)) - ; // Wait end of transaction + while(!hal_gpio_read(&gpio_cc1101_g0)) osDelay(1); // Wait for sync + while(hal_gpio_read(&gpio_cc1101_g0)) osDelay(1); // Wait end of transaction count--; } - api_hal_subghz_reset(); + api_hal_subghz_sleep(); api_hal_subghz_set_path(ApiHalSubGhzPathIsolate); - hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } void subghz_cli_command_rx_pt(Cli* cli, string_t args, void* context) { @@ -204,12 +198,73 @@ void subghz_cli_command_rx_pt(Cli* cli, string_t args, void* context) { printf("Received %lu packets", packet_cnt); - api_hal_subghz_reset(); + api_hal_subghz_sleep(); api_hal_subghz_set_path(ApiHalSubGhzPathIsolate); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } +#define SUBGHZ_PT_SHORT 260 +#define SUBGHZ_PT_LONG (SUBGHZ_PT_SHORT * 3) +#define SUBGHZ_PT_GUARD 8060 + void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { + uint32_t frequency = 433920000; + size_t repeat = 10; + uint32_t key = 0x0074BADE; + + if(string_size(args)) { + int ret = sscanf(string_get_cstr(args), "%lx %lu %u", &key, &frequency, &repeat); + if(ret != 3) { + printf( + "sscanf returned %d, key: %lx, frequency: %lu, repeat: %u\r\n", + ret, + key, + frequency, + repeat); + cli_print_usage( + "subghz_rx", + "<3 Byte Key in hex> ", + string_get_cstr(args)); + return; + } + + if(!subghz_check_frequency_range(frequency)) { + printf( + "Frequency must be in " CC1101_FREQUENCY_RANGE_STR " range, not %lu\r\n", + frequency); + return; + } + } + + size_t subghz_test_data_size = 25 * 2 * sizeof(uint32_t); + uint32_t* subghz_test_data = furi_alloc(subghz_test_data_size); + + size_t pos = 0; + for(uint8_t i = 0; i < 24; i++) { + uint8_t byte = i / 8; + uint8_t bit = i % 8; + bool value = (((uint8_t*)&key)[2 - byte] >> (7 - bit)) & 1; + if(value) { + subghz_test_data[pos++] = SUBGHZ_PT_SHORT; + subghz_test_data[pos++] = SUBGHZ_PT_LONG; + } else { + subghz_test_data[pos++] = SUBGHZ_PT_LONG; + subghz_test_data[pos++] = SUBGHZ_PT_SHORT; + } + } + subghz_test_data[pos++] = SUBGHZ_PT_SHORT; + subghz_test_data[pos++] = SUBGHZ_PT_SHORT + SUBGHZ_PT_GUARD; + + api_hal_subghz_reset(); + api_hal_subghz_load_preset(ApiHalSubGhzPresetMP); + frequency = api_hal_subghz_set_frequency_and_path(frequency); + + api_hal_subghz_start_async_tx(subghz_test_data, subghz_test_data_size, repeat); + api_hal_subghz_wait_async_tx(); + api_hal_subghz_stop_async_tx(); + + free(subghz_test_data); + api_hal_subghz_sleep(); } #include @@ -248,25 +303,20 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { } api_hal_subghz_reset(); - api_hal_subghz_idle(); api_hal_subghz_load_preset(ApiHalSubGhzPresetMP); + frequency = api_hal_subghz_set_frequency_and_path(frequency); + hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); SubGhzProtocol* protocol = subghz_protocol_alloc(); subghz_protocol_load_keeloq_file(protocol, "/assets/subghz/keeloq_mfcodes"); subghz_protocol_load_nice_flor_s_file(protocol, "/assets/subghz/nice_floor_s_rx"); subghz_protocol_enable_dump_text(protocol, NULL, NULL); - frequency = api_hal_subghz_set_frequency_and_path(frequency); - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); - StreamBufferHandle_t rx_stream = xStreamBufferCreate(sizeof(LevelDuration) * 1024, sizeof(LevelDuration)); - api_hal_subghz_set_capture_callback(subghz_cli_command_rx_callback, rx_stream); - api_hal_subghz_enable_capture(); - - api_hal_subghz_flush_rx(); - api_hal_subghz_rx(); + api_hal_subghz_set_async_rx_callback(subghz_cli_command_rx_callback, rx_stream); + api_hal_subghz_start_async_rx(); printf("Listening at %lu. Press CTRL+C to stop\r\n", frequency); LevelDuration level_duration; @@ -284,8 +334,8 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { } } + api_hal_subghz_stop_async_rx(); + api_hal_subghz_sleep(); subghz_protocol_free(protocol); vStreamBufferDelete(rx_stream); - api_hal_subghz_disable_capture(); - api_hal_subghz_init(); } diff --git a/applications/subghz/views/subghz_capture.c b/applications/subghz/views/subghz_capture.c index 3dbcb5f3..c2cd44af 100644 --- a/applications/subghz/views/subghz_capture.c +++ b/applications/subghz/views/subghz_capture.c @@ -156,8 +156,8 @@ void subghz_capture_enter(void* context) { hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); - api_hal_subghz_set_capture_callback(subghz_worker_rx_callback, subghz_capture->worker); - api_hal_subghz_enable_capture(); + api_hal_subghz_set_async_rx_callback(subghz_worker_rx_callback, subghz_capture->worker); + api_hal_subghz_start_async_rx(); subghz_worker_start(subghz_capture->worker); @@ -171,8 +171,8 @@ void subghz_capture_exit(void* context) { subghz_worker_stop(subghz_capture->worker); - api_hal_subghz_disable_capture(); - api_hal_subghz_init(); + api_hal_subghz_stop_async_rx(); + api_hal_subghz_sleep(); } uint32_t subghz_capture_back(void* context) { diff --git a/applications/subghz/views/subghz_static.c b/applications/subghz/views/subghz_static.c index 4506b027..0d8977cc 100644 --- a/applications/subghz/views/subghz_static.c +++ b/applications/subghz/views/subghz_static.c @@ -100,15 +100,15 @@ bool subghz_static_input(InputEvent* event, void* context) { uint8_t bit = i % 8; bool value = (key[byte] >> (7 - bit)) & 1; // Payload send - hal_gpio_write(&gpio_cc1101_g0, false); - delay_us(value ? SUBGHZ_PT_ONE : SUBGHZ_PT_ZERO); hal_gpio_write(&gpio_cc1101_g0, true); + delay_us(value ? SUBGHZ_PT_ONE : SUBGHZ_PT_ZERO); + hal_gpio_write(&gpio_cc1101_g0, false); delay_us(value ? SUBGHZ_PT_ZERO : SUBGHZ_PT_ONE); } // Last bit - hal_gpio_write(&gpio_cc1101_g0, false); - delay_us(SUBGHZ_PT_ONE); hal_gpio_write(&gpio_cc1101_g0, true); + delay_us(SUBGHZ_PT_ONE); + hal_gpio_write(&gpio_cc1101_g0, false); // Guard time delay_us(10600); } @@ -132,7 +132,7 @@ void subghz_static_enter(void* context) { api_hal_subghz_load_preset(ApiHalSubGhzPresetOokAsync); hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_cc1101_g0, true); + hal_gpio_write(&gpio_cc1101_g0, false); with_view_model( subghz_static->view, (SubghzStaticModel * model) { @@ -151,7 +151,7 @@ void subghz_static_exit(void* context) { // SubghzStatic* subghz_static = context; // Reinitialize IC to default state - api_hal_subghz_init(); + api_hal_subghz_sleep(); } uint32_t subghz_static_back(void* context) { diff --git a/applications/subghz/views/subghz_test_basic.c b/applications/subghz/views/subghz_test_basic.c index cdfe1f0c..b3107d54 100644 --- a/applications/subghz/views/subghz_test_basic.c +++ b/applications/subghz/views/subghz_test_basic.c @@ -108,7 +108,7 @@ bool subghz_test_basic_input(InputEvent* event, void* context) { osTimerStart(subghz_test_basic->timer, 1024 / 4); } else { hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_cc1101_g0, false); + hal_gpio_write(&gpio_cc1101_g0, true); api_hal_subghz_tx(); } @@ -150,7 +150,7 @@ void subghz_test_basic_exit(void* context) { osTimerStop(subghz_test_basic->timer); // Reinitialize IC to default state - api_hal_subghz_init(); + api_hal_subghz_sleep(); } void subghz_test_basic_rssi_timer_callback(void* context) { diff --git a/applications/subghz/views/subghz_test_packet.c b/applications/subghz/views/subghz_test_packet.c index 27aa264b..7ee4f7d3 100644 --- a/applications/subghz/views/subghz_test_packet.c +++ b/applications/subghz/views/subghz_test_packet.c @@ -157,7 +157,7 @@ void subghz_test_packet_exit(void* context) { osTimerStop(subghz_test_packet->timer); // Reinitialize IC to default state - api_hal_subghz_init(); + api_hal_subghz_sleep(); } void subghz_test_packet_rssi_timer_callback(void* context) { diff --git a/firmware/targets/api-hal-include/api-hal-subghz.h b/firmware/targets/api-hal-include/api-hal-subghz.h index d4e5cb5d..bb460e85 100644 --- a/firmware/targets/api-hal-include/api-hal-subghz.h +++ b/firmware/targets/api-hal-include/api-hal-subghz.h @@ -2,6 +2,7 @@ #include #include +#include #include #ifdef __cplusplus @@ -23,12 +24,28 @@ typedef enum { ApiHalSubGhzPath868, /** Center Frquency: 868MHz. Path 3: SW1RF3-SW2RF3, LCLC */ } ApiHalSubGhzPath; +/** SubGhz state */ +typedef enum { + SubGhzStateInit, /** Init pending */ + + SubGhzStateIdle, /** Idle, energy save mode */ + + SubGhzStateAsyncRx, /** Async RX started */ + + SubGhzStateAsyncTx, /** Async TX started, DMA and timer is on */ + SubGhzStateAsyncTxLast, /** Async TX continue, DMA completed and timer got last value to go */ + SubGhzStateAsyncTxEnd, /** Async TX complete, cleanup needed */ +} SubGhzState; + /** 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_subghz_init(); +/** Send device to sleep mode */ +void api_hal_subghz_sleep(); + /** Dump info to stdout */ void api_hal_subghz_dump_state(); @@ -60,7 +77,6 @@ void api_hal_subghz_write_packet(const uint8_t* data, uint8_t size); * @param data, pointer * @param size, size */ - void api_hal_subghz_read_packet(uint8_t* data, uint8_t* size); /** Flush rx FIFO buffer */ @@ -108,23 +124,40 @@ uint32_t api_hal_subghz_set_frequency(uint32_t value); */ void api_hal_subghz_set_path(ApiHalSubGhzPath path); +/* High Level API */ + /** Signal Timings Capture callback */ typedef void (*ApiHalSubGhzCaptureCallback)(bool level, uint32_t duration, void* context); /** Set signal timings capture callback * @param callback - your callback for front capture */ -void api_hal_subghz_set_capture_callback(ApiHalSubGhzCaptureCallback callback, void* context); +void api_hal_subghz_set_async_rx_callback(ApiHalSubGhzCaptureCallback callback, void* context); /** Enable signal timings capture * Initializes GPIO and TIM2 for timings capture */ -void api_hal_subghz_enable_capture(); +void api_hal_subghz_start_async_rx(); /** Disable signal timings capture * Resets GPIO and TIM2 */ -void api_hal_subghz_disable_capture(); +void api_hal_subghz_stop_async_rx(); + +/** Send buffer + * Initializes GPIO, TIM2 and DMA1 for signal output + * @param buffer - pointer to data buffer + * @param buffer_size - buffer size in bytes + */ +void api_hal_subghz_start_async_tx(uint32_t* buffer, size_t buffer_size, size_t repeat); + +/** Wait for async transmission to complete */ +void api_hal_subghz_wait_async_tx(); + +/** Stop async transmission and cleanup resources + * Resets GPIO, TIM2, and DMA1 + */ +void api_hal_subghz_stop_async_tx(); #ifdef __cplusplus } diff --git a/firmware/targets/api-hal-include/api-hal.h b/firmware/targets/api-hal-include/api-hal.h index be9849f3..145961dc 100644 --- a/firmware/targets/api-hal-include/api-hal.h +++ b/firmware/targets/api-hal-include/api-hal.h @@ -5,6 +5,7 @@ template struct STOP_EXTERNING_ME {}; #endif #include "api-hal-boot.h" +#include "api-hal-clock.h" #include "api-hal-os.h" #include "api-hal-i2c.h" #include "api-hal-resources.h" @@ -15,6 +16,7 @@ template struct STOP_EXTERNING_ME {}; #include "api-hal-task.h" #include "api-hal-power.h" #include "api-hal-vcp.h" +#include "api-hal-interrupt.h" #include "api-hal-version.h" #include "api-hal-bt.h" #include "api-hal-spi.h" diff --git a/firmware/targets/f5/api-hal/api-hal-interrupt.h b/firmware/targets/f5/api-hal/api-hal-interrupt.h new file mode 100644 index 00000000..e69de29b diff --git a/firmware/targets/f5/api-hal/api-hal-subghz.c b/firmware/targets/f5/api-hal/api-hal-subghz.c index 73091dc8..c102ccf2 100644 --- a/firmware/targets/f5/api-hal/api-hal-subghz.c +++ b/firmware/targets/f5/api-hal/api-hal-subghz.c @@ -2,11 +2,15 @@ #include #include +#include #include + #include #include #include +static volatile SubGhzState api_hal_subghz_state = SubGhzStateInit; + static const uint8_t api_hal_subghz_preset_ook_async_regs[][2] = { /* Base setting */ { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input @@ -22,7 +26,7 @@ static const uint8_t api_hal_subghz_preset_ook_async_regs[][2] = { }; static const uint8_t api_hal_subghz_preset_ook_async_patable[8] = { - 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const uint8_t api_hal_subghz_preset_mp_regs[][2] = { @@ -61,7 +65,7 @@ static const uint8_t api_hal_subghz_preset_mp_regs[][2] = { }; static const uint8_t api_hal_subghz_preset_mp_patable[8] = { - 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const uint8_t api_hal_subghz_preset_2fsk_packet_regs[][2] = { @@ -83,25 +87,52 @@ static const uint8_t api_hal_subghz_preset_2fsk_packet_patable[8] = { }; void api_hal_subghz_init() { - hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_init(&gpio_rf_sw_1, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_assert(api_hal_subghz_state == SubGhzStateInit); + api_hal_subghz_state = SubGhzStateIdle; const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); - // Reset and shutdown + + // Reset + hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); cc1101_reset(device); + cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + // Prepare GD0 for power on self test hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + // GD0 low cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW); while(hal_gpio_read(&gpio_cc1101_g0) != false); + // GD0 high cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); while(hal_gpio_read(&gpio_cc1101_g0) != true); + // Reset GD0 to floating state cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - // Turn off oscillator + + // RF switches + hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + hal_gpio_init(&gpio_rf_sw_1, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + + // Go to sleep cc1101_shutdown(device); + + api_hal_spi_device_return(device); +} + +void api_hal_subghz_sleep() { + furi_assert(api_hal_subghz_state == SubGhzStateIdle); + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + + cc1101_switch_to_idle(device); + + cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + cc1101_shutdown(device); + api_hal_spi_device_return(device); } @@ -181,7 +212,10 @@ void api_hal_subghz_shutdown() { void api_hal_subghz_reset() { const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + cc1101_switch_to_idle(device); cc1101_reset(device); + cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); api_hal_spi_device_return(device); } @@ -266,8 +300,15 @@ void api_hal_subghz_set_path(ApiHalSubGhzPath path) { } } -void api_hal_subghz_set_capture_callback(ApiHalSubGhzCaptureCallback callback, void* context) {} +void api_hal_subghz_set_async_rx_callback(ApiHalSubGhzCaptureCallback callback, void* context) {} -void api_hal_subghz_enable_capture() {} +void api_hal_subghz_start_async_rx() {} + +void api_hal_subghz_stop_async_rx() {} + +void api_hal_subghz_start_async_tx(uint32_t* buffer, size_t buffer_size, size_t repeat) {} + +void api_hal_subghz_wait_async_tx() {} + +void api_hal_subghz_stop_async_tx() {} -void api_hal_subghz_disable_capture() {} diff --git a/firmware/targets/f6/api-hal/api-hal-clock.c b/firmware/targets/f6/api-hal/api-hal-clock.c index 4659ca45..d07d0d95 100644 --- a/firmware/targets/f6/api-hal/api-hal-clock.c +++ b/firmware/targets/f6/api-hal/api-hal-clock.c @@ -2,6 +2,15 @@ #include +void api_hal_clock_init() { + // AHB + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); + + // APB + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); +} + void api_hal_clock_switch_to_hsi() { LL_RCC_HSI_Enable( ); diff --git a/firmware/targets/f6/api-hal/api-hal-clock.h b/firmware/targets/f6/api-hal/api-hal-clock.h index aa6b1da4..077d4f3f 100644 --- a/firmware/targets/f6/api-hal/api-hal-clock.h +++ b/firmware/targets/f6/api-hal/api-hal-clock.h @@ -1,7 +1,10 @@ #pragma once -/* Switch to HSI clock */ +/** Initialize clocks */ +void api_hal_clock_init(); + +/** Switch to HSI clock */ void api_hal_clock_switch_to_hsi(); -/* Switch to PLL clock */ +/** Switch to PLL clock */ void api_hal_clock_switch_to_pll(); diff --git a/firmware/targets/f6/api-hal/api-hal-interrupt.c b/firmware/targets/f6/api-hal/api-hal-interrupt.c index 00f45228..cbaf67fd 100644 --- a/firmware/targets/f6/api-hal/api-hal-interrupt.c +++ b/firmware/targets/f6/api-hal/api-hal-interrupt.c @@ -6,15 +6,17 @@ volatile ApiHalInterruptISR api_hal_tim_tim2_isr = NULL; -void TIM2_IRQHandler(void) { - if (api_hal_tim_tim2_isr) { - api_hal_tim_tim2_isr(); - } else { - HAL_TIM_IRQHandler(&htim2); - } +#define API_HAL_INTERRUPT_DMA_COUNT 2 +#define API_HAL_INTERRUPT_DMA_CHANNELS_COUNT 8 + +volatile ApiHalInterruptISR api_hal_dma_channel_isr[API_HAL_INTERRUPT_DMA_COUNT][API_HAL_INTERRUPT_DMA_CHANNELS_COUNT] = {0}; + +void api_hal_interrupt_init() { + NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_EnableIRQ(DMA1_Channel1_IRQn); } -void api_hal_interrupt_set_timer_isr(TIM_TypeDef *timer, ApiHalInterruptISR isr) { +void api_hal_interrupt_set_timer_isr(TIM_TypeDef* timer, ApiHalInterruptISR isr) { if (timer == TIM2) { if (isr) { furi_assert(api_hal_tim_tim2_isr == NULL); @@ -27,6 +29,19 @@ void api_hal_interrupt_set_timer_isr(TIM_TypeDef *timer, ApiHalInterruptISR isr) } } +void api_hal_interrupt_set_dma_channel_isr(DMA_TypeDef* dma, uint32_t channel, ApiHalInterruptISR isr) { + --channel; // Pascal + furi_check(dma); + furi_check(channel < API_HAL_INTERRUPT_DMA_CHANNELS_COUNT); + if (dma == DMA1) { + api_hal_dma_channel_isr[0][channel] = isr; + } else if (dma == DMA1) { + api_hal_dma_channel_isr[1][channel] = isr; + } else { + furi_check(0); + } +} + extern void api_interrupt_call(InterruptType type, void* hw); /* ST HAL symbols */ @@ -40,3 +55,78 @@ void HAL_COMP_TriggerCallback(COMP_HandleTypeDef* hcomp) { void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) { api_interrupt_call(InterruptTypeTimerUpdate, htim); } + +/* Timer 2 */ +void TIM2_IRQHandler(void) { + if (api_hal_tim_tim2_isr) { + api_hal_tim_tim2_isr(); + } else { + HAL_TIM_IRQHandler(&htim2); + } +} + +/* DMA 1 */ +void DMA1_Channel1_IRQHandler(void) { + if (api_hal_dma_channel_isr[0][0]) api_hal_dma_channel_isr[0][0](); +} + +void DMA1_Channel2_IRQHandler(void) { + if (api_hal_dma_channel_isr[0][1]) api_hal_dma_channel_isr[0][1](); +} + +void DMA1_Channel3_IRQHandler(void) { + if (api_hal_dma_channel_isr[0][2]) api_hal_dma_channel_isr[0][2](); +} + +void DMA1_Channel4_IRQHandler(void) { + if (api_hal_dma_channel_isr[0][3]) api_hal_dma_channel_isr[0][3](); +} + +void DMA1_Channel5_IRQHandler(void) { + if (api_hal_dma_channel_isr[0][4]) api_hal_dma_channel_isr[0][4](); +} + +void DMA1_Channel6_IRQHandler(void) { + if (api_hal_dma_channel_isr[0][5]) api_hal_dma_channel_isr[0][5](); +} + +void DMA1_Channel7_IRQHandler(void) { + if (api_hal_dma_channel_isr[0][6]) api_hal_dma_channel_isr[0][6](); +} + +void DMA1_Channel8_IRQHandler(void) { + if (api_hal_dma_channel_isr[0][7]) api_hal_dma_channel_isr[0][7](); +} + +/* DMA 2 */ +void DMA2_Channel1_IRQHandler(void) { + if (api_hal_dma_channel_isr[1][0]) api_hal_dma_channel_isr[1][0](); +} + +void DMA2_Channel2_IRQHandler(void) { + if (api_hal_dma_channel_isr[1][1]) api_hal_dma_channel_isr[1][1](); +} + +void DMA2_Channel3_IRQHandler(void) { + if (api_hal_dma_channel_isr[1][2]) api_hal_dma_channel_isr[1][2](); +} + +void DMA2_Channel4_IRQHandler(void) { + if (api_hal_dma_channel_isr[1][3]) api_hal_dma_channel_isr[1][3](); +} + +void DMA2_Channel5_IRQHandler(void) { + if (api_hal_dma_channel_isr[1][4]) api_hal_dma_channel_isr[1][4](); +} + +void DMA2_Channel6_IRQHandler(void) { + if (api_hal_dma_channel_isr[1][5]) api_hal_dma_channel_isr[1][5](); +} + +void DMA2_Channel7_IRQHandler(void) { + if (api_hal_dma_channel_isr[1][6]) api_hal_dma_channel_isr[1][6](); +} + +void DMA2_Channel8_IRQHandler(void) { + if (api_hal_dma_channel_isr[1][7]) api_hal_dma_channel_isr[1][7](); +} diff --git a/firmware/targets/f6/api-hal/api-hal-interrupt.h b/firmware/targets/f6/api-hal/api-hal-interrupt.h index 5efb2ba3..eeb0afe9 100644 --- a/firmware/targets/f6/api-hal/api-hal-interrupt.h +++ b/firmware/targets/f6/api-hal/api-hal-interrupt.h @@ -9,11 +9,22 @@ extern "C" { /** Timer ISR */ typedef void (*ApiHalInterruptISR)(); +/** Initialize interrupt subsystem */ +void api_hal_interrupt_init(); + +/** Set DMA Channel ISR + * We don't clear interrupt flags for you, do it by your self. + * @param dma - DMA instance + * @param channel - DMA channel + * @param isr - your interrupt service routine or use NULL to clear + */ +void api_hal_interrupt_set_dma_channel_isr(DMA_TypeDef* dma, uint32_t channel, ApiHalInterruptISR isr); + /** Set Timer ISR * By default ISR is serviced by ST HAL. Use this function to override it. * We don't clear interrupt flags for you, do it by your self. - * @timer - timer instance - * @isr - your interrupt service routine or use NULL to clear + * @param timer - timer instance + * @param isr - your interrupt service routine or use NULL to clear */ void api_hal_interrupt_set_timer_isr(TIM_TypeDef *timer, ApiHalInterruptISR isr); diff --git a/firmware/targets/f6/api-hal/api-hal-subghz.c b/firmware/targets/f6/api-hal/api-hal-subghz.c index eb9d4eab..3e38c795 100644 --- a/firmware/targets/f6/api-hal/api-hal-subghz.c +++ b/firmware/targets/f6/api-hal/api-hal-subghz.c @@ -9,6 +9,8 @@ #include #include +static volatile SubGhzState api_hal_subghz_state = SubGhzStateInit; + static const uint8_t api_hal_subghz_preset_ook_async_regs[][2] = { /* Base setting */ { CC1101_IOCFG0, 0x0D }, // GD0 as async serial data output/input @@ -24,7 +26,7 @@ static const uint8_t api_hal_subghz_preset_ook_async_regs[][2] = { }; static const uint8_t api_hal_subghz_preset_ook_async_patable[8] = { - 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const uint8_t api_hal_subghz_preset_mp_regs[][2] = { @@ -63,7 +65,7 @@ static const uint8_t api_hal_subghz_preset_mp_regs[][2] = { }; static const uint8_t api_hal_subghz_preset_mp_patable[8] = { - 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const uint8_t api_hal_subghz_preset_2fsk_packet_regs[][2] = { @@ -85,9 +87,19 @@ static const uint8_t api_hal_subghz_preset_2fsk_packet_patable[8] = { }; void api_hal_subghz_init() { + furi_assert(api_hal_subghz_state == SubGhzStateInit); + api_hal_subghz_state = SubGhzStateIdle; + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); - // Reset and shutdown + +#ifdef API_HAL_SUBGHZ_TX_GPIO + hal_gpio_init(&API_HAL_SUBGHZ_TX_GPIO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); +#endif + + // Reset + hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); cc1101_reset(device); + cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); // Prepare GD0 for power on self test hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); @@ -108,8 +120,23 @@ void api_hal_subghz_init() { hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); - // Turn off oscillator + // Go to sleep cc1101_shutdown(device); + + api_hal_spi_device_return(device); +} + +void api_hal_subghz_sleep() { + furi_assert(api_hal_subghz_state == SubGhzStateIdle); + const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + + cc1101_switch_to_idle(device); + + cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + cc1101_shutdown(device); + api_hal_spi_device_return(device); } @@ -189,7 +216,10 @@ void api_hal_subghz_shutdown() { void api_hal_subghz_reset() { const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); + hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + cc1101_switch_to_idle(device); cc1101_reset(device); + cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); api_hal_spi_device_return(device); } @@ -207,7 +237,6 @@ void api_hal_subghz_rx() { void api_hal_subghz_tx() { const ApiHalSpiDevice* device = api_hal_spi_device_get(ApiHalSpiDeviceIdSubGhz); - cc1101_switch_to_idle(device); cc1101_switch_to_tx(device); api_hal_spi_device_return(device); } @@ -281,11 +310,6 @@ volatile uint32_t api_hal_subghz_capture_delta_duration = 0; volatile ApiHalSubGhzCaptureCallback api_hal_subghz_capture_callback = NULL; volatile void* api_hal_subghz_capture_callback_context = NULL; -void api_hal_subghz_set_capture_callback(ApiHalSubGhzCaptureCallback callback, void* context) { - api_hal_subghz_capture_callback = callback; - api_hal_subghz_capture_callback_context = context; -} - static void api_hal_subghz_capture_ISR() { // Channel 1 if(LL_TIM_IsActiveFlag_CC1(TIM2)) { @@ -308,10 +332,14 @@ static void api_hal_subghz_capture_ISR() { } } -void api_hal_subghz_enable_capture() { - /* Peripheral clock enable */ - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); +void api_hal_subghz_set_async_rx_callback(ApiHalSubGhzCaptureCallback callback, void* context) { + api_hal_subghz_capture_callback = callback; + api_hal_subghz_capture_callback_context = context; +} + +void api_hal_subghz_start_async_rx() { + furi_assert(api_hal_subghz_state == SubGhzStateIdle); + api_hal_subghz_state = SubGhzStateAsyncRx; hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); @@ -323,24 +351,27 @@ void api_hal_subghz_enable_capture() { TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; LL_TIM_Init(TIM2, &TIM_InitStruct); - // Timer: advanced and channel + // Timer: advanced LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); LL_TIM_DisableARRPreload(TIM2); LL_TIM_SetTriggerInput(TIM2, LL_TIM_TS_TI2FP2); LL_TIM_SetSlaveMode(TIM2, LL_TIM_SLAVEMODE_RESET); - LL_TIM_CC_DisableChannel(TIM2, LL_TIM_CHANNEL_CH2); - LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); - LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING); - LL_TIM_DisableIT_TRIG(TIM2); - LL_TIM_DisableDMAReq_TRIG(TIM2); LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET); LL_TIM_EnableMasterSlaveMode(TIM2); + LL_TIM_DisableDMAReq_TRIG(TIM2); + LL_TIM_DisableIT_TRIG(TIM2); + + // Timer: channel 1 indirect LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_INDIRECTTI); LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1); - LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1); LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_FALLING); + LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1); + + // Timer: channel 2 direct LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI); LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); + LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING); + LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); // ISR setup api_hal_interrupt_set_timer_isr(TIM2, api_hal_subghz_capture_ISR); @@ -356,10 +387,132 @@ void api_hal_subghz_enable_capture() { // Start timer LL_TIM_SetCounter(TIM2, 0); LL_TIM_EnableCounter(TIM2); + + // Switch to RX + api_hal_subghz_rx(); } -void api_hal_subghz_disable_capture() { +void api_hal_subghz_stop_async_rx() { + furi_assert(api_hal_subghz_state == SubGhzStateAsyncRx); + api_hal_subghz_state = SubGhzStateIdle; + + // Shutdown radio + api_hal_subghz_idle(); + LL_TIM_DeInit(TIM2); api_hal_interrupt_set_timer_isr(TIM2, NULL); + + hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); +} + +volatile size_t api_hal_subghz_tx_repeat = 0; + +static void api_hal_subghz_tx_dma_isr() { + if (LL_DMA_IsActiveFlag_TC1(DMA1)) { + LL_DMA_ClearFlag_TC1(DMA1); + furi_assert(api_hal_subghz_state == SubGhzStateAsyncTx); + if (--api_hal_subghz_tx_repeat == 0) { + api_hal_subghz_state = SubGhzStateAsyncTxLast; + LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1); + } + } +} + +static void api_hal_subghz_tx_timer_isr() { + if(LL_TIM_IsActiveFlag_UPDATE(TIM2)) { + LL_TIM_ClearFlag_UPDATE(TIM2); + if (api_hal_subghz_state == SubGhzStateAsyncTxLast) { + LL_TIM_DisableCounter(TIM2); + api_hal_subghz_state = SubGhzStateAsyncTxEnd; + } + } +} + +void api_hal_subghz_start_async_tx(uint32_t* buffer, size_t buffer_size, size_t repeat) { + furi_assert(api_hal_subghz_state == SubGhzStateIdle); + api_hal_subghz_state = SubGhzStateAsyncTx; + api_hal_subghz_tx_repeat = repeat; + + // Connect CC1101_GD0 to TIM2 as output + hal_gpio_init_ex(&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); + + // Configure DMA + LL_DMA_InitTypeDef dma_config = {0}; + dma_config.PeriphOrM2MSrcAddress = (uint32_t)&(TIM2->ARR); + dma_config.MemoryOrM2MDstAddress = (uint32_t)buffer; + dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; + dma_config.Mode = LL_DMA_MODE_CIRCULAR; + dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; + dma_config.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; + dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; + dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; + dma_config.NbData = buffer_size / sizeof(uint32_t); + dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; + dma_config.Priority = LL_DMA_MODE_NORMAL; + LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); + api_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, api_hal_subghz_tx_dma_isr); + LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); + + // Configure TIM2 + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + TIM_InitStruct.Prescaler = 64-1; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 1000; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(TIM2, &TIM_InitStruct); + LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_EnableARRPreload(TIM2); + + // Configure TIM2 CH2 + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_TOGGLE; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 0; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + LL_TIM_OC_Init(TIM2, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH2); + LL_TIM_DisableMasterSlaveMode(TIM2); + + api_hal_interrupt_set_timer_isr(TIM2, api_hal_subghz_tx_timer_isr); + LL_TIM_EnableIT_UPDATE(TIM2); + LL_TIM_EnableDMAReq_UPDATE(TIM2); + LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2); + + // Start counter + LL_TIM_GenerateEvent_UPDATE(TIM2); +#ifdef API_HAL_SUBGHZ_TX_GPIO + hal_gpio_write(&API_HAL_SUBGHZ_TX_GPIO, true); +#endif + api_hal_subghz_tx(); + + LL_TIM_SetCounter(TIM2, 0); + LL_TIM_EnableCounter(TIM2); +} + +void api_hal_subghz_wait_async_tx() { + while(api_hal_subghz_state != SubGhzStateAsyncTxEnd) osDelay(1); +} + +void api_hal_subghz_stop_async_tx() { + furi_assert(api_hal_subghz_state == SubGhzStateAsyncTxEnd); + api_hal_subghz_state = SubGhzStateIdle; + + // Shutdown radio + api_hal_subghz_idle(); +#ifdef API_HAL_SUBGHZ_TX_GPIO + hal_gpio_write(&API_HAL_SUBGHZ_TX_GPIO, false); +#endif + + // Deinitialize Timer + LL_TIM_DeInit(TIM2); + api_hal_interrupt_set_timer_isr(TIM2, NULL); + + // Deinitialize DMA + LL_DMA_DeInit(DMA1, LL_DMA_CHANNEL_1); + api_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, NULL); + + // Deinitialize GPIO hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } diff --git a/firmware/targets/f6/api-hal/api-hal.c b/firmware/targets/f6/api-hal/api-hal.c index c56ad62b..05e47bed 100644 --- a/firmware/targets/f6/api-hal/api-hal.c +++ b/firmware/targets/f6/api-hal/api-hal.c @@ -3,6 +3,10 @@ void api_hal_init() { api_hal_boot_init(); FURI_LOG_I("FURI_HAL", "BOOT OK"); + api_hal_interrupt_init(); + FURI_LOG_I("FURI_HAL", "INTERRUPT OK"); + api_hal_clock_init(); + FURI_LOG_I("FURI_HAL", "CLOCK OK"); api_hal_version_init(); FURI_LOG_I("FURI_HAL", "VERSION OK"); api_hal_delay_init(); diff --git a/firmware/targets/f6/target.mk b/firmware/targets/f6/target.mk index 737ddb8d..fca7981a 100644 --- a/firmware/targets/f6/target.mk +++ b/firmware/targets/f6/target.mk @@ -19,6 +19,11 @@ ifeq ($(API_HAL_OS_DEBUG), 1) CFLAGS += -DAPI_HAL_OS_DEBUG endif +API_HAL_SUBGHZ_TX_GPIO ?= 0 +ifneq ($(API_HAL_SUBGHZ_TX_GPIO), 0) +CFLAGS += -DAPI_HAL_SUBGHZ_TX_GPIO=$(API_HAL_SUBGHZ_TX_GPIO) +endif + ifeq ($(INVERT_RFID_IN), 1) CFLAGS += -DINVERT_RFID_IN endif @@ -46,8 +51,6 @@ C_SOURCES += \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_crc.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_crc_ex.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_dma.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_dma_ex.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_exti.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash_ex.c \ @@ -72,6 +75,7 @@ C_SOURCES += \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_uart_ex.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_lptim.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_adc.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_dma.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_gpio.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_i2c.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_rcc.c \ diff --git a/lib/drivers/cc1101.c b/lib/drivers/cc1101.c index 5acde04d..2df0cc3d 100644 --- a/lib/drivers/cc1101.c +++ b/lib/drivers/cc1101.c @@ -145,7 +145,7 @@ void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[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); + api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, sizeof(rx), CC1101_TIMEOUT); hal_gpio_write(device->chip_select, true); assert((rx[0].CHIP_RDYn|rx[8].CHIP_RDYn) == 0);