cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7B3I -DK unable to activate LCD - screen through registers

richi
Associate III

Please I need someone to review the code I wrote I double checked few times but am probably missing some info and configuration. I want to display red color on display module by only setting bits in the register. Here is the provided code. Someone please help I am working on a homework project.

#include <stdint.h>
#include "stm32h7b3xxq.h"
#include "reg_util.h"
#include "main.h"

void SystemClockSetup(void);
void VcoreSetup(void);
void LTDC_Peripheral_Init(void);
void LTDC_Peripheral_Setup(void);

int main(void)
{
  HAL_Init();
  SystemClockSetup();
  VcoreSetup();
  LTDC_Peripheral_Init();
  LTDC_Peripheral_Setup();

  /*Loop forever */
  for (;;);
}

void VcoreSetup(void)
{
 	//Povecaj wait states i latency

  FLASH->ACR |= (3 << 4);
  FLASH->ACR |= 0b0111;

 	//Disable SMP
 	//PWR -> CR3 &= ~(PWR_CR3_SMPSEN);

 	//Disable Bypass
 	//PWR -> CR3 &= ~(PWR_CR3_BYPASS);

 	//Wait for ACTVOSRDY bit
 	//while(!REG_READ_BIT(PWR -> CSR1,PWR_CSR1_ACTVOSRDY_Pos));

 	//Povisi voltage na VOS0;
  PWR->SRDCR |= (3 << 14);

 	//Wait for VOSRDY bit
 	//while(!REG_READ_BIT(PWR -> SRDCR,PWR_SRDCR_VOSRDY_Pos));

 	//Enable PLL1
  RCC->CR |= RCC_CR_PLL1ON;

 	//Wait for PLL stabilization
  while (!REG_READ_BIT(RCC->CR, RCC_CR_PLL1RDY_Pos));

 	//PLL as the main clock
  RCC->CFGR |= 3;	// pll1_p_ck je main clock

 	//Wait for confirmation

  while (!((RCC->CFGR >> 3) &(0x3) == (0x3)));

 	//Enable PLL3
  RCC->CR |= RCC_CR_PLL3ON;

 	//Wait for PLL stabilization
  while (!REG_READ_BIT(RCC->CR, RCC_CR_PLL3RDY_Pos));

 	//Omoguci clock za LTDC na APB3 busu
  RCC->APB3ENR |= RCC_APB3ENR_LTDCEN;

}

void SystemClockSetup(void)
{
 	//System Clock je HSI 64 MHz (default)

 	//DIVM1 i DIVM3 prescaler za smanjivanje frekvencije na 8 MHz
  RCC->PLLCKSELR |= RCC_PLLCKSELR_DIVM1_3;
  RCC->PLLCKSELR |= RCC_PLLCKSELR_DIVM3_3;

 	//Disable  pll2 divider
  RCC->PLLCKSELR &= ~(32 << 12);	//Disable PLL2

 	//Ja koristim pll3_r_ck i pll1_p_ck, ostale ugasiti
  RCC->PLLCFGR &= ~(RCC_PLLCFGR_DIVQ1EN);	//Disable Q1 divider
  RCC->PLLCFGR &= ~(RCC_PLLCFGR_DIVR1EN);	//Disable R1 divider

  RCC->PLLCFGR &= ~(RCC_PLLCFGR_DIVP3EN);	//Disable P3 divider
  RCC->PLLCFGR &= ~(RCC_PLLCFGR_DIVQ3EN);	//Disable Q3 divider

 	//Choose input VCO frequency range 8 - 16 MHz
  RCC->PLLCFGR |= RCC_PLLCFGR_PLL1RGE_3;
  RCC->PLLCFGR |= RCC_PLLCFGR_PLL3RGE_3;

 	//Za PLL1 trebam pomnožiti sa 69(70 zapravo) i podijeliti sa 2(default state)
  RCC->PLL1DIVR |= 69;

 	//Pomnozi sa 17(18 zapravo) i podijeli sa 15(zapravo 16) 8 * 18/7 = 9 MHz za lcd driver na display modulu
  RCC->PLL3DIVR |= 17;	//Množenje sa 18
  RCC->PLL3DIVR |= (15 << 24);	// Dijeljenje sa 16;

 	//Namjesti Prescalere za PLL1 APB3 bus da bude max outan tj. 140 MHz
  RCC->CDCFGR1 |= RCC_CDCFGR1_CDPPRE_2;	//sys_clk / 2 = 140 MHz

}

void LTDC_Peripheral_Init(void)
{
 	//Enable AHB peripheral I,J,K ports
  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOIEN;	// LCD_CLK, LCD_HSYNC, LCD_VSYNC
  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOJEN;	//
  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOKEN;	// LCD_DE

 	//Enable all 24 pins as Alternate functions
  GPIOI->MODER &= ~(GPIO_MODER_MODE12_0);	//PIN 12, LCD_HSYNC
  GPIOI->MODER &= ~(GPIO_MODER_MODE13_0);	//PIN 13, LCD_VSYNC
  GPIOI->MODER &= ~(GPIO_MODER_MODE14_0);	//PIN 14, LCD_CLK
  GPIOI->MODER &= ~(GPIO_MODER_MODE15_0);	//PIN 15, R0

  GPIOJ->MODER &= ~(GPIO_MODER_MODE0_0);	//PIN 0,  R1
  GPIOJ->MODER &= ~(GPIO_MODER_MODE1_0);	//PIN 1,  R2
  GPIOJ->MODER &= ~(GPIO_MODER_MODE2_0);	//PIN 2   R3
  GPIOJ->MODER &= ~(GPIO_MODER_MODE3_0);	//PIN 3   R4
  GPIOJ->MODER &= ~(GPIO_MODER_MODE4_0);	//PIN 4   R5
  GPIOJ->MODER &= ~(GPIO_MODER_MODE5_0);	//PIN 5   R6
  GPIOJ->MODER &= ~(GPIO_MODER_MODE6_0);	//PIN 6   R7
  GPIOJ->MODER &= ~(GPIO_MODER_MODE7_0);	//PIN 7   G0
  GPIOJ->MODER &= ~(GPIO_MODER_MODE8_0);	//PIN 8   G1
  GPIOJ->MODER &= ~(GPIO_MODER_MODE9_0);	//PIN 9   G2
  GPIOJ->MODER &= ~(GPIO_MODER_MODE10_0);	//PIN 10  G3
  GPIOJ->MODER &= ~(GPIO_MODER_MODE11_0);	//PIN 11  G4
  GPIOJ->MODER &= ~(GPIO_MODER_MODE12_0);	//PIN 12  B0
  GPIOJ->MODER &= ~(GPIO_MODER_MODE13_0);	//PIN 13  B1
  GPIOJ->MODER &= ~(GPIO_MODER_MODE14_0);	//PIN 14  B2
  GPIOJ->MODER &= ~(GPIO_MODER_MODE15_0);	//PIN 15  B3

  GPIOK->MODER &= ~(GPIO_MODER_MODE0_0);	//PIN 0   G5
  GPIOK->MODER &= ~(GPIO_MODER_MODE1_0);	//PIN 1   G6
  GPIOK->MODER &= ~(GPIO_MODER_MODE2_0);	//PIN 2   G7
  GPIOK->MODER &= ~(GPIO_MODER_MODE3_0);	//PIN 3   B4
  GPIOK->MODER &= ~(GPIO_MODER_MODE4_0);	//PIN 4   B5
  GPIOK->MODER &= ~(GPIO_MODER_MODE5_0);	//PIN 5   B6
  GPIOK->MODER &= ~(GPIO_MODER_MODE6_0);	//PIN 6   B7
  GPIOK->MODER &= ~(GPIO_MODER_MODE7_0);	//PIN 7   LCD_DE

 	//Set peripherals to AF14 so it could be configured for LCD-TFT
  GPIOI->AFR[1] |= (14 << GPIO_AFRH_AFSEL12_Pos);
  GPIOI->AFR[1] |= (14 << GPIO_AFRH_AFSEL13_Pos);
  GPIOI->AFR[1] |= (14 << GPIO_AFRH_AFSEL14_Pos);
  GPIOI->AFR[1] |= (14 << GPIO_AFRH_AFSEL15_Pos);

  GPIOJ->AFR[0] |= (14 << GPIO_AFRL_AFSEL0_Pos);
  GPIOJ->AFR[0] |= (14 << GPIO_AFRL_AFSEL1_Pos);
  GPIOJ->AFR[0] |= (14 << GPIO_AFRL_AFSEL2_Pos);
  GPIOJ->AFR[0] |= (14 << GPIO_AFRL_AFSEL3_Pos);
  GPIOJ->AFR[0] |= (14 << GPIO_AFRL_AFSEL4_Pos);
  GPIOJ->AFR[0] |= (14 << GPIO_AFRL_AFSEL5_Pos);
  GPIOJ->AFR[0] |= (14 << GPIO_AFRL_AFSEL6_Pos);
  GPIOJ->AFR[0] |= (14 << GPIO_AFRL_AFSEL7_Pos);
  GPIOJ->AFR[1] |= (14 << GPIO_AFRH_AFSEL8_Pos);
  GPIOJ->AFR[1] |= (14 << GPIO_AFRH_AFSEL9_Pos);
  GPIOJ->AFR[1] |= (14 << GPIO_AFRH_AFSEL10_Pos);
  GPIOJ->AFR[1] |= (14 << GPIO_AFRH_AFSEL11_Pos);
  GPIOJ->AFR[1] |= (14 << GPIO_AFRH_AFSEL12_Pos);
  GPIOJ->AFR[1] |= (14 << GPIO_AFRH_AFSEL13_Pos);
  GPIOJ->AFR[1] |= (14 << GPIO_AFRH_AFSEL14_Pos);
  GPIOJ->AFR[1] |= (14 << GPIO_AFRH_AFSEL15_Pos);

  GPIOK->AFR[0] |= (14 << GPIO_AFRL_AFSEL0_Pos);
  GPIOK->AFR[0] |= (14 << GPIO_AFRL_AFSEL1_Pos);
  GPIOK->AFR[0] |= (14 << GPIO_AFRL_AFSEL2_Pos);
  GPIOK->AFR[0] |= (14 << GPIO_AFRL_AFSEL3_Pos);
  GPIOK->AFR[0] |= (14 << GPIO_AFRL_AFSEL4_Pos);
  GPIOK->AFR[0] |= (14 << GPIO_AFRL_AFSEL5_Pos);
  GPIOK->AFR[0] |= (14 << GPIO_AFRL_AFSEL6_Pos);
  GPIOK->AFR[0] |= (14 << GPIO_AFRL_AFSEL7_Pos);

 	//Set every Pin to have Very high speed (OSPEEDR)
  GPIOI->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED12_Pos);
  GPIOI->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED13_Pos);
  GPIOI->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED14_Pos);
  GPIOI->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED15_Pos);

  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED0_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED1_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED2_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED3_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED4_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED5_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED6_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED7_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED8_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED9_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED10_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED11_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED12_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED13_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED14_Pos);
  GPIOJ->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED15_Pos);

  GPIOK->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED0_Pos);
  GPIOK->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED1_Pos);
  GPIOK->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED2_Pos);
  GPIOK->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED3_Pos);
  GPIOK->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED4_Pos);
  GPIOK->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED5_Pos);
  GPIOK->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED6_Pos);
  GPIOK->OSPEEDR |= (3 << GPIO_OSPEEDR_OSPEED7_Pos);

}

void LTDC_Peripheral_Setup(void)
{
 	//Set Hsync and Vsync in LTDC_SSCR
  LTDC->SSCR |= ((20 - 1) << LTDC_SSCR_VSH_Pos);	//Vsync
  LTDC->SSCR |= ((30 - 1) << LTDC_SSCR_HSW_Pos);	//Wsync

 	//Back porch configuration
  LTDC->BPCR |= ((20 + 12 - 1) << LTDC_BPCR_AVBP_Pos);	//Vsync + VBP
  LTDC->BPCR |= ((43 + 30 - 1) << LTDC_BPCR_AHBP_Pos);	//Hsync + HBP

 	//Active width and height configuration
  LTDC->AWCR |= ((20 + 12 + 272 - 1) << LTDC_AWCR_AAH_Pos);	//Active height
  LTDC->AWCR |= ((43 + 30 + 480 - 1) << LTDC_AWCR_AAW_Pos);	//Active weight

 	//Total width configuration
  LTDC->TWCR |= ((20 + 12 + 272 + 4 - 1) << LTDC_TWCR_TOTALH_Pos);	//Total height
  LTDC->TWCR |= ((43 + 30 + 480 + 8 - 1) << LTDC_TWCR_TOTALW_Pos);	//Total weight

 	//Configure color red

  LTDC->BCCR |= (0xFF UL << LTDC_BCCR_BCRED_Pos);

 	//Enable LTDC peripheral
  LTDC->GCR |= (1 << 0);
}
1 ACCEPTED SOLUTION

Accepted Solutions

You need to download the all package from this link

Then go to this path: \Projects\STM32H7B3I-DK\Examples\LTDC

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

View solution in original post

17 REPLIES 17
jiangfan
ST Employee

You may refer to an example for this board:

STM32CubeH7/Projects/STM32H7B3I-DK/Examples/LTDC at master · STMicroelectronics/STM32CubeH7 · GitHub

 

after the example is OK for your board, you may translate the source code to your desired style - only setting bits in the register.

SofLit
ST Employee

Hello,

It's a very painful task to check this kind of code (direct access to the registers).

As stated by @jiangfan , you need to run the example(s) provided in CubeH7 then you can inspire from it and finally doing optimization by a direct access to the registers.

PS: next time use  </> button to insert the code for readability.

Thank you.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Peter BENSCH
ST Employee

@richi I sent the code through a code beautifier for you and inserted it as code with </> as suggested by @SofLit. It's much easier to read, don't you think?

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

@Peter BENSCH indeed but he needs to start by using HAL before going to direct access to the registers. Analyzing each bit (set/reset) in each register with different peripherals needs a huge time to analyze.

I suggest him to start with HAL. If he faces issues, he can post the code as it will be easy to analyze.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Maybe a *** question but repo does not have the classic "Code<>" button where I can just copy the URL. Is there any other way to download the code?

richi_0-1709125832063.png

 

You need to download the all package from this link

Then go to this path: \Projects\STM32H7B3I-DK\Examples\LTDC

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

I downloaded code but I dont know how to flash it to board. I opened the project in STM cube IDE but it does not allow me to build it. I went to File > Open Projects from File System and chose the LTDC_Display_2_Layers folder. Is there any other correct way?

richi_0-1709129945503.png

 

 

SofLit
ST Employee

How you did open the project?

This is what you have to get as view:

SofLit_0-1709130745885.png

You need to have "IDE" label in blue square on the project view.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

I did manage to load it into workspace, but when I tried to build I get this error , in which folder should I paste that header file? 

richi_0-1709134165624.png