u08 mmcRead(u32 sector, u08* buffer) { u08 r1; u16 i; // assert chip select cbi(MMC_CS_PORT,MMC_CS_PIN); // issue command r1 = mmcCommand(MMC_READ_SINGLE_BLOCK, sector<<9); #ifdef MMC_DEBUG rprintf("MMC Read Block R1=0x%x\r\n", r1); #endif // check for valid response if(r1 != 0x00) return r1; // wait for block start while(spiTransferByte(0xFF) != MMC_STARTBLOCK_READ); // read in data for(i=0; i<0x200; i++) { *buffer++ = spiTransferByte(0xFF); } // read 16-bit CRC spiTransferByte(0xFF); spiTransferByte(0xFF); // release chip select sbi(MMC_CS_PORT,MMC_CS_PIN); // return success return 0; }
u08 mmcSendCommand(u08 cmd, u32 arg) { u08 r1; // assert chip select cbi(MMC_CS_PORT,MMC_CS_PIN); // issue the command r1 = mmcCommand(cmd, arg); // release chip select sbi(MMC_CS_PORT,MMC_CS_PIN); return r1; }
u08 mmcSendCommand(u08 cmd, u32 arg) { u08 r1; u16 wait = 0; // assert chip select _mmcEnableCS(); spiTransferByte(0xFF); // issue the command r1 = mmcCommand(cmd, arg); // release chip select while (wait < 1900) { wait++; } _mmcDisableCS(); return r1; }
u08 mmcWrite(u32 sector, u08* buffer) { u08 r1; u16 i; // assert chip select cbi(MMC_CS_PORT,MMC_CS_PIN); // issue command r1 = mmcCommand(MMC_WRITE_BLOCK, sector<<9); #ifdef MMC_DEBUG rprintf("MMC Write Block R1=0x%x\r\n", r1); #endif // check for valid response if(r1 != 0x00) return r1; // send dummy spiTransferByte(0xFF); // send data start token spiTransferByte(MMC_STARTBLOCK_WRITE); // write data for(i=0; i<0x200; i++) { spiTransferByte(*buffer++); } // write 16-bit CRC (dummy values) spiTransferByte(0xFF); spiTransferByte(0xFF); // read data response token r1 = spiTransferByte(0xFF); if( (r1&MMC_DR_MASK) != MMC_DR_ACCEPT) return r1; #ifdef MMC_DEBUG rprintf("Data Response Token=0x%x\r\n", r1); #endif // wait until card not busy while(!spiTransferByte(0xFF)); // release chip select sbi(MMC_CS_PORT,MMC_CS_PIN); // return success return 0; }
u08 mmcWrite(u32 sector, u08* buffer) { u08 r1; u16 i; u16 retries; spiSetClockPhase(SD_CLOCK_PHASE); spiSetBitrate(SD_TRANSFER_SPI_DIV); // assert chip select _mmcEnableCS(); retries = 0; // wait for card not busy, at most 250ms if (cardBusy) { spiTransferByte(0xFF); do { r1 = spiTransferByte(0xFF); retries++; if (!r1) { delay_us(250); } else break; } while (!r1 && retries < 0xFFE); } if (retries == 0xFFE) { _mmcDisableCS(); rprintf("mmcWrite - card still busy, sector "); rprintfu32(sector); rprintfCRLF(); return -1; } // issue command r1 = mmcCommand(MMC_WRITE_BLOCK, sector<<9); #ifdef MMC_DEBUG //rprintf("MMC Write Block R1=0x%x\r\n", r1); #endif // check for valid response if(r1 != 0x00) { _mmcDisableCS(); // Andreas - was reversed rprintf("mmcWrite - invalid response %x\r\n",r1); return r1; } // send dummy spiTransferByte(0xFF); // send data start token spiTransferByte(MMC_STARTBLOCK_WRITE); // write data for(i=0; i<0x200; i++) { spiTransferByte(*buffer++); } // write 16-bit CRC (dummy values) spiTransferByte(0xFF); spiTransferByte(0xFF); // read data response token r1 = spiTransferByte(0xFF); if( (r1&MMC_DR_MASK) != MMC_DR_ACCEPT) { _mmcDisableCS(); return r1; } #ifdef MMC_DEBUG //rprintf("Data Response Token=0x%x\r\n", r1); #endif /* old busy code // wait until card not busy while(!spiTransferByte(0xFF)); */ // Provide card with 8 clock cycles to complete the operation spiTransferByte(0xFF); cardBusy = 1; // release chip select _mmcDisableCS(); // return success return 0; }