#include <LPC21xx.H>	//Подключаем файл для данного МК
#include "LCD_fonts.h"	//Здесь шрифты и ещё кое-что для ГЖКД
#include "LCD_image.h"	//Здесь находится картинка 

// Global variables
int screenX, screenY;	//Эти глобальные координаты используются для хранения местоположения следующей записи данных


void delay_us(int wait){		//Процедура задержки в микросек.(точноть небольшая) при 11 Мгц
unsigned int d; 	
for (d=0;d<wait*2;d++) 	
	{}
}


static void SPI0_Init(void)	//Процедура инициализации SPI
{
    PINSEL0 |= 0x1100;             //Конфигурируем SPI пины, все пины GPIO кроме MOSI и SCK
    S0SPCCR = 0xc8;                 //Предделитель = 200, master clock = 62500
    S0SPCR  = 0x20;                //Режим работы: Мастер, без прерываний, LSB - 60, MSB - 20
}
 void LCD_writeData(unsigned char data)	//Процедура записи данных в ГЖКД
 {
       IO0CLR=(1<<7);  			//SCE=0
	    delay_us(1000);	//Небольшая задержка
	   IO0SET=(1<<5);  			//CD=1
	    delay_us(1000);	//Небольшая задержка 
	   S0SPDR  = data;            //Посылаем данные через SPI
        while (!(S0SPSR & 0x80));  //Ждём, пока завершится передача
	   IO0SET=(1<<7);  			//SCE=1
 }
void LCD_writeCommand (unsigned char command)	//Процедура записи команд в ГЖКД
 {      
	   IO0CLR=(1<<7);  			//SCE=0
	   delay_us(1000);	//Небольшая задержка
	   IO0CLR=(1<<5);  			//CD=0 
	   delay_us(1000);	//Небольшая задержка
	   S0SPDR  = command;         //Посылаем команды через SPI
        while (!(S0SPSR & 0x80)) ; //Ждём, пока завершится передача
	   IO0SET=(1<<7);  			//SCE=1
 }

void LCD_gotoXY ( unsigned char x, unsigned char y )	//Процедура перехода по координатам дисплея
{
	//Шлём команду дисплею, на каких координатах мы будем рисовать
     LCD_writeCommand (0x80 | x);   //Столбцы
	 delay_us(1000);	//Небольшая задержка
	LCD_writeCommand (0x40 | y);   //Строки
	delay_us(1000);	//Небольшая задержка
	
	//Обновить глобыльные переменны, так мы сможем отследить их позднее
	screenX = x;
	screenY = y;
}

void LCD_clear ( void ){	//Процедура очистки дисплея
int i,j;
	LCD_gotoXY (0,0);  	//Начать с (0,0) позиции

    for (i=0; i<6; i++)				//Для всех пикселов по высоте
		for(j=0; j<84; j++)			//И для всех пикселов по ширине
			LCD_writeData( 0x00 );	//Заполнить пустыми пикселями (нулями)
   	
    LCD_gotoXY (0,0);	//Вернуться в начальную позицию на дисплее (0,0)
}

void init_screen()		//Процедура инициализации дисплея
 {
       
	  /* LCD_writeCommand(0x21);            	//ГЖКД Расширенные команды
	   delay_us(1000);	//Небольшая задержка
       LCD_writeCommand(0xE0);			//Установить Vop (контраст).
	   delay_us(1000);	//Небольшая задержка
	   LCD_writeCommand(0x06);  			//Установить температурный коэффициент.
	   delay_us(1000);	//Небольшая задержка
	   LCD_writeCommand(0x13);			//Установить bias mode 1:48.
	   delay_us(1000);	//Небольшая задержка
	   LCD_writeCommand(0x20);			//Установить стандартные команды, горизонтальная адресация
	   delay_us(1000);	//Небольшая задержка
	   LCD_writeCommand(0x0c); 			//Установить ГЖКД в нормальный режим работы
	   delay_us(1000);	//Небольшая задержка
	   LCD_clear();					//Очитстить ГЖКД от мусора во внутренней памяти
	   delay_us(1000);	//Небольшая задержка*/


	   LCD_writeCommand(0x21);            	//ГЖКД Расширенные команды
	   delay_us(1000);	//Небольшая задержка
       LCD_writeCommand(0xc5);			//Установить Vop (контраст).
	   delay_us(1000);	//Небольшая задержка
	   LCD_writeCommand(0x13);			//Установить bias mode 1:48.
	   delay_us(1000);	//Небольшая задержка
	   LCD_writeCommand(0x20);			//Установить стандартные команды, горизонтальная адресация
	   delay_us(1000);	//Небольшая задержка
	   LCD_writeCommand(0x0c); 			//Установить ГЖКД в нормальный режим работы
	   delay_us(1000);	//Небольшая задержка
	   LCD_clear();					//Очитстить ГЖКД от мусора во внутренней памяти
	   delay_us(1000);	//Небольшая задержка*/
 }


void LCD_drawChar ( unsigned char ch ){		//Процедуры вывода одного символа
int j;
	// Newline = 0x0A in hex, if the char we want to draw is this,
	// we call gotoXY and increase Y by 1
	if(ch == 0x0A){
		LCD_gotoXY(0, ++screenY);
		return;	// We don't have anything more to do, return function.
	}
	
	// Sometimes the character we want to draw is too close to the edge of the screen
	// to be draw normally. To prevent the character from being partly drawn over 2 lines
	// we check if we have enough room so draw the character, and if we don't, we simply
	// draw it on the next line instead
	
	if(84-screenX < 5){	// If there are less than 5 pixels left of this ,
						// Count how many pixels this character needs
	
		int width = 0;
		for(j=0; j<5; j++){
			// Do not count skips
			if(font [(ch-32)*5 + j] == 128)
				continue;
			width++;
		}
		// If the width of this character is over the amount of pixels left on the X axis
		if(width > 84-screenX)
			LCD_gotoXY(0, ++screenY);	// Goto next line
	}
	// For 5 pixels (Our font maximum width)
	for(j=0; j<5; j++){
	
		// The first draw-able character we have is space (32 in decimal)
		// Our font do not use the first 32 ASCII characters, so we remove 32 from the character
		// we want to draw, and we get the same character as in out font!
		
		// As some of the characters don't use all 5 pixels, we can make it look nicer by not
		// drawing the empty space. 0b10000000 is the value for not drawing anything in our font, aka "skip"
		if(font [(ch-32)*5 + j] == 128)
		continue;
		// Remove 32 from the character we want to draw, and then draw is.
		LCD_writeData( font [(ch-32)*5 + j] );
	}
	
	//Draw one pixel of spacing between the character and the next one
	LCD_writeData(0x00);
}
void LCD_image()	//Вывод картинки на ГЖКД из файла LCD_image.h 
{
int j;
	for(j=0; j<504; j++){
		LCD_writeData( image [j] );
	}
	
	delay_us(8000000);
	LCD_clear(); 	

	for(j=0; j<504; j++){
		LCD_writeData( image2 [j] );
	}
	delay_us(8000000);
	LCD_clear();

	for(j=0; j<504; j++){
		LCD_writeData( image3 [j] );
	}
	delay_us(8000000);
	LCD_clear(); 
}


int main() {
int i,wait;

static const unsigned char display[] = { "Vse rabotaet!" };	//В массиве выводимая строка
wait=1000000;
PINSEL0 = 0x1100;   //Конфигурируем SPI пины, все пины GPIO кроме MOSI и SCK	   
IODIR0=0xffffffff;		//Конфигурируем пины на вывод

IO0SET=(1<<20);  		//подаём питание на дисплей (он будет питаться от вывода МК т.к. вывод МК = 3,3В, а дисплей потребляет мало)
IO0CLR=(1<<19);  		//reset=0  сбрасываем экран сразу после подачи питания
delay_us(500);
IO0SET=(1<<19);  		//reset=1
delay_us(10000);



SPI0_Init();		//Инициализируем SPI							
init_screen();	    	//Инициализируем дисплей							

while (1){
	LCD_gotoXY(20,1);	//ПЕреходим во вторую строку, двадцатую позицию на дисплее	

	LCD_drawChar('E');	//Выводим желаемые символы
	delay_us(wait);
	LCD_drawChar('L');	//"A" = A, 'A' = 66.
	delay_us(wait);
	LCD_drawChar('E');
	delay_us(wait);
	LCD_drawChar('S');
	delay_us(wait);
	LCD_drawChar('S');
	delay_us(wait);
	LCD_drawChar('A');
	delay_us(wait);
	LCD_drawChar('R');
	delay_us(wait);


delay_us(wait*5);
					//Или же выводим массив через цикл
	LCD_gotoXY(5,3);						
	for(i=0;i<sizeof(display)-1;++i){	// For byte in the array (1 character = 1 byte).
		LCD_drawChar(display[i]);}	// Draw the character to screen.

LCD_gotoXY(0,0);
delay_us(wait*5);
LCD_image();
delay_us(wait*8);
LCD_clear();   
} 
}

