/** * @brief Fill an area with a color. * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled * @param[in] color The color of the fill * * @notapi */ void GDISP_LLD(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif uint32_t area; area = cx*cy; GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1); GDISP_LLD(writestreamstart)(); #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) uint8_t i; dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color); dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M); for (i = area/65535; i; i--) { dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535); dmaStreamEnable(GDISP_DMA_STREAM); dmaWaitCompletion(GDISP_DMA_STREAM); } dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535); dmaStreamEnable(GDISP_DMA_STREAM); dmaWaitCompletion(GDISP_DMA_STREAM); #else uint32_t index; for(index = 0; index < area; index++) GDISP_LLD(writedata)(color); #endif //#ifdef GDISP_USE_DMA }
/** * @brief Draws a pixel on the display. * * @param[in] x X location of the pixel * @param[in] y Y location of the pixel * @param[in] color The color of the pixel * * @notapi */ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) { #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; #endif GDISP_LLD(setwindow)(x, y, x, y); GDISP_LLD(writestreamstart)(); GDISP_LLD(writedata)(color); }
static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) { volatile uint16_t dummy; GDISP_LLD(write_index)(lcdReg); dummy = lld_lcdReadData(); (void)dummy; return lld_lcdReadData(); }
void GDISP_LLD(setwindow)(coord_t x0, coord_t y0, coord_t x1, coord_t y1) { /* We don't need to validate here as the LLD routines will validate first. * * #if GDISP_NEED_VALIDATION * if (x0 >= GDISP.Width || y0 >= GDISP.Height || x0 < 0 || y0 < 0) return; * else if (x1 >= GDISP.Width || y1 >= GDISP.Height || y1 < 0 || y2 < 0) return; * #endif */ GDISP_LLD(writeindex)(SSD1963_SET_PAGE_ADDRESS); GDISP_LLD(writedata)((y0 >> 8) & 0xFF); GDISP_LLD(writedata)((y0 >> 0) & 0xFF); GDISP_LLD(writedata)((y1 >> 8) & 0xFF); GDISP_LLD(writedata)((y1 >> 0) & 0xFF); GDISP_LLD(writeindex)(SSD1963_SET_COLUMN_ADDRESS); GDISP_LLD(writedata)((x0 >> 8) & 0xFF); GDISP_LLD(writedata)((x0 >> 0) & 0xFF); GDISP_LLD(writedata)((x1 >> 8) & 0xFF); GDISP_LLD(writedata)((x1 >> 0) & 0xFF); }
/** * @brief Fill an area with a bitmap. * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled * @param[in] srcx, srcy The bitmap position to start the fill from * @param[in] srccx The width of a line in the bitmap. * @param[in] buffer The pixels to use to fill the area. * * @notapi */ void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; } if (srcx+cx > srccx) cx = srccx - srcx; if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1); GDISP_LLD(writestreamstart)(); buffer += srcx + srcy * srccx; #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) uint32_t area = cx*cy; uint8_t i; dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer); dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M); for (i = area/65535; i; i--) { dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535); dmaStreamEnable(GDISP_DMA_STREAM); dmaWaitCompletion(GDISP_DMA_STREAM); } dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535); dmaStreamEnable(GDISP_DMA_STREAM); dmaWaitCompletion(GDISP_DMA_STREAM); #else coord_t endx, endy; unsigned lg; endx = srcx + cx; endy = y + cy; lg = srccx - cx; for(; y < endy; y++, buffer += lg) for(x=srcx; x < endx; x++) GDISP_LLD(writedata)(*buffer++); #endif //#ifdef GDISP_USE_DMA }
__inline void GDISP_LLD(readstreamstart)(void) { GDISP_LLD(writeindex)(SSD1963_READ_MEMORY_START); }
__inline void GDISP_LLD(writestreamstart)(void) { GDISP_LLD(writeindex)(SSD1963_WRITE_MEMORY_START); }
/** * @brief Driver Control * @details Unsupported control codes are ignored. * @note The value parameter should always be typecast to (void *). * @note There are some predefined and some specific to the low level driver. * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver * that only supports off/on anything other * than zero is on. * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100. * GDISP_CONTROL_LLD - Low level driver control constants start at * this value. * * @param[in] what What to do. * @param[in] value The value to use (always cast to a void *). * * @notapi */ void GDISP_LLD(control)(unsigned what, void *value) { /* NOT IMPLEMENTED YET */ switch(what) { case GDISP_CONTROL_POWER: if (GDISP.Powermode == (gdisp_powermode_t)value) return; switch((gdisp_powermode_t)value) { case powerOff: GDISP_LLD(writeindex)(SSD1963_EXIT_SLEEP_MODE); // leave sleep mode chThdSleepMicroseconds(5000); GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_OFF); GDISP_LLD(writeindex)(SSD1963_SET_DEEP_SLEEP); // enter deep sleep mode break; case powerOn: GDISP_LLD(readreg)(0x0000); chThdSleepMicroseconds(5000); // 2x Dummy reads to wake up from deep sleep GDISP_LLD(readreg)(0x0000); chThdSleepMicroseconds(5000); if (GDISP.Powermode != powerSleep) GDISP_LLD(init)(); GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_ON); break; case powerSleep: GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_OFF); GDISP_LLD(writeindex)(SSD1963_ENTER_SLEEP_MODE); // enter sleep mode chThdSleepMicroseconds(5000); break; default: return; } GDISP.Powermode = (gdisp_powermode_t)value; return; case GDISP_CONTROL_ORIENTATION: if (GDISP.Orientation == (gdisp_orientation_t)value) return; switch((gdisp_orientation_t)value) { case GDISP_ROTATE_0: /* Code here */ GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_90: /* Code here */ GDISP.Height = GDISP_SCREEN_WIDTH; GDISP.Width = GDISP_SCREEN_HEIGHT; break; case GDISP_ROTATE_180: /* Code here */ GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_270: /* Code here */ GDISP.Height = GDISP_SCREEN_WIDTH; GDISP.Width = GDISP_SCREEN_HEIGHT; break; default: return; } #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION GDISP.clipx0 = 0; GDISP.clipy0 = 0; GDISP.clipx1 = GDISP.Width; GDISP.clipy1 = GDISP.Height; #endif GDISP.Orientation = (gdisp_orientation_t)value; return; /* case GDISP_CONTROL_BACKLIGHT: case GDISP_CONTROL_CONTRAST: */ } }
/** * @brief Low level GDISP driver initialisation. * @return TRUE if successful, FALSE on error. * * @notapi */ bool_t GDISP_LLD(init)(void) { /* Initialise the display */ #if defined(GDISP_USE_FSMC) #if defined(STM32F1XX) || defined(STM32F3XX) /* FSMC setup for F1/F3 */ rccEnableAHB(RCC_AHBENR_FSMCEN, 0); #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) #error "DMA not implemented for F1/F3 Devices" #endif #elif defined(STM32F4XX) || defined(STM32F2XX) /* STM32F2-F4 FSMC init */ rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0); #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM) if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL)) chSysHalt(); dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM); dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M); #endif #else #error "FSMC not implemented for this device" #endif /* set pins to FSMC mode */ IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0}; IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | (1 << 13) | (1 << 14) | (1 << 15), 0}; palSetBusMode(&busD, PAL_MODE_ALTERNATE(12)); palSetBusMode(&busE, PAL_MODE_ALTERNATE(12)); const unsigned char FSMC_Bank = 0; /* FSMC timing */ FSMC_Bank1->BTCR[FSMC_Bank+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \ | (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \ | (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ; /* Bank1 NOR/SRAM control register configuration * This is actually not needed as already set by default after reset */ FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; #elif defined(GDISP_USE_GPIO) IOBus busCMD = {GDISP_CMD_PORT, (1 << GDISP_CS) | (1 << GDISP_RS) | (1 << GDISP_WR) | (1 << GDISP_RD), 0}; IOBus busDATA = {GDISP_CMD_PORT, 0xFFFFF, 0}; palSetBusMode(&busCMD, PAL_MODE_OUTPUT_PUSHPULL); palSetBusMode(&busDATA, PAL_MODE_OUTPUT_PUSHPULL); #else #error "Please define GDISP_USE_FSMC or GDISP_USE_GPIO" #endif GDISP_LLD(writeindex)(SSD1963_SOFT_RESET); chThdSleepMicroseconds(100); /* Driver PLL config */ GDISP_LLD(writeindex)(SSD1963_SET_PLL_MN); GDISP_LLD(writedata)(35); // PLLclk = REFclk (10Mhz) * 36 (360Mhz) GDISP_LLD(writedata)(2); // SYSclk = PLLclk / 3 (120MHz) GDISP_LLD(writedata)(4); // Apply calculation bit, else it is ignored GDISP_LLD(writeindex)(SSD1963_SET_PLL); // Enable PLL GDISP_LLD(writedata)(0x01); chThdSleepMicroseconds(200); GDISP_LLD(writeindex)(SSD1963_SET_PLL); // Use PLL GDISP_LLD(writedata)(0x03); chThdSleepMicroseconds(200); GDISP_LLD(writeindex)(SSD1963_SOFT_RESET); chThdSleepMicroseconds(100); /* Screen size */ GDISP_LLD(writeindex)(SSD1963_SET_GDISP_MODE); // GDISP_LLD(writedata)(0x0000); GDISP_LLD(writedata)(0b00011000); //Enabled dithering GDISP_LLD(writedata)(0x0000); GDISP_LLD(writedata)(mHIGH((GDISP_SCREEN_WIDTH+1))); GDISP_LLD(writedata)((GDISP_SCREEN_WIDTH+1)); GDISP_LLD(writedata)(mHIGH((GDISP_SCREEN_HEIGHT+1))); GDISP_LLD(writedata)((GDISP_SCREEN_HEIGHT+1)); GDISP_LLD(writedata)(0x0000); GDISP_LLD(writeindex)(SSD1963_SET_PIXEL_DATA_INTERFACE); GDISP_LLD(writedata)(SSD1963_PDI_16BIT565); /* LCD Clock specs */ GDISP_LLD(writeindex)(SSD1963_SET_LSHIFT_FREQ); GDISP_LLD(writedata)((GDISP_FPR >> 16) & 0xFF); GDISP_LLD(writedata)((GDISP_FPR >> 8) & 0xFF); GDISP_LLD(writedata)(GDISP_FPR & 0xFF); GDISP_LLD(writeindex)(SSD1963_SET_HORI_PERIOD); GDISP_LLD(writedata)(mHIGH(SCREEN_HSYNC_PERIOD)); GDISP_LLD(writedata)(mLOW(SCREEN_HSYNC_PERIOD)); GDISP_LLD(writedata)(mHIGH((SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH))); GDISP_LLD(writedata)(mLOW((SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH))); GDISP_LLD(writedata)(SCREEN_HSYNC_PULSE); GDISP_LLD(writedata)(0x00); GDISP_LLD(writedata)(0x00); GDISP_LLD(writedata)(0x00); GDISP_LLD(writeindex)(SSD1963_SET_VERT_PERIOD); GDISP_LLD(writedata)(mHIGH(SCREEN_VSYNC_PERIOD)); GDISP_LLD(writedata)(mLOW(SCREEN_VSYNC_PERIOD)); GDISP_LLD(writedata)(mHIGH((SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH))); GDISP_LLD(writedata)(mLOW((SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH))); GDISP_LLD(writedata)(SCREEN_VSYNC_PULSE); GDISP_LLD(writedata)(0x00); GDISP_LLD(writedata)(0x00); /* Tear effect indicator ON. This is used to tell the host MCU when the driver is not refreshing the panel */ GDISP_LLD(writeindex)(SSD1963_SET_TEAR_ON); GDISP_LLD(writedata)(0x0000); /* Turn on */ GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_ON); #if defined(GDISP_USE_FSMC) /* FSMC delay reduced as the controller now runs at full speed */ FSMC_Bank1->BTCR[FSMC_Bank+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ; FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; #endif /* Initialise the GDISP structure to match */ GDISP.Width = GDISP_SCREEN_WIDTH; GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Orientation = GDISP_ROTATE_0; GDISP.Powermode = powerOn; GDISP.Backlight = 100; GDISP.Contrast = 50; #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP GDISP.clipx0 = 0; GDISP.clipy0 = 0; GDISP.clipx1 = GDISP.Width; GDISP.clipy1 = GDISP.Height; #endif return TRUE; }
/** * @brief Driver Control * @detail Unsupported control codes are ignored. * @note The value parameter should always be typecast to (void *). * @note There are some predefined and some specific to the low level driver. * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver * that only supports off/on anything other * than zero is on. * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100. * GDISP_CONTROL_LLD - Low level driver control constants start at * this value. * * @param[in] what What to do. * @param[in] value The value to use (always cast to a void *). * * @notapi */ void GDISP_LLD(control)(unsigned what, void *value) { switch(what) { case GDISP_CONTROL_POWER: if (GDISP.Powermode == (gdisp_powermode_t)value) return; switch((gdisp_powermode_t)value) { case powerOff: lld_lcdWriteReg(0x0010, 0x0000); // leave sleep mode lld_lcdWriteReg(0x0007, 0x0000); // halt operation lld_lcdWriteReg(0x0000, 0x0000); // turn off oszillator lld_lcdWriteReg(0x0010, 0x0001); // enter sleepmode break; case powerOn: lld_lcdWriteReg(0x0010, 0x0000); // leave sleep mode if (GDISP.Powermode != powerSleep) GDISP_LLD(init)(); break; case powerSleep: lld_lcdWriteReg(0x0010, 0x0001); // enter sleep mode break; default: return; } GDISP.Powermode = (gdisp_powermode_t)value; return; case GDISP_CONTROL_ORIENTATION: if (GDISP.Orientation == (gdisp_orientation_t)value) return; switch((gdisp_orientation_t)value) { case portrait: lld_lcdWriteReg(0x0001, 0x2B3F); /* ID = 11 AM = 0 */ lld_lcdWriteReg(0x0011, 0x6070); GDISP.Height = SCREEN_HEIGHT; GDISP.Width = SCREEN_WIDTH; break; case landscape: lld_lcdWriteReg(0x0001, 0x293F); /* ID = 11 AM = 1 */ lld_lcdWriteReg(0x0011, 0x6078); GDISP.Height = SCREEN_WIDTH; GDISP.Width = SCREEN_HEIGHT; break; case portraitInv: lld_lcdWriteReg(0x0001, 0x2B3F); /* ID = 01 AM = 0 */ lld_lcdWriteReg(0x0011, 0x6040); GDISP.Height = SCREEN_HEIGHT; GDISP.Width = SCREEN_WIDTH; break; case landscapeInv: lld_lcdWriteReg(0x0001, 0x293F); /* ID = 01 AM = 1 */ lld_lcdWriteReg(0x0011, 0x6048); GDISP.Height = SCREEN_WIDTH; GDISP.Width = SCREEN_HEIGHT; break; default: return; } #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION GDISP.clipx0 = 0; GDISP.clipy0 = 0; GDISP.clipx1 = GDISP.Width; GDISP.clipy1 = GDISP.Height; #endif GDISP.Orientation = (gdisp_orientation_t)value; return; /* case GDISP_CONTROL_BACKLIGHT: case GDISP_CONTROL_CONTRAST: */ } }
static __inline void lld_lcdWriteReg(uint16_t lcdReg, uint16_t lcdRegValue) { GDISP_LLD(write_index)(lcdReg); GDISP_LLD(write_data)(lcdRegValue); }
static __inline void lld_lcdWriteData(uint16_t data) { GDISP_LLD(write_data)(data); }
static __inline void lld_lcdWriteIndex(uint16_t index) { GDISP_LLD(write_index)(index); }
void GDISP_LLD(control)(unsigned what, void *value) { switch(what) { case GDISP_CONTROL_POWER: if(GDISP.Powermode == (gdisp_powermode_t)value) return; switch((gdisp_powermode_t)value) { case powerOff: lld_lcdWriteReg(0x0007, 0x0000); lld_lcdWriteReg(0x0010, 0x0000); lld_lcdWriteReg(0x0011, 0x0000); lld_lcdWriteReg(0x0012, 0x0000); lld_lcdWriteReg(0x0013, 0x0000); GDISP_LLD(set_backlight)(0); break; case powerOn: //*************Power On sequence ******************// lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */ lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */ lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */ lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */ lld_lcdWriteReg(0x0010, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ lld_lcdWriteReg(0x0011, 0x0147); /* DC1[2:0], DC0[2:0], VC[2:0] */ lld_lcdDelay(500); lld_lcdWriteReg(0x0012, 0x013C); /* VREG1OUT voltage */ lld_lcdDelay(500); lld_lcdWriteReg(0x0013, 0x0E00); /* VDV[4:0] for VCOM amplitude */ lld_lcdWriteReg(0x0029, 0x0009); /* VCM[4:0] for VCOMH */ lld_lcdDelay(500); lld_lcdWriteReg(0x0007, 0x0173); /* 262K color and display ON */ GDISP_LLD(set_backlight)(GDISP.Backlight); if(GDISP.Powermode != powerSleep || GDISP.Powermode != powerDeepSleep) GDISP_LLD(init)(); break; case powerSleep: lld_lcdWriteReg(0x0007, 0x0000); /* display OFF */ lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */ lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */ lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */ lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */ lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */ lld_lcdWriteReg(0x0010, 0x0002); /* SAP, BT[3:0], APE, AP, DSTB, SLP */ GDISP_LLD(set_backlight)(0); break; case powerDeepSleep: lld_lcdWriteReg(0x0007, 0x0000); /* display OFF */ lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */ lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */ lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */ lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */ lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */ lld_lcdWriteReg(0x0010, 0x0004); /* SAP, BT[3:0], APE, AP, DSTB, SLP */ GDISP_LLD(set_backlight)(0); break; default: return; } GDISP.Powermode = (gdisp_powermode_t)value; return; case GDISP_CONTROL_ORIENTATION: if(GDISP.Orientation == (gdisp_orientation_t)value) return; switch((gdisp_orientation_t)value) { case GDISP_ROTATE_0: lld_lcdWriteReg(0x0001, 0x0100); lld_lcdWriteReg(0x0003, 0x1038); lld_lcdWriteReg(0x0060, 0x2700); GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_90: lld_lcdWriteReg(0x0001, 0x0000); lld_lcdWriteReg(0x0003, 0x1030); lld_lcdWriteReg(0x0060, 0x2700); GDISP.Height = GDISP_SCREEN_WIDTH; GDISP.Width = GDISP_SCREEN_HEIGHT; break; case GDISP_ROTATE_180: lld_lcdWriteReg(0x0001, 0x0000); lld_lcdWriteReg(0x0003, 0x1038); lld_lcdWriteReg(0x0060, 0xa700); GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_270: lld_lcdWriteReg(0x0001, 0x0100); lld_lcdWriteReg(0x0003, 0x1030); lld_lcdWriteReg(0x0060, 0xA700); GDISP.Height = GDISP_SCREEN_WIDTH; GDISP.Width = GDISP_SCREEN_HEIGHT; break; default: return; } #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION GDISP.clipx0 = 0; GDISP.clipy0 = 0; GDISP.clipx1 = GDISP.Width; GDISP.clipy1 = GDISP.Height; #endif GDISP.Orientation = (gdisp_orientation_t)value; return; case GDISP_CONTROL_BACKLIGHT: if((unsigned)value > 100) value = (void *)100; GDISP_LLD(set_backlight)((unsigned)value); GDISP.Backlight = (unsigned)value; break; default: return; } }
bool_t GDISP_LLD(init)(void) { /* Initialise your display */ GDISP_LLD(init_board)(); /* Hardware reset */ GDISP_LLD(setpin_reset)(TRUE); lld_lcdDelay(1000); GDISP_LLD(setpin_reset)(FALSE); lld_lcdDelay(1000); // chinese code starts here lld_lcdWriteReg(0x0000,0x0001); lld_lcdDelay(10); lld_lcdWriteReg(0x0015,0x0030); lld_lcdWriteReg(0x0011,0x0040); lld_lcdWriteReg(0x0010,0x1628); lld_lcdWriteReg(0x0012,0x0000); lld_lcdWriteReg(0x0013,0x104d); lld_lcdDelay(10); lld_lcdWriteReg(0x0012,0x0010); lld_lcdDelay(10); lld_lcdWriteReg(0x0010,0x2620); lld_lcdWriteReg(0x0013,0x344d); //304d lld_lcdDelay(10); lld_lcdWriteReg(0x0001,0x0100); lld_lcdWriteReg(0x0002,0x0300); lld_lcdWriteReg(0x0003,0x1038);//0x1030 lld_lcdWriteReg(0x0008,0x0604); lld_lcdWriteReg(0x0009,0x0000); lld_lcdWriteReg(0x000A,0x0008); lld_lcdWriteReg(0x0041,0x0002); lld_lcdWriteReg(0x0060,0x2700); lld_lcdWriteReg(0x0061,0x0001); lld_lcdWriteReg(0x0090,0x0182); lld_lcdWriteReg(0x0093,0x0001); lld_lcdWriteReg(0x00a3,0x0010); lld_lcdDelay(10); //################# void Gamma_Set(void) ####################// lld_lcdWriteReg(0x30,0x0000); lld_lcdWriteReg(0x31,0x0502); lld_lcdWriteReg(0x32,0x0307); lld_lcdWriteReg(0x33,0x0305); lld_lcdWriteReg(0x34,0x0004); lld_lcdWriteReg(0x35,0x0402); lld_lcdWriteReg(0x36,0x0707); lld_lcdWriteReg(0x37,0x0503); lld_lcdWriteReg(0x38,0x1505); lld_lcdWriteReg(0x39,0x1505); lld_lcdDelay(10); //################## void Display_ON(void) ####################// lld_lcdWriteReg(0x0007,0x0001); lld_lcdDelay(10); lld_lcdWriteReg(0x0007,0x0021); lld_lcdWriteReg(0x0007,0x0023); lld_lcdDelay(10); lld_lcdWriteReg(0x0007,0x0033); lld_lcdDelay(10); lld_lcdWriteReg(0x0007,0x0133); // chinese code ends here // Turn on the backlight GDISP_LLD(set_backlight)(GDISP_INITIAL_BACKLIGHT); /* Initialise the GDISP structure */ GDISP.Width = GDISP_SCREEN_WIDTH; GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Orientation = GDISP_ROTATE_0; GDISP.Powermode = powerOn; GDISP.Backlight = GDISP_INITIAL_BACKLIGHT; GDISP.Contrast = GDISP_INITIAL_CONTRAST; #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP GDISP.clipx0 = 0; GDISP.clipy0 = 0; GDISP.clipx1 = GDISP.Width; GDISP.clipy1 = GDISP.Height; #endif return TRUE; }