Library for New Haven NHD_0420DZW OLED

Committer:
JackB
Date:
Wed Oct 26 12:19:43 2016 +0000
Revision:
0:91420dff6791
Library for New Haven NHD_0420DZW OLED

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JackB 0:91420dff6791 1 /**
JackB 0:91420dff6791 2 * @file NHD_0420DZW_OLED.cpp
JackB 0:91420dff6791 3 * @brief This C++ file contains the functions to interface the New Haven
JackB 0:91420dff6791 4 * NHD_0420DZW display using a 4-wire software spi bus bus.
JackB 0:91420dff6791 5 * 10-bit SPI operation, ie spi.format(10, 3), does not work with Nucleo-F746ZG,
JackB 0:91420dff6791 6 * it remains 8-bit, so unfortunately I had to do bit banging
JackB 0:91420dff6791 7 * @author Jack Berkhout
JackB 0:91420dff6791 8 *
JackB 0:91420dff6791 9 * @date 2016-10-21
JackB 0:91420dff6791 10 */
JackB 0:91420dff6791 11 #include "NHD_0420DZW_OLED.h"
JackB 0:91420dff6791 12 #include "mbed.h"
JackB 0:91420dff6791 13
JackB 0:91420dff6791 14 NHD_0420DZW_OLED::NHD_0420DZW_OLED(PinName sdi, PinName sdo, PinName scl, PinName csb, const char *name) :
JackB 0:91420dff6791 15 Stream(name), _lcd_sdi(sdi), _lcd_sdo(sdo), _lcd_scl(scl), _lcd_csb(csb)
JackB 0:91420dff6791 16 // TextDisplay(name), _lcd_sdi(sdi), _lcd_sdo(sdo), _lcd_scl(scl), _lcd_csb(csb)
JackB 0:91420dff6791 17 {
JackB 0:91420dff6791 18 _lcd_csb = 1;
JackB 0:91420dff6791 19 _lcd_scl = 1;
JackB 0:91420dff6791 20 _lcd_sdi = 0;
JackB 0:91420dff6791 21
JackB 0:91420dff6791 22 // --- claim ---
JackB 0:91420dff6791 23 _row = 0;
JackB 0:91420dff6791 24 _column = 0;
JackB 0:91420dff6791 25 if (name == NULL) {
JackB 0:91420dff6791 26 _path = NULL;
JackB 0:91420dff6791 27 } else {
JackB 0:91420dff6791 28 _path = new char[strlen(name) + 2];
JackB 0:91420dff6791 29 sprintf(_path, "/%s", name);
JackB 0:91420dff6791 30 }
JackB 0:91420dff6791 31 // -------------
JackB 0:91420dff6791 32
JackB 0:91420dff6791 33 init();
JackB 0:91420dff6791 34 }
JackB 0:91420dff6791 35
JackB 0:91420dff6791 36 void NHD_0420DZW_OLED::init(void)
JackB 0:91420dff6791 37 {
JackB 0:91420dff6791 38 writeCommand(LCD_FUNCTION_SET);
JackB 0:91420dff6791 39 writeCommand(LCD_DISPLAY_OFF);
JackB 0:91420dff6791 40 writeCommand(LCD_CLEAR_DISPLAY);
JackB 0:91420dff6791 41 writeCommand(LCD_CURSOR_INCR);
JackB 0:91420dff6791 42 writeCommand(LCD_RETURN_HOME);
JackB 0:91420dff6791 43 writeCommand(LCD_DISPLAY_ON);
JackB 0:91420dff6791 44
JackB 0:91420dff6791 45 // custom characters
JackB 0:91420dff6791 46 // In the character generator RAM, the user can rewrite character patterns
JackB 0:91420dff6791 47 // For 5x8 dots, eight character patterns can be written
JackB 0:91420dff6791 48 // Store custom chars in LCD's CGRAM
JackB 0:91420dff6791 49 writeCommand(LCD_CGRAM(1));
JackB 0:91420dff6791 50 char CharacterBytes[] = CHARACTERBYTES;
JackB 0:91420dff6791 51 for (unsigned char Index = 0; Index < sizeof(CharacterBytes); Index++) {
JackB 0:91420dff6791 52 writeData(CharacterBytes[Index]);
JackB 0:91420dff6791 53 }
JackB 0:91420dff6791 54 }
JackB 0:91420dff6791 55
JackB 0:91420dff6791 56 void NHD_0420DZW_OLED::cls(void)
JackB 0:91420dff6791 57 {
JackB 0:91420dff6791 58 writeCommand(LCD_CLEAR_DISPLAY); // Clear display
JackB 0:91420dff6791 59 }
JackB 0:91420dff6791 60
JackB 0:91420dff6791 61 void NHD_0420DZW_OLED::cursorHome(void)
JackB 0:91420dff6791 62 {
JackB 0:91420dff6791 63 writeCommand(LCD_RETURN_HOME); // Clear display
JackB 0:91420dff6791 64 }
JackB 0:91420dff6791 65
JackB 0:91420dff6791 66 void NHD_0420DZW_OLED::writeCharacter(int column, int row, int c)
JackB 0:91420dff6791 67 {
JackB 0:91420dff6791 68 locate(column, row);
JackB 0:91420dff6791 69 writeData(c);
JackB 0:91420dff6791 70 }
JackB 0:91420dff6791 71
JackB 0:91420dff6791 72 void NHD_0420DZW_OLED::writeCharacter(char c)
JackB 0:91420dff6791 73 {
JackB 0:91420dff6791 74 writeData((int)c);
JackB 0:91420dff6791 75 }
JackB 0:91420dff6791 76
JackB 0:91420dff6791 77 void NHD_0420DZW_OLED::writeString(char *charString)
JackB 0:91420dff6791 78 {
JackB 0:91420dff6791 79 uint8_t length = strlen(charString);
JackB 0:91420dff6791 80 for (uint8_t i = 0; i < length; i++) {
JackB 0:91420dff6791 81 writeCharacter(charString[i]);
JackB 0:91420dff6791 82 }
JackB 0:91420dff6791 83 }
JackB 0:91420dff6791 84
JackB 0:91420dff6791 85 void NHD_0420DZW_OLED::writeString(int row, char *charString)
JackB 0:91420dff6791 86 {
JackB 0:91420dff6791 87 locate(0, row);
JackB 0:91420dff6791 88 writeString(charString);
JackB 0:91420dff6791 89 }
JackB 0:91420dff6791 90
JackB 0:91420dff6791 91 void NHD_0420DZW_OLED::writeString(int column, int row, char *charString)
JackB 0:91420dff6791 92 {
JackB 0:91420dff6791 93 locate(column, row);
JackB 0:91420dff6791 94 writeString(charString);
JackB 0:91420dff6791 95 }
JackB 0:91420dff6791 96
JackB 0:91420dff6791 97 void NHD_0420DZW_OLED::clearLine(int row)
JackB 0:91420dff6791 98 {
JackB 0:91420dff6791 99 int length = LCD_NUMBER_OF_CHARACTERS;
JackB 0:91420dff6791 100 locate(0, row);
JackB 0:91420dff6791 101 while(length--) {
JackB 0:91420dff6791 102 writeCharacter(' ');
JackB 0:91420dff6791 103 }
JackB 0:91420dff6791 104 locate(0, row);
JackB 0:91420dff6791 105 }
JackB 0:91420dff6791 106
JackB 0:91420dff6791 107 void NHD_0420DZW_OLED::clearRegion(int column, int row, int length)
JackB 0:91420dff6791 108 {
JackB 0:91420dff6791 109 locate(column, row);
JackB 0:91420dff6791 110 while(length--) {
JackB 0:91420dff6791 111 writeCharacter(' ');
JackB 0:91420dff6791 112 }
JackB 0:91420dff6791 113 locate(column, row);
JackB 0:91420dff6791 114 }
JackB 0:91420dff6791 115
JackB 0:91420dff6791 116 void NHD_0420DZW_OLED::locate(int column, int row)
JackB 0:91420dff6791 117 {
JackB 0:91420dff6791 118 if ((column > LCD_NUMBER_OF_CHARACTERS) || (row > LCD_NUMBER_OF_LINES))
JackB 0:91420dff6791 119 {
JackB 0:91420dff6791 120 return;
JackB 0:91420dff6791 121 }
JackB 0:91420dff6791 122 else
JackB 0:91420dff6791 123 {
JackB 0:91420dff6791 124 switch (row) {
JackB 0:91420dff6791 125 case 0:
JackB 0:91420dff6791 126 writeCommand(LCD_LINE_1 + column); /* command - position cursor at 0x00 (0x80 + 0x00 ) */
JackB 0:91420dff6791 127 break;
JackB 0:91420dff6791 128 case 1:
JackB 0:91420dff6791 129 writeCommand(LCD_LINE_2 + column); /* command - position cursor at 0x40 (0x80 + 0x00 ) */
JackB 0:91420dff6791 130 break;
JackB 0:91420dff6791 131 case 2:
JackB 0:91420dff6791 132 writeCommand(LCD_LINE_3 + column); /* command - position cursor at 0x40 (0x80 + 0x00 ) */
JackB 0:91420dff6791 133 break;
JackB 0:91420dff6791 134 case 3:
JackB 0:91420dff6791 135 writeCommand(LCD_LINE_4 + column); /* command - position cursor at 0x40 (0x80 + 0x00 ) */
JackB 0:91420dff6791 136 break;
JackB 0:91420dff6791 137 default:
JackB 0:91420dff6791 138 writeCommand(LCD_LINE_1 + column); /* command - position cursor at 0x00 (0x80 + 0x00 ) */
JackB 0:91420dff6791 139 break;
JackB 0:91420dff6791 140 }
JackB 0:91420dff6791 141 }
JackB 0:91420dff6791 142 }
JackB 0:91420dff6791 143
JackB 0:91420dff6791 144 void NHD_0420DZW_OLED::drawBar(int column, int row, int Value, int Max)
JackB 0:91420dff6791 145 {
JackB 0:91420dff6791 146 int Count = 0;
JackB 0:91420dff6791 147 int Characters = Max / 5;
JackB 0:91420dff6791 148 if (Value > Max)
JackB 0:91420dff6791 149 Value = Max;
JackB 0:91420dff6791 150 locate(column, row);
JackB 0:91420dff6791 151 // Print the characters
JackB 0:91420dff6791 152 while (Count < Characters)
JackB 0:91420dff6791 153 {
JackB 0:91420dff6791 154 if ((Value >= 6) && (Value <= Max))
JackB 0:91420dff6791 155 writeData('\6'); // *****
JackB 0:91420dff6791 156 else
JackB 0:91420dff6791 157 if ((Value == 0) || (Value > Max))
JackB 0:91420dff6791 158 writeData('\1'); // .....
JackB 0:91420dff6791 159 else
JackB 0:91420dff6791 160 writeData(Value+1); // ***..
JackB 0:91420dff6791 161 Value -= 5;
JackB 0:91420dff6791 162 Count++;
JackB 0:91420dff6791 163 }
JackB 0:91420dff6791 164 }
JackB 0:91420dff6791 165
JackB 0:91420dff6791 166 void NHD_0420DZW_OLED::writeCommand(int data)
JackB 0:91420dff6791 167 {
JackB 0:91420dff6791 168 waitBusy();
JackB 0:91420dff6791 169 writeSerial(LCD_COMMAND, LCD_WRITE, data);
JackB 0:91420dff6791 170 }
JackB 0:91420dff6791 171
JackB 0:91420dff6791 172 void NHD_0420DZW_OLED::writeData(int data)
JackB 0:91420dff6791 173 {
JackB 0:91420dff6791 174 // waitBusy();
JackB 0:91420dff6791 175 writeSerial(LCD_DATA, LCD_WRITE, data);
JackB 0:91420dff6791 176 }
JackB 0:91420dff6791 177
JackB 0:91420dff6791 178 int NHD_0420DZW_OLED::readAddress(void)
JackB 0:91420dff6791 179 {
JackB 0:91420dff6791 180 writeSerial(LCD_COMMAND, LCD_READ, 0x00); // Dummy read
JackB 0:91420dff6791 181 return (serialData(LCD_COMMAND, LCD_READ, 0x00, 0x00) >> 3) & 0x7F;
JackB 0:91420dff6791 182 }
JackB 0:91420dff6791 183
JackB 0:91420dff6791 184 void NHD_0420DZW_OLED::waitBusy(void)
JackB 0:91420dff6791 185 {
JackB 0:91420dff6791 186 while (readBusyFlag());
JackB 0:91420dff6791 187 }
JackB 0:91420dff6791 188
JackB 0:91420dff6791 189 int NHD_0420DZW_OLED::readBusyFlag(void)
JackB 0:91420dff6791 190 {
JackB 0:91420dff6791 191 return (serialInstruction(LCD_COMMAND, LCD_READ, 0x00, 0x00) >> 10);
JackB 0:91420dff6791 192 }
JackB 0:91420dff6791 193
JackB 0:91420dff6791 194 void NHD_0420DZW_OLED::writeSerial(int rs, int rw, int data)
JackB 0:91420dff6791 195 {
JackB 0:91420dff6791 196 // CSB ---|_________________________________________|----
JackB 0:91420dff6791 197 // SCL -----|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|------
JackB 0:91420dff6791 198 // SDI .....|RS0|RW0|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |....
JackB 0:91420dff6791 199 // SDO .............|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |....
JackB 0:91420dff6791 200 // RS=1: Data
JackB 0:91420dff6791 201 // RS=0: Command <---
JackB 0:91420dff6791 202 // RW=1: Read
JackB 0:91420dff6791 203 // RW=0: Write <---
JackB 0:91420dff6791 204 if (rs > 0) {
JackB 0:91420dff6791 205 data |= LCD_RS_BIT_MASK;
JackB 0:91420dff6791 206 }
JackB 0:91420dff6791 207 if (rw > 0) {
JackB 0:91420dff6791 208 data |= LCD_Rw_BIT_MASK;
JackB 0:91420dff6791 209 }
JackB 0:91420dff6791 210
JackB 0:91420dff6791 211 selectSerial(true);
JackB 0:91420dff6791 212 clockSerial(data, 10);
JackB 0:91420dff6791 213 selectSerial(false);
JackB 0:91420dff6791 214 }
JackB 0:91420dff6791 215
JackB 0:91420dff6791 216 int NHD_0420DZW_OLED::serialInstruction(int rs, int rw, int data1, int data2)
JackB 0:91420dff6791 217 {
JackB 0:91420dff6791 218 // CSB ---|_________________________________________________________________________________|----
JackB 0:91420dff6791 219 // SCL -----|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|------
JackB 0:91420dff6791 220 // SDI .....|RS0|RW1|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |RS |RW |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |....
JackB 0:91420dff6791 221 // SDO .............|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |D7 |D6 |....
JackB 0:91420dff6791 222 // RS=1: Data
JackB 0:91420dff6791 223 // RS=0: Command <---
JackB 0:91420dff6791 224 // RW=1: Read <---
JackB 0:91420dff6791 225 // RW=0: Write
JackB 0:91420dff6791 226 // Read Bussy Flag & Address BF AC6 AC5 AC4 AC3 AC2 AC1 AC0
JackB 0:91420dff6791 227 if (rs > 0) {
JackB 0:91420dff6791 228 data1 |= LCD_RS_BIT_MASK;
JackB 0:91420dff6791 229 data2 |= LCD_RS_BIT_MASK;
JackB 0:91420dff6791 230 }
JackB 0:91420dff6791 231 if (rw > 0) {
JackB 0:91420dff6791 232 data1 |= LCD_Rw_BIT_MASK;
JackB 0:91420dff6791 233 data2 |= LCD_Rw_BIT_MASK;
JackB 0:91420dff6791 234 }
JackB 0:91420dff6791 235
JackB 0:91420dff6791 236 selectSerial(true);
JackB 0:91420dff6791 237 clockSerial(data1, 10);
JackB 0:91420dff6791 238 int data = clockSerial(data2, 10);
JackB 0:91420dff6791 239 selectSerial(false);
JackB 0:91420dff6791 240 return data;
JackB 0:91420dff6791 241 }
JackB 0:91420dff6791 242
JackB 0:91420dff6791 243 int NHD_0420DZW_OLED::serialData(int rs, int rw, int data1, int data2)
JackB 0:91420dff6791 244 {
JackB 0:91420dff6791 245 // CSB ---|_________________________________________________________________________________|----
JackB 0:91420dff6791 246 // SCL -----|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|------
JackB 0:91420dff6791 247 // SDI .....|RS1|RW1|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |RS |RW |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |....
JackB 0:91420dff6791 248 // SDO .............|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |D7 |D6 |....
JackB 0:91420dff6791 249 // RS=1: Data <---
JackB 0:91420dff6791 250 // RS=0: Command
JackB 0:91420dff6791 251 // RW=1: Read <---
JackB 0:91420dff6791 252 // RW=0: Write
JackB 0:91420dff6791 253 // Read data from CGRAM or DDRAM
JackB 0:91420dff6791 254 if (rs > 0) {
JackB 0:91420dff6791 255 data1 |= LCD_RS_BIT_MASK;
JackB 0:91420dff6791 256 }
JackB 0:91420dff6791 257 if (rw > 0) {
JackB 0:91420dff6791 258 data1 |= LCD_Rw_BIT_MASK;
JackB 0:91420dff6791 259 }
JackB 0:91420dff6791 260
JackB 0:91420dff6791 261 selectSerial(true);
JackB 0:91420dff6791 262 clockSerial(data1, 10);
JackB 0:91420dff6791 263 int data = clockSerial(data2, 8);
JackB 0:91420dff6791 264 selectSerial(false);
JackB 0:91420dff6791 265 return data;
JackB 0:91420dff6791 266 }
JackB 0:91420dff6791 267
JackB 0:91420dff6791 268 int NHD_0420DZW_OLED::clockSerial(int dataOut, int bits)
JackB 0:91420dff6791 269 {
JackB 0:91420dff6791 270 int dataIn = 0;
JackB 0:91420dff6791 271 for (int bit = bits; bit > 0; bit--) {
JackB 0:91420dff6791 272 _lcd_scl = 0;
JackB 0:91420dff6791 273 if ((dataOut & (1 << (bit-1))) == 0) {
JackB 0:91420dff6791 274 _lcd_sdi = 0;
JackB 0:91420dff6791 275 } else {
JackB 0:91420dff6791 276 _lcd_sdi = 1;
JackB 0:91420dff6791 277 }
JackB 0:91420dff6791 278 // wait_us(LCD_CLOCK_PULSE_LENGTH);
JackB 0:91420dff6791 279 _lcd_scl = 1;
JackB 0:91420dff6791 280 dataIn |= _lcd_sdo;
JackB 0:91420dff6791 281 dataIn <<= 1;
JackB 0:91420dff6791 282 // wait_us(LCD_CLOCK_PULSE_LENGTH);
JackB 0:91420dff6791 283 }
JackB 0:91420dff6791 284 return dataIn;
JackB 0:91420dff6791 285 }
JackB 0:91420dff6791 286
JackB 0:91420dff6791 287 void NHD_0420DZW_OLED::selectSerial(bool select)
JackB 0:91420dff6791 288 {
JackB 0:91420dff6791 289 if (select)
JackB 0:91420dff6791 290 _lcd_csb = 0;
JackB 0:91420dff6791 291 else
JackB 0:91420dff6791 292 _lcd_csb = 1;
JackB 0:91420dff6791 293 // wait_us(LCD_CLOCK_PULSE_LENGTH);
JackB 0:91420dff6791 294 }
JackB 0:91420dff6791 295
JackB 0:91420dff6791 296 bool NHD_0420DZW_OLED::claim (FILE *stream) {
JackB 0:91420dff6791 297 if ( _path == NULL) {
JackB 0:91420dff6791 298 fprintf(stderr, "claim requires a name to be given in the instantioator of the TextDisplay instance!\r\n");
JackB 0:91420dff6791 299 return false;
JackB 0:91420dff6791 300 }
JackB 0:91420dff6791 301 if (freopen(_path, "w", stream) == NULL) {
JackB 0:91420dff6791 302 // Failed, should not happen
JackB 0:91420dff6791 303 return false;
JackB 0:91420dff6791 304 }
JackB 0:91420dff6791 305 // make sure we use line buffering
JackB 0:91420dff6791 306 setvbuf(stdout, NULL, _IOLBF, LCD_NUMBER_OF_CHARACTERS);
JackB 0:91420dff6791 307 return true;
JackB 0:91420dff6791 308 }