Library for New Haven NHD_0420DZW OLED
NHD_0420DZW_OLED.cpp
- Committer:
- JackB
- Date:
- 2016-10-26
- Revision:
- 0:91420dff6791
File content as of revision 0:91420dff6791:
/** * @file NHD_0420DZW_OLED.cpp * @brief This C++ file contains the functions to interface the New Haven * NHD_0420DZW display using a 4-wire software spi bus bus. * 10-bit SPI operation, ie spi.format(10, 3), does not work with Nucleo-F746ZG, * it remains 8-bit, so unfortunately I had to do bit banging * @author Jack Berkhout * * @date 2016-10-21 */ #include "NHD_0420DZW_OLED.h" #include "mbed.h" NHD_0420DZW_OLED::NHD_0420DZW_OLED(PinName sdi, PinName sdo, PinName scl, PinName csb, const char *name) : Stream(name), _lcd_sdi(sdi), _lcd_sdo(sdo), _lcd_scl(scl), _lcd_csb(csb) // TextDisplay(name), _lcd_sdi(sdi), _lcd_sdo(sdo), _lcd_scl(scl), _lcd_csb(csb) { _lcd_csb = 1; _lcd_scl = 1; _lcd_sdi = 0; // --- claim --- _row = 0; _column = 0; if (name == NULL) { _path = NULL; } else { _path = new char[strlen(name) + 2]; sprintf(_path, "/%s", name); } // ------------- init(); } void NHD_0420DZW_OLED::init(void) { writeCommand(LCD_FUNCTION_SET); writeCommand(LCD_DISPLAY_OFF); writeCommand(LCD_CLEAR_DISPLAY); writeCommand(LCD_CURSOR_INCR); writeCommand(LCD_RETURN_HOME); writeCommand(LCD_DISPLAY_ON); // custom characters // In the character generator RAM, the user can rewrite character patterns // For 5x8 dots, eight character patterns can be written // Store custom chars in LCD's CGRAM writeCommand(LCD_CGRAM(1)); char CharacterBytes[] = CHARACTERBYTES; for (unsigned char Index = 0; Index < sizeof(CharacterBytes); Index++) { writeData(CharacterBytes[Index]); } } void NHD_0420DZW_OLED::cls(void) { writeCommand(LCD_CLEAR_DISPLAY); // Clear display } void NHD_0420DZW_OLED::cursorHome(void) { writeCommand(LCD_RETURN_HOME); // Clear display } void NHD_0420DZW_OLED::writeCharacter(int column, int row, int c) { locate(column, row); writeData(c); } void NHD_0420DZW_OLED::writeCharacter(char c) { writeData((int)c); } void NHD_0420DZW_OLED::writeString(char *charString) { uint8_t length = strlen(charString); for (uint8_t i = 0; i < length; i++) { writeCharacter(charString[i]); } } void NHD_0420DZW_OLED::writeString(int row, char *charString) { locate(0, row); writeString(charString); } void NHD_0420DZW_OLED::writeString(int column, int row, char *charString) { locate(column, row); writeString(charString); } void NHD_0420DZW_OLED::clearLine(int row) { int length = LCD_NUMBER_OF_CHARACTERS; locate(0, row); while(length--) { writeCharacter(' '); } locate(0, row); } void NHD_0420DZW_OLED::clearRegion(int column, int row, int length) { locate(column, row); while(length--) { writeCharacter(' '); } locate(column, row); } void NHD_0420DZW_OLED::locate(int column, int row) { if ((column > LCD_NUMBER_OF_CHARACTERS) || (row > LCD_NUMBER_OF_LINES)) { return; } else { switch (row) { case 0: writeCommand(LCD_LINE_1 + column); /* command - position cursor at 0x00 (0x80 + 0x00 ) */ break; case 1: writeCommand(LCD_LINE_2 + column); /* command - position cursor at 0x40 (0x80 + 0x00 ) */ break; case 2: writeCommand(LCD_LINE_3 + column); /* command - position cursor at 0x40 (0x80 + 0x00 ) */ break; case 3: writeCommand(LCD_LINE_4 + column); /* command - position cursor at 0x40 (0x80 + 0x00 ) */ break; default: writeCommand(LCD_LINE_1 + column); /* command - position cursor at 0x00 (0x80 + 0x00 ) */ break; } } } void NHD_0420DZW_OLED::drawBar(int column, int row, int Value, int Max) { int Count = 0; int Characters = Max / 5; if (Value > Max) Value = Max; locate(column, row); // Print the characters while (Count < Characters) { if ((Value >= 6) && (Value <= Max)) writeData('\6'); // ***** else if ((Value == 0) || (Value > Max)) writeData('\1'); // ..... else writeData(Value+1); // ***.. Value -= 5; Count++; } } void NHD_0420DZW_OLED::writeCommand(int data) { waitBusy(); writeSerial(LCD_COMMAND, LCD_WRITE, data); } void NHD_0420DZW_OLED::writeData(int data) { // waitBusy(); writeSerial(LCD_DATA, LCD_WRITE, data); } int NHD_0420DZW_OLED::readAddress(void) { writeSerial(LCD_COMMAND, LCD_READ, 0x00); // Dummy read return (serialData(LCD_COMMAND, LCD_READ, 0x00, 0x00) >> 3) & 0x7F; } void NHD_0420DZW_OLED::waitBusy(void) { while (readBusyFlag()); } int NHD_0420DZW_OLED::readBusyFlag(void) { return (serialInstruction(LCD_COMMAND, LCD_READ, 0x00, 0x00) >> 10); } void NHD_0420DZW_OLED::writeSerial(int rs, int rw, int data) { // CSB ---|_________________________________________|---- // SCL -----|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|------ // SDI .....|RS0|RW0|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |.... // SDO .............|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |.... // RS=1: Data // RS=0: Command <--- // RW=1: Read // RW=0: Write <--- if (rs > 0) { data |= LCD_RS_BIT_MASK; } if (rw > 0) { data |= LCD_Rw_BIT_MASK; } selectSerial(true); clockSerial(data, 10); selectSerial(false); } int NHD_0420DZW_OLED::serialInstruction(int rs, int rw, int data1, int data2) { // CSB ---|_________________________________________________________________________________|---- // SCL -----|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|------ // SDI .....|RS0|RW1|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |RS |RW |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |.... // SDO .............|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |D7 |D6 |.... // RS=1: Data // RS=0: Command <--- // RW=1: Read <--- // RW=0: Write // Read Bussy Flag & Address BF AC6 AC5 AC4 AC3 AC2 AC1 AC0 if (rs > 0) { data1 |= LCD_RS_BIT_MASK; data2 |= LCD_RS_BIT_MASK; } if (rw > 0) { data1 |= LCD_Rw_BIT_MASK; data2 |= LCD_Rw_BIT_MASK; } selectSerial(true); clockSerial(data1, 10); int data = clockSerial(data2, 10); selectSerial(false); return data; } int NHD_0420DZW_OLED::serialData(int rs, int rw, int data1, int data2) { // CSB ---|_________________________________________________________________________________|---- // SCL -----|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|------ // SDI .....|RS1|RW1|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |RS |RW |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |.... // SDO .............|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |D7 |D6 |.... // RS=1: Data <--- // RS=0: Command // RW=1: Read <--- // RW=0: Write // Read data from CGRAM or DDRAM if (rs > 0) { data1 |= LCD_RS_BIT_MASK; } if (rw > 0) { data1 |= LCD_Rw_BIT_MASK; } selectSerial(true); clockSerial(data1, 10); int data = clockSerial(data2, 8); selectSerial(false); return data; } int NHD_0420DZW_OLED::clockSerial(int dataOut, int bits) { int dataIn = 0; for (int bit = bits; bit > 0; bit--) { _lcd_scl = 0; if ((dataOut & (1 << (bit-1))) == 0) { _lcd_sdi = 0; } else { _lcd_sdi = 1; } // wait_us(LCD_CLOCK_PULSE_LENGTH); _lcd_scl = 1; dataIn |= _lcd_sdo; dataIn <<= 1; // wait_us(LCD_CLOCK_PULSE_LENGTH); } return dataIn; } void NHD_0420DZW_OLED::selectSerial(bool select) { if (select) _lcd_csb = 0; else _lcd_csb = 1; // wait_us(LCD_CLOCK_PULSE_LENGTH); } bool NHD_0420DZW_OLED::claim (FILE *stream) { if ( _path == NULL) { fprintf(stderr, "claim requires a name to be given in the instantioator of the TextDisplay instance!\r\n"); return false; } if (freopen(_path, "w", stream) == NULL) { // Failed, should not happen return false; } // make sure we use line buffering setvbuf(stdout, NULL, _IOLBF, LCD_NUMBER_OF_CHARACTERS); return true; }