/** * @brief Pause Audio stream * @param None. * @retval Audio state. */ AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_PauseResume(void) { if(haudio.in.state == AUDIO_RECORDER_PLAYING) { osThreadSuspend(AudioThreadId); BSP_AUDIO_OUT_Pause(); haudio.in.state = AUDIO_RECORDER_PLAY_PAUSE; } else if(haudio.in.state == AUDIO_RECORDER_RECORDING) { osThreadSuspend(AudioThreadId); BSP_AUDIO_IN_Pause(); haudio.in.state = AUDIO_RECORDER_RECORD_PAUSE; } else if(haudio.in.state == AUDIO_RECORDER_PLAY_PAUSE) { osThreadResume(AudioThreadId); BSP_AUDIO_OUT_Resume(); haudio.in.state = AUDIO_RECORDER_PLAYING; } else if(haudio.in.state == AUDIO_RECORDER_RECORD_PAUSE) { osThreadResume(AudioThreadId); BSP_AUDIO_IN_Resume(); haudio.in.state = AUDIO_RECORDER_RECORDING; } return AUDIO_RECORDER_ERROR_NONE; }
/** * @brief Toggle LED2 thread * @param argument not used * @retval None */ static void LED_Thread2(void const *argument) { uint32_t count; (void) argument; for(;;) { count = osKernelSysTick() + 10000; /* Toggle LED2 every 500 ms for 10 s */ while (count >= osKernelSysTick()) { BSP_LED_Toggle(LED2); osDelay(500); } /* Turn off LED2 */ BSP_LED_Off(LED2); /* Resume Thread 1 */ osThreadResume(LEDThread1Handle); /* Suspend Thread 2 */ osThreadSuspend(NULL); } }
/** * @brief Semaphore Thread 2 function * @param argument: shared semaphore * @retval None */ static void SemaphoreThread2 (void const *argument) { uint32_t count = 0; osSemaphoreId semaphore = (osSemaphoreId) argument; for(;;) { if (semaphore != NULL) { /* Try to obtain the semaphore. */ if(osSemaphoreWait(semaphore , 0) == osOK) { /* Resume Thread 1 (higher priority)*/ osThreadResume(SemThread1Handle); count = osKernelSysTick() + 5000; /* Toggle LED3 every 200 ms for 5 seconds*/ while (count >= osKernelSysTick()) { BSP_LED_Toggle(LED3); osDelay(200); } /* Turn off LED3 */ BSP_LED_Off(LED3); /* Release the semaphore to unblock Thread 1 (higher priority) */ osSemaphoreRelease(semaphore); } } } }
/** * @brief Play audio stream * @param frequency: Audio frequency used to play the audio stream. * @retval Audio state. */ AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_Play(uint32_t frequency) { uint32_t numOfReadBytes; BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO, DEFAULT_REC_AUDIO_VOLUME, DEFAULT_AUDIO_IN_FREQ); BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); /* Fill whole buffer @ first time */ if(f_read(&wav_file, &haudio.buff[0], AUDIO_OUT_BUFFER_SIZE, (void *)&numOfReadBytes) == FR_OK) { if(numOfReadBytes != 0) { if(haudio.in.state == AUDIO_RECORDER_SUSPENDED) { osThreadResume(AudioThreadId); } haudio.in.state = AUDIO_RECORDER_PLAYING; BSP_AUDIO_OUT_Play((uint16_t*)&haudio.buff[0], AUDIO_OUT_BUFFER_SIZE); return AUDIO_RECORDER_ERROR_NONE; } } return AUDIO_RECORDER_ERROR_IO; }
/** * @brief Play audio stream * @param frequency: Audio frequency used to play the audio stream. * @retval Audio state. */ AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_StartRec(uint32_t frequency) { uint32_t byteswritten = 0; /* Initialize header file */ WavProcess_EncInit(DEFAULT_AUDIO_IN_FREQ, pHeaderBuff); haudio.ppcm = 0; /* Write header file */ if(f_write(&wav_file, pHeaderBuff, 44, (void*)&byteswritten) == FR_OK) { if(byteswritten != 0) { BSP_AUDIO_IN_Init(DEFAULT_AUDIO_IN_FREQ, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR); BSP_AUDIO_IN_Record((uint16_t*)&haudio.pdm[0], AUDIO_IN_PDM_BUFFER_SIZE); if(haudio.in.state == AUDIO_RECORDER_SUSPENDED) { osThreadResume(AudioThreadId); } haudio.in.state = AUDIO_RECORDER_RECORDING; haudio.in.fptr = byteswritten; return AUDIO_RECORDER_ERROR_NONE; } } return AUDIO_RECORDER_ERROR_IO; }
/** * @brief Toggle LED3 thread * @param argument not used * @retval None */ static void LED_Thread2(void const *argument) { uint32_t count; (void) argument; for (;;) { count = osKernelSysTick() + 10000; while (count >= osKernelSysTick()) { BSP_LED_On(LED3); osDelay(100); BSP_LED_Off(LED3); osDelay(100); BSP_LED_On(LED3); osDelay(100); BSP_LED_Off(LED3); HAL_Delay(1000); } /* Turn off LED3 */ BSP_LED_Off(LED3); /* Resume Thread 1 */ osThreadResume(LEDThread1Handle); /* Suspend Thread 2 */ osThreadSuspend(NULL); } }
/** * @brief Play audio stream * @param frequency: Audio frequency used to play the audio stream. * @retval Audio state. */ AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_StartRec(uint32_t frequency) { uint32_t byteswritten = 0; /* Initialize header file */ WavProcess_EncInit(DEFAULT_AUDIO_IN_FREQ, pHeaderBuff); /* Write header file */ if(f_write(&wav_file, pHeaderBuff, 44, (void*)&byteswritten) == FR_OK) { if(byteswritten != 0) { BSP_AUDIO_IN_Init(INPUT_DEVICE_DIGITAL_MICROPHONE_2, haudio.in.volume, DEFAULT_AUDIO_IN_FREQ); BSP_AUDIO_IN_Record((uint16_t*)&haudio.buff[0], AUDIO_IN_BUFFER_SIZE/2); if(haudio.in.state == AUDIO_RECORDER_SUSPENDED) { osThreadResume(AudioThreadId); } haudio.in.state = AUDIO_RECORDER_RECORDING; haudio.in.fptr = byteswritten; return AUDIO_RECORDER_ERROR_NONE; } } return AUDIO_RECORDER_ERROR_IO; }
/** * @brief Resume Audio stream * @param None. * @retval Audio state. */ AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_Resume(void) { if(AudioThreadId != 0) { osThreadResume(AudioThreadId); } BSP_AUDIO_OUT_Resume(); return AUDIOPLAYER_ERROR_NONE; }
/** * @brief Toggle LED1 * @param thread not used * @retval None */ static void LED_Thread1(void const *argument) { (void) argument; for (;;) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET); osDelay(2000); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); osThreadSuspend(LEDThread2Handle); osDelay(1900); osThreadResume(LEDThread2Handle); } }
/** * @brief Play audio stream * @param frequency: Audio frequency used to play the audio stream. * @retval Audio state. */ AUDIOPLAYER_ErrorTypdef AUDIOPLAYER_Play(uint32_t frequency) { uint32_t numOfReadBytes; haudio.state = AUDIOPLAYER_PLAY; /* Fill whole buffer @ first time */ if(f_read(&wav_file, &haudio.buffer[0], AUDIO_BUFFER_SIZE, (void *)&numOfReadBytes) == FR_OK) { if(numOfReadBytes != 0) { BSP_AUDIO_OUT_SetFrequency(frequency); osThreadResume(AudioThreadId); BSP_AUDIO_OUT_Play((uint16_t*)&haudio.buffer[0], AUDIO_BUFFER_SIZE); return AUDIOPLAYER_ERROR_NONE; } } return AUDIOPLAYER_ERROR_IO; }
/** * @brief Toggle LED3 and LED4 thread * @param thread not used * @retval None */ static void LED_Thread1(void const *argument) { uint32_t count = 0; (void) argument; for (;;) { count = osKernelSysTick() + 5000; /* Toggle LED3 every 200 ms for 5 s */ while (count >= osKernelSysTick()) { BSP_LED_Toggle(LED3); osDelay(200); } /* Turn off LED3 */ BSP_LED_Off(LED3); /* Suspend Thread 1 */ osThreadSuspend(NULL); count = osKernelSysTick() + 5000; /* Toggle LED3 every 400 ms for 5 s */ while (count >= osKernelSysTick()) { BSP_LED_Toggle(LED3); osDelay(400); } /* Resume Thread 2*/ osThreadResume(LEDThread2Handle); } }
/** * @brief Mutex Low Priority Thread. * @param argument: Not used * @retval None */ static void MutexLowPriorityThread(void const *argument) { /* Just to remove compiler warning. */ (void) argument; for(;;) { /* Keep attempting to obtain the mutex. We should only obtain it when the medium-priority thread has suspended itself, which in turn should only happen when the high-priority thread is also suspended. */ if(osMutexWait(osMutex, mutexNO_DELAY) == osOK) { /* Is the haigh and medium-priority threads suspended? */ if((osThreadGetState(osHighPriorityThreadHandle) != osThreadSuspended) || (osThreadGetState(osMediumPriorityThreadHandle) != osThreadSuspended)) { /* Toggle LED 3 to indicate error */ BSP_LED_Toggle(LED3); } else { /* Keep count of the number of cycles this task has performed so a stall can be detected. */ LowPriorityThreadCycles++; BSP_LED_Toggle(LED4); /* We can resume the other tasks here even though they have a higher priority than the this thread. When they execute they will attempt to obtain the mutex but fail because the low-priority thread is still the mutex holder. this thread will then inherit the higher priority. The medium-priority thread will block indefinitely when it attempts to obtain the mutex, the high-priority thread will only block for a fixed period and an error will be latched if the high-priority thread has not returned the mutex by the time this fixed period has expired. */ osThreadResume(osMediumPriorityThreadHandle); osThreadResume(osHighPriorityThreadHandle); /* The other two tasks should now have executed and no longer be suspended. */ if((osThreadGetState(osHighPriorityThreadHandle) == osThreadSuspended) || (osThreadGetState(osMediumPriorityThreadHandle) == osThreadSuspended)) { /* Toggle LED 3 to indicate error */ BSP_LED_Toggle(LED3); } /* Release the mutex, disinheriting the higher priority again. */ if(osMutexRelease(osMutex) != osOK) { /* Toggle LED 3 to indicate error */ BSP_LED_Toggle(LED3); } } } #if configUSE_PREEMPTION == 0 { taskYIELD(); } #endif } }