This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Am3358 LCD controller getting constant sync lost interrupts

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

}