I've been trying to do the same thing on a TS-7260, and ran into the
same issues. One maybe not-so-obvious issue is that if you call
usleep() in user-space, you will go to sleep for a *minimum* of 10ms
using the supplied kernel. Also, even if you don't call usleep(),
the kernel can take the CPU away from your process, and will probably
not give it back until its next 10ms "time window".
I think the only possible way of reading the ADC at its limit (even
in its slower 9ksps mode) requires writing a device driver. There's
simply no way to arrange the right usleep() behavior from user-
space. Until I figure out how to compile device drivers, this issue
has left me with a 10sps rate doing it from user-space (two
channels). While very slow, I haven't missed any samples in several
days of operation with several other things running.
There are some other mysterious things going on in the supplied
sample code. While the sample code works (both ADC_poll in busybox
and adc_72xx), its unclear to me, for example, why the data mask is
defined as 0xFFFF instead of 0x0FFF as you would expect for a 12-bit
ADC (the upper four bits read into the result have "unspecified"
values according to the EP9302 manual - I think these four bits are
later divided out). A bigger mystery is that in the adc_72xx code,
the ADC status is read as busy when the high bit is "set" in the
result register, reading the result as soon as this bit becomes
clear. In contrast, in ADC_poll, it busy-waits until this bit is
clear, then busy-waits until it's set, and only then reads the
result. Then it inexplicably sleeps for 2000 microseconds, which is
10ms in "real life". Its really not very comforting to not know why
this is working, but I've not been able to successfully modify the
sample code so far to give expected results "in the expected way" -
only in the quirky way done in the sample code. Considering that the
two example programs use completely opposite criteria to determine if
the ADC result is ready, I can't really explain why they work at all.
A definitive ADC driver would be really, really useful.
-Ilya
On Nov 2, 2007, at 12:23 PM, lyy_henry wrote:
> Hi guys:
>
> I am currently trying to set the built-in ADC in the ARM EP9302
> processor to collect samples at its highest -> 3750 samples per
> second. According to the EP9302 manual, I have to enable the ADIV bit
> in the ADCCLKDIV register which is bit 16 to either 0 or 1.
>
> Why 0 or 1. Because I am not sure either 0 or 1. There were two EP9302
> manuals that I have been studying, One is the EP93xx family manual and
> the second one is EP9302 manual, they were talking differently to each
> other regarding to this issue, one said enable 0 and the other said
> enable 1. So I started testing it myself. However, either I enabled 1
> or 0, it still gave me the same result. I have attached the init_ADC
> function below, this is the bit that I have added:
>
> //Enable ADIV bit to 1 in able to get the higest sample rate
> val = PEEK32(syscon_page + ADCCLKDIV_OFFSET);
> POKE32(syscon_page + SYSCON_UNLOCK, UNLOCK_VAL);
> POKE32(syscon_page + ADCCLKDIV_OFFSET, val & ~0x10000);
>
> Have I done anything wrong with it or I have misunderstand the manuals
> ? If I did something wrong please indicate me. Thanks a lot guys.
>
> Full init_ADC function:
>
> void init_ADC(unsigned long adc_page, unsigned long syscon_page)
> {
> unsigned long val;
>
> /* set TSEN bit */
> val = PEEK32(syscon_page + ADCCLKDIV_OFFSET);
> //unlock the software lock
> POKE32(syscon_page + SYSCON_UNLOCK, UNLOCK_VAL);
> POKE32(syscon_page + ADCCLKDIV_OFFSET, TSEN_MASK | val);
>
> //Enable ADIV bit to 1 in able to get the higest sample rate
> val = PEEK32(syscon_page + ADCCLKDIV_OFFSET);
> POKE32(syscon_page + SYSCON_UNLOCK, UNLOCK_VAL);
> POKE32(syscon_page + ADCCLKDIV_OFFSET, val & ~0x10000);
>
> /* set ADCEN bit */
> val = PEEK32(syscon_page + DEVICECFG_OFFSET);
> POKE32(adc_page + SYSCON_UNLOCK, UNLOCK_VAL); //unlock the soft lock
> POKE32(syscon_page + DEVICECFG_OFFSET, val | ADCEN_MASK);
>
> /* clear ADCPD bit */
> val = PEEK32(syscon_page + DEVICECFG_OFFSET);
> POKE32(adc_page + SYSCON_UNLOCK, UNLOCK_VAL); //unlock the soft lock
> POKE32(syscon_page + DEVICECFG_OFFSET, val & ~ADCPD_MASK);
> }
>
>
>
>
> Yahoo! Groups Links
>
>
>
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/ts-7000/join
(Yahoo! ID required)
<*> To change settings via email:
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|