open-story-teller/firmware/test/platform_validation.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);
}
}