AnsweredAssumed Answered

Not able to read data from SPI2 Interface on STM32F4 board

Question asked by Jean Paul Talledo Vilela on Mar 3, 2018
Latest reply on Mar 3, 2018 by waclawek.jan

Hi

I would like to get suggestions and recommendations about this issue. I can see on Scope that my SPI Slave device ADS7959 (ADC) is talking back over SPI but when I debug my code and check the data read is always zero when it should be something different.

 

My code for setting up the SPI2 and Pins is the following:

 

    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_13 | GPIO_Pin_15);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStructure); //!< @pinSetup PB13: SPI2_SCK, PB15: SPI2_MOSI GPIO setup
    
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStructure); //!< @pinSetup PB14: SPI2_MISO GPIO setup
    
    // connect SPIx pins to SPI alternate function
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2); //!< @pinSetup PB15: SPI2_MOSI AF setup
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2); //!< @pinSetup PB14: SPI2_MISO AF setup
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2); //!< @pinSetup PB13: SPI2_SCK  AF setup

 

 

   RCC->APB1RSTR |=  RCC_APB1RSTR_SPI2RST;
   RCC->APB1RSTR &= ~RCC_APB1RSTR_SPI2RST;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
    
    SPI_InitTypeDef SPI_InitStruct;
    SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex mode, seperate MOSI and MISO lines
    SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has to be always high
    SPI_InitStruct.SPI_DataSize = SPI_DataSize_16b; // one packet of data is 8 bits wide
    SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        // clock is low when idle
    SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
    SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;// | SPI_NSSInternalSoft_Set; // set the NSS management to internal and pull internal NSS high
    SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; // see freq notes above
    SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
    SPI_InitStruct.SPI_CRCPolynomial = 0x07; // arbitrary (not using), just can't be <= 1 or fails init with ASSERT()
    SPI_Init(SPI2, &SPI_InitStruct);
        
        SPI2->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_CRCEN);
         
    // enable SPI peripheral
    SPI_Cmd(SPI2, ENABLE);

 

 

To write and read data to/from SPI:

 

uint16_t AuxAdc::writeWord(uint16_t word)
{
    ASSERT_AUXADC_CS;
    for( uint32_t i = 0; i<firstClockWait; i++ ){asm("nop");} // see timing notes in header
    SPI2->DR = word; // write data to be transmitted to the SPI data register
    
        
        uint32_t timeout = 0;
    while( !(SPI2->SR & SPI_I2S_FLAG_TXE) ) // wait until transmit complete
    {
        if( timeout++ > 50000 )
        {
            RELEASE_AUXADC_CS;
            return 0; //!< @TODO RG: need to report this
        }
    }
    timeout = 0;
    while( !(SPI2->SR & SPI_I2S_FLAG_RXNE) ) // wait until receive complete
    {
        if( timeout++ > 50000 )
        {
            RELEASE_AUXADC_CS;
            return 0; //!< @TODO RG: need to report this
        }
    }
    timeout = 0;
    while( SPI2->SR & SPI_I2S_FLAG_BSY ) // wait until SPI is not busy anymore
    {
        if( timeout++ > 50000 )
        {
            RELEASE_AUXADC_CS;
            return 0; //!< @TODO RG: need to report this
        }
    }
       
    for( uint32_t i = 0; i<lastClockWait; i++ ){asm("nop");} // see timing notes in header
    RELEASE_AUXADC_CS;
    for( uint32_t i = 0; i<postWait; i++ ){asm("nop");} // see timing notes in header
    return SPI2->DR; // return received data from SPI data register
} // end writeWord()

 

 

Not sure what exactly could be wrong, I already tried different board with same effect.

 

Using the debugger (IAR) and checking SPI->DR it never changes to a value even when I am writing to it. is this maybe showing a symptom of malfunction?

Outcomes