C
Qt Quick Ultralite freertos_app_switch Example
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
#include <stm32f769i_discovery.h>
#include <stm32f769i_discovery_lcd.h>
#include <stm32f7xx_hal_dsi.h>
#include "bg_image.h"
#include "string.h" //for memcpy and memset
#include <stdbool.h>
extern int __BOOT_VAL_ADDR;
extern LTDC_HandleTypeDef hltdc_discovery;
extern DSI_HandleTypeDef hdsi_discovery;
const int bgImageWidth = 200;
const int bgImageHeight = 200;
const int bpp = 4;
volatile bool refreshComplete = false;
static void endOfRefreshCallback(DSI_HandleTypeDef *hdsi)
{
(void) hdsi;
refreshComplete = true;
}
static void refreshDisplay(uint32_t address, bool rightArea)
{
/* For OTM8009A CASET: Column address set. XS[15:0] and XE[15:0] */
/* Each value represents one column line in the frame memory */
uint8_t pColLeft[] = {0x00, 0x00, 0x01, 0x8F}; /* 0 -> 399 = 0x0000 - 0x018F */
/* For OTM8009A CASET: Column address set. XS[15:0] and XE[15:0] */
/* Each value represents one column line in the frame memory */
uint8_t pColRight[] = {0x01, 0x90, 0x03, 0x1F}; /* 400 -> 799 = 0x0190 - 0x031F */
if (rightArea) {
address += 400 * bpp;
}
__HAL_DSI_WRAPPER_DISABLE(&hdsi_discovery);
LTDC_LAYER(&hltdc_discovery, 0)->CFBAR = address;
__HAL_LTDC_RELOAD_CONFIG(&hltdc_discovery);
__HAL_DSI_WRAPPER_ENABLE(&hdsi_discovery);
HAL_DSI_LongWrite(&hdsi_discovery,
0,
DSI_DCS_LONG_PKT_WRITE,
sizeof(pColRight),
OTM8009A_CMD_CASET,
rightArea ? pColRight : pColLeft);
HAL_DSI_Refresh(&hdsi_discovery);
}
static void cleanInvalidateDCacheByAddr(void *addr, int size)
{
uint32_t a = (uint32_t) addr;
// addr must be 32 byte aligned
int delta = a & 0x1f;
a &= ~0x1f;
SCB_CleanInvalidateDCache_by_Addr((uint32_t *) a, size + delta);
}
int readBootValue()
{
int *ptr = &__BOOT_VAL_ADDR;
return *ptr;
}
void writeBootValue(int app)
{
int *ptr = &__BOOT_VAL_ADDR;
*ptr = app;
cleanInvalidateDCacheByAddr((void *) ptr, sizeof(int));
}
void reset(int app)
{
writeBootValue(app);
NVIC_SystemReset();
}
void initLED()
{
BSP_LED_Init(LED1);
}
void toggleLED()
{
BSP_LED_Toggle(LED1);
}
void displayApp2Background()
{
// Get framebuffer pointer
unsigned char *fb = (unsigned char *) LCD_FB_START_ADDRESS;
//Set white background (memset framebuffer to 255)
const int width = BSP_LCD_GetXSize();
const int height = BSP_LCD_GetYSize();
memset((void *) fb, 255, width * height * bpp);
//Copy the content of bg_image to the framebuffer line by line
const unsigned int h_offset = ((height - bgImageHeight) / 2) * width * bpp;
const unsigned int w_offset = ((width - bgImageWidth) / 2) * bpp;
for (int i = 0; i < bgImageHeight; ++i) {
unsigned char *dst = fb + h_offset + w_offset + i * width * bpp;
unsigned char *src = &bg_image[i * bgImageWidth * bpp];
memcpy((void *) dst, (void *) src, bgImageWidth * bpp);
}
cleanInvalidateDCacheByAddr(fb, width * height * bpp);
HAL_DSI_RegisterCallback(&hdsi_discovery, HAL_DSI_ENDOF_REFRESH_CB_ID, endOfRefreshCallback);
refreshComplete = false;
refreshDisplay((uint32_t) fb, false);
while (!refreshComplete)
;
refreshComplete = false;
refreshDisplay((uint32_t) fb, true);
while (!refreshComplete)
;
HAL_DSI_RegisterCallback(&hdsi_discovery, HAL_DSI_ENDOF_REFRESH_CB_ID, HAL_DSI_EndOfRefreshCallback);
BSP_LCD_DisplayOn();
}