EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Problem with SPI1 on LPC2119

Started by irafalovsky August 8, 2006
--- In l..., wrote:
>
> I was never able to get the SPI engine to send 16 bits. I ended up
writing my own code to do it by GPIO.
> I don't believe the LPC SPI engines can do anything but 8 bit data
word size.
>
> Chris.
>

I never tried working with 16 bit frames, only 9 bits.
Anyway Mr Irafalovsky is working with 8 bit frames and is sending
2x8bit frames in order to read the 16 bit result.
Pheraps here is the problem: the SSEL1 signal goes high between the
two 8 bit frames; are you sure this are not causing problems to your
slave device?

>
> ----- Original Message -----
> From: irafalovsky
> To: l...
> Sent: Tuesday, August 08, 2006 9:00 PM
> Subject: [lpc2000] Re: Problem with SPI1 on LPC2119
> Thank you for your help! Unfortunately, this approach does not work
> either...
>
> Now, the question is -- is it at all possible to make LPC2119 read
> 16 bits sent by SPI peripheral in succession?
>
> --- In l..., "Alan Strickland"
> wrote:
> >

Looking at the SPI signals with a scope, do you see the command sent
out in the MOSI line and your peripheral answer in the MISO line?
If yes, the problem is restricted to the LPC software.

An Engineer's Guide to the LPC2100 Series

This is pretty much our conclusion at this point. It doesn't seem
that SPI in LPC2119 is able to handle data sizes over ine byte, at
least we can't find any references anywhere to the possibility of
that...

It seems that the only way to handle this scenario is through bit
banging, which is the shame. To this point we had absolutely no
issues with LPC2119s... SPI in single byte scenario also works
flawlessly.

What are we missing here?! :-)

--- In l..., "c.barbaro" wrote:
>
> --- In l..., wrote:
> >
> > I was never able to get the SPI engine to send 16 bits. I
ended up
> writing my own code to do it by GPIO.
> > I don't believe the LPC SPI engines can do anything but 8 bit
data
> word size.
> >
> > Chris.
> > I never tried working with 16 bit frames, only 9 bits.
> Anyway Mr Irafalovsky is working with 8 bit frames and is sending
> 2x8bit frames in order to read the 16 bit result.
> Pheraps here is the problem: the SSEL1 signal goes high between the
> two 8 bit frames; are you sure this are not causing problems to
your
> slave device?

Well, SSEL1 pin is connected to VDD (on LPC2119, of course), so I
don't know how this would affect us... We are not toggling
peripheral's SS line between the two byte reads.

>
> > Looking at the SPI signals with a scope, do you see the command
sent
> out in the MOSI line and your peripheral answer in the MISO line?
> If yes, the problem is restricted to the LPC software.
>

We see the command sent correctly on the MOSI with proper timing,
peripheral behaves properly (at least it brings up DRDY line after
measurement is completed) and then we see peripheral pulsing bits on
the MISO line during the first 8 cycles of SCLK, however we never
saw a single pulse during next 8 cycles.
The User Manual for the LPC2119 does not seem to indicate any
capability for SPI transfer sizes other than 8 bits at a time? However
the user manuals for the LPC2138 and LPC2148 *do* indicate transfer
sizes from 8 to 16 bits per transfer, and give control register
settings for doing those transfer sizes. It probably could be infered
from that, that if the LPC2119 could do 16 bit transfers that the
manual would have indicated it??????????

http://www.standardics.philips.com/products/lpc2000/

-- Dave
--- In l..., wrote:
>
> I was never able to get the SPI engine to send 16 bits. I ended up
writing my own code to do it by GPIO.
> I don't believe the LPC SPI engines can do anything but 8 bit data
word size.
>
> Chris.
> ----- Original Message -----
> From: irafalovsky
> To: l...
> Sent: Tuesday, August 08, 2006 9:00 PM
> Subject: [lpc2000] Re: Problem with SPI1 on LPC2119
> Thank you for your help! Unfortunately, this approach does not work
> either...
>
Perhaps it was a typo but the line where you wait for the sensor to
signal that data is ready...

while(!(IOPIN0 && (1 << 22))){;;} // Wait for Data Ready

has an extra & in the masking of IOPIN0. Don't you really mean...

while(!(IOPIN0 & (1 << 22))){;;} // Wait for Data Ready

The first line will only take the while() path once because (1<<22)
will always evaluate (and thus the ! of the whole statement will make
it leave the loop) to true and it won't ever matter what the read
of IOPIN0 is. This seems like it may be consistent with your failure
since the sensor is probably never ready when you start asking it for
the data (i.e doing you SPI reads).

Try Alan's example code with this correction and maybe things will
start working..assuming you've configured the peripheral properly etc.

Also, someone made the point about the SSEL1 toggling after every
byte. This may cause problems with the sensor which probably expects
the chip select to stay low through all 16 clocks for the data. So
unless you are manually controlling another GPIO for the chip
select...be aware of that behaviour on SSEL1.

Hope this helps.

Best regards,
Ryan.

--- In l..., "Alan Strickland"
wrote:
>
> To clear the SPIF bit in S1SPSR you have to access the S1SPSR then
> access the S1SPDR (ie read or write to it). You also have to shift
> out a byte to receive one, and wait for the SPI status to indicate
> SPIF before the received byte can be read.
>
> I use interrupts, so I can't speak to how well polling the SPI
status
> register works. This code is also ignoring any errors that the SPI
> may be setting as well.
>
> Try something along these lines:
>
> S1SPDR = 0x41; // Send Measure X command
> while((S1SPSR & 0x80)!= 0x80){;;} // Wait for SPI status
> temp = S1SPDR; // Clears SPIF in S1SPSR.
>
> while(!(IOPIN0 && (1 << 22))){;;} // Wait for Data Ready
>
> S1SPDR = 0;.
> while((S1SPSR & 0x80)!= 0x80){;;} // Wait for SPI status
> MM3_HB = S1SPDR; // Clears SPIF in S1SPSR.
>
> S1SPDR = 0;
> while((S1SPSR & 0x80)!= 0x80){;;} // Wait for SPI status
> MM3_LB = S1SPDR; // Clears SPIF in S1SPSR.
>
> wMM3_X = MM3_HB;
> wMM3_X = (wMM3_X << 8) | MM3_LB;
>
> --- In l..., "irafalovsky" wrote:
> >
> > If we attempt to send 2 bytes after peripheral indicates
available
> > data, we simply get zeroes in return...
> >
> > Here's what code looks like:
> >
> > IOSET0 |= 1 << 23; // Set RESET HIGH, this is to reset the MM3
> > delay(10);
> > IOCLR0 |= 1 << 23; // Set RESET LOW, pulse formed
> > delay(10);
> > S1SPDR = 0x41; // Send Measure X command
> > while((S1SPSR & 0x80)!= 0x80){;;} // Wait for SPI status
> > while(!(IOPIN0 && (1 << 22))){;;} // Wait for Data Ready
> > S1SPDR = 0;
> > S1SPDR = 0;
> > MM3_HB = S1SPDR;
> > MM3_LB = S1SPDR;
> > wMM3_X = MM3_HB;
> > wMM3_X = (wMM3_X << 8) | MM3_LB;
> >
> >
> > >
> > > Do you send 2 bytes out from LPC2119 to allow the SPI clock to
go so
> > > you can get back the 2 bytes that you are expecting?
> > >
> > > We have an application with LPC2138 running in slave mode and
> > > receiving packets of 9 bits characters from an host processor
and
> > > responding with packets of 9 bits characters.
> > > Naturally, in order to be able to send back the answer the LPC
must
> > > receive the spi clock from the master so the host processor
must pump
> > > out dummy characters to allow the answer to come back.
> > >
> > > Regards,
> > >
> > > Carlo Barbaro
> > >
>
>Original Message:
>-----------------
>From: derbaier
>The User Manual for the LPC2119 does not seem to indicate any
>capability for SPI transfer sizes other than 8 bits at a time? However
>the user manuals for the LPC2138 and LPC2148 *do* indicate transfer
>sizes from 8 to 16 bits per transfer, and give control register
>settings for doing those transfer sizes. It probably could be infered
>from that, that if the LPC2119 could do 16 bit transfers that the
>manual would have indicated it??????????

Don't confuse word size with frame size. I have not seen an SPI peripheral
yet that limited the frame size even though many have a fixed word size of
8 bits.

The standard SPI peripheral, which I have worked with, uses a fixed 8 bit
words size and has no problem with multiple word in the same frame.

Robert
--------------------------------
mail2web - Check your email from the web at
http://mail2web.com/ .
It seems that LPC2138/LPC2148 have SPI1 configured as SSP with
buffered data register, which manual for LPC2119 has no mentioning
of... In fact, first two bits of S1SPCR register are defined as
reserved, whereas first two bits of this register for 2138/2148
defind as data size...

--- In l..., "derbaier" wrote:
> The User Manual for the LPC2119 does not seem to indicate any
> capability for SPI transfer sizes other than 8 bits at a time?
However
> the user manuals for the LPC2138 and LPC2148 *do* indicate transfer
> sizes from 8 to 16 bits per transfer, and give control register
> settings for doing those transfer sizes. It probably could be
infered
> from that, that if the LPC2119 could do 16 bit transfers that the
> manual would have indicated it??????????
>
> http://www.standardics.philips.com/products/lpc2000/
>
> -- Dave
> --- In l..., wrote:
> >
> > I was never able to get the SPI engine to send 16 bits. I
ended up
> writing my own code to do it by GPIO.
> > I don't believe the LPC SPI engines can do anything but 8 bit
data
> word size.
> >
> > Chris.
> >
> >
> > ----- Original Message -----
> > From: irafalovsky
> > To: l...
> > Sent: Tuesday, August 08, 2006 9:00 PM
> > Subject: [lpc2000] Re: Problem with SPI1 on LPC2119
> >
> >
> > Thank you for your help! Unfortunately, this approach does not
work
> > either...
>
In our code, we make chipselect using a separate pin, LPC2119
requires SPI SSEL pin to be high if MCU is in master mode, therefore
we connected it to VDD, as per user manual.

I will ask the engineer who used && operand there for his reasoning,
I think it wasn't a typo...

--- In l..., "tirfec" wrote:
>
> Perhaps it was a typo but the line where you wait for the sensor
to
> signal that data is ready...
>
> while(!(IOPIN0 && (1 << 22))){;;} // Wait for Data Ready
>
> has an extra & in the masking of IOPIN0. Don't you really mean...
>
> while(!(IOPIN0 & (1 << 22))){;;} // Wait for Data Ready
>
> The first line will only take the while() path once because
(1<<22)
> will always evaluate (and thus the ! of the whole statement will
make
> it leave the loop) to true and it won't ever matter what the read
> of IOPIN0 is. This seems like it may be consistent with your
failure
> since the sensor is probably never ready when you start asking it
for
> the data (i.e doing you SPI reads).
>
> Try Alan's example code with this correction and maybe things will
> start working..assuming you've configured the peripheral properly
etc.
>
> Also, someone made the point about the SSEL1 toggling after every
> byte. This may cause problems with the sensor which probably
expects
> the chip select to stay low through all 16 clocks for the data. So
> unless you are manually controlling another GPIO for the chip
> select...be aware of that behaviour on SSEL1.
>
> Hope this helps.
>
> Best regards,
> Ryan.
>
> --- In l..., "Alan Strickland"
> wrote:
> >
> > To clear the SPIF bit in S1SPSR you have to access the S1SPSR
then
> > access the S1SPDR (ie read or write to it). You also have to
shift
> > out a byte to receive one, and wait for the SPI status to
indicate
> > SPIF before the received byte can be read.
> >
> > I use interrupts, so I can't speak to how well polling the SPI
> status
> > register works. This code is also ignoring any errors that the
SPI
> > may be setting as well.
> >
> > Try something along these lines:
> >
> > S1SPDR = 0x41; // Send Measure X command
> > while((S1SPSR & 0x80)!= 0x80){;;} // Wait for SPI status
> > temp = S1SPDR; // Clears SPIF in S1SPSR.
> >
> > while(!(IOPIN0 && (1 << 22))){;;} // Wait for Data Ready
> >
> > S1SPDR = 0;.
> > while((S1SPSR & 0x80)!= 0x80){;;} // Wait for SPI status
> > MM3_HB = S1SPDR; // Clears SPIF in S1SPSR.
> >
> > S1SPDR = 0;
> > while((S1SPSR & 0x80)!= 0x80){;;} // Wait for SPI status
> > MM3_LB = S1SPDR; // Clears SPIF in S1SPSR.
> >
> > wMM3_X = MM3_HB;
> > wMM3_X = (wMM3_X << 8) | MM3_LB;
> >
> > --- In l..., "irafalovsky" wrote:
> > >
> > > If we attempt to send 2 bytes after peripheral indicates
> available
> > > data, we simply get zeroes in return...
> > >
> > > Here's what code looks like:
> > >
> > > IOSET0 |= 1 << 23; // Set RESET HIGH, this is to reset the
MM3
> > > delay(10);
> > > IOCLR0 |= 1 << 23; // Set RESET LOW, pulse formed
> > > delay(10);
> > > S1SPDR = 0x41; // Send Measure X command
> > > while((S1SPSR & 0x80)!= 0x80){;;} // Wait for SPI status
> > > while(!(IOPIN0 && (1 << 22))){;;} // Wait for Data Ready
> > > S1SPDR = 0;
> > > S1SPDR = 0;
> > > MM3_HB = S1SPDR;
> > > MM3_LB = S1SPDR;
> > > wMM3_X = MM3_HB;
> > > wMM3_X = (wMM3_X << 8) | MM3_LB;
> > >
> > >
> > > >
> > > > Do you send 2 bytes out from LPC2119 to allow the SPI clock
to
> go so
> > > > you can get back the 2 bytes that you are expecting?
> > > >
> > > > We have an application with LPC2138 running in slave mode and
> > > > receiving packets of 9 bits characters from an host
processor
> and
> > > > responding with packets of 9 bits characters.
> > > > Naturally, in order to be able to send back the answer the
LPC
> must
> > > > receive the spi clock from the master so the host processor
> must pump
> > > > out dummy characters to allow the answer to come back.
> > > >
> > > > Regards,
> > > >
> > > > Carlo Barbaro
> > > >
> > >
>
--- In l..., "subscriptions@..."
wrote:
>
> >Original Message:
> >-----------------
> >From: derbaier
> >The User Manual for the LPC2119 does not seem to indicate any
> >capability for SPI transfer sizes other than 8 bits at a time? However
> >the user manuals for the LPC2138 and LPC2148 *do* indicate transfer
> >sizes from 8 to 16 bits per transfer, and give control register
> >settings for doing those transfer sizes. It probably could be infered
> >from that, that if the LPC2119 could do 16 bit transfers that the
> >manual would have indicated it??????????
>
> Don't confuse word size with frame size. I have not seen an SPI
peripheral
> yet that limited the frame size even though many have a fixed word
size of
> 8 bits.
>
> The standard SPI peripheral, which I have worked with, uses a fixed
8 bit
> words size and has no problem with multiple word in the same frame.
>
> Robert
>
Your interpretation *may* be more correct than mine, but I thought
that it might be useful to put that information out since nothing else
has worked so far.

My interpretation from the SPI documentation is that the word size is
defined by hardware, and frame size is purely a software construct
above the hardware implementation. So any frame size should work as
long as both sides of the transaction aggree what it is. However, both
sets of hardware also need to agree on a word size too, since the
state machines controling the transfer need to remain in
synchronization. That is how I viewed the transfer when I built some
code to use SPI with MMC/SD cards, and it does work when viewed that way.

-- Dave
>Original Message:
>-----------------
>From: derbaier
>My interpretation from the SPI documentation is that the word size is
>defined by hardware, and frame size is purely a software construct
>above the hardware implementation. So any frame size should work as
>long as both sides of the transaction aggree what it is.

Agreed, although some SPI HW lets you choose the word size to some degree.
The HW/SW split is pretty arbitrary, it could occur at any level. The
hierarchy is reasonable though and it's not a bad mental model.
>However, both
>sets of hardware also need to agree on a word size too, since the
>state machines controling the transfer need to remain in
>synchronization.

There is no way for the slave HW to know how many bits the master uses per
word so it cannot have any dependancies on word size. However, all the SPI
slaves I've used that have frame sizes that are not muliples of 8 bits
allow the frame to be padded up to an 8 bit multiple at either the leading
or trailing edge. Some allow an arbitrary padding only paying attention to
the first n or last n bits.

I've heard rumors that devices exist that frame on clock idle times rather
than a chip select, in that case interword delays would need to be checked.
Strictly speaking that's not really SPI anymore though.
Robert
--------------------------------
mail2web - Check your email from the web at
http://mail2web.com/ .
--- In l..., "irafalovsky" wrote:
>
> It seems that LPC2138/LPC2148 have SPI1 configured as SSP with
> buffered data register, which manual for LPC2119 has no mentioning
> of... In fact, first two bits of S1SPCR register are defined as
> reserved, whereas first two bits of this register for 2138/2148
> defind as data size...
>
> --- In l..., "derbaier" wrote:

In the LPC2138/48 there two SPIs. SPI0 is "Compliant with Serial
Peripheral Interface (SPI) specification." , whereas SPI1 is
"Compatible with Motorola SPI, 4-wire TI SSI, and National
Semiconductor Microwire
buses." In SPI0 bits 11:8 of S0SPCR control the units of transfer,
while bits 3:0 of SSPCR0 in SPI1 control the units of transfer. There
is also an 8 word/frame FIFO in SPI1 which is 16 bits wide, as is the
data register of SPI0. However, the data register of the LPC2119 is
only 8 bits wide, so transfers have to be in units of 8 bits. You
should be able to combine as many 8 bit units as needed if both sides
of the transfer agree, since the hardware state machine in the LPC2119
is going to deslect the slave after each 8 bit unit.
That is all in my interpretation of course!

-- Dave

The 2024 Embedded Online Conference