📄 dac.c
字号:
/*--------------------------------------------------------*/
/* WQ21ST SOFTWARE STUDIO. */
/*--------------------------------------------------------*/
/* Offchip DAC test for EVM320LF2407 */
/* This test requires a loopback connector */
/*--------------------------------------------------------*/
/* */
/* filename: dac.c */
/* original: 08/20/2001 by: WQ */
/* last update: 08/28/2000 by: WQ */
/*--------------------------------------------------------*/
#include "dac.h"
#include "ioreg.h"
#include "prot2407.h"
#include "led.h"
unsigned int DacSawTooth( void );
volatile unsigned int dacdata;
#define ADCTRL1 0x70A0
#define ADCTRL2 0X70A1
#define MAX_CONV 0x70A2
#define CHSELSEQ1 0x70A3
#define CHSELSEQ2 0x70A4
#define CHSELSEQ3 0x70A5
#define CHSELSEQ4 0x70A6
#define AUTO_SEQ_SR 0x70A7
#define RESULT0 0x70A8
#define RESULT1 0x70A9
#define RESULT2 0x70AA
#define RESULT3 0x70AB
#define RESULT4 0x70AC
#define RESULT5 0x70AD
#define RESULT6 0x70AE
#define RESULT7 0x70AF
#define RESULT8 0x70B0
#define RESULT9 0x70B1
#define RESULT10 0x70B2
#define RESULT11 0x70B3
#define RESULT12 0x70B4
#define RESULT13 0x70B5
#define RESULT14 0x70B6
#define RESULT15 0x70B7
#define CALIBRATION 0x70B8
#define ADC_FTEST_ENA 0x0001
#define ADC_HI_LO 0x0002
#define ADC_BRG_ENA 0x0004
#define ADC_CAL_ENA 0x0008
#define ADC_SEQ_CASC 0x0010
#define ADC_INT_PRI 0x0020
#define ADC_CONT_RUN 0x0040
#define ADC_CPS 0x0080
#define ADC_ACQ_PS0 0x0100
#define ADC_ACQ_PS1 0x0200
#define ADC_ACQ_PS2 0x0400
#define ADC_ACQ_PS3 0x0800
#define ADC_FREE 0x1000
#define ADC_SOFT 0x2000
#define ADC_RESET 0x4000
#define ADC_RESVD 0x8000
#define RST_SEQ1 0x4000
#define SOC_SEQ1 0x2000
#define SEQ1_BSY 0x1000
#define ADC_SIZE 16
#define MAX_DAC 4
volatile unsigned int ADCVals[ADC_SIZE];
volatile unsigned int CmpValLow[ADC_SIZE];
volatile unsigned int CmpValHigh[ADC_SIZE];
volatile unsigned int CmpValErrL[ADC_SIZE];
volatile unsigned int CmpValErrH[ADC_SIZE];
/*
======================= CODE FOLLOWS ============================
*/
unsigned int dac_delay(volatile unsigned int ctr2)
{
volatile unsigned int ctr1;
ctr1 = 0;
while (ctr2)
{
ctr1++;
ctr2--;
}
return(ctr1);
}
/* #define MS_TIME_LOOP 0x0680 0x0800 */
#define MS_TIME_LOOP 0x500
unsigned int wait_ms( volatile unsigned int delay_val )
{
unsigned int i;
/* unsigned int ms_ctr; */
int ms_ctr;
for ( i = 0; i < delay_val; i++ )
{
ms_ctr = MS_TIME_LOOP;
while ( ms_ctr )
{
ms_ctr--;
}
}
return( delay_val );
}
void write_dac(unsigned int dac_num, unsigned int dac_val)
{
unsigned int write_dac_status;
if ( dac_num < MAX_DAC )
{
dacdata = dac_val; /* put in global location */
switch (dac_num)
{
case DAC0:
OUTMAC( _DAC0, dacdata);
break;
case DAC1:
OUTMAC( _DAC1, dacdata);
break;
case DAC2:
OUTMAC( _DAC2, dacdata);
break;
case DAC3:
OUTMAC( _DAC3, dacdata);
break;
}
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
asm(" nop" );
OUTMAC( _DAC_XFER, dacdata); /* just need a write, any data */
}
}
void atod_init(void)
{
volatile unsigned int ADCtrl1;
volatile unsigned int ADCtrl2;
volatile unsigned int RdADCtrl1;
volatile unsigned int RdADCtrl2;
/* Set Calibration Register to 0 */
*(volatile unsigned int *)CALIBRATION = 0;
wait_ms( 50 );
*(volatile unsigned int *)ADCTRL1 = ADC_RESET;
wait_ms( 50 );
/* *(volatile unsigned int *)ADCTRL1 = ADC_CAL_ENA;
*
* wait_ms( 50 );
*/
/* Enable AD CTL REGISTER1 */
ADCtrl1 = ADC_SOFT | ADC_ACQ_PS0 | ADC_ACQ_PS1 | ADC_ACQ_PS2; /* ADC_SEQ_CASC;*/
*(volatile unsigned int *)ADCTRL1 = ADCtrl1;
RdADCtrl1 = *(volatile unsigned int *)ADCTRL1;
/*----------------------------------------*/
/* Set Maximum Conversion to 15 at a time */
/*----------------------------------------*/
*(volatile unsigned int *)MAX_CONV = 0x0007;
/*---------------------------------------------*/
/* set the mux */
/*---------------------------------------------*/
*(volatile unsigned int *)CHSELSEQ1 = 0x3210;
*(volatile unsigned int *)CHSELSEQ2 = 0x7654;
/* *(volatile unsigned int *)CHSELSEQ3 = 0xba98;
*(volatile unsigned int *)CHSELSEQ4 = 0xfedc; */
}
#define ADC_ERROR 0xFFFF
volatile unsigned int read_atod(unsigned int chan_num)
{
volatile unsigned int ADCtrl1;
volatile unsigned int ADCtrl2;
volatile unsigned int TimeOutCtr;
volatile unsigned int ADCVal;
volatile unsigned int ADC_Status;
volatile unsigned int *ResultPtr;
if (chan_num > ADC_SIZE )
{
return( (unsigned int )ADC_ERROR );
}
/*---------------------------------------------*/
/* Make sure Conversion is not in progress */
/*---------------------------------------------*/
do
{
ADC_Status = *(volatile unsigned int *)ADCTRL2;
}while( ADC_Status & SEQ1_BSY );
/*---------------------------------------------*/
/* turn on enable bits and start of conversion */
/*---------------------------------------------*/
ADCtrl2 = *(volatile unsigned int *)ADCTRL2;
ADCtrl2 |= ( RST_SEQ1 | SOC_SEQ1);
*(volatile unsigned int *)ADCTRL2 = ADCtrl2;
asm(" nop");
asm(" nop");
/*---------------------------------------------*/
/* Read Back For Debug */
/*---------------------------------------------*/
/*ADCtrl2 = *(volatile unsigned int *)ADCTRL2;
*
*asm(" nop");
*asm(" nop");
*/
TimeOutCtr = 0xffff;
while ( TimeOutCtr-- )
{
ADCtrl2 = *(volatile unsigned int *)ADCTRL2;
/* Finished the Conversion */
if(!(ADCtrl2 & SEQ1_BSY ))
{
break;
}
}
if( TimeOutCtr )
{
ResultPtr= (volatile unsigned int * )RESULT0;
ADCVal = ResultPtr[chan_num];
ADCVal >>= 6; /* shift it down */
return( ADCVal );
}
return( ( unsigned int )ADC_ERROR );
}
unsigned int dactest(void)
{
unsigned int dac_i;
unsigned int dac_status;
atod_init(); /* init pointers & regs */
DacCalibrate();
dac_status = DacSawTooth();
if (dac_status)
{
return(dac_status);
}
return((unsigned int)0x0000); /* good return */
}
/* Create sawtooth waves on all the dac outputs 90 degrees out of phase */
/* #define DAC_END_COUNTS 0x0FFF */
#define DAC_END_COUNTS 0x0fff /* 0x666----->2V */
/* #define DAC_WAVES_COUNT 0x1000 */
#define DAC_WAVES_COUNT 0x1000
#define ADC_DAC_ERROR 0x0F0 /* 4*(1024 * .05) = +/- 5% ADC */
#define MAX_CONVERT_ERRORS 0x010
unsigned int DacSawTooth( void )
{
unsigned int i;
unsigned int Low;
unsigned int High;
unsigned int loop_count;
unsigned int dac_vals[4];
unsigned int temp;
unsigned int status;
unsigned int testing;
unsigned int trash;
unsigned int convert_errors=0;
unsigned int ConvertFail = 0;
loop_count = DAC_WAVES_COUNT;
temp = DAC_END_COUNTS >> 2;
dac_vals[0] = temp;
dac_vals[1] = temp + temp;
dac_vals[2] = temp+ temp + temp;
dac_vals[3] = temp + temp + temp + temp;
testing = 0x1;
while ( testing-- )
{
while( loop_count-- )
{
for( i = 0; i < 4; i++ )
{
dac_vals[i] +=40; /* no use setting less than 4 since 12 bit */
/* DAC 10 ADC */
if ( dac_vals[i] > DAC_END_COUNTS )
{
dac_vals[i] = 0;
}
write_dac(i, dac_vals[i]); /* put out value */
if( dac_vals[i] > ADC_DAC_ERROR )
{
Low = dac_vals[i] - ADC_DAC_ERROR ;
}
else
{
Low = 0;
}
High = dac_vals[i] + ADC_DAC_ERROR ;
switch( i )
{
case 0:
CmpValHigh[0] = High;
CmpValHigh[4] = High;
CmpValLow[0] = Low;
CmpValLow[4] = Low;
break;
case 1:
CmpValHigh[1] = High;
CmpValHigh[5] = High;
CmpValLow[1] = Low;
CmpValLow[5] = Low;
break;
case 2:
CmpValHigh[2] = High;
CmpValHigh[6] = High;
CmpValLow[2] = Low;
CmpValLow[6] = Low;
break;
case 3:
CmpValHigh[3] = High;
CmpValHigh[7] = High;
CmpValLow[3] = Low;
CmpValLow[7] = Low;
break;
default:
break;
}
}
status = wait_ms( 1 );
for( i = 0; i < 8; i++ )
{
ADCVals[i] = read_atod(i);
ADCVals[i] <<=2; /* Align with DAC */
ADCVals[i] = ADCVals[i]*3;
ADCVals[i] >>=1;
}
/* for( i = 0; i < 8; i++ ) */
for( i = 0; i < 8; i++ )
{
/* Compare DAC Output to ADC Input */
if ( CmpValHigh[i] > ADCVals[i] )
{
if( CmpValLow[i] <= ADCVals[i] )
{
trash++;
}
else
{
convert_errors++;
if( convert_errors > MAX_CONVERT_ERRORS )
{
ConvertFail = 1;
break;
}
}
}
}
if( ConvertFail )
{
return( 1 );
}
}
}
return((unsigned int)0x0000);
}
unsigned int DacCalibrate( void )
{
unsigned int i;
unsigned int j;
unsigned int dac_vals[4];
unsigned int status;
/* Write Out Max Value Dac 5.0 Volts to all Channels */
for( i = 0; i < 4; i++ )
{
switch( i )
{
case 0:
dac_vals[0] = DAC_END_COUNTS;
dac_vals[1] = 0;
dac_vals[2] = 0;
dac_vals[3] = 0;
break;
case 1:
dac_vals[0] = 0;
dac_vals[1] = DAC_END_COUNTS;
dac_vals[2] = 0;
dac_vals[3] = 0;
break;
case 2:
dac_vals[0] = 0;
dac_vals[1] = 0;
dac_vals[2] = DAC_END_COUNTS;
dac_vals[3] = 0;
break;
case 3:
dac_vals[0] = 0;
dac_vals[1] = 0;
dac_vals[2] = 0;
dac_vals[3] = DAC_END_COUNTS;
break;
default:
break;
}
for( j = 0; j < 4; j++ )
{
write_dac(j, dac_vals[j]); /* put out value */
}
status = wait_ms( 1 );
for( j = 0; j < 8; j++ )
{
ADCVals[j] = read_atod(j);
ADCVals[j] <<=2; /* Align with DAC */
}
switch( i )
{
case 0:
CmpValErrH[2] = dac_vals[0] - ADCVals[2];
CmpValErrH[6] = dac_vals[0] - ADCVals[6];
break;
case 1:
CmpValErrH[3] = dac_vals[1] - ADCVals[3];
CmpValErrH[7] = dac_vals[1] - ADCVals[7];
break;
case 2:
CmpValErrH[0] = dac_vals[2] - ADCVals[0];
CmpValErrH[4] = dac_vals[2] - ADCVals[4];
break;
case 3:
CmpValErrH[1] = dac_vals[3] - ADCVals[1];
CmpValErrH[5] = dac_vals[3] - ADCVals[5];
break;
default:
break;
}
}
return((unsigned int)0x0000);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -