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

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 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;