2663 lines
64 KiB
C
2663 lines
64 KiB
C
|
/*****************************************************************************
|
||
|
*
|
||
|
* Copyright Andes Technology Corporation 2007-2008
|
||
|
* All Rights Reserved.
|
||
|
*
|
||
|
* Revision History:
|
||
|
*
|
||
|
* Sep.26.2007 Created.
|
||
|
****************************************************************************/
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* FILE NAME VERSION
|
||
|
*
|
||
|
* sdd_sd.c
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* Secure digital card specification 2.0 definition.
|
||
|
*
|
||
|
* Currently only Secure Digital Memory standards are well-defined.
|
||
|
* Remaining spec mostly are left for future developers.
|
||
|
*
|
||
|
* DATA STRUCTURES
|
||
|
*
|
||
|
* None
|
||
|
*
|
||
|
* DEPENDENCIES
|
||
|
*
|
||
|
* None
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#include "sdd.h"
|
||
|
#include "sdd_sd.h"
|
||
|
|
||
|
/*
|
||
|
* If SDD_SMALL_FOOTPRINT is defined, SD command routines are defined as
|
||
|
* macros which will be redirect to a general command issuing routine.
|
||
|
*
|
||
|
* If performance is required, set SDD_SMALL_FOOTPRINT to 0. The SD command
|
||
|
* issuing routines are then a set of expanded code.
|
||
|
*/
|
||
|
#if (SDD_SMALL_FOOTPRINT)
|
||
|
#define SDC_INLINE static _inline
|
||
|
#else /* SDD_SMALL_FOOTPRINT */
|
||
|
#define SDC_INLINE static
|
||
|
#endif /* SDD_SMALL_FOOTPRINT */
|
||
|
|
||
|
/* Local Helper Routines */
|
||
|
SDC_INLINE uint32_t _sd_cmd(uint32_t cmd)
|
||
|
{
|
||
|
uint32_t retry_cnt = 0;
|
||
|
|
||
|
/* Make sure card exists */
|
||
|
if (GETB32(SDC_STATUS, SDC_SR_CARD_DETECT_BIT))
|
||
|
return SDD_CARD_REMOVED;
|
||
|
|
||
|
/* Clear SDC status bits */
|
||
|
OUT32(SDC_CLEAR, SDC_RSP_CRC_FAIL_MASK | SDC_RSP_TIMEOUT_MASK |
|
||
|
SDC_RSP_CRC_OK_MASK | SDC_CMD_SENT_MASK);
|
||
|
/*OUT32(SDC_CLEAR, SDC_CLEAR_ALL); */
|
||
|
|
||
|
/* Send command */
|
||
|
OUT32(SDC_CMD, cmd);
|
||
|
|
||
|
/* Wait until the command is on the way to the card ... */
|
||
|
while (retry_cnt++ < SD_CMD_MAX_RETRY_COUNT) {
|
||
|
|
||
|
/* Make sure card exists */
|
||
|
if (GETB32(SDC_STATUS, SDC_SR_CARD_DETECT_BIT))
|
||
|
return SDD_CARD_REMOVED;
|
||
|
|
||
|
/* Get new status of SDC */
|
||
|
if (GETB32(SDC_STATUS, SDC_SR_CMD_SENT_BIT) != 0)
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
|
||
|
return SDD_CMD_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
SDC_INLINE uint32_t _sd_cmd_arg(uint32_t cmd, uint32_t arg)
|
||
|
{
|
||
|
uint32_t retry_cnt = 0;
|
||
|
|
||
|
/* Make sure card exists */
|
||
|
if (GETB32(SDC_STATUS, SDC_SR_CARD_DETECT_BIT))
|
||
|
return SDD_CARD_REMOVED;
|
||
|
|
||
|
/* Clear SDC status bits */
|
||
|
OUT32(SDC_CLEAR, SDC_RSP_CRC_FAIL_MASK | SDC_RSP_TIMEOUT_MASK |
|
||
|
SDC_RSP_CRC_OK_MASK | SDC_CMD_SENT_MASK);
|
||
|
/*OUT32(SDC_CLEAR, SDC_CLEAR_ALL); */
|
||
|
|
||
|
/* Prepare Argument */
|
||
|
OUT32(SDC_CMD_ARG, arg);
|
||
|
|
||
|
/* Send command */
|
||
|
OUT32(SDC_CMD, cmd);
|
||
|
|
||
|
/* Wait until the command is on the way to the card ... */
|
||
|
while (retry_cnt++ < SD_CMD_MAX_RETRY_COUNT) {
|
||
|
|
||
|
/* Make sure card exists */
|
||
|
if (GETB32(SDC_STATUS, SDC_SR_CARD_DETECT_BIT))
|
||
|
return SDD_CARD_REMOVED;
|
||
|
|
||
|
/* Get new status of SDC */
|
||
|
if (GETB32(SDC_STATUS, SDC_SR_CMD_SENT_BIT) != 0)
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
|
||
|
return SDD_CMD_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
SDC_INLINE uint32_t _sd_cmd_r32(uint32_t cmd, SD_R32 * rsp)
|
||
|
{
|
||
|
uint32_t retry_cnt = 0;
|
||
|
uint32_t sdc_sr = 0;
|
||
|
|
||
|
/* Make sure card exists */
|
||
|
if (GETB32(SDC_STATUS, SDC_SR_CARD_DETECT_BIT))
|
||
|
return SDD_CARD_REMOVED;
|
||
|
|
||
|
/* Clear SDC status bits */
|
||
|
OUT32(SDC_CLEAR, SDC_RSP_CRC_FAIL_MASK | SDC_RSP_TIMEOUT_MASK |
|
||
|
SDC_RSP_CRC_OK_MASK | SDC_CMD_SENT_MASK);
|
||
|
/*OUT32(SDC_CLEAR, SDC_CLEAR_ALL); */
|
||
|
|
||
|
/* Send command */
|
||
|
OUT32(SDC_CMD, cmd);
|
||
|
|
||
|
/* Wait until the command is responsed ... */
|
||
|
while (retry_cnt++ < SD_CMD_MAX_RETRY_COUNT) {
|
||
|
|
||
|
sdc_sr = IN32(SDC_STATUS);
|
||
|
|
||
|
/* Make sure card exists */
|
||
|
if (sdc_sr & SDC_SR_CARD_DETECT_BIT)
|
||
|
return SDD_CARD_REMOVED;
|
||
|
|
||
|
/* Check error status */
|
||
|
if (sdc_sr & SDC_SR_RSP_CRC_OK_MASK) {
|
||
|
|
||
|
rsp->r[0] = IN32(SDC_R0);
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
else if (sdc_sr & SDC_SR_RSP_CRC_FAIL_MASK) {
|
||
|
|
||
|
return SDD_RSP_CRC_ERROR;
|
||
|
}
|
||
|
else if (sdc_sr & SDC_SR_RSP_TIMEOUT_MASK) {
|
||
|
|
||
|
return SDD_RSP_TIMEOUT;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_CMD_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
SDC_INLINE uint32_t _sd_cmd_arg_r32(uint32_t cmd, uint32_t arg, SD_R32 * rsp)
|
||
|
{
|
||
|
uint32_t sdc_sr = 0;
|
||
|
|
||
|
/* Make sure card exists */
|
||
|
if (GETB32(SDC_STATUS, SDC_SR_CARD_DETECT_BIT))
|
||
|
return SDD_CARD_REMOVED;
|
||
|
|
||
|
/* Clear SDC status bits */
|
||
|
OUT32(SDC_CLEAR, SDC_RSP_CRC_FAIL_MASK | SDC_RSP_TIMEOUT_MASK |
|
||
|
SDC_RSP_CRC_OK_MASK);
|
||
|
/*OUT32(SDC_CLEAR, SDC_CLEAR_ALL); */
|
||
|
|
||
|
/* Prepare Argument */
|
||
|
OUT32(SDC_CMD_ARG, arg);
|
||
|
|
||
|
/* Send command */
|
||
|
OUT32(SDC_CMD, cmd);
|
||
|
|
||
|
/* Wait until the command is responsed ... */
|
||
|
while (1) {
|
||
|
|
||
|
// _nds_kwait(0x1000); /* hw need delay ? */
|
||
|
|
||
|
sdc_sr = IN32(SDC_STATUS);
|
||
|
|
||
|
/* Make sure card exists */
|
||
|
if (sdc_sr & SDC_SR_CARD_DETECT_BIT)
|
||
|
return SDD_CARD_REMOVED;
|
||
|
|
||
|
/* Check error status */
|
||
|
if (sdc_sr & SDC_SR_RSP_CRC_OK_MASK) {
|
||
|
|
||
|
rsp->r[0] = IN32(SDC_R0);
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
else if (sdc_sr & SDC_SR_RSP_CRC_FAIL_MASK) {
|
||
|
|
||
|
return SDD_RSP_CRC_ERROR;
|
||
|
}
|
||
|
else if (sdc_sr & SDC_SR_RSP_TIMEOUT_MASK) {
|
||
|
|
||
|
return SDD_RSP_TIMEOUT;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_CMD_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
SDC_INLINE uint32_t _sd_cmd_r128(uint32_t cmd, SD_R128 * rsp)
|
||
|
{
|
||
|
uint32_t retry_cnt = 0;
|
||
|
uint32_t sdc_sr = 0;
|
||
|
|
||
|
/* Make sure card exists */
|
||
|
if (GETB32(SDC_STATUS, SDC_SR_CARD_DETECT_BIT))
|
||
|
return SDD_CARD_REMOVED;
|
||
|
|
||
|
/* Clear SDC status bits */
|
||
|
OUT32(SDC_CLEAR, SDC_RSP_CRC_FAIL_MASK | SDC_RSP_TIMEOUT_MASK |
|
||
|
SDC_RSP_CRC_OK_MASK | SDC_CMD_SENT_MASK);
|
||
|
/*OUT32(SDC_CLEAR, SDC_CLEAR_ALL); */
|
||
|
|
||
|
/* Send command */
|
||
|
OUT32(SDC_CMD, cmd);
|
||
|
|
||
|
/* Wait until the command is responsed ... */
|
||
|
while (retry_cnt++ < SD_CMD_MAX_RETRY_COUNT) {
|
||
|
|
||
|
sdc_sr = IN32(SDC_STATUS);
|
||
|
|
||
|
/* Make sure card exists */
|
||
|
if (sdc_sr & SDC_SR_CARD_DETECT_BIT)
|
||
|
return SDD_CARD_REMOVED;
|
||
|
|
||
|
/* Check error status */
|
||
|
if (sdc_sr & SDC_SR_RSP_CRC_OK_MASK) {
|
||
|
|
||
|
rsp->r[0] = IN32(SDC_R0);
|
||
|
rsp->r[1] = IN32(SDC_R1);
|
||
|
rsp->r[2] = IN32(SDC_R2);
|
||
|
rsp->r[3] = IN32(SDC_R3);
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
else if (sdc_sr & SDC_SR_RSP_CRC_FAIL_MASK) {
|
||
|
|
||
|
return SDD_RSP_CRC_ERROR;
|
||
|
}
|
||
|
else if (sdc_sr & SDC_SR_RSP_TIMEOUT_MASK) {
|
||
|
|
||
|
return SDD_RSP_TIMEOUT;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_CMD_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
SDC_INLINE uint32_t _sd_cmd_arg_r128(uint32_t cmd, uint32_t arg, SD_R128 * rsp)
|
||
|
{
|
||
|
uint32_t retry_cnt = 0;
|
||
|
uint32_t sdc_sr = 0;
|
||
|
|
||
|
/* Make sure card exists */
|
||
|
if (GETB32(SDC_STATUS, SDC_SR_CARD_DETECT_BIT))
|
||
|
return SDD_CARD_REMOVED;
|
||
|
|
||
|
/* Clear SDC status bits */
|
||
|
OUT32(SDC_CLEAR, SDC_RSP_CRC_FAIL_MASK | SDC_RSP_TIMEOUT_MASK |
|
||
|
SDC_RSP_CRC_OK_MASK | SDC_CMD_SENT_MASK);
|
||
|
/*OUT32(SDC_CLEAR, SDC_CLEAR_ALL); */
|
||
|
|
||
|
/* Prepare Argument */
|
||
|
OUT32(SDC_CMD_ARG, arg);
|
||
|
|
||
|
/* Send command */
|
||
|
OUT32(SDC_CMD, cmd);
|
||
|
|
||
|
/* Wait until the command is responsed ... */
|
||
|
while (retry_cnt++ < SD_CMD_MAX_RETRY_COUNT) {
|
||
|
|
||
|
sdc_sr = IN32(SDC_STATUS);
|
||
|
|
||
|
/* Make sure card exists */
|
||
|
if (sdc_sr & SDC_SR_CARD_DETECT_BIT)
|
||
|
return SDD_CARD_REMOVED;
|
||
|
|
||
|
/* Check error status */
|
||
|
if (sdc_sr & SDC_SR_RSP_CRC_OK_MASK) {
|
||
|
|
||
|
rsp->r[0] = IN32(SDC_R0);
|
||
|
rsp->r[1] = IN32(SDC_R1);
|
||
|
rsp->r[2] = IN32(SDC_R2);
|
||
|
rsp->r[3] = IN32(SDC_R3);
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
else if (sdc_sr & SDC_SR_RSP_CRC_FAIL_MASK) {
|
||
|
|
||
|
return SDD_RSP_CRC_ERROR;
|
||
|
}
|
||
|
else if (sdc_sr & SDC_SR_RSP_TIMEOUT_MASK) {
|
||
|
|
||
|
return SDD_RSP_TIMEOUT;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_CMD_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd0
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command GO_IDLE_STATE: Reset all cards to idle
|
||
|
* state.
|
||
|
*
|
||
|
* Class: 0 (basic commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* idle -> idle
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] stuff bits
|
||
|
*
|
||
|
* Response:
|
||
|
* None
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* None.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd0(void)
|
||
|
{
|
||
|
return _sd_cmd(SDC_CMD0_GO_IDLE_STATE);
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd2
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command ALL_SEND_CID: Ask any card to send the
|
||
|
* CID numbers
|
||
|
*
|
||
|
* Class: 0 (basic commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* ready -> identification
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] stuff bits
|
||
|
*
|
||
|
* Response:
|
||
|
* R2 [127:1] CID
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* cid : Pointer to SD_CID struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* cid : SD_CID struct which holds the card's CID register value.
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_cmd2(SD_CID * cid)
|
||
|
{
|
||
|
return _sd_cmd_r128(SDC_CMD2_ALL_SEND_CID, cid);
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd3
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SEND_RELATIVE_ADDR: Ask the card to
|
||
|
* publish a new RCA.
|
||
|
*
|
||
|
* Class: 0 (basic commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* identification -> standby
|
||
|
* standy -> standby
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] stuff bits
|
||
|
*
|
||
|
* Response:
|
||
|
* R6 [23:08] card status bits: 23, 22, 19, 12:0
|
||
|
* [39:24] New publishded RCA
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : Pointer to SD_R32 struct to receive RCA.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* rca : SD_R32 struct where RCA will be placed at [31:16].
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_cmd3(SD_R32 * rca)
|
||
|
{
|
||
|
return _sd_cmd_r32(SDC_CMD3_SEND_RELATIVE_ADDR, rca);
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd4
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SET_DSR: Program DSR of all cards.
|
||
|
*
|
||
|
* Class: 0 (basic commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* standy -> standby
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:16] DSR
|
||
|
*
|
||
|
* Response:
|
||
|
* None
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* dsr : uint32_t value where DSR is at [31:16].
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd4(uint32_t dsr)
|
||
|
{
|
||
|
return _sd_cmd_arg(SDC_CMD4_SET_DSR, dsr);
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd7
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SELECT/DESELECT_CARD: Toggles between
|
||
|
* standby and transfer states or between programming and disconnect
|
||
|
* states. Cards with matching RCA is selected, otherwise deselected.
|
||
|
*
|
||
|
* Class: 0 (basic commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* selected card:
|
||
|
* standby -> transfer
|
||
|
* disconnected -> programming
|
||
|
* deselected card
|
||
|
* standby -> standby
|
||
|
* transfer -> standby
|
||
|
* sending-data -> standby
|
||
|
* programming -> disconnected
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:16] RCA
|
||
|
*
|
||
|
* Response:
|
||
|
* R1b [39:8] card status
|
||
|
* DAT0 busy signal
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : SD_R32 struct where RCA is at [31:16].
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_cmd7(uint32_t rca, SD_R32 * csr)
|
||
|
{
|
||
|
uint32_t status = _sd_cmd_arg_r32(SDC_CMD7_SELECT_DESELECT_CARD, rca, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd8
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SEND_IF_COND: Send VHS to SD card before
|
||
|
* issuing ACMD41 during initialization and identification process.
|
||
|
*
|
||
|
* Class: 0 (basic commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* idle -> idle
|
||
|
*
|
||
|
* Argument:
|
||
|
* [11:8] VHS (see R7 bellow)
|
||
|
* [ 7:0] Arbitrary Check Pattern (10101010b(0xaa) is suggested)
|
||
|
*
|
||
|
* Response:
|
||
|
* R7 [19:16] voltage accepted (VHS)
|
||
|
* 0001b (0x01) -> 2.7-3.6v
|
||
|
* others are reserved or undefined
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* vhs_arg: uint32_t value with VHS at [11:8] and check-ptn at [7:0].
|
||
|
* vhs_rsp: Pointer to SD_R32 struct to hold the response.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* vhs_rsp: SD_R32 struct with VHS at [11:8] and check-ptn at [7:0].
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_cmd8(uint32_t vhs_arg, SD_R32 * vhs_rsp)
|
||
|
{
|
||
|
return _sd_cmd_arg_r32(SDC_CMD8_SEND_IF_COND, vhs_arg, vhs_rsp);
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd9
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SEND_CSD: Ask addressed card to send its
|
||
|
* CSD on the command line.
|
||
|
*
|
||
|
* Class: 0 (basic commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* standby -> standby
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:16] RCA
|
||
|
*
|
||
|
* Response:
|
||
|
* R2 [127:1] CSD
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
* csd : Pointer to SD_CSD struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csd : SD_CSD struct which contains CSD response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_cmd9(uint32_t rca, SD_CSD * csd)
|
||
|
{
|
||
|
return _sd_cmd_arg_r128(SDC_CMD9_SEND_CSD, rca, csd);
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd10
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SEND_CID: Ask addressed card to send its
|
||
|
* CID on the command line.
|
||
|
*
|
||
|
* Class: 0 (basic commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* standby -> standby
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:16] RCA
|
||
|
*
|
||
|
* Response:
|
||
|
* R2 [127:1] CID
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
* cid : Pointer to SD_CID struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* cid : SD_CID struct which contains CID response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd10(uint32_t rca, SD_CID * cid)
|
||
|
{
|
||
|
return _sd_cmd_arg_r128(SDC_CMD10_SEND_CID, rca, cid);
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd12
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command STOP_TRANSMISSION: Forces the card to
|
||
|
* stop transmission.
|
||
|
*
|
||
|
* Class: 0 (basic commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* snedning-data -> transfer
|
||
|
* receiving-data -> programming
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] stuff bits
|
||
|
*
|
||
|
* Response:
|
||
|
* R1b [39:8] card status
|
||
|
* DAT0 busy signal
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* csr : Pointer to SD_R32 value.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_cmd12(SD_R32 * csr)
|
||
|
{
|
||
|
uint32_t status = _sd_cmd_r32(SDC_CMD12_STOP_TRANSMISSION, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr)) /* todo: ok to check all error bits */
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd13
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SEND_STATUS: Ask the card to send its
|
||
|
* card status.
|
||
|
*
|
||
|
* Class: 0 (basic commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* standby -> standby
|
||
|
* transfer -> transfer
|
||
|
* sending-data -> sending-data
|
||
|
* receiving-data -> receieving-data
|
||
|
* programming -> programming
|
||
|
* disconnect -> disconnect
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:16] RCA
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
* csr : Pointer to SD_R32 to receive CSR.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 which holds the received CSR.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_cmd13(uint32_t rca, SD_R32 * csr)
|
||
|
{
|
||
|
uint32_t status = _sd_cmd_arg_r32(SDC_CMD13_SEND_STATUS, rca, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd15
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command GO_INACTIVE_STATE: Inactivate the
|
||
|
* addressed card to inactive state.
|
||
|
*
|
||
|
* Class: 0 (basic commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* standby -> inactive
|
||
|
* transfer -> inactive
|
||
|
* sending-data -> inactive
|
||
|
* receiving-data -> inactive
|
||
|
* programming -> inactive
|
||
|
* disconnect -> inactive
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:16] RCA
|
||
|
* [15: 0] Should be 0!
|
||
|
*
|
||
|
* Response:
|
||
|
* None
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value with RCA at [31:16], 0 at [15:0].
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd15(uint32_t rca)
|
||
|
{
|
||
|
return _sd_cmd_arg(SDC_CMD15_GO_INACTIVE_STATE, rca);
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd16
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SET_BLOCKLEN: Set block length (bytes)
|
||
|
* for standard capacity SD cards. SDHC is fixed to 512 bytes and ignores
|
||
|
* this field except the LOCK_UNLOCK command.
|
||
|
*
|
||
|
* Class: 2/4/7 (block-oriented read/write/lock_unlock commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> transfer
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] block length
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* blk_len: uint32_t block length value.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_cmd16(uint32_t blk_len, SD_R32 * csr)
|
||
|
{
|
||
|
uint32_t status = _sd_cmd_arg_r32(SDC_CMD16_SET_BLOCKLEN, blk_len, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd17
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command READ_SINGLE_BLOCK: Reads a single block
|
||
|
* size of data.
|
||
|
*
|
||
|
* Class: 2 (block-oriented read commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> sending-data
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] data address (byte-unit for SD, block unit for SDHC)
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* addr : uint32_t address value.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd17(uint32_t addr, SD_R32 * csr)
|
||
|
{
|
||
|
#if 0
|
||
|
uint32_t retry = 0;
|
||
|
|
||
|
while (retry++ < SD_STATE_MAX_RETRY_COUNT) {
|
||
|
#endif
|
||
|
/* Send SD command */
|
||
|
uint32_t status =
|
||
|
_sd_cmd_arg_r32(SDC_CMD17_READ_SINGLE_BLOCK, addr, csr);
|
||
|
if (status != HAL_SUCCESS) {
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
/* Check error status */
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
#if 0
|
||
|
/* Check whether make transition to sending-data state */
|
||
|
switch (SD_CSR_GET_CURRENT_STATE(*csr)) {
|
||
|
case SD_STATE_DATA:
|
||
|
/* The card is ready to send out data */
|
||
|
return HAL_SUCCESS;
|
||
|
case SD_STATE_TRAN:
|
||
|
/* Repeat previous command until the card get to the state */
|
||
|
break;
|
||
|
case SD_STATE_STBY:
|
||
|
case SD_STATE_RCV:
|
||
|
case SD_STATE_PRG:
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
case SD_STATE_DIS:
|
||
|
default:
|
||
|
/* Invalid current state before deselecting the card. */
|
||
|
return SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
#else
|
||
|
return HAL_SUCCESS;
|
||
|
#endif
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd18
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command READ_MULTIPLE_BLOCK: Reads blocks of data
|
||
|
* from card continuously until a STOP_TRANSMISSION command.
|
||
|
*
|
||
|
* Class: 2 (block-oriented read commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> sending-data
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] data address (byte-unit for SD, block unit for SDHC)
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* addr : uint32_t address value.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_cmd18(uint32_t addr, SD_R32 * csr) {
|
||
|
#if 0
|
||
|
uint32_t retry = 0;
|
||
|
|
||
|
while (retry++ < SD_STATE_MAX_RETRY_COUNT) {
|
||
|
#endif
|
||
|
/* Send SD command */
|
||
|
uint32_t status =
|
||
|
_sd_cmd_arg_r32(SDC_CMD18_READ_MULTIPLE_BLOCK, addr,
|
||
|
csr);
|
||
|
if (status != HAL_SUCCESS) {
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
/* Check error status */
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
#if 0
|
||
|
/* Check whether make transition to sending-data state */
|
||
|
switch (SD_CSR_GET_CURRENT_STATE(*csr)) {
|
||
|
case SD_STATE_DATA:
|
||
|
/* The card is ready to send out data */
|
||
|
return HAL_SUCCESS;
|
||
|
case SD_STATE_TRAN:
|
||
|
/* Repeat previous command until the card get to the state */
|
||
|
break;
|
||
|
case SD_STATE_STBY:
|
||
|
case SD_STATE_RCV:
|
||
|
case SD_STATE_PRG:
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
case SD_STATE_DIS:
|
||
|
default:
|
||
|
/* Invalid current state before deselecting the card. */
|
||
|
return SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
#else
|
||
|
return HAL_SUCCESS;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd24
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command WRITE_SINGLE_BLOCK: Writes a single
|
||
|
* block size of data.
|
||
|
*
|
||
|
* Class: 2 (block-oriented write commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> receiving-data
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] data address (byte-unit for SD, block unit for SDHC)
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* addr : uint32_t address value.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd24(uint32_t addr, SD_R32 * csr) {
|
||
|
#if 0
|
||
|
uint32_t retry = 0;
|
||
|
|
||
|
while (retry++ < SD_STATE_MAX_RETRY_COUNT) {
|
||
|
#endif
|
||
|
/* Send SD command */
|
||
|
uint32_t status = _sd_cmd_arg_r32(SDC_CMD24_WRITE_BLOCK, addr, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
/* Check error status */
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
#if 0
|
||
|
/* Check whether make transition to sending-data state */
|
||
|
switch (SD_CSR_GET_CURRENT_STATE(*csr)) {
|
||
|
case SD_STATE_RCV:
|
||
|
/* The card is ready to send out data */
|
||
|
return HAL_SUCCESS;
|
||
|
case SD_STATE_TRAN:
|
||
|
/* Repeat previous command until the card get to the state */
|
||
|
break;
|
||
|
case SD_STATE_STBY:
|
||
|
case SD_STATE_DATA:
|
||
|
case SD_STATE_PRG:
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
case SD_STATE_DIS:
|
||
|
default:
|
||
|
/* Invalid current state before deselecting the card. */
|
||
|
return SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
#else
|
||
|
return HAL_SUCCESS;
|
||
|
#endif
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd25
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command WRITE_MULTIPLE_BLOCK: Writes blocks of
|
||
|
* data to the card continuously until a STOP_TRANSMISSION command.
|
||
|
*
|
||
|
* Class: 2 (block-oriented write commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> receiving-data
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] data address (byte-unit for SD, block unit for SDHC)
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* addr : uint32_t address value.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_cmd25(uint32_t addr, SD_R32 * csr) {
|
||
|
#if 0
|
||
|
uint32_t retry = 0;
|
||
|
|
||
|
while (retry++ < SD_STATE_MAX_RETRY_COUNT) {
|
||
|
#endif
|
||
|
/* Send SD command */
|
||
|
uint32_t status = _sd_cmd_arg_r32 (SDC_CMD25_WRITE_MULTIPLE_BLOCK, addr, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
/* Check error status */
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
#if 0
|
||
|
/* Check whether make transition to sending-data state */
|
||
|
switch (SD_CSR_GET_CURRENT_STATE(*csr)) {
|
||
|
case SD_STATE_RCV:
|
||
|
/* The card is ready to send out data */
|
||
|
return HAL_SUCCESS;
|
||
|
case SD_STATE_TRAN:
|
||
|
/* Repeat previous command until the card get to the state */
|
||
|
break;
|
||
|
case SD_STATE_STBY:
|
||
|
case SD_STATE_DATA:
|
||
|
case SD_STATE_PRG:
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
case SD_STATE_DIS:
|
||
|
default:
|
||
|
/* Invalid current state before deselecting the card. */
|
||
|
return SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
#else
|
||
|
return HAL_SUCCESS;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd27
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command PROGRAM_CSD: Programming the
|
||
|
* programmable bits of the CSD (using DATx lines).
|
||
|
*
|
||
|
* Class: 2 (block-oriented write commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> receiving-data
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] stufing bits
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd27(SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_r32(SDC_CMD27_PROGRAM_CSD, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd28
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SET_WRITE_PROT: Sets the write protection
|
||
|
* bits of the addressed group, if supported. (Not supported in SDHC)
|
||
|
*
|
||
|
* Class: 6 (block-oriented write protection commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> programming
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] data address (byte unit)
|
||
|
*
|
||
|
* Response:
|
||
|
* R1b [39:8] card status
|
||
|
* DAT0 busy signal
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* addr : uint32_t address value.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd28(uint32_t addr, SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_arg_r32 (SDC_CMD28_SET_WRITE_PROT, addr, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd29
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command CLR_WRITE_PROT: Clears the write
|
||
|
* protection bits of the addressed group, if supported.
|
||
|
* (Not supported in SDHC)
|
||
|
*
|
||
|
* Class: 6 (block-oriented write protection commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> programming
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] data address (byte unit)
|
||
|
*
|
||
|
* Response:
|
||
|
* R1b [39:8] card status
|
||
|
* DAT0 busy signal
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* addr : uint32_t address value.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd29(uint32_t addr, SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_arg_r32 (SDC_CMD29_CLR_WRITE_PROT, addr, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd30
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SEND_WRITE_PROT: Ask the card to send
|
||
|
* the status of the protection bits of the addressed group, if supported.
|
||
|
* (Not supported in SDHC)
|
||
|
*
|
||
|
* Class: 6 (block-oriented write protection commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> receiving-data
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] data address (byte unit)
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* addr : uint32_t address value.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd30(uint32_t addr, SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_arg_r32 (SDC_CMD30_SEND_WRITE_PROT, addr, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd32
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command ERASE_WR_BLK_START: Sets the address of
|
||
|
* the first write block to be erased.
|
||
|
*
|
||
|
* Class: 5 (erase commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> transfer
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] data address (SD: byte unit, SDHC: block unit)
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* addr : uint32_t address value.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd32(uint32_t addr, SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_arg_r32 (SDC_CMD32_ERASE_WR_BLK_START, addr, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd33
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command ERASE_WR_BLK_END: Sets the address of
|
||
|
* the last write block of a continuous range to be erased.
|
||
|
*
|
||
|
* Class: 5 (erase commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> transfer
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] data address (SD: byte unit, SDHC: block unit)
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* addr : uint32_t address value.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd33(uint32_t addr, SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_arg_r32 (SDC_CMD33_ERASE_WR_BLK_END, addr, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd38
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command ERASE: Erase all previously selected
|
||
|
* write blocks.
|
||
|
*
|
||
|
* Class: 5 (erase commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> programming
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] stuff bits
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
* DAT0 busy signal
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* addr : uint32_t address value.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd38(SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_r32(SDC_CMD38_ERASE, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd42
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command LOCK_UNLOCK: Set/reset the password or
|
||
|
* lock/unlock the card.
|
||
|
*
|
||
|
* Class: 7 (lock card)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> receiving-data
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] should be all 0!
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd42(SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_arg_r32 (SDC_CMD42_LOCK_UNLOCK, 0, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd55
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command APP_CMD: Indicates the next command is
|
||
|
* an application specific command.
|
||
|
*
|
||
|
* Class: 8 (application-specific commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* idle -> idle
|
||
|
* standby -> standby
|
||
|
* transfer -> transfer
|
||
|
* sending-data -> sending-data
|
||
|
* receiving-data -> receiving-data
|
||
|
* programming -> programming
|
||
|
* disconnected -> disconnected
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:16] RCA
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_cmd55(uint32_t rca, SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_arg_r32(SDC_CMD55_APP_CMD, rca, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd56
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command GEN_CMD: To transfer data block from/to
|
||
|
* the card for general-purpose/application-specific commands.
|
||
|
*
|
||
|
* Class: 8 (application-specific commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* RD/WR = 0 (write)
|
||
|
* transfer -> receiving-data
|
||
|
* RD/WR = 1 (read)
|
||
|
* transfer -> sending-data
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31: 1] stuff bits
|
||
|
* [0] RD/WR
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rdwr : uint32_t value where bit [0] is RD/WR.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd56(uint32_t rdwr, SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_arg_r32(SDC_CMD56_GEN_CMD, rdwr, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_acmd6
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SET_BUS_WIDTH: Defines the data bus
|
||
|
* width to be used for data transfer. The allowed bus widths are given
|
||
|
* in the SCR register.
|
||
|
*
|
||
|
* Class: 8 (application-specific commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> transfer
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:2] stuff bits
|
||
|
* [ 1:0] bus width (00b -> 1bit, 10b -> 4bits)
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* bw : uint32_t value where bit [1:0] is bus width.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_acmd6(uint32_t bw, SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_arg_r32 (SDC_ACMD6_SET_BUS_WIDTH, bw, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_acmd13
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SD_STATUS: Send the SD status.
|
||
|
*
|
||
|
* Class: 8 (application-specific commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> sending-data
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] stuff bits
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_acmd13(SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_r32(SDC_ACMD13_SD_STATUS, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_acmd22
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SEND_NUM_WR_BLOCKS: Send the number of
|
||
|
* non-error write blocks.
|
||
|
*
|
||
|
* If (WRITE_BL_PARTIAL == 0)
|
||
|
* unit of ACMD22 is 512 bytes
|
||
|
* else
|
||
|
* unit of ACMD22 is a block length of write command
|
||
|
*
|
||
|
* Class: 8 (application-specific commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> sending-data
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] stuff bits
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_acmd22(SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_r32 (SDC_ACMD22_SEND_NUM_WR_BLOCKS, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_acmd23
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SET_WR_BLK_ERASE_COUNT: Send the number
|
||
|
* of write blocks to be pre-erased before writing (for faster multiple-
|
||
|
* block-WR command). Default is 1.
|
||
|
*
|
||
|
* Class: 8 (application-specific commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> transfer
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:23] stuff bits
|
||
|
* [22: 0] number of blocks
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* blocks : uint32_t value represents the number of blocks.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_acmd23(uint32_t blocks, SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_arg_r32 (SDC_ACMD23_SET_WR_BLK_ERASE_COUNT, blocks, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_acmd41
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SD_SEND_OP_COND: Send HCS and get OCR
|
||
|
* during the initialization and identification process.
|
||
|
*
|
||
|
* Class: 8 (application-specific commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* idle -> ready (OCR check OK and card is not busy)
|
||
|
* idle -> idle (OCR check OK and card is busy)
|
||
|
* idle -> inactive (OCR check fails)
|
||
|
* idle -> idle (query mode)
|
||
|
*
|
||
|
* Argument:
|
||
|
* [30] HCS (OCR[32])
|
||
|
* [23:0] Vdd voltage window (OCR[23:0])
|
||
|
*
|
||
|
* Response:
|
||
|
* R3 [39:8] OCR
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* hcs : uint32_t value represents the host capacity support information.
|
||
|
* ocr : Pointer to SD_OCR struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* ocr : SD_OCR struct which holds the R3/OCR response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_acmd41(uint32_t hcs, SD_OCR * ocr) {
|
||
|
|
||
|
return _sd_cmd_arg_r32 (SDC_ACMD41_SD_SEND_OP_COND, hcs, ocr);
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_acmd42
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SET_CLR_CARD_DETECT: Connect/Disconnect
|
||
|
* the 50 KOmh pull-up resister on CD/DAT3 (pin1) of the card.
|
||
|
*
|
||
|
* Class: 8 (application-specific commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> transfer
|
||
|
*
|
||
|
* Argument:
|
||
|
* [0] set_cd (1: connect, 0: disconnect)
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* conn : uint32_t value where [0] denotes set_cd.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_acmd42(uint32_t conn, SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_arg_r32 (SDC_ACMD42_SET_CLR_CARD_DETECT, conn, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_acmd51
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SEND_SCR: Reads the SD configuration
|
||
|
* register (SCR).
|
||
|
*
|
||
|
* Class: 8 (application-specific commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> sending-data
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31:0] stuff bits
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_acmd51(SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_r32(SDC_ACMD51_SEND_SCR, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_cmd6
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function issues SD command SWITCH_FUNC: Check switchable function
|
||
|
* or switch card function.
|
||
|
*
|
||
|
* Class: 8 (application-specific commands)
|
||
|
*
|
||
|
* State Transition:
|
||
|
* transfer -> sending-data
|
||
|
*
|
||
|
* Argument:
|
||
|
* [31] mode (0: check, 1: switch)
|
||
|
* [30:24] should be 0
|
||
|
* [23:20] 00h or 0fh (reserved for function group 6)
|
||
|
* [19:16] 00h or 0fh (reserved for function group 5)
|
||
|
* [15:12] 00h or 0fh (reserved for function group 4)
|
||
|
* [11: 8] 00h or 0fh (reserved for function group 3)
|
||
|
* [ 7: 4] function group 2 for command system
|
||
|
* [ 3: 0] function group 1 for access mode
|
||
|
*
|
||
|
* Response:
|
||
|
* R1 [39:8] card status
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* mode : uint32_t value which holds the function mode.
|
||
|
* csr : Pointer to SD_R32 struct.
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* csr : SD_R32 struct which holds the R1 response.
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
#if (SDD_SMALL_SD_FOOTPRINT == 0)
|
||
|
uint32_t _sd_cmd6(uint32_t mode, SD_R32 * csr) {
|
||
|
|
||
|
uint32_t status = _sd_cmd_arg_r32 (SDC_CMD6_SWITCH_FUNC, mode, csr);
|
||
|
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
if (SD_CSR_CHECK_ERROR_BITS(*csr))
|
||
|
return SDD_CSR_ERROR;
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
#endif /* (SDD_SMALL_SD_FOOTPRINT == 0) */
|
||
|
|
||
|
#if 0
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_wait_sending_state
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function waits the transfer state make transition to the sending-
|
||
|
* data state. This is equivalent to waiting for the card start to send
|
||
|
* out data after cmd17 or cmd18.
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_wait_sending_state(uint32_t rca) {
|
||
|
uint32_t status;
|
||
|
SD_R32 sd_rsp32;
|
||
|
uint32_t retry = 0;
|
||
|
|
||
|
while (retry++ <
|
||
|
SD_TRANSFER_MAX_RETRY_COUNT) {
|
||
|
/* Get current state */
|
||
|
status =
|
||
|
_sd_cmd13(rca, &sd_rsp32);
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
switch (SD_CSR_GET_CURRENT_STATE
|
||
|
(sd_rsp32)) {
|
||
|
case SD_STATE_DATA:
|
||
|
return HAL_SUCCESS;
|
||
|
case SD_STATE_TRAN:
|
||
|
break;
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
case SD_STATE_STBY:
|
||
|
case SD_STATE_RCV:
|
||
|
case SD_STATE_DIS:
|
||
|
case SD_STATE_PRG:
|
||
|
default:
|
||
|
return
|
||
|
SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_wait_receiving_state
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function waits the transfer state make transition to the receiving-
|
||
|
* data state. This is equivalent to waiting for the card start to receive
|
||
|
* data after cmd24/25/27/42/56.
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_wait_receiving_state(uint32_t rca) {
|
||
|
uint32_t status;
|
||
|
SD_R32 sd_rsp32;
|
||
|
uint32_t retry = 0;
|
||
|
|
||
|
while (retry++ <
|
||
|
SD_TRANSFER_MAX_RETRY_COUNT) {
|
||
|
/* Get current state */
|
||
|
status =
|
||
|
_sd_cmd13(rca, &sd_rsp32);
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
switch (SD_CSR_GET_CURRENT_STATE
|
||
|
(sd_rsp32)) {
|
||
|
case SD_STATE_RCV:
|
||
|
if (SD_CSR_GET_READY_FOR_DATA(sd_rsp32))
|
||
|
return
|
||
|
HAL_SUCCESS;
|
||
|
break;
|
||
|
case SD_STATE_TRAN:
|
||
|
break;
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
case SD_STATE_STBY:
|
||
|
case SD_STATE_DATA:
|
||
|
case SD_STATE_DIS:
|
||
|
case SD_STATE_PRG:
|
||
|
default:
|
||
|
return
|
||
|
SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
}
|
||
|
#endif /* 0 */
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_wait_programmed
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function waits the disconnected state make transition to the
|
||
|
* standby state or the transfer state. This is equivalent to waiting for
|
||
|
* the completion of programming.
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_wait_programmed(uint32_t rca) {
|
||
|
|
||
|
uint32_t status;
|
||
|
SD_R32 sd_rsp32;
|
||
|
uint32_t retry = 0;
|
||
|
|
||
|
while (retry++ < SD_TRANSFER_MAX_RETRY_COUNT) {
|
||
|
|
||
|
/* Get current state */
|
||
|
status = _sd_cmd13(rca, &sd_rsp32);
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
switch (SD_CSR_GET_CURRENT_STATE
|
||
|
(sd_rsp32)) {
|
||
|
case SD_STATE_STBY:
|
||
|
case SD_STATE_TRAN:
|
||
|
return HAL_SUCCESS;
|
||
|
case SD_STATE_DIS:
|
||
|
case SD_STATE_PRG:
|
||
|
break;
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
case SD_STATE_DATA:
|
||
|
case SD_STATE_RCV:
|
||
|
default:
|
||
|
return
|
||
|
SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_wait_transferred
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function waits the data/rcv/prog state make transition to the
|
||
|
* transfer state. This is equivalent to waiting for the
|
||
|
* completion of all current data transfer traffic.
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_wait_transferred(uint32_t rca) {
|
||
|
|
||
|
uint32_t status;
|
||
|
SD_R32 sd_rsp32;
|
||
|
uint32_t retry = 0;
|
||
|
|
||
|
while (retry++ < SD_TRANSFER_MAX_RETRY_COUNT) {
|
||
|
|
||
|
/* Get current state */
|
||
|
status = _sd_cmd13(rca, &sd_rsp32);
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
switch (SD_CSR_GET_CURRENT_STATE (sd_rsp32)) {
|
||
|
|
||
|
case SD_STATE_TRAN:
|
||
|
return HAL_SUCCESS;
|
||
|
case SD_STATE_DATA:
|
||
|
case SD_STATE_RCV:
|
||
|
case SD_STATE_PRG:
|
||
|
break;
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
case SD_STATE_STBY:
|
||
|
case SD_STATE_DIS:
|
||
|
default:
|
||
|
return
|
||
|
SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_disconnect
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function forces the prog state make transition to the
|
||
|
* disconnect state.
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_disconnect(uint32_t rca) {
|
||
|
|
||
|
uint32_t status;
|
||
|
SD_R32 sd_rsp32;
|
||
|
uint32_t retry = 0;
|
||
|
|
||
|
while (retry++ < SD_STATE_MAX_RETRY_COUNT) {
|
||
|
/* Get current state */
|
||
|
status = _sd_cmd13(rca, &sd_rsp32);
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
/* Perform state transition according to spec 2.0 fig 4-3. */
|
||
|
switch (SD_CSR_GET_CURRENT_STATE (sd_rsp32)) {
|
||
|
|
||
|
case SD_STATE_STBY:
|
||
|
case SD_STATE_DIS:
|
||
|
/* The card with the target rca is already disconnected. Just */
|
||
|
/* return that the card is disconnected successfully. */
|
||
|
return HAL_SUCCESS;
|
||
|
case SD_STATE_PRG:
|
||
|
/* Try to enter disconnected state ... */
|
||
|
status = _sd_cmd7(rca, &sd_rsp32); /* disconnect the card */
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
break;
|
||
|
case SD_STATE_TRAN:
|
||
|
case SD_STATE_DATA:
|
||
|
case SD_STATE_RCV:
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
default:
|
||
|
/* Invalid current state before disconnect the card. */
|
||
|
return
|
||
|
SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_connect
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function forces the disconnect state make transition to the
|
||
|
* programming state.
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_connect(uint32_t rca) {
|
||
|
|
||
|
uint32_t status;
|
||
|
SD_R32 sd_rsp32;
|
||
|
uint32_t retry = 0;
|
||
|
|
||
|
while (retry++ < SD_STATE_MAX_RETRY_COUNT) {
|
||
|
|
||
|
/* Get current state */
|
||
|
status = _sd_cmd13(rca, &sd_rsp32);
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
/* Perform state transition according to spec 2.0 fig 4-3. */
|
||
|
switch (SD_CSR_GET_CURRENT_STATE (sd_rsp32)) {
|
||
|
case SD_STATE_PRG:
|
||
|
case SD_STATE_TRAN:
|
||
|
/*
|
||
|
* The card with the target rca is already connected. Just
|
||
|
* return that the card is connected successfully.
|
||
|
*/
|
||
|
return HAL_SUCCESS;
|
||
|
case SD_STATE_DIS:
|
||
|
/* Try to enter programming state ... */
|
||
|
status = _sd_cmd7(rca, &sd_rsp32); /* connect the card */
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
break;
|
||
|
case SD_STATE_STBY:
|
||
|
case SD_STATE_DATA:
|
||
|
case SD_STATE_RCV:
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
default:
|
||
|
/* Invalid current state before connect the card. */
|
||
|
return
|
||
|
SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_deselect_card
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function forces the transfer state make transition to the
|
||
|
* standby state.
|
||
|
*
|
||
|
* If the card is currently in data or transfer state, the function will
|
||
|
* issue trnasition command and continue loop until the card enters standby
|
||
|
* state.
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_deselect_card(uint32_t rca) {
|
||
|
|
||
|
uint32_t status;
|
||
|
SD_R32 sd_rsp32;
|
||
|
uint32_t retry = 0;
|
||
|
|
||
|
while (retry++ < SD_STATE_MAX_RETRY_COUNT) {
|
||
|
/* Get current state */
|
||
|
status = _sd_cmd13(rca, &sd_rsp32);
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
/* Perform state transition according to spec 2.0 fig 4-3. */
|
||
|
switch (SD_CSR_GET_CURRENT_STATE (sd_rsp32)) {
|
||
|
|
||
|
case SD_STATE_STBY:
|
||
|
/*
|
||
|
* The card with the target rca is already deselected. Just
|
||
|
* return that the card is deselected successfully.
|
||
|
*/
|
||
|
return HAL_SUCCESS;
|
||
|
case SD_STATE_TRAN:
|
||
|
case SD_STATE_DATA:
|
||
|
/* Try to enter standby state ... */
|
||
|
status = _sd_cmd7(rca, &sd_rsp32); /* deselect the card */
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
break;
|
||
|
case SD_STATE_RCV:
|
||
|
case SD_STATE_PRG:
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
case SD_STATE_DIS:
|
||
|
default:
|
||
|
/* Invalid current state before deselecting the card. */
|
||
|
return
|
||
|
SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_select_card
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function forces the standby state make transition to the
|
||
|
* transfer state.
|
||
|
*
|
||
|
* If the card is currently in data/rcv state, the function will wait for
|
||
|
* a limitted time. After timeout, it forces to stop the current
|
||
|
* operation and try to make transition back to standby state.
|
||
|
*
|
||
|
* If the card is currently in the prog state, the function will wait for
|
||
|
* a limitted time. If timeout then it will return that failed to make
|
||
|
* the desired state transition.
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_select_card(uint32_t rca) {
|
||
|
|
||
|
uint32_t status;
|
||
|
SD_R32 sd_rsp32;
|
||
|
uint32_t retry = 0;
|
||
|
|
||
|
while (retry++ < SD_STATE_MAX_RETRY_COUNT) {
|
||
|
|
||
|
/* Get current state */
|
||
|
status = _sd_cmd13(rca, &sd_rsp32);
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
/* Perform state transition according to spec 2.0 fig 4-3. */
|
||
|
switch (SD_CSR_GET_CURRENT_STATE (sd_rsp32)) {
|
||
|
|
||
|
case SD_STATE_TRAN:
|
||
|
/*
|
||
|
* The card with the target rca is already selected. Just
|
||
|
* return that the card is selected successfully.
|
||
|
*/
|
||
|
return HAL_SUCCESS;
|
||
|
case SD_STATE_STBY:
|
||
|
/* Try to enter transfer state ... */
|
||
|
status = _sd_cmd7(rca, &sd_rsp32); /* select the card */
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
break;
|
||
|
case SD_STATE_DATA:
|
||
|
case SD_STATE_RCV:
|
||
|
/*
|
||
|
* The card is still transferring data or programming.
|
||
|
* Wait a short period for transfer completion. The
|
||
|
* card will back to transfer state after operation
|
||
|
* completion.
|
||
|
*/
|
||
|
status = _sd_wait_transferred (rca);
|
||
|
|
||
|
if (status == HAL_SUCCESS) {
|
||
|
|
||
|
return HAL_SUCCESS;
|
||
|
}
|
||
|
else if (status == SDD_WAIT_TIMEOUT)
|
||
|
{
|
||
|
/*
|
||
|
* Stop the current transmission after waiting timeout. Then
|
||
|
* continue status check loop to fall back to transfer state.
|
||
|
*/
|
||
|
status = _sd_cmd12(&sd_rsp32); /* stop transmission */
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
}
|
||
|
else {
|
||
|
return status;
|
||
|
}
|
||
|
break;
|
||
|
case SD_STATE_PRG:
|
||
|
|
||
|
status = _sd_wait_transferred (rca);
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
break;
|
||
|
case SD_STATE_DIS:
|
||
|
/* Continue status check loop to fall back to standby state. */
|
||
|
break;
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
default:
|
||
|
/* Invalid current state before selecting the card. */
|
||
|
return SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* _sd_stop_transmission
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
*
|
||
|
* This function forces the data/rcv/prog state make transition to the
|
||
|
* transfer state.
|
||
|
*
|
||
|
* If the card is currently in data/rcv state, the function will issue
|
||
|
* stop command directly. Then continue check loop to wait for back to
|
||
|
* the transfer or standby state.
|
||
|
*
|
||
|
* If the card is currently in the prog state, the function will wait for
|
||
|
* a limitted time. If timeout then it will return that failed to make
|
||
|
* the desired state transition.
|
||
|
*
|
||
|
* INPUTS
|
||
|
*
|
||
|
* rca : uint32_t value where RCA is at [31:16].
|
||
|
*
|
||
|
* OUTPUTS
|
||
|
*
|
||
|
* uint32_t : Returns HAL_SUCCESS if successful,
|
||
|
* else positive value is SDD-specific error code,
|
||
|
* else negative value is NU system error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
uint32_t _sd_stop_transmission(uint32_t rca) {
|
||
|
|
||
|
uint32_t status;
|
||
|
SD_R32 sd_rsp32;
|
||
|
|
||
|
while (1) {
|
||
|
|
||
|
// _nds_kwait(0x1000);
|
||
|
|
||
|
/* Get current state */
|
||
|
status = _sd_cmd13(rca, &sd_rsp32);
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
/* Perform state transition according to spec 2.0 fig 4-3. */
|
||
|
switch (SD_CSR_GET_CURRENT_STATE (sd_rsp32)) {
|
||
|
|
||
|
case SD_STATE_STBY:
|
||
|
case SD_STATE_TRAN:
|
||
|
/* The card with the target rca is already stopped. Just */
|
||
|
/* return that the card is stopped successfully. */
|
||
|
return HAL_SUCCESS;
|
||
|
case SD_STATE_DATA:
|
||
|
case SD_STATE_RCV:
|
||
|
/* Try to back to transfer state ... */
|
||
|
status = _sd_cmd12(&sd_rsp32); /* stop transmission */
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
break;
|
||
|
case SD_STATE_PRG:
|
||
|
/* The card is still transferring data or programming. */
|
||
|
/* Wait a short period for transfer completion. The */
|
||
|
/* card will back to transfer state after operation */
|
||
|
/* completion. */
|
||
|
status = _sd_wait_transferred (rca);
|
||
|
if (status != HAL_SUCCESS)
|
||
|
return status;
|
||
|
|
||
|
break;
|
||
|
case SD_STATE_IDLE:
|
||
|
case SD_STATE_READY:
|
||
|
case SD_STATE_IDENT:
|
||
|
case SD_STATE_DIS:
|
||
|
default:
|
||
|
/* Invalid current state before selecting the card. */
|
||
|
return SDD_INVALID_STATE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return SDD_WAIT_TIMEOUT;
|
||
|
}
|