Hello
I configured PEG to use double buffer.
In standalone, the problem occurs ONLY during the following phase (which consist to copy image from flash to the second buffer in RAM not yet used by the LCDC) (Problem during imbricated "for" loop):
void K70_TWRLCDScreen::MemoryToScreen(void)
...
for(Row = Top; Row < (Top + Height); Row++)
{
...
pGet = (PEGCOLOR *)(pSurface->pScanPointers[0]);
...
pPut = (PEGULONG *)mpVidMemBase;
for(Column = 0; Column < Width ; Column++)
{
#if defined (PEG_RGB_USE_565)
PEGCOLOR Color = *pGet++;
//Debug AG, BIT 0 to 5 Used, not 8 to 2.
/* *pPut++ = ((Color & 0xf800) << 8) |
((Color & 0x7e0) << 5) |
((Color & 0x1f) << 3);*/
*pPut++ = ((Color & 0xf800) << 6) | //Rouge
((Color & 0x7e0) << 3) | //Vert
((Color & 0x1f) << 1); //Bleu
#else
PEGCOLOR Color = *pGet++;
*pPut++ = ((Color & 0x7c00) << 9) |
((Color & 0x3e0) << 6) |
((Color & 0x1f) << 3);
#endif
}
}
....
#if defined (PEG_DOUBLE_BUFFER)
SwapFrameBuffers(Copy); // !!!!! Here, LCDC address is swap to the buffer copied just above
#endif
...
void K70_TWRLCDScreen::SwapFrameBuffers(PegRect &Copy)
{
PEGINT* pPut;
PEGINT* pGet;
PEGINT Row;
PEGINT Top = Copy.Top;
PEGINT Left = Copy.Left;
PEGINT Width = Copy.Width();
PEGINT Height = Copy.Height();
PEGULONG* pReg;
pReg = (PEGULONG*) LCDC_LSSAR;
*pReg = (PEGULONG) mpVidMemBase;
if(LCDC_LSSAR == (PEGULONG) mpFrameBufferB)
{
pGet = (PEGINT *)mpFrameBufferA;
pPut = (PEGINT *)mpFrameBufferB;
LCDC_LSSAR = (PEGULONG) mpFrameBufferA;
}
else
{
pGet = (PEGINT *)mpFrameBufferB;
pPut = (PEGINT *)mpFrameBufferA;
LCDC_LSSAR = (PEGULONG) mpFrameBufferB;
}
#if defined(SYNCHRONIZE_DOUBLE_BUFFER)
WaitForEndOfFrame();
#endif
pGet += mHRes * Top;
pGet += Left;
pPut += mHRes * Top;
pPut += Left;
for(Row = Top; Row < (Top + Height); Row++)
{
memcpy(pPut, pGet, Width * 4);
pGet += mHRes;
pPut += mHRes;
}
}
#endif // PEG_DOUBLE_BUFFER
If this problem comes from a wrong LCDC configuration, why all run correclty when RAM concurent access is not done? Why it run correctly when TFT clock is down to 20Mhz?
My LCDC config:
oid K70_TWRLCDScreen::ConfigureController(void)
{
/*Enable Port clocks */
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK |
SIM_SCGC5_PORTB_MASK |
SIM_SCGC5_PORTC_MASK |
SIM_SCGC5_PORTD_MASK |
SIM_SCGC5_PORTE_MASK |
SIM_SCGC5_PORTF_MASK;
/* Enable LCDC and DDR Modules */
SIM_SCGC3 |= SIM_SCGC3_LCDC_MASK | SIM_SCGC3_DDR_MASK;
/* Disable MPU */
MPU_CESR &= ~MPU_CESR_VLD_MASK;
/* Setup LCD pin muxing */
LcdPanelPinsInit();
/* Basic LCD configuration */
/* set LCD Screen Start Address (if double buffered, rendering starts in B) */
LCDC_LSSAR = (PEGUINT)mpVidMemBase;
/* set LCD Size */
LCDC_LSR = LCDC_LSR_XMAX( (mHRes / 16) ) | LCDC_LSR_YMAX(mVRes);
/* set LCD virtual page width */
LCDC_LVPWR = LCDC_LVPWR_VPW( mHRes);
/* set LCD cursor positon & settings (turn off) */
LCDC_LCPR = 0;
LCDC_LCWHB = 0;
/* set LCD panel configuration */
LCDC_LPCR =
LCDC_LPCR_TFT_MASK | /* TFT Screen */
LCDC_LPCR_COLOR_MASK | /* Color */
LCDC_LPCR_BPIX(0x7) | /* bpp */
LCDC_LPCR_FLMPOL_MASK | /* first line marker active low */
LCDC_LPCR_LPPOL_MASK | /* line pulse active low */
LCDC_LPCR_END_SEL_MASK | /* Use big-endian mode (0xFFAA5500 means R=AA,G=55,B=00) */
LCDC_LPCR_SCLKIDLE_MASK | /* Enalbe LSCLK when vsync is idle */
LCDC_LPCR_SCLKSEL_MASK | /* Always enable clock */
//Debug AG LCDC_LPCR_CLKPOL_MASK | /* Active on positive edge of LSCLK. In TFT mode, active on negative edge of LSCLK. */
LCDC_LPCR_PCD(3); /* Divide 120 PLL clock by (3+1)=4 to get 30MHz clock */
//Debug AG timming on p2232 datasheet
/* set LCD horizontal configuration based on panel data ( 6.1 Innolux datasheet) */
LCDC_LHCR =
LCDC_LHCR_H_WIDTH(63) | /* (63+1)=64 SCLK period for HSYNC activated */
LCDC_LHCR_H_WAIT_1(99) | /* (99+1)=100 SCLK period between end of OE and beginning of HSYNC */
LCDC_LHCR_H_WAIT_2(63); /* (63+3)=66 SCLK periods between end of HSYNC and beginning of OE */
/* Total of 230 TCLK for Thb. */
/* set LCD vertical configuration based on panel data (Figure 3-3 in Seiko datasheet) */
LCDC_LVCR =
LCDC_LVCR_V_WIDTH(2) | /* 2 SCLK period for VSYNC activated */
LCDC_LVCR_V_WAIT_1(10) | /* 20 SCLK period between end of OE and beginning of VSYNC */
LCDC_LVCR_V_WAIT_2(2); /* 2 SCLK periods between end of VSYNC and beginning of OE */
/* set LCD panning offset */
LCDC_LPOR = 0;
/* set LCD interrupt configuration */
LCDC_LICR = 0;
/* set LCD interrupt enable */
LCDC_LIER = 0;
/* set LCD graphic window start address */
LCDC_LGWSAR = 0x80000000;
/* set LCD graphic window size */
LCDC_LGWSR =
LCDC_LGWSR_GWW(0) |
LCDC_LGWSR_GWH(0);
/* set LCD graphic window virtual page width */
LCDC_LGWVPWR = 0;
/* set LCD graphic window panning offset */
LCDC_LGWPOR = 0;
/* set LCD graphic window position */
LCDC_LGWPR =
LCDC_LGWPR_GWXP(0) |
LCDC_LGWPR_GWYP(0);
/* set LCD graphic window control */
LCDC_LGWCR =
LCDC_LGWCR_GWAV(0xF) | /* alpha-transparent */
(1 << LCDC_LGWCR_GWCKE_SHIFT) | /* color key enable */
LCDC_LGWCR_GWCKR(0xFF) | /* color key */
LCDC_LGWCR_GWCKG(0) |
LCDC_LGWCR_GWCKB(80);
/*Set background plane DMA to burst mode */
LCDC_LDCR&=~LCDC_LDCR_BURST_MASK;
/*Set graphic window DMA to burst mode */
LCDC_LGWDCR&=~LCDC_LGWDCR_GWBT_MASK;
/* Set PWM backlight */
LCDC_LPCCR = LCDC_LPCCR_PW(128) | /* Set PWM duty to 50% */
LCDC_LPCCR_CC_EN_MASK ; /* Enable contrast control */
/* Change PTD12 to outputs and set to 1(Enable Backlight)*/
GPIOD_PDDR |= GPIO_PIN(12);
GPIOD_PSOR = GPIO_PSOR_PTSO(GPIO_PIN(12));
/* Enable LCD */
SIM_MCR|=SIM_MCR_LCDSTART_MASK;
return;