EmbeddedRelated.com
Forums

Device halts when SPI clock divider is set...

Started by Me August 16, 2009
I'm using an LPC2148 on a project. I need to interface with an SPI
device with the microcontroller as the master. I'm just setting things
up now, trying to get a clock signal out from the '2148.

Right now my program doesn't do much. There is a polled serial output
routine that emits debug messages and I toggle a GPIO pin to show that
the micro is alive.

Everything worked well until I attempted to set the SPI clock divisor,
SOSPCCR. If I don't set it, the processor runs fine, though I don't get
any output from the SPI clock like I would expect.

As soon as I set the SPI clock divisor, the microcontroller stops
running after 10 seconds or so. If I leave it unset, it runs forever
with no problem, other than there is no SPI clock output.

I have no interrupts enabled.

Here is the relevant code:

// set up the SPI pins to drive the 8 channel DAC
// TI TLC5628.

// P0.4 gets set to the SCK0 function
// set bits 9:8 on PINSEL0 to 0b01
PINSEL0 = PINSEL0 | (0x01 << 8);

// P0.5 gets set to a GPIO output
// nothing to set here for the function
// but make it an output pin
IO0DIR = IO0DIR | (0x01 << 5);

// P0.6 gets set to the M0SIO function
// set bits 13:12 to 0b01 on PINSEL0
PINSEL0 = PINSEL0 | (0x01 << 12);

// Set up S0SPCCR (Clock Counter Register)
// The SPI0 rate may be calculated as: PCLK / SPCCR0 value. The PCLK
rate is
// CCLK /APB divider rate as determined by the APBDIV register contents.
// must always be even and great than 8.

// CCLK is 60 MHz. 12 MHz crystal with a div by 5. (Register loaded
with 4)
// APBDIV is 1.0. Thus the PCLK is running at 60 MHz.
// A 100 KHz SPI clock would need a divisor of 60 MHz/ 100 KHz = 600.

S0SPCCR = 600; // was 16

// Set up S0SPCR (SPI Control Register)
// bits 1:0 - not used
// bit 2: value = 1. Send the bit count according to bits 11:8
// bit 3: CPHA value = 1 Data is sampled on the second clock edge
// bit 4: CPOL value = 0 SCK is active high
// bit 5: MSTR value = 1 SPI operates in master mode
// bit 6: LSBF value = 1 LSB is transferred first
// bit 7: SPIE value = 0 No interrupts
// bits 11:8 bit count. Value = 0b1100 (12d) 12 bit transfers
// bits 15:12 not used
S0SPCR = (12 << 8) + (1 << 6) + (1 << 5) + (1 << 3) + (1 << 2);

I have an ARM-USB debugger, but I am only using it for flashing code
right now.

Any ideas why this is happening or how I would troubleshoot it ?

Are there any limits on what PCLK or the SPI clock can run at ?

Thanks

An Engineer's Guide to the LPC2100 Series

I just saw that the divider is a 7 bit value. I decreased my divisor to
254 and it seems to work fine.

I'd still like to know if there any limits on what PCLK or the SPI clock
can run at ?

Thanks
On Sun, 2009-08-16 at 20:36 -0600, Me wrote:
> I'm using an LPC2148 on a project. I need to interface with an SPI
> device with the microcontroller as the master. I'm just setting things
> up now, trying to get a clock signal out from the '2148.
>
> Right now my program doesn't do much. There is a polled serial output
> routine that emits debug messages and I toggle a GPIO pin to show that
> the micro is alive.
>
> Everything worked well until I attempted to set the SPI clock divisor,
> SOSPCCR. If I don't set it, the processor runs fine, though I don't get
> any output from the SPI clock like I would expect.
>
> As soon as I set the SPI clock divisor, the microcontroller stops
> running after 10 seconds or so. If I leave it unset, it runs forever
> with no problem, other than there is no SPI clock output.
>
> I have no interrupts enabled.
>
> Here is the relevant code:
>
> // set up the SPI pins to drive the 8 channel DAC
> // TI TLC5628.
>
> // P0.4 gets set to the SCK0 function
> // set bits 9:8 on PINSEL0 to 0b01
> PINSEL0 = PINSEL0 | (0x01 << 8);
>
> // P0.5 gets set to a GPIO output
> // nothing to set here for the function
> // but make it an output pin
> IO0DIR = IO0DIR | (0x01 << 5);
>
> // P0.6 gets set to the M0SIO function
> // set bits 13:12 to 0b01 on PINSEL0
> PINSEL0 = PINSEL0 | (0x01 << 12);
>
> // Set up S0SPCCR (Clock Counter Register)
> // The SPI0 rate may be calculated as: PCLK / SPCCR0 value. The PCLK
> rate is
> // CCLK /APB divider rate as determined by the APBDIV register contents.
> // must always be even and great than 8.
>
> // CCLK is 60 MHz. 12 MHz crystal with a div by 5. (Register loaded
> with 4)
> // APBDIV is 1.0. Thus the PCLK is running at 60 MHz.
> // A 100 KHz SPI clock would need a divisor of 60 MHz/ 100 KHz = 600.
>
> S0SPCCR = 600; // was 16
>
> // Set up S0SPCR (SPI Control Register)
> // bits 1:0 - not used
> // bit 2: value = 1. Send the bit count according to bits 11:8
> // bit 3: CPHA value = 1 Data is sampled on the second clock edge
> // bit 4: CPOL value = 0 SCK is active high
> // bit 5: MSTR value = 1 SPI operates in master mode
> // bit 6: LSBF value = 1 LSB is transferred first
> // bit 7: SPIE value = 0 No interrupts
> // bits 11:8 bit count. Value = 0b1100 (12d) 12 bit transfers
> // bits 15:12 not used
> S0SPCR = (12 << 8) + (1 << 6) + (1 << 5) + (1 << 3) + (1 << 2);
>
> I have an ARM-USB debugger, but I am only using it for flashing code
> right now.
>
> Any ideas why this is happening or how I would troubleshoot it ?
>
> Are there any limits on what PCLK or the SPI clock can run at ?
>
> Thanks

--- In l..., Me wrote:
>
> I just saw that the divider is a 7 bit value. I decreased my divisor to
> 254 and it seems to work fine.
>
> I'd still like to know if there any limits on what PCLK or the SPI clock
> can run at ?
>
> Thanks
> On Sun, 2009-08-16 at 20:36 -0600, Me wrote:
> > I'm using an LPC2148 on a project. I need to interface with an SPI
> > device with the microcontroller as the master. I'm just setting things
> > up now, trying to get a clock signal out from the '2148.
> >
> > Right now my program doesn't do much. There is a polled serial output
> > routine that emits debug messages and I toggle a GPIO pin to show that
> > the micro is alive.
> >
> > Everything worked well until I attempted to set the SPI clock divisor,
> > SOSPCCR. If I don't set it, the processor runs fine, though I don't get
> > any output from the SPI clock like I would expect.
> >
> > As soon as I set the SPI clock divisor, the microcontroller stops
> > running after 10 seconds or so. If I leave it unset, it runs forever
> > with no problem, other than there is no SPI clock output.
> >
> > I have no interrupts enabled.
> >
> > Here is the relevant code:
> >
> > // set up the SPI pins to drive the 8 channel DAC
> > // TI TLC5628.
> >
> > // P0.4 gets set to the SCK0 function
> > // set bits 9:8 on PINSEL0 to 0b01
> > PINSEL0 = PINSEL0 | (0x01 << 8);
> >
> > // P0.5 gets set to a GPIO output
> > // nothing to set here for the function
> > // but make it an output pin
> > IO0DIR = IO0DIR | (0x01 << 5);
> >
> > // P0.6 gets set to the M0SIO function
> > // set bits 13:12 to 0b01 on PINSEL0
> > PINSEL0 = PINSEL0 | (0x01 << 12);
> >
> > // Set up S0SPCCR (Clock Counter Register)
> > // The SPI0 rate may be calculated as: PCLK / SPCCR0 value. The PCLK
> > rate is
> > // CCLK /APB divider rate as determined by the APBDIV register contents.
> > // must always be even and great than 8.
> >
> > // CCLK is 60 MHz. 12 MHz crystal with a div by 5. (Register loaded
> > with 4)
> > // APBDIV is 1.0. Thus the PCLK is running at 60 MHz.
> > // A 100 KHz SPI clock would need a divisor of 60 MHz/ 100 KHz = 600.
> >
> > S0SPCCR = 600; // was 16
> >
> > // Set up S0SPCR (SPI Control Register)
> > // bits 1:0 - not used
> > // bit 2: value = 1. Send the bit count according to bits 11:8
> > // bit 3: CPHA value = 1 Data is sampled on the second clock edge
> > // bit 4: CPOL value = 0 SCK is active high
> > // bit 5: MSTR value = 1 SPI operates in master mode
> > // bit 6: LSBF value = 1 LSB is transferred first
> > // bit 7: SPIE value = 0 No interrupts
> > // bits 11:8 bit count. Value = 0b1100 (12d) 12 bit transfers
> > // bits 15:12 not used
> > S0SPCR = (12 << 8) + (1 << 6) + (1 << 5) + (1 << 3) + (1 << 2);
> >
> > I have an ARM-USB debugger, but I am only using it for flashing code
> > right now.
> >
> > Any ideas why this is happening or how I would troubleshoot it ?
> >
> > Are there any limits on what PCLK or the SPI clock can run at ?
> >
> > Thanks
>

I wondered about that also. The way I interpreted the manual, it seemed to strongly imply that either 15 or 20MHz was tops. About a month ago, someone here posted a link to an old thread (also here) in which an NXP rep assured the group that a 60MHz PCLK would work fine. Sorry, too lazy to track down the thread - dunno re the SPI clock.

-Hugh

Hi:

The LPC2148 User Manual clearly states that the S0SPCCR register is a 8 bit register and its value should be an even number greater than 8(range from 10 to 254). 600 is invalid.
(User Manual UM10139.pdf Revision 0.1 August 2005, Section 12.4.4, page 178).

Therefore, you need to calculate a different SPI clock Frequency or use a divided PCLK for the SPI peripheral.

Regards,

Alex.
--- In l..., Me wrote:
>
> I'm using an LPC2148 on a project. I need to interface with an SPI
> device with the microcontroller as the master. I'm just setting things
> up now, trying to get a clock signal out from the '2148.
>
> Right now my program doesn't do much. There is a polled serial output
> routine that emits debug messages and I toggle a GPIO pin to show that
> the micro is alive.
>
> Everything worked well until I attempted to set the SPI clock divisor,
> SOSPCCR. If I don't set it, the processor runs fine, though I don't get
> any output from the SPI clock like I would expect.
>
> As soon as I set the SPI clock divisor, the microcontroller stops
> running after 10 seconds or so. If I leave it unset, it runs forever
> with no problem, other than there is no SPI clock output.
>
> I have no interrupts enabled.
>
> Here is the relevant code:
>
> // set up the SPI pins to drive the 8 channel DAC
> // TI TLC5628.
>
> // P0.4 gets set to the SCK0 function
> // set bits 9:8 on PINSEL0 to 0b01
> PINSEL0 = PINSEL0 | (0x01 << 8);
>
> // P0.5 gets set to a GPIO output
> // nothing to set here for the function
> // but make it an output pin
> IO0DIR = IO0DIR | (0x01 << 5);
>
> // P0.6 gets set to the M0SIO function
> // set bits 13:12 to 0b01 on PINSEL0
> PINSEL0 = PINSEL0 | (0x01 << 12);
>
> // Set up S0SPCCR (Clock Counter Register)
> // The SPI0 rate may be calculated as: PCLK / SPCCR0 value. The PCLK
> rate is
> // CCLK /APB divider rate as determined by the APBDIV register contents.
> // must always be even and great than 8.
>
> // CCLK is 60 MHz. 12 MHz crystal with a div by 5. (Register loaded
> with 4)
> // APBDIV is 1.0. Thus the PCLK is running at 60 MHz.
> // A 100 KHz SPI clock would need a divisor of 60 MHz/ 100 KHz = 600.
>
> S0SPCCR = 600; // was 16
>
> // Set up S0SPCR (SPI Control Register)
> // bits 1:0 - not used
> // bit 2: value = 1. Send the bit count according to bits 11:8
> // bit 3: CPHA value = 1 Data is sampled on the second clock edge
> // bit 4: CPOL value = 0 SCK is active high
> // bit 5: MSTR value = 1 SPI operates in master mode
> // bit 6: LSBF value = 1 LSB is transferred first
> // bit 7: SPIE value = 0 No interrupts
> // bits 11:8 bit count. Value = 0b1100 (12d) 12 bit transfers
> // bits 15:12 not used
> S0SPCR = (12 << 8) + (1 << 6) + (1 << 5) + (1 << 3) + (1 << 2);
>
> I have an ARM-USB debugger, but I am only using it for flashing code
> right now.
>
> Any ideas why this is happening or how I would troubleshoot it ?
>
> Are there any limits on what PCLK or the SPI clock can run at ?
>
> Thanks
>
Just reading through your code comments and was wondering if you are really attempting to talk to the the TI TLC5628 as your comments say?
If so, does it work with LSB first (your setting in the S0SPCR)?
Can't the TI part run faster than 100kHz (your comment....)?
Any reason to use SPI over the SSP controller? Just curious...

--- In l..., Me wrote:
>
> I'm using an LPC2148 on a project. I need to interface with an SPI
> device with the microcontroller as the master. I'm just setting things
> up now, trying to get a clock signal out from the '2148.
>
> Right now my program doesn't do much. There is a polled serial output
> routine that emits debug messages and I toggle a GPIO pin to show that
> the micro is alive.
>
> Everything worked well until I attempted to set the SPI clock divisor,
> SOSPCCR. If I don't set it, the processor runs fine, though I don't get
> any output from the SPI clock like I would expect.
>
> As soon as I set the SPI clock divisor, the microcontroller stops
> running after 10 seconds or so. If I leave it unset, it runs forever
> with no problem, other than there is no SPI clock output.
>
> I have no interrupts enabled.
>
> Here is the relevant code:
>
> // set up the SPI pins to drive the 8 channel DAC
> // TI TLC5628.
>
> // P0.4 gets set to the SCK0 function
> // set bits 9:8 on PINSEL0 to 0b01
> PINSEL0 = PINSEL0 | (0x01 << 8);
>
> // P0.5 gets set to a GPIO output
> // nothing to set here for the function
> // but make it an output pin
> IO0DIR = IO0DIR | (0x01 << 5);
>
> // P0.6 gets set to the M0SIO function
> // set bits 13:12 to 0b01 on PINSEL0
> PINSEL0 = PINSEL0 | (0x01 << 12);
>
> // Set up S0SPCCR (Clock Counter Register)
> // The SPI0 rate may be calculated as: PCLK / SPCCR0 value. The PCLK
> rate is
> // CCLK /APB divider rate as determined by the APBDIV register contents.
> // must always be even and great than 8.
>
> // CCLK is 60 MHz. 12 MHz crystal with a div by 5. (Register loaded
> with 4)
> // APBDIV is 1.0. Thus the PCLK is running at 60 MHz.
> // A 100 KHz SPI clock would need a divisor of 60 MHz/ 100 KHz = 600.
>
> S0SPCCR = 600; // was 16
>
> // Set up S0SPCR (SPI Control Register)
> // bits 1:0 - not used
> // bit 2: value = 1. Send the bit count according to bits 11:8
> // bit 3: CPHA value = 1 Data is sampled on the second clock edge
> // bit 4: CPOL value = 0 SCK is active high
> // bit 5: MSTR value = 1 SPI operates in master mode
> // bit 6: LSBF value = 1 LSB is transferred first
> // bit 7: SPIE value = 0 No interrupts
> // bits 11:8 bit count. Value = 0b1100 (12d) 12 bit transfers
> // bits 15:12 not used
> S0SPCR = (12 << 8) + (1 << 6) + (1 << 5) + (1 << 3) + (1 << 2);
>
> I have an ARM-USB debugger, but I am only using it for flashing code
> right now.
>
> Any ideas why this is happening or how I would troubleshoot it ?
>
> Are there any limits on what PCLK or the SPI clock can run at ?
>
> Thanks
>