forked from springcute/rt-thread
[bsp/Infineon]psoc6 add drv sdcard (#7522)
Co-authored-by: Man, Jianting (Meco) <920369182@qq.com>
This commit is contained in:
parent
9217865c6a
commit
a36d2df236
|
@ -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']
|
||||
|
||||
|
|
|
@ -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 <rtthread.h>
|
||||
#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 <drv_log.h>
|
||||
|
||||
#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 <dfs_fs.h>
|
||||
#include <drivers/mmcsd_core.h>
|
||||
#include <drivers/gpt.h>
|
||||
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
|
||||
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue