Commit 114dfd62 authored by Erik Strand's avatar Erik Strand

Read an SD card, if somewhat unreliably

Bit banging is not the way to go.
parent 563f471a
......@@ -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();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment