test
Diff: chan_fs/diskio.c
- Revision:
- 1:68378811b1e2
- Parent:
- 0:c1253c12d4bc
--- a/chan_fs/diskio.c Sun Feb 21 02:45:09 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,300 +0,0 @@ -/*-----------------------------------------------------------------------*/ -/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */ -/*-----------------------------------------------------------------------*/ -/* This is a stub disk I/O module that acts as front end of the existing */ -/* disk I/O modules and attach it to FatFs module with common interface. */ -/*-----------------------------------------------------------------------*/ - -#include "diskio.h" -#include "mbed.h" - - -//****************************************************************************************************************** -// MBED SPI/CS Select functions.... Modify for your layout. -//************************************************************************************** - -SPI _spi(p5, p6, p7); // mosi, miso, sclk -DigitalOut _cs(p8); - -//****************************************************************************************************************** -// Low Level Sector Access Function Prototypes('C' Castrated versions of Simon Ford's C++ MBED SDFileSystem class -//****************************************************************************************************************** -int _cmd(int cmd, int arg); -int _read(BYTE *buffer, int length); -int _write(BYTE *buffer, int length); -int ext_bits(BYTE *data, int msb, int lsb); -int _sd_sectors(); -int _sectors; - -#define SD_COMMAND_TIMEOUT 5000 - - -//****************************************************************************************************************** -// Sector Access functions for CHAN FatFs -//****************************************************************************************************************** - -DRESULT disk_ioctl ( - BYTE drv, /* Physical drive nmuber (0..) */ - BYTE ctrl, /* Control code */ - void *buff /* Buffer to send/receive control data */ -) -{ - DRESULT res; - - switch(ctrl) - { - case CTRL_SYNC: - res = RES_OK; - break; - - case GET_SECTOR_SIZE: - res = RES_OK; - *(WORD *)buff = 512; - break; - - case GET_SECTOR_COUNT: - res = RES_OK; - *(DWORD *)buff = (WORD)_sd_sectors(); - break; - - case GET_BLOCK_SIZE: - res = RES_OK; - *(DWORD *)buff = 1; - break; - - default: - res = RES_OK; - break; - } - return res; -} - -DSTATUS disk_initialize(BYTE Drive) { - - _spi.frequency(100000); // Set to 100kHz for initialisation - - // Initialise the card by clocking it a bit (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) != 0x01) { - fprintf(stderr, "Not in idle state\n"); - return STA_NOINIT; - } - - // ACMD41 to give host capacity support (repeat until not busy) - // ACMD41 is application specific command, so we send APP_CMD (CMD55) beforehand - for(int i=0;; i++) { - _cmd(55, 0); - int response = _cmd(41, 0); - if(response == 0) { - break; - } else if(i > SD_COMMAND_TIMEOUT) { - fprintf(stderr, "Timeout waiting for card\n"); - return STA_NOINIT; - } - } - - _sectors = _sd_sectors(); - - // Set block length to 512 (CMD16) - if(_cmd(16, 512) != 0) { - fprintf(stderr, "Set block timeout\n"); - return STA_NOINIT; - } - - _spi.frequency(10000000); // Set to 10MHz for data transfer - return 0; -} - -DRESULT disk_write(BYTE Drive,const BYTE * Buffer, DWORD SectorNumber, BYTE SectorCount) -{ - BYTE i; - - BYTE * MyBufOut = (BYTE *)Buffer; - - for(i=0;i<SectorCount;i++) - { - // set write address for single block (CMD24) - if(_cmd(24, (SectorNumber + i) * 512 ) != 0) { - return RES_ERROR; - } - - // send the data block - _write(MyBufOut, 512); - - MyBufOut+=512; - } - return RES_OK; -} - -DRESULT disk_read(BYTE Drive, BYTE * Buffer,DWORD SectorNumber, BYTE SectorCount) -{ - BYTE i; - for(i=0;i<SectorCount;i++) - { - // set read address for single block (CMD17) - if(_cmd(17, (SectorNumber+i) * 512) != 0) - { - return RES_ERROR; - } - // receive the data - _read(Buffer, 512); - - Buffer+=512; - } - return RES_OK; -} - - -DWORD get_fattime(void) -{ - time_t CurrentTimeStamp; - tm *CurrentLocalTime; - DWORD FATFSTimeCode; - - CurrentTimeStamp = time(NULL); - CurrentLocalTime = localtime(&CurrentTimeStamp); - - //Map the tm struct time into the FatFs time code - FATFSTimeCode = ((CurrentLocalTime->tm_year-80)<<25) | - ((CurrentLocalTime->tm_mon+1)<<21) | - ((CurrentLocalTime->tm_mday)<<16) | - ((CurrentLocalTime->tm_hour)<<11) | - ((CurrentLocalTime->tm_min)<<5) | - ((CurrentLocalTime->tm_sec)); - - return FATFSTimeCode; -} - -DSTATUS disk_status(BYTE Drive) -{ - return 0; -} - -//************************************************************************************** -// Low Level Sector Access Functions (Castrated versions of Simon Fords C++ MBED class -//************************************************************************************** - -int _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; - return response; - } - } - _cs = 1; - return -1; // timeout -} - -int _read(BYTE *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; - return 0; -} - -int _write(BYTE *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; - return 1; - } - - // wait for write to finish - while(_spi.write(0xFF) == 0); - - _cs = 1; - return 0; -} - -int ext_bits(BYTE *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 _sd_sectors() { - - // CMD9, Response R2 (R1 byte + 16-byte block read) - if(_cmd(9, 0) != 0) { - fprintf(stderr, "Didn't get a response from the disk\n"); - return 0; - } - - BYTE 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] - - 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); - - if(csd_structure != 0) { - fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures"); - return 0; - } - - int blocks = (c_size + 1) * (1 << (c_size_mult + 2)); - int block_size = 1 << read_bl_len; - - if(block_size != 512) { - fprintf(stderr, "This disk tastes funny! I only like 512 byte blocks (%d)\r\n",block_size); - return 0; - } - - return blocks; -}