Karl,
As a further suggestion to anyone taking this approach, I'd suggest
the following optimisations (which can be applied in other scenarios
as well that require speedy o/p).
1. Prepare the samples in buffers that are "ready to go", rather than
doing any processing in the o/p interrupt. I know that on ARM shifts
can sometimes be "free", but in some cases they're not.
2. Use power-of two sized buffers, and load using something like:
#define BUFF_SIZE 256
#define BUFF_SIZE_MASK (BUFF_SIZE - 1)
REG = buffer[index++];
index &= (BUFF_SIZE_MASK);
3. If you're really pushed for cycles for one particular interrupt,
you can use an FIQ interrupt and "pre-load" certain registers.
For example, in this case, in your start-up code:
load r8 with the DAC o/p register address
load r9 with the buffer address
load r10 with the current index
In the FIQ interrupt:
- just fall through from the bottom of the vector table (i.e. don't
branch or jump)
- use the pre-loaded r8, r9 and r10 (and others): no need to save
these as they're unique to FIQ interrupts
- update the pre-loaded registers of required for next time: they are
preserved across interrupts
We use these (and other) techniques in a system that both generates
and samples at high speed (200 Khz and above), and it works very well
Hope this of help to someone.
Regards
Brendan
--- In lpc2000@yahoogroups.com, "Karl Olsen" <kro@p...> wrote:
>
> ---- Original Message ----
> From: "drareve" <everard.kamphorst@g...>
> To: <lpc2000@yahoogroups.com>
> Sent: Monday, January 16, 2006 9:40 PM
> Subject: [lpc2000] Maximum periodic D/A speed
>
> > Does anyone know what is the maximum speed that I could send
> > data to the D/A at fixed frequency?
> >
> > I am using a LPC2148 with a 10MHz crystal and a PLL M value of 6,
and
> > P value of 2. My PCLK should be 60Mhz (VPBDIV=0x1)
> >
> > I have tried setting up a timer to send a sample every 1uS, but
the
> > output appears to be quite unstable.
>
> As far as I know, the D/A converter itself doesn't limit the update
rate,
> other than its fast/slow settling time. But having a timer
interrupt that
> is called every 60 clocks that updates the DAC, requires some very
careful
> programming, and in the best case, you'll get very few spare clocks
left for
> the foreground program. Just the stores that write to DACR and
T0IR take 7
> clocks each since they are behind the slow APB bridge.
>
> Something like this (gcc):
>
> unsigned short buf[1024];
> int index;
>
> void timer0_handler (void) __attribute__ ((interrupt("IRQ")));
> void timer0_handler (void)
> {
> int next_index;
>
> DACR = buf[index] << 6;
> if ((next_index = index+1) == 1024)
> next_index = 0;
> index = next_index;
> T0IR = 0x01;
> VICVectAddr = 0x00;
> }
>
> with the usual LDR PC, [PC, #-0x0FF0] at 0x0018 and MAM enabled
and
> MAMTIM=3, will take around 83 clocks. Check the compiler output
and see
> http://groups.yahoo.com/group/lpc2000/message/7808 . If you use
FIQ instead
> of IRQ, and carefully write it in assembler, you may be able to get
below 60
> clocks.
>
> The DAC updating will have a jitter of a few clocks, because at
each timer
> interrupt, the current instruction of the foreground program must
complete,
> and that can take a variable number of clocks.
>
> Karl Olsen
>Message
Re: Maximum periodic D/A speed
2006-01-17 by brendanmurphy37
Attachments
- No local attachments were found for this message.