/* LCD_GD-5360P.h
   Hlavièkový súbor pre ovládanie LCD displeja GD-5360P na vývojovej doske
   TWR-S08LH64 s mikrokontrolérom MC9S08LH64
   Autor: Miroslav Štibraný, FEKT VUT Brno 2014 */

#include "derivative.h" 
#include "IO.h"
#ifndef LCD 
#define LCD

#define	max_position	5	   // Poèet sedemsegmentových pozícií
#define char_range_min	' '	   // Zaèiatoèný znak v poli table[]
#define char_range_max	'Z'	   // Koneèný znak v poli table[]
#define seg_on			0x33   // Zapnutie oboch segmentov na jednom vývode backplane ( LCDWFxx = 0b0011 0011 ) aj v alternatívnych fázach E a F
#define spec_char_max	3	   // Poèet nadefinovaných špeciálnych znakov v poli table_special[] ( v súbore LCD_GD-5360P.c )

// Makrá
#define Set_bits(num,bit)   LCDWF##num |=  ( ( 1 << (bit) ) | ( 1 << (bit+4) ) )	// Trvalé zobrazenie segmentu ( vo fázach A alebo B a E alebo F  )
#define Set_bit(num,bit)	LCDWF##num |=    ( 1 << (bit) )							// Zobrazenie len vo fáze A alebo B
#define Set_bit2(num,bit)	LCDWF##num |=    ( 1 << (4+bit) )						// Zobrazenie len vo fáze E alebo F ( alternatívne fázy pri využití možnosti blikania - register LCDBCTL ) 
#define Clear_bits(num,bit) LCDWF##num &= ~( ( 1 << (bit) ) | ( 1 << (bit+4) ) )
#define Clear_bit(num,bit)  LCDWF##num &= ~( ( 1 << (bit) ) )
#define Clear_bit2(num,bit) LCDWF##num &= ~( ( 1 << (4+bit) ) )
#define Reg(num)   		    LCDWF##num
#define Clr_reg(num)        LCDWF##num = 0

// Zapnutie jednotlivých špeciálnych segmentov	  
#define P0_on    Set_bits(1,0)
#define P1_on    Set_bits(1,1)
#define P2_on    Set_bits(2,1)
#define P3_on    Set_bits(2,0)
#define P4_on    Set_bits(3,0)
#define MO_on    Set_bits(0,0)
#define TU_on    Set_bits(4,0)
#define WE_on    Set_bits(13,0)
#define TH_on    Set_bits(14,0)
#define FR_on    Set_bits(18,0)
#define SA_on    Set_bits(19,1)
#define SU_on    Set_bits(20,1)
#define T1_on    Set_bits(0,1)
#define COL_on   Set_bits(13,1)
#define AM_on    Set_bits(24,0)
#define PM_on    Set_bits(24,1)
#define HEAT_on  Set_bits(19,0)
#define COLD_on  Set_bits(20,0)
#define FLTR_on  Set_bits(25,0)
#define HOLD_on  Set_bits(25,1)

// Zapnutie blikania jednotlivých segmentov
#define P0_blink_on    Clear_bit2(1,0);  Set_bit(1,0)
#define P1_blink_on    Clear_bit2(1,1);  Set_bit(1,1)
#define P2_blink_on    Clear_bit2(2,1);  Set_bit(2,1)
#define P3_blink_on    Clear_bit2(2,0);  Set_bit(2,0)
#define P4_blink_on    Clear_bit2(3,0);  Set_bit(3,0)
#define MO_blink_on    Clear_bit2(0,0);  Set_bit(0,0)
#define TU_blink_on    Clear_bit2(4,0);  Set_bit(4,0)
#define WE_blink_on    Clear_bit2(13,0); Set_bit(13,0)
#define TH_blink_on    Clear_bit2(14,0); Set_bit(14,0)
#define FR_blink_on    Clear_bit2(18,0); Set_bit(18,0)
#define SA_blink_on    Clear_bit2(19,1); Set_bit(19,1)
#define SU_blink_on    Clear_bit2(20,1); Set_bit(20,1)
#define T1_blink_on    Clear_bit2(0,1);  Set_bit(0,1)
#define COL_blink_on   Clear_bit2(13,1); Set_bit(13,1)
#define AM_blink_on    Clear_bit2(24,0); Set_bit(24,0)
#define PM_blink_on    Clear_bit2(24,1); Set_bit(24,1)
#define HEAT_blink_on  Clear_bit2(19,0); Set_bit(19,0)
#define COLD_blink_on  Clear_bit2(20,0); Set_bit(20,0)
#define FLTR_blink_on  Clear_bit2(25,0); Set_bit(25,0)
#define HOLD_blink_on  Clear_bit2(25,1); Set_bit(25,1)

// Zapnutie blikania jednotlivých segmentov v opaènej fáze
#define P0_blink_inv_on    Clear_bit(1,0);  Set_bit2(1,0)
#define P1_blink_inv_on    Clear_bit(1,1);  Set_bit2(1,1)
#define P2_blink_inv_on    Clear_bit(2,1);  Set_bit2(2,1)
#define P3_blink_inv_on    Clear_bit(2,0);  Set_bit2(2,0)
#define P4_blink_inv_on    Clear_bit(3,0);  Set_bit2(3,0)
#define MO_blink_inv_on    Clear_bit(0,0);  Set_bit2(0,0)
#define TU_blink_inv_on    Clear_bit(4,0);  Set_bit2(4,0)
#define WE_blink_inv_on    Clear_bit(13,0); Set_bit2(13,0)
#define TH_blink_inv_on    Clear_bit(14,0); Set_bit2(14,0)
#define FR_blink_inv_on    Clear_bit(18,0); Set_bit2(18,0)
#define SA_blink_inv_on    Clear_bit(19,1); Set_bit2(19,1)
#define SU_blink_inv_on    Clear_bit(20,1); Set_bit2(20,1)
#define T1_blink_inv_on    Clear_bit(0,1);  Set_bit2(0,1)
#define COL_blink_inv_on   Clear_bit(13,1); Set_bit2(13,1)
#define AM_blink_inv_on    Clear_bit(24,0); Set_bit2(24,0)
#define PM_blink_inv_on    Clear_bit(24,1); Set_bit2(24,1)
#define HEAT_blink_inv_on  Clear_bit(19,0); Set_bit2(19,0)
#define COLD_blink_inv_on  Clear_bit(20,0); Set_bit2(20,0)
#define FLTR_blink_inv_on  Clear_bit(25,0); Set_bit2(25,0)
#define HOLD_blink_inv_on  Clear_bit(25,1); Set_bit2(25,1)

// Vypnutie jednotlivých špeciálnych segmentov
#define P0_off    Clear_bits(1,0)
#define P1_off    Clear_bits(1,1)
#define P2_off    Clear_bits(2,1)
#define P3_off    Clear_bits(2,0)
#define P4_off    Clear_bits(3,0)
#define MO_off    Clear_bits(0,0)
#define TU_off    Clear_bits(4,0)
#define WE_off    Clear_bits(13,0)
#define TH_off    Clear_bits(14,0)
#define FR_off    Clear_bits(18,0)
#define SA_off    Clear_bits(19,1)
#define SU_off    Clear_bits(20,1)
#define T1_off    Clear_bits(0,1)
#define COL_off   Clear_bits(13,1)
#define AM_off    Clear_bits(24,0)
#define PM_off    Clear_bits(24,1)
#define HEAT_off  Clear_bits(19,0)
#define COLD_off  Clear_bits(20,0)
#define FLTR_off  Clear_bits(25,0)
#define HOLD_off  Clear_bits(25,1)
	  	  
const unsigned char table[];
const unsigned char table_special[];
const unsigned char bit_position[];
unsigned char * const LCDWF_Registers[];
//typedef enum { MO = 1, TU, WE, TH, FR, SA, SU } days;

void Init_clock ( void );	/* Inicializácia hodinového signálu pre LCD radiè */
void Init_LCD ( void );		/* Inicializácia registrov LCD radièa */
void All_seg_on ( void );	/* Procedúra zobrazí všetky segmenty displeja */ 
void All_seg_off ( void );	/* Procedúra vypne všetky segmenty LCD displeja GD-5360P */

void Write_char ( char character, unsigned char position );
/* Procedúra zapíše zadaný znak na zadanú pozíciu, kontroluje sa, èi taká pozícia existuje
   alebo èi je taký znak definovaný v poli table[], pokia¾ neexistuje, výpis sa nevykoná. */

void Write_spec_char ( unsigned char char_code, unsigned char position );
/* Procedúra zapíše špeciálny znak ( nadefinovaný v poli table_special[] ) na zadanú pozíciu, kontroluje sa,
   èi taká pozícia existuje alebo èi je taký znak nadefinovaný, pokia¾ neexistuje, výpis sa nevykoná. */

void Write_string ( char *str, unsigned char init_position );
/* Procedúra zapisuje znakový re�azec str od pozície init_postition */

void Num_aux ( int num );
/* Výpis èísla v rozsahu -9 až 99 na sedemsegmentových pozíciach 4 a 5.
   Pri pokuse vypísa� èíslo mimo rozsah funkcia vypíše na displej OL ( overload ) */

void Num_aux_hex ( unsigned int num );
/* Výpis èísla v rozsahu 0 až 0xff na sedemsegmentových pozíciach 4 a 5.
   Pri pokuse vypísa� èíslo mimo rozsah funkcia vypíše na displej OL ( overload ) */

void Num_small ( int num );
/* Výpis èísla v rozsahu -99 až 1 999, s využitím segmentu T1 (znak jedna) a sedemsegmentových znakov 1 až 3.
   Pri pokuse vypísa� èíslo mimo rozsah funkcia vypíše na displej OL ( overload ) */

void Num_small_hex ( unsigned int num );
/* Výpis èísla v rozsahu 0 až 0x1fff, s využitím segmentu T1 (znak jedna) a sedemsegmentových znakov 1 až 3.
   Pri pokuse vypísa� èíslo mimo rozsah funkcia vypíše na displej OL ( overload ) */

void Num_big ( long int num );
/* Výpis èísla v rozsahu -9999 až 199 999, s využitím segmentu T1 (znak jedna) a sedemsegmentových znakov 1 až 5.
   Pri pokuse vypísa� èíslo mimo rozsah funkcia vypíše na displej OL ( overload ) */

void Num_big_hex ( unsigned long int num );
/* Výpis èísla v rozsahu 0 až 0x1fffff, s využitím segmentu T1 (znak jedna) a sedemsegmentových znakov 1 až 5.
   Pri pokuse vypísa� èíslo mimo rozsah funkcia vypíše na displej OL ( overload ) */

void Set_week_day ( enum days );	/* Procedúra sa stará o vypisovanie zvoleného dòa v týždni. */
void Clr_week_day ( void );			/* Procedúra zmaže segmenty dní v týždni z displeja */
void Battery ( unsigned char ctrl );/* Procedúra zobrazuje stav batérie. */

void Time_HM ( unsigned int hours, unsigned int minutes );
/* Výpis hodín - vstupom je poèet hodín od 0 do 23, poèet minút od 0 do 59. 
   Na displeji sa zobrazujú v 12 hodinovom formáte ( AM / PM ). Znak dvojbodky bliká. */

void Time_HMS ( unsigned int hours, unsigned int minutes, unsigned int seconds );
/* Procedúra pre laboratórnu úlohu */
/* Výpis hodín - vstupom je poèet hodín od 0 do 23, poèet minút od 0 do 59 a poèet sekúnd od 0 do 59. 
   Na displeji sa zobrazujú v 12 hodinovom formáte ( AM / PM ). Znak dvojbodky bliká. */

void Stopwatch ( unsigned int minutes, unsigned int seconds, unsigned int ticks );
/* Procedúra pre laboratórnu úlohu */
/* Výpis èasu pri stopkách. Vstupom je poèet minút od 0 do 19, poèet sekúnd od 0 do 59 a poèet stotín sekundy od 0 do 99. */


#endif
