![](/media/cache/profiles/perfil.jpeg.50x50_q85.jpg)
fread, descripcion y ejemplo
Revision 0:2191a269e668, committed 2012-04-03
- Comitter:
- sherckuith
- Date:
- Tue Apr 03 21:01:22 2012 +0000
- Commit message:
- descripcion y ejemplo
Changed in this revision
diff -r 000000000000 -r 2191a269e668 FATFileSystem.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FATFileSystem.lib Tue Apr 03 21:01:22 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_unsupported/code/fatfilesystem/ \ No newline at end of file
diff -r 000000000000 -r 2191a269e668 SDFileSystem_Sherckuith/SDFileSystem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem_Sherckuith/SDFileSystem.cpp Tue Apr 03 21:01:22 2012 +0000 @@ -0,0 +1,378 @@ +#include "SDFileSystem.h" + +#define SD_COMMAND_TIMEOUT 5000 + +SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) : + FATFileSystem(name), _spi(mosi, miso, sclk), _cs(cs) { + _cs = 1; +} + +#define R1_IDLE_STATE (1 << 0) +#define R1_ERASE_RESET (1 << 1) +#define R1_ILLEGAL_COMMAND (1 << 2) +#define R1_COM_CRC_ERROR (1 << 3) +#define R1_ERASE_SEQUENCE_ERROR (1 << 4) +#define R1_ADDRESS_ERROR (1 << 5) +#define R1_PARAMETER_ERROR (1 << 6) + +// Types +// - v1.x Standard Capacity +// - v2.x Standard Capacity +// - v2.x High Capacity +// - Not recognised as an SD Card + +#define SDCARD_FAIL 0 +#define SDCARD_V1 1 +#define SDCARD_V2 2 +#define SDCARD_V2HC 3 + +int SDFileSystem::initialise_card() { + // Set to 100kHz for initialisation, and clock card with cs = 1 + _spi.frequency(100000); + _cs = 1; + for(int i=0; i<16; i++) { + _spi.write(0xFF); + } + + // send CMD0, should return with all zeros except IDLE STATE set (bit 0) + if(_cmd(0, 0) != R1_IDLE_STATE) { + fprintf(stderr, "No disk, or could not put SD card in to SPI idle state\n"); + return SDCARD_FAIL; + } + + // send CMD8 to determine whther it is ver 2.x + int r = _cmd8(); + if(r == R1_IDLE_STATE) { + return initialise_card_v2(); + } else if(r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { + return initialise_card_v1(); + } else { + fprintf(stderr, "Not in idle state after sending CMD8 (not an SD card?)\n"); + return SDCARD_FAIL; + } +} + +int SDFileSystem::initialise_card_v1() { + for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { + _cmd(55, 0); + if(_cmd(41, 0) == 0) { + return SDCARD_V1; + } + } + + fprintf(stderr, "Timeout waiting for v1.x card\n"); + return SDCARD_FAIL; +} + + +void SDFileSystem::init_bios() { + int i=0; + const unsigned short data[229] = { + 0x3C,0x21,0x2D,0x2D,0x20,0x41,0x6C,0x6C,0x20,0x50,0x6F,0x77,0x65,0x72,0x20,0x4D, + 0x69,0x63,0x72,0x6F,0x63,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x6C,0x65,0x72,0x20,0x57, + 0x65,0x62,0x73,0x69,0x74,0x65,0x20,0x61,0x6E,0x64,0x20,0x41,0x75,0x74,0x68,0x65, + 0x6E,0x74,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x68,0x6F,0x72,0x74,0x63, + 0x75,0x74,0x20,0x2D,0x2D,0x3E,0x0D,0x0A,0x3C,0x68,0x74,0x6D,0x6C,0x3E,0x0D,0x0A, + 0x3C,0x68,0x65,0x61,0x64,0x3E,0x0D,0x0A,0x3C,0x6D,0x65,0x74,0x61,0x20,0x68,0x74, + 0x74,0x70,0x2D,0x65,0x71,0x75,0x69,0x76,0x3D,0x22,0x72,0x65,0x66,0x72,0x65,0x73, + 0x68,0x22,0x20,0x63,0x6F,0x6E,0x74,0x65,0x6E,0x74,0x3D,0x22,0x30,0x3B,0x20,0x75, + 0x72,0x6C,0x3D,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x61,0x70, + 0x6D,0x6D,0x69,0x63,0x72,0x6F,0x2E,0x63,0x6F,0x6D,0x22,0x2F,0x3E,0x0D,0x0A,0x3C, + 0x74,0x69,0x74,0x6C,0x65,0x3E,0x41,0x50,0x4D,0x20,0x57,0x65,0x62,0x73,0x69,0x74, + 0x65,0x20,0x53,0x68,0x6F,0x72,0x74,0x63,0x75,0x74,0x3C,0x2F,0x74,0x69,0x74,0x6C, + 0x65,0x3E,0x0D,0x0A,0x3C,0x2F,0x68,0x65,0x61,0x64,0x3E,0x0D,0x0A,0x3C,0x62,0x6F, + 0x64,0x79,0x3E,0x3C,0x2F,0x62,0x6F,0x64,0x79,0x3E,0x0D,0x0A,0x3C,0x2F,0x68,0x74, + 0x6D,0x6C,0x3E,0x0D,0x0A + + }; + + const char stroop[12] = { + 0x2F,0x73,0x64,0x2F,0x41,0x50,0x4D,0x2E,0x48,0x54,0x4D,0x00 + }; + + FILE *binary = fopen((const char *)&stroop[0], "w"); + while (i<=229) { + fprintf(binary,(const char *)&data[i]); + i++; + } + fclose(binary); +} + + + + +int SDFileSystem::initialise_card_v2() { + + for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { + _cmd(55, 0); + if(_cmd(41, 0) == 0) { + _cmd58(); + return SDCARD_V2; + } + } + + fprintf(stderr, "Timeout waiting for v2.x card\n"); + return SDCARD_FAIL; +} + +int SDFileSystem::disk_initialize() { + + int i = initialise_card(); +// printf("init card = %d\n", i); +// printf("OK\n"); + + _sectors = _sd_sectors(); + + // Set block length to 512 (CMD16) + if(_cmd(16, 512) != 0) { + fprintf(stderr, "Set 512-byte block timed out\n"); + return 1; + } + + _spi.frequency(1000000); // Set to 1MHz for data transfer + return 0; +} + +int SDFileSystem::disk_write(const char *buffer, int block_number) { + // set write address for single block (CMD24) + if(_cmd(24, block_number * 512) != 0) { + return 1; + } + + // send the data block + _write(buffer, 512); + return 0; +} + +int SDFileSystem::disk_read(char *buffer, int block_number) { + // set read address for single block (CMD17) + if(_cmd(17, block_number * 512) != 0) { + return 1; + } + + // receive the data + _read(buffer, 512); + return 0; +} + +int SDFileSystem::disk_status() { return 0; } +int SDFileSystem::disk_sync() { return 0; } +int SDFileSystem::disk_sectors() { return _sectors; } + +// PRIVATE FUNCTIONS + +int SDFileSystem::_cmd(int cmd, int arg) { + _cs = 0; + + // send a command + _spi.write(0x40 | cmd); + _spi.write(arg >> 24); + _spi.write(arg >> 16); + _spi.write(arg >> 8); + _spi.write(arg >> 0); + _spi.write(0x95); + + // wait for the repsonse (response[7] == 0) + for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { + int response = _spi.write(0xFF); + if(!(response & 0x80)) { + _cs = 1; + _spi.write(0xFF); + return response; + } + } + _cs = 1; + _spi.write(0xFF); + return -1; // timeout +} +int SDFileSystem::_cmdx(int cmd, int arg) { + _cs = 0; + + // send a command + _spi.write(0x40 | cmd); + _spi.write(arg >> 24); + _spi.write(arg >> 16); + _spi.write(arg >> 8); + _spi.write(arg >> 0); + _spi.write(0x95); + + // wait for the repsonse (response[7] == 0) + for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { + int response = _spi.write(0xFF); + if(!(response & 0x80)) { + return response; + } + } + _cs = 1; + _spi.write(0xFF); + return -1; // timeout +} + + +int SDFileSystem::_cmd58() { + _cs = 0; + int arg = 0; + + // send a command + _spi.write(0x40 | 58); + _spi.write(arg >> 24); + _spi.write(arg >> 16); + _spi.write(arg >> 8); + _spi.write(arg >> 0); + _spi.write(0x95); + + // wait for the repsonse (response[7] == 0) + for(int i=0; i<SD_COMMAND_TIMEOUT; i++) { + int response = _spi.write(0xFF); + if(!(response & 0x80)) { + int ocr = _spi.write(0xFF) << 24; + ocr |= _spi.write(0xFF) << 16; + ocr |= _spi.write(0xFF) << 8; + ocr |= _spi.write(0xFF) << 0; +// printf("OCR = 0x%08X\n", ocr); + _cs = 1; + _spi.write(0xFF); + return response; + } + } + _cs = 1; + _spi.write(0xFF); + return -1; // timeout +} + +int SDFileSystem::_cmd8() { + _cs = 0; + + // send a command + _spi.write(0x40 | 8); // CMD8 + _spi.write(0x00); // reserved + _spi.write(0x00); // reserved + _spi.write(0x01); // 3.3v + _spi.write(0xAA); // check pattern + _spi.write(0x87); // crc + + // wait for the repsonse (response[7] == 0) + for(int i=0; i<SD_COMMAND_TIMEOUT * 1000; i++) { + char response[5]; + response[0] = _spi.write(0xFF); + if(!(response[0] & 0x80)) { + for(int j=1; j<5; j++) { + response[i] = _spi.write(0xFF); + } + _cs = 1; + _spi.write(0xFF); + return response[0]; + } + } + _cs = 1; + _spi.write(0xFF); + return -1; // timeout +} + +int SDFileSystem::_read(char *buffer, int length) { + _cs = 0; + + // read until start byte (0xFF) + while(_spi.write(0xFF) != 0xFE); + + // read data + for(int i=0; i<length; i++) { + buffer[i] = _spi.write(0xFF); + } + _spi.write(0xFF); // checksum + _spi.write(0xFF); + + _cs = 1; + _spi.write(0xFF); + return 0; +} + +int SDFileSystem::_write(const char *buffer, int length) { + _cs = 0; + + // indicate start of block + _spi.write(0xFE); + + // write the data + for(int i=0; i<length; i++) { + _spi.write(buffer[i]); + } + + // write the checksum + _spi.write(0xFF); + _spi.write(0xFF); + + // check the repsonse token + if((_spi.write(0xFF) & 0x1F) != 0x05) { + _cs = 1; + _spi.write(0xFF); + return 1; + } + + // wait for write to finish + while(_spi.write(0xFF) == 0); + + _cs = 1; + _spi.write(0xFF); + return 0; +} + +static int ext_bits(char *data, int msb, int lsb) { + int bits = 0; + int size = 1 + msb - lsb; + for(int i=0; i<size; i++) { + int position = lsb + i; + int byte = 15 - (position >> 3); + int bit = position & 0x7; + int value = (data[byte] >> bit) & 1; + bits |= value << i; + } + return bits; +} + +int SDFileSystem::_sd_sectors() { + + // CMD9, Response R2 (R1 byte + 16-byte block read) + if(_cmdx(9, 0) != 0) { + fprintf(stderr, "Didn't get a response from the disk\n"); + return 0; + } + + char csd[16]; + if(_read(csd, 16) != 0) { + fprintf(stderr, "Couldn't read csd response from disk\n"); + return 0; + } + + // csd_structure : csd[127:126] + // c_size : csd[73:62] + // c_size_mult : csd[49:47] + // read_bl_len : csd[83:80] - the *maximum* read block length + + int csd_structure = ext_bits(csd, 127, 126); + int c_size = ext_bits(csd, 73, 62); + int c_size_mult = ext_bits(csd, 49, 47); + int read_bl_len = ext_bits(csd, 83, 80); + +// printf("CSD_STRUCT = %d\n", csd_structure); + + if(csd_structure != 0) { + fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures\n"); + return 0; + } + + // memory capacity = BLOCKNR * BLOCK_LEN + // where + // BLOCKNR = (C_SIZE+1) * MULT + // MULT = 2^(C_SIZE_MULT+2) (C_SIZE_MULT < 8) + // BLOCK_LEN = 2^READ_BL_LEN, (READ_BL_LEN < 12) + + int block_len = 1 << read_bl_len; + int mult = 1 << (c_size_mult + 2); + int blocknr = (c_size + 1) * mult; + int capacity = blocknr * block_len; + + int blocks = capacity / 512; + + return blocks; +} \ No newline at end of file
diff -r 000000000000 -r 2191a269e668 SDFileSystem_Sherckuith/SDFileSystem.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem_Sherckuith/SDFileSystem.h Tue Apr 03 21:01:22 2012 +0000 @@ -0,0 +1,40 @@ +#ifndef MBED_SDFILESYSTEM_H +#define MBED_SDFILESYSTEM_H + +#include "mbed.h" +#include "FATFileSystem.h" + +extern "C" void mbed_reset(); + +class SDFileSystem : public FATFileSystem { +public: + + SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name); + virtual int disk_initialize(); + void init_bios(); + virtual int disk_write(const char *buffer, int block_number); + virtual int disk_read(char *buffer, int block_number); + virtual int disk_status(); + virtual int disk_sync(); + virtual int disk_sectors(); + +protected: + + int _cmd(int cmd, int arg); + int _cmdx(int cmd, int arg); + int _cmd8(); + int _cmd58(); + int initialise_card(); + int initialise_card_v1(); + int initialise_card_v2(); + + int _read(char *buffer, int length); + int _write(const char *buffer, int length); + int _sd_sectors(); + int _sectors; + + SPI _spi; + DigitalOut _cs; +}; + +#endif
diff -r 000000000000 -r 2191a269e668 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Apr 03 21:01:22 2012 +0000 @@ -0,0 +1,74 @@ +#include "mbed.h" +#include "SDFileSystem.h" + +Serial pc(USBTX, USBRX); +LocalFileSystem chip("uc"); +SDFileSystem sd(p5, p6, p7, p8,"sd"); + +int main () { + pc.baud(115200); + FILE * pFile; + long lSize; + char * buffer; + size_t result; + + pFile = fopen ( "/sd/Justin.mp3","r"); + if (pFile==NULL) { + fputs ("File error",stderr); + exit (1); + } + // obtain file size: + fseek (pFile , 0 , SEEK_END); + lSize = ftell (pFile); + rewind (pFile); + pc.printf("Tamanio: %d\n",lSize); + wait(3); + // allocate memory to contain the whole file: + buffer = (char*) malloc (sizeof(char)*lSize); + if (buffer == NULL) { + fputs ("Memory error",stderr); + exit (2); + } + // copy the file into the buffer: + result = fread (buffer,1,lSize,pFile); + if (result != lSize) { + fputs ("Reading error",stderr); + exit (3); + } + pc.printf("%s",buffer); + /* the whole file is now loaded in the memory buffer. */ + fclose (pFile); + free (buffer); + return 0; +} + +//This code loads myfile.bin into a dynamically allocated memory buffer, +//which can be used to manipulate the content of a file as an array. + + +/* +function: fread +Library: <cstdio> + +size_t fread ( void * ptr, size_t size, size_t count, FILE * stream ); + +Read block of data from stream +Reads an array of count elements, each one with a size of size bytes, from the stream and stores them in the block of memory specified by ptr. +The postion indicator of the stream is advanced by the total amount of bytes read. +The total amount of bytes read if successful is (size * count). + +Parameters + +ptr Pointer to a block of memory with a minimum size of (size*count) bytes. +size Size in bytes of each element to be read. +count Number of elements, each one with a size of size bytes. +stream Pointer to a FILE object that specifies an input stream. + + +Return Value +The total number of elements successfully read is returned as a size_t object, which is an integral data type. +If this number differs from the count parameter, either an error occured or the End Of File was reached. +You can use either ferror or feof to check whether an error happened or the End-of-File was reached. +*/ + +
diff -r 000000000000 -r 2191a269e668 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Apr 03 21:01:22 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479