1 /* 2 * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha (at) intel.com> 3 * Copyright (c) 2014 Intel Corporation. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be 14 * included in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 #include <stdexcept> 26 #include <string> 27 #include <unistd.h> 28 29 #include "hd44780_bits.h" 30 #include "ssd1308.h" 31 32 using namespace upm; 33 34 SSD1308::SSD1308(int bus_in, int addr_in) : m_i2c_lcd_control(bus_in) 35 { 36 m_lcd_control_address = addr_in; 37 m_name = "SSD1308"; 38 39 mraa::Result error = m_i2c_lcd_control.address(m_lcd_control_address); 40 if (error != mraa::SUCCESS) { 41 throw std::invalid_argument(std::string(__FUNCTION__) + 42 ": I2c.address() failed"); 43 return; 44 } 45 46 m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_OFF); // display off 47 usleep(4500); 48 m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_ON); // display on 49 usleep(4500); 50 setNormalDisplay(); // set to normal display '1' is ON 51 52 clear(); 53 setAddressingMode(PAGE); 54 } 55 56 SSD1308::~SSD1308() 57 { 58 } 59 60 mraa::Result 61 SSD1308::draw(uint8_t* data, int bytes) 62 { 63 mraa::Result error = mraa::SUCCESS; 64 65 setAddressingMode(HORIZONTAL); 66 for (int idx = 0; idx < bytes; idx++) { 67 m_i2c_lcd_control.writeReg(LCD_DATA, data[idx]); 68 } 69 70 return error; 71 } 72 73 /* 74 * ************** 75 * virtual area 76 * ************** 77 */ 78 mraa::Result 79 SSD1308::write(std::string msg) 80 { 81 mraa::Result error = mraa::SUCCESS; 82 uint8_t data[2] = { 0x40, 0 }; 83 84 setAddressingMode(PAGE); 85 for (std::string::size_type i = 0; i < msg.size(); ++i) { 86 writeChar(msg[i]); 87 } 88 89 return error; 90 } 91 92 mraa::Result 93 SSD1308::setCursor(int row, int column) 94 { 95 mraa::Result error = mraa::SUCCESS; 96 97 error = m_i2c_lcd_control.writeReg(LCD_CMD, BASE_PAGE_START_ADDR + row); // set page address 98 error = m_i2c_lcd_control.writeReg(LCD_CMD, 99 BASE_LOW_COLUMN_ADDR + (8 * column & 0x0F)); // set column 100 // lower address 101 error = m_i2c_lcd_control.writeReg(LCD_CMD, 102 BASE_HIGH_COLUMN_ADDR + 103 ((8 * column >> 4) & 0x0F)); // set column higher address 104 105 return error; 106 } 107 108 mraa::Result 109 SSD1308::clear() 110 { 111 mraa::Result error = mraa::SUCCESS; 112 uint8_t columnIdx, rowIdx; 113 114 m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_OFF); // display off 115 for (rowIdx = 0; rowIdx < 8; rowIdx++) { 116 setCursor(rowIdx, 0); 117 118 // clear all columns 119 for (columnIdx = 0; columnIdx < 16; columnIdx++) { 120 writeChar(' '); 121 } 122 } 123 m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_ON); // display on 124 home(); 125 126 return mraa::SUCCESS; 127 } 128 129 mraa::Result 130 SSD1308::home() 131 { 132 return setCursor(0, 0); 133 } 134 135 /* 136 * ************** 137 * private area 138 * ************** 139 */ 140 mraa::Result 141 SSD1308::writeChar(uint8_t value) 142 { 143 mraa::Result rv; 144 if (value < 0x20 || value > 0x7F) { 145 value = 0x20; // space 146 } 147 148 for (uint8_t idx = 0; idx < 8; idx++) { 149 rv = m_i2c_lcd_control.writeReg(LCD_DATA, BasicFont[value - 32][idx]); 150 } 151 152 return rv; 153 } 154 155 mraa::Result 156 SSD1308::setNormalDisplay() 157 { 158 return m_i2c_lcd_control.writeReg(LCD_CMD, 159 DISPLAY_CMD_SET_NORMAL_1308); // set to normal display '1' is 160 // ON 161 } 162 163 mraa::Result 164 SSD1308::setAddressingMode(displayAddressingMode mode) 165 { 166 mraa::Result rv; 167 rv =m_i2c_lcd_control.writeReg(LCD_CMD, DISPLAY_CMD_MEM_ADDR_MODE); // set addressing mode 168 rv =m_i2c_lcd_control.writeReg(LCD_CMD, mode); // set page addressing mode 169 return rv; 170 } 171