Skip to content

Commit

Permalink
SubGhz: add subghz tx_from_file CLI cmd, major TX flow refactoring,…
Browse files Browse the repository at this point in the history
… various improvements and bug fixes (flipperdevices#3302)

By Skorpionm
* SubGhz: add cmd CLI "subghz tx_from_file"
* SubGhz:  add sending raw.sub files
* SubGhz: add load custom preset
* SubGhz: remove unnecessary files
* SubGhz: change message
* SubGhz: fix printf formatting
* SubGhz: Cli refactoring code
* FuriHal: add furi_hal_subghz Tx Rx IDLE state switching test
* SubGhz: remove debug code, fix ext driver compilation
* SubGhz: cleanup code, move wait status routine to cc1101 driver
* SubGhz: proper pin mode transition in tx stop isr routine, proper DMA and ISR priorities, fix issue with async tx stuck
* SubGhz: simplify async tx stop flow, fix ISR ARR check condition race
* SubGhz: check ARR only when we transmitting
* SubGhz: check ARR only when we transmitting for ext cc1101
* SubGhz: lower ISR priorities to safe level
* SubGhz: proper gpio config, comments update

Co-authored-by: あく <alleteam@gmail.com>
  • Loading branch information
xMasterX and skotopes committed Jan 19, 2024
1 parent 1fd4839 commit 36114de
Show file tree
Hide file tree
Showing 8 changed files with 362 additions and 109 deletions.
49 changes: 18 additions & 31 deletions applications/drivers/subghz/cc1101_ext/cc1101_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ typedef enum {
SubGhzDeviceCC1101ExtStateIdle, /**< Idle, energy save mode */
SubGhzDeviceCC1101ExtStateAsyncRx, /**< Async RX started */
SubGhzDeviceCC1101ExtStateAsyncTx, /**< Async TX started, DMA and timer is on */
SubGhzDeviceCC1101ExtStateAsyncTxEnd, /**< Async TX complete, cleanup needed */
} SubGhzDeviceCC1101ExtState;

/** SubGhz regulation, receive transmission on the current frequency for the
Expand Down Expand Up @@ -417,6 +416,9 @@ void subghz_device_cc1101_ext_reset() {
void subghz_device_cc1101_ext_idle() {
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
cc1101_switch_to_idle(subghz_device_cc1101_ext->spi_bus_handle);
//waiting for the chip to switch to IDLE mode
furi_check(cc1101_wait_status_state(
subghz_device_cc1101_ext->spi_bus_handle, CC1101StateIDLE, 10000));
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
if(subghz_device_cc1101_ext->power_amp) {
furi_hal_gpio_write(SUBGHZ_DEVICE_CC1101_EXT_E07_AMP_GPIO, 0);
Expand All @@ -426,6 +428,9 @@ void subghz_device_cc1101_ext_idle() {
void subghz_device_cc1101_ext_rx() {
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
cc1101_switch_to_rx(subghz_device_cc1101_ext->spi_bus_handle);
//waiting for the chip to switch to Rx mode
furi_check(
cc1101_wait_status_state(subghz_device_cc1101_ext->spi_bus_handle, CC1101StateRX, 10000));
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
if(subghz_device_cc1101_ext->power_amp) {
furi_hal_gpio_write(SUBGHZ_DEVICE_CC1101_EXT_E07_AMP_GPIO, 0);
Expand All @@ -436,6 +441,9 @@ bool subghz_device_cc1101_ext_tx() {
if(subghz_device_cc1101_ext->regulation != SubGhzDeviceCC1101ExtRegulationTxRx) return false;
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
cc1101_switch_to_tx(subghz_device_cc1101_ext->spi_bus_handle);
//waiting for the chip to switch to Tx mode
furi_check(
cc1101_wait_status_state(subghz_device_cc1101_ext->spi_bus_handle, CC1101StateTX, 10000));
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
if(subghz_device_cc1101_ext->power_amp) {
furi_hal_gpio_write(SUBGHZ_DEVICE_CC1101_EXT_E07_AMP_GPIO, 1);
Expand Down Expand Up @@ -706,7 +714,6 @@ static void subghz_device_cc1101_ext_async_tx_refill(uint32_t* buffer, size_t sa
if(LL_DMA_IsActiveFlag_TC3(SUBGHZ_DEVICE_CC1101_EXT_DMA)) {
LL_DMA_ClearFlag_TC3(SUBGHZ_DEVICE_CC1101_EXT_DMA);
}
LL_TIM_EnableIT_UPDATE(TIM17);
break;
} else {
// Lowest possible value is 4us
Expand Down Expand Up @@ -742,22 +749,6 @@ static void subghz_device_cc1101_ext_async_tx_dma_isr() {
#endif
}

static void subghz_device_cc1101_ext_async_tx_timer_isr() {
if(LL_TIM_IsActiveFlag_UPDATE(TIM17)) {
if(LL_TIM_GetAutoReload(TIM17) == 0) {
if(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTx) {
LL_DMA_DisableChannel(SUBGHZ_DEVICE_CC1101_EXT_DMA_CH3_DEF);
subghz_device_cc1101_ext->state = SubGhzDeviceCC1101ExtStateAsyncTxEnd;
furi_hal_gpio_write(subghz_device_cc1101_ext->g0_pin, false);
if(subghz_device_cc1101_ext->async_mirror_pin != NULL)
furi_hal_gpio_write(subghz_device_cc1101_ext->async_mirror_pin, false);
LL_TIM_DisableCounter(TIM17);
}
}
LL_TIM_ClearFlag_UPDATE(TIM17);
}
}

bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callback, void* context) {
furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateIdle);
furi_assert(callback);
Expand Down Expand Up @@ -786,7 +777,7 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb
SUBGHZ_DEVICE_CC1101_EXT_DMA_CH3_DEF,
LL_DMA_DIRECTION_MEMORY_TO_PERIPH | LL_DMA_MODE_CIRCULAR | LL_DMA_PERIPH_NOINCREMENT |
LL_DMA_MEMORY_INCREMENT | LL_DMA_PDATAALIGN_WORD | LL_DMA_MDATAALIGN_WORD |
LL_DMA_MODE_NORMAL);
LL_DMA_PRIORITY_VERYHIGH);
LL_DMA_SetDataLength(
SUBGHZ_DEVICE_CC1101_EXT_DMA_CH3_DEF, SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_FULL);
LL_DMA_SetPeriphRequest(SUBGHZ_DEVICE_CC1101_EXT_DMA_CH3_DEF, LL_DMAMUX_REQ_TIM17_UP);
Expand All @@ -809,9 +800,6 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb
LL_TIM_SetClockSource(TIM17, LL_TIM_CLOCKSOURCE_INTERNAL);
LL_TIM_DisableARRPreload(TIM17);

furi_hal_interrupt_set_isr(
FuriHalInterruptIdTim1TrgComTim17, subghz_device_cc1101_ext_async_tx_timer_isr, NULL);

subghz_device_cc1101_ext_async_tx_middleware_idle(
&subghz_device_cc1101_ext->async_tx.middleware);
subghz_device_cc1101_ext_async_tx_refill(
Expand Down Expand Up @@ -869,22 +857,21 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb
}

bool subghz_device_cc1101_ext_is_async_tx_complete() {
return subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTxEnd;
return (
(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTx) &&
(LL_TIM_GetAutoReload(TIM17) == 0));
}

void subghz_device_cc1101_ext_stop_async_tx() {
furi_assert(
subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTx ||
subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTxEnd);

// Deinitialize GPIO
furi_hal_gpio_write(subghz_device_cc1101_ext->g0_pin, false);
furi_hal_gpio_init(
subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTx);

// Shutdown radio
subghz_device_cc1101_ext_idle();

// Deinitialize GPIO
furi_hal_gpio_write(subghz_device_cc1101_ext->g0_pin, false);
furi_hal_gpio_init(subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);

// Deinitialize Timer
furi_hal_bus_disable(FuriHalBusTIM17);
furi_hal_interrupt_set_isr(FuriHalInterruptIdTim1TrgComTim17, NULL, NULL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ static void nfc_scene_read_menu_on_enter_mf_classic(NfcApp* instance) {
}
}

static void nfc_scene_read_success_on_enter_mf_classic(NfcApp* instance) {
static void nfc_scene_read_success_on_enter_mf_classic(NfcApp* instance) { //-V524
const NfcDevice* device = instance->nfc_device;
const MfClassicData* data = nfc_device_get_data(device, NfcProtocolMfClassic);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
uint32_t frequency = 0;
float rssi_temp = 0;
uint32_t frequency_temp = 0;
CC1101Status status;

FuriHalSpiBusHandle* spi_bus = instance->spi_bus;
const SubGhzDevice* radio_device = instance->radio_device;
Expand Down Expand Up @@ -143,9 +142,8 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
frequency = cc1101_set_frequency(spi_bus, current_frequency);

cc1101_calibrate(spi_bus);
do {
status = cc1101_get_status(spi_bus);
} while(status.STATE != CC1101StateIDLE);

furi_check(cc1101_wait_status_state(spi_bus, CC1101StateIDLE, 10000));

cc1101_switch_to_rx(spi_bus);
furi_hal_spi_release(spi_bus);
Expand Down Expand Up @@ -191,9 +189,8 @@ static int32_t subghz_frequency_analyzer_worker_thread(void* context) {
frequency = cc1101_set_frequency(spi_bus, i);

cc1101_calibrate(spi_bus);
do {
status = cc1101_get_status(spi_bus);
} while(status.STATE != CC1101StateIDLE);

furi_check(cc1101_wait_status_state(spi_bus, CC1101StateIDLE, 10000));

cc1101_switch_to_rx(spi_bus);
furi_hal_spi_release(spi_bus);
Expand Down
Loading

0 comments on commit 36114de

Please sign in to comment.