Subversion Repositories group.electronics

Rev

Rev 61 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <avr/io.h>
#include <stdlib.h>
#include "wire.h"
#include "lcd.h"
#include "avrutil.h"
#include <util/delay.h>

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);
}


/************************/
/** Fancy functions    **/
/************************/
void lcd_percent_graph(uint8_t val, uint8_t row, uint8_t col) {
        uint8_t i = 0;
        uint8_t c = val / 10;   
        lcd_setCursor(col, row);
        for (i = 0; i<10; i++) {
                if (i < c)
                        lcd_char(0xff);
                else
                        lcd_char(0x00);
        }
}

/************************/
/** Character Printing **/
/************************/

uint8_t lcd_print_right(char *str) {
        uint8_t c = 0;
        char* oldstr = str;

        // Find the null terminator
        while ((++str)[0] != 0x00)
                c++;

        // Print backwards to start 
        lcd_autocursorRight();
        while (--str != oldstr -1)
                lcd_char((uint8_t) str[0]);
        lcd_autocursorLeft();

        return c;
}

void lcd_overprint_right(char *str, uint8_t len, uint8_t col, uint8_t row) {
        uint8_t c = 1;
        char* oldstr = str;
        while ((++str)[0] != 0x00)
                c++;

        lcd_setCursor(col+1, row);
        uint8_t i = 0;
        for (i = 0; i<(len-c); i++) 
                lcd_char(0x20);

        for (i = 0; i<c; i++) 
                lcd_char(oldstr[i]);
}

uint8_t lcd_print(char* str) {
        uint8_t c = 0;
        while ((str++)[0] != 0x00) {
                lcd_char((uint8_t) (str-1)[0]);
                c++;
        }
        return c;
}

void lcd_overprint(char * str, uint8_t len, uint8_t col, uint8_t row) {
        uint8_t i = 0;
        lcd_setCursor(col, row);

        uint8_t size = lcd_print(str);
        for (i=size; i<=len; i++)
                lcd_char(0x20);
}


/************************/
/** 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_autocursorLeft(void) {
        lcd.display |= LCD_ENTRYLEFT;
        lcd_command(LCD_ENTRYMODESET | lcd.display);
}

void lcd_autocursorRight(void) {
        lcd.display &= ~LCD_ENTRYLEFT;
        lcd_command(LCD_ENTRYMODESET | lcd.display);
}

void lcd_autoscroll() {
        lcd.display |= LCD_ENTRYSHIFTINCREMENT;
        lcd_command(LCD_ENTRYMODESET | lcd.display);
}

void lcd_noAutoscroll() {
        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]));
}

/************************/
/** Low level functions **/
/************************/

void lcd_command(uint8_t data) {
        lcd_send(data, LCD_MODE_CM);
}

void lcd_char(uint8_t data) {
        lcd_send(data, LCD_MODE_RS);
}

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]);
        }
}