202 lines
7.4 KiB
C
202 lines
7.4 KiB
C
/**
|
|
* @copyright 2015 Indie Semiconductor.
|
|
*
|
|
* This file is proprietary to Indie Semiconductor.
|
|
* All rights reserved. Reproduction or distribution, in whole
|
|
* or in part, is forbidden except by express written permission
|
|
* of Indie Semiconductor.
|
|
*
|
|
* @file adc_device.c
|
|
* @Author: Jack.Pan
|
|
* @E-mail:jack.pan@indiemicro.com
|
|
* @Date: 2020/09/10
|
|
*/
|
|
|
|
#include <adc_device.h>
|
|
#include <isrfuncs.h>
|
|
#include <appConfig.h>
|
|
#include <motorControlTask.h>
|
|
#include <pwm_aux_device.h>
|
|
|
|
static ADCMeasureParam_t adcMeasParamm = {ADC_MEASURE_ITEM_NONE, 0};
|
|
static adc_cb_func_t adcCallback = NULL;
|
|
static uint16_t adcResult[10];
|
|
|
|
void ADC_Handler(void)
|
|
{
|
|
if (adcCallback !=NULL){
|
|
if(adcMeasParamm.item == ADC_MEASURE_ITEM_VAMP){
|
|
adcResult[0] = (uint16_t)(SAR_CTRL_SFRS->DATA[0].DATA & 0x07FFU);//VAMP
|
|
adcResult[1] = (uint16_t)(SAR_CTRL_SFRS->DATA[1].DATA & 0x0FFFU);//VBAT
|
|
adcResult[2] = (uint16_t)(SAR_CTRL_SFRS->DATA[2].DATA & 0x0FFFU);//VPB3
|
|
adcResult[3] = (uint16_t)(SAR_CTRL_SFRS->DATA[3].DATA & 0x0FFFU);//VPC4
|
|
}else{
|
|
adcResult[1] = 160;//(uint16_t)(SAR_CTRL_SFRS->DATA[1].DATA & 0x0FFFU);//VBAT
|
|
adcResult[2] = 150;//(uint16_t)(SAR_CTRL_SFRS->DATA[2].DATA & 0x0FFFU);//VTEMP
|
|
}
|
|
adcCallback(adcMeasParamm, adcResult);
|
|
}
|
|
SAR_CTRL_SFRS->SARINT.CLEAR.INT_CONV_DONE_CLR = 1U;
|
|
SAR_CTRL_SFRS->SARCTRL.SARENAREQ = 1U;
|
|
}
|
|
|
|
void ADC_GeneralInit(void)
|
|
{
|
|
#if SYS_MAIN_CLOCK_DIV == CLOCK_DIV_1
|
|
SAR_CTRL_SFRS->SARCLKDIV = 4U;
|
|
#elif SYS_MAIN_CLOCK_DIV == CLOCK_DIV_2
|
|
SAR_CTRL_SFRS->SARCLKDIV = 2U;
|
|
#else
|
|
SAR_CTRL_SFRS->SARCLKDIV = 1U;
|
|
#endif
|
|
|
|
for (uint8_t i = 0U; i < 10U; i++){
|
|
|
|
SAR_CTRL_SFRS->ADCCHCTRL2R.WORD &= ~((uint32_t)0x03UL << (i*2+8U));//clear
|
|
SAR_CTRL_SFRS->ADCCHCTRL2R.WORD |= ((uint32_t)ADC_REF_VDD_3V3 << (i*2+8U));//set vref 3v3
|
|
|
|
SAR_CTRL_SFRS->ADCCHCTRL0R.WORD &= ~((uint32_t)0x03UL << (i*2+0U));
|
|
SAR_CTRL_SFRS->ADCCHCTRL0R.WORD |= ((uint32_t)ADC_AFE_INPUT_ALL_EXT << (i*2+0U));
|
|
|
|
SAR_CTRL_SFRS->ADCCHCTRL0R.WORD &= ~((uint32_t)0x01UL << (i*1+20U));
|
|
SAR_CTRL_SFRS->ADCCHCTRL0R.WORD |= ((uint32_t)ADC_AFE_GAIN_31_OF_32 << (i*1+20U));
|
|
}
|
|
|
|
SAR_CTRL_SFRS->ADCCHCTRL0R.SARINPUTGAINCH4 = ADC_AFE_GAIN_22_OF_32;
|
|
|
|
SAR_CTRL_SFRS->SARINT.ENABLE.INT_CONV_DONE_ENA = 0;//1:Convert Done Interrupt Enable.
|
|
SAR_CTRL_SFRS->SARINT.ENABLE.INT_TRIG_CLASH_ENA = 0;//1:Trigger Clash Interrupt Enable.
|
|
SAR_CTRL_SFRS->SARINT.CLEAR.INT_CONV_DONE_CLR = 1;
|
|
SAR_CTRL_SFRS->SARINT.CLEAR.INT_TRIG_CLASH_CLR = 1;
|
|
}
|
|
|
|
void ADC_Init(AdcMeasureItem_t item, uint8_t channel)
|
|
{
|
|
ADCTriggerParam_t source;
|
|
adcMeasParamm.item = item;
|
|
adcMeasParamm.channel = channel;
|
|
switch(item){
|
|
case ADC_MEASURE_ITEM_VAMP:/* 1x */
|
|
|
|
SAR_CTRL_SFRS->SARCFG.TRIGDLY = 15U;
|
|
// SAR_CTRL_SFRS->SARCFG.TRIGSEL = 1U;//0x1: Select PWMAUX_TRIGSEL
|
|
// SAR_CTRL_SFRS->SARCFG.PWMAUXCHSEL = 0U;//0x0: Select PWMAUX Channel 0
|
|
// SAR_CTRL_SFRS->SARCFG.PWMAUXTRIGSEL = 4U;// 0x4: Triggered by PWM AUX counter 0 period. 0x8: Triggered by PWM AUX counter 1 period.
|
|
// SAR_CTRL_SFRS->SARCFG.TRIGSRC = 8U;//Triggered through hardware, either select from TRIGSRC[2:0] or from PWMAUX_TRIGSEL.TRIGSRC[2:0]=0x0: Triggered by the PWM compare trigger0.
|
|
|
|
source.selection = ADC_TRIGGER_SEL_PWM_AUX_TRIGSRC;
|
|
source.channel = ADC_PWMAUX_CHN0;
|
|
source.pwmAux = ADC_PWMAUX_TRIG_SRC_PWM_PERIOD0;
|
|
source.general = ADC_TRIG_SRC_PWM_CMP0;
|
|
/*
|
|
SYSCTRLA_SFRS->CSACTRLR.CSAGAINSEL = 0U;//5 gain
|
|
SYSCTRLA_SFRS->CSACTRLR.CSAZEROEN = 0U;
|
|
SYSCTRLA_SFRS->CSACTRLR.CSAPOWEN = 1U;
|
|
*/
|
|
SAR_CTRL_SFRS->AFECTRL.SARAFEEN = 1;//ADC AFE Enable. adc afe enable. If vinp, vinn and vin vcm all choose external, adc afe should be disabled: adc_adc_en=0, otherwise, adc afe must be enabled: adc_afe_en=1.
|
|
SAR_CTRL_SFRS->AFECTRL.ADCSELVINVCMEXT = 0;//Select External Inputs to ADC. choose ADC input common voltage. 0: choose internal vin_vcm, equals to (vinp+vinn)/2; 1: choose external vin_vcm, for PN detect.
|
|
SAR_CTRL_SFRS->AFECTRL.SARPREAMPEN = 1;// adc pre-amp enable.
|
|
|
|
SAR_CTRL_SFRS->ADCCHCONF.CH1SEL = ADC_CH_SEL_TSENSOR_GND;//
|
|
SAR_CTRL_SFRS->ADCCHCONF.CH2SEL = ADC_CH_SEL_VBAT_GND;
|
|
SAR_CTRL_SFRS->ADCCHCONF.CH3SEL = ADC_CH_SEL_PB6_GND;
|
|
SAR_CTRL_SFRS->ADCCHCONF.CH4SEL = ADC_CH_SEL_PB7_GND;
|
|
|
|
SAR_CTRL_SFRS->ADCCHCTRL1R.SAMPCYCCH1 = 15U;//max 15
|
|
SAR_CTRL_SFRS->SARCTRL.DIGRESET = 0X1U;
|
|
SAR_CTRL_SFRS->ADCCHCONF.SEQCNT = ADC_SQ_CH1_2_CH4;//0x3: CH1->CH2->CH3
|
|
break;
|
|
case ADC_MEASURE_ITEM_VBAT_VTEMP:/* 1x */
|
|
SAR_CTRL_SFRS->ADCCHCONF.CH2SEL = ADC_CH_SEL_VBAT_GND;
|
|
SAR_CTRL_SFRS->ADCCHCONF.CH3SEL = ADC_CH_SEL_TSENSOR_GND;
|
|
SAR_CTRL_SFRS->ADCCHCONF.SEQCNT = (uint8_t)ADC_SQ_CH1_2_CH3;
|
|
source.selection = ADC_TRIGGER_SEL_GENERAL_TRIGSRC;
|
|
source.general = ADC_TRIG_SRC_SOFT_INPUT;
|
|
|
|
break;
|
|
|
|
case ADC_MEASURE_ITEM_VBG: /*1x */
|
|
SAR_CTRL_SFRS->ADCCHCONF.CH1SEL = ADC_CH_SEL_REF_GND;
|
|
SAR_CTRL_SFRS->ADCCHCONF.SEQCNT = (uint8_t)ADC_SQ_CH1_2_CH1;
|
|
source.selection = ADC_TRIGGER_SEL_GENERAL_TRIGSRC;
|
|
source.general = ADC_TRIG_SRC_SOFT_INPUT;
|
|
break;
|
|
|
|
case ADC_MEASURE_ITEM_VBAT: /*1/16x */
|
|
SAR_CTRL_SFRS->ADCCHCONF.CH1SEL = ADC_CH_SEL_VBAT_GND;
|
|
SAR_CTRL_SFRS->ADCCHCONF.SEQCNT = (uint8_t)ADC_SQ_CH1_2_CH1;
|
|
source.selection = ADC_TRIGGER_SEL_GENERAL_TRIGSRC;
|
|
source.general = ADC_TRIG_SRC_SOFT_INPUT;
|
|
break;
|
|
|
|
case ADC_MEASURE_ITEM_VDD1V5:
|
|
SAR_CTRL_SFRS->ADCCHCONF.CH1SEL = ADC_CH_SEL_1V5_GND;
|
|
SAR_CTRL_SFRS->ADCCHCONF.SEQCNT = (uint8_t)ADC_SQ_CH1_2_CH1;
|
|
source.selection = ADC_TRIGGER_SEL_GENERAL_TRIGSRC;
|
|
source.general = ADC_TRIG_SRC_SOFT_INPUT;
|
|
break;
|
|
default:
|
|
|
|
break;
|
|
}
|
|
SAR_CTRL_SFRS->SARCFG.TRIGSEL = source.selection;
|
|
if (source.selection == ADC_TRIGGER_SEL_GENERAL_TRIGSRC){
|
|
SAR_CTRL_SFRS->SARCFG.TRIGSRC = source.general;
|
|
}else{
|
|
|
|
SAR_CTRL_SFRS->SARCFG.PWMAUXCHSEL = source.channel;
|
|
SAR_CTRL_SFRS->SARCFG.PWMAUXTRIGSEL = source.pwmAux;
|
|
SAR_CTRL_SFRS->SARCFG.TRIGSRC = source.general;
|
|
SAR_CTRL_SFRS->SARCFG.ROUND = 1U;//0x1: Negative code+1
|
|
}
|
|
}
|
|
|
|
void ADC_UnInit(AdcMeasureItem_t item)
|
|
{
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief Register a callback function to ADC interrupt handler.
|
|
*
|
|
* @param dev Pointer to the ADC device.
|
|
* @param cb The callback function to be registered.
|
|
* @return 0 for success or error code upon a failure.
|
|
*/
|
|
void ADC_RegisterIRQ(adc_cb_func_t callback)
|
|
{
|
|
adcCallback = callback;
|
|
SAR_CTRL_SFRS->SARINT.CLEAR.INT_CONV_DONE_CLR = 1U;
|
|
SAR_CTRL_SFRS->SARINT.ENABLE.INT_CONV_DONE_ENA = 1U;
|
|
NVIC_EnableIRQ(ADC_IRQn);
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief Unregister a callback function to ADC interrupt handler.
|
|
*
|
|
* @param dev Pointer to the ADC device.
|
|
* @param cb The callback function to be unregistered.
|
|
* @return 0 for success or error code upon a failure.
|
|
*/
|
|
void ADC_UnregisterIRQ(void)
|
|
{
|
|
adcCallback = NULL;
|
|
SAR_CTRL_SFRS->SARINT.CLEAR.INT_CONV_DONE_CLR = 1U;
|
|
SAR_CTRL_SFRS->SARINT.ENABLE.INT_CONV_DONE_ENA = 0U;
|
|
NVIC_DisableIRQ(ADC_IRQn);
|
|
}
|
|
|
|
void ADC_Start(void)
|
|
{
|
|
SAR_CTRL_SFRS->SARINT.CLEAR.INT_CONV_DONE_CLR = 1U;
|
|
SAR_CTRL_SFRS->SARCTRL.SARENAREQ = 1U;
|
|
SAR_CTRL_SFRS->SARCTRL.CONVERT = 1U;
|
|
}
|
|
|
|
ADCMeasureParam_t ADC_GetadcMeasParamm(void){
|
|
return adcMeasParamm;
|
|
}
|
|
|