How to use LTDC layers from CM33 and CA35 simultaneously

Revision as of 14:19, 17 June 2024 by Registered User (→‎Operating mode)
Applicable for STM32MP25x lines

1. Article purpose[edit source]

This article aims to specify how to use LTDC 3rd Layer, controlled by Arm®-Cortex® M33 while displaying standard HMI on OpenSTLinux running on Arm®-Cortex® A35, using STM32Cube MPU firmware example.

This article also explains how to configure LTDC 3rd layer (Resolution, Window sizing, Opacity etc.) and how to make changes in OP-TEE RIF settings from External device tree so that LTDC 3rd Layer can be controlled via Arm®-Cortex® M33.

2. Prerequisites[edit source]

To run the STM32Cube Example to demonstrate the LTDC 3rd layer controlled by CM33 while displaying Standard HMI on OpenSTLinux running on Arm®-Cortex® A35, required hardware and software stacks are listed below:

Warning white.png Warning
  • Be sure to have installed the STM32CubeMP2 Package and the STM32CubeIDE.
  • Be sure also to have connected ST-Link and Ethernet cables to your board.

3. LTDC 3rd Layer example description[edit source]

The goal of this example is to demonstrate Arm®-Cortex® M33 controlled 3rd Layer non-protected while displaying standard HMI on OpenSTLinux running on Arm®-Cortex® A35.

This example displays a splash screen logo and a message during 20 seconds. It can be adapted for various use cases like displaying parameters of a running process controlled by the Arm®-Cortex® M33: motor speed, camera status, detected events, visual watch dog...

Info white.png Information
You can browse this example source code in <CubePackage>/Projects/STM32MP257F-EV1/Examples/LTDC

3.1. Steps to configure the 3rd Layer of LTDC[edit source]

  • Read back LTDC "common registers" to determine Panel information (height and width). Note that the display panel and the LTDC internal peripheral have already been initialized by OpenSTLinux running on Arm®-Cortex® A35
  • Configure the LTDC 3rd Layer with "no Reload trigger"
  1. Window Sizing (Full Screen and Partial Screen Mode) controlled by "FULLSCREEN" Preprocessor
  2. Opacity (controlled by "constA" : set in such a way HMI will be visible)
  3. Input Pixel Format (Input Pixel Format will be RGB565)
  • Set Immediate reload type (reload)
Info white.png Information
Refer to the LTDC internal peripheral article for more details.

3.2. LTDC 3rd layer display content[edit source]

  • Splash screen will be displayed with content (Example description, and ST logo)
  • Splash screen will disappear after 20 second timeout (SUCCESS)

3.3. Operating mode[edit source]

After the LCD initialization, the LCD layer 3 is configured as following:

  • FULLSCREEN Mode (with "FULLSCREEN" Preprocessor): layer 3 is configured to display a framebuffer content read from the DDR memory with direct color (RGB565) as pixel format and 1024x600 as resolution (same resolution as the panel).
LTDC 3rd Layer Framebuffer Content in FULLSCREEN Mode
  • Partial Screen Mode (with no "FULLSCREEN" Preprocessor): Layer 3 is configured to display a framebuffer content read from the DDR memory with direct color (RGB565) as pixel format and 720x480 as resolution (smaller resolution than the panel.
LTDC 3rd Layer Framebuffer content in Partial Mode

3.4. Display composition[edit source]

The LTDC internal peripheral supports 3 Layers of display composition, where blending order and blending factor of each layer with other can be configured. The LTDC common register, Layer 1 and Layer 2 configuration is being controlled by CA35 whereas to demonstrate the LTDC 3rd Layer, Layer 3 resource is allocated to Arm®-Cortex® M33.

LTDC Layers Display Composition

4. How to configure RIF to use LTDC 3rd layer in a non-secure context from Arm-Cortex M33[edit source]

"ltdc_m33_layer" region of 4M size has been used for framebuffer (fb_address: 0x81300000 of 4MB).

To be able to write via Arm®-Cortex® M33 and read via LTDC AXI DMA engine in NSEC state to this framebuffer region, CID2 and CID4 are listed into read and write list of RISAF region 12

LTDC_L2_ID resource under RIFSC has been statically allocated to CID2 and set to non-secure access

  • Refer below changes in the External DT
<EXTERNAL DT>/optee/stm32mp257f-ev1-ca35tdcid-ostl-m33-examples-rif.dtsi

&rifsc {
       st,protreg = <
                .
                . 
                .
                RIFPROT(STM32MP25_RIFSC_LTDC_L0L1_ID, RIF_UNUSED, RIF_UNLOCK, RIF_NSEC, RIF_PRIV, RIF_CID1, RIF_SEM_DIS, RIF_CFEN)
-               RIFPROT(STM32MP25_RIFSC_LTDC_L2_ID, RIF_UNUSED, RIF_UNLOCK, RIF_NSEC, RIF_PRIV, RIF_CID1, RIF_SEM_DIS, RIF_CFEN)
+               RIFPROT(STM32MP25_RIFSC_LTDC_L2_ID, RIF_UNUSED, RIF_UNLOCK, RIF_NSEC, RIF_PRIV, RIF_CID2, RIF_SEM_DIS, RIF_CFEN)
                RIFPROT(STM32MP25_RIFSC_LTDC_ROT_ID, RIF_UNUSED, RIF_UNLOCK, RIF_NSEC, RIF_PRIV, RIF_CID1, RIF_SEM_DIS, RIF_CFEN)
                .
                .   
                .
      >;
 };       

&rifsc {
        st,rimu = <
                .
                .  
                RIMUPROT(RIMU_ID(9), RIF_UNUSED, RIF_NSEC, RIF_PRIV, RIF_CIDSEL_P)
                RIMUPROT(RIMU_ID(10), RIF_UNUSED, RIF_NSEC, RIF_PRIV, RIF_CIDSEL_P)
                RIMUPROT(RIMU_ID(11), RIF_CID4, RIF_NSEC, RIF_PRIV, RIF_CIDSEL_M)
-               RIMUPROT(RIMU_ID(12), RIF_CID4, RIF_SEC, RIF_PRIV, RIF_CIDSEL_M)
+               RIMUPROT(RIMU_ID(12), RIF_CID4, RIF_NSEC, RIF_PRIV, RIF_CIDSEL_M)
                RIMUPROT(RIMU_ID(13), RIF_CID4, RIF_NSEC, RIF_PRIV, RIF_CIDSEL_M)
                RIMUPROT(RIMU_ID(14), RIF_UNUSED, RIF_NSEC, RIF_PRIV, RIF_CIDSEL_P)
                RIMUPROT(RIMU_ID(15), RIF_UNUSED, RIF_NSEC, RIF_PRIV, RIF_CIDSEL_P)
                .
                .
      >;
 };


&ltdc_m33_layer {
         st,protreg = <RISAFPROT(RISAF_REG_ID(12), RIF_CID2_BF|RIF_CID4_BF, RIF_CID2_BF|RIF_CID4_BF, RIF_UNUSED, RIF_NSEC, RIF_ENC_DIS, RIF_BREN_EN)>;
};


 &risaf4 {
-       memory-region= <&tfm_code>, <&cm33_cube_fw>, <&tfm_data>, <&cm33_cube_data>, <&ipc_shmem>, <&spare1>, <&bl31_context>, <&op_tee>, <&linuxkernel1>, <&gpu_reserved>, <&ltdc_sec_layer>, <&ltdc_sec_rotation>, <&linuxkernel2>;
+       memory-region= <&tfm_code>, <&cm33_cube_fw>, <&tfm_data>, <&cm33_cube_data>, <&ipc_shmem>, <&spare1>, <&bl31_context>, <&op_tee>, <&linuxkernel1>, <&gpu_reserved>, <&ltdc_m33_layer>, <&ltdc_sec_layer>, <&ltdc_sec_rotation>, <&linuxkernel2>;
 };

<EXTERNAL DT>/optee/stm32mp257f-ev1-ca35tdcid-ostl-m33-examples-resmem.dtsi

       reserved-memory {
               #address-cells = <2>;
               #size-cells = <2>;
               ranges;
               .
               .
               .
+               ltdc_sec_rotation: ltdc-sec-rotation@ff000000 {
+                       reg = <0x0 0xff000000 0x0 0x1000000>;
+                       no-map;
+               };
               . 
               .
      }
  • Run following commands:
cd <OPTEE>/out/arm-plat-stm32mp2/core
fiptool update fip-stm32mp257f-ev1-ca35tdcid-ostl-m33-examples-optee.bin --tos-fw tee-header_v2.bin --tos-fw-extra1 tee-pager_v2.bin --tos-fw-extra2 tee-pageable_v2.bin
  • Copy FIP binary into the target device inside the folder /home/root/
  • Run command for micro SD card:
dd if=fip-stm32mp257f-ev1-ca35tdcid-ostl-m33-examples-optee.bin  of=/dev/mmcblk0p5  conv=fdatasync
    • where mmcblk0p5 - mmcblk<MMC_INSTANCE>p<FIP_IMAGE_PARTITION_NUM>
  • Run command for eMMC:
dd if=fip-stm32mp257f-ev1-ca35tdcid-ostl-m33-examples-optee.bin  of=/dev/mmcblk1p3  conv=fdatasync
    • where mmcblk0p5 - mmcblk<MMC_INSTANCE>p<FIP_IMAGE_PARTITION_NUM>
  • Reboot the target device
  • Run the example

5. How to run STM32Cube MPU example[edit source]

To run the example on STM32MP257x-EV1 Evaluation board More info green.png, perform following steps:

  • Open the Project folder containing the example at following path <CubePackage>/Projects/STM32MP257F-EV1/Examples/LTDC and double-click on file .project to open Eclipse IDE
  • Build with config: CA35TDCID_m33_ns_sign
  • ssh root@192.168.7.1 'mkdir -p /home/root/LTDC_Display_3rdLayer/lib/firmware'
  • scp the signed firmware LTDC_Display_3rdLayer_CM33_NonSecure_sign.bin to root@192.168.7.1:/home/root/LTDC_Display_3rdLayer/lib/firmware
  • scp the script Firmware/Utilities/scripts/fw_cortex_m33.sh to root@192.168.7.1:/home/root/LTDC_Display_3rdLayer/
  • To run the example on target shell run following command:
 cd /home/root/LTDC_Display_3rdLayer
 ./fw_cortex_m33.sh start
Info white.png Information
You can browse this example source code in <CubePackage>/Projects/STM32MP257F-EV1/Examples/LTDC

.