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
// happens.
// 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(arg >> 24);
spi_sendbyte(arg >> 16);
@ -77,7 +83,7 @@ uint64_t sd_cmd(uint8_t cmd, uint32_t arg, uint8_t crc) {
waittx();
// 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();
}
@ -90,12 +96,24 @@ uint64_t sd_cmd(uint8_t cmd, uint32_t arg, uint8_t crc) {
// Wait for transfer fifo again
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
for (i = 0; i < response_len; i++) {
for (i = 1; i < response_len; i++) {
rbyte = spi_readbyte();
r = r | (rbyte << ((response_len - 1 - i)*8));
}
if (cmd != 18) {
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_AUTO);
}
return r;
} // sd_cmd
@ -128,33 +146,50 @@ uint64_t sd_read64(uint16_t * crc) {
// init_sd: ----------------------------------------------------------
// This first initializes the SPI peripheral then initializes the SD
// 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();
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
// Initializes SD card into SPI mode if CS is asserted '0'
if (!(( r = CMD0() ) & 0x10) ) {
print_uart("SD ERROR: ");
print_uart_byte(r & 0xff);
print_uart("\r\n");
}
// We expect to get the R1 response 0x01 which means that the
// card has been put into the idle state.
print_uart("CMD0: ");
do {
r = CMD0();
} while ( r != 0x01 );
println_with_r1("Success, r = 0x", r & 0xff);
// CMD8 -------------------------------------------------------------
//
if (!(( r = CMD8() ) & 0x10 )) {
print_uart("SD ERROR: ");
print_uart_byte(r & 0xff);
print_uart("\r\n");
print_uart("CMD8: ");
r = CMD8();
if ((r & 0x000000ff0000ffff) != 0x01000001aa) {
println_with_r7("Failed, 0x", r);
}
println_with_r7("Success, 0x", r);
// ACMD41 -----------------------------------------------------------
print_uart("ACMD41: ");
do {
CMD55();
r = ACMD41();
} 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
#define R1_RESPONSE 1
#define R7_RESPONSE 7
#define R7_RESPONSE 5
#define R1B_RESPONSE 2
uint8_t crc7(uint8_t prev, uint8_t in);
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_read64(uint16_t * crc);
void init_sd();
int init_sd(uint32_t freq, uint32_t sdclk);