This commit is contained in:
Thomas Laduguie committed 2026-09-04 09:57:30 +02:00
commit 75fbf8809d
489 files changed
+398278

No files matched your search

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+179
View File
@@ -0,0 +1,179 @@
/* USER CODE BEGIN Header */
/*
* FreeRTOS Kernel V10.5.1
* Portion Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Portion Copyright (C) 2019 StMicroelectronics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE .
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/* USER CODE END Header */
#ifndef __FREERTOS_CONFIG_H
#define __FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* These parameters and more are described within the 'configuration' section of the
* FreeRTOS API documentation available on the FreeRTOS.org web site.
*
* See http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* Section where include file can be added */
/* USER CODE END Includes */
/* Ensure definitions are only used by the compiler, and not by the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
#ifndef CMSIS_device_header
#define CMSIS_device_header "stm32h7rsxx.h"
#endif /* CMSIS_device_header */
#define configENABLE_FPU 0
#define configENABLE_MPU 0
#define configUSE_PREEMPTION 1
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ((TickType_t)1000)
#define configMAX_PRIORITIES ( 56 )
#define configUSE_SB_COMPLETED_CALLBACK ( 0 )
#define configUSE_MINI_LIST_ITEM ( 1 )
#define configMINIMAL_STACK_SIZE ((uint16_t)128)
#define configTOTAL_HEAP_SIZE ((size_t)50000)
#define configMAX_TASK_NAME_LEN ( 16 )
#define configHEAP_CLEAR_MEMORY_ON_FREE 0
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_APPLICATION_TASK_TAG 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
/* Defaults to size_t for backward compatibility, but can be changed
if lengths will always be less than the number of bytes in a size_t. */
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH 256
/* The following flag must be enabled only when using newlib */
#define configUSE_NEWLIB_REENTRANT 1
/* CMSIS-RTOS V2 flags */
#define configUSE_OS2_THREAD_SUSPEND_RESUME 1
#define configUSE_OS2_THREAD_ENUMERATE 1
#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1
#define configUSE_OS2_THREAD_FLAGS 1
#define configUSE_OS2_TIMER 1
#define configUSE_OS2_MUTEX 1
#define configTEX_S_C_B_SRAM ( 0x03UL )
#define configTOTAL_MPU_REGIONS 16
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_xTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xQueueGetMutexHolder 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_eTaskGetState 1
/*
* The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
* by the application thus the correct define need to be enabled below
*/
#define USE_FreeRTOS_HEAP_4
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
/* USER CODE BEGIN 1 */
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
/* USER CODE END 1 */
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */
#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 0
/* USER CODE BEGIN Defines */
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
#define traceTASK_SWITCHED_OUT() xTaskCallApplicationTaskHook( pxCurrentTCB, (void*)1 )
#define traceTASK_SWITCHED_IN() xTaskCallApplicationTaskHook( pxCurrentTCB, (void*)0 )
/* USER CODE END Defines */
#endif /* __FREERTOS_CONFIG_H */
+28
View File
@@ -0,0 +1,28 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file
* @author MCD Application Team
* @version V2.0.0
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __RTE_COMPONENTS_H__
#define __RTE_COMPONENTS_H__
/* Defines ------------------------------------------------------------------*/
/* STMicroelectronics.X-CUBE-TOUCHGFX.4.26.1 */
#define TOUCHGFX_APP
#endif /* __RTE_COMPONENTS_H__ */
+62
View File
@@ -0,0 +1,62 @@
/**
******************************************************************************
* @file jpeg_utils_conf.h
* @author MCD Application Team
* @brief jpeg_utils configuration file.
******************************************************************************
* @attention
*
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __JPEG_UTILS_CONF_H__
#define __JPEG_UTILS_CONF_H__
/* Includes ------------------------------------------------------------------*/
#include "stm32h7rsxx_hal.h"
#include "stm32h7rsxx_hal_jpeg.h"
/* Private define ------------------------------------------------------------*/
/** @addtogroup JPEG_Private_Defines
* @{
*/
/* RGB Color format definition for JPEG encoding/Decoding : Should not be modified*/
#define JPEG_ARGB8888 0 /* ARGB8888 Color Format */
#define JPEG_RGB888 1 /* RGB888 Color Format */
#define JPEG_RGB565 2 /* RGB565 Color Format */
/*
* Define USE_JPEG_DECODER
*/
#define USE_JPEG_DECODER 1 /* 1 or 0 ********* Value different from default value : 1 ********** */
/*
* Define USE_JPEG_ENCODER
*/
#define USE_JPEG_ENCODER 0 /* 1 or 0 */
/*
* Define JPEG_RGB_FORMAT
*/
#define JPEG_RGB_FORMAT JPEG_ARGB8888 /* JPEG_ARGB8888, JPEG_RGB888, JPEG_RGB565 ********* Value different from default value : 0 ********** */
/*
* Define JPEG_SWAP_RB
*/
#define JPEG_SWAP_RB 0 /* 0 or 1 ********* Value different from default value : 0 ********** */
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __JPEG_UTILS_CONF_H__ */
+90
View File
@@ -0,0 +1,90 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.h
* @brief : Header for main.c file.
* This file contains the common defines of the application.
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32h7rsxx_hal.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
#define FRAME_RATE_Pin GPIO_PIN_3
#define FRAME_RATE_GPIO_Port GPIOF
#define RENDER_TIME_Pin GPIO_PIN_2
#define RENDER_TIME_GPIO_Port GPIOF
#define ADF1_CK_Pin GPIO_PIN_2
#define ADF1_CK_GPIO_Port GPIOE
#define MCU_ACTIVE_Pin GPIO_PIN_4
#define MCU_ACTIVE_GPIO_Port GPIOF
#define VSYNC_FREQ_Pin GPIO_PIN_1
#define VSYNC_FREQ_GPIO_Port GPIOF
#define LCD_EN_Pin GPIO_PIN_15
#define LCD_EN_GPIO_Port GPIOE
#define ADF1_D_Pin GPIO_PIN_6
#define ADF1_D_GPIO_Port GPIOD
#define TP_IRQ_Pin GPIO_PIN_3
#define TP_IRQ_GPIO_Port GPIOE
#define TP_IRQ_EXTI_IRQn EXTI3_IRQn
#define LCD_BL_CTRL_Pin GPIO_PIN_15
#define LCD_BL_CTRL_GPIO_Port GPIOG
#define MIC_DET_Pin GPIO_PIN_1
#define MIC_DET_GPIO_Port GPIOH
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
+520
View File
@@ -0,0 +1,520 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32h7rsxx_hal_conf.h
* @author MCD Application Team
* @brief HAL configuration template file.
* This file should be copied to the application folder and renamed
* to stm32h7rsxx_hal_conf.h.
*
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32H7RSxx_HAL_CONF_H
#define STM32H7RSxx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* ########################## Module Selection ############################## */
/**
* @brief This is the list of modules to be used in the HAL driver
*/
#define HAL_MODULE_ENABLED
/* #define HAL_ADC_MODULE_ENABLED */
/* #define HAL_CEC_MODULE_ENABLED */
/* #define HAL_CORDIC_MODULE_ENABLED */
#define HAL_CRC_MODULE_ENABLED
/* #define HAL_CRYP_MODULE_ENABLED */
/* #define HAL_DCMIPP_MODULE_ENABLED */
#define HAL_DMA2D_MODULE_ENABLED
/* #define HAL_DTS_MODULE_ENABLED */
/* #define HAL_ETH_MODULE_ENABLED */
/* #define HAL_FDCAN_MODULE_ENABLED */
/* #define HAL_GFXMMU_MODULE_ENABLED */
/* #define HAL_GFXTIM_MODULE_ENABLED */
#define HAL_GPU2D_MODULE_ENABLED
/* #define HAL_HASH_MODULE_ENABLED */
/* #define HAL_HCD_MODULE_ENABLED */
#define HAL_I2C_MODULE_ENABLED
#define HAL_I2S_MODULE_ENABLED
/* #define HAL_I3C_MODULE_ENABLED */
#define HAL_ICACHE_MODULE_ENABLED
/* #define HAL_IRDA_MODULE_ENABLED */
/* #define HAL_IWDG_MODULE_ENABLED */
#define HAL_JPEG_MODULE_ENABLED
/* #define HAL_LPTIM_MODULE_ENABLED */
#define HAL_LTDC_MODULE_ENABLED
/* #define HAL_MCE_MODULE_ENABLED */
#define HAL_MDF_MODULE_ENABLED
/* #define HAL_MMC_MODULE_ENABLED */
/* #define HAL_NAND_MODULE_ENABLED */
/* #define HAL_NOR_MODULE_ENABLED */
/* #define HAL_PCD_MODULE_ENABLED */
/* #define HAL_PKA_MODULE_ENABLED */
/* #define HAL_PSSI_MODULE_ENABLED */
/* #define HAL_RAMECC_MODULE_ENABLED */
/* #define HAL_RCC_MODULE_ENABLED */
/* #define HAL_RNG_MODULE_ENABLED */
/* #define HAL_RTC_MODULE_ENABLED */
/* #define HAL_SAI_MODULE_ENABLED */
/* #define HAL_SD_MODULE_ENABLED */
/* #define HAL_SDIO_MODULE_ENABLED */
/* #define HAL_SDRAM_MODULE_ENABLED */
/* #define HAL_SMARTCARD_MODULE_ENABLED */
/* #define HAL_SMBUS_MODULE_ENABLED */
/* #define HAL_SPDIFRX_MODULE_ENABLED */
/* #define HAL_SPI_MODULE_ENABLED */
/* #define HAL_SRAM_MODULE_ENABLED */
#define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_WWDG_MODULE_ENABLED */
/* #define HAL_XSPI_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_EXTI_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
/* ########################## Oscillator Values adaptation ####################*/
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE 24000000UL /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up (in ms) */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE 64000000UL /*!< Value of the Internal oscillator in Hz */
#endif /* HSI_VALUE */
/**
* @brief Internal Low-power oscillator (CSI) default value.
* This value is the default CSI range value after Reset.
*/
#if !defined (CSI_VALUE)
#define CSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz */
#endif /* CSI_VALUE */
/**
* @brief Internal High Speed oscillator (HSI48) value for USB OTG FS and RNG.
* This internal oscillator is mainly dedicated to provide a high precision clock to
* the USB peripheral by means of a special Clock Recovery System (CRS) circuitry.
* When the CRS is not used, the HSI48 RC oscillator runs on it default frequency
* which is subject to manufacturing process variations.
*/
#if !defined (HSI48_VALUE)
#define HSI48_VALUE 48000000UL /*!< Value of the Internal High Speed oscillator for USB OTG FS/RNG in Hz.
The real value my vary depending on manufacturing process variations. */
#endif /* HSI48_VALUE */
/**
* @brief Internal Low Speed oscillator (LSI) value.
*/
#if !defined (LSI_VALUE)
#define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz.
Value of the Internal Low Speed oscillator in Hz.
The real value may vary depending on the variations
in voltage and temperature.*/
#endif /* LSI_VALUE */
/**
* @brief External Low Speed oscillator (LSE) value.
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/
#endif /* LSE_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up (in ms) */
#endif /* LSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for digital audio interfaces: SPI/I2S, SAI and ADF
* This value is used by the RCC HAL module to provide the digital audio interfaces
* frequency. This clock source is inserted directly through I2S_CKIN pad.
*/
#if !defined (EXTERNAL_CLOCK_VALUE)
#define EXTERNAL_CLOCK_VALUE 48000UL /*!< Value of the external clock source in Hz */
#endif /* EXTERNAL_CLOCK_VALUE */
/* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE 3300UL /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY (4UL)/*!< tick interrupt priority (lowest by default) */
#define USE_RTOS 0U
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* ################## Register callback feature configuration ############### */
/**
* @brief Set below the peripheral configuration to "1U" to add the support
* of HAL callback registration/unregistration feature for the HAL
* driver(s). This allows user application to provide specific callback
* functions thanks to HAL_PPP_RegisterCallback() rather than overwriting
* the default weak callback functions (see each stm32h7rsxx_hal_ppp.h file
* for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef
* for each PPP peripheral).
*/
#define USE_HAL_ADC_REGISTER_CALLBACKS 1U
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U
#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U
#define USE_HAL_DCMIPP_REGISTER_CALLBACKS 0U
#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U
#define USE_HAL_GFXMMU_REGISTER_CALLBACKS 0U
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U
#define USE_HAL_I2C_REGISTER_CALLBACKS 1U
#define USE_HAL_I2S_REGISTER_CALLBACKS 1U
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U
#define USE_HAL_JPEG_REGISTER_CALLBACKS 0U
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U
#define USE_HAL_MDF_REGISTER_CALLBACKS 1U
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U
#define USE_HAL_PKA_REGISTER_CALLBACKS 0U
#define USE_HAL_PSSI_REGISTER_CALLBACKS 0U
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U
#define USE_HAL_SAI_REGISTER_CALLBACKS 1U
#define USE_HAL_SD_REGISTER_CALLBACKS 0U
#define USE_HAL_SDIO_REGISTER_CALLBACKS 0U
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U
#define USE_HAL_SPI_REGISTER_CALLBACKS 1U
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U
#define USE_HAL_UART_REGISTER_CALLBACKS 1U
#define USE_HAL_USART_REGISTER_CALLBACKS 0U
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U
#define USE_HAL_XSPI_REGISTER_CALLBACKS 1U
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
* Activated: CRC code is present inside driver
* Deactivated: CRC code cleaned from driver
*/
#define USE_SPI_CRC 1U
/* ################## CRYP peripheral configuration ########################## */
/**
* @brief For code optimization purpose, uncomment and set to "1U" the USE_HAL_CRYP_ONLY or USE_HAL_SAES_ONLY,
* to use only one peripheral. Both defines cannot be set to "1U" at the same time.
*/
/* #define USE_HAL_CRYP_ONLY 1U */
/* #define USE_HAL_SAES_ONLY 0U */
#define USE_HAL_CRYP_SUSPEND_RESUME 0U
/* ################## HASH peripheral configuration ########################## */
#define USE_HAL_HASH_SUSPEND_RESUME 0U
/* ################## SDMMC peripheral configuration ######################### */
#define USE_SD_TRANSCEIVER 0U
/* ################## SDIO peripheral configuration ######################### */
#define USE_SDIO_TRANSCEIVER 0U
#define SDIO_MAX_IO_NUMBER 7U
/* Includes ------------------------------------------------------------------*/
/**
* @brief Include module's header file
*/
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32h7rsxx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32h7rsxx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32h7rsxx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32h7rsxx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
#include "stm32h7rsxx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_CEC_MODULE_ENABLED
#include "stm32h7rsxx_hal_cec.h"
#endif /* HAL_CEC_MODULE_ENABLED */
#ifdef HAL_CORDIC_MODULE_ENABLED
#include "stm32h7rsxx_hal_cordic.h"
#endif /* HAL_CORDIC_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
#include "stm32h7rsxx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_CRYP_MODULE_ENABLED
#include "stm32h7rsxx_hal_cryp.h"
#endif /* HAL_CRYP_MODULE_ENABLED */
#ifdef HAL_DCMIPP_MODULE_ENABLED
#include "stm32h7rsxx_hal_dcmipp.h"
#endif /* HAL_DCMIPP_MODULE_ENABLED */
#ifdef HAL_DMA2D_MODULE_ENABLED
#include "stm32h7rsxx_hal_dma2d.h"
#endif /* HAL_DMA2D_MODULE_ENABLED */
#ifdef HAL_DTS_MODULE_ENABLED
#include "stm32h7rsxx_hal_dts.h"
#endif /* HAL_DTS_MODULE_ENABLED */
#ifdef HAL_ETH_MODULE_ENABLED
#include "stm32h7rsxx_hal_eth.h"
#endif /* HAL_ETH_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED
#include "stm32h7rsxx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_FDCAN_MODULE_ENABLED
#include "stm32h7rsxx_hal_fdcan.h"
#endif /* HAL_FDCAN_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32h7rsxx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_GFXMMU_MODULE_ENABLED
#include "stm32h7rsxx_hal_gfxmmu.h"
#endif /* HAL_GFXMMU_MODULE_ENABLED */
#ifdef HAL_GFXTIM_MODULE_ENABLED
#include "stm32h7rsxx_hal_gfxtim.h"
#endif /* HAL_GFXTIM_MODULE_ENABLED */
#ifdef HAL_GPU2D_MODULE_ENABLED
#include "stm32h7rsxx_hal_gpu2d.h"
#endif /* HAL_GPU2D_MODULE_ENABLED */
#ifdef HAL_HASH_MODULE_ENABLED
#include "stm32h7rsxx_hal_hash.h"
#endif /* HAL_HASH_MODULE_ENABLED */
#ifdef HAL_HCD_MODULE_ENABLED
#include "stm32h7rsxx_hal_hcd.h"
#endif /* HAL_HCD_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32h7rsxx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_I2S_MODULE_ENABLED
#include "stm32h7rsxx_hal_i2s.h"
#endif /* HAL_I2S_MODULE_ENABLED */
#ifdef HAL_I3C_MODULE_ENABLED
#include "stm32h7rsxx_hal_i3c.h"
#endif /* HAL_I3C_MODULE_ENABLED */
#ifdef HAL_ICACHE_MODULE_ENABLED
#include "stm32h7rsxx_hal_icache.h"
#endif /* HAL_ICACHE_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32h7rsxx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32h7rsxx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_JPEG_MODULE_ENABLED
#include "stm32h7rsxx_hal_jpeg.h"
#endif /* HAL_JPEG_MODULE_ENABLED */
#ifdef HAL_LTDC_MODULE_ENABLED
#include "stm32h7rsxx_hal_ltdc.h"
#endif /* HAL_LTDC_MODULE_ENABLED */
#ifdef HAL_LPTIM_MODULE_ENABLED
#include "stm32h7rsxx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */
#ifdef HAL_MCE_MODULE_ENABLED
#include "stm32h7rsxx_hal_mce.h"
#endif /* HAL_MCE_MODULE_ENABLED */
#ifdef HAL_MDF_MODULE_ENABLED
#include "stm32h7rsxx_hal_mdf.h"
#endif /* HAL_MDF_MODULE_ENABLED */
#ifdef HAL_MMC_MODULE_ENABLED
#include "stm32h7rsxx_hal_mmc.h"
#endif /* HAL_MMC_MODULE_ENABLED */
#ifdef HAL_NAND_MODULE_ENABLED
#include "stm32h7rsxx_hal_nand.h"
#endif /* HAL_NAND_MODULE_ENABLED */
#ifdef HAL_NOR_MODULE_ENABLED
#include "stm32h7rsxx_hal_nor.h"
#endif /* HAL_NOR_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
#include "stm32h7rsxx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_PKA_MODULE_ENABLED
#include "stm32h7rsxx_hal_pka.h"
#endif /* HAL_PKA_MODULE_ENABLED */
#ifdef HAL_PSSI_MODULE_ENABLED
#include "stm32h7rsxx_hal_pssi.h"
#endif /* HAL_PSSI_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32h7rsxx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_RAMECC_MODULE_ENABLED
#include "stm32h7rsxx_hal_ramecc.h"
#endif /* HAL_RAMECC_MODULE_ENABLED */
#ifdef HAL_RNG_MODULE_ENABLED
#include "stm32h7rsxx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
#include "stm32h7rsxx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SAI_MODULE_ENABLED
#include "stm32h7rsxx_hal_sai.h"
#endif /* HAL_SAI_MODULE_ENABLED */
#ifdef HAL_SD_MODULE_ENABLED
#include "stm32h7rsxx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */
#ifdef HAL_SDIO_MODULE_ENABLED
#include "stm32h7rsxx_hal_sdio.h"
#endif /* HAL_SDIO_MODULE_ENABLED */
#ifdef HAL_SDRAM_MODULE_ENABLED
#include "stm32h7rsxx_hal_sdram.h"
#endif /* HAL_SDRAM_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32h7rsxx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_SMBUS_MODULE_ENABLED
#include "stm32h7rsxx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */
#ifdef HAL_SPDIFRX_MODULE_ENABLED
#include "stm32h7rsxx_hal_spdifrx.h"
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
#include "stm32h7rsxx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_SRAM_MODULE_ENABLED
#include "stm32h7rsxx_hal_sram.h"
#endif /* HAL_SRAM_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
#include "stm32h7rsxx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
#include "stm32h7rsxx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
#include "stm32h7rsxx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32h7rsxx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
#ifdef HAL_XSPI_MODULE_ENABLED
#include "stm32h7rsxx_hal_xspi.h"
#endif /* HAL_XSPI_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t *file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* STM32H7RSxx_HAL_CONF_H */
+75
View File
@@ -0,0 +1,75 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32h7rsxx_it.h
* @brief This file contains the headers of the interrupt handlers.
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32H7RSxx_IT_H
#define __STM32H7RSxx_IT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void DebugMon_Handler(void);
void EXTI3_IRQHandler(void);
void GPDMA1_Channel0_IRQHandler(void);
void GPDMA1_Channel2_IRQHandler(void);
void TIM6_IRQHandler(void);
void HPDMA1_Channel0_IRQHandler(void);
void HPDMA1_Channel1_IRQHandler(void);
void LTDC_IRQHandler(void);
void DMA2D_IRQHandler(void);
void JPEG_IRQHandler(void);
void ADF1_FLT0_IRQHandler(void);
void GPU2D_IRQHandler(void);
void GPU2D_ER_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
#ifdef __cplusplus
}
#endif
#endif /* __STM32H7RSxx_IT_H */
@@ -0,0 +1,65 @@
/**
******************************************************************************
* @file stm32h7s78_discovery_conf.h
* @author MCD Application Team
* @brief STM32H7S78-DK board configuration file.
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32H7S78_DISCOVERY_CONF_H
#define STM32H7S78_DISCOVERY_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32h7rsxx_hal.h"
/* COM defines */
#define USE_COM_LOG 0U
#define USE_BSP_COM_FEATURE 1U
/* Touch Sensing controller defines */
#define USE_FT5336_TS_CTRL 1U
/* TS supported features defines */
#define USE_TS_GESTURE 1U
#define USE_TS_MULTI_TOUCH 1U
/* Default TS touch number */
#define TS_TOUCH_NBR 2U
/* LCD defines */
#define LCD_LAYER_0_ADDRESS 0x90000000U
#define LCD_LAYER_1_ADDRESS 0x90200000U
/* Default Audio IN internal buffer size */
#define DEFAULT_AUDIO_IN_BUFFER_SIZE 2048U
/* IRQ priorities (Default is 15 as lowest priority level) */
#define BSP_SDRAM_IT_PRIORITY 15U
#define BSP_BUTTON_USER_IT_PRIORITY 15U
#define BSP_AUDIO_OUT_IT_PRIORITY 2U // testé à 1 (au-dessus du micro) sur plusieurs redémarrages : aucun effet -> la contention NVIC n'est pas en cause
#define BSP_AUDIO_IN_IT_PRIORITY 2U
#define BSP_SD_IT_PRIORITY 14U
#define BSP_SD_RX_IT_PRIORITY 14U
#define BSP_SD_TX_IT_PRIORITY 15U
#define BSP_TS_IT_PRIORITY 15U
#define BSP_XSPI_RAM_IT_PRIORITY 15U
#define BSP_XSPI_RAM_DMA_IT_PRIORITY 15U
#ifdef __cplusplus
}
#endif
#endif /* STM32H7S78_DISCOVERY_CONF_H */
+79
View File
@@ -0,0 +1,79 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : freertos.c
* Description : Code for freertos applications
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
extern portBASE_TYPE IdleTaskHook(void* p);
/* USER CODE END FunctionPrototypes */
/* Hook prototypes */
void vApplicationIdleHook(void);
/* USER CODE BEGIN 2 */
void vApplicationIdleHook( void )
{
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */
vTaskSetApplicationTaskTag(NULL, IdleTaskHook);
}
/* USER CODE END 2 */
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */
File diff suppressed because it is too large. Load diff
+803
View File
@@ -0,0 +1,803 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32h7rsxx_hal_msp.c
* @brief This file provides code for the MSP Initialization
* and de-Initialization codes.
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern DMA_NodeTypeDef Node_GPDMA1_Channel0;
extern DMA_QListTypeDef List_GPDMA1_Channel0;
extern DMA_HandleTypeDef handle_GPDMA1_Channel0;
extern DMA_HandleTypeDef handle_HPDMA1_Channel1;
extern DMA_HandleTypeDef handle_HPDMA1_Channel0;
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN Define */
/* USER CODE END Define */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
/* USER CODE END Macro */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* External functions --------------------------------------------------------*/
/* USER CODE BEGIN ExternalFunctions */
/* USER CODE END ExternalFunctions */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
/* System interrupt init*/
/* PendSV_IRQn interrupt configuration */
HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
/**
* @brief MDF MSP Initialization
* This function configures the hardware resources used in this example
* @param hmdf: MDF handle pointer
* @retval None
*/
void HAL_MDF_MspInit(MDF_HandleTypeDef* hmdf)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
DMA_NodeConfTypeDef NodeConfig;
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if(IS_MDF_ALL_INSTANCE(hmdf->Instance))
{
/* USER CODE BEGIN ADF1_MspInit 0 */
/* USER CODE END ADF1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADF1;
PeriphClkInit.Adf1ClockSelection = RCC_ADF1CLKSOURCE_PLL2P;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_ADF1_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**ADF1 GPIO Configuration
PE2 ------> ADF1_CCK0
PD6 ------> ADF1_SDI0
*/
GPIO_InitStruct.Pin = ADF1_CK_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // était LOW : bien trop lent pour piloter proprement une horloge à 6-12MHz+ vers le micro PDM
GPIO_InitStruct.Alternate = GPIO_AF1_ADF1;
HAL_GPIO_Init(ADF1_CK_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = ADF1_D_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF3_ADF1;
HAL_GPIO_Init(ADF1_D_GPIO_Port, &GPIO_InitStruct);
/* ADF1 DMA Init */
/* GPDMA1_REQUEST_ADF1_FLT0 Init */
NodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
NodeConfig.Init.Request = GPDMA1_REQUEST_ADF1_FLT0;
NodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
NodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY;
NodeConfig.Init.SrcInc = DMA_SINC_FIXED;
NodeConfig.Init.DestInc = DMA_DINC_INCREMENTED;
NodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
NodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
NodeConfig.Init.SrcBurstLength = 1;
NodeConfig.Init.DestBurstLength = 1;
NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
NodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
NodeConfig.Init.Mode = DMA_NORMAL;
NodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
NodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
NodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
if (HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel0) != HAL_OK)
{
Error_Handler();
}
if (HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel0, NULL, &Node_GPDMA1_Channel0) != HAL_OK)
{
Error_Handler();
}
if (HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel0) != HAL_OK)
{
Error_Handler();
}
handle_GPDMA1_Channel0.Instance = GPDMA1_Channel0;
handle_GPDMA1_Channel0.InitLinkedList.Priority = DMA_HIGH_PRIORITY;
handle_GPDMA1_Channel0.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
handle_GPDMA1_Channel0.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT1;
handle_GPDMA1_Channel0.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_GPDMA1_Channel0.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
if (HAL_DMAEx_List_Init(&handle_GPDMA1_Channel0) != HAL_OK)
{
Error_Handler();
}
if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel0, &List_GPDMA1_Channel0) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hmdf, hdma, handle_GPDMA1_Channel0);
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel0, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
/* ADF1 interrupt Init */
HAL_NVIC_SetPriority(ADF1_FLT0_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(ADF1_FLT0_IRQn);
/* USER CODE BEGIN ADF1_MspInit 1 */
/* USER CODE END ADF1_MspInit 1 */
}
}
/**
* @brief MDF MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hmdf: MDF handle pointer
* @retval None
*/
void HAL_MDF_MspDeInit(MDF_HandleTypeDef* hmdf)
{
if(IS_MDF_ALL_INSTANCE(hmdf->Instance))
{
/* USER CODE BEGIN ADF1_MspDeInit 0 */
/* USER CODE END ADF1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_ADF1_CLK_DISABLE();
/**ADF1 GPIO Configuration
PE2 ------> ADF1_CCK0
PD6 ------> ADF1_SDI0
*/
HAL_GPIO_DeInit(ADF1_CK_GPIO_Port, ADF1_CK_Pin);
HAL_GPIO_DeInit(ADF1_D_GPIO_Port, ADF1_D_Pin);
/* ADF1 DMA DeInit */
HAL_DMA_DeInit(hmdf->hdma);
/* ADF1 interrupt DeInit */
HAL_NVIC_DisableIRQ(ADF1_FLT0_IRQn);
/* USER CODE BEGIN ADF1_MspDeInit 1 */
/* USER CODE END ADF1_MspDeInit 1 */
}
}
/**
* @brief CRC MSP Initialization
* This function configures the hardware resources used in this example
* @param hcrc: CRC handle pointer
* @retval None
*/
void HAL_CRC_MspInit(CRC_HandleTypeDef* hcrc)
{
if(hcrc->Instance==CRC)
{
/* USER CODE BEGIN CRC_MspInit 0 */
/* USER CODE END CRC_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CRC_CLK_ENABLE();
/* USER CODE BEGIN CRC_MspInit 1 */
/* USER CODE END CRC_MspInit 1 */
}
}
/**
* @brief CRC MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hcrc: CRC handle pointer
* @retval None
*/
void HAL_CRC_MspDeInit(CRC_HandleTypeDef* hcrc)
{
if(hcrc->Instance==CRC)
{
/* USER CODE BEGIN CRC_MspDeInit 0 */
/* USER CODE END CRC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CRC_CLK_DISABLE();
/* USER CODE BEGIN CRC_MspDeInit 1 */
/* USER CODE END CRC_MspDeInit 1 */
}
}
/**
* @brief DMA2D MSP Initialization
* This function configures the hardware resources used in this example
* @param hdma2d: DMA2D handle pointer
* @retval None
*/
void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef* hdma2d)
{
if(hdma2d->Instance==DMA2D)
{
/* USER CODE BEGIN DMA2D_MspInit 0 */
/* USER CODE END DMA2D_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_DMA2D_CLK_ENABLE();
/* DMA2D interrupt Init */
HAL_NVIC_SetPriority(DMA2D_IRQn, 5, 0);
/* USER CODE BEGIN DMA2D_MspInit 1 */
/* USER CODE END DMA2D_MspInit 1 */
}
}
/**
* @brief DMA2D MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hdma2d: DMA2D handle pointer
* @retval None
*/
void HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef* hdma2d)
{
if(hdma2d->Instance==DMA2D)
{
/* USER CODE BEGIN DMA2D_MspDeInit 0 */
/* USER CODE END DMA2D_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_DMA2D_CLK_DISABLE();
/* DMA2D interrupt DeInit */
HAL_NVIC_DisableIRQ(DMA2D_IRQn);
/* USER CODE BEGIN DMA2D_MspDeInit 1 */
/* USER CODE END DMA2D_MspDeInit 1 */
}
}
/**
* @brief GPU2D MSP Initialization
* This function configures the hardware resources used in this example
* @param hgpu2d: GPU2D handle pointer
* @retval None
*/
void HAL_GPU2D_MspInit(GPU2D_HandleTypeDef* hgpu2d)
{
if(hgpu2d->Instance==GPU2D)
{
/* USER CODE BEGIN GPU2D_MspInit 0 */
/* USER CODE END GPU2D_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_GPU2D_CLK_ENABLE();
/* GPU2D interrupt Init */
HAL_NVIC_SetPriority(GPU2D_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(GPU2D_IRQn);
HAL_NVIC_SetPriority(GPU2D_ER_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(GPU2D_ER_IRQn);
/* USER CODE BEGIN GPU2D_MspInit 1 */
/* USER CODE END GPU2D_MspInit 1 */
}
}
/**
* @brief GPU2D MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hgpu2d: GPU2D handle pointer
* @retval None
*/
void HAL_GPU2D_MspDeInit(GPU2D_HandleTypeDef* hgpu2d)
{
if(hgpu2d->Instance==GPU2D)
{
/* USER CODE BEGIN GPU2D_MspDeInit 0 */
/* USER CODE END GPU2D_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_GPU2D_CLK_DISABLE();
/* GPU2D interrupt DeInit */
HAL_NVIC_DisableIRQ(GPU2D_IRQn);
HAL_NVIC_DisableIRQ(GPU2D_ER_IRQn);
/* USER CODE BEGIN GPU2D_MspDeInit 1 */
/* USER CODE END GPU2D_MspDeInit 1 */
}
}
/**
* @brief I2C MSP Initialization
* This function configures the hardware resources used in this example
* @param hi2c: I2C handle pointer
* @retval None
*/
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1_I3C1;
PeriphClkInit.I2c1_I3c1ClockSelection = RCC_I2C1_I3C1CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
__HAL_RCC_GPIOB_CLK_ENABLE();
/**I2C1 GPIO Configuration
PB9 ------> I2C1_SDA
PB6 ------> I2C1_SCL
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
/**
* @brief I2C MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hi2c: I2C handle pointer
* @retval None
*/
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspDeInit 0 */
/* USER CODE END I2C1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_I2C1_CLK_DISABLE();
/**I2C1 GPIO Configuration
PB9 ------> I2C1_SDA
PB6 ------> I2C1_SCL
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
/* USER CODE BEGIN I2C1_MspDeInit 1 */
/* USER CODE END I2C1_MspDeInit 1 */
}
}
/**
* @brief JPEG MSP Initialization
* This function configures the hardware resources used in this example
* @param hjpeg: JPEG handle pointer
* @retval None
*/
void HAL_JPEG_MspInit(JPEG_HandleTypeDef* hjpeg)
{
DMA_DataHandlingConfTypeDef DataHandlingConfig;
if(hjpeg->Instance==JPEG)
{
/* USER CODE BEGIN JPEG_MspInit 0 */
/* USER CODE END JPEG_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_JPEG_CLK_ENABLE();
/* JPEG DMA Init */
/* HPDMA1_REQUEST_JPEG_TX Init */
handle_HPDMA1_Channel1.Instance = HPDMA1_Channel1;
handle_HPDMA1_Channel1.Init.Request = HPDMA1_REQUEST_JPEG_TX;
handle_HPDMA1_Channel1.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
handle_HPDMA1_Channel1.Init.Direction = DMA_PERIPH_TO_MEMORY;
handle_HPDMA1_Channel1.Init.SrcInc = DMA_SINC_FIXED;
handle_HPDMA1_Channel1.Init.DestInc = DMA_DINC_INCREMENTED;
handle_HPDMA1_Channel1.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
handle_HPDMA1_Channel1.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
handle_HPDMA1_Channel1.Init.Priority = DMA_HIGH_PRIORITY;
handle_HPDMA1_Channel1.Init.SrcBurstLength = 8;
handle_HPDMA1_Channel1.Init.DestBurstLength = 8;
handle_HPDMA1_Channel1.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT1|DMA_DEST_ALLOCATED_PORT0;
handle_HPDMA1_Channel1.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_HPDMA1_Channel1.Init.Mode = DMA_NORMAL;
if (HAL_DMA_Init(&handle_HPDMA1_Channel1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hjpeg, hdmaout, handle_HPDMA1_Channel1);
if (HAL_DMA_ConfigChannelAttributes(&handle_HPDMA1_Channel1, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
/* HPDMA1_REQUEST_JPEG_RX Init */
handle_HPDMA1_Channel0.Instance = HPDMA1_Channel0;
handle_HPDMA1_Channel0.Init.Request = HPDMA1_REQUEST_JPEG_RX;
handle_HPDMA1_Channel0.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
handle_HPDMA1_Channel0.Init.Direction = DMA_MEMORY_TO_PERIPH;
handle_HPDMA1_Channel0.Init.SrcInc = DMA_SINC_INCREMENTED;
handle_HPDMA1_Channel0.Init.DestInc = DMA_DINC_FIXED;
handle_HPDMA1_Channel0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
handle_HPDMA1_Channel0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
handle_HPDMA1_Channel0.Init.Priority = DMA_HIGH_PRIORITY;
handle_HPDMA1_Channel0.Init.SrcBurstLength = 8;
handle_HPDMA1_Channel0.Init.DestBurstLength = 8;
handle_HPDMA1_Channel0.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
handle_HPDMA1_Channel0.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_HPDMA1_Channel0.Init.Mode = DMA_NORMAL;
if (HAL_DMA_Init(&handle_HPDMA1_Channel0) != HAL_OK)
{
Error_Handler();
}
DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
DataHandlingConfig.DataAlignment = DMA_DATA_PACK;
if (HAL_DMAEx_ConfigDataHandling(&handle_HPDMA1_Channel0, &DataHandlingConfig) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hjpeg, hdmain, handle_HPDMA1_Channel0);
if (HAL_DMA_ConfigChannelAttributes(&handle_HPDMA1_Channel0, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
/* JPEG interrupt Init */
HAL_NVIC_SetPriority(JPEG_IRQn, 8, 0);
HAL_NVIC_EnableIRQ(JPEG_IRQn);
/* USER CODE BEGIN JPEG_MspInit 1 */
/* USER CODE END JPEG_MspInit 1 */
}
}
/**
* @brief JPEG MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hjpeg: JPEG handle pointer
* @retval None
*/
void HAL_JPEG_MspDeInit(JPEG_HandleTypeDef* hjpeg)
{
if(hjpeg->Instance==JPEG)
{
/* USER CODE BEGIN JPEG_MspDeInit 0 */
/* USER CODE END JPEG_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_JPEG_CLK_DISABLE();
/* JPEG DMA DeInit */
HAL_DMA_DeInit(hjpeg->hdmaout);
HAL_DMA_DeInit(hjpeg->hdmain);
/* JPEG interrupt DeInit */
HAL_NVIC_DisableIRQ(JPEG_IRQn);
/* USER CODE BEGIN JPEG_MspDeInit 1 */
/* USER CODE END JPEG_MspDeInit 1 */
}
}
/**
* @brief LTDC MSP Initialization
* This function configures the hardware resources used in this example
* @param hltdc: LTDC handle pointer
* @retval None
*/
void HAL_LTDC_MspInit(LTDC_HandleTypeDef* hltdc)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if(hltdc->Instance==LTDC)
{
/* USER CODE BEGIN LTDC_MspInit 0 */
/* USER CODE END LTDC_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLL3R;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_LTDC_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**LTDC GPIO Configuration
PF0 ------> LTDC_R2
PG0 ------> LTDC_R7
PB3(JTDO/TRACESWO) ------> LTDC_R4
PG2 ------> LTDC_HSYNC
PE11 ------> LTDC_VSYNC
PA12 ------> LTDC_B2
PA11 ------> LTDC_B3
PB4(NJTRST) ------> LTDC_R3
PA9 ------> LTDC_B5
PG1 ------> LTDC_R6
PA10 ------> LTDC_B4
PG14 ------> LTDC_B1
PA8 ------> LTDC_B6
PG13 ------> LTDC_CLK
PA15(JTDI) ------> LTDC_R5
PF7 ------> LTDC_G0
PF9 ------> LTDC_R0
PF10 ------> LTDC_R1
PB12 ------> LTDC_G5
PA0 ------> LTDC_G3
PA1 ------> LTDC_G2
PF11 ------> LTDC_B0
PB14 ------> LTDC_DE
PB15 ------> LTDC_G7
PF15 ------> LTDC_G1
PB11 ------> LTDC_G6
PB13 ------> LTDC_G4
PA6 ------> LTDC_B7
*/
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF11_LTDC;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_14
|GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF13_LTDC;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_12|GPIO_PIN_14
|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF13_LTDC;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF11_LTDC;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_8|GPIO_PIN_15
|GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF13_LTDC;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_9|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF13_LTDC;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_15|GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF10_LTDC;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF12_LTDC;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* LTDC interrupt Init */
HAL_NVIC_SetPriority(LTDC_IRQn, 5, 0);
/* USER CODE BEGIN LTDC_MspInit 1 */
/* USER CODE END LTDC_MspInit 1 */
}
}
/**
* @brief LTDC MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hltdc: LTDC handle pointer
* @retval None
*/
void HAL_LTDC_MspDeInit(LTDC_HandleTypeDef* hltdc)
{
if(hltdc->Instance==LTDC)
{
/* USER CODE BEGIN LTDC_MspDeInit 0 */
/* USER CODE END LTDC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_LTDC_CLK_DISABLE();
/**LTDC GPIO Configuration
PF0 ------> LTDC_R2
PG0 ------> LTDC_R7
PB3(JTDO/TRACESWO) ------> LTDC_R4
PG2 ------> LTDC_HSYNC
PE11 ------> LTDC_VSYNC
PA12 ------> LTDC_B2
PA11 ------> LTDC_B3
PB4(NJTRST) ------> LTDC_R3
PA9 ------> LTDC_B5
PG1 ------> LTDC_R6
PA10 ------> LTDC_B4
PG14 ------> LTDC_B1
PA8 ------> LTDC_B6
PG13 ------> LTDC_CLK
PA15(JTDI) ------> LTDC_R5
PF7 ------> LTDC_G0
PF9 ------> LTDC_R0
PF10 ------> LTDC_R1
PB12 ------> LTDC_G5
PA0 ------> LTDC_G3
PA1 ------> LTDC_G2
PF11 ------> LTDC_B0
PB14 ------> LTDC_DE
PB15 ------> LTDC_G7
PF15 ------> LTDC_G1
PB11 ------> LTDC_G6
PB13 ------> LTDC_G4
PA6 ------> LTDC_B7
*/
HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0|GPIO_PIN_7|GPIO_PIN_9|GPIO_PIN_10
|GPIO_PIN_11|GPIO_PIN_15);
HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_14
|GPIO_PIN_13);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_12|GPIO_PIN_14
|GPIO_PIN_15|GPIO_PIN_11|GPIO_PIN_13);
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_11);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_9|GPIO_PIN_10
|GPIO_PIN_8|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1
|GPIO_PIN_6);
/* LTDC interrupt DeInit */
HAL_NVIC_DisableIRQ(LTDC_IRQn);
/* USER CODE BEGIN LTDC_MspDeInit 1 */
/* USER CODE END LTDC_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
@@ -0,0 +1,192 @@
/**
******************************************************************************
* @file stm32h7rsxx_hal_timebase_tim.c
* @author MCD Application Team
* @brief Template for HAL time base based on the peripheral hardware TIM6.
*
* This file override the native HAL time base functions (defined as weak)
* the TIM time base:
* + Initializes the TIM6 peripheral to generate a Period elapsed Event each 1ms
* + HAL_IncTick is called inside HAL_TIM_PeriodElapsedCallback ie each 1ms
*
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "stm32h7rsxx_hal.h"
/** @addtogroup STM32H7RSxx_HAL_Driver
* @{
*/
/** @addtogroup HAL_TimeBase
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define TIM_CNT_FREQ 1000000U /* Timer counter frequency : 1 MHz */
#define TIM_FREQ 1000U /* Timer frequency : 1 kHz => to have 1 ms interrupt */
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim6;
/* Private function prototypes -----------------------------------------------*/
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1U)
void TimeBase_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
/* Private functions ---------------------------------------------------------*/
/**
* @brief This function configures the TIM6 as a time base source.
* The time source is configured to have 1ms time base with a dedicated
* Tick interrupt priority.
* @note This function is called automatically at the beginning of program after
* reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
* @param TickPriority Tick interrupt priority.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
RCC_ClkInitTypeDef clkconfig;
uint32_t uwTimclock;
uint32_t uwAPB1Prescaler;
uint32_t uwPrescalerValue;
uint32_t pFLatency;
HAL_StatusTypeDef Status;
/* Enable TIM6 clock */
__HAL_RCC_TIM6_CLK_ENABLE();
/* Get clock configuration */
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
/* Get APB1 prescaler */
uwAPB1Prescaler = clkconfig.APB1CLKDivider;
/* Compute TIM6 clock */
if (uwAPB1Prescaler == RCC_APB1_DIV1)
{
uwTimclock = HAL_RCC_GetPCLK1Freq();
}
else if (uwAPB1Prescaler == RCC_APB1_DIV2)
{
uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq();
}
else
{
if (__HAL_RCC_GET_TIMCLKPRESCALER() == RCC_TIMPRES_DISABLE)
{
uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq();
}
else
{
uwTimclock = 4UL * HAL_RCC_GetPCLK1Freq();
}
}
/* Compute the prescaler value to have TIM6 counter clock equal to TIM_CNT_FREQ */
uwPrescalerValue = (uint32_t)((uwTimclock / TIM_CNT_FREQ) - 1U);
/* Initialize TIM6 */
htim6.Instance = TIM6;
/* Initialize TIMx peripheral as follow:
+ Period = [uwTickFreq * (TIM_CNT_FREQ/TIM_FREQ) - 1]. to have a (uwTickFreq/TIM_FREQ) s time base.
+ Prescaler = (uwTimclock/TIM_CNT_FREQ - 1) to have a TIM_CNT_FREQ counter clock.
+ ClockDivision = 0
+ Counter direction = Up
*/
htim6.Init.Period = ((uint32_t)uwTickFreq * (TIM_CNT_FREQ / TIM_FREQ)) - 1U;
htim6.Init.Prescaler = uwPrescalerValue;
htim6.Init.ClockDivision = 0;
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
Status = HAL_TIM_Base_Init(&htim6);
if (Status == HAL_OK)
{
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1U)
HAL_TIM_RegisterCallback(&htim6, HAL_TIM_PERIOD_ELAPSED_CB_ID, TimeBase_TIM_PeriodElapsedCallback);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
/* Start the TIM time Base generation in interrupt mode */
Status = HAL_TIM_Base_Start_IT(&htim6);
if (Status == HAL_OK)
{
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
{
/* Configure the TIM6 global Interrupt priority */
HAL_NVIC_SetPriority(TIM6_IRQn, TickPriority, 0);
/* Enable the TIM6 global Interrupt */
HAL_NVIC_EnableIRQ(TIM6_IRQn);
uwTickPrio = TickPriority;
}
else
{
Status = HAL_ERROR;
}
}
}
/* Return function status */
return Status;
}
/**
* @brief Suspend Tick increment.
* @note Disable the tick increment by disabling TIM6 update interrupt.
* @retval None
*/
void HAL_SuspendTick(void)
{
/* Disable TIM6 update interrupt */
__HAL_TIM_DISABLE_IT(&htim6, TIM_IT_UPDATE);
}
/**
* @brief Resume Tick increment.
* @note Enable the tick increment by enabling TIM6 update interrupt.
* @retval None
*/
void HAL_ResumeTick(void)
{
/* Enable TIM6 update interrupt */
__HAL_TIM_ENABLE_IT(&htim6, TIM_IT_UPDATE);
}
/**
* @brief Period elapsed callback in non blocking mode
* @note This function is called when TIM6 interrupt took place, inside
* HAL_TIM6_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
* a global variable "uwTick" used as application time base.
* @param htim TIM handle
* @retval None
*/
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1U)
void TimeBase_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(htim);
HAL_IncTick();
}
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
/**
* @}
*/
/**
* @}
*/
+337
View File
@@ -0,0 +1,337 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32h7rsxx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32h7rsxx_it.h"
#include "stm32h7s78_discovery_audio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern DMA_NodeTypeDef Node_GPDMA1_Channel0;
extern DMA_QListTypeDef List_GPDMA1_Channel0;
extern DMA_HandleTypeDef handle_GPDMA1_Channel0;
extern MDF_HandleTypeDef AdfHandle0;
extern DMA2D_HandleTypeDef hdma2d;
extern GPU2D_HandleTypeDef hgpu2d;
extern DMA_HandleTypeDef handle_HPDMA1_Channel1;
extern DMA_HandleTypeDef handle_HPDMA1_Channel0;
extern JPEG_HandleTypeDef hjpeg;
extern LTDC_HandleTypeDef hltdc;
extern TIM_HandleTypeDef htim6;
extern DMA_HandleTypeDef hDmaI2sTx;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
while (1)
{
}
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
/**
* @brief This function handles Pre-fetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
}
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/******************************************************************************/
/* STM32H7RSxx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32h7rsxx.s). */
/******************************************************************************/
/**
* @brief This function handles EXTI line3 interrupt.
*/
void EXTI3_IRQHandler(void)
{
/* USER CODE BEGIN EXTI3_IRQn 0 */
/* USER CODE END EXTI3_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(TP_IRQ_Pin);
/* USER CODE BEGIN EXTI3_IRQn 1 */
/* USER CODE END EXTI3_IRQn 1 */
}
/**
* @brief This function handles GPDMA1 Channel 0 global interrupt.
*/
void GPDMA1_Channel0_IRQHandler(void)
{
/* USER CODE BEGIN GPDMA1_Channel0_IRQn 0 */
/* USER CODE END GPDMA1_Channel0_IRQn 0 */
HAL_DMA_IRQHandler(&handle_GPDMA1_Channel0);
/* USER CODE BEGIN GPDMA1_Channel0_IRQn 1 */
/* USER CODE END GPDMA1_Channel0_IRQn 1 */
}
void GPDMA1_Channel2_IRQHandler(void)
{
BSP_AUDIO_OUT_IRQHandler(0, AUDIO_OUT_HEADPHONE);
}
/**
* @brief This function handles TIM6 global interrupt.
*/
void TIM6_IRQHandler(void)
{
/* USER CODE BEGIN TIM6_IRQn 0 */
/* USER CODE END TIM6_IRQn 0 */
HAL_TIM_IRQHandler(&htim6);
/* USER CODE BEGIN TIM6_IRQn 1 */
/* USER CODE END TIM6_IRQn 1 */
}
/**
* @brief This function handles HPDMA1 Channel 0 global interrupt.
*/
void HPDMA1_Channel0_IRQHandler(void)
{
/* USER CODE BEGIN HPDMA1_Channel0_IRQn 0 */
/* USER CODE END HPDMA1_Channel0_IRQn 0 */
HAL_DMA_IRQHandler(&handle_HPDMA1_Channel0);
/* USER CODE BEGIN HPDMA1_Channel0_IRQn 1 */
/* USER CODE END HPDMA1_Channel0_IRQn 1 */
}
/**
* @brief This function handles HPDMA1 Channel 1 global interrupt.
*/
void HPDMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN HPDMA1_Channel1_IRQn 0 */
/* USER CODE END HPDMA1_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&handle_HPDMA1_Channel1);
/* USER CODE BEGIN HPDMA1_Channel1_IRQn 1 */
/* USER CODE END HPDMA1_Channel1_IRQn 1 */
}
/**
* @brief This function handles LTDC global interrupt.
*/
void LTDC_IRQHandler(void)
{
/* USER CODE BEGIN LTDC_IRQn 0 */
/* USER CODE END LTDC_IRQn 0 */
HAL_LTDC_IRQHandler(&hltdc);
/* USER CODE BEGIN LTDC_IRQn 1 */
/* USER CODE END LTDC_IRQn 1 */
}
/**
* @brief This function handles DMA2D global interrupt.
*/
void DMA2D_IRQHandler(void)
{
/* USER CODE BEGIN DMA2D_IRQn 0 */
/* USER CODE END DMA2D_IRQn 0 */
HAL_DMA2D_IRQHandler(&hdma2d);
/* USER CODE BEGIN DMA2D_IRQn 1 */
/* USER CODE END DMA2D_IRQn 1 */
}
/**
* @brief This function handles JPEG global interrupt.
*/
void JPEG_IRQHandler(void)
{
/* USER CODE BEGIN JPEG_IRQn 0 */
/* USER CODE END JPEG_IRQn 0 */
HAL_JPEG_IRQHandler(&hjpeg);
/* USER CODE BEGIN JPEG_IRQn 1 */
/* USER CODE END JPEG_IRQn 1 */
}
/**
* @brief This function handles ADF1 Filter 0 global Interrupt.
*/
void ADF1_FLT0_IRQHandler(void)
{
/* USER CODE BEGIN ADF1_FLT0_IRQn 0 */
/* USER CODE END ADF1_FLT0_IRQn 0 */
HAL_MDF_IRQHandler(&AdfHandle0);
/* USER CODE BEGIN ADF1_FLT0_IRQn 1 */
/* USER CODE END ADF1_FLT0_IRQn 1 */
}
/**
* @brief This function handles GPU2D global interrupt.
*/
void GPU2D_IRQHandler(void)
{
/* USER CODE BEGIN GPU2D_IRQn 0 */
/* USER CODE END GPU2D_IRQn 0 */
HAL_GPU2D_IRQHandler(&hgpu2d);
/* USER CODE BEGIN GPU2D_IRQn 1 */
/* USER CODE END GPU2D_IRQn 1 */
}
/**
* @brief This function handles GPU2D Error interrupt.
*/
void GPU2D_ER_IRQHandler(void)
{
/* USER CODE BEGIN GPU2D_ER_IRQn 0 */
/* USER CODE END GPU2D_ER_IRQn 0 */
HAL_GPU2D_ER_IRQHandler(&hgpu2d);
/* USER CODE BEGIN GPU2D_ER_IRQn 1 */
/* USER CODE END GPU2D_ER_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
+304
View File
@@ -0,0 +1,304 @@
/**
******************************************************************************
* @file system_stm32h7rsxx.c
* @author MCD Application Team
* @brief CMSIS Cortex-M7 Device Peripheral Access Layer System Source File
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32h7rsxx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (sys_cpu_ck), it can
* be used by the user application to setup the
* SysTick timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* After each device reset the HSI (64 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32h7rsxx.s" file, to
* optionally configure the system clock before to branch to main program.
*
*=============================================================================
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup STM32H7RSxx_System
* @{
*/
/** @addtogroup STM32H7RSxx_System_Private_Includes
* @{
*/
#include "stm32h7rsxx.h"
#include <math.h>
/**
* @}
*/
/** @addtogroup STM32H7RSxx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32H7RSxx_System_Private_Defines
* @{
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE 24000000UL /*!< Value of the High-Speed External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE 64000000UL /*!< Value of the High-Speed Internal oscillator in Hz */
#endif /* HSI_VALUE */
#if !defined (CSI_VALUE)
#define CSI_VALUE 4000000UL /*!< Value of the Low-power Internal oscillator in Hz */
#endif /* CSI_VALUE */
/* Note: Following vector table addresses must be defined in line with linker
configuration. */
/*!< Uncomment the following line or define USER_VECT_TAB_ADDRESS at compiler level if you need
to relocate the vector table anywhere in Flash or Sram, else the vector table is kept at
the automatic remap of the selected boot address */
/* #define USER_VECT_TAB_ADDRESS */
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line or define VECT_TAB_SRAM at compiler level if you need
to relocate your vector Table in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#if !defined(VECT_TAB_BASE_ADDRESS)
#define VECT_TAB_BASE_ADDRESS ITCM_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x400. */
#endif
#if !defined(VECT_TAB_OFFSET)
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x400. */
#endif
#else
#if !defined(VECT_TAB_BASE_ADDRESS)
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x400. */
#endif
#if !defined(VECT_TAB_OFFSET)
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x400. */
#endif
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
/******************************************************************************/
/**
* @}
*/
/** @addtogroup STM32H7RSxx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32H7RSxx_System_Private_Variables
* @{
*/
/* The SystemCoreClock variable is updated in two ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the first function listed above, since SystemCoreClock
variable is updated automatically.
*/
uint32_t SystemCoreClock = HSI_VALUE;
/**
* @}
*/
/** @addtogroup STM32H7RSxx_System_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32H7RSxx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system.
* @retval None
*/
void SystemInit(void)
{
/* Configure the Vector Table location -------------------------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET;
#endif
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
#endif
}
/**
* @brief Update SystemCoreClock variable according to RCC registers values.
* The SystemCoreClock variable contains the core clock (sys_cpu_ck), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
*
* - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(**)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSI_VALUE(*)
* or CSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
*
* (*) HSI_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value
* 64 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) CSI_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value
* 4 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (***) HSE_VALUE is a constant defined in stm32h7rsxx_hal.h file (default value
* 24 MHz), user has to ensure that HSE_VALUE is same as the real
* frequency of the crystal used. Otherwise, this function may
* have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
* @retval None
*/
void SystemCoreClockUpdate(void)
{
uint32_t sysclk, hsivalue, pllsource, pllm, pllp, core_presc;
float_t pllfracn, pllvco;
/* Get SYSCLK source -------------------------------------------------------*/
switch (RCC->CFGR & RCC_CFGR_SWS)
{
case 0x00: /* HSI used as system clock source (default after reset) */
sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
break;
case 0x08: /* CSI used as system clock source */
sysclk = CSI_VALUE;
break;
case 0x10: /* HSE used as system clock source */
sysclk = HSE_VALUE;
break;
case 0x18: /* PLL1 used as system clock source */
/* PLL1_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
SYSCLK = PLL1_VCO / PLL1R
*/
pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos) ;
if ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN) != 0U)
{
pllfracn = (float_t)(uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN)>> RCC_PLL1FRACR_FRACN_Pos));
}
else
{
pllfracn = (float_t)0U;
}
if (pllm != 0U)
{
switch (pllsource)
{
case 0x02: /* HSE used as PLL1 clock source */
pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 );
break;
case 0x01: /* CSI used as PLL1 clock source */
pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 );
break;
case 0x00: /* HSI used as PLL1 clock source */
default:
hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (pllfracn/(float_t)0x2000) +(float_t)1 );
break;
}
pllp = (((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1U ) ;
sysclk = (uint32_t)(float_t)(pllvco/(float_t)pllp);
}
else
{
sysclk = 0U;
}
break;
default: /* Unexpected, default to HSI used as system clock source (default after reset) */
sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
break;
}
/* system clock frequency : CM7 CPU frequency */
core_presc = (RCC->CDCFGR & RCC_CDCFGR_CPRE);
if (core_presc >= 8U)
{
SystemCoreClock = (sysclk >> (core_presc - RCC_CDCFGR_CPRE_3 + 1U));
}
else
{
SystemCoreClock = sysclk;
}
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
BIN
View File
Binary file not shown.
+90
View File
@@ -0,0 +1,90 @@
/**
******************************************************************************
* File Name : app_touchgfx.c
******************************************************************************
* This file was created by TouchGFX Generator 4.26.1. This file is only
* generated once! Delete this file from your project and re-generate code
* using STM32CubeMX or change this file manually to update it.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "app_touchgfx.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void touchgfx_init(void);
void touchgfx_components_init(void);
void touchgfx_taskEntry(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/**
* PreOS Initialization function
*/
void MX_TouchGFX_PreOSInit(void)
{
}
/**
* Initialize TouchGFX application
*/
void MX_TouchGFX_Init(void)
{
// Calling forward to touchgfx_init in C++ domain
touchgfx_components_init();
touchgfx_init();
}
/**
* TouchGFX application entry function
*/
void MX_TouchGFX_Process(void)
{
// Calling forward to touchgfx_taskEntry in C++ domain
touchgfx_taskEntry();
}
/**
* TouchGFX application thread
*/
void TouchGFX_Task(void* argument)
{
// Calling forward to touchgfx_taskEntry in C++ domain
touchgfx_taskEntry();
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+60
View File
@@ -0,0 +1,60 @@
/**
******************************************************************************
* File Name : app_touchgfx.h
******************************************************************************
* This file was created by TouchGFX Generator 4.26.1. This file is only
* generated once! Delete this file from your project and re-generate code
* using STM32CubeMX or change this file manually to update it.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef APP_TOUCHGFX_H
#define APP_TOUCHGFX_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void MX_TouchGFX_PreOSInit(void);
void MX_TouchGFX_Init(void);
void MX_TouchGFX_Process(void);
void TouchGFX_Task(void* argument);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
#ifdef __cplusplus
}
#endif
#endif /* APP_TOUCHGFX_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,34 @@
{
"Application": {
"Name": "STM32H7S78-DK",
"TouchGfxPath": "../Middlewares/ST/touchgfx",
"AvailableColorDepths": [ 16 ],
"AvailableLCDs":
{
"16": "LCDGPU2D"
},
"AvailableResolutions": [
{
"Width": 800,
"Height": 480
}
],
"PostGenerateTargetCommand": "touchgfx update_project",
"Family": "STM32H7",
"SubFamily": "STM32H7R7/7S7",
"Platform": "m7",
"Toolchain": "STM32CubeIDE",
"ProjectFile": "../../STM32H7S78-DK.ioc",
"OptionalComponentsRoot": "../Middlewares/ST/touchgfx_components",
"OptionalComponents": [
"GPU2D"
],
"AdditionalFeatures": [
"GPU2DVector",
"VectorFonts",
"Video"
]
},
"Version": "4.26.1"
}
+193
View File
@@ -0,0 +1,193 @@
{
"Application": {
"Screens": [
{
"Name": "InitScreen",
"Components": [
{
"Type": "Image",
"Name": "image1",
"Width": 800,
"Height": 480,
"RelativeFilename": "__generated\\alternate_theme_images_backgrounds_800x480_meteor_rain.png"
},
{
"Type": "ButtonWithIcon",
"Name": "buttonWithIcon1",
"X": 280,
"Y": 215,
"Width": 240,
"Height": 50,
"Pressed": "__generated\\alternate_theme_images_widgets_button_regular_height_50_medium_rounded_pressed.png",
"Released": "__generated\\alternate_theme_images_widgets_button_regular_height_50_medium_rounded_normal.png",
"IconPressed": "__generated\\icon_theme_images_action_done_50_50_E8F6FB.svg.png",
"IconReleased": "__generated\\icon_theme_images_action_input_50_50_E8F6FB.svg.png",
"IconX": 97,
"IconHeight": 50,
"IconWidth": 50,
"Preset": "alternate_theme\\presets\\button\\regular\\height_50\\medium_rounded_normal.json"
}
],
"Interactions": [
{
"InteractionName": "Interaction1",
"Trigger": {
"Type": "TriggerClicked",
"TriggerComponent": "buttonWithIcon1"
},
"Action": {
"Type": "ActionGotoScreen",
"ScreenTransitionType": "ScreenTransitionBlock",
"ActionComponent": "Screen1"
}
}
],
"CustomActions": [
{
"Name": "changeScreen"
}
]
},
{
"Name": "Screen1",
"Components": [
{
"Type": "Image",
"Name": "image1",
"Width": 800,
"Height": 480,
"RelativeFilename": "__generated\\glass_theme_images_backgrounds_800x480_gradient_rainbow.png"
},
{
"Type": "Slider",
"Name": "slider1",
"X": 360,
"Y": 224,
"Width": 300,
"Height": 11,
"IsHorizontalSlider": true,
"BackgroundUnselected": "__generated\\alternate_theme_images_widgets_slider_horizontal_thick_track_medium.png",
"BackgroundSelected": "__generated\\alternate_theme_images_widgets_slider_horizontal_thick_filler_medium.png",
"Indicator": "__generated\\alternate_theme_images_widgets_slider_horizontal_thick_rounded_dark.png",
"BackgroundX": 16,
"BackgroundY": 11,
"IndicatorMax": 300,
"ValueMax": 100,
"Preset": "alternate_theme\\presets\\slider\\horizontal\\thick\\medium_rounded_dark.json"
},
{
"Type": "Gauge",
"Name": "gauge1",
"X": 41,
"Y": 104,
"Width": 240,
"Height": 240,
"Preset": "alternate_theme\\presets\\gauges\\medium\\active.json",
"FileNameBackground": "__generated\\alternate_theme_images_widgets_gauge_medium_backgrounds_active.png",
"RotationCenterX": 120.0,
"RotationCenterY": 120.0,
"StartAngle": -113.0,
"EndAngle": 112.0,
"RangeMax": 100.0,
"InitialValue": 50.0,
"UseAnimation": true,
"Easing": "Linear",
"EasingOption": "In",
"FileNameNeedle": "__generated\\alternate_theme_images_widgets_gauge_medium_needles_smooth.png",
"NeedleRotationCenterX": 7.0,
"NeedleRotationCenterY": 67.0,
"NeedleMovingRenderingAlgorithm": "Bilinear Interpolation",
"NeedleSteadyRenderingAlgorithm": "Bilinear Interpolation",
"ArcColor": {
"Red": 20,
"Green": 151,
"Blue": 197
},
"ArcCapStyle": "Butt"
}
],
"Interactions": [
{
"InteractionName": "InteractionSlider1",
"HasCompletedTrigger": true,
"Trigger": {
"Type": "TriggerSliderValueChanged",
"TriggerComponent": "slider1"
},
"Action": {
"Type": "ActionCustom",
"FunctionName": "slider1Clicked"
}
}
],
"CustomActions": [
{
"Name": "Volume",
"HasValue": true,
"ValueType": "int16_t"
}
]
}
],
"CustomContainerDefinitions": [],
"Name": "CelloEffects",
"Resolution": {
"Width": 800,
"Height": 480
},
"SelectedColorDepth": 16,
"StartupScreenName": "InitScreen",
"SelectedStartupLanguage": "GB",
"TouchGfxPath": "../Middlewares/ST/touchgfx",
"UIPath": ".",
"AvailableColorDepths": [
16
],
"AvailableLCDs": {
"16": "LCDGPU2D"
},
"AvailableSections": [
"ExtFlashSection",
"IntFlashSection"
],
"AvailableResolutions": [
{
"Width": 800,
"Height": 480
}
],
"PhysicalButtons": [],
"GenerateAssetsCommand": "make -f simulator/gcc/Makefile assets -j8",
"GenerateAssetsCommandOverride": "make -f simulator/gcc/Makefile assets -j8",
"PostGenerateCommand": "touchgfx update_project --project-file=simulator/msvs/Application.vcxproj",
"PostGenerateCommandOverride": "touchgfx update_project --project-file=simulator/msvs/Application.vcxproj",
"PostGenerateTargetCommand": "touchgfx update_project",
"CompileSimulatorCommand": "make -f simulator/gcc/Makefile -j8",
"CompileSimulatorCommandOverride": "make -f simulator/gcc/Makefile -j1",
"RunSimulatorCommand": "build\\bin\\simulator.exe",
"CompileTargetCommandOverride": "make -f gcc/Makefile -j8",
"FlashTargetCommandOverride": "make -f gcc/Makefile flash",
"FlashTargetIntCommandOverride": "make -f gcc/Makefile intflash",
"LandscapeSkinX": 0,
"LandscapeSkinY": 0,
"PortraitSkinX": 0,
"PortraitSkinY": 0,
"DisplayOrientation": "Landscape",
"Family": "STM32H7",
"SubFamily": "STM32H7R7/7S7",
"Toolchain": "STM32CubeIDE",
"Platform": "m7",
"ProjectFile": "../../STM32H7S78-DK.ioc",
"OptionalComponentsRoot": "../Middlewares/ST/touchgfx_components",
"OptionalComponents": [
"GPU2D"
],
"AdditionalFeatures": [
"GPU2DVector",
"VectorFonts",
"Video"
]
},
"Version": "4.26.1",
"CreatedBy": "4.26.1"
}
+68
View File
@@ -0,0 +1,68 @@
{
"Application": {
"Screens": [
{
"Name": "Screen1",
"Components": [],
"Interactions": []
}
],
"CustomContainerDefinitions": [],
"Name": "CelloEffects",
"Resolution": {
"Width": 800,
"Height": 480
},
"SelectedColorDepth": 16,
"StartupScreenName": "Screen1",
"SelectedStartupLanguage": "GB",
"TouchGfxPath": "../Middlewares/ST/touchgfx",
"UIPath": ".",
"AvailableColorDepths": [
16
],
"AvailableLCDs": {
"16": "LCDGPU2D"
},
"AvailableSections": [
"ExtFlashSection",
"IntFlashSection"
],
"AvailableResolutions": [
{
"Width": 800,
"Height": 480
}
],
"PhysicalButtons": [],
"GenerateAssetsCommand": "make -f simulator/gcc/Makefile assets -j8",
"PostGenerateCommand": "touchgfx update_project --project-file=simulator/msvs/Application.vcxproj",
"PostGenerateTargetCommand": "touchgfx update_project",
"CompileSimulatorCommand": "make -f simulator/gcc/Makefile -j8",
"RunSimulatorCommand": "build\\bin\\simulator.exe",
"CompileTargetCommandOverride": "make -f ../../gcc/Makefile -j8",
"FlashTargetCommandOverride": "make -f ../../gcc/Makefile flash",
"FlashTargetIntCommandOverride": "make -f ../../gcc/Makefile intflash",
"LandscapeSkinX": 0,
"LandscapeSkinY": 0,
"PortraitSkinX": 0,
"PortraitSkinY": 0,
"DisplayOrientation": "Landscape",
"Family": "STM32H7",
"SubFamily": "STM32H7R7/7S7",
"Toolchain": "STM32CubeIDE",
"Platform": "m7",
"ProjectFile": "../../STM32H7S78-DK.ioc",
"OptionalComponentsRoot": "../Middlewares/ST/touchgfx_components",
"OptionalComponents": [
"GPU2D"
],
"AdditionalFeatures": [
"GPU2DVector",
"VectorFonts",
"Video"
]
},
"Version": "4.26.1",
"CreatedBy": "4.26.1"
}
+24
View File
@@ -0,0 +1,24 @@
{
"image_configuration": {
"dither_algorithm": "2",
"alpha_dither": "yes",
"layout_rotation": "0",
"opaque_image_format": "RGB565",
"nonopaque_image_format": "ARGB8888",
"l8_compression": "no",
"section": "ExtFlashSection",
"extra_section": "ExtFlashSection",
"images": {},
"rgb_compression": "no"
},
"text_configuration": {
"remap": "yes",
"a4": "yes",
"binary_translations": "no",
"binary_fonts": "no",
"framebuffer_bpp": "16",
"font_format": "0",
"cache_size": 4096,
"copy_translations_to_ram": "no"
}
}
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B

+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<TextDatabase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="texts.xsd" Version="4.26.1">
<Languages>
<Language Id="GB" />
</Languages>
<Texts>
<TextGroup Id="Group1" />
</Texts>
<Typographies>
<Typography Id="Default" Font="arial.ttf" Size="20" Bpp="4" IsVector="no" Direction="LTR" FallbackCharacter="?" />
<Typography Id="Large" Font="arial.ttf" Size="40" Bpp="4" IsVector="no" Direction="LTR" FallbackCharacter="?" />
<Typography Id="Small" Font="arial.ttf" Size="10" Bpp="4" IsVector="no" Direction="LTR" FallbackCharacter="?" />
</Typographies>
</TextDatabase>
+168
View File
@@ -0,0 +1,168 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!--Types-->
<xs:simpleType name="direction" final="restriction" >
<xs:restriction base="xs:string">
<xs:enumeration value="LTR" />
<xs:enumeration value="RTL" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="alignment" final="restriction" >
<xs:restriction base="xs:string">
<xs:enumeration value="Left" />
<xs:enumeration value="LEFT" />
<xs:enumeration value="left" />
<xs:enumeration value="Center" />
<xs:enumeration value="CENTER" />
<xs:enumeration value="center" />
<xs:enumeration value="Right" />
<xs:enumeration value="RIGHT" />
<xs:enumeration value="right" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="bpp" final="restriction" >
<xs:restriction base="xs:string">
<xs:enumeration value="1" />
<xs:enumeration value="2" />
<xs:enumeration value="4" />
<xs:enumeration value="8" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="fallbackCharacter" final="restriction" >
<xs:restriction base="xs:string">
<xs:pattern value="|.|skip|(0[xX][0-9a-fA-F]{1,4})" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ellipsisCharacter" final="restriction" >
<xs:restriction base="xs:string">
<xs:pattern value="|.|(0[xX][0-9a-fA-F]{1,4})" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="wildcardCharacterRanges" final="restriction" >
<xs:restriction base="xs:string">
<xs:pattern value="|(.-.|(0[xX][0-9a-fA-F]{1,4}|[0-9]{1,5})(-(0[xX][0-9a-fA-F]{1,4}|[0-9]{1,5}))?)(,(.-.|(0[xX][0-9a-fA-F]{1,4}|[0-9]{1,5})(-(0[xX][0-9a-fA-F]{1,4}|[0-9]{1,5}))?))*" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="validCppIdentifier" final="restriction" >
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z_][a-zA-Z0-9_]*" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="validIdentifier" final="restriction" >
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z0-9_]+" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="fontSize" final="restriction">
<xs:restriction base="xs:unsignedInt">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="1000"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="isVector" final="restriction" >
<xs:restriction base="xs:string">
<xs:enumeration value="yes" />
<xs:enumeration value="no" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="isCompressed" final="restriction" >
<xs:restriction base="xs:string">
<xs:enumeration value="yes" />
<xs:enumeration value="no" />
</xs:restriction>
</xs:simpleType>
<!--TextDatabase specification-->
<xs:element name="TextDatabase">
<xs:complexType>
<xs:sequence>
<xs:element name="Languages">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Language">
<xs:complexType>
<xs:attribute name="Id" type="validCppIdentifier" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:sequence>
<xs:element name="Texts">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="TextGroup">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Text">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="unbounded" name="Translation">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Language" type="validCppIdentifier" use="required" />
<xs:attribute name="Alignment" type="alignment" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="validIdentifier" use="required" />
<xs:attribute name="Alignment" type="alignment" use="required" />
<xs:attribute name="TypographyId" type="validCppIdentifier" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="validIdentifier" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:element name="Typographies">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Typography">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="LanguageSetting">
<xs:complexType>
<xs:attribute name="Language" type="validCppIdentifier" use="required" />
<xs:attribute name="Font" type="xs:string" use="required" />
<xs:attribute name="Size" type="fontSize" use="required" />
<xs:attribute name="Bpp" type="bpp" use="required" />
<xs:attribute name="IsVector" type="isVector" use="required" />
<xs:attribute name="Direction" type="direction" use="required" />
<xs:attribute name="IsCompressed" type="isCompressed" use="optional" />
<xs:attribute name="FallbackCharacter" type="fallbackCharacter" use="optional" />
<xs:attribute name="WildcardCharacters" type="xs:string" use="optional" />
<xs:attribute name="WidgetWildcardCharacters" type="xs:string" use="optional" />
<xs:attribute name="WildcardCharacterRanges" type="wildcardCharacterRanges" use="optional" />
<xs:attribute name="EllipsisCharacter" type="ellipsisCharacter" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="validCppIdentifier" use="required" />
<xs:attribute name="Font" type="xs:string" use="required" />
<xs:attribute name="Size" type="fontSize" use="required" />
<xs:attribute name="Bpp" type="bpp" use="required" />
<xs:attribute name="IsVector" type="isVector" use="required" />
<xs:attribute name="Direction" type="direction" use="required" />
<xs:attribute name="IsCompressed" type="isCompressed" use="optional" />
<xs:attribute name="FallbackCharacter" type="fallbackCharacter" use="optional" />
<xs:attribute name="WildcardCharacters" type="xs:string" use="optional" />
<xs:attribute name="WidgetWildcardCharacters" type="xs:string" use="optional" />
<xs:attribute name="WildcardCharacterRanges" type="wildcardCharacterRanges" use="optional" />
<xs:attribute name="EllipsisCharacter" type="ellipsisCharacter" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Version" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>
@@ -0,0 +1,24 @@
#ifndef FRONTENDAPPLICATION_HPP
#define FRONTENDAPPLICATION_HPP
#include <gui_generated/common/FrontendApplicationBase.hpp>
class FrontendHeap;
using namespace touchgfx;
class FrontendApplication : public FrontendApplicationBase
{
public:
FrontendApplication(Model& m, FrontendHeap& heap);
virtual ~FrontendApplication() { }
virtual void handleTickEvent()
{
model.tick();
FrontendApplicationBase::handleTickEvent();
}
private:
};
#endif // FRONTENDAPPLICATION_HPP
@@ -0,0 +1,74 @@
#ifndef FRONTENDHEAP_HPP
#define FRONTENDHEAP_HPP
#include <gui_generated/common/FrontendHeapBase.hpp>
class FrontendHeap : public FrontendHeapBase
{
public:
/* List any user-defined view types here*/
typedef touchgfx::meta::TypeList< touchgfx::meta::Nil, //Replace this with first user-defined type
touchgfx::meta::Nil //List must always end with meta::Nil !
> UserDefinedViewTypes;
/* List any user-defined presenter types here*/
typedef touchgfx::meta::TypeList< touchgfx::meta::Nil, //Replace this with first user-defined type
touchgfx::meta::Nil //List must always end with meta::Nil !
> UserDefinedPresenterTypes;
/* List any user-defined transition types here*/
typedef touchgfx::meta::TypeList< touchgfx::meta::Nil, //Replace this with first user-defined type
touchgfx::meta::Nil //List must always end with meta::Nil !
> UserDefinedTransitionTypes;
/* Calculate largest view, both from generated and user-defined typelists */
typedef touchgfx::meta::select_type_maxsize< UserDefinedViewTypes >::type MaxUserViewType;
typedef touchgfx::meta::TypeList< MaxGeneratedViewType,
touchgfx::meta::TypeList< MaxUserViewType,
touchgfx::meta::Nil
> > CombinedViewTypes;
typedef touchgfx::meta::select_type_maxsize< CombinedViewTypes >::type MaxViewType;
/* Calculate largest presenter, both from generated and user-defined typelists */
typedef touchgfx::meta::select_type_maxsize< UserDefinedPresenterTypes >::type MaxUserPresenterType;
typedef touchgfx::meta::TypeList< MaxGeneratedPresenterType,
touchgfx::meta::TypeList< MaxUserPresenterType,
touchgfx::meta::Nil
> > CombinedPresenterTypes;
typedef touchgfx::meta::select_type_maxsize< CombinedPresenterTypes >::type MaxPresenterType;
/* Calculate largest transition, both from generated and user-defined typelists */
typedef touchgfx::meta::select_type_maxsize< UserDefinedTransitionTypes >::type MaxUserTransitionType;
typedef touchgfx::meta::TypeList< MaxGeneratedTransitionType,
touchgfx::meta::TypeList< MaxUserTransitionType,
touchgfx::meta::Nil
> > CombinedTransitionTypes;
typedef touchgfx::meta::select_type_maxsize< CombinedTransitionTypes >::type MaxTransitionType;
static FrontendHeap& getInstance()
{
static FrontendHeap instance;
return instance;
}
touchgfx::Partition< CombinedPresenterTypes, 1 > presenters;
touchgfx::Partition< CombinedViewTypes, 1 > views;
touchgfx::Partition< CombinedTransitionTypes, 1 > transitions;
Model model;
FrontendApplication app;
private:
FrontendHeap() : FrontendHeapBase(presenters, views, transitions, app),
app(model, *this)
{
gotoStartScreen(app);
}
};
#endif // FRONTENDHEAP_HPP
@@ -0,0 +1,36 @@
#ifndef INITSCREENPRESENTER_HPP
#define INITSCREENPRESENTER_HPP
#include <gui/model/ModelListener.hpp>
#include <mvp/Presenter.hpp>
using namespace touchgfx;
class InitScreenView;
class InitScreenPresenter : public touchgfx::Presenter, public ModelListener
{
public:
InitScreenPresenter(InitScreenView& v);
/**
* The activate function is called automatically when this screen is "switched in"
* (ie. made active). Initialization logic can be placed here.
*/
virtual void activate();
/**
* The deactivate function is called automatically when this screen is "switched out"
* (ie. made inactive). Teardown functionality can be placed here.
*/
virtual void deactivate();
virtual ~InitScreenPresenter() {}
private:
InitScreenPresenter();
InitScreenView& view;
};
#endif // INITSCREENPRESENTER_HPP
@@ -0,0 +1,17 @@
#ifndef INITSCREENVIEW_HPP
#define INITSCREENVIEW_HPP
#include <gui_generated/initscreen_screen/InitScreenViewBase.hpp>
#include <gui/initscreen_screen/InitScreenPresenter.hpp>
class InitScreenView : public InitScreenViewBase
{
public:
InitScreenView();
virtual ~InitScreenView() {}
virtual void setupScreen();
virtual void tearDownScreen();
protected:
};
#endif // INITSCREENVIEW_HPP
@@ -0,0 +1,21 @@
#ifndef MODEL_HPP
#define MODEL_HPP
class ModelListener;
class Model
{
public:
Model();
void bind(ModelListener* listener)
{
modelListener = listener;
}
void tick();
protected:
ModelListener* modelListener;
};
#endif // MODEL_HPP
@@ -0,0 +1,21 @@
#ifndef MODELLISTENER_HPP
#define MODELLISTENER_HPP
#include <gui/model/Model.hpp>
class ModelListener
{
public:
ModelListener() : model(0) {}
virtual ~ModelListener() {}
void bind(Model* m)
{
model = m;
}
protected:
Model* model;
};
#endif // MODELLISTENER_HPP
@@ -0,0 +1,36 @@
#ifndef SCREEN1PRESENTER_HPP
#define SCREEN1PRESENTER_HPP
#include <gui/model/ModelListener.hpp>
#include <mvp/Presenter.hpp>
using namespace touchgfx;
class Screen1View;
class Screen1Presenter : public touchgfx::Presenter, public ModelListener
{
public:
Screen1Presenter(Screen1View& v);
/**
* The activate function is called automatically when this screen is "switched in"
* (ie. made active). Initialization logic can be placed here.
*/
virtual void activate();
/**
* The deactivate function is called automatically when this screen is "switched out"
* (ie. made inactive). Teardown functionality can be placed here.
*/
virtual void deactivate();
virtual ~Screen1Presenter() {}
private:
Screen1Presenter();
Screen1View& view;
};
#endif // SCREEN1PRESENTER_HPP
@@ -0,0 +1,18 @@
#ifndef SCREEN1VIEW_HPP
#define SCREEN1VIEW_HPP
#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>
class Screen1View : public Screen1ViewBase
{
public:
Screen1View();
virtual ~Screen1View() {}
virtual void setupScreen();
virtual void tearDownScreen();
virtual void slider1Clicked(int value);
protected:
};
#endif // SCREEN1VIEW_HPP
@@ -0,0 +1,7 @@
#include <gui/common/FrontendApplication.hpp>
FrontendApplication::FrontendApplication(Model& m, FrontendHeap& heap)
: FrontendApplicationBase(m, heap)
{
}
@@ -0,0 +1,18 @@
#include <gui/initscreen_screen/InitScreenView.hpp>
#include <gui/initscreen_screen/InitScreenPresenter.hpp>
InitScreenPresenter::InitScreenPresenter(InitScreenView& v)
: view(v)
{
}
void InitScreenPresenter::activate()
{
}
void InitScreenPresenter::deactivate()
{
}
@@ -0,0 +1,16 @@
#include <gui/initscreen_screen/InitScreenView.hpp>
InitScreenView::InitScreenView()
{
}
void InitScreenView::setupScreen()
{
InitScreenViewBase::setupScreen();
}
void InitScreenView::tearDownScreen()
{
InitScreenViewBase::tearDownScreen();
}
+12
View File
@@ -0,0 +1,12 @@
#include <gui/model/Model.hpp>
#include <gui/model/ModelListener.hpp>
Model::Model() : modelListener(0)
{
}
void Model::tick()
{
}
@@ -0,0 +1,18 @@
#include <gui/screen1_screen/Screen1View.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>
Screen1Presenter::Screen1Presenter(Screen1View& v)
: view(v)
{
}
void Screen1Presenter::activate()
{
}
void Screen1Presenter::deactivate()
{
}
@@ -0,0 +1,20 @@
#include <gui/screen1_screen/Screen1View.hpp>
Screen1View::Screen1View()
{
}
void Screen1View::setupScreen()
{
Screen1ViewBase::setupScreen();
}
void Screen1View::tearDownScreen()
{
Screen1ViewBase::tearDownScreen();
}
void Screen1View::slider1Clicked(int value)
{
gauge1.setValue(value);
}
@@ -0,0 +1,48 @@
#include <CortexMMCUInstrumentation.hpp>
#include <touchgfx/hal/HAL.hpp>
namespace touchgfx
{
void CortexMMCUInstrumentation::init()
{
// See: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/CEGHJDCF.html
//
// [24] Read/write TRCENA This bit must be set to 1 to enable use of the trace and debug blocks:
// Data Watchpoint and Trace (DWT)
// Instrumentation Trace Macrocell (ITM)
// Embedded Trace Macrocell (ETM)
// Trace Port Interface Unit (TPIU).
// This enables control of power usage unless tracing is required. The application can enable this, for ITM use, or use by a debugger.
// Enable Debug Exception and Monitor Control Register
*((volatile unsigned int*)0xE000EDFC) |= 0x01000000;
// Enable Lock Access Register
*((volatile unsigned int*)0xE0001FB0) |= 0xC5ACCE55;
// Enable Data Watchpoint and Trace Control Register
*((volatile unsigned int*)0xE0001000) |= 1;
}
//Board specific clockfrequency
unsigned int CortexMMCUInstrumentation::getElapsedUS(unsigned int start, unsigned int now, unsigned int clockfrequency)
{
return ((now - start) + (clockfrequency / 2)) / clockfrequency;
}
unsigned int CortexMMCUInstrumentation::getCPUCycles()
{
return *((volatile unsigned int*)0xE0001004);
}
void CortexMMCUInstrumentation::setMCUActive(bool active)
{
if (active) //idle task sched out
{
uint32_t cc_temp = getCPUCycles() - cc_in;
cc_consumed += cc_temp;
}
else //idle task sched in
{
cc_in = getCPUCycles();
}
}
}
@@ -0,0 +1,74 @@
#ifndef CORTEXMMCUINSTRUMENTATION_HPP
#define CORTEXMMCUINSTRUMENTATION_HPP
#include <platform/core/MCUInstrumentation.hpp>
#include <stdint.h>
namespace touchgfx
{
/**
* @class CortexMMCUInstrumentation CortexMMCUInstrumentation.hpp platform/core/arm/cortex-m/CortexMMCUInstrumentation.hpp
*
* @brief Interface for instrumenting Cortex-M processors to measure MCU load via measured CPU
* cycles.
*
* Interface for instrumenting Cortex-M processors to measure MCU load via measured CPU
* cycles.
*
* @sa MCUInstrumentation
*/
class CortexMMCUInstrumentation : public MCUInstrumentation
{
public:
/**
* @fn virtual void CortexMMCUInstrumentation::init();
*
* @brief Initialization.
*
* Initialization.
*/
virtual void init();
/**
* @fn virtual unsigned int CortexMMCUInstrumentation::getElapsedUS(unsigned int start, unsigned int now, unsigned int clockfrequency);
*
* @brief Gets elapsed microseconds basedon clockfrequency.
*
* Gets elapsed microseconds basedon clockfrequency.
*
* @param start Start time.
* @param now Current time.
* @param clockfrequency Clock frequency of the system.
*
* @return Elapsed microseconds start and now.
*/
virtual unsigned int getElapsedUS(unsigned int start, unsigned int now, unsigned int clockfrequency);
/**
* @fn virtual unsigned int CortexMMCUInstrumentation::getCPUCycles();
*
* @brief Gets CPU cycles from register.
*
* Gets CPU cycles from register.
*
* @return CPU cycles.
*/
virtual unsigned int getCPUCycles();
/**
* @fn virtual void CortexMMCUInstrumentation::setMCUActive(bool active);
*
* @brief Register if MCU is active by measuring cpu cycles.
*
* Register if MCU is active by measuring cpu cycles. If user wishes to track
* MCU load, this method should be called whenever the OS Idle task is scheduled
* in or out. This method makes calls to a concrete implementation of GPIO
* functionality and a concrete implementation of cpu cycles.
*
* @param active If true, MCU is registered as being active, inactive otherwise.
*/
virtual void setMCUActive(bool active);
};
} // namespace touchgfx
#endif // CORTEXMMCUINSTRUMENTATION_HPP
@@ -0,0 +1,94 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : STM32TouchController.cpp
******************************************************************************
* This file was created by TouchGFX Generator 4.22.1. This file is only
* generated once! Delete this file from your project and re-generate code
* using STM32CubeMX or change this file manually to update it.
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* USER CODE BEGIN STM32TouchController */
#include <touchgfx/hal/HAL.hpp>
#include <touchgfx/hal/Types.hpp>
#include <STM32TouchController.hpp>
#include "main.h"
volatile bool doSampleTouch = false;
extern "C" I2C_HandleTypeDef hi2c1;
using namespace touchgfx;
extern "C"
{
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == TP_IRQ_Pin)
{
/* Communication with TS is done via I2C.
Often the sw requires ISRs (interrupt service routines) to be quick while communication
with I2C can be considered relatively long (depending on SW requirements).
Considering that the TS feature don't need immediate reaction,
it is suggested to use polling mode instead of EXTI mode,
in order to avoid blocking I2C communication on interrupt service routines */
/* Here an example of implementation is proposed which is a mix between pooling and exit mode:
On ISR a flag is set (exti5_received), the main loop polls on the flag rather then polling the TS;
Mcu communicates with TS only when the flag has been set by ISR. This is just an example:
the users should choose they strategy depending on their application needs.*/
doSampleTouch = true;
return;
}
}
}
void STM32TouchController::init()
{
// No init needed
}
bool STM32TouchController::sampleTouch(int32_t& x, int32_t& y)
{
uint8_t touches = 0;
uint8_t buf[6];
const uint16_t STATUS_REG = 0x814E;
const uint16_t TOUCH_POS_REG = 0x8150;
uint8_t ZERO = 0;
NVIC_DisableIRQ(TP_IRQ_EXTI_IRQn);
if (doSampleTouch)
{
HAL_I2C_Mem_Read(&hi2c1, 0xBA, STATUS_REG, 2, buf, 1, HAL_MAX_DELAY);
touches = (0x0F & buf[0]);
HAL_I2C_Mem_Write(&hi2c1, 0xBA, STATUS_REG, 2, &ZERO, 1, HAL_MAX_DELAY);
doSampleTouch = false;
if (touches > 0)
{
HAL_I2C_Mem_Read(&hi2c1, 0xBA, TOUCH_POS_REG, 2, buf, 4, HAL_MAX_DELAY);
x = buf[0] + (buf[1] << 8);
y = buf[2] + (buf[3] << 8);
}
}
NVIC_EnableIRQ(TP_IRQ_EXTI_IRQn);
return (touches > 0);
}
/* USER CODE END STM32TouchController */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,72 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : STM32TouchController.hpp
******************************************************************************
* This file was created by TouchGFX Generator 4.22.1. This file is only
* generated once! Delete this file from your project and re-generate code
* using STM32CubeMX or change this file manually to update it.
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* USER CODE BEGIN STM32TouchController */
#ifndef STM32TOUCHCONTROLLER_HPP
#define STM32TOUCHCONTROLLER_HPP
#include <platform/driver/touch/TouchController.hpp>
/**
* @class STM32TouchController
*
* @brief This class specializes TouchController Interface.
*
* @sa touchgfx::TouchController
*/
class STM32TouchController : public touchgfx::TouchController
{
public:
STM32TouchController() {}
/**
* @fn virtual void STM32TouchController::init() = 0;
*
* @brief Initializes touch controller.
*
* Initializes touch controller.
*/
virtual void init();
/**
* @fn virtual bool STM32TouchController::sampleTouch(int32_t& x, int32_t& y) = 0;
*
* @brief Checks whether the touch screen is being touched, and if so, what coordinates.
*
* Checks whether the touch screen is being touched, and if so, what coordinates.
*
* @param [out] x The x position of the touch
* @param [out] y The y position of the touch
*
* @return True if a touch has been detected, otherwise false.
*/
virtual bool sampleTouch(int32_t& x, int32_t& y);
};
#endif // STM32TOUCHCONTROLLER_HPP
/* USER CODE END STM32TouchController */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+176
View File
@@ -0,0 +1,176 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : TouchGFXGPIO.cpp
******************************************************************************
* This file was created by TouchGFX Generator 4.22.1. This file is only
* generated once! Delete this file from your project and re-generate code
* using STM32CubeMX or change this file manually to update it.
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
#include <touchgfx/hal/GPIO.hpp>
/**
* GPIO_ID Enum
* The signals represented by this enum are used by TouchGFX framework to signal internal events.
*
* VSYNC_FREQ, /// Pin is toggled at each VSYNC
* RENDER_TIME, /// Pin is high when frame rendering begins, low when finished
* FRAME_RATE, /// Pin is toggled when the frame buffers are swapped.
* MCU_ACTIVE /// Pin is high when framework is utilizing the MCU.
*
* Configure GPIO's with the same name as the GPIO_IDs above, as output, in CubeMX to export
* the signals for performance measuring. See support.touchgfx.com for further details.
*
*/
/* USER CODE BEGIN TouchGFXGPIO.cpp */
#include "main.h"
using namespace touchgfx;
/*
* Perform configuration of IO pins.
*/
void GPIO::init()
{
}
/*
* Sets a pin high.
*/
void GPIO::set(GPIO_ID id)
{
switch (id)
{
case GPIO::VSYNC_FREQ:
#if defined(VSYNC_FREQ_GPIO_Port) && defined(VSYNC_FREQ_Pin)
HAL_GPIO_WritePin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin, GPIO_PIN_SET);
#endif
break;
case GPIO::RENDER_TIME:
#if defined(RENDER_TIME_GPIO_Port) && defined(RENDER_TIME_Pin)
HAL_GPIO_WritePin(RENDER_TIME_GPIO_Port, RENDER_TIME_Pin, GPIO_PIN_SET);
#endif
break;
case GPIO::FRAME_RATE:
#if defined(FRAME_RATE_GPIO_Port) && defined(FRAME_RATE_Pin)
HAL_GPIO_WritePin(FRAME_RATE_GPIO_Port, FRAME_RATE_Pin, GPIO_PIN_SET);
#endif
break;
case GPIO::MCU_ACTIVE:
#if defined(MCU_ACTIVE_GPIO_Port) && defined(MCU_ACTIVE_Pin)
HAL_GPIO_WritePin(MCU_ACTIVE_GPIO_Port, MCU_ACTIVE_Pin, GPIO_PIN_SET);
#endif
break;
}
}
/*
* Sets a pin low.
*/
void GPIO::clear(GPIO_ID id)
{
switch (id)
{
case GPIO::VSYNC_FREQ:
#if defined(VSYNC_FREQ_GPIO_Port) && defined(VSYNC_FREQ_Pin)
HAL_GPIO_WritePin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin, GPIO_PIN_RESET);
#endif
break;
case GPIO::RENDER_TIME:
#if defined(RENDER_TIME_GPIO_Port) && defined(RENDER_TIME_Pin)
HAL_GPIO_WritePin(RENDER_TIME_GPIO_Port, RENDER_TIME_Pin, GPIO_PIN_RESET);
#endif
break;
case GPIO::FRAME_RATE:
#if defined(FRAME_RATE_GPIO_Port) && defined(FRAME_RATE_Pin)
HAL_GPIO_WritePin(FRAME_RATE_GPIO_Port, FRAME_RATE_Pin, GPIO_PIN_RESET);
#endif
break;
case GPIO::MCU_ACTIVE:
#if defined(MCU_ACTIVE_GPIO_Port) && defined(MCU_ACTIVE_Pin)
HAL_GPIO_WritePin(MCU_ACTIVE_GPIO_Port, MCU_ACTIVE_Pin, GPIO_PIN_RESET);
#endif
break;
}
}
/*
* Toggles a pin.
*/
void GPIO::toggle(GPIO_ID id)
{
switch (id)
{
case GPIO::VSYNC_FREQ:
#if defined(VSYNC_FREQ_GPIO_Port) && defined(VSYNC_FREQ_Pin)
HAL_GPIO_TogglePin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin);
#endif
break;
case GPIO::RENDER_TIME:
#if defined(RENDER_TIME_GPIO_Port) && defined(RENDER_TIME_Pin)
HAL_GPIO_TogglePin(RENDER_TIME_GPIO_Port, RENDER_TIME_Pin);
#endif
break;
case GPIO::FRAME_RATE:
#if defined(FRAME_RATE_GPIO_Port) && defined(FRAME_RATE_Pin)
HAL_GPIO_TogglePin(FRAME_RATE_GPIO_Port, FRAME_RATE_Pin);
#endif
break;
case GPIO::MCU_ACTIVE:
#if defined(MCU_ACTIVE_GPIO_Port) && defined(MCU_ACTIVE_Pin)
HAL_GPIO_TogglePin(MCU_ACTIVE_GPIO_Port, MCU_ACTIVE_Pin);
#endif
break;
}
}
/*
* Gets the state of a pin.
*/
bool GPIO::get(GPIO_ID id)
{
GPIO_PinState bitstatus = GPIO_PIN_RESET;
switch (id)
{
case GPIO::VSYNC_FREQ:
#if defined(VSYNC_FREQ_GPIO_Port) && defined(VSYNC_FREQ_Pin)
bitstatus = HAL_GPIO_ReadPin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin);
#endif
break;
case GPIO::RENDER_TIME:
#if defined(RENDER_TIME_GPIO_Port) && defined(RENDER_TIME_Pin)
bitstatus = HAL_GPIO_ReadPin(RENDER_TIME_GPIO_Port, RENDER_TIME_Pin);
#endif
break;
case GPIO::FRAME_RATE:
#if defined(FRAME_RATE_GPIO_Port) && defined(FRAME_RATE_Pin)
bitstatus = HAL_GPIO_ReadPin(FRAME_RATE_GPIO_Port, FRAME_RATE_Pin);
#endif
break;
case GPIO::MCU_ACTIVE:
#if defined(MCU_ACTIVE_GPIO_Port) && defined(MCU_ACTIVE_Pin)
bitstatus = HAL_GPIO_ReadPin(MCU_ACTIVE_GPIO_Port, MCU_ACTIVE_Pin);
#endif
break;
}
return (bitstatus == GPIO_PIN_SET);
}
/* USER CODE END TouchGFXGPIO.cpp */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+189
View File
@@ -0,0 +1,189 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : TouchGFXHAL.cpp
******************************************************************************
* This file was created by TouchGFX Generator 4.22.1. This file is only
* generated once! Delete this file from your project and re-generate code
* using STM32CubeMX or change this file manually to update it.
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
#include <TouchGFXHAL.hpp>
/* USER CODE BEGIN TouchGFXHAL.cpp */
#include "FreeRTOS.h"
using namespace touchgfx;
namespace
{
LOCATION_PRAGMA_NOLOAD("TouchGFX_Framebuffer")
uint32_t animationBuffer[(800 * 480 * 2 + 3) / 4] LOCATION_ATTRIBUTE_NOLOAD("TouchGFX_Framebuffer");
}
void TouchGFXHAL::initialize()
{
// Calling parent implementation of initialize().
//
// To overwrite the generated implementation, omit call to parent function
// and implemented needed functionality here.
// Please note, HAL::initialize() must be called to initialize the framework.
TouchGFXGeneratedHAL::initialize();
setAnimationStorage((void*)animationBuffer); //enable the animation storage to allow slide animations
instrumentation.init();
setMCUInstrumentation(&instrumentation);
enableMCULoadCalculation(true);
}
/**
* Gets the frame buffer address used by the TFT controller.
*
* @return The address of the frame buffer currently being displayed on the TFT.
*/
uint16_t* TouchGFXHAL::getTFTFrameBuffer() const
{
// Calling parent implementation of getTFTFrameBuffer().
//
// To overwrite the generated implementation, omit call to parent function
// and implemented needed functionality here.
return TouchGFXGeneratedHAL::getTFTFrameBuffer();
}
/**
* Sets the frame buffer address used by the TFT controller.
*
* @param [in] address New frame buffer address.
*/
void TouchGFXHAL::setTFTFrameBuffer(uint16_t* address)
{
// Calling parent implementation of setTFTFrameBuffer(uint16_t* address).
//
// To overwrite the generated implementation, omit call to parent function
// and implemented needed functionality here.
TouchGFXGeneratedHAL::setTFTFrameBuffer(address);
}
/**
* This function is called whenever the framework has performed a partial draw.
*
* @param rect The area of the screen that has been drawn, expressed in absolute coordinates.
*
* @see flushFrameBuffer().
*/
void TouchGFXHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
// Calling parent implementation of flushFrameBuffer(const touchgfx::Rect& rect).
//
// To overwrite the generated implementation, omit call to parent function
// and implemented needed functionality here.
// Please note, HAL::flushFrameBuffer(const touchgfx::Rect& rect) must
// be called to notify the touchgfx framework that flush has been performed.
// To calculate he start adress of rect,
// use advanceFrameBufferToRect(uint8_t* fbPtr, const touchgfx::Rect& rect)
// defined in TouchGFXGeneratedHAL.cpp
TouchGFXGeneratedHAL::flushFrameBuffer(rect);
}
bool TouchGFXHAL::blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes)
{
return TouchGFXGeneratedHAL::blockCopy(dest, src, numBytes);
}
/**
* Configures the interrupts relevant for TouchGFX. This primarily entails setting
* the interrupt priorities for the DMA and LCD interrupts.
*/
void TouchGFXHAL::configureInterrupts()
{
// Calling parent implementation of configureInterrupts().
//
// To overwrite the generated implementation, omit call to parent function
// and implemented needed functionality here.
TouchGFXGeneratedHAL::configureInterrupts();
}
/**
* Used for enabling interrupts set in configureInterrupts()
*/
void TouchGFXHAL::enableInterrupts()
{
// Calling parent implementation of enableInterrupts().
//
// To overwrite the generated implementation, omit call to parent function
// and implemented needed functionality here.
TouchGFXGeneratedHAL::enableInterrupts();
}
/**
* Used for disabling interrupts set in configureInterrupts()
*/
void TouchGFXHAL::disableInterrupts()
{
// Calling parent implementation of disableInterrupts().
//
// To overwrite the generated implementation, omit call to parent function
// and implemented needed functionality here.
TouchGFXGeneratedHAL::disableInterrupts();
}
/**
* Configure the LCD controller to fire interrupts at VSYNC. Called automatically
* once TouchGFX initialization has completed.
*/
void TouchGFXHAL::enableLCDControllerInterrupt()
{
// Calling parent implementation of enableLCDControllerInterrupt().
//
// To overwrite the generated implementation, omit call to parent function
// and implemented needed functionality here.
TouchGFXGeneratedHAL::enableLCDControllerInterrupt();
}
bool TouchGFXHAL::beginFrame()
{
return TouchGFXGeneratedHAL::beginFrame();
}
void TouchGFXHAL::endFrame()
{
TouchGFXGeneratedHAL::endFrame();
}
extern "C"
{
portBASE_TYPE IdleTaskHook(void* p)
{
if ((int)p) //idle task sched out
{
touchgfx::HAL::getInstance()->setMCUActive(true);
}
else //idle task sched in
{
touchgfx::HAL::getInstance()->setMCUActive(false);
}
return pdTRUE;
}
}
/* USER CODE END TouchGFXHAL.cpp */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+174
View File
@@ -0,0 +1,174 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : TouchGFXHAL.hpp
******************************************************************************
* This file was created by TouchGFX Generator 4.22.1. This file is only
* generated once! Delete this file from your project and re-generate code
* using STM32CubeMX or change this file manually to update it.
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
#ifndef TouchGFXHAL_HPP
#define TouchGFXHAL_HPP
/* USER CODE BEGIN TouchGFXHAL.hpp */
#include <TouchGFXGeneratedHAL.hpp>
#include <CortexMMCUInstrumentation.hpp>
/**
* @class TouchGFXHAL
*
* @brief HAL implementation for TouchGFX.
*
* @sa HAL
*/
class TouchGFXHAL : public TouchGFXGeneratedHAL
{
public:
/**
* @fn TouchGFXHAL::TouchGFXHAL(touchgfx::DMA_Interface& dma, touchgfx::LCD& display, touchgfx::TouchController& tc, uint16_t width, uint16_t height) : TouchGFXGeneratedHAL(dma, display, tc, width, height)
*
* @brief Constructor.
*
* Constructor. Initializes members.
*
* @param [in,out] dma Reference to DMA interface.
* @param [in,out] display Reference to LCD interface.
* @param [in,out] tc Reference to Touch Controller driver.
* @param width Width of the display.
* @param height Height of the display.
*/
TouchGFXHAL(touchgfx::DMA_Interface& dma, touchgfx::LCD& display, touchgfx::TouchController& tc, uint16_t width, uint16_t height) : TouchGFXGeneratedHAL(dma, display, tc, width, height)
{
}
virtual void initialize();
/**
* @fn virtual void TouchGFXHAL::disableInterrupts();
*
* @brief Disables the DMA and LCD interrupts.
*
* Disables the DMA and LCD interrupts.
*/
virtual void disableInterrupts();
/**
* @fn virtual void TouchGFXHAL::enableInterrupts();
*
* @brief Enables the DMA and LCD interrupts.
*
* Enables the DMA and LCD interrupts.
*/
virtual void enableInterrupts();
/**
* @fn virtual void TouchGFXHAL::configureInterrupts();
*
* @brief Sets the DMA and LCD interrupt priorities.
*
* Sets the DMA and LCD interrupt priorities.
*/
virtual void configureInterrupts();
/**
* @fn virtual void TouchGFXHAL::enableLCDControllerInterrupt();
*
* @brief Configure the LCD controller to fire interrupts at VSYNC.
*
* Configure the LCD controller to fire interrupts at VSYNC. Called automatically
* once TouchGFX initialization has completed.
*/
virtual void enableLCDControllerInterrupt();
virtual bool beginFrame();
virtual void endFrame();
/**
* @fn virtual void TouchGFXHAL::flushFrameBuffer();
*
* @brief This function is called whenever the framework has performed a complete draw.
*
* This specialization is only in place to keep compilers happy. Base impl. will call the
* Rect version.
* @see HAL::flushFrameBuffer
*/
virtual void flushFrameBuffer()
{
TouchGFXGeneratedHAL::flushFrameBuffer();
}
/**
* @fn virtual void TouchGFXHAL::flushFrameBuffer(const Rect& rect);
*
* @brief This function is called whenever the framework has performed a partial draw.
*
* This function is called whenever the framework has performed a partial draw.
* On the STM32F7, make sure to clean and invalidate the data cache. This is to
* ensure that LTDC sees correct data when transferring to the display.
*
* @param rect The area of the screen that has been drawn, expressed in absolute coordinates.
*
* @see flushFrameBuffer().
*/
virtual void flushFrameBuffer(const touchgfx::Rect& rect);
/**
* @fn virtual bool TouchGFXHAL::blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes);
*
* @brief This function performs a platform-specific memcpy.
*
* This function performs a platform-specific memcpy, if supported by the hardware.
*
* @param [out] dest Pointer to destination memory.
* @param [in] src Pointer to source memory.
* @param numBytes Number of bytes to copy.
*
* @return true if the copy succeeded, false if copy was not performed.
*/
virtual bool blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes);
protected:
/**
* @fn virtual uint16_t* TouchGFXHAL::getTFTFrameBuffer() const;
*
* @brief Gets the frame buffer address used by the TFT controller.
*
* Gets the frame buffer address used by the TFT controller.
*
* @return The address of the frame buffer currently being displayed on the TFT.
*/
virtual uint16_t* getTFTFrameBuffer() const;
/**
* @fn virtual void TouchGFXHAL::setTFTFrameBuffer(uint16_t* adr);
*
* @brief Sets the frame buffer address used by the TFT controller.
*
* Sets the frame buffer address used by the TFT controller.
*
* @param [in,out] adr New frame buffer address.
*/
virtual void setTFTFrameBuffer(uint16_t* adr);
private:
touchgfx::CortexMMCUInstrumentation instrumentation;
};
/* USER CODE END TouchGFXHAL.hpp */
#endif // TouchGFXHAL_HPP
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,370 @@
/**
******************************************************************************
* File Name : DirectFrameBufferVideoController.hpp
******************************************************************************
* This file is generated by TouchGFX Generator 4.26.1. Please, do not edit!
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
#ifndef TOUCHGFX_DIRECTFRAMEBUFFERVIDEOCONTROLLER_HPP
#define TOUCHGFX_DIRECTFRAMEBUFFERVIDEOCONTROLLER_HPP
#include <touchgfx/transforms/DisplayTransformation.hpp>
#include <touchgfx/widgets/VideoWidget.hpp>
#include <MJPEGDecoder.hpp>
#include <string.h>
/**
* Strategy:
* Decode directly into the framebuffer in draw.
* Tick will decide if we are going to a new frame.
*/
template <uint32_t no_streams, touchgfx::Bitmap::BitmapFormat output_format>
class DirectFrameBufferVideoController : public touchgfx::VideoController
{
public:
DirectFrameBufferVideoController()
: VideoController(), allowSkipFrames(true)
{
assert((no_streams > 0) && "Video: Number of streams zero!");
// Clear arrays
memset(mjpegDecoders, 0, sizeof(mjpegDecoders));
}
virtual Handle registerVideoWidget(touchgfx::VideoWidget& widget)
{
// Find stream handle for Widget
Handle handle = getFreeHandle();
streams[handle].isActive = true;
//Set Widget buffer format and address
widget.setVideoBufferFormat(output_format, 0, 0);
widget.setVideoBuffer((uint8_t*)0);
return handle;
}
virtual void unregisterVideoWidget(const Handle handle)
{
streams[handle].isActive = false;
}
virtual void setFrameRate(const Handle handle, uint32_t ui_frames, uint32_t video_frames)
{
assert(handle < no_streams);
Stream& stream = streams[handle];
// Reset counters
stream.frameCount = 0;
stream.tickCount = 0;
// Save requested frame rate ratio
stream.frame_rate_ticks = ui_frames;
stream.frame_rate_video = video_frames;
}
virtual void setVideoData(const Handle handle, const uint8_t* movie, const uint32_t length)
{
assert(handle < no_streams);
// Reset decoder to first frame
mjpegDecoders[handle]->setVideoData(movie, length);
// Lower flag to show the first frame
Stream& stream = streams[handle];
stream.frameNumber = mjpegDecoders[handle]->getCurrentFrameNumber();
stream.doDecodeNextFrame = false;
// Stop playing
setCommand(handle, PAUSE, 0);
}
virtual void setVideoData(const Handle handle, touchgfx::VideoDataReader& reader)
{
assert(handle < no_streams);
// Reset decoder to first frame
mjpegDecoders[handle]->setVideoData(reader);
// Lower flag to show the first frame
Stream& stream = streams[handle];
stream.frameNumber = mjpegDecoders[handle]->getCurrentFrameNumber();
stream.doDecodeNextFrame = false;
// Stop playing
setCommand(handle, PAUSE, 0);
}
virtual void setCommand(const Handle handle, Command cmd, uint32_t param)
{
assert(handle < no_streams);
Stream& stream = streams[handle];
switch (cmd)
{
case PLAY:
// Cannot Play without movie
if (mjpegDecoders[handle]->hasVideo())
{
stream.isPlaying = true;
stream.isShowingOneFrame = false;
// Reset counters
stream.frameCount = 0;
stream.tickCount = 0;
// If non-repeating video stopped at the end, kick to next frame
if (!stream.repeat)
{
MJPEGDecoder* const decoder = mjpegDecoders[handle];
if (decoder->getCurrentFrameNumber() == decoder->getNumberOfFrames())
{
decoder->gotoNextFrame();
}
}
}
break;
case PAUSE:
stream.isPlaying = false;
stream.isShowingOneFrame = false;
break;
case SEEK:
stream.seek_to_frame = param;
// Reset counters
stream.frameCount = 0;
stream.tickCount = 0;
break;
case SHOW:
stream.seek_to_frame = param;
stream.isShowingOneFrame = true;
stream.doDecodeNextFrame = true;
// Reset counters
stream.frameCount = 0;
stream.tickCount = 0;
break;
case STOP:
stream.isPlaying = false;
stream.isShowingOneFrame = false;
stream.seek_to_frame = 1;
// Reset counters
stream.frameCount = 0;
stream.tickCount = 0;
break;
case SET_REPEAT:
stream.repeat = (param > 0);
break;
}
}
virtual bool updateFrame(const Handle handle, touchgfx::VideoWidget& widget)
{
assert(handle < no_streams);
Stream& stream = streams[handle];
bool hasMoreFrames = true;
if (stream.isPlaying || stream.isShowingOneFrame)
{
// Increase tickCount
stream.tickCount += HAL::getInstance()->getLCDRefreshCount();
// Lower flag
stream.isShowingOneFrame = false;
if (stream.doDecodeNextFrame)
{
MJPEGDecoder* const decoder = mjpegDecoders[handle];
// Invalidate to get widget redrawn
widget.invalidate();
// Seek or increment video frame
if (stream.seek_to_frame > 0)
{
decoder->gotoFrame(stream.seek_to_frame);
hasMoreFrames = (stream.seek_to_frame < decoder->getNumberOfFrames());
stream.seek_to_frame = 0;
}
else
{
if (stream.skip_frames > 0)
{
decoder->gotoFrame(decoder->getCurrentFrameNumber() + stream.skip_frames);
stream.frameCount += stream.skip_frames;
stream.skip_frames = 0;
}
if (stream.repeat)
{
hasMoreFrames = decoder->gotoNextFrame();
}
else
{
if (decoder->getCurrentFrameNumber() < decoder->getNumberOfFrames())
{
hasMoreFrames = decoder->gotoNextFrame();
}
else
{
stream.isPlaying = false;
hasMoreFrames = false;
}
}
}
stream.frameNumber = decoder->getCurrentFrameNumber();
stream.frameCount++;
}
// Save decode status for next frame
stream.doDecodeNextFrame = decodeForNextTick(stream);
}
return hasMoreFrames;
}
virtual void draw(const Handle handle, const touchgfx::Rect& invalidatedArea, const touchgfx::VideoWidget& widget)
{
assert(handle < no_streams);
if (output_format != Bitmap::RGB565 && output_format != Bitmap::RGB888 && output_format != Bitmap::ARGB8888)
{
return;
}
if (mjpegDecoders[handle]->hasVideo())
{
uint8_t* wbuf = (uint8_t*)touchgfx::HAL::getInstance()->lockFrameBufferForRenderingMethod(touchgfx::HAL::HARDWARE);
touchgfx::Rect absolute = widget.getAbsoluteRect();
DisplayTransformation::transformDisplayToFrameBuffer(absolute);
// Get frame buffer pointer to upper left of widget in framebuffer coordinates
switch (output_format)
{
case Bitmap::RGB565:
wbuf += (absolute.x + absolute.y * touchgfx::HAL::FRAME_BUFFER_WIDTH) * 2;
break;
case Bitmap::RGB888:
wbuf += (absolute.x + absolute.y * touchgfx::HAL::FRAME_BUFFER_WIDTH) * 3;
break;
case Bitmap::ARGB8888:
wbuf += (absolute.x + absolute.y * touchgfx::HAL::FRAME_BUFFER_WIDTH) * 4;
break;
default:
break;
}
// Decode relevant part of the frame to the framebuffer
mjpegDecoders[handle]->decodeFrame(invalidatedArea, wbuf, touchgfx::HAL::FRAME_BUFFER_WIDTH);
// Release frame buffer
touchgfx::HAL::getInstance()->unlockFrameBuffer();
}
}
void addDecoder(MJPEGDecoder& decoder, uint32_t index)
{
assert(index < no_streams);
mjpegDecoders[index] = &decoder;
}
virtual uint32_t getCurrentFrameNumber(const Handle handle)
{
assert(handle < no_streams);
Stream& stream = streams[handle];
return stream.frameNumber;
}
virtual void getVideoInformation(const Handle handle, touchgfx::VideoInformation* data)
{
assert(handle < no_streams);
mjpegDecoders[handle]->getVideoInfo(data);
}
virtual bool getIsPlaying(const Handle handle)
{
assert(handle < no_streams);
Stream& stream = streams[handle];
return stream.isPlaying;
}
virtual void setVideoFrameRateCompensation(const bool allow)
{
allowSkipFrames = allow;
}
private:
class Stream
{
public:
Stream()
: frameCount(0), frameNumber(0), tickCount(0),
frame_rate_video(0), frame_rate_ticks(0),
seek_to_frame(0),
isActive(false), isPlaying(false), isShowingOneFrame(false), repeat(true),
doDecodeNextFrame(false)
{
}
uint32_t frameCount; // Video frames decoded since play
uint32_t frameNumber; // Video frame showed number
uint32_t tickCount; // UI frames since play
uint32_t frame_rate_video; // Ratio of frames wanted counter
uint32_t frame_rate_ticks; // Ratio of frames wanted divider
uint32_t seek_to_frame; // Requested next frame number
uint32_t skip_frames; // Number of frames to skip to keep frame rate
bool isActive;
bool isPlaying;
bool isShowingOneFrame;
bool repeat;
bool doDecodeNextFrame; // High if we should go to next frame in next tick
};
MJPEGDecoder* mjpegDecoders[no_streams];
Stream streams[no_streams];
bool allowSkipFrames;
/**
* Return true, if new video frame should be decoded for the next tick (keep video decode framerate low)
*/
bool decodeForNextTick(Stream& stream)
{
// Running in UI thread
// Compare tickCount/frameNumber to frame_rate_ticks/frame_rate_video
if ((stream.tickCount * stream.frame_rate_video) > (stream.frame_rate_ticks * stream.frameCount))
{
if (allowSkipFrames)
{
stream.skip_frames = (stream.tickCount * stream.frame_rate_video - stream.frame_rate_ticks * stream.frameCount) / stream.frame_rate_ticks;
if (stream.skip_frames > 0)
{
stream.skip_frames--;
}
}
return true;
}
return false;
}
Handle getFreeHandle()
{
for (uint32_t i = 0; i < no_streams; i++)
{
if (streams[i].isActive == false)
{
return static_cast<VideoController::Handle>(i);
}
}
assert(0 && "Unable to find free video stream handle!");
return static_cast<VideoController::Handle>(0);
}
};
#endif // TOUCHGFX_DIRECTFRAMEBUFFERVIDEOCONTROLLER_HPP
@@ -0,0 +1,934 @@
/**
******************************************************************************
* File Name : HardwareMJPEGDecoder.cpp
******************************************************************************
* This file is generated by TouchGFX Generator 4.26.1. Please, do not edit!
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
#include <HardwareMJPEGDecoder.hpp>
#include <touchgfx/hal/BlitOp.hpp>
extern "C"
{
#include <string.h>
#include <stm32h7rsxx_hal.h>
uint32_t JPEG_Decode_DMA(JPEG_HandleTypeDef* hjpeg, uint8_t* input, uint32_t chunkSizeIn, uint8_t* output);
uint32_t JPEG_OutputHandler(JPEG_HandleTypeDef* hjpeg);
void HAL_JPEG_DecodeCpltCallback(JPEG_HandleTypeDef* hjpeg);
void HAL_JPEG_ErrorCallback(JPEG_HandleTypeDef* hjpeg);
void HAL_JPEG_DataReadyCallback(JPEG_HandleTypeDef* hjpeg, uint8_t* pDataOut, uint32_t OutDataLength);
void DMA2D_CropBuffer(JPEG_Data_BufferTypeDef& job);
void DMA2D_CopyBuffer(JPEG_Data_BufferTypeDef& job);
void DMA2D_ExternalJobCompleted(JPEG_Data_BufferTypeDef& job);
}
namespace
{
uint8_t* FrameBufferAddress;
uint32_t JPEG_InputImageIndex;
uint32_t JPEG_InputImageSize_Bytes;
uint32_t JPEG_InputImageAddress;
volatile uint32_t Jpeg_HWDecodingEnd = 0;
volatile uint32_t JPEG_output_is_paused = 0;
volatile uint32_t JpegProcessing_End = 0;
uint32_t MCU_TotalNb = 0;
touchgfx::DMA_Interface* DMA2D_reference;
volatile uint32_t JPEG_OUT_Write_BufferIndex = 0;
uint32_t FrameBufferWidth;
volatile uint32_t line_count = 0;
}
#define MCU_WIDTH_PIXELS ((uint32_t)16)
#define MCU_HEIGHT_PIXELS ((uint32_t)16)
#define MCU_CHROMA_420_SIZE_BYTES ((uint32_t)384)
#define CHUNK_SIZE_IN ((uint32_t)(1024*52)) /* Max block size */
#define CHUNK_SIZE_OUT ((uint32_t)(MCU_CHROMA_420_SIZE_BYTES * ((800 + MCU_WIDTH_PIXELS - 1) / MCU_WIDTH_PIXELS)))
LOCATION_PRAGMA_32("TouchGFX_MCU_Data_OutBuffer0")
uint8_t MCU_Data_OutBuffer0[CHUNK_SIZE_OUT] LOCATION_ATTRIBUTE_32("TouchGFX_MCU_Data_OutBuffer0");
LOCATION_PRAGMA_32("TouchGFX_MCU_Data_OutBuffer1")
uint8_t MCU_Data_OutBuffer1[CHUNK_SIZE_OUT] LOCATION_ATTRIBUTE_32("TouchGFX_MCU_Data_OutBuffer1");
uint8_t MCU_Cropping_Buffer[MCU_WIDTH_PIXELS * MCU_HEIGHT_PIXELS * 2];
__IO uint32_t MCU_BlockIndex = 0;
SEM_TYPE semDecodingDone;
extern JPEG_ConfTypeDef* JPEG_Info;
extern JPEG_HandleTypeDef hjpeg;
volatile uint32_t JPEG_OUT_Read_BufferIndex = 0;
volatile uint32_t DMA2D_CopyBufferEnd = 0;
JPEG_Data_BufferTypeDef Jpeg_OUT_BufferTab[NB_OUTPUT_DATA_BUFFERS] =
{
{JPEG_BUFFER_EMPTY, MCU_Data_OutBuffer0, 0, 0, NULL, false, false, 0, false},
{JPEG_BUFFER_EMPTY, MCU_Data_OutBuffer1, 0, 0, NULL, false, false, 0, false},
};
static struct JPEG_MCU_RGB_Converter
{
uint32_t WidthExtend;
uint32_t ScaledWidth;
uint32_t LastLineHeight;
uint32_t MCU_pr_line;
uint32_t bytes_pr_pixel;
uint32_t startY;
uint32_t endY;
uint32_t startX;
uint32_t endX;
uint32_t MCUStart;
uint32_t MCUEnd;
uint32_t MCU_pr_job;
uint32_t firstColOffset;
uint32_t firstRowOffset;
uint32_t lastColOffset;
uint32_t lastRowOffset;
} JPEG_ConvertorParams;
HardwareMJPEGDecoder::HardwareMJPEGDecoder()
: frameNumber(0), currentMovieOffset(0), indexOffset(0), firstFrameOffset(0), lastFrameEnd(0), movieLength(0), movieData(0),
reader(0), aviBuffer(0), aviBufferLength(0), aviBufferStartOffset(0), lastError(AVI_NO_ERROR)
{
/* Clear video info */
videoInfo.frame_height = 0;
videoInfo.frame_width = 0;
videoInfo.ms_between_frames = 0;
videoInfo.number_of_frames = 0;
/* Create decoding semaphore */
semDecodingDone = SEM_CREATE();
}
int HardwareMJPEGDecoder::compare(const uint32_t offset, const char* str, uint32_t num)
{
const char* src;
if (reader != 0)
{
/* Assuming data is in buffer! */
src = reinterpret_cast<const char*>(aviBuffer + (offset - aviBufferStartOffset));
}
else
{
src = (const char*)movieData + offset;
}
return strncmp(src, str, num);
}
inline uint32_t HardwareMJPEGDecoder::getU32(const uint32_t offset)
{
if (reader != 0)
{
/* Assuming data is in buffer! */
const uint32_t index = offset - aviBufferStartOffset;
return aviBuffer[index + 0] | (aviBuffer[index + 1] << 8) | (aviBuffer[index + 2] << 16) | (aviBuffer[index + 3] << 24);
}
else
{
volatile const uint8_t* const d = movieData + offset;
uint32_t val = 0U;
val |= d[0];
val |= d[1] << 8;
val |= d[2] << 16;
val |= d[3] << 24;
return val;
}
}
inline uint32_t HardwareMJPEGDecoder::getU16(const uint32_t offset)
{
if (reader != 0)
{
/* Assuming data is in buffer! */
const uint32_t index = offset - aviBufferStartOffset;
return aviBuffer[index + 0] | (aviBuffer[index + 1] << 8);
}
else
{
volatile const uint8_t* const d = movieData + offset;
uint32_t val = 0U;
val |= d[0];
val |= d[1] << 8;
return val;
}
}
const uint8_t* HardwareMJPEGDecoder::readData(uint32_t offset, uint32_t length)
{
if (reader != 0)
{
if (length > aviBufferLength)
{
lastError = AVI_ERROR_FILE_BUFFER_TO_SMALL;
assert(!"Buffer to small");
}
reader->seek(offset);
if (!reader->readData(aviBuffer, length))
{
lastError = AVI_ERROR_EOF_REACHED;
}
aviBufferStartOffset = offset;
return aviBuffer;
}
return movieData + offset;
}
bool HardwareMJPEGDecoder::decodeNextFrame(uint8_t* buffer, uint16_t buffer_width, uint16_t buffer_height, uint32_t buffer_stride)
{
assert((frameNumber > 0) && "HardwareMJPEGDecoder decoding without frame data!");
/* find next frame and decode it */
readData(currentMovieOffset, 8);
uint32_t streamNo = getU16(currentMovieOffset);
uint32_t chunkType = getU16(currentMovieOffset + 2);
uint32_t chunkSize = getU32(currentMovieOffset + 4);
const uint16_t STREAM0 = 0x3030;
const uint16_t TYPEDC = 0x6364;
bool isCurrentFrameLast;
/* play frame if we have it all */
if (currentMovieOffset + 8 + chunkSize < movieLength)
{
if (streamNo == STREAM0 && chunkType == TYPEDC && chunkSize > 0)
{
currentMovieOffset += 8;
/* decode frame */
const uint8_t* chunk = readData(currentMovieOffset, chunkSize);
decodeMJPEGFrame(chunk, chunkSize, buffer, buffer_width, buffer_height, buffer_stride);
frameNumber++;
}
isCurrentFrameLast = false;
/* Advance to next frame */
currentMovieOffset += chunkSize;
if (chunkSize == 0) /* Empty frame - Skip */
{
currentMovieOffset += 8;
}
currentMovieOffset = (currentMovieOffset + 1) & 0xFFFFFFFE; /* pad to next word */
if (currentMovieOffset == lastFrameEnd)
{
frameNumber = 1;
currentMovieOffset = firstFrameOffset; /* start over */
isCurrentFrameLast = true;
}
}
else
{
frameNumber = 1;
currentMovieOffset = firstFrameOffset; /* start over */
isCurrentFrameLast = true;
}
return !isCurrentFrameLast;
}
bool HardwareMJPEGDecoder::gotoNextFrame()
{
assert((frameNumber > 0) && "HardwareMJPEGDecoder decoding without frame data!");
readData(currentMovieOffset, 8);
uint32_t chunkSize = getU32(currentMovieOffset + 4);
/* increment until next video frame */
while (currentMovieOffset + 8 + chunkSize < movieLength)
{
/* increment one frame */
currentMovieOffset += chunkSize + 8;
currentMovieOffset = (currentMovieOffset + 1) & 0xFFFFFFFE; /* pad to next word */
frameNumber++;
/* next chunk */
readData(currentMovieOffset, 8);
/* check it is a video frame */
uint32_t streamNo = getU16(currentMovieOffset);
uint32_t chunkType = getU16(currentMovieOffset + 2);
chunkSize = getU32(currentMovieOffset + 4);
const uint16_t STREAM0 = 0x3030;
const uint16_t TYPEDC = 0x6364;
if (streamNo == STREAM0 && chunkType == TYPEDC)
{
/* Found next frame */
return true;
}
}
/* skip back to first frame */
frameNumber = 1;
currentMovieOffset = firstFrameOffset; /* start over */
return false;
}
void HardwareMJPEGDecoder::setVideoData(const uint8_t* movie, const uint32_t length)
{
movieData = movie;
movieLength = length;
reader = 0; /* not using reader */
readVideoHeader();
}
void HardwareMJPEGDecoder::setVideoData(touchgfx::VideoDataReader& reader)
{
this->reader = &reader;
movieData = 0;
movieLength = reader.getDataLength();
readVideoHeader();
}
bool HardwareMJPEGDecoder::hasVideo()
{
return (reader != 0) || (movieData != 0);
}
void HardwareMJPEGDecoder::readVideoHeader()
{
/* Start from the start */
currentMovieOffset = 0;
lastError = AVI_NO_ERROR;
/* Make header available in buffer */
readData(0, 72);
/* Decode the movie header to find first frame */
/* Must be RIFF file */
if (compare(currentMovieOffset, "RIFF", 4))
{
lastError = AVI_ERROR_NOT_RIFF;
assert(!"RIFF header not found");
}
/* skip fourcc and length */
currentMovieOffset += 8;
if (compare(currentMovieOffset, "AVI ", 4))
{
lastError = AVI_ERROR_AVI_HEADER_NOT_FOUND;
assert(!"AVI header not found");
}
currentMovieOffset += 4;
if (compare(currentMovieOffset, "LIST", 4))
{
lastError = AVI_ERROR_AVI_LIST_NOT_FOUND;
assert(!"AVI LIST not found");
}
/* save AVI List info */
const uint32_t aviListSize = getU32(currentMovieOffset + 4);
const uint32_t aviListOffset = currentMovieOffset;
assert(aviListSize);
/* look into header to find frame rate */
bool foundFrame = true;
uint32_t offset = currentMovieOffset + 8;
if (compare(offset, "hdrl", 4))
{
lastError = AVI_ERROR_AVI_HDRL_NOT_FOUND;
foundFrame = false;
}
offset += 4;
if (compare(offset, "avih", 4))
{
lastError = AVI_ERROR_AVI_AVIH_NOT_FOUND;
foundFrame = false;
}
if (foundFrame)
{
offset += 8; /* skip fourcc and cb in AVIMAINHEADER */
videoInfo.ms_between_frames = getU32(offset) / 1000;
videoInfo.number_of_frames = getU32(offset + 16);
videoInfo.frame_width = getU32(offset + 32);
videoInfo.frame_height = getU32(offset + 36);
}
/* skip rest of AVI header, start from end of AVI List */
/* look for list with 'movi' header */
uint32_t listOffset = aviListOffset + aviListSize + 8;
readData(listOffset, 12);
while (compare(listOffset + 8, "movi", 4) && (lastError == AVI_NO_ERROR) && listOffset < movieLength)
{
const uint32_t listSize = getU32(listOffset + 4) + 8;
listOffset += listSize;
readData(listOffset, 12);
}
if (lastError != AVI_NO_ERROR)
{
lastError = AVI_ERROR_MOVI_NOT_FOUND;
return;
}
/* save first frame and end of last frame */
currentMovieOffset = listOffset + 8 + 4; /* skip LIST and 'movi' */
lastFrameEnd = listOffset + 8 + getU32(listOffset + 4);
/* find idx */
const uint32_t listSize = getU32(listOffset + 4) + 8;
listOffset += listSize;
readData(listOffset, 4);
if (!compare(listOffset, "idx1", 4))
{
indexOffset = listOffset;
}
else
{
lastError = AVI_ERROR_IDX1_NOT_FOUND;
return;
}
/* start on first frame */
frameNumber = 1; /* next frame number is 1 */
firstFrameOffset = currentMovieOffset;
}
void HardwareMJPEGDecoder::decodeMJPEGFrame(const uint8_t* const mjpgdata, const uint32_t length, uint8_t* outputBuffer, uint16_t bufferWidth, uint16_t bufferHeight, uint32_t bufferStride)
{
if (length == 0)
{
return;
}
if (outputBuffer) /* only decode if buffers are assigned. */
{
/* Update JPEG conversion parameters */
JPEG_ConvertorParams.bytes_pr_pixel = 2;
JPEG_ConvertorParams.WidthExtend = videoInfo.frame_width;
if ((JPEG_ConvertorParams.WidthExtend % 16) != 0)
{
JPEG_ConvertorParams.WidthExtend += 16 - (JPEG_ConvertorParams.WidthExtend % 16);
}
JPEG_ConvertorParams.ScaledWidth = 800 * JPEG_ConvertorParams.bytes_pr_pixel;
JPEG_ConvertorParams.MCU_pr_line = JPEG_ConvertorParams.WidthExtend / MCU_WIDTH_PIXELS;
JPEG_ConvertorParams.LastLineHeight = (videoInfo.frame_height % MCU_HEIGHT_PIXELS) == 0 ? 0 : MCU_HEIGHT_PIXELS - (videoInfo.frame_height % MCU_HEIGHT_PIXELS);
FrameBufferWidth = bufferStride / 2;
FrameBufferAddress = outputBuffer;
JPEG_Decode_DMA(&hjpeg, const_cast<uint8_t*>(mjpgdata), length, outputBuffer);
DMA2D_reference = dma;
do
{
JpegProcessing_End = JPEG_OutputHandler(&hjpeg);
/* If nothing to do, allow other tasks */
if (JpegProcessing_End == 2)
{
SEM_WAIT(semDecodingDone);
}
} while (JpegProcessing_End != 1);
/* reset flag */
Jpeg_HWDecodingEnd = 0;
DMA2D_CopyBufferEnd = 0;
}
}
bool HardwareMJPEGDecoder::decodeFrame(const touchgfx::Rect& area, uint8_t* frameBuffer, uint32_t framebuffer_width)
{
/* Assuming that chunk is available and streamNo and chunkType is correct. */
/* Check by gotoNextFrame */
readData(currentMovieOffset, 8);
const uint32_t length = getU32(currentMovieOffset + 4);
/* Ensure whole frame is read */
const uint8_t* mjpgdata = readData(currentMovieOffset + 8, length);
/* Update JPEG conversion parameters */
JPEG_ConvertorParams.bytes_pr_pixel = 2;
JPEG_ConvertorParams.WidthExtend = videoInfo.frame_width;
if ((JPEG_ConvertorParams.WidthExtend % 16) != 0)
{
JPEG_ConvertorParams.WidthExtend += 16 - (JPEG_ConvertorParams.WidthExtend % 16);
}
JPEG_ConvertorParams.ScaledWidth = 800 * JPEG_ConvertorParams.bytes_pr_pixel;
JPEG_ConvertorParams.MCU_pr_line = JPEG_ConvertorParams.WidthExtend / MCU_WIDTH_PIXELS;
JPEG_ConvertorParams.startY = area.y;
JPEG_ConvertorParams.endY = MIN((uint32_t)area.bottom(), videoInfo.frame_height);
JPEG_ConvertorParams.startX = area.x;
JPEG_ConvertorParams.endX = MIN((uint32_t)area.right(), videoInfo.frame_width);
JPEG_ConvertorParams.MCUStart = JPEG_ConvertorParams.startX / MCU_WIDTH_PIXELS;
JPEG_ConvertorParams.MCUEnd = (JPEG_ConvertorParams.endX + MCU_WIDTH_PIXELS - 1) / MCU_WIDTH_PIXELS; // Ceil division
JPEG_ConvertorParams.MCU_pr_job = JPEG_ConvertorParams.MCUEnd - JPEG_ConvertorParams.MCUStart;
JPEG_ConvertorParams.firstColOffset = JPEG_ConvertorParams.startX % MCU_WIDTH_PIXELS;
JPEG_ConvertorParams.firstRowOffset = JPEG_ConvertorParams.startY % MCU_HEIGHT_PIXELS;
JPEG_ConvertorParams.lastColOffset = (JPEG_ConvertorParams.endX % MCU_WIDTH_PIXELS) == 0 ? 0 : MCU_WIDTH_PIXELS - (JPEG_ConvertorParams.endX % MCU_WIDTH_PIXELS);
JPEG_ConvertorParams.lastRowOffset = (JPEG_ConvertorParams.endY % MCU_HEIGHT_PIXELS) == 0 ? 0 : MCU_HEIGHT_PIXELS - (JPEG_ConvertorParams.endY % MCU_HEIGHT_PIXELS);
FrameBufferWidth = framebuffer_width;
FrameBufferAddress = frameBuffer;
JPEG_Decode_DMA(&hjpeg, const_cast<uint8_t*>(mjpgdata), length, frameBuffer);
DMA2D_reference = dma;
do
{
JpegProcessing_End = JPEG_OutputHandler(&hjpeg);
/* If nothing to do, wait */
if (JpegProcessing_End == 2)
{
SEM_WAIT(semDecodingDone);
}
} while (JpegProcessing_End != 1);
/* reset flag */
Jpeg_HWDecodingEnd = 0;
DMA2D_CopyBufferEnd = 0;
return true;
}
bool HardwareMJPEGDecoder::decodeThumbnail(uint32_t frameno, uint8_t* buffer, uint16_t width, uint16_t height)
{
assert(0);
return false;
}
void HardwareMJPEGDecoder::gotoFrame(uint32_t frameNumber)
{
if (frameNumber == 0)
{
frameNumber = 1;
}
if (frameNumber > getNumberOfFrames())
{
frameNumber = getNumberOfFrames();
}
uint32_t offset = indexOffset + 8 + (frameNumber - 1) * 16;
readData(offset, 16);
currentMovieOffset = getU32(offset + 8) + firstFrameOffset - 4;
this->frameNumber = frameNumber;
}
uint32_t HardwareMJPEGDecoder::getNumberOfFrames()
{
return videoInfo.number_of_frames;
}
void HardwareMJPEGDecoder::setRepeatVideo(bool repeat)
{
}
void HardwareMJPEGDecoder::getVideoInfo(touchgfx::VideoInformation* data)
{
*data = videoInfo;
}
/* C HELPER FUNCTIONS */
extern "C"
{
/**
* @brief Decode_DMA
* @param hjpeg: JPEG handle pointer
* @param JPEGImageBufferAddress : jpg image buffer Address.
* @param JPEGImageSize_Bytes : jpg image size in bytes.
* @param DestAddress : ARGB8888 destination Frame Buffer Address.
* @retval None
*/
uint32_t JPEG_Decode_DMA(JPEG_HandleTypeDef* hjpeg, uint8_t* input, uint32_t chunkSizeIn /* length */, uint8_t* output)
{
JPEG_output_is_paused = 0;
JPEG_OUT_Read_BufferIndex = 0;
JPEG_OUT_Write_BufferIndex = 0;
JPEG_InputImageIndex = 0;
JPEG_InputImageAddress = (uint32_t)input;
JPEG_InputImageSize_Bytes = chunkSizeIn;
MCU_BlockIndex = 0;
line_count = 0;
/* Init buffers */
for (uint32_t i = 0; i < NB_OUTPUT_DATA_BUFFERS; ++i)
{
Jpeg_OUT_BufferTab[i].State = JPEG_BUFFER_EMPTY;
Jpeg_OUT_BufferTab[i].DataBufferSize = 0;
Jpeg_OUT_BufferTab[i].MCU_index = 0;
Jpeg_OUT_BufferTab[i].OutputBuffer = NULL;
Jpeg_OUT_BufferTab[i].MCU_drawn = 0;
Jpeg_OUT_BufferTab[i].DoCropping = false;
Jpeg_OUT_BufferTab[i].FirstJob = false;
Jpeg_OUT_BufferTab[i].LastJob = false;
}
Jpeg_OUT_BufferTab[0].FirstJob = true;
if (JPEG_ConvertorParams.firstRowOffset != 0)
{
Jpeg_OUT_BufferTab[0].DoCropping = true;
}
/* Do not return from this function until done with decoding all chunks. */
HAL_JPEG_Decode_DMA(hjpeg, input, CHUNK_SIZE_IN, Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].DataBuffer, MCU_CHROMA_420_SIZE_BYTES * JPEG_ConvertorParams.MCU_pr_line);
return 0;
}
/**
* @brief JPEG Info ready callback
* @param hjpeg: JPEG handle pointer
* @param pInfo: JPEG Info Struct pointer
* @retval None
*/
void HAL_JPEG_InfoReadyCallback(JPEG_HandleTypeDef* hjpeg, JPEG_ConfTypeDef* pInfo)
{
uint32_t hMCU, vMCU;
if (pInfo->ChromaSubsampling == JPEG_420_SUBSAMPLING)
{
if ((pInfo->ImageWidth % 16) != 0)
{
pInfo->ImageWidth += (16 - (pInfo->ImageWidth % 16));
}
if ((pInfo->ImageHeight % 16) != 0)
{
pInfo->ImageHeight += (16 - (pInfo->ImageHeight % 16));
}
hMCU = (pInfo->ImageWidth / MCU_WIDTH_PIXELS);
vMCU = (pInfo->ImageHeight / MCU_HEIGHT_PIXELS);
MCU_TotalNb = (hMCU * vMCU);
}
else
{
if (pInfo->ChromaSubsampling == JPEG_422_SUBSAMPLING)
{
if ((pInfo->ImageWidth % 16) != 0)
{
pInfo->ImageWidth += (16 - (pInfo->ImageWidth % 16));
}
if ((pInfo->ImageHeight % 8) != 0)
{
pInfo->ImageHeight += (8 - (pInfo->ImageHeight % 8));
}
}
if (pInfo->ChromaSubsampling == JPEG_444_SUBSAMPLING)
{
if ((pInfo->ImageWidth % 8) != 0)
{
pInfo->ImageWidth += (8 - (pInfo->ImageWidth % 8));
}
if ((pInfo->ImageHeight % 8) != 0)
{
pInfo->ImageHeight += (8 - (pInfo->ImageHeight % 8));
}
}
}
}
/**
* @brief JPEG Get Data callback.
* @param hjpeg: JPEG handle pointer
* @param NbDecodedData: Number of decoded (consummed) bytes from input buffer
* @retval None
*/
void HAL_JPEG_GetDataCallback(JPEG_HandleTypeDef* hjpeg, uint32_t NbDecodedData)
{
/* Input buffer has been consumed by the peripheral and to ask for a new data chunk if the operation (encoding/decoding) has not been complete yet. */
JPEG_InputImageIndex += NbDecodedData;
if (JPEG_InputImageIndex < JPEG_InputImageSize_Bytes)
{
JPEG_InputImageAddress = JPEG_InputImageAddress + NbDecodedData;
uint32_t inDataLength = JPEG_InputImageSize_Bytes - JPEG_InputImageIndex;
HAL_JPEG_ConfigInputBuffer(hjpeg, (uint8_t*)JPEG_InputImageAddress, inDataLength >= CHUNK_SIZE_IN ? CHUNK_SIZE_IN : inDataLength);
}
}
/**
* @brief JPEG Data Ready callback. Data has been converted from JPEG to YCbCr.
* @param hjpeg: JPEG handle pointer
* @param pDataOut: pointer to the output data buffer
* @param OutDataLength: length of output buffer in bytes
* @retval None
*/
void HAL_JPEG_DataReadyCallback(JPEG_HandleTypeDef* hjpeg, uint8_t* pDataOut, uint32_t OutDataLength)
{
line_count += MCU_HEIGHT_PIXELS;
Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].OutputBuffer = FrameBufferAddress;
/* Increment framebuffer */
FrameBufferAddress += FrameBufferWidth * MCU_HEIGHT_PIXELS * JPEG_ConvertorParams.bytes_pr_pixel;
/* Decode until we reach area to draw */
if (line_count <= JPEG_ConvertorParams.startY)
{
HAL_JPEG_ConfigOutputBuffer(hjpeg, Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].DataBuffer, MCU_CHROMA_420_SIZE_BYTES * JPEG_ConvertorParams.MCU_pr_line);
return;
}
Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].State = JPEG_BUFFER_FULL;
Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].DataBufferSize = OutDataLength;
Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].MCU_drawn = 0;
/* Left column requires cropping */
if (JPEG_ConvertorParams.firstColOffset != 0)
{
Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].DoCropping = true;
}
if (line_count < JPEG_ConvertorParams.endY)
{
Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].LastJob = false;
JPEG_OUT_Write_BufferIndex++;
if (JPEG_OUT_Write_BufferIndex >= NB_OUTPUT_DATA_BUFFERS)
{
JPEG_OUT_Write_BufferIndex = 0;
}
/* if the other buffer is full, then ui thread might be converting it */
if (Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].State != JPEG_BUFFER_EMPTY)
{
HAL_JPEG_Pause(hjpeg, JPEG_PAUSE_RESUME_OUTPUT);
JPEG_output_is_paused = 1;
}
HAL_JPEG_ConfigOutputBuffer(hjpeg, Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].DataBuffer, MCU_CHROMA_420_SIZE_BYTES * JPEG_ConvertorParams.MCU_pr_line);
}
/* Stop decoding when we exit area to draw */
if (line_count >= JPEG_ConvertorParams.endY)
{
Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].LastJob = true;
Jpeg_HWDecodingEnd = 1;
HAL_JPEG_Pause(hjpeg, JPEG_PAUSE_RESUME_OUTPUT);
}
/* Signal Hardware Decoding to wake up */
if (!DMA2D_reference->isDMARunning())
{
SEM_POST(semDecodingDone);
}
}
/**
* @brief JPEG Error callback
* @param hjpeg: JPEG handle pointer
* @retval None
*/
void HAL_JPEG_ErrorCallback(JPEG_HandleTypeDef* hjpeg)
{
__disable_irq();
while (1)
{
}
}
/**
* @brief JPEG Decode complete callback
* @param hjpeg: JPEG handle pointer
* @retval None
*/
void HAL_JPEG_DecodeCpltCallback(JPEG_HandleTypeDef* hjpeg)
{
Jpeg_HWDecodingEnd = 1;
}
}
/**
* @brief JPEG Ouput Data BackGround Postprocessing .
* @param hjpeg: JPEG handle pointer
* @retval 1 : if JPEG processing has finished, 0 : if JPEG processing still ongoing
*/
uint32_t JPEG_OutputHandler(JPEG_HandleTypeDef* hjpeg)
{
/* Decode frame complete */
if (Jpeg_HWDecodingEnd && DMA2D_CopyBufferEnd)
{
/* Abort any ongoing operations */
if (HAL_JPEG_GetState(hjpeg) == HAL_JPEG_STATE_BUSY_DECODING)
{
HAL_JPEG_Abort(hjpeg);
}
return 1;
}
/* Try to start DMA2D video transfer if next buffer if full */
if (!DMA2D_reference->isDMARunning() && (Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex].State == JPEG_BUFFER_FULL) && (DMA2D_CopyBufferEnd == 0))
{
DMA2D_reference->start();
}
/* Start JPEG IP if paused and next buffer is empty */
if ((JPEG_output_is_paused == 1) && (Jpeg_OUT_BufferTab[JPEG_OUT_Write_BufferIndex].State == JPEG_BUFFER_EMPTY) && (Jpeg_HWDecodingEnd == 0))
{
JPEG_output_is_paused = 0;
HAL_JPEG_Resume(hjpeg, JPEG_PAUSE_RESUME_OUTPUT);
}
return 2;
}
/**
* @brief Configures external DMA2D job to copy YCbCr data to RGB buffer(s)
* @param job: External job reference
* @retval None
*/
void DMA2D_CopyBuffer(JPEG_Data_BufferTypeDef& job)
{
const uint32_t width = JPEG_ConvertorParams.MCU_pr_job * MCU_WIDTH_PIXELS - job.MCU_drawn * MCU_WIDTH_PIXELS - JPEG_ConvertorParams.lastColOffset;
const uint32_t scaledWidth = (width % MCU_WIDTH_PIXELS) == 0 ? 0 : MCU_WIDTH_PIXELS - (width % MCU_WIDTH_PIXELS);
const uint32_t srcOffset = (JPEG_ConvertorParams.MCUStart + job.MCU_drawn) * MCU_CHROMA_420_SIZE_BYTES;
const uint32_t dstOffset = JPEG_ConvertorParams.MCUStart * MCU_WIDTH_PIXELS * JPEG_ConvertorParams.bytes_pr_pixel
+ job.MCU_drawn * MCU_WIDTH_PIXELS * JPEG_ConvertorParams.bytes_pr_pixel;
/* Mark job as fully drawn */
job.MCU_drawn = JPEG_ConvertorParams.MCU_pr_job;
/* DMA2D OPFCCR register configuration */
WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565);
/* Configure DMA2D data size */
if (job.LastJob) /* Last line of frame */
{
WRITE_REG(DMA2D->NLR, (MCU_HEIGHT_PIXELS - JPEG_ConvertorParams.lastRowOffset) | (width << DMA2D_NLR_PL_Pos));
}
else
{
WRITE_REG(DMA2D->NLR, MCU_HEIGHT_PIXELS | (width << DMA2D_NLR_PL_Pos));
}
/* Configure DMA2D destination address */
WRITE_REG(DMA2D->OMAR, reinterpret_cast<uint32_t>(job.OutputBuffer + dstOffset));
/* DMA2D OOR register configuration */
WRITE_REG(DMA2D->OOR, FrameBufferWidth - width);
/* DMA2D FGOR register configuration */
WRITE_REG(DMA2D->FGOR, scaledWidth);
/* DMA2D FGPFCCR register configuration */
WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_YCBCR | (DMA2D_CSS_420 << DMA2D_FGPFCCR_CSS_Pos) | (DMA2D_REPLACE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (0xFFU << DMA2D_FGPFCCR_ALPHA_Pos));
/* Configure DMA2D source address */
WRITE_REG(DMA2D->FGMAR, reinterpret_cast<uint32_t>(job.DataBuffer + srcOffset));
/* Configure DMA2D contol register */
WRITE_REG(DMA2D->CR, DMA2D_M2M_PFC | DMA2D_IT_TC | DMA2D_CR_START | DMA2D_IT_CE | DMA2D_IT_TE);
}
/**
* @brief Configures external DMA2D job to copy and crop YCbCr data to an RGB cropping buffer
* @param job: External job reference
* @retval None
*/
void DMA2D_CropBuffer(JPEG_Data_BufferTypeDef& job)
{
const uint32_t colLeftOffset = job.MCU_drawn == 0 ? JPEG_ConvertorParams.firstColOffset : 0;
const uint32_t colRightOffset = job.MCU_drawn == JPEG_ConvertorParams.MCU_pr_job - 1 ? JPEG_ConvertorParams.lastColOffset : 0;
const uint32_t rowTopOffset = job.FirstJob ? JPEG_ConvertorParams.firstRowOffset : 0;
const uint32_t rowBottomOffset = job.LastJob ? JPEG_ConvertorParams.lastRowOffset : 0;
const uint32_t srcOffset = (JPEG_ConvertorParams.MCUStart + job.MCU_drawn) * MCU_CHROMA_420_SIZE_BYTES;
const uint32_t dstOffset = JPEG_ConvertorParams.MCUStart * MCU_WIDTH_PIXELS * JPEG_ConvertorParams.bytes_pr_pixel
+ job.MCU_drawn * MCU_WIDTH_PIXELS * JPEG_ConvertorParams.bytes_pr_pixel
+ rowTopOffset * JPEG_ConvertorParams.bytes_pr_pixel * FrameBufferWidth
+ colLeftOffset * JPEG_ConvertorParams.bytes_pr_pixel;
const uint32_t cropSrcOffset = colLeftOffset * JPEG_ConvertorParams.bytes_pr_pixel
+ rowTopOffset * JPEG_ConvertorParams.bytes_pr_pixel * MCU_HEIGHT_PIXELS;
/* Update job and assert if more cropping is needed */
job.MCU_drawn++;
if ((JPEG_ConvertorParams.firstRowOffset == 0) || !job.FirstJob)
{
job.DoCropping = false;
}
/* Configure BlitOp */
touchgfx::BlitOp blitOp;
blitOp.operation = touchgfx::BLIT_OP_COPY;
blitOp.pSrc = reinterpret_cast<uint16_t*>(MCU_Cropping_Buffer + cropSrcOffset);
blitOp.nSteps = MCU_WIDTH_PIXELS - colLeftOffset - colRightOffset;
blitOp.nLoops = MCU_HEIGHT_PIXELS - rowTopOffset - rowBottomOffset;
blitOp.srcLoopStride = MCU_WIDTH_PIXELS;
blitOp.dstLoopStride = FrameBufferWidth;
blitOp.pDst = reinterpret_cast<uint16_t*>(job.OutputBuffer + dstOffset);
blitOp.srcFormat = touchgfx::Bitmap::RGB565;
blitOp.dstFormat = touchgfx::Bitmap::RGB565;
DMA2D_reference->addToQueue(blitOp);
/* DMA2D OPFCCR register configuration */
WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565);
/* Configure DMA2D data size */
WRITE_REG(DMA2D->NLR, MCU_HEIGHT_PIXELS | (MCU_WIDTH_PIXELS << DMA2D_NLR_PL_Pos));
/* Configure DMA2D destination address */
WRITE_REG(DMA2D->OMAR, reinterpret_cast<uint32_t>(MCU_Cropping_Buffer));
/* DMA2D OOR register configuration */
WRITE_REG(DMA2D->OOR, 0);
/* DMA2D FGOR register configuration */
WRITE_REG(DMA2D->FGOR, 0);
/* DMA2D FGPFCCR register configuration */
WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_YCBCR | (DMA2D_CSS_420 << DMA2D_FGPFCCR_CSS_Pos) | (DMA2D_REPLACE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (0xFFU << DMA2D_FGPFCCR_ALPHA_Pos));
/* Configure DMA2D source address */
WRITE_REG(DMA2D->FGMAR, reinterpret_cast<uint32_t>(job.DataBuffer + srcOffset));
/* Configure DMA2D contol register */
WRITE_REG(DMA2D->CR, DMA2D_M2M_PFC | DMA2D_IT_TC | DMA2D_CR_START | DMA2D_IT_CE | DMA2D_IT_TE);
}
/**
* @brief External DMA2D job complete callback
* @param job: External job reference
* @retval None
*/
void DMA2D_ExternalJobCompleted(JPEG_Data_BufferTypeDef& job)
{
/* Mark job done if all MCUs are drawn */
if (job.MCU_drawn == JPEG_ConvertorParams.MCU_pr_job)
{
job.State = JPEG_BUFFER_EMPTY;
job.DataBufferSize = 0;
job.DoCropping = false;
job.FirstJob = false;
JPEG_OUT_Read_BufferIndex++;
if (JPEG_OUT_Read_BufferIndex >= NB_OUTPUT_DATA_BUFFERS)
{
JPEG_OUT_Read_BufferIndex = 0;
}
/* Check if last line */
if (job.LastJob)
{
DMA2D_CopyBufferEnd = 1;
}
/* Signal decoder thread to wake up and continue decoding */
SEM_POST(semDecodingDone);
}
}
@@ -0,0 +1,107 @@
/**
******************************************************************************
* File Name : HardwareMJPEGDecoder.hpp
******************************************************************************
* This file is generated by TouchGFX Generator 4.26.1. Please, do not edit!
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
#ifndef TOUCHGFX_HARDWAREMJPEGDECODER_HPP
#define TOUCHGFX_HARDWAREMJPEGDECODER_HPP
#include <MJPEGDecoder.hpp>
#include <STM32DMA.hpp>
#include "cmsis_os2.h"
#if defined(osCMSIS) && (osCMSIS < 0x20000)
#define MUTEX_CREATE() osMutexCreate(0)
#define MUTEX_LOCK(m) osMutexWait(m, osWaitForever)
#define MUTEX_TYPE osMutexId
#define MUTEX_UNLOCK(m) osMutexRelease(m)
#define SEM_CREATE() osSemaphoreCreate(0, 1)
#define SEM_POST(s) osSemaphoreRelease(s)
#define SEM_TYPE osSemaphoreId
#define SEM_WAIT(s) osSemaphoreWait(s, osWaitForever)
#else
#define MUTEX_CREATE() osMutexNew(0)
#define MUTEX_LOCK(m) osMutexAcquire(m, osWaitForever)
#define MUTEX_TYPE osMutexId_t
#define MUTEX_UNLOCK(m) osMutexRelease(m)
#define SEM_CREATE() osSemaphoreNew(1, 0, 0)
#define SEM_POST(s) osSemaphoreRelease(s)
#define SEM_TYPE osSemaphoreId_t
#define SEM_WAIT(s) osSemaphoreAcquire(s, osWaitForever)
#endif
class HardwareMJPEGDecoder : public MJPEGDecoder
{
public:
HardwareMJPEGDecoder();
//Set video data for the decoder
virtual void setVideoData(const uint8_t* movie, const uint32_t length);
virtual void setVideoData(touchgfx::VideoDataReader& reader);
virtual bool hasVideo();
//Increment position to next frame and decode
virtual bool decodeNextFrame(uint8_t* frameBuffer, uint16_t width, uint16_t height, uint32_t framebuffer_width);
//Increment position to next frame and decode
virtual bool gotoNextFrame();
//Decode part of the current frame
virtual bool decodeFrame(const touchgfx::Rect& area, uint8_t* frameBuffer, uint32_t framebuffer_width);
virtual bool decodeThumbnail(uint32_t frameno, uint8_t* buffer, uint16_t width, uint16_t height);
virtual void gotoFrame(uint32_t frameno);
virtual uint32_t getCurrentFrameNumber() const
{
return frameNumber;
}
virtual uint32_t getNumberOfFrames();
virtual void setRepeatVideo(bool repeat);
virtual void getVideoInfo(touchgfx::VideoInformation* data);
void setAVIFileBuffer(uint8_t* buffer, uint32_t size)
{
aviBuffer = buffer, aviBufferLength = size;
}
virtual AVIErrors getLastError()
{
return lastError;
}
void addDMA(touchgfx::DMA_Interface& dma)
{
this->dma = &dma;
}
private:
void readVideoHeader();
void decodeMJPEGFrame(const uint8_t* const mjpgdata, const uint32_t length, uint8_t* buffer, uint16_t width, uint16_t height, uint32_t stride);
int compare(const uint32_t offset, const char* str, uint32_t num);
uint32_t getU32(const uint32_t offset);
uint32_t getU16(const uint32_t offset);
const uint8_t* readData(uint32_t offset, uint32_t length);
touchgfx::VideoInformation videoInfo;
uint32_t frameNumber;
uint32_t currentMovieOffset;
uint32_t indexOffset;
uint32_t firstFrameOffset;
uint32_t lastFrameEnd;
uint32_t movieLength;
const uint8_t* movieData;
touchgfx::VideoDataReader* reader;
uint8_t* aviBuffer;
uint32_t aviBufferLength;
uint32_t aviBufferStartOffset;
AVIErrors lastError;
touchgfx::DMA_Interface* dma;
};
#endif // TOUCHGFX_HARDWAREMJPEGDECODER_HPP
@@ -0,0 +1,89 @@
/**
******************************************************************************
* File Name : MJPEGDecoder.hpp
******************************************************************************
* This file is generated by TouchGFX Generator 4.26.1. Please, do not edit!
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
#ifndef TOUCHGFX_MJPEGDECODER_HPP
#define TOUCHGFX_MJPEGDECODER_HPP
#include <touchgfx/hal/Types.hpp>
#include <touchgfx/hal/VideoController.hpp>
class MJPEGDecoder
{
public:
virtual ~MJPEGDecoder()
{
}
//Set video data for the decoder
virtual void setVideoData(const uint8_t* movie, const uint32_t length) = 0;
//Set video data for the decoder
virtual void setVideoData(touchgfx::VideoDataReader& reader) = 0;
/**
* Check if MJPEGDecoder has a video.
*
* @return Returns true if the MJPEGDecoder has a video.
*/
virtual bool hasVideo() = 0;
//Increment position to next frame and decode and convert to RGB
virtual bool decodeNextFrame(uint8_t* buffer, uint16_t width, uint16_t height, uint32_t stride) = 0;
//Increment position to next frame and decode. Used with decodeFrame.
virtual bool gotoNextFrame() = 0;
//Decode part of the current frame, framebuffer is locked, area is drawn relative to frameBuffer
virtual bool decodeFrame(const touchgfx::Rect& area, uint8_t* frameBuffer, uint32_t framebufferStride) = 0;
//Decode thumbnail, assumes buffer stride is width
virtual bool decodeThumbnail(uint32_t frameno, uint8_t* buffer, uint16_t width, uint16_t height) = 0;
//Set current frame number
virtual void gotoFrame(uint32_t frameno) = 0;
//Get current frame number
virtual uint32_t getCurrentFrameNumber() const = 0;
//Get number of frames in video
virtual uint32_t getNumberOfFrames() = 0;
//Read video information
virtual void getVideoInfo(touchgfx::VideoInformation* data) = 0;
enum AVIErrors
{
AVI_NO_ERROR,
AVI_NO_BUFFERS,
AVI_NO_FILE,
AVI_ERROR_NOT_RIFF,
AVI_ERROR_AVI_HEADER_NOT_FOUND,
AVI_ERROR_AVI_LIST_NOT_FOUND,
AVI_ERROR_AVI_HDRL_NOT_FOUND,
AVI_ERROR_AVI_AVIH_NOT_FOUND,
AVI_ERROR_AVI_HEADER_TO_SHORT, //not full header provided
AVI_ERROR_FILE_BUFFER_TO_SMALL,
AVI_ERROR_MOVI_NOT_FOUND,
AVI_ERROR_IDX1_NOT_FOUND,
AVI_ERROR_FRAMENO_TO_HIGH,
AVI_ERROR_EOF_REACHED
};
AVIErrors virtual getLastError() = 0;
};
#endif // TOUCHGFX_MJPEGDECODER_HPP
@@ -0,0 +1,156 @@
/**
******************************************************************************
* File Name : OSWrappers.cpp
******************************************************************************
* This file is generated by TouchGFX Generator 4.26.1. Please, do not edit!
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
#include <touchgfx/hal/HAL.hpp>
#include <touchgfx/hal/OSWrappers.hpp>
#include <cmsis_os2.h>
#include <cassert>
static osSemaphoreId_t frame_buffer_sem = NULL;
static osMessageQueueId_t vsync_queue = NULL;
// Just a dummy value to insert in the VSYNC queue.
static uint32_t dummy = 0x5a;
using namespace touchgfx;
/*
* Initialize frame buffer semaphore and queue/mutex for VSYNC signal.
*/
void OSWrappers::initialize()
{
// Create a queue of length 1
frame_buffer_sem = osSemaphoreNew(1, 1, NULL); // Binary semaphore
assert((frame_buffer_sem != NULL) && "Creation of framebuffer semaphore failed");
// Create a queue of length 1
vsync_queue = osMessageQueueNew(1, 4, NULL);
assert((vsync_queue != NULL) && "Creation of vsync message queue failed");
}
/*
* Take the frame buffer semaphore. Blocks until semaphore is available.
*/
void OSWrappers::takeFrameBufferSemaphore()
{
osSemaphoreAcquire(frame_buffer_sem, osWaitForever);
}
/*
* Release the frame buffer semaphore.
*/
void OSWrappers::giveFrameBufferSemaphore()
{
osSemaphoreRelease(frame_buffer_sem);
}
/*
* Attempt to obtain the frame buffer semaphore. If semaphore is not available, do
* nothing.
*
* Note must return immediately! This function does not care who has the taken the semaphore,
* it only serves to make sure that the semaphore is taken by someone.
*/
void OSWrappers::tryTakeFrameBufferSemaphore()
{
osSemaphoreAcquire(frame_buffer_sem, 0);
}
/*
* Release the frame buffer semaphore in a way that is safe in interrupt context. Called
* from ISR.
*
* Release the frame buffer semaphore in a way that is safe in interrupt context.
* Called from ISR.
*/
void OSWrappers::giveFrameBufferSemaphoreFromISR()
{
osSemaphoreRelease(frame_buffer_sem);
}
/*
* Signal that a VSYNC has occurred. Should make the vsync queue/mutex available.
*
* Note This function is called from an ISR, and should (depending on OS) trigger a
* scheduling.
*/
void OSWrappers::signalVSync()
{
osMessageQueuePut(vsync_queue, &dummy, 0, 0);
}
/*
* Signal that the rendering of the frame has completed. Used by
* some systems to avoid using any previous vsync.
*/
void OSWrappers::signalRenderingDone()
{
// Empty implementation for CMSIS V2
}
/*
* This function blocks until a VSYNC occurs.
*
* Note This function must first clear the mutex/queue and then wait for the next one to
* occur.
*/
void OSWrappers::waitForVSync()
{
uint32_t dummyGet;
// First make sure the queue is empty, by trying to remove an element with 0 timeout.
osMessageQueueGet(vsync_queue, &dummyGet, 0, 0);
// Then, wait for next VSYNC to occur.
osMessageQueueGet(vsync_queue, &dummyGet, 0, osWaitForever);
}
/*
* A function that causes executing task to sleep for a number of milliseconds.
*
* A function that causes executing task to sleep for a number of milliseconds.
* This function is OPTIONAL. It is only used by the TouchGFX in the case of
* a specific frame refresh strategy (REFRESH_STRATEGY_OPTIM_SINGLE_BUFFER_TFT_CTRL).
* Due to backwards compatibility, in order for this function to be useable by the HAL
* the function must be explicitly registered:
* hal.registerTaskDelayFunction(&OSWrappers::taskDelay)
*
* see HAL::setFrameRefreshStrategy(FrameRefreshStrategy s)
* see HAL::registerTaskDelayFunction(void (*delayF)(uint16_t))
*/
void OSWrappers::taskDelay(uint16_t ms)
{
osDelay(static_cast<uint32_t>(ms));
}
/**
* A function that causes the executing task to yield control to
* another thread. This function is used by the framework when it
* is necessary to wait a little before continuing (e.g. drawing).
*
* The implementation should typically request the operating
* system to change to another task of similar priority. When
* running without an operating system, the implementation can run
* a very short task and return.
*/
void OSWrappers::taskYield()
{
osThreadYield();
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,263 @@
/**
******************************************************************************
* File Name : STM32DMA.hpp
******************************************************************************
* This file is generated by TouchGFX Generator 4.26.1. Please, do not edit!
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
#ifndef STM32DMA_HPP
#define STM32DMA_HPP
#include <touchgfx/Bitmap.hpp>
#include <touchgfx/hal/DMA.hpp>
#define JPEG_BUFFER_EMPTY 0
#define JPEG_BUFFER_FULL 1
#define NB_OUTPUT_DATA_BUFFERS 2
extern volatile uint32_t JPEG_OUT_Read_BufferIndex;
extern volatile uint32_t DMA2D_CopyBufferEnd;
typedef struct
{
uint8_t State;
uint8_t* DataBuffer;
uint32_t DataBufferSize;
uint32_t MCU_index;
uint8_t* OutputBuffer;
bool FirstJob;
bool LastJob;
uint32_t MCU_drawn;
bool DoCropping;
} JPEG_Data_BufferTypeDef;
extern JPEG_Data_BufferTypeDef Jpeg_OUT_BufferTab[NB_OUTPUT_DATA_BUFFERS];
extern "C" void DMA2D_CropBuffer(JPEG_Data_BufferTypeDef& job);
extern "C" void DMA2D_CopyBuffer(JPEG_Data_BufferTypeDef& job);
extern "C" void DMA2D_ExternalJobCompleted(JPEG_Data_BufferTypeDef& job);
/**
* @class STM32DMA
*
* @brief This class specializes DMA_Interface for the STM32 processors.
*
* @sa touchgfx::DMA_Interface
*/
class STM32DMA : public touchgfx::DMA_Interface
{
/**
* @typedef touchgfx::DMA_Interface Base
*
* @brief Defines an alias representing the base.
*
Defines an alias representing the base.
*/
typedef touchgfx::DMA_Interface Base;
public:
/**
* @fn STM32DMA::STM32DMA();
*
* @brief Default constructor.
*
* Default constructor.
*/
STM32DMA();
/**
* @fn STM32DMA::~STM32DMA();
*
* @brief Destructor.
*
* Destructor.
*/
virtual ~STM32DMA();
/**
* @fn DMAType touchgfx::STM32DMA::getDMAType()
*
* @brief Function for obtaining the DMA type of the concrete DMA_Interface implementation.
*
* Function for obtaining the DMA type of the concrete DMA_Interface implementation.
* As default, will return DMA_TYPE_CHROMART type value.
*
* @return a DMAType value of the concrete DMA_Interface implementation.
*/
virtual touchgfx::DMAType getDMAType(void)
{
return touchgfx::DMA_TYPE_CHROMART;
}
/**
* @fn touchgfx::BlitOperations STM32DMA::getBlitCaps();
*
* @brief Gets the blit capabilities.
*
* Gets the blit capabilities.
*
* This DMA supports a range of blit caps: BLIT_OP_COPY, BLIT_OP_COPY_ARGB8888,
* BLIT_OP_COPY_ARGB8888_WITH_ALPHA, BLIT_OP_COPY_A4, BLIT_OP_COPY_A8.
*
*
* @return Currently supported blitcaps.
*/
virtual touchgfx::BlitOperations getBlitCaps();
/**
* @fn void STM32DMA::initialize();
*
* @brief Perform hardware specific initialization.
*
* Perform hardware specific initialization.
*/
virtual void initialize();
/**
* @fn void STM32DMA::signalDMAInterrupt()
*
* @brief Raises a DMA interrupt signal.
*
* Raises a DMA interrupt signal.
*/
virtual void signalDMAInterrupt()
{
if (!started_by_external_job)
{
executeCompleted();
/* Start new external job if next buffer is full */
if (Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex].State == JPEG_BUFFER_FULL && !DMA2D_CopyBufferEnd && !isRunning)
{
started_by_external_job = true;
externalJobExecute();
}
}
else
{
externalJobCompleted();
/* Prioritize BlitOps if there are any pending */
if (!queue.isEmpty() && isAllowed)
{
started_by_external_job = false;
execute();
}
}
}
virtual void start()
{
if (!queue.isEmpty() && isAllowed && !isRunning)
{
started_by_external_job = false;
execute();
}
else if ((Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex].State == JPEG_BUFFER_FULL) && !isRunning)
{
started_by_external_job = true;
externalJobExecute();
}
}
protected:
/**
* @fn virtual void STM32DMA::setupDataCopy(const touchgfx::BlitOp& blitOp);
*
* @brief Configures the DMA for copying data to the frame buffer.
*
* Configures the DMA for copying data to the frame buffer.
*
* @param blitOp Details on the copy to perform.
*/
virtual void setupDataCopy(const touchgfx::BlitOp& blitOp);
/**
* @fn virtual void STM32DMA::setupDataFill(const touchgfx::BlitOp& blitOp);
*
* @brief Configures the DMA for "filling" the frame-buffer with a single color.
*
* Configures the DMA for "filling" the frame-buffer with a single color.
*
* @param blitOp Details on the "fill" to perform.
*/
virtual void setupDataFill(const touchgfx::BlitOp& blitOp);
/**
* @fn void STM32DMA::externalJobCompleted();
*
* @brief Handle DMA2D when an external job has been executed
*
* @param None
*/
void externalJobCompleted()
{
if (isRunning)
{
isRunning = false;
DMA2D_ExternalJobCompleted(Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex]);
}
}
/**
* @fn void STM32DMA::externalJobExecute();
*
* @brief Executes an external DMA2D job
*
* @param None
*/
void externalJobExecute()
{
isRunning = true;
if (Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex].DoCropping)
{
DMA2D_CropBuffer(Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex]);
}
else
{
DMA2D_CopyBuffer(Jpeg_OUT_BufferTab[JPEG_OUT_Read_BufferIndex]);
}
}
private:
touchgfx::LockFreeDMA_Queue dma_queue;
touchgfx::BlitOp queue_storage[96];
bool started_by_external_job;
/**
* @fn void STM32DMA::getChromARTInputFormat()
*
* @brief Convert Bitmap format to ChromART Input format.
*
* @param format Bitmap format.
*
* @return ChromART Input format.
*/
inline uint32_t getChromARTInputFormat(touchgfx::Bitmap::BitmapFormat format);
/**
* @fn void STM32DMA::getChromARTOutputFormat()
*
* @brief Convert Bitmap format to ChromART Output format.
*
* @param format Bitmap format.
*
* @return ChromART Output format.
*/
inline uint32_t getChromARTOutputFormat(touchgfx::Bitmap::BitmapFormat format);
};
#endif // STM32DMA_HPP
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,95 @@
/**
******************************************************************************
* File Name : TouchGFXConfiguration.cpp
******************************************************************************
* This file is generated by TouchGFX Generator 4.26.1. Please, do not edit!
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
#include <texts/TypedTextDatabase.hpp>
#include <fonts/ApplicationFontProvider.hpp>
#include <gui/common/FrontendHeap.hpp>
#include <BitmapDatabase.hpp>
#include <touchgfx/VectorFontRendererImpl.hpp>
#include <touchgfx_nema/LCDGPU2D_AXI.hpp>
extern "C"
{
#include <nema_hal.h>
#include <nema_vg.h>
}
#include <STM32DMA.hpp>
#include <TouchGFXHAL.hpp>
#include <STM32TouchController.hpp>
#include <stm32h7rsxx_hal.h>
extern "C" void touchgfx_init();
extern "C" void touchgfx_taskEntry();
extern "C" void touchgfx_components_init();
static STM32TouchController tc;
static STM32DMA dma;
static LCDGPU2D_AXI display;
static VectorFontRendererImpl vectorFontRenderer;
static ApplicationFontProvider fontProvider;
static Texts texts;
static TouchGFXHAL hal(dma, display, tc, 800, 480);
void touchgfx_init()
{
Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(), BitmapDatabase::getInstanceSize());
TypedText::registerTexts(&texts);
Texts::setLanguage(0);
display.setFrameBufferFormat(Bitmap::RGB565);
display.setVectorFontRenderer(&vectorFontRenderer);
FontManager::setFontProvider(&fontProvider);
FrontendHeap& heap = FrontendHeap::getInstance();
/*
* we need to obtain the reference above to initialize the frontend heap.
*/
(void)heap;
/*
* Initialize TouchGFX
*/
hal.initialize();
}
void touchgfx_components_init()
{
nema_init();
nema_reg_write(0xFFC, 0x7E); /* Enable bus error interrupts */
nema_vg_init_stencil_pool(800, 480, 1);
nema_vg_handle_large_coords(1, 1);
nema_ext_hold_enable(2);
nema_ext_hold_irq_enable(2);
nema_ext_hold_enable(3);
nema_ext_hold_irq_enable(3);
}
void touchgfx_taskEntry()
{
/*
* Main event loop. Will wait for VSYNC signal, and then process next frame. Call
* this function from your GUI task.
*
* Note This function never returns
*/
hal.taskEntry();
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,222 @@
/**
******************************************************************************
* File Name : TouchGFXGeneratedHAL.cpp
******************************************************************************
* This file is generated by TouchGFX Generator 4.26.1. Please, do not edit!
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
#include <TouchGFXGeneratedHAL.hpp>
#include <touchgfx/hal/OSWrappers.hpp>
#include <gui/common/FrontendHeap.hpp>
#include <touchgfx/hal/GPIO.hpp>
#include <touchgfx_nema/GPU2DVectorRenderer.hpp>
#include <HardwareMJPEGDecoder.hpp>
#include <DirectFrameBufferVideoController.hpp>
#include <stm32h7rsxx_hal.h>
HardwareMJPEGDecoder mjpegdecoder1;
namespace
{
DirectFrameBufferVideoController<1, Bitmap::RGB565> videoController;
}
//Singleton Factory
VideoController& VideoController::getInstance()
{
return videoController;
}
namespace touchgfx
{
VectorRenderer* VectorRenderer::getInstance()
{
static GPU2DVectorRenderer renderer;
return &renderer;
}
} // namespace touchgfx
#include "stm32h7rsxx.h"
#include "stm32h7rsxx_hal_ltdc.h"
using namespace touchgfx;
namespace
{
// Use the section "TouchGFX_Framebuffer" in the linker script to specify the placement of the buffer
LOCATION_PRAGMA_NOLOAD("TouchGFX_Framebuffer")
uint32_t frameBuf[(800 * 480 * 2 + 3) / 4 * 2] LOCATION_ATTRIBUTE_NOLOAD("TouchGFX_Framebuffer");
static uint16_t lcd_int_active_line;
static uint16_t lcd_int_porch_line;
}
void TouchGFXGeneratedHAL::initialize()
{
HALGPU2D::initialize(16384);
registerEventListener(*(Application::getInstance()));
setFrameBufferStartAddresses((void*)frameBuf, (void*)(frameBuf + sizeof(frameBuf) / (sizeof(uint32_t) * 2)), (void*)0);
/*
* Add DMA2D to hardware decoder
*/
mjpegdecoder1.addDMA(dma);
/*
* Add hardware decoder to video controller
*/
videoController.addDecoder(mjpegdecoder1, 0);
}
void TouchGFXGeneratedHAL::configureInterrupts()
{
NVIC_SetPriority(DMA2D_IRQn, 9);
NVIC_SetPriority(LTDC_IRQn, 9);
NVIC_SetPriority(GPU2D_IRQn, 9);
}
void TouchGFXGeneratedHAL::enableInterrupts()
{
NVIC_EnableIRQ(DMA2D_IRQn);
NVIC_EnableIRQ(LTDC_IRQn);
NVIC_EnableIRQ(GPU2D_IRQn);
}
void TouchGFXGeneratedHAL::disableInterrupts()
{
NVIC_DisableIRQ(DMA2D_IRQn);
NVIC_DisableIRQ(LTDC_IRQn);
NVIC_DisableIRQ(GPU2D_IRQn);
}
void TouchGFXGeneratedHAL::enableLCDControllerInterrupt()
{
lcd_int_active_line = (LTDC->BPCR & LTDC_BPCR_AVBP_Msk) - 1;
lcd_int_porch_line = (LTDC->AWCR & LTDC_AWCR_AAH_Msk) - 1;
/* Sets the Line Interrupt position */
LTDC->LIPCR = lcd_int_active_line;
/* Line Interrupt Enable */
LTDC->IER |= LTDC_IER_LIE;
}
bool TouchGFXGeneratedHAL::beginFrame()
{
return HALGPU2D::beginFrame();
}
void TouchGFXGeneratedHAL::endFrame()
{
HALGPU2D::endFrame();
}
void TouchGFXGeneratedHAL::submitGPU2D()
{
HALGPU2D::submitExecBuffer();
}
uint16_t* TouchGFXGeneratedHAL::getTFTFrameBuffer() const
{
return (uint16_t*)LTDC_Layer1->CFBAR;
}
void TouchGFXGeneratedHAL::setTFTFrameBuffer(uint16_t* adr)
{
LTDC_Layer1->CFBAR = (uint32_t)adr;
/* Reload immediate */
LTDC->SRCR = (uint32_t)LTDC_SRCR_IMR;
}
void TouchGFXGeneratedHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
HALGPU2D::flushFrameBuffer(rect);
}
bool TouchGFXGeneratedHAL::blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes)
{
return HALGPU2D::blockCopy(dest, src, numBytes);
}
void TouchGFXGeneratedHAL::InvalidateCache()
{
// Because DMA2D access main memory directly, the DCache must be invalidated
// becuase it could hold a wrong image of the framebuffer. That's done
// using the function SCB_CleanInvalidateDCache(). Remember to enable
// "CPU Cache" in the "System Core" settings for "Cortex M7" in CubeMX
// in order for this function call to work.
if (SCB->CCR & SCB_CCR_DC_Msk)
{
SCB_CleanInvalidateDCache();
}
}
void TouchGFXGeneratedHAL::FlushCache()
{
// If the framebuffer is placed in Write-Back cached memory (e.g. SRAM) then
// the DCache must be flushed prior to DMA2D accessing it. That's done
// using the function SCB_CleanInvalidateDCache(). Remember to enable
// "CPU Cache" in the "System Core" settings for "Cortex M7" in CubeMX in
// order for this function call to work.
if (SCB->CCR & SCB_CCR_DC_Msk)
{
SCB_CleanInvalidateDCache();
}
}
void TouchGFXGeneratedHAL::InvalidateTextureCache()
{
// Hook to invalidate texture cache(s) prior to drawing to a framebuffer.
//
// When drawing into other buffers in RAM (e.g., dynamic bitmaps), the GPU2D
// texture cache may be incoherent with the main memory.
HAL_ICACHE_Invalidate();
}
extern "C"
{
void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef* hltdc)
{
if (!HAL::getInstance())
{
return;
}
if (LTDC->LIPCR == lcd_int_active_line)
{
//entering active area
HAL_LTDC_ProgramLineEvent(hltdc, lcd_int_porch_line);
HAL::getInstance()->vSync();
OSWrappers::signalVSync();
// Swap frame buffers immediately instead of waiting for the task to be scheduled in.
// Note: task will also swap when it wakes up, but that operation is guarded and will not have
// any effect if already swapped.
HAL::getInstance()->swapFrameBuffers();
GPIO::set(GPIO::VSYNC_FREQ);
}
else
{
//exiting active area
HAL_LTDC_ProgramLineEvent(hltdc, lcd_int_active_line);
// Signal to the framework that display update has finished.
HAL::getInstance()->frontPorchEntered();
GPIO::clear(GPIO::VSYNC_FREQ);
}
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,211 @@
/**
******************************************************************************
* File Name : TouchGFXGeneratedHAL.hpp
******************************************************************************
* This file is generated by TouchGFX Generator 4.26.1. Please, do not edit!
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
#ifndef TouchGFXGeneratedHAL_HPP
#define TouchGFXGeneratedHAL_HPP
#include <touchgfx_nema/HALGPU2D.hpp>
/**
* @class TouchGFXGeneratedHAL
*
* @brief HAL implementation for TouchGFXGenerated.
*
* @sa HAL
*/
class TouchGFXGeneratedHAL : public touchgfx::HALGPU2D
{
public:
/**
* @fn TouchGFXGeneratedHAL::TouchGFXGeneratedHAL(touchgfx::DMA_Interface& dma, touchgfx::LCD& display, touchgfx::TouchController& tc, uint16_t width, uint16_t height) : touchgfx::HALGPU2D(dma, display, tc, width, height)
*
* @brief Constructor.
*
* Constructor. Initializes members.
*
* @param [in,out] dma Reference to DMA interface.
* @param [in,out] display Reference to LCD interface.
* @param [in,out] tc Reference to Touch Controller driver.
* @param width Width of the display.
* @param height Height of the display.
*/
TouchGFXGeneratedHAL(touchgfx::DMA_Interface& dma, touchgfx::LCD& display, touchgfx::TouchController& tc, uint16_t width, uint16_t height) :
touchgfx::HALGPU2D(dma, display, tc, width, height)
{
}
/**
* @fn void TouchGFXGeneratedHAL::initialize();
*
* @brief This function is responsible for initializing the entire framework.
*
* This function is responsible for initializing the entire framework.
*/
virtual void initialize();
/**
* @fn virtual void TouchGFXGeneratedHAL::configureInterrupts();
*
* @brief Sets the DMA, LCD, and GPU2D (if enabled) interrupt priorities.
*
* Sets the DMA, LCD, and GPU2D (if enabled) interrupt priorities.
*/
virtual void configureInterrupts();
/**
* @fn virtual void TouchGFXGeneratedHAL::enableInterrupts();
*
* @brief Enables the DMA, LCD, and GPU2D (if enabled) interrupts.
*
* Enables the DMA, LCD, and GPU2D (if enabled) interrupts.
*/
virtual void enableInterrupts();
/**
* @fn virtual void TouchGFXGeneratedHAL::disableInterrupts();
*
* @brief Disables the DMA, LDC, and GPU2D (if enabled) interrupts.
*
* Disables the DMA, LDC, and GPU2D (if enabled) interrupts.
*/
virtual void disableInterrupts();
/**
* @fn virtual void TouchGFXGeneratedHAL::enableLCDControllerInterrupt();
*
* @brief Configure the LCD controller to fire interrupts at VSYNC.
*
* Configure the LCD controller to fire interrupts at VSYNC. Called automatically
* once TouchGFX initialization has completed.
*/
virtual void enableLCDControllerInterrupt();
/**
* @fn virtual void TouchGFXGeneratedHAL::flushFrameBuffer();
*
* @brief This function is called whenever the framework has performed a complete draw.
*
* This specialization is only in place to keep compilers happy. Base impl. will call the
* Rect version.
* @see HAL::flushFrameBuffer
*/
virtual void flushFrameBuffer()
{
HAL::flushFrameBuffer();
}
/**
* @fn virtual void TouchGFXGeneratedHAL::unlockFrameBuffer();
*
* @brief Unlocks the framebuffer.
*
* This specialization is marks DMA2D as un-reserved by the framwork.
* @see HAL::unlockFrameBuffer
*/
virtual void unlockFrameBuffer()
{
HAL::unlockFrameBuffer();
}
/**
* @fn virtual void TouchGFXGeneratedHAL::flushFrameBuffer(const touchgfx::Rect& rect);
*
* @brief This function is called whenever the framework has performed a partial draw.
*
* This function is called whenever the framework has performed a partial draw.
*
* @param rect The area of the screen that has been drawn, expressed in absolute coordinates.
*
* @see flushFrameBuffer().
*/
virtual void flushFrameBuffer(const touchgfx::Rect& rect);
/**
*
* @fn virtual void TouchGFXGeneratedHAL::blockCopy();
*
* This function performs a platform-specific memcpy, if supported by the hardware.
*
* @param [out] dest Pointer to destination memory.
* @param [in] src Pointer to source memory.
* @param numBytes Number of bytes to copy.
*
* @return true if the copy succeeded, false if copy was not performed.
*/
virtual bool blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes);
/**
* @fn virtual void TouchGFXGeneratedHAL::beginFrame();
*
* @brief Called when beginning to rendering a frame.
*
* Called when beginning to rendering a frame.
*
* @return true if rendering can begin, false otherwise.
*/
virtual bool beginFrame();
/**
* @fn virtual void TouchGFXGeneratedHAL::endFrame();
*
* @brief Called when a rendering pass is completed.
*
* Called when a rendering pass is completed.
*/
virtual void endFrame();
/**
* @fn virtual void TouchGFXGeneratedHAL::submitGPU2D();
*
* @brief This function can be used to explicitly submit any GPU2D operations that
* might be queued in the command list. Can be called if e.g. the task is
* about to sleep, to ensure GPU2D operations are running in the background.
*/
virtual void submitGPU2D();
protected:
/**
* @fn virtual uint16_t* TouchGFXGeneratedHAL::getTFTFrameBuffer() const;
*
* @brief Gets the frame buffer address used by the TFT controller.
*
* Gets the frame buffer address used by the TFT controller.
*
* @return The address of the frame buffer currently being displayed on the TFT.
*/
virtual uint16_t* getTFTFrameBuffer() const;
/**
* @fn virtual void TouchGFXGeneratedHAL::setTFTFrameBuffer(uint16_t* adr);
*
* @brief Sets the frame buffer address used by the TFT controller.
*
* Sets the frame buffer address used by the TFT controller.
*
* @param [in,out] adr New frame buffer address.
*/
virtual void setTFTFrameBuffer(uint16_t* adr);
virtual void InvalidateCache();
virtual void FlushCache();
virtual void InvalidateTextureCache();
};
#endif // TouchGFXGeneratedHAL_HPP
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+275
View File
@@ -0,0 +1,275 @@
/**
******************************************************************************
* @file nema_hal.c
* @author MCD Application Team
* @brief NemaGFX Interfaces and Platform Specific APIs with FreeRTOS CMSISV2
* support.
* This file provides NemaGFX functions to manage the following
* functionalities of the NemaGFX library:
* + Initialization and de-initialization functions
* + GPU2D Registers access operation functions
* + Buffer Creation, Destruction, MMAP and Flusing functions
* + Interrupt management functions
* + Memory management functions
* + Locking/Unlocking resources functions
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
#include <touchgfx/hal/Config.hpp>
#include <nema_sys_defs.h>
#include <nema_core.h>
#include <assert.h>
#include <string.h>
#include <stm32h7rsxx_hal.h>
#include <cmsis_os2.h>
#include "tsi_malloc.h"
#define RING_SIZE 1024 /* Ring Buffer Size in byte */
#define NEMAGFX_MEM_POOL_SIZE 24320 /* NemaGFX byte pool size in byte */
#define NEMAGFX_STENCIL_POOL_SIZE 389120 /* NemaGFX stencil buffer pool size in byte */
LOCATION_PRAGMA_NOLOAD("Nemagfx_Memory_Pool_Buffer")
static uint8_t nemagfx_pool_mem[NEMAGFX_MEM_POOL_SIZE] LOCATION_ATTRIBUTE_NOLOAD("Nemagfx_Memory_Pool_Buffer"); /* NemaGFX memory pool */
LOCATION_PRAGMA_NOLOAD("Nemagfx_Stencil_Buffer")
static uint8_t nemagfx_stencil_buffer_mem[NEMAGFX_STENCIL_POOL_SIZE] LOCATION_ATTRIBUTE_NOLOAD("Nemagfx_Stencil_Buffer"); /* NemaGFX stencil buffer memory */
static nema_ringbuffer_t ring_buffer_str;
volatile static int last_cl_id = -1;
extern GPU2D_HandleTypeDef hgpu2d;
static osSemaphoreId_t nema_irq_sem = NULL; // Declare CL IRQ semaphore
#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1)
static void GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef* hgpu2d, uint32_t CmdListID)
#else /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 0 */
void HAL_GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef* hgpu2d, uint32_t CmdListID)
#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hgpu2d);
last_cl_id = CmdListID;
/* Return a token back to a semaphore */
osSemaphoreRelease(nema_irq_sem);
}
void HAL_GPU2D_ErrorCallback(GPU2D_HandleTypeDef *hgpu2d)
{
uint32_t val = nema_reg_read(GPU2D_SYS_INTERRUPT); /* clear the ER interrupt */
nema_reg_write(GPU2D_SYS_INTERRUPT, val);
/* external GPU2D cache maintenance */
if (val & (1UL << 2))
{
HAL_ICACHE_Disable();
nema_ext_hold_deassert_imm(2);
}
if (val & (1UL << 3))
{
HAL_ICACHE_Enable();
HAL_ICACHE_Invalidate();
nema_ext_hold_deassert_imm(3);
}
return;
}
void platform_disable_cache(void)
{
nema_ext_hold_assert(2, 1);
}
void platform_invalidate_cache(void)
{
nema_ext_hold_assert(3, 1);
}
int32_t nema_sys_init(void)
{
int error_code = 0;
/* Setup GPU2D Callback */
#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1)
/* Register Command List Comlete Callback */
HAL_GPU2D_RegisterCommandListCpltCallback(&hgpu2d, GPU2D_CommandListCpltCallback);
#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */
/* Create IRQ semaphore */
nema_irq_sem = osSemaphoreNew(1, 1, NULL);
assert(nema_irq_sem != NULL);
/* Initialise Mem Space */
error_code = tsi_malloc_init_pool_aligned(0, (void*)nemagfx_pool_mem, (uintptr_t)nemagfx_pool_mem, NEMAGFX_MEM_POOL_SIZE, 1, 8);
assert(error_code == 0);
error_code = tsi_malloc_init_pool_aligned(1, (void*)nemagfx_stencil_buffer_mem, (uintptr_t)nemagfx_stencil_buffer_mem, NEMAGFX_STENCIL_POOL_SIZE, 1, 8);
assert(error_code == 0);
/* Allocate ring_buffer memory */
ring_buffer_str.bo = nema_buffer_create(RING_SIZE);
assert(ring_buffer_str.bo.base_virt);
/* Initialize Ring Buffer */
error_code = nema_rb_init(&ring_buffer_str, 1);
if (error_code < 0)
{
return error_code;
}
/* Reset last_cl_id counter */
last_cl_id = 0;
return error_code;
}
uint32_t nema_reg_read(uint32_t reg)
{
return HAL_GPU2D_ReadRegister(&hgpu2d, reg);
}
void nema_reg_write(uint32_t reg, uint32_t value)
{
HAL_GPU2D_WriteRegister(&hgpu2d, reg, value);
}
int nema_wait_irq(void)
{
/* Wait indefinitely for a free semaphore */
osSemaphoreAcquire(nema_irq_sem, osWaitForever);
return 0;
}
int nema_wait_irq_cl(int cl_id)
{
while (last_cl_id < cl_id)
{
(void)nema_wait_irq();
}
return 0;
}
int nema_wait_irq_brk(int brk_id)
{
while (nema_reg_read(GPU2D_BREAKPOINT) == 0U)
{
(void)nema_wait_irq();
}
return 0;
}
void nema_host_free(void* ptr)
{
tsi_free(ptr);
}
void* nema_host_malloc(unsigned size)
{
return tsi_malloc(size);
}
nema_buffer_t nema_buffer_create(int size)
{
nema_buffer_t bo;
memset(&bo, 0, sizeof(bo));
bo.base_virt = tsi_malloc(size);
bo.base_phys = (uint32_t)bo.base_virt;
bo.size = size;
assert(bo.base_virt != 0 && "Unable to allocate memory in nema_buffer_create");
return bo;
}
nema_buffer_t nema_buffer_create_pool(int pool, int size)
{
nema_buffer_t bo;
memset(&bo, 0, sizeof(bo));
bo.base_virt = tsi_malloc_pool(pool, size);
bo.base_phys = (uint32_t)bo.base_virt;
bo.size = size;
bo.fd = 0;
assert(bo.base_virt != 0 && "Unable to allocate memory in nema_buffer_create_pool");
return bo;
}
void* nema_buffer_map(nema_buffer_t* bo)
{
return bo->base_virt;
}
void nema_buffer_unmap(nema_buffer_t* bo)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(bo);
}
void nema_buffer_destroy(nema_buffer_t* bo)
{
if (bo->fd == -1)
{
return; /* Buffer weren't allocated! */
}
tsi_free(bo->base_virt);
bo->base_virt = (void*)0;
bo->base_phys = 0;
bo->size = 0;
bo->fd = -1; /* Buffer not allocated */
}
uintptr_t nema_buffer_phys(nema_buffer_t* bo)
{
return bo->base_phys;
}
void nema_buffer_flush(nema_buffer_t* bo)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(bo);
}
int nema_mutex_lock(int mutex_id)
{
int retval = 0;
/* USER CODE BEGIN nema_mutex_lock */
/* Prevent unused argument(s) compilation warning */
UNUSED(mutex_id);
/* USER CODE END nema_mutex_lock */
return retval;
}
int nema_mutex_unlock(int mutex_id)
{
int retval = 0;
/* USER CODE BEGIN nema_mutex_unlock */
/* Prevent unused argument(s) compilation warning */
UNUSED(mutex_id);
/* USER CODE END nema_mutex_unlock */
return retval;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+304
View File
@@ -0,0 +1,304 @@
/*
******************************************************************************
**
** @file : LinkerScript.ld
**
** @author : STM32CubeIDE
**
** Abstract : Linker script for STM32H7Rxx8 Device
** 64Kbytes FLASH
** 456Kbytes RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed as is, without any warranty
** of any kind.
**
******************************************************************************
** @attention
**
** Copyright (c) 2023 STMicroelectronics.
** All rights reserved.
**
** This software is licensed under terms that can be found in the LICENSE file
** in the root directory of this software component.
** If no LICENSE file comes with this software, it is provided AS-IS.
**
******************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Memories definition */
MEMORY
{
RAM (rw) : ORIGIN = 0x24000000, LENGTH = 0x00060000
RAM_CMD (rw) : ORIGIN = 0x24060000, LENGTH = 0x00010000
ITCM (rw) : ORIGIN = 0x00000000, LENGTH = 0x00010000
DTCM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00003000
DTCM_RTOS (rw) : ORIGIN = 0x20003000, LENGTH = 0x0000D000
SRAMAHB (rw) : ORIGIN = 0x30000000, LENGTH = 0x00008000
BKPSRAM (rw) : ORIGIN = 0x38800000, LENGTH = 0x00001000
FLASH (xr) : ORIGIN = 0x70000000, LENGTH = 0x00200000
FLASH_GFX (r) : ORIGIN = 0x70200000, LENGTH = 0x07e00000
EXTRAM (rw) : ORIGIN = 0x90000000, LENGTH = 0x02000000
}
/* Highest address of the user mode stack */
_estack = ORIGIN(DTCM) + LENGTH(DTCM); /* end of "DTCM" Ram type memory */
_Min_Heap_Size = 0x1000; /* required amount of heap */
_Min_Stack_Size = 0x1000; /* required amount of stack */
/* Link ISR vectors */
SECTIONS
{
/* The startup code into "FLASH" Rom type memory */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
}
/* Define specific placement of memory areas */
SECTIONS
{
BufferSection (NOLOAD) :
{
*(TouchGFX_Framebuffer TouchGFX_Framebuffer.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x8);
*(Nemagfx_Stencil_Buffer Nemagfx_Stencil_Buffer.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x8);
} >EXTRAM
UncachedSection (NOLOAD) :
{
. = ALIGN(32);
KEEP(*(noncacheable_buffer))
KEEP(*(.noncacheable_buffer*))
. = ALIGN(32);
*(Nemagfx_Memory_Pool_Buffer Nemagfx_Memory_Pool_Buffer.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x8);
} >RAM_CMD
FontFlashSection :
{
*(FontFlashSection FontFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >FLASH_GFX
TextFlashSection :
{
*(TextFlashSection TextFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >FLASH_GFX
ExtFlashSection :
{
*(ExtFlashSection ExtFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >FLASH_GFX
}
/* Sections */
SECTIONS
{
/* The program code and other data into "FLASH" Rom type memory */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data into "FLASH" Rom type memory */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab (READONLY) :
{
. = ALIGN(4);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
} >FLASH
.ARM (READONLY) :
{
. = ALIGN(4);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(4);
} >FLASH
.preinit_array (READONLY) :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
} >FLASH
.init_array (READONLY) :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
} >FLASH
.fini_array (READONLY) :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
} >FLASH
/* Used by the startup to initialize data */
_sidata = LOADADDR(.data);
FreeRtosHeapSection :
{
*(.bss.ucHeap)
. = ALIGN(0x8);
} >DTCM_RTOS
/* Initialized data sections into "RAM" Ram type memory */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(.RamFunc) /* .RamFunc sections */
*(.RamFunc*) /* .RamFunc* sections */
. = ALIGN(4);
} >RAM AT> FLASH
/* Initialized TLS data section */
.tdata : ALIGN(4)
{
*(.tdata .tdata.* .gnu.linkonce.td.*)
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
PROVIDE(__data_end = .);
PROVIDE(__tdata_end = .);
} >RAM AT> FLASH
PROVIDE( __tdata_start = ADDR(.tdata) );
PROVIDE( __tdata_size = __tdata_end - __tdata_start );
PROVIDE( __data_start = ADDR(.data) );
PROVIDE( __data_size = __data_end - __data_start );
PROVIDE( __tdata_source = LOADADDR(.tdata) );
PROVIDE( __tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) );
PROVIDE( __tdata_source_size = __tdata_source_end - __tdata_source );
PROVIDE( __data_source = LOADADDR(.data) );
PROVIDE( __data_source_end = __tdata_source_end );
PROVIDE( __data_source_size = __data_source_end - __data_source );
/* Uninitialized data section into "RAM" Ram type memory */
/* Uninitialized TLS data section */
.tbss (NOLOAD) : ALIGN(4)
{
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.tbss .tbss.*)
. = ALIGN(4);
PROVIDE( __tbss_end = . );
} >RAM
PROVIDE( __tbss_start = ADDR(.tbss) );
PROVIDE( __tbss_size = __tbss_end - __tbss_start );
PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) );
PROVIDE( __tls_base = __tdata_start );
PROVIDE( __tls_end = __tbss_end );
PROVIDE( __tls_size = __tls_end - __tls_base );
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1) );
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) );
.bss (NOLOAD) : ALIGN(4)
{
/* This is used by the startup in order to initialize the .bss section */
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
PROVIDE( __bss_end = .);
} >RAM
PROVIDE( __non_tls_bss_start = ADDR(.bss) );
PROVIDE( __bss_start = __tbss_start );
PROVIDE( __bss_size = __bss_end - __bss_start );
/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack (NOLOAD) :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >DTCM
/* Remove information from the compiler libraries */
/DISCARD/ :
{
libc.a:* ( * )
libm.a:* ( * )
libgcc.a:* ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}