AnsweredAssumed Answered

STM32F030 interface with SD card using SPI

Question asked by potdar.rohit on Mar 16, 2015
Latest reply on Mar 16, 2015 by potdar.rohit
I am trying to implement this project using the demo files provided by ST "STM32Cube_FW_F0_V1.0.0\Middlewares\Third_Party\FatFs".
I have also written the necessory code for low level SPI driver. The commands and sent from STM32 to SD card but there is absolutely no reply from the SD card.
I have tried with few other SD cards as well but there is no reply from SD card over SO line. I have attached the SPI driver code below. Please help me with solving this issue.
Thank you.
/**
  ******************************************************************************
  * File Name          : SPI.c
  * Date               : 13/10/2014 19:30:51
  * Description        : This file provides code for the configuration
  *                      of the SPI instances.
  ******************************************************************************
  *
  * COPYRIGHT(c) 2014 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
 
/* Includes ------------------------------------------------------------------*/
#include "spi.h"
#include "../sdCard/thirdboard_sd.h"
#include "gpio.h"
 
/* USER CODE BEGIN 0 */
#define SD_CS_LOW()                     GPIOB->BSRRH = GPIO_PIN_12
 
#define SD_CS_HIGH()                    GPIOB->BSRRL = GPIO_PIN_12
/* USER CODE END 0 */
uint8_t SPI_RX_Buff[4];
uint8_t frame[9];
 
 
SPI_HandleTypeDef hspi2;
 
/* SPI2 init function */
void MX_SPI2_Init(void)
{
 
  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;//SPI_NSS_SOFT;//SPI_NSS_HARD_OUTPUT;
  //hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLED;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLED;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
  hspi2.Init.CRCPolynomial = 7;
  HAL_SPI_Init(&hspi2);
 
}
 
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
 
  GPIO_InitTypeDef GPIO_InitStruct;
  if(hspi->Instance==SPI2)
  {
    /* Peripheral clock enable */
    __GPIOB_CLK_ENABLE();
    __SPI2_CLK_ENABLE();
   
    /**SPI2 GPIO Configuration   
    PB12     ------> SPI2_NSS
    PB13     ------> SPI2_SCK
    PB14     ------> SPI2_MISO
    PB15     ------> SPI2_MOSI
    */
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    //GPIO_InitStruct.Alternate = GPIO_AF0_SPI2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
     
    GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_15;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF0_SPI2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
     
    GPIO_InitStruct.Pin = GPIO_PIN_14;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF0_SPI2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
     
     
    __SPI2_FORCE_RESET();
    __SPI2_RELEASE_RESET();
 
  }
}
 
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
{
 
  if(hspi->Instance==SPI2)
  {
    /* Peripheral clock disable */
    __SPI2_CLK_DISABLE();
   
    /**SPI2 GPIO Configuration   
    PB13     ------> SPI2_SCK
    PB14     ------> SPI2_MISO
    PB15     ------> SPI2_MOSI
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15);
 
  }
}
 
 
void SD_IO_Init(void)
    //GPIO_InitTypeDef  GPIO_InitStruct;
    uint8_t counter;
 
    MX_SPI2_Init();
     
    /* SD_CS_GPIO Periph clock enable */
    //SD_CS_GPIO_CLK_ENABLE();
 
//  /* Configure SD_CS_PIN pin: SD Card CS pin */
//  GPIO_InitStruct.Pin = SD_CS_PIN;
//  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//  GPIO_InitStruct.Pull = GPIO_PULLUP;
//  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
//  HAL_GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStruct);
 
    /*------------Put SD in SPI mode--------------*/
    /* SD SPI Config */
    //SPIx_Init();
 
    /* SD chip select high */
    SD_CS_HIGH();
 
    /* Send dummy byte 0xFF, 10 times with CS high */
    /* Rise CS and MOSI for 80 clocks cycles */
    for (counter = 0; counter <= 9; counter++)
    {
        /* Send dummy byte 0xFF */
        //frame[counter] = SD_DUMMY_BYTE;
        SD_IO_WriteByte(SD_DUMMY_BYTE);
    }
    //HAL_SPI_Transmit(&hspi2, frame, 9, 0xFFFF);
}
 
static void HAL_SPI_Error (void)
{
  /* De-initialize the SPI communication BUS */
  HAL_SPI_MspDeInit(&hspi2);
   
  /* Re- Initiaize the SPI communication BUS */
  MX_SPI2_Init();
}
 
uint8_t SD_IO_ReadByte(void)
{
  //uint8_t data = 0xFF;
   
  /* Get the received data */
//  //data = SPIx_Read();
//  hspi2.Instance->DR = data;
//  while((hspi2.Instance->SR & SPI_FLAG_RXNE) != RESET);
//  data = hspi2.Instance->DR;
//  hspi2.State= HAL_SPI_STATE_READY;
   
//  HAL_SPI_Receive(&hspi2, SPI_RX_Buff, 1, 0xFFFF);
//  /* Return the shifted data */
//  return SPI_RX_Buff[0];
   
  HAL_StatusTypeDef status = HAL_OK;
  uint32_t readvalue = 0x0;
  uint32_t writevalue = 0xFFFFFFFF;
   
  status = HAL_SPI_TransmitReceive(&hspi2, (uint8_t*) &writevalue, (uint8_t*) &readvalue, 1, 1000);
 
  /* Check the communication status */
  if(status != HAL_OK)
  {
    /* Execute user timeout callback */
    HAL_SPI_Error();
  }
 
  return readvalue;
}
 
void SD_IO_WriteByte(uint8_t Value)
{
  /* Send the byte */
  //SPIx_Write(Data);
//  hspi2.Instance->DR = Data;
//  while((hspi2.Instance->SR & SPI_FLAG_TXE) != RESET);
//  hspi2.State= HAL_SPI_STATE_READY;
  //SPI_WaitFlagStateUntilTimeout(&hspi2,SPI_FLAG_TXE,SPI_FLAG_TXE,0xFFFF);
  //HAL_SPI_Transmit(&hspi2, &Data, 1, 0xFFFF);
   
  HAL_StatusTypeDef status = HAL_OK;
 
  status = HAL_SPI_Transmit(&hspi2, (uint8_t*) &Value, 1, 1000);
 
  /* Check the communication status */
  if(status != HAL_OK)
  {
    /* Execute user timeout callback */
    HAL_SPI_Error();
  }
}
 
HAL_StatusTypeDef SD_IO_WaitResponse(uint8_t Response)
{
    uint32_t timeout = 0xFFF;
 
    /* Check if response is got or a timeout is happen */
    while ((SD_IO_ReadByte() != Response) && timeout)
    {
        timeout--;
    }
 
    if (timeout == 0)
    {
        /* After time out */
        return HAL_TIMEOUT;
    }
    else
    {
        /* Right response got */
        return HAL_OK;
    }
}
 
HAL_StatusTypeDef SD_IO_WriteCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Response)
{
    uint32_t counter = 0x00;
     
 
    /* Prepare Frame to send */
    frame[0] = (Cmd | 0x40);         /* Construct byte 1 */
    frame[1] = (uint8_t)(Arg >> 24); /* Construct byte 2 */
    frame[2] = (uint8_t)(Arg >> 16); /* Construct byte 3 */
    frame[3] = (uint8_t)(Arg >> 8);  /* Construct byte 4 */
    frame[4] = (uint8_t)(Arg);       /* Construct byte 5 */
    frame[5] = (Crc);                /* Construct byte 6 */
 
    /* SD chip select low */
    SD_CS_LOW();
 
    /* Send Frame */
    for (counter = 0; counter < 6; counter++)
    {
        SD_IO_WriteByte(frame[counter]); /* Send the Cmd bytes */
    }
     
//  HAL_SPI_Transmit(&hspi2, frame, 6, 0xFFFF);
 
    if(Response != SD_NO_RESPONSE_EXPECTED)
    {
        return SD_IO_WaitResponse(Response);
    }
 
    return HAL_OK;
}
 
void SD_IO_WriteDummy(void)
{
    /* SD chip select high */
    SD_CS_HIGH();
 
    /* Send the byte */
    SD_IO_WriteByte(SD_DUMMY_BYTE);
}
    
 
/**
  * @}
  */
 
/**
  * @}
  */
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Outcomes