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 "bg_image.h"
#include "qul_display_helpers.h"

#include "fsl_gpio.h"
#include "fsl_common.h"
#include "fsl_dc_fb.h"
#include "fsl_dc_fb_lcdifv2.h"

#include "string.h" //for memcpy and memset

extern int __BOOT_VAL_ADDR;
extern const dc_fb_t g_dc;

#define BG_IMG_WIDTH 200
#define BG_IMG_HEIGHT BG_IMG_WIDTH

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)
{
    __disable_irq();
    writeBootValue(app);
    NVIC_SystemReset();
}

#define LOGIC_LED_OFF (1U)
#ifndef BOARD_USER_LED_GPIO
#define BOARD_USER_LED_GPIO GPIO9
#endif
#ifndef BOARD_USER_LED_GPIO_PIN
#define BOARD_USER_LED_GPIO_PIN (3U)
#endif

void initLED()
{
    GPIO_PinWrite(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN, LOGIC_LED_OFF);
    BOARD_USER_LED_GPIO->GDIR |= (1U << BOARD_USER_LED_GPIO_PIN);
}

void toggleLED()
{
    GPIO_PinWrite(BOARD_USER_LED_GPIO,
                  BOARD_USER_LED_GPIO_PIN,
                  0x1 ^ GPIO_PinRead(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN));
}

typedef struct pixel
{
    uint8_t B;
    uint8_t G;
    uint8_t R;
    uint8_t X;
} pixel_t;

AT_NONCACHEABLE_SECTION_ALIGN(static pixel_t s_frameBuffer[1280][720], 32);

static dc_fb_info_t fbInfo;

void displayApp2Background()
{
    initDisplayController();

    g_dc.ops->getLayerDefaultConfig(&g_dc, 0, &fbInfo);

    fbInfo.pixelFormat = kVIDEO_PixelFormatXRGB8888;
    fbInfo.startX = 0;
    fbInfo.startY = 0;
    fbInfo.width = 720;
    fbInfo.height = 1280;
    fbInfo.strideBytes = 720 * sizeof(pixel_t);

    g_dc.ops->setLayerConfig(&g_dc, 0, &fbInfo);

    for (int i = 0; i < fbInfo.height; i++) {
        for (int j = 0; j < fbInfo.width; j++) {
            s_frameBuffer[i][j].X = 0x00;
            s_frameBuffer[i][j].R = 0xFF;
            s_frameBuffer[i][j].G = 0xFF;
            s_frameBuffer[i][j].B = 0xFF;
        }
    }

    //Copy the content of bg_image to the framebuffer line by line
    const unsigned int h_offset = ((fbInfo.height - BG_IMG_HEIGHT) / 2) * fbInfo.width;
    const unsigned int w_offset = ((fbInfo.width - BG_IMG_WIDTH) / 2);
    for (int i = 0; i < BG_IMG_HEIGHT; ++i) {
        pixel_t *dst = (pixel_t *) s_frameBuffer + h_offset + w_offset + i * fbInfo.width;
        unsigned char *src = &bg_image[i * BG_IMG_WIDTH * 4];
        memcpy((void *) dst, (void *) src, BG_IMG_WIDTH * 4);
    }

    g_dc.ops->setFrameBuffer(&g_dc, 0, s_frameBuffer);

    g_dc.ops->enableLayer(&g_dc, 0);
}