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.

220 lines
6.3 KiB

  1. /*
  2. Copyright 2022
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #pragma once
  15. #include <stdint.h>
  16. #include <stdbool.h>
  17. /**
  18. * \defgroup hd44780
  19. *
  20. * HD44780 Character LCD Driver
  21. * \{
  22. */
  23. /*
  24. * HD44780 instructions
  25. * https://www.sparkfun.com/datasheets/LCD/HD44780.pdf
  26. * Table 6 (p24)
  27. */
  28. // Clear display
  29. #define HD44780_CMD_CLEAR_DISPLAY 0x01
  30. // Return home
  31. #define HD44780_CMD_RETURN_HOME 0x02
  32. // Entry mode set
  33. #define HD44780_CMD_ENTRY_MODE 0x04
  34. #define HD44780_ENTRY_MODE_INC 0x02 // I/D
  35. #define HD44780_ENTRY_MODE_SHIFT 0x01 // S
  36. // Display on/off control
  37. #define HD44780_CMD_DISPLAY 0x08
  38. #define HD44780_DISPLAY_ON 0x04 // D
  39. #define HD44780_DISPLAY_CURSOR 0x02 // C
  40. #define HD44780_DISPLAY_BLINK 0x01 // B
  41. // Cursor or display shift
  42. #define HD44780_CMD_MOVE 0x10
  43. #define HD44780_MOVE_DISPLAY 0x08 // S/C
  44. #define HD44780_MOVE_RIGHT 0x04 // R/L
  45. // Function set
  46. #define HD44780_CMD_FUNCTION 0x20
  47. #define HD44780_FUNCTION_8_BIT 0x10 // DL
  48. #define HD44780_FUNCTION_2_LINES 0x08 // N
  49. #define HD44780_FUNCTION_5X10_DOTS 0x04 // F
  50. // Set CGRAM address
  51. #define HD44780_CMD_SET_CGRAM_ADDRESS 0x40
  52. // Set DDRAM address
  53. #define HD44780_CMD_SET_DDRAM_ADDRESS 0x80
  54. // Bitmask for busy flag when reading
  55. #define HD44780_BUSY_FLAG 0x80
  56. /**
  57. * \brief Write a byte to the display.
  58. *
  59. * \param data The byte to send to the display.
  60. * \param isData Whether the byte is an instruction or character data.
  61. */
  62. void hd44780_write(uint8_t data, bool isData);
  63. /**
  64. * \brief Read a byte from the display.
  65. *
  66. * \param isData Whether to read the current cursor position, or the character at the cursor.
  67. *
  68. * \return If `isData` is `true`, the returned byte will be the character at the current DDRAM address. Otherwise, it will be the current DDRAM address and the busy flag.
  69. */
  70. uint8_t hd44780_read(bool isData);
  71. /**
  72. * \brief Indicates whether the display is currently processing, and cannot accept instructions.
  73. *
  74. * \return `true` if the display is busy.
  75. */
  76. bool hd44780_busy(void);
  77. /**
  78. * \brief Send a command to the display. Refer to the datasheet for the valid commands.
  79. *
  80. * This function waits for the display to clear the busy flag before sending the command.
  81. *
  82. * \param command The command to send.
  83. */
  84. void hd44780_command(uint8_t command);
  85. /**
  86. * \brief Send a byte of data to the display.
  87. *
  88. * This function waits for the display to clear the busy flag before sending the data.
  89. *
  90. * \param data The byte of data to send.
  91. */
  92. void hd44780_data(uint8_t data);
  93. /**
  94. * \brief Clear the display.
  95. *
  96. * This function is called on init.
  97. */
  98. void hd44780_clear(void);
  99. /**
  100. * \brief Move the cursor to the home position.
  101. *
  102. * This function is called on init.
  103. */
  104. void hd44780_home(void);
  105. /**
  106. * \brief Turn the display on, and/or set the cursor position.
  107. *
  108. * This function is called on init.
  109. *
  110. * \param cursor Whether to show the cursor.
  111. * \param blink Whether to blink the cursor, if shown.
  112. */
  113. void hd44780_on(bool cursor, bool blink);
  114. /**
  115. * \brief Turn the display off.
  116. */
  117. void hd44780_off(void);
  118. /**
  119. * \brief Set the CGRAM address.
  120. *
  121. * This function is used when defining custom characters.
  122. *
  123. * \param address The CGRAM address to move to, from `0x00` to `0x3F`.
  124. */
  125. void hd44780_set_cgram_address(uint8_t address);
  126. /**
  127. * \brief Set the DDRAM address.
  128. *
  129. * This function is used when printing characters to the display, and setting the cursor.
  130. *
  131. * \param address The DDRAM address to move to, from `0x00` to `0x7F`.
  132. */
  133. void hd44780_set_ddram_address(uint8_t address);
  134. /**
  135. * \brief Initialize the display.
  136. *
  137. * This function should be called only once, before any of the other functions can be called.
  138. *
  139. * \param cursor Whether to show the cursor.
  140. * \param blink Whether to blink the cursor, if shown.
  141. */
  142. void hd44780_init(bool cursor, bool blink);
  143. /**
  144. * \brief Move the cursor to the specified position on the display.
  145. *
  146. * \param col The column number to move to, from 0 to 15 on 16x2 displays.
  147. * \param line The line number to move to, either 0 or 1 on 16x2 displays.
  148. */
  149. void hd44780_set_cursor(uint8_t col, uint8_t line);
  150. /**
  151. * \brief Define a custom character.
  152. *
  153. * \param index The index of the custom character to define, from 0 to 7.
  154. * \param data An array of 8 bytes containing the 5-bit row data of the character, where the first byte is the topmost row, and the least significant bit of each byte is the rightmost column.
  155. */
  156. void hd44780_define_char(uint8_t index, uint8_t *data);
  157. /**
  158. * \brief Print a character to the display. The newline character will move the cursor to the start of the next line.
  159. *
  160. * The exact character shown may depend on the ROM code of your particular display - refer to the datasheet for the full character set.
  161. *
  162. * \param c The character to print.
  163. */
  164. void hd44780_putc(char c);
  165. /**
  166. * \brief Print a string of characters to the display.
  167. *
  168. * \param s The string to print.
  169. */
  170. void hd44780_puts(const char *s);
  171. #if defined(__AVR__) || defined(__DOXYGEN__)
  172. /**
  173. * \brief Define a custom character from PROGMEM.
  174. *
  175. * On ARM devices, this function is simply an alias of hd44780_define_char().
  176. *
  177. * \param index The index of the custom character to define, from 0 to 7.
  178. * \param data A PROGMEM array of 8 bytes containing the 5-bit row data of the character, where the first byte is the topmost row, and the least significant bit of each byte is the rightmost column.
  179. */
  180. void hd44780_define_char_P(uint8_t index, const uint8_t *data);
  181. /**
  182. * \brief Print a string of characters from PROGMEM to the display.
  183. *
  184. * On ARM devices, this function is simply an alias of hd44780_puts().
  185. *
  186. * \param s The PROGMEM string to print.
  187. */
  188. void hd44780_puts_P(const char *s);
  189. #else
  190. # define hd44780_define_char_P(index, data) hd44780_define_char(index, data)
  191. # define hd44780_puts_P(s) hd44780_puts(s)
  192. #endif
  193. /** \} */