C

Qt Quick Ultralite freertos_app_switch Example

/******************************************************************************
**
** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Quick Ultralite module.
**
** $QT_BEGIN_LICENSE:COMM$
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** $QT_END_LICENSE$
**
******************************************************************************/

#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();
}