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
Diff: SDFileSystem/SDFileSystem.cpp
- 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(); +}