bs_bcu_app/drv/drv_stm32f4xx/drv_adc.c

116 lines
3.5 KiB
C

#include "drv_adc.h"
#include "drv_clk.h"
#include "drv_dma.h"
#include "kit_data.h"
#include "kit_debug.h"
#define CR1_SCAN_Set ((uint32_t)0x00000100)
#define CR2_DMA_Set ((uint32_t)0x00000100)
#define CR2_RSTCAL_Set ((uint32_t)0x00000008)
#define CR2_CAL_Set ((uint32_t)0x00000004)
#define CR2_SWSTART_Set ((uint32_t)0x00500000)
#define CR2_CONT_Set ((uint32_t)0x00000002)
#define CR2_ADON_Set ((uint32_t)0x00000001)
#define CFGR_ADCPRE_Reset_Mask ((uint32_t)0xFFFF3FFF)
#define RCC_PCLK2_Div8 ((uint32_t)0x0000C000)
#define SMPR_SMP_Set ((uint32_t)0x00000007)
#define SQR_SQ_Set ((uint32_t)0x0000001F)
#define ADC_ExternalTrigConv_None ((uint32_t)0x000E0000) /*!< For ADC1, ADC2 and ADC3 */
typedef struct
{
DmaStream dma_stream;
DmaChannel dma_channel;
ADC_TypeDef* reg;
}STM32AdcProp;
STM32AdcProp stm32_adc_prop[kAdcDev_End] =
{
{kDma2Stream_0, kDmaChannel_0, ADC1},
{kDma2Stream_3, kDmaChannel_1, ADC2},
{kDma2Stream_0, kDmaChannel_2, ADC3},
};
typedef struct
{
uint16_t arr_len;
uint16_t sample_cnt;
uint16_t *dma_buf;
}AdcItem;
AdcItem adc1_item;
uint8_t drv_adc_init(AdcDev dev, const AdcArray *adc_arr, uint16_t len, uint16_t* dma_buf, uint8_t sample_cnt)
{
uint8_t tmp1_8u, tmp2_8u;
uint32_t i;
__IO uint32_t *sqr[3];
__IO uint32_t *smpr[2];
ADC_TypeDef *reg;
if(dev < kAdcDev_End)
{
adc1_item.arr_len = len;
adc1_item.dma_buf = dma_buf;
adc1_item.sample_cnt = sample_cnt;
reg = stm32_adc_prop[dev].reg;
//dma init
drv_dma_init(stm32_adc_prop[dev].dma_stream, stm32_adc_prop[dev].dma_channel, DMA_CFG_DATA_DIR_P2M | DMA_CFG_CYCLE_EXE | DMA_CFG_DATA_M_I|DMA_CFG_DATA_P_N|DMA_CFG_DATA_LEN_2B, (uint32_t)&reg->DR);
drv_dma_set_buf(stm32_adc_prop[dev].dma_stream, (uint8_t*)dma_buf, len * sample_cnt);
RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN << dev); //开启时钟
//设置ADC通道的转换顺序和采样时间
sqr[0] = &reg->SQR3;
sqr[1] = &reg->SQR2;
sqr[2] = &reg->SQR1;
smpr[0] = &reg->SMPR2;
smpr[1] = &reg->SMPR1;
for(i = 0; i < len ; i++)
{
tmp1_8u = adc_arr[i].channel / 10;
tmp2_8u = adc_arr[i].channel % 10 * 3;
*smpr[tmp1_8u] &= ~(SMPR_SMP_Set << tmp2_8u);
*smpr[tmp1_8u] |= (adc_arr[i].cycle << tmp2_8u);
tmp1_8u = i / 6;
tmp2_8u = i % 6 * 5;
*sqr[tmp1_8u] &= ~(SQR_SQ_Set << tmp2_8u);
*sqr[tmp1_8u] |= (adc_arr[i].channel << tmp2_8u);
}
//设置规则通道数目
reg->SQR1 &= ~KIT_CREAT_BITS(20, 23);
reg->SQR1 |= (uint32_t)(len - 1 ) << 20;
KIT_CLR_BIT(reg->SR, 5);
//设置ADC频率
reg->CR1 |= ADC_CR1_SCAN;
ADC->CCR |= 0x30000; //PCLK2 8分频
//calibration
reg->CR2 |= ADC_CR2_ADON | ADC_CR2_CONT | ADC_CR2_DDS | ADC_CR2_DMA;
reg->CR2 |= ADC_CR2_SWSTART;
}
return true;
}
bool drv_adc_is_overflow(AdcDev dev)
{
return ((stm32_adc_prop[dev].reg->SR & 0x20) != 0);
}
uint16_t drv_adc_get_data(uint8_t idx)
{
uint16_t res = 0;
KIT_ASSERT_PARAM(idx < adc1_item.arr_len);
if(idx < adc1_item.arr_len)
{
res = kit_get_dma_avg_filter_min_max(adc1_item.dma_buf, adc1_item.arr_len, idx, adc1_item.sample_cnt);
}
return res;
}