Skip to main content
Associate III
February 27, 2024
Solved

STM32H7B3I -DK unable to activate LCD - screen through registers

  • February 27, 2024
  • 7 replies
  • 6977 views

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);
}
Best answer by mƎALLEm

You need to download the all package from this link

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

7 replies

jiangfan
ST Employee
February 28, 2024

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.

richiAuthor
Associate III
February 28, 2024

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

 

mƎALLEm
mƎALLEmBest answer
ST Technical Moderator
February 28, 2024

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 "Best answer" on the reply which solved your issue or answered your question.
mƎALLEm
ST Technical Moderator
February 28, 2024

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 "Best answer" on the reply which solved your issue or answered your question.
Peter BENSCH
ST Technical Moderator
February 28, 2024

@richi I sent the code through a code beautifier for you and inserted it as code with </> as suggested by @mƎALLEm. 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.
mƎALLEm
ST Technical Moderator
February 28, 2024

@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 "Best answer" on the reply which solved your issue or answered your question.
mƎALLEm
ST Technical Moderator
February 28, 2024

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 "Best answer" on the reply which solved your issue or answered your question.
richiAuthor
Associate III
February 28, 2024

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

 

mƎALLEm
ST Technical Moderator
February 29, 2024

Sorry I didn't understand what you copied? and why you copied it?

You need to have the all package and build the project (out of the box) from here: STM32Cube_FW_H7_VX.Y.0\Projects\STM32H7B3I-DK\Examples\LTDC\LTDC_Display_2Layers\STM32CubeIDE\

 No need to copy or move any file!

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.
mƎALLEm
ST Technical Moderator
March 1, 2024

Please re-download the package from here and build the project as it is .. There is no problems with the projects.

Also try to shorten the path to the projects from your drive root for example copy your STM32CubeH7 package directly under C: as Windows uses a path length limitation.

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.
Peter BENSCH
ST Technical Moderator
March 1, 2024

@richi The firmware library uses relative paths and expects .c/.h files to be located at a specific relative position. So you cannot simply copy an example from the firmware structure and expect everything to be compilable.

Have you tested the examples directly from the directory structure recommended by @mƎALLEm , i.e. without copying them anywhere?

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.
richiAuthor
Associate III
March 1, 2024

I did , they out of the box cannot be built because they throw errors that stm32h7xx.h is missing 

richi_0-1709330862336.png

 

Peter BENSCH
ST Technical Moderator
March 2, 2024

I can see from your screenshot that you are neither working in the unchanged directory structure nor using a short path as suggested by @mƎALLEm. As long as you do not implement this, you will always have problems.

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.
richiAuthor
Associate III
March 3, 2024

richi_0-1709459815422.png

I must say that I dont understand what does it mean to "test the examples directly from the directory structure". I tried to go File >> Open Projects from File System choose the LTDC_2Layers directory , but then I am unable to build the project. If I go to LTDC_2Layers and click on the .project file it imports my project in Cube , I build it and the above picture is the result. I changed relative path in C: but error persists.

 

mƎALLEm
ST Technical Moderator
March 4, 2024

Hello,

When CubeMx suggested you to download the H7 library did you do it?

You need to have the H7 cube package on this path <user>\STM32Cube\Repository\STM32Cube_FW_H7_VX.YY.ZZ

No need to import the project from File >> Open Projects . Simply open the project by clicking .project file.

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