From: luki Date: Sat, 23 Jan 2010 15:25:47 +0000 (+0100) Subject: example using a hd44780 lcd simulator added. X-Git-Tag: v1.0a7~34^2 X-Git-Url: https://git.htl-mechatronik.at/public/?a=commitdiff_plain;h=74f174c6a1339e88b85a14da3f832e38ddb1d75b;p=sx%2Fsimavr.git example using a hd44780 lcd simulator added. --- diff --git a/examples/board_charlcd/Makefile b/examples/board_charlcd/Makefile new file mode 100644 index 0000000..8da9583 --- /dev/null +++ b/examples/board_charlcd/Makefile @@ -0,0 +1,70 @@ +# +# Copyright 2008, 2009 Michel Pollet +# +# This file is part of simavr. +# +# simavr is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# simavr is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with simavr. If not, see . + +board= charlcd +firm_src = ${wildcard at*${board}.c} +firmware = ${firm_src:.c=.axf} +simavr = ../../ + +SHELL = /bin/bash + +IPATH = . +IPATH += ../parts +IPATH += ${simavr}/include +IPATH += ${simavr}/simavr/sim + +VPATH = . +VPATH += ../parts + +LDFLAGS += -lpthread +LDFLAGS += -lGLU +LDFLAGS += -lGL +LDFLAGS += `sdl-config --libs` +LDFLAGS += -lSDL_image + +CFLAGS = `sdl-config --cflags` +#ifneq (${shell uname}, Darwin) +#else +#LDFLAGS += -framework GLUT -framework OpenGL +#endif +all: obj atmega48_charlcd.axf ${board} + +atmega48_charlcd.axf: atmega48_charlcd.c atmega48_lcd.c atmega48_lcd.h + @echo AVR-CC ${<} + ${AVR}gcc -Wall -gdwarf-2 -Os -std=gnu99 \ + -mmcu=atmega48 \ + -DF_CPU=8000000 \ + -fno-inline-small-functions \ + -ffunction-sections -fdata-sections \ + -Wl,--relax,--gc-sections \ + -Wl,--undefined=_mmcu,--section-start=.mmcu=0x910000 \ + -I../include -I../../include \ + atmega48_charlcd.c atmega48_lcd.c -o atmega48_charlcd.axf + @${AVR}size ${@}|sed '1d' + +include ${simavr}/Makefile.common + +${board} : ${OBJ}/ac_input.o +${board} : ${OBJ}/hd44780.o +${board} : ${OBJ}/hd44780_glut.o +${board} : ${OBJ}/${board}.o + @echo LD $@ + @gcc -MD ${CFLAGS} ${LFLAGS} -o $@ $^ $(LDFLAGS) ${simavr}/simavr/libsimavr.a + +clean: + rm -rf obj *.hex *.a *.axf ${board} *.vcd .*.swo .*.swp .*.swm .*.swn diff --git a/examples/board_charlcd/ac_input.c b/examples/board_charlcd/ac_input.c new file mode 100644 index 0000000..29447f5 --- /dev/null +++ b/examples/board_charlcd/ac_input.c @@ -0,0 +1,18 @@ + +#include "sim_avr.h" +#include "ac_input.h" +#include "stdio.h" + +static avr_cycle_count_t switch_auto( struct avr_t * avr, avr_cycle_count_t when, void * param){ + ac_input_t * b = (ac_input_t *)param; + b->value = b->value == 0 ? 1 : 0; + avr_raise_irq( b->irq + IRQ_AC_OUT, b->value ); + return when + avr_usec_to_cycles(avr,10000); +} + +void ac_input_init(struct avr_t *avr, ac_input_t *b){ + b->irq = avr_alloc_irq(0,IRQ_AC_COUNT); + b->avr = avr; + b->value = 0; + avr_cycle_timer_register_usec(avr, 10000, switch_auto, b); +} diff --git a/examples/board_charlcd/ac_input.h b/examples/board_charlcd/ac_input.h new file mode 100644 index 0000000..07c2c4b --- /dev/null +++ b/examples/board_charlcd/ac_input.h @@ -0,0 +1,23 @@ +#ifndef __AC_INPUT_H__ +#define __AC_INPUT_H__ + +#include "sim_irq.h" + +/* + * Simulates a 50hz changing signal + */ + +enum { + IRQ_AC_OUT = 0, + IRQ_AC_COUNT +}; + +typedef struct ac_input_t { + avr_irq_t * irq; + struct avr_t * avr; + uint8_t value; +} ac_input_t; + +void ac_input_init(struct avr_t * avr, ac_input_t * b); + +#endif diff --git a/examples/board_charlcd/atmega48_charlcd.c b/examples/board_charlcd/atmega48_charlcd.c new file mode 100644 index 0000000..993190a --- /dev/null +++ b/examples/board_charlcd/atmega48_charlcd.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include "stdlib.h" +#include "string.h" + +#include "atmega48_lcd.h" + +#include "avr_mcu_section.h" +AVR_MCU(F_CPU, "atmega48"); + +static uint8_t subsecct = 0; +static uint8_t hour = 0; +static uint8_t minute = 0; +static uint8_t second = 0; +static volatile uint8_t update_needed = 0; + +ISR( INT0_vect ){ + /* External interrupt on pin D2 */ + subsecct++; + if( subsecct == 50 ){ + second++; + update_needed = 1; + if(second ==60){ + minute++; + second = 0; + if(minute==60){ + minute =0; + hour++; + if(hour==24) hour =0; + } + } + } +} + +int main(){ + lcd_init(); + + + EICRA = (1< +#include "atmega48_lcd.h" +#include + +// sendet ein Datenbyte an das LCD + +void lcd_data(unsigned char temp1) +{ + unsigned char temp2 = temp1; + + LCD_PORT |= (1<> 4; + temp1 = temp1 & 0x0F; + LCD_PORT &= 0xF0; + LCD_PORT |= temp1; // setzen + lcd_enable(); + + temp2 = temp2 & 0x0F; + LCD_PORT &= 0xF0; + LCD_PORT |= temp2; // setzen + lcd_enable(); + + _delay_us(42); +} + +// sendet einen Befehl an das LCD + +void lcd_command(unsigned char temp1) +{ + unsigned char temp2 = temp1; + + LCD_PORT &= ~(1<> 4; // oberes Nibble holen + temp1 = temp1 & 0x0F; // maskieren + LCD_PORT &= 0xF0; + LCD_PORT |= temp1; // setzen + lcd_enable(); + + temp2 = temp2 & 0x0F; // unteres Nibble holen und maskieren + LCD_PORT &= 0xF0; + LCD_PORT |= temp2; // setzen + lcd_enable(); + + _delay_us(42); +} + +// erzeugt den Enable-Puls +void lcd_enable(void) +{ + // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers einfügen + // http://www.mikrocontroller.net/topic/81974#685882 + LCD_PORT |= (1< +#include +#include + +#include "sim_avr.h" +#include "avr_ioport.h" +#include "sim_elf.h" +#include "sim_gdb.h" +#include "sim_vcd_file.h" + +#include +#include +#include + +#include "SDL.h" +#include "SDL_image.h" + +#include "ac_input.h" +#include "hd44780.h" +#include "hd44780_glut.h" + +/* screen width, height, and bit depth */ +#define SCREEN_WIDTH 800 +#define SCREEN_HEIGHT 600 +#define SCREEN_BPP 16 + +int window; +avr_t * avr = NULL; +avr_vcd_t vcd_file; +ac_input_t ac_input; +hd44780_t hd44780; + +SDL_Surface *surface; + +static void * avr_run_thread( ){ + while(1){ + avr_run(avr); + } +} + +void Quit( int returnCode ) +{ + SDL_Quit( ); + exit( returnCode ); +} + +int resizeWindow( int width, int height ) +{ + if ( height == 0 ) height = 1; + glViewport( 0, 0, ( GLsizei )width, ( GLsizei )height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity( ); + glOrtho(0, 800, 0, 600, 0, 10); + + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity( ); + + return 1; +} + +void handleKeyPress( SDL_keysym *keysym ) +{ + switch ( keysym->sym ) + { + case SDLK_ESCAPE: + Quit( 0 ); + break; + case SDLK_F1: + SDL_WM_ToggleFullScreen( surface ); + break; + default: + break; + } +} + +int initGL( GLvoid ) +{ + glEnable( GL_TEXTURE_2D ); + glShadeModel( GL_SMOOTH ); + + glClearColor( 0.8f, 0.8f, 0.8f, 1.0f ); + glColor4f( 1.0f,1.0f,1.0f,1.0f); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable( GL_BLEND); + + glClearDepth( 1.0f ); + + glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); + + hd44780_gl_init(); + + return 1; +} + +int drawGLScene( GLvoid ) +{ + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glMatrixMode(GL_MODELVIEW); // Select modelview matrix + glPushMatrix(); + glLoadIdentity(); // Start with an identity matrix + glScalef(3,3,1); + glTranslatef( 89.66f,150,0); + hd44780_gl_draw( &hd44780 ); + glPopMatrix(); + SDL_GL_SwapBuffers(); + return 1; +} + + +int main(int argc, char *argv[]) +{ + elf_firmware_t f; + const char * fname = "atmega48_charlcd.axf"; + char path[256]; + sprintf(path, "%s/%s", dirname(argv[0]), fname); + printf("Firmware pathname is %s\n", path); + elf_read_firmware(path, &f); + + printf("firmware %s f=%d mmcu=%s\n", fname, (int)f.frequency, f.mmcu); + + avr = avr_make_mcu_by_name(f.mmcu); + if (!avr) { + fprintf(stderr, "%s: AVR '%s' now known\n", argv[0], f.mmcu); + exit(1); + } + + avr_init(avr); + avr_load_firmware(avr,&f); + ac_input_init(avr, &ac_input); + avr_connect_irq( + ac_input.irq + IRQ_AC_OUT, + avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('D'),2)); + + hd44780_init(avr, &hd44780); +/* hd44780_print2x16(&hd44780); */ + + /* Connect Data Lines to Port B, 0-3 */ + for( int i =0; i<4;i++){ + avr_irq_register_notify( + avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), i), + hd44780_data_changed_hook, + &hd44780); + } + /* Connect Cmd Lines */ + for( int i =4; i<7;i++){ + avr_irq_register_notify( + avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), i), + hd44780_cmd_changed_hook, + &hd44780); + } + + avr_vcd_init(avr, "gtkwave_output.vcd", &vcd_file, 100 /* usec */); + avr_vcd_add_signal(&vcd_file, + avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('B'), IOPORT_IRQ_PIN_ALL), 8 /* bits */ , + "portb" ); + + avr_vcd_add_signal(&vcd_file, + ac_input.irq + IRQ_AC_OUT, 1, "ac_input"); + + avr_vcd_start(&vcd_file); + + //avr_gdb_init(avr); + //avr->state = cpu_Stopped; + + + avr_vcd_stop(&vcd_file); + + + if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { + fprintf( stderr, "Video initialization failed: %s\n",SDL_GetError( ) ); + Quit( 1 ); + } + int done =0, isActive=1; + SDL_Event event; + int videoFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE | SDL_RESIZABLE | SDL_HWSURFACE | SDL_HWACCEL; + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + surface = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, videoFlags ); + SDL_WM_SetCaption("HD44780 Simulation",""); + if( !surface ) { + fprintf( stderr, "Video mode set failed: %s\n", SDL_GetError( ) ); + Quit( 1 ); + } + initGL( ); + resizeWindow( SCREEN_WIDTH, SCREEN_HEIGHT); + + pthread_t run; + pthread_create(&run, NULL, avr_run_thread, NULL); + + while(!done){ + while ( SDL_PollEvent( &event ) ) + { + switch( event.type ) + { + case SDL_ACTIVEEVENT: + if ( event.active.gain == 0 ) + isActive = 0; + else + isActive = 1; + break; + case SDL_VIDEORESIZE: + /* handle resize event */ + surface = SDL_SetVideoMode( event.resize.w, + event.resize.h, + 16, videoFlags ); + if ( !surface ) + { + fprintf( stderr, "Could not get a surface after resize: %s\n", SDL_GetError( ) ); + Quit( 1 ); + } + resizeWindow( event.resize.w, event.resize.h ); + break; + case SDL_KEYDOWN: + /* handle key presses */ + handleKeyPress( &event.key.keysym ); + break; + case SDL_QUIT: + /* handle quit requests */ + done = 1; + break; + default: + break; + } + } + drawGLScene(); + } + return 0; + +} diff --git a/examples/board_charlcd/data/blu.tiff b/examples/board_charlcd/data/blu.tiff new file mode 100644 index 0000000..0db74e2 Binary files /dev/null and b/examples/board_charlcd/data/blu.tiff differ diff --git a/examples/board_charlcd/data/processblu.py b/examples/board_charlcd/data/processblu.py new file mode 100644 index 0000000..17f89f6 --- /dev/null +++ b/examples/board_charlcd/data/processblu.py @@ -0,0 +1,75 @@ +import Image,struct +img = Image.open('blu.tiff') + +class CharData(object): + def __init__(self, data): + if data is None: + self.data = [ [] for y in range(7) ] + else: + self.data = data + + def concat( self, other ): + for y in range(7): + self.data[y] += other.data[y] + + def get_bindata(self): + ll = len(self.data[0]) + ret='' + for y in reversed(range(7)): + for x in self.data[y]: + ret += struct.pack('BBBB',*x) + return ret + + + def save_as(self, name): + height = 7 + width = len(self.data[0]) + outimg = Image.frombuffer( "RGBA", (width, height), + self.get_bindata()) + outimg.save(name) + + +def char_at(char_x,char_y): + """ + char_x specifies, zero based, the x position of the character + """ + start_x = 1+char_x+ 14*char_x+2 + start_y = 1+char_y*22+1 + print "Starting at %i,%i" %( start_x,start_y) + return CharData([[ img.getpixel( (start_x+2*x,start_y+2*y) ) for x in range(5)] for y in range(7)]) + + +chardata = CharData(None) +for x in range(16): #0x00 - 0x0F + chardata.concat( char_at(0,x) ) +for x in range(16): #0x10 - 0x1F + chardata.concat( char_at(0,x) ) +for x in range(16): #0x20 - 0x2F + chardata.concat( char_at(1,x) ) +for x in range(16): #0x30 - 0x3F + chardata.concat( char_at(2,x) ) +for x in range(16): #0x40 - 0x4F + chardata.concat( char_at(3,x) ) +for x in range(16): #0x50 - 0x5F + chardata.concat( char_at(4,x) ) +for x in range(16): #0x60 - 0x6F + chardata.concat( char_at(5,x) ) +for x in range(16): #0x70 - 0x7F + chardata.concat( char_at(6,x) ) +for x in range(16): #0x80 - 0x8F + chardata.concat( char_at(0,x) ) +for x in range(16): #0x90 - 0x9F + chardata.concat( char_at(0,x) ) +for x in range(16): #0xA0 - 0xAF + chardata.concat( char_at(7,x) ) +for x in range(16): #0xB0 - 0xBF + chardata.concat( char_at(8,x) ) +for x in range(16): #0xC0 - 0xCF + chardata.concat( char_at(9,x) ) +for x in range(16): #0xD0 - 0xDF + chardata.concat( char_at(10,x) ) +for x in range(16): #0xE0 - 0xEF + chardata.concat( char_at(11,x) ) +for x in range(16): #0xF0 - 0xFF + chardata.concat( char_at(12,x) ) +print chardata.save_as('7x5font.tiff') diff --git a/examples/board_charlcd/font.tiff b/examples/board_charlcd/font.tiff new file mode 100644 index 0000000..d5a146e Binary files /dev/null and b/examples/board_charlcd/font.tiff differ diff --git a/examples/board_charlcd/hd44780.c b/examples/board_charlcd/hd44780.c new file mode 100644 index 0000000..46178e8 --- /dev/null +++ b/examples/board_charlcd/hd44780.c @@ -0,0 +1,185 @@ +#include "hd44780.h" +#include +#include +#include +#include + +void debug_print( const char* format, ... ) { + + va_list args; + va_start( args, format ); + #ifdef HD44780_DEBUG + vprintf( format, args ); + #endif + va_end( args ); +} + +int check_flag( hd44780_t *b, int flag){ + return (b->flags>>flag)&1; +} + +void reset_cursor( hd44780_t *b){ + b->cursor = b->ddram; +} + +void clear_screen( hd44780_t *b){ + memset(b->ddram,' ',80); +} + +void handle_function_8bit( hd44780_t *b, int realportstate ){ + debug_print("handle_function_8bit realportstate 0x%x\n",realportstate); + /* + if( realportstate == 0x22){ + debug_print("Activating 4Bit Mode\n"); + b->mode_4bit = 1; + } + */ + if( realportstate == 1) { + clear_screen(b); + debug_print("Clear Screen\n"); + } + if( realportstate >> 1 == 1) { + debug_print("Move Cursor to startpos\n"); + reset_cursor(b); + } + if( realportstate >> 2 == 1) { + debug_print("Setting I/S mode\n"); + b->flags &= ~(3<flags |= (realportstate & 3)<> 3 == 1) { + debug_print("Setting Display/Cursor Mode\n"); + b->flags &= ~(7<flags |= realportstate&7 << HD44780_FLAG_B; // Set B,C,D bits + } + if( realportstate >> 4 == 1) { + debug_print("Moving Display/Cursor Mode\n"); + b->flags &= ~(3<flags |= (realportstate & 3)<> 5 == 1) { + debug_print("Functions\n"); + b->flags &= ~(7<flags |= (realportstate>>2)&7 << HD44780_FLAG_F; // Set F,N,DL bits + if( !check_flag(b, HD44780_FLAG_D_L) ){ + debug_print("Enabling 4Bit Mode\n"); + b->mode_4bit = 1; + } + } + if( realportstate >> 6 == 1) printf("Set CGRAM Address\n"); + if( realportstate >> 7 == 1) { + debug_print("Set DDRAM Address\n"); + b->cursor = b->ddram + (realportstate & 0x7f); + } + debug_print("Flags are 0x%x\n",b->flags); +} + +void handle_data_8bit( hd44780_t *b, int realportstate ){ + /* printf("handle_data_8bit realportstate 0x%x\n",realportstate); */ + *(b->cursor) = realportstate & 0xff; + if( !check_flag(b, HD44780_FLAG_S_C) ){ + // Move Cursor + if( check_flag(b, HD44780_FLAG_I_D) ){ + b->cursor++; + } + else{ + b->cursor--; + } + } + else { + printf("!! NOT IMPLEMENTED\n"); + // Move Display + if( check_flag(b, HD44780_FLAG_R_L) ){ + //Move right + + } + else { + // Move left + } + } + if( b->cursor < b->ddram || b->cursor > b->ddram+80){ + debug_print("Cursor out of range!\n"); + reset_cursor(b); + } + #ifdef HD44780_DEBUG + hd44780_print2x16( b ); + #endif +} + +void hd44780_init( struct avr_t *avr, struct hd44780_t * b) { + b->irq = avr_alloc_irq(0,IRQ_HD44780_COUNT); + b->portstate = 0x00; + b->mode_4bit = 0; + b->four_bit_cache = 0; + b->inits_recv = 0; + b->flags = 0; + reset_cursor(b); + clear_screen(b); +} + +void hd44780_print2x16( struct hd44780_t *b){ + printf("/******************\\\n| "); + fwrite( b->ddram, 1, 16, stdout); + printf(" |\n| "); +// fputc('\n',stdout); + fwrite( b->ddram + 0x40, 1, 16, stdout); + printf(" |\n\\******************/\n"); +} + +void hd44780_data_changed_hook( struct avr_irq_t * irq, uint32_t value, void *param){ + hd44780_t *b = (hd44780_t *)param; + int datapos = -1; + if( irq->irq == DATA_PIN_0) datapos = 0; + if( irq->irq == DATA_PIN_1) datapos = 1; + if( irq->irq == DATA_PIN_2) datapos = 2; + if( irq->irq == DATA_PIN_3) datapos = 3; + if( irq->irq == DATA_PIN_4) datapos = 4; + if( irq->irq == DATA_PIN_5) datapos = 5; + if( irq->irq == DATA_PIN_6) datapos = 6; + if( irq->irq == DATA_PIN_7) datapos = 7; + if( datapos >= 0){ + if( value == 1) b->portstate |= 1<portstate &= ~(1<irq == RS_PIN){ + b->rs=value; + } + if( irq->irq == RW_PIN){ + b->rw=value; + } + if( irq->irq == ENABLE_PIN && value == 0){ + debug_print("enable pulse! portstate 0x%x\n", b->portstate); + if( b->inits_recv < 3 ){ + if( b->portstate == 0x30 ){ + debug_print("Init received\n"); + b->inits_recv++; + } + else debug_print("Uuups, received command before fully initialized?\n"); + } + else { + int realportstate=0; + int received = 1; + if( b->mode_4bit == 1) b->four_bit_cache = b->portstate, b->mode_4bit++,received=0; + else if( b->mode_4bit == 2) { + realportstate = (b->four_bit_cache&0xf0) | (b->portstate&0xf0)>>4; + b->mode_4bit=1; + } + else realportstate = b->portstate; + debug_print("four bit cache is 0x%x\n",b->four_bit_cache); + + if(received){ + if( !b->rs ) handle_function_8bit( b, realportstate ); + else handle_data_8bit( b, realportstate ); + } + } + } +// printf("pin %i is now %i, portstate 0x%x\n", irq->irq, value, b->portstate); +} + + + diff --git a/examples/board_charlcd/hd44780.h b/examples/board_charlcd/hd44780.h new file mode 100644 index 0000000..4b4ce12 --- /dev/null +++ b/examples/board_charlcd/hd44780.h @@ -0,0 +1,69 @@ +#ifndef __HD44780_H__ +#define __HD44780_H__ + +#include "sim_irq.h" + +/****************** + * Simulates a HD44780 controlled character LED. + * All the Data Pins have to be on the same Port. + * All the Cmd Pins have to be on the same Port. In 4 Bit mode, + * they can share one Port. + * For output of the display contents, use hd44780_print2x16 or a opengl function. + ******************/ + +#define ENABLE_PIN 5 +#define RW_PIN 6 +#define RS_PIN 4 +/* Use -1 for not connected */ +#define DATA_PIN_0 -1 +#define DATA_PIN_1 -1 +#define DATA_PIN_2 -1 +#define DATA_PIN_3 -1 +#define DATA_PIN_4 0 +#define DATA_PIN_5 1 +#define DATA_PIN_6 2 +#define DATA_PIN_7 3 + +/* #define HD44780_DEBUG */ + +enum { + HD44780_FLAG_F = 0, //5x7 Font, 5x10 Font + HD44780_FLAG_N, //1-zeiliges Display, 2/4-zeiliges Display + HD44780_FLAG_D_L, //4-Bit Interface, 8-Bit Interface + HD44780_FLAG_R_L, // Nach links schieben,Nach rechts schieben + HD44780_FLAG_S_C, //Cursor bewegen, Displayinhalt schieben + HD44780_FLAG_B, //Cursor blinkt nicht, Cursor blinkt + HD44780_FLAG_C, //Cursor aus,Cursor an + HD44780_FLAG_D, //Display aus,Display an + HD44780_FLAG_S, //Displayinhalt fest, Displayinhalt weiterschieben + HD44780_FLAG_I_D +}; + +enum { + IRQ_HD44780_IN = 0, + IRQ_HD44780_COUNT +}; + + +typedef struct hd44780_t { + avr_irq_t * irq; + struct avr_t * avr; + char *cursor; + char ddram[80]; + char cgram[64]; + uint32_t rw; /* R/W pin */ + uint32_t rs; /* RS pin */ + int portstate; + char mode_4bit; /* 0=disabled, 1=waitingforfirstnibble, 2=waitingforsecondnibble */ + uint32_t flags; + int four_bit_cache; + char inits_recv; /* num of init sequences received */ +} hd44780_t; + +void hd44780_init( struct avr_t *avr, struct hd44780_t * b); +void hd44780_print2x16( struct hd44780_t *b); + +void hd44780_data_changed_hook( struct avr_irq_t * irq, uint32_t value, void *param); +void hd44780_cmd_changed_hook( struct avr_irq_t * irq, uint32_t value, void *param); + +#endif diff --git a/examples/board_charlcd/hd44780_glut.c b/examples/board_charlcd/hd44780_glut.c new file mode 100644 index 0000000..4f9dee8 --- /dev/null +++ b/examples/board_charlcd/hd44780_glut.c @@ -0,0 +1,94 @@ +#include "hd44780_glut.h" + +#include "SDL.h" +#include "SDL_image.h" +#include +#include + +static GLuint font_texture; +static int charwidth = 5; +static int charheight = 7; + +void hd44780_gl_init(){ + SDL_Surface *image; + image = IMG_Load("font.tiff"); + if( !image) { + printf("Problem loading texture\n"); + return; + } + glGenTextures(1,&font_texture); + glBindTexture(GL_TEXTURE_2D, font_texture); +/* printf("imagew %i, imageh %i, bytesperpixel %i\n", image->w, image->h, image->format->BytesPerPixel); */ + glTexImage2D( GL_TEXTURE_2D, 0, 4, image->w, image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef( 1.0f/(GLfloat)image->w, 1.0f/(GLfloat)image->h,1.0f); + + SDL_FreeSurface(image); + glMatrixMode(GL_MODELVIEW); +} + +void glputchar(char c){ + int index = c; + int left = index * charwidth; + int right = index*charwidth+charwidth; + int top = 0; + int bottom =7; + + glDisable(GL_TEXTURE_2D); + glColor3f( 0.0f, 1.0f, 0.0f); + glBegin( GL_QUADS); + glVertex3i( 5, 7, 0 ); + glVertex3i( 0, 7, 0 ); + glVertex3i( 0, 0, 0 ); + glVertex3i( 5, 0, 0 ); + glEnd( ); + + glEnable(GL_TEXTURE_2D); + glColor3f( 1.0f, 1.0f, 1.0f); + glBindTexture(GL_TEXTURE_2D, font_texture); + glBegin( GL_QUADS); + glTexCoord2i(right,top); glVertex3i( 5, 7, 0 ); + glTexCoord2i(left, top); glVertex3i( 0, 7, 0 ); + glTexCoord2i(left, bottom); glVertex3i( 0, 0, 0 ); + glTexCoord2i(right,bottom); glVertex3i( 5, 0, 0 ); + glEnd( ); + +} + +void glputstr( char *str){ + while( *(++str) != 0 ){ + glputchar(*str); + glTranslatef(6,0,0); + } +} + +void hd44780_gl_draw( hd44780_t *b){ + int rows = 16; + int lines = 2; + int border = 3; + glDisable(GL_TEXTURE_2D); + glColor3f(0.0f,0.4f,0.0f); + glTranslatef(0,-8,0); + glBegin(GL_QUADS); + glVertex3f( rows*charwidth + (rows-1) + border, -border,0); + glVertex3f( - border, -border,0); + glVertex3f( - border, lines*charheight + (lines-1)+border,0); + glVertex3f( rows*charwidth + (rows-1) + border, lines*charheight + (lines-1)+border,0); + glEnd(); + glTranslatef(0,8,0); + glColor3f(1.0f,1.0f,1.0f); + for( int i=0; i<16; i++) { + glputchar( b->ddram[i] ); + glTranslatef(6,0,0); + } + glTranslatef(-96,-8,0); + for( int i=0; i<16; i++) { + glputchar( b->ddram[i+0x40] ); + glTranslatef(6,0,0); + } + +} diff --git a/examples/board_charlcd/hd44780_glut.h b/examples/board_charlcd/hd44780_glut.h new file mode 100644 index 0000000..53d9403 --- /dev/null +++ b/examples/board_charlcd/hd44780_glut.h @@ -0,0 +1,10 @@ +#ifndef __HD44780_GLUT_H__ +#define __HD44780_GLUT_H__ + +#include "hd44780.h" + +void hd44780_gl_draw( hd44780_t *b); + +void hd44780_gl_init(); + +#endif