Merge branch 'flipperdevices:dev' into 420

This commit is contained in:
RogueMaster
2022-11-30 14:27:57 -05:00
committed by GitHub
5 changed files with 204 additions and 44 deletions

View File

@@ -564,13 +564,9 @@ void furi_hal_subghz_stop_async_rx() {
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
}
#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL (256)
#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL / 2)
#define API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME 333
typedef struct {
uint32_t* buffer;
bool flip_flop;
LevelDuration carry_ld;
FuriHalSubGhzAsyncTxCallback callback;
void* callback_context;
uint64_t duty_high;
@@ -580,37 +576,48 @@ typedef struct {
static FuriHalSubGhzAsyncTx furi_hal_subghz_async_tx = {0};
static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) {
furi_assert(furi_hal_subghz.state == SubGhzStateAsyncTx);
while(samples > 0) {
bool is_odd = samples % 2;
LevelDuration ld =
furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context);
LevelDuration ld;
if(level_duration_is_reset(furi_hal_subghz_async_tx.carry_ld)) {
ld = furi_hal_subghz_async_tx.callback(furi_hal_subghz_async_tx.callback_context);
} else {
ld = furi_hal_subghz_async_tx.carry_ld;
furi_hal_subghz_async_tx.carry_ld = level_duration_reset();
}
if(level_duration_is_wait(ld)) {
return;
*buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME;
buffer++;
samples--;
} else if(level_duration_is_reset(ld)) {
// One more even sample required to end at low level
if(is_odd) {
*buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME;
buffer++;
samples--;
furi_hal_subghz_async_tx.duty_low += API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME;
}
*buffer = 0;
buffer++;
samples--;
LL_DMA_DisableIT_HT(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_1);
LL_TIM_EnableIT_UPDATE(TIM2);
break;
} else {
// Inject guard time if level is incorrect
bool level = level_duration_get_level(ld);
if(is_odd == level) {
// Inject guard time if level is incorrect
if(is_odd != level) {
*buffer = API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME;
buffer++;
samples--;
if(!level) {
if(is_odd) {
furi_hal_subghz_async_tx.duty_high += API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME;
} else {
furi_hal_subghz_async_tx.duty_low += API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME;
}
// This code must be invoked only once: when encoder starts with low level.
// Otherwise whole thing will crash.
furi_check(samples > 0);
// Special case: prevent buffer overflow if sample is last
if(samples == 0) {
furi_hal_subghz_async_tx.carry_ld = ld;
break;
}
}
uint32_t duration = level_duration_get_duration(ld);
@@ -619,22 +626,17 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) {
buffer++;
samples--;
if(level) {
if(is_odd) {
furi_hal_subghz_async_tx.duty_high += duration;
} else {
furi_hal_subghz_async_tx.duty_low += duration;
}
}
}
memset(buffer, 0, samples * sizeof(uint32_t));
}
static void furi_hal_subghz_async_tx_dma_isr() {
furi_assert(
furi_hal_subghz.state == SubGhzStateAsyncTx ||
furi_hal_subghz.state == SubGhzStateAsyncTxEnd ||
furi_hal_subghz.state == SubGhzStateAsyncTxLast);
furi_assert(furi_hal_subghz.state == SubGhzStateAsyncTx);
if(LL_DMA_IsActiveFlag_HT1(DMA1)) {
LL_DMA_ClearFlag_HT1(DMA1);
furi_hal_subghz_async_tx_refill(
@@ -654,11 +656,14 @@ static void furi_hal_subghz_async_tx_timer_isr() {
if(LL_TIM_GetAutoReload(TIM2) == 0) {
if(furi_hal_subghz.state == SubGhzStateAsyncTx) {
furi_hal_subghz.state = SubGhzStateAsyncTxLast;
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
} else if(furi_hal_subghz.state == SubGhzStateAsyncTxLast) {
furi_hal_subghz.state = SubGhzStateAsyncTxEnd;
//forcibly pulls the pin to the ground so that there is no carrier
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullDown, GpioSpeedLow);
} else {
furi_hal_subghz.state = SubGhzStateAsyncTxEnd;
LL_TIM_DisableCounter(TIM2);
} else {
furi_crash(NULL);
}
}
}
@@ -681,8 +686,6 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
furi_hal_subghz_async_tx.buffer =
malloc(API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL * sizeof(uint32_t));
furi_hal_subghz_async_tx_refill(
furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL);
// Connect CC1101_GD0 to TIM2 as output
furi_hal_gpio_init_ex(
@@ -723,14 +726,16 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
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;
TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_LOW;
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);
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_subghz_async_tx_timer_isr, NULL);
LL_TIM_EnableIT_UPDATE(TIM2);
furi_hal_subghz_async_tx_refill(
furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL);
LL_TIM_EnableDMAReq_UPDATE(TIM2);
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2);
@@ -749,8 +754,8 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
&SUBGHZ_DEBUG_CC1101_PIN, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
const GpioPin* gpio = &SUBGHZ_DEBUG_CC1101_PIN;
subghz_debug_gpio_buff[0] = gpio->pin;
subghz_debug_gpio_buff[1] = (uint32_t)gpio->pin << GPIO_NUMBER;
subghz_debug_gpio_buff[0] = (uint32_t)gpio->pin << GPIO_NUMBER;
subghz_debug_gpio_buff[1] = gpio->pin;
dma_config.MemoryOrM2MDstAddress = (uint32_t)subghz_debug_gpio_buff;
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (gpio->port->BSRR);