2015-11-03 03:34 PM
Hi guys, STM32 newbie here :)
I'm trying to get a simple project working with Nucleo STM32F302R8 board. I want to do full duplex SPI where the Nucleo is the master. Environment: I'm using theSTM32_Nucleo_FW_V1.2.1 package (withSTM32F30x_StdPeriph_Driver), I started by copying the IOToggle example. My IDE is Atollic 5.3.0 (free). The problem I get is that this line hangs: ''while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);'' If I comment that line out, then when viewed with a logic analyzer the MISO data looks random (often zero, but not always, does not correspond to what the other device should be sending). The CS, CLK, MOSI look ok. I tried SPI by bitbanging (using the same pins & everything else) and that works fine. The code:int
main()
{
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
// CLK | MOSI | MISO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_5);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_5);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_5);
// CS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_8);
SPI_InitTypeDef SPI_InitStruct;
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI2, &SPI_InitStruct);
SPI_Cmd(SPI2, ENABLE);
while
(1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_8);
while
(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
SPI_SendData8(SPI2, 0x11);
//while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
uint8_t result = SPI_ReceiveData8(SPI2);
GPIO_SetBits(GPIOB, GPIO_Pin_8);
Delay(10);
}
}
Clearly I'm missing something very basic about how SPI should be initialized... but what?
P.S. I'm not using CubeMX because Cube-generated projects don't build in Atollic (but that would be another question). The StdPeriph examples at least work out of the box. I don't *have* to use Atollic, or this particular board, or StdPeriph, I just need working SPI :) Any working SPI master example for F3/F4 would help me out a lot. Thanks!
#stm32f302 #nucleo #spi
2015-11-03 03:48 PM
Really not seeing anything objectionable there. Could you try turning OFF optimization?
The DSP/SPL release has more example code. STM32F30x_DSP_StdPeriph_Lib_V1.1.0\Utilities\STM32_EVAL\STM32303C_EVAL\stm32303c_eval_spi_ee.c2015-11-03 06:19 PM
Hi Clive,
Thanks! I found what was wrong with it, by looking at thestm32303c_eval_spi_ee.c just like you said. It was missing one call:...
SPI_Init(SPI2, &SPI_InitStruct);
SPI_RxFIFOThresholdConfig(SPI2, SPI_RxFIFOThreshold_QF);
// <- this was missing!
SPI_Cmd(SPI2, ENABLE);
...
I guess there is no default value for the RX threshold.
That's not the really weird thing though. Without that call, the MISO pin ends up apparently not floating, and not pulled up or down. It is ... something else? Sort of like an output pin with junk data. I've only been looking at a logic analyzer soI haven't had a chance to fully test it, I should really put a series resistor on it and record both sides with an oscilloscope. But it doesn't look anything like what it looks like when it's an input pin when bitbanging. I'm good now, just thought I should mention it in case someone else runs into this :)
Best,
-Alex