SD Card change detection w/ debouncing
This commit is contained in:
parent
0df364760a
commit
986e37ee06
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user