2223 lines
94 KiB
C
2223 lines
94 KiB
C
/*******************************************************************************
|
|
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
|
|
*
|
|
* This software component is licensed by HDSC under BSD 3-Clause license
|
|
* (the "License"); You may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at:
|
|
* opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
/******************************************************************************/
|
|
/** \file hc32f460_sdioc.c
|
|
**
|
|
** A detailed description is available at
|
|
** @link SdiocGroup SDIOC description @endlink
|
|
**
|
|
** - 2018-11-11 CDT First version for Device Driver Library of SDIOC.
|
|
**
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Include files
|
|
******************************************************************************/
|
|
#include "hc32f460_sdioc.h"
|
|
#include "hc32f460_utility.h"
|
|
|
|
#if (DDL_SDIOC_ENABLE == DDL_ON)
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \addtogroup SdiocGroup
|
|
******************************************************************************/
|
|
//@{
|
|
|
|
/*******************************************************************************
|
|
* Local type definitions ('typedef')
|
|
******************************************************************************/
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief SDIOC internal data
|
|
**
|
|
******************************************************************************/
|
|
typedef struct stc_sdioc_intern_data
|
|
{
|
|
stc_sdioc_normal_irq_cb_t stcNormalIrqCb; ///< Normal irq callback function structure
|
|
|
|
stc_sdioc_error_irq_cb_t stcErrorIrqCb; ///< Error irq callback function structure
|
|
} stc_sdioc_intern_data_t;
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief SDIOC instance data
|
|
**
|
|
******************************************************************************/
|
|
typedef struct stc_sdioc_instance_data
|
|
{
|
|
const M4_SDIOC_TypeDef *SDIOCx; ///< pointer to registers of an instance
|
|
|
|
stc_sdioc_intern_data_t stcInternData; ///< module internal data of instance
|
|
} stc_sdioc_instance_data_t;
|
|
|
|
/*******************************************************************************
|
|
* Local pre-processor symbols/macros ('#define')
|
|
******************************************************************************/
|
|
|
|
/*!< Parameter valid check for SDIOC Instances. */
|
|
#define IS_VALID_SDIOC(__SDIOCx__) \
|
|
( (M4_SDIOC1 == (__SDIOCx__)) || \
|
|
(M4_SDIOC2 == (__SDIOCx__)))
|
|
|
|
/*!< Parameter valid check for SDIOC mode. */
|
|
#define IS_VALID_SDIOC_MODE(x) \
|
|
( (SdiocModeSD == (x)) || \
|
|
(SdiocModeMMC == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC Response Register. */
|
|
#define IS_VALID_SDIOC_RESP(x) \
|
|
( (SdiocRegResp01 == (x)) || \
|
|
(SdiocRegResp23 == (x)) || \
|
|
(SdiocRegResp45 == (x)) || \
|
|
(SdiocRegResp67 == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC bus width. */
|
|
#define IS_VALID_SDIOC_BUS_WIDTH(x) \
|
|
( (SdiocBusWidth1Bit == (x)) || \
|
|
(SdiocBusWidth4Bit == (x)) || \
|
|
(SdiocBusWidth8Bit == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC speed mode. */
|
|
#define IS_VALID_SDIOC_SPEED_MODE(x) \
|
|
( (SdiocHighSpeedMode == (x)) || \
|
|
(SdiocNormalSpeedMode == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC Clock division. */
|
|
#define IS_VALID_SDIOC_CLK_DIV(x) \
|
|
( (SdiocClkDiv_1 == (x)) || \
|
|
(SdiocClkDiv_2 == (x)) || \
|
|
(SdiocClkDiv_4 == (x)) || \
|
|
(SdiocClkDiv_8 == (x)) || \
|
|
(SdiocClkDiv_16 == (x)) || \
|
|
(SdiocClkDiv_32 == (x)) || \
|
|
(SdiocClkDiv_64 == (x)) || \
|
|
(SdiocClkDiv_128 == (x)) || \
|
|
(SdiocClkDiv_256 == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC command type. */
|
|
#define IS_VALID_SDIOC_CMD_TYPE(x) \
|
|
( (SdiocCmdAbort == (x)) || \
|
|
(SdiocCmdResume == (x)) || \
|
|
(SdiocCmdNormal == (x)) || \
|
|
(SdiocCmdSuspend == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC data transfer direction. */
|
|
#define IS_VALID_SDIOC_TRANSFER_DIR(x) \
|
|
( (SdiocTransferToCard == (x)) || \
|
|
(SdiocTransferToHost == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC software reset type. */
|
|
#define IS_VALID_SDIOC_SWRESETTYPE(x) \
|
|
( (SdiocSwResetAll == (x)) || \
|
|
(SdiocSwResetCmdLine == (x)) || \
|
|
(SdiocSwResetDatLine == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC data transfer mode. */
|
|
#define IS_VALID_SDIOC_TRANSFER_MODE(x) \
|
|
( (SdiocTransferSingle == (x)) || \
|
|
(SdiocTransferInfinite == (x)) || \
|
|
(SdiocTransferMultiple == (x)) || \
|
|
(SdiocTransferStopMultiple == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC data timeout. */
|
|
#define IS_VALID_SDIOC_DATA_TIMEOUT(x) \
|
|
( (SdiocDtoSdclk_2_13 == (x)) || \
|
|
(SdiocDtoSdclk_2_14 == (x)) || \
|
|
(SdiocDtoSdclk_2_15 == (x)) || \
|
|
(SdiocDtoSdclk_2_16 == (x)) || \
|
|
(SdiocDtoSdclk_2_17 == (x)) || \
|
|
(SdiocDtoSdclk_2_18 == (x)) || \
|
|
(SdiocDtoSdclk_2_19 == (x)) || \
|
|
(SdiocDtoSdclk_2_20 == (x)) || \
|
|
(SdiocDtoSdclk_2_21 == (x)) || \
|
|
(SdiocDtoSdclk_2_22 == (x)) || \
|
|
(SdiocDtoSdclk_2_23 == (x)) || \
|
|
(SdiocDtoSdclk_2_24 == (x)) || \
|
|
(SdiocDtoSdclk_2_25 == (x)) || \
|
|
(SdiocDtoSdclk_2_26 == (x)) || \
|
|
(SdiocDtoSdclk_2_27 == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC Response type name. */
|
|
#define IS_VALID_SDIOC_RESP_TYPE_NAME(x) \
|
|
( (SdiocCmdRspR1 == (x)) || \
|
|
(SdiocCmdRspR1b == (x)) || \
|
|
(SdiocCmdRspR2 == (x)) || \
|
|
(SdiocCmdRspR3 == (x)) || \
|
|
(SdiocCmdRspR4 == (x)) || \
|
|
(SdiocCmdRspR5 == (x)) || \
|
|
(SdiocCmdRspR5b == (x)) || \
|
|
(SdiocCmdRspR6 == (x)) || \
|
|
(SdiocCmdRspR7 == (x)) || \
|
|
(SdiocCmdNoRsp == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC data timeout. */
|
|
#define IS_VALID_SDIOC_HOST_STATUS(x) \
|
|
( (SdiocCmdPinLvl == (x)) || \
|
|
(SdiocData0PinLvl == (x)) || \
|
|
(SdiocData1PinLvl == (x)) || \
|
|
(SdiocData2PinLvl == (x)) || \
|
|
(SdiocData3PinLvl == (x)) || \
|
|
(SdiocCardInserted == (x)) || \
|
|
(SdiocDataLineActive == (x)) || \
|
|
(SdiocCardStateStable == (x)) || \
|
|
(SdiocBufferReadEnble == (x)) || \
|
|
(SdiocBufferWriteEnble == (x)) || \
|
|
(SdiocCardDetectPinLvl == (x)) || \
|
|
(SdiocCommandInhibitCmd == (x)) || \
|
|
(SdiocWriteProtectPinLvl == (x)) || \
|
|
(SdiocCommandInhibitData == (x)) || \
|
|
(SdiocReadTransferActive == (x)) || \
|
|
(SdiocWriteTransferActive == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC normal interrupt. */
|
|
#define IS_VALID_SDIOC_NOR_INT(x) \
|
|
( (SdiocCardInt == (x)) || \
|
|
(SdiocErrorInt == (x)) || \
|
|
(SdiocCardRemoval == (x)) || \
|
|
(SdiocBlockGapEvent == (x)) || \
|
|
(SdiocCardInsertedInt == (x)) || \
|
|
(SdiocCommandComplete == (x)) || \
|
|
(SdiocBufferReadReady == (x)) || \
|
|
(SdiocBufferWriteReady == (x)) || \
|
|
(SdiocTransferComplete == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC error interrupt. */
|
|
#define IS_VALID_SDIOC_ERR_INT(x) \
|
|
( (SdiocCmdCrcErr == (x)) || \
|
|
(SdiocDataCrcErr == (x)) || \
|
|
(SdiocCmdIndexErr == (x)) || \
|
|
(SdiocCmdEndBitErr == (x)) || \
|
|
(SdiocAutoCmd12Err == (x)) || \
|
|
(SdiocCmdTimeoutErr == (x)) || \
|
|
(SdiocDataEndBitErr == (x)) || \
|
|
(SdiocDataTimeoutErr == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC auto CMD12 error status. */
|
|
#define IS_VALID_SDIOC_AUTOCMD_ERR(x) \
|
|
( (SdiocCmdNotIssuedErr == (x)) || \
|
|
(SdiocAutoCmd12CrcErr == (x)) || \
|
|
(SdiocAutoCmd12Timeout == (x)) || \
|
|
(SdiocAutoCmd12IndexErr == (x)) || \
|
|
(SdiocAutoCmd12EndBitErr == (x)) || \
|
|
(SdiocAutoCmd12NotExecuted == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC detect card signal. */
|
|
#define IS_VALID_SDIOC_DETECT_SIG(x) \
|
|
( (SdiocSdcdPinLevel == (x)) || \
|
|
(SdiocCardDetectTestLevel == (x)))
|
|
|
|
/*!< Parameter valid check for SDIOC data block count value. */
|
|
#define IS_VALID_SDIOC_BLKCNT(x) ((x) != 0u)
|
|
|
|
/*!< Parameter valid check for SDIOC data block size value. */
|
|
#define IS_VALID_SDIOC_BLKSIZE(x) (!((x) & 0xF000ul))
|
|
|
|
/*!< Parameter valid check for SDIOC command value. */
|
|
#define IS_VALID_SDIOC_CMD_VAL(x) (!(0xC0u & (x)))
|
|
|
|
/*!< Parameter valid check for buffer address. */
|
|
#define IS_VALID_TRANSFER_BUF_ALIGN(x) (!((SDIOC_BUF_ALIGN_SIZE-1ul) & ((uint32_t)(x))))
|
|
|
|
/*!< Parameter valid check for SDIOC command value. */
|
|
#define IS_VALID_TRANSFER_BUF_LEN(x) (!((SDIOC_BUF_ALIGN_SIZE-1ul) & ((uint32_t)(x))))
|
|
|
|
/*!< SDIOC unit max count value. */
|
|
#define SDIOC_UNIT_MAX_CNT (ARRAY_SZ(m_astcSdiocInstanceDataLut))
|
|
|
|
/*!< SDIOC default sdclk frequency. */
|
|
#define SDIOC_SDCLK_400K (400000ul)
|
|
|
|
/*!< Get the specified register address of the specified SDIOC unit */
|
|
#define SDIOC_ARG01(__SDIOCx__) ((uint32_t)(&((__SDIOCx__)->ARG0)))
|
|
#define SDIOC_BUF01(__SDIOCx__) ((uint32_t)(&((__SDIOCx__)->BUF0)))
|
|
#define SDIOC_RESPx(__SDIOCx__, RESP_REG) ((uint32_t)(&((__SDIOCx__)->RESP0)) + (uint32_t)(RESP_REG))
|
|
|
|
/* SDIOC buffer align size */
|
|
#define SDIOC_BUF_ALIGN_SIZE (4ul)
|
|
|
|
/*******************************************************************************
|
|
* Global variable definitions (declared in header file with 'extern')
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Local function prototypes ('static')
|
|
******************************************************************************/
|
|
static en_sdioc_clk_div_t SdiocGetClkDiv(uint32_t u32Exclk,
|
|
uint32_t u32SdiocClkFreq);
|
|
static stc_sdioc_intern_data_t* SdiocGetInternDataPtr(const M4_SDIOC_TypeDef *SDIOCx);
|
|
|
|
/*******************************************************************************
|
|
* Local variable definitions ('static')
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Function implementation - global ('extern') and local ('static')
|
|
******************************************************************************/
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Get SDIOC clock division.
|
|
**
|
|
** \param [in] u32Exclk Exclk frequency
|
|
** \param [in] u32ClkFreq SDIOC clock frequency
|
|
**
|
|
** \retval SdiocClkDiv_1 EXCLK/1
|
|
** \retval SdiocClkDiv_2 EXCLK/2
|
|
** \retval SdiocClkDiv_4 EXCLK/4
|
|
** \retval SdiocClkDiv_8 EXCLK/8
|
|
** \retval SdiocClkDiv_16 EXCLK/16
|
|
** \retval SdiocClkDiv_32 EXCLK/32
|
|
** \retval SdiocClkDiv_64 EXCLK/64
|
|
** \retval SdiocClkDiv_128 EXCLK/128
|
|
** \retval SdiocClkDiv_256 EXCLK/256
|
|
**
|
|
******************************************************************************/
|
|
static en_sdioc_clk_div_t SdiocGetClkDiv(uint32_t u32Exclk,
|
|
uint32_t u32ClkFreq)
|
|
{
|
|
uint32_t u32SdClkDiv = 0ul;
|
|
en_sdioc_clk_div_t enClockDiv = SdiocClkDiv_256;
|
|
|
|
if(0ul != u32ClkFreq)
|
|
{
|
|
u32SdClkDiv = u32Exclk / u32ClkFreq;
|
|
if (u32Exclk % u32ClkFreq)
|
|
{
|
|
u32SdClkDiv++;
|
|
}
|
|
|
|
if ((128ul < u32SdClkDiv) && (u32SdClkDiv <= 256ul))
|
|
{
|
|
enClockDiv = SdiocClkDiv_256;
|
|
}
|
|
else if ((64ul < u32SdClkDiv) && (u32SdClkDiv <= 128ul))
|
|
{
|
|
enClockDiv = SdiocClkDiv_128;
|
|
}
|
|
else if ((32ul < u32SdClkDiv) && (u32SdClkDiv <= 64ul))
|
|
{
|
|
enClockDiv = SdiocClkDiv_64;
|
|
}
|
|
else if ((16ul < u32SdClkDiv) && (u32SdClkDiv <= 32ul))
|
|
{
|
|
enClockDiv = SdiocClkDiv_32;
|
|
}
|
|
else if ((16ul < u32SdClkDiv) && (u32SdClkDiv <= 32ul))
|
|
{
|
|
enClockDiv = SdiocClkDiv_32;
|
|
}
|
|
else if ((8ul < u32SdClkDiv) && (u32SdClkDiv <= 16ul))
|
|
{
|
|
enClockDiv = SdiocClkDiv_16;
|
|
}
|
|
else if ((4ul < u32SdClkDiv) && (u32SdClkDiv <= 8ul))
|
|
{
|
|
enClockDiv = SdiocClkDiv_8;
|
|
}
|
|
else if ((2ul < u32SdClkDiv) && (u32SdClkDiv <= 4ul))
|
|
{
|
|
enClockDiv = SdiocClkDiv_4;
|
|
}
|
|
else if ((1ul < u32SdClkDiv) && (u32SdClkDiv <= 2ul))
|
|
{
|
|
enClockDiv = SdiocClkDiv_2;
|
|
}
|
|
else
|
|
{
|
|
enClockDiv = SdiocClkDiv_1;
|
|
}
|
|
}
|
|
|
|
return enClockDiv;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Return the internal data for a certain SDIOC instance.
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
**
|
|
** \retval Pointer to internal data or NULL if instance is not enabled (or not known)
|
|
**
|
|
******************************************************************************/
|
|
static stc_sdioc_intern_data_t* SdiocGetInternDataPtr(const M4_SDIOC_TypeDef *SDIOCx)
|
|
{
|
|
uint8_t i;
|
|
stc_sdioc_intern_data_t *pstcInternData = NULL;
|
|
static stc_sdioc_instance_data_t m_astcSdiocInstanceDataLut[2];
|
|
|
|
m_astcSdiocInstanceDataLut[0].SDIOCx = M4_SDIOC1;
|
|
m_astcSdiocInstanceDataLut[1].SDIOCx = M4_SDIOC2;
|
|
|
|
if (NULL != SDIOCx)
|
|
{
|
|
for (i = 0u; i < SDIOC_UNIT_MAX_CNT; i++)
|
|
{
|
|
if (SDIOCx == m_astcSdiocInstanceDataLut[i].SDIOCx)
|
|
{
|
|
pstcInternData = &m_astcSdiocInstanceDataLut[i].stcInternData;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return pstcInternData;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief SDIOC instance interrupt service routine
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
**
|
|
** \retval None
|
|
**
|
|
******************************************************************************/
|
|
void SDIOC_IrqHandler(M4_SDIOC_TypeDef *SDIOCx)
|
|
{
|
|
stc_sdioc_intern_data_t *pstcSdiocInternData = SdiocGetInternDataPtr(SDIOCx);
|
|
|
|
/* Check for NULL pointer */
|
|
if (NULL != pstcSdiocInternData)
|
|
{
|
|
/**************** Normal interrupt handler ****************/
|
|
if (1u == SDIOCx->NORINTST_f.CC) /* Command complete */
|
|
{
|
|
SDIOCx->NORINTST_f.CC = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnCommandCompleteIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnCommandCompleteIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->NORINTST_f.TC) /* Transfer complete */
|
|
{
|
|
SDIOCx->NORINTST_f.TC = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnTransferCompleteIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnTransferCompleteIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->NORINTST_f.BGE) /* Block gap event */
|
|
{
|
|
SDIOCx->NORINTST_f.BGE = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnBlockGapIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnBlockGapIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->NORINTST_f.BWR) /* Buffer write ready */
|
|
{
|
|
SDIOCx->NORINTST_f.BWR = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnBufferWriteReadyIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnBufferWriteReadyIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->NORINTST_f.BRR) /* Buffer read ready */
|
|
{
|
|
SDIOCx->NORINTST_f.BRR = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnBufferReadReadyIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnBufferReadReadyIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->NORINTST_f.CIST) /* Card insertion */
|
|
{
|
|
SDIOCx->NORINTST_f.CIST = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnCardInsertIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnCardInsertIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->NORINTST_f.CRM) /* Card removal */
|
|
{
|
|
SDIOCx->NORINTST_f.CRM = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnCardRemovalIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnCardRemovalIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->NORINTST_f.CINT) /* Card interrupt */
|
|
{
|
|
SDIOCx->NORINTST_f.CINT = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcNormalIrqCb.pfnCardIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnCardIrqCb();
|
|
}
|
|
}
|
|
|
|
/**************** Error interrupt handler ****************/
|
|
if (1u == SDIOCx->ERRINTST_f.CTOE) /* Command timeout error */
|
|
{
|
|
SDIOCx->ERRINTST_f.CTOE = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnCmdTimeoutErrIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnCmdTimeoutErrIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->ERRINTST_f.CCE) /* Command CRC error */
|
|
{
|
|
SDIOCx->ERRINTST_f.CCE = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnCmdCrcErrIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnCmdCrcErrIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->ERRINTST_f.CEBE) /* Command end bit error */
|
|
{
|
|
SDIOCx->ERRINTST_f.CEBE = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnCmdEndBitErrIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnCmdEndBitErrIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->ERRINTST_f.CIE) /* Command index error */
|
|
{
|
|
SDIOCx->ERRINTST_f.CIE = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnCmdIndexErrIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnCmdIndexErrIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->ERRINTST_f.DTOE) /* Data timeout error */
|
|
{
|
|
SDIOCx->ERRINTST_f.DTOE = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnDataTimeoutErrIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnDataTimeoutErrIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->ERRINTST_f.DEBE) /* Data end bit error */
|
|
{
|
|
SDIOCx->ERRINTST_f.DEBE = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnDataEndBitErrIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnDataEndBitErrIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->ERRINTST_f.DCE) /* Data CRC error */
|
|
{
|
|
SDIOCx->ERRINTST_f.DCE = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnDataCrcErrIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnDataCrcErrIrqCb();
|
|
}
|
|
}
|
|
|
|
if (1u == SDIOCx->ERRINTST_f.ACE) /* Auto CMD12 error */
|
|
{
|
|
SDIOCx->ERRINTST_f.ACE = 1u; /* Clear interrupt flag */
|
|
if (NULL != pstcSdiocInternData->stcErrorIrqCb.pfnAutoCmdErrIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnAutoCmdErrIrqCb();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Initializes a SDIOC.
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] pstcInitCfg Pointer to SDIOC configure structure
|
|
** \arg This parameter detail refer @ref stc_sdioc_init_t
|
|
**
|
|
** \retval Ok SDIOC initialized normally
|
|
** \retval ErrorTimeout SDIOCx reset timeout
|
|
** \retval ErrorInvalidParameter If one of following cases matches:
|
|
** - SDIOCx is invalid
|
|
** - pstcInitCfg == NULL
|
|
** - Other invalid configuration
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_Init(M4_SDIOC_TypeDef *SDIOCx,
|
|
const stc_sdioc_init_t *pstcInitCfg)
|
|
{
|
|
__IO uint32_t i = 0ul;
|
|
uint32_t u32Exclk = 0ul;
|
|
uint32_t u32Cnt = SystemCoreClock / 100ul;
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
stc_sdioc_intern_data_t *pstcSdiocInternData = NULL;
|
|
|
|
/* Get pointer to internal data structure. */
|
|
pstcSdiocInternData = SdiocGetInternDataPtr(SDIOCx);
|
|
if (NULL != pstcSdiocInternData) /* Check for instance available or not */
|
|
{
|
|
/* Reset all */
|
|
SDIOCx->SFTRST_f.RSTA = 1u;
|
|
while (0u != SDIOCx->SFTRST_f.RSTA) /* Wait until reset finish */
|
|
{
|
|
if (i++ > u32Cnt)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i < u32Cnt)
|
|
{
|
|
/* Get EXCLK frequency */
|
|
u32Exclk = SystemCoreClock / (1ul << M4_SYSREG->CMU_SCFGR_f.EXCKS);
|
|
|
|
SDIOCx->CLKCON_f.FS = SdiocGetClkDiv(u32Exclk, SdiocClk400K);
|
|
SDIOCx->CLKCON_f.CE = (uint16_t)1u;
|
|
SDIOCx->CLKCON_f.ICE = (uint16_t)1u;
|
|
SDIOCx->PWRCON_f.PWON = (uint8_t)1u; /* Power on */
|
|
|
|
/* Enable all status */
|
|
SDIOCx->ERRINTST = (uint16_t)0x017Fu; /* Clear Error interrupt status */
|
|
SDIOCx->ERRINTSTEN = (uint16_t)0x017Fu; /* Enable Error interrupt status */
|
|
SDIOCx->NORINTST = (uint16_t)0x00F7u; /* Clear Normal interrupt status */
|
|
SDIOCx->NORINTSTEN = (uint16_t)0x01F7u; /* Enable Normal interrupt status */
|
|
|
|
/* Enable normal interrupt signal */
|
|
if (NULL != pstcInitCfg)
|
|
{
|
|
if (NULL != pstcInitCfg->pstcNormalIrqEn)
|
|
{
|
|
SDIOCx->NORINTSGEN = pstcInitCfg->pstcNormalIrqEn->u16NormalIntsgEn;
|
|
}
|
|
|
|
/* Set normal interrupt callback functions */
|
|
if (NULL != pstcInitCfg->pstcNormalIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnCommandCompleteIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnCommandCompleteIrqCb;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnTransferCompleteIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnTransferCompleteIrqCb;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnBlockGapIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnBlockGapIrqCb;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnBufferWriteReadyIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnBufferWriteReadyIrqCb;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnBufferReadReadyIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnBufferReadReadyIrqCb;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnCardInsertIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnCardInsertIrqCb;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnCardRemovalIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnCardRemovalIrqCb;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnCardIrqCb = pstcInitCfg->pstcNormalIrqCb->pfnCardIrqCb;
|
|
}
|
|
|
|
/* Enable error interrupt signal */
|
|
if (NULL != pstcInitCfg->pstcErrorIrqEn)
|
|
{
|
|
SDIOCx->ERRINTSGEN = pstcInitCfg->pstcErrorIrqEn->u16ErrorIntsgEn;
|
|
}
|
|
|
|
/* Set error interrupt callback functions */
|
|
if (NULL != pstcInitCfg->pstcErrorIrqCb)
|
|
{
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnCmdTimeoutErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnCmdTimeoutErrIrqCb;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnCmdCrcErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnCmdCrcErrIrqCb;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnCmdEndBitErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnCmdEndBitErrIrqCb;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnCmdIndexErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnCmdIndexErrIrqCb;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnDataTimeoutErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnDataTimeoutErrIrqCb;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnDataEndBitErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnDataEndBitErrIrqCb;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnDataCrcErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnDataCrcErrIrqCb;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnAutoCmdErrIrqCb = pstcInitCfg->pstcErrorIrqCb->pfnAutoCmdErrIrqCb;
|
|
}
|
|
}
|
|
enRet = Ok;
|
|
}
|
|
else
|
|
{
|
|
enRet = ErrorTimeout;
|
|
}
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief De-Initializes the specified SDIOC unit.
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
**
|
|
** \retval Ok De-Initialize successfully.
|
|
** \retval ErrorTimeout SDIOCx reset timeout.
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid.
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_DeInit(M4_SDIOC_TypeDef *SDIOCx)
|
|
{
|
|
__IO uint32_t i = 0ul;
|
|
uint32_t u32Cnt = SystemCoreClock / 100ul;
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
stc_sdioc_intern_data_t *pstcSdiocInternData = NULL;
|
|
|
|
/* Get pointer to internal data structure. */
|
|
pstcSdiocInternData = SdiocGetInternDataPtr(SDIOCx);
|
|
if (NULL != pstcSdiocInternData) /* Check for instance available or not */
|
|
{
|
|
/* Reset all */
|
|
SDIOCx->SFTRST_f.RSTA = 1u;
|
|
while (0u != SDIOCx->SFTRST_f.RSTA) /* Wait until reset finish */
|
|
{
|
|
if (i++ > u32Cnt)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i < u32Cnt)
|
|
{
|
|
/* Set normal interrupt callback functions */
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnCommandCompleteIrqCb = NULL;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnTransferCompleteIrqCb = NULL;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnBlockGapIrqCb = NULL;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnBufferWriteReadyIrqCb = NULL;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnBufferReadReadyIrqCb = NULL;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnCardInsertIrqCb = NULL;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnCardRemovalIrqCb = NULL;
|
|
pstcSdiocInternData->stcNormalIrqCb.pfnCardIrqCb = NULL;
|
|
|
|
/* Set error interrupt callback functions */
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnCmdTimeoutErrIrqCb = NULL;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnCmdCrcErrIrqCb = NULL;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnCmdEndBitErrIrqCb = NULL;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnCmdIndexErrIrqCb = NULL;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnDataTimeoutErrIrqCb = NULL;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnDataEndBitErrIrqCb = NULL;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnDataCrcErrIrqCb = NULL;
|
|
pstcSdiocInternData->stcErrorIrqCb.pfnAutoCmdErrIrqCb = NULL;
|
|
enRet = Ok;
|
|
}
|
|
else
|
|
{
|
|
enRet = ErrorTimeout;
|
|
}
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
* @brief Set SDIOC mode.
|
|
* @param [in] SDIOCx Pointer to SDIOC instance register base
|
|
* This parameter can be one of the following values:
|
|
* @arg M4_SDIOC1: SDIOC unit 1 instance register base
|
|
* @arg M4_SDIOC2: SDIOC unit 2 instance register base
|
|
* @param [in] enMode SDIOCx mode
|
|
* @arg SdiocModeSD: SD mode
|
|
* @arg SdiocModeMMC: MMC mode
|
|
*/
|
|
void SDIOC_SetMode(const M4_SDIOC_TypeDef *SDIOCx, en_sdioc_mode_t enMode)
|
|
{
|
|
/* Check parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
|
|
DDL_ASSERT(IS_VALID_SDIOC_MODE(enMode));
|
|
|
|
if (M4_SDIOC1 == SDIOCx)
|
|
{
|
|
M4_PERIC->SDIOC_SYCTLREG_f.SELMMC1 = (uint32_t)enMode;
|
|
}
|
|
else
|
|
{
|
|
M4_PERIC->SDIOC_SYCTLREG_f.SELMMC2 = (uint32_t)enMode;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Send SD command
|
|
**
|
|
** This function sends command on CMD line
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] pstcCmdCfg Pointer to command transfer configuration structure.
|
|
** \arg This parameter detail refer @ref stc_sdioc_cmd_cfg_t
|
|
**
|
|
** \retval Ok Command sent normally
|
|
** \retval ErrorInvalidParameter If one of following cases matches:
|
|
** - SDIOCx is invalid
|
|
** - pstcCmdCfg == NULL
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_SendCommand(M4_SDIOC_TypeDef *SDIOCx,
|
|
const stc_sdioc_cmd_cfg_t *pstcCmdCfg)
|
|
{
|
|
uint32_t u32Addr;
|
|
stc_sdioc_cmd_field_t stcCmdField;
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for NULL pointer */
|
|
if ((IS_VALID_SDIOC(SDIOCx)) && (NULL != pstcCmdCfg))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_CMD_VAL(pstcCmdCfg->u8CmdIndex));
|
|
DDL_ASSERT(IS_VALID_SDIOC_CMD_TYPE(pstcCmdCfg->enCmdType));
|
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcCmdCfg->enDataPresentEnable));
|
|
DDL_ASSERT(IS_VALID_SDIOC_RESP_TYPE_NAME(pstcCmdCfg->enRspIndex));
|
|
|
|
enRet = Ok;
|
|
switch (pstcCmdCfg->enRspIndex)
|
|
{
|
|
case SdiocCmdNoRsp:
|
|
stcCmdField.RESTYP = SdiocResponseNoneBit;
|
|
stcCmdField.CCE = 0u;
|
|
stcCmdField.ICE = 0u;
|
|
break;
|
|
case SdiocCmdRspR2:
|
|
stcCmdField.RESTYP = SdiocResponse136Bit;
|
|
stcCmdField.CCE = 1u;
|
|
stcCmdField.ICE = 0u;
|
|
break;
|
|
case SdiocCmdRspR3:
|
|
case SdiocCmdRspR4:
|
|
stcCmdField.RESTYP = SdiocResponse48Bit;
|
|
stcCmdField.CCE = 0u;
|
|
stcCmdField.ICE = 0u;
|
|
break;
|
|
case SdiocCmdRspR1:
|
|
case SdiocCmdRspR5:
|
|
case SdiocCmdRspR6:
|
|
case SdiocCmdRspR7:
|
|
stcCmdField.RESTYP = SdiocResponse48Bit;
|
|
stcCmdField.CCE = 1u;
|
|
stcCmdField.ICE = 1u;
|
|
break;
|
|
case SdiocCmdRspR1b:
|
|
case SdiocCmdRspR5b:
|
|
stcCmdField.RESTYP = SdiocResponse48BitCheckBusy;
|
|
stcCmdField.CCE = 1u;
|
|
stcCmdField.ICE = 1u;
|
|
break;
|
|
default:
|
|
enRet = ErrorInvalidParameter;
|
|
break;
|
|
}
|
|
|
|
if (enRet == Ok)
|
|
{
|
|
stcCmdField.RESERVED2 = (uint16_t)0u;
|
|
stcCmdField.TYP = (uint16_t)pstcCmdCfg->enCmdType;
|
|
stcCmdField.IDX = (uint16_t)pstcCmdCfg->u8CmdIndex;
|
|
stcCmdField.DAT = (uint16_t)(pstcCmdCfg->enDataPresentEnable);
|
|
|
|
u32Addr = SDIOC_ARG01(SDIOCx);
|
|
*(__IO uint32_t *)u32Addr = pstcCmdCfg->u32Argument;
|
|
|
|
u32Addr = (uint32_t)&stcCmdField;
|
|
SDIOCx->CMD = *(uint16_t *)u32Addr;
|
|
}
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Get the response received from the card for the last command
|
|
**
|
|
** This function sends command on CMD line
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enRespReg Response Specifies the SDIOC response register.
|
|
** \arg SdiocRegResp01 Response0 and Response1 Register
|
|
** \arg SdiocRegResp23 Response2 and Response3 Register
|
|
** \arg SdiocRegResp45 Response4 and Response5 Register
|
|
** \arg SdiocRegResp67 Response6 and Response7 Register
|
|
**
|
|
** \retval The Corresponding response register value
|
|
**
|
|
******************************************************************************/
|
|
uint32_t SDIOC_GetResponse(const M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_response_reg_t enRespReg)
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
|
|
DDL_ASSERT(IS_VALID_SDIOC_RESP(enRespReg));
|
|
|
|
return *(__IO uint32_t *)SDIOC_RESPx(SDIOCx, enRespReg) ;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Read data from SDIOCx data buffer
|
|
**
|
|
** This function reads 32-bit data from data buffer
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] au8Data Buffer which will store SDIOC_BUFFER data
|
|
** \param [in] u32Len Data length
|
|
**
|
|
** \retval Ok Data is read normally
|
|
** \retval ErrorInvalidParameter If one of following cases matches:
|
|
** - SDIOCx is invalid
|
|
** - pu32Data == NULL
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_ReadBuffer(M4_SDIOC_TypeDef *SDIOCx,
|
|
uint8_t au8Data[],
|
|
uint32_t u32Len)
|
|
{
|
|
uint32_t i = 0ul;
|
|
uint32_t u32Temp = 0ul;;
|
|
__IO uint32_t *SDIO_BUF_REG = NULL;
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx && pu8Data pointer */
|
|
if ((NULL != au8Data) && \
|
|
(IS_VALID_SDIOC(SDIOCx)) && \
|
|
(IS_VALID_TRANSFER_BUF_LEN(u32Len)))
|
|
{
|
|
SDIO_BUF_REG = (__IO uint32_t *)SDIOC_BUF01(SDIOCx);
|
|
|
|
while (i < u32Len)
|
|
{
|
|
u32Temp = *SDIO_BUF_REG;
|
|
au8Data[i++] = (uint8_t)((u32Temp >> 0ul) & 0x000000FF);
|
|
au8Data[i++] = (uint8_t)((u32Temp >> 8ul) & 0x000000FF);
|
|
au8Data[i++] = (uint8_t)((u32Temp >> 16ul) & 0x000000FF);
|
|
au8Data[i++] = (uint8_t)((u32Temp >> 24ul) & 0x000000FF);
|
|
}
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Write data to SDIOCx data buffer
|
|
**
|
|
** This function writes 32-bit data to data buffer
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] au8Data Buffer which will be wrote to SDIOC_BUFFER
|
|
** \param [in] u32Len Data length
|
|
**
|
|
** \retval Ok Data is written normally
|
|
** \retval ErrorInvalidParameter If one of following cases matches:
|
|
** - SDIOCx is invalid
|
|
** - pu8Data == NULL
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_WriteBuffer(M4_SDIOC_TypeDef *SDIOCx,
|
|
uint8_t au8Data[],
|
|
uint32_t u32Len)
|
|
{
|
|
uint32_t i = 0ul;
|
|
uint32_t u32Temp = 0ul;
|
|
__IO uint32_t *SDIO_BUF_REG = NULL;
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx && pu8Data pointer */
|
|
if ((NULL != au8Data) && \
|
|
(IS_VALID_SDIOC(SDIOCx)) && \
|
|
(IS_VALID_TRANSFER_BUF_LEN(u32Len)))
|
|
{
|
|
SDIO_BUF_REG = (__IO uint32_t *)SDIOC_BUF01(SDIOCx);
|
|
|
|
while (i < u32Len)
|
|
{
|
|
u32Temp = (((uint32_t)au8Data[i++]) << 0ul) & 0x000000FFul;
|
|
u32Temp += (((uint32_t)au8Data[i++]) << 8ul) & 0x0000FF00ul;
|
|
u32Temp += (((uint32_t)au8Data[i++]) << 16ul) & 0x00FF0000ul;
|
|
u32Temp += (((uint32_t)au8Data[i++]) << 24ul) & 0xFF000000ul;
|
|
|
|
*SDIO_BUF_REG = u32Temp;
|
|
}
|
|
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Configure SDIOCx data parameters
|
|
**
|
|
** This function writes 32-bit data to data buffer
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] pstcDataCfg Pointer to SDIOC data transfer configuration structure
|
|
** \arg This parameter detail refer @ref stc_sdioc_data_cfg_t
|
|
**
|
|
** \retval Ok configure normally
|
|
** \retval ErrorInvalidParameter If one of following cases matches:
|
|
** - SDIOCx is invalid
|
|
** - pstcDataCfg == NULL
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_ConfigData(M4_SDIOC_TypeDef *SDIOCx,
|
|
const stc_sdioc_data_cfg_t *pstcDataCfg)
|
|
{
|
|
uint16_t u16BlkCnt = (uint16_t)0;
|
|
uint32_t u32Addr;
|
|
stc_sdioc_transmode_field_t stcTransModeField = {0};
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx && pstcDataCfg pointer */
|
|
if ((IS_VALID_SDIOC(SDIOCx)) && (NULL != pstcDataCfg))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_BLKCNT(pstcDataCfg->u16BlkCnt));
|
|
DDL_ASSERT(IS_VALID_SDIOC_BLKSIZE(pstcDataCfg->u16BlkSize));
|
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(pstcDataCfg->enAutoCmd12Enable));
|
|
DDL_ASSERT(IS_VALID_SDIOC_DATA_TIMEOUT(pstcDataCfg->enDataTimeOut));
|
|
DDL_ASSERT(IS_VALID_SDIOC_TRANSFER_DIR(pstcDataCfg->enTransferDir));
|
|
DDL_ASSERT(IS_VALID_SDIOC_TRANSFER_MODE(pstcDataCfg->enTransferMode));
|
|
|
|
enRet = Ok;
|
|
|
|
switch (pstcDataCfg->enTransferMode)
|
|
{
|
|
case SdiocTransferSingle:
|
|
stcTransModeField.MULB = 0u;
|
|
stcTransModeField.BCE = 0u;
|
|
break;
|
|
case SdiocTransferInfinite:
|
|
stcTransModeField.MULB = 1u;
|
|
stcTransModeField.BCE = 0u;
|
|
break;
|
|
case SdiocTransferMultiple:
|
|
u16BlkCnt = pstcDataCfg->u16BlkCnt;
|
|
stcTransModeField.MULB = 1u;
|
|
stcTransModeField.BCE = 1u;
|
|
break;
|
|
case SdiocTransferStopMultiple:
|
|
stcTransModeField.MULB = 1u;
|
|
stcTransModeField.BCE = 1u;
|
|
break;
|
|
default:
|
|
enRet = ErrorInvalidParameter;
|
|
break;
|
|
}
|
|
|
|
if (enRet == Ok)
|
|
{
|
|
stcTransModeField.RESERVED0 = (uint16_t)0u;
|
|
stcTransModeField.DDIR = (uint16_t)(pstcDataCfg->enTransferDir);
|
|
stcTransModeField.ATCEN = (uint16_t)(pstcDataCfg->enAutoCmd12Enable);
|
|
|
|
/* Set the SDIOC Data Transfer Timeout value */
|
|
SDIOCx->TOUTCON = (uint8_t)(pstcDataCfg->enDataTimeOut);
|
|
/* Set the SDIOC Block Count value */
|
|
SDIOCx->BLKCNT = u16BlkCnt;
|
|
/* Set the SDIOC Block Size value */
|
|
SDIOCx->BLKSIZE = pstcDataCfg->u16BlkSize;
|
|
/* Set the SDIOC Data Transfer Mode */
|
|
u32Addr = (uint32_t)&stcTransModeField;
|
|
SDIOCx->TRANSMODE = *(uint16_t *)u32Addr;
|
|
}
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Enable/Disable SDCLK output
|
|
**
|
|
** SD host drives SDCLK line.
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enCmd The SDCLK functional state command
|
|
** \arg Enable Enable SDCLK function
|
|
** \arg Disable Disable SDCLK function
|
|
**
|
|
** \retval Ok SDCLK output of SDIOCx enabled normally
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_SdclkCmd(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_functional_state_t enCmd)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
|
|
|
|
SDIOCx->CLKCON_f.CE = (uint16_t)(enCmd);
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Set the clock division of SD clock
|
|
**
|
|
** This function changes the SD clock division.
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enClkDiv SDIOC clock division value
|
|
** \arg SdiocClkDiv_1 EXCLK/1
|
|
** \arg SdiocClkDiv_2 EXCLK/2
|
|
** \arg SdiocClkDiv_4 EXCLK/4
|
|
** \arg SdiocClkDiv_8 EXCLK/8
|
|
** \arg SdiocClkDiv_16 EXCLK/16
|
|
** \arg SdiocClkDiv_32 EXCLK/32
|
|
** \arg SdiocClkDiv_64 EXCLK/64
|
|
** \arg SdiocClkDiv_128 EXCLK/128
|
|
** \arg SdiocClkDiv_256 EXCLK/256
|
|
**
|
|
** \retval Ok SDIOC clock division is changed normally
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_SetClkDiv(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_clk_div_t enClkDiv)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_CLK_DIV(enClkDiv));
|
|
|
|
/* Set clock division */
|
|
SDIOCx->CLKCON_f.FS = (uint16_t)enClkDiv;
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Get the clock division of SD clock
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
**
|
|
** \retval SdiocClkDiv_1 EXCLK/1
|
|
** \retval SdiocClkDiv_2 EXCLK/2
|
|
** \retval SdiocClkDiv_4 EXCLK/4
|
|
** \retval SdiocClkDiv_8 EXCLK/8
|
|
** \retval SdiocClkDiv_16 EXCLK/16
|
|
** \retval SdiocClkDiv_32 EXCLK/32
|
|
** \retval SdiocClkDiv_64 EXCLK/64
|
|
** \retval SdiocClkDiv_128 EXCLK/128
|
|
**
|
|
******************************************************************************/
|
|
en_sdioc_clk_div_t SDIOC_GetClkDiv(M4_SDIOC_TypeDef *SDIOCx)
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
|
|
|
|
return ((en_sdioc_clk_div_t)SDIOCx->CLKCON_f.FS);
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Get the clock division of SD clock
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] u32ClkFreq SDIOC clock frequency
|
|
**
|
|
** \retval Ok Set successfully.
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_SetClk(M4_SDIOC_TypeDef *SDIOCx, uint32_t u32ClkFreq)
|
|
{
|
|
uint32_t u32Exclk = 0ul;
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Get EXCLK frequency */
|
|
u32Exclk = SystemCoreClock / (1ul << M4_SYSREG->CMU_SCFGR_f.EXCKS);
|
|
|
|
SDIOCx->CLKCON_f.CE = (uint16_t)0u;
|
|
SDIOCx->CLKCON_f.FS = (uint16_t)SdiocGetClkDiv(u32Exclk, u32ClkFreq);
|
|
SDIOCx->CLKCON_f.CE = (uint16_t)1u;
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Set the bus width of SD Bus
|
|
**
|
|
** This function changes the SD bus width.
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enBusWidth Bus width
|
|
** \arg SdiocBusWidth1Bit The SDIOC bus width 1 bit
|
|
** \arg SdiocBusWidth4Bit The SDIOC bus width 4 bit
|
|
** \arg SdiocBusWidth8Bit The SDIOC bus width 8 bit
|
|
**
|
|
** \retval Ok Bus width is set normally
|
|
** \retval ErrorInvalidParameter If one of following conditions are met:
|
|
** - SDIOCx is invalid
|
|
** - enBusWidth is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_SetBusWidth(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_bus_width_t enBusWidth)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_BUS_WIDTH(enBusWidth));
|
|
|
|
enRet = Ok;
|
|
|
|
switch (enBusWidth)
|
|
{
|
|
case SdiocBusWidth1Bit:
|
|
SDIOCx->HOSTCON_f.EXDW = 0u;
|
|
SDIOCx->HOSTCON_f.DW = 0u;
|
|
break;
|
|
case SdiocBusWidth4Bit:
|
|
SDIOCx->HOSTCON_f.EXDW = 0u;
|
|
SDIOCx->HOSTCON_f.DW = 1u;
|
|
break;
|
|
case SdiocBusWidth8Bit:
|
|
SDIOCx->HOSTCON_f.EXDW = 1u;
|
|
break;
|
|
default:
|
|
enRet = ErrorInvalidParameter;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Get the bus width of SD Bus
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
**
|
|
** \retval SdiocBusWidth1Bit The SDIOC bus width 1 bit
|
|
** \retval SdiocBusWidth4Bit The SDIOC bus width 4 bit
|
|
** \retval SdiocBusWidth8Bit The SDIOC bus width 8 bit
|
|
**
|
|
******************************************************************************/
|
|
en_sdioc_bus_width_t SDIOC_GetBusWidth(M4_SDIOC_TypeDef *SDIOCx)
|
|
{
|
|
en_sdioc_bus_width_t enBusWidth = SdiocBusWidth4Bit;
|
|
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
|
|
|
|
if (0u == SDIOCx->HOSTCON_f.EXDW)
|
|
{
|
|
if (0u == SDIOCx->HOSTCON_f.DW)
|
|
{
|
|
enBusWidth = SdiocBusWidth1Bit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
enBusWidth = SdiocBusWidth8Bit;
|
|
}
|
|
|
|
return enBusWidth;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Set the bus speed mode of SD Bus
|
|
**
|
|
** This function changes the SD bus speed mode.
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enSpeedMode Speed mode
|
|
** \arg SdiocHighSpeedMode High speed mode
|
|
** \arg SdiocNormalSpeedMode Normal speed mode
|
|
**
|
|
** \retval Ok Bus speed is set normally
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_SetSpeedMode(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_speed_mode_t enSpeedMode)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_SPEED_MODE(enSpeedMode));
|
|
|
|
/* Set high speed mode */
|
|
SDIOCx->HOSTCON_f.HSEN = ((SdiocHighSpeedMode == enSpeedMode) ? 1u : 0u);
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Get the bus speed mode of SD Bus
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
**
|
|
** \retval SdiocHighSpeedMode High speed mode
|
|
** \retval SdiocNormalSpeedMode Normal speed mode
|
|
**
|
|
******************************************************************************/
|
|
en_sdioc_speed_mode_t SDIOC_GetSpeedMode(M4_SDIOC_TypeDef *SDIOCx)
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
|
|
|
|
return ((SDIOCx->HOSTCON_f.HSEN) ? SdiocHighSpeedMode : SdiocNormalSpeedMode);
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Set data timeout counter value
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enTimeout Data timeout count value
|
|
** \arg SdiocDtoSdclk_2_13 Timeout time: SDCLK*2^13
|
|
** \arg SdiocDtoSdclk_2_14 Timeout time: SDCLK*2^14
|
|
** \arg SdiocDtoSdclk_2_15 Timeout time: SDCLK*2^15
|
|
** \arg SdiocDtoSdclk_2_16 Timeout time: SDCLK*2^16
|
|
** \arg SdiocDtoSdclk_2_17 Timeout time: SDCLK*2^17
|
|
** \arg SdiocDtoSdclk_2_18 Timeout time: SDCLK*2^18
|
|
** \arg SdiocDtoSdclk_2_19 Timeout time: SDCLK*2^19
|
|
** \arg SdiocDtoSdclk_2_20 Timeout time: SDCLK*2^20
|
|
** \arg SdiocDtoSdclk_2_21 Timeout time: SDCLK*2^21
|
|
** \arg SdiocDtoSdclk_2_22 Timeout time: SDCLK*2^22
|
|
** \arg SdiocDtoSdclk_2_23 Timeout time: SDCLK*2^23
|
|
** \arg SdiocDtoSdclk_2_24 Timeout time: SDCLK*2^24
|
|
** \arg SdiocDtoSdclk_2_25 Timeout time: SDCLK*2^25
|
|
** \arg SdiocDtoSdclk_2_26 Timeout time: SDCLK*2^26
|
|
** \arg SdiocDtoSdclk_2_27 Timeout time: SDCLK*2^27
|
|
**
|
|
** \retval Ok Bus speed is set normally
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_SetDataTimeout(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_data_timeout_t enTimeout)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_DATA_TIMEOUT(enTimeout));
|
|
|
|
/* Set data timeout */
|
|
SDIOCx->TOUTCON_f.DTO = (uint8_t)enTimeout;
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Get data timeout counter value
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
**
|
|
** \retval SdiocDtoSdclk_2_13 Timeout time: SDCLK*2^13
|
|
** \retval SdiocDtoSdclk_2_14 Timeout time: SDCLK*2^14
|
|
** \retval SdiocDtoSdclk_2_15 Timeout time: SDCLK*2^15
|
|
** \retval SdiocDtoSdclk_2_16 Timeout time: SDCLK*2^16
|
|
** \retval SdiocDtoSdclk_2_17 Timeout time: SDCLK*2^17
|
|
** \retval SdiocDtoSdclk_2_18 Timeout time: SDCLK*2^18
|
|
** \retval SdiocDtoSdclk_2_19 Timeout time: SDCLK*2^19
|
|
** \retval SdiocDtoSdclk_2_20 Timeout time: SDCLK*2^20
|
|
** \retval SdiocDtoSdclk_2_21 Timeout time: SDCLK*2^21
|
|
** \retval SdiocDtoSdclk_2_22 Timeout time: SDCLK*2^22
|
|
** \retval SdiocDtoSdclk_2_23 Timeout time: SDCLK*2^23
|
|
** \retval SdiocDtoSdclk_2_24 Timeout time: SDCLK*2^24
|
|
** \retval SdiocDtoSdclk_2_25 Timeout time: SDCLK*2^25
|
|
** \retval SdiocDtoSdclk_2_26 Timeout time: SDCLK*2^26
|
|
** \retval SdiocDtoSdclk_2_27 Timeout time: SDCLK*2^27
|
|
**
|
|
******************************************************************************/
|
|
en_sdioc_data_timeout_t SDIOC_GetDataTimeout(M4_SDIOC_TypeDef *SDIOCx)
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
|
|
|
|
return (en_sdioc_data_timeout_t)(SDIOCx->TOUTCON_f.DTO);
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Set the card detect signal
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enDetectSignal Card detect signal
|
|
** \arg SdiocSdcdPinLevel SDCD# is selected (for normal use)
|
|
** \arg SdiocCardDetectTestLevel The Card Detect Test Level is selected(for test purpose)
|
|
**
|
|
** \retval Ok Set normally
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_SetCardDetectSignal(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_detect_signal_t enDetectSignal)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_DETECT_SIG(enDetectSignal));
|
|
SDIOCx->HOSTCON_f.CDSS = (uint8_t)enDetectSignal;
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Get card inserted or not.
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
**
|
|
** \retval Set Card Inserted
|
|
** \retval Reset No Card
|
|
**
|
|
** \note This bit is enabled while the Card Detect Signal Selection is set to 1
|
|
** and it indicates card inserted or not.
|
|
**
|
|
******************************************************************************/
|
|
en_flag_status_t SDIOC_GetCardDetectTestLevel(M4_SDIOC_TypeDef *SDIOCx)
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
|
|
|
|
return (en_flag_status_t)(SDIOCx->HOSTCON_f.CDTL);
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Power on SD bus power
|
|
**
|
|
** This function starts power supply on SD bus
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
**
|
|
** \retval Ok Power on normally
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_BusPowerOn(M4_SDIOC_TypeDef *SDIOCx)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
SDIOCx->PWRCON_f.PWON = 1u;
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Power off SD bus power
|
|
**
|
|
** This function stops power supply on SD bus
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
**
|
|
** \retval Ok Power off normally
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_BusPowerOff(M4_SDIOC_TypeDef *SDIOCx)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
SDIOCx->PWRCON_f.PWON = 0u;
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Enable/Disable the function of Stop At Block Gap Request during block gap
|
|
**
|
|
** This function is used to stop data trasnfer of multi-block transfer
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enCmd SDIOC Stop At Block Gap Request functional state
|
|
** \arg Enable Enable the function of Stop At Block Gap Request
|
|
** \arg Disable Disable the function of Stop At Block Gap Request
|
|
**
|
|
** \retval Ok Set successfully
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_StopAtBlockGapCmd(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_functional_state_t enCmd)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
|
|
SDIOCx->BLKGPCON_f.SABGR = (uint8_t)(enCmd);
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Restart data transfer
|
|
**
|
|
** This function is used to restart data transfer when transfer is pending
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
**
|
|
** \retval Ok Set successfully
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_RestartTransfer(M4_SDIOC_TypeDef *SDIOCx)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
SDIOCx->BLKGPCON_f.CR = 1u;
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Enable/Disable the function of Read Wait Control
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enCmd SDIOC Read Wait Control functional state
|
|
** \arg Enable Enable the Read Wait Control function
|
|
** \arg Disable Disable the Read Wait Control function
|
|
**
|
|
** \retval Ok Set successfully
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_ReadWaitCmd(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_functional_state_t enCmd)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
|
|
SDIOCx->BLKGPCON_f.RWC = (uint8_t)(enCmd);
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Enable/Disable the function of Interrupt At Block Gap
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enCmd SDIOC Interrupt At Block Gap functional state
|
|
** \arg Enable Enable the function of Interrupt At Block Gap
|
|
** \arg Disable Disable the function of Interrupt At Block Gap
|
|
**
|
|
** \retval Ok Set successfully
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_InterruptAtBlockGapCmd(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_functional_state_t enCmd)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
|
|
SDIOCx->BLKGPCON_f.IABG = (uint8_t)(enCmd);
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Generate software reset to SD card
|
|
**
|
|
** This function generates software reset all command to SD card
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enSwResetType Software reset type
|
|
** \arg SdiocSwResetAll This reset affects the entire Host Controller except for the card detection circuit.
|
|
** \arg SdiocSwResetCmdLine Only part of command circuit is reset.
|
|
** \arg SdiocSwResetDataLine Only part of data circuit is reset.
|
|
**
|
|
** \retval Ok Software reset is done normally
|
|
** \retval ErrorTimeout SDIOCx reset timeout
|
|
** \retval ErrorInvalidParameter If one of following conditions are met:
|
|
** - SDIOCx is invalid
|
|
** - enSwResetType is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_SoftwareReset(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_sw_reset_t enSwResetType)
|
|
{
|
|
__IO uint32_t i = 0ul;
|
|
uint32_t u32Cnt = SystemCoreClock / 100ul;
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_SWRESETTYPE(enSwResetType));
|
|
|
|
enRet = Ok;
|
|
switch (enSwResetType)
|
|
{
|
|
case SdiocSwResetAll:
|
|
SDIOCx->SFTRST_f.RSTA = (uint8_t)1u;
|
|
while(0u != SDIOCx->SFTRST_f.RSTA) /* Wait until reset finish */
|
|
{
|
|
if (i++ > u32Cnt)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case SdiocSwResetCmdLine:
|
|
SDIOCx->SFTRST_f.RSTC = (uint8_t)1u;
|
|
while(0u != SDIOCx->SFTRST_f.RSTC) /* Wait until reset finish */
|
|
{
|
|
if (i++ > u32Cnt)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case SdiocSwResetDatLine:
|
|
SDIOCx->SFTRST_f.RSTD = (uint8_t)1u;
|
|
while(0u != SDIOCx->SFTRST_f.RSTD) /* Wait until reset finish */
|
|
{
|
|
if (i++ > u32Cnt)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
enRet = ErrorInvalidParameter;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i > u32Cnt)
|
|
{
|
|
enRet = ErrorTimeout;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Get the status of SDIOC host controller
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enHostStatus SDIOC host status
|
|
** \arg SdiocCommandInhibitCmd Command Inhibit(CMD). 1: Cannot issue command; 0:Can issue command using only CMD line
|
|
** \arg SdiocCommandInhibitData Command Inhibit(DAT). 1: Cannot issue command which uses the DAT line; 0:Can issue command which uses the DAT line
|
|
** \arg SdiocDataLineActive 1: DAT Line Active; 0: DAT Line Inactive
|
|
** \arg SdiocWriteTransferActive Write Transfer Active.1: Transferring data; 0: No valid data
|
|
** \arg SdiocReadTransferActive Read Transfer Active.1: Transferring data; 0: No valid data
|
|
** \arg SdiocBufferWriteEnble 1: Write enable; 0: Write Disable
|
|
** \arg SdiocBufferReadEnble 1: Read enable; 0: Read Disable
|
|
** \arg SdiocCardInserted 1: Card Inserted; 0: Reset or Debouncing or No Card
|
|
** \arg SdiocCardStateStable 1: No Card or Inserted; 0: Reset or Debouncing
|
|
** \arg SdiocCardDetectPinLvl 1: Card present; 0: No card present
|
|
** \arg SdiocWriteProtectPinLvl 1: Write enabled; 0: Write protected
|
|
** \arg SdiocData0PinLvl 1: DAT0 line signal level high; 0: DAT0 line signal level low
|
|
** \arg SdiocData1PinLvl 1: DAT1 line signal level high; 0: DAT1 line signal level low
|
|
** \arg SdiocData2PinLvl 1: DAT2 line signal level high; 0: DAT2 line signal level low
|
|
** \arg SdiocData3PinLvl 1: DAT3 line signal level high; 0: DAT3 line signal level low
|
|
** \arg SdiocCmdPinLvl 1: CMD line signal level high; 0: CMD line signal level low
|
|
**
|
|
** \retval Set The specified status is set
|
|
** \retval Reset The specified status is zero
|
|
**
|
|
******************************************************************************/
|
|
en_flag_status_t SDIOC_GetStatus(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_host_status_t enHostStatus)
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
|
|
DDL_ASSERT(IS_VALID_SDIOC_HOST_STATUS(enHostStatus));
|
|
|
|
return ((SDIOCx->PSTAT & ((uint32_t)enHostStatus)) ? Set : Reset);
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Enable/Disable the specified signal of SDIOC normal interrupt
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enNorInt SDIOC normal interrupt
|
|
** \arg SdiocCommandComplete Command Complete. 1: Command complete; 0:No command complete
|
|
** \arg SdiocTransferComplete Transfer Complete. 1: Data transfer complete; 0:No transfer complete
|
|
** \arg SdiocBlockGapEvent Block Gap Event. 1: Transaction stopped at block gap; 0: No Block Gap Event
|
|
** \arg SdiocBufferWriteReady Buffer Write Ready. 1: Ready to Write buffer; 0: No ready to Write buffer
|
|
** \arg SdiocBufferReadReady Buffer Read Ready. 1: Ready to read buffer; 0: No ready to read buffer
|
|
** \arg SdiocCardInsertedInt Write Transfer Active.1: Transferring data; 0: No valid data
|
|
** \arg SdiocCardRemoval Card Removal. 1: Card removed; 0: Card state stable or Debouncing
|
|
** \arg SdiocCardInt Card Interrupt. 1: Generate Card Interrupt; 0: No Card Interrupt
|
|
** \arg SdiocErrorInt Error Interrupt. 1: Error; 0: No Error
|
|
** \param [in] enCmd SDIOC normal interrupt signal functional state
|
|
** \arg Enable Enable the specified signal of SD normal interrupt
|
|
** \arg Disable Disable the specified signal of SD normal interrupt
|
|
**
|
|
** \retval Ok Set normally
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_NormalIrqSignalCmd(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_nor_int_sel_t enNorInt,
|
|
en_functional_state_t enCmd)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
|
|
DDL_ASSERT(IS_VALID_SDIOC_NOR_INT(enNorInt));
|
|
|
|
if (Enable == enCmd)
|
|
{
|
|
SDIOCx->NORINTSGEN |= (uint16_t)enNorInt;
|
|
}
|
|
else
|
|
{
|
|
SDIOCx->NORINTSGEN &= (uint16_t)(~((uint16_t)enNorInt));
|
|
}
|
|
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Enable/Disable the status of SDIOC normal interrupt
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enNorInt SDIOC normal interrupt
|
|
** \arg SdiocCommandComplete Command Complete. 1: Command complete; 0:No command complete
|
|
** \arg SdiocTransferComplete Transfer Complete. 1: Data transfer complete; 0:No transfer complete
|
|
** \arg SdiocBlockGapEvent Block Gap Event. 1: Transaction stopped at block gap; 0: No Block Gap Event
|
|
** \arg SdiocBufferWriteReady Buffer Write Ready. 1: Ready to Write buffer; 0: No ready to Write buffer
|
|
** \arg SdiocBufferReadReady Buffer Read Ready. 1: Ready to read buffer; 0: No ready to read buffer
|
|
** \arg SdiocCardInsertedInt Write Transfer Active.1: Transferring data; 0: No valid data
|
|
** \arg SdiocCardRemoval Card Removal. 1: Card removed; 0: Card state stable or Debouncing
|
|
** \arg SdiocCardInt Card Interrupt. 1: Generate Card Interrupt; 0: No Card Interrupt
|
|
** \arg SdiocErrorInt Error Interrupt. 1: Error; 0: No Error
|
|
** \param [in] enCmd SDIOC normal interrupt status functional state
|
|
** \arg Enable Enable the specified status of SD normal interrupt
|
|
** \arg Disable Disable the specified status of SD normal interrupt
|
|
**
|
|
** \retval Ok Set normally
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_NormalIrqStatusCmd(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_nor_int_sel_t enNorInt,
|
|
en_functional_state_t enCmd)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
|
|
DDL_ASSERT(IS_VALID_SDIOC_NOR_INT(enNorInt));
|
|
|
|
if (Enable == enCmd)
|
|
{
|
|
SDIOCx->NORINTSTEN |= (uint16_t)enNorInt;
|
|
}
|
|
else
|
|
{
|
|
SDIOCx->NORINTSTEN &= (uint16_t)(~((uint16_t)enNorInt));
|
|
}
|
|
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Get the flag of SD normal interrupt
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enNorInt SDIOC normal interrupt
|
|
** \arg SdiocCommandComplete Command Complete. 1: Command complete; 0:No command complete
|
|
** \arg SdiocTransferComplete Transfer Complete. 1: Data transfer complete; 0:No transfer complete
|
|
** \arg SdiocBlockGapEvent Block Gap Event. 1: Transaction stopped at block gap; 0: No Block Gap Event
|
|
** \arg SdiocBufferWriteReady Buffer Write Ready. 1: Ready to Write buffer; 0: No ready to Write buffer
|
|
** \arg SdiocBufferReadReady Buffer Read Ready. 1: Ready to read buffer; 0: No ready to read buffer
|
|
** \arg SdiocCardInsertedInt Write Transfer Active.1: Transferring data; 0: No valid data
|
|
** \arg SdiocCardRemoval Card Removal. 1: Card removed; 0: Card state stable or Debouncing
|
|
** \arg SdiocCardInt Card Interrupt. 1: Generate Card Interrupt; 0: No Card Interrupt
|
|
** \arg SdiocErrorInt Error Interrupt. 1: Error; 0: No Error
|
|
**
|
|
** \retval Set The specified interupt flag is set
|
|
** \retval Reset The specified interupt flag is zero
|
|
**
|
|
******************************************************************************/
|
|
en_flag_status_t SDIOC_GetNormalIrqFlag(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_nor_int_flag_t enNorInt)
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
|
|
DDL_ASSERT(IS_VALID_SDIOC_NOR_INT(enNorInt));
|
|
|
|
return ((SDIOCx->NORINTST & ((uint16_t)enNorInt)) ? Set : Reset);
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Clear the flag of SD normal interrupt
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enNorInt SDIOC normal interrupt
|
|
** \arg SdiocCommandComplete Command Complete. 1: Command complete; 0:No command complete
|
|
** \arg SdiocTransferComplete Transfer Complete. 1: Data transfer complete; 0:No transfer complete
|
|
** \arg SdiocBlockGapEvent Block Gap Event. 1: Transaction stopped at block gap; 0: No Block Gap Event
|
|
** \arg SdiocBufferWriteReady Buffer Write Ready. 1: Ready to Write buffer; 0: No ready to Write buffer
|
|
** \arg SdiocBufferReadReady Buffer Read Ready. 1: Ready to read buffer; 0: No ready to read buffer
|
|
** \arg SdiocCardInsertedInt Write Transfer Active.1: Transferring data; 0: No valid data
|
|
** \arg SdiocCardRemoval Card Removal. 1: Card removed; 0: Card state stable or Debouncing
|
|
** \arg SdiocCardInt Card Interrupt. 1: Generate Card Interrupt; 0: No Card Interrupt
|
|
** \arg SdiocErrorInt Error Interrupt. 1: Error; 0: No Error
|
|
**
|
|
** \retval Ok Clear successfully.
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_ClearNormalIrqFlag(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_nor_int_flag_t enNorInt)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_NOR_INT(enNorInt));
|
|
SDIOCx->NORINTST = (uint16_t)enNorInt;
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Enable/Disable the signal of SD error interrupt
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enErrInt SDIOC error interrupt
|
|
** \arg SdiocCmdTimeoutErr Command Timeout Error. 1: Timer out; 0:No Error
|
|
** \arg SdiocCmdCrcErr Command CRC Error. 1: Command CRC Error Generated; 0:No Error
|
|
** \arg SdiocCmdEndBitErr Command End Bit Error. 1: End Bit Error Generated; 0:No Error
|
|
** \arg SdiocCmdIndexErr Command Index Error. 1: Command Index Error Generatedr; 0:No Error
|
|
** \arg SdiocDataTimeoutErr Data Timeout Error. 1: Timer out; 0:No Error
|
|
** \arg SdiocDataCrcErr Data CRC Error. 1: Data CRC Error Generated; 0:No Error
|
|
** \arg SdiocDataEndBitErr Data End Bit Error. 1: End Bit Error Generated; 0:No Error
|
|
** \arg SdiocAutoCmd12Err Auto CMD12 Error. 1: Error; 0:No Error
|
|
** \param [in] enCmd SDIOC error interrupt signal functional state
|
|
** \arg Enable Enable the specified signal of SD error interrupt
|
|
** \arg Disable Disable the specified signal of SD error interrupt
|
|
**
|
|
** \retval Ok Set normally
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_ErrIrqSignalCmd(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_err_int_sel_t enErrInt,
|
|
en_functional_state_t enCmd)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_ERR_INT(enErrInt));
|
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
|
|
|
|
if (Enable == enCmd)
|
|
{
|
|
SDIOCx->ERRINTSGEN |= (uint16_t)enErrInt;
|
|
}
|
|
else
|
|
{
|
|
SDIOCx->ERRINTSGEN &= (uint16_t)enErrInt;
|
|
}
|
|
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Enable/Disable the status of SD error interrupt
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enErrInt SDIOC error interrupt
|
|
** \arg SdiocCmdTimeoutErr Command Timeout Error. 1: Timer out; 0:No Error
|
|
** \arg SdiocCmdCrcErr Command CRC Error. 1: Command CRC Error Generated; 0:No Error
|
|
** \arg SdiocCmdEndBitErr Command End Bit Error. 1: End Bit Error Generated; 0:No Error
|
|
** \arg SdiocCmdIndexErr Command Index Error. 1: Command Index Error Generatedr; 0:No Error
|
|
** \arg SdiocDataTimeoutErr Data Timeout Error. 1: Timer out; 0:No Error
|
|
** \arg SdiocDataCrcErr Data CRC Error. 1: Data CRC Error Generated; 0:No Error
|
|
** \arg SdiocDataEndBitErr Data End Bit Error. 1: End Bit Error Generated; 0:No Error
|
|
** \arg SdiocAutoCmd12Err Auto CMD12 Error. 1: Error; 0:No Error
|
|
** \param [in] enCmd SDIOC error interrupt status functional state
|
|
** \arg Enable Enable the specified status of SD error interrupt
|
|
** \arg Disable Disable the specified status of SD error interrupt
|
|
**
|
|
** \retval Ok Set normally
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_ErrIrqStatusCmd(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_err_int_sel_t enErrInt,
|
|
en_functional_state_t enCmd)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_ERR_INT(enErrInt));
|
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enCmd));
|
|
|
|
if (Enable == enCmd)
|
|
{
|
|
SDIOCx->ERRINTSTEN |= (uint16_t)enErrInt;
|
|
}
|
|
else
|
|
{
|
|
SDIOCx->ERRINTSTEN &= (uint16_t)enErrInt;
|
|
}
|
|
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Get the flag of SD error interrupt
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enErrInt SDIOC error interrupt
|
|
** \arg SdiocCmdTimeoutErr Command Timeout Error. 1: Timer out; 0:No Error
|
|
** \arg SdiocCmdCrcErr Command CRC Error. 1: Command CRC Error Generated; 0:No Error
|
|
** \arg SdiocCmdEndBitErr Command End Bit Error. 1: End Bit Error Generated; 0:No Error
|
|
** \arg SdiocCmdIndexErr Command Index Error. 1: Command Index Error Generatedr; 0:No Error
|
|
** \arg SdiocDataTimeoutErr Data Timeout Error. 1: Timer out; 0:No Error
|
|
** \arg SdiocDataCrcErr Data CRC Error. 1: Data CRC Error Generated; 0:No Error
|
|
** \arg SdiocDataEndBitErr Data End Bit Error. 1: End Bit Error Generated; 0:No Error
|
|
** \arg SdiocAutoCmd12Err Auto CMD12 Error. 1: Error; 0:No Error
|
|
**
|
|
** \retval Set The specified interupt flag is set
|
|
** \retval Reset The specified interupt flag is zero
|
|
**
|
|
******************************************************************************/
|
|
en_flag_status_t SDIOC_GetErrIrqFlag(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_err_int_flag_t enErrInt)
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
|
|
DDL_ASSERT(IS_VALID_SDIOC_ERR_INT(enErrInt));
|
|
|
|
return ((SDIOCx->ERRINTST & ((uint16_t)enErrInt)) ? Set : Reset);
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Clear the flag of SD error interrupt
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enErrInt SDIOC error interrupt
|
|
** \arg SdiocCmdTimeoutErr Command Timeout Error. 1: Timer out; 0:No Error
|
|
** \arg SdiocCmdCrcErr Command CRC Error. 1: Command CRC Error Generated; 0:No Error
|
|
** \arg SdiocCmdEndBitErr Command End Bit Error. 1: End Bit Error Generated; 0:No Error
|
|
** \arg SdiocCmdIndexErr Command Index Error. 1: Command Index Error Generatedr; 0:No Error
|
|
** \arg SdiocDataTimeoutErr Data Timeout Error. 1: Timer out; 0:No Error
|
|
** \arg SdiocDataCrcErr Data CRC Error. 1: Data CRC Error Generated; 0:No Error
|
|
** \arg SdiocDataEndBitErr Data End Bit Error. 1: End Bit Error Generated; 0:No Error
|
|
** \arg SdiocAutoCmd12Err Auto CMD12 Error. 1: Error; 0:No Error
|
|
**
|
|
** \retval Ok Clear successfully.
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_ClearErrIrqFlag(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_err_int_flag_t enErrInt)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_ERR_INT(enErrInt));
|
|
SDIOCx->ERRINTST = (uint16_t)enErrInt;
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Force the specified error interrupt flag
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enErrInt SDIOC error interrupt
|
|
** \arg SdiocCmdTimeoutErr Command Timeout Error. 1: Timer out; 0:No Error
|
|
** \arg SdiocCmdCrcErr Command CRC Error. 1: Command CRC Error Generated; 0:No Error
|
|
** \arg SdiocCmdEndBitErr Command End Bit Error. 1: End Bit Error Generated; 0:No Error
|
|
** \arg SdiocCmdIndexErr Command Index Error. 1: Command Index Error Generatedr; 0:No Error
|
|
** \arg SdiocDataTimeoutErr Data Timeout Error. 1: Timer out; 0:No Error
|
|
** \arg SdiocDataCrcErr Data CRC Error. 1: Data CRC Error Generated; 0:No Error
|
|
** \arg SdiocDataEndBitErr Data End Bit Error. 1: End Bit Error Generated; 0:No Error
|
|
** \arg SdiocAutoCmd12Err Auto CMD12 Error. 1: Error; 0:No Error
|
|
**
|
|
** \retval Ok Set successfully.
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_ForceErrIrqFlag(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_err_int_sel_t enErrInt)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_ERR_INT(enErrInt));
|
|
SDIOCx->FEE |= (uint16_t)enErrInt;
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Get the status of auto CMD12 error
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enAutoCmdErr SDIOC auto cmd error status selection
|
|
** \arg SdiocAutoCmd12NotExecuted Auto CMD12 Not Executed. 1: Not executed; 0:Executed
|
|
** \arg SdiocAutoCmd12Timeout Auto CMD12 Timeout Error. 1: Time out; 0:No error
|
|
** \arg SdiocAutoCmd12CrcErr Auto CMD12 CRC Error. 1: CRC Error Generated; 0: No error
|
|
** \arg SdiocAutoCmd12EndBitErr Auto CMD12 End Bit Error. 1: End Bit Error Generated; 0: No error to Write buffer
|
|
** \arg SdiocAutoCmd12IndexErr Auto CMD12 Index Error. 1: Error; 0: No error
|
|
** \arg SdiocCmdNotIssuedErr Command Not Issued By Auto CMD12 Error.1: Not Issued; 0: No error
|
|
**
|
|
** \retval Set The specified status flag is set
|
|
** \retval Reset The specified status flag is zero
|
|
**
|
|
******************************************************************************/
|
|
en_flag_status_t SDIOC_GetAutoCmdErrStatus(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_atuo_cmd_err_status_t enAutoCmdErr)
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC(SDIOCx));
|
|
DDL_ASSERT(IS_VALID_SDIOC_AUTOCMD_ERR(enAutoCmdErr));
|
|
|
|
return ((SDIOCx->ATCERRST & ((uint16_t)enAutoCmdErr)) ? Set : Reset);
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
** \brief Force the specified auto CMD12 error
|
|
**
|
|
** \param [in] SDIOCx Pointer to SDIOC instance register base
|
|
** \arg M4_SDIOC1 SDIOC unit 1 instance register base
|
|
** \arg M4_SDIOC2 SDIOC unit 2 instance register base
|
|
** \param [in] enAutoCmdErr SDIOC auto cmd error selection
|
|
** \arg SdiocAutoCmd12NotExecuted Auto CMD12 Not Executed. 1: Not executed; 0:Executed
|
|
** \arg SdiocAutoCmd12Timeout Auto CMD12 Timeout Error. 1: Time out; 0:No error
|
|
** \arg SdiocAutoCmd12CrcErr Auto CMD12 CRC Error. 1: CRC Error Generated; 0: No error
|
|
** \arg SdiocAutoCmd12EndBitErr Auto CMD12 End Bit Error. 1: End Bit Error Generated; 0: No error to Write buffer
|
|
** \arg SdiocAutoCmd12IndexErr Auto CMD12 Index Error. 1: Error; 0: No error
|
|
** \arg SdiocCmdNotIssuedErr Command Not Issued By Auto CMD12 Error.1: Not Issued; 0: No error
|
|
**
|
|
** \retval Ok Set successfully.
|
|
** \retval ErrorInvalidParameter SDIOCx is invalid
|
|
**
|
|
******************************************************************************/
|
|
en_result_t SDIOC_ForceAutoCmdErr(M4_SDIOC_TypeDef *SDIOCx,
|
|
en_sdioc_atuo_cmd_err_sel_t enAutoCmdErr)
|
|
{
|
|
en_result_t enRet = ErrorInvalidParameter;
|
|
|
|
/* Check for SDIOCx pointer */
|
|
if (IS_VALID_SDIOC(SDIOCx))
|
|
{
|
|
/* Check the parameters */
|
|
DDL_ASSERT(IS_VALID_SDIOC_AUTOCMD_ERR(enAutoCmdErr));
|
|
SDIOCx->FEA |= (uint16_t)enAutoCmdErr;
|
|
enRet = Ok;
|
|
}
|
|
|
|
return enRet;
|
|
}
|
|
|
|
//@} // SdiocGroup
|
|
|
|
#endif /* DDL_SDIOC_ENABLE */
|
|
|
|
/*******************************************************************************
|
|
* EOF (not truncated)
|
|
******************************************************************************/
|