#ifdef __cplusplus
extern "C" {
#endif 

#include "spi.h"
#include "nvic.h"	 

#define GPIO_SPI1     GPIOA
#define RCC_SPI1      RCC_APB2Periph_GPIOA
#define SPI1_NSS      GPIO_Pin_4
#define SPI1_SCK      GPIO_Pin_5
#define SPI1_MISO     GPIO_Pin_6
#define SPI1_MOSI     GPIO_Pin_7

#define GPIO_SPI2     GPIOB
#define RCC_SPI2      RCC_APB2Periph_GPIOB
#define SPI2_NSS      GPIO_Pin_12
#define SPI2_SCK      GPIO_Pin_13
#define SPI2_MISO     GPIO_Pin_14
#define SPI2_MOSI     GPIO_Pin_15	 

void PB_SPI_Init(uint8_t SPI_Channel , unsigned char GPIO_AF)    //SPI interface initialization, input parameter SPI1 SPI2
{	 
    SPI_TypeDef *SPIx;
    SPI_InitTypeDef  SPI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;   	//initialize SPI structure
    
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // SPI设置为两线全双工
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                      // config SPI working on master mode
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                  // SPI发送接收为8位数据帧结构
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                         // 串行时钟在不操作时,时钟为低电平
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                       // 第一个时钟沿开始采集数据
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                          // NSS有软件(使用SSI为)管理
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; // SPI波特率预分频值为8
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                 // data start transmiss at MSB
    SPI_InitStructure.SPI_CRCPolynomial = 7;                           // CRC值计算的多项式
    
    if(SPI_Channel == 1){
        SPIx=SPI1;
    }
    else if(SPI_Channel == 2){
        SPIx=SPI2;
    }
    else if(SPI_Channel == 3){
        SPIx=SPI3;
    }
    else{
        return;
    }

    if(SPIx == SPI1)
    {
        RCC_APB2PeriphClockCmd(	RCC_APB2Periph_SPI1, ENABLE );
        if (GPIO_AF == 0 ){
            RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE );
            GPIO_InitStructure.GPIO_Pin = SPI1_MISO| SPI1_MOSI| SPI1_SCK;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //Multiplexing push-pull output
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_Init(GPIO_SPI1, &GPIO_InitStructure);
            GPIO_SetBits(GPIO_SPI1,SPI1_MISO| SPI1_MOSI| SPI1_SCK);
        }
        else if(GPIO_AF == 1){
            RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB, ENABLE );
            GPIO_PinRemapConfig(GPIO_Remap_SPI1 , ENABLE);		     //Pin Multiplexing to spi1
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //Multiplexing push-pull output
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_Init(GPIO_SPI1, &GPIO_InitStructure);
            GPIO_SetBits(GPIO_SPI1,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5);
        }
    }
    else if(SPIx == SPI2)
    {
        RCC_APB1PeriphClockCmd(	RCC_APB1Periph_SPI2, ENABLE );
        if (GPIO_AF == 0 ){
            RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE );
            GPIO_InitStructure.GPIO_Pin = SPI2_MISO| SPI2_MOSI| SPI2_SCK;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //Multiplexing push-pull output
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_Init(GPIO_SPI2, &GPIO_InitStructure);
            GPIO_SetBits(GPIO_SPI2,SPI2_MISO| SPI2_MOSI| SPI2_SCK);
        }
        else if(GPIO_AF == 1){
        }  
    }
    SPI_Init(SPIx, &SPI_InitStructure);
    SPI_Cmd(SPIx, ENABLE);
    PB_SPI_ReadWriteByte(SPI_Channel,0xff);                                           //start transmission
} 	 

uint8_t PB_SPI_ReadWriteByte(uint8_t SPI_Channel , uint8_t TxData)
{
    SPI_TypeDef *SPIx;

    if(SPI_Channel == 1){
        SPIx=SPI1;
    }
    else if(SPI_Channel == 2){
        SPIx=SPI2;
    }
    else if(SPI_Channel == 3){
        SPIx=SPI3;
    }
    else{
        return 0;
    }

    while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);     //flag of send cache is not reset
    SPI_I2S_SendData(SPIx, TxData);                                     //send data
    while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);    //flag of receivecache is not reset
    return SPI_I2S_ReceiveData(SPIx);                                   //receive data
}	

#ifdef __cplusplus
}
#endif