Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers/sdmmc: store SDMMC device descriptor references in XFA #19899

Merged
merged 1 commit into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 59 additions & 8 deletions drivers/include/sdmmc/sdmmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
#include "byteorder.h"
#include "macros/units.h"
#include "periph_conf.h"
#include "xfa.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -1387,22 +1388,72 @@ typedef struct sdmmc_dev {
} sdmmc_dev_t;

/**
* @brief Retrieve SDIO/SD/MMC device descriptor from the peripheral index
* @brief SDIO/SD/MMC device descriptor references as read-only XFA
*
* The array contains the references to all SDIO/SD/MMC device descriptors.
* The i-th device in this array can then be accessed with `sdmmc_devs[i]`.
* The number of SDIO/SD/MMC device descriptor references defined in this array
* is `XFA_LEN(sdmmc_devs)`, see @ref SDMMC_NUMOF.
*
* @warning To ensure to have the references to all SDIO/SD/MMC device
* descriptors in this array, the low-level SDIO/SD/MMC peripheral
* drivers must define the references to their SDIO/SD/MMC
* device descriptors as XFA members by using the macro
* `XFA_CONST(sdmmc_devs, 0)` as shown in the example below.
*
* For example, if the low-level
* SDIO/SD/MMC peripheral driver defines an MCU-specific SDIO/SD/MMC
* device descriptor structure `_mcu_sdmmc_dev_t` and defines the device
* descriptors in an array `_mcu_sdmmc_dev`, it must define the references
* to them as members of the XFA `sdmmc_devs` as follows:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
* typedef struct {
* sdmmc_dev_t sdmmc_dev; // Inherited sdmmc_dev_t struct
* const sdmmc_conf_t *config; // SDIO/SD/MMC peripheral config
* ...
* } _mcu_sdmmc_dev_t;
*
* static _mcu_sdmmc_dev_t _mcu_sdmmc_devs[] = {
* {
* ...
* },
* {
* ...
* },
* };
*
* XFA_CONST(sdmmc_devs, 0) sdmmc_dev_t * const _sdmmc_1 = (sdmmc_dev_t * const)&_mcu_sdmmc_devs[0];
* XFA_CONST(sdmmc_devs, 0) sdmmc_dev_t * const _sdmmc_2 = (sdmmc_dev_t * const)&_mcu_sdmmc_devs[1];
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* The function converts the peripheral index to the corresponding SDIO/SD/MMC
* device descriptor.
*/
#if !DOXYGEN
XFA_USE_CONST(sdmmc_dev_t * const, sdmmc_devs);
#else
sdmmc_dev_t sdmmc_devs[];
#endif

/**
* @brief Number of SDIO/SD/MMC devices defined
*/
#define SDMMC_NUMOF XFA_LEN(sdmmc_dev_t *, sdmmc_devs)

/**
* @brief Retrieve SDIO/SD/MMC device descriptor reference from device index
*
* @note This function has to be implemented by the low-level SDIO/SD/MMC
* peripheral driver to allow to convert a SDIO/SD/MMC peripheral index
* to the corresponding SDIO/SD/MMC device descriptor.
* The function converts the device index to the corresponding SDIO/SD/MMC
* device descriptor. See also @ref sdmmc_devs.
*
* @param[in] num SDIO/SD/MMC peripheral index
*
* @retval pointer to the SDIO/SD/MMC device descriptor at index @p num on success
* @retval NULL if @p num is greater than the number of SDIO/SD/MMC device
* descriptors
*/
sdmmc_dev_t *sdmmc_get_dev(unsigned num);
static inline sdmmc_dev_t *sdmmc_get_dev(unsigned num)
{
return (num < SDMMC_NUMOF) ? sdmmc_devs[num] : NULL;
}

/**
* @brief Basic initialization of the given SDIO/SD/MMC device
Expand Down Expand Up @@ -1569,7 +1620,7 @@ int sdmmc_send_acmd(sdmmc_dev_t *dev, sdmmc_cmd_t cmd_idx, uint32_t arg,
*
* @warning If the low-level SDIO/SD/MMC peripheral driver defines its own
* @ref sdmmc_driver_t::card_init function, this function is used
* instead. \n
* instead.\n
* However, the low-level SDIO/SD/MMC peripheral driver should
* define its own @ref sdmmc_driver_t::card_init function only in
* very special cases, e.g. when special hardware handling is
Expand Down
3 changes: 3 additions & 0 deletions drivers/sdmmc/sdmmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ typedef struct __attribute__((packed)) {
uint8_t reserved[32]; /**< reserved [255:0] */
} sdmmc_sw_status_t;

/* Definition of the XFA for the SDIO/SD/MMC device descriptor references */
XFA_INIT_CONST(sdmmc_dev_t * const, sdmmc_devs);

/* forward declaration of internal functions */
static int _send_cmd(sdmmc_dev_t *dev, sdmmc_cmd_t cmd_idx, uint32_t arg,
sdmmc_resp_t resp_type, uint32_t *resp);
Expand Down