Rev 48 | Rev 51 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include <avr/io.h>
#include "wire.h"
#include "lcd.h"
#include "petelib.h"
#include <util/delay.h>
struct {
uint8_t display;
uint8_t function;
uint8_t backlight;
} lcd;
void lcd_init() {
lcd.backlight = LCD_BACKLIGHT;
lcd.display = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
lcd.function = LCD_2LINE;
lcd_pulse(0x30);
_delay_ms(50);
lcd_pulse(0x30);
_delay_ms(50);
lcd_pulse(0x30);
_delay_ms(50);
lcd_pulse(0x20);
_delay_ms(10);
lcd_command(LCD_FUNCTIONSET | lcd.function);
_delay_ms(10);
lcd_command(LCD_DISPLAYCONTROL | lcd.display);
_delay_ms(10);
lcd_clear();
_delay_ms(10);
lcd_home();
_delay_ms(10);
}
void lcd_pergraph(uint8_t val, uint8_t row, uint8_t col) {
uint8_t i = 0;
uint8_t c = val / 10;
lcd_setCursor(row, col);
for (i = 0; i<=10; i++) {
if (i <= c)
lcd_char(0xff);
else
lcd_char(0x00);
}
}
/** Helper functions **/
inline void lcd_clear() {
lcd_command(LCD_CLEARDISPLAY);
}
inline void lcd_home() {
lcd_command(LCD_RETURNHOME);
}
inline void lcd_backlight() {
lcd.backlight = LCD_BACKLIGHT;
}
inline void lcd_noBacklight() {
lcd.backlight = LCD_NOBACKLIGHT;
}
void lcd_display() {
lcd.display |= LCD_DISPLAYON;
lcd_command(LCD_DISPLAYCONTROL | lcd.display);
}
void lcd_noDisplay() {
lcd.display &= ~LCD_DISPLAYON;
lcd_command(LCD_DISPLAYCONTROL | lcd.display);
}
void lcd_autoscroll() {
lcd.display |= LCD_ENTRYSHIFTINCREMENT;
lcd_command(LCD_ENTRYMODESET | lcd.display);
}
void lcd_setCursor(uint8_t col, uint8_t row) {
uint8_t row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
lcd_command(LCD_SETDDRAMADDR | ((col - 1)+ row_offsets[row]));
}
void lcd_overprint(char * str, uint8_t len, uint8_t col, uint8_t row) {
uint8_t i = 0;
for (i=0; i<=len; i++)
lcd_char(0x20);
lcd_setCursor(row, col);
uint8_t size = lcd_print(str);
for (i=size; i<=len; i++)
lcd_char(0x20);
}
/** End helpers **/
void lcd_command(uint8_t data) {
lcd_send(data, LCD_MODE_CM);
}
void lcd_char(uint8_t data) {
lcd_send(data, LCD_MODE_RS);
}
uint8_t lcd_print(char* str) {
uint8_t c = 0;
while (str[0] != 0x00) {
lcd_char((uint8_t) str[0]);
str++;
c++;
}
return c;
}
void lcd_send(uint8_t value, uint8_t mode) {
uint8_t high = value & 0xf0;
uint8_t low = (value << 4) & 0xf0;
lcd_pulse((high)|mode);
lcd_pulse((low)|mode);
}
void lcd_pulse(uint8_t data) {
i2c_beginTransmission(LCD_ADDR);
i2c_writeByte((int) data | LCD_MODE_EN | lcd.backlight);
i2c_writeByte((int) data | lcd.backlight);
i2c_endTransmission(1);
_delay_us(5);
}
void lcd_createChar(uint8_t location, uint8_t charmap[]) {
location &= 0x7; // we only have 8 locations 0-7
lcd_command(LCD_SETCGRAMADDR | (location << 3));
uint8_t i = 0;
for (i=0; i<8; i++) {
lcd_char(charmap[i]);
}
}