#include "platform.h"
#include "hal_headfile.h"
#include "board.h"
#include "debug.h"
#include "heap_5.h"
#include "audio.h"


audio_src_handle_typedef  src0;
DMA_HandleTypeDef         src0_rx_dma;
DMA_HandleTypeDef         src0_tx_dma;

#define SRC0_FRAM_POINTS           256
__ALIGNED(4) volatile uint8_t *src0_rx_dma_ptr;
__ALIGNED(4) volatile uint8_t *src0_tx_dma_ptr;
__ALIGNED(4) volatile audio_buff_deal_def  src0_data_mag[2];


/**
 * This function will initialize SRC0
 *
 * @param :none
 * @return:none.
 */
void src0_init(void)
{
    uint32_t  *cbuff_addr;
    src0.init.dev_sel = RX_ASI0_TX_MEM;
    src0.init.input_sampe_rate = aec_param.iis_smplerate;
    src0.init.output_sampe_rate = 15600;
    src0.init.input_fmt = LOW_16BIT;
    src0.init.output_fmt = LOW_16BIT;
    src0.init.track = SRC_STEREO;
    src0.dma_rx_handle = &src0_rx_dma;
    src0.dma_tx_handle = &src0_tx_dma;
    src0.Instance = SRC0;

    if ((src0.init.dev_sel == RX_MEM_TX_DAC) || (src0.init.dev_sel == RX_MEM_TX_ASI0) || (src0.init.dev_sel == RX_MEM_TX_ASI1))
    {
        src0_rx_dma_ptr = NULL;
        src0_rx_dma_ptr = (uint8_t *)pvPortMalloc(SRC0_FRAM_POINTS * 2 * 2 * 2); //2字节*2个通道*2个缓冲区

        if (src0_rx_dma_ptr == NULL)
        {
            debug("src0 src0_rx_dma_ptr error\r\n");

            while (1);
        }

        src0_rx_dma_init(src0.dma_rx_handle);
        src0_data_mag[0].addr = (uint8_t *)pvPortMalloc(SRC0_FRAM_POINTS * 2 * 2);
        src0_data_mag[0].status = BUFF_FREE;
        src0_data_mag[1].addr = (uint8_t *)pvPortMalloc(SRC0_FRAM_POINTS * 2 * 2);
        src0_data_mag[1].status = BUFF_FREE;

        if ((src0_data_mag[0].addr == NULL) || (src0_data_mag[0].addr == NULL))
        {
            debug("src0 src0_rx_dma_ptr error\r\n");

            while (1);
        }
    }

    if ((src0.init.dev_sel == RX_ADC_TX_MEM) || (src0.init.dev_sel == RX_ASI0_TX_MEM) || (src0.init.dev_sel == RX_ASI1_TX_MEM))
    {
        src0_tx_dma_ptr = NULL;
        src0_tx_dma_ptr = (uint8_t *)pvPortMalloc(SRC0_FRAM_POINTS * 2 * 2 * 2);

        if (src0_tx_dma_ptr == NULL)
        {
            debug("src0 src0_tx_dma_ptr error\r\n");

            while (1);
        }

        src0_tx_dma_init(src0.dma_tx_handle);
    }

    cbuff_addr = (uint32_t *)pvPortMalloc(2048 * 4);

    if (cbuff_addr == NULL)
    {
        debug("src0 cbuff malloc error\r\n");

        while (1);
    }

    src0.cfg_buff = cbuff_addr;
    hal_src_init(&src0);
    vPortFree(cbuff_addr);
}

/**
 * This function is used to initialize the src receiving DMA
 *
 * @param dma_handle:  DMA handle
 * @return: none.
 */
void src0_rx_dma_init(DMA_HandleTypeDef *dma_handle)
{
    /*目标地址*/
    dma_handle->init.dst_data_loc = DMA_Data_Location_Select_Low;
    dma_handle->init.dst_data_width = DMA_Data_Width_16Bit;
    dma_handle->init.dst_inc = DMA_Address_Type_Fix;
    /*源地址*/
    dma_handle->init.src_data_loc = DMA_Data_Location_Select_Low;
    dma_handle->init.src_data_width = DMA_Data_Width_16Bit;
    dma_handle->init.src_inc = DMA_Address_Type_Inc;
    /*DMA*/
    dma_handle->init.memory_burst = DMA_Burst_Length_Burst2;
    dma_handle->init.channel = CH4;
    dma_handle->init.priority = 4;
    dma_handle->init.mode = DMA_Mode_Circular;
    hal_dma_init(dma_handle);
    hal_dma_register_callback(dma_handle, HAL_DMA_XFER_CPLT_CB_ID, (void *)src0_rx_full_cplt);   /*注册完成中断服务函数*/
    hal_dma_register_callback(dma_handle, HAL_DMA_XFER_HALFCPLT_CB_ID, (void *)src0_rx_half_cplt); /*注册半完成中断服务函数*/
    hal_dma_start_it(dma_handle, (uint32_t)src0_rx_dma_ptr, (uint32_t)(&(src0.Instance->WBUF)), SRC0_FRAM_POINTS * 2 * 2 * 2, NULL); /*dma开始传输*/
}

/**
 * This function is used to initialize the src sending DMA
 *
 * @param dma_handle:  DMA handle
 * @return: none.
 */
void src0_tx_dma_init(DMA_HandleTypeDef *dma_handle)
{
    /*目标地址*/
    dma_handle->init.dst_data_loc = DMA_Data_Location_Select_High;
    dma_handle->init.dst_data_width = DMA_Data_Width_16Bit;
    dma_handle->init.dst_inc = DMA_Address_Type_Inc;
    /*源地址*/
    dma_handle->init.src_data_loc = DMA_Data_Location_Select_High;
    dma_handle->init.src_data_width = DMA_Data_Width_16Bit;
    dma_handle->init.src_inc = DMA_Address_Type_Fix;
    /*DMA*/
    dma_handle->init.memory_burst = DMA_Burst_Length_Burst2;
    dma_handle->init.channel = CH3;
    dma_handle->init.priority = 3;
    dma_handle->init.mode = DMA_Mode_Circular;
    hal_dma_init(dma_handle);
    hal_dma_register_callback(dma_handle, HAL_DMA_XFER_CPLT_CB_ID, src0_tx_full_cplt);   /*注册完成中断服务函数*/
    hal_dma_register_callback(dma_handle, HAL_DMA_XFER_HALFCPLT_CB_ID, src0_tx_half_cplt); /*注册半完成中断服务函数*/
    hal_dma_start_it(dma_handle, (uint32_t)(&(src0.Instance->RBUF)), (uint32_t)src0_tx_dma_ptr, SRC0_FRAM_POINTS * 2 * 2 * 2, NULL);
}

/**
 * SRC0 input full completes the DMA interrupt function
 *
 * @param dma_handle:  DMA handle
 * @return: none.
 */
void src0_rx_full_cplt(DMA_HandleTypeDef dma, void *param)
{
    if (src0_data_mag[1].status == BUFF_BUSY)
    {
        brom_memcpy(((uint8_t *)src0_rx_dma_ptr) + (SRC0_FRAM_POINTS << 2), (uint8_t *)(src0_data_mag[1].addr), SRC0_FRAM_POINTS << 2); //
        src0_data_mag[1].status = BUFF_FREE;
    }
    else
    {
        brom_memset(((uint8_t *)src0_rx_dma_ptr) + (SRC0_FRAM_POINTS << 2), 0, SRC0_FRAM_POINTS << 2);
    }
}
/**
 * SRC0 input half completes the DMA interrupt function
 *
 * @param dma_handle:  DMA handle
 * @return: none.
 */
void src0_rx_half_cplt(DMA_HandleTypeDef dma, void *param)
{
    if (src0_data_mag[0].status == BUFF_BUSY)
    {
        brom_memcpy((uint8_t *)src0_rx_dma_ptr, (uint8_t *)(src0_data_mag[0].addr), SRC0_FRAM_POINTS << 2);
        src0_data_mag[0].status = BUFF_FREE;
    }
    else
    {
        brom_memset((uint8_t *)src0_rx_dma_ptr, 0, SRC0_FRAM_POINTS << 2);
    }
}
/**
 * SRC0 output full completes the DMA interrupt function
 *
 * @param dma_handle:  DMA handle
 * @return: none.
 */
void src0_tx_full_cplt(DMA_HandleTypeDef dma, void *param)
{
#ifdef DEBUG_PRINT_WAV
    debug_puts_hex((uint8_t *)((uint8_t *)src0_tx_dma_ptr + SRC0_FRAM_POINTS * 2 * 2), SRC0_FRAM_POINTS * 2 * 2);
#else
    push_primitive_audio_from_iis_rx((int16_t *)((uint8_t *)src0_tx_dma_ptr + SRC0_FRAM_POINTS * 2 * 2), SRC0_FRAM_POINTS); //point num
#endif
}
/**
 * SRC0 output half completes the DMA interrupt function
 *
 * @param dma_handle:  DMA handle
 * @return: none.
 */
void src0_tx_half_cplt(DMA_HandleTypeDef dma, void *param)
{
#ifdef DEBUG_PRINT_WAV
    debug_puts_hex((uint8_t *)((uint8_t *)src0_tx_dma_ptr + 0), SRC0_FRAM_POINTS * 2 * 2);
#else
    push_primitive_audio_from_iis_rx((int16_t *)((uint8_t *)src0_tx_dma_ptr + 0), SRC0_FRAM_POINTS); //point num
#endif
}
/**
 * This function is used to write audio data for src0
 *
 * @param buf:     addr of audio data
 * @param points:  points number of audio data
 * @return: none.
 */
int32_t src0_write_data(uint8_t *buf, uint16_t points)
{
    static uint8_t i = 0;

    if (points != (SRC0_FRAM_POINTS)) //每次给256个点
    {
        return -1;
    }

    if (src0_data_mag[i].status == BUFF_FREE)
    {
        brom_memcpy((uint8_t *)(src0_data_mag[i].addr), (uint8_t *)buf, SRC0_FRAM_POINTS << 2);
        src0_data_mag[i].status = BUFF_BUSY;
    }
    else
    {
        return -2;
    }

    i = (i + 1) % 2;
    return -0;
}

// void src_ch0_dynamic_ratio(uint8_t cmd)
// {
//  static uint16_t wbuf_wlevel_bak,time_cnt,set_up_step,set_down_step;
//  uint16_t wbuf_wlevel;
//  wbuf_wlevel = DEV_SRC->CHN[0].STA_f.WBUF_WLVL;
//  //show_uart_wave(wbuf_wlevel,0,0,0,0);
//  if(!cmd)
//  {
//      return;
//  }
//  if(wbuf_wlevel < 200)//有危险多调点
//  {
//      DEV_SRC->CHN[0].LSR += 0x200;
//  }
//  else if(wbuf_wlevel > 2048-200)//有危险多调点
//  {
//      DEV_SRC->CHN[0].LSR -= 0x100;
//  }
//  if(time_cnt == 0)
//  {
//     wbuf_wlevel_bak = wbuf_wlevel;
//  }
//     time_cnt ++;
//     if(time_cnt >= 1)
//     {
//      if((wbuf_wlevel >800)&&(wbuf_wlevel < wbuf_wlevel_bak))//大于800，但是趋势是向下走,加速向下
//      {
//          time_cnt = 0;
//          DEV_SRC->CHN[0].LSR -= 0x60;
//      }
//      else if((wbuf_wlevel >500)&&(wbuf_wlevel > wbuf_wlevel_bak))//大于1024，但是趋势是向上走
//      {
//          if(set_down_step < 0x300)
//          {
//              set_down_step += 10;
//          }
//          DEV_SRC->CHN[0].LSR -= set_down_step;
//          time_cnt = 0;
//          set_up_step = 0;
//      }
//      else if((wbuf_wlevel < 500)&&(wbuf_wlevel < wbuf_wlevel_bak))//小于1024，但是趋势是向下走
//      {
//          if(set_up_step < 0x300)
//          {
//              set_up_step += 10;
//          }
//          DEV_SRC->CHN[0].LSR += set_up_step;
//          time_cnt = 0;
//          set_down_step = 0;
//      }
//      else if((wbuf_wlevel < 300)&&(wbuf_wlevel > wbuf_wlevel_bak))//小于1024，但是趋势是向上走，
//      {
//          DEV_SRC->CHN[0].LSR += 0x60;
//          time_cnt = 0;
//      }
//     }
// }
