Home | History | Annotate | Download | only in st7735
      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