summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-11-16 17:22:44 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2010-11-16 17:22:44 (GMT)
commit064c017eebe19e073efb6e8d8f7eae1d664b54e0 (patch)
treec8eba9906b97434746cc37b2f8a709a6afbe2518
parentff4d3cd9b0bb38ccb86ae1cf1a8903aa3abe64b2 (diff)
downloadabc8000-old-064c017eebe19e073efb6e8d8f7eae1d664b54e0.zip
abc8000-old-064c017eebe19e073efb6e8d8f7eae1d664b54e0.tar.gz
abc8000-old-064c017eebe19e073efb6e8d8f7eae1d664b54e0.tar.bz2
abc8000-old-064c017eebe19e073efb6e8d8f7eae1d664b54e0.tar.xz
Flash an LED on SD card disk access
-rw-r--r--data/sysrom/sdcard.c55
-rw-r--r--data/sysrom/sysrom.h1
-rw-r--r--data/sysrom/sysstart.c2
3 files changed, 55 insertions, 3 deletions
diff --git a/data/sysrom/sdcard.c b/data/sysrom/sdcard.c
index b2d6d5d..a962a4e 100644
--- a/data/sysrom/sdcard.c
+++ b/data/sysrom/sdcard.c
@@ -92,6 +92,37 @@ struct sdcard_info sdc = {
.status = STA_NOINIT
};
+/* < 0 if it should be left on, 0 for off, > 0 for off after timeout */
+static volatile int8_t sdcard_led;
+
+/*
+ * Called by the timer interrupt
+ */
+void sdcard_timer_tick(void)
+{
+ if (sdcard_led > 0) {
+ if (--sdcard_led == 0)
+ *IO_SYS_LED &= ~0x01;
+ }
+}
+
+/*
+ * Enable LED
+ */
+static void sdcard_led_on(void)
+{
+ sdcard_led = -1;
+ *IO_SYS_LED |= 0x01;
+}
+
+/*
+ * Disable LED after timeout
+ */
+static void sdcard_led_off(void)
+{
+ sdcard_led = 4; /* 4 ticks @ 64 Hz = 62.5 ms */
+}
+
static int sdcard_send_cmd(uint8_t opcode, uint32_t argument)
{
int8_t crc7, status;
@@ -249,6 +280,8 @@ int sdcard_read_sectors(void *buf, uint32_t lba, int count)
if (!count)
return 0;
+ sdcard_led_on();
+
printf("sdcard: reading %d sectors at %u to %p\n", count, lba, buf);
if (sdc.card_type == 1)
@@ -257,14 +290,14 @@ int sdcard_read_sectors(void *buf, uint32_t lba, int count)
rv = sdcard_send_cmd(CMD_READ_MULTIPLE_BLOCK, lba);
if (rv) {
printf("sdcard: read_multiple error %02x\n", rv);
- return 0;
+ goto out;
}
while (count--) {
rv = sdcard_read_block(p, SECTOR_SIZE, 200000,
count ? NULL : stop_transmission);
if (rv)
- return okcount;
+ goto out;
okcount++;
p += SECTOR_SIZE;
@@ -283,6 +316,8 @@ int sdcard_read_sectors(void *buf, uint32_t lba, int count)
resp);
}
+out:
+ sdcard_led_off();
return okcount;
}
@@ -326,6 +361,8 @@ int sdcard_write_sectors(const void *buf, uint32_t lba, int count)
if (!count)
return 0;
+ sdcard_led_on();
+
printf("sdcard: writing %d sectors at %u from %p\n", count, lba, buf);
if (sdc.card_type == 1)
@@ -334,7 +371,7 @@ int sdcard_write_sectors(const void *buf, uint32_t lba, int count)
rv = sdcard_send_cmd(CMD_WRITE_MULTIPLE_BLOCK, lba);
if (rv) {
printf("sdcard: write_multiple error %02x\n", rv);
- return 0;
+ goto out;
}
while (count--) {
@@ -410,6 +447,8 @@ int sdcard_write_sectors(const void *buf, uint32_t lba, int count)
resp = readb(IO_SDC_RD_B(SDC_BYTE|SDC_START));
} while (resp == 0x00);
+out:
+ sdcard_led_off();
return okcount;
}
@@ -519,6 +558,8 @@ DSTATUS disk_initialize(BYTE drive)
return sdc.status = STA_NOINIT|STA_NODISK;
}
+ sdcard_led_on();
+
/* Generate 256 clock cycles in slow mode, with CS# high */
writew(0x03, IO_SDC_WR_CTL(0)); /* Slow mode, CS# high */
for (i = 0; i < 16; i++)
@@ -529,6 +570,7 @@ DSTATUS disk_initialize(BYTE drive)
rv = sdcard_send_cmd(CMD_GO_IDLE_STATE, 0);
if (rv != 0x01) {
printf("sdcard: CMD0 error %02x\n", rv);
+ sdcard_led_off();
return sdc.status = STA_NOINIT;
}
@@ -548,6 +590,7 @@ DSTATUS disk_initialize(BYTE drive)
/* CMD8 supported */
if (rv & ~0x03) {
printf("sdcard; CMD8 error %02x\n", rv);
+ sdcard_led_off();
return sdc.status = STA_NOINIT;
}
@@ -561,6 +604,7 @@ DSTATUS disk_initialize(BYTE drive)
if ((sdc.if_cond & 0x1ff) != 0x1aa) {
printf("sdcard: CMD8 reports unusable card (0x%x)\n",
sdc.if_cond);
+ sdcard_led_off();
return sdc.status = STA_NOINIT;
}
try_sdhc = 1 << 30;
@@ -576,6 +620,7 @@ DSTATUS disk_initialize(BYTE drive)
if (rv & ~0x01) {
printf("sdcard: ACMD41 error %02x\n", rv);
+ sdcard_led_off();
return sdc.status = STA_NOINIT;
}
} while (rv);
@@ -585,6 +630,7 @@ DSTATUS disk_initialize(BYTE drive)
rv = sdcard_send_cmd(CMD_READ_OCR, try_sdhc);
if (rv) {
printf("sdcard: CMD58 error %02x\n", rv);
+ sdcard_led_off();
return sdc.status = STA_NOINIT;
}
/* Shift in the second data byte */
@@ -596,6 +642,7 @@ DSTATUS disk_initialize(BYTE drive)
rv = sdcard_send_cmd(CMD_SEND_OP_COND, 0);
if (rv & ~0x01) {
printf("sdcard: CMD1 error %02x\n", rv);
+ sdcard_led_off();
return sdc.status = STA_NOINIT;
}
} while (rv);
@@ -608,6 +655,7 @@ DSTATUS disk_initialize(BYTE drive)
rv = sdcard_send_cmd(CMD_SET_BLOCKLEN, 512);
if (rv) {
printf("sdcard: CMD16 error %02x\n", rv);
+ sdcard_led_off();
return sdc.status = STA_NOINIT;
}
@@ -640,6 +688,7 @@ DSTATUS disk_initialize(BYTE drive)
if (!(status & 0x08))
sdc.status |= STA_PROTECT;
+ sdcard_led_off();
return sdc.status;
}
diff --git a/data/sysrom/sysrom.h b/data/sysrom/sysrom.h
index ac90f31..8fe9e45 100644
--- a/data/sysrom/sysrom.h
+++ b/data/sysrom/sysrom.h
@@ -15,6 +15,7 @@ void monitor(void);
__noreturn die(void);
void __spurious_irq(void);
+void sdcard_timer_tick(void);
int sdcard_read_sectors(void *buf, uint32_t lba, int count);
int sdcard_write_sectors(const void *buf, uint32_t lba, int count);
diff --git a/data/sysrom/sysstart.c b/data/sysrom/sysstart.c
index 0443fbe..bf190df 100644
--- a/data/sysrom/sysstart.c
+++ b/data/sysrom/sysstart.c
@@ -118,6 +118,8 @@ static void __attribute__((interrupt)) timer_irq(void)
writel(led.val, IO_SYS_7SEG);
}
+
+ sdcard_timer_tick();
}
void __attribute__((interrupt)) __spurious_irq(void)