/** * @brief Stops audio recording. * @param Option: could be one of the following parameters * - CODEC_PDWN_SW: for software power off (by writing registers). * Then no need to reconfigure the Codec after power on. * - CODEC_PDWN_HW: completely shut down the codec (physically). * Then need to reconfigure the Codec after power on. * @retval AUDIO_OK if correct communication, else wrong communication */ uint8_t BSP_AUDIO_IN_Stop(uint32_t Option) { /* Call the Media layer stop function */ HAL_SAI_DMAStop(&haudio_in_sai); /* Call Audio Codec Stop function */ if(audio_drv->Stop(AUDIO_I2C_ADDRESS, Option) != 0) { return AUDIO_ERROR; } else { if(Option == CODEC_PDWN_HW) { /* Wait at least 100us */ HAL_Delay(1); } /* Return AUDIO_OK when all operations are correctly done */ return AUDIO_OK; } }
/** * @brief Stops audio playing and Power down the Audio Codec. * @param Option: could be one of the following parameters * - CODEC_PDWN_SW: for software power off (by writing registers). * Then no need to reconfigure the Codec after power on. * - CODEC_PDWN_HW: completely shut down the codec (physically). * Then need to reconfigure the Codec after power on. * @retval BSP AUDIO status */ uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option) { /* Call Audio Codec Stop function */ if (hAudioOut.AudioDrv->Stop(AUDIO_I2C_ADDRESS, Option) != 0) { return AUDIO_ERROR; } if(Option == CODEC_PDWN_HW) { /* Wait at least 100us */ HAL_Delay(1); } /* Stop DMA transfer of PCM samples towards the serial audio interface */ if (HAL_SAI_DMAStop(&BSP_AUDIO_hSai)!= HAL_OK) { return AUDIO_ERROR; } return AUDIO_OK; }
int playback_from_flash(void) { int ret = 0; int i; int pos_buff = 0; uint32_t pos_flash = 0; uint32_t part_len = DATA_BUFF_LEN / 2; uint32_t part_bytes = part_len * SAI_DATA_BYTES; uint32_t total_size = get_audio_part_len(); if (!aos_mutex_is_valid(&sai_mutex)) { KIDS_A10_PRT("aos_mutex_is_valid return false.\n"); return -1; } ret = aos_mutex_lock(&sai_mutex, SAI_WAIT_TIMEOUT); if (ret != 0) { KIDS_A10_PRT("SAI is very busy now.\n"); return -1; } if (!aos_sem_is_valid(&audio_sem)) { KIDS_A10_PRT("aos_sem_is_valid return false.\n"); ret = -1; goto PB_EXIT; } ret = reinit_sai_and_dma(SAI_dir_tx_m2p); if (ret != 0) { ret = -1; goto PB_EXIT; } printf("Playback time is %f seconds!\n", get_run_time()); #ifdef FLASH_MONO_DATA ret = hal_flash_read(PART_FOR_AUDIO, &pos_flash, &data_buff[pos_buff], part_bytes); if (ret != 0) { ret = -1; goto PB_EXIT; } ready_to_send(data_buff, part_len); ret = HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *)data_buff, DATA_BUFF_LEN); if (ret != 0) { KIDS_A10_PRT("HAL_SAI_Transmit_DMA return failed.\n"); ret = -1; goto PB_EXIT; } while (1) { /* Wait a callback event */ while (UpdatePointer == -1) { aos_sem_wait(&audio_sem, DMA_WAIT_TIMEOUT); if (ret != 0) KIDS_A10_PRT("DMA timeout.\n"); } pos_buff = UpdatePointer; UpdatePointer = -1; /* Upate the first or the second part of the buffer */ ret = hal_flash_read(PART_FOR_AUDIO, &pos_flash, &data_buff[pos_buff], part_bytes / 2); if (ret != 0) { ret = -1; break; } ready_to_send(&data_buff[pos_buff], part_len / 2); /* check the end of the file */ if ((pos_flash + part_bytes / 2) > total_size) { ret = HAL_SAI_DMAStop(&hsai_BlockA1); if (ret != 0) { KIDS_A10_PRT("HAL_SAI_DMAStop return failed.\n"); ret = -1; } break; } if (UpdatePointer != -1) { /* Buffer update time is too long compare to the data transfer time */ KIDS_A10_PRT("UpdatePointer error.\n"); ret = -1; break; } } #else ret = hal_flash_read(PART_FOR_AUDIO, &pos_flash, &data_buff[pos_buff], DATA_BUFF_LEN * SAI_DATA_BYTES); if (ret != 0) { ret = -1; goto PB_EXIT; } ret = HAL_SAI_Transmit_DMA(&hsai_BlockA1, (uint8_t *)data_buff, DATA_BUFF_LEN); if (ret != 0) { KIDS_A10_PRT("HAL_SAI_Transmit_DMA return failed.\n"); ret = -1; goto PB_EXIT; } while (1) { /* Wait a callback event */ while (UpdatePointer == -1) { aos_sem_wait(&audio_sem, DMA_WAIT_TIMEOUT); if (ret != 0) KIDS_A10_PRT("DMA timeout.\n"); } pos_buff = UpdatePointer; UpdatePointer = -1; /* Upate the first or the second part of the buffer */ ret = hal_flash_read(PART_FOR_AUDIO, &pos_flash, &data_buff[pos_buff], part_bytes); if (ret != 0) { ret = -1; break; } /* check the end of the file */ if ((pos_flash + part_bytes) > total_size) { ret = HAL_SAI_DMAStop(&hsai_BlockA1); if (ret != 0) { KIDS_A10_PRT("HAL_SAI_DMAStop return failed.\n"); ret = -1; } break; } if (UpdatePointer != -1) { /* Buffer update time is too long compare to the data transfer time */ KIDS_A10_PRT("UpdatePointer error.\n"); ret = -1; break; } } #endif PB_EXIT: ret = aos_mutex_unlock(&sai_mutex); if (ret != 0) { KIDS_A10_PRT("SAI release failed.\n"); } return ret; }