Add SDCARD SPI driver

This commit is contained in:
iabdalkader 2014-06-28 01:26:32 +02:00
parent 0191702058
commit 92563b6190
7 changed files with 606 additions and 19 deletions

View File

@ -145,6 +145,7 @@ OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/, \
sensor.o \
led.o \
rng.o \
sdcard.o \
stm32f407_hal_msp.o \
)

@ -1 +1 @@
Subproject commit 689b021b07127ab1ba37e95f5fb81a93a7d1058f
Subproject commit 29bd22ea4b03d5b09f5bc3fbccb7523fb6c767df

View File

@ -11,6 +11,7 @@ SRCS += $(addprefix , \
sensor.c \
led.c \
rng.c \
sdcard.c \
stm32f407_hal_msp.c \
)

View File

@ -42,7 +42,7 @@
int errno;
static FATFS fatfs0;
//static FATFS fatfs1;
static FATFS fatfs1;
void flash_error(int n) {
for (int i = 0; i < n; i++) {
@ -273,10 +273,6 @@ soft_reset:
usb_storage_medium_t usb_medium = USB_STORAGE_MEDIUM_FLASH;
#endif
#if MICROPY_HW_HAS_SDCARD
/* prepare workarea for sdcard fs */
//f_mount(&fatfs1, "1:", 0);
// if an SD card is present then mount it on 1:/
if (reset_mode == 1 && sdcard_is_present()) {
FRESULT res = f_mount(&fatfs1, "1:", 1);
@ -288,16 +284,10 @@ soft_reset:
if (first_soft_reset) {
// use SD card as medium for the USB MSD
#if defined(USE_DEVICE_MODE)
usb_medium = USB_STORAGE_MEDIUM_SDCARD;
#endif
}
}
}
#else
// Get rid of compiler warning if no SDCARD is configured.
(void)first_soft_reset;
#endif
// turn boot-up LEDs off
led_state(LED_RED, 0);

View File

@ -73,4 +73,25 @@ extern const gpio_t led_pins[];
#define DCMI_PWDN_LOW() HAL_GPIO_WritePin(DCMI_PWDN_PORT, DCMI_PWDN_PIN, GPIO_PIN_RESET)
#define DCMI_PWDN_HIGH() HAL_GPIO_WritePin(DCMI_PWDN_PORT, DCMI_PWDN_PIN, GPIO_PIN_SET)
/* uSD */
#define SD_SPI (SPI2)
#define SD_SPI_AF (GPIO_AF5_SPI2)
#define SD_CD_PIN (GPIO_PIN_0)
#define SD_CS_PIN (GPIO_PIN_1)
#define SD_SCLK_PIN (GPIO_PIN_13)
#define SD_MISO_PIN (GPIO_PIN_2)
#define SD_MOSI_PIN (GPIO_PIN_3)
#define SD_CD_PORT (GPIOC)
#define SD_CS_PORT (GPIOC)
#define SD_SCLK_PORT (GPIOB)
#define SD_MISO_PORT (GPIOC)
#define SD_MOSI_PORT (GPIOC)
#define SD_SPI_CLK_ENABLE() __SPI2_CLK_ENABLE()
#define SD_SPI_CLK_DISABLE() __SPI2_CLK_DISABLE()
#define SD_SELECT() HAL_GPIO_WritePin(SD_CS_PORT, SD_CS_PIN, GPIO_PIN_RESET)
#define SD_DESELECT() HAL_GPIO_WritePin(SD_CS_PORT, SD_CS_PIN, GPIO_PIN_SET)
#endif //__PINCFG_H__

531
src/omv/sdcard.c Normal file
View File

@ -0,0 +1,531 @@
/*-----------------------------------------------------------------------*/
/* MMC/SDSC/SDHC (in SPI mode) control module for STM32 Version 1.1.6 */
/* (C) Martin Thomas, 2010 - based on the AVR MMC module (C)ChaN, 2007 */
/*-----------------------------------------------------------------------*/
/* Copyright (c) 2010, Martin Thomas, ChaN
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of the copyright holders nor the names of
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 OWNER 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. */
#include <stdbool.h>
#include <stm32f4xx_hal.h>
#include "mdefs.h"
#include "ffconf.h"
#include "diskio.h"
#include "pincfg.h"
#include "systick.h"
#include "sdcard.h"
#ifdef STM32_SD_USE_DMA
// #warning "Information only: using DMA"
#pragma message "*** Using DMA ***"
#endif
#define DMA_Channel_SPIx_RX DMA1_Channel4
#define DMA_Channel_SPIx_TX DMA1_Channel5
#define DMA_FLAG_SPIx_TC_RX DMA1_FLAG_TC4
#define DMA_FLAG_SPIx_TC_TX DMA1_FLAG_TC5
#define SPI_BaudRatePrescaler_SPIx SPI_BAUDRATEPRESCALER_2
/* Definitions for MMC/SDC command */
#define CMD0 (0x40+0) /* GO_IDLE_STATE */
#define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */
#define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */
#define CMD8 (0x40+8) /* SEND_IF_COND */
#define CMD9 (0x40+9) /* SEND_CSD */
#define CMD10 (0x40+10) /* SEND_CID */
#define CMD12 (0x40+12) /* STOP_TRANSMISSION */
#define ACMD13 (0xC0+13) /* SD_STATUS (SDC) */
#define CMD16 (0x40+16) /* SET_BLOCKLEN */
#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
#define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
#define CMD23 (0x40+23) /* SET_BLOCK_COUNT (MMC) */
#define ACMD23 (0xC0+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
#define CMD24 (0x40+24) /* WRITE_BLOCK */
#define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
#define CMD55 (0x40+55) /* APP_CMD */
#define CMD58 (0x40+58) /* READ_OCR */
#define SD_TIMEOUT (1000000)
/*--------------------------------------------------------------------------
Module Private Functions and Variables
---------------------------------------------------------------------------*/
static BYTE CardType; /* Card type flags */
static const DWORD socket_state_mask_cp = (1 << 0);
static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */
SPI_HandleTypeDef SPIHandle;
DRESULT sdcard_ioctl(BYTE drv, BYTE ctrl, void *buff);
bool sdcard_is_present(void)
{
return (HAL_GPIO_ReadPin(SD_CD_PORT, SD_CD_PIN)==GPIO_PIN_RESET);
}
/*-----------------------------------------------------------------------*/
/* Transmit/Receive a byte to MMC via SPI (Platform dependent) */
/*-----------------------------------------------------------------------*/
static BYTE stm32_spi_rw(BYTE out)
{
volatile HAL_StatusTypeDef st;
st = HAL_SPI_TransmitReceive(&SPIHandle, &out, &out, 1, SD_TIMEOUT);
if (st != HAL_OK) {
BREAK();
}
return out;
}
/*-----------------------------------------------------------------------*/
/* Transmit a byte to MMC via SPI (Platform dependent) */
/*-----------------------------------------------------------------------*/
#define xmit_spi(dat) stm32_spi_rw(dat)
/*-----------------------------------------------------------------------*/
/* Receive a byte from MMC via SPI (Platform dependent) */
/*-----------------------------------------------------------------------*/
static BYTE rcvr_spi (void)
{
return stm32_spi_rw(0xff);
}
/* Alternative macro to receive data fast */
#define rcvr_spi_m(dst) *(dst)=stm32_spi_rw(0xff)
/*-----------------------------------------------------------------------*/
/* Wait for card ready */
/*-----------------------------------------------------------------------*/
static BYTE wait_ready (void)
{
BYTE res;
volatile int timeout = SD_TIMEOUT;
rcvr_spi();
do
res = rcvr_spi();
while ((res != 0xFF) && timeout--);
return res;
}
/*-----------------------------------------------------------------------*/
/* SD_DESELECT the card and release SPI bus */
/*-----------------------------------------------------------------------*/
static void release_spi (void)
{
SD_DESELECT();
rcvr_spi();
}
/*-----------------------------------------------------------------------*/
/* Receive a data packet from MMC */
/*-----------------------------------------------------------------------*/
static bool rcvr_datablock (
BYTE *buff, /* Data buffer to store received data */
UINT btr /* Byte count (must be multiple of 4) */
)
{
BYTE token;
volatile int timeout = SD_TIMEOUT;
do { /* Wait for data packet in timeout of 100ms */
token = rcvr_spi();
} while ((token == 0xFF) && timeout--);
if(token != 0xFE) return false; /* If not valid data token, return with error */
#ifdef STM32_SD_USE_DMA
stm32_dma_transfer( true, buff, btr );
#else
do { /* Receive the data block into buffer */
rcvr_spi_m(buff++);
rcvr_spi_m(buff++);
rcvr_spi_m(buff++);
rcvr_spi_m(buff++);
} while (btr -= 4);
#endif /* STM32_SD_USE_DMA */
rcvr_spi(); /* Discard CRC */
rcvr_spi();
return true; /* Return with success */
}
/*-----------------------------------------------------------------------*/
/* Send a data packet to MMC */
/*-----------------------------------------------------------------------*/
static
bool xmit_datablock (
const BYTE *buff, /* data block to be transmitted */
BYTE token /* Data/Stop token */
)
{
BYTE resp;
#ifndef STM32_SD_USE_DMA
BYTE wc;
#endif
if (wait_ready() != 0xFF) return false;
xmit_spi(token); /* transmit data token */
if (token != 0xFD) { /* Is data token */
#ifdef STM32_SD_USE_DMA
stm32_dma_transfer( false, buff, SDCARD_BLOCK_SIZE);
#else
wc = 0;
do { /* transmit the data block to MMC */
xmit_spi(*buff++);
xmit_spi(*buff++);
} while (--wc);
#endif /* STM32_SD_USE_DMA */
xmit_spi(0xFF); /* CRC (Dummy) */
xmit_spi(0xFF);
resp = rcvr_spi(); /* Receive data response */
if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */
return false;
}
return true;
}
static BYTE send_cmd (
BYTE cmd, /* Command byte */
DWORD arg /* Argument */
)
{
BYTE n, res;
if (cmd & 0x80) { /* ACMD<n> is the command sequence of CMD55-CMD<n> */
cmd &= 0x7F;
res = send_cmd(CMD55, 0);
if (res > 1) return res;
}
/* SD_SELECT the card and wait for ready */
SD_DESELECT();
SD_SELECT();
if (wait_ready() != 0xFF) {
return 0xFF;
}
/* Send command packet */
xmit_spi(cmd); /* Start + Command index */
xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
xmit_spi((BYTE)arg); /* Argument[7..0] */
n = 0x01; /* Dummy CRC + Stop */
if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */
if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
xmit_spi(n);
/* Receive command response */
if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */
n = 10; /* Wait for a valid response in timeout of 10 attempts */
do
res = rcvr_spi();
while ((res & 0x80) && --n);
return res; /* Return with the response value */
}
void sdcard_hw_init(uint32_t baudrate)
{
/* SPI configuration */
SPIHandle.Instance = SD_SPI;
SPIHandle.Init.Mode = SPI_MODE_MASTER;
SPIHandle.Init.Direction = SPI_DIRECTION_2LINES;
SPIHandle.Init.DataSize = SPI_DATASIZE_8BIT;
SPIHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
SPIHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
SPIHandle.Init.NSS = SPI_NSS_SOFT;
SPIHandle.Init.BaudRatePrescaler = baudrate;
SPIHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SPIHandle.Init.TIMode = SPI_TIMODE_DISABLED;
SPIHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
SPIHandle.Init.CRCPolynomial = 7;
if (HAL_SPI_Init(&SPIHandle) == HAL_OK) {
/* dummy read */
uint8_t buf[1];
HAL_SPI_Receive(&SPIHandle, buf, sizeof(buf), SD_TIMEOUT);
} else {
/* error */
BREAK();
}
}
void sdcard_init(void)
{
BYTE n, cmd, ty, ocr[4];
volatile int timeout = SD_TIMEOUT;
/* init HW */
sdcard_hw_init(SPI_BAUDRATEPRESCALER_256);
systick_sleep(1000);
for (n = 10; n; n--) {
/* 80 dummy clocks */
rcvr_spi();
}
ty = 0;
if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
if (send_cmd(CMD8, 0x1AA) == 1) { /* SDHC */
for (n = 0; n < 4; n++) {
ocr[n] = rcvr_spi(); /* Get trailing return value of R7 response */
}
if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at VDD range of 2.7-3.6V */
while (--timeout && send_cmd(ACMD41, 1UL << 30)); /* Wait for leaving idle state (ACMD41 with HCS bit) */
if (timeout && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
for (n = 0; n < 4; n++) {
ocr[n] = rcvr_spi();
}
ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;
}
}
} else { /* SDSC or MMC */
if (send_cmd(ACMD41, 0) <= 1) {
ty = CT_SD1; cmd = ACMD41; /* SDSC */
} else {
ty = CT_MMC; cmd = CMD1; /* MMC */
}
while (--timeout && send_cmd(cmd, 0)); /* Wait for leaving idle state */
if (!timeout || send_cmd(CMD16, SDCARD_BLOCK_SIZE) != 0) /* Set R/W block length */
ty = 0;
}
}
CardType = ty;
release_spi();
if (ty) { /* Initialization succeeded */
Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
sdcard_hw_init(SPI_BAUDRATEPRESCALER_2);
} else {
/* Initialization failed */
BREAK();
}
}
bool sdcard_power_on(void)
{
return true;
}
void sdcard_power_off(void)
{
}
bool sdcard_read_blocks(uint8_t *buff, uint32_t sector, uint32_t count)
{
if (Stat & STA_NOINIT) {
return false;
}
if (!(CardType & CT_BLOCK)) {
sector *= SDCARD_BLOCK_SIZE; /* Convert to byte address if needed */
}
if (count == 1) { /* Single block read */
if (send_cmd(CMD17, sector) == 0) { /* READ_SINGLE_BLOCK */
if (rcvr_datablock(buff, SDCARD_BLOCK_SIZE)) {
count = 0;
}
}
} else { /* Multiple block read */
if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
do {
if (!rcvr_datablock(buff, SDCARD_BLOCK_SIZE)) {
break;
}
buff += SDCARD_BLOCK_SIZE;
} while (--count);
send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
}
}
release_spi();
return count ? false: true;
}
bool sdcard_write_blocks(const uint8_t *buff, uint32_t sector, uint32_t count)
{
if (Stat & STA_NOINIT) {
return false;
}
if (!(CardType & CT_BLOCK)) {
sector *= SDCARD_BLOCK_SIZE; /* Convert to byte address if needed */
}
if (count == 1) { /* Single block write */
if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
&& xmit_datablock(buff, 0xFE))
count = 0;
} else { /* Multiple block write */
if (CardType & CT_SDC) {
send_cmd(ACMD23, count);
}
if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
do {
if (!xmit_datablock(buff, 0xFC)) break;
buff += SDCARD_BLOCK_SIZE;
} while (--count);
if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
count = 1;
}
}
release_spi();
return count ? false: true;
}
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
uint64_t sdcard_get_capacity_in_bytes(void)
{
uint32_t sec;
sdcard_ioctl(0, GET_SECTOR_COUNT, &sec);
return sec * SDCARD_BLOCK_SIZE;
}
DRESULT sdcard_ioctl (
BYTE drv, /* Physical drive number (0) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
BYTE n, csd[16], *ptr = buff;
WORD csize;
if (drv) return RES_PARERR;
res = RES_ERROR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
switch (ctrl) {
case CTRL_SYNC : /* Make sure that no pending write process */
SD_SELECT();
if (wait_ready() == 0xFF)
res = RES_OK;
break;
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
if ((csd[0] >> 6) == 1) { /* SDC version 2.00 */
csize = csd[9] + ((WORD)csd[8] << 8) + 1;
*(DWORD*)buff = (DWORD)csize << 10;
} else { /* SDC version 1.XX or MMC*/
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
*(DWORD*)buff = (DWORD)csize << (n - 9);
}
res = RES_OK;
}
break;
case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */
*(WORD*)buff = SDCARD_BLOCK_SIZE;
res = RES_OK;
break;
case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
if (CardType & CT_SD2) { /* SDC version 2.00 */
if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */
rcvr_spi();
if (rcvr_datablock(csd, 16)) { /* Read partial block */
for (n = 64 - 16; n; n--) rcvr_spi(); /* Purge trailing data */
*(DWORD*)buff = 16UL << (csd[10] >> 4);
res = RES_OK;
}
}
} else { /* SDC version 1.XX or MMC */
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */
if (CardType & CT_SD1) { /* SDC version 1.XX */
*(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
} else { /* MMC */
*(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
}
res = RES_OK;
}
}
break;
case MMC_GET_TYPE : /* Get card type flags (1 byte) */
*ptr = CardType;
res = RES_OK;
break;
case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */
if (send_cmd(CMD9, 0) == 0 /* READ_CSD */
&& rcvr_datablock(ptr, 16))
res = RES_OK;
break;
case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */
if (send_cmd(CMD10, 0) == 0 /* READ_CID */
&& rcvr_datablock(ptr, 16))
res = RES_OK;
break;
case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */
if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
for (n = 4; n; n--) *ptr++ = rcvr_spi();
res = RES_OK;
}
break;
case MMC_GET_SDSTAT : /* Receive SD status as a data block (64 bytes) */
if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */
rcvr_spi();
if (rcvr_datablock(ptr, 64))
res = RES_OK;
}
break;
default:
res = RES_PARERR;
}
release_spi();
return res;
}

View File

@ -46,19 +46,22 @@ void HAL_MspInit(void)
/* Enable the CCM RAM */
__CCMDATARAMEN_CLK_ENABLE();
/* DCMI RESET/PWDN GPIO configuration */
/* Conigure DCMI GPIO */
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pin = DCMI_RESET_PIN;
HAL_GPIO_Init(DCMI_RESET_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pin = DCMI_PWDN_PIN;
HAL_GPIO_Init(DCMI_PWDN_PORT, &GPIO_InitStructure);
/* LED GPIO config */
/* Configure LED GPIO */
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
for (int i=0; i<NUM_LED_PINS; i++) {
HAL_GPIO_WritePin(led_pins[i].port,
led_pins[i].pin, GPIO_PIN_SET);
@ -66,6 +69,22 @@ void HAL_MspInit(void)
GPIO_InitStructure.Pin = led_pins[i].pin;
HAL_GPIO_Init(led_pins[i].port, &GPIO_InitStructure);
}
/* Configure SD GPIO */
GPIO_InitStructure.Pin = SD_CS_PIN;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(SD_CS_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pin = SD_CD_PIN;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(SD_CD_PORT, &GPIO_InitStructure);
/* De-select the Card: Chip Select high */
SD_DESELECT();
}
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
@ -89,6 +108,14 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
}
}
void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c)
{
if (hi2c->Instance == SCCB_I2C) {
HAL_I2C_DeInit(hi2c);
SCCB_CLK_DISABLE();
}
}
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
if (htim->Instance == DCMI_TIM) {
@ -124,11 +151,27 @@ void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi)
}
}
void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c)
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
if (hi2c->Instance == SCCB_I2C) {
HAL_I2C_DeInit(hi2c);
SCCB_CLK_DISABLE();
if (hspi->Instance == SD_SPI) {
/* Enable clock */
SD_SPI_CLK_ENABLE();
/* Configure SPI GPIOs */
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Alternate = SD_SPI_AF;
GPIO_InitStructure.Pin = SD_MOSI_PIN;
HAL_GPIO_Init(SD_MOSI_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pin = SD_MISO_PIN;
HAL_GPIO_Init(SD_MISO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pin = SD_SCLK_PIN;
HAL_GPIO_Init(SD_SCLK_PORT, &GPIO_InitStructure);
}
}