Test of Embedded Artists LPCXpresso baseboard ethernet, SD card, audio and OLED display facilities. The program displays the day, date and time on the baseboard OLED and sounds the Big Ben chimes on the hour and quarter hour. On initial startup the program checks that the mbed clock is set and that the chime wav files can be accessed on the SD card. If not it asks to be connected to the internet to obtain the current time and to download the wav files to the SD card.
Dependencies: EthernetNetIf NTPClient_NetServices mbed EAOLED
SDHCFileSystem.cpp
00001 /* mbed SDFileSystem Library, for providing file access to SD cards 00002 * Copyright (c) 2008-2010, sford 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy 00005 * of this software and associated documentation files (the "Software"), to deal 00006 * in the Software without restriction, including without limitation the rights 00007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 * copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in 00012 * all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 * THE SOFTWARE. 00021 */ 00022 00023 /* Introduction 00024 * ------------ 00025 * SD and MMC cards support a number of interfaces, but common to them all 00026 * is one based on SPI. This is the one I'm implmenting because it means 00027 * it is much more portable even though not so performant, and we already 00028 * have the mbed SPI Interface! 00029 * 00030 * The main reference I'm using is Chapter 7, "SPI Mode" of: 00031 * http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf 00032 * 00033 * SPI Startup 00034 * ----------- 00035 * The SD card powers up in SD mode. The SPI interface mode is selected by 00036 * asserting CS low and sending the reset command (CMD0). The card will 00037 * respond with a (R1) response. 00038 * 00039 * CMD8 is optionally sent to determine the voltage range supported, and 00040 * indirectly determine whether it is a version 1.x SD/non-SD card or 00041 * version 2.x. I'll just ignore this for now. 00042 * 00043 * ACMD41 is repeatedly issued to initialise the card, until "in idle" 00044 * (bit 0) of the R1 response goes to '0', indicating it is initialised. 00045 * 00046 * You should also indicate whether the host supports High Capicity cards, 00047 * and check whether the card is high capacity - i'll also ignore this 00048 * 00049 * SPI Protocol 00050 * ------------ 00051 * The SD SPI protocol is based on transactions made up of 8-bit words, with 00052 * the host starting every bus transaction by asserting the CS signal low. The 00053 * card always responds to commands, data blocks and errors. 00054 * 00055 * The protocol supports a CRC, but by default it is off (except for the 00056 * first reset CMD0, where the CRC can just be pre-calculated, and CMD8) 00057 * I'll leave the CRC off I think! 00058 * 00059 * Standard capacity cards have variable data block sizes, whereas High 00060 * Capacity cards fix the size of data block to 512 bytes. I'll therefore 00061 * just always use the Standard Capacity cards with a block size of 512 bytes. 00062 * This is set with CMD16. 00063 * 00064 * You can read and write single blocks (CMD17, CMD25) or multiple blocks 00065 * (CMD18, CMD25). For simplicity, I'll just use single block accesses. When 00066 * the card gets a read command, it responds with a response token, and then 00067 * a data token or an error. 00068 * 00069 * SPI Command Format 00070 * ------------------ 00071 * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC. 00072 * 00073 * +---------------+------------+------------+-----------+----------+--------------+ 00074 * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 | 00075 * +---------------+------------+------------+-----------+----------+--------------+ 00076 * 00077 * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95) 00078 * 00079 * All Application Specific commands shall be preceded with APP_CMD (CMD55). 00080 * 00081 * SPI Response Format 00082 * ------------------- 00083 * The main response format (R1) is a status byte (normally zero). Key flags: 00084 * idle - 1 if the card is in an idle state/initialising 00085 * cmd - 1 if an illegal command code was detected 00086 * 00087 * +-------------------------------------------------+ 00088 * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle | 00089 * +-------------------------------------------------+ 00090 * 00091 * R1b is the same, except it is followed by a busy signal (zeros) until 00092 * the first non-zero byte when it is ready again. 00093 * 00094 * Data Response Token 00095 * ------------------- 00096 * Every data block written to the card is acknowledged by a byte 00097 * response token 00098 * 00099 * +----------------------+ 00100 * | xxx | 0 | status | 1 | 00101 * +----------------------+ 00102 * 010 - OK! 00103 * 101 - CRC Error 00104 * 110 - Write Error 00105 * 00106 * Single Block Read and Write 00107 * --------------------------- 00108 * 00109 * Block transfers have a byte header, followed by the data, followed 00110 * by a 16-bit CRC. In our case, the data will always be 512 bytes. 00111 * 00112 * +------+---------+---------+- - - -+---------+-----------+----------+ 00113 * | 0xFE | data[0] | data[1] | | data[n] | crc[15:8] | crc[7:0] | 00114 * +------+---------+---------+- - - -+---------+-----------+----------+ 00115 */ 00116 00117 /* 00118 * Comment: Changes for SDHC support till 32GB 00119 * Name: KB 00120 * Date: 07/24/2010 00121 * Release: 0.1 00122 */ 00123 00124 #include "SDHCFileSystem.h" 00125 00126 #define DEBUG 00127 #define SD_COMMAND_TIMEOUT 5000 00128 00129 00130 SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) : 00131 FATFileSystem(name), _spi(mosi, miso, sclk), _cs(cs) { 00132 _cs = 1; 00133 } 00134 00135 #define R1_IDLE_STATE (1 << 0) 00136 #define R1_ERASE_RESET (1 << 1) 00137 #define R1_ILLEGAL_COMMAND (1 << 2) 00138 #define R1_COM_CRC_ERROR (1 << 3) 00139 #define R1_ERASE_SEQUENCE_ERROR (1 << 4) 00140 #define R1_ADDRESS_ERROR (1 << 5) 00141 #define R1_PARAMETER_ERROR (1 << 6) 00142 00143 // Types 00144 // - v1.x Standard Capacity 00145 // - v2.x Standard Capacity 00146 // - v2.x High Capacity 00147 // - Not recognised as an SD Card 00148 00149 #define SDCARD_FAIL 0 00150 #define SDCARD_V1 1 00151 #define SDCARD_V2 2 00152 #define SDCARD_V2HC 3 00153 00154 int SDFileSystem::initialise_card() { 00155 // Set to 100kHz for initialisation, and clock card with cs = 1 00156 _spi.frequency(100000); 00157 _cs = 1; 00158 for(int i=0; i<16; i++) { 00159 _spi.write(0xFF); 00160 } 00161 00162 // send CMD0, should return with all zeros except IDLE STATE set (bit 0) 00163 if(_cmd(0, 0) != R1_IDLE_STATE) { 00164 fprintf(stderr, "No disk, or could not put SD card in to SPI idle state\n"); 00165 return SDCARD_FAIL; 00166 } 00167 00168 // send CMD8 to determine whther it is ver 2.x 00169 int r = _cmd8(); 00170 if(r == R1_IDLE_STATE) { 00171 return initialise_card_v2(); 00172 } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { 00173 return initialise_card_v1(); 00174 } else { 00175 fprintf(stderr, "Not in idle state after sending CMD8 (not an SD card?)\n"); 00176 return SDCARD_FAIL; 00177 } 00178 } 00179 00180 int SDFileSystem::initialise_card_v1() { 00181 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00182 _cmd(55, 0); 00183 if(_cmd(41, 0) == 0) { 00184 cdv = 512; 00185 #ifdef DEBUG 00186 printf("\n\rInit: SEDCARD_V1\n\r"); 00187 #endif 00188 return SDCARD_V1; 00189 } 00190 } 00191 00192 fprintf(stderr, "Timeout waiting for v1.x card\n"); 00193 return SDCARD_FAIL; 00194 } 00195 00196 int SDFileSystem::initialise_card_v2() { 00197 00198 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00199 wait_ms(50); 00200 _cmd58(); 00201 _cmd(55, 0); 00202 if(_cmd(41, 0x40000000) == 0) { 00203 _cmd58(); 00204 #ifdef DEBUG 00205 printf("\n\rInit: SDCARD_V2\n\r"); 00206 #endif 00207 cdv = 1; 00208 return SDCARD_V2; 00209 } 00210 } 00211 00212 fprintf(stderr, "Timeout waiting for v2.x card\n"); 00213 return SDCARD_FAIL; 00214 } 00215 00216 int SDFileSystem::disk_initialize() { 00217 00218 int i = initialise_card(); 00219 #ifdef DEBUG 00220 printf("init card = %d\n", i); 00221 #endif 00222 _sectors = _sd_sectors(); 00223 00224 // Set block length to 512 (CMD16) 00225 if(_cmd(16, 512) != 0) { 00226 fprintf(stderr, "Set 512-byte block timed out\n"); 00227 return 1; 00228 } 00229 00230 _spi.frequency(1000000); // Set to 1MHz for data transfer 00231 return 0; 00232 } 00233 00234 int SDFileSystem::disk_write(const char *buffer, int block_number) { 00235 // set write address for single block (CMD24) 00236 if(_cmd(24, block_number * cdv) != 0) { 00237 return 1; 00238 } 00239 00240 // send the data block 00241 _write(buffer, 512); 00242 return 0; 00243 } 00244 00245 int SDFileSystem::disk_read(char *buffer, int block_number) { 00246 // set read address for single block (CMD17) 00247 if(_cmd(17, block_number * cdv) != 0) { 00248 return 1; 00249 } 00250 00251 // receive the data 00252 _read(buffer, 512); 00253 return 0; 00254 } 00255 00256 int SDFileSystem::disk_status() { return 0; } 00257 int SDFileSystem::disk_sync() { return 0; } 00258 int SDFileSystem::disk_sectors() { return _sectors; } 00259 00260 // PRIVATE FUNCTIONS 00261 00262 int SDFileSystem::_cmd(int cmd, int arg) { 00263 _cs = 0; 00264 00265 // send a command 00266 _spi.write(0x40 | cmd); 00267 _spi.write(arg >> 24); 00268 _spi.write(arg >> 16); 00269 _spi.write(arg >> 8); 00270 _spi.write(arg >> 0); 00271 _spi.write(0x95); 00272 00273 // wait for the repsonse (response[7] == 0) 00274 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00275 int response = _spi.write(0xFF); 00276 if(!(response & 0x80)) { 00277 _cs = 1; 00278 _spi.write(0xFF); 00279 return response; 00280 } 00281 } 00282 _cs = 1; 00283 _spi.write(0xFF); 00284 return -1; // timeout 00285 } 00286 int SDFileSystem::_cmdx(int cmd, int arg) { 00287 _cs = 0; 00288 00289 // send a command 00290 _spi.write(0x40 | cmd); 00291 _spi.write(arg >> 24); 00292 _spi.write(arg >> 16); 00293 _spi.write(arg >> 8); 00294 _spi.write(arg >> 0); 00295 _spi.write(0x95); 00296 00297 // wait for the repsonse (response[7] == 0) 00298 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00299 int response = _spi.write(0xFF); 00300 if(!(response & 0x80)) { 00301 return response; 00302 } 00303 } 00304 _cs = 1; 00305 _spi.write(0xFF); 00306 return -1; // timeout 00307 } 00308 00309 00310 int SDFileSystem::_cmd58() { 00311 _cs = 0; 00312 int arg = 0; 00313 00314 // send a command 00315 _spi.write(0x40 | 58); 00316 _spi.write(arg >> 24); 00317 _spi.write(arg >> 16); 00318 _spi.write(arg >> 8); 00319 _spi.write(arg >> 0); 00320 _spi.write(0x95); 00321 00322 // wait for the repsonse (response[7] == 0) 00323 for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { 00324 int response = _spi.write(0xFF); 00325 if(!(response & 0x80)) { 00326 int ocr = _spi.write(0xFF) << 24; 00327 ocr |= _spi.write(0xFF) << 16; 00328 ocr |= _spi.write(0xFF) << 8; 00329 ocr |= _spi.write(0xFF) << 0; 00330 // printf("OCR = 0x%08X\n", ocr); 00331 _cs = 1; 00332 _spi.write(0xFF); 00333 return response; 00334 } 00335 } 00336 _cs = 1; 00337 _spi.write(0xFF); 00338 return -1; // timeout 00339 } 00340 00341 int SDFileSystem::_cmd8() { 00342 _cs = 0; 00343 00344 // send a command 00345 _spi.write(0x40 | 8); // CMD8 00346 _spi.write(0x00); // reserved 00347 _spi.write(0x00); // reserved 00348 _spi.write(0x01); // 3.3v 00349 _spi.write(0xAA); // check pattern 00350 _spi.write(0x87); // crc 00351 00352 // wait for the repsonse (response[7] == 0) 00353 for(int i=0; i<SD_COMMAND_TIMEOUT * 1000; i++) { 00354 char response[5]; 00355 response[0] = _spi.write(0xFF); 00356 if(!(response[0] & 0x80)) { 00357 for(int j=1; j<5; j++) { 00358 response[i] = _spi.write(0xFF); 00359 } 00360 _cs = 1; 00361 _spi.write(0xFF); 00362 return response[0]; 00363 } 00364 } 00365 _cs = 1; 00366 _spi.write(0xFF); 00367 return -1; // timeout 00368 } 00369 00370 int SDFileSystem::_read(char *buffer, int length) { 00371 _cs = 0; 00372 00373 // read until start byte (0xFF) 00374 while(_spi.write(0xFF) != 0xFE); 00375 00376 // read data 00377 for(int i=0; i<length; i++) { 00378 buffer[i] = _spi.write(0xFF); 00379 } 00380 _spi.write(0xFF); // checksum 00381 _spi.write(0xFF); 00382 00383 _cs = 1; 00384 _spi.write(0xFF); 00385 return 0; 00386 } 00387 00388 int SDFileSystem::_write(const char *buffer, int length) { 00389 _cs = 0; 00390 00391 // indicate start of block 00392 _spi.write(0xFE); 00393 00394 // write the data 00395 for(int i=0; i<length; i++) { 00396 _spi.write(buffer[i]); 00397 } 00398 00399 // write the checksum 00400 _spi.write(0xFF); 00401 _spi.write(0xFF); 00402 00403 // check the repsonse token 00404 if((_spi.write(0xFF) & 0x1F) != 0x05) { 00405 _cs = 1; 00406 _spi.write(0xFF); 00407 return 1; 00408 } 00409 00410 // wait for write to finish 00411 while(_spi.write(0xFF) == 0); 00412 00413 _cs = 1; 00414 _spi.write(0xFF); 00415 return 0; 00416 } 00417 00418 static int ext_bits(char *data, int msb, int lsb) { 00419 int bits = 0; 00420 int size = 1 + msb - lsb; 00421 for(int i=0; i<size; i++) { 00422 int position = lsb + i; 00423 int byte = 15 - (position >> 3); 00424 int bit = position & 0x7; 00425 int value = (data[byte] >> bit) & 1; 00426 bits |= value << i; 00427 } 00428 return bits; 00429 } 00430 00431 int SDFileSystem::_sd_sectors() { 00432 00433 int c_size, c_size_mult, read_bl_len; 00434 int block_len, mult, blocknr, capacity; 00435 int blocks, hc_c_size; 00436 uint64_t hc_capacity; 00437 00438 // CMD9, Response R2 (R1 byte + 16-byte block read) 00439 if(_cmdx(9, 0) != 0) { 00440 fprintf(stderr, "Didn't get a response from the disk\n"); 00441 return 0; 00442 } 00443 00444 char csd[16]; 00445 if(_read(csd, 16) != 0) { 00446 fprintf(stderr, "Couldn't read csd response from disk\n"); 00447 return 0; 00448 } 00449 00450 // csd_structure : csd[127:126] 00451 // c_size : csd[73:62] 00452 // c_size_mult : csd[49:47] 00453 // read_bl_len : csd[83:80] - the *maximum* read block length 00454 00455 int csd_structure = ext_bits(csd, 127, 126); 00456 00457 #ifdef DEBUG 00458 printf("\n\rCSD_STRUCT = %d\n", csd_structure); 00459 #endif 00460 00461 switch (csd_structure){ 00462 case 0: 00463 cdv = 512; 00464 c_size = ext_bits(csd, 73, 62); 00465 c_size_mult = ext_bits(csd, 49, 47); 00466 read_bl_len = ext_bits(csd, 83, 80); 00467 00468 block_len = 1 << read_bl_len; 00469 mult = 1 << (c_size_mult + 2); 00470 blocknr = (c_size + 1) * mult; 00471 capacity = blocknr * block_len; 00472 blocks = capacity / 512; 00473 #ifdef DEBUG 00474 printf("\n\rSDCard\n\rc_size: %.4X \n\rcapacity: %.ld \n\rsectors: %d\n\r", c_size, capacity, blocks); 00475 #endif 00476 break; 00477 00478 case 1: 00479 cdv = 1; 00480 hc_c_size = ext_bits(csd, 63, 48); 00481 int hc_read_bl_len = ext_bits(csd, 83, 80); 00482 hc_capacity = hc_c_size+1; 00483 blocks = (hc_c_size+1)*1024; 00484 #ifdef DEBUG 00485 printf("\n\rSDHC Card \n\rhc_c_size: %.4X \n\rcapacity: %.lld \n\rsectors: %d\n\r", hc_c_size, hc_capacity*512*1024, blocks); 00486 #endif 00487 break; 00488 00489 default: 00490 fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures\n"); 00491 return 0; 00492 // break; 00493 }; 00494 return blocks; 00495 }
Generated on Mon Jul 25 2022 09:57:29 by 1.7.2