cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 Discovery as SPI slave with interrupts

sreejuviswan
Associate
Posted on June 13, 2013 at 11:08

hi,

  I am working on  a project where I need to sample some data using the ADC in discovery at 1MSPs and transfer it to a raspberry pi board via SPI. As Rpi supports only SPI master mode the discovery board acts as a slave.However I am not able to get the discovery board work in slave mode. I am posting it a sample program I used to test spi in discovery board . 

&sharpinclude <stm32f4xx.h>

&sharpinclude <stm32f4xx_spi.h>

uint8_t SPI1_send(uint8_t data);

// this function initializes the SPI1 peripheral

void init_SPI1(void){

GPIO_InitTypeDef GPIO_InitStruct;

SPI_InitTypeDef SPI_InitStruct;

// enable clock for used IO pins

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

/* configure pins used by SPI1

* PA5 = SCK

* PA6 = MISO

* PA7 = MOSI

*/

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;

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(GPIOB, &GPIO_InitStruct);

// connect SPI1 pins to SPI alternate function

GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);

// enable clock for used IO pins

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

// enable peripheral clock

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

/* configure SPI1 in Mode 0 

* CPOL = 0 --> clock is low when idle

* CPHA = 0 --> data is sampled at the first edge

*/

SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex mode, seperate MOSI and MISO lines

SPI_InitStruct.SPI_Mode = SPI_Mode_Slave;

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 | SPI_NSSInternalSoft_Set; // set the NSS management to internal and pull internal NSS high

SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; // SPI frequency is APB2 frequency / 4

SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first

SPI_Init(SPI2, &SPI_InitStruct); 

SPI_Cmd(SPI2, ENABLE); // enable SPI1

}

/* This funtion is used to transmit and receive data 

 * with SPI1

 * data --> data to be transmitted

 * returns received value

 */

uint8_t SPI2_recv(){

uint8_t temp ;

   while( !(SPI2->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete

temp = SPI2->DR ; // write data to be transmitted to the SPI data register

while( !(SPI2->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete

while( SPI2->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore

return temp; // return received data from SPI data register

}

&sharpif 1

int main(void){

uint8_t received_val = 0;

init_SPI1();

while(1){

received_val = SPI2_recv(); // transmit dummy byte and receive data

}

}

&sharpendif

When I debug the code I see that  while( !(SPI2->SR & SPI_I2S_FLAG_RXNE) );  condition is never being met. Also how to I enable interrupts for the same?

#slave #discovery #stm32f4 #spi
2 REPLIES 2
frank
Associate II
Posted on August 03, 2013 at 16:14

This might be of some use to you - it is for the F0Discovery board but it should be easy to port:

http://eleceng.dit.ie/frank/arm/BareMetalSTM32F0Discovery/pi_spi/

gcntrk
Associate II
Posted on December 10, 2013 at 09:15

Hello, I am trying to solve a similar problem. I have problem with that while loop too and I will try to solve the problem with interrupts. Did you solve your problem and if so how did you use interrupts?