Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
LS013B7DH03.cpp
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
Generated on Fri Jul 15 2022 01:41:58 by
1.7.2