MXC-A36-Demo/MCU/components/drivers/peripheral/Src/driver_mp3_dec.c

204 lines
6.5 KiB
C
Raw Normal View History

/*
******************************************************************************
* @file driver_mp3_dec.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief MP3 decoder module driver.
* This file provides firmware functions to manage the
* MP3 DECODEER peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/******************************************************************************
* @fn mp3_decoder_init
*
* @brief Initialize the mp3 decoder according to the specified parameters
* in the MP3_DEC_HandleTypeDef
*
* @param hmp3dec : MP3_DEC_HandleTypeDef structure that contains the
* configuration information for MP3DEC module.
* pcm_buff : mp3 decoder paddr
* pcm_buf_size : pcm buffer size
*/
void mp3_dec_init(MP3_DEC_HandleTypeDef *hmp3dec, uint32_t *pcm_buff, uint32_t pcm_buf_size)
{
__MP3D_SOFTRST();//softreset
__MP3D_PCM_FIFO_RESET();
__MP3D_ISSUE_NEW_FILE();
MP3D->MP3D_CTRL.Bits.DAI_EN = hmp3dec->mp3dec_ctrl_Init.Bits.DAI_EN;
__MP3D_OPERA_ENABLE();
MP3D->MP3D_CTRL.Bits.ISR_EN = hmp3dec->mp3dec_ctrl_Init.Bits.ISR_EN;
MP3D->MP3D_PADDR = (uint32_t)pcm_buff;
MP3D->MP3D_PSIZE.Word = pcm_buf_size;
memset(pcm_buff,0,pcm_buf_size);
}
/******************************************************************************
* @fn mp3_decoder_start
*
* @brief Start the mp3 decoder
*
* @param src_buff : src data pointer
* src_size : src data size
*/
static void mp3_dec_start(uint8_t *src_buff, uint32_t src_size)
{
MP3D->MP3D_SADDR = (uint32_t)src_buff;
MP3D->MP3D_SSIZE.Word = src_size;
MP3D->MP3D_INTSTA.Bits.SOURCE_CMPLETION_ISR = 1;
MP3D->MP3D_CTRL.Bits.OPERA_START = 1;
}
/******************************************************************************
* @fn mp3_decoder_stop
*
* @brief Stop the mp3 decoder
*
* @param void
*/
static void mp3d_stop(void)
{
__MP3D_PCM_FIFO_RESET();
__MP3D_ISSUE_NEW_FILE();
}
/******************************************************************************
* @fn mp3_clear_isr
*
* @brief Clear the mp3 decoder isr flag
*
* @param isr : enum_mp3d_isr_t contains info
*/
static void mp3d_clear_isr(enum_mp3d_isr_t isr)
{
MP3D->MP3D_INTSTA.Word = (1 << isr);
}
/******************************************************************************
* @fn mp3_dec_playdata
*
* @brief Mp3 decoder play data
*
* @param hmp3dec : mp3 decoder handler
* fp_Data : the data which is needed to decoder
* fu32_Size : the decoded data's size
*/
void mp3_dec_playdata(MP3_DEC_HandleTypeDef *hmp3dec, uint8_t *fp_Data, uint32_t fu32_Size)
{
uint32_t length = 0;
uint32_t CurrentIndex = 0;
uint32_t DataSize = fu32_Size;
while(DataSize != 0)
{
length = fu32_Size > 512 ? 512 : fu32_Size;
mp3_dec_start((uint8_t *)&fp_Data[CurrentIndex], length);
DataSize -= length;
while(1)
{
if(__MP3D_CHECK_NEED_SEC())
{
mp3d_clear_isr(SOURCE_COMPLETE_ISR);
CurrentIndex += length;
break;
}
}
}
mp3d_stop();
}
/******************************************************************************
* @fn mp3_dec_playdata_IT
*
* @brief Mp3 decoder play data with isr
*
* @param hmp3dec : mp3 decoder handler
* fp_Data : the data which is needed to decoder
* fu32_Size : the decoded data's size
*/
void mp3_dec_playdata_IT(MP3_DEC_HandleTypeDef *hmp3dec, uint8_t *fp_Data, uint32_t fu32_Size)
{
__MP3D_COMPLETE_ISR_ENABLE();
hmp3dec->MP3Enced_Data = fp_Data;
hmp3dec->MP3Enced_Index = 0;
hmp3dec->LeftLen = fu32_Size;
hmp3dec->FrameLen = hmp3dec->LeftLen > 512 ? 512 : hmp3dec->LeftLen;
mp3_dec_start((uint8_t *)&hmp3dec->MP3Enced_Data[hmp3dec->MP3Enced_Index], hmp3dec->FrameLen);
hmp3dec->MP3Enced_Index += hmp3dec->FrameLen;
hmp3dec->LeftLen -= hmp3dec->FrameLen;
}
/******************************************************************************
* @fn mp3d_get_stream_info
*
* @brief Mp3 decoder get the decoded frame info
*
* @param info : struct_MP3D_stream_info_t structure contains
*/
void mp3d_get_stream_info(struct_MP3D_stream_info_t *info)
{
info->audio_ver = MP3D->MP3D_INFO.Bits.MP3_STREAM_AUDIO_VER;
info->audio_emphasis = MP3D->MP3D_INFO.Bits.MP3_STREAM_AUDIO_EMPHASIS;
info->audio_mode = MP3D->MP3D_INFO.Bits.MP3_STREAM_AUDIO_MODE;
info->bit_rate = MP3D->MP3D_INFO.Bits.MP3_STREAM_BIT_RATE;
info->copyright = MP3D->MP3D_INFO.Bits.MP3_STREAM_COPYRIGHT;
info->error_protection = MP3D->MP3D_INFO.Bits.MP3_STREAM_ERROR_PROTECT;
info->frame_locked = MP3D->MP3D_INFO.Bits.MP3_FRAME_LOCKED;
info->main_done = MP3D->MP3D_INFO.Bits.MP3_MAIN_DONE;
info->main_exhaust = MP3D->MP3D_INFO.Bits.MP3_MAIN_EXHAUST;
info->mode_extension = MP3D->MP3D_INFO.Bits.MP3_STREAM_AUDIO_MODE_EXTEN;
info->original = MP3D->MP3D_INFO.Bits.MP3_STREAM_ORIGINAL;
info->sample_rate = MP3D->MP3D_INFO.Bits.MP3_STREAM_SAMPLE_RATE;
}
/******************************************************************************
* @fn mp3d_check_dec_failed
*
* @brief check whether the mp3dec is failed or successful
*
* @param void
*/
int mp3d_check_dec_failed(void)
{
if((MP3D->MP3D_INTSTA.Bits.MP3_FRAME_LOCKED_ISR == 1) ||
(MP3D->MP3D_INFO.Bits.MP3_FRAME_LOCKED == 0))
{
MP3D->MP3D_INTSTA.Word = (1 << MP3_FRAME_LOCKED_ISR);
return 1;
}
return 0;
}
/******************************************************************************
* @fn mp3dec_IRQHandler
*
* @brief mp3 decoder handle function in mo3 dec isr
*
* @param hmp3dec : MP3 decoder handle
*/
void mp3dec_IRQHandler(MP3_DEC_HandleTypeDef *hmp3dec)
{
if(__MP3D_SRC_COMPLETE_ISR_IS_SET())
{
if(hmp3dec->LeftLen != 0)
{
hmp3dec->FrameLen = hmp3dec->LeftLen > 512 ? 512 : hmp3dec->LeftLen;
mp3_dec_start((uint8_t *)&hmp3dec->MP3Enced_Data[hmp3dec->MP3Enced_Index], hmp3dec->FrameLen);
hmp3dec->MP3Enced_Index += hmp3dec->FrameLen;
hmp3dec->LeftLen -= hmp3dec->FrameLen;
}
else
{
__MP3D_COMPLETE_ISR_DISABLE();
mp3d_stop();
}
}
}