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 <iostream> 26 #include <string> 27 #include <stdexcept> 28 #include <unistd.h> 29 #include <stdlib.h> 30 #include <stdio.h> 31 #include <string.h> 32 33 #include "st7735.h" 34 35 using namespace upm; 36 37 ST7735::ST7735 (uint8_t csLCD, uint8_t cSD, uint8_t rs, uint8_t rst) 38 : GFX (160, 128, m_map, font), m_csLCDPinCtx(csLCD), m_cSDPinCtx(cSD), 39 m_rSTPinCtx(rst), m_rSPinCtx(rs), m_spi(0) { 40 41 initModule (); 42 configModule (); 43 } 44 45 void 46 ST7735::initModule () { 47 mraa::Result error = mraa::SUCCESS; 48 49 m_height = 160; 50 m_width = 128; 51 52 m_spi.frequency(15 * 1000000); 53 54 error = m_csLCDPinCtx.dir(mraa::DIR_OUT); 55 if (error != mraa::SUCCESS) { 56 mraa::printError (error); 57 } 58 59 error = m_cSDPinCtx.dir(mraa::DIR_OUT); 60 if (error != mraa::SUCCESS) { 61 mraa::printError (error); 62 } 63 64 error = m_rSTPinCtx.dir(mraa::DIR_OUT); 65 if (error != mraa::SUCCESS) { 66 mraa::printError (error); 67 } 68 69 error = m_rSPinCtx.dir(mraa::DIR_OUT); 70 if (error != mraa::SUCCESS) { 71 mraa::printError (error); 72 } 73 74 error = m_spi.frequency(15 * 1000000); 75 if (error != mraa::SUCCESS) { 76 mraa::printError (error); 77 } 78 79 lcdCSOn (); 80 } 81 82 void 83 ST7735::write (uint8_t value) { 84 rsLOW (); 85 m_spi.writeByte(value); 86 } 87 88 void 89 ST7735::data (uint8_t value) { 90 rsHIGH (); 91 m_spi.writeByte(value); 92 } 93 94 void 95 ST7735::executeCMDList(const uint8_t *addr) { 96 uint8_t numCommands, numArgs; 97 uint16_t ms; 98 99 numCommands = *(addr++); // Number of commands to follow 100 while(numCommands--) { // For each command... 101 write (*(addr++)); // Read, issue command 102 numArgs = *(addr++); // Number of args to follow 103 ms = numArgs & DELAY; // If hibit set, delay follows args 104 numArgs &= ~DELAY; // Mask out delay bit 105 while(numArgs--) { // For each argument... 106 data (*(addr++)); // Read, issue argument 107 } 108 109 if(ms) { 110 ms = *(addr++); // Read post-command delay time (ms) 111 if (ms == 255) { 112 ms = 500; // If 255, delay for 500 ms 113 } 114 usleep (ms * 1000); 115 } 116 } 117 } 118 119 void 120 ST7735::setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) { 121 uint8_t colstart, rowstart; 122 colstart = rowstart = 0; 123 124 write (ST7735_CASET); // Column addr set 125 126 rsHIGH (); 127 m_spiBuffer[0] = 0x00; 128 m_spiBuffer[1] = x0 + colstart; // XSTART 129 m_spiBuffer[2] = 0x00; 130 m_spiBuffer[3] = x1 + colstart; // XEND 131 m_spi.write(m_spiBuffer, 4); 132 133 write (ST7735_RASET); // Row addr set 134 135 rsHIGH (); 136 m_spiBuffer[0] = 0x00; 137 m_spiBuffer[1] = y0 + rowstart; // YSTART 138 m_spiBuffer[2] = 0x00; 139 m_spiBuffer[3] = y1 + rowstart; // YEND 140 m_spi.write(m_spiBuffer, 4); 141 142 write (ST7735_RAMWR); // write to RAM 143 } 144 145 void 146 ST7735::drawPixel(int16_t x, int16_t y, uint16_t color) { 147 if (mraa::SUCCESS != setPixel (x, y, color)) { 148 return; 149 } 150 151 refresh (); 152 } 153 154 void 155 ST7735::refresh () { 156 rsHIGH (); 157 158 int fragmentSize = m_height * m_width * 2 / 20; 159 for (int fragment = 0; fragment < 20; fragment++) { 160 m_spi.write(&m_map[fragment * fragmentSize], fragmentSize); 161 } 162 } 163 164 void 165 ST7735::configModule() { 166 rsHIGH (); 167 lcdCSOff (); 168 lcdCSOn (); 169 170 m_rSTPinCtx.write(HIGH); 171 usleep (500000); 172 m_rSTPinCtx.write(LOW); 173 usleep (500000); 174 m_rSTPinCtx.write(HIGH); 175 usleep (500000); 176 177 executeCMDList (Rcmd1); 178 executeCMDList (Rcmd2red); 179 executeCMDList (Rcmd3); 180 181 write (ST7735_MADCTL); 182 data (0xC0); 183 184 setAddrWindow (0, 0, m_width - 1, m_height - 1); 185 186 fillScreen (ST7735_BLACK); 187 refresh (); 188 } 189 190 mraa::Result 191 ST7735::lcdCSOn () { 192 mraa::Result error = mraa::SUCCESS; 193 194 error = m_csLCDPinCtx.write(LOW); 195 if (error != mraa::SUCCESS) { 196 mraa::printError (error); 197 } 198 199 error = m_cSDPinCtx.write(HIGH); 200 if (error != mraa::SUCCESS) { 201 mraa::printError (error); 202 } 203 204 return error; 205 } 206 207 mraa::Result 208 ST7735::lcdCSOff () { 209 mraa::Result error = mraa::SUCCESS; 210 211 error = m_csLCDPinCtx.write(HIGH); 212 if (error != mraa::SUCCESS) { 213 mraa::printError (error); 214 } 215 216 return error; 217 } 218 219 mraa::Result 220 ST7735::sdCSOn () { 221 mraa::Result error = mraa::SUCCESS; 222 223 error = m_cSDPinCtx.write(LOW); 224 if (error != mraa::SUCCESS) { 225 mraa::printError (error); 226 } 227 228 error = m_csLCDPinCtx.write(HIGH); 229 if (error != mraa::SUCCESS) { 230 mraa::printError (error); 231 } 232 233 return error; 234 } 235 236 mraa::Result 237 ST7735::sdCSOff () { 238 mraa::Result error = mraa::SUCCESS; 239 240 error = m_cSDPinCtx.write(HIGH); 241 if (error != mraa::SUCCESS) { 242 mraa::printError (error); 243 } 244 245 return error; 246 } 247 248 mraa::Result 249 ST7735::rsHIGH () { 250 mraa::Result error = mraa::SUCCESS; 251 252 error = m_rSPinCtx.write(HIGH); 253 if (error != mraa::SUCCESS) { 254 mraa::printError (error); 255 } 256 257 return error; 258 } 259 260 mraa::Result 261 ST7735::rsLOW () { 262 mraa::Result error = mraa::SUCCESS; 263 264 error = m_rSPinCtx.write(LOW); 265 if (error != mraa::SUCCESS) { 266 mraa::printError (error); 267 } 268 269 return error; 270 } 271