Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

C Code for ADC

Altera_Forum
Honored Contributor II
1,460 Views

Hi, I have one question about the code.I have a A/D Converter on the DE0-Nano Dev Board. THe code is nearly the same like in the Demo for the A/D Converter how comes with the CD. 

 

My Question is it possible to let the code work faster or s shorter program so i can read the ADC faster. 

 

Here is the code but the commends are German. 

 

--- Quote Start ---  

#define START_FLAG 0x8000 //1000 0000 0000 0000# define DONE_FLAG 0x8000 //1000 0000 0000 0000 

 

 

alt_u16 ADC_Read(alt_u8 NextChannel){ //Wiedergabewert 16bit ( Übergabewert 8bit) 

int bDone = FALSE; 

alt_u16 Data16, DigitalValue = 0; // 16bit Data16 

const int nMaxWait = 10; //Konstante nMaxWait = 1000 

int nWaitCnt = 0; 

 

// start 

Data16 = NextChannel; //Data16 = Übrgabewert (zu lesneder Kanal) 

IOWR(READ_ADC_BASE, 0, Data16); //schreibe zu lesender Kanal 

Data16 |= START_FLAG; // Data 16 -> Startflag 

IOWR(READ_ADC_BASE, 0, Data16); // Übertragung starten 

 

// wait done 

while(!bDone && nWaitCnt++ <= nMaxWait){ //Schleife hört auf wenn bDone = true oder nWaitCnt >=nMaxWait 

Data16 = IORD(READ_ADC_BASE,0); //Data16 = Wert des Kanals 

bDone = (Data16 & DONE_FLAG)?TRUE:FALSE; //Vergleich Kanal mit Done_Flag 

 

if (bDone) // Wenn Data16 = DONE_FLAG -> Data16 Null schreiben 

DigitalValue = Data16 & 0xFFF; // 12 bits 

 

// stop 

IOWR(READ_ADC_BASE, 0, 0); //Kanal löschen 

 

return DigitalValue; //DigitalValue zurückgeben 

--- Quote End ---  

thanks everybody for helping
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
717 Views

1) Make sure you compile everything with -O3 

2) Get rid of superfluous boolean variables, use break and return. 

3) Use do { ... } while (...); to remove the test from the loop top 

4) Don't use 'const int' - it is still likely to be a variable. 

 

I would code the bottom of the loop as: 

// wait done nWaitCnt = nMaxWait; for (;;) { Data16 = IORD(READ_ADC_BASE,0); //Data16 = Wert des Kanals if (Data16 & DONE_FLAG) break; if (--nWaitCnt == 0) // All gone horribly wrong.... return 0; } DigitalValue = Data16 & 0xFFF // 12 bits // stop IOWR(READ_ADC_BASE, 0, 0); //Kanal löschen return DigitalValue; //DigitalValue zurückgeben You may also want to use gcc's __builtin_expect() to force which code paths are inlined.
0 Kudos
Altera_Forum
Honored Contributor II
717 Views

Moving to the software section since this doesn't have anything to do with C2H.... 

 

Also if you want more read speed and code or compiler setting changes don't give you enough speed I recommend using a DMA engine to place the samples directly into memory and then the CPU can read the data directly from memory. You could have an interrupt fire when 'x' number of bytes have been locally stored or just poll the DMA engine to figure out how many samples have been buffered. 

 

A simplier but less efficient hardware method would be to buffer and post process the samples in a FIFO built into your ADC interface. First you would read a FIFO watermark that tells you how much data is buffered (or use an interrupt to signal a fill level) and once you know that just read the data as fast as possible. That data masking of 0xFFF could be done in hardware if you made the interface 16-bit wide. Also if you wanted to store a lot of samples into memory you can make the FIFO interface 32-bit wide and read two samples at a time. 

 

So start with the suggestions DSL has since making the changes on the software side should be easier. If that doesn't give you enough speed changing the hardware to be more efficient might be your only choice afterwards.
0 Kudos
Altera_Forum
Honored Contributor II
717 Views

Make sure you compile everything with -O3 

 

 

What do you mean with that.I don`t know and i find now option how i can change something like that.
0 Kudos
Altera_Forum
Honored Contributor II
717 Views

 

--- Quote Start ---  

Make sure you compile everything with -O3 

 

 

What do you mean with that.I don`t know and i find now option how i can change something like that. 

--- Quote End ---  

 

 

 

ohh sorry my fault i find it and try it
0 Kudos
Altera_Forum
Honored Contributor II
717 Views

 

--- Quote Start ---  

1) Make sure you compile everything with -O3 

2) Get rid of superfluous boolean variables, use break and return. 

3) Use do { ... } while (...); to remove the test from the loop top 

4) Don't use 'const int' - it is still likely to be a variable. 

 

I would code the bottom of the loop as: 

// wait done nWaitCnt = nMaxWait; for (;;) { Data16 = IORD(READ_ADC_BASE,0); //Data16 = Wert des Kanals if (Data16 & DONE_FLAG) break; if (--nWaitCnt == 0) // All gone horribly wrong.... return 0; } DigitalValue = Data16 & 0xFFF // 12 bits // stop IOWR(READ_ADC_BASE, 0, 0); //Kanal löschen return DigitalValue; //DigitalValue zurückgeben You may also want to use gcc's __builtin_expect() to force which code paths are inlined. 

--- Quote End ---  

 

 

 

Hi again, I tried the Code but It didn`t work but my old Code also. What ever I do I alway had the Max Value and I don`t know why. The A/D Converter is not connected and I get the max Value?? 

 

Maybe somebody could help. Thx
0 Kudos
Reply