/* * Delta mp3 player * Firmware V0.1 CC http://www.lestmar.com/ * This software is licensed under Creative Commons 3.0 in the the form of by-nc, wich means * that the use of this code is limited for non-commercial use. Any other use is permitted. * The routines used for MMC/SD and mp3 chip are licensed by Raphael Abrahams with different * restrictions (please check teuthis.com). */ // $Id: lcd_4bits.c 21 2010-07-28 08:38:59Z Tino $ #include "lcd.h" #byte LCD_LAT = 0xF89 // Port A #byte LCD_PORT = 0xF80 #byte LCD_TRIS = 0xF92 #byte CTRL_LAT = 0xF8C // Port D #byte CTRL_PORT = 0xF83 #byte CTRL_TRIS = 0xF95 #bit lcd4_rs = CTRL_LAT.2 #bit lcd4_rw = CTRL_LAT.3 #bit lcd4_e = CTRL_LAT.4 #bit lcd4_t_rs = CTRL_TRIS.2 #bit lcd4_t_rw = CTRL_TRIS.3 #bit lcd4_t_e = CTRL_TRIS.4 #bit busy_flag = LCD_PORT.7 static void lcd_post3(); static void lcd_busy(); #define PIPE_LEN 70 struct lcd_pipe_item { int1 cmd; char data; }; struct lcd_pipe_item pipe[PIPE_LEN]; int pipe_i=0; int pipe_f=0; int1 lcd_full() { return (((pipe_f+1) % PIPE_LEN) == pipe_i); } int1 lcd_empty() { return (pipe_f == pipe_i); } void lcd_pushcmd(char d) { pipe[pipe_f].cmd=1; pipe[pipe_f].data=d; pipe_f = (pipe_f+1) % PIPE_LEN; } void lcd_pushchar(char d) { pipe[pipe_f].cmd=0; pipe[pipe_f].data=d; pipe_f = (pipe_f+1) % PIPE_LEN; } void lcd_pop() { static int count=0; if (pipe_i != pipe_f) { struct lcd_pipe_item data; data = pipe[pipe_i]; if( data.cmd && (count>0) ) --count; else { if( data.cmd ) { lcd_putcmd(data.data); count=3; // Ensure at least x cycles between commands } else { lcd_putchar(data.data); if( data.cmd > 0) --count; } pipe_i = (pipe_i+1) % PIPE_LEN; } } } #if 0 int lcd4_test_busy() { char s = 0; int i; LCD_TRIS |= 0x0F; lcd4_rs = 0; lcd4_rw = 1; for(i=0;i<2;i++); lcd4_e = 1; delay_cycles(1); s=busy_flag; lcd4_e = 0; if( s == 1) check_cond(1); lcd4_rw = 0; LCD_TRIS &= 0xF0; } #endif static void lcd_post3() { lcd4_rs = 0; lcd4_rw = 0; LCD_LAT = 0x3; lcd4_e = 1; lcd4_e = 0; } void lcd_init() { lcd4_t_rs = 0; lcd4_t_rw = 0; lcd4_t_e = 0; lcd4_rs = 0; lcd4_rw = 0; lcd4_e = 0; LCD_TRIS &= 0xF0; LCD_LAT &= 0xF0; delay_ms(15); lcd_post3(); delay_ms(5); lcd_post3(); delay_ms(1); lcd_post3(); delay_ms(1); lcd_post3(); delay_ms(1); lcd_putcmd(0x28); // 8-bit mode 0x28 delay_ms(1); lcd_putcmd(0x8); // Display off 0x8 delay_ms(1); lcd_putcmd(0xC); // Display on, curs.off, no-blink, 0xC delay_ms(1); lcd_putcmd(0x6); // Entry Mode 0x06 delay_ms(1); lcd_putcmd(0x1); // ? delay_ms(1); } static void lcd_busy() { char s = 1; int i; LCD_TRIS |= 0x0F; lcd4_rs = 0; lcd4_rw = 1; for (i=0;i<5;i++) { #asm NOP #endasm /* delay_cycles(10); // 50ns */ lcd4_e = 1; #asm NOP #endasm /*delay_cycles(1); */ s = busy_flag; lcd4_e = 0; #asm NOP #endasm if (s) break; } lcd4_rw = 0; LCD_TRIS &= 0xF0; } void lcd_putcmd(unsigned char c) { lcd_busy(); lcd4_rs = 0; lcd4_rw = 0; LCD_LAT &= 0xF0; LCD_LAT |= c >> 4; lcd4_e = 1; lcd4_e = 0; LCD_LAT &= 0xF0; LCD_LAT |= c; lcd4_e = 1; lcd4_e = 0; } void lcd_clear() { lcd_putcmd(0x01); // Clear Screen pipe_i=0; // Empties the lcd buffer pipe_f=0; } void lcd_putchar(unsigned char c) { lcd_busy(); lcd4_rs = 1; lcd4_rw = 0; LCD_LAT &= 0xF0; LCD_LAT |= c >> 4; lcd4_e = 1; lcd4_e = 0; LCD_LAT &= 0xF0; LCD_LAT |= c; lcd4_e = 1; lcd4_e = 0; }