Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: Maximum periodic D/A speed

2006-01-17 by brendanmurphy37

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
>

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.