Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FATFileSystem
Revision 23:c03ef1abef0e, committed 2016-03-31
- 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
--- 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 */