204 lines
11 KiB
C
204 lines
11 KiB
C
#include "AD1.h"
|
|
|
|
#define IDLE 0x00U /* IDLE state */
|
|
#define SINGLE 0x01U /* SINGLE state */
|
|
#define MEASURE 0x02U /* MESURE state */
|
|
#define CONTINUOUS 0x04U /* CONTINUOUS state */
|
|
|
|
#define CMD_EOL 0xC0000000U /* Command End of list used as the last command in CSL */
|
|
#define CMD_EOL_CONTINUOUS 0x80000000U /* Command End of list with continuous measurement of the whole list used as the last command in CSL */
|
|
#define CLEAR_CMD_EOL 0x3FFFFFFFU /* Constant for clearing the EOL command - for channel methods */
|
|
|
|
static const word Table[] = { /* Table of mask constants */
|
|
0x01U,0x02U,0x04U,0x08U,0x10U,0x20U,0x40U,0x80U,0x0100U};
|
|
#pragma DATA_SEG DEFAULT /* Select data segment "DEFAULT" */
|
|
|
|
static volatile dword CSL[10] __attribute__ ((aligned (4))) = { /* Channel/Sample settings */
|
|
0x00D90000U,0x00D80000U,0x00D70000U,0x00D60000U,0x00D50000U,0x00D40000U,0x00D30000U,0x00D20000U,0xC0D10000U,CMD_EOL};
|
|
static volatile word RVL[18] __attribute__ ((aligned (4))); /* HW DMA result buffer */
|
|
static volatile word OutFlg; /* Measurement finish flag */
|
|
static volatile byte SumChan; /* Number of the measured channels */
|
|
static volatile word ModeFlg; /* Current state of device */
|
|
word AD1_OutV[9];
|
|
|
|
#define CMD_LAST_SAMPLE_PLUS_EOL 0xC0D10000U /* Last sample with command End of list */
|
|
#define CMD_LAST_SAMPLE_PLUS_EOL_CONTINUOUS 0x80D10000U /* Last sample with command End of list */
|
|
|
|
//word ADCVALUE[9]={0,0,0,0,0,0,0,0,0};
|
|
byte ADC_convert_over_flag=0;//AD转换完成标志
|
|
|
|
//AD转换完成中断函数
|
|
void AD1_OnEnd()
|
|
{
|
|
ADC_convert_over_flag=1;//AD转换完成
|
|
/*ADCVALUE[0]=AD1_OutV[0];//
|
|
ADCVALUE[1]=AD1_OutV[1];//
|
|
ADCVALUE[2]=AD1_OutV[2];//
|
|
ADCVALUE[3]=AD1_OutV[3];//
|
|
ADCVALUE[4]=AD1_OutV[4];//
|
|
ADCVALUE[5]=AD1_OutV[5];//
|
|
ADCVALUE[6]=AD1_OutV[6];//
|
|
ADCVALUE[7]=AD1_OutV[7];//
|
|
ADCVALUE[8]=AD1_OutV[8];*/
|
|
}
|
|
|
|
//AD转换错误中断
|
|
void AD1_OnError()
|
|
{
|
|
|
|
}
|
|
|
|
//AD转换终止中断
|
|
void AD1_OnAbort()
|
|
{
|
|
|
|
}
|
|
|
|
//Get AD average value
|
|
word AD_Average_Calculate(word *AD_Array,byte Arrsize)
|
|
{
|
|
byte AD_i=0;
|
|
word AD_Sum=0;
|
|
for(AD_i=0;AD_i<Arrsize;AD_i++)
|
|
{
|
|
AD_Sum+=AD_Array[AD_i];
|
|
}
|
|
return (word)(AD_Sum/Arrsize);
|
|
}
|
|
|
|
void AD1_Init(void)
|
|
{
|
|
OutFlg = 0x00U; /* No measured value */
|
|
ModeFlg = IDLE; /* Device isn't running */
|
|
/* ADC0CTL: ADC_EN=0,ADC_SR=0,FRZ_MOD=0,SWAI=0,ACC_CFG=0,STR_SEQA=0,MOD_CFG=0,CSL_BMOD=0,RVL_BMOD=0,SMOD_ACC=0,AUT_RSTA=0,??=0,??=0,??=0,??=0 */
|
|
setReg16(ADC0CTL, 0x00U); /* Disable periphery to make accesible WP bits in enable mode */
|
|
ADC0CBP = CSL;
|
|
ADC0RBP = RVL;
|
|
/* ADC0FMT: DJM=1,??=0,??=0,??=0,??=0,SRES=2 */
|
|
setReg8(ADC0FMT, 0x82U); /* Set Format register */
|
|
/* ADC0TIM: ??=0,PRS=0 */
|
|
setReg8(ADC0TIM, 0x00U); /* Set Timing register */
|
|
/* ADC0CROFF1: ??=0,CMDRES_OFF1=8 */
|
|
setReg8(ADC0CROFF1, 0x00U); /* Set Command and Result Offset 1 register */
|
|
/* ADC0EIF: IA_EIF=0,CMD_EIF=0,EOL_EIF=0,??=0,TRIG_EIF=0,RSTAR_EIF=1,LDOK_EIF=1,??=0 */
|
|
setReg8(ADC0EIF, 0x06U); /* Clear error flag that could be cleared by write 1 */
|
|
/* ADC0EIE: IA_EIE=1,CMD_EIE=1,EOL_EIE=1,??=1,TRIG_EIE=1,RSTAR_EIE=1,LDOK_EIE=0,??=0 */
|
|
setReg8(ADC0EIE, 0xFCU); /* Set Error interrupt enable register */
|
|
/* ADC0IF: SEQAD_IF=1,CONIF_OIF=1,??=0,??=0,??=0,??=0,??=0,??=0 */
|
|
setReg8(ADC0IF, 0xC0U); /* Clear other flags */
|
|
/* ADC0IE: SEQAD_IE=1,CONIF_OIE=1,??=0,??=0,??=0,??=0,??=0,??=0 */
|
|
setReg8(ADC0IE, 0xC0U); /* Set Abort and Conversion overrun interrupt */
|
|
/* ADC0CONIF: CON_IF15=0,CON_IF14=0,CON_IF13=0,CON_IF12=0,CON_IF11=0,CON_IF10=0,CON_IF9=0,CON_IF8=0,CON_IF7=0,CON_IF6=0,CON_IF5=0,CON_IF4=0,CON_IF3=0,CON_IF2=0,CON_IF1=0,EOL_IF=1 */
|
|
setReg16(ADC0CONIF, 0x01U); /* Clear scan cycle complete flag */
|
|
/* ADC0CONIE: CON_IE15=0,CON_IE14=0,CON_IE13=0,CON_IE12=0,CON_IE11=0,CON_IE10=0,CON_IE9=0,CON_IE8=0,CON_IE7=0,CON_IE6=0,CON_IE5=0,CON_IE4=0,CON_IE3=0,CON_IE2=0,CON_IE1=0,EOL_IE=1 */
|
|
setReg16(ADC0CONIE, 0x01U); /* Set End of list interrupt in Conversion interrupt enable register */
|
|
/* ADC0CTL: ADC_EN=1,ADC_SR=0,FRZ_MOD=0,SWAI=0,ACC_CFG=2,STR_SEQA=0,MOD_CFG=0,CSL_BMOD=1,RVL_BMOD=1,SMOD_ACC=0,AUT_RSTA=0,??=0,??=0,??=0,??=0 */
|
|
setReg16(ADC0CTL, 0x8800U); /* Set Control register */
|
|
}
|
|
|
|
byte AD1_Start(void)
|
|
{
|
|
byte FlwCtrl_Mask = ADC0FLWCTL_RSTA_MASK; /* Add request for the restart of the measurement into flow control register */
|
|
|
|
if (ModeFlg != IDLE) { /* Is the device in running mode? */
|
|
return ERR_BUSY; /* If yes then error */
|
|
}
|
|
ModeFlg = CONTINUOUS; /* Set state of device to the CONTINUOUS mode */
|
|
OutFlg = 0x00U; /* Reset measured value validity */
|
|
/* Note: Next 9 lines are speed optimized */
|
|
AD1_OutV[0] = 0U; /* Set variable for storing measured values to 0 */
|
|
AD1_OutV[1] = 0U; /* Set variable for storing measured values to 0 */
|
|
AD1_OutV[2] = 0U; /* Set variable for storing measured values to 0 */
|
|
AD1_OutV[3] = 0U; /* Set variable for storing measured values to 0 */
|
|
AD1_OutV[4] = 0U; /* Set variable for storing measured values to 0 */
|
|
AD1_OutV[5] = 0U; /* Set variable for storing measured values to 0 */
|
|
AD1_OutV[6] = 0U; /* Set variable for storing measured values to 0 */
|
|
AD1_OutV[7] = 0U; /* Set variable for storing measured values to 0 */
|
|
AD1_OutV[8] = 0U; /* Set variable for storing measured values to 0 */
|
|
if ((ADC0STS & ADC0STS_CSL_SEL_MASK) != 0x00U) { /* Is the appropriate CSL selected? */
|
|
FlwCtrl_Mask |= ADC0FLWCTL_LDOK_MASK; /* If not add change of CSL to the request into flow control register */
|
|
}
|
|
while((ADC0STS & ADC0STS_READY_MASK) == 0x00U) {} /* Wait until the periphery is in idle state */
|
|
ADC0FLWCTL = FlwCtrl_Mask; /* Prepare start of the measurement */
|
|
while(ADC0FLWCTL != 0x00U) {} /* Wait until the restart event is not finished */
|
|
/* ADC0FLWCTL: SEQA=0,TRIG=1,RSTA=0,LDOK=0,??=0,??=0,??=0,??=0 */
|
|
setReg8(ADC0FLWCTL, 0x40U); /* TRIG for start of the measurement */
|
|
return ERR_OK; /* OK */
|
|
}
|
|
|
|
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
|
void interrupt VectorNumber_Vadc0conv_compl ad_convert_over(void)
|
|
{
|
|
word temp0; /* MISRA side effect eliminator */
|
|
word temp1; /* MISRA side effect eliminator */
|
|
volatile word *ResPointer; /* Pointer to result buffer for reading of the current results */
|
|
|
|
/* ADC0CONIF: CON_IF15=0,CON_IF14=0,CON_IF13=0,CON_IF12=0,CON_IF11=0,CON_IF10=0,CON_IF9=0,CON_IF8=0,CON_IF7=0,CON_IF6=0,CON_IF5=0,CON_IF4=0,CON_IF3=0,CON_IF2=0,CON_IF1=0,EOL_IF=1 */
|
|
setReg16(ADC0CONIF, 0x01U); /* Clear scan cycle complete flag */
|
|
if (ModeFlg == IDLE) { /* Is the driver in IDLE mode? */
|
|
return;
|
|
}
|
|
ResPointer = ((ADC0EOLRI & ADC0EOLRI_RVL_EOL_MASK)?(RVL+ADC0CROFF1):RVL); /* Select the result buffer with current results */
|
|
if ((ModeFlg & 0x01U) == 0x00U) { /* Non channel mode active (MEASURE, CONTINUOUS, CONTINUOUS_INT_TRIGGER, CONTINUOUS_EXT_TRIGGER) */
|
|
AD1_OutV[0] = *ResPointer++; /* Save measured value to the output buffer */
|
|
AD1_OutV[1] = *ResPointer++; /* Save measured value to the output buffer */
|
|
AD1_OutV[2] = *ResPointer++; /* Save measured value to the output buffer */
|
|
AD1_OutV[3] = *ResPointer++; /* Save measured value to the output buffer */
|
|
AD1_OutV[4] = *ResPointer++; /* Save measured value to the output buffer */
|
|
AD1_OutV[5] = *ResPointer++; /* Save measured value to the output buffer */
|
|
AD1_OutV[6] = *ResPointer++; /* Save measured value to the output buffer */
|
|
AD1_OutV[7] = *ResPointer++; /* Save measured value to the output buffer */
|
|
AD1_OutV[8] = *ResPointer++; /* Save measured value to the output buffer */
|
|
OutFlg = 0x01FFU; /* Measured values are available */
|
|
if (ModeFlg == MEASURE) { /* Not running in trigger nor continuous mode? */
|
|
ModeFlg = IDLE; /* Set the component to the IDLE mode */
|
|
}
|
|
AD1_OnEnd(); /* If yes then invoke user event */
|
|
} else { /* Channel mode active (SINGLE, CONTINUOUS_INT_CHAN_TRIGGER, CONTINUOUS_EXT_CHAN_TRIGGER) */
|
|
AD1_OutV[SumChan] = *ResPointer; /* Save measured value to the output buffer */
|
|
temp1 = Table[SumChan]; /* Read mask of the measured sample */
|
|
OutFlg |= temp1; /* Measured values are available */
|
|
ModeFlg = IDLE; /* Set the component to the IDLE mode */
|
|
AD1_OnEnd(); /* If yes then invoke user event */
|
|
}
|
|
if (ModeFlg != IDLE) {
|
|
while((ADC0STS & ADC0STS_READY_MASK) == 0x00U) {} /* Wait until the periphery is in idle state */
|
|
/* ADC0FLWCTL: SEQA=0,TRIG=0,RSTA=1,LDOK=0,??=0,??=0,??=0,??=0 */
|
|
setReg8(ADC0FLWCTL, 0x20U); /* RSTA for prepare of the next measurement */
|
|
while(ADC0FLWCTL != 0x00U) {} /* Wait until the restart event is not finished */
|
|
/* ADC0FLWCTL: SEQA=0,TRIG=1,RSTA=0,LDOK=0,??=0,??=0,??=0,??=0 */
|
|
setReg8(ADC0FLWCTL, 0x40U); /* TRIG for start of the measurement */
|
|
}
|
|
}
|
|
|
|
#pragma CODE_SEG AD1_CODE
|
|
|
|
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
|
void interrupt VectorNumber_Vadc0err ad_error(void)
|
|
{
|
|
if ((ADC0EIF & CEASE_ERROR_MASK) != 0U) {
|
|
ModeFlg = IDLE;
|
|
/* ADC0CTL: ADC_SR=1 */
|
|
setReg16Bits(ADC0CTL, 0x4000U); /* Trigger the soft reset */
|
|
} else {
|
|
/* ADC0EIF: IA_EIF=0,CMD_EIF=0,EOL_EIF=0,??=0,TRIG_EIF=0,RSTAR_EIF=1,LDOK_EIF=1,??=0 */
|
|
setReg8(ADC0EIF, 0x06U); /* Clear Non cease error flag */
|
|
/* ADC0IF: SEQAD_IF=0,CONIF_OIF=1,??=0,??=0,??=0,??=0,??=0,??=0 */
|
|
setReg8(ADC0IF, 0x40U); /* Clear flags in the Interrupt flag register */
|
|
}
|
|
AD1_OnError(); /* If yes then invoke user event */
|
|
}
|
|
|
|
#pragma CODE_SEG AD1_CODE
|
|
|
|
#pragma CODE_SEG __NEAR_SEG NON_BANKED
|
|
void interrupt VectorNumber_Vadc0conv_seq_abrt ad_onabort(void)
|
|
{
|
|
/* ADC0IF: SEQAD_IF=1,CONIF_OIF=0,??=0,??=0,??=0,??=0,??=0,??=0 */
|
|
setReg8(ADC0IF, 0x80U); /* Clear Abort flag */
|
|
ModeFlg = IDLE;
|
|
AD1_OnAbort(); /* If yes then invoke user event */
|
|
}
|
|
|
|
#pragma CODE_SEG AD1_CODE
|