diff --git a/Versuch5/Core/Src/main.c b/Versuch5/Core/Src/main.c index 1226cf2..9c19209 100644 --- a/Versuch5/Core/Src/main.c +++ b/Versuch5/Core/Src/main.c @@ -21,6 +21,7 @@ #include "cmsis_os.h" #include "fatfs.h" #include "usb_host.h" +#include "waveplayer.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ @@ -162,12 +163,12 @@ void createGuiElements(){ // helper to update volume value on display -uint8_t volume = 70; -void drawVolume(){ +uint8_t volumeVersuch4 = 70; +void drawVolumeVersuch4(){ Display_Printf( 0, 40, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, - "%03d", volume + "%03d", volumeVersuch4 ); } @@ -180,7 +181,7 @@ void Task9_receiveGuiEvents(void *){ uint8_t gui_msg = 0; //initially draw volume - drawVolume(); + drawVolumeVersuch4(); // receive gui events while(1){ @@ -189,13 +190,13 @@ void Task9_receiveGuiEvents(void *){ switch(gui_msg){ case BUTTON_PLUS: - if (++volume > 100) volume = 100; - drawVolume(); + if (++volumeVersuch4 > 100) volumeVersuch4 = 100; + drawVolumeVersuch4(); break; case BUTTON_MINUS: - if (volume-- == 0) volume = 0; - drawVolume(); + if (volumeVersuch4-- == 0) volumeVersuch4 = 0; + drawVolumeVersuch4(); break; case BUTTON_PLAY: @@ -338,7 +339,7 @@ void Task8_printLoad(void *){ Display_Printf( 0, 0, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, - "%03d", Usage_GetUsage() + "%03d%%", Usage_GetUsage() ); Usage_PrintStats(); @@ -388,9 +389,8 @@ int main(void) /* USER CODE BEGIN 2 */ Usage_Init(); - Display_Init(); - + Player_Init(); GUI_Init(); // local variables uint32_t timestamp_lastCounted = HAL_GetTick(); @@ -445,8 +445,8 @@ int main(void) //xTaskCreate(Task6_countButtonPresses, "Task6_countButtonPresses", 256, NULL, 0, NULL); //xTaskCreate(Task7_receiveQueueEvents, "Task7_receiveQueueEvents", 256, NULL, 0, NULL); - xTaskCreate(Task8_printLoad, "Task8_stats", 256, NULL, 0, NULL); - xTaskCreate(Task9_receiveGuiEvents, "Task9_GUI", 256, NULL, 0, NULL); + xTaskCreate(Task8_printLoad, "Task8_stats", 256, NULL, 0, NULL); + // xTaskCreate(Task9_receiveGuiEvents, "Task9_GUI", 256, NULL, 0, NULL); /* USER CODE END RTOS_THREADS */ diff --git a/Versuch5/Core/Src/waveplayer.c b/Versuch5/Core/Src/waveplayer.c index de07c37..28f2581 100644 --- a/Versuch5/Core/Src/waveplayer.c +++ b/Versuch5/Core/Src/waveplayer.c @@ -1,66 +1,187 @@ -/******************************************************************* -File: waveplayer.c -Date: 29-September-2025 -Author: Peter Spindler -Description: Functions to play a wave file. Requires functions from audio.c - ********************************************************************/ -#include "stm32f7xx_hal.h" -#include "audio.h" - -#include "FreeRTOS.h" -#include "semphr.h" -#include "task.h" - -#include "ff.h" -#include "fatfs.h" - -#include "audio.h" -#include "gui.h" -#include "display.h" - -FIL WaveFile; -#define AUDIO_BUFFER_SIZE_WORDS (1024*8) -uint16_t Audio_Buffer[AUDIO_BUFFER_SIZE_WORDS]; - -void Player_Start( const char *Filename ) { - FRESULT res; - if( (res=f_open(&WaveFile, Filename , FA_READ )) != FR_OK) { - printf("Error: Can't open audio file %s: %d\n", Filename, res); - return; - } - printf("Open wavefile %s: successful\n", Filename ); - - Audio_SetFrequency(22050); - - /* ToDo: Fill audio buffer completely */ - - Audio_Play( (uint8_t*) Audio_Buffer, sizeof(Audio_Buffer)/2 ); -} - -void Player_Stop( void ) { - Audio_Stop(); - f_close(&WaveFile); -} - -// Player_HalfTransfer_CallBack: called from DMA2_Stream4-ISR if first half of audio buffer has been transferred to SAI2 -void Player_HalfTransfer_CallBack( void ) { - /* ToDo: Inform Player_Task about first half*/ -} - -// Player_CompleteTransfer_CallBack: called from DMA2_Stream4-ISR if second half of audio buffer has been transferred to SAI2 -void Player_CompleteTransfer_CallBack( void ) { - /* ToDo: Inform Player_Task about second half*/ -} - -static void Player_Task( void *arguments ) { - /* ToDo */ -} - -void Player_Init( void ) { - portENABLE_INTERRUPTS(); // Workaround to re-enable interrupts after FreeRTOS functions - // 70: initial volume, 44100: initial sampling frequency - if( Audio_Init(OUTPUT_DEVICE_AUTO,70,44100) != AUDIO_OK ) { - printf("Error: Can't init audio!\n"); - } - xTaskCreate(Player_Task,"Player", 512,NULL,0,NULL); -} +/******************************************************************* +File: waveplayer.c +Date: 29-September-2025 +Author: Peter Spindler +Description: Functions to play a wave file. Requires functions from audio.c + ********************************************************************/ +#include "stm32f7xx_hal.h" +#include "audio.h" + +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +#include "ff.h" +#include "fatfs.h" + +#include "audio.h" +#include "gui.h" +#include "display.h" +#include +#include + +#define BUTTON_PLUS 0 +#define BUTTON_MINUS 1 +#define BUTTON_PLAY 2 +#define BUTTON_PAUSE 3 +#define BUTTON_STOP 4 + +enum playerState {PAUSED, PLAYING, STOPPED} playerState = PLAYING; + +FIL WaveFile; +#define AUDIO_BUFFER_SIZE_WORDS (1024*8) +uint16_t Audio_Buffer[AUDIO_BUFFER_SIZE_WORDS]; +#define PLAYER_NOTIFY_HALF (1UL << 0) +#define PLAYER_NOTIFY_FULL (1UL << 1) +static TaskHandle_t PlayerTaskHandle = NULL; + + +SemaphoreHandle_t Semphr_FillBuffer = NULL; +uint8_t fillFlag = 0; + +// helper to update volume value on display +uint8_t volume = 70; +void drawVolume(){ + Display_Printf( 0, 40, + LCD_COLOR_WHITE, LCD_COLOR_BLACK, + &FontBig, + "%03d", volume + ); +} + +void Player_Start( const char *Filename ) { + FRESULT res; + printf("debug: Player_Start opening file...\n"); + // FIXME: Currently is stuck / crashes here (when stopping, then playing again) =================== + if( (res=f_open(&WaveFile, Filename , FA_READ )) != FR_OK) { + printf("Error: Can't open audio file %s: %d\n", Filename, res); + return; + } + printf("debug: Player_start finished opening file. \n"); + printf("Open wavefile %s: successful\n", Filename ); + + Audio_SetFrequency(22050); + + // fill audio buffer completely + UINT bytesRead = 0; + res = f_read(&WaveFile, Audio_Buffer, sizeof(Audio_Buffer), &bytesRead); + if( res != FR_OK ) { + printf("Error: Can't read audio file %s: %d\n", Filename, res); + f_close(&WaveFile); + return; + } + + Audio_Play( (uint8_t*) Audio_Buffer, sizeof(Audio_Buffer)/2 ); +} + +void Player_Stop( void ) { + Audio_Stop(); + f_close(&WaveFile); +} + +// Player_HalfTransfer_CallBack: called from DMA2_Stream4-ISR if first half of audio buffer has been transferred to SAI2 +void Player_HalfTransfer_CallBack( void ) { + fillFlag = 0; + //printf("give 0\n"); + xSemaphoreGiveFromISR(Semphr_FillBuffer, NULL); +} + +// Player_CompleteTransfer_CallBack: called from DMA2_Stream4-ISR if second half of audio buffer has been transferred to SAI2 +void Player_CompleteTransfer_CallBack( void ) { + fillFlag = 1; + //printf("give 1\n"); + xSemaphoreGiveFromISR(Semphr_FillBuffer, NULL); +} + +static void Player_Task( void *arguments ) { + UINT bytesRead = 0; + uint32_t notifyValue = 0; + drawVolume(); + while(1) { + // 1. fill audio buffer if requested + if (xSemaphoreTake(Semphr_FillBuffer, pdMS_TO_TICKS(20))){ + if (playerState != PLAYING) continue; + if (fillFlag == 0){ // half flag -> fill first half + if( f_read(&WaveFile, &Audio_Buffer[0], sizeof(Audio_Buffer)/2, &bytesRead) != FR_OK ) { + bytesRead = 0; + } + if( bytesRead < AUDIO_BUFFER_SIZE_WORDS/2 ) { + printf("error reading bytes, stopping playback\n"); + Player_Stop(); + playerState = STOPPED; + } + } + + else if (fillFlag == 1){ // complete flag -> fill second half + bytesRead = 0; + if( f_read(&WaveFile, &Audio_Buffer[AUDIO_BUFFER_SIZE_WORDS/2], sizeof(Audio_Buffer)/2, &bytesRead) != FR_OK ) { + bytesRead = 0; + } + if( bytesRead < AUDIO_BUFFER_SIZE_WORDS/2 ) { + printf("error reading bytes, stopping playback\n"); + Player_Stop(); + playerState = STOPPED; + } + } + } + + // 2. run player control (handle gui events) + //printf("running player control...\n"); + uint8_t gui_msg = 0; + if (xQueueReceive(GUIQueue, &gui_msg, pdMS_TO_TICKS(0))){ + printf("Received GUI event %d\n", gui_msg); + + switch(gui_msg){ + case BUTTON_PLUS: + if (++volume > 100) volume = 100; + drawVolume(); + Audio_SetVolume(volume); + break; + + case BUTTON_MINUS: + if (volume-- == 0) volume = 0; + drawVolume(); + Audio_SetVolume(volume); + break; + + case BUTTON_PLAY: + printf("Play\r\n"); + if (playerState == STOPPED){ + printf("was stopped, starting player from start\n"); + // FATFS fs; + // printf("1. mounting filesystem...\n"); + // f_mount(&fs, "/", 0); + Player_Start("audio.wav"); + } else if (playerState == PAUSED){ + printf("was paused, resuming...\n"); + Audio_Resume(); + } + playerState = PLAYING; + break; + + case BUTTON_PAUSE: + printf("Pausing\r\n"); + Audio_Pause(); + playerState = PAUSED; + break; + + case BUTTON_STOP: + printf("Stopping player\r\n"); + Player_Stop(); + playerState = STOPPED; + break; + } + } + vTaskDelay(pdMS_TO_TICKS(10)); + } +} + +void Player_Init( void ) { + portENABLE_INTERRUPTS(); // Workaround to re-enable interrupts after FreeRTOS functions + // 70: initial volume, 44100: initial sampling frequency + if( Audio_Init(OUTPUT_DEVICE_AUTO,70,44100) != AUDIO_OK ) { + printf("Error: Can't init audio!\n"); + } + Semphr_FillBuffer = xSemaphoreCreateBinary(); + xTaskCreate(Player_Task,"Player", 512,NULL,0,&PlayerTaskHandle); +} diff --git a/Versuch5/USB_HOST/App/usb_host.c b/Versuch5/USB_HOST/App/usb_host.c index 606cf89..8282745 100644 --- a/Versuch5/USB_HOST/App/usb_host.c +++ b/Versuch5/USB_HOST/App/usb_host.c @@ -28,6 +28,9 @@ /* USER CODE BEGIN Includes */ +#include "waveplayer.h" +#include "fatfs.h" + /* USER CODE END Includes */ /* USER CODE BEGIN PV */ @@ -94,6 +97,9 @@ void MX_USB_HOST_Init(void) /* * user callback definition */ + + #define VERSUCH_5 1 + static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id) { /* USER CODE BEGIN CALL_BACK_1 */ @@ -110,7 +116,26 @@ static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id) case HOST_USER_CLASS_ACTIVE: Appli_state = APPLICATION_READY; printf("USB device ready\n\r"); +#if VERSUCH_4 versuch4_write_file(); + +#else if VERSUCH_5 + + FATFS fs; + FRESULT res; + + // mount fs + printf("1. mounting filesystem...\n"); + res = f_mount(&fs, "/", 0); + if (res != FR_OK){ + printf("Fehler beim mounten vom dateisystem\n"); + return; + } + + printf("2. starting playback..."); + Player_Start("audio.wav"); +#endif + break; case HOST_USER_CONNECTION: