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
SDFileSystem/SDFileSystem.cpp
- Committer:
- Lightsource
- Date:
- 2018-04-19
- Revision:
- 4:95e30a911d97
File content as of revision 4:95e30a911d97:
/* 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(); }