2014-03-04 03:10 AM
Hi,
I have the SPI communication working but do not receive the answer of the slave. I can see the answer on the scope but not in the controller. Can anybody help ?My main.c/* Includes ------------------------------------------------------------------*/&sharpinclude ''main.h''void spiInit(void);void spiInit(){ SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB ,ENABLE); RCC_APB2PeriphClockCmd (RCC_APB2Periph_SPI1, ENABLE); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; ///////////////////////////////////////////////////////////////////////////// // SPI1 Master initialization, SCK -> PA5, MOSI -> PA7 GPIO_StructInit (&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_0); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_0); // MISO -> PA6 GPIO_StructInit (&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_0); // CS or SS chip select -> PA4 GPIO_StructInit (&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOA, &GPIO_InitStructure); // SPI1 SPI_Init(SPI1, &SPI_InitStructure); SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF); SPI_Cmd(SPI1, ENABLE); }void ChipSelectLow(){ GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);}void ChipSelectHigh (){ GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);}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(){ uint8_t received_val = 0; spiInit(); ChipSelectHigh (); //********************************* ChipSelectLow (); SPI_SendData8(SPI1 , 0x01); SPI_SendData8(SPI1 , 0x10); 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 ChipSelectHigh (); //********************************* ChipSelectLow (); received_val = SPI1_send (0x81); ChipSelectHigh (); ChipSelectLow (); SPI_SendData8(SPI1 , received_val); // test um auf der SPI zu sehen, ob etwas angekommen ist 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 ChipSelectHigh (); while (1) { } } #stm32f051-spi2014-03-04 05:27 AM
If it behaves like other STM32 parts, it might help significantly if you check TXE before randomly jamming data into the SPI->DR (SendData)
2014-03-04 05:41 AM
Finally found it myself! :)
one thing is that MISO has to be configured GPIO_Mode_AF and not GPIO_Mode_IN:// MISO -> PA6 GPIO_StructInit (&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_0);the main now looks like:uint8_t Send( uint8_t data){ SPI_SendData8(SPI1, data); while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore return SPI_ReceiveData8(SPI1);}int main(){ uint8_t received_val[4]; spiInit(); //********************************* ChipSelectLow (); received_val[0]=Send(0x01); received_val[1]=Send(0x10); ChipSelectHigh (); //********************************* //********************************* ChipSelectLow (); received_val[2]=Send(0x81); received_val[3]=Send(0x00); ChipSelectHigh (); //********************************* ChipSelectLow (); SPI_SendData8(SPI1 , received_val[3]); // test um auf der SPI zu sehen, ob etwas angekommen ist while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore ChipSelectHigh (); while (1) { } }I hope it helps if anybody ist searching for a long time like me.I always read that somebody found the problem but never the code was published.2014-03-04 07:22 AM
The code originally posted look a lot like some other stuff that's been posted in recent days, no real idea where that came from.
Yes the Mode_IN is not what SPI pins are typically set too, most all STM32 parts other than the F1 have peripheral pins set to AF, and the direction controlled by the peripheral itself. At better source of SPI example code might be those in the library for the EVAL boards? STM32F0xx_StdPeriph_Lib_V1.0.0\Project\STM32F0xx_StdPeriph_Examples\SPI\SPI_TwoBoards