#include "stm32f1xx_hal.h"
#include "ssd1805.h"



char lcd_x = 0;
char lcd_y = 0;
char column=0; 
char line=0; 
char contrast=10;
float t=0;


static const char ASCII[][5] ={
 {0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ?
,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f ?
};


void Delay_us(uint32_t cnt)
{
  while (cnt--) {
  }
}

void LcdWrite2(char dc, char data){
 if (dc==1) LCD_DC_GPIO_Port->BSRR = LCD_DC_Pin;
 else LCD_DC_GPIO_Port->BRR = LCD_DC_Pin;
LCD_CS_GPIO_Port->BRR = LCD_CS_Pin;
LCD_SCK_GPIO_Port->BSRR = LCD_SCK_Pin;
LCD_SCK_GPIO_Port->BRR = LCD_SCK_Pin;

	for (char i=0; i<8; i++) {
	if(data &(0x80>>i)) LCD_SDA_GPIO_Port->BSRR = LCD_SDA_Pin;
	else LCD_SDA_GPIO_Port->BRR = LCD_SDA_Pin;

LCD_SCK_GPIO_Port->BSRR = LCD_SCK_Pin;
LCD_SCK_GPIO_Port->BRR = LCD_SCK_Pin;
}
LCD_CS_GPIO_Port->BSRR = LCD_CS_Pin;
}

void LcdWrite(char dc, char data){
 if (dc==1) LCD_DC_GPIO_Port->BSRR = LCD_DC_Pin;
 else LCD_DC_GPIO_Port->BSRR = (uint32_t)LCD_DC_Pin << 16u;
 
LCD_CS_GPIO_Port->BSRR = (uint32_t)LCD_CS_Pin << 16u;

for (char i=0; i<8; i++) {
  LCD_SCK_GPIO_Port->BSRR = (uint32_t)LCD_SCK_Pin << 16u;
  
  if(data &(0x80>>i)) LCD_SDA_GPIO_Port->BSRR = LCD_SDA_Pin;
  else LCD_SDA_GPIO_Port->BSRR = (uint32_t)LCD_SDA_Pin << 16u;
  //Delay_us(2);
  LCD_SCK_GPIO_Port->BSRR = LCD_SCK_Pin;
  //Delay_us(2);
}
LCD_CS_GPIO_Port->BSRR = LCD_CS_Pin;
}

void LcdWrite_neg(char dc, char data){
 if (dc==1) LCD_DC_GPIO_Port->BSRR = LCD_DC_Pin;
 else LCD_DC_GPIO_Port->BSRR = (uint32_t)LCD_DC_Pin << 16u;
 
LCD_CS_GPIO_Port->BSRR = (uint32_t)LCD_CS_Pin << 16u;

for (char i=8; i>00; i--) {
  LCD_SCK_GPIO_Port->BSRR = (uint32_t)LCD_SCK_Pin << 16u;
  
  if(data &(0x80>>i)) LCD_SDA_GPIO_Port->BSRR = LCD_SDA_Pin;
  else LCD_SDA_GPIO_Port->BSRR = (uint32_t)LCD_SDA_Pin << 16u;
  //Delay_us(2);
  LCD_SCK_GPIO_Port->BSRR = LCD_SCK_Pin;
  //Delay_us(2);
}
LCD_CS_GPIO_Port->BSRR = LCD_CS_Pin;
}


  
  void LcdClear(void){
for (int index = 0; index < 1024 ; index++)
{
  LcdWrite(LCD_D, 0x00);
}
}

  void LcdClear_line(char l){
Lcd_set_pos_pix(0,l);
for (int index = 0; index < 132 ; index++)
{
  LcdWrite(LCD_D, 0x00);
}
}

void Lcd_set_pos_pix(char c, char r){
  lcd_x = c;
  lcd_y = r;
  LcdWrite(LCD_C,0xB0 | (r & 0x0F));
  LcdWrite(LCD_C,0x10 | ((c >> 4) & 0x07));
  LcdWrite(LCD_C,0x00 | (c & 0x0F));
}


void Lcd_set_pos(char c, char r){
  c = (c*6) ;
  r = r*1;
  Lcd_set_pos_pix(c,r);
}


void lcd_crlf(void){
  lcd_x = 0;
  lcd_y = lcd_y+1;
  if(lcd_y>=8) lcd_y = 0;
  Lcd_set_pos_pix(lcd_x,lcd_y);}
  
 
  void lcd_contrast(char contrast){
    contrast = contrast & 0x1F;
    LcdWrite(LCD_C,0x80 + contrast); 
  }
  
  
  void Lcd_drawColumn(char sline, char value){

    char lines=9-sline;
    if (value > lines*8) value = lines*8;
    char mrk = (lines*8 - 1 - value)/8;
    for (char line = 0; line < mrk; line++) { 
        Lcd_set_pos_pix(column, sline + line);
        LcdWrite(LCD_D, 0x00);}
        
    char b = 0xff;
    for (char i = 0; i < lines*8 - mrk*8 - value; i++) {
        b <<= 1;
    }
    Lcd_set_pos_pix(column, sline + mrk);
    LcdWrite(LCD_D, b);

    for (unsigned char line = mrk + 1; line < lines; line++) {
        Lcd_set_pos_pix(column, sline + line);
        LcdWrite(LCD_D, 0xff);
    } }


void LcdInitialise(void){
  
LCD_RST_GPIO_Port->BSRR = (uint32_t)LCD_RST_Pin << 16u;
HAL_Delay(50);
LCD_RST_GPIO_Port->BSRR = LCD_RST_Pin;
HAL_Delay(50);

LcdWrite(LCD_C, 0xE2);

LcdWrite(LCD_C, 0x2F); // power control register ok
LcdWrite(LCD_C, 0x26); // internal gain resistor ratio   ok


LcdWrite(LCD_C, 0x81);// contrast   ok
LcdWrite(LCD_C, 0x20);// contrast value   ok

LcdWrite(LCD_C, 0x85);

LcdWrite(LCD_C, 0xA0); // lcd direction

LcdWrite(LCD_C, 0xd1); // icon enable

LcdWrite(LCD_C, 0xA2); // lcd bias
LcdWrite(LCD_C, 0xC8); // Set COM Output Scan Direction
 
LcdWrite(LCD_C, 0xA4); // display normal / reverse

LcdWrite(LCD_C, 0xA6); // Display ON
LcdWrite(LCD_C, 0xAF);// display panel on

}





void LcdCharacter(char character){
  LcdWrite(LCD_D, 0x00);
  for (int index = 0; index < 5; index++)
  {LcdWrite(LCD_D, ASCII[character - 0x20][index]);
  }}

void LcdCharacter_neg(char character){
  LcdWrite(LCD_D, 0xff);
  for (int index = 0; index < 5; index++){
  LcdWrite(LCD_D, 0xff - (ASCII[character - 0x20][index]));
  }}

	void LcdString(char *characters){
while (*characters){
LcdCharacter(*characters++);
}
}
	
void LcdString_neg(char *characters, uint8_t neg){
if (neg==1){
while (*characters){
LcdCharacter_neg(*characters++);
}
}
else {
while (*characters){
LcdCharacter(*characters++);
}
}
}

void LcdString_f(unsigned int func){
char k = 0;
if (func>9999) func=9999;
unsigned int n=10000;
for ( char i = 0; i < 4; i++){
 n=n/10; 
 char tetra= func/n;
 if (tetra>0)  k = 1;
 char bukva=tetra+0x30; 
 if (k>0|| i==3) LcdCharacter(bukva);
 else LcdCharacter(0x20);
 func=func-tetra*n;}

}



 void DrawVlin (char y0, char y1)
{ char lin_y1=0;
  char lin_y0=0;
  char data_l=0;
  if  (y1==y0)
    { lin_y1=y1/8 ; data_l=1<< (y1-8*lin_y1) ;
      Lcd_set_pos_pix(column,lin_y1);
        LcdWrite(LCD_D, data_l);
    }
   else {lin_y0=y0/8; lin_y1=y1/8;
          if (lin_y0==lin_y1) {
             if (y1>y0) {char n=7-(y1-y0); char m=255>>n; data_l=m<<(y0-8*lin_y0);}
             else {char n=7-(y0-y1); char m=255>>n; data_l=m<<(y1-8*lin_y1);}
              Lcd_set_pos_pix(column,lin_y1); LcdWrite(LCD_D, data_l); }
          else {if (y1>y0) {char n=7-(y1-8*lin_y1); char m=255>>n; data_l=m;
                  Lcd_set_pos_pix(column,lin_y1); LcdWrite(LCD_D, data_l);
                  n=y0-8*lin_y0;  m=255<<n; data_l=m;
                  Lcd_set_pos_pix(column,lin_y0); LcdWrite(LCD_D, data_l);
                  if ((lin_y1-lin_y0)>1) { 
                    for ( char i=(lin_y0+1); i <lin_y1; i++) {
                      Lcd_set_pos_pix(column,i); LcdWrite(LCD_D, 255); }  }}
                
                  
                  char n=7-(y0-8*lin_y0); char m=255>>n; data_l=m;
                  Lcd_set_pos_pix(column,lin_y0); LcdWrite(LCD_D, data_l);
                  n=y1-8*lin_y1;  m=255<<n; data_l=m;
                  Lcd_set_pos_pix(column,lin_y1); LcdWrite(LCD_D, data_l);
                  if ((lin_y0-lin_y1)>1) { 
                    for ( char i=(lin_y1+1); i <lin_y0; i++) {
                      Lcd_set_pos_pix(column,i); LcdWrite(LCD_D, 255); }  }}
                                                                           }  }

void draw_progbar(int value,int row){
	int index;
	if(value>92)value=92;
	Lcd_set_pos(0,row);
	LcdWrite(LCD_D, 0xff);
	LcdWrite(LCD_D, 0x81);
	for (index = 0; index < 92; index++)
	{if (index<value)LcdWrite(LCD_D, 0xbd);
	else LcdWrite(LCD_D, 0x81);
	}
	LcdWrite(LCD_D, 0x81);
	LcdWrite(LCD_D, 0xff);
}

void draw_bitmap( const unsigned char *bitmap,unsigned char X_size,unsigned char Y_size,unsigned char X_start,unsigned char Y_start){
unsigned short row=0,z=0,index=0;
int index2=0;
row = Y_size/8;
row += Y_start;
if ((Y_size%8) != 0){row+=1;}
for ( z = Y_start; z < row; z++){
Lcd_set_pos_pix(X_start, z);
for ( index = 0; index < X_size; index++)
{LcdWrite(LCD_D, bitmap[index2]); index2++;
}
}
}
