Implement Versuch5 (works but freezes at stop->start)

This commit is contained in:
jonny 2025-12-16 12:06:54 +01:00
parent d109215710
commit 77360487d2
3 changed files with 225 additions and 79 deletions

View File

@ -21,6 +21,7 @@
#include "cmsis_os.h" #include "cmsis_os.h"
#include "fatfs.h" #include "fatfs.h"
#include "usb_host.h" #include "usb_host.h"
#include "waveplayer.h"
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
@ -162,12 +163,12 @@ void createGuiElements(){
// helper to update volume value on display // helper to update volume value on display
uint8_t volume = 70; uint8_t volumeVersuch4 = 70;
void drawVolume(){ void drawVolumeVersuch4(){
Display_Printf( 0, 40, Display_Printf( 0, 40,
LCD_COLOR_WHITE, LCD_COLOR_BLACK, LCD_COLOR_WHITE, LCD_COLOR_BLACK,
&FontBig, &FontBig,
"%03d", volume "%03d", volumeVersuch4
); );
} }
@ -180,7 +181,7 @@ void Task9_receiveGuiEvents(void *){
uint8_t gui_msg = 0; uint8_t gui_msg = 0;
//initially draw volume //initially draw volume
drawVolume(); drawVolumeVersuch4();
// receive gui events // receive gui events
while(1){ while(1){
@ -189,13 +190,13 @@ void Task9_receiveGuiEvents(void *){
switch(gui_msg){ switch(gui_msg){
case BUTTON_PLUS: case BUTTON_PLUS:
if (++volume > 100) volume = 100; if (++volumeVersuch4 > 100) volumeVersuch4 = 100;
drawVolume(); drawVolumeVersuch4();
break; break;
case BUTTON_MINUS: case BUTTON_MINUS:
if (volume-- == 0) volume = 0; if (volumeVersuch4-- == 0) volumeVersuch4 = 0;
drawVolume(); drawVolumeVersuch4();
break; break;
case BUTTON_PLAY: case BUTTON_PLAY:
@ -338,7 +339,7 @@ void Task8_printLoad(void *){
Display_Printf( 0, 0, Display_Printf( 0, 0,
LCD_COLOR_WHITE, LCD_COLOR_BLACK, LCD_COLOR_WHITE, LCD_COLOR_BLACK,
&FontBig, &FontBig,
"%03d", Usage_GetUsage() "%03d%%", Usage_GetUsage()
); );
Usage_PrintStats(); Usage_PrintStats();
@ -388,9 +389,8 @@ int main(void)
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */
Usage_Init(); Usage_Init();
Display_Init(); Display_Init();
Player_Init();
GUI_Init(); GUI_Init();
// local variables // local variables
uint32_t timestamp_lastCounted = HAL_GetTick(); uint32_t timestamp_lastCounted = HAL_GetTick();
@ -445,8 +445,8 @@ int main(void)
//xTaskCreate(Task6_countButtonPresses, "Task6_countButtonPresses", 256, NULL, 0, NULL); //xTaskCreate(Task6_countButtonPresses, "Task6_countButtonPresses", 256, NULL, 0, NULL);
//xTaskCreate(Task7_receiveQueueEvents, "Task7_receiveQueueEvents", 256, NULL, 0, NULL); //xTaskCreate(Task7_receiveQueueEvents, "Task7_receiveQueueEvents", 256, NULL, 0, NULL);
xTaskCreate(Task8_printLoad, "Task8_stats", 256, NULL, 0, NULL); xTaskCreate(Task8_printLoad, "Task8_stats", 256, NULL, 0, NULL);
xTaskCreate(Task9_receiveGuiEvents, "Task9_GUI", 256, NULL, 0, NULL); // xTaskCreate(Task9_receiveGuiEvents, "Task9_GUI", 256, NULL, 0, NULL);
/* USER CODE END RTOS_THREADS */ /* USER CODE END RTOS_THREADS */

View File

@ -1,66 +1,187 @@
/******************************************************************* /*******************************************************************
File: waveplayer.c File: waveplayer.c
Date: 29-September-2025 Date: 29-September-2025
Author: Peter Spindler Author: Peter Spindler
Description: Functions to play a wave file. Requires functions from audio.c Description: Functions to play a wave file. Requires functions from audio.c
********************************************************************/ ********************************************************************/
#include "stm32f7xx_hal.h" #include "stm32f7xx_hal.h"
#include "audio.h" #include "audio.h"
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "semphr.h" #include "semphr.h"
#include "task.h" #include "task.h"
#include "ff.h" #include "ff.h"
#include "fatfs.h" #include "fatfs.h"
#include "audio.h" #include "audio.h"
#include "gui.h" #include "gui.h"
#include "display.h" #include "display.h"
#include <stdio.h>
FIL WaveFile; #include <string.h>
#define AUDIO_BUFFER_SIZE_WORDS (1024*8)
uint16_t Audio_Buffer[AUDIO_BUFFER_SIZE_WORDS]; #define BUTTON_PLUS 0
#define BUTTON_MINUS 1
void Player_Start( const char *Filename ) { #define BUTTON_PLAY 2
FRESULT res; #define BUTTON_PAUSE 3
if( (res=f_open(&WaveFile, Filename , FA_READ )) != FR_OK) { #define BUTTON_STOP 4
printf("Error: Can't open audio file %s: %d\n", Filename, res);
return; enum playerState {PAUSED, PLAYING, STOPPED} playerState = PLAYING;
}
printf("Open wavefile %s: successful\n", Filename ); FIL WaveFile;
#define AUDIO_BUFFER_SIZE_WORDS (1024*8)
Audio_SetFrequency(22050); uint16_t Audio_Buffer[AUDIO_BUFFER_SIZE_WORDS];
#define PLAYER_NOTIFY_HALF (1UL << 0)
/* ToDo: Fill audio buffer completely */ #define PLAYER_NOTIFY_FULL (1UL << 1)
static TaskHandle_t PlayerTaskHandle = NULL;
Audio_Play( (uint8_t*) Audio_Buffer, sizeof(Audio_Buffer)/2 );
}
SemaphoreHandle_t Semphr_FillBuffer = NULL;
void Player_Stop( void ) { uint8_t fillFlag = 0;
Audio_Stop();
f_close(&WaveFile); // helper to update volume value on display
} uint8_t volume = 70;
void drawVolume(){
// Player_HalfTransfer_CallBack: called from DMA2_Stream4-ISR if first half of audio buffer has been transferred to SAI2 Display_Printf( 0, 40,
void Player_HalfTransfer_CallBack( void ) { LCD_COLOR_WHITE, LCD_COLOR_BLACK,
/* ToDo: Inform Player_Task about first half*/ &FontBig,
} "%03d", volume
);
// 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*/ void Player_Start( const char *Filename ) {
} FRESULT res;
printf("debug: Player_Start opening file...\n");
static void Player_Task( void *arguments ) { // FIXME: Currently is stuck / crashes here (when stopping, then playing again) ===================
/* ToDo */ if( (res=f_open(&WaveFile, Filename , FA_READ )) != FR_OK) {
} printf("Error: Can't open audio file %s: %d\n", Filename, res);
return;
void Player_Init( void ) { }
portENABLE_INTERRUPTS(); // Workaround to re-enable interrupts after FreeRTOS functions printf("debug: Player_start finished opening file. \n");
// 70: initial volume, 44100: initial sampling frequency printf("Open wavefile %s: successful\n", Filename );
if( Audio_Init(OUTPUT_DEVICE_AUTO,70,44100) != AUDIO_OK ) {
printf("Error: Can't init audio!\n"); Audio_SetFrequency(22050);
}
xTaskCreate(Player_Task,"Player", 512,NULL,0,NULL); // 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);
}

View File

@ -28,6 +28,9 @@
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
#include "waveplayer.h"
#include "fatfs.h"
/* USER CODE END Includes */ /* USER CODE END Includes */
/* USER CODE BEGIN PV */ /* USER CODE BEGIN PV */
@ -94,6 +97,9 @@ void MX_USB_HOST_Init(void)
/* /*
* user callback definition * user callback definition
*/ */
#define VERSUCH_5 1
static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id) static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
{ {
/* USER CODE BEGIN CALL_BACK_1 */ /* 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: case HOST_USER_CLASS_ACTIVE:
Appli_state = APPLICATION_READY; Appli_state = APPLICATION_READY;
printf("USB device ready\n\r"); printf("USB device ready\n\r");
#if VERSUCH_4
versuch4_write_file(); 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; break;
case HOST_USER_CONNECTION: case HOST_USER_CONNECTION: