SD Card change detection w/ debouncing

This commit is contained in:
ikari 2011-02-08 00:57:16 +01:00
parent 0df364760a
commit 986e37ee06
2 changed files with 35 additions and 20 deletions

View File

@ -96,7 +96,7 @@
- send transfer cmds - send transfer cmds
*/ */
/* /*
static CMD payloads. (no CRC calc required) static CMD payloads. (no CRC calc required)
- CMD0: 0x40 0x00 0x00 0x00 0x00 0x95 - CMD0: 0x40 0x00 0x00 0x00 0x00 0x95
- CMD8: 0x48 0x00 0x00 0x01 0xaa 0x87 - CMD8: 0x48 0x00 0x00 0x01 0xaa 0x87
@ -117,6 +117,8 @@ enum cmd_state { CMD_RSP = 0, CMD_RSPDAT, CMD_DAT };
int during_blocktrans = TRANS_NONE; int during_blocktrans = TRANS_NONE;
uint32_t last_block = 0; uint32_t last_block = 0;
volatile int sd_changed;
/** /**
* getbits - read value from bit buffer * getbits - read value from bit buffer
* @buffer: pointer to the data buffer * @buffer: pointer to the data buffer
@ -202,7 +204,7 @@ static inline void wait_busy(void) {
wiggle_fast_neg(4); wiggle_fast_neg(4);
} }
/* /*
send_command_slow send_command_slow
send SD command and put response in rsp. send SD command and put response in rsp.
returns length of response or 0 if there was no response returns length of response or 0 if there was no response
@ -245,7 +247,7 @@ int send_command_slow(uint8_t* cmd, uint8_t* rsp){
wiggle_slow_pos(1); wiggle_slow_pos(1);
BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 0; BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 0;
if(rsplen) { if(rsplen) {
uint16_t timeout=1000; uint16_t timeout=1000;
while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) { while((BITBAND(SD_CMDREG->FIOPIN, SD_CMDPIN)) && --timeout) {
@ -273,7 +275,7 @@ int send_command_slow(uint8_t* cmd, uint8_t* rsp){
} }
/* /*
send_command_fast send_command_fast
send SD command and put response in rsp. send SD command and put response in rsp.
returns length of response or 0 if there was no response returns length of response or 0 if there was no response
@ -298,6 +300,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
rsplen = 6; rsplen = 6;
waitbusy = 1; waitbusy = 1;
break; break;
case 13:
case 17: case 17:
case 18: case 18:
dat = 1; dat = 1;
@ -329,7 +332,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
wiggle_fast_pos1(); wiggle_fast_pos1();
BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 0; BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 0;
if(rsplen) { if(rsplen) {
uint32_t timeout=2000000; uint32_t timeout=2000000;
/* wait for response */ /* wait for response */
@ -422,12 +425,12 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
return rsplen; return rsplen;
} }
} }
if(state==CMD_DAT) { /* transfer rest of data */ if(state==CMD_DAT) { /* transfer rest of data */
DBG_SD printf("remaining data: %d\n", j); DBG_SD printf("remaining data: %d\n", j);
if(datshift==8) { if(datshift==8) {
while(1) { while(1) {
datdata |= SD_DAT << 4; datdata |= SD_DAT << 4;
wiggle_fast_neg1(); wiggle_fast_neg1();
datdata |= SD_DAT; datdata |= SD_DAT;
@ -556,7 +559,7 @@ void stream_datablock(uint8_t *buf) {
j--; j--;
if(!j) break; if(!j) break;
} }
/* eat the crc for now */ /* eat the crc for now */
wiggle_fast_neg(17); wiggle_fast_neg(17);
} }
} }
@ -575,7 +578,7 @@ void send_datablock(uint8_t *buf) {
BITBAND(SD_DAT1REG->FIOCLR, SD_DAT1PIN) = 1; BITBAND(SD_DAT1REG->FIOCLR, SD_DAT1PIN) = 1;
BITBAND(SD_DAT2REG->FIOCLR, SD_DAT2PIN) = 1; BITBAND(SD_DAT2REG->FIOCLR, SD_DAT2PIN) = 1;
BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1; BITBAND(SD_DAT3REG->FIOCLR, SD_DAT3PIN) = 1;
wiggle_fast_pos1(); /* send start bit to card */ wiggle_fast_pos1(); /* send start bit to card */
crcshift=8; crcshift=8;
while(cnt--) { while(cnt--) {
@ -657,7 +660,7 @@ void send_datablock(uint8_t *buf) {
BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1; BITBAND(SD_DAT3REG->FIOSET, SD_DAT3PIN) = 1;
wiggle_fast_pos1(); wiggle_fast_pos1();
BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 0; BITBAND(SD_DAT0REG->FIODIR, SD_DAT0PIN) = 0;
BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 0; BITBAND(SD_DAT1REG->FIODIR, SD_DAT1PIN) = 0;
BITBAND(SD_DAT2REG->FIODIR, SD_DAT2PIN) = 0; BITBAND(SD_DAT2REG->FIODIR, SD_DAT2PIN) = 0;
@ -693,7 +696,7 @@ void read_block(uint32_t address, uint8_t *buf) {
if(during_blocktrans) { if(during_blocktrans) {
// uart_putc('_'); // uart_putc('_');
//printf("nonseq read (%lx -> %lx), restarting transmission\n", last_block, address); //printf("nonseq read (%lx -> %lx), restarting transmission\n", last_block, address);
/* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */ /* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp); cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
} }
last_block=address; last_block=address;
@ -770,7 +773,7 @@ DRESULT sdn_initialize(BYTE drv) {
} }
wiggle_slow_neg(1); wiggle_slow_neg(1);
} }
printf("sd_init start\n"); printf("sd_init start\n");
cmd_slow(GO_IDLE_STATE, 0, 0x95, NULL, rsp); cmd_slow(GO_IDLE_STATE, 0, 0x95, NULL, rsp);
if((rsplen=cmd_slow(SEND_IF_COND, 0x000001aa, 0x87, NULL, rsp))) { if((rsplen=cmd_slow(SEND_IF_COND, 0x000001aa, 0x87, NULL, rsp))) {
@ -825,8 +828,8 @@ DSTATUS disk_initialize(BYTE drv) __attribute__ ((weak, alias("sdn_initialize"))
void sdn_init(void) { void sdn_init(void) {
/* enable GPIO interrupt on SD detect pin, both edges */ /* enable GPIO interrupt on SD detect pin, both edges */
NVIC_EnableIRQ(EINT3_IRQn); /* NVIC_EnableIRQ(EINT3_IRQn);
SD_DT_INT_SETUP(); SD_DT_INT_SETUP(); */
/* disconnect SSP1 */ /* disconnect SSP1 */
LPC_PINCON->PINSEL0 &= ~(BV(13) | BV(15) | BV(17) | BV(19)); LPC_PINCON->PINSEL0 &= ~(BV(13) | BV(15) | BV(17) | BV(19));
/* prepare GPIOs */ /* prepare GPIOs */
@ -847,7 +850,7 @@ DSTATUS sdn_status(BYTE drv) {
return STA_PROTECT; return STA_PROTECT;
} else { } else {
return RES_OK; return RES_OK;
} }
} else { } else {
return STA_NOINIT|STA_NODISK; return STA_NOINIT|STA_NODISK;
} }
@ -903,17 +906,21 @@ DRESULT sdn_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count) {
buf+=512; buf+=512;
} }
writeled(0); writeled(0);
return RES_OK; return RES_OK;
} }
DRESULT disk_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count) __attribute__ ((weak, alias("sdn_write"))); DRESULT disk_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count) __attribute__ ((weak, alias("sdn_write")));
/* Detect changes of SD card 0 */ /* Detect changes of SD card 0 */
void sdn_changed() { void sdn_changed() {
if (SDCARD_DETECT) { if (sd_changed) {
disk_state = DISK_CHANGED; printf("ch ");
} else { if(SDCARD_DETECT) {
disk_state = DISK_REMOVED; disk_state = DISK_CHANGED;
} else {
disk_state = DISK_REMOVED;
}
sd_changed = 0;
} }
} }

View File

@ -6,6 +6,7 @@
#include "timer.h" #include "timer.h"
#include "clock.h" #include "clock.h"
#include "uart.h" #include "uart.h"
#include "sdnative.h"
/* bit definitions */ /* bit definitions */
#define RITINT 0 #define RITINT 0
@ -13,6 +14,7 @@
#define PCRIT 16 #define PCRIT 16
extern volatile int sd_changed;
volatile tick_t ticks; volatile tick_t ticks;
volatile int wokefromrit; volatile int wokefromrit;
@ -23,6 +25,12 @@ void __attribute__((weak,noinline)) SysTick_Hook(void) {
/* Systick interrupt handler */ /* Systick interrupt handler */
void SysTick_Handler(void) { void SysTick_Handler(void) {
ticks++; ticks++;
static uint16_t sdch_state = 0;
sdch_state = (sdch_state << 1) | SDCARD_DETECT | 0xe000;
if((sdch_state == 0xf000) || (sdch_state == 0xefff)) {
sd_changed = 1;
}
sdn_changed();
SysTick_Hook(); SysTick_Hook();
} }