This demo reads a bitmap from a FAT formatted SD-card, copies it to flash and displays it on the screen. The demo is based on the following project: https://os.mbed.com/users/DieterGraef/code/DISCO-F746NG_SDFileSystem/

Dependencies:   LCD_DISCO_F746NG TS_DISCO_F746NG mbed FATFileSystem

Fork of DISCO-F746NG_SDFileSystem by Dieter Graef

Revision:
4:95e30a911d97
diff -r f93fcb3e2650 -r 95e30a911d97 SDFileSystem/SDFileSystem.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem/SDFileSystem.cpp	Thu Apr 19 19:59:54 2018 +0000
@@ -0,0 +1,351 @@
+/* SD/MMC File System Library
+ * Copyright (c) 2016 Neil Thiessen
+ * Modified for the use with STM32F746 Discovery (C) 2016 Dieter Greaf
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SDFileSystem.h"
+#include "diskio.h"
+#include "SDCRC.h"
+//for cache flush function
+#include "SD_Helper.h"
+
+SDFileSystem::SDFileSystem( const char* name)
+    : FATFileSystem(name), m_Cd(PC_13)
+{
+    //Initialize the member variables
+    uint8_t initstat;
+    void* h;
+    m_CardType = CARD_NONE;
+    m_Crc = true;
+    m_LargeFrames = false;
+    m_WriteValidation = true;
+    m_Status = STA_NOINIT;
+    m_Cd.mode(PullUp);
+    m_CdAssert = 0;
+    m_Cd.rise(this, &SDFileSystem::onCardRemoval);
+    h=(void*)&SDFileSystem::DMA2_Stream3_IRQHandler;
+    NVIC_SetVector(DMA2_Stream3_IRQn,(uint32_t)h);
+    h=(void*)&SDFileSystem::DMA2_Stream6_IRQHandler;
+    NVIC_SetVector(DMA2_Stream6_IRQn,(uint32_t)h);
+    h=(void*)&SDFileSystem::SDMMC1_IRQHandler;
+    NVIC_SetVector(SDMMC1_IRQn,(uint32_t)h);
+    BSP_SD_Clear_Busy();
+    initstat=BSP_SD_Init();
+   if (initstat!=MSD_OK)
+   {
+       m_Status |= STA_NOINIT;
+   }
+   else
+   {
+        m_Status &= ~STA_NOINIT;
+   }
+}
+
+bool SDFileSystem::card_present()
+{
+    //Check the card socket
+    checkSocket();
+
+    //Return whether or not a card is present
+    return !(m_Status & STA_NODISK);
+}
+
+SDFileSystem::CardType SDFileSystem::card_type()
+{
+    //Check the card socket
+    checkSocket();
+
+    //Return the card type
+    return m_CardType;
+}
+
+bool SDFileSystem::crc()
+{
+    //Return whether or not CRC is enabled
+    return m_Crc;
+}
+
+void SDFileSystem::crc(bool enabled)
+{
+    //Check the card socket
+    checkSocket();
+
+    //Just update the member variable if the card isn't initialized
+    if (m_Status & STA_NOINIT) {
+        m_Crc = enabled;
+        return;
+    }
+
+    //Enable or disable CRC
+    if (enabled && !m_Crc) {
+        //Send CMD59(0x00000001) to enable CRC
+        m_Crc = true;
+        BSP_SD_CommandTransaction(CMD59, 0x00000001);
+    } else if (!enabled && m_Crc) {
+        //Send CMD59(0x00000000) to disableAPP/MBED/targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG CRC
+        BSP_SD_CommandTransaction(CMD59, 0x00000000);
+        m_Crc = false;
+    }
+}
+
+bool SDFileSystem::large_frames()
+{
+    //Return whether or not 16-bit frames are enabled
+    return m_LargeFrames;
+}
+
+void SDFileSystem::large_frames(bool enabled)
+{
+    //Set whether or not 16-bit frames are enabled
+    m_LargeFrames = enabled;
+}
+
+bool SDFileSystem::write_validation()
+{
+    //Return whether or not write validation is enabled
+    return m_WriteValidation;
+}
+
+void SDFileSystem::write_validation(bool enabled)
+{
+    //Set whether or not write validation is enabled
+    m_WriteValidation = enabled;
+}
+
+int SDFileSystem::unmount()
+{
+    //Unmount the filesystem
+    FATFileSystem::unmount();
+
+    //Change the status to not initialized, and the card type to unknown
+    m_Status |= STA_NOINIT;
+    m_CardType = CARD_UNKNOWN;
+
+    //Always succeeds
+    return 0;
+}
+
+int SDFileSystem::disk_initialize()
+{
+
+    //Make sure there's a card in the socket before proceeding
+    checkSocket();
+    if (m_Status & STA_NODISK)
+        return m_Status;
+   BSP_SD_GetCardInfo(&m_CardInfo);
+
+   switch(m_CardInfo.CardType)
+   {
+   case STD_CAPACITY_SD_CARD_V1_1:
+       { m_CardType =  CARD_SD;
+         break; }
+    case STD_CAPACITY_SD_CARD_V2_0:
+       { m_CardType =  CARD_SD;
+         break; }
+    case HIGH_CAPACITY_SD_CARD:
+       { m_CardType =  CARD_SDHC;
+         break; }
+    case MULTIMEDIA_CARD:
+       { m_CardType =  CARD_MMC;
+         break; }
+    case SECURE_DIGITAL_IO_CARD:
+       { m_CardType =  CARD_SD;
+         break; }
+    case HIGH_SPEED_MULTIMEDIA_CARD:
+       { m_CardType =  CARD_MMC;
+         break; }
+    case SECURE_DIGITAL_IO_COMBO_CARD:
+       { m_CardType =  CARD_SD;
+         break; }
+    case HIGH_CAPACITY_MMC_CARD:
+       { m_CardType =  CARD_MMC;
+         break; }
+    default:
+       {m_CardType = CARD_UNKNOWN;
+       return m_Status;}
+   }
+    //The card is now initialized
+    m_Status &= ~STA_NOINIT;
+
+    //Return the disk status
+    return m_Status;
+}
+
+int SDFileSystem::disk_status()
+{
+    //Check the card socket
+    checkSocket();
+
+    //Return the disk status
+    return m_Status;
+}
+
+int SDFileSystem::disk_read(uint8_t* buffer, uint32_t sector, uint32_t count)
+{
+    int retval;
+    //Make sure the card is initialized before proceeding
+    if (m_Status & STA_NOINIT)
+        return RES_NOTRDY;
+    __DSB();
+    __ISB();
+    while(BSP_SD_Get_Busy()==1){;}
+    BSP_SD_Set_Busy();
+    //Read a single block, or multiple blocks
+    if (count > 1) {
+        BSP_SD_Set_RX_Busy();
+        SCB_InvalidateDCache_by_Addr((uint32_t *)buffer,(512*count));
+        retval=BSP_SD_ReadBlocks_DMA((uint32_t *)buffer, (uint64_t) (sector * 512),512, count);
+        while((BSP_SD_Get_RX_Busy()==1)&&(retval==MSD_OK)){;}
+        CPU_CACHE_Flush((uint32_t *)buffer,(512*count));
+        BSP_SD_Clear_Busy();
+        return (retval ? RES_ERROR : RES_OK);
+    } else {
+        BSP_SD_Set_RX_Busy();
+        SCB_InvalidateDCache_by_Addr((uint32_t *)buffer,(512));
+        retval= BSP_SD_ReadBlocks_DMA((uint32_t *)buffer, (uint64_t) (sector * 512), 512, 1);
+        while((BSP_SD_Get_RX_Busy()==1)&&(retval==MSD_OK)){;}
+        CPU_CACHE_Flush((uint32_t *)buffer,(512));
+        BSP_SD_Clear_Busy();
+        return (retval ? RES_ERROR : RES_OK);
+    }
+}
+
+int SDFileSystem::disk_write(const uint8_t* buffer, uint32_t sector, uint32_t count)
+{
+    int retval;
+    //Make sure the card is initialized before proceeding
+    if (m_Status & STA_NOINIT)
+        return RES_NOTRDY;
+    __DSB();
+    __ISB();
+    while(BSP_SD_Get_Busy()==1){;}
+    BSP_SD_Set_Busy();
+    //Make sure the card isn't write protected before proceeding
+    if (m_Status & STA_PROTECT)
+    {
+    BSP_SD_Clear_Busy();
+    return RES_WRPRT;
+    }
+    //Write a single block, or multiple blocks
+    if (count > 1) {
+        CPU_CACHE_Flush((uint32_t *)buffer,(512*count));
+        BSP_SD_Set_TX_Busy();
+        retval= BSP_SD_WriteBlocks_DMA((uint32_t *)buffer, (uint64_t) (sector * 512), 512, count);
+         while((BSP_SD_Get_TX_Busy()==1)&&(retval==MSD_OK)){;}
+         BSP_SD_Clear_Busy();
+         return (retval? RES_ERROR : RES_OK);
+    } else {
+        CPU_CACHE_Flush((uint32_t *)buffer,(512));
+        BSP_SD_Set_TX_Busy();
+        retval= BSP_SD_WriteBlocks_DMA((uint32_t *)buffer, (uint64_t) (sector * 512), 512, 1);
+         while((BSP_SD_Get_TX_Busy()==1)&&(retval==MSD_OK)){;}
+         BSP_SD_Clear_Busy();
+         return (retval? RES_ERROR : RES_OK);
+
+    }
+}
+
+int SDFileSystem::disk_sync()
+{
+    //Select the card so we're forced to wait for the end of any internal write processes
+    __DSB();
+    __ISB();
+    while(BSP_SD_Get_Busy()==1){;}
+    BSP_SD_Set_Busy();
+    while(BSP_SD_GetStatus()==SD_TRANSFER_BUSY){;}
+    if(BSP_SD_GetStatus()==SD_TRANSFER_OK)
+    {
+        BSP_SD_Clear_Busy();
+        return RES_OK;
+    } else {
+        BSP_SD_Clear_Busy();
+        return RES_ERROR;
+    }
+}
+
+uint32_t SDFileSystem::disk_sectors()
+{
+    uint32_t sectors=0;
+    //Make sure the card is initialized before proceeding
+    if (m_Status & STA_NOINIT)
+        return 0;
+    __DSB();
+    __ISB();
+    while(BSP_SD_Get_Busy()==1){;}
+    BSP_SD_Set_Busy();
+    BSP_SD_GetCardInfo(&m_CardInfo);
+    sectors=m_CardInfo.CardCapacity>>9;
+    BSP_SD_Clear_Busy();
+    return sectors;
+}
+
+void SDFileSystem::onCardRemoval()
+{
+    //Check the card socket
+    checkSocket();
+}
+
+inline void SDFileSystem::checkSocket()
+{
+    //Use the card detect switch (if available) to determine if the socket is occupied
+    if (m_CdAssert != -1) {
+        if (m_Status & STA_NODISK) {
+            if (m_Cd == m_CdAssert) {
+                //The socket is now occupied
+                m_Status &= ~STA_NODISK;
+                m_CardType = CARD_UNKNOWN;
+            }
+        } else {
+            if (m_Cd != m_CdAssert) {
+                //The socket is now empty
+                m_Status |= (STA_NODISK | STA_NOINIT);
+                m_CardType = CARD_NONE;
+            }
+        }
+    }
+}
+
+
+/*interrupthandlers */
+/**
+  * @brief  This function handles DMA2 Stream 3 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void SDFileSystem::DMA2_Stream3_IRQHandler(void)
+{
+  BSP_SD_DMA_Rx_IRQHandler();
+  BSP_SD_Clear_RX_Busy();
+}
+
+/**
+  * @brief  This function handles DMA2 Stream 6 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void SDFileSystem::DMA2_Stream6_IRQHandler(void)
+{
+  BSP_SD_DMA_Tx_IRQHandler();
+  BSP_SD_Clear_TX_Busy();
+}
+
+/**
+  * @brief  This function handles SDIO interrupt request.
+  * @param  None
+  * @retval None
+  */
+void SDFileSystem::SDMMC1_IRQHandler(void)
+{
+  BSP_SD_IRQHandler();
+}