From 74f174c6a1339e88b85a14da3f832e38ddb1d75b Mon Sep 17 00:00:00 2001 From: luki Date: Sat, 23 Jan 2010 16:25:47 +0100 Subject: [PATCH] example using a hd44780 lcd simulator added. --- examples/board_charlcd/Makefile | 70 +++++++ examples/board_charlcd/ac_input.c | 18 ++ examples/board_charlcd/ac_input.h | 23 +++ examples/board_charlcd/atmega48_charlcd.c | 62 ++++++ examples/board_charlcd/atmega48_lcd.c | 146 ++++++++++++++ examples/board_charlcd/atmega48_lcd.h | 33 ++++ examples/board_charlcd/charlcd.c | 228 ++++++++++++++++++++++ examples/board_charlcd/data/blu.tiff | Bin 0 -> 277114 bytes examples/board_charlcd/data/processblu.py | 75 +++++++ examples/board_charlcd/font.tiff | Bin 0 -> 35982 bytes examples/board_charlcd/hd44780.c | 185 ++++++++++++++++++ examples/board_charlcd/hd44780.h | 69 +++++++ examples/board_charlcd/hd44780_glut.c | 94 +++++++++ examples/board_charlcd/hd44780_glut.h | 10 + 14 files changed, 1013 insertions(+) create mode 100644 examples/board_charlcd/Makefile create mode 100644 examples/board_charlcd/ac_input.c create mode 100644 examples/board_charlcd/ac_input.h create mode 100644 examples/board_charlcd/atmega48_charlcd.c create mode 100644 examples/board_charlcd/atmega48_lcd.c create mode 100644 examples/board_charlcd/atmega48_lcd.h create mode 100644 examples/board_charlcd/charlcd.c create mode 100644 examples/board_charlcd/data/blu.tiff create mode 100644 examples/board_charlcd/data/processblu.py create mode 100644 examples/board_charlcd/font.tiff create mode 100644 examples/board_charlcd/hd44780.c create mode 100644 examples/board_charlcd/hd44780.h create mode 100644 examples/board_charlcd/hd44780_glut.c create mode 100644 examples/board_charlcd/hd44780_glut.h 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 0000000000000000000000000000000000000000..0db74e2cb4943743522039860592cde9440db782 GIT binary patch literal 277114 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d5a146e3214eb5c27e1f6b2208ba32d5b20580ae GIT binary patch literal 35982 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 M-aR|R9Q~W;|A7z7IsgCw literal 0 HcmV?d00001 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 -- 2.39.5