/********************************************************************************
 * @file    DMA_ScatterGather.c
 * @author  SOC AE Team
 * @version V1.1
 * @date    2025-06-27
 * @brief  把DMA_ScatterGather_Data1、2、3数组每前4个数据合并成长度为12Byte的数组。
 *
 *******************************************************************************/
#include "sc32_conf.h"
#include "Function_Init.h"

 uint8_t DMA_ScatterGather_Data1[6] = "ABCDEF";
 uint8_t DMA_ScatterGather_Data2[6] = "abcdef";
 uint8_t DMA_ScatterGather_Data3[6] = "123456";

void DMA_ScatterGather_Function(void)
{
  DMA_InitTypeDef DMA_InitStruct; //定义DMA初始化结构体变量
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

  const uint8_t* DMA_ScatterGather_ScatterSrc[] =
  {
    DMA_ScatterGather_Data1, DMA_ScatterGather_Data2,
    DMA_ScatterGather_Data3
  };
  uint8_t DMA_ScatterGather_GatherDst[12];

  /* 使能TIM1时钟 */
  RCC_APB0Cmd(ENABLE);
  RCC_APB0PeriphClockCmd(RCC_APB0Periph_TIM1, ENABLE);
  /* 使能DMA的时钟 */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);

  /* TIM配置结构体初始化 */
  TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
  /* 设置TIM配置结构体 */
  TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;	//TIM工作在向上计数模式
  TIM_TimeBaseInitStruct.TIM_EXENX = TIM_EXENX_Disable;	//外部重加载管脚失能
#if defined(SC32f10xx)||defined(SC32f12xx)
  TIM_TimeBaseInitStruct.TIM_Preload = 65535-(32000000 / 1000);	//设置TIM的定时器频率为1000Hz@APB0Clock=32M                                                                   //TIM向上计数时，重载值=65536-(TIM时钟频率/1000000*TIM定时频率)
#endif	
  TIM_TimeBaseInitStruct.TIM_Prescaler = TIM_PRESCALER_2;	//TIM分频为2分频
  TIM_TimeBaseInitStruct.TIM_WorkMode = TIM_WorkMode_Timer;	//TIM工作在定时器模式，时钟源为APB0时钟
  /* TIM时基配置 */
  TIM_TIMBaseInit(TIM1, &TIM_TimeBaseInitStruct);
  TIM_DMACmd(TIM1, TIM_DMAReq_TI, ENABLE);
  TIM_Cmd(TIM1, ENABLE);

  /* DMA外设配置 */
  DMA_StructInit(&DMA_InitStruct);
  DMA_InitStruct.DMA_BufferSize = 4;	//DMA搬运数量为4个
  DMA_InitStruct.DMA_Burst = DMA_Burst_Disable;	//Brust模式关闭
  DMA_InitStruct.DMA_CircularMode = DMA_CircularMode_Enable;	//开启循环模式
  DMA_InitStruct.DMA_DataSize = DMA_DataSize_Byte;	//传输宽度为字节
  DMA_InitStruct.DMA_SourceMode = DMA_SourceMode_INC_CIRC;	//源地址循环递增
  DMA_InitStruct.DMA_TargetMode = DMA_TargetMode_INC;	//目标地址递增
  DMA_InitStruct.DMA_SrcAddress = (uint32_t)0x00;	//不需要设置，通过DMA1自动传输
  DMA_InitStruct.DMA_DstAddress = (uint32_t)DMA_ScatterGather_GatherDst;	//设置目标地址
  DMA_InitStruct.DMA_Request = DMA_Request_TIM1_TI;	//TIM1触发DMA0
  DMA_InitStruct.DMA_Priority = DMA_Priority_HIGH;	//设置优先级为高
  DMA_Init(DMA0, &DMA_InitStruct);
  DMA_DMACmd(DMA0, DMA_DMAReq_CHRQ, ENABLE);


  DMA_InitStruct.DMA_BufferSize = 3; 
  DMA_InitStruct.DMA_CircularMode = DMA_CircularMode_Disable;	//关闭循环模式
  DMA_InitStruct.DMA_Burst = DMA_Burst_Disable;	//Brust模式关闭
  DMA_InitStruct.DMA_DataSize = DMA_DataSize_Word;	//传输宽度为字
  DMA_InitStruct.DMA_TargetMode = DMA_TargetMode_FIXED;	//原地址循环递增
  DMA_InitStruct.DMA_SourceMode = DMA_SourceMode_INC_CIRC;	//目标地址不修改
  DMA_InitStruct.DMA_SrcAddress = (uint32_t)&DMA_ScatterGather_ScatterSrc[0];	//设置后续传输地址
  DMA_InitStruct.DMA_DstAddress = (uint32_t)&DMA0->DMA_SADR;
  DMA_InitStruct.DMA_Request = DMA_Request_DMA0;	//TIM1触发TIM0
  DMA_InitStruct.DMA_Priority = DMA_Priority_HIGH;	//设置优先级

  DMA_Init(DMA1, &DMA_InitStruct);

  DMA_Cmd(DMA1, ENABLE);
  DMA_SoftwareTrigger(DMA1);	//DMA0使能前，通过DMA1写入Data1个数组的地址
	
  DMA_Cmd(DMA0, ENABLE);

  while(1)
  {
    if(DMA_GetFlagStatus(DMA1, DMA_FLAG_TCIF) == SET)
    {
      DMA_DMACmd(DMA0, DMA_DMAReq_CHRQ, DISABLE);	//此时需要关闭DMA0的CHRQ，否则标志位不置起
      while(DMA_GetFlagStatus(DMA0, DMA_FLAG_TCIF) == RESET);
      DMA_Cmd(DMA0,DISABLE);        //DMA0失能
      DMA_Cmd(DMA1,DISABLE);        //DMA1失能
      DMA_ClearFlag(DMA0, DMA_FLAG_TCIF);
      printf("ScatterGather模式下搬运完成数据：%.12s。\r\n", DMA_ScatterGather_GatherDst);
    }
  }
}
