bug fix with sdspi select.
code style fixes.
This commit is contained in:
parent
e9d279620f
commit
28619eabc0
|
@ -47,9 +47,9 @@ Berlin, 2007
|
||||||
* @brief MMC-/SD-Card library
|
* @brief MMC-/SD-Card library
|
||||||
*
|
*
|
||||||
* @author Michael Baar <baar@inf.fu-berlin.de>
|
* @author Michael Baar <baar@inf.fu-berlin.de>
|
||||||
* @version $Revision: 1.8 $
|
* @version $Revision: 1.9 $
|
||||||
*
|
*
|
||||||
* $Id: sd.c,v 1.8 2009/05/26 12:15:46 nvt-se Exp $
|
* $Id: sd.c,v 1.9 2009/05/26 13:00:07 nvt-se Exp $
|
||||||
*
|
*
|
||||||
* Initialisation and basic functions for read and write access
|
* Initialisation and basic functions for read and write access
|
||||||
*/
|
*/
|
||||||
|
@ -71,10 +71,10 @@ volatile sd_state_t sd_state;
|
||||||
void
|
void
|
||||||
sd_init(void)
|
sd_init(void)
|
||||||
{
|
{
|
||||||
// depending on the system global variables may not get initialised on startup
|
/* depending on the system global variables may not get initialised on startup */
|
||||||
memset((void *)&sd_state, 0, sizeof (sd_state));
|
memset((void *)&sd_state, 0, sizeof (sd_state));
|
||||||
|
|
||||||
// initialize io ports
|
/* initialize io ports */
|
||||||
sd_init_platform();
|
sd_init_platform();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,24 +96,24 @@ sd_init_card(sd_cache_t * pCache)
|
||||||
return SD_INIT_SUCCESS;
|
return SD_INIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for UART and switch to SPI mode
|
/* Wait for UART and switch to SPI mode */
|
||||||
if(!uart_lock_wait(UART_MODE_SPI)) {
|
if(!uart_lock_wait(UART_MODE_SPI)) {
|
||||||
return SD_INIT_FAILED;
|
return SD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset card
|
/* reset card */
|
||||||
resetcnt = _sd_reset(&r3);
|
resetcnt = _sd_reset(&r3);
|
||||||
|
|
||||||
if(resetcnt >= SD_RESET_RETRY_COUNT) {
|
if(resetcnt >= SD_RESET_RETRY_COUNT) {
|
||||||
ret = SD_INIT_FAILED;
|
ret = SD_INIT_FAILED;
|
||||||
goto sd_init_card_fail;
|
goto sd_init_card_fail;
|
||||||
}
|
}
|
||||||
// Test for hardware compatibility
|
/* Test for hardware compatibility */
|
||||||
if((r3.ocr & SD_V_MASK) != SD_V_MASK) {
|
if((r3.ocr & SD_V_MASK) != SD_V_MASK) {
|
||||||
ret = SD_INIT_NOTSUPP;
|
ret = SD_INIT_NOTSUPP;
|
||||||
goto sd_init_card_fail;
|
goto sd_init_card_fail;
|
||||||
}
|
}
|
||||||
// Test for software compatibility
|
/* Test for software compatibility */
|
||||||
if(!_sd_read_register(&csd, SD_CMD_SEND_CSD, sizeof (struct sd_csd))) {
|
if(!_sd_read_register(&csd, SD_CMD_SEND_CSD, sizeof (struct sd_csd))) {
|
||||||
ret = SD_INIT_FAILED;
|
ret = SD_INIT_FAILED;
|
||||||
goto sd_init_card_fail;
|
goto sd_init_card_fail;
|
||||||
|
@ -138,7 +138,7 @@ sd_init_card_fail:
|
||||||
if(ret != SD_INIT_SUCCESS) {
|
if(ret != SD_INIT_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
// state
|
/* state */
|
||||||
sd_state.MinBlockLen_bit = 9;
|
sd_state.MinBlockLen_bit = 9;
|
||||||
sd_state.MaxBlockLen_bit = SD_CSD_READ_BL_LEN(csd);
|
sd_state.MaxBlockLen_bit = SD_CSD_READ_BL_LEN(csd);
|
||||||
sd_state.Flags = SD_INITIALIZED;
|
sd_state.Flags = SD_INITIALIZED;
|
||||||
|
@ -186,7 +186,7 @@ sd_close(void)
|
||||||
{
|
{
|
||||||
sd_flush();
|
sd_flush();
|
||||||
|
|
||||||
// reset state
|
/* reset state */
|
||||||
memset((void *)&sd_state, 0, sizeof (sd_state));
|
memset((void *)&sd_state, 0, sizeof (sd_state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,12 +197,12 @@ sd_set_blocklength(const uint8_t blocklength_bit)
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
uint8_t arg[4];
|
uint8_t arg[4];
|
||||||
|
|
||||||
// test if already set
|
/* test if already set */
|
||||||
if(blocklength_bit == sd_state.BlockLen_bit) {
|
if(blocklength_bit == sd_state.BlockLen_bit) {
|
||||||
return sd_state.BlockLen_bit;
|
return sd_state.BlockLen_bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for UART and switch to SPI mode
|
/* Wait for UART and switch to SPI mode */
|
||||||
if(!uart_lock_wait(UART_MODE_SPI)) {
|
if(!uart_lock_wait(UART_MODE_SPI)) {
|
||||||
return sd_state.BlockLen_bit;
|
return sd_state.BlockLen_bit;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ sd_set_blocklength(const uint8_t blocklength_bit)
|
||||||
((uint16_t *)arg)[1] = 0;
|
((uint16_t *)arg)[1] = 0;
|
||||||
((uint16_t *)arg)[0] = 1 << blocklength_bit;
|
((uint16_t *)arg)[0] = 1 << blocklength_bit;
|
||||||
|
|
||||||
// set blocklength command
|
/* set blocklength command */
|
||||||
if(_sd_send_cmd(SD_CMD_SET_BLOCKLENGTH, SD_RESPONSE_SIZE_R1, arg, NULL)) {
|
if(_sd_send_cmd(SD_CMD_SET_BLOCKLENGTH, SD_RESPONSE_SIZE_R1, arg, NULL)) {
|
||||||
sd_state.BlockLen_bit = blocklength_bit;
|
sd_state.BlockLen_bit = blocklength_bit;
|
||||||
sd_state.BlockLen = ((uint16_t *)arg)[0];
|
sd_state.BlockLen = ((uint16_t *)arg)[0];
|
||||||
|
@ -219,17 +219,17 @@ sd_set_blocklength(const uint8_t blocklength_bit)
|
||||||
ret = SD_BLOCKLENGTH_INVALID;
|
ret = SD_BLOCKLENGTH_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unlock uart
|
/* unlock uart */
|
||||||
uart_unlock(UART_MODE_SPI);
|
uart_unlock(UART_MODE_SPI);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//@}
|
/*@} */
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/*///////////////////////////////////////////////////////////////////////////// */
|
||||||
// Public functions, Reading
|
/* Public functions, Reading */
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/*///////////////////////////////////////////////////////////////////////////// */
|
||||||
uint16_t
|
uint16_t
|
||||||
sd_align_address(uint32_t * pAddress)
|
sd_align_address(uint32_t * pAddress)
|
||||||
{
|
{
|
||||||
|
@ -257,7 +257,7 @@ sd_read_block(void (*const pBuffer), const uint32_t address)
|
||||||
|
|
||||||
sdspi_read(pBuffer, sd_state.BlockLen, TRUE);
|
sdspi_read(pBuffer, sd_state.BlockLen, TRUE);
|
||||||
|
|
||||||
// receive CRC16 and finish
|
/* receive CRC16 and finish */
|
||||||
_sd_read_stop(2);
|
_sd_read_stop(2);
|
||||||
|
|
||||||
splx(s);
|
splx(s);
|
||||||
|
@ -274,19 +274,19 @@ sd_read_byte(void *pBuffer, const uint32_t address)
|
||||||
return sd_read_block(pBuffer, address);
|
return sd_read_block(pBuffer, address);
|
||||||
} else {
|
} else {
|
||||||
uint32_t blAdr = address;
|
uint32_t blAdr = address;
|
||||||
uint16_t offset; // bytes from aligned address to start of first byte to keep
|
uint16_t offset; /* bytes from aligned address to start of first byte to keep */
|
||||||
// align
|
/* align */
|
||||||
offset = sd_align_address(&blAdr);
|
offset = sd_align_address(&blAdr);
|
||||||
|
|
||||||
// start
|
/* start */
|
||||||
if(!_sd_read_start(SD_CMD_READ_SINGLE_BLOCK, address)) {
|
if(!_sd_read_start(SD_CMD_READ_SINGLE_BLOCK, address)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read
|
/* read */
|
||||||
sdspi_read(pBuffer, offset + 1, FALSE);
|
sdspi_read(pBuffer, offset + 1, FALSE);
|
||||||
|
|
||||||
// done
|
/* done */
|
||||||
_sd_read_stop(sd_state.BlockLen - offset - 1);
|
_sd_read_stop(sd_state.BlockLen - offset - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,84 +298,84 @@ sd_read_byte(void *pBuffer, const uint32_t address)
|
||||||
unsigned int
|
unsigned int
|
||||||
sd_read(void *pBuffer, unsigned long address, unsigned int size)
|
sd_read(void *pBuffer, unsigned long address, unsigned int size)
|
||||||
{
|
{
|
||||||
unsigned char *p; // pointer to current pos in receive buffer
|
unsigned char *p; /* pointer to current pos in receive buffer */
|
||||||
unsigned int offset; // bytes from aligned address to start of first byte to keep
|
unsigned int offset; /* bytes from aligned address to start of first byte to keep */
|
||||||
unsigned int read_count; // num bytes to read in one iteration
|
unsigned int read_count; /* num bytes to read in one iteration */
|
||||||
bool dump_flag; // number of bytes to dump in last iteration
|
bool dump_flag; /* number of bytes to dump in last iteration */
|
||||||
unsigned int num_bytes_read; // number of bytes read into receive buffer
|
unsigned int num_bytes_read; /* number of bytes read into receive buffer */
|
||||||
unsigned char ret;
|
unsigned char ret;
|
||||||
|
|
||||||
//
|
/* */
|
||||||
// parameter processing
|
/* parameter processing */
|
||||||
//
|
/* */
|
||||||
if(size == 0) {
|
if(size == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// align to block
|
/* align to block */
|
||||||
offset = sd_align_address(&address);
|
offset = sd_align_address(&address);
|
||||||
|
|
||||||
if((offset == 0) && (sd_state.BlockLen == size)) {
|
if((offset == 0) && (sd_state.BlockLen == size)) {
|
||||||
// best case: perfectly block aligned, no chunking
|
/* best case: perfectly block aligned, no chunking */
|
||||||
// -> do shortcut
|
/* -> do shortcut */
|
||||||
return sd_read_block(pBuffer, address);
|
return sd_read_block(pBuffer, address);
|
||||||
}
|
}
|
||||||
// calculate first block
|
/* calculate first block */
|
||||||
if(size > sd_state.BlockLen) {
|
if(size > sd_state.BlockLen) {
|
||||||
read_count = sd_state.BlockLen;
|
read_count = sd_state.BlockLen;
|
||||||
} else {
|
} else {
|
||||||
read_count = size;
|
read_count = size;
|
||||||
}
|
}
|
||||||
//
|
/* */
|
||||||
// Data transfer
|
/* Data transfer */
|
||||||
//
|
/* */
|
||||||
|
|
||||||
s = splhigh(s);
|
s = splhigh(s);
|
||||||
|
|
||||||
// request data transfer
|
/* request data transfer */
|
||||||
ret = _sd_read_start(SD_CMD_READ_SINGLE_BLOCK, address);
|
ret = _sd_read_start(SD_CMD_READ_SINGLE_BLOCK, address);
|
||||||
if(!ret) {
|
if(!ret) {
|
||||||
splx(s);
|
splx(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// run to offset
|
/* run to offset */
|
||||||
if(offset) {
|
if(offset) {
|
||||||
sdspi_read(pBuffer, offset, FALSE); // dump till offset
|
sdspi_read(pBuffer, offset, FALSE); /* dump till offset */
|
||||||
dump_flag = ((read_count + offset) < sd_state.BlockLen);
|
dump_flag = ((read_count + offset) < sd_state.BlockLen);
|
||||||
if(!dump_flag) {
|
if(!dump_flag) {
|
||||||
read_count = sd_state.BlockLen - offset; // max bytes to read from first block
|
read_count = sd_state.BlockLen - offset; /* max bytes to read from first block */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dump_flag = (read_count < sd_state.BlockLen);
|
dump_flag = (read_count < sd_state.BlockLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/* */
|
||||||
// block read loop
|
/* block read loop */
|
||||||
//
|
/* */
|
||||||
num_bytes_read = 0;
|
num_bytes_read = 0;
|
||||||
p = pBuffer;
|
p = pBuffer;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// whole block will be processed
|
/* whole block will be processed */
|
||||||
size -= read_count; // global counter
|
size -= read_count; /* global counter */
|
||||||
|
|
||||||
// read to receive buffer
|
/* read to receive buffer */
|
||||||
sdspi_read(p, read_count, TRUE);
|
sdspi_read(p, read_count, TRUE);
|
||||||
|
|
||||||
p += read_count; // increment buffer pointer
|
p += read_count; /* increment buffer pointer */
|
||||||
num_bytes_read += read_count;
|
num_bytes_read += read_count;
|
||||||
|
|
||||||
// finish block
|
/* finish block */
|
||||||
if(dump_flag) {
|
if(dump_flag) {
|
||||||
// cancel remaining bytes (last iteration)
|
/* cancel remaining bytes (last iteration) */
|
||||||
_sd_read_stop(sd_state.BlockLen - read_count - offset);
|
_sd_read_stop(sd_state.BlockLen - read_count - offset);
|
||||||
break;
|
break;
|
||||||
// unselect is included in send_cmd
|
/* unselect is included in send_cmd */
|
||||||
} else {
|
} else {
|
||||||
sdspi_idle(2); // receive CRC16
|
sdspi_idle(2); /* receive CRC16 */
|
||||||
if(size != 0) {
|
if(size != 0) {
|
||||||
// address calculation for next block
|
/* address calculation for next block */
|
||||||
offset = 0;
|
offset = 0;
|
||||||
address += sd_state.BlockLen;
|
address += sd_state.BlockLen;
|
||||||
if(size > sd_state.BlockLen) {
|
if(size > sd_state.BlockLen) {
|
||||||
|
@ -393,7 +393,7 @@ sd_read(void *pBuffer, unsigned long address, unsigned int size)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// finished
|
/* finished */
|
||||||
_sd_read_stop(0);
|
_sd_read_stop(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -405,11 +405,11 @@ sd_read(void *pBuffer, unsigned long address, unsigned int size)
|
||||||
return num_bytes_read;
|
return num_bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SD_READ_ANY
|
#endif /* SD_READ_ANY */
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/*///////////////////////////////////////////////////////////////////////////// */
|
||||||
// Public functions, Writing
|
/* Public functions, Writing */
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/*///////////////////////////////////////////////////////////////////////////// */
|
||||||
#if SD_WRITE
|
#if SD_WRITE
|
||||||
enum sd_write_ret
|
enum sd_write_ret
|
||||||
_sd_write_finish(void)
|
_sd_write_finish(void)
|
||||||
|
@ -427,10 +427,10 @@ _sd_write_finish(void)
|
||||||
|
|
||||||
s = splhigh();
|
s = splhigh();
|
||||||
|
|
||||||
// dummy crc
|
/* dummy crc */
|
||||||
sdspi_idle(2);
|
sdspi_idle(2);
|
||||||
|
|
||||||
// receive data response (ZZS___ 3 bits crc response)
|
/* receive data response (ZZS___ 3 bits crc response) */
|
||||||
for(i = 0; i < SD_TIMEOUT_NCR; i++) {
|
for(i = 0; i < SD_TIMEOUT_NCR; i++) {
|
||||||
ret = sdspi_rx();
|
ret = sdspi_rx();
|
||||||
if((ret > 0) && (ret < 0xFF)) {
|
if((ret > 0) && (ret < 0xFF)) {
|
||||||
|
@ -442,23 +442,23 @@ _sd_write_finish(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for data to be written
|
/* wait for data to be written */
|
||||||
_sd_wait_standby(NULL);
|
_sd_wait_standby(NULL);
|
||||||
splx(s);
|
splx(s);
|
||||||
sdspi_unselect();
|
sdspi_unselect();
|
||||||
|
|
||||||
if(ret) {
|
if(ret) {
|
||||||
// data transfer to sd card buffer was successful
|
/* data transfer to sd card buffer was successful */
|
||||||
// query for result of actual write operation
|
/* query for result of actual write operation */
|
||||||
ret = _sd_send_cmd(SD_CMD_SEND_STATUS, SD_RESPONSE_SIZE_R2, NULL, &r2);
|
ret = _sd_send_cmd(SD_CMD_SEND_STATUS, SD_RESPONSE_SIZE_R2, NULL, &r2);
|
||||||
if(ret && (r2 == 0)) {
|
if(ret && (r2 == 0)) {
|
||||||
result = SD_WRITE_SUCCESS;
|
result = SD_WRITE_SUCCESS;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// data transfer to sd card buffer failed
|
/* data transfer to sd card buffer failed */
|
||||||
}
|
}
|
||||||
|
|
||||||
// unlock uart (locked from every write operation)
|
/* unlock uart (locked from every write operation) */
|
||||||
uart_unlock(UART_MODE_SPI);
|
uart_unlock(UART_MODE_SPI);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -486,17 +486,18 @@ _sd_write_block(const uint32_t * pAddress, const void *pBuffer, int increment)
|
||||||
uint8_t r1, ret;
|
uint8_t r1, ret;
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
// block write-access on write protection
|
/* block write-access on write protection */
|
||||||
if(sd_protected()) {
|
if(sd_protected()) {
|
||||||
return SD_WRITE_PROTECTED_ERR;
|
return SD_WRITE_PROTECTED_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// acquire uart
|
/* acquire uart */
|
||||||
if(!uart_lock_wait(UART_MODE_SPI)) {
|
if(!uart_lock_wait(UART_MODE_SPI)) {
|
||||||
return SD_WRITE_INTERFACE_ERR;
|
return SD_WRITE_INTERFACE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start write
|
/* start write */
|
||||||
|
s = splhigh();
|
||||||
SD_LED_WRITE_ON;
|
SD_LED_WRITE_ON;
|
||||||
r1 = 0;
|
r1 = 0;
|
||||||
ret = _sd_send_cmd(SD_CMD_WRITE_SINGLE_BLOCK, SD_RESPONSE_SIZE_R1,
|
ret = _sd_send_cmd(SD_CMD_WRITE_SINGLE_BLOCK, SD_RESPONSE_SIZE_R1,
|
||||||
|
@ -504,12 +505,13 @@ _sd_write_block(const uint32_t * pAddress, const void *pBuffer, int increment)
|
||||||
if(!ret || r1) {
|
if(!ret || r1) {
|
||||||
leds_on(LEDS_ALL);
|
leds_on(LEDS_ALL);
|
||||||
_sd_reset(NULL);
|
_sd_reset(NULL);
|
||||||
|
splx(s);
|
||||||
uart_unlock(UART_MODE_SPI);
|
uart_unlock(UART_MODE_SPI);
|
||||||
SD_LED_WRITE_OFF;
|
SD_LED_WRITE_OFF;
|
||||||
return SD_WRITE_COMMAND_ERR;
|
return SD_WRITE_COMMAND_ERR;
|
||||||
}
|
}
|
||||||
// write data
|
|
||||||
s = splhigh();
|
/* write data */
|
||||||
sdspi_select();
|
sdspi_select();
|
||||||
sdspi_tx(0xFF);
|
sdspi_tx(0xFF);
|
||||||
sdspi_tx(SD_TOKEN_WRITE);
|
sdspi_tx(SD_TOKEN_WRITE);
|
||||||
|
@ -517,7 +519,7 @@ _sd_write_block(const uint32_t * pAddress, const void *pBuffer, int increment)
|
||||||
|
|
||||||
SD_LED_WRITE_OFF;
|
SD_LED_WRITE_OFF;
|
||||||
|
|
||||||
// finish write
|
/* finish write */
|
||||||
#if SPI_DMA_WRITE
|
#if SPI_DMA_WRITE
|
||||||
sdspi_dma_lock = TRUE;
|
sdspi_dma_lock = TRUE;
|
||||||
splx(s);
|
splx(s);
|
||||||
|
@ -535,19 +537,17 @@ sd_set_block(const uint32_t address, const char (*const pChar))
|
||||||
return _sd_write_block(&address, pChar, FALSE);
|
return _sd_write_block(&address, pChar, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum sd_write_ret
|
enum sd_write_ret
|
||||||
sd_write_block(const uint32_t address, void const (*const pBuffer))
|
sd_write_block(const uint32_t address, void const (*const pBuffer))
|
||||||
{
|
{
|
||||||
return _sd_write_block(&address, pBuffer, TRUE);
|
return _sd_write_block(&address, pBuffer, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/*///////////////////////////////////////////////////////////////////////////// */
|
||||||
// Supporting functions
|
/* Supporting functions */
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
/*///////////////////////////////////////////////////////////////////////////// */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -559,7 +559,7 @@ inline bool _sd_get_op_cond(struct sd_response_r1 * pResponse)
|
||||||
{
|
{
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
// SD style
|
/* SD style */
|
||||||
ret = _sd_send_cmd(SD_CMD_APP_SECIFIC_CMD, SD_RESPONSE_SIZE_R1, NULL,
|
ret = _sd_send_cmd(SD_CMD_APP_SECIFIC_CMD, SD_RESPONSE_SIZE_R1, NULL,
|
||||||
pResponse);
|
pResponse);
|
||||||
|
|
||||||
|
@ -568,7 +568,7 @@ inline bool _sd_get_op_cond(struct sd_response_r1 * pResponse)
|
||||||
ret = _sd_send_cmd(SD_ACMD_SEND_OP_COND, SD_RESPONSE_SIZE_R1, &arg,
|
ret = _sd_send_cmd(SD_ACMD_SEND_OP_COND, SD_RESPONSE_SIZE_R1, &arg,
|
||||||
pResponse);
|
pResponse);
|
||||||
} else {
|
} else {
|
||||||
// MMC style init
|
/* MMC style init */
|
||||||
ret = _sd_send_cmd(SD_CMD_SEND_OP_COND, SD_RESPONSE_SIZE_R1, NULL,
|
ret = _sd_send_cmd(SD_CMD_SEND_OP_COND, SD_RESPONSE_SIZE_R1, NULL,
|
||||||
pResponse);
|
pResponse);
|
||||||
if(*((uint8_t *)pResponse) & SD_R1_ERROR_MASK) {
|
if(*((uint8_t *)pResponse) & SD_R1_ERROR_MASK) {
|
||||||
|
@ -653,11 +653,12 @@ _sd_send_cmd(const uint8_t command,
|
||||||
int i; /* loop counter */
|
int i; /* loop counter */
|
||||||
int s; /* interrupt state */
|
int s; /* interrupt state */
|
||||||
|
|
||||||
|
sdspi_select();
|
||||||
|
|
||||||
#if SD_WRITE && SPI_DMA_WRITE
|
#if SD_WRITE && SPI_DMA_WRITE
|
||||||
sd_write_flush();
|
sd_write_flush();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sdspi_select();
|
|
||||||
cmd[0] |= command;
|
cmd[0] |= command;
|
||||||
if(pArg != NULL) {
|
if(pArg != NULL) {
|
||||||
cmd[1] = ((uint8_t *)pArg)[3];
|
cmd[1] = ((uint8_t *)pArg)[3];
|
||||||
|
@ -669,7 +670,7 @@ _sd_send_cmd(const uint8_t command,
|
||||||
s = splhigh();
|
s = splhigh();
|
||||||
sdspi_write(cmd, 6, 1);
|
sdspi_write(cmd, 6, 1);
|
||||||
|
|
||||||
// wait for start bit
|
/* wait for start bit */
|
||||||
i = SD_TIMEOUT_NCR;
|
i = SD_TIMEOUT_NCR;
|
||||||
do {
|
do {
|
||||||
data = sdspi_rx();
|
data = sdspi_rx();
|
||||||
|
@ -684,10 +685,10 @@ _sd_send_cmd(const uint8_t command,
|
||||||
|
|
||||||
_sd_send_cmd_response:
|
_sd_send_cmd_response:
|
||||||
s = splhigh();
|
s = splhigh();
|
||||||
// start bit received, read response with size i
|
/* start bit received, read response with size i */
|
||||||
i = response_size - 1;
|
i = response_size - 1;
|
||||||
if(pResponse != NULL) {
|
if(pResponse != NULL) {
|
||||||
// copy response to response buffer
|
/* copy response to response buffer */
|
||||||
do {
|
do {
|
||||||
((uint8_t *)pResponse)[i] = data;
|
((uint8_t *)pResponse)[i] = data;
|
||||||
if(i == 0) {
|
if(i == 0) {
|
||||||
|
@ -698,11 +699,11 @@ _sd_send_cmd_response:
|
||||||
i--;
|
i--;
|
||||||
} while(1);
|
} while(1);
|
||||||
} else {
|
} else {
|
||||||
// receive and ignore response
|
/* receive and ignore response */
|
||||||
sdspi_read(&data, i, 0);
|
sdspi_read(&data, i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// done successfully
|
/* done successfully */
|
||||||
sdspi_unselect();
|
sdspi_unselect();
|
||||||
|
|
||||||
splx(s);
|
splx(s);
|
||||||
|
@ -710,7 +711,7 @@ _sd_send_cmd_response:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
sd_send_cmd_fail:
|
sd_send_cmd_fail:
|
||||||
// failed
|
/* failed */
|
||||||
sdspi_unselect();
|
sdspi_unselect();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -744,7 +745,7 @@ _sd_read_start(uint8_t cmd, uint32_t address)
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
|
|
||||||
// aquire uart
|
/* acquire uart */
|
||||||
if(!uart_lock_wait(UART_MODE_SPI)) {
|
if(!uart_lock_wait(UART_MODE_SPI)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -754,26 +755,15 @@ _sd_read_start(uint8_t cmd, uint32_t address)
|
||||||
goto _sd_read_start_fail;
|
goto _sd_read_start_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for start bit (0)
|
/* Wait for start bit (0) */
|
||||||
sdspi_select();
|
sdspi_select();
|
||||||
|
|
||||||
i = sdspi_wait_token(0xFF, 0xFF, SD_TOKEN_READ, SD_TIMEOUT_READ);
|
i = sdspi_wait_token(0xFF, 0xFF, SD_TOKEN_READ, SD_TIMEOUT_READ);
|
||||||
|
|
||||||
if(i < SD_TIMEOUT_READ) {
|
if(i < SD_TIMEOUT_READ) {
|
||||||
// token received, data bytes follow
|
/* token received, data bytes follow */
|
||||||
SD_LED_READ_ON;
|
SD_LED_READ_ON;
|
||||||
|
|
||||||
/*
|
|
||||||
Following code handles error tokens. Since these are currently not used in the
|
|
||||||
application they can just be ignored. Anyway this is still useful when debugging.
|
|
||||||
else if( (data != 0) && (data & SD_DATA_ERROR_TOKEN_MASK) == data ) {
|
|
||||||
// data error token
|
|
||||||
sdspi_rx();
|
|
||||||
break;
|
|
||||||
} */
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else {
|
|
||||||
// error or timeout
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_sd_read_start_fail:
|
_sd_read_start_fail:
|
||||||
|
@ -789,7 +779,7 @@ _sd_read_start_fail:
|
||||||
void
|
void
|
||||||
_sd_read_stop(uint16_t count)
|
_sd_read_stop(uint16_t count)
|
||||||
{
|
{
|
||||||
// finish block + crc
|
/* finish block + crc */
|
||||||
if(count) {
|
if(count) {
|
||||||
uint8_t dump;
|
uint8_t dump;
|
||||||
|
|
||||||
|
@ -799,11 +789,11 @@ _sd_read_stop(uint16_t count)
|
||||||
|
|
||||||
SD_LED_READ_OFF;
|
SD_LED_READ_OFF;
|
||||||
|
|
||||||
// wait for switch to standby mode
|
/* wait for switch to standby mode */
|
||||||
if(!_sd_wait_standby(NULL)) {
|
if(!_sd_wait_standby(NULL)) {
|
||||||
_sd_reset(NULL);
|
_sd_reset(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unlock uart (locked from _sd_read_start)
|
/* unlock uart (locked from _sd_read_start) */
|
||||||
uart_unlock(UART_MODE_SPI);
|
uart_unlock(UART_MODE_SPI);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue