lcd-wo-fault-mode.cpp 21 KB

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