1/* 2 * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@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 35using namespace upm; 36 37ST7735::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 45void 46ST7735::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 82void 83ST7735::write (uint8_t value) { 84 rsLOW (); 85 m_spi.writeByte(value); 86} 87 88void 89ST7735::data (uint8_t value) { 90 rsHIGH (); 91 m_spi.writeByte(value); 92} 93 94void 95ST7735::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 119void 120ST7735::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 145void 146ST7735::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 154void 155ST7735::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 164void 165ST7735::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 190mraa::Result 191ST7735::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 207mraa::Result 208ST7735::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 219mraa::Result 220ST7735::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 236mraa::Result 237ST7735::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 248mraa::Result 249ST7735::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 260mraa::Result 261ST7735::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