硬汉嵌入式论坛

 找回密码
 立即注册
查看: 7124|回复: 12
收起左侧

[DMA] STM32H7的MDMA的几个官方实例学习,功能强,但使用也稍复杂

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
发表于 2018-8-9 14:09:48 | 显示全部楼层 |阅读模式
实例1:MDMA_GPDMA_Triggering


例程说明:


串口的接收采用DMA方式,使用DMA1 stream5,接收到数据后,会有一个DMA1 stream5接收标志用来触发MDMA传输,传输到缓冲aMDMA_RxBuffer里面,然后再将其回传。

这个例子应该是MDMA里面最简单的了。
注:由于这个例子开启Cache了,但是aMDMA_RxBuffer是TCM空间,所以发送前,无需做Cache无效化操作。

配置如下:
  1.   /*##-1- Enable the MDMA clock ###############################################*/  
  2.   __HAL_RCC_MDMA_CLK_ENABLE();  
  3.   
  4.   /*##-2- Select the MDMA instance to be used : MDMA_Channel0 #################*/
  5.   MDMA_Handle.Instance = MDMA_INSTANCE;  
  6.   
  7.   /*##-3- Configure the MDMA for block transfer in HW request mode ############*/  
  8.   /* MDMA HW request is set to DMA1 stream5 Transfer Complete Flag
  9.      i.e The MDMA transfer will be triggered by the DMA1 Stream5 Transfer complete flag */
  10.   MDMA_Handle.Init.Request              = MDMA_HW_REQUEST_TRIGGER;
  11.   MDMA_Handle.Init.TransferTriggerMode  = MDMA_BLOCK_TRANSFER;  
  12.   MDMA_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;
  13.   MDMA_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;

  14.   MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_BYTE;
  15.   MDMA_Handle.Init.DestinationInc       = MDMA_DEST_INC_BYTE;
  16.   MDMA_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_BYTE;
  17.   MDMA_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_BYTE;
  18.   MDMA_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  19.   MDMA_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  20.   MDMA_Handle.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  21.   MDMA_Handle.Init.BufferTransferLength = 128;

  22.   MDMA_Handle.Init.SourceBlockAddressOffset  = 0;
  23.   MDMA_Handle.Init.DestBlockAddressOffset    = 0;

  24.   /*##-4- Initialize the MDMA channel ##########################################*/  
  25.   hal_status = HAL_MDMA_Init(&MDMA_Handle);
  26.   
  27.   if(hal_status != HAL_OK)  
  28.   {
  29.     /* Initialization Error */
  30.     Error_Handler();
  31.   }
  32.   
  33.   /*##-5- Select Callbacks functions called after MDMA Transfer complete and Transfer error */
  34.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_CPLT_CB_ID, MDMA_TransferCompleteCallback);
  35.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_ERROR_CB_ID, MDMA_TransferErrorCallback);
  36.   
  37.   /*##-6- Configure NVIC for MDMA transfer complete/error interrupts ##########*/
  38.   /* Set Interrupt Group Priority */
  39.   HAL_NVIC_SetPriority(MDMA_IRQn, 0, 0);
  40.   
  41.   /* Enable the MDMA channel global Interrupt */
  42.   HAL_NVIC_EnableIRQ(MDMA_IRQn);  
  43.   
  44.   /*##-7- Start the MDMA transfer process #####################################*/
  45.   /* MDMA will transfer content of  "aUART_RxBuffer" buffer to "aMDMA_RxBuffer" buffer
  46.      knowing that MDMA HW trigger is DMA1 stream 5 which is used for UART reception.
  47.      as consequence MDMA transfer will be triggered once the UART received user message to
  48.      "aUART_RxBuffer" buffer and the MDMA will transfer it to the "aMDMA_RxBuffer" buffer
  49.   */  
  50.   hal_status = HAL_MDMA_Start_IT(&MDMA_Handle, (uint32_t)&aUART_RxBuffer,
  51.                                                (uint32_t)&aMDMA_RxBuffer,
  52.                                                RXBUFFERSIZE,
  53.                                                1);
复制代码






回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2018-8-9 16:45:14 | 显示全部楼层
实例2:MDMA_LinkedList


例程说明:

这个例程实现的功能也比较简单,不过最重要的功能是实现MDMA的List模式,这个模式简单的说就是大家可以做多种配置,然后将其做成个列表连接起来,MDMA可以按照相应的配置,依次进行传输。

这个例子配置三个源地址空间和三个目的地址,然后分别配置好,进行传输。
注意事项:
1、配置的节点0是通过函数HAL_MDMA_Init创建,后面增加节点通过函数HAL_MDMA_LinkedList_CreateNode/HAL_MDMA_LinkedList_AddNode
2、节点1和节点2的的结构体定义用的32字节对齐
ALIGN_32BYTES( MDMA_LinkNodeTypeDef Xfer_Node1);
ALIGN_32BYTES( MDMA_LinkNodeTypeDef Xfer_Node2);


3、Cache问题
启动前,节点1和节点2的结构体变量做了Clean操作,保证内容写入到此变量了。
但是MDMA传输完毕后,读取MDMA的目的缓冲区,此例子没有做无效化操作,个人觉得不妥。

配置如下:

  1. /* Private typedef -----------------------------------------------------------*/
  2. #define BUFFER_SIZE0 32
  3. #define BUFFER_SIZE1 16
  4. #define BUFFER_SIZE2 8

  5. /* Private define ------------------------------------------------------------*/
  6. /* Private macro -------------------------------------------------------------*/
  7. /* Private variables ---------------------------------------------------------*/
  8. MDMA_HandleTypeDef     MDMA_Handle;

  9. static const uint32_t SRC_Const_Buffer0[BUFFER_SIZE0] =
  10. {
  11.   0x01020304, 0x05060708, 0x090A0B0C, 0x0D0E0F10,
  12.   0x11121314, 0x15161718, 0x191A1B1C, 0x1D1E1F20,
  13.   0x21222324, 0x25262728, 0x292A2B2C, 0x2D2E2F30,
  14.   0x31323334, 0x35363738, 0x393A3B3C, 0x3D3E3F40,
  15.   0x41424344, 0x45464748, 0x494A4B4C, 0x4D4E4F50,
  16.   0x51525354, 0x55565758, 0x595A5B5C, 0x5D5E5F60,
  17.   0x61626364, 0x65666768, 0x696A6B6C, 0x6D6E6F70,
  18.   0x71727374, 0x75767778, 0x797A7B7C, 0x7D7E7F80
  19. };

  20. static const uint32_t SRC_Const_Buffer1[BUFFER_SIZE1] =
  21. {
  22.   0x0A0B0C0D, 0x1A1B1C1D, 0x2A2B2C2D, 0x2A2B2C2D,
  23.   0x3A3B3C3D, 0x4A4B4C4D, 0x5A5B5C5D, 0x6A6B6C6D,
  24.   0x7A7B7C7D, 0x8A8B8C8D, 0x9A9B9C9D, 0xAAABACAD,
  25.   0xBABBBCBD, 0xCACBCCCD, 0xDADBDCDD, 0xEAEBECED
  26. };

  27. static const uint32_t SRC_Const_Buffer2[BUFFER_SIZE2] =
  28. {
  29.   0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F,
  30.   0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF
  31. };

  32. /******** MDMA Destination 0 Buffer definition *******/
  33. /*Buffer location and size should aligned to cache line size (32 bytes) */
  34. #if defined ( __ICCARM__ )
  35. #pragma location = 0x24004000
  36. uint32_t DESTBuffer0_D1_AXISRAM[BUFFER_SIZE0];
  37. #elif defined ( __CC_ARM )
  38. ALIGN_32BYTES(__attribute__((section (".RAM_D1"))) uint32_t DESTBuffer0_D1_AXISRAM[BUFFER_SIZE0]);
  39. #elif defined ( __GNUC__ )
  40. ALIGN_32BYTES(uint32_t __attribute__((section (".RAM_D1"))) DESTBuffer0_D1_AXISRAM[BUFFER_SIZE0]);
  41. #endif

  42. /*****************************************************/


  43. /******** MDMA Destination 1 Buffer definition *******/
  44. /*Buffer location and size should aligned to cache line size (32 bytes) */
  45. #if defined ( __ICCARM__ )
  46. #pragma location = 0x30000000
  47. uint32_t DESTBuffer1_D2_SRAM1[BUFFER_SIZE0];
  48. #elif defined ( __CC_ARM )
  49. ALIGN_32BYTES(__attribute__((section (".RAM_D2"))) uint32_t DESTBuffer1_D2_SRAM1[BUFFER_SIZE0]);
  50. #elif defined ( __GNUC__ )
  51. ALIGN_32BYTES(uint32_t __attribute__((section (".RAM_D2"))) DESTBuffer1_D2_SRAM1[BUFFER_SIZE0]);
  52. #endif
  53. /*****************************************************/


  54. /******** MDMA Destination 2 Buffer definition *******/
  55. /*Buffer location and size should aligned to cache line size (32 bytes) */
  56. #if defined ( __ICCARM__ )
  57. #pragma location = 0x38000000
  58. uint32_t DESTBuffer2_D3_AHBSRAM[BUFFER_SIZE0];
  59. #elif defined ( __CC_ARM )
  60. ALIGN_32BYTES(uint32_t __attribute__((section (".RAM_D3"))) DESTBuffer2_D3_AHBSRAM[BUFFER_SIZE0]);
  61. #elif defined ( __GNUC__ )
  62. ALIGN_32BYTES(uint32_t __attribute__((section (".RAM_D3"))) DESTBuffer2_D3_AHBSRAM[BUFFER_SIZE0]);
  63. #endif
  64. /*****************************************************/

  65. __IO uint32_t TransferErrorDetected = 0;
  66. __IO uint32_t TransferCompleteDetected = 0;



  67. /******** Linked list nodes 1 to 2 definition *******/

  68. /*
  69. According to the Ref Manual :  
  70.   The channel configuration (LAR address) must be in the AXI address space.
  71.   LAR value must be aligned at a Double Word address, i.e. LAR[2:0] = 0x0

  72. The LAR address register represents the next Linked list Node address.
  73. As consequence the Liked list transfer nodes must be 64 bits aligned and must be in the AXI address space.
  74. */
  75. /* 32-bytes Alignement is needed for cache maintenance purpose */
  76. ALIGN_32BYTES( MDMA_LinkNodeTypeDef Xfer_Node1);
  77. ALIGN_32BYTES( MDMA_LinkNodeTypeDef Xfer_Node2);
  78. /*****************************************************/

  79. /**
  80.   * @brief  MDMA Liked List transfer configuraion
  81.   * @note   This function configure the DMA for a linked list transfer.
  82.   *         The linked list contains 3 nodes.
  83.   *         Node 0 transfer parameters are configured within the Handle init parameters.
  84.   *         Next nodes are filled using HAL function "HAL_MDMA_SetLinkNodeParams"
  85.   *         after setting all nodes parameters (node 0 using HAL_MDMA_Init and
  86.   *         next nodes uing HAL_MDMA_SetLinkNodeParams) start the transfer in interrupt mode
  87.   *         using function "HAL_MDMA_Start_IT". Note that the source and destination addresses given to
  88.   *         the function HAL_MDMA_Start_IT must correspond to the node 0 source and destination addresses,
  89.   *         same for the transfer data length.
  90.   *         Note that using the MDMA the transfer data length is always expressed in bytes whatever
  91.   *         is the source and data size (byte, half word, word or double word)
  92.   *
  93.   * @retval None
  94.   */
  95. static void MDMA_Config(void)
  96. {
  97.   MDMA_LinkNodeConfTypeDef mdmaLinkNodeConfig;
  98.   uint32_t hal_status = HAL_OK;
  99.   
  100.   /*##-1- Enable the MDMA clock ###############################################*/
  101.   __HAL_RCC_MDMA_CLK_ENABLE();
  102.   
  103.   
  104.   /*##-2- Select the MDMA instance to be used for the transfer : MDMA_Channel0 #*/
  105.   MDMA_Handle.Instance = MDMA_INSTANCE;
  106.   
  107.   /*##-3- Initialize the MDMA channel for Node 0###############################*/
  108.   
  109.   /* Set the parameters to be configured for transfer Node0*/
  110.   MDMA_Handle.Init.Request              = MDMA_REQUEST_SW;
  111.   MDMA_Handle.Init.TransferTriggerMode  = MDMA_FULL_TRANSFER;   
  112.   MDMA_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;
  113.   MDMA_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  114.   MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_WORD;
  115.   MDMA_Handle.Init.DestinationInc       = MDMA_DEST_INC_BYTE;
  116.   MDMA_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_WORD;
  117.   MDMA_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_BYTE;
  118.   MDMA_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  119.   MDMA_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  120.   MDMA_Handle.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  121.   MDMA_Handle.Init.BufferTransferLength = 4;
  122.   MDMA_Handle.Init.SourceBlockAddressOffset  = 0;
  123.   MDMA_Handle.Init.DestBlockAddressOffset    = 0;


  124.   hal_status = HAL_MDMA_Init(&MDMA_Handle);

  125.   if(hal_status != HAL_OK)  
  126.   {
  127.     /* Initialization Error */
  128.     Error_Handler();
  129.   }  
  130.   
  131.   /*##-4 Add linkedklist node 1 and  2##########################################*/  
  132.   /* Set the parameters to be configured for transfer Node1*/
  133.   mdmaLinkNodeConfig.Init.Request              = MDMA_REQUEST_SW;
  134.   mdmaLinkNodeConfig.Init.TransferTriggerMode  = MDMA_FULL_TRANSFER;  
  135.   mdmaLinkNodeConfig.Init.Priority             = MDMA_PRIORITY_HIGH;
  136.   mdmaLinkNodeConfig.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  137.   mdmaLinkNodeConfig.Init.SourceInc            = MDMA_SRC_INC_BYTE;
  138.   mdmaLinkNodeConfig.Init.DestinationInc       = MDMA_DEST_INC_BYTE;
  139.   mdmaLinkNodeConfig.Init.SourceDataSize       = MDMA_SRC_DATASIZE_BYTE;
  140.   mdmaLinkNodeConfig.Init.DestDataSize         = MDMA_DEST_DATASIZE_BYTE;
  141.   mdmaLinkNodeConfig.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  142.   mdmaLinkNodeConfig.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  143.   mdmaLinkNodeConfig.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  144.   mdmaLinkNodeConfig.Init.BufferTransferLength = 2;
  145.   mdmaLinkNodeConfig.Init.SourceBlockAddressOffset  = 0;
  146.   mdmaLinkNodeConfig.Init.DestBlockAddressOffset    = 0;
  147.   
  148.   mdmaLinkNodeConfig.SrcAddress      = (uint32_t)SRC_Const_Buffer1;
  149.   mdmaLinkNodeConfig.DstAddress      = (uint32_t)DESTBuffer1_D2_SRAM1;
  150.   mdmaLinkNodeConfig.BlockDataLength = (BUFFER_SIZE1*4);
  151.   mdmaLinkNodeConfig.BlockCount      = 1;
  152.   
  153.   HAL_MDMA_LinkedList_CreateNode(&Xfer_Node1, &mdmaLinkNodeConfig);
  154.   
  155.   /* Set the parameters to be configured for transfer Node2*/
  156.   mdmaLinkNodeConfig.Init.Request              = MDMA_REQUEST_SW;
  157.   mdmaLinkNodeConfig.Init.TransferTriggerMode  = MDMA_FULL_TRANSFER;
  158.   mdmaLinkNodeConfig.Init.Priority             = MDMA_PRIORITY_HIGH;
  159.   mdmaLinkNodeConfig.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  160.   mdmaLinkNodeConfig.Init.SourceInc            = MDMA_SRC_INC_BYTE;
  161.   mdmaLinkNodeConfig.Init.DestinationInc       = MDMA_DEST_INC_WORD;
  162.   mdmaLinkNodeConfig.Init.SourceDataSize       = MDMA_SRC_DATASIZE_BYTE;
  163.   mdmaLinkNodeConfig.Init.DestDataSize         = MDMA_DEST_DATASIZE_WORD;
  164.   mdmaLinkNodeConfig.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  165.   mdmaLinkNodeConfig.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  166.   mdmaLinkNodeConfig.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  167.   mdmaLinkNodeConfig.Init.BufferTransferLength = 4;
  168.   mdmaLinkNodeConfig.Init.SourceBlockAddressOffset  = 0;
  169.   mdmaLinkNodeConfig.Init.DestBlockAddressOffset    = 0;

  170.   mdmaLinkNodeConfig.SrcAddress      = (uint32_t)SRC_Const_Buffer2;
  171.   mdmaLinkNodeConfig.DstAddress      = (uint32_t)DESTBuffer2_D3_AHBSRAM;
  172.   mdmaLinkNodeConfig.BlockDataLength = (BUFFER_SIZE2*4);
  173.   mdmaLinkNodeConfig.BlockCount      = 1;
  174.   
  175.   HAL_MDMA_LinkedList_CreateNode(&Xfer_Node2, &mdmaLinkNodeConfig);
  176.   
  177.   HAL_MDMA_LinkedList_AddNode(&MDMA_Handle, &Xfer_Node1, 0);
  178.   HAL_MDMA_LinkedList_AddNode(&MDMA_Handle, &Xfer_Node2, 0);
  179.   
  180.   /*##-5- Select Callbacks functions called after Transfer complete and Transfer error */
  181.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_CPLT_CB_ID, MDMA_TransferCompleteCallback);
  182.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_ERROR_CB_ID, MDMA_TransferErrorCallback);
  183.   
  184.   /*##-6- Configure NVIC for MDMA transfer complete/error interrupts ##########*/
  185.   /* Set Interrupt Group Priority */
  186.   HAL_NVIC_SetPriority(MDMA_IRQn, 0, 0);
  187.   
  188.   /* Enable the MDMA channel global Interrupt */
  189.   HAL_NVIC_EnableIRQ(MDMA_IRQn);
  190.   
  191.   /*
  192.     As the MDMA Nodes descriptor are located in the SRAM which
  193.     is cacheable, it is necessary to clean the data cache after creating the node
  194.     in order to make sure that the MDMA will load up to date data from the linked list node
  195.   */
  196.   SCB_CleanDCache_by_Addr( (uint32_t*)&Xfer_Node1, sizeof(MDMA_LinkNodeTypeDef));
  197.   SCB_CleanDCache_by_Addr( (uint32_t*)&Xfer_Node2, sizeof(MDMA_LinkNodeTypeDef));
  198.   
  199.   /*##-7- Start the MDMA transfer using the interrupt mode ####################*/
  200.   /* Configure the source, destination and buffer size MDMA fields and Start MDMA channel transfer of the Node 0 */
  201.   hal_status = HAL_MDMA_Start_IT(&MDMA_Handle, (uint32_t)&SRC_Const_Buffer0,
  202.                                                (uint32_t)&DESTBuffer0_D1_AXISRAM,
  203.                                                (BUFFER_SIZE0 * 4),
  204.                                                1);
  205.   if(hal_status != HAL_OK)   
  206.   {
  207.     /* Transfer Error */
  208.     Error_Handler();
  209.   }
  210. }
复制代码


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2018-8-11 11:42:37 | 显示全部楼层
实例3:MDMA_LinkedList_ColorsComp


例程说明:

这个例子实现了一个简单的颜色提取器,先通过创建的三个list节点,将ARGB8888的Alpha通道复制过去,也就是0xFF00 0000。
然后再创建3个节点,分别将图片的R,G,B三原色分别提取出来并绘制,绘制的大小是原始图片的一半。

注意一点,使用list模式的话,参数TransferTriggerMode触发模式要选择MDMA_FULL_TRANSFER。其它参数不支持list。


配置如下:

  1. /**
  2.   * @brief  MDMA Linked List transfer configuraion
  3.   * @note   This function configure the DMA for a Repeat BLock transfer.
  4.   * @param  None
  5.   * @retval None
  6.   */
  7. static void MDMA_Config(void)
  8. {
  9.   uint32_t mdma_Destination_address = 0, mdma_Source_address, x = 0, y = 0;   
  10.   MDMA_LinkNodeConfTypeDef mdmaLinkNodeConfig;  
  11.   
  12.   /*##-1- Enable the MDMA clock ###############################################*/
  13.   __HAL_RCC_MDMA_CLK_ENABLE();
  14.   
  15.   /*##-2- Select the MDMA instance to be used for the transfer : MDMA_Channel0 #*/
  16.   MDMA_Handle.Instance = MDMA_INSTANCE;
  17.   
  18.   HAL_MDMA_DeInit(&MDMA_Handle);
  19.   
  20.   /*##-3- Initialize the MDMA channel (with liked list node 0 parameters) ####*/
  21.   MDMA_Handle.Init.Request              = MDMA_REQUEST_SW;
  22.   MDMA_Handle.Init.TransferTriggerMode  = MDMA_FULL_TRANSFER;  
  23.   MDMA_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;                          
  24.   MDMA_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;

  25.   MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_WORD;
  26.   MDMA_Handle.Init.DestinationInc       = MDMA_DEST_INC_WORD;  
  27.    
  28.   MDMA_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_WORD;
  29.   MDMA_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_WORD;
  30.   MDMA_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  31.   MDMA_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  32.   MDMA_Handle.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  33.   MDMA_Handle.Init.BufferTransferLength = 64;
  34.       
  35.   MDMA_Handle.Init.SourceBlockAddressOffset  = 0;
  36.   MDMA_Handle.Init.DestBlockAddressOffset    = (LCD_X_Size - IMAGE_WIDTH) * ARGB8888_BYTES_PER_PIXEL;

  37.   if (HAL_MDMA_Init(&MDMA_Handle) != HAL_OK)
  38.   {
  39.     /* Initialization Error */
  40.     Error_Handler();
  41.   }
  42.   

  43.   /*##-4- Create Linked list Node 0_1, 0_2 and 0_3 to erase Red/Green Blue sub images ####*/      
  44.   
  45.   mdmaLinkNodeConfig.Init.Request              = MDMA_REQUEST_SW;
  46.   mdmaLinkNodeConfig.Init.TransferTriggerMode  = MDMA_FULL_TRANSFER;  
  47.   mdmaLinkNodeConfig.Init.Priority             = MDMA_PRIORITY_HIGH;
  48.   mdmaLinkNodeConfig.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  49.   
  50.   mdmaLinkNodeConfig.Init.SourceInc            = MDMA_SRC_INC_DISABLE;
  51.   mdmaLinkNodeConfig.Init.DestinationInc       = MDMA_DEST_INC_WORD;
  52.   
  53.   mdmaLinkNodeConfig.Init.SourceDataSize       = MDMA_SRC_DATASIZE_WORD;
  54.   mdmaLinkNodeConfig.Init.DestDataSize         = MDMA_DEST_DATASIZE_WORD;
  55.   mdmaLinkNodeConfig.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  56.   mdmaLinkNodeConfig.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  57.   mdmaLinkNodeConfig.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  58.   mdmaLinkNodeConfig.Init.BufferTransferLength = 64;
  59.   
  60.   mdmaLinkNodeConfig.Init.SourceBlockAddressOffset  = 0;
  61.   mdmaLinkNodeConfig.Init.DestBlockAddressOffset    = (LCD_X_Size - (IMAGE_WIDTH/2)) * ARGB8888_BYTES_PER_PIXEL;
  62.   
  63.   /* Create Node0_1 : erase Red region */
  64.   mdma_Source_address = (uint32_t)(&RGBReset_Value);  
  65.   x = 40;
  66.   y = (LCD_Y_Size - (IMAGE_HEIGHT/2)) - 16;
  67.   mdma_Destination_address = (uint32_t)LCD_FRAME_BUFFER  + ((y * LCD_X_Size) + x) * ARGB8888_BYTES_PER_PIXEL;
  68.   
  69.   mdmaLinkNodeConfig.SrcAddress      = mdma_Source_address;
  70.   mdmaLinkNodeConfig.DstAddress      = mdma_Destination_address;
  71.   mdmaLinkNodeConfig.BlockDataLength = (IMAGE_WIDTH/2) * ARGB8888_BYTES_PER_PIXEL;
  72.   mdmaLinkNodeConfig.BlockCount      = IMAGE_HEIGHT/2;
  73.   
  74.   HAL_MDMA_LinkedList_CreateNode(&Xfer_Node0_1, &mdmaLinkNodeConfig);

  75.   /* Create Node0_2 : erase Green region*/
  76.   mdma_Source_address = (uint32_t)(&RGBReset_Value);  
  77.   x = 80 + (IMAGE_WIDTH/2);
  78.   y = (LCD_Y_Size - (IMAGE_HEIGHT/2)) - 16;
  79.   mdma_Destination_address = (uint32_t)LCD_FRAME_BUFFER  + ((y * LCD_X_Size) + x) * ARGB8888_BYTES_PER_PIXEL;
  80.   

  81.   mdmaLinkNodeConfig.SrcAddress = mdma_Source_address;
  82.   mdmaLinkNodeConfig.DstAddress = mdma_Destination_address;
  83.   mdmaLinkNodeConfig.BlockDataLength = (IMAGE_WIDTH/2) * ARGB8888_BYTES_PER_PIXEL;
  84.   mdmaLinkNodeConfig.BlockCount      = IMAGE_HEIGHT/2;
  85.   
  86.   HAL_MDMA_LinkedList_CreateNode(&Xfer_Node0_2, &mdmaLinkNodeConfig);
  87.   
  88.   /* Create Node0_3 : erase Blue region*/
  89.   mdma_Source_address = (uint32_t)(&RGBReset_Value);  
  90.   x = 120 + IMAGE_WIDTH;
  91.   y = (LCD_Y_Size - (IMAGE_HEIGHT/2)) - 16;
  92.   mdma_Destination_address = (uint32_t)LCD_FRAME_BUFFER  + ((y * LCD_X_Size) + x) * ARGB8888_BYTES_PER_PIXEL;
  93.   
  94.   mdmaLinkNodeConfig.SrcAddress      = mdma_Source_address;
  95.   mdmaLinkNodeConfig.DstAddress      = mdma_Destination_address;
  96.   mdmaLinkNodeConfig.BlockDataLength = (IMAGE_WIDTH/2) * ARGB8888_BYTES_PER_PIXEL;
  97.   mdmaLinkNodeConfig.BlockCount      = IMAGE_HEIGHT/2;
  98.   
  99.   HAL_MDMA_LinkedList_CreateNode(&Xfer_Node0_3, &mdmaLinkNodeConfig);

  100.   
  101.   /*##-5- Create Linked list Node 1, Node2 and Node3 to copy Red/Green Blue subimages ###*/
  102.   mdmaLinkNodeConfig.Init.Request              = MDMA_REQUEST_SW;
  103.   mdmaLinkNodeConfig.Init.TransferTriggerMode  = MDMA_FULL_TRANSFER;  
  104.   mdmaLinkNodeConfig.Init.Priority             = MDMA_PRIORITY_HIGH;
  105.   mdmaLinkNodeConfig.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  106.   
  107.   mdmaLinkNodeConfig.Init.SourceInc            = MDMA_SRC_INC_DOUBLEWORD;
  108.   mdmaLinkNodeConfig.Init.DestinationInc       = MDMA_DEST_INC_WORD;
  109.   
  110.   mdmaLinkNodeConfig.Init.SourceDataSize       = MDMA_SRC_DATASIZE_BYTE;
  111.   mdmaLinkNodeConfig.Init.DestDataSize         = MDMA_DEST_DATASIZE_BYTE;
  112.   mdmaLinkNodeConfig.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  113.   mdmaLinkNodeConfig.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  114.   mdmaLinkNodeConfig.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  115.   mdmaLinkNodeConfig.Init.BufferTransferLength = 64;
  116.   
  117.   mdmaLinkNodeConfig.Init.SourceBlockAddressOffset  = IMAGE_WIDTH * ARGB8888_BYTES_PER_PIXEL;
  118.   mdmaLinkNodeConfig.Init.DestBlockAddressOffset    = (LCD_X_Size - (IMAGE_WIDTH/2)) * ARGB8888_BYTES_PER_PIXEL;
  119.   
  120.   /* Create Node1*/
  121.   /* Set the parameters to be configured for transfer Node1 : Red color component */
  122.   /* Set source and destination start address to extract Red component*/  
  123.   
  124.   mdma_Source_address = ((uint32_t)&image_320x240_argb8888) + 2;  
  125.   x = 40;
  126.   y = (LCD_Y_Size - (IMAGE_HEIGHT/2)) - 16;
  127.   mdma_Destination_address = 2+ ((uint32_t)LCD_FRAME_BUFFER  + ((y * LCD_X_Size) + x) * ARGB8888_BYTES_PER_PIXEL);   

  128.   mdmaLinkNodeConfig.SrcAddress      = mdma_Source_address;
  129.   mdmaLinkNodeConfig.DstAddress      = mdma_Destination_address;
  130.   mdmaLinkNodeConfig.BlockDataLength = IMAGE_WIDTH/2;
  131.   mdmaLinkNodeConfig.BlockCount      = IMAGE_HEIGHT/2;  
  132.   
  133.   HAL_MDMA_LinkedList_CreateNode(&Xfer_Node1, &mdmaLinkNodeConfig);

  134.   /* Create Node2*/
  135.   /* Set the parameters to be configured for transfer Node2 : Green color component */
  136.   /* Set source and destination start address to extract Green component*/        
  137.   
  138.   mdma_Source_address = ((uint32_t)&image_320x240_argb8888) + 1;  
  139.   x = 80 + (IMAGE_WIDTH/2);
  140.   y = (LCD_Y_Size - (IMAGE_HEIGHT/2)) - 16;
  141.   mdma_Destination_address = 1 + ((uint32_t)LCD_FRAME_BUFFER  + ((y * LCD_X_Size) + x) * ARGB8888_BYTES_PER_PIXEL);  

  142.   mdmaLinkNodeConfig.SrcAddress      = mdma_Source_address;
  143.   mdmaLinkNodeConfig.DstAddress      = mdma_Destination_address;
  144.   mdmaLinkNodeConfig.BlockDataLength = IMAGE_WIDTH/2;
  145.   mdmaLinkNodeConfig.BlockCount      = IMAGE_HEIGHT/2;   
  146.   
  147.   HAL_MDMA_LinkedList_CreateNode(&Xfer_Node2, &mdmaLinkNodeConfig);
  148.   

  149.   /* Create Node3*/
  150.   /* Set the parameters to be configured for transfer Node1 : Blue color component */
  151.   /* Set source and destination start address to extract Blue component*/  
  152.   mdma_Source_address = ((uint32_t)&image_320x240_argb8888);
  153.   x = 120 + IMAGE_WIDTH;
  154.   y = (LCD_Y_Size - (IMAGE_HEIGHT/2)) - 16;  
  155.   mdma_Destination_address = (uint32_t)LCD_FRAME_BUFFER  + ((y * LCD_X_Size) + x) * ARGB8888_BYTES_PER_PIXEL;  

  156.   mdmaLinkNodeConfig.SrcAddress      = mdma_Source_address;
  157.   mdmaLinkNodeConfig.DstAddress      = mdma_Destination_address;
  158.   mdmaLinkNodeConfig.BlockDataLength = IMAGE_WIDTH/2;
  159.   mdmaLinkNodeConfig.BlockCount      = IMAGE_HEIGHT/2;      
  160.   
  161.   HAL_MDMA_LinkedList_CreateNode(&Xfer_Node3, &mdmaLinkNodeConfig);  
  162.    
  163.   /*##-5- Add linked list nodes ##############################################*/
  164.   HAL_MDMA_LinkedList_AddNode(&MDMA_Handle, &Xfer_Node0_1, 0);
  165.   HAL_MDMA_LinkedList_AddNode(&MDMA_Handle, &Xfer_Node0_2, 0);
  166.   HAL_MDMA_LinkedList_AddNode(&MDMA_Handle, &Xfer_Node0_3, 0);
  167.    
  168.   HAL_MDMA_LinkedList_AddNode(&MDMA_Handle, &Xfer_Node1, 0);
  169.   HAL_MDMA_LinkedList_AddNode(&MDMA_Handle, &Xfer_Node2, 0);
  170.   HAL_MDMA_LinkedList_AddNode(&MDMA_Handle, &Xfer_Node3, 0);

  171.   /*
  172.     As the MDMA Nodes descriptor are located in the SRAM which
  173.     is cacheable, it is necessary to clean the data cache after creating the node
  174.     in order to make sure that the MDMA will load up to date data from the linked list node
  175.   */
  176.   SCB_CleanDCache();

  177.   /*##-6- Select Callbacks functions called after Transfer complete and Transfer error */
  178.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_CPLT_CB_ID, MDMA_TransferCompleteCallback);
  179.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_ERROR_CB_ID, MDMA_TransferErrorCallback);

  180.   /*##-7- Configure NVIC for MDMA transfer complete/error interrupts ##########*/
  181.   /* Set Interrupt Group Priority */
  182.   HAL_NVIC_SetPriority(MDMA_IRQn, 0, 0);
  183.   
  184.   /* Enable the MDMA channel global Interrupt */
  185.   HAL_NVIC_EnableIRQ(MDMA_IRQn);
  186. }
复制代码


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2018-8-11 12:02:24 | 显示全部楼层
实例4:MDMA_LTDC_Triggering


例程说明:

这个例子比较的复杂,应该是MDMA里面最复杂的了。实现了一个在不需要CPU参与的情况下,图片的轮番切换功能。
简单的框图如下,通过list模式创建两个三个节点,节点0,节点1和节点3。其中节点0仅执行一次,后面连个节点创建成了循环模式,一直循环执行下去。

               LPTIM1   ----------------------------->   DMA1 Stream0   ---------------------------------->list模式节点1
  100ms触发一次DMA1 Stream0          触发后,切换list模式节点1的源图片地址             通过LTDC的行中断触发节点1
                                                    触发方式是采用的DMAMUX Request generator
                                                                           |
                                                                           |
                                                                           v
                                                                    DMA1 Stream1    ---------------------------------->list模式节点2
                                                 通过DMA1 Stream0的同步触发连接DMA1 Stream1       通过DMA1 Stream1触发节点2
                                                                                                                               从而实现循环模式不断循环执行。

配置如下:
  1. /**
  2.   * @brief  Initialize the MDMA For repeat block transfer in linked list circular
  3.     repeat block transfer.
  4.   * @param  None
  5.   * @retval None
  6.   */
  7. static void MDMA_Config(void)
  8. {
  9.   uint32_t hal_status = HAL_OK;  
  10.   MDMA_LinkNodeConfTypeDef mdmaLinkNodeConfig;   
  11.    
  12.   /*##-1- Enable the MDMA clock ###############################################*/  
  13.   __HAL_RCC_MDMA_CLK_ENABLE();  
  14.   
  15.   /*##-2- Select the MDMA instance to be used : MDMA_Channel0 #################*/
  16.   MDMA_Handle.Instance = MDMA_Channel0;  
  17.   
  18.   /*##-3- Configure the MDMA for block transfer in HW request mode ############*/  
  19.   /*
  20.      This is the Node 0 of the linked list, node 0 will be executed only one time
  21.      to clear the LCD frame buffer with default color
  22.   */
  23.   
  24.   MDMA_Handle.Init.Request              = MDMA_REQUEST_LTDC_LINE_IT;
  25.   MDMA_Handle.Init.TransferTriggerMode  = MDMA_REPEAT_BLOCK_TRANSFER;  
  26.   MDMA_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;
  27.   MDMA_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  28.   MDMA_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  29.   MDMA_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  30.   MDMA_Handle.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  31.   MDMA_Handle.Init.BufferTransferLength = 32;
  32.   
  33.   /* Source and Destination data size are word , 4 bytes that correspond to an ARGB8888 pixel 32 bpp */     
  34.   MDMA_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_WORD;
  35.   MDMA_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_WORD;

  36.   /* Source Increment Disabled as the source is always the LCD_Fill_Color
  37.      that represents the default color used to fill the LCD frame buffer */      
  38.   MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_DISABLE;
  39.   /* Destination  Increment is word , 4 bytes that correspond to an ARGB8888 pixel 32 bpp */      
  40.   MDMA_Handle.Init.DestinationInc       = MDMA_DEST_INC_WORD;

  41.   /* Source block offset set to Zero : no increment of the source block address */
  42.   MDMA_Handle.Init.SourceBlockAddressOffset  = 0;
  43.   
  44.   /* Destination block offset set to LCD_Offset */
  45.   MDMA_Handle.Init.DestBlockAddressOffset    = LCD_Offset;   
  46.   
  47.   /*##-4- Initialize the MDMA channel ##########################################*/  
  48.   hal_status = HAL_MDMA_Init(&MDMA_Handle);
  49.   
  50.   if(hal_status != HAL_OK)  
  51.   {
  52.     /* Initialization Error */
  53.     Error_Handler();
  54.   }

  55.   /* MDMA Post request address and  Mask set respecetevly to the LTDC Interrupt Clear register address
  56.      and the Clear Line Interrupt Flag mask in order to clear the LTDC Line Interrupt flag
  57.      after each transfer knowing that this last flag is the MDMA transfer trigger
  58.   */
  59.   HAL_MDMA_ConfigPostRequestMask(&MDMA_Handle, (uint32_t)(&(LTDC->ICR)), LTDC_ICR_CLIF);
  60.   
  61.   /*##-5- Create Linked list Nodes ############################################*/
  62.   
  63.   /* Node 1 : First node is used to transfer an image from the flash to the LCD frame buffer
  64.     The MDMA transfer trigger is set to the LTDC Line Interrupt flag.
  65.   */
  66.   mdmaLinkNodeConfig.Init.Request              = MDMA_REQUEST_LTDC_LINE_IT;
  67.   mdmaLinkNodeConfig.Init.TransferTriggerMode  = MDMA_REPEAT_BLOCK_TRANSFER;
  68.   mdmaLinkNodeConfig.Init.Priority             = MDMA_PRIORITY_HIGH;         
  69.   mdmaLinkNodeConfig.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;         
  70.   
  71.   mdmaLinkNodeConfig.Init.SourceInc            = MDMA_SRC_INC_WORD;     
  72.   mdmaLinkNodeConfig.Init.DestinationInc       = MDMA_DEST_INC_WORD;
  73.   
  74.   mdmaLinkNodeConfig.Init.SourceDataSize       = MDMA_SRC_DATASIZE_WORD;      
  75.   mdmaLinkNodeConfig.Init.DestDataSize         = MDMA_DEST_DATASIZE_WORD;        
  76.   mdmaLinkNodeConfig.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                                 
  77.   mdmaLinkNodeConfig.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;         
  78.   mdmaLinkNodeConfig.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;           
  79.   mdmaLinkNodeConfig.Init.BufferTransferLength = 32;
  80.   
  81.   mdmaLinkNodeConfig.Init.SourceBlockAddressOffset  = 0;
  82.   mdmaLinkNodeConfig.Init.DestBlockAddressOffset    = LCD_Offset;
  83.   
  84.   /* MDMA Post request address and  Mask set respectively to the LTDC Interrupt Clear register address
  85.      and the Clear Line Interrupt Flag mask in order to clear the LTDC Line Interrupt flag
  86.      after each transfer knowing that this last flag is the MDMA transfer trigger
  87.   */  
  88.   mdmaLinkNodeConfig.PostRequestMaskAddress = (uint32_t)(&(LTDC->ICR));
  89.   mdmaLinkNodeConfig.PostRequestMaskData = LTDC_ICR_CLIF;
  90.   
  91.   /* Destination Address is set to the LCD_FRAME_BUFFER address*/
  92.   mdmaLinkNodeConfig.DstAddress      = LCD_FRAME_BUFFER;
  93.   /* BlockDataLength is set to the size in bytes of the image width (line size) */
  94.   mdmaLinkNodeConfig.BlockDataLength = IMAGE_WIDTH * ARGB8888_BYTES_PER_PIXEL;
  95.   /* BlockCount is set to the image height (number of lines) */
  96.   mdmaLinkNodeConfig.BlockCount      = IMAGE_HEIGHT;

  97.   /* Source Address is set to the first image address */  
  98.   mdmaLinkNodeConfig.SrcAddress = Nodes_SourceAddress[0];
  99.   
  100.   /* Create Node 1*/
  101.   HAL_MDMA_LinkedList_CreateNode(&Xfer_Node, &mdmaLinkNodeConfig);
  102.   /*Add created Node to the linkedlist */
  103.   HAL_MDMA_LinkedList_AddNode(&MDMA_Handle, &Xfer_Node, 0);
  104.   
  105.   
  106.   /* Node 2 : Dummy node (inserted to able to wait for Node 1 source address update done by DMA1 stream 0 transfer)
  107.     For this node the MDMA transfer trigger is set to DMA1 stream1 Transfer complete flag.
  108.     Knowing that DMA1 stream1 (circular) transfer is a dummy transfer triggerd by DMA1 Stream0
  109.     transfer event
  110.   */
  111.   mdmaLinkNodeConfig.Init.Request              = MDMA_REQUEST_DMA1_Stream1_TC;
  112.   mdmaLinkNodeConfig.Init.TransferTriggerMode  = MDMA_BUFFER_TRANSFER;
  113.   mdmaLinkNodeConfig.Init.Priority             = MDMA_PRIORITY_HIGH;         
  114.   mdmaLinkNodeConfig.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;         
  115.   
  116.   mdmaLinkNodeConfig.Init.SourceInc            = MDMA_SRC_INC_WORD;     
  117.   mdmaLinkNodeConfig.Init.DestinationInc       = MDMA_DEST_INC_WORD;
  118.   
  119.   mdmaLinkNodeConfig.Init.SourceDataSize       = MDMA_SRC_DATASIZE_WORD;      
  120.   mdmaLinkNodeConfig.Init.DestDataSize         = MDMA_DEST_DATASIZE_WORD;        
  121.   mdmaLinkNodeConfig.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                                 
  122.   mdmaLinkNodeConfig.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;         
  123.   mdmaLinkNodeConfig.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;           
  124.   mdmaLinkNodeConfig.Init.BufferTransferLength = 32;
  125.   
  126.   mdmaLinkNodeConfig.Init.SourceBlockAddressOffset  = 0;
  127.   mdmaLinkNodeConfig.Init.DestBlockAddressOffset    = 0;
  128.   
  129.   /* MDMA Post request address and  Mask set respectively to the DMA1 stream1 Interrupt Clear register address
  130.      and the DMA1 stream1 Clear Transfer Interrurpt flag mask in order to clear the DMA1 stream1
  131.      Transfer complete flag
  132.   */   
  133.   mdmaLinkNodeConfig.PostRequestMaskAddress = (uint32_t)(&(DMA1->LIFCR));
  134.   mdmaLinkNodeConfig.PostRequestMaskData = DMA_LIFCR_CTCIF1;
  135.   
  136.   /* Source and destination address are dummy , BlockDataLength  is 4 bytes and block count is 1*/
  137.   mdmaLinkNodeConfig.DstAddress      = (uint32_t)(&dummy_destination);
  138.   mdmaLinkNodeConfig.BlockDataLength = 4;
  139.   mdmaLinkNodeConfig.BlockCount      = 1;

  140.   mdmaLinkNodeConfig.SrcAddress = (uint32_t)(&dummy_source);
  141.   
  142.   HAL_MDMA_LinkedList_CreateNode(&Xfer_DummyNode, &mdmaLinkNodeConfig);
  143.   /*Add created Node to the linkedlist */
  144.   HAL_MDMA_LinkedList_AddNode(&MDMA_Handle, &Xfer_DummyNode, 0);  

  145.   
  146.   /* Make the linked list circular */
  147.   HAL_MDMA_LinkedList_EnableCircularMode(&MDMA_Handle);

  148.   /*
  149.     As the MDMA Node descriptor "Xfer_Node" is located in the D1 AXI-SRAM which
  150.     is cacheable, it is necessary to clean the data cache after creating the node
  151.     in order to make sure that the MDMA will load up to date data from the linked list node
  152.   */
  153.   SCB_CleanDCache_by_Addr((uint32_t *)&(Xfer_Node), sizeof(MDMA_LinkNodeTypeDef));
  154.   SCB_CleanDCache_by_Addr((uint32_t *)&(Xfer_DummyNode), sizeof(MDMA_LinkNodeTypeDef));
  155.   
  156.   /*##-6- Select Callbacks functions called in case of  MDMA Transfer error */
  157.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_ERROR_CB_ID, MDMA_TransferErrorCallback);
  158.   
  159.   /*##-7- Configure NVIC for MDMA transfer complete/error interrupts ##########*/
  160.   /* Set Interrupt Group Priority */
  161.   HAL_NVIC_SetPriority(MDMA_IRQn, 0, 0);
  162.   
  163.   /* Enable the MDMA channel global Interrupt */
  164.   HAL_NVIC_EnableIRQ(MDMA_IRQn);  
  165. }


  166. void DMA_Config(void)
  167. {
  168.   HAL_DMA_MuxRequestGeneratorConfigTypeDef dmamux_ReqGenParams;
  169.   HAL_DMA_MuxSyncConfigTypeDef dmamux_syncParams;
  170.   
  171.   /* Enable BDMA clock */
  172.   __HAL_RCC_DMA1_CLK_ENABLE();
  173.   
  174.   /* Configure DMA1_Stream0     */
  175.   /* DMA mode is set to circular for an infinite DMA transfer :
  176.      This transfer is used to update the MDMA Node 1 source address
  177.      to the next image address each time.
  178.      This transfer is triggered by the DMA request generator 0 with Signal ID set to
  179.      LPTIM1 output knoing that the LPTIM1 is configured with 100ms auto-reload
  180.   */  
  181.   DMA_Handlel1.Instance                 = DMA1_Stream0;
  182.   
  183.   DMA_Handlel1.Init.Request             = DMA_REQUEST_GENERATOR0;  
  184.   DMA_Handlel1.Init.Direction           = DMA_MEMORY_TO_PERIPH;
  185.   DMA_Handlel1.Init.PeriphInc           = DMA_PINC_DISABLE;
  186.   DMA_Handlel1.Init.MemInc              = DMA_MINC_ENABLE;
  187.   DMA_Handlel1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  188.   DMA_Handlel1.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
  189.   DMA_Handlel1.Init.Mode                = DMA_CIRCULAR;
  190.   DMA_Handlel1.Init.Priority            = DMA_PRIORITY_LOW;
  191.   DMA_Handlel1.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
  192.   DMA_Handlel1.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  193.   DMA_Handlel1.Init.MemBurst            = DMA_MBURST_SINGLE;
  194.   DMA_Handlel1.Init.PeriphBurst         = DMA_PBURST_SINGLE;
  195.   
  196.   DMA_Handlel1.XferCpltCallback         = NULL;
  197.   DMA_Handlel1.XferErrorCallback        = NULL;
  198.   
  199.   /* Initialize the DMA with for Transmission process */
  200.   HAL_DMA_Init(&DMA_Handlel1);
  201.   
  202.   /*##-3- Configure and enable the DMAMUX Request generator  ####################*/
  203.   dmamux_ReqGenParams.SignalID  = HAL_DMAMUX1_REQ_GEN_LPTIM1_OUT; /* External request signal is EXTI0 signal */
  204.   dmamux_ReqGenParams.Polarity  = HAL_DMAMUX_REQ_GEN_RISING;      /* External request signal edge is Rising  */
  205.   dmamux_ReqGenParams.RequestNumber = 1;                          /* 1 requests on each edge of the external request signal  */
  206.   
  207.   /* Configure the DMAMUX Synchronization with Synchro disabled and event generation enabled
  208.      in order to generate an evenet on each transfer request that will trig the second DMA (DMA_Handlel2)
  209.   */
  210.   dmamux_syncParams.EventEnable    = ENABLE;                 /* Enable DMAMUX event generation each time  RequestNumber are passed from DMAMUX to the DMA */
  211.   dmamux_syncParams.SyncPolarity  = HAL_DMAMUX_SYNC_RISING;  /* Synchronization edge is Rising  */
  212.   dmamux_syncParams.RequestNumber = 1;                       /* 1 requests are autorized after each edge of the sync signal */
  213.   dmamux_syncParams.SyncSignalID  = 0;                       /* No need for synchro signal as the   Synchronization is disabled */
  214.   dmamux_syncParams.SyncEnable     = DISABLE;                /* Synchronization is disabled */   
  215.   
  216.   HAL_DMAEx_ConfigMuxSync(&DMA_Handlel1, &dmamux_syncParams);
  217.   
  218.   
  219.   HAL_DMAEx_ConfigMuxRequestGenerator(&DMA_Handlel1, &dmamux_ReqGenParams);
  220.   HAL_DMAEx_EnableMuxRequestGenerator (&DMA_Handlel1);
  221.   
  222. /* Config DMA1_Stream1 */
  223. /* DMA mode is set to circular for an infinite DMA transfer.
  224.     This transfer is adummy transfer synchronized with DMA1 Stream0 transfer event.
  225.     The MDMA Node2 is a dummy transfer that is triggered with this DMA1 stream1 transfer compelete
  226.     which indicates that DMA1 Stream0 has updated the Node1 source address with the next image address
  227. */  
  228.   DMA_Handlel2.Instance                 = DMA1_Stream1;
  229.   
  230.   DMA_Handlel2.Init.Request             = DMA_REQUEST_GENERATOR1;  
  231.   DMA_Handlel2.Init.Direction           = DMA_MEMORY_TO_PERIPH;
  232.   DMA_Handlel2.Init.PeriphInc           = DMA_PINC_DISABLE;
  233.   DMA_Handlel2.Init.MemInc              = DMA_MINC_DISABLE;
  234.   DMA_Handlel2.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  235.   DMA_Handlel2.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
  236.   DMA_Handlel2.Init.Mode                = DMA_CIRCULAR;
  237.   DMA_Handlel2.Init.Priority            = DMA_PRIORITY_LOW;
  238.   DMA_Handlel2.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
  239.   DMA_Handlel2.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  240.   DMA_Handlel2.Init.MemBurst            = DMA_MBURST_SINGLE;
  241.   DMA_Handlel2.Init.PeriphBurst         = DMA_PBURST_SINGLE;
  242.   
  243.   DMA_Handlel2.XferCpltCallback         = NULL;
  244.   DMA_Handlel2.XferErrorCallback        = NULL;
  245.   
  246.   /* Initialize the DMA with for Transmission process */
  247.   HAL_DMA_Init(&DMA_Handlel2);
  248.   
  249.   /*##-3- Configure and enable the DMAMUX Request generator  ####################*/
  250.   dmamux_ReqGenParams.SignalID  = HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT; /* External request signal DMAMUX1 CH0 event : i.e DMA1_Steam0 event */
  251.   dmamux_ReqGenParams.Polarity  = HAL_DMAMUX_REQ_GEN_RISING;           /* External request signal edge is Rising  */
  252.   dmamux_ReqGenParams.RequestNumber = 1;                                   /* 1 requests on each edge of the external request signal  */
  253.   
  254.   HAL_DMAEx_ConfigMuxRequestGenerator(&DMA_Handlel2, &dmamux_ReqGenParams);
  255.   HAL_DMAEx_EnableMuxRequestGenerator (&DMA_Handlel2);
  256.   
  257.   /* Start DMAs*/
  258.   HAL_DMA_Start_IT(&DMA_Handlel1, (uint32_t)Nodes_SourceAddress, (uint32_t)(&(Xfer_Node.CSAR)), MDMA_IMAGE_NB);
  259.   HAL_DMA_Start_IT(&DMA_Handlel2, (uint32_t)(&dummy_source), (uint32_t)(&dummy_destination), 1);

  260. }

  261. /**
  262.   * @brief  Configure and start the LPTIM1 with 100ms period and 50% duty cycle.
  263.   * @param  None
  264.   * @retval None
  265.   */
  266. void LPTIM_Config(void)
  267. {

  268.   uint32_t periodValue;
  269.   uint32_t pulseValue ;
  270.   
  271.   RCC_OscInitTypeDef RCC_OscInitStruct;
  272.   RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct;
  273.   
  274.   
  275.   /* Enable the LSE clock source */
  276.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
  277.   RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  278.   RCC_OscInitStruct.PLL.PLLState  = RCC_PLL_NONE;
  279.   HAL_RCC_OscConfig(&RCC_OscInitStruct);
  280.   
  281.   /* LPTIM1 clock source set to LSE*/
  282.   PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1;
  283.   PeriphClkInitStruct.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSE;
  284.   HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);  

  285.   periodValue =  (2 * (LSE_VALUE/20))/4;  /* Calculate the Timer  Autoreload value for 100ms period */
  286.   pulseValue  = periodValue/2;            /* Set the Timer  pulse value for 50% duty cycle         */
  287.   
  288.   /* TIM1 Peripheral clock enable */
  289.   __HAL_RCC_LPTIM1_CLK_ENABLE();
  290.   
  291.   LptimHandle.Instance                           = LPTIM1;

  292.   LptimHandle.Init.CounterSource                 = LPTIM_COUNTERSOURCE_INTERNAL;
  293.   LptimHandle.Init.UpdateMode                    = LPTIM_UPDATE_ENDOFPERIOD;
  294.   LptimHandle.Init.OutputPolarity                = LPTIM_OUTPUTPOLARITY_LOW;
  295.   LptimHandle.Init.Clock.Source                  = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
  296.   LptimHandle.Init.Clock.Prescaler               = LPTIM_PRESCALER_DIV4;
  297.   LptimHandle.Init.UltraLowPowerClock.Polarity   = LPTIM_CLOCKPOLARITY_RISING;
  298.   LptimHandle.Init.UltraLowPowerClock.SampleTime = LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
  299.   LptimHandle.Init.Trigger.Source                = LPTIM_TRIGSOURCE_SOFTWARE;
  300.   LptimHandle.Init.Trigger.ActiveEdge            = LPTIM_ACTIVEEDGE_RISING;
  301.   LptimHandle.Init.Trigger.SampleTime            = LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION;

  302.   if(HAL_LPTIM_Init(&LptimHandle) != HAL_OK)
  303.   {
  304.     /* Initialization Error */
  305.     Error_Handler();
  306.   }
  307.   
  308.   /* Start the timer */
  309.   if (HAL_LPTIM_PWM_Start(&LptimHandle, periodValue, pulseValue) != HAL_OK)
  310.   {
  311.     Error_Handler();
  312.   }  
  313.   
  314. }
复制代码





回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2018-8-11 12:23:51 | 显示全部楼层
实例5:MDMA_LTDC_Triggering


例程说明:

这个例子实现DMA2D完成标志触发MDMA的功能。每次DMA2D绘制完毕一个图片后,触发的MDMA再将这个图片旋转180度镜像显示出来。
MDMA创建了两个节点,节点0和节点1,节点1配置成循环模式。两个节点的功能一样,只是节点0仅执行一次,之后节点1循环执行。

配置如下:


  1. /**
  2.   * @brief  Initialize the MDMA For repeat block transfer in linked list circular
  3.     with trigger set to DMA2D Transfer complete flag and trigger mode set to
  4.     repeat block transfer.
  5.   * @param  None
  6.   * @retval None
  7.   */
  8. static void MDMA_Config(void)
  9. {
  10.   uint32_t hal_status = HAL_OK;  
  11.   MDMA_LinkNodeConfTypeDef mdmaLinkNodeConfig;   
  12.    
  13.   /*##-1- Enable the MDMA clock ###############################################*/  
  14.   __HAL_RCC_MDMA_CLK_ENABLE();  
  15.   
  16.   /*##-2- Select the MDMA instance to be used : MDMA_Channel0 #################*/
  17.   MDMA_Handle.Instance = MDMA_Channel0;  
  18.   
  19.   /*##-3- Configure the MDMA for block transfer in HW request mode ############*/  
  20.   /*
  21.   Config the MDMA to copy the source image to the LCD frame buffer at the center
  22.   position with 180?rotation and mirror effect.
  23.   Each block corresponds to a line of the source/destination image.
  24.   The number of blocks corresponds to the number of lines of the image.
  25.   
  26.   The MDMA Request is set to DMA2D Transfer complete flag and the MDMA trigger Mode
  27.   is set to Repeat block mode. As consequence each DMA2D transfer complete event
  28.   (DMA2D has end copying an image to the Top-center of the LCD frame buffer ),
  29.   the MDMA will start a repeat block transfer which correspond of copying the DMA2D
  30.   image with 180?and rotation effect to the bottom-center of the LCD frame buffer.
  31.   */
  32.   
  33.   MDMA_Handle.Init.Request              = MDMA_REQUEST_DMA2D_TC;
  34.   MDMA_Handle.Init.TransferTriggerMode  = MDMA_REPEAT_BLOCK_TRANSFER;  
  35.   MDMA_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;
  36.   MDMA_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  37.   MDMA_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  38.   MDMA_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  39.   MDMA_Handle.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  40.   MDMA_Handle.Init.BufferTransferLength = 128;
  41.   
  42.   /* Source and Destination data size are word , 4 bytes that correspond to an ARGB8888 pixel 32 bpp */     
  43.   MDMA_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_WORD;
  44.   MDMA_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_WORD;
  45.   
  46.   /* Source and Destination  Increment is word , 4 bytes that correspond to an ARGB8888 pixel 32 bpp */      
  47.   MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_WORD;
  48.   MDMA_Handle.Init.DestinationInc       = MDMA_DEST_INC_WORD;

  49.   /*Source Block address offset is set to LCD Offset as the source image is in the center of the LCD */   
  50.   MDMA_Handle.Init.SourceBlockAddressOffset  = (int32_t)LCD_Offset;
  51.   
  52.   /* Destination Block address offset is set in order to place the image in the center of the LCD frame buffer
  53.   the destination blocks are not contiguous. The LCD_Offset is = to LCD X size - image width
  54.   Knowing that the destination address is set to the first pixel address of the last line
  55.   in the destination image, the destination block offset allows to decrement the destination address
  56.   after each block in order to start the next block at previous line */      
  57.   MDMA_Handle.Init.DestBlockAddressOffset    = ((-2) * ((int32_t)(ARGB8888_BYTES_PER_PIXEL * IMAGE_WIDTH))) - ((int32_t)LCD_Offset);   
  58.   
  59.   /*##-4- Initialize the MDMA channel ##########################################*/  
  60.   hal_status = HAL_MDMA_Init(&MDMA_Handle);
  61.   
  62.   if(hal_status != HAL_OK)  
  63.   {
  64.     /* Initialization Error */
  65.     Error_Handler();
  66.   }

  67.   HAL_MDMA_ConfigPostRequestMask(&MDMA_Handle, 0, 0);
  68.   
  69.   /*##-5- Create Linked list Node ############################################*/
  70.   
  71.   /*
  72.      Create and add a linked list node that have the same parameters as the
  73.      initial transfer.
  74.      The purpose of the linked list node is to create a circular list. the MDMA
  75.      transfer will then loop infinitely. Each DMA2D Transfer complete flag will trig
  76.      a Node transfer ( a repeat block transfer) that correspond to a new image transfer
  77.   */
  78.   mdmaLinkNodeConfig.Init.Request              = MDMA_Handle.Init.Request;
  79.   mdmaLinkNodeConfig.Init.TransferTriggerMode  = MDMA_Handle.Init.TransferTriggerMode;
  80.   mdmaLinkNodeConfig.Init.Priority             = MDMA_Handle.Init.Priority;         
  81.   mdmaLinkNodeConfig.Init.Endianness           = MDMA_Handle.Init.Endianness;         
  82.   
  83.   mdmaLinkNodeConfig.Init.SourceInc            = MDMA_Handle.Init.SourceInc;     
  84.   mdmaLinkNodeConfig.Init.DestinationInc       = MDMA_Handle.Init.DestinationInc;
  85.   
  86.   mdmaLinkNodeConfig.Init.SourceDataSize       = MDMA_Handle.Init.SourceDataSize;      
  87.   mdmaLinkNodeConfig.Init.DestDataSize         = MDMA_Handle.Init.DestDataSize;        
  88.   mdmaLinkNodeConfig.Init.DataAlignment        = MDMA_Handle.Init.DataAlignment;                                 
  89.   mdmaLinkNodeConfig.Init.SourceBurst          = MDMA_Handle.Init.SourceBurst;         
  90.   mdmaLinkNodeConfig.Init.DestBurst            = MDMA_Handle.Init.DestBurst;           
  91.   mdmaLinkNodeConfig.Init.BufferTransferLength = MDMA_Handle.Init.BufferTransferLength;
  92.   
  93.   mdmaLinkNodeConfig.Init.SourceBlockAddressOffset  = MDMA_Handle.Init.SourceBlockAddressOffset;
  94.   mdmaLinkNodeConfig.Init.DestBlockAddressOffset    = MDMA_Handle.Init.DestBlockAddressOffset;
  95.   
  96.   mdmaLinkNodeConfig.PostRequestMaskAddress = 0;
  97.   mdmaLinkNodeConfig.PostRequestMaskData = 0;  
  98.   
  99.   /* Create Node*/  
  100.   mdmaLinkNodeConfig.SrcAddress      = dma2d_destination;
  101.   mdmaLinkNodeConfig.DstAddress      = mdma_destination;
  102.   mdmaLinkNodeConfig.BlockDataLength = IMAGE_WIDTH * ARGB8888_BYTES_PER_PIXEL;
  103.   mdmaLinkNodeConfig.BlockCount      = IMAGE_HEIGHT;

  104.   HAL_MDMA_LinkedList_CreateNode(&Xfer_Node, &mdmaLinkNodeConfig);
  105.   
  106.   /*Add created Node to the linkedlist */
  107.   HAL_MDMA_LinkedList_AddNode(&MDMA_Handle, &Xfer_Node, 0);
  108.   
  109.   /* Make the linked list circular */
  110.   HAL_MDMA_LinkedList_EnableCircularMode(&MDMA_Handle);
  111.   
  112.   /*
  113.     As the MDMA Node descriptor "Xfer_Node" is located in the D1 AXI-SRAM which
  114.     is cacheable, it is necessary to clean the data cache after creating the node
  115.     in order to make sure that the MDMA will load up to date data from the linked list node
  116.   */
  117.   SCB_CleanDCache_by_Addr((uint32_t *)&(Xfer_Node), sizeof(MDMA_LinkNodeTypeDef));
  118.   
  119.   /*##-6- Select Callbacks functions called after MDMA Repeat block Transfer complete and Transfer error */
  120.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_REPBLOCKCPLT_CB_ID, MDMA_RepeatBlockTransferCompleteCallback);
  121.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_ERROR_CB_ID, MDMA_TransferErrorCallback);
  122.   
  123.   /*##-7- Configure NVIC for MDMA transfer complete/error interrupts ##########*/
  124.   /* Set Interrupt Group Priority */
  125.   HAL_NVIC_SetPriority(MDMA_IRQn, 0, 0);
  126.   
  127.   /* Enable the MDMA channel global Interrupt */
  128.   HAL_NVIC_EnableIRQ(MDMA_IRQn);  
  129.   

  130. }

  131. /**
  132.   * @brief  Initialize the DMA2D for Mem TO Mem copy with output offset set to
  133.     place the image in the center of the LCD frame buffer.
  134.   * @param  xSize: Image width  
  135.   * @retval None
  136.   */
  137. static void DMA2D_Config(uint16_t xSize)
  138. {   
  139.   uint32_t hal_status = HAL_OK;
  140.   
  141.   /*##-1- Configure the DMA2D Mode, Color Mode and output offset #############*/
  142.   DMA2D_Handle.Init.Mode          = DMA2D_M2M;
  143.   DMA2D_Handle.Init.ColorMode     = DMA2D_OUTPUT_ARGB8888;
  144.   DMA2D_Handle.Init.OutputOffset  = LCD_X_Size - xSize;
  145.   DMA2D_Handle.Init.AlphaInverted = DMA2D_REGULAR_ALPHA;  /* No Output Alpha Inversion*/  
  146.   DMA2D_Handle.Init.RedBlueSwap   = DMA2D_RB_REGULAR;     /* No Output Red & Blue swap */  
  147.   
  148.   /*##-2- DMA2D Callbacks Configuration ######################################*/
  149.   DMA2D_Handle.XferCpltCallback  = NULL;
  150.   
  151.   /*##-3- Foreground Configuration ###########################################*/
  152.   DMA2D_Handle.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
  153.   DMA2D_Handle.LayerCfg[1].InputAlpha = 0xFF;
  154.   DMA2D_Handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888;
  155.   DMA2D_Handle.LayerCfg[1].InputOffset = 0;
  156.   DMA2D_Handle.LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR; /* No ForeGround Red/Blue swap */
  157.   DMA2D_Handle.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; /* No ForeGround Alpha inversion */  

  158.   DMA2D_Handle.Instance          = DMA2D;
  159.    
  160.   /* DMA2D Initialization */
  161.   hal_status = HAL_DMA2D_Init(&DMA2D_Handle);
  162.   
  163.   if(hal_status != HAL_OK)
  164.   {
  165.     Error_Handler();
  166.   }

  167.   hal_status = HAL_DMA2D_ConfigLayer(&DMA2D_Handle, 1);
  168.   
  169.   if(hal_status != HAL_OK)
  170.   {
  171.     Error_Handler();
  172.   }   
  173. }
复制代码


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2018-8-11 12:32:53 | 显示全部楼层
实例6:MDMA_RepeatBlock_Rotation


例程说明:

这个例子主要是图片四个方向的旋转显示。对于不同方向的选择,重点理解参数MDMA_Handle.Init.DestBlockAddressOffset即可。而理解这个参数,仅需明白一点,它是指的的当前行结束点到下一个起始点之间的间距

下面配置代码里面除了四个方向的选择显示,还有一个清背景的功能,即Config = 0;
配置如下:

  1. /**
  2.   * @brief  MDMA Repeat blocks ransfer configuraion
  3.   * @note   This function configure the DMA for a Repeat BLock transfer.
  4.   * @retval None
  5.   */
  6. static void MDMA_Config(uint32_t Config)
  7. {
  8.   
  9.   /*##-1- Select the MDMA instance to be used for the transfer : MDMA_Channel0 #*/
  10.   MDMA_Handle.Instance = MDMA_INSTANCE;
  11.   
  12.   HAL_MDMA_DeInit(&MDMA_Handle);
  13.   
  14.   /*## Enable peripherals and GPIO Clocks #*/
  15.   __HAL_RCC_MDMA_CLK_ENABLE();

  16.   /*## Configure NVIC for MDMA transfer complete/error interrupts #*/
  17.   /* Set Interrupt Group Priority */
  18.   HAL_NVIC_SetPriority(MDMA_IRQn, 0xF, 0xF);
  19.   
  20.   /* Enable the MDMA channel global Interrupt */
  21.   HAL_NVIC_EnableIRQ(MDMA_IRQn);  
  22.   
  23.   /*##-2- Select the MDMA functional Parameters ###############################*/
  24.   
  25.   /* Set the MDMA parameters : For repeated block transfer*/  
  26.   if(Config == 0)
  27.   {
  28.     /* config in Repeat Block to clear the LCD frame buffer with default color
  29.        Each block corresponds to a line of the LCD frame buffer.
  30.        The number of blocks corresponds to the number of lines in the LCD frame buffer
  31.     */
  32.     MDMA_Handle.Init.Request              = MDMA_REQUEST_SW;
  33.     MDMA_Handle.Init.TransferTriggerMode  = MDMA_REPEAT_BLOCK_TRANSFER;  
  34.     MDMA_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;
  35.     MDMA_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  36.     MDMA_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  37.     MDMA_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  38.     MDMA_Handle.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  39.     MDMA_Handle.Init.BufferTransferLength = 128;
  40.    
  41.     /*Source Block address offset is null, the source blocks are contiguous*/
  42.     MDMA_Handle.Init.SourceBlockAddressOffset  = 0;
  43.    
  44.     /* Source and Destination data size are half word , 2 bytes that correspond to an RGB565 pixel 16 bpp */
  45.     MDMA_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_HALFWORD;
  46.     MDMA_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_HALFWORD;
  47.    
  48.     /* Source Increment is disabled : the source address always corresponds
  49.        to the address of the LCD_Fill_Color variable that holds the default color value*/
  50.     MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_DISABLE;
  51.     /* Destination  Increment is half word , 2 bytes that correspond to an RGB565 pixel 16 bpp */
  52.     MDMA_Handle.Init.DestinationInc       = MDMA_DEST_INC_HALFWORD;  
  53.   
  54.     /*Destination Block address offset is null, the destination blocks are contiguous*/
  55.     MDMA_Handle.Init.DestBlockAddressOffset    = 0;   
  56.   }
  57.   else if(Config == 1)
  58.   {
  59.     /*
  60.       Config to copy the source image to the LCD frame buffer at the center position.
  61.       Each block corresponds to a line of the source/destination image.
  62.       The number of blocks corresponds to the number of lines of the image
  63.     */
  64.     MDMA_Handle.Init.Request              = MDMA_REQUEST_SW;
  65.     MDMA_Handle.Init.TransferTriggerMode  = MDMA_REPEAT_BLOCK_TRANSFER;  
  66.     MDMA_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;
  67.     MDMA_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  68.     MDMA_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  69.     MDMA_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  70.     MDMA_Handle.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  71.     MDMA_Handle.Init.BufferTransferLength = 128;

  72.    /*Source Block address offset is null, the source blocks are contiguous*/   
  73.     MDMA_Handle.Init.SourceBlockAddressOffset  = 0;

  74.     /* Source and Destination data size are half word , 2 bytes that correspond to an RGB565 pixel 16 bpp */   
  75.     MDMA_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_HALFWORD;
  76.     MDMA_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_HALFWORD;

  77.     /* Source and Destination  Increment is half word , 2 bytes that correspond to an RGB565 pixel 16 bpp */     
  78.     MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_HALFWORD;
  79.     MDMA_Handle.Init.DestinationInc       = MDMA_DEST_INC_HALFWORD;
  80.   
  81.    /* Destination Block address offset is set in order to place the image in the center of the LCD frame buffer
  82.       the destination blocks are not contiguous. The LCD_Offset is = to LCD X size - image width */   
  83.     MDMA_Handle.Init.DestBlockAddressOffset = LCD_Offset;   
  84.   }   
  85.   else if(Config == 2)
  86.   {
  87.     /*
  88.       Config to copy the source image to the LCD frame buffer at the center position with mirror effect.
  89.       Each block corresponds to a line of the source/destination image.
  90.       The number of blocks corresponds to the number of lines of the image
  91.     */
  92.     MDMA_Handle.Init.Request              = MDMA_REQUEST_SW;
  93.     MDMA_Handle.Init.TransferTriggerMode  = MDMA_REPEAT_BLOCK_TRANSFER;  
  94.     MDMA_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;
  95.     MDMA_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  96.     MDMA_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  97.     MDMA_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  98.     MDMA_Handle.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  99.     MDMA_Handle.Init.BufferTransferLength = 128;
  100.    
  101.     /*Source Block address offset is null, the source blocks are contiguous*/
  102.     MDMA_Handle.Init.SourceBlockAddressOffset  = 0;

  103.     /* Source and Destination data size are half word , 2 bytes that correspond to an RGB565 pixel 16 bpp */     
  104.     MDMA_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_HALFWORD;
  105.     MDMA_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_HALFWORD;

  106.     /* Source Increment is half word , 2 bytes that correspond to an RGB565 pixel 16 bpp
  107.        Knowing that the source address is set to the source image start address */      
  108.     MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_HALFWORD;
  109.     /* Destination  Decrement by half word , 2 bytes that correspond to an RGB565 pixel 16 bpp
  110.        Knowing that the destination address is set to the last pixel address in the first line
  111.        of the destination image */      
  112.     MDMA_Handle.Init.DestinationInc       = MDMA_DEST_DEC_HALFWORD;  

  113.    /* Destination Block address offset is set in order to place the image in the center of the LCD frame buffer
  114.       the destination blocks are not contiguous. The LCD_Offset is = to LCD X size - image width
  115.       Knowing that the destination address is set to the last pixel address in the first line
  116.       of the destination image, the destination block offset takes also into acount that
  117.       the destination address is decrementing*/      
  118.     MDMA_Handle.Init.DestBlockAddressOffset    = (int32_t)(LCD_Offset + (2 * (RGB565_BYTES_PER_PIXEL * IMAGE_WIDTH)));
  119.   }
  120.   else if(Config == 3)
  121.   {
  122.     /* Config to copy the source image to the LCD frame buffer at the center position with 180?rotation effect
  123.        Each block corresponds to a line of the source/destination image.
  124.       The number of blocks corresponds to the number of lines of the image
  125.     */
  126.     MDMA_Handle.Init.Request              = MDMA_REQUEST_SW;
  127.     MDMA_Handle.Init.TransferTriggerMode  = MDMA_REPEAT_BLOCK_TRANSFER;  
  128.     MDMA_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;
  129.     MDMA_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  130.     MDMA_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  131.     MDMA_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  132.     MDMA_Handle.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  133.     MDMA_Handle.Init.BufferTransferLength = 128;
  134.    
  135.     /*Source Block address offset is null, the source blocks are contiguous*/
  136.     MDMA_Handle.Init.SourceBlockAddressOffset  = 0;
  137.    
  138.      /* Source and Destination data size are half word , 2 bytes that correspond to an RGB565 pixel 16 bpp */
  139.     MDMA_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_HALFWORD;
  140.     MDMA_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_HALFWORD;

  141.     /* Source Increment is half word , 2 bytes that correspond to an RGB565 pixel 16 bpp
  142.        Knowing that the source address is set to the source image start address */      
  143.     MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_HALFWORD;
  144.     /* Destination  Decrement by half word , 2 bytes that correspond to an RGB565 pixel 16 bpp
  145.        Knowing that the destination address is set to the last pixel of the destination image */     
  146.     MDMA_Handle.Init.DestinationInc       = MDMA_DEST_DEC_HALFWORD;

  147.     /* Destination Block address offset is set in order to place the image in the center of the LCD frame buffer
  148.       the destination blocks are not contiguous. The LCD_Offset is = to LCD X size - image width
  149.       Knowing that the destination address is set to  the last pixel address of
  150.       the destination image, the destination block offset takes also into acount that the destination address is decrementing*/   
  151.     MDMA_Handle.Init.DestBlockAddressOffset    = (int32_t)((-1) * LCD_Offset);   
  152.   }
  153.   else if(Config == 4)
  154.   {
  155.     /*
  156.       Config copy the source image to the LCD frame buffer at the center position with 180?rotation and mirror effect
  157.       Each block corresponds to a line of the source/destination image.
  158.       The number of blocks corresponds to the number of lines of the image
  159.     */
  160.     MDMA_Handle.Init.Request              = MDMA_REQUEST_SW;
  161.     MDMA_Handle.Init.TransferTriggerMode  = MDMA_REPEAT_BLOCK_TRANSFER;  
  162.     MDMA_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;
  163.     MDMA_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  164.     MDMA_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  165.     MDMA_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  166.     MDMA_Handle.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  167.     MDMA_Handle.Init.BufferTransferLength = 128;

  168.     /*Source Block address offset is null, the source blocks are contiguous*/   
  169.     MDMA_Handle.Init.SourceBlockAddressOffset  = 0;

  170.     /* Source and Destination data size are half word , 2 bytes that correspond to an RGB565 pixel 16 bpp */     
  171.     MDMA_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_HALFWORD;
  172.     MDMA_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_HALFWORD;

  173.     /* Source and Destination  Increment is half word , 2 bytes that correspond to an RGB565 pixel 16 bpp */      
  174.     MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_HALFWORD;
  175.     MDMA_Handle.Init.DestinationInc       = MDMA_DEST_INC_HALFWORD;

  176.     /* Destination Block address offset is set in order to place the image in the center of the LCD frame buffer
  177.       the destination blocks are not contiguous. The LCD_Offset is = to LCD X size - image width
  178.       Knowing that the destination address is set to the first pixel address of the last line
  179.       in the destination image, the destination block offset allows to decrement the destination address
  180.       after each block in order to start the next block at previous line */      
  181.     MDMA_Handle.Init.DestBlockAddressOffset    = ((-2) * ((int32_t)(RGB565_BYTES_PER_PIXEL * IMAGE_WIDTH))) - ((int32_t)LCD_Offset);   
  182.   }  
  183.   
  184.   /*##-3- Initialize the MDMA channel ##########################################*/
  185.   if (HAL_MDMA_Init(&MDMA_Handle) != HAL_OK)
  186.   {
  187.     /* in case of Initialization Error */
  188.     Error_Handler();
  189.   }
  190.   
  191.   /*##-4- Select Callbacks functions called after Transfer complete and Transfer error */
  192.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_CPLT_CB_ID, MDMA_TransferCompleteCallback);
  193.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_ERROR_CB_ID, MDMA_TransferErrorCallback);  

  194. }
复制代码





回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2018-8-11 12:44:51 | 显示全部楼层
实例7:MDMA_RepeatBlock_ZoomOut


例程说明:

这个例子比较简单,主要是实现利用MDMA实现清屏,原图大小图片和图片缩小一倍的显示。

配置如下:
  1. /**
  2.   * @brief  MDMA Liked List transfer configuraion
  3.   * @note   This function configure the DMA for a Repeat BLock transfer.
  4.   *
  5.   * @retval None
  6.   */
  7. static void MDMA_Config(uint32_t DecimationFactor)
  8. {
  9.   
  10.   /*##-1- Select the MDMA instance to be used for the transfer : MDMA_Channel0 #*/
  11.   MDMA_Handle.Instance = MDMA_INSTANCE;
  12.   
  13.   HAL_MDMA_DeInit(&MDMA_Handle);
  14.   
  15.   /*## Enable peripherals and GPIO Clocks #*/
  16.   __HAL_RCC_MDMA_CLK_ENABLE();

  17.   /*## Configure NVIC for MDMA transfer complete/error interrupts #*/
  18.   /* Set Interrupt Group Priority */
  19.   HAL_NVIC_SetPriority(MDMA_IRQn, 0xF, 0xF);
  20.   
  21.   /* Enable the MDMA channel global Interrupt */
  22.   HAL_NVIC_EnableIRQ(MDMA_IRQn);  
  23.   
  24.   /* Set the MDMA parameters : For repeated block transfer*/
  25.   MDMA_Handle.Init.Request              = MDMA_REQUEST_SW;
  26.   MDMA_Handle.Init.TransferTriggerMode  = MDMA_REPEAT_BLOCK_TRANSFER;  
  27.   MDMA_Handle.Init.Priority             = MDMA_PRIORITY_HIGH;
  28.   MDMA_Handle.Init.Endianness           = MDMA_LITTLE_ENDIANNESS_PRESERVE;

  29.   /* Destination  Increment is half word , 2 bytes that correspond to an RGB565 pixel 16 bpp */   
  30.   MDMA_Handle.Init.DestinationInc       = MDMA_DEST_INC_HALFWORD;
  31.   
  32.   /* Source and Destination data size are half word , 2 bytes that correspond to an RGB565 pixel 16 bpp */   
  33.   MDMA_Handle.Init.SourceDataSize       = MDMA_SRC_DATASIZE_HALFWORD;
  34.   MDMA_Handle.Init.DestDataSize         = MDMA_DEST_DATASIZE_HALFWORD;
  35.   MDMA_Handle.Init.DataAlignment        = MDMA_DATAALIGN_PACKENABLE;                           
  36.   MDMA_Handle.Init.SourceBurst          = MDMA_SOURCE_BURST_SINGLE;
  37.   MDMA_Handle.Init.DestBurst            = MDMA_DEST_BURST_SINGLE;
  38.   MDMA_Handle.Init.BufferTransferLength = 128;  
  39.   
  40.   /* Destination Block address offset is set in order to place the image in the center of the LCD frame buffer
  41.      the destination blocks are not contiguous. The LCD_Offset is = to LCD X size - image width */      
  42.   MDMA_Handle.Init.DestBlockAddressOffset    = LCD_Offset;  
  43.       
  44.   if(DecimationFactor == 0)
  45.   {
  46.     /* This case is used to clear the LCD with the default gray color */

  47.     /* Source Increment is disabled : the source address always corresponds
  48.        to the address of the LCD_Fill_Color variable that holds the default color value*/   
  49.     MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_DISABLE;

  50.     MDMA_Handle.Init.SourceBlockAddressOffset  = 0;  
  51.   }
  52.   else
  53.   {
  54.     /*
  55.       In case of a decimation by 2 , the source block address offset is set to :
  56.           Image_width * bytes_per_pixels = Image_width * 2.
  57.       This allows  to jump one line over 2 from the source image allowing to decimate vertically the original image by 2.
  58.       
  59.       In case of a decimation by 4 , the source block address offset is set to :
  60.           3 * Image_width * bytes_per_pixels = 3 * Image_width * 2.
  61.       This allows  to jump Three lines from the source image allowing to decimate vertically the original image by 4.  
  62.    
  63.       If no decimation (DecimationFactor = 1) , the he source block address offset is set to zero.
  64.     */
  65.     MDMA_Handle.Init.SourceBlockAddressOffset  = (IMAGE_WIDTH * RGB565_BYTES_PER_PIXEL * (DecimationFactor - 1));   
  66.   }
  67.   
  68.   if(DecimationFactor == 1)
  69.   {
  70.     /*No decimation by 2, the source increment is set  half word Same as the source data size*/
  71.     MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_HALFWORD;   
  72.   }
  73.   else if(DecimationFactor == 2)
  74.   {
  75.     /*In case of a decimation by 2, the source increment is set to WORD (2 half word) allowing to skip one pixel over two.*/
  76.     MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_WORD;
  77.   }
  78.   else  if(DecimationFactor == 4)
  79.   {
  80.     /*In case of a decimation by 4, the source increment is set to DOUBLE WORD (4 half word) allowing to skip 3 pixels over 4.*/
  81.     MDMA_Handle.Init.SourceInc            = MDMA_SRC_INC_DOUBLEWORD;
  82.   }

  83.   /*##-4- Initialize the MDMA channel ##########################################*/
  84.   if (HAL_MDMA_Init(&MDMA_Handle) != HAL_OK)
  85.   {
  86.     /* Initialization Error */
  87.     Error_Handler();
  88.   }
  89.   
  90.   /*##-5- Select Callbacks functions called after Transfer complete and Transfer error */
  91.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_CPLT_CB_ID, MDMA_TransferCompleteCallback);
  92.   HAL_MDMA_RegisterCallback(&MDMA_Handle, HAL_MDMA_XFER_ERROR_CB_ID, MDMA_TransferErrorCallback);
  93. }
复制代码


回复

使用道具 举报

8

主题

157

回帖

181

积分

初级会员

积分
181
发表于 2023-8-25 14:33:42 | 显示全部楼层
不错不错,省的找了
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2023-10-10 10:30:15 | 显示全部楼层
记号,正在学习这个,多数据块迁移。
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2023-10-12 16:04:28 | 显示全部楼层
STM32H750VB 使用 MDMA+FMC 能显示,但只有半屏(刷纯色),而且发觉比 DMA+FMC 快不了多少,还是能看到拉窗的情况。
使用 MDMA_REPEAT_BLOCK_TRANSFER;  模式,块长 15360, 块数 10。
能指点下半屏的问题?谢谢。

1. MDMA 传输 GRAM 数据到 FMC,屏 RGB320*480, 驱动 ILI4988 16bit(RGB565).  uint16_t GRAM[153600]。

2. 启动 MDMA 传输:
        LCD_Block_Write(0,0,COL-1,ROW-1);        //x1/y1,x2/y2, COL=320, ROW=480
        HAL_MDMA_Start_IT(&hmdma_mdma_channel0_sw_0, (uint32_t)&GRAM, (uint32_t)&LCD->RAM, pSize, pCount);

3. 初始化代码:
void MX_MDMA_Init(void)
{

  /* MDMA controller clock enable */
  __HAL_RCC_MDMA_CLK_ENABLE();
  /* Local variables */

  /* Configure MDMA channel MDMA_Channel0 */
  /* Configure MDMA request hmdma_mdma_channel0_sw_0 on MDMA_Channel0 */
  hmdma_mdma_channel0_sw_0.Instance                           = MDMA_Channel0;
  hmdma_mdma_channel0_sw_0.Init.Request                      = MDMA_REQUEST_SW;
  hmdma_mdma_channel0_sw_0.Init.TransferTriggerMode      = MDMA_REPEAT_BLOCK_TRANSFER;
  hmdma_mdma_channel0_sw_0.Init.Priority                        = MDMA_PRIORITY_VERY_HIGH;
  hmdma_mdma_channel0_sw_0.Init.Endianness                   = MDMA_LITTLE_ENDIANNESS_PRESERVE;
  hmdma_mdma_channel0_sw_0.Init.SourceInc                    = MDMA_SRC_INC_HALFWORD;
  hmdma_mdma_channel0_sw_0.Init.DestinationInc               = MDMA_DEST_INC_DISABLE;
  hmdma_mdma_channel0_sw_0.Init.SourceDataSize              = MDMA_SRC_DATASIZE_HALFWORD;
  hmdma_mdma_channel0_sw_0.Init.DestDataSize                 = MDMA_DEST_DATASIZE_HALFWORD;
  hmdma_mdma_channel0_sw_0.Init.DataAlignment               = MDMA_DATAALIGN_PACKENABLE;
  hmdma_mdma_channel0_sw_0.Init.BufferTransferLength       = 128;
  hmdma_mdma_channel0_sw_0.Init.SourceBurst                    = MDMA_SOURCE_BURST_SINGLE;
  hmdma_mdma_channel0_sw_0.Init.DestBurst                       = MDMA_DEST_BURST_SINGLE;
  hmdma_mdma_channel0_sw_0.Init.SourceBlockAddressOffset = 0;
  hmdma_mdma_channel0_sw_0.Init.DestBlockAddressOffset    = 0;
  if (HAL_MDMA_Init(&hmdma_mdma_channel0_sw_0) != HAL_OK)
  {
    Error_Handler();
  }

  /* MDMA interrupt initialization */
  /* MDMA_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(MDMA_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(MDMA_IRQn);

}


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106649
QQ
 楼主| 发表于 2023-10-13 01:24:02 | 显示全部楼层
sky9218 发表于 2023-10-12 16:04
STM32H750VB 使用 MDMA+FMC 能显示,但只有半屏(刷纯色),而且发觉比 DMA+FMC 快不了多少,还是能看到拉窗 ...

pSize, pCount配置的多少。
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2023-10-13 15:28:18 | 显示全部楼层
eric2013 发表于 2023-10-13 01:24
pSize, pCount配置的多少。

试过下列配置都一样。
pSize=480, pCount=320.
pSize=51200, pCount=3.
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2023-10-23 21:46:22 | 显示全部楼层
硬汉哥 请问你这些例程去哪找呢?求指教
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-27 22:44 , Processed in 0.201608 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表