
//S65 display (L2F50) - http://www.watterott.net


//#define LCD_MIRROR         //define to mirror the display
#define LCD_WIDTH            (176)
#define LCD_HEIGHT           (132)
#define RGB(r,g,b)           (((r&0xF8)<<8)|((g&0xFC)<<3)|((b&0xF8)>>3)) //5 red | 6 green | 5 blue

#define LCD_RST_DISABLE()    RST high
#define LCD_RST_ENABLE()     RST low
#define LCD_CS_DISABLE()     CS high
#define LCD_CS_ENABLE()      CS low
#define LCD_RS_DISABLE()     RS high
#define LCD_RS_ENABLE()      RS low


void lcd_clear(unsigned int color)
{
  unsigned int i;

  lcd_area(0, 0, (LCD_WIDTH-1), (LCD_HEIGHT-1));

  lcd_drawstart();
  for(i=(LCD_WIDTH*LCD_HEIGHT/8); i!=0; i--)
  {
    lcd_draw(color); //1
    lcd_draw(color); //2
    lcd_draw(color); //3
    lcd_draw(color); //4
    lcd_draw(color); //5
    lcd_draw(color); //6
    lcd_draw(color); //7
    lcd_draw(color); //8
  }
  lcd_drawstop();

  return;
}


void lcd_draw(unsigned int color)
{
  spi_write(color>>8);
  spi_write(color);

  return;
}


void lcd_drawstop(void)
{
  spi_wait();
  LCD_CS_DISABLE();

  return;
}


void lcd_drawstart(void)
{
  lcd_cmd(0x5C);
  LCD_RS_DISABLE(); //data
  LCD_CS_ENABLE();

  return;
}


void lcd_area(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1)
{
#ifdef LCD_MIRROR
  lcd_cmd(0x15);                    //column address set 
  lcd_data(0x08+(LCD_HEIGHT-1)-y1); //start column
  lcd_data(0x01);                   //start column
  lcd_data(0x08+(LCD_HEIGHT-1)-y0); //end column
  lcd_data(0x01);                   //end column
  lcd_cmd(0x75); //page address set 
  lcd_data(x0);  //start page
  lcd_data(x1);  //end page
#else
  lcd_cmd(0x15);     //column address set 
  lcd_data(0x08+y0); //start column
  lcd_data(0x01);    //start column
  lcd_data(0x08+y1); //end column
  lcd_data(0x01);    //end column
  lcd_cmd(0x75); //page address set 
  lcd_data(x0);  //start page
  lcd_data(x1);  //end page
#endif

  return;
}


void lcd_cursor(unsigned int x, unsigned int y)
{
#ifdef LCD_MIRROR
  lcd_cmd(0x15);                   //column address set 
  lcd_data(0x08+(LCD_HEIGHT-1)-y); //start column
  lcd_data(0x01);                  //start column
  lcd_data(0x08+(LCD_HEIGHT-1)-y); //end column
  lcd_data(0x01);                  //end column
  lcd_cmd(0x75); //page address set 
  lcd_data(x);   //start page
  lcd_data(x);   //end page
#else
  lcd_cmd(0x15);    //column address set 
  lcd_data(0x08+y); //start column
  lcd_data(0x01);   //start column
  lcd_data(0x08+y); //end column
  lcd_data(0x01);   //end column
  lcd_cmd(0x75); //page address set 
  lcd_data(x);   //start page
  lcd_data(x);   //end page
#endif

  return;
}


void lcd_cmd(unsigned int cmd)
{
  LCD_RS_ENABLE(); //cmd
  LCD_CS_ENABLE();
  spi_write(cmd);
  spi_write(0x00);
  spi_wait();
  LCD_CS_DISABLE();

  return;
}


void lcd_data(unsigned int data)
{
  LCD_RS_DISABLE(); //data
  LCD_CS_ENABLE();
  spi_write(data);
  spi_write(0x00);
  spi_wait();
  LCD_CS_DISABLE();

  return;
}


void lcd_reset(void)
{
  //reset
  LCD_CS_DISABLE();
  LCD_RS_DISABLE();
  LCD_RST_ENABLE();
  delay_ms(50);
  LCD_RST_DISABLE();
  delay_ms(50);

  lcd_cmd(0xAE); //display off

  lcd_cmd(0xBC);  //data control
#ifdef LCD_MIRROR
  lcd_data(0x2A); //565 mode, 0x2A=normal, 0x2B=180
#else
  lcd_data(0x2B); //565 mode, 0x2A=normal, 0x2B=180
#endif

  lcd_cmd(0xCA);  //display control 
  lcd_data(0x4C); //P1
  lcd_data(0x01); //P2
  lcd_data(0x53); //P3
  lcd_data(0x00); //P4
  lcd_data(0x02); //P5
  lcd_data(0xB4); //P6
  lcd_data(0xB0); //P7
  lcd_data(0x02); //P8
  lcd_data(0x00); //P9

  lcd_cmd(0x94); //sleep out

  delay_ms(5);

  lcd_cmd(0xAF); //display on

  delay_ms(5);

  lcd_setarea(0, 0, (LCD_WIDTH-1), (LCD_HEIGHT-1));

  return;
}

