AnsweredAssumed Answered

Programming LTDC CLUT on STM32F746NG-DISCOVERY - seems not to work as I would expect

Question asked by dalewheat on Apr 22, 2017

I've been able to get a graphical image displayed on the LCD on the STM32F746NG-DISCO board, using only internal SRAM and the L8 pixel format using the CLUT, but it is only showing up as linear monochrome output, i.e., a pixel value of 0x00 is black and a pixel value of 0xFF is white (and everything linearly in between as gray-scale).  I've programmed the CLUT with just 8 entries as a test but these values do not seem to be reflected in the actual display.  Here is my LTDC initialization code:

 

volatile uint8_t __attribute__((section(".frame_buffer"))) frame_buffer[272][480]; // LCD frame buffer

void init_lcd(void) {

// initialize LCD

RCC->APB2ENR |= RCC_APB2ENR_LTDCEN; // enable clock for LTDC

pllsaicfgr.cfgr.PLLSAIN = 192;
pllsaicfgr.cfgr.PLLSAIP = 1; // P = /4 for PLLSAI48CLK (used by USB, RNG, SDMMC)
pllsaicfgr.cfgr.PLLSAIQ = 4; // Q = /4 for PLLSAI clock
pllsaicfgr.cfgr.PLLSAIR = 5; // R = /5 for PLLLSAI clock

RCC->PLLSAICFGR = pllsaicfgr.value;

RCC->DCKCFGR1 = RCC_DCKCFGR1_PLLSAIDIVR_0; // /4 for LTDC clock

RCC->CR |= RCC_CR_PLLSAION; // enable PLLSAI

while((RCC->CR & RCC_CR_PLLSAIRDY) == 0); // wait for PLLSAI to lock

LTDC->SSCR = ((HSYNC_WIDTH -1) << 16) | (VSYNC_HEIGHT -1); // configure HSYNC width (41) & VSYNC height (10) (less one)
LTDC->BPCR = ((HSYNC_WIDTH + HBP -1) << 16) | (VSYNC_HEIGHT + VBP -1); // back porch configuration
LTDC->AWCR = ((HSYNC_WIDTH + HBP + ACTIVE_WIDTH -1) << 16) | (VSYNC_HEIGHT + VBP + ACTIVE_HEIGHT -1); // configure active area
LTDC->TWCR = ((HSYNC_WIDTH + HBP + ACTIVE_WIDTH + HFP -1) << 16) | (VSYNC_HEIGHT + VBP + ACTIVE_HEIGHT + VFP -1); // front porch configuration
LTDC->GCR = 0x00000000; // configure signal polarities (all default values)
LTDC->BCCR = 0x00000000; // background color is black

// configure Layer 1

LTDC_Layer1->WHPCR = ((HSYNC_WIDTH + HBP + ACTIVE_WIDTH -1) << 16) | (HSYNC_WIDTH + HBP); // horizontal stop and start positions
LTDC_Layer1->WVPCR = ((VSYNC_HEIGHT + VBP + ACTIVE_HEIGHT -1) << 16) | (VSYNC_HEIGHT + VBP); // vertical stop and start positions
LTDC_Layer1->PFCR = 5; // pixel format = L8

// load color look-up table (CLUT)

// *** debug *** CLUT for 8 colors

LTDC_Layer1->CLUTWR = 0x00000000; // 0 = black
LTDC_Layer1->CLUTWR = 0x01FF0000; // 1 = red
LTDC_Layer1->CLUTWR = 0x0200FF00; // 2 = green
LTDC_Layer1->CLUTWR = 0x03FFFF00; // 3 = yellow
LTDC_Layer1->CLUTWR = 0x040000FF; // 4 = blue
LTDC_Layer1->CLUTWR = 0x05FF00FF; // 5 = purple
LTDC_Layer1->CLUTWR = 0x0600FFFF; // 6 = cyan
LTDC_Layer1->CLUTWR = 0x07FFFFFF; // 7 = white

LTDC_Layer1->CR |= LTDC_LxCR_CLUTEN; // enable CLUT

//LTDC_Layer1->CFBAR = 0x08000000; // *** debug *** ROM
//LTDC_Layer1->CFBAR = 0x20010000; // *** debug *** SRAM1
LTDC_Layer1->CFBAR = (uint32_t)&frame_buffer; // color fram buffer address
LTDC_Layer1->CFBLR = ((480 * 1 /* bytes per pixel */) << 16) | (ACTIVE_WIDTH * 1 /* bytes per pixel */ + 3); // color frame buffer length

LTDC_Layer1->CR = LTDC_LxCR_LEN; // enable layer 1
LTDC->SRCR = LTDC_SRCR_IMR; // immediate reload of shadow registers
LTDC->GCR |= LTDC_GCR_LTDCEN; // enable LTDC

sbi(GPIOI, 12); // enable LCD_DISP signal

LCD_BL_ON(); // turn on LCD backlight (PK3)
}

I'm only using Layer 1 at this time.  I perform all the GPIO/alternate-function initialization in another, previously-executed function, and I'm certainly getting an image on the screen, but it's always in gray-scale and not in the primary colors that I *thought* I told it to use.

 

I fill the screen in my main() function with increasingly "brighter" lines using the following code:

 

 for(i = 0; i < 272; i++) {
    for(j = 0; j < 480; j++) {
       frame_buffer[i][j] = i % 64;
    }
}

I would have expected the first 8 lines of each 64 line section to be the bright, "primary" colors indicated in the CLUT, i.e., black, red, green, yellow, blue, purple (magenta), cyan and white.

 

Any ideas what I am doing wrong or omitting?

 

Any insights are appreciated.

 

Thanks,

 

Dale 

Outcomes