cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F030 interface with SD card using SPI

rohittheozzy
Associate II
Posted on March 16, 2015 at 08:52

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****/

#sd-card #spi #sd-card-init
2 REPLIES 2
Posted on March 16, 2015 at 12:17

GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // I don't think so

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rohittheozzy
Associate II
Posted on March 16, 2015 at 14:03

Thank you Clive! It worked.