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
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
Generated on Tue Jul 12 2022 19:08:01 by 1.7.2