mirror of https://github.com/ARMmbed/mbed-os.git
Bug fixes to interrupt/event handling in SDHC HAL
parent
8ad377add3
commit
5c899a3350
|
@ -76,23 +76,23 @@ typedef enum
|
||||||
|
|
||||||
/** SDHC interrupt triggers */
|
/** SDHC interrupt triggers */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CYHAL_SDHC_CMD_COMPLETE, //!> Command Complete
|
CYHAL_SDHC_CMD_COMPLETE = 0x0001, //!> Command Complete
|
||||||
CYHAL_SDHC_XFER_COMPLETE, //!> Host read/write transfer is complete
|
CYHAL_SDHC_XFER_COMPLETE = 0x0002, //!> Host read/write transfer is complete
|
||||||
CYHAL_SDHC_BGAP_EVENT, //!> This bit is set when both read/write transaction is stopped
|
CYHAL_SDHC_BGAP_EVENT = 0x0004, //!> This bit is set when both read/write transaction is stopped at the block gap
|
||||||
CYHAL_SDHC_DMA_INTERRUPT, //!> Host controller detects an SDMA Buffer Boundary during transfer
|
CYHAL_SDHC_DMA_INTERRUPT = 0x0008, //!> Host controller detects an SDMA Buffer Boundary during transfer
|
||||||
CYHAL_SDHC_BUF_WR_READY, //!> This bit is set if the Buffer Write Enable changes from 0 to 1
|
CYHAL_SDHC_BUF_WR_READY = 0x0010, //!> This bit is set if the Buffer Write Enable changes from 0 to 1
|
||||||
CYHAL_SDHC_BUF_RD_READY, //!> This bit is set if the Buffer Read Enable changes from 0 to 1
|
CYHAL_SDHC_BUF_RD_READY = 0x0020, //!> This bit is set if the Buffer Read Enable changes from 0 to 1
|
||||||
CYHAL_SDHC_CARD_INSERTION, //!> This bit is set if the Card Inserted in the Present State
|
CYHAL_SDHC_CARD_INSERTION = 0x0040, //!> This bit is set if the Card Inserted in the Present State register changes from 0 to 1.
|
||||||
CYHAL_SDHC_CARD_REMOVAL, //!> This bit is set if the Card Inserted in the Present State
|
CYHAL_SDHC_CARD_REMOVAL = 0x0080, //!> This bit is set if the Card Inserted in the Present State register changes from 1 to 0.
|
||||||
CYHAL_SDHC_CARD_INTERRUPT, //!> The synchronized value of the DAT[1] interrupt input for SD mode
|
CYHAL_SDHC_CARD_INTERRUPT = 0x0100, //!> The synchronized value of the DAT[1] interrupt input for SD mode
|
||||||
CYHAL_SDHC_INT_A,
|
CYHAL_SDHC_INT_A = 0x0200,
|
||||||
CYHAL_SDHC_INT_B,
|
CYHAL_SDHC_INT_B = 0x0400,
|
||||||
CYHAL_SDHC_INT_C,
|
CYHAL_SDHC_INT_C = 0x0800,
|
||||||
CYHAL_SDHC_RE_TUNE_EVENT, //!> This bit is set if the Re-Tuning Request changes from 0 to 1
|
CYHAL_SDHC_RE_TUNE_EVENT = 0x1000, //!> This bit is set if the Re-Tuning Request changes from 0 to 1
|
||||||
CYHAL_SDHC_FX_EVENT, //!> This status is set when R[14] of response register is set to 1
|
CYHAL_SDHC_FX_EVENT = 0x2000, //!> This status is set when R[14] of response register is set to 1
|
||||||
CYHAL_SDHC_CQE_EVENT, //!> This status is set if Command Queuing/Crypto event has occurred
|
CYHAL_SDHC_CQE_EVENT = 0x4000, //!> This status is set if Command Queuing/Crypto event has occurred
|
||||||
CYHAL_SDHC_ERR_INTERRUPT, //!> If any of the bits in the Error Interrupt Status register are set
|
CYHAL_SDHC_ERR_INTERRUPT = 0x8000, //!> If any of the bits in the Error Interrupt Status register are set
|
||||||
CYHAL_SDHC_ALL_INTERRUPTS, //!> Is used to enable/disable all interrupts
|
CYHAL_SDHC_ALL_INTERRUPTS = 0xFFFF, //!> Is used to enable/disable all interrupts
|
||||||
} cyhal_sdhc_event_t;
|
} cyhal_sdhc_event_t;
|
||||||
|
|
||||||
/** \} group_hal_sdhc_enums */
|
/** \} group_hal_sdhc_enums */
|
||||||
|
@ -121,7 +121,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
bool enableLedControl; //!< Drive one IO to indicate when the card is being accessed
|
bool enableLedControl; //!< Drive one IO to indicate when the card is being accessed
|
||||||
bool lowVoltageSignaling; //!< Whether 1.8V signaling is supported
|
bool lowVoltageSignaling; //!< Whether 1.8V signaling is supported
|
||||||
bool isEmmc; //!< true if eMMC card, other way false
|
bool isEmmc; //!< true if eMMC card, otherwise false
|
||||||
uint8_t busWidth; //!< The desired bus width
|
uint8_t busWidth; //!< The desired bus width
|
||||||
} cyhal_sdhc_config_t;
|
} cyhal_sdhc_config_t;
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ void cyhal_sdhc_free(cyhal_sdhc_t *obj);
|
||||||
* @param[in] obj The SDHC object
|
* @param[in] obj The SDHC object
|
||||||
* @param[in] address The address to read data from
|
* @param[in] address The address to read data from
|
||||||
* @param[out] data Pointer to the byte-array of data to read from the device
|
* @param[out] data Pointer to the byte-array of data to read from the device
|
||||||
* @param[in,out] length Number of bytes to read, updated with the number actually read
|
* @param[in,out] length Number of 512 byte blocks to read, updated with the number actually read
|
||||||
* @return The status of the read request
|
* @return The status of the read request
|
||||||
*/
|
*/
|
||||||
cy_rslt_t cyhal_sdhc_read(const cyhal_sdhc_t *obj, uint32_t address, uint8_t *data, size_t *length);
|
cy_rslt_t cyhal_sdhc_read(const cyhal_sdhc_t *obj, uint32_t address, uint8_t *data, size_t *length);
|
||||||
|
@ -196,7 +196,7 @@ cy_rslt_t cyhal_sdhc_read(const cyhal_sdhc_t *obj, uint32_t address, uint8_t *da
|
||||||
* @param[in] obj The SDHC object
|
* @param[in] obj The SDHC object
|
||||||
* @param[in] address The address to write data to
|
* @param[in] address The address to write data to
|
||||||
* @param[in] data Pointer to the byte-array of data to write to the device
|
* @param[in] data Pointer to the byte-array of data to write to the device
|
||||||
* @param[in,out] length Number of bytes to read, updated with the number actually read
|
* @param[in,out] length Number of 512 byte blocks to write, updated with the number actually written
|
||||||
* @return The status of the write request
|
* @return The status of the write request
|
||||||
*/
|
*/
|
||||||
cy_rslt_t cyhal_sdhc_write(const cyhal_sdhc_t *obj, uint32_t address, const uint8_t *data, size_t *length);
|
cy_rslt_t cyhal_sdhc_write(const cyhal_sdhc_t *obj, uint32_t address, const uint8_t *data, size_t *length);
|
||||||
|
@ -205,7 +205,7 @@ cy_rslt_t cyhal_sdhc_write(const cyhal_sdhc_t *obj, uint32_t address, const uint
|
||||||
*
|
*
|
||||||
* @param[in] obj The SDHC object
|
* @param[in] obj The SDHC object
|
||||||
* @param[in] startAddr Is the address of the first byte to erase
|
* @param[in] startAddr Is the address of the first byte to erase
|
||||||
* @param[in] length The number of bytes (starting at startAddr) to erase
|
* @param[in] length Number of 512 byte blocks (starting at startAddr) to erase
|
||||||
* @return The status of the erase request
|
* @return The status of the erase request
|
||||||
*/
|
*/
|
||||||
cy_rslt_t cyhal_sdhc_erase(const cyhal_sdhc_t *obj, uint32_t startAddr, size_t length);
|
cy_rslt_t cyhal_sdhc_erase(const cyhal_sdhc_t *obj, uint32_t startAddr, size_t length);
|
||||||
|
@ -215,7 +215,7 @@ cy_rslt_t cyhal_sdhc_erase(const cyhal_sdhc_t *obj, uint32_t startAddr, size_t l
|
||||||
* @param[in] obj The SDHC object that holds the transfer information
|
* @param[in] obj The SDHC object that holds the transfer information
|
||||||
* @param[in] address The address to read data from
|
* @param[in] address The address to read data from
|
||||||
* @param[out] data The receive buffer
|
* @param[out] data The receive buffer
|
||||||
* @param[in,out] length Number of bytes to read, updated with the number actually read
|
* @param[in,out] length Number of 512 byte blocks to read, updated with the number actually read
|
||||||
* @return The status of the read_async request
|
* @return The status of the read_async request
|
||||||
*/
|
*/
|
||||||
cy_rslt_t cyhal_sdhc_read_async(const cyhal_sdhc_t *obj, uint32_t address, uint8_t *data, size_t *length);
|
cy_rslt_t cyhal_sdhc_read_async(const cyhal_sdhc_t *obj, uint32_t address, uint8_t *data, size_t *length);
|
||||||
|
@ -225,7 +225,7 @@ cy_rslt_t cyhal_sdhc_read_async(const cyhal_sdhc_t *obj, uint32_t address, uint8
|
||||||
* @param[in] obj The SDHC object that holds the transfer information
|
* @param[in] obj The SDHC object that holds the transfer information
|
||||||
* @param[in] address The address to write data to
|
* @param[in] address The address to write data to
|
||||||
* @param[in] data The transmit buffer
|
* @param[in] data The transmit buffer
|
||||||
* @param[in,out] length Number of bytes to read, updated with the number actually read
|
* @param[in,out] length The number of 512 byte blocks to write, updated with the number actually written
|
||||||
* @return The status of the write_async request
|
* @return The status of the write_async request
|
||||||
*/
|
*/
|
||||||
cy_rslt_t cyhal_sdhc_write_async(const cyhal_sdhc_t *obj, uint32_t address, const uint8_t *data, size_t *length);
|
cy_rslt_t cyhal_sdhc_write_async(const cyhal_sdhc_t *obj, uint32_t address, const uint8_t *data, size_t *length);
|
||||||
|
|
|
@ -135,6 +135,15 @@ extern "C"
|
||||||
#define CYHAL_SDIO_DS_CB_ORDER (0U)
|
#define CYHAL_SDIO_DS_CB_ORDER (0U)
|
||||||
#endif /* !defined(CYHAL_SDIO_DS_CB_ORDER) */
|
#endif /* !defined(CYHAL_SDIO_DS_CB_ORDER) */
|
||||||
|
|
||||||
|
/* Defines for mapping sdhc events on interrupts */
|
||||||
|
#define SDHC_EVENTS_NUM (12U)
|
||||||
|
#define SDHC_EVENTS_MAP_NUM (2U)
|
||||||
|
|
||||||
|
#define SDHC_EVENT (0U)
|
||||||
|
#define SDHC_ISR (1U)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* List of available SDHC instances */
|
/* List of available SDHC instances */
|
||||||
static SDHC_Type * const CYHAL_SDHC_BASE_ADDRESSES[CY_IP_MXSDHC_INSTANCES] =
|
static SDHC_Type * const CYHAL_SDHC_BASE_ADDRESSES[CY_IP_MXSDHC_INSTANCES] =
|
||||||
{
|
{
|
||||||
|
@ -197,6 +206,24 @@ static uint8_t cyhal_sd_get_block_from_irqn(IRQn_Type irqn)
|
||||||
|
|
||||||
static void *cyhal_sd_config_structs[CY_IP_MXSDHC_INSTANCES];
|
static void *cyhal_sd_config_structs[CY_IP_MXSDHC_INSTANCES];
|
||||||
|
|
||||||
|
|
||||||
|
/* Structure to map SDHC events on SDHC interrupts */
|
||||||
|
const uint32_t eventMap[SDHC_EVENTS_NUM][SDHC_EVENTS_MAP_NUM] =
|
||||||
|
{
|
||||||
|
{ (uint32_t)CYHAL_SDHC_CMD_COMPLETE, (uint32_t)CY_SD_HOST_CMD_COMPLETE},
|
||||||
|
{ (uint32_t)CYHAL_SDHC_XFER_COMPLETE, (uint32_t)CY_SD_HOST_XFER_COMPLETE },
|
||||||
|
{ (uint32_t)CYHAL_SDHC_BGAP_EVENT, (uint32_t)CY_SD_HOST_BGAP },
|
||||||
|
{ (uint32_t)CYHAL_SDHC_DMA_INTERRUPT, (uint32_t)CY_SD_HOST_DMA_INTERRUPT },
|
||||||
|
{ (uint32_t)CYHAL_SDHC_BUF_WR_READY, (uint32_t)CY_SD_HOST_BUF_WR_READY },
|
||||||
|
{ (uint32_t)CYHAL_SDHC_BUF_RD_READY, (uint32_t)CY_SD_HOST_BUF_RD_READY },
|
||||||
|
{ (uint32_t)CYHAL_SDHC_CARD_INSERTION, (uint32_t)CY_SD_HOST_CARD_INSERTION },
|
||||||
|
{ (uint32_t)CYHAL_SDHC_CARD_REMOVAL, (uint32_t)CY_SD_HOST_CARD_REMOVAL },
|
||||||
|
{ (uint32_t)CYHAL_SDHC_CARD_INTERRUPT, (uint32_t)CY_SD_HOST_CARD_INTERRUPT },
|
||||||
|
{ (uint32_t)CYHAL_SDHC_FX_EVENT, (uint32_t)CY_SD_HOST_FX_EVENT },
|
||||||
|
{ (uint32_t)CYHAL_SDHC_CQE_EVENT, (uint32_t)CY_SD_HOST_CQE_EVENT },
|
||||||
|
{ (uint32_t)CYHAL_SDHC_ERR_INTERRUPT, (uint32_t)CY_SD_HOST_ERR_INTERRUPT },
|
||||||
|
};
|
||||||
|
|
||||||
static void release_pin_if_used(cyhal_gpio_t *pin)
|
static void release_pin_if_used(cyhal_gpio_t *pin)
|
||||||
{
|
{
|
||||||
if (CYHAL_NC_PIN_VALUE != *pin)
|
if (CYHAL_NC_PIN_VALUE != *pin)
|
||||||
|
@ -248,6 +275,7 @@ static cy_en_sd_host_status_t Cy_SD_Host_SdCardChangeClock(SDHC_Type *base, uint
|
||||||
static cy_en_sd_host_bus_width_t convert_buswidth(uint8_t stopbits);
|
static cy_en_sd_host_bus_width_t convert_buswidth(uint8_t stopbits);
|
||||||
static cy_en_syspm_status_t cyhal_sdio_syspm_callback(cy_stc_syspm_callback_params_t *params,
|
static cy_en_syspm_status_t cyhal_sdio_syspm_callback(cy_stc_syspm_callback_params_t *params,
|
||||||
cy_en_syspm_callback_mode_t mode);
|
cy_en_syspm_callback_mode_t mode);
|
||||||
|
static cyhal_sdhc_event_t get_event_from_isr(uint32_t asserted_interrupt);
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Deep Sleep Callback Service Routine
|
* Deep Sleep Callback Service Routine
|
||||||
|
@ -484,21 +512,20 @@ static void cyhal_sdhc_irq_handler(void)
|
||||||
|
|
||||||
uint32_t interruptStatus = Cy_SD_Host_GetNormalInterruptStatus(blockAddr);
|
uint32_t interruptStatus = Cy_SD_Host_GetNormalInterruptStatus(blockAddr);
|
||||||
uint32_t userInterruptStatus = interruptStatus & obj->irq_cause;
|
uint32_t userInterruptStatus = interruptStatus & obj->irq_cause;
|
||||||
|
cyhal_sdhc_event_t user_events = get_event_from_isr(userInterruptStatus);
|
||||||
|
|
||||||
if (obj->callback_data.callback != NULL)
|
if (obj->callback_data.callback != NULL)
|
||||||
{
|
{
|
||||||
cyhal_sdhc_event_callback_t callback = (cyhal_sdhc_event_callback_t) obj->callback_data.callback;
|
cyhal_sdhc_event_callback_t callback = (cyhal_sdhc_event_callback_t) obj->callback_data.callback;
|
||||||
|
|
||||||
/* Call registered callbacks here */
|
/* Call registered callbacks here */
|
||||||
(void) (callback) (obj->callback_data.callback_arg, (cyhal_sdhc_event_t) userInterruptStatus);
|
(void) (callback) (obj->callback_data.callback_arg, user_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear only handled events */
|
/* Clear only handled events */
|
||||||
Cy_SD_Host_ClearNormalInterruptStatus(blockAddr, userInterruptStatus);
|
Cy_SD_Host_ClearNormalInterruptStatus(blockAddr, interruptStatus);
|
||||||
|
|
||||||
/* To clear SD Card interrupt need to disable SD Card Interrupt Enable bit.
|
/* To clear SD Card interrupt need to disable SD Card Interrupt Enable bit */
|
||||||
* The SD Card interrupt is enabled in the bulk transfer function later on
|
|
||||||
* the next data transfer.
|
|
||||||
*/
|
|
||||||
if (0U != (interruptStatus & CY_SD_HOST_CARD_INTERRUPT))
|
if (0U != (interruptStatus & CY_SD_HOST_CARD_INTERRUPT))
|
||||||
{
|
{
|
||||||
uint32_t interruptMask = Cy_SD_Host_GetNormalInterruptEnable(blockAddr);
|
uint32_t interruptMask = Cy_SD_Host_GetNormalInterruptEnable(blockAddr);
|
||||||
|
@ -507,7 +534,26 @@ static void cyhal_sdhc_irq_handler(void)
|
||||||
/* Disable SD Card interrupt */
|
/* Disable SD Card interrupt */
|
||||||
Cy_SD_Host_SetNormalInterruptEnable(blockAddr, interruptMask);
|
Cy_SD_Host_SetNormalInterruptEnable(blockAddr, interruptMask);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static cyhal_sdhc_event_t get_event_from_isr(uint32_t asserted_interrupt)
|
||||||
|
{
|
||||||
|
cyhal_sdhc_event_t anded_events = (cyhal_sdhc_event_t) 0U;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < SDHC_EVENTS_NUM; i++)
|
||||||
|
{
|
||||||
|
const uint32_t *map_entry = eventMap[i];
|
||||||
|
|
||||||
|
/* Anded events should be handled in user callback function as only
|
||||||
|
* there exist the knowledge of enabled events
|
||||||
|
*/
|
||||||
|
if ((asserted_interrupt & map_entry[SDHC_ISR]) != 0)
|
||||||
|
{
|
||||||
|
anded_events |= map_entry[SDHC_EVENT];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return anded_events;
|
||||||
}
|
}
|
||||||
|
|
||||||
cy_rslt_t cyhal_sdhc_init(cyhal_sdhc_t *obj,
|
cy_rslt_t cyhal_sdhc_init(cyhal_sdhc_t *obj,
|
||||||
|
@ -680,7 +726,7 @@ cy_rslt_t cyhal_sdhc_init(cyhal_sdhc_t *obj,
|
||||||
|
|
||||||
/* Do not support eMMC card */
|
/* Do not support eMMC card */
|
||||||
obj->emmc = config->isEmmc;
|
obj->emmc = config->isEmmc;
|
||||||
obj->dmaType = CY_SD_HOST_DMA_SDMA;
|
obj->dmaType = CY_SD_HOST_DMA_ADMA2;
|
||||||
|
|
||||||
/* Configure SD Host to operate */
|
/* Configure SD Host to operate */
|
||||||
cy_stc_sd_host_init_config_t hostConfig;
|
cy_stc_sd_host_init_config_t hostConfig;
|
||||||
|
@ -807,6 +853,7 @@ cy_rslt_t cyhal_sdhc_read(const cyhal_sdhc_t *obj, uint32_t address, uint8_t *da
|
||||||
cy_rslt_t ret = CY_RSLT_SUCCESS;
|
cy_rslt_t ret = CY_RSLT_SUCCESS;
|
||||||
cy_en_sd_host_status_t driverRet;
|
cy_en_sd_host_status_t driverRet;
|
||||||
cy_stc_sd_host_write_read_config_t dataConfig;
|
cy_stc_sd_host_write_read_config_t dataConfig;
|
||||||
|
uint32_t regIntrSts = Cy_SD_Host_GetNormalInterruptMask(obj->base);
|
||||||
|
|
||||||
dataConfig.data = (uint32_t*)data; /* The pointer to data. */
|
dataConfig.data = (uint32_t*)data; /* The pointer to data. */
|
||||||
dataConfig.address = address; /* The address to write/read data on the card or eMMC. */
|
dataConfig.address = address; /* The address to write/read data on the card or eMMC. */
|
||||||
|
@ -818,6 +865,12 @@ cy_rslt_t cyhal_sdhc_read(const cyhal_sdhc_t *obj, uint32_t address, uint8_t *da
|
||||||
dataConfig.enReliableWrite = false; /* For EMMC cards enable reliable write. */
|
dataConfig.enReliableWrite = false; /* For EMMC cards enable reliable write. */
|
||||||
dataConfig.enableDma = true;
|
dataConfig.enableDma = true;
|
||||||
|
|
||||||
|
/* First clear out the transfer and command complete statuses */
|
||||||
|
Cy_SD_Host_ClearNormalInterruptStatus(obj->base, (CY_SD_HOST_XFER_COMPLETE | CY_SD_HOST_CMD_COMPLETE));
|
||||||
|
|
||||||
|
/* Disable CMD Done interrupt, will be enabled after transition is complete */
|
||||||
|
Cy_SD_Host_SetNormalInterruptMask(obj->base, (regIntrSts & (uint32_t)~(CY_SD_HOST_XFER_COMPLETE | CY_SD_HOST_CMD_COMPLETE)));
|
||||||
|
|
||||||
driverRet = Cy_SD_Host_Read(obj->base, &dataConfig, &obj->context);
|
driverRet = Cy_SD_Host_Read(obj->base, &dataConfig, &obj->context);
|
||||||
|
|
||||||
if (CY_SD_HOST_SUCCESS != driverRet)
|
if (CY_SD_HOST_SUCCESS != driverRet)
|
||||||
|
@ -834,8 +887,11 @@ cy_rslt_t cyhal_sdhc_read(const cyhal_sdhc_t *obj, uint32_t address, uint8_t *da
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Restore interrupts after transition */
|
||||||
|
Cy_SD_Host_SetNormalInterruptMask(obj->base, regIntrSts);
|
||||||
|
|
||||||
/* Enable SD Card interrupt because it was disabled in interrupt handler */
|
/* Enable SD Card interrupt because it was disabled in interrupt handler */
|
||||||
if ((uint32_t) CYHAL_SDHC_CARD_INTERRUPT == ((uint32_t)CYHAL_SDHC_CARD_INTERRUPT & obj->irq_cause))
|
if (0U != (obj->irq_cause & CY_SD_HOST_CARD_INTERRUPT))
|
||||||
{
|
{
|
||||||
uint32_t intrStsEn = Cy_SD_Host_GetNormalInterruptEnable(obj->base);
|
uint32_t intrStsEn = Cy_SD_Host_GetNormalInterruptEnable(obj->base);
|
||||||
|
|
||||||
|
@ -851,6 +907,7 @@ cy_rslt_t cyhal_sdhc_write(const cyhal_sdhc_t *obj, uint32_t address, const uint
|
||||||
cy_rslt_t ret = CY_RSLT_SUCCESS;
|
cy_rslt_t ret = CY_RSLT_SUCCESS;
|
||||||
cy_en_sd_host_status_t driverRet;
|
cy_en_sd_host_status_t driverRet;
|
||||||
cy_stc_sd_host_write_read_config_t dataConfig;
|
cy_stc_sd_host_write_read_config_t dataConfig;
|
||||||
|
uint32_t regIntrSts = Cy_SD_Host_GetNormalInterruptMask(obj->base);
|
||||||
|
|
||||||
dataConfig.data = (uint32_t*)data; /* The pointer to data. */
|
dataConfig.data = (uint32_t*)data; /* The pointer to data. */
|
||||||
dataConfig.address = address; /* The address to write/read data on the card or eMMC. */
|
dataConfig.address = address; /* The address to write/read data on the card or eMMC. */
|
||||||
|
@ -862,6 +919,12 @@ cy_rslt_t cyhal_sdhc_write(const cyhal_sdhc_t *obj, uint32_t address, const uint
|
||||||
dataConfig.enReliableWrite = false; /* For EMMC cards enable reliable write. */
|
dataConfig.enReliableWrite = false; /* For EMMC cards enable reliable write. */
|
||||||
dataConfig.enableDma = true;
|
dataConfig.enableDma = true;
|
||||||
|
|
||||||
|
/* First clear out the transfer and command complete statuses */
|
||||||
|
Cy_SD_Host_ClearNormalInterruptStatus(obj->base, (CY_SD_HOST_XFER_COMPLETE | CY_SD_HOST_CMD_COMPLETE));
|
||||||
|
|
||||||
|
/* Disable CMD Done interrupt, will be enabled after transition is complete */
|
||||||
|
Cy_SD_Host_SetNormalInterruptMask(obj->base, (regIntrSts & (uint32_t)~(CY_SD_HOST_XFER_COMPLETE | CY_SD_HOST_CMD_COMPLETE)));
|
||||||
|
|
||||||
driverRet = Cy_SD_Host_Write(obj->base, &dataConfig, &obj->context);
|
driverRet = Cy_SD_Host_Write(obj->base, &dataConfig, &obj->context);
|
||||||
|
|
||||||
if (CY_SD_HOST_SUCCESS != driverRet)
|
if (CY_SD_HOST_SUCCESS != driverRet)
|
||||||
|
@ -878,8 +941,11 @@ cy_rslt_t cyhal_sdhc_write(const cyhal_sdhc_t *obj, uint32_t address, const uint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Restore interrupts after transition */
|
||||||
|
Cy_SD_Host_SetNormalInterruptMask(obj->base, regIntrSts);
|
||||||
|
|
||||||
/* Enable SD Card interrupt because it was disabled in interrupt handler */
|
/* Enable SD Card interrupt because it was disabled in interrupt handler */
|
||||||
if ((uint32_t) CYHAL_SDHC_CARD_INTERRUPT == ((uint32_t)CYHAL_SDHC_CARD_INTERRUPT & obj->irq_cause))
|
if (0U != (obj->irq_cause & CY_SD_HOST_CARD_INTERRUPT))
|
||||||
{
|
{
|
||||||
uint32_t intrStsEn = Cy_SD_Host_GetNormalInterruptEnable(obj->base);
|
uint32_t intrStsEn = Cy_SD_Host_GetNormalInterruptEnable(obj->base);
|
||||||
|
|
||||||
|
@ -897,20 +963,29 @@ cy_rslt_t cyhal_sdhc_erase(const cyhal_sdhc_t *obj, uint32_t startAddr, size_t l
|
||||||
cy_en_sd_host_erase_type_t eraseType = CY_SD_HOST_ERASE_ERASE;
|
cy_en_sd_host_erase_type_t eraseType = CY_SD_HOST_ERASE_ERASE;
|
||||||
uint32_t i = SDHC_RETRY_TIMES;
|
uint32_t i = SDHC_RETRY_TIMES;
|
||||||
uint32_t cardStatus;
|
uint32_t cardStatus;
|
||||||
|
uint32_t regIntrSts = Cy_SD_Host_GetNormalInterruptMask(obj->base);
|
||||||
|
|
||||||
if (obj->emmc)
|
if (obj->emmc)
|
||||||
{
|
{
|
||||||
eraseType = CY_SD_HOST_ERASE_TRIM;
|
eraseType = CY_SD_HOST_ERASE_TRIM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* First clear out the transfer and command complete statuses */
|
||||||
|
Cy_SD_Host_ClearNormalInterruptStatus(obj->base, (CY_SD_HOST_XFER_COMPLETE | CY_SD_HOST_CMD_COMPLETE));
|
||||||
|
|
||||||
|
/* Disable CMD Done interrupt, will be enabled after transition is complete */
|
||||||
|
Cy_SD_Host_SetNormalInterruptMask(obj->base, (regIntrSts & (uint32_t)~(CY_SD_HOST_XFER_COMPLETE | CY_SD_HOST_CMD_COMPLETE)));
|
||||||
|
|
||||||
driverRet = Cy_SD_Host_Erase(obj->base, startAddr, (startAddr + length), eraseType, &obj->context);
|
driverRet = Cy_SD_Host_Erase(obj->base, startAddr, (startAddr + length), eraseType, &obj->context);
|
||||||
|
|
||||||
if (CY_SD_HOST_SUCCESS != driverRet)
|
if (CY_SD_HOST_SUCCESS != driverRet)
|
||||||
{
|
{
|
||||||
ret = CY_RSLT_TYPE_ERROR;
|
ret = CY_RSLT_TYPE_ERROR;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
driverRet = Cy_SD_Host_PollCmdComplete(obj->base);
|
{
|
||||||
|
driverRet = Cy_SD_Host_PollCmdComplete(obj->base);
|
||||||
|
}
|
||||||
|
|
||||||
if (CY_SD_HOST_SUCCESS != driverRet)
|
if (CY_SD_HOST_SUCCESS != driverRet)
|
||||||
{
|
{
|
||||||
|
@ -945,8 +1020,11 @@ cy_rslt_t cyhal_sdhc_erase(const cyhal_sdhc_t *obj, uint32_t startAddr, size_t l
|
||||||
Cy_SysLib_Delay(SDHC_EMMC_TRIM_DELAY_MS);
|
Cy_SysLib_Delay(SDHC_EMMC_TRIM_DELAY_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Restore interrupts after transition */
|
||||||
|
Cy_SD_Host_SetNormalInterruptMask(obj->base, regIntrSts);
|
||||||
|
|
||||||
/* Enable SD Card interrupt because it was disabled in interrupt handler */
|
/* Enable SD Card interrupt because it was disabled in interrupt handler */
|
||||||
if ((uint32_t) CYHAL_SDHC_CARD_INTERRUPT == ((uint32_t)CYHAL_SDHC_CARD_INTERRUPT & obj->irq_cause))
|
if (0U != (obj->irq_cause & CY_SD_HOST_CARD_INTERRUPT))
|
||||||
{
|
{
|
||||||
uint32_t intrStsEn = Cy_SD_Host_GetNormalInterruptEnable(obj->base);
|
uint32_t intrStsEn = Cy_SD_Host_GetNormalInterruptEnable(obj->base);
|
||||||
|
|
||||||
|
@ -1001,85 +1079,63 @@ void cyhal_sdhc_register_callback(cyhal_sdhc_t *obj, cyhal_sdhc_event_callback_t
|
||||||
|
|
||||||
void cyhal_sdhc_enable_event(cyhal_sdhc_t *obj, cyhal_sdhc_event_t event, uint8_t intrPriority, bool enable)
|
void cyhal_sdhc_enable_event(cyhal_sdhc_t *obj, cyhal_sdhc_event_t event, uint8_t intrPriority, bool enable)
|
||||||
{
|
{
|
||||||
const uint8_t eventCount = 12;
|
uint32_t interruptMask = Cy_SD_Host_GetNormalInterruptMask(obj->base);
|
||||||
const uint32_t eventMap[12][2] =
|
|
||||||
{
|
|
||||||
{ (uint32_t)CYHAL_SDHC_CMD_COMPLETE, (uint32_t)CY_SD_HOST_CMD_COMPLETE},
|
|
||||||
{ (uint32_t)CYHAL_SDHC_XFER_COMPLETE, (uint32_t)CY_SD_HOST_XFER_COMPLETE },
|
|
||||||
{ (uint32_t)CYHAL_SDHC_BGAP_EVENT, (uint32_t)CY_SD_HOST_BGAP },
|
|
||||||
{ (uint32_t)CYHAL_SDHC_DMA_INTERRUPT, (uint32_t)CY_SD_HOST_DMA_INTERRUPT },
|
|
||||||
{ (uint32_t)CYHAL_SDHC_BUF_WR_READY, (uint32_t)CY_SD_HOST_BUF_WR_READY },
|
|
||||||
{ (uint32_t)CYHAL_SDHC_BUF_RD_READY, (uint32_t)CY_SD_HOST_BUF_RD_READY },
|
|
||||||
{ (uint32_t)CYHAL_SDHC_CARD_INSERTION, (uint32_t)CY_SD_HOST_CARD_INSERTION },
|
|
||||||
{ (uint32_t)CYHAL_SDHC_CARD_REMOVAL, (uint32_t)CY_SD_HOST_CARD_REMOVAL },
|
|
||||||
{ (uint32_t)CYHAL_SDHC_CARD_INTERRUPT, (uint32_t)CY_SD_HOST_CARD_INTERRUPT },
|
|
||||||
{ (uint32_t)CYHAL_SDHC_FX_EVENT, (uint32_t)CY_SD_HOST_FX_EVENT },
|
|
||||||
{ (uint32_t)CYHAL_SDHC_CQE_EVENT, (uint32_t)CY_SD_HOST_CQE_EVENT },
|
|
||||||
{ (uint32_t)CYHAL_SDHC_ERR_INTERRUPT, (uint32_t)CY_SD_HOST_ERR_INTERRUPT },
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t interruptMask;
|
|
||||||
uint32_t interruptEnable;
|
|
||||||
|
|
||||||
interruptEnable = Cy_SD_Host_GetNormalInterruptEnable(obj->base);
|
|
||||||
interruptMask = Cy_SD_Host_GetNormalInterruptMask(obj->base);
|
|
||||||
|
|
||||||
IRQn_Type irqn = CYHAL_SDHC_IRQ_N[obj->resource.block_num];
|
IRQn_Type irqn = CYHAL_SDHC_IRQ_N[obj->resource.block_num];
|
||||||
NVIC_SetPriority(irqn, intrPriority);
|
NVIC_SetPriority(irqn, intrPriority);
|
||||||
|
|
||||||
if(enable == true)
|
if(enable == true)
|
||||||
{
|
{
|
||||||
obj->irq_cause |= event;
|
|
||||||
|
|
||||||
/* Enable specific interrupt */
|
/* Enable specific interrupt */
|
||||||
if((uint32_t) event < (uint32_t) CYHAL_SDHC_ALL_INTERRUPTS)
|
if((uint32_t) event < (uint32_t) CYHAL_SDHC_ALL_INTERRUPTS)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < eventCount; i++)
|
obj->irq_cause |= event;
|
||||||
|
uint32_t event_count = SDHC_EVENTS_NUM;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < event_count; i++)
|
||||||
{
|
{
|
||||||
const uint32_t *map_entry = eventMap[i];
|
const uint32_t *map_entry = eventMap[i];
|
||||||
if ((map_entry[0] & obj->irq_cause) > 0)
|
if ((map_entry[SDHC_EVENT] & obj->irq_cause) != 0)
|
||||||
{
|
{
|
||||||
interruptEnable |= map_entry[1];
|
interruptMask |= map_entry[SDHC_ISR];
|
||||||
interruptMask |= map_entry[1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Enable all interrupts */
|
/* Enable all interrupts */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
interruptEnable = SDIO_ALL_INTERRUPTS_ENABLE_MASK;
|
interruptMask = SDIO_SET_ALL_INTERRUPTS_MASK;
|
||||||
interruptMask = SDIO_SET_ALL_INTERRUPTS_MASK;
|
obj->irq_cause = SDIO_SET_ALL_INTERRUPTS_MASK;
|
||||||
obj->irq_cause = (uint32_t) CYHAL_SDHC_ALL_INTERRUPTS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Disable interrupt */
|
/* Disable interrupt */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
obj->irq_cause &= ~event;
|
|
||||||
|
|
||||||
if((uint32_t) event < (uint32_t) CYHAL_SDHC_ALL_INTERRUPTS)
|
if((uint32_t) event < (uint32_t) CYHAL_SDHC_ALL_INTERRUPTS)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < eventCount; i++)
|
obj->irq_cause &= ~event;
|
||||||
|
uint32_t event_count = SDHC_EVENTS_NUM;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < event_count; i++)
|
||||||
{
|
{
|
||||||
const uint32_t *map_entry = eventMap[i];
|
const uint32_t *map_entry = eventMap[i];
|
||||||
if ((map_entry[0] & obj->irq_cause) > 0)
|
if ((map_entry[SDHC_EVENT] & obj->irq_cause) != 0)
|
||||||
{
|
{
|
||||||
interruptEnable &= ~map_entry[1];
|
interruptMask &= ~map_entry[SDHC_ISR];
|
||||||
interruptMask &= ~map_entry[1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Disable all interrupts */
|
/* Disable all interrupts */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
interruptEnable = SDIO_CLEAR_ALL_INTERRUPTS_ENABLE_MASK;
|
|
||||||
interruptMask = SDIO_CLEAR_ALL_INTERRUPTS_MASK;
|
interruptMask = SDIO_CLEAR_ALL_INTERRUPTS_MASK;
|
||||||
obj->irq_cause = 0u;
|
obj->irq_cause = SDIO_CLEAR_ALL_INTERRUPTS_MASK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Cy_SD_Host_SetNormalInterruptMask(obj->base, interruptMask);
|
Cy_SD_Host_SetNormalInterruptMask(obj->base, interruptMask);
|
||||||
Cy_SD_Host_SetNormalInterruptEnable(obj->base, interruptEnable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cyhal_sdio_irq_handler()
|
static void cyhal_sdio_irq_handler()
|
||||||
|
@ -1129,6 +1185,12 @@ cy_rslt_t cyhal_sdio_init(cyhal_sdio_t *obj, cyhal_gpio_t cmd, cyhal_gpio_t clk,
|
||||||
|
|
||||||
obj->resource.type = CYHAL_RSC_INVALID;
|
obj->resource.type = CYHAL_RSC_INVALID;
|
||||||
obj->base = NULL;
|
obj->base = NULL;
|
||||||
|
obj->pin_cmd = CYHAL_NC_PIN_VALUE;
|
||||||
|
obj->pin_clk = CYHAL_NC_PIN_VALUE;
|
||||||
|
obj->pin_data0 = CYHAL_NC_PIN_VALUE;
|
||||||
|
obj->pin_data1 = CYHAL_NC_PIN_VALUE;
|
||||||
|
obj->pin_data2 = CYHAL_NC_PIN_VALUE;
|
||||||
|
obj->pin_data3 = CYHAL_NC_PIN_VALUE;
|
||||||
|
|
||||||
result = setup_pin(
|
result = setup_pin(
|
||||||
cmd, cyhal_pin_map_sdhc_card_cmd, COUNT(cyhal_pin_map_sdhc_card_cmd), &(obj->pin_cmd));
|
cmd, cyhal_pin_map_sdhc_card_cmd, COUNT(cyhal_pin_map_sdhc_card_cmd), &(obj->pin_cmd));
|
||||||
|
@ -1713,7 +1775,6 @@ void cyhal_sdio_enable_event(cyhal_sdio_t *obj, cyhal_sdio_irq_event_t event, ui
|
||||||
/* Configure interrupt-based event(s) */
|
/* Configure interrupt-based event(s) */
|
||||||
if (0U != ((uint32_t) event & (uint32_t) CYHAL_SDIO_ALL_INTERRUPTS))
|
if (0U != ((uint32_t) event & (uint32_t) CYHAL_SDIO_ALL_INTERRUPTS))
|
||||||
{
|
{
|
||||||
uint32_t interruptEnable = Cy_SD_Host_GetNormalInterruptEnable(obj->base);
|
|
||||||
uint32_t interruptMask = Cy_SD_Host_GetNormalInterruptMask(obj->base);
|
uint32_t interruptMask = Cy_SD_Host_GetNormalInterruptMask(obj->base);
|
||||||
|
|
||||||
IRQn_Type irqn = CYHAL_SDHC_IRQ_N[obj->resource.block_num];
|
IRQn_Type irqn = CYHAL_SDHC_IRQ_N[obj->resource.block_num];
|
||||||
|
@ -1721,21 +1782,16 @@ void cyhal_sdio_enable_event(cyhal_sdio_t *obj, cyhal_sdio_irq_event_t event, ui
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
interruptEnable |= event;
|
|
||||||
interruptMask |= event;
|
interruptMask |= event;
|
||||||
|
|
||||||
obj->irq_cause |= event;
|
obj->irq_cause |= event;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
interruptEnable &= ~(event);
|
|
||||||
interruptMask &= ~(event);
|
interruptMask &= ~(event);
|
||||||
|
|
||||||
obj->irq_cause &= ~event;
|
obj->irq_cause &= ~event;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cy_SD_Host_SetNormalInterruptMask(obj->base, interruptMask);
|
Cy_SD_Host_SetNormalInterruptMask(obj->base, interruptMask);
|
||||||
Cy_SD_Host_SetNormalInterruptEnable(obj->base, interruptEnable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure non-interrupt based event(s) */
|
/* Configure non-interrupt based event(s) */
|
||||||
|
|
Loading…
Reference in New Issue