Other Parts Discussed in Thread: AM3358
Hi,
I'm trying to write a code to enable the LCD controller on the AM3358 rev 2.1 (SoC on the Beaglebone Black), but I am running into issues with sync lost. So far I have written a code to configure the LCD controller to work in TFT 16-bpp mode. I have defined the following structure for the frame buffer
/* Frame dimensions*/
#define LINES 1648
#define COLUMNS 750
/* Framebuffer structure */
typedef struct __attribute__((packed))
{
uint16_t palette0;
uint16_t palette1_15[15]; // unused palettes for 16-BPP mode
uint16_t raw_pixels[LINES * COLUMNS]; // pixels
} LCDFrameBuffer;
LCDFrameBuffer frame0 __attribute__ ((section (".LCDBUFF")));
I have the buffer initialized and stored in the DDR3 memory as follows:
void InitFrameBuffer(){
int i = 0;
/* Initialize palette entries */
frame0.palette0 = 0x4000; // entry 0 must be 0x4000 according to the TRM
memset(frame0.palette1_15, 0, 31); // rest must be 0s
/* Initialize pixel values*/
for(i = 0; i < LINES*COLUMNS; i++){
frame0.raw_pixels[i] = RED(25) | GREEN(10) | BLUE(5);
}
}
When I run the program, I get constant sync lost interrupts! What could be the problem?
Below is the configuration code for the LCD controller:
int InitLCDController(){
int i = 0;
/* Enable PRCM clocks to lcd controller*/
HWREG(SOC_CM_PER_REGS + CM_PER_LCDC_CLKCTRL) = CM_PER_LCDC_CLKCTRL_MODULEMODE_ENABLE;
while((HWREG(SOC_CM_PER_REGS + CM_PER_LCDC_CLKCTRL) & CM_PER_LCDC_CLKCTRL_IDLEST) != 0);
/* Configure pin MUX */
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_VSYNC) = (1 << 4); // LCD_VSYNC
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_HSYNC) = (1 << 4); // LCD_HSYNC
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_PCLK) = (1 << 4); // LCD_PCLK
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_AC_BIAS_EN) = (1 << 4); // LCD_AC_BIAS_EN
/* LCD_DATA[0:15] PINS*/
for(i = 0; i < 16; i++)
HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(i)) = (1 << 4);
/*
* Configure LCD controller module
*/
/* Disable Autoidle */
HWREG(SOC_LCDC_0_REGS + LCDC_SYSCONFIG) = ((LCDC_SYSCONFIG_IDLEMODE_SMART << LCDC_SYSCONFIG_IDLEMODE_SHIFT) | (LCDC_SYSCONFIG_STANDBYMODE_SMART << LCDC_SYSCONFIG_STANDBYMODE_SHIFT));
/* Enable internal clocks */
HWREG(SOC_LCDC_0_REGS + LCDC_CLKC_ENABLE) = LCDC_CLKC_ENABLE_CORE;
while(HWREG(SOC_LCDC_0_REGS + LCDC_CLKC_ENABLE) != LCDC_CLKC_ENABLE_CORE);
/* Select raster mode*/
HWREG(SOC_LCDC_0_REGS + LCDC_LCD_CTRL) = (LCDC_LCD_CTRL_MODESEL_RASTER << LCDC_LCD_CTRL_MODESEL_SHIFT);
/* Reset raster module*/
HWREG(SOC_LCDC_0_REGS + LCDC_IRQSTATUS) = 0x3FF; // clear interrupts
HWREG(SOC_LCDC_0_REGS + LCDC_RASTER_CTRL) = 0; // disable controller
while((HWREG(SOC_LCDC_0_REGS + LCDC_IRQSTATUS) & LCDC_IRQSTATUS_RECURRENT_RASTER) != 0); // wait for done
HWREG(SOC_LCDC_0_REGS + LCDC_CLKC_RESET) = LCDC_CLKC_RESET_CORE; // activate reset
delay_ms(1);
HWREG(SOC_LCDC_0_REGS + LCDC_CLKC_RESET) = 0x00; // deactivate reset
/* Frame buffers */
InitFrameBuffer();
fb0_ceiling = 0x80000000 + sizeof(LCDFrameBuffer); // calculate ceiling of the buffer
HWREG(SOC_LCDC_0_REGS + LCDC_LCDDMA_CTRL) = ((6 << 8) | (4 << 4) | (1 << 0)); // 512 FIFO threshold, ping-pong buffers, 16 burst
HWREG(SOC_LCDC_0_REGS + LCDC_LCDDMA_FB0_BASE) = (unsigned int)&frame0;
HWREG(SOC_LCDC_0_REGS + LCDC_LCDDMA_FB0_CEILING) = fb0_ceiling;
HWREG(SOC_LCDC_0_REGS + LCDC_LCDDMA_FB1_BASE) = (unsigned int)&frame0;
HWREG(SOC_LCDC_0_REGS + LCDC_LCDDMA_FB1_CEILING) = fb0_ceiling;
HWREG(SOC_LCDC_0_REGS + LCDC_CLKC_ENABLE) |= LCDC_CLKC_ENABLE_DMA; // enable DMA
/* Setup timing registers */
// Pixel clock
HWREG(SOC_CM_DPLL_REGS + CM_DPLL_CLKSEL_LCDC_PIXEL_CLK) = 0 ; // select disp pll as source
HWREG(SOC_LCDC_0_REGS + LCDC_LCD_CTRL) |= (2 << LCDC_LCD_CTRL_CLKDIV_SHIFT); // clock div
// Timings. TODO: set other timing parameters
HWREG(SOC_LCDC_0_REGS + LCDC_RASTER_TIMING_0) = (102 << 4); // 1648 H lines
HWREG(SOC_LCDC_0_REGS + LCDC_RASTER_TIMING_1) = (750 << 0);// 750 V lines
/* Set interrupts & enable raster controller */
HWREG(SOC_LCDC_0_REGS + LCDC_IRQSTATUS) = 0x3FF; // clear interrupts flags
HWREG(SOC_LCDC_0_REGS + LCDC_IRQENABLE_CLEAR) = 0x3FF; // clear all interrupts
HWREG(SOC_LCDC_0_REGS + LCDC_IRQENABLE_SET) = ((1 << 2) | (1 << 8) | (1 << 9)); // enable fb0, fb1, and sync lost interrupts
HWREG(SOC_LCDC_0_REGS + LCDC_RASTER_CTRL) = ((1 << 0) | (1 << 7)); // enable raster controller with TFT mode
}