git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2923 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2011-05-07 13:24:04 +00:00
parent f8c8c48fa9
commit 7109dcee27
4 changed files with 58 additions and 21 deletions

View File

@ -46,6 +46,7 @@
#define SDC_CMD_STOP_TRANSMISSION 12 #define SDC_CMD_STOP_TRANSMISSION 12
#define SDC_CMD_SET_BLOCKLEN 16 #define SDC_CMD_SET_BLOCKLEN 16
#define SDC_CMD_READ_MULTIPLE_BLOCK 18 #define SDC_CMD_READ_MULTIPLE_BLOCK 18
#define SDC_CMD_SET_BLOCK_COUNT 23
#define SDC_CMD_WRITE_MULTIPLE_BLOCK 25 #define SDC_CMD_WRITE_MULTIPLE_BLOCK 25
#define SDC_CMD_APP_OP_COND 41 #define SDC_CMD_APP_OP_COND 41
#define SDC_CMD_APP_CMD 55 #define SDC_CMD_APP_CMD 55
@ -60,6 +61,8 @@
#define SDC_ACMD41_RETRY 100 #define SDC_ACMD41_RETRY 100
#define SDC_R1_ERROR_MASK 0xFDFFE008
/*===========================================================================*/ /*===========================================================================*/
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -205,7 +205,7 @@ void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
SDIO->CMD = (uint32_t)cmd | SDIO_CMD_CPSMEN; SDIO->CMD = (uint32_t)cmd | SDIO_CMD_CPSMEN;
while ((SDIO->STA & SDIO_STA_CMDSENT) == 0) while ((SDIO->STA & SDIO_STA_CMDSENT) == 0)
; ;
SDIO->ICR = 0xFFFFFFFF; SDIO->ICR = SDIO_ICR_CMDSENTC;
} }
/** /**
@ -233,7 +233,7 @@ bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
SDIO_STA_CCRCFAIL)) == 0) SDIO_STA_CCRCFAIL)) == 0)
; ;
SDIO->ICR = 0xFFFFFFFF; SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
if ((sta & (SDIO_STA_CTIMEOUT)) != 0) if ((sta & (SDIO_STA_CTIMEOUT)) != 0)
return TRUE; return TRUE;
*resp = SDIO->RESP1; *resp = SDIO->RESP1;
@ -264,7 +264,7 @@ bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
SDIO_STA_CCRCFAIL)) == 0) SDIO_STA_CCRCFAIL)) == 0)
; ;
SDIO->ICR = 0xFFFFFFFF; SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0) if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0)
return TRUE; return TRUE;
*resp = SDIO->RESP1; *resp = SDIO->RESP1;
@ -297,7 +297,7 @@ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
SDIO_STA_CCRCFAIL)) == 0) SDIO_STA_CCRCFAIL)) == 0)
; ;
SDIO->ICR = 0xFFFFFFFF; SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0) if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0)
return TRUE; return TRUE;
*resp = SDIO->RESP1; *resp = SDIO->RESP1;
@ -305,9 +305,10 @@ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
} }
/** /**
* @brief Data read through the SDIO bus. * @brief Reads one or more blocks.
* *
* @param[in] sdcp pointer to the @p SDCDriver object * @param[in] sdcp pointer to the @p SDCDriver object
* @param[in] startblk first block to read
* @param[out] buf pointer to the read buffer * @param[out] buf pointer to the read buffer
* @param[in] n number of blocks to read * @param[in] n number of blocks to read
* @return The operation status. * @return The operation status.
@ -317,24 +318,40 @@ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
* *
* @notapi * @notapi
*/ */
bool_t sdc_lld_read_blocks(SDCDriver *sdcp, uint8_t *buf, uint32_t n) { bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
uint8_t *buf, uint32_t n) {
msg_t msg; msg_t msg;
uint32_t resp[1];
chSysLock(); /* Clearing status.*/
/* Prepares the DMA channel.*/ SDIO->ICR = 0xFFFFFFFF;
/* Prepares the DMA channel for reading.*/
dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
(n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf, (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf,
(STM32_SDC_SDIO_DMA_PRIORITY << 12) | (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 | DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
DMA_CCR1_MINC); DMA_CCR1_MINC);
/* Setting up data transfer.
Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/
SDIO->DTIMER = STM32_SDC_DATATIMEOUT;
SDIO->DLEN = n; SDIO->DLEN = n;
/* Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/
SDIO->DCTRL = SDIO_DCTRL_RWMOD | SDIO->DCTRL = SDIO_DCTRL_RWMOD |
SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_3 |
SDIO_DCTRL_DMAEN | SDIO_DCTRL_DMAEN |
SDIO_DCTRL_DTEN; SDIO_DCTRL_DTEN;
/* DMA channel activation.*/ /* DMA channel activation.*/
dmaEnableChannel(&STM32_DMA2, STM32_DMA_CHANNEL_4); dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK, n, resp) ||
(resp[0] & SDC_R1_ERROR_MASK)) {
dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
SDIO->DCTRL = 0;
return TRUE;
}
chDbgAssert(sdcp->thread == NULL, "sdc_lld_read_blocks(), #1", "not NULL"); chDbgAssert(sdcp->thread == NULL, "sdc_lld_read_blocks(), #1", "not NULL");
sdcp->thread = chThdSelf(); sdcp->thread = chThdSelf();
chSchGoSleepS(THD_STATE_SUSPENDED); chSchGoSleepS(THD_STATE_SUSPENDED);
@ -345,9 +362,10 @@ bool_t sdc_lld_read_blocks(SDCDriver *sdcp, uint8_t *buf, uint32_t n) {
} }
/** /**
* @brief Data write through the SDIO bus. * @brief Writes one or more blocks.
* *
* @param[in] sdcp pointer to the @p SDCDriver object * @param[in] sdcp pointer to the @p SDCDriver object
* @param[in] startblk first block to write
* @param[out] buf pointer to the write buffer * @param[out] buf pointer to the write buffer
* @param[in] n number of blocks to write * @param[in] n number of blocks to write
* @return The operation status. * @return The operation status.
@ -357,7 +375,8 @@ bool_t sdc_lld_read_blocks(SDCDriver *sdcp, uint8_t *buf, uint32_t n) {
* *
* @notapi * @notapi
*/ */
bool_t sdc_lld_write_blocks(SDCDriver *sdcp, const uint8_t *buf, uint32_t n) { bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
const uint8_t *buf, uint32_t n) {
return TRUE; return TRUE;
} }

View File

@ -184,8 +184,10 @@ extern "C" {
uint32_t *resp); uint32_t *resp);
bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
uint32_t *resp); uint32_t *resp);
bool_t sdc_lld_read_blocks(SDCDriver *sdcp, uint8_t *buffer, uint32_t n); bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
bool_t sdc_lld_write_blocks(SDCDriver *sdcp, const uint8_t *buf, uint32_t n); uint8_t *buf, uint32_t n);
bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
const uint8_t *buf, uint32_t n);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -211,11 +211,11 @@ bool_t sdcConnect(SDCDriver *sdcp) {
goto failed; goto failed;
/* Switches to wide bus mode.*/ /* Switches to wide bus mode.*/
switch (sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) { /* switch (sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) {
case SDC_MODE_CARDTYPE_SDV11: case SDC_MODE_CARDTYPE_SDV11:
case SDC_MODE_CARDTYPE_SDV20: case SDC_MODE_CARDTYPE_SDV20:
SDIO->CLKCR |= SDIO_CLKCR_WIDBUS_0; SDIO->CLKCR |= SDIO_CLKCR_WIDBUS_0;
} }*/
sdcp->state = SDC_ACTIVE; sdcp->state = SDC_ACTIVE;
return FALSE; return FALSE;
@ -268,20 +268,33 @@ bool_t sdcDisconnect(SDCDriver *sdcp) {
bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk, bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk,
uint8_t *buf, uint32_t n) { uint8_t *buf, uint32_t n) {
bool_t sts; bool_t sts;
uint32_t resp[1]; uint32_t resp[4];
chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcRead"); chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcRead");
chSysLock();
chDbgAssert(sdcp->state == SDC_ACTIVE,
"sdcDisconnect(), #1", "invalid state");
sdcp->state = SDC_READING;
chSysUnlock();
if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
startblk *= SDC_BLOCK_SIZE; startblk *= SDC_BLOCK_SIZE;
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK, /* if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
startblk, resp)) (resp[0] & SDC_R1_ERROR_MASK))
return TRUE;
if (sdc_lld_send_cmd_long_crc(sdcp, 51, 0, resp))
return TRUE; return TRUE;
sts = sdc_lld_read_blocks(sdcp, buf, n); if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BLOCK_COUNT, n, resp) ||
(resp[0] & SDC_R1_ERROR_MASK))
return TRUE;*/
sts = sdc_lld_read(sdcp, startblk, buf, n);
sts = sts || sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, sts = sts || sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION,
0, resp); 0, resp);
sdcp->state = SDC_ACTIVE;
return sts; return sts;
} }
@ -315,7 +328,7 @@ bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
startblk, resp)) startblk, resp))
return TRUE; return TRUE;
sts = sdc_lld_write_blocks(sdcp, buf, n); sts = sdc_lld_write(sdcp, startblk, buf, n);
sts = sts || sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, sts = sts || sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION,
0, resp); 0, resp);
return sts; return sts;