AnsweredAssumed Answered

HAL drivers SPI problem on STM32F4 Discovery

Question asked by Venec on Feb 16, 2016
Latest reply on Feb 18, 2016 by markt
I have run into a problem when trying to setup a SPI com between the STM32F4 Discovery and a CR95HF RFID. The MISO data looks correct in the scope, however the software reads the bit 0 as 0 always, giving me the wrong data. this is the code. 

This is my SPI and GPIO inits:


#define CR95HF_SPI                                               SPI1
#define CR95HF_SPI_ALT                                           GPIO_AF5_SPI1


#define CR95HF_SPI_SCK_PIN                                 GPIO_PIN_3                 
#define CR95HF_SPI_SCK_GPIO_PORT                            GPIOB
          
#define CR95HF_SPI_MISO_PIN                                 GPIO_PIN_4                 
#define CR95HF_SPI_MISO_GPIO_PORT                           GPIOB                 
          
#define CR95HF_SPI_MOSI_PIN                                 GPIO_PIN_5                 
#define CR95HF_SPI_MOSI_GPIO_PORT                           GPIOB   
          
#define CR95HF_SPI_NSS_PIN                                   GPIO_PIN_7                  
#define CR95HF_SPI_NSS_GPIO_PORT                           GPIOD


GPIO_InitTypeDef GPIO_InitStruct;
//SCK
GPIO_InitStruct.Pin = CR95HF_SPI_SCK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Alternate = CR95HF_SPI_ALT;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(CR95HF_SPI_SCK_GPIO_PORT, &GPIO_InitStruct); 
 
//MISO
GPIO_InitStruct.Pin = CR95HF_SPI_MISO_PIN ;
HAL_GPIO_Init(CR95HF_SPI_MISO_GPIO_PORT, &GPIO_InitStruct);
 
//MOSI
GPIO_InitStruct.Pin = CR95HF_SPI_MOSI_PIN;
HAL_GPIO_Init(CR95HF_SPI_MOSI_GPIO_PORT, &GPIO_InitStruct);
 
//SS A.K.A CS
HAL_GPIO_WritePin(CR95HF_SPI_NSS_GPIO_PORT, CR95HF_SPI_NSS_PIN, GPIO_PIN_SET); 
GPIO_InitStruct.Pin = CR95HF_SPI_NSS_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(CR95HF_SPI_NSS_GPIO_PORT, &GPIO_InitStruct);

    SPI_InitTypeDef  SPI_InitStructure;
     
    //Setup SPI
    hspi.Instance = CR95HF_SPI;
    hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
    hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
    hspi.Init.Direction = SPI_DIRECTION_2LINES;
    hspi.Init.Mode = SPI_MODE_MASTER;
    hspi.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi.Init.CLKPhase = SPI_PHASE_1EDGE;
    hspi.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi.Init.CRCPolynomial = 7;
    hspi.Init.TIMode =  SPI_TIMODE_DISABLE;
    hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi.Init.NSS = SPI_NSS_SOFT;
     
//#ifdef USE_DMA
    //SPI_I2S_DMACmd(CR95HF_SPI, SPI_I2S_DMAReq_Rx, ENABLE);
    //SPI_I2S_DMACmd(CR95HF_SPI, SPI_I2S_DMAReq_Tx, ENABLE);
//#endif   
 
    if (HAL_SPI_Init(&hspi) != HAL_OK)
    {
        return 1;
    }
     
 
    return 0;

This is the functions I use to receive data

CR89HF_SPI_NSS_set();  
    SPI_txByte(CR95HF_COMMAND_RECEIVE);
    pResponse[0] = SPI_rxByte(); // read response code
    pResponse[1] = SPI_rxByte(); // read data length
 
    for (i = 0; i < pResponse[1]; i++)
    {
         
        pResponse[i + 2] = SPI_rxByte();
         
    }
    CR89HF_SPI_NSS_reset();
void SPI_txByte(uint8_t data)
{  
    taskENTER_CRITICAL();
    switch (HAL_SPI_Transmit(&hspi, &data, 1, 100)) {
    case HAL_OK: 
        break;
    case HAL_BUSY:
        //debug("PANIC: SPI: busy state occured at %s, line %d .\n", __FILE__, __LINE__);
        while (1)
            ;
        break;
    case HAL_TIMEOUT:
        //debug("PANIC: SPI: transmit/receive timeout occured at %s, line %d .\n", __FILE__, __LINE__);
        while (1)
            ;
        break; 
    case HAL_ERROR:
        //debug("PANIC: SPI: transmit/receive error at %s, line %d.\n", __FILE__, __LINE__);
        while (1)
            ;
        break;
    default:
        //debug("PANIC: SPI: transmit/receive WUT HAPPEND at %s, line %d.\n", __FILE__, __LINE__);
        while (1)
            ;
        break;
    }
    taskEXIT_CRITICAL();
}
 
/**
 *  @brief  Receives one byte over SPI
 *  @retval None
 */
uint8_t SPI_rxByte()
{
    uint8_t recv_data;
 
    taskENTER_CRITICAL();
    switch (HAL_SPI_Receive(&hspi, &recv_data, 1, 100)) {
    case HAL_OK: 
        break;
    case HAL_BUSY:
        //debug("PANIC: SPI: busy state occured at %s, line %d .\n", __FILE__, __LINE__);
        while (1)
            ;
        break;
    case HAL_TIMEOUT:
        //debug("PANIC: SPI: transmit/receive timeout occured at %s, line %d .\n", __FILE__, __LINE__);
        while (1)
            ;
        break; 
    case HAL_ERROR:
        //debug("PANIC: SPI: transmit/receive error at %s, line %d.\n", __FILE__, __LINE__);
        while (1)
            ;
        break;
    default:
        //debug("PANIC: SPI: transmit/receive WUT HAPPEND at %s, line %d.\n", __FILE__, __LINE__);
        while (1)
            ;
        break;
    }
    taskEXIT_CRITICAL();
 
    return recv_data;
}
 
This is what I see on the Scope:

Scope

So, basically what I see on the scope looks fine, but the software instead of returning the MISO data, is reading the "garbage" bytes being sent to read data. I.e. I am expecting to read 4E 46 43 20 .... but what the software reads is 4F 46 42 20, bit 0 is always read as 0.

Can somebody guide me on how to solve this? something i might be doing wrong?

Thanks

Outcomes