Reply by jasuk1970 February 13, 20082008-02-13
--- In l..., "michael brown" wrote:
>
> jasuk1970 wrote:
>
> > I've dropped all my code and started with yours and referencing the
> > James Lynch tutorial and have now got the screen working with the
> > Crossworks compiler. (To a degree :) )
> >
> > I need to look into a few things to iron out speed issues etc. And how
> > to do the reset (FIO commands seem to compile but not work, though IO
> > ones do, but there is no IO3 which means the reset cannot be done for
> > the moment (So I run the clear screen routine to make sure everything
> > is OK.
>
> I was disappointed with how slow I have to clock the SPI interface
to make
> it work (4MHz IIRC). It should be able to run much faster according
to the
> datasheets, but for some reason it won't work at higher speeds on my
board.
> It has been a couple of months since I played with this stuff, so
I'm kinda
> fuzzy on the details. I do believe that I have a bunch of unnecessary
> delays in places where I tried to get the SPI clocking faster.
>
> Do you have one of these:
> SCS |= (1UL<<0); // set GPIOM in SCS for fast IO on PORT0 and PORT1
>
> PORT2 and PORT3 are always accessed via the "fast" i/o methods;
that's why
> there is no IO3.
>

Hi,
I had actually not yet found the UM10211 document, Paul from Rowley
mentioned some stuff in it which has now caused me to finally start
understanding how everything works :).

I've use:

SCS |= SCS_GPIO0M;

to enable the FIO on port 0 and 1.

I've removed the delays that you had in the program and to run the CLS
takes around 1/4 of a second, its just visible to the naked eye.

Now that I've found this document I may go through the port
configuration and find out why changing the clock rate doesn't seem to
make any difference. I'll let you know how I get on.

Thanks again for the help.

Jas

An Engineer's Guide to the LPC2100 Series

Reply by jasuk1970 February 12, 20082008-02-12
A quick follow-up.

Taking out any sleeps and changing SSP0CPSR = 18 to = 4 does make a
difference in the speed.

But a clear screen to a colour does still seem to update visibly.

Jas

--- In l..., "jasuk1970" wrote:
>
> --- In l..., "michael brown" wrote:
> >
> > jasuk1970 wrote:
> >
> > > I've dropped all my code and started with yours and referencing the
> > > James Lynch tutorial and have now got the screen working with the
> > > Crossworks compiler. (To a degree :) )
> > >
> > > I need to look into a few things to iron out speed issues etc.
And how
> > > to do the reset (FIO commands seem to compile but not work,
though IO
> > > ones do, but there is no IO3 which means the reset cannot be
done for
> > > the moment (So I run the clear screen routine to make sure
everything
> > > is OK.
> >
> > I was disappointed with how slow I have to clock the SPI interface
> to make
> > it work (4MHz IIRC). It should be able to run much faster according
> to the
> > datasheets, but for some reason it won't work at higher speeds on my
> board.
> > It has been a couple of months since I played with this stuff, so
> I'm kinda
> > fuzzy on the details. I do believe that I have a bunch of
unnecessary
> > delays in places where I tried to get the SPI clocking faster.
> >
> > Do you have one of these:
> > SCS |= (1UL<<0); // set GPIOM in SCS for fast IO on PORT0 and PORT1
> >
> > PORT2 and PORT3 are always accessed via the "fast" i/o methods;
> that's why
> > there is no IO3.
> > Hi,
> I had actually not yet found the UM10211 document, Paul from Rowley
> mentioned some stuff in it which has now caused me to finally start
> understanding how everything works :).
>
> I've use:
>
> SCS |= SCS_GPIO0M;
>
> to enable the FIO on port 0 and 1.
>
> I've removed the delays that you had in the program and to run the CLS
> takes around 1/4 of a second, its just visible to the naked eye.
>
> Now that I've found this document I may go through the port
> configuration and find out why changing the clock rate doesn't seem to
> make any difference. I'll let you know how I get on.
>
> Thanks again for the help.
>
> Jas
>
Reply by michael brown February 12, 20082008-02-12
jasuk1970 wrote:

> I've dropped all my code and started with yours and referencing the
> James Lynch tutorial and have now got the screen working with the
> Crossworks compiler. (To a degree :) )
>
> I need to look into a few things to iron out speed issues etc. And how
> to do the reset (FIO commands seem to compile but not work, though IO
> ones do, but there is no IO3 which means the reset cannot be done for
> the moment (So I run the clear screen routine to make sure everything
> is OK.

I was disappointed with how slow I have to clock the SPI interface to make
it work (4MHz IIRC). It should be able to run much faster according to the
datasheets, but for some reason it won't work at higher speeds on my board.
It has been a couple of months since I played with this stuff, so I'm kinda
fuzzy on the details. I do believe that I have a bunch of unnecessary
delays in places where I tried to get the SPI clocking faster.

Do you have one of these:
SCS |= (1UL<<0); // set GPIOM in SCS for fast IO on PORT0 and PORT1

PORT2 and PORT3 are always accessed via the "fast" i/o methods; that's why
there is no IO3.
Reply by jasuk1970 February 12, 20082008-02-12
> I use some slightly different code.
>
> void WriteSpiCommand(volatile unsigned int command) {
>
> // wait for the previous transfer to complete
> while((SSP0SR & (1<<0)) == 0);
> wait_uS(10);
>
> // clear bit 8 - indicates a "command"
> command = (command & ~0x0100);
>
> // send the command
> SSP0DR = command;
> }
> void WriteSpiData(volatile unsigned int data) {
>
> // wait for the transfer to complete
> while((SSP0SR & (1<<0)) == 0);
> wait_uS(10);
>
> // set bit 8, indicates "data"
> data = (data | 0x0100);
>
> // send the data
> SSP0DR = data;
> }
>

Thanks Michael,
I've dropped all my code and started with yours and referencing the
James Lynch tutorial and have now got the screen working with the
Crossworks compiler. (To a degree :) )

I need to look into a few things to iron out speed issues etc. And how
to do the reset (FIO commands seem to compile but not work, though IO
ones do, but there is no IO3 which means the reset cannot be done for
the moment (So I run the clear screen routine to make sure everything
is OK.

Cheers,

Jas
Reply by michael brown February 11, 20082008-02-11
jasuk1970 wrote:
> Michael,
> After having played with it for a bit, I've still not managed to get
> the screen to display anything. The WriteSpiCommand I've done is based
> on the documentation on SPI and also from the James Lynch tutorial:
>
> void WriteSpiCommand(volatile unsigned int command)
> {
> command = (command & 0x0100) // Clear bit 8 to indicate a command
> S0SPDR = command; // Send the command
> while(S0SPDR & S0SPSR_SPIF) == 0); // wait for transfer to complete
> (Status bit goes high)
> int i = S0SPSR; // read the buffer to reset
> }
>
> What happens for me is the while loop, loops indefinitely.
>
> I'm assuming that the SPI initialisation code isn't working.

I use some slightly different code.

void WriteSpiCommand(volatile unsigned int command) {

// wait for the previous transfer to complete
while((SSP0SR & (1<<0)) == 0);
wait_uS(10);

// clear bit 8 - indicates a "command"
command = (command & ~0x0100);

// send the command
SSP0DR = command;
}
void WriteSpiData(volatile unsigned int data) {

// wait for the transfer to complete
while((SSP0SR & (1<<0)) == 0);
wait_uS(10);

// set bit 8, indicates "data"
data = (data | 0x0100);

// send the data
SSP0DR = data;
}
Reply by Ivan Vernot February 11, 20082008-02-11
Hello,
I am pretty sure that Olimex supplies code for the LPC-2378-STK board.
There are a few BUTs though
1. IIRC its for the Keil complier (might be IAR)
2. It is not open source (there is a copyright by Keil/IAR)
3. You need to email the people you purchased the board from to get the
source. (I tried to email Olimex directly but they insisted that I go back
to the people I purchased it from?!)

HTH
Ivan Vernot

> -----Original Message-----
> From: l... [mailto:l...] On Behalf
> Of jasuk1970
> Sent: Sunday, 10 February 2008 6:41 AM
> To: l...
> Subject: [lpc2000] Re: LPC-2378-STK board LCD Screen using Crossworks.
>
> After a little research, I need to access the screen via an SPI
> interface. I've had a look at the schematic and worked out which pins
> are connected to screen:
>
> SPI
> ---
> SCK = P1.20/PWM1.2/SCK0 (49)
> DIO = P1.23/PWM1.4/MISO0 (53)
> CS = P1.21/PWM1.3/SSEL0 (50)
>
> Back Light
> ----------
> LEDGND = P1.26/PWM1.6/CAP0.0/LCD_BL (57)
>
> Trying to implement this SPI code is where I'm falling down ;-).
>
> Is anyone able to help?
>
> Thanks,
>
> Jas
>
> --- In l..., "jasuk1970" wrote:
> >
> > Hi,
> >
> > Hopefully by the weekend I should be up and running with
> Crossworks
> > and my Olimex LPC-2378-STK Board. One of the things I would like to
> be
> > able to do is start using the Nokia Screen on the device. Does
> anyone
> > have a basic examples of using the screen with the Crossworks
> compiler?
> >
> > I am new to Arm programming but If I could basically
> Initialise/power
> > up the screen and send data to it, that should be enough to get me
> > going. There are a lot of info in the James Lynch tutorial about how
> > to get the most out of it, but this was for a different board and
> > different compiler. (Mine used the Epson driver if this is of any
> help)
> >
> > Any help will be greatfully appreciated.
> >
> > Cheers,
> >
> > Jas
> >
Reply by jasuk1970 February 11, 20082008-02-11
Whoops, that was a typo, it was supposed to be:

command = (command & ~0x0100)

I copied manually from a machine not connected to the net, my typing
wasn't up to scratch.

Jas

--- In l..., "rtstofer" wrote:
>
> --- In l..., "jasuk1970" wrote:
> >
> > Michael,
> > After having played with it for a bit, I've still not managed to get
> > the screen to display anything. The WriteSpiCommand I've done is based
> > on the documentation on SPI and also from the James Lynch tutorial:
> >
> > void WriteSpiCommand(volatile unsigned int command)
> > {
> > command = (command & 0x0100) // Clear bit 8 to indicate a command
> > S0SPDR = command; // Send the command
> > while(S0SPDR & S0SPSR_SPIF) == 0); // wait for transfer to complete
> > (Status bit goes high)
> > int i = S0SPSR; // read the buffer to reset
> > }
>
> It looks to me like the command = ... statement clears everything
> EXCEPT bit 8. The only possible values for command, after the
> assignment are 0x0100 or 0x0000. I don't know if this matters.
>
> I find it much easier to get SPI and I2C working if I use a logic
> analyzer. I can't afford a high priced unit so I use this one:
> http://www.sump.org/projects/analyzer/ $100 for a pretty good unit.
> Some assembly required...
>
> The other way to do it is to sync the scope on SSEL' and continually
> send a pattern. In code, set SSEL' low, send a byte (or whatever),
> wait for completion and then set SSEL' high. Put it in a loop and
> perhaps add a little delay at the end of the loop. With luck, you
> should be able to see the pattern on a scope. In fact, with most
> scopes, you can use SSEL' on the EXT SYNC, data on CH 1 and clock on CH
> 2.
>
> Richard
>
Reply by rtstofer February 11, 20082008-02-11
--- In l..., "jasuk1970" wrote:
>
> Michael,
> After having played with it for a bit, I've still not managed to get
> the screen to display anything. The WriteSpiCommand I've done is based
> on the documentation on SPI and also from the James Lynch tutorial:
>
> void WriteSpiCommand(volatile unsigned int command)
> {
> command = (command & 0x0100) // Clear bit 8 to indicate a command
> S0SPDR = command; // Send the command
> while(S0SPDR & S0SPSR_SPIF) == 0); // wait for transfer to complete
> (Status bit goes high)
> int i = S0SPSR; // read the buffer to reset
> }

It looks to me like the command = ... statement clears everything
EXCEPT bit 8. The only possible values for command, after the
assignment are 0x0100 or 0x0000. I don't know if this matters.

I find it much easier to get SPI and I2C working if I use a logic
analyzer. I can't afford a high priced unit so I use this one:
http://www.sump.org/projects/analyzer/ $100 for a pretty good unit.
Some assembly required...

The other way to do it is to sync the scope on SSEL' and continually
send a pattern. In code, set SSEL' low, send a byte (or whatever),
wait for completion and then set SSEL' high. Put it in a loop and
perhaps add a little delay at the end of the loop. With luck, you
should be able to see the pattern on a scope. In fact, with most
scopes, you can use SSEL' on the EXT SYNC, data on CH 1 and clock on CH
2.

Richard
Reply by jasuk1970 February 11, 20082008-02-11
Michael,
After having played with it for a bit, I've still not managed to get
the screen to display anything. The WriteSpiCommand I've done is based
on the documentation on SPI and also from the James Lynch tutorial:

void WriteSpiCommand(volatile unsigned int command)
{
command = (command & 0x0100) // Clear bit 8 to indicate a command
S0SPDR = command; // Send the command
while(S0SPDR & S0SPSR_SPIF) == 0); // wait for transfer to complete
(Status bit goes high)
int i = S0SPSR; // read the buffer to reset
}

What happens for me is the while loop, loops indefinitely.

I'm assuming that the SPI initialisation code isn't working.

Jas
--- In l..., "michael brown" wrote:
>
> I can email you the program I was playing with. I believe that I
have the
> same dev board as you, but I use GCC. My program incorporates some
code
> from a nice tutorial from James P Lynch that I found on the web.
Here's
> some snippets of my version:
>
> void InitSpi(void) {
>
> PCONP |= (1<<21); // power on SSP0 module
>
> //P1.26 is back light
> FIO1DIR |= (1<<26); // make it output pin
> FIO1SET = (1<<26); // turn on the backlight
> FIO1CLR = (1<<26); // turn off the backlight
>
> // SSP0CR0 = 0x00C8; // Phase = 1, Polarity = 1, SPI mode, 9 bits
> SSP0CR0 = 0x0048; // Phase = 0, Polarity = 1, SPI mode, 9 bits
> // SSP0CR0 = 0x0088; // Phase = 1, Polarity = 0, SPI mode, 9 bits
> // SSP0CR0 = 0x0008; // Phase = 0, Polarity = 0, SPI mode, 9 bits
>
> SSP0CPSR = 18; // 4 MHz clock rate (72/18)
>
> PINSEL3 |= 0x0003CF00; // setup SCK0, SSEL0, MISO0, MOSI0
>
> SSP0CR1 = 0x2; // Enable the SSP
>
> }
>
> void InitLcd(void) {
>
> // Hardware reset
> // LCD_RESET_LOW;
> // Delay(10000);
> // LCD_RESET_HIGH;
> // Delay(10000);
> // reset the LCD
> FIO3DIR |= (1<<25); // make output pin
> FIO3CLR = (1<<25); // pull low to reset LCD
> wait_mS(100);
> FIO3SET = (1<<25); // end reset
> wait_mS(100);
> // Display control
> WriteSpiCommand(DISCTL);
> WriteSpiData(0x00); // P1: 0x00 = 2 divisions, switching period=8
(default)
> WriteSpiData(0x20); // P2: 0x20 = nlines/4 - 1 = 132/4 - 1 = 32)
> WriteSpiData(0x00); // P3: 0x00 = no inversely highlighted lines
>
> // COM scan
> WriteSpiCommand(COMSCN);
> WriteSpiData(1); // P1: 0x01 = Scan 1->80, 160<-81
>
> // Internal oscilator ON
> WriteSpiCommand(OSCON);
>
> wait_mS(100);
>
> // Sleep out
> WriteSpiCommand(SLPOUT);
>
> // Voltage control (contrast setting)
> WriteSpiCommand(VOLCTR);
> WriteSpiData(32); // P1 = 32 volume value (experiment with this
value to
> get the best contrast)
> WriteSpiData(3); // P2 = 3 resistance ratio (only value that works)
>
> // Power control
> WriteSpiCommand(PWRCTR);
> WriteSpiData(0x0f); // reference voltage regulator on, circuit voltage
> follower on, BOOST ON
>
> // allow power supply to stabilize
> wait_mS(150);
>
> // Inverse display
> WriteSpiCommand(DISINV);
>
> // Data control
> WriteSpiCommand(DATCTL);
> WriteSpiData(0x01); // P1: 0x01 = page address inverted, column
address
> normal, address scan in column direction
> WriteSpiData(0x00); // P2: 0x00 = RGB sequence (default value)
> WriteSpiData(0x02); // P3: 0x02 = Grayscale -> 16 (selects 12-bit
color,
> type A)
>
> // turn on the display
> WriteSpiCommand(DISON);
> }
> jasuk1970 wrote:
> > So far I've managed to get the back light on and off using:
> >
> > #define LCD_BL (1 << 26)
> > IO1DIR |= LCD_BL;
> > IO1SET = LCD_BL;
> >
> > I've found a snippet of code for setting up the SPI port on a LPC2468,
> > which was written for Crossworks compiler:
> >
> > //Init SSP0 for master mode, 6Mbits/s
> > //set I/O pin config for LPC2468
> > //available pins:
> > //SCK0 P0.15 P1.20 P2.22
> > //SSEL0 p0.16 P1.21 P2.23
> > //MISO0 p0.17 P1.23 P2.26
> > //MOSI0 p0.18 P1.24 P2.27
> >
> > PINSEL0 |= (2 << 30); //SCK0 on P0.15
> > PINSEL1 |= (2 << 0); //SSEL0 on P0.16
> > PINSEL1 |= (2 << 2); //MISO0 on P0.17
> > PINSEL1 |= (2 << 4); //MOSI0 on P0.18
> >
> > // enable clock to SSP0 just to make sure. By default, it's enabled
> > already
> > PCONP |= PCONP_PCSSP0;
> > //set PCLK divider for SSP0 to 1
> > PCLKSEL1 = (PCLKSEL1 & ~PCLKSEL1_PCLK_SSP0_MASK) | (1 <<
> > PCLKSEL1_PCLK_SSP0_BIT);
> >
> > //NOTE: in slave mode CPSR must be >
> > SSP0CPSR = 12; //SCK = CCLK / PCLKdiv / CPSR / SCR = 72/1/12/1 = 6 MHz
> > SSP0CR0 = 0x000F; //16-bit, SPI, SPO=0, SPH=0, SCR=0
> > SSP0CR1 = SSP0CR1_SSE; //Master mode, SSP enabled
> >
> > I am unsure about the PINSEL command above in setting up the port on
> > the 2378-STK. I know that SCK0 is on P1.20, SSEL0 is on P1.21, MISO0
> > is on P1.23, MOSI0 is connected to MISO0 by a 10k resistor according
> > to the Olimex schematic.
> >
> > Anyone able to help with this?
> >
> > cheers,
> >
> > Jas
> >
> > --- In l..., "jasuk1970" wrote:
> >>
> >> After a little research, I need to access the screen via an SPI
> >> interface. I've had a look at the schematic and worked out which pins
> >> are connected to screen:
> >>
> >> SPI
> >> ---
> >> SCK = P1.20/PWM1.2/SCK0 (49)
> >> DIO = P1.23/PWM1.4/MISO0 (53)
> >> CS = P1.21/PWM1.3/SSEL0 (50)
> >>
> >> Back Light
> >> ----------
> >> LEDGND = P1.26/PWM1.6/CAP0.0/LCD_BL (57)
> >>
> >> Trying to implement this SPI code is where I'm falling down ;-).
> >>
> >> Is anyone able to help?
> >>
> >> Thanks,
> >>
> >> Jas
> >>
> >> --- In l..., "jasuk1970" mail@ wrote:
> >>>
> >>> Hi,
> >>>
> >>> Hopefully by the weekend I should be up and running with
> >>> Crossworks and my Olimex LPC-2378-STK Board. One of the things I
> >>> would like to be able to do is start using the Nokia Screen on the
> >>> device. Does anyone have a basic examples of using the screen with
> >>> the Crossworks compiler?
> >>>
> >>> I am new to Arm programming but If I could basically
> >>> Initialise/power up the screen and send data to it, that should be
> >>> enough to get me going. There are a lot of info in the James Lynch
> >>> tutorial about how to get the most out of it, but this was for a
> >>> different board and different compiler. (Mine used the Epson driver
> >>> if this is of any help)
> >>>
> >>> Any help will be greatfully appreciated.
> >>>
> >>> Cheers,
> >>>
> >>> Jas
> >>>
> >>
> >
> >
> >
> >
> >
> >
> >
> >
> >
Reply by jasuk1970 February 11, 20082008-02-11
Thanks for that, it's helped a lot.

The only problem I have so far is in the reset port for the board is
P3.25 as your example code shows:

http://www.olimex.com/dev/images/LPC2378-STK-sch.gif

But the include file for the LPC2378 with Crossworks only goes up to
IO2. For now I'll do a board reset to get round this.

A quick question, does Crossworks have a sleep_ms type function or do
I need to code this myself (Based on the clock speed)?

cheers,
Jas

Looking at the Olimex schematic, it shows the LCD_RST is 3.26
--- In l..., "michael brown" wrote:
>
> I can email you the program I was playing with. I believe that I
have the
> same dev board as you, but I use GCC. My program incorporates some
code
> from a nice tutorial from James P Lynch that I found on the web.
Here's
> some snippets of my version:
>
> void InitSpi(void) {
>
> PCONP |= (1<<21); // power on SSP0 module
>
> //P1.26 is back light
> FIO1DIR |= (1<<26); // make it output pin
> FIO1SET = (1<<26); // turn on the backlight
> FIO1CLR = (1<<26); // turn off the backlight
>
> // SSP0CR0 = 0x00C8; // Phase = 1, Polarity = 1, SPI mode, 9 bits
> SSP0CR0 = 0x0048; // Phase = 0, Polarity = 1, SPI mode, 9 bits
> // SSP0CR0 = 0x0088; // Phase = 1, Polarity = 0, SPI mode, 9 bits
> // SSP0CR0 = 0x0008; // Phase = 0, Polarity = 0, SPI mode, 9 bits
>
> SSP0CPSR = 18; // 4 MHz clock rate (72/18)
>
> PINSEL3 |= 0x0003CF00; // setup SCK0, SSEL0, MISO0, MOSI0
>
> SSP0CR1 = 0x2; // Enable the SSP
>
> }
>
> void InitLcd(void) {
>
> // Hardware reset
> // LCD_RESET_LOW;
> // Delay(10000);
> // LCD_RESET_HIGH;
> // Delay(10000);
> // reset the LCD
> FIO3DIR |= (1<<25); // make output pin
> FIO3CLR = (1<<25); // pull low to reset LCD
> wait_mS(100);
> FIO3SET = (1<<25); // end reset
> wait_mS(100);
> // Display control
> WriteSpiCommand(DISCTL);
> WriteSpiData(0x00); // P1: 0x00 = 2 divisions, switching period=8
(default)
> WriteSpiData(0x20); // P2: 0x20 = nlines/4 - 1 = 132/4 - 1 = 32)
> WriteSpiData(0x00); // P3: 0x00 = no inversely highlighted lines
>
> // COM scan
> WriteSpiCommand(COMSCN);
> WriteSpiData(1); // P1: 0x01 = Scan 1->80, 160<-81
>
> // Internal oscilator ON
> WriteSpiCommand(OSCON);
>
> wait_mS(100);
>
> // Sleep out
> WriteSpiCommand(SLPOUT);
>
> // Voltage control (contrast setting)
> WriteSpiCommand(VOLCTR);
> WriteSpiData(32); // P1 = 32 volume value (experiment with this
value to
> get the best contrast)
> WriteSpiData(3); // P2 = 3 resistance ratio (only value that works)
>
> // Power control
> WriteSpiCommand(PWRCTR);
> WriteSpiData(0x0f); // reference voltage regulator on, circuit voltage
> follower on, BOOST ON
>
> // allow power supply to stabilize
> wait_mS(150);
>
> // Inverse display
> WriteSpiCommand(DISINV);
>
> // Data control
> WriteSpiCommand(DATCTL);
> WriteSpiData(0x01); // P1: 0x01 = page address inverted, column
address
> normal, address scan in column direction
> WriteSpiData(0x00); // P2: 0x00 = RGB sequence (default value)
> WriteSpiData(0x02); // P3: 0x02 = Grayscale -> 16 (selects 12-bit
color,
> type A)
>
> // turn on the display
> WriteSpiCommand(DISON);
> }