cancel
Showing results for 
Search instead for 
Did you mean: 

Problem configuring STM32F4 Discovery as SPI slave

flukeco
Associate II
Posted on July 04, 2014 at 11:25

Hi,

I'm currently trying to make SPI communication between PIC18F2580 as master and STM32F4 Discovery as slave.

The communication doesn't work, both master and slave receives 0xFF all the time.

I have it working in the opposite direction where I configure STM32F4 Discovery as master and PIC18F2580 as slave.

The working code is as follows:

STM32F4 Discovery SPI master code:

// 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_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_100MHz; 
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); 
// enable peripheral clock 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); 
/* configure SPI1 
* CPOL = 1 --> clock is high when idle 
* CPHA = 0 --> data is sampled at the second 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_High; 
// clock is high when idle 
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge; 
// data sampled at second 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, &SPI_InitStruct); 
SPI_Cmd(SPI1, ENABLE); 
// enable SPI1 
} 
/* This funtion is used to transmit and receive data 
* with SPI1 
* data --> data to be transmitted 
* returns received value 
*/
uint8_t SPI1_send(uint8_t data){ 
SPI1->DR = data; 
// write data to be transmitted to the SPI data register 
while
( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); 
// wait until transmit complete 
while
( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); 
// wait until receive complete 
while
( SPI1->SR & SPI_I2S_FLAG_BSY ); 
// wait until SPI is not busy anymore 
return
SPI1->DR; 
// return received data from SPI data register 
} 
int
main(
void
) { 
init_SPI1(); 
while
(1){ 
SPI1_send(0x00); 
// transmit data 
} 
} 

PIC18F2580 slave code:

/********************************************************************* 
* 
* Defines 
* 
*********************************************************************/
#define _MASTER_MODE 0 
#define _SLAVE_MODE 1 
#define _SMP 0 /* 0 = Input data sampled at middle of data output time (SMP must be cleared in slave mode) */ 
#define _CKE 0 /* 0 = Transmit occurs on transition from idle to active clock state */ 
#define _CKP 1 /* 1 = Idle state for clock is a high level */ 
#define _SSPM_MASTER 0b0000 /* 0000 = Master mode, clock = Fosc/4 */ 
#define _SSPM_SLAVE 0b0101 /* 0101 = Slave mode, clock = SCK pin, SS pin disabled (can be used as I/O pin) */ 
void
SPI_init(unsigned 
char
mode) { 
TRISA = 0x00; 
/* set all port A pins as output pins */
ADCON1 = 0x0F; 
/* set all port A pins, including SS (RA5), as digital I/O */
if
(mode == _MASTER_MODE) { 
TRISC = 0b00010000; 
/* Set SCK pin (RC3) as output 
* SDI pin (RC4) as input 
* SDO pin (RC5) as output */
} 
else
{ 
TRISC = 0b00011000; 
/* Set SCK pin (RC3) as input 
* SDI pin (RC4) as input 
* SDO pin (RC5) as output */
} 
SSPSTAT = 0b00000000; 
/* Initialize SSPSTAT register to POR state */
SSPSTATbits.SMP = _SMP; 
/* Configure sample bit */
SSPSTATbits.CKE = _CKE; 
/* Configure clock select bit */
SSPCON1 = 0b00000000; 
/* Initialize SSPCON1 register to POR state */
SSPCON1bits.CKP = _CKP; 
/* Configure clock polarity select bit */
SSPCON1bits.SSPEN = 1; 
/* Enable SPI (set SCK, SDO, SDI, and SS as serial port pins)*/
if
(mode == _MASTER_MODE) 
SSPCON1bits.SSPM = _SSPM_MASTER; 
/* Configure sync mode bits for master */
else
SSPCON1bits.SSPM = _SSPM_SLAVE; 
/* Configure sync mode bits for slave */
} 
unsigned 
char
SPI_send(unsigned 
char
data) { 
unsigned 
char
TempVar; 
TempVar = SSPBUF; 
/* Clears BF */
PIR1bits.SSPIF = 0; 
/* Clear interrupt flag */
SSPCON1bits.WCOL = 0; 
/* Clear any previous write collision */
SSPBUF = data; 
/* clock out data */
while
(!PIR1bits.SSPIF); 
/* wait until transmission completed */
PIR1bits.SSPIF = 0; 
/* clear interrupt flag bit */
return
(SSPBUF); 
} 
int
main(
void
) { 
SPI_init(_SLAVE_MODE); 
while
(1) { 
SPI_send(
'A'
); 
} 
return
(EXIT_SUCCESS); 
} 

The above code work fine. STM32F4 discovery (master) send 0x00 and receive 'A' while PIC18F2580 send 'A' and receive 0x00.

However, I need STM32F4 to be slave and PIC18F2580 to be master. I modify above code as follow:

Modify 1 line for STM32F4 Discovery code

..... 
SPI_InitStruct.SPI_Mode = SPI_Mode_Slave; 
// transmit in slave mode 
.....

And modify the call to SPI_init() function to be initialized as master

.... 
SPI_init(_MASTER_MODE); 
....

As I mention earlier, this doesn't work as both slave and master receive 0xFF.

I don't have access to oscilloscope or logic analyzer, so the best I can do is to set breakpoint as watch the values while debugging.

I doubt that this maybe because PIC18 run at slower CPU speed (40 Mhz) while STM32F4 runs at 168 Mhz.

But why does it work in one way (STM32 as master) and not another (PIC18 as master)? Or it is the code that cause the problem?

If you spot something wrong in the code or the concepts, please let me know.

Thank you in advance for your suggestions, any help will be highly appreciated.

Best Regards,

Pat
2 REPLIES 2
flukeco
Associate II
Posted on July 05, 2014 at 08:52

flukeco
Associate II
Posted on July 05, 2014 at 08:54