
#include <stdio.h>
#include "stm32l4xx_hal.h"
#include "stm32l4xx_it.h"

// My 2004A module address = 0x40

uint8_t SlaveAddress; //address variable

extern I2C_HandleTypeDef hi2c1; // define I2C line!!!


  //Set I2C Adress
  void lcd_set_address (uint8_t Adress)
  {
	SlaveAddress = Adress;
  }


  //Send command
  void lcd_send_cmd (char cmd)
  {
    char data_u, data_l;
  	uint8_t data_t[4];
  	data_u = (cmd & (0xf0));
  	data_l = ((cmd<<4) & (0xf0));
  	data_t[0] = data_u|0x0C;  //en=1, rs=0
  	data_t[1] = data_u|0x08;  //en=0, rs=0
  	data_t[2] = data_l|0x0C;  //en=1, rs=0
  	data_t[3] = data_l|0x08;  //en=0, rs=0
  	HAL_I2C_Master_Transmit (&hi2c1, SlaveAddress, data_t, 4, 100);
  	HAL_Delay(1);
  }


  //Send data
  void lcd_send_data (char data)
  {
  	char data_u, data_l;
  	uint8_t data_t[4];
  	data_u = (data& (0xf0));
  	data_l = ((data<<4) & (0xf0));
  	data_t[0] = data_u|0x0D;  //en=1, rs=1
  	data_t[1] = data_u|0x09;  //en=0, rs=1
  	data_t[2] = data_l|0x0D;  //en=1, rs=1
  	data_t[3] = data_l|0x09;  //en=0, rs=1
  	HAL_I2C_Master_Transmit (&hi2c1, SlaveAddress, data_t, 4, 100);
  	HAL_Delay(1);
  }


  //Send string
  void lcd_send_string (char *str)
  {
  	while (*str){
  		lcd_send_data (*str++);
  	}
  }


  //Initialize Display
  void lcd_init ()
  {
  	// 4 bit initialization
  	HAL_Delay(50);  // wait for >40ms
  	lcd_send_cmd (0x30);
  	HAL_Delay(5);
  	lcd_send_cmd (0x30);
  	HAL_Delay(5);
  	lcd_send_cmd (0x30);
  	HAL_Delay(10);
  	lcd_send_cmd (0x20);  // 4bit mode
  	HAL_Delay(10);

    // display initialization
  	lcd_send_cmd (0x28); // Function set --> DL=0 (4 bit mode), N = 1 (2 line display) F = 0 (5x8 characters)
  	HAL_Delay(5);
  	lcd_send_cmd (0x08); //Display on/off control --> D=0,C=0, B=0  ---> display off
  	HAL_Delay(5);
  	lcd_send_cmd (0x01);  //Clear display
  	HAL_Delay(5);
  	lcd_send_cmd (0x06); //Entry mode set --> I/D = 1 (increment cursor) & S = 0 (no shift)
  	HAL_Delay(5);
  	lcd_send_cmd (0x0C); //Display on/off control --> D = 1, C and B = 0. (Cursor and blink, last two bits)
  	HAL_Delay(5);
  }


  //line set 0-3, col set 0-19
  void lcd_set_line_col (uint8_t line, uint8_t col)
  {
	  if(((line<4) && (line>=0)) && ((col >= 0) && (col < 20))){

		  switch (line)
		  {
			  case 0 :
					  lcd_send_cmd(0x80|(0x00+(col)));
					  break;

				  case 1 :
					  lcd_send_cmd(0x80|(0x40+(col)));
					  break;

				  case 2 :
					  lcd_send_cmd(0x80|(0x14+col));
					  break;

				  case 3 :
					  lcd_send_cmd(0x80|(0x54+col));
					  break;

				  default:
					  break;
		  }
	  }
  }


  //clear LCD
  void lcd_clear()
  {
	  lcd_send_cmd(0x01);
	  HAL_Delay(2);
  }






