Fork of Silabs MemoryLCD library

Dependents:   demoUI whrmDemoUI Host_Software_MAX32664GWEB_HR_EXTENDED Host_Software_MAX32664GWEC_SpO2_HR-_EXTE ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LS013B7DH03.cpp Source File

LS013B7DH03.cpp

Go to the documentation of this file.
00001 /***************************************************************************//**
00002  * @file LS013B7DH03.cpp
00003  * @brief Driver class for the Sharp LS013B7DH03 memory LCD on some kits.
00004  *******************************************************************************
00005  * @section License
00006  * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
00007  *******************************************************************************
00008  *
00009  * Permission is granted to anyone to use this software for any purpose,
00010  * including commercial applications, and to alter it and redistribute it
00011  * freely, subject to the following restrictions:
00012  *
00013  * 1. The origin of this software must not be misrepresented; you must not
00014  *    claim that you wrote the original software.
00015  * 2. Altered source versions must be plainly marked as such, and must not be
00016  *    misrepresented as being the original software.
00017  * 3. This notice may not be removed or altered from any source distribution.
00018  *
00019  * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
00020  * obligation to support this Software. Silicon Labs is providing the
00021  * Software "AS IS", with no express or implied warranties of any kind,
00022  * including, but not limited to, any implied warranties of merchantability
00023  * or fitness for any particular purpose or warranties against infringement
00024  * of any proprietary rights of a third party.
00025  *
00026  * Silicon Labs will not be liable for any consequential, incidental, or
00027  * special damages, or any other relief, or for any claim by any third party,
00028  * arising from your use of this Software.
00029  *
00030  ******************************************************************************/
00031 
00032 #include "../screen/LS013B7DH03.h"
00033 
00034 #include <mbed.h>
00035 #include "SPI.h"
00036 //#include "Peripherals.h"
00037 
00038 /* LS013B7DH03 SPI commands */
00039 #define LS013B7DH03_CMD_UPDATE     (0x01)
00040 #define LS013B7DH03_CMD_ALL_CLEAR  (0x04)
00041 
00042 /* Macro to switch endianness on char value */
00043 #define SWAP8(a) ((((a) & 0x80) >> 7) | (((a) & 0x40) >> 5) | (((a) & 0x20) >> 3) | (((a) & 0x10) >> 1) | (((a) & 0x08) << 1) | (((a) & 0x04) << 3) | (((a) & 0x02) << 5) | (((a) & 0x01) << 7))
00044 
00045 namespace silabs {
00046 
00047 
00048 LS013B7DH03::LS013B7DH03(mbed::SPI * spi, DigitalOut * CS, const char *name) : BufferedDisplay( name )  {
00049     //Save pointer to ChipSelect pin
00050     _CS = CS;
00051     _CS->write(0);
00052     DigitalOut DISP(P6_6);
00053 
00054 //Save pointer to ExtCom pin
00055 /// _EXTCOM = ExtCom;
00056 /// _EXTCOM->write(0);
00057 
00058     DISP  = 0;
00059     wait_ms(1);
00060     DISP = 1;
00061 
00062     //Save pointer to spi peripheral
00063     _spi = spi;
00064     //_spi->frequency(600000);
00065     _spi->format( 8, 0 );
00066 
00067     _internalEventCallback.attach(this, &LS013B7DH03::_cbHandler);
00068 
00069     //Initialize
00070     //_spi->set_dma_usage((DMAUsage)DMA_USAGE_NEVER);
00071     _refreshCount = 0;
00072     _lcdPolarity = 0;
00073     _state = IDLE;
00074     _completionCallbackPtr = NULL;
00075     _rowCount = 0;
00076 
00077     //Start toggling the EXTCOM pin
00078     //_displayToggler.attach(this, &LS013B7DH03::toggle, 0.008f);
00079 }
00080 
00081 /**
00082  * Call this function at 55 ~ 65 Hz to keep the display up-to-date.
00083  */
00084 void LS013B7DH03::toggle() {
00085 //  _EXTCOM->write(!_EXTCOM->read());
00086 //  _refreshCount++;
00087 }
00088 
00089 /**
00090  * Function to get internal refresh counter
00091  */
00092 uint32_t LS013B7DH03::getRefreshTicks() {
00093     return _refreshCount;
00094 }
00095 
00096 /**
00097  * Call this function to push all changes to the display
00098  */
00099 int LS013B7DH03::update( cbptr_t callback ) {
00100     uint32_t rowCount = 0;
00101     bool update = false;
00102 
00103     // Check if something actually changed in the pixelbuffer
00104     for(rowCount = 0; rowCount < DISPLAY_HEIGHT/DISPLAY_BUFFER_TYPE_SIZE; rowCount++) {
00105         if(_dirtyRows[rowCount] != 0) update = true;
00106     }
00107 
00108     if(update == false) return LS013B7DH03_NO_ACTION;
00109 
00110     // Watch out to not mess up a transfer
00111     if(_state != IDLE) return LS013B7DH03_ERROR_BUSY;
00112 
00113     _completionCallbackPtr = callback;
00114 
00115     // Take control
00116     _state = WAIT_WRITE;
00117     _rowCount = 0;
00118 
00119     //Initialize the command vector
00120     _cmd[0] = (uint8_t)SWAP8(LS013B7DH03_CMD_UPDATE);
00121     _cmd[1] = SWAP8(1);
00122 
00123     // Activate LCD
00124     _CS->write(1);
00125     _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
00126 
00127     return LS013B7DH03_OK;
00128 }
00129 
00130 /**
00131  * Function to test display buffer
00132  */
00133 int LS013B7DH03::showDemo() {
00134     for(uint32_t i = 0; i < DISPLAY_BUFFER_ELEMENTS; i+=2) {
00135         _pixelBuffer[i] = 0x00555345;
00136     }
00137     memset((void*)_dirtyRows, 0x33, sizeof(_dirtyRows));
00138 
00139     return LS013B7DH03_OK;
00140 }
00141 
00142 /**
00143  * Call this function to immediately clear the display
00144  */
00145 int LS013B7DH03::clearImmediate( cbptr_t callback ) {
00146     // Watch out to not mess up a transfer
00147     if(_state != IDLE) return LS013B7DH03_ERROR_BUSY;
00148 
00149     _state = WAIT_CLEAR;
00150     _completionCallbackPtr = callback;
00151 
00152     // Clear out the pixel buffer
00153     memset((void*)_pixelBuffer, White, sizeof(_pixelBuffer));
00154     memset((void*)_dirtyRows, 0, sizeof(_dirtyRows));
00155 
00156     _cmd[0] = (uint8_t)(SWAP8(LS013B7DH03_CMD_ALL_CLEAR | _lcdPolarity));
00157     _cmd[1] = 0;
00158 
00159     // Wait for the ChipSelect line
00160     _CS->write(1);
00161     _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
00162 
00163     return LS013B7DH03_OK;
00164 }
00165 
00166 void LS013B7DH03::_cbHandlerTimeout( void ) {
00167     this->_cbHandler(0);
00168 }
00169 
00170 void LS013B7DH03::_cbHandler( int event ) {
00171     if((_state == WAIT_WRITE) || (_state == WRITING))
00172     {
00173         _state = WRITING;
00174         while(_rowCount < DISPLAY_HEIGHT) {
00175             // Determine the next line to send
00176             if((_dirtyRows[_rowCount / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (_rowCount % DISPLAY_BUFFER_TYPE_SIZE))) != 0) {
00177 
00178                 // Row is dirty, send an update to the display
00179                 _cmd[1] = (uint8_t)SWAP8(_rowCount + 1);
00180                 memcpy((void*)&(_cmd[2]), (const void*)&(_pixelBuffer[_rowCount*(DISPLAY_WIDTH/DISPLAY_BUFFER_TYPE_SIZE)]), DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE));
00181 
00182                 if(_spi->write((const char*)_cmd, (2 + (DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE))) , (char*)NULL, 0/*, _internalEventCallback, SPI_EVENT_COMPLETE*/) != (2 + (DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE)))) {
00183                     // SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
00184                     _state = DONE;
00185                     //printf("Failed at _cbHandler\n");
00186                     // Make sure the handler is called again
00187                     _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
00188                 }else{  //sc...
00189                     _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.001f);
00190                 }
00191 
00192                 // Transaction is in progress, so update row state
00193                 _dirtyRows[_rowCount / DISPLAY_BUFFER_TYPE_SIZE] &= ~(1 << (_rowCount % DISPLAY_BUFFER_TYPE_SIZE));
00194                 _rowCount++;
00195                 return;
00196             }
00197 
00198             // Row wasn't touched, so check the next row
00199             _rowCount++;
00200         }
00201 
00202         // Done sending!
00203         _cmd[1] = 0xFF;
00204         _state = TRANSFERS_DONE;
00205         if(_spi->write((const char*)_cmd, 2, (char*)NULL, 0/*, _internalEventCallback, SPI_EVENT_COMPLETE*/) != 2) {
00206             // SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
00207             _state = DONE;
00208 
00209             // Make sure the handler is called again
00210             _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
00211         }else{  //sc...
00212             _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.001f);
00213         }
00214         return;
00215     }
00216     else if (_state == WAIT_CLEAR)
00217     {
00218         _state = TRANSFERS_DONE;
00219         if(_spi->write((const char*)_cmd, 2, (char*)NULL, 0/*, _internalEventCallback, SPI_EVENT_COMPLETE*/) != 2) {
00220             // SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
00221             _state = DONE;
00222 
00223             // Make sure the handler is called again
00224             _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
00225         }else{  //sc...
00226             _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.001f);
00227         }
00228         return;
00229     }
00230     else if (_state == TRANSFERS_DONE)
00231     {
00232         _state = DONE;
00233         _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
00234         return;
00235     }
00236     else if (_state == DONE)
00237     {
00238         _CS->write(0);
00239         _state = IDLE;
00240         if(_completionCallbackPtr != 0) _completionCallbackPtr();
00241         return;
00242     }
00243 }
00244 
00245 } // namespace silabs