From 5c899a3350a2dae5447dfd63f7086ee85ef245ff Mon Sep 17 00:00:00 2001 From: Ryan Morse Date: Tue, 27 Aug 2019 12:52:10 -0700 Subject: [PATCH] Bug fixes to interrupt/event handling in SDHC HAL --- .../psoc6csp/hal/include/cyhal_sdhc.h | 46 ++--- .../psoc6csp/hal/src/cyhal_sdhc.c | 172 ++++++++++++------ 2 files changed, 137 insertions(+), 81 deletions(-) diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/hal/include/cyhal_sdhc.h b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/hal/include/cyhal_sdhc.h index c1e400d44b..51d1a3b5b2 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/hal/include/cyhal_sdhc.h +++ b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/hal/include/cyhal_sdhc.h @@ -76,23 +76,23 @@ typedef enum /** SDHC interrupt triggers */ typedef enum { - CYHAL_SDHC_CMD_COMPLETE, //!> Command Complete - CYHAL_SDHC_XFER_COMPLETE, //!> Host read/write transfer is complete - CYHAL_SDHC_BGAP_EVENT, //!> This bit is set when both read/write transaction is stopped - CYHAL_SDHC_DMA_INTERRUPT, //!> 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_RD_READY, //!> 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_REMOVAL, //!> This bit is set if the Card Inserted in the Present State - CYHAL_SDHC_CARD_INTERRUPT, //!> The synchronized value of the DAT[1] interrupt input for SD mode - CYHAL_SDHC_INT_A, - CYHAL_SDHC_INT_B, - CYHAL_SDHC_INT_C, - CYHAL_SDHC_RE_TUNE_EVENT, //!> 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_CQE_EVENT, //!> 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_ALL_INTERRUPTS, //!> Is used to enable/disable all interrupts + CYHAL_SDHC_CMD_COMPLETE = 0x0001, //!> Command Complete + CYHAL_SDHC_XFER_COMPLETE = 0x0002, //!> Host read/write transfer is complete + CYHAL_SDHC_BGAP_EVENT = 0x0004, //!> This bit is set when both read/write transaction is stopped at the block gap + CYHAL_SDHC_DMA_INTERRUPT = 0x0008, //!> Host controller detects an SDMA Buffer Boundary during transfer + 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 = 0x0020, //!> This bit is set if the Buffer Read Enable changes from 0 to 1 + 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 = 0x0080, //!> This bit is set if the Card Inserted in the Present State register changes from 1 to 0. + CYHAL_SDHC_CARD_INTERRUPT = 0x0100, //!> The synchronized value of the DAT[1] interrupt input for SD mode + CYHAL_SDHC_INT_A = 0x0200, + CYHAL_SDHC_INT_B = 0x0400, + CYHAL_SDHC_INT_C = 0x0800, + CYHAL_SDHC_RE_TUNE_EVENT = 0x1000, //!> This bit is set if the Re-Tuning Request changes from 0 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 = 0x4000, //!> This status is set if Command Queuing/Crypto event has occurred + CYHAL_SDHC_ERR_INTERRUPT = 0x8000, //!> If any of the bits in the Error Interrupt Status register are set + CYHAL_SDHC_ALL_INTERRUPTS = 0xFFFF, //!> Is used to enable/disable all interrupts } cyhal_sdhc_event_t; /** \} group_hal_sdhc_enums */ @@ -121,7 +121,7 @@ typedef struct { bool enableLedControl; //!< Drive one IO to indicate when the card is being accessed 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 } cyhal_sdhc_config_t; @@ -186,7 +186,7 @@ void cyhal_sdhc_free(cyhal_sdhc_t *obj); * @param[in] obj The SDHC object * @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[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 */ 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] address The address to write data to * @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 */ 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] 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 */ 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] address The address to read data from * @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 */ 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] address The address to write data to * @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 */ cy_rslt_t cyhal_sdhc_write_async(const cyhal_sdhc_t *obj, uint32_t address, const uint8_t *data, size_t *length); diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/hal/src/cyhal_sdhc.c b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/hal/src/cyhal_sdhc.c index 167bfb1452..b3bc8c5ad9 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/hal/src/cyhal_sdhc.c +++ b/targets/TARGET_Cypress/TARGET_PSOC6/psoc6csp/hal/src/cyhal_sdhc.c @@ -135,6 +135,15 @@ extern "C" #define CYHAL_SDIO_DS_CB_ORDER (0U) #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 */ 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]; + +/* 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) { 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_syspm_status_t cyhal_sdio_syspm_callback(cy_stc_syspm_callback_params_t *params, 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 @@ -484,21 +512,20 @@ static void cyhal_sdhc_irq_handler(void) uint32_t interruptStatus = Cy_SD_Host_GetNormalInterruptStatus(blockAddr); uint32_t userInterruptStatus = interruptStatus & obj->irq_cause; + cyhal_sdhc_event_t user_events = get_event_from_isr(userInterruptStatus); if (obj->callback_data.callback != NULL) { cyhal_sdhc_event_callback_t callback = (cyhal_sdhc_event_callback_t) obj->callback_data.callback; + /* 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 */ - 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. - * The SD Card interrupt is enabled in the bulk transfer function later on - * the next data transfer. - */ + /* To clear SD Card interrupt need to disable SD Card Interrupt Enable bit */ if (0U != (interruptStatus & CY_SD_HOST_CARD_INTERRUPT)) { uint32_t interruptMask = Cy_SD_Host_GetNormalInterruptEnable(blockAddr); @@ -507,7 +534,26 @@ static void cyhal_sdhc_irq_handler(void) /* Disable SD Card interrupt */ 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, @@ -680,7 +726,7 @@ cy_rslt_t cyhal_sdhc_init(cyhal_sdhc_t *obj, /* Do not support eMMC card */ obj->emmc = config->isEmmc; - obj->dmaType = CY_SD_HOST_DMA_SDMA; + obj->dmaType = CY_SD_HOST_DMA_ADMA2; /* Configure SD Host to operate */ 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_en_sd_host_status_t driverRet; 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.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.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); 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 */ - 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); @@ -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_en_sd_host_status_t driverRet; 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.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.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); 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 */ - 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); @@ -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; uint32_t i = SDHC_RETRY_TIMES; uint32_t cardStatus; + uint32_t regIntrSts = Cy_SD_Host_GetNormalInterruptMask(obj->base); if (obj->emmc) { 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); if (CY_SD_HOST_SUCCESS != driverRet) { ret = CY_RSLT_TYPE_ERROR; } - - driverRet = Cy_SD_Host_PollCmdComplete(obj->base); + else + { + driverRet = Cy_SD_Host_PollCmdComplete(obj->base); + } 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); } + /* Restore interrupts after transition */ + Cy_SD_Host_SetNormalInterruptMask(obj->base, regIntrSts); + /* 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); @@ -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) { - const uint8_t eventCount = 12; - 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); + uint32_t interruptMask = Cy_SD_Host_GetNormalInterruptMask(obj->base); IRQn_Type irqn = CYHAL_SDHC_IRQ_N[obj->resource.block_num]; NVIC_SetPriority(irqn, intrPriority); if(enable == true) { - obj->irq_cause |= event; - /* Enable specific interrupt */ 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]; - if ((map_entry[0] & obj->irq_cause) > 0) + if ((map_entry[SDHC_EVENT] & obj->irq_cause) != 0) { - interruptEnable |= map_entry[1]; - interruptMask |= map_entry[1]; + interruptMask |= map_entry[SDHC_ISR]; } } } /* Enable all interrupts */ else { - interruptEnable = SDIO_ALL_INTERRUPTS_ENABLE_MASK; - interruptMask = SDIO_SET_ALL_INTERRUPTS_MASK; - obj->irq_cause = (uint32_t) CYHAL_SDHC_ALL_INTERRUPTS; + interruptMask = SDIO_SET_ALL_INTERRUPTS_MASK; + obj->irq_cause = SDIO_SET_ALL_INTERRUPTS_MASK; } } /* Disable interrupt */ else { - obj->irq_cause &= ~event; - 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]; - if ((map_entry[0] & obj->irq_cause) > 0) + if ((map_entry[SDHC_EVENT] & obj->irq_cause) != 0) { - interruptEnable &= ~map_entry[1]; - interruptMask &= ~map_entry[1]; + interruptMask &= ~map_entry[SDHC_ISR]; } } } /* Disable all interrupts */ else { - interruptEnable = SDIO_CLEAR_ALL_INTERRUPTS_ENABLE_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_SetNormalInterruptEnable(obj->base, interruptEnable); } 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->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( 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) */ 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); 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) { - interruptEnable |= event; interruptMask |= event; - obj->irq_cause |= event; } else { - interruptEnable &= ~(event); interruptMask &= ~(event); - obj->irq_cause &= ~event; } Cy_SD_Host_SetNormalInterruptMask(obj->base, interruptMask); - Cy_SD_Host_SetNormalInterruptEnable(obj->base, interruptEnable); } /* Configure non-interrupt based event(s) */