title: How to setup an interrupt driven SPI with stm32F4
body: <p>I'am using STM32F4 board with CMSIS library and I want setup an interrupt driven SPI, it means an interrupt is triggered each time a byte is sent by the SPI peripheral. The initiaisation function is as below:</p>
  
  <pre><code>void init_SPI1(void)
  {
    NVIC_InitTypeDef NVIC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStruct;
    SPI_InitTypeDef SPI_InitStruct; 
  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5|GPIO_Pin_4;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &amp;GPIO_InitStruct);
  
    // connect SPI1 pins to SPI alternate function
    //GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_SPI1);
  
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
  
    //Set chip select high 
    GPIOA-&gt;BSRRL |= GPIO_Pin_4; // set PE4 high
  
    // enable peripheral clock
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
  
    /* configure SPI1 in Mode 0 
     * CPOL = 0 --&gt; clock is low when idle
     * CPHA = 0 --&gt; data is sampled at the first edge
     */
    SPI_StructInit(&amp;SPI_InitStruct); // set default settings 
    SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex mode, seperate MOSI and MISO lines
    SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has to be always high
    SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide
    SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        // clock is low when idle
    SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
    SPI_InitStruct.SPI_NSS = SPI_NSS_Soft ; // set the NSS management to internal and pull internal NSS high
    SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // SPI frequency is APB2 frequency / 4
    SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
    SPI_Init(SPI1, &amp;SPI_InitStruct); 
  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&amp;NVIC_InitStructure);
  
    /* Enable SPI1*/
    SPI_Cmd(SPI1, ENABLE);
    return;
  }
  </code></pre>
  
  <p>Then i just loopback SPI_MOSI to SPI_MISO and use a function that transmit the data (a very basic function that takes data from a buffer and then uses CMSIS functions for the transmission). The problem is that when the SPI interrupt is triggered, the program won't get out from the handler. the handler function looks lihe this:</p>
  
  <pre><code>void SPI1_IRQHandler()
  {
   int a;
   a++;
   SPI_I2S_ClearITPendingBit(SPI1,SPI_I2S_IT_TXE);
   return;
  }
  </code></pre>
  
  <p>Is it a problem in the CMSIS library, or I am not configuring the SPI interrupt in the good way? Please guide me to the right point.</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>This is the function i use for data transmission </p>
  
  <pre><code>void write_SPI1()
  {
   int i;
  
     for (i=0;i&lt;SPI_TX_MAX; i++)
    {
     SPI_I2S_SendData(SPI1,spiTxBuff[i]);
     SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_RXNE,ENABLE);
    }
  }
  </code></pre>
  
  <p>and the interruption deals with the data reception, it just fill spiRxBuff when receiving new data.  </p>
  
  <pre><code>void SPI1_IRQHandler()
  {
   while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)== RESET);
  
    spiRxBuff[spiRxCount]= SPI_I2S_ReceiveData(SPI1);
    spiRxCount++;
  }
  </code></pre>
  
  <p>The variable used for Reception / Transmission are declared as below :</p>
  
  <pre><code>uint8_t spiTxBuff[SPI_TX_MAX] = {0x01,0x02,0x03,0x04,0x05,0x06};
  uint8_t spiRxBuff[SPI_RX_MAX];
  static volatile int spiRxCount= 0;  // used in SPI1_IRQHandler
  </code></pre>
  
  <p>what is strange now is that i'am having <code>{0x01,0x02,0x03,0x05,0x06}</code> in spiRxBuff instead of <code>{0x01,0x02,0x03,0x04,0x05,0x06}</code>, but using debug mode the data in spiRxBuff are correct, what goes wrong in your opinion ? </p>