From f4bf6556d1e6471962387b5256f05bf2a5100097 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Tue, 17 Sep 2024 10:00:50 +0200 Subject: [PATCH 1/3] chore: remove BSP_SD_DetectITConfig Interrupt have to be managed using Arduino interrupt API Signed-off-by: Frederic Pillon --- src/Sd2Card.cpp | 3 +- src/bsp_sd.c | 76 +++---------------------------------------------- src/bsp_sd.h | 3 +- 3 files changed, 6 insertions(+), 76 deletions(-) diff --git a/src/Sd2Card.cpp b/src/Sd2Card.cpp index 4178f84..5b96782 100644 --- a/src/Sd2Card.cpp +++ b/src/Sd2Card.cpp @@ -57,8 +57,7 @@ bool Sd2Card::init(uint32_t detect, uint32_t level) 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), level) != MSD_OK) { + BSP_SD_DetectPin(p, level) != MSD_OK) { return false; } } diff --git a/src/bsp_sd.c b/src/bsp_sd.c index 1cabd56..d624125 100644 --- a/src/bsp_sd.c +++ b/src/bsp_sd.c @@ -381,13 +381,14 @@ uint8_t BSP_SD_TransceiverPin(GPIO_TypeDef *enport, uint32_t enpin, GPIO_TypeDef /** * @brief Set the SD card device detect pin, port and level. - * @param port one of the gpio port - * @param pin one of the gpio pin + * @param p PinName of the detect pin * @param level the level of the detect pin (HIGH or LOW) * @retval SD status */ -uint8_t BSP_SD_DetectPin(GPIO_TypeDef *port, uint32_t pin, uint32_t level) +uint8_t BSP_SD_DetectPin(PinName p, uint32_t level) { + GPIO_TypeDef *port = set_GPIO_Port_Clock(STM_PORT(p)); + uint32_t pin = STM_LL_GPIO_PIN(p); if (port != 0) { SD_detect_ll_gpio_pin = pin; SD_detect_gpio_port = port; @@ -397,75 +398,6 @@ uint8_t BSP_SD_DetectPin(GPIO_TypeDef *port, uint32_t pin, uint32_t level) return MSD_ERROR; } -/** - * @brief Configures Interrupt mode for SD detection pin. - * @retval Status - */ -uint8_t BSP_SD_DetectITConfig(void (*callback)(void)) -{ - uint8_t sd_state = MSD_ERROR; - if (SD_detect_ll_gpio_pin != LL_GPIO_PIN_ALL) { - LL_GPIO_SetPinPull(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_PULL_UP); - uint16_t SD_detect_gpio_pin = GPIO_PIN_All; - switch (SD_detect_ll_gpio_pin) { - case LL_GPIO_PIN_0: - SD_detect_gpio_pin = GPIO_PIN_0; - break; - case LL_GPIO_PIN_1: - SD_detect_gpio_pin = GPIO_PIN_1; - break; - case LL_GPIO_PIN_2: - SD_detect_gpio_pin = GPIO_PIN_2; - break; - case LL_GPIO_PIN_3: - SD_detect_gpio_pin = GPIO_PIN_3; - break; - case LL_GPIO_PIN_4: - SD_detect_gpio_pin = GPIO_PIN_4; - break; - case LL_GPIO_PIN_5: - SD_detect_gpio_pin = GPIO_PIN_5; - break; - case LL_GPIO_PIN_6: - SD_detect_gpio_pin = GPIO_PIN_6; - break; - case LL_GPIO_PIN_7: - SD_detect_gpio_pin = GPIO_PIN_7; - break; - case LL_GPIO_PIN_8: - SD_detect_gpio_pin = GPIO_PIN_8; - break; - case LL_GPIO_PIN_9: - SD_detect_gpio_pin = GPIO_PIN_9; - break; - case LL_GPIO_PIN_10: - SD_detect_gpio_pin = GPIO_PIN_10; - break; - case LL_GPIO_PIN_11: - SD_detect_gpio_pin = GPIO_PIN_11; - break; - case LL_GPIO_PIN_12: - SD_detect_gpio_pin = GPIO_PIN_12; - break; - case LL_GPIO_PIN_13: - SD_detect_gpio_pin = GPIO_PIN_13; - break; - case LL_GPIO_PIN_14: - SD_detect_gpio_pin = GPIO_PIN_14; - break; - case LL_GPIO_PIN_15: - SD_detect_gpio_pin = GPIO_PIN_15; - break; - default: - Error_Handler(); - break; - } - stm32_interrupt_enable(SD_detect_gpio_port, SD_detect_gpio_pin, callback, GPIO_MODE_IT_RISING_FALLING); - sd_state = MSD_OK; - } - return sd_state; -} - /** * @brief Detects if SD card is correctly plugged in the memory slot or not. * @retval Returns if SD is detected or not diff --git a/src/bsp_sd.h b/src/bsp_sd.h index e964403..bf95f49 100644 --- a/src/bsp_sd.h +++ b/src/bsp_sd.h @@ -174,8 +174,7 @@ uint8_t BSP_SD_DeInit(void); #if defined(USE_SD_TRANSCEIVER) && (USE_SD_TRANSCEIVER != 0U) uint8_t BSP_SD_TransceiverPin(GPIO_TypeDef *enport, uint32_t enpin, GPIO_TypeDef *selport, uint32_t selpin); #endif -uint8_t BSP_SD_DetectPin(GPIO_TypeDef *port, uint32_t pin, uint32_t level); -uint8_t BSP_SD_DetectITConfig(void (*callback)(void)); +uint8_t BSP_SD_DetectPin(PinName p, uint32_t level); uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout); uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout); uint8_t BSP_SD_Erase(uint64_t StartAddr, uint64_t EndAddr); From 063cdab88a8552f0eb6f996ffb07e3302e31a4ad Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Tue, 24 Sep 2024 17:05:00 +0200 Subject: [PATCH 2/3] chore: add end() method Fixes #71 Signed-off-by: Frederic Pillon --- src/SD.cpp | 14 +++++++ src/STM32SD.h | 2 + src/Sd2Card.cpp | 8 ++++ src/Sd2Card.h | 1 + src/SdFatFs.cpp | 13 +++++++ src/SdFatFs.h | 1 + src/bsp_sd.c | 101 +++++++++++++++++++++++++++++++++++++----------- src/bsp_sd.h | 4 +- 8 files changed, 121 insertions(+), 23 deletions(-) diff --git a/src/SD.cpp b/src/SD.cpp index d22ddec..f220f47 100644 --- a/src/SD.cpp +++ b/src/SD.cpp @@ -72,6 +72,20 @@ bool SDClass::begin(uint32_t detect, uint32_t level) return false; } +/** + * @brief UnLink SD, unregister the file system object and unconfigure + * relatives SD IOs including SD Detect Pin and level if any + * @retval true or false + */ +bool SDClass::end(void) +{ + /*##-1- DeInitializes SD IOs ###########################################*/ + if (_fatFs.deinit()) { + return _card.deinit(); + } + return false; +} + /** * @brief Check if a file or folder exist on the SD disk * @param filename: File name diff --git a/src/STM32SD.h b/src/STM32SD.h index 9b7f451..ed52396 100644 --- a/src/STM32SD.h +++ b/src/STM32SD.h @@ -87,6 +87,8 @@ class SDClass { public: /* Initialize the SD peripheral */ bool begin(uint32_t detect = SD_DETECT_NONE, uint32_t level = SD_DETECT_LEVEL); + /* Call this when a card is removed. It will allow to insert and initialise a new card. */ + bool end(void); // set* have to be called before begin() void setDx(uint32_t data0, uint32_t data1 = PNUM_NOT_DEFINED, uint32_t data2 = PNUM_NOT_DEFINED, uint32_t data3 = PNUM_NOT_DEFINED) diff --git a/src/Sd2Card.cpp b/src/Sd2Card.cpp index 5b96782..0b06b17 100644 --- a/src/Sd2Card.cpp +++ b/src/Sd2Card.cpp @@ -78,6 +78,14 @@ bool Sd2Card::init(uint32_t detect, uint32_t level) return false; } +bool Sd2Card::deinit(void) +{ + if (BSP_SD_DeInit() == MSD_OK) { + return true; + } + return false; +} + uint8_t Sd2Card::type(void) const { uint8_t cardType = SD_CARD_TYPE_UKN; diff --git a/src/Sd2Card.h b/src/Sd2Card.h index 2dfbd5f..69d6818 100644 --- a/src/Sd2Card.h +++ b/src/Sd2Card.h @@ -55,6 +55,7 @@ class Sd2Card { Sd2Card(); bool init(uint32_t detect = SD_DETECT_NONE, uint32_t level = SD_DETECT_LEVEL); + bool deinit(void); // set* have to be called before init() void setDx(uint32_t data0, uint32_t data1 = PNUM_NOT_DEFINED, uint32_t data2 = PNUM_NOT_DEFINED, uint32_t data3 = PNUM_NOT_DEFINED) diff --git a/src/SdFatFs.cpp b/src/SdFatFs.cpp index 9dea4bd..c59c6cc 100644 --- a/src/SdFatFs.cpp +++ b/src/SdFatFs.cpp @@ -51,6 +51,19 @@ bool SdFatFs::init(void) return false; } +bool SdFatFs::deinit(void) +{ + /*##-1- Unregister the file system object to the FatFs module ##############*/ + if (f_unmount((TCHAR const *)_SDPath) == FR_OK) { + /*##-2- Unlink the SD disk I/O driver ####################################*/ + if (FATFS_UnLinkDriver(_SDPath) == 0) { + /* FatFs deInitialization done */ + return true; + } + } + return false; +} + uint8_t SdFatFs::fatType(void) { switch (_SDFatFs.fs_type) { diff --git a/src/SdFatFs.h b/src/SdFatFs.h index fdef3ba..6f7be73 100644 --- a/src/SdFatFs.h +++ b/src/SdFatFs.h @@ -82,6 +82,7 @@ class SdFatFs { public: bool init(void); + bool deinit(void); /** Return the FatFs type: 12, 16, 32 (0: unknown)*/ uint8_t fatType(void); diff --git a/src/bsp_sd.c b/src/bsp_sd.c index d624125..59d813f 100644 --- a/src/bsp_sd.c +++ b/src/bsp_sd.c @@ -354,6 +354,15 @@ uint8_t BSP_SD_DeInit(void) /* Msp SD deinitialization */ BSP_SD_MspDeInit(&uSdHandle, NULL); + + if (SD_detect_ll_gpio_pin != LL_GPIO_PIN_ALL) { + BSP_SD_Detect_MspDeInit(&uSdHandle, NULL); + } +#if defined(USE_SD_TRANSCEIVER) && (USE_SD_TRANSCEIVER != 0U) + BSP_SD_Transceiver_MspDeInit(&uSdHandle, NULL); +#endif + + return sd_state; } @@ -523,26 +532,6 @@ __weak void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params) #endif } -/** - * @brief Initializes the SD Detect pin MSP. - * @param hsd: SD handle - * @param Params : pointer on additional configuration parameters, can be NULL. - */ -__weak void BSP_SD_Detect_MspInit(SD_HandleTypeDef *hsd, void *Params) -{ - UNUSED(hsd); - UNUSED(Params); - - /* GPIO configuration in input for uSD_Detect signal */ -#ifdef LL_GPIO_SPEED_FREQ_VERY_HIGH - LL_GPIO_SetPinSpeed(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_SPEED_FREQ_VERY_HIGH); -#else - LL_GPIO_SetPinSpeed(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_SPEED_FREQ_HIGH); -#endif - LL_GPIO_SetPinMode(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_MODE_INPUT); - LL_GPIO_SetPinPull(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_PULL_UP); -} - /** * @brief DeInitializes the SD MSP. * @param hsd: SD handle @@ -608,6 +597,47 @@ __weak void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params) #endif } +/** + * @brief Initializes the SD Detect pin MSP. + * @param hsd: SD handle + * @param Params : pointer on additional configuration parameters, can be NULL. + */ +__weak void BSP_SD_Detect_MspInit(SD_HandleTypeDef *hsd, void *Params) +{ + UNUSED(hsd); + UNUSED(Params); + + /* GPIO configuration in input for uSD_Detect signal */ +#ifdef LL_GPIO_SPEED_FREQ_VERY_HIGH + LL_GPIO_SetPinSpeed(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_SPEED_FREQ_VERY_HIGH); +#else + LL_GPIO_SetPinSpeed(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_SPEED_FREQ_HIGH); +#endif + LL_GPIO_SetPinMode(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_MODE_INPUT); + LL_GPIO_SetPinPull(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_PULL_UP); +} + +/** + * @brief DeInitializes the SD Detect pin MSP. + * @param hsd: SD handle + * @param Params : pointer on additional configuration parameters, can be NULL. + */ +__weak void BSP_SD_Detect_MspDeInit(SD_HandleTypeDef *hsd, void *Params) +{ + UNUSED(hsd); + UNUSED(Params); + + /* GPIO configuration in analog to saves the consumption */ + LL_GPIO_SetPinSpeed(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_SPEED_FREQ_LOW); +#ifndef LL_GPIO_PULL_NO + /* For STM32F1xx */ + LL_GPIO_SetPinPull(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_MODE_FLOATING); +#else + LL_GPIO_SetPinPull(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_PULL_NO); +#endif + LL_GPIO_SetPinMode(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_MODE_ANALOG); +} + #if defined(USE_SD_TRANSCEIVER) && (USE_SD_TRANSCEIVER != 0U) /** * @brief Initializes the SD Transceiver pin MSP. @@ -621,12 +651,20 @@ __weak void BSP_SD_Transceiver_MspInit(SD_HandleTypeDef *hsd, void *Params) LL_GPIO_SetPinSpeed(SD_trans_en_gpio_port, SD_trans_en_ll_gpio_pin, LL_GPIO_SPEED_FREQ_HIGH); LL_GPIO_SetPinMode(SD_trans_en_gpio_port, SD_trans_en_ll_gpio_pin, LL_GPIO_MODE_OUTPUT); +#ifndef LL_GPIO_PULL_NO + /* For STM32F1xx */ + LL_GPIO_SetPinPull(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_MODE_FLOATING); +#else LL_GPIO_SetPinPull(SD_trans_en_gpio_port, SD_trans_en_ll_gpio_pin, LL_GPIO_PULL_NO); - +#endif LL_GPIO_SetPinSpeed(SD_trans_sel_gpio_port, SD_trans_sel_ll_gpio_pin, LL_GPIO_SPEED_FREQ_HIGH); LL_GPIO_SetPinMode(SD_trans_sel_gpio_port, SD_trans_sel_ll_gpio_pin, LL_GPIO_MODE_OUTPUT); +#ifndef LL_GPIO_PULL_NO + /* For STM32F1xx */ + LL_GPIO_SetPinPull(SD_detect_gpio_port, SD_detect_ll_gpio_pin, LL_GPIO_MODE_FLOATING); +#else LL_GPIO_SetPinPull(SD_trans_sel_gpio_port, SD_trans_sel_ll_gpio_pin, LL_GPIO_PULL_NO); - +#endif /* Enable the level shifter */ LL_GPIO_SetOutputPin(SD_trans_en_gpio_port, SD_trans_en_ll_gpio_pin); @@ -634,6 +672,25 @@ __weak void BSP_SD_Transceiver_MspInit(SD_HandleTypeDef *hsd, void *Params) LL_GPIO_ResetOutputPin(SD_trans_sel_gpio_port, SD_trans_sel_ll_gpio_pin); } +/** + * @brief DeInitializes the SD Transceiver pin MSP. + * @param hsd: SD handle + * @param Params : pointer on additional configuration parameters, can be NULL. + */ +__weak void BSP_SD_Transceiver_MspDeInit(SD_HandleTypeDef *hsd, void *Params) +{ + UNUSED(hsd); + UNUSED(Params); + + LL_GPIO_SetPinSpeed(SD_trans_en_gpio_port, SD_trans_en_ll_gpio_pin, LL_GPIO_SPEED_FREQ_LOW); + LL_GPIO_SetPinMode(SD_trans_en_gpio_port, SD_trans_en_ll_gpio_pin, LL_GPIO_MODE_ANALOG); + LL_GPIO_SetPinPull(SD_trans_en_gpio_port, SD_trans_en_ll_gpio_pin, LL_GPIO_PULL_NO); + + LL_GPIO_SetPinSpeed(SD_trans_sel_gpio_port, SD_trans_sel_ll_gpio_pin, LL_GPIO_SPEED_FREQ_LOW); + LL_GPIO_SetPinMode(SD_trans_sel_gpio_port, SD_trans_sel_ll_gpio_pin, LL_GPIO_MODE_ANALOG); + LL_GPIO_SetPinPull(SD_trans_sel_gpio_port, SD_trans_sel_ll_gpio_pin, LL_GPIO_PULL_NO); +} + /** * @brief Enable/Disable the SD Transceiver 1.8V Mode Callback. * @param status: Voltage Switch State diff --git a/src/bsp_sd.h b/src/bsp_sd.h index bf95f49..3828ee6 100644 --- a/src/bsp_sd.h +++ b/src/bsp_sd.h @@ -185,10 +185,12 @@ uint8_t BSP_SD_IsDetected(void); /* These __weak function can be surcharged by application code in case the current settings (e.g. DMA stream) need to be changed for specific needs */ void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params); -void BSP_SD_Detect_MspInit(SD_HandleTypeDef *hsd, void *Params); void BSP_SD_MspDeInit(SD_HandleTypeDef *hsd, void *Params); +void BSP_SD_Detect_MspInit(SD_HandleTypeDef *hsd, void *Params); +void BSP_SD_Detect_MspDeInit(SD_HandleTypeDef *hsd, void *Params); #if defined(USE_SD_TRANSCEIVER) && (USE_SD_TRANSCEIVER != 0U) void BSP_SD_Transceiver_MspInit(SD_HandleTypeDef *hsd, void *Params); +void BSP_SD_Transceiver_MspDeInit(SD_HandleTypeDef *hsd, void *Params); #endif #ifdef __cplusplus From 68b1357eb8a8f008ac4b498c62238027e86e8ded Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 26 Sep 2024 09:30:33 +0200 Subject: [PATCH 3/3] chore(examples): add end() API Signed-off-by: Frederic Pillon --- examples/CardInfo/CardInfo.ino | 21 +- examples/Datalogger/Datalogger.ino | 15 +- examples/DumpFile/DumpFile.ino | 14 +- examples/Files/Files.ino | 24 +-- examples/Full/Full.ino | 313 ++++++++++++----------------- examples/ReadWrite/ReadWrite.ino | 14 +- examples/listfiles/listfiles.ino | 76 +++---- 7 files changed, 209 insertions(+), 268 deletions(-) diff --git a/examples/CardInfo/CardInfo.ino b/examples/CardInfo/CardInfo.ino index 02c210b..cdc8e4d 100644 --- a/examples/CardInfo/CardInfo.ino +++ b/examples/CardInfo/CardInfo.ino @@ -20,15 +20,15 @@ Sd2Card card; SdFatFs fatFs; -void setup() -{ +void setup() { bool disp = false; // Open serial communications and wait for port to open: Serial.begin(9600); - while (!Serial); + while (!Serial) + ; Serial.print("\nInitializing SD card..."); - while(!card.init(SD_DETECT_PIN)) { + while (!card.init(SD_DETECT_PIN)) { if (!disp) { Serial.println("initialization failed. Is a card inserted?"); disp = true; @@ -66,9 +66,9 @@ void setup() Serial.println(fatFs.fatType(), DEC); Serial.println(); - volumesize = fatFs.blocksPerCluster(); // clusters are collections of blocks - volumesize *= fatFs.clusterCount(); // we'll have a lot of clusters - volumesize *= 512; // SD card blocks are always 512 bytes + volumesize = fatFs.blocksPerCluster(); // clusters are collections of blocks + volumesize *= fatFs.clusterCount(); // we'll have a lot of clusters + volumesize *= 512; // SD card blocks are always 512 bytes Serial.print("Volume size (bytes): "); Serial.println(volumesize); Serial.print("Volume size (Kbytes): "); @@ -85,6 +85,13 @@ void setup() // list all files in the card with date and size root.ls(LS_R | LS_DATE | LS_SIZE); root.close(); + if (!fatFs.deinit()) { + Serial.println("Failed to deinit card"); + } + if (!card.deinit()) { + Serial.println("Failed to deinit card"); + } + Serial.println("###### End of the SD tests ######"); } diff --git a/examples/Datalogger/Datalogger.ino b/examples/Datalogger/Datalogger.ino index 515ce17..7604c2a 100644 --- a/examples/Datalogger/Datalogger.ino +++ b/examples/Datalogger/Datalogger.ino @@ -18,22 +18,20 @@ #define SD_DETECT_PIN SD_DETECT_NONE #endif -uint32_t A[] = { A0, A1, A2}; +uint32_t A[] = { A0, A1, A2 }; File dataFile; -void setup() -{ +void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only + ; // wait for serial port to connect. Needed for Leonardo only } Serial.print("Initializing SD card..."); // see if the card is present and can be initialized: - while (!SD.begin(SD_DETECT_PIN)) - { + while (!SD.begin(SD_DETECT_PIN)) { delay(10); } delay(100); @@ -52,8 +50,7 @@ void setup() } } -void loop() -{ +void loop() { // make a string for assembling the data to log: String dataString = ""; @@ -70,7 +67,7 @@ void loop() // if the file is available, write to it: if (dataFile) { dataFile.println(dataString); - dataFile.flush(); // use flush to ensure the data written + dataFile.flush(); // use flush to ensure the data written // print to the serial port too: Serial.println(dataString); } diff --git a/examples/DumpFile/DumpFile.ino b/examples/DumpFile/DumpFile.ino index 41a755e..2927b65 100644 --- a/examples/DumpFile/DumpFile.ino +++ b/examples/DumpFile/DumpFile.ino @@ -19,19 +19,17 @@ #define SD_DETECT_PIN SD_DETECT_NONE #endif -void setup() -{ +void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only + ; // wait for serial port to connect. Needed for Leonardo only } Serial.print("Initializing SD card..."); // see if the card is present and can be initialized: - while (!SD.begin(SD_DETECT_PIN)) - { + while (!SD.begin(SD_DETECT_PIN)) { delay(10); } delay(100); @@ -52,9 +50,11 @@ void setup() else { Serial.println("error opening datalog.txt"); } + if (!SD.end()) { + Serial.println("Failed to properly end the SD."); + } Serial.println("###### End of the SD tests ######"); } -void loop() -{ +void loop() { } diff --git a/examples/Files/Files.ino b/examples/Files/Files.ino index 73503d8..8413439 100644 --- a/examples/Files/Files.ino +++ b/examples/Files/Files.ino @@ -18,40 +18,37 @@ File myFile; -void setup() -{ +void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only + ; // wait for serial port to connect. Needed for Leonardo only } Serial.print("Initializing SD card..."); - while (!SD.begin(SD_DETECT_PIN)) - { + while (!SD.begin(SD_DETECT_PIN)) { delay(10); } Serial.println("initialization done."); if (SD.exists("example.txt")) { Serial.println("example.txt exists."); - } - else { + } else { Serial.println("example.txt doesn't exist."); } // open a new file and immediately close it: Serial.println("Creating example.txt..."); + Serial.flush(); myFile = SD.open("example.txt", FILE_WRITE); myFile.close(); // Check to see if the file exists: if (SD.exists("example.txt")) { Serial.println("example.txt exists."); - } - else { + } else { Serial.println("example.txt doesn't exist."); } @@ -61,14 +58,15 @@ void setup() if (SD.exists("example.txt")) { Serial.println("example.txt exists."); - } - else { + } else { Serial.println("example.txt doesn't exist."); } + if (!SD.end()) { + Serial.println("Failed to properly end the SD."); + } Serial.println("###### End of the SD tests ######"); } -void loop() -{ +void loop() { // nothing happens after setup finishes. } diff --git a/examples/Full/Full.ino b/examples/Full/Full.ino index 01124c1..39b7c2c 100644 --- a/examples/Full/Full.ino +++ b/examples/Full/Full.ino @@ -6,244 +6,199 @@ #define SD_DETECT_PIN SD_DETECT_NONE #endif -#define COUNTOF(__BUFFER__) (sizeof(__BUFFER__) / sizeof(*(__BUFFER__))) -#define BUFFERSIZE (COUNTOF(wtext) -1) +#define COUNTOF(__BUFFER__) (sizeof(__BUFFER__) / sizeof(*(__BUFFER__))) +#define BUFFERSIZE (COUNTOF(wtext) - 1) uint32_t file_size = 0, seek_val = false, peek_val = 0; uint32_t byteswritten, bytesread = 0; /* File write buffer */ -uint8_t wtext[] = "This is the Arduino SD Test working with FatFs."; -/* File read buffer */ -uint8_t rtext[BUFFERSIZE]; +const char wtext[] = "This is the Arduino SD Test working with FatFs."; +/* File read buffer including extra "\n\0" */ +char rtext[BUFFERSIZE + 2] = { '\0' }; uint32_t i = 0; bool isdir = false; File MyFile; -void setup() -{ +typedef struct { + const char* tst; + const char* err; + bool res; +} result_t; + + +result_t aResult[] = { + { .tst = "Creating 'STM32' directory...", .err = NULL, .res = false }, + { .tst = "Creating 'ARDUINO' directory...", .err = NULL, .res = false }, + { .tst = "Creating 'ARDUINO/SD' directory...", .err = NULL, .res = false }, + { .tst = "Test bool operator...", .err = "Error MyFile should not be initialized!", .res = false }, + { .tst = "Opening 'STM32/Toremove.txt' file...", .err = "Error to open 'STM32/Toremove.txt' file.", .res = false }, + { .tst = "Opening 'ARDUINO/SD/ARDUINO_SD_TEXT.txt' file...", .err = "Error to open 'ARDUINO/SD/ARDUINO_SD_TEXT.txt' file", .res = false }, + { .tst = " Writing `This is the Arduino SD Test working with FatFs.` into ARDUINO_SD_TEXT.txt file...", .err = NULL, .res = false }, + { .tst = "Opening 'ARDUINO/SD/ARDUINO_SD_TEXT.txt' file...", .err = "Error to open 'ARDUINO/SD/ARDUINO_SD_TEXT.txt' file", .res = false }, + { .tst = " Reading ARDUINO/SD/ARDUINO_SD_TEXT.txt file...", .err = NULL, .res = false }, + { .tst = "Opening 'ARDUINO/SD/TEXT.txt' file...", .err = "Error to open 'ARDUINO/SD/TEXT.txt' file", .res = false }, + { .tst = " Writing and flush `This is the Arduino SD Test working with FatFs.` into ARDUINO/SD/TEXT.txt file...", .err = NULL, .res = false }, + { .tst = "Opening 'ARDUINO/SD/TEXT.txt' file...", .err = "Error to open 'ARDUINO/SD/TEXT.txt' file", .res = false }, + { .tst = " TEXT.txt size:", .err = NULL, .res = false }, + { .tst = " TEXT.txt position value:", .err = NULL, .res = false }, + { .tst = " TEXT.txt seek value over size:", .err = NULL, .res = false }, + { .tst = " TEXT.txt seek value to size:", .err = NULL, .res = false }, + { .tst = " TEXT.txt position value: ", .err = NULL, .res = false }, + { .tst = " TEXT.txt seek value to 0: ", .err = NULL, .res = false }, + { .tst = " TEXT.txt position value: ", .err = NULL, .res = false }, + { .tst = " TEXT.txt peek (10 times): ", .err = NULL, .res = false }, + { .tst = " TEXT.txt content read byte per byte: ", .err = NULL, .res = false }, + { .tst = "Opening 'STM32' dir...", .err = "Error to open 'STM32' dir", .res = false }, + { .tst = "Is 'STM32' is a dir...", .err = NULL, .res = false }, + { .tst = "Opening 'STM32/Toremove.txt' file...", .err = "Error to open 'STM32/Toremove.txt' file", .res = false }, + { .tst = " Is 'STM32/Toremove.txt' is a file: ", .err = NULL, .res = false }, + { .tst = "Removing 'STM32/Toremove.txt' file...", .err = NULL, .res = false }, + { .tst = "Removing 'STM32' dir...", .err = NULL, .res = false }, + { .tst = "Opening 'ARDUINO/SD/PRINT.txt' file...", .err = "Error to open 'ARDUINO/SD/PRINT.txt' file", .res = false }, + { .tst = " Printing to 'ARDUINO/SD/PRINT.txt' file...", .err = NULL, .res = false }, + { .tst = "Opening 'ARDUINO/SD/WRITE.txt' file...", .err = "Error to open 'ARDUINO/SD/WRITE.txt' file", .res = false }, + { .tst = " Writing 'ARDUINO/SD/WRITE.txt' file: ", .err = NULL, .res = false }, + { .tst = "Opening 'ARDUINO/SD/WRITE.txt' file...", .err = "Error to open 'ARDUINO/SD/WRITE.txt' file", .res = false }, + { .tst = " Reading 'ARDUINO/SD/WRITE.txt' file: ", .err = NULL, .res = false }, + { .tst = "Opening 'ARDUINO/SD/WRITE.txt' file...", .err = "Error to open 'ARDUINO/SD/WRITE.txt' file", .res = false }, + { .tst = " Reading 'ARDUINO/SD/WRITE.txt' file: ", .err = NULL, .res = false }, + { .tst = "End SD access...", .err = NULL, .res = false }, +}; + +void setup() { + uint32_t idx = 0; + Serial.begin(9600); - while (!Serial); + while (!Serial) + ; /* Test begin() method */ - while (!SD.begin(SD_DETECT_PIN)) - { + while (!SD.begin(SD_DETECT_PIN)) { delay(10); } delay(100); /* Test mkdir() method */ - Serial.print("Creating 'STM32' directory..."); - if (SD.mkdir("STM32")) { - Serial.println("OK"); - } else { - Serial.println("KO"); - } - Serial.print("Creating 'ARDUINO' directory..."); - if (SD.mkdir("ARDUINO")) { - Serial.println("OK"); - } else { - Serial.println("KO"); - } - Serial.print("Creating 'ARDUINO/SD' directory..."); - if (SD.mkdir("ARDUINO/SD")) { - Serial.println("OK"); - } else { - Serial.println("KO"); - } + aResult[idx++].res = SD.mkdir("STM32"); + aResult[idx++].res = SD.mkdir("ARDUINO"); + aResult[idx++].res = SD.mkdir("ARDUINO/SD"); /* Test bool operator method */ - Serial.print("Test bool operator..."); - if (!MyFile) { - Serial.println("OK"); - } else { - Serial.println("KO --> Error MyFile should not be initialized!"); - } + aResult[idx++].res = !MyFile; /* Test open() method */ - Serial.print("Opening 'STM32/Toremove.txt' file..."); MyFile = SD.open("STM32/Toremove.txt", FILE_WRITE); if (MyFile) { - Serial.println("OK"); - Serial.print("Closing 'STM32/Toremove.txt' file..."); + aResult[idx++].res = true; MyFile.close(); - Serial.println("OK"); } else { - Serial.println("KO --> Error to open 'STM32/Toremove.txt' file"); + idx += 1; } - Serial.print("Opening 'ARDUINO/SD/ARDUINO_SD_TEXT.txt' file..."); + MyFile = SD.open("ARDUINO/SD/ARDUINO_SD_TEXT.txt", FILE_WRITE); if (MyFile) { - Serial.println("OK"); + aResult[idx++].res = true; /* Test print() method */ - Serial.print(" writing \""); - Serial.print((const char*)wtext); - Serial.print("\" into ARDUINO_SD_TEXT.txt file..."); - byteswritten = MyFile.print((const char*)wtext); + byteswritten = MyFile.print(wtext); byteswritten += MyFile.print("\n"); - Serial.print(byteswritten, DEC); - Serial.println(" bytes written."); - Serial.print("Closing 'ARDUINO/SD/ARDUINO_SD_TEXT.txt' file..."); + aResult[idx++].res = (byteswritten == (BUFFERSIZE + 1)); MyFile.close(); - Serial.println("OK"); } else { - Serial.println("KO --> Error to open 'ARDUINO/SD/ARDUINO_SD_TEXT.txt' file"); + idx += 2; } - Serial.print("Opening 'ARDUINO/SD/ARDUINO_SD_TEXT.txt' file..."); MyFile = SD.open("ARDUINO/SD/ARDUINO_SD_TEXT.txt"); if (MyFile) { - Serial.println("OK"); - Serial.print(" reading ARDUINO/SD/ARDUINO_SD_TEXT.txt file..."); + aResult[idx++].res = true; bytesread = MyFile.read(rtext, MyFile.size()); - Serial.print(bytesread, DEC); - Serial.println(" bytes read."); - Serial.print("Closing 'ARDUINO/SD/ARDUINO_SD_TEXT.txt' file..."); + aResult[idx++].res = (bytesread == (BUFFERSIZE + 1)); MyFile.close(); - Serial.println("OK"); } else { - Serial.println("KO -- > Error to open 'ARDUINO/SD/ARDUINO_SD_TEXT.txt' file"); + idx += 2; } - Serial.print("Opening 'ARDUINO/SD/TEXT.txt' file..."); MyFile = SD.open("ARDUINO/SD/TEXT.txt", FILE_WRITE); if (MyFile) { - Serial.println("OK"); - Serial.print(" writing and flush \""); - Serial.print((const char*)rtext); - Serial.print("\" into ARDUINO/SD/TEXT.txt file..."); - byteswritten = MyFile.print((const char*)rtext); + aResult[idx++].res = true; + byteswritten = MyFile.print(rtext); MyFile.flush(); - Serial.print(byteswritten, DEC); - Serial.println(" bytes written."); - Serial.print("Closing 'ARDUINO/SD/TEXT.txt' file..."); + aResult[idx++].res = (byteswritten == (BUFFERSIZE + 1)); MyFile.close(); - Serial.println("OK"); } else { - Serial.println("KO --> Error to open 'ARDUINO/SD/TEXT.txt' file"); + idx += 2; } - Serial.print("Opening 'ARDUINO/SD/TEXT.txt' file..."); MyFile = SD.open("ARDUINO/SD/TEXT.txt"); if (MyFile) { - Serial.println("OK"); + aResult[idx++].res = true; /* Test size() method */ file_size = MyFile.size(); - Serial.print(" TEXT.txt size: "); - Serial.println(file_size); - + aResult[idx++].res = (file_size == (BUFFERSIZE + 1)); /* Test position and seek method */ - Serial.print(" TEXT.txt position value: "); - Serial.println(MyFile.position()); - Serial.print(" TEXT.txt seek value over size: "); - if (!MyFile.seek(MyFile.size() + 1)) { - Serial.println("OK"); - } else { - Serial.println("KO"); - } - Serial.print(" TEXT.txt seek value to size: "); - if (MyFile.seek(MyFile.size())) { - Serial.println("OK"); - } else { - Serial.println("KO"); - } - Serial.print(" TEXT.txt position value: "); - Serial.println(MyFile.position()); - Serial.print(" TEXT.txt seek value to 0: "); - if (MyFile.seek(0)) { - Serial.println("OK"); - } else { - Serial.println("KO"); - } - Serial.print(" TEXT.txt position value: "); - Serial.println(MyFile.position()); + aResult[idx++].res = (MyFile.position() == 0); + aResult[idx++].res = !MyFile.seek(MyFile.size() + 1); + aResult[idx++].res = MyFile.seek(MyFile.size()); + aResult[idx++].res = (MyFile.position() == (BUFFERSIZE + 1)); + aResult[idx++].res = MyFile.seek(0); + aResult[idx++].res = (MyFile.position() == 0); /* Test peek() method */ - Serial.println(" TEXT.txt peek (10 times): "); - for (i = 0; i < 10; i++) - { - peek_val = MyFile.peek(); - Serial.print(" "); - Serial.print(peek_val); - Serial.print(" '"); - Serial.write(peek_val); - Serial.println("'"); + aResult[idx].res = true; + for (i = 0; i < 10; i++) { + if (MyFile.peek() != wtext[0]) { + aResult[idx].res = false; + } } i = 0; + idx++; /* Test available() and read() methods */ - Serial.println(" TEXT.txt content read byte per byte: "); - while (MyFile.available()) - { - rtext[i] = (uint8_t)MyFile.read(); - Serial.print(" "); - Serial.print(rtext[i]); - Serial.print(" '"); - Serial.write(rtext[i]); - Serial.println("'"); - i++; + /* skip '\n' */ + aResult[idx].res = true; + while (MyFile.available() - 1) { + if (MyFile.read() != wtext[i++]) { + aResult[idx].res = false; + } } - /* Test close method */ - Serial.print("Closing 'ARDUINO/SD/TEXT.txt' file..."); + idx++; MyFile.close(); - Serial.println("OK"); } else { - Serial.println("KO --> Error to open 'ARDUINO/SD/TEXT.txt' file"); + idx += 10; } /* Test isDirectory() method */ - Serial.print("Opening 'STM32' dir..."); MyFile = SD.open("STM32"); if (MyFile) { - Serial.println("OK"); - Serial.print("Is 'STM32' is a dir..."); - if (MyFile.isDirectory()) { - Serial.println("OK"); - } else { - Serial.println("KO"); - } + aResult[idx++].res = true; + aResult[idx++].res = MyFile.isDirectory(); MyFile.close(); } else { - Serial.println("KO --> Error to open 'STM32' dir"); + idx += 2; } - Serial.print("Opening 'STM32/Toremove.txt' file..."); MyFile = SD.open("STM32/Toremove.txt"); if (MyFile) { - Serial.println("OK"); - Serial.print(" Is 'STM32/Toremove.txt' is a file: "); - if (MyFile.isDirectory()) { - Serial.println("KO"); - } else { - Serial.println("OK"); - } - Serial.print("Closing 'STM32/Toremove.txt' file..."); + aResult[idx++].res = true; + aResult[idx++].res = !MyFile.isDirectory(); MyFile.close(); - Serial.println("OK"); } else { - Serial.println("KO --> Error to open 'STM32/Toremove.txt' file"); + idx += 2; } /* Test exists(), remove() and rmdir() methods */ - Serial.print("Removing 'STM32/Toremove.txt' file..."); - while (SD.exists("STM32/Toremove.txt") == true) - { + while (SD.exists("STM32/Toremove.txt") == true) { SD.remove("STM32/Toremove.txt"); } - Serial.println("OK"); - - Serial.print("Removing 'STM32' dir..."); - while (SD.exists("STM32") == true) - { + aResult[idx++].res = true; + while (SD.exists("STM32") == true) { SD.rmdir("STM32"); } - Serial.println("OK"); + aResult[idx++].res = true; /* Test println(), println(data) methods */ - Serial.print("Opening 'ARDUINO/SD/PRINT.txt' file..."); MyFile = SD.open("ARDUINO/SD/PRINT.txt", FILE_WRITE); if (MyFile) { - Serial.println("OK"); + aResult[idx++].res = true; String str = String("This is a String object on line 7"); - Serial.print(" Printing to 'ARDUINO/SD/PRINT.txt' file..."); MyFile.println("This should be line 1"); MyFile.println(); MyFile.println("This should be line 3"); @@ -253,69 +208,53 @@ void setup() MyFile.println(str); MyFile.print("This should be line "); MyFile.println(8); - Serial.println("OK"); - Serial.print("Closing 'ARDUINO/SD/PRINT.txt' file"); - Serial.println("OK"); + aResult[idx++].res = (MyFile.size() == 154); MyFile.close(); } else { - Serial.println("KO --> Error to open 'ARDUINO/SD/PRINT.txt' file"); + idx += 2; } /* Test write(buf, len) method */ - Serial.print("Opening 'ARDUINO/SD/WRITE.txt' file..."); MyFile = SD.open("ARDUINO/SD/WRITE.txt", FILE_WRITE); if (MyFile) { - Serial.println("OK"); - Serial.print(" Writing 'ARDUINO/SD/WRITE.txt' file: "); - byteswritten = MyFile.write(wtext, BUFFERSIZE); - Serial.print(byteswritten); - Serial.println(" bytes written"); - Serial.print("Closing 'ARDUINO/SD/WRITE.txt' file"); + aResult[idx++].res = true; + aResult[idx++].res = (MyFile.write(wtext, BUFFERSIZE) == BUFFERSIZE); MyFile.close(); - Serial.println("OK"); } else { - Serial.println("KO --> Error to open 'ARDUINO/SD/WRITE.txt' file"); + idx += 2; } /* Test read(buf, len) method */ - Serial.print("Opening 'ARDUINO/SD/WRITE.txt' file..."); MyFile = SD.open("ARDUINO/SD/WRITE.txt"); if (MyFile) { - Serial.println("OK"); - Serial.print(" Reading 'ARDUINO/SD/WRITE.txt' file: "); + aResult[idx++].res = true; bytesread = MyFile.read(rtext, MyFile.size()); - Serial.print(bytesread); - Serial.println(" bytes read"); - Serial.println((const char*)rtext); - Serial.print("Closing 'ARDUINO/SD/WRITE.txt' file..."); + aResult[idx++].res = (MyFile.size() == bytesread); MyFile.close(); - Serial.println("OK"); } else { - Serial.println("KO --> Error to open 'ARDUINO/SD/WRITE.txt' file"); + idx += 2; } /* Test readBytes(buf, len) method */ - Serial.print("Opening 'ARDUINO/SD/WRITE.txt' file..."); MyFile = SD.open("ARDUINO/SD/WRITE.txt"); if (MyFile) { - Serial.println("OK"); - Serial.print(" Reading 'ARDUINO/SD/WRITE.txt' file: "); + aResult[idx++].res = true; bytesread = MyFile.readBytes(rtext, MyFile.size()); - Serial.print(bytesread); - Serial.println(" bytes read"); - Serial.println((const char*)rtext); - Serial.print("Closing 'ARDUINO/SD/WRITE.txt' file..."); + aResult[idx++].res = (MyFile.size() == bytesread); MyFile.close(); - Serial.println("OK"); } else { - Serial.println("KO --> Error to open 'ARDUINO/SD/WRITE.txt' file"); + idx += 2; } - Serial.println("###### End of the SD tests ######"); + aResult[idx++].res = SD.end(); + for (uint32_t i = 0; i < idx; i++) { + Serial.printf("%s %s\n", aResult[i].tst, (aResult[i].res) ? "OK" : (aResult[i].err) ? aResult[i].err + : "KO"); + } + Serial.println("###### End of the SD tests ######"); } -void loop() -{ +void loop() { // do nothing } diff --git a/examples/ReadWrite/ReadWrite.ino b/examples/ReadWrite/ReadWrite.ino index f344037..95f6cb7 100644 --- a/examples/ReadWrite/ReadWrite.ino +++ b/examples/ReadWrite/ReadWrite.ino @@ -19,18 +19,16 @@ File myFile; -void setup() -{ +void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { - ; // wait for serial port to connect. Needed for Leonardo only + ; // wait for serial port to connect. Needed for Leonardo only } Serial.print("Initializing SD card..."); - while (!SD.begin(SD_DETECT_PIN)) - { + while (!SD.begin(SD_DETECT_PIN)) { delay(10); } Serial.println("initialization done."); @@ -66,10 +64,12 @@ void setup() // if the file didn't open, print an error: Serial.println("error opening test.txt"); } + if (!SD.end()) { + Serial.println("Failed to properly end the SD."); + } Serial.println("###### End of the SD tests ######"); } -void loop() -{ +void loop() { // nothing happens after setup } diff --git a/examples/listfiles/listfiles.ino b/examples/listfiles/listfiles.ino index 3b891d4..a6870d6 100644 --- a/examples/listfiles/listfiles.ino +++ b/examples/listfiles/listfiles.ino @@ -20,63 +20,63 @@ File root; -void setup() -{ +void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { - ; // wait for Serial port to connect. Needed for Leonardo only + ; // wait for Serial port to connect. Needed for Leonardo only } Serial.print("Initializing SD card..."); - while (!SD.begin(SD_DETECT_PIN)) - { + while (!SD.begin(SD_DETECT_PIN)) { delay(10); } Serial.println("initialization done."); root = SD.open("/"); - if(root) + if (root) { printDirectory(root, 0); - else + delay(2000); + Serial.println(); + Serial.println("Rewinding, and repeating below:"); + Serial.println(); + delay(2000); + root.rewindDirectory(); + printDirectory(root, 0); + root.close(); + } else { Serial.println("Could not open root"); - delay(2000); - Serial.println(); - Serial.println("Rewinding, and repeating below:" ); - Serial.println(); - delay(2000); - root.rewindDirectory(); - printDirectory(root, 0); - root.close(); + } + if (!SD.end()) { + Serial.println("Failed to properly end the SD."); + } Serial.println("###### End of the SD tests ######"); } -void loop() -{ +void loop() { // nothing happens after setup finishes. } void printDirectory(File dir, int numTabs) { - while(true) { - File entry = dir.openNextFile(); - if (! entry) { - // no more files - break; - } - for (uint8_t i=0; i