Library for New Haven NHD_0420DZW OLED

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NHD_0420DZW_OLED.cpp Source File

NHD_0420DZW_OLED.cpp

Go to the documentation of this file.
00001 /**
00002 * @file NHD_0420DZW_OLED.cpp
00003 * @brief This C++ file contains the functions to interface the New Haven
00004 * NHD_0420DZW display using a 4-wire software spi bus bus.
00005 * 10-bit SPI operation, ie spi.format(10, 3), does not work with Nucleo-F746ZG,
00006 * it remains 8-bit, so unfortunately I had to do bit banging
00007 * @author Jack Berkhout
00008 *
00009 * @date 2016-10-21
00010 */
00011 #include "NHD_0420DZW_OLED.h"
00012 #include "mbed.h"
00013 
00014 NHD_0420DZW_OLED::NHD_0420DZW_OLED(PinName sdi, PinName sdo, PinName scl, PinName csb, const char *name) : 
00015   Stream(name), _lcd_sdi(sdi), _lcd_sdo(sdo), _lcd_scl(scl), _lcd_csb(csb)
00016 //  TextDisplay(name), _lcd_sdi(sdi), _lcd_sdo(sdo), _lcd_scl(scl), _lcd_csb(csb)
00017 {
00018     _lcd_csb = 1;
00019     _lcd_scl = 1;
00020     _lcd_sdi = 0;
00021     
00022     // --- claim ---
00023     _row = 0;
00024     _column = 0;
00025     if (name == NULL) {
00026         _path = NULL;
00027     } else {
00028         _path = new char[strlen(name) + 2];
00029         sprintf(_path, "/%s", name);
00030     }
00031     // -------------
00032         
00033     init();
00034 }
00035 
00036 void NHD_0420DZW_OLED::init(void)
00037 {
00038     writeCommand(LCD_FUNCTION_SET);
00039     writeCommand(LCD_DISPLAY_OFF);
00040     writeCommand(LCD_CLEAR_DISPLAY);
00041     writeCommand(LCD_CURSOR_INCR);
00042     writeCommand(LCD_RETURN_HOME);
00043     writeCommand(LCD_DISPLAY_ON);
00044 
00045     // custom characters
00046     // In the character generator RAM, the user can rewrite character patterns
00047     // For 5x8 dots, eight character patterns can be written
00048     // Store custom chars in LCD's CGRAM
00049     writeCommand(LCD_CGRAM(1));
00050     char CharacterBytes[] = CHARACTERBYTES;
00051     for (unsigned char Index = 0; Index < sizeof(CharacterBytes); Index++) {
00052         writeData(CharacterBytes[Index]);
00053     }
00054 }
00055 
00056 void NHD_0420DZW_OLED::cls(void)
00057 {
00058     writeCommand(LCD_CLEAR_DISPLAY);   // Clear display
00059 }
00060 
00061 void NHD_0420DZW_OLED::cursorHome(void)
00062 {
00063     writeCommand(LCD_RETURN_HOME);   // Clear display
00064 }
00065 
00066 void NHD_0420DZW_OLED::writeCharacter(int column, int row, int c)
00067 {
00068     locate(column, row);
00069     writeData(c);
00070 }
00071 
00072 void NHD_0420DZW_OLED::writeCharacter(char c)
00073 {
00074     writeData((int)c);
00075 }
00076 
00077 void NHD_0420DZW_OLED::writeString(char *charString)
00078 {
00079     uint8_t length = strlen(charString);
00080     for (uint8_t i = 0; i < length; i++) {
00081         writeCharacter(charString[i]);
00082     }
00083 }
00084 
00085 void NHD_0420DZW_OLED::writeString(int row, char *charString)
00086 {
00087     locate(0, row);
00088     writeString(charString);
00089 }
00090 
00091 void NHD_0420DZW_OLED::writeString(int column, int row, char *charString)
00092 {
00093     locate(column, row);
00094     writeString(charString);
00095 }
00096 
00097 void NHD_0420DZW_OLED::clearLine(int row)
00098 {
00099     int length = LCD_NUMBER_OF_CHARACTERS;
00100     locate(0, row);
00101     while(length--) {
00102         writeCharacter(' ');
00103     }
00104     locate(0, row);
00105 }
00106 
00107 void NHD_0420DZW_OLED::clearRegion(int column, int row, int length)
00108 {
00109     locate(column, row);
00110     while(length--) {
00111         writeCharacter(' ');
00112     }
00113     locate(column, row);
00114 }
00115 
00116 void NHD_0420DZW_OLED::locate(int column, int row)
00117 {
00118     if ((column > LCD_NUMBER_OF_CHARACTERS) || (row > LCD_NUMBER_OF_LINES))
00119     {
00120         return;
00121     }
00122     else
00123     {
00124         switch (row) {
00125             case 0:
00126                 writeCommand(LCD_LINE_1 + column);   /* command - position cursor at 0x00 (0x80 + 0x00 ) */
00127                 break;
00128             case 1:
00129                 writeCommand(LCD_LINE_2 + column);   /* command - position cursor at 0x40 (0x80 + 0x00 ) */
00130                 break;
00131             case 2:
00132                 writeCommand(LCD_LINE_3 + column);   /* command - position cursor at 0x40 (0x80 + 0x00 ) */
00133                 break;
00134             case 3:
00135                 writeCommand(LCD_LINE_4 + column);   /* command - position cursor at 0x40 (0x80 + 0x00 ) */
00136                 break;
00137             default:
00138                 writeCommand(LCD_LINE_1 + column);   /* command - position cursor at 0x00 (0x80 + 0x00 ) */
00139                 break;
00140         }
00141     }
00142 }
00143 
00144 void NHD_0420DZW_OLED::drawBar(int column, int row, int Value, int Max)
00145 {
00146   int Count = 0;
00147   int Characters = Max / 5;
00148   if (Value > Max)
00149     Value = Max;
00150   locate(column, row);
00151   // Print the characters
00152   while (Count < Characters)
00153   {
00154     if ((Value >= 6) && (Value <= Max))
00155       writeData('\6');  // *****
00156     else
00157     if ((Value == 0) || (Value > Max))
00158       writeData('\1');  // .....
00159     else
00160       writeData(Value+1);  // ***..
00161     Value -= 5;
00162     Count++;
00163   }
00164 }
00165 
00166 void NHD_0420DZW_OLED::writeCommand(int data)
00167 {
00168     waitBusy();
00169     writeSerial(LCD_COMMAND, LCD_WRITE, data);
00170 }
00171 
00172 void NHD_0420DZW_OLED::writeData(int data)
00173 {
00174 //    waitBusy();
00175     writeSerial(LCD_DATA, LCD_WRITE, data);
00176 }
00177 
00178 int NHD_0420DZW_OLED::readAddress(void)
00179 {
00180     writeSerial(LCD_COMMAND, LCD_READ, 0x00);   // Dummy read
00181     return (serialData(LCD_COMMAND, LCD_READ, 0x00, 0x00) >> 3) & 0x7F;
00182 }
00183 
00184 void NHD_0420DZW_OLED::waitBusy(void)
00185 {
00186     while (readBusyFlag());
00187 }
00188 
00189 int NHD_0420DZW_OLED::readBusyFlag(void)
00190 {
00191     return (serialInstruction(LCD_COMMAND, LCD_READ, 0x00, 0x00) >> 10);
00192 }
00193 
00194 void NHD_0420DZW_OLED::writeSerial(int rs, int rw, int data)
00195 {
00196     // CSB ---|_________________________________________|----
00197     // SCL -----|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|------
00198     // SDI .....|RS0|RW0|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |....
00199     // SDO .............|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |....
00200     // RS=1: Data
00201     // RS=0: Command <---
00202     // RW=1: Read
00203     // RW=0: Write <---
00204     if (rs > 0) {
00205         data |= LCD_RS_BIT_MASK;
00206     }
00207     if (rw > 0) {
00208         data |= LCD_Rw_BIT_MASK;
00209     }
00210 
00211     selectSerial(true);
00212     clockSerial(data, 10);
00213     selectSerial(false);
00214 }
00215 
00216 int NHD_0420DZW_OLED::serialInstruction(int rs, int rw, int data1, int data2)
00217 {
00218     // CSB ---|_________________________________________________________________________________|----
00219     // SCL -----|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|------
00220     // SDI .....|RS0|RW1|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |RS |RW |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |....
00221     // SDO .............|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |D7 |D6 |....
00222     // RS=1: Data
00223     // RS=0: Command <---
00224     // RW=1: Read <---
00225     // RW=0: Write
00226     // Read Bussy Flag & Address BF AC6 AC5 AC4 AC3 AC2 AC1 AC0
00227     if (rs > 0) {
00228         data1 |= LCD_RS_BIT_MASK;
00229         data2 |= LCD_RS_BIT_MASK;
00230     }
00231     if (rw > 0) {
00232         data1 |= LCD_Rw_BIT_MASK;
00233         data2 |= LCD_Rw_BIT_MASK;
00234     }
00235 
00236     selectSerial(true);
00237     clockSerial(data1, 10);
00238     int data = clockSerial(data2, 10);
00239     selectSerial(false);
00240     return data;
00241 }
00242 
00243 int NHD_0420DZW_OLED::serialData(int rs, int rw, int data1, int data2)
00244 {
00245     // CSB ---|_________________________________________________________________________________|----
00246     // SCL -----|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|------
00247     // SDI .....|RS1|RW1|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |RS |RW |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |....
00248     // SDO .............|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |D7 |D6 |....
00249     // RS=1: Data <---
00250     // RS=0: Command
00251     // RW=1: Read <---
00252     // RW=0: Write
00253     // Read data from CGRAM or DDRAM
00254     if (rs > 0) {
00255         data1 |= LCD_RS_BIT_MASK;
00256     }
00257     if (rw > 0) {
00258         data1 |= LCD_Rw_BIT_MASK;
00259     }
00260 
00261     selectSerial(true);
00262     clockSerial(data1, 10);
00263     int data = clockSerial(data2, 8);
00264     selectSerial(false);
00265     return data;
00266 }
00267 
00268 int NHD_0420DZW_OLED::clockSerial(int dataOut, int bits)
00269 {
00270     int dataIn = 0;
00271     for (int bit = bits; bit > 0; bit--) {
00272         _lcd_scl = 0;
00273         if ((dataOut & (1 << (bit-1))) == 0) {
00274             _lcd_sdi = 0;
00275         } else {
00276             _lcd_sdi = 1;
00277         }
00278 //        wait_us(LCD_CLOCK_PULSE_LENGTH);
00279         _lcd_scl = 1;
00280         dataIn |= _lcd_sdo;
00281         dataIn <<= 1;
00282 //        wait_us(LCD_CLOCK_PULSE_LENGTH);
00283     }
00284     return dataIn;
00285 }
00286 
00287 void NHD_0420DZW_OLED::selectSerial(bool select)
00288 {
00289     if (select)
00290         _lcd_csb = 0;
00291     else
00292         _lcd_csb = 1;
00293 //    wait_us(LCD_CLOCK_PULSE_LENGTH);
00294 }
00295 
00296 bool NHD_0420DZW_OLED::claim (FILE *stream) {
00297     if ( _path == NULL) {
00298         fprintf(stderr, "claim requires a name to be given in the instantioator of the TextDisplay instance!\r\n");
00299         return false;
00300     }
00301     if (freopen(_path, "w", stream) == NULL) {
00302         // Failed, should not happen
00303         return false;
00304     }
00305     // make sure we use line buffering
00306     setvbuf(stdout, NULL, _IOLBF, LCD_NUMBER_OF_CHARACTERS);
00307     return true;
00308 }