cancel
Showing results for 
Search instead for 
Did you mean: 

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

dale
Associate III
Posted on April 22, 2017 at 22:02

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 

1 ACCEPTED SOLUTION

Accepted Solutions
dale
Associate III
Posted on April 24, 2017 at 05:47

Solved.

I was enabling the LTDC_Layer1->CR bit CLUTEN to enable the color look up table, but then subsequently clearing it when writing all 32 bits to the same register to turn on just the Layer Enable (LEN) bit.  ORing them together for the write solved the problem.  Rookie mistake.

View solution in original post

1 REPLY 1
dale
Associate III
Posted on April 24, 2017 at 05:47

Solved.

I was enabling the LTDC_Layer1->CR bit CLUTEN to enable the color look up table, but then subsequently clearing it when writing all 32 bits to the same register to turn on just the Layer Enable (LEN) bit.  ORing them together for the write solved the problem.  Rookie mistake.