mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
164 lines
4 KiB
C
164 lines
4 KiB
C
|
|
|
|
void sd_card_test(void);
|
|
|
|
int main()
|
|
{
|
|
sd_card_test();
|
|
}
|
|
|
|
|
|
uint8_t const CMD0 = 0X00;
|
|
/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/
|
|
uint8_t const CMD8 = 0X08;
|
|
/** SEND_CSD - read the Card Specific Data (CSD register) */
|
|
uint8_t const CMD9 = 0X09;
|
|
/** SEND_CID - read the card identification information (CID register) */
|
|
uint8_t const CMD10 = 0X0A;
|
|
/** SEND_STATUS - read the card status register */
|
|
uint8_t const CMD13 = 0X0D;
|
|
/** READ_BLOCK - read a single data block from the card */
|
|
uint8_t const CMD17 = 0X11;
|
|
/** WRITE_BLOCK - write a single data block to the card */
|
|
uint8_t const CMD24 = 0X18;
|
|
/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */
|
|
uint8_t const CMD25 = 0X19;
|
|
/** ERASE_WR_BLK_START - sets the address of the first block to be erased */
|
|
uint8_t const CMD32 = 0X20;
|
|
/** ERASE_WR_BLK_END - sets the address of the last block of the continuous
|
|
range to be erased*/
|
|
uint8_t const CMD33 = 0X21;
|
|
/** ERASE - erase all previously selected blocks */
|
|
uint8_t const CMD38 = 0X26;
|
|
/** APP_CMD - escape for application specific command */
|
|
uint8_t const CMD55 = 0X37;
|
|
/** READ_OCR - read the OCR register of a card */
|
|
uint8_t const CMD58 = 0X3A;
|
|
/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be
|
|
pre-erased before writing */
|
|
uint8_t const ACMD23 = 0X17;
|
|
/** SD_SEND_OP_COMD - Sends host capacity support information and
|
|
activates the card's initialization process */
|
|
uint8_t const ACMD41 = 0X29;
|
|
//------------------------------------------------------------------------------
|
|
/** status for card in the ready state */
|
|
uint8_t const R1_READY_STATE = 0X00;
|
|
/** status for card in the idle state */
|
|
uint8_t const R1_IDLE_STATE = 0X01;
|
|
/** status bit for illegal command */
|
|
uint8_t const R1_ILLEGAL_COMMAND = 0X04;
|
|
/** start data token for read or write single block*/
|
|
uint8_t const DATA_START_BLOCK = 0XFE;
|
|
/** stop token for write multiple blocks*/
|
|
uint8_t const STOP_TRAN_TOKEN = 0XFD;
|
|
/** start data token for write multiple blocks*/
|
|
uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC;
|
|
/** mask for data response tokens after a write block operation */
|
|
uint8_t const DATA_RES_MASK = 0X1F;
|
|
/** write data accepted token */
|
|
uint8_t const DATA_RES_ACCEPTED = 0X05;
|
|
|
|
uint8_t status_ = 0;
|
|
|
|
static void spiSend(uint8_t b) {
|
|
spi_transfer(b);
|
|
}
|
|
/** Receive a byte from the card */
|
|
static uint8_t spiRec(void) {
|
|
return spi_transfer(0xFF);
|
|
}
|
|
|
|
uint32_t millis()
|
|
{
|
|
return msTicks;
|
|
}
|
|
|
|
uint8_t waitNotBusy(unsigned int timeoutMillis) {
|
|
unsigned int t0 = millis();
|
|
unsigned int d;
|
|
do {
|
|
if (spiRec() == 0XFF) {
|
|
return true;
|
|
}
|
|
d = millis() - t0;
|
|
} while (d < timeoutMillis);
|
|
return false;
|
|
}
|
|
|
|
void chipSelectLow()
|
|
{
|
|
spi_ss(0);
|
|
}
|
|
|
|
uint8_t cardCommand(uint8_t cmd, uint32_t arg) {
|
|
|
|
// select card
|
|
chipSelectLow();
|
|
|
|
// wait up to 300 ms if busy
|
|
waitNotBusy(300);
|
|
|
|
// send command
|
|
spiSend(cmd | 0x40);
|
|
|
|
// send argument
|
|
for (int8_t s = 24; s >= 0; s -= 8) {
|
|
spiSend(arg >> s);
|
|
}
|
|
|
|
// send CRC
|
|
uint8_t crc = 0XFF;
|
|
if (cmd == CMD0) {
|
|
crc = 0X95; // correct crc for CMD0 with arg 0
|
|
}
|
|
if (cmd == CMD8) {
|
|
crc = 0X87; // correct crc for CMD8 with arg 0X1AA
|
|
}
|
|
spiSend(crc);
|
|
|
|
// wait for response
|
|
for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++)
|
|
;
|
|
return status_;
|
|
}
|
|
|
|
static void sd_card_test(void)
|
|
{
|
|
bool inserted = false;
|
|
|
|
debug_printf("--- SD Card Test ---\n");
|
|
|
|
inserted = !HAL_GPIO_CD_read();
|
|
|
|
debug_printf("SD Card is %s\n", inserted ? "inserted" : "not inserted");
|
|
|
|
if (inserted)
|
|
{
|
|
unsigned int t0 = millis();
|
|
|
|
for (uint8_t i = 0; i < 10; i++) {
|
|
spiSend(0XFF);
|
|
}
|
|
|
|
spi_ss(0);
|
|
bool error = false;
|
|
|
|
while ((status_ = cardCommand(CMD0, 0)) != 0x01) {
|
|
unsigned int d = millis() - t0;
|
|
if (d > 2000) {
|
|
error = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (error) {
|
|
debug_printf("Failure :(\n");
|
|
} else {
|
|
debug_printf("SUCCESS !\n");
|
|
}
|
|
|
|
spi_ss(1);
|
|
}
|
|
}
|
|
|