Implement Versuch5 (works but freezes at stop->start)
This commit is contained in:
parent
d109215710
commit
77360487d2
@ -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 */
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user