From 114dfd624a977449de9be7b32cf79004d2613f79 Mon Sep 17 00:00:00 2001 From: Erik Strand <erik.strand@cba.mit.edu> Date: Sun, 12 May 2019 16:08:47 -0400 Subject: [PATCH] Read an SD card, if somewhat unreliably Bit banging is not the way to go. --- sd_tests/neil/read_sd.c | 123 +++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 47 deletions(-) diff --git a/sd_tests/neil/read_sd.c b/sd_tests/neil/read_sd.c index 65e67f6..936a263 100644 --- a/sd_tests/neil/read_sd.c +++ b/sd_tests/neil/read_sd.c @@ -221,7 +221,7 @@ unsigned char SPI_write(uint8_t chr) { // SD_command // write an SD command and return the response // -void SD_command(uint8_t command,uint32_t argument,uint8_t CRC,uint8_t *result) { +void SD_command(uint8_t command, uint32_t argument, uint8_t CRC, uint8_t *result) { clear(CS_port,CS_pin); SPI_write(command); SPI_write((argument >> 24) & 0xFF); @@ -300,49 +300,22 @@ void SD_read(uint32_t sector,uint16_t offset,uint8_t *buffer,uint16_t size) { set(CS_port,CS_pin); } -// -// main -// -int main(void) { - // - // main - // +void sd_loop() { + static uint8_t count, sectors_per_cluster, FATs, attribute, result[8], buffer[50]; + static uint16_t bytes_per_sector, reserved_sectors, offset, file_cluster_low, file_cluster_hi, + buffer_length, sector_count; + static uint32_t partition, FAT_sectors, fat_sector, root_cluster, root_sector, file_length, + file_cluster, file_sector, chars_read; - // Debug loop to verify we can detect when the card is inserted - // Configure DETECT_pin as an input and led_pin as an output - DETECT_direction &= ~DETECT_pin; - led_direction |= led_pin; - while (1) { - if (PINA & DETECT_pin) { - led_port &= ~led_pin; - } else { - led_port |= led_pin; - } + // Wait for card to be inserted + while (PINA & DETECT_pin) { + led_port |= led_pin; + _delay_ms(200); + led_port &= ~led_pin; + _delay_ms(200); } + led_port |= led_pin; - static uint8_t count,sectors_per_cluster,FATs,attribute,result[8],buffer[50]; - static uint16_t bytes_per_sector,reserved_sectors,offset, - file_cluster_low,file_cluster_hi,buffer_length,sector_count; - static uint32_t partition,FAT_sectors,fat_sector,root_cluster, - root_sector,file_length,file_cluster,file_sector,chars_read; - // - // set clock divider to /1 - // - CLKPR = (1 << CLKPCE); - CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); - // - // initialize output pins - // - set(serial_port,serial_pin_out); - output(serial_direction,serial_pin_out); - set(CS_port,CS_pin); - output(CS_direction,CS_pin); - clear(MOSI_port,MOSI_pin); - output(MOSI_direction,MOSI_pin); - set(SCK_port,SCK_pin); - output(SCK_direction,SCK_pin); - set(MISO_port,MISO_pin); //turn on pull-up - input(MISO_direction,MISO_pin); // // put card in SPI mode // @@ -354,20 +327,23 @@ int main(void) { clear(SCK_port,SCK_pin); SPI_delay(); } + // // CMD0: reset and enter idle state // should return 0x01 // put_flash_string(PSTR("\r\nreset: 0x")); - SD_command(0x40,0,0x95,result); + SD_command(0x40, 0, 0x95, result); put_hex_string(result,8); + // // CMD8: send interface condition, set SDHC // should return 0x01000001AA // put_flash_string(PSTR("\r\nset interface: 0x")); - SD_command(0x48,0x000001AA,0x87,result); + SD_command(0x48, 0x000001AA, 0x87, result); put_hex_string(result,8); + // // initialization loop // @@ -378,21 +354,31 @@ int main(void) { // should return 0x01 // put_flash_string(PSTR("\r\n application command: ")); - SD_command(0x77,0,0,result); - put_hex_string(result,8); + SD_command(0x77, 0, 0, result); + put_hex_string(result, 8); + // // ACMD41: initialize the card // should return 0x00 when ready // put_flash_string(PSTR("\r\n initialize card: 0x")); - SD_command(0x69,0x40000000,0,result); + SD_command(0x69, 0x40000000, 0, result); put_hex_string(result,8); + // // check if done // - if (result[1] == 0) + if (result[1] == 0) { + put_string("\ncard initialized"); break; } + + if (PINA & DETECT_pin) { + put_string("\ncard removed"); + return; + } + } + // // read the first partition table // @@ -403,6 +389,7 @@ int main(void) { put_flash_string(PSTR("\r\n first sector: 0x")); put_hex_string(buffer+8,4); memcpy(&partition,buffer+8,4); + // // read the first partition block // @@ -442,6 +429,7 @@ int main(void) { put_hex_char((root_cluster >> 16) & 0xFF); put_hex_char((root_cluster >> 8) & 0xFF); put_hex_char(root_cluster & 0xFF); + // // read the root directory // @@ -498,6 +486,7 @@ int main(void) { } offset += 32; } + // // read the file // @@ -520,6 +509,7 @@ int main(void) { put_char_string(buffer,buffer_length); chars_read += buffer_length; offset += buffer_length; + // // check sector length // @@ -549,9 +539,48 @@ int main(void) { offset = 0; } } + // // sector length not reached, continue // } put_flash_string(PSTR("\r\n\r\nend of file\r\n")); + led_port &= ~led_pin; +} + +// +// main +// +int main(void) { + // + // main + // + + // + // set clock divider to /1 + // + CLKPR = (1 << CLKPCE); + CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); + + // Configure DETECT_pin as an input and led_pin as an output + DETECT_direction &= ~DETECT_pin; + led_direction |= led_pin; + + // + // initialize output pins + // + set(serial_port,serial_pin_out); + output(serial_direction,serial_pin_out); + set(CS_port,CS_pin); + output(CS_direction,CS_pin); + clear(MOSI_port,MOSI_pin); + output(MOSI_direction,MOSI_pin); + set(SCK_port,SCK_pin); + output(SCK_direction,SCK_pin); + set(MISO_port,MISO_pin); //turn on pull-up + input(MISO_direction,MISO_pin); + + while (1) { + sd_loop(); + } } -- GitLab