📄 sdp.nc
字号:
for(j = 0; j < 512; j++){
if(spiSendByte(0xff)){
break;
}
}
return response;
}
error_t setIdle(){
char response;
CS_LOW();
// put card in SPI mode
sendCmd(MMC_GO_IDLE_STATE, 0, 0x95);
// confirm that card is READY
if((response = getResponse()) != 0x01)
return MMC_INIT_ERROR;
do{
CS_HIGH();
spiSendByte(0xff);
CS_LOW();
sendCmd(MMC_SEND_OP_COND, 0x00, 0xff);
}while((response = getResponse()) == 0x01);
CS_HIGH();
spiSendByte(0xff);
return MMC_SUCCESS;
}
error_t cardInit(){
register uint8_t i;
uint8_t r;
initSPI();
CS_HIGH();
for(i = 0; i < 10; i++)
spiSendByte(0xff);
r = setIdle();
// here's where we set the clock speed up to smclk / 2 (512k)
call Usart.setUbr(0x0002);
call Usart.setUmctl(0x00);
return r;
}
// change block length to 2^len bytes; default is 512
error_t setBlockLength (const uint16_t len) {
CS_LOW ();
sendCmd(MMC_SET_BLOCKLEN, len, 0xff);
// get response from card, should be 0; so, shouldn't this be 'while'?
if(getResponse() != 0x00){
cardInit();
sendCmd(MMC_SET_BLOCKLEN, len, 0xff);
getResponse();
}
CS_HIGH ();
// Send 8 Clock pulses of delay.
spiSendByte(0xff);
return MMC_SUCCESS;
}
/*
* renamed to clear the way for renaming what was readSector -- which called this --
* to be renamed readBlock. --sma
*/
error_t read_block(const uint32_t address, const uint16_t count, uint8_t * buffer){
register uint16_t i = 0;
uint8_t rvalue = MMC_RESPONSE_ERROR;
// Set the block length to read
if(setBlockLength(count) == MMC_SUCCESS){ // block length can be set
CS_LOW ();
sendCmd(MMC_READ_SINGLE_BLOCK, address, 0xff);
// Send 8 Clock pulses of delay, check if the MMC acknowledged the read block command
// it will do this by sending an affirmative response
// in the R1 format (0x00 is no errors)
if(getResponse() == 0x00){
// now look for the data token to signify the start of the data
if(getXXResponse(MMC_START_DATA_BLOCK_TOKEN) == MMC_START_DATA_BLOCK_TOKEN){
// clock the actual data transfer and receive the bytes; spi_read automatically finds the Data Block
for (i = 0; i < count; i++)
buffer[i] = spiSendByte(0xff); // is executed with card inserted
// get CRC bytes (not really needed by us, but required by MMC)
spiSendByte(0xff);
spiSendByte(0xff);
rvalue = MMC_SUCCESS;
}
else{
// the data token was never received
rvalue = MMC_DATA_TOKEN_ERROR; // 3
}
}
else{
// the MMC never acknowledge the read command
rvalue = MMC_RESPONSE_ERROR; // 2
}
}
else{
rvalue = MMC_BLOCK_SET_ERROR; // 1
}
CS_HIGH ();
spiSendByte(0xff);
return rvalue;
}
/*
* need to test dock pin for some platforms
* on others this will be attached to a pullup
*/
command error_t SD.readBlock(const uint32_t sector, uint8_t * buffer) {
if(!TOSH_READ_DOCK_N_PIN())
return MMC_INIT_ERROR;
return read_block(sector * 512, 512, buffer);
}
error_t write_block(const uint32_t address, const uint16_t count, uint8_t * buffer){
register uint16_t i;
uint8_t rvalue = MMC_RESPONSE_ERROR; // MMC_SUCCESS;
// Set the block length to write
if(setBlockLength (count) == MMC_SUCCESS){ // block length could be set
CS_LOW ();
sendCmd(MMC_WRITE_BLOCK, address, 0xff);
// check if the MMC acknowledged the write block command
// it will do this by sending an affirmative response
// in the R1 format (0x00 is no errors)
if(getXXResponse(MMC_R1_RESPONSE) == MMC_R1_RESPONSE){
spiSendByte(0xff);
// send the data token to signify the start of the data
spiSendByte(0xfe);
// clock the actual data transfer and transmitt the bytes
for(i = 0; i < count; i++)
spiSendByte(buffer[i]);
// put CRC bytes (not really needed by us, but required by MMC)
spiSendByte(0xff);
spiSendByte(0xff);
// read the data response xxx0<status>1 : status 010: Data accected, status 101: Data
// rejected due to a crc error, status 110: Data rejected due to a Write error.
checkBusy();
rvalue = MMC_SUCCESS;
}
else{
// the MMC never acknowledge the write command
rvalue = MMC_RESPONSE_ERROR; // 2
}
}
else{
rvalue = MMC_BLOCK_SET_ERROR; // 1
}
CS_HIGH ();
// Send 8 Clock pulses of delay.
spiSendByte(0xff);
return rvalue;
}
command error_t SD.writeBlock(const uint32_t sector, uint8_t * buffer){
/*
* need to test dock pin for some platforms
* on others this will be attached to a pullup
*/
if(!TOSH_READ_DOCK_N_PIN())
return MMC_INIT_ERROR;
return write_block(sector * 512, 512, buffer);
}
/*
* feel our way out over the cliff of the card to estimate the size
* turns out cmd9 is not supported on sdio, as there's no csd register
*/
uint32_t hackGetCardSize() {
uint32_t howbig = 0;
uint8_t b[512];
error_t failed;
/* we'll estimate based upon popular sizes of cards, e.g. 128mb, 256 mb, 512mb, 1gb, 2gb
* experimentally, we find that 512mb == ~990900 sectors, 1gb == ~1983000 sectors
* extrapolating down, we'll say that 247700 should be readable on a 128mb
* reading beyond that returns an error
*/
failed = call SD.readBlock(0, b);
failed = call SD.readBlock(200000, b);
// if we can't get this far, we're toast anyway
if(!failed){
howbig = 247000;
while(!call SD.readBlock(howbig, b)){
howbig = howbig * 2;
}
howbig = howbig / 2;
}
return howbig;
}
// Read the Card Size from the CSD Register
// this command is unsupported on sdio-only, like sandisk micro sd cards
command uint32_t SD.readCardSize(){
// Read contents of Card Specific Data (CSD)
uint32_t MMC_CardSize = 0;
uint16_t i, j, b, response, mmc_C_SIZE;
uint8_t mmc_READ_BL_LEN, mmc_C_SIZE_MULT;
// return hackGetCardSize();
CS_LOW ();
spiSendByte(MMC_READ_CSD); // CMD 9
for(i = 0; i < 4; i++) // Send four dummy bytes
spiSendByte(0);
spiSendByte(0xff); // Send CRC byte
response = getResponse();
// data transmission always starts with 0xFE
b = spiSendByte(0xff);
if(!response){
while(b != 0xfe)
b = spiSendByte(0xff);
// bits 127:87
for(j = 0; j < 5; j++) // Host must keep the clock running for at
b = spiSendByte(0xff);
// 4 bits of READ_BL_LEN
// bits 84:80
b = spiSendByte(0xff); // lower 4 bits of CCC and
mmc_READ_BL_LEN = b & 0x0f;
b = spiSendByte(0xff);
// bits 73:62 C_Size
// xxCC CCCC CCCC CC
mmc_C_SIZE = (b & 0x03) << 10;
b = spiSendByte(0xff);
mmc_C_SIZE += b << 2;
b = spiSendByte(0xff);
mmc_C_SIZE += b >> 6;
// bits 55:53
b = spiSendByte(0xff);
// bits 49:47
mmc_C_SIZE_MULT = (b & 0x03) << 1;
b = spiSendByte(0xff);
mmc_C_SIZE_MULT += b >> 7;
// bits 41:37
b = spiSendByte(0xff);
b = spiSendByte(0xff);
b = spiSendByte(0xff);
b = spiSendByte(0xff);
b = spiSendByte(0xff);
for(j = 0; j < 4; j++) // Host must keep the clock running for at
b = spiSendByte(0xff); // least Ncr (max = 4 bytes) cycles after
// the card response is received
b = spiSendByte(0xff);
CS_LOW ();
MMC_CardSize = (mmc_C_SIZE + 1);
for(i = 2, j = mmc_C_SIZE_MULT + 2; j > 1; j--)
i <<= 1;
MMC_CardSize *= i;
for(i = 2,j = mmc_READ_BL_LEN; j > 1; j--)
i <<= 1;
MMC_CardSize *= i;
}
return MMC_CardSize;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -