On Mon, 2009-05-04 at 16:48 -0600, Weddington, Eric wrote: Sorry about the reply, I just hit reply, did not check the address...
I know about the case sensitivity of options, I did a typo in a make file. I normally use -Os, changed to -O3 (-o3) while playing with this. Source code attached.
/* * 4x40-lcd.c - interface witht the L4044 LCD module * * The L4044 LCD is connected via an 18-pin connector. * * LCD * STK500 Pin Signal Signal * Port No. Name Function * ---- --- ---- ------------- * PA7 1 DB7 Data bus line * PA6 2 DB6 Data bus line * PA5 3 DB5 Data bus line * PA4 4 DB4 Data bus line * PA3 5 DB3 Data bus line * PA2 6 DB2 Data bus line * PA1 7 DB1 Data bus line * PA0 8 DB0 Data bus line * PC0 9 E1 Enable * PC3 10 R/W L: Data write from MPU to LCM. H: Data read from LCM * PC2 11 RS L: Instruction code input. H: Data input * 12 VLC Liquid crystal driving voltage * 13 VSS GND * 14 VDD Power supply voltage + 5 V * PC1 15 E2 Enable (for lower 2 lines)make AVR_TYPE=m128 program * 16 NC * 17 VA* Anodemake AVR_TYPE=m128 program * 18 VC* Cathode * * $Id$ */ #include <avr/io.h> /* Ports, etc. */ #include <stdint.h> /* uint8_t, etc. */ #include <avr/interrupt.h> /* sei */ #include <avr/sleep.h> /* sleep_mode() */ /* * measure width of E1 and E2 - define MEASURE_E 1 */ #define MEASURE_E 1 /* * Ports and Direction Registers */ #define LCD_CTRL PORTD #define LCD_CTRL_DDR DDRD #define LCD_DATA PORTC #define LCD_DATA_DDR DDRC #define LCD_DATA_PIN PINC #warning "Trace Port is Port A" #define TRACE_PORT PORTA #define TRACE_PORT_DDR DDRA #define TRACE_ON(n) (TRACE_PORT |= _BV((n))) #define TRACE_OFF(n) (TRACE_PORT &= ~_BV((n))) /* * Direction Control Bits */ #define ALL_OUT 0xff #define ALL_IN 0x0 /* * Control Port Bits */ #define RW_BIT 5 #define RS_BIT 4 #define E2_BIT 7 #define E1_BIT 6 #define CTRL_BITS (_BV(RW_BIT) | _BV(RS_BIT) | _BV(E2_BIT) | _BV(E1_BIT)) /* * Partial Cycles - Bit Set and Clear */ #define COMMAND LCD_CTRL &= ~(_BV(RS_BIT)) #define DATA LCD_CTRL |= (_BV(RS_BIT)) #define READ LCD_DATA_DDR=ALL_IN; LCD_CTRL |= (_BV(RW_BIT)) #define WRITE LCD_DATA_DDR=ALL_OUT; LCD_CTRL &= ~(_BV(RW_BIT)) #define E1_UP LCD_CTRL |= (_BV(E1_BIT)) #define E1_DOWN LCD_CTRL &= ~(_BV(E1_BIT)) #define E2_UP LCD_CTRL |= (_BV(E2_BIT)) #define E2_DOWN LCD_CTRL &= ~(_BV(E2_BIT)) #define E1_E2_UP LCD_CTRL |= ((_BV(E1_BIT))|(_BV(E2_BIT))) #define E1_E2_DOWN LCD_CTRL &= ~((_BV(E1_BIT))|(_BV(E2_BIT))) #define CYCLE_E1 E1_UP; E1_DOWN #define CYCLE_E2 E2_UP; E2_DOWN #define CYCLE_E1_E2 LCD_CTRL |= ((_BV(E1_BIT))|(_BV(E2_BIT))); \ LCD_CTRL &= ~((_BV(E1_BIT))|(_BV(E2_BIT))); /* * =============================================================== */ /* * Complete Cycles */ #define STRETCH_E asm("nop"); asm("nop"); asm("nop"); asm("nop"); #define E1_DATA_READ_CYCLE(d) \ DATA;\ READ;\ E1_UP;\ STRETCH_E;\ (d)=LCD_DATA;\ STRETCH_E;\ E1_DOWN; #define E1_DATA_WRITE_CYCLE(d) \ DATA;\ WRITE;\ E1_UP;\ STRETCH_E;\ LCD_DATA=d;\ STRETCH_E;\ E1_DOWN; /* need almost 1 usec betweek E up and data valid */ #define E1_COMMAND_READ_CYCLE(d) \ COMMAND;\ READ;\ E1_UP;\ STRETCH_E;\ STRETCH_E;\ STRETCH_E;\ d=LCD_DATA_PIN;\ STRETCH_E;\ E1_DOWN; #define E1_COMMAND_WRITE_CYCLE(d) \ COMMAND;\ WRITE;\ E1_UP;\ STRETCH_E;\ LCD_DATA=d;\ STRETCH_E;\ E1_DOWN; #define E2_DATA_READ_CYCLE(d) \ DATA;\ READ;\ E2_UP;\ STRETCH_E;\ d=LCD_DATA;\ STRETCH_E;\ E2_DOWN; #define E2_DATA_WRITE_CYCLE(d) \ DATA;\ WRITE;\ E2_UP;\ STRETCH_E;\ LCD_DATA=d;\ STRETCH_E;\ E2_DOWN; /* need almost 1 usec betweek E up and data valid */ #define E2_COMMAND_READ_CYCLE(d) \ COMMAND;\ READ;\ E2_UP;\ STRETCH_E;\ STRETCH_E;\ STRETCH_E;\ d=LCD_DATA_PIN;\ STRETCH_E;\ E2_DOWN; #define E2_COMMAND_WRITE_CYCLE(d) \ COMMAND;\ WRITE;\ E2_UP;\ STRETCH_E;\ LCD_DATA=d;\ STRETCH_E;\ E2_DOWN; #define E1_E2_COMMAND_WRITE_CYCLE(d) \ COMMAND;\ WRITE;\ E1_E2_UP;\ STRETCH_E;\ LCD_DATA=d;\ STRETCH_E;\ E1_E2_DOWN; void e1_command_write(uint8_t); void e1_command_write(uint8_t d) { COMMAND; WRITE; E1_UP; STRETCH_E; LCD_DATA=d; STRETCH_E; E1_DOWN; } void e2_command_write(uint8_t); void e2_command_write(uint8_t d) { COMMAND; WRITE; E2_UP; STRETCH_E; LCD_DATA=d; STRETCH_E; E2_DOWN; } void e1_e2_command_write(uint8_t); void e1_e2_command_write(uint8_t d) { COMMAND; WRITE; E1_E2_UP; STRETCH_E; LCD_DATA=d; STRETCH_E; E1_E2_DOWN; } #define DELAY_4_1_msec start_tcnt0_4_1_msec() #define DELAY_100_usec start_tcnt0_100_usec() #define DELAY_37_usec start_tcnt0_37_usec() #define E1_CMND_WRITE_DELAY(d,f) \ e1_command_write(d);\ f;\ sleep_mode(); /* wait for interrupt */ #define E2_CMND_WRITE_DELAY(d,f) \ e2_command_write(d);\ f;\ sleep_mode(); /* wait for interrupt */ #define E1_E2_CMND_WRITE_DELAY(d,f) \ e1_e2_command_write(d);\ f;\ sleep_mode(); /* wait for interrupt */ #define E1_E2_COMMAND_READ_CYCLE(d) \ COMMAND;\ READ;\ E1_E2_UP;\ STRETCH_E;\ d=LCD_DATA;\ STRETCH_E;\ E1_E2_DOWN; ISR(SIG_OVERFLOW0) { TIMSK &= ~_BV(TOIE0); } ISR(SIG_OUTPUT_COMPARE0) { TRACE_ON(1); TIMSK &= ~_BV(OCIE0); TRACE_OFF(1); } /* * =============================================================== * Values tuned for ATmega8515 * * time of OCR0 is * time = counts * prescale/F_CPU * or * counts = time*F_CPU/prescale * * 37 usec uses f_cpu/8 * 100 usec uses f_cpu/8 * 4.1 msec uses f_cpu/1024 */ #define F_CPU 16000000.0 #define OCR0_37_USEC_CNT (uint8_t)( 37.0/(1000000.0*8.0/F_CPU))+1 #define OCR0_100_USEC_CNT (uint8_t)(100.0/(1000000.0*8.0/F_CPU))+1 #define OCR0_4_1_MSEC_CNT (uint8_t)( 41.0/(10000.0*1024.0/F_CPU))+1 void start_tcnt0_4_1_msec(void); void start_tcnt0_4_1_msec() { TIMSK = _BV(OCIE0); OCR0 = OCR0_4_1_MSEC_CNT; TCCR0 = _BV(CS02) | _BV(CS01) | _BV(CS00) | _BV(WGM01); TCNT0 = 0; } void start_tcnt0_100_usec(void); void start_tcnt0_100_usec() { TIMSK = _BV(OCIE0); OCR0 = OCR0_100_USEC_CNT; TCCR0 = _BV(CS01) | _BV(WGM01); TCNT0 = 0; } void start_tcnt0_37_usec(void); void start_tcnt0_37_usec() { TIMSK = _BV(OCIE0); OCR0 = OCR0_37_USEC_CNT; TCCR0 = _BV(CS01) | _BV(WGM01); TCNT0 = 0; } #define CLEAR_DISPLAY _BV(0) #define RETURN_HOME _BV(1) #define ENTRY_MODE _BV(2) #define ID_INCR _BV(1) #define ID_DECR 0 #define DISPLAY _BV(3) #define DISPLAY_ON _BV(2) #define DISPLAY_OFF 0 #define CURSOR_ON _BV(1) #define CURSOR_OFF 0 #define BLINK _BV(0) #define SHIFT _BV(4) #define DISP_SHIFT _BV(3) #define CURSOR_MOVE 0 #define SHIFT_RIGHT _BV(2) #define SHIFT_LEFT 0 #define FUNCTION _BV(5) #define IF_8_BITS _BV(4) #define IF_4_BITS 0 #define TWO_LINE _BV(3) #define ONE_LINE 0 #define FONT_5x10 _BV(2) #define FONT_5x8 0 #define SET_CGADDR _BV(6) #define SET_DDADDR _BV(7) void wait_e1_busy(void); void wait_e2_busy(void); void lcd_init(void); void lcd_init() { TRACE_ON(2); E1_E2_CMND_WRITE_DELAY(0x38, DELAY_4_1_msec); E1_E2_CMND_WRITE_DELAY(0x38, DELAY_4_1_msec); E1_E2_CMND_WRITE_DELAY(0x38, DELAY_4_1_msec); e1_e2_command_write(0x38); wait_e1_busy(); wait_e2_busy(); e1_e2_command_write(0x08); wait_e1_busy(); wait_e2_busy(); e1_e2_command_write(0x01); wait_e1_busy(); wait_e2_busy(); e1_e2_command_write(0x06); wait_e1_busy(); wait_e2_busy(); //e1_e2_command_write(0x0F); e1_e2_command_write(0x0C); wait_e1_busy(); wait_e2_busy(); TRACE_OFF(2); } #define BUSY_FLAG 0x80 void wait_e1_busy() { uint8_t d; do { E1_COMMAND_READ_CYCLE(d); } while (d&0x80); return; } void wait_e2_busy() { uint8_t d; do { E2_COMMAND_READ_CYCLE(d); } while (d&0x80); return; } void lcd_write_row1(uint8_t *); void lcd_write_row1(uint8_t *c) { e1_command_write(0x80); wait_e1_busy(); while (*c) { E1_DATA_WRITE_CYCLE(*c++); wait_e1_busy(); } } void lcd_write_row2(uint8_t *); void lcd_write_row2(uint8_t *c) { e1_command_write(0xC0); wait_e1_busy(); while (*c) { E1_DATA_WRITE_CYCLE(*c++); wait_e1_busy(); } } void lcd_write_row3(uint8_t *); void lcd_write_row3(uint8_t *c) { e2_command_write(0x80); wait_e2_busy(); while (*c) { E2_DATA_WRITE_CYCLE(*c++); wait_e2_busy(); } } void lcd_write_row4(uint8_t *); void lcd_write_row4(uint8_t *c) { e2_command_write(0xC0); wait_e2_busy(); while (*c) { E2_DATA_WRITE_CYCLE(*c++); wait_e2_busy(); } } void jtag_off(void); int main() { /* * DISABLE THE JTAG INTERFACE SO CAN USE PORTC[5:2] */ //jtag_off(); // 0123456789112345678921234567893123456789 char *row1 = "L xx LF xx RF xx R xx Ping xxx SRF xxx"; char *row2 = "LPWM xx LFLT x LDIR x LCUR xx "; char *row3 = "RPWM xx RFLT x RDIR x RCUR XX "; char *row4 = "HDG xxx SPD xxx TBRG xxx TDST xxx ARB xx"; /* * set os calibration byte */ OSCCAL=0xa8; TRACE_PORT_DDR=ALL_OUT; TRACE_PORT = 0; /* * lcd data port output */ LCD_DATA_DDR=ALL_OUT; LCD_DATA=0; /* * lcd ctrl port output */ LCD_CTRL_DDR |= CTRL_BITS; // R/W=1, RS=0, E2=0, E1=0 LCD_CTRL = (LCD_CTRL & ~CTRL_BITS) | _BV(RW_BIT); TCCR0 = 0; /* stop timers */ sei(); /* enable interrupts */ set_sleep_mode(SLEEP_MODE_IDLE); //while(1) { // TRACE_PORT ^= _BV(3); // E1_E2_CMND_WRITE_DELAY(0x38, DELAY_4_1_msec); //} lcd_init(); while (1) { TRACE_PORT ^= _BV(0); lcd_write_row1((uint8_t *)row1); lcd_write_row2((uint8_t *)row2); lcd_write_row3((uint8_t *)row3); lcd_write_row4((uint8_t *)row4); //TRACE_OFF(0); } return 0; }
;; control the jtag interface ;; The JTD bit in the MCUCSR register is set to disable the jtag ;; interface. The JTD bit in the MCUCSR register is cleared to enable the ;; jtag interface. To change the JTD bit, the register must be written ;; two times in 4 cycles ;; ;; 20090315 tomdean - initial version ;; ;; $Id$ #include <avr/io.h> .file "jtag_ctl.S" .text .global jtag_on .type jtag_on, @function ;; ;; This only changes the Z and R24 registers. ;; Both protected by avr-gcc for function calls. ;; jtag_on: ldi r30,lo8(MCUCSR) ldi r31,hi8(MCUCSR) ld r24,Z andi r24,~_BV(JTD) ;; ;; CAUTION, do not put instructions between the next two ;; st X,r24 ; write the bit the first time st X,r24 ; write the bit the second time ret .size jtag_on, .-jtag_on .global jtag_off .type jtag_off, @function jtag_off: ldi r30,lo8(MCUCSR) ldi r31,hi8(MCUCSR) ld r24,Z ori r24,_BV(JTD) ;; ;; CAUTION, do not put instructions between the next two ;; st X,r24 ; write the bit the first time st X,r24 ; write the bit the second time ret .size jtag_off, .-jtag_off
_______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list