Interface for Sharp LS012B7DD01 TFT-LCD

Dependents:   MAX32630FTHR_iButton_uSD_Logger

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Sharp_LS012B7DD01.cpp Source File

Sharp_LS012B7DD01.cpp

00001 /*******************************************************************************
00002 * The MIT License (MIT)
00003 *
00004 * Copyright (c) 2016 j3
00005 *
00006 * Permission is hereby granted, free of charge, to any person obtaining a copy 
00007 * of this software and associated documentation files (the "Software"), to deal
00008 * in the Software without restriction, including without limitation the rights 
00009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
00010 * copies of the Software, and to permit persons to whom the Software is 
00011 * furnished to do so, subject to the following conditions:
00012 *
00013 * The above copyright notice and this permission notice shall be included in 
00014 * all copies or substantial portions of the Software.
00015 *
00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
00017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
00018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
00019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
00020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
00021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
00022 * SOFTWARE.
00023 ******************************************************************************/
00024 
00025 
00026 #include "Sharp_LS012B7DD01.h"
00027 
00028 //5x7 character bit map
00029 static const uint8_t font_5x7[95][6] = {
00030     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //SPACE
00031     {0x00, 0x00, 0x00, 0xf2, 0x00, 0x00}, //!
00032     {0x00, 0x00, 0xe0, 0x00, 0xe0, 0x00}, //"
00033     {0x00, 0x28, 0xfe, 0x28, 0xfe, 0x28}, //#
00034     {0x00, 0x24, 0x54, 0xfe, 0x54, 0x48}, //$
00035     {0x00, 0xc4, 0xc8, 0x10, 0x26, 0x46}, //%
00036     {0x00, 0x6c, 0x92, 0xaa, 0x44, 0x0a}, //&
00037     {0x00, 0x00, 0xa0, 0xc0, 0x00, 0x00}, //'
00038     {0x00, 0x00, 0x38, 0x44, 0x82, 0x00}, //(
00039     {0x00, 0x00, 0x82, 0x44, 0x38, 0x00}, //)
00040     {0x00, 0x28, 0x10, 0x7c, 0x10, 0x28}, //*
00041     {0x00, 0x10, 0x10, 0x7c, 0x10, 0x10}, //+
00042     {0x00, 0x00, 0x0a, 0x0c, 0x00, 0x00}, //,
00043     {0x00, 0x10, 0x10, 0x10, 0x10, 0x10}, //-
00044     {0x00, 0x00, 0x06, 0x06, 0x00, 0x00}, //.
00045     {0x00, 0x04, 0x08, 0x10, 0x20, 0x40}, ///
00046     {0x00, 0x7c, 0x8a, 0x92, 0xa2, 0x7c}, //0
00047     {0x00, 0x00, 0x42, 0xfe, 0x02, 0x00}, //1
00048     {0x00, 0x42, 0x86, 0x8a, 0x92, 0x62}, //2
00049     {0x00, 0x84, 0x82, 0xa2, 0xd2, 0x8c}, //3
00050     {0x00, 0x18, 0x28, 0x48, 0xfe, 0x08}, //4
00051     {0x00, 0xe4, 0xa2, 0xa2, 0xa2, 0x9c}, //5
00052     {0x00, 0x3c, 0x52, 0x92, 0x92, 0x0c}, //6
00053     {0x00, 0x80, 0x8e, 0x90, 0xa0, 0xc0}, //7
00054     {0x00, 0x6c, 0x92, 0x92, 0x92, 0x6c}, //8
00055     {0x00, 0x60, 0x92, 0x92, 0x94, 0x78}, //9
00056     {0x00, 0x6c, 0x6c, 0x00, 0x00, 0x00}, //:
00057     {0x00, 0x6a, 0x6c, 0x00, 0x00, 0x00}, //;
00058     {0x00, 0x10, 0x28, 0x44, 0x82, 0x00}, //<
00059     {0x00, 0x28, 0x28, 0x28, 0x28, 0x28}, //=
00060     {0x00, 0x00, 0x82, 0x44, 0x28, 0x10}, //>
00061     {0x00, 0x40, 0x80, 0x8a, 0x90, 0x60}, //?
00062     {0x00, 0x0c, 0x92, 0x9e, 0x82, 0x7c}, //@
00063     {0x00, 0x7e, 0x88, 0x88, 0x88, 0x7e}, //A
00064     {0x00, 0xfe, 0x92, 0x92, 0x92, 0x6c}, //B
00065     {0x00, 0x7c, 0x82, 0x82, 0x82, 0x44}, //C
00066     {0x00, 0xfe, 0x82, 0x82, 0x44, 0x38}, //D
00067     {0x00, 0xfe, 0x92, 0x92, 0x92, 0x82}, //E
00068     {0x00, 0xfe, 0x90, 0x90, 0x90, 0x80}, //F
00069     {0x00, 0x7c, 0x82, 0x92, 0x92, 0x5e}, //G
00070     {0x00, 0xfe, 0x10, 0x10, 0x10, 0xfe}, //H
00071     {0x00, 0x00, 0x82, 0xfe, 0x82, 0x00}, //I
00072     {0x00, 0x04, 0x02, 0x82, 0xfc, 0x80}, //J
00073     {0x00, 0xfe, 0x10, 0x28, 0x44, 0x82}, //K
00074     {0x00, 0xfe, 0x02, 0x02, 0x02, 0x02}, //L
00075     {0x00, 0xfe, 0x40, 0x30, 0x40, 0xfe}, //M
00076     {0x00, 0xfe, 0x20, 0x10, 0x08, 0xfe}, //N
00077     {0x00, 0x7c, 0x82, 0x82, 0x82, 0x7c}, //O
00078     {0x00, 0xfe, 0x90, 0x90, 0x90, 0x60}, //P
00079     {0x00, 0x7c, 0x82, 0x8a, 0x84, 0x7a}, //Q
00080     {0x00, 0xfe, 0x90, 0x98, 0x94, 0x62}, //R
00081     {0x00, 0x62, 0x92, 0x92, 0x92, 0x8c}, //S
00082     {0x00, 0x80, 0x80, 0xfe, 0x80, 0x80}, //T
00083     {0x00, 0xfc, 0x02, 0x02, 0x02, 0xfc}, //U
00084     {0x00, 0xf8, 0x04, 0x02, 0x04, 0xf8}, //V
00085     {0x00, 0xfc, 0x02, 0x0c, 0x02, 0xfc}, //W
00086     {0x00, 0xc6, 0x28, 0x10, 0x28, 0xc6}, //X
00087     {0x00, 0xe0, 0x10, 0x0e, 0x10, 0xe0}, //Y
00088     {0x00, 0x86, 0x8a, 0x92, 0xa2, 0xc2}, //Z
00089     {0x00, 0x00, 0xfe, 0x82, 0x82, 0x00}, //[
00090     {0x00, 0x40, 0x20, 0x10, 0x08, 0x04}, //backslash
00091     {0x00, 0x00, 0x82, 0x82, 0xfe, 0x00}, //]
00092     {0x00, 0x20, 0x40, 0x80, 0x40, 0x20}, //^
00093     {0x00, 0x02, 0x02, 0x02, 0x02, 0x02}, //_
00094     {0x00, 0x00, 0x80, 0x40, 0x20, 0x00}, //`
00095     {0x00, 0x04, 0x2a, 0x2a, 0x2a, 0x1e}, //a
00096     {0x00, 0xfe, 0x0a, 0x12, 0x12, 0x0c}, //b
00097     {0x00, 0x1c, 0x22, 0x22, 0x22, 0x04}, //c
00098     {0x00, 0x1c, 0x22, 0x22, 0x12, 0xfe}, //d
00099     {0x00, 0x1c, 0x2a, 0x2a, 0x2a, 0x18}, //e
00100     {0x00, 0x10, 0x7e, 0x90, 0x80, 0x40}, //f
00101     {0x00, 0x30, 0x4a, 0x4a, 0x4a, 0x7c}, //g
00102     {0x00, 0xfe, 0x10, 0x20, 0x20, 0x1e}, //h
00103     {0x00, 0x00, 0x22, 0xbe, 0x02, 0x00}, //i
00104     {0x00, 0x04, 0x02, 0x22, 0xbc, 0x00}, //j
00105     {0x00, 0xfe, 0x08, 0x14, 0x22, 0x00}, //k
00106     {0x00, 0x00, 0x82, 0xfe, 0x02, 0x00}, //l
00107     {0x00, 0x1e, 0x20, 0x1a, 0x22, 0x1e}, //m
00108     {0x00, 0x3e, 0x10, 0x20, 0x20, 0x1e}, //n
00109     {0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c}, //o
00110     {0x00, 0x3e, 0x28, 0x28, 0x28, 0x10}, //p
00111     {0x00, 0x10, 0x28, 0x28, 0x18, 0x3e}, //q
00112     {0x00, 0x3e, 0x10, 0x20, 0x20, 0x10}, //r
00113     {0x00, 0x12, 0x2a, 0x2a, 0x2a, 0x04}, //s
00114     {0x00, 0x20, 0xfc, 0x22, 0x02, 0x04}, //t
00115     {0x00, 0x3c, 0x02, 0x02, 0x04, 0x3e}, //u
00116     {0x00, 0x38, 0x04, 0x02, 0x04, 0x38}, //v
00117     {0x00, 0x3c, 0x02, 0x0c, 0x02, 0x3c}, //w
00118     {0x00, 0x22, 0x14, 0x08, 0x14, 0x22}, //x
00119     {0x00, 0x30, 0x0a, 0x0a, 0x0a, 0x3c}, //y
00120     {0x00, 0x22, 0x26, 0x2a, 0x32, 0x22}, //z
00121     {0x00, 0x00, 0x10, 0x6c, 0x82, 0x00}, //{
00122     {0x00, 0x00, 0x00, 0xfe, 0x00, 0x00}, //|
00123     {0x00, 0x00, 0x82, 0x6c, 0x10, 0x00}, //}
00124     {0x00, 0x30, 0x40, 0x30, 0x08, 0x30}  //~
00125 };
00126 
00127 /*****************************************************************************/
00128 SharpLS012B7DD01::SharpLS012B7DD01(PinName disp, PinName extcomin, PinName cs, SPI &spiBus)
00129 :m_disp(disp, 0), m_extcomin(extcomin, 0), m_cs(cs, 0), m_spi(spiBus)
00130 {
00131     update(SharpLS012B7DD01::ALL_CLEAR_MODE);
00132     m_disp = !m_disp;
00133     wait_us(30);
00134     m_extcominTicker.attach(callback(this, &SharpLS012B7DD01::toggle_extcomin), 0.016);
00135 }
00136 
00137 
00138 /*****************************************************************************/
00139 SharpLS012B7DD01::~SharpLS012B7DD01()
00140 {
00141 }
00142 
00143 /*****************************************************************************/
00144 SharpLS012B7DD01::SharpCmdResult SharpLS012B7DD01::print_char(uint8_t ln, uint8_t pos, char c)
00145 {
00146     SharpLS012B7DD01::SharpCmdResult rtnVal = SharpLS012B7DD01::Failure;
00147     
00148     uint8_t char_buff[6];
00149     memcpy(char_buff, &(font_5x7[c - 0x20][0]), 6);
00150     
00151     if((ln < 4) && (pos < 30))
00152     {
00153         ln = ((ln * 8) + 4);
00154         pos = ((pos * 6) + 2);
00155         
00156         uint8_t temp;
00157         for(uint8_t c_bit = 0; c_bit < 8; c_bit++)
00158         {
00159             temp = 0;
00160             for(uint8_t c_byte = 0; c_byte < 6; c_byte++)
00161             {
00162                 if(((1 << (7 - c_bit)) & char_buff[c_byte]))
00163                 {
00164                     temp |= (1 << c_byte);
00165                 }
00166             }
00167             
00168             //display is active low
00169             temp = ~temp;
00170             
00171             if((pos % 8) == 0)
00172             {
00173                 if(pos)
00174                 {
00175                     m_data[ln + c_bit][pos/8] &= ~(0x3F);
00176                     m_data[ln + c_bit][pos/8] |= temp;
00177                 }
00178                 else
00179                 {
00180                     m_data[ln + c_bit][0] &= ~(0x3F);
00181                     m_data[ln + c_bit][0] |= temp;
00182                 }
00183             }
00184             else
00185             {
00186                 m_data[ln + c_bit][pos/8] &= ~(0x3F << (pos%8));
00187                 m_data[ln + c_bit][pos/8] |= (temp << (pos%8));
00188                 if((pos % 8) > 2)
00189                 {
00190                     uint8_t temp2 = 0;
00191                     for(uint8_t idx = 0; idx < ((pos%8) -2); idx++)
00192                     {
00193                         temp2 |= (1 << idx);
00194                     }
00195                     m_data[ln + c_bit][(pos/8) + 1] &= ~temp2;
00196                     m_data[ln + c_bit][(pos/8) + 1] |= (temp >> (8 - (pos%8)));
00197                 }
00198             }
00199         }
00200         
00201         rtnVal = write_memory(m_data, 8, ln);
00202     }
00203     
00204     return rtnVal;
00205 }
00206 
00207 
00208 /*****************************************************************************/
00209 SharpLS012B7DD01::SharpCmdResult SharpLS012B7DD01::print_str(uint8_t ln, uint8_t pos, const char *s)
00210 {
00211     SharpLS012B7DD01::SharpCmdResult rtnVal = SharpLS012B7DD01::Failure;
00212     
00213     size_t len = strlen(s);
00214     
00215     if((ln < 4) && ((pos + (len - 1)) < 30))
00216     {
00217         for(size_t idx = 0; idx < len; idx++)
00218         {
00219             rtnVal = print_char(ln, (pos + idx), s[idx]);
00220         }
00221     }
00222     
00223     return rtnVal;
00224 }
00225 
00226 
00227 /*****************************************************************************/
00228 void SharpLS012B7DD01::clear_display()
00229 {
00230     update(SharpLS012B7DD01::ALL_CLEAR_MODE);
00231 }
00232 
00233 
00234 /*****************************************************************************/
00235 SharpLS012B7DD01::SharpCmdResult SharpLS012B7DD01::write_memory(uint8_t data[][23], uint8_t lines, uint8_t offset)
00236 {
00237     SharpLS012B7DD01::SharpCmdResult rtnVal = Failure;
00238     
00239     if((lines + offset) <= 38)
00240     {
00241         m_cs = !m_cs;
00242         //send mode
00243         m_spi.write(SharpLS012B7DD01::DATA_UPDATE_MODE);
00244         for(uint8_t idy = offset; idy < (lines + offset); idy++)
00245         {
00246             //send line adrs
00247             m_spi.write(rev_bit(idy + 1));
00248             for(uint8_t idx = 0; idx < 23; idx++)
00249             {
00250                 m_spi.write(rev_bit(data[idy][idx]));
00251             }
00252             //dummy data required by datasheet
00253             m_spi.write(0);
00254             m_spi.write(0);
00255         }
00256         //last line requires 16 xfr clocks too
00257         m_spi.write(0);
00258         m_cs = !m_cs;
00259         
00260         rtnVal = Success;
00261     }
00262     
00263     return rtnVal;
00264 }
00265 
00266 
00267 /*****************************************************************************/
00268 void SharpLS012B7DD01::update(const uint8_t mode)
00269 {
00270     m_cs = !m_cs;
00271     //send mode
00272     m_spi.write(mode);
00273     m_spi.write(0);
00274     m_spi.write(0);
00275     m_cs = !m_cs;
00276     
00277     if(mode == SharpLS012B7DD01::ALL_CLEAR_MODE)
00278     {
00279         for(uint8_t idy = 0; idy < 38; idy++)
00280         {
00281             for(uint8_t idx = 0; idx < 23; idx ++)
00282             {
00283                 m_data[idy][idx] = 0xFF;
00284             }
00285         }
00286     }
00287 }
00288 
00289 
00290 /*****************************************************************************/
00291 uint8_t SharpLS012B7DD01::rev_bit(uint8_t data)
00292 {
00293     uint8_t temp = 0;
00294     for(uint8_t idx = 0; idx < 8; idx++)
00295     {
00296         if((1 << idx) & data)
00297         {
00298             temp |= (0x80 >> idx);
00299         }
00300     }
00301     
00302     return temp;
00303 }
00304 
00305 
00306 /*****************************************************************************/
00307 void SharpLS012B7DD01::toggle_extcomin()
00308 {
00309     m_extcomin = !m_extcomin;
00310 }