123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475 |
- #include "all-headers.h"
- #include <stddef.h>
- #include <stdbool.h>
- // http://esd.cs.ucr.edu/labs/interface/interface.html
- // PORT CONFIGURATION *
- // LCD D4 : Teensy D16
- // LCD D5 : Teensy D15
- // LCD D6 : Teensy D14
- // LCD D7 : Teensy D19
- // LCD RS : Teensy D18
- // LCD E : Teensy D17
- static const DigitalPort LCD_D4 = DigitalPort::D16 ;
- static const DigitalPort LCD_D5 = DigitalPort::D15 ;
- static const DigitalPort LCD_D6 = DigitalPort::D14 ;
- static const DigitalPort LCD_D7 = DigitalPort::D19 ;
- static const DigitalPort LCD_RS = DigitalPort::D18 ;
- static const DigitalPort LCD_E = DigitalPort::D17 ;
- // SEMAPHORE
- static Semaphore sem(1);
- // UTILITY ROUTINES — ANY MODE
- static void driveHighE (void) {
- digitalWrite (LCD_E, true) ;
- }
- static void driveLowE (void) {
- digitalWrite (LCD_E, false) ;
- }
- static void driveHighRS (void) {
- digitalWrite (LCD_RS, true) ;
- }
- static void driveLowRS (void) {
- digitalWrite (LCD_RS, false) ;
- }
- static void setD4 (const bool inValue) {
- digitalWrite (LCD_D4, inValue) ;
- }
- static void setD5 (const bool inValue) {
- digitalWrite (LCD_D5, inValue) ;
- }
- static void setD6 (const bool inValue) {
- digitalWrite (LCD_D6, inValue) ;
- }
- static void setD7 (const bool inValue) {
- digitalWrite (LCD_D7, inValue) ;
- }
- static void programLcd4BitDataBusOutput (const uint8_t inValue) {
- setD4 ((inValue & 0x01) != 0) ;
- setD5 ((inValue & 0x02) != 0) ;
- setD6 ((inValue & 0x04) != 0) ;
- setD7 ((inValue & 0x08) != 0) ;
- }
- // UTILITY ROUTINES — INIT_MODE
- static void write4BitCommand_initMode (INIT_MODE_ const uint8_t inCommand) {
- busyWaitDuring_initMode (MODE_ 1) ;
- driveLowRS () ;
- programLcd4BitDataBusOutput (inCommand) ;
- driveHighE () ;
- busyWaitDuring_initMode (MODE_ 1) ;
- driveLowE () ;
- }
- static void write8bitCommand_initMode (INIT_MODE_ const uint8_t inCommand) {
- busyWaitDuring_initMode (MODE_ 1) ;
- driveLowRS () ;
- programLcd4BitDataBusOutput ((uint8_t) (inCommand >> 4)) ;
- driveHighE () ;
- busyWaitDuring_initMode (MODE_ 1) ;
- driveLowE () ;
- busyWaitDuring_initMode (MODE_ 1) ;
- programLcd4BitDataBusOutput (inCommand) ;
- driveHighE () ;
- busyWaitDuring_initMode (MODE_ 1) ;
- driveLowE () ;
- }
- // LCD INIT
- static void setupLCD (INIT_MODE) {
- // Step 1: Configure ports
- pinMode (LCD_D4, DigitalMode::OUTPUT) ;
- pinMode (LCD_D5, DigitalMode::OUTPUT) ;
- pinMode (LCD_D6, DigitalMode::OUTPUT) ;
- pinMode (LCD_D7, DigitalMode::OUTPUT) ;
- pinMode (LCD_RS, DigitalMode::OUTPUT) ;
- pinMode (LCD_E, DigitalMode::OUTPUT) ;
- // Step 2: wait for 15 ms
- busyWaitDuring_initMode (MODE_ 15) ;
- // Step 3: write command 0x30
- write4BitCommand_initMode (MODE_ 0x3) ;
- // Step 4: wait for 4,1 ms (actually 5 ms)
- busyWaitDuring_initMode (MODE_ 5) ;
- // Step 5: write command 0x30 again
- write4BitCommand_initMode (MODE_ 0x3) ;
- // Step 6: wait for 100 µs (actually 1 ms)
- busyWaitDuring_initMode (MODE_ 1) ;
- // Step 7: write command 0x30 (third)
- write4BitCommand_initMode (MODE_ 0x3) ;
- // Step 8: write command 0x20 (4-bit mode)
- write4BitCommand_initMode (MODE_ 0x2) ;
- // Step 9: write command 'Set Interface Length' : 0 0 1 DL N F * *
- // DL : Data interface length : 0 (4 bits)
- // N : Number of Display lines : 1 (2 lines)
- // F : Character Font : 0 (5x7)
- write8bitCommand_initMode (MODE_ 0x28) ;
- // Step 10: write command 'Display Off'
- write8bitCommand_initMode (MODE_ 0x08) ;
- // Step 11: write command 'Clear Display'
- write8bitCommand_initMode (MODE_ 0x01) ;
- // Step 12: write command 'Set Cursor Move Direction' : 0 0 0 0 0 1 ID S
- // ID : Increment Cursor after Each Byte Written to Display : 1 (yes)
- // S : Shift Display When Byte Written : 0 (no)
- write8bitCommand_initMode (MODE_ 0x06) ;
- // Step 13: write command 'Move Cursor / Shift Display' : 0 0 0 1 SC RL * *
- // SC : Display Shift On : 1 (oui)
- // RL : Direction of Shift : 1 (to right)
- write8bitCommand_initMode (MODE_ 0x1C) ;
- // Step 14: write command 'Return Cursor and LCD to Home Position'
- write8bitCommand_initMode (MODE_ 0x02) ;
- // Step 15: write command 'Enable Display / Cursor' : 0 0 0 0 1 D C B
- // D : Turn Display On : 1 (yes)
- // C : Turn Cursor On : 0 (no)
- // B : Cursor Blink On : 0 (no)
- write8bitCommand_initMode (MODE_ 0x0C) ;
- }
- MACRO_INIT_ROUTINE (setupLCD) ;
- // UTILITY ROUTINES — USER MODE
- static void write8bitCommand (USER_MODE_ const uint8_t inCommand) {
- waitDuring (MODE_ 1) ;
- driveLowRS () ;
- programLcd4BitDataBusOutput ((uint8_t) (inCommand >> 4)) ;
- driveHighE () ;
- waitDuring (MODE_ 1) ;
- driveLowE () ;
- waitDuring (MODE_ 1) ;
- programLcd4BitDataBusOutput (inCommand) ;
- driveHighE () ;
- waitDuring (MODE_ 1) ;
- driveLowE () ;
- }
- static void writeData (USER_MODE_ const uint8_t inData) {
- sem.P(MODE);
- waitDuring (MODE_ 1) ;
- driveHighRS () ;
- programLcd4BitDataBusOutput (inData >> 4) ;
- driveHighE () ;
- waitDuring (MODE_ 1) ;
- driveLowE () ;
- waitDuring (MODE_ 1) ;
- programLcd4BitDataBusOutput (inData) ;
- driveHighE () ;
- waitDuring (MODE_ 1) ;
- driveLowE () ;
- sem.V(MODE);
- }
- // PRINT ROUTINES — USER MODE
- void clearScreen (USER_MODE) {
- write8bitCommand (MODE_ 0x01) ;
- }
- // Line 0 : 00 -> 19
- // Line 1 : 64 -> 83
- // Line 2 : 20 -> 39
- // Line 3 : 84 -> 103
- void gotoLineColumn (USER_MODE_ const uint32_t inLine, const uint32_t inColumn) {
- static const uint8_t tab [4] = {0, 64, 20, 84} ;
- if ((inLine < 4) && (inColumn < 20)) {
- write8bitCommand (MODE_ tab [inLine] + inColumn + 0x80U) ;
- }
- }
- void printString (USER_MODE_ const char * inString) {
- if (NULL != inString) {
- while ('\0' != *inString) {
- writeData (MODE_ *inString) ;
- inString ++ ;
- }
- }
- }
- void printChar (USER_MODE_ const char inChar) {
- writeData (MODE_ inChar) ;
- }
- void printSpaces (USER_MODE_ const uint32_t inCount) {
- uint32_t count = inCount ;
- while (count > 0) {
- printChar (MODE_ ' ') ;
- count -- ;
- }
- }
- void printUnsigned (USER_MODE_ const uint32_t inValue) {
- uint32_t divisor = 1000 * 1000 * 1000 ; // 10**9
- uint32_t value = inValue ;
- bool isPrinting = false ;
- while (divisor > 0) {
- if (isPrinting || (value >= divisor)) {
- printChar (MODE_ '0' + value / divisor) ;
- value %= divisor ;
- isPrinting = true ;
- }
- divisor /= 10 ;
- }
- if (!isPrinting) {
- printChar (MODE_ '0') ;
- }
- }
- void printUnsigned64 (USER_MODE_ const uint64_t inValue) {
- char buffer [20] ;
- buffer [19] = '\0' ;
- buffer [18] = (inValue % 10) + '0' ;
- uint32_t idx = 18 ;
- uint64_t v = inValue / 10 ;
- while (v != 0) {
- idx -- ;
- buffer [idx] = (v % 10) + '0' ;
- v /= 10 ;
- }
- printString (MODE_ & buffer [idx]) ;
- }
- void printSigned (USER_MODE_ const int32_t inValue) {
- if (inValue < 0) {
- printChar (MODE_ '-') ;
- printUnsigned (MODE_ (uint32_t) -inValue) ;
- }else{
- printUnsigned (MODE_ (uint32_t) inValue) ;
- }
- }
- void printHex1 (USER_MODE_ const uint32_t inValue) {
- const uint32_t v = inValue & 0xF ;
- if (v < 10) {
- printChar (MODE_ '0' + v) ;
- }else{
- printChar (MODE_ 'A' + v - 10) ;
- }
- }
- void printHex2 (USER_MODE_ const uint32_t inValue) {
- printHex1 (MODE_ inValue >> 4) ;
- printHex1 (MODE_ inValue) ;
- }
- void printHex4 (USER_MODE_ const uint32_t inValue) {
- printHex2 (MODE_ inValue >> 8) ;
- printHex2 (MODE_ inValue) ;
- }
- void printHex8 (USER_MODE_ const uint32_t inValue) {
- printHex4 (MODE_ inValue >> 16) ;
- printHex4 (MODE_ inValue) ;
- }
- void printHex16 (USER_MODE_ const uint64_t inValue) {
- printHex8 (MODE_ (uint32_t) (inValue >> 32)) ;
- printHex8 (MODE_ (uint32_t) inValue) ;
- }
- // FAULT MODE
- static void write4BitCommand_faultMode (FAULT_MODE_ const uint8_t inCommand) {
- busyWaitDuring_faultMode (MODE_ 1) ;
- driveLowRS () ;
- programLcd4BitDataBusOutput (inCommand) ;
- driveHighE () ;
- busyWaitDuring_faultMode (MODE_ 1) ;
- driveLowE () ;
- }
- static void write8bitCommand_faultMode (FAULT_MODE_ const uint8_t inCommand) {
- busyWaitDuring_faultMode (MODE_ 1) ;
- driveLowRS () ;
- programLcd4BitDataBusOutput ((uint8_t) (inCommand >> 4)) ;
- driveHighE () ;
- busyWaitDuring_faultMode (MODE_ 1) ;
- driveLowE () ;
- busyWaitDuring_faultMode (MODE_ 1) ;
- programLcd4BitDataBusOutput (inCommand) ;
- driveHighE () ;
- busyWaitDuring_faultMode (MODE_ 1) ;
- driveLowE () ;
- }
- void initScreen_faultMode (FAULT_MODE) {
- // Step 1: Configure ports
- pinMode (LCD_D4, DigitalMode::OUTPUT) ;
- pinMode (LCD_D5, DigitalMode::OUTPUT) ;
- pinMode (LCD_D6, DigitalMode::OUTPUT) ;
- pinMode (LCD_D7, DigitalMode::OUTPUT) ;
- pinMode (LCD_RS, DigitalMode::OUTPUT) ;
- pinMode (LCD_E, DigitalMode::OUTPUT) ;
- // Step 2: wait for 15 ms
- busyWaitDuring_faultMode (MODE_ 15) ;
- // Step 3: write command 0x30
- write4BitCommand_faultMode (MODE_ 0x3) ;
- // Step 4: wait for 4,1 ms (actually 5 ms)
- busyWaitDuring_faultMode (MODE_ 5) ;
- // Step 5: write command 0x30 again
- write4BitCommand_faultMode (MODE_ 0x3) ;
- // Step 6: wait for 100 µs (actually 1 ms)
- busyWaitDuring_faultMode (MODE_ 1) ;
- // Step 7: write command 0x30 (third)
- write4BitCommand_faultMode (MODE_ 0x3) ;
- // Step 8: write command 0x20 (4-bit mode)
- write4BitCommand_faultMode (MODE_ 0x2) ;
- // Step 9: write command 'Set Interface Length' : 0 0 1 DL N F * *
- // DL : Data interface length : 0 (4 bits)
- // N : Number of Display lines : 1 (2 lines)
- // F : Character Font : 0 (5x7)
- write8bitCommand_faultMode (MODE_ 0x28) ;
- // Step 10: write command 'Display Off'
- write8bitCommand_faultMode (MODE_ 0x08) ;
- // Step 11: write command 'Clear Display'
- write8bitCommand_faultMode (MODE_ 0x01) ;
- // Step 12: write command 'Set Cursor Move Direction' : 0 0 0 0 0 1 ID S
- // ID : Increment Cursor after Each Byte Written to Display : 1 (yes)
- // S : Shift Display When Byte Written : 0 (no)
- write8bitCommand_faultMode (MODE_ 0x06) ;
- // Step 13: write command 'Move Cursor / Shift Display' : 0 0 0 1 SC RL * *
- // SC : Display Shift On : 1 (oui)
- // RL : Direction of Shift : 1 (to right)
- write8bitCommand_faultMode (MODE_ 0x1C) ;
- // Step 14: write command 'Return Cursor and LCD to Home Position'
- write8bitCommand_faultMode (MODE_ 0x02) ;
- // Step 15: write command 'Enable Display / Cursor' : 0 0 0 0 1 D C B
- // D : Turn Display On : 1 (yes)
- // C : Turn Cursor On : 0 (no)
- // B : Cursor Blink On : 0 (no)
- write8bitCommand_faultMode (MODE_ 0x0C) ;
- }
- void gotoLineColumn_faultMode (FAULT_MODE_ const uint32_t inLine, const uint32_t inColumn) {
- static const uint8_t tab [4] = {0, 64, 20, 84} ;
- if ((inLine < 4) && (inColumn < 20)) {
- write8bitCommand_faultMode (MODE_ tab [inLine] + inColumn + 0x80U) ;
- }
- }
- static void writeData_faultMode (FAULT_MODE_ const uint8_t inData) {
- busyWaitDuring_faultMode (MODE_ 1) ;
- driveHighRS () ;
- programLcd4BitDataBusOutput (inData >> 4) ;
- driveHighE () ;
- busyWaitDuring_faultMode (MODE_ 1) ;
- driveLowE () ;
- busyWaitDuring_faultMode (MODE_ 1) ;
- programLcd4BitDataBusOutput (inData) ;
- driveHighE () ;
- busyWaitDuring_faultMode (MODE_ 1) ;
- driveLowE () ;
- }
- void printString_faultMode (FAULT_MODE_ const char * inString) {
- if (NULL != inString) {
- while ('\0' != *inString) {
- writeData_faultMode (MODE_ *inString) ;
- inString ++ ;
- }
- }
- }
- void printChar_faultMode (FAULT_MODE_ const char inChar) {
- writeData_faultMode (MODE_ inChar) ;
- }
- void printUnsigned_faultMode (FAULT_MODE_ const uint32_t inValue) {
- uint32_t divisor = 1000 * 1000 * 1000 ; // 10**9
- uint32_t value = inValue ;
- bool isPrinting = false ;
- while (divisor > 0) {
- if (isPrinting || (value >= divisor)) {
- printChar_faultMode (MODE_ '0' + value / divisor) ;
- value %= divisor ;
- isPrinting = true ;
- }
- divisor /= 10 ;
- }
- if (!isPrinting) {
- printChar_faultMode (MODE_ '0') ;
- }
- }
- static void printHex1_faultMode (FAULT_MODE_ const uint32_t inValue) {
- const uint32_t v = inValue & 0xF ;
- if (v < 10) {
- printChar_faultMode (MODE_ '0' + v) ;
- }else{
- printChar_faultMode (MODE_ 'A' + v - 10) ;
- }
- }
- void printHex2_faultMode (FAULT_MODE_ const uint32_t inValue) {
- printHex1_faultMode (MODE_ inValue >> 4) ;
- printHex1_faultMode (MODE_ inValue) ;
- }
- void printHex4_faultMode (FAULT_MODE_ const uint32_t inValue) {
- printHex2_faultMode (MODE_ inValue >> 8) ;
- printHex2_faultMode (MODE_ inValue) ;
- }
- void printHex8_faultMode (FAULT_MODE_ const uint32_t inValue) {
- printHex4_faultMode (MODE_ inValue >> 16) ;
- printHex4_faultMode (MODE_ inValue) ;
- }
|