LPC2378STK SPI Setup

Hi Everybody,

I’m a new user of the ARM platform, and I’m coming up to speed using an Olimex LPC2378STK development board. I’m having trouble getting the SPI to work and talk to the LCD on the board.

I can run the Olimex code that came with the board (shows the Olimex logo on the LCD), and I can run my LED blinky program without any problems. I can also send debug msgs out on UART0 just fine.

I can’t get the SPI working and talking to the LCD though. Here’s my SPI init code:

void InitSpi(void)

{

// Pin P3.25 used for LCD_RST (can only be configured as fast i/o, not // gpio)

PINSEL7 &= ~((1<<19) | (1<<18)); // Configure P3.25 as fast i/o (00)

PINMODE7 &= ~(1<<18); // w/o pullup or pulldown (10)

PINMODE7 |= (1<<19); // w/o pullup or pulldown (10)

FIO3DIR |= (1<<25); // direction = output (1)

// Set P3.25 to HIGH (assert LCD Reset low then high to reset the controller)

FIO3SET |= (1<<25);

// Pin P1.21 used for SSEL0 (chip select)

// PINSEL3 &= ~((1<<11) | (1<<10)); // Configure P1.21 as GPIO

// PINMODE3 &= ~(1<<10); // w/o pullup or pulldown (10)

// PINMODE3 |= (1<<11); // w/o pullup or pulldown (10)

// Set P1.21 to LOW (assert CS_LCD low to enable transmission)

PINSEL3 |= (1<<11) | (1<<10); // set P1.21 = SSEL0 mode

IO1DIR |= (1<<21); // direction = output (1)

IO1CLR |= (1<<21);

PCONP |= (1<<8); // turn on SPI power (PCSPI)

PINSEL3 |= (1<<9) | (1<<8); // set P1.20 = SCK0 mode

IO1DIR |= (1<<20); // direction = output (1)

PINSEL3 |= (1<<17) | (1<<16); // set P1.23/24 = MOSI0 mode

IO1DIR |= (1<<23); // direction = output (1)

// set SPI clock divider = PCLK_SPI / SPCCR0 = (CCLK/4)/ 8

SPI_SPCCR = 0x08;

// PCLKSEL0 &= ~((1<<17) | (1<<16)); // set SPI clock (CCLK / 4)

// set SPI control register

// 9 bit data, phase 0, SCK active low, SPI master, MSb first, interrupts inactive

SPI_SPCR |= (1<<2) | (1<<4) |(1<<5) |(1<<8) |(1<11); // 0000 1001 0011 0100

}

Here’s the code I use to send commands to the LCD:

void WriteSpiCommand(volatile unsigned int command)

{

// wait for the previous transfer to complete

while(!(SPI_SPSR & 0x80)); // wait while not complete

putstring_serial0(“SPI Command XFER Complete…\n”);

// clear bit 8 - indicates a “command”

command = (command & ~0x0100);

// send the command

SPI_SPDR = command;

}

I don’t think anything’s going out to the LCD - the code is stuck on the while loop waiting for SPSR to change state & it never does so the command never goes out. Unfortunately I don’t have a 'scope so I can’t see if there’s a clock signal, etc.

Can anyone see it there’s anything obvious I’m missing in the setup of the SPI? It seems like this should be straightforward but it won’t work.

Thanks all…

hedgehog:
Can anyone see it there’s anything obvious I’m missing in the setup of the SPI?

Yes - The LCD on the LPC2378 STK is is driven by the SSP (i.e. SPI1 not SPI0). Here's my Init Code (in Oberon-07):
  PROCEDURE Init*;
  VAR
    s: SET;
  BEGIN
    SYSTEM.GET(LPC.PCONP, s);
    SYSTEM.PUT(LPC.PCONP, s + {8, 21});
    SYSTEM.GET(LPC.SCS, s);
    SYSTEM.PUT(LPC.SCS, s + {0, 1});
    (* setup    SCK0, SSEL0, MISO0, MOSI0 *)
    (* PS3 bits  9:8, 11:10, 15:14, 17:16 := 11 *) 
    SYSTEM.GET(LPC.PINSEL3, s);
    SYSTEM.PUT(LPC.PINSEL3, s + {8..11, 14..17});
    
    (* backlight P1.26 *)
    SYSTEM.GET(LPC.FIO1DIR, s);
    SYSTEM.PUT(LPC.FIO1DIR, s + {26}); 
    SYSTEM.PUT(LPC.FIO1SET, {26}); 
    (* LCD reset P3.25 *)
    SYSTEM.GET(LPC.FIO3DIR, s); 
    SYSTEM.PUT(LPC.FIO3DIR, s + {25});
    SYSTEM.PUT(LPC.FIO3SET, {25}); 
    (* Set to HIGH (assert P1.21 CS_LCD low to enable transmission) *)
    SYSTEM.GET(LPC.FIO1DIR, s);
    SYSTEM.PUT(LPC.FIO1DIR, s + {21}); 
    SYSTEM.PUT(LPC.FIO1SET, {21}); 
    
    (* Enable the SSP *)    
    SYSTEM.PUT(LPC.SSP0CR1, 02H);

    (* Phase = 0, Polarity = 0, SPI mode, 9 bits, SCR = 7 *)    
    SYSTEM.PUT(LPC.SSP0CR0, 00708H); 
    SYSTEM.PUT(LPC.SSP0CPSR, 2); 
  END Init;

Hey thanks Chris, that did the trick!