EBO-77/Sources/AD1.c
2024-12-23 11:04:44 +08:00

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