From a36d2df236d943d14389578b5852b332d147b770 Mon Sep 17 00:00:00 2001 From: vandoul Date: Sat, 20 May 2023 13:26:34 +0800 Subject: [PATCH] [bsp/Infineon]psoc6 add drv sdcard (#7522) Co-authored-by: Man, Jianting (Meco) <920369182@qq.com> --- bsp/Infineon/libraries/HAL_Drivers/SConscript | 3 + .../libraries/HAL_Drivers/drv_sdcard.c | 360 ++++++++++++++++++ .../psoc6-evaluationkit-062S2/board/Kconfig | 78 ++++ 3 files changed, 441 insertions(+) create mode 100644 bsp/Infineon/libraries/HAL_Drivers/drv_sdcard.c diff --git a/bsp/Infineon/libraries/HAL_Drivers/SConscript b/bsp/Infineon/libraries/HAL_Drivers/SConscript index 74d05cac7d..e62120048c 100644 --- a/bsp/Infineon/libraries/HAL_Drivers/SConscript +++ b/bsp/Infineon/libraries/HAL_Drivers/SConscript @@ -29,6 +29,9 @@ if GetDepend(['RT_USING_I2C']): if GetDepend(['BSP_USING_SDIO1']): src += Glob('drv_sdio.c') +if GetDepend(['BSP_USING_SDCARD']): + src += Glob('drv_sdcard.c') + if GetDepend(['BSP_USING_PWM']): src += ['drv_pwm.c'] diff --git a/bsp/Infineon/libraries/HAL_Drivers/drv_sdcard.c b/bsp/Infineon/libraries/HAL_Drivers/drv_sdcard.c new file mode 100644 index 0000000000..9873b3a893 --- /dev/null +++ b/bsp/Infineon/libraries/HAL_Drivers/drv_sdcard.c @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-05-05 vandoul first + */ + +#include +#include "cy_gpio.h" +#include "cyhal_gpio.h" +#include "cyhal_sdhc.h" + +#ifdef BSP_USING_SDCARD + +//#define DRV_DEBUG +#define LOG_TAG "drv.sdio" +#include + +#define SDIO_BLOCK_SIZE (512) + +#if BSP_USING_SDCARD_LED_CTRL_ENANBLE +#define SDCARD_LED_CTRL_ENABLE true +#else +#define SDCARD_LED_CTRL_ENABLE false +#endif +#if BSP_USING_SDCARD_EMMC_ENANBLE +#define SDCARD_EMMC_ENABLE true +#else +#define SDCARD_EMMC_ENABLE false +#endif + +struct _cy_sdio_pin_and_name_config +{ + const char *name; + cyhal_gpio_t cmd; /**< The pin connected to the command signal. */ + cyhal_gpio_t clk; /**< The pin connected to the clock signal. */ + cyhal_gpio_t data0; /**< The pin connected to the data0 signal. */ + cyhal_gpio_t data1; /**< The pin connected to the data1 signal. */ + cyhal_gpio_t data2; /**< The pin connected to the data2 signal. */ + cyhal_gpio_t data3; /**< The pin connected to the data3 signal. */ + cyhal_gpio_t data4; /**< The pin connected to the data4 signal; pass NC when unused. */ + cyhal_gpio_t data5; /**< The pin connected to the data5 signal; pass NC when unused. */ + cyhal_gpio_t data6; /**< The pin connected to the data6 signal; pass NC when unused. */ + cyhal_gpio_t data7; /**< The pin connected to the data7 signal; pass NC when unused. */ + cyhal_gpio_t card_detect; /**< The pin connected to the card detect signal. */ + cyhal_gpio_t io_volt_sel; /**< The pin connected to the voltage select signal. */ + cyhal_gpio_t card_if_pwr_en; /**< The pin connected to the card interface power enable signal. */ + cyhal_gpio_t card_mech_write_prot; /**< The pin connected to the write protect signal. */ + cyhal_gpio_t led_ctrl; /**< The pin connected to the LED control signal. */ + cyhal_gpio_t card_emmc_reset; /**< The pin connected to the eMMC card reset signal. */ +}; + +static const struct _cy_sdio_pin_and_name_config _sdcard_config = +{ + .name = "sd0", + .cmd = BSP_USING_SDCARD_CMD_PIN, + .clk = BSP_USING_SDCARD_CLK_PIN, + .data0 = BSP_USING_SDCARD_DAT0_PIN, + .data1 = BSP_USING_SDCARD_DAT1_PIN, + .data2 = BSP_USING_SDCARD_DAT2_PIN, + .data3 = BSP_USING_SDCARD_DAT3_PIN, + .data4 = BSP_USING_SDCARD_DAT4_PIN, + .data5 = BSP_USING_SDCARD_DAT5_PIN, + .data6 = BSP_USING_SDCARD_DAT6_PIN, + .data7 = BSP_USING_SDCARD_DAT7_PIN, + .card_detect = BSP_USING_SDCARD_DETECT_PIN, + .io_volt_sel = BSP_USING_SDCARD_IO_VOLT_SEL_PIN, + .card_if_pwr_en = BSP_USING_SDCARD_CARD_IF_PWR_EN_PIN, + .card_mech_write_prot = BSP_USING_SDCARD_CARD_MECH_WRITE_PROT_PIN, + #if BSP_USING_SDCARD_LED_CTRL_PIN + .led_ctrl = BSP_USING_SDCARD_LED_CTRL_PIN, + #else + .led_ctrl = -1, + #endif + .card_emmc_reset = BSP_USING_SDCARD_CARD_EMMC_RESET_PIN, +}; + +#include +#include +#include +struct rthw_sdio +{ + struct rt_device parent; + cyhal_sdhc_t sdhc_obj; /**< Object for use with the SDHC HAL driver. */ + cyhal_sdhc_config_t sdhc_config; /**< Card configuration structure to be passed to the HAL driver. */ + const struct _cy_sdio_pin_config *pins_cfg; + struct dfs_partition part; + struct rt_device_blk_geometry geometry; +}; +static rt_err_t rt_mmcsd_init(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_err_t rt_mmcsd_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t rt_mmcsd_close(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_err_t rt_mmcsd_control(rt_device_t dev, int cmd, void *args) +{ + struct rthw_sdio *sdio = (struct rthw_sdio *)dev; + struct dfs_partition *part = &sdio->part; + struct rt_device_blk_geometry *geometry = &sdio->geometry; + struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data; + switch (cmd) + { + case RT_DEVICE_CTRL_BLK_GETGEOME: + rt_memcpy(args, geometry, sizeof(struct rt_device_blk_geometry)); + break; + case RT_DEVICE_CTRL_BLK_PARTITION: + rt_memcpy(args, part, sizeof(struct dfs_partition)); + default: + break; + } + return RT_EOK; +} + +static rt_ssize_t rt_mmcsd_read(rt_device_t dev, + rt_off_t pos, + void *buffer, + rt_size_t size) +{ + rt_err_t err = 0; + void *rd_ptr = (void *)buffer; + struct rthw_sdio *sdio = (struct rthw_sdio *)dev; + cyhal_sdhc_t *hw_sdio = &sdio->sdhc_obj; + off_t offset = sdio->part.offset; + + LOG_D("mmc read: off:%d pos:%d size:%d", offset, pos, size); + if (dev == RT_NULL) + { + rt_set_errno(-RT_EINVAL); + return 0; + } + + rt_sem_take(sdio->part.lock, RT_WAITING_FOREVER); + do { + size_t block_count = size; + uint32_t addr = (offset + pos); + cy_rslt_t result = cyhal_sdhc_read_async(hw_sdio, addr, buffer, &block_count); + if(CY_RSLT_SUCCESS != result) + { + err = -RT_ERROR; + break; + } + /* Waits on a semaphore until the transfer completes, when RTOS_AWARE component is defined. */ + result = cyhal_sdhc_wait_transfer_complete(hw_sdio); + if(CY_RSLT_SUCCESS != result) + { + err = -RT_ERROR; + break; + } + }while(0); + rt_sem_release(sdio->part.lock); + + /* the length of reading must align to SECTOR SIZE */ + if (err) + { + rt_set_errno(-RT_EIO); + return 0; + } + return size; +} + +static rt_ssize_t rt_mmcsd_write(rt_device_t dev, + rt_off_t pos, + const void *buffer, + rt_size_t size) +{ + rt_err_t err = 0; + void *rd_ptr = (void *)buffer; + struct rthw_sdio *sdio = (struct rthw_sdio *)dev; + cyhal_sdhc_t *hw_sdio = &sdio->sdhc_obj; + off_t offset = sdio->part.offset; + + LOG_D("mmc write: off:%d pos:%d size:%d", offset, pos, size); + if (dev == RT_NULL) + { + rt_set_errno(-RT_EINVAL); + return 0; + } + + rt_sem_take(sdio->part.lock, RT_WAITING_FOREVER); + do { + size_t block_count = size ; + uint32_t addr = (offset + pos); + cy_rslt_t result = cyhal_sdhc_write_async(hw_sdio, addr, buffer, &block_count); + if(CY_RSLT_SUCCESS != result) + { + err = -RT_ERROR; + break; + } + /* Waits on a semaphore until the transfer completes, when RTOS_AWARE component is defined. */ + result = cyhal_sdhc_wait_transfer_complete(hw_sdio); + if(CY_RSLT_SUCCESS != result) + { + err = -RT_ERROR; + break; + } + }while(0); + rt_sem_release(sdio->part.lock); + + /* the length of reading must align to SECTOR SIZE */ + if (err) + { + rt_set_errno(-RT_EIO); + return 0; + } + return size; +} +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops mmcsd_blk_ops = +{ + rt_mmcsd_init, + rt_mmcsd_open, + rt_mmcsd_close, + rt_mmcsd_read, + rt_mmcsd_write, + rt_mmcsd_control +}; +#endif +int rt_hw_sdio_init(void) +{ + struct rthw_sdio *sdio = RT_NULL; + struct _cy_sdio_pin_config *pins_cfg; + char sname[16]; + + sdio = rt_malloc(sizeof(struct rthw_sdio)); + if (sdio == RT_NULL) + { + LOG_E("malloc rthw_sdio fail"); + return RT_NULL; + } + rt_memset(sdio, 0, sizeof(struct rthw_sdio)); + + LOG_D("sdio pins: cmd=%d,clk=%d,d0=%d,d1=%d,d2=%d,d3=%d,d4=%d,d5=%d,d6=%d,d7=%d", + _sdio1_pins_and_name.cmd, _sdio1_pins_and_name.clk, + _sdio1_pins_and_name.data0, _sdio1_pins_and_name.data1, _sdio1_pins_and_name.data2, _sdio1_pins_and_name.data3, + _sdio1_pins_and_name.data4, _sdio1_pins_and_name.data5, _sdio1_pins_and_name.data6, _sdio1_pins_and_name.data7 + ); + LOG_D("\tdetect=%d,volt_sel=%d,pwr_en=%d,write_prot=%d,led_ctrl=%d,emmc_reset=%d", + _sdio1_pins_and_name.card_detect, _sdio1_pins_and_name.io_volt_sel, _sdio1_pins_and_name.card_if_pwr_en, + _sdio1_pins_and_name.card_mech_write_prot, _sdio1_pins_and_name.led_ctrl, _sdio1_pins_and_name.card_emmc_reset + ); + /* register mmcsd device */ + sdio->parent.type = RT_Device_Class_Block; +#ifdef RT_USING_DEVICE_OPS + sdio->parent.ops = &mmcsd_blk_ops; +#else + sdio->parent.init = rt_mmcsd_init; + sdio->parent.open = rt_mmcsd_open; + sdio->parent.close = rt_mmcsd_close; + sdio->parent.read = rt_mmcsd_read; + sdio->parent.write = rt_mmcsd_write; + sdio->parent.control = rt_mmcsd_control; +#endif + + do { + sdio->sdhc_config.enableLedControl = SDCARD_LED_CTRL_ENABLE; + sdio->sdhc_config.isEmmc = SDCARD_EMMC_ENABLE; + sdio->sdhc_config.lowVoltageSignaling = false; + sdio->sdhc_config.busWidth = BSP_USING_SDCARD_BUS_WIDTH; + /* Initialize the SD Card interface. */ + int rslt = cyhal_sdhc_init_hw(&sdio->sdhc_obj, &sdio->sdhc_config, _sdcard_config.cmd, _sdcard_config.clk, + _sdcard_config.data0, _sdcard_config.data1, _sdcard_config.data2, _sdcard_config.data3, + _sdcard_config.data4, _sdcard_config.data5, _sdcard_config.data6, _sdcard_config.data7, + _sdcard_config.card_detect, _sdcard_config.io_volt_sel, _sdcard_config.card_if_pwr_en, + _sdcard_config.card_mech_write_prot, _sdcard_config.led_ctrl, _sdcard_config.card_emmc_reset, RT_NULL); + if(rslt != CY_RSLT_SUCCESS) + { + LOG_E("sdhc hw init fail: (0x%x)", rslt); + break; + } + + rslt = cyhal_sdhc_init_card(&sdio->sdhc_obj); + if(rslt != CY_RSLT_SUCCESS) + { + LOG_E("sdhc init fail: (0x%x)", rslt); + break; + } + + rt_uint32_t block_count; + rslt = cyhal_sdhc_get_block_count(&sdio->sdhc_obj, &block_count); + if(rslt != CY_RSLT_SUCCESS) + { + LOG_E("get block count fail: (0x%x)", rslt); + break; + } + LOG_D("block count:%d(0x%x)", block_count, block_count); + + sdio->geometry.bytes_per_sector = 512; + sdio->geometry.block_size = 512; + sdio->geometry.sector_count = block_count; + + rt_snprintf(sname, sizeof(sname) - 1, "sem_%s%d", _sdcard_config.name, 0); + sdio->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); + if(sdio->part.lock == RT_NULL) + { + LOG_E("create part.lock fail"); + break; + } + + rt_uint8_t *sector = rt_malloc(512); + if(sector == RT_NULL) + { + LOG_E("malloc sector fail"); + break; + } + if(rt_mmcsd_read(&sdio->parent, 0, sector, 1) < 0) + { + LOG_E("rt_mmcsd_read fail"); + rt_free(sector); + break; + } + rslt = dfs_filesystem_get_partition(&sdio->part, sector, 0); + rt_free(sector); + if(rslt != RT_EOK) + { + LOG_E("partition not found!"); + break; + } + + rslt = rt_device_register(&(sdio->parent), _sdcard_config.name, + RT_DEVICE_FLAG_RDWR); + + if(rslt != RT_EOK) + { + LOG_E("register device fail!"); + break; + } + + return RT_EOK; + + }while(0); + + if(sdio) + { + cyhal_sdhc_free(&sdio->sdhc_obj); + if(sdio->part.lock) + { + rt_sem_delete(sdio->part.lock); + } + rt_free(sdio); + } + + return -RT_ERROR; +} +INIT_DEVICE_EXPORT(rt_hw_sdio_init); + +#endif + diff --git a/bsp/Infineon/psoc6-evaluationkit-062S2/board/Kconfig b/bsp/Infineon/psoc6-evaluationkit-062S2/board/Kconfig index f85c9ba739..f942675ef9 100644 --- a/bsp/Infineon/psoc6-evaluationkit-062S2/board/Kconfig +++ b/bsp/Infineon/psoc6-evaluationkit-062S2/board/Kconfig @@ -14,6 +14,84 @@ menu "Onboard Peripheral Drivers" select BSP_USING_UART select BSP_USING_UART6 default y + + menuconfig BSP_USING_SDMMC + bool "Enable SDMMC (sd card)" + default n + select RT_USING_DFS + select RT_USING_DFS_ELMFAT + if BSP_USING_SDMMC + menuconfig BSP_USING_SDCARD + bool "Enable SDCARD (sd card)" + select BSP_USING_SDCARD_PIN_CONFIG + default n + if BSP_USING_SDCARD + config BSP_USING_SDCARD_EMMC_ENANBLE + bool "Enable SDCARD emmc" + default false + config BSP_USING_SDCARD_BUS_WIDTH + int "Enable SDCARD bus width" + default 4 + config BSP_USING_SDCARD_LED_CTRL_ENANBLE + bool "Enable SDCARD led control" + default false + menuconfig BSP_USING_SDCARD_PIN_CONFIG + bool "Enable SDCARD pin config" + default y + if BSP_USING_SDCARD_PIN_CONFIG + config BSP_USING_SDCARD_CMD_PIN + int "Enable SDCARD cmd pin,default:P2_4 --> 20" + default 20 + config BSP_USING_SDCARD_CLK_PIN + int "Enable SDCARD clk pin,default:P2_5 --> 21" + default 21 + config BSP_USING_SDCARD_DAT0_PIN + int "Enable SDCARD dat0 pin,default:P2_0 --> 16" + default 16 + config BSP_USING_SDCARD_DAT1_PIN + int "Enable SDCARD dat1 pin,default:P2_1 --> 17" + default 17 + config BSP_USING_SDCARD_DAT2_PIN + int "Enable SDCARD dat2 pin,default:P2_2 --> 18" + default 18 + config BSP_USING_SDCARD_DAT3_PIN + int "Enable SDCARD dat3 pin,default:P2_3 --> 19" + default 19 + config BSP_USING_SDCARD_DAT4_PIN + int "Enable SDCARD dat4 pin,default:NC" + default -1 + config BSP_USING_SDCARD_DAT5_PIN + int "Enable SDCARD dat5 pin,default:NC" + default -1 + config BSP_USING_SDCARD_DAT6_PIN + int "Enable SDCARD dat6 pin,default:NC" + default -1 + config BSP_USING_SDCARD_DAT7_PIN + int "Enable SDCARD dat7 pin,default:NC" + default -1 + config BSP_USING_SDCARD_DETECT_PIN + int "Enable SDCARD detect pin,default:P2_6 --> 22" + default 22 + config BSP_USING_SDCARD_IO_VOLT_SEL_PIN + int "Enable SDCARD io volt sel pin,default:NC" + default -1 + config BSP_USING_SDCARD_CARD_IF_PWR_EN_PIN + int "Enable SDCARD card if pwr en pin,default:NC" + default -1 + config BSP_USING_SDCARD_CARD_MECH_WRITE_PROT_PIN + int "Enable SDCARD card mech write prot pin,default:NC" + default -1 + if BSP_USING_SDCARD_LED_CTRL_ENANBLE + config BSP_USING_SDCARD_LED_CTRL_PIN + int "Enable SDCARD led ctrl pin,default:NC" + default -1 + endif + config BSP_USING_SDCARD_CARD_EMMC_RESET_PIN + int "Enable SDCARD card emmc reset pin,default:NC" + default -1 + endif + endif + endif endmenu menu "On-chip Peripheral Drivers"