EmbeddedRelated.com
Forums

SPI0 on LPC2148

Started by Sutton Mehaffey May 16, 2007
I know somebody is going to chastise me with 'RTFM', but I have and I
have also reviewed numerous posts on this, but I still am unsure. So,
I will ask my version of the question.

In reviewing several SPI posts, it appears that several uCs don't
allow SSEL0 to be used as GPIO as a chip select when used as a master.
SSEL0 must be selected as such thru PINSEL and tied high, otherwise
SPI does not work. And, you must use another pin as chip select. Is
this right? If so, is that a bug or just how the chip works?

And, on the LPC213x and 214x, SSEL0 CAN be used as GPIO as a chip
select, thus not having to utilize another pin for that purpose. Is
that right? And, the only need to use SSEL0 as such is to have the uC
used as a slave device? Is that right?

This question was brought up because I am having some trouble getting
a voice chip to work correctly on either SPI0 or SPI1 on a LPC2148.
It is a beta version of the voice chip, but I remembered about the
posts on SSEL0 and having been trying to make sure I have that
configured correctly. The previous posts haven't made me 100% sure on
the issue.

Thanks.

Sutton

An Engineer's Guide to the LPC2100 Series

> -----Original Message-----
> From: l...
> [mailto:l...]On Behalf
> Of Sutton Mehaffey
> Sent: Wednesday, May 16, 2007 10:24 AM
> To: l...
> Subject: [lpc2000] SPI0 on LPC2148
> I know somebody is going to chastise me with 'RTFM', but I have and I
> have also reviewed numerous posts on this, but I still am unsure. So,
> I will ask my version of the question.
>
> In reviewing several SPI posts, it appears that several uCs don't
> allow SSEL0 to be used as GPIO as a chip select when used as a master.
> SSEL0 must be selected as such thru PINSEL and tied high, otherwise
> SPI does not work. And, you must use another pin as chip select. Is
> this right? If so, is that a bug or just how the chip works?
>
This is correct for the parts that work this way. To my knowledge, it
is not a bug.

> And, on the LPC213x and 214x, SSEL0 CAN be used as GPIO as a chip
> select, thus not having to utilize another pin for that purpose. Is
> that right? And, the only need to use SSEL0 as such is to have the uC
> used as a slave device? Is that right?

For the LPC214x (I don't know about the LPC213x), SSEL0 can be used as
GPIO in master mode. SSEL1 can be used as GPIO, or as an automatic
SSEL. I believe that SSEL is required in slave mode, but I have not
used slave mode.

>
> This question was brought up because I am having some trouble getting
> a voice chip to work correctly on either SPI0 or SPI1 on a LPC2148.
> It is a beta version of the voice chip, but I remembered about the
> posts on SSEL0 and having been trying to make sure I have that
> configured correctly. The previous posts haven't made me 100% sure on
> the issue.
>
> Thanks.
>
> Sutton

Good luck,

Mike
Thanks for your input.

Does anybody see anything functionally wrong with this SPI0 setup?
I'm trying to send a SPI POWER DOWN command (0x12) to a voice chip.
Then READ STATUS (0x40). The Status after POWER DOWN should be 0x80.
Bit 7 is the power down bit. I'm getting a 0x00. Therefore, I think
something is wrong with the code somewhere. I'm getting a SPI bus
monitor next week, but in the meantime, I can't find the problem.

All the other setups work fine, so I won't bore you with all the other
setups (PLL, etc.) unless you want me to verify some setting. Thanks
in advance.

Sutton
void main()
{
unsigned char status;

set_up_spi0();
for(;;)
{
spi_voice(POWER_DOWN);
delay(SEC,0.25);
status = spi_voice(READ_STATUS); // always 00
delay(SEC,0.25);
}
}
void set_up_spi0()
{
// set up SPI0

// P0.4, P0.5, P0.6 need to be SPI0 ports
// P0.7 is GPIO and set high to deselect voice chip

PINSEL0 &= 0xFFFF00FF;
PINSEL0 |= 0x00001500; // P0.4-6 as SPI0 ports, P0.7 as GPIO

IO0DIR |= 0x00000080; // P0.7 as output
IO0SET |= 0x00000080; // SSEL0 = "1" to deselect voice chip

S0SPCR = 0x0038; // master mode, CPHA = CPOL = 1
// (voice chip requires this mode)
S0SPCCR = 0x08; // this makes the SPI0 bus 1.5Mhz
// (PCLK/8 = 12Mhz/8)

PCONP |= 0x00000010; // turn on SPI0
}
void spi0_send(unsigned char *buf, unsigned char buflen)
{
unsigned char i, dummy;

for (i = 0; i < buflen; i++)
{
S0SPDR = *buf;
while ((S0SPSR & 0x80) == 0);
dummy = S0SPDR;
buf++;
}
}
void spi0_rcv(unsigned char *buf, unsigned char buflen)
{
unsigned char i;

for (i = 0; i < buflen; i++)
{
*buf = spi0_rcv_byte();
buf++;
}
}
unsigned char spi0_rcv_byte()
{
unsigned char data;

S0SPDR = 0xff;
while ((S0SPSR & 0x80) == 0);
data = S0SPDR;
return(data);
}
unsigned char spi_voice(unsigned char cmdtype)
{
unsigned char SPIBuf[8];

SPIBuf[0] = cmdtype;
IO0CLR = 0x00000080; // chip select
delay(SEC,0.5);

switch(cmdtype)
{
case READ_STATUS:
spi0_send(SPIBuf,1);
spi0_rcv(SPIBuf,1);
IO0SET = 0x00000080; // chip unselect
return(SPIBuf[0]);

case POWER_UP:
case POWER_DOWN:
spi0_send(SPIBuf,1);
IO0SET = 0x00000080; // chip unselect
return(0);

default:
IO0SET = 0x00000080;
return(0);
}
}

--- In l..., "Michael Anton" wrote:
>
> > -----Original Message-----
> > From: l...
> > [mailto:l...]On Behalf
> > Of Sutton Mehaffey
> > Sent: Wednesday, May 16, 2007 10:24 AM
> > To: l...
> > Subject: [lpc2000] SPI0 on LPC2148
> >
> >
> > I know somebody is going to chastise me with 'RTFM', but I have and I
> > have also reviewed numerous posts on this, but I still am unsure. So,
> > I will ask my version of the question.
> >
> > In reviewing several SPI posts, it appears that several uCs don't
> > allow SSEL0 to be used as GPIO as a chip select when used as a master.
> > SSEL0 must be selected as such thru PINSEL and tied high, otherwise
> > SPI does not work. And, you must use another pin as chip select. Is
> > this right? If so, is that a bug or just how the chip works?
> >
> This is correct for the parts that work this way. To my knowledge, it
> is not a bug.
>
> > And, on the LPC213x and 214x, SSEL0 CAN be used as GPIO as a chip
> > select, thus not having to utilize another pin for that purpose. Is
> > that right? And, the only need to use SSEL0 as such is to have the uC
> > used as a slave device? Is that right?
>
> For the LPC214x (I don't know about the LPC213x), SSEL0 can be used as
> GPIO in master mode. SSEL1 can be used as GPIO, or as an automatic
> SSEL. I believe that SSEL is required in slave mode, but I have not
> used slave mode.
>
> >
> > This question was brought up because I am having some trouble getting
> > a voice chip to work correctly on either SPI0 or SPI1 on a LPC2148.
> > It is a beta version of the voice chip, but I remembered about the
> > posts on SSEL0 and having been trying to make sure I have that
> > configured correctly. The previous posts haven't made me 100% sure on
> > the issue.
> >
> > Thanks.
> >
> > Sutton
> >
> > Good luck,
>
> Mike
>
> -----Original Message-----
> From: l...
> [mailto:l...]On Behalf
> Of Sutton Mehaffey
> Sent: Wednesday, May 16, 2007 3:47 PM
> To: l...
> Subject: [lpc2000] Re: SPI0 on LPC2148
> Thanks for your input.
>
> Does anybody see anything functionally wrong with this SPI0 setup?
> I'm trying to send a SPI POWER DOWN command (0x12) to a voice chip.
> Then READ STATUS (0x40). The Status after POWER DOWN should be 0x80.
> Bit 7 is the power down bit. I'm getting a 0x00. Therefore, I think
> something is wrong with the code somewhere. I'm getting a SPI bus
> monitor next week, but in the meantime, I can't find the problem.
>
> All the other setups work fine, so I won't bore you with all the other
> setups (PLL, etc.) unless you want me to verify some setting. Thanks
> in advance.
>
> Sutton
> void main()
> {
> unsigned char status;
>
> set_up_spi0();
> for(;;)
> {
> spi_voice(POWER_DOWN);
> delay(SEC,0.25);
> status = spi_voice(READ_STATUS); // always 00
> delay(SEC,0.25);
> }
> }
> void set_up_spi0()
> {
> // set up SPI0
>
> // P0.4, P0.5, P0.6 need to be SPI0 ports
> // P0.7 is GPIO and set high to deselect voice chip
>
> PINSEL0 &= 0xFFFF00FF;
> PINSEL0 |= 0x00001500; // P0.4-6 as SPI0 ports, P0.7 as GPIO
>
> IO0DIR |= 0x00000080; // P0.7 as output
> IO0SET |= 0x00000080; // SSEL0 = "1" to deselect voice chip

This should be:
IO0SET = 0x00000080; // SSEL0 = "1" to deselect voice chip

>
> S0SPCR = 0x0038; // master mode, CPHA = CPOL = 1
> // (voice chip requires this mode)
> S0SPCCR = 0x08; // this makes the SPI0 bus 1.5Mhz
> // (PCLK/8 = 12Mhz/8)
>
> PCONP |= 0x00000010; // turn on SPI0

You need to turn on the SPI0 before you access any of its registers.
The way this is currently coded, likely the SPI0 is ignoring the
configuration that you have done, and is using the reset values instead.

Good luck,

Mike
"You need to turn on the SPI0 before you access any of its registers.
The way this is currently coded, likely the SPI0 is ignoring the
configuration that you have done, and is using the reset values instead."

I don't think that is correct. PCONP has all but 1 peripheral turned
on by default. This was just a statement in the code for me to
confirm that, so the code actually did nothing. Usually this
statement is omitted in most code that I have seen. In any case, it
made no difference.

Sutton
--- In l..., "Michael Anton" wrote:
>
> > -----Original Message-----
> > From: l...
> > [mailto:l...]On Behalf
> > Of Sutton Mehaffey
> > Sent: Wednesday, May 16, 2007 3:47 PM
> > To: l...
> > Subject: [lpc2000] Re: SPI0 on LPC2148
> >
> >
> > Thanks for your input.
> >
> > Does anybody see anything functionally wrong with this SPI0 setup?
> > I'm trying to send a SPI POWER DOWN command (0x12) to a voice chip.
> > Then READ STATUS (0x40). The Status after POWER DOWN should be 0x80.
> > Bit 7 is the power down bit. I'm getting a 0x00. Therefore, I think
> > something is wrong with the code somewhere. I'm getting a SPI bus
> > monitor next week, but in the meantime, I can't find the problem.
> >
> > All the other setups work fine, so I won't bore you with all the other
> > setups (PLL, etc.) unless you want me to verify some setting. Thanks
> > in advance.
> >
> > Sutton
> >
> >
> > void main()
> > {
> > unsigned char status;
> >
> > set_up_spi0();
> > for(;;)
> > {
> > spi_voice(POWER_DOWN);
> > delay(SEC,0.25);
> > status = spi_voice(READ_STATUS); // always 00
> > delay(SEC,0.25);
> > }
> > }
> >
> >
> > void set_up_spi0()
> > {
> > // set up SPI0
> >
> > // P0.4, P0.5, P0.6 need to be SPI0 ports
> > // P0.7 is GPIO and set high to deselect voice chip
> >
> > PINSEL0 &= 0xFFFF00FF;
> > PINSEL0 |= 0x00001500; // P0.4-6 as SPI0 ports, P0.7 as GPIO
> >
> > IO0DIR |= 0x00000080; // P0.7 as output
> > IO0SET |= 0x00000080; // SSEL0 = "1" to deselect voice chip
>
> This should be:
> IO0SET = 0x00000080; // SSEL0 = "1" to deselect voice chip
>
> >
> > S0SPCR = 0x0038; // master mode, CPHA = CPOL = 1
> > // (voice chip requires this mode)
> > S0SPCCR = 0x08; // this makes the SPI0 bus 1.5Mhz
> > // (PCLK/8 = 12Mhz/8)
> >
> > PCONP |= 0x00000010; // turn on SPI0
>
> You need to turn on the SPI0 before you access any of its registers.
> The way this is currently coded, likely the SPI0 is ignoring the
> configuration that you have done, and is using the reset values instead.
>
> Good luck,
>
> Mike
>
> -----Original Message-----
> From: l...
> [mailto:l...]On Behalf
> Of Sutton Mehaffey
> Sent: Thursday, May 17, 2007 5:38 AM
> To: l...
> Subject: [lpc2000] Re: SPI0 on LPC2148
> "You need to turn on the SPI0 before you access any of its registers.
> The way this is currently coded, likely the SPI0 is ignoring the
> configuration that you have done, and is using the reset
> values instead."
>
> I don't think that is correct. PCONP has all but 1 peripheral turned
> on by default. This was just a statement in the code for me to
> confirm that, so the code actually did nothing. Usually this
> statement is omitted in most code that I have seen. In any case, it
> made no difference.
>
> Sutton

You are correct. As long as the peripheral was already on, you are
ok. In my code, I turn all peripherals off, and then turn them on
when the init functions get called.

Have you verified that you get traffic on the SPI bus? If you do,
then there is probably some issue in the protocol used to communicate
with the chip.

Mike
> --- In l..., "Michael Anton" wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: l...
> > > [mailto:l...]On Behalf
> > > Of Sutton Mehaffey
> > > Sent: Wednesday, May 16, 2007 3:47 PM
> > > To: l...
> > > Subject: [lpc2000] Re: SPI0 on LPC2148
> > >
> > >
> > > Thanks for your input.
> > >
> > > Does anybody see anything functionally wrong with this
> SPI0 setup?
> > > I'm trying to send a SPI POWER DOWN command (0x12) to a
> voice chip.
> > > Then READ STATUS (0x40). The Status after POWER DOWN
> should be 0x80.
> > > Bit 7 is the power down bit. I'm getting a 0x00.
> Therefore, I think
> > > something is wrong with the code somewhere. I'm getting a SPI bus
> > > monitor next week, but in the meantime, I can't find the problem.
> > >
> > > All the other setups work fine, so I won't bore you with
> all the other
> > > setups (PLL, etc.) unless you want me to verify some
> setting. Thanks
> > > in advance.
> > >
> > > Sutton
> > >
> > >
> > > void main()
> > > {
> > > unsigned char status;
> > >
> > > set_up_spi0();
> > > for(;;)
> > > {
> > > spi_voice(POWER_DOWN);
> > > delay(SEC,0.25);
> > > status = spi_voice(READ_STATUS); // always 00
> > > delay(SEC,0.25);
> > > }
> > > }
> > >
> > >
> > > void set_up_spi0()
> > > {
> > > // set up SPI0
> > >
> > > // P0.4, P0.5, P0.6 need to be SPI0 ports
> > > // P0.7 is GPIO and set high to deselect voice chip
> > >
> > > PINSEL0 &= 0xFFFF00FF;
> > > PINSEL0 |= 0x00001500; // P0.4-6 as SPI0 ports,
> P0.7 as GPIO
> > >
> > > IO0DIR |= 0x00000080; // P0.7 as output
> > > IO0SET |= 0x00000080; // SSEL0 = "1" to deselect
> voice chip
> >
> > This should be:
> > IO0SET = 0x00000080; // SSEL0 = "1" to deselect
> voice chip
> >
> > >
> > > S0SPCR = 0x0038; // master mode, CPHA = CPOL = 1
> > > // (voice chip requires this mode)
> > > S0SPCCR = 0x08; // this makes the SPI0 bus 1.5Mhz
> > > // (PCLK/8 = 12Mhz/8)
> > >
> > > PCONP |= 0x00000010; // turn on SPI0
> >
> > You need to turn on the SPI0 before you access any of its registers.
> > The way this is currently coded, likely the SPI0 is ignoring the
> > configuration that you have done, and is using the reset
> values instead.
> >
> > Good luck,
> >
> > Mike
> >
>
> Yahoo! Groups Links
>