From 7464dbec8b8c53678d586686242c821071ba2753 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Fri, 16 Jun 2023 17:23:20 +0200 Subject: [PATCH] feat: support new SD pins management Fixe #47 Signed-off-by: Frederic Pillon --- README.md | 108 ++++++++++++++++++++++++++++++--- keywords.txt | 8 ++- src/SD.cpp | 61 ++++++++++++++++++- src/STM32SD.h | 70 +++++++++++++++++++++- src/Sd2Card.cpp | 33 ++++++++++- src/Sd2Card.h | 75 ++++++++++++++++++++++- src/bsp_sd.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++- src/bsp_sd.h | 54 ++++++++++++++++- 8 files changed, 541 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 8f73300..338ab84 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ http://www.arduino.cc/en/Reference/SD ## Dependency -This library is based on FatFs, a generic FAT file system module for small embedded systems. +This library is based on FatFs, a generic FAT file system module for small embedded systems. [http://elm-chan.org/fsw/ff](http://elm-chan.org/fsw/ff/00index_e.html) The FatFs has been ported as Arduino library [here](https://github.com/stm32duino/FatFs). @@ -31,11 +31,105 @@ User can provide his own defined options by adding his configuration in a file n ### SD Some default definitions can be overridden using: - * board `variant.h` - * `build_opt.h`: see [Customize build options](https://github.com/stm32duino/wiki/wiki/Customize-build-options-using-build_opt.h) - - * `hal_conf_extra.h`: see [HAL configuration](https://github.com/stm32duino/wiki/wiki/HAL-configuration) - + * board `variant*.h` + * `build_opt.h`: see [Customize build options](https://github.com/stm32duino/Arduino_Core_STM32/wiki/Customize-build-options-using-build_opt.h) + + * `hal_conf_extra.h`: see [HAL configuration](https://github.com/stm32duino/Arduino_Core_STM32/wiki/HAL-configuration) + +#### SDIO/SDMMC pins definition + +Since STM32 core v2.6.0, the `PinMap_SD[]` array defined in the `PeripheralPins*.c` has been split per signals: +```C +PinMap_SD_CK[] +PinMap_SD_DATA0[] +PinMap_SD_DATA1[] +PinMap_SD_DATA2[] +PinMap_SD_DATA3[] +PinMap_SD_DATA4[] +PinMap_SD_DATA5[] +PinMap_SD_DATA6[] +PinMap_SD_DATA7[] +/* Only for SDMMC */ +PinMap_SD_CKIN[] +PinMap_SD_CDIR[] +PinMap_SD_D0DIR[] +PinMap_SD_D123DIR[] +``` + +This allows to define the SDIO/SDMMC pins to use instead of using all the pins defined in the old array. +By default, if no pins are explicitly defined, the first one from each array is used. + +* To redefine the default one, use the following macros: + + * `SDX_D0` + * `SDX_D1` + * `SDX_D2` + * `SDX_D3` + * `SDX_CMD` + * `SDX_CK` + + * Only for `SDMMC`: + * `SDX_CKIN` + * `SDX_CDIR` + * `SDX_D0DIR` + * `SDX_D123DIR` + +* or redefine the default one before call of `begin()` of `SDClass` or `init()` of `Sd2Card`, use the following methods: + + * `setDx(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3)` + * `setCK(uint32_t ck)` + * `setCK(PinName ck)` + * `setCMD(uint32_t cmd)` + * `setCMD(PinName cmd)` + + * Only for `SDMMC`: + * `setCKIN(uint32_t ckin)` + * `setCKIN(PinName ckin)` + * `setCDIR(uint32_t cdir)` + * `setCDIR(PinName cdir)` + * `setDxDIR(uint32_t d0dir, uint32_t d123dir)` + * `setDxDIR(PinName d0dir, PinName d123dir)` + + *Code snippet:* +```C++ + Sd2Card card; + card.setDx(PE12, PE13, PE14, PE15); + card.setCMD(PB_14); // using PinName + card.setCK(PB15); + card.init(); +``` + or +```C++ + SD.setDx(PE12, PE13, PE14, PE15); + SD.setCMD(PB14); + SD.setCK(PB_15); // using PinName + SD.begin(); +``` + +* or using the `begin()` of `SDClass` or `init()` of `Sd2Card` methods: + + * For `SDIO`: + * `SDClass`: + * `begin(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, uint32_t ck, uint32_t cmd)` + * `begin(uint32_t detect = SD_DETECT_NONE, uint32_t data0 = SDX_D0, uint32_t data1 = SDX_D1, uint32_t data2 = SDX_D2, uint32_t data3 = SDX_D3, uint32_t ck = SDX_CK, uint32_t cmd = SDX_CMD, uint32_t ckin = SDX_CKIN, uint32_t cdir = SDX_CDIR, uint32_t d0dir = SDX_D0DIR, uint32_t d123dir = SDX_D123DIR);` + * `Sd2Card`: + * `init(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, uint32_t ck, uint32_t cmd)` + * `init(uint32_t detect = SD_DETECT_NONE, uint32_t data0 = SDX_D0, uint32_t data1 = SDX_D1, uint32_t data2 = SDX_D2, uint32_t data3 = SDX_D3, uint32_t ck = SDX_CK, uint32_t cmd = SDX_CMD);` + + * For `SDMMC`: + * `SDClass`: + * `begin(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, uint32_t ck, uint32_t cmd, uint32_t ckin, uint32_t cdir, uint32_t d0dir, uint32_t d123dir);` + * `begin(uint32_t detect = SD_DETECT_NONE, uint32_t data0 = SDX_D0, uint32_t data1 = SDX_D1, uint32_t data2 = SDX_D2, uint32_t data3 = SDX_D3, uint32_t ck = SDX_CK, uint32_t cmd = SDX_CMD, uint32_t ckin = SDX_CKIN, uint32_t cdir = SDX_CDIR, uint32_t d0dir = SDX_D0DIR, uint32_t d123dir = SDX_D123DIR);` + * + * * `Sd2Card`: + * `init(uint32_t data0 = SDX_D0, uint32_t data1 = SDX_D1, uint32_t data2 = SDX_D2, uint32_t data3 = SDX_D3, uint32_t ck = SDX_CK, uint32_t cmd = SDX_CMD, uint32_t ckin = SDX_CKIN, uint32_t cdir = SDX_CDIR, uint32_t d0dir = SDX_D0DIR, uint32_t d123dir = SDX_D123DIR)` + * `init(uint32_t detect = SD_DETECT_NONE, uint32_t data0 = SDX_D0, uint32_t data1 = SDX_D1, uint32_t data2 = SDX_D2, uint32_t data3 = SDX_D3, uint32_t ck = SDX_CK, uint32_t cmd = SDX_CMD, uint32_t ckin = SDX_CKIN, uint32_t cdir = SDX_CDIR, uint32_t d0dir = SDX_D0DIR, uint32_t d123dir = SDX_D123DIR);` + + *Code snippet:* +```C++ + card.init(PE12, PE13, PE14, PE15, PB14, PB15); + SD.begin(SD_DETECT_PIN, PE12, PE13, PE14, PE15, PB14, PB15); +``` #### SD configurations @@ -68,4 +162,4 @@ Some default definitions can be overridden using: #### SD detect and timeout * `SD_DETECT_PIN` pin number -* `SD_DATATIMEOUT` constant for Read/Write block \ No newline at end of file +* `SD_DATATIMEOUT` constant for Read/Write block diff --git a/keywords.txt b/keywords.txt index f3f6633..dc9f811 100644 --- a/keywords.txt +++ b/keywords.txt @@ -24,7 +24,13 @@ open KEYWORD2 close KEYWORD2 seek KEYWORD2 position KEYWORD2 -size KEYWORD2 +size KEYWORD2 +setDx KEYWORD2 +setCK KEYWORD2 +setCMD KEYWORD2 +setCKIN KEYWORD2 +setCDIR KEYWORD2 +setDxDIR KEYWORD2 ####################################### # Constants (LITERAL1) diff --git a/src/SD.cpp b/src/SD.cpp index 21c8faa..4dd294e 100644 --- a/src/SD.cpp +++ b/src/SD.cpp @@ -59,13 +59,68 @@ SDClass SD; /** * @brief Link SD, register the file system object to the FatFs mode and configure * relatives SD IOs including SD Detect Pin if any - * @param None + * @param data0: data0 pin number (default SDX_D0) + * @param data1: data1 pin number (default SDX_D1) + * @param data2: data2 pin number (default SDX_D2) + * @param data3: data3 pin number (default SDX_D3) + * @param ck: ck pin number (default SDX_CK) + * @param cmd: cmd pin number (default SDX_CMD) + * @param ckin: ckin pin number only for SDMMC (default SDX_CKIN) + * @param cdir: cdir pin number only for SDMMC (default SDX_CDIR) + * @param d0dir: d0dir pin number only for SDMMC (default SDX_D0DIR) + * @param d123dir: d123dir pin number only for SDMMC (default SDX_D123DIR) * @retval true or false */ -bool SDClass::begin(uint32_t detectpin) +#if defined(SDMMC1) || defined(SDMMC2) +bool SDClass::begin(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, + uint32_t ck, uint32_t cmd, uint32_t ckin, uint32_t cdir, + uint32_t d0dir, uint32_t d123dir) +{ + return begin(SD_DETECT_NONE, data0, data1, data2, data3, ck, cmd, ckin, cdir, d0dir, d123dir); +} + +#else +bool SDClass::begin(uint32_t data0, uint32_t data1, uint32_t data2, + uint32_t data3, uint32_t ck, uint32_t cmd) { + return begin(SD_DETECT_NONE, data0, data1, data2, data3, ck, cmd); +} +#endif + +/** + * @brief Link SD, register the file system object to the FatFs mode and configure + * relatives SD IOs including SD Detect Pin if any + * @param detect: detect pin number (default SD_DETECT_NONE) + * @param data0: data0 pin number (default SDX_D0) + * @param data1: data1 pin number (default SDX_D1) + * @param data2: data2 pin number (default SDX_D2) + * @param data3: data3 pin number (default SDX_D3) + * @param ck: ck pin number (default SDX_CK) + * @param cmd: cmd pin number (default SDX_CMD) + * @param ckin: ckin pin number only for SDMMC (default SDX_CKIN) + * @param cdir: cdir pin number only for SDMMC (default SDX_CDIR) + * @param d0dir: d0dir pin number only for SDMMC (default SDX_D0DIR) + * @param d123dir: d123dir pin number only for SDMMC (default SDX_D123DIR) + * @retval true or false + */ +#if defined(SDMMC1) || defined(SDMMC2) +bool SDClass::begin(uint32_t detect, uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, + uint32_t ck, uint32_t cmd, uint32_t ckin, uint32_t cdir, uint32_t d0dir, uint32_t d123dir) +#else +bool SDClass::begin(uint32_t detect, uint32_t data0, uint32_t data1, uint32_t data2, + uint32_t data3, uint32_t ck, uint32_t cmd) +#endif +{ + setDx(data0, data1, data2, data3); + setCK(ck); + setCMD(cmd); +#if defined(SDMMC1) || defined(SDMMC2) + setCKIN(ckin); + setCDIR(cdir); + setDxDIR(d0dir, d123dir); +#endif /*##-1- Initializes SD IOs #############################################*/ - if (_card.init(detectpin)) { + if (_card.init(detect)) { return _fatFs.init(); } return false; diff --git a/src/STM32SD.h b/src/STM32SD.h index 5249d36..8033e2a 100644 --- a/src/STM32SD.h +++ b/src/STM32SD.h @@ -84,9 +84,75 @@ class File { class SDClass { public: - /* Initialize the SD peripheral */ - bool begin(uint32_t detectpin = SD_DETECT_NONE); +#if defined(SDMMC1) || defined(SDMMC2) + bool begin(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, uint32_t ck, uint32_t cmd, + uint32_t ckin, uint32_t cdir, uint32_t d0dir, uint32_t d123dir + ); + bool begin(uint32_t detect = SD_DETECT_NONE, uint32_t data0 = SDX_D0, uint32_t data1 = SDX_D1, + uint32_t data2 = SDX_D2, uint32_t data3 = SDX_D3, uint32_t ck = SDX_CK, uint32_t cmd = SDX_CMD, + uint32_t ckin = SDX_CKIN, uint32_t cdir = SDX_CDIR, uint32_t d0dir = SDX_D0DIR, uint32_t d123dir = SDX_D123DIR + ); +#else + bool begin(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, uint32_t ck, uint32_t cmd); + bool begin(uint32_t detect = SD_DETECT_NONE, uint32_t data0 = SDX_D0, uint32_t data1 = SDX_D1, + uint32_t data2 = SDX_D2, uint32_t data3 = SDX_D3, uint32_t ck = SDX_CMD, uint32_t cmd = SDX_CMD + ); +#endif + + // set* have to be called before begin() + void setDx(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3) + { + _card.setDx(data0, data1, data2, data3); + }; + void setCK(uint32_t ck) + { + _card.setCK(ck); + }; + void setCMD(uint32_t cmd) + { + _card.setCMD(cmd); + }; + + void setDx(PinName data0, PinName data1, PinName data2, PinName data3) + { + _card.setDx(data0, data1, data2, data3); + }; + void setCK(PinName ck) + { + _card.setCK(ck); + }; + void setCMD(PinName cmd) + { + _card.setCMD(cmd); + }; +#if defined(SDMMC1) || defined(SDMMC2) + void setCKIN(uint32_t ckin) + { + _card.setCKIN(ckin); + }; + void setCDIR(uint32_t cdir) + { + _card.setCDIR(cdir); + }; + void setDxDIR(uint32_t d0dir, uint32_t d123dir) + { + _card.setDxDIR(d0dir, d123dir); + }; + + void setCKIN(PinName ckin) + { + _card.setCKIN(ckin); + }; + void setCDIR(PinName cdir) + { + _card.setCDIR(cdir); + }; + void setDxDIR(PinName d0dir, PinName d123dir) + { + _card.setDxDIR(d0dir, d123dir); + }; +#endif static File open(const char *filepath, uint8_t mode = FA_READ); static bool exists(const char *filepath); static bool mkdir(const char *filepath); diff --git a/src/Sd2Card.cpp b/src/Sd2Card.cpp index 7d70900..2c7cb8a 100644 --- a/src/Sd2Card.cpp +++ b/src/Sd2Card.cpp @@ -37,10 +37,37 @@ #include #include "Sd2Card.h" -bool Sd2Card::init(uint32_t detectpin) +#if defined(SDMMC1) || defined(SDMMC2) +bool Sd2Card::init(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, uint32_t ck, uint32_t cmd, + uint32_t ckin, uint32_t cdir, uint32_t d0dir, uint32_t d123dir) { - if (detectpin != SD_DETECT_NONE) { - PinName p = digitalPinToPinName(detectpin); + return init(SD_DETECT_NONE, data0, data1, data2, data3, ck, cmd, ckin, cdir, d0dir, d123dir); +} +#else +bool Sd2Card::init(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, uint32_t ck, uint32_t cmd) +{ + return init(SD_DETECT_NONE, data0, data1, data2, data3, ck, cmd); +} +#endif + +#if defined(SDMMC1) || defined(SDMMC2) +bool Sd2Card::init(uint32_t detect, uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, + uint32_t ck, uint32_t cmd, uint32_t ckin, uint32_t cdir, uint32_t d0dir, uint32_t d123dir) +#else +bool Sd2Card::init(uint32_t detect, uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, + uint32_t ck, uint32_t cmd) +#endif +{ + setDx(data0, data1, data2, data3); + setCK(ck); + setCMD(cmd); +#if defined(SDMMC1) || defined(SDMMC2) + setCKIN(ckin); + setCDIR(cdir); + setDxDIR(d0dir, d123dir); +#endif + if (detect != SD_DETECT_NONE) { + PinName p = digitalPinToPinName(detect); if ((p == NC) || \ BSP_SD_DetectPin(set_GPIO_Port_Clock(STM_PORT(p)), STM_LL_GPIO_PIN(p)) != MSD_OK) { diff --git a/src/Sd2Card.h b/src/Sd2Card.h index 5dbee9f..eb2effb 100644 --- a/src/Sd2Card.h +++ b/src/Sd2Card.h @@ -52,9 +52,82 @@ class Sd2Card { public: +#if defined(SDMMC1) || defined(SDMMC2) + bool init(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, uint32_t ck, uint32_t cmd, + uint32_t ckin, uint32_t cdir, uint32_t d0dir, uint32_t d123dir + ); + bool init(uint32_t detect = SD_DETECT_NONE, uint32_t data0 = SDX_D0, uint32_t data1 = SDX_D1, + uint32_t data2 = SDX_D2, uint32_t data3 = SDX_D3, uint32_t ck = SDX_CK, uint32_t cmd = SDX_CMD, + uint32_t ckin = SDX_CKIN, uint32_t cdir = SDX_CDIR, uint32_t d0dir = SDX_D0DIR, uint32_t d123dir = SDX_D123DIR + ); +#else + bool init(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3, uint32_t ck, uint32_t cmd); + bool init(uint32_t detect = SD_DETECT_NONE, uint32_t data0 = SDX_D0, uint32_t data1 = SDX_D1, + uint32_t data2 = SDX_D2, uint32_t data3 = SDX_D3, uint32_t ck = SDX_CK, uint32_t cmd = SDX_CMD + ); +#endif - bool init(uint32_t detectpin = SD_DETECT_NONE); + // set* have to be called before init() + void setDx(uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3) + { + SD_PinNames.pin_d0 = digitalPinToPinName(data0); + SD_PinNames.pin_d1 = digitalPinToPinName(data1); + SD_PinNames.pin_d2 = digitalPinToPinName(data2); + SD_PinNames.pin_d3 = digitalPinToPinName(data3); + }; + void setCK(uint32_t ck) + { + SD_PinNames.pin_ck = digitalPinToPinName(ck); + }; + void setCMD(uint32_t cmd) + { + SD_PinNames.pin_cmd = digitalPinToPinName(cmd); + }; + void setDx(PinName data0, PinName data1, PinName data2, PinName data3) + { + SD_PinNames.pin_d0 = data0; + SD_PinNames.pin_d1 = data1; + SD_PinNames.pin_d2 = data2; + SD_PinNames.pin_d3 = data3; + }; + void setCK(PinName ck) + { + SD_PinNames.pin_ck = ck; + }; + void setCMD(PinName cmd) + { + SD_PinNames.pin_cmd = cmd; + }; +#if defined(SDMMC1) || defined(SDMMC2) + void setCKIN(uint32_t ckin) + { + SD_PinNames.pin_ckin = digitalPinToPinName(ckin); + }; + void setCDIR(uint32_t cdir) + { + SD_PinNames.pin_cdir = digitalPinToPinName(cdir); + }; + void setDxDIR(uint32_t d0dir, uint32_t d123dir) + { + SD_PinNames.pin_d0dir = digitalPinToPinName(d0dir); + SD_PinNames.pin_d123dir = digitalPinToPinName(d123dir); + }; + + void setCKIN(PinName ckin) + { + SD_PinNames.pin_ckin = ckin; + }; + void setCDIR(PinName cdir) + { + SD_PinNames.pin_cdir = cdir; + }; + void setDxDIR(PinName d0dir, PinName d123dir) + { + SD_PinNames.pin_d0dir = d0dir; + SD_PinNames.pin_d123dir = d123dir; + }; +#endif /** Return the card type: SD V1, SD V2 or SDHC */ uint8_t type(void) const; diff --git a/src/bsp_sd.c b/src/bsp_sd.c index 7e641e6..ee767cc 100644 --- a/src/bsp_sd.c +++ b/src/bsp_sd.c @@ -35,6 +35,7 @@ /* Includes ------------------------------------------------------------------*/ #include "bsp_sd.h" +#include "core_debug.h" #include "interrupt.h" #include "PeripheralPins.h" #include "stm32yyxx_ll_gpio.h" @@ -122,7 +123,105 @@ static GPIO_TypeDef *SD_detect_gpio_port = GPIOA; #endif #define SD_TRANSFER_OK ((uint8_t)0x00) #define SD_TRANSFER_BUSY ((uint8_t)0x01) +SD_PinName_t SD_PinNames = { + .pin_d0 = NC, + .pin_d1 = NC, + .pin_d2 = NC, + .pin_d3 = NC, + .pin_cmd = NC, + .pin_ck = NC, +#if defined(SDMMC1) || defined(SDMMC2) + .pin_ckin = NC, + .pin_cdir = NC, + .pin_d0dir = NC, + .pin_d123dir = NC +#endif +}; +#if defined(STM32_CORE_VERSION) && (STM32_CORE_VERSION > 0x02050000) +/** + * @brief Get the SD card device instance from pins + * @retval SD status + */ +uint8_t BSP_SD_GetInstance(void) +{ + SD_TypeDef *sd_d0 = NP; + SD_TypeDef *sd_d1 = NP; + SD_TypeDef *sd_d2 = NP; + SD_TypeDef *sd_d3 = NP; + SD_TypeDef *sd_cmd = NP; + SD_TypeDef *sd_ck = NP; + + if (SD_PinNames.pin_d0 == NC) { + /* No pin defined assume to use first pin available in each PinMap_SD_* arrays */ + SD_PinNames.pin_d0 = PinMap_SD_DATA0[0].pin; + SD_PinNames.pin_d1 = PinMap_SD_DATA1[0].pin; + SD_PinNames.pin_d2 = PinMap_SD_DATA2[0].pin; + SD_PinNames.pin_d3 = PinMap_SD_DATA3[0].pin; + SD_PinNames.pin_cmd = PinMap_SD_CMD[0].pin; + SD_PinNames.pin_ck = PinMap_SD_CK[0].pin; +#if defined(SDMMC1) && defined(SDMMC2) + SD_PinNames.pin_ckin = PinMap_SD_CKIN[0].pin; + SD_PinNames.pin_cdir = PinMap_SD_CDIR[0].pin; + SD_PinNames.pin_d0dir = PinMap_SD_D0DIR[0].pin; + SD_PinNames.pin_d123dir = PinMap_SD_D123DIR[0].pin; +#endif /* SDMMC1 && SDMMC2 */ + } + /* Get SD instance from pins */ + sd_d0 = pinmap_peripheral(SD_PinNames.pin_d0, PinMap_SD_DATA0); + sd_d1 = pinmap_peripheral(SD_PinNames.pin_d1, PinMap_SD_DATA1); + sd_d2 = pinmap_peripheral(SD_PinNames.pin_d2, PinMap_SD_DATA2); + sd_d3 = pinmap_peripheral(SD_PinNames.pin_d3, PinMap_SD_DATA3); + + sd_cmd = pinmap_peripheral(SD_PinNames.pin_cmd, PinMap_SD_CMD); + sd_ck = pinmap_peripheral(SD_PinNames.pin_ck, PinMap_SD_CK); + + /* Pins Dx/cmd/CK must not be NP. */ + if (sd_d0 == NP || sd_d1 == NP || sd_d2 == NP || sd_d3 == NP || sd_cmd == NP || sd_ck == NP) { + core_debug("ERROR: at least one SD pin has no peripheral\n"); + return MSD_ERROR; + } + + SD_TypeDef *sd_d01 = pinmap_merge_peripheral(sd_d0, sd_d1); + SD_TypeDef *sd_d23 = pinmap_merge_peripheral(sd_d2, sd_d3); + SD_TypeDef *sd_cx = pinmap_merge_peripheral(sd_cmd, sd_ck); + SD_TypeDef *sd_dx = pinmap_merge_peripheral(sd_d01, sd_d23); + SD_TypeDef *sd_base = pinmap_merge_peripheral(sd_dx, sd_cx); + if (sd_d01 == NP || sd_d23 == NP || sd_cx == NP || sd_dx == NP || sd_base == NP) { + core_debug("ERROR: SD pins mismatch\n"); + return MSD_ERROR; + } + uSdHandle.Instance = sd_base; +#if defined(SDMMC1) && defined(SDMMC2) + if (SD_PinNames.pin_ckin != NC) { + SD_TypeDef *sd_ckin = pinmap_peripheral(SD_PinNames.pin_ckin, PinMap_SD_CKIN); + SD_TypeDef *sd_cdir = pinmap_peripheral(SD_PinNames.pin_cdir, PinMap_SD_CDIR); + SD_TypeDef *sd_d0dir = pinmap_peripheral(SD_PinNames.pin_d0dir, PinMap_SD_D0DIR); + SD_TypeDef *sd_d123dir = pinmap_peripheral(SD_PinNames.pin_d123dir, PinMap_SD_D123DIR); + + /* Pins Dx/cmd/CK must not be NP. */ + if (sd_ckin == NP || sd_cdir == NP || sd_d0dir == NP || sd_d123dir == NP) { + core_debug("ERROR: at least one SDMMC pin has no peripheral\n"); + return MSD_ERROR; + } + SD_TypeDef *sdmmc_cx = pinmap_merge_peripheral(sd_ckin, sd_cdir); + SD_TypeDef *sdmmc_dx = pinmap_merge_peripheral(sd_d0dir, sd_d123dir); + SD_TypeDef *sdmmc_base = pinmap_merge_peripheral(sdmmc_cx, sdmmc_dx); + if (sdmmc_cx == NP || sdmmc_dx == NP || sdmmc_base == NP) { + core_debug("ERROR: SD pins mismatch\n"); + return MSD_ERROR; + } + uSdHandle.Instance = pinmap_merge_peripheral(sd_base, sdmmc_base); + } +#endif + /* Are all pins connected to the same SDx instance? */ + if (uSdHandle.Instance == NP) { + core_debug("ERROR: SD pins mismatch\n"); + return MSD_ERROR; + } + return MSD_OK; +} +#endif /* STM32_CORE_VERSION */ /** * @brief Initializes the SD card device with CS check if any. @@ -135,7 +234,13 @@ uint8_t BSP_SD_Init(void) /* Check if SD is not yet initialized */ if (uSdHandle.State == HAL_SD_STATE_RESET) { /* uSD device interface configuration */ +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x02050000) uSdHandle.Instance = SD_INSTANCE; +#else + if (BSP_SD_GetInstance() == MSD_ERROR) { + return MSD_ERROR; + } +#endif uSdHandle.Init.ClockEdge = SD_CLK_EDGE; #if defined(SD_CLK_BYPASS) @@ -191,7 +296,13 @@ uint8_t BSP_SD_DeInit(void) { uint8_t sd_state = MSD_OK; +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x02050000) uSdHandle.Instance = SD_INSTANCE; +#else + if (BSP_SD_GetInstance() == MSD_ERROR) { + return MSD_ERROR; + } +#endif /* HAL SD deinitialization */ if (HAL_SD_DeInit(&uSdHandle) != HAL_OK) { @@ -382,14 +493,29 @@ uint8_t BSP_SD_Erase(uint64_t StartAddr, uint64_t EndAddr) __weak void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params) { UNUSED(Params); - +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x02050000) /* Configure SD GPIOs */ const PinMap *map = PinMap_SD; while (map->pin != NC) { pin_function(map->pin, map->function); map++; } - +#else + /* Configure SD GPIO pins */ + pinmap_pinout(SD_PinNames.pin_d0, PinMap_SD_DATA0); + pinmap_pinout(SD_PinNames.pin_d1, PinMap_SD_DATA1); + pinmap_pinout(SD_PinNames.pin_d2, PinMap_SD_DATA2); + pinmap_pinout(SD_PinNames.pin_d3, PinMap_SD_DATA3); + pinmap_pinout(SD_PinNames.pin_cmd, PinMap_SD_CMD); + pinmap_pinout(SD_PinNames.pin_ck, PinMap_SD_CK); +#if defined(SDMMC1) && defined(SDMMC2) + if (SD_PinNames.pin_ckin != NC) { + pinmap_pinout(SD_PinNames.pin_ckin, PinMap_SD_CKIN); + pinmap_pinout(SD_PinNames.pin_cdir, PinMap_SD_CDIR); + pinmap_pinout(SD_PinNames.pin_d0dir, PinMap_SD_D0DIR); + pinmap_pinout(SD_PinNames.pin_d123dir, PinMap_SD_D123DIR); + } +#endif /* Enable SD clock */ #if defined(SDMMC1) && defined(SDMMC2) if (hsd->Instance == SDMMC1) { @@ -401,6 +527,7 @@ __weak void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params) UNUSED(hsd); SD_CLK_ENABLE(); #endif +#endif } /** @@ -431,9 +558,30 @@ __weak void BSP_SD_Detect_MspInit(SD_HandleTypeDef *hsd, void *Params) __weak void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params) { UNUSED(Params); - /* DeInit GPIO pins can be done in the application (by surcharging this __weak function) */ +#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x02050000) + const PinMap *map = PinMap_SD; + while (map->pin != NC) { + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(map->pin), STM_GPIO_PIN(map->pin)); + map++; + } +#else + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(SD_PinNames.pin_d0), STM_GPIO_PIN(SD_PinNames.pin_d0)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(SD_PinNames.pin_d1), STM_GPIO_PIN(SD_PinNames.pin_d1)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(SD_PinNames.pin_d2), STM_GPIO_PIN(SD_PinNames.pin_d2)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(SD_PinNames.pin_d3), STM_GPIO_PIN(SD_PinNames.pin_d3)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(SD_PinNames.pin_cmd), STM_GPIO_PIN(SD_PinNames.pin_cmd)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(SD_PinNames.pin_ck), STM_GPIO_PIN(SD_PinNames.pin_ck)); +#if defined(SDMMC1) && defined(SDMMC2) + if (SD_PinNames.pin_ckin != NC) { + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(SD_PinNames.pin_ckin), STM_GPIO_PIN(SD_PinNames.pin_ckin)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(SD_PinNames.pin_cdir), STM_GPIO_PIN(SD_PinNames.pin_cdir)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(SD_PinNames.pin_d0dir), STM_GPIO_PIN(SD_PinNames.pin_d0dir)); + HAL_GPIO_DeInit((GPIO_TypeDef *)STM_PORT(SD_PinNames.pin_d123dir), STM_GPIO_PIN(SD_PinNames.pin_d123dir)); + } +#endif +#endif /* Disable SD clock */ #if defined(SDMMC1) && defined(SDMMC2) diff --git a/src/bsp_sd.h b/src/bsp_sd.h index e08e209..a651c21 100644 --- a/src/bsp_sd.h +++ b/src/bsp_sd.h @@ -44,10 +44,9 @@ extern "C" { #endif /* Includes ------------------------------------------------------------------*/ +#include "PinNames.h" #include "stm32_def.h" -#if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x01050000) #include "variant.h" -#endif #if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x01060100) #error "This library version required a STM32 core version > 1.6.1.\ Please update the core or install previous library version." @@ -91,6 +90,57 @@ Please update the core or install previous library version." #define GPIO_PIN_All GPIO_PIN_ALL #endif +/* Default SDx pins definitions */ +#ifndef SDX_D0 +#define SDX_D0 NUM_DIGITAL_PINS +#endif +#ifndef SDX_D1 +#define SDX_D1 NUM_DIGITAL_PINS +#endif +#ifndef SDX_D2 +#define SDX_D2 NUM_DIGITAL_PINS +#endif +#ifndef SDX_D3 +#define SDX_D3 NUM_DIGITAL_PINS +#endif +#ifndef SDX_CMD +#define SDX_CMD NUM_DIGITAL_PINS +#endif +#ifndef SDX_CK +#define SDX_CK NUM_DIGITAL_PINS +#endif +#if defined(SDMMC1) || defined(SDMMC2) +#ifndef SDX_CKIN +#define SDX_CKIN NUM_DIGITAL_PINS +#endif +#ifndef SDX_CDIR +#define SDX_CDIR NUM_DIGITAL_PINS +#endif +#ifndef SDX_D0DIR +#define SDX_D0DIR NUM_DIGITAL_PINS +#endif +#ifndef SDX_D123DIR +#define SDX_D123DIR NUM_DIGITAL_PINS +#endif +#endif /* SDMMC1 || SDMMC2 */ + +typedef struct { + PinName pin_d0; + PinName pin_d1; + PinName pin_d2; + PinName pin_d3; + PinName pin_cmd; + PinName pin_ck; +#if defined(SDMMC1) || defined(SDMMC2) + PinName pin_ckin; + PinName pin_cdir; + PinName pin_d0dir; + PinName pin_d123dir; +#endif +} SD_PinName_t; + +extern SD_PinName_t SD_PinNames; + /* SD Exported Functions */ uint8_t BSP_SD_Init(void); uint8_t BSP_SD_DeInit(void);