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
00170 #if defined( LCD_PORT_DISP_PWR )
00171 PAL_GpioPinModeSet(LCD_PORT_DISP_PWR,LCD_PIN_DISP_PWR,palGpioModePushPull,0);
00172 #endif
00173
00174 PAL_GpioPinModeSet(LCD_PORT_EXTMODE, LCD_PIN_EXTMODE, palGpioModePushPull,0);
00175 PAL_GpioPinModeSet(LCD_PORT_EXTCOMIN,LCD_PIN_EXTCOMIN,palGpioModePushPull,0);
00176
00177 #ifdef PAL_TIMER_REPEAT_FUNCTION
00178
00179
00180
00181
00182 status =
00183 PAL_TimerRepeat((void(*)(void*)) DisplayPolarityInverse, 0,
00184 LS013B7DH03_POLARITY_INVERSION_FREQUENCY);
00185 #elif defined POLARITY_INVERSION_EXTCOMIN_PAL_AUTO_TOGGLE
00186
00187 status = PAL_GpioPinAutoToggle(LCD_PORT_EXTCOMIN, LCD_PIN_EXTCOMIN,
00188 LS013B7DH03_POLARITY_INVERSION_FREQUENCY);
00189 #else
00190
00191 return DISPLAY_EMSTATUS_NOT_SUPPORTED;
00192 #endif
00193 if (PAL_EMSTATUS_OK != status)
00194 {
00195 return status;
00196 }
00197
00198
00199 display.name = SHARP_MEMLCD_DEVICE_NAME;
00200 display.colourMode = DISPLAY_COLOUR_MODE_MONOCHROME_INVERSE;
00201 display.addressMode = DISPLAY_ADDRESSING_BY_ROWS_ONLY;
00202 display.geometry.width = LS013B7DH03_WIDTH;
00203 display.geometry.height = LS013B7DH03_HEIGHT;
00204
00205 display.geometry.stride =
00206 display.geometry.width + LS013B7DH03_CONTROL_BYTES*8;
00207
00208 display.pDisplayPowerOn = DisplayEnable;
00209 #ifdef PIXEL_MATRIX_ALLOC_SUPPORT
00210 display.pPixelMatrixAllocate = PixelMatrixAllocate;
00211 display.pPixelMatrixFree = PixelMatrixFree;
00212 #else
00213 display.pPixelMatrixAllocate = NULL;
00214 display.pPixelMatrixFree = NULL;
00215 #endif
00216 display.pPixelMatrixDraw = PixelMatrixDraw;
00217 display.pPixelMatrixClear = PixelMatrixClear;
00218 display.pDriverRefresh = DriverRefresh;
00219
00220 status = DISPLAY_DeviceRegister (&display);
00221
00222 if (DISPLAY_EMSTATUS_OK == status)
00223 {
00224
00225 DisplayEnable(&display, true);
00226
00227
00228 DisplayClear();
00229 }
00230
00231 return status;
00232 }
00233
00234
00235
00236
00237
00238
00239
00246 static EMSTATUS DriverRefresh(DISPLAY_Device_t* device)
00247 {
00248 EMSTATUS status = DISPLAY_EMSTATUS_OK;
00249
00250 (void) device;
00251
00252
00253 PAL_TimerInit();
00254 PAL_SpiInit();
00255
00256 return status;
00257 }
00258
00259
00260
00273 static EMSTATUS DisplayEnable(DISPLAY_Device_t* device,
00274 bool enable)
00275 {
00276 (void) device;
00277
00278 if (enable)
00279 {
00280
00281 PAL_GpioPinOutSet(LCD_PORT_DISP_SEL, LCD_PIN_DISP_SEL);
00282
00283 #if defined( LCD_PORT_DISP_PWR )
00284
00285 PAL_GpioPinOutSet(LCD_PORT_DISP_PWR, LCD_PIN_DISP_PWR);
00286 #endif
00287 }
00288 else
00289 {
00290 #if defined( LCD_PORT_DISP_PWR )
00291
00292 PAL_GpioPinOutClear(LCD_PORT_DISP_PWR, LCD_PIN_DISP_PWR);
00293 #endif
00294
00295
00296 PAL_GpioPinOutClear(LCD_PORT_DISP_SEL, LCD_PIN_DISP_SEL);
00297 }
00298
00299 return DISPLAY_EMSTATUS_OK;
00300 }
00301
00302
00303
00310 static EMSTATUS DisplayClear ( void )
00311 {
00312 uint16_t cmd;
00313
00314
00315 PAL_GpioPinOutSet( LCD_PORT_SCS, LCD_PIN_SCS );
00316
00317
00318 PAL_TimerMicroSecondsDelay(6);
00319
00320
00321 cmd = LS013B7DH03_CMD_ALL_CLEAR | lcdPolarity;
00322 PAL_SpiTransmit ((uint8_t*) &cmd, 2 );
00323
00324
00325 PAL_TimerMicroSecondsDelay(2);
00326
00327
00328 PAL_GpioPinOutClear( LCD_PORT_SCS, LCD_PIN_SCS );
00329
00330 return DISPLAY_EMSTATUS_OK;
00331 }
00332
00333
00334 #ifdef PAL_TIMER_REPEAT_FUNCTION
00335
00336
00344 static EMSTATUS DisplayPolarityInverse (void)
00345 {
00346 #ifdef POLARITY_INVERSION_EXTCOMIN
00347
00348
00349 PAL_GpioPinOutToggle( LCD_PORT_EXTCOMIN, LCD_PIN_EXTCOMIN );
00350
00351 #else
00352
00353
00354 PAL_GpioPinOutSet( LCD_PORT_SCS, LCD_PIN_SCS );
00355
00356
00357 PAL_TimerMicroSecondsDelay(6);
00358
00359
00360 PAL_SpiTransmit ((uint8_t*) &lcdPolarity, 2 );
00361
00362
00363 PAL_TimerMicroSecondsDelay(2);
00364
00365 PAL_GpioPinOutClear( LCD_PORT_SCS, LCD_PIN_SCS );
00366
00367
00368 if (lcdPolarity == 0x00)
00369 {
00370 lcdPolarity = 0x02;
00371 }
00372 else
00373 {
00374 lcdPolarity = 0x00;
00375 }
00376
00377 #endif
00378
00379 return DISPLAY_EMSTATUS_OK;
00380 }
00381
00382 #endif
00383
00384
00385 #ifdef PIXEL_MATRIX_ALLOC_SUPPORT
00386
00404 static EMSTATUS PixelMatrixAllocate( DISPLAY_Device_t* device,
00405 unsigned int width,
00406 #ifdef EMWIN_WORKAROUND
00407 unsigned int userStride,
00408 #endif
00409 unsigned int height,
00410 DISPLAY_PixelMatrix_t *pixelMatrix)
00411 {
00412 #ifdef EMWIN_WORKAROUND
00413 unsigned int allocSize = (userStride/8 + LS013B7DH03_CONTROL_BYTES) * height;
00414 #else
00415 unsigned int allocSize = (width/8 + LS013B7DH03_CONTROL_BYTES) * height;
00416 #endif
00417
00418 (void) device;
00419
00420 if (width != LS013B7DH03_WIDTH)
00421 return DISPLAY_EMSTATUS_OUT_OF_RANGE;
00422 #ifdef EMWIN_WORKAROUND
00423 if (userStride < width)
00424 return DISPLAY_EMSTATUS_INVALID_PARAMETER;
00425 #endif
00426
00427 #ifdef USE_MALLOC
00428
00429
00430 *pixelMatrix = (DISPLAY_PixelMatrix_t) malloc (allocSize);
00431
00432 if (NULL == *pixelMatrix)
00433 return DISPLAY_EMSTATUS_NOT_ENOUGH_MEMORY;
00434 else
00435 return DISPLAY_EMSTATUS_OK;
00436
00437 #endif
00438
00439 #ifdef USE_STATIC_PIXEL_MATRIX_POOL
00440
00441 if (((uint8_t*)pixelMatrixPool) + allocSize >
00442 ((uint8_t*)pixelMatrixPoolBase) + PIXEL_MATRIX_POOL_SIZE)
00443 {
00444 *pixelMatrix = NULL;
00445 return DISPLAY_EMSTATUS_NOT_ENOUGH_MEMORY;
00446 }
00447 else
00448 {
00449 *pixelMatrix = pixelMatrixPool;
00450 pixelMatrixPool += allocSize / sizeof(PixelMatrixAlign_t) +
00451 ((allocSize % sizeof(PixelMatrixAlign_t))? 1 : 0);
00452 return DISPLAY_EMSTATUS_OK;
00453 }
00454
00455 #endif
00456
00457 }
00458 #endif
00459
00460
00461 #ifdef PIXEL_MATRIX_ALLOC_SUPPORT
00462
00472 static EMSTATUS PixelMatrixFree( DISPLAY_Device_t* device,
00473 DISPLAY_PixelMatrix_t pixelMatrix)
00474 {
00475 (void) device;
00476
00477 #ifdef USE_MALLOC
00478 free(pixelMatrix);
00479 return DISPLAY_EMSTATUS_OK;
00480 #endif
00481
00482 #ifdef USE_STATIC_PIXEL_MATRIX_POOL
00483
00484
00485
00486
00487
00488 (void) pixelMatrix;
00489 return DISPLAY_EMSTATUS_NOT_SUPPORTED;
00490 #endif
00491 }
00492 #endif
00493
00494
00495
00512 static EMSTATUS PixelMatrixClear( DISPLAY_Device_t* device,
00513 DISPLAY_PixelMatrix_t pixelMatrix,
00514 unsigned int width,
00515 unsigned int height)
00516 {
00517 uint8_t* pByte = (uint8_t*) pixelMatrix;
00518 unsigned int i;
00519
00520 (void) device;
00521 (void) width;
00522
00523 for (i=0; i<height; i++)
00524 {
00525
00526 memset(pByte, 0, LS013B7DH03_WIDTH/8);
00527 pByte += LS013B7DH03_WIDTH/8;
00528
00529 #ifdef USE_CONTROL_BYTES
00530
00531 *pByte++ = 0xff;
00532
00533 *pByte++ = i+1;
00534 #endif
00535 }
00536
00537 return DISPLAY_EMSTATUS_OK;
00538 }
00539
00540
00541 #ifdef USE_CONTROL_BYTES
00542
00553 static EMSTATUS pixelMatrixSetup( DISPLAY_PixelMatrix_t pixelMatrix,
00554 unsigned int startRow,
00555 unsigned int height
00556 #ifdef EMWIN_WORKAROUND
00557 ,
00558 unsigned int userStride
00559 #endif
00560 )
00561 {
00562 int i = 0;
00563 uint8_t* pByte = (uint8_t*) pixelMatrix;
00564 #ifdef EMWIN_WORKAROUND
00565 int strideGap =
00566 (userStride-LS013B7DH03_WIDTH-(LS013B7DH03_CONTROL_BYTES*8)) /
00567 8 / sizeof(uint8_t);
00568 if ((userStride-LS013B7DH03_WIDTH) % sizeof(uint16_t))
00569 return DISPLAY_EMSTATUS_INVALID_PARAMETER;
00570 #endif
00571
00572 while (i<height)
00573 {
00574 pByte += LS013B7DH03_WIDTH/8;
00575
00576 *pByte++ = 0xff;
00577
00578 if (i == height-1)
00579 {
00580
00581 *pByte++ = 0xff;
00582 break;
00583 }
00584 else
00585
00586 *pByte++ = startRow + (++i);
00587
00588 #ifdef EMWIN_WORKAROUND
00589 pByte += strideGap;
00590 #endif
00591 }
00592
00593 return DISPLAY_EMSTATUS_OK;
00594 }
00595
00596 #endif
00597
00598
00599
00616 static EMSTATUS PixelMatrixDraw( DISPLAY_Device_t* device,
00617 DISPLAY_PixelMatrix_t pixelMatrix,
00618 unsigned int startColumn,
00619 unsigned int width,
00620 #ifdef EMWIN_WORKAROUND
00621 unsigned int userStride,
00622 #endif
00623 unsigned int startRow,
00624 unsigned int height )
00625 {
00626 unsigned int i;
00627 uint16_t* p = (uint16_t *)pixelMatrix;
00628 uint16_t cmd;
00629 #ifdef EMWIN_WORKAROUND
00630 int strideGap =
00631 (userStride-width-(LS013B7DH03_CONTROL_BYTES*8)) / 8 / sizeof(uint16_t);
00632 if ((userStride-width) % sizeof(uint16_t))
00633 return DISPLAY_EMSTATUS_INVALID_PARAMETER;
00634 #else
00635 (void) width;
00636 #endif
00637 (void) startColumn;
00638 (void) device;
00639
00640
00641
00642 startRow++;
00643
00644 #ifdef USE_CONTROL_BYTES
00645
00646 pixelMatrixSetup(pixelMatrix, startRow, height
00647 #ifdef EMWIN_WORKAROUND
00648 , userStride
00649 #endif
00650 );
00651 #endif
00652
00653
00654 PAL_GpioPinOutSet( LCD_PORT_SCS, LCD_PIN_SCS );
00655
00656
00657 PAL_TimerMicroSecondsDelay(6);
00658
00659
00660 cmd = LS013B7DH03_CMD_UPDATE | (startRow << 8);
00661 PAL_SpiTransmit((uint8_t*) &cmd, 2 );
00662
00663
00664 for ( i=0; i<height; i++ ) {
00665
00666
00667 PAL_SpiTransmit((uint8_t*) p,
00668 LS013B7DH03_WIDTH/8 + LS013B7DH03_CONTROL_BYTES);
00669 p+=(LS013B7DH03_WIDTH/8 + LS013B7DH03_CONTROL_BYTES) / sizeof(uint16_t);
00670
00671 #ifndef USE_CONTROL_BYTES
00672 if (i==height-1)
00673 {
00674 cmd = 0xffff;
00675 }
00676 else
00677 {
00678 cmd = 0xff | ((startRow+i+1) << 8);
00679 }
00680 PAL_SpiTransmit((uint8_t*) &cmd, 2 );
00681 #endif
00682
00683 #ifdef EMWIN_WORKAROUND
00684 p += strideGap;
00685 #endif
00686
00687 }
00688
00689
00690 PAL_TimerMicroSecondsDelay(2);
00691
00692
00693 PAL_GpioPinOutClear( LCD_PORT_SCS, LCD_PIN_SCS );
00694
00695 return DISPLAY_EMSTATUS_OK;
00696 }
00697