Advertisement
Guest User

Untitled

a guest
Apr 25th, 2018
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.87 KB | None | 0 0
  1. /*
  2. * startup.c
  3. *
  4. */
  5.  
  6. #import "delay.h"
  7.  
  8. #define GPIO_E 0x40021000
  9. #define GPIO_E_MODER ((volatile unsigned int *) GPIO_E)
  10. #define GPIO_E_OTYPER ((volatile unsigned short *) GPIO_E + 0x4)
  11. #define GPIO_E_OSPEEDR ((volatile unsigned int *) GPIO_E + 0x8)
  12. #define GPIO_E_PUPDR ((volatile unsigned int *) GPIO_E + 0xC)
  13. #define GPIO_E_IDR_LOW ((volatile unsigned char*) GPIO_E + 0x10)
  14. #define GPIO_E_IDR_HIGH ((volatile unsigned char*) GPIO_E + 0x11)
  15. #define GPIO_E_ODR_LOW ((volatile unsigned char*) GPIO_E + 0x14)
  16. #define GPIO_E_ODR_HIGH ((volatile unsigned char*) GPIO_E + 0x15)
  17. #define B_E 0b01000000
  18. #define B_SELECT 0b00000100
  19. #define B_RW 0b00000010
  20. #define B_RS 0b00000001
  21.  
  22. void startup(void) __attribute__((naked)) __attribute__((section (".start_section")) );
  23.  
  24. void startup ( void )
  25. {
  26. __asm volatile(
  27. " LDR R0,=0x2001C000\n" /* set stack */
  28. " MOV SP,R0\n"
  29. " BL main\n" /* call main */
  30. "_exit: B .\n" /* never return */
  31. ) ;
  32. }
  33.  
  34. void ascii_ctrl_bit_set( unsigned char x )
  35. {
  36. *GPIO_E_ODR_LOW |= (B_SELECT | x) ;
  37. }
  38.  
  39. void ascii_ctrl_bit_clear( unsigned char x )
  40. {
  41. *GPIO_E_ODR_LOW &= ( B_SELECT | ~x );
  42. }
  43.  
  44.  
  45. unsigned char ascii_read_controller( void )
  46. {
  47. ascii_ctrl_bit_set( B_E );
  48. delay_250ns();
  49. delay_250ns();
  50. unsigned char rv = *GPIO_E_IDR_HIGH;
  51. ascii_ctrl_bit_clear( B_E );
  52. return rv;
  53. }
  54.  
  55. void ascii_write_controller( unsigned char byte )
  56. {
  57. ascii_ctrl_bit_set( B_E );
  58. *GPIO_E_ODR_HIGH = byte;
  59. delay_250ns();
  60. ascii_ctrl_bit_clear( B_E );
  61. }
  62.  
  63. void ascii_write_cmd( unsigned char command )
  64. {
  65. ascii_ctrl_bit_clear( B_RS ); //ascii_ctrl_bit_clear( B_RS | B_RW );
  66. ascii_ctrl_bit_clear( B_RW );
  67. ascii_write_controller( command );
  68. }
  69.  
  70. void ascii_write_data( unsigned char data )
  71. {
  72. ascii_ctrl_bit_set( B_RS );
  73. ascii_ctrl_bit_clear( B_RW );
  74. ascii_write_controller( data );
  75. }
  76.  
  77. unsigned char ascii_read_status( void )
  78. {
  79. *GPIO_E_MODER = 0x00005555; //configure GPIO_E to become an inport so we can read from it
  80. ascii_ctrl_bit_clear( B_RS );
  81. ascii_ctrl_bit_set( B_RW );
  82. unsigned char rv = ascii_read_controller();
  83. *GPIO_E_MODER = 0x55555555; //turn GPIO_E back to an outport
  84. return rv;
  85. }
  86.  
  87. unsigned char ascii_read_data( void )
  88. {
  89. *GPIO_E_MODER = 0x00005555; //configure GPIO_E to become an inport so we can read from it
  90. ascii_ctrl_bit_set( B_RS | B_RW ); //Set both RS and RW bits to be '1'
  91. unsigned char rv = ascii_read_controller();
  92. *GPIO_E_MODER = 0x55555555; //turn GPIO_E back to an outport
  93. return rv;
  94. }
  95.  
  96. void ascii_command( unsigned short command )
  97. {
  98. 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)
  99. delay_mikro( 8 );
  100. 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)
  101. //and convert to byte (ascii_write_cmd takes a byte, not a short)
  102. switch( command ) {
  103. case 0b0000000001 ... 0b0000000011: //For clear display and return home
  104. delay_milli(2); //For commands that require <2ms delay;
  105. break;
  106. case 0b0010000000 ... 0b0011111111: //For 'read address' and 'read status'
  107. break; //For command that doesn't require a delay
  108. default: //For display control, function set, address, etc
  109. 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)
  110. }
  111. }
  112.  
  113. void ascii_write_char( char c )
  114. {
  115. while ( (ascii_read_status() & 0x80) == 0x80 ) {} //Wait for statusflag to indicate that asciidisplay is not busy
  116. delay_mikro(8);
  117. ascii_write_data( c );
  118. delay_mikro(50);
  119. }
  120.  
  121. void ascii_gotoxy( unsigned int x, unsigned int y )
  122. {
  123. unsigned int address = x - 1; //Convert from 1-indexing to 0-indexing
  124. if( y == 2 ) { //If writig to second line
  125. 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))
  126. }
  127. ascii_write_cmd( 0x80 | address );
  128. }
  129.  
  130.  
  131. void app_init( void )
  132. {
  133. *GPIO_E_MODER = 0x55555555;
  134. ascii_ctrl_bit_clear(0b11111111); //reset all before execution
  135. }
  136.  
  137. void ascii_init( )
  138. {
  139. ascii_command( 1 ); //Clear screen
  140. ascii_command( 0b0000111000 ); //Init with 2 rows, 5x8 dots per letter
  141. ascii_command( 0b0000001110 ); //Turn on display, show marker
  142. ascii_command( 0b0000000110 ); //possibly wrong? idk, addressing with increment, no shift of buffer
  143. }
  144.  
  145.  
  146.  
  147. int main(int argc, char **argv)
  148. {
  149. char *s;
  150. char test1[] = "Alfanumerisk";
  151. char test2[] = "Display - test";
  152.  
  153. app_init();
  154. ascii_init();
  155. ascii_gotoxy(1, 1);
  156. s = test1;
  157. while( *s )
  158. {
  159. ascii_write_char( *s++ );
  160. }
  161. ascii_gotoxy(1,2);
  162. s = test2;
  163. while( *s )
  164. {
  165. ascii_write_char( *s++ );
  166. }
  167. return 0;
  168.  
  169.  
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement