2017-04-22 01:02 PM
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
Solved! Go to Solution.
2017-04-23 08:47 PM
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.
2017-04-23 08:47 PM
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.