#include "usartconfig.h"
#include "usart2.h"
#include "usart3.h"

/**********************************USART IO口初始化***************************************/
//从外设->存储器模式/8位数据宽度/存储器增量模式
//DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chx:DMA通道选择,@ref DMA_channel DMA_Channel_0~DMA_Channel_7
//PeripheralBaseAddr:外设地址
//Memory0BaseAddr:存储器地址
//BufferSize:数据传输量  
/*****************************************************************************************/
void MyLib_UsartConfig(USART_TypeDef* USARTx,uint32_t BaudRate,uint16_t WordLength,uint16_t StopBits,uint16_t Parity)
{

	USART_InitTypeDef 	USART_InitStructure;
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	if(USARTx == USART1)
	{
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); 
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);			//使能USART2时钟
			
		/***********************GPIO初始化***************************/
		//PA9  USART2_TX
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 				//	PA9		
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;			//普通输出模式
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		//推挽输出
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_USART2;//100MHz
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;				
		GPIO_Init(GPIOA, &GPIO_InitStructure);
		
		//PA10  USART2_RX
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 				//PA10							
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;			//输入模式
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		//推挽输出
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_USART2;//100MHz
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;				
		GPIO_Init(GPIOA, &GPIO_InitStructure);
		
		GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA2复用为USART2
		GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA3复用为USART2
	}

	if(USARTx == USART2)
	{
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); 
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);			//使能USART2时钟
			
		/***********************GPIO初始化***************************/
		//PA2  USART2_TX
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; 				//	PA2		
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;			//普通输出模式
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		//推挽输出
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_USART2;//100MHz
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;				
		GPIO_Init(GPIOA, &GPIO_InitStructure);
		
		//PA3  USART2_RX
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; 				//PA3							
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;			//输入模式
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		//推挽输出
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_USART2;//100MHz
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;				
		GPIO_Init(GPIOA, &GPIO_InitStructure);
		
		GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2); //GPIOA2复用为USART2
		GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2); //GPIOA3复用为USART2
	}
		
	if(USARTx == USART3)
	{
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); 
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);			//使能USART3时钟
			
		/***********************GPIO初始化***************************/
		//PB10  USART3_TX
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 				//	PB10		
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;			//普通输出模式
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		//推挽输出
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_USART3;//100MHz
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;				
		GPIO_Init(GPIOB, &GPIO_InitStructure);
		
		//PB11  USART3_RX
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; 				//PB11							
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;			//输入模式
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		//推挽输出
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_USART3;//100MHz
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;				
		GPIO_Init(GPIOB, &GPIO_InitStructure);
		
		GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_USART3); //GPIOB10复用为USART3
		GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_USART3); //GPIOB11复用为USART3
	}
	
	
	if(USARTx == UART4)
	{
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); 
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4,ENABLE);			//使能UART4时钟
			
		/***********************GPIO初始化***************************/
		//PA0  BLUETXD
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 				//	PA0		
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;			//普通输出模式
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		//推挽输出
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_USART3;//100MHz
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;				
		GPIO_Init(GPIOA, &GPIO_InitStructure);
		
		//PA1  BLUERXD
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; 				//PA1							
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;			//输入模式
		GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		//推挽输出
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_USART3;//100MHz
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;				
		GPIO_Init(GPIOA, &GPIO_InitStructure);
		
		GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_UART4); //GPIOA0复用为USRT3
		GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_UART4); //GPIOA1复用为UART3
	}
	
	/***********************USART初始化***************************/
	USART_InitStructure.USART_BaudRate = BaudRate; 
	USART_InitStructure.USART_WordLength = WordLength; 
	USART_InitStructure.USART_StopBits = StopBits;  
	USART_InitStructure.USART_Parity = Parity;    
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;           
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_Init(USARTx, &USART_InitStructure);
	
	USART_Cmd(USARTx, ENABLE);  //使能串口	
	USART_ClearFlag(USARTx, USART_FLAG_TC);
}

/**********************************DMAx---Rx的各通道配置***************************************/
//从外设->存储器模式/8位数据宽度/存储器增量模式
//DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chx:DMA通道选择,@ref DMA_channel DMA_Channel_0~DMA_Channel_7
//PeripheralBaseAddr:外设地址
//Memory0BaseAddr:存储器地址
//BufferSize:数据传输量  
/*****************************************************************************************/
void MyLib_UsartDMARx(USART_TypeDef* USARTx,DMA_Stream_TypeDef *DMA_Streamx,u32 Channel,u32 Memory0BaseAddr,u16 BufferSize,u32 DMA_Mode)
{
	
	DMA_InitTypeDef  DMA_InitStructure;
	
	if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
	{
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能 
		
	}
	else 
	{
	  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);//DMA1时钟使能 
	}
  DMA_DeInit(DMA_Streamx);
	
	while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}//等待DMA可配置 
		

  DMA_InitStructure.DMA_Channel = Channel;  //通道选择
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USARTx->DR;//DMA外设地址
  DMA_InitStructure.DMA_Memory0BaseAddr = Memory0BaseAddr;//DMA 存储器0地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//接收时从外设到存储器DMA_DIR_PeripheralToMemory					//发送时存储器到外设模式DMA_DIR_MemoryToPeripheral
  DMA_InitStructure.DMA_BufferSize = BufferSize;//数据传输量 
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据长度:8位
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器数据长度:8位
  DMA_InitStructure.DMA_Mode = DMA_Mode;// 使用普通模式 
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等优先级
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
  DMA_Init(DMA_Streamx, &DMA_InitStructure);//初始化DMA Stream
		
	USART_DMACmd(USARTx,USART_DMAReq_Rx,ENABLE);
		
	MYDMA_Enable(DMA_Streamx,BufferSize);
//	DMA_Cmd(DMA_Streamx,ENABLE); 
	
}

/**********************************DMAx---Tx的各通道配置***************************************/
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chx:DMA通道选择,@ref DMA_channel DMA_Channel_0~DMA_Channel_7
//PeripheralBaseAddr:外设地址
//Memory0BaseAddr:存储器地址
//BufferSize:数据传输量  
/*****************************************************************************************/
void MyLib_UsartDMATx(USART_TypeDef* USARTx,DMA_Stream_TypeDef *DMA_Streamx,u32 Channel,u32 Memory0BaseAddr,u16 BufferSize,u32 DMA_Mode)
{
	
	DMA_InitTypeDef  DMA_InitStructure;
	
	if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
	{
		RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能 
		
	}
	else 
	{
	  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);//DMA1时钟使能 
	}
  DMA_DeInit(DMA_Streamx);
	
	while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}//等待DMA可配置 
		

  DMA_InitStructure.DMA_Channel = Channel;  //通道选择
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USARTx->DR;//DMA外设地址
  DMA_InitStructure.DMA_Memory0BaseAddr = Memory0BaseAddr;//DMA 存储器0地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//接收时从外设到存储器DMA_DIR_PeripheralToMemory					//发送时存储器到外设模式DMA_DIR_MemoryToPeripheral
  DMA_InitStructure.DMA_BufferSize = BufferSize;//数据传输量 
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据长度:8位
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器数据长度:8位
  DMA_InitStructure.DMA_Mode = DMA_Mode;// 使用普通模式 
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等优先级
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
  DMA_Init(DMA_Streamx, &DMA_InitStructure);//初始化DMA Stream
		
	USART_DMACmd(USARTx,USART_DMAReq_Tx,ENABLE);
	MYDMA_Enable(DMA_Streamx,BufferSize);		
//	DMA_Cmd(DMA_Streamx,ENABLE);
		

		
}

//开启一次DMA传输
//DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7 
//BufferSize:数据传输量  
void MYDMA_Enable(DMA_Stream_TypeDef *DMA_Streamx,u16 BufferSize)
{
 
	DMA_Cmd(DMA_Streamx, DISABLE);                      //关闭DMA传输 
	
	while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}	//确保DMA可以被设置  
		
	DMA_SetCurrDataCounter(DMA_Streamx,BufferSize);          //数据传输量  
 
	DMA_Cmd(DMA_Streamx, ENABLE);                      //开启DMA传输 
}

void MYUSART_Init(void)
{

	/**************USART2初始化*******************/	
	MyLib_UsartConfig(USART2,115200,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No);
//	MyLib_UsartConfig(USART2,460800,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No);	
	MyLib_UsartDMARx(USART2,DMA1_Stream5,DMA_Channel_4,(u32)USART2_Buffer_Rx,256,DMA_Mode_Normal);
	
	/**************USART3初始化*******************/	
	MyLib_UsartConfig(USART3,115200,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No);
	MyLib_UsartDMARx(USART3,DMA1_Stream1,DMA_Channel_4,(u32)USART3_Buffer_Rx,256,DMA_Mode_Normal);
	
	/**************USART1初始化*******************/	
	MyLib_UsartConfig(USART1,115200,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No);
	MyLib_UsartDMARx(USART1,DMA2_Stream5,DMA_Channel_4,(u32)USART1_Buffer_Rx,256,DMA_Mode_Normal);
	
	/**************UART4初始化*******************/	
	MyLib_UsartConfig(UART4,115200,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No);
	MyLib_UsartDMARx(UART4,DMA1_Stream2,DMA_Channel_4,(u32)UART4_Buffer_Rx,256,DMA_Mode_Normal);
}



