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.

215 lines
7.8 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
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. with Ada.Text_IO;
  10. use Ada.Text_IO;
  11. package body st7565lcd is
  12. procedure io_init is
  13. begin
  14. bcm2835_gpio_fsel(pin => LCD_CS, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
  15. bcm2835_gpio_fsel(pin => LCD_RST, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
  16. bcm2835_gpio_fsel(pin => LCD_A0, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
  17. bcm2835_gpio_fsel(pin => LCD_CLK, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
  18. bcm2835_gpio_fsel(pin => LCD_SI, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
  19. end io_init;
  20. procedure lcd_init is
  21. begin
  22. -- reset
  23. bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(HIGH));
  24. bcm2835_delayMicroseconds(unsigned_long_long(1));
  25. bcm2835_gpio_write(pin => LCD_RST, on => unsigned_char(LOW));
  26. bcm2835_delayMicroseconds(unsigned_long_long(1));
  27. bcm2835_gpio_write(pin => LCD_RST, on => unsigned_char(HIGH));
  28. bcm2835_delayMicroseconds(unsigned_long_long(1));
  29. -- init routine
  30. for index in lcd_init_data'range loop
  31. lcd_transfer_data(value => lcd_init_data(index), si => false);
  32. end loop;
  33. lcd_clear;
  34. end lcd_init;
  35. -- display strings on the lcd at a given position
  36. -- data is a string with any allowed range
  37. -- for strings not beginning at 0 we have to decrement the index
  38. -- variable for xpos by the value of the range begin, so we get
  39. -- for xpos a range from (xpos + 0 .. xpos + number of char in string)
  40. procedure lcd_ascii57_string (xpos : natural; ypos : natural; data : string) is
  41. begin
  42. for index in data'range loop
  43. lcd_ascii57(xpos => xpos + (index - data'first) * 6, ypos => ypos, data => character'val(character'pos(data(index))));
  44. end loop;
  45. end lcd_ascii57_string;
  46. procedure lcd_ascii57 (xpos : natural; ypos : natural; data : character) is
  47. begin
  48. lcd_set_page(page => ypos, column => xpos);
  49. -- write one 5x7 char
  50. for index in 0..4 loop
  51. lcd_transfer_data(value => font_5x7(character'pos(data))(index), si => true);
  52. end loop;
  53. -- one free column between chars
  54. lcd_transfer_data(value => 16#00#, si => true);
  55. end lcd_ascii57;
  56. procedure lcd_picture (xpos : natural; ypos: natural; picture : t_lcd_array) is
  57. begin
  58. for outdex in 0..7 loop
  59. lcd_set_page(page => ypos + outdex, column => xpos);
  60. for index in (128 * outdex) .. (128 * (outdex + 1) - 1) loop
  61. lcd_transfer_data(value => picture(index), si => true);
  62. end loop;
  63. end loop;
  64. end lcd_picture;
  65. procedure lcd_clear is
  66. begin
  67. bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(LOW));
  68. for outdex in 0..7 loop
  69. lcd_set_page(page => outdex, column => 0);
  70. for index in 0..128 loop
  71. lcd_transfer_data(value => 16#00#, si => true);
  72. end loop;
  73. end loop;
  74. bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(HIGH));
  75. end lcd_clear;
  76. procedure lcd_transfer_data (value : byte; si : boolean) is
  77. begin
  78. bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(LOW));
  79. bcm2835_gpio_write(pin => LCD_CLK, on => unsigned_char(HIGH));
  80. if si then
  81. bcm2835_gpio_write(pin => LCD_A0, on => unsigned_char(HIGH));
  82. else
  83. bcm2835_gpio_write(pin => LCD_A0, on => unsigned_char(LOW));
  84. end if;
  85. lcd_byte(value);
  86. bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(HIGH));
  87. end lcd_transfer_data;
  88. procedure lcd_set_page (page : natural; column : natural) is
  89. lsb : byte := byte(column + 1) and 16#0f#;
  90. msb : byte := byte(column + 1) and 16#f0#;
  91. page_int : byte := byte(page) or 16#b0#;
  92. begin
  93. msb := Shift_Right(msb, 4);
  94. msb := msb or 16#10#;
  95. lcd_transfer_data(value => page_int, si => false);
  96. lcd_transfer_data(value => msb, si => false);
  97. lcd_transfer_data(value => lsb, si => false);
  98. null;
  99. end lcd_set_page;
  100. procedure lcd_byte (data : byte) is
  101. data_int : byte := data;
  102. begin
  103. for index in 0..7 loop
  104. bcm2835_delayMicroseconds(unsigned_long_long(1));
  105. bcm2835_gpio_write(pin => LCD_CLK, on => unsigned_char(LOW));
  106. if (data_int and 16#80#) = 16#80# then
  107. bcm2835_gpio_write(pin => LCD_SI, on => unsigned_char(HIGH));
  108. else
  109. bcm2835_gpio_write(pin => LCD_SI, on => unsigned_char(LOW));
  110. end if;
  111. data_int := Shift_Left(data_int, 1);
  112. bcm2835_delayMicroseconds(unsigned_long_long(1));
  113. bcm2835_gpio_write(pin => LCD_CLK, on => unsigned_char(HIGH));
  114. end loop;
  115. end lcd_byte;
  116. function bmp_to_lcd (bmp_picture : t_bmp_picture) return t_lcd_array is
  117. lcd : t_lcd_array := (others => 16#00#);
  118. logic : byte;
  119. begin
  120. for aussen in 0 .. 7 loop
  121. logic := 16#01#;
  122. for outdex in 0 .. 7 loop
  123. for index in 0 .. 127 loop
  124. if ((bmp_picture.data(aussen * 1024 + outdex * 128 + index)(which_byte(bmp_picture.mask.red)) or
  125. bmp_picture.data(aussen * 1024 + outdex * 128 + index)(which_byte(bmp_picture.mask.green)) or
  126. bmp_picture.data(aussen * 1024 + outdex * 128 + index)(which_byte(bmp_picture.mask.blue))) < 16#88#) then
  127. lcd(aussen * 128 + index) := lcd(aussen * 128 + index) or logic;
  128. end if;
  129. end loop;
  130. logic := Shift_Left(logic, 1);
  131. end loop;
  132. end loop;
  133. return lcd;
  134. end bmp_to_lcd;
  135. function which_byte (data : dword) return integer is
  136. begin
  137. case data is
  138. when 16#000000FF# =>
  139. return 0;
  140. when 16#0000FF00# =>
  141. return 1;
  142. when 16#00FF0000# =>
  143. return 2;
  144. when 16#FF000000# =>
  145. return 3;
  146. when others =>
  147. raise mask_exception;
  148. end case;
  149. end which_byte;
  150. -- read_bmp : read a bmp file in t_bmp_picture record
  151. procedure read_bmp (file : in Ada.Streams.Stream_IO.File_Type;
  152. file_access : access Ada.Streams.Root_Stream_Type'Class;
  153. bmp_picture : in out t_bmp_picture) is
  154. begin
  155. -- read header
  156. t_bmp_header'Read(file_access, bmp_picture.header);
  157. -- check for valid header
  158. if (abs bmp_picture.header.biHeight /= 64 or bmp_picture.header.biWidth /= 128 or
  159. (bmp_picture.header.biCompression /= 0 and bmp_picture.header.biCompression /= 3) or
  160. bmp_picture.header.biBitCount /= 32) then
  161. raise bmp_exception;
  162. end if;
  163. -- get color map if existing
  164. if bmp_picture.header.biCompression = 3 then
  165. t_color_mask'Read(file_access, bmp_picture.mask);
  166. end if;
  167. -- read in image data
  168. if bmp_picture.header.biHeight < 0 then
  169. -- top-down pixel matrix
  170. for index in bmp_picture.data'range loop
  171. if not Ada.Streams.Stream_IO.End_Of_File(file) then
  172. t_byte_array'Read(file_access, bmp_picture.data(index));
  173. end if;
  174. end loop;
  175. else
  176. -- bottom-top pixel matrix
  177. for row in reverse 0 .. 63 loop
  178. for column in 0 .. 127 loop
  179. if not Ada.Streams.Stream_IO.End_Of_File(file) then
  180. t_byte_array'Read(file_access, bmp_picture.data(row * 128 + column));
  181. end if;
  182. end loop;
  183. end loop;
  184. end if;
  185. end read_bmp;
  186. end st7565lcd;