/******===================LCD Driveri ===== 

File    :lcd.c
Pääohjelma timeri.c
Project : e:\pic\2008\keno\
File    :  PIC18F2331    
Copyright :    Pekka Ritamäki PROBYTE Oy 9.9.2016
aseta logo 2*8
   CCS/PCW 3.073
            LCD neljän bitin LCD kytkentä
            LCD1 = 0V
            LCD2 = 5V
            LCD3 = kontrasti noin 0.6V ( trimmeri 10k 0 ja 5V välille, tai aluksi nasta3 maihin  )
            PORTB0 LCD data 0  LCD nasta 11
            PORTB1 LCD data 1   LCD nasta 12
            PORTB2 LCD data 2   LCD nasta 13
            PORTB3 LCD data 3  LCD nasta 14
            PORTB.4 LCD RS
            ei käytössä PORTB.7 LCD RW
            PORTB.6 lcd ENABLE



*******************************/



//#use fast_io(C)

#define CMD 0
#define DAT 1
#define  LCD_CURSOR_ON 0xF
#define  LCD_CURSOR_OFF 0xD
#define  LCD_CURSOR_RIGHT 0x14
#define  CursorBack  16
 //' siirrä LCD kursoria taaksepäin
#define  CursorFwd   20

 


void lcd_send_byte( unsigned int8 address, unsigned int8 n ) ;
 
 
 
 

int rowcount;  /* pidä lukua koska mennaään seuraavalle riville */
  /* lcd näytön poweripivitys**/
 

char row ;
 
#define LCD_ROW_EE 0
  /* 15 tai 19  merkkiä rivillä */
#define SPEED_EE 1
 /* eeprom mopeus paikassa 1 1= 9600 */

#define all_out 0
#define all_in 0xff
//#define boolean Short
//#define unsigned int8 Int
#define  LCD4MODE 3
#define  LCD_16_1 1           // 1*16 LCD mode
#define  LCD_CLEAR 1
#define  LCD_HOME 2
#define  LCD_ENTRY_MODE 6
#define LCD_BACK 0x10
#define ROW1 0x80 /* gotoxy (1, 1)*/
#define ROW2 0xC0      /*   2*16 40 +80  */
//#define ROW2 0xB9  /* gotoxy (1, 2)*/
#define ROW3 0x94  /* gotoxy (1, 3) */
#define ROW4 0xd4  /* gotoxy (1, 4) */
#define CURSOROFF 0x0C   /* Display on, cursor off 2, blink off */
#define CURSORON 0x0D   /* Display on, cursor ON , blink off */

#define VOLTAGE 0
#define CURRENT 1


 
//int1 buzzer_bit=0;
#bit RS =PORTB.5
//#bit RW= PORT.6  ei käytössä
#bit ENABLE =PORTB.4


//   LCD:n bitit D0-D3 ei käytetä ( 4-bit mode )
//char MAXcount ; /* monta merkkiä rivillä -1 2*16 = 15 ja 2*20 = 19 */



struct lcd_pin_map {                 // Tämä  structuuri on B-portille
           int8  data : 4 ;         // 4 bittiä alusta B3..B6
           unsigned int1 spare ;   //enable
           unsigned int1 spare2;  //
           unsigned int1 spare3;  // ENABLE on B2
           unsigned int1 spere4; //
        } LCD;
//#unsigned int8 PORTB = 0x0F81
#BYTE LCD =  0x0F81           // LCD on mapattu ositteeseen 6 eli B-porttiin
                        //  Struktuuri oisoittaa portti C:n ( osoitteessa 7)
#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 rivi„
#define lcd_line_two 0x40    // LCD RAM:in osoite toiselle  riville vain eräillä LCD:llä
//#define  LCD4MODE 3
unsigned int8  const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                             // Nämä unsigned int8t pitää lähettää käynnistyksessä LCD
                             // Seuraavia käytetän IO-portin suunnissa
                             // asettamaan I/O portin suuntarekisteriä

//struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0};
// Kirjoita tilassa ( LCD), kaikki io-nastat asetetaan Outputeiksi
//struct lcd_pin_map const LCD_READ = {15,0,0,0,0};
 // Read modessa datat ovat input-modessa, huom alku osa input


void lcd_send_nibble( unsigned int8 n ) {
      LCD.data = n;
     // delay_us(10);
     // printf("\r%X ENAB=0 data0%d ",PORTB&0x30, n); // while(MODE); delay_ms(100);    while(!MODE);
      ENABLE= 1;
     //     printf("\r B=%XENAB=1",PORTB&0x30); while(MODE); delay_ms(100);    while(!MODE);
      delay_us(10);
      ENABLE= 0;
}

// RS=mode CMD=0 DAT=1
void lcd_send_lcd ( unsigned int8 mode, unsigned int8 n ) {
 //     RS = 0;
      delay_ms(1); // pieni viive koska lcd ei lueta takain

      RS = mode;
      //      printf("\r B=%X send daddr=%d data=%d ", PORTB&0x30,address,n);  while(MODE); delay_ms(100);    while(!MODE);
      delay_us(10);

      ENABLE= 0;  // enablen lepotila
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
      RS=1; // datamode, RS=0 on komentomode
}

/*===========================0

Tämä pitää alustaa ennen käyttöä

==============================*/
void lcd_init(void) {
    unsigned int8 i;
    set_tris_b(0xC0);
    RS = 0;
  //  RW = 0;
    ENABLE= 0;
    delay_ms(15);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(LCD4MODE);  // 4-bit mode =3
       delay_ms(5);
    }
    lcd_send_nibble(2);    // alusta LCD
    for(i=0;i<=3;++i)
       lcd_send_lcd(CMD,LCD_INIT_STRING[i]);

   lcd_send_lcd(CMD,  LCD_CURSOR_OFF); /* kursori päälle ja eteenpäin */
  // printf("\r LCD init");

}

// x = data
void lcd_gotoxyl( unsigned int8 x, unsigned int8 rivi) {
   unsigned int8 address;

   if(rivi!=1)
     address=lcd_line_two;
   else
     address=0;
   address+=x-1;
   lcd_send_lcd(0,0x80|address);
}
/*=================
aseta LCD kursoriosoiteet
===================*/
void lcd_gotoxy( unsigned int8 x) {
   lcd_send_lcd(CMD,x);
}
/*************
 yksi merkki LCD.lle
*******/
char lcd_putc( char c) {
   switch (c) {
  /**   case '\f'   : lcd_send_unsigned int8(0,1);
                  delay_ms(2);
                                       break; ******/
     case '\n'   : lcd_gotoxy(2);        break;  // contrl/ J = enter
     case '\b'   : lcd_send_lcd(0,0x10);  break; /* mode =0 komento 10 0backstep */
     default     : lcd_send_lcd(DAT,c);     break; /* mode=1, data */
   }
   return c;
}


void lcdrow1 ( void) {
lcd_send_lcd(CMD,ROW1);
}

void lcdrow2 ( void) {
lcd_send_lcd(CMD,ROW2);
}

/**************** aseta rivi ja kursorin paikka ****************/
void set_row( void) {
 

if( row > 2)
     row=0;

switch ( row) {
     case 0: lcd_gotoxy(ROW2+rowcount);  break;
   case 1: lcd_gotoxy(ROW3+rowcount);    break;
   default: lcd_gotoxy(ROW1+rowcount);   break; // huom oli ROW4 , mutta nyt se on käytössä voltti ja virta

   } // switche end

}

void clearLcd( void) {
  lcd_send_lcd(CMD,LCD_CLEAR); 
}
void del200( void) {
delay_ms(200); 
 while (!MODE) ; // odota MODE painonapin poismeneoa 
}
/********************
 lue logo eeprommista
******************************/

//const char  [4]={ROW1,ROW2,ROW3,ROW4};
void  lcdlogo( void) {
 
 clearLcd(); // nollaa näyttö aluksi

       lcdrow1 ();    printf(lcd_putc,"Probyte   ") ;
       lcdrow2 ();   printf(lcd_putc,"Timer") ;

 
}

 
 
 
 
 
 
