Block device class for creating a block device to access a SD/MMC card via SD/MMC interface on DISCO_F746NG

Dependencies:   BSP_DISCO_F746NG

Dependents:   DISCO-F746NG_BLOCK_DEVICE_SDCARD DISCO-F746NG_BLOCK_DEVICE_WITH_FAT_FILESYSTEM_ON_SDCARD SDReaderTest

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SDBlockDeviceDISCOF746NG.cpp Source File

SDBlockDeviceDISCOF746NG.cpp

00001 /* SD/MMC Block device Library for MBED-OS
00002  * Copyright 2017 Roy Krikke
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  *
00016  */
00017 
00018 #include "SDBlockDeviceDISCOF746NG.h"
00019 #include "mbed_debug.h"
00020 
00021 /* Required version: 5.5.0 and above */
00022 #if defined(MBED_MAJOR_VERSION) && MBED_MAJOR_VERSION >= 5
00023 #if (MBED_VERSION < MBED_ENCODE_VERSION(5,5,0))
00024 #error "Incompatible mbed-os version detected! Required 5.5.0 and above"
00025 #endif
00026 #else
00027 #warning "mbed-os version 5.5.0 or above required"
00028 #endif
00029 
00030 /* Required version: 5.5.0 and above */
00031 #warning "Block device class BD_SD_DISCO_F746NG is depending on BSP_DISCO_F746NG libary (Revision 9:df2ea349c37a with date 06 Jul 2017)"
00032 
00033 #define SD_DBG 0 /*!< 1 - Enable debugging */
00034 
00035 /** Enum of standard error codes
00036  *
00037  *  @enum bd_sd_error
00038  */
00039 enum bd_sd_error {
00040     SD_BLOCK_DEVICE_OK = 0,             /*!< no error */
00041     SD_BLOCK_DEVICE_ERROR = -5000,      /*!< device specific error */
00042     //SD_BLOCK_DEVICE_ERROR_WOULD_BLOCK = -5001,  /*!< operation would block */
00043     //SD_BLOCK_DEVICE_ERROR_UNSUPPORTED = -5002,  /*!< unsupported operation */
00044     SD_BLOCK_DEVICE_ERROR_PARAMETER = -5003,    /*!< invalid parameter */
00045     SD_BLOCK_DEVICE_ERROR_NO_INIT = -5004,      /*!< uninitialized */
00046     SD_BLOCK_DEVICE_ERROR_NO_DEVICE = -5005,    /*!< device is missing or not connected */
00047     //SD_BLOCK_DEVICE_ERROR_WRITE_PROTECTED = -5006,    /*!< write protected */
00048     //SD_BLOCK_DEVICE_ERROR_UNUSABLE = -5007,           /*!< unusable card */
00049     //SD_BLOCK_DEVICE_ERROR_NO_RESPONSE = -5008,        /*!< No response from device */
00050     //SD_BLOCK_DEVICE_ERROR_CRC = -5009,                /*!< CRC error */
00051     SD_BLOCK_DEVICE_ERROR_ERASE = -5010,        /*!< Erase error */
00052     SD_BLOCK_DEVICE_ERROR_READ = -5011,         /*!< Read error */
00053     SD_BLOCK_DEVICE_ERROR_PROGRAM = -5012,      /*!< Program error */
00054 };
00055 
00056 #define BLOCK_SIZE_HC 512 /*!< Block size supported for SD card is 512 bytes  */
00057 
00058 SDBlockDeviceDISCOF746NG::SDBlockDeviceDISCOF746NG() :
00059     _read_size (BLOCK_SIZE_HC), _program_size (BLOCK_SIZE_HC),
00060     _erase_size(BLOCK_SIZE_HC), _block_size (BLOCK_SIZE_HC),
00061     _capacity_in_blocks (0)
00062 {
00063     _timeout = 1000;
00064 }
00065 
00066 SDBlockDeviceDISCOF746NG::~SDBlockDeviceDISCOF746NG()
00067 {
00068     if(_is_initialized) {
00069         deinit ();
00070     }
00071 }
00072 
00073 int SDBlockDeviceDISCOF746NG::init()
00074 {
00075     lock();
00076     _sd_state = BSP_SD_Init();
00077 
00078     if(_sd_state != MSD_OK) {
00079         if(_sd_state == MSD_ERROR_SD_NOT_PRESENT) {
00080             debug_if(SD_DBG, "SD card is missing or not connected\n");
00081             unlock ();
00082             return SD_BLOCK_DEVICE_ERROR_NO_DEVICE;
00083         } else {
00084             debug_if(SD_DBG, "SD card initialization failed\n");
00085             unlock();
00086             return SD_BLOCK_DEVICE_ERROR_NO_INIT;
00087         }
00088     }
00089     BSP_SD_GetCardInfo(&_current_card_info);
00090 
00091     _card_type = _current_card_info.CardType;
00092     _read_size = _current_card_info.BlockSize;
00093     _program_size = _current_card_info.BlockSize;
00094     _erase_size = _current_card_info.BlockSize;
00095     _block_size = _current_card_info.BlockSize;
00096     _capacity_in_blocks = _current_card_info.BlockNbr;
00097 
00098     debug_if(SD_DBG, "Card Type: %i\n", _current_card_info.CardType);
00099     debug_if(SD_DBG, "Card Version: %i\n", _current_card_info.CardVersion);
00100     debug_if(SD_DBG, "Class: %i\n", _current_card_info.Class);
00101     debug_if(SD_DBG, "Relative Card Address: %x\n", _current_card_info.RelCardAdd);
00102     debug_if(SD_DBG, "Card Capacity in blocks: %i\n", _current_card_info.BlockNbr);
00103     debug_if(SD_DBG, "One block size in bytes: %i\n", _current_card_info.BlockSize);
00104     debug_if(SD_DBG, "Card logical Capacity in blocks: %i\n", _current_card_info.LogBlockNbr);
00105     debug_if(SD_DBG, "Logical block size in bytes: %i\n", _current_card_info.LogBlockSize);
00106     debug_if(SD_DBG, "Timeout: %i\n", _timeout);
00107 
00108     _is_initialized = true;
00109     unlock();
00110     return SD_BLOCK_DEVICE_OK;
00111 }
00112 
00113 int SDBlockDeviceDISCOF746NG::deinit()
00114 {
00115     lock();
00116     _sd_state = BSP_SD_DeInit ();
00117     if(_sd_state != MSD_OK) {
00118         debug_if (SD_DBG, "SD card deinitialization failed\n");
00119         return SD_BLOCK_DEVICE_ERROR;
00120     }
00121     _is_initialized = false;
00122     unlock();
00123     return BD_ERROR_OK;
00124 }
00125 
00126 int SDBlockDeviceDISCOF746NG::read(void *b, bd_addr_t addr, bd_size_t size)
00127 {
00128     if(!is_valid_read (addr, size)) {
00129         return SD_BLOCK_DEVICE_ERROR_PARAMETER;
00130     }
00131 
00132     lock();
00133     if(!_is_initialized) {
00134         unlock();
00135         return SD_BLOCK_DEVICE_ERROR_NO_INIT;
00136     }
00137 
00138     uint32_t *buffer = static_cast<uint32_t *> (b);
00139     int status = SD_BLOCK_DEVICE_OK;
00140 
00141     // Get block address
00142     uint32_t block_addr = addr / _block_size;
00143     // Get block count
00144     uint32_t block_cnt = size / _block_size;
00145 
00146     debug_if(
00147         SD_DBG,
00148         "BD_SD_DISCO_F746NG::read addr: 0x%x, block_addr: %i size: %lu block count: %i\n",
00149         addr, block_addr, size, block_cnt);
00150 
00151     if(BSP_SD_ReadBlocks (buffer, block_addr, block_cnt, _timeout) != MSD_OK) {
00152         status = SD_BLOCK_DEVICE_ERROR_READ;
00153     }
00154 
00155     // Wait until SD card is ready to use for new operation
00156     while(BSP_SD_GetCardState() != SD_TRANSFER_OK) {
00157     }
00158 
00159     unlock ();
00160     return status;
00161 }
00162 
00163 int SDBlockDeviceDISCOF746NG::program(const void *b, bd_addr_t addr, bd_size_t size)
00164 {
00165     if(!is_valid_program (addr, size)) {
00166         return SD_BLOCK_DEVICE_ERROR_PARAMETER;
00167     }
00168 
00169     lock();
00170     if(!_is_initialized) {
00171         unlock ();
00172         return SD_BLOCK_DEVICE_ERROR_NO_INIT;
00173     }
00174 
00175     uint32_t* buffer =
00176         const_cast<uint32_t*> (reinterpret_cast<const uint32_t*> (b));
00177     int status = SD_BLOCK_DEVICE_OK;
00178 
00179     // Get block address
00180     uint32_t block_addr = addr / _block_size;
00181     // Get block count
00182     uint32_t block_cnt = size / _block_size;
00183 
00184     debug_if (
00185         SD_DBG,
00186         "BD_SD_DISCO_F746NG::program addr: 0x%x, block_addr: %i size: %lu block count: %i\n",
00187         addr, block_addr, size, block_cnt);
00188 
00189     if(BSP_SD_WriteBlocks (buffer, block_addr, block_cnt, _timeout) != MSD_OK) {
00190         status = SD_BLOCK_DEVICE_ERROR_PROGRAM;
00191     }
00192 
00193     // Wait until SD card is ready to use for new operation
00194     while(BSP_SD_GetCardState() != SD_TRANSFER_OK) {
00195     }
00196 
00197     unlock();
00198     return status;
00199 }
00200 
00201 int SDBlockDeviceDISCOF746NG::erase(bd_addr_t addr, bd_size_t size)
00202 {
00203     if (!is_valid_erase(addr, size)) {
00204         return SD_BLOCK_DEVICE_ERROR_PARAMETER;
00205     }
00206 
00207     lock();
00208     if(!_is_initialized) {
00209         unlock();
00210         return SD_BLOCK_DEVICE_ERROR_NO_INIT;
00211     }
00212 
00213     size -= _block_size;
00214 
00215     int status = SD_BLOCK_DEVICE_OK;
00216     uint32_t start_addr = addr;
00217     uint32_t end_addr = start_addr + size;
00218 
00219     // Get block count
00220     uint32_t block_start_addr = start_addr / _block_size;
00221     // Get block address
00222     uint32_t block_end_addr = end_addr / _block_size;
00223 
00224     debug_if(
00225         SD_DBG,
00226         "BD_SD_DISCO_F746NG::erase start_addr: 0x%x, block_start_addr: %i | end_addr: 0x%x, block_end_addr: %i size: %lu\n",
00227         start_addr, block_start_addr, end_addr, block_end_addr, size);
00228 
00229     if(BSP_SD_Erase (block_start_addr, block_end_addr) != MSD_OK) {
00230         status = SD_BLOCK_DEVICE_ERROR_ERASE;
00231     }
00232 
00233     /* Wait until SD card is ready to use for new operation */
00234     while(BSP_SD_GetCardState() != SD_TRANSFER_OK) {
00235     }
00236 
00237     unlock();
00238     return status;
00239 }
00240 
00241 bd_size_t SDBlockDeviceDISCOF746NG::get_read_size() const
00242 {
00243     return _read_size;
00244 }
00245 
00246 bd_size_t SDBlockDeviceDISCOF746NG::get_program_size() const
00247 {
00248     return _program_size;
00249 }
00250 
00251 bd_size_t SDBlockDeviceDISCOF746NG::get_erase_size() const
00252 {
00253     return _erase_size;
00254 }
00255 
00256 bd_size_t SDBlockDeviceDISCOF746NG::size() const
00257 {
00258     return (_block_size * _capacity_in_blocks);
00259 }
00260