lcd-wo-fault-mode.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #include "all-headers.h"
  2. #include <stddef.h>
  3. #include <stdbool.h>
  4. // http://esd.cs.ucr.edu/labs/interface/interface.html
  5. // PORT CONFIGURATION *
  6. // LCD D4 : Teensy D16
  7. // LCD D5 : Teensy D15
  8. // LCD D6 : Teensy D14
  9. // LCD D7 : Teensy D19
  10. // LCD RS : Teensy D18
  11. // LCD E : Teensy D17
  12. static const DigitalPort LCD_D4 = DigitalPort::D16 ;
  13. static const DigitalPort LCD_D5 = DigitalPort::D15 ;
  14. static const DigitalPort LCD_D6 = DigitalPort::D14 ;
  15. static const DigitalPort LCD_D7 = DigitalPort::D19 ;
  16. static const DigitalPort LCD_RS = DigitalPort::D18 ;
  17. static const DigitalPort LCD_E = DigitalPort::D17 ;
  18. // UTILITY ROUTINES — ANY MODE *
  19. static void driveHighE (void) {
  20. digitalWrite (LCD_E, true) ;
  21. }
  22. static void driveLowE (void) {
  23. digitalWrite (LCD_E, false) ;
  24. }
  25. static void driveHighRS (void) {
  26. digitalWrite (LCD_RS, true) ;
  27. }
  28. static void driveLowRS (void) {
  29. digitalWrite (LCD_RS, false) ;
  30. }
  31. static void setD4 (const bool inValue) {
  32. digitalWrite (LCD_D4, inValue) ;
  33. }
  34. static void setD5 (const bool inValue) {
  35. digitalWrite (LCD_D5, inValue) ;
  36. }
  37. static void setD6 (const bool inValue) {
  38. digitalWrite (LCD_D6, inValue) ;
  39. }
  40. static void setD7 (const bool inValue) {
  41. digitalWrite (LCD_D7, inValue) ;
  42. }
  43. static void programLcd4BitDataBusOutput (const uint8_t inValue) {
  44. setD4 ((inValue & 0x01) != 0) ;
  45. setD5 ((inValue & 0x02) != 0) ;
  46. setD6 ((inValue & 0x04) != 0) ;
  47. setD7 ((inValue & 0x08) != 0) ;
  48. }
  49. // UTILITY ROUTINES — INIT_MODE
  50. static void write4BitCommand_initMode (INIT_MODE_ const uint8_t inCommand) {
  51. busyWaitDuring_initMode (MODE_ 1) ;
  52. driveLowRS () ;
  53. programLcd4BitDataBusOutput (inCommand) ;
  54. driveHighE () ;
  55. busyWaitDuring_initMode (MODE_ 1) ;
  56. driveLowE () ;
  57. }
  58. static void write8bitCommand_initMode (INIT_MODE_ const uint8_t inCommand) {
  59. busyWaitDuring_initMode (MODE_ 1) ;
  60. driveLowRS () ;
  61. programLcd4BitDataBusOutput ((uint8_t) (inCommand >> 4)) ;
  62. driveHighE () ;
  63. busyWaitDuring_initMode (MODE_ 1) ;
  64. driveLowE () ;
  65. busyWaitDuring_initMode (MODE_ 1) ;
  66. programLcd4BitDataBusOutput (inCommand) ;
  67. driveHighE () ;
  68. busyWaitDuring_initMode (MODE_ 1) ;
  69. driveLowE () ;
  70. }
  71. // LCD INIT
  72. static void setupLCD (INIT_MODE) {
  73. //--- Step 1: Configure ports
  74. pinMode (LCD_D4, DigitalMode::OUTPUT) ;
  75. pinMode (LCD_D5, DigitalMode::OUTPUT) ;
  76. pinMode (LCD_D6, DigitalMode::OUTPUT) ;
  77. pinMode (LCD_D7, DigitalMode::OUTPUT) ;
  78. pinMode (LCD_RS, DigitalMode::OUTPUT) ;
  79. pinMode (LCD_E, DigitalMode::OUTPUT) ;
  80. //--- Step 2: wait for 15 ms
  81. busyWaitDuring_initMode (MODE_ 15) ;
  82. //--- Step 3: write command 0x30
  83. write4BitCommand_initMode (MODE_ 0x3) ;
  84. //--- Step 4: wait for 4,1 ms (actually 5 ms)
  85. busyWaitDuring_initMode (MODE_ 5) ;
  86. //--- Step 5: write command 0x30 again
  87. write4BitCommand_initMode (MODE_ 0x3) ;
  88. //--- Step 6: wait for 100 µs (actually 1 ms)
  89. busyWaitDuring_initMode (MODE_ 1) ;
  90. //--- Step 7: write command 0x30 (third)
  91. write4BitCommand_initMode (MODE_ 0x3) ;
  92. //--- Step 8: write command 0x20 (4-bit mode)
  93. write4BitCommand_initMode (MODE_ 0x2) ;
  94. //--- Step 9: write command 'Set Interface Length' : 0 0 1 DL N F * *
  95. // DL : Data interface length : 0 (4 bits)
  96. // N : Number of Display lines : 1 (2 lines)
  97. // F : Character Font : 0 (5x7)
  98. write8bitCommand_initMode (MODE_ 0x28) ;
  99. //--- Step 10: write command 'Display Off'
  100. write8bitCommand_initMode (MODE_ 0x08) ;
  101. //--- Step 11: write command 'Clear Display'
  102. write8bitCommand_initMode (MODE_ 0x01) ;
  103. //--- Step 12: write command 'Set Cursor Move Direction' : 0 0 0 0 0 1 ID S
  104. // ID : Increment Cursor after Each Byte Written to Display : 1 (yes)
  105. // S : Shift Display When Byte Written : 0 (no)
  106. write8bitCommand_initMode (MODE_ 0x06) ;
  107. //--- Step 13: write command 'Move Cursor / Shift Display' : 0 0 0 1 SC RL * *
  108. // SC : Display Shift On : 1 (oui)
  109. // RL : Direction of Shift : 1 (to right)
  110. write8bitCommand_initMode (MODE_ 0x1C) ;
  111. //--- Step 14: write command 'Return Cursor and LCD to Home Position'
  112. write8bitCommand_initMode (MODE_ 0x02) ;
  113. //--- Step 15: write command 'Enable Display / Cursor' : 0 0 0 0 1 D C B
  114. // D : Turn Display On : 1 (yes)
  115. // C : Turn Cursor On : 0 (no)
  116. // B : Cursor Blink On : 0 (no)
  117. write8bitCommand_initMode (MODE_ 0x0C) ;
  118. }
  119. MACRO_INIT_ROUTINE (setupLCD) ;
  120. // UTILITY ROUTINES — USER MODE
  121. static void write8bitCommand (USER_MODE_ const uint8_t inCommand) {
  122. busyWaitDuring (MODE_ 1) ;
  123. driveLowRS () ;
  124. programLcd4BitDataBusOutput ((uint8_t) (inCommand >> 4)) ;
  125. driveHighE () ;
  126. busyWaitDuring (MODE_ 1) ;
  127. driveLowE () ;
  128. busyWaitDuring (MODE_ 1) ;
  129. programLcd4BitDataBusOutput (inCommand) ;
  130. driveHighE () ;
  131. busyWaitDuring (MODE_ 1) ;
  132. driveLowE () ;
  133. }
  134. static void writeData (USER_MODE_ const uint8_t inData) {
  135. busyWaitDuring (MODE_ 1) ;
  136. driveHighRS () ;
  137. programLcd4BitDataBusOutput (inData >> 4) ;
  138. driveHighE () ;
  139. busyWaitDuring (MODE_ 1) ;
  140. driveLowE () ;
  141. busyWaitDuring (MODE_ 1) ;
  142. programLcd4BitDataBusOutput (inData) ;
  143. driveHighE () ;
  144. busyWaitDuring (MODE_ 1) ;
  145. driveLowE () ;
  146. }
  147. // PRINT ROUTINES — USER MODE
  148. void clearScreen (USER_MODE) {
  149. write8bitCommand (MODE_ 0x01) ;
  150. }
  151. // Line 0 : 00 -> 19
  152. // Line 1 : 64 -> 83
  153. // Line 2 : 20 -> 39
  154. // Line 3 : 84 -> 103
  155. void gotoLineColumn (USER_MODE_ const uint32_t inLine, const uint32_t inColumn) {
  156. static const uint8_t tab [4] = {0, 64, 20, 84} ;
  157. if ((inLine < 4) && (inColumn < 20)) {
  158. write8bitCommand (MODE_ tab [inLine] + inColumn + 0x80U) ;
  159. }
  160. }
  161. void printString (USER_MODE_ const char * inString) {
  162. if (NULL != inString) {
  163. while ('\0' != *inString) {
  164. writeData (MODE_ *inString) ;
  165. inString ++ ;
  166. }
  167. }
  168. }
  169. void printChar (USER_MODE_ const char inChar) {
  170. writeData (MODE_ inChar) ;
  171. }
  172. void printSpaces (USER_MODE_ const uint32_t inCount) {
  173. uint32_t count = inCount ;
  174. while (count > 0) {
  175. printChar (MODE_ ' ') ;
  176. count -- ;
  177. }
  178. }
  179. void printUnsigned (USER_MODE_ const uint32_t inValue) {
  180. uint32_t divisor = 1000 * 1000 * 1000 ; // 10**9
  181. uint32_t value = inValue ;
  182. bool isPrinting = false ;
  183. while (divisor > 0) {
  184. if (isPrinting || (value >= divisor)) {
  185. printChar (MODE_ '0' + value / divisor) ;
  186. value %= divisor ;
  187. isPrinting = true ;
  188. }
  189. divisor /= 10 ;
  190. }
  191. if (!isPrinting) {
  192. printChar (MODE_ '0') ;
  193. }
  194. }
  195. void printUnsigned64 (USER_MODE_ const uint64_t inValue) {
  196. char buffer [20] ;
  197. buffer [19] = '\0' ;
  198. buffer [18] = (inValue % 10) + '0' ;
  199. uint32_t idx = 18 ;
  200. uint64_t v = inValue / 10 ;
  201. while (v != 0) {
  202. idx -- ;
  203. buffer [idx] = (v % 10) + '0' ;
  204. v /= 10 ;
  205. }
  206. printString (MODE_ & buffer [idx]) ;
  207. }
  208. void printSigned (USER_MODE_ const int32_t inValue) {
  209. if (inValue < 0) {
  210. printChar (MODE_ '-') ;
  211. printUnsigned (MODE_ (uint32_t) -inValue) ;
  212. }else{
  213. printUnsigned (MODE_ (uint32_t) inValue) ;
  214. }
  215. }
  216. void printHex1 (USER_MODE_ const uint32_t inValue) {
  217. const uint32_t v = inValue & 0xF ;
  218. if (v < 10) {
  219. printChar (MODE_ '0' + v) ;
  220. }else{
  221. printChar (MODE_ 'A' + v - 10) ;
  222. }
  223. }
  224. void printHex2 (USER_MODE_ const uint32_t inValue) {
  225. printHex1 (MODE_ inValue >> 4) ;
  226. printHex1 (MODE_ inValue) ;
  227. }
  228. void printHex4 (USER_MODE_ const uint32_t inValue) {
  229. printHex2 (MODE_ inValue >> 8) ;
  230. printHex2 (MODE_ inValue) ;
  231. }
  232. void printHex8 (USER_MODE_ const uint32_t inValue) {
  233. printHex4 (MODE_ inValue >> 16) ;
  234. printHex4 (MODE_ inValue) ;
  235. }
  236. void printHex16 (USER_MODE_ const uint64_t inValue) {
  237. printHex8 (MODE_ (uint32_t) (inValue >> 32)) ;
  238. printHex8 (MODE_ (uint32_t) inValue) ;
  239. }