TEST

Dependencies:   max32630fthr Adafruit_FeatherOLED USBDevice

Committer:
wwwarunraj
Date:
Sun Apr 19 11:19:57 2020 +0000
Revision:
4:291477e8690d
Parent:
1:f60eafbf009a
19/04

Who changed what in which revision?

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