Yahoo Groups archive

Lpc2000

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

Thread

Maximum periodic D/A speed

Maximum periodic D/A speed

2006-01-16 by drareve

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.

  Thank you

Re: [lpc2000] Maximum periodic D/A speed

2006-01-16 by Karl Olsen

---- Original Message ----
Show quoted textHide quoted text
From: "drareve" <everard.kamphorst@...>
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

Re: [lpc2000] Maximum periodic D/A speed

2006-01-16 by David Hawkins

>>Does anyone know what is the maximum speed that I could send
>>data to the D/A at fixed frequency?

You can eliminate the software jitter by introducing a set of
latches.

Use the hardware timer or PWM hardware to generate a fixed
frequency square-wave (or edge at least) on an output pin.
Use this to latch the input to the DAC.

In your software, triggered from the same timer, write the
next valid sample to the input of the latch, eg. on the
output pins of the micro, or to another latch that
preceeds the DAC latch.

The software jitter then only affects the data written
to the first latch, data written to the second latch
(or DAC internal latch) is done by the timer I/O pin,
so is unaffected by the software jitter.

If you use software to fill a FIFO, then the DAC can be
driven by the FIFO draining, and software can fill it
up on an 'almost empty' interrupt. You'll get higher
performance from the DAC with this scheme.

Cheers
Dave

Re: Maximum periodic D/A speed

2006-01-17 by brendanmurphy37

Hi,

I presume you're talking about using some form of external DAC as 
part of your suggestion? If not, can you explain the statement "Use 
this to latch the input to the DAC".

A significant problem with the on-board DAC is that there is no latch 
signal that can be applied, making some degree of jitter inevitable 
on any software-driven setup.

We had to abandon the idea of using the on-board DAC for our software 
modem for this very reason: even a few clocks of jitter at 60 Mhz is 
enough to generate significant noise on the output.

I suspect anyone else (the original questioner on this topic?) trying 
to drive the DAC at high speeds will hit this problem before they hit 
the maximum o/p speed problem (unless having a noisy o/p isn't a 
concern). This is unfortunate, as it means that the DAC can't really 
be used for even relatively simple signal generation without a noisy 
o/p.

A very simple addition to the DAC, namely a latch signal, would be a 
great help here. 

Of course, a DMA-fed FIFO arrangement would be even better.....

Brendan

P.S. as an aside, we did come up with a jitter-free software-fed DAC, 
but it consumed significant MIPS, and just wasn't worth the effort.

--- In lpc2000@yahoogroups.com, David Hawkins <dwh@o...> wrote:
Show quoted textHide quoted text
>
> 
> >>Does anyone know what is the maximum speed that I could send
> >>data to the D/A at fixed frequency?
> 
> You can eliminate the software jitter by introducing a set of
> latches.
> 
> Use the hardware timer or PWM hardware to generate a fixed
> frequency square-wave (or edge at least) on an output pin.
> Use this to latch the input to the DAC.
> 
> In your software, triggered from the same timer, write the
> next valid sample to the input of the latch, eg. on the
> output pins of the micro, or to another latch that
> preceeds the DAC latch.
> 
> The software jitter then only affects the data written
> to the first latch, data written to the second latch
> (or DAC internal latch) is done by the timer I/O pin,
> so is unaffected by the software jitter.
> 
> If you use software to fill a FIFO, then the DAC can be
> driven by the FIFO draining, and software can fill it
> up on an 'almost empty' interrupt. You'll get higher
> performance from the DAC with this scheme.
> 
> Cheers
> Dave
>

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,
Show quoted textHide quoted text
> and that can take a variable number of clocks.
> 
> Karl Olsen
>

Re: Maximum periodic D/A speed

2006-01-17 by brendanmurphy37

Just to clarify the example below:

In your startup code, you can pre-load FIQ registers, but obviously 
you have to be in FIQ mode to do this! We do this as part of the 
initial startup that switches between modes to initialise the stack 
pointers for each mode.

Brendan

--- In lpc2000@yahoogroups.com, "brendanmurphy37" 
<brendan.murphy@i...> wrote:
>
> 
> 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 
Show quoted textHide quoted text
> 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
> >
>

Re: Maximum periodic D/A speed

2006-01-17 by Karl Olsen

--- In lpc2000@yahoogroups.com, "brendanmurphy37" 
<brendan.murphy@i...> wrote:
>
> I presume you're talking about using some form of external DAC as 
> part of your suggestion? If not, can you explain the statement "Use 
> this to latch the input to the DAC".
> 
> A significant problem with the on-board DAC is that there is no
> latch  signal that can be applied, making some degree of jitter
> inevitable on any software-driven setup.
> 
> We had to abandon the idea of using the on-board DAC for our
> software modem for this very reason: even a few clocks of jitter at 
> 60 Mhz is enough to generate significant noise on the output.
> 
> I suspect anyone else (the original questioner on this topic?)
> trying to drive the DAC at high speeds will hit this problem before 
> they hit the maximum o/p speed problem (unless having a noisy o/p
> isn't a concern). This is unfortunate, as it means that the DAC
> can't really be used for even relatively simple signal generation
> without a noisy o/p.
> 
> A very simple addition to the DAC, namely a latch signal, would be 
> a great help here. 
> 
> Of course, a DMA-fed FIFO arrangement would be even better.....

Yep.  You can add an external "analog latch", i.e. a sample-hold 
circuit with an analog switch and a capacitor, where the analog 
switch is controlled by a PWM output.  The software then updates the 
DAC output (at an imprecise time) while the analog switch is off and 
the capacitor holds the voltage, and the PWM output later, at a 
precise time, turns the analog switch on and lets the new voltage get 
to the capacitor.

Karl Olsen

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.