/*
 *      lcd.c ... HD44780 LCD for STM32F4
 *
 *      Copyright (C) 2012 Jiri Pittner <jiri@pittnerovi.com>
 *
 *      This program is free software: you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation, either version 3 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      You should have received a copy of the GNU General Public License
 *      along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 */


#include "stm32f4_discovery.h"
#include "stm32f4xx_conf.h" // again, added because ST didn't put it here ?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "delay.h"


// LCD routines
/*located at PD0-7
        PD0-3=DB4-7
        PD4=E
        PD5=RW
        PD6=RS 
        PD7=light (via NPN transistor - 150mA)
*/


#define lcd_delay 50

volatile uint8_t light=0;

void lcd_w4bit(uint8_t rs, uint8_t x)
{
uint8_t val=1<<4|light|rs<<6;
GPIO_Write(GPIOD,val);
delay_xs(lcd_delay);
val |= (x&0x0f);
GPIO_Write(GPIOD,val);
delay_xs(lcd_delay);
GPIO_ResetBits(GPIOD, GPIO_Pin_4);
delay_xs(lcd_delay);
GPIO_SetBits(GPIOD, GPIO_Pin_4);
delay_xs(lcd_delay);
}

void lcd_init4bit(void)
{
delay_xs(20000);
lcd_w4bit(0,3);
delay_xs(10000);
lcd_w4bit(0,3);
delay_xs(500);
lcd_w4bit(0,3);
lcd_w4bit(0,2);
}

void lcd_wbyte(uint8_t rs, uint8_t x)
{
lcd_w4bit(rs,x>>4);
lcd_w4bit(rs,x);
}

void lcd_clear(void)
{
lcd_wbyte(0,0x01);
delay_xs(30000);
}


void lcd_init(void)
{
//hardware init
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = 0x00ff;//all 8 lower pins
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);


//software init
lcd_init4bit();
lcd_wbyte(0,0x28);
lcd_wbyte(0,0x08);
lcd_clear();
lcd_wbyte(0,0x06);
lcd_wbyte(0,0x0c);
}

void lcd_print(char *t)
{
while(*t) if(*t=='\n') {++t; lcd_wbyte(0,0xc0);} else lcd_wbyte(1,*t++);
}


void lcd_print8(char *t)
{
uint8_t l=0;
while(*t) {lcd_wbyte(1,*t++); ++l;}
while(l<8) {lcd_wbyte(1,' '); ++l;}
}

void lcd_cursor(uint8_t r, uint8_t c)
{
lcd_wbyte(0,0x80+c+(r<<6));
}



#ifdef standalone


int main(void)
{
usart2_init(115200);


char c[64];
print(USART2, "lcd testik\n"); 
lcd_init();
print(USART2, "lcd init done\n");

lcd_print("hello world!");
  while (1)
  {
  }
}

#endif

