Skip to main content
Bob jenkins
Associate II
January 12, 2017
Question

STM32F1 (stm32vldiscovery) - Can't make SPI work

  • January 12, 2017
  • 1 reply
  • 707 views
Posted on January 12, 2017 at 15:27

Hello

I am trying to get SPI working on stm32vldiscovery.

In my project I am using STM32 Peripheral Library (SPL), not HAL.

For now I am trying to make SPI1 send data to SPI2, SPI2 echoes everything back to SPI1, and SPI1 sends the received data to USART1, so I can see the output in a serial terminal app.

I also have a logic analyzer connected to both USART1 and 4 SPI lines (ss, mosi, miso, clk).

What I see is USART always sending 0xff bytes (instead of the actual bytes I am sending to SPI), and there are one less byte than I actually send with SPI. USART sends other non-spi related bytes correctly.

SPI1 is configured as Master, SPI2 is configured as Slave.

What is wrong with the following code?

USART is set up and functioning correctly. I am getting 'Application started' when I launch the program. Something must be wrong with the SPI settings but I can't figure out what.

Thanks for your help!

//Initializing SPI1 as master

//SPI1 SS(PA4), SCK(PA5), MISO(PA6), MOSI(PA7)

&sharpdefine SPI1_SS GPIO_Pin_4

&sharpdefine SPI1_SCK GPIO_Pin_5

&sharpdefine SPI1_MISO GPIO_Pin_6

&sharpdefine SPI1_MOSI GPIO_Pin_7

//Clock

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

//GPIO (for SPI1)

GPIO_InitTypeDef spiGpioInitStruct;

spiGpioInitStruct.GPIO_Pin = SPI1_SCK | SPI1_MOSI | SPI1_SS;

spiGpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;

spiGpioInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOA, &spiGpioInitStruct);

spiGpioInitStruct.GPIO_Pin = SPI1_MISO;

spiGpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;

spiGpioInitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &spiGpioInitStruct);

//Initializing SPI itself

SPI_InitTypeDef spiInitStruct;

spiInitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

spiInitStruct.SPI_DataSize = SPI_DataSize_8b;

spiInitStruct.SPI_CPOL = SPI_CPOL_Low;

spiInitStruct.SPI_CPHA = SPI_CPHA_1Edge;

spiInitStruct.SPI_NSS = SPI_NSS_Hard;

spiInitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;

spiInitStruct.SPI_FirstBit = SPI_FirstBit_MSB;

spiInitStruct.SPI_Mode = SPI_Mode_Master;

SPI_Init(SPI1, &spiInitStruct);

SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);

SPI_Cmd(SPI1, ENABLE);

NVIC_EnableIRQ(SPI1_IRQn);

//Initializing SPI2 as slave

//SPI2 SS(PB12), SCK(PB13), MISO(PB14), MOSI(PB15)

&sharpdefine SPI2_SS GPIO_Pin_12

&sharpdefine SPI2_SCK GPIO_Pin_13

&sharpdefine SPI2_MISO GPIO_Pin_14

&sharpdefine SPI2_MOSI GPIO_Pin_15

//Clock

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

//GPIO (for SPI2)

GPIO_InitTypeDef spi2GpioInitStruct;

spi2GpioInitStruct.GPIO_Pin = SPI2_MISO | SPI2_SS;

spi2GpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;

spi2GpioInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOB, &spi2GpioInitStruct);

spi2GpioInitStruct.GPIO_Pin = SPI2_SCK | SPI2_MOSI;

spi2GpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;

spi2GpioInitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOB, &spi2GpioInitStruct);

//Initializing SPI itself

SPI_InitTypeDef spi2InitStruct;

spi2InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

spi2InitStruct.SPI_DataSize = SPI_DataSize_8b;

spi2InitStruct.SPI_CPOL = SPI_CPOL_Low;

spi2InitStruct.SPI_CPHA = SPI_CPHA_1Edge;

spi2InitStruct.SPI_NSS = SPI_NSS_Hard;

spi2InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;

spi2InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;

spi2InitStruct.SPI_Mode = SPI_Mode_Slave;

SPI_Init(SPI2, &spi2InitStruct);

SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);

SPI_Cmd(SPI2, ENABLE);

NVIC_EnableIRQ(SPI2_IRQn);

sendStringToUart('Application started\n');

char *buf = 'oh well this is it';

while(1) {

if(*buf) {

while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);

SPI_I2S_SendData(SPI1, (uint16_t)*buf);

buf++;

}

processUsartRxBuffer();

}

}

//Master SPI

void SPI1_IRQHandler() {

if(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == SET) { //this is RX not empty (i.e., byte received)

uint8_t receivedByte = SPI1->DR;

//... do something with the received byte

sendBufToUart(&receivedByte, 1); //lets send it to UART and print in terminal

//i++;

}

}

//Slave SPI

void SPI2_IRQHandler() {

if(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == SET) { //this is RX not empty (i.e., byte received)

uint8_t receivedByte = SPI_I2S_ReceiveData(SPI2);

//... do something with the received byte

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) != SET); //wait for previous transmission to be completed

SPI_I2S_SendData(SPI2, receivedByte); //just echo what slave has received from master

//SPI2->DR = receivedByte;

}

}

Thank you.

#spi #stm32f1 #stm32f1-spi
This topic has been closed for replies.

1 reply

ST Technical Moderator
January 13, 2017
Posted on January 13, 2017 at 09:36

Hello

jenkins.bob

‌,

I suggest you to have a look at the SPI example under the STM32F1 standard peripheral library that can help to build your project and have more idea about SPI configuration:

STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\SPI

You can refer to the manual

http://www.st.com/content/ccc/resource/technical/document/reference_manual/a2/2d/02/4b/78/57/41/a3/CD00246pdf/files/CD00246pdf/jcr:content/translations/en.CD00246pdf

, exactly in section 'Serial peripheral interface (SPI)' for more details/clarification. Also, check if you have the same condition as described in the

http://www.st.com/content/ccc/resource/technical/document/errata_sheet/a9/f2/ac/eb/22/6b/4f/70/CD00260pdf/files/CD00260pdf/jcr:content/translations/en.CD00260pdf

related to SPI limitation for your device.

Hope this helps you.

Thanks

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks