v1
This commit is contained in:
@@ -0,0 +1,440 @@
|
||||
/*!
|
||||
* \file adc.c
|
||||
*
|
||||
* \brief Target 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 "adc.h"
|
||||
#include "xc6xxx_hal_adc.h"
|
||||
#include "xc6xxx_hal_adc_dmac.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
uint8_t adc_ch_buff[1000];
|
||||
extern uint32_t adc_val_buff[500];
|
||||
uint16_t adc_con = 0;
|
||||
/*------------------------------------------------------------------------------------
|
||||
Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief adc_demo
|
||||
* @details
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
|
||||
void adc_demo(void)
|
||||
{
|
||||
DEBUG("__ADC_DEMO__\r");
|
||||
DEBUG("XC_ADC->RF_CTL:%x\n", XC_ADC->RF_CTL);
|
||||
|
||||
uint16_t integer;
|
||||
uint16_t decimal;
|
||||
uint16_t adc_val = 0;
|
||||
adc_cfg adc_cfg;
|
||||
|
||||
/*----- Special Pin -----*/
|
||||
/*< SWD 和 SWCK 引脚也可以作为 ADC 使用,
|
||||
注意 PIN 脚的功能重映射 >*/
|
||||
// GPIO_MuxCtl(12,1);
|
||||
// GPIO_MuxCtl(13,1);
|
||||
/*-----------------------*/
|
||||
|
||||
// *((volatile unsigned *)(0x4002F000 + 0x03C)) &= ~(0x1<<14);
|
||||
|
||||
adc_cfg.Freq = ADC_FREQ_2M;
|
||||
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_cfg.ExtSampleNum = ADC_SAMPLE_NUM_8;
|
||||
adc_cfg.ExtTriggerSel = ADC_TRIGGER_SEL_PWM0;
|
||||
|
||||
ADC_Init(XC_ADC, &adc_cfg);
|
||||
|
||||
while (1) {
|
||||
DEBUG("XC_ADC->RF_CTL22:%x\n", XC_ADC->RF_CTL);
|
||||
ADC_StartGetValue(XC_ADC, ADC_CHANNEL4_PIN0, &adc_val);
|
||||
|
||||
if (adc_cfg.RefVol == ADC_REF_VOL_3_3V) {
|
||||
integer = ((adc_val) * 3.3 * 100) / (1.0 * 4096) / 100;
|
||||
decimal = ((uint32_t)((adc_val * 3.3 * 100) / 4096) % 100);
|
||||
|
||||
DEBUG("3.3v ref adc_vol=%d.%d ,adc_val=%d\n", integer, decimal,
|
||||
adc_val);
|
||||
} else if (adc_cfg.RefVol == ADC_REFVOL_2_33V) {
|
||||
integer = ((adc_val) * 2.33 * 100) / (1.0 * 4096) / 100;
|
||||
decimal = ((uint32_t)((adc_val * 2.33 * 100) / 4096) % 100);
|
||||
DEBUG("2.33v ref adc_vol=%d.%d ,adc_val=%d\n", integer, decimal,
|
||||
adc_val);
|
||||
}
|
||||
Delay_Ms(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief adc_channel_sw_demo
|
||||
* @details
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
|
||||
void adc_channelswitch_sw_demo(void)
|
||||
{
|
||||
DEBUG("ADC channelswitch sw demo\n");
|
||||
|
||||
uint16_t integer;
|
||||
uint16_t decimal;
|
||||
adc_cfg adc_cfg;
|
||||
Delay_Ms(500);
|
||||
|
||||
*((volatile unsigned int *)(0x400001BC)) &=
|
||||
~(1 << 12); // 防止GPIO6被接到运放,导致GADC\上拉无效问题
|
||||
|
||||
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 = 20;
|
||||
GPIO_Init(&GPIO_InitCfg);
|
||||
|
||||
GPIO_InitCfg.Pin = 18;
|
||||
GPIO_Init(&GPIO_InitCfg);
|
||||
|
||||
GPIO_InitCfg.Pin = 19;
|
||||
GPIO_Init(&GPIO_InitCfg);
|
||||
|
||||
GPIO_InitCfg.Pin = 0;
|
||||
GPIO_Init(&GPIO_InitCfg);
|
||||
|
||||
GPIO_FunSel(3, UART0_TX); // 更换打印口
|
||||
GPIO_FunSel(2, UART0_RX);
|
||||
|
||||
// *((volatile unsigned *)(0x4002F000 + 0x03C)) &= ~(0x1<<14);
|
||||
|
||||
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_4;
|
||||
adc_cfg.ExtTriggerSel = ADC_TRIGGER_SEL_PWM0;
|
||||
|
||||
ADC_Init(XC_ADC, &adc_cfg);
|
||||
|
||||
__ADC_ChannelSet(XC_ADC, ADC_CHANNEL4_PIN0);
|
||||
|
||||
//==================中断设置=========================
|
||||
ADC_Enable_IT(XC_ADC, ADC_INT_EN_READ_REQ_EN_ENABLE |
|
||||
ADC_INT_EN_FIFO_ERROR_EN_ENABLE);
|
||||
NVIC_EnableIRQ(GADC_IRQn);
|
||||
//===========================================
|
||||
|
||||
__ADC_FIFO_ReqIntLenthSet(XC_ADC);
|
||||
|
||||
__ADC_FIFO_Flush(XC_ADC);
|
||||
|
||||
__ADC_Clear_IT_Flag(XC_ADC);
|
||||
|
||||
// ADC DMA enable
|
||||
// XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_DMAS_ON_ENABLE;
|
||||
// XC_ADC->MAIN_CTL |= ADC_MAIN_CTL_DMAS_ON_ENABLE;
|
||||
// ADC_DMA_Init();
|
||||
|
||||
__ADC_Enable(XC_ADC);
|
||||
|
||||
uint32_t val;
|
||||
ADC_FIFO_TypeDef *fifo_val = NULL;
|
||||
|
||||
while (1) {
|
||||
|
||||
if (adc_con >= 500 && adc_con != 0xffff) {
|
||||
fifo_val = (ADC_FIFO_TypeDef *)&val;
|
||||
|
||||
for (uint16_t i = 0; i < 500; i++) {
|
||||
val = adc_val_buff[i];
|
||||
|
||||
integer = ((uint32_t)(fifo_val->value_1) * (3.3 * 100)) /
|
||||
(1.0 * 4095) / 100;
|
||||
decimal =
|
||||
((uint32_t)((fifo_val->value_1 * (3.3 * 100)) / 4095) %
|
||||
100);
|
||||
DEBUG("i_dex1: %4d ch : %d val: %d adc_vol=%d.%02dV\n", i,
|
||||
fifo_val->chanel_1, fifo_val->value_1, integer, decimal);
|
||||
|
||||
integer = ((uint32_t)(fifo_val->value_2) * (3.3 * 100)) /
|
||||
(1.0 * 4095) / 100;
|
||||
decimal =
|
||||
((uint32_t)((fifo_val->value_2 * (3.3 * 100)) / 4095) %
|
||||
100);
|
||||
DEBUG("i_dex2: %4d ch : %d val: %d adc_vol=%d.%02dV\n", i,
|
||||
fifo_val->chanel_2, fifo_val->value_2, integer, decimal);
|
||||
|
||||
if ((i % 2))
|
||||
DEBUG("\r\n\r\n");
|
||||
// DEBUG("i_dex: %4d ch : %d val: %d\n",i,
|
||||
// adc_ch_buff[i],adc_val_buff[i]);
|
||||
}
|
||||
adc_con = 0xffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief adc_channel_sw_demo
|
||||
* @details
|
||||
* @param void
|
||||
* @retval void
|
||||
*/
|
||||
void adc_channelswitch_hw_demo(void)
|
||||
{
|
||||
DEBUG("ADC channelswitch hw demo\n");
|
||||
|
||||
uint16_t integer;
|
||||
uint16_t decimal;
|
||||
adc_cfg adc_cfg;
|
||||
Delay_Ms(500);
|
||||
|
||||
*((volatile unsigned int *)(0x400001BC)) &=
|
||||
~(1 << 12); // 防止GPIO6被接到运放,导致GADC\上拉无效问题
|
||||
|
||||
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 = 20;
|
||||
GPIO_Init(&GPIO_InitCfg);
|
||||
|
||||
GPIO_InitCfg.Pin = 18;
|
||||
GPIO_Init(&GPIO_InitCfg);
|
||||
|
||||
GPIO_InitCfg.Pin = 19;
|
||||
GPIO_Init(&GPIO_InitCfg);
|
||||
|
||||
GPIO_InitCfg.Pin = 0;
|
||||
GPIO_Init(&GPIO_InitCfg);
|
||||
|
||||
GPIO_FunSel(3, UART0_TX); // 更换打印口
|
||||
GPIO_FunSel(2, UART0_RX);
|
||||
|
||||
// *((volatile unsigned *)(0x4002F000 + 0x03C)) &= ~(0x1<<14);
|
||||
|
||||
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_4;
|
||||
adc_cfg.ExtTriggerSel = ADC_TRIGGER_SEL_PWM0;
|
||||
|
||||
ADC_Init(XC_ADC, &adc_cfg);
|
||||
|
||||
XC_ADC->TIMER1 = 62;
|
||||
XC_ADC->TIMER0 = 1;
|
||||
|
||||
//=============设置需要切换的通道(1---4通道,1个bit表示一个通道)=============
|
||||
XC_ADC->CHAN_CTL &= ~ADC_CHAN_CTL_CHAN_AUTO_Msk;
|
||||
XC_ADC->CHAN_CTL |= 0xf << 8;
|
||||
|
||||
// 使能ADC自动切换
|
||||
XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
|
||||
XC_ADC->MAIN_CTL |=
|
||||
ADC_MAIN_CTL_AUTO_SW_ENABLE; //(ADC_MAIN_CTL_AUTO_SW_ENABLE<<ADC_MAIN_CTL_AUTO_SW_Pos);
|
||||
|
||||
//==================中断设置=========================
|
||||
ADC_Enable_IT(XC_ADC, ADC_INT_EN_READ_REQ_EN_ENABLE |
|
||||
ADC_INT_EN_FIFO_ERROR_EN_ENABLE);
|
||||
NVIC_EnableIRQ(GADC_IRQn);
|
||||
//===========================================
|
||||
|
||||
__ADC_FIFO_ReqIntLenthSet(XC_ADC);
|
||||
|
||||
__ADC_FIFO_Flush(XC_ADC);
|
||||
|
||||
__ADC_Clear_IT_Flag(XC_ADC);
|
||||
|
||||
// ADC DMA enable
|
||||
// XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_DMAS_ON_ENABLE;
|
||||
// XC_ADC->MAIN_CTL |= ADC_MAIN_CTL_DMAS_ON_ENABLE;
|
||||
// ADC_DMA_Init();
|
||||
|
||||
__ADC_Enable(XC_ADC);
|
||||
|
||||
uint32_t val;
|
||||
ADC_FIFO_TypeDef *fifo_val = NULL;
|
||||
|
||||
while (1) {
|
||||
|
||||
if (adc_con >= 500 && adc_con != 0xffff) {
|
||||
fifo_val = (ADC_FIFO_TypeDef *)&val;
|
||||
|
||||
for (uint16_t i = 0; i < 500; i++) {
|
||||
val = adc_val_buff[i];
|
||||
|
||||
integer = ((uint32_t)(fifo_val->value_1) * (3.3 * 100)) /
|
||||
(1.0 * 4095) / 100;
|
||||
decimal =
|
||||
((uint32_t)((fifo_val->value_1 * (3.3 * 100)) / 4095) %
|
||||
100);
|
||||
DEBUG("i_dex1: %4d ch : %d val: %d adc_vol=%d.%02dV\n", i,
|
||||
fifo_val->chanel_1, fifo_val->value_1, integer, decimal);
|
||||
|
||||
integer = ((uint32_t)(fifo_val->value_2) * (3.3 * 100)) /
|
||||
(1.0 * 4095) / 100;
|
||||
decimal =
|
||||
((uint32_t)((fifo_val->value_2 * (3.3 * 100)) / 4095) %
|
||||
100);
|
||||
DEBUG("i_dex2: %4d ch : %d val: %d adc_vol=%d.%02dV\n", i,
|
||||
fifo_val->chanel_2, fifo_val->value_2, integer, decimal);
|
||||
|
||||
if ((i % 2))
|
||||
DEBUG("\r\n\r\n");
|
||||
// DEBUG("i_dex: %4d ch : %d val: %d\n",i,
|
||||
// adc_ch_buff[i],adc_val_buff[i]);
|
||||
}
|
||||
adc_con = 0xffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ADC_channelswitch_sw_Intr_Callback(void)
|
||||
{
|
||||
uint32_t adc_int;
|
||||
static uint8_t adc_start = 0;
|
||||
|
||||
adc_int = XC_ADC->INT;
|
||||
|
||||
if (!(adc_int & (ADC_INT_READ_REQ_INT_Msk | ADC_INT_FIFO_ERROR_INT_Msk))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (adc_con >= 500) {
|
||||
//__ADC_Clear_IT_Flag(XC_ADC);
|
||||
return;
|
||||
}
|
||||
//__ADC_Disable(XC_ADC);
|
||||
|
||||
__ADC_Clear_IT_Flag(XC_ADC);
|
||||
|
||||
if (++adc_start > 3)
|
||||
adc_start = 0;
|
||||
|
||||
switch (adc_start) {
|
||||
case 0:
|
||||
__ADC_ChannelSet(XC_ADC, ADC_CHANNEL1_PIN20);
|
||||
|
||||
GPIO_Output_Low(1);
|
||||
GPIO_Output_High(1);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
__ADC_ChannelSet(XC_ADC, ADC_CHANNEL11_PIN2);
|
||||
// XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
__ADC_ChannelSet(XC_ADC, ADC_CHANNEL4_PIN0);
|
||||
// XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
__ADC_ChannelSet(XC_ADC, ADC_CHANNEL6_PIN4);
|
||||
// XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
|
||||
break;
|
||||
|
||||
// case 4:
|
||||
// __ADC_ChannelSet(XC_ADC, ADC_CHANNEL7_PIN5);
|
||||
// //XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
|
||||
// break;
|
||||
//
|
||||
// case 5:
|
||||
// __ADC_ChannelSet(XC_ADC, ADC_CHANNEL2_PIN19);
|
||||
// //XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
|
||||
// break;
|
||||
//
|
||||
// case 6:
|
||||
// __ADC_ChannelSet(XC_ADC, ADC_CHANNEL3_PIN18);
|
||||
// //XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
|
||||
// break;
|
||||
//
|
||||
// case 7:
|
||||
// __ADC_ChannelSet(XC_ADC, ADC_CHANNEL4_PIN0);
|
||||
// //XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
|
||||
// break;
|
||||
}
|
||||
|
||||
for (int t = 0; t < ADC_FIFO_CTL_READ_REQ_THRESH_LEN_2; t++) {
|
||||
// val = XC_ADC->FIFO;
|
||||
adc_val_buff[adc_con] = XC_ADC->FIFO;
|
||||
adc_con++;
|
||||
}
|
||||
|
||||
//__ADC_Enable(XC_ADC);
|
||||
//__ADC_FIFO_Flush(XC_ADC);
|
||||
//__ADC_Clear_IT_Flag(XC_ADC);
|
||||
}
|
||||
|
||||
void ADC_channelswitch_hw_Intr_Callback(void)
|
||||
{
|
||||
uint32_t adc_int;
|
||||
|
||||
adc_int = XC_ADC->INT;
|
||||
|
||||
if (!(adc_int & (ADC_INT_READ_REQ_INT_Msk | ADC_INT_FIFO_ERROR_INT_Msk))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (adc_con >= 500) {
|
||||
return;
|
||||
}
|
||||
//__ADC_Disable(XC_ADC);
|
||||
|
||||
__ADC_Clear_IT_Flag(XC_ADC);
|
||||
|
||||
for (int t = 0; t < ADC_FIFO_CTL_READ_REQ_THRESH_LEN_2; t++) {
|
||||
adc_val_buff[adc_con] = XC_ADC->FIFO;
|
||||
adc_con++;
|
||||
}
|
||||
}
|
||||
|
||||
// void ADC_Intr_Callback(void)
|
||||
//{
|
||||
// ADC_channelswitch_hw_Intr_Callback(); //adc硬件切换
|
||||
//// ADC_channelswitch_sw_Intr_Callback();//adc软件切换
|
||||
//// PGA_ADC_Intr_Callback(); //录音pga
|
||||
//}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*!
|
||||
* \file adc.h
|
||||
*
|
||||
* \brief The head file of adc.c
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __ADC_H__
|
||||
#define __ADC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void adc_demo(void);
|
||||
void adc_channelswitch_sw_demo(void);
|
||||
void adc_channelswitch_hw_demo(void);
|
||||
void mic_pga_adc_demo(void);
|
||||
void ADC_channelswitch_hw_Intr_Callback(void);
|
||||
void ADC_channelswitch_sw_Intr_Callback(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ADC_H__ */
|
||||
@@ -0,0 +1,610 @@
|
||||
/*!
|
||||
* \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
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*!
|
||||
* \file pga_adc.h
|
||||
*
|
||||
* \brief The head file of pga_adc.h
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* _ __ _ ________ _
|
||||
* | |/ /(_)___ / ____/ /_ (_)___
|
||||
* | // / __ \/ / / __ \/ / __ \
|
||||
* / |/ / / / / /___/ / / / / /_/ /
|
||||
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
|
||||
* /_/
|
||||
* (C) 2022-2025 XinChip
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author ( XinChip ) Alex-J
|
||||
*
|
||||
* \author ( XinChip )
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __BSP_PGA_ADC_H_
|
||||
#define __BSP_PGA_ADC_H_
|
||||
|
||||
/*-----------------------------------------------------------------------------------
|
||||
INCLUDE HEADE FILES
|
||||
------------------------------------------------------------------------------------*/
|
||||
#include "stdint.h"
|
||||
#include "xc60xx.h"
|
||||
/*------------------------------------------------------------------------------------
|
||||
Macros
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
#define SAMPLING_DEBUG 1
|
||||
#define REC_TEST_EN 1 //录音测试,定时录音
|
||||
|
||||
#define ADC_CLOCK_FREQ_8M ADC_CLK_DIV_0 // ADC_FREQ_8M
|
||||
#define ADC_CLOCK_FREQ_4M ADC_CLK_DIV_2 // ADC_FREQ_4M
|
||||
#define ADC_CLOCK_FREQ_2M ADC_CLK_DIV_4 // ADC_FREQ_2M
|
||||
#define ADC_CLOCK_FREQ_1M ADC_CLK_DIV_8 // ADC_FREQ_1M
|
||||
#define ADC_CLOCK_FREQ_500K ADC_CLK_DIV_16 // ADC_FREQ_500K
|
||||
|
||||
#define ADC_FREQ_CLOCK ADC_CLK_DIV_4 // ADC时钟选择
|
||||
|
||||
#define MIC_SAMPLING_8K 0
|
||||
#define MIC_SAMPLING_16K 1
|
||||
#define SAMPLING_TYPE MIC_SAMPLING_16K
|
||||
|
||||
#define MIC_SAMPLING_MAX_LEN 1 * 256 //缓冲长度,根据需求调节
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
TypeDef
|
||||
-------------------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct {
|
||||
short mic_adc_buff[2][MIC_SAMPLING_MAX_LEN]; //双缓存buff,方便读取以及采样
|
||||
uint16_t pga_adc_rx_index; //缓存buff下标
|
||||
uint8_t
|
||||
save_buf_index; //双缓存buff下标,存放第几个mic_adc_buff[save_buf_index][]
|
||||
uint8_t buf_full_flag;
|
||||
|
||||
uint8_t freq_con; //采样率计算
|
||||
|
||||
#if SAMPLING_DEBUG
|
||||
uint32_t pga_adc_rx_con;
|
||||
uint8_t rx_flag;
|
||||
#endif
|
||||
|
||||
#if REC_TEST_EN || SAMPLING_DEBUG
|
||||
uint8_t rec_len_time;
|
||||
#endif
|
||||
|
||||
} Mic_sampling_cb;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Global Variables
|
||||
-------------------------------------------------------------------------------------*/
|
||||
extern Mic_sampling_cb m_sampling_cb;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Exported Functions
|
||||
-------------------------------------------------------------------------------------*/
|
||||
void audio_adc_rx_dma_event_handler(void);
|
||||
void pga_adc_rx_event_handler(uint16_t pga_adc_val);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user