Cleaned up code formatting a bit and added ability to set the SD card clock speed.

This commit is contained in:
Jacob Pease 2024-07-31 10:59:41 -05:00
parent a263f836f2
commit c4ae17c679
2 changed files with 52 additions and 17 deletions

View file

@ -62,8 +62,14 @@ uint64_t sd_cmd(uint8_t cmd, uint32_t arg, uint8_t crc) {
// response length. Probably unecessary so let's wait and see what // response length. Probably unecessary so let's wait and see what
// happens. // happens.
// write_reg(SPI_RXMARK, response_len); // write_reg(SPI_RXMARK, response_len);
// Chip select must remain asserted during transaction
if (cmd != SD_CMD_STOP_TRANSMISSION) {
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_HOLD);
}
// Write all 6 bytes into transfer fifo // Write all 7 bytes into transfer fifo
// spi_sendbyte(0xff);
spi_sendbyte(0x40 | cmd); spi_sendbyte(0x40 | cmd);
spi_sendbyte(arg >> 24); spi_sendbyte(arg >> 24);
spi_sendbyte(arg >> 16); spi_sendbyte(arg >> 16);
@ -77,7 +83,7 @@ uint64_t sd_cmd(uint8_t cmd, uint32_t arg, uint8_t crc) {
waittx(); waittx();
// Read the dummy rxFIFO entries to move the head back to the tail // Read the dummy rxFIFO entries to move the head back to the tail
for (i = 0; i < 6; i++) { for (i = 0; i < 7; i++) {
spi_readbyte(); spi_readbyte();
} }
@ -90,12 +96,24 @@ uint64_t sd_cmd(uint8_t cmd, uint32_t arg, uint8_t crc) {
// Wait for transfer fifo again // Wait for transfer fifo again
waittx(); waittx();
// Wait for actual response from SD card
// All responses start with a 0. Output of SDCIn is high, unless
// a message is being transferred.
do {
rbyte = spi_txrx(0xff);
} while ( (rbyte & 0x80) != 0 );
r = r | (rbyte << ((response_len - 1)*8));
// Read rxfifo response // Read rxfifo response
for (i = 0; i < response_len; i++) { for (i = 1; i < response_len; i++) {
rbyte = spi_readbyte(); rbyte = spi_readbyte();
r = r | (rbyte << ((response_len - 1 - i)*8)); r = r | (rbyte << ((response_len - 1 - i)*8));
} }
if (cmd != 18) {
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_AUTO);
}
return r; return r;
} // sd_cmd } // sd_cmd
@ -128,33 +146,50 @@ uint64_t sd_read64(uint16_t * crc) {
// init_sd: ---------------------------------------------------------- // init_sd: ----------------------------------------------------------
// This first initializes the SPI peripheral then initializes the SD // This first initializes the SPI peripheral then initializes the SD
// card itself. We use the uart to display anything that goes wrong. // card itself. We use the uart to display anything that goes wrong.
void init_sd(){ int init_sd(uint32_t freq, uint32_t sdclk){
spi_init(); spi_init();
uint64_t r; uint64_t r;
uint32_t newClockDiv;
print_uart("Initializing SD Card in SPI mode.\r\n"); println("Initializing SD Card in SPI mode.");
// This is necessary. This is the card's pre-init state initialization.
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_OFF);
for (int i = 0; i < 10; i++) {
spi_txrx(0xff);
}
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_AUTO);
// CMD0 --------------------------------------------------------------
// Reset SD Card command // Reset SD Card command
// Initializes SD card into SPI mode if CS is asserted '0' // Initializes SD card into SPI mode if CS is asserted '0'
if (!(( r = CMD0() ) & 0x10) ) { // We expect to get the R1 response 0x01 which means that the
print_uart("SD ERROR: "); // card has been put into the idle state.
print_uart_byte(r & 0xff); print_uart("CMD0: ");
print_uart("\r\n"); do {
} r = CMD0();
} while ( r != 0x01 );
println_with_r1("Success, r = 0x", r & 0xff);
// CMD8 -------------------------------------------------------------
// //
if (!(( r = CMD8() ) & 0x10 )) { print_uart("CMD8: ");
print_uart("SD ERROR: "); r = CMD8();
print_uart_byte(r & 0xff); if ((r & 0x000000ff0000ffff) != 0x01000001aa) {
print_uart("\r\n"); println_with_r7("Failed, 0x", r);
} }
println_with_r7("Success, 0x", r);
// ACMD41 -----------------------------------------------------------
print_uart("ACMD41: ");
do { do {
CMD55(); CMD55();
r = ACMD41(); r = ACMD41();
} while (r == 0x1); } while (r == 0x1);
println_with_r1("Success, r = 0x", r & 0xff);
print_uart("SD card is initialized.\n\r"); println_with_dec("New clock frequency: ", (uint64_t)sdclk);
spi_set_clock(freq, sdclk);
println("SD card is initialized.");
} }

View file

@ -9,11 +9,11 @@
// Response lengths in bytes // Response lengths in bytes
#define R1_RESPONSE 1 #define R1_RESPONSE 1
#define R7_RESPONSE 7 #define R7_RESPONSE 5
#define R1B_RESPONSE 2 #define R1B_RESPONSE 2
uint8_t crc7(uint8_t prev, uint8_t in); uint8_t crc7(uint8_t prev, uint8_t in);
uint16_t crc16(uint16_t crc, uint8_t data); uint16_t crc16(uint16_t crc, uint8_t data);
uint64_t sd_cmd(uint8_t cmd, uint32_t arg, uint8_t crc); uint64_t sd_cmd(uint8_t cmd, uint32_t arg, uint8_t crc);
uint64_t sd_read64(uint16_t * crc); uint64_t sd_read64(uint16_t * crc);
void init_sd(); int init_sd(uint32_t freq, uint32_t sdclk);