Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * startup.c
- *
- */
- #import "delay.h"
- #define GPIO_E 0x40021000
- #define GPIO_E_MODER ((volatile unsigned int *) GPIO_E)
- #define GPIO_E_OTYPER ((volatile unsigned short *) GPIO_E + 0x4)
- #define GPIO_E_OSPEEDR ((volatile unsigned int *) GPIO_E + 0x8)
- #define GPIO_E_PUPDR ((volatile unsigned int *) GPIO_E + 0xC)
- #define GPIO_E_IDR_LOW ((volatile unsigned char*) GPIO_E + 0x10)
- #define GPIO_E_IDR_HIGH ((volatile unsigned char*) GPIO_E + 0x11)
- #define GPIO_E_ODR_LOW ((volatile unsigned char*) GPIO_E + 0x14)
- #define GPIO_E_ODR_HIGH ((volatile unsigned char*) GPIO_E + 0x15)
- #define B_E 0b01000000
- #define B_SELECT 0b00000100
- #define B_RW 0b00000010
- #define B_RS 0b00000001
- void startup(void) __attribute__((naked)) __attribute__((section (".start_section")) );
- void startup ( void )
- {
- __asm volatile(
- " LDR R0,=0x2001C000\n" /* set stack */
- " MOV SP,R0\n"
- " BL main\n" /* call main */
- "_exit: B .\n" /* never return */
- ) ;
- }
- void ascii_ctrl_bit_set( unsigned char x )
- {
- *GPIO_E_ODR_LOW |= (B_SELECT | x) ;
- }
- void ascii_ctrl_bit_clear( unsigned char x )
- {
- *GPIO_E_ODR_LOW &= ( B_SELECT | ~x );
- }
- unsigned char ascii_read_controller( void )
- {
- ascii_ctrl_bit_set( B_E );
- delay_250ns();
- delay_250ns();
- unsigned char rv = *GPIO_E_IDR_HIGH;
- ascii_ctrl_bit_clear( B_E );
- return rv;
- }
- void ascii_write_controller( unsigned char byte )
- {
- ascii_ctrl_bit_set( B_E );
- *GPIO_E_ODR_HIGH = byte;
- delay_250ns();
- ascii_ctrl_bit_clear( B_E );
- }
- void ascii_write_cmd( unsigned char command )
- {
- ascii_ctrl_bit_clear( B_RS ); //ascii_ctrl_bit_clear( B_RS | B_RW );
- ascii_ctrl_bit_clear( B_RW );
- ascii_write_controller( command );
- }
- void ascii_write_data( unsigned char data )
- {
- ascii_ctrl_bit_set( B_RS );
- ascii_ctrl_bit_clear( B_RW );
- ascii_write_controller( data );
- }
- unsigned char ascii_read_status( void )
- {
- *GPIO_E_MODER = 0x00005555; //configure GPIO_E to become an inport so we can read from it
- ascii_ctrl_bit_clear( B_RS );
- ascii_ctrl_bit_set( B_RW );
- unsigned char rv = ascii_read_controller();
- *GPIO_E_MODER = 0x55555555; //turn GPIO_E back to an outport
- return rv;
- }
- unsigned char ascii_read_data( void )
- {
- *GPIO_E_MODER = 0x00005555; //configure GPIO_E to become an inport so we can read from it
- ascii_ctrl_bit_set( B_RS | B_RW ); //Set both RS and RW bits to be '1'
- unsigned char rv = ascii_read_controller();
- *GPIO_E_MODER = 0x55555555; //turn GPIO_E back to an outport
- return rv;
- }
- void ascii_command( unsigned short command )
- {
- while ( (ascii_read_status() & 0x80) == 0x80 ) {} //Wait for B_E to become '0' to indicate that the ASCII display is ready to receive a command (that it isn't busy)
- delay_mikro( 8 );
- ascii_write_cmd( (char)(command & 0b0011111111) ); //must reset two first bits (they're not used in this function, only to indicate what delay to pick in switch statement below)
- //and convert to byte (ascii_write_cmd takes a byte, not a short)
- switch( command ) {
- case 0b0000000001 ... 0b0000000011: //For clear display and return home
- delay_milli(2); //For commands that require <2ms delay;
- break;
- case 0b0010000000 ... 0b0011111111: //For 'read address' and 'read status'
- break; //For command that doesn't require a delay
- default: //For display control, function set, address, etc
- delay_mikro(50); //default case for all the other commands that require 39 or 43us delay minimum (and we use 50us as a safety measure to ensure it works)
- }
- }
- void ascii_write_char( char c )
- {
- while ( (ascii_read_status() & 0x80) == 0x80 ) {} //Wait for statusflag to indicate that asciidisplay is not busy
- delay_mikro(8);
- ascii_write_data( c );
- delay_mikro(50);
- }
- void ascii_gotoxy( unsigned int x, unsigned int y )
- {
- unsigned int address = x - 1; //Convert from 1-indexing to 0-indexing
- if( y == 2 ) { //If writig to second line
- address += 0x40; //offset address with 0x40 (64) to start writing on the second row (each row is 64 long, but no scroll is used so we only see 20 per row))
- }
- ascii_write_cmd( 0x80 | address );
- }
- void app_init( void )
- {
- *GPIO_E_MODER = 0x55555555;
- ascii_ctrl_bit_clear(0b11111111); //reset all before execution
- }
- void ascii_init( )
- {
- ascii_command( 1 ); //Clear screen
- ascii_command( 0b0000111000 ); //Init with 2 rows, 5x8 dots per letter
- ascii_command( 0b0000001110 ); //Turn on display, show marker
- ascii_command( 0b0000000110 ); //possibly wrong? idk, addressing with increment, no shift of buffer
- }
- int main(int argc, char **argv)
- {
- char *s;
- char test1[] = "Alfanumerisk";
- char test2[] = "Display - test";
- app_init();
- ascii_init();
- ascii_gotoxy(1, 1);
- s = test1;
- while( *s )
- {
- ascii_write_char( *s++ );
- }
- ascii_gotoxy(1,2);
- s = test2;
- while( *s )
- {
- ascii_write_char( *s++ );
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement