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 }