148 lines
4.4 KiB
C++
148 lines
4.4 KiB
C++
|
/**
|
||
|
******************************************************************************
|
||
|
* File Name : TouchGFXGeneratedHAL.cpp
|
||
|
******************************************************************************
|
||
|
* @attention
|
||
|
*
|
||
|
* <h2><center>© 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****/
|