static void lld_lcdSetCursor(uint16_t x, uint16_t y) { /* Reg 0x004E is an 8 bit value * Reg 0x004F is 9 bit * Use a bit mask to make sure they are not set too high */ switch(GDISP.Orientation) { case portraitInv: lld_lcdWriteReg(0x004e, (SCREEN_WIDTH-1-x) & 0x00FF); lld_lcdWriteReg(0x004f, (SCREEN_HEIGHT-1-y) & 0x01FF); break; case portrait: lld_lcdWriteReg(0x004e, x & 0x00FF); lld_lcdWriteReg(0x004f, y & 0x01FF); break; case landscape: lld_lcdWriteReg(0x004e, y & 0x00FF); lld_lcdWriteReg(0x004f, x & 0x01FF); break; case landscapeInv: lld_lcdWriteReg(0x004e, (SCREEN_WIDTH - y - 1) & 0x00FF); lld_lcdWriteReg(0x004f, (SCREEN_HEIGHT - x - 1) & 0x01FF); break; } }
/** * @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 lld_lcdSetCursor(x, y); lld_lcdWriteReg(0x0022, color); }
/** * @brief Clear the display. * @note Optional - The high level driver can emulate using software. * * @param[in] color The color of the pixel * * @notapi */ void GDISP_LLD(clear)(color_t color) { uint16_t lcdBitBLTBuffer[14]; lld_lcdWriteReg( 0x80, 0x80); lcdBitBLTBuffer[0] = 0x04; /* 0x82 */ lcdBitBLTBuffer[2] = 0x02; /* 0x86 */ lcdBitBLTBuffer[5] = 0x00; /* 0x8C */ lcdBitBLTBuffer[6] = 0x00; /* 0x8E */ lcdBitBLTBuffer[7] = GDISP_SCREEN_WIDTH; /* 0x90 */ lcdBitBLTBuffer[8] = GDISP_SCREEN_WIDTH; /* 0x92 */ lcdBitBLTBuffer[9] = GDISP_SCREEN_HEIGHT; /* 0x94 */ lcdBitBLTBuffer[12] = color; /* 0x9A */ lld_lcdBurstWriteMemory(0x60882, lcdBitBLTBuffer, 14); lld_lcdWriteReg( 0x80, 0x01); lld_lcdWaitBlit(); }
/** * @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 if (cx < 1 || cy < 1 || x >= GDISP.Width || y >= GDISP.Height) return; if (x+cx > GDISP.Width) cx = GDISP.Width - x; if (y+cy > GDISP.Height) cy = GDISP.Height - y; #endif uint16_t lcdBitBLTBuffer[14]; lcdBitBLTBuffer[0] = 0x04; /* 0x82 */ lcdBitBLTBuffer[2] = 0x02; /* 0x86 */ lcdBitBLTBuffer[5] = (y * GDISP_SCREEN_WIDTH * 2) + (x * 2); /* 0x8C */ lcdBitBLTBuffer[6] = ((y * GDISP_SCREEN_WIDTH * 2) + (x * 2)) >> 16; /* 0x8E */ lcdBitBLTBuffer[7] = GDISP_SCREEN_WIDTH; /* 0x90 */ lcdBitBLTBuffer[8] = cx; /* 0x92 */ lcdBitBLTBuffer[9] = cy; /* 0x94 */ lcdBitBLTBuffer[12] = color; /* 0x9A */ lld_lcdBurstWriteMemory(0x60882, lcdBitBLTBuffer, 14); lld_lcdWriteReg( 0x80, 0x01); lld_lcdWaitBlit(); }
static void lld_lcdSetCursor(uint16_t x, uint16_t y) { switch(GDISP.Orientation) { case GDISP_ROTATE_0: lld_lcdWriteReg(0x0020, x); lld_lcdWriteReg(0x0021, y); break; case GDISP_ROTATE_90: lld_lcdWriteReg(0x0020, y); lld_lcdWriteReg(0x0021, x); break; case GDISP_ROTATE_180: lld_lcdWriteReg(0x0020, x); lld_lcdWriteReg(0x0021, y); break; case GDISP_ROTATE_270: lld_lcdWriteReg(0x0020, y); lld_lcdWriteReg(0x0021, x); break; } }
/** * @brief Low level GDISP driver initialization. * * @notapi */ bool_t GDISP_LLD(init)(void) { #ifdef LCD_USE_FSMC /* FSMC setup. TODO: this only works for STM32F1 */ rccEnableAHB(RCC_AHBENR_FSMCEN, 0); int FSMC_Bank = 0; /* timing structure */ /* from datasheet: address setup: 0ns address hold: 0ns Data setup: 5ns Data hold: 5ns Data access: 250ns output hold: 100ns */ FSMC_Bank1->BTCR[FSMC_Bank+1] = FSMC_BTR1_ADDSET_1 | FSMC_BTR1_DATAST_1; /* Bank1 NOR/SRAM control register configuration */ FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN; #endif lld_lcdWriteReg(0x0000,0x0001); lld_lcdDelay(5); lld_lcdWriteReg(0x0003,0xA8A4); lld_lcdDelay(5); lld_lcdWriteReg(0x000C,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x000D,0x080C); lld_lcdDelay(5); lld_lcdWriteReg(0x000E,0x2B00); lld_lcdDelay(5); lld_lcdWriteReg(0x001E,0x00B0); lld_lcdDelay(5); lld_lcdWriteReg(0x0001,0x2B3F); lld_lcdDelay(5); lld_lcdWriteReg(0x0002,0x0600); lld_lcdDelay(5); lld_lcdWriteReg(0x0010,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x0011,0x6070); lld_lcdDelay(5); lld_lcdWriteReg(0x0005,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x0006,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x0016,0xEF1C); lld_lcdDelay(5); lld_lcdWriteReg(0x0017,0x0003); lld_lcdDelay(5); lld_lcdWriteReg(0x0007,0x0133); lld_lcdDelay(5); lld_lcdWriteReg(0x000B,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x000F,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x0041,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x0042,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x0048,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x0049,0x013F); lld_lcdDelay(5); lld_lcdWriteReg(0x004A,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x004B,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x0044,0xEF00); lld_lcdDelay(5); lld_lcdWriteReg(0x0045,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x0046,0x013F); lld_lcdDelay(5); lld_lcdWriteReg(0x0030,0x0707); lld_lcdDelay(5); lld_lcdWriteReg(0x0031,0x0204); lld_lcdDelay(5); lld_lcdWriteReg(0x0032,0x0204); lld_lcdDelay(5); lld_lcdWriteReg(0x0033,0x0502); lld_lcdDelay(5); lld_lcdWriteReg(0x0034,0x0507); lld_lcdDelay(5); lld_lcdWriteReg(0x0035,0x0204); lld_lcdDelay(5); lld_lcdWriteReg(0x0036,0x0204); lld_lcdDelay(5); lld_lcdWriteReg(0x0037,0x0502); lld_lcdDelay(5); lld_lcdWriteReg(0x003A,0x0302); lld_lcdDelay(5); lld_lcdWriteReg(0x003B,0x0302); lld_lcdDelay(5); lld_lcdWriteReg(0x0023,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x0024,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x0025,0x8000); lld_lcdDelay(5); lld_lcdWriteReg(0x004f,0x0000); lld_lcdDelay(5); lld_lcdWriteReg(0x004e,0x0000); lld_lcdDelay(5); /* Initialise the GDISP structure */ GDISP.Width = SCREEN_WIDTH; GDISP.Height = SCREEN_HEIGHT; GDISP.Orientation = portrait; 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: */ } }
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_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_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_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_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_backlight((unsigned)value); GDISP.Backlight = (unsigned)value; break; default: return; } }
static void lld_lcdSetViewPort(uint16_t x, uint16_t y, uint16_t cx, uint16_t cy) { switch(GDISP.Orientation) { case GDISP_ROTATE_0: lld_lcdWriteReg(0x0050, x); lld_lcdWriteReg(0x0051, x + cx - 1); lld_lcdWriteReg(0x0052, y); lld_lcdWriteReg(0x0053, y + cy - 1); break; case GDISP_ROTATE_90: lld_lcdWriteReg(0x0050, y); lld_lcdWriteReg(0x0051, y + cy - 1); lld_lcdWriteReg(0x0052, x); lld_lcdWriteReg(0x0053, x + cx - 1); break; case GDISP_ROTATE_180: lld_lcdWriteReg(0x0050, x); lld_lcdWriteReg(0x0051, x + cx - 1); lld_lcdWriteReg(0x0052, y); lld_lcdWriteReg(0x0053, y + cy - 1); break; case GDISP_ROTATE_270: lld_lcdWriteReg(0x0050, y); lld_lcdWriteReg(0x0051, y + cy - 1); lld_lcdWriteReg(0x0052, x); lld_lcdWriteReg(0x0053, x + cx - 1); break; } lld_lcdSetCursor(x, y); }
bool_t gdisp_lld_init(void) { /* Initialise your display */ gdisp_lld_init_board(); /* Hardware reset */ gdisp_lld_reset_pin(TRUE); lld_lcdDelay(1000); gdisp_lld_reset_pin(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_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; }
/** * @brief Low level GDISP driver initialization. * * @notapi */ bool_t GDISP_LLD(init)(void) { #ifdef LCD_USE_FSMC /* Enable FSMC clock */ RCC->AHB3ENR |= RCC_AHB3ENR_FSMCEN; /* Enable GPIOD and GPIOE clock */ RCC->AHB1ENR |= (RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN); /* FSMC GPIOD pin setting as Alternate Function, 100MHz */ /* Pin: 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 * Mask32b: 00 00 11 11 00 00 00 00 00 11 00 00 11 11 00 00 = 00001111000000000011000011110000 = 0x0F0030F0 * Mask16b: 0 0 1 1 0 0 0 0 0 1 0 0 1 1 0 0 = 0011000001001100 = 0x304C * MODER: 10 10 00 00 10 10 10 10 10 00 10 10 00 00 10 10 = 10100000101010101000101000001010 = 0xA0AA8A0A * OSPEEDR: 11 11 00 00 11 11 11 11 11 00 11 11 00 00 11 11 = 11110000111111111100111100001111 = 0xF0FFCF0F * OTYPER: all zero (using mask16b) * PUPDR: all zero (using mask32b) * */ GPIOD->MODER &= 0x0F0030F0; /* Reseting bits to be configured */ GPIOD->MODER |= 0xA0AA8A0A; /* Configuring bits for AF */ GPIOD->OSPEEDR &= 0x0F0030F0; GPIOD->OSPEEDR |= 0xF0FFCF0F; /* Configuring bits for speed 100MHz */ GPIOD->OTYPER &= 0x304C; /* Output type push-pull */ GPIOD->PUPDR &= 0x0F0030F0; /* No pull-up or pull-down */ /* FSMC GPIOE pin setting as Alternate Function, 100MHz */ /* Pin: 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 * Mask32b: 00 00 00 00 00 00 00 00 00 11 11 11 11 11 11 11 = 00000000000000000011111111111111 = 0x00003FFF * Mask16b: 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 = 0000000001111111 = 0x007F * MODER: 10 10 10 10 10 10 10 10 10 00 00 00 00 00 00 00 = 10101010101010101000000000000000 = 0xAAAA8000 * OSPEEDR: 11 11 11 11 11 11 11 11 11 00 00 00 00 00 00 00 = 11111111111111111100000000000000 = 0xFFFFC000 * OTYPER: all zero (using mask16b) * PUPDR: all zero (using mask32b) * */ GPIOE->MODER &= 0x00003FFF; /* Reseting bits to be configured */ GPIOE->MODER |= 0xAAAA8000; /* Configuring bits for AF */ GPIOE->OSPEEDR &= 0x00003FFF; /* Reseting bits to be configured */ GPIOE->OSPEEDR |= 0xFFFFC000; /* Configuring bits for speed 100MHz */ GPIOE->OTYPER &= 0x007F; /* Output type push-pull */ GPIOE->PUPDR &= 0x00003FFF; /* No pull-up or pull-down */ /* FSMC GPIOD pin alternate function setup (0xC) */ /* Pin AFRL: 07 06 05 04 03 02 01 00 * MaskAFRL: 0000 1111 0000 0000 1111 1111 0000 0000 = 0x0F00FF00 * AFRL: 1100 0000 1100 1100 0000 0000 1100 1100 = 0xC0CC00CC * Pin AFRH: 15 14 13 12 11 10 09 08 * MaskAFRH: 0000 0000 1111 1111 0000 0000 0000 0000 = 0x00FF0000 * AFRH: 1100 1100 0000 0000 1100 1100 1100 1100 = 0xCC00CCCC * */ GPIOD->AFR[0] &= 0x0F00FF00; GPIOD->AFR[0] |= 0xC0CC00CC; GPIOD->AFR[1] &= 0x00FF0000; GPIOD->AFR[1] |= 0xCC00CCCC; /* FSMC GPIOE pin alternate function setup (0xC) */ /* Pin AFRL: 07 06 05 04 03 02 01 00 * MaskAFRL: 0000 1111 1111 1111 1111 1111 1111 1111 = 0x0FFFFFFF * AFRL: 1100 0000 0000 0000 0000 0000 0000 0000 = 0xC0000000 * Pin AFRH: 15 14 13 12 11 10 09 08 * MaskAFRH: 0000 0000 0000 0000 0000 0000 0000 0000 = 0x00000000 * AFRH: 1100 1100 1100 1100 1100 1100 1100 1100 = 0xCCCCCCCC * */ GPIOE->AFR[0] &= 0x0FFFFFFF; GPIOE->AFR[0] |= 0xC0000000; GPIOE->AFR[1] = 0xCCCCCCCC; 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(LCD_USE_GPIO) //IOBus busCMD = {LCD_CMD_PORT, (1 << LCD_CS) | (1 << LCD_RS) | (1 << LCD_WR) | (1 << LCD_RD), 0}; //IOBus busDATA = {LCD_CMD_PORT, 0xFFFFF, 0}; //palSetBusMode(&busCMD, PAL_MODE_OUTPUT_PUSHPULL); //palSetBusMode(&busDATA, PAL_MODE_OUTPUT_PUSHPULL); #else #error "Please define LCD_USE_FSMC or LCD_USE_GPIO" #endif lld_lcdWriteReg(0x0007,0x0021); DelayTask(1); lld_lcdWriteReg(0x0000,0x0001); DelayTask(1); lld_lcdWriteReg(0x0007,0x0023); DelayTask(1); lld_lcdWriteReg(0x0010,0x0000); DelayTask(1); lld_lcdWriteReg(0x0007,0x0033); DelayTask(1); lld_lcdWriteReg(0x0011,0x6830); DelayTask(1); lld_lcdWriteReg(0x0002,0x0600); DelayTask(1); lld_lcdWriteReg(0x0012,0x6CEB); DelayTask(1); lld_lcdWriteReg(0x0003,0xA8A4); DelayTask(1); lld_lcdWriteReg(0x000C,0x0000); DelayTask(1); lld_lcdWriteReg(0x000D,0x080C); DelayTask(1); lld_lcdWriteReg(0x000E,0x2B00); DelayTask(1); lld_lcdWriteReg(0x001E,0x00B0); DelayTask(1); lld_lcdWriteReg(0x0001,0x2b3F); DelayTask(1); //RGB lld_lcdWriteReg(0x0005,0x0000); DelayTask(1); lld_lcdWriteReg(0x0006,0x0000); DelayTask(1); lld_lcdWriteReg(0x0016,0xEF1C); DelayTask(1); lld_lcdWriteReg(0x0017,0x0103); DelayTask(1); lld_lcdWriteReg(0x000B,0x0000); DelayTask(1); lld_lcdWriteReg(0x000F,0x0000); DelayTask(1); lld_lcdWriteReg(0x0041,0x0000); DelayTask(1); lld_lcdWriteReg(0x0042,0x0000); DelayTask(1); lld_lcdWriteReg(0x0048,0x0000); DelayTask(1); lld_lcdWriteReg(0x0049,0x013F); DelayTask(1); lld_lcdWriteReg(0x004A,0x0000); DelayTask(1); lld_lcdWriteReg(0x004B,0x0000); DelayTask(1); lld_lcdWriteReg(0x0044,0xEF00); DelayTask(1); lld_lcdWriteReg(0x0045,0x0000); DelayTask(1); lld_lcdWriteReg(0x0046,0x013F); DelayTask(1); lld_lcdWriteReg(0x0030,0x0707); DelayTask(1); lld_lcdWriteReg(0x0031,0x0204); DelayTask(1); lld_lcdWriteReg(0x0032,0x0204); DelayTask(1); lld_lcdWriteReg(0x0033,0x0502); DelayTask(1); lld_lcdWriteReg(0x0034,0x0507); DelayTask(1); lld_lcdWriteReg(0x0035,0x0204); DelayTask(1); lld_lcdWriteReg(0x0036,0x0204); DelayTask(1); lld_lcdWriteReg(0x0037,0x0502); DelayTask(1); lld_lcdWriteReg(0x003A,0x0302); DelayTask(1); lld_lcdWriteReg(0x002F,0x12BE); DelayTask(1); lld_lcdWriteReg(0x003B,0x0302); DelayTask(1); lld_lcdWriteReg(0x0023,0x0000); DelayTask(1); lld_lcdWriteReg(0x0024,0x0000); DelayTask(1); lld_lcdWriteReg(0x0025,0x8000); DelayTask(1); lld_lcdWriteReg(0x004f,0x0000); DelayTask(1); lld_lcdWriteReg(0x004e,0x0000); DelayTask(1); #if defined(LCD_USE_FSMC) /* FSMC delay reduced as the controller now runs at full speed */ FSMC_Bank1->BTCR[FSMC_Bank+1] = FSMC_BTR1_ADDSET_1 | 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 */ GDISP.Width = SCREEN_WIDTH; GDISP.Height = SCREEN_HEIGHT; GDISP.Orientation = portrait; 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; }
static void lld_lcdSetViewPort(uint16_t x, uint16_t y, uint16_t cx, uint16_t cy) { lld_lcdSetCursor(x, y); /* Reg 0x44 - Horizontal RAM address position * Upper Byte - HEA * Lower Byte - HSA * 0 <= HSA <= HEA <= 0xEF * Reg 0x45,0x46 - Vertical RAM address position * Lower 9 bits gives 0-511 range in each value * 0 <= Reg(0x45) <= Reg(0x46) <= 0x13F */ switch(GDISP.Orientation) { case portrait: lld_lcdWriteReg(0x44, (((x+cx-1) << 8) & 0xFF00 ) | (x & 0x00FF)); lld_lcdWriteReg(0x45, y & 0x01FF); lld_lcdWriteReg(0x46, (y+cy-1) & 0x01FF); break; case landscape: lld_lcdWriteReg(0x44, (((y+cy-1) << 8) & 0xFF00) | (y & 0x00FF)); lld_lcdWriteReg(0x45, x & 0x01FF); lld_lcdWriteReg(0x46, (x+cx-1) & 0x01FF); break; case portraitInv: lld_lcdWriteReg(0x44, (((SCREEN_WIDTH-x-1) & 0x00FF) << 8) | ((SCREEN_WIDTH - (x+cx)) & 0x00FF)); lld_lcdWriteReg(0x45, (SCREEN_HEIGHT-(y+cy)) & 0x01FF); lld_lcdWriteReg(0x46, (SCREEN_HEIGHT-y-1) & 0x01FF); break; case landscapeInv: lld_lcdWriteReg(0x44, (((SCREEN_WIDTH - y - 1) & 0x00FF) << 8) | ((SCREEN_WIDTH - (y+cy)) & 0x00FF)); lld_lcdWriteReg(0x45, (SCREEN_HEIGHT - (x+cx)) & 0x01FF); lld_lcdWriteReg(0x46, (SCREEN_HEIGHT - x - 1) & 0x01FF); break; } lld_lcdSetCursor(x, y); }
bool_t gdisp_lld_init(void) { /* Initialise your display */ gdisp_lld_init_board(); /* Hardware reset */ gdisp_lld_reset_pin(TRUE); lld_lcdDelay(1000); gdisp_lld_reset_pin(FALSE); lld_lcdDelay(1000); DISPLAY_CODE = lld_lcdReadReg(0); lld_lcdWriteReg(0x0000, 0x0001); //start Int. osc lld_lcdDelay(500); lld_lcdWriteReg(0x0001, 0x0100); //Set SS bit (shift direction of outputs is from S720 to S1) lld_lcdWriteReg(0x0002, 0x0700); //select the line inversion lld_lcdWriteReg(0x0003, 0x1038); //Entry mode(Horizontal : increment,Vertical : increment, AM=1) lld_lcdWriteReg(0x0004, 0x0000); //Resize control(No resizing) lld_lcdWriteReg(0x0008, 0x0202); //front and back porch 2 lines lld_lcdWriteReg(0x0009, 0x0000); //select normal scan lld_lcdWriteReg(0x000A, 0x0000); //display control 4 lld_lcdWriteReg(0x000C, 0x0000); //system interface(2 transfer /pixel), internal sys clock, lld_lcdWriteReg(0x000D, 0x0000); //Frame marker position lld_lcdWriteReg(0x000F, 0x0000); //selects clk, enable and sync signal polarity, lld_lcdWriteReg(0x0010, 0x0000); // lld_lcdWriteReg(0x0011, 0x0000); //power control 2 reference voltages = 1:1, lld_lcdWriteReg(0x0012, 0x0000); //power control 3 VRH lld_lcdWriteReg(0x0013, 0x0000); //power control 4 VCOM amplitude lld_lcdDelay(500); lld_lcdWriteReg(0x0010, 0x17B0); //power control 1 BT,AP lld_lcdWriteReg(0x0011, 0x0137); //power control 2 DC,VC lld_lcdDelay(500); lld_lcdWriteReg(0x0012, 0x0139); //power control 3 VRH lld_lcdDelay(500); lld_lcdWriteReg(0x0013, 0x1d00); //power control 4 vcom amplitude lld_lcdWriteReg(0x0029, 0x0011); //power control 7 VCOMH lld_lcdDelay(500); lld_lcdWriteReg(0x0030, 0x0007); lld_lcdWriteReg(0x0031, 0x0403); lld_lcdWriteReg(0x0032, 0x0404); lld_lcdWriteReg(0x0035, 0x0002); lld_lcdWriteReg(0x0036, 0x0707); lld_lcdWriteReg(0x0037, 0x0606); lld_lcdWriteReg(0x0038, 0x0106); lld_lcdWriteReg(0x0039, 0x0007); lld_lcdWriteReg(0x003c, 0x0700); lld_lcdWriteReg(0x003d, 0x0707); lld_lcdWriteReg(0x0020, 0x0000); //starting Horizontal GRAM Address lld_lcdWriteReg(0x0021, 0x0000); //starting Vertical GRAM Address lld_lcdWriteReg(0x0050, 0x0000); //Horizontal GRAM Start Position lld_lcdWriteReg(0x0051, 0x00EF); //Horizontal GRAM end Position lld_lcdWriteReg(0x0052, 0x0000); //Vertical GRAM Start Position lld_lcdWriteReg(0x0053, 0x013F); //Vertical GRAM end Position switch (DISPLAY_CODE) { case 0x9320: lld_lcdWriteReg(0x0060, 0x2700); //starts scanning from G1, and 320 drive lines break; case 0x9325: lld_lcdWriteReg(0x0060, 0xA700); //starts scanning from G1, and 320 drive lines break; } lld_lcdWriteReg(0x0061, 0x0001); //fixed base display lld_lcdWriteReg(0x006a, 0x0000); //no scroll lld_lcdWriteReg(0x0090, 0x0010); //set Clocks/Line =16, Internal Operation Clock Frequency=fosc/1, lld_lcdWriteReg(0x0092, 0x0000); //set gate output non-overlap period=0 lld_lcdWriteReg(0x0093, 0x0003); //set Source Output Position=3 lld_lcdWriteReg(0x0095, 0x0110); //RGB interface(Clocks per line period=16 clocks) lld_lcdWriteReg(0x0097, 0x0110); //set Gate Non-overlap Period 0 locksc lld_lcdWriteReg(0x0098, 0x0110); // lld_lcdWriteReg(0x0007, 0x0173); //display On // Turn on the backlight gdisp_lld_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; }
/** * @brief Low level GDISP driver initialization. * * @notapi */ bool_t GDISP_LLD(init)(void) { #ifdef GDISP_USE_SPI spiStart(&SPID2, &spi2cfg); #endif lld_lcdWriteReg( 0x06, 0x0100 ); /* Software Reset Register */ chThdSleepMicroseconds(10000); /* LCD Panel Power On Delay (in ms) */ lld_lcdWriteReg( 0x04, 0x0002 ); /* Power Save Register */ lld_lcdWriteReg( 0x10, 0x0000 ); /* PLL Setting Register 0 */ lld_lcdWriteReg( 0x12, 0x000F ); /* PLL Setting Register 1 */ lld_lcdWriteReg( 0x14, 0x0029 ); /* PLL Setting Register 2 */ lld_lcdWriteReg( 0x10, 0x0001 ); /* PLL Setting Register 0 */ chThdSleepMicroseconds(2500); /* PLL Register Programming Delay (in us) */ lld_lcdWriteReg( 0x16, 0x0006 ); /* Internal Clock Configuration Register */ lld_lcdWriteReg( 0x04, 0x0002 ); /* Power Save Register */ lld_lcdWriteReg( 0x20, 0x004F ); /* Panel Setting Register */ lld_lcdWriteReg( 0x22, 0x0001 ); /* Display Setting Register */ lld_lcdWriteReg( 0x24, 0x003C ); /* Horizontal Display Width Register */ lld_lcdWriteReg( 0x26, 0x002D ); /* Horizontal Non-Display Period Register */ lld_lcdWriteReg( 0x28, 0x0110 ); /* Vertical Display Height Register */ lld_lcdWriteReg( 0x2A, 0x0012 ); /* Vertical Non-Display Period Register */ lld_lcdWriteReg( 0x2C, 0x0090 ); /* HS Pulse Width Register */ lld_lcdWriteReg( 0x2E, 0x0010 ); /* HS Pulse Start Position Register */ lld_lcdWriteReg( 0x30, 0x0002 ); /* VS Pulse Width Register */ lld_lcdWriteReg( 0x32, 0x0011 ); /* VS Pulse Start Position Register */ lld_lcdWriteReg( 0x40, 0x0001 ); /* Main Layer Setting Register */ lld_lcdWriteReg( 0x42, 0x0000 ); /* Main Layer Start Address Register 0 */ lld_lcdWriteReg( 0x44, 0x0000 ); /* Main Layer Start Address Register 1 */ lld_lcdWriteReg( 0x50, 0x0006 ); /* PIP Layer Setting Register */ lld_lcdWriteReg( 0x52, 0xFC00 ); /* PIP Layer Start Address Register 0 */ lld_lcdWriteReg( 0x54, 0x0003 ); /* PIP Layer Start Address Register 1 */ lld_lcdWriteReg( 0x56, 0x01e0 ); /* PIP Layer Width Register */ lld_lcdWriteReg( 0x58, 0x0110 ); /* PIP Layer Height Register */ lld_lcdWriteReg( 0x5A, 0x0000 ); /* PIP Layer X Start Position Register */ lld_lcdWriteReg( 0x5C, 0x0000 ); /* PIP Layer Y Start Position Register */ lld_lcdWriteReg( 0x60, 0x0000 ); /* PIP Enable Register */ lld_lcdWriteReg( 0x62, 0x0040 ); /* Alpha Blending Register */ lld_lcdWriteReg( 0x64, 0x0000 ); /* Transparency Register */ lld_lcdWriteReg( 0x66, 0x0000 ); /* Key Color Register 0 */ lld_lcdWriteReg( 0x68, 0x0000 ); /* Key Color Register 1 */ lld_lcdWriteReg( 0xD0, 0x0000 ); /* GPIO Configuration Register */ lld_lcdWriteReg( 0xD2, 0x0000 ); /* GPIO Status / Control Register */ lld_lcdWriteReg( 0xD4, 0x000F ); /* GPIO Pull-Down Control Register */ chThdSleepMicroseconds(10000); /* * Enable backlight */ lld_lcdWriteReg(0xD0, 0x0003); lld_lcdWriteReg(0xD2, 0x0003); // lld_lcdResetViewPort(); /* Now initialise the GDISP structure */ GDISP.clipx0 = 0; GDISP.clipy0 = 0; GDISP.clipx1 = GDISP_SCREEN_WIDTH; GDISP.clipy1 = GDISP_SCREEN_HEIGHT; GDISP.Width = GDISP_SCREEN_WIDTH; GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Orientation = GDISP_ROTATE_0; GDISP.Powermode = powerOn; GDISP.Backlight = 100; GDISP.Contrast = 50; 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: /* Code here */ /* break; */ case powerOn: /* Code here */ /* You may need this --- if (GDISP.Powermode != powerSleep) GDISP_LLD(init(); */ /* break; */ case powerSleep: /* Code here */ /* 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,0x0127); lld_lcdWriteReg(0x03, 0b0011); GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_90: lld_lcdWriteReg(0x0001,0x0027); lld_lcdWriteReg(0x0003, 0b1011); GDISP.Height = GDISP_SCREEN_WIDTH; GDISP.Width = GDISP_SCREEN_HEIGHT; break; case GDISP_ROTATE_180: lld_lcdWriteReg(0x0001,0x0127); lld_lcdWriteReg(0x0003, 0b0000); GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_270: lld_lcdWriteReg(0x0001,0x0027); lld_lcdWriteReg(0x0003, 0b1000); GDISP.Height = GDISP_SCREEN_WIDTH; GDISP.Width = GDISP_SCREEN_HEIGHT; break; default: return; } GDISP.Orientation = (gdisp_orientation_t)value; return; /* case GDISP_CONTROL_BACKLIGHT: case GDISP_CONTROL_CONTRAST: */ } }
/** * @brief Draw a character using a filled background. * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The top-left corner of the text * @param[in] c The character to print * @param[in] color The color of the character * @param[in] bgcolor The background color * * @notapi */ void GDISP_LLD(fillchar)(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor) { volatile coord_t width, height; // TODO check why volatile is needed. Otherwise width * height = 0 if height is optimized out coord_t xscale, yscale; /* Check we actually have something to print */ width = _getCharWidth(font, c); if (!width) return; xscale = font->xscale; yscale = font->yscale; height = font->height * yscale; width *= xscale; const fontcolumn_t *ptr; fontcolumn_t column; coord_t i, j, xs, ys; /* Working buffer for fast non-transparent text rendering [patch by Badger] This needs to be larger than the largest character we can print. Assume the max is double sized. */ static pixel_t buf[20*(sizeof(fontcolumn_t)*8)*2]; #if GDISP_NEED_VALIDATION /* Check our buffer is big enough */ if ((unsigned)(width * height) > sizeof(buf)/sizeof(buf[0])) return; #endif ptr = _getCharData(font, c); /* Loop through the data and display. The font data is LSBit first, down the column */ for(i = 0; i < width; i+=xscale) { /* Get the font bitmap data for the column */ column = *ptr++; /* Draw each pixel */ for(j = 0; j < height; j+=yscale, column >>= 1) { if (column & 0x01) { for(xs=0; xs < xscale; xs++) for(ys=0; ys < yscale; ys++) gdispPackPixels(buf, width, i+xs, j+ys, color); } else { for(xs=0; xs < xscale; xs++) for(ys=0; ys < yscale; ys++) gdispPackPixels(buf, width, i+xs, j+ys, bgcolor); } } } /* * write char in display memory (after end of normal memory) */ lld_lcdBurstWriteMemory(480 * 272 * 2, buf, width * height); uint16_t lcdBitBLTBuffer[10]; lcdBitBLTBuffer[0] = 0x05; /* 0x82 16bpp, source linear */ lcdBitBLTBuffer[2] = 0x00; /* 0x86 Move positive */ lcdBitBLTBuffer[3] = ((480*272)*2) & 0xffff; /* 0x88 Source start address */ lcdBitBLTBuffer[4] = (480*272*2)>>16; /* 0x8A Source start address */ lcdBitBLTBuffer[5] = (y * GDISP_SCREEN_WIDTH * 2) + (x * 2); /* 0x8C Destination start address */ lcdBitBLTBuffer[6] = ((y * GDISP_SCREEN_WIDTH * 2) + (x * 2)) >> 16; /* 0x8E Destination start address */ lcdBitBLTBuffer[7] = GDISP_SCREEN_WIDTH; /* 0x90 Rectangle offset (screen width) */ lcdBitBLTBuffer[8] = width; /* 0x92 Width */ lcdBitBLTBuffer[9] = height; /* 0x94 Height */ lld_lcdBurstWriteMemory(0x60882, lcdBitBLTBuffer, 10); lld_lcdWriteReg( 0x80, 0x01); /* Start blit */ }