lpc2148: wiered SSP behaviour or hardware bug???

Started by diwilru December 13, 2005
Hi Fellows,

Something strange happens when I try to use SSP in lpc2148.

So, I initiate SSP as per spi1_init(2,11) in SPI mode with tx FIFO half empty interrupts
enabled (see the code below).

Then I start to transfer bytes over SPI.
The first portion of the data until tx FIFO is empty being transfered Ok. Then
I expect SPI1 interrupt routine should be called, but it never happens. I actually
expect ISR being called when tx FIFO is half empty in order to stuff it with more data.

I got also timer interrupts configured on compare match and it works.

However, if I configure SPI1 interrupts having higher priority than timer's ones none of
interrupts happen. Nevertheless SPI1's tx FIFO being emptied.

If I assign SPI1 to default vector, SPI1 generates interrupts, but...

RFF bit is always 1 regardless of the number of words I write to SSPDR.
MCU falls into SPI ISR and never exits from it.

The question is:
Is this a hardware bug or did I miss something?

MCU works as expected if timer0, I2C and UART0 interrupts enabled.
Compiler is not an issue - the binary code is fine (no inter-working , arm mode only)
None of unexpected interrupts happen.
Pull-up at SSEL1 does not make any difference.

Thanks in advance
Dmitry.

===================================================
void __attribute__((naked)) spi1_ISR(void);

void
spi1_init(int divide, int prio)
{
int *veccntl = (int *)0xFFFFF200 + prio;
int *vecaddr = (int *)0xFFFFF100 + prio;

PINSEL1 |= (2<<2) | (2<<4) | (2<<6) | (2<<8);

SSPCR0 = (0xf<<0) | (1<<6) | (1<<7); // CPOL == 1; CHPA == 1, 16-bit
transfer

SSPCPSR = divide;

SSPIMSC = 0x8; // tx FIFO half empty

VICIntSelect &= ~VIC_BIT(VIC_SPI1); // SPI1 selected as IRQ
VICIntEnable |= VIC_BIT(VIC_SPI1); // SPI1 interrupt enabled

*veccntl = VIC_ENABLE | VIC_SPI1;
*vecaddr = (uint32_t)spi1_ISR; // address of the ISR

SSPCR1 = 2 ;

}

void __attribute__((naked)) spi1_ISR(void)
{
unsigned int why;
short dummy;
ISR_ENTRY(); // clear rcv bit

why = SSPMIS;

if(why == 8)
SSPDR = 0x1111;

if(why != 8)
SSPICR = 3;
VICVectAddr = 0x00000000; // Clear interrupt in
ISR_EXIT();
}


An Engineer's Guide to the LPC2100 Series

Just found a problem:

The lpc2148 user guide says:
If SSE bit in SSPCR1 is set "The SSP controller will interact with other devices on the
serial bus. Software should write the appropriate control information to the other SSP
registers and interrupt controller registers, before setting this bit."

However, if SSPIMSC with an appropriate interrupt mask is updated afret SSPCR1 value
is set to 2 then everything works just fine!

manual manual manual.....

Cheers,
Dmitry.