Maxim Integrated / Mbed OS MAXREFDES101_SOURCE

Dependencies:   max32630fthr Adafruit_FeatherOLED USBDevice

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 <mbed.h>
00033 #include "LS013B7DH03.h"
00034 #include "SPI.h"
00035 #include "Peripherals.h"
00036 
00037 /* LS013B7DH03 SPI commands */
00038 #define LS013B7DH03_CMD_UPDATE     (0x01)
00039 #define LS013B7DH03_CMD_ALL_CLEAR  (0x04)
00040 
00041 /* Macro to switch endianness on char value */
00042 #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))
00043 
00044 namespace silabs {
00045 
00046 
00047 LS013B7DH03::LS013B7DH03(mbed::SPI * spi, DigitalOut * CS, const char *name) : BufferedDisplay( name )  {
00048     //Save pointer to ChipSelect pin
00049     _CS = CS;
00050     _CS->write(0);
00051     DigitalOut DISP(P6_6);
00052 
00053 //Save pointer to ExtCom pin
00054 /// _EXTCOM = ExtCom;
00055 /// _EXTCOM->write(0);
00056 
00057     DISP  = 0;
00058     wait_ms(1);
00059     DISP = 1;
00060 
00061     //Save pointer to spi peripheral
00062     _spi = spi;
00063     //_spi->frequency(600000);
00064     _spi->format( 8, 0 );
00065 
00066     _internalEventCallback.attach(this, &LS013B7DH03::_cbHandler);
00067 
00068     //Initialize
00069     //_spi->set_dma_usage((DMAUsage)DMA_USAGE_NEVER);
00070     _refreshCount = 0;
00071     _lcdPolarity = 0;
00072     _state = IDLE;
00073     _completionCallbackPtr = NULL;
00074     _rowCount = 0;
00075 
00076     //Start toggling the EXTCOM pin
00077     //_displayToggler.attach(this, &LS013B7DH03::toggle, 0.008f);
00078 }
00079 
00080 /**
00081  * Call this function at 55 ~ 65 Hz to keep the display up-to-date.
00082  */
00083 void LS013B7DH03::toggle() {
00084 //  _EXTCOM->write(!_EXTCOM->read());
00085 //  _refreshCount++;
00086 }
00087 
00088 /**
00089  * Function to get internal refresh counter
00090  */
00091 uint32_t LS013B7DH03::getRefreshTicks() {
00092     return _refreshCount;
00093 }
00094 
00095 /**
00096  * Call this function to push all changes to the display
00097  */
00098 int LS013B7DH03::update( cbptr_t callback ) {
00099     uint32_t rowCount = 0;
00100     bool update = false;
00101 
00102     // Check if something actually changed in the pixelbuffer
00103     for(rowCount = 0; rowCount < DISPLAY_HEIGHT/DISPLAY_BUFFER_TYPE_SIZE; rowCount++) {
00104         if(_dirtyRows[rowCount] != 0) update = true;
00105     }
00106 
00107     if(update == false) return LS013B7DH03_NO_ACTION;
00108 
00109     // Watch out to not mess up a transfer
00110     if(_state != IDLE) return LS013B7DH03_ERROR_BUSY;
00111 
00112     _completionCallbackPtr = callback;
00113 
00114     // Take control
00115     _state = WAIT_WRITE;
00116     _rowCount = 0;
00117 
00118     //Initialize the command vector
00119     _cmd[0] = (uint8_t)SWAP8(LS013B7DH03_CMD_UPDATE);
00120     _cmd[1] = SWAP8(1);
00121 
00122     // Activate LCD
00123     _CS->write(1);
00124     _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
00125 
00126     return LS013B7DH03_OK;
00127 }
00128 
00129 /**
00130  * Function to test display buffer
00131  */
00132 int LS013B7DH03::showDemo() {
00133     for(uint32_t i = 0; i < DISPLAY_BUFFER_ELEMENTS; i+=2) {
00134         _pixelBuffer[i] = 0x00FFF000;
00135     }
00136     memset((void*)_dirtyRows, 0xFF, sizeof(_dirtyRows));
00137 
00138     return LS013B7DH03_OK;
00139 }
00140 
00141 /**
00142  * Function to get internal refresh counter
00143  */
00144 int LS013B7DH03::executeOnceLCD() {
00145     if(interrupt_received)
00146         _cbHandler(0);
00147 }
00148 
00149 /**
00150  * Call this function to immediately clear the display
00151  */
00152 int LS013B7DH03::clearImmediate( cbptr_t callback ) {
00153     // Watch out to not mess up a transfer
00154     if(_state != IDLE) return LS013B7DH03_ERROR_BUSY;
00155 
00156     _state = WAIT_CLEAR;
00157     _completionCallbackPtr = callback;
00158 
00159     // Clear out the pixel buffer
00160     memset((void*)_pixelBuffer, White, sizeof(_pixelBuffer));
00161     memset((void*)_dirtyRows, 0, sizeof(_dirtyRows));
00162 
00163     _cmd[0] = (uint8_t)(SWAP8(LS013B7DH03_CMD_ALL_CLEAR | _lcdPolarity));
00164     _cmd[1] = 0;
00165 
00166     // Wait for the ChipSelect line
00167     _CS->write(1);
00168     _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
00169 
00170     return LS013B7DH03_OK;
00171 }
00172 
00173 void LS013B7DH03::_cbHandlerTimeout( void ) {
00174     interrupt_received = true;
00175     //this->_cbHandler(0);
00176 }
00177 
00178 void LS013B7DH03::_cbHandler( int event ) {
00179     interrupt_received = false;
00180     if((_state == WAIT_WRITE) || (_state == WRITING))
00181     {
00182         _state = WRITING;
00183         while(_rowCount < DISPLAY_HEIGHT) {
00184             // Determine the next line to send
00185             if((_dirtyRows[_rowCount / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (_rowCount % DISPLAY_BUFFER_TYPE_SIZE))) != 0) {
00186 
00187                 // Row is dirty, send an update to the display
00188                 _cmd[1] = (uint8_t)SWAP8(_rowCount + 1);
00189                 memcpy((void*)&(_cmd[2]), (const void*)&(_pixelBuffer[_rowCount*(DISPLAY_WIDTH/DISPLAY_BUFFER_TYPE_SIZE)]), DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE));
00190 
00191                 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)))) {
00192                     // SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
00193                     _state = DONE;
00194                     //printf("Failed at _cbHandler\n");
00195                     // Make sure the handler is called again
00196                     _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
00197                 }else{  //sc...
00198                     _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.001f);
00199                 }
00200 
00201                 // Transaction is in progress, so update row state
00202                 _dirtyRows[_rowCount / DISPLAY_BUFFER_TYPE_SIZE] &= ~(1 << (_rowCount % DISPLAY_BUFFER_TYPE_SIZE));
00203                 _rowCount++;
00204                 return;
00205             }
00206 
00207             // Row wasn't touched, so check the next row
00208             _rowCount++;
00209         }
00210 
00211         // Done sending!
00212         _cmd[1] = 0xFF;
00213         _state = TRANSFERS_DONE;
00214         if(_spi->write((const char*)_cmd, 2, (char*)NULL, 0/*, _internalEventCallback, SPI_EVENT_COMPLETE*/) != 2) {
00215             // SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
00216             _state = DONE;
00217 
00218             // Make sure the handler is called again
00219             _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
00220         }else{  //sc...
00221             _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.001f);
00222         }
00223         return;
00224     }
00225     else if (_state == WAIT_CLEAR)
00226     {
00227         _state = TRANSFERS_DONE;
00228         if(_spi->write((const char*)_cmd, 2, (char*)NULL, 0/*, _internalEventCallback, SPI_EVENT_COMPLETE*/) != 2) {
00229             // SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
00230             _state = DONE;
00231 
00232             // Make sure the handler is called again
00233             _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
00234         }else{  //sc...
00235             _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.001f);
00236         }
00237         return;
00238     }
00239     else if (_state == TRANSFERS_DONE)
00240     {
00241         _state = DONE;
00242         _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
00243         return;
00244     }
00245     else if (_state == DONE)
00246     {
00247         _CS->write(0);
00248         _state = IDLE;
00249         if(_completionCallbackPtr != 0) _completionCallbackPtr();
00250         return;
00251     }
00252 }
00253 
00254 } // namespace silabs