2025-12-07 4:45 AM
Hello everyone,
I am currently trying to integrate TouchGFX into an existing STM32 project (an FDCAN master node application), and I am facing several issues.
I enabled the TouchGFX generator in STM32CubeMX and configured all required peripherals (LTDC, FreeRTOS, DMA2D, OSPI/HyperRAM, clocks, etc.).
I also adjusted the clock configuration to match the display timing.
However, after flashing the application, the screen remains completely black.
Nothing I have tried so far has made any difference.
I have now discovered that the thread I created for the TouchGFX task is never executed, and I have not been able to find the root cause of this.
Any hints or guidance would be greatly appreciated.
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_ADC2_Init();
MX_ADC3_Init();
MX_DAC1_Init();
MX_ETH_Init();
MX_FDCAN1_Init();
MX_FDCAN2_Init();
MX_I2C4_Init();
MX_LTDC_Init();
MX_OCTOSPI1_Init();
MX_OCTOSPI2_Init();
MX_SAI1_Init();
// MX_SDMMC1_SD_Init();
MX_TIM1_Init();
MX_TIM4_Init();
MX_TIM5_Init();
MX_USART1_UART_Init();
MX_USART3_UART_Init();
MX_USB_OTG_HS_USB_Init();
MX_TIM17_Init();
MX_CRC_Init();
MX_DMA2D_Init();
MX_LIBJPEG_Init();
MX_TouchGFX_Init();
/* Call PreOsInit function */
MX_TouchGFX_PreOSInit();
/* USER CODE BEGIN 2 */
canOpenNodeSTM32_Master.CANHandle = &hfdcan1;
canOpenNodeSTM32_Master.HWInitFunction = MX_FDCAN1_Init;
canOpenNodeSTM32_Master.timerHandle = &htim17;
canOpenNodeSTM32_Master.desiredNodeID = 0x18; // Master Node-ID
canOpenNodeSTM32_Master.baudrate = 1000; // 1M
canopen_app_init(&canOpenNodeSTM32_Master);
printf("main starting\r\n");
/* USER CODE END 2 */
printf("TouchGFX_Task Adresse: %p\r\n", (void*)TouchGFX_Task);
printf("StartDefaultTask Adresse: %p\r\n", (void*)StartDefaultTask);
HAL_Delay(100);
/* Init scheduler */
osKernelInitialize();
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
TouchGFXTaskHandle = osThreadNew(TouchGFX_Task, NULL, &TouchGFXTask_attributes);
osKernelStart();
while (1)
{
printf(" if while bad news \r\n");
}
}TouchGFX_Task in app_touchgfx.c : i am not getting this print message :(
void TouchGFX_Task(void* argument)
{
// Calling forward to touchgfx_taskEntry in C++ domain
touchgfx_taskEntry();
printf("touchgfx task\n\r");
}
2025-12-08 12:14 AM
2025-12-08 2:49 AM
Hallo@JohanAstrup ,
Thanks for your reply.
I have deleted the old task and created a new one as described in the documentation. I am now receiving a print message from TouchGFX_Task, but only one message. However, my screen still remains completely black.
I added additional printf statements inside touchgfx_taskEntry(), and the program does reach that function. I also discovered that my taskEntry()function is using the SDL library, which I don’t understand, because I always thought SDL was only used for Windows applications. I don’t know what I did wrong, since the GUI was generated by TouchGFX Designer itself.
Here is the function that appears when I use Ctrl + Click:
void HALSDL2::taskEntry()
{
uint32_t lastTick = SDL_GetTicks();
while (isAlive)
{
SDL_Event event;
if (SDL_PollEvent(&event) == 1)
{
switch (event.type)
{
case SDL_MOUSEMOTION:
_xMouse = event.motion.x;
_yMouse = event.motion.y;
if (debugInfoEnabled)
{
updateTitle();
}
if ((event.motion.state & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0)
{
_x = _xMouse;
_y = _yMouse;
pushTouch(true);
}
if (isWindowBeingDragged)
{
int newMouseX;
int newMouseY;
SDL_GetGlobalMouseState(&newMouseX, &newMouseY);
SDL_SetWindowPosition(simulatorWindow, initialWindowX + (newMouseX - initialMouseX), initialWindowY + (newMouseY - initialMouseY));
}
break;
case SDL_MOUSEBUTTONDOWN:
SDL_CaptureMouse(SDL_TRUE);
if (event.button.button == SDL_BUTTON_LEFT)
{
_x = event.motion.x;
_y = event.motion.y;
pushTouch(true);
}
isWindowBeingDragged = (event.button.button == SDL_BUTTON_RIGHT);
if (isWindowBeingDragged)
{
SDL_GetWindowPosition(simulatorWindow, &initialWindowX, &initialWindowY);
SDL_GetGlobalMouseState(&initialMouseX, &initialMouseY);
}
break;
case SDL_MOUSEBUTTONUP:
SDL_CaptureMouse(SDL_FALSE);
if (event.button.button == SDL_BUTTON_LEFT)
{
pushTouch(false);
}
if (isWindowBeingDragged)
{
int newMouseX;
int newMouseY;
SDL_GetGlobalMouseState(&newMouseX, &newMouseY);
SDL_SetWindowPosition(simulatorWindow, initialWindowX + (newMouseX - initialMouseX), initialWindowY + (newMouseY - initialMouseY));
isWindowBeingDragged = false;
}
break;
case SDL_TEXTINPUT:
if (strlen(event.text.text) == 1)
{
keyPressed = (uint8_t)(event.text.text[0]);
}
break;
case SDL_KEYUP:
if (event.key.keysym.sym == SDLK_F1)
{
debugInfoEnabled = !debugInfoEnabled;
updateTitle();
}
else if (event.key.keysym.sym == SDLK_F2)
{
setFlashInvalidatedAreas(!flashInvalidatedRect);
}
else if (event.key.keysym.sym == SDLK_F3)
{
if (event.key.keysym.mod & KMOD_CTRL)
{
// Repeat
saveNextScreenshots(50);
}
else if (event.key.keysym.mod & KMOD_SHIFT)
{
// clipboard
copyScreenshotToClipboard();
}
else if (event.key.keysym.mod & KMOD_ALT)
{
// Do nothing
}
else if (event.key.keysym.mod & KMOD_GUI)
{
// Do nothing
}
else
{
// No modifiers
saveScreenshot();
}
}
else if (event.key.keysym.sym == SDLK_F4)
{
if (currentSkin != 0 && currentSkin->surface)
{
isSkinActive = !isSkinActive;
}
else
{
isWindowBorderless = !isWindowBorderless;
}
recreateWindow();
}
else if (event.key.keysym.sym == SDLK_ESCAPE)
{
isAlive = false;
}
else if (event.key.keysym.sym == SDLK_F5)
{
Application::getInstance()->changeToStartScreen();
// If stopped in single stepping, perform one step
if (singleSteppingEnabled && singleSteppingSteps == 0)
{
singleSteppingSteps++;
}
}
else if (event.key.keysym.sym == SDLK_F9)
{
setSingleStepping(!singleSteppingEnabled);
}
else if (event.key.keysym.sym == SDLK_F10)
{
if (singleSteppingEnabled)
{
singleSteppingSteps++;
}
}
break;
case SDL_QUIT:
isAlive = false;
break;
case SDL_WINDOWEVENT:
switch (event.window.event)
{
case SDL_WINDOWEVENT_EXPOSED:
// Window has been exposed and should be redrawn
if (simulatorWindow != NULL)
{
Rect display(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
renderLCD_FrameBufferToMemory(display, doRotate(scaleTo24bpp(getTFTFrameBuffer(), lcd().framebufferFormat())));
}
break;
case SDL_WINDOWEVENT_CLOSE:
// The window manager requests that the window be closed
isAlive = false;
break;
}
break;
default:
break;
}
}
else // No SDL event waiting
{
uint32_t thisTick = SDL_GetTicks();
int msSinceLastTick = thisTick - lastTick;
lastTick = thisTick;
msPassed += msSinceLastTick;
if (msPassed >= msBetweenTicks)
{
if (singleSteppingEnabled && singleSteppingSteps == 0)
{
// Eat up extra ms when waiting for next step
while (msPassed >= msBetweenTicks)
{
msPassed -= msBetweenTicks;
}
}
else
{
while (msPassed >= msBetweenTicks)
{
msPassed -= msBetweenTicks;
vSync();
}
backPorchExited();
frontPorchEntered();
if (screenshotcount > 0)
{
screenshotcount--;
saveScreenshot();
}
}
if (singleSteppingEnabled && singleSteppingSteps > 0)
{
singleSteppingSteps--;
}
}
else
{
// Sleep until we have the next tick
uint32_t delay = (uint32_t)(msBetweenTicks - msPassed);
// Due to rounding, delay might be zero.
SDL_Delay(delay == 0 ? 1 : delay);
}
}
}
}
2025-12-11 2:20 AM
What happens when you debug the application? Is the application running but not entering the TouchGFX thread, or does it stall completely?
The taskEntry reference to SDL sounds like an incorrect reference by you IDE. Which IDE are you using?
Best regards,
Johan
2025-12-12 1:45 AM
Hallo @JohanAstrup
I am using STM32CubeIDE together with TouchGFX Designer. I discovered that the IDE did not recognize my board because the selected target in TouchGFX Designer was marked as A/N. Therefore, I deleted the old project, recreated it from TouchGFX Designer, and exported it again into STM32CubeIDE.
The GUI now works correctly, but this introduced another problem: I can no longer use FDCAN. I added the STM32 CANopen stack to the project and configured the FDCAN interface in CubeMX, but it no longer works at all.
Additionally, even simple printf messages are not working, and I am still trying to determine what is wrong with printf. Debugging does not help, because the program gets stuck in SCB_EnableDCache().
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os.h"
#include "libjpeg.h"
#include "app_touchgfx.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stm32h735g_discovery_ospi.h"
#include "stm32h7xx_hal_ospi.h"
#include "CO_app_STM32.h"
#include "OD.h"
/* 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 ---------------------------------------------------------*/
CRC_HandleTypeDef hcrc;
DMA2D_HandleTypeDef hdma2d;
FDCAN_HandleTypeDef hfdcan1;
LTDC_HandleTypeDef hltdc;
OSPI_HandleTypeDef hospi1;
OSPI_HandleTypeDef hospi2;
TIM_HandleTypeDef htim17;
UART_HandleTypeDef huart3;
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for TouchGFXTask */
osThreadId_t TouchGFXTaskHandle;
const osThreadAttr_t TouchGFXTask_attributes = {
.name = "TouchGFXTask",
.stack_size = 1024 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for videoTask */
osThreadId_t videoTaskHandle;
const osThreadAttr_t videoTask_attributes = {
.name = "videoTask",
.stack_size = 1024 * 4,
.priority = (osPriority_t) osPriorityLow,
};
/* USER CODE BEGIN PV */
#define SLAVE1_ID 0x01 // NUCLEO-L5A1 + 53L8A1
#define SLAVE2_ID 0x02 // NUCLEO-C0 + 6283A1
#define NODE_COUNT 2
uint8_t slaveList[NODE_COUNT] = { SLAVE1_ID, SLAVE2_ID };
CANopenNodeSTM32 canOpenNodeSTM32_Master;
uint8_t last_press=0 ;
uint32_t message = 0 ;
#ifdef __GNUC__
# define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
# define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void PeriphCommonClock_Config(void);
static void MPU_Config(void);
static void MX_GPIO_Init(void);
static void MX_CRC_Init(void);
static void MX_DMA2D_Init(void);
static void MX_LTDC_Init(void);
static void MX_OCTOSPI1_Init(void);
static void MX_OCTOSPI2_Init(void);
static void MX_FDCAN1_Init(void);
static void MX_TIM17_Init(void);
static void MX_USART3_UART_Init(void);
void StartDefaultTask(void *argument);
extern void TouchGFX_Task(void *argument);
extern void videoTaskFunc(void *argument);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* Enable the CPU Cache */
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CRC_Init();
MX_DMA2D_Init();
MX_LTDC_Init();
MX_OCTOSPI1_Init();
MX_OCTOSPI2_Init();
MX_LIBJPEG_Init();
MX_FDCAN1_Init();
MX_TIM17_Init();
MX_USART3_UART_Init();
MX_TouchGFX_Init();
/* Call PreOsInit function */
MX_TouchGFX_PreOSInit();
/* USER CODE BEGIN 2 */
canOpenNodeSTM32_Master.CANHandle = &hfdcan1;
canOpenNodeSTM32_Master.HWInitFunction = MX_FDCAN1_Init;
canOpenNodeSTM32_Master.timerHandle = &htim17;
canOpenNodeSTM32_Master.desiredNodeID = 0x18; // Master Node-ID
canOpenNodeSTM32_Master.baudrate = 1000; // 1M
canopen_app_init(&canOpenNodeSTM32_Master);
HAL_UART_Transmit(&huart3, (uint8_t*)"UART Direct Test OK\r\n", 21, 100); // <- Test mit HAL
printf("printf Test OK\r\n"); // <- Test mit printf
/* USER CODE END 2 */
/* Init scheduler */
osKernelInitialize();
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* creation of TouchGFXTask */
TouchGFXTaskHandle = osThreadNew(TouchGFX_Task, NULL, &TouchGFXTask_attributes);
/* creation of videoTask */
videoTaskHandle = osThreadNew(videoTaskFunc, NULL, &videoTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */
/* USER CODE END RTOS_EVENTS */
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 2;
RCC_OscInitStruct.PLL.PLLN = 44;
RCC_OscInitStruct.PLL.PLLP = 1;
RCC_OscInitStruct.PLL.PLLQ = 11;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief Peripherals Common Clock Configuration
* @retval None
*/
void PeriphCommonClock_Config(void)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_OSPI;
PeriphClkInitStruct.PLL2.PLL2M = 5;
PeriphClkInitStruct.PLL2.PLL2N = 80;
PeriphClkInitStruct.PLL2.PLL2P = 2;
PeriphClkInitStruct.PLL2.PLL2Q = 2;
PeriphClkInitStruct.PLL2.PLL2R = 2;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_2;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
PeriphClkInitStruct.OspiClockSelection = RCC_OSPICLKSOURCE_PLL2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief CRC Initialization Function
* @param None
* @retval None
*/
static void MX_CRC_Init(void)
{
/* USER CODE BEGIN CRC_Init 0 */
/* USER CODE END CRC_Init 0 */
/* USER CODE BEGIN CRC_Init 1 */
/* USER CODE END CRC_Init 1 */
hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;
hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
if (HAL_CRC_Init(&hcrc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CRC_Init 2 */
/* USER CODE END CRC_Init 2 */
}
/**
* @brief DMA2D Initialization Function
* @param None
* @retval None
*/
static void MX_DMA2D_Init(void)
{
/* USER CODE BEGIN DMA2D_Init 0 */
/* USER CODE END DMA2D_Init 0 */
/* USER CODE BEGIN DMA2D_Init 1 */
/* USER CODE END DMA2D_Init 1 */
hdma2d.Instance = DMA2D;
hdma2d.Init.Mode = DMA2D_R2M;
hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB888;
hdma2d.Init.OutputOffset = 0;
if (HAL_DMA2D_Init(&hdma2d) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN DMA2D_Init 2 */
/* USER CODE END DMA2D_Init 2 */
}
/**
* @brief FDCAN1 Initialization Function
* @param None
* @retval None
*/
static void MX_FDCAN1_Init(void)
{
/* USER CODE BEGIN FDCAN1_Init 0 */
/* USER CODE END FDCAN1_Init 0 */
/* USER CODE BEGIN FDCAN1_Init 1 */
/* USER CODE END FDCAN1_Init 1 */
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE;
hfdcan1.Init.TransmitPause = ENABLE;
hfdcan1.Init.ProtocolException = DISABLE;
hfdcan1.Init.NominalPrescaler = 1;
hfdcan1.Init.NominalSyncJumpWidth = 4;
hfdcan1.Init.NominalTimeSeg1 = 28;
hfdcan1.Init.NominalTimeSeg2 = 21;
hfdcan1.Init.DataPrescaler = 1;
hfdcan1.Init.DataSyncJumpWidth = 4;
hfdcan1.Init.DataTimeSeg1 = 19;
hfdcan1.Init.DataTimeSeg2 = 5;
hfdcan1.Init.MessageRAMOffset = 0;
hfdcan1.Init.StdFiltersNbr = 0;
hfdcan1.Init.ExtFiltersNbr = 0;
hfdcan1.Init.RxFifo0ElmtsNbr = 0;
hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.RxFifo1ElmtsNbr = 0;
hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.RxBuffersNbr = 0;
hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.TxEventsNbr = 0;
hfdcan1.Init.TxBuffersNbr = 0;
hfdcan1.Init.TxFifoQueueElmtsNbr = 0;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN FDCAN1_Init 2 */
/* USER CODE END FDCAN1_Init 2 */
}
/**
* @brief LTDC Initialization Function
* @param None
* @retval None
*/
static void MX_LTDC_Init(void)
{
/* USER CODE BEGIN LTDC_Init 0 */
/* USER CODE END LTDC_Init 0 */
LTDC_LayerCfgTypeDef pLayerCfg = {0};
/* USER CODE BEGIN LTDC_Init 1 */
/* USER CODE END LTDC_Init 1 */
hltdc.Instance = LTDC;
hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
hltdc.Init.HorizontalSync = 40;
hltdc.Init.VerticalSync = 9;
hltdc.Init.AccumulatedHBP = 53;
hltdc.Init.AccumulatedVBP = 11;
hltdc.Init.AccumulatedActiveW = 533;
hltdc.Init.AccumulatedActiveH = 283;
hltdc.Init.TotalWidth = 565;
hltdc.Init.TotalHeigh = 285;
hltdc.Init.Backcolor.Blue = 0;
hltdc.Init.Backcolor.Green = 0;
hltdc.Init.Backcolor.Red = 0;
if (HAL_LTDC_Init(&hltdc) != HAL_OK)
{
Error_Handler();
}
pLayerCfg.WindowX0 = 0;
pLayerCfg.WindowX1 = 480;
pLayerCfg.WindowY0 = 0;
pLayerCfg.WindowY1 = 272;
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB888;
pLayerCfg.Alpha = 255;
pLayerCfg.Alpha0 = 0;
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
pLayerCfg.FBStartAdress = 0x70000000;
pLayerCfg.ImageWidth = 480;
pLayerCfg.ImageHeight = 272;
pLayerCfg.Backcolor.Blue = 0;
pLayerCfg.Backcolor.Green = 0;
pLayerCfg.Backcolor.Red = 0;
if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN LTDC_Init 2 */
/* USER CODE END LTDC_Init 2 */
}
/**
* @brief OCTOSPI1 Initialization Function
* @param None
* @retval None
*/
static void MX_OCTOSPI1_Init(void)
{
/* USER CODE BEGIN OCTOSPI1_Init 0 */
BSP_OSPI_NOR_Init_t ospi_nor_int;
/* USER CODE END OCTOSPI1_Init 0 */
OSPIM_CfgTypeDef sOspiManagerCfg = {0};
/* USER CODE BEGIN OCTOSPI1_Init 1 */
/* USER CODE END OCTOSPI1_Init 1 */
/* OCTOSPI1 parameter configuration*/
hospi1.Instance = OCTOSPI1;
hospi1.Init.FifoThreshold = 4;
hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_MACRONIX;
hospi1.Init.DeviceSize = 32;
hospi1.Init.ChipSelectHighTime = 2;
hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
hospi1.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
hospi1.Init.ClockPrescaler = 2;
hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
hospi1.Init.ChipSelectBoundary = 0;
hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
hospi1.Init.MaxTran = 0;
hospi1.Init.Refresh = 0;
if (HAL_OSPI_Init(&hospi1) != HAL_OK)
{
Error_Handler();
}
sOspiManagerCfg.ClkPort = 1;
sOspiManagerCfg.DQSPort = 1;
sOspiManagerCfg.NCSPort = 1;
sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_1_HIGH;
if (HAL_OSPIM_Config(&hospi1, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN OCTOSPI1_Init 2 */
HAL_OSPI_DeInit(&hospi1);
ospi_nor_int.InterfaceMode = BSP_OSPI_NOR_OPI_MODE;
ospi_nor_int.TransferRate = BSP_OSPI_NOR_DTR_TRANSFER;
BSP_OSPI_NOR_DeInit(0);
if(BSP_OSPI_NOR_Init(0, &ospi_nor_int) != BSP_ERROR_NONE)
{
Error_Handler();
}
if(BSP_OSPI_NOR_EnableMemoryMappedMode(0) != BSP_ERROR_NONE)
{
Error_Handler();
}
/* USER CODE END OCTOSPI1_Init 2 */
}
/**
* @brief OCTOSPI2 Initialization Function
* @param None
* @retval None
*/
static void MX_OCTOSPI2_Init(void)
{
/* USER CODE BEGIN OCTOSPI2_Init 0 */
BSP_OSPI_RAM_Init_t ospi_ram_init;
/* USER CODE END OCTOSPI2_Init 0 */
OSPIM_CfgTypeDef sOspiManagerCfg = {0};
OSPI_HyperbusCfgTypeDef sHyperBusCfg = {0};
/* USER CODE BEGIN OCTOSPI2_Init 1 */
OSPI_HyperbusCmdTypeDef sCommand = {0};
OSPI_MemoryMappedTypeDef sMemMappedCfg = {0};
/* USER CODE END OCTOSPI2_Init 1 */
/* OCTOSPI2 parameter configuration*/
hospi2.Instance = OCTOSPI2;
hospi2.Init.FifoThreshold = 4;
hospi2.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi2.Init.MemoryType = HAL_OSPI_MEMTYPE_HYPERBUS;
hospi2.Init.DeviceSize = 24;
hospi2.Init.ChipSelectHighTime = 4;
hospi2.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
hospi2.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
hospi2.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
hospi2.Init.ClockPrescaler = 2;
hospi2.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
hospi2.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
hospi2.Init.ChipSelectBoundary = 23;
hospi2.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED;
hospi2.Init.MaxTran = 0;
hospi2.Init.Refresh = 400;
if (HAL_OSPI_Init(&hospi2) != HAL_OK)
{
Error_Handler();
}
sOspiManagerCfg.ClkPort = 2;
sOspiManagerCfg.DQSPort = 2;
sOspiManagerCfg.NCSPort = 2;
sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_2_LOW;
sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_2_HIGH;
if (HAL_OSPIM_Config(&hospi2, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
sHyperBusCfg.RWRecoveryTime = 3;
sHyperBusCfg.AccessTime = 6;
sHyperBusCfg.WriteZeroLatency = HAL_OSPI_LATENCY_ON_WRITE;
sHyperBusCfg.LatencyMode = HAL_OSPI_FIXED_LATENCY;
if (HAL_OSPI_HyperbusCfg(&hospi2, &sHyperBusCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN OCTOSPI2_Init 2 */
sCommand.AddressSpace = HAL_OSPI_MEMORY_ADDRESS_SPACE;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.DQSMode = HAL_OSPI_DQS_ENABLE;
sCommand.Address = 0;
sCommand.NbData = 1;
if (HAL_OSPI_HyperbusCmd(&hospi2, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;
if (HAL_OSPI_MemoryMapped(&hospi2, &sMemMappedCfg) != HAL_OK)
{
Error_Handler();
}
/* USER CODE END OCTOSPI2_Init 2 */
}
/**
* @brief TIM17 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM17_Init(void)
{
/* USER CODE BEGIN TIM17_Init 0 */
/* USER CODE END TIM17_Init 0 */
/* USER CODE BEGIN TIM17_Init 1 */
/* USER CODE END TIM17_Init 1 */
htim17.Instance = TIM17;
htim17.Init.Prescaler = 274;
htim17.Init.CounterMode = TIM_COUNTERMODE_UP;
htim17.Init.Period = 1000;
htim17.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim17.Init.RepetitionCounter = 0;
htim17.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim17) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM17_Init 2 */
/* USER CODE END TIM17_Init 2 */
}
/**
* @brief USART3 Initialization Function
* @param None
* @retval None
*/
static void MX_USART3_UART_Init(void)
{
/* USER CODE BEGIN USART3_Init 0 */
/* USER CODE END USART3_Init 0 */
/* USER CODE BEGIN USART3_Init 1 */
/* USER CODE END USART3_Init 1 */
huart3.Instance = USART3;
huart3.Init.BaudRate = 115200;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart3) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart3) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART3_Init 2 */
/* USER CODE END USART3_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOG, LCD_BL_CTRL_Pin|RENDER_TIME_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, MCU_ACTIVE_Pin|FRAME_RATE_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LCD_DISP_GPIO_Port, LCD_DISP_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(VSYNC_FREQ_GPIO_Port, VSYNC_FREQ_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : LCD_BL_CTRL_Pin */
GPIO_InitStruct.Pin = LCD_BL_CTRL_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LCD_BL_CTRL_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : RENDER_TIME_Pin */
GPIO_InitStruct.Pin = RENDER_TIME_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(RENDER_TIME_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : MCU_ACTIVE_Pin FRAME_RATE_Pin */
GPIO_InitStruct.Pin = MCU_ACTIVE_Pin|FRAME_RATE_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : LCD_DISP_Pin */
GPIO_InitStruct.Pin = LCD_DISP_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LCD_DISP_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : VSYNC_FREQ_Pin */
GPIO_InitStruct.Pin = VSYNC_FREQ_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(VSYNC_FREQ_GPIO_Port, &GPIO_InitStruct);
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
/*
int _write(int file, char *ptr, int len) {
HAL_UART_Transmit(&huart3, (uint8_t*)ptr, len, HAL_MAX_DELAY);
return len;
} */
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 4 */
/* USER CODE BEGIN Header_StartDefaultTask */
/**
* @brief Function implementing the defaultTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN 5 */
/* Infinite loop */
for(;;)
{ canopen_app_process();
printf("canopen! Master is running.\r\n");
osDelay(250);
}
/* USER CODE END 5 */
}
/* MPU Configuration */
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x70000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512MB;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.Size = MPU_REGION_SIZE_8MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.BaseAddress = 0x90000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512MB;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.Size = MPU_REGION_SIZE_64MB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
/**
* @brief Period elapsed callback in non blocking mode
* @note This function is called when TIM6 interrupt took place, inside
* HAL_TIM_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
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */
/* USER CODE END Callback 0 */
if (htim->Instance == TIM6) {
HAL_IncTick();
}
/* USER CODE BEGIN Callback 1 */
if (htim == canopenNodeSTM32->timerHandle) {
canopen_app_interrupt();
}
/* USER CODE END Callback 1 */
}
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
2025-12-18 12:52 AM
I am not sure, I understand that.
The GUI works correctly, but at the same time the application does not run? I do not see how that is possible.
Are you using version control, and can you restore the previous state in which FDCAN worked, but TouchGFX did not? Maybe you could manually set the target, so you do not need to delete and recreate the entire project .. ?
Best regards,
Johan