STM32F4: Add SDIO support

This commit is contained in:
Gordon Williams 2024-11-21 10:34:19 +00:00
parent 399f7ff99a
commit 01594b5a29
17 changed files with 3689 additions and 231 deletions

View File

@ -61,6 +61,7 @@
Add Serial.isConnected to check if Bluetooth/USB/etc actually connected
Pixl.js: Remove Wiznet W5100 support from default build (there's now a espruino_#v##_pixljs_wiznet.zip without JIT enabled) to ensure we have enough flash to continue builds
Enable nostartfiles optimisation for Pixl,MDBT42 and nRF52DK
STM32F4: Add SDIO support
2v24 : Bangle.js2: Add 'Bangle.touchRd()', 'Bangle.touchWr()'
Bangle.js2: After Bangle.showTestScreen, put Bangle.js into a hard off state (not soft off)

View File

@ -390,9 +390,8 @@ libs/filesystem/fat_sd/option/unicode.c # for LFN support (see _USE_LFN in ff.h)
ifeq ($(USE_FILESYSTEM_SDIO),1)
DEFINES += -DUSE_FILESYSTEM_SDIO
SOURCES += \
libs/filesystem/fat_sd/sdio_diskio.c \
libs/filesystem/fat_sd/sdio_sdcard.c
SOURCES += libs/filesystem/fat_sd/sdio_diskio.c
# sdio_sdcard_X.c is added in make/family/X.make
else #USE_FILESYSTEM_SDIO
ifdef USE_FLASHFS
DEFINES += -DUSE_FLASHFS

View File

@ -135,6 +135,7 @@ This is a partial list of definitions that can be added in a `BOARD.py` file's `
* `SPIFLASH_SLEEP_CMD` - Set if SPI flash needs to be explicitly slept and woken up
* `SPIFLASH_READ2X` - Enable 2x speed reads of external flash (using MOSI+MOSI as inputs)
* `ESPR_JSVAR_FLASH_BUFFER_SIZE=32` - The buffer size in bytes we use when executing/iterating over data in external flash memory (default 16). Should be set based on benchmarks.
* `ESPR_FS_LARGE_WRITE_BUFFER` - When using FS library, should we allocate a 1kb buffer on the stack for writes? It can be ~3x faster but then allocating 1k can be dangerous without checking
* `ESPR_PBF_FONTS` - Enable support for loading and displaying Pebble-style PBF font files with `g.setFontPBF`
* `ESPR_BLUETOOTH_ANCS` - Enable Apple ANCS(notification), AMS and CTS support
* `ESPR_USE_STEPPER_TIMER` - add builtin `Stepper` class to handle higher speed stepper handling
@ -160,6 +161,7 @@ There are some specifically that are useful for cutting a few bytes out of the b
* `ESPR_NO_REGEX_OPTIMISE` - strips out some speed optimisations from the regex library
* On nRF52, `'LDFLAGS += -nostartfiles', 'ASFLAGS += -D__STARTUP_CLEAR_BSS -D__START=main',` can save ~300b by not including CRT startup code
These are set automatically when `SAVE_ON_FLASH` is set (see `jsutils.h`)
* `SAVE_ON_FLASH_MATH` - Replace some Maths functions that use a bunch of Flash memory (sin/atan/atan2/fft) with slower, smaller versions

View File

@ -15,13 +15,6 @@
SD_CardInfo SDCardInfo2;
/*--------------------------------------------------------------------------
Public Functions
---------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */
/*-----------------------------------------------------------------------*/
@ -34,6 +27,8 @@ DSTATUS disk_initialize (
//jsiConsolePrint("SD_Init\n");
SD_Init();
#ifndef STM32F4
// FIXME: Do we even need this in EspruinoBoard? seems like SD_GetCardInfo especially just wastes time
//jsiConsolePrint("SD_GetCardInfo\n");
SD_GetCardInfo(&SDCardInfo2);
//jsiConsolePrint("SD_SelectDeselect\n");
@ -42,13 +37,14 @@ DSTATUS disk_initialize (
SD_EnableWideBusOperation(SDIO_BusWide_4b);
//jsiConsolePrint("SD_SetDeviceMode\n");
SD_SetDeviceMode(SD_DMA_MODE);
#endif
//jsiConsolePrint("NVIC_Init\n");
NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//NAND_Init();
return 0;
}
@ -70,6 +66,27 @@ DSTATUS disk_status (
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
#ifndef ESPR_SDIO_FAST_UNALIGNED
DRESULT disk_read_unaligned (
BYTE drv, /* Physical drive number (0) */
BYTE *buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Start sector number (LBA) */
UINT count /* Sector count */
)
{
uint8_t alignedBuffer[512] __attribute__ ((aligned (8)));
uint32_t Memory_Offset;
Memory_Offset = sector * 512;
while (count--) {
SD_ReadBlock(Memory_Offset, (uint32_t *)alignedBuffer, 512);
memcpy(buff, alignedBuffer, 512);
Memory_Offset += 512;
buff += 512;
}
return RES_OK;
}
#endif
DRESULT disk_read (
BYTE drv, /* Physical drive number (0) */
BYTE *buff, /* Pointer to the data buffer to store read data */
@ -83,8 +100,31 @@ DRESULT disk_read (
Transfer_Length = count * 512;
Memory_Offset = sector * 512;
#ifdef ESPR_SDIO_FAST_UNALIGNED
/* ESPR_SDIO_FAST_UNALIGNED is a really nasty hack. STM32 can't DMA to unaligned
addresses so what we do is we push the address forward to the next aligned point,
then we memmove it back by the correct amount after DMA. THIS MEANS THAT ANY
BUFFER WE F_READ INTO SHOULD BE 4 BYTES LONGER THAN THE MAX READ REQUEST
*/
int misalignment = ((size_t)buff)&3;
BYTE *correctbuff = buff;
if (misalignment)
buff += 4-misalignment;
#else
if ((size_t)buff&3) // unaligned read - must read to aligned buffer because of DMA
return disk_read_unaligned(drv, buff, sector, count);
#endif
if (count<=1)
SD_ReadBlock(Memory_Offset, (uint32_t *)buff, Transfer_Length);
//NAND_Read(Memory_Offset, (uint32_t *)buff, Transfer_Length);
else
SD_ReadMultiBlocks(Memory_Offset, (uint32_t *)buff, 512, count);
#ifdef ESPR_SDIO_FAST_UNALIGNED
if (misalignment) {
// move data back to correct point
memmove(correctbuff, buff, Transfer_Length);
}
#endif
return RES_OK;
}
@ -106,8 +146,11 @@ DRESULT disk_write (
Transfer_Length = count * 512;
Memory_Offset = sector * 512;
assert(((size_t)buff&3)==0);
if (count<=1)
SD_WriteBlock(Memory_Offset, (uint32_t *)buff, Transfer_Length);
else
SD_WriteMultiBlocks(Memory_Offset, (uint32_t *)buff, 512, count);
//NAND_Write(Memory_Offset, (uint32_t *)buff, Transfer_Length);
return RES_OK;
@ -125,19 +168,13 @@ DRESULT disk_ioctl (
)
{
DRESULT res = RES_OK;
uint32_t status = SD_NO_TRANSFER;
//uint32_t status = NAND_READY;
switch (ctrl) {
case CTRL_SYNC : /// Make sure that no pending write process
status = SD_GetTransferState();
if (status == SD_NO_TRANSFER)
//status = FSMC_NAND_GetStatus();
//if (status == NAND_READY)
{res = RES_OK;}
else{res = RES_ERROR;}
res = RES_OK;
break;
case GET_SECTOR_COUNT : // Get number of sectors on the disk (DWORD)

View File

@ -160,11 +160,26 @@ typedef enum
#define SDIO_SD_APP_CHANGE_SECURE_AREA ((uint8_t)49) /* For SD Card only */
#define SDIO_SD_APP_SECURE_WRITE_MKB ((uint8_t)48) /* For SD Card only */
#ifdef STM32F1
typedef enum
{
SD_NO_TRANSFER = 0,
SD_TRANSFER_IN_PROGRESS
} SDTransferState;
#endif
#ifdef STM32F4
typedef enum
{
SD_TRANSFER_OK = 0,
SD_TRANSFER_BUSY = 1,
SD_TRANSFER_ERROR
} SDTransferState;
#define SD_PRESENT ((uint8_t)0x01)
#define SD_NOT_PRESENT ((uint8_t)0x00)
uint8_t SD_Detect(void);
#endif
SDTransferState SD_GetTransferState(void);
typedef struct
{
@ -267,7 +282,6 @@ SD_Error SD_ReadBlock(uint32_t addr, uint32_t *readbuff, uint16_t BlockSize);
SD_Error SD_ReadMultiBlocks(uint32_t addr, uint32_t *readbuff, uint16_t BlockSize, uint32_t NumberOfBlocks);
SD_Error SD_WriteBlock(uint32_t addr, uint32_t *writebuff, uint16_t BlockSize);
SD_Error SD_WriteMultiBlocks(uint32_t addr, uint32_t *writebuff, uint16_t BlockSize, uint32_t NumberOfBlocks);
SDTransferState SD_GetTransferState(void);
SD_Error SD_StopTransfer(void);
SD_Error SD_Erase(uint32_t startaddr, uint32_t endaddr);
SD_Error SD_SendStatus(uint32_t *pcardstatus);

View File

@ -71,7 +71,12 @@ void jsfsReportError(const char *msg, FRESULT res) {
}
bool jsfsInit() {
#ifdef SD_POWER_PIN
if (jshPinGetValue(SD_POWER_PIN)==0) {
jshPinOutput(SD_POWER_PIN, 1);
jshDelayMicroseconds(5000);
}
#endif
#ifndef LINUX
if (!fat_initialised) {
#ifndef USE_FLASHFS
@ -99,7 +104,9 @@ bool jsfsInit() {
FRESULT res;
if ((res = f_mount(&jsfsFAT, "", 1)) != FR_OK) {
#ifndef PIPBOY // Don't throw an error for the Pip-Boy - just return false
jsfsReportError("Unable to mount media", res);
#endif
return false;
}
fat_initialised = true;
@ -417,7 +424,12 @@ size_t jswrap_file_write(JsVar* parent, JsVar* buffer) {
if(file.data->mode == FM_WRITE || file.data->mode == FM_READ_WRITE) {
JsvIterator it;
jsvIteratorNew(&it, buffer, JSIF_EVERY_ARRAY_ELEMENT);
#ifdef ESPR_FS_LARGE_WRITE_BUFFER
// writes are faster with sector-size buffers but we can't always safely allocate 512b on the stack unless we're sure we have a big stack
char buf[512];
#else
char buf[32];
#endif
while (jsvIteratorHasElement(&it)) {
// pull in a buffer's worth of data

View File

@ -64,6 +64,8 @@ typedef struct JsFile {
// Called when stopping, to make sure all files are closed
void jswrap_file_kill();
bool jsfsInit();
bool jsfsGetPathString(char *pathStr, JsVar *path);
void jswrap_E_connectSDCard(JsVar *spi, Pin csPin);
JsVar* jswrap_E_openFile(JsVar* path, JsVar* mode);
@ -75,7 +77,5 @@ void jswrap_file_skip_or_seek(JsVar* parent, int length, bool is_skip);
void jswrap_file_close(JsVar* parent);
#ifdef USE_FLASHFS
void jsfsReportError(const char *msg, FRESULT res);
bool jsfsInit();
int jswrap_E_flashFatFS(JsVar* options);
#endif

View File

@ -51,10 +51,7 @@ and for examples on wiring up an SD card if your device doesn't come with one.
*must* call `E.unmountSD()` or you may cause damage to the card.
*/
#ifndef LINUX
#define JS_DIR_BUF_SIZE 64
#else
#define JS_DIR_BUF_SIZE 256
#ifdef LINUX
#define FR_OK (0)
#endif
@ -69,8 +66,6 @@ and for examples on wiring up an SD card if your device doesn't come with one.
#endif
// from jswrap_file
bool jsfsGetPathString(char *pathStr, JsVar *path);
extern bool jsfsInit();
extern void jsfsReportError(const char *msg, FRESULT res);
/*JSON{

View File

@ -13,6 +13,13 @@
*/
#include "jsvar.h"
#ifndef LINUX
#define JS_DIR_BUF_SIZE 64
#else
#define JS_DIR_BUF_SIZE 256
#define FR_OK (0)
#endif
JsVar *jswrap_fs_readdir(JsVar *path);
bool jswrap_fs_writeOrAppendFile(JsVar *path, JsVar *data, bool append);
JsVar *jswrap_fs_readFile(JsVar *path);

View File

@ -33,3 +33,6 @@ targetlibs/stm32f1/lib/system_stm32f10x.c
ifdef USB
include make/common/STM32_LEGACY_USB.make
endif
ifeq ($(USE_FILESYSTEM_SDIO),1)
SOURCES += targets/stm32/sdio_sdcard_stm32f1.c
endif

View File

@ -62,3 +62,7 @@ targetlibs/stm32f4/lib/system_stm32f4xx.c
ifdef USB
include make/common/STM32_USB.make
endif
ifeq ($(USE_FILESYSTEM_SDIO),1)
SOURCES += targets/stm32/sdio_sdcard_stm32f4.c
SOURCES += targets/stm32/sdio_sdcard_stm32f4_ll.c
endif

View File

@ -108,7 +108,7 @@ else: # NOT LINUX
flash_saved_code2_pages = 0
if "saved_code" in board.chip:
flash_saved_code_start = board.chip["saved_code"]["address"]
flash_saved_code_start = hex(board.chip["saved_code"]["address"])
flash_page_size = board.chip["saved_code"]["page_size"]
flash_saved_code_pages = board.chip["saved_code"]["pages"]
flash_available_for_code = board.chip["saved_code"]["flash_available"]*1024
@ -309,12 +309,12 @@ else:
codeOut("")
codeOut("#define FLASH_SAVED_CODE_START "+str(flash_saved_code_start))
codeOut("#define FLASH_SAVED_CODE_LENGTH "+str(int(flash_page_size*flash_saved_code_pages)))
codeOut("#define FLASH_SAVED_CODE_START "+flash_saved_code_start)
codeOut("#define FLASH_SAVED_CODE_LENGTH "+hex(int(flash_page_size*flash_saved_code_pages)))
if flash_saved_code2_pages:
codeOut("// Extra flash pages in external flash")
codeOut("#define FLASH_SAVED_CODE2_START "+str(flash_saved_code2_start))
codeOut("#define FLASH_SAVED_CODE2_LENGTH "+str(int(flash_page_size*flash_saved_code2_pages)))
codeOut("#define FLASH_SAVED_CODE2_START "+hex(flash_saved_code2_start))
codeOut("#define FLASH_SAVED_CODE2_LENGTH "+hex(int(flash_page_size*flash_saved_code2_pages)))
codeOut("");
codeOut("#define CLOCK_SPEED_MHZ "+str(board.chip["speed"]))
@ -371,6 +371,10 @@ if 'util_timer_tasks' in board.info:
if 'io_buffer_size' in board.info:
bufferSizeIO = board.info['io_buffer_size']
if 'xoff_thresh' in board.info:
xoff_thresh = board.info['xoff_thresh']
if 'xon_thresh' in board.info:
xon_thresh = board.info['xon_thresh']
codeOut("#define IOBUFFERMASK "+str(bufferSizeIO-1)+" // (max 65535) amount of items in event buffer - events take 5 bytes each")
codeOut("#define TXBUFFERMASK "+str(bufferSizeTX-1)+" // (max 255) amount of items in the transmit buffer - 2 bytes each")
@ -446,18 +450,26 @@ if "LCD" in board.devices:
codeOutDevicePins("LCD","LCD");
if "SD" in board.devices:
if not "pin_d3" in board.devices["SD"]: # NOT SDIO - normal SD
if "pin_cs" in board.devices["SD"]: codeOutDevicePin("SD", "pin_cs", "SD_CS_PIN")
if "pin_di" in board.devices["SD"]: codeOutDevicePin("SD", "pin_di", "SD_DI_PIN")
if "pin_do" in board.devices["SD"]: codeOutDevicePin("SD", "pin_do", "SD_DO_PIN")
if "pin_clk" in board.devices["SD"]:
codeOutDevicePin("SD", "pin_clk", "SD_CLK_PIN")
if "pin_cd" in board.devices["SD"]: codeOutDevicePin("SD", "pin_cd", "SD_DETECT_PIN")
if "pin_pwr" in board.devices["SD"]: codeOutDevicePin("SD", "pin_pwr", "SD_POWER_PIN")
if "pin_cs" in board.devices["SD"]: codeOutDevicePin("SD", "pin_cs", "SD_CS_PIN")
if "pin_di" in board.devices["SD"]: codeOutDevicePin("SD", "pin_di", "SD_DI_PIN")
if "pin_do" in board.devices["SD"]: codeOutDevicePin("SD", "pin_do", "SD_DO_PIN")
if "pin_clk" in board.devices["SD"]:
codeOutDevicePin("SD", "pin_clk", "SD_CLK_PIN")
if not "pin_d3" in board.devices["SD"]: # NOT SDIO - normal SD
sdClkPin = pinutils.findpin(pins, "P"+board.devices["SD"]["pin_clk"], False)
spiNum = 0
for func in sdClkPin["functions"]:
if func[:3]=="SPI": spiNum = int(func[3])
if spiNum==0: die("No SPI peripheral found for SD card's CLK pin")
codeOut("#define SD_SPI EV_SPI"+str(spiNum))
# SDIO
if "pin_d0" in board.devices["SD"]: codeOutDevicePin("SD", "pin_d0", "SD_D0_PIN")
if "pin_d1" in board.devices["SD"]: codeOutDevicePin("SD", "pin_d1", "SD_D1_PIN")
if "pin_d2" in board.devices["SD"]: codeOutDevicePin("SD", "pin_d2", "SD_D2_PIN")
if "pin_d3" in board.devices["SD"]: codeOutDevicePin("SD", "pin_d3", "SD_D3_PIN")
if "pin_cmd" in board.devices["SD"]: codeOutDevicePin("SD", "pin_cmd", "SD_CMD_PIN")
if "IR" in board.devices:
codeOutDevicePin("IR", "pin_anode", "IR_ANODE_PIN")
@ -531,7 +543,8 @@ if "DRIVER1" in board.devices:
if "SPIFLASH" in board.devices:
codeOut("#define SPIFLASH_PAGESIZE 4096")
codeOut("#define SPIFLASH_LENGTH "+str(board.devices["SPIFLASH"]["size"]))
codeOut("#define SPIFLASH_BASE "+str(board.devices["SPIFLASH"]["memmap_base"])+"UL")
if "memmap_base" in board.devices["SPIFLASH"]:
codeOut("#define SPIFLASH_BASE "+str(board.devices["SPIFLASH"]["memmap_base"])+"UL")
codeOutDevicePins("SPIFLASH", "SPIFLASH")
for device in pinutils.OTHER_DEVICES:

View File

@ -91,7 +91,7 @@ DEVICES = {
"TEMP":"TEMP",
};
for i in range(0,7):
for i in range(0,10):
DEVICES["LED"+str(i)]="LED"+str(i)
DEVICES["BTN"+str(i)]="BTN"+str(i)
DEVICES["POT"+str(i)]="POT"+str(i)
@ -118,8 +118,8 @@ URLS = {
# LED/Button devices
SIMPLE_DEVICES = [
"LED1","LED2","LED3","LED4","LED5","LED6","LED7","LED8",
"BTN1","BTN2","BTN3","BTN4","BTN5","BTN6","BTN7","BTN8" ];
"LED1","LED2","LED3","LED4","LED5","LED6","LED7","LED8","LED9","LED10",
"BTN1","BTN2","BTN3","BTN4","BTN5","BTN6","BTN7","BTN8","BTN9","BTN10", ];
# Devices with pins that we should leave alone at reset time
OTHER_DEVICES = [

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,187 @@
#include "sdio_sdcard.h"
#include "sdio_sdcard_stm32f4_ll.h"
#include "jsinteractive.h"
/**
* @brief DeInitializes the SDIO interface.
* @param None
* @retval None
*/
void SD_LowLevel_DeInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*!< Disable SDIO Clock */
SDIO_ClockCmd(DISABLE);
/*!< Set Power State to OFF */
SDIO_SetPowerState(SDIO_PowerState_OFF);
/*!< DeInitializes the SDIO peripheral */
SDIO_DeInit();
/* Disable the SDIO APB2 Clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, DISABLE);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_MCO);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_MCO);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_MCO);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_MCO);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_MCO);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_MCO);
/* Configure PC.08, PC.09, PC.10, PC.11 pins: D0, D1, D2, D3 pins */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Configure PD.02 CMD line */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure PC.12 pin: CLK pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
/**
* @brief Initializes the SD Card and put it into StandBy State (Ready for
* data transfer).
* @param None
* @retval None
*/
void SD_LowLevel_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOC and GPIOD Periph clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD/* | SD_DETECT_GPIO_CLK*/, ENABLE);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_SDIO);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_SDIO);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_SDIO);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_SDIO);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_SDIO);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_SDIO);
/* Configure PC.08, PC.09, PC.10, PC.11 pins: D0, D1, D2, D3 pins */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Configure PD.02 CMD line */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure PC.12 pin: CLK pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*!< Configure SD_SPI_DETECT_PIN pin: SD Card detect pin */
/*GPIO_InitStructure.GPIO_Pin = SD_DETECT_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStructure);*/
/* Enable the SDIO APB2 Clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE);
/* Enable the DMA2 Clock */
RCC_AHB1PeriphClockCmd(SD_SDIO_DMA_CLK, ENABLE);
}
/**
* @brief Configures the DMA2 Channel4 for SDIO Tx request.
* @param BufferSRC: pointer to the source buffer
* @param BufferSize: buffer size
* @retval None
*/
void SD_LowLevel_DMA_TxConfig(uint32_t *BufferSRC, uint32_t BufferSize)
{
DMA_InitTypeDef SDDMA_InitStructure;
DMA_ClearFlag(SD_SDIO_DMA_STREAM, SD_SDIO_DMA_FLAG_FEIF | SD_SDIO_DMA_FLAG_DMEIF | SD_SDIO_DMA_FLAG_TEIF | SD_SDIO_DMA_FLAG_HTIF | SD_SDIO_DMA_FLAG_TCIF);
/* DMA2 Stream3 or Stream6 disable */
DMA_Cmd(SD_SDIO_DMA_STREAM, DISABLE);
/* DMA2 Stream3 or Stream6 Config */
DMA_DeInit(SD_SDIO_DMA_STREAM);
SDDMA_InitStructure.DMA_Channel = SD_SDIO_DMA_CHANNEL;
SDDMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;
SDDMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)BufferSRC;
SDDMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
SDDMA_InitStructure.DMA_BufferSize = 0;
SDDMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
SDDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
SDDMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
SDDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
SDDMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
SDDMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
SDDMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
SDDMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
SDDMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
SDDMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;
DMA_Init(SD_SDIO_DMA_STREAM, &SDDMA_InitStructure);
DMA_ITConfig(SD_SDIO_DMA_STREAM, DMA_IT_TC, ENABLE);
DMA_FlowControllerConfig(SD_SDIO_DMA_STREAM, DMA_FlowCtrl_Peripheral);
/* DMA2 Stream3 or Stream6 enable */
DMA_Cmd(SD_SDIO_DMA_STREAM, ENABLE);
}
/**
* @brief Configures the DMA2 Channel4 for SDIO Rx request.
* @param BufferDST: pointer to the destination buffer
* @param BufferSize: buffer size
* @retval None
*/
void SD_LowLevel_DMA_RxConfig(uint32_t *BufferDST, uint32_t BufferSize)
{
DMA_InitTypeDef SDDMA_InitStructure;
DMA_ClearFlag(SD_SDIO_DMA_STREAM, SD_SDIO_DMA_FLAG_FEIF | SD_SDIO_DMA_FLAG_DMEIF | SD_SDIO_DMA_FLAG_TEIF | SD_SDIO_DMA_FLAG_HTIF | SD_SDIO_DMA_FLAG_TCIF);
/* DMA2 Stream3 or Stream6 disable */
DMA_Cmd(SD_SDIO_DMA_STREAM, DISABLE);
/* DMA2 Stream3 or Stream6 Config */
DMA_DeInit(SD_SDIO_DMA_STREAM);
SDDMA_InitStructure.DMA_Channel = SD_SDIO_DMA_CHANNEL;
SDDMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;
SDDMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)BufferDST;
SDDMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
SDDMA_InitStructure.DMA_BufferSize = 0;
SDDMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
SDDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
SDDMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
SDDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
SDDMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
SDDMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
SDDMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
SDDMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
SDDMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
SDDMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;
DMA_Init(SD_SDIO_DMA_STREAM, &SDDMA_InitStructure);
DMA_ITConfig(SD_SDIO_DMA_STREAM, DMA_IT_TC, ENABLE);
DMA_FlowControllerConfig(SD_SDIO_DMA_STREAM, DMA_FlowCtrl_Peripheral);
/* DMA2 Stream3 or Stream6 enable */
DMA_Cmd(SD_SDIO_DMA_STREAM, ENABLE);
}
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,64 @@
//******************************************************************************
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4_DISCOVERY_SDIO_SD_LOWLEVEL_H
#define __STM32F4_DISCOVERY_SDIO_SD_LOWLEVEL_H
#include "stm32f4xx.h"
/** @addtogroup STM32F4_DISCOVERY_LOW_LEVEL_SD_FLASH
* @{
*/
/**
* @brief SD FLASH SDIO Interface
*/
#define SD_DETECT_PIN GPIO_Pin_2 /* PC.02 */
#define SD_DETECT_GPIO_PORT GPIOC /* GPIOC */
#define SD_DETECT_GPIO_CLK RCC_AHB1Periph_GPIOC
#define SDIO_FIFO_ADDRESS ((uint32_t)0x40012C80)
/**
* @brief SDIO Intialization Frequency (400KHz max)
*/
#define SDIO_INIT_CLK_DIV ((uint8_t)0x76)
/**
* @brief SDIO Data Transfer Frequency (25MHz max)
*/
#define SDIO_TRANSFER_CLK_DIV ((uint8_t)0x2)
#define SD_SDIO_DMA DMA2
#define SD_SDIO_DMA_CLK RCC_AHB1Periph_DMA2
#define SD_SDIO_DMA_STREAM3 3
//#define SD_SDIO_DMA_STREAM6 6
#ifdef SD_SDIO_DMA_STREAM3
#define SD_SDIO_DMA_STREAM DMA2_Stream3
#define SD_SDIO_DMA_CHANNEL DMA_Channel_4
#define SD_SDIO_DMA_FLAG_FEIF DMA_FLAG_FEIF3
#define SD_SDIO_DMA_FLAG_DMEIF DMA_FLAG_DMEIF3
#define SD_SDIO_DMA_FLAG_TEIF DMA_FLAG_TEIF3
#define SD_SDIO_DMA_FLAG_HTIF DMA_FLAG_HTIF3
#define SD_SDIO_DMA_FLAG_TCIF DMA_FLAG_TCIF3
#define SD_SDIO_DMA_IRQn DMA2_Stream3_IRQn
#define SD_SDIO_DMA_IRQHANDLER DMA2_Stream3_IRQHandler
#elif defined SD_SDIO_DMA_STREAM6
#define SD_SDIO_DMA_STREAM DMA2_Stream6
#define SD_SDIO_DMA_CHANNEL DMA_Channel_4
#define SD_SDIO_DMA_FLAG_FEIF DMA_FLAG_FEIF6
#define SD_SDIO_DMA_FLAG_DMEIF DMA_FLAG_DMEIF6
#define SD_SDIO_DMA_FLAG_TEIF DMA_FLAG_TEIF6
#define SD_SDIO_DMA_FLAG_HTIF DMA_FLAG_HTIF6
#define SD_SDIO_DMA_FLAG_TCIF DMA_FLAG_TCIF6
#define SD_SDIO_DMA_IRQn DMA2_Stream6_IRQn
#define SD_SDIO_DMA_IRQHANDLER DMA2_Stream6_IRQHandler
#endif /* SD_SDIO_DMA_STREAM3 */
void SD_LowLevel_DeInit(void);
void SD_LowLevel_Init(void);
void SD_LowLevel_DMA_TxConfig(uint32_t *BufferSRC, uint32_t BufferSize);
void SD_LowLevel_DMA_RxConfig(uint32_t *BufferDST, uint32_t BufferSize);
#endif /* __STM32F4_DISCOVERY_SDIO_SD_LOWLEVEL_H */
//******************************************************************************