What is SPI Interrupt (SPIE) in SPI control register?

I have been trying to understand SPI Interrupt i.e. what does it do and why is it used ? Reading about it on the web has not helped me. Can some one please explain it in a simple terms ?

I can’t seem to locate SPIE…just SPE… Would be nice i you reference the manual and which page you are referring to. :smiley:

The SPI interrupt, when enabled, will be triggered based on different selectable events such as transmit buffer empty or a fault (see table). There is a single global interrupt vector for each SPI device on the STM32F103 so when it is tripped, the code needs to looks an SPI register to determine the source.

The core firmware SPI code presently contains stubs for attaching an SPI interrupt and defining the interrupt handler. Perhaps @zachary can comment on whether this feature will be completed or not?

@Pravi,

The current SPI implementation is based on polling mode and so the below interrupt based code in spark_wiring_spi.cpp has not been implemented.

void SPIClass::attachInterrupt() {
  //To Do
}

void SPIClass::detachInterrupt() {
  //To Do
}

void Wiring_SPI1_Interrupt_Handler(void)
{
  //To Do
}

To change that to interrupt based and to give a general idea, we need to update the above as following:

void SPIClass::attachInterrupt() {
  // Configure and enable interrupts
  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 12;//refer platform_config.h
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  // Enable SPI1 TXE interrupt
  SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE);
  // Enable SPI1 RXNE interrupt
  SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
}

void SPIClass::detachInterrupt() {
  // Disable SPI1 TXE interrupt
  SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, DISABLE);
  // Disable SPI1 RXNE interrupt
  SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, DISABLE);
}

void Wiring_SPI1_Interrupt_Handler(void) {
  if (SPI_I2S_GetITStatus(SPI1, SPI_I2S_IT_TXE) != RESET)
  {
    //Send SPI1 data
    //SPI_I2S_SendData(SPI1, data);//just an idea here as how send needs to be done

    //clear interrupt bit
    SPI_I2S_ClearITPendingBit(SPI1, SPI_I2S_IT_TXE);
  }

  if (SPI_I2S_GetITStatus(SPI1, SPI_I2S_IT_RXNE) != RESET)
  {
    //Receive SPI1 data
    //data = SPI_I2S_ReceiveData(SPI1);//just an idea here as how receive needs to be done

    //clear interrupt bit
    SPI_I2S_ClearITPendingBit(SPI1, SPI_I2S_IT_RXNE);
  }
}

byte SPIClass::transfer(byte _data)
{
  //This needs to be updated as well
}

At the moment the current SPI function polls meaning when in use it checks after each transmission for any communications taking place on the wire. Because SPI is full duplex (It can send data simultaneously both directions) there’s no emendate need to implement the interrupt handler, although the STM32F10xx processor does support it.

Right now when you use SPI it polls the connection for activity, active high for a predetermined clock cycle. Using SPI right now you have full functionality and should be able to connect a number of slave devices, using the spark core as the master. At the current time, the interrupt handler would have to be implemented to set the Spark core as a slave due to it at times needing to take control of the bus, SPI wires, for communication thus setting flags to interrupt a communication and depending of priority and changing master slave relationships. I hope that helps you understand the SPI interrupt handler and why we haven’t taken the time to code it. Can I ask What you are using SPI for?

@Nicholas, @satishgn, We are trying to use Spark Core as a master to control a slave. We would like to send operation codes (opcodes) from the master to the slave via SPI interface.

While transferring data (more than one byte) through SPI, do we need to check if the first byte has been transferred fully before we start to transfer the second byte ? If yes, how do we do this ?
or does the controller automatically manage the data transfer without data collision ?

Hey @Pravi
The device sounds like it also needs to be configured to send back a busy signal for a length of time sadly Interrupts are not covered by the SPI standard; their usage is neither forbidden nor specified by the standard, and we are currently not working on implementing this feature on SPI.

Sounds like you want to wait some length of time to check the first byte’s received, at the current time I don’t know of anyway to do this without the slave being able to send data back and say byte received.

Its possible to slow the clock down on SPI using SPI.setClockDivider(divider) ;. another ways to break off the first byte and send it independently and then have the Salve device send it back and the Master check that it matches. If it matches send the remanning data, theres not any documentation for SPI that allows bit checking sadly as its not supported by the standard. Best of luck, and let me know how it works out.