MAXREFDES143#: DeepCover Embedded Security in IoT Authenticated Sensing & Notification
Dependencies: MaximInterface mbed
Display.cpp
00001 /******************************************************************************* 00002 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 *******************************************************************************/ 00032 00033 #include <sstream> 00034 #include <I2C.h> 00035 #include <wait_api.h> 00036 #include "Display.hpp" 00037 00038 // LCD Commands 00039 // If the RS bit is set to logic 1, these display bytes are stored in the 00040 // display RAM at the address specified by the data pointer. The data pointer is 00041 // automatically updated and the data is directed to the intended ST7036i 00042 // device. If the RS bit of the last control byte is set to logic 0, these 00043 // command bytes will be decoded and the setting of the device will be changed 00044 // according to the received commands. 00045 enum LCD_Commands { 00046 // Only one control byte will be sent. 00047 // Only a stream of data bytes is allowed to follow. 00048 ControlByte = 0x00, 00049 // Only one control byte will be sent with the RS bit set. 00050 // Only a stream of data bytes is allowed to follow. 00051 ControlByte_RS_Set = 0x40, 00052 // Another control byte will follow, unless an I2C Stop condition is received. 00053 ControlBytes = 0x80, 00054 // RS Set and another control byte will follow, unless an I2C Stop condition 00055 // is received. 00056 ControlBytes_RS_Set =0xC0 00057 }; 00058 00059 // LCD Instructions 00060 enum LCD_Instructions { 00061 ClearDisplay = 0x01, 00062 Display_OFF = 0x08, // Display off 00063 Display_ON = 0x0C, // Display on, cursor off, cursor position off 00064 ReturnHome = 0x02, 00065 SetDdramAddress = 0x80 00066 }; 00067 00068 // LED Driver Port Registers 00069 // Initial port state 0x80 00070 enum LED_Driver_Ports { 00071 P1 = 0x01, 00072 P2 = 0x02, // Blue LED 00073 P3 = 0x03, // Green LED 00074 P4 = 0x04 // Red LED 00075 }; 00076 00077 // Convert a byte color value into the representation used by the MAX7306 PWM registers 00078 static uint8_t convertColorToPwmRegVal(uint8_t color) { 00079 const uint8_t staticOffRegVal = 0x80; // LED is static off by setting to input 00080 const uint8_t staticOnRegVal = 0x00; // LED is static on 00081 const uint8_t minOnRegVal = 0x01; // LED on for minimum duty cycle 00082 00083 uint8_t regVal; 00084 if (color == 0x00) // Use static off for no color 00085 { 00086 regVal = staticOffRegVal; 00087 } else if (color == 0xFF) // Use static on for full color 00088 { 00089 regVal = staticOnRegVal; 00090 } else // Use standard PWN for all other values 00091 { 00092 // The 3 least significant bits cannot be rendered with the MAX7306 00093 regVal = color >> 3; 00094 if (regVal == staticOnRegVal) 00095 regVal = minOnRegVal; 00096 } 00097 return regVal; 00098 } 00099 00100 Display::Display (mbed::I2C & I2C_intf, uint8_t LCD_I2C_addr, 00101 uint8_t LED_driver_I2C_addr) 00102 : m_I2C_intf(I2C_intf), m_LCD_I2C_addr(LCD_I2C_addr), 00103 m_LED_driver_I2C_addr(LED_driver_I2C_addr) {} 00104 00105 void Display::initialize() { 00106 initializeLCD(); 00107 initializeLED_Driver(); 00108 } 00109 00110 void Display::initializeLED_Driver() { 00111 const uint8_t Configuration26 = 0x26; // Intial port state 0xEC 00112 const uint8_t Configuration27 = 0x27; // Intial port state 0x8F 00113 00114 // Intial mode 00115 // Write to Configuration Register 0x26 00116 m_I2C_intf.start(); 00117 m_I2C_intf.write(m_LED_driver_I2C_addr); 00118 m_I2C_intf.write(Configuration26); 00119 // RST resets registers to power-on-reset state 00120 // RST does reset PWM/blink counters, 00121 m_I2C_intf.write(0x1F); 00122 m_I2C_intf.stop(); 00123 00124 // Write to Configuration Register 0x27 00125 m_I2C_intf.start(); 00126 m_I2C_intf.write(m_LED_driver_I2C_addr); 00127 m_I2C_intf.write(Configuration27); 00128 // Enable bus time out, and set P1, P2, P3 to be controlled by their registers 00129 // (0x01, 0x02, 0x03) 00130 m_I2C_intf.write(0x0E); 00131 m_I2C_intf.stop(); 00132 } 00133 00134 void Display::setBackLightColor(const Color & color) { 00135 // Red 00136 m_I2C_intf.start(); 00137 m_I2C_intf.write(m_LED_driver_I2C_addr); 00138 m_I2C_intf.write(P4); 00139 m_I2C_intf.write(convertColorToPwmRegVal(color.R)); 00140 m_I2C_intf.stop(); 00141 00142 // Green 00143 m_I2C_intf.start(); 00144 m_I2C_intf.write(m_LED_driver_I2C_addr); 00145 m_I2C_intf.write(P3); 00146 m_I2C_intf.write(convertColorToPwmRegVal(color.G)); 00147 m_I2C_intf.stop(); 00148 00149 // Blue 00150 m_I2C_intf.start(); 00151 m_I2C_intf.write(m_LED_driver_I2C_addr); 00152 m_I2C_intf.write(P2); 00153 m_I2C_intf.write(convertColorToPwmRegVal(color.B)); 00154 m_I2C_intf.stop(); 00155 } 00156 00157 void Display::clearLine(Line line) { 00158 writeCompleteLine("", line); 00159 setCursorPosition(line); 00160 } 00161 00162 void Display::clearDisplay() { 00163 m_I2C_intf.start(); 00164 m_I2C_intf.write(m_LCD_I2C_addr); 00165 m_I2C_intf.write(ControlByte); //No more control bytes will be sent 00166 m_I2C_intf.write(ClearDisplay); 00167 m_I2C_intf.stop(); 00168 } 00169 00170 void Display::initializeLCD() { 00171 m_I2C_intf.start(); 00172 m_I2C_intf.write(m_LCD_I2C_addr); 00173 m_I2C_intf.write(ControlByte); // No more control bytes will be sent 00174 // Function Set IS[2:1] = 0,0 (&h38 = Single height font, 0x3C = double height font) 00175 m_I2C_intf.write(0x38); 00176 m_I2C_intf.write(0x39); //Function Set IS[2:1] = (0,1) 00177 // When IS[2:1]=(0,0): normal instruction be selected(refer instruction table 0) 00178 // When IS[2:1]=(0,1): extension instruction be selected(refer instruction table 1) 00179 // When IS[2:1]=(1,0): extension instruction be selected(refer instruction table 2) 00180 m_I2C_intf.write(0x14); // BIAS SET 00181 m_I2C_intf.write(0x70); // CONTRAST (was 0x78) 00182 m_I2C_intf.write(0x5E); // POWER/ICON CONTROL/CONTRAST (upper two bits) 00183 m_I2C_intf.write(0x6D); // FOLLOWER CONTROL 00184 m_I2C_intf.stop(); 00185 wait_ms(200); // Wait for power stable 00186 m_I2C_intf.start(); 00187 m_I2C_intf.write(m_LCD_I2C_addr); 00188 m_I2C_intf.write(ControlByte); // No more control bytes will be sent 00189 m_I2C_intf.write(Display_ON); // Display on, cursor on, cursor position on 00190 m_I2C_intf.write(ClearDisplay); // Clear Display 00191 m_I2C_intf.write(0x06); // ENTRY MODE 00192 m_I2C_intf.stop(); 00193 } 00194 00195 void Display::writeCharacter(uint8_t character) { 00196 m_I2C_intf.start(); 00197 m_I2C_intf.write(m_LCD_I2C_addr); 00198 m_I2C_intf.write(ControlByte_RS_Set); // No more control bytes will be sent 00199 m_I2C_intf.write(character); // Display on, cursor on, cursor position on 00200 m_I2C_intf.stop(); 00201 } 00202 00203 void Display::writeText(const std::string & text) { 00204 const char RETURN_CHAR = 0x16; 00205 00206 size_t length = text.length(); 00207 if (length > lineLength) 00208 length = lineLength; 00209 00210 //Write to LCD 00211 m_I2C_intf.start(); 00212 m_I2C_intf.write(m_LCD_I2C_addr); 00213 m_I2C_intf.write(ControlByte_RS_Set); 00214 00215 for (size_t i = 0; i < length; i++) { 00216 if (text[i] != RETURN_CHAR) 00217 m_I2C_intf.write(text[i]); 00218 } 00219 00220 m_I2C_intf.stop(); 00221 } 00222 00223 void Display::setCursorPosition(Line line, size_t position) { 00224 // Set to last line character for values outside the upper bound 00225 if (position > (lineLength - 1)) 00226 position = (lineLength - 1); 00227 00228 m_I2C_intf.start(); 00229 m_I2C_intf.write(m_LCD_I2C_addr); 00230 m_I2C_intf.write(ControlByte); // No more control bytes will be sent 00231 if (line == SecondLine) // Offset for second line 00232 position += 0x40; 00233 m_I2C_intf.write(SetDdramAddress | position); 00234 m_I2C_intf.stop(); 00235 } 00236 00237 void Display::writeLine(const std::string & text, Line line) { 00238 setCursorPosition(line); 00239 writeText(text); 00240 } 00241 00242 void Display::writeCompleteLine(const std::string & text, Line line) { 00243 // Add padding to user's string 00244 std::string writeText(text); 00245 if (writeText.length() < lineLength) 00246 writeText.append(lineLength - writeText.length(), ' '); 00247 00248 writeLine(writeText, line); 00249 } 00250 00251 void Display::writeMessage(const std::string & message) { 00252 if (message.length() > lineLength) { 00253 // Find split point 00254 std::istringstream messageStream(message); 00255 std::string word; 00256 size_t splitIndex = 0; 00257 do { 00258 if (word.length() > 0) 00259 splitIndex += (word.length() + 1); 00260 std::getline(messageStream, word, ' '); 00261 } while ((splitIndex + word.length()) <= lineLength); 00262 if (splitIndex == 0) // First word is too long 00263 { 00264 writeCompleteLine(message.substr(0, lineLength), FirstLine); 00265 writeCompleteLine(message.substr(lineLength), SecondLine); 00266 } else { 00267 writeCompleteLine(message.substr(0, splitIndex - 1), FirstLine); 00268 writeCompleteLine(message.substr(splitIndex), SecondLine); 00269 } 00270 } else { 00271 writeCompleteLine(message, FirstLine); 00272 writeCompleteLine("", SecondLine); 00273 } 00274 }
Generated on Wed Jul 13 2022 21:31:02 by 1.7.2