lpc2138 SPI and 3310 LCD

Hi, i’m trying to connect a Nokia 3310 LCD to my board using the onboard SPI module. Of course it doesn’t work :slight_smile: so i’ll need someone to give another look to my configuration ( i checked the wiring at least 10 times). I’m assuming it’s a configuration problem because i have some code that blinks a led on the board and the board blinks only if i comment out the SPI communication part, otherwise the PC gets there but nothing happens.

code to set up SPI and PLL:

#define SPI0_SCK0_P4	0x100 	//0x01 << 8
#define SPI0_MISO_P5	0x400	//0x01 << 10
#define SPI0_MOSI_P6	0x1000	//0x01 << 12
#define SPI0_SSEL_P7	0x4000	//0x01 << 14

//MASTER mode and EDGE2
#define SPI0_MASTER		0x28	//0x01 << 5 | 0x01 << 3

void SetSPI(void)
{
	//set pin modes to SPI
	PINSEL0 |= SPI0_SCK0_P4 | SPI0_MISO_P5 | SPI0_MOSI_P6 | SPI0_SSEL_P7;
	//set SPI to master mode
	S0SPCR = SPI0_MASTER;
	//set SPI clock divider
	S0SPCCR = 134;
}

void Initialize(void)  {


	// Setting Multiplier and Divider values
  	PLLCFG=0x23;
  	feed();

	// Enabling the PLL */
	PLLCON=0x1;
	feed();

	// Wait for the PLL to lock to set frequency
	while(!(PLLSTAT & PLOCK)) ;

	// Connect the PLL as the clock source
	PLLCON=0x3;
	feed();

	// Enabling MAM and setting number of clocks used for Flash memory fetch (4 cclks in this case)
	MAMCR=0x2;
	MAMTIM=0x4;

	// Setting peripheral Clock (pclk) to System Clock (cclk)
	VPBDIV=0x1;

}

The board has an external 14.7456 mhz oscillator so the clock is set to 60Mhz and peripheral clock is set to 60Mhz also. I need ~4.5 mhz for SPI so i’m setting the divider to 134.

i have an init function and a send function for the lcd:

#define PIN_RESET		0x01
#define PIN_CMD			0x02
#define PIN_LCD_SELECT 	0x03

#define SPI0_SPIF		0x80	//0x01 << 7
void lcd_init(void)
{
	int j;
	//set pins as output
	IODIR0 = PIN_RESET | PIN_CMD | PIN_LCD_SELECT;
	// Pull-up on reset pin
	IOSET0 = PIN_RESET;

	for (j = 0; j < 500000; j++){};

	// Toggle display reset pin
	IOCLR0 = PIN_RESET;
	for (j = 0; j < 500000; j++){};
	IOSET0 = PIN_RESET;

	lcd_send(0x21, LCD_CMD);  // LCD Extended Commands
	lcd_send(0xC8, LCD_CMD);  // Set LCD Vop(Contrast)
	lcd_send(0x06, LCD_CMD);  // Set Temp coefficent
	lcd_send(0x13, LCD_CMD);  // LCD bias mode 1:48
	lcd_send(0x20, LCD_CMD);  // Standard Commands, Horizontal addressing
	lcd_send(0x0C, LCD_CMD);  // LCD in normal mode

	// Clear lcd
	//lcd_clear();
}

/* Sends data to display controller */
void lcd_send(unsigned char data, LcdCmdData cd)
{
	// Either command or data
	if(cd == LCD_DATA)
	{
		IOSET0 = PIN_CMD;
	}
	else
	{
		IOCLR0 = PIN_CMD;
	}

	S0SPDR = data;
	//wait for the transfer to finish
	while (!(S0SPSR & SPI0_SPIF))
	{
	}
}

main function:

int	main (void) {

	int		j;										// loop counter (stack variable)


	// Initialize the system
	Initialize();

	SetSPI();


	IODIR0 |= 0x80003000;	// P0.12 & P0.13 output
	IOSET0 =  0x00000000;

	lcd_init();

	// endless loop to toggle the two leds
	while (1) {

		for (j = 0; j < 500000; j++ );		// wait 500 msec
		IOSET0 = 0x80003000;
		IOCLR0 = 0x00000000;
		for (j = 0; j < 500000; j++ );		// wait 500 msec
		IOSET0 = 0x00000000;
		IOCLR0 = 0x80003000;

	}
}

If i comment out the lcd_init() call all is fine and the led blinks. If lcd_init() is called nothing happens (display doesn’t reset, led doesn’t blink). I’m sure the program is not hanging in this while: “while (!(S0SPSR & SPI0_SPIF))” so this means that the SPI is not reporting any problem.

Also does anyone know if this type of lcd should give any visual feedback when it’s reset? (maybe my lcd is broken)

I’m using an olimex LPC-H2138 board with an olimex ARM-USB-TINY.

Thanks for reading this far :smiley:

Do you have SSEL pulled high? This is not a SSEL output, but rather an input that causes transfers to abort if low. I’m pretty sure this will be required on a LPC2139, though I have not checked the user manual.