Fork of Silabs MemoryLCD library

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

C++ library for Sharp Microelectronics 1.28 inch LCD TFT, LS013B7DH03, SPI bus. Forked from Silicon Labs MemoryLCD display driver.

Committer:
gmehmet
Date:
Wed Jan 02 13:20:35 2019 +0300
Revision:
12:ca0bcb4777e9
Parent:
2:2f10f00fe56c
adapt memorylcd code to use it with maxim boards

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Steven Cooreman 0:a0faa86660d4 1 /***************************************************************************//**
Steven Cooreman 0:a0faa86660d4 2 * @file LS013B7DH03.cpp
Steven Cooreman 0:a0faa86660d4 3 * @brief Driver class for the Sharp LS013B7DH03 memory LCD on some kits.
Steven Cooreman 0:a0faa86660d4 4 *******************************************************************************
Steven Cooreman 0:a0faa86660d4 5 * @section License
Steven Cooreman 0:a0faa86660d4 6 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
Steven Cooreman 0:a0faa86660d4 7 *******************************************************************************
Steven Cooreman 0:a0faa86660d4 8 *
Steven Cooreman 0:a0faa86660d4 9 * Permission is granted to anyone to use this software for any purpose,
Steven Cooreman 0:a0faa86660d4 10 * including commercial applications, and to alter it and redistribute it
Steven Cooreman 0:a0faa86660d4 11 * freely, subject to the following restrictions:
Steven Cooreman 0:a0faa86660d4 12 *
Steven Cooreman 0:a0faa86660d4 13 * 1. The origin of this software must not be misrepresented; you must not
Steven Cooreman 0:a0faa86660d4 14 * claim that you wrote the original software.
Steven Cooreman 0:a0faa86660d4 15 * 2. Altered source versions must be plainly marked as such, and must not be
Steven Cooreman 0:a0faa86660d4 16 * misrepresented as being the original software.
Steven Cooreman 0:a0faa86660d4 17 * 3. This notice may not be removed or altered from any source distribution.
Steven Cooreman 0:a0faa86660d4 18 *
Steven Cooreman 0:a0faa86660d4 19 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
Steven Cooreman 0:a0faa86660d4 20 * obligation to support this Software. Silicon Labs is providing the
Steven Cooreman 0:a0faa86660d4 21 * Software "AS IS", with no express or implied warranties of any kind,
Steven Cooreman 0:a0faa86660d4 22 * including, but not limited to, any implied warranties of merchantability
Steven Cooreman 0:a0faa86660d4 23 * or fitness for any particular purpose or warranties against infringement
Steven Cooreman 0:a0faa86660d4 24 * of any proprietary rights of a third party.
Steven Cooreman 0:a0faa86660d4 25 *
Steven Cooreman 0:a0faa86660d4 26 * Silicon Labs will not be liable for any consequential, incidental, or
Steven Cooreman 0:a0faa86660d4 27 * special damages, or any other relief, or for any claim by any third party,
Steven Cooreman 0:a0faa86660d4 28 * arising from your use of this Software.
Steven Cooreman 0:a0faa86660d4 29 *
Steven Cooreman 0:a0faa86660d4 30 ******************************************************************************/
Steven Cooreman 0:a0faa86660d4 31
gmehmet 12:ca0bcb4777e9 32 #include "../screen/LS013B7DH03.h"
gmehmet 12:ca0bcb4777e9 33
Steven Cooreman 0:a0faa86660d4 34 #include <mbed.h>
Steven Cooreman 0:a0faa86660d4 35 #include "SPI.h"
gmehmet 12:ca0bcb4777e9 36 //#include "Peripherals.h"
Steven Cooreman 0:a0faa86660d4 37
Steven Cooreman 0:a0faa86660d4 38 /* LS013B7DH03 SPI commands */
Steven Cooreman 0:a0faa86660d4 39 #define LS013B7DH03_CMD_UPDATE (0x01)
Steven Cooreman 0:a0faa86660d4 40 #define LS013B7DH03_CMD_ALL_CLEAR (0x04)
Steven Cooreman 0:a0faa86660d4 41
Steven Cooreman 0:a0faa86660d4 42 /* Macro to switch endianness on char value */
Steven Cooreman 0:a0faa86660d4 43 #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))
Steven Cooreman 0:a0faa86660d4 44
Steven Cooreman 0:a0faa86660d4 45 namespace silabs {
Steven Cooreman 0:a0faa86660d4 46
gmehmet 12:ca0bcb4777e9 47
gmehmet 12:ca0bcb4777e9 48 LS013B7DH03::LS013B7DH03(mbed::SPI * spi, DigitalOut * CS, const char *name) : BufferedDisplay( name ) {
Steven Cooreman 0:a0faa86660d4 49 //Save pointer to ChipSelect pin
Steven Cooreman 0:a0faa86660d4 50 _CS = CS;
Steven Cooreman 0:a0faa86660d4 51 _CS->write(0);
gmehmet 12:ca0bcb4777e9 52 DigitalOut DISP(P6_6);
Steven Cooreman 0:a0faa86660d4 53
gmehmet 12:ca0bcb4777e9 54 //Save pointer to ExtCom pin
gmehmet 12:ca0bcb4777e9 55 /// _EXTCOM = ExtCom;
gmehmet 12:ca0bcb4777e9 56 /// _EXTCOM->write(0);
gmehmet 12:ca0bcb4777e9 57
gmehmet 12:ca0bcb4777e9 58 DISP = 0;
gmehmet 12:ca0bcb4777e9 59 wait_ms(1);
gmehmet 12:ca0bcb4777e9 60 DISP = 1;
Steven Cooreman 0:a0faa86660d4 61
Steven Cooreman 0:a0faa86660d4 62 //Save pointer to spi peripheral
Steven Cooreman 0:a0faa86660d4 63 _spi = spi;
gmehmet 12:ca0bcb4777e9 64 //_spi->frequency(600000);
gmehmet 12:ca0bcb4777e9 65 _spi->format( 8, 0 );
gmehmet 12:ca0bcb4777e9 66
Steven Cooreman 2:2f10f00fe56c 67 _internalEventCallback.attach(this, &LS013B7DH03::_cbHandler);
Steven Cooreman 0:a0faa86660d4 68
Steven Cooreman 0:a0faa86660d4 69 //Initialize
gmehmet 12:ca0bcb4777e9 70 //_spi->set_dma_usage((DMAUsage)DMA_USAGE_NEVER);
Steven Cooreman 0:a0faa86660d4 71 _refreshCount = 0;
Steven Cooreman 0:a0faa86660d4 72 _lcdPolarity = 0;
Steven Cooreman 0:a0faa86660d4 73 _state = IDLE;
Steven Cooreman 0:a0faa86660d4 74 _completionCallbackPtr = NULL;
Steven Cooreman 0:a0faa86660d4 75 _rowCount = 0;
Steven Cooreman 0:a0faa86660d4 76
Steven Cooreman 0:a0faa86660d4 77 //Start toggling the EXTCOM pin
Steven Cooreman 2:2f10f00fe56c 78 //_displayToggler.attach(this, &LS013B7DH03::toggle, 0.008f);
Steven Cooreman 0:a0faa86660d4 79 }
Steven Cooreman 0:a0faa86660d4 80
Steven Cooreman 0:a0faa86660d4 81 /**
Steven Cooreman 0:a0faa86660d4 82 * Call this function at 55 ~ 65 Hz to keep the display up-to-date.
Steven Cooreman 0:a0faa86660d4 83 */
Steven Cooreman 0:a0faa86660d4 84 void LS013B7DH03::toggle() {
gmehmet 12:ca0bcb4777e9 85 // _EXTCOM->write(!_EXTCOM->read());
gmehmet 12:ca0bcb4777e9 86 // _refreshCount++;
Steven Cooreman 0:a0faa86660d4 87 }
Steven Cooreman 0:a0faa86660d4 88
Steven Cooreman 0:a0faa86660d4 89 /**
Steven Cooreman 0:a0faa86660d4 90 * Function to get internal refresh counter
Steven Cooreman 0:a0faa86660d4 91 */
Steven Cooreman 0:a0faa86660d4 92 uint32_t LS013B7DH03::getRefreshTicks() {
Steven Cooreman 0:a0faa86660d4 93 return _refreshCount;
Steven Cooreman 0:a0faa86660d4 94 }
Steven Cooreman 0:a0faa86660d4 95
Steven Cooreman 0:a0faa86660d4 96 /**
Steven Cooreman 0:a0faa86660d4 97 * Call this function to push all changes to the display
Steven Cooreman 0:a0faa86660d4 98 */
Steven Cooreman 0:a0faa86660d4 99 int LS013B7DH03::update( cbptr_t callback ) {
Steven Cooreman 0:a0faa86660d4 100 uint32_t rowCount = 0;
Steven Cooreman 0:a0faa86660d4 101 bool update = false;
Steven Cooreman 0:a0faa86660d4 102
Steven Cooreman 0:a0faa86660d4 103 // Check if something actually changed in the pixelbuffer
Steven Cooreman 0:a0faa86660d4 104 for(rowCount = 0; rowCount < DISPLAY_HEIGHT/DISPLAY_BUFFER_TYPE_SIZE; rowCount++) {
Steven Cooreman 0:a0faa86660d4 105 if(_dirtyRows[rowCount] != 0) update = true;
Steven Cooreman 0:a0faa86660d4 106 }
Steven Cooreman 0:a0faa86660d4 107
Steven Cooreman 0:a0faa86660d4 108 if(update == false) return LS013B7DH03_NO_ACTION;
Steven Cooreman 0:a0faa86660d4 109
Steven Cooreman 0:a0faa86660d4 110 // Watch out to not mess up a transfer
Steven Cooreman 0:a0faa86660d4 111 if(_state != IDLE) return LS013B7DH03_ERROR_BUSY;
Steven Cooreman 0:a0faa86660d4 112
Steven Cooreman 0:a0faa86660d4 113 _completionCallbackPtr = callback;
Steven Cooreman 0:a0faa86660d4 114
Steven Cooreman 0:a0faa86660d4 115 // Take control
Steven Cooreman 0:a0faa86660d4 116 _state = WAIT_WRITE;
Steven Cooreman 0:a0faa86660d4 117 _rowCount = 0;
Steven Cooreman 0:a0faa86660d4 118
Steven Cooreman 0:a0faa86660d4 119 //Initialize the command vector
Steven Cooreman 0:a0faa86660d4 120 _cmd[0] = (uint8_t)SWAP8(LS013B7DH03_CMD_UPDATE);
Steven Cooreman 0:a0faa86660d4 121 _cmd[1] = SWAP8(1);
Steven Cooreman 0:a0faa86660d4 122
Steven Cooreman 0:a0faa86660d4 123 // Activate LCD
Steven Cooreman 0:a0faa86660d4 124 _CS->write(1);
Steven Cooreman 0:a0faa86660d4 125 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
Steven Cooreman 0:a0faa86660d4 126
Steven Cooreman 0:a0faa86660d4 127 return LS013B7DH03_OK;
Steven Cooreman 0:a0faa86660d4 128 }
Steven Cooreman 0:a0faa86660d4 129
Steven Cooreman 0:a0faa86660d4 130 /**
Steven Cooreman 0:a0faa86660d4 131 * Function to test display buffer
Steven Cooreman 0:a0faa86660d4 132 */
Steven Cooreman 0:a0faa86660d4 133 int LS013B7DH03::showDemo() {
Steven Cooreman 0:a0faa86660d4 134 for(uint32_t i = 0; i < DISPLAY_BUFFER_ELEMENTS; i+=2) {
gmehmet 12:ca0bcb4777e9 135 _pixelBuffer[i] = 0x00555345;
Steven Cooreman 0:a0faa86660d4 136 }
gmehmet 12:ca0bcb4777e9 137 memset((void*)_dirtyRows, 0x33, sizeof(_dirtyRows));
Steven Cooreman 0:a0faa86660d4 138
Steven Cooreman 0:a0faa86660d4 139 return LS013B7DH03_OK;
Steven Cooreman 0:a0faa86660d4 140 }
Steven Cooreman 0:a0faa86660d4 141
Steven Cooreman 0:a0faa86660d4 142 /**
Steven Cooreman 0:a0faa86660d4 143 * Call this function to immediately clear the display
Steven Cooreman 0:a0faa86660d4 144 */
Steven Cooreman 0:a0faa86660d4 145 int LS013B7DH03::clearImmediate( cbptr_t callback ) {
Steven Cooreman 0:a0faa86660d4 146 // Watch out to not mess up a transfer
Steven Cooreman 0:a0faa86660d4 147 if(_state != IDLE) return LS013B7DH03_ERROR_BUSY;
Steven Cooreman 0:a0faa86660d4 148
Steven Cooreman 0:a0faa86660d4 149 _state = WAIT_CLEAR;
Steven Cooreman 0:a0faa86660d4 150 _completionCallbackPtr = callback;
Steven Cooreman 0:a0faa86660d4 151
Steven Cooreman 0:a0faa86660d4 152 // Clear out the pixel buffer
Steven Cooreman 0:a0faa86660d4 153 memset((void*)_pixelBuffer, White, sizeof(_pixelBuffer));
Steven Cooreman 0:a0faa86660d4 154 memset((void*)_dirtyRows, 0, sizeof(_dirtyRows));
Steven Cooreman 0:a0faa86660d4 155
Steven Cooreman 0:a0faa86660d4 156 _cmd[0] = (uint8_t)(SWAP8(LS013B7DH03_CMD_ALL_CLEAR | _lcdPolarity));
Steven Cooreman 0:a0faa86660d4 157 _cmd[1] = 0;
Steven Cooreman 0:a0faa86660d4 158
Steven Cooreman 0:a0faa86660d4 159 // Wait for the ChipSelect line
Steven Cooreman 0:a0faa86660d4 160 _CS->write(1);
Steven Cooreman 0:a0faa86660d4 161 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
Steven Cooreman 0:a0faa86660d4 162
Steven Cooreman 0:a0faa86660d4 163 return LS013B7DH03_OK;
Steven Cooreman 0:a0faa86660d4 164 }
Steven Cooreman 0:a0faa86660d4 165
Steven Cooreman 0:a0faa86660d4 166 void LS013B7DH03::_cbHandlerTimeout( void ) {
Steven Cooreman 0:a0faa86660d4 167 this->_cbHandler(0);
Steven Cooreman 0:a0faa86660d4 168 }
Steven Cooreman 0:a0faa86660d4 169
Steven Cooreman 0:a0faa86660d4 170 void LS013B7DH03::_cbHandler( int event ) {
Steven Cooreman 0:a0faa86660d4 171 if((_state == WAIT_WRITE) || (_state == WRITING))
Steven Cooreman 0:a0faa86660d4 172 {
Steven Cooreman 0:a0faa86660d4 173 _state = WRITING;
Steven Cooreman 0:a0faa86660d4 174 while(_rowCount < DISPLAY_HEIGHT) {
Steven Cooreman 0:a0faa86660d4 175 // Determine the next line to send
Steven Cooreman 0:a0faa86660d4 176 if((_dirtyRows[_rowCount / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (_rowCount % DISPLAY_BUFFER_TYPE_SIZE))) != 0) {
Steven Cooreman 0:a0faa86660d4 177
Steven Cooreman 0:a0faa86660d4 178 // Row is dirty, send an update to the display
Steven Cooreman 0:a0faa86660d4 179 _cmd[1] = (uint8_t)SWAP8(_rowCount + 1);
Steven Cooreman 0:a0faa86660d4 180 memcpy((void*)&(_cmd[2]), (const void*)&(_pixelBuffer[_rowCount*(DISPLAY_WIDTH/DISPLAY_BUFFER_TYPE_SIZE)]), DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE));
Steven Cooreman 0:a0faa86660d4 181
gmehmet 12:ca0bcb4777e9 182 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)))) {
Steven Cooreman 0:a0faa86660d4 183 // SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
Steven Cooreman 0:a0faa86660d4 184 _state = DONE;
gmehmet 12:ca0bcb4777e9 185 //printf("Failed at _cbHandler\n");
Steven Cooreman 0:a0faa86660d4 186 // Make sure the handler is called again
Steven Cooreman 0:a0faa86660d4 187 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
gmehmet 12:ca0bcb4777e9 188 }else{ //sc...
gmehmet 12:ca0bcb4777e9 189 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.001f);
Steven Cooreman 0:a0faa86660d4 190 }
Steven Cooreman 0:a0faa86660d4 191
Steven Cooreman 0:a0faa86660d4 192 // Transaction is in progress, so update row state
Steven Cooreman 0:a0faa86660d4 193 _dirtyRows[_rowCount / DISPLAY_BUFFER_TYPE_SIZE] &= ~(1 << (_rowCount % DISPLAY_BUFFER_TYPE_SIZE));
Steven Cooreman 0:a0faa86660d4 194 _rowCount++;
Steven Cooreman 0:a0faa86660d4 195 return;
Steven Cooreman 0:a0faa86660d4 196 }
Steven Cooreman 0:a0faa86660d4 197
Steven Cooreman 0:a0faa86660d4 198 // Row wasn't touched, so check the next row
Steven Cooreman 0:a0faa86660d4 199 _rowCount++;
Steven Cooreman 0:a0faa86660d4 200 }
Steven Cooreman 0:a0faa86660d4 201
Steven Cooreman 0:a0faa86660d4 202 // Done sending!
Steven Cooreman 0:a0faa86660d4 203 _cmd[1] = 0xFF;
Steven Cooreman 0:a0faa86660d4 204 _state = TRANSFERS_DONE;
gmehmet 12:ca0bcb4777e9 205 if(_spi->write((const char*)_cmd, 2, (char*)NULL, 0/*, _internalEventCallback, SPI_EVENT_COMPLETE*/) != 2) {
Steven Cooreman 0:a0faa86660d4 206 // SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
Steven Cooreman 0:a0faa86660d4 207 _state = DONE;
Steven Cooreman 0:a0faa86660d4 208
Steven Cooreman 0:a0faa86660d4 209 // Make sure the handler is called again
Steven Cooreman 0:a0faa86660d4 210 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
gmehmet 12:ca0bcb4777e9 211 }else{ //sc...
gmehmet 12:ca0bcb4777e9 212 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.001f);
Steven Cooreman 0:a0faa86660d4 213 }
Steven Cooreman 0:a0faa86660d4 214 return;
Steven Cooreman 0:a0faa86660d4 215 }
Steven Cooreman 0:a0faa86660d4 216 else if (_state == WAIT_CLEAR)
Steven Cooreman 0:a0faa86660d4 217 {
Steven Cooreman 0:a0faa86660d4 218 _state = TRANSFERS_DONE;
gmehmet 12:ca0bcb4777e9 219 if(_spi->write((const char*)_cmd, 2, (char*)NULL, 0/*, _internalEventCallback, SPI_EVENT_COMPLETE*/) != 2) {
Steven Cooreman 0:a0faa86660d4 220 // SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
Steven Cooreman 0:a0faa86660d4 221 _state = DONE;
Steven Cooreman 0:a0faa86660d4 222
Steven Cooreman 0:a0faa86660d4 223 // Make sure the handler is called again
Steven Cooreman 0:a0faa86660d4 224 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
gmehmet 12:ca0bcb4777e9 225 }else{ //sc...
gmehmet 12:ca0bcb4777e9 226 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.001f);
Steven Cooreman 0:a0faa86660d4 227 }
Steven Cooreman 0:a0faa86660d4 228 return;
Steven Cooreman 0:a0faa86660d4 229 }
Steven Cooreman 0:a0faa86660d4 230 else if (_state == TRANSFERS_DONE)
Steven Cooreman 0:a0faa86660d4 231 {
Steven Cooreman 0:a0faa86660d4 232 _state = DONE;
Steven Cooreman 0:a0faa86660d4 233 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
Steven Cooreman 0:a0faa86660d4 234 return;
Steven Cooreman 0:a0faa86660d4 235 }
Steven Cooreman 0:a0faa86660d4 236 else if (_state == DONE)
Steven Cooreman 0:a0faa86660d4 237 {
Steven Cooreman 0:a0faa86660d4 238 _CS->write(0);
Steven Cooreman 0:a0faa86660d4 239 _state = IDLE;
Steven Cooreman 0:a0faa86660d4 240 if(_completionCallbackPtr != 0) _completionCallbackPtr();
Steven Cooreman 0:a0faa86660d4 241 return;
Steven Cooreman 0:a0faa86660d4 242 }
Steven Cooreman 0:a0faa86660d4 243 }
Steven Cooreman 0:a0faa86660d4 244
Steven Cooreman 0:a0faa86660d4 245 } // namespace silabs