LCDInfo.com

http://www.lcdinfo.com
It is currently Thu Mar 28, 2024 10:46

All times are UTC + 2 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Fri Mar 17, 2006 3:37 
Offline

Joined: Fri Mar 17, 2006 3:13
Posts: 6
Hey all,

I'm trying to parse the SparkFun sample code for the knock-off nokia. I'm using an atmega32 micro, and want to use SPI to talk to the Epson micro. I'm using the board SparkFun is offering.

So there's no real choice but to use the 9-bit serial interface, since the A0 line is not brought out. Anyhow, it looks like the sparkfun sample code (using a philips micro) writes two bytes to the SPI data register (in their case, they are using a 16 bit SSP register (SSPDR) unavailable on the Atmega32) -- the first byte is:

0000 0001 to set up for a command in spi_command()
0000 0000 to set up for data in spi_data()

the second byte is the command, or the data.

So that one bit getting toggled is the first bit of the 9-bit stream, and corresponds to A0. So, the first seven bits of the first byte are basically junk, right?

Their code:

Code:
void spi_command(int dat){
  int temp;
  IOCLR0 |= LCD_CS;
  SSPDR  = dat & ~0x0100;// & ~0x00000100;   // send next SPI channel 0 data
  while ((SSPSR & 0x10)) ;     // wait for transfer completed
  IOSET0 |= LCD_CS;
}



So they basically look like they are hitting chip select, sending two bytes, waiting for xmit to finish and resetting CS.

But that seems weird! The data sheet (p. 13) for the epson says that it reads the first bit at the first clock-edge to set the next byte as command or data. But doesn't writing the first seven bits of the first "dummy" byte get the clock going -- and the epson sees a 0 (the first bit in the dummy byte) at the first clock, every time?

is there something i am missing here? are the sparkfun guys doing some clever timing, such that the clock doesn't start going til the last bit in the first byte gets piped along (seems crazy)? Or will the following C code for the atmega32 work:

Code:

void spi_command(int dat) {

PB4 = 0; //this is the SS (CS) pin on the atmega32 -- just bringing SS low
             // to get the slave (the epson micro) ready

SPDR = 0x01; //dummy byte for command
 while (!(SPSR & (1<<SPIF))); //just wait for the transfer to end
SPDR = dat; //send the actual command
 while (!(SPSR & (1<<SPIF))); //just wait for the transfer to end
PB4 = 1; //all done, bring SS high and exit

}



?

spi_data would be analagous.

any help would be most appreciated. thanks so much!
confused,
jeevan
jeevan [at] media [dot] mit [dott edu


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 17, 2006 14:56 
Offline

Joined: Thu Mar 16, 2006 22:01
Posts: 13
Your in luck, i just finished the code for the same display and processor last night. Unfortunatly i dont have the code here with me at work. When i get home tonight i will reply again with the info you need.

Jimbo


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 18, 2006 1:48 
Offline

Joined: Thu Mar 16, 2006 22:01
Posts: 13
#define LCDCommand 0
#define LCDData 1

Useage:
SendLcd(LCDCommand, [Your Command]);
SendLcd(LCDData, [your data]);

NOTE: i cannot take all credit, jimminy came up with the idea for the function call parameters. i just changed the routine. i used the hardware SPI calls because it was MUCH faster then banging the bits out.

void SendLcd(u_char type, u_char dat)
{

LCD_DATA(type); // set up first bit as command or data
LCD_CS(0); // Enable device CS

LCD_CLK(0); // Pull Clock LOW
LCD_CLK(1); // Pul Clock HIGH

SPCR |=0x50; // Enable Hardware SPI

SPDR = dat; // send data

while(!(SPSR & 0x80)); // wait until send complete

LCD_CS(1); // disable device CS

SPCR &=~0x50;
// Disable Hardware SPI, this releases the SPI pins
// for general IO use. which is used to send the 1'st bit out
}


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 19, 2006 0:52 
Offline

Joined: Sun Feb 26, 2006 14:56
Posts: 6
Location: Australia
For those of you using a micro without hardware support for a 9 bit spi, I knocked up some code for a philips lpc2119 that does 9 bit spi. In the case of an AVR, the calls to spi_delay() should not be necessary - the philips arm devices are mighty quick.

I still haven't got my display operating as I would expect yet, so I'm going to try buying some in from Hong Kong to see if I get better luck!



Code:
void spi_command(int dat)
{
  int temp;
  char bit_count;

  temp = dat & 0x00ff;
  IOCLR0 |= LCD_CS;

   for   (bit_count = 0; bit_count< 9;bit_count++)
      {
      if (temp & 0x0100)
         {
         IOSET0 = LCD_DI;
         }
      else
         {
         IOCLR0 = LCD_DI;
         }
      IOCLR0 = LCD_SCK;      //data valid on falling clock
      spi_delay();
      IOSET0 = LCD_SCK;
      temp<<=1;         //shift next bit
      spi_delay();
      }
  IOSET0 |= LCD_CS;
}

void spi_data(int dat)
{
  int temp;
  char bit_count;

  temp = dat | 0x0100;      //set the data/command bit
     
  IOCLR0 = LCD_CS;

   for   (bit_count = 0; bit_count< 9;bit_count++)
      {
      if (temp & 0x0100)
         {
         IOSET0 = LCD_DI;
         }
      else
         {
         IOCLR0 = LCD_DI;
         }
      IOCLR0 = LCD_SCK;      //data valid on falling clock
      spi_delay();
      IOSET0 = LCD_SCK;
      temp<<=1;         //shift next bit
      spi_delay();
      }
  IOSET0 |= LCD_CS;
}


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 20, 2006 19:19 
Offline

Joined: Fri Mar 17, 2006 3:13
Posts: 6
hi, thanks!

i've got a few questions about this code, though -- due probably to my inexperience with micro programming.

So, are LCD_DATA, LCD_CS and LCD_CLK #defined somewhere? I take it that LCD_CS and LCD_CLK correspond to the SPI pins for SS and SCK, respectively, which are PORTB4 and PORTB7 on the atmega32.

Is LCD_DATA #defined to be MOSI (PORTB5)? (I guess these aren't really #defines, since they seem to be taking arguments...)

I see otherwise how it works -- you put the command bit "ready" on a pin and then manually flip the clock -- then use SPI for the data byte.

Anyways, I am sure this code works, I would just like to understand the LCD_X a bit better.

thanks for all your help
jeevan



seulater wrote:

#define LCDCommand 0
#define LCDData 1

Useage:
SendLcd(LCDCommand, [Your Command]);
SendLcd(LCDData, [your data]);

NOTE: i cannot take all credit, jimminy came up with the idea for the function call parameters. i just changed the routine. i used the hardware SPI calls because it was MUCH faster then banging the bits out.

void SendtLcd(u_char type, u_char dat)
{

LCD_DATA(type); // set up first bit as command or data
LCD_CS(0); // Enable device CS

LCD_CLK(0); // Pull Clock LOW
LCD_CLK(1); // Pul Clock HIGH

SPCR |=0x50; // Enable Hardware SPI

SPDR = dat; // send data

while(!(SPSR & 0x80)); // wait until send complete

LCD_CS(1); // disable device CS

SPCR &=~0x50;
// Disable Hardware SPI, this releases the SPI pins
// for general IO use. which is used to send the 1'st bit out
}


Top
 Profile  
 
 Post subject: i figured it out, thanks
PostPosted: Wed Mar 22, 2006 12:32 
Offline

Joined: Fri Mar 17, 2006 3:13
Posts: 6
hey all,

seulater's/jimminy's code will get you up and running in a flash -- and if any other newbies like me are confused by LCD_CLK, etc., here's what it means:

Code:
/* LCD_CLK
 * -------
 * Function that allows you to pull the SPI SCK clock pin (SCK)
 * high or low.
 */

void LCD_CLK(uint8_t clock) {

   if (clock == 0 ) { //pull clock low
      SPI_PORT &= ~_BV(SPI_SCK);
   } else if (clock == 1) { //pull clock high
      SPI_PORT |= _BV(SPI_SCK);
   }
}


SPI_PORT is just a #define for whatever port your chip uses for SPI (PORTB on the atmega32). SPI_SCK is just the pin that your chip uses for its SPI clock (PORTB7 on the atmega32). So, in my case, I had

Code:

#define SPI_PORT     PORTB
#define SPI_SCK       PORTB7
   


(_BV(blah) is just a macro for (1<<blah); it allows you to target a given bit in a byte. It's included in avrlib-c. for more info, see:

http://www.nongnu.org/avr-libc/user-man ... faq_use_bv)

All the other LCD_X functions are analagous. This is a pretty handy little template for pulling arbitrary pins high and low -- thanks for the tips, all!
jeevan


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 31, 2006 4:53 
Offline

Joined: Thu Mar 16, 2006 22:01
Posts: 13
I would just like to understand the LCD_X a bit better.

Sorry about that...

here is the defines for it.

#define LCD_CS(x) PORTC.2=x;
#define LCD_CLK(x) PORTB.7=x;
#define LCD_DATA(x) PORTB.5=x;
#define LCD_RESET(x) PORTC.0=x;


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC + 2 hours


Who is online

Users browsing this forum: No registered users and 28 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group