Skip to content

Commit a36d2df

Browse files
Vandoulmysterywolf
andauthored
[bsp/Infineon]psoc6 add drv sdcard (#7522)
Co-authored-by: Man, Jianting (Meco) <[email protected]>
1 parent 9217865 commit a36d2df

File tree

3 files changed

+441
-0
lines changed

3 files changed

+441
-0
lines changed

bsp/Infineon/libraries/HAL_Drivers/SConscript

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ if GetDepend(['RT_USING_I2C']):
2929
if GetDepend(['BSP_USING_SDIO1']):
3030
src += Glob('drv_sdio.c')
3131

32+
if GetDepend(['BSP_USING_SDCARD']):
33+
src += Glob('drv_sdcard.c')
34+
3235
if GetDepend(['BSP_USING_PWM']):
3336
src += ['drv_pwm.c']
3437

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
/*
2+
* Copyright (c) 2006-2023, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2023-05-05 vandoul first
9+
*/
10+
11+
#include <rtthread.h>
12+
#include "cy_gpio.h"
13+
#include "cyhal_gpio.h"
14+
#include "cyhal_sdhc.h"
15+
16+
#ifdef BSP_USING_SDCARD
17+
18+
//#define DRV_DEBUG
19+
#define LOG_TAG "drv.sdio"
20+
#include <drv_log.h>
21+
22+
#define SDIO_BLOCK_SIZE (512)
23+
24+
#if BSP_USING_SDCARD_LED_CTRL_ENANBLE
25+
#define SDCARD_LED_CTRL_ENABLE true
26+
#else
27+
#define SDCARD_LED_CTRL_ENABLE false
28+
#endif
29+
#if BSP_USING_SDCARD_EMMC_ENANBLE
30+
#define SDCARD_EMMC_ENABLE true
31+
#else
32+
#define SDCARD_EMMC_ENABLE false
33+
#endif
34+
35+
struct _cy_sdio_pin_and_name_config
36+
{
37+
const char *name;
38+
cyhal_gpio_t cmd; /**< The pin connected to the command signal. */
39+
cyhal_gpio_t clk; /**< The pin connected to the clock signal. */
40+
cyhal_gpio_t data0; /**< The pin connected to the data0 signal. */
41+
cyhal_gpio_t data1; /**< The pin connected to the data1 signal. */
42+
cyhal_gpio_t data2; /**< The pin connected to the data2 signal. */
43+
cyhal_gpio_t data3; /**< The pin connected to the data3 signal. */
44+
cyhal_gpio_t data4; /**< The pin connected to the data4 signal; pass NC when unused. */
45+
cyhal_gpio_t data5; /**< The pin connected to the data5 signal; pass NC when unused. */
46+
cyhal_gpio_t data6; /**< The pin connected to the data6 signal; pass NC when unused. */
47+
cyhal_gpio_t data7; /**< The pin connected to the data7 signal; pass NC when unused. */
48+
cyhal_gpio_t card_detect; /**< The pin connected to the card detect signal. */
49+
cyhal_gpio_t io_volt_sel; /**< The pin connected to the voltage select signal. */
50+
cyhal_gpio_t card_if_pwr_en; /**< The pin connected to the card interface power enable signal. */
51+
cyhal_gpio_t card_mech_write_prot; /**< The pin connected to the write protect signal. */
52+
cyhal_gpio_t led_ctrl; /**< The pin connected to the LED control signal. */
53+
cyhal_gpio_t card_emmc_reset; /**< The pin connected to the eMMC card reset signal. */
54+
};
55+
56+
static const struct _cy_sdio_pin_and_name_config _sdcard_config =
57+
{
58+
.name = "sd0",
59+
.cmd = BSP_USING_SDCARD_CMD_PIN,
60+
.clk = BSP_USING_SDCARD_CLK_PIN,
61+
.data0 = BSP_USING_SDCARD_DAT0_PIN,
62+
.data1 = BSP_USING_SDCARD_DAT1_PIN,
63+
.data2 = BSP_USING_SDCARD_DAT2_PIN,
64+
.data3 = BSP_USING_SDCARD_DAT3_PIN,
65+
.data4 = BSP_USING_SDCARD_DAT4_PIN,
66+
.data5 = BSP_USING_SDCARD_DAT5_PIN,
67+
.data6 = BSP_USING_SDCARD_DAT6_PIN,
68+
.data7 = BSP_USING_SDCARD_DAT7_PIN,
69+
.card_detect = BSP_USING_SDCARD_DETECT_PIN,
70+
.io_volt_sel = BSP_USING_SDCARD_IO_VOLT_SEL_PIN,
71+
.card_if_pwr_en = BSP_USING_SDCARD_CARD_IF_PWR_EN_PIN,
72+
.card_mech_write_prot = BSP_USING_SDCARD_CARD_MECH_WRITE_PROT_PIN,
73+
#if BSP_USING_SDCARD_LED_CTRL_PIN
74+
.led_ctrl = BSP_USING_SDCARD_LED_CTRL_PIN,
75+
#else
76+
.led_ctrl = -1,
77+
#endif
78+
.card_emmc_reset = BSP_USING_SDCARD_CARD_EMMC_RESET_PIN,
79+
};
80+
81+
#include <dfs_fs.h>
82+
#include <drivers/mmcsd_core.h>
83+
#include <drivers/gpt.h>
84+
struct rthw_sdio
85+
{
86+
struct rt_device parent;
87+
cyhal_sdhc_t sdhc_obj; /**< Object for use with the SDHC HAL driver. */
88+
cyhal_sdhc_config_t sdhc_config; /**< Card configuration structure to be passed to the HAL driver. */
89+
const struct _cy_sdio_pin_config *pins_cfg;
90+
struct dfs_partition part;
91+
struct rt_device_blk_geometry geometry;
92+
};
93+
static rt_err_t rt_mmcsd_init(rt_device_t dev)
94+
{
95+
return RT_EOK;
96+
}
97+
98+
static rt_err_t rt_mmcsd_open(rt_device_t dev, rt_uint16_t oflag)
99+
{
100+
return RT_EOK;
101+
}
102+
103+
static rt_err_t rt_mmcsd_close(rt_device_t dev)
104+
{
105+
return RT_EOK;
106+
}
107+
108+
static rt_err_t rt_mmcsd_control(rt_device_t dev, int cmd, void *args)
109+
{
110+
struct rthw_sdio *sdio = (struct rthw_sdio *)dev;
111+
struct dfs_partition *part = &sdio->part;
112+
struct rt_device_blk_geometry *geometry = &sdio->geometry;
113+
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
114+
switch (cmd)
115+
{
116+
case RT_DEVICE_CTRL_BLK_GETGEOME:
117+
rt_memcpy(args, geometry, sizeof(struct rt_device_blk_geometry));
118+
break;
119+
case RT_DEVICE_CTRL_BLK_PARTITION:
120+
rt_memcpy(args, part, sizeof(struct dfs_partition));
121+
default:
122+
break;
123+
}
124+
return RT_EOK;
125+
}
126+
127+
static rt_ssize_t rt_mmcsd_read(rt_device_t dev,
128+
rt_off_t pos,
129+
void *buffer,
130+
rt_size_t size)
131+
{
132+
rt_err_t err = 0;
133+
void *rd_ptr = (void *)buffer;
134+
struct rthw_sdio *sdio = (struct rthw_sdio *)dev;
135+
cyhal_sdhc_t *hw_sdio = &sdio->sdhc_obj;
136+
off_t offset = sdio->part.offset;
137+
138+
LOG_D("mmc read: off:%d pos:%d size:%d", offset, pos, size);
139+
if (dev == RT_NULL)
140+
{
141+
rt_set_errno(-RT_EINVAL);
142+
return 0;
143+
}
144+
145+
rt_sem_take(sdio->part.lock, RT_WAITING_FOREVER);
146+
do {
147+
size_t block_count = size;
148+
uint32_t addr = (offset + pos);
149+
cy_rslt_t result = cyhal_sdhc_read_async(hw_sdio, addr, buffer, &block_count);
150+
if(CY_RSLT_SUCCESS != result)
151+
{
152+
err = -RT_ERROR;
153+
break;
154+
}
155+
/* Waits on a semaphore until the transfer completes, when RTOS_AWARE component is defined. */
156+
result = cyhal_sdhc_wait_transfer_complete(hw_sdio);
157+
if(CY_RSLT_SUCCESS != result)
158+
{
159+
err = -RT_ERROR;
160+
break;
161+
}
162+
}while(0);
163+
rt_sem_release(sdio->part.lock);
164+
165+
/* the length of reading must align to SECTOR SIZE */
166+
if (err)
167+
{
168+
rt_set_errno(-RT_EIO);
169+
return 0;
170+
}
171+
return size;
172+
}
173+
174+
static rt_ssize_t rt_mmcsd_write(rt_device_t dev,
175+
rt_off_t pos,
176+
const void *buffer,
177+
rt_size_t size)
178+
{
179+
rt_err_t err = 0;
180+
void *rd_ptr = (void *)buffer;
181+
struct rthw_sdio *sdio = (struct rthw_sdio *)dev;
182+
cyhal_sdhc_t *hw_sdio = &sdio->sdhc_obj;
183+
off_t offset = sdio->part.offset;
184+
185+
LOG_D("mmc write: off:%d pos:%d size:%d", offset, pos, size);
186+
if (dev == RT_NULL)
187+
{
188+
rt_set_errno(-RT_EINVAL);
189+
return 0;
190+
}
191+
192+
rt_sem_take(sdio->part.lock, RT_WAITING_FOREVER);
193+
do {
194+
size_t block_count = size ;
195+
uint32_t addr = (offset + pos);
196+
cy_rslt_t result = cyhal_sdhc_write_async(hw_sdio, addr, buffer, &block_count);
197+
if(CY_RSLT_SUCCESS != result)
198+
{
199+
err = -RT_ERROR;
200+
break;
201+
}
202+
/* Waits on a semaphore until the transfer completes, when RTOS_AWARE component is defined. */
203+
result = cyhal_sdhc_wait_transfer_complete(hw_sdio);
204+
if(CY_RSLT_SUCCESS != result)
205+
{
206+
err = -RT_ERROR;
207+
break;
208+
}
209+
}while(0);
210+
rt_sem_release(sdio->part.lock);
211+
212+
/* the length of reading must align to SECTOR SIZE */
213+
if (err)
214+
{
215+
rt_set_errno(-RT_EIO);
216+
return 0;
217+
}
218+
return size;
219+
}
220+
#ifdef RT_USING_DEVICE_OPS
221+
const static struct rt_device_ops mmcsd_blk_ops =
222+
{
223+
rt_mmcsd_init,
224+
rt_mmcsd_open,
225+
rt_mmcsd_close,
226+
rt_mmcsd_read,
227+
rt_mmcsd_write,
228+
rt_mmcsd_control
229+
};
230+
#endif
231+
int rt_hw_sdio_init(void)
232+
{
233+
struct rthw_sdio *sdio = RT_NULL;
234+
struct _cy_sdio_pin_config *pins_cfg;
235+
char sname[16];
236+
237+
sdio = rt_malloc(sizeof(struct rthw_sdio));
238+
if (sdio == RT_NULL)
239+
{
240+
LOG_E("malloc rthw_sdio fail");
241+
return RT_NULL;
242+
}
243+
rt_memset(sdio, 0, sizeof(struct rthw_sdio));
244+
245+
LOG_D("sdio pins: cmd=%d,clk=%d,d0=%d,d1=%d,d2=%d,d3=%d,d4=%d,d5=%d,d6=%d,d7=%d",
246+
_sdio1_pins_and_name.cmd, _sdio1_pins_and_name.clk,
247+
_sdio1_pins_and_name.data0, _sdio1_pins_and_name.data1, _sdio1_pins_and_name.data2, _sdio1_pins_and_name.data3,
248+
_sdio1_pins_and_name.data4, _sdio1_pins_and_name.data5, _sdio1_pins_and_name.data6, _sdio1_pins_and_name.data7
249+
);
250+
LOG_D("\tdetect=%d,volt_sel=%d,pwr_en=%d,write_prot=%d,led_ctrl=%d,emmc_reset=%d",
251+
_sdio1_pins_and_name.card_detect, _sdio1_pins_and_name.io_volt_sel, _sdio1_pins_and_name.card_if_pwr_en,
252+
_sdio1_pins_and_name.card_mech_write_prot, _sdio1_pins_and_name.led_ctrl, _sdio1_pins_and_name.card_emmc_reset
253+
);
254+
/* register mmcsd device */
255+
sdio->parent.type = RT_Device_Class_Block;
256+
#ifdef RT_USING_DEVICE_OPS
257+
sdio->parent.ops = &mmcsd_blk_ops;
258+
#else
259+
sdio->parent.init = rt_mmcsd_init;
260+
sdio->parent.open = rt_mmcsd_open;
261+
sdio->parent.close = rt_mmcsd_close;
262+
sdio->parent.read = rt_mmcsd_read;
263+
sdio->parent.write = rt_mmcsd_write;
264+
sdio->parent.control = rt_mmcsd_control;
265+
#endif
266+
267+
do {
268+
sdio->sdhc_config.enableLedControl = SDCARD_LED_CTRL_ENABLE;
269+
sdio->sdhc_config.isEmmc = SDCARD_EMMC_ENABLE;
270+
sdio->sdhc_config.lowVoltageSignaling = false;
271+
sdio->sdhc_config.busWidth = BSP_USING_SDCARD_BUS_WIDTH;
272+
/* Initialize the SD Card interface. */
273+
int rslt = cyhal_sdhc_init_hw(&sdio->sdhc_obj, &sdio->sdhc_config, _sdcard_config.cmd, _sdcard_config.clk,
274+
_sdcard_config.data0, _sdcard_config.data1, _sdcard_config.data2, _sdcard_config.data3,
275+
_sdcard_config.data4, _sdcard_config.data5, _sdcard_config.data6, _sdcard_config.data7,
276+
_sdcard_config.card_detect, _sdcard_config.io_volt_sel, _sdcard_config.card_if_pwr_en,
277+
_sdcard_config.card_mech_write_prot, _sdcard_config.led_ctrl, _sdcard_config.card_emmc_reset, RT_NULL);
278+
if(rslt != CY_RSLT_SUCCESS)
279+
{
280+
LOG_E("sdhc hw init fail: (0x%x)", rslt);
281+
break;
282+
}
283+
284+
rslt = cyhal_sdhc_init_card(&sdio->sdhc_obj);
285+
if(rslt != CY_RSLT_SUCCESS)
286+
{
287+
LOG_E("sdhc init fail: (0x%x)", rslt);
288+
break;
289+
}
290+
291+
rt_uint32_t block_count;
292+
rslt = cyhal_sdhc_get_block_count(&sdio->sdhc_obj, &block_count);
293+
if(rslt != CY_RSLT_SUCCESS)
294+
{
295+
LOG_E("get block count fail: (0x%x)", rslt);
296+
break;
297+
}
298+
LOG_D("block count:%d(0x%x)", block_count, block_count);
299+
300+
sdio->geometry.bytes_per_sector = 512;
301+
sdio->geometry.block_size = 512;
302+
sdio->geometry.sector_count = block_count;
303+
304+
rt_snprintf(sname, sizeof(sname) - 1, "sem_%s%d", _sdcard_config.name, 0);
305+
sdio->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO);
306+
if(sdio->part.lock == RT_NULL)
307+
{
308+
LOG_E("create part.lock fail");
309+
break;
310+
}
311+
312+
rt_uint8_t *sector = rt_malloc(512);
313+
if(sector == RT_NULL)
314+
{
315+
LOG_E("malloc sector fail");
316+
break;
317+
}
318+
if(rt_mmcsd_read(&sdio->parent, 0, sector, 1) < 0)
319+
{
320+
LOG_E("rt_mmcsd_read fail");
321+
rt_free(sector);
322+
break;
323+
}
324+
rslt = dfs_filesystem_get_partition(&sdio->part, sector, 0);
325+
rt_free(sector);
326+
if(rslt != RT_EOK)
327+
{
328+
LOG_E("partition not found!");
329+
break;
330+
}
331+
332+
rslt = rt_device_register(&(sdio->parent), _sdcard_config.name,
333+
RT_DEVICE_FLAG_RDWR);
334+
335+
if(rslt != RT_EOK)
336+
{
337+
LOG_E("register device fail!");
338+
break;
339+
}
340+
341+
return RT_EOK;
342+
343+
}while(0);
344+
345+
if(sdio)
346+
{
347+
cyhal_sdhc_free(&sdio->sdhc_obj);
348+
if(sdio->part.lock)
349+
{
350+
rt_sem_delete(sdio->part.lock);
351+
}
352+
rt_free(sdio);
353+
}
354+
355+
return -RT_ERROR;
356+
}
357+
INIT_DEVICE_EXPORT(rt_hw_sdio_init);
358+
359+
#endif
360+

0 commit comments

Comments
 (0)