On Timers & ADC

classic Classic list List threaded Threaded
2 messages Options
jbsnyder jbsnyder
Reply | Threaded
Open this post in threaded view
|

On Timers & ADC

I suppose one other option here is to use virtual timers instead of dedicated ones? I've looked at the virtual timer stuff that has been checked in, but I have to admit that I've not yet quite figured out how to make use of them. It looks like they're using SysTick?

I've seen another "virtual" timer implementation out there that was posted on the LM boards (not sure how generalizable the code might be for other platforms, nor what license the code is under), which supposedly allows for setting up an "unlimited" number of timers, events and delays.

Certainly interesting :-)

----- Original Message -----
From: "James Snyder" <jbsnyder at fanplastic.org>
To: "eLua development list" <elua-dev at lists.berlios.de>
Sent: Thursday, January 22, 2009 4:02:53 PM GMT -06:00 US/Canada Central
Subject: [eLua-dev] On Timers & ADC

So I've been thinking about how to accomplish burst sampling at a given rate (or background sampling). The Stellaris ADCs are programmable in terms of selecting a sampling rate, but the range is pretty limited, and fairly fast (125 ksamples/s - 1 msample/s). In order to do more arbitrary rates, I'll need to use a timer. The issue I see is: what if I'm already using a timer, or multiple timers for some purpose? In cases where something like this is needed should timers be reserved/locked?


I've not worked with all the other supported platforms, but from working with some other microcontrollers I think a timer will be needed. In going with how things are already implemented (platform_uart_recv), I'm going to assume this is how I'll have to adjust things. As such, I suppose the ADC API should be amended a bit, as follows:



void platform_adc_burst( unsigned id, u16* buf, unsigned count, unsigned timer_id, u32 frequency );








The current API then looks like this:



int platform_adc_exists( unsigned id );
u16 platform_adc_sample( unsigned id );
u16 platform_adc_maxval( unsigned id );
void platform_adc_start( unsigned id );
int platform_adc_is_done( unsigned id );
void platform_adc_set_mode( unsigned id, int mode );
void platform_adc_burst( unsigned id, u16* buf, unsigned count, unsigned timer_id, u32 frequency );


If continuous mode sampling is to run at a rate that isn't in the range of 125 ksamples to 1 msamples, we might either need to have the set_mode function accept a timer (which is less useful in the case of doing single-shot, but timers can be used that way :-)), or have another function like burst, but that isn't blocking, and has a corresponding stop function.


I'm also going to add a smoothing option, which in the context of single shot or continuous simply means that enough samples must be averaged before the result is_done. For burst, we could do this too, either as oversampling (i.e. each burst sample is actually 5 averaged values, that are available because we're actually sampling at 5 times the rate passed to adc_burst) or with a moving average filter. For single shot, these would be the same, but they differ when we're talking about continuous or burst sampling. One requires that filter_length samples be collected prior to each averaged sample being released, and the other runs at the sampling rate, as soon as filter_length samples are collected so that the moving average has enough data. Hmm...


The stellaris platform has hardware averaging, though it is designed for being used for oversampling, not just rolling averages.


This article does a decent job of outlining the issues:
http://www.zlgmcu.com/luminary/download/LM3SAPP_ADC_OverSample_Tech_en.pdf 




I think for now I will implement smoothing as follows, using a moving average filter:
void platform_adc_set_smoothing( unsigned id, u8 length );


--
James Snyder
Biomedical Engineering
Northwestern University
jbsnyder at fanplastic.org
http://fanplastic.org/key.txt 
ph: (847) 644-2322

_______________________________________________ Elua-dev mailing list Elua-dev at lists.berlios.de https://lists.berlios.de/mailman/listinfo/elua-dev 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.berlios.de/pipermail/elua-dev/attachments/20090122/13d4504d/attachment-0001.html 

BogdanM BogdanM
Reply | Threaded
Open this post in threaded view
|

On Timers & ADC

On Fri, Jan 23, 2009 at 3:52 AM, James Snyder <jbsnyder at fanplastic.org>wrote:

> I suppose one other option here is to use virtual timers instead of
> dedicated ones?  I've looked at the virtual timer stuff that has been
> checked in, but I have to admit that I've not yet quite figured out how to
> make use of them.  It looks like they're using SysTick?
>

They can use any timer interrupt, they just happen to use SysTick on LM3S
because that doesn't 'eat' one of the regular timers (the ones we use in the
tmr module). And it just increments some 32-bit counters. Very simple stuff
really, see src/common.c for details, I think they're quite straightforward.
You use them just like you use the other timer functions, but you specify a
virtual timer ID instead of an actual timer ID (the magic that makes this
work also happens in src/common.c).


> I've seen another "virtual" timer implementation out there that was posted
> on the LM boards (not sure how generalizable the code might be for other
> platforms, nor what license the code is under), which supposedly allows for
> setting up an "unlimited" number of timers, events and delays.
>

You can have unlimited timers here too. Provided, of course, you also have
unlimited memory :)

Best,
Bogdan


> ----- Original Message -----
> From: "James Snyder" <jbsnyder at fanplastic.org>
> To: "eLua development list" <elua-dev at lists.berlios.de>
> Sent: Thursday, January 22, 2009 4:02:53 PM GMT -06:00 US/Canada Central
> Subject: [eLua-dev] On Timers & ADC
>
> So I've been thinking about how to accomplish burst sampling at a given
> rate (or background sampling).  The Stellaris ADCs are programmable in terms
> of selecting a sampling rate, but the range is pretty limited, and fairly
> fast (125 ksamples/s - 1 msample/s).  In order to do more arbitrary rates,
> I'll need to use a timer.  The issue I see is: what if I'm already using a
> timer, or multiple timers for some purpose?  In cases where something like
> this is needed should timers be reserved/locked?
> I've not worked with all the other supported platforms, but from working
> with some other microcontrollers I think a timer will be needed.  In going
> with how things are already implemented (platform_uart_recv), I'm going to
> assume this is how I'll have to adjust things.  As such, I suppose the ADC
> API should be amended a bit, as follows:
>
> void platform_adc_burst( unsigned id, u16* buf, unsigned count, unsigned timer_id,
> u32 frequency );
>
> The current API then looks like this:
>
> int platform_adc_exists( unsigned id );
> u16 platform_adc_sample( unsigned id );
> u16 platform_adc_maxval( unsigned id );
> void platform_adc_start( unsigned id );
> int platform_adc_is_done( unsigned id );
> void platform_adc_set_mode( unsigned id, int mode );
> void platform_adc_burst( unsigned id, u16* buf, unsigned count, unsigned timer_id,
> u32 frequency );
>
> If continuous mode sampling is to run at a rate that isn't in the range of
> 125 ksamples to 1 msamples, we might either need to have the set_mode
> function accept a timer (which is less useful in the case of doing
> single-shot, but timers can be used that way :-)), or have another function
> like burst, but that isn't blocking, and has a corresponding stop function.
>
> I'm also going to add a smoothing option, which in the context of single
> shot or continuous simply means that  enough samples must be averaged before
> the result is_done.  For burst, we could do this too, either as oversampling
> (i.e. each burst sample is actually 5 averaged values, that are available
> because we're actually sampling at 5 times the rate passed to adc_burst) or
> with a moving average filter.  For single shot, these would be the same, but
> they differ when we're talking about continuous or burst sampling.  One
> requires that filter_length samples be collected prior to each averaged
> sample being released, and the other runs at the sampling rate, as soon as
> filter_length samples are collected so that the moving average has enough
> data. Hmm...
>
> The stellaris platform has hardware averaging, though it is designed for
> being used for oversampling, not just rolling averages.
>
> This article does a decent job of outlining the issues:
> http://www.zlgmcu.com/luminary/download/LM3SAPP_ADC_OverSample_Tech_en.pdf
>
>
> I think for now I will implement smoothing as follows, using a moving
> average filter:
> void platform_adc_set_smoothing( unsigned id, u8 length );
>
> --
> James Snyder
> Biomedical Engineering
> Northwestern University
> jbsnyder at fanplastic.org
> http://fanplastic.org/key.txt
> ph: (847) 644-2322
>
>
> _______________________________________________ Elua-dev mailing list
> Elua-dev at lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/elua-dev
>
> _______________________________________________
> Elua-dev mailing list
> Elua-dev at lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/elua-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.berlios.de/pipermail/elua-dev/attachments/20090123/98de9dea/attachment-0001.html