Some checks failed
Basic Checks / license-check (push) Has been cancelled
Basic Checks / include-check (push) Has been cancelled
Basic Checks / style-check (push) Has been cancelled
Basic Checks / docs-check (push) Has been cancelled
Basic Checks / python-tests (push) Has been cancelled
Basic Checks / pin-validation (push) Has been cancelled
Basic Checks / cmake-checks (push) Has been cancelled
Basic Checks / frozen-tools-check (push) Has been cancelled
Publish or Update docker image for head of branch / prepare-tags (push) Has been cancelled
Release or update docker image for a released mbed-os version / prepare-tags (push) Has been cancelled
Publish or Update docker image for head of branch / build-container (push) Has been cancelled
Publish or Update docker image for head of branch / test-container (linux/amd64) (push) Has been cancelled
Publish or Update docker image for head of branch / test-container (linux/arm64) (push) Has been cancelled
Publish or Update docker image for head of branch / deploy-container (push) Has been cancelled
Release or update docker image for a released mbed-os version / build-container (push) Has been cancelled
Release or update docker image for a released mbed-os version / test-container (linux/amd64) (push) Has been cancelled
Release or update docker image for a released mbed-os version / test-container (linux/arm64) (push) Has been cancelled
Release or update docker image for a released mbed-os version / deploy-container (push) Has been cancelled
Prune temporary docker images / prune-images (push) Has been cancelled
348 lines
16 KiB
C
348 lines
16 KiB
C
/***************************************************************************//**
|
|
* \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-2021 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 to the Secure Digital Input Output (SDIO).
|
|
*
|
|
* This driver allows commands to be sent over the SDIO bus; the supported commands
|
|
* can be found in \ref cyhal_sdio_command_t. Bulk data transfer is also supported
|
|
* via cyhal_sdio_bulk_transfer().
|
|
*
|
|
* The SDIO protocol is an extension of the SD
|
|
* interface for general I/O functions. Refer to the SD Specifications Part 1 SDIO
|
|
* Specifications Version 4.10 for more information on the SDIO protocol and specifications.
|
|
*
|
|
*
|
|
* \section subsection_sdio_features Features
|
|
* * Supports 4-bit interface
|
|
* * Supports Ultra High Speed (UHS-I) mode
|
|
* * Supports Default Speed (DS), High Speed (HS), SDR12, SDR25 and SDR50 speed modes
|
|
* * Supports SDIO card interrupts in both 1-bit and 4-bit modes
|
|
* * Supports Standard capacity (SDSC), High capacity (SDHC) and Extended capacity (SDXC) memory
|
|
*
|
|
* \section subsection_sdio_quickstart Quick Start
|
|
*
|
|
* \ref cyhal_sdio_init initializes the SDIO peripheral and passes a pointer to the SDIO block through the **obj** object of type \ref cyhal_sdio_t.
|
|
*
|
|
* \section subsection_sdio_code_snippets Code Snippets
|
|
*
|
|
* \subsection subsection_sdio_use_case_1 Snippet1: Simple SDIO Initialization example
|
|
* The following snippet shows how to initialize the SDIO interface with a pre-defined configuration
|
|
*
|
|
* \snippet hal_sdio.c snippet_cyhal_sdio_simple_init
|
|
*
|
|
* \subsection subsection_sdio_use_case_2 Snippet2: Configure Interrupt
|
|
* The following snippet shows how to configure an interrupt and handle specific events. Refer \ref cyhal_sdio_event_t for different types of events.
|
|
*
|
|
* \snippet hal_sdio.c snippet_cyhal_sdio_interrupt_callback
|
|
*
|
|
* \subsection subsection_sdio_use_case_3 Snippet3: Sending Commands
|
|
* The following snippet shows how to send a particular command. Some steps of the card initialization have been provided for reference. Refer \ref cyhal_sdio_command_t for different commands.
|
|
*
|
|
* \snippet hal_sdio.c snippet_cyhal_sdio_send_command
|
|
*
|
|
* \subsection subsection_sdio_use_case_4 Snippet4: Bulk Data Transfer
|
|
* The following snippet shows how to start a bulk data transfer.
|
|
*
|
|
* \snippet hal_sdio.c snippet_cyhal_sdio_bulk_transfer
|
|
*
|
|
* \subsection subsection_sdio_use_case_5 Snippet5: Async Data Transfer
|
|
*
|
|
* The following snippet shows how to start an async data transfer.
|
|
* \snippet hal_sdio.c snippet_cyhal_sdio_async_transfer
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include "cy_result.h"
|
|
#include "cyhal_hw_types.h"
|
|
|
|
#if defined(__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*******************************************************************************
|
|
* Defines
|
|
*******************************************************************************/
|
|
|
|
/* HAL return value defines */
|
|
|
|
/** \addtogroup group_hal_results_sdio SDIO HAL Results
|
|
* SDIO specific return codes
|
|
* \ingroup group_hal_results
|
|
* \{ *//**
|
|
*/
|
|
|
|
/** Incorrect parameter value define */
|
|
#define CYHAL_SDIO_RSLT_ERR_BAD_PARAM \
|
|
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SDIO, 0))
|
|
/** Define to indicate canceled operation */
|
|
#define CYHAL_SDIO_RSLT_CANCELED \
|
|
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SDIO, 1))
|
|
/** Transfers are not allowed after the SDIO block has allowed power mode transition. */
|
|
#define CYHAL_SDIO_RSLT_ERR_PM_PENDING \
|
|
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SDIO, 2))
|
|
/** Requested feature is not supported on this hardware. */
|
|
#define CYHAL_SDIO_RSLT_ERR_UNSUPPORTED \
|
|
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SDIO, 3))
|
|
/** Failure in command send. */
|
|
#define CYHAL_SDIO_RSLT_ERR_COMMAND_SEND \
|
|
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SDIO, 4))
|
|
/** SDIO Configuration error. */
|
|
#define CYHAL_SDIO_RSLT_ERR_CONFIG \
|
|
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_SDIO, 5))
|
|
|
|
/**
|
|
* \}
|
|
*/
|
|
|
|
|
|
/*******************************************************************************
|
|
* Enumerations
|
|
*******************************************************************************/
|
|
|
|
/** 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;
|
|
|
|
/** Types of events that could be asserted by SDIO */
|
|
typedef enum {
|
|
/* Interrupt-based thread events */
|
|
CYHAL_SDIO_CMD_COMPLETE = 0x00001, //!< Command Complete
|
|
CYHAL_SDIO_XFER_COMPLETE = 0x00002, //!< Host read/write transfer is complete
|
|
CYHAL_SDIO_BGAP_EVENT = 0x00004, //!< This bit is set when both read/write transaction is stopped
|
|
CYHAL_SDIO_DMA_INTERRUPT = 0x00008, //!< Host controller detects an SDMA Buffer Boundary during transfer
|
|
CYHAL_SDIO_BUF_WR_READY = 0x00010, //!< This bit is set if the Buffer Write Enable changes from 0 to 1
|
|
CYHAL_SDIO_BUF_RD_READY = 0x00020, //!< This bit is set if the Buffer Read Enable changes from 0 to 1
|
|
CYHAL_SDIO_CARD_INSERTION = 0x00040, //!< This bit is set if the Card Inserted in the Present State
|
|
CYHAL_SDIO_CARD_REMOVAL = 0x00080, //!< This bit is set if the Card Inserted in the Present State
|
|
CYHAL_SDIO_CARD_INTERRUPT = 0x00100, //!< The synchronized value of the DAT[1] interrupt input for SD mode
|
|
CYHAL_SDIO_INT_A = 0x00200, //!< Reserved: set to 0
|
|
CYHAL_SDIO_INT_B = 0x00400, //!< Reserved: set to 0
|
|
CYHAL_SDIO_INT_C = 0x00800, //!< Reserved: set to 0
|
|
CYHAL_SDIO_RE_TUNE_EVENT = 0x01000, //!< Reserved: set to 0
|
|
CYHAL_SDIO_FX_EVENT = 0x02000, //!< This status is set when R[14] of response register is set to 1
|
|
CYHAL_SDIO_CQE_EVENT = 0x04000, //!< This status is set if Command Queuing/Crypto event has occurred
|
|
CYHAL_SDIO_ERR_INTERRUPT = 0x08000, //!< If any of the bits in the Error Interrupt Status register are set
|
|
|
|
/* Non-interrupt-based thread events */
|
|
CYHAL_SDIO_GOING_DOWN = 0x10000, //!< The interface is going away (eg: powering down for some period of time)
|
|
CYHAL_SDIO_COMING_UP = 0x20000, //!< The interface is back up (eg: came back from a low power state)
|
|
|
|
CYHAL_SDIO_ALL_INTERRUPTS = 0x0E1FF, //!< Is used to enable/disable all interrupts events
|
|
} cyhal_sdio_event_t;
|
|
|
|
|
|
/*******************************************************************************
|
|
* Data Structures
|
|
*******************************************************************************/
|
|
|
|
/** @brief SDIO controller initial configuration */
|
|
typedef struct
|
|
{
|
|
uint32_t frequencyhal_hz; //!< Clock frequency, in hertz
|
|
uint16_t block_size; //!< Block size
|
|
} cyhal_sdio_cfg_t;
|
|
|
|
/** Callback for SDIO events */
|
|
typedef void (*cyhal_sdio_event_callback_t)(void *callback_arg, cyhal_sdio_event_t event);
|
|
|
|
|
|
/*******************************************************************************
|
|
* Data Structures
|
|
*******************************************************************************/
|
|
/** Initialize the SDIO peripheral
|
|
*
|
|
* @param[out] obj Pointer to an SDIO object.
|
|
* The caller must allocate the memory for this object but the init
|
|
* function will initialize its contents.
|
|
* @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
|
|
*
|
|
* Returns \ref CY_RSLT_SUCCESS on successful operation. Refer \ref subsection_sdio_use_case_1 for more information.
|
|
*/
|
|
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 block.
|
|
*
|
|
* @param[in,out] obj The SDIO object
|
|
*/
|
|
void cyhal_sdio_free(cyhal_sdio_t *obj);
|
|
|
|
/** Configure the SDIO block with required parameters. Refer \ref cyhal_sdio_cfg_t for more information.
|
|
*
|
|
* @param[in,out] obj The SDIO object
|
|
* @param[in] config The SDIO configuration to apply
|
|
* @return The status of the configure request.
|
|
*
|
|
* Returns \ref CY_RSLT_SUCCESS on successful operation.
|
|
*/
|
|
cy_rslt_t cyhal_sdio_configure(cyhal_sdio_t *obj, const cyhal_sdio_cfg_t *config);
|
|
|
|
/** Sends command to the SDIO device. See \ref cyhal_sdio_command_t for list of available commands.
|
|
*
|
|
* This will block until the command is completed.
|
|
*
|
|
* @param[in,out] obj The SDIO object
|
|
* @param[in] direction The direction of transfer (read/write)
|
|
* @param[in] command The command to send to the SDIO device
|
|
* @param[in] argument The argument to the command
|
|
* @param[out] response The response from the SDIO device
|
|
* @return The status of the command transfer.
|
|
*
|
|
* Returns \ref CY_RSLT_SUCCESS on successful operation. Refer \ref subsection_sdio_use_case_3 for more information.
|
|
*/
|
|
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. Sends \ref CYHAL_SDIO_CMD_IO_RW_EXTENDED command (CMD=53) which allows writing and reading of a large number of I/O registers with a single command.
|
|
*
|
|
* This will block until the transfer is completed.
|
|
*
|
|
* @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. A bulk transfer is done in block
|
|
* size (default: 64 bytes) chunks for better performance. Therefore,
|
|
* the size of the data buffer passed into this function must be at least
|
|
* `length` bytes and a multiple of the block size. For example, when
|
|
* requesting to read 100 bytes of data with a block size 64 bytes, the
|
|
* data buffer needs to be at least 128 bytes. The first 100 bytes of data
|
|
* in the buffer will be the requested data.
|
|
* @param[in] length The number of bytes to send
|
|
* @param[out] response The response from the SDIO device
|
|
* @return The status of the bulk transfer operation.
|
|
*
|
|
* Returns \ref CY_RSLT_SUCCESS on successful operation. Refer \ref subsection_sdio_use_case_4 for more information.
|
|
*/
|
|
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 asynchronous data transfer by issuing the \ref CYHAL_SDIO_CMD_IO_RW_EXTENDED command(CMD=53) to the SDIO block.
|
|
* After exiting this function the \ref CYHAL_SDIO_CMD_COMPLETE and \ref CYHAL_SDIO_XFER_COMPLETE events are not asserted.
|
|
*
|
|
* The \ref CYHAL_SDIO_CMD_COMPLETE and \ref CYHAL_SDIO_XFER_COMPLETE events are enabled
|
|
* after the asynchronous transfer is complete and in the condition they were
|
|
* enabled in before the transfer operation started. Handle these events in the interrupt callback.
|
|
*
|
|
* When the transfer is complete, the \ref CYHAL_SDIO_XFER_COMPLETE event will be raised.
|
|
* See \ref cyhal_sdio_register_callback and \ref cyhal_sdio_enable_event.
|
|
*
|
|
* @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 async tranfer operation.
|
|
*
|
|
* Returns \ref CY_RSLT_SUCCESS on successful operation. Refer \ref subsection_sdio_use_case_5 for more information.
|
|
*/
|
|
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 true if SDIO is in use. false, otherwise.
|
|
*/
|
|
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.
|
|
*
|
|
* Returns \ref CY_RSLT_SUCCESS on successful operation.
|
|
*/
|
|
cy_rslt_t cyhal_sdio_abort_async(const cyhal_sdio_t *obj);
|
|
|
|
/** Register an SDIO event callback to be invoked when the event is triggered.
|
|
*
|
|
* This function will be called when one of the events enabled by \ref cyhal_sdio_enable_event occurs.
|
|
*
|
|
* @param[in] obj The SDIO object
|
|
* @param[in] callback The callback function which will be invoked when the event triggers
|
|
* @param[in] callback_arg Generic argument that will be provided to the callback when executed
|
|
*
|
|
* Refer \ref subsection_sdio_use_case_2 for more implementation.
|
|
*/
|
|
void cyhal_sdio_register_callback(cyhal_sdio_t *obj, cyhal_sdio_event_callback_t callback, void *callback_arg);
|
|
|
|
/** Enables callbacks to be triggered for specified SDIO events. Refer \ref cyhal_sdio_event_t for all events.
|
|
*
|
|
* @param[in] obj The SDIO object
|
|
* @param[in] event The SDIO event type
|
|
* @param[in] intr_priority The priority for NVIC interrupt events
|
|
* @param[in] enable Set to true to enable events, or false to disable them
|
|
*
|
|
* Refer \ref subsection_sdio_use_case_2 for more information.
|
|
*/
|
|
void cyhal_sdio_enable_event(cyhal_sdio_t *obj, cyhal_sdio_event_t event, uint8_t intr_priority, bool enable);
|
|
|
|
/*******************************************************************************
|
|
* Backward compatibility macro. The following code is DEPRECATED and must
|
|
* not be used in new projects
|
|
*******************************************************************************/
|
|
/** \cond INTERNAL */
|
|
#define cyhal_sdio_register_irq cyhal_sdio_register_callback
|
|
#define cyhal_sdio_irq_enable(obj, event, enable) cyhal_sdio_enable_event(obj, event, CYHAL_ISR_PRIORITY_DEFAULT, enable)
|
|
typedef cyhal_sdio_event_t cyhal_sdio_irq_event_t;
|
|
typedef cyhal_sdio_event_callback_t cyhal_sdio_irq_handler_t;
|
|
/** \endcond */
|
|
|
|
#if defined(__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
#ifdef CYHAL_SDIO_IMPL_HEADER
|
|
#include CYHAL_SDIO_IMPL_HEADER
|
|
#endif /* CYHAL_SDIO_IMPL_HEADER */
|
|
|
|
/** \} group_hal_sdio */
|