AnsweredAssumed Answered

SPI can send but not receive? STM32F302R8

Question asked by Alex/I on Nov 4, 2015
Latest reply on Nov 4, 2015 by Alex/I
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 the STM32_Nucleo_FW_V1.2.1 package (with STM32F30x_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!

Outcomes