00001
00018 #include <stdint.h>
00019 #include <stdbool.h>
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023
00024
00025 #include "displayconfigall.h"
00026 #include "displaypal.h"
00027 #include "displaybackend.h"
00028 #include "displayls013b7dh03.h"
00029
00032
00033
00034
00035
00036
00037 #define LS013B7DH03_CMD_UPDATE (0x01)
00038 #define LS013B7DH03_CMD_ALL_CLEAR (0x04)
00039
00040
00041 #ifndef LS013B7DH03_POLARITY_INVERSION_FREQUENCY
00042 #define LS013B7DH03_POLARITY_INVERSION_FREQUENCY (64)
00043 #endif
00044
00045 #ifdef USE_CONTROL_BYTES
00046 #define LS013B7DH03_CONTROL_BYTES (2)
00047 #else
00048 #define LS013B7DH03_CONTROL_BYTES (0)
00049 #endif
00050
00051 #ifdef PIXEL_MATRIX_ALLOC_SUPPORT
00052
00053 #ifdef USE_STATIC_PIXEL_MATRIX_POOL
00054
00055
00056 #undef USE_MALLOC
00057 #endif
00058
00059 #ifdef USE_MALLOC
00060
00061
00062 #undef USE_STATIC_PIXEL_MATRIX_POOL
00063 #endif
00064
00065 #endif
00066
00067
00068
00069
00070
00071
00072 #ifdef PIXEL_MATRIX_ALLOC_SUPPORT
00073 #ifndef PIXEL_MATRIX_ALIGNMENT
00074 typedef uint8_t PixelMatrixAlign_t;
00075 #else
00076 #if (1 == PIXEL_MATRIX_ALIGNMENT)
00077 typedef uint8_t PixelMatrixAlign_t;
00078 #elif (2 == PIXEL_MATRIX_ALIGNMENT)
00079 typedef uint16_t PixelMatrixAlign_t;
00080 #elif (4 == PIXEL_MATRIX_ALIGNMENT)
00081 typedef uint32_t PixelMatrixAlign_t;
00082 #else
00083 #error Unsupported PIXEL_MATRIX_ALIGNMENT.
00084 #endif
00085 #endif
00086 #endif
00087
00088
00089
00090
00091
00092
00093
00094 static uint8_t lcdPolarity = 0;
00095
00096 #ifdef PIXEL_MATRIX_ALLOC_SUPPORT
00097 #ifdef USE_STATIC_PIXEL_MATRIX_POOL
00098 #define PIXEL_MATRIX_POOL_ELEMENTS \
00099 (PIXEL_MATRIX_POOL_SIZE/sizeof(PixelMatrixAlign_t) + \
00100 ((PIXEL_MATRIX_POOL_SIZE%sizeof(PixelMatrixAlign_t))? 1 : 0))
00101 static PixelMatrixAlign_t pixelMatrixPoolBase[PIXEL_MATRIX_POOL_ELEMENTS];
00102 static PixelMatrixAlign_t* pixelMatrixPool = pixelMatrixPoolBase;
00103 #endif
00104 #endif
00105
00106
00107
00108
00109
00110
00111 static EMSTATUS DisplayEnable(DISPLAY_Device_t* device,
00112 bool enable);
00113 static EMSTATUS DisplayClear(void);
00114 #ifndef POLARITY_INVERSION_EXTCOMIN_PAL_AUTO_TOGGLE
00115 static EMSTATUS DisplayPolarityInverse (void);
00116 #endif
00117
00118 #ifdef PIXEL_MATRIX_ALLOC_SUPPORT
00119 static EMSTATUS PixelMatrixAllocate( DISPLAY_Device_t* device,
00120 unsigned int width,
00121 #ifdef EMWIN_WORKAROUND
00122 unsigned int userStride,
00123 #endif
00124 unsigned int height,
00125 DISPLAY_PixelMatrix_t *pixelMatrix);
00126 static EMSTATUS PixelMatrixFree( DISPLAY_Device_t* device,
00127 DISPLAY_PixelMatrix_t pixelMatrix);
00128 #endif
00129 static EMSTATUS PixelMatrixDraw( DISPLAY_Device_t* device,
00130 DISPLAY_PixelMatrix_t pixelMatrix,
00131 unsigned int startColumn,
00132 unsigned int width,
00133 #ifdef EMWIN_WORKAROUND
00134 unsigned int userStride,
00135 #endif
00136 unsigned int startRow,
00137 unsigned int height );
00138 static EMSTATUS PixelMatrixClear( DISPLAY_Device_t* device,
00139 DISPLAY_PixelMatrix_t pixelMatrix,
00140 unsigned int width,
00141 unsigned int height);
00142 static EMSTATUS DriverRefresh (DISPLAY_Device_t* device);
00143
00144
00145
00146
00147
00148
00149
00154 EMSTATUS DISPLAY_Ls013b7dh03Init(void)
00155 {
00156 DISPLAY_Device_t display;
00157 EMSTATUS status;
00158
00159
00160 PAL_TimerInit();
00161 PAL_SpiInit();
00162 PAL_GpioInit();
00163
00164
00165 PAL_GpioPinModeSet(LCD_PORT_SCLK, LCD_PIN_SCLK, palGpioModePushPull,0);
00166 PAL_GpioPinModeSet(LCD_PORT_SI, LCD_PIN_SI, palGpioModePushPull,0);
00167 PAL_GpioPinModeSet(LCD_PORT_SCS, LCD_PIN_SCS, palGpioModePushPull,0);
00168 PAL_GpioPinModeSet(LCD_PORT_DISP_SEL,LCD_PIN_DISP_SEL,palGpioModePushPull,0);
00169 PAL_GpioPinModeSet(LCD_PORT_DISP_PWR,LCD_PIN_DISP_PWR,palGpioModePushPull,0);
00170 PAL_GpioPinModeSet(LCD_PORT_EXTMODE, LCD_PIN_EXTMODE, palGpioModePushPull,0);
00171 PAL_GpioPinModeSet(LCD_PORT_EXTCOMIN,LCD_PIN_EXTCOMIN,palGpioModePushPull,0);
00172
00173 #ifdef PAL_TIMER_REPEAT_FUNCTION
00174
00175
00176
00177
00178 status =
00179 PAL_TimerRepeat((void(*)(void*)) DisplayPolarityInverse, 0,
00180 LS013B7DH03_POLARITY_INVERSION_FREQUENCY);
00181 #elif defined POLARITY_INVERSION_EXTCOMIN_PAL_AUTO_TOGGLE
00182
00183 status = PAL_GpioPinAutoToggle(LCD_PORT_EXTCOMIN, LCD_PIN_EXTCOMIN,
00184 LS013B7DH03_POLARITY_INVERSION_FREQUENCY);
00185 #else
00186
00187 return DISPLAY_EMSTATUS_NOT_SUPPORTED;
00188 #endif
00189 if (PAL_EMSTATUS_OK != status)
00190 {
00191 return status;
00192 }
00193
00194
00195 display.name = SHARP_MEMLCD_DEVICE_NAME;
00196 display.colourMode = DISPLAY_COLOUR_MODE_MONOCHROME_INVERSE;
00197 display.addressMode = DISPLAY_ADDRESSING_BY_ROWS_ONLY;
00198 display.geometry.width = LS013B7DH03_WIDTH;
00199 display.geometry.height = LS013B7DH03_HEIGHT;
00200
00201 display.geometry.stride =
00202 display.geometry.width + LS013B7DH03_CONTROL_BYTES*8;
00203
00204 display.pDisplayPowerOn = DisplayEnable;
00205 #ifdef PIXEL_MATRIX_ALLOC_SUPPORT
00206 display.pPixelMatrixAllocate = PixelMatrixAllocate;
00207 display.pPixelMatrixFree = PixelMatrixFree;
00208 #else
00209 display.pPixelMatrixAllocate = NULL;
00210 display.pPixelMatrixFree = NULL;
00211 #endif
00212 display.pPixelMatrixDraw = PixelMatrixDraw;
00213 display.pPixelMatrixClear = PixelMatrixClear;
00214 display.pDriverRefresh = DriverRefresh;
00215
00216 status = DISPLAY_DeviceRegister (&display);
00217
00218 if (DISPLAY_EMSTATUS_OK == status)
00219 {
00220
00221 DisplayEnable(&display, true);
00222
00223
00224 DisplayClear();
00225 }
00226
00227 return status;
00228 }
00229
00230
00231
00232
00233
00234
00235
00242 static EMSTATUS DriverRefresh(DISPLAY_Device_t* device)
00243 {
00244 EMSTATUS status = DISPLAY_EMSTATUS_OK;
00245
00246 (void) device;
00247
00248
00249 PAL_TimerInit();
00250 PAL_SpiInit();
00251
00252 return status;
00253 }
00254
00255
00256
00269 static EMSTATUS DisplayEnable(DISPLAY_Device_t* device,
00270 bool enable)
00271 {
00272 (void) device;
00273
00274 if (enable)
00275 {
00276
00277 PAL_GpioPinOutSet(LCD_PORT_DISP_SEL, LCD_PIN_DISP_SEL);
00278
00279 PAL_GpioPinOutSet(LCD_PORT_DISP_PWR, LCD_PIN_DISP_PWR);
00280 }
00281 else
00282 {
00283
00284 PAL_GpioPinOutClear(LCD_PORT_DISP_PWR, LCD_PIN_DISP_PWR);
00285
00286 PAL_GpioPinOutClear(LCD_PORT_DISP_SEL, LCD_PIN_DISP_SEL);
00287 }
00288
00289 return DISPLAY_EMSTATUS_OK;
00290 }
00291
00292
00293
00300 static EMSTATUS DisplayClear ( void )
00301 {
00302 uint16_t cmd;
00303
00304
00305 PAL_GpioPinOutSet( LCD_PORT_SCS, LCD_PIN_SCS );
00306
00307
00308 PAL_TimerMicroSecondsDelay(6);
00309
00310
00311 cmd = LS013B7DH03_CMD_ALL_CLEAR | lcdPolarity;
00312 PAL_SpiTransmit ((uint8_t*) &cmd, 2 );
00313
00314
00315 PAL_TimerMicroSecondsDelay(2);
00316
00317
00318 PAL_GpioPinOutClear( LCD_PORT_SCS, LCD_PIN_SCS );
00319
00320 return DISPLAY_EMSTATUS_OK;
00321 }
00322
00323
00324 #ifdef PAL_TIMER_REPEAT_FUNCTION
00325
00326
00334 static EMSTATUS DisplayPolarityInverse (void)
00335 {
00336 #ifdef POLARITY_INVERSION_EXTCOMIN
00337
00338
00339 PAL_GpioPinOutToggle( LCD_PORT_EXTCOMIN, LCD_PIN_EXTCOMIN );
00340
00341 #else
00342
00343
00344 PAL_GpioPinOutSet( LCD_PORT_SCS, LCD_PIN_SCS );
00345
00346
00347 PAL_TimerMicroSecondsDelay(6);
00348
00349
00350 PAL_SpiTransmit ((uint8_t*) &lcdPolarity, 2 );
00351
00352
00353 PAL_TimerMicroSecondsDelay(2);
00354
00355 PAL_GpioPinOutClear( LCD_PORT_SCS, LCD_PIN_SCS );
00356
00357
00358 if (lcdPolarity == 0x00)
00359 {
00360 lcdPolarity = 0x02;
00361 }
00362 else
00363 {
00364 lcdPolarity = 0x00;
00365 }
00366
00367 #endif
00368
00369 return DISPLAY_EMSTATUS_OK;
00370 }
00371
00372 #endif
00373
00374
00375 #ifdef PIXEL_MATRIX_ALLOC_SUPPORT
00376
00394 static EMSTATUS PixelMatrixAllocate( DISPLAY_Device_t* device,
00395 unsigned int width,
00396 #ifdef EMWIN_WORKAROUND
00397 unsigned int userStride,
00398 #endif
00399 unsigned int height,
00400 DISPLAY_PixelMatrix_t *pixelMatrix)
00401 {
00402 #ifdef EMWIN_WORKAROUND
00403 unsigned int allocSize = (userStride/8 + LS013B7DH03_CONTROL_BYTES) * height;
00404 #else
00405 unsigned int allocSize = (width/8 + LS013B7DH03_CONTROL_BYTES) * height;
00406 #endif
00407
00408 (void) device;
00409
00410 if (width != LS013B7DH03_WIDTH)
00411 return DISPLAY_EMSTATUS_OUT_OF_RANGE;
00412 #ifdef EMWIN_WORKAROUND
00413 if (userStride < width)
00414 return DISPLAY_EMSTATUS_INVALID_PARAMETER;
00415 #endif
00416
00417 #ifdef USE_MALLOC
00418
00419
00420 *pixelMatrix = (DISPLAY_PixelMatrix_t) malloc (allocSize);
00421
00422 if (NULL == *pixelMatrix)
00423 return DISPLAY_EMSTATUS_NOT_ENOUGH_MEMORY;
00424 else
00425 return DISPLAY_EMSTATUS_OK;
00426
00427 #endif
00428
00429 #ifdef USE_STATIC_PIXEL_MATRIX_POOL
00430
00431 if (((uint8_t*)pixelMatrixPool) + allocSize >
00432 ((uint8_t*)pixelMatrixPoolBase) + PIXEL_MATRIX_POOL_SIZE)
00433 {
00434 *pixelMatrix = NULL;
00435 return DISPLAY_EMSTATUS_NOT_ENOUGH_MEMORY;
00436 }
00437 else
00438 {
00439 *pixelMatrix = pixelMatrixPool;
00440 pixelMatrixPool += allocSize / sizeof(PixelMatrixAlign_t) +
00441 ((allocSize % sizeof(PixelMatrixAlign_t))? 1 : 0);
00442 return DISPLAY_EMSTATUS_OK;
00443 }
00444
00445 #endif
00446
00447 }
00448 #endif
00449
00450
00451 #ifdef PIXEL_MATRIX_ALLOC_SUPPORT
00452
00462 static EMSTATUS PixelMatrixFree( DISPLAY_Device_t* device,
00463 DISPLAY_PixelMatrix_t pixelMatrix)
00464 {
00465 (void) device;
00466
00467 #ifdef USE_MALLOC
00468 free(pixelMatrix);
00469 return DISPLAY_EMSTATUS_OK;
00470 #endif
00471
00472 #ifdef USE_STATIC_PIXEL_MATRIX_POOL
00473
00474
00475
00476
00477
00478 (void) pixelMatrix;
00479 return DISPLAY_EMSTATUS_NOT_SUPPORTED;
00480 #endif
00481 }
00482 #endif
00483
00484
00485
00502 static EMSTATUS PixelMatrixClear( DISPLAY_Device_t* device,
00503 DISPLAY_PixelMatrix_t pixelMatrix,
00504 unsigned int width,
00505 unsigned int height)
00506 {
00507 uint8_t* pByte = (uint8_t*) pixelMatrix;
00508 unsigned int i;
00509
00510 (void) device;
00511 (void) width;
00512
00513 for (i=0; i<height; i++)
00514 {
00515
00516 memset(pByte, 0, LS013B7DH03_WIDTH/8);
00517 pByte += LS013B7DH03_WIDTH/8;
00518
00519 #ifdef USE_CONTROL_BYTES
00520
00521 *pByte++ = 0xff;
00522
00523 *pByte++ = i+1;
00524 #endif
00525 }
00526
00527 return DISPLAY_EMSTATUS_OK;
00528 }
00529
00530
00531 #ifdef USE_CONTROL_BYTES
00532
00543 static EMSTATUS pixelMatrixSetup( DISPLAY_PixelMatrix_t pixelMatrix,
00544 unsigned int startRow,
00545 unsigned int height
00546 #ifdef EMWIN_WORKAROUND
00547 ,
00548 unsigned int userStride
00549 #endif
00550 )
00551 {
00552 int i = 0;
00553 uint8_t* pByte = (uint8_t*) pixelMatrix;
00554 #ifdef EMWIN_WORKAROUND
00555 int strideGap =
00556 (userStride-LS013B7DH03_WIDTH-(LS013B7DH03_CONTROL_BYTES*8)) /
00557 8 / sizeof(uint8_t);
00558 if ((userStride-LS013B7DH03_WIDTH) % sizeof(uint16_t))
00559 return DISPLAY_EMSTATUS_INVALID_PARAMETER;
00560 #endif
00561
00562 while (i<height)
00563 {
00564 pByte += LS013B7DH03_WIDTH/8;
00565
00566 *pByte++ = 0xff;
00567
00568 if (i == height-1)
00569 {
00570
00571 *pByte++ = 0xff;
00572 break;
00573 }
00574 else
00575
00576 *pByte++ = startRow + (++i);
00577
00578 #ifdef EMWIN_WORKAROUND
00579 pByte += strideGap;
00580 #endif
00581 }
00582
00583 return DISPLAY_EMSTATUS_OK;
00584 }
00585
00586 #endif
00587
00588
00589
00606 static EMSTATUS PixelMatrixDraw( DISPLAY_Device_t* device,
00607 DISPLAY_PixelMatrix_t pixelMatrix,
00608 unsigned int startColumn,
00609 unsigned int width,
00610 #ifdef EMWIN_WORKAROUND
00611 unsigned int userStride,
00612 #endif
00613 unsigned int startRow,
00614 unsigned int height )
00615 {
00616 unsigned int i;
00617 uint16_t* p = (uint16_t *)pixelMatrix;
00618 uint16_t cmd;
00619 #ifdef EMWIN_WORKAROUND
00620 int strideGap =
00621 (userStride-width-(LS013B7DH03_CONTROL_BYTES*8)) / 8 / sizeof(uint16_t);
00622 if ((userStride-width) % sizeof(uint16_t))
00623 return DISPLAY_EMSTATUS_INVALID_PARAMETER;
00624 #else
00625 (void) width;
00626 #endif
00627 (void) startColumn;
00628 (void) device;
00629
00630
00631
00632 startRow++;
00633
00634 #ifdef USE_CONTROL_BYTES
00635
00636 pixelMatrixSetup(pixelMatrix, startRow, height
00637 #ifdef EMWIN_WORKAROUND
00638 , userStride
00639 #endif
00640 );
00641 #endif
00642
00643
00644 PAL_GpioPinOutSet( LCD_PORT_SCS, LCD_PIN_SCS );
00645
00646
00647 PAL_TimerMicroSecondsDelay(6);
00648
00649
00650 cmd = LS013B7DH03_CMD_UPDATE | (startRow << 8);
00651 PAL_SpiTransmit((uint8_t*) &cmd, 2 );
00652
00653
00654 for ( i=0; i<height; i++ ) {
00655
00656
00657 PAL_SpiTransmit((uint8_t*) p,
00658 LS013B7DH03_WIDTH/8 + LS013B7DH03_CONTROL_BYTES);
00659 p+=(LS013B7DH03_WIDTH/8 + LS013B7DH03_CONTROL_BYTES) / sizeof(uint16_t);
00660
00661 #ifndef USE_CONTROL_BYTES
00662 if (i==height-1)
00663 {
00664 cmd = 0xffff;
00665 }
00666 else
00667 {
00668 cmd = 0xff | ((startRow+i+1) << 8);
00669 }
00670 PAL_SpiTransmit((uint8_t*) &cmd, 2 );
00671 #endif
00672
00673 #ifdef EMWIN_WORKAROUND
00674 p += strideGap;
00675 #endif
00676
00677 }
00678
00679
00680 PAL_TimerMicroSecondsDelay(2);
00681
00682
00683 PAL_GpioPinOutClear( LCD_PORT_SCS, LCD_PIN_SCS );
00684
00685 return DISPLAY_EMSTATUS_OK;
00686 }
00687