LTVA1 2 лет назад
Родитель
Сommit
cdafdd51fe
4 измененных файлов с 109 добавлено и 94 удалено
  1. 2 3
      application.fam
  2. 32 32
      wav_player.c
  3. 73 59
      wav_player_hal.c
  4. 2 0
      wav_player_hal.h

+ 2 - 3
application.fam

@@ -1,11 +1,10 @@
 App(
-    appid="My_WAV_Player",
+    appid="wav_player",
     name="WAV Player",
     apptype=FlipperAppType.EXTERNAL,
     entry_point="wav_player_app",
-    cdefines=["APP_MY_WAV_PLAYER"],
     stack_size=4 * 1024,
-    order=60,
+    order=46,
     fap_icon="wav_10px.png",
     fap_category="Media",
     fap_icon_assets="images",

+ 32 - 32
wav_player.c

@@ -11,9 +11,8 @@
 #include "wav_parser.h"
 #include "wav_player_view.h"
 #include <math.h>
-#include <My_WAV_Player_icons.h>
 
-#include <My_WAV_Player_icons.h>
+#include <wav_player_icons.h>
 
 #define TAG "WavPlayer"
 
@@ -127,10 +126,8 @@ static void app_free(WavPlayerApp* app) {
 }
 
 // TODO: that works only with 8-bit 2ch audio
-static bool fill_data(WavPlayerApp* app, size_t index)
-{
-    if(app->num_channels == 1 && app->bits_per_sample == 8)
-    {
+static bool fill_data(WavPlayerApp* app, size_t index) {
+    if(app->num_channels == 1 && app->bits_per_sample == 8) {
         uint16_t* sample_buffer_start = &app->sample_buffer[index];
         size_t count = stream_read(app->stream, app->tmp_buffer, app->samples_count_half);
 
@@ -169,8 +166,7 @@ static bool fill_data(WavPlayerApp* app, size_t index)
         return count != app->samples_count_half;
     }
 
-    if(app->num_channels == 1 && app->bits_per_sample == 16)
-    {
+    if(app->num_channels == 1 && app->bits_per_sample == 16) {
         uint16_t* sample_buffer_start = &app->sample_buffer[index];
         size_t count = stream_read(app->stream, app->tmp_buffer, app->samples_count);
 
@@ -178,9 +174,9 @@ static bool fill_data(WavPlayerApp* app, size_t index)
             //app->tmp_buffer[i] = 0;
         }
 
-        for(size_t i = 0; i < app->samples_count; i += 2)
-        {
-            int16_t int_16 = (((int16_t)app->tmp_buffer[i + 1] << 8) + (int16_t)app->tmp_buffer[i]);
+        for(size_t i = 0; i < app->samples_count; i += 2) {
+            int16_t int_16 =
+                (((int16_t)app->tmp_buffer[i + 1] << 8) + (int16_t)app->tmp_buffer[i]);
 
             float data = ((float)int_16 / 256.0 + 127.0);
             data -= UINT8_MAX / 2; // to signed
@@ -208,17 +204,15 @@ static bool fill_data(WavPlayerApp* app, size_t index)
         return count != app->samples_count;
     }
 
-    if(app->num_channels == 2 && app->bits_per_sample == 16)
-    {
+    if(app->num_channels == 2 && app->bits_per_sample == 16) {
         uint16_t* sample_buffer_start = &app->sample_buffer[index];
         size_t count = stream_read(app->stream, app->tmp_buffer, app->samples_count);
 
-        for(size_t i = 0; i < app->samples_count; i += 4)
-        {
+        for(size_t i = 0; i < app->samples_count; i += 4) {
             int16_t L = (((int16_t)app->tmp_buffer[i + 1] << 8) + (int16_t)app->tmp_buffer[i]);
             int16_t R = (((int16_t)app->tmp_buffer[i + 3] << 8) + (int16_t)app->tmp_buffer[i + 2]);
             int32_t int_16 = L / 2 + R / 2; // (L + R) / 2
-            
+
             float data = ((float)int_16 / 256.0 + 127.0);
             data -= UINT8_MAX / 2; // to signed
             data /= UINT8_MAX / 2; // scale -1..1
@@ -242,12 +236,11 @@ static bool fill_data(WavPlayerApp* app, size_t index)
 
         count = stream_read(app->stream, app->tmp_buffer, app->samples_count);
 
-        for(size_t i = 0; i < app->samples_count; i += 4)
-        {
+        for(size_t i = 0; i < app->samples_count; i += 4) {
             int16_t L = (((int16_t)app->tmp_buffer[i + 1] << 8) + (int16_t)app->tmp_buffer[i]);
             int16_t R = (((int16_t)app->tmp_buffer[i + 3] << 8) + (int16_t)app->tmp_buffer[i + 2]);
             int32_t int_16 = L / 2 + R / 2; // (L + R) / 2
-            
+
             float data = ((float)int_16 / 256.0 + 127.0);
             data -= UINT8_MAX / 2; // to signed
             data /= UINT8_MAX / 2; // scale -1..1
@@ -274,8 +267,7 @@ static bool fill_data(WavPlayerApp* app, size_t index)
         return count != app->samples_count;
     }
 
-    if(app->num_channels == 2 && app->bits_per_sample == 8)
-    {
+    if(app->num_channels == 2 && app->bits_per_sample == 8) {
         uint16_t* sample_buffer_start = &app->sample_buffer[index];
         size_t count = stream_read(app->stream, app->tmp_buffer, app->samples_count);
 
@@ -283,8 +275,7 @@ static bool fill_data(WavPlayerApp* app, size_t index)
             app->tmp_buffer[i] = 0;
         }
 
-        for(size_t i = 0; i < app->samples_count; i += 2) 
-        {
+        for(size_t i = 0; i < app->samples_count; i += 2) {
             float data = (app->tmp_buffer[i] + app->tmp_buffer[i + 1]) / 2; // (L + R) / 2
             data -= UINT8_MAX / 2; // to signed
             data /= UINT8_MAX / 2; // scale -1..1
@@ -366,12 +357,12 @@ static void app_run(WavPlayerApp* app) {
     bool eof = fill_data(app, 0);
     eof = fill_data(app, app->samples_count_half);
 
-    wav_player_speaker_init(app->sample_rate);
-    wav_player_dma_init((uint32_t)app->sample_buffer, app->samples_count);
+    if(furi_hal_speaker_acquire(1000)) {
+        wav_player_speaker_init(app->sample_rate);
+        wav_player_dma_init((uint32_t)app->sample_buffer, app->samples_count);
 
-    furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, wav_player_dma_isr, app->queue);
+        furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, wav_player_dma_isr, app->queue);
 
-    if(furi_hal_speaker_acquire(1000)) {
         wav_player_dma_start();
         wav_player_speaker_start();
 
@@ -413,14 +404,20 @@ static void app_run(WavPlayerApp* app) {
                 } else if(event.type == WavPlayerEventCtrlMoveL) {
                     int32_t seek =
                         stream_tell(app->stream) - wav_parser_get_data_start(app->parser);
-                    seek =
-                        MIN(seek, (int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100) % 2 ? ((int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100) - 1) : (int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100));
+                    seek = MIN(
+                        seek,
+                        (int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100) % 2 ?
+                            ((int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100) - 1) :
+                            (int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100));
                     stream_seek(app->stream, -seek, StreamOffsetFromCurrent);
                     wav_player_view_set_current(app->view, stream_tell(app->stream));
                 } else if(event.type == WavPlayerEventCtrlMoveR) {
                     int32_t seek = wav_parser_get_data_end(app->parser) - stream_tell(app->stream);
-                    seek =
-                        MIN(seek, (int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100) % 2 ? ((int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100) - 1) : (int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100));
+                    seek = MIN(
+                        seek,
+                        (int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100) % 2 ?
+                            ((int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100) - 1) :
+                            (int32_t)(wav_parser_get_data_len(app->parser) / (size_t)100));
                     stream_seek(app->stream, seek, StreamOffsetFromCurrent);
                     wav_player_view_set_current(app->view, stream_tell(app->stream));
                 } else if(event.type == WavPlayerEventCtrlOk) {
@@ -443,6 +440,9 @@ static void app_run(WavPlayerApp* app) {
         furi_hal_speaker_release();
     }
 
+    // Reset GPIO pin and bus states
+    wav_player_hal_deinit();
+
     furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL);
 }
 
@@ -459,4 +459,4 @@ int32_t wav_player_app(void* p) {
     app_run(app);
     app_free(app);
     return 0;
-}
+}

+ 73 - 59
wav_player_hal.c

@@ -16,82 +16,96 @@
 #define FURI_HAL_SPEAKER_CHANNEL LL_TIM_CHANNEL_CH1
 #define DMA_INSTANCE DMA1, LL_DMA_CHANNEL_1
 
-void wav_player_speaker_init(uint32_t sample_rate) 
-{
-	LL_TIM_InitTypeDef TIM_InitStruct = {0};
-	//TIM_InitStruct.Prescaler = 4;
-	TIM_InitStruct.Prescaler = 1;
-	TIM_InitStruct.Autoreload =
-		255; //in this fork used purely as PWM timer, the DMA now is triggered by SAMPLE_RATE_TIMER
-	LL_TIM_Init(FURI_HAL_SPEAKER_TIMER, &TIM_InitStruct);
-
-	LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
-	TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
-	TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE;
-	TIM_OC_InitStruct.CompareValue = 127;
-	LL_TIM_OC_Init(FURI_HAL_SPEAKER_TIMER, FURI_HAL_SPEAKER_CHANNEL, &TIM_OC_InitStruct);
-
-	//======================================================
-
-	TIM_InitStruct.Prescaler = 0;
-	//TIM_InitStruct.Autoreload = 1451; //64 000 000 / 1451 ~= 44100 Hz
-
-	TIM_InitStruct.Autoreload = 64000000 / sample_rate - 1; //to support various sample rates
-
-	LL_TIM_Init(SAMPLE_RATE_TIMER, &TIM_InitStruct);
-
-	//LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
-	TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
-	TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE;
-	TIM_OC_InitStruct.CompareValue = 127;
-	LL_TIM_OC_Init(SAMPLE_RATE_TIMER, FURI_HAL_SPEAKER_CHANNEL, &TIM_OC_InitStruct);
+void wav_player_speaker_init(uint32_t sample_rate) {
+    // Enable bus
+    furi_hal_bus_enable(FuriHalBusTIM2);
+
+    LL_TIM_InitTypeDef TIM_InitStruct = {0};
+    //TIM_InitStruct.Prescaler = 4;
+    TIM_InitStruct.Prescaler = 1;
+    TIM_InitStruct.Autoreload =
+        255; //in this fork used purely as PWM timer, the DMA now is triggered by SAMPLE_RATE_TIMER
+    LL_TIM_Init(FURI_HAL_SPEAKER_TIMER, &TIM_InitStruct);
+
+    LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
+    TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
+    TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE;
+    TIM_OC_InitStruct.CompareValue = 127;
+    LL_TIM_OC_Init(FURI_HAL_SPEAKER_TIMER, FURI_HAL_SPEAKER_CHANNEL, &TIM_OC_InitStruct);
+
+    //======================================================
+
+    TIM_InitStruct.Prescaler = 0;
+    //TIM_InitStruct.Autoreload = 1451; //64 000 000 / 1451 ~= 44100 Hz
+
+    TIM_InitStruct.Autoreload = 64000000 / sample_rate - 1; //to support various sample rates
+
+    LL_TIM_Init(SAMPLE_RATE_TIMER, &TIM_InitStruct);
+
+    //LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
+    TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
+    TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE;
+    TIM_OC_InitStruct.CompareValue = 127;
+    LL_TIM_OC_Init(SAMPLE_RATE_TIMER, FURI_HAL_SPEAKER_CHANNEL, &TIM_OC_InitStruct);
+
+    //=========================================================
+    //configuring PA6 pin as TIM16 output
+
+    furi_hal_gpio_init_ex(
+        &gpio_ext_pa6,
+        GpioModeAltFunctionPushPull,
+        GpioPullNo,
+        GpioSpeedVeryHigh,
+        GpioAltFn14TIM16);
+}
 
-	//=========================================================
-	//configuring PA6 pin as TIM16 output
+void wav_player_hal_deinit() {
+    furi_hal_gpio_init(&gpio_ext_pa6, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
 
-	furi_hal_gpio_init_ex(&gpio_ext_pa6, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn14TIM16);
+    // Disable bus
+    furi_hal_bus_disable(FuriHalBusTIM2);
 }
 
 void wav_player_speaker_start() {
-	LL_TIM_EnableAllOutputs(FURI_HAL_SPEAKER_TIMER);
-	LL_TIM_EnableCounter(FURI_HAL_SPEAKER_TIMER);
+    LL_TIM_EnableAllOutputs(FURI_HAL_SPEAKER_TIMER);
+    LL_TIM_EnableCounter(FURI_HAL_SPEAKER_TIMER);
 
-	LL_TIM_EnableAllOutputs(SAMPLE_RATE_TIMER);
-	LL_TIM_EnableCounter(SAMPLE_RATE_TIMER);
+    LL_TIM_EnableAllOutputs(SAMPLE_RATE_TIMER);
+    LL_TIM_EnableCounter(SAMPLE_RATE_TIMER);
 }
 
 void wav_player_speaker_stop() {
-	LL_TIM_DisableAllOutputs(FURI_HAL_SPEAKER_TIMER);
-	LL_TIM_DisableCounter(FURI_HAL_SPEAKER_TIMER);
+    LL_TIM_DisableAllOutputs(FURI_HAL_SPEAKER_TIMER);
+    LL_TIM_DisableCounter(FURI_HAL_SPEAKER_TIMER);
 
-	LL_TIM_DisableAllOutputs(SAMPLE_RATE_TIMER);
-	LL_TIM_DisableCounter(SAMPLE_RATE_TIMER);
+    LL_TIM_DisableAllOutputs(SAMPLE_RATE_TIMER);
+    LL_TIM_DisableCounter(SAMPLE_RATE_TIMER);
 }
 
 void wav_player_dma_init(uint32_t address, size_t size) {
-	uint32_t dma_dst = (uint32_t) & (FURI_HAL_SPEAKER_TIMER->CCR1);
-
-	LL_DMA_ConfigAddresses(DMA_INSTANCE, address, dma_dst, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
-	LL_DMA_SetDataLength(DMA_INSTANCE, size);
-
-	LL_DMA_SetPeriphRequest(DMA_INSTANCE, LL_DMAMUX_REQ_TIM2_UP);
-	LL_DMA_SetDataTransferDirection(DMA_INSTANCE, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
-	LL_DMA_SetChannelPriorityLevel(DMA_INSTANCE, LL_DMA_PRIORITY_VERYHIGH);
-	LL_DMA_SetMode(DMA_INSTANCE, LL_DMA_MODE_CIRCULAR);
-	LL_DMA_SetPeriphIncMode(DMA_INSTANCE, LL_DMA_PERIPH_NOINCREMENT);
-	LL_DMA_SetMemoryIncMode(DMA_INSTANCE, LL_DMA_MEMORY_INCREMENT);
-	LL_DMA_SetPeriphSize(DMA_INSTANCE, LL_DMA_PDATAALIGN_HALFWORD);
-	LL_DMA_SetMemorySize(DMA_INSTANCE, LL_DMA_MDATAALIGN_HALFWORD);
-
-	LL_DMA_EnableIT_TC(DMA_INSTANCE);
-	LL_DMA_EnableIT_HT(DMA_INSTANCE);
+    uint32_t dma_dst = (uint32_t) & (FURI_HAL_SPEAKER_TIMER->CCR1);
+
+    LL_DMA_ConfigAddresses(DMA_INSTANCE, address, dma_dst, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
+    LL_DMA_SetDataLength(DMA_INSTANCE, size);
+
+    LL_DMA_SetPeriphRequest(DMA_INSTANCE, LL_DMAMUX_REQ_TIM2_UP);
+    LL_DMA_SetDataTransferDirection(DMA_INSTANCE, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
+    LL_DMA_SetChannelPriorityLevel(DMA_INSTANCE, LL_DMA_PRIORITY_VERYHIGH);
+    LL_DMA_SetMode(DMA_INSTANCE, LL_DMA_MODE_CIRCULAR);
+    LL_DMA_SetPeriphIncMode(DMA_INSTANCE, LL_DMA_PERIPH_NOINCREMENT);
+    LL_DMA_SetMemoryIncMode(DMA_INSTANCE, LL_DMA_MEMORY_INCREMENT);
+    LL_DMA_SetPeriphSize(DMA_INSTANCE, LL_DMA_PDATAALIGN_HALFWORD);
+    LL_DMA_SetMemorySize(DMA_INSTANCE, LL_DMA_MDATAALIGN_HALFWORD);
+
+    LL_DMA_EnableIT_TC(DMA_INSTANCE);
+    LL_DMA_EnableIT_HT(DMA_INSTANCE);
 }
 
 void wav_player_dma_start() {
-	LL_DMA_EnableChannel(DMA_INSTANCE);
-	LL_TIM_EnableDMAReq_UPDATE(SAMPLE_RATE_TIMER);
+    LL_DMA_EnableChannel(DMA_INSTANCE);
+    LL_TIM_EnableDMAReq_UPDATE(SAMPLE_RATE_TIMER);
 }
 
 void wav_player_dma_stop() {
-	LL_DMA_DisableChannel(DMA_INSTANCE);
+    LL_DMA_DisableChannel(DMA_INSTANCE);
 }

+ 2 - 0
wav_player_hal.h

@@ -18,6 +18,8 @@ void wav_player_dma_start();
 
 void wav_player_dma_stop();
 
+void wav_player_hal_deinit();
+
 #ifdef __cplusplus
 }
 #endif