cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F1 (stm32vldiscovery) - Can't make SPI work

Bob jenkins
Associate II
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
1 REPLY 1
Imen.D
ST Employee
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

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen