hi, all
I'm working on a SPI interface between to stm32f103.
I would like to enable DMA on both sides for high speed transition purpose.
And I want to use EXTI(I wonder if I can use the NSS pin) for synchronization on the master side.( the slave side will have SPI_I2S_IT_RXNE enable and the ISR will be triggered when PTX from master). Please correct me if I am wrong.
The followed is my code, one code base with different macro(WIFI_SPI_MASTER VS WIFI_SPI_SLAVE) defined.
Any input would be grateful. Many thanks.

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_spi.h"
#include "delay.h"
 
 
/* Private constants -----------------------------------------------------------*/
#define WIFI_SPI_MASTER // or #define WIFI_SPI_SLAVE
#define WIFI_SPI            SPI2
#define TIP_WIFI_SPI_GRP     GPIOB
#define TIP_WIFI_NSS_PIN     GPIO_Pin_10
#define TIP_WIFI_SCK_PIN     GPIO_Pin_13
#define TIP_WIFI_MISO_PIN    GPIO_Pin_14
#define TIP_WIFI_MOSI_PIN    GPIO_Pin_15
 
#define TIP_WIFI_IRQ_PORT_SRC   GPIO_PortSourceGPIOB
#define TIP_WIFI_IRQ_PIN_SRC    GPIO_PinSource10
#define TIP_WIFI_IRQ_EXTI_LINE  EXTI_Line10
#define TIP_WIFI_IRQ_EXTI_CHN   EXTI15_10_IRQn
 
 
#define BufferSize 128
 
#define SPI_DMA              DMA1
#define SPI_DMA_CLK          RCC_AHBPeriph_DMA1 
#define SPI_Rx_DMA_Channel   DMA1_Channel4
#define SPI_Rx_DMA_FLAG      DMA1_FLAG_TC4
#define SPI_Tx_DMA_Channel   DMA1_Channel5
#define SPI_Tx_DMA_FLAG      DMA1_FLAG_TC5 
 
/* Private typedef -------------------------------------------------------------*/
/* Private macro --------------------------------------------------------------*/
 
#ifdef WIFI_SPI_SLAVE
#define SLV2MST_CS  GPIO_SetBits(TIP_WIFI_SPI_GRP,TIP_WIFI_NSS_PIN)
#define SLV2MST_NCS GPIO_ResetBits(TIP_WIFI_SPI_GRP,TIP_WIFI_NSS_PIN)
#endif /* WIFI_SPI_SLAVE */
 
/* Private variable -------------------------------------------------------------*/
uint8_t usb_rx_count = 0;
uint8_t usb_rx_buf[BufferSize] = {0};
uint8_t usb_flag = 0;
uint8_t spi_rx_flag = 0;
uint8_t spi_rx_count = 0;
uint8_t spi_rx_buf[BufferSize] = {0};
uint8_t spi_tx_flag = 0;
uint8_t dma_tx_available = 1;
DMA_InitTypeDef DMA_InitStructure_Tx;
 
 
/* Private functions prototype ----------------------------------------------------*/
/* Private functions ------------------------------------------------------------*/
void RccInit(void)
{
    ErrorStatus HSEStartUpStatus;
    /* RCC system reset(for debug purpose) */
    RCC_DeInit();
 
    /* Enable HSE */
    RCC_HSEConfig(RCC_HSE_ON);
 
    /* Wait till HSE is ready */
    HSEStartUpStatus = RCC_WaitForHSEStartUp();
 
    if(HSEStartUpStatus == SUCCESS)
    {
        /* HCLK = SYSCLK */
        RCC_HCLKConfig(RCC_SYSCLK_Div1);
 
        /* PCLK2 = HCLK */
        RCC_PCLK2Config(RCC_HCLK_Div1);
 
        /* PCLK1 = HCLK/2 */
        RCC_PCLK1Config(RCC_HCLK_Div2);
 
        /* Flash 2 wait state */
        FLASH_SetLatency(FLASH_Latency_2);
        /* Enable Prefetch Buffer */
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
 
        /* PLLCLK = 8MHz * 9 = 72 MHz */
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
        /* Enable PLL */
        RCC_PLLCmd(ENABLE);
 
        /* Wait till PLL is ready */
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
        {
        }
 
        /* Select PLL as system clock source */
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
 
        /* Wait till PLL is used as system clock source */
        while(RCC_GetSYSCLKSource() != 0x08)
        {
        }
    }
 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
     
}
 
void GpioInit(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
 
    /* Enable GPIOA, GPIOB, GPIOC and AFIO clocks */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC , ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO  , ENABLE); 
     
    /*  SPI2 : SCK, MISO and MOSI */
#ifdef WIFI_SPI_MASTER 
    GPIO_InitStructure.GPIO_Pin = TIP_WIFI_SCK_PIN | TIP_WIFI_MOSI_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
    GPIO_Init(TIP_WIFI_SPI_GRP, &GPIO_InitStructure);
 
    GPIO_InitStructure.GPIO_Pin = TIP_WIFI_MISO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   
    GPIO_Init(TIP_WIFI_SPI_GRP, &GPIO_InitStructure);  
     
    //NSS   SPI_NSS_Soft
    GPIO_InitStructure.GPIO_Pin = TIP_WIFI_NSS_PIN;                             
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  
    GPIO_Init(TIP_WIFI_SPI_GRP, &GPIO_InitStructure);      
#else
    GPIO_InitStructure.GPIO_Pin = TIP_WIFI_SCK_PIN | TIP_WIFI_MOSI_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
    GPIO_Init(TIP_WIFI_SPI_GRP, &GPIO_InitStructure);
 
    GPIO_InitStructure.GPIO_Pin = TIP_WIFI_MISO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
    GPIO_Init(TIP_WIFI_SPI_GRP, &GPIO_InitStructure);  
 
    //NSS   SPI_NSS_Soft
    GPIO_InitStructure.GPIO_Pin = TIP_WIFI_NSS_PIN;                             
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(TIP_WIFI_SPI_GRP, &GPIO_InitStructure);  
    GPIO_ResetBits(TIP_WIFI_SPI_GRP,TIP_WIFI_NSS_PIN);
#endif
     
}
 
void DmaInit(void)
{
    DMA_InitTypeDef  DMA_InitStructure;
 
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    /* SPI_MASTER_Rx_DMA_Channel configuration ---------------------------------*/
    DMA_DeInit(SPI_Rx_DMA_Channel);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&WIFI_SPI->DR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)spi_rx_buf;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    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;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(SPI_Rx_DMA_Channel, &DMA_InitStructure);
         
    /* SPI_MASTER_Tx_DMA_Channel configuration ---------------------------------*/
    DMA_DeInit(SPI_Tx_DMA_Channel); 
    DMA_InitStructure_Tx.DMA_PeripheralBaseAddr = (uint32_t)(&WIFI_SPI->DR);
    DMA_InitStructure_Tx.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure_Tx.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure_Tx.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure_Tx.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure_Tx.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure_Tx.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure_Tx.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure_Tx.DMA_M2M = DMA_M2M_Disable;
}
 
void NvicInit(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
     
#ifdef WIFI_SPI_MASTER
    EXTI_InitTypeDef EXTI_InitStructure;
#endif /* WIFI_SPI_MASTER */
     
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
#ifdef WIFI_SPI_MASTER
 
    /* EXTI NVIC configuration*/   
    NVIC_InitStructure.NVIC_IRQChannel = TIP_WIFI_IRQ_EXTI_CHN;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);                                            
 
    GPIO_EXTILineConfig(TIP_WIFI_IRQ_PORT_SRC, TIP_WIFI_IRQ_PIN_SRC);
    EXTI_InitStructure.EXTI_Line = TIP_WIFI_IRQ_EXTI_LINE;                         
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;           //EXTI
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;      //failling edge triger
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;                               //enable exti
    EXTI_Init(&EXTI_InitStructure);
#endif /* WIFI_SPI_MASTER */
 
    /*SPI NVIC configuration*/
    NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
    /* DMA NVIC configuration*/
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
     
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
}
 
void TIPSpiDmaInit(void)
{
    SPI_InitTypeDef  SPI_InitStructure;
 
    RccInit();
    GpioInit();
    DmaInit();
    NvicInit();
     
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);    //APB1
 
    SPI_Cmd(WIFI_SPI, DISABLE); 
    /* SPI configuration */
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;    //Full-duplex
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                                             //master mode
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                                     //8bit
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                                                    //SCK idle low
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                                              //SCK sampling begin at first clock edge
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                                                     // software generate NSS
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;   //baudrate control SYSCLK/4
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;                                    //first bit is most segnificant bit
    SPI_InitStructure.SPI_CRCPolynomial = 7;                                              //CRC calculation value 7
    SPI_Init(WIFI_SPI, &SPI_InitStructure); 
 
#ifdef WIFI_SPI_SLAVE
    SPI_I2S_ITConfig(WIFI_SPI, SPI_I2S_IT_RXNE, ENABLE);
#endif
    SPI_Cmd(WIFI_SPI, ENABLE); 
     
}
 
 bool TIPSpiDmaSend(uint8_t* buf, uint8_t len)
{
    /* DMA1 Channel (triggered by USART_Tx event) Config */
 
    DMA_Cmd(SPI_Tx_DMA_Channel, DISABLE);
    SPI_I2S_DMACmd(WIFI_SPI, SPI_I2S_DMAReq_Tx, DISABLE);
    SPI_Cmd(WIFI_SPI, DISABLE);
     
    DMA_DeInit(SPI_Tx_DMA_Channel);  /*needs deInit before Init*/
    DMA_InitStructure_Tx.DMA_MemoryBaseAddr = (uint32_t)buf;
    DMA_InitStructure_Tx.DMA_BufferSize = len;
    DMA_Init(SPI_Tx_DMA_Channel, &DMA_InitStructure_Tx);
 
#ifdef WIFI_SPI_SLAVE
    SLV2MST_CS;
#endif /* WIFI_SPI_SLAVE */
 
    /* Enable DMA1 Channel_Tx */
    DMA_Cmd(SPI_Tx_DMA_Channel, ENABLE);
    SPI_I2S_DMACmd(WIFI_SPI,  SPI_I2S_DMAReq_Tx, ENABLE);
    DMA_ITConfig(SPI_Tx_DMA_Channel, DMA_IT_TC, ENABLE);
 
    /* Enable the WIFI_SPI */
    SPI_Cmd(WIFI_SPI, ENABLE); 
    dma_tx_available = 0;
    return TRUE;
}
   
 int main(void)
 {
    uint8_t count = 0;
    TIPUSBInit();
    TIPSpiDmaInit();
     
    for(;;)
    {
        if(usb_flag)
        {
            usb_flag = 0;
            TIPSpiDmaSend(usb_rx_buf,usb_rx_count);
        }
        if(spi_rx_flag)
        {
            delay_ms(100);
            USBSend(spi_rx_buf,BufferSize-DMA_GetCurrDataCounter(SPI_Rx_DMA_Channel));
        spi_rx_flag = 0;
        }
    }
 
 
  
 /*******************************************************************************
 * Function Name  : SPI2_IRQHandler
 * Description    : This function handles SPI2 global interrupt request.
 * Input          : None
 * Output         : None
 * Return         : None
 *******************************************************************************/
 void SPI2_IRQHandler(void)
 {
 
    if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET)
    {
        if(!spi_rx_flag)
        {
            spi_rx_flag = 1;
            SPI_I2S_DMACmd(WIFI_SPI,  SPI_I2S_DMAReq_Rx, ENABLE);
        }  
    }
 }
  
 void EXTI15_10_IRQHandler(void)
 {
     if(EXTI_GetITStatus(TIP_WIFI_IRQ_EXTI_LINE) != RESET)
     {
        if(GPIO_ReadInputDataBit(TIP_WIFI_SPI_GRP,TIP_WIFI_NSS_PIN)==Bit_SET) /*it is a raising edge, begin of transition*/
        {
            SPI_I2S_DMACmd(WIFI_SPI,  SPI_I2S_DMAReq_Rx, ENABLE);
            spi_rx_flag = 1;
        }
        else /*it is a falling edge, end of transition*/
        {
            SPI_I2S_DMACmd(WIFI_SPI,  SPI_I2S_DMAReq_Rx, DISABLE);
            spi_rx_flag = 0;
        }
        EXTI_ClearITPendingBit(TIP_WIFI_IRQ_EXTI_LINE);
     }
 }
 
void EXTI1_IRQHandler(void)
{
     if(EXTI_GetITStatus(TIP_WIFI_IRQ_EXTI_LINE) != RESET)
     {
        if(GPIO_ReadInputDataBit(TIP_WIFI_SPI_GRP,TIP_WIFI_NSS_PIN)==Bit_SET) /*it is a raising edge, begin of transition*/
        {
            spi_rx_flag = 1;
 
        }
        else /*it is a falling edge, end of transition*/
        {
            spi_rx_flag = 0;
        }
        EXTI_ClearITPendingBit(TIP_WIFI_IRQ_EXTI_LINE);
     }
 
}
 
  /*******************************************************************************
 * Function Name  : DMA1_Channel4_IRQHandler
 * Description    : This function handles DMA1 Channel 4 interrupt request.
 * Input          : None
 * Output         : None
 * Return         : None
 *******************************************************************************/
 void DMA1_Channel4_IRQHandler(void)
 {
     if(DMA_GetITStatus(DMA1_IT_TC4))
         DMA_ClearFlag(DMA1_FLAG_TC4);
 }
  
 /*******************************************************************************
 * Function Name  : DMA1_Channel5_IRQHandler
 * Description    : This function handles DMA1 Channel 5 interrupt request.
 * Input          : None
 * Output         : None
 * Return         : None
 *******************************************************************************/
 void DMA1_Channel5_IRQHandler(void)
 {
     if(DMA_GetITStatus(DMA1_IT_TC5))
         DMA_ClearFlag(DMA1_FLAG_TC5);
     dma_tx_available = 1;
#ifdef WIFI_SPI_SLAVE
    SLV2MST_NCS;
#endif /* WIFI_SPI_SLAVE */ 
 }