Merge branch 'fz-dev' into dev

This commit is contained in:
MX
2022-12-17 07:25:49 +03:00
15 changed files with 365 additions and 149 deletions

View File

@@ -1,23 +1,66 @@
#include <furi_hal_speaker.h>
#include <furi_hal_gpio.h>
#include <furi_hal_resources.h>
#include <furi_hal_power.h>
#include <stm32wbxx_ll_tim.h>
#include <furi_hal_cortex.h>
#define TAG "FuriHalSpeaker"
#define FURI_HAL_SPEAKER_TIMER TIM16
#define FURI_HAL_SPEAKER_CHANNEL LL_TIM_CHANNEL_CH1
#define FURI_HAL_SPEAKER_PRESCALER 500
#define FURI_HAL_SPEAKER_MAX_VOLUME 60
static FuriMutex* furi_hal_speaker_mutex = NULL;
// #define FURI_HAL_SPEAKER_NEW_VOLUME
void furi_hal_speaker_init() {
furi_assert(furi_hal_speaker_mutex == NULL);
furi_hal_speaker_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
FURI_CRITICAL_ENTER();
LL_TIM_DeInit(FURI_HAL_SPEAKER_TIMER);
FURI_CRITICAL_EXIT();
FURI_LOG_I(TAG, "Init OK");
}
furi_hal_gpio_init_ex(
&gpio_speaker, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn14TIM16);
void furi_hal_speaker_deinit() {
furi_check(furi_hal_speaker_mutex != NULL);
LL_TIM_DeInit(FURI_HAL_SPEAKER_TIMER);
furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_mutex_free(furi_hal_speaker_mutex);
furi_hal_speaker_mutex = NULL;
}
bool furi_hal_speaker_acquire(uint32_t timeout) {
furi_check(!FURI_IS_IRQ_MODE());
if(furi_mutex_acquire(furi_hal_speaker_mutex, timeout) == FuriStatusOk) {
furi_hal_power_insomnia_enter();
furi_hal_gpio_init_ex(
&gpio_speaker, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn14TIM16);
return true;
} else {
return false;
}
}
void furi_hal_speaker_release() {
furi_check(!FURI_IS_IRQ_MODE());
furi_check(furi_hal_speaker_is_mine());
furi_hal_speaker_stop();
furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_power_insomnia_exit();
furi_check(furi_mutex_release(furi_hal_speaker_mutex) == FuriStatusOk);
}
bool furi_hal_speaker_is_mine() {
return (FURI_IS_IRQ_MODE()) ||
(furi_mutex_get_owner(furi_hal_speaker_mutex) == furi_thread_get_current_id());
}
static inline uint32_t furi_hal_speaker_calculate_autoreload(float frequency) {
@@ -54,6 +97,8 @@ static inline uint32_t furi_hal_speaker_calculate_compare(float volume) {
}
void furi_hal_speaker_start(float frequency, float volume) {
furi_check(furi_hal_speaker_is_mine());
if(volume <= 0) {
furi_hal_speaker_stop();
return;
@@ -75,6 +120,7 @@ void furi_hal_speaker_start(float frequency, float volume) {
}
void furi_hal_speaker_set_volume(float volume) {
furi_check(furi_hal_speaker_is_mine());
if(volume <= 0) {
furi_hal_speaker_stop();
return;
@@ -88,6 +134,7 @@ void furi_hal_speaker_set_volume(float volume) {
}
void furi_hal_speaker_stop() {
furi_check(furi_hal_speaker_is_mine());
LL_TIM_DisableAllOutputs(FURI_HAL_SPEAKER_TIMER);
LL_TIM_DisableCounter(FURI_HAL_SPEAKER_TIMER);
}

View File

@@ -3,7 +3,6 @@
#include <furi_hal_version.h>
#include <furi_hal_rtc.h>
#include <furi_hal_gpio.h>
#include <furi_hal_spi.h>
#include <furi_hal_interrupt.h>
#include <furi_hal_resources.h>
@@ -18,39 +17,26 @@
#define TAG "FuriHalSubGhz"
/*
* Uncomment define to enable duplication of
* IO GO0 CC1101 to an external comb.
* Debug pin can be assigned
* gpio_ext_pc0
* gpio_ext_pc1
* gpio_ext_pc3
* gpio_ext_pb2
* gpio_ext_pb3
* gpio_ext_pa4
* gpio_ext_pa6
* gpio_ext_pa7
* Attention this setting switches pin to output.
* Make sure it is not connected directly to power or ground
*/
//#define SUBGHZ_DEBUG_CC1101_PIN gpio_ext_pa7
#ifdef SUBGHZ_DEBUG_CC1101_PIN
uint32_t subghz_debug_gpio_buff[2];
#endif
static uint32_t furi_hal_subghz_debug_gpio_buff[2];
typedef struct {
volatile SubGhzState state;
volatile SubGhzRegulation regulation;
volatile FuriHalSubGhzPreset preset;
const GpioPin* async_mirror_pin;
} FuriHalSubGhz;
volatile FuriHalSubGhz furi_hal_subghz = {
.state = SubGhzStateInit,
.regulation = SubGhzRegulationTxRx,
.preset = FuriHalSubGhzPresetIDLE,
.async_mirror_pin = NULL,
};
void furi_hal_subghz_set_async_mirror_pin(const GpioPin* pin) {
furi_hal_subghz.async_mirror_pin = pin;
}
void furi_hal_subghz_init() {
furi_assert(furi_hal_subghz.state == SubGhzStateInit);
furi_hal_subghz.state = SubGhzStateIdle;
@@ -406,6 +392,29 @@ void furi_hal_subghz_set_path(FuriHalSubGhzPath path) {
furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
}
static bool furi_hal_subghz_start_debug() {
bool ret = false;
if(furi_hal_subghz.async_mirror_pin != NULL) {
furi_hal_gpio_init(
furi_hal_subghz.async_mirror_pin,
GpioModeOutputPushPull,
GpioPullNo,
GpioSpeedVeryHigh);
ret = true;
}
return ret;
}
static bool furi_hal_subghz_stop_debug() {
bool ret = false;
if(furi_hal_subghz.async_mirror_pin != NULL) {
furi_hal_gpio_init(
furi_hal_subghz.async_mirror_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
ret = true;
}
return ret;
}
volatile uint32_t furi_hal_subghz_capture_delta_duration = 0;
volatile FuriHalSubGhzCaptureCallback furi_hal_subghz_capture_callback = NULL;
volatile void* furi_hal_subghz_capture_callback_context = NULL;
@@ -416,9 +425,9 @@ static void furi_hal_subghz_capture_ISR() {
LL_TIM_ClearFlag_CC1(TIM2);
furi_hal_subghz_capture_delta_duration = LL_TIM_IC_GetCaptureCH1(TIM2);
if(furi_hal_subghz_capture_callback) {
#ifdef SUBGHZ_DEBUG_CC1101_PIN
furi_hal_gpio_write(&SUBGHZ_DEBUG_CC1101_PIN, false);
#endif
if(furi_hal_subghz.async_mirror_pin != NULL)
furi_hal_gpio_write(furi_hal_subghz.async_mirror_pin, false);
furi_hal_subghz_capture_callback(
true,
furi_hal_subghz_capture_delta_duration,
@@ -429,9 +438,9 @@ static void furi_hal_subghz_capture_ISR() {
if(LL_TIM_IsActiveFlag_CC2(TIM2)) {
LL_TIM_ClearFlag_CC2(TIM2);
if(furi_hal_subghz_capture_callback) {
#ifdef SUBGHZ_DEBUG_CC1101_PIN
furi_hal_gpio_write(&SUBGHZ_DEBUG_CC1101_PIN, true);
#endif
if(furi_hal_subghz.async_mirror_pin != NULL)
furi_hal_gpio_write(furi_hal_subghz.async_mirror_pin, true);
furi_hal_subghz_capture_callback(
false,
LL_TIM_IC_GetCaptureCH2(TIM2) - furi_hal_subghz_capture_delta_duration,
@@ -493,10 +502,8 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void*
LL_TIM_SetCounter(TIM2, 0);
LL_TIM_EnableCounter(TIM2);
#ifdef SUBGHZ_DEBUG_CC1101_PIN
furi_hal_gpio_init(
&SUBGHZ_DEBUG_CC1101_PIN, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
#endif
// Start debug
furi_hal_subghz_start_debug();
// Switch to RX
furi_hal_subghz_rx();
@@ -512,9 +519,8 @@ void furi_hal_subghz_stop_async_rx() {
FURI_CRITICAL_ENTER();
LL_TIM_DeInit(TIM2);
#ifdef SUBGHZ_DEBUG_CC1101_PIN
furi_hal_gpio_init(&SUBGHZ_DEBUG_CC1101_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
#endif
// Stop debug
furi_hal_subghz_stop_debug();
FURI_CRITICAL_EXIT();
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL);
@@ -707,30 +713,27 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
LL_TIM_SetCounter(TIM2, 0);
LL_TIM_EnableCounter(TIM2);
#ifdef SUBGHZ_DEBUG_CC1101_PIN
furi_hal_gpio_init(
&SUBGHZ_DEBUG_CC1101_PIN, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
// Start debug
if(furi_hal_subghz_start_debug()) {
const GpioPin* gpio = furi_hal_subghz.async_mirror_pin;
furi_hal_subghz_debug_gpio_buff[0] = (uint32_t)gpio->pin << GPIO_NUMBER;
furi_hal_subghz_debug_gpio_buff[1] = gpio->pin;
const GpioPin* gpio = &SUBGHZ_DEBUG_CC1101_PIN;
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);
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 = 2;
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP;
dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH;
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, 2);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
#endif
dma_config.MemoryOrM2MDstAddress = (uint32_t)furi_hal_subghz_debug_gpio_buff;
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (gpio->port->BSRR);
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 = 2;
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP;
dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH;
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, 2);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
}
return true;
}
@@ -764,10 +767,10 @@ void furi_hal_subghz_stop_async_tx() {
// Deinitialize GPIO
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
#ifdef SUBGHZ_DEBUG_CC1101_PIN
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
furi_hal_gpio_init(&SUBGHZ_DEBUG_CC1101_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
#endif
// Stop debug
if(furi_hal_subghz_stop_debug()) {
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
}
FURI_CRITICAL_EXIT();