cancel
Showing results for 
Search instead for 
Did you mean: 

SPI with two Boards

marcel2
Associate
Posted on August 12, 2015 at 12:21

Hello,

I've two STM32F4 Boards which I want to send data to each other via SPI. I think that I configured the master board (STM32F411 Nucleo board) well, because at the scope, I ''saw'' the sended data. My problem is the receiving of this data with the SPI slave (STM32F429 Discovery board). I want to receive the data at first in the main loop without an interrupt. My questions: is the CS-pin well declared and connected with SPI interface? What is the typical sequence to receive data, which flag should I check? (I read a lot of examples and every example uses another flag, is there an overview about this SPI flags?) This is my slave-code:

// SPI3 SCK
#define SPI3_SCK_PinSource GPIO_PinSource10
#define SPI3_SCK_Pin GPIO_Pin_10
#define SPI3_SCK_Bank GPIOC
// SPI3 MISO
#define SPI3_MISO_PinSource GPIO_PinSource11
#define SPI3_MISO_Pin GPIO_Pin_11
#define SPI3_MISO_Bank GPIOC
// SPI3 MOSI
#define SPI3_MOSI_PinSource GPIO_PinSource12
#define SPI3_MOSI_Pin GPIO_Pin_12
#define SPI3_MOSI_Bank GPIOC
// SPI3 CS
#define SPI3_CS_PinSource GPIO_PinSource15
#define SPI3_CS_Pin GPIO_Pin_15
#define SPI3_CS_Bank GPIOA

This is the SPI.c:


/*

**

** SPI3.c

**

**

**********************************************************************/

/*

Device: STM32F429 Discovery


**********************************************************************/

#include ''stm32f4xx_conf.h''

#include ''SPI3.h''

#include ''definitions.h''




void
SPI3_Slave_init()

{ 
/* Clocks für SPI3 enablen*/

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);

/* Definitionsstruct */

SPI_InitTypeDef SPI_InitTypeDefStruct;

// Baudraten Prescaler gibt Geschwindigkeit an

// 2 = schnellste

SPI_InitTypeDefStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;


// Richtung der Datenverbindung

SPI_InitTypeDefStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

//Master oder Slave

SPI_InitTypeDefStruct.SPI_Mode = SPI_Mode_Slave;

//Größe der Datenpakete - 8 oder 16 bit

SPI_InitTypeDefStruct.SPI_DataSize = SPI_DataSize_8b;

//ChipSelect durch Hardware oder Software

SPI_InitTypeDefStruct.SPI_NSS = SPI_NSS_Soft;

//Reihenfolge der Daten - Little Endian oder Big Endian (LSB oder MSB)

//Sollte bei beiden Endgeräten identisch sein

//Wikipedia: Byte-Reihenfolge

SPI_InitTypeDefStruct.SPI_FirstBit = SPI_FirstBit_MSB;

//Clock Polarity --> Muss bei beiden Endgeräten identisch sein

SPI_InitTypeDefStruct.SPI_CPOL = SPI_CPOL_Low;

//Definiert Flanke, ab wann Daten empfangen werden soll (1st oder 2nd Edge)

SPI_InitTypeDefStruct.SPI_CPHA = SPI_CPHA_2Edge;

//Wird im Beispiel nicht angewendet

//SPI_InitTypeDefStruct.SPI_CRCPolynomial = ;



//SPI initialisieren

SPI_Init(SPI3, &SPI_InitTypeDefStruct);


/* Clocks für GPIOs enablen*/

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE);

/* GPIO-Initialisierungsstruct*/

GPIO_InitTypeDef GPIO_InitStruct;


/*-------- Configuring SCK-MOSI-MISO --------*/

GPIO_InitStruct.GPIO_Pin = SPI3_SCK_Pin;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(SPI3_SCK_Bank, &GPIO_InitStruct);


GPIO_InitStruct.GPIO_Pin = SPI3_MISO_Pin | SPI3_MOSI_Pin;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(SPI3_MISO_Bank, &GPIO_InitStruct);



/*-------- Configuring ChipSelect-Pin --------*/

GPIO_InitStruct.GPIO_Pin = SPI3_CS_Pin;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;

GPIO_Init(SPI3_CS_Bank, &GPIO_InitStruct);




/*Funktion der PINs eindeutig definieren */

GPIO_PinAFConfig(SPI3_SCK_Bank, SPI3_SCK_PinSource, GPIO_AF_SPI3);

GPIO_PinAFConfig(SPI3_MISO_Bank, SPI3_MISO_PinSource, GPIO_AF_SPI3);

GPIO_PinAFConfig(SPI3_MOSI_Bank, SPI3_MOSI_PinSource, GPIO_AF_SPI3);





/* SPI enablen */

SPI_Cmd(SPI3, ENABLE);

SPI_NSSInternalSoftwareConfig(SPI3, SPI_NSSInternalSoft_Set);

}

And the main.c:


/*

**

** Main.c

**

**

**********************************************************************/

/*

Device: STM32F429 Discovery



**********************************************************************/

#include ''stm32f4xx_conf.h''

#include ''stm32f4xx_spi.h''

#include ''definitions.h''

#include ''SPI3.h''

#include ''stdbool.h''


uint8_t received_data;

GPIO_InitTypeDef GPIO_InitStruct;

uint8_t rxData;

bool
a=
false
;


int
main(
void
)

{

//System Initialization (Clock Setup and stuff like that)

SystemInit();


//initUserLED();


//Enable GPIO Clock

SPI3_Slave_init();


while
(1)

{


rxData=0x00;

if
(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == SET){

a=
true
;
// Application never reaches here!

rxData = SPI3->DR;

}

if
(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == SET){

if
(a){

SPI1->DR = 0xAB;

a=
false
; 

}

}


}

}

In the main.c, I never reach the part, where the bool a is set. What is the main routine to receive 1 byte, many bytes? The master is always sending 1 byte every cycle (tx=0xB5 // only test value) and on the scope I can see the 0xB5. Thanks for your help! #spitwoboards #spi-slave
1 REPLY 1
Amel NASRI
ST Employee
Posted on August 18, 2015 at 14:08

Hi kassner.marcel,

If you can migrate to the Cube, it will be easier for you to start with an example on the STM32CubeF4 package.

Ex: STM32Cube_FW_F4_V1.7.0\Projects\STM32F429I-Discovery\Examples\SPI\SPI_FullDuplex_ComPolling.

There are also examples in the standard peripheral library where the data transfer is made in DMA or IT mode (STM32F4xx_DSP_StdPeriph_Lib\Project\STM32F4xx_StdPeriph_Examples\SPI\SPI_TwoBoards).

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.