Display driver for Sharp's range of SPI-driven memory LCD's, leveraging the power of asynchronous transfers. Currently supports LS013B7DH03, but easily extendable to other models as well.

Dependents:   memLCD-Demo memLCD-Demo memLCD-Demo MemLCD-Temperature-Humidity-Demo ... more

Information

All examples in this repo are considered EXPERIMENTAL QUALITY, meaning this code has been created as one-off proof-of-concept and is suitable as a demonstration for experimental purposes only. This code will not be regularly maintained by Silicon Labs and there is no guarantee that these projects will work across all environments, SDK versions and hardware.

Memory LCD extension board

Caution

This library builds upon the asynchronous SPI interface provided by mbed, but not all platforms currently support this. So, make sure your platform is capable of asynchronous SPI (all Silicon Labs platforms are), otherwise you will get compiler errors!

Usage

The library is purposefully quite simple to use. To set it up, you initialize an SPI object and the required I/O pins, and call the library constructor with those. Make sure the display is powered on, enabled, and the inversion mode is set to external (EXTMODE is high).

setup

#define SCK     PD2
#define MOSI 	PD0

DigitalOut CS(PD3);
DigitalOut EXTCOM(PC4);

SPI displaySPI(MOSI, NC, SCK);
silabs::LS013B7DH03 display(&displaySPI, &CS, &EXTCOM);

You should also swap out the pin names for the relevant names on your platform.

After setup, you usually want to clear any static information left on the screen. To do that, you would call clearImmediate, and optionally provide a callback. The callback will get called when the clearing operation is complete and the display has been cleared. In this example, refreshCallback sets a global boolean 'refreshed' to true when called.

clearing the display

refreshed = false;
int result = display.clearImmediate(refreshCallback);
if(result == LS013B7DH03_OK) {
    while(refreshed == false) sleep();
} else {
    printf("Display error: %d", result);
}

Of course, instead of sleeping while the display is clearing, you could also just continue with the program, and check back whether the callback happened or not.

Then comes the fun part, actually writing stuff on the display! Since the display only supports one-way communication (i.e. you cannot read from it), it uses an internal frame buffer in RAM. So, to actually display something on the LCD, two steps need to happen: writing to the pixel buffer, and at the very end writing the pixel buffer to the LCD.

Pixelbuffer operations

The MemoryLCD library builds upon Simon Ford's TextDisplay library, which means you can use all of that functionality. Even printf is supported!

most important display operations

// Set one pixel at x=10, y=40 to the color White
display.pixel(10,40,White); 

// print "I love mbed" at the character position x=4, y=5
// i.e. starting on row 5, 4 characters from the left border
display.locate(4,5);
display.printf("I love mbed!");

// show a bitmap at a given location
// Constraints: bitmap is 8-bit, MSB first, 1 bit per pixel. Width, height and starting coordinates must be divisible by 8.
// This example: show a bitmap which is 128 pixels wide and high, and start at location 0,0.
display.showBMP(&mbed_logo, 128, 128, 0, 0);

//Draw a line (really a 1px wide rectangle) from (4,10) until (4,15)
display.fill(4, 10, 1, 5, White);

Updating the LCD

Updating the LCD (i.e. moving the framebuffer to the display) happens much the same way as clearing it: asynchronously. To start the update, you call update() on the display, optionally providing a callback to be called after the whole update has happened. In the example below, refreshCallback sets a global boolean 'refreshed' to true when called. Signature: void refreshCallback(void);

updating the display

refreshed = false;
int result = display.update(refreshCallback);
if(result == LS013B7DH03_OK) {
    while(refreshed == false) sleep();
} else {
    printf("Display error: %d", result);
}

Full example

example program

#include "LS013B7DH03.h"
#include "mbed_logo.h"
/******************** Define I/O *****************************/
DigitalOut myled(LED1);

#define SCK     PD2
#define MOSI 	PD0

DigitalOut CS(PD3);
DigitalOut EXTCOM(PC4);
DigitalOut EXTMODE(PD4);
DigitalOut DISP(PD5);

SPI displaySPI(MOSI, NC, SCK);
silabs::LS013B7DH03 display(&displaySPI, &CS, &EXTCOM);

/******************** Define Timers *****************************/

LowPowerTicker timeKeeping;

/***************** Define global variables **********************/
#define INIT_SECONDS		17600

volatile uint32_t prevSeconds = INIT_SECONDS, seconds = INIT_SECONDS;
volatile bool refreshed = false;

/***************** Define callback handlers *********************/
void secondsCallback(void);
void refreshCallback(void);

void secondsCallback(void) {
	seconds++;
}

/**
 * Callback for refresh completion
 */
void refreshCallback(void) {
	refreshed = true;
}

/*************************** MAIN *******************************/
int main() {
    // Enable the LCD
	EXTMODE = 1;
	DISP = 1;

	// Start generating the 1Hz call for keeping time
	timeKeeping.attach(&secondsCallback, 1.0f);

	// Reset the LCD to a blank state. (All white)
	refreshed = false;
	display.clearImmediate(refreshCallback);
	while(refreshed == false) sleep();

	printf("Initialization done! \n");

	// Apply mbed logo bitmap to the pixel buffer
	display.showBMP((uint8_t*)mbed_enabled_logo, 128, 128, 0, 0);
	display.printf("I like MBED!");

	// Push update to the display
	refreshed = false;
	display.update(refreshCallback);

	// Sleep while doing the transmit
	while(refreshed == false) sleep();

	// Go into clock mode
	while(1) {
		sleep();

		// In clock mode, only update once per second
		if(prevSeconds != seconds) {
			display.locate(4,15);
			display.printf("%02d:%02d:%02d", (seconds / 1200) % 24, (seconds / 60) % 60, seconds % 60);
			if(refreshed == true) {
				prevSeconds = seconds;
				refreshed = false;
				display.update(refreshCallback);
			}
		}
	}
}

Datasheet

Datasheet for the LCD (hosted by Mouser)

Committer:
stevew817
Date:
Wed Aug 12 14:06:07 2015 +0000
Revision:
11:0f8ae10b308d
Parent:
2:2f10f00fe56c
Implement Paul Staron's enhancements to the display driver classes, from https://developer.mbed.org/users/star297/code/MemoryLCD/rev/b64f87859c57

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
Steven Cooreman 0:a0faa86660d4 32 #include <mbed.h>
Steven Cooreman 0:a0faa86660d4 33 #include "LS013B7DH03.h"
Steven Cooreman 0:a0faa86660d4 34 #include "SPI.h"
Steven Cooreman 0:a0faa86660d4 35
Steven Cooreman 0:a0faa86660d4 36 /* LS013B7DH03 SPI commands */
Steven Cooreman 0:a0faa86660d4 37 #define LS013B7DH03_CMD_UPDATE (0x01)
Steven Cooreman 0:a0faa86660d4 38 #define LS013B7DH03_CMD_ALL_CLEAR (0x04)
Steven Cooreman 0:a0faa86660d4 39
Steven Cooreman 0:a0faa86660d4 40 /* Macro to switch endianness on char value */
Steven Cooreman 0:a0faa86660d4 41 #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 42
Steven Cooreman 0:a0faa86660d4 43 namespace silabs {
Steven Cooreman 0:a0faa86660d4 44
Steven Cooreman 0:a0faa86660d4 45 LS013B7DH03::LS013B7DH03(mbed::SPI * spi, DigitalOut * CS, DigitalOut * ExtCom, const char *name) : BufferedDisplay(name) {
Steven Cooreman 0:a0faa86660d4 46 //Save pointer to ChipSelect pin
Steven Cooreman 0:a0faa86660d4 47 _CS = CS;
Steven Cooreman 0:a0faa86660d4 48 _CS->write(0);
Steven Cooreman 0:a0faa86660d4 49
Steven Cooreman 0:a0faa86660d4 50 //Save pointer to ExtCom pin
Steven Cooreman 0:a0faa86660d4 51 _EXTCOM = ExtCom;
Steven Cooreman 0:a0faa86660d4 52 _EXTCOM->write(0);
Steven Cooreman 0:a0faa86660d4 53
Steven Cooreman 0:a0faa86660d4 54 //Save pointer to spi peripheral
Steven Cooreman 0:a0faa86660d4 55 _spi = spi;
Steven Cooreman 2:2f10f00fe56c 56 _internalEventCallback.attach(this, &LS013B7DH03::_cbHandler);
Steven Cooreman 0:a0faa86660d4 57
Steven Cooreman 0:a0faa86660d4 58 //Initialize
Steven Cooreman 0:a0faa86660d4 59 _spi->set_dma_usage((DMAUsage)DMA_USAGE_NEVER);
Steven Cooreman 0:a0faa86660d4 60 _refreshCount = 0;
Steven Cooreman 0:a0faa86660d4 61 _lcdPolarity = 0;
Steven Cooreman 0:a0faa86660d4 62 _state = IDLE;
Steven Cooreman 0:a0faa86660d4 63 _completionCallbackPtr = NULL;
Steven Cooreman 0:a0faa86660d4 64 _rowCount = 0;
Steven Cooreman 0:a0faa86660d4 65
Steven Cooreman 0:a0faa86660d4 66 //Start toggling the EXTCOM pin
Steven Cooreman 2:2f10f00fe56c 67 //_displayToggler.attach(this, &LS013B7DH03::toggle, 0.008f);
Steven Cooreman 0:a0faa86660d4 68 }
Steven Cooreman 0:a0faa86660d4 69
Steven Cooreman 0:a0faa86660d4 70 /**
Steven Cooreman 0:a0faa86660d4 71 * Call this function at 55 ~ 65 Hz to keep the display up-to-date.
Steven Cooreman 0:a0faa86660d4 72 */
Steven Cooreman 0:a0faa86660d4 73 void LS013B7DH03::toggle() {
Steven Cooreman 0:a0faa86660d4 74 _EXTCOM->write(!_EXTCOM->read());
Steven Cooreman 0:a0faa86660d4 75 _refreshCount++;
Steven Cooreman 0:a0faa86660d4 76 }
Steven Cooreman 0:a0faa86660d4 77
Steven Cooreman 0:a0faa86660d4 78 /**
Steven Cooreman 0:a0faa86660d4 79 * Function to get internal refresh counter
Steven Cooreman 0:a0faa86660d4 80 */
Steven Cooreman 0:a0faa86660d4 81 uint32_t LS013B7DH03::getRefreshTicks() {
Steven Cooreman 0:a0faa86660d4 82 return _refreshCount;
Steven Cooreman 0:a0faa86660d4 83 }
Steven Cooreman 0:a0faa86660d4 84
Steven Cooreman 0:a0faa86660d4 85 /**
Steven Cooreman 0:a0faa86660d4 86 * Call this function to push all changes to the display
Steven Cooreman 0:a0faa86660d4 87 */
Steven Cooreman 0:a0faa86660d4 88 int LS013B7DH03::update( cbptr_t callback ) {
Steven Cooreman 0:a0faa86660d4 89 uint32_t rowCount = 0;
Steven Cooreman 0:a0faa86660d4 90 bool update = false;
Steven Cooreman 0:a0faa86660d4 91
Steven Cooreman 0:a0faa86660d4 92 // Check if something actually changed in the pixelbuffer
Steven Cooreman 0:a0faa86660d4 93 for(rowCount = 0; rowCount < DISPLAY_HEIGHT/DISPLAY_BUFFER_TYPE_SIZE; rowCount++) {
Steven Cooreman 0:a0faa86660d4 94 if(_dirtyRows[rowCount] != 0) update = true;
Steven Cooreman 0:a0faa86660d4 95 }
Steven Cooreman 0:a0faa86660d4 96
Steven Cooreman 0:a0faa86660d4 97 if(update == false) return LS013B7DH03_NO_ACTION;
Steven Cooreman 0:a0faa86660d4 98
Steven Cooreman 0:a0faa86660d4 99 // Watch out to not mess up a transfer
Steven Cooreman 0:a0faa86660d4 100 if(_state != IDLE) return LS013B7DH03_ERROR_BUSY;
Steven Cooreman 0:a0faa86660d4 101
Steven Cooreman 0:a0faa86660d4 102 _completionCallbackPtr = callback;
Steven Cooreman 0:a0faa86660d4 103
Steven Cooreman 0:a0faa86660d4 104 // Take control
Steven Cooreman 0:a0faa86660d4 105 _state = WAIT_WRITE;
Steven Cooreman 0:a0faa86660d4 106 _rowCount = 0;
Steven Cooreman 0:a0faa86660d4 107
Steven Cooreman 0:a0faa86660d4 108 //Initialize the command vector
Steven Cooreman 0:a0faa86660d4 109 _cmd[0] = (uint8_t)SWAP8(LS013B7DH03_CMD_UPDATE);
Steven Cooreman 0:a0faa86660d4 110 _cmd[1] = SWAP8(1);
Steven Cooreman 0:a0faa86660d4 111
Steven Cooreman 0:a0faa86660d4 112 // Activate LCD
Steven Cooreman 0:a0faa86660d4 113 _CS->write(1);
Steven Cooreman 0:a0faa86660d4 114 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
Steven Cooreman 0:a0faa86660d4 115
Steven Cooreman 0:a0faa86660d4 116 return LS013B7DH03_OK;
Steven Cooreman 0:a0faa86660d4 117 }
Steven Cooreman 0:a0faa86660d4 118
Steven Cooreman 0:a0faa86660d4 119 /**
Steven Cooreman 0:a0faa86660d4 120 * Function to test display buffer
Steven Cooreman 0:a0faa86660d4 121 */
Steven Cooreman 0:a0faa86660d4 122 int LS013B7DH03::showDemo() {
Steven Cooreman 0:a0faa86660d4 123 for(uint32_t i = 0; i < DISPLAY_BUFFER_ELEMENTS; i+=2) {
Steven Cooreman 0:a0faa86660d4 124 _pixelBuffer[i] = 0x00FFF000;
Steven Cooreman 0:a0faa86660d4 125 }
Steven Cooreman 0:a0faa86660d4 126 memset((void*)_dirtyRows, 0xFF, sizeof(_dirtyRows));
Steven Cooreman 0:a0faa86660d4 127
Steven Cooreman 0:a0faa86660d4 128 return LS013B7DH03_OK;
Steven Cooreman 0:a0faa86660d4 129 }
Steven Cooreman 0:a0faa86660d4 130
Steven Cooreman 0:a0faa86660d4 131 /**
Steven Cooreman 0:a0faa86660d4 132 * Call this function to immediately clear the display
Steven Cooreman 0:a0faa86660d4 133 */
Steven Cooreman 0:a0faa86660d4 134 int LS013B7DH03::clearImmediate( cbptr_t callback ) {
Steven Cooreman 0:a0faa86660d4 135 // Watch out to not mess up a transfer
Steven Cooreman 0:a0faa86660d4 136 if(_state != IDLE) return LS013B7DH03_ERROR_BUSY;
Steven Cooreman 0:a0faa86660d4 137
Steven Cooreman 0:a0faa86660d4 138 _state = WAIT_CLEAR;
Steven Cooreman 0:a0faa86660d4 139 _completionCallbackPtr = callback;
Steven Cooreman 0:a0faa86660d4 140
Steven Cooreman 0:a0faa86660d4 141 // Clear out the pixel buffer
Steven Cooreman 0:a0faa86660d4 142 memset((void*)_pixelBuffer, White, sizeof(_pixelBuffer));
Steven Cooreman 0:a0faa86660d4 143 memset((void*)_dirtyRows, 0, sizeof(_dirtyRows));
Steven Cooreman 0:a0faa86660d4 144
Steven Cooreman 0:a0faa86660d4 145 _cmd[0] = (uint8_t)(SWAP8(LS013B7DH03_CMD_ALL_CLEAR | _lcdPolarity));
Steven Cooreman 0:a0faa86660d4 146 _cmd[1] = 0;
Steven Cooreman 0:a0faa86660d4 147
Steven Cooreman 0:a0faa86660d4 148 // Wait for the ChipSelect line
Steven Cooreman 0:a0faa86660d4 149 _CS->write(1);
Steven Cooreman 0:a0faa86660d4 150 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
Steven Cooreman 0:a0faa86660d4 151
Steven Cooreman 0:a0faa86660d4 152 return LS013B7DH03_OK;
Steven Cooreman 0:a0faa86660d4 153 }
Steven Cooreman 0:a0faa86660d4 154
Steven Cooreman 0:a0faa86660d4 155 void LS013B7DH03::_cbHandlerTimeout( void ) {
Steven Cooreman 0:a0faa86660d4 156 this->_cbHandler(0);
Steven Cooreman 0:a0faa86660d4 157 }
Steven Cooreman 0:a0faa86660d4 158
Steven Cooreman 0:a0faa86660d4 159 void LS013B7DH03::_cbHandler( int event ) {
Steven Cooreman 0:a0faa86660d4 160 if((_state == WAIT_WRITE) || (_state == WRITING))
Steven Cooreman 0:a0faa86660d4 161 {
Steven Cooreman 0:a0faa86660d4 162 _state = WRITING;
Steven Cooreman 0:a0faa86660d4 163 while(_rowCount < DISPLAY_HEIGHT) {
Steven Cooreman 0:a0faa86660d4 164 // Determine the next line to send
Steven Cooreman 0:a0faa86660d4 165 if((_dirtyRows[_rowCount / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (_rowCount % DISPLAY_BUFFER_TYPE_SIZE))) != 0) {
Steven Cooreman 0:a0faa86660d4 166
Steven Cooreman 0:a0faa86660d4 167 // Row is dirty, send an update to the display
Steven Cooreman 0:a0faa86660d4 168 _cmd[1] = (uint8_t)SWAP8(_rowCount + 1);
Steven Cooreman 0:a0faa86660d4 169 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 170
Steven Cooreman 2:2f10f00fe56c 171 if(_spi->transfer((uint8_t*)_cmd, (2 + (DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE))) , (uint8_t*)NULL, 0, _internalEventCallback, SPI_EVENT_COMPLETE) != 0) {
Steven Cooreman 0:a0faa86660d4 172 // SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
Steven Cooreman 0:a0faa86660d4 173 _state = DONE;
Steven Cooreman 0:a0faa86660d4 174
Steven Cooreman 0:a0faa86660d4 175 // Make sure the handler is called again
Steven Cooreman 0:a0faa86660d4 176 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
Steven Cooreman 0:a0faa86660d4 177 }
Steven Cooreman 0:a0faa86660d4 178
Steven Cooreman 0:a0faa86660d4 179 // Transaction is in progress, so update row state
Steven Cooreman 0:a0faa86660d4 180 _dirtyRows[_rowCount / DISPLAY_BUFFER_TYPE_SIZE] &= ~(1 << (_rowCount % DISPLAY_BUFFER_TYPE_SIZE));
Steven Cooreman 0:a0faa86660d4 181 _rowCount++;
Steven Cooreman 0:a0faa86660d4 182 return;
Steven Cooreman 0:a0faa86660d4 183 }
Steven Cooreman 0:a0faa86660d4 184
Steven Cooreman 0:a0faa86660d4 185 // Row wasn't touched, so check the next row
Steven Cooreman 0:a0faa86660d4 186 _rowCount++;
Steven Cooreman 0:a0faa86660d4 187 }
Steven Cooreman 0:a0faa86660d4 188
Steven Cooreman 0:a0faa86660d4 189 // Done sending!
Steven Cooreman 0:a0faa86660d4 190 _cmd[1] = 0xFF;
Steven Cooreman 0:a0faa86660d4 191 _state = TRANSFERS_DONE;
Steven Cooreman 2:2f10f00fe56c 192 if(_spi->transfer((uint8_t*)_cmd, 2, (uint8_t*)NULL, 0, _internalEventCallback, SPI_EVENT_COMPLETE) != 0) {
Steven Cooreman 0:a0faa86660d4 193 // SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
Steven Cooreman 0:a0faa86660d4 194 _state = DONE;
Steven Cooreman 0:a0faa86660d4 195
Steven Cooreman 0:a0faa86660d4 196 // Make sure the handler is called again
Steven Cooreman 0:a0faa86660d4 197 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
Steven Cooreman 0:a0faa86660d4 198 }
Steven Cooreman 0:a0faa86660d4 199 return;
Steven Cooreman 0:a0faa86660d4 200 }
Steven Cooreman 0:a0faa86660d4 201 else if (_state == WAIT_CLEAR)
Steven Cooreman 0:a0faa86660d4 202 {
Steven Cooreman 0:a0faa86660d4 203 _state = TRANSFERS_DONE;
Steven Cooreman 2:2f10f00fe56c 204 if(_spi->transfer((uint8_t*)_cmd, 2, (uint8_t*)NULL, 0, _internalEventCallback, SPI_EVENT_COMPLETE) != 0) {
Steven Cooreman 0:a0faa86660d4 205 // SPI is busy, with another transaction. This means the data to the LCD has been corrupted, so fail here.
Steven Cooreman 0:a0faa86660d4 206 _state = DONE;
Steven Cooreman 0:a0faa86660d4 207
Steven Cooreman 0:a0faa86660d4 208 // Make sure the handler is called again
Steven Cooreman 0:a0faa86660d4 209 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.1f);
Steven Cooreman 0:a0faa86660d4 210 }
Steven Cooreman 0:a0faa86660d4 211 return;
Steven Cooreman 0:a0faa86660d4 212 }
Steven Cooreman 0:a0faa86660d4 213 else if (_state == TRANSFERS_DONE)
Steven Cooreman 0:a0faa86660d4 214 {
Steven Cooreman 0:a0faa86660d4 215 _state = DONE;
Steven Cooreman 0:a0faa86660d4 216 _csTimeout.attach(this, &LS013B7DH03::_cbHandlerTimeout, 0.01f);
Steven Cooreman 0:a0faa86660d4 217 return;
Steven Cooreman 0:a0faa86660d4 218 }
Steven Cooreman 0:a0faa86660d4 219 else if (_state == DONE)
Steven Cooreman 0:a0faa86660d4 220 {
Steven Cooreman 0:a0faa86660d4 221 _CS->write(0);
Steven Cooreman 0:a0faa86660d4 222 _state = IDLE;
Steven Cooreman 0:a0faa86660d4 223 if(_completionCallbackPtr != 0) _completionCallbackPtr();
Steven Cooreman 0:a0faa86660d4 224 return;
Steven Cooreman 0:a0faa86660d4 225 }
Steven Cooreman 0:a0faa86660d4 226 }
Steven Cooreman 0:a0faa86660d4 227
Steven Cooreman 0:a0faa86660d4 228 } // namespace silabs