Various projects using Raspberry Pi
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
6.1 KiB

10 years ago
  1. with Interfaces;
  2. use Interfaces;
  3. with Interfaces.C;
  4. use Interfaces.C;
  5. with Interfaces.C.extensions;
  6. use Interfaces.C.extensions;
  7. with bcm2835_h;
  8. use bcm2835_h;
  9. package body st7565lcd is
  10. procedure io_init is
  11. begin
  12. bcm2835_gpio_fsel(pin => LCD_CS, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
  13. bcm2835_gpio_fsel(pin => LCD_RST, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
  14. bcm2835_gpio_fsel(pin => LCD_A0, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
  15. bcm2835_gpio_fsel(pin => LCD_CLK, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
  16. bcm2835_gpio_fsel(pin => LCD_SI, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
  17. end io_init;
  18. procedure lcd_init is
  19. begin
  20. -- reset
  21. bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(HIGH));
  22. bcm2835_delayMicroseconds(unsigned_long_long(1));
  23. bcm2835_gpio_write(pin => LCD_RST, on => unsigned_char(LOW));
  24. bcm2835_delayMicroseconds(unsigned_long_long(1));
  25. bcm2835_gpio_write(pin => LCD_RST, on => unsigned_char(HIGH));
  26. bcm2835_delayMicroseconds(unsigned_long_long(1));
  27. -- init routine
  28. for index in lcd_init_data'range loop
  29. lcd_transfer_data(value => lcd_init_data(index), si => false);
  30. end loop;
  31. lcd_clear;
  32. end lcd_init;
  33. -- display strings on the lcd at a given position
  34. -- data is a string with any allowed range
  35. -- for strings not beginning at 0 we have to decrement the index
  36. -- variable for xpos by the value of the range begin, so we get
  37. -- for xpos a range from (xpos + 0 .. xpos + number of char in string)
  38. procedure lcd_ascii57_string (xpos : natural; ypos : natural; data : string) is
  39. begin
  40. for index in data'range loop
  41. lcd_ascii57(xpos => xpos + (index - data'first) * 6, ypos => ypos, data => character'val(character'pos(data(index))));
  42. end loop;
  43. end lcd_ascii57_string;
  44. procedure lcd_ascii57 (xpos : natural; ypos : natural; data : character) is
  45. begin
  46. lcd_set_page(page => ypos, column => xpos);
  47. -- write one 5x7 char
  48. for index in 0..4 loop
  49. lcd_transfer_data(value => font_5x7(character'pos(data))(index), si => true);
  50. end loop;
  51. -- one free column between chars
  52. lcd_transfer_data(value => 16#00#, si => true);
  53. end lcd_ascii57;
  54. procedure lcd_picture (xpos : natural; ypos: natural; picture : t_lcd_array) is
  55. begin
  56. for outdex in 0..7 loop
  57. lcd_set_page(page => ypos + outdex, column => xpos);
  58. for index in (128 * outdex) .. (128 * (outdex + 1) - 1) loop
  59. lcd_transfer_data(value => picture(index), si => true);
  60. end loop;
  61. end loop;
  62. end lcd_picture;
  63. procedure lcd_clear is
  64. begin
  65. bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(LOW));
  66. for outdex in 0..7 loop
  67. lcd_set_page(page => outdex, column => 0);
  68. for index in 0..128 loop
  69. lcd_transfer_data(value => 16#00#, si => true);
  70. end loop;
  71. end loop;
  72. bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(HIGH));
  73. end lcd_clear;
  74. procedure lcd_transfer_data (value : byte; si : boolean) is
  75. begin
  76. bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(LOW));
  77. bcm2835_gpio_write(pin => LCD_CLK, on => unsigned_char(HIGH));
  78. if si then
  79. bcm2835_gpio_write(pin => LCD_A0, on => unsigned_char(HIGH));
  80. else
  81. bcm2835_gpio_write(pin => LCD_A0, on => unsigned_char(LOW));
  82. end if;
  83. lcd_byte(value);
  84. bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(HIGH));
  85. end lcd_transfer_data;
  86. procedure lcd_set_page (page : natural; column : natural) is
  87. lsb : byte := byte(column + 1) and 16#0f#;
  88. msb : byte := byte(column + 1) and 16#f0#;
  89. page_int : byte := byte(page) or 16#b0#;
  90. begin
  91. msb := Shift_Right(msb, 4);
  92. msb := msb or 16#10#;
  93. lcd_transfer_data(value => page_int, si => false);
  94. lcd_transfer_data(value => msb, si => false);
  95. lcd_transfer_data(value => lsb, si => false);
  96. null;
  97. end lcd_set_page;
  98. procedure lcd_byte (data : byte) is
  99. data_int : byte := data;
  100. begin
  101. for index in 0..7 loop
  102. bcm2835_delayMicroseconds(unsigned_long_long(1));
  103. bcm2835_gpio_write(pin => LCD_CLK, on => unsigned_char(LOW));
  104. if (data_int and 16#80#) = 16#80# then
  105. bcm2835_gpio_write(pin => LCD_SI, on => unsigned_char(HIGH));
  106. else
  107. bcm2835_gpio_write(pin => LCD_SI, on => unsigned_char(LOW));
  108. end if;
  109. data_int := Shift_Left(data_int, 1);
  110. bcm2835_delayMicroseconds(unsigned_long_long(1));
  111. bcm2835_gpio_write(pin => LCD_CLK, on => unsigned_char(HIGH));
  112. end loop;
  113. end lcd_byte;
  114. function bmp_to_lcd (bmp : t_bmp_array; color_mask : t_color_mask) return t_lcd_array is
  115. lcd : t_lcd_array := (others => 16#00#);
  116. logic : byte;
  117. begin
  118. for aussen in 0 .. 7 loop
  119. logic := 16#01#;
  120. for outdex in 0 .. 7 loop
  121. for index in 0 .. 127 loop
  122. if ((bmp(aussen * 1024 + outdex * 128 + index)(which_byte(color_mask.red)) or
  123. bmp(aussen * 1024 + outdex * 128 + index)(which_byte(color_mask.green)) or
  124. bmp(aussen * 1024 + outdex * 128 + index)(which_byte(color_mask.blue))) < 16#77#) then
  125. lcd(aussen * 128 + index) := lcd(aussen * 128 + index) or logic;
  126. end if;
  127. end loop;
  128. logic := Shift_Left(logic, 1);
  129. end loop;
  130. end loop;
  131. return lcd;
  132. end bmp_to_lcd;
  133. function which_byte (data : dword) return integer is
  134. begin
  135. case data is
  136. when 16#000000FF# =>
  137. return 0;
  138. when 16#0000FF00# =>
  139. return 1;
  140. when 16#00FF0000# =>
  141. return 2;
  142. when 16#FF000000# =>
  143. return 3;
  144. when others =>
  145. return -1;
  146. end case;
  147. end which_byte;
  148. end st7565lcd;