/* lcd.c provide support for graphic display */ #include "defs.h" #define STK_CTRL ((volatile unsigned int *)(0xE000E010)) #define STK_LOAD ((volatile unsigned int *)(0xE000E014)) #define STK_VAL ((volatile unsigned int *)(0xE000E018)) /* FRÅN LAB 2.2 */ void delay_250ns( void ) { /* SystemCoreClock = 168000000 */ *STK_CTRL = 0; *STK_LOAD = ( (168/4) -1 ); *STK_VAL = 0; *STK_CTRL = 5; while( (*STK_CTRL & 0x10000 )== 0 ); *STK_CTRL = 0; } void delay_micro(unsigned int us) { while( us > 0 ) { delay_250ns(); delay_250ns(); delay_250ns(); delay_250ns(); us--; } } void delay_milli(unsigned int ms) { while( ms > 0 ) { delay_micro( 1000 ); ms--; } } void delay_500ns( void ) { delay_250ns(); delay_250ns(); } /* ----------------------------------------------------------------- */ #define GPIO_E_BASE 0x40021000 /* MD407 port E */ #define GPIO_E_MODER ((volatile unsigned int *) (GPIO_E_BASE)) #define GPIO_E_OTYPER ((volatile unsigned short *)(GPIO_E_BASE+0x4)) #define GPIO_E_OSPEEDR ((volatile unsigned int *) (GPIO_E_BASE+0x8)) #define GPIO_E_PUPDR ((volatile unsigned int *) (GPIO_E_BASE+0xC)) /* Byte address definitions */ #define GPIO_E_IDRHIGH ((volatile unsigned char *) (GPIO_E_BASE+0x10+1)) #define GPIO_E_ODRLOW ((volatile unsigned char *) (GPIO_E_BASE+0x14)) #define GPIO_E_ODRHIGH ((volatile unsigned char *) (GPIO_E_BASE+0x14+1)) /* ----------------------------------------------------------------- */ /* Register bit definitions */ #define B_E 0x40 #define B_RST 0x20 #define B_CS2 0x10 #define B_CS1 8 #define B_SELECT 4 #define B_RW 2 #define B_DI 1 #define B_RS 1 #define LCD_ON 0x3F #define LCD_OFF 0x3E #define LCD_SET_ADD 0x40 #define LCD_SET_PAGE 0xB8 #define LCD_DISP_START 0xC0 #define LCD_BUSY 0x80 /* ----------------------------------------------------------------- */ /* Graphic display */ static void graphic_ctrl_bit_set( unsigned char x ) { *GPIO_E_ODRLOW |= ( ~B_SELECT & x ); } static void graphic_ctrl_bit_clear( unsigned char x ) { *GPIO_E_ODRLOW &= ( ~B_SELECT & ~x ); } static void select_controller(unsigned char controller) { switch(controller){ case 0: graphic_ctrl_bit_clear(B_CS1|B_CS2); break; case B_CS1 : graphic_ctrl_bit_set(B_CS1); graphic_ctrl_bit_clear(B_CS2); break; case B_CS2 : graphic_ctrl_bit_set(B_CS2); graphic_ctrl_bit_clear(B_CS1); break; case B_CS1|B_CS2 : graphic_ctrl_bit_set(B_CS1|B_CS2); break; } } static void graphic_wait_ready(void) { unsigned char c; graphic_ctrl_bit_clear( B_E ); *GPIO_E_MODER = 0x00005555; /* b15-8 are inputs, 7-0 are outputs */ graphic_ctrl_bit_clear( B_DI ); graphic_ctrl_bit_set( B_RW ); delay_500ns(); while( 1 ) { graphic_ctrl_bit_set( B_E ); delay_500ns(); c = *GPIO_E_IDRHIGH & 0x80; graphic_ctrl_bit_clear( B_E ); delay_500ns(); if( c == 0 )break; } *GPIO_E_MODER = 0x55555555; /* all bits outputs */ } static unsigned char display_read(unsigned char controller) { unsigned char c; *GPIO_E_MODER = 0x00005555; /* b15-8 are inputs, 7-0 are outputs */ select_controller( controller ); graphic_ctrl_bit_clear( B_E ); graphic_ctrl_bit_set( B_DI | B_RW ); delay_500ns(); graphic_ctrl_bit_set( B_E ); delay_500ns(); c = *GPIO_E_IDRHIGH; graphic_ctrl_bit_clear( B_E ); *GPIO_E_MODER = 0x55555555; /* all bits outputs */ if( controller & B_CS1 ) { select_controller( B_CS1); graphic_wait_ready(); } if( controller & B_CS2 ) { select_controller( B_CS2); graphic_wait_ready(); } return c; } static void graphic_write(unsigned char val, unsigned char controller) { *GPIO_E_ODRHIGH = val; select_controller( controller ); delay_500ns(); graphic_ctrl_bit_set( B_E ); delay_500ns(); graphic_ctrl_bit_clear( B_E ); if( controller & B_CS1 ) { select_controller( B_CS1); graphic_wait_ready(); } if( controller & B_CS2 ) { select_controller( B_CS2); graphic_wait_ready(); } *GPIO_E_ODRHIGH = 0; graphic_ctrl_bit_set( B_E ); select_controller( 0 ); } static unsigned char graphic_read(unsigned char controller) { display_read(controller); return display_read(controller); } static void graphic_writeCommand(unsigned char commandToWrite, unsigned char controller) { graphic_ctrl_bit_clear( B_E ); graphic_ctrl_bit_clear( B_DI | B_RW ); graphic_write(commandToWrite, controller); } static void graphic_writeData(unsigned char data, unsigned char controller) { graphic_ctrl_bit_clear( B_E ); graphic_ctrl_bit_set( B_DI ); graphic_ctrl_bit_clear( B_RW ); graphic_write(data, controller); } static void pixel( int x, int y, int set ) { unsigned char mask,c, controller; int index; if( (x > 128 ) || (y > 64) ) return; mask = 0; index = (y-1)/8; switch( (y-1)%8 ) { case 0: mask = 1; break; case 1: mask = 2; break; case 2: mask = 4; break; case 3: mask = 8; break; case 4: mask = 0x10; break; case 5: mask = 0x20; break; case 6: mask = 0x40; break; case 7: mask = 0x80; break; } if( set == 0) mask = ~mask; if(x > 64){ controller = B_CS2; x = x - 65; }else{ controller = B_CS1; x = x-1; } graphic_writeCommand(LCD_SET_ADD | x, controller ); graphic_writeCommand(LCD_SET_PAGE | index, controller ); c = graphic_read( controller ); graphic_writeCommand(LCD_SET_ADD | x, controller ); if( set ) mask = mask | c; else mask = mask & c; graphic_writeData( mask, controller); } void graphic_initalize(void) { /* PORT E */ *GPIO_E_MODER = 0x55555555; /* all bits outputs */ *GPIO_E_OTYPER = 0x00000000; /* outputs are push/pull */ *GPIO_E_OSPEEDR = 0x55555555; /* medium speed */ *GPIO_E_PUPDR = 0x55550000; /* inputs are pull up */ *GPIO_E_ODRHIGH = 0; graphic_ctrl_bit_set( B_E ); delay_micro(10); graphic_ctrl_bit_clear(B_CS1|B_CS2|B_RST|B_E); delay_milli( 30 ); graphic_ctrl_bit_set(B_RST); delay_milli( 100 ); graphic_writeCommand(LCD_OFF, B_CS1|B_CS2); graphic_writeCommand(LCD_ON, B_CS1|B_CS2); graphic_writeCommand(LCD_DISP_START, B_CS1|B_CS2); graphic_writeCommand(LCD_SET_ADD, B_CS1|B_CS2); graphic_writeCommand(LCD_SET_PAGE, B_CS1|B_CS2); select_controller(0); } void graphic_clearScreen(void) { unsigned char i, j; for(j = 0; j < 8; j++) { graphic_writeCommand(LCD_SET_PAGE | j, B_CS1|B_CS2 ); graphic_writeCommand(LCD_SET_ADD | 0, B_CS1|B_CS2 ); for(i = 0; i <= 63; i++){ graphic_writeData(0, B_CS1|B_CS2); } } } void pixelset( int x, int y) { pixel( x, y, 1 ); } void pixelclear( int x, int y) { pixel( x, y, 0 ); }