From be79333a79c2009da8beb2aeced076a2582e0a81 Mon Sep 17 00:00:00 2001 From: rcitach Date: Mon, 10 Aug 2026 03:44:02 +0000 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84ra6w1=E7=9A=84=E5=9F=BA?= =?UTF-8?q?=E7=A1=80BSP=E9=A9=B1=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HAL_Drivers/drivers/config/drv_config.h | 4 + .../drivers/config/raw/ra6w1/adc_config.h | 47 + .../drivers/config/raw/ra6w1/uart_config.h | 12 +- .../libraries/HAL_Drivers/drivers/drv_adc.c | 64 +- .../libraries/HAL_Drivers/drivers/drv_i2c.c | 72 +- .../libraries/HAL_Drivers/drivers/drv_rtc.c | 136 +- .../libraries/HAL_Drivers/drivers/drv_spi.c | 86 +- .../libraries/HAL_Drivers/drivers/drv_wdt.c | 25 +- .../.ci/attachconfig/attachconfig.yml | 56 + bsp/renesas/ra6w1-ek/.config | 19 + bsp/renesas/ra6w1-ek/board/Kconfig | 331 + bsp/renesas/ra6w1-ek/board/board.c | 44 + bsp/renesas/ra6w1-ek/board/board.h | 21 +- bsp/renesas/ra6w1-ek/board/ports/SConscript | 12 + bsp/renesas/ra6w1-ek/board/ports/drv_gpio_w.c | 36 +- bsp/renesas/ra6w1-ek/board/ports/drv_gpio_w.h | 33 + bsp/renesas/ra6w1-ek/board/ports/drv_pwm_w.c | 220 + .../ra6w1-ek/board/ports/drv_timer_w.c | 382 ++ bsp/renesas/ra6w1-ek/board/ports/fal_cfg.h | 27 + bsp/renesas/ra6w1-ek/board/ports/gpio_cfg.h | 83 - .../ra6w1-ek/board/ports/ra6w1_ospi_flash.c | 185 + .../ra6w1-ek/board/ports/ra6w1_qspi_psram.c | 268 + bsp/renesas/ra6w1-ek/ra/SConscript | 3 +- .../ra6w1-ek/ra/fsp/inc/api/r_sdmmc_api.h | 496 ++ .../ra6w1-ek/ra/fsp/inc/instances/r_dmac_w.h | 168 + .../ra6w1-ek/ra/fsp/inc/instances/r_ospi_w.h | 2 +- .../ra/fsp/inc/instances/r_sdemmc_w.h | 235 + .../cmsis/Device/RENESAS/Source/system.c | 9 +- .../ra6w1-ek/ra/fsp/src/r_adc_w/r_adc_w.c | 2 +- .../ra6w1-ek/ra/fsp/src/r_dmac_w/r_dmac_w.c | 745 +++ .../ra/fsp/src/r_sdemmc_w/r_sdemmc_w.c | 5623 +++++++++++++++++ .../fsp/src/r_sdemmc_w/r_sdemmc_w_private.h | 567 ++ .../ra6w1-ek/rafw_cfg/fsp_cfg/r_dmac_w_cfg.h | 13 + .../rafw_cfg/fsp_cfg/r_sdemmc_w_cfg.h | 16 + bsp/renesas/ra6w1-ek/rafw_gen/SConscript | 14 +- bsp/renesas/ra6w1-ek/rafw_gen/bsp_clock_cfg.h | 4 +- bsp/renesas/ra6w1-ek/rafw_gen/common_data.c | 16 +- bsp/renesas/ra6w1-ek/rafw_gen/common_data.h | 28 +- bsp/renesas/ra6w1-ek/rafw_gen/hal_data.c | 1046 ++- bsp/renesas/ra6w1-ek/rafw_gen/hal_data.h | 163 +- bsp/renesas/ra6w1-ek/rafw_gen/pin_data.c | 726 ++- bsp/renesas/ra6w1-ek/rafw_gen/vector_data.c | 72 +- bsp/renesas/ra6w1-ek/rafw_gen/vector_data.h | 106 +- bsp/renesas/ra6w1-ek/rtconfig.h | 6 + bsp/renesas/ra6w1-ek/rtconfig.py | 4 +- 45 files changed, 11756 insertions(+), 471 deletions(-) create mode 100644 bsp/renesas/libraries/HAL_Drivers/drivers/config/raw/ra6w1/adc_config.h create mode 100644 bsp/renesas/ra6w1-ek/.ci/attachconfig/attachconfig.yml create mode 100644 bsp/renesas/ra6w1-ek/board/board.c create mode 100644 bsp/renesas/ra6w1-ek/board/ports/drv_gpio_w.h create mode 100644 bsp/renesas/ra6w1-ek/board/ports/drv_pwm_w.c create mode 100644 bsp/renesas/ra6w1-ek/board/ports/drv_timer_w.c create mode 100644 bsp/renesas/ra6w1-ek/board/ports/fal_cfg.h delete mode 100644 bsp/renesas/ra6w1-ek/board/ports/gpio_cfg.h create mode 100644 bsp/renesas/ra6w1-ek/board/ports/ra6w1_ospi_flash.c create mode 100644 bsp/renesas/ra6w1-ek/board/ports/ra6w1_qspi_psram.c create mode 100644 bsp/renesas/ra6w1-ek/ra/fsp/inc/api/r_sdmmc_api.h create mode 100644 bsp/renesas/ra6w1-ek/ra/fsp/inc/instances/r_dmac_w.h create mode 100644 bsp/renesas/ra6w1-ek/ra/fsp/inc/instances/r_sdemmc_w.h create mode 100644 bsp/renesas/ra6w1-ek/ra/fsp/src/r_dmac_w/r_dmac_w.c create mode 100644 bsp/renesas/ra6w1-ek/ra/fsp/src/r_sdemmc_w/r_sdemmc_w.c create mode 100644 bsp/renesas/ra6w1-ek/ra/fsp/src/r_sdemmc_w/r_sdemmc_w_private.h create mode 100644 bsp/renesas/ra6w1-ek/rafw_cfg/fsp_cfg/r_dmac_w_cfg.h create mode 100644 bsp/renesas/ra6w1-ek/rafw_cfg/fsp_cfg/r_sdemmc_w_cfg.h diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/config/drv_config.h b/bsp/renesas/libraries/HAL_Drivers/drivers/config/drv_config.h index e7bf194c8c18..a0c72f265a1f 100644 --- a/bsp/renesas/libraries/HAL_Drivers/drivers/config/drv_config.h +++ b/bsp/renesas/libraries/HAL_Drivers/drivers/config/drv_config.h @@ -290,6 +290,10 @@ extern "C" #if defined(SOC_FAMILY_RENESAS_RA_WIRELESS) #if defined(SOC_SERIES_R7SA6W1) #include "raw/ra6w1/uart_config.h" +#ifdef BSP_USING_ADC +#include "raw/ra6w1/adc_config.h" +#endif + #endif /* SOC_SERIES_R7SA6W1 */ #endif /* SOC_FAMILY_RENESAS_RA_WIRELESS */ diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/config/raw/ra6w1/adc_config.h b/bsp/renesas/libraries/HAL_Drivers/drivers/config/raw/ra6w1/adc_config.h new file mode 100644 index 000000000000..fc92a84c66cc --- /dev/null +++ b/bsp/renesas/libraries/HAL_Drivers/drivers/config/raw/ra6w1/adc_config.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2026-07-29 rcitach first version + */ + +#ifndef __ADC_CONFIG_H__ +#define __ADC_CONFIG_H__ + +#include +#include +#include "hal_data.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BSP_USING_ADC) + +#ifndef BSP_USING_ADC0 +#define BSP_USING_ADC0 +#endif + +struct rt_adc_dev +{ + struct rt_adc_ops ops; + struct rt_adc_device adc_device; +}; + +struct ra_adc_map +{ + const char *device_name; + const adc_cfg_t *g_cfg; + const adc_ctrl_t *g_ctrl; + const void *g_channel_cfg; +}; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __ADC_CONFIG_H__ */ diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/config/raw/ra6w1/uart_config.h b/bsp/renesas/libraries/HAL_Drivers/drivers/config/raw/ra6w1/uart_config.h index 82e8ecaf23aa..d201a81e3c13 100644 --- a/bsp/renesas/libraries/HAL_Drivers/drivers/config/raw/ra6w1/uart_config.h +++ b/bsp/renesas/libraries/HAL_Drivers/drivers/config/raw/ra6w1/uart_config.h @@ -23,8 +23,8 @@ extern "C" { #define UART0_CONFIG \ { \ .name = "uart0", \ - .p_api_ctrl = &g_uart1_ctrl, \ - .p_cfg = &g_uart1_cfg, \ + .p_api_ctrl = &g_uart0_ctrl, \ + .p_cfg = &g_uart0_cfg, \ } #endif /* UART0_CONFIG */ #endif /* BSP_USING_UART0 */ @@ -34,8 +34,8 @@ extern "C" { #define UART1_CONFIG \ { \ .name = "uart1", \ - .p_api_ctrl = &g_uart2_ctrl, \ - .p_cfg = &g_uart2_cfg, \ + .p_api_ctrl = &g_uart1_ctrl, \ + .p_cfg = &g_uart1_cfg, \ } #endif /* UART1_CONFIG */ #endif /* BSP_USING_UART1 */ @@ -45,8 +45,8 @@ extern "C" { #define UART2_CONFIG \ { \ .name = "uart2", \ - .p_api_ctrl = &g_uart3_ctrl, \ - .p_cfg = &g_uart3_cfg, \ + .p_api_ctrl = &g_uart2_ctrl, \ + .p_cfg = &g_uart2_cfg, \ } #endif /* UART2_CONFIG */ #endif /* BSP_USING_UART2 */ diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_adc.c b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_adc.c index 09feabeb7a56..5c469ddaa1a1 100644 --- a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_adc.c +++ b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_adc.c @@ -12,11 +12,11 @@ #ifdef RT_USING_ADC #define DRV_DEBUG -#define DBG_TAG "drv.adc" +#define DBG_TAG "drv.adc" #ifdef DRV_DEBUG - #define DBG_LVL DBG_LOG +#define DBG_LVL DBG_LOG #else - #define DBG_LVL DBG_INFO +#define DBG_LVL DBG_INFO #endif /* DRV_DEBUG */ #include @@ -26,36 +26,46 @@ #define R_ADC_ScanCfg R_ADC_B_ScanCfg #define R_ADC_ScanStart R_ADC_B_ScanStart #define R_ADC_Read32 R_ADC_B_Read32 -#define R_ADC_Read R_ADC_B_Read +#define R_ADC_Read R_ADC_B_Read #define R_ADC_ScanStop R_ADC_B_ScanStop +#define R_ADC_Close R_ADC_B_Close + +#elif defined(SOC_SERIES_R7SA6W1) + +#define R_ADC_Open R_ADC_W_Open +#define R_ADC_ScanCfg R_ADC_W_ScanCfg +#define R_ADC_ScanStart R_ADC_W_ScanStart +#define R_ADC_Read32 R_ADC_W_Read32 +#define R_ADC_Read R_ADC_W_Read +#define R_ADC_ScanStop R_ADC_W_ScanStop +#define R_ADC_Close R_ADC_W_Close #endif -struct ra_adc_map ra_adc[] = -{ +struct ra_adc_map ra_adc[] = { #ifdef BSP_USING_ADC0 { - .device_name = "adc0", - .g_cfg = &g_adc0_cfg, - .g_ctrl = &g_adc0_ctrl, + .device_name = "adc0", + .g_cfg = &g_adc0_cfg, + .g_ctrl = &g_adc0_ctrl, #ifdef SOC_SERIES_R7KA8P1 - .g_channel_cfg = &g_adc0_scan_cfg, + .g_channel_cfg = &g_adc0_scan_cfg, #else - .g_channel_cfg = &g_adc0_channel_cfg, + .g_channel_cfg = &g_adc0_channel_cfg, #endif }, #endif #ifdef BSP_USING_ADC1 { - .device_name = "adc1", - .g_cfg = &g_adc1_cfg, - .g_ctrl = &g_adc1_ctrl, - .g_channel_cfg = &g_adc1_channel_cfg, + .device_name = "adc1", + .g_cfg = &g_adc1_cfg, + .g_ctrl = &g_adc1_ctrl, + .g_channel_cfg = &g_adc1_channel_cfg, }, #endif }; -static struct rt_adc_dev adc_obj[sizeof(ra_adc) / sizeof(ra_adc[0])] = {0}; +static struct rt_adc_dev adc_obj[sizeof(ra_adc) / sizeof(ra_adc[0])] = { 0 }; static rt_err_t ra_adc_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled) { @@ -106,10 +116,22 @@ static rt_err_t ra_get_adc_value(struct rt_adc_device *device, rt_int8_t channel return RT_EOK; } -static const struct rt_adc_ops ra_adc_ops = +static rt_uint8_t ra_adc_get_resolution(struct rt_adc_device *device) { + LOG_W("ra_adc_get_resolution is not supported."); + return 0; +} +static rt_int16_t ra_adc_get_vref(struct rt_adc_device *device) +{ + LOG_W("ra_adc_get_vref is not supported."); + return 0; +} + +static const struct rt_adc_ops ra_adc_ops = { .enabled = ra_adc_enabled, .convert = ra_get_adc_value, + .get_resolution = ra_adc_get_resolution, + .get_vref = ra_adc_get_vref, }; static int ra_adc_init(void) @@ -125,10 +147,10 @@ static int ra_adc_init(void) result = R_ADC_ScanCfg((adc_ctrl_t *)ra_adc[i].g_ctrl, ra_adc[i].g_channel_cfg); /* register ADC device */ - if(rt_hw_adc_register(&adc_obj[i].adc_device, - ra_adc[i].device_name, - &ra_adc_ops, - &ra_adc[i]) == RT_EOK) + if (rt_hw_adc_register(&adc_obj[i].adc_device, + ra_adc[i].device_name, + &ra_adc_ops, + &ra_adc[i]) == RT_EOK) { LOG_D("%s init success", ra_adc[i].device_name); } diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_i2c.c b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_i2c.c index 0c9053da0bf5..727baae4af62 100644 --- a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_i2c.c +++ b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_i2c.c @@ -17,31 +17,33 @@ #ifdef BSP_USING_HW_I2C #define DRV_DEBUG -#define LOG_TAG "drv.hwi2c" +#define LOG_TAG "drv.hwi2c" #include #include -#ifndef BIT -#define BIT(idx) (1ul << (idx)) -#endif +#define RA_SCI_EVENT_ABORTED 0x01 +#define RA_SCI_EVENT_RX_COMPLETE 0x02 +#define RA_SCI_EVENT_TX_COMPLETE 0x04 +#define RA_SCI_EVENT_ERROR 0x08 +#define RA_SCI_EVENT_ALL 0x0F -#ifndef BITS -#define BITS(b,e) ((((uint32_t)-1)<<(b))&(((uint32_t)-1)>>(31-(e)))) -#endif +#if defined(SOC_SERIES_R7FA2E2) + +#define R_IIC_MASTER_Open R_IIC_B_MASTER_Open +#define R_IIC_MASTER_Write R_IIC_B_MASTER_Write +#define R_IIC_MASTER_Read R_IIC_B_MASTER_Read +#define R_IIC_MASTER_SlaveAddressSet R_IIC_B_MASTER_SlaveAddressSet +#define R_IIC_MASTER_CallbackSet R_IIC_B_MASTER_CallbackSet + +#elif defined(SOC_SERIES_R7SA6W1) + +#define R_IIC_MASTER_Open R_I2C_MASTER_W_Open +#define R_IIC_MASTER_Write R_I2C_MASTER_W_Write +#define R_IIC_MASTER_Read R_I2C_MASTER_W_Read +#define R_IIC_MASTER_SlaveAddressSet R_I2C_MASTER_W_SlaveAddressSet +#define R_IIC_MASTER_CallbackSet R_I2C_MASTER_W_CallbackSet -#define RA_SCI_EVENT_ABORTED BIT(0) -#define RA_SCI_EVENT_RX_COMPLETE BIT(1) -#define RA_SCI_EVENT_TX_COMPLETE BIT(2) -#define RA_SCI_EVENT_ERROR BIT(3) -#define RA_SCI_EVENT_ALL BITS(0,3) - -#ifdef SOC_SERIES_R7FA2E2 -#define R_IIC_MASTER_Open R_IIC_B_MASTER_Open -#define R_IIC_MASTER_Write R_IIC_B_MASTER_Write -#define R_IIC_MASTER_Read R_IIC_B_MASTER_Read -#define R_IIC_MASTER_SlaveAddressSet R_IIC_B_MASTER_SlaveAddressSet -#define R_IIC_MASTER_CallbackSet R_IIC_B_MASTER_CallbackSet #endif struct ra_i2c_handle @@ -53,16 +55,27 @@ struct ra_i2c_handle struct rt_event event; }; -static struct ra_i2c_handle ra_i2cs[] = -{ +static struct ra_i2c_handle ra_i2cs[] = { #ifdef BSP_USING_HW_I2C0 - {.bus_name = "i2c0", .i2c_cfg = &g_i2c_master0_cfg, .i2c_ctrl = &g_i2c_master0_ctrl,}, + { + .bus_name = "i2c0", + .i2c_cfg = &g_i2c_master0_cfg, + .i2c_ctrl = &g_i2c_master0_ctrl, + }, #endif #ifdef BSP_USING_HW_I2C1 - {.bus_name = "i2c1", .i2c_cfg = &g_i2c_master1_cfg, .i2c_ctrl = &g_i2c_master1_ctrl,}, + { + .bus_name = "i2c1", + .i2c_cfg = &g_i2c_master1_cfg, + .i2c_ctrl = &g_i2c_master1_ctrl, + }, #endif #ifdef BSP_USING_HW_I2C2 - {.bus_name = "i2c2", .i2c_cfg = &g_i2c_master2_cfg, .i2c_ctrl = &g_i2c_master2_ctrl,}, + { + .bus_name = "i2c2", + .i2c_cfg = &g_i2c_master2_cfg, + .i2c_ctrl = &g_i2c_master2_ctrl, + }, #endif }; @@ -177,16 +190,15 @@ static rt_ssize_t ra_i2c_mst_xfer(struct rt_i2c_bus_device *bus, return (rt_ssize_t)i; } -static const struct rt_i2c_bus_device_ops ra_i2c_ops = -{ - .master_xfer = ra_i2c_mst_xfer, - .slave_xfer = RT_NULL, - .i2c_bus_control = RT_NULL +static const struct rt_i2c_bus_device_ops ra_i2c_ops = { + .master_xfer = ra_i2c_mst_xfer, + .slave_xfer = RT_NULL, + .i2c_bus_control = RT_NULL }; int ra_hw_i2c_init(void) { - fsp_err_t err = FSP_SUCCESS; + fsp_err_t err = FSP_SUCCESS; for (rt_uint32_t i = 0; i < sizeof(ra_i2cs) / sizeof(ra_i2cs[0]); i++) { ra_i2cs[i].bus.ops = &ra_i2c_ops; diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_rtc.c b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_rtc.c index f638ee9c5579..6a2c54071d39 100644 --- a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_rtc.c +++ b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_rtc.c @@ -16,14 +16,26 @@ #ifdef BSP_USING_ONCHIP_RTC -#define DBG_TAG "drv.rtc" +#define DBG_TAG "drv.rtc" #ifdef DRV_DEBUG - #define DBG_LVL DBG_LOG +#define DBG_LVL DBG_LOG #else - #define DBG_LVL DBG_INFO +#define DBG_LVL DBG_INFO #endif /* DRV_DEBUG */ #include +#if defined(SOC_SERIES_R7SA6W1) + +#define R_RTC_Open R_RTC_W_Open +#define R_RTC_CalendarTimeGet R_RTC_W_CalendarTimeGet +#define R_RTC_CalendarTimeSet R_RTC_W_CalendarTimeSet +#define R_RTC_CalendarAlarmGet R_RTC_W_CalendarAlarmGet +#define R_RTC_CalendarAlarmSet R_RTC_W_CalendarAlarmSet +#define g_rtc_ctrl g_rtc_w_ctrl +#define g_rtc_cfg g_rtc_w_cfg + +#endif + static rt_err_t ra_rtc_init(void) { rt_err_t result = RT_EOK; @@ -35,14 +47,13 @@ static rt_err_t ra_rtc_init(void) } #if defined(SOC_SERIES_R9A07G0) - rtc_time_t default_set_time = - { - .tm_sec = 0, - .tm_min = 0, + rtc_time_t default_set_time = { + .tm_sec = 0, + .tm_min = 0, .tm_hour = 0, .tm_mday = 1, .tm_wday = 1, - .tm_mon = 1, + .tm_mon = 1, .tm_year = 1900, }; @@ -53,21 +64,21 @@ static rt_err_t ra_rtc_init(void) static time_t get_rtc_timestamp(void) { - struct tm tm_new = {0}; - rtc_time_t g_current_time = {0}; + struct tm tm_new = { 0 }; + rtc_time_t g_current_time = { 0 }; R_RTC_CalendarTimeGet(&g_rtc_ctrl, &g_current_time); - tm_new.tm_year = g_current_time.tm_year; - tm_new.tm_mon = g_current_time.tm_mon; - tm_new.tm_mday = g_current_time.tm_mday; + tm_new.tm_year = g_current_time.tm_year; + tm_new.tm_mon = g_current_time.tm_mon; + tm_new.tm_mday = g_current_time.tm_mday; - tm_new.tm_hour = g_current_time.tm_hour; - tm_new.tm_min = g_current_time.tm_min; - tm_new.tm_sec = g_current_time.tm_sec; + tm_new.tm_hour = g_current_time.tm_hour; + tm_new.tm_min = g_current_time.tm_min; + tm_new.tm_sec = g_current_time.tm_sec; - tm_new.tm_wday = g_current_time.tm_wday; - tm_new.tm_yday = g_current_time.tm_yday; + tm_new.tm_wday = g_current_time.tm_wday; + tm_new.tm_yday = g_current_time.tm_yday; tm_new.tm_isdst = g_current_time.tm_isdst; return timegm(&tm_new); @@ -75,30 +86,29 @@ static time_t get_rtc_timestamp(void) static rt_err_t ra_get_secs(time_t *sec) { - *(rt_uint32_t *)sec = get_rtc_timestamp(); - LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)sec); + *sec = get_rtc_timestamp(); + LOG_D("RTC: get rtc_time %x\n", (rt_uint32_t)*sec); return RT_EOK; } static rt_err_t set_rtc_time_stamp(time_t time_stamp) { - struct tm now; - rtc_time_t g_current_time = {0}; - gmtime_r(&time_stamp, &now); - if (now.tm_year < 100) + struct tm now = { 0 }; + rtc_time_t g_current_time = { 0 }; + if (RT_NULL == gmtime_r(&time_stamp, &now)) { return -RT_ERROR; } - g_current_time.tm_sec = now.tm_sec ; - g_current_time.tm_min = now.tm_min ; - g_current_time.tm_hour = now.tm_hour; - g_current_time.tm_mday = now.tm_mday; - g_current_time.tm_mon = now.tm_mon; - g_current_time.tm_year = now.tm_year; - g_current_time.tm_wday = now.tm_wday; - g_current_time.tm_yday = now.tm_yday; + g_current_time.tm_sec = now.tm_sec; + g_current_time.tm_min = now.tm_min; + g_current_time.tm_hour = now.tm_hour; + g_current_time.tm_mday = now.tm_mday; + g_current_time.tm_mon = now.tm_mon; + g_current_time.tm_year = now.tm_year; + g_current_time.tm_wday = now.tm_wday; + g_current_time.tm_yday = now.tm_yday; if (R_RTC_CalendarTimeSet(&g_rtc_ctrl, &g_current_time) != FSP_SUCCESS) { @@ -111,14 +121,13 @@ static rt_err_t set_rtc_time_stamp(time_t time_stamp) static rt_err_t ra_set_secs(time_t *sec) { - rt_err_t result = RT_EOK; - if (set_rtc_time_stamp(*(rt_uint32_t *)sec)) + if (set_rtc_time_stamp(*sec)) { result = -RT_ERROR; } - LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)sec); + LOG_D("RTC: set rtc_time %x\n", (rt_uint32_t)*sec); return result; } @@ -128,22 +137,21 @@ static rt_err_t ra_get_alarm(struct rt_rtc_wkalarm *alarm) { rt_err_t result = RT_EOK; struct rt_rtc_wkalarm *wkalarm = alarm; - rtc_alarm_time_t alarm_time_get = - { - .sec_match = RT_FALSE, - .min_match = RT_FALSE, - .hour_match = RT_FALSE, - .mday_match = RT_FALSE, - .mon_match = RT_FALSE, - .year_match = RT_FALSE, - .dayofweek_match = RT_FALSE, + rtc_alarm_time_t alarm_time_get = { + .sec_match = RT_FALSE, + .min_match = RT_FALSE, + .hour_match = RT_FALSE, + .mday_match = RT_FALSE, + .mon_match = RT_FALSE, + .year_match = RT_FALSE, + .dayofweek_match = RT_FALSE, }; if (RT_EOK == R_RTC_CalendarAlarmGet(&g_rtc_ctrl, &alarm_time_get)) { wkalarm->tm_hour = alarm_time_get.time.tm_hour; - wkalarm->tm_min = alarm_time_get.time.tm_min; - wkalarm->tm_sec = alarm_time_get.time.tm_sec; + wkalarm->tm_min = alarm_time_get.time.tm_min; + wkalarm->tm_sec = alarm_time_get.time.tm_sec; } else { @@ -157,20 +165,19 @@ static rt_err_t ra_set_alarm(struct rt_rtc_wkalarm *alarm) { rt_err_t result = RT_EOK; struct rt_rtc_wkalarm *wkalarm = alarm; - rtc_alarm_time_t alarm_time_set = - { - .sec_match = RT_TRUE, - .min_match = RT_TRUE, - .hour_match = RT_TRUE, - .mday_match = RT_FALSE, - .mon_match = RT_FALSE, - .year_match = RT_FALSE, - .dayofweek_match = RT_FALSE, + rtc_alarm_time_t alarm_time_set = { + .sec_match = RT_TRUE, + .min_match = RT_TRUE, + .hour_match = RT_TRUE, + .mday_match = RT_FALSE, + .mon_match = RT_FALSE, + .year_match = RT_FALSE, + .dayofweek_match = RT_FALSE, }; alarm_time_set.time.tm_hour = wkalarm->tm_hour; - alarm_time_set.time.tm_min = wkalarm->tm_min; - alarm_time_set.time.tm_sec = wkalarm->tm_sec; + alarm_time_set.time.tm_min = wkalarm->tm_min; + alarm_time_set.time.tm_sec = wkalarm->tm_sec; if (1 == wkalarm->enable) { if (RT_EOK != R_RTC_CalendarAlarmSet(&g_rtc_ctrl, &alarm_time_set)) @@ -181,9 +188,9 @@ static rt_err_t ra_set_alarm(struct rt_rtc_wkalarm *alarm) } else { - alarm_time_set.sec_match = RT_FALSE; - alarm_time_set.min_match = RT_FALSE; - alarm_time_set.hour_match = RT_FALSE; + alarm_time_set.sec_match = RT_FALSE; + alarm_time_set.min_match = RT_FALSE; + alarm_time_set.hour_match = RT_FALSE; if (RT_EOK != R_RTC_CalendarAlarmSet(&g_rtc_ctrl, &alarm_time_set)) { LOG_E("Calendar alarm Stop failed."); @@ -205,11 +212,10 @@ void rtc_callback(rtc_callback_args_t *p_args) #endif } -static const struct rt_rtc_ops ra_rtc_ops = -{ - .init = ra_rtc_init, - .get_secs = ra_get_secs, - .set_secs = ra_set_secs, +static const struct rt_rtc_ops ra_rtc_ops = { + .init = ra_rtc_init, + .get_secs = ra_get_secs, + .set_secs = ra_set_secs, #ifdef RT_USING_ALARM .set_alarm = ra_set_alarm, .get_alarm = ra_get_alarm, diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_spi.c b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_spi.c index 505097440687..a7cb2adc7615 100644 --- a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_spi.c +++ b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_spi.c @@ -16,11 +16,11 @@ #ifdef BSP_USING_SPI //#define DRV_DEBUG -#define DBG_TAG "drv.spi" +#define DBG_TAG "drv.spi" #ifdef DRV_DEBUG - #define DBG_LVL DBG_LOG +#define DBG_LVL DBG_LOG #else - #define DBG_LVL DBG_INFO +#define DBG_LVL DBG_INFO #endif /* DRV_DEBUG */ #include @@ -28,32 +28,53 @@ #define RA_SPI0_EVENT 0x01 #define RA_SPI1_EVENT 0x02 #define RA_SPI2_EVENT 0x03 -static struct rt_event complete_event = {0}; +static struct rt_event complete_event = { 0 }; #if defined(SOC_SERIES_R7FA8M85) || defined(SOC_SERIES_R7KA8P1) -#define R_SPI_Write R_SPI_B_Write -#define R_SPI_Read R_SPI_B_Read -#define R_SPI_WriteRead R_SPI_B_WriteRead -#define R_SPI_Open R_SPI_B_Open + +#define R_SPI_Write R_SPI_B_Write +#define R_SPI_Read R_SPI_B_Read +#define R_SPI_WriteRead R_SPI_B_WriteRead +#define R_SPI_Open R_SPI_B_Open #define spi_extended_cfg_t spi_b_extended_cfg_t + +#elif defined(SOC_SERIES_R7SA6W1) + +#define R_SPI_Write R_SPI_W_Write +#define R_SPI_Read R_SPI_W_Read +#define R_SPI_WriteRead R_SPI_W_WriteRead +#define R_SPI_Open R_SPI_W_Open +#define spi_extended_cfg_t spi_w_extended_cfg_t + #endif -static struct ra_spi_handle spi_handle[] = -{ +static struct ra_spi_handle spi_handle[] = { #ifdef BSP_USING_SPI0 - {.bus_name = "spi0", .spi_ctrl_t = &g_spi0_ctrl, .spi_cfg_t = &g_spi0_cfg,}, + { + .bus_name = "spi0", + .spi_ctrl_t = &g_spi0_ctrl, + .spi_cfg_t = &g_spi0_cfg, + }, #endif #ifdef BSP_USING_SPI1 - {.bus_name = "spi1", .spi_ctrl_t = &g_spi1_ctrl, .spi_cfg_t = &g_spi1_cfg,}, + { + .bus_name = "spi1", + .spi_ctrl_t = &g_spi1_ctrl, + .spi_cfg_t = &g_spi1_cfg, + }, #endif #ifdef BSP_USING_SPI2 - {.bus_name = "spi2", .spi_ctrl_t = &g_spi2_ctrl, .spi_cfg_t = &g_spi2_cfg,}, + { + .bus_name = "spi2", + .spi_ctrl_t = &g_spi2_ctrl, + .spi_cfg_t = &g_spi2_cfg, + }, #endif }; -static struct ra_spi spi_config[sizeof(spi_handle) / sizeof(spi_handle[0])] = {0}; +static struct ra_spi spi_config[sizeof(spi_handle) / sizeof(spi_handle[0])] = { 0 }; void spi0_callback(spi_callback_args_t *p_args) { @@ -120,11 +141,17 @@ static spi_bit_width_t ra_width_shift(rt_uint8_t data_width) { spi_bit_width_t bit_width = SPI_BIT_WIDTH_8_BITS; if (data_width == 1) + { bit_width = SPI_BIT_WIDTH_8_BITS; + } else if (data_width == 2) + { bit_width = SPI_BIT_WIDTH_16_BITS; + } else if (data_width == 4) + { bit_width = SPI_BIT_WIDTH_32_BITS; + } return bit_width; } @@ -135,7 +162,7 @@ static rt_err_t ra_write_message(struct rt_spi_device *device, const void *send_ RT_ASSERT(send_buf != NULL); RT_ASSERT(len > 0); rt_err_t err = RT_EOK; - struct ra_spi *spi_dev = rt_container_of(device->bus, struct ra_spi, bus); + struct ra_spi *spi_dev = rt_container_of(device->bus, struct ra_spi, bus); spi_bit_width_t bit_width = ra_width_shift(spi_dev->rt_spi_cfg_t->data_width); /**< send msessage */ @@ -156,7 +183,7 @@ static rt_err_t ra_read_message(struct rt_spi_device *device, void *recv_buf, co RT_ASSERT(recv_buf != NULL); RT_ASSERT(len > 0); rt_err_t err = RT_EOK; - struct ra_spi *spi_dev = rt_container_of(device->bus, struct ra_spi, bus); + struct ra_spi *spi_dev = rt_container_of(device->bus, struct ra_spi, bus); spi_bit_width_t bit_width = ra_width_shift(spi_dev->rt_spi_cfg_t->data_width); /**< receive message */ @@ -177,7 +204,7 @@ static rt_err_t ra_write_read_message(struct rt_spi_device *device, struct rt_sp RT_ASSERT(message != NULL); RT_ASSERT(message->length > 0); rt_err_t err = RT_EOK; - struct ra_spi *spi_dev = rt_container_of(device->bus, struct ra_spi, bus); + struct ra_spi *spi_dev = rt_container_of(device->bus, struct ra_spi, bus); spi_bit_width_t bit_width = ra_width_shift(spi_dev->rt_spi_cfg_t->data_width); /**< write and receive message */ @@ -204,7 +231,7 @@ static rt_err_t ra_hw_spi_configure(struct rt_spi_device *device, RT_ASSERT(configuration != NULL); rt_err_t err = RT_EOK; - struct ra_spi *spi_dev = rt_container_of(device->bus, struct ra_spi, bus); + struct ra_spi *spi_dev = rt_container_of(device->bus, struct ra_spi, bus); /**< data_width : 1 -> 8 bits , 2 -> 16 bits, 4 -> 32 bits, default 32 bits*/ rt_uint8_t data_width = configuration->data_width / 8; @@ -212,18 +239,20 @@ static rt_err_t ra_hw_spi_configure(struct rt_spi_device *device, configuration->data_width = configuration->data_width / 8; spi_dev->rt_spi_cfg_t = configuration; - spi_extended_cfg_t spi_cfg = *(spi_extended_cfg_t *)spi_dev->ra_spi_handle_t->spi_cfg_t->p_extend; + spi_extended_cfg_t *spi_cfg = (spi_extended_cfg_t *)spi_dev->ra_spi_handle_t->spi_cfg_t->p_extend; /**< Configure Select Line */ rt_pin_write(device->cs_pin, PIN_HIGH); /**< config bitrate */ #if defined(SOC_SERIES_R7FA8M85) || defined(SOC_SERIES_R7KA8P1) - R_SPI_B_CalculateBitrate(spi_dev->rt_spi_cfg_t->max_hz, SPI_B_CLOCK_SOURCE_PCLK, &spi_cfg.spck_div); + R_SPI_B_CalculateBitrate(spi_dev->rt_spi_cfg_t->max_hz, SPI_B_CLOCK_SOURCE_PCLK, &spi_cfg->spck_div); #elif defined(SOC_SERIES_R9A07G0) - R_SPI_CalculateBitrate(spi_dev->rt_spi_cfg_t->max_hz, SPI_CLOCK_SOURCE_PCLKM, &spi_cfg.spck_div); + R_SPI_CalculateBitrate(spi_dev->rt_spi_cfg_t->max_hz, SPI_CLOCK_SOURCE_PCLKM, &spi_cfg->spck_div); +#elif defined(SOC_SERIES_R7SA6W1) + R_SPI_W_CalculateBitrate(spi_dev->rt_spi_cfg_t->max_hz, &spi_cfg->spck_div, spi_dev->ra_spi_handle_t->spi_cfg_t->channel); #else - R_SPI_CalculateBitrate(spi_dev->rt_spi_cfg_t->max_hz, &spi_cfg.spck_div); + R_SPI_CalculateBitrate(spi_dev->rt_spi_cfg_t->max_hz, &spi_cfg->spck_div); #endif /**< init */ @@ -248,9 +277,13 @@ static rt_ssize_t ra_spixfer(struct rt_spi_device *device, struct rt_spi_message if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) { if (device->config.mode & RT_SPI_CS_HIGH) + { rt_pin_write(device->cs_pin, PIN_HIGH); + } else + { rt_pin_write(device->cs_pin, PIN_LOW); + } } if (message->length > 0) @@ -268,22 +301,25 @@ static rt_ssize_t ra_spixfer(struct rt_spi_device *device, struct rt_spi_message else if (message->send_buf != RT_NULL && message->recv_buf != RT_NULL) { /**< send and receive message */ - err = ra_write_read_message(device, message); + err = ra_write_read_message(device, message); } } if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) { if (device->config.mode & RT_SPI_CS_HIGH) + { rt_pin_write(device->cs_pin, PIN_LOW); + } else + { rt_pin_write(device->cs_pin, PIN_HIGH); + } } return err; } -static const struct rt_spi_ops ra_spi_ops = -{ +static const struct rt_spi_ops ra_spi_ops = { .configure = ra_hw_spi_configure, .xfer = ra_spixfer, }; diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_wdt.c b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_wdt.c index 83559a9e255d..39af4cdb836d 100644 --- a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_wdt.c +++ b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_wdt.c @@ -17,8 +17,19 @@ #ifdef RT_USING_WDT +#if defined(SOC_SERIES_R7SA6W1) + +#define R_WDT_Refresh R_WDOG_W_Refresh +#define R_WDT_TimeoutGet R_WDOG_W_TimeoutGet +#define R_WDT_TimeoutSet R_WDOG_W_TimeoutSet +#define R_WDT_Open R_WDOG_W_Open +#define g_wdt_ctrl g_wdog_w_ctrl +#define g_wdt_cfg g_wdog_w_cfg + +#endif + //#define DRV_DEBUG -#define LOG_TAG "drv.wdt" +#define LOG_TAG "drv.wdt" #include static struct rt_watchdog_device ra_wdt_dev; @@ -32,7 +43,7 @@ static rt_err_t wdt_init(rt_watchdog_t *wdt) static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg) { rt_err_t ret = -RT_ERROR; - struct st_wdt_timeout_values *wdt_value = {0}; + struct st_wdt_timeout_values *wdt_value = { 0 }; switch (cmd) { /* feed the watchdog */ @@ -40,7 +51,7 @@ static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg) if (R_WDT_Refresh(&g_wdt_ctrl) != FSP_SUCCESS) { LOG_E("watch dog keepalive fail."); - ret = -RT_ERROR; + ret = -RT_ERROR; } else { @@ -58,7 +69,7 @@ static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg) if (R_WDT_TimeoutGet(&g_wdt_ctrl, wdt_value) != FSP_SUCCESS) { LOG_E("wdt get timeout failed."); - ret = -RT_ERROR; + ret = -RT_ERROR; } else { @@ -71,7 +82,7 @@ static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg) if (R_WDT_Refresh(&g_wdt_ctrl) != FSP_SUCCESS) { LOG_E("wdt start failed."); - ret = -RT_ERROR; + ret = -RT_ERROR; } else { @@ -81,12 +92,12 @@ static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg) else { LOG_E("wdt start failed."); - ret = -RT_ERROR; + ret = -RT_ERROR; } break; default: LOG_W("This command is not supported."); - ret = -RT_ERROR; + ret = -RT_ERROR; } return ret; } diff --git a/bsp/renesas/ra6w1-ek/.ci/attachconfig/attachconfig.yml b/bsp/renesas/ra6w1-ek/.ci/attachconfig/attachconfig.yml new file mode 100644 index 000000000000..1413e7eadb16 --- /dev/null +++ b/bsp/renesas/ra6w1-ek/.ci/attachconfig/attachconfig.yml @@ -0,0 +1,56 @@ +# ------ devices CI ------ +devices.uart: + kconfig: + - CONFIG_BSP_USING_UART1=y + - CONFIG_BSP_USING_UART2=y +devices.adc: + kconfig: + - CONFIG_BSP_USING_ADC=y +devices.spi: + kconfig: + - CONFIG_BSP_USING_SPI=y + - CONFIG_BSP_USING_SPI0=y + - CONFIG_BSP_USING_SPI1=y +devices.i2c: + kconfig: + - CONFIG_BSP_USING_HW_I2C=y + - CONFIG_BSP_USING_HW_I2C0=y + - CONFIG_BSP_USING_HW_I2C1=y +devices.timer: + kconfig: + - CONFIG_BSP_USING_TIM_W=y + - CONFIG_BSP_USING_TIM0=y + - CONFIG_BSP_USING_TIM1=y + - CONFIG_BSP_USING_TIM2=y + - CONFIG_BSP_USING_TIM3=y + - CONFIG_BSP_USING_TIM4=y + - CONFIG_BSP_USING_TIM5=y + - CONFIG_BSP_USING_TIM6=y + - CONFIG_BSP_USING_TIM7=y +devices.pwm: + kconfig: + - CONFIG_BSP_USING_PWM_W=y + - CONFIG_BSP_USING_PWM0=y + - CONFIG_BSP_USING_PWM1=y + - CONFIG_BSP_USING_PWM2=y + - CONFIG_BSP_USING_PWM3=y + - CONFIG_BSP_USING_PWM4=y + - CONFIG_BSP_USING_PWM5=y + - CONFIG_BSP_USING_PWM6=y + - CONFIG_BSP_USING_PWM7=y +devices.rtc: + kconfig: + - CONFIG_BSP_USING_ONCHIP_RTC=y +devices.wdt: + kconfig: + - CONFIG_BSP_USING_WDT=y +devices.psram: + kconfig: + - CONFIG_BSP_USING_QSPI_PSRAM=y +devices.flash: + kconfig: + - CONFIG_BSP_USING_OSPI_FLASH=y + + + + diff --git a/bsp/renesas/ra6w1-ek/.config b/bsp/renesas/ra6w1-ek/.config index 51abcedfedba..dfc0413d5452 100644 --- a/bsp/renesas/ra6w1-ek/.config +++ b/bsp/renesas/ra6w1-ek/.config @@ -1452,9 +1452,28 @@ CONFIG_SOC_SERIES_R7SA6W1=y CONFIG_BSP_USING_GPIO_W=y CONFIG_BSP_USING_UART=y CONFIG_BSP_USING_UART0=y +CONFIG_BSP_UART0_RX_PIN="p000" +CONFIG_BSP_UART0_TX_PIN="p001" # CONFIG_BSP_UART0_RX_USING_DMA is not set # CONFIG_BSP_UART0_TX_USING_DMA is not set CONFIG_BSP_UART0_RX_BUFSIZE=256 CONFIG_BSP_UART0_TX_BUFSIZE=0 +# CONFIG_BSP_USING_UART1 is not set +# CONFIG_BSP_USING_UART2 is not set +# CONFIG_BSP_USING_SPI is not set +# CONFIG_BSP_USING_HW_I2C is not set +# CONFIG_BSP_USING_ADC is not set +# CONFIG_BSP_USING_TIM_W is not set +# CONFIG_BSP_USING_PWM_W is not set +# CONFIG_BSP_USING_QSPI is not set +# CONFIG_BSP_USING_ONCHIP_RTC is not set +# CONFIG_BSP_USING_WDT is not set # end of On-chip Peripheral Drivers + +# +# On-chip Peripheral Port +# +# CONFIG_BSP_USING_OSPI_FLASH is not set +# CONFIG_BSP_USING_QSPI_PSRAM is not set +# end of On-chip Peripheral Port # end of Hardware Drivers Config diff --git a/bsp/renesas/ra6w1-ek/board/Kconfig b/bsp/renesas/ra6w1-ek/board/Kconfig index 6e7cb35098be..341c9d2f7117 100644 --- a/bsp/renesas/ra6w1-ek/board/Kconfig +++ b/bsp/renesas/ra6w1-ek/board/Kconfig @@ -10,12 +10,21 @@ menu "Hardware Drivers Config" menuconfig BSP_USING_UART bool "Enable UART" default y + select BSP_USING_GPIO_W select RT_USING_SERIAL if BSP_USING_UART menuconfig BSP_USING_UART0 bool "Enable UART0" default y if BSP_USING_UART0 + config BSP_UART0_RX_PIN + string "UART0 RX pin" + default "p000" + + config BSP_UART0_TX_PIN + string "UART0 TX pin" + default "p001" + config BSP_UART0_RX_USING_DMA bool "Enable UART0 RX DMA" depends on BSP_USING_UART0 && RT_SERIAL_USING_DMA @@ -39,6 +48,328 @@ menu "Hardware Drivers Config" default 0 endif + menuconfig BSP_USING_UART1 + bool "Enable UART1" + default n + if BSP_USING_UART1 + config BSP_UART1_RX_PIN + string "UART1 RX pin" + default "p004" + + config BSP_UART1_TX_PIN + string "UART1 TX pin" + default "p005" + + config BSP_UART1_RX_USING_DMA + bool "Enable UART1 RX DMA" + depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA + default n + + config BSP_UART1_TX_USING_DMA + bool "Enable UART1 TX DMA" + depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA + default n + + config BSP_UART1_RX_BUFSIZE + int "Set UART1 RX buffer size" + range 64 65535 + depends on RT_USING_SERIAL_V2 + default 256 + + config BSP_UART1_TX_BUFSIZE + int "Set UART1 TX buffer size" + range 0 65535 + depends on RT_USING_SERIAL_V2 + default 0 + endif + + menuconfig BSP_USING_UART2 + bool "Enable UART2" + default n + if BSP_USING_UART2 + config BSP_UART2_RX_PIN + string "UART2 RX pin" + default "p110" + + config BSP_UART2_TX_PIN + string "UART2 TX pin" + default "p111" + + config BSP_UART2_RX_USING_DMA + bool "Enable UART2 RX DMA" + depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA + default n + + config BSP_UART2_TX_USING_DMA + bool "Enable UART2 TX DMA" + depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA + default n + + config BSP_UART2_RX_BUFSIZE + int "Set UART2 RX buffer size" + range 64 65535 + depends on RT_USING_SERIAL_V2 + default 256 + + config BSP_UART2_TX_BUFSIZE + int "Set UART2 TX buffer size" + range 0 65535 + depends on RT_USING_SERIAL_V2 + default 0 + endif + endif + + menuconfig BSP_USING_SPI + bool "Enable SPI BUS" + default n + select BSP_USING_GPIO_W + select RT_USING_SPI + if BSP_USING_SPI + config BSP_USING_SPI0 + bool "Enable SPI0 BUS" + default n + if BSP_USING_SPI0 + config BSP_SPI0_DI_PIN + string "SPI0 DI pin" + default "p101" + + config BSP_SPI0_DO_PIN + string "SPI0 DO pin" + default "p102" + + config BSP_SPI0_CLK_PIN + string "SPI0 CLK pin" + default "p100" + + config BSP_SPI0_CSN0_PIN + string "SPI0 CSN0 pin" + default "p103" + endif + + config BSP_USING_SPI1 + bool "Enable SPI1 BUS" + default n + if BSP_USING_SPI1 + config BSP_SPI1_DI_PIN + string "SPI1 DI pin" + default "p113" + + config BSP_SPI1_DO_PIN + string "SPI1 DO pin" + default "p114" + + config BSP_SPI1_CLK_PIN + string "SPI1 CLK pin" + default "p112" + + config BSP_SPI1_CSN0_PIN + string "SPI1 CSN0 pin" + default "p115" + endif + endif + + + menuconfig BSP_USING_HW_I2C + bool "Enable hardware I2C bus" + default n + select BSP_USING_GPIO_W + select RT_USING_I2C + if BSP_USING_HW_I2C + config BSP_USING_HW_I2C0 + bool "Enable I2C0 bus" + default n + if BSP_USING_HW_I2C0 + config BSP_I2C0_SCL_PIN + string "I2C0 SCL pin" + default "p004" + + config BSP_I2C0_SDA_PIN + string "I2C0 SDA pin" + default "p005" + endif + + config BSP_USING_HW_I2C1 + bool "Enable I2C1 bus" + default n + if BSP_USING_HW_I2C1 + config BSP_I2C1_SCL_PIN + string "I2C1 SCL pin" + default "p006" + + config BSP_I2C1_SDA_PIN + string "I2C1 SDA pin" + default "p007" + endif + endif + + menuconfig BSP_USING_ADC + bool "Enable ADC" + select BSP_USING_GPIO_W + select RT_USING_ADC + default n + if BSP_USING_ADC + config BSP_USING_ADC_PIN_NUM + int "ADC channel count" + range 1 4 + default 4 + endif + + menuconfig BSP_USING_TIM_W + bool "Enable timer driver" + select RT_USING_CLOCK_TIME + default n + if BSP_USING_TIM_W + config BSP_USING_TIM0 + bool "Enable timer0" + default n + + config BSP_USING_TIM1 + bool "Enable timer1" + default n + + config BSP_USING_TIM2 + bool "Enable timer2" + default n + + config BSP_USING_TIM3 + bool "Enable timer3" + default n + + config BSP_USING_TIM4 + bool "Enable timer4" + default n + + config BSP_USING_TIM5 + bool "Enable timer5" + default n + + config BSP_USING_TIM6 + bool "Enable timer6" + default n + + config BSP_USING_TIM7 + bool "Enable timer7" + default n endif + + menuconfig BSP_USING_PWM_W + bool "Enable PWM driver" + select BSP_USING_GPIO_W + select RT_USING_PWM + select BSP_USING_TIM_W + default n + if BSP_USING_PWM_W + config BSP_USING_PWM0 + bool "Enable PWM0" + select BSP_USING_TIM0 + default n + if BSP_USING_PWM0 + config BSP_PWM0_PIN + string "PWM0 pin" + default "p004" + endif + + config BSP_USING_PWM1 + bool "Enable PWM1" + select BSP_USING_TIM1 + default n + if BSP_USING_PWM1 + config BSP_PWM1_PIN + string "PWM1 pin" + default "p005" + endif + + config BSP_USING_PWM2 + bool "Enable PWM2" + select BSP_USING_TIM2 + default n + if BSP_USING_PWM2 + config BSP_PWM2_PIN + string "PWM2 pin" + default "p006" + endif + + config BSP_USING_PWM3 + bool "Enable PWM3" + select BSP_USING_TIM3 + default n + if BSP_USING_PWM3 + config BSP_PWM3_PIN + string "PWM3 pin" + default "p007" + endif + + config BSP_USING_PWM4 + bool "Enable PWM4" + select BSP_USING_TIM4 + default n + if BSP_USING_PWM4 + config BSP_PWM4_PIN + string "PWM4 pin" + default "p100" + endif + + config BSP_USING_PWM5 + bool "Enable PWM5" + select BSP_USING_TIM5 + default n + if BSP_USING_PWM5 + config BSP_PWM5_PIN + string "PWM5 pin" + default "p101" + endif + + config BSP_USING_PWM6 + bool "Enable PWM6" + select BSP_USING_TIM6 + default n + if BSP_USING_PWM6 + config BSP_PWM6_PIN + string "PWM6 pin" + default "p102" + endif + + config BSP_USING_PWM7 + bool "Enable PWM7" + select BSP_USING_TIM7 + default n + if BSP_USING_PWM7 + config BSP_PWM7_PIN + string "PWM7 pin" + default "p103" + endif + endif + + config BSP_USING_QSPI + bool "Enable QSPI driver" + select BSP_USING_GPIO_W + default n + + config BSP_USING_ONCHIP_RTC + bool "Enable On-chip RTC" + select RT_USING_RTC + default n + + config BSP_USING_WDT + bool "Enable Watchdog Timer" + select RT_USING_WDT + default n + + endmenu + + menu "On-chip Peripheral Port" + + config BSP_USING_OSPI_FLASH + bool "Enable OSPI external flash" + select RT_USING_FAL + select FAL_PART_HAS_TABLE_CFG + default n + + config BSP_USING_QSPI_PSRAM + bool "Enable QSPI PSRAM" + select BSP_USING_QSPI + select RT_USING_MEMHEAP + default n + endmenu endmenu diff --git a/bsp/renesas/ra6w1-ek/board/board.c b/bsp/renesas/ra6w1-ek/board/board.c new file mode 100644 index 000000000000..16c19b5cf66f --- /dev/null +++ b/bsp/renesas/ra6w1-ek/board/board.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "board.h" + +#ifdef RT_USING_PIN +#include +#endif + +#ifdef RT_USING_SERIAL_V2 +#include +#endif + +extern void rt_hw_systick_init(void); +void rt_hw_board_init(void) +{ + rt_hw_systick_init(); + +#if defined(RT_USING_HEAP) + rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); +#endif + +#ifdef RT_USING_PIN + rt_hw_pin_init(); +#endif + +#ifdef RT_USING_SERIAL_V2 + rt_hw_usart_init(); +#endif + +#if defined(RT_USING_CONSOLE) + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif +} diff --git a/bsp/renesas/ra6w1-ek/board/board.h b/bsp/renesas/ra6w1-ek/board/board.h index 0c367c3db101..fcb86119f728 100644 --- a/bsp/renesas/ra6w1-ek/board/board.h +++ b/bsp/renesas/ra6w1-ek/board/board.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2026, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -31,27 +31,8 @@ extern int __RAM_segment_used_end__; #define HEAP_END RA_SRAM_END -#ifdef BSP_USING_GPIO_W -#define R_IOPORT_Open R_GPIO_W_Open -#define R_IOPORT_Close R_GPIO_W_Close -#define R_IOPORT_PinsCfg R_GPIO_W_PinsCfg -#define R_IOPORT_PinCfg R_GPIO_W_PinCfg -#define R_IOPORT_PinRead R_GPIO_W_PinRead -#define R_IOPORT_PinWrite R_GPIO_W_PinWrite -#define R_IOPORT_PortDirectionSet R_GPIO_W_PortDirectionSet -#define R_IOPORT_PortEventInputRead R_GPIO_W_PortEventInputRead -#define R_IOPORT_PortEventOutputWrite R_GPIO_W_PortEventOutputWrite -#define R_IOPORT_PortRead R_GPIO_W_PortRead -#define R_IOPORT_PortWrite R_GPIO_W_PortWrite - -#define g_ioport g_gpio_w -#define g_ioport_ctrl g_gpio_w_ctrl -int rt_hw_pin_init(void); -#endif - #ifdef __cplusplus } #endif #endif - diff --git a/bsp/renesas/ra6w1-ek/board/ports/SConscript b/bsp/renesas/ra6w1-ek/board/ports/SConscript index 6bc17b8362e2..e70560313ddd 100644 --- a/bsp/renesas/ra6w1-ek/board/ports/SConscript +++ b/bsp/renesas/ra6w1-ek/board/ports/SConscript @@ -9,6 +9,18 @@ CPPPATH = [cwd] if GetDepend(["BSP_USING_GPIO_W"]): src += ["drv_gpio_w.c"] +if GetDepend(["BSP_USING_TIM_W"]): + src += ["drv_timer_w.c"] + +if GetDepend(["BSP_USING_PWM_W"]): + src += ["drv_pwm_w.c"] + +if GetDepend(["BSP_USING_QSPI_PSRAM"]): + src += ["ra6w1_qspi_psram.c"] + +if GetDepend(["BSP_USING_OSPI_FLASH"]): + src += ["ra6w1_ospi_flash.c"] + objs = DefineGroup('Port', src, depend = [''], CPPPATH = CPPPATH) list = os.listdir(cwd) diff --git a/bsp/renesas/ra6w1-ek/board/ports/drv_gpio_w.c b/bsp/renesas/ra6w1-ek/board/ports/drv_gpio_w.c index 0eaeee5b76f6..15f6204a41fd 100644 --- a/bsp/renesas/ra6w1-ek/board/ports/drv_gpio_w.c +++ b/bsp/renesas/ra6w1-ek/board/ports/drv_gpio_w.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2026, RT-Thread Development Team + * Copyright (c) 2006-2025, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -9,15 +9,10 @@ * 2026-07-15 rain RA Wireless GPIO adapter */ -#include -#include -#include -#include -#include "r_ext_irq_w.h" -#include "common_data.h" -#include "board.h" +#include -#ifdef BSP_USING_GPIO_W +#ifdef RT_USING_PIN +#ifdef R_EXT_IRQ_W_H #define DBG_TAG "drv.gpio.wireless" #ifdef DRV_DEBUG @@ -156,13 +151,6 @@ static void ra_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode) return; } - err = R_IOPORT_Open(&g_ioport_ctrl, &g_bsp_pin_cfg); - if ((err != FSP_SUCCESS) && (err != FSP_ERR_ALREADY_OPEN)) - { - LOG_E("GPIO open failed"); - return; - } - switch (mode) { case PIN_MODE_OUTPUT: @@ -313,7 +301,6 @@ static rt_err_t ra_pin_attach_irq(struct rt_device *device, rt_base_t pin, rt_hw_interrupt_enable(level); return RT_EOK; } - if (pin_irq_hdr_tab[irqx].pin != -1) { rt_hw_interrupt_enable(level); @@ -438,9 +425,20 @@ const static struct rt_pin_ops _ra_pin_ops = int rt_hw_pin_init(void) { + fsp_err_t err; + ra_irq_tab_init(); + ra_w_pin_config_init(); + + err = R_IOPORT_Open(&g_ioport_ctrl, &g_bsp_pin_cfg); + if ((err != FSP_SUCCESS) && (err != FSP_ERR_ALREADY_OPEN)) + { + LOG_E("GPIO open failed: %d", err); + return -RT_ERROR; + } + return rt_device_pin_register("pin", &_ra_pin_ops, RT_NULL); } - -#endif /* BSP_USING_GPIO_W */ +#endif /* R_EXT_IRQ_W_H */ +#endif /* RT_USING_PIN */ diff --git a/bsp/renesas/ra6w1-ek/board/ports/drv_gpio_w.h b/bsp/renesas/ra6w1-ek/board/ports/drv_gpio_w.h new file mode 100644 index 000000000000..64b94ccfe883 --- /dev/null +++ b/bsp/renesas/ra6w1-ek/board/ports/drv_gpio_w.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2006-2025, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-07-29 KyleChan first version + */ + +#ifndef __DRV_GPIO_H__ +#define __DRV_GPIO_H__ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void ra_w_pin_config_init(void); +int rt_hw_pin_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __DRV_GPIO_H__ */ + diff --git a/bsp/renesas/ra6w1-ek/board/ports/drv_pwm_w.c b/bsp/renesas/ra6w1-ek/board/ports/drv_pwm_w.c new file mode 100644 index 000000000000..d2981896ef73 --- /dev/null +++ b/bsp/renesas/ra6w1-ek/board/ports/drv_pwm_w.c @@ -0,0 +1,220 @@ +#include +#include + +#define LOG_TAG "drv.pwm_w" +#include + +#include "drv_config.h" +#include "hal_data.h" + +#if defined(BSP_USING_PWM) && \ + (defined(BSP_USING_PWM0) || defined(BSP_USING_PWM1) || \ + defined(BSP_USING_PWM2) || defined(BSP_USING_PWM3) || \ + defined(BSP_USING_PWM4) || defined(BSP_USING_PWM5) || \ + defined(BSP_USING_PWM6) || defined(BSP_USING_PWM7)) + +#define RA_PWM_W_MAX_COUNT (TIM_W_PWM_MAX + 1U) +#define RA_PWM_W_CLOCK_HZ(pwm) (BSP_CFG_XTALM_HZ / ((rt_uint32_t) (pwm)->g_cfg->source_div + 1U)) + +enum +{ +#ifdef BSP_USING_PWM0 + BSP_PWM0_INDEX, +#endif +#ifdef BSP_USING_PWM1 + BSP_PWM1_INDEX, +#endif +#ifdef BSP_USING_PWM2 + BSP_PWM2_INDEX, +#endif +#ifdef BSP_USING_PWM3 + BSP_PWM3_INDEX, +#endif +#ifdef BSP_USING_PWM4 + BSP_PWM4_INDEX, +#endif +#ifdef BSP_USING_PWM5 + BSP_PWM5_INDEX, +#endif +#ifdef BSP_USING_PWM6 + BSP_PWM6_INDEX, +#endif +#ifdef BSP_USING_PWM7 + BSP_PWM7_INDEX, +#endif + RA_PWM_W_COUNT +}; + +struct ra_pwm_w +{ + struct rt_device_pwm pwm_device; + tim_w_instance_ctrl_t *g_ctrl; + const timer_cfg_t *g_cfg; + const char *name; +}; + +static struct ra_pwm_w ra_pwm_w_obj[RA_PWM_W_COUNT] = +{ +#ifdef BSP_USING_PWM0 + [BSP_PWM0_INDEX] = { .name = "pwm0", .g_cfg = &g_timer0_cfg, .g_ctrl = &g_timer0_ctrl }, +#endif +#ifdef BSP_USING_PWM1 + [BSP_PWM1_INDEX] = { .name = "pwm1", .g_cfg = &g_timer1_cfg, .g_ctrl = &g_timer1_ctrl }, +#endif +#ifdef BSP_USING_PWM2 + [BSP_PWM2_INDEX] = { .name = "pwm2", .g_cfg = &g_timer2_cfg, .g_ctrl = &g_timer2_ctrl }, +#endif +#ifdef BSP_USING_PWM3 + [BSP_PWM3_INDEX] = { .name = "pwm3", .g_cfg = &g_timer3_cfg, .g_ctrl = &g_timer3_ctrl }, +#endif +#ifdef BSP_USING_PWM4 + [BSP_PWM4_INDEX] = { .name = "pwm4", .g_cfg = &g_timer4_cfg, .g_ctrl = &g_timer4_ctrl }, +#endif +#ifdef BSP_USING_PWM5 + [BSP_PWM5_INDEX] = { .name = "pwm5", .g_cfg = &g_timer5_cfg, .g_ctrl = &g_timer5_ctrl }, +#endif +#ifdef BSP_USING_PWM6 + [BSP_PWM6_INDEX] = { .name = "pwm6", .g_cfg = &g_timer6_cfg, .g_ctrl = &g_timer6_ctrl }, +#endif +#ifdef BSP_USING_PWM7 + [BSP_PWM7_INDEX] = { .name = "pwm7", .g_cfg = &g_timer7_cfg, .g_ctrl = &g_timer7_ctrl }, +#endif +}; + +static rt_uint32_t ra_pwm_w_ns_to_cycles(const struct ra_pwm_w *pwm, + rt_uint32_t nanoseconds) +{ + rt_uint64_t cycles; + rt_uint32_t clock_hz = RA_PWM_W_CLOCK_HZ(pwm); + + if (nanoseconds == 0U) + { + return 0U; + } + + cycles = ((rt_uint64_t) nanoseconds * clock_hz + 999999999ULL) / 1000000000ULL; + if (cycles == 0U) + { + cycles = 1U; + } + if (cycles > RA_PWM_W_MAX_COUNT) + { + cycles = RA_PWM_W_MAX_COUNT; + } + + return (rt_uint32_t) cycles; +} + +static rt_uint32_t ra_pwm_w_cycles_to_ns(const struct ra_pwm_w *pwm, + rt_uint32_t cycles) +{ + return (rt_uint32_t) (((rt_uint64_t) cycles * 1000000000ULL) / + RA_PWM_W_CLOCK_HZ(pwm)); +} + +static rt_err_t ra_pwm_w_set(struct ra_pwm_w *pwm, + struct rt_pwm_configuration *configuration) +{ + rt_uint32_t period_cycles; + rt_uint32_t pulse_cycles; + + if (configuration->period == 0U) + { + return -RT_EINVAL; + } + + period_cycles = ra_pwm_w_ns_to_cycles(pwm, configuration->period); + pulse_cycles = ra_pwm_w_ns_to_cycles(pwm, configuration->pulse); + if (pulse_cycles > period_cycles) + { + pulse_cycles = period_cycles; + } + + /* TIM_W stores period as cycles - 1 and duty as the number of high cycles. */ + if (R_TIM_W_PeriodSet(pwm->g_ctrl, period_cycles - 1U) != FSP_SUCCESS) + { + return -RT_ERROR; + } + + if (pulse_cycles > TIM_W_PWM_MAX) + { + pulse_cycles = TIM_W_PWM_MAX; + } + pwm->g_ctrl->p_reg->TIMER_PWM_CTRL_REG_b.TIM_PWM_DC = (uint16_t) pulse_cycles; + + configuration->channel = 0; + configuration->period = ra_pwm_w_cycles_to_ns(pwm, period_cycles); + configuration->pulse = ra_pwm_w_cycles_to_ns(pwm, pulse_cycles); + return RT_EOK; +} + +static rt_err_t ra_pwm_w_control(struct rt_device_pwm *device, int cmd, void *arg) +{ + struct ra_pwm_w *pwm = (struct ra_pwm_w *) device->parent.user_data; + struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *) arg; + rt_uint32_t period_cycles; + rt_uint32_t pulse_cycles; + + if ((pwm == RT_NULL) || (configuration == RT_NULL) || (configuration->channel != 0U)) + { + return -RT_EINVAL; + } + + switch (cmd) + { + case PWM_CMD_ENABLE: + return (R_TIM_W_Start(pwm->g_ctrl) == FSP_SUCCESS) ? RT_EOK : -RT_ERROR; + + case PWM_CMD_DISABLE: + return (R_TIM_W_Stop(pwm->g_ctrl) == FSP_SUCCESS) ? RT_EOK : -RT_ERROR; + + case PWM_CMD_SET: + return ra_pwm_w_set(pwm, configuration); + + case PWM_CMD_GET: + period_cycles = (rt_uint32_t) pwm->g_ctrl->p_reg->TIMER_PWM_CTRL_REG_b.TIM_PWM_FREQ + 1U; + pulse_cycles = (rt_uint32_t) pwm->g_ctrl->p_reg->TIMER_PWM_CTRL_REG_b.TIM_PWM_DC; + configuration->channel = 0; + configuration->period = ra_pwm_w_cycles_to_ns(pwm, period_cycles); + configuration->pulse = ra_pwm_w_cycles_to_ns(pwm, pulse_cycles); + return RT_EOK; + + default: + return -RT_EINVAL; + } +} + +static const struct rt_pwm_ops ra_pwm_w_ops = +{ + .control = ra_pwm_w_control, +}; + +static int rt_hw_pwm_w_init(void) +{ + int result = RT_EOK; + + for (rt_size_t i = 0; i < RA_PWM_W_COUNT; i++) + { + if (R_TIM_W_Open(ra_pwm_w_obj[i].g_ctrl, ra_pwm_w_obj[i].g_cfg) != FSP_SUCCESS) + { + LOG_E("%s open failed", ra_pwm_w_obj[i].name); + result = -RT_ERROR; + continue; + } + + if (rt_device_pwm_register(&ra_pwm_w_obj[i].pwm_device, + ra_pwm_w_obj[i].name, + &ra_pwm_w_ops, + &ra_pwm_w_obj[i]) != RT_EOK) + { + LOG_E("%s register failed", ra_pwm_w_obj[i].name); + (void) R_TIM_W_Close(ra_pwm_w_obj[i].g_ctrl); + result = -RT_ERROR; + } + } + + return result; +} +INIT_BOARD_EXPORT(rt_hw_pwm_w_init); + +#endif /* BSP_USING_PWM */ diff --git a/bsp/renesas/ra6w1-ek/board/ports/drv_timer_w.c b/bsp/renesas/ra6w1-ek/board/ports/drv_timer_w.c new file mode 100644 index 000000000000..b82832062249 --- /dev/null +++ b/bsp/renesas/ra6w1-ek/board/ports/drv_timer_w.c @@ -0,0 +1,382 @@ +#include +#include + +#define LOG_TAG "drv.timer_w" +#include + +#include "drv_config.h" +#include "hal_data.h" + +#define RA_TIMER_W_MAX_FREQ (BSP_CFG_XTALM_HZ) +#define RA_TIMER_W_MIN_FREQ (BSP_CFG_XTALM_HZ / 32U) +#define RA_TIMER_W_FREQ_COUNT (32U) + +#define RA_TIMER_W_FREQ_TABLE \ + BSP_CFG_XTALM_HZ / 1U, BSP_CFG_XTALM_HZ / 2U, BSP_CFG_XTALM_HZ / 3U, BSP_CFG_XTALM_HZ / 4U, \ + BSP_CFG_XTALM_HZ / 5U, BSP_CFG_XTALM_HZ / 6U, BSP_CFG_XTALM_HZ / 7U, BSP_CFG_XTALM_HZ / 8U, \ + BSP_CFG_XTALM_HZ / 9U, BSP_CFG_XTALM_HZ / 10U, BSP_CFG_XTALM_HZ / 11U, BSP_CFG_XTALM_HZ / 12U, \ + BSP_CFG_XTALM_HZ / 13U, BSP_CFG_XTALM_HZ / 14U, BSP_CFG_XTALM_HZ / 15U, BSP_CFG_XTALM_HZ / 16U, \ + BSP_CFG_XTALM_HZ / 17U, BSP_CFG_XTALM_HZ / 18U, BSP_CFG_XTALM_HZ / 19U, BSP_CFG_XTALM_HZ / 20U, \ + BSP_CFG_XTALM_HZ / 21U, BSP_CFG_XTALM_HZ / 22U, BSP_CFG_XTALM_HZ / 23U, BSP_CFG_XTALM_HZ / 24U, \ + BSP_CFG_XTALM_HZ / 25U, BSP_CFG_XTALM_HZ / 26U, BSP_CFG_XTALM_HZ / 27U, BSP_CFG_XTALM_HZ / 28U, \ + BSP_CFG_XTALM_HZ / 29U, BSP_CFG_XTALM_HZ / 30U, BSP_CFG_XTALM_HZ / 31U, BSP_CFG_XTALM_HZ / 32U + +enum +{ +#if defined(BSP_USING_TIM0) && !defined(BSP_USING_PWM0) + BSP_TIMER0_INDEX, +#endif +#if defined(BSP_USING_TIM1) && !defined(BSP_USING_PWM1) + BSP_TIMER1_INDEX, +#endif +#if defined(BSP_USING_TIM2) && !defined(BSP_USING_PWM2) + BSP_TIMER2_INDEX, +#endif +#if defined(BSP_USING_TIM3) && !defined(BSP_USING_PWM3) + BSP_TIMER3_INDEX, +#endif +#if defined(BSP_USING_TIM4) && !defined(BSP_USING_PWM4) + BSP_TIMER4_INDEX, +#endif +#if defined(BSP_USING_TIM5) && !defined(BSP_USING_PWM5) + BSP_TIMER5_INDEX, +#endif +#if defined(BSP_USING_TIM6) && !defined(BSP_USING_PWM6) + BSP_TIMER6_INDEX, +#endif +#if defined(BSP_USING_TIM7) && !defined(BSP_USING_PWM7) + BSP_TIMER7_INDEX, +#endif + RA_TIMER_W_TIMER_COUNT +}; + +#ifdef RT_USING_CLOCK_TIME +struct ra_timer_w_timer +{ + rt_clock_timer_t tmr_device; + tim_w_instance_ctrl_t *g_ctrl; + const timer_instance_t *g_timer; + const timer_cfg_t *g_cfg; + const char *name; + rt_bool_t opened; +}; + +static struct ra_timer_w_timer ra_timer_w_timer_obj[RA_TIMER_W_TIMER_COUNT] = +{ +#if defined(BSP_USING_TIM0) && !defined(BSP_USING_PWM0) + [BSP_TIMER0_INDEX] = { .name = "timer0", .g_cfg = &g_timer0_cfg, .g_ctrl = &g_timer0_ctrl, .g_timer = &g_timer0 }, +#endif +#if defined(BSP_USING_TIM1) && !defined(BSP_USING_PWM1) + [BSP_TIMER1_INDEX] = { .name = "timer1", .g_cfg = &g_timer1_cfg, .g_ctrl = &g_timer1_ctrl, .g_timer = &g_timer1 }, +#endif +#if defined(BSP_USING_TIM2) && !defined(BSP_USING_PWM2) + [BSP_TIMER2_INDEX] = { .name = "timer2", .g_cfg = &g_timer2_cfg, .g_ctrl = &g_timer2_ctrl, .g_timer = &g_timer2 }, +#endif +#if defined(BSP_USING_TIM3) && !defined(BSP_USING_PWM3) + [BSP_TIMER3_INDEX] = { .name = "timer3", .g_cfg = &g_timer3_cfg, .g_ctrl = &g_timer3_ctrl, .g_timer = &g_timer3 }, +#endif +#if defined(BSP_USING_TIM4) && !defined(BSP_USING_PWM4) + [BSP_TIMER4_INDEX] = { .name = "timer4", .g_cfg = &g_timer4_cfg, .g_ctrl = &g_timer4_ctrl, .g_timer = &g_timer4 }, +#endif +#if defined(BSP_USING_TIM5) && !defined(BSP_USING_PWM5) + [BSP_TIMER5_INDEX] = { .name = "timer5", .g_cfg = &g_timer5_cfg, .g_ctrl = &g_timer5_ctrl, .g_timer = &g_timer5 }, +#endif +#if defined(BSP_USING_TIM6) && !defined(BSP_USING_PWM6) + [BSP_TIMER6_INDEX] = { .name = "timer6", .g_cfg = &g_timer6_cfg, .g_ctrl = &g_timer6_ctrl, .g_timer = &g_timer6 }, +#endif +#if defined(BSP_USING_TIM7) && !defined(BSP_USING_PWM7) + [BSP_TIMER7_INDEX] = { .name = "timer7", .g_cfg = &g_timer7_cfg, .g_ctrl = &g_timer7_ctrl, .g_timer = &g_timer7 }, +#endif +}; + +static const rt_uint32_t ra_timer_w_freq_table[RA_TIMER_W_FREQ_COUNT] = +{ + RA_TIMER_W_FREQ_TABLE +}; + +static rt_uint32_t ra_timer_w_freq_select(rt_uint32_t requested, rt_uint32_t *actual) +{ + rt_uint32_t index = 0; + rt_uint64_t best_diff = ~(rt_uint64_t) 0; + + for (rt_uint32_t i = 0; i < RA_TIMER_W_FREQ_COUNT; i++) + { + rt_uint64_t current = ra_timer_w_freq_table[i]; + rt_uint64_t diff = (current > requested) ? (current - requested) : (requested - current); + + if (diff < best_diff) + { + best_diff = diff; + index = i; + } + } + + if (actual != RT_NULL) + { + *actual = ra_timer_w_freq_table[index]; + } + + return index; +} + +static void timer_init(struct rt_clock_timer_device *timer, rt_uint32_t state) +{ + struct ra_timer_w_timer *tim; + + RT_ASSERT(timer != RT_NULL); + tim = (struct ra_timer_w_timer *) timer->parent.user_data; + + if (state) + { + if (R_TIM_W_Open(tim->g_ctrl, tim->g_cfg) != FSP_SUCCESS) + { + LOG_E("%s init failed", tim->name); + return; + } + + tim->opened = RT_TRUE; + } + else if (tim->opened) + { + if (R_TIM_W_Close(tim->g_ctrl) != FSP_SUCCESS) + { + LOG_W("%s close failed", tim->name); + } + + tim->opened = RT_FALSE; + } +} + +static rt_err_t timer_start(rt_clock_timer_t *timer, rt_uint32_t period, + rt_clock_timer_mode_t mode) +{ + struct ra_timer_w_timer *tim; + + RT_ASSERT(timer != RT_NULL); + RT_UNUSED(mode); + + tim = (struct ra_timer_w_timer *) timer->parent.user_data; + if (!tim->opened) + { + return -RT_ERROR; + } + + /* TIM_W one-shot timing is stopped by rt_clock_timer_isr(). */ + if (R_TIM_W_Reset(tim->g_ctrl) != FSP_SUCCESS || + R_TIM_W_PeriodSet(tim->g_ctrl, period) != FSP_SUCCESS || + R_TIM_W_Start(tim->g_ctrl) != FSP_SUCCESS) + { + LOG_E("%s start failed", tim->name); + return -RT_ERROR; + } + + return RT_EOK; +} + +static void timer_stop(rt_clock_timer_t *timer) +{ + struct ra_timer_w_timer *tim; + + RT_ASSERT(timer != RT_NULL); + tim = (struct ra_timer_w_timer *) timer->parent.user_data; + + if (!tim->opened) + { + return; + } + + (void) R_TIM_W_Stop(tim->g_ctrl); + (void) R_TIM_W_Reset(tim->g_ctrl); +} + +static rt_uint32_t timer_counter_get(rt_clock_timer_t *timer) +{ + struct ra_timer_w_timer *tim; + timer_status_t status; + + RT_ASSERT(timer != RT_NULL); + tim = (struct ra_timer_w_timer *) timer->parent.user_data; + + if (!tim->opened || (R_TIM_W_StatusGet(tim->g_ctrl, &status) != FSP_SUCCESS)) + { + return 0; + } + + return status.counter; +} + +static rt_err_t timer_ctrl(rt_clock_timer_t *timer, rt_uint32_t cmd, void *arg) +{ + struct ra_timer_w_timer *tim; + rt_uint32_t requested; + rt_uint32_t actual; + rt_uint32_t divider; + + RT_ASSERT(timer != RT_NULL); + tim = (struct ra_timer_w_timer *) timer->parent.user_data; + + if (cmd != CLOCK_TIMER_CTRL_FREQ_SET) + { + return -RT_ENOSYS; + } + + if (arg == RT_NULL) + { + return -RT_EINVAL; + } + + requested = *((rt_uint32_t *) arg); + if ((requested < RA_TIMER_W_MIN_FREQ) || + (requested > RA_TIMER_W_MAX_FREQ)) + { + return -RT_EINVAL; + } + + divider = ra_timer_w_freq_select(requested, &actual); + tim->g_ctrl->p_reg->TIMER_PRE_SETTINGS_REG_b.TIM_PRESCALER2 = divider; + + /* clock_timer stores the value returned through arg as its active rate. */ + *((rt_uint32_t *) arg) = actual; + return RT_EOK; +} + +#if defined(BSP_USING_TIM0) && !defined(BSP_USING_PWM0) +void timer0_callback(timer_callback_args_t *p_args) +{ + rt_interrupt_enter(); + if ((p_args != RT_NULL) && (p_args->event == TIMER_EVENT_CYCLE_END)) + { + rt_clock_timer_isr(&ra_timer_w_timer_obj[BSP_TIMER0_INDEX].tmr_device); + } + rt_interrupt_leave(); +} +#endif + +#if defined(BSP_USING_TIM1) && !defined(BSP_USING_PWM1) +void timer1_callback(timer_callback_args_t *p_args) +{ + rt_interrupt_enter(); + if ((p_args != RT_NULL) && (p_args->event == TIMER_EVENT_CYCLE_END)) + { + rt_clock_timer_isr(&ra_timer_w_timer_obj[BSP_TIMER1_INDEX].tmr_device); + } + rt_interrupt_leave(); +} +#endif + +#if defined(BSP_USING_TIM2) && !defined(BSP_USING_PWM2) +void timer2_callback(timer_callback_args_t *p_args) +{ + rt_interrupt_enter(); + if ((p_args != RT_NULL) && (p_args->event == TIMER_EVENT_CYCLE_END)) + { + rt_clock_timer_isr(&ra_timer_w_timer_obj[BSP_TIMER2_INDEX].tmr_device); + } + rt_interrupt_leave(); +} +#endif + +#if defined(BSP_USING_TIM3) && !defined(BSP_USING_PWM3) +void timer3_callback(timer_callback_args_t *p_args) +{ + rt_interrupt_enter(); + if ((p_args != RT_NULL) && (p_args->event == TIMER_EVENT_CYCLE_END)) + { + rt_clock_timer_isr(&ra_timer_w_timer_obj[BSP_TIMER3_INDEX].tmr_device); + } + rt_interrupt_leave(); +} +#endif + +#if defined(BSP_USING_TIM4) && !defined(BSP_USING_PWM4) +void timer4_callback(timer_callback_args_t *p_args) +{ + rt_interrupt_enter(); + if ((p_args != RT_NULL) && (p_args->event == TIMER_EVENT_CYCLE_END)) + { + rt_clock_timer_isr(&ra_timer_w_timer_obj[BSP_TIMER4_INDEX].tmr_device); + } + rt_interrupt_leave(); +} +#endif + +#if defined(BSP_USING_TIM5) && !defined(BSP_USING_PWM5) +void timer5_callback(timer_callback_args_t *p_args) +{ + rt_interrupt_enter(); + if ((p_args != RT_NULL) && (p_args->event == TIMER_EVENT_CYCLE_END)) + { + rt_clock_timer_isr(&ra_timer_w_timer_obj[BSP_TIMER5_INDEX].tmr_device); + } + rt_interrupt_leave(); +} +#endif + +#if defined(BSP_USING_TIM6) && !defined(BSP_USING_PWM6) +void timer6_callback(timer_callback_args_t *p_args) +{ + rt_interrupt_enter(); + if ((p_args != RT_NULL) && (p_args->event == TIMER_EVENT_CYCLE_END)) + { + rt_clock_timer_isr(&ra_timer_w_timer_obj[BSP_TIMER6_INDEX].tmr_device); + } + rt_interrupt_leave(); +} +#endif + +#if defined(BSP_USING_TIM7) && !defined(BSP_USING_PWM7) +void timer7_callback(timer_callback_args_t *p_args) +{ + rt_interrupt_enter(); + if ((p_args != RT_NULL) && (p_args->event == TIMER_EVENT_CYCLE_END)) + { + rt_clock_timer_isr(&ra_timer_w_timer_obj[BSP_TIMER7_INDEX].tmr_device); + } + rt_interrupt_leave(); +} +#endif + +static const struct rt_clock_timer_ops ra_timer_w_ops = +{ + .init = timer_init, + .start = timer_start, + .stop = timer_stop, + .count_get = timer_counter_get, + .control = timer_ctrl, +}; + +static const struct rt_clock_timer_info ra_timer_w_info = +{ + .maxfreq = RA_TIMER_W_MAX_FREQ, + .minfreq = RA_TIMER_W_MIN_FREQ, + .maxcnt = 0xFFFFFFFFU, + .cntmode = CLOCK_TIMER_CNTMODE_UP, +}; + +static int rt_hw_timer_w_init(void) +{ + int result = RT_EOK; + + for (rt_size_t i = 0; i < RA_TIMER_W_TIMER_COUNT; i++) + { + ra_timer_w_timer_obj[i].tmr_device.info = &ra_timer_w_info; + ra_timer_w_timer_obj[i].tmr_device.ops = &ra_timer_w_ops; + + if (rt_clock_timer_register(&ra_timer_w_timer_obj[i].tmr_device, + ra_timer_w_timer_obj[i].name, + &ra_timer_w_timer_obj[i]) != RT_EOK) + { + LOG_E("%s register failed", ra_timer_w_timer_obj[i].name); + result = -RT_ERROR; + } + else + { + LOG_D("%s register success", ra_timer_w_timer_obj[i].name); + } + } + + return result; +} +INIT_BOARD_EXPORT(rt_hw_timer_w_init); + +#endif /* RT_USING_CLOCK_TIME */ diff --git a/bsp/renesas/ra6w1-ek/board/ports/fal_cfg.h b/bsp/renesas/ra6w1-ek/board/ports/fal_cfg.h new file mode 100644 index 000000000000..fd455fb6f595 --- /dev/null +++ b/bsp/renesas/ra6w1-ek/board/ports/fal_cfg.h @@ -0,0 +1,27 @@ +#ifndef __RA6W1_FAL_CFG_H__ +#define __RA6W1_FAL_CFG_H__ + +#include +#include "bsp_api.h" +#include "bsp_sflash_map_ra6w1.h" + +#define RA6W1_OSPI_FLASH_DEV_NAME "ospi_flash" + +#if defined(BSP_USING_OSPI_FLASH) +extern const struct fal_flash_dev ra6w1_ospi_flash; + +#define FAL_FLASH_DEV_TABLE \ +{ \ + &ra6w1_ospi_flash, \ +} + +#ifdef FAL_PART_HAS_TABLE_CFG +#define FAL_PART_TABLE \ +{ \ + {FAL_PART_MAGIC_WORD, "filesystem", RA6W1_OSPI_FLASH_DEV_NAME, SF_USER_AREA, SF_USER_AREA_SIZE, 0}, \ +} +#endif /* FAL_PART_HAS_TABLE_CFG */ + +#endif /* BSP_USING_OSPI_FLASH */ + +#endif /* __RA6W1_FAL_CFG_H__ */ diff --git a/bsp/renesas/ra6w1-ek/board/ports/gpio_cfg.h b/bsp/renesas/ra6w1-ek/board/ports/gpio_cfg.h deleted file mode 100644 index ad2b4c86d17c..000000000000 --- a/bsp/renesas/ra6w1-ek/board/ports/gpio_cfg.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2006-2026, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-01-19 Sherman first version - */ - -/* Number of IRQ channels on the device */ -#define RA_IRQ_MAX 16 - -/* PIN to IRQx table */ -#define PIN2IRQX_TABLE \ -{ \ - switch (pin) \ - { \ - case BSP_IO_PORT_04_PIN_00: \ - case BSP_IO_PORT_02_PIN_06: \ - case BSP_IO_PORT_01_PIN_05: \ - return 0; \ - case BSP_IO_PORT_02_PIN_05: \ - case BSP_IO_PORT_01_PIN_01: \ - case BSP_IO_PORT_01_PIN_04: \ - return 1; \ - case BSP_IO_PORT_02_PIN_03: \ - case BSP_IO_PORT_01_PIN_00: \ - case BSP_IO_PORT_02_PIN_13: \ - return 2; \ - case BSP_IO_PORT_02_PIN_02: \ - case BSP_IO_PORT_01_PIN_10: \ - case BSP_IO_PORT_02_PIN_12: \ - return 3; \ - case BSP_IO_PORT_04_PIN_02: \ - case BSP_IO_PORT_01_PIN_11: \ - case BSP_IO_PORT_04_PIN_11: \ - return 4; \ - case BSP_IO_PORT_04_PIN_01: \ - case BSP_IO_PORT_03_PIN_02: \ - case BSP_IO_PORT_04_PIN_10: \ - return 5; \ - case BSP_IO_PORT_03_PIN_01: \ - case BSP_IO_PORT_00_PIN_00: \ - case BSP_IO_PORT_04_PIN_09: \ - return 6; \ - case BSP_IO_PORT_00_PIN_01: \ - case BSP_IO_PORT_04_PIN_08: \ - return 7; \ - case BSP_IO_PORT_00_PIN_02: \ - case BSP_IO_PORT_03_PIN_05: \ - case BSP_IO_PORT_04_PIN_15: \ - return 8; \ - case BSP_IO_PORT_00_PIN_04: \ - case BSP_IO_PORT_03_PIN_04: \ - case BSP_IO_PORT_04_PIN_14: \ - return 9; \ - case BSP_IO_PORT_00_PIN_05: \ - case BSP_IO_PORT_07_PIN_09: \ - return 10; \ - case BSP_IO_PORT_05_PIN_01: \ - case BSP_IO_PORT_00_PIN_06: \ - case BSP_IO_PORT_07_PIN_08: \ - return 11; \ - case BSP_IO_PORT_05_PIN_02: \ - case BSP_IO_PORT_00_PIN_08: \ - return 12; \ - case BSP_IO_PORT_00_PIN_15: \ - case BSP_IO_PORT_00_PIN_09: \ - return 13; \ - case BSP_IO_PORT_04_PIN_03: \ - case BSP_IO_PORT_05_PIN_12: \ - case BSP_IO_PORT_05_PIN_05: \ - return 14; \ - case BSP_IO_PORT_04_PIN_04: \ - case BSP_IO_PORT_05_PIN_11: \ - case BSP_IO_PORT_05_PIN_06: \ - return 15; \ - default : \ - return -1; \ - } \ -} - diff --git a/bsp/renesas/ra6w1-ek/board/ports/ra6w1_ospi_flash.c b/bsp/renesas/ra6w1-ek/board/ports/ra6w1_ospi_flash.c new file mode 100644 index 000000000000..91698fc6df71 --- /dev/null +++ b/bsp/renesas/ra6w1-ek/board/ports/ra6w1_ospi_flash.c @@ -0,0 +1,185 @@ +#include + +#if defined(BSP_USING_OSPI_FLASH) + +#include +#include + +#include "fal_cfg.h" +#include +#include "hal_data.h" +#include "bsp_sflash_map_ra6w1.h" + +static int ra6w1_ospi_flash_init(void) +{ + return RT_EOK; +} + +static int ra6w1_ospi_flash_read(long offset, rt_uint8_t *buf, rt_size_t size) +{ + rt_memcpy((void *) buf, (void *) ((uint32_t)offset | OSPI_W_AUTOMODE_BASE_ADD), size); + return (int)size; +} + +static int ra6w1_ospi_flash_write(long offset, const rt_uint8_t *buf, rt_size_t size) +{ + uint32_t addr = (uint32_t)offset; + uint32_t remaining = (uint32_t)size; + uint32_t buf_offs = 0; + uint32_t write_len; + fsp_err_t err; + + R_OSPI_W_Open((spi_flash_ctrl_t *)&g_ospi_flash_ctrl, &g_ospi_flash_cfg); + + while (remaining > 0) + { + write_len = (remaining > FLASH_SECTOR_SIZE) ? FLASH_SECTOR_SIZE : remaining; + + /* Stash tail if writing less than a full sector */ + uint8_t *stash = RT_NULL; + uint32_t stash_len = 0; + + if (write_len < FLASH_SECTOR_SIZE) + { + stash_len = FLASH_SECTOR_SIZE - write_len; + stash = rt_malloc(stash_len); + if (stash == RT_NULL) + return -RT_ENOMEM; + + rt_memcpy(stash, + (const void *)((addr + write_len) | OSPI_W_AUTOMODE_BASE_ADD), + stash_len); + } + + err = R_OSPI_W_Erase((spi_flash_ctrl_t *)&g_ospi_flash_ctrl, + (uint8_t *)(uintptr_t)addr, + FLASH_SECTOR_SIZE); + if (err != FSP_SUCCESS) + { + if (stash) rt_free(stash); + return -RT_ERROR; + } + + err = R_OSPI_W_Write((spi_flash_ctrl_t *)&g_ospi_flash_ctrl, + buf + buf_offs, + (uint8_t *)(uintptr_t)addr, + write_len); + if (err != FSP_SUCCESS) + { + if (stash) rt_free(stash); + return -RT_ERROR; + } + + addr += write_len; + buf_offs += write_len; + + /* Restore stashed tail */ + if (stash_len > 0) + { + err = R_OSPI_W_Write((spi_flash_ctrl_t *)&g_ospi_flash_ctrl, + stash, + (uint8_t *)(uintptr_t)addr, + stash_len); + rt_free(stash); + + if (err != FSP_SUCCESS) + return -RT_ERROR; + } + + remaining -= write_len; + } + + return (int)size; +} + +static int ra6w1_ospi_flash_erase(long offset, rt_size_t size) +{ + uint32_t addr = (uint32_t)offset; + uint32_t remaining = (uint32_t)size; + uint32_t erase_len; + fsp_err_t err; + + R_OSPI_W_Open((spi_flash_ctrl_t *)&g_ospi_flash_ctrl, &g_ospi_flash_cfg); + + while (remaining > 0) + { + erase_len = (remaining > FLASH_SECTOR_SIZE) ? FLASH_SECTOR_SIZE : remaining; + + /* Stash tail if erasing less than a full sector */ + uint8_t *stash = RT_NULL; + uint32_t stash_len = 0; + + if (erase_len < FLASH_SECTOR_SIZE) + { + stash_len = FLASH_SECTOR_SIZE - erase_len; + stash = rt_malloc(stash_len); + if (stash == RT_NULL) + return -RT_ENOMEM; + + rt_memcpy(stash, + (const void *)((addr + erase_len) | OSPI_W_AUTOMODE_BASE_ADD), + stash_len); + } + + err = R_OSPI_W_Erase((spi_flash_ctrl_t *)&g_ospi_flash_ctrl, + (uint8_t *)(uintptr_t)addr, + FLASH_SECTOR_SIZE); + if (err != FSP_SUCCESS) + { + if (stash) rt_free(stash); + return -RT_ERROR; + } + + addr += erase_len; + + /* Restore stashed tail */ + if (stash_len > 0) + { + err = R_OSPI_W_Write((spi_flash_ctrl_t *)&g_ospi_flash_ctrl, + stash, + (uint8_t *)(uintptr_t)addr, + stash_len); + rt_free(stash); + + if (err != FSP_SUCCESS) + return -RT_ERROR; + } + + remaining -= erase_len; + } + + return (int)size; +} + +const struct fal_flash_dev ra6w1_ospi_flash = +{ + .name = RA6W1_OSPI_FLASH_DEV_NAME, + .addr = SF_BASE_ADDR, + .len = MEMORY_QSPIF_SIZE, + .blk_size = FLASH_SECTOR_SIZE, + .ops = + { + .init = ra6w1_ospi_flash_init, + .read = ra6w1_ospi_flash_read, + .write = ra6w1_ospi_flash_write, + .erase = ra6w1_ospi_flash_erase, + }, + .write_gran = 1, + .blocks = + { + { + .size = FLASH_SECTOR_SIZE, + .count = MEMORY_QSPIF_SIZE / FLASH_SECTOR_SIZE, + }, + }, +}; + +static int ra6w1_fal_auto_init(void) +{ + fal_init(); + + return RT_EOK; +} +INIT_COMPONENT_EXPORT(ra6w1_fal_auto_init); + +#endif /* RT_USING_FAL && BSP_USING_OSPI_FLASH */ diff --git a/bsp/renesas/ra6w1-ek/board/ports/ra6w1_qspi_psram.c b/bsp/renesas/ra6w1-ek/board/ports/ra6w1_qspi_psram.c new file mode 100644 index 000000000000..e2e275931bbe --- /dev/null +++ b/bsp/renesas/ra6w1-ek/board/ports/ra6w1_qspi_psram.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2006-2026, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#ifdef BSP_USING_QSPI_PSRAM +#include +#include "hal_data.h" +#include "r_qspi_w.h" + +#define RA6W1_QSPI_PSRAM_SZ_1K (1024U) +#define RA6W1_QSPI_PSRAM_SZ_1M (RA6W1_QSPI_PSRAM_SZ_1K * RA6W1_QSPI_PSRAM_SZ_1K) + +#define QSPI_RAM_COMMAND_ENTER_QPI_MODE (0x35U) +#define QSPI_RAM_COMMAND_EXIT_QPI_MODE (0xF5U) +#define QSPI_RAM_COMMAND_READ_ID (0x9FU) +#define QSPI_RAM_COMMAND_RESET_ENABLE (0x66U) +#define QSPI_RAM_COMMAND_RESET (0x99U) +#define RA6W1_QSPI_PSRAM_ID_LENGTH (9U) + +#define RA6W1_QSPI_PSRAM_DEFAULT_SIZE (8U * RA6W1_QSPI_PSRAM_SZ_1M) +#define RA6W1_QSPI_PSRAM_MEMHEAP_NAME "psram" + +struct ra6w1_qspi_psram_density +{ + rt_uint32_t mbits; + rt_size_t bytes; + const char *name; +}; + +static const struct ra6w1_qspi_psram_density s_qspi_psram_density[] = +{ + {16U, 2U * RA6W1_QSPI_PSRAM_SZ_1M, "16Mbit/2MiB"}, + {32U, 4U * RA6W1_QSPI_PSRAM_SZ_1M, "32Mbit/4MiB"}, + {64U, 8U * RA6W1_QSPI_PSRAM_SZ_1M, "64Mbit/8MiB"}, +}; + +static rt_bool_t s_qspi_psram_opened = RT_FALSE; +static rt_bool_t s_qspi_psram_initialized = RT_FALSE; +static rt_size_t s_qspi_psram_size = RA6W1_QSPI_PSRAM_DEFAULT_SIZE; + +#ifdef RT_USING_MEMHEAP +static struct rt_memheap s_qspi_psram_memheap; +static rt_bool_t s_qspi_psram_memheap_initialized = RT_FALSE; +#endif + +static rt_err_t ra6w1_fsp_to_rt_err(fsp_err_t err) +{ + if ((FSP_SUCCESS == err) || (FSP_ERR_ALREADY_OPEN == err)) + return RT_EOK; + return -RT_ERROR; +} + +static rt_err_t ra6w1_qspi_psram_open(void) +{ + fsp_err_t err; + if (s_qspi_psram_opened) return RT_EOK; + err = R_QSPI_W_Open(&g_qspi_ram0_ctrl, &g_qspi_ram0_cfg); + if ((FSP_SUCCESS != err) && (FSP_ERR_ALREADY_OPEN != err)) + { + rt_kprintf("[qspi] open failed: %d\n", (int)err); + return ra6w1_fsp_to_rt_err(err); + } + s_qspi_psram_opened = RT_TRUE; + return RT_EOK; +} + +static rt_err_t ra6w1_qspi_psram_set_protocol(spi_flash_protocol_t protocol) +{ + fsp_err_t err; + + err = R_QSPI_W_SpiProtocolSet(&g_qspi_ram0_ctrl, protocol); + if (FSP_SUCCESS != err) + { + rt_kprintf("[qspi] protocol set failed: %d\n", (int)err); + return ra6w1_fsp_to_rt_err(err); + } + + return RT_EOK; +} + +static rt_err_t ra6w1_qspi_psram_exit_qpi_mode(void) +{ + fsp_err_t err; + uint8_t cmd = QSPI_RAM_COMMAND_EXIT_QPI_MODE; + + if (RT_EOK != ra6w1_qspi_psram_set_protocol(SPI_FLASH_PROTOCOL_QPI)) + return -RT_ERROR; + + err = R_QSPI_W_DirectWrite(&g_qspi_ram0_ctrl, &cmd, 1, false); + if (FSP_SUCCESS != err) return ra6w1_fsp_to_rt_err(err); + + return ra6w1_qspi_psram_set_protocol(SPI_FLASH_PROTOCOL_EXTENDED_SPI); +} + +static rt_err_t ra6w1_qspi_psram_reset(void) +{ + fsp_err_t err; + uint8_t cmd = QSPI_RAM_COMMAND_RESET_ENABLE; + + /* A CPU-only reset can leave the external PSRAM in QPI mode. Exit QPI first so SPI reset/read-ID work. */ + (void)ra6w1_qspi_psram_exit_qpi_mode(); + + if (RT_EOK != ra6w1_qspi_psram_set_protocol(SPI_FLASH_PROTOCOL_EXTENDED_SPI)) + return -RT_ERROR; + + err = R_QSPI_W_DirectWrite(&g_qspi_ram0_ctrl, &cmd, 1, false); + if (FSP_SUCCESS != err) return ra6w1_fsp_to_rt_err(err); + + cmd = QSPI_RAM_COMMAND_RESET; + err = R_QSPI_W_DirectWrite(&g_qspi_ram0_ctrl, &cmd, 1, false); + if (FSP_SUCCESS != err) return ra6w1_fsp_to_rt_err(err); + + s_qspi_psram_initialized = RT_FALSE; + return RT_EOK; +} + +static rt_err_t ra6w1_qspi_psram_read_id(rt_uint8_t id[RA6W1_QSPI_PSRAM_ID_LENGTH]) +{ + fsp_err_t err; + rt_uint8_t cmd[4] = {QSPI_RAM_COMMAND_READ_ID, 0, 0, 0}; + + err = R_QSPI_W_DirectWrite(&g_qspi_ram0_ctrl, cmd, sizeof(cmd), true); + if (FSP_SUCCESS != err) return ra6w1_fsp_to_rt_err(err); + + err = R_QSPI_W_DirectRead(&g_qspi_ram0_ctrl, id, RA6W1_QSPI_PSRAM_ID_LENGTH); + if (FSP_SUCCESS != err) return ra6w1_fsp_to_rt_err(err); + + return RT_EOK; +} + +static void ra6w1_qspi_psram_update_size_from_id(const rt_uint8_t id[RA6W1_QSPI_PSRAM_ID_LENGTH]) +{ + rt_uint8_t density = id[2] >> 5; + + rt_kprintf("[qspi] id:"); + for (rt_uint32_t i = 0; i < RA6W1_QSPI_PSRAM_ID_LENGTH; i++) + { + rt_kprintf(" %02x", id[i]); + } + rt_kprintf("\n"); + + if (0x5DU != id[1]) + { + rt_kprintf("[qspi] warning: KGD=0x%02x, keep default size %lu bytes\n", + id[1], + (unsigned long)s_qspi_psram_size); + return; + } + + if (density < (sizeof(s_qspi_psram_density) / sizeof(s_qspi_psram_density[0]))) + { + s_qspi_psram_size = s_qspi_psram_density[density].bytes; + rt_kprintf("[qspi] density=%s\n", s_qspi_psram_density[density].name); + } + else + { + rt_kprintf("[qspi] warning: unknown density index %u, keep default size %lu bytes\n", + density, + (unsigned long)s_qspi_psram_size); + } +} + +static rt_err_t ra6w1_qspi_psram_enter_qpi(void) +{ + fsp_err_t err; + uint8_t cmd = QSPI_RAM_COMMAND_ENTER_QPI_MODE; + + err = R_QSPI_W_DirectWrite(&g_qspi_ram0_ctrl, &cmd, 1, false); + if (FSP_SUCCESS != err) return ra6w1_fsp_to_rt_err(err); + + return ra6w1_qspi_psram_set_protocol(SPI_FLASH_PROTOCOL_QPI); +} + +rt_err_t ra6w1_qspi_psram_init(void) +{ + rt_err_t ret; + rt_uint8_t id[RA6W1_QSPI_PSRAM_ID_LENGTH]; + + if (s_qspi_psram_initialized) return RT_EOK; + + ret = ra6w1_qspi_psram_open(); + if (RT_EOK != ret) return ret; + + ret = ra6w1_qspi_psram_reset(); + if (RT_EOK != ret) return ret; + + if (RT_EOK == ra6w1_qspi_psram_read_id(id)) + { + ra6w1_qspi_psram_update_size_from_id(id); + } + else + { + rt_kprintf("[qspi] warning: read id failed, keep default size %lu bytes\n", + (unsigned long)s_qspi_psram_size); + } + + ret = ra6w1_qspi_psram_enter_qpi(); + if (RT_EOK != ret) + { + rt_kprintf("[qspi] enter QPI failed: %d\n", (int)ret); + return ret; + } + + s_qspi_psram_initialized = RT_TRUE; + rt_kprintf("[qspi] PSRAM ready, QPI 4-4-4 mode, size=%lu base=0x%08x\n", + (unsigned long)s_qspi_psram_size, + (unsigned)(uintptr_t)QSPI_W_DEVICE_START_ADDRESS); + return RT_EOK; +} + +void *ra6w1_qspi_psram_base(void) +{ + return (void *)QSPI_W_DEVICE_START_ADDRESS; +} + +rt_size_t ra6w1_qspi_psram_size(void) +{ + return s_qspi_psram_size; +} + +#ifdef RT_USING_MEMHEAP +rt_err_t ra6w1_qspi_psram_memheap_init(void) +{ + rt_err_t ret; + + if (s_qspi_psram_memheap_initialized) return RT_EOK; + + ret = ra6w1_qspi_psram_init(); + if (RT_EOK != ret) return ret; + + ret = rt_memheap_init(&s_qspi_psram_memheap, + RA6W1_QSPI_PSRAM_MEMHEAP_NAME, + (void *)QSPI_W_DEVICE_START_ADDRESS, + s_qspi_psram_size); + if (RT_EOK != ret) + { + rt_kprintf("[qspi] PSRAM memheap init failed: %d\n", (int)ret); + return ret; + } + + s_qspi_psram_memheap_initialized = RT_TRUE; + rt_kprintf("[qspi] PSRAM memheap ready, name=%s total=%lu available=%lu\n", + RA6W1_QSPI_PSRAM_MEMHEAP_NAME, + (unsigned long)s_qspi_psram_memheap.pool_size, + (unsigned long)s_qspi_psram_memheap.available_size); + + return RT_EOK; +} + +static int ra6w1_qspi_psram_memheap_auto_init(void) +{ + return (int)ra6w1_qspi_psram_memheap_init(); +} +INIT_COMPONENT_EXPORT(ra6w1_qspi_psram_memheap_auto_init); + +struct rt_memheap *ra6w1_qspi_psram_memheap(void) +{ + if (RT_EOK != ra6w1_qspi_psram_memheap_init()) return RT_NULL; + + return &s_qspi_psram_memheap; +} +#endif + +#endif /* BSP_USING_QSPI_PSRAM */ diff --git a/bsp/renesas/ra6w1-ek/ra/SConscript b/bsp/renesas/ra6w1-ek/ra/SConscript index 8daa4a4e3835..2725c2fb27d5 100644 --- a/bsp/renesas/ra6w1-ek/ra/SConscript +++ b/bsp/renesas/ra6w1-ek/ra/SConscript @@ -26,6 +26,7 @@ src += Glob("./fsp/src/bsp_w/mcu/ra6w1/*.c") src += Glob("./fsp/src/r_gpio_w/*.c") src += Glob("./fsp/src/r_uart_w/*.c") src += Glob("./fsp/src/r_ext_irq_w/*.c") +src += Glob("./fsp/src/r_dmac_w/*.c") if GetDepend(["BSP_USING_ONCHIP_RTC"]): src += Glob("./fsp/src/r_rtc_w/*.c") @@ -36,7 +37,7 @@ if GetDepend(["BSP_USING_SPI"]): if GetDepend(["BSP_USING_ADC"]): src += Glob("./fsp/src/r_adc_w/*.c") -if GetDepend(["BSP_USING_TIM"]): +if GetDepend(["BSP_USING_TIM_W"]): src += Glob("./fsp/src/r_tim_w/*.c") if GetDepend(["BSP_USING_WDT"]): diff --git a/bsp/renesas/ra6w1-ek/ra/fsp/inc/api/r_sdmmc_api.h b/bsp/renesas/ra6w1-ek/ra/fsp/inc/api/r_sdmmc_api.h new file mode 100644 index 000000000000..078920f36878 --- /dev/null +++ b/bsp/renesas/ra6w1-ek/ra/fsp/inc/api/r_sdmmc_api.h @@ -0,0 +1,496 @@ +/* +* Copyright (c) 2020 - 2025 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef R_SDMMC_API_H +#define R_SDMMC_API_H + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ + +/* Register definitions, common services and error codes. */ +#include "bsp_api.h" +#include "r_transfer_api.h" + +/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ +FSP_HEADER + +/*******************************************************************************************************************//** + * @ingroup RENESAS_STORAGE_INTERFACES + * @defgroup SDMMC_API SD/MMC Interface + * @brief Interface for accessing SD, eMMC, and SDIO devices. + * + * @section SDMMC_API_SUMMARY Summary + * The r_sdhi interface provides standard SD and eMMC media functionality. This interface also supports SDIO. + * + * + * @{ + **********************************************************************************************************************/ + +/********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ + +/********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ + +/** SD/MMC media uses SD protocol or MMC protocol. */ +typedef enum e_sdmmc_card_type +{ + SDMMC_CARD_TYPE_MMC = 0, ///< The media is an eMMC device. + SDMMC_CARD_TYPE_SD = 1, ///< The media is an SD card. + SDMMC_CARD_TYPE_SDIO = 2, ///< The media is an SDIO card. +} sdmmc_card_type_t; + +/** SD/MMC data bus is 1, 4 or 8 bits wide. */ +typedef enum e_sdmmc_bus_width +{ + SDMMC_BUS_WIDTH_1_BIT = 1, ///< Data bus is 1 bit wide. + SDMMC_BUS_WIDTH_4_BITS = 4, ///< Data bus is 4 bits wide. + SDMMC_BUS_WIDTH_8_BITS = 8, ///< Data bus is 8 bits wide. +} sdmmc_bus_width_t; + +/** SDIO transfer mode, configurable in SDIO read/write extended commands. */ +typedef enum e_sdmmc_io_transfer_mode +{ + SDMMC_IO_MODE_TRANSFER_BYTE = 0, ///< SDIO byte transfer mode + SDMMC_IO_MODE_TRANSFER_BLOCK ///< SDIO block transfer mode +} sdmmc_io_transfer_mode_t; + +/** SDIO address mode, configurable in SDIO read/write extended commands. */ +typedef enum e_sdmmc_io_address_mode +{ + SDMMC_IO_ADDRESS_MODE_FIXED = 0, ///< Write all data to the same address + SDMMC_IO_ADDRESS_MODE_INCREMENT ///< Increment destination address after each write +} sdmmc_io_address_mode_t; + +/** Controls the RAW (read after write) flag of CMD52. Used to read back the status after writing a control register. */ +typedef enum e_sdmmc_io_write_mode +{ + SDMMC_IO_WRITE_MODE_NO_READ = 0, ///< Write only (do not read back) + SDMMC_IO_WRITE_READ_AFTER_WRITE ///< Read back the register after write +} sdmmc_io_write_mode_t; + +/** Events that can trigger a callback function */ +typedef enum e_sdmmc_event +{ + SDMMC_EVENT_CARD_REMOVED = 1U << 0, ///< Card removed event. + SDMMC_EVENT_CARD_INSERTED = 1U << 1, ///< Card inserted event. + SDMMC_EVENT_RESPONSE = 1U << 3, ///< Response event. + SDMMC_EVENT_SDIO = 1U << 4, ///< IO event. + SDMMC_EVENT_TRANSFER_COMPLETE = 1U << 5, ///< Read or write complete. + SDMMC_EVENT_TRANSFER_ERROR = 1U << 6, ///< Read or write failed. + SDMMC_EVENT_ERASE_COMPLETE = 1U << 7, ///< Erase completed. + SDMMC_EVENT_ERASE_BUSY = 1U << 8, ///< Erase timeout, poll @ref sdmmc_api_t::statusGet. +} sdmmc_event_t; + +/** Card detection configuration options. */ +/* Card detection using DAT3 is not supported. */ +typedef enum e_sdmmc_card_detect +{ + SDMMC_CARD_DETECT_NONE, ///< Card detection unused. + SDMMC_CARD_DETECT_CD, ///< Card detection using the CD pin +} sdmmc_card_detect_t; + +/** Write protection configuration options. */ +typedef enum e_sdmmc_write_protect +{ + SDMMC_WRITE_PROTECT_NONE, ///< Write protection unused. + SDMMC_WRITE_PROTECT_WP, ///< Write protection using WP pin +} sdmmc_write_protect_t; + +/** Card state when receiving the prior command. */ +typedef enum e_sdmmc_r1_state +{ + SDMMC_R1_STATE_IDLE = 0, ///< Idle State + SDMMC_R1_STATE_READY = 0, ///< Ready State + SDMMC_R1_STATE_IDENT = 0, ///< Identification State + SDMMC_R1_STATE_STBY = 0, ///< Stand-by State + SDMMC_R1_STATE_TRAN = 0, ///< Transfer State + SDMMC_R1_STATE_DATA = 0, ///< Sending-data State + SDMMC_R1_STATE_RCV = 0, ///< Receive-data State + SDMMC_R1_STATE_PRG = 0, ///< Programming State + SDMMC_R1_STATE_DIS = 0, ///< Disconnect State (between programming and stand-by) + SDMMC_R1_STATE_IO = 15, ///< This is an I/O card and memory states do not apply +} sdmmc_r1_state_t; + +/* Structure for decoding the response of a command. For advanced use only. */ +typedef union u_sdmmc_response +{ + uint32_t status; + + /** SDIO Card Status Register. */ + struct + { + uint32_t : 3; + uint32_t ake_seq_error : 1; // Error in the sequence of the authentication process + uint32_t : 1; + uint32_t app_cmd : 1; // The card will expect ACMD, or an indication that the command has been interpreted as ACMD + uint32_t fx_event : 1; // Extension Functions may set this bit to get host to deal with events + uint32_t switch_error : 1; // + uint32_t ready_for_data : 1; // Corresponds to the buffer empty signaling on the bus + + /* The state of the card when receiving the command. If the command execution causes a state change, it will be + * visible to the host in the response to the next command. */ + sdmmc_r1_state_t current_state : 4; + uint32_t erase_reset : 1; // An erase sequence was cleared before executing because an out of erase sequence command was received. + uint32_t card_ecc_disabled : 1; // The command has been executed without using the internal ECC. + uint32_t wp_erase_skip : 1; // Set when only partial address space was erased due to existing write protected blocks or the temporary or permanent write protected card was erased. + uint32_t csd_overwrite : 1; // The read only section of the CSD does not match the card content or an attempt to reverse the copy or permanent WP bits was made. + uint32_t : 2; + uint32_t error : 1; // A general or unknown error occurred during the operation. + uint32_t cc_error : 1; // Internal card controller error. + uint32_t card_ecc_failed : 1; // Card internal ECC was applied but failed to correct the data. + uint32_t illegal_command : 1; // Command not legal for the card state. + uint32_t com_crc_error : 1; // The CRC check of the previous command failed. + uint32_t lock_unlock_failed : 1; // Set when a sequence or password error has been detected in the lock/unlock command. + uint32_t device_is_locked : 1; // When set, signals that the card is locked by the host. + uint32_t wp_violation : 1; // Set when the host attempts to write to a protected block or to the temporary or permanent write protected card. + uint32_t erase_param : 1; // An invalid selection of write-blocks for erase occurred. + uint32_t erase_seq_error : 1; // An error in the sequence of erase commands occurred. + uint32_t block_len_error : 1; // The transferred block length is not allowed for this card, or the number of transferred bytes does not match the block length. + uint32_t address_error : 1; // A misaligned address which did not match the block length was used in the command. + uint32_t out_of_range : 1; // The command's argument was out of the allowed range for this card. + } status_b; + + struct + { + uint32_t reserved_0 : 7; + + uint32_t reserved_lvr : 1; + uint32_t reserved_8 : 7; + uint32_t v_27_28 : 1; + uint32_t v_28_29 : 1; + uint32_t v_29_30 : 1; + uint32_t v_30_31 : 1; + uint32_t v_31_32 : 1; + uint32_t v_32_33 : 1; + uint32_t v_33_34 : 1; + uint32_t v_34_35 : 1; + uint32_t v_35_36 : 1; + uint32_t s18A : 1; + uint32_t reserved_25 : 5; + uint32_t card_capacity_status : 1; + uint32_t power_up_status : 1; + } r3; + + struct + { + uint32_t ocr : 24; + + uint32_t reserved_24 : 3; + uint32_t memory : 1; + uint32_t io_functions : 3; + uint32_t ready : 1; + } r4; + + struct + { + uint32_t read_write_data : 8; + + uint32_t out_of_range : 1; + uint32_t invalid_function : 1; + uint32_t rfu : 1; + uint32_t error : 1; + uint32_t current_state : 2; + uint32_t illegal_command : 1; + uint32_t crc_error : 1; + uint32_t reserved_16 : 16; + } r5; + + struct + { + uint32_t reserved_0 : 3; + + uint32_t ake_seq_error : 1; + uint32_t reserved_4 : 1; + uint32_t app_cmd : 1; + uint32_t reserved_6 : 2; + uint32_t ready_for_data : 1; + sdmmc_r1_state_t current_state : 4; + uint32_t error : 1; + uint32_t illegal_command : 1; + uint32_t com_crc_error : 1; + uint32_t rca : 16; + } r6; + + struct + { + uint32_t check_pattern : 8; + + uint32_t voltage_accepted : 4; + uint32_t reserved_11 : 20; + } r7; +} sdmmc_response_t; + +/** Current status. */ +typedef struct s_sdmmc_status +{ + /** False if card was removed (only applies if MCU supports card detection and SDnCD pin is connected), true otherwise. + * + * If ready is false, call @ref sdmmc_api_t::mediaInit to reinitialize it + */ + bool initialized; + bool transfer_in_progress; ///< true = Card is busy + bool card_inserted; ///< Card detect status, true if card detect is not used +} sdmmc_status_t; + +/** Information obtained from the media device. */ +typedef struct s_sdmmc_device +{ + sdmmc_card_type_t card_type; ///< SD, eMMC, or SDIO + bool write_protected; ///< true = Card is write protected + uint32_t clock_rate; ///< Current clock rate + uint32_t sector_count; ///< Sector count + uint32_t sector_size_bytes; ///< Sector size + uint32_t erase_sector_count; ///< Minimum erasable unit (in 512 byte sectors) +} sdmmc_device_t; + +/** Callback function parameter data */ +typedef struct st_sdmmc_callback_args +{ + sdmmc_event_t event; ///< The event can be used to identify what caused the callback. + sdmmc_response_t response; ///< Response from card, only valid if SDMMC_EVENT_RESPONSE is set in event. + void * p_context; ///< Placeholder for user data. +} sdmmc_callback_args_t; + +/** Non-secure arguments for writeIo guard function */ +typedef struct st_sdmmc_write_io_args_t +{ + uint8_t * const p_data; + uint32_t function; + uint32_t address; + sdmmc_io_write_mode_t read_after_write; +} sdmmc_write_io_args_t; + +/** Non-secure arguments for readIoExt guard function */ +typedef struct st_sdmmc_read_io_ext_args_t +{ + uint8_t * const p_dest; + uint32_t function; + uint32_t address; + uint32_t * const count; + sdmmc_io_transfer_mode_t transfer_mode; + sdmmc_io_address_mode_t address_mode; +} sdmmc_read_io_ext_args_t; + +/** Non-secure arguments for writeIoExt guard function */ +typedef struct st_sdmmc_write_io_ext_args_t +{ + uint8_t const * const p_source; + uint32_t function; + uint32_t address; + uint32_t count; + sdmmc_io_transfer_mode_t transfer_mode; + sdmmc_io_address_mode_t address_mode; +} sdmmc_write_io_ext_args_t; + +/** SD/MMC Configuration */ +typedef struct st_sdmmc_cfg +{ + /* SD/MMC generic configuration */ + uint8_t channel; ///< Channel of SD/MMC host interface. + sdmmc_bus_width_t bus_width; ///< Device bus width is 1, 4 or 8 bits wide. + transfer_instance_t const * p_lower_lvl_transfer; ///< Transfer instance used to move data with DMA or DTC + + /* Configuration for SD/MMC Event processing */ + void (* p_callback)(sdmmc_callback_args_t * p_args); ///< Pointer to callback function + void * p_context; ///< User defined context passed into callback function + + /* Pointer to SD/MMC peripheral specific configuration */ + void const * p_extend; ///< SD/MMC hardware dependent configuration + + /** Block size in bytes. Block size must be 512 bytes for SD cards and eMMC devices. Block size can be 1-512 + * bytes for SDIO. */ + uint32_t block_size; + + /** Whether or not card detection is used. */ + sdmmc_card_detect_t card_detect; + + /** Select whether or not to use the write protect pin. Select Not Used if the MCU or device does not have a write protect pin. */ + sdmmc_write_protect_t write_protect; + IRQn_Type access_irq; ///< Access IRQ number + IRQn_Type sdio_irq; ///< SDIO IRQ number + IRQn_Type card_irq; ///< Card IRQ number + IRQn_Type dma_req_irq; ///< DMA request IRQ number + uint8_t access_ipl; ///< Access interrupt priority + uint8_t sdio_ipl; ///< SDIO interrupt priority + uint8_t card_ipl; ///< Card interrupt priority + uint8_t dma_req_ipl; ///< DMA request interrupt priority +} sdmmc_cfg_t; + +/** SD/MMC control block. Allocate an instance specific control block to pass into the SD/MMC API calls. + */ +typedef void sdmmc_ctrl_t; + +/** SD/MMC functions implemented at the HAL layer API. */ +typedef struct st_sdmmc_api +{ + /** Open the SD/MMC driver. + * + * + * @param[in] p_ctrl Pointer to SD/MMC instance control block. + * @param[in] p_cfg Pointer to SD/MMC instance configuration structure. + */ + fsp_err_t (* open)(sdmmc_ctrl_t * const p_ctrl, sdmmc_cfg_t const * const p_cfg); + + /** Initializes an SD/MMC device. If the device is a card, the card must be plugged in prior to calling this API. + * This API blocks until the device initialization procedure is complete. + * + * + * @param[in] p_ctrl Pointer to SD/MMC instance control block. + * @param[out] p_device Pointer to store device information. + */ + fsp_err_t (* mediaInit)(sdmmc_ctrl_t * const p_ctrl, sdmmc_device_t * const p_device); + + /** Read data from an SD/MMC channel. + * This API is not supported for SDIO devices. + * + * + * @param[in] p_ctrl Pointer to an open SD/MMC instance control block. + * @param[out] p_dest Pointer to data buffer to read data to. + * @param[in] start_sector First sector address to read. + * @param[in] sector_count Number of sectors to read. All sectors must be in the range of + * sdmmc_device_t::sector_count. + */ + fsp_err_t (* read)(sdmmc_ctrl_t * const p_ctrl, uint8_t * const p_dest, uint32_t const start_sector, + uint32_t const sector_count); + + /** Write data to SD/MMC channel. + * This API is not supported for SDIO devices. + * + * + * @param[in] p_ctrl Pointer to an open SD/MMC instance control block. + * @param[in] p_source Pointer to data buffer to write data from. + * @param[in] start_sector First sector address to write to. + * @param[in] sector_count Number of sectors to write. All sectors must be in the range of + * sdmmc_device_t::sector_count. + */ + fsp_err_t (* write)(sdmmc_ctrl_t * const p_ctrl, uint8_t const * const p_source, uint32_t const start_sector, + uint32_t const sector_count); + + /** Read one byte of I/O data from an SDIO device. + * This API is not supported for SD or eMMC memory devices. + * + * + * @param[in] p_ctrl Pointer to an open SD/MMC instance control block. + * @param[out] p_data Pointer to location to store data byte. + * @param[in] function SDIO Function Number. + * @param[in] address SDIO register address. + */ + fsp_err_t (* readIo)(sdmmc_ctrl_t * const p_ctrl, uint8_t * const p_data, uint32_t const function, + uint32_t const address); + + /** Write one byte of I/O data to an SDIO device. + * This API is not supported for SD or eMMC memory devices. + * + * + * @param[in] p_ctrl Pointer to an open SD/MMC instance control block. + * @param[in,out] p_data Pointer to data byte to write. Read data is also provided here if + * read_after_write is true. + * @param[in] function SDIO Function Number. + * @param[in] address SDIO register address. + * @param[in] read_after_write Whether or not to read back the same register after writing + */ + fsp_err_t (* writeIo)(sdmmc_ctrl_t * const p_ctrl, uint8_t * const p_data, uint32_t const function, + uint32_t const address, sdmmc_io_write_mode_t const read_after_write); + + /** Read multiple bytes or blocks of I/O data from an SDIO device. + * This API is not supported for SD or eMMC memory devices. + * + * + * @param[in] p_ctrl Pointer to an open SD/MMC instance control block. + * @param[out] p_dest Pointer to data buffer to read data to. + * @param[in] function SDIO Function Number. + * @param[in] address SDIO register address. + * @param[in] count Number of bytes or blocks to read, maximum 512 bytes or 511 blocks. + * @param[in] transfer_mode Byte or block mode + * @param[in] address_mode Fixed or incrementing address mode + */ + fsp_err_t (* readIoExt)(sdmmc_ctrl_t * const p_ctrl, uint8_t * const p_dest, uint32_t const function, + uint32_t const address, uint32_t * const count, sdmmc_io_transfer_mode_t transfer_mode, + sdmmc_io_address_mode_t address_mode); + + /** Write multiple bytes or blocks of I/O data to an SDIO device. + * This API is not supported for SD or eMMC memory devices. + * + * + * @param[in] p_ctrl Pointer to an open SD/MMC instance control block. + * @param[in] p_source Pointer to data buffer to write data from. + * @param[in] function_number SDIO Function Number. + * @param[in] address SDIO register address. + * @param[in] count Number of bytes or blocks to write, maximum 512 bytes or 511 blocks. + * @param[in] transfer_mode Byte or block mode + * @param[in] address_mode Fixed or incrementing address mode + */ + fsp_err_t (* writeIoExt)(sdmmc_ctrl_t * const p_ctrl, uint8_t const * const p_source, uint32_t const function, + uint32_t const address, uint32_t const count, sdmmc_io_transfer_mode_t transfer_mode, + sdmmc_io_address_mode_t address_mode); + + /** Enables SDIO interrupt for SD/MMC instance. + * This API is not supported for SD or eMMC memory devices. + * + * + * @param[in] p_ctrl Pointer to an open SD/MMC instance control block. + * @param[in] enable Interrupt enable = true, interrupt disable = false. + */ + fsp_err_t (* ioIntEnable)(sdmmc_ctrl_t * const p_ctrl, bool enable); + + /** Get SD/MMC device status. + * + * + * @param[in] p_ctrl Pointer to an open SD/MMC instance control block. + * @param[out] p_status Pointer to current driver status. + */ + fsp_err_t (* statusGet)(sdmmc_ctrl_t * const p_ctrl, sdmmc_status_t * const p_status); + + /** Erase SD/MMC sectors. The sector size for erase is fixed at 512 bytes. + * This API is not supported for SDIO devices. + * + * + * @param[in] p_ctrl Pointer to an open SD/MMC instance control block. + * @param[in] start_sector First sector to erase. Must be a multiple of sdmmc_device_t::erase_sector_count. + * @param[in] sector_count Number of sectors to erase. Must be a multiple of sdmmc_device_t::erase_sector_count. + * All sectors must be in the range of sdmmc_device_t::sector_count. + */ + fsp_err_t (* erase)(sdmmc_ctrl_t * const p_ctrl, uint32_t const start_sector, uint32_t const sector_count); + + /** Specify callback function and optional context pointer and working memory pointer. + * + * @param[in] p_ctrl Control block set in @ref sdmmc_api_t::open call. + * @param[in] p_callback Callback function to register + * @param[in] p_context Pointer to send to callback function + * @param[in] p_working_memory Pointer to volatile memory where callback structure can be allocated. + * Callback arguments allocated here are only valid during the callback. + */ + fsp_err_t (* callbackSet)(sdmmc_ctrl_t * const p_ctrl, void (* p_callback)(sdmmc_callback_args_t *), + void * const p_context, sdmmc_callback_args_t * const p_callback_memory); + + /** Close open SD/MMC device. + * + * + * @param[in] p_ctrl Pointer to an open SD/MMC instance control block. + */ + fsp_err_t (* close)(sdmmc_ctrl_t * const p_ctrl); +} sdmmc_api_t; + +/** This structure encompasses everything that is needed to use an instance of this interface. */ +typedef struct st_sdmmc_instance +{ + sdmmc_ctrl_t * p_ctrl; ///< Pointer to the control structure for this instance + sdmmc_cfg_t const * p_cfg; ///< Pointer to the configuration structure for this instance + sdmmc_api_t const * p_api; ///< Pointer to the API structure for this instance +} sdmmc_instance_t; + +/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ +FSP_FOOTER + +#endif + +/*******************************************************************************************************************//** + * @} (end defgroup SDMMC_API) + **********************************************************************************************************************/ diff --git a/bsp/renesas/ra6w1-ek/ra/fsp/inc/instances/r_dmac_w.h b/bsp/renesas/ra6w1-ek/ra/fsp/inc/instances/r_dmac_w.h new file mode 100644 index 000000000000..763dad25d97a --- /dev/null +++ b/bsp/renesas/ra6w1-ek/ra/fsp/inc/instances/r_dmac_w.h @@ -0,0 +1,168 @@ +/* +* Copyright (c) 2020 - 2026 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +/*******************************************************************************************************************//** + * @addtogroup DMAC_W + * @{ + **********************************************************************************************************************/ + +#ifndef R_DMAC_W_H +#define R_DMAC_W_H + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ +#include "bsp_api.h" +#include "r_transfer_api.h" + +/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ +FSP_HEADER + +/*********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ + +/** Max configurable number of transfers in TRANSFER_MODE_NORMAL. */ +#define DMAC_MAX_NORMAL_TRANSFER_LENGTH (0xFFFF) + +/*********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ + +/** Callback function parameter data. */ +typedef transfer_callback_args_t dmac_callback_args_t; + +/* Control block used by driver. DO NOT INITIALIZE - this structure will be initialized in @ref transfer_api_t::open. */ +typedef struct st_dmac_instance_ctrl +{ + uint32_t open; // Driver ID + + transfer_cfg_t const * p_cfg; + + /* Pointer to base register. */ + DMA_Type * p_reg; + + void (* p_callback)(dmac_callback_args_t *); // Pointer to callback. + dmac_callback_args_t * p_callback_memory; // Pointer to optional callback argument memory. + void * p_context; // Pointer to context to be passed into callback function. +} dmac_instance_ctrl_t; + +/** DMAC channel start mode */ +typedef enum e_dmac_start_mode +{ + /** DMAC channel starts immediately. */ + DMAC_START_IMMEDIATELY = 0, + + /** DMAC channel must be triggered by a peripheral DMA request. */ + DMAC_START_ON_PERIPHERAL_REQUEST = 1, +} dmac_start_mode_t; + +/** DMAC channel burst mode */ +typedef enum e_dmac_burst_mode +{ + /** DMAC burst mode is disabled */ + DMAC_BURST_MODE_DISABLED = 0, + + /** DMAC burst mode enabled, burst size of 4 data units is used */ + DMAC_BURST_MODE_4x = 1, + + /** DMAC burst mode enabled, burst size of 8 data units is used */ + DMAC_BURST_MODE_8x = 2, +} dmac_burst_mode_t; + +/** DMA idle mode + * + * In blocking mode the DMA performs a fast back-to-back + * copy, disabling bus access for any bus master with lower priority. + * In interrupting mode the DMAC inserts a wait cycle after each + * store allowing other bus masters to perform a + * burst read. */ +typedef enum e_dmac_idle_mode +{ + /** Blocking mode. */ + DMAC_IDLE_BLOCKING_MODE = 0, + + /** Interrupting mode. */ + DMAC_IDLE_INTERRUPTING_MODE = 1, +} dmac_idle_mode_t; + +typedef enum e_dmac_init_mode +{ + /** DMA performs copy A1 to B1, A2 to B2 */ + DMAC_INIT_AX_BX_AY_BY = 0, + + /** DMA performs copy A1 to B1, B2 */ + DMAC_INIT_AX_BX_BY = 1, +} dmac_init_mode_t; + +/** DMAC transfer configuration extension. This extension is required. */ +typedef struct st_dmac_extended_cfg +{ + uint8_t channel; ///< Channel number, does not apply to all HAL drivers. + IRQn_Type irq; ///< DMAC interrupt number + uint8_t ipl; ///< DMAC interrupt priority + + dmac_start_mode_t start_mode; ///< Start DMA immediately or have it triggered by peripheral. + dmac_idle_mode_t idle_mode; ///< Idle mode: blocking or interrupting. + dmac_init_mode_t init_mode; ///< Copy mode: block copy or mem init. + dmac_burst_mode_t burst_mode; ///< Enable/Disable burst mode. + uint8_t channel_prio; ///< DMAC channel priority. + bsp_dmac_trig_t periph_trigger; ///< Trigger source, if DMAC starts on a peripheral request. + + /** Number of transfers before IRQ generation. Set to 0 to fire IRQ after transfer ends. */ + uint16_t irq_num_of_trans; + + /** Callback for transfer end interrupt. */ + void (* p_callback)(dmac_callback_args_t * cb_data); + dmac_callback_args_t * p_callback_memory; + + /** Placeholder for user data. Passed to the user p_callback in ::dmac_callback_args_t. */ + void * p_context; +} dmac_extended_cfg_t; + +/********************************************************************************************************************** + * Exported global variables + **********************************************************************************************************************/ + +/** @cond INC_HEADER_DEFS_SEC */ +/** Filled in Interface API structure for this Instance. */ +extern const transfer_api_t g_transfer_on_dmac_w; + +/** @endcond */ + +/*********************************************************************************************************************** + * Public Function Prototypes + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_Open(transfer_ctrl_t * const p_api_ctrl, transfer_cfg_t const * const p_cfg); +fsp_err_t R_DMAC_W_Reconfigure(transfer_ctrl_t * const p_api_ctrl, transfer_info_t * p_info); +fsp_err_t R_DMAC_W_Reset(transfer_ctrl_t * const p_api_ctrl, + void const * volatile p_src, + void * volatile p_dest, + uint16_t const num_transfers); +fsp_err_t R_DMAC_W_SoftwareStart(transfer_ctrl_t * const p_api_ctrl, transfer_start_mode_t mode); +fsp_err_t R_DMAC_W_SoftwareStop(transfer_ctrl_t * const p_api_ctrl); +fsp_err_t R_DMAC_W_Enable(transfer_ctrl_t * const p_api_ctrl); +fsp_err_t R_DMAC_W_Disable(transfer_ctrl_t * const p_api_ctrl); +fsp_err_t R_DMAC_W_InfoGet(transfer_ctrl_t * const p_api_ctrl, transfer_properties_t * const p_info); +fsp_err_t R_DMAC_W_Reload(transfer_ctrl_t * const p_api_ctrl, + void const * p_src, + void * p_dest, + uint32_t const num_transfers); +fsp_err_t R_DMAC_W_CallbackSet(transfer_ctrl_t * const p_api_ctrl, + void ( * p_callback)(dmac_callback_args_t *), + void * const p_context, + dmac_callback_args_t * const p_callback_memory); +fsp_err_t R_DMAC_W_Close(transfer_ctrl_t * const p_api_ctrl); +fsp_err_t R_DMAC_W_Freeze(bool freeze); + +/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ +FSP_FOOTER + +#endif + +/*******************************************************************************************************************//** + * @} (end defgroup DMAC_W) + **********************************************************************************************************************/ diff --git a/bsp/renesas/ra6w1-ek/ra/fsp/inc/instances/r_ospi_w.h b/bsp/renesas/ra6w1-ek/ra/fsp/inc/instances/r_ospi_w.h index 5116043795f8..ed101140ffd7 100644 --- a/bsp/renesas/ra6w1-ek/ra/fsp/inc/instances/r_ospi_w.h +++ b/bsp/renesas/ra6w1-ek/ra/fsp/inc/instances/r_ospi_w.h @@ -19,7 +19,7 @@ #include "r_ospi_w_cfg.h" #include "r_spi_flash_api.h" -#include "../../src/bsp/mcu/ra6w1/sdk_defs.h" +#include "../../src/bsp_w/mcu/ra6w1/sdk_defs.h" #if OSPI_W_CFG_DMAC_SUPPORT_ENABLE #include "r_transfer_api.h" #endif diff --git a/bsp/renesas/ra6w1-ek/ra/fsp/inc/instances/r_sdemmc_w.h b/bsp/renesas/ra6w1-ek/ra/fsp/inc/instances/r_sdemmc_w.h new file mode 100644 index 000000000000..9574857e2b15 --- /dev/null +++ b/bsp/renesas/ra6w1-ek/ra/fsp/inc/instances/r_sdemmc_w.h @@ -0,0 +1,235 @@ +/* +* Copyright (c) 2020 - 2026 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef R_SDEMMC_W_H +#define R_SDEMMC_W_H + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ +#include "bsp_api.h" +#include "r_sdemmc_w_cfg.h" +#include "r_sdmmc_api.h" + +/* Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ +FSP_HEADER + +/*******************************************************************************************************************//** + * @addtogroup SDEMMC_W + * @{ + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ + +#define SDEMMC_W_MAX_BLOCK_SIZE (512U) + +#define SDEMMC_W_CLK_DIV_40M (0U) +#define SDEMMC_W_CLK_DIV_20M (1U) +#define SDEMMC_W_CLK_DIV_10M (2U) +#define SDEMMC_W_CLK_DIV_5M (4U) + +#define SDEMMC_W_HOST_PORT_0 (0U) +#define SDEMMC_W_HOST_PORT_1 (1U) + +#define SDEMMC_W_HOST_RXCLK_IN_0 (0U) +#define SDEMMC_W_HOST_RXCLK_IN_1 (1U) + +#define SDEMMC_W_DEVICE_PORT_0 (0U) +#define SDEMMC_W_DEVICE_PORT_1 (1U) + +/*********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ + +/** Private enumeration used in sdemmc_w_instance_ctrl_t. */ +typedef enum e_sdemmc_w_transfer_dir +{ + SDEMMC_W_TRANSFER_DIR_NONE, ///< The transfer direction is none + SDEMMC_W_TRANSFER_DIR_READ, ///< The transfer direction is read + SDEMMC_W_TRANSFER_DIR_WRITE ///< The transfer direction is write +} sdemmc_w_transfer_dir_t; + +/** Private structure used in sdemmc_w_instance_ctrl_t. */ +typedef union +{ + uint32_t word; + + struct s_sdemmc_w_event_type + { + uint32_t response_end : 1; ///< response end detected + uint32_t access_end : 1; ///< access end detected + uint32_t reserved_1 : 4; + uint32_t card_inserted : 1; ///< card insertion detected by cd pin + uint32_t card_removed : 1; ///< card removal detected by cd pin + uint32_t CardInterrupt : 1; ///< [8..8] CardInterrupt + uint32_t reserved_5 : 6; + uint32_t ErrorInterrupt : 1; ///< [15..15] ErrorInterrupt + uint32_t CommandTimeoutError: 1; ///< [16..16] CommandTimeoutError + uint32_t crc_err : 1; ///< crc error + uint32_t end_err : 1; ///< end bit error + uint32_t cmd_err : 1; ///< command error + uint32_t dto : 1; ///< data timeout + uint32_t DataCRCError : 1; ///< [21..21] DataCRCError + uint32_t DataEndBitError : 1; ///< [22..22] DataEndBitError + uint32_t CurrentLimitError : 1; ///< [23..23] CurrentLimitError + uint32_t AutoCMDError : 1; ///< [24..24] AutoCMDError + uint32_t ADMAError : 1; ///< [25..25] ADMAError + uint32_t TuningError : 1; ///< [26..26] TuningError + uint32_t VendorSpecificError: 5; ///< VendorSpecificError + } bit; +} sdemmc_w_event_t; + +/** Private enumeration used in sdmmc_callback_args_t. */ +typedef enum e_sdemmc_w_priv_event +{ + SDEMMC_W_PRIV_EVENT_CARD_REMOVED = 1U << 0, ///< Card removed event. + SDEMMC_W_PRIV_EVENT_CARD_INSERTED = 1U << 1, ///< Card inserted event. + SDEMMC_W_PRIV_EVENT_RESPONSE = 1U << 3, ///< Response event. + SDEMMC_W_PRIV_EVENT_SDIO = 1U << 4, ///< IO event. + SDEMMC_W_PRIV_EVENT_TRANSFER_COMPLETE = 1U << 5, ///< Read or write complete. + SDEMMC_W_PRIV_EVENT_TRANSFER_ERROR = 1U << 6, ///< Read or write failed. + SDEMMC_W_PRIV_EVENT_ERASE_COMPLETE = 1U << 7, ///< Erase completed. + SDEMMC_W_PRIV_EVENT_ERASE_BUSY = 1U << 8, ///< Erase timeout, poll @ref sdmmc_api_t::statusGet. + SDEMMC_W_PRIV_EVENT_SDIO_FN1_WR_OVR = 1U << 9, ///< IO event. + SDEMMC_W_PRIV_EVENT_SDIO_FN1_RD_OVR = 1U << 10, ///< IO event. + SDEMMC_W_PRIV_EVENT_SDIO_FN1_MSG_RDY = 1U << 11, ///< IO event. + SDEMMC_W_PRIV_EVENT_SDIO_FN1_ACK_TO_ARM = 1U << 12, ///< IO event. +} sdemmc_w_priv_event_t; + +/** SDIO pads drive current */ +typedef enum e_sdemmc_w_sdio_device_drive_current +{ + SDEMMC_W_SDIO_DEVICE_DRIVE_CURRENT_2 = 0, ///< 2 mA @3.3V + SDEMMC_W_SDIO_DEVICE_DRIVE_CURRENT_4 = 1, ///< 4 mA @3.3V + SDEMMC_W_SDIO_DEVICE_DRIVE_CURRENT_8 = 2, ///< 8 mA @3.3V + SDEMMC_W_SDIO_DEVICE_DRIVE_CURRENT_14 = 3, ///< 14 mA @3.3V +} sdemmc_w_sdio_device_drive_current_t; + +/** SDIO DMA configuration */ +typedef struct +{ + uint32_t sdio_dma_length; ///< DMA length + uint32_t sdio_dma_buf_address; ///< DMA buffer address +} sdio_device_dma_config; + +/** SDIO role used in sdmmc_cfg_t p_extend. */ +typedef enum e_sdemmc_w_role +{ + SDEMMC_W_ROLE_HOST, ///< Act as SD/eMMC/SDIO host + SDEMMC_W_ROLE_DEVICE, ///< Act as SDIO device +} sdemmc_w_role_t; + +/** Extended SDMMC interface configuration */ +typedef struct st_sdemmc_w_extended_cfg +{ + sdio_device_dma_config dma_config_tx; ///< ADMA Region physical memory + sdio_device_dma_config dma_config_rx; ///< ADMA Region physical memory + uint32_t sdemmc_w_role; ///< SD/eMMC/SDIO host or SDIO device + uint8_t clk_div; ///< Clock divider value + uint8_t host_port_sel; ///< SD/eMMC/SDIO host port selection. 0: P0_[13:4], 1: P1_[3:0] and P1_[15:10] + uint8_t host_rxclk_in_sel; ///< SD/eMMC/SDIO host rxclk_in selection. 0: clkout signal, 1: clkout_inv signal + uint8_t host_pull_en_cfg; ///< SD/eMMC/SDIO host PADs mode pull enable. + uint8_t host_pull_sel_cfg; ///< SD/eMMC/SDIO host PADs mode pull selection. + uint8_t device_port_sel; ///< SDIO device port selection. 0: Port P0_[13:8], 1: Port P1_[15:10] + uint8_t device_pull_en_cfg; ///< SDIO device PADs mode pull enable + uint8_t device_pull_sel_cfg; ///< SDIO device PADs mode pull selection + sdemmc_w_sdio_device_drive_current_t drive_current; ///< Drive current +} sdemmc_w_extended_cfg_t; + +/** SDMMC extended callback arguments structure */ +typedef struct st_sdemmc_w_transfer_result +{ + uint32_t sdio_blk_or_byte; ///< This bit indicates current transaction is Block(1)/Byte(0) + uint32_t sdio_blk_size; ///< The block size programmed by the SD host + uint32_t sdio_blk_count; ///< The block count transferred from/to the SD host +} sdemmc_w_transfer_result_t; + +/** SDMMC instance control block. This is private to the FSP and should not be used or modified by the application. */ +typedef struct st_sdemmc_w_instance_ctrl +{ + uint32_t open; ///< Indicates whether the open() API has been successfully called. + sdmmc_cfg_t const * p_cfg; ///< Pointer to instance configuration + sdmmc_device_t device; ///< Information of the media device used + bool sector_addressing; ///< Whether or not use sector addressing in transfer + bool transfer_in_progress; ///< Whether or not transfer is in progress + bool initialized; ///< Whether or not driver is initialized + SDIO_Type * p_reg; ///< Base SDIO register for this channel + SDEMMC_Type * p_reg_mmc; ///< Base SD/eMMC register for this channel + volatile sdemmc_w_event_t sdemmc_w_event; ///< Events of SDEMMC_W + sdemmc_w_transfer_result_t result; ///< Extended callback arguments + + void (* p_callback)(sdmmc_callback_args_t *); ///< Pointer to callback + sdmmc_callback_args_t * p_callback_memory; ///< Pointer to optional callback argument memory + void * p_context; ///< Pointer to context to be passed into callback function +} sdemmc_w_instance_ctrl_t; + +/********************************************************************************************************************** + * Exported global variables + **********************************************************************************************************************/ + +/** @cond INC_HEADER_DEFS_SEC */ +/** Filled in Interface API structure for this Instance. */ +extern const sdmmc_api_t g_sdmmc_on_sdemmc_w; + +/** @endcond */ + +/********************************************************************************************************************** + * Function Prototypes + **********************************************************************************************************************/ + +fsp_err_t R_SDEMMC_W_Open(sdmmc_ctrl_t * const p_api_ctrl, sdmmc_cfg_t const * const p_cfg); +fsp_err_t R_SDEMMC_W_MediaInit(sdmmc_ctrl_t * const p_api_ctrl, sdmmc_device_t * const p_device); +fsp_err_t R_SDEMMC_W_Read(sdmmc_ctrl_t * const p_api_ctrl, + uint8_t * const p_dest, + uint32_t const start_sector, + uint32_t const sector_count); +fsp_err_t R_SDEMMC_W_Write(sdmmc_ctrl_t * const p_api_ctrl, + uint8_t const * const p_source, + uint32_t const start_sector, + uint32_t const sector_count); +fsp_err_t R_SDEMMC_W_ReadIo(sdmmc_ctrl_t * const p_api_ctrl, + uint8_t * const p_data, + uint32_t const function, + uint32_t const address); +fsp_err_t R_SDEMMC_W_WriteIo(sdmmc_ctrl_t * const p_api_ctrl, + uint8_t * const p_data, + uint32_t const function, + uint32_t const address, + sdmmc_io_write_mode_t const read_after_write); +fsp_err_t R_SDEMMC_W_ReadIoExt(sdmmc_ctrl_t * const p_api_ctrl, + uint8_t * const p_dest, + uint32_t const function, + uint32_t const address, + uint32_t * const count, + sdmmc_io_transfer_mode_t transfer_mode, + sdmmc_io_address_mode_t address_mode); +fsp_err_t R_SDEMMC_W_WriteIoExt(sdmmc_ctrl_t * const p_api_ctrl, + uint8_t const * const p_source, + uint32_t const function, + uint32_t const address, + uint32_t const count, + sdmmc_io_transfer_mode_t transfer_mode, + sdmmc_io_address_mode_t address_mode); +fsp_err_t R_SDEMMC_W_IoIntEnable(sdmmc_ctrl_t * const p_api_ctrl, bool enable); +fsp_err_t R_SDEMMC_W_StatusGet(sdmmc_ctrl_t * const p_api_ctrl, sdmmc_status_t * const p_status); +fsp_err_t R_SDEMMC_W_Erase(sdmmc_ctrl_t * const p_api_ctrl, uint32_t const start_sector, uint32_t const sector_count); +fsp_err_t R_SDEMMC_W_CallbackSet(sdmmc_ctrl_t * const p_api_ctrl, + void ( * p_callback)(sdmmc_callback_args_t *), + void * const p_context, + sdmmc_callback_args_t * const p_callback_memory); +fsp_err_t R_SDEMMC_W_Close(sdmmc_ctrl_t * const p_api_ctrl); +fsp_err_t R_SDEMMC_W_ResultGet(sdmmc_ctrl_t * const p_api_ctrl, sdemmc_w_transfer_result_t * p_result); + +/* Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ +FSP_FOOTER + +#endif /* R_SDEMMC_W_H */ + +/*******************************************************************************************************************//** + * @} (end addtogroup SDEMMC_W) + **********************************************************************************************************************/ diff --git a/bsp/renesas/ra6w1-ek/ra/fsp/src/bsp_w/cmsis/Device/RENESAS/Source/system.c b/bsp/renesas/ra6w1-ek/ra/fsp/src/bsp_w/cmsis/Device/RENESAS/Source/system.c index bc849f109a5f..efb0d815c681 100644 --- a/bsp/renesas/ra6w1-ek/ra/fsp/src/bsp_w/cmsis/Device/RENESAS/Source/system.c +++ b/bsp/renesas/ra6w1-ek/ra/fsp/src/bsp_w/cmsis/Device/RENESAS/Source/system.c @@ -241,6 +241,9 @@ void SystemInit (void) /* Initialize ELC events that will be used to trigger NVIC interrupts. */ bsp_irq_cfg(); + + /* Call any BSP specific code. No arguments are needed so NULL is sent. */ + bsp_init(NULL); } /*******************************************************************************************************************//** @@ -413,7 +416,7 @@ extern int _kill_r(void * _reent, int _pid, int _signal); extern int _getpid_r(void * _reent); extern int _gettimeofday_r(void * _reent, void * _tp, void * _tzp); - #if 0 + #if BSP_MCU_GROUP_RA6W1 // TIN-TODO: All these are required due to the printfs inside RA6W1 BSP. Are printfs accepted at BSP level? struct stat; @@ -472,9 +475,8 @@ int _gettimeofday_r (void * _reent, void * _tp, void * _tzp) return -1; } -#endif - #if 0 + #if BSP_MCU_GROUP_RA6W1 // TIN-TODO: All these are required due to the printfs inside RA6W1 BSP. Are printfs accepted at BSP level? /*******************************************************************************************************************//** * Stub to override _open_r(), to silence a link warning when using recent gcc @@ -548,6 +550,7 @@ int _unlink_r (struct _reent * _reent, const char * _path) #endif #endif +#endif #if defined(__GNUC__) || defined(__ICCARM__) __STATIC_FORCEINLINE void bsp_debugger_enable (void) diff --git a/bsp/renesas/ra6w1-ek/ra/fsp/src/r_adc_w/r_adc_w.c b/bsp/renesas/ra6w1-ek/ra/fsp/src/r_adc_w/r_adc_w.c index 65ef9a62a006..a770cf07225c 100644 --- a/bsp/renesas/ra6w1-ek/ra/fsp/src/r_adc_w/r_adc_w.c +++ b/bsp/renesas/ra6w1-ek/ra/fsp/src/r_adc_w/r_adc_w.c @@ -9,7 +9,7 @@ **********************************************************************************************************************/ #include "r_adc_w_cfg.h" #include "r_adc_w.h" -#include "../bsp/mcu/ra6w1/config/bsp_device_definitions.h" +#include "../bsp_w/mcu/ra6w1/config/bsp_device_definitions.h" /********************************************************************************************************************** * Macro definitions diff --git a/bsp/renesas/ra6w1-ek/ra/fsp/src/r_dmac_w/r_dmac_w.c b/bsp/renesas/ra6w1-ek/ra/fsp/src/r_dmac_w/r_dmac_w.c new file mode 100644 index 000000000000..923eed93243d --- /dev/null +++ b/bsp/renesas/ra6w1-ek/ra/fsp/src/r_dmac_w/r_dmac_w.c @@ -0,0 +1,745 @@ +/* +* Copyright (c) 2020 - 2026 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ +#include "r_dmac_w.h" +#include "r_dmac_w_cfg.h" + +/*********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ + +/** Driver ID (DMAC in ASCII) */ +#define DMAC_ID (0x444d4143) + +/* Calculate the mask bits for byte alignment from the transfer_size_t. */ +#define DMAC_PRV_MASK_ALIGN_N_BYTES(x) ((1U << (x)) - 1U) + +#define DMAC_PRV_REG(ch) (DMA_Type *) (&DMA->DMA0_A_START_REG + \ + (&DMA->DMA1_A_START_REG - &DMA->DMA0_A_START_REG) * (ch)) + +#define DMAC_PRV_MUX_SEL_MASK (DMA_DMA_REQ_MUX_REG_DMA0_SEL_Msk) + +#define DMAC_PRV_MUX_SEL_BITS (DMA_DMA_REQ_MUX_REG_DMA1_SEL_Pos - DMA_DMA_REQ_MUX_REG_DMA0_SEL_Pos) + +#define DMAC_PRV_MUX_CH_OFFSET (4) + +#define DMAC_PRV_CHANNEL_PRIO_HIGHEST (7) + +/*********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Private function prototypes + **********************************************************************************************************************/ +void dmac_w_int_isr(void); + +static void r_dmac_w_config_transfer_info(dmac_instance_ctrl_t * p_ctrl, transfer_info_t * p_info); +static fsp_err_t r_dmac_w_channel_enable(dmac_instance_ctrl_t * p_ctrl); +static void r_dmac_w_peripherals_map(dmac_instance_ctrl_t * const p_ctrl); +static void r_dmac_w_peripherals_unmap(uint8_t channel); +static void r_dmac_w_interrupt_handle(dmac_instance_ctrl_t * const p_ctrl); +static void r_dmac_w_irq_enable(dmac_instance_ctrl_t * const p_ctrl); +static void r_dmac_w_irq_disable(dmac_instance_ctrl_t * const p_ctrl); +static void r_dmac_w_dma_mux_reg_set(uint8_t channel, bsp_dmac_trig_t periph_trigger); + +#if DMAC_W_CFG_PARAM_CHECKING_ENABLE +static fsp_err_t r_dma_open_parameter_checking(dmac_instance_ctrl_t * const p_ctrl, transfer_cfg_t const * const p_cfg); +static fsp_err_t r_dmac_w_reconfigure_parameter_checking(transfer_info_t const * const p_info); +static fsp_err_t r_dmac_w_enable_parameter_checking(dmac_instance_ctrl_t * const p_ctrl); + +#endif + +/*********************************************************************************************************************** + * Private global variables + **********************************************************************************************************************/ + +#if BSP_FEATURE_DMAC_HAS_SHARED_IRQ +static dmac_instance_ctrl_t * volatile gp_dmac_ctrls[BSP_FEATURE_DMAC_MAX_CHANNEL]; +#endif + +/*********************************************************************************************************************** + * Exported global variables + **********************************************************************************************************************/ + +/** DMAC implementation of transfer API. */ +const transfer_api_t g_transfer_on_dmac_w = +{ + .open = R_DMAC_W_Open, + .reconfigure = R_DMAC_W_Reconfigure, + .reset = R_DMAC_W_Reset, + .infoGet = R_DMAC_W_InfoGet, + .softwareStart = R_DMAC_W_SoftwareStart, + .softwareStop = R_DMAC_W_SoftwareStop, + .enable = R_DMAC_W_Enable, + .disable = R_DMAC_W_Disable, + .reload = R_DMAC_W_Reload, + .callbackSet = R_DMAC_W_CallbackSet, + .close = R_DMAC_W_Close, +}; + +/*******************************************************************************************************************//** + * @addtogroup DMAC_W + * @{ + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Functions + **********************************************************************************************************************/ + +/*******************************************************************************************************************//** + * Configure a DMAC channel. + * + * Example: + * @snippet r_dmac_w_example.c R_DMAC_W_Open + * + * @retval FSP_SUCCESS Successful open. + * @retval FSP_ERR_ASSERTION An input parameter is invalid. + * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT The configured channel is invalid. + * @retval FSP_ERR_IRQ_BSP_DISABLED The IRQ associated with the activation source is not enabled in the BSP. + * @retval FSP_ERR_ALREADY_OPEN The control structure is already opened. + * @retval FSP_ERR_UNSUPPORTED A Selected setting is not supported by this API. + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_Open (transfer_ctrl_t * const p_api_ctrl, transfer_cfg_t const * const p_cfg) +{ +#if DMAC_W_CFG_PARAM_CHECKING_ENABLE + fsp_err_t err = FSP_SUCCESS; + err = r_dma_open_parameter_checking(p_api_ctrl, p_cfg); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); +#endif + + dmac_instance_ctrl_t * p_ctrl = (dmac_instance_ctrl_t *) p_api_ctrl; + dmac_extended_cfg_t * p_extend = (dmac_extended_cfg_t *) p_cfg->p_extend; + + p_ctrl->p_cfg = p_cfg; + p_ctrl->p_reg = (DMA_Type *) DMAC_PRV_REG(p_extend->channel); + + /* Set callback and context pointers, if configured */ + p_ctrl->p_callback = p_extend->p_callback; + p_ctrl->p_context = p_extend->p_context; + p_ctrl->p_callback_memory = NULL; + + /* Configure the transfer settings. */ + r_dmac_w_config_transfer_info(p_ctrl, p_cfg->p_info); + + /* Mark driver as open by initializing "DMAC" in its ASCII equivalent.*/ + p_ctrl->open = DMAC_ID; + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Reconfigure the transfer with new transfer info. + * + * @retval FSP_SUCCESS Transfer is configured and will start when R_DMAC_W_Enable() is called. + * @retval FSP_ERR_ASSERTION An input parameter is invalid. + * @retval FSP_ERR_UNSUPPORTED A Selected setting is not supported by this API. + * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_W_Open to initialize the control block. + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_Reconfigure (transfer_ctrl_t * const p_api_ctrl, transfer_info_t * p_info) +{ + fsp_err_t err; + dmac_instance_ctrl_t * p_ctrl = (dmac_instance_ctrl_t *) p_api_ctrl; + +#if DMAC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(DMAC_ID == p_ctrl->open, FSP_ERR_NOT_OPEN); + err = r_dmac_w_reconfigure_parameter_checking(p_info); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); +#else + FSP_PARAMETER_NOT_USED(err); +#endif + + /* Reconfigure the transfer settings. */ + r_dmac_w_config_transfer_info(p_ctrl, p_info); + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Reset transfer source and destination. + * + * @retval FSP_ERR_UNSUPPORTED This feature is not supported. + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_Reset (transfer_ctrl_t * const p_api_ctrl, + void const * volatile p_src, + void * volatile p_dest, + uint16_t const num_transfers) +{ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(p_src); + FSP_PARAMETER_NOT_USED(p_dest); + FSP_PARAMETER_NOT_USED(num_transfers); + + return FSP_ERR_UNSUPPORTED; +} + +/*******************************************************************************************************************//** + * If the mode is TRANSFER_START_MODE_SINGLE initiate a single transfer with software. If the mode is + * TRANSFER_START_MODE_REPEAT continue triggering transfers until all of the transfers are completed. + * + * @retval FSP_ERR_UNSUPPORTED This feature is not supported. + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_SoftwareStart (transfer_ctrl_t * const p_api_ctrl, transfer_start_mode_t mode) +{ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(mode); + + return FSP_ERR_UNSUPPORTED; +} + +/*******************************************************************************************************************//** + * Stop software transfers if they were started with TRANSFER_START_MODE_REPEAT. + * + * @retval FSP_ERR_UNSUPPORTED This feature is not supported. + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_SoftwareStop (transfer_ctrl_t * const p_api_ctrl) +{ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + + return FSP_ERR_UNSUPPORTED; +} + +/*******************************************************************************************************************//** + * Enable a DMAC channel. + * + * Example: + * @snippet r_dmac_w_example.c R_DMAC_W_Enable + * + * @retval FSP_SUCCESS DMAC channel activated successfully. + * @retval FSP_ERR_ASSERTION An input parameter is invalid. + * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_W_Open to initialize the control block. + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_Enable (transfer_ctrl_t * const p_api_ctrl) +{ + dmac_instance_ctrl_t * p_ctrl = (dmac_instance_ctrl_t *) p_api_ctrl; +#if DMAC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(DMAC_ID == p_ctrl->open, FSP_ERR_NOT_OPEN); +#endif + fsp_err_t err = r_dmac_w_channel_enable(p_ctrl); + + return err; +} + +/*******************************************************************************************************************//** + * Disable a Dmac channel. + * + * @retval FSP_SUCCESS DMAC channel disabled successfully. + * @retval FSP_ERR_ASSERTION An input parameter is invalid. + * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_W_Open to initialize the control block. + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_Disable (transfer_ctrl_t * const p_api_ctrl) +{ + dmac_instance_ctrl_t * p_ctrl = (dmac_instance_ctrl_t *) p_api_ctrl; +#if DMAC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(DMAC_ID == p_ctrl->open, FSP_ERR_NOT_OPEN); +#endif + p_ctrl->p_reg->DMA0_CTRL_REG_b.DMA_ON = 0U; + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Set driver specific information in provided pointer. + * + * @retval FSP_SUCCESS Information has been written to p_info. + * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_W_Open to initialize the control block. + * @retval FSP_ERR_ASSERTION An input parameter is invalid. + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_InfoGet (transfer_ctrl_t * const p_api_ctrl, transfer_properties_t * const p_info) +{ + dmac_instance_ctrl_t * p_ctrl = (dmac_instance_ctrl_t *) p_api_ctrl; +#if DMAC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(DMAC_ID == p_ctrl->open, FSP_ERR_NOT_OPEN); + FSP_ASSERT(NULL != p_info); +#endif + + p_info->block_count_remaining = 0U; + p_info->block_count_max = 0U; + p_info->transfer_length_max = DMAC_MAX_NORMAL_TRANSFER_LENGTH; + + if ((p_ctrl->p_reg->DMA0_LEN_REG == p_ctrl->p_reg->DMA0_IDX_REG) && (0U != p_ctrl->p_reg->DMA0_LEN_REG)) + { + p_info->transfer_length_remaining = 0U; + } + else + { + p_info->transfer_length_remaining = (p_ctrl->p_reg->DMA0_LEN_REG + 1) - p_ctrl->p_reg->DMA0_IDX_REG; + } + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * To update next transfer information without interruption during transfer. + * + * @retval FSP_ERR_UNSUPPORTED This feature is not supported. + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_Reload (transfer_ctrl_t * const p_api_ctrl, + void const * p_src, + void * p_dest, + uint32_t const num_transfers) +{ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(p_src); + FSP_PARAMETER_NOT_USED(p_dest); + FSP_PARAMETER_NOT_USED(num_transfers); + + return FSP_ERR_UNSUPPORTED; +} + +/*******************************************************************************************************************//** + * Updates the user callback with the option to provide memory for the callback argument structure. + * + * @retval FSP_SUCCESS Callback updated successfully. + * @retval FSP_ERR_ASSERTION A required pointer is NULL. + * @retval FSP_ERR_NOT_OPEN The control block has not been opened. + * @retval FSP_ERR_IRQ_BSP_DISABLED The IRQ associated with the activation source is not enabled in the BSP. + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_CallbackSet (transfer_ctrl_t * const p_api_ctrl, + void ( * p_callback)(dmac_callback_args_t *), + void * const p_context, + dmac_callback_args_t * const p_callback_memory) +{ + FSP_PARAMETER_NOT_USED(p_callback_memory); + + dmac_instance_ctrl_t * p_ctrl = (dmac_instance_ctrl_t *) p_api_ctrl; + +#if DMAC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ASSERT(p_callback); + FSP_ERROR_RETURN(p_ctrl->open == DMAC_ID, FSP_ERR_NOT_OPEN); + dmac_extended_cfg_t * p_extend = (dmac_extended_cfg_t *) p_ctrl->p_cfg->p_extend; + FSP_ERROR_RETURN(p_extend->irq >= 0, FSP_ERR_IRQ_BSP_DISABLED); +#endif + + p_ctrl->p_callback = p_callback; + p_ctrl->p_context = p_context; + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Disable transfer and clean up internal data. Implements @ref transfer_api_t::close. + * + * @retval FSP_SUCCESS Successful close. + * @retval FSP_ERR_ASSERTION An input parameter is invalid. + * @retval FSP_ERR_NOT_OPEN Handle is not initialized. Call R_DMAC_W_Open to initialize the control block. + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_Close (transfer_ctrl_t * const p_api_ctrl) +{ + dmac_instance_ctrl_t * p_ctrl = (dmac_instance_ctrl_t *) p_api_ctrl; +#if DMAC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(DMAC_ID == p_ctrl->open, FSP_ERR_NOT_OPEN); +#endif + + dmac_extended_cfg_t * p_extend = (dmac_extended_cfg_t *) p_ctrl->p_cfg->p_extend; + + p_ctrl->p_reg->DMA0_CTRL_REG_b.DMA_ON = 0U; + + r_dmac_w_peripherals_unmap(p_extend->channel); + + if (NULL != p_ctrl->p_callback) + { + r_dmac_w_irq_disable(p_ctrl); + + R_BSP_DMAC_ChannelInterruptsDisable(p_extend->channel); + +#if BSP_FEATURE_DMAC_HAS_SHARED_IRQ + gp_dmac_ctrls[p_extend->channel] = NULL; +#endif + } + + /* Clear ID so control block can be reused. */ + p_ctrl->open = 0U; + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Temporarily freeze/unfreeze all channels of the DMAC controller. + * + * Example: + * @snippet r_dmac_w_example.c R_DMAC_W_Freeze + * + * @retval FSP_SUCCESS Successful freeze. + **********************************************************************************************************************/ +fsp_err_t R_DMAC_W_Freeze (bool freeze) +{ + if (freeze) + { + R_BSP_PeripheralFreeze(BSP_FREEZE_PERIPHERAL_DMA); + } + else + { + R_BSP_PeripheralUnFreeze(BSP_FREEZE_PERIPHERAL_DMA); + } + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * @} (end addtogroup DMAC_W) + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Private Functions + **********************************************************************************************************************/ + +/*******************************************************************************************************************//** + * Write the transfer info to the hardware registers. + * + * @param[in] p_ctrl Pointer to control structure. + * @param p_info Pointer to transfer info. + **********************************************************************************************************************/ +static void r_dmac_w_config_transfer_info (dmac_instance_ctrl_t * p_ctrl, transfer_info_t * p_info) +{ + dmac_extended_cfg_t * p_extend = (dmac_extended_cfg_t *) p_ctrl->p_cfg->p_extend; + + p_ctrl->p_reg->DMA0_CTRL_REG_b.DMA_ON = 0U; + + uint32_t a_inc = ((TRANSFER_ADDR_MODE_INCREMENTED == p_info->transfer_settings_word_b.src_addr_mode) ? 1 : 0); + uint32_t b_inc = ((TRANSFER_ADDR_MODE_INCREMENTED == p_info->transfer_settings_word_b.dest_addr_mode) ? 1 : 0); + + p_ctrl->p_reg->DMA0_CTRL_REG = + (p_info->transfer_settings_word_b.size << DMA_DMA0_CTRL_REG_BW_Pos) | + ((uint32_t) p_extend->start_mode << DMA_DMA0_CTRL_REG_DREQ_MODE_Pos) | + (a_inc << DMA_DMA0_CTRL_REG_AINC_Pos) | + (b_inc << DMA_DMA0_CTRL_REG_BINC_Pos) | + (p_info->transfer_settings_word_b.mode << DMA_DMA0_CTRL_REG_CIRCULAR_Pos) | + (p_extend->channel_prio << DMA_DMA0_CTRL_REG_DMA_PRIO_Pos) | + (p_extend->idle_mode << DMA_DMA0_CTRL_REG_DMA_IDLE_Pos) | + (p_extend->init_mode << DMA_DMA0_CTRL_REG_DMA_INIT_Pos) | + (p_extend->burst_mode << DMA_DMA0_CTRL_REG_BURST_MODE_Pos) | + (DMA_DMA0_CTRL_REG_BUS_ERROR_DETECT_Msk); + + if (NULL != p_ctrl->p_callback) + { +#if BSP_FEATURE_DMAC_HAS_SHARED_IRQ + gp_dmac_ctrls[p_extend->channel] = p_ctrl; +#endif + R_BSP_DMAC_ChannelInterruptsEnable(p_extend->channel); + + r_dmac_w_irq_enable(p_ctrl); + } + else + { + R_BSP_DMAC_ChannelInterruptsDisable(p_extend->channel); + } + + r_dmac_w_peripherals_map(p_ctrl); + + if (R_BSP_DMAC_IsEdgeSensitiveTrigger(p_extend->periph_trigger)) + { + p_ctrl->p_reg->DMA0_CTRL_REG_b.REQ_SENSE = 1U; + } + + p_ctrl->p_reg->DMA0_A_START_REG = (uint32_t) p_info->p_src; + p_ctrl->p_reg->DMA0_B_START_REG = (uint32_t) p_info->p_dest; + + if (p_extend->irq_num_of_trans > 0) + { + p_ctrl->p_reg->DMA0_INT_REG = (uint32_t) (p_extend->irq_num_of_trans - 1); + } + else + { + p_ctrl->p_reg->DMA0_INT_REG = (uint32_t) (p_info->length - 1); + } + + p_ctrl->p_reg->DMA0_LEN_REG = (uint32_t) (p_info->length - 1); +} + +/*******************************************************************************************************************//** + * Enable transfers for the channel. + * + * @param[in] p_ctrl Pointer to control structure. + * + * @retval FSP_SUCCESS Successful enable. + * @retval FSP_ERR_ASSERTION An input parameter is invalid. + **********************************************************************************************************************/ +static fsp_err_t r_dmac_w_channel_enable (dmac_instance_ctrl_t * p_ctrl) +{ +#if DMAC_W_CFG_PARAM_CHECKING_ENABLE + fsp_err_t err = r_dmac_w_enable_parameter_checking(p_ctrl); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); +#endif + + p_ctrl->p_reg->DMA0_CTRL_REG_b.DMA_ON = 1U; + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Set DMA MUX mapping for the requested channel / trigger combination. + * + * @param[in] channel DMA channel. + * @param[in] periph_trigger The peripheral trigger to map on the DMAC channel. + **********************************************************************************************************************/ +static void r_dmac_w_dma_mux_reg_set (uint8_t channel, bsp_dmac_trig_t periph_trigger) +{ + uint8_t mux_index = (uint8_t) (channel / DMAC_PRV_MUX_CH_OFFSET); + uint8_t mux_sel = (uint8_t) (channel % DMAC_PRV_MUX_CH_OFFSET); + volatile uint32_t * p_dma_req_mux_regs = &DMA->DMA_REQ_MUX_REG; + + /* DMAC MUX registers are placed in the memory one after another. + * We can access every MUX register as an array element. */ + + p_dma_req_mux_regs[mux_index] = ((p_dma_req_mux_regs[mux_index] & + ~(DMAC_PRV_MUX_SEL_MASK << (mux_sel * DMAC_PRV_MUX_SEL_BITS))) | + ((uint32_t) periph_trigger << (mux_sel * DMAC_PRV_MUX_SEL_BITS))); +} + +/*******************************************************************************************************************//** + * Map DMAC channel to specific peripheral trigger. + * + * @param[in] p_ctrl Pointer to control structure. + **********************************************************************************************************************/ +static void r_dmac_w_peripherals_map (dmac_instance_ctrl_t * const p_ctrl) +{ + dmac_extended_cfg_t * p_extend = (dmac_extended_cfg_t *) p_ctrl->p_cfg->p_extend; + FSP_CRITICAL_SECTION_DEFINE; + + FSP_CRITICAL_SECTION_ENTER; + r_dmac_w_dma_mux_reg_set(p_extend->channel, p_extend->periph_trigger); + FSP_CRITICAL_SECTION_EXIT; +} + +/*******************************************************************************************************************//** + * Disable peripheral mapping on the DMAC channel. + * + * @param[in] channel DMAC channel. + **********************************************************************************************************************/ +static void r_dmac_w_peripherals_unmap (uint8_t channel) +{ + FSP_CRITICAL_SECTION_DEFINE; + + FSP_CRITICAL_SECTION_ENTER; + r_dmac_w_dma_mux_reg_set(channel, BSP_DMAC_TRIG_NONE); + FSP_CRITICAL_SECTION_EXIT; +} + +#if DMAC_W_CFG_PARAM_CHECKING_ENABLE + +/*******************************************************************************************************************//** + * Parameter checking of R_DMAC_W_Open. + * + * @param[in] p_ctrl Pointer to control structure. + * @param[in] p_cfg Pointer to configuration structure. All elements of the structure must be + * set by user. + * + * @retval FSP_SUCCESS Input Parameters are Valid. + * @retval FSP_ERR_ASSERTION An input parameter is invalid. + * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT The configured channel is invalid. + * @retval FSP_ERR_IRQ_BSP_DISABLED Callback is not NULL but the DMAC IRQ is not enabled. + * @retval FSP_ERR_ALREADY_OPEN The control structure is already opened. + * @retval FSP_ERR_UNSUPPORTED A Selected setting is not supported by this API. + **********************************************************************************************************************/ +static fsp_err_t r_dma_open_parameter_checking (dmac_instance_ctrl_t * const p_ctrl, transfer_cfg_t const * const p_cfg) +{ + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(DMAC_ID != p_ctrl->open, FSP_ERR_ALREADY_OPEN); + FSP_ASSERT(NULL != p_cfg); + dmac_extended_cfg_t * p_extend = (dmac_extended_cfg_t *) p_cfg->p_extend; + FSP_ASSERT(NULL != p_cfg->p_extend); + FSP_ASSERT(DMAC_PRV_CHANNEL_PRIO_HIGHEST >= p_extend->channel_prio); + FSP_ERROR_RETURN(BSP_FEATURE_DMAC_MAX_CHANNEL > p_extend->channel, FSP_ERR_IP_CHANNEL_NOT_PRESENT); + + if (NULL != p_extend->p_callback) + { + FSP_ERROR_RETURN(p_extend->irq >= 0, FSP_ERR_IRQ_BSP_DISABLED); + } + + fsp_err_t err = r_dmac_w_reconfigure_parameter_checking(p_cfg->p_info); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Checks for errors in the transfer into structure. + * + * @param[in] p_info Pointer transfer info. + * + * @retval FSP_SUCCESS The transfer info is valid. + * @retval FSP_ERR_ASSERTION A transfer info setting is invalid. + * @retval FSP_ERR_UNSUPPORTED A Selected setting is not supported by this API. + **********************************************************************************************************************/ +static fsp_err_t r_dmac_w_reconfigure_parameter_checking (transfer_info_t const * const p_info) +{ + FSP_ASSERT(NULL != p_info); + FSP_ASSERT(0 < p_info->length); + + FSP_ERROR_RETURN((TRANSFER_ADDR_MODE_FIXED == p_info->transfer_settings_word_b.src_addr_mode) || + (TRANSFER_ADDR_MODE_INCREMENTED == p_info->transfer_settings_word_b.src_addr_mode), + FSP_ERR_UNSUPPORTED); + + FSP_ERROR_RETURN((TRANSFER_ADDR_MODE_FIXED == p_info->transfer_settings_word_b.dest_addr_mode) || + (TRANSFER_ADDR_MODE_INCREMENTED == p_info->transfer_settings_word_b.dest_addr_mode), + FSP_ERR_UNSUPPORTED); + + FSP_ERROR_RETURN((TRANSFER_MODE_NORMAL == p_info->transfer_settings_word_b.mode) || + (TRANSFER_MODE_REPEAT == p_info->transfer_settings_word_b.mode), + FSP_ERR_UNSUPPORTED); + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Parameter checking for transfer configuration. + * + * @param[in] p_ctrl Pointer to control structure. + * + * @retval FSP_SUCCESS Alignment on source and destination pointers is valid. + * @retval FSP_ERR_ASSERTION The current configuration is invalid. + **********************************************************************************************************************/ +static fsp_err_t r_dmac_w_enable_parameter_checking (dmac_instance_ctrl_t * const p_ctrl) +{ + FSP_ASSERT(0U == p_ctrl->p_reg->DMA0_CTRL_REG_b.DMA_ON); + + void const * p_src = (void const *) p_ctrl->p_reg->DMA0_A_START_REG; + void const * p_dest = (void const *) p_ctrl->p_reg->DMA0_B_START_REG; + + transfer_size_t size = (transfer_size_t) p_ctrl->p_reg->DMA0_CTRL_REG_b.BW; + transfer_mode_t mode = (transfer_mode_t) p_ctrl->p_reg->DMA0_CTRL_REG_b.CIRCULAR; + + /* The source and destination pointers cannot be NULL. */ + FSP_ASSERT(NULL != p_src); + FSP_ASSERT(NULL != p_dest); + + /* The source and destination pointers must be aligned to the transfer size. */ + + FSP_ASSERT(0U == ((uint32_t) p_dest & DMAC_PRV_MASK_ALIGN_N_BYTES(size))); + FSP_ASSERT(0U == ((uint32_t) p_src & DMAC_PRV_MASK_ALIGN_N_BYTES(size))); + + if (TRANSFER_MODE_REPEAT == mode) + { + FSP_ASSERT(1U == p_ctrl->p_reg->DMA0_CTRL_REG_b.DREQ_MODE); + } + + return FSP_SUCCESS; +} + +#endif + +/*******************************************************************************************************************//** + * Enable IRQ for DMA channel. + * + * @param[in] p_ctrl Pointer to control structure. + **********************************************************************************************************************/ +static void r_dmac_w_irq_enable (dmac_instance_ctrl_t * const p_ctrl) +{ + dmac_extended_cfg_t * p_extend = (dmac_extended_cfg_t *) p_ctrl->p_cfg->p_extend; + +#if BSP_FEATURE_DMAC_HAS_SHARED_IRQ + for (uint8_t channel = 0; BSP_FEATURE_DMAC_MAX_CHANNEL > channel; channel++) + { + if ((NULL != gp_dmac_ctrls[channel]) && (channel != p_extend->channel)) + { + + /* If we have registered channel previously. No need to enable DMA IRQ again. */ + return; + } + } +#endif + + R_BSP_IrqCfgEnable(p_extend->irq, p_extend->ipl, p_ctrl); +} + +/*******************************************************************************************************************//** + * Disable IRQ for DMA channel. + * + * @param[in] p_ctrl Pointer to control structure. + **********************************************************************************************************************/ +static void r_dmac_w_irq_disable (dmac_instance_ctrl_t * const p_ctrl) +{ + dmac_extended_cfg_t * p_extend = (dmac_extended_cfg_t *) p_ctrl->p_cfg->p_extend; + +#if BSP_FEATURE_DMAC_HAS_SHARED_IRQ + for (uint8_t channel = 0; BSP_FEATURE_DMAC_MAX_CHANNEL > channel; channel++) + { + if ((NULL != gp_dmac_ctrls[channel]) && (channel != p_extend->channel)) + { + + /* It isn't last registered channel. No need to disable DMA IRQ just yet. */ + return; + } + } +#endif + + R_BSP_IrqDisable(p_extend->irq); + R_FSP_IsrContextSet(p_extend->irq, NULL); +} + +/*******************************************************************************************************************//** + * Process interrupt on specific DMA channel. + * + * @param[in] p_ctrl Pointer to control structure. + **********************************************************************************************************************/ +static void r_dmac_w_interrupt_handle (dmac_instance_ctrl_t * const p_ctrl) +{ + dmac_extended_cfg_t * p_extend = (dmac_extended_cfg_t *) p_ctrl->p_cfg->p_extend; + + DMA->DMA_CLEAR_INT_REG = 1 << p_extend->channel; + + /* Call user callback */ + dmac_callback_args_t args; + args.p_context = p_ctrl->p_context; + p_ctrl->p_callback(&args); +} + +/*******************************************************************************************************************//** + * DMAC ISR + **********************************************************************************************************************/ +void dmac_w_int_isr (void) +{ + /* Save context if RTOS is used */ + FSP_CONTEXT_SAVE; + +#if BSP_FEATURE_BSP_HAS_ICU || BSP_FEATURE_DMAC_HAS_SHARED_IRQ == 0 + IRQn_Type irq = R_FSP_CurrentIrqGet(); + + #if BSP_FEATURE_BSP_HAS_ICU + + /* Clear IRQ to make sure it doesn't fire again after exiting */ + R_BSP_IrqStatusClear(irq); + #endif +#endif + +#if BSP_FEATURE_DMAC_HAS_SHARED_IRQ + uint32_t channel_interrupts = DMA->DMA_INT_STATUS_REG; + + /* Go over all the DMA channels. Check for interrupt events */ + for (uint8_t channel = 0; + 0 != channel_interrupts && BSP_FEATURE_DMAC_MAX_CHANNEL > channel; + channel_interrupts >>= 1, channel++) + { + if (0 != (channel_interrupts & 1)) + { + if (NULL != gp_dmac_ctrls[channel]) + { + r_dmac_w_interrupt_handle(gp_dmac_ctrls[channel]); + } + } + } + +#else + + /* Handle interrupt for a channel associated with received IRQn */ + dmac_instance_ctrl_t * p_ctrl = R_FSP_IsrContextGet(irq); + + r_dmac_w_interrupt_handle(p_ctrl); +#endif + + /* Restore context if RTOS is used. */ + FSP_CONTEXT_RESTORE; +} diff --git a/bsp/renesas/ra6w1-ek/ra/fsp/src/r_sdemmc_w/r_sdemmc_w.c b/bsp/renesas/ra6w1-ek/ra/fsp/src/r_sdemmc_w/r_sdemmc_w.c new file mode 100644 index 000000000000..baef2215fca2 --- /dev/null +++ b/bsp/renesas/ra6w1-ek/ra/fsp/src/r_sdemmc_w/r_sdemmc_w.c @@ -0,0 +1,5623 @@ +/* +* Copyright (c) 2020 - 2026 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +/*********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ +#include +#include +#include +#include "r_sdemmc_w.h" +#include "r_sdemmc_w_private.h" +#include "r_sdemmc_w_cfg.h" + +#if (CFG_PMGR == 1) && (SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE == 1) + #include "rm_pmgr_w_instance.h" +#endif + +/*********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ + +/** "SDHI" in ASCII, used to determine if channel is open. */ +#define SDEMMC_W_PRV_OPEN (0x53444849U) +#define SDEMMC_W_PRV_SLEEP (0xAAAAAAAAU) + +/* Create a bitmask of access errors. */ +/* Command error */ +#define SDEMMC_W_PRV_CARD_CMD_ERR (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_CommandIndexError_Msk) + +/* CRC error */ +#define SDEMMC_W_PRV_CARD_CRC_ERR (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_CommandCRCError_Msk) + +/* End bit error */ +#define SDEMMC_W_PRV_CARD_END_ERR (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_CommandEndBitError_Msk) + +/* Data Timeout */ +#define SDEMMC_W_PRV_CARD_DTO (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_DataTimeoutError_Msk) + +/* Error Interrupt */ +#define SDEMMC_W_PRV_CARD_ERR_INT (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_ErrorInterrupt_Msk) + +/* Timeout */ +#define SDEMMC_W_PRV_CARD_CTO (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_CommandTimeoutError_Msk) + +/* Data CRC error */ +#define SDEMMC_W_PRV_CARD_D_CRC_ERR (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_DataCRCError_Msk) + +/* Data End bit error */ +#define SDEMMC_W_PRV_CARD_D_END_ERR (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_DataEndBitError_Msk) + +/* Current Limit error */ +#define SDEMMC_W_PRV_CARD_CUR_LMT (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_CurrentLimitError_Msk) + +/* Auto Command error */ +#define SDEMMC_W_PRV_CARD_AUTO_ERR (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_AutoCMDError_Msk) + +/* ADMA error */ +#define SDEMMC_W_PRV_CARD_ADMA_ERR (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_ADMAError_Msk) + +/* Tuning error */ +#define SDEMMC_W_PRV_CARD_TUNE_ERR (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_TuningError_Msk) + +#define SDEMMC_W_PRV_ACCESS_ERROR_MASK (SDEMMC_W_PRV_CARD_CMD_ERR | SDEMMC_W_PRV_CARD_CRC_ERR | \ + SDEMMC_W_PRV_CARD_END_ERR | SDEMMC_W_PRV_CARD_DTO | \ + SDEMMC_W_PRV_CARD_ERR_INT | SDEMMC_W_PRV_CARD_CTO | \ + SDEMMC_W_PRV_CARD_D_CRC_ERR | SDEMMC_W_PRV_CARD_D_END_ERR | \ + SDEMMC_W_PRV_CARD_CUR_LMT | SDEMMC_W_PRV_CARD_AUTO_ERR | \ + SDEMMC_W_PRV_CARD_ADMA_ERR | SDEMMC_W_PRV_CARD_TUNE_ERR) + +/* The clock register can be accessed 8 SD clock cycles after the last command completes. */ + +/* SDEMMC_NORMAL_ITNR_STATUS_REG */ +/* Response End */ +#define SDEMMC_W_PRV_SDHI_INFO1_RESPONSE_END (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_CommandComplete_Msk) + +/* Access End */ +#define SDEMMC_W_PRV_SDHI_INFO1_ACCESS_END (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_TransferComplete_Msk) + +/* Card Removed */ +#define SDEMMC_W_PRV_SDHI_INFO1_CARD_REMOVED (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_CardRemoval_Msk) + +/* Card Inserted */ +#define SDEMMC_W_PRV_SDHI_INFO1_CARD_INSERTED (SDEMMC_SDEMMC_NORMAL_ITNR_STATUS_REG_CardInsertion_Msk) + +#define SDEMMC_W_PRV_SDHI_INFO1_ACCESS_MASK ((SDEMMC_W_PRV_SDHI_INFO1_RESPONSE_END | \ + SDEMMC_W_PRV_SDHI_INFO1_ACCESS_END)) +#define SDEMMC_W_PRV_SDHI_INFO1_CARD_MASK ((SDEMMC_W_PRV_SDHI_INFO1_CARD_REMOVED | \ + SDEMMC_W_PRV_SDHI_INFO1_CARD_INSERTED)) + +/* The relationship of the SD Clock Control Register SDCLKFrequencySelect to the division of the source PERI_CLK + * div 0 -> 40Mhz == 40Mhz + * div 1 -> 40Mhz / (1 * 2) == 20Mhz + * div 2 -> 40Mhz / (2 * 2) == 10Mhz + * div 4 -> 40Mhz / (4 * 2) == 5Mhz + * div 8 -> 40Mhz / (8 * 2) == 2.5Mhz + * div 16 -> 40Mhz / (16 * 2) == 1.25Mhz + * div 32 -> 40Mhz / (32 * 2) == 625k + * div 64 -> 40Mhz / (64 * 2) == 312.5k + * div 128 -> 40Mhz / (128 * 2) == 156.25k + * div 256 -> 40Mhz / (256 * 2) == 78.125k + * Other settings are prohibited. + */ +#define SDEMMC_W_PRV_CLK_CTRL_DIV_INVALID (0xFFU) + +/* Delay up to 10 ms before timing out waiting for response or response timeout flag. */ +#define SDEMMC_W_PRV_RESPONSE_TIMEOUT_US (10000U) + +/* Delay up to 5 seconds before timing out waiting for busy after updating bus width or high speed status for eMMC. */ +#define SDEMMC_W_PRV_BUSY_TIMEOUT_US (5000000U) + +/* Delay up to 500 ms before timing out waiting for data or data timeout flag. */ +#define SDEMMC_W_PRV_DATA_TIMEOUT_US (500000U) + +/* Delay up to 100 ms before timing out waiting for access end flag after receiving data during initialization. */ +#define SDEMMC_W_PRV_ACCESS_TIMEOUT_US (100000U) + +/* 400 kHz maximum clock required for initialization. */ +#define SDEMMC_W_PRV_INIT_MAX_CLOCK_RATE_HZ (400000U) +#define SDEMMC_W_PRV_BITS_PER_COMMAD (48U) +#define SDEMMC_W_PRV_BITS_PER_RESPONSE (48U) +#define SDEMMC_W_PRV_CLOCKS_BETWEEN_COMMANDS (8U) +#define SDEMMC_W_PRV_MIN_CYCLES_PER_COMMAND_RESPONSE \ + ((SDEMMC_W_PRV_BITS_PER_COMMAD + \ + SDEMMC_W_PRV_BITS_PER_RESPONSE) + \ + SDEMMC_W_PRV_CLOCKS_BETWEEN_COMMANDS) +#define SDEMMC_W_PRV_INIT_ONE_SECOND_TIMEOUT_ITERATIONS \ + (SDEMMC_W_PRV_INIT_MAX_CLOCK_RATE_HZ / \ + SDEMMC_W_PRV_MIN_CYCLES_PER_COMMAND_RESPONSE) + +/* CCCR function address */ +#define SDEMMC_W_SDIO_CCCR_CCCR (0x00) +#define SDEMMC_W_SDIO_CCCR_IOEX (0x02) +#define SDEMMC_W_SDIO_CCCR_IORX (0x03) +#define SDEMMC_W_SDIO_CCCR_IOASX_RESET (0x06) +#define SDEMMC_W_SDIO_CCCR_BUS_INTERFACE_CONTROL (0x07) +#define SDEMMC_W_SDIO_CCCR_BUS_WIDTH_MASK (0x03) +#define SDEMMC_W_SDIO_CCCR_BUS_WIDTH_BIT_4BIT (1U << 1) /* Enable 4bit bit of SDIO bus interface control register */ +#define SDEMMC_W_SDIO_CCCR_CAPS (0x08) +#define SDEMMC_W_SDIO_CCCR_POWER (0x12) +#define SDEMMC_W_SDIO_CCCR_SPEED (0x13) +#define SDEMMC_W_PRV_SDIO_REG_HIGH_SPEED (0x13U) /* SDIO High Speed register address */ +#define SDEMMC_W_PRV_SDIO_REG_HIGH_SPEED_BIT_EHS (1U << 1) /* Enable high speed bit of SDIO high speed register */ +#define SDEMMC_W_PRV_SDIO_REG_HIGH_SPEED_BIT_SHS (1U << 0) /* Support high speed bit of SDIO high speed register */ +#define SDEMMC_W_PRV_CSD_REG_CCC_CLASS_10_BIT (1U << 10) /* CCC_CLASS bit is set if the card supports high speed */ + +/* SDIO maximum bytes allows in writeIoExt() and readIoExt(). */ +#define SDEMMC_W_PRV_SDIO_EXT_MAX_BYTES (512U) + +/* SDIO maximum blocks allows in writeIoExt() and readIoExt(). */ +#define SDEMMC_W_PRV_SDIO_EXT_MAX_BLOCKS (511U) + +/* Masks for CMD53 argument. */ +#define SDEMMC_W_PRV_SDIO_CMD52_CMD53_COUNT_MASK (0x1FFU) +#define SDEMMC_W_PRV_SDIO_CMD52_CMD53_FUNCTION_MASK (0x7U) +#define SDEMMC_W_PRV_SDIO_CMD52_CMD53_ADDRESS_MASK (0x1FFFFU) + +/* Device bus width is 1, 4 or 8 bits wide. */ +#define SDEMMC_W_SDEMMC_DT_WIDTH_1BIT (0) +#define SDEMMC_W_SDEMMC_DT_WIDTH_4BIT (1) +#define SDEMMC_W_SDEMMC_DT_WIDTH_8BIT (2) + +#define SDEMMC_W_PRV_SDIO_INFO1_IRQ_CLEAR (0x00000000U) +#define SDEMMC_W_PRV_SDIO_INFO1_FN0_INT_TO_ARM_MASK (0x00000001U) +#define SDEMMC_W_PRV_SDIO_INFO1_FN1_INT_TO_ARM_MASK (0x00000002U) +#define SDEMMC_W_PRV_SDIO_INFO1_VALUE_GLB_INT_ENA (0x3U) +#define SDEMMC_W_ATTRIBUTE (0x23) +#define SDEMMC_W_ATTRIBUTE_DUMMY_DESC (0x21) +#define SDEMMC_W_ATTRIBUTE_TRANS_ERROR (0x02) +#define SDEMMC_W_BLKSIZE_MASK (0xFFF) +#define SDEMMC_W_B_BLK_CNT_MASK (0x1FF) +#define SDEMMC_W_1BIT_MASK (0x01) +#define SDEMMC_W_2BIT_MASK (0x03) +#define SDEMMC_W_12BIT_MASK (0xFFF) +#define SDEMMC_W_MUL_BLK_SHIFT (12) +#define SDEMMC_W_FN_NO_SHIFT (28) +#define SDEMMC_W_VALUE_IO_ACC_MODE (0x7F) +#define SDEMMC_W_AHBSOFT_RST (0x1) +#define SDEMMC_W_VOLT_SWITCH_CMD (0x2) +#define SDEMMC_W_CARD_VOLT_ACCEPT (0x4) +#define SDEMMC_W_SD_CLK_LINE_SWCH (0x8) +#define SDEMMC_W_SD_CMD_LINE_SWCH (0x10) +#define SDEMMC_W_VALUE_SOFT_RST_AHB (0x1) + +/* interrupt field */ +#define SDEMMC_W_FN1_WR_OVR (0x1) +#define SDEMMC_W_FN1_RD_OVR (0x2) +#define SDEMMC_W_FN1_RD_ERROR (0x4) +#define SDEMMC_W_FN1_RST (0x8) +#define SDEMMC_W_FN1_MSG_RDY (0x10) +#define SDEMMC_W_FN1_ACK_TO_ARM (0x20) +#define SDEMMC_W_FN1_SDIO_RD_STRT (0x40) +#define SDEMMC_W_FN1_SDIO_WR_STRT (0x80) +#define SDEMMC_W_FN1_ADMA_END (0x100) +#define SDEMMC_W_FN1_SUSPEND (0x200) +#define SDEMMC_W_FN1_RESUME (0x400) +#define SDEMMC_W_FN1_ADMA_INT (0x800) +#define SDEMMC_W_FN1_ADMA_ERR (0x1000) +#define SDEMMC_W_FN1_READY (0x2000) +#define SDEMMC_W_PRV_BYTES_PER_KILOBYTE (1024) +#define SDEMMC_W_PRV_SECTOR_COUNT_IN_EXT_CSD (0xFFFU) +#define SDEMMC_W_PRV_SD_CLK_CTRL_DEFAULT (200U) + +#define SDEMMC_W_PRV_ACCESS_BIT (2U) +#define SDEMMC_W_PRV_RESPONSE_BIT (0U) + +#define SDEMMC_W_PRV_CIS_NAME "CIS" +#define SDEMMC_W_PRV_CISTPL_FUNC_NAME "CISTPL_FUNCE" + +#define SDEMMC_W_CIS0_AHB_ADDR (0x200afc00) /* Physical fixed address of CIS0 */ +#define SDEMMC_W_CIS1_AHB_ADDR (0x200afd00) /* physical fixed address of CIS1 */ + +#define SDEMMC_W_CCCR_REV (0x2) +#define SDEMMC_W_SDIO_REV (0x3) +#define SDEMMC_W_SD_PHY_SPEC (0x2) +#define SDEMMC_W_SCSI (0x1) +#define SDEMMC_W_SDC (0x1) +#define SDEMMC_W_SMB (0x1) +#define SDEMMC_W_SRW (0x1) +#define SDEMMC_W_SBS (0x1) +#define SDEMMC_W_S4MI (0x1) +#define SDEMMC_W_LSC (0x0) +#define SDEMMC_W_BLS (0x0) +#define SDEMMC_W_SMPC (0x1) +#define SDEMMC_W_SHS (0x1) + +#define SDEMMC_W_VALUE_OCR (0xFF8000) +#define SDEMMC_W_VALUE_GLB_INT_ENA (0x3) +#define SDEMMC_W_VALUE_AHB_FN0_INT_ENA (0xF) +#define SDEMMC_W_VALUE_AHB_FN1_INT_ENA (0x3fff) /* 0x3FFF 0x2000 func 1 enable interrupt */ +#define SDEMMC_W_VALUE_FBR (0x2017) +#define SDEMMC_W_VALUE_IOR (0x1) +#define SDEMMC_W_VALUE_FUNRDY (0x1) +#define SDEMMC_W_VALUE_INT_COND (0x3) + +#define SDEMMC_W_FN1_RD_DAT_RDY (0x1) + +#define SDEMMC_W_SDIO_FBR_BLKSZ (0x10) + +#define SDEMMC_W_DUMMY_DESC_LEN (0x4) + +#define SDEMMC_W_R5_OUT_OF_RANGE (1 << 8) +#define SDEMMC_W_R5_FUNC_NO (1 << 9) +#define SDEMMC_W_R5_ERROR (1 << 11) + +#define SDEMMC_W_SDIO_NO_RESPONSE (0) +#define SDEMMC_W_SDIO_R3_RESPONSE (2) +#define SDEMMC_W_SDIO_SHORT_RESPONSE (2) /* (48bits) */ +#define SDEMMC_W_SDIO_LONG_RESPONSE (1) /* (136bits) */ +#define SDEMMC_W_GET_CMD_RESP_TYPE(x) ((SDEMMC_W_PRV_CMD_ALL_SEND_CID == x) ? SDEMMC_W_SDIO_LONG_RESPONSE : \ + (SDEMMC_W_PRV_CMD_SEND_CSD == x) ? SDEMMC_W_SDIO_LONG_RESPONSE : \ + (SDEMMC_W_PRV_CMD_SEND_CID == x) ? SDEMMC_W_SDIO_LONG_RESPONSE : \ + (SDEMMC_W_PRV_CMD_SD_SEND_OP_COND == x) ? SDEMMC_W_SDIO_R3_RESPONSE : \ + (SDEMMC_W_PRV_CMD_IF_COND == x) ? SDEMMC_W_SDIO_SHORT_RESPONSE : \ + (SDEMMC_W_PRV_CMD_APP_CMD == x) ? SDEMMC_W_SDIO_SHORT_RESPONSE : \ + SDEMMC_W_SDIO_SHORT_RESPONSE) + +#ifndef SDEMMC_W_NTOH32 + #define SDEMMC_W_NTOH32(x) (((x & 0xff000000) >> 24) | ((x & 0x00ff0000) >> 8) | \ + ((x & 0x0000ff00) << 8) | ((x & 0x000000ff) << 24)) +#endif + +/*********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ + +#if (CFG_PMGR == 1) && (SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE == 1) + +/* SDEMMC sleep context required by PMGR */ + +typedef struct st_sdemmc_pmgr_state +{ + uint32_t SDIO_CCCR_REG; + uint32_t SDIO_OCR_REG; + uint32_t SDIO_GLB_INT_ENA_REG; + uint32_t SDIO_AHB_FN0_INT_ENABLE_REG; + uint32_t SDIO_AHB_FN0_INT_REG; + uint32_t SDIO_AHB_FN1_INT_ENABLE_REG; + uint32_t SDIO_AHB_FN1_INT_REG; + uint32_t SDIO_FBR_REG; + uint32_t SDIO_IOR_REG; + uint32_t SDIO_GLB_INT_STS_REG; + uint32_t SDIO_FUNRDY_REG; + uint32_t GPIO_SDIO_MODE_REG; +} sdemmc_w_pmgr_state_t; + +typedef struct st_sdemmc_w_pmgr_context +{ + pmgr_instance_info_t pmgr_info; + pmgr_callback_args_t clbk_args; + pmgr_w_notifier_extend_t pmgr_notifier_ext; + sdemmc_w_instance_ctrl_t * p_ctrl; + sdemmc_w_pmgr_state_t state; +} sdemmc_w_pmgr_context_t; +#endif + +/*********************************************************************************************************************** + * Private function prototypes + **********************************************************************************************************************/ +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE +static fsp_err_t r_sdemmc_open_param_check(sdemmc_w_instance_ctrl_t * p_ctrl, sdmmc_cfg_t const * const p_cfg); + +#endif +static fsp_err_t r_sdemmc_erase_error_check(sdemmc_w_instance_ctrl_t * const p_ctrl, + uint32_t const start_sector, + uint32_t const sector_count); + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE +static fsp_err_t r_sdemmc_csd_save(sdemmc_w_instance_ctrl_t * const p_ctrl, + uint32_t rca, + sdmmc_priv_csd_reg_t * const p_csd_reg, + uint32_t send_flag); +static void r_sdemmc_write_protect_get(sdemmc_w_instance_ctrl_t * const p_ctrl); +static fsp_err_t r_sdemmc_command_send(sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t command, uint32_t argument); +static fsp_err_t r_sdemmc_wait_for_event(sdemmc_w_instance_ctrl_t * const p_ctrl, uint32_t bit, uint32_t timeout); +static fsp_err_t r_sdemmc_wait_for_device(sdemmc_w_instance_ctrl_t * const p_ctrl); +static void r_sdemmc_command_send_no_wait(sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t command, uint32_t argument); + +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +static fsp_err_t r_sdemmc_common_error_check(sdemmc_w_instance_ctrl_t * const p_ctrl); + +static void r_sdemmc_irq_enable(IRQn_Type irq, uint8_t priority, void * p_context); +static void r_sdemmc_irq_disable(IRQn_Type irq); + +static void r_sdemmc_access_irq_process(sdemmc_w_instance_ctrl_t * p_ctrl, sdmmc_callback_args_t * p_args); + +static void r_sdemmc_call_callback(sdemmc_w_instance_ctrl_t * p_ctrl, sdmmc_callback_args_t * p_args); + +void sdhimmc_accs_isr(void); + +void sdhimmc_sdio_isr(void); + +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE +static void r_sdemmc_handle_interrupt_fn0(sdemmc_w_instance_ctrl_t * p_ctrl); + +static void r_sdemmc_handle_interrupt_fn1(sdemmc_w_instance_ctrl_t * p_ctrl, sdmmc_callback_args_t * p_args); + +static void r_sdemmc_adma_dummy(sdemmc_w_instance_ctrl_t * p_ctrl); + +static void r_sdemmc_host_read(sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t length); + +static void r_sdemmc_host_write(sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t length); + +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + +static void r_sdemmc_hw_sdemmc_renable_prepare(sdemmc_w_instance_ctrl_t * p_ctrl); +static void r_sdemmc_hw_sdemmc_renable(sdemmc_w_instance_ctrl_t * p_ctrl); + +static void r_sdemmc_hw_sdemmc_enable(sdemmc_w_instance_ctrl_t * p_ctrl); + +static void r_sdemmc_hw_sdemmc_disable(sdemmc_w_instance_ctrl_t * p_ctrl); + +static void r_sdemmc_sdemmc_interrupt_enable(sdemmc_w_instance_ctrl_t * p_ctrl); + +static fsp_err_t r_sdemmc_sdemmc_wait_for_complete_interrupt(sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t * resp); + +static fsp_err_t r_sdemmc_emmc_cmd_with_res(sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp); + +static fsp_err_t r_sdemmc_sdemmc_wait_for_transfer_interrupt(sdemmc_w_instance_ctrl_t * p_ctrl); +static fsp_err_t r_sdemmc_sdemmc_wait_write_done(sdemmc_w_instance_ctrl_t * p_ctrl); + +#if (SDEMMC_W_CFG_SD_SUPPORT_ENABLE | SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) +static void r_sdemmc_emmc_cmd_without_res(sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t cmd, uint32_t cmd_arg); +static fsp_err_t r_sdemmc_emmc_single_read_data_with_wait(sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t blk_size, + uint32_t * p_rsp, + uint8_t * p_buf); +static fsp_err_t r_sdemmc_emmc_single_read_data(sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t blk_size, + uint32_t * p_rsp, + uint8_t * p_buf); +static fsp_err_t r_sdemmc_emmc_multi_read_data(sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp, + uint8_t * p_buf, + uint32_t block_count); +static fsp_err_t r_sdemmc_emmc_block_read_data(sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp, + uint8_t * p_buf, + uint32_t block_count); +static fsp_err_t r_sdemmc_emmc_single_write_data(sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t blk_size, + uint32_t * p_rsp, + uint8_t * p_buf); +static fsp_err_t r_sdemmc_emmc_multi_write_data(sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp, + uint8_t * p_buf, + uint32_t block_count); +static fsp_err_t r_sdemmc_emmc_block_write_data(sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp, + uint8_t * p_buf, + uint32_t block_count); + +#endif /* (SDEMMC_W_CFG_SD_SUPPORT_ENABLE | SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) */ + +static inline uint32_t BITS_FOR_UNSTUFF(uint32_t * p_resp, uint32_t start, uint32_t size); + +static fsp_err_t r_sdemmc_sdio_init_card(sdemmc_w_instance_ctrl_t * p_ctrl, st_sdemmc_config_t * p_config, + uint32_t ocr); +static fsp_err_t r_sdemmc_sd_init_card(sdemmc_w_instance_ctrl_t * p_ctrl, st_sdemmc_config_t * p_config, uint32_t ocr); +static fsp_err_t r_sdemmc_emmc_init_card(sdemmc_w_instance_ctrl_t * p_ctrl, st_sdemmc_config_t * p_config, + uint32_t ocr); + +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE +static fsp_err_t r_sdemmc_sdio_block_read_data(sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp, + uint8_t * p_buf, + uint32_t block_size, + uint32_t block_count); +static fsp_err_t r_sdemmc_sdio_multi_write_data(sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp, + uint8_t * p_buf, + uint32_t block_size, + uint32_t block_count); +static fsp_err_t r_sdemmc_sdio_io_rw_direct(sdemmc_w_instance_ctrl_t * p_ctrl, + uint8_t write, + uint8_t fn, + uint32_t addr, + uint8_t in, + uint8_t * p_value); +static fsp_err_t r_sdemmc_sdio_io_rw_extended(sdemmc_w_instance_ctrl_t * p_ctrl, + uint8_t write, + uint8_t fn, + uint32_t addr, + uint32_t incr_addr, + uint8_t * p_buf, + uint32_t block_count, + uint32_t blksz); +static void r_sdemmc_hw_sdio_device_init(sdemmc_w_instance_ctrl_t * p_ctrl); +static uint32_t r_sdemmc_hw_sdio_device_rx(sdemmc_w_instance_ctrl_t * p_ctrl, uint8_t * p_data, uint32_t length); +static uint32_t r_sdemmc_hw_sdio_device_tx(sdemmc_w_instance_ctrl_t * p_ctrl, const uint8_t * p_data, uint32_t length); +static void r_sdemmc_hw_sdio_device_deinit(sdemmc_w_instance_ctrl_t * p_ctrl); +static fsp_err_t r_sdemmc_common_fne_for_cistpl(st_sdemmc_config_t * p_config, uint8_t * p_buf, uint32_t size); +static fsp_err_t r_sdemmc_fn_fne_for_cistpl(st_sdemmc_config_t * p_config, uint8_t * p_buf, uint32_t size); +static fsp_err_t r_sdemmc_version_1_for_cistpl(st_sdemmc_config_t * p_config, uint8_t * p_buf, uint32_t size); +static fsp_err_t r_sdemmc_man_fid_for_cistpl(st_sdemmc_config_t * p_config, uint8_t * p_buf, uint32_t size); +static fsp_err_t r_sdemmc_local_cistpl_fn(st_sdemmc_config_t * p_config, uint8_t * p_buffer, uint32_t sz); +static fsp_err_t r_sdemmc_sdio_cis_tpl_parse(st_sdemmc_config_t * p_config, + uint8_t * p_data, + uint8_t tpl_code, + uint8_t tpl_link); +static fsp_err_t r_sdemmc_parse_for_cis_tuple(st_sdemmc_config_t * p_config, + uint8_t * p_tpl_descr, + const struct tuples_for_cis * p_tpl, + int32_t tpl_count, + uint8_t code, + uint8_t * p_buf, + uint32_t size); +static fsp_err_t r_sdemmc_hw_sdemmc_sdio_func_enable(sdemmc_w_instance_ctrl_t * p_ctrl, + st_sdemmc_config_t * p_config, + uint32_t func_num); +static fsp_err_t r_sdemmc_hw_sdemmc_sdio_set_block_size(sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t func_num, + uint32_t blk_size); + +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE +static fsp_err_t r_sdemmc_mmc_decode_scr(st_sdemmc_config_t * p_config); +static fsp_err_t r_sdemmc_sd_decode_csd(sdemmc_w_instance_ctrl_t * const p_ctrl, st_sdemmc_config_t * p_config); +static fsp_err_t r_sdemmc_sd_decode_cid(st_sdemmc_config_t * p_config); +static fsp_err_t r_sdemmc_mmd_decode_ssr(st_sdemmc_config_t * p_config); +static uint32_t r_sdemmc_sd_make_switch_arg(int32_t mode, int32_t group, int32_t value); + +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE +static fsp_err_t r_sdemmc_emmc_wait_ready(sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t * p_rocr); +static fsp_err_t r_sdemmc_emmc_decode_csd(sdemmc_w_instance_ctrl_t * const p_ctrl, st_sdemmc_config_t * p_config); +static fsp_err_t r_sdemmc_emmc_decode_ext_csd(sdemmc_w_instance_ctrl_t * p_ctrl, st_sdemmc_config_t * p_config); +static fsp_err_t r_sdemmc_emmc_decode_cid(st_sdemmc_config_t * p_config); +static uint32_t r_sdemmc_emmc_make_switch_arg(uint8_t set, uint8_t index, uint8_t value); +static fsp_err_t r_sdemmc_emmc_send_op_cond(sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t ocr, uint32_t * p_rocr); + +#endif /* SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +#if (CFG_PMGR == 1) && (SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE == 1) +static fsp_err_t r_sdemmc_w_enter_sleep(sdemmc_w_pmgr_context_t * p_context); +static fsp_err_t r_sdemmc_w_wakeup(sdemmc_w_pmgr_context_t * p_context); +static void r_sdemmc_w_pmgr_callback(pmgr_callback_args_t * args); +static fsp_err_t r_sdemmc_w_subscribe_for_pmgr_notifications(sdemmc_w_instance_ctrl_t * const p_ctrl); +static fsp_err_t r_sdemmc_w_unsubscribe_from_pmgr_notifications(sdemmc_w_instance_ctrl_t * const p_ctrl); + +#endif + +/*********************************************************************************************************************** + * Private global variables + **********************************************************************************************************************/ +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE +static const st_tuples_for_cis_t gs_func_list_for_cis_tpl[] = +{ + {0, 4, r_sdemmc_common_fne_for_cistpl}, + {1, 0, r_sdemmc_fn_fne_for_cistpl }, + {4, 8, NULL }, +}; + +/* Known TPL_CODEs table for CIS tuples */ +static const st_tuples_for_cis_t gs_list_cis_tpl[] = +{ + {21, 3, r_sdemmc_version_1_for_cistpl}, + {32, 4, r_sdemmc_man_fid_for_cistpl }, + {33, 2, NULL }, + {34, 0, r_sdemmc_local_cistpl_fn }, +}; + +static const uint8_t gs_speed_val[16] = +{ + 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 +}; + +static const uint32_t gs_speed_unit[8] = +{ + 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 +}; + +/* Default value supplied by Renesas for CSI0 */ +static const uint8_t gs_sdio_b_cis0_data[] = +{ + 0x21, /* TPL_CODE_CISTPL_FUNCID */ + 0x02, /* Link to next tuple */ + 0x0C, /* Card function code */ + 0x00, /* Not used */ + 0x22, /* TPL_CODE_CISTPL_FUNCE */ + 0x04, /* Link to next tuple */ + 0x00, /* Extended data */ + 0x00, /* Only block size function 0 can support (2048 = 0x0800) was 0x08 */ + 0x08, /* Together with previous byte was 0x00 */ + 0x0A, /* Transfer rate (25 Mbit/sec) 0x32-> 50Mhz 0x0A -> 10Mhz 0x09 -> 1Mhz 0x48 -> 400k */ + 0x20, /* TPL_CODE_CISTPL_MANFID */ + 0x04, /* Link to next tuple */ + 0x45, /* SDIO manufacturer code 0x0296 */ + 0x52, /* Used with previous byte */ + 0x54, /* Part number/revision number OEM ID = 0x5347 */ + 0x41, /* Used with previous byte */ + 0xFF +}; /* End of tuple chain */ + +/* Default value supplied by Arasan for CSI1 */ +static const uint8_t gs_sdio_b_cis1_data[] = +{ + 0x21, /* TPL_CODE_CISTPL_FUNCID */ + 0x02, /* Link to next tuple */ + 0x0C, /* Card function type */ + 0x00, /* Not used */ + 0x22, /* TPL_CODE_CISTPL_FUNCE */ + 0x2A, /* Link to next tuple was 0x1c it should be 42byte */ + 0x01, /* Type of extended data */ + 0x01, /* Wakeup support */ + 0x11, /* X.Y revision was 0x00 */ + 0x00, /* No serial number */ + 0x00, /* No serial number */ + 0x00, /* No serial number */ + 0x00, /* No serial number */ + 0x00, /* Size of the CSA space available for this function in bytes (0) */ + 0x00, /* Used with previous */ + 0x02, /* Used with previous was 0x00 */ + 0x00, /* Used with previous */ + 0x03, /* CSA property: Bit 0 - 0 implies R/W capability in CSA */ + + /* Bit 1 - 0 implies the Host may reformat the file system */ + 0x00, /* Maximum block size (256 bytes) was 0x80 */ + 0x08, /* Used with previous was 0x00 */ + 0x00, /* OCR value of the function was 0x08 */ + 0x08, /* Used with previous was 0x01 */ + 0xFF, /* Used with previous was 0xff */ + 0x00, /* Used with previous */ + 0x08, /* Minimum power required by this function (8 mA) */ + + 0x0a, /* ADDED=>Average power required by this function when operating(10 mA) */ + 0x0f, /* ADDED=>Maximum power required by this function when operating(15 mA) */ + + 0x01, /* Stand by is not supported was 0x00 */ + 0x01, /* Used with previous was 0x00 */ + 0x01, /* Used with previous was 0x00 */ + + 0x00, /* Minimum BW */ + 0x00, /* Used with previous */ + 0x00, /* Optional BW */ + 0x00, /* Used with previous */ + + /* ADDED -> */ + 0x00, /* Card required no timeout */ + 0x00, + 0x00, + 0x00, + + 0x00, /* High power mode - average power */ + 0x00, /* High power function is not supported */ + 0x00, + 0x00, + + 0x00, /* High power mode - peak power */ + 0x00, /* High power function is not supported */ + 0x00, + 0x00, + + 0x00, + 0x00, + + 0x91, /* TPL_CODE_CISTPL_SDIO_STD */ + 0x03, /* TPL_LINK */ + 0x07, /* SDIO Standard I/O device type */ + 0x00, /* Format and type of data */ + + 0x00, + 0xFF +}; /* End of tuple */ + +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + +#if (SDEMMC_W_CFG_SD_SUPPORT_ENABLE | SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) +static const uint32_t gs_tran_exp[] = +{ + 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 +}; + +static const uint8_t gs_tran_mant[] = +{ + 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, +}; + +static const uint32_t gs_tacc_exp[] = +{ + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, +}; + +static const uint32_t gs_tacc_mant[] = +{ + 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, +}; +#endif /* (SDEMMC_W_CFG_SD_SUPPORT_ENABLE | SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) */ + +static st_sdemmc_config_t gs_body; +static uint32_t g_DataTransferWidth; +static uint32_t g_ExtendedDataTransferWidth; +static uint32_t g_SDCLKFrequencySelect; +static uint32_t g_DriveStrengthSelect; +static uint32_t g_BlockCountForCurrentTransfer; + +#if (CFG_PMGR == 1) && (SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE == 1) + #ifdef BSP_FEATURE_SDHI_VALID_CHANNEL_MASK + #define R_SDEMMC_W_MAX_CHANNELS __builtin_popcount(BSP_FEATURE_SDHI_VALID_CHANNEL_MASK) + #else + #define R_SDEMMC_W_MAX_CHANNELS (1) + #endif +static sdemmc_w_pmgr_context_t g_sdemmc_pmgr_context[R_SDEMMC_W_MAX_CHANNELS]; +#endif + +/*********************************************************************************************************************** + * Global Variables + **********************************************************************************************************************/ + +/** SDMMC function pointers */ +const sdmmc_api_t g_sdmmc_on_sdemmc_w = +{ + .open = R_SDEMMC_W_Open, + .mediaInit = R_SDEMMC_W_MediaInit, + .read = R_SDEMMC_W_Read, + .write = R_SDEMMC_W_Write, + .readIo = R_SDEMMC_W_ReadIo, + .writeIo = R_SDEMMC_W_WriteIo, + .readIoExt = R_SDEMMC_W_ReadIoExt, + .writeIoExt = R_SDEMMC_W_WriteIoExt, + .ioIntEnable = R_SDEMMC_W_IoIntEnable, + .statusGet = R_SDEMMC_W_StatusGet, + .erase = R_SDEMMC_W_Erase, + .callbackSet = R_SDEMMC_W_CallbackSet, + .close = R_SDEMMC_W_Close, +}; + +/*******************************************************************************************************************//** + * @addtogroup SDEMMC_W + * @{ + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Functions + **********************************************************************************************************************/ + +/*******************************************************************************************************************//** + * Opens the driver. Resets SDEMMC_W, and enables card detection interrupts if card detection is enabled. + * @ref R_SDEMMC_W_MediaInit must be called after this function before any other functions can be used. + * + * Implements @ref sdmmc_api_t::open(). + * + * Example: + * @snippet r_sdemmc_w_example.c R_SDEMMC_W_Open + * + * @retval FSP_SUCCESS Module is now open. + * @retval FSP_ERR_ASSERTION Null Pointer or block size is not in the valid range of 1-512. Block size + * must be 512 bytes for SD cards and eMMC devices. It is configurable for + * SDIO only. + * @retval FSP_ERR_ALREADY_OPEN Driver has already been opened with this instance of the control + * structure. + * @retval FSP_ERR_IRQ_BSP_DISABLED Access interrupt is not enabled. + * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT Requested channel does not exist on this MCU. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_Open (sdmmc_ctrl_t * const p_api_ctrl, sdmmc_cfg_t const * const p_cfg) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + fsp_err_t err = FSP_SUCCESS; + err = r_sdemmc_open_param_check(p_ctrl, p_cfg); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); +#endif + + /* Initialize control block. */ + memset(p_ctrl, 0, sizeof(*p_ctrl)); + p_ctrl->p_reg = SDIO; + p_ctrl->p_reg_mmc = SDEMMC; + p_ctrl->p_cfg = p_cfg; + +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + + /* SDIO Device only. */ + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + /* Set SDIO_MODE_REG */ + GPIO->SDIO_MODE_REG_b.SDIO_PAD_ENABLE = 1U; + GPIO->SDIO_MODE_REG_b.SDIO_PORT_SEL = + (uint32_t) (((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->device_port_sel) & 1; + + if (((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->device_pull_en_cfg == 0) + { + GPIO->SDIO_MODE_REG_b.SDIO_PULL_EN = 0U; + } + else + { + GPIO->SDIO_MODE_REG_b.SDIO_PULL_EN = 0x3EU; + } + + if (((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->device_pull_sel_cfg == 0) + { + GPIO->SDIO_MODE_REG_b.SDIO_PULL_SEL = 0U; + } + else + { + GPIO->SDIO_MODE_REG_b.SDIO_PULL_SEL = 0x3EU; + } + + /* Reset SDIO. */ + r_sdemmc_hw_sdio_device_init(p_ctrl); + } +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE || SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + + /* SD/MMC/SDIO Host only. */ + if (SDEMMC_W_ROLE_HOST == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + /* Set EMMC_MODE_REG */ + GPIO->EMMC_MODE_REG_b.EMMC_ENABLE = 1U; + GPIO->EMMC_MODE_REG_b.EMMC_PORT_SEL = + (uint32_t) (((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->host_port_sel) & 1; + GPIO->EMMC_MODE_REG_b.EMMC_CLKIN_SEL = + (uint32_t) (((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->host_rxclk_in_sel) & 1; + + if (p_ctrl->p_cfg->bus_width == SDMMC_BUS_WIDTH_8_BITS) + { + GPIO->EMMC_MODE_REG_b.EMMC_OCTA_MODE = 1U; + } + else + { + GPIO->EMMC_MODE_REG_b.EMMC_OCTA_MODE = 0U; + } + + if (((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->host_pull_en_cfg == 0) + { + GPIO->EMMC_MODE_REG_b.EMMC_PULL_EN = 0U; + } + else + { + if (p_ctrl->p_cfg->bus_width == SDMMC_BUS_WIDTH_8_BITS) + { + GPIO->EMMC_MODE_REG_b.EMMC_PULL_EN = 0x3FEU; + } + else + { + GPIO->EMMC_MODE_REG_b.EMMC_PULL_EN = 0x3EU; + } + } + + if (((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->host_pull_sel_cfg == 0) + { + GPIO->EMMC_MODE_REG_b.EMMC_PULL_SEL = 0U; + } + else + { + if (p_ctrl->p_cfg->bus_width == SDMMC_BUS_WIDTH_8_BITS) + { + GPIO->EMMC_MODE_REG_b.EMMC_PULL_SEL = 0x3FEU; + } + else + { + GPIO->EMMC_MODE_REG_b.EMMC_PULL_SEL = 0x3EU; + } + } + + /* Reset stale interrupt flags */ + r_sdemmc_hw_sdemmc_enable(p_ctrl); + r_sdemmc_sdemmc_interrupt_enable(p_ctrl); + } +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE || SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + + /* Set callback and context pointers, if configured */ + p_ctrl->p_callback = p_cfg->p_callback; + p_ctrl->p_context = p_cfg->p_context; + p_ctrl->p_callback_memory = NULL; + + /* Configure and enable interrupts. */ + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + r_sdemmc_irq_enable(p_cfg->sdio_irq, p_cfg->sdio_ipl, p_ctrl); + } + else + { + r_sdemmc_irq_enable(p_cfg->access_irq, p_cfg->access_ipl, p_ctrl); + } + +#if (CFG_PMGR == 1) && (SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE == 1) + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + r_sdemmc_w_subscribe_for_pmgr_notifications((sdemmc_w_instance_ctrl_t *) p_ctrl); + } +#endif + + p_ctrl->initialized = false; + p_ctrl->open = SDEMMC_W_PRV_OPEN; + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Initializes the SDEMMC_W hardware and completes identification and configuration for the SD or eMMC or SDIO device. + * This procedure requires several sequential commands. This function blocks until all identification and configuration + * commands are complete. + * + * Implements @ref sdmmc_api_t::mediaInit(). + * + * Example: + * @snippet r_sdemmc_w_example.c R_SDEMMC_W_MediaInit + * + * @retval FSP_SUCCESS Module is now ready for read/write access. + * @retval FSP_ERR_ASSERTION Null Pointer or block size is not in the valid range of 1-512. Block size must + * be 512 bytes for SD cards and eMMC devices. It is configurable for SDIO only. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + * @retval FSP_ERR_TIMEOUT Device did not respond. + * @retval FSP_ERR_INVALID_DATA Unrecognized structure version. + * @retval FSP_ERR_UNSUPPORTED Unsupported device. + * @retval FSP_ERR_INVALID_STATE Sending command retry failure. + * @retval FSP_ERR_OUT_OF_MEMORY There is no more memory available. + * @retval FSP_ERR_NOT_FOUND Card not exist. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_MediaInit (sdmmc_ctrl_t * const p_api_ctrl, sdmmc_device_t * const p_device) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + + fsp_err_t err = FSP_SUCCESS; +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + uint8_t reg = 0; +#endif +#if (SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) + uint32_t rsp = 0; +#endif + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(SDEMMC_W_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); +#endif + + /* Device is not initialized until this function completes. */ + p_ctrl->initialized = false; + p_ctrl->device.card_type = 0xFF; + + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + /* Return device information to user. */ + p_ctrl->device.sector_size_bytes = p_ctrl->p_cfg->block_size; + + if (NULL != p_device) + { + *p_device = p_ctrl->device; + } + + p_ctrl->initialized = true; + + return FSP_SUCCESS; + } + + err = r_sdemmc_sdio_init_card(p_ctrl, &gs_body, gs_body.ocr); + +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + if (!err) + { + /* the inserted card is sdio card */ + p_ctrl->device.card_type = SDMMC_CARD_TYPE_SDIO; + gs_body.card_type = SDMMC_PRIV_CT_SDIO_CARD; + + if (SDMMC_BUS_WIDTH_1_BIT == p_ctrl->p_cfg->bus_width) + { + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.DataTransferWidth = SDEMMC_W_SDEMMC_DT_WIDTH_1BIT; + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_READ, + 0, + SDEMMC_W_SDIO_CCCR_BUS_INTERFACE_CONTROL, + 0, + ®); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + reg = (uint8_t) (reg & ~SDEMMC_W_SDIO_CCCR_BUS_WIDTH_MASK); + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_WRITE, + 0, + SDEMMC_W_SDIO_CCCR_BUS_INTERFACE_CONTROL, + reg, + NULL); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + } + else + { + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.DataTransferWidth = SDEMMC_W_SDEMMC_DT_WIDTH_4BIT; + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_READ, + 0, + SDEMMC_W_SDIO_CCCR_BUS_INTERFACE_CONTROL, + 0, + ®); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + reg = + (uint8_t) ((uint8_t) (reg & ~SDEMMC_W_SDIO_CCCR_BUS_WIDTH_MASK) | + SDEMMC_W_SDIO_CCCR_BUS_WIDTH_BIT_4BIT); + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_WRITE, + 0, + SDEMMC_W_SDIO_CCCR_BUS_INTERFACE_CONTROL, + reg, + NULL); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + } + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + err = r_sdemmc_hw_sdemmc_sdio_func_enable(p_ctrl, &gs_body, 1); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + /* Return device information to user. */ + p_ctrl->device.sector_size_bytes = p_ctrl->p_cfg->block_size; + + if (NULL != p_device) + { + *p_device = p_ctrl->device; + } + + /* Check block size, 512 bytes is the maximum block size the peripheral supports */ + FSP_ASSERT(0U != p_ctrl->p_cfg->block_size); + FSP_ASSERT(p_ctrl->p_cfg->block_size <= SDEMMC_W_MAX_BLOCK_SIZE); + err = r_sdemmc_hw_sdemmc_sdio_set_block_size(p_ctrl, 1, p_ctrl->p_cfg->block_size); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDCLKFrequencySelect = + ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->clk_div; + p_ctrl->initialized = true; + + return FSP_SUCCESS; + } +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + + err = r_sdemmc_sd_init_card(p_ctrl, &gs_body, gs_body.ocr); + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE + if (!err) + { + /* the inserted card is sd card */ + p_ctrl->device.card_type = SDMMC_CARD_TYPE_SD; + + if (SDMMC_BUS_WIDTH_1_BIT == p_ctrl->p_cfg->bus_width) + { + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.DataTransferWidth = SDEMMC_W_SDEMMC_DT_WIDTH_1BIT; + } + else + { + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.DataTransferWidth = SDEMMC_W_SDEMMC_DT_WIDTH_4BIT; + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_APP_CMD, ((gs_body.rca << 16) | 0xffff), &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SET_BUS_WIDTH, SDEMMC_W_PRV_SD_BUS_WIDTH_4, &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + } + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + + /* Check to see if the card is write protected. */ + r_sdemmc_write_protect_get(p_ctrl); + + /* Return device information to user. */ + p_ctrl->device.sector_size_bytes = p_ctrl->p_cfg->block_size; + + if (NULL != p_device) + { + *p_device = p_ctrl->device; + } + + /* SD and eMMC cards only support block size of 512 bytes on the SDEMMC_W hardware. */ + /* This can't be checked until we know it's not an SDIO card if SDIO is enabled. */ + FSP_ASSERT(SDEMMC_W_MAX_BLOCK_SIZE == p_ctrl->p_cfg->block_size); + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDCLKFrequencySelect = + ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->clk_div; + p_ctrl->initialized = true; + + return FSP_SUCCESS; + } +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE */ + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + + err = r_sdemmc_emmc_init_card(p_ctrl, &gs_body, gs_body.ocr); + +#if SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + if (!err) + { + /* the inserted card is emmc card */ + gs_body.card_type = SDMMC_PRIV_CT_MMC_CARD; + p_ctrl->device.card_type = SDMMC_CARD_TYPE_MMC; + + if (SDMMC_BUS_WIDTH_1_BIT == p_ctrl->p_cfg->bus_width) + { + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.DataTransferWidth = SDEMMC_W_SDEMMC_DT_WIDTH_1BIT; + } + else if ((SDMMC_BUS_WIDTH_8_BITS == p_ctrl->p_cfg->bus_width) && + (1 == p_ctrl->p_reg_mmc->SDEMMC_CAPABILITIES0_REG_b.SupportforEmbeddedDevice8bit)) + { + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.ExtendedDataTransferWidth = 1; + err = + r_sdemmc_emmc_cmd_with_res(p_ctrl, + SDEMMC_W_PRV_CMD_SWITCH, + r_sdemmc_emmc_make_switch_arg(SDEMMC_W_PRV_E_CSD_CMD_SET_NORMAL, + SDEMMC_W_PRV_E_CSD_BUS_WIDTH, + SDEMMC_W_SDEMMC_DT_WIDTH_8BIT), + &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + } + else + { + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.DataTransferWidth = SDEMMC_W_SDEMMC_DT_WIDTH_4BIT; + err = + r_sdemmc_emmc_cmd_with_res(p_ctrl, + SDEMMC_W_PRV_CMD_SWITCH, + r_sdemmc_emmc_make_switch_arg(SDEMMC_W_PRV_E_CSD_CMD_SET_NORMAL, + SDEMMC_W_PRV_E_CSD_BUS_WIDTH, + SDEMMC_W_SDEMMC_DT_WIDTH_4BIT), + &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + } + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + + /* Check to see if the card is write protected. */ + r_sdemmc_write_protect_get(p_ctrl); + + /* Return device information to user. */ + p_ctrl->device.sector_size_bytes = p_ctrl->p_cfg->block_size; + + if (NULL != p_device) + { + *p_device = p_ctrl->device; + } + + /* SD and eMMC cards only support block size of 512 bytes on the SDEMMC_W hardware. */ + /* This can't be checked until we know it's not an SDIO card if SDIO is enabled. */ + FSP_ASSERT(SDEMMC_W_MAX_BLOCK_SIZE == p_ctrl->p_cfg->block_size); + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDCLKFrequencySelect = + ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->clk_div; + p_ctrl->initialized = true; + + return FSP_SUCCESS; + } +#endif /* SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + + FSP_ERROR_RETURN(FSP_ERR_UNSUPPORTED != err, FSP_ERR_UNSUPPORTED); + + FSP_RETURN(FSP_ERR_NOT_FOUND); +} + +/*******************************************************************************************************************//** + * Reads data from an SD or eMMC device. Up to 0x10000 sectors can be read at a time. + * Implements @ref sdmmc_api_t::read(). + * + * A callback with the event SDMMC_EVENT_TRANSFER_COMPLETE is called when the read data is available. + * + * Example: + * @snippet r_sdemmc_w_example.c R_SDEMMC_W_Read + * + * @retval FSP_SUCCESS Data read successfully. + * @retval FSP_ERR_ASSERTION NULL pointer. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged. + * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation. + * @retval FSP_ERR_UNSUPPORTED SD and eMMC support disabled in SDEMMC_W_CFG_SD_SUPPORT_ENABLE and + * SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE. + * @retval FSP_ERR_TIMEOUT Device did not respond. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_Read (sdmmc_ctrl_t * const p_api_ctrl, + uint8_t * const p_dest, + uint32_t const start_sector, + uint32_t const sector_count) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + + fsp_err_t err = FSP_SUCCESS; + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_dest); + FSP_ASSERT(sector_count <= (UINT16_MAX + 1)); +#endif + err = r_sdemmc_common_error_check(p_ctrl); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + +#if (SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) + uint32_t rsp = 0; + uint32_t argument = start_sector; + + if (!p_ctrl->sector_addressing) + { + /* Standard capacity SD cards and some eMMC devices use byte addressing. */ + argument *= p_ctrl->p_cfg->block_size; + } + + if (sector_count > 1) + { + if (SDMMC_CARD_TYPE_MMC != p_ctrl->device.card_type) + { + if (gs_body.scr.sd_cmds & SDEMMC_W_PRV_SCR_CMD23_SUPPORT) /* closed */ + { + /* read multi block */ + err = + r_sdemmc_emmc_block_read_data(p_ctrl, SDEMMC_W_PRV_CMD_READ_MULTIPLE_BLOCK, argument, &rsp, + (uint8_t *) p_dest, sector_count); + } + else + { + /* read open mode */ + err = + r_sdemmc_emmc_multi_read_data(p_ctrl, SDEMMC_W_PRV_CMD_READ_MULTIPLE_BLOCK, argument, &rsp, + (uint8_t *) p_dest, sector_count); + } + } + else + { + /* read multi block */ + err = r_sdemmc_emmc_block_read_data(p_ctrl, + SDEMMC_W_PRV_CMD_READ_MULTIPLE_BLOCK, + argument, + &rsp, + (uint8_t *) p_dest, + sector_count); + } + } + else + { + /* read single block */ + err = r_sdemmc_emmc_single_read_data(p_ctrl, + SDEMMC_W_PRV_CMD_READ_SINGLE_BLOCK, + argument, + 512, + &rsp, + (uint8_t *) p_dest); + } + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +#else /* (SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) */ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(p_dest); + FSP_PARAMETER_NOT_USED(start_sector); + FSP_PARAMETER_NOT_USED(sector_count); + + FSP_RETURN(FSP_ERR_UNSUPPORTED); +#endif /* (SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) */ +} + +/*******************************************************************************************************************//** + * Writes data to an SD or eMMC device. Up to 0x10000 sectors can be written at a time. + * Implements @ref sdmmc_api_t::write(). + * + * A callback with the event SDMMC_EVENT_TRANSFER_COMPLETE is called when the all data has been written and the device + * is no longer holding DAT0 low to indicate it is busy. + * + * Example: + * @snippet r_sdemmc_w_example.c R_SDEMMC_W_Write + * + * @retval FSP_SUCCESS Card write finished successfully. + * @retval FSP_ERR_ASSERTION Handle or Source address is NULL. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged. + * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation. + * @retval FSP_ERR_CARD_WRITE_PROTECTED SD card is Write Protected. + * @retval FSP_ERR_WRITE_FAILED Write operation failed. + * @retval FSP_ERR_UNSUPPORTED SD and eMMC support disabled in SDEMMC_W_CFG_SD_SUPPORT_ENABLE and + * SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE. + * @retval FSP_ERR_TIMEOUT Device did not respond. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_Write (sdmmc_ctrl_t * const p_api_ctrl, + uint8_t const * const p_source, + uint32_t const start_sector, + uint32_t const sector_count) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + + fsp_err_t err = FSP_SUCCESS; + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_source); + FSP_ASSERT(sector_count <= (UINT16_MAX + 1)); +#endif + err = r_sdemmc_common_error_check(p_ctrl); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + +#if (SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) + uint32_t rsp = 0; + + /* Check for write protection */ + FSP_ERROR_RETURN(false == p_ctrl->device.write_protected, FSP_ERR_CARD_WRITE_PROTECTED); + + /* Call SDMMC protocol write function */ + uint32_t argument = start_sector; + + if (!p_ctrl->sector_addressing) + { + /* Standard capacity SD cards and some eMMC devices use byte addressing. */ + argument *= p_ctrl->p_cfg->block_size; + } + + if (sector_count > 1) + { + if (SDMMC_CARD_TYPE_MMC != p_ctrl->device.card_type) + { + if (gs_body.scr.sd_cmds & SDEMMC_W_PRV_SCR_CMD23_SUPPORT) + { + err = + r_sdemmc_emmc_block_write_data(p_ctrl, SDEMMC_W_PRV_CMD_WRITE_MULTIPLE_BLOCK, argument, &rsp, + (uint8_t *) p_source, sector_count); + } + else + { + err = + r_sdemmc_emmc_multi_write_data(p_ctrl, SDEMMC_W_PRV_CMD_WRITE_MULTIPLE_BLOCK, argument, &rsp, + (uint8_t *) p_source, sector_count); + } + } + else + { + err = + r_sdemmc_emmc_block_write_data(p_ctrl, + SDEMMC_W_PRV_CMD_WRITE_MULTIPLE_BLOCK, + argument, + &rsp, + (uint8_t *) p_source, + sector_count); + } + } + else + { + /* write single block */ + err = + r_sdemmc_emmc_single_write_data(p_ctrl, + SDEMMC_W_PRV_CMD_WRITE_SINGLE_BLOCK, + argument, + 512, + &rsp, + (uint8_t *) p_source); + } + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +#else /* (SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) */ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(p_source); + FSP_PARAMETER_NOT_USED(start_sector); + FSP_PARAMETER_NOT_USED(sector_count); + + FSP_RETURN(FSP_ERR_UNSUPPORTED); +#endif /* (SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) */ +} + +/*******************************************************************************************************************//** + * The Read function reads a one byte register from an SDIO card. Implements @ref sdmmc_api_t::readIo(). + * + * This function blocks until the command is sent and the response is received. p_data contains the register value read + * when this function returns. + * + * @retval FSP_SUCCESS Data read successfully. + * @retval FSP_ERR_ASSERTION NULL pointer. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged. + * @retval FSP_ERR_UNSUPPORTED SDIO support disabled in SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE. + * @retval FSP_ERR_TIMEOUT Device did not respond. + * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is + * ongoing. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_ReadIo (sdmmc_ctrl_t * const p_api_ctrl, + uint8_t * const p_data, + uint32_t const function, + uint32_t const address) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + + fsp_err_t err = FSP_SUCCESS; + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_data); +#endif + err = r_sdemmc_common_error_check(p_ctrl); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + err = r_sdemmc_hw_sdio_device_rx(p_ctrl, p_data, 1); + } + else + { + /* Call SDMMC protocol read function */ + *p_data = 0U; + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_READ, + (uint8_t) function, + address, + 0, + p_data); + } + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +#else /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(p_data); + FSP_PARAMETER_NOT_USED(function); + FSP_PARAMETER_NOT_USED(address); + + FSP_RETURN(FSP_ERR_UNSUPPORTED); +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ +} + +/*******************************************************************************************************************//** + * Writes a one byte register to an SDIO card. Implements @ref sdmmc_api_t::writeIo(). + * + * This function blocks until the command is sent and the response is received. The register has been written when this + * function returns. If read_after_write is true, p_data contains the register value read when this function returns. + * + * @retval FSP_SUCCESS Card write finished successfully. + * @retval FSP_ERR_ASSERTION Handle or Source address is NULL. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged. + * @retval FSP_ERR_WRITE_FAILED Write operation failed. + * @retval FSP_ERR_UNSUPPORTED SDIO support disabled in SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE. + * @retval FSP_ERR_TIMEOUT Device did not respond. + * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is + * ongoing. + * @retval FSP_ERR_UNSUPPORTED SDIO support disabled in SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_WriteIo (sdmmc_ctrl_t * const p_api_ctrl, + uint8_t * const p_data, + uint32_t const function, + uint32_t const address, + sdmmc_io_write_mode_t const read_after_write) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + + fsp_err_t err = FSP_SUCCESS; + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_data); +#endif + err = r_sdemmc_common_error_check(p_ctrl); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + err = r_sdemmc_hw_sdio_device_tx(p_ctrl, p_data, 1); + } + else + { + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_WRITE, + (uint8_t) function, + address, + *p_data, + NULL); + FSP_ERROR_RETURN(FSP_SUCCESS == err, FSP_ERR_WRITE_FAILED); + + if (SDMMC_IO_WRITE_READ_AFTER_WRITE == read_after_write) + { + /* Call SDMMC protocol read function */ + *p_data = 0U; + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_READ, + (uint8_t) function, + address, + 0, + p_data); + } + } + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +#else /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(p_data); + FSP_PARAMETER_NOT_USED(function); + FSP_PARAMETER_NOT_USED(address); + FSP_PARAMETER_NOT_USED(read_after_write); + + FSP_RETURN(FSP_ERR_UNSUPPORTED); +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ +} + +/*******************************************************************************************************************//** + * Reads data from an SDIO card function. Implements @ref sdmmc_api_t::readIoExt(). + * + * This function blocks until the command is sent and the response is received. A callback with the event + * SDMMC_EVENT_TRANSFER_COMPLETE is called when the read data is available. + * + * @retval FSP_SUCCESS Data read successfully. + * @retval FSP_ERR_ASSERTION NULL pointer, or count is not in the valid range of 1-512 for byte mode or + * 1-511 for block mode. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged. + * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation. + * @retval FSP_ERR_INVALID_ARGUMENT Parameter passed into function was invalid. + * @retval FSP_ERR_TIMEOUT Device did not respond. + * @retval FSP_ERR_UNSUPPORTED SDIO support disabled in SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_ReadIoExt (sdmmc_ctrl_t * const p_api_ctrl, + uint8_t * const p_dest, + uint32_t const function, + uint32_t const address, + uint32_t * const count, + sdmmc_io_transfer_mode_t transfer_mode, + sdmmc_io_address_mode_t address_mode) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + + fsp_err_t err = FSP_SUCCESS; + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_dest); + FSP_ASSERT(NULL != count); + FSP_ASSERT(0U != (*count)); +#endif + err = r_sdemmc_common_error_check(p_ctrl); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + if (SDMMC_IO_MODE_TRANSFER_BLOCK == transfer_mode) + { + #if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT((*count) <= SDEMMC_W_PRV_SDIO_EXT_MAX_BLOCKS); + #endif + err = r_sdemmc_hw_sdio_device_rx(p_ctrl, p_dest, *count * p_ctrl->p_cfg->block_size); + } + else + { + #if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT((*count) <= SDEMMC_W_PRV_SDIO_EXT_MAX_BYTES); + #endif + err = r_sdemmc_hw_sdio_device_rx(p_ctrl, p_dest, *count); + } + } + else + { + if (SDMMC_IO_MODE_TRANSFER_BLOCK == transfer_mode) + { + #if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT((*count) <= SDEMMC_W_PRV_SDIO_EXT_MAX_BLOCKS); + #endif + err = r_sdemmc_sdio_io_rw_extended(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_READ, + (uint8_t) function, + address, + address_mode, + p_dest, + *count, + p_ctrl->p_cfg->block_size); + } + else + { + #if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT((*count) <= SDEMMC_W_PRV_SDIO_EXT_MAX_BYTES); + #endif + err = r_sdemmc_sdio_io_rw_extended(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_READ, + (uint8_t) function, + address, + address_mode, + p_dest, + *count, + 1); + } + } + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +#else /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(p_dest); + FSP_PARAMETER_NOT_USED(function); + FSP_PARAMETER_NOT_USED(address); + FSP_PARAMETER_NOT_USED(count); + FSP_PARAMETER_NOT_USED(transfer_mode); + FSP_PARAMETER_NOT_USED(address_mode); + + FSP_RETURN(FSP_ERR_UNSUPPORTED); +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ +} + +/*******************************************************************************************************************//** + * Writes data to an SDIO card function. Implements @ref sdmmc_api_t::writeIoExt(). + * + * This function blocks until the command is sent and the response is received. A callback with the event + * SDMMC_EVENT_TRANSFER_COMPLETE is called when the all data has been written. + * + * @retval FSP_SUCCESS Card write finished successfully. + * @retval FSP_ERR_ASSERTION NULL pointer, or count is not in the valid range of 1-512 for byte mode or + * 1-511 for block mode. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged. + * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation. + * @retval FSP_ERR_INVALID_ARGUMENT Parameter passed into function was invalid. + * @retval FSP_ERR_TIMEOUT Device did not respond. + * @retval FSP_ERR_UNSUPPORTED SDIO support disabled in SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_WriteIoExt (sdmmc_ctrl_t * const p_api_ctrl, + uint8_t const * const p_source, + uint32_t const function, + uint32_t const address, + uint32_t const count, + sdmmc_io_transfer_mode_t transfer_mode, + sdmmc_io_address_mode_t address_mode) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + + fsp_err_t err = FSP_SUCCESS; + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_source); + FSP_ASSERT(0U != count); +#endif + err = r_sdemmc_common_error_check(p_ctrl); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + if (SDMMC_IO_MODE_TRANSFER_BLOCK == transfer_mode) + { + #if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(count <= SDEMMC_W_PRV_SDIO_EXT_MAX_BLOCKS); + #endif + err = r_sdemmc_hw_sdio_device_tx(p_ctrl, p_source, count * p_ctrl->p_cfg->block_size); + } + else + { + #if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(count <= SDEMMC_W_PRV_SDIO_EXT_MAX_BYTES); + #endif + err = r_sdemmc_hw_sdio_device_tx(p_ctrl, p_source, count); + } + } + else + { + if (SDMMC_IO_MODE_TRANSFER_BLOCK == transfer_mode) + { + #if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(count <= SDEMMC_W_PRV_SDIO_EXT_MAX_BLOCKS); + #endif + err = r_sdemmc_sdio_io_rw_extended(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_WRITE, + (uint8_t) function, + address, + address_mode, + (uint8_t *) p_source, + count, + p_ctrl->p_cfg->block_size); + } + else + { + #if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(count <= SDEMMC_W_PRV_SDIO_EXT_MAX_BYTES); + #endif + err = r_sdemmc_sdio_io_rw_extended(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_WRITE, + (uint8_t) function, + address, + address_mode, + (uint8_t *) p_source, + count, + 1); + } + } + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +#else /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(p_source); + FSP_PARAMETER_NOT_USED(function); + FSP_PARAMETER_NOT_USED(address); + FSP_PARAMETER_NOT_USED(count); + FSP_PARAMETER_NOT_USED(transfer_mode); + FSP_PARAMETER_NOT_USED(address_mode); + + FSP_RETURN(FSP_ERR_UNSUPPORTED); +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ +} + +/*******************************************************************************************************************//** + * Enables or disables the SDIO Interrupt. Implements @ref sdmmc_api_t::ioIntEnable(). + * + * @retval FSP_SUCCESS Card enabled or disabled SDIO interrupts successfully. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + * @retval FSP_ERR_ASSERTION NULL pointer. + * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation. + * @retval FSP_ERR_UNSUPPORTED SDIO support disabled in SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_IoIntEnable (sdmmc_ctrl_t * const p_api_ctrl, bool enable) +{ +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + + #if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + + FSP_ERROR_RETURN(SDEMMC_W_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); + #endif + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + /* Make sure the device is not busy. */ + FSP_ERROR_RETURN((0x1 == p_ctrl->p_reg->SDIO_CARDRDY_REG_b.CARD_RDY), FSP_ERR_DEVICE_BUSY); + + /* Enable or disable interrupt. */ + if (enable) + { + NVIC_EnableIRQ(SDIO_IRQn); /* Enable interrupt */ + } + else + { + NVIC_DisableIRQ(SDIO_IRQn); /* Disable interrupt */ + } + } + else + { + /* Make sure the card is not busy. */ + FSP_ERROR_RETURN((0xF == p_ctrl->p_reg_mmc->SDEMMC_PRESENTSTATE_REG_b.DAT3TO0LineSignalLevel), + FSP_ERR_DEVICE_BUSY); + + /* Enable or disable interrupt. */ + if (enable) + { + NVIC_EnableIRQ(SDEMMC_IRQn); /* Enable interrupt */ + } + else + { + NVIC_DisableIRQ(SDEMMC_IRQn); /* Disable interrupt */ + } + } + + return FSP_SUCCESS; +#else /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(enable); + + FSP_RETURN(FSP_ERR_UNSUPPORTED); +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ +} + +/*******************************************************************************************************************//** + * Provides driver status. Implements @ref sdmmc_api_t::statusGet(). + * + * @retval FSP_SUCCESS Status stored in p_status. + * @retval FSP_ERR_ASSERTION NULL pointer. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_StatusGet (sdmmc_ctrl_t * const p_api_ctrl, sdmmc_status_t * const p_status) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + + /* Check pointers for NULL values */ + FSP_ASSERT(NULL != p_ctrl); + FSP_ASSERT(NULL != p_status); + + FSP_ERROR_RETURN(SDEMMC_W_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); +#endif + + /* Check CD pin. */ + if (SDEMMC_W_ROLE_HOST == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + if (SDMMC_CARD_DETECT_CD == p_ctrl->p_cfg->card_detect) + { + p_status->card_inserted = p_ctrl->p_reg_mmc->SDEMMC_PRESENTSTATE_REG_b.CardInserted; + } + else + { + p_status->card_inserted = true; + } + } + + /* Whether or not the media is initialized. */ + p_status->initialized = p_ctrl->initialized; + + /* Check if the card is busy. */ + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + p_status->transfer_in_progress = + (0x1 != p_ctrl->p_reg->SDIO_CARDRDY_REG_b.CARD_RDY); + } + else + { + p_status->transfer_in_progress = + (0xF != p_ctrl->p_reg_mmc->SDEMMC_PRESENTSTATE_REG_b.DAT3TO0LineSignalLevel); + } + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Erases sectors of an SD card or eMMC device. Implements @ref sdmmc_api_t::erase(). + * + * Poll the status to determine when erase is complete. + * + * @retval FSP_SUCCESS Erase operation requested. + * @retval FSP_ERR_ASSERTION A required pointer is NULL or an argument is invalid. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged. + * @retval FSP_ERR_CARD_WRITE_PROTECTED SD card is Write Protected. + * @retval FSP_ERR_RESPONSE Device responded with an error. + * @retval FSP_ERR_TIMEOUT Device did not respond. + * @retval FSP_ERR_UNSUPPORTED SD and eMMC support disabled in SDEMMC_W_CFG_SD_SUPPORT_ENABLE and + * SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE. + * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is + * ongoing. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_Erase (sdmmc_ctrl_t * const p_api_ctrl, uint32_t const start_sector, uint32_t const sector_count) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + + fsp_err_t err = FSP_SUCCESS; + + err = r_sdemmc_erase_error_check(p_ctrl, start_sector, sector_count); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + +#if (SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) + uint32_t start_address = 0; + uint32_t end_address = 0; + uint32_t start_command = 0; + uint32_t end_command = 0; + uint32_t argument = 0; + uint32_t transfer_reg = 0; + + /* SDHC, SDXC and eMMC high capacity media use block addressing. */ + if (true == p_ctrl->sector_addressing) + { + start_address = start_sector; + end_address = ((start_sector + sector_count) - 1); + } + else + { + start_address = (start_sector * p_ctrl->p_cfg->block_size); + end_address = ((start_sector + sector_count) * p_ctrl->p_cfg->block_size) - 1U; + } + + #if SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + if (SDMMC_CARD_TYPE_MMC == p_ctrl->device.card_type) + { + start_command = SDEMMC_W_PRV_CMD_TAG_ERASE_GROUP_START; + end_command = SDEMMC_W_PRV_CMD_TAG_ERASE_GROUP_END; + argument = SDEMMC_W_PRV_EMMC_ERASE_ARGUMENT_TRIM; + } + else + #endif + { + start_command = SDEMMC_W_PRV_CMD_ERASE_WR_BLK_START; + end_command = SDEMMC_W_PRV_CMD_ERASE_WR_BLK_END; + argument = 0U; /* Argument unused for SD */ + } + + /* Send command to set start erase address (CMD35 for eMMC, CMD32 for SD). */ + err = r_sdemmc_command_send(p_ctrl, start_command, start_address); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + /* Send command to set end erase address (CMD36 for eMMC, CMD33 for SD). */ + err = r_sdemmc_command_send(p_ctrl, end_command, end_address); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + /* Send erase command (CMD38). */ + transfer_reg = SDEMMC_W_PRV_CMD_ERASE << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos | + SDEMMC_W_GET_CMD_RESP_TYPE(SDEMMC_W_PRV_CMD_ERASE) << + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_ResponseTypeSelect_Pos | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndexCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DMAEnable_Msk; + r_sdemmc_command_send_no_wait(p_ctrl, transfer_reg, argument); + + return FSP_SUCCESS; +#else /* (SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) */ + FSP_PARAMETER_NOT_USED(p_api_ctrl); + FSP_PARAMETER_NOT_USED(start_sector); + FSP_PARAMETER_NOT_USED(sector_count); + + FSP_RETURN(FSP_ERR_UNSUPPORTED); +#endif /* (SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) */ +} + +/*******************************************************************************************************************//** + * Updates the user callback with the option to provide memory for the callback argument structure. + * Implements @ref sdmmc_api_t::callbackSet. + * + * @retval FSP_SUCCESS Callback updated successfully. + * @retval FSP_ERR_ASSERTION A required pointer is NULL. + * @retval FSP_ERR_NOT_OPEN The control block has not been opened. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_CallbackSet (sdmmc_ctrl_t * const p_api_ctrl, + void ( * p_callback)(sdmmc_callback_args_t *), + void * const p_context, + sdmmc_callback_args_t * const p_callback_memory) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(p_ctrl); + FSP_ASSERT(p_callback); + FSP_ERROR_RETURN(SDEMMC_W_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); +#endif + + /* Store callback and context */ + p_ctrl->p_callback = p_callback; + p_ctrl->p_context = p_context; + p_ctrl->p_callback_memory = p_callback_memory; + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Get the SDEMMC transfer result. + * + * @retval FSP_SUCCESS Callback updated successfully. + * @retval FSP_ERR_ASSERTION A required pointer is NULL. + * @retval FSP_ERR_NOT_OPEN The control block has not been opened. + * @note This function should only be called from an ISR or within a critical section to ensure + * the result reflects the current transfer and not a subsequent one. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_ResultGet (sdmmc_ctrl_t * const p_api_ctrl, sdemmc_w_transfer_result_t * p_result) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(p_ctrl); + FSP_ASSERT(p_result); + FSP_ERROR_RETURN(SDEMMC_W_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); +#endif + + memcpy(p_result, &p_ctrl->result, sizeof(sdemmc_w_transfer_result_t)); + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Closes an open SD/MMC device. Implements @ref sdmmc_api_t::close(). + * + * @retval FSP_SUCCESS Successful close. + * @retval FSP_ERR_ASSERTION The parameter p_ctrl is NULL. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + * @retval FSP_ERR_TIMEOUT Device did not respond. + **********************************************************************************************************************/ +fsp_err_t R_SDEMMC_W_Close (sdmmc_ctrl_t * const p_api_ctrl) +{ + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) p_api_ctrl; +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + fsp_err_t err = FSP_SUCCESS; + uint8_t reg = 0; +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + + FSP_ERROR_RETURN(SDEMMC_W_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); +#endif + + if (SDEMMC_W_ROLE_HOST == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + + /* For SDIO, follow the procedure in Figure 3-2 "Card Initialization Flow in SD mode (SDIO Aware Host)" in SDIO + * Specification Version 2.00. */ + + /* Reset I/O: In order to reset an I/O only card or the I/O portion of a combo card, use CMD52 to set the RES bit + * in the CCCR (bit 3 of register 6). Reference Table 6-2 "CCCR bit definitions" in SDIO Specification + * Version 2.00. */ + if (SDMMC_CARD_TYPE_SDIO == p_ctrl->device.card_type) + { + reg = 1U << 3; + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_WRITE, + 0, + SDEMMC_W_SDIO_CCCR_IOASX_RESET, + reg, + NULL); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + } +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + if ((SDMMC_CARD_TYPE_SD == p_ctrl->device.card_type) || (SDMMC_CARD_TYPE_MMC == p_ctrl->device.card_type)) + { + /* Put the card in idle state (CMD0). */ + r_sdemmc_emmc_cmd_without_res(p_ctrl, SDEMMC_W_PRV_CMD_GO_IDLE_STATE, 0); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + } +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + } + + p_ctrl->open = 0U; + +#if (CFG_PMGR == 1) && (SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE == 1) + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + r_sdemmc_w_unsubscribe_from_pmgr_notifications((sdemmc_w_instance_ctrl_t *) p_ctrl); + } +#endif + + /* Deinitialize callback and context. */ + p_ctrl->p_callback = NULL; + p_ctrl->p_context = NULL; + p_ctrl->p_callback_memory = NULL; + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + if ((SDMMC_CARD_TYPE_SD == p_ctrl->device.card_type) || (SDMMC_CARD_TYPE_MMC == p_ctrl->device.card_type)) + { + /* Put the card in idle state (CMD0). */ + r_sdemmc_emmc_cmd_without_res(p_ctrl, SDEMMC_W_PRV_CMD_GO_IDLE_STATE, 0); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + } +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + + /* Disable SDEMMC_W interrupts. */ + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + r_sdemmc_irq_disable(p_ctrl->p_cfg->sdio_irq); + } + else + { + r_sdemmc_irq_disable(p_ctrl->p_cfg->access_irq); + } + + if (SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + r_sdemmc_hw_sdio_device_deinit(p_ctrl); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + /* Reset SDIO_MODE_REG */ + GPIO->SDIO_MODE_REG_b.SDIO_PAD_ENABLE = 0; + GPIO->SDIO_MODE_REG_b.SDIO_PULL_EN = 0; + GPIO->SDIO_MODE_REG_b.SDIO_PULL_SEL = 0; + } + else + { + r_sdemmc_hw_sdemmc_disable(p_ctrl); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + + /* Reset EMMC_MODE_REG */ + GPIO->EMMC_MODE_REG_b.EMMC_ENABLE = 0; + GPIO->EMMC_MODE_REG_b.EMMC_CLKIN_SEL = 0; + GPIO->EMMC_MODE_REG_b.EMMC_OCTA_MODE = 0; + GPIO->EMMC_MODE_REG_b.EMMC_PULL_EN = 0; + GPIO->EMMC_MODE_REG_b.EMMC_PULL_SEL = 0; + } + + /* Do not set the module stop bit since the CMD0 may not be complete yet. Do not wait for CMD0 to complete because + * the card could be unplugged and waiting for the response timeout in this function is not desirable. */ + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * @} (end addtogroup SDEMMC_W) + **********************************************************************************************************************/ + +/*********************************************************************************************************************** + * Private Functions + **********************************************************************************************************************/ + +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + +/*******************************************************************************************************************//** + * Parameter checking for the open function. + * + * @param[in] p_ctrl Pointer to the instance control block. + * @param[in] p_cfg Pointer to the instance configuration structure. + * + * @retval FSP_SUCCESS Parameters to open() are in the valid range. + * @retval FSP_ERR_ASSERTION A required input pointer is NULL. + * @retval FSP_ERR_ALREADY_OPEN Driver has already been opened with this instance of the control + * structure. + * @retval FSP_ERR_IP_CHANNEL_NOT_PRESENT Requested channel does not exist on this MCU. + * @retval FSP_ERR_IRQ_BSP_DISABLED Access interrupt is not enabled. + **********************************************************************************************************************/ +static fsp_err_t r_sdemmc_open_param_check (sdemmc_w_instance_ctrl_t * p_ctrl, sdmmc_cfg_t const * const p_cfg) +{ + FSP_ASSERT(NULL != p_ctrl); + FSP_ASSERT(NULL != p_cfg); + FSP_ERROR_RETURN(SDEMMC_W_PRV_OPEN != p_ctrl->open, FSP_ERR_ALREADY_OPEN); + + #ifdef BSP_FEATURE_SDHI_VALID_CHANNEL_MASK + + /* Verify the requested channel exists on the MCU. */ + FSP_ERROR_RETURN(0U != ((1U << p_cfg->channel) & BSP_FEATURE_SDHI_VALID_CHANNEL_MASK), + FSP_ERR_IP_CHANNEL_NOT_PRESENT); + #else /* BSP_FEATURE_SDHI_VALID_CHANNEL_MASK */ + /* Verify the requested channel exists on the MCU. */ + FSP_ERROR_RETURN(0U == p_cfg->channel, FSP_ERR_IP_CHANNEL_NOT_PRESENT); + #endif /* BSP_FEATURE_SDHI_VALID_CHANNEL_MASK */ + + /* SD/MMC/SDIO Host only. */ + if (SDEMMC_W_ROLE_HOST == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role) + { + /* Access interrupt is required. */ + FSP_ERROR_RETURN(p_cfg->access_irq >= 0, FSP_ERR_IRQ_BSP_DISABLED); + } + + return FSP_SUCCESS; +} + +#endif + +/*******************************************************************************************************************//** + * Parameter checking for erase. + * + * @param[in] p_ctrl Pointer to the instance control block. + * @param[in] start_sector First sector to erase + * @param[in] sector_count Number of sectors to erase + * + * @retval FSP_SUCCESS Erase operation requested. + * @retval FSP_ERR_ASSERTION A required pointer is NULL or an argument is invalid. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged. + * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation. + * @retval FSP_ERR_CARD_WRITE_PROTECTED SD card is Write Protected. + **********************************************************************************************************************/ +static fsp_err_t r_sdemmc_erase_error_check (sdemmc_w_instance_ctrl_t * const p_ctrl, + uint32_t const start_sector, + uint32_t const sector_count) +{ + fsp_err_t err = r_sdemmc_common_error_check(p_ctrl); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + FSP_PARAMETER_NOT_USED(start_sector); + FSP_PARAMETER_NOT_USED(sector_count); + + /* Check for write protection */ + FSP_ERROR_RETURN(false == p_ctrl->device.write_protected, FSP_ERR_CARD_WRITE_PROTECTED); + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Parameter checking for runtime APIs. + * + * @param[in] p_ctrl Pointer to the instance control block. + * + * @retval FSP_SUCCESS Device is ready to be accessed. + * @retval FSP_ERR_ASSERTION A required pointer is NULL. + * @retval FSP_ERR_NOT_OPEN Driver has not been initialized. + * @retval FSP_ERR_CARD_NOT_INITIALIZED Card was unplugged. + * @retval FSP_ERR_DEVICE_BUSY Driver is busy with a previous operation. + **********************************************************************************************************************/ +static fsp_err_t r_sdemmc_common_error_check (sdemmc_w_instance_ctrl_t * const p_ctrl) +{ +#if SDEMMC_W_CFG_PARAM_CHECKING_ENABLE + FSP_ASSERT(NULL != p_ctrl); + FSP_ERROR_RETURN(SDEMMC_W_PRV_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN); +#endif + + if (SDMMC_CARD_TYPE_MMC == p_ctrl->device.card_type) + { + /* Because the default card_type value is 0, if mediaInit has not yet been called, + * return FSP_ERR_CARD_NOT_INITIALIZED.*/ + FSP_ERROR_RETURN(p_ctrl->initialized, FSP_ERR_CARD_NOT_INITIALIZED); + + /* To verify no command sequence is in progress in SDEMMC_W, verify SD_INFO2.CBSY is not set. + * To verify the card has completed the requested operation, verify SD_INFO2.SDD0MON is set. */ + FSP_ERROR_RETURN((0xF == p_ctrl->p_reg_mmc->SDEMMC_PRESENTSTATE_REG_b.DAT3TO0LineSignalLevel), + FSP_ERR_DEVICE_BUSY); + } + else if (SDMMC_CARD_TYPE_SD == p_ctrl->device.card_type) + { + /* Verify the card has not been removed since the last card initialization. */ + FSP_ERROR_RETURN(p_ctrl->initialized, FSP_ERR_CARD_NOT_INITIALIZED); + } + + return FSP_SUCCESS; +} + +/*******************************************************************************************************************//** + * Configures and enables an interrupt. + * + * @param[in] irq Interrupt number. + * @param[in] priority NVIC priority of the interrupt + * @param[in] p_context Pointer to data required in the ISR. + **********************************************************************************************************************/ +static void r_sdemmc_irq_enable (IRQn_Type irq, uint8_t priority, void * p_context) +{ + if (irq >= 0) + { + R_BSP_IrqCfgEnable(irq, priority, p_context); + } +} + +/*******************************************************************************************************************//** + * Disables an interrupt. + * + * @param[in] irq Interrupt to disable. + **********************************************************************************************************************/ +static void r_sdemmc_irq_disable (IRQn_Type irq) +{ + if (irq >= 0) + { + /* Disables interrupts in the NVIC. */ + R_BSP_IrqDisable(irq); + + /* Clears the control block from the vector information array. */ + R_FSP_IsrContextSet(irq, NULL); + } +} + +/*******************************************************************************************************************//** + * Stores access interrupt flags in the control block and calls the callback. + * + * @param[in] p_ctrl Pointer to the instance control block. + * @param[in] p_args Pointer to SDMMC callback arguments. + **********************************************************************************************************************/ +static void r_sdemmc_access_irq_process (sdemmc_w_instance_ctrl_t * p_ctrl, sdmmc_callback_args_t * p_args) +{ + sdemmc_w_event_t flags; + + /* Read interrupt flag registers. */ + flags.word = p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_REG; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_REG = 0; + + if (flags.bit.response_end) + { + p_args->event |= SDMMC_EVENT_RESPONSE; + + p_args->response.status = p_ctrl->p_reg_mmc->SDEMMC_RESPONSE0_REG; + + if (SDEMMC_W_PRV_CMD_ERASE == p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG_b.CommandIndex) + { + /* Determine if erase is complete or not based on DAT0. Access interrupt is not required for erase. */ + if (0xF == p_ctrl->p_reg_mmc->SDEMMC_PRESENTSTATE_REG_b.DAT3TO0LineSignalLevel) + { + p_args->event |= SDMMC_EVENT_ERASE_COMPLETE; + + /* Disable response end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 0; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 0; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SoftwareResetForDATLine = 1; + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + } + else + { + p_args->event |= SDMMC_EVENT_ERASE_BUSY; + } + } + else + { + /* Disable response end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 0; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 0; + } + } + + if (flags.bit.access_end) + { + p_ctrl->result.sdio_blk_or_byte = + (p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG & 0x08000000) ? 1 : 0; + p_ctrl->result.sdio_blk_size = + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize; + p_ctrl->result.sdio_blk_count = g_BlockCountForCurrentTransfer; + + p_args->event |= SDMMC_EVENT_TRANSFER_COMPLETE; + + /* Disable access end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.TransferCompleteSignalEnb = 0; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.TransferCompleteStatusEnb = 0; + } + + if (flags.bit.card_removed) + { + p_args->event |= SDMMC_EVENT_CARD_REMOVED; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CardRemovalSignalEnb = 0; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CardRemovalStatusEnb = 0; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CardInsertionSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CardInsertionStatusEnb = 1; + } + + if (flags.bit.card_inserted) + { + p_args->event |= SDMMC_EVENT_CARD_INSERTED; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CardInsertionSignalEnb = 0; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CardInsertionStatusEnb = 0; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CardRemovalSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CardRemovalStatusEnb = 1; + } + + if (flags.bit.CardInterrupt) + { + /* card interrupt should be disabled during ISR operation. */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CardInterruptSignalEnb = 0; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CardInterruptStatusEnb = 0; + } + + /* Check for errors */ + if (flags.word & SDEMMC_W_PRV_ACCESS_ERROR_MASK) + { + flags.bit.ErrorInterrupt = 1U; + p_args->event |= SDMMC_EVENT_TRANSFER_ERROR; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG = 0; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG = 0; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.InternalClockEnable = 0; + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.InternalClockEnable = 1; + } + + /* Combine all events for each command because this flag is polled in some functions. */ + p_ctrl->sdemmc_w_event.word |= flags.word; +} + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + +/*******************************************************************************************************************//** + * Send a command to the SD, eMMC, or SDIO device. + * + * @param[in] p_ctrl Pointer to the instance control block. + * @param[in] command Command to send. + * @param[in] argument Argument to send with the command. + **********************************************************************************************************************/ +static void r_sdemmc_command_send_no_wait (sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t command, uint32_t argument) +{ + /* Clear Status */ + p_ctrl->sdemmc_w_event.word = 0U; + p_ctrl->p_reg_mmc->SDEMMC_SDMA_SYS_ADDR__ARGU_2_REG = 0; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize = 0; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.HostSDMABufferBoundry = 7; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.BlockCountForCurrentTransfer = 0; + g_BlockCountForCurrentTransfer = 0; + + /* Enable response end interrupt. */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + + /* Write argument, then command to the SDEMMC_W peripheral. */ + p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG = argument; + p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG = command; + + /* Enable Clock */ + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDClockEnable = 1; +} + +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + +/*******************************************************************************************************************//** + * Send a command to the SD, eMMC, or SDIO device and wait for response + * + * @param[in] p_ctrl Pointer to the instance control block. + * @param[in] command Command to send. + * @param[in] argument Argument to send with the command. + * + * @retval FSP_SUCCESS Command sent and response received, no errors in response. + * @retval FSP_ERR_RESPONSE Device responded with an error. + * @retval FSP_ERR_TIMEOUT Device did not respond. + * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing. + **********************************************************************************************************************/ +static fsp_err_t r_sdemmc_command_send (sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t command, uint32_t argument) +{ + uint32_t transfer_reg = 0; + + /* Verify the device is not busy. */ + r_sdemmc_wait_for_device(p_ctrl); + + /* Send the command. */ + transfer_reg = command << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataPresentSelect_Msk | + (uint32_t) (SDEMMC_W_GET_CMD_RESP_TYPE(command) << + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_ResponseTypeSelect_Pos) | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndexCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DMAEnable_Msk; + r_sdemmc_command_send_no_wait(p_ctrl, transfer_reg, argument); + + /* Wait for end of response, error or timeout */ + return r_sdemmc_wait_for_event(p_ctrl, SDEMMC_W_PRV_RESPONSE_BIT, SDEMMC_W_PRV_RESPONSE_TIMEOUT_US); +} + +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + +/*******************************************************************************************************************//** + * Update write protection status in control block. + * + * @param[in] p_ctrl Pointer to the instance control block. + **********************************************************************************************************************/ +static void r_sdemmc_write_protect_get (sdemmc_w_instance_ctrl_t * const p_ctrl) +{ + /* Update write protection status in the control block if the device is a card. */ + if (p_ctrl->p_cfg->write_protect) + { + p_ctrl->device.write_protected = + (0 == p_ctrl->p_reg_mmc->SDEMMC_PRESENTSTATE_REG_b.WriteProtectSwitchPinLevel); + } +} + +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + +/*******************************************************************************************************************//** + * Wait for the device. + * + * @param[in] p_ctrl Pointer to the instance control block. + * + * @retval FSP_SUCCESS Previous operation is complete, and SDEMMC_W is ready for the next operation. + * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing. + **********************************************************************************************************************/ +static fsp_err_t r_sdemmc_wait_for_device (sdemmc_w_instance_ctrl_t * const p_ctrl) +{ + /* Wait for the device to stop holding DAT0 low. */ + uint32_t timeout = SDEMMC_W_PRV_BUSY_TIMEOUT_US; + + while (0xF != p_ctrl->p_reg_mmc->SDEMMC_PRESENTSTATE_REG_b.DAT3TO0LineSignalLevel) + { + FSP_ERROR_RETURN(timeout > 0, FSP_ERR_DEVICE_BUSY); + + R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS); + timeout--; + } + + return FSP_SUCCESS; +} + +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + +/*******************************************************************************************************************//** + * Waits for the access end interrupt. + * + * @param[in] p_ctrl Pointer to the instance control block. + * @param[in] bit Bit to check in p_ctrl->sdemmc_w_event + * @param[in] timeout_us Number of loops to check bit (at least 1 us per loop). + * + * @retval FSP_SUCCESS Requested bit (access end or response end) is set. + * @retval FSP_ERR_RESPONSE Device responded with an error. + * @retval FSP_ERR_TIMEOUT Device did not respond. + **********************************************************************************************************************/ +static fsp_err_t r_sdemmc_wait_for_event (sdemmc_w_instance_ctrl_t * const p_ctrl, uint32_t bit, uint32_t timeout_us) +{ + /* The event status is updated in the access interrupt. Use a local copy of the event status to make sure + * it isn't updated during the loop. */ + volatile sdemmc_w_event_t event; + + while (true) + { + /* Check for updates to the event status. */ + event.word = p_ctrl->sdemmc_w_event.word; + + /* Return an error if a hardware error occurred. */ + if (event.bit.ErrorInterrupt) + { + r_sdemmc_hw_sdemmc_renable_prepare(p_ctrl); + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SoftwareResetForAll = 1; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.HardwareRst = 1; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.InternalClockEnable = 0; + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + r_sdemmc_hw_sdemmc_renable(p_ctrl); + r_sdemmc_sdemmc_interrupt_enable(p_ctrl); + FSP_RETURN(FSP_ERR_RESPONSE); + } + + /* If the requested bit is set, return success. */ + if (event.word & (1U << bit)) + { + return FSP_SUCCESS; + } + + /* Check for timeout. */ + timeout_us--; + + if (0U == timeout_us) + { + FSP_RETURN(FSP_ERR_TIMEOUT); + } + + /* Wait 1 us for consistent loop timing. */ + R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS); + } +} + +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + +/*******************************************************************************************************************//** + * Save Card Specific Data. + * + * @param[in] p_ctrl Pointer to the instance control block. + * @param[in] rca Relative card address + * @param[out] p_csd_reg Pointer to card specific data. + * + * @retval FSP_SUCCESS Card specific data stored in provided pointer. + * @retval FSP_ERR_RESPONSE Device responded with an error. + * @retval FSP_ERR_TIMEOUT Device did not respond. + * @retval FSP_ERR_DEVICE_BUSY Device is holding DAT0 low (device is busy) or another operation is ongoing. + **********************************************************************************************************************/ +static fsp_err_t r_sdemmc_csd_save (sdemmc_w_instance_ctrl_t * const p_ctrl, + uint32_t rca, + sdmmc_priv_csd_reg_t * const p_csd_reg, + uint32_t send_flag) +{ + if (true == send_flag) + { + /* Send CMD9 to get CSD */ + fsp_err_t err = r_sdemmc_command_send(p_ctrl, SDEMMC_W_PRV_CMD_SEND_CSD, (rca << 16)); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + } + + /* SDResponseR2 are bits from 8-127, first 8 MSBs are reserved */ + p_csd_reg->reg.sdrsp10 = p_ctrl->p_reg_mmc->SDEMMC_RESPONSE0_REG; + p_csd_reg->reg.sdrsp32 = p_ctrl->p_reg_mmc->SDEMMC_RESPONSE1_REG; + p_csd_reg->reg.sdrsp54 = p_ctrl->p_reg_mmc->SDEMMC_RESPONSE2_REG; + p_csd_reg->reg.sdrsp76 = p_ctrl->p_reg_mmc->SDEMMC_RESPONSE3_REG; + + /* Get the CSD version. */ + uint32_t csd_version = p_csd_reg->csd_v1_b.csd_structure; + + /* Save sector count (total number of sectors on device) and erase sector count (minimum erasable unit in + * sectors). */ + uint32_t mult = 0; + + if ((SDEMMC_W_PRV_CSD_VERSION_1_0 == csd_version) || (SDMMC_CARD_TYPE_MMC == p_ctrl->device.card_type)) + { + mult = (1U << (p_csd_reg->csd_v1_b.c_size_mult + 2)); + p_ctrl->device.sector_count = ((p_csd_reg->csd_v1_b.c_size + 1U) * mult); + + /* Scale the sector count by the actual block size. */ + uint32_t read_sector_size = 1U << p_csd_reg->csd_v1_b.read_bl_len; + p_ctrl->device.sector_count = p_ctrl->device.sector_count * (read_sector_size / SDEMMC_W_MAX_BLOCK_SIZE); + + if (SDMMC_CARD_TYPE_MMC == p_ctrl->device.card_type) + { + /* If c_size is 0xFFF, then sector_count should be obtained from the extended CSD. + * Set it to 0 to indicate it should come from the extended CSD later. */ + if (SDEMMC_W_PRV_SECTOR_COUNT_IN_EXT_CSD == p_csd_reg->csd_v1_b.c_size) + { + p_ctrl->device.sector_count = 0U; + } + } + } + + #if SDEMMC_W_CFG_SD_SUPPORT_ENABLE + else if (SDEMMC_W_PRV_CSD_VERSION_2_0 == csd_version) + { + p_ctrl->device.sector_count = (p_csd_reg->csd_v2_b.c_size + 1U) * SDEMMC_W_PRV_BYTES_PER_KILOBYTE; + } + else + { + /* Do Nothing */ + } + + if (SDEMMC_W_PRV_CSD_VERSION_1_0 == csd_version) + { + /* Get the minimum erasable unit (in 512 byte sectors). */ + p_ctrl->device.erase_sector_count = p_csd_reg->csd_v1_b.sector_size + 1U; + } + else + #endif + { + /* For SDHC and SDXC cards, there are no erase group restrictions. + * Using the eMMC TRIM operation, there are no erase group restrictions. */ + p_ctrl->device.erase_sector_count = 1U; + } + + return FSP_SUCCESS; +} + +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE || SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +/*******************************************************************************************************************//** + * Calls user callback + * + * @param[in] p_ctrl Pointer to the instance control block. + * @param[in] p_args Pointer to callback arguments with event and response set. + **********************************************************************************************************************/ +static void r_sdemmc_call_callback (sdemmc_w_instance_ctrl_t * p_ctrl, sdmmc_callback_args_t * p_args) +{ + /* Call user callback if provided, if an event was determined, and if the driver is initialized. */ + if (NULL != p_ctrl->p_callback) + { + sdmmc_callback_args_t args; + + /* Store callback arguments in memory provided by user if available. This allows callback arguments to be + * stored in non-secure memory so they can be accessed by a non-secure callback function. */ + sdmmc_callback_args_t * p_args_memory = p_ctrl->p_callback_memory; + + if (NULL == p_args_memory) + { + /* Use provided args struct on stack */ + p_args_memory = p_args; + } + else + { + /* Save current arguments on the stack in case this is a nested interrupt. */ + args = *p_args_memory; + + /* Copy the stacked args to callback memory */ + *p_args_memory = *p_args; + } + + p_args_memory->p_context = p_ctrl->p_context; + + /* If the project is not Trustzone Secure, + * then it will never need to change security state in order to call the callback. */ + p_ctrl->p_callback(p_args_memory); + + if (NULL != p_ctrl->p_callback_memory) + { + /* Restore callback memory in case this is a nested interrupt. */ + *p_ctrl->p_callback_memory = args; + } + } +} + +/*******************************************************************************************************************//** + * Calls user callback after response or data transfer complete. + **********************************************************************************************************************/ +void sdhimmc_accs_isr (void) +{ + /* Save context if RTOS is used */ + FSP_CONTEXT_SAVE; + + IRQn_Type irq = R_FSP_CurrentIrqGet(); + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) R_FSP_IsrContextGet(irq); + + sdmmc_callback_args_t args; + memset(&args, 0U, sizeof(args)); + r_sdemmc_access_irq_process(p_ctrl, &args); + + /* Call user callback */ + if (((p_ctrl->initialized) && (0U != args.event)) || + (0U != (args.event & (SDMMC_EVENT_CARD_INSERTED | SDMMC_EVENT_CARD_REMOVED)))) + { + r_sdemmc_call_callback(p_ctrl, &args); + } + + if (0 != (args.event & SDMMC_EVENT_CARD_REMOVED)) + { + p_ctrl->initialized = false; + } + +#if BSP_FEATURE_BSP_HAS_ICU + + /* Clear the IR flag in the ICU */ + /* Clearing the IR bit must be done after clearing the interrupt source in the the peripheral */ + R_BSP_IrqStatusClear(irq); +#endif /* BSP_FEATURE_BSP_HAS_ICU */ + + /* Restore context if RTOS is used */ + FSP_CONTEXT_RESTORE; +} + +/*******************************************************************************************************************//** + * Calls callback and clears interrupt flags. + **********************************************************************************************************************/ +void sdhimmc_sdio_isr (void) +{ +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + + /* Save context if RTOS is used */ + FSP_CONTEXT_SAVE; + + IRQn_Type irq = R_FSP_CurrentIrqGet(); + sdemmc_w_instance_ctrl_t * p_ctrl = (sdemmc_w_instance_ctrl_t *) R_FSP_IsrContextGet(irq); + + /* Determine the source of the interrupt. */ + sdmmc_callback_args_t args; + memset(&args, 0U, sizeof(args)); + uint32_t info1 = p_ctrl->p_reg->SDIO_GLB_INT_STS_REG; + + if (info1 & SDEMMC_W_PRV_SDIO_INFO1_FN0_INT_TO_ARM_MASK) + { + /* Disable the GLB_INT_ENA Register */ + p_ctrl->p_reg->SDIO_GLB_INT_ENA_REG = (~SDEMMC_W_PRV_SDIO_INFO1_VALUE_GLB_INT_ENA & 0x3); + + /* Clear the Global INT STS Register Value */ + p_ctrl->p_reg->SDIO_GLB_INT_STS_REG = SDEMMC_W_PRV_SDIO_INFO1_FN0_INT_TO_ARM_MASK; + r_sdemmc_handle_interrupt_fn0(p_ctrl); + + /* Enable the GLB INT ENA Register */ + p_ctrl->p_reg->SDIO_GLB_INT_ENA_REG = (SDEMMC_W_PRV_SDIO_INFO1_VALUE_GLB_INT_ENA & 0x3); + } + + if (info1 & SDEMMC_W_PRV_SDIO_INFO1_FN1_INT_TO_ARM_MASK) + { + /* Disable the GLB_INT_ENA Register */ + p_ctrl->p_reg->SDIO_GLB_INT_ENA_REG = (~SDEMMC_W_PRV_SDIO_INFO1_VALUE_GLB_INT_ENA & 0x3); + + /* Clear the Global INT STS Register Value */ + p_ctrl->p_reg->SDIO_GLB_INT_STS_REG = SDEMMC_W_PRV_SDIO_INFO1_FN1_INT_TO_ARM_MASK; + r_sdemmc_handle_interrupt_fn1(p_ctrl, &args); + + /* Enable the GLB INT ENA Register */ + p_ctrl->p_reg->SDIO_GLB_INT_ENA_REG = (SDEMMC_W_PRV_SDIO_INFO1_VALUE_GLB_INT_ENA & 0x3); + } + + /* I/O interrupt requested by device. */ + args.event |= SDMMC_EVENT_SDIO; + + /* Call user callback */ + if (p_ctrl->initialized) + { + r_sdemmc_call_callback(p_ctrl, &args); + } + + /* Clear interrupt flags */ + p_ctrl->p_reg->SDIO_GLB_INT_STS_REG = SDEMMC_W_PRV_SDIO_INFO1_IRQ_CLEAR; + + #if BSP_FEATURE_BSP_HAS_ICU + + /* Clear the IR flag in the ICU */ + /* Clearing the IR bit must be done after clearing the interrupt source in the the peripheral */ + R_BSP_IrqStatusClear(irq); + #endif /* BSP_FEATURE_BSP_HAS_ICU */ + + /* Restore context if RTOS is used */ + FSP_CONTEXT_RESTORE; +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ +} + +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + +static void r_sdemmc_handle_interrupt_fn0 (sdemmc_w_instance_ctrl_t * p_ctrl) +{ + uint32_t status = 0; + uint32_t mask = 0; + + /* Read the AHB FN0 INT Register */ + status = p_ctrl->p_reg->SDIO_AHB_FN0_INT_REG; + + if (SDEMMC_W_AHBSOFT_RST == (status & SDEMMC_W_AHBSOFT_RST)) /* Check soft reset interrupt */ + { + /* Clear the AHBSOFT_RST INTerrupt. Write 1 to clear the INTerrupt */ + status = p_ctrl->p_reg->SDIO_AHB_FN0_INT_REG; + p_ctrl->p_reg->SDIO_AHB_FN0_INT_REG = (status | SDEMMC_W_AHBSOFT_RST); + p_ctrl->p_reg->SDIO_SOFT_RST_AHB_REG = (SDEMMC_W_VALUE_SOFT_RST_AHB & 0x1); + } + + if (SDEMMC_W_VOLT_SWITCH_CMD == (status & SDEMMC_W_VOLT_SWITCH_CMD)) /* Check volt switch cmd interrupt */ + { + mask = p_ctrl->p_reg->SDIO_UHS_SUPPORT_REG; + mask = mask | (SDEMMC_W_CARD_VOLT_ACCEPT); + p_ctrl->p_reg->SDIO_UHS_SUPPORT_REG = mask; + + /* Clear the VOLT_SWITCH_CMD INTerrupt. Write 1 to clear the INTerrupt */ + status = p_ctrl->p_reg->SDIO_AHB_FN0_INT_REG; + p_ctrl->p_reg->SDIO_AHB_FN0_INT_REG = (status | SDEMMC_W_VOLT_SWITCH_CMD); + } +} + +static void r_sdemmc_handle_interrupt_fn1 (sdemmc_w_instance_ctrl_t * p_ctrl, sdmmc_callback_args_t * p_args) +{ + uint32_t status = 0; + uint32_t mask = 0; + uint32_t blksize = 0; + uint32_t mul_blk = 0; + uint32_t b_blk_cnt = 0; + uint32_t length = 0; + + /* Read the AHB FN1 INT Register */ + status = p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG; + + if (SDEMMC_W_FN1_WR_OVR == (status & SDEMMC_W_FN1_WR_OVR)) /* Check for fn1 wr over interrupt */ + { + p_ctrl->result.sdio_blk_or_byte = + p_ctrl->p_reg->SDIO_BLKSIZE_REG_b.SIN_MUL_BLK; + p_ctrl->result.sdio_blk_size = + p_ctrl->p_reg->SDIO_BLKSIZE_REG_b.BLK_SIZE; + p_ctrl->result.sdio_blk_count = + p_ctrl->p_reg->SDIO_WRBLKCNT_REG_b.WR_BLK_CNT; + + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_WR_OVR); + p_ctrl->p_reg->SDIO_WRBLKCNT_REG = 0; + p_args->event |= SDEMMC_W_PRIV_EVENT_SDIO_FN1_WR_OVR; + } + + if (SDEMMC_W_FN1_RD_OVR == (status & SDEMMC_W_FN1_RD_OVR)) /* Check for fn1 rd over interrupt */ + { + p_ctrl->result.sdio_blk_or_byte = + p_ctrl->p_reg->SDIO_BLKSIZE_REG_b.SIN_MUL_BLK; + p_ctrl->result.sdio_blk_size = + p_ctrl->p_reg->SDIO_BLKSIZE_REG_b.BLK_SIZE; + p_ctrl->result.sdio_blk_count = + p_ctrl->p_reg->SDIO_RDBLKCNT_REG_b.RD_BLK_CNT; + + /* Clear the fn1_rd_ovr INTerrupt. Write 1 to clear the INTerrupt */ + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_RD_OVR); + p_ctrl->p_reg->SDIO_RDBLKCNT_REG = 0; + p_args->event |= SDEMMC_W_PRIV_EVENT_SDIO_FN1_RD_OVR; + } + + if (SDEMMC_W_FN1_RD_ERROR == (status & SDEMMC_W_FN1_RD_ERROR)) + { + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_RD_ERROR); + } + + if (SDEMMC_W_FN1_RST == (status & SDEMMC_W_FN1_RST)) + { + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_RST); + } + + if (SDEMMC_W_FN1_MSG_RDY == (status & SDEMMC_W_FN1_MSG_RDY)) /* Check for sd host fn1 msg ready interrupt */ + { + /* Read the sd host general purpose register */ + mask = p_ctrl->p_reg->SDIO_SD_HOST_GP_REG; + + /* Clear the sdhost fn1 msg ready interrupt. Write 1 to clear the interrupt */ + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_MSG_RDY); + p_args->event |= SDEMMC_W_PRIV_EVENT_SDIO_FN1_MSG_RDY; + } + + if (SDEMMC_W_FN1_ACK_TO_ARM == (status & SDEMMC_W_FN1_ACK_TO_ARM)) + { + /* Clear the fn1 ack to arm interrupt. Write 1 to clear the interrupt */ + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_ACK_TO_ARM); + p_args->event |= SDEMMC_W_PRIV_EVENT_SDIO_FN1_ACK_TO_ARM; + } + + if (SDEMMC_W_FN1_SDIO_RD_STRT == (status & SDEMMC_W_FN1_SDIO_RD_STRT)) /* Check fn1 sdio rd start interrupt */ + { + /* Reading blksize Register */ + mask = p_ctrl->p_reg->SDIO_BLKSIZE_REG; + blksize = (mask & SDEMMC_W_BLKSIZE_MASK); + mul_blk = (mask >> SDEMMC_W_MUL_BLK_SHIFT); + + /* Reading Argument Register */ + mask = p_ctrl->p_reg->SDIO_ARGUMENT_REG; + b_blk_cnt = (mask & SDEMMC_W_B_BLK_CNT_MASK); + + /* Calculating the data length */ + if (1 == mul_blk) + { + length = b_blk_cnt * blksize; + } + else + { + if (0 == b_blk_cnt) + { + b_blk_cnt = SDEMMC_W_PRV_SDIO_EXT_MAX_BYTES; + } + + length = b_blk_cnt; + } + + r_sdemmc_host_read(p_ctrl, length); + + /* Clear the fn1_sdio_rd_strt INTerrupt. Write 1 to clear the INTerrupt */ + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_SDIO_RD_STRT); + } + + if (SDEMMC_W_FN1_SDIO_WR_STRT == (status & SDEMMC_W_FN1_SDIO_WR_STRT)) /* Check for fn1 wr strt interrupt */ + { + /* Reading Blksize Register */ + mask = p_ctrl->p_reg->SDIO_BLKSIZE_REG; + blksize = (mask & SDEMMC_W_BLKSIZE_MASK); + mul_blk = (mask >> SDEMMC_W_MUL_BLK_SHIFT); + + /* Reading Argument Register */ + mask = p_ctrl->p_reg->SDIO_ARGUMENT_REG; + b_blk_cnt = (mask & SDEMMC_W_B_BLK_CNT_MASK); + + /* Calculating the data length */ + if (mul_blk == 1) + { + length = b_blk_cnt * blksize; + } + else + { + if (0 == b_blk_cnt) + { + b_blk_cnt = SDEMMC_W_PRV_SDIO_EXT_MAX_BYTES; + } + + length = b_blk_cnt; + } + + r_sdemmc_host_write(p_ctrl, length); + + /* Clear the fn1_sdio_wr_strt INTerrupt. Write 1 to clear the interrupt */ + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_SDIO_WR_STRT); + } + + if (SDEMMC_W_FN1_ADMA_END == (status & SDEMMC_W_FN1_ADMA_END)) /* Check for fn1_adma_end_bit interrupt */ + { + /* Update the new System Address */ + /* sets the dummy descriptor */ + r_sdemmc_adma_dummy(p_ctrl); + + /* Clear the fn1_adma_end INTerrupt. Write 1 to clear the INTerrupt */ + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_ADMA_END); + } + + if (SDEMMC_W_FN1_SUSPEND == (status & SDEMMC_W_FN1_SUSPEND)) + { + /* Clear the fn1 ack to arm interrupt. Write 1 to clear the interrupt */ + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_SUSPEND); + } + + if (SDEMMC_W_FN1_RESUME == (status & SDEMMC_W_FN1_RESUME)) + { + /* Clear the fn1 ack to arm interrupt. Write 1 to clear the interrupt */ + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_RESUME); + } + + if (SDEMMC_W_FN1_ADMA_INT == (status & SDEMMC_W_FN1_ADMA_INT)) + { + /* Clear the fn1 ack to arm interrupt. Write 1 to clear the interrupt */ + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_ADMA_INT); + } + + if (SDEMMC_W_FN1_ADMA_ERR == (status & SDEMMC_W_FN1_ADMA_ERR)) + { + r_sdemmc_adma_dummy(p_ctrl); + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_ADMA_ERR); + } + + if (SDEMMC_W_FN1_READY == (status & SDEMMC_W_FN1_READY)) + { + /* Clear the fn1 ack to arm interrupt. Write 1 to clear the interrupt */ + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_FN1_READY); + } +} + +/* this function is called after ADMA done */ +static void r_sdemmc_adma_dummy (sdemmc_w_instance_ctrl_t * p_ctrl) +{ + volatile sdio_device_dma_config dummy_dma_config; + dummy_dma_config.sdio_dma_length = (SDEMMC_W_DUMMY_DESC_LEN << 16) | SDEMMC_W_ATTRIBUTE_DUMMY_DESC; + + /* Update the fetch address in ADMA System Address register */ + p_ctrl->p_reg->SDIO_ADMA_SYSTEM_ADDRESS_REG = (uint32_t) (&dummy_dma_config) | 0x20000000; +} + +static void r_sdemmc_host_read (sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t host_length) +{ + uint32_t device_length; + uint32_t attribute = SDEMMC_W_ATTRIBUTE; + + device_length = (((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->dma_config_tx.sdio_dma_length >> 16) & + 0x0000FFFF; + if (host_length <= device_length) + { + device_length = host_length; + } + else + { + attribute = SDEMMC_W_ATTRIBUTE_TRANS_ERROR; + } + + ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->dma_config_tx.sdio_dma_length = (device_length << 16) | + attribute; + p_ctrl->p_reg->SDIO_AHB_TRANSCOUNT_REG = device_length; + + /* Update the fetch address in ADMA System Address register */ + p_ctrl->p_reg->SDIO_ADMA_SYSTEM_ADDRESS_REG = + (uint32_t) (&((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->dma_config_tx) | 0x20000000; + + if (attribute == SDEMMC_W_ATTRIBUTE_TRANS_ERROR) + { + r_sdemmc_adma_dummy(p_ctrl); + } +} + +static void r_sdemmc_host_write (sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t host_length) +{ + uint32_t device_length; + uint32_t attribute = SDEMMC_W_ATTRIBUTE; + + device_length = + (uint16_t) (((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->dma_config_rx.sdio_dma_length >> 16); + if (host_length <= device_length) + { + device_length = host_length; + } + else + { + attribute = SDEMMC_W_ATTRIBUTE_TRANS_ERROR; + } + + ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->dma_config_rx.sdio_dma_length = (device_length << 16) | + attribute; + + /* Update the fetch address in ADMA System Address register */ + p_ctrl->p_reg->SDIO_ADMA_SYSTEM_ADDRESS_REG = + (uint32_t) (&((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->dma_config_rx) | 0x20000000; +} + +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + +static void r_sdemmc_hw_sdemmc_renable_prepare (sdemmc_w_instance_ctrl_t * p_ctrl) +{ + g_DataTransferWidth = p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.DataTransferWidth; + g_ExtendedDataTransferWidth = p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.ExtendedDataTransferWidth; + g_SDCLKFrequencySelect = p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDCLKFrequencySelect; + g_DriveStrengthSelect = p_ctrl->p_reg_mmc->SDEMMC_AUTOCMDERRORSTATUS_REG_b.DriveStrengthSelect; +} + +static void r_sdemmc_hw_sdemmc_renable (sdemmc_w_instance_ctrl_t * p_ctrl) +{ + volatile uint8_t rdata = 0; + + CRG_PER->SET_CLK_COM_REG_b.SDEMMC_ENABLE = 1U; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SoftwareResetForAll = 1; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SoftwareResetForAll = 0; + + while (0x0F00 != (p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG & 0xF00)) + { + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG |= 0x0F00; + } + + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.HardwareRst = 1; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.HardwareRst = 0; + + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.SpiMode = 0; + + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.LEDControl = 0; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.DataTransferWidth = (g_DataTransferWidth & + SDEMMC_W_1BIT_MASK); + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.HighSpeedEnable = 0; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.DMASelect = 0; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.ExtendedDataTransferWidth = (g_ExtendedDataTransferWidth & + SDEMMC_W_1BIT_MASK); + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.CardDetectTestLevel = 0; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.CardDetectSignalSelection = 0; + + p_ctrl->p_reg_mmc->SDEMMC_VENDOR_REG_b.AutoGateSDCLK = 1; + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.InternalClockEnable = 1; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDCLKFrequencySelect = (uint8_t) g_SDCLKFrequencySelect; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.UpperBitsofSDCLKFrequencySelect = 0; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.ClockGeneratorSelect = 1; + + /* increase drive strength to 12mA */ + p_ctrl->p_reg_mmc->SDEMMC_AUTOCMDERRORSTATUS_REG_b.DriveStrengthSelect = (g_DriveStrengthSelect & + SDEMMC_W_2BIT_MASK); + + do + { + rdata = p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.InternalClockStable; + } while (0 == rdata); +} + +static void r_sdemmc_hw_sdemmc_enable (sdemmc_w_instance_ctrl_t * p_ctrl) +{ + uint8_t rdata = 0; + + CRG_PER->SET_CLK_COM_REG_b.SDEMMC_ENABLE = 1U; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SoftwareResetForAll = 1; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SoftwareResetForAll = 0; + + while (0x0F00 != (p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG & 0xF00)) + { + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG |= 0x0F00; + } + + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.HardwareRst = 1; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.HardwareRst = 0; + + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.SpiMode = 0; + + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.LEDControl = 0; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.DataTransferWidth = SDEMMC_W_SDEMMC_DT_WIDTH_1BIT; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.HighSpeedEnable = 0; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.DMASelect = 0; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.ExtendedDataTransferWidth = 0; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.CardDetectTestLevel = 0; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.CardDetectSignalSelection = 0; + + p_ctrl->p_reg_mmc->SDEMMC_VENDOR_REG_b.AutoGateSDCLK = 1; + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.InternalClockEnable = 1; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDCLKFrequencySelect = SDEMMC_W_PRV_SD_CLK_CTRL_DEFAULT; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.UpperBitsofSDCLKFrequencySelect = 0; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.ClockGeneratorSelect = 1; + + /* increase drive strength to 12mA */ + p_ctrl->p_reg_mmc->SDEMMC_AUTOCMDERRORSTATUS_REG_b.DriveStrengthSelect = 0; + + do + { + rdata = p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.InternalClockStable; + } while (0 == rdata); +} + +static void r_sdemmc_hw_sdemmc_disable (sdemmc_w_instance_ctrl_t * p_ctrl) +{ + CRG_PER->SET_CLK_COM_REG_b.SDEMMC_ENABLE = 1U; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SoftwareResetForAll = 1; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.HardwareRst = 1; +} + +static void r_sdemmc_sdemmc_interrupt_enable (sdemmc_w_instance_ctrl_t * p_ctrl) +{ + while (1 != p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb) + { + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + } + + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.TransferCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.TransferCompleteStatusEnb = 1; + + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.DataTimeoutErrorSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.DataTimeoutErrorStatusEnb = 1; + + /* Configure card detection. */ + if (SDMMC_CARD_DETECT_CD == p_ctrl->p_cfg->card_detect) + { + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CardInterruptSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CardInterruptStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CardInsertionSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CardInsertionStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CardRemovalSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CardRemovalStatusEnb = 1; + } + + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCRCErrorSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCRCErrorStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandTimeoutErrorSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandTimeoutErrorStatusEnb = 1; +} + +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + +static void r_sdemmc_hw_sdio_device_init (sdemmc_w_instance_ctrl_t * p_ctrl) +{ + GPIO->SDIO_MODE_REG_b.CFG_DRV = ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->drive_current; + CRG_PER->SET_CLK_COM_REG_b.SDIO_ENABLE = 1U; + memcpy((void *) SDEMMC_W_CIS0_AHB_ADDR, (const void *) gs_sdio_b_cis0_data, sizeof(gs_sdio_b_cis0_data)); + memcpy((void *) SDEMMC_W_CIS1_AHB_ADDR, (const void *) gs_sdio_b_cis1_data, sizeof(gs_sdio_b_cis1_data)); + + p_ctrl->p_reg->SDIO_SOFT_RST_AHB_REG_b.AHBSOFT_VALID = 0x1U; + p_ctrl->p_reg->SDIO_SOFT_RST_AHB_REG_b.AHBSOFT_VALID = 0x0U; + + /* Program the CCCR Register */ + p_ctrl->p_reg->SDIO_CCCR_REG = (((SDEMMC_W_SHS & 0x1) << 21) | ((SDEMMC_W_SMPC & 0x1) << 20) | + ((SDEMMC_W_BLS & 0x1) << 19) | ((SDEMMC_W_LSC & 0x1) << 18) | + ((SDEMMC_W_S4MI & 0x1) << 17) | ((SDEMMC_W_SBS & 0x1) << 16) | + ((SDEMMC_W_SRW & 0x1) << 15) | ((SDEMMC_W_SMB & 0x1) << 14) | + ((SDEMMC_W_SDC & 0x1) << 13) | ((SDEMMC_W_SCSI & 0x1) << 12) | + (((SDEMMC_W_SD_PHY_SPEC) & 0xF) << 8) | + (((SDEMMC_W_SDIO_REV) & 0xF) << 4) | ((SDEMMC_W_CCCR_REV) & 0xF)); + + /* Program the OCR(For Function1) Register */ + p_ctrl->p_reg->SDIO_OCR_REG = (SDEMMC_W_VALUE_OCR & 0xFFFFFF); + + /* Program the GLB_INT_ENA Register */ + p_ctrl->p_reg->SDIO_GLB_INT_ENA_REG = (SDEMMC_W_VALUE_GLB_INT_ENA & 0x3); + + /* Program the AHB_FN0_INT_ENABLE */ + p_ctrl->p_reg->SDIO_AHB_FN0_INT_ENABLE_REG = (SDEMMC_W_VALUE_AHB_FN0_INT_ENA & 0x0003); + + /* Program the AHB_FN0_INT_STS_ENABLE */ + p_ctrl->p_reg->SDIO_AHB_FN0_INT_REG = (SDEMMC_W_VALUE_AHB_FN0_INT_ENA & 0x0003); + + /* Program the AHB_FN1_INT_ENABLE */ + p_ctrl->p_reg->SDIO_AHB_FN1_INT_ENABLE_REG = (SDEMMC_W_VALUE_AHB_FN1_INT_ENA & 0x11C3); + + /* Program the AHB_FN1_INT_STS_ENABLE */ + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = (SDEMMC_W_VALUE_AHB_FN1_INT_ENA & 0x11C3); + + /* Program the FBR Register - For Function1 */ + p_ctrl->p_reg->SDIO_FBR_REG = (SDEMMC_W_VALUE_FBR & 0x3FFF); + + /* Program the IOR Register - For Function1 */ + p_ctrl->p_reg->SDIO_IOR_REG = (SDEMMC_W_VALUE_IOR & 0x1); + + /* Program the GLB_INT_STS Register - For Function0/1 */ + p_ctrl->p_reg->SDIO_GLB_INT_STS_REG = (SDEMMC_W_VALUE_INT_COND & 0x3); + + /* Program the FUNRDY - to indicate card is readt to operate */ + p_ctrl->p_reg->SDIO_FUNRDY_REG = (SDEMMC_W_VALUE_FUNRDY & 0x1); +} + +static uint32_t r_sdemmc_hw_sdio_device_rx (sdemmc_w_instance_ctrl_t * p_ctrl, uint8_t * data, uint32_t length) +{ + ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->dma_config_rx.sdio_dma_length = + (length << 16) | SDEMMC_W_ATTRIBUTE; + ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->dma_config_rx.sdio_dma_buf_address = (uint32_t) data; + + return FSP_SUCCESS; +} + +static uint32_t r_sdemmc_hw_sdio_device_tx (sdemmc_w_instance_ctrl_t * p_ctrl, const uint8_t * data, uint32_t length) +{ + /* Program the AHB transfer count register */ + p_ctrl->p_reg->SDIO_AHB_TRANSCOUNT_REG = (length & 0x1FFFFF); + + /* Program the Read data ready register */ + p_ctrl->p_reg->SDIO_RDDATRDY_REG = SDEMMC_W_FN1_RD_DAT_RDY; + + ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->dma_config_tx.sdio_dma_length = + (length << 16) | SDEMMC_W_ATTRIBUTE; + ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->dma_config_tx.sdio_dma_buf_address = (uint32_t) data; + + return FSP_SUCCESS; +} + +static void r_sdemmc_hw_sdio_device_deinit (sdemmc_w_instance_ctrl_t * p_ctrl) +{ + CRG_PER->SET_CLK_COM_REG_b.SDIO_ENABLE = 1U; + p_ctrl->p_reg->SDIO_SOFT_RST_AHB_REG_b.AHBSOFT_VALID = 0x1U; + p_ctrl->p_reg->SDIO_SOFT_RST_AHB_REG_b.AHBSOFT_VALID = 0x0U; +} + +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + +static fsp_err_t r_sdemmc_sdemmc_wait_for_complete_interrupt (sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t * resp) +{ + uint32_t timeout = UINT16_MAX; + + while ((0 == p_ctrl->sdemmc_w_event.bit.response_end) && + (0 == p_ctrl->sdemmc_w_event.bit.CommandTimeoutError) && + (0 == p_ctrl->sdemmc_w_event.bit.crc_err)) + { + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + timeout--; + + if ((0 == timeout) || (p_ctrl->sdemmc_w_event.bit.CommandTimeoutError) || (p_ctrl->sdemmc_w_event.bit.crc_err)) + { + r_sdemmc_hw_sdemmc_renable_prepare(p_ctrl); + CRG_PER->SET_CLK_COM_REG_b.SDEMMC_ENABLE = 1U; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SoftwareResetForAll = 1; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.HardwareRst = 1; + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + r_sdemmc_hw_sdemmc_renable(p_ctrl); + r_sdemmc_sdemmc_interrupt_enable(p_ctrl); + + FSP_RETURN(FSP_ERR_TIMEOUT); + } + } + + if (NULL != resp) + { + *resp = p_ctrl->p_reg_mmc->SDEMMC_RESPONSE0_REG; + } + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_sdemmc_wait_for_transfer_interrupt (sdemmc_w_instance_ctrl_t * p_ctrl) +{ + uint32_t timeout = UINT16_MAX; + + while ((0 == p_ctrl->sdemmc_w_event.bit.access_end) && + (0 == p_ctrl->sdemmc_w_event.bit.dto) && + (0 == p_ctrl->sdemmc_w_event.bit.CommandTimeoutError) && + (0 == p_ctrl->sdemmc_w_event.bit.crc_err)) + { + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + timeout--; + + if (0 == timeout) + { + r_sdemmc_hw_sdemmc_renable_prepare(p_ctrl); + CRG_PER->SET_CLK_COM_REG_b.SDEMMC_ENABLE = 1U; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SoftwareResetForAll = 1; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.HardwareRst = 1; + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + r_sdemmc_hw_sdemmc_renable(p_ctrl); + r_sdemmc_sdemmc_interrupt_enable(p_ctrl); + + FSP_RETURN(FSP_ERR_TIMEOUT); + } + } + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_sdemmc_wait_write_done (sdemmc_w_instance_ctrl_t * p_ctrl) +{ + uint32_t timeout = UINT16_MAX; + + while (0xF != p_ctrl->p_reg_mmc->SDEMMC_PRESENTSTATE_REG_b.DAT3TO0LineSignalLevel) + { + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + timeout--; + + if (0 == timeout) + { + r_sdemmc_hw_sdemmc_renable_prepare(p_ctrl); + CRG_PER->SET_CLK_COM_REG_b.SDEMMC_ENABLE = 1U; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SoftwareResetForAll = 1; + p_ctrl->p_reg_mmc->SDEMMC_HOST_CTRL_1_REG_b.HardwareRst = 1; + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + r_sdemmc_hw_sdemmc_renable(p_ctrl); + r_sdemmc_sdemmc_interrupt_enable(p_ctrl); + + FSP_RETURN(FSP_ERR_TIMEOUT); + } + } + + return FSP_SUCCESS; +} + +#if (SDEMMC_W_CFG_SD_SUPPORT_ENABLE | SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) + +static void r_sdemmc_emmc_cmd_without_res (sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t cmd, uint32_t cmd_arg) +{ + uint32_t transfer_reg = 0; + + /* Clear Status */ + p_ctrl->sdemmc_w_event.word = 0U; + p_ctrl->p_reg_mmc->SDEMMC_SDMA_SYS_ADDR__ARGU_2_REG = 0; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize = 0; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.HostSDMABufferBoundry = 7; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.BlockCountForCurrentTransfer = 0; + g_BlockCountForCurrentTransfer = 0; + p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG = cmd_arg; + + /* Enable response end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + + transfer_reg = cmd << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos; + p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG = transfer_reg; + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDClockEnable = 1; + + r_sdemmc_sdemmc_wait_for_complete_interrupt(p_ctrl, NULL); +} + +#endif /* (SDEMMC_W_CFG_SD_SUPPORT_ENABLE | SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) */ + +static fsp_err_t r_sdemmc_emmc_cmd_with_res (sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * rsp) +{ + fsp_err_t err = FSP_SUCCESS; + uint32_t transfer_reg = 0; + uint32_t check_option = 0; + + /* Clear Status */ + p_ctrl->sdemmc_w_event.word = 0U; + p_ctrl->p_reg_mmc->SDEMMC_SDMA_SYS_ADDR__ARGU_2_REG = 0; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize = 0; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.HostSDMABufferBoundry = 7; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.BlockCountForCurrentTransfer = 0; + g_BlockCountForCurrentTransfer = 0; + p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG = cmd_arg; + + /* Enable response end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + + switch (SDEMMC_W_GET_CMD_RESP_TYPE(cmd)) + { + case SDEMMC_W_SDIO_NO_RESPONSE: + case SDEMMC_W_SDIO_SHORT_RESPONSE: + { + check_option = 0; + break; + } + + case SDEMMC_W_SDIO_LONG_RESPONSE: + { + check_option = SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk; + break; + } + + case 3: + case 4: + { + check_option = SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndexCheckEnable_Msk; + break; + } + + default: + { + FSP_RETURN(FSP_ERR_INVALID_ARGUMENT); + } + } + + transfer_reg = (uint32_t) (cmd << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos) | + (uint32_t) (SDEMMC_W_GET_CMD_RESP_TYPE(cmd) << + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_ResponseTypeSelect_Pos) | + check_option; + p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG = transfer_reg; + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDClockEnable = 1; + + err = r_sdemmc_sdemmc_wait_for_complete_interrupt(p_ctrl, rsp); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + if (SDEMMC_W_SDIO_LONG_RESPONSE == SDEMMC_W_GET_CMD_RESP_TYPE(cmd)) + { + uint32_t temp_rsp[4]; + temp_rsp[0] = p_ctrl->p_reg_mmc->SDEMMC_RESPONSE3_REG; + temp_rsp[1] = p_ctrl->p_reg_mmc->SDEMMC_RESPONSE2_REG; + temp_rsp[2] = p_ctrl->p_reg_mmc->SDEMMC_RESPONSE1_REG; + temp_rsp[3] = p_ctrl->p_reg_mmc->SDEMMC_RESPONSE0_REG; + rsp[0] = temp_rsp[0] << 8 | ((temp_rsp[1] & 0xff000000) >> 24); + rsp[1] = temp_rsp[1] << 8 | ((temp_rsp[2] & 0xff000000) >> 24); + rsp[2] = temp_rsp[2] << 8 | ((temp_rsp[3] & 0xff000000) >> 24); + rsp[3] = temp_rsp[3] << 8; + } + + return FSP_SUCCESS; +} + +#if (SDEMMC_W_CFG_SD_SUPPORT_ENABLE | SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) + +static fsp_err_t r_sdemmc_emmc_single_read_data_with_wait (sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t blk_size, + uint32_t * p_rsp, + uint8_t * p_buf) +{ + fsp_err_t err = FSP_SUCCESS; + uint32_t transfer_reg = 0; + + /* Clear Status */ + p_ctrl->sdemmc_w_event.word = 0U; + + p_ctrl->p_reg_mmc->SDEMMC_SDMA_SYS_ADDR__ARGU_2_REG = (uint32_t) p_buf; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize = blk_size & SDEMMC_W_12BIT_MASK; + + /* + * 000b - 4KB(Detects A11 Carry out) + * 001b - 8KB(Detects A12 Carry out) + * 010b - 16KB(Detects A13 Carry out) + * 011b - 32KB(Detects A14 Carry out) + * 100b - 64KB(Detects A15 Carry out) + * 101b - 128KB(Detects A16 Carry out) + * 110b - 256KB(Detects A17 Carry out) + * 111b - 512KB(Detects A18 Carry out) + */ + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.HostSDMABufferBoundry = 7; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.BlockCountForCurrentTransfer = 1; + g_BlockCountForCurrentTransfer = 1; + p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG = cmd_arg; + + /* Enable response end interrupt and access end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.TransferCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.TransferCompleteStatusEnb = 1; + + transfer_reg = cmd << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataPresentSelect_Msk | + (uint32_t) (SDEMMC_W_GET_CMD_RESP_TYPE(cmd) << + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_ResponseTypeSelect_Pos) | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndexCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataTransferDirectionSelect_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DMAEnable_Msk; + p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG = transfer_reg; + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDClockEnable = 1; + err = r_sdemmc_sdemmc_wait_for_complete_interrupt(p_ctrl, p_rsp); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_sdemmc_wait_for_transfer_interrupt(p_ctrl); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_sdemmc_wait_write_done(p_ctrl); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_emmc_single_read_data (sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t blk_size, + uint32_t * p_rsp, + uint8_t * p_buf) +{ + FSP_PARAMETER_NOT_USED(p_rsp); + uint32_t transfer_reg = 0; + + /* Clear Status */ + p_ctrl->sdemmc_w_event.word = 0U; + + p_ctrl->p_reg_mmc->SDEMMC_SDMA_SYS_ADDR__ARGU_2_REG = (uint32_t) p_buf; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize = blk_size & SDEMMC_W_12BIT_MASK; + + /* + * 000b - 4KB(Detects A11 Carry out) + * 001b - 8KB(Detects A12 Carry out) + * 010b - 16KB(Detects A13 Carry out) + * 011b - 32KB(Detects A14 Carry out) + * 100b - 64KB(Detects A15 Carry out) + * 101b - 128KB(Detects A16 Carry out) + * 110b - 256KB(Detects A17 Carry out) + * 111b - 512KB(Detects A18 Carry out) + */ + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.HostSDMABufferBoundry = 7; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.BlockCountForCurrentTransfer = 1; + g_BlockCountForCurrentTransfer = 1; + p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG = cmd_arg; + + /* Enable response end interrupt and access end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.TransferCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.TransferCompleteStatusEnb = 1; + + transfer_reg = cmd << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataPresentSelect_Msk | + (uint32_t) (SDEMMC_W_GET_CMD_RESP_TYPE(cmd) << + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_ResponseTypeSelect_Pos) | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndexCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataTransferDirectionSelect_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DMAEnable_Msk; + p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG = transfer_reg; + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDClockEnable = 1; + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_emmc_multi_read_data (sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp, + uint8_t * p_buf, + uint32_t block_count) +{ + uint32_t ret_rsp = 0; + uint32_t transfer_reg = 0; + fsp_err_t err = FSP_SUCCESS; + + /* Clear Status */ + p_ctrl->sdemmc_w_event.word = 0U; + + p_ctrl->p_reg_mmc->SDEMMC_SDMA_SYS_ADDR__ARGU_2_REG = (uint32_t) p_buf; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize = 512; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.HostSDMABufferBoundry = 7; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.BlockCountForCurrentTransfer = (uint16_t) block_count; + g_BlockCountForCurrentTransfer = block_count; + + p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG = cmd_arg; + + /* Enable response end interrupt and access end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.TransferCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.TransferCompleteStatusEnb = 1; + + transfer_reg = cmd << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataPresentSelect_Msk | + (uint32_t) (SDEMMC_W_GET_CMD_RESP_TYPE(cmd) << + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_ResponseTypeSelect_Pos) | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndexCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_MultiSingleBlockSelect_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataTransferDirectionSelect_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_BlockCountEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DMAEnable_Msk; + p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG = transfer_reg; + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDClockEnable = 1; + err = r_sdemmc_sdemmc_wait_for_complete_interrupt(p_ctrl, p_rsp); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_sdemmc_wait_for_transfer_interrupt(p_ctrl); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_STOP_TRANSM, 0, &ret_rsp); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_emmc_block_read_data (sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp, + uint8_t * p_buf, + uint32_t block_count) +{ + FSP_PARAMETER_NOT_USED(p_rsp); + uint32_t ret_rsp = 0; + uint32_t transfer_reg = 0; + fsp_err_t err = FSP_SUCCESS; + int32_t i = 0; + + /* send CMD23 */ + for (i = 0; i < SDEMMC_W_PRV_MMC_RETRY_COUNT; i++) + { + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SET_BLK_CNT, (block_count & 0x0000ffff), &ret_rsp); + + if ((!err) && !(ret_rsp & 0xfff80000)) + { + break; + } + } + + if (SDEMMC_W_PRV_MMC_RETRY_COUNT == i) + { + FSP_RETURN(FSP_ERR_WRITE_FAILED); + } + + /* Clear Status */ + p_ctrl->sdemmc_w_event.word = 0U; + + p_ctrl->p_reg_mmc->SDEMMC_SDMA_SYS_ADDR__ARGU_2_REG = (uint32_t) p_buf; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize = 512; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.HostSDMABufferBoundry = 7; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.BlockCountForCurrentTransfer = (uint16_t) block_count; + g_BlockCountForCurrentTransfer = block_count; + p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG = cmd_arg; + + /* Enable response end interrupt and access end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.TransferCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.TransferCompleteStatusEnb = 1; + + transfer_reg = cmd << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataPresentSelect_Msk | + (uint32_t) (SDEMMC_W_GET_CMD_RESP_TYPE(cmd) << + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_ResponseTypeSelect_Pos) | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndexCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_MultiSingleBlockSelect_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataTransferDirectionSelect_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_BlockCountEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DMAEnable_Msk; + p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG = transfer_reg; + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDClockEnable = 1; + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_emmc_single_write_data (sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t blk_size, + uint32_t * p_rsp, + uint8_t * p_buf) +{ + FSP_PARAMETER_NOT_USED(p_rsp); + uint32_t transfer_reg = 0; + + /* Clear Status */ + p_ctrl->sdemmc_w_event.word = 0U; + + p_ctrl->p_reg_mmc->SDEMMC_SDMA_SYS_ADDR__ARGU_2_REG = (uint32_t) p_buf; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize = blk_size & SDEMMC_W_12BIT_MASK; + + /* + * 000b - 4KB(Detects A11 Carry out) + * 001b - 8KB(Detects A12 Carry out) + * 010b - 16KB(Detects A13 Carry out) + * 011b - 32KB(Detects A14 Carry out) + * 100b - 64KB(Detects A15 Carry out) + * 101b -128KB(Detects A16 Carry out) + * 110b - 256KB(Detects A17 Carry out) + * 111b - 512KB(Detects A18 Carry out) + */ + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.HostSDMABufferBoundry = 7; + + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.BlockCountForCurrentTransfer = 1; + g_BlockCountForCurrentTransfer = 1; + p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG = cmd_arg; + + /* Enable response end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.TransferCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.TransferCompleteStatusEnb = 1; + + transfer_reg = cmd << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataPresentSelect_Msk | + (uint32_t) (SDEMMC_W_GET_CMD_RESP_TYPE(cmd) << + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_ResponseTypeSelect_Pos) | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndexCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DMAEnable_Msk; + p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG = transfer_reg; + + SDEMMC->SDEMMC__CLK__CTRL__REG_b.SDClockEnable = 1; + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_emmc_multi_write_data (sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp, + uint8_t * p_buf, + uint32_t block_count) +{ + uint32_t ret_rsp = 0; + uint32_t transfer_reg = 0; + fsp_err_t err = FSP_SUCCESS; + + /* Clear Status */ + p_ctrl->sdemmc_w_event.word = 0U; + + p_ctrl->p_reg_mmc->SDEMMC_SDMA_SYS_ADDR__ARGU_2_REG = (uint32_t) p_buf; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize = 512; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.HostSDMABufferBoundry = 7; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.BlockCountForCurrentTransfer = (uint16_t) block_count; + g_BlockCountForCurrentTransfer = block_count; + + p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG = cmd_arg; + + /* Enable response end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.TransferCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.TransferCompleteStatusEnb = 1; + + transfer_reg = cmd << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataPresentSelect_Msk | + (uint32_t) (SDEMMC_W_GET_CMD_RESP_TYPE(cmd) << + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_ResponseTypeSelect_Pos) | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndexCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_MultiSingleBlockSelect_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_BlockCountEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DMAEnable_Msk; + p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG = transfer_reg; + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDClockEnable = 1; + err = r_sdemmc_sdemmc_wait_for_complete_interrupt(p_ctrl, p_rsp); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_sdemmc_wait_for_transfer_interrupt(p_ctrl); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_STOP_TRANSM, 0, &ret_rsp); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_sdemmc_wait_write_done(p_ctrl); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_emmc_block_write_data (sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp, + uint8_t * p_buf, + uint32_t block_count) +{ + FSP_PARAMETER_NOT_USED(p_rsp); + uint32_t ret_rsp = 0; + uint32_t transfer_reg = 0; + fsp_err_t err = FSP_SUCCESS; + int32_t i = 0; + + /* send CMD23 */ + for (i = 0; i < SDEMMC_W_PRV_MMC_RETRY_COUNT; i++) + { + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SET_BLK_CNT, (block_count & 0x0000ffff), &ret_rsp); + + if ((!err) && !(ret_rsp & 0xfff80000)) + { + break; + } + } + + if (SDEMMC_W_PRV_MMC_RETRY_COUNT == i) + { + FSP_RETURN(FSP_ERR_WRITE_FAILED); + } + + /* Clear Status */ + p_ctrl->sdemmc_w_event.word = 0U; + + p_ctrl->p_reg_mmc->SDEMMC_SDMA_SYS_ADDR__ARGU_2_REG = (uint32_t) p_buf; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize = 512; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.HostSDMABufferBoundry = 7; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.BlockCountForCurrentTransfer = (uint16_t) block_count; + g_BlockCountForCurrentTransfer = block_count; + p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG = cmd_arg; + + /* Enable response end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.TransferCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.TransferCompleteStatusEnb = 1; + + transfer_reg = cmd << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataPresentSelect_Msk | + (uint32_t) (SDEMMC_W_GET_CMD_RESP_TYPE(cmd) << + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_ResponseTypeSelect_Pos) | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndexCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_MultiSingleBlockSelect_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_BlockCountEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DMAEnable_Msk; + p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG = transfer_reg; + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDClockEnable = 1; + + return FSP_SUCCESS; +} + +#endif /* (SDEMMC_W_CFG_SD_SUPPORT_ENABLE | SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE) */ + +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + +static fsp_err_t r_sdemmc_sdio_block_read_data (sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp, + uint8_t * p_buf, + uint32_t block_size, + uint32_t block_count) +{ + fsp_err_t err = FSP_SUCCESS; + uint32_t transfer_reg = 0; + + /* Clear Status */ + p_ctrl->sdemmc_w_event.word = 0U; + + p_ctrl->p_reg_mmc->SDEMMC_SDMA_SYS_ADDR__ARGU_2_REG = (uint32_t) p_buf; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize = (block_size & SDEMMC_W_12BIT_MASK); + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.HostSDMABufferBoundry = 7; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.BlockCountForCurrentTransfer = (uint16_t) block_count; + g_BlockCountForCurrentTransfer = block_count; + p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG = cmd_arg; + + /* Enable response end interrupt and access end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.TransferCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.TransferCompleteStatusEnb = 1; + + transfer_reg = cmd << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataPresentSelect_Msk | + (uint32_t) (SDEMMC_W_GET_CMD_RESP_TYPE(cmd) << + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_ResponseTypeSelect_Pos) | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndexCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_MultiSingleBlockSelect_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataTransferDirectionSelect_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_BlockCountEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DMAEnable_Msk; + p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG = transfer_reg; + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDClockEnable = 1; + err = r_sdemmc_sdemmc_wait_for_complete_interrupt(p_ctrl, p_rsp); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_sdemmc_wait_for_transfer_interrupt(p_ctrl); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_sdio_multi_write_data (sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t cmd, + uint32_t cmd_arg, + uint32_t * p_rsp, + uint8_t * p_buf, + uint32_t block_size, + uint32_t block_count) +{ + fsp_err_t err = FSP_SUCCESS; + uint32_t transfer_reg = 0; + + /* Clear Status */ + p_ctrl->sdemmc_w_event.word = 0U; + + p_ctrl->p_reg_mmc->SDEMMC_SDMA_SYS_ADDR__ARGU_2_REG = (uint32_t) p_buf; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.TransferBlockSize = (block_size & SDEMMC_W_12BIT_MASK); + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.HostSDMABufferBoundry = 7; + p_ctrl->p_reg_mmc->SDEMMC_BLOCK_REG_b.BlockCountForCurrentTransfer = (uint16_t) block_count; + g_BlockCountForCurrentTransfer = block_count; + p_ctrl->p_reg_mmc->SDEMMC__ARGU_1_REG = cmd_arg; + + /* Enable response end interrupt and access end interrupt */ + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.CommandCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.CommandCompleteStatusEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_SIGNAL_EN_REG_b.TransferCompleteSignalEnb = 1; + p_ctrl->p_reg_mmc->SDEMMC_NORMAL_ITNR_STATUS_EN_REG_b.TransferCompleteStatusEnb = 1; + + transfer_reg = cmd << SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndex_Pos | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DataPresentSelect_Msk | + (uint32_t) (SDEMMC_W_GET_CMD_RESP_TYPE(cmd) << + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_ResponseTypeSelect_Pos) | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandIndexCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_CommandCRCCheckEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_MultiSingleBlockSelect_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_BlockCountEnable_Msk | + SDEMMC_SDEMMC_TRANSFERMODE_COMMAND_REG_DMAEnable_Msk; + p_ctrl->p_reg_mmc->SDEMMC_TRANSFERMODE_COMMAND_REG = transfer_reg; + + p_ctrl->p_reg_mmc->SDEMMC__CLK__CTRL__REG_b.SDClockEnable = 1; + err = r_sdemmc_sdemmc_wait_for_complete_interrupt(p_ctrl, p_rsp); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + *p_rsp = (*p_rsp >> 8) & 0xFF; + err = r_sdemmc_sdemmc_wait_for_transfer_interrupt(p_ctrl); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_sdemmc_wait_write_done(p_ctrl); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_sdio_io_rw_direct (sdemmc_w_instance_ctrl_t * p_ctrl, + uint8_t write, + uint8_t fn, + uint32_t addr, + uint8_t in, + uint8_t * p_value) +{ + uint32_t arg = 0; + uint32_t rsp = 0; + fsp_err_t err = FSP_SUCCESS; + + arg = (1 == write) ? 0x80000000 : 0x00000000; + arg |= fn << 28; + arg |= addr << 9; + arg |= in; + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_IO_RW_DIRECT, arg, &rsp); + + if (!write) + { + *p_value = (uint8_t) (rsp & 0xff); + } + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_sdio_io_rw_extended (sdemmc_w_instance_ctrl_t * p_ctrl, + uint8_t write, + uint8_t fn, + uint32_t addr, + uint32_t incr_addr, + uint8_t * p_buf, + uint32_t block_count, + uint32_t blksz) +{ + uint32_t arg = 0; + uint32_t rsp = 0; + + if (addr & (uint32_t) ~0x1FFFF) + { + FSP_RETURN(FSP_ERR_INVALID_ARGUMENT); + } + + arg = write ? 0x80000000 : 0x00000000; + arg |= fn << 28; + arg |= incr_addr ? 0x04000000 : 0x00000000; + arg |= addr << 9; + + if ((1 == blksz) && (block_count <= 512)) + { + arg |= block_count; + } + else + { + arg |= 0x08000000 | block_count; + } + + if (write) + { + if (arg & 0x08000000) + { + r_sdemmc_sdio_multi_write_data(p_ctrl, SDEMMC_W_PRV_CMD_IO_RW_EXTENDED, arg, &rsp, p_buf, blksz, + block_count); + } + else + { + r_sdemmc_sdio_multi_write_data(p_ctrl, SDEMMC_W_PRV_CMD_IO_RW_EXTENDED, arg, &rsp, p_buf, block_count, + blksz); + } + } + else + { + if (arg & 0x08000000) + { + r_sdemmc_sdio_block_read_data(p_ctrl, SDEMMC_W_PRV_CMD_IO_RW_EXTENDED, arg, &rsp, p_buf, blksz, + block_count); + } + else + { + r_sdemmc_sdio_block_read_data(p_ctrl, SDEMMC_W_PRV_CMD_IO_RW_EXTENDED, arg, &rsp, p_buf, block_count, + blksz); + } + } + + if (rsp & SDEMMC_W_R5_ERROR) + { + FSP_RETURN(FSP_ERR_INVALID_ARGUMENT); + } + + if (rsp & SDEMMC_W_R5_FUNC_NO) + { + FSP_RETURN(FSP_ERR_INVALID_ARGUMENT); + } + + if (rsp & SDEMMC_W_R5_OUT_OF_RANGE) + { + FSP_RETURN(FSP_ERR_INVALID_ARGUMENT); + } + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_version_1_for_cistpl (st_sdemmc_config_t * p_config, uint8_t * p_buf, uint32_t size) +{ + uint32_t nr_strings = 0; + uint8_t ** buffer; + uint8_t * string; + + p_buf += 2; + size -= 2; + + uint32_t i; + for (i = 0; i < size; i++) + { + if (0xff == p_buf[i]) + { + break; + } + + if (0 == p_buf[i]) + { + nr_strings++; + } + } + + if (0 == nr_strings) + { + return FSP_SUCCESS; + } + + size = i; + + buffer = (uint8_t **) malloc(sizeof(char *) * nr_strings + size); + + if (!buffer) + { + FSP_RETURN(FSP_ERR_OUT_OF_MEMORY); + } + + string = (uint8_t *) (buffer + nr_strings); + + for (i = 0; i < nr_strings; i++) + { + buffer[i] = string; + strcpy((char *) string, (char const *) p_buf); + string += strlen((char const *) string) + 1; + p_buf += strlen((char const *) p_buf) + 1; + } + + p_config->sdio_num_info = nr_strings; + p_config->psdio_info = buffer; + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_man_fid_for_cistpl (st_sdemmc_config_t * p_config, uint8_t * p_buf, uint32_t size) +{ + uint32_t vendor = 0; + uint32_t device = 0; + FSP_PARAMETER_NOT_USED(size); + + /* TPLMID_MANF */ + vendor = (uint32_t) (p_buf[0] | (p_buf[1] << 8)); + + /* TPLMID_CARD */ + device = (uint32_t) (p_buf[2] | (p_buf[3] << 8)); + + p_config->cis.vendor = (uint16_t) vendor; + p_config->cis.device = (uint16_t) device; + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_parse_for_cis_tuple (st_sdemmc_config_t * p_config, + uint8_t * p_tpl_descr, + const struct tuples_for_cis * p_tpl, + int32_t tpl_count, + uint8_t code, + uint8_t * p_buf, + uint32_t size) +{ + fsp_err_t err = FSP_SUCCESS; + int32_t i; + FSP_PARAMETER_NOT_USED(p_tpl_descr); + + /* look for a matching code in the table */ + for (i = 0; i < tpl_count; i++) + { + if (p_tpl->code == code) + { + break; + } + + p_tpl++; + } + + if (i < tpl_count) + { + if (size >= p_tpl->min_size) + { + if (p_tpl->parse) + { + err = p_tpl->parse(p_config, p_buf, size); + } + else + { + err = FSP_SUCCESS; /* known tuple, not parsed */ + } + } + else + { + /* invalid tuple */ + err = FSP_ERR_INVALID_DATA; + } + } + else + { + /* unknown tuple */ + err = FSP_ERR_UNSUPPORTED; + } + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_common_fne_for_cistpl (st_sdemmc_config_t * p_config, uint8_t * p_buf, uint32_t size) +{ + FSP_PARAMETER_NOT_USED(size); + + /* TPLFE_FN0_BLK_SIZE */ + p_config->cis.blksize = (uint16_t) (p_buf[1] | (p_buf[2] << 8)); + + /* TPLFE_MAX_TRAN_SPEED */ + p_config->cis.max_dtr = gs_speed_val[(p_buf[3] >> 3) & 15] * gs_speed_unit[p_buf[3] & 7]; + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_fn_fne_for_cistpl (st_sdemmc_config_t * p_config, uint8_t * p_buf, uint32_t size) +{ + uint32_t vsn = 0; + uint32_t min_size = 0; + + /* + * This tuple has a different length depending on the SDIO spec + * version. + */ + vsn = p_config->cccr.sdio_vsn; + min_size = (vsn == SDEMMC_W_PRV_SDIO_SDIO_R_1_00) ? 28 : 42; + + if (size < min_size) + { + FSP_RETURN(FSP_ERR_INVALID_ARGUMENT); + } + + /* TPLFE_MAX_BLK_SIZE */ + p_config->max_blk_size = (uint32_t) (p_buf[12] | (p_buf[13] << 8)); + + /* TPLFE_ENABLE_TIMEOUT_VAL, present in ver 1.1 and above */ + if (vsn > SDEMMC_W_PRV_SDIO_SDIO_R_1_00) + { + p_config->cis.enable_timeout = (uint32_t) ((p_buf[28] | (p_buf[29] << 8)) * 10); + } + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_local_cistpl_fn (st_sdemmc_config_t * p_config, uint8_t * p_buffer, uint32_t sz) +{ + if (sz < 1) + { + FSP_RETURN(FSP_ERR_INVALID_ARGUMENT); + } + + return r_sdemmc_parse_for_cis_tuple(p_config, + (uint8_t *) SDEMMC_W_PRV_CISTPL_FUNC_NAME, + gs_func_list_for_cis_tpl, + SDEMMC_W_ARRAY_SIZE(gs_func_list_for_cis_tpl), + p_buffer[0], + p_buffer, + sz); +} + +static fsp_err_t r_sdemmc_sdio_cis_tpl_parse (st_sdemmc_config_t * p_config, + uint8_t * p_data, + uint8_t tpl_code, + uint8_t tpl_link) +{ + fsp_err_t err = FSP_SUCCESS; + + err = r_sdemmc_parse_for_cis_tuple(p_config, + (uint8_t *) SDEMMC_W_PRV_CIS_NAME, + gs_list_cis_tpl, + SDEMMC_W_ARRAY_SIZE(gs_list_cis_tpl), + tpl_code, + p_data, + (uint32_t) tpl_link); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +} + +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + +static inline uint32_t BITS_FOR_UNSTUFF (uint32_t * p_resp, uint32_t start, uint32_t size) +{ + int32_t isize = (int32_t) size; + uint32_t mask = (uint32_t) ((isize < 32 ? 1 << isize : 0) - 1); + int32_t off = (int32_t) (3 - ((start) / 32)); + int32_t shift = (start) & 31; + uint32_t res; + + res = p_resp[off] >> shift; + + if (isize + shift > 32) + { + res |= p_resp[off - 1] << ((32 - shift) % 32); + } + + return res & mask; +} + +#if SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + +static fsp_err_t r_sdemmc_emmc_decode_csd (sdemmc_w_instance_ctrl_t * const p_ctrl, st_sdemmc_config_t * p_config) +{ + st_mmc_csd_t * tmp_mmc_csd = &(p_config->csd); + uint32_t e = 0; + uint32_t m = 0; + uint32_t a = 0; + uint32_t b = 0; + uint32_t * decode_rsp = p_config->raw_csd; + sdmmc_priv_csd_reg_t csd_reg; + + p_ctrl->device.card_type = SDMMC_CARD_TYPE_MMC; + r_sdemmc_csd_save(p_ctrl, p_config->rca, &csd_reg, false); + + tmp_mmc_csd->mmc_struct = (uint8_t) BITS_FOR_UNSTUFF(decode_rsp, 126, 2); + + if (0 == tmp_mmc_csd->mmc_struct) + { + FSP_RETURN(FSP_ERR_INVALID_DATA); + } + + tmp_mmc_csd->mmca_vsn = (uint8_t) BITS_FOR_UNSTUFF(decode_rsp, 122, 4); + m = BITS_FOR_UNSTUFF(decode_rsp, 115, 4); + e = BITS_FOR_UNSTUFF(decode_rsp, 112, 3); + tmp_mmc_csd->ns_for_tacc = (gs_tacc_exp[e] * gs_tacc_mant[m] + 9) / 10; + tmp_mmc_csd->clks_for_tacc = (uint16_t) (BITS_FOR_UNSTUFF(decode_rsp, 104, 8) * 100); + + m = BITS_FOR_UNSTUFF(decode_rsp, 99, 4); + e = BITS_FOR_UNSTUFF(decode_rsp, 96, 3); + tmp_mmc_csd->max_dtr = gs_tran_exp[e] * gs_tran_mant[m]; + tmp_mmc_csd->command_class = (uint16_t) BITS_FOR_UNSTUFF(decode_rsp, 84, 12); + + e = BITS_FOR_UNSTUFF(decode_rsp, 47, 3); + m = BITS_FOR_UNSTUFF(decode_rsp, 62, 12); + tmp_mmc_csd->capa_size = (1 + m) << (e + 2); + + tmp_mmc_csd->rd_bits_for_blk = BITS_FOR_UNSTUFF(decode_rsp, 80, 4); + tmp_mmc_csd->rd_part = BITS_FOR_UNSTUFF(decode_rsp, 79, 1) & SDEMMC_W_1BIT_MASK; + tmp_mmc_csd->wr_misalign_flag = BITS_FOR_UNSTUFF(decode_rsp, 78, 1) & SDEMMC_W_1BIT_MASK; + tmp_mmc_csd->rd_misalign_flag = BITS_FOR_UNSTUFF(decode_rsp, 77, 1) & SDEMMC_W_1BIT_MASK; + tmp_mmc_csd->factor_for_r2w = BITS_FOR_UNSTUFF(decode_rsp, 26, 3); + tmp_mmc_csd->wr_bits_for_blk = BITS_FOR_UNSTUFF(decode_rsp, 22, 4); + tmp_mmc_csd->wr_part = BITS_FOR_UNSTUFF(decode_rsp, 21, 1) & SDEMMC_W_1BIT_MASK; + + if (tmp_mmc_csd->wr_bits_for_blk >= 9) + { + a = BITS_FOR_UNSTUFF(decode_rsp, 42, 5); + b = BITS_FOR_UNSTUFF(decode_rsp, 37, 5); + tmp_mmc_csd->sz_for_erase = (a + 1) * (b + 1); + tmp_mmc_csd->sz_for_erase <<= tmp_mmc_csd->wr_bits_for_blk - 9; + } + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_emmc_decode_ext_csd (sdemmc_w_instance_ctrl_t * p_ctrl, st_sdemmc_config_t * p_config) +{ + p_config->ext_csd.raw_ext_csd_structure = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_STRUCTURE]; + + if (3 == p_config->csd.mmc_struct) + { + if (p_config->ext_csd.raw_ext_csd_structure > 2) + { + FSP_RETURN(FSP_ERR_INVALID_DATA); + } + } + + p_config->ext_csd.rev = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_REV]; + + p_config->ext_csd.raw_sectors[0] = p_config->pext_csd[SDEMMC_W_PRV_EMMC_EXT_CSD_SEC_COUNT_OFFSET + 0]; + p_config->ext_csd.raw_sectors[1] = p_config->pext_csd[SDEMMC_W_PRV_EMMC_EXT_CSD_SEC_COUNT_OFFSET + 1]; + p_config->ext_csd.raw_sectors[2] = p_config->pext_csd[SDEMMC_W_PRV_EMMC_EXT_CSD_SEC_COUNT_OFFSET + 2]; + p_config->ext_csd.raw_sectors[3] = p_config->pext_csd[SDEMMC_W_PRV_EMMC_EXT_CSD_SEC_COUNT_OFFSET + 3]; + + if (p_config->ext_csd.rev >= 2) + { + p_config->ext_csd.sectors = + (uint32_t) (p_config->pext_csd[SDEMMC_W_PRV_EMMC_EXT_CSD_SEC_COUNT_OFFSET + 0] << 0) | + (uint32_t) (p_config->pext_csd[SDEMMC_W_PRV_EMMC_EXT_CSD_SEC_COUNT_OFFSET + 1] << 8) | + (uint32_t) (p_config->pext_csd[SDEMMC_W_PRV_EMMC_EXT_CSD_SEC_COUNT_OFFSET + 2] << 16) | + (uint32_t) (p_config->pext_csd[SDEMMC_W_PRV_EMMC_EXT_CSD_SEC_COUNT_OFFSET + 3] << 24); + p_ctrl->device.sector_count = p_config->ext_csd.sectors; + } + + p_config->ext_csd.raw_card_type = p_config->pext_csd[SDEMMC_W_PRV_EMMC_EXT_CSD_DEVICE_TYPE_OFFSET]; + + switch (p_config->pext_csd[SDEMMC_W_PRV_EMMC_EXT_CSD_DEVICE_TYPE_OFFSET] & SDEMMC_W_PRV_E_CSD_CD_TYPE_MASK) + { + case SDEMMC_W_PRV_E_CSD_CD_TYPE_DDR_52 | SDEMMC_W_PRV_E_CSD_CD_TYPE_52 | SDEMMC_W_PRV_E_CSD_CD_TYPE_26: + { + p_config->ext_csd.hs_max_dtr = 52000000; + p_config->ext_csd.card_type = SDEMMC_W_PRV_E_CSD_CD_TYPE_DDR_52; + break; + } + + case SDEMMC_W_PRV_E_CSD_CD_TYPE_DDR_1_2V | SDEMMC_W_PRV_E_CSD_CD_TYPE_52 | SDEMMC_W_PRV_E_CSD_CD_TYPE_26: + { + p_config->ext_csd.hs_max_dtr = 52000000; + p_config->ext_csd.card_type = SDEMMC_W_PRV_E_CSD_CD_TYPE_DDR_1_2V; + break; + } + + case SDEMMC_W_PRV_E_CSD_CD_TYPE_DDR_1_8V | SDEMMC_W_PRV_E_CSD_CD_TYPE_52 | SDEMMC_W_PRV_E_CSD_CD_TYPE_26: + { + p_config->ext_csd.hs_max_dtr = 52000000; + p_config->ext_csd.card_type = SDEMMC_W_PRV_E_CSD_CD_TYPE_DDR_1_8V; + break; + } + + case SDEMMC_W_PRV_E_CSD_CD_TYPE_52 | SDEMMC_W_PRV_E_CSD_CD_TYPE_26: + { + p_config->ext_csd.hs_max_dtr = 52000000; + break; + } + + case SDEMMC_W_PRV_E_CSD_CD_TYPE_26: + { + p_config->ext_csd.hs_max_dtr = 26000000; + break; + } + + default: + { + /* MMC v4 spec says this cannot happen */ + break; + } + } + + p_config->ext_csd.raw_s_a_timeout = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_S_A_TIMEOUT]; + p_config->ext_csd.raw_erase_timeout_mult = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_ER_TO_MULT]; + p_config->ext_csd.raw_hc_erase_grp_size = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_HC_ERASE_GRP_SIZE]; + + if (p_config->ext_csd.rev >= 3) + { + uint8_t sa_shift = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_S_A_TIMEOUT]; + p_config->ext_csd.part_config = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_PART_CFG]; + + /* EXT_CSD value is in units of 10ms, but we store in ms */ + p_config->ext_csd.part_time = 10 * p_config->pext_csd[SDEMMC_W_PRV_E_CSD_PART_SWCH_TM]; + + /* Sleep / awake timeout in 100ns units */ + + if ((sa_shift > 0) && (sa_shift <= 0x17)) + { + p_config->ext_csd.sa_timeout = 1 << p_config->pext_csd[SDEMMC_W_PRV_E_CSD_S_A_TIMEOUT]; + } + + p_config->ext_csd.erase_group_def = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_ER_GRP_DEF]; + p_config->ext_csd.hc_erase_timeout = 300 * p_config->pext_csd[SDEMMC_W_PRV_E_CSD_ER_TO_MULT]; + p_config->ext_csd.hc_erase_size = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_HC_ERASE_GRP_SIZE] << 10; + + p_config->ext_csd.rel_sectors = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_REL_WR_SEC_C]; + + /* + * There are two boot regions of equal size, defined in + * multiples of 128K. + */ + p_config->ext_csd.boot_size = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_BOOT_MULT] << 17; + } + + p_config->ext_csd.raw_hc_erase_gap_size = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_PART_ATTR]; + p_config->ext_csd.raw_sec_trim_mult = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_SEC_TRIM_MULT]; + p_config->ext_csd.raw_sec_erase_mult = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_SEC_ERASE_MULT]; + p_config->ext_csd.raw_sec_feature_support = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_SEC_FT_SUPP]; + p_config->ext_csd.raw_trim_mult = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_TRIM_MULT]; + + if (p_config->ext_csd.rev >= 4) + { + /* + * Enhanced area feature support -- check whether the eMMC + * emmc has the Enhanced area enabled. If so, export enhanced + * area offset and size to user by adding sysfs interface. + */ + p_config->ext_csd.raw_partition_support = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_PART_SUPP]; + + if ((p_config->pext_csd[SDEMMC_W_PRV_E_CSD_PART_SUPP] & 0x2) && + (p_config->pext_csd[SDEMMC_W_PRV_E_CSD_PART_ATTR] & 0x1)) + { + uint8_t hc_erase_grp_sz = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_HC_ERASE_GRP_SIZE]; + uint8_t hc_wp_grp_sz = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_HC_WP_GRP_SIZE]; + + p_config->ext_csd.enhanced_area_en = 1; + + /* calculate the enhanced data area offset, in bytes */ + p_config->ext_csd.enhanced_area_offset = (uint64_t) ((p_config->pext_csd[139] << 24) + + (p_config->pext_csd[138] << 16) + + (p_config->pext_csd[137] << 8) + + p_config->pext_csd[136]); + + /* calculate the enhanced data area size, in kilobytes */ + p_config->ext_csd.enhanced_area_size = (uint32_t) ((p_config->pext_csd[142] << 16) + + (p_config->pext_csd[141] << 8) + + p_config->pext_csd[140]); + p_config->ext_csd.enhanced_area_size *= (size_t) (hc_erase_grp_sz * hc_wp_grp_sz); + p_config->ext_csd.enhanced_area_size <<= 9; + } + else + { + /* + * If the enhanced area is not enabled, disable these + * device attributes. + */ + p_config->ext_csd.enhanced_area_offset = 0xFFFFFFFFFFFFFFFF; + p_config->ext_csd.enhanced_area_size = 0xFFFFFFFF; + } + + p_config->ext_csd.sec_trim_mult = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_SEC_TRIM_MULT]; + p_config->ext_csd.sec_erase_mult = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_SEC_ERASE_MULT]; + p_config->ext_csd.sec_feature_support = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_SEC_FT_SUPP]; + p_config->ext_csd.trim_timeout = 300 * p_config->pext_csd[SDEMMC_W_PRV_E_CSD_TRIM_MULT]; + } + + p_config->ext_csd.raw_erased_mem_count = p_config->pext_csd[SDEMMC_W_PRV_E_CSD_ERASED_MEM_CONT]; + + if (p_config->pext_csd[SDEMMC_W_PRV_E_CSD_ERASED_MEM_CONT]) + { + p_config->erased_byte = 0xFF; + } + else + { + p_config->erased_byte = 0x0; + } + + return FSP_SUCCESS; +} + +#endif /* SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE + +static fsp_err_t r_sdemmc_sd_decode_csd (sdemmc_w_instance_ctrl_t * const p_ctrl, st_sdemmc_config_t * p_config) +{ + st_mmc_csd_t * csd = &(p_config->csd); + uint32_t e = 0; + uint32_t m = 0; + uint32_t * resp = p_config->raw_csd; + sdmmc_priv_csd_reg_t csd_reg; + + r_sdemmc_csd_save(p_ctrl, p_config->rca, &csd_reg, false); + + csd->mmc_struct = (uint8_t) BITS_FOR_UNSTUFF(resp, 126, 2); + + switch (csd->mmc_struct) + { + case 0: + { + m = BITS_FOR_UNSTUFF(resp, 115, 4); + e = BITS_FOR_UNSTUFF(resp, 112, 3); + csd->ns_for_tacc = (gs_tacc_exp[e] * gs_tacc_mant[m] + 9) / 10; + csd->clks_for_tacc = (uint16_t) (BITS_FOR_UNSTUFF(resp, 104, 8) * 100); + + m = BITS_FOR_UNSTUFF(resp, 99, 4); + e = BITS_FOR_UNSTUFF(resp, 96, 3); + csd->max_dtr = gs_tran_exp[e] * gs_tran_mant[m]; + csd->command_class = (uint16_t) BITS_FOR_UNSTUFF(resp, 84, 12); + + e = BITS_FOR_UNSTUFF(resp, 47, 3); + m = BITS_FOR_UNSTUFF(resp, 62, 12); + csd->capa_size = (1 + m) << (e + 2); + + csd->rd_bits_for_blk = BITS_FOR_UNSTUFF(resp, 80, 4); + csd->rd_part = BITS_FOR_UNSTUFF(resp, 79, 1) & SDEMMC_W_1BIT_MASK; + csd->wr_misalign_flag = BITS_FOR_UNSTUFF(resp, 78, 1) & SDEMMC_W_1BIT_MASK; + csd->rd_misalign_flag = BITS_FOR_UNSTUFF(resp, 77, 1) & SDEMMC_W_1BIT_MASK; + csd->factor_for_r2w = BITS_FOR_UNSTUFF(resp, 26, 3); + csd->wr_bits_for_blk = BITS_FOR_UNSTUFF(resp, 22, 4); + csd->wr_part = BITS_FOR_UNSTUFF(resp, 21, 1) & SDEMMC_W_1BIT_MASK; + + if (BITS_FOR_UNSTUFF(resp, 46, 1)) + { + csd->sz_for_erase = 1; + } + else if (csd->wr_bits_for_blk >= 9) + { + csd->sz_for_erase = BITS_FOR_UNSTUFF(resp, 39, 7) + 1; + csd->sz_for_erase <<= csd->wr_bits_for_blk - 9; + } + + break; + } + + case 1: + { + csd->ns_for_tacc = 0; /* Unused */ + csd->clks_for_tacc = 0; /* Unused */ + + m = BITS_FOR_UNSTUFF(resp, 99, 4); + e = BITS_FOR_UNSTUFF(resp, 96, 3); + csd->max_dtr = gs_tran_exp[e] * gs_tran_mant[m]; + csd->command_class = (uint16_t) BITS_FOR_UNSTUFF(resp, 84, 12); + csd->c_sz = BITS_FOR_UNSTUFF(resp, 48, 22); + + /* SDXC emmcs have a minimum C_SIZE of 0x00FFFF */ + m = BITS_FOR_UNSTUFF(resp, 48, 22); + csd->capa_size = (1 + m) << 10; + + csd->rd_bits_for_blk = 9; + csd->rd_part = 0; + csd->wr_misalign_flag = 0; + csd->rd_misalign_flag = 0; + csd->factor_for_r2w = 4; /* Unused */ + csd->wr_bits_for_blk = 9; + csd->wr_part = 0; + csd->sz_for_erase = 1; + break; + } + + default: + { + FSP_RETURN(FSP_ERR_INVALID_DATA); + } + } + + return FSP_SUCCESS; +} + +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + +static fsp_err_t r_sdemmc_emmc_decode_cid (st_sdemmc_config_t * p_config) +{ + uint32_t * resp = p_config->raw_cid; + + switch (p_config->csd.mmca_vsn) + { + case 0: /* MMC v1.0 - v1.2 */ + case 1: /* MMC v1.4 */ + { + p_config->cid.manfid = BITS_FOR_UNSTUFF(resp, 104, 24); + p_config->cid.prod_name[0] = (int8_t) BITS_FOR_UNSTUFF(resp, 96, 8); + p_config->cid.prod_name[1] = (int8_t) BITS_FOR_UNSTUFF(resp, 88, 8); + p_config->cid.prod_name[2] = (int8_t) BITS_FOR_UNSTUFF(resp, 80, 8); + p_config->cid.prod_name[3] = (int8_t) BITS_FOR_UNSTUFF(resp, 72, 8); + p_config->cid.prod_name[4] = (int8_t) BITS_FOR_UNSTUFF(resp, 64, 8); + p_config->cid.prod_name[5] = (int8_t) BITS_FOR_UNSTUFF(resp, 56, 8); + p_config->cid.prod_name[6] = (int8_t) BITS_FOR_UNSTUFF(resp, 48, 8); + p_config->cid.hwrev = (uint8_t) BITS_FOR_UNSTUFF(resp, 44, 4); + p_config->cid.fwrev = (uint8_t) BITS_FOR_UNSTUFF(resp, 40, 4); + p_config->cid.serial = BITS_FOR_UNSTUFF(resp, 16, 24); + p_config->cid.month = (uint8_t) BITS_FOR_UNSTUFF(resp, 12, 4); + p_config->cid.year = (uint16_t) (BITS_FOR_UNSTUFF(resp, 8, 4) + 1997); + break; + } + + case 2: /* MMC v2.0 - v2.2 */ + case 3: /* MMC v3.1 - v3.3 */ + case 4: /* MMC v4 */ + { + p_config->cid.manfid = BITS_FOR_UNSTUFF(resp, 120, 8); + p_config->cid.oemid = (uint16_t) BITS_FOR_UNSTUFF(resp, 104, 16); + p_config->cid.prod_name[0] = (int8_t) BITS_FOR_UNSTUFF(resp, 96, 8); + p_config->cid.prod_name[1] = (int8_t) BITS_FOR_UNSTUFF(resp, 88, 8); + p_config->cid.prod_name[2] = (int8_t) BITS_FOR_UNSTUFF(resp, 80, 8); + p_config->cid.prod_name[3] = (int8_t) BITS_FOR_UNSTUFF(resp, 72, 8); + p_config->cid.prod_name[4] = (int8_t) BITS_FOR_UNSTUFF(resp, 64, 8); + p_config->cid.prod_name[5] = (int8_t) BITS_FOR_UNSTUFF(resp, 56, 8); + p_config->cid.serial = BITS_FOR_UNSTUFF(resp, 16, 32); + p_config->cid.month = (uint8_t) BITS_FOR_UNSTUFF(resp, 12, 4); + p_config->cid.year = (uint16_t) (BITS_FOR_UNSTUFF(resp, 8, 4) + 1997); + break; + } + + default: + { + FSP_RETURN(FSP_ERR_INVALID_DATA); + } + } + + return FSP_SUCCESS; +} + +#endif /* SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE + +static fsp_err_t r_sdemmc_sd_decode_cid (st_sdemmc_config_t * p_config) +{ + uint32_t * resp = p_config->raw_cid; + + p_config->cid.manfid = BITS_FOR_UNSTUFF(resp, 120, 8); + p_config->cid.oemid = (uint16_t) BITS_FOR_UNSTUFF(resp, 104, 16); + p_config->cid.prod_name[0] = (int8_t) BITS_FOR_UNSTUFF(resp, 96, 8); + p_config->cid.prod_name[1] = (int8_t) BITS_FOR_UNSTUFF(resp, 88, 8); + p_config->cid.prod_name[2] = (int8_t) BITS_FOR_UNSTUFF(resp, 80, 8); + p_config->cid.prod_name[3] = (int8_t) BITS_FOR_UNSTUFF(resp, 72, 8); + p_config->cid.prod_name[4] = (int8_t) BITS_FOR_UNSTUFF(resp, 64, 8); + p_config->cid.hwrev = (uint8_t) BITS_FOR_UNSTUFF(resp, 60, 4); + p_config->cid.fwrev = (uint8_t) BITS_FOR_UNSTUFF(resp, 56, 4); + p_config->cid.serial = BITS_FOR_UNSTUFF(resp, 24, 32); + p_config->cid.year = (uint16_t) BITS_FOR_UNSTUFF(resp, 12, 8); + p_config->cid.month = (uint8_t) BITS_FOR_UNSTUFF(resp, 8, 4); + + p_config->cid.year += 2000; /* SD year offset */ + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_mmc_decode_scr (st_sdemmc_config_t * p_config) +{ + st_sd_scr_t * scr = &(p_config->scr); + uint32_t scr_struct = 0; + uint32_t resp[4]; + + resp[3] = SDEMMC_W_NTOH32(p_config->raw_scr[1]); + resp[2] = SDEMMC_W_NTOH32(p_config->raw_scr[0]); + resp[1] = 0; + resp[0] = 0; + + scr_struct = BITS_FOR_UNSTUFF(resp, 60, 4); + + if (0 != scr_struct) + { + FSP_RETURN(FSP_ERR_INVALID_DATA); + } + + scr->sda_vsn = (uint8_t) BITS_FOR_UNSTUFF(resp, 56, 4); + scr->bus_wid = (uint8_t) BITS_FOR_UNSTUFF(resp, 48, 4); + + if (SDEMMC_W_PRV_SCR_SPEC_VER_2 == scr->sda_vsn) + { + /* Check if Physical Layer Spec v3.0 is supported */ + scr->sda_spec3 = (uint8_t) BITS_FOR_UNSTUFF(resp, 47, 1); + } + + if (scr->sda_spec3) + { + scr->sd_cmds = (uint8_t) BITS_FOR_UNSTUFF(resp, 32, 2); + } + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_mmd_decode_ssr (st_sdemmc_config_t * p_config) +{ + st_sd_ssr_t * ssr = &(p_config->ssr); + uint32_t allocation_unit = 0; + uint32_t erase_size = 0; + uint32_t erase_timeout = 0; + uint32_t erase_offset = 0; + uint32_t * resp; + uint32_t i; + + for (i = 0; i < 16; i++) + { + p_config->raw_ssr[i] = SDEMMC_W_NTOH32(p_config->raw_ssr[i]); + } + + resp = p_config->raw_ssr; + + ssr->bus_width = BITS_FOR_UNSTUFF(resp, (510 - 384), 2); + ssr->cd_type = (uint16_t) BITS_FOR_UNSTUFF(resp, (480 - 384), 16); + ssr->area_protected = BITS_FOR_UNSTUFF(resp, (448 - 384), 32); + ssr->spd_class = BITS_FOR_UNSTUFF(resp, (440 - 384), 8); + ssr->perf_mv = (uint8_t) BITS_FOR_UNSTUFF(resp, (432 - 384), 8); + allocation_unit = BITS_FOR_UNSTUFF(resp, (428 - 384), 4); + ssr->au = 1 << (allocation_unit + 4); + erase_size = BITS_FOR_UNSTUFF(resp, (408 - 384), 16); + erase_timeout = BITS_FOR_UNSTUFF(resp, (402 - 384), 6); + erase_offset = BITS_FOR_UNSTUFF(resp, (400 - 384), 2); + + if (erase_size && erase_timeout) + { + ssr->erase_to = (erase_timeout * 1000) / erase_size; /* In milliseconds */ + ssr->erase_off = erase_offset * 1000; /* In milliseconds */ + } + + return FSP_SUCCESS; +} + +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + +static fsp_err_t r_sdemmc_emmc_wait_ready (sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t * p_rocr) +{ + FSP_PARAMETER_NOT_USED(p_rocr); + uint32_t rsp = 0; + uint32_t try_count = 100; + uint32_t i; + + for (i = 0; i < try_count; i++) + { + r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SEND_OP_COND, (0x40ff8080 | (0x01 << 30)), &rsp); + + if ((0x80ff8080 == rsp) || (0xc0ff8080 == rsp)) + { + return FSP_SUCCESS; + } + + rsp = 0; + R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MICROSECONDS); + } + + FSP_RETURN(FSP_ERR_INVALID_STATE); +} + +#endif /* SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + +static uint32_t r_sdemmc_emmc_make_switch_arg (uint8_t set, uint8_t index, uint8_t value) +{ + return (uint32_t) (SDEMMC_W_PRV_MMC_SWITCH_MODE_WRITE_BYTE << 24) | + (uint32_t) (index << 16) | (uint32_t) (value << 8) | + (uint32_t) set; +} + +#endif /* SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE + +static uint32_t r_sdemmc_sd_make_switch_arg (int32_t mode, int32_t group, int32_t value) +{ + uint32_t arg = 0; + + arg = (uint32_t) (mode << 31 | 0x00FFFFFF); + arg &= (uint32_t) ~(0xF << (group * 4)); + arg |= (uint32_t) (value << (group * 4)); + + return arg; +} + +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE */ + +#if SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + +static fsp_err_t r_sdemmc_emmc_send_op_cond (sdemmc_w_instance_ctrl_t * p_ctrl, uint32_t ocr, uint32_t * p_rocr) +{ + FSP_PARAMETER_NOT_USED(ocr); + uint32_t rsp = 0; + fsp_err_t err = FSP_SUCCESS; + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SEND_OP_COND, 0, &rsp); + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + if (0x00ff8080 == rsp) + { + /* device capacity is less than or to 2GB */ + err = r_sdemmc_emmc_wait_ready(p_ctrl, &rsp); + } + else if (0x40ff8080 == rsp) + { + err = r_sdemmc_emmc_wait_ready(p_ctrl, &rsp); + } + else + { + err = r_sdemmc_emmc_wait_ready(p_ctrl, &rsp); + } + + *p_rocr = rsp; + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +} + +#endif /* SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + +static fsp_err_t r_sdemmc_sdio_init_card (sdemmc_w_instance_ctrl_t * p_ctrl, st_sdemmc_config_t * p_config, + uint32_t ocr) +{ +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + uint32_t rocr = 0; + uint32_t rsp = 0; + uint32_t cis_ptr = 0; + uint8_t data = 0; + uint8_t cccr_vsn = 0; + fsp_err_t err = FSP_SUCCESS; + uint32_t i; + FSP_PARAMETER_NOT_USED(ocr); + + for (i = 0; i < SDEMMC_W_PRV_MMC_RETRY_COUNT; i++) + { + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_SDIO_SEND_OP_COND, rocr, &rocr); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + if (0 == rocr) + { + FSP_RETURN(FSP_ERR_INVALID_DATA); + } + + if (0 == (rocr & SDEMMC_W_PRV_SUPPORT_VOLTAGE)) + { + FSP_RETURN(FSP_ERR_UNSUPPORTED); + } + + if (rocr & SDEMMC_W_PRV_CARD_READY) + { + break; + } + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + } + + if (SDEMMC_W_PRV_MMC_RETRY_COUNT == i) + { + FSP_RETURN(FSP_ERR_INVALID_STATE); + } + + p_config->ocr = rocr & SDEMMC_W_PRV_SUPPORT_VOLTAGE; + + for (i = 0; i < SDEMMC_W_PRV_MMC_RETRY_COUNT; i++) + { + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_SDIO_SEND_OP_COND, p_config->ocr, &rocr); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + if (0 == rocr) + { + FSP_RETURN(FSP_ERR_INVALID_DATA); + } + + if (rocr & SDEMMC_W_PRV_CARD_READY) + { + break; + } + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + } + + if (SDEMMC_W_PRV_MMC_RETRY_COUNT == i) + { + FSP_RETURN(FSP_ERR_INVALID_STATE); + } + + if (p_config->ocr & SDEMMC_W_PRV_R4_MEM_PR) + { + FSP_RETURN(FSP_ERR_UNSUPPORTED); + } + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SEND_RELATIVE_ADDR, 0, &rsp); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + p_config->rca = rsp >> 16; + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SEL_DES_CARD, (p_config->rca << 16), &rsp); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_READ, 0, SDEMMC_W_PRV_SDIO_CCCR_CCCR, 0, &data); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + cccr_vsn = data & 0x0f; + p_config->cccr.sdio_vsn = (data & 0xf0) >> 4; + + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_READ, 0, SDEMMC_W_PRV_SDIO_CCCR_CAPS, 0, &data); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + if (data & SDEMMC_W_PRV_SDIO_CCCR_CAP_SMB) + { + p_config->cccr.multi_block = 1; + p_config->cccr.wide_bus = 1; + } + + if (data & SDEMMC_W_PRV_SDIO_CCCR_CAP_LSC) + { + p_config->cccr.low_speed = 1; + + if (data & SDEMMC_W_PRV_SDIO_CCCR_CAP_4BLS) + { + p_config->cccr.wide_bus = 1; + } + } + + if (cccr_vsn >= SDEMMC_W_PRV_SDIO_CCCR_R_1_10) + { + err = + r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_READ, 0, SDEMMC_W_PRV_SDIO_CCCR_POWER, 0, &data); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + if (data & SDEMMC_W_PRV_SDIO_PWR_SMPC) + { + p_config->cccr.high_power = 1; + } + } + + if (cccr_vsn >= SDEMMC_W_PRV_SDIO_CCCR_R_1_20) + { + err = + r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_READ, 0, SDEMMC_W_PRV_SDIO_CCCR_SPEED, 0, &data); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + if (data & SDEMMC_W_PRV_SDIO_SPEED_SHS) + { + p_config->cccr.high_speed = 1; + } + } + + for (i = 0; i < 3; i++) + { + err = + r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_READ, 0, + (SDEMMC_W_PRV_SDIO_FBR_BASE(0) + SDEMMC_W_PRV_SDIO_FBR_CIS + i), 0, &data); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + cis_ptr |= data << (i * 8); + } + + do + { + uint8_t tpl_code; + uint8_t tpl_link; + + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_READ, 0, cis_ptr++, 0, &tpl_code); + + if (err) + { + break; + } + + if (0xff == tpl_code) + { + break; + } + + if (0x00 == tpl_code) + { + continue; + } + + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_READ, 0, cis_ptr++, 0, &tpl_link); + + if (err) + { + break; + } + + if (0xff == tpl_link) + { + break; + } + + p_config->psdio_cis = (uint8_t *) malloc(tpl_link); + + if (!(p_config->psdio_cis)) + { + FSP_RETURN(FSP_ERR_OUT_OF_MEMORY); + } + + for (i = 0; i < tpl_link; i++) + { + err = + r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_READ, 0, (cis_ptr + i), 0, + &(p_config->psdio_cis[i])); + + if (err) + { + free(p_config->psdio_cis); + FSP_RETURN(err); + } + } + + err = r_sdemmc_sdio_cis_tpl_parse(p_config, p_config->psdio_cis, tpl_code, tpl_link); + free((void *) p_config->psdio_cis); + p_config->psdio_cis = NULL; + + if (err) + { + break; + } + + cis_ptr += tpl_link; + } while (!err); + + cis_ptr = 0; + + for (i = 0; i < 3; i++) + { + err = + r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_READ, 0, + (SDEMMC_W_PRV_SDIO_FBR_BASE(1) + SDEMMC_W_PRV_SDIO_FBR_CIS + i), 0, &data); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + cis_ptr |= data << (i * 8); + } + + /* 4bit, push_pull up */ + return FSP_SUCCESS; +#else /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + FSP_PARAMETER_NOT_USED(p_ctrl); + FSP_PARAMETER_NOT_USED(p_config); + FSP_PARAMETER_NOT_USED(ocr); + FSP_RETURN(FSP_ERR_UNSUPPORTED); +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ +} + +static fsp_err_t r_sdemmc_sd_init_card (sdemmc_w_instance_ctrl_t * p_ctrl, st_sdemmc_config_t * p_config, uint32_t ocr) +{ +#if SDEMMC_W_CFG_SD_SUPPORT_ENABLE + FSP_PARAMETER_NOT_USED(ocr); + uint32_t rocr = 0; + uint32_t rsp = 0; + uint8_t buf[64]; + fsp_err_t err = FSP_SUCCESS; + + r_sdemmc_emmc_cmd_without_res(p_ctrl, SDEMMC_W_PRV_CMD_GO_IDLE_STATE, 0x12345678); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + r_sdemmc_emmc_cmd_without_res(p_ctrl, SDEMMC_W_PRV_CMD_GO_IDLE_STATE, 0xffffffff); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_IF_COND, 0x15a, &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_APP_CMD, 0xffff, &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SD_SEND_OP_COND, 0, &rocr); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + int32_t i; + for (i = 0; i < SDEMMC_W_PRV_MMC_RETRY_COUNT; i++) + { + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_APP_CMD, 0xffff, &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SD_SEND_OP_COND, 0x40ff0000, &rocr); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + if (rocr & SDEMMC_W_PRV_CARD_READY) + { + break; + } + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + } + + if (SDEMMC_W_PRV_MMC_RETRY_COUNT == i) + { + FSP_RETURN(FSP_ERR_INVALID_STATE); + } + + p_config->ocr = rocr; + + sdmmc_response_t response; + response.status = rocr; + + if (response.r3.power_up_status) + { + /* High capacity card ? */ + /* 0 = SDSC, 1 = SDHC or SDXC */ + p_ctrl->sector_addressing = (response.r3.card_capacity_status > 0U); + } + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_ALL_SEND_CID, 0xffffffff, p_config->raw_cid); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + r_sdemmc_sd_decode_cid(p_config); + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SEND_RELATIVE_ADDR, 0, &rsp); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + p_config->rca = rsp >> 16; + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SEND_CSD, (p_config->rca << 16), p_config->raw_csd); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_sd_decode_csd(p_ctrl, p_config); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SEL_DES_CARD, (p_config->rca << 16), &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_SD_APP_SD_STS, (p_config->rca << 16), &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_APP_CMD, (p_config->rca << 16), &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + err = r_sdemmc_emmc_single_read_data_with_wait(p_ctrl, + SDEMMC_W_PRV_SD_APP_SEND_SCR, + 0, + 8, + &rsp, + (uint8_t *) p_config->raw_scr); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_mmc_decode_scr(p_config); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_APP_CMD, (p_config->rca << 16), &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + err = r_sdemmc_emmc_single_read_data_with_wait(p_ctrl, + SDEMMC_W_PRV_SD_APP_SD_STS, + 0, + 64, + &rsp, + (uint8_t *) p_config->raw_ssr); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_mmd_decode_ssr(p_config); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = + r_sdemmc_emmc_single_read_data_with_wait(p_ctrl, SDEMMC_W_PRV_CMD_SET_BUS_WIDTH, + r_sdemmc_sd_make_switch_arg(0, 0, 1), 64, &rsp, (uint8_t *) buf); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, FSP_ERR_INVALID_STATE); + + /* check data group1 high speed */ + if (buf[13] & 0x02) + { + p_config->caps.hs_max_dtr = 25000000; + + err = r_sdemmc_emmc_single_read_data_with_wait(p_ctrl, + SDEMMC_W_PRV_CMD_SET_BUS_WIDTH, + r_sdemmc_sd_make_switch_arg(1, 0, 1), + 64, + &rsp, + (uint8_t *) buf); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, FSP_ERR_INVALID_STATE); + + /* set again */ + err = r_sdemmc_emmc_single_read_data_with_wait(p_ctrl, + SDEMMC_W_PRV_CMD_SET_BUS_WIDTH, + r_sdemmc_sd_make_switch_arg(1, 0, 1), + 64, + &rsp, + (uint8_t *) buf); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, FSP_ERR_INVALID_STATE); + + if (1 != (buf[16] & 0x0f)) + { + FSP_RETURN(FSP_ERR_INVALID_STATE); + } + } + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_APP_CMD, ((p_config->rca << 16) | 0xffff), &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10, BSP_DELAY_UNITS_MICROSECONDS); + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SET_BUS_WIDTH, SDEMMC_W_PRV_SD_BUS_WIDTH_1, &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + /* 4bit, high speed, push_pull up */ + + if (p_config->csd.capa_size < 2048000) + { + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SET_BLOCKLEN, 512, &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + p_config->card_type = SDMMC_PRIV_CT_SD_CARD_1_1; + } + else + { + p_config->card_type = SDMMC_PRIV_CT_SD_CARD; + } + + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_SD_APP_SD_STS, ((p_config->rca << 16) | 0xffff), &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +#else /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE */ + FSP_PARAMETER_NOT_USED(p_ctrl); + FSP_PARAMETER_NOT_USED(p_config); + FSP_PARAMETER_NOT_USED(ocr); + FSP_RETURN(FSP_ERR_UNSUPPORTED); +#endif /* SDEMMC_W_CFG_SD_SUPPORT_ENABLE */ +} + +static fsp_err_t r_sdemmc_emmc_init_card (sdemmc_w_instance_ctrl_t * p_ctrl, st_sdemmc_config_t * p_config, + uint32_t ocr) +{ +#if SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE + FSP_PARAMETER_NOT_USED(ocr); + uint32_t rocr = 0; + uint32_t rsp = 0; + fsp_err_t err = FSP_SUCCESS; + int32_t i = 0; + + r_sdemmc_emmc_cmd_without_res(p_ctrl, SDEMMC_W_PRV_CMD_GO_IDLE_STATE, 0); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + err = r_sdemmc_emmc_send_op_cond(p_ctrl, 0, &rocr); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, FSP_ERR_UNSUPPORTED); + + p_config->ocr = rocr; + + /* get response of CMD1 */ + sdmmc_response_t response; + response.status = rocr; + + /* High capacity card ? */ + p_ctrl->sector_addressing = (response.r3.card_capacity_status > 0U); + + /* send cid */ + for (i = 0; i < SDEMMC_W_PRV_MMC_RETRY_COUNT; i++) + { + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_ALL_SEND_CID, 0, p_config->raw_cid); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + if (!err) + { + break; + } + } + + if (SDEMMC_W_PRV_MMC_RETRY_COUNT == i) + { + FSP_RETURN(FSP_ERR_INVALID_STATE); + } + + p_config->rca = 1; + for (i = 0; i < SDEMMC_W_PRV_MMC_RETRY_COUNT; i++) + { + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SEND_RELATIVE_ADDR, (p_config->rca << 16), &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + if (!err) + { + break; + } + } + + if (SDEMMC_W_PRV_MMC_RETRY_COUNT == i) + { + FSP_RETURN(err); + } + + for (i = 0; i < SDEMMC_W_PRV_MMC_RETRY_COUNT; i++) + { + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SEND_CSD, (p_config->rca << 16), p_config->raw_csd); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + if (!err) + { + break; + } + } + + if (SDEMMC_W_PRV_MMC_RETRY_COUNT == i) + { + FSP_RETURN(FSP_ERR_INVALID_STATE); + } + + err = r_sdemmc_emmc_decode_csd(p_ctrl, p_config); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = r_sdemmc_emmc_decode_cid(p_config); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, FSP_ERR_INVALID_STATE); + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + for (i = 0; i < SDEMMC_W_PRV_MMC_RETRY_COUNT; i++) + { + err = r_sdemmc_emmc_cmd_with_res(p_ctrl, SDEMMC_W_PRV_CMD_SEL_DES_CARD, (p_config->rca << 16), &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + if (!err) + { + break; + } + } + + if (SDEMMC_W_PRV_MMC_RETRY_COUNT == i) + { + FSP_RETURN(err); + } + + if (p_config->csd.mmca_vsn < 4) + { + FSP_RETURN(FSP_ERR_UNSUPPORTED); + } + + for (i = 0; i < SDEMMC_W_PRV_MMC_RETRY_COUNT; i++) + { + err = r_sdemmc_emmc_single_read_data_with_wait(p_ctrl, + SDEMMC_W_PRV_CMD_IF_COND, + 0, + SDEMMC_W_PRV_EMMC_EXT_CSD_SIZE, + &rsp, + (uint8_t *) &p_config->pext_csd); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_10000, BSP_DELAY_UNITS_MICROSECONDS); + + if (err) + { + continue; + } + + err = r_sdemmc_emmc_decode_ext_csd(p_ctrl, p_config); + + if (!err) + { + break; + } + } + + if (SDEMMC_W_PRV_MMC_RETRY_COUNT == i) + { + FSP_RETURN(err); + } + + if (0 != p_config->ext_csd.hs_max_dtr) + { + err = + r_sdemmc_emmc_cmd_with_res(p_ctrl, + SDEMMC_W_PRV_CMD_SWITCH, + r_sdemmc_emmc_make_switch_arg(SDEMMC_W_PRV_E_CSD_CMD_SET_NORMAL, + SDEMMC_W_PRV_EMMC_EXT_CSD_HS_TIMING_OFFSET, 1), + &rsp); + + if (err) + { + err = FSP_SUCCESS; + } + } + + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + for (i = 0; i < SDEMMC_W_PRV_MMC_RETRY_COUNT; i++) + { + err = + r_sdemmc_emmc_cmd_with_res(p_ctrl, + SDEMMC_W_PRV_CMD_SWITCH, + r_sdemmc_emmc_make_switch_arg(SDEMMC_W_PRV_E_CSD_CMD_SET_NORMAL, + SDEMMC_W_PRV_E_CSD_BUS_WIDTH, + SDEMMC_W_SDEMMC_DT_WIDTH_1BIT), + &rsp); + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + + if (!err) + { + break; + } + } + + if (SDEMMC_W_PRV_MMC_RETRY_COUNT == i) + { + FSP_RETURN(err); + } + + p_config->card_type = SDMMC_PRIV_CT_MMC_CARD; + + return FSP_SUCCESS; +#else /* SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ + FSP_PARAMETER_NOT_USED(p_ctrl); + FSP_PARAMETER_NOT_USED(p_config); + FSP_PARAMETER_NOT_USED(ocr); + FSP_RETURN(FSP_ERR_UNSUPPORTED); +#endif /* SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE */ +} + +#if SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE + +static fsp_err_t r_sdemmc_hw_sdemmc_sdio_func_enable (sdemmc_w_instance_ctrl_t * p_ctrl, + st_sdemmc_config_t * p_config, + uint32_t func_num) +{ + fsp_err_t err = FSP_SUCCESS; + uint8_t reg = 0; + FSP_PARAMETER_NOT_USED(p_config); + + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_READ, 0, SDEMMC_W_PRV_SDIO_CCCR_IOEX, 0, ®); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + reg |= (uint8_t) (1 << func_num); + + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_WRITE, 0, SDEMMC_W_PRV_SDIO_CCCR_IOEX, reg, NULL); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + int32_t i; + for (i = 0; i < SDEMMC_W_PRV_SDIO_CCR_IOR_RETRY_COUNT; i++) + { + err = r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_READ, 0, SDEMMC_W_PRV_SDIO_CCCR_IORX, 0, ®); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + if (reg & (1 << func_num)) + { + break; + } + + err = FSP_ERR_TIMEOUT; + R_BSP_SoftwareDelay(SDEMMC_W_PRV_EMMC_DELAY_100, BSP_DELAY_UNITS_MICROSECONDS); + } + + if (SDEMMC_W_PRV_SDIO_CCR_IOR_RETRY_COUNT == i) + { + FSP_RETURN(FSP_ERR_TIMEOUT); + } + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_hw_sdemmc_sdio_set_block_size (sdemmc_w_instance_ctrl_t * p_ctrl, + uint32_t func_num, + uint32_t blk_size) +{ + fsp_err_t err = FSP_SUCCESS; + + if (blk_size > SDEMMC_W_MAX_BLOCK_SIZE) + { + FSP_RETURN(FSP_ERR_INVALID_ARGUMENT); + } + + if (0 == blk_size) + { + FSP_RETURN(FSP_ERR_INVALID_ARGUMENT); + } + + err = + r_sdemmc_sdio_io_rw_direct(p_ctrl, + SDEMMC_W_PRV_SDIO_CMD52_WRITE, + 0, + (SDEMMC_W_PRV_SDIO_FBR_BASE(func_num) + SDEMMC_W_SDIO_FBR_BLKSZ), + (blk_size & 0xff), + NULL); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + err = + r_sdemmc_sdio_io_rw_direct(p_ctrl, SDEMMC_W_PRV_SDIO_CMD52_WRITE, 0, + (SDEMMC_W_PRV_SDIO_FBR_BASE(func_num) + SDEMMC_W_SDIO_FBR_BLKSZ + 1), + ((blk_size >> 8) & 0xff), NULL); + + FSP_ERROR_RETURN(FSP_SUCCESS == err, err); + + return FSP_SUCCESS; +} + +#endif /* SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE */ + +#if (CFG_PMGR == 1) && (SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE == 1) + +/*******************************************************************************************************************/ /** + * Prepare SDIO for sleep mode 4/5 + * + * @param[in] p_context Pointer to PMGR interface of SDIO instance + **********************************************************************************************************************/ +static fsp_err_t r_sdemmc_w_enter_sleep (sdemmc_w_pmgr_context_t * p_context) +{ + fsp_err_t err = FSP_SUCCESS; + #if (SDEMMC_W_CFG_PARAM_CHECKING_ENABLE) + FSP_ASSERT(p_context); + #endif + + sdemmc_w_instance_ctrl_t * p_ctrl = p_context->p_ctrl; + FSP_ERROR_RETURN(p_ctrl->open == SDEMMC_W_PRV_OPEN, FSP_ERR_INVALID_MODE); + + /* Backup actual HW regs state */ + p_context->state.SDIO_CCCR_REG = p_ctrl->p_reg->SDIO_CCCR_REG; + p_context->state.SDIO_OCR_REG = p_ctrl->p_reg->SDIO_OCR_REG; + p_context->state.SDIO_GLB_INT_ENA_REG = p_ctrl->p_reg->SDIO_GLB_INT_ENA_REG; + p_context->state.SDIO_AHB_FN0_INT_ENABLE_REG = p_ctrl->p_reg->SDIO_AHB_FN0_INT_ENABLE_REG; + p_context->state.SDIO_AHB_FN0_INT_REG = p_ctrl->p_reg->SDIO_AHB_FN0_INT_REG; + p_context->state.SDIO_AHB_FN1_INT_ENABLE_REG = p_ctrl->p_reg->SDIO_AHB_FN1_INT_ENABLE_REG; + p_context->state.SDIO_AHB_FN1_INT_REG = p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG; + p_context->state.SDIO_FBR_REG = p_ctrl->p_reg->SDIO_FBR_REG; + p_context->state.SDIO_IOR_REG = p_ctrl->p_reg->SDIO_IOR_REG; + p_context->state.SDIO_GLB_INT_STS_REG = p_ctrl->p_reg->SDIO_GLB_INT_STS_REG; + p_context->state.SDIO_FUNRDY_REG = p_ctrl->p_reg->SDIO_FUNRDY_REG; + + p_context->state.GPIO_SDIO_MODE_REG = GPIO->SDIO_MODE_REG; + + p_ctrl->open = SDEMMC_W_PRV_SLEEP; + + return err; +} + +/*******************************************************************************************************************/ /** + * Restore SDIO from wakeup + * + * @param[in] p_context Pointer to PMGR interface of SDIO instance + **********************************************************************************************************************/ +static fsp_err_t r_sdemmc_w_wakeup (sdemmc_w_pmgr_context_t * p_context) +{ + fsp_err_t err = FSP_SUCCESS; + #if (SDEMMC_W_CFG_PARAM_CHECKING_ENABLE) + FSP_ASSERT(p_context); + #endif + sdemmc_w_instance_ctrl_t * p_ctrl = p_context->p_ctrl; + + FSP_ERROR_RETURN(p_ctrl->open == SDEMMC_W_PRV_SLEEP, FSP_ERR_INVALID_MODE); + FSP_ASSERT(SDEMMC_W_ROLE_DEVICE == ((sdemmc_w_extended_cfg_t *) p_ctrl->p_cfg->p_extend)->sdemmc_w_role); + + /* Restore HW regs state */ + p_ctrl->p_reg->SDIO_CCCR_REG = p_context->state.SDIO_CCCR_REG; + p_ctrl->p_reg->SDIO_OCR_REG = p_context->state.SDIO_OCR_REG; + p_ctrl->p_reg->SDIO_GLB_INT_ENA_REG = p_context->state.SDIO_GLB_INT_ENA_REG; + p_ctrl->p_reg->SDIO_AHB_FN0_INT_ENABLE_REG = p_context->state.SDIO_AHB_FN0_INT_ENABLE_REG; + p_ctrl->p_reg->SDIO_AHB_FN0_INT_REG = p_context->state.SDIO_AHB_FN0_INT_REG; + p_ctrl->p_reg->SDIO_AHB_FN1_INT_ENABLE_REG = p_context->state.SDIO_AHB_FN1_INT_ENABLE_REG; + p_ctrl->p_reg->SDIO_AHB_FN1_INT_REG = p_context->state.SDIO_AHB_FN1_INT_REG; + p_ctrl->p_reg->SDIO_FBR_REG = p_context->state.SDIO_FBR_REG; + p_ctrl->p_reg->SDIO_IOR_REG = p_context->state.SDIO_IOR_REG; + p_ctrl->p_reg->SDIO_GLB_INT_STS_REG = p_context->state.SDIO_GLB_INT_STS_REG; + p_ctrl->p_reg->SDIO_FUNRDY_REG = p_context->state.SDIO_FUNRDY_REG; + + // TODO: is here a right place for this? + GPIO->SDIO_MODE_REG = p_context->state.GPIO_SDIO_MODE_REG; + + CRG_PER->SET_CLK_COM_REG_b.SDIO_ENABLE = 1U; + + /* Configure and enable interrupts. */ + r_sdemmc_irq_enable(p_ctrl->p_cfg->sdio_irq, p_ctrl->p_cfg->sdio_ipl, p_ctrl); + + p_ctrl->open = SDEMMC_W_PRV_OPEN; + + return err; +} + +static void r_sdemmc_w_pmgr_callback (pmgr_callback_args_t * p_args) +{ + pmgr_instance_info_t * p_pmgr_info = (pmgr_instance_info_t *) p_args->p_instance_info; + + if (p_pmgr_info->power_mode == PMGR_LLD_POWER_MODE_SLEEP4) + { + if (p_args->event == PMGR_EVENT_ENTERING_SLEEP) + { + /* Entering sleep 4/5 - close UART */ + r_sdemmc_w_enter_sleep((sdemmc_w_pmgr_context_t *) p_args->p_context); + } + else if (p_args->event == PMGR_EVENT_EXITING_SLEEP) + { + /* Open UART with previous settings */ + r_sdemmc_w_wakeup((sdemmc_w_pmgr_context_t *) p_args->p_context); + } + } +} + +static fsp_err_t r_sdemmc_w_subscribe_for_pmgr_notifications (sdemmc_w_instance_ctrl_t * const p_ctrl) +{ + fsp_err_t err = FSP_SUCCESS; + pmgr_ctrl_t * pmgr_ctrl = NULL; + + sdemmc_w_pmgr_context_t * context = &g_sdemmc_pmgr_context[p_ctrl->p_cfg->channel]; + + context->pmgr_info.power_mode = PMGR_LLD_POWER_MODE_SLEEP4; + context->pmgr_info.wake_source = PMGR_WAKE_SOURCE_NONE, + context->pmgr_notifier_ext.order = PMGR_W_NOTIFIER_ORDER_SYS_LOW; + context->p_ctrl = p_ctrl; + + context->clbk_args.constraints = PMGR_CONSTRAINT_NONE; + context->clbk_args.event = PMGR_EVENT_NOT_SET; + context->clbk_args.p_context = (void *) context; + context->clbk_args.p_instance_info = (void *) &context->pmgr_info; + + pmgr_ctrl = RM_PMGR_W_get_ctrl(); + FSP_ASSERT(pmgr_ctrl != NULL); + + err = RM_PMGR_W_notifier_register(pmgr_ctrl, + r_sdemmc_w_pmgr_callback, + &context->clbk_args, + &context->pmgr_notifier_ext); + FSP_ASSERT(FSP_SUCCESS == err); + + return FSP_SUCCESS; +} + +static fsp_err_t r_sdemmc_w_unsubscribe_from_pmgr_notifications (sdemmc_w_instance_ctrl_t * const p_ctrl) +{ + fsp_err_t err = FSP_SUCCESS; + pmgr_ctrl_t * pmgr_ctrl = NULL; + + pmgr_ctrl = RM_PMGR_W_get_ctrl(); + FSP_ASSERT(pmgr_ctrl != NULL); + + sdemmc_w_pmgr_context_t * context = &g_sdemmc_pmgr_context[p_ctrl->p_cfg->channel]; + err = RM_PMGR_W_notifier_unregister(pmgr_ctrl, context->pmgr_notifier_ext.notifier_id); + FSP_ASSERT(FSP_SUCCESS == err); + + return FSP_SUCCESS; +} + +#endif diff --git a/bsp/renesas/ra6w1-ek/ra/fsp/src/r_sdemmc_w/r_sdemmc_w_private.h b/bsp/renesas/ra6w1-ek/ra/fsp/src/r_sdemmc_w/r_sdemmc_w_private.h new file mode 100644 index 000000000000..d782f8cf4fb4 --- /dev/null +++ b/bsp/renesas/ra6w1-ek/ra/fsp/src/r_sdemmc_w/r_sdemmc_w_private.h @@ -0,0 +1,567 @@ +/* +* Copyright (c) 2020 - 2026 Renesas Electronics Corporation and/or its affiliates +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef SDEMMC_W_PRV_R_SDEMMC_PRIVATE_H +#define SDEMMC_W_PRV_R_SDEMMC_PRIVATE_H + +/********************************************************************************************************************** + * Includes + **********************************************************************************************************************/ +#include "bsp_api.h" + +/** Common macro for FSP header files. There is also a corresponding FSP_FOOTER macro at the end of this file. */ +FSP_HEADER + +/********************************************************************************************************************** + * Macro definitions + **********************************************************************************************************************/ +#define SDEMMC_W_PRV_CSD_VERSION_1_0 (0U) +#define SDEMMC_W_PRV_CSD_VERSION_2_0 (1U) /* value of 1 is CSD 2.0 according to SD spec. */ + +#define SDEMMC_W_PRV_CMD_GO_IDLE_STATE (0U) +#define SDEMMC_W_PRV_CMD_SEND_OP_COND (1U) +#define SDEMMC_W_PRV_CMD_ALL_SEND_CID (2U) +#define SDEMMC_W_PRV_CMD_SEND_RELATIVE_ADDR (3U) +#define SDEMMC_W_PRV_CMD_SDIO (5U) +#define SDEMMC_W_PRV_CMD_SET_BUS_WIDTH (6U) +#define SDEMMC_W_PRV_CMD_SWITCH (6U) +#define SDEMMC_W_PRV_CMD_SEL_DES_CARD (7U) +#define SDEMMC_W_PRV_CMD_IF_COND (8U) +#define SDEMMC_W_PRV_CMD_SEND_CSD (9U) +#define SDEMMC_W_PRV_CMD_SEND_CID (10U) +#define SDEMMC_W_PRV_CMD_STOP_TRANSM (12U) +#define SDEMMC_W_PRV_CMD_SET_BLOCKLEN (16U) +#define SDEMMC_W_PRV_CMD_READ_SINGLE_BLOCK (17U) +#define SDEMMC_W_PRV_CMD_READ_MULTIPLE_BLOCK (18U) +#define SDEMMC_W_PRV_CMD_SET_BLK_CNT (23U) +#define SDEMMC_W_PRV_CMD_WRITE_SINGLE_BLOCK (24U) +#define SDEMMC_W_PRV_CMD_WRITE_MULTIPLE_BLOCK (25U) +#define SDEMMC_W_PRV_CMD_ERASE_WR_BLK_START (32U) +#define SDEMMC_W_PRV_CMD_ERASE_WR_BLK_END (33U) +#define SDEMMC_W_PRV_CMD_TAG_ERASE_GROUP_START (0x423U) +#define SDEMMC_W_PRV_CMD_TAG_ERASE_GROUP_END (0x424U) +#define SDEMMC_W_PRV_CMD_ERASE (38U) +#define SDEMMC_W_PRV_CMD_SD_SEND_OP_COND (41U) +#define SDEMMC_W_PRV_CMD_IO_RW_DIRECT (52U) +#define SDEMMC_W_PRV_CMD_IO_RW_EXTENDED (53U) +#define SDEMMC_W_PRV_CMD_IO_READ_EXT_SINGLE_BLOCK (0x1c35U) +#define SDEMMC_W_PRV_CMD_IO_EXT_MULTI_BLOCK (0x6000U) +#define SDEMMC_W_PRV_CMD_IO_WRITE_EXT_SINGLE_BLOCK (0x0c35U) + +#define SDEMMC_W_PRV_CMD_APP_CMD (55U) +#define SDEMMC_W_PRV_CMD_C_ACMD (1U << 6) /* APP Command */ + +#define SDEMMC_W_PRV_IF_COND_VOLTAGE (1U) +#define SDEMMC_W_PRV_IF_COND_CHECK_PATTERN (0xAAU) + +#define SDEMMC_W_PRV_OCR_CAPACITY_HC (1U << 30) + +#define SDEMMC_W_PRV_OCR_VDD_2_7_V (1U << 15) +#define SDEMMC_W_PRV_OCR_VDD_2_8_V (1U << 16) +#define SDEMMC_W_PRV_OCR_VDD_2_9_V (1U << 17) +#define SDEMMC_W_PRV_OCR_VDD_3_0_V (1U << 18) +#define SDEMMC_W_PRV_OCR_VDD_3_1_V (1U << 19) +#define SDEMMC_W_PRV_OCR_VDD_3_2_V (1U << 20) +#define SDEMMC_W_PRV_OCR_VDD_3_3_V (1U << 21) +#define SDEMMC_W_PRV_OCR_VDD_3_4_V (1U << 22) +#define SDEMMC_W_PRV_OCR_VDD_3_5_V (1U << 23) +#define SDEMMC_W_PRV_OCR_VDD_SUPPORTED \ + (SDEMMC_W_PRV_OCR_VDD_2_7_V | SDEMMC_W_PRV_OCR_VDD_2_8_V | SDEMMC_W_PRV_OCR_VDD_2_9_V | SDEMMC_W_PRV_OCR_VDD_3_0_V | \ + SDEMMC_W_PRV_OCR_VDD_3_1_V | \ + SDEMMC_W_PRV_OCR_VDD_3_2_V | SDEMMC_W_PRV_OCR_VDD_3_3_V | SDEMMC_W_PRV_OCR_VDD_3_4_V | SDEMMC_W_PRV_OCR_VDD_3_5_V) + +/* CMD52 Arguments */ +#define SDEMMC_W_PRV_SDIO_CMD52_READ (0U) +#define SDEMMC_W_PRV_SDIO_CMD52_WRITE (1U) + +/* SWITCH command argument's bit postion */ +#define SDEMMC_W_PRV_SWITCH_ACCESS_SHIFT (24U) +#define SDEMMC_W_PRV_SWITCH_INDEX_SHIFT (16U) +#define SDEMMC_W_PRV_SWITCH_VALUE_SHIFT (8U) + +#define SDEMMC_W_PRV_EMMC_EXT_CSD_SIZE (512U) + +/* Offsets */ +#define SDEMMC_W_PRV_E_CSD_PART_ATTR (156U) /* R/W */ +#define SDEMMC_W_PRV_E_CSD_PART_SUPP (160U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_ER_GRP_DEF (175U) /* R/W */ +#define SDEMMC_W_PRV_E_CSD_PART_CFG (179U) /* R/W */ +#define SDEMMC_W_PRV_E_CSD_ERASED_MEM_CONT (181U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_BUS_WIDTH (183U) /* R/W */ +#define SDEMMC_W_PRV_EMMC_EXT_CSD_HS_TIMING_OFFSET (185U) /* R/W */ +#define SDEMMC_W_PRV_E_CSD_STRUCTURE (194U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_REV (192U) /* Read Only */ +#define SDEMMC_W_PRV_EMMC_EXT_CSD_DEVICE_TYPE_OFFSET (196U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_PART_SWCH_TM (199U) /* Read Only */ +#define SDEMMC_W_PRV_EMMC_EXT_CSD_SEC_COUNT_OFFSET (212U) /* Read Only, 4 bytes */ +#define SDEMMC_W_PRV_E_CSD_S_A_TIMEOUT (217U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_HC_WP_GRP_SIZE (221U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_REL_WR_SEC_C (222U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_ER_TO_MULT (223U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_HC_ERASE_GRP_SIZE (224U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_BOOT_MULT (226U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_SEC_TRIM_MULT (229U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_SEC_ERASE_MULT (230U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_SEC_FT_SUPP (231U) /* Read Only */ +#define SDEMMC_W_PRV_E_CSD_TRIM_MULT (232U) /* Read Only */ + +/* Commands */ +#define SDEMMC_W_PRV_EMMC_SWITCH_ACCESS_WRITE_BYTE (3U) +#define SDEMMC_W_PRV_EMMC_HIGH_SPEED_52_MHZ_BIT (2U) +#define SDEMMC_W_PRV_EMMC_HIGH_SPEED_MODE (((SDEMMC_W_PRV_EMMC_SWITCH_ACCESS_WRITE_BYTE << 24U) | \ + (SDEMMC_W_PRV_EMMC_EXT_CSD_HS_TIMING_OFFSET << 16U)) | \ + (SDEMMC_W_PRV_EMMC_HIGH_SPEED_52_MHZ_BIT << 8U)) + +#define SDEMMC_W_PRV_SD_SWITCH_STATUS_SIZE (64U) +#define SDEMMC_W_PRV_SD_SWITCH_HIGH_SPEED_RESPONSE (13U) +#define SDEMMC_W_PRV_SD_SWITCH_HIGH_SPEED_ERROR_RESPONSE (16U) +#define SDEMMC_W_PRV_SD_SWITCH_HIGH_SPEED_ERROR (0x0fU) +#define SDEMMC_W_PRV_SD_SWITCH_HIGH_SPEED_OK (0x02U) + +#define SDEMMC_W_PRV_EMMC_SEND_OP_COND (0x701U) +#define SDEMMC_W_PRV_EMMC_CMD_SWITCH_WBUSY (0x506U) /* eMMC CMD6 switch command "with response busy" */ +#define SDEMMC_W_PRV_EMMC_CMD_SEND_EXT_CSD (0x1C08U) /* CMD 8, read data */ +#define SDEMMC_W_PRV_EMMC_DEFAULT_CLOCK_RATE (26000000U) /* 26 MHz */ +#define SDEMMC_W_PRV_EMMC_HIGH_SPEED_CLOCK_RATE (52000000U) /* 52 MHz */ +#define SDEMMC_W_PRV_SD_HIGH_SPEED_MODE_SWITCH (0x80FFFFF1U) /* set SD high speed */ +#define SDEMMC_W_PRV_SD_DEFAULT_CLOCK_RATE (25000000U) /* 25 MHz */ +#define SDEMMC_W_PRV_SD_HIGH_SPEED_CLOCK_RATE (50000000U) /* 50 MHz */ +#define SDEMMC_W_PRV_SDIO_HIGH_SPEED_CLOCK_RATE (50000000U) /* 50 MHz */ + +#define SDEMMC_W_PRV_EMMC_ERASE_ARGUMENT_TRIM (1U) + +#define SDEMMC_W_PRV_CSD_CID_SERIAL_NUMBER_BITS (32) +#define SDEMMC_W_PRV_CSD_CID_PRODUCT_NAME_BITS (40) + +#define SDEMMC_W_PRV_MMC_RETRY_COUNT (100) +#define SDEMMC_W_PRV_SDIO_CCR_IOR_RETRY_COUNT (10) + +#define SDEMMC_W_PRV_EMMC_DELAY_10 (10) +#define SDEMMC_W_PRV_EMMC_DELAY_100 (100) +#define SDEMMC_W_PRV_EMMC_DELAY_10000 (10000) + +#define SDEMMC_W_PRV_SDIO_SEND_OP_COND (5) +#define SDEMMC_W_PRV_CARD_READY (0x80000000) +#define SDEMMC_W_PRV_R4_MEM_PR (0x08000000) +#define SDEMMC_W_PRV_SUPPORT_VOLTAGE (0x00300000) + +#define SDEMMC_W_PRV_SDIO_CCCR_CCCR (0x00) + +#define SDEMMC_W_PRV_SDIO_CCCR_CAPS (0x08) +#define SDEMMC_W_PRV_SDIO_CCCR_CAP_SMB (0x02) +#define SDEMMC_W_PRV_SDIO_CCCR_CAP_LSC (0x40) +#define SDEMMC_W_PRV_SDIO_CCCR_CAP_4BLS (0x80) + +#define SDEMMC_W_PRV_SDIO_SPEED_SHS (0x01) +#define SDEMMC_W_PRV_SDIO_FBR_BASE(y) (0x100 * (y)) +#define SDEMMC_W_PRV_SDIO_FBR_CIS (0x09) + +#define SDEMMC_W_PRV_SDIO_CCCR_IOEX (0x02) +#define SDEMMC_W_PRV_SDIO_CCCR_IORX (0x03) + +#define SDEMMC_W_PRV_SDIO_SDIO_R_1_00 (0) +#define SDEMMC_W_PRV_SDIO_SDIO_R_2_00 (3) +#define SDEMMC_W_PRV_SDIO_CCCR_R_1_10 (1) +#define SDEMMC_W_PRV_SDIO_CCCR_R_1_20 (2) + +#define SDEMMC_W_PRV_SDIO_CCCR_POWER (0x12) +#define SDEMMC_W_PRV_SDIO_PWR_SMPC (0x01) +#define SDEMMC_W_PRV_SDIO_CCCR_SPEED (0x13) +#define SDEMMC_W_PRV_SDIO_FBR_BLKSZ (0x10) + +/* Commands for applications */ +#define SDEMMC_W_PRV_SD_APP_SD_STS (13) +#define SDEMMC_W_PRV_SD_APP_SEND_SCR (51) + +/* SCR field definitions (sda_vsn) */ +#define SDEMMC_W_PRV_SCR_SPEC_VER_0 (0) /* Implements system specification 1.0 - 1.01 */ +#define SDEMMC_W_PRV_SCR_SPEC_VER_1 (1) /* Implements system specification 1.10 */ +#define SDEMMC_W_PRV_SCR_SPEC_VER_2 (2) /* Implements system specification 2.00-3.0X */ + + +/* SD bus widths (bus_wid) */ +#define SDEMMC_W_PRV_SD_BUS_WIDTH_1 (0) +#define SDEMMC_W_PRV_SD_BUS_WIDTH_4 (2) + +/* CMD23 support (sd_cmds) */ +#define SDEMMC_W_PRV_SCR_CMD23_SUPPORT (1 << 1) + +#define SDEMMC_W_PRV_E_CSD_CD_TYPE_26 (1 << 0) /* 26MHz Read : Card Type */ +#define SDEMMC_W_PRV_E_CSD_CD_TYPE_52 (1 << 1) /* 52MHz Read : Card Type */ +#define SDEMMC_W_PRV_E_CSD_CD_TYPE_DDR_1_8V (1 << 2) /* 52MHz Read : DDR I/O mode @1.8V or 3V */ +#define SDEMMC_W_PRV_E_CSD_CD_TYPE_DDR_1_2V (1 << 3) /* 52MHz Read : DDR I/O mode @1.2V */ +#define SDEMMC_W_PRV_E_CSD_CD_TYPE_MASK (0xF) + +#define SDEMMC_W_PRV_E_CSD_CD_TYPE_DDR_52 (SDEMMC_W_PRV_E_CSD_CD_TYPE_DDR_1_8V | SDEMMC_W_PRV_E_CSD_CD_TYPE_DDR_1_2V) + +#define SDEMMC_W_PRV_E_CSD_CMD_SET_NORMAL (1 << 0) + +#define SDEMMC_W_PRV_MMC_SWITCH_MODE_WRITE_BYTE (0x03) + +#ifndef SDEMMC_W_ARRAY_SIZE +#define SDEMMC_W_ARRAY_SIZE(array)\ + (sizeof(array) / sizeof(array[0])) +#endif + +/********************************************************************************************************************** + * Typedef definitions + **********************************************************************************************************************/ +typedef enum e_sdmmc_priv_sd_state +{ + SDMMC_PRIV_SD_STATE_IDLE, + SDMMC_PRIV_SD_STATE_READY, + SDMMC_PRIV_SD_STATE_IDENT, + SDMMC_PRIV_SD_STATE_STBY, + SDMMC_PRIV_SD_STATE_TRANSFER, + SDMMC_PRIV_SD_STATE_DATA, + SDMMC_PRIV_SD_STATE_RCV, + SDMMC_PRIV_SD_STATE_PROG, + SDMMC_PRIV_SD_STATE_DIS, + SDMMC_PRIV_SD_STATE_RSVD9, + SDMMC_PRIV_SD_STATE_RSVD10, + SDMMC_PRIV_SD_STATE_RSVD11, + SDMMC_PRIV_SD_STATE_RSVD12, + SDMMC_PRIV_SD_STATE_RSVD13, + SDMMC_PRIV_SD_STATE_RSVD14, + SDMMC_PRIV_SD_STATE_RSVD15 +} sdmmc_priv_sd_state_t; + +typedef enum e_sdmmc_priv_card_type +{ + SDMMC_PRIV_CT_UNKNOWN_TYPE, + SDMMC_PRIV_CT_SDIO_CARD, + SDMMC_PRIV_CT_SD_CARD_1_1, + SDMMC_PRIV_CT_SD_CARD, + SDMMC_PRIV_CT_MMC_CARD, + SDMMC_PRIV_CT_CARD_MAX +} sdmmc_priv_card_type_t; + +/** SDMMC card specific data */ +typedef struct st_sdmmc_priv_csd_reg +{ + union + { + uint8_t array[16]; + + /* All structures in this union must be packed since some bitfields span more than one 32-bit word. */ +#if defined(__ICCARM__) + __packed struct +#elif defined(__GNUC__) + struct __attribute__((__packed__)) +#endif + { + volatile uint32_t sdrsp10; + volatile uint32_t sdrsp32; + volatile uint32_t sdrsp54; + volatile uint32_t sdrsp76; + } reg; + + /* All structures in this union must be packed since some bitfields span more than one 32-bit word. */ +#if defined(__ICCARM__) + __packed struct +#elif defined(__GNUC__) + struct __attribute__((__packed__)) +#endif + { + uint32_t reserved_8 : 2; /* [9:8] */ + uint32_t file_format : 2; /* [11:10] file format */ + uint32_t tmp_write_protect : 1; /* [12] temporary write protection */ + uint32_t perm_write_protect : 1; /* [13] permanent write protection */ + uint32_t copy : 1; /* [14] copy flag */ + uint32_t file_format_grp : 1; /* [15] file format group */ + uint32_t reserved_20 : 5; /* [16-20] */ + uint32_t write_bl_partial : 1; /* [21] partial blocks for write allowed */ + uint32_t write_bl_len : 4; /* [25:22] max. write data block length */ + uint32_t r2w_factor : 3; /* [28:26] write speed factor */ + uint32_t reserved_29 : 2; /* [30:29] */ + uint32_t wp_grp_enable : 1; /* [31] write protect group enable */ + uint32_t wp_grp_size : 7; /* [38:32] write protect group size */ + uint32_t sector_size : 7; /* [45:39] erase sector size */ + uint32_t erase_blk_en : 1; /* [46] erase single block enable */ + uint32_t c_size_mult : 3; /* [49:47] device size multiplier */ + uint32_t vdd_w_curr_max : 3; /* [52:50] max. write current for vdd max */ + uint32_t vdd_w_curr_min : 3; /* [55:53] max. write current for vdd min */ + uint32_t vdd_r_curr_max : 3; /* [58:56] max. read current for vdd max */ + uint32_t vdd_r_curr_min : 3; /* [61:59] max. read current for vdd min */ + uint32_t c_size : 12; /* [73:62] device size */ + uint32_t reserved_74 : 2; /* [75:74] */ + uint32_t dsr_imp : 1; /* [76] dsr implemented */ + uint32_t read_blk_misalign : 1; /* [77] read block misalignment */ + uint32_t write_blk_misalign : 1; /* [78] write block misalignment */ + uint32_t read_bl_partial : 1; /* [79] partial blocks for read allowed */ + uint32_t read_bl_len : 4; /* [83:80] max read data block length */ + uint32_t ccc : 12; /* [95:84] card command classes */ + uint32_t tran_speed : 8; /* [103:96] max. data transfer rate */ + uint32_t nsac : 8; /* [111:104] data read access-time-2 clk cycles */ + uint32_t taac : 8; /* [119:112] data read access-time-1 */ + uint32_t reserved_120 : 6; /* [125:120] */ + uint32_t csd_structure : 2; /* [127:126] csd structure */ + uint32_t reserved_128 : 8; /* [135:128] */ + } csd_v1_b; + + /* All structures in this union must be packed since some bitfields span more than one 32-bit word. */ +#if defined(__ICCARM__) + __packed struct +#elif defined(__GNUC__) + struct __attribute__((__packed__)) +#endif + { + uint32_t reserved_8 : 2; /* [9:8] */ + uint32_t file_format : 2; /* [11:10] file format */ + uint32_t tmp_write_protect : 1; /* [12] temporary write protection */ + uint32_t perm_write_protect : 1; /* [13] permanent write protection */ + uint32_t copy : 1; /* [14] copy flag */ + uint32_t file_format_grp : 1; /* [15] file format group */ + uint32_t reserved_20 : 5; /* [20:16] */ + uint32_t write_bl_partial : 1; /* [21] partial blocks for write allowed */ + uint32_t write_bl_len : 4; /* [25:22] max. write data block length */ + uint32_t r2w_factor : 3; /* [28:26] write speed factor */ + uint32_t reserved_29 : 2; /* [30:29] */ + uint32_t wp_grp_enable : 1; /* [31] write protect group enable */ + uint32_t wp_grp_size : 7; /* [38:32] write protect group size */ + uint32_t sector_size : 7; /* [45:39] erase sector size */ + uint32_t erase_blk_en : 1; /* [46] erase single block enable */ + uint32_t reserved_47 : 1; /* [47] */ + uint32_t c_size : 22; /* [69:48] device size */ + uint32_t reserved_70 : 6; /* [75:70] */ + uint32_t dsr_imp : 1; /* [76] dsr implemented */ + uint32_t read_blk_misalign : 1; /* [77] read block misalignment */ + uint32_t write_blk_misalign : 1; /* [78] write block misalignment */ + uint32_t read_bl_partial : 1; /* [79] partial blocks for read allowed */ + uint32_t read_bl_len : 4; /* [83:80] max read data block length */ + uint32_t ccc : 12; /* [95:84] card command classes */ + uint32_t tran_speed : 8; /* [103:96] max. data transfer rate */ + uint32_t nsac : 8; /* [111:104] data read access-time-2 clk cycles */ + uint32_t taac : 8; /* [119:112] data read access-time-1 */ + uint32_t reserved_120 : 6; /* [125:120] */ + uint32_t csd_structure : 2; /* [127:126] csd structure */ + uint32_t reserved_128 : 8; /* [135:128] */ + } csd_v2_b; + + /* All structures in this union must be packed since some bitfields span more than one 32-bit word. */ +#if defined(__ICCARM__) + __packed struct +#elif defined(__GNUC__) + struct __attribute__((__packed__)) +#endif + { + uint32_t reserved_0 : 1; + + uint32_t crc : 7; + uint32_t mfg_date : 12; + uint32_t reserved_23 : 4; + uint32_t serial_number : SDEMMC_W_PRV_CSD_CID_SERIAL_NUMBER_BITS; + uint32_t product_revision : 8; + uint64_t product_name : SDEMMC_W_PRV_CSD_CID_PRODUCT_NAME_BITS; + uint32_t oem_id : 16; + uint32_t mfg_id : 8; + uint32_t reserved_128 : 8; + } cid; + }; +} sdmmc_priv_csd_reg_t; + +typedef union u_sdmmc_priv_sdio_arg_t +{ + uint32_t arg; + + struct + { + uint32_t data : 8; /* read/write data */ + uint32_t stuff_8 : 1; /* Stuff bit */ + uint32_t register_address : 17; /* Register Address */ + uint32_t stuff_26 : 1; /* Stuff bit should be set to 1 */ + uint32_t raw : 1; /* 1= Read after write. */ + uint32_t function_number : 3; /* function0~function7 */ + uint32_t rw_flag : 1; /* 0:read, 1:write */ + } cmd_52_arg; + + struct + { + uint32_t count : 9; /* Byte/Block Count */ + uint32_t register_address : 17; /* Register Address */ + uint32_t op_code : 1; /* 0:fixed address, 1:incrementing address */ + uint32_t block_mode : 1; /* 0: Byte, 1:Block */ + uint32_t function_number : 3; /* function0~function7 */ + uint32_t rw_flag : 1; /* 0:read, 1:write */ + } cmd_53_arg; +} sdmmc_priv_sdio_arg_t; + +typedef struct st_mmc_csd +{ + uint8_t mmc_struct; /* Structure */ + uint8_t mmca_vsn; + uint16_t command_class; + uint16_t clks_for_tacc; + uint32_t ns_for_tacc; + uint32_t c_sz; + uint32_t factor_for_r2w; + uint32_t max_dtr; + uint32_t sz_for_erase; /* erase_size In sectors */ + uint32_t rd_bits_for_blk; + uint32_t wr_bits_for_blk; + uint32_t capa_size; + uint32_t rd_part:1, + rd_misalign_flag:1, + wr_part:1, + wr_misalign_flag:1; +} st_mmc_csd_t; + +typedef struct st_mmc_ext_csd +{ + uint8_t rev; + uint8_t erase_group_def; + uint8_t sec_feature_support; + uint8_t rel_sectors; + uint8_t rel_param; + uint8_t part_config; + uint8_t rst_n_function; + uint8_t cache_ctrl; + uint8_t max_packed_writes; + uint8_t max_packed_reads; + uint8_t packed_event_en; + uint32_t part_time; /* Units: ms */ + uint32_t sa_timeout; /* Units: 100ns */ + uint32_t generic_cmd6_time; /* Units: 10ms */ + uint32_t power_off_longtime; /* Units: ms */ + uint32_t hs_max_dtr; + uint32_t sectors; + uint32_t card_type; + uint32_t hc_erase_size; /* In sectors */ + uint32_t hc_erase_timeout; /* In milliseconds */ + uint32_t sec_trim_mult; /* Secure trim multiplier */ + uint32_t sec_erase_mult; /* Secure erase multiplier */ + uint32_t trim_timeout; /* In milliseconds */ + uint8_t enhanced_area_en; /* enable bit */ + uint64_t enhanced_area_offset; /* Units: Byte */ + uint32_t enhanced_area_size; /* Units: KB */ + uint32_t boot_size; /* in bytes */ + uint32_t cache_size; /* Units: KB */ + uint8_t hpi_en; /* HPI enablebit */ + uint8_t hpi; /* HPI support bit */ + uint32_t hpi_cmd; /* cmd used as HPI */ + uint8_t raw_partition_support; /* 160 */ + uint8_t raw_erased_mem_count; /* 181 */ + uint8_t raw_ext_csd_structure; /* 194 */ + uint8_t raw_card_type; /* 196 */ + uint8_t out_of_int_time; /* 198 */ + uint8_t raw_s_a_timeout; /* 217 */ + uint8_t raw_hc_erase_gap_size; /* 221 */ + uint8_t raw_erase_timeout_mult; /* 223 */ + uint8_t raw_hc_erase_grp_size; /* 224 */ + uint8_t raw_sec_trim_mult; /* 229 */ + uint8_t raw_sec_erase_mult; /* 230 */ + uint8_t raw_sec_feature_support;/* 231 */ + uint8_t raw_trim_mult; /* 232 */ + uint8_t raw_sectors[4]; /* 212 - 4 bytes */ + + uint32_t feature_support; +#define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */ +} st_mmc_ext_csd_t; + +typedef struct st_mmc_cid +{ + uint32_t manfid; + int8_t prod_name[8]; + uint32_t serial; + uint16_t oemid; + uint16_t year; + uint8_t hwrev; + uint8_t fwrev; + uint8_t month; +} st_mmc_cid_t; + +typedef struct st_sd_scr +{ + uint8_t sda_vsn; + uint8_t sda_spec3; + uint8_t bus_wid; + uint8_t sd_cmds; +} st_sd_scr_t; + +typedef struct st_sd_ssr +{ + uint32_t bus_width; + uint16_t cd_type; + uint32_t area_protected; + uint32_t spd_class; + uint8_t perf_mv; + uint32_t au; + uint32_t erase_to; + uint32_t erase_off; +} st_sd_ssr_t; + +typedef struct st_sd_swt_caps +{ + uint32_t hs_max_dtr; + uint32_t uhs_max_dtr; + uint32_t sd3_bus_mode; + uint32_t sd3_drv_type; + uint32_t sd3_curr_limit; +} st_sd_swt_caps_t; + +typedef struct st_sdio_cccr +{ + uint32_t sdio_vsn; + uint32_t sd_vsn; + uint32_t multi_block:1, + low_speed:1, + wide_bus:1, + high_power:1, + high_speed:1, + disable_cd:1; +} st_sdio_cccr_t; + +typedef struct st_sdio_cis +{ + uint16_t vendor; + uint16_t device; + uint16_t blksize; + uint32_t max_dtr; + uint32_t enable_timeout; +} st_sdio_cis_t; + +typedef struct st_sdemmc_config +{ + sdmmc_priv_card_type_t card_type; + uint32_t ocr; + uint32_t rca; + uint32_t type; + uint32_t raw_cid[4]; + uint32_t raw_csd[4]; + uint32_t raw_scr[2]; + uint32_t raw_ssr[16]; + uint32_t use_spi; + uint32_t clock; + uint32_t max_blk_size; + uint32_t cur_blk_size; + uint32_t bus_width; + uint32_t erased_byte; + st_mmc_csd_t csd; + st_mmc_ext_csd_t ext_csd; + st_mmc_cid_t cid; + st_sd_scr_t scr; + st_sd_ssr_t ssr; + st_sd_swt_caps_t caps; + st_sdio_cccr_t cccr; + st_sdio_cis_t cis; + uint8_t pext_csd[SDEMMC_W_PRV_EMMC_EXT_CSD_SIZE]; + uint8_t *psdio_cis; + uint32_t sdio_num_info; + uint8_t **psdio_info; +} st_sdemmc_config_t; + +typedef fsp_err_t (tpl_parse_t)(st_sdemmc_config_t *config, uint8_t *buf, uint32_t size); + +typedef struct tuples_for_cis { + uint8_t code; + uint8_t min_size; + tpl_parse_t *parse; +} st_tuples_for_cis_t; + +/** Common macro for FSP header files. There is also a corresponding FSP_HEADER macro at the top of this file. */ +FSP_FOOTER + +#endif diff --git a/bsp/renesas/ra6w1-ek/rafw_cfg/fsp_cfg/r_dmac_w_cfg.h b/bsp/renesas/ra6w1-ek/rafw_cfg/fsp_cfg/r_dmac_w_cfg.h new file mode 100644 index 000000000000..ab5b17e13eb0 --- /dev/null +++ b/bsp/renesas/ra6w1-ek/rafw_cfg/fsp_cfg/r_dmac_w_cfg.h @@ -0,0 +1,13 @@ +/* generated configuration header file - do not edit */ +#ifndef R_DMAC_W_CFG_H_ +#define R_DMAC_W_CFG_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#define DMAC_W_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE) + +#ifdef __cplusplus +} +#endif +#endif /* R_DMAC_W_CFG_H_ */ diff --git a/bsp/renesas/ra6w1-ek/rafw_cfg/fsp_cfg/r_sdemmc_w_cfg.h b/bsp/renesas/ra6w1-ek/rafw_cfg/fsp_cfg/r_sdemmc_w_cfg.h new file mode 100644 index 000000000000..46b7feaec3bd --- /dev/null +++ b/bsp/renesas/ra6w1-ek/rafw_cfg/fsp_cfg/r_sdemmc_w_cfg.h @@ -0,0 +1,16 @@ +/* generated configuration header file - do not edit */ +#ifndef R_SDEMMC_W_CFG_H_ +#define R_SDEMMC_W_CFG_H_ +#ifdef __cplusplus + extern "C" { + #endif + +#define SDEMMC_W_CFG_PARAM_CHECKING_ENABLE (BSP_CFG_PARAM_CHECKING_ENABLE) +#define SDEMMC_W_CFG_SD_SUPPORT_ENABLE ((1)) +#define SDEMMC_W_CFG_EMMC_SUPPORT_ENABLE ((0)) +#define SDEMMC_W_CFG_SDIO_SUPPORT_ENABLE ((0)) + +#ifdef __cplusplus + } + #endif +#endif /* R_SDEMMC_W_CFG_H_ */ diff --git a/bsp/renesas/ra6w1-ek/rafw_gen/SConscript b/bsp/renesas/ra6w1-ek/rafw_gen/SConscript index 180db757ac47..2ba267e5db50 100644 --- a/bsp/renesas/ra6w1-ek/rafw_gen/SConscript +++ b/bsp/renesas/ra6w1-ek/rafw_gen/SConscript @@ -3,16 +3,8 @@ Import('rtconfig') from building import * cwd = GetCurrentDir() -src = [] -group = [] -CPPPATH = [] +CPPPATH = [cwd] +src = Glob('*.c') -if rtconfig.PLATFORM in ['iccarm']: - print("\nThe current project does not support IAR build\n") - Return('group') -elif rtconfig.PLATFORM in ['gcc', 'armclang']: - src = Glob('*.c') - CPPPATH = [cwd] - -group = DefineGroup('ra_gen', src, depend = [''], CPPPATH = CPPPATH) +group = DefineGroup('rafw_gen', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/bsp/renesas/ra6w1-ek/rafw_gen/bsp_clock_cfg.h b/bsp/renesas/ra6w1-ek/rafw_gen/bsp_clock_cfg.h index 7d3fcb7840ce..f80c57078a9e 100644 --- a/bsp/renesas/ra6w1-ek/rafw_gen/bsp_clock_cfg.h +++ b/bsp/renesas/ra6w1-ek/rafw_gen/bsp_clock_cfg.h @@ -17,13 +17,13 @@ #define BSP_CFG_PLL_SYS_MUL (BSP_CLOCKS_PLL_SYS_CLOCK_MUL_1_3) /* PLL_SYS Mul 1/3 */ #define BSP_CFG_CLOCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL) /* SYS_CLK Src: PLL_SYS */ #define BSP_CFG_HCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* HCLK Div /1 */ -#define BSP_CFG_QSPICLK_DIV (BSP_CLOCKS_QSPI_CLK_DIV_2) /* QSPICLK Div /2 */ +#define BSP_CFG_QSPICLK_DIV (BSP_CLOCKS_QSPI_CLK_DIV_1) /* QSPICLK Div /1 */ #define BSP_CFG_PLL_SPI_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* PLL_SPI Disabled */ #define BSP_CFG_PLL_SPI_MUL (BSP_CLOCKS_PLL_SPI_CLOCK_MUL_1_6) /* PLL_SPI Mul 1/6 */ #define BSP_CFG_SPICLK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_XTAL_SYS) /* SPI_CLK Src: XTAL_SYS */ #define BSP_CFG_PLL_PERI_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL) /* PLL_PERI Src: PLL */ #define BSP_CFG_PLL_PERI_DIV (BSP_CLOCKS_PLL_PERI_CLOCK_DIV_1_6) /* PLL_PERI Div /6 */ -#define BSP_CFG_PERI_CLK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_XTAL_SYS) /* PERI_CLK Src: XTAL_SYS */ +#define BSP_CFG_PERI_CLK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL_PERI) /* PERI_CLK Src: PLL */ #define BSP_CFG_I2C1CLK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_DIV1) /* I2C1 Div /1 */ #define BSP_CFG_I2C2CLK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_DIV1) /* I2C2 Div /1 */ #define BSP_CFG_WDOG_DIV (BSP_CLOCKS_WDOG_DIV_320) /* WDOG Div /320 */ diff --git a/bsp/renesas/ra6w1-ek/rafw_gen/common_data.c b/bsp/renesas/ra6w1-ek/rafw_gen/common_data.c index 86ff4994ec7a..d36ab26cc6c7 100644 --- a/bsp/renesas/ra6w1-ek/rafw_gen/common_data.c +++ b/bsp/renesas/ra6w1-ek/rafw_gen/common_data.c @@ -1,7 +1,15 @@ /* generated common source file - do not edit */ #include "common_data.h" -gpio_w_instance_ctrl_t g_gpio_w_ctrl; -const ioport_instance_t g_gpio_w = { .p_api = &g_ioport_on_gpio_w, .p_ctrl = - &g_gpio_w_ctrl, .p_cfg = &g_bsp_pin_cfg, }; -void g_common_init(void) { + +gpio_w_instance_ctrl_t g_ioport_ctrl; + +const ioport_instance_t g_ioport = +{ + .p_ctrl = &g_ioport_ctrl, + .p_cfg = &g_bsp_pin_cfg, + .p_api = &g_ioport_on_gpio_w, +}; + +void g_common_init(void) +{ } diff --git a/bsp/renesas/ra6w1-ek/rafw_gen/common_data.h b/bsp/renesas/ra6w1-ek/rafw_gen/common_data.h index 88563494ee40..129ae1da9590 100644 --- a/bsp/renesas/ra6w1-ek/rafw_gen/common_data.h +++ b/bsp/renesas/ra6w1-ek/rafw_gen/common_data.h @@ -5,16 +5,28 @@ #include "bsp_api.h" #include "r_gpio_w.h" #include "bsp_pin_cfg.h" -FSP_HEADER -#define IOPORT_CFG_NAME g_bsp_pin_cfg -#define IOPORT_CFG_OPEN R_GPIO_W_Open -#define IOPORT_CFG_CTRL g_gpio_w_ctrl -/* GPIO_W Instance */ -extern const ioport_instance_t g_gpio_w; +#define R_IOPORT_Open R_GPIO_W_Open +#define R_IOPORT_Close R_GPIO_W_Close +#define R_IOPORT_PinsCfg R_GPIO_W_PinsCfg +#define R_IOPORT_PinCfg R_GPIO_W_PinCfg +#define R_IOPORT_PinRead R_GPIO_W_PinRead +#define R_IOPORT_PinWrite R_GPIO_W_PinWrite +#define R_IOPORT_PortDirectionSet R_GPIO_W_PortDirectionSet +#define R_IOPORT_PortEventInputRead R_GPIO_W_PortEventInputRead +#define R_IOPORT_PortEventOutputWrite R_GPIO_W_PortEventOutputWrite +#define R_IOPORT_PortRead R_GPIO_W_PortRead +#define R_IOPORT_PortWrite R_GPIO_W_PortWrite +#ifndef IOPORT_CFG_NMOS_ENABLE +#define IOPORT_CFG_NMOS_ENABLE BSP_IO_DIRECTION_OUTPUT +#endif +#ifndef IOPORT_CFG_NAME +#define IOPORT_CFG_NAME g_bsp_pin_cfg +#endif -/* GPIO_W control structure. */ -extern gpio_w_instance_ctrl_t g_gpio_w_ctrl; +FSP_HEADER +extern const ioport_instance_t g_ioport; +extern gpio_w_instance_ctrl_t g_ioport_ctrl; void g_common_init(void); FSP_FOOTER #endif /* COMMON_DATA_H_ */ diff --git a/bsp/renesas/ra6w1-ek/rafw_gen/hal_data.c b/bsp/renesas/ra6w1-ek/rafw_gen/hal_data.c index f2e6b10bd5c9..65048b0d59a4 100644 --- a/bsp/renesas/ra6w1-ek/rafw_gen/hal_data.c +++ b/bsp/renesas/ra6w1-ek/rafw_gen/hal_data.c @@ -1,47 +1,1021 @@ /* generated HAL source file - do not edit */ #include "hal_data.h" +#include "vector_data.h" + +uart_w_instance_ctrl_t g_uart0_ctrl; + +uart_w_baud_setting_t g_uart0_baud_setting = +{ + .fra_baud = 26, + .int_baud = 43, +}; + +const uart_w_extended_cfg_t g_uart0_cfg_extend = +{ + .p_baud_setting = &g_uart0_baud_setting, + .loop_back_enable = UART_W_LOOP_BACK_DISABLE, + .fifo_enable = UART_W_FIFO_ENABLE, + .rx_fifo_trigger = UART_W_RX_FIFO_TRIGGER_SEVEN_EIGHTHS, + .tx_fifo_trigger = UART_W_TX_FIFO_TRIGGER_EIGHTH, + .flow_control = UART_W_AUTO_FLOW_CONTROL_DISABLED, + .rs485_enable = UART_W_RS485_DISABLE, +}; + +const uart_cfg_t g_uart0_cfg = +{ + .channel = 1 - UART_W_CHANNEL_OFFSET, + .data_bits = UART_W_DATA_BITS_8, + .parity = UART_PARITY_OFF, + .stop_bits = UART_STOP_BITS_1, + .p_callback = user_uart0_callback, + .p_context = NULL, + .p_extend = &g_uart0_cfg_extend, + .p_transfer_tx = NULL, + .p_transfer_rx = NULL, + .rxi_ipl = DEFAULT_UART_W_IRQ_PRIORITY, +#if defined(VECTOR_NUMBER_UARTW0_IRQ) + .rxi_irq = VECTOR_NUMBER_UARTW0_IRQ, +#else + .rxi_irq = FSP_INVALID_VECTOR, +#endif +}; + +const uart_instance_t g_uart0 = +{ + .p_ctrl = &g_uart0_ctrl, + .p_cfg = &g_uart0_cfg, + .p_api = &g_uart_on_uart_w, +}; + +#ifdef BSP_USING_UART1 uart_w_instance_ctrl_t g_uart1_ctrl; -/** UART_W extended configuration for UART HAL driver */ -uart_w_baud_setting_t g_uart1_baud_setting = { .fra_baud = 26, .int_baud = 43 }; -/** UART extended configuration for UART_W HAL driver */ +uart_w_baud_setting_t g_uart1_baud_setting = +{ + .fra_baud = 26, + .int_baud = 43, +}; + const uart_w_extended_cfg_t g_uart1_cfg_extend = - { .fifo_enable = UART_W_FIFO_ENABLE, .rx_fifo_trigger = - UART_W_RX_FIFO_TRIGGER_SEVEN_EIGHTHS, .tx_fifo_trigger = - UART_W_TX_FIFO_TRIGGER_EIGHTH, .p_baud_setting = - &g_uart1_baud_setting, .flow_control = - UART_W_AUTO_FLOW_CONTROL_DISABLED, .loop_back_enable = - UART_W_LOOP_BACK_DISABLE, .rs485_enable = UART_W_RS485_DISABLE, }; - -/** UART interface configuration */ -const uart_cfg_t g_uart1_cfg = { .channel = 1 - UART_W_CHANNEL_OFFSET, - .data_bits = UART_W_DATA_BITS_8, .parity = UART_PARITY_OFF, .stop_bits = - UART_STOP_BITS_1, .p_callback = user_uart0_callback, .p_context = - NULL, .p_extend = &g_uart1_cfg_extend, -#define FSP_NOT_DEFINED (1) -#if (FSP_NOT_DEFINED == FSP_NOT_DEFINED) - .p_transfer_tx = NULL, -#else - .p_transfer_tx = &FSP_NOT_DEFINED, -#endif -#if (FSP_NOT_DEFINED == FSP_NOT_DEFINED) - .p_transfer_rx = NULL, -#else - .p_transfer_rx = &FSP_NOT_DEFINED, -#endif -#undef FSP_NOT_DEFINED - .rxi_ipl = (12), +{ + .p_baud_setting = &g_uart1_baud_setting, + .loop_back_enable = UART_W_LOOP_BACK_DISABLE, + .fifo_enable = UART_W_FIFO_ENABLE, + .rx_fifo_trigger = UART_W_RX_FIFO_TRIGGER_SEVEN_EIGHTHS, + .tx_fifo_trigger = UART_W_TX_FIFO_TRIGGER_EIGHTH, + .flow_control = UART_W_AUTO_FLOW_CONTROL_DISABLED, + .rs485_enable = UART_W_RS485_DISABLE, +}; + +const uart_cfg_t g_uart1_cfg = +{ + .channel = 2 - UART_W_CHANNEL_OFFSET, + .data_bits = UART_W_DATA_BITS_8, + .parity = UART_PARITY_OFF, + .stop_bits = UART_STOP_BITS_1, + .p_callback = user_uart1_callback, + .p_context = NULL, + .p_extend = &g_uart1_cfg_extend, + .p_transfer_tx = NULL, + .p_transfer_rx = NULL, + .rxi_ipl = DEFAULT_UART_W_IRQ_PRIORITY, #if defined(VECTOR_NUMBER_UARTW1_IRQ) - .rxi_irq = VECTOR_NUMBER_UARTW1_IRQ, + .rxi_irq = VECTOR_NUMBER_UARTW1_IRQ, +#else + .rxi_irq = FSP_INVALID_VECTOR, +#endif +}; + +const uart_instance_t g_uart1 = +{ + .p_ctrl = &g_uart1_ctrl, + .p_cfg = &g_uart1_cfg, + .p_api = &g_uart_on_uart_w, +}; +#endif + +#ifdef BSP_USING_UART2 + +#define RA6W1_UART2_CALLBACK user_uart2_callback +#define RA6W1_UART2_FLOW_CONTROL UART_W_AUTO_FLOW_CONTROL_DISABLED +#define RA6W1_UART2_RXI_IPL DEFAULT_UART_W_IRQ_PRIORITY + +uart_w_instance_ctrl_t g_uart2_ctrl; + +uart_w_baud_setting_t g_uart2_baud_setting = +{ + .fra_baud = 26, + .int_baud = 43, +}; + +const uart_w_extended_cfg_t g_uart2_cfg_extend = +{ + .p_baud_setting = &g_uart2_baud_setting, + .loop_back_enable = UART_W_LOOP_BACK_DISABLE, + .fifo_enable = UART_W_FIFO_ENABLE, + .rx_fifo_trigger = UART_W_RX_FIFO_TRIGGER_SEVEN_EIGHTHS, + .tx_fifo_trigger = UART_W_TX_FIFO_TRIGGER_EIGHTH, + .flow_control = RA6W1_UART2_FLOW_CONTROL, + .rs485_enable = UART_W_RS485_DISABLE, +}; + +const uart_cfg_t g_uart2_cfg = +{ + .channel = 3 - UART_W_CHANNEL_OFFSET, + .data_bits = UART_W_DATA_BITS_8, + .parity = UART_PARITY_OFF, + .stop_bits = UART_STOP_BITS_1, + .p_callback = RA6W1_UART2_CALLBACK, + .p_context = NULL, + .p_extend = &g_uart2_cfg_extend, + .p_transfer_tx = NULL, + .p_transfer_rx = NULL, + .rxi_ipl = RA6W1_UART2_RXI_IPL, +#if defined(VECTOR_NUMBER_UARTW2_IRQ) + .rxi_irq = VECTOR_NUMBER_UARTW2_IRQ, +#else + .rxi_irq = FSP_INVALID_VECTOR, +#endif +}; + +const uart_instance_t g_uart2 = +{ + .p_ctrl = &g_uart2_ctrl, + .p_cfg = &g_uart2_cfg, + .p_api = &g_uart_on_uart_w, +}; +#undef RA6W1_UART2_CALLBACK +#undef RA6W1_UART2_FLOW_CONTROL +#undef RA6W1_UART2_RXI_IPL +#endif + +#ifdef BSP_USING_ADC +#define RA6W1_ADC_SCAN_MASK ((1U << BSP_USING_ADC_PIN_NUM) - 1U) + +adc_w_instance_ctrl_t g_adc0_ctrl; + +static const adc_w_channel_cfg_t g_adc0_channel_cfg_default = +{ + .interrupt_mode_fifo = ADC_W_INTERRUPT_FIFO_NONE, + .interrupt_mode_thd = ADC_W_INTERRUPT_THD_NONE, + .dma_en = ADC_W_DMA_DISABLED, + .sensorwakeup_en = ADC_W_SENSOR_WAKEUP_DISABLED, + .thd_value = 0, + .threshold_mode = ADC_W_SENSOR_WAKEUP_THD_OVER, +}; + +const adc_w_extended_cfg_t g_adc0_cfg_extend = +{ + .conversion_clockdiv = 3, + .upper_bound_limit = 0x0FFF, + .lower_bound_limit = 0, + .p_channel_cfgs = + { + &g_adc0_channel_cfg_default, + &g_adc0_channel_cfg_default, + &g_adc0_channel_cfg_default, + &g_adc0_channel_cfg_default, + }, + .timer_count_clock_source = ADC_W_TIMER_COUNT_SOURCE_1000, + .timer_value = 1, + .sample_average = ADC_W_SAMPLE_AVERAGE_4, +}; + +const adc_w_scan_cfg_t g_adc0_channel_cfg = +{ + .scan_mask = RA6W1_ADC_SCAN_MASK, +}; + +const adc_cfg_t g_adc0_cfg = +{ + .unit = 0, + .mode = ADC_MODE_CONTINUOUS_SCAN, + .resolution = ADC_RESOLUTION_12_BIT, + .alignment = ADC_ALIGNMENT_RIGHT, + .trigger = ADC_TRIGGER_SOFTWARE, + .scan_end_irq = FSP_INVALID_VECTOR, + .scan_end_b_irq = FSP_INVALID_VECTOR, + .scan_end_c_irq = FSP_INVALID_VECTOR, + .scan_end_ipl = BSP_IRQ_DISABLED, + .scan_end_b_ipl = BSP_IRQ_DISABLED, + .scan_end_c_ipl = BSP_IRQ_DISABLED, + .p_callback = NULL, + .p_context = NULL, + .p_extend = &g_adc0_cfg_extend, +}; + +const adc_instance_t g_adc0 = +{ + .p_ctrl = &g_adc0_ctrl, + .p_cfg = &g_adc0_cfg, + .p_channel_cfg = &g_adc0_channel_cfg, + .p_api = &g_adc_on_adc_w, +}; +#endif + +#ifdef BSP_USING_TIM_W +#define RA6W1_TIM_DEFAULT_SOURCE_DIV TIMER_SOURCE_DIV_32 +#define RA6W1_TIM_DEFAULT_PERIOD_COUNTS ((BSP_CFG_XTALM_HZ / 32U) / 1000U) +#define RA6W1_TIM_PWM_PERIOD_COUNTS (1000U) +#define RA6W1_TIM_PWM_DUTY_COUNTS (500U) + +#define RA6W1_TIM_MODE(num) RA6W1_TIM_MODE_I(num) +#define RA6W1_TIM_MODE_I(num) RA6W1_TIM_MODE_##num +#define RA6W1_TIM_PERIOD(num) RA6W1_TIM_PERIOD_I(num) +#define RA6W1_TIM_PERIOD_I(num) RA6W1_TIM_PERIOD_##num +#define RA6W1_TIM_DUTY(num) RA6W1_TIM_DUTY_I(num) +#define RA6W1_TIM_DUTY_I(num) RA6W1_TIM_DUTY_##num +#define RA6W1_TIM_IRQ(num) RA6W1_TIM_IRQ_I(num) +#define RA6W1_TIM_IRQ_I(num) RA6W1_TIM_IRQ_##num +#define RA6W1_TIM_CALLBACK(num) RA6W1_TIM_CALLBACK_I(num) +#define RA6W1_TIM_CALLBACK_I(num) RA6W1_TIM_CALLBACK_##num + +#ifdef BSP_USING_PWM0 +#define RA6W1_TIM_MODE_0 TIMER_MODE_PWM +#define RA6W1_TIM_PERIOD_0 RA6W1_TIM_PWM_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_0 RA6W1_TIM_PWM_DUTY_COUNTS +#define RA6W1_TIM_IRQ_0 FSP_INVALID_VECTOR +#define RA6W1_TIM_CALLBACK_0 NULL +#else +#define RA6W1_TIM_MODE_0 TIMER_MODE_PERIODIC +#define RA6W1_TIM_PERIOD_0 RA6W1_TIM_DEFAULT_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_0 0U +#define RA6W1_TIM_IRQ_0 VECTOR_NUMBER_TIMW0_IRQ +#define RA6W1_TIM_CALLBACK_0 timer0_callback +#endif + +#ifdef BSP_USING_PWM1 +#define RA6W1_TIM_MODE_1 TIMER_MODE_PWM +#define RA6W1_TIM_PERIOD_1 RA6W1_TIM_PWM_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_1 RA6W1_TIM_PWM_DUTY_COUNTS +#define RA6W1_TIM_IRQ_1 FSP_INVALID_VECTOR +#define RA6W1_TIM_CALLBACK_1 NULL +#else +#define RA6W1_TIM_MODE_1 TIMER_MODE_PERIODIC +#define RA6W1_TIM_PERIOD_1 RA6W1_TIM_DEFAULT_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_1 0U +#define RA6W1_TIM_IRQ_1 VECTOR_NUMBER_TIMW1_IRQ +#define RA6W1_TIM_CALLBACK_1 timer1_callback +#endif + +#ifdef BSP_USING_PWM2 +#define RA6W1_TIM_MODE_2 TIMER_MODE_PWM +#define RA6W1_TIM_PERIOD_2 RA6W1_TIM_PWM_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_2 RA6W1_TIM_PWM_DUTY_COUNTS +#define RA6W1_TIM_IRQ_2 FSP_INVALID_VECTOR +#define RA6W1_TIM_CALLBACK_2 NULL +#else +#define RA6W1_TIM_MODE_2 TIMER_MODE_PERIODIC +#define RA6W1_TIM_PERIOD_2 RA6W1_TIM_DEFAULT_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_2 0U +#define RA6W1_TIM_IRQ_2 VECTOR_NUMBER_TIMW2_IRQ +#define RA6W1_TIM_CALLBACK_2 timer2_callback +#endif + +#ifdef BSP_USING_PWM3 +#define RA6W1_TIM_MODE_3 TIMER_MODE_PWM +#define RA6W1_TIM_PERIOD_3 RA6W1_TIM_PWM_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_3 RA6W1_TIM_PWM_DUTY_COUNTS +#define RA6W1_TIM_IRQ_3 FSP_INVALID_VECTOR +#define RA6W1_TIM_CALLBACK_3 NULL +#else +#define RA6W1_TIM_MODE_3 TIMER_MODE_PERIODIC +#define RA6W1_TIM_PERIOD_3 RA6W1_TIM_DEFAULT_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_3 0U +#define RA6W1_TIM_IRQ_3 VECTOR_NUMBER_TIMW3_IRQ +#define RA6W1_TIM_CALLBACK_3 timer3_callback +#endif + +#ifdef BSP_USING_PWM4 +#define RA6W1_TIM_MODE_4 TIMER_MODE_PWM +#define RA6W1_TIM_PERIOD_4 RA6W1_TIM_PWM_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_4 RA6W1_TIM_PWM_DUTY_COUNTS +#define RA6W1_TIM_IRQ_4 FSP_INVALID_VECTOR +#define RA6W1_TIM_CALLBACK_4 NULL +#else +#define RA6W1_TIM_MODE_4 TIMER_MODE_PERIODIC +#define RA6W1_TIM_PERIOD_4 RA6W1_TIM_DEFAULT_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_4 0U +#define RA6W1_TIM_IRQ_4 VECTOR_NUMBER_TIMW4_IRQ +#define RA6W1_TIM_CALLBACK_4 timer4_callback +#endif + +#ifdef BSP_USING_PWM5 +#define RA6W1_TIM_MODE_5 TIMER_MODE_PWM +#define RA6W1_TIM_PERIOD_5 RA6W1_TIM_PWM_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_5 RA6W1_TIM_PWM_DUTY_COUNTS +#define RA6W1_TIM_IRQ_5 FSP_INVALID_VECTOR +#define RA6W1_TIM_CALLBACK_5 NULL +#else +#define RA6W1_TIM_MODE_5 TIMER_MODE_PERIODIC +#define RA6W1_TIM_PERIOD_5 RA6W1_TIM_DEFAULT_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_5 0U +#define RA6W1_TIM_IRQ_5 VECTOR_NUMBER_TIMW5_IRQ +#define RA6W1_TIM_CALLBACK_5 timer5_callback +#endif + +#ifdef BSP_USING_PWM6 +#define RA6W1_TIM_MODE_6 TIMER_MODE_PWM +#define RA6W1_TIM_PERIOD_6 RA6W1_TIM_PWM_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_6 RA6W1_TIM_PWM_DUTY_COUNTS +#define RA6W1_TIM_IRQ_6 FSP_INVALID_VECTOR +#define RA6W1_TIM_CALLBACK_6 NULL +#else +#define RA6W1_TIM_MODE_6 TIMER_MODE_PERIODIC +#define RA6W1_TIM_PERIOD_6 RA6W1_TIM_DEFAULT_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_6 0U +#define RA6W1_TIM_IRQ_6 VECTOR_NUMBER_TIMW6_IRQ +#define RA6W1_TIM_CALLBACK_6 timer6_callback +#endif + +#ifdef BSP_USING_PWM7 +#define RA6W1_TIM_MODE_7 TIMER_MODE_PWM +#define RA6W1_TIM_PERIOD_7 RA6W1_TIM_PWM_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_7 RA6W1_TIM_PWM_DUTY_COUNTS +#define RA6W1_TIM_IRQ_7 FSP_INVALID_VECTOR +#define RA6W1_TIM_CALLBACK_7 NULL +#else +#define RA6W1_TIM_MODE_7 TIMER_MODE_PERIODIC +#define RA6W1_TIM_PERIOD_7 RA6W1_TIM_DEFAULT_PERIOD_COUNTS +#define RA6W1_TIM_DUTY_7 0U +#define RA6W1_TIM_IRQ_7 VECTOR_NUMBER_TIMW7_IRQ +#define RA6W1_TIM_CALLBACK_7 timer7_callback +#endif + +#define RA6W1_TIM_INSTANCE_DEFINE(num, tim_channel, irq_vector) \ + tim_w_instance_ctrl_t g_timer##num##_ctrl; \ + \ + const tim_w_extended_cfg_t g_timer##num##_extend = \ + { \ + .free_run = false, \ + .count_source = TIM_W_CLOCK_DIVN, \ + .direction = TIMER_DIRECTION_UP, \ + .pwm_sync_map = 0, \ + .gpio_source = BSP_IO_PORT_00_PIN_00, \ + .gpio_trigger = TIM_W_GPIO_TRIGGER_DISABLED, \ + .oneshot_switch_to_periodic = false, \ + .oneshot_delay = 0, \ + .p_ccm_cfg = NULL, \ + }; \ + \ + const timer_cfg_t g_timer##num##_cfg = \ + { \ + .mode = RA6W1_TIM_MODE(num), \ + .period_counts = RA6W1_TIM_PERIOD(num), \ + .source_div = (timer_source_div_t) RA6W1_TIM_DEFAULT_SOURCE_DIV, \ + .duty_cycle_counts = RA6W1_TIM_DUTY(num), \ + .channel = (tim_channel), \ + .cycle_end_ipl = 12, \ + .cycle_end_irq = RA6W1_TIM_IRQ(num), \ + .p_callback = RA6W1_TIM_CALLBACK(num), \ + .p_context = NULL, \ + .p_extend = &g_timer##num##_extend, \ + }; \ + \ + const timer_instance_t g_timer##num = \ + { \ + .p_ctrl = &g_timer##num##_ctrl, \ + .p_cfg = &g_timer##num##_cfg, \ + .p_api = &g_timer_on_tim_w, \ + }; + +#ifdef BSP_USING_TIM0 +RA6W1_TIM_INSTANCE_DEFINE(0, TIM_W_TIM1, VECTOR_NUMBER_TIMW0_IRQ) +#endif +#ifdef BSP_USING_TIM1 +RA6W1_TIM_INSTANCE_DEFINE(1, TIM_W_TIM2, VECTOR_NUMBER_TIMW1_IRQ) +#endif +#ifdef BSP_USING_TIM2 +RA6W1_TIM_INSTANCE_DEFINE(2, TIM_W_TIM3, VECTOR_NUMBER_TIMW2_IRQ) +#endif +#ifdef BSP_USING_TIM3 +RA6W1_TIM_INSTANCE_DEFINE(3, TIM_W_TIM4, VECTOR_NUMBER_TIMW3_IRQ) +#endif +#ifdef BSP_USING_TIM4 +RA6W1_TIM_INSTANCE_DEFINE(4, TIM_W_TIM5, VECTOR_NUMBER_TIMW4_IRQ) +#endif +#ifdef BSP_USING_TIM5 +RA6W1_TIM_INSTANCE_DEFINE(5, TIM_W_TIM6, VECTOR_NUMBER_TIMW5_IRQ) +#endif +#ifdef BSP_USING_TIM6 +RA6W1_TIM_INSTANCE_DEFINE(6, TIM_W_TIM7, VECTOR_NUMBER_TIMW6_IRQ) +#endif +#ifdef BSP_USING_TIM7 +RA6W1_TIM_INSTANCE_DEFINE(7, TIM_W_TIM8, VECTOR_NUMBER_TIMW7_IRQ) +#endif + +#undef RA6W1_TIM_INSTANCE_DEFINE +#undef RA6W1_TIM_MODE +#undef RA6W1_TIM_MODE_I +#undef RA6W1_TIM_PERIOD +#undef RA6W1_TIM_PERIOD_I +#undef RA6W1_TIM_DUTY +#undef RA6W1_TIM_DUTY_I +#undef RA6W1_TIM_IRQ +#undef RA6W1_TIM_IRQ_I +#undef RA6W1_TIM_CALLBACK +#undef RA6W1_TIM_CALLBACK_I +#undef RA6W1_TIM_PWM_PERIOD_COUNTS +#undef RA6W1_TIM_PWM_DUTY_COUNTS +#undef RA6W1_TIM_DEFAULT_SOURCE_DIV +#undef RA6W1_TIM_DEFAULT_PERIOD_COUNTS +#endif /* BSP_USING_TIM_W */ + +#ifdef BSP_USING_HW_I2C0 +i2c_master_w_instance_ctrl_t g_i2c_master0_ctrl; + +const i2c_master_w_extended_cfg_t g_i2c_master0_extend = +{ +#if (I2C_MASTER_W_CFG_DMA_ENABLE) + .enable_dma_bursts_tx = 0, + .enable_dma_bursts_rx = 0, +#endif + .select_divn = BSP_CFG_I2C1CLK_SOURCE, +#if defined(VECTOR_NUMBER_I2CW0_IRQ) + .gen_irq = VECTOR_NUMBER_I2CW0_IRQ, +#else + .gen_irq = FSP_INVALID_VECTOR, +#endif + .gen_ipl = 12, + /* Actual calculated bitrate: 399600. Actual calculated duty cycle: 50%. Frequency of the selected clock source: 80000000. */ + .clock_settings.scl_lcnt = 100, + .clock_settings.scl_hcnt = 93, +}; + +const i2c_master_cfg_t g_i2c_master0_cfg = +{ + .channel = 1 - I2C_MASTER_W_CHANNEL_OFFSET, + .rate = I2C_MASTER_RATE_FAST, + .slave = 0x1D, + .addr_mode = I2C_MASTER_ADDR_MODE_7BIT, + .p_transfer_tx = NULL, + .p_transfer_rx = NULL, + .p_callback = i2c_master_callback, + .p_context = NULL, +#if defined(VECTOR_NUMBER_I2CW0_RX_IRQ) + .rxi_irq = VECTOR_NUMBER_I2CW0_RX_IRQ, +#else + .rxi_irq = FSP_INVALID_VECTOR, +#endif +#if defined(VECTOR_NUMBER_I2CW0_TXE_IRQ) + .txi_irq = VECTOR_NUMBER_I2CW0_TXE_IRQ, +#else + .txi_irq = FSP_INVALID_VECTOR, +#endif +#if defined(VECTOR_NUMBER_I2CW0_TXR_IRQ) + .tei_irq = VECTOR_NUMBER_I2CW0_TXR_IRQ, +#else + .tei_irq = FSP_INVALID_VECTOR, +#endif +#if defined(VECTOR_NUMBER_I2CW0_ERR_IRQ) + .eri_irq = VECTOR_NUMBER_I2CW0_ERR_IRQ, +#else + .eri_irq = FSP_INVALID_VECTOR, +#endif + .ipl = BSP_IRQ_DISABLED, + .p_extend = &g_i2c_master0_extend, +}; + +const i2c_master_instance_t g_i2c_master0 = +{ + .p_ctrl = &g_i2c_master0_ctrl, + .p_cfg = &g_i2c_master0_cfg, + .p_api = &g_i2c_master_on_i2c_w, +}; +#endif + +#ifdef BSP_USING_HW_I2C1 +i2c_master_w_instance_ctrl_t g_i2c_master1_ctrl; + +const i2c_master_w_extended_cfg_t g_i2c_master1_extend = +{ +#if (I2C_MASTER_W_CFG_DMA_ENABLE) + .enable_dma_bursts_tx = 0, + .enable_dma_bursts_rx = 0, +#endif + .select_divn = BSP_CFG_I2C2CLK_SOURCE, +#if defined(VECTOR_NUMBER_I2CW1_IRQ) + .gen_irq = VECTOR_NUMBER_I2CW1_IRQ, +#else + .gen_irq = FSP_INVALID_VECTOR, +#endif + .gen_ipl = 12, + /* Actual calculated bitrate: 399600. Actual calculated duty cycle: 50%. Frequency of the selected clock source: 80000000. */ + .clock_settings.scl_lcnt = 100, + .clock_settings.scl_hcnt = 93, +}; + +const i2c_master_cfg_t g_i2c_master1_cfg = +{ + .channel = 2 - I2C_MASTER_W_CHANNEL_OFFSET, + .rate = I2C_MASTER_RATE_FAST, + .slave = 0x1D, + .addr_mode = I2C_MASTER_ADDR_MODE_7BIT, + .p_transfer_tx = NULL, + .p_transfer_rx = NULL, + .p_callback = i2c_master_callback, + .p_context = NULL, +#if defined(VECTOR_NUMBER_I2CW1_RX_IRQ) + .rxi_irq = VECTOR_NUMBER_I2CW1_RX_IRQ, +#else + .rxi_irq = FSP_INVALID_VECTOR, +#endif +#if defined(VECTOR_NUMBER_I2CW1_TXE_IRQ) + .txi_irq = VECTOR_NUMBER_I2CW1_TXE_IRQ, +#else + .txi_irq = FSP_INVALID_VECTOR, +#endif +#if defined(VECTOR_NUMBER_I2CW1_TXR_IRQ) + .tei_irq = VECTOR_NUMBER_I2CW1_TXR_IRQ, +#else + .tei_irq = FSP_INVALID_VECTOR, +#endif +#if defined(VECTOR_NUMBER_I2CW1_ERR_IRQ) + .eri_irq = VECTOR_NUMBER_I2CW1_ERR_IRQ, +#else + .eri_irq = FSP_INVALID_VECTOR, +#endif + .ipl = BSP_IRQ_DISABLED, + .p_extend = &g_i2c_master1_extend, +}; + +const i2c_master_instance_t g_i2c_master1 = +{ + .p_ctrl = &g_i2c_master1_ctrl, + .p_cfg = &g_i2c_master1_cfg, + .p_api = &g_i2c_master_on_i2c_w, +}; +#endif + +#ifdef BSP_USING_SPI0 +spi_w_instance_ctrl_t g_spi0_ctrl; + +spi_w_extended_cfg_t g_spi0_cfg_extend = +{ + .spck_div = 0, + .byte_swap = SPI_W_BYTE_SWAP_DISABLE, + .cap_edge = SPI_W_CAPTURE_CURRENT_EDGE, + .cs_select = SPI_W_CS_SELECT_CS0, + .rx_fifo_lvl_thres = 1, + .tx_fifo_lvl_thres = 1, +#if defined(VECTOR_NUMBER_SPIW0_IRQ) + .gen_irq = VECTOR_NUMBER_SPIW0_IRQ, +#else + .gen_irq = FSP_INVALID_VECTOR, +#endif + .gen_ipl = 4, +#if SPI_W_CFG_FAST_MODE_ENABLE + .skip_disable = false, +#endif + .skip_busy_check = false, +}; + +const spi_cfg_t g_spi0_cfg = +{ + .channel = 0, + .rxi_irq = FSP_INVALID_VECTOR, + .txi_irq = FSP_INVALID_VECTOR, + .tei_irq = FSP_INVALID_VECTOR, + .eri_irq = FSP_INVALID_VECTOR, + .rxi_ipl = BSP_IRQ_DISABLED, + .txi_ipl = BSP_IRQ_DISABLED, + .tei_ipl = BSP_IRQ_DISABLED, + .eri_ipl = BSP_IRQ_DISABLED, + .operating_mode = SPI_MODE_MASTER, + .clk_phase = SPI_CLK_PHASE_EDGE_ODD, + .clk_polarity = SPI_CLK_POLARITY_LOW, + .mode_fault = SPI_MODE_FAULT_ERROR_DISABLE, + .bit_order = SPI_BIT_ORDER_MSB_FIRST, + .p_transfer_tx = NULL, + .p_transfer_rx = NULL, + .p_callback = spi0_callback, + .p_context = NULL, + .p_extend = &g_spi0_cfg_extend, +}; + +const spi_instance_t g_spi0 = +{ + .p_ctrl = &g_spi0_ctrl, + .p_cfg = &g_spi0_cfg, + .p_api = &g_spi_on_spi_w, +}; +#endif + +#ifdef BSP_USING_SPI1 +spi_w_instance_ctrl_t g_spi1_ctrl; + +spi_w_extended_cfg_t g_spi1_cfg_extend = +{ + .spck_div = 0, + .byte_swap = SPI_W_BYTE_SWAP_DISABLE, + .cap_edge = SPI_W_CAPTURE_CURRENT_EDGE, + .cs_select = SPI_W_CS_SELECT_CS0, + .rx_fifo_lvl_thres = 1, + .tx_fifo_lvl_thres = 1, +#if defined(VECTOR_NUMBER_SPIW1_IRQ) + .gen_irq = VECTOR_NUMBER_SPIW1_IRQ, #else - .rxi_irq = FSP_INVALID_VECTOR, + .gen_irq = FSP_INVALID_VECTOR, +#endif + .gen_ipl = 4, +#if SPI_W_CFG_FAST_MODE_ENABLE + .skip_disable = false, +#endif + .skip_busy_check = false, +}; + +const spi_cfg_t g_spi1_cfg = +{ + .channel = 1, + .rxi_irq = FSP_INVALID_VECTOR, + .txi_irq = FSP_INVALID_VECTOR, + .tei_irq = FSP_INVALID_VECTOR, + .eri_irq = FSP_INVALID_VECTOR, + .rxi_ipl = BSP_IRQ_DISABLED, + .txi_ipl = BSP_IRQ_DISABLED, + .tei_ipl = BSP_IRQ_DISABLED, + .eri_ipl = BSP_IRQ_DISABLED, + .operating_mode = SPI_MODE_MASTER, + .clk_phase = SPI_CLK_PHASE_EDGE_ODD, + .clk_polarity = SPI_CLK_POLARITY_LOW, + .mode_fault = SPI_MODE_FAULT_ERROR_DISABLE, + .bit_order = SPI_BIT_ORDER_MSB_FIRST, + .p_transfer_tx = NULL, + .p_transfer_rx = NULL, + .p_callback = spi1_callback, + .p_context = NULL, + .p_extend = &g_spi1_cfg_extend, +}; + +const spi_instance_t g_spi1 = +{ + .p_ctrl = &g_spi1_ctrl, + .p_cfg = &g_spi1_cfg, + .p_api = &g_spi_on_spi_w, +}; +#endif + + +#ifdef BSP_USING_QSPI_PSRAM +qspi_w_instance_ctrl_t g_qspi_ram0_ctrl; + +static qspi_w_write_instr_cfg_t g_qspi_ram0_write_cfg = +{ + .write_opcode = 0x38, + .write_opcode_wb = 0, + .opcode_bus_mode = QSPI_W_BUS_MODE_QUAD, + .addr_bus_mode = QSPI_W_BUS_MODE_QUAD, + .data_bus_mode = QSPI_W_BUS_MODE_QUAD, + .dummy_bus_mode = QSPI_W_BUS_MODE_QUAD, + .dummy_en = false, + .dummy_bytes = 0, + .wdex_en = 0, + .cs_hi_min_clk_cycles = 0x01, + .send_wen_req = 0, +}; + +static qspi_w_read_instr_cfg_t g_qspi_ram0_read_cfg = +{ + .opcode = 0xEB, + .opcode_wb = 0, + .extra_byte_value = 0xFF, + .opcode_bus_mode = QSPI_W_BUS_MODE_QUAD, + .addr_bus_mode = QSPI_W_BUS_MODE_QUAD, + .extra_byte_bus_mode = QSPI_W_BUS_MODE_QUAD, + .dummy_bus_mode = QSPI_W_BUS_MODE_QUAD, + .data_bus_mode = QSPI_W_BUS_MODE_QUAD, + .extra_byte_en = QSPI_W_EXTRA_BYTE_ENABLE, + .extra_byte_half_cfg = QSPI_W_EXTRA_BYTE_HALF_DISABLE, + .dummy_bytes = 2, + .dummy_en = true, + .dummy_force = false, + .instr_md = QSPI_W_INSTR_MD_TX_AT_ANY_BURST_ACCESS, + .wrap_md = QSPI_W_WRAP_MD_SEL_INSTR, + .wrap_blen = 0, + .wrap_size = 0, + .wrap_wr_en = QSPI_W_WRAP_WR_EN_INST, + .cs_high_min_cycles = 0x01, + .rd_bend_md = QSPI_W_RD_BEND_MD_TERMINATE_ASAP, + .rd_rdb_en = QSPI_W_RD_RDB_EN_MIN_CLK_PULSES, +}; + +static qspi_w_break_instr_cfg_t g_qspi_ram0_break_cfg = +{ + .break_opcode = 0xffff, + .break_sz = 0, + .break_tx_md = QSPI_W_BUS_MODE_QUAD, + .break_sec_hf = QSPI_W_BREAK_SEC_HF_DRIVE, + .break_en = QSPI_W_BREAK_DISABLE, /* APS6404L PSRAM does not require read-break */ +}; + +static qspi_w_memblen_cfg_t g_qspi_ram0_memblen_cfg = +{ + .memblen = QSPI_W_MEMBLEN_BURST_INCR_UNSPECIFIED, + .tcem_cc = 0, + .tcem_en = QSPI_W_T_CEM_DISABLE, + .rd_lin_en = false, + .keep_active = false, /* Must be false for PSRAM: tCEM limits max CS low time */ + .wcmd_hybrid = false, + .dielen = 0, + .active_thr = 0, +}; + +static qspi_w_ctrl_ddr_cfg_t g_qspi_ram0_ddr_cfg = +{ + .ctrl_ddra = 0, + .ctrl_ddrb = 0, +}; + +static qspi_w_extra_registers_cfg_t g_qspi_ram0_extra_regs_cfg = +{ + .ctrl_mr_reg = 0, + .drst_cmd_reg = 0, +}; + +static qspi_w_flash_cfg_t g_qspi_ram0_flash_cfg = +{ + .is_ram = true, + .clk_mode = QSPI_W_CLK_MODE_LOW, + .p_read_instr_cfg = &g_qspi_ram0_read_cfg, + .p_write_instr_cfg = &g_qspi_ram0_write_cfg, + .p_break_instr_cfg = &g_qspi_ram0_break_cfg, + .p_memblen_cfg = &g_qspi_ram0_memblen_cfg, + .p_ctrl_ddr = &g_qspi_ram0_ddr_cfg, + .p_extra_regs = &g_qspi_ram0_extra_regs_cfg, +}; + +static qspi_w_extended_cfg_t g_qspi_ram0_extended_cfg = +{ + .channel = 0, + .qspi_mode = QSPI_W_MODE_SDR, + .qspclk_div = (qspi_w_qspclk_div_t) BSP_CFG_QSPICLK_DIV, + .qspi_drive_current = QSPI_W_DRIVE_CURRENT_4, + .qspi_slew_rate = QSPI_W_SLEW_RATE_FAST, + .p_qspi_flash_cfg = &g_qspi_ram0_flash_cfg, + .qspi_dcache = QSPI_W_DCACHE_DISABLE, /* PSRAM is read-write; dcache is for flash only */ +}; + +const spi_flash_cfg_t g_qspi_ram0_cfg = +{ + .spi_protocol = 0, + .read_mode = 0, + .dummy_clocks = 0, + .page_program_address_lines = 0, + .page_program_command = 0, + .address_bytes = SPI_FLASH_ADDRESS_BYTES_3, + .page_size_bytes = 256, + .p_extend = &g_qspi_ram0_extended_cfg, +}; + +const spi_flash_instance_t g_qspi_ram0 = +{ + .p_ctrl = &g_qspi_ram0_ctrl, + .p_cfg = &g_qspi_ram0_cfg, + .p_api = &g_spi_flash_on_qspi_w, +}; +#endif + + +#ifdef BSP_USING_OSPI_FLASH +/*********************************************************************************************************************** + * Private global variables + **********************************************************************************************************************/ + +static spi_flash_erase_command_t g_ospi_flash_erase_command_list[] = +{ +#if ((0x20 > 0) && (4096 > 0)) + {.command = 0x20, .size = 4096 }, +#endif +#if ((0x52 > 0) && (32768 > 0)) + {.command = 0x52, .size = 32768}, +#endif +#if (0xD8 > 0) + {.command = 0xD8, .size = 65536}, +#endif +}; + +ospi_w_xspi_command_set_t g_ospi_flash_high_speed_command_set = +{ + .protocol = SPI_FLASH_PROTOCOL_1S_4S_4S, + .command_bytes = OSPI_W_COMMAND_BYTES_1, + .read_command = 0xEB, + .page_program_command = 0x32, + .write_enable_command = 0x06, + .status_command = 0x05, + .read_dummy_cycles = 0x02, + .program_dummy_cycles = 0, + .status_dummy_cycles = 0, + + /* Use the default commands spi_flash_cfg_t */ + .p_erase_command_list = NULL, + .erase_command_list_length = 0, +}; + +ospi_w_device_config_t g_ospi_flash_hw_cfg = +{ + .clk_div = OSPI_W_DEVICE_CLK_DIV_2, + .bus_mode = OSPI_W_DEVICE_BUS_MODE_SINGLE, + .access_mode = OSPI_W_DEVICE_ACCESS_MODE_AUTO, + .clock_mode = OSPI_W_DEVICE_CLK_MODE_HIGH, + .io2_dir = OSPI_W_DEVICE_IO_DIR_AUTO_SEL, + .io2_value = OSPI_W_DEVICE_IO_VALUE_LOW, + .io3_dir = OSPI_W_DEVICE_IO_DIR_AUTO_SEL, + .io3_value = OSPI_W_DEVICE_IO_VALUE_LOW, + .io4_7_dir = OSPI_W_DEVICE_IO_DIR_AUTO_SEL, + .io4_7_value = OSPI_W_DEVICE_IO4_7_VALUE_0000, + .hready_mode = OSPI_W_DEVICE_HREADY_MODE_WAIT, + .sampling_edge = OSPI_W_DEVICE_SAMPLING_EDGE_NEG, + .read_pipe = OSPI_W_DEVICE_READ_PIPE_ENABLE, + .read_pipe_delay = OSPI_W_DEVICE_READ_PIPE_DELAY_7, + .address_size = OSPI_W_DEVICE_ADDR_SIZE_24, + .dummy_mode = OSPI_W_DEVICE_DUMMY_MODE_LAST_2_CLK, + .slew_rate = OSPI_W_DEVICE_SLEW_RATE_0, + .drive_current = OSPI_W_DEVICE_DRIVE_CURRENT_12, + .manualmode_config.dir_change_mode = OSPI_W_DEVICE_DIR_CHANGE_MODE_DUMMY_ACCESS, + .manualmode_config.mapped_addr_rd_acc_response = OSPI_W_DEVICE_MAPPED_ADDR_RD_ACC_RESPONSE_IGNORE, + .automode_config.full_buffer_mode = OSPI_W_DEVICE_FULL_BUFFER_MODE_BLOCK, + .automode_config.instruct_size = OSPI_W_DEVICE_INSTRUCT_SZ_1_BYTE, + .automode_config.burst_len_limit = OSPI_W_DEVICE_BURST_LEN_LIMIT_UNSPECIFIED, +}; + +ospi_w_device_read_instr_config_t g_ospi_flash_read_instr_config = +{ + .enable = 1, + .instr = 0xEB, + .instr_extra_byte = 0xA0, + .instr_bus_mode = OSPI_W_DEVICE_BUS_MODE_SINGLE, + .addr_bus_mode = OSPI_W_DEVICE_BUS_MODE_QUAD, + .extra_byte_bus_mode = OSPI_W_DEVICE_BUS_MODE_QUAD, + .dummy_bus_mode = OSPI_W_DEVICE_BUS_MODE_QUAD, + .data_bus_mode = OSPI_W_DEVICE_BUS_MODE_QUAD, + .extra_byte_cfg = OSPI_W_DEVICE_EXTRA_BYTE_ENABLE, + .extra_byte_half_cfg = OSPI_W_DEVICE_EXTRA_BYTE_HALF_DISABLE, + .dummy_bytes = 2, + .instr_mode = OSPI_W_DEVICE_INSTR_MODE_SEND_ONCE, + .idle_state_duration = OSPI_W_DEVICE_IDLE_STATE_DURATION_3, +}; + +ospi_w_device_wrap_burst_instr_config_t g_ospi_flash_wrap_burst_instr_config = +{ + .enable = 0, +}; + +ospi_w_device_read_status_config_t g_ospi_flash_read_status_config = +{ + .enable = 1, + .instr = 0x05, + .instr_bus_mode = OSPI_W_DEVICE_BUS_MODE_SINGLE, + .receive_bus_mode = OSPI_W_DEVICE_BUS_MODE_SINGLE, + .dummy_bus_mode = OSPI_W_DEVICE_BUS_MODE_SINGLE, + .busy_pos = 0, + .busy_val = OSPI_W_DEVICE_BUSY_HIGH, + .read_stat_del = 0, + + .read_stat_reg_cnt = OSPI_W_DEVICE_READ_STATUS_REG_CNT_RESSTS, + .dummy_bytes = 0, + .dummy_val = 0, +}; + +ospi_w_device_erase_instr_config_t g_ospi_flash_erase_instr_config = +{ + .enable = 1, + .instr = 0x20, + .instr_bus_mode = OSPI_W_DEVICE_BUS_MODE_SINGLE, + .addr_bus_mode = OSPI_W_DEVICE_BUS_MODE_SINGLE, + .hclk_cycles = 14, + .cs_hi_cycles = 30, +}; + +ospi_w_device_write_enable_instr_config_t g_ospi_flash_write_enable_instr_config = +{ + .enable = 1, + .instr = 0x06, + .instr_bus_mode = OSPI_W_DEVICE_BUS_MODE_SINGLE, +}; + +ospi_w_device_suspend_resume_instr_config_t g_ospi_flash_suspend_resume_instr_config = +{ + .enable = 1, + .suspend_instr = 0x75, + .resume_instr = 0x7A, + .suspend_bus_mode = OSPI_W_DEVICE_BUS_MODE_SINGLE, + .resume_bus_mode = OSPI_W_DEVICE_BUS_MODE_SINGLE, + .read_stat_del = 128, +}; + +ospi_w_extended_cfg_t g_ospi_flash_extended_cfg = +{ + .channel = 0, + .p_timing_settings = NULL, + .p_xspi_command_set_list = &g_ospi_flash_high_speed_command_set, + .xspi_command_set_list_length = 1, + .p_autocalibration_preamble_pattern_addr = NULL, + .data_latch_delay_clocks = 0, +#if OSPI_W_CFG_DMAC_SUPPORT_ENABLE + + /* DMA Transfer instance used for data transmission */ + transfer_instance_t const * p_lower_lvl_transfer; +#endif + .p_ospi_w_device_cfg = &g_ospi_flash_hw_cfg, + .p_read_instr_cfg = &g_ospi_flash_read_instr_config, + .p_wrap_burst_instr_cfg = &g_ospi_flash_wrap_burst_instr_config, + .p_read_status_instr_cfg = &g_ospi_flash_read_status_config, + .p_write_enable_instr_cfg = &g_ospi_flash_write_enable_instr_config, + .p_erase_instr_cfg = &g_ospi_flash_erase_instr_config, + .p_suspend_resume_instr_cfg = &g_ospi_flash_suspend_resume_instr_config, +}; +spi_flash_cfg_t g_ospi_flash_cfg = +{ + .spi_protocol = SPI_FLASH_PROTOCOL_1S_1S_1S, + .read_mode = SPI_FLASH_READ_MODE_FAST_READ_QUAD_IO, + .address_bytes = SPI_FLASH_ADDRESS_BYTES_3, + .dummy_clocks = SPI_FLASH_DUMMY_CLOCKS_2, + .page_program_address_lines = SPI_FLASH_DATA_LINES_4, + .page_size_bytes = 256, + .write_status_bit = 0, + .write_enable_bit = 1, + .page_program_command = 0x32, + .write_enable_command = 0x06, + .status_command = 0x05, + .read_command = 0xEB, + .xip_enter_command = 0U, + .xip_exit_command = 0U, + .erase_command_list_length = sizeof(g_ospi_flash_erase_command_list) / + sizeof(g_ospi_flash_erase_command_list[0]), + .p_erase_command_list = &g_ospi_flash_erase_command_list[0], + .p_extend = &g_ospi_flash_extended_cfg, +}; + +/** This structure encompasses everything that is needed to use an instance of this interface. */ +ospi_w_instance_ctrl_t g_ospi_flash_ctrl; +#endif + +#ifdef BSP_USING_ONCHIP_RTC +rtc_w_instance_ctrl_t g_rtc_w_ctrl; + +static const rtc_extended_cfg_t g_rtc_w_cfg_extend = +{ + .reserved = 0U, +}; + +const rtc_cfg_t g_rtc_w_cfg = +{ + .clock_source = RTC_CLOCK_SOURCE_SUBCLK, + .freq_compare_value = 0U, + .p_err_cfg = NULL, + .alarm_ipl = BSP_IRQ_DISABLED, + .alarm_irq = FSP_INVALID_VECTOR, + .periodic_ipl = BSP_IRQ_DISABLED, + .periodic_irq = FSP_INVALID_VECTOR, + .carry_ipl = BSP_IRQ_DISABLED, + .carry_irq = FSP_INVALID_VECTOR, + .p_callback = NULL, + .p_context = NULL, + .p_extend = &g_rtc_w_cfg_extend, +}; + +const rtc_instance_t g_rtc_w = +{ + .p_ctrl = &g_rtc_w_ctrl, + .p_cfg = &g_rtc_w_cfg, + .p_api = &g_rtc_on_rtc_w, +}; +#endif + +#ifdef BSP_USING_WDT +#ifndef BSP_WDOG_TIMEOUT_CLOCKS +#define BSP_WDOG_TIMEOUT_CLOCKS (1000U) /* 10 seconds at the 100 Hz WDT clock. */ #endif - }; +wdog_w_instance_ctrl_t g_wdog_w_ctrl; + +static const wdog_w_extended_cfg_t g_wdog_w_cfg_extend = +{ + .wdt_clk_src = WDOG_W_CLK_SRC_RCLP, +}; + +const wdt_cfg_t g_wdog_w_cfg = +{ + .timeout = BSP_WDOG_TIMEOUT_CLOCKS, + .clock_division = WDT_CLOCK_DIVISION_1, + .window_start = WDT_WINDOW_START_100, + .window_end = WDT_WINDOW_END_0, + .reset_control = WDT_RESET_CONTROL_RESET, + .stop_control = WDT_STOP_CONTROL_DISABLE, + .p_callback = NULL, + .p_context = NULL, + .p_extend = &g_wdog_w_cfg_extend, +}; + +const wdt_instance_t g_wdog_w = +{ + .p_ctrl = &g_wdog_w_ctrl, + .p_cfg = &g_wdog_w_cfg, + .p_api = &g_wdt_on_wdog_w, +}; +#endif -/* Instance structure to use this module. */ -const uart_instance_t g_uart1 = { .p_ctrl = &g_uart1_ctrl, - .p_cfg = &g_uart1_cfg, .p_api = &g_uart_on_uart_w }; -void g_hal_init(void) { - g_common_init(); +void g_hal_init(void) +{ + g_common_init(); } diff --git a/bsp/renesas/ra6w1-ek/rafw_gen/hal_data.h b/bsp/renesas/ra6w1-ek/rafw_gen/hal_data.h index 32c889808291..82ab73f9818b 100644 --- a/bsp/renesas/ra6w1-ek/rafw_gen/hal_data.h +++ b/bsp/renesas/ra6w1-ek/rafw_gen/hal_data.h @@ -2,22 +2,173 @@ #ifndef HAL_DATA_H_ #define HAL_DATA_H_ #include +#include #include "bsp_api.h" #include "common_data.h" #include "r_uart_w.h" -#include "r_uart_api.h" +#include "r_spi_w.h" +#include "r_ospi_w.h" +#include "r_qspi_w.h" +#include "r_spi_flash_api.h" +#include "r_ext_irq_w.h" +#include "r_i2c_master_w.h" +#include "r_adc_w.h" +#include "r_tim_w.h" +#include "r_rtc_w.h" +#include "r_wdog_w.h" + + FSP_HEADER -/** UART_W Instance. */ -extern const uart_instance_t g_uart1; +void user_uart0_callback(uart_callback_args_t * p_args); +extern const uart_instance_t g_uart0; +extern uart_w_instance_ctrl_t g_uart0_ctrl; +extern const uart_cfg_t g_uart0_cfg; +extern const uart_w_extended_cfg_t g_uart0_cfg_extend; -/** Access the UART instance using these structures when calling API functions directly (::p_api is not used). */ +#ifdef BSP_USING_UART1 +void user_uart1_callback(uart_callback_args_t * p_args); +extern const uart_instance_t g_uart1; extern uart_w_instance_ctrl_t g_uart1_ctrl; extern const uart_cfg_t g_uart1_cfg; extern const uart_w_extended_cfg_t g_uart1_cfg_extend; +#endif -#ifndef user_uart0_callback -void user_uart0_callback(uart_callback_args_t *p_args); +#ifdef BSP_USING_UART2 +void user_uart2_callback(uart_callback_args_t * p_args); +extern const uart_instance_t g_uart2; +extern uart_w_instance_ctrl_t g_uart2_ctrl; +extern const uart_cfg_t g_uart2_cfg; +extern const uart_w_extended_cfg_t g_uart2_cfg_extend; #endif + +#ifdef BSP_USING_HW_I2C +void i2c_master_callback(i2c_master_callback_args_t *p_args); +#ifdef BSP_USING_HW_I2C0 +extern const i2c_master_instance_t g_i2c_master0; +extern i2c_master_w_instance_ctrl_t g_i2c_master0_ctrl; +extern const i2c_master_cfg_t g_i2c_master0_cfg; +extern const i2c_master_w_extended_cfg_t g_i2c_master0_extend; +#endif + +#ifdef BSP_USING_HW_I2C1 +extern const i2c_master_instance_t g_i2c_master1; +extern i2c_master_w_instance_ctrl_t g_i2c_master1_ctrl; +extern const i2c_master_cfg_t g_i2c_master1_cfg; +extern const i2c_master_w_extended_cfg_t g_i2c_master1_extend; +#endif +#endif + +#ifdef BSP_USING_ADC +extern const adc_instance_t g_adc0; +extern adc_w_instance_ctrl_t g_adc0_ctrl; +extern const adc_cfg_t g_adc0_cfg; +extern const adc_w_scan_cfg_t g_adc0_channel_cfg; +extern const adc_w_extended_cfg_t g_adc0_cfg_extend; +#endif + +#ifdef BSP_USING_TIM0 +void timer0_callback(timer_callback_args_t * p_args); +extern const timer_instance_t g_timer0; +extern tim_w_instance_ctrl_t g_timer0_ctrl; +extern const timer_cfg_t g_timer0_cfg; +extern const tim_w_extended_cfg_t g_timer0_extend; +#endif + +#ifdef BSP_USING_TIM1 +void timer1_callback(timer_callback_args_t * p_args); +extern const timer_instance_t g_timer1; +extern tim_w_instance_ctrl_t g_timer1_ctrl; +extern const timer_cfg_t g_timer1_cfg; +extern const tim_w_extended_cfg_t g_timer1_extend; +#endif + +#ifdef BSP_USING_TIM2 +void timer2_callback(timer_callback_args_t * p_args); +extern const timer_instance_t g_timer2; +extern tim_w_instance_ctrl_t g_timer2_ctrl; +extern const timer_cfg_t g_timer2_cfg; +extern const tim_w_extended_cfg_t g_timer2_extend; +#endif + +#ifdef BSP_USING_TIM3 +void timer3_callback(timer_callback_args_t * p_args); +extern const timer_instance_t g_timer3; +extern tim_w_instance_ctrl_t g_timer3_ctrl; +extern const timer_cfg_t g_timer3_cfg; +extern const tim_w_extended_cfg_t g_timer3_extend; +#endif + +#ifdef BSP_USING_TIM4 +void timer4_callback(timer_callback_args_t * p_args); +extern const timer_instance_t g_timer4; +extern tim_w_instance_ctrl_t g_timer4_ctrl; +extern const timer_cfg_t g_timer4_cfg; +extern const tim_w_extended_cfg_t g_timer4_extend; +#endif + +#ifdef BSP_USING_TIM5 +void timer5_callback(timer_callback_args_t * p_args); +extern const timer_instance_t g_timer5; +extern tim_w_instance_ctrl_t g_timer5_ctrl; +extern const timer_cfg_t g_timer5_cfg; +extern const tim_w_extended_cfg_t g_timer5_extend; +#endif + +#ifdef BSP_USING_TIM6 +void timer6_callback(timer_callback_args_t * p_args); +extern const timer_instance_t g_timer6; +extern tim_w_instance_ctrl_t g_timer6_ctrl; +extern const timer_cfg_t g_timer6_cfg; +extern const tim_w_extended_cfg_t g_timer6_extend; +#endif + +#ifdef BSP_USING_TIM7 +void timer7_callback(timer_callback_args_t * p_args); +extern const timer_instance_t g_timer7; +extern tim_w_instance_ctrl_t g_timer7_ctrl; +extern const timer_cfg_t g_timer7_cfg; +extern const tim_w_extended_cfg_t g_timer7_extend; +#endif + +#ifdef BSP_USING_QSPI_PSRAM +extern const spi_flash_instance_t g_qspi_ram0; +extern qspi_w_instance_ctrl_t g_qspi_ram0_ctrl; +extern const spi_flash_cfg_t g_qspi_ram0_cfg; +#endif + +#ifdef BSP_USING_SPI0 +void spi0_callback(spi_callback_args_t * p_args); +extern const spi_instance_t g_spi0; +extern spi_w_instance_ctrl_t g_spi0_ctrl; +extern const spi_cfg_t g_spi0_cfg; +extern spi_w_extended_cfg_t g_spi0_cfg_extend; +#endif + +#ifdef BSP_USING_SPI1 +void spi1_callback(spi_callback_args_t * p_args); +extern const spi_instance_t g_spi1; +extern spi_w_instance_ctrl_t g_spi1_ctrl; +extern const spi_cfg_t g_spi1_cfg; +extern spi_w_extended_cfg_t g_spi1_cfg_extend; +#endif + +#ifdef BSP_USING_OSPI_FLASH +extern ospi_w_instance_ctrl_t g_ospi_flash_ctrl; +extern spi_flash_cfg_t g_ospi_flash_cfg; +#endif + +#ifdef BSP_USING_ONCHIP_RTC +extern rtc_w_instance_ctrl_t g_rtc_w_ctrl; +extern const rtc_cfg_t g_rtc_w_cfg; +extern const rtc_instance_t g_rtc_w; +#endif + +#ifdef BSP_USING_WDT +extern wdog_w_instance_ctrl_t g_wdog_w_ctrl; +extern const wdt_cfg_t g_wdog_w_cfg; +extern const wdt_instance_t g_wdog_w; +#endif + void hal_entry(void); void g_hal_init(void); FSP_FOOTER diff --git a/bsp/renesas/ra6w1-ek/rafw_gen/pin_data.c b/bsp/renesas/ra6w1-ek/rafw_gen/pin_data.c index 8b8eec63a0f7..97c34d11d7c1 100644 --- a/bsp/renesas/ra6w1-ek/rafw_gen/pin_data.c +++ b/bsp/renesas/ra6w1-ek/rafw_gen/pin_data.c @@ -1,100 +1,656 @@ /* generated pin source file - do not edit */ +#include +#define DBG_TAG "pin" +#define DBG_LVL DBG_INFO +#include #include "bsp_api.h" +#include "hal_data.h" #include "r_gpio_w.h" -const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = { { .pin = BSP_IO_PORT_00_PIN_00, - .pin_cfg = (GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN - | GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_SLW_FAST - | GPIO_W_PERIPHERAL_UART_RX) }, { .pin = BSP_IO_PORT_00_PIN_01, - .pin_cfg = (GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN - | GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_SLOW - | GPIO_W_PERIPHERAL_UART_TX) }, { .pin = BSP_IO_PORT_00_PIN_02, - .pin_cfg = (GPIO_W_CFG_ANALOG_ENABLE | GPIO_W_CFG_DRV_8mA - | GPIO_W_CFG_SLW_SLOW) }, { .pin = BSP_IO_PORT_00_PIN_03, - .pin_cfg = (GPIO_W_CFG_ANALOG_ENABLE | GPIO_W_CFG_DRV_8mA - | GPIO_W_CFG_SLW_SLOW) }, { .pin = BSP_IO_PORT_00_PIN_10, - .pin_cfg = (GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PORT_DIRECTION_OUTPUT - | GPIO_W_CFG_PORT_OUTPUT_LOW | GPIO_W_CFG_SLW_SLOW) }, { .pin = - BSP_IO_PORT_01_PIN_00, .pin_cfg = (GPIO_W_CFG_DRV_8mA - | GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_PORT_OUTPUT_LOW - | GPIO_W_CFG_SLW_SLOW) }, { .pin = BSP_IO_PORT_01_PIN_01, .pin_cfg = - (GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PORT_DIRECTION_OUTPUT - | GPIO_W_CFG_PORT_OUTPUT_LOW | GPIO_W_CFG_SLW_SLOW) }, { .pin = - BSP_IO_PORT_01_PIN_02, .pin_cfg = (GPIO_W_CFG_DRV_8mA - | GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_PORT_OUTPUT_LOW - | GPIO_W_CFG_SLW_SLOW) }, { .pin = BSP_IO_PORT_01_PIN_03, .pin_cfg = - (GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PORT_DIRECTION_OUTPUT - | GPIO_W_CFG_PORT_OUTPUT_LOW | GPIO_W_CFG_SLW_SLOW) }, { .pin = - BSP_IO_PORT_01_PIN_16, .pin_cfg = (GPIO_W_CFG_PERIPHERAL_PIN - | GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_PERIPHERAL_SWCLK) }, { .pin = - BSP_IO_PORT_01_PIN_17, .pin_cfg = (GPIO_W_CFG_PERIPHERAL_PIN - | GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_PERIPHERAL_SWDIO) }, }; - -#if !defined(BSP_MCU_GROUP_RA6W1) //TIN-TODO -gpio_w_extended_cfg_t g_bsp_pin_cfg_extd = { .power.p1_pwr = - GPIO_W_CFG_SUPPLY_V30, -#if BSP_FEATURE_IO_HAS_WEAK_CONFIG_PER_PORT - .weak_pad_power = - { - .p0_pwr = GPIO_W_CFG_DRV_NORMAL, - .p1_pwr = GPIO_W_CFG_DRV_NORMAL, - #if BSP_FEATURE_IO_PORT2_GPIO_COUNT > 0 - .p2_pwr = GPIO_W_CFG_DRV_NORMAL, - #endif - }, -#else - .weak_pad_power.aggregate = GPIO_W_CFG_DRV_NORMAL, -#endif - .fixed_pin_clk_out = BSP_IO_CLK_NONE_OUT, -#if BSP_CFG_CLKOUT_SOURCE - .sel_pin_clk_out.clk_en = 1, - .sel_pin_clk_out.clk_sel = BSP_CFG_CLKOUT_SOURCE - 1, -#else - .sel_pin_clk_out.clk_en = 0, .sel_pin_clk_out.clk_sel = - (bsp_io_clk_func_t) 0, -#endif - }; -#endif - -const ioport_cfg_t g_bsp_pin_cfg = { .number_of_pins = - sizeof(g_bsp_pin_cfg_data) / sizeof(ioport_pin_cfg_t), .p_pin_cfg_data = - &g_bsp_pin_cfg_data[0], -#if !defined(BSP_MCU_GROUP_RA6W1) //TIN-TODO - .p_extend = &g_bsp_pin_cfg_extd, -#endif - }; - -#if BSP_TZ_SECURE_BUILD - -void R_BSP_PinCfgSecurityInit(void); - -/* Initialize SAR registers for secure pins. */ -void R_BSP_PinCfgSecurityInit(void) +ioport_pin_cfg_t g_bsp_pin_cfg_data[] = { - #if (2U == BSP_FEATURE_IOPORT_VERSION) - uint32_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; - #else - uint16_t pmsar[BSP_FEATURE_BSP_NUM_PMSAR]; - #endif - memset(pmsar, 0xFF, BSP_FEATURE_BSP_NUM_PMSAR * sizeof(R_PMISC->PMSAR[0])); +#ifdef BSP_USING_UART0 + { + .pin = BSP_IO_PORT_00_PIN_00, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_UART_RX, + }, + { + .pin = BSP_IO_PORT_00_PIN_01, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_UART_TX, + }, +#endif +#ifdef BSP_USING_UART1 + { + .pin = BSP_IO_PORT_00_PIN_04, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_UART2_RX, + }, + { + .pin = BSP_IO_PORT_00_PIN_05, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_UART2_TX, + }, +#endif +#ifdef BSP_USING_UART2 + { + .pin = BSP_IO_PORT_01_PIN_10, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_UART3_RX, + }, + { + .pin = BSP_IO_PORT_01_PIN_11, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_UART3_TX, + }, +#endif + +#ifdef BSP_USING_PWM0 + { + .pin = BSP_IO_PORT_00_PIN_04, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_TIM_PWM, + }, +#endif + +#ifdef BSP_USING_PWM1 + { + .pin = BSP_IO_PORT_00_PIN_05, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_TIM2_PWM, + }, +#endif +#ifdef BSP_USING_PWM2 + { + .pin = BSP_IO_PORT_00_PIN_06, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_TIM3_PWM, + }, +#endif +#ifdef BSP_USING_PWM3 + { + .pin = BSP_IO_PORT_00_PIN_07, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_TIM4_PWM, + }, +#endif +#ifdef BSP_USING_PWM4 + { + .pin = BSP_IO_PORT_01_PIN_00, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_TIM5_PWM, + }, +#endif +#ifdef BSP_USING_PWM5 + { + .pin = BSP_IO_PORT_01_PIN_01, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_TIM6_PWM, + }, +#endif +#ifdef BSP_USING_PWM6 + { + .pin = BSP_IO_PORT_01_PIN_02, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_TIM7_PWM, + }, +#endif +#ifdef BSP_USING_PWM7 + { + .pin = BSP_IO_PORT_01_PIN_03, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_TIM8_PWM, + }, +#endif + +#ifdef BSP_USING_HW_I2C0 + { + .pin = BSP_IO_PORT_00_PIN_04, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_OPEN_DRAIN_ENABLE | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_I2C_SCL, + }, + { + .pin = BSP_IO_PORT_00_PIN_05, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_OPEN_DRAIN_ENABLE | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_I2C_SDA, + }, +#endif +#ifdef BSP_USING_HW_I2C1 + { + .pin = BSP_IO_PORT_00_PIN_06, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_OPEN_DRAIN_ENABLE | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_I2C2_SCL, + }, + { + .pin = BSP_IO_PORT_00_PIN_07, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_OPEN_DRAIN_ENABLE | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_I2C2_SDA, + }, +#endif + +#ifdef BSP_USING_ADC +#if BSP_USING_ADC_PIN_NUM >= 1 + { + .pin = BSP_IO_PORT_00_PIN_04, + .pin_cfg = GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_ANALOG_ENABLE, + }, +#endif +#if BSP_USING_ADC_PIN_NUM >= 2 + { + .pin = BSP_IO_PORT_00_PIN_05, + .pin_cfg = GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_ANALOG_ENABLE, + }, +#endif +#if BSP_USING_ADC_PIN_NUM >= 3 + { + .pin = BSP_IO_PORT_00_PIN_06, + .pin_cfg = GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_ANALOG_ENABLE, + }, +#endif +#if BSP_USING_ADC_PIN_NUM >= 4 + { + .pin = BSP_IO_PORT_00_PIN_07, + .pin_cfg = GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_ANALOG_ENABLE, + }, +#endif +#endif + +#ifdef BSP_USING_SPI0 + { + .pin = BSP_IO_PORT_01_PIN_00, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_SPI_CLK, + }, + { + .pin = BSP_IO_PORT_01_PIN_01, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_SPI_DI, + }, + { + .pin = BSP_IO_PORT_01_PIN_02, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_SPI_DO, + }, + { + .pin = BSP_IO_PORT_01_PIN_03, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_SPI_CSN0, + }, +#endif +#if defined(BSP_USING_SPI1) + { + .pin = BSP_IO_PORT_01_PIN_12, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_SPI2_CLK, + }, + { + .pin = BSP_IO_PORT_01_PIN_13, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_SPI2_DI, + }, + { + .pin = BSP_IO_PORT_01_PIN_14, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_SPI2_DO, + }, + { + .pin = BSP_IO_PORT_01_PIN_15, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST | + GPIO_W_PERIPHERAL_SPI2_CSN0, + }, +#endif +#ifdef BSP_USING_QSPI + { + .pin = BSP_IO_PORT_00_PIN_08, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST, + }, + { + .pin = BSP_IO_PORT_00_PIN_09, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_OUTPUT | GPIO_W_CFG_SLW_FAST, + }, + { + .pin = BSP_IO_PORT_00_PIN_10, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_SLW_FAST, + }, + { + .pin = BSP_IO_PORT_00_PIN_11, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_SLW_FAST, + }, + { + .pin = BSP_IO_PORT_00_PIN_12, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_SLW_FAST, + }, + { + .pin = BSP_IO_PORT_00_PIN_13, + .pin_cfg = GPIO_W_CFG_DRV_8mA | GPIO_W_CFG_PERIPHERAL_PIN | + GPIO_W_CFG_PORT_DIRECTION_INPUT | GPIO_W_CFG_SLW_FAST, + }, +#endif + { + .pin = BSP_IO_PORT_01_PIN_16, + .pin_cfg = GPIO_W_CFG_PERIPHERAL_PIN | GPIO_W_CFG_PORT_DIRECTION_INPUT | + GPIO_W_PERIPHERAL_SWCLK, + }, + { + .pin = BSP_IO_PORT_01_PIN_17, + .pin_cfg = GPIO_W_CFG_PERIPHERAL_PIN | GPIO_W_CFG_PORT_DIRECTION_INPUT | + GPIO_W_PERIPHERAL_SWDIO, + }, +}; + +static const char * const g_bsp_pin_cfg_name[] = +{ +#ifdef BSP_USING_UART0 + "uart0.rx", + "uart0.tx", +#endif +#ifdef BSP_USING_UART1 + "uart1.rx", + "uart1.tx", +#endif +#ifdef BSP_USING_UART2 + "uart2.rx", + "uart2.tx", +#endif + +#ifdef BSP_USING_PWM0 + "pwm0", +#endif + +#ifdef BSP_USING_PWM1 + "pwm1", +#endif +#ifdef BSP_USING_PWM2 + "pwm2", +#endif +#ifdef BSP_USING_PWM3 + "pwm3", +#endif +#ifdef BSP_USING_PWM4 + "pwm4", +#endif +#ifdef BSP_USING_PWM5 + "pwm5", +#endif +#ifdef BSP_USING_PWM6 + "pwm6", +#endif +#ifdef BSP_USING_PWM7 + "pwm7", +#endif + +#ifdef BSP_USING_HW_I2C0 + "i2c0.scl", + "i2c0.sda", +#endif +#ifdef BSP_USING_HW_I2C1 + "i2c1.scl", + "i2c1.sda", +#endif + +#ifdef BSP_USING_ADC +#if BSP_USING_ADC_PIN_NUM >= 1 + "adc0", +#endif +#if BSP_USING_ADC_PIN_NUM >= 2 + "adc1", +#endif +#if BSP_USING_ADC_PIN_NUM >= 3 + "adc2", +#endif +#if BSP_USING_ADC_PIN_NUM >= 4 + "adc3", +#endif +#endif + +#ifdef BSP_USING_SPI0 + "spi0.clk", + "spi0.di", + "spi0.do", + "spi0.csn0", +#endif +#if defined(BSP_USING_SPI1) + "spi1.clk", + "spi1.di", + "spi1.do", + "spi1.csn0", +#endif +#ifdef BSP_USING_QSPI + "qspi.clk", + "qspi.csn", + "qspi.io0", + "qspi.io1", + "qspi.io2", + "qspi.io3", +#endif + "swd.swclk", + "swd.swdio", +}; + +#define RA_W_PIN_CFG_COUNT (sizeof(g_bsp_pin_cfg_data) / sizeof(g_bsp_pin_cfg_data[0])) +#define RA_W_PIN_NAME_COUNT (sizeof(g_bsp_pin_cfg_name) / sizeof(g_bsp_pin_cfg_name[0])) + +struct ra_w_invalid_pin_cfg +{ + const char *cfg_name; + const char *pin_name; + bsp_io_port_pin_t default_pin; +}; + +static struct ra_w_invalid_pin_cfg ra_w_invalid_pin_cfg_data[RA_W_PIN_CFG_COUNT]; +static uint32_t ra_w_invalid_pin_cfg_count; +static int ra_w_pin_layout_error; + +static int ra_w_pin_valid(bsp_io_port_pin_t pin) +{ + uint32_t port = ((uint32_t) pin & BSP_IO_PORT_BITS) >> BSP_IO_PORT_OFFSET; + uint32_t pin_id = (uint32_t) pin & BSP_IO_PIN_BITS; + + return (((port == BSP_IO_PORT_00) && (pin_id < BSP_FEATURE_IO_PORT0_GPIO_COUNT)) || + ((port == BSP_IO_PORT_01) && (pin_id < BSP_FEATURE_IO_PORT1_GPIO_COUNT))); +} + +static void ra_w_pin_to_string(bsp_io_port_pin_t pin, char *buf, uint32_t size) +{ + uint32_t port = ((uint32_t) pin & BSP_IO_PORT_BITS) >> BSP_IO_PORT_OFFSET; + uint32_t pin_id = (uint32_t) pin & BSP_IO_PIN_BITS; + + rt_snprintf(buf, size, "P%u_%02u", port, pin_id); +} + +static const char *ra_w_pin_cfg_name_get(uint32_t index) +{ + if (index < RA_W_PIN_NAME_COUNT) + { + return g_bsp_pin_cfg_name[index]; + } + + return "unknown"; +} + +static void ra_w_invalid_pin_cfg_record(const char *cfg_name, + const char *pin_name, + bsp_io_port_pin_t default_pin) +{ + if (ra_w_invalid_pin_cfg_count < RA_W_PIN_CFG_COUNT) + { + ra_w_invalid_pin_cfg_data[ra_w_invalid_pin_cfg_count].cfg_name = cfg_name; + ra_w_invalid_pin_cfg_data[ra_w_invalid_pin_cfg_count].pin_name = pin_name; + ra_w_invalid_pin_cfg_data[ra_w_invalid_pin_cfg_count].default_pin = default_pin; + } + + ra_w_invalid_pin_cfg_count++; +} + +static int ra_w_pin_name_parse(const char *name, bsp_io_port_pin_t *p_pin) +{ + int port = -1; + int pin_id = -1; + + if ((name == RT_NULL) || (p_pin == RT_NULL)) + { + return -1; + } + + if (((name[0] == 'P') || (name[0] == 'p')) && (name[1] >= '0') && (name[1] <= '9')) + { + port = name[1] - '0'; + + if ((name[2] == '_') && (name[3] >= '0') && (name[3] <= '9') && + (name[4] >= '0') && (name[4] <= '9') && (name[5] == '\0')) + { + pin_id = ((name[3] - '0') * 10) + (name[4] - '0'); + } + else if ((name[2] >= '0') && (name[2] <= '9') && + (name[3] >= '0') && (name[3] <= '9') && (name[4] == '\0')) + { + pin_id = ((name[2] - '0') * 10) + (name[3] - '0'); + } + } + + if (((port == BSP_IO_PORT_00) && (pin_id >= 0) && (pin_id < BSP_FEATURE_IO_PORT0_GPIO_COUNT)) || + ((port == BSP_IO_PORT_01) && (pin_id >= 0) && (pin_id < BSP_FEATURE_IO_PORT1_GPIO_COUNT))) + { + *p_pin = (bsp_io_port_pin_t) ((port << BSP_IO_PORT_OFFSET) | pin_id); + return 0; + } + + return -1; +} + +static bsp_io_port_pin_t ra_w_pin_cfg_get(const char *cfg_name, const char *name, bsp_io_port_pin_t default_pin) +{ + bsp_io_port_pin_t pin; + + if (ra_w_pin_name_parse(name, &pin) == 0) + { + return pin; + } + + ra_w_invalid_pin_cfg_record(cfg_name, name, default_pin); + + return default_pin; +} + +static void ra_w_pin_config_set(uint32_t *p_index, const char *cfg_name, const char *pin_name) +{ + uint32_t index = *p_index; + + if (index >= RA_W_PIN_CFG_COUNT) + { + ra_w_pin_layout_error = 1; + return; + } + + (*p_index)++; + g_bsp_pin_cfg_data[index].pin = ra_w_pin_cfg_get(cfg_name, pin_name, g_bsp_pin_cfg_data[index].pin); +} + +void ra_w_pin_config_check(void) +{ + uint32_t i; + uint32_t j; + int error_count = 0; + + for (i = 0; (i < ra_w_invalid_pin_cfg_count) && (i < RA_W_PIN_CFG_COUNT); i++) + { + char default_pin_name[8]; + + ra_w_pin_to_string(ra_w_invalid_pin_cfg_data[i].default_pin, + default_pin_name, + sizeof(default_pin_name)); + LOG_E("invalid %s pin \"%s\", use default %s", + ra_w_invalid_pin_cfg_data[i].cfg_name, + ra_w_invalid_pin_cfg_data[i].pin_name == RT_NULL ? + "(null)" : ra_w_invalid_pin_cfg_data[i].pin_name, + default_pin_name); + error_count++; + } + + if (ra_w_invalid_pin_cfg_count > RA_W_PIN_CFG_COUNT) + { + LOG_E("%u invalid pin config(s) not listed", + (unsigned int) (ra_w_invalid_pin_cfg_count - RA_W_PIN_CFG_COUNT)); + error_count++; + } + if (ra_w_pin_layout_error) + { + LOG_E("pin configuration table layout mismatch"); + error_count++; + } - for(uint32_t i = 0; i < g_bsp_pin_cfg.number_of_pins; i++) + if (RA_W_PIN_CFG_COUNT != RA_W_PIN_NAME_COUNT) { - uint32_t port_pin = g_bsp_pin_cfg.p_pin_cfg_data[i].pin; - uint32_t port = port_pin >> 8U; - uint32_t pin = port_pin & 0xFFU; - pmsar[port] &= (uint16_t) ~(1U << pin); + LOG_E("pin config name count mismatch, cfg=%u name=%u", + (unsigned int) RA_W_PIN_CFG_COUNT, + (unsigned int) RA_W_PIN_NAME_COUNT); + error_count++; } - for(uint32_t i = 0; i < BSP_FEATURE_BSP_NUM_PMSAR; i++) + for (i = 0; i < RA_W_PIN_CFG_COUNT; i++) { - #if (2U == BSP_FEATURE_IOPORT_VERSION) - R_PMISC->PMSAR[i].PMSAR = (uint16_t) pmsar[i]; - #else - R_PMISC->PMSAR[i].PMSAR = pmsar[i]; - #endif + char pin_name[8]; + + ra_w_pin_to_string(g_bsp_pin_cfg_data[i].pin, pin_name, sizeof(pin_name)); + if (!ra_w_pin_valid(g_bsp_pin_cfg_data[i].pin)) + { + LOG_E("invalid config: %s uses %s", + ra_w_pin_cfg_name_get(i), + pin_name); + error_count++; + } + + for (j = i + 1; j < RA_W_PIN_CFG_COUNT; j++) + { + if (g_bsp_pin_cfg_data[i].pin == g_bsp_pin_cfg_data[j].pin) + { + LOG_E("conflict: %s and %s both use %s", + ra_w_pin_cfg_name_get(i), + ra_w_pin_cfg_name_get(j), + pin_name); + error_count++; + } + } } + if (error_count > 0) + { + LOG_E("check failed with %d error(s)", error_count); + } + else + { + LOG_I("check passed: %u pin(s)", (unsigned int) RA_W_PIN_CFG_COUNT); + } } + +#ifdef BSP_USING_GPIO_W +static int ra_w_pin_config_check_auto(void) +{ + ra_w_pin_config_check(); + + return 0; +} +INIT_COMPONENT_EXPORT(ra_w_pin_config_check_auto); #endif + +void ra_w_pin_config_init(void) +{ + uint32_t index = 0; + + ra_w_invalid_pin_cfg_count = 0; + ra_w_pin_layout_error = 0; + +#ifdef BSP_USING_UART0 + ra_w_pin_config_set(&index, "uart0.rx", BSP_UART0_RX_PIN); + ra_w_pin_config_set(&index, "uart0.tx", BSP_UART0_TX_PIN); +#endif +#ifdef BSP_USING_UART1 + ra_w_pin_config_set(&index, "uart1.rx", BSP_UART1_RX_PIN); + ra_w_pin_config_set(&index, "uart1.tx", BSP_UART1_TX_PIN); +#endif +#ifdef BSP_USING_UART2 + ra_w_pin_config_set(&index, "uart2.rx", BSP_UART2_RX_PIN); + ra_w_pin_config_set(&index, "uart2.tx", BSP_UART2_TX_PIN); +#endif + +#ifdef BSP_USING_PWM0 + ra_w_pin_config_set(&index, "pwm0", BSP_PWM0_PIN); +#endif +#ifdef BSP_USING_PWM1 + ra_w_pin_config_set(&index, "pwm1", BSP_PWM1_PIN); +#endif +#ifdef BSP_USING_PWM2 + ra_w_pin_config_set(&index, "pwm2", BSP_PWM2_PIN); +#endif +#ifdef BSP_USING_PWM3 + ra_w_pin_config_set(&index, "pwm3", BSP_PWM3_PIN); +#endif +#ifdef BSP_USING_PWM4 + ra_w_pin_config_set(&index, "pwm4", BSP_PWM4_PIN); +#endif +#ifdef BSP_USING_PWM5 + ra_w_pin_config_set(&index, "pwm5", BSP_PWM5_PIN); +#endif +#ifdef BSP_USING_PWM6 + ra_w_pin_config_set(&index, "pwm6", BSP_PWM6_PIN); +#endif +#ifdef BSP_USING_PWM7 + ra_w_pin_config_set(&index, "pwm7", BSP_PWM7_PIN); +#endif + +#ifdef BSP_USING_HW_I2C0 + ra_w_pin_config_set(&index, "i2c0.scl", BSP_I2C0_SCL_PIN); + ra_w_pin_config_set(&index, "i2c0.sda", BSP_I2C0_SDA_PIN); +#endif +#ifdef BSP_USING_HW_I2C1 + ra_w_pin_config_set(&index, "i2c1.scl", BSP_I2C1_SCL_PIN); + ra_w_pin_config_set(&index, "i2c1.sda", BSP_I2C1_SDA_PIN); +#endif + +#ifdef BSP_USING_ADC + index += BSP_USING_ADC_PIN_NUM; +#endif + +#ifdef BSP_USING_SPI0 + ra_w_pin_config_set(&index, "spi0.clk", BSP_SPI0_CLK_PIN); + ra_w_pin_config_set(&index, "spi0.di", BSP_SPI0_DI_PIN); + ra_w_pin_config_set(&index, "spi0.do", BSP_SPI0_DO_PIN); + ra_w_pin_config_set(&index, "spi0.csn0", BSP_SPI0_CSN0_PIN); +#endif +#if defined(BSP_USING_SPI1) + ra_w_pin_config_set(&index, "spi1.clk", BSP_SPI1_CLK_PIN); + ra_w_pin_config_set(&index, "spi1.di", BSP_SPI1_DI_PIN); + ra_w_pin_config_set(&index, "spi1.do", BSP_SPI1_DO_PIN); + ra_w_pin_config_set(&index, "spi1.csn0", BSP_SPI1_CSN0_PIN); +#endif + +#ifdef BSP_USING_QSPI + index += 6; +#endif + + /* SWD pins are fixed and are always the last two entries. */ + index += 2; + if (index != RA_W_PIN_CFG_COUNT) + { + ra_w_pin_layout_error = 1; + } +} + +const ioport_cfg_t g_bsp_pin_cfg = +{ + .number_of_pins = sizeof(g_bsp_pin_cfg_data) / sizeof(ioport_pin_cfg_t), + .p_pin_cfg_data = &g_bsp_pin_cfg_data[0], +}; diff --git a/bsp/renesas/ra6w1-ek/rafw_gen/vector_data.c b/bsp/renesas/ra6w1-ek/rafw_gen/vector_data.c index 2652fdaef8aa..95384fd6697a 100644 --- a/bsp/renesas/ra6w1-ek/rafw_gen/vector_data.c +++ b/bsp/renesas/ra6w1-ek/rafw_gen/vector_data.c @@ -1,22 +1,56 @@ /* generated vector source file - do not edit */ -#include "bsp_api.h" -/* Do not build these data structures if no interrupts are currently allocated because IAR will have build errors. */ -#if BSP_FEATURE_BSP_HAS_ICU - #if VECTOR_DATA_IRQ_COUNT > 0 - BSP_DONT_REMOVE const fsp_vector_t g_vector_table[BSP_ICU_VECTOR_MAX_ENTRIES] BSP_PLACE_IN_SECTION(BSP_SECTION_APPLICATION_VECTORS) = - { - [0] = uart_w_isr, /* UARTW1 IRQ (Generic interrupt) */ - }; - const bsp_interrupt_event_t g_interrupt_event_link_select[BSP_ICU_VECTOR_MAX_ENTRIES] = - { - [0] = BSP_PRV_IELS_ENUM(EVENT_UARTW1_IRQ), /* UARTW1 IRQ (Generic interrupt) */ - }; - #endif - #else -BSP_DONT_REMOVE const fsp_vector_t g_vector_table[BSP_IRQ_VECTOR_MAX_ENTRIES] BSP_PLACE_IN_SECTION(BSP_SECTION_APPLICATION_VECTORS) = +#include "vector_data.h" + +BSP_DONT_REMOVE const fsp_vector_t g_vector_table[BSP_IRQ_VECTOR_MAX_ENTRIES] +/* cppcheck-suppress-begin unknownMacro */ + BSP_PLACE_IN_SECTION(BSP_SECTION_APPLICATION_VECTORS) = { -#if VECTOR_DATA_IRQ_COUNT > 0 - [2] = uart_w_isr, /* UARTW1 IRQ (Generic interrupt) */ - #endif -}; + [UART_IRQn] = uart_w_isr, /* UARTW IRQ (Generic interrupt) */ +#ifdef BSP_USING_UART1 + [UART2_IRQn] = uart_w_isr, /* UARTW2 IRQ (Generic interrupt) */ +#endif +#ifdef BSP_USING_UART2 + [UART3_IRQn] = uart_w_isr, /* UARTW3 IRQ (Generic interrupt) */ +#endif +#ifdef BSP_USING_HW_I2C0 + [I2C_IRQn] = i2c_master_w_gen_isr, /* I2CW IRQ */ +#endif +#ifdef BSP_USING_HW_I2C1 + [I2C2_IRQn] = i2c_master_w_gen_isr, /* I2CW2 IRQ */ +#endif +#ifdef BSP_USING_SPI0 + [SPI_IRQn] = spi_w_gen_isr, /* SPIW IRQ */ +#endif +#ifdef BSP_USING_SPI1 + [SPI2_IRQn] = spi_w_gen_isr, /* SPIW2 IRQ */ +#endif +#ifdef BSP_USING_TIM_W +#ifdef BSP_USING_TIM0 + [TIMER_IRQn] = r_tim_w_generic_isr, /* TIM_W1 IRQ */ +#endif +#ifdef BSP_USING_TIM1 + [TIMER2_IRQn] = r_tim_w_generic_isr, /* TIM_W2 IRQ */ #endif +#ifdef BSP_USING_TIM2 + [TIMER3_IRQn] = r_tim_w_generic_isr, /* TIM_W3 IRQ */ +#endif +#ifdef BSP_USING_TIM3 + [TIMER4_IRQn] = r_tim_w_generic_isr, /* TIM_W4 IRQ */ +#endif +#ifdef BSP_USING_TIM4 + [TIMER5_IRQn] = r_tim_w_generic_isr, /* TIM_W5 IRQ */ +#endif +#ifdef BSP_USING_TIM5 + [TIMER6_IRQn] = r_tim_w_generic_isr, /* TIM_W6 IRQ */ +#endif +#ifdef BSP_USING_TIM6 + [TIMER7_IRQn] = r_tim_w_generic_isr, /* TIM_W7 IRQ */ +#endif +#ifdef BSP_USING_TIM7 + [TIMER8_IRQn] = r_tim_w_generic_isr, /* TIM_W8 IRQ */ +#endif +#endif /* BSP_USING_TIM_W */ + [GPIO_P0_IRQn] = r_ext_irq_w_isr, /* EXTIRQW P0 IRQ */ + [GPIO_P1_IRQn] = r_ext_irq_w_isr, /* EXTIRQW P1 IRQ */ +}; +/* cppcheck-suppress-end unknownMacro */ diff --git a/bsp/renesas/ra6w1-ek/rafw_gen/vector_data.h b/bsp/renesas/ra6w1-ek/rafw_gen/vector_data.h index c6ccaacd440e..b18124b3f5b8 100644 --- a/bsp/renesas/ra6w1-ek/rafw_gen/vector_data.h +++ b/bsp/renesas/ra6w1-ek/rafw_gen/vector_data.h @@ -1,25 +1,99 @@ /* generated vector header file - do not edit */ #ifndef VECTOR_DATA_H #define VECTOR_DATA_H + #ifdef __cplusplus - extern "C" { - #endif -/* Number of interrupts allocated */ -#ifndef VECTOR_DATA_IRQ_COUNT -#define VECTOR_DATA_IRQ_COUNT (1) +extern "C" { #endif -/* ISR prototypes */ + +#include +#include "bsp_api.h" + void uart_w_isr(void); -#if defined(BSP_MCU_GROUP_RA6B1) || defined(BSP_MCU_GROUP_RA6U1) //BROMINE-TODO - /* Vector table allocations */ - #define VECTOR_NUMBER_UARTW1_IRQ ((IRQn_Type) 0) /* UARTW1 IRQ (Generic interrupt) */ - #define UARTW1_IRQ_IRQn ((IRQn_Type) 0) /* UARTW1 IRQ (Generic interrupt) */ -#else -/* Vector table allocations */ -#define VECTOR_NUMBER_UARTW1_IRQ ((IRQn_Type) 2) /* UARTW1 IRQ (Generic interrupt) */ -#define UARTW1_IRQ_IRQn ((IRQn_Type) 2) /* UARTW1 IRQ (Generic interrupt) */ +void r_ext_irq_w_isr(void); + +#define VECTOR_NUMBER_UARTW0_IRQ ((IRQn_Type) UART_IRQn) /* UARTW IRQ (Generic interrupt) */ +#define UARTW0_IRQ_IRQn ((IRQn_Type) UART_IRQn) /* UARTW IRQ (Generic interrupt) */ + +#ifdef BSP_USING_UART1 +#define VECTOR_NUMBER_UARTW1_IRQ ((IRQn_Type) UART2_IRQn) /* UARTW2 IRQ (Generic interrupt) */ +#define UARTW1_IRQ_IRQn ((IRQn_Type) UART2_IRQn) /* UARTW2 IRQ (Generic interrupt) */ #endif + +#ifdef BSP_USING_UART2 +#define VECTOR_NUMBER_UARTW2_IRQ ((IRQn_Type) UART3_IRQn) /* UARTW3 IRQ (Generic interrupt) */ +#define UARTW2_IRQ_IRQn ((IRQn_Type) UART3_IRQn) /* UARTW3 IRQ (Generic interrupt) */ +#endif + +#define VECTOR_NUMBER_EXTIRQW_P0_IRQ ((IRQn_Type) GPIO_P0_IRQn) /* EXTIRQW P0 IRQ */ +#define EXTIRQW_P0_IRQ_IRQn ((IRQn_Type) GPIO_P0_IRQn) /* EXTIRQW P0 IRQ */ +#define VECTOR_NUMBER_EXTIRQW_P1_IRQ ((IRQn_Type) GPIO_P1_IRQn) /* EXTIRQW P1 IRQ */ +#define EXTIRQW_P1_IRQ_IRQn ((IRQn_Type) GPIO_P1_IRQn) /* EXTIRQW P1 IRQ */ + +#ifdef BSP_USING_SPI +void spi_w_gen_isr(void); +#ifdef BSP_USING_SPI0 +#define VECTOR_NUMBER_SPIW0_IRQ ((IRQn_Type) SPI_IRQn) /* SPIW IRQ */ +#define SPIW0_IRQ_IRQn ((IRQn_Type) SPI_IRQn) /* SPIW IRQ */ +#endif /* BSP_USING_SPI0 */ + +#ifdef BSP_USING_SPI1 +#define VECTOR_NUMBER_SPIW1_IRQ ((IRQn_Type) SPI2_IRQn) /* SPIW2 IRQ */ +#define SPIW1_IRQ_IRQn ((IRQn_Type) SPI2_IRQn) /* SPIW2 IRQ */ +#endif /* BSP_USING_SPI1 */ +#endif /* BSP_USING_SPI */ + +#ifdef BSP_USING_HW_I2C +void i2c_master_w_gen_isr(void); +#ifdef BSP_USING_HW_I2C0 +#define VECTOR_NUMBER_I2CW0_IRQ ((IRQn_Type) I2C_IRQn) /* I2CW IRQ */ +#define I2CW0_IRQ_IRQn ((IRQn_Type) I2C_IRQn) /* I2CW IRQ */ +#endif /* BSP_USING_HW_I2C0 */ + +#ifdef BSP_USING_HW_I2C1 +#define VECTOR_NUMBER_I2CW1_IRQ ((IRQn_Type) I2C2_IRQn) /* I2CW2 IRQ */ +#define I2CW1_IRQ_IRQn ((IRQn_Type) I2C2_IRQn) /* I2CW2 IRQ */ +#endif /* BSP_USING_HW_I2C1 */ +#endif /* BSP_USING_HW_I2C */ + +#ifdef BSP_USING_TIM_W +void r_tim_w_generic_isr(void); +#ifdef BSP_USING_TIM0 +#define VECTOR_NUMBER_TIMW0_IRQ ((IRQn_Type) TIMER_IRQn) +#define TIMW0_IRQ_IRQn ((IRQn_Type) TIMER_IRQn) +#endif +#ifdef BSP_USING_TIM1 +#define VECTOR_NUMBER_TIMW1_IRQ ((IRQn_Type) TIMER2_IRQn) +#define TIMW1_IRQ_IRQn ((IRQn_Type) TIMER2_IRQn) +#endif +#ifdef BSP_USING_TIM2 +#define VECTOR_NUMBER_TIMW2_IRQ ((IRQn_Type) TIMER3_IRQn) +#define TIMW2_IRQ_IRQn ((IRQn_Type) TIMER3_IRQn) +#endif +#ifdef BSP_USING_TIM3 +#define VECTOR_NUMBER_TIMW3_IRQ ((IRQn_Type) TIMER4_IRQn) +#define TIMW3_IRQ_IRQn ((IRQn_Type) TIMER4_IRQn) +#endif +#ifdef BSP_USING_TIM4 +#define VECTOR_NUMBER_TIMW4_IRQ ((IRQn_Type) TIMER5_IRQn) +#define TIMW4_IRQ_IRQn ((IRQn_Type) TIMER5_IRQn) +#endif +#ifdef BSP_USING_TIM5 +#define VECTOR_NUMBER_TIMW5_IRQ ((IRQn_Type) TIMER6_IRQn) +#define TIMW5_IRQ_IRQn ((IRQn_Type) TIMER6_IRQn) +#endif +#ifdef BSP_USING_TIM6 +#define VECTOR_NUMBER_TIMW6_IRQ ((IRQn_Type) TIMER7_IRQn) +#define TIMW6_IRQ_IRQn ((IRQn_Type) TIMER7_IRQn) +#endif +#ifdef BSP_USING_TIM7 +#define VECTOR_NUMBER_TIMW7_IRQ ((IRQn_Type) TIMER8_IRQn) +#define TIMW7_IRQ_IRQn ((IRQn_Type) TIMER8_IRQn) +#endif +#endif /* BSP_USING_TIM_W */ + #ifdef __cplusplus - } - #endif +} +#endif + #endif /* VECTOR_DATA_H */ diff --git a/bsp/renesas/ra6w1-ek/rtconfig.h b/bsp/renesas/ra6w1-ek/rtconfig.h index f13cfde9ecb7..faaddf945a07 100644 --- a/bsp/renesas/ra6w1-ek/rtconfig.h +++ b/bsp/renesas/ra6w1-ek/rtconfig.h @@ -422,9 +422,15 @@ #define BSP_USING_GPIO_W #define BSP_USING_UART #define BSP_USING_UART0 +#define BSP_UART0_RX_PIN "p000" +#define BSP_UART0_TX_PIN "p001" #define BSP_UART0_RX_BUFSIZE 256 #define BSP_UART0_TX_BUFSIZE 0 /* end of On-chip Peripheral Drivers */ + +/* On-chip Peripheral Port */ + +/* end of On-chip Peripheral Port */ /* end of Hardware Drivers Config */ #endif diff --git a/bsp/renesas/ra6w1-ek/rtconfig.py b/bsp/renesas/ra6w1-ek/rtconfig.py index f806d3bf7f08..3122a259228b 100644 --- a/bsp/renesas/ra6w1-ek/rtconfig.py +++ b/bsp/renesas/ra6w1-ek/rtconfig.py @@ -20,8 +20,8 @@ if os.getenv('RTT_EXEC_PATH'): EXEC_PATH = os.getenv('RTT_EXEC_PATH') -# BUILD = 'debug' -BUILD = 'release' +BUILD = 'debug' +# BUILD = 'release' if PLATFORM == 'gcc': # toolchains