📄 pu_irom_sdhc_ip.c
字号:
/******************************************************************************* pu_irom_sdhc_ip.c**** Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.**** This file contains copyrighted material. Use of this file is** restricted by the provisions of a Freescale Software License** Agreement, which has either been electronically accepted by** you or has been expressly executed between the parties.**** Description: Explanation for the usage of this file.**** Revision History:** -----------------*****************************************************************************//*! * @file pu_irom_sdhc_ip.c * * @brief source code for the mmc card operation * * @ingroup mmc *///#define TY_DBG/*==================================================================================================== INCLUDE FILES==================================================================================================*/#include "Common.h"#include "MX31_def.h"#include "pu_irom_sdhc_ipp.h"#include "pu_irom_sdhc_ip.h"#ifdef TY_DBG/* Ty adds for debug */#include "stdio.h"#include "channel.h"#endif/*================================================================================================== Global Defines ==================================================================================================*/ /* Gloal pointer to SDHC register set */volatile psdhc_t psdhc;/*================================================================================================== MACROS==================================================================================================*/ /*================================================================================================== ENUMS==================================================================================================*//*================================================================================================== Static Functions ==================================================================================================*//*! * Configure SDHC registers for sending a command to MMC/SD. * @cmd * command_t * - a pointer to structure defining a command*/ static void sdhc_cmd_config(command_t *cmd) { /* Write command index */ psdhc->sdhc_cmd = cmd->command; /* Write command arg */ psdhc->sdhc_arg = cmd->arg; /* workaround for CMD0, send 80 clock cycles before CMD0 */ if (cmd->command == 0) { /* Set the type of transfer */ psdhc->sdhc_cmd_dat_cont = (((cmd->data_transfer) << SDHC_CMD_DATA_CTRL_WRITE_READ_SHIFT) | ((cmd->response_format) << SDHC_CMD_DATA_CTRL_FROMAT_OF_RESP_SHIFT) | ((cmd->data_present) << SDHC_CMD_DATA_CTRL_DATA_ENABLE_SHIFT) | ((SDHC_CMD_DATA_CTRL_BUS_WIDTH_1_BIT) << SDHC_CMD_DATA_CTRL_BUS_WIDTH_SHIFT) | (SDHC_CMD_DATA_CTRL_INIT) ); } else { psdhc->sdhc_cmd_dat_cont = (((cmd->data_transfer) << SDHC_CMD_DATA_CTRL_WRITE_READ_SHIFT) | ((cmd->response_format) << SDHC_CMD_DATA_CTRL_FROMAT_OF_RESP_SHIFT) | ((cmd->data_present) << SDHC_CMD_DATA_CTRL_DATA_ENABLE_SHIFT) | ((SDHC_CMD_DATA_CTRL_BUS_WIDTH_1_BIT) << SDHC_CMD_DATA_CTRL_BUS_WIDTH_SHIFT) ); } return; }/*! * Start the clock and wait until the clock is started.*/ static void sdhc_start_clk(void){ /* Start the clock */ psdhc->sdhc_str_stp_clk = SDHC_STR_STP_CLK_START; /* Wait till the clock has started, then the command * will begin transfering to the card */ while(!(psdhc->sdhc_status & SDHC_STATUS_CLK_RUN_MSK)); return;}/*! * Stop the clock and wait until the clock is stoped. */ static void sdhc_stop_clk(void ){ /* Stop MMC/SD clock */ psdhc->sdhc_str_stp_clk = SDHC_STR_STP_CLK_STOP; /* Wait until clock is stopped */ while((psdhc->sdhc_status & SDHC_STATUS_CLK_RUN_MSK));}/*! * Wait a END_CMD_RESP interrupt by polling status register. The fields * RESP_CRC_ERR (Status[5]) and TIME_OUT_RESP(STATUS[1]) are checked * to determine if an error has occurred. */ static void sdhc_wait_end_cmd_resp_intr(void){ /* Wait for end command response interrupt * This interrupt may raise when one of STATUS[1], * STATUS[5] or STATUS[13] are set. */ while(!(psdhc->sdhc_status & SDHC_STATUS_END_CMD_RESP_MSK));}/*! * Check whether the interrupt is an END_CMD_RESP * or a response time out or a CRC error. */ static U32 sdhc_check_response(void){ U32 sdhc_status = SDHC_STATUS_PASS; /* Check whether the interrupt is an END_CMD_RESP * or a time out or a CRC error */ if((psdhc->sdhc_status & SDHC_STATUS_END_CMD_RESP_MSK) && !(psdhc->sdhc_status & SDHC_STATUS_TIME_OUT_RESP_MSK) && !(psdhc->sdhc_status & SDHC_STATUS_RESP_CRC_ERR_MSK)) { sdhc_status = SDHC_STATUS_PASS; } else { sdhc_status = SDHC_STATUS_FAILURE; }#ifdef TY_DBG { // Terry adds for debug, :-) U8 au8StrBuf[100] = { 0 }; sprintf(au8StrBuf, "Ty, chk_resp: sdhc_status: %d, judge: %d result: %d\n", psdhc->sdhc_status, ((psdhc->sdhc_status & SDHC_STATUS_END_CMD_RESP_MSK) && !(psdhc->sdhc_status & SDHC_STATUS_TIME_OUT_RESP_MSK) && !(psdhc->sdhc_status & SDHC_STATUS_RESP_CRC_ERR_MSK)), sdhc_status); atk_channel_send(au8StrBuf, sizeof(au8StrBuf)); memset(au8StrBuf, 0, 100); sprintf(au8StrBuf, "Ty, 1:%d 2:%d 3:%d", psdhc->sdhc_status & SDHC_STATUS_END_CMD_RESP_MSK, psdhc->sdhc_status & SDHC_STATUS_TIME_OUT_RESP_MSK, psdhc->sdhc_status & SDHC_STATUS_RESP_CRC_ERR_MSK); atk_channel_send(au8StrBuf, sizeof(au8StrBuf)); }#endif return sdhc_status;}/*! * Set SDHC_BLK_LEN and SDHC_NOB registers. * @blk_len U32 - the length of the block to be transfered * @nob U32 - the number of blocks to be transfered */ void interface_config_block_info(U32 blk_len, U32 nob){ psdhc->sdhc_blk_len = blk_len; psdhc->sdhc_nob = nob;}/*! * Wait a BUF_READ_READY or BUF_WRITE_READY interrupt by polling STATUS register. * @mask U32 - an integer defining the mask to be applied on the STATUS register */ static void sdhc_wait_buf_rdy_intr(U32 mask){ if((mask == SDHC_STATUS_BUF_READ_RDY_MSK) || (mask == SDHC_STATUS_BUF_WRITE_RDY_MSK)) { /* Wait for interrupt (BUF_READ_RDY/BUF_WRITE_RDY) */ while(!(psdhc->sdhc_status & mask)); } }/*! * Wait a WRITE_OP_DONE or a READ_OP_DONE by pooling STAUTUS register. * @op_done_mask U32 - an integer defining the mask to be applied on the STATUS register */ static void sdhc_wait_op_done_intr(U32 op_done_mask){ if((op_done_mask == SDHC_STATUS_READ_OP_DONE_MSK) || (op_done_mask == SDHC_STATUS_WRITE_OP_DONE_MSK)) { /* Wait interrupt (WRITE_OP_DONE/READ_OP_DONE) */ while(!(psdhc->sdhc_status & op_done_mask)); } }/*! * If WRITE_OP_DONE/READ_OP_DONE occured check WR_CRC_ERR_CODE/RD_CRC_ERR_CODE * and WRITE_CRC_ERR/READ_CRC_ERR to determine if an error occured * @op_done_mask U32 - an integer defining the WRITE_OP_DONE/READ_OP_DONE mask to be applied on the STATUS register * @crc_err_code_mask U32 - an integer defining the WR_CRC_ERR_CODE/RD_CRC_ERR_CODE mask * to be applied on the STATUS register * @crc_err_mask U32 - an integer defining the WRITE_CRC_ERR/READ_CRC_ERR mask * to be applied on the STATUS register * @return UINT32 */ static U32 sdhc_check_data(U32 op_done_mask, U32 crc_err_code_mask, U32 crc_err_mask){ U32 sdhc_status = SDHC_STATUS_FAILURE; /* Check whether the interrupt is an OP_DONE * or a data time out or a CRC error */ if((psdhc->sdhc_status & op_done_mask) && !(psdhc->sdhc_status & crc_err_code_mask) && !(psdhc->sdhc_status & crc_err_mask)) { sdhc_status = SDHC_STATUS_PASS; } else { sdhc_status = SDHC_STATUS_FAILURE; } return sdhc_status;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -