📄 adc.c
字号:
/***DMA0 init***/
rDISRC0 =0x5800000c; // rADCDAT0
rDISRCC0=(1<<1)|(1<<0); // APB,Fixed
rDIDST0 =(int)dst; // dst
rDIDSTC0=(0<<1)|(0<<0); // AHB,++
rDCON0 =(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(3<<24)|(1<<23)|(1<<22)|(2<<20)|REQCNT;
//handshake, sync PCLK, TC int, single tx, single service, Timer, Timer(H/W) request,
//auto-reload off, word, REQCNT
rDMASKTRIG0=(0<<2)|(1<<1)+0; //no-stop, DMA0 channel on, no-SW trigger
/*
for(i=0;i<5;i++)
Uart_Printf("%d:0x%x\n",i, *(int *)(0x4b000000+i*4) );
*/
/***Timer0 init***/
// rTCFG0=255; //prescaler0=255
rTCFG0=0; //prescaler0=0
rTCFG1=(1<<20) | 3; //Timer0 DMA, div=16
// rTCNTB0=4900; //(1/(50MHz/255/16))*4900=(1/(12254.9) * 4900)=0.0000816 * 4900 = 0.401 sec
// rTCNTB0=1226; //0.0000816 * 1226 = 0.1 sec
// rTCNTB0=2452; //0.0000816 * 2452 = 0.2 sec
// rTCNTB0=1716; //0.0000816 * 1716 = 0.14 sec
rTCNTB0=6; //(1/(50MHz/1/16))*6=(1/(3125000)*10)=0.0000003*6 = 0.0000018 sec (1.8us)
// rTCNTB0=7; //(1/(50MHz/1/16))*7=(1/(3125000)*10)=0.0000003*7 = 0.0000018 sec (2.1us)
// rTCNTB0=10; //(1/(50MHz/1/16))*10=(1/(3125000)*10)=0.0000003*10 = 0.000003 sec (3us)
// rTCNTB0=100; //0.0000003*100 = 0.00003 sec (30us)
// rTCNTB0=2000; //(1/(50MHz/1/16))*2000=(1/(3125000)*2000)=0.0000003*2000 = 0.0006 sec
rTCON=0xa; //auto reload, manual update
rTCON=0x9; //Start Timer0
rADCDAT0; //Read out dummy data and start first ADC operation
while(!end_test);
tmp=dst;
for(i=0;i<REQCNT;i++)
{
*tmp = (*tmp) & 0x3ff;
tmp++;
}
for(i=0;i<REQCNT;i++)
Uart_Printf("%04d\n",*dst++); //May 08, 2002 SOP
// Uart_Printf("%02d=%04d\n",i,*dst++);
// Uart_Printf("%02d=0x%x\n",i,*dst++);
rINTMSK|=BIT_DMA0;
}
//==================================================================================
void __irq DMA0_Done(void)
{
ClearPending(BIT_DMA0);
rTCON=0x0; //Stop
end_test=1; //set end flag
}
//==================================================================================
// Test code for Verifone
// PCLK is normally set to 50Mhz FCLK 200mhz, HCLK 100
static void ADCInit (void)
{
// ECFLG = x, PRSCEN = 1 (enable), PRSCVL = ?, SEL_MUX = 0 (AIN0),
// STDBM = 0 (normal mode), READ_START = 0 (disable), ENABLE_START = 0 (nop)
#define tadc_us 2
#define mega 1000000
#define PRSCVL ((((PCLK/5)*tadc_us)/mega)-1) // A/D converter prescaler enable
#if ((PCLK*tadc_us)/((PRSCVL+1)*5)) - mega
//#error Cannot generate exact 500-KHz source clock for ADC.
#endif
//***************************************************************************************************
//** We Have a system variable used by the O/S to allow us to change the prescaler value. Normally
//** we don't have this defined. SO for this code assume it not to be defined. **/
//***************************************************************************************************
#ifdef ADCVar
#define kADCCON ((1<<14) | (0<<6) | (0<<3))
rADCCON = kADCCON | (sys_get_valid_env("*ADC", 0, PRSCVL, 255) << 6);
#else
#define kADCCON ((1<<14) | (PRSCVL<<6) | (0<<3)) // A/D converter prescaler enable, vlaue, AIN0
rADCCON = kADCCON;
#endif
// UD_SEN = 0 (stylus down interrupt),
// YM_SEN = 0, YP_SEN = 1, XM_SEN = 0, XP_SEN = 1,
// PULL_UP = 1 (XP pull-up disable), AUTO_PST = 0 (normal ADC conversion), XY_PST = 00 (nop)
rADCTSC = 0x58; // default 0x58
// normal conversion mode, minimum delay (1)
rADCDLY = 1;
ClearPending(BIT_ADC);
}
//=====================================================================================================
//*****************************************************************************************************
//** Used to read the Requested ADC channel **/
//*****************************************************************************************************
static int ADCRead (int reg)
{
int SPSR;
unsigned short int temp;
//SPSR = Disable();
#ifdef ADCVar
rADCCON = kADCCON | ((reg & 7) << 3) | (rADCCON & (0xFF<<6));
#else
rADCCON = kADCCON | ((reg & 7) << 3); // Analog input channel select
#endif
rADCCON |= 1; // Enable start by read operation
while (!(rADCCON & (1<<15))); // waitting End of A/D conversion
//temp = rADCDAT0 & 0x03FF; // Normal ADC conversion data value
temp = rADCDAT0 & 0x3FF; // Normal ADC conversion data value
//Enable(SPSR);
return temp;
}
// End Test code for Verifone
//==================================================================================
void Test_DMA_ADCforVerifone(void)
{
unsigned int *dst,*tmp,i;
end_test=0;
pISR_DMA0 = (unsigned)DMA0_Done; //Regist interrupt service routine
rINTMSK = ~(BIT_DMA0); //Clear int mask bit.
Uart_Printf("Test of the 'Start by read' in ADC block.\n");
Uart_Printf("Change the voltage of AIN6..(Sampling 100)\n");
dst = (unsigned int *)0x31000000; //Non-cacheable Area
tmp = dst;
for(i=0;i<REQCNT;i++)
*tmp++=i;
/***ADC init***/
#if 0
preScaler = PCLK/ADC_FREQ -1;
rADCCON=(1<<14)|(preScaler<<6)|(2<<3)|0x2; //normal,ADCPRS,AIN2,enable start by read
#else
ADCInit(); // from Verifone 10/19/2004 SOP
#endif
/***DMA0 init***/
rDISRC0 = 0x5800000c; // rADCDAT0
rDISRCC0 = (1<<1)|(1<<0); // APB,Fixed
rDIDST0 = (int)dst; // dst
rDIDSTC0 = (0<<1)|(0<<0); // AHB,++
rDCON0 = (1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(3<<24)|(1<<23)|(1<<22)|(2<<20)|REQCNT;
//handshake, sync PCLK, TC int, single tx, single service, Timer, Timer(H/W) request,
//auto-reload off, word, REQCNT
rDMASKTRIG0=(0<<2)|(1<<1)+0; //no-stop, DMA0 channel on, no-SW trigger
/***Timer0 init***/
rTCFG0 = 255; //prescaler0=255
rTCFG1 = (1<<20) | 3; //Timer0 DMA, div=16
rTCNTB0 = 1226; //0.0000816 * 1226 = 0.1 sec
rTCON = 0xa; //auto reload, manual update
rTCON = 0x9; //Start Timer0
rADCDAT0; //Read out dummy data and start first ADC operation
while(!end_test); // Waitting DMA0 done
tmp = dst;
for(i=0;i<REQCNT;i++)
{
*tmp = (*tmp) & 0x3ff;
tmp++;
}
for(i=0;i<REQCNT;i++)
Uart_Printf("%04d\n",*dst++); //May 08, 2002 SOP
rINTMSK|=BIT_DMA0;
}
//==================================================================================
void Test_AdcForVerifone(void)
{
int i,key;
int a6=0; //Initialize variables
Uart_Printf("[ ADC_IN Test (For Verifone)]\n");
Uart_Printf("0. Dispaly Count 100 1. Continued ...\n\n");
Uart_Printf("Selet : ");
key = Uart_GetIntNum();
Uart_Printf("\n\n");
#if 0
Uart_Printf("The ADC_IN are adjusted to the following values.\n");
Uart_Printf("ADC conv. freq. = %dHz\n",ADC_FREQ);
preScaler = PCLK/ADC_FREQ -1; //PCLK:50.7MHz (PreScaler=19), PCLK:67.5MHz (PreScler=26)
//ADC conversion time = 5CYCLES*(1/(ADC Freq.)), ADC Freq. = PCLK/(ADCPSR+1)
//ADC Conversion Time = 1/(ADC Freq./5 Cycles)
Uart_Printf("A/D Converter Prescaler Value (PRSCVL)= %d\n",preScaler);
Uart_Printf("Maximum Conversion Rate = %dKSPS\n",(ADC_FREQ/5)/1000);
Uart_Printf("\nPush any key to exit!!!\n");
#else
ADCInit(); // from Verifone 10/20/2004 SOP
#endif
if (key == 0)
{
Uart_Printf("[ AIN6 ]\n");
for(i=0;i<REQCNT;i++)
{
a6=ADCRead(6);
Uart_Printf("%04d\n",a6);
}
}
else if(key == 1)
{
while(Uart_GetKey()==0)
{
a6=ADCRead(6);
Uart_Printf("AIN6: %04d\n", a6);
}
}
rADCCON=(0<<14)|(19<<6)|(7<<3)|(1<<2); //stand by mode to reduce power consumption
Uart_Printf("\nrADCCON = 0x%x\n", rADCCON);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -