/* Useful functions for using a HD44780 character LCD
 * The LCD should be connected through a 74168 8-bit SIPO
 * shift register (or any other SIPO shift register with some modification)
 */

#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>

#include "lcd_util.h"

void shift_out(char data) {
	char i, bit;
	for (i = 0; i <= 7; i++) {
		bit = data & (1 << i);		
		(bit > 0) ? (LCD_PORT |= (1 << SH_DATA)) : (LCD_PORT &= ~(1 << SH_DATA));
		LCD_PORT |= (1 << SH_CLOCK);
		LCD_PORT &= ~(1 << SH_CLOCK);
		_delay_us(100);
	}
return;
}

void instruction_cmd(char data) {
	shift_out(data);	
	LCD_PORT &= ~(1 << RS);	
	LCD_PORT |= (1 << EN);
	LCD_PORT &= ~(1 << EN);
	_delay_ms(3);
return;
}

void data_cmd(char data) {
	shift_out(data);
	LCD_PORT |= (1 << RS);	
	LCD_PORT |= (1 << EN);
	LCD_PORT &= ~(1 << EN);
	_delay_ms(3);
return;
}

void init_lcd() {
	instruction_cmd(0x38);
	instruction_cmd(0x0C);
	instruction_cmd(0x06);
	instruction_cmd(0x01);
return;
}

void print_string_pmem(PGM_P pstring, char pos) {
	uint8_t i = 0;
	char in_ram;
	instruction_cmd(SET_DDRAM | pos);
	while (in_ram = pgm_read_byte(&pstring[i])) {
		data_cmd(in_ram);
		i++;
	};
}

void print_string(char * string, char pos) {
	uint8_t i = 0;
	instruction_cmd(SET_DDRAM | pos);
	do {
		data_cmd(string[i]);
		i++;
	} while (string[i] != '\0');
return;
}

void ctos(char * s, char i) {
	s[3] = '\0';
	s[0] = (i/100) | 0x30;
	if (s[0] == 0x30) s[0] = ' ';
	s[1] = (i/10)%10 | 0x30;
	if ((s[1] == 0x30) && (s[0] == ' ')) s[1] = ' ';
	s[2] = (i%10) | 0x30;

}
