Programming LTDC CLUT on STM32F746NG-DISCOVERY - seems not to work as I would expect
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