2025-10-10 16:07:00 +08:00

635 lines
27 KiB
C
Executable File

// Copyright 2020-2021 Beken
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Copyright 2020-2021 Beken
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdlib.h>
#include <common/bk_include.h>
#include <os/mem.h>
#include "arch_interrupt.h"
#include "sys_driver.h"
#include "gpio_map.h"
#include "gpio_driver.h"
#include <driver/gpio.h>
#include <driver/int.h>
#include "dma2d_hal.h"
#include <driver/dma2d_types.h>
#include <driver/dma2d.h>
#include <modules/pm.h>
#define DMA2D_TIMEOUT_ABORT (1000U) /**< 1s */
#define DMA2D_TIMEOUT_SUSPEND (1000U) /**< 1s */
#define TAG "dma2d_drv"
#define DMA2D_LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define DMA2D_LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define DMA2D_LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define DMA2D_LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
static dma2d_isr_t s_dma2d_isr[DMA2D_ISR_NUM] = {NULL};
static void dma2d_isr(void);
static void dma2d_isr_common(void);
#endif
#define DMA2D_RETURN_ON_NOT_INIT() do {\
if (!s_dma2d_driver_is_init) {\
return BK_ERR_DMA2D_NOT_INIT;\
}\
} while(0)
static bool s_dma2d_driver_is_init = false;
/**
* @brief initializes the DMA2D peripheral registers
* @param dma2d_init_t pointr structure that contains
* the configuration information for the DMA2D
*usage example:
*
* @retval None
*/
bk_err_t bk_dma2d_driver_init(void)
{
if (s_dma2d_driver_is_init) {
DMA2D_LOGW("%s already init. \n", __func__);
return BK_OK;
}
dma2d_hal_soft_reset();
bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_VIDP_DMA2D, PM_POWER_MODULE_STATE_ON);
sys_drv_int_enable(DMA2D_INTERRUPT_CTRL_BIT);
dma2d_hal_transfes_ability(TRANS_16BYTES);
#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
os_memset(&s_dma2d_isr, 0, sizeof(s_dma2d_isr));
bk_int_isr_register(INT_SRC_DMA2D, dma2d_isr, NULL);
if(sys_drv_dma2d_set(0) != 0) {
DMA2D_LOGE("dma2d sys clk config error \r\n");
return BK_FAIL;
}
#endif
s_dma2d_driver_is_init = true;
DMA2D_LOGI("%s \n", __func__);
return BK_OK;
}
bk_err_t bk_dma2d_init(dma2d_config_t *dma2d)
{
dma2d_hal_init(dma2d);
dma2d_hal_start_transfer(0);
return BK_OK;
}
void bk_dma2d_soft_reset(void)
{
dma2d_hal_soft_reset();
}
/**
* @brief Deinitializes the DMA2D peripheral registers to their default reset values.
* @retval None
*/
bk_err_t bk_dma2d_driver_deinit(void)
{
if (!s_dma2d_driver_is_init) {
DMA2D_LOGW("%s already deinit. \n", __func__);
return BK_OK;
}
dma2d_hal_soft_reset();
bk_int_isr_unregister(INT_SRC_DMA2D);
dma2d_hal_deinit();
bk_pm_module_vote_power_ctrl(PM_POWER_SUB_MODULE_NAME_VIDP_DMA2D, PM_POWER_MODULE_STATE_OFF);
s_dma2d_driver_is_init = false;
DMA2D_LOGI("%s complete\n", __func__);
return BK_OK;
}
/**
* @brief Configure the DMA2D Layer according to the specified
* @param dma2d Pointer to a dma2d_init_t structure that contains the configuration information for the DMA2D.
* @param LayerIdx DMA2D Layer index.
* This parameter can be one of the following values:
* DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
* @retval HAL status
*/
bk_err_t bk_dma2d_layer_config(dma2d_config_t *dma2d, uint32_t layer_idx)
{
dma2d_hal_layer_config(dma2d, layer_idx);
return BK_OK;
}
/**
* @brief the DMA2D Transfer config
* @param dma2d Pointer to a dma2d_init_t structure that contains the configuration information for the DMA2D.
* @param pdata Configure the source memory Buffer address if
* the Memory-to-Memory or Memory-to-Memory with pixel format
* conversion mode is selected, or configure
* the color value if Register-to-Memory mode is selected.
* @param dst_addr The destination memory Buffer address.
* @param Width The width of data to be transferred from source to destination (expressed in number of pixels per line).
* @param Height The height of data to be transferred from source to destination (expressed in number of lines).
* @retval bk_err_t status
*/
bk_err_t bk_dma2d_transfer_config(dma2d_config_t *dma2d, uint32_t pdata, uint32_t dst_addr, uint32_t width, uint32_t height)
{
dma2d_hal_config(dma2d, pdata, dst_addr, width, height);
// dma2d_hal_start_transfer(1);
return BK_OK;
}
/**
* @brief bk_dma2d_wait_transfer_done
* @retval return 0: transfer done, return others not transfer done
*/
bool bk_dma2d_is_transfer_busy(void)
{
return dma2d_hal_is_transfer_done();
}
bk_err_t bk_dma2d_start_transfer(void)
{
dma2d_hal_start_transfer(1);
return BK_OK;
}
bk_err_t bk_dma2d_stop_transfer(void)
{
dma2d_hal_start_transfer(0);
return BK_OK;
}
/**
* @brief Start the multi-source DMA2D Transfer.
* @param dma2d Pointer to a dma2d_init_t structure that contains the configuration information for the DMA2D.
* @param src_addr1 The source memory Buffer address for the foreground layer.
* @param src_addr2 The source memory Buffer address for the background layer.
* @param dst_addr The destination memory Buffer address.
* @param Width The width of data to be transferred from source to destination (expressed in number of pixels per line).
* @param Height The height of data to be transferred from source to destination (expressed in number of lines).
* @retval bk_err_t status
*/
bk_err_t bk_dma2d_blending_config(dma2d_config_t *dma2d, uint32_t fg_addr, uint32_t bg_addr, uint32_t dst_addr, uint32_t width, uint32_t height)
{
dma2d_hal_blending_start(dma2d, fg_addr, bg_addr, dst_addr, width, height);
return BK_OK;
}
/**
* @brief bk_dma2d_int_config.
* @param int_type select from DMA2D_INT_TYPE, include int type:
DMA2D_CFG_ERROR
DMA2D_CLUT_TRANS_COMPLETE
DMA2D_CLUT_TRANS_ERROR
DMA2D_WARTERMARK_INT
DMA2D_TRANS_COMPLETE
DMA2D_TRANS_ERROR
* @param enable int
* @retval bk_err_t status
*/
bk_err_t bk_dma2d_int_enable(dma2d_int_type_t int_type, bool enable)
{
dma2d_hal_int_config(int_type, enable);
return BK_OK;
}
/**
* @brief bk_dma2d_int_status_get.
* @retval return <value> is all int status, can used by <value> & DMA2D_INT_STATUS check which int triggered
typedef enum
{
DMA2D_TRANS_ERROR_STATUS = 0x1,
DMA2D_TRANS_COMPLETE_STATUS,
DMA2D_WARTERMARK_INT_STATUS,
DMA2D_CLUT_TRANS_ERROR_STATUS,
DMA2D_CLUT_TRANS_COMPLETE_STATUS,
DMA2D_CFG_ERROR_STATUS
}DMA2D_INT_STATUS;
*/
uint32_t bk_dma2d_int_status_get(void)
{
return dma2d_hal_int_status_get();
}
/**
* @brief clear int status
* @param int_status select from DMA2D_INT_STATUS include:
DMA2D_TRANS_ERROR_STATUS
DMA2D_TRANS_COMPLETE_STATUS
DMA2D_WARTERMARK_INT_STATUS
DMA2D_CLUT_TRANS_ERROR_STATUS
DMA2D_CLUT_TRANS_COMPLETE_STATUS
DMA2D_CFG_ERROR_STATUS
* @retval bk_err_t status
*/
bk_err_t bk_dma2d_int_status_clear(dma2d_int_status_t int_status)
{
dma2d_hal_int_status_clear(int_status);
return BK_OK;
}
/**
* @brief bk_dma2d_suspend
* @param suspend 1:suspend 0:resume
* @retval bk_err_t status
*/
bk_err_t bk_driver_dma2d_suspend(bool suspend)
{
dma2d_hal_suspend(suspend);
return BK_OK;
}
/**
* @brief register dma2d cpu int isr
* @param dma2d_isr the function you registr isr
* @retval bk_err_t status
*/
bk_err_t bk_dma2d_isr_register(dma2d_isr_t dma2d_isr)
{
bk_int_isr_register(INT_SRC_DMA2D, dma2d_isr, NULL);
return BK_OK;
}
static uint32_t HAL_GetTick()
{
return 0;
}
/**
* @brief bk_dma2d_abort
* @param abort
* @retval bk_err_t status
*/
bk_err_t bk_driver_dma2d_abort(bool abort)
{
uint32_t tickstart;
/* Abort the DMA2D transfer */
/* START bit is reset to make sure not to set it again, in the event the HW clears it
between the register read and the register write by the CPU (writing 0 has no
effect on START bitvalue) */
dma2d_hal_abort(abort);
/* Get tick */
tickstart = HAL_GetTick();
/* Check if the DMA2D is effectively disabled */
while(!dma2d_hal_is_transfer_done()) {
if ((HAL_GetTick() - tickstart ) > DMA2D_TIMEOUT_ABORT) {
return BK_ERR_TIMEOUT;
}
}
return BK_OK;
}
#if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
/* dma2d interrupt enter */
static void dma2d_isr(void)
{
dma2d_isr_common();
}
/* dma2d check interrupt flag and excute correponding isr function when enter interrupt */
static void dma2d_isr_common(void)
{
uint32_t int_status;
int_status = bk_dma2d_int_status_get();
if (int_status & DMA2D_CFG_ERROR_STATUS) {
if (s_dma2d_isr[DMA2D_CFG_ERROR_ISR]) {
s_dma2d_isr[DMA2D_CFG_ERROR_ISR]();
}
bk_dma2d_int_status_clear(DMA2D_CFG_ERROR_STATUS);
}
//Transfer Error Interrupt management
if (int_status & DMA2D_TRANS_ERROR_STATUS) {
if (s_dma2d_isr[DMA2D_TRANS_ERROR_ISR]) {
s_dma2d_isr[DMA2D_TRANS_ERROR_ISR]();
}
bk_dma2d_int_status_clear(DMA2D_TRANS_ERROR_STATUS);
}
if (int_status & DMA2D_TRANS_COMPLETE_STATUS) {
if (s_dma2d_isr[DMA2D_TRANS_COMPLETE_ISR]) {
s_dma2d_isr[DMA2D_TRANS_COMPLETE_ISR]();
}
bk_dma2d_int_status_clear(DMA2D_TRANS_COMPLETE_STATUS);
}
if (int_status & DMA2D_WARTERMARK_INT_STATUS) {
if (s_dma2d_isr[DMA2D_WARTERMARK_INT_ISR]) {
s_dma2d_isr[DMA2D_WARTERMARK_INT_ISR]();
}
bk_dma2d_int_status_clear(DMA2D_WARTERMARK_INT_STATUS);
}
if (int_status & DMA2D_CLUT_TRANS_COMPLETE_STATU) {
if (s_dma2d_isr[DMA2D_CLUT_TRANS_COMPLETE_ISR]) {
s_dma2d_isr[DMA2D_CLUT_TRANS_COMPLETE_ISR]();
}
bk_dma2d_int_status_clear(DMA2D_CLUT_TRANS_COMPLETE_STATU);
}
if (int_status & DMA2D_CLUT_TRANS_ERROR_STATUS) {
if (s_dma2d_isr[DMA2D_CLUT_TRANS_ERROR_ISR]) {
s_dma2d_isr[DMA2D_CLUT_TRANS_ERROR_ISR]();
}
bk_dma2d_int_status_clear(DMA2D_CLUT_TRANS_ERROR_STATUS);
}
}
/**
* @brief register dma2d int type isr ,user option function
open the macro #define USE_HAL_DMA2D_REGISTER_CALLBACKS 1
* @param isr_id based on int type, a int type can register a isr, select from:
typedef enum
{
DMA2D_CFG_ERROR_ISR = 0,
DMA2D_CLUT_TRANS_COMPLETE_ISR,
DMA2D_CLUT_TRANS_ERROR_ISR,
DMA2D_WARTERMARK_INT_ISR,
DMA2D_TRANS_COMPLETE_ISR,
DMA2D_TRANS_ERROR_ISR,
}DMA2D_ISR_ID;
* @param cb_isr the user register int callback function
* @retval bk_err_t status
*/
bk_err_t bk_dma2d_register_int_callback_isr(dm2d_isr_id_t isr_id, dma2d_isr_t cb_isr)
{
if ((isr_id) >= DMA2D_ISR_NUM)
return BK_FAIL;
uint32_t int_level = rtos_disable_int();
s_dma2d_isr[isr_id] = cb_isr;
rtos_enable_int(int_level);
return BK_OK;
}
#endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */
//===========to do input_data_reverse
bk_err_t bk_dma2d_blend(dma2d_blend_t *dma2d_blend)
{
dma2d_config_t dma2d_config = {0};
/*##-1- Configure the DMA2D Mode, Output Color Mode and output offset #############*/
dma2d_config.init.mode = DMA2D_M2M_BLEND; /**< Mode Memory To Memory */
dma2d_config.init.color_mode = dma2d_blend->dst_color_mode; /**< output format of DMA2D */
dma2d_config.init.output_offset= dma2d_blend->dest_offline; /**< output offset */
dma2d_config.init.red_blue_swap = DMA2D_RB_REGULAR; /**< No R&B swap for the output image */
dma2d_config.init.alpha_inverted = DMA2D_REGULAR_ALPHA; /**< No alpha inversion for the output image */
dma2d_config.init.trans_ability = TRANS_16BYTES;
dma2d_config.init.out_byte_by_byte_reverse = NO_REVERSE;
/**< Foreground layer Configuration */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].alpha_mode = dma2d_blend->fg_alpha_mode; /**< Keep original Alpha from ARGB4444 input */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_alpha = dma2d_blend->fg_alpha_value; /**< 127 : semi-transparent */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_color_mode = dma2d_blend->fg_color_mode; /**< Foreground color is RGB565 : 16 bpp */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_offset = dma2d_blend->fg_offline; /**< No offset in input */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].red_blue_swap = dma2d_blend->red_bule_swap; /**< No R&B swap for the input image */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].alpha_inverted = DMA2D_REGULAR_ALPHA; /**< No alpha inversion for the input image */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_data_reverse = NO_REVERSE; /**< for yuv format data reverse, select byte by byte or hfword by hfword reverse */
/**< Background layer Configuration */
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].alpha_mode = dma2d_blend->bg_alpha_mode;
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].input_alpha = dma2d_blend->bg_alpha_value; /**< 255 : fully opaque */
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].input_color_mode = dma2d_blend->bg_color_mode; /**< Background format is ARGB8888*/
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].input_offset = dma2d_blend->bg_offline;/**< Background input offset*/
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].red_blue_swap = DMA2D_RB_REGULAR; /**< No R&B swap for the input background image */
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].alpha_inverted = DMA2D_REGULAR_ALPHA; /**< No alpha inversion for the input background image */
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].input_data_reverse = NO_REVERSE; /**< for yuv format data reverse, select byte by byte or hfword by hfword reverse */
bk_dma2d_init(&dma2d_config);
bk_dma2d_layer_config(&dma2d_config, DMA2D_FOREGROUND_LAYER);
bk_dma2d_layer_config(&dma2d_config, DMA2D_BACKGROUND_LAYER);
// bk_dma2d_int_config(DMA2D_TRANS_ERROR | DMA2D_TRANS_COMPLETE ,1);
// bk_dma2d_isr_register(dma2d_isr);
/*## RGB565_240x130_1[] is the foreground layer and LCD_FRAME_BUFFER is the background layer */
bk_dma2d_blending_config(&dma2d_config,
(uint32_t)dma2d_blend->pfg_addr, /**< Foreground image */
(uint32_t)dma2d_blend->pbg_addr, /**< Background image */
(uint32_t)dma2d_blend->pdst_addr, /**< Destination address */
dma2d_blend->xsize , /**< width in pixels */
dma2d_blend->ysize); /**< height in pixels */
//while (bk_dma2d_is_transfer_busy()) {}
return BK_OK;
}
bk_err_t bk_dma2d_offset_blend(dma2d_offset_blend_t *dma2d_blend)
{
dma2d_config_t dma2d_config = {0};
void *p_fg_addr = &(((uint8_t *)dma2d_blend->pfg_addr)[(dma2d_blend->fg_frame_width * dma2d_blend->fg_frame_ypos + dma2d_blend->fg_frame_xpos) * dma2d_blend->fg_pixel_byte]);
void *p_bg_addr = &(((uint8_t *)dma2d_blend->pbg_addr)[(dma2d_blend->bg_frame_width * dma2d_blend->bg_frame_ypos + dma2d_blend->bg_frame_xpos) * dma2d_blend->bg_pixel_byte]);
void *p_output_addr = &(((uint8_t *)dma2d_blend->pdst_addr)[(dma2d_blend->dst_frame_width * dma2d_blend->dst_frame_ypos + dma2d_blend->dst_frame_xpos) * dma2d_blend->dst_pixel_byte]);
/*##-1- Configure the DMA2D Mode, Output Color Mode and output offset #############*/
dma2d_config.init.mode = DMA2D_M2M_BLEND; /**< Mode Memory To Memory */
dma2d_config.init.color_mode = dma2d_blend->dst_color_mode; /**< output format of DMA2D */
dma2d_config.init.output_offset= dma2d_blend->dst_frame_width - dma2d_blend->dma2d_width; /**< output offset */
dma2d_config.init.red_blue_swap = dma2d_blend->dst_red_blue_swap; /**< No R&B swap for the output image */
dma2d_config.init.alpha_inverted = DMA2D_REGULAR_ALPHA; /**< No alpha inversion for the output image */
dma2d_config.init.trans_ability = TRANS_16BYTES;
dma2d_config.init.out_byte_by_byte_reverse = NO_REVERSE;
/**< Foreground layer Configuration */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].alpha_mode = dma2d_blend->fg_alpha_mode; /**< Keep original Alpha from ARGB4444 input */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_alpha = dma2d_blend->fg_alpha_value; /**< 127 : semi-transparent */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_color_mode = dma2d_blend->fg_color_mode; /**< Foreground color is RGB565 : 16 bpp */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_offset = dma2d_blend->fg_frame_width - dma2d_blend->dma2d_width; /**< No offset in input */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].red_blue_swap = dma2d_blend->fg_red_blue_swap; /**< No R&B swap for the input image */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].alpha_inverted = DMA2D_REGULAR_ALPHA; /**< No alpha inversion for the input image */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_data_reverse = NO_REVERSE; /**< for yuv format data reverse, select byte by byte or hfword by hfword reverse */
/**< Background layer Configuration */
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].alpha_mode = dma2d_blend->bg_alpha_mode;
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].input_alpha = dma2d_blend->bg_alpha_value; /**< 255 : fully opaque */
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].input_color_mode = dma2d_blend->bg_color_mode; /**< Background format is ARGB8888*/
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].input_offset = dma2d_blend->bg_frame_width - dma2d_blend->dma2d_width;/**< Background input offset*/
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].red_blue_swap = dma2d_blend->bg_red_blue_swap; /**< No R&B swap for the input background image */
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].alpha_inverted = DMA2D_REGULAR_ALPHA; /**< No alpha inversion for the input background image */
dma2d_config.layer_cfg[DMA2D_BACKGROUND_LAYER].input_data_reverse = NO_REVERSE; /**< for yuv format data reverse, select byte by byte or hfword by hfword reverse */
bk_dma2d_init(&dma2d_config);
bk_dma2d_layer_config(&dma2d_config, DMA2D_FOREGROUND_LAYER);
bk_dma2d_layer_config(&dma2d_config, DMA2D_BACKGROUND_LAYER);
// bk_dma2d_int_config(DMA2D_TRANS_ERROR | DMA2D_TRANS_COMPLETE ,1);
// bk_dma2d_isr_register(dma2d_isr);
/*## RGB565_240x130_1[] is the foreground layer and LCD_FRAME_BUFFER is the background layer */
bk_dma2d_blending_config(&dma2d_config,
(uint32_t)p_fg_addr, /**< Foreground image */
(uint32_t)p_bg_addr, /**< Background image */
(uint32_t)p_output_addr, /**< Destination address */
dma2d_blend->dma2d_width , /**< width in pixels */
dma2d_blend->dma2d_height); /**< height in pixels */
//while (bk_dma2d_is_transfer_busy()) {}
return BK_OK;
}
void bk_dma2d_memcpy_or_pixel_convert(dma2d_memcpy_pfc_t *pixel_convert)
{
dma2d_config_t dma2d_config = {0};
void *p_input_addr = &(((uint8_t *)pixel_convert->input_addr)[(pixel_convert->src_frame_width * pixel_convert->src_frame_ypos + pixel_convert->src_frame_xpos) * pixel_convert->src_pixel_byte]);
void *p_output_addr = &(((uint8_t *)pixel_convert->output_addr)[(pixel_convert->dst_frame_width * pixel_convert->dst_frame_ypos + pixel_convert->dst_frame_xpos) * pixel_convert->dst_pixel_byte]);
/*##-1- Configure the DMA2D Mode, Output Color Mode and output offset #############*/
dma2d_config.init.mode = pixel_convert->mode; /**< DMA2D Mode memory to memory with PFC*/
dma2d_config.init.color_mode = pixel_convert->output_color_mode; /**< output format of DMA2D */
dma2d_config.init.output_offset = pixel_convert->dst_frame_width - pixel_convert->dma2d_width;
dma2d_config.init.red_blue_swap = pixel_convert->output_red_blue_swap; /**< No R&B swap for the output image */
dma2d_config.init.alpha_inverted = DMA2D_REGULAR_ALPHA; /**< No alpha inversion for the output image */
dma2d_config.init.trans_ability = TRANS_16BYTES;
dma2d_config.init.out_byte_by_byte_reverse = NO_REVERSE;
/**< Foreground layer Configuration */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].alpha_mode = DMA2D_NO_MODIF_ALPHA; /**< Keep original Alpha from ARGB4444 input */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_alpha = pixel_convert->input_alpha; /**< Fully opaque */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_color_mode = pixel_convert->input_color_mode; /**< Input color is RGB565 : 16 bpp */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_offset = pixel_convert->src_frame_width - pixel_convert->dma2d_width; /**< No offset in input */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].red_blue_swap = pixel_convert->input_red_blue_swap; /**< No R&B swap for the input image */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].alpha_inverted = DMA2D_REGULAR_ALPHA; /**< No alpha inversion for the input image */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_data_reverse = NO_REVERSE; /**< for yuv format data reverse, select byte by byte or hfword by hfword reverse */
bk_dma2d_init(&dma2d_config);
bk_dma2d_layer_config(&dma2d_config, DMA2D_FOREGROUND_LAYER);
bk_dma2d_transfer_config(&dma2d_config,
(uint32_t)p_input_addr, /**< Source buffer in format RGB565 and size 320x240 */
(uint32_t)p_output_addr,/**< framebuf+2*(LCD_X_SIZE*sy+sx)*/
pixel_convert->dma2d_width, /**< width in pixels */
pixel_convert->dma2d_height); /**< height in pixels */
}
bk_err_t dma2d_fill(dma2d_fill_t *fill)
{
dma2d_config_t dma2d_config = {0};
void *pDiSt=&(((uint8_t *)fill->frameaddr)[(fill->frame_xsize * fill->ypos + fill->xpos) * fill->pixel_byte]);
DMA2D_LOGD("frame_addr = %p, start fill addr %p \n", fill->frameaddr, pDiSt);
dma2d_config.init.mode = DMA2D_R2M; /**< Mode Register to Memory */
dma2d_config.init.color_mode = fill->color_format; /**< DMA2D Output color mode is ARGB4444 (16 bpp) */
dma2d_config.init.output_offset = fill->frame_xsize - fill->width; /**< No offset in output */
dma2d_config.init.red_blue_swap = DMA2D_RB_REGULAR; /**< No R&B swap for the output image */
dma2d_config.init.alpha_inverted = DMA2D_REGULAR_ALPHA; /**< No alpha inversion for the output image */
bk_dma2d_init(&dma2d_config);
dma2d_hal_config(&dma2d_config, fill->color, (uint32_t)pDiSt, fill->width, fill->height);
return BK_OK;
}
void dma2d_memcpy_psram(void *Psrc, void *Pdst, uint32_t xsize, uint32_t ysize, uint32_t src_offline, uint32_t dest_offline)
{
dma2d_config_t dma2d_config = {0};
/*##-1- Configure the DMA2D Mode, Output Color Mode and output offset #############*/
dma2d_config.init.mode = DMA2D_M2M; /**< Mode Memory To Memory */
dma2d_config.init.color_mode = DMA2D_OUTPUT_ARGB8888; /**< Output color mode is ARGB4444 : 16 bpp */
dma2d_config.init.output_offset = dest_offline/2; /**< No offset on output */
dma2d_config.init.red_blue_swap = DMA2D_RB_REGULAR; /**< No R&B swap for the output image */
dma2d_config.init.alpha_inverted = DMA2D_REGULAR_ALPHA; /**< No alpha inversion for the output image */
dma2d_config.init.trans_ability = TRANS_16BYTES;
dma2d_config.init.out_byte_by_byte_reverse = NO_REVERSE;
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].alpha_mode = DMA2D_NO_MODIF_ALPHA; /**< Keep original Alpha from ARGB4444 input */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_alpha = 0xFF; /**< Fully opaque */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_color_mode = DMA2D_INPUT_ARGB8888; /**< Input color is ARGB4444 : 16 bpp */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_offset = src_offline/2; /**< No offset in input */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].red_blue_swap = DMA2D_RB_REGULAR; /**< No R&B swap for the input image */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].alpha_inverted = DMA2D_REGULAR_ALPHA; /**< No alpha inversion for the input image */
dma2d_config.layer_cfg[DMA2D_FOREGROUND_LAYER].input_data_reverse = NO_REVERSE;
bk_dma2d_init(&dma2d_config);
bk_dma2d_layer_config(&dma2d_config, DMA2D_FOREGROUND_LAYER);
bk_dma2d_transfer_config(&dma2d_config, (uint32_t)Psrc, (uint32_t)Pdst, xsize/2, ysize);
bk_dma2d_start_transfer();
}
void dma2d_memcpy_psram_for_lvgl(void *Psrc, uint32_t src_xsize, uint32_t src_ysize,
void *Pdst, uint32_t dst_xsize, uint32_t dst_ysize,
uint32_t src_xpos, uint32_t src_ypos,
uint32_t dst_xpos, uint32_t dst_ypos)
{
dma2d_memcpy_pfc_t dma2d_memcpy_pfc = {0};
dma2d_memcpy_pfc.input_addr = (char *)Psrc;
dma2d_memcpy_pfc.output_addr = (char *)Pdst;
dma2d_memcpy_pfc.mode = DMA2D_M2M;
dma2d_memcpy_pfc.input_color_mode = DMA2D_INPUT_RGB565;
dma2d_memcpy_pfc.src_pixel_byte = TWO_BYTES;
dma2d_memcpy_pfc.output_color_mode = DMA2D_OUTPUT_RGB565;
dma2d_memcpy_pfc.dst_pixel_byte = TWO_BYTES;
dma2d_memcpy_pfc.dma2d_width = src_xsize;
dma2d_memcpy_pfc.dma2d_height = src_ysize;
dma2d_memcpy_pfc.src_frame_width = src_xsize;
dma2d_memcpy_pfc.src_frame_height = src_ysize;
dma2d_memcpy_pfc.dst_frame_width = dst_xsize;
dma2d_memcpy_pfc.dst_frame_height = dst_ysize;
dma2d_memcpy_pfc.src_frame_xpos = src_xpos;
dma2d_memcpy_pfc.src_frame_ypos = src_ypos;
dma2d_memcpy_pfc.dst_frame_xpos = dst_xpos;
dma2d_memcpy_pfc.dst_frame_ypos = dst_ypos;
bk_dma2d_memcpy_or_pixel_convert(&dma2d_memcpy_pfc);
bk_dma2d_start_transfer();
}
void dma2d_driver_transfes_ability(dma2d_trans_ability_t trans_ability)
{
dma2d_hal_transfes_ability(trans_ability);
}