/*****************************************************
Библиотека работы с модулем экрана Nokia 3310
*****************************************************/
#ifndef _FastSoft_Nokia3110Lib_Included_
#define _FastSoft_Nokia3110Lib_Included_

//Выбор выводов подключения 
#define LCD5110_SCE PORTC.0 //если закоментировать то не будет производится операции выбора чипа
#define LCD5110_RST PORTC.1
#define LCD5110_DC PORTC.2
#define LCD5110_MOSI PORTC.3
#define LCD5110_CLK PORTC.4

//Настройки, коментируем строки с тем что не надо ...
#define LCD5110_Graphics    //Включает графические функции, при этом размер экрана высота 48 ширина 84 пикселя
#define LCD5110_AutoRefresh //Включает авто синхронизацию между буфером и LCD модулем после каждой графической функции

#define LCD5110_TextPositionInPixels //Включает пиксельное позиционирование шрифтов в графическом режиме, при отключении позиционируется в знакоместах 
#define LCD5110_TextScreen_4x8 //Включает функции текстового дисплея с шрифтом 4x8, при отключенном гафическом режиме дисплей делится на 6 строк 21 колонку
#define LCD5110_TextScreen_4x8_Font //Включает в компиляцию шрифт 4x8 занимает 1024 байта в полной комплектации
#define LCD5110_TextScreen_4x8_Font_SysSym





/*
    -------------- Общаие функции --------------
*/

#ifdef LCD5110_Graphics 
unsigned char LCD5110_GraphScreen[504];//Буфер экрана
#endif

#ifdef LCD5110_TextScreen_4x8_Font
flash unsigned char LCD5110_Font48[]={
                                0x00,0x10,0x00,0x00, //0x00 Символ неизвестности (точка) 
    #ifdef LCD5110_TextScreen_4x8_Font_SysSym 
                                0x74,0xA2,0x74,0x00, //0x01 белая рожа
                                0x00,0x10,0x00,0x00, //0x02
                                0x00,0x10,0x00,0x00, //0x03
                                0x00,0x10,0x00,0x00, //0x04
                                0x00,0x10,0x00,0x00, //0x05
                                0x00,0x10,0x00,0x00, //0x06
                                0x00,0x10,0x00,0x00, //0x07
                                0x00,0x10,0x00,0x00, //0x08
                                0x00,0x10,0x00,0x00, //0x09
                                0x00,0x10,0x00,0x00, //0x0A
                                0x00,0x10,0x00,0x00, //0x0B
                                0x00,0x10,0x00,0x00, //0x0C
                                0x00,0x10,0x00,0x00, //0x0D
                                0x00,0x10,0x00,0x00, //0x0E
                                0x00,0x10,0x00,0x00, //0x0F
                                0x00,0x10,0x00,0x00, //0x10
                                0x00,0x10,0x00,0x00, //0x11
                                0x00,0x10,0x00,0x00, //0x12
                                0x00,0x10,0x00,0x00, //0x13
                                0x00,0x10,0x00,0x00, //0x14
                                0x00,0x10,0x00,0x00, //0x15
                                0x00,0x10,0x00,0x00, //0x16
                                0x00,0x10,0x00,0x00, //0x17
                                0x00,0x10,0x00,0x00, //0x18
                                0x00,0x10,0x00,0x00, //0x19
                                0x00,0x10,0x00,0x00, //0x1A
                                0x00,0x10,0x00,0x00, //0x1B
                                0x00,0x10,0x00,0x00, //0x1C
                                0x00,0x10,0x00,0x00, //0x1E
                                0x00,0x10,0x00,0x00, //0x1D
                                0x00,0x10,0x00,0x00, //0x1F
    #endif 
                                0x00,0x10,0x00,0x00, //0x20 Space
                                0x00,0x5F,0x00,0x00, //0x21 !
                                0x03,0x00,0x03,0x00, //0x22 "
                                0x7F,0x24,0x7F,0x24, //0x23 #
                                0x46,0x89,0xFF,0x72, //0x24 $
                                0x00,0x10,0x00,0x00, //0x
                                0x00,0x10,0x00,0x00, //0x
                                
                                0xFC,0x22,0xFC,0x00 //A
                                }; 
#endif 
                                
/*
    -------------- Общие функции -----------------
*/
/*
    Функция отправляет байт data в модуль экрана
*/
void LCD5110_Wite(unsigned char data)
{
    int i=8;
    while (i--)
    {  
        LCD5110_MOSI= data & 128;
        LCD5110_CLK=1;
        data=data<<1;
        LCD5110_CLK=0;
    }
}

/*
    Функция отправляет команду в модуль экрана
*/
void LCD5110_WiteCMD(unsigned char data)
{
    LCD5110_DC=0; //Command Mode
    
    LCD5110_SCE=0;
    
    LCD5110_Wite(data);
    LCD5110_SCE=1;
}

/*
    Функция отправляет данные в модуль экрана
*/
void LCD5110_WriteData(unsigned char data)
{
    LCD5110_DC=1; //Data Mode
    
    LCD5110_SCE=0;
    
    LCD5110_Wite(data);
    LCD5110_SCE=1;
}

/*
    Функция инициализирует модуль экрана
*/
void LCD5110_Init(void)
{
    //Сброс чипа
    
    LCD5110_RST=0;
    
    LCD5110_RST=1;
    

    LCD5110_WiteCMD( 0x21 ); // LCD Extended Commands.
    
    LCD5110_WiteCMD( 0xBF ); // Set LCD Vop (Contrast)
    
    LCD5110_WiteCMD( 0x06 ); // Set Temp coefficent
    
    LCD5110_WiteCMD( 0x14 ); // LCD bias mode 1:48
    

    LCD5110_WiteCMD( 0x20 ); // LCD Standard Commands.
    LCD5110_WiteCMD( 0x0C ); // LCD in normal mode. 0x0d for inverse
}

/*
    Функция отчистки содержимого экрана
*/
void LCD5110_Cls(void)
{
    //Зачистка данных в экранном модуле
    int i=504;
    while(i--)
    {
        LCD5110_WriteData(0x00);
        
#ifdef LCD5110_Graphics         
        LCD5110_GraphScreen[i-1]=0x00;
#endif
    }
    //Отчистка для графической библиотеки
}

/*
    Функция устанавливает указатель вывода данных модуля в координаты
*/
void LCD5110_SetLcdAddr(unsigned char X,unsigned char Y)
{
    LCD5110_WiteCMD(0x80 | (X & 0x7F));
    LCD5110_WiteCMD(0x40 | (Y & 0x3F));    
}    

/*
    -------------- Графические функции --------------
*/
#ifdef LCD5110_Graphics 
/*
    Функция обновления содержимого экрана,синхронизирует буфер в модуль экрана
*/
void LCD5110_RefreshGrph(void)
{
    int i;
    
    LCD5110_SetLcdAddr(0,0);//ставим позицию экрана в ноль
    for(i=0;i<504;i++)
    {
      LCD5110_WriteData(LCD5110_GraphScreen[i]);   
    }
}

/*
    Функция накладывает байт на байт в зависимости от режима
*/
unsigned char LCD5110_Imposition(unsigned char One,unsigned char Two,unsigned char Mode)
{
  switch (Mode)
  {
   case 1:return One | Two; // (OR)
   case 2:return One ^ Two; // (XOR)
   default:return One & (Two^0xFF); // Reset
  }
}
/*
    Функция вывода точки
*/
void LCD5110_Point(unsigned char X,unsigned char Y,unsigned char Mode)
{
    unsigned char SY,SYB,B;
    if(Y>47 || X>83) return; //Точку не видать то ...
    SY=Y>>3;//Получаем номер строки байта по Y
    SYB=Y&7;//Получаем номер бита

    //Вычесляем бит
    B=1;
    while (SYB)
    {
        B=B<<1;
        SYB--;
    }
 
    LCD5110_GraphScreen[(SY*84)+X]=LCD5110_Imposition(LCD5110_GraphScreen[(SY*84)+X],B,Mode);

#ifdef LCD5110_AutoRefresh
    LCD5110_RefreshGrph();
#endif
}
/*

    void LCD5110_ScrollUp(unsigned char Pixels)
    {
    }
    void LCD5110_ScrollDown(unsigned char Pixels)
    {
    } 
    void LCD5110_ScrollLeft(unsigned char Pixels)
    {
         
    } 
    void LCD5110_ScrollRight(unsigned char Pixels)
    {
    } 
    void LCD5110_RollUp(unsigned char Pixels)
    {
    }
    void LCD5110_RollDown(unsigned char Pixels)
    {
    } 
    void LCD5110_RollLeft(unsigned char Pixels)
    {
    } 
    void LCD5110_RollRight(unsigned char Pixels)
    {
    } 
*/ 
#endif

/*
    -------------- Текстовые функции --------------
*/

/*
    Выводит один символ
        если включен режим графической библиотеки то координаты задаются в пикселях
        в противном случае в символах
*/
void LCD5110_DrawChar48(unsigned char X,unsigned char Y,unsigned char SymCode,unsigned char Mode)
{
    unsigned int Addr;
    unsigned char i=4,Shift;
    
    //Расчет смещения шрифта
    flash unsigned char *Font=LCD5110_Font48;
    Font+=SymCode*4;
    
    #ifdef LCD5110_Graphics
        //Обработка в режиме графики
        #ifdef LCD5110_TextPositionInPixels
            //Обработка вывода с пиксельным позиционированием
            if(X>83 | Y>47)return;//Не будем тратить время на рисование того что не увидим
            
            Shift=Y & 7;//Вычесляем сдвиг
            Y=Y>>3;//Приводим к номеру строки Y координату
            Addr=Y*84+X;//Расчитываем адрес вывода
            
            while(i--)
            {
                //перебераем все байты символа
                if(Shift)
                {
                    //Если нужно сдвигать то сдвигаем
                    LCD5110_GraphScreen[Addr]=LCD5110_Imposition(LCD5110_GraphScreen[Addr],*Font<<Shift,Mode);
                    if(Addr+84<503)LCD5110_GraphScreen[Addr+84]=LCD5110_Imposition(LCD5110_GraphScreen[Addr+84],*Font>>8-Shift,Mode);
                }
                else
                {
                    LCD5110_GraphScreen[Addr]=LCD5110_Imposition(LCD5110_GraphScreen[Addr],*Font,Mode);    
                }                
                Font++;
                Addr++;
            }
        #else 
            //Обработка вывода в символьном режиме
            if(X>20 | Y>5)return;//Не будем тратить время на рисование того что не увидим
            Addr=Y*84+X*4;
            while(i--)
            {
                LCD5110_GraphScreen[Addr]=LCD5110_Imposition(LCD5110_GraphScreen[Addr],*Font,Mode);
                Addr++;
                Font++;   
            }
        #endif
 
        #ifdef LCD5110_AutoRefresh
            LCD5110_RefreshGrph();
        #endif        
    #else
        //Обработка с отключенным графическим режимом
        if(X>20 | Y>5)return;//Не будем тратить время на рисование того что не увидим
        LCD5110_SetLcdAddr(X*4,Y);//Устанавливаем адрес вывода 
        while(i--)
        {
            LCD5110_WriteData(*Font);
            Font++;   
        }
    #endif
}
#endif