285 lines
12 KiB
C
285 lines
12 KiB
C
/*
|
|
* @brief LPC18xx/43xx SD/MMC card driver
|
|
*
|
|
* @note
|
|
* Copyright(C) NXP Semiconductors, 2012
|
|
* All rights reserved.
|
|
*
|
|
* @par
|
|
* Software that is described herein is for illustrative purposes only
|
|
* which provides customers with programming information regarding the
|
|
* LPC products. This software is supplied "AS IS" without any warranties of
|
|
* any kind, and NXP Semiconductors and its licensor disclaim any and
|
|
* all warranties, express or implied, including all implied warranties of
|
|
* merchantability, fitness for a particular purpose and non-infringement of
|
|
* intellectual property rights. NXP Semiconductors assumes no responsibility
|
|
* or liability for the use of the software, conveys no license or rights under any
|
|
* patent, copyright, mask work right, or any other intellectual property rights in
|
|
* or to any products. NXP Semiconductors reserves the right to make changes
|
|
* in the software without notification. NXP Semiconductors also makes no
|
|
* representation or warranty that such application will be suitable for the
|
|
* specified use without further testing or modification.
|
|
*
|
|
* @par
|
|
* Permission to use, copy, modify, and distribute this software and its
|
|
* documentation is hereby granted, under NXP Semiconductors' and its
|
|
* licensor's relevant copyrights in the software, without fee, provided that it
|
|
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
|
* copyright, permission, and disclaimer notice must appear in all copies of
|
|
* this code.
|
|
*/
|
|
|
|
#ifndef __SDIO_18XX_43XX_H_
|
|
#define __SDIO_18XX_43XX_H_
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/** @defgroup SDIO_18XX_43XX CHIP: LPC18xx/43xx SDIO Card driver
|
|
* @ingroup CHIP_18XX_43XX_Drivers
|
|
* @{
|
|
*/
|
|
|
|
/** @brief SDIO Driver events */
|
|
enum SDIO_EVENT
|
|
{
|
|
SDIO_START_COMMAND, /**! SDIO driver is about to start a command transfer */
|
|
SDIO_START_DATA, /**! SDIO driver is about to start a data transfer */
|
|
SDIO_WAIT_DELAY, /**! SDIO driver needs to wait for given milli seconds */
|
|
SDIO_WAIT_COMMAND, /**! SDIO driver is waiting for a command to complete */
|
|
SDIO_WAIT_DATA, /**! SDIO driver is waiting for data transfer to complete */
|
|
|
|
SDIO_CARD_DETECT, /**! SDIO driver has detected a card */
|
|
SDIO_CMD_ERR, /**! Error in command transfer */
|
|
SDIO_CMD_DONE, /**! Command transfer successful */
|
|
SDIO_DATA_ERR, /**! Data transfer error */
|
|
SDIO_DATA_DONE, /**! Data transfer successful */
|
|
SDIO_CARD_INT, /**! SDIO Card interrupt (from a function) */
|
|
};
|
|
|
|
/** @brief SDIO Command Responses */
|
|
#define SDIO_CMD_RESP_R1 (1UL << 6)
|
|
#define SDIO_CMD_RESP_R2 (3UL << 6)
|
|
#define SDIO_CMD_RESP_R3 (1UL << 6)
|
|
#define SDIO_CMD_RESP_R4 (1UL << 6)
|
|
#define SDIO_CMD_RESP_R5 (1UL << 6)
|
|
#define SDIO_CMD_RESP_R6 (1UL << 6)
|
|
|
|
/** @brief SDIO Command misc options */
|
|
#define SDIO_CMD_CRC (1UL << 8) /**! Response must have a valid CRC */
|
|
#define SDIO_CMD_DATA (1UL << 9) /**! Command is a data transfer command */
|
|
|
|
/** @brief List of commands */
|
|
#define CMD0 (0 | (1 << 15))
|
|
#define CMD5 (5 | SDIO_CMD_RESP_R4)
|
|
#define CMD3 (3 | SDIO_CMD_RESP_R6)
|
|
#define CMD7 (7 | SDIO_CMD_RESP_R1)
|
|
#define CMD52 (52 | SDIO_CMD_RESP_R5 | SDIO_CMD_CRC)
|
|
#define CMD53 (53 | SDIO_CMD_RESP_R5 | SDIO_CMD_DATA | SDIO_CMD_CRC)
|
|
|
|
/** @brief SDIO Error numbers */
|
|
#define SDIO_ERROR -1 /**! General SDIO Error */
|
|
#define SDIO_ERR_FNUM -2 /**! Error getting Number of functions supported */
|
|
#define SDIO_ERR_READWRITE -3 /**! Error when performing Read/write of data */
|
|
#define SDIO_ERR_VOLT -4 /**! Error Reading or setting up the voltage to 3v3 */
|
|
#define SDIO_ERR_RCA -5 /**! Error during RCA phase */
|
|
#define SDIO_ERR_INVFUNC -6 /**! Invalid function argument */
|
|
#define SDIO_ERR_INVARG -7 /**! Invalid argument supplied to function */
|
|
|
|
#define SDIO_VOLT_3_3 0x00100000UL /* for CMD5 */
|
|
|
|
/* SDIO Data transfer modes */
|
|
/** @brief Block mode transfer flag
|
|
*
|
|
* When this flag is specified in a transfer the data will be transfered in blocks if not
|
|
* it will be transfered in bytes. See SDIO_Card_DataRead(), SDIO_Card_DataWrite()
|
|
* for more information.
|
|
*/
|
|
#define SDIO_MODE_BLOCK (1UL << 27)
|
|
|
|
/** @brief Buffer mode transfer flag
|
|
*
|
|
* Default mode for SDIO_Card_ReadData() and SDIO_Card_WriteData() is FIFO mode
|
|
* in FIFO mode all the given data will be written to or read from the same
|
|
* register address in the function. This flag will set the transfers to BUFFER
|
|
* mode; in BUFFER mode read first byte will be read from the given source address
|
|
* and the next byte will be read from the next source address (i.e src_addr + 1),
|
|
* and so on, in BUFFER mode write first byte will be written to dest_addr, next
|
|
* byte will be written to dest_addr + 1 and so on.
|
|
*/
|
|
#define SDIO_MODE_BUFFER (1UL << 26)
|
|
|
|
/* ---- SDIO Internal map ---- */
|
|
#define SDIO_AREA_CIA 0 /* function 0 */
|
|
|
|
/* ---- Card Capability(0x08) register ---- */
|
|
#define SDIO_CCCR_LSC 0x40u /* card is low-speed cards */
|
|
#define SDIO_CCCR_4BLS 0x80u /* 4-bit support for low-speed cards */
|
|
|
|
#define SDIO_POWER_INIT 1
|
|
|
|
#define SDIO_CLK_HISPEED 33000000UL /* High-Speed Clock */
|
|
#define SDIO_CLK_FULLSPEED 16000000UL /* Full-Speed Clock */
|
|
#define SDIO_CLK_LOWSPEED 400000 /* Low-Speed Clock */
|
|
|
|
/**
|
|
* @brief Initialize the SDIO card
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @param freq : Initial frequency to use during the enumeration
|
|
* @return 0 on Success; > 0 on response error [like CRC error] < 0 on BUS error
|
|
*/
|
|
int SDIO_Card_Init(LPC_SDMMC_T *pSDMMC, uint32_t freq);
|
|
|
|
/**
|
|
* @brief Write 8-Bit register from SDIO register space
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @param func : function number [0 to 7] [0 = CIA function]
|
|
* @param addr : Address of the register to read
|
|
* @param data : 8-bit data be written
|
|
* @return 0 on Success; > 0 on response error [like CRC error] < 0 on BUS error
|
|
* @note SDIO_Setup_Callback() function must be called to setup the call backs before
|
|
* calling this API.
|
|
*/
|
|
int SDIO_Write_Direct(LPC_SDMMC_T *pSDMMC, uint32_t func, uint32_t addr, uint32_t data);
|
|
|
|
/**
|
|
* @brief Write 8-Bit register from SDIO register space and read the register back
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @param func : function number [0 to 7] [0 = CIA function]
|
|
* @param addr : Address of the register to read
|
|
* @param data : Pointer to memory where the 8-bit data be stored
|
|
* @return 0 on Success; > 0 on response error [like CRC error] < 0 on BUS error
|
|
* @note @a data must have the value to be written stored in it when the function is called
|
|
*/
|
|
int SDIO_WriteRead_Direct(LPC_SDMMC_T *pSDMMC, uint32_t func, uint32_t addr, uint32_t *data);
|
|
|
|
/**
|
|
* @brief Read an 8-Bit register from SDIO register space
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @param func : function number [0 to 7] [0 = CIA function]
|
|
* @param addr : Address of the register to read
|
|
* @param data : Pointer to memory where the 8-bit data be stored
|
|
* @return 0 on Success; > 0 on response error [like CRC error] < 0 on BUS error
|
|
*/
|
|
int SDIO_Read_Direct(LPC_SDMMC_T *pSDMMC, uint32_t func, uint32_t addr, uint32_t *data);
|
|
|
|
/**
|
|
* @brief Setup SDIO wait and wakeup callbacks
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @param wake_evt : Wakeup event call-back handler
|
|
* @param wait_evt : Wait event call-back handler
|
|
* @return Nothing
|
|
* @note @a wake_evt and @a wait_evt should always be non-null function pointers
|
|
* This function must be called before calling SDIO_Card_Init() function
|
|
*/
|
|
void SDIO_Setup_Callback(LPC_SDMMC_T *pSDMMC,
|
|
void (*wake_evt)(LPC_SDMMC_T *pSDMMC, uint32_t event, void *arg),
|
|
uint32_t (*wait_evt)(LPC_SDMMC_T *pSDMMC, uint32_t event, void *arg));
|
|
|
|
/**
|
|
* @brief SDIO Event handler [Should be called from SDIO interrupt handler]
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @return Nothing
|
|
*/
|
|
void SDIO_Handler(LPC_SDMMC_T *pSDMMC);
|
|
|
|
/**
|
|
* @brief Sends a command to the SDIO Card [Example CMD52]
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @param cmd : Command to be sent along with any flags
|
|
* @param arg : Argument for the command
|
|
* @return 0 on Success; Non-Zero on failure
|
|
*/
|
|
uint32_t SDIO_Send_Command(LPC_SDMMC_T *pSDMMC, uint32_t cmd, uint32_t arg);
|
|
|
|
/**
|
|
* @brief Gets the block size of a given function
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @param func : function number [0 to 7] [0 = CIA function]
|
|
* @return Block size of the given function
|
|
* @sa SDIO_Card_SetBlockSize()
|
|
* @note If the return value is 0 then bock size is not set using
|
|
* SDIO_Card_SetBlockSize(), or given @a func is not valid or the
|
|
* card does not support block data transfers.
|
|
*/
|
|
uint32_t SDIO_Card_GetBlockSize(LPC_SDMMC_T *pSDMMC, uint32_t func);
|
|
|
|
/**
|
|
* @brief Sets the block size of a given function
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @param func : function number [0 to 7] [0 = CIA function]
|
|
* @param blkSize : Block size to set
|
|
* @return 0 on success; Non-Zero on failure
|
|
* @sa SDIO_Card_GetBlockSize()
|
|
* @note After setting block size using this API, if
|
|
* SDIO_Card_GetBlockSize() returns 0 for a valid function then the card
|
|
* does not support block transfers.
|
|
*/
|
|
int SDIO_Card_SetBlockSize(LPC_SDMMC_T *pSDMMC, uint32_t func, uint32_t blkSize);
|
|
|
|
/**
|
|
* @brief Writes stream or block of data to the SDIO card [Using CMD53]
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @param func : function number [0 to 7] [0 = CIA function]
|
|
* @param dest_addr : Address where the data to be written (inside @a func register space)
|
|
* @param src_addr : Buffer from which data to be taken
|
|
* @param size : Number of Bytes/Blocks to be transfered [Must be in the range 1 to 512]
|
|
* @param flags : Or-ed value of #SDIO_MODE_BLOCK, #SDIO_MODE_BUFFER
|
|
* @return 0 on success; Non-Zero on failure
|
|
* @note When #SDIO_MODE_BLOCK is set in @a flags the size is number of blocks, so
|
|
* the number of bytes transferd will be @a size * "block size" [See SDIO_Card_GetBlockSize() and
|
|
* SDIO_Card_SetBlockSize() for more information]
|
|
*/
|
|
int SDIO_Card_WriteData(LPC_SDMMC_T *pSDMMC, uint32_t func,
|
|
uint32_t dest_addr, const uint8_t *src_addr,
|
|
uint32_t size, uint32_t flags);
|
|
|
|
/**
|
|
* @brief Reads stream or block of data from the SDIO card [Using CMD53]
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @param func : function number [0 to 7] [0 = CIA function]
|
|
* @param dest_addr : memory where the data to be read into
|
|
* @param src_addr : Register address from which data to be read (inside @a func register space)
|
|
* @param size : Number of Bytes/Blocks to be transfered [Must be in the range 1 to 512]
|
|
* @param flags : Or-ed value of #SDIO_MODE_BLOCK, #SDIO_MODE_BUFFER
|
|
* @return 0 on success; Non-Zero on failure
|
|
* @note When #SDIO_MODE_BLOCK is set in @a flags the size is number of blocks, so
|
|
* the number of bytes transferd will be @a size * "block size" [See SDIO_Card_GetBlockSize() and
|
|
* SDIO_Card_SetBlockSize() for more information]
|
|
*/
|
|
int SDIO_Card_ReadData(LPC_SDMMC_T *pSDMMC, uint32_t func,
|
|
uint8_t *dest_addr, uint32_t src_addr,
|
|
uint32_t size, uint32_t flags);
|
|
|
|
/**
|
|
* @brief Disable SDIO interrupt for a given function
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @param func : function number [0 to 7] [0 = CIA function]
|
|
* @return 0 - on success; Non zero on failure
|
|
*/
|
|
int SDIO_Card_DisableInt(LPC_SDMMC_T *pSDMMC, uint32_t func);
|
|
|
|
/**
|
|
* @brief Enable SDIO interrupt for a given function
|
|
* @param pSDMMC : SDMMC peripheral selected
|
|
* @param func : function number [0 to 7] [0 = CIA function]
|
|
* @return 0 - on success; Non zero on failure
|
|
*/
|
|
int SDIO_Card_EnableInt(LPC_SDMMC_T *pSDMMC, uint32_t func);
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __SDIO_18XX_43XX_H_ */
|
|
|
|
|
|
|
|
|
|
|
|
|