/** ****************************************************************************** * File Name : TouchGFXGeneratedHAL.cpp ****************************************************************************** * @attention * *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * 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 #include #include #include #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****/