276 lines
7.4 KiB
C
276 lines
7.4 KiB
C
|
|
/**
|
|
******************************************************************************
|
|
* @file nema_hal.c
|
|
* @author MCD Application Team
|
|
* @brief NemaGFX Interfaces and Platform Specific APIs with FreeRTOS CMSISV2
|
|
* support.
|
|
* This file provides NemaGFX functions to manage the following
|
|
* functionalities of the NemaGFX library:
|
|
* + Initialization and de-initialization functions
|
|
* + GPU2D Registers access operation functions
|
|
* + Buffer Creation, Destruction, MMAP and Flusing functions
|
|
* + Interrupt management functions
|
|
* + Memory management functions
|
|
* + Locking/Unlocking resources functions
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
* All rights reserved.</center></h2>
|
|
*
|
|
* This software component is licensed by ST under BSD 3-Clause license,
|
|
* the "License"; You may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at:
|
|
* opensource.org/licenses/BSD-3-Clause
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include <touchgfx/hal/Config.hpp>
|
|
#include <nema_sys_defs.h>
|
|
#include <nema_core.h>
|
|
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
|
|
#include <stm32h7rsxx_hal.h>
|
|
|
|
#include <cmsis_os2.h>
|
|
|
|
#include "tsi_malloc.h"
|
|
|
|
#define RING_SIZE 1024 /* Ring Buffer Size in byte */
|
|
#define NEMAGFX_MEM_POOL_SIZE 24320 /* NemaGFX byte pool size in byte */
|
|
#define NEMAGFX_STENCIL_POOL_SIZE 389120 /* NemaGFX stencil buffer pool size in byte */
|
|
|
|
LOCATION_PRAGMA_NOLOAD("Nemagfx_Memory_Pool_Buffer")
|
|
static uint8_t nemagfx_pool_mem[NEMAGFX_MEM_POOL_SIZE] LOCATION_ATTRIBUTE_NOLOAD("Nemagfx_Memory_Pool_Buffer"); /* NemaGFX memory pool */
|
|
|
|
LOCATION_PRAGMA_NOLOAD("Nemagfx_Stencil_Buffer")
|
|
static uint8_t nemagfx_stencil_buffer_mem[NEMAGFX_STENCIL_POOL_SIZE] LOCATION_ATTRIBUTE_NOLOAD("Nemagfx_Stencil_Buffer"); /* NemaGFX stencil buffer memory */
|
|
|
|
static nema_ringbuffer_t ring_buffer_str;
|
|
volatile static int last_cl_id = -1;
|
|
extern GPU2D_HandleTypeDef hgpu2d;
|
|
|
|
static osSemaphoreId_t nema_irq_sem = NULL; // Declare CL IRQ semaphore
|
|
|
|
#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1)
|
|
static void GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef* hgpu2d, uint32_t CmdListID)
|
|
#else /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 0 */
|
|
void HAL_GPU2D_CommandListCpltCallback(GPU2D_HandleTypeDef* hgpu2d, uint32_t CmdListID)
|
|
#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */
|
|
{
|
|
/* Prevent unused argument(s) compilation warning */
|
|
UNUSED(hgpu2d);
|
|
|
|
last_cl_id = CmdListID;
|
|
|
|
/* Return a token back to a semaphore */
|
|
osSemaphoreRelease(nema_irq_sem);
|
|
}
|
|
|
|
void HAL_GPU2D_ErrorCallback(GPU2D_HandleTypeDef *hgpu2d)
|
|
{
|
|
uint32_t val = nema_reg_read(GPU2D_SYS_INTERRUPT); /* clear the ER interrupt */
|
|
nema_reg_write(GPU2D_SYS_INTERRUPT, val);
|
|
|
|
/* external GPU2D cache maintenance */
|
|
if (val & (1UL << 2))
|
|
{
|
|
HAL_ICACHE_Disable();
|
|
nema_ext_hold_deassert_imm(2);
|
|
}
|
|
if (val & (1UL << 3))
|
|
{
|
|
HAL_ICACHE_Enable();
|
|
HAL_ICACHE_Invalidate();
|
|
nema_ext_hold_deassert_imm(3);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void platform_disable_cache(void)
|
|
{
|
|
nema_ext_hold_assert(2, 1);
|
|
}
|
|
|
|
void platform_invalidate_cache(void)
|
|
{
|
|
nema_ext_hold_assert(3, 1);
|
|
}
|
|
|
|
int32_t nema_sys_init(void)
|
|
{
|
|
int error_code = 0;
|
|
|
|
/* Setup GPU2D Callback */
|
|
#if (USE_HAL_GPU2D_REGISTER_CALLBACKS == 1)
|
|
/* Register Command List Comlete Callback */
|
|
HAL_GPU2D_RegisterCommandListCpltCallback(&hgpu2d, GPU2D_CommandListCpltCallback);
|
|
#endif /* USE_HAL_GPU2D_REGISTER_CALLBACKS = 1 */
|
|
|
|
/* Create IRQ semaphore */
|
|
nema_irq_sem = osSemaphoreNew(1, 1, NULL);
|
|
assert(nema_irq_sem != NULL);
|
|
|
|
/* Initialise Mem Space */
|
|
error_code = tsi_malloc_init_pool_aligned(0, (void*)nemagfx_pool_mem, (uintptr_t)nemagfx_pool_mem, NEMAGFX_MEM_POOL_SIZE, 1, 8);
|
|
assert(error_code == 0);
|
|
error_code = tsi_malloc_init_pool_aligned(1, (void*)nemagfx_stencil_buffer_mem, (uintptr_t)nemagfx_stencil_buffer_mem, NEMAGFX_STENCIL_POOL_SIZE, 1, 8);
|
|
assert(error_code == 0);
|
|
|
|
/* Allocate ring_buffer memory */
|
|
ring_buffer_str.bo = nema_buffer_create(RING_SIZE);
|
|
assert(ring_buffer_str.bo.base_virt);
|
|
|
|
/* Initialize Ring Buffer */
|
|
error_code = nema_rb_init(&ring_buffer_str, 1);
|
|
if (error_code < 0)
|
|
{
|
|
return error_code;
|
|
}
|
|
|
|
/* Reset last_cl_id counter */
|
|
last_cl_id = 0;
|
|
|
|
return error_code;
|
|
}
|
|
|
|
uint32_t nema_reg_read(uint32_t reg)
|
|
{
|
|
return HAL_GPU2D_ReadRegister(&hgpu2d, reg);
|
|
}
|
|
|
|
void nema_reg_write(uint32_t reg, uint32_t value)
|
|
{
|
|
HAL_GPU2D_WriteRegister(&hgpu2d, reg, value);
|
|
}
|
|
|
|
int nema_wait_irq(void)
|
|
{
|
|
/* Wait indefinitely for a free semaphore */
|
|
osSemaphoreAcquire(nema_irq_sem, osWaitForever);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int nema_wait_irq_cl(int cl_id)
|
|
{
|
|
while (last_cl_id < cl_id)
|
|
{
|
|
(void)nema_wait_irq();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int nema_wait_irq_brk(int brk_id)
|
|
{
|
|
while (nema_reg_read(GPU2D_BREAKPOINT) == 0U)
|
|
{
|
|
(void)nema_wait_irq();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void nema_host_free(void* ptr)
|
|
{
|
|
tsi_free(ptr);
|
|
}
|
|
|
|
void* nema_host_malloc(unsigned size)
|
|
{
|
|
return tsi_malloc(size);
|
|
}
|
|
|
|
nema_buffer_t nema_buffer_create(int size)
|
|
{
|
|
nema_buffer_t bo;
|
|
memset(&bo, 0, sizeof(bo));
|
|
bo.base_virt = tsi_malloc(size);
|
|
bo.base_phys = (uint32_t)bo.base_virt;
|
|
bo.size = size;
|
|
assert(bo.base_virt != 0 && "Unable to allocate memory in nema_buffer_create");
|
|
|
|
return bo;
|
|
}
|
|
|
|
nema_buffer_t nema_buffer_create_pool(int pool, int size)
|
|
{
|
|
nema_buffer_t bo;
|
|
memset(&bo, 0, sizeof(bo));
|
|
bo.base_virt = tsi_malloc_pool(pool, size);
|
|
bo.base_phys = (uint32_t)bo.base_virt;
|
|
bo.size = size;
|
|
bo.fd = 0;
|
|
assert(bo.base_virt != 0 && "Unable to allocate memory in nema_buffer_create_pool");
|
|
|
|
return bo;
|
|
}
|
|
|
|
void* nema_buffer_map(nema_buffer_t* bo)
|
|
{
|
|
return bo->base_virt;
|
|
}
|
|
|
|
void nema_buffer_unmap(nema_buffer_t* bo)
|
|
{
|
|
/* Prevent unused argument(s) compilation warning */
|
|
UNUSED(bo);
|
|
}
|
|
|
|
void nema_buffer_destroy(nema_buffer_t* bo)
|
|
{
|
|
if (bo->fd == -1)
|
|
{
|
|
return; /* Buffer weren't allocated! */
|
|
}
|
|
|
|
tsi_free(bo->base_virt);
|
|
|
|
bo->base_virt = (void*)0;
|
|
bo->base_phys = 0;
|
|
bo->size = 0;
|
|
bo->fd = -1; /* Buffer not allocated */
|
|
}
|
|
|
|
uintptr_t nema_buffer_phys(nema_buffer_t* bo)
|
|
{
|
|
return bo->base_phys;
|
|
}
|
|
|
|
void nema_buffer_flush(nema_buffer_t* bo)
|
|
{
|
|
/* Prevent unused argument(s) compilation warning */
|
|
UNUSED(bo);
|
|
}
|
|
|
|
int nema_mutex_lock(int mutex_id)
|
|
{
|
|
int retval = 0;
|
|
|
|
/* USER CODE BEGIN nema_mutex_lock */
|
|
/* Prevent unused argument(s) compilation warning */
|
|
UNUSED(mutex_id);
|
|
/* USER CODE END nema_mutex_lock */
|
|
|
|
return retval;
|
|
}
|
|
|
|
int nema_mutex_unlock(int mutex_id)
|
|
{
|
|
int retval = 0;
|
|
|
|
/* USER CODE BEGIN nema_mutex_unlock */
|
|
/* Prevent unused argument(s) compilation warning */
|
|
UNUSED(mutex_id);
|
|
/* USER CODE END nema_mutex_unlock */
|
|
|
|
return retval;
|
|
}
|
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|