689 lines
24 KiB
C++
689 lines
24 KiB
C++
|
|
/**
|
|
******************************************************************************
|
|
* File Name : STM32DMA.cpp
|
|
******************************************************************************
|
|
* This file is generated by TouchGFX Generator 4.22.0. Please, do not edit!
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2023 STMicroelectronics.
|
|
* All rights reserved.
|
|
*
|
|
* This software is licensed under terms that can be found in the LICENSE file
|
|
* in the root directory of this software component.
|
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include "stm32h7xx_hal.h"
|
|
#include "stm32h7xx_hal_dma2d.h"
|
|
#include <STM32DMA.hpp>
|
|
#include <cassert>
|
|
#include <touchgfx/Color.hpp>
|
|
#include <touchgfx/hal/HAL.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" void DMA2D_IRQHandler()
|
|
{
|
|
/* Transfer Complete Interrupt management ************************************/
|
|
if ((READ_REG(DMA2D->ISR) & DMA2D_FLAG_TC) != RESET)
|
|
{
|
|
/* Verify Transfer Complete Interrupt */
|
|
if ((READ_REG(DMA2D->CR) & DMA2D_IT_TC) != RESET)
|
|
{
|
|
/* Disable the transfer complete interrupt */
|
|
DMA2D->CR &= ~(DMA2D_IT_TC);
|
|
|
|
/* Clear the transfer complete flag */
|
|
DMA2D->IFCR = (DMA2D_FLAG_TC);
|
|
|
|
/* Signal DMA queue of execution complete */
|
|
touchgfx::HAL::getInstance()->signalDMAInterrupt();
|
|
}
|
|
}
|
|
}
|
|
|
|
STM32DMA::STM32DMA()
|
|
: DMA_Interface(dma_queue), dma_queue(queue_storage, sizeof(queue_storage) / sizeof(queue_storage[0]))
|
|
{
|
|
}
|
|
|
|
STM32DMA::~STM32DMA()
|
|
{
|
|
/* Disable DMA2D global Interrupt */
|
|
NVIC_DisableIRQ(DMA2D_IRQn);
|
|
}
|
|
|
|
void STM32DMA::initialize()
|
|
{
|
|
/* Ensure DMA2D Clock is enabled */
|
|
__HAL_RCC_DMA2D_CLK_ENABLE();
|
|
__HAL_RCC_DMA2D_FORCE_RESET();
|
|
__HAL_RCC_DMA2D_RELEASE_RESET();
|
|
|
|
/* Enable DMA2D global Interrupt */
|
|
HAL_NVIC_SetPriority(DMA2D_IRQn, 5, 0);
|
|
HAL_NVIC_EnableIRQ(DMA2D_IRQn);
|
|
}
|
|
|
|
inline uint32_t STM32DMA::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 STM32DMA::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 STM32DMA::getBlitCaps()
|
|
{
|
|
return static_cast<BlitOperations>(BLIT_OP_FILL
|
|
| BLIT_OP_FILL_WITH_ALPHA
|
|
| BLIT_OP_COPY
|
|
| BLIT_OP_COPY_L8
|
|
| BLIT_OP_COPY_WITH_ALPHA
|
|
| BLIT_OP_COPY_ARGB8888
|
|
| BLIT_OP_COPY_ARGB8888_WITH_ALPHA
|
|
| BLIT_OP_COPY_A4
|
|
| BLIT_OP_COPY_A8);
|
|
}
|
|
|
|
/*
|
|
* void STM32DMA::setupDataCopy(const BlitOp& blitOp) handles blit operation of
|
|
* BLIT_OP_COPY
|
|
* BLIT_OP_COPY_L8
|
|
* BLIT_OP_COPY_WITH_ALPHA
|
|
* BLIT_OP_COPY_ARGB8888
|
|
* BLIT_OP_COPY_ARGB8888_WITH_ALPHA
|
|
* BLIT_OP_COPY_A4
|
|
* BLIT_OP_COPY_A8
|
|
*/
|
|
void STM32DMA::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_FGPFCCR_AM_Pos) | (blitOp.alpha << 24));
|
|
|
|
/* set DMA2D foreground color */
|
|
WRITE_REG(DMA2D->FGCOLR, blitOp.color);
|
|
|
|
/* 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_FGPFCCR_AM_Pos) | (blitOp.alpha << 24));
|
|
|
|
/* set DMA2D foreground color */
|
|
WRITE_REG(DMA2D->FGCOLR, blitOp.color);
|
|
|
|
/* 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_FGPFCCR_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;
|
|
case BLIT_OP_COPY_L8:
|
|
{
|
|
bool blend = true;
|
|
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));
|
|
|
|
/* Set DMA2D color mode and alpha mode */
|
|
WRITE_REG(DMA2D->FGPFCCR, dma2dForegroundColorMode | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_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));
|
|
|
|
/* Configure CLUT */
|
|
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:
|
|
if (blitOp.alpha == 255)
|
|
{
|
|
blend = false;
|
|
}
|
|
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)
|
|
{
|
|
}
|
|
DMA2D->IFCR = (DMA2D_FLAG_CTC);
|
|
|
|
/* Set DMA2D mode */
|
|
if (blend)
|
|
{
|
|
WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_IT_TC | DMA2D_CR_START);
|
|
}
|
|
else
|
|
{
|
|
WRITE_REG(DMA2D->CR, DMA2D_M2M_PFC | 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_FGPFCCR_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_FGPFCCR_AM_Pos) | (blitOp.alpha << 24));
|
|
|
|
/* Perform pixel-format-conversion (PFC) If Bitmap format is not same format as framebuffer format */
|
|
if (blitOp.srcFormat != blitOp.dstFormat)
|
|
{
|
|
/* Start DMA2D : PFC Mode */
|
|
WRITE_REG(DMA2D->CR, DMA2D_M2M_PFC | DMA2D_IT_TC | DMA2D_CR_START);
|
|
}
|
|
else
|
|
{
|
|
/* Start DMA2D : M2M Mode */
|
|
WRITE_REG(DMA2D->CR, DMA2D_M2M | DMA2D_IT_TC | DMA2D_CR_START);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* void STM32DMA::setupDataFill(const BlitOp& blitOp) handles blit operation of
|
|
* BLIT_OP_FILL
|
|
* BLIT_OP_FILL_WITH_ALPHA
|
|
*/
|
|
void STM32DMA::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, DMA2D_INPUT_A8 | (DMA2D_REPLACE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | ((blitOp.alpha << 24) & DMA2D_FGPFCCR_ALPHA));
|
|
|
|
/* DMA2D FGCOLR register configuration */
|
|
WRITE_REG(DMA2D->FGCOLR, blitOp.color);
|
|
|
|
/* 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_FGPFCCR_AM_Pos));
|
|
|
|
/* DMA2D FGOR register configuration */
|
|
WRITE_REG(DMA2D->FGOR, 0);
|
|
|
|
/* Set color */
|
|
WRITE_REG(DMA2D->OCOLR, ((blitOp.color >> 8) & 0xF800) | ((blitOp.color >> 5) & 0x07E0) | ((blitOp.color >> 3) & 0x001F));
|
|
|
|
/* Enable the Peripheral and Enable the transfer complete interrupt */
|
|
WRITE_REG(DMA2D->CR, (DMA2D_IT_TC | DMA2D_CR_START | DMA2D_R2M));
|
|
}
|
|
}
|
|
|
|
namespace touchgfx
|
|
{
|
|
namespace paint
|
|
{
|
|
namespace
|
|
{
|
|
const clutData_t* L8CLUT = 0;
|
|
uint32_t L8ClutLoaded = 0;
|
|
} // namespace
|
|
|
|
void setL8Palette(const uint8_t* const data)
|
|
{
|
|
L8CLUT = reinterpret_cast<const clutData_t*>(data - offsetof(clutData_t, data));
|
|
L8ClutLoaded = 0;
|
|
}
|
|
|
|
/**
|
|
* @fn void tearDown();
|
|
*
|
|
* @brief Waits until previous DMA drawing operation has finished
|
|
*/
|
|
void tearDown()
|
|
{
|
|
/* Wait for DMA2D to finish last run */
|
|
while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U);
|
|
|
|
/* Clear transfer flags */
|
|
WRITE_REG(DMA2D->IFCR, DMA2D_FLAG_TC | DMA2D_FLAG_CE | DMA2D_FLAG_TE);
|
|
}
|
|
|
|
namespace rgb565
|
|
{
|
|
/**
|
|
* @fn void lineFromColor();
|
|
*
|
|
* @brief Renders Canvas Widget chunks using DMA.
|
|
* This functions will not generate an interrupt, and will not affect the DMA queue.
|
|
*/
|
|
void lineFromColor(uint16_t* const ptr, const unsigned count, const uint32_t color, const uint8_t alpha, const uint32_t color565)
|
|
{
|
|
/* Wait for DMA2D to finish last run */
|
|
while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U);
|
|
|
|
/* Clear transfer flags */
|
|
WRITE_REG(DMA2D->IFCR, DMA2D_FLAG_TC | DMA2D_FLAG_CE | DMA2D_FLAG_TE);
|
|
|
|
/* DMA2D OPFCCR register configuration */
|
|
WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565);
|
|
|
|
/* Configure DMA2D data size */
|
|
WRITE_REG(DMA2D->NLR, (1 | (count << DMA2D_NLR_PL_Pos)));
|
|
|
|
/* Configure DMA2D destination address */
|
|
WRITE_REG(DMA2D->OMAR, reinterpret_cast<uint32_t>(ptr));
|
|
|
|
if (alpha < 0xFF)
|
|
{
|
|
/* Write DMA2D BGPFCCR register */
|
|
WRITE_REG(DMA2D->BGPFCCR, DMA2D_OUTPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos));
|
|
|
|
/* Write DMA2D FGPFCCR register */
|
|
WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_A8 | (DMA2D_REPLACE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | ((alpha << 24) & DMA2D_FGPFCCR_ALPHA));
|
|
|
|
/* DMA2D FGCOLR register configuration */
|
|
WRITE_REG(DMA2D->FGCOLR, color);
|
|
|
|
/* Configure DMA2D Stream source2 address */
|
|
WRITE_REG(DMA2D->BGMAR, (uint32_t)ptr);
|
|
|
|
/* Configure DMA2D source address */
|
|
WRITE_REG(DMA2D->FGMAR, (uint32_t)ptr);
|
|
|
|
/* Enable the Peripheral and Enable the transfer complete interrupt */
|
|
WRITE_REG(DMA2D->CR, (DMA2D_CR_START | DMA2D_M2M_BLEND));
|
|
}
|
|
else
|
|
{
|
|
/* Write DMA2D FGPFCCR register */
|
|
WRITE_REG(DMA2D->FGPFCCR, DMA2D_OUTPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_FGPFCCR_AM_Pos));
|
|
|
|
/* Set color */
|
|
WRITE_REG(DMA2D->OCOLR, color565);
|
|
|
|
/* Enable the Peripheral and Enable the transfer complete interrupt */
|
|
WRITE_REG(DMA2D->CR, (DMA2D_CR_START | DMA2D_R2M));
|
|
}
|
|
}
|
|
|
|
void lineFromRGB565(uint16_t* const ptr, const uint16_t* const data, const unsigned count, const uint8_t alpha)
|
|
{
|
|
/* Wait for DMA2D to finish last run */
|
|
while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U);
|
|
|
|
/* Clear transfer flags */
|
|
WRITE_REG(DMA2D->IFCR, DMA2D_FLAG_TC | DMA2D_FLAG_CE | DMA2D_FLAG_TE);
|
|
|
|
/* DMA2D OPFCCR register configuration */
|
|
WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565);
|
|
|
|
/* Configure DMA2D data size */
|
|
WRITE_REG(DMA2D->NLR, (1 | (count << DMA2D_NLR_PL_Pos)));
|
|
|
|
/* Configure DMA2D destination address */
|
|
WRITE_REG(DMA2D->OMAR, reinterpret_cast<uint32_t>(ptr));
|
|
|
|
/* Configure DMA2D source address */
|
|
WRITE_REG(DMA2D->FGMAR, reinterpret_cast<uint32_t>(data));
|
|
|
|
if (alpha < 0xFF)
|
|
{
|
|
/* Set DMA2D color mode and alpha mode */
|
|
WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << 24));
|
|
|
|
/* Write DMA2D BGPFCCR register */
|
|
WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos));
|
|
|
|
/* Configure DMA2D Stream source2 address */
|
|
WRITE_REG(DMA2D->BGMAR, reinterpret_cast<uint32_t>(ptr));
|
|
|
|
/* Set DMA2D mode */
|
|
WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START);
|
|
}
|
|
else
|
|
{
|
|
/* Set DMA2D color mode and alpha mode */
|
|
WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_COMBINE_ALPHA << DMA2D_FGPFCCR_AM_Pos) | (alpha << 24));
|
|
|
|
/* Start DMA2D : M2M Mode */
|
|
WRITE_REG(DMA2D->CR, DMA2D_M2M | DMA2D_CR_START);
|
|
}
|
|
}
|
|
|
|
void lineFromARGB8888(uint16_t* const ptr, const uint32_t* const data, const unsigned count, const uint8_t alpha)
|
|
{
|
|
/* Wait for DMA2D to finish last run */
|
|
while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U);
|
|
|
|
/* Clear transfer flags */
|
|
WRITE_REG(DMA2D->IFCR, DMA2D_FLAG_TC | DMA2D_FLAG_CE | DMA2D_FLAG_TE);
|
|
|
|
/* DMA2D OPFCCR register configuration */
|
|
WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565);
|
|
|
|
/* Configure DMA2D data size */
|
|
WRITE_REG(DMA2D->NLR, (1 | (count << DMA2D_NLR_PL_Pos)));
|
|
|
|
/* Configure DMA2D destination address */
|
|
WRITE_REG(DMA2D->OMAR, reinterpret_cast<uint32_t>(ptr));
|
|
|
|
/* Configure DMA2D source address */
|
|
WRITE_REG(DMA2D->FGMAR, reinterpret_cast<uint32_t>(data));
|
|
|
|
/* Set DMA2D color mode and alpha mode */
|
|
WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_ARGB8888 | (DMA2D_COMBINE_ALPHA << DMA2D_BGPFCCR_AM_Pos) | (alpha << 24));
|
|
|
|
/* Write DMA2D BGPFCCR register */
|
|
WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos));
|
|
|
|
/* Configure DMA2D Stream source2 address */
|
|
WRITE_REG(DMA2D->BGMAR, reinterpret_cast<uint32_t>(ptr));
|
|
|
|
/* Set DMA2D mode */
|
|
WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START);
|
|
}
|
|
|
|
void lineFromL8RGB888(uint16_t* const ptr, const uint8_t* const data, const unsigned count, const uint8_t alpha)
|
|
{
|
|
/* wait for DMA2D to finish last run */
|
|
while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U);
|
|
|
|
/* DMA2D OPFCCR register configuration */
|
|
WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565);
|
|
|
|
/* Configure DMA2D data size */
|
|
WRITE_REG(DMA2D->NLR, (1 | (count << DMA2D_NLR_PL_Pos)));
|
|
|
|
/* Configure DMA2D destination address */
|
|
WRITE_REG(DMA2D->OMAR, reinterpret_cast<uint32_t>(ptr));
|
|
|
|
/* Configure DMA2D source address */
|
|
WRITE_REG(DMA2D->FGMAR, reinterpret_cast<uint32_t>(data));
|
|
|
|
/* Configure DMA2D Stream source2 address */
|
|
WRITE_REG(DMA2D->BGMAR, reinterpret_cast<uint32_t>(ptr));
|
|
|
|
/* Load CLUT if not already loaded */
|
|
if (L8ClutLoaded == 0)
|
|
{
|
|
/* Write foreground CLUT memory address */
|
|
WRITE_REG(DMA2D->FGCMAR, reinterpret_cast<uint32_t>(&L8CLUT->data));
|
|
|
|
/* Set DMA2D color mode and alpha mode */
|
|
WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_L8 | (DMA2D_COMBINE_ALPHA << DMA2D_BGPFCCR_AM_Pos) | (alpha << 24));
|
|
|
|
MODIFY_REG(DMA2D->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), (((L8CLUT->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);
|
|
|
|
/* Write DMA2D BGPFCCR register */
|
|
WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos));
|
|
|
|
/* Mark CLUT loaded */
|
|
L8ClutLoaded = 1;
|
|
|
|
/* Wait for load to finish */
|
|
while ((READ_REG(DMA2D->FGPFCCR) & DMA2D_FGPFCCR_START) != 0U);
|
|
|
|
/* Clear CLUT Transfer Complete flag */
|
|
DMA2D->IFCR = (DMA2D_FLAG_CTC);
|
|
}
|
|
else
|
|
{
|
|
/* Set correct alpha for these pixels */
|
|
MODIFY_REG(DMA2D->FGPFCCR, DMA2D_BGPFCCR_ALPHA_Msk, alpha << 24);
|
|
}
|
|
|
|
/* Start pixel transfer in correct mode */
|
|
if (alpha < 0xFF)
|
|
{
|
|
/* Set DMA2D mode */
|
|
WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START);
|
|
}
|
|
else
|
|
{
|
|
/* Set DMA2D mode */
|
|
WRITE_REG(DMA2D->CR, DMA2D_M2M_PFC | DMA2D_CR_START);
|
|
}
|
|
}
|
|
|
|
void lineFromL8ARGB8888(uint16_t* const ptr, const uint8_t* const data, const unsigned count, const uint8_t alpha)
|
|
{
|
|
/* wait for DMA2D to finish last run */
|
|
while ((READ_REG(DMA2D->CR) & DMA2D_CR_START) != 0U);
|
|
|
|
/* DMA2D OPFCCR register configuration */
|
|
WRITE_REG(DMA2D->OPFCCR, DMA2D_OUTPUT_RGB565);
|
|
|
|
/* Configure DMA2D data size */
|
|
WRITE_REG(DMA2D->NLR, (1 | (count << DMA2D_NLR_PL_Pos)));
|
|
|
|
/* Configure DMA2D destination address */
|
|
WRITE_REG(DMA2D->OMAR, reinterpret_cast<uint32_t>(ptr));
|
|
|
|
/* Configure DMA2D source address */
|
|
WRITE_REG(DMA2D->FGMAR, reinterpret_cast<uint32_t>(data));
|
|
|
|
/* Configure DMA2D Stream source2 address */
|
|
WRITE_REG(DMA2D->BGMAR, reinterpret_cast<uint32_t>(ptr));
|
|
|
|
/* Load CLUT if not already loaded */
|
|
if (L8ClutLoaded == 0)
|
|
{
|
|
/* Write foreground CLUT memory address */
|
|
WRITE_REG(DMA2D->FGCMAR, reinterpret_cast<uint32_t>(&L8CLUT->data));
|
|
|
|
/* Set DMA2D color mode and alpha mode */
|
|
WRITE_REG(DMA2D->FGPFCCR, DMA2D_INPUT_L8 | (DMA2D_COMBINE_ALPHA << DMA2D_BGPFCCR_AM_Pos) | (alpha << 24));
|
|
|
|
MODIFY_REG(DMA2D->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM), (((L8CLUT->size - 1) << DMA2D_FGPFCCR_CS_Pos) | (DMA2D_CCM_ARGB8888 << DMA2D_FGPFCCR_CCM_Pos)));
|
|
|
|
/* Enable the CLUT loading for the foreground */
|
|
SET_BIT(DMA2D->FGPFCCR, DMA2D_FGPFCCR_START);
|
|
|
|
/* Write DMA2D BGPFCCR register */
|
|
WRITE_REG(DMA2D->BGPFCCR, DMA2D_INPUT_RGB565 | (DMA2D_NO_MODIF_ALPHA << DMA2D_BGPFCCR_AM_Pos));
|
|
|
|
/* Mark CLUT loaded */
|
|
L8ClutLoaded = 1;
|
|
|
|
/* Wait for load to finish */
|
|
while ((READ_REG(DMA2D->FGPFCCR) & DMA2D_FGPFCCR_START) != 0U);
|
|
|
|
/* Clear CLUT Transfer Complete flag */
|
|
DMA2D->IFCR = (DMA2D_FLAG_CTC);
|
|
}
|
|
else
|
|
{
|
|
/* Set correct alpha for these pixels */
|
|
MODIFY_REG(DMA2D->FGPFCCR, DMA2D_BGPFCCR_ALPHA_Msk, alpha << 24);
|
|
}
|
|
|
|
/* Start pixel transfer in blending mode */
|
|
WRITE_REG(DMA2D->CR, DMA2D_M2M_BLEND | DMA2D_CR_START);
|
|
}
|
|
|
|
} // namespace rgb565
|
|
} // namespace paint
|
|
} // namespace touchgfx
|
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|