#include "SPI_DMA.h"

u8 RxCounterSpi1;
u8 TxCounterSpi1;
u8 RxCounterSpi2;
u8 TxCounterSpi2;

u8 SPI1_TX_Buff[BufferSize] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                               0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
                               0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
                               0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20
                              };
u8 SPI1_RX_Buff[BufferSize+4];
u8 SPI2_TX_Buff[BufferSize] = {0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
                               0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60,
                               0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
                               0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70
                              };
u8 SPI2_RX_Buff[BufferSize+4];

bool SPI1_data_come = false;
bool SPI2_data_come = false;

/******************************SPI1 配置************************************/
void SPI1_GPIO_Configuration ( void )
{
#if SPI1_DMA_SD_def
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef  SPI_InitStructure;

    //启动GPIO/AFIO
    SPI1_RCC_GPIO_CONFIG();
    //启动SPI1
    SPI1_RCC_CONFIG();

    /* Configure SPI1 pins: SCK, MISO and MOSI */
    GPIO_InitStructure.GPIO_Pin = SPI1_PIN_AF_CONFIG;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init ( SPI1_PORT_CONFIG, &GPIO_InitStructure );
    /* Configure I/O for EEPROM Chip select */
    GPIO_InitStructure.GPIO_Pin = SPI1_PIN_CS_CONFIG;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init ( SPI1_PORT_CONFIG, &GPIO_InitStructure );
    SPI_EEPROM_CS_HIGH();

	/* SPI1 configuration */ 
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI1设置为两线全双工
	SPI_InitStructure.SPI_Mode = SPI1_Mode_CONFIG;					   //设置SPI1为主模式
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;				   //SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; 					   //串行时钟在不操作时，时钟为1电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;					   //第2个时钟沿开始采样数据
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;						   //NSS信号由软件（使用SSI位）管理
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI1_Baud_CONFIG; //定义波特率预分频的值:波特率预分频值为8
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;				   //数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;						   //CRC值计算的多项式
	SPI_Init(SPI1_CONFIG, &SPI_InitStructure);

	/* SPI CRC */
	SPI_CalculateCRC(SPI1_CONFIG, ENABLE);

	//SPI中断
	//SPI_I2S_ITConfig ( SPI1_CONFIG, SPI_I2S_IT_RXNE, ENABLE );
	//SPI_I2S_ITConfig(SPI1_CONFIG, SPI_I2S_IT_IDLE,ENABLE);

	/* Enable SPI1 */
	SPI_Cmd(SPI1_CONFIG, ENABLE);

#endif
}


void SPI1_NVIC_Configuration ( void )
{
#if SPI1_DMA_SD_def
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 1 bit for pre-emption priority, 3 bits for subpriority */
    NVIC_PriorityGroupConfig ( SPI1_NVIC_Group );

    /* Configure and enable SPI1 interrupt -------------------------------------*/
    NVIC_InitStructure.NVIC_IRQChannel = SPI1_NVIC_Interrupt;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SPI1_NVIC_Pre;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = SPI1_NVIC_Sub;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init ( &NVIC_InitStructure );
#endif
}

/*******************************************************************************
* Function Name  : SPI1_DMA_Configuration
* Description    : 配置SPI1_RX的DMA通道2，SPI1_TX的DMA通道3
* Input          : None
* Output         : None
* Return         : None
* Attention             :
*******************************************************************************/
void DMA1_SPI1_Configuration ( void )
{
#if SPI1_DMA_SD_def
    DMA_InitTypeDef DMA_InitStructure;

    //启动DMA时钟
    RCC_AHBPeriphClockCmd ( DMA_SPI1_RCC_CONFIG, ENABLE );

    /* DMA1 Channel2 (triggered by SPI1 Rx event) Config */
    DMA_DeInit ( DMA_SPI1_Rx_CHANNLE_CONFIG );
    DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_SPI1_DR_Addr;                          //设置 SPI1 发送外设(0x4001300C) 地址(目的地址)
    DMA_InitStructure.DMA_MemoryBaseAddr = ( uint32_t ) DMA_SPI1_Rx_ADDR_CONFIG;                 //设置 SRAM 存储地址(目的地址)
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                                //传输方向 外设-内存
    DMA_InitStructure.DMA_BufferSize = BufferSize+1;                         //设置 SPI1 发送长度
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA_Mode_Normal
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init ( DMA_SPI1_Rx_CHANNLE_CONFIG, &DMA_InitStructure );

    /* DMA1 Channel3 (triggered by SPI1 Tx event) Config */
    DMA_DeInit ( DMA_SPI1_Tx_CHANNLE_CONFIG );
    DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_SPI1_DR_Addr;                          //设置  接收外设(0x4001300C) 地址(源地址)
    DMA_InitStructure.DMA_MemoryBaseAddr = ( uint32_t ) DMA_SPI1_Tx_ADDR_CONFIG;                 //设置 SRAM 存储地址(源地址)
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                                //传输方向 内存-外设
    DMA_InitStructure.DMA_BufferSize = BufferSize;                           //设置 SPI1 接收长度
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init ( DMA_SPI1_Tx_CHANNLE_CONFIG, &DMA_InitStructure );

	/* 中断标志*/
	DMA_ITConfig(DMA_SPI1_Rx_CHANNLE_CONFIG, DMA_IT_TC, ENABLE);
	DMA_ITConfig(DMA_SPI1_Rx_CHANNLE_CONFIG, DMA_IT_TE, ENABLE);
	DMA_ITConfig(DMA_SPI1_Tx_CHANNLE_CONFIG, DMA_IT_TC, ENABLE);
	DMA_ITConfig(DMA_SPI1_Tx_CHANNLE_CONFIG, DMA_IT_TE, ENABLE);

	/* Enable SPI1 DMA Tx/Rx request */
	SPI_I2S_DMACmd(SPI1_CONFIG, SPI_I2S_DMAReq_Tx, ENABLE);
	SPI_I2S_DMACmd(SPI1_CONFIG, SPI_I2S_DMAReq_Rx, ENABLE);

	/* Enable channe2 and channel3 */
	DMA_Cmd(DMA_SPI1_Rx_CHANNLE_CONFIG, ENABLE);	//开接收
	DMA_Cmd(DMA_SPI1_Tx_CHANNLE_CONFIG, DISABLE);	//关发送

#endif
}

void DMA1_SPI1_NVIC_Configuration ( void )
{
#if SPI1_DMA_SD_def
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 1 bit for pre-emption priority, 3 bits for subpriority */
    NVIC_PriorityGroupConfig ( DMA_SPI1_NVIC_Group );

    /* Configure and enable DMA1 interrupt -------------------------------------*/
    NVIC_InitStructure.NVIC_IRQChannel = DMA_SPI1_NVIC_Rx_Interrupt;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SPI1_NVIC_Rx_Pre;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_SPI1_NVIC_Rx_Sub;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init ( &NVIC_InitStructure );

	/* Configure and enable DMA1 interrupt -------------------------------------*/
	 NVIC_InitStructure.NVIC_IRQChannel = DMA_SPI1_NVIC_Tx_Interrupt;
	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SPI1_NVIC_Tx_Pre;
	 NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_SPI1_NVIC_Tx_Sub;
	 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	 NVIC_Init ( &NVIC_InitStructure );
	
#endif
}

//SPIx 读写一个字节
//返回值:读取到的字节
u8 SPIx_ReadWriteByte(u8 byte)
{		
  /* Loop while DR register in not emplty */
  while(SPI_I2S_GetFlagStatus(SPI1_CONFIG, SPI_I2S_FLAG_TXE) == RESET);

  /* Send byte through the SPI2 peripheral */
  SPI_I2S_SendData(SPI1_CONFIG, byte);

  /* Wait to receive a byte */
  while(SPI_I2S_GetFlagStatus(SPI1_CONFIG, SPI_I2S_FLAG_RXNE) == RESET);

  /* Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI1_CONFIG);				    
}

/*******************************************************************************
* Function Name  : SPI1_Send
* Description    : SPI1的DMA方式发送
* Input          : SPI1_TX_Buff[SPI1_SendBufferSize]
* Output         : None
* Return         : None
* Attention             : 关闭DMA通道3之前必须等待TXE为1，等待忙标志为0
*******************************************************************************/
void SPI1_Send ( u8 *buff, u32 len )
{
    DMA_SPI1_Tx_CHANNLE_CONFIG->CPAR = DMA_SPI1_DR_Addr; //外设地址
    DMA_SPI1_Tx_CHANNLE_CONFIG->CMAR = ( u32 ) buff; //mem地址
    DMA_SPI1_Tx_CHANNLE_CONFIG->CNDTR = len ; //传输长度
    DMA_SPI1_Tx_CHANNLE_CONFIG->CCR = ( 0 << 14 ) | // 非存储器到存储器模式
                         ( 2 << 12 ) | // 通道优先级高
                         ( 0 << 11 ) | // 存储器数据宽度8bit
                         ( 0 << 10 ) | // 存储器数据宽度8bit
                         ( 0 <<  9 ) | // 外设数据宽度8bit
                         ( 0 <<  8 ) | // 外设数据宽度8bit
                         ( 1 <<  7 ) | // 存储器地址增量模式
                         ( 0 <<  6 ) | // 外设地址增量模式(不增)
                         ( 0 <<  5 ) | // 非循环模式
                         ( 1 <<  4 ) | // 从存储器读
                         ( 1 <<  3 ) | // 允许传输错误中断
                         ( 0 <<  2 ) | // 允许半传输中断
                         ( 1 <<  1 ) | // 允许传输完成中断
                         ( 1 );      // 通道开启
}

/*******************************************************************************
* Function Name  : SPI1_Recive
* Description    : SPI1的DMA方式接收
* Input          : None
* Output         : SPI1_RX_Buff[SPI1_ReciveBufferSize]
* Return         : None
* Attention             : 必须要先关闭通道2,然后再配置通道2的参数
*******************************************************************************/
void SPI1_Recive ( u8 *buff, u32 len )
{
    DMA_SPI1_Rx_CHANNLE_CONFIG->CCR &= ~ ( 1 << 0 );         //关闭DMA通道2

    DMA_SPI1_Rx_CHANNLE_CONFIG->CPAR = DMA_SPI1_DR_Addr; //外设地址
    DMA_SPI1_Rx_CHANNLE_CONFIG->CMAR = ( uint32_t ) buff; //mem地址
    DMA_SPI1_Rx_CHANNLE_CONFIG->CNDTR = len ; //传输长度
    DMA_SPI1_Rx_CHANNLE_CONFIG->CCR = ( 0 << 14 ) | // 非存储器到存储器模式
                         ( 2 << 12 ) | // 通道优先级高
                         ( 0 << 11 ) | // 存储器数据宽度8bit
                         ( 0 << 10 ) | // 存储器数据宽度8bit
                         ( 0 <<  9 ) | // 外设数据宽度8bit
                         ( 0 <<  8 ) | // 外设数据宽度8bit
                         ( 1 <<  7 ) | // 存储器地址增量模式
                         ( 0 <<  6 ) | // 外设地址增量模式(不增)
                         ( 0 <<  5 ) | // 非循环模式
                         ( 0 <<  4 ) | // 传输方向 外设-内存
                         ( 0 <<  3 ) | // 允许传输错误中断
                         ( 0 <<  2 ) | // 允许半传输中断
                         ( 1 <<  1 ) | // 允许传输完成中断
                         ( 1 );      // 通道开启
}


/******************************SPI2 配置************************************/
void SPI2_GPIO_Configuration ( void )
{
#if SPI2_DMA_SD_def
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef  SPI_InitStructure;

    //启动GPIO/AFIO
    SPI2_RCC_GPIO_CONFIG();
    //启动SPI2
    SPI2_RCC_CONFIG();

    /* Configure SPI1 pins: SCK, MISO and MOSI */
    GPIO_InitStructure.GPIO_Pin = SPI2_PIN_AF_CONFIG;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init ( SPI2_PORT_CONFIG, &GPIO_InitStructure );
#if 1	//副的接收cs	
    /* Configure I/O for EEPROM Chip select */
    GPIO_InitStructure.GPIO_Pin = SPI2_PIN_CS_CONFIG;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init ( SPI2_PORT_CONFIG, &GPIO_InitStructure );
    //SPI_EEPROM_CS_HIGH();
#endif

	/* SPI2 configuration */ 
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI1设置为两线全双工
	SPI_InitStructure.SPI_Mode = SPI2_Mode_CONFIG;					   //设置SPI1为主模式
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;				   //SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; 					   //串行时钟在不操作时，时钟为1电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;					   //第2个时钟沿开始采样数据
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;						   //NSS信号由软件（使用SSI位）管理
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI2_Baud_CONFIG; //定义波特率预分频的值:波特率预分频值为8
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;				   //数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;						   //CRC值计算的多项式
	SPI_Init(SPI2_CONFIG, &SPI_InitStructure);

	/* SPI CRC */
	SPI_CalculateCRC(SPI2_CONFIG, ENABLE);

	//SPI中断
	//SPI_I2S_ITConfig ( SPI2_CONFIG, SPI_I2S_IT_RXNE, ENABLE );
//	SPI_I2S_ITConfig(SPI1_CONFIG, SPI_I2S_IT_IDLE,ENABLE);

	/* Enable SPI1 */
	SPI_Cmd(SPI2_CONFIG, ENABLE);

#endif
}


void SPI2_NVIC_Configuration ( void )
{
#if SPI1_DMA_SD_def
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 1 bit for pre-emption priority, 3 bits for subpriority */
    NVIC_PriorityGroupConfig ( SPI2_NVIC_Group );

    /* Configure and enable SPI1 interrupt -------------------------------------*/
    NVIC_InitStructure.NVIC_IRQChannel = SPI2_NVIC_Interrupt;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SPI2_NVIC_Pre;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = SPI2_NVIC_Sub;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init ( &NVIC_InitStructure );
#endif
}

/*******************************************************************************
* Function Name  : SPI1_DMA_Configuration
* Description    : 配置SPI1_RX的DMA通道2，SPI1_TX的DMA通道3
* Input          : None
* Output         : None
* Return         : None
* Attention             :
*******************************************************************************/
void DMA1_SPI2_Configuration ( void )
{
#if SPI2_DMA_SD_def
    DMA_InitTypeDef DMA_InitStructure;

    //启动DMA时钟
    RCC_AHBPeriphClockCmd ( DMA_SPI2_RCC_CONFIG, ENABLE );

    /* DMA1 Channel2 (triggered by SPI1 Rx event) Config */
    DMA_DeInit ( DMA_SPI2_Rx_CHANNLE_CONFIG );
    DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_SPI2_DR_Addr;                          //设置 SPI1 发送外设(0x4001300C) 地址(目的地址)
    DMA_InitStructure.DMA_MemoryBaseAddr = ( uint32_t ) DMA_SPI2_Rx_ADDR_CONFIG;                 //设置 SRAM 存储地址(目的地址)
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                                //传输方向 外设-内存
    DMA_InitStructure.DMA_BufferSize = BufferSize+1;                         //设置 SPI1 发送长度
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA_Mode_Normal
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init ( DMA_SPI2_Rx_CHANNLE_CONFIG, &DMA_InitStructure );

    /* DMA1 Channel3 (triggered by SPI1 Tx event) Config */
    DMA_DeInit ( DMA_SPI2_Tx_CHANNLE_CONFIG );
    DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_SPI2_DR_Addr;                          //设置  接收外设(0x4001300C) 地址(源地址)
    DMA_InitStructure.DMA_MemoryBaseAddr = ( uint32_t ) DMA_SPI2_Tx_ADDR_CONFIG;                 //设置 SRAM 存储地址(源地址)
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                                //传输方向 内存-外设
    DMA_InitStructure.DMA_BufferSize = BufferSize;                           //设置 SPI1 接收长度
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init ( DMA_SPI2_Tx_CHANNLE_CONFIG, &DMA_InitStructure );

	/* 中断标志*/
	DMA_ITConfig(DMA_SPI2_Rx_CHANNLE_CONFIG, DMA_IT_TC, ENABLE);
	DMA_ITConfig(DMA_SPI2_Rx_CHANNLE_CONFIG, DMA_IT_TE, ENABLE);
	DMA_ITConfig(DMA_SPI2_Tx_CHANNLE_CONFIG, DMA_IT_TC, ENABLE);
	DMA_ITConfig(DMA_SPI2_Tx_CHANNLE_CONFIG, DMA_IT_TE, ENABLE);

	/* Enable SPI1 DMA Tx/Rx request */
	SPI_I2S_DMACmd(SPI2_CONFIG, SPI_I2S_DMAReq_Tx, ENABLE);
	SPI_I2S_DMACmd(SPI2_CONFIG, SPI_I2S_DMAReq_Rx, ENABLE);

	/* Enable channe2 and channel3 */
	DMA_Cmd(DMA_SPI2_Rx_CHANNLE_CONFIG, ENABLE);	//开接收
	DMA_Cmd(DMA_SPI2_Tx_CHANNLE_CONFIG, DISABLE);	//关发送

#endif
}

void DMA1_SPI2_NVIC_Configuration ( void )
{
#if SPI2_DMA_SD_def
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 1 bit for pre-emption priority, 3 bits for subpriority */
    NVIC_PriorityGroupConfig ( DMA_SPI2_NVIC_Group );

    /* Configure and enable DMA1 interrupt -------------------------------------*/
    NVIC_InitStructure.NVIC_IRQChannel = DMA_SPI2_NVIC_Rx_Interrupt;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SPI2_NVIC_Rx_Pre;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_SPI2_NVIC_Rx_Sub;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init ( &NVIC_InitStructure );

	/* Configure and enable DMA1 interrupt -------------------------------------*/
	 NVIC_InitStructure.NVIC_IRQChannel = DMA_SPI2_NVIC_Tx_Interrupt;
	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SPI1_NVIC_Tx_Pre;
	 NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_SPI2_NVIC_Tx_Sub;
	 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	 NVIC_Init ( &NVIC_InitStructure );
	
#endif
}

//SPIx 读写一个字节
//返回值:读取到的字节
u8 SPI2_ReadWriteByte(u8 byte)
{		
  /* Loop while DR register in not emplty */
  while(SPI_I2S_GetFlagStatus(SPI2_CONFIG, SPI_I2S_FLAG_TXE) == RESET);

  /* Send byte through the SPI2 peripheral */
  SPI_I2S_SendData(SPI2_CONFIG, byte);

  /* Wait to receive a byte */
  while(SPI_I2S_GetFlagStatus(SPI2_CONFIG, SPI_I2S_FLAG_RXNE) == RESET);

  /* Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI2_CONFIG);				    
}

/*******************************************************************************
* Function Name  : SPI1_Send
* Description    : SPI1的DMA方式发送
* Input          : SPI1_TX_Buff[SPI1_SendBufferSize]
* Output         : None
* Return         : None
* Attention             : 关闭DMA通道3之前必须等待TXE为1，等待忙标志为0
*******************************************************************************/
void SPI2_Send ( u8 *buff, u32 len )
{
    DMA_SPI2_Tx_CHANNLE_CONFIG->CPAR = DMA_SPI2_DR_Addr; //外设地址
    DMA_SPI2_Tx_CHANNLE_CONFIG->CMAR = ( u32 ) buff; //mem地址
    DMA_SPI2_Tx_CHANNLE_CONFIG->CNDTR = len ; //传输长度
    DMA_SPI2_Tx_CHANNLE_CONFIG->CCR = ( 0 << 14 ) | // 非存储器到存储器模式
                         ( 2 << 12 ) | // 通道优先级高
                         ( 0 << 11 ) | // 存储器数据宽度8bit
                         ( 0 << 10 ) | // 存储器数据宽度8bit
                         ( 0 <<  9 ) | // 外设数据宽度8bit
                         ( 0 <<  8 ) | // 外设数据宽度8bit
                         ( 1 <<  7 ) | // 存储器地址增量模式
                         ( 0 <<  6 ) | // 外设地址增量模式(不增)
                         ( 0 <<  5 ) | // 非循环模式
                         ( 1 <<  4 ) | // 从存储器读
                         ( 1 <<  3 ) | // 允许传输错误中断
                         ( 0 <<  2 ) | // 允许半传输中断
                         ( 1 <<  1 ) | // 允许传输完成中断
                         ( 1 );      // 通道开启
}

/*******************************************************************************
* Function Name  : SPI1_Recive
* Description    : SPI1的DMA方式接收
* Input          : None
* Output         : SPI1_RX_Buff[SPI1_ReciveBufferSize]
* Return         : None
* Attention             : 必须要先关闭通道2,然后再配置通道2的参数
*******************************************************************************/
void SPI2_Recive ( u8 *buff, u32 len )
{
    DMA_SPI2_Rx_CHANNLE_CONFIG->CCR &= ~ ( 1 << 0 );         //关闭DMA通道2

    DMA_SPI2_Rx_CHANNLE_CONFIG->CPAR = DMA_SPI2_DR_Addr; //外设地址
    DMA_SPI2_Rx_CHANNLE_CONFIG->CMAR = ( uint32_t ) buff; //mem地址
    DMA_SPI2_Rx_CHANNLE_CONFIG->CNDTR = len ; //传输长度
    DMA_SPI2_Rx_CHANNLE_CONFIG->CCR = ( 0 << 14 ) | // 非存储器到存储器模式
                         ( 2 << 12 ) | // 通道优先级高
                         ( 0 << 11 ) | // 存储器数据宽度8bit
                         ( 0 << 10 ) | // 存储器数据宽度8bit
                         ( 0 <<  9 ) | // 外设数据宽度8bit
                         ( 0 <<  8 ) | // 外设数据宽度8bit
                         ( 1 <<  7 ) | // 存储器地址增量模式
                         ( 0 <<  6 ) | // 外设地址增量模式(不增)
                         ( 0 <<  5 ) | // 非循环模式
                         ( 0 <<  4 ) | // 传输方向 外设-内存
                         ( 0 <<  3 ) | // 允许传输错误中断
                         ( 0 <<  2 ) | // 允许半传输中断
                         ( 1 <<  1 ) | // 允许传输完成中断
                         ( 1 );      // 通道开启
}



