SPI Slave setup on STM32F4 board
interrupt, master-slave, spi, stm32f4discovery
Solution
You should change mode to `SPI_Mode_Slave` (by the way, `SPI_Mode_Master` implies `SPI_NSSInternalSoft_Set`), set `SPI_NSS` based on slave select method you are going to use:
- If you use `SPI_NSS_Hard`, configure appropriate pin as `AF/OD` with pull-up (if you haven't external pull-up resistor) and connect it to `AF` using `GPIO_PinAFConfig`.
- If you have only one slave, use `SPI_NSS_Soft`: it'll be automatically selected (if you won't set `SPI_NSSInternalSoft_Set`).
- If you use non-standard pin for slave select, configure `EXTI` to recieve interrupt on slave selection and reset internal `NSS` with `SPI_NSSInternalSoft_Reset` by software.
The last one is unrecommended, it's kind of kludge.
So, to get simple configuration use `NSS_Soft` (permanently selected). If you have more than 1 slave, use `NSS_Hard`.
Also you have to configure GPIO. `SCK` and `MOSI` should be `AF/PP` outputs on master and AF inputs on slave; `MISO` should be `AF` input on master and `AF/PP` output on slave; `NSS` should be `AF` input on slave.
Problem
I am trying to communicate between two STM32F4 discovery boards via SPI in Master & Slave configuration. I already have the code for the master but I am a bit confused on the changes I need to make on the SPI initialisation for the slave. I would also like to implement an interrupt whenever the master is sending data, rather than having the slave poll the RXNE register all the time. However, I am unsure of the exact configurations for the NVIC for the SPI. Below is the master's configuration code ``` void init_SPI1(void) { GPIO_InitTypeDef GPIO_InitStruct; SPI_InitTypeDef SPI_InitStruct; // enable clock for used IO pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /* configure pins used by SPI1 * PA5 = SCK * PA6 = MISO * PA7 = MOSI */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5; 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, &GPIO_InitStruct); // connect SPI1 pins to SPI alternate function GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); // enable clock for used IO pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); /* Configure the chip select pin in this case we will use PE7 */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOE, &GPIO_InitStruct); GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 high // enable peripheral clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, 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_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 | SPI_NSSInternalSoft_Set; // 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, &SPI_InitStruct); SPI_Cmd(SPI1, ENABLE); // enable SPI1 } ``` The reference manual states that I need the CPOL and CPHA bits to be configured the same as the master, this is also true for MSB/LSB first frame format. Apart from this I am unsure on how to configure the rest.