Files
hpw421/component/xc6xx_drivers/Drivers/test_case/ADC/pga_adc.c
T
2026-06-06 16:49:48 +08:00

611 lines
17 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*!
* \file pga_adc.c
*
* \brief Target pga adc implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "pga_adc.h"
#include "adc.h"
#include "ringbuffer.h"
#include "xc6xxx_hal_adc.h"
#include "xc6xxx_hal_uart.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
#define USER_NOISE_EN 0
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
Mic_sampling_cb m_sampling_cb;
extern void UART_SendByte(UART_TypeDef *UARTx, uint8_t Byte);
extern uint8_t adc_ch_buff[1000];
extern uint32_t adc_val_buff[500];
extern uint16_t adc_con;
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
****************************************************************************************
* @brief
*
* @param[in]
* @param[in]
* @return[out]
*
****************************************************************************************
*/
void adc_uart_init(void)
{
// uint8_t rxbuff[26];
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Mux = GPIO_Mux0;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Int = NOT_INT;
GPIO_InitStruct.Pin = GPIO_3;
GPIO_InitStruct.Dir = GPIO_DIR_OUTPUT;
GPIO_InitStruct.FunSel = UART1_TX;
GPIO_Init(&GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_2;
GPIO_InitStruct.Dir = GPIO_DIR_INPUT;
GPIO_InitStruct.FunSel = UART1_RX;
GPIO_Init(&GPIO_InitStruct);
UART_InitTypeDef UART_InitStruct = {0};
UART_InitStruct.Parity = UART_PARITY_DISABLE;
UART_InitStruct.StopBits = UART_STOP_1_BITS;
UART_InitStruct.WordLength = UART_UARTx_TCR_CLS_8BITS;
UART_InitStruct.BaudRate = UART_BAUDRATE_1M;
UART_InitStruct.HardwareFlowControl = UART_UARTx_MCR_AFCE_DISABLE;
UART_Init(XC_UART1, &UART_InitStruct);
UART_Enable_RxIT(XC_UART1);
NVIC_EnableIRQ(UART1_IRQn);
}
void uart_seed_data(uint8_t data) { UART_SendByte(XC_UART1, data); }
void uart_seed_buff(uint8_t *Data, uint16_t len)
{
UART_SendData(XC_UART1, Data, len);
}
// extern unsigned int filter_data(unsigned int data);
// 对采样到的ADC值进行处理
void pga_adc_rx_event_handler(uint16_t pga_adc_val)
{
#if USER_NOISE_EN
static uint8_t delay_con = 0;
static uint32_t voice_data_bk = 0;
#endif
static uint8_t freq_con = 0;
short voice_data = 0;
freq_con++;
if (freq_con < m_sampling_cb.freq_con)
return;
freq_con = 0;
#if SAMPLING_DEBUG
if (m_sampling_cb.rx_flag)
return;
m_sampling_cb.pga_adc_rx_con++;
#endif
#if REC_TEST_EN || SAMPLING_DEBUG
if (!m_sampling_cb.rec_len_time) {
#if SAMPLING_DEBUG
m_sampling_cb.rx_flag = 1;
#endif // SAMPLING_DEBUG
return;
}
#endif // REC_TEST_EN || SAMPLING_DEBUG
// voice_data = pga_adc_val;
// if (pga_adc_val > 50) pga_adc_val = pga_adc_val - 50;//平移
voice_data = pga_adc_val;
#if USER_NOISE_EN
if (pga_adc_val > 2100 || pga_adc_val < 1900) {
delay_con = 0;
} else {
delay_con++;
if (delay_con >= 50) {
delay_con = 50;
pga_adc_val = (voice_data_bk + pga_adc_val) / 2;
pga_adc_val = 1024 + pga_adc_val / 2;
}
}
voice_data_bk = voice_data = pga_adc_val;
#endif // USER_NOISE_EN
if (voice_data > 2047) {
voice_data = (((uint32_t)voice_data - 2047) * 0x7fff / 2048);
voice_data &= ~0x8000;
} else {
voice_data = (((uint32_t)2047 - voice_data) * 0x7fff / 2048);
voice_data = 0x7fff - voice_data;
voice_data |= 0x8000;
}
m_sampling_cb.mic_adc_buff[m_sampling_cb.save_buf_index]
[m_sampling_cb.pga_adc_rx_index] = voice_data;
m_sampling_cb.pga_adc_rx_index++;
if (m_sampling_cb.pga_adc_rx_index >= MIC_SAMPLING_MAX_LEN) {
m_sampling_cb.pga_adc_rx_index = 0;
m_sampling_cb.save_buf_index = !m_sampling_cb.save_buf_index;
m_sampling_cb.buf_full_flag = 1;
}
}
#if (USE_XIP == 1)
/**
* @brief mic_pga_adc_sampling_set
* @details
* @param void
* @retval void
*/
void mic_pga_adc_sampling_set(void)
{
CLOCK_HighFreq_In_Typedef uclock_freq = CLOCK_HighFreq_Get();
#if (SAMPLING_TYPE == MIC_SAMPLING_8K)
#if (ADC_FREQ_CLOCK == ADC_CLK_DIV_2)
if (uclock_freq == CLOCK_HFCLK_IN_96M) {
m_sampling_cb.freq_con = 32;
} else if (uclock_freq == CLOCK_HFCLK_IN_64M) {
m_sampling_cb.freq_con = 24;
} else {
m_sampling_cb.freq_con = 19;
}
#else
//===========ADC时钟为2/4M的时候
if (uclock_freq == CLOCK_HFCLK_IN_96M) {
m_sampling_cb.freq_con = 32;
} else if (uclock_freq == CLOCK_HFCLK_IN_64M) {
m_sampling_cb.freq_con = 21;
} else {
m_sampling_cb.freq_con = 15;
}
#endif //(ADC_FREQ_CLOCK == ADC_CLK_DIV_2)
#else // 16k采样
#if (ADC_FREQ_CLOCK == ADC_CLK_DIV_2)
if (uclock_freq == CLOCK_HFCLK_IN_96M) {
m_sampling_cb.freq_con = 18;
} else if (uclock_freq == CLOCK_HFCLK_IN_64M) {
m_sampling_cb.freq_con = 12;
} else {
m_sampling_cb.freq_con = 9;
}
#elif (ADC_FREQ_CLOCK == ADC_CLK_DIV_4)
if (uclock_freq == CLOCK_HFCLK_IN_96M) {
m_sampling_cb.freq_con = 13;
} else if (uclock_freq == CLOCK_HFCLK_IN_64M) {
m_sampling_cb.freq_con = 8;
} else {
m_sampling_cb.freq_con = 7;
}
#else
//===========ADC时钟为2的时候
if (uclock_freq == CLOCK_HFCLK_IN_96M) {
m_sampling_cb.freq_con = 16;
} else if (uclock_freq == CLOCK_HFCLK_IN_64M) {
m_sampling_cb.freq_con = 9;
} else {
m_sampling_cb.freq_con = 5;
}
#endif //(ADC_FREQ_CLOCK == ADC_CLK_DIV_2)
#endif //(SAMPLING_TYPE == MIC_SAMPLING_8K)
}
#else
/**
* @brief mic_pga_adc_sampling_set
* @details
* @param void
* @retval void
*/
void mic_pga_adc_sampling_set(void)
{
CLOCK_HighFreq_In_Typedef uclock_freq = CLOCK_HighFreq_Get();
#if (SAMPLING_TYPE == MIC_SAMPLING_8K)
if (uclock_freq == CLOCK_HFCLK_IN_96M) {
m_sampling_cb.freq_con = 32;
} else if (uclock_freq == CLOCK_HFCLK_IN_64M) {
m_sampling_cb.freq_con = 24;
} else {
m_sampling_cb.freq_con = 20;
}
//===========ADC采样率为2/4M的时候
if (uclock_freq == CLOCK_HFCLK_IN_96M)
// {
// m_sampling_cb.freq_con = 32;
// }
// else if (uclock_freq == CLOCK_HFCLK_IN_64M)
// {
// m_sampling_cb.freq_con = 21;
// }
// else
// {
// m_sampling_cb.freq_con = 20;
// }
#else
if (uclock_freq == CLOCK_HFCLK_IN_96M) {
m_sampling_cb.freq_con = 16;
} else if (uclock_freq == CLOCK_HFCLK_IN_64M) {
m_sampling_cb.freq_con = 12;
} else {
m_sampling_cb.freq_con = 10;
}
//===========ADC采样率为2/4M的时候
// if (uclock_freq == CLOCK_HFCLK_IN_96M)
// {
// m_sampling_cb.freq_con = 16;
// }
// else if (uclock_freq == CLOCK_HFCLK_IN_64M)
// {
// m_sampling_cb.freq_con = 9;
// }
// else
// {
// m_sampling_cb.freq_con = 7;
// }
#endif // (SAMPLING_TYPE == MIC_SAMPLING_8K)
}
#endif // USE_XIP == 1
/**
* @brief mic_pga_adc_sampling_set
* @details
* @param void
* @retval void
*/
uint32_t pga_adc_data_uart_byte_delay(void)
{
uint32_t delay = 0;
CLOCK_HighFreq_In_Typedef uclock_freq = CLOCK_HighFreq_Get();
#if (ADC_FREQ_CLOCK == ADC_CLK_DIV_2)
if (uclock_freq == CLOCK_HFCLK_IN_64M) {
delay = 210;
} else {
delay = 75;
}
#else
if (uclock_freq == CLOCK_HFCLK_IN_64M) {
delay = 210;
} else {
delay = 86;
}
#endif
return delay;
}
/**
* @brief pga_init
* @details
* @param void
* @retval void
*/
void pga_init(void)
{
uint32_t adc_reg = 0;
DEBUG("audio_adc_ctrl_reg0 = %x\n",
*((volatile unsigned int *)(0x400001BC)));
// for(int i=0; i<0x100000; i++); //delay
adc_reg = *((volatile unsigned int *)(0x400001BC));
adc_reg &= ~(1 << 28);
adc_reg |= (1 << 28); // opa第1级增益 +20DB
adc_reg &= ~(0x0f << 24);
adc_reg |= (0x0a << 24); // opa第2级增益 +16DB //主要修改增益处(<24-27>
adc_reg &= ~(0x7 << 21);
adc_reg |= (0x7 << 21); // BIT21-23电流大小控制,最大为000,最小为111
adc_reg &= ~(0x0F << 0); // bias寄存器 控制电流
adc_reg &= ~(0x1 << 4); // opa pd信号
adc_reg &= ~(1 << 12); // open pdbias
adc_reg |= (0x1 << 5); // 差分
adc_reg &= ~(1 << 7); // open pdbias pga第1级增益,
*((volatile unsigned int *)(0x400001BC)) = adc_reg;
DEBUG("after audio_adc_ctrl_reg0 = %x\n",
*((volatile unsigned int *)(0x400001BC)));
}
/**
* @brief mic_pga_adc_demo
* @details
* @param void
* @retval void
*/
void mic_pga_adc_demo(void)
{
// DEBUG("__MIC_PGA_ADC_DEMO__\r");
adc_uart_init();
// uint16_t adc_val = 0;
adc_cfg adc_cfg;
GPIO_InitTypeDef GPIO_InitCfg = {0};
GPIO_InitCfg.Mux = GPIO_Mux0;
GPIO_InitCfg.FunSel = GPIO_Dx;
GPIO_InitCfg.Pull = GPIO_NOPULL;
// Board Led1 Initialization
GPIO_InitCfg.Dir = GPIO_DIR_INPUT;
GPIO_InitCfg.Int = NOT_INT;
GPIO_InitCfg.Pin = 6;
GPIO_Init(&GPIO_InitCfg);
// GPIO_InitCfg.Pin = 8;
// GPIO_Init(&GPIO_InitCfg);
//
// GPIO_InitCfg.Pin = 9;
// GPIO_Init(&GPIO_InitCfg);
#if SAMPLING_DEBUG || REC_TEST_EN
TIMER_BaseInitTypeDef Timer_Init;
Timer_Init.src_clk = TIMER_CLK_SRC_32M_DIV;
Timer_Init.mode = TIMER_MODE_CYCLE_COUNT;
Timer_Init.div_clk = TIMER_DIV_CLK_1MHzOr1K;
// Timer0 Config & Start
TIMER_Base_Init(XC_TIMER1, &Timer_Init);
TIMER_SetUs(XC_TIMER1,
1000000); // 测试采样到的时候改成1秒,录音测试改成5秒或者其他
#endif
// pga初始化
pga_init();
/*----- Special Pin -----*/
/*< SWD 和 SWCK 引脚也可以作为 ADC 使用,
注意 PIN 脚的功能重映射 >*/
// GPIO_MuxCtl(12,GPIO_Mux1);
// GPIO_MuxCtl(13,GPIO_Mux1);
/*-----------------------*/
adc_cfg.Freq = ADC_FREQ_4M;
adc_cfg.RefVol = ADC_REF_VOL_3_3V;
adc_cfg.SampEdge = ADC_SAMPEDGE_FALL;
adc_cfg.ExtDataMode = ADC_DATA_MODE_32BIT;
adc_cfg.ExtEdgeSel =
ADC_EXT_EDGE_SEL_INTER; // ADC_EXT_EDGE_SEL_EXTERN_RISE //
// ADC_EXT_EDGE_SEL_EXTERN_BOTH
adc_cfg.ExtSampleNum = ADC_SAMPLE_NUM_16;
adc_cfg.ExtTriggerSel = ADC_TRIGGER_SEL_PWM0;
ADC_Init(XC_ADC, &adc_cfg);
// 采样率设置
mic_pga_adc_sampling_set(); // ADC改动跟着改动
__ADC_ChannelSet(XC_ADC, ADC_CHANNEL13_PIN6);
__ADC_FIFO_ReqIntLenthSet(XC_ADC);
__ADC_FIFO_Flush(XC_ADC);
__ADC_Clear_IT_Flag(XC_ADC);
//=============中断=======================
ADC_Enable_IT(XC_ADC, ADC_INT_EN_READ_REQ_EN_ENABLE |
ADC_INT_EN_FIFO_ERROR_EN_ENABLE);
NVIC_EnableIRQ(GADC_IRQn);
__ADC_Enable(XC_ADC);
#if SAMPLING_DEBUG || REC_TEST_EN
TIMER_Start_IT(XC_TIMER1);
m_sampling_cb.rec_len_time = 5; // 秒
uint8_t rec_time;
rec_time = m_sampling_cb.rec_len_time;
#endif
DEBUG("start adc\n");
short voice_data = 0;
uint16_t voice_adc_rx_index = 0;
uint32_t uart_byte_delay = pga_adc_data_uart_byte_delay();
while (1) {
#if SAMPLING_DEBUG
if (m_sampling_cb.rx_flag) {
Delay_Ms(500);
DEBUG("sampling: %d.%dKhz\n",
(m_sampling_cb.pga_adc_rx_con / rec_time) / 1000,
(m_sampling_cb.pga_adc_rx_con / rec_time) % 1000);
}
#endif
// ADC_MIC_StartGetValue(XC_ADC, ADC_CHANNEL13_PIN6,&adc_val); //轮询
if (m_sampling_cb.buf_full_flag) {
m_sampling_cb.buf_full_flag = 0;
voice_adc_rx_index = 0;
while (voice_adc_rx_index < MIC_SAMPLING_MAX_LEN) {
voice_data =
m_sampling_cb.mic_adc_buff[!m_sampling_cb.save_buf_index]
[voice_adc_rx_index];
// DEBUG("%d\n",voice_data);
uart_seed_data(voice_data & 0xff);
for (uint16_t i = 0; i < uart_byte_delay; i++)
; // 64M延时
uart_seed_data((voice_data >> 8) & 0xff);
for (uint16_t i = 0; i < uart_byte_delay; i++)
; // 64M延时
voice_adc_rx_index++;
}
// m_sampling_cb.save_buf_index = !m_sampling_cb.save_buf_index;
}
}
}
void Timer1_Callback(void *context)
{
(void)context;
#if SAMPLING_DEBUG
// m_sampling_cb.rx_flag = 1;
#endif
#if REC_TEST_EN
if (m_sampling_cb.rec_len_time) {
// DEBUG("m_sampling_cb.rec_len_time\n");
m_sampling_cb.rec_len_time--;
}
#endif
}
//=========================================PGA+ADC相关的=========================================
void ADC_MIC_StartGetValue(ADC_TypeDef *ADCx, ADC_ChannelTypeDef Channel,
uint16_t *adc_val)
{
uint32_t val;
ADC_FIFO_TypeDef *fifo_val = NULL;
if (__ADC_ChannelGet(XC_ADC) != Channel) {
__ADC_Disable(ADCx);
__ADC_ChannelSet(ADCx, Channel);
__ADC_FIFO_ReqIntLenthSet(ADCx);
__ADC_FIFO_Flush(ADCx);
__ADC_Clear_IT_Flag(ADCx);
__ADC_Enable(ADCx);
}
val = ADCx->INT_RAW;
if (((val & ADC_INT_READ_REQ_INT_Msk) != ADC_INT_READ_REQ_INT_Msk)) {
return;
}
__ADC_Clear_IT_Flag(ADCx);
fifo_val = (ADC_FIFO_TypeDef *)&val;
for (int t = 0; t < ADC_FIFO_CTL_READ_REQ_THRESH_LEN_8; t++) {
val = ADCx->FIFO;
if (fifo_val->chanel_1 != fifo_val->chanel_2) {
// DEBUG("channel error :%d\n",t);
continue;
}
if (fifo_val->chanel_1 != Channel) {
// DEBUG("channel error :%d\n",t);
continue;
}
pga_adc_rx_event_handler(fifo_val->value_1);
pga_adc_rx_event_handler(fifo_val->value_2);
}
*adc_val = fifo_val->value_1;
__ADC_FIFO_Flush(ADCx);
// __ADC_Disable(ADCx);
// __ADC_ChannelSet(ADCx, Channel);
// __ADC_Clear_IT_Flag(XC_ADC);
// __ADC_Enable(XC_ADC);
}
//=================================================================================
void PGA_ADC_Intr_Callback(void)
{
uint32_t adc_int;
uint32_t val;
ADC_FIFO_TypeDef *fifo_val = NULL;
adc_int = XC_ADC->INT;
if (!(adc_int & (ADC_INT_READ_REQ_INT_Msk | ADC_INT_FIFO_ERROR_INT_Msk))) {
return;
}
// 开关ADC会影响采样率,需要重新调整
//__ADC_Disable(XC_ADC);
fifo_val = (ADC_FIFO_TypeDef *)&val;
for (int t = 0; t < ADC_FIFO_CTL_READ_REQ_THRESH_LEN_8; t++) {
val = XC_ADC->FIFO;
if (fifo_val->chanel_1 == ADC_CHANNEL13_PIN6) {
pga_adc_rx_event_handler(fifo_val->value_1);
}
if (fifo_val->chanel_2 == ADC_CHANNEL13_PIN6) {
pga_adc_rx_event_handler(fifo_val->value_2);
}
// if (t==7)
// __ADC_Enable(XC_ADC);
}
// __ADC_Enable(XC_ADC);
__ADC_FIFO_Flush(XC_ADC);
}
void ADC_Intr_Callback(void)
{
ADC_channelswitch_hw_Intr_Callback(); // adc硬件切换
// ADC_channelswitch_sw_Intr_Callback();//adc软件切换
// PGA_ADC_Intr_Callback(); //录音pga
}