#include "raspberrylcd.h" #include #include #include void waitMs(uint32_t ms) { delay(ms); } LCDScreen* configurePins(LCDScreen* screen, uint8_t RS, uint8_t RW, uint8_t E, uint8_t D0, uint8_t D1, uint8_t D2, uint8_t D3, uint8_t D4, uint8_t D5, uint8_t D6, uint8_t D7) { // Simply set all the fields to the supplied pins screen->RS = RS; screen->RW = RW; screen->E = E; screen->D0 = D0; screen->D1 = D1; screen->D2 = D2; screen->D3 = D3; screen->D4 = D4; screen->D5 = D5; screen->D6 = D6; screen->D7 = D7; // Initialize the pins to be output wiringPiSetup(); pinMode(screen->RS, OUTPUT); pinMode(screen->RW, OUTPUT); pinMode(screen->E, OUTPUT); pinMode(screen->D0, OUTPUT); pinMode(screen->D1, OUTPUT); pinMode(screen->D2, OUTPUT); pinMode(screen->D3, OUTPUT); pinMode(screen->D4, OUTPUT); pinMode(screen->D5, OUTPUT); pinMode(screen->D6, OUTPUT); pinMode(screen->D7, OUTPUT); return screen; } void initScreen(LCDScreen* screen, uint8_t interface_bits, uint8_t num_lines, uint8_t fontType, uint8_t cursor, uint8_t writeDirection) { // Set interface bits of screen screen->interface_bits = interface_bits; // Tell LCD screen to operate in intended bit mode sendCommand(screen, (FUNCTION_SET | interface_bits) >> 4); // Set number of display lines and font type sendCommand(screen, FUNCTION_SET | num_lines | fontType); // Turn display on and set cursor sendCommand(screen, DISPLAY_SWITCH | DISPLAY_ON | cursor); // Clear screen sendCommand(screen, SCREEN_CLEAR); // Set write direction sendCommand(screen, INPUT_SET | writeDirection); } void resetPins(LCDScreen* screen) { // Pull all pins low digitalWrite(screen->D7, LOW); digitalWrite(screen->D6, LOW); digitalWrite(screen->D5, LOW); digitalWrite(screen->D4, LOW); digitalWrite(screen->D3, LOW); digitalWrite(screen->D2, LOW); digitalWrite(screen->D1, LOW); digitalWrite(screen->D0, LOW); digitalWrite(screen->E, LOW); digitalWrite(screen->RW, LOW); digitalWrite(screen->RS, LOW); } // A helper function to send bytes to the screen // This function is not visible to the user void helper_send(LCDScreen* screen, uint8_t byte) { // Pull Enable high digitalWrite(screen->E, HIGH); // Write high nibble digitalWrite(screen->D7, (byte >> 7) & 0x1); digitalWrite(screen->D6, (byte >> 6) & 0x1); digitalWrite(screen->D5, (byte >> 5) & 0x1); digitalWrite(screen->D4, (byte >> 4) & 0x1); // If we're in 8-bit mode, write the lower nibbles as well if(screen->interface_bits == FULL_BYTE_INTERFACE) { digitalWrite(screen->D3, (byte >> 3) & 0x1); digitalWrite(screen->D2, (byte >> 2) & 0x1); digitalWrite(screen->D1, (byte >> 1) & 0x1); digitalWrite(screen->D0, (byte >> 0) & 0x1); } // If in 4-bit, then send the high nibbles and then set the lower nibbles else if(screen->interface_bits == HALF_BYTE_INTERFACE) { delayMicroseconds(1000); digitalWrite(screen->E, LOW); delayMicroseconds(10000); digitalWrite(screen->E, HIGH); digitalWrite(screen->D7, (byte >> 3) & 0x1); digitalWrite(screen->D6, (byte >> 2) & 0x1); digitalWrite(screen->D5, (byte >> 1) & 0x1); digitalWrite(screen->D4, (byte >> 0) & 0x1); } // Send the data supplied on the pins delayMicroseconds(1000); digitalWrite(screen->E, LOW); delayMicroseconds(10000); } // Sends a command by pulling RW and RS low void sendCommand(LCDScreen* screen, uint8_t command) { digitalWrite(screen->RW, LOW); digitalWrite(screen->RS, LOW); helper_send(screen, command); } // Sends a character by pulling only RW low void sendData(LCDScreen* screen, uint8_t data) { digitalWrite(screen->RW, LOW); digitalWrite(screen->RS, HIGH); helper_send(screen, data); } // Loops over a char* and sends each character individually. Supports the katakana and math as well void sendText(LCDScreen* screen, const char* text) { for(const char* c = text; *c != '\x00'; c++) { if(*c == '\xe3') { uint16_t symbol = ((uint16_t)(*(c + 1)) << 8) | ((uint16_t)(*(c + 2))); switch(symbol) { /* */ case 0x8080: sendData(screen, ' '); break; /*、*/ case 0x8081: sendData(screen, JAPANESE_COMMA); break; /*。*/ case 0x8082: sendData(screen, JAPANESE_PERIOD); break; /*「*/ case 0x808C: sendData(screen, JAPANESE_QUOTE_START); break; /*」*/ case 0x808D: sendData(screen, JAPANESE_QUOTE_END); break; /*ァ*/ case 0x82A1: sendData(screen, JAPANESE_KATAKANA_CHIISAI_A); break; /*ア*/ case 0x82A2: sendData(screen, JAPANESE_KATAKANA_A); break; /*ィ*/ case 0x82A3: sendData(screen, JAPANESE_KATAKANA_CHIISAI_I); break; /*イ*/ case 0x82A4: sendData(screen, JAPANESE_KATAKANA_I); break; /*ゥ*/ case 0x82A5: sendData(screen, JAPANESE_KATAKANA_CHIISAI_U); break; /*ウ*/ case 0x82A6: sendData(screen, JAPANESE_KATAKANA_U); break; /*ェ*/ case 0x82A7: sendData(screen, JAPANESE_KATAKANA_CHIISAI_E); break; /*エ*/ case 0x82A8: sendData(screen, JAPANESE_KATAKANA_E); break; /*ォ*/ case 0x82A9: sendData(screen, JAPANESE_KATAKANA_CHIISAI_O); break; /*オ*/ case 0x82AA: sendData(screen, JAPANESE_KATAKANA_O); break; /*カ*/ case 0x82AB: sendData(screen, JAPANESE_KATAKANA_KA); break; /*ガ*/ case 0x82AC: sendChars(screen, 2, JAPANESE_KATAKANA_KA, JAPANESE_DAKUTEN); break; /*キ*/ case 0x82AD: sendData(screen, JAPANESE_KATAKANA_KI); break; /*ギ*/ case 0x82AE: sendChars(screen, 2, JAPANESE_KATAKANA_KI, JAPANESE_DAKUTEN); break; /*ク*/ case 0x82AF: sendData(screen, JAPANESE_KATAKANA_KU); break; /*グ*/ case 0x82B0: sendChars(screen, 2, JAPANESE_KATAKANA_KU, JAPANESE_DAKUTEN); break; /*ケ*/ case 0x82B1: sendData(screen, JAPANESE_KATAKANA_KE); break; /*ゲ*/ case 0x82B2: sendChars(screen, 2, JAPANESE_KATAKANA_KE, JAPANESE_DAKUTEN); break; /*コ*/ case 0x82B3: sendData(screen, JAPANESE_KATAKANA_KO); break; /*ゴ*/ case 0x82B4: sendChars(screen, 2, JAPANESE_KATAKANA_KO, JAPANESE_DAKUTEN); break; /*サ*/ case 0x82B5: sendData(screen, JAPANESE_KATAKANA_SA); break; /*ザ*/ case 0x82B6: sendChars(screen, 2, JAPANESE_KATAKANA_SA, JAPANESE_DAKUTEN); break; /*シ*/ case 0x82B7: sendData(screen, JAPANESE_KATAKANA_SHI); break; /*ジ*/ case 0x82B8: sendChars(screen, 2, JAPANESE_KATAKANA_SHI, JAPANESE_DAKUTEN); break; /*ス*/ case 0x82B9: sendData(screen, JAPANESE_KATAKANA_SU); break; /*ズ*/ case 0x82BA: sendChars(screen, 2, JAPANESE_KATAKANA_SU, JAPANESE_DAKUTEN); break; /*セ*/ case 0x82BB: sendData(screen, JAPANESE_KATAKANA_SE); break; /*ゼ*/ case 0x82BC: sendChars(screen, 2, JAPANESE_KATAKANA_SE, JAPANESE_DAKUTEN); break; /*ソ*/ case 0x82BD: sendData(screen, JAPANESE_KATAKANA_SO); break; /*ゾ*/ case 0x82BE: sendChars(screen, 2, JAPANESE_KATAKANA_SO, JAPANESE_DAKUTEN); break; /*タ*/ case 0x82BF: sendData(screen, JAPANESE_KATAKANA_TA); break; /*ダ*/ case 0x8380: sendChars(screen, 2, JAPANESE_KATAKANA_TA, JAPANESE_DAKUTEN); break; /*チ*/ case 0x8381: sendData(screen, JAPANESE_KATAKANA_CHI); break; /*ヂ*/ case 0x8382: sendChars(screen, 2, JAPANESE_KATAKANA_CHI, JAPANESE_DAKUTEN); break; /*ッ*/ case 0x8383: sendData(screen, JAPANESE_KATAKANA_CHIISAI_TSU); break; /*ツ*/ case 0x8384: sendData(screen, JAPANESE_KATAKANA_TSU); break; /*ヅ*/ case 0x8385: sendChars(screen, 2, JAPANESE_KATAKANA_TSU, JAPANESE_DAKUTEN); break; /*テ*/ case 0x8386: sendData(screen, JAPANESE_KATAKANA_TE); break; /*デ*/ case 0x8387: sendChars(screen, 2, JAPANESE_KATAKANA_TE, JAPANESE_DAKUTEN); break; /*ト*/ case 0x8388: sendData(screen, JAPANESE_KATAKANA_TO); break; /*ド*/ case 0x8389: sendChars(screen, 2, JAPANESE_KATAKANA_TO, JAPANESE_DAKUTEN); break; /*ナ*/ case 0x838A: sendData(screen, JAPANESE_KATAKANA_NA); break; /*ニ*/ case 0x838B: sendData(screen, JAPANESE_KATAKANA_NI); break; /*ヌ*/ case 0x838C: sendData(screen, JAPANESE_KATAKANA_NU); break; /*ネ*/ case 0x838D: sendData(screen, JAPANESE_KATAKANA_NE); break; /*ノ*/ case 0x838E: sendData(screen, JAPANESE_KATAKANA_NO); break; /*ハ*/ case 0x838F: sendData(screen, JAPANESE_KATAKANA_HA); break; /*バ*/ case 0x8390: sendChars(screen, 2, JAPANESE_KATAKANA_HA, JAPANESE_DAKUTEN); break; /*パ*/ case 0x8391: sendChars(screen, 2, JAPANESE_KATAKANA_HA, JAPANESE_HANDAKUTEN); break; /*ヒ*/ case 0x8392: sendData(screen, JAPANESE_KATAKANA_HI); break; /*ビ*/ case 0x8393: sendChars(screen, 2, JAPANESE_KATAKANA_HI, JAPANESE_DAKUTEN); break; /*ピ*/ case 0x8394: sendChars(screen, 2, JAPANESE_KATAKANA_HI, JAPANESE_HANDAKUTEN); break; /*フ*/ case 0x8395: sendData(screen, JAPANESE_KATAKANA_FU); break; /*ブ*/ case 0x8396: sendChars(screen, 2, JAPANESE_KATAKANA_FU, JAPANESE_DAKUTEN); break; /*プ*/ case 0x8397: sendChars(screen, 2, JAPANESE_KATAKANA_FU, JAPANESE_HANDAKUTEN); break; /*ヘ*/ case 0x8398: sendData(screen, JAPANESE_KATAKANA_HE); break; /*ベ*/ case 0x8399: sendChars(screen, 2, JAPANESE_KATAKANA_HE, JAPANESE_DAKUTEN); break; /*ペ*/ case 0x839A: sendChars(screen, 2, JAPANESE_KATAKANA_HE, JAPANESE_HANDAKUTEN); break; /*ホ*/ case 0x839B: sendData(screen, JAPANESE_KATAKANA_HO); break; /*ボ*/ case 0x839C: sendChars(screen, 2, JAPANESE_KATAKANA_HO, JAPANESE_DAKUTEN); break; /*ポ*/ case 0x839D: sendChars(screen, 2, JAPANESE_KATAKANA_HO, JAPANESE_HANDAKUTEN); break; /*マ*/ case 0x839E: sendData(screen, JAPANESE_KATAKANA_MA); break; /*ミ*/ case 0x839F: sendData(screen, JAPANESE_KATAKANA_MI); break; /*ム*/ case 0x83A0: sendData(screen, JAPANESE_KATAKANA_MU); break; /*メ*/ case 0x83A1: sendData(screen, JAPANESE_KATAKANA_ME); break; /*モ*/ case 0x83A2: sendData(screen, JAPANESE_KATAKANA_MO); break; /*ャ*/ case 0x83A3: sendData(screen, JAPANESE_KATAKANA_CHIISAI_YA); break; /*ヤ*/ case 0x83A4: sendData(screen, JAPANESE_KATAKANA_YA); break; /*ュ*/ case 0x83A5: sendData(screen, JAPANESE_KATAKANA_CHIISAI_YU); break; /*ユ*/ case 0x83A6: sendData(screen, JAPANESE_KATAKANA_YU); break; /*ョ*/ case 0x83A7: sendData(screen, JAPANESE_KATAKANA_CHIISAI_YO); break; /*ヨ*/ case 0x83A8: sendData(screen, JAPANESE_KATAKANA_YO); break; /*ラ*/ case 0x83A9: sendData(screen, JAPANESE_KATAKANA_RA); break; /*リ*/ case 0x83AA: sendData(screen, JAPANESE_KATAKANA_RI); break; /*ル*/ case 0x83AB: sendData(screen, JAPANESE_KATAKANA_RU); break; /*レ*/ case 0x83AC: sendData(screen, JAPANESE_KATAKANA_RE); break; /*ロ*/ case 0x83AD: sendData(screen, JAPANESE_KATAKANA_RO); break; /*ワ*/ case 0x83AF: sendData(screen, JAPANESE_KATAKANA_WA); break; /*ヲ*/ case 0x83B2: sendData(screen, JAPANESE_KATAKANA_WO); break; /*ン*/ case 0x83B3: sendData(screen, JAPANESE_KATAKANA_N); break; /*ヴ*/ case 0x83B4: sendChars(screen, 2, JAPANESE_KATAKANA_U, JAPANESE_DAKUTEN); break; /*ヴ*/ case 0x83B5: sendChars(screen, 2, JAPANESE_KATAKANA_WA, JAPANESE_DAKUTEN); break; /*ヺ*/ case 0x83BA: sendChars(screen, 2, JAPANESE_KATAKANA_WO, JAPANESE_DAKUTEN); break; /*・*/ case 0x83BB: sendData(screen, JAPANESE_INTERPUNCT); break; /*ー*/ case 0x83BC: sendData(screen, JAPANESE_CHOONPU); break; default: printf("Unknown char: %x\n", symbol); sendData(screen, CURSOR); break; } c += 2; } else { sendData(screen, *c); } } } // Sends a list of chars, similar to sendText void sendChars(LCDScreen* screen, size_t len, ...) { va_list args; va_start(args, len); for(size_t i = 0; i < len; i++) sendData(screen, (uint8_t)va_arg(args, int)); va_end(args); } // Loads a custom character into CGRAM void loadCustomChar(LCDScreen* screen, uint8_t cgram_addr, ...) { // Initialize va_args va_list args; va_start(args, cgram_addr); // Choose correct scram address sendCommand(screen, CGRAM_AD_SET | (cgram_addr << 3)); // Write data to RAM for(int i = 0; i < 8; i++) sendData(screen, va_arg(args, int)); // Free va_args va_end(args); }