查看: 2361|回复: 0

【怪兽F7】开始打怪——DMA2D图形加速

[复制链接]
  • TA的每日心情
    奋斗
    2023-7-6 08:48
  • 签到天数: 169 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2016-6-24 13:00:39 | 显示全部楼层 |阅读模式
    分享到:
    DMA2D(Chrom-Art Accelerator™)是专用于图像处理的专业 DMA,就是Chrom-Art加速器控制器
    DMA2D可以执行如下的几个工作:
    1、用特定颜色填充目标图像的一部分或全部
    2、将源图像的一部分(或全部)复制到目标图像的一部分(或全部)中
    3、通过像素格式转换将源图像的一部分或全部复制到目标图像的一部分或全部中
    4、将像素格式不同的两个源图像部分和 / 或全部混合,再将结果复制到颜色格式不同的部分或整个目标图像中。
    DMA2D的主要特性有:

    DMA2D控制器执行直接存储器传输。作为一个 AHB主设备,它可以控制 AHB总线矩阵来启动 AHB事务。

    DMA2D有四种工作模式,可以通过DMA2D_CR寄存器的 MODE[1:0]位选择:
    1、寄存器到存储器
    2、存储器到存储器
    3、存储器到存储器并执行像素格式转换
    4、存储器到存储器并执行像素格式转换和混合
    DMA2D_CR寄存器:

    1、寄存器到存储器
    寄存器到存储器模式用于以预定义颜色填充用户自定义区域。
    颜色格式在 DMA2D_OPFCCR中设置。
    DMA2D不从任何源获取数据。它只将 DMA2D_OCOLR寄存器中定义的颜色写入通过DMA2D_OMAR 寻址以及 DMA2D_NLR和 DMA2D_OOR定义的区域。
    2、存储器到存储器
    在存储器到存储器模式下,DMA2D不执行任何图形数据转换。前景层输入 FIFO充当缓冲区,数据从 DMA2D_FGMAR中定义的源存储单元传输到 DMA2D_OMAR寻址的目标存储单元。
    DMA2D_FGPFCCR 寄存器的 CM[3:0] 位中编程的颜色模式决定输入和输出的每像素位数。
    对于要传输的区域大小,源区域大小由 DMA2D_NLR和 DMA2D_FGOR寄存器定义,目标区域大小则由 DMA2D_NLR和 DMA2D_OOR寄存器定义。
    3、存储器到存储器并执行 PFC
    此模式下,DMA2D对源数据执行像素格式转换并将结果存储在目标存储单元。
    对于要传输的区域大小,源区域大小由 DMA2D_NLR和 DMA2D_FGOR寄存器定义,目标区域大小则由 DMA2D_NLR和 DMA2D_OOR寄存器定义。
    从 DMA2D_FGMAR寄存器定义的位置获取数据,并由前景层 PFC进行处理。原始像素格式通过 DMA2D_FGPFCCR寄存器配置。
    4、存储器到存储器并执行 PFC和混合
    此模式下,将在前景层 FIFO和背景层 FIFO (分别在 DMA2D_FGMAR 和 DMA2D_BGMAR中定义)获取 2 个源图像。
    必须按存储器到存储器模式中所述配置两个像素格式转换器。由于这两个像素格式转换器各自独立且自身具有 CLUT 存储器,因此其配置可以不同。
    DMA2D中断也可以使用中断。
    中断源有:

    DMA2D 的配置使用了DMA2D_HandleTypeDef类型的结构体。
    结构体成员如下图:
    其中有两个函数,一个是DMA2D完成回调,一个是DMA2D错误回调。

    初始化函数如下:
    static void DMA2D_Config(void){      HAL_StatusTypeDef hal_status = HAL_OK;    /* Configure the DMA2D Mode, Color Mode and output offset */  Dma2dHandle.Init.Mode         = DMA2D_M2M_PFC; /* DMA2D mode Memory to Memory with Pixel Format Conversion */  Dma2dHandle.Init.ColorMode    = DMA2D_OUTPUT_ARGB4444; /* DMA2D Output color mode is ARGB4444 (16 bpp) */  Dma2dHandle.Init.OutputOffset = 0x0; /* No offset in output */      /* DMA2D Callbacks Configuration */  Dma2dHandle.XferCpltCallback  = TransferComplete;  Dma2dHandle.XferErrorCallback = TransferError;    /* Foreground layer Configuration : layer 1 */  Dma2dHandle.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;  Dma2dHandle.LayerCfg[1].InputAlpha = 0xFF; /* Alpha fully opaque */  Dma2dHandle.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888; /* Layer 1 input format is ARGB8888 (32 bpp) */  Dma2dHandle.LayerCfg[1].InputOffset = 0x0; /* No offset in input */  Dma2dHandle.Instance = DMA2D;     /* DMA2D Initialization */  hal_status = HAL_DMA2D_Init(&Dma2dHandle);  OnError_Handler(hal_status != HAL_OK);    hal_status = HAL_DMA2D_ConfigLayer(&Dma2dHandle, 1);  OnError_Handler(hal_status != HAL_OK);}这里定义的两个函数分别为TransferComplete()与TransferError()。
    DMA2D的工作模式是Memory to Memory。输出颜色格式为ARGB4444。输入的颜色格式为ARGB8888。
    通过HAL_DMA2D_Init函数,把DMA2D_HandleTypeDef类型结构体变量Dma2dHandle写入到DMA2D的寄存器中,如果写入正确,则返回HAL_OK。
    HAL_StatusTypeDef HAL_DMA2D_Init(DMA2D_HandleTypeDef *hdma2d){   /* Check the DMA2D peripheral state */  if(hdma2d == NULL)  {     return HAL_ERROR;  }  /* Check the parameters */  assert_param(IS_DMA2D_ALL_INSTANCE(hdma2d->Instance));  assert_param(IS_DMA2D_MODE(hdma2d->Init.Mode));  assert_param(IS_DMA2D_CMODE(hdma2d->Init.ColorMode));  assert_param(IS_DMA2D_OFFSET(hdma2d->Init.OutputOffset));  if(hdma2d->State == HAL_DMA2D_STATE_RESET)  {    /* Allocate lock resource and initialize it */    hdma2d->Lock = HAL_UNLOCKED;    /* Init the low level hardware */    HAL_DMA2D_MspInit(hdma2d);  }    /* Change DMA2D peripheral state */  hdma2d->State = HAL_DMA2D_STATE_BUSY;    /* DMA2D CR register configuration -------------------------------------------*/  MODIFY_REG(hdma2d->Instance->CR, DMA2D_CR_MODE, hdma2d->Init.Mode);  /* DMA2D OPFCCR register configuration ---------------------------------------*/  MODIFY_REG(hdma2d->Instance->OPFCCR, DMA2D_OPFCCR_CM, hdma2d->Init.ColorMode);  /* DMA2D OOR register configuration ------------------------------------------*/    MODIFY_REG(hdma2d->Instance->OOR, DMA2D_OOR_LO, hdma2d->Init.OutputOffset);  #if defined (DMA2D_OPFCCR_AI)  /* DMA2D OPFCCR AI fields setting (Output Alpha Inversion)*/  MODIFY_REG(hdma2d->Instance->OPFCCR, DMA2D_OPFCCR_AI, (hdma2d->Init.AlphaInverted << DMA2D_POSITION_OPFCCR_AI));#endif /* DMA2D_OPFCCR_AI */   #if defined (DMA2D_OPFCCR_RBS)   MODIFY_REG(hdma2d->Instance->OPFCCR, DMA2D_OPFCCR_RBS,(hdma2d->Init.RedBlueSwap << DMA2D_POSITION_OPFCCR_RBS));#endif /* DMA2D_OPFCCR_RBS */    /* Update error code */  hdma2d->ErrorCode = HAL_DMA2D_ERROR_NONE;  /* Initialize the DMA2D state*/  hdma2d->State  = HAL_DMA2D_STATE_READY;  return HAL_OK;}之后,再看一下上面说的两个回调函数,一个是点亮LED,一个是闪烁LED。
    static void TransferComplete(DMA2D_HandleTypeDef *hdma2d){  /* Turn LED1 On */  BSP_LED_On(LED1);}static void TransferError(DMA2D_HandleTypeDef *hdma2d){  while (1)  {    /* Toggle LED1 with a period of 1 s */    BSP_LED_Toggle(LED1);    HAL_Delay(1000);  }}使用HAL_DMA2D_Start_IT函数开始进行DMA2D。
    HAL_DMA2D_Start_IT函数共有5个参数。

    这个函数的的输入图像为ARGB8888_300x120。

    显示结果:

    显示一个RGB565的240*130的图片结果:
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-5-4 19:49 , Processed in 0.126931 second(s), 18 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.