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