Skip to content

Commit 6df147b

Browse files
committed
samples: sdhc: add SDIO CMD52 read/write sample.
The sample performs the following: - Initializes the SDIO interface. - Reads a register using CMD52. - Writes a value using CMD52. - Verifies the write by reading back the reg. Signed-off-by: Sara Touqan <[email protected]>
1 parent 9486e5f commit 6df147b

File tree

6 files changed

+167
-0
lines changed

6 files changed

+167
-0
lines changed

samples/drivers/sdhc/index.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.. zephyr:code-sample-category:: sdhc
2+
:name: Secure Digital Host Controller (SDHC)
3+
:show-listing:
4+
5+
These samples demonstrate how to use the :ref:`sdhc` driver API.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(sdhc_read_write)
6+
7+
FILE(GLOB app_sources src/*.c)
8+
target_sources(app PRIVATE ${app_sources})
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
SDHC CMD52 Read/Write Sample
2+
============================
3+
4+
Overview
5+
--------
6+
7+
This sample demonstrates how to use the SDIO CMD52 (direct) command to read from and write to SDIO registers using the Zephyr SDHC API.
8+
9+
The sample performs the following:
10+
- Initializes the SDIO interface
11+
- Reads a register using CMD52
12+
- Writes a value using CMD52
13+
- Verifies the write by reading back and checking the result
14+
15+
Requirements
16+
------------
17+
18+
- A board with SDIO host (SDMMC) support.
19+
- A connected SDIO device (e.g., Wi-Fi module)
20+
- Proper DTS configuration enabling SDMMC
21+
22+
Building and Running
23+
--------------------
24+
25+
1. Navigate to the sample directory:
26+
27+
cd zephyr/samples/drivers/sdhc/sdhc_read_write
28+
29+
2. Build the sample for your board:
30+
31+
west build -b <your_board> .
32+
33+
3. Flash and run:
34+
35+
west flash
36+
37+
Sample output
38+
--------------------
39+
Connect to the console output to observe CMD52 results.
40+
When the sample runs successfully, you should see output similar to the following:
41+
42+
I: SDIO Init Passed Successfully.
43+
*** Booting Zephyr OS build v4.1.0-2351-ge261a86d79de ***
44+
I: CMD52 READ passed: data = 0x40
45+
I: CMD52 WRITE passed: wrote 0x01
46+
I: read data after write was as expected, data = 0x41
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
sdhc: &sdmmc1 {
2+
compatible = "st,stm32-sdhc";
3+
hw-flow-control;
4+
bus-width=<4>;
5+
pinctrl-0 = <&sdmmc1_d0_pc8 &sdmmc1_d1_pc9
6+
&sdmmc1_d2_pc10 &sdmmc1_d3_pc11
7+
&sdmmc1_ck_pc12 &sdmmc1_cmd_pd2>;
8+
pinctrl-names = "default";
9+
status= "okay";
10+
sdhi-on-gpios = <&gpioj 1 GPIO_ACTIVE_HIGH>;
11+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CONFIG_LOG=y
2+
CONFIG_LOG_DEFAULT_LEVEL=3
3+
CONFIG_LOG_MODE_MINIMAL=y
4+
CONFIG_SDHC=y
5+
CONFIG_SDIO_STACK=y
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Copyright (c) 2025 EXALT Technologies.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <string.h>
8+
#include <stdio.h>
9+
#include <assert.h>
10+
#include <zephyr/kernel.h>
11+
#include <zephyr/device.h>
12+
#include <zephyr/sys/util.h>
13+
#include <zephyr/logging/log.h>
14+
#include <zephyr/drivers/sdhc.h>
15+
16+
LOG_MODULE_REGISTER(sdio_sample, LOG_LEVEL_INF);
17+
18+
int cmd52_read(const struct device *dev, struct sdhc_command *cmd, enum sdio_func_num func,
19+
uint32_t reg_addr)
20+
{
21+
cmd->opcode = SDIO_RW_DIRECT;
22+
cmd->arg = (func << SDIO_CMD_ARG_FUNC_NUM_SHIFT) |
23+
((reg_addr & SDIO_CMD_ARG_REG_ADDR_MASK) << SDIO_CMD_ARG_REG_ADDR_SHIFT);
24+
cmd->response_type = (SD_RSP_TYPE_R5);
25+
cmd->timeout_ms = CONFIG_SD_CMD_TIMEOUT;
26+
return sdhc_request(dev, cmd, NULL);
27+
}
28+
29+
int cmd52_write(const struct device *dev, struct sdhc_command *cmd, enum sdio_func_num func,
30+
uint32_t reg_addr, uint8_t data_in)
31+
{
32+
cmd->opcode = SDIO_RW_DIRECT;
33+
cmd->arg = (func << SDIO_CMD_ARG_FUNC_NUM_SHIFT) |
34+
((reg_addr & SDIO_CMD_ARG_REG_ADDR_MASK) << SDIO_CMD_ARG_REG_ADDR_SHIFT);
35+
cmd->arg |= data_in & SDIO_DIRECT_CMD_DATA_MASK;
36+
cmd->arg |= BIT(SDIO_CMD_ARG_RW_SHIFT);
37+
if (data_in) {
38+
cmd->arg |= BIT(SDIO_DIRECT_CMD_ARG_RAW_SHIFT);
39+
}
40+
cmd->response_type = (SD_RSP_TYPE_R5);
41+
cmd->timeout_ms = CONFIG_SD_CMD_TIMEOUT;
42+
return sdhc_request(dev, cmd, NULL);
43+
}
44+
45+
int main(void)
46+
{
47+
int res;
48+
uint8_t data = 1;
49+
uint8_t original_data = 0, read_data = 0, expected = 0;
50+
struct sdhc_command cmd = {0};
51+
enum sdio_func_num func_num = SDIO_FUNC_NUM_0;
52+
53+
const struct device *sdmmc_dev = DEVICE_DT_GET(DT_NODELABEL(sdmmc1));
54+
55+
if (!device_is_ready(sdmmc_dev)) {
56+
LOG_ERR("sdhc dev is not ready!\n");
57+
return -1;
58+
}
59+
60+
res = cmd52_read(sdmmc_dev, &cmd, func_num, SDIO_CCCR_BUS_IF);
61+
if (res == 0) {
62+
original_data = cmd.response[0U];
63+
LOG_INF("CMD52 READ passed: data = 0x%02X", cmd.response[0U]);
64+
} else {
65+
LOG_ERR("CMD52 READ failed");
66+
}
67+
68+
k_msleep(100);
69+
res = cmd52_write(sdmmc_dev, &cmd, func_num, SDIO_CCCR_BUS_IF, data);
70+
if (res == 0) {
71+
LOG_INF("CMD52 WRITE passed: wrote 0x%02X", data);
72+
} else {
73+
LOG_ERR("CMD52 WRITE failed for data 0x%02X", data);
74+
}
75+
76+
k_msleep(100);
77+
res = cmd52_read(sdmmc_dev, &cmd, func_num, SDIO_CCCR_BUS_IF);
78+
if (res == 0) {
79+
expected = original_data | data;
80+
read_data = cmd.response[0U];
81+
if (read_data == expected) {
82+
LOG_INF("read data after write was as expected, data = 0x%02X", read_data);
83+
} else {
84+
LOG_ERR("read data was not as expected, expected 0x%02X, got 0x%02X",
85+
expected, read_data);
86+
}
87+
} else {
88+
LOG_ERR("CMD52 READ (post-write) failed");
89+
}
90+
91+
return 0;
92+
}

0 commit comments

Comments
 (0)