/***************************************************************************//** * \file cyhal_sdio.h * * \brief * Provides a high level interface for interacting with the Cypress SDIO interface. * This interface abstracts out the chip specific details. If any chip specific * functionality is necessary, or performance is critical the low level functions * can be used directly. * ******************************************************************************** * \copyright * Copyright 2018-2019 Cypress Semiconductor Corporation * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ /** * \addtogroup group_hal_sdio SDIO (Secure Digital Input Output) * \ingroup group_hal * \{ * High level interface for interacting with the Cypress SDIO interface. * * \defgroup group_hal_sdio_macros Macros * \defgroup group_hal_sdio_functions Functions * \defgroup group_hal_sdio_data_structures Data Structures * \defgroup group_hal_sdio_enums Enumerated Types */ #pragma once #include #include #include "cy_result.h" #include "cyhal_hw_types.h" #include "cyhal_modules.h" #if defined(__cplusplus) extern "C" { #endif /** * \addtogroup group_hal_sdio_macros * \{ */ #define CYHAL_SDIO_RET_NO_ERRORS (0x00) /**< No error*/ #define CYHAL_SDIO_RET_NO_SP_ERRORS (0x01) /**< Non-specific error code*/ #define CYHAL_SDIO_RET_CMD_CRC_ERROR (0x02) /**< There was a CRC error on the Command/Response*/ #define CYHAL_SDIO_RET_CMD_IDX_ERROR (0x04) /**< The index for the command didn't match*/ #define CYHAL_SDIO_RET_CMD_EB_ERROR (0x08) /**< There was an end bit error on the command*/ #define CYHAL_SDIO_RET_DAT_CRC_ERROR (0x10) /**< There was a data CRC Error*/ #define CYHAL_SDIO_RET_CMD_TIMEOUT (0x20) /**< The command didn't finish before the timeout period was over*/ #define CYHAL_SDIO_RET_DAT_TIMEOUT (0x40) /**< The data didn't finish before the timeout period was over*/ #define CYHAL_SDIO_RET_RESP_FLAG_ERROR (0x80) /**< There was an error in the resposne flag for command 53*/ #define CYHAL_SDIO_CLOCK_ERROR (0x100) /**< Failed to initial clock for SDIO */ #define CYHAL_SDIO_BAD_ARGUMENT (0x200) /**< Bad argument passed for SDIO */ #define CYHAL_SDIO_SEMA_NOT_INITED (0x400) /**< Semaphore is not initiated */ #define CYHAL_SDIO_FUNC_NOT_SUPPORTED (0x800) /**< Function is not supported */ /* HAL return value defines */ /** Incorrect parameter value define */ #define CYHAL_SDIO_RSLT_ERR_BAD_PARAM CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, \ CYHAL_RSLT_MODULE_SDIO, \ CYHAL_SDIO_BAD_ARGUMENT) /** Clock initialization error define */ #define CYHAL_SDIO_RSLT_ERR_CLOCK CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, \ CYHAL_RSLT_MODULE_SDIO, \ CYHAL_SDIO_CLOCK_ERROR) /** Semaphore not initiated error define */ #define CYHAL_SDIO_RSLT_ERR_SEMA_NOT_INITED CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, \ CYHAL_RSLT_MODULE_SDIO, \ CYHAL_SDIO_SEMA_NOT_INITED) /** Error define based on SDIO lower function return value */ #define CYHAL_SDIO_RSLT_ERR_FUNC_RET(retVal) CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, \ CYHAL_RSLT_MODULE_SDIO, (retVal) ) /** \} group_hal_sdio_macros */ /** * \addtogroup group_hal_sdio_enums * \{ */ /** Commands that can be issued */ typedef enum { CYHAL_SDIO_CMD_GO_IDLE_STATE = 0, //!> Go to idle state CYHAL_SDIO_CMD_SEND_RELATIVE_ADDR = 3, //!> Send a relative address CYHAL_SDIO_CMD_IO_SEND_OP_COND = 5, //!> Send an OP IO CYHAL_SDIO_CMD_SELECT_CARD = 7, //!> Send a card select CYHAL_SDIO_CMD_GO_INACTIVE_STATE = 15, //!> Go to inactive state CYHAL_SDIO_CMD_IO_RW_DIRECT = 52, //!> Perform a direct read/write CYHAL_SDIO_CMD_IO_RW_EXTENDED = 53, //!> Perform an extended read/write } cyhal_sdio_command_t; /** Types of transfer that can be performed */ typedef enum { CYHAL_READ, //!> Read from the card CYHAL_WRITE //!> Write to the card } cyhal_transfer_t; /** Events that can cause an SDIO interrupt */ typedef enum { CYHAL_SDIO_CMD_COMPLETE = 0x0001, //!> Command Complete CYHAL_SDIO_XFER_COMPLETE = 0x0002, //!> Host read/write transfer is complete CYHAL_SDIO_BGAP_EVENT = 0x0004, //!> This bit is set when both read/write transaction is stopped CYHAL_SDIO_DMA_INTERRUPT = 0x0008, //!> Host controller detects an SDMA Buffer Boundary during transfer CYHAL_SDIO_BUF_WR_READY = 0x0010, //!> This bit is set if the Buffer Write Enable changes from 0 to 1 CYHAL_SDIO_BUF_RD_READY = 0x0020, //!> This bit is set if the Buffer Read Enable changes from 0 to 1 CYHAL_SDIO_CARD_INSERTION = 0x0040, //!> This bit is set if the Card Inserted in the Present State CYHAL_SDIO_CARD_REMOVAL = 0x0080, //!> This bit is set if the Card Inserted in the Present State CYHAL_SDIO_CARD_INTERRUPT = 0x0100, //!> The synchronized value of the DAT[1] interrupt input for SD mode CYHAL_SDIO_INT_A = 0x0200, //!> Reserved: set to 0 CYHAL_SDIO_INT_B = 0x0400, //!> Reserved: set to 0 CYHAL_SDIO_INT_C = 0x0800, //!> Reserved: set to 0, CYHAL_SDIO_RE_TUNE_EVENT = 0x1000, //!> Reserved: set to 0, CYHAL_SDIO_FX_EVENT = 0x2000, //!> This status is set when R[14] of response register is set to 1 CYHAL_SDIO_CQE_EVENT = 0x4000, //!> This status is set if Command Queuing/Crypto event has occurred CYHAL_SDIO_ERR_INTERRUPT = 0x8000, //!> If any of the bits in the Error Interrupt Status register are set CYHAL_SDIO_ALL_INTERRUPTS = 0xE1FF, //!> Is used to enable/disable all interrupts } cyhal_sdio_irq_event_t; /** \} group_hal_sdio_enums */ /** * \addtogroup group_hal_sdio_data_structures * \{ */ /** SDIO controller initial configuration */ typedef struct { uint32_t frequencyhal_hz; //!< Clock frequency, in hertz uint16_t block_size; //!< Block size } cyhal_sdio_cfg_t; /** Handler for SDIO interrupts */ typedef void (*cyhal_sdio_irq_handler_t)(void *handler_arg, cyhal_sdio_irq_event_t event); /** \} group_hal_sdio_data_structures */ /** * \addtogroup group_hal_sdio_functions * \{ */ /** Initialize the SDIO peripheral * * @param[out] obj The SDIO object * @param[out] clk The pin connected to the clk signal * @param[in] cmd The pin connected to the command signal * @param[in] data0 The pin connected to the data0 signal * @param[in] data1 The pin connected to the data1 signal * @param[in] data2 The pin connected to the data2 signal * @param[in] data3 The pin connected to the data3 signal * @return The status of the init request */ cy_rslt_t cyhal_sdio_init(cyhal_sdio_t *obj, cyhal_gpio_t cmd, cyhal_gpio_t clk, cyhal_gpio_t data0, cyhal_gpio_t data1, cyhal_gpio_t data2, cyhal_gpio_t data3); /** Release the SDIO peripheral, not currently invoked. It requires further * resource management. * * @param[in,out] obj The SDIO object */ void cyhal_sdio_free(cyhal_sdio_t *obj); /** Configure the SDIO block. * * @param[in,out] obj The SDIO object * @param[in] config The sdio configuration to apply * @return The status of the configure request */ cy_rslt_t cyhal_sdio_configure(cyhal_sdio_t *obj, const cyhal_sdio_cfg_t *config); /** Sends a command to the SDIO block. * * @param[in,out] obj The SDIO object * @param[in] direction The direction of transfer (read/write) * @param[in] command The SDIO command to send * @param[in] argument The argument to the command * @param[out] response The response from the SDIO device * @return The status of the configure request */ cy_rslt_t cyhal_sdio_send_cmd(const cyhal_sdio_t *obj, cyhal_transfer_t direction, cyhal_sdio_command_t command, uint32_t argument, uint32_t *response); /** Performs a bulk data transfer (CMD=53) to the SDIO block. * * @param[in,out] obj The SDIO object * @param[in] direction The direction of transfer (read/write) * @param[in] argument The argument to the command * @param[in] data The data to send to the SDIO device. The data buffer * should be aligned to the block size (64 bytes) if data * size is greater that block size (64 bytes). * @param[in] length The number of bytes to send * @param[out] response The response from the SDIO device * @return The status of the configure request */ cy_rslt_t cyhal_sdio_bulk_transfer(cyhal_sdio_t *obj, cyhal_transfer_t direction, uint32_t argument, const uint32_t *data, uint16_t length, uint32_t *response); /** Performs a bulk asynchronus data transfer (CMD=53) to the SDIO block. * * @param[in,out] obj The SDIO object * @param[in] direction The direction of transfer (read/write) * @param[in] argument The argument to the command * @param[in] data The data to send to the SDIO device * @param[in] length The number of bytes to send * @return The status of the configure request */ cy_rslt_t cyhal_sdio_transfer_async(cyhal_sdio_t *obj, cyhal_transfer_t direction, uint32_t argument, const uint32_t *data, uint16_t length); /** Checks if the specified SDIO is in use * * @param[in] obj The SDIO peripheral to check * @return Indication of whether the SDIO is still transmitting */ bool cyhal_sdio_is_busy(const cyhal_sdio_t *obj); /** Abort an SDIO transfer * * @param[in] obj The SDIO peripheral to stop * @return The status of the abort_async request */ cy_rslt_t cyhal_sdio_abort_async(const cyhal_sdio_t *obj); /** The sdio interrupt handler registration * * @param[in] obj The SDIO object * @param[in] handler The callback handler which will be invoked when the interrupt fires * @param[in] handler_arg Generic argument that will be provided to the handler when called */ void cyhal_sdio_register_irq(cyhal_sdio_t *obj, cyhal_sdio_irq_handler_t handler, void *handler_arg); /** Configure sdio interrupt. * * @param[in] obj The SDIO object * @param[in] event The sdio IRQ type * @param[in] enable Set to non-zero to enable events, or zero to disable them */ void cyhal_sdio_irq_enable(cyhal_sdio_t *obj, cyhal_sdio_irq_event_t event, bool enable); /** \} group_hal_sdio_functions */ #if defined(__cplusplus) } #endif /** \} group_hal_sdio */