DDS working

Started by Leon Heller December 3, 2003
Thanks for the suggestions.

It's working OK now (sine, triangle, sawtooth and square waves) with the
following code:

adder = 202500; //set up adder
acc = 0; //clear accumulator
while (1)
{
acc = acc + adder; //update phase accumulator
ptr = (acc &= 0xFF); //pointer into table
IOSET = sawtooth[ptr] << 8;
IOCLR = (~sawtooth[ptr] << 8);
}

apart from glitches - spurs on the waveforms. I think I had the ~ in the
wrong place.

I didn't get those glitches with the AVR, using the same DAC. I've got some
LEDs on some of the lines to the DAC, so I'll try disconnecting them - they
might be pulling the signals down. Although the DAC is a 5V device,
according to the spec it is LV CMOS compatible (as low as 2V for a logic
high) on the inputs, so it should be OK with the LPC2106 outputs. I might
try pulling the inputs up to 5V if I still have problems.

Leon
--
Leon Heller, G1HSM
Email:
http://webspace.webring.com/people/jl/leon_heller/




An Engineer's Guide to the LPC2100 Series

Hi Leon,

> apart from glitches - spurs on the waveforms. I think I had the ~ in the
> wrong place.
>
> I didn't get those glitches with the AVR, using the same DAC. I've got
some
> LEDs on some of the lines to the DAC, so I'll try disconnecting them -
they

I figured it had to do something with the IOCLR write of complemented
values.
I think you'll find that the glitches represent the time it takes between
the IOSET and the IOCLR
operation to update the I/O (ie. there are a few instructions involved).

The only way probably will be to use a latch, unless your DAC has a strobe.

Tip : Try declaring a long* for IOCLR and one for IOSET, and write to the
port that way.
Register move instructions are then generated instead of the LDR, which
takes less cycles/time.
If you find the glitches get "narrower", then it's definitely the update
time between IOSET, and
writing the complement to IOCLR.

-- Kris
www.microbit.com.au



----- Original Message -----
From: "microbit" <>
To: <>
Sent: Wednesday, December 03, 2003 4:00 PM
Subject: Re: [lpc2100] DDS working > Hi Leon,
>
> > apart from glitches - spurs on the waveforms. I think I had the ~ in the
> > wrong place.
> >
> > I didn't get those glitches with the AVR, using the same DAC. I've got
> some
> > LEDs on some of the lines to the DAC, so I'll try disconnecting them -
> they
>
> I figured it had to do something with the IOCLR write of complemented
> values.
> I think you'll find that the glitches represent the time it takes between
> the IOSET and the IOCLR
> operation to update the I/O (ie. there are a few instructions involved).
>
> The only way probably will be to use a latch, unless your DAC has a
strobe.

The DAC has got a latch, so I can try that.

>
> Tip : Try declaring a long* for IOCLR and one for IOSET, and write to the
> port that way.
> Register move instructions are then generated instead of the LDR, which
> takes less cycles/time.
> If you find the glitches get "narrower", then it's definitely the update
> time between IOSET, and
> writing the complement to IOCLR.

I'll try that.

Thanks,
Leon
--
Leon Heller, G1HSM
Email:
http://webspace.webring.com/people/jl/leon_heller/




> while (1)
> {
> acc = acc + adder; //update phase accumulator
> ptr = (acc &= 0xFF); //pointer into table
> IOSET = sawtooth[ptr] << 8;
> IOCLR = (~sawtooth[ptr] << 8);
> }
>
>apart from glitches - spurs on the waveforms. I think I had the ~ in the
>wrong place.
>
>I didn't get those glitches with the AVR, using the same DAC.

Scope your output lines and compare to the glitches. I suspect they are
coming from the fact that not all of your lines change at the same
time. Going from a value of 3 to a value of 4 I would expect to see a
sequence of 3, 7, 4 given your code.

I think there may be either a HW or a SW fix. THE SW fix would involve
going against the User manuals recommendations though.

Robert



On Wed, Dec 03, 2003 at 11:14:07AM -0500, Robert Adsett wrote:
>
> > while (1)
> > {
> > acc = acc + adder; //update phase accumulator
> > ptr = (acc &= 0xFF); //pointer into table
> > IOSET = sawtooth[ptr] << 8;
> > IOCLR = (~sawtooth[ptr] << 8);
> > }
> >
> >apart from glitches - spurs on the waveforms. I think I had the ~ in the
> >wrong place.
> >
> >I didn't get those glitches with the AVR, using the same DAC.
>
> Scope your output lines and compare to the glitches. I suspect they are
> coming from the fact that not all of your lines change at the same
> time.

yeah, I pointed out the code being produced is loading the table
value twice, which is why I suggested that the sawtooth[ptr]
be loaded into a temporary variable and used.

ie:

while (1)
{
unsigned int val;

acc = acc + adder; //update phase accumulator
ptr = (acc &= 0xFF); //pointer into table
val = swatooth[ptr] << 8; // get our value

// set our value onto the output lines..
IOSET = val;
IOCLR = ~val;
}

if you wanted to get better IOSET/IOCLR then you could do

while (1)
{
unsigned int val, vali;

acc = acc + adder; //update phase accumulator
ptr = (acc &= 0xFF); //pointer into table
val = swatooth[ptr] << 8; // get our value
vali = ~val;

// set our value onto the output lines..
IOSET = val;
IOCLR = vali;
}

which should pre-compute the inverse of val and then do the
set of the two registers. You could possibly get a little more
perfomance to go to assembly.

--
Ben

Q: What's a light-year?
A: One-third less calories than a regular year.



Attachment (not stored)
attachment
Type: application/pgp-signature




>
> which should pre-compute the inverse of val and then do the
> set of the two registers. You could possibly get a little more
> perfomance to go to assembly.


Thanks, Ben. That speeded it up somewhat. Compiling for Release rather
than Debug made a big difference as well.

I've never used C before for this sort of thing, it probaly shows.

Leon


Hmmm, I didn't see the post of Ben, seems like I'm in the same boat
as Robert here :-)
Obviously not all posts are always routed fully to every member.

-- Kris

----- Original Message -----
From: "leon_heller" <>
To: <>
Sent: Thursday, December 04, 2003 5:15 AM
Subject: [lpc2100] Re: DDS working >
>
> >
> > which should pre-compute the inverse of val and then do the
> > set of the two registers. You could possibly get a little more
> > perfomance to go to assembly.
>
>
> Thanks, Ben. That speeded it up somewhat. Compiling for Release rather
> than Debug made a big difference as well.
>
> I've never used C before for this sort of thing, it probaly shows.
>
> Leon





At 05:20 PM 12/3/03 +0000, you wrote:
>if you wanted to get better IOSET/IOCLR then you could do
>
> while (1)
> {
> unsigned int val, vali;
>
> acc = acc + adder; //update phase accumulator
> ptr = (acc &= 0xFF); //pointer into table
> val = swatooth[ptr] << 8; // get our value
> vali = ~val;
>
> // set our value onto the output lines..
> IOSET = val;
> IOCLR = vali;
> }
>
>which should pre-compute the inverse of val and then do the
>set of the two registers. You could possibly get a little more
>perfomance to go to assembly.

Even with assembly I would expect to see a significant glitch. Even at max
speed I was seeing several hundred nS to perform both operations. (see
earlier thread of discussion "Simple test program - is now instruction")

Robert

" 'Freedom' has no meaning of itself. There are always restrictions,
be they legal, genetic, or physical. If you don't believe me, try to
chew a radio signal. "

Kelvin Throop, III



--- In , "microbit" <microbit@c...> wrote:
> Hmmm, I didn't see the post of Ben, seems like I'm in the same boat
> as Robert here :-)
> Obviously not all posts are always routed fully to every member.

I have the same problem as well. They appear almost immediately on the
group's web page, but sometimes the emailed version takes a long time.
I've got a feeling that Yahoo sends them out periodically, not when
they are initially posted. I've noticed it with other groups.

Leon


On Wed, Dec 03, 2003 at 01:20:50PM -0500, Robert Adsett wrote:
> At 05:20 PM 12/3/03 +0000, you wrote:
> >if you wanted to get better IOSET/IOCLR then you could do
> >
> > while (1)
> > {
> > unsigned int val, vali;
> >
> > acc = acc + adder; //update phase accumulator
> > ptr = (acc &= 0xFF); //pointer into table
> > val = swatooth[ptr] << 8; // get our value
> > vali = ~val;
> >
> > // set our value onto the output lines..
> > IOSET = val;
> > IOCLR = vali;
> > }
> >
> >which should pre-compute the inverse of val and then do the
> >set of the two registers. You could possibly get a little more
> >perfomance to go to assembly.
>
> Even with assembly I would expect to see a significant glitch. Even at max
> speed I was seeing several hundred nS to perform both operations. (see
> earlier thread of discussion "Simple test program - is now instruction")

yeah, the best way is to use some form of latch to clean the signal up.

--
Ben

Q: What's a light-year?
A: One-third less calories than a regular year.



Attachment (not stored)
attachment
Type: application/pgp-signature