1
0

add screen library

This commit is contained in:
2024-01-13 19:15:18 +01:00
parent 7b660f0fe2
commit 65ff5de90f
533 changed files with 113575 additions and 2 deletions

View File

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

View File

@ -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

View File

@ -0,0 +1,176 @@
/**
******************************************************************************
* File Name : STM32TouchController.cpp
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 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 BEGIN STM32TouchController */
#include <STM32TouchController.hpp>
#include <TouchGFXHAL.hpp>
#include <ft5336.h>
#include <stm32f7xx_hal.h>
#include <touchgfx/hal/OSWrappers.hpp>
static TS_DrvTypeDef* tsDriver;
extern I2C_HandleTypeDef hi2c3;
void STM32TouchController::init()
{
/* Initialize the TS driver structure */
tsDriver = &ft5336_ts_drv;
/* Initialize the TS driver */
tsDriver->Start(TS_I2C_ADDRESS);
}
bool STM32TouchController::sampleTouch(int32_t& x, int32_t& y)
{
/**
* By default sampleTouch returns false,
* return true if a touch has been detected, otherwise false.
*
* Coordinates are passed to the caller by reference by x and y.
*
* This function is called by the TouchGFX framework.
* By default sampleTouch is called every tick, this can be adjusted by HAL::setTouchSampleRate(int8_t);
*
*/
if (tsDriver)
{
if (tsDriver->DetectTouch(TS_I2C_ADDRESS))
{
/* Get each touch coordinates */
tsDriver->GetXY(TS_I2C_ADDRESS, (uint16_t*)&y, (uint16_t*)&x);
return true;
}
}
return false;
}
/**
* @brief Manages error callback by re-initializing I2C.
* @param i2c_handler : I2C handler
* @param Addr: I2C Address
* @retval None
*/
static void I2Cx_Error(I2C_HandleTypeDef* i2c_handler, uint8_t Addr)
{
/* De-initialize the I2C communication bus */
HAL_I2C_DeInit(i2c_handler);
/* Re-Initialize the I2C communication bus */
//I2Cx_Init(i2c_handler);
}
/**
* @brief Reads multiple data.
* @param i2c_handler : I2C handler
* @param Addr: I2C address
* @param Reg: Reg address
* @param MemAddress: Memory address
* @param Buffer: Pointer to data buffer
* @param Length: Length of the data
* @retval Number of read data
*/
static HAL_StatusTypeDef I2Cx_ReadMultiple(I2C_HandleTypeDef* i2c_handler,
uint8_t Addr,
uint16_t Reg,
uint16_t MemAddress,
uint8_t* Buffer,
uint16_t Length)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Read(i2c_handler, Addr, (uint16_t)Reg, MemAddress, Buffer, Length, 1000);
/* Check the communication status */
if (status != HAL_OK)
{
/* I2C error occurred */
I2Cx_Error(i2c_handler, Addr);
}
return status;
}
/**
* @brief Writes a value in a register of the device through BUS in using DMA mode.
* @param i2c_handler : I2C handler
* @param Addr: Device address on BUS Bus.
* @param Reg: The target register address to write
* @param MemAddress: Memory address
* @param Buffer: The target register value to be written
* @param Length: buffer size to be written
* @retval HAL status
*/
static HAL_StatusTypeDef I2Cx_WriteMultiple(I2C_HandleTypeDef* i2c_handler,
uint8_t Addr,
uint16_t Reg,
uint16_t MemAddress,
uint8_t* Buffer,
uint16_t Length)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Write(i2c_handler, Addr, (uint16_t)Reg, MemAddress, Buffer, Length, 1000);
/* Check the communication status */
if (status != HAL_OK)
{
/* Re-Initiaize the I2C Bus */
I2Cx_Error(i2c_handler, Addr);
}
return status;
}
/**
* @brief Writes a single data.
* @param Addr: I2C address
* @param Reg: Reg address
* @param Value: Data to be written
* @retval None
*/
void TS_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value)
{
I2Cx_WriteMultiple(&hi2c3, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&Value, 1);
}
/**
* @brief Reads a single data.
* @param Addr: I2C address
* @param Reg: Reg address
* @retval Data to be read
*/
uint8_t TS_IO_Read(uint8_t Addr, uint8_t Reg)
{
uint8_t read_value = 0;
I2Cx_ReadMultiple(&hi2c3, Addr, Reg, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&read_value, 1);
return read_value;
}
/**
* @brief TS delay
* @param Delay: Delay in ms
* @retval None
*/
void TS_IO_Delay(uint32_t Delay)
{
HAL_Delay(Delay);
}
/* USER CODE END STM32TouchController */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,70 @@
/**
******************************************************************************
* File Name : STM32TouchController.hpp
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 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 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);
private:
static const uint16_t TS_I2C_ADDRESS = ((uint16_t)0x70);
};
#endif // STM32TOUCHCONTROLLER_HPP
/* USER CODE END STM32TouchController */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,76 @@
/**
******************************************************************************
* File Name : TouchGFXGPIO.cpp
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 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
*
******************************************************************************
*/
#include <touchgfx/hal/GPIO.hpp>
/**
* GPIO_ID Enum, these are used bt TouchGFX framework to signal 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.
*
*/
/* USER CODE BEGIN TouchGFXGPIO.cpp */
using namespace touchgfx;
/*
* Perform configuration of IO pins.
*/
void GPIO::init()
{
}
/*
* Sets a pin high.
*/
void GPIO::set(GPIO_ID id)
{
}
/*
* Sets a pin low.
*/
void GPIO::clear(GPIO_ID id)
{
}
/*
* Toggles a pin.
*/
void GPIO::toggle(GPIO_ID id)
{
}
/*
* Gets the state of a pin.
*/
bool GPIO::get(GPIO_ID id)
{
return false;
}
/* USER CODE END TouchGFXGPIO.cpp */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,208 @@
/**
******************************************************************************
* File Name : TouchGFXHAL.cpp
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 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
*
******************************************************************************
*/
#include <TouchGFXHAL.hpp>
/* USER CODE BEGIN TouchGFXHAL.cpp */
#include "stm32f7xx.h"
#include <touchgfx/hal/OSWrappers.hpp>
#include <CortexMMCUInstrumentation.hpp>
#include "touchgfx-config.h"
#if (TOUCHGFX_FREERTOS != 0)
#include "FreeRTOS.h"
#include "task.h"
#endif // TOUCHGFX_FREERTOS
using namespace touchgfx;
CortexMMCUInstrumentation instrumentation;
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();
setFrameBufferStartAddresses((void*)0xC0000000, (void*)0xC003FC00, (void*)0xC007F800); //enable the animation storage to allow slide animations
lockDMAToFrontPorch(false);
instrumentation.init();
setMCUInstrumentation(&instrumentation);
enableMCULoadCalculation(true);
}
#if (TOUCHGFX_BAREMETAL != 0)
void TouchGFXHAL::taskEntry()
{
static bool firstCall = true;
if (firstCall)
{
firstCall = false;
enableLCDControllerInterrupt();
enableInterrupts();
}
OSWrappers::waitForVSync();
//backPorchExited();
// Not necessary to call here when it is done by the
// OSWrappers::waitForVSync() method
}
#endif // TOUCHGFX_BAREMETAL
/**
* 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.
TouchGFXGeneratedHAL::flushFrameBuffer(rect);
// If the framebuffer is placed in Write Through cached memory (e.g. SRAM) then we need
// to flush the Dcache to make sure framebuffer is correct in RAM. That's done
// using SCB_CleanInvalidateDCache().
if ((SCB->CCR & SCB_CCR_DC_Msk) != 0) // Check data cache is enabled
{
SCB_CleanInvalidateDCache();
}
}
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();
}
extern "C"
{
#if (TOUCHGFX_FREERTOS != 0)
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;
}
#endif // TOUCHGFX_FREERTOS
}
/* USER CODE END TouchGFXHAL.cpp */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,166 @@
/**
******************************************************************************
* File Name : TouchGFXHAL.hpp
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 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
*
******************************************************************************
*/
#ifndef TouchGFXHAL_HPP
#define TouchGFXHAL_HPP
/* USER CODE BEGIN TouchGFXHAL.hpp */
#include <TouchGFXGeneratedHAL.hpp>
#include "touchgfx-config.h"
/**
* @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)
{
}
void initialize();
#if ( TOUCHGFX_BAREMETAL != 0)
virtual void taskEntry();
#endif // TOUCHGFX_BAREMETAL
/**
* @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();
/**
* @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);
};
/* USER CODE END TouchGFXHAL.hpp */
#endif // TouchGFXHAL_HPP
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,224 @@
/**
******************************************************************************
* File Name : OSWrappers.cpp
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 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
*
******************************************************************************
*/
#include "touchgfx-config.h"
#if ( TOUCHGFX_BAREMETAL != 0)
#include <stm32f7xx_hal.h>
#include <TouchGFXHAL.hpp>
#endif // TOUCHGFX_BAREMETAL
#if ( TOUCHGFX_FREERTOS != 0)
#include <cassert>
#include <cmsis_os2.h>
#include <touchgfx/hal/HAL.hpp>
#endif // TOUCHGFX_FREERTOS
#include <touchgfx/hal/OSWrappers.hpp>
#if (TOUCHGFX_BAREMETAL != 0)
static volatile uint32_t fb_sem;
static volatile uint32_t vsync_sem;
#endif // TOUCHGFX_BAREMETAL
#if (TOUCHGFX_FREERTOS != 0)
#include <cmsis_os2.h>
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;
#endif //TOUCHGFX_FREERTOS
using namespace touchgfx;
/*
* Initialize frame buffer semaphore and queue/mutex for VSYNC signal.
*/
void OSWrappers::initialize()
{
#if (TOUCHGFX_BAREMETAL != 0)
fb_sem = 0;
vsync_sem = 0;
#endif // TOUCHGFX_BAREMETAL
#if (TOUCHGFX_FREERTOS != 0)
// 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");
#endif // TOUCHGFX_FREERTOS
}
/*
* Take the frame buffer semaphore. Blocks until semaphore is available.
*/
void OSWrappers::takeFrameBufferSemaphore()
{
#if (TOUCHGFX_BAREMETAL != 0)
while(fb_sem);
fb_sem = 1;
#endif // TOUCHGFX_BAREMETAL
#if (TOUCHGFX_FREERTOS != 0)
osSemaphoreAcquire(frame_buffer_sem, osWaitForever);
#endif // TOUCHGFX_FREERTOS
}
/*
* Release the frame buffer semaphore.
*/
void OSWrappers::giveFrameBufferSemaphore()
{
#if (TOUCHGFX_BAREMETAL != 0)
fb_sem = 0;
#endif // TOUCHGFX_BAREMETAL
#if (TOUCHGFX_FREERTOS != 0)
osSemaphoreRelease(frame_buffer_sem);
#endif // TOUCHGFX_FREERTOS
}
/*
* 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()
{
#if (TOUCHGFX_BAREMETAL != 0)
fb_sem = 1;
#endif // TOUCHGFX_BAREMETAL
#if (TOUCHGFX_FREERTOS != 0)
osSemaphoreAcquire(frame_buffer_sem, 0);
#endif // TOUCHGFX_FREERTOS
}
/*
* 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()
{
#if (TOUCHGFX_BAREMETAL != 0)
fb_sem = 0;
#endif // TOUCHGFX_BAREMETAL
#if (TOUCHGFX_FREERTOS != 0)
osSemaphoreRelease(frame_buffer_sem);
#endif // TOUCHGFX_FREERTOS
}
/*
* 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()
{
#if (TOUCHGFX_BAREMETAL != 0)
vsync_sem = 1;
#endif // TOUCHGFX_BAREMETAL
#if (TOUCHGFX_FREERTOS != 0)
osMessageQueuePut(vsync_queue, &dummy, 0, 0);
#endif // TOUCHGFX_FREERTOS
}
/*
* Signal that the rendering of the frame has completed. Used by
* some systems to avoid using any previous vsync.
*/
void OSWrappers::signalRenderingDone()
{
#if (TOUCHGFX_BAREMETAL != 0)
vsync_sem = 0;
#endif // TOUCHGFX_BAREMETAL
#if (TOUCHGFX_FREERTOS != 0)
// Empty implementation for CMSIS V2
#endif // TOUCHGFX_FREERTOS
}
/*
* This function checks if a VSync occurred after last rendering.
* The function is used in systems that cannot wait in waitForVSync
* (because they are also checking other event sources.
*
* @note signalRenderingDone is typically used together with this function.
*
* @return True if VSync occurred.
*/
bool OSWrappers::isVSyncAvailable()
{
#if (TOUCHGFX_BAREMETAL != 0)
return vsync_sem;
#endif // TOUCHGFX_BAREMETAL
#if (TOUCHGFX_FREERTOS != 0)
return true;
#endif // TOUCHGFX_FREERTOS
}
/*
* This function check if a VSYNC has occured.
* If VSYNC has occured, signal TouchGFX to start a rendering
*/
void OSWrappers::waitForVSync()
{
#if (TOUCHGFX_BAREMETAL != 0)
if(vsync_sem)
{
vsync_sem = 0;
HAL::getInstance()->backPorchExited();
}
#endif // TOUCHGFX_BAREMETAL
#if (TOUCHGFX_FREERTOS != 0)
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);
#endif // TOUCHGFX_FREERTOS
}
/*
* 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)
{
#if (TOUCHGFX_BAREMETAL != 0)
HAL_Delay(ms);
#endif // TOUCHGFX_BAREMETAL
#if (TOUCHGFX_FREERTOS != 0)
osDelay(static_cast<uint32_t>(ms));
#endif // TOUCHGFX_FREERTOS
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,387 @@
/**
******************************************************************************
* File Name : STM32DMA.cpp
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 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
*
******************************************************************************
*/
#include "stm32f7xx_hal.h"
#include "stm32f7xx_hal_dma2d.h"
#include <STM32DMA.hpp>
#include <cassert>
#include <touchgfx/Color.hpp>
#include <touchgfx/hal/HAL.hpp>
#include <touchgfx/hal/OSWrappers.hpp>
#include <touchgfx/lcd/LCD.hpp>
/* Makes touchgfx specific types and variables visible to this file */
using namespace touchgfx;
typedef struct
{
const uint16_t format;
const uint16_t size;
const uint32_t* const data;
} clutData_t;
extern "C" DMA2D_HandleTypeDef hdma2d;
extern "C" {
static void DMA2D_XferCpltCallback(DMA2D_HandleTypeDef* handle)
{
(void)handle; // Unused argument
HAL::getInstance()->signalDMAInterrupt();
}
}
STM32F7DMA::STM32F7DMA()
: DMA_Interface(dma_queue), dma_queue(queue_storage, sizeof(queue_storage) / sizeof(queue_storage[0]))
{
}
STM32F7DMA::~STM32F7DMA()
{
/* Disable DMA2D global Interrupt */
NVIC_DisableIRQ(DMA2D_IRQn);
}
void STM32F7DMA::initialize()
{
/* Ensure DMA2D Clock is enabled */
__HAL_RCC_DMA2D_CLK_ENABLE();
__HAL_RCC_DMA2D_FORCE_RESET();
__HAL_RCC_DMA2D_RELEASE_RESET();
/* Add transfer complete callback function */
hdma2d.XferCpltCallback = DMA2D_XferCpltCallback;
/* Enable DMA2D global Interrupt */
NVIC_EnableIRQ(DMA2D_IRQn);
}
inline uint32_t STM32F7DMA::getChromARTInputFormat(Bitmap::BitmapFormat format)
{
// Default color mode set to ARGB8888
uint32_t dma2dColorMode = DMA2D_INPUT_ARGB8888;
switch (format)
{
case Bitmap::ARGB8888: /* DMA2D input mode set to 32bit ARGB */
dma2dColorMode = DMA2D_INPUT_ARGB8888;
break;
case Bitmap::RGB888: /* DMA2D input mode set to 24bit RGB */
dma2dColorMode = DMA2D_INPUT_RGB888;
break;
case Bitmap::RGB565: /* DMA2D input mode set to 16bit RGB */
dma2dColorMode = DMA2D_INPUT_RGB565;
break;
case Bitmap::ARGB2222: /* Fall through */
case Bitmap::ABGR2222: /* Fall through */
case Bitmap::RGBA2222: /* Fall through */
case Bitmap::BGRA2222: /* Fall through */
case Bitmap::L8: /* DMA2D input mode set to 8bit Color Look up table*/
dma2dColorMode = DMA2D_INPUT_L8;
break;
case Bitmap::BW: /* Fall through */
case Bitmap::BW_RLE: /* Fall through */
case Bitmap::GRAY4: /* Fall through */
case Bitmap::GRAY2: /* Fall through */
default: /* Unsupported input format for DMA2D */
assert(0 && "Unsupported Format!");
break;
}
return dma2dColorMode;
}
inline uint32_t STM32F7DMA::getChromARTOutputFormat(Bitmap::BitmapFormat format)
{
// Default color mode set to ARGB8888
uint32_t dma2dColorMode = DMA2D_OUTPUT_ARGB8888;
switch (format)
{
case Bitmap::ARGB8888: /* DMA2D output mode set to 32bit ARGB */
dma2dColorMode = DMA2D_OUTPUT_ARGB8888;
break;
case Bitmap::RGB888: /* Fall through */
case Bitmap::ARGB2222: /* Fall through */
case Bitmap::ABGR2222: /* Fall through */
case Bitmap::RGBA2222: /* Fall through */
case Bitmap::BGRA2222: /* DMA2D output mode set to 24bit RGB */
dma2dColorMode = DMA2D_OUTPUT_RGB888;
break;
case Bitmap::RGB565: /* DMA2D output mode set to 16bit RGB */
dma2dColorMode = DMA2D_OUTPUT_RGB565;
break;
case Bitmap::L8: /* Fall through */
case Bitmap::BW: /* Fall through */
case Bitmap::BW_RLE: /* Fall through */
case Bitmap::GRAY4: /* Fall through */
case Bitmap::GRAY2: /* Fall through */
default: /* Unsupported output format for DMA2D */
assert(0 && "Unsupported Format!");
break;
}
return dma2dColorMode;
}
BlitOperations STM32F7DMA::getBlitCaps()
{
return static_cast<BlitOperations>(BLIT_OP_FILL
| BLIT_OP_FILL_WITH_ALPHA
| BLIT_OP_COPY
| BLIT_OP_COPY_WITH_ALPHA
| BLIT_OP_COPY_ARGB8888
| BLIT_OP_COPY_ARGB8888_WITH_ALPHA
| BLIT_OP_COPY_A4
| BLIT_OP_COPY_A8);
}
/*
* void STM32F7DMA::setupDataCopy(const BlitOp& blitOp) handles blit operation of
* BLIT_OP_COPY
* BLIT_OP_COPY_WITH_ALPHA
* BLIT_OP_COPY_ARGB8888
* BLIT_OP_COPY_ARGB8888_WITH_ALPHA
* BLIT_OP_COPY_A4
* BLIT_OP_COPY_A8
*/
void STM32F7DMA::setupDataCopy(const BlitOp& blitOp)
{
uint32_t dma2dForegroundColorMode = getChromARTInputFormat(static_cast<Bitmap::BitmapFormat>(blitOp.srcFormat));
uint32_t dma2dBackgroundColorMode = getChromARTInputFormat(static_cast<Bitmap::BitmapFormat>(blitOp.dstFormat));
uint32_t dma2dOutputColorMode = getChromARTOutputFormat(static_cast<Bitmap::BitmapFormat>(blitOp.dstFormat));
/* DMA2D OOR register configuration ------------------------------------------*/
WRITE_REG(DMA2D->OOR, blitOp.dstLoopStride - blitOp.nSteps);
/* DMA2D BGOR register configuration -------------------------------------*/
WRITE_REG(DMA2D->BGOR, blitOp.dstLoopStride - blitOp.nSteps);
/* DMA2D FGOR register configuration -------------------------------------*/
WRITE_REG(DMA2D->FGOR, blitOp.srcLoopStride - blitOp.nSteps);
/* DMA2D OPFCCR register configuration ---------------------------------------*/
WRITE_REG(DMA2D->OPFCCR, dma2dOutputColorMode);
/* Configure DMA2D data size */
WRITE_REG(DMA2D->NLR, (blitOp.nLoops | (blitOp.nSteps << DMA2D_NLR_PL_Pos)));
/* Configure DMA2D destination address */
WRITE_REG(DMA2D->OMAR, reinterpret_cast<uint32_t>(blitOp.pDst));
/* Configure DMA2D source address */
WRITE_REG(DMA2D->FGMAR, reinterpret_cast<uint32_t>(blitOp.pSrc));
switch (blitOp.operation)
{
case BLIT_OP_COPY_A4:
/* Set DMA2D color mode and alpha mode */
WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_A4 | (DMA2D_COMBINE_ALPHA << DMA2D_BGPFCCR_AM_Pos) | (blitOp.alpha << 24));
/* set DMA2D foreground color */
WRITE_REG(DMA2D->FGCOLR, ((blitOp.color & 0xF800) << 8) | ((blitOp.color & 0x07E0) << 5) | ((blitOp.color & 0x001F) << 3));
/* Write DMA2D BGPFCCR register */
WRITE_REG(DMA2D->BGPFCCR, dma2dBackgroundColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos));
/* Configure DMA2D Stream source2 address */
WRITE_REG(DMA2D->BGMAR, reinterpret_cast<uint32_t>(blitOp.pDst));
/* Set DMA2D mode */
WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_IT_TC | DMA2D_CR_START);
break;
case BLIT_OP_COPY_A8:
/* Set DMA2D color mode and alpha mode */
WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_A8 | (DMA2D_COMBINE_ALPHA << DMA2D_BGPFCCR_AM_Pos) | (blitOp.alpha << 24));
/* set DMA2D foreground color */
WRITE_REG(DMA2D->FGCOLR, ((blitOp.color & 0xF800) << 8) | ((blitOp.color & 0x07E0) << 5) | ((blitOp.color & 0x001F) << 3));
/* Write DMA2D BGPFCCR register */
WRITE_REG(DMA2D->BGPFCCR, dma2dBackgroundColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos));
/* Configure DMA2D Stream source2 address */
WRITE_REG(DMA2D->BGMAR, reinterpret_cast<uint32_t>(blitOp.pDst));
/* Set DMA2D mode */
WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_IT_TC | DMA2D_CR_START);
break;
case BLIT_OP_COPY_WITH_ALPHA:
/* Set DMA2D color mode and alpha mode */
WRITE_REG(DMA2D->FGPFCCR, dma2dForegroundColorMode | (DMA2D_COMBINE_ALPHA << DMA2D_BGPFCCR_AM_Pos) | (blitOp.alpha << 24));
/* Write DMA2D BGPFCCR register */
WRITE_REG(DMA2D->BGPFCCR, dma2dBackgroundColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos));
/* Configure DMA2D Stream source2 address */
WRITE_REG(DMA2D->BGMAR, reinterpret_cast<uint32_t>(blitOp.pDst));
if (blitOp.srcFormat == Bitmap::L8)
{
const clutData_t* const palette = reinterpret_cast<const clutData_t*>(blitOp.pClut);
/* Write foreground CLUT memory address */
WRITE_REG(DMA2D->FGCMAR, reinterpret_cast<uint32_t>(&palette->data));
switch ((Bitmap::ClutFormat)palette->format)
{
case Bitmap::CLUT_FORMAT_L8_ARGB8888:
/* Write foreground CLUT size and CLUT color mode */
MODIFY_REG(DMA2D->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), (((palette->size - 1) << DMA2D_FGPFCCR_CS_Pos) | (DMA2D_CCM_ARGB8888 << DMA2D_FGPFCCR_CCM_Pos)));
break;
case Bitmap::CLUT_FORMAT_L8_RGB888:
MODIFY_REG(DMA2D->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), (((palette->size - 1) << DMA2D_FGPFCCR_CS_Pos) | (DMA2D_CCM_RGB888 << DMA2D_FGPFCCR_CCM_Pos)));
break;
case Bitmap::CLUT_FORMAT_L8_RGB565:
default:
assert(0 && "Unsupported format");
break;
}
/* Enable the CLUT loading for the foreground */
SET_BIT(DMA2D->FGPFCCR, DMA2D_FGPFCCR_START);
while ((READ_REG(DMA2D->FGPFCCR) & DMA2D_FGPFCCR_START) != 0U)
{
__NOP();
}
DMA2D->IFCR = (DMA2D_FLAG_CTC);
}
/* Set DMA2D mode */
WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_IT_TC | DMA2D_CR_START);
break;
case BLIT_OP_COPY_ARGB8888:
case BLIT_OP_COPY_ARGB8888_WITH_ALPHA:
/* Set DMA2D color mode and alpha mode */
WRITE_REG(DMA2D->FGPFCCR, dma2dForegroundColorMode | (DMA2D_COMBINE_ALPHA << DMA2D_BGPFCCR_AM_Pos) | (blitOp.alpha << 24));
/* Write DMA2D BGPFCCR register */
WRITE_REG(DMA2D->BGPFCCR, dma2dBackgroundColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos));
/* Configure DMA2D Stream source2 address */
WRITE_REG(DMA2D->BGMAR, reinterpret_cast<uint32_t>(blitOp.pDst));
/* Set DMA2D mode */
WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_IT_TC | DMA2D_CR_START);
break;
default: /* BLIT_OP_COPY */
/* Set DMA2D color mode and alpha mode */
WRITE_REG(DMA2D->FGPFCCR, dma2dForegroundColorMode | (DMA2D_COMBINE_ALPHA << DMA2D_BGPFCCR_AM_Pos) | (blitOp.alpha << 24));
if (blitOp.srcFormat == Bitmap::L8)
{
const clutData_t* const palette = reinterpret_cast<const clutData_t*>(blitOp.pClut);
/* Write foreground CLUT memory address */
WRITE_REG(DMA2D->FGCMAR, reinterpret_cast<uint32_t>(&palette->data));
/* Write foreground CLUT size and CLUT color mode */
MODIFY_REG(DMA2D->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), (((palette->size - 1) << DMA2D_FGPFCCR_CS_Pos) | (DMA2D_CCM_RGB888 << DMA2D_FGPFCCR_CCM_Pos)));
/* Enable the CLUT loading for the foreground */
SET_BIT(DMA2D->FGPFCCR, DMA2D_FGPFCCR_START);
while ((READ_REG(DMA2D->FGPFCCR) & DMA2D_FGPFCCR_START) != 0U)
{
__NOP();
}
DMA2D->IFCR = (DMA2D_FLAG_CTC);
/* Start DMA2D */
WRITE_REG(DMA2D->CR, DMA2D_M2M_PFC | DMA2D_IT_TC | DMA2D_CR_START);
}
else
{
/* Start DMA2D */
WRITE_REG(DMA2D->CR, DMA2D_M2M | DMA2D_IT_TC | DMA2D_CR_START);
}
break;
}
}
/*
* void STM32F7DMA::setupDataFill(const BlitOp& blitOp) handles blit operation of
* BLIT_OP_FILL
* BLIT_OP_FILL_WITH_ALPHA
*/
void STM32F7DMA::setupDataFill(const BlitOp& blitOp)
{
uint32_t dma2dOutputColorMode = getChromARTOutputFormat(static_cast<Bitmap::BitmapFormat>(blitOp.dstFormat));
/* DMA2D OPFCCR register configuration ---------------------------------------*/
WRITE_REG(DMA2D->OPFCCR, dma2dOutputColorMode);
/* Configure DMA2D data size */
WRITE_REG(DMA2D->NLR, (blitOp.nLoops | (blitOp.nSteps << DMA2D_NLR_PL_Pos)));
/* Configure DMA2D destination address */
WRITE_REG(DMA2D->OMAR, reinterpret_cast<uint32_t>(blitOp.pDst));
/* DMA2D OOR register configuration ------------------------------------------*/
WRITE_REG(DMA2D->OOR, blitOp.dstLoopStride - blitOp.nSteps);
if (blitOp.operation == BLIT_OP_FILL_WITH_ALPHA)
{
/* DMA2D BGOR register configuration -------------------------------------*/
WRITE_REG(DMA2D->BGOR, blitOp.dstLoopStride - blitOp.nSteps);
/* DMA2D FGOR register configuration -------------------------------------*/
WRITE_REG(DMA2D->FGOR, blitOp.dstLoopStride - blitOp.nSteps);
/* Write DMA2D BGPFCCR register */
WRITE_REG(DMA2D->BGPFCCR, dma2dOutputColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos));
/* Write DMA2D FGPFCCR register */
WRITE_REG(DMA2D->FGPFCCR, CM_A8 | (DMA2D_REPLACE_ALPHA << DMA2D_BGPFCCR_AM_Pos) | ((blitOp.alpha << 24) & DMA2D_BGPFCCR_ALPHA));
/* DMA2D FGCOLR register configuration -------------------------------------*/
WRITE_REG(DMA2D->FGCOLR, ((blitOp.alpha << 24) | ((blitOp.color & 0xF800) << 8) | ((blitOp.color & 0x07E0) << 5) | ((blitOp.color & 0x001F) << 3)) & (DMA2D_FGCOLR_BLUE | DMA2D_FGCOLR_GREEN | DMA2D_FGCOLR_RED));
/* Configure DMA2D Stream source2 address */
WRITE_REG(DMA2D->BGMAR, reinterpret_cast<uint32_t>(blitOp.pDst));
/* Configure DMA2D source address */
WRITE_REG(DMA2D->FGMAR, reinterpret_cast<uint32_t>(blitOp.pDst));
/* Enable the Peripheral and Enable the transfer complete interrupt */
WRITE_REG(DMA2D->CR, (DMA2D_IT_TC | DMA2D_CR_START | DMA2D_M2M_BLEND));
}
else
{
/* Write DMA2D FGPFCCR register */
WRITE_REG(DMA2D->FGPFCCR, dma2dOutputColorMode | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos));
/* DMA2D FGOR register configuration -------------------------------------*/
WRITE_REG(DMA2D->FGOR, 0);
if (blitOp.dstFormat == Bitmap::RGB565)
{
// set color
WRITE_REG(DMA2D->OCOLR, blitOp.color);
}
else
{
// set color
WRITE_REG(DMA2D->OCOLR, (blitOp.alpha << 24) | (blitOp.alpha << 24) | ((blitOp.color & 0xF800) << 8) | ((blitOp.color & 0x07E0) << 5) | ((blitOp.color & 0x001F) << 3));
}
/* Enable the Peripheral and Enable the transfer complete interrupt */
WRITE_REG(DMA2D->CR, (DMA2D_IT_TC | DMA2D_CR_START | DMA2D_R2M));
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,164 @@
/**
******************************************************************************
* File Name : STM32DMA.hpp
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 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
*
******************************************************************************
*/
#ifndef STM32F7DMA_HPP
#define STM32F7DMA_HPP
#include <touchgfx/Bitmap.hpp>
#include <touchgfx/hal/DMA.hpp>
/**
* @class STM32F7DMA
*
* @brief This class specializes DMA_Interface for the STM32F7 processors.
*
* @sa touchgfx::DMA_Interface
*/
class STM32F7DMA : 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 STM32F7DMA::STM32F7DMA();
*
* @brief Default constructor.
*
* Default constructor.
*/
STM32F7DMA();
/**
* @fn STM32F7DMA::~STM32F7DMA();
*
* @brief Destructor.
*
* Destructor.
*/
virtual ~STM32F7DMA();
/**
* @fn DMAType touchgfx::STM32F7DMA::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 STM32F7DMA::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 STM32F7DMA::initialize();
*
* @brief Perform hardware specific initialization.
*
* Perform hardware specific initialization.
*/
virtual void initialize();
/**
* @fn void STM32F7DMA::signalDMAInterrupt()
*
* @brief Raises a DMA interrupt signal.
*
* Raises a DMA interrupt signal.
*/
virtual void signalDMAInterrupt()
{
executeCompleted();
}
protected:
/**
* @fn virtual void STM32F7DMA::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 STM32F7DMA::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);
private:
touchgfx::LockFreeDMA_Queue dma_queue;
touchgfx::BlitOp queue_storage[96];
/**
* @fn void STM32F7DMA::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 STM32F7DMA::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 // STM32F7DMA_HPP
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,68 @@
/**
******************************************************************************
* File Name : TouchGFXConfiguration.cpp
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 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
*
******************************************************************************
*/
#include <texts/TypedTextDatabase.hpp>
#include <fonts/ApplicationFontProvider.hpp>
#include <gui/common/FrontendHeap.hpp>
#include <BitmapDatabase.hpp>
#include <platform/driver/lcd/LCD16bpp.hpp>
#include <STM32DMA.hpp>
#include <TouchGFXHAL.hpp>
#include <STM32TouchController.hpp>
#include <stm32f7xx_hal.h>
extern "C" void touchgfx_init();
extern "C" void touchgfx_taskEntry();
static STM32TouchController tc;
static STM32F7DMA dma;
static LCD16bpp display;
static ApplicationFontProvider fontProvider;
static Texts texts;
static TouchGFXHAL hal(dma, display, tc, 480, 272);
void touchgfx_init()
{
Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(), BitmapDatabase::getInstanceSize());
TypedText::registerTexts(&texts);
Texts::setLanguage(0);
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_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****/

View File

@ -0,0 +1,147 @@
/**
******************************************************************************
* File Name : TouchGFXGeneratedHAL.cpp
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 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
*
******************************************************************************
*/
#include <TouchGFXGeneratedHAL.hpp>
#include <touchgfx/hal/OSWrappers.hpp>
#include <gui/common/FrontendHeap.hpp>
#include <touchgfx/hal/GPIO.hpp>
#include "stm32f7xx.h"
#include "stm32f7xx_hal_ltdc.h"
using namespace touchgfx;
namespace {
static uint16_t lcd_int_active_line;
static uint16_t lcd_int_porch_line;
}
void TouchGFXGeneratedHAL::initialize()
{
HAL::initialize();
registerEventListener(*(Application::getInstance()));
setFrameBufferStartAddresses((void*)0xC0000000, (void*)0xC003FC00, (void*)0);
}
void TouchGFXGeneratedHAL::configureInterrupts()
{
NVIC_SetPriority(DMA2D_IRQn, 9);
NVIC_SetPriority(LTDC_IRQn, 9);
}
void TouchGFXGeneratedHAL::enableInterrupts()
{
NVIC_EnableIRQ(DMA2D_IRQn);
NVIC_EnableIRQ(LTDC_IRQn);
}
void TouchGFXGeneratedHAL::disableInterrupts()
{
NVIC_DisableIRQ(DMA2D_IRQn);
NVIC_DisableIRQ(LTDC_IRQn);
}
void TouchGFXGeneratedHAL::enableLCDControllerInterrupt()
{
lcd_int_active_line = (LTDC->BPCR & 0x7FF) - 1;
lcd_int_porch_line = (LTDC->AWCR & 0x7FF) - 1;
/* Sets the Line Interrupt position */
LTDC->LIPCR = lcd_int_active_line;
/* Line Interrupt Enable */
LTDC->IER |= LTDC_IER_LIE;
}
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)
{
HAL::flushFrameBuffer(rect);
// If the framebuffer is placed in Write Through cached memory (e.g. SRAM) then we need
// to flush the Dcache prior to letting DMA2D accessing it. That's done
// using SCB_CleanInvalidateDCache().
if ((SCB->CCR & SCB_CCR_DC_Msk) != 0) // Check data cache is enabled
{
SCB_CleanInvalidateDCache();
}
}
bool TouchGFXGeneratedHAL::blockCopy(void* RESTRICT dest, const void* RESTRICT src, uint32_t numBytes)
{
return HAL::blockCopy(dest, src, numBytes);
}
void TouchGFXGeneratedHAL::InvalidateCache()
{
// If the framebuffer is placed in Write Through cached memory (e.g. SRAM) then we need
// to flush the Dcache prior to letting DMA2D accessing it. That's done
// using SCB_CleanInvalidateDCache().
if ((SCB->CCR & SCB_CCR_DC_Msk) != 0) // Check data cache is enabled
{
SCB_CleanInvalidateDCache();
}
}
void TouchGFXGeneratedHAL::FlushCache()
{
// If the framebuffer is placed in Write Through cached memory (e.g. SRAM) then we need
// to flush the Dcache prior to letting DMA2D accessing it. That's done
// using SCB_CleanInvalidateDCache().
if ((SCB->CCR & SCB_CCR_DC_Msk) != 0) // Check data cache is enabled
{
SCB_CleanInvalidateDCache();
}
}
extern "C"
{
void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *hltdc)
{
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);
GPIO::clear(GPIO::VSYNC_FREQ);
HAL::getInstance()->frontPorchEntered();
}
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,168 @@
/**
******************************************************************************
* File Name : TouchGFXGeneratedHAL.hpp
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 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
*
******************************************************************************
*/
#ifndef TouchGFXGeneratedHAL_HPP
#define TouchGFXGeneratedHAL_HPP
#include <touchgfx/hal/HAL.hpp>
/**
* @class TouchGFXGeneratedHAL
*
* @brief HAL implementation for TouchGFXGenerated.
*
* @sa HAL
*/
class TouchGFXGeneratedHAL : public touchgfx::HAL
{
public:
/**
* @fn TouchGFXGeneratedHAL::TouchGFXGeneratedHAL(touchgfx::DMA_Interface& dma, touchgfx::LCD& display, touchgfx::TouchController& tc, uint16_t width, uint16_t height) : touchgfx::HAL(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::HAL(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.
*/
void initialize();
/**
* @fn virtual void TouchGFXGeneratedHAL::configureInterrupts();
*
* @brief Sets the DMA and LCD interrupt priorities.
*
* Sets the DMA and LCD interrupt priorities.
*/
virtual void configureInterrupts();
/**
* @fn virtual void TouchGFXGeneratedHAL::enableInterrupts();
*
* @brief Enables the DMA and LCD interrupts.
*
* Enables the DMA and LCD interrupts.
*/
virtual void enableInterrupts();
/**
* @fn virtual void TouchGFXGeneratedHAL::disableInterrupts();
*
* @brief Disables the DMA and LCD interrupts.
*
* Disables the DMA and LCD 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::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.
* 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 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);
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();
};
#endif // TouchGFXGeneratedHAL_HPP
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/