/********************************************************************************
 * @file    UART_Communication_DMA.c
 * @author  SOC AE Team
 * @version V1.1
 * @date    2025-06-27
 * @brief   UART1通过DMA1将接收的200个8位自定义数据放到缓冲数组后，再通过DMA0重新发送出去，波特率为115200。
 *					（数据个数必须与数组大小一致，否则数据将移位）
 *******************************************************************************/
#include "sc32_conf.h"
#include "Function_Init.h"

static volatile FlagStatus UART_RxFlag = RESET, UART_TxFlag = RESET;

void UART_Communication_DMA_Function(void)
{
    volatile uint16_t UART_RxData;
    UART_InitTypeDef UART_InitStruct; //定义UART初始化结构体变量
    DMA_InitTypeDef DMA_InitStruct; //定义DMA初始化结构体变量
    uint8_t UART_Communication_DMA_Data[200];//发送200个8位自定义数据（若要修改数据个数需修改相应数组大小和DMA搬运个数）

    /* 使能DMA时钟 */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);

    /* UART时钟使能 */
    /* UART0/1挂载在APB0时钟上 */
    RCC_APB0Cmd(ENABLE);//开启APB0时钟
    RCC_APB0PeriphClockCmd(RCC_APB0Periph_UART1,ENABLE);//开启UART1时钟

    DMA_StructInit(&DMA_InitStruct);

    DMA_InitStruct.DMA_BufferSize = 200;	//DMA搬运数量为200个
    DMA_InitStruct.DMA_CircularMode = DMA_CircularMode_Disable;	//关闭循环模式
    DMA_InitStruct.DMA_DataSize = DMA_DataSize_Byte;	//传输宽度为字节
    DMA_InitStruct.DMA_SourceMode = DMA_SourceMode_INC_CIRC;	//源地址循环递增
    DMA_InitStruct.DMA_TargetMode = DMA_TargetMode_FIXED;	//目标地址固定
    DMA_InitStruct.DMA_SrcAddress = (uint32_t)UART_Communication_DMA_Data;
    DMA_InitStruct.DMA_DstAddress = (uint32_t)&UART1->UART_DATA;
    DMA_InitStruct.DMA_Request = DMA_Request_UART1_TX;	//UART1发送触发DMA0
    DMA_InitStruct.DMA_Priority = DMA_Priority_HIGH;	//设置优先级为高
    DMA_Init(DMA0, &DMA_InitStruct);
    DMA_ITConfig(DMA0, DMA_IT_INTEN | DMA_IT_TCIE, ENABLE);
    NVIC_EnableIRQ(DMA0_IRQn);

    DMA_Cmd(DMA0, ENABLE);	//使能DMA0

    DMA_InitStruct.DMA_BufferSize = 200;	//DMA搬运数量为200个
    DMA_InitStruct.DMA_CircularMode = DMA_CircularMode_Enable;	//关闭循环模式
    DMA_InitStruct.DMA_DataSize = DMA_DataSize_Byte;	//传输宽度为字节
    DMA_InitStruct.DMA_SourceMode = DMA_SourceMode_FIXED;	//源地址循环递增
    DMA_InitStruct.DMA_TargetMode = DMA_TargetMode_INC_CIRC;	//目标地址固定
    DMA_InitStruct.DMA_SrcAddress = (uint32_t)&UART1->UART_DATA;
    DMA_InitStruct.DMA_DstAddress = (uint32_t)UART_Communication_DMA_Data;
    DMA_InitStruct.DMA_Request = DMA_Request_UART1_RX;	//UART1接受触发DMA1
    DMA_InitStruct.DMA_Priority = DMA_Priority_VERY_HIGH;	//设置优先级为高
    DMA_Init(DMA1, &DMA_InitStruct);
    DMA_ITConfig(DMA1, DMA_IT_INTEN | DMA_IT_TCIE, ENABLE);
    NVIC_EnableIRQ(DMA1_IRQn);

    DMA_Cmd(DMA1, ENABLE);	//使能DMA1

    UART_InitStruct.UART_BaudRate = 115200;	//串口波特率为115200
#if defined(SC32f10xx)||defined(SC32f12xx)
    UART_InitStruct.UART_ClockFrequency = 32000000;	//APB时钟频率配置为32MHz
#endif
    UART_InitStruct.UART_Mode = UART_Mode_10B;	//工作在模式1
    /*  根据结构体配置初始化串口 */
    UART_Init(UART1, &UART_InitStruct);

    UART_DMACmd(UART1, UART_DMAReq_TX | UART_DMAReq_RX, ENABLE);

    /* 使能接收发送口 */
    UART_TXCmd(UART1, ENABLE);
    UART_RXCmd(UART1, ENABLE);

  while(1)
  {
    if(UART_RxFlag == SET)//DMA1搬运完成
    {
      UART_RxFlag = RESET;//清标志
			
      /* DMA1重新使能 */
      DMA_SetCurrDataCounter(DMA0,200);//重新写入搬运个数
      UART_DMACmd(UART1, UART_DMAReq_TX, DISABLE);//重新使能UART1 TX触发DMA1
      UART_DMACmd(UART1, UART_DMAReq_TX, ENABLE);
			
	  /* 软件使能DMA0搬运 */
      DMA_SoftwareTrigger(DMA0);
      while(UART_TxFlag == RESET);//等待DMA0搬运完成
	  UART_TxFlag = RESET; //清标志
    }
  }
}

//DMA0中断
void UART_Communication_DMA_DAM0Handler(void)
{
  if(DMA_GetFlagStatus(DMA0, DMA_FLAG_TCIF))
  {
    DMA_ClearFlag(DMA0, DMA_FLAG_TCIF);
    UART_TxFlag = SET;
  }
}
//DMA1中断
void UART_Communication_DMA_DAM1Handler(void)
{
  if(DMA_GetFlagStatus(DMA1, DMA_FLAG_TCIF))
  {
    DMA_ClearFlag(DMA1, DMA_FLAG_TCIF);
    UART_RxFlag = SET;
  }
}
