SDFileSystem for STM32F746NG DISCOVERY with 4bit SDMMC interface on fixed pins

Dependencies:   FATFileSystem

Dependents:   DISCO-F746NG_SDFileSystem uzairkhan DISCO-F746NG_Scope_copy

Fork of SDFileSystem by Neil Thiessen

Files at this revision

API Documentation at this revision

Comitter:
DieterGraef
Date:
Thu Mar 31 17:39:48 2016 +0000
Parent:
22:3fa5eaf48e81
Child:
24:698affe9560c
Commit message:
For use with STM32F746NG Discovery with SDMMC 4Bit Bus on fixed Pins

Changed in this revision

SDFileSystem.cpp Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.h Show annotated file Show diff for this revision Revisions of this file
SD_Helper.c Show annotated file Show diff for this revision Revisions of this file
SD_Helper.h Show annotated file Show diff for this revision Revisions of this file
--- a/SDFileSystem.cpp	Wed Feb 24 17:46:31 2016 +0000
+++ b/SDFileSystem.cpp	Thu Mar 31 17:39:48 2016 +0000
@@ -1,6 +1,6 @@
 /* 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
@@ -16,49 +16,39 @@
 
 #include "SDFileSystem.h"
 #include "diskio.h"
-#include "pinmap.h"
 #include "SDCRC.h"
+//for cache flush function
+#include "SD_Helper.h"
 
-SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name, PinName cd, SwitchType cdtype, int hz)
-    : FATFileSystem(name),
-      m_Spi(mosi, miso, sclk),
-      m_Cs(cs, 1),
-      m_Cd(cd),
-      m_FREQ(hz)
+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;
-
-    //Enable the internal pull-up resistor on MISO
-    pin_mode(miso, PullUp);
-
-    //Configure the SPI bus
-    m_Spi.format(8, 0);
-
-    //Configure the card detect pin
-    if (cdtype == SWITCH_POS_NO) {
-        m_Cd.mode(PullDown);
-        m_CdAssert = 1;
-        m_Cd.fall(this, &SDFileSystem::onCardRemoval);
-    } else if (cdtype == SWITCH_POS_NC) {
-        m_Cd.mode(PullDown);
-        m_CdAssert = 0;
-        m_Cd.rise(this, &SDFileSystem::onCardRemoval);
-    } else if (cdtype == SWITCH_NEG_NO) {
-        m_Cd.mode(PullUp);
-        m_CdAssert = 0;
-        m_Cd.rise(this, &SDFileSystem::onCardRemoval);
-    } else if (cdtype == SWITCH_NEG_NC) {
-        m_Cd.mode(PullUp);
-        m_CdAssert = 1;
-        m_Cd.fall(this, &SDFileSystem::onCardRemoval);
-    } else {
-        m_CdAssert = -1;
-    }
+    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);
+    initstat=BSP_SD_Init();
+   if (initstat!=MSD_OK)
+   {
+       m_Status |= STA_NOINIT;
+   }
+   else
+   {
+        m_Status &= ~STA_NOINIT;
+   }
 }
 
 bool SDFileSystem::card_present()
@@ -100,10 +90,10 @@
     if (enabled && !m_Crc) {
         //Send CMD59(0x00000001) to enable CRC
         m_Crc = true;
-        commandTransaction(CMD59, 0x00000001);
+        BSP_SD_CommandTransaction(CMD59, 0x00000001);
     } else if (!enabled && m_Crc) {
-        //Send CMD59(0x00000000) to disable CRC
-        commandTransaction(CMD59, 0x00000000);
+        //Send CMD59(0x00000000) to disableAPP/MBED/targets/hal/TARGET_STM/TARGET_STM32F7/TARGET_DISCO_F746NG CRC
+        BSP_SD_CommandTransaction(CMD59, 0x00000000);
         m_Crc = false;
     }
 }
@@ -147,163 +137,43 @@
 
 int SDFileSystem::disk_initialize()
 {
-    char token;
-    unsigned int resp;
 
     //Make sure there's a card in the socket before proceeding
     checkSocket();
     if (m_Status & STA_NODISK)
         return m_Status;
-
-    //Make sure we're not already initialized before proceeding
-    if (!(m_Status & STA_NOINIT))
-        return m_Status;
-
-    //Set the SPI frequency to 400kHz for initialization
-    m_Spi.frequency(400000);
-
-    //Send 80 dummy clocks with /CS deasserted and DI held high
-    m_Cs = 1;
-    for (int i = 0; i < 10; i++)
-        m_Spi.write(0xFF);
-
-    //Send CMD0(0x00000000) to reset the card
-    if (commandTransaction(CMD0, 0x00000000) != 0x01) {
-        //Initialization failed
-        m_CardType = CARD_UNKNOWN;
-        return m_Status;
-    }
-
-    //Send CMD59(0x00000001) to enable CRC if necessary
-    if (m_Crc) {
-        if (commandTransaction(CMD59, 0x00000001) != 0x01) {
-            //Initialization failed
-            m_CardType = CARD_UNKNOWN;
-            return m_Status;
-        }
-    }
-
-    //Send CMD8(0x000001AA) to see if this is an SDCv2 card
-    if (commandTransaction(CMD8, 0x000001AA, &resp) == 0x01) {
-        //This is an SDCv2 card, get the 32-bit return value and verify the voltage range/check pattern
-        if ((resp & 0xFFF) != 0x1AA) {
-            //Initialization failed
-            m_CardType = CARD_UNKNOWN;
-            return m_Status;
-        }
-
-        //Send CMD58(0x00000000) to read the OCR, and verify that the card supports 3.2-3.3V
-        if (commandTransaction(CMD58, 0x00000000, &resp) != 0x01 || !(resp & (1 << 20))) {
-            //Initialization failed
-            m_CardType = CARD_UNKNOWN;
-            return m_Status;
-        }
-
-        //Try to initialize the card using ACMD41(0x00100000)
-        for (int i = 0; i < 1000; i++) {
-            token = commandTransaction(ACMD41, 0x40100000);
-            if (token != 0x01) {
-                break;
-            }
-        }
-
-        //Check if the card initialized
-        if (token != 0x00) {
-            //Initialization failed
-            m_CardType = CARD_UNKNOWN;
-            return m_Status;
-        }
-
-        //Send CMD58(0x00000000) to read the OCR
-        if (commandTransaction(CMD58, 0x00000000, &resp) == 0x00) {
-            //Check the CCS bit to determine if this is a high capacity card
-            if (resp & (1 << 30))
-                m_CardType = CARD_SDHC;
-            else
-                m_CardType = CARD_SD;
+   BSP_SD_GetCardInfo(&m_CardInfo);
 
-            //Increase the SPI frequency to full speed (up to 25MHz for SDCv2)
-            if (m_FREQ > 25000000)
-                m_Spi.frequency(25000000);
-            else
-                m_Spi.frequency(m_FREQ);
-        } else {
-            //Initialization failed
-            m_CardType = CARD_UNKNOWN;
-            return m_Status;
-        }
-    } else {
-        //Didn't respond or illegal command, this is either an SDCv1 or MMC card
-        //Send CMD58(0x00000000) to read the OCR, and verify that the card supports 3.2-3.3V
-        if (commandTransaction(CMD58, 0x00000000, &resp) != 0x01 || !(resp & (1 << 20))) {
-            //Initialization failed
-            m_CardType = CARD_UNKNOWN;
-            return m_Status;
-        }
-
-        //Try to initialize the card using ACMD41(0x00100000)
-        for (int i = 0; i < 1000; i++) {
-            token = commandTransaction(ACMD41, 0x40100000);
-            if (token != 0x01) {
-                break;
-            }
-        }
-
-        //Check if the card initialized
-        if (token == 0x00) {
-            //This is an SDCv1 standard capacity card
-            m_CardType = CARD_SD;
-
-            //Increase the SPI frequency to full speed (up to 25MHz for SDCv1)
-            if (m_FREQ > 25000000)
-                m_Spi.frequency(25000000);
-            else
-                m_Spi.frequency(m_FREQ);
-        } else {
-            //Try to initialize the card using CMD1(0x00100000)
-            for (int i = 0; i < 1000; i++) {
-                token = commandTransaction(CMD1, 0x00100000);
-                if (token != 0x01) {
-                    break;
-                }
-            }
-
-            //Check if the card initialized
-            if (token == 0x00) {
-                //This is an MMCv3 card
-                m_CardType = CARD_MMC;
-
-                //Increase the SPI frequency to full speed (up to 20MHz for MMCv3)
-                if (m_FREQ > 20000000)
-                    m_Spi.frequency(20000000);
-                else
-                    m_Spi.frequency(m_FREQ);
-            } else {
-                //Initialization failed
-                m_CardType = CARD_UNKNOWN;
-                return m_Status;
-            }
-        }
-    }
-
-    //Send ACMD42(0x00000000) to disconnect the internal pull-up resistor on pin 1 if necessary
-    if (m_CardType != CARD_MMC) {
-        if (commandTransaction(ACMD42, 0x00000000) != 0x00) {
-            //Initialization failed
-            m_CardType = CARD_UNKNOWN;
-            return m_Status;
-        }
-    }
-
-    //Send CMD16(0x00000200) to force the block size to 512B if necessary
-    if (m_CardType != CARD_SDHC) {
-        if (commandTransaction(CMD16, 0x00000200) != 0x00) {
-            //Initialization failed
-            m_CardType = CARD_UNKNOWN;
-            return m_Status;
-        }
-    }
-
+   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;
 
@@ -322,20 +192,30 @@
 
 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;
 
     //Read a single block, or multiple blocks
     if (count > 1) {
-        return readBlocks((char*)buffer, sector, count) ? RES_OK : RES_ERROR;
+        BSP_SD_Set_RX_Busy();
+        retval=BSP_SD_ReadBlocks_DMA((uint32_t *)buffer, (uint64_t) (sector * 512),512, count);
+        while(BSP_SD_Get_RX_busy()==1){;}
+        CPU_CACHE_Flush((uint32_t *)buffer,(512*count));
+        return (retval ? RES_ERROR : RES_OK);
     } else {
-        return readBlock((char*)buffer, sector) ? RES_OK : RES_ERROR;
+        BSP_SD_Set_RX_Busy();
+        retval= BSP_SD_ReadBlocks_DMA((uint32_t *)buffer, (uint64_t) (sector * 512), 512, 1);
+        while(BSP_SD_Get_RX_busy()==1){;}
+        CPU_CACHE_Flush((uint32_t *)buffer,(512));
+        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;
@@ -346,17 +226,27 @@
 
     //Write a single block, or multiple blocks
     if (count > 1) {
-        return writeBlocks((const char*)buffer, sector, count) ? RES_OK : RES_ERROR;
+        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){;}
+         return (retval? RES_ERROR : RES_OK);
     } else {
-        return writeBlock((const char*)buffer, sector) ? RES_OK : RES_ERROR;
+        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){;}
+         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
-    if (select()) {
-        deselect();
+    while(BSP_SD_GetStatus()==SD_TRANSFER_BUSY){;}
+    if(BSP_SD_GetStatus()==SD_TRANSFER_OK)
+    {
         return RES_OK;
     } else {
         return RES_ERROR;
@@ -365,45 +255,13 @@
 
 uint32_t SDFileSystem::disk_sectors()
 {
+    uint32_t sectors=0;
     //Make sure the card is initialized before proceeding
     if (m_Status & STA_NOINIT)
         return 0;
-
-    //Try to read the CSD register up to 3 times
-    for (int f = 0; f < 3; f++) {
-        //Select the card, and wait for ready
-        if(!select())
-            break;
-
-        //Send CMD9(0x00000000) to read the CSD register
-        if (writeCommand(CMD9, 0x00000000) == 0x00) {
-            //Read the 16B CSD data block
-            char csd[16];
-            bool success = readData(csd, 16);
-            deselect();
-            if (success) {
-                //Calculate the sector count based on the card type
-                if ((csd[0] >> 6) == 0x01) {
-                    //Calculate the sector count for a high capacity card
-                    unsigned int size = (((csd[7] & 0x3F) << 16) | (csd[8] << 8) | csd[9]) + 1;
-                    return size << 10;
-                } else {
-                    //Calculate the sector count for a standard capacity card
-                    unsigned int size = (((csd[6] & 0x03) << 10) | (csd[7] << 2) | ((csd[8] & 0xC0) >> 6)) + 1;
-                    size <<= ((((csd[9] & 0x03) << 1) | ((csd[10] & 0x80) >> 7)) + 2);
-                    size <<= (csd[5] & 0x0F);
-                    return size >> 9;
-                }
-            }
-        } else {
-            //The command failed, get out
-            break;
-        }
-    }
-
-    //The read operation failed 3 times
-    deselect();
-    return 0;
+   BSP_SD_GetCardInfo(&m_CardInfo);
+   sectors=m_CardInfo.CardCapacity>>9;
+    return sectors;
 }
 
 void SDFileSystem::onCardRemoval()
@@ -432,454 +290,39 @@
     }
 }
 
-inline bool SDFileSystem::waitReady(int timeout)
-{
-    char resp;
 
-    //Keep sending dummy clocks with DI held high until the card releases the DO line
-    m_Timer.start();
-    do {
-        resp = m_Spi.write(0xFF);
-    } while (resp == 0x00 && m_Timer.read_ms() < timeout);
-    m_Timer.stop();
-    m_Timer.reset();
-
-    //Return success/failure
-    return (resp > 0x00);
-}
-
-inline bool SDFileSystem::select()
-{
-    //Assert /CS
-    m_Cs = 0;
-
-    //Send 8 dummy clocks with DI held high to enable DO
-    m_Spi.write(0xFF);
-
-    //Wait for up to 500ms for the card to become ready
-    if (waitReady(500)) {
-        return true;
-    } else {
-        //We timed out, deselect and return false
-        deselect();
-        return false;
-    }
-}
-
-inline void SDFileSystem::deselect()
-{
-    //Deassert /CS
-    m_Cs = 1;
-
-    //Send 8 dummy clocks with DI held high to disable DO
-    m_Spi.write(0xFF);
-}
-
-inline char SDFileSystem::commandTransaction(char cmd, unsigned int arg, unsigned int* resp)
-{
-    //Select the card, and wait for ready
-    if(!select())
-        return 0xFF;
-
-    //Perform the command transaction
-    char token = writeCommand(cmd, arg, resp);
-
-    //Deselect the card, and return the R1 response token
-    deselect();
-    return token;
-}
-
-char SDFileSystem::writeCommand(char cmd, unsigned int arg, unsigned int* resp)
+/*interrupthandlers */
+/**
+  * @brief  This function handles DMA2 Stream 3 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void SDFileSystem::DMA2_Stream3_IRQHandler(void)
 {
-    char token;
-
-    //Try to send the command up to 3 times
-    for (int f = 0; f < 3; f++) {
-        //Send CMD55(0x00000000) prior to an application specific command
-        if (cmd == ACMD22 || cmd == ACMD23 || cmd == ACMD41 || cmd == ACMD42) {
-            token = writeCommand(CMD55, 0x00000000);
-            if (token > 0x01)
-                return token;
-
-            //Deselect and reselect the card between CMD55 and an ACMD
-            deselect();
-            if(!select())
-                return 0xFF;
-        }
-
-        //Prepare the command packet
-        char cmdPacket[6];
-        cmdPacket[0] = cmd;
-        cmdPacket[1] = arg >> 24;
-        cmdPacket[2] = arg >> 16;
-        cmdPacket[3] = arg >> 8;
-        cmdPacket[4] = arg;
-        if (m_Crc || cmd == CMD0 || cmd == CMD8)
-            cmdPacket[5] = (SDCRC::crc7(cmdPacket, 5) << 1) | 0x01;
-        else
-            cmdPacket[5] = 0x01;
-
-        //Send the command packet
-        for (int i = 0; i < 6; i++)
-            m_Spi.write(cmdPacket[i]);
-
-        //Discard the stuff byte immediately following CMD12
-        if (cmd == CMD12)
-            m_Spi.write(0xFF);
-
-        //Allow up to 8 bytes of delay for the R1 response token
-        for (int i = 0; i < 9; i++) {
-            token = m_Spi.write(0xFF);
-            if (!(token & 0x80))
-                break;
-        }
-
-        //Verify the R1 response token
-        if (token == 0xFF) {
-            //No data was received, get out early
-            break;
-        } else if (token & (1 << 3)) {
-            //There was a CRC error, try again
-            continue;
-        } else if (token > 0x01) {
-            //An error occured, get out early
-            break;
-        }
-
-        //Handle R2 and R3/R7 response tokens
-        if (cmd == CMD13 && resp != NULL) {
-            //Read the R2 response value
-            *resp = m_Spi.write(0xFF);
-        } else if ((cmd == CMD8 || cmd == CMD58) && resp != NULL) {
-            //Read the R3/R7 response value
-            *resp = (m_Spi.write(0xFF) << 24);
-            *resp |= (m_Spi.write(0xFF) << 16);
-            *resp |= (m_Spi.write(0xFF) << 8);
-            *resp |= m_Spi.write(0xFF);
-        }
-
-        //The command was successful
-        break;
-    }
-
-    //Return the R1 response token
-    return token;
-}
-
-bool SDFileSystem::readData(char* buffer, int length)
-{
-    char token;
-    unsigned short crc;
-
-    //Wait for up to 500ms for a token to arrive
-    m_Timer.start();
-    do {
-        token = m_Spi.write(0xFF);
-    } while (token == 0xFF && m_Timer.read_ms() < 500);
-    m_Timer.stop();
-    m_Timer.reset();
-
-    //Check if a valid start block token was received
-    if (token != 0xFE)
-        return false;
-
-    //Check if large frames are enabled or not
-    if (m_LargeFrames) {
-        //Switch to 16-bit frames for better performance
-        m_Spi.format(16, 0);
-
-        //Read the data block into the buffer
-        unsigned short dataWord;
-        for (int i = 0; i < length; i += 2) {
-            dataWord = m_Spi.write(0xFFFF);
-            buffer[i] = dataWord >> 8;
-            buffer[i + 1] = dataWord;
-        }
-
-        //Read the CRC16 checksum for the data block
-        crc = m_Spi.write(0xFFFF);
-
-        //Switch back to 8-bit frames
-        m_Spi.format(8, 0);
-    } else {
-        //Read the data into the buffer
-        for (int i = 0; i < length; i++)
-            buffer[i] = m_Spi.write(0xFF);
-
-        //Read the CRC16 checksum for the data block
-        crc = (m_Spi.write(0xFF) << 8);
-        crc |= m_Spi.write(0xFF);
-    }
-
-    //Return the validity of the CRC16 checksum (if enabled)
-    return (!m_Crc || crc == SDCRC::crc16(buffer, length));
-}
-
-char SDFileSystem::writeData(const char* buffer, char token)
-{
-    //Calculate the CRC16 checksum for the data block (if enabled)
-    unsigned short crc = (m_Crc) ? SDCRC::crc16(buffer, 512) : 0xFFFF;
-
-    //Wait for up to 500ms for the card to become ready
-    if (!waitReady(500))
-        return false;
-
-    //Send the start block token
-    m_Spi.write(token);
-
-    //Check if large frames are enabled or not
-    if (m_LargeFrames) {
-        //Switch to 16-bit frames for better performance
-        m_Spi.format(16, 0);
-
-        //Write the data block from the buffer
-        for (int i = 0; i < 512; i += 2)
-            m_Spi.write((buffer[i] << 8) | buffer[i + 1]);
-
-        //Send the CRC16 checksum for the data block
-        m_Spi.write(crc);
-
-        //Switch back to 8-bit frames
-        m_Spi.format(8, 0);
-    } else {
-        //Write the data block from the buffer
-        for (int i = 0; i < 512; i++)
-            m_Spi.write(buffer[i]);
-
-        //Send the CRC16 checksum for the data block
-        m_Spi.write(crc >> 8);
-        m_Spi.write(crc);
-    }
-
-    //Return the data response token
-    return (m_Spi.write(0xFF) & 0x1F);
+  BSP_SD_DMA_Rx_IRQHandler();
+  BSP_SD_Clear_RX_Busy();
 }
 
-inline bool SDFileSystem::readBlock(char* buffer, unsigned int lba)
-{
-    //Try to read the block up to 3 times
-    for (int f = 0; f < 3; f++) {
-        //Select the card, and wait for ready
-        if(!select())
-            break;
-
-        //Send CMD17(block) to read a single block
-        if (writeCommand(CMD17, (m_CardType == CARD_SDHC) ? lba : lba << 9) == 0x00) {
-            //Try to read the block, and deselect the card
-            bool success = readData(buffer, 512);
-            deselect();
-
-            //Return if successful
-            if (success)
-                return true;
-        } else {
-            //The command failed, get out
-            break;
-        }
-    }
-
-    //The single block read failed
-    deselect();
-    return false;
-}
-
-inline bool SDFileSystem::readBlocks(char* buffer, unsigned int lba, unsigned int count)
+/**
+  * @brief  This function handles DMA2 Stream 6 interrupt request.
+  * @param  None
+  * @retval None
+  */
+void SDFileSystem::DMA2_Stream6_IRQHandler(void)
 {
-    //Try to read each block up to 3 times
-    for (int f = 0; f < 3;) {
-        //Select the card, and wait for ready
-        if(!select())
-            break;
-
-        //Send CMD18(block) to read multiple blocks
-        if (writeCommand(CMD18, (m_CardType == CARD_SDHC) ? lba : lba << 9) == 0x00) {
-            //Try to read all of the data blocks
-            do {
-                //Read the next block, and break on errors
-                if (!readData(buffer, 512)) {
-                    f++;
-                    break;
-                }
-
-                //Update the variables
-                lba++;
-                buffer += 512;
-                f = 0;
-            } while (--count);
-
-            //Send CMD12(0x00000000) to stop the transmission
-            if (writeCommand(CMD12, 0x00000000) != 0x00) {
-                //The command failed, get out
-                break;
-            }
-
-            //Deselect the card, and return if successful
-            deselect();
-            if (count == 0)
-                return true;
-        } else {
-            //The command failed, get out
-            break;
-        }
-    }
-
-    //The multiple block read failed
-    deselect();
-    return false;
+  BSP_SD_DMA_Tx_IRQHandler();
+  BSP_SD_Clear_TX_Busy();
 }
 
-inline bool SDFileSystem::writeBlock(const char* buffer, unsigned int lba)
+/**
+  * @brief  This function handles SDIO interrupt request.
+  * @param  None
+  * @retval None
+  */
+void SDFileSystem::SDMMC1_IRQHandler(void)
 {
-    //Try to write the block up to 3 times
-    for (int f = 0; f < 3; f++) {
-        //Select the card, and wait for ready
-        if(!select())
-            break;
-
-        //Send CMD24(block) to write a single block
-        if (writeCommand(CMD24, (m_CardType == CARD_SDHC) ? lba : lba << 9) == 0x00) {
-            //Try to write the block, and deselect the card
-            char token = writeData(buffer, 0xFE);
-            deselect();
-
-            //Check the data response token
-            if (token == 0x0A) {
-                //A CRC error occured, try again
-                continue;
-            } else if (token == 0x0C) {
-                //A write error occured, get out
-                break;
-            }
-
-            //Send CMD13(0x00000000) to verify that the programming was successful if enabled
-            if (m_WriteValidation) {
-                unsigned int resp;
-                if (commandTransaction(CMD13, 0x00000000, &resp) != 0x00 || resp != 0x00) {
-                    //Some manner of unrecoverable write error occured during programming, get out
-                    break;
-                }
-            }
-
-            //The data was written successfully
-            return true;
-        } else {
-            //The command failed, get out
-            break;
-        }
-    }
-
-    //The single block write failed
-    deselect();
-    return false;
+  BSP_SD_IRQHandler();
 }
 
-inline bool SDFileSystem::writeBlocks(const char* buffer, unsigned int lba, unsigned int count)
-{
-    char token;
-    const char* currentBuffer = buffer;
-    unsigned int currentLba = lba;
-    int currentCount = count;
-
-    //Try to write each block up to 3 times
-    for (int f = 0; f < 3;) {
-        //If this is an SD card, send ACMD23(count) to set the number of blocks to pre-erase
-        if (m_CardType != CARD_MMC) {
-            if (commandTransaction(ACMD23, currentCount) != 0x00) {
-                //The command failed, get out
-                break;
-            }
-        }
-
-        //Select the card, and wait for ready
-        if(!select())
-            break;
-
-        //Send CMD25(block) to write multiple blocks
-        if (writeCommand(CMD25, (m_CardType == CARD_SDHC) ? currentLba : currentLba << 9) == 0x00) {
-            //Try to write all of the data blocks
-            do {
-                //Write the next block and break on errors
-                token = writeData(currentBuffer, 0xFC);
-                if (token != 0x05) {
-                    f++;
-                    break;
-                }
-
-                //Update the variables
-                currentBuffer += 512;
-                f = 0;
-            } while (--currentCount);
-
-            //Wait for up to 500ms for the card to finish processing the last block
-            if (!waitReady(500))
-                break;
-
-            //Finalize the transmission
-            if (currentCount == 0) {
-                //Send the stop tran token, and deselect the card
-                m_Spi.write(0xFD);
-                deselect();
 
-                //Send CMD13(0x00000000) to verify that the programming was successful if enabled
-                if (m_WriteValidation) {
-                    unsigned int resp;
-                    if (commandTransaction(CMD13, 0x00000000, &resp) != 0x00 || resp != 0x00) {
-                        //Some manner of unrecoverable write error occured during programming, get out
-                        break;
-                    }
-                }
 
-                //The data was written successfully
-                return true;
-            } else {
-                //Send CMD12(0x00000000) to abort the transmission
-                if (writeCommand(CMD12, 0x00000000) != 0x00) {
-                    //The command failed, get out
-                    break;
-                }
-
-                //Deselect the card
-                deselect();
-
-                //Check the error token
-                if (token == 0x0A) {
-                    //Determine the number of well written blocks if possible
-                    unsigned int writtenBlocks = 0;
-                    if (m_CardType != CARD_MMC && select()) {
-                        //Send ACMD22(0x00000000) to get the number of well written blocks
-                        if (writeCommand(ACMD22, 0x00000000) == 0x00) {
-                            //Read the data
-                            char acmdData[4];
-                            if (readData(acmdData, 4)) {
-                                //Extract the number of well written blocks
-                                writtenBlocks = acmdData[0] << 24;
-                                writtenBlocks |= acmdData[1] << 16;
-                                writtenBlocks |= acmdData[2] << 8;
-                                writtenBlocks |= acmdData[3];
-                            }
-                        }
-                        deselect();
-                    }
-
-                    //Roll back the variables based on the number of well written blocks
-                    currentBuffer = buffer + (writtenBlocks << 9);
-                    currentLba = lba + writtenBlocks;
-                    currentCount = count - writtenBlocks;
-
-                    //Try again
-                    continue;
-                } else {
-                    //A write error occured, get out
-                    break;
-                }
-            }
-        } else {
-            //The command failed, get out
-            break;
-        }
-    }
-
-    //The multiple block write failed
-    deselect();
-    return false;
-}
--- a/SDFileSystem.h	Wed Feb 24 17:46:31 2016 +0000
+++ b/SDFileSystem.h	Thu Mar 31 17:39:48 2016 +0000
@@ -1,6 +1,6 @@
 /* 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
@@ -18,6 +18,7 @@
 #define SD_FILE_SYSTEM_H
 
 #include "mbed.h"
+#include "stm32746g_discovery_sd.h"
 #include "FATFileSystem.h"
 
 /** SDFileSystem class.
@@ -29,7 +30,7 @@
  * #include "SDFileSystem.h"
  *
  * //Create an SDFileSystem object
- * SDFileSystem sd(p5, p6, p7, p20, "sd");
+ * SDFileSystem sd("sd");
  *
  * int main()
  * {
@@ -65,7 +66,11 @@
  *     sd.unmount();
  * }
  * @endcode
+
  */
+ #define CMD59  (0x40 | 59)
+using namespace mbed;
+
 class SDFileSystem : public FATFileSystem
 {
 public:
@@ -100,7 +105,7 @@
      * @param cdtype The type of card detect switch.
      * @param hz The SPI bus frequency (defaults to 1MHz).
      */
-    SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name, PinName cd = NC, SwitchType cdtype = SWITCH_NONE, int hz = 1000000);
+    SDFileSystem( const char* name);
 
     /** Determine whether or not a card is present
      *
@@ -169,55 +174,21 @@
     virtual uint32_t disk_sectors();
 
 private:
-    //Commands
-    enum Command {
-        CMD0 = (0x40 | 0),      /**< GO_IDLE_STATE */
-        CMD1 = (0x40 | 1),      /**< SEND_OP_COND */
-        CMD8 = (0x40 | 8),      /**< SEND_IF_COND */
-        CMD9 = (0x40 | 9),      /**< SEND_CSD */
-        CMD12 = (0x40 | 12),    /**< STOP_TRANSMISSION */
-        CMD13 = (0x40 | 13),    /**< SEND_STATUS */
-        CMD16 = (0x40 | 16),    /**< SET_BLOCKLEN */
-        CMD17 = (0x40 | 17),    /**< READ_SINGLE_BLOCK */
-        CMD18 = (0x40 | 18),    /**< READ_MULTIPLE_BLOCK */
-        ACMD22 = (0x40 | 22),   /**< SEND_NUM_WR_BLOCKS */
-        ACMD23 = (0x40 | 23),   /**< SET_WR_BLK_ERASE_COUNT */
-        CMD24 = (0x40 | 24),    /**< WRITE_BLOCK */
-        CMD25 = (0x40 | 25),    /**< WRITE_MULTIPLE_BLOCK */
-        ACMD41 = (0x40 | 41),   /**< SD_SEND_OP_COND */
-        ACMD42 = (0x40 | 42),   /**< SET_CLR_CARD_DETECT */
-        CMD55 = (0x40 | 55),    /**< APP_CMD */
-        CMD58 = (0x40 | 58),    /**< READ_OCR */
-        CMD59 = (0x40 | 59)     /**< CRC_ON_OFF */
-    };
-
-    //Member variables
     Timer m_Timer;
-    SPI m_Spi;
-    DigitalOut m_Cs;
     InterruptIn m_Cd;
     int m_CdAssert;
-    const int m_FREQ;
     SDFileSystem::CardType m_CardType;
     bool m_Crc;
     bool m_LargeFrames;
     bool m_WriteValidation;
     int m_Status;
-
+    HAL_SD_CardInfoTypedef m_CardInfo;
     //Internal methods
     void onCardRemoval();
     void checkSocket();
-    bool waitReady(int timeout);
-    bool select();
-    void deselect();
-    char commandTransaction(char cmd, unsigned int arg, unsigned int* resp = NULL);
-    char writeCommand(char cmd, unsigned int arg, unsigned int* resp = NULL);
-    bool readData(char* buffer, int length);
-    char writeData(const char* buffer, char token);
-    bool readBlock(char* buffer, unsigned int lba);
-    bool readBlocks(char* buffer, unsigned int lba, unsigned int count);
-    bool writeBlock(const char* buffer, unsigned int lba);
-    bool writeBlocks(const char* buffer, unsigned int lba, unsigned int count);
+    void DMA2_Stream3_IRQHandler();
+    void DMA2_Stream6_IRQHandler();
+    void SDMMC1_IRQHandler();
 };
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SD_Helper.c	Thu Mar 31 17:39:48 2016 +0000
@@ -0,0 +1,126 @@
+#include "SD_Helper.h"
+#include "stm32746g_discovery_sd.h"
+
+#define _CCSIDR_LSSHIFT(x)  (((x) & SCB_CCSIDR_LINESIZE_Msk) >> SCB_CCSIDR_LINESIZE_Pos)
+
+static SD_HandleTypeDef uSdHandle;
+static int RX_Busy;
+static int TX_Busy;
+
+
+
+
+/* cache flush */
+void CPU_CACHE_Flush(uint32_t * buffer, uint32_t length)
+{
+ // SCB_InvalidateDCache_by_Addr(buffer,length);
+  uint32_t ccsidr;
+  uint32_t smask;
+  uint32_t sshift;
+  uint32_t ways;
+  uint32_t wshift;
+  uint32_t ssize;
+  uint32_t sets;
+  uint32_t sw;
+  uint32_t start;
+  uint32_t ende;
+
+  start=(uint32_t)buffer;
+  ende=start+length;
+  /* Get the characteristics of the D-Cache */
+
+  ccsidr = SCB->CCSIDR;
+  smask  = CCSIDR_SETS(ccsidr);          /* (Number of sets) - 1 */
+  sshift = _CCSIDR_LSSHIFT(ccsidr) + 4;   /* log2(cache-line-size-in-bytes) */
+  ways   = CCSIDR_WAYS(ccsidr);          /* (Number of ways) - 1 */
+
+  /* Calculate the bit offset for the way field in the DCCISW register by
+   * counting the number of leading zeroes.  For example:
+   *
+   *   Number of  Value of ways  Field
+   *   Ways       'ways'         Offset
+   *     2         1             31
+   *     4         3             30
+   *     8         7             29
+   *   ...
+   */
+
+  wshift = __CLZ(ways) & 0x1f;
+
+  /* Clean and invalidate the D-Cache over the range of addresses */
+
+  ssize  = (1 << sshift);
+  start &= ~(ssize - 1);
+  __DSB();
+
+  do
+    {
+      int32_t tmpways = ways;
+
+      /* Isolate the cache line associated with this address.  For example
+       * if the cache line size is 32 bytes and the cache size is 16KB, then
+       *
+       *   sshift = 5      : Offset to the beginning of the set field
+       *   smask  = 0x007f : Mask of the set field
+       */
+
+      sets = ((uint32_t)start >> sshift) & smask;
+
+      /* Clean and invalidate each way for this cacheline */
+
+      do
+        {
+          sw = ((tmpways << wshift) | (sets << sshift));
+          SCB->DCCISW=sw;
+
+        }
+      while (tmpways--);
+
+      /* Increment the address by the size of one cache line. */
+
+      start += ssize;
+    }
+  while (start < ende);
+
+  __DSB();
+  __ISB();
+}
+
+void BSP_SD_CommandTransaction(char cmd, unsigned int arg)
+{
+  SDMMC_CmdInitTypeDef sdmmc_cmdinitstructure;
+  uSdHandle.Instance = SDMMC1;
+  sdmmc_cmdinitstructure.Argument         = (uint32_t)arg;
+  sdmmc_cmdinitstructure.CmdIndex         = cmd;
+  sdmmc_cmdinitstructure.Response         = SDMMC_RESPONSE_SHORT;
+  sdmmc_cmdinitstructure.WaitForInterrupt = SDMMC_WAIT_NO;
+  sdmmc_cmdinitstructure.CPSM             = SDMMC_CPSM_ENABLE;
+  SDMMC_SendCommand(uSdHandle.Instance, &sdmmc_cmdinitstructure);
+}
+
+
+void BSP_SD_Set_RX_Busy(void)
+{
+    RX_Busy=1;
+}
+void BSP_SD_Clear_RX_Busy(void)
+{
+    RX_Busy=0;
+}
+int BSP_SD_Get_RX_busy(void)
+{
+    return RX_Busy;
+}
+
+void BSP_SD_Set_TX_Busy(void)
+{
+    TX_Busy=1;
+}
+void BSP_SD_Clear_TX_Busy(void)
+{
+    TX_Busy=0;
+}
+int BSP_SD_Get_TX_busy(void)
+{
+    return TX_Busy;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SD_Helper.h	Thu Mar 31 17:39:48 2016 +0000
@@ -0,0 +1,26 @@
+ /* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef ___SD_Helper
+#define ___SD_Helper
+
+#include "cmsis.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+void CPU_CACHE_Flush(uint32_t * buffer, uint32_t length);
+
+void    BSP_SD_CommandTransaction(char cmd, unsigned int arg);
+
+void BSP_SD_Set_RX_Busy(void);
+void BSP_SD_Clear_RX_Busy(void);
+int BSP_SD_Get_RX_busy(void);
+void BSP_SD_Set_TX_Busy(void);
+void BSP_SD_Clear_TX_Busy(void);
+int BSP_SD_Get_TX_busy(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ___SD_Helper */