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

Reply via email to