cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H755 FMC LCD working on M4 core but not on M7 core

giorgio
Associate II

I'm using an STM43H755 (on a NUCLEO-H755ZI-Q) and I need to send pixels to an external LCD module (320x240, 8bit MCU bus on ILI9341 controller, 3.3V compatible).

I've used plenty of single core MCUs like F0, F4, F7 and others from ST in the past but It's my first contact with this dual core MCU, so perhaps I'm missing some initialization or code down the path..

I'm focusing on access time and performance so I'm using the FMC on the LCD 1 bank, with Register Select on A8, Chip Select on NE1, 8 bit data on [A0..A7], Write Operation enabled, Write FIFO enabled, Extended mode disabled, FMC bank mapping is set to Default.

Speculation default mode, MPU, I-Cache and D-Cache on the M7 core are disabled, MPU on the M4 core is disabled.

No other peripherals are enabled except: 3 GPIO outputs for the leds on the Nucleo, 1 GPIO input from the blue button, 1 GPIO output for the LCD reset.

The main 8 MHz clock is taken from the debugger, M7 clock is 400 MHz, M4 clock is 200 MHz, FMC clock is 200 MHz, Supply source is PWR_DIRECT_SMPS_SUPPLY and Power regulator voltage scale is set to 1.

No other middle-ware or OS is included in the project, It's a clean .ioc.

By now I'm accessing the display using pointers but I'm planning to use some DMA (MDMA?) later.

 

#define FMC_LCD1_BASE_REG 		((uint32_t)0x60000000)
#define FMC_LCD1_BASE_DATA 		((uint32_t)0x60000100)

#define FMC_LCD1_WriteReg(x)	*(volatile uint8_t *) (FMC_LCD1_BASE_REG)  = (x)
#define FMC_LCD1_WriteData(x)	*(volatile uint8_t *) (FMC_LCD1_BASE_DATA) = (x)
#define	FMC_LCD1_ReadData()		*(volatile uint8_t *) (FMC_LCD1_BASE_DATA)

 

The MCU seems to startup both cores and run a simple blinky test on both to check everything is ok (including debug on both).

The LCD initialization and test (some alternating full screen colors) runs fine on the M4 core, but I've no success in running it on the M7.

The FMC peripheral is initialized by the M7 in the case of the test running on the M7 and is initialized on the M4 in the case of the test running on the M4, the LCD init code is called in the main of the selected core after all the MX inits right before the "while(1)", there is no shared access to the FMC.

On both cores no compiler optimization is enabled (-O0).

While M7 is in charge of the init and test the bus seems to be alive and moving, but I've no means to confirm that the data transmitted is physically ok, anyway the same exact init and test runs fine on the M4 so I'm really confident that the ILI9341 initialization is done correctly and pixel data format is right.

I'm running out of ideas to try, can someone help me out on this?

Thank you!

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
SofLit
ST Employee

Hello,

You didn't mention what kind of issue you faced with CM7. timing issue? data integrity? 

What do you mean by "but I've no success in running it on the M7" ?

Did you try to check the FMC signals with a logic analyzer or an oscilloscope and compare the behavior CM7 vs CM4?

Did you configure the LCD memory region as Device or Strongly-ordred using the MPU?

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

3 REPLIES 3
SofLit
ST Employee

Hello,

You didn't mention what kind of issue you faced with CM7. timing issue? data integrity? 

What do you mean by "but I've no success in running it on the M7" ?

Did you try to check the FMC signals with a logic analyzer or an oscilloscope and compare the behavior CM7 vs CM4?

Did you configure the LCD memory region as Device or Strongly-ordred using the MPU?

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.

Hi @SofLit,


@SofLit wrote:

You didn't mention what kind of issue you faced with CM7. timing issue? data integrity? 


After some test the issue with the M7 seems to be the data writes (address 0x60000100), while commands writes  (address 0x60000000) are reaching the display controller.


@SofLit wrote:

What do you mean by "but I've no success in running it on the M7" ?


The same init and test sequence on M4 is running perfectly.

On the M7 the whole init "seems" to end correctly (the display is turning on), but from my observations I can see that only single byte commands (the ones not followed by any data writes) are executed.


@SofLit wrote:

Did you configure the LCD memory region as Device or Strongly-ordred using the MPU?


MPU is disabled in my configuration, do i need to enable it?

 


@SofLit wrote:

Did you try to check the FMC signals with a logic analyzer or an oscilloscope and compare the behavior CM7 vs CM4?


I need to hookup a DSO to confirm this theory asap.

Thank you.

 

EDIT: Searching into the forum the words "device strongly-ordred MPU STM32H7 FMC" lead me to:

  1. This community post 
  2. STM32_MPU_tips

I'll give them a read. 

giorgio
Associate II

Thanks @SofLit for pointing out the MPU issue.

After the correct MPU initialization the LCD works under the M7 control.

Addresses 0x60000000 and 0x60000100 needed to be set as Strongly-Ordered.

void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct = {0};

  /* Disables the MPU */
  HAL_MPU_Disable();

  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.BaseAddress = 0x60000000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_32B;
  MPU_InitStruct.SubRegionDisable = 0x0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);

  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Number = MPU_REGION_NUMBER1;
  MPU_InitStruct.BaseAddress = 0x60000100;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

}