diff --git a/.ci/attachconfig/ci.attachconfig.yml b/.ci/attachconfig/ci.attachconfig.yml deleted file mode 100644 index 0ae089b..0000000 --- a/.ci/attachconfig/ci.attachconfig.yml +++ /dev/null @@ -1,189 +0,0 @@ -scons.args: &scons - scons_arg: - - '--strict' -# ------ kernel CI ------ -kernel.klibc-stdlib: - <<: *scons - kconfig: - - CONFIG_RT_KLIBC_USING_STDLIB=y - - CONFIG_RT_KLIBC_USING_STDLIB_MEMORY=y -kernel.klibc-tinysize: - <<: *scons - kconfig: - - CONFIG_RT_KLIBC_USING_TINY_SIZE=y -kernel.klibc-vsnprintf-std: - <<: *scons - kconfig: - - CONFIG_RT_KLIBC_USING_VSNPRINTF_STANDARD=y - - CONFIG_RT_KLIBC_USING_PRINTF_LONGLONG=y - - CONFIG_RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS=y - - CONFIG_RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS=y - - CONFIG_RT_KLIBC_USING_VSNPRINTF_WRITEBACK_SPECIFIER=y - - CONFIG_RT_KLIBC_USING_VSNPRINTF_CHECK_NUL_IN_FORMAT_SPECIFIER=y - - CONFIG_RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS=y -# ------ online-packages CI ------ -online-packages.iot.at_devices: - <<: *scons - kconfig: - - CONFIG_PKG_USING_AT_DEVICE=y - # Quectel M26/MC20 - - CONFIG_AT_DEVICE_USING_M26=y - - CONFIG_AT_DEVICE_M26_INIT_ASYN=y - # Quectel EC20 - - CONFIG_AT_DEVICE_USING_EC20=y - - CONFIG_AT_DEVICE_EC20_INIT_ASYN=y - # Espressif ESP32 - - CONFIG_AT_DEVICE_USING_ESP32=y - - CONFIG_AT_DEVICE_ESP32_INIT_ASYN=y - # Espressif ESP8266 - - CONFIG_AT_DEVICE_USING_ESP8266=y - - CONFIG_AT_DEVICE_ESP8266_INIT_ASYN=y - # Realthread RW007 - - CONFIG_AT_DEVICE_USING_RW007=y - - CONFIG_AT_DEVICE_RW007_INIT_ASYN=y - # SIMCom SIM800C - - CONFIG_AT_DEVICE_USING_SIM800C=y - - CONFIG_AT_DEVICE_SIM800C_INIT_ASYN=y - # SIMCom SIM76XX - - CONFIG_AT_DEVICE_USING_SIM76XX=y - - CONFIG_AT_DEVICE_SIM76XX_INIT_ASYN=y - # Notion MW31 - - CONFIG_AT_DEVICE_USING_MW31=y - - CONFIG_AT_DEVICE_MW31_INIT_ASYN=y - # WinnerMicro W60X - - CONFIG_AT_DEVICE_USING_W60X=y - - CONFIG_AT_DEVICE_W60X_INIT_ASYN=y - # Ai-Think A9G - - CONFIG_AT_DEVICE_USING_A9G=y - - CONFIG_AT_DEVICE_A9G_INIT_ASYN=y - # Quectel BC26 - - CONFIG_AT_DEVICE_USING_BC26=y - - CONFIG_AT_DEVICE_BC26_INIT_ASYN=y - # luat Air720 - - CONFIG_AT_DEVICE_USING_AIR720=y - - CONFIG_AT_DEVICE_AIR720_INIT_ASYN=y - # Gosuncn ME3616 - - CONFIG_AT_DEVICE_USING_ME3616=y - - CONFIG_AT_DEVICE_ME3616_INIT_ASYN=y - # ChinaMobile M6315 - - CONFIG_AT_DEVICE_USING_M6315=y - - CONFIG_AT_DEVICE_M6315_INIT_ASYN=y - # Quectel BC28 - - CONFIG_AT_DEVICE_USING_BC28=y - - CONFIG_AT_DEVICE_BC28_INIT_ASYN=y - # Quectel EC200T/EC200S - - CONFIG_AT_DEVICE_USING_EC200X=y - - CONFIG_AT_DEVICE_EC200X_INIT_ASYN=y - # Neoway N21 - - CONFIG_AT_DEVICE_USING_N21=y - - CONFIG_AT_DEVICE_N21_INIT_ASYN=y - # Neoway N58 - - CONFIG_AT_DEVICE_USING_N58=y - - CONFIG_AT_DEVICE_N58_INIT_ASYN=y - # ChinaMobile M5311 - - CONFIG_AT_DEVICE_USING_M5311=y - - CONFIG_AT_DEVICE_M5311_INIT_ASYN=y - # Fibocom L610 - - CONFIG_AT_DEVICE_USING_L610=y - - CONFIG_AT_DEVICE_L610_INIT_ASYN=y - # Neoway N720 - - CONFIG_AT_DEVICE_USING_N720=y - - CONFIG_AT_DEVICE_N720_INIT_ASYN=y - # Gosuncn ML305 - - CONFIG_AT_DEVICE_USING_ML305=y - - CONFIG_AT_DEVICE_ML305_INIT_ASYN=y -online-packages.misc.misc: - <<: *scons - kconfig: - - CONFIG_PKG_USING_MULTIBUTTON=y -online-packages.misc.vi: - <<: *scons - kconfig: - - CONFIG_PKG_USING_VI=y - # - CONFIG_VI_ENABLE_8BIT=y - - CONFIG_VI_ENABLE_COLON=y - - CONFIG_VI_ENABLE_COLON_EXPAND=y - - CONFIG_VI_ENABLE_YANKMARK=y - - CONFIG_VI_ENABLE_SEARCH=y - - CONFIG_VI_ENABLE_DOT_CMD=y - - CONFIG_VI_ENABLE_READONLY=y - - CONFIG_VI_ENABLE_SETOPTS=y - - CONFIG_VI_ENABLE_SET=y - - CONFIG_VI_ENABLE_WIN_RESIZE=y - - CONFIG_VI_ENABLE_VI_ASK_TERMINAL=y - - CONFIG_VI_ENABLE_UNDO=y - - CONFIG_VI_ENABLE_UNDO_QUEUE=y - - CONFIG_VI_ENABLE_VERBOSE_STATUS=y -online-packages.multimedia.lvgl-v8.3-latest: - <<: *scons - kconfig: - - CONFIG_BSP_USING_LVGL=y - - CONFIG_BSP_USING_LVGL_DEMO=y - - CONFIG_PKG_LVGL_USING_V8_3_LATEST=y -online-packages.multimedia.lvgl-v8.3.11: - <<: *scons - kconfig: - - CONFIG_BSP_USING_LVGL=y - - CONFIG_BSP_USING_LVGL_DEMO=y - - CONFIG_PKG_LVGL_USING_V080311=y -online-packages.multimedia.lvgl-v8.4-latest: - <<: *scons - kconfig: - - CONFIG_BSP_USING_LVGL=y - - CONFIG_BSP_USING_LVGL_DEMO=y - - CONFIG_PKG_LVGL_USING_V8_4_LATEST=y -online-packages.system.enhanced-kservice: - <<: *scons - kconfig: - - CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE=y - - CONFIG_PKG_USING_RT_MEMCPY_CM=y -online-packages.system.os-wrappers: - <<: *scons - kconfig: - - CONFIG_PKG_USING_FREERTOS_WRAPPER=y -# ------ peripheral CI ------ -peripheral.aht21: - kconfig: - - CONFIG_BSP_USING_AHT21=y -peripheral.ap3216c: - kconfig: - - CONFIG_BSP_USING_AP3216C=y -peripheral.ethernet_28j60: - kconfig: - - CONFIG_BSP_USING_ENC28j60=y -peripheral.fal_easyflash: - kconfig: - - CONFIG_BSP_USING_EASYFLASH=y -peripheral.filesystem: - kconfig: - - CONFIG_BSP_USING_FS=y - - CONFIG_BSP_USING_FLASH_FATFS=y -peripheral.icm20608: - kconfig: - - CONFIG_BSP_USING_ICM20608=y -peripheral.lcd_st7787: - kconfig: - - CONFIG_BSP_USING_ONBOARD_LCD=y -peripheral.led_matrix: - kconfig: - - CONFIG_BSP_USING_ONBOARD_LED_MATRIX=y -peripheral.rs485: - kconfig: - - CONFIG_BSP_USING_RS485=y -peripheral.rw007: - kconfig: - - CONFIG_BSP_USING_RW007_WLAN=y -peripheral.spi_flash_w25q64: - kconfig: - - CONFIG_BSP_USING_SPI_FLASH=y -peripheral.sram: - kconfig: - - CONFIG_BSP_USING_SRAM=y -peripheral.usb_mouse: - kconfig: - - CONFIG_BSP_USING_USB_MOUSE=y -# ------ nano CI ------ -nano: - <<: *scons - kconfig: - - CONFIG_RT_USING_NANO=y \ No newline at end of file diff --git a/libraries/HAL_Drivers/drivers/SConscript b/libraries/HAL_Drivers/drivers/SConscript index 3a836bd..0f6b8dc 100644 --- a/libraries/HAL_Drivers/drivers/SConscript +++ b/libraries/HAL_Drivers/drivers/SConscript @@ -52,10 +52,8 @@ if GetDepend(['RT_USING_DAC']): if GetDepend(['RT_USING_CAN']): src += ['drv_can.c'] -if GetDepend(['RT_USING_PM']): +if GetDepend(['RT_USING_PM', 'SOC_SERIES_STM32L4']): src += ['drv_pm.c'] - -if GetDepend(['BSP_USING_LPTIM']): src += ['drv_lptim.c'] if GetDepend('BSP_USING_SDRAM'): @@ -124,6 +122,9 @@ if GetDepend(['BSP_USING_PULSE_ENCODER']): if GetDepend(['BSP_USING_USBH']): src += ['drv_usbh.c'] +if GetDepend(['BSP_USING_TEST']): + src += ['drv_test.c'] + path += [os.path.join(cwd, 'config')] if GetDepend('BSP_USING_ON_CHIP_FLASH'): diff --git a/libraries/HAL_Drivers/drivers/config/f1/dma_config.h b/libraries/HAL_Drivers/drivers/config/f1/dma_config.h index 652a576..ff610bd 100644 --- a/libraries/HAL_Drivers/drivers/config/f1/dma_config.h +++ b/libraries/HAL_Drivers/drivers/config/f1/dma_config.h @@ -19,13 +19,6 @@ extern "C" { #endif /* DMA1 channel1 */ -#if defined(BSP_ADC1_USING_DMA) && !defined(ADC1_DMA_INSTANCE) -#define ADC1_DMA_IRQHandler DMA1_Channel1_IRQHandler -#define ADC1_DMA_RCC RCC_AHBENR_DMA1EN -#define ADC1_DMA_INSTANCE DMA1_Channel1 -#define ADC1_DMA_IRQ DMA1_Channel1_IRQn -#endif - /* DMA1 channel2 */ #if defined(BSP_SPI1_RX_USING_DMA) && !defined(SPI1_RX_DMA_INSTANCE) #define SPI1_DMA_RX_IRQHandler DMA1_Channel2_IRQHandler @@ -63,11 +56,6 @@ extern "C" { #define UART1_TX_DMA_RCC RCC_AHBENR_DMA1EN #define UART1_TX_DMA_INSTANCE DMA1_Channel4 #define UART1_TX_DMA_IRQ DMA1_Channel4_IRQn -#elif defined(BSP_I2C2_TX_USING_DMA) && !defined(I2C2_TX_DMA_INSTANCE) -#define I2C2_DMA_TX_IRQHandler DMA1_Channel4_IRQHandler -#define I2C2_TX_DMA_RCC RCC_AHBENR_DMA1EN -#define I2C2_TX_DMA_INSTANCE DMA1_Channel4 -#define I2C2_TX_DMA_IRQ DMA1_Channel4_IRQn #endif /* DMA1 channel5 */ @@ -76,16 +64,12 @@ extern "C" { #define SPI2_TX_DMA_RCC RCC_AHBENR_DMA1EN #define SPI2_TX_DMA_INSTANCE DMA1_Channel5 #define SPI2_TX_DMA_IRQ DMA1_Channel5_IRQn + #elif defined(BSP_UART1_RX_USING_DMA) && !defined(UART1_RX_DMA_INSTANCE) #define UART1_DMA_RX_IRQHandler DMA1_Channel5_IRQHandler #define UART1_RX_DMA_RCC RCC_AHBENR_DMA1EN #define UART1_RX_DMA_INSTANCE DMA1_Channel5 #define UART1_RX_DMA_IRQ DMA1_Channel5_IRQn -#elif defined(BSP_I2C2_RX_USING_DMA) && !defined(I2C2_RX_DMA_INSTANCE) -#define I2C2_DMA_RX_IRQHandler DMA1_Channel5_IRQHandler -#define I2C2_RX_DMA_RCC RCC_AHBENR_DMA1EN -#define I2C2_RX_DMA_INSTANCE DMA1_Channel5 -#define I2C2_RX_DMA_IRQ DMA1_Channel5_IRQn #endif /* DMA1 channel6 */ @@ -94,11 +78,6 @@ extern "C" { #define UART2_RX_DMA_RCC RCC_AHBENR_DMA1EN #define UART2_RX_DMA_INSTANCE DMA1_Channel6 #define UART2_RX_DMA_IRQ DMA1_Channel6_IRQn -#elif defined(BSP_I2C1_TX_USING_DMA) && !defined(I2C1_TX_DMA_INSTANCE) -#define I2C1_DMA_TX_IRQHandler DMA1_Channel6_IRQHandler -#define I2C1_TX_DMA_RCC RCC_AHBENR_DMA1EN -#define I2C1_TX_DMA_INSTANCE DMA1_Channel6 -#define I2C1_TX_DMA_IRQ DMA1_Channel6_IRQn #endif /* DMA1 channel7 */ @@ -107,11 +86,6 @@ extern "C" { #define UART2_TX_DMA_RCC RCC_AHBENR_DMA1EN #define UART2_TX_DMA_INSTANCE DMA1_Channel7 #define UART2_TX_DMA_IRQ DMA1_Channel7_IRQn -#elif defined(BSP_I2C1_RX_USING_DMA) && !defined(I2C1_RX_DMA_INSTANCE) -#define I2C1_DMA_RX_IRQHandler DMA1_Channel7_IRQHandler -#define I2C1_RX_DMA_RCC RCC_AHBENR_DMA1EN -#define I2C1_RX_DMA_INSTANCE DMA1_Channel7 -#define I2C1_RX_DMA_IRQ DMA1_Channel7_IRQn #endif /* DMA2 channel1 */ @@ -137,27 +111,9 @@ extern "C" { #define UART4_RX_DMA_INSTANCE DMA2_Channel3 #define UART4_RX_DMA_IRQ DMA2_Channel3_IRQn #endif - /* DMA2 channel4 */ -#if defined(BSP_SDIO_TX_USING_DMA) && !defined(SDIO_TX_DMA_INSTANCE) -#define SDIO_DMA_TX_IRQHandler DMA2_Channel4_5_IRQHandler -#define SDIO_TX_DMA_RCC RCC_AHBENR_DMA2EN -#define SDIO_TX_DMA_INSTANCE DMA2_Channel4 -#define SDIO_TX_DMA_IRQ DMA2_Channel4_5_IRQn -#elif defined(BSP_SDIO_RX_USING_DMA) && !defined(SDIO_RX_DMA_INSTANCE) -#define SDIO_DMA_RX_IRQHandler DMA2_Channel4_5_IRQHandler -#define SDIO_RX_DMA_RCC RCC_AHBENR_DMA2EN -#define SDIO_RX_DMA_INSTANCE DMA2_Channel4 -#define SDIO_RX_DMA_IRQ DMA2_Channel4_5_IRQn -#endif - /* DMA2 channel5 */ -#if defined(BSP_ADC3_USING_DMA) && !defined(ADC3_DMA_INSTANCE) -#define ADC3_DMA_IRQHandler DMA2_Channel4_5_IRQHandler -#define ADC3_DMA_RCC RCC_AHBENR_DMA2EN -#define ADC3_DMA_INSTANCE DMA2_Channel5 -#define ADC3_DMA_IRQ DMA2_Channel4_5_IRQn -#elif defined(BSP_UART4_TX_USING_DMA) && !defined(UART4_TX_DMA_INSTANCE) +#if defined(BSP_UART4_TX_USING_DMA) && !defined(UART4_TX_DMA_INSTANCE) #define UART4_DMA_TX_IRQHandler DMA2_Channel4_5_IRQHandler #define UART4_TX_DMA_RCC RCC_AHBENR_DMA2EN #define UART4_TX_DMA_INSTANCE DMA2_Channel5 diff --git a/libraries/HAL_Drivers/drivers/config/f1/i2c_hard_config.h b/libraries/HAL_Drivers/drivers/config/f1/i2c_hard_config.h deleted file mode 100644 index cdb4324..0000000 --- a/libraries/HAL_Drivers/drivers/config/f1/i2c_hard_config.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-02-06 Dyyt587 first version - * 2024-04-23 Zeidan Add I2Cx_xx_DMA_CONFIG - */ -#ifndef __I2C_HARD_CONFIG_H__ -#define __I2C_HARD_CONFIG_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef BSP_USING_HARD_I2C1 -#ifndef I2C1_BUS_CONFIG -#define I2C1_BUS_CONFIG \ - { \ - .Instance = I2C1, \ - .timeout=0x1000, \ - .name = "hwi2c1", \ - .evirq_type = I2C1_EV_IRQn, \ - .erirq_type = I2C1_ER_IRQn, \ - } -#endif /* I2C1_BUS_CONFIG */ -#endif /* BSP_USING_HARD_I2C1 */ - -#ifdef BSP_I2C1_TX_USING_DMA -#ifndef I2C1_TX_DMA_CONFIG -#define I2C1_TX_DMA_CONFIG \ - { \ - .dma_rcc = I2C1_TX_DMA_RCC, \ - .Instance = I2C1_TX_DMA_INSTANCE, \ - .dma_irq = I2C1_TX_DMA_IRQ, \ - } -#endif /* I2C1_TX_DMA_CONFIG */ -#endif /* BSP_I2C1_TX_USING_DMA */ - -#ifdef BSP_I2C1_RX_USING_DMA -#ifndef I2C1_RX_DMA_CONFIG -#define I2C1_RX_DMA_CONFIG \ - { \ - .dma_rcc = I2C1_RX_DMA_RCC, \ - .Instance = I2C1_RX_DMA_INSTANCE, \ - .dma_irq = I2C1_RX_DMA_IRQ, \ - } -#endif /* I2C1_RX_DMA_CONFIG */ -#endif /* BSP_I2C1_RX_USING_DMA */ - -#ifdef BSP_USING_HARD_I2C2 -#ifndef I2C2_BUS_CONFIG -#define I2C2_BUS_CONFIG \ - { \ - .Instance = I2C2, \ - .timeout=0x1000, \ - .name = "hwi2c2", \ - .evirq_type = I2C2_EV_IRQn, \ - .erirq_type = I2C2_ER_IRQn, \ - } -#endif /* I2C2_BUS_CONFIG */ -#endif /* BSP_USING_HARD_I2C2 */ - -#ifdef BSP_I2C2_TX_USING_DMA -#ifndef I2C2_TX_DMA_CONFIG -#define I2C2_TX_DMA_CONFIG \ - { \ - .dma_rcc = I2C2_TX_DMA_RCC, \ - .Instance = I2C2_TX_DMA_INSTANCE, \ - .dma_irq = I2C2_TX_DMA_IRQ, \ - } -#endif /* I2C2_TX_DMA_CONFIG */ -#endif /* BSP_I2C2_TX_USING_DMA */ - -#ifdef BSP_I2C2_RX_USING_DMA -#ifndef I2C2_RX_DMA_CONFIG -#define I2C2_RX_DMA_CONFIG \ - { \ - .dma_rcc = I2C2_RX_DMA_RCC, \ - .Instance = I2C2_RX_DMA_INSTANCE, \ - .dma_irq = I2C2_RX_DMA_IRQ, \ - } -#endif /* I2C2_RX_DMA_CONFIG */ -#endif /* BSP_I2C2_RX_USING_DMA */ - -#ifdef BSP_USING_HARD_I2C3 -#ifndef I2C3_BUS_CONFIG -#define I2C3_BUS_CONFIG \ - { \ - .Instance = I2C3, \ - .timeout=0x1000, \ - .name = "hwi2c3", \ - .evirq_type = I2C3_EV_IRQn, \ - .erirq_type = I2C3_ER_IRQn, \ - } -#endif /* I2C3_BUS_CONFIG */ -#endif /* BSP_USING_HARD_I2C3 */ - -#ifdef BSP_I2C3_TX_USING_DMA -#ifndef I2C3_TX_DMA_CONFIG -#define I2C3_TX_DMA_CONFIG \ - { \ - .dma_rcc = I2C3_TX_DMA_RCC, \ - .Instance = I2C3_TX_DMA_INSTANCE, \ - .dma_irq = I2C3_TX_DMA_IRQ, \ - } -#endif /* I2C3_TX_DMA_CONFIG */ -#endif /* BSP_I2C3_TX_USING_DMA */ - -#ifdef BSP_I2C3_RX_USING_DMA -#ifndef I2C3_RX_DMA_CONFIG -#define I2C3_RX_DMA_CONFIG \ - { \ - .dma_rcc = I2C3_RX_DMA_RCC, \ - .Instance = I2C3_RX_DMA_INSTANCE, \ - .dma_irq = I2C3_RX_DMA_IRQ, \ - } -#endif /* I2C3_RX_DMA_CONFIG */ -#endif /* BSP_I2C3_RX_USING_DMA */ - -#ifdef __cplusplus -} -#endif - -#endif /*__I2C_HARD_CONFIG_H__ */ diff --git a/libraries/HAL_Drivers/drivers/config/h7/lptim_config.h b/libraries/HAL_Drivers/drivers/config/h7/lptim_config.h deleted file mode 100644 index 794289d..0000000 --- a/libraries/HAL_Drivers/drivers/config/h7/lptim_config.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-11 wdfk-prog first version - */ - -#ifndef __LPTIM_CONFIG_H__ -#define __LPTIM_CONFIG_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef LPTIM_DEV_INFO_CONFIG -#define LPTIM_DEV_INFO_CONFIG \ - { \ - .maxfreq = 1000000, \ - .minfreq = 3000, \ - .maxcnt = 0xFFFF, \ - .cntmode = HWTIMER_CNTMODE_UP, \ - } -#endif /* TIM_DEV_INFO_CONFIG */ - -#ifdef BSP_USING_LPTIM1 -#ifndef LPTIM1_CONFIG -#define LPTIM1_CONFIG \ - { \ - .tim_handle.Instance = LPTIM1, \ - .tim_irqn = LPTIM1_IRQn, \ - .name = "lptim1", \ - } -#endif /* LPTIM1_CONFIG */ -#endif /* BSP_USING_LPTIM1 */ - -#ifdef BSP_USING_LPTIM2 -#ifndef LPTIM2_CONFIG -#define LPTIM2_CONFIG \ - { \ - .tim_handle.Instance = LPTIM2, \ - .tim_irqn = LPTIM2_IRQn, \ - .name = "lptim2", \ - } -#endif /* LPTIM1_CONFIG */ -#endif /* BSP_USING_LPTIM1 */ - -#ifdef BSP_USING_LPTIM3 -#ifndef LPTIM3_CONFIG -#define LPTIM3_CONFIG \ - { \ - .tim_handle.Instance = LPTIM3, \ - .tim_irqn = LPTIM3_IRQn, \ - .name = "lptim3", \ - } -#endif /* LPTIM3_CONFIG */ -#endif /* BSP_USING_LPTIM3 */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LPTIM_CONFIG_H__ */ diff --git a/libraries/HAL_Drivers/drivers/drv_can.c b/libraries/HAL_Drivers/drivers/drv_can.c index e12624a..1b50b66 100644 --- a/libraries/HAL_Drivers/drivers/drv_can.c +++ b/libraries/HAL_Drivers/drivers/drv_can.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -174,6 +174,8 @@ static rt_err_t _can_config(struct rt_can_device *can, struct can_configure *cfg /* default filter config */ HAL_CAN_ConfigFilter(&drv_can->CanHandle, &drv_can->FilterConfig); + /* can start */ + HAL_CAN_Start(&drv_can->CanHandle); return RT_EOK; } @@ -319,7 +321,7 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg) rt_uint32_t id_l = 0; rt_uint32_t mask_h = 0; rt_uint32_t mask_l = 0; - rt_uint32_t mask_l_tail = 0; /*CAN_FxR2 bit [2:0]*/ + rt_uint32_t mask_l_tail = 0; //CAN_FxR2 bit [2:0] if (RT_NULL == arg) { @@ -465,20 +467,8 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg) drv_can->device.status.errcode = errtype & 0x07; rt_memcpy(arg, &drv_can->device.status, sizeof(drv_can->device.status)); - break; } - case RT_CAN_CMD_START: - argval = (rt_uint32_t) arg; - if (argval == 0) - { - HAL_CAN_Stop(&drv_can->CanHandle); - } - else - { - HAL_CAN_Start(&drv_can->CanHandle); - } - - break; + break; } return RT_EOK; diff --git a/libraries/HAL_Drivers/drivers/drv_config.h b/libraries/HAL_Drivers/drivers/drv_config.h index cc53b17..fdb6eef 100644 --- a/libraries/HAL_Drivers/drivers/drv_config.h +++ b/libraries/HAL_Drivers/drivers/drv_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -35,7 +35,6 @@ extern "C" { #include "f1/sdio_config.h" #include "f1/pwm_config.h" #include "f1/usbd_config.h" -#include "f1/i2c_hard_config.h" #include "f1/pulse_encoder_config.h" #elif defined(SOC_SERIES_STM32F2) #include "f2/dma_config.h" @@ -123,7 +122,6 @@ extern "C" { #include "h7/adc_config.h" #include "h7/dac_config.h" #include "h7/tim_config.h" -#include "h7/lptim_config.h" #include "h7/sdio_config.h" #include "h7/pwm_config.h" #include "h7/usbd_config.h" diff --git a/libraries/HAL_Drivers/drivers/drv_gpio.c b/libraries/HAL_Drivers/drivers/drv_gpio.c index 5d336d6..3ff92b1 100644 --- a/libraries/HAL_Drivers/drivers/drv_gpio.c +++ b/libraries/HAL_Drivers/drivers/drv_gpio.c @@ -394,6 +394,7 @@ static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin, const struct pin_irq_map *irqmap; rt_base_t level; rt_int32_t irqindex = -1; + GPIO_InitTypeDef GPIO_InitStruct; if (PIN_PORT(pin) >= PIN_STPORT_MAX) { @@ -402,8 +403,6 @@ static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin, if (enabled == PIN_IRQ_ENABLE) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - irqindex = bit2bitno(PIN_STPIN(pin)); if (irqindex < 0 || irqindex >= (rt_int32_t)ITEM_NUM(pin_irq_map)) { diff --git a/libraries/HAL_Drivers/drivers/drv_hard_i2c.c b/libraries/HAL_Drivers/drivers/drv_hard_i2c.c index 424adaf..405644a 100644 --- a/libraries/HAL_Drivers/drivers/drv_hard_i2c.c +++ b/libraries/HAL_Drivers/drivers/drv_hard_i2c.c @@ -7,10 +7,14 @@ * Date Author Notes * 2024-02-17 Dyyt587 first version * 2024-04-23 Zeidan fix bugs, test on STM32F429IGTx - * 2024-12-10 zzk597 add support for STM32F1 series */ +#include +#include +#include #include "drv_hard_i2c.h" +#include "drv_config.h" +#include /* not fully support for I2C4 */ #if defined(BSP_USING_HARD_I2C1) || defined(BSP_USING_HARD_I2C2) || defined(BSP_USING_HARD_I2C3) @@ -47,27 +51,28 @@ static struct stm32_i2c_config i2c_config[] = static struct stm32_i2c i2c_objs[sizeof(i2c_config) / sizeof(i2c_config[0])] = {0}; + static rt_err_t stm32_i2c_init(struct stm32_i2c *i2c_drv) { RT_ASSERT(i2c_drv != RT_NULL); I2C_HandleTypeDef *i2c_handle = &i2c_drv->handle; - struct stm32_i2c_config *cfg = i2c_drv->config; - rt_memset(i2c_handle, 0, sizeof(I2C_HandleTypeDef)); - + struct stm32_i2c_config *cfg = i2c_drv->config; i2c_handle->Instance = cfg->Instance; #if defined(SOC_SERIES_STM32H7) i2c_handle->Init.Timing = cfg->timing; #endif /* defined(SOC_SERIES_STM32H7) */ -#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F4) +#if defined(SOC_SERIES_STM32F4) i2c_handle->Init.ClockSpeed = 100000; i2c_handle->Init.DutyCycle = I2C_DUTYCYCLE_2; -#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F4) */ +#endif /* defined(SOC_SERIES_STM32F4) */ i2c_handle->Init.OwnAddress1 = 0; i2c_handle->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; +#if defined(SOC_SERIES_STM32H7) + i2c_handle->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; +#endif /* defined(SOC_SERIES_STM32H7) */ i2c_handle->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; - i2c_handle->Init.OwnAddress2 = 0; i2c_handle->Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; i2c_handle->Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_DeInit(i2c_handle) != HAL_OK) @@ -115,12 +120,11 @@ static rt_err_t stm32_i2c_init(struct stm32_i2c *i2c_drv) HAL_NVIC_EnableIRQ(i2c_drv->config->dma_tx->dma_irq); } - /* In the data transfer function stm32_i2c_master_xfer(), the IT transfer function - HAL_I2C_Master_Seq_Transmit_IT() is used when DMA is not used, so the IT interrupt - must be enable anyway, regardless of the DMA configuration, otherwise - the rt_completion_wait() will always timeout. */ - HAL_NVIC_SetPriority(i2c_drv->config->evirq_type, 2, 0); - HAL_NVIC_EnableIRQ(i2c_drv->config->evirq_type); + if (i2c_drv->i2c_dma_flag & I2C_USING_TX_DMA_FLAG || i2c_drv->i2c_dma_flag & I2C_USING_RX_DMA_FLAG) + { + HAL_NVIC_SetPriority(i2c_drv->config->evirq_type, 2, 0); + HAL_NVIC_EnableIRQ(i2c_drv->config->evirq_type); + } return RT_EOK; } @@ -156,14 +160,11 @@ static rt_ssize_t stm32_i2c_master_xfer(struct rt_i2c_bus_device *bus, uint8_t next_flag = 0; struct rt_completion *completion; rt_uint32_t timeout; - if (num == 0) { return 0; } - RT_ASSERT((msgs != RT_NULL) && (bus != RT_NULL)); - i2c_obj = rt_container_of(bus, struct stm32_i2c, i2c_bus); completion = &i2c_obj->completion; I2C_HandleTypeDef *handle = &i2c_obj->handle; @@ -344,48 +345,6 @@ int RT_hw_i2c_bus_init(void) i2c_objs[i].config = &i2c_config[i]; i2c_objs[i].i2c_bus.timeout = i2c_config[i].timeout; - if ((i2c_objs[i].i2c_dma_flag & I2C_USING_RX_DMA_FLAG)) - { - i2c_objs[i].dma.handle_rx.Instance = i2c_config[i].dma_rx->Instance; -#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) - i2c_objs[i].dma.handle_rx.Init.Channel = i2c_config[i].dma_rx->channel; -#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7) - i2c_objs[i].dma.handle_rx.Init.Request = i2c_config[i].dma_rx->request; -#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */ -#ifndef SOC_SERIES_STM32U5 - i2c_objs[i].dma.handle_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; - i2c_objs[i].dma.handle_rx.Init.PeriphInc = DMA_PINC_DISABLE; - i2c_objs[i].dma.handle_rx.Init.MemInc = DMA_MINC_ENABLE; - i2c_objs[i].dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - i2c_objs[i].dma.handle_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - i2c_objs[i].dma.handle_rx.Init.Mode = DMA_NORMAL; - i2c_objs[i].dma.handle_rx.Init.Priority = DMA_PRIORITY_LOW; -#endif -#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) - i2c_objs[i].dma.handle_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - i2c_objs[i].dma.handle_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; - i2c_objs[i].dma.handle_tx.Init.MemBurst = DMA_MBURST_INC4; - i2c_objs[i].dma.handle_tx.Init.PeriphBurst = DMA_PBURST_INC4; -#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) */ - { - rt_uint32_t tmpreg = 0x00U; -#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0) - /* enable DMA clock && Delay after an RCC peripheral clock enabling*/ - SET_BIT(RCC->AHBENR, i2c_config[i].dma_rx->dma_rcc); - tmpreg = READ_BIT(RCC->AHBENR, i2c_config[i].dma_rx->dma_rcc); -#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7) - SET_BIT(RCC->AHB1ENR, i2c_config[i].dma_rx->dma_rcc); - /* Delay after an RCC peripheral clock enabling */ - tmpreg = READ_BIT(RCC->AHB1ENR, i2c_config[i].dma_rx->dma_rcc); -#elif defined(SOC_SERIES_STM32MP1) - __HAL_RCC_DMAMUX_CLK_ENABLE(); - SET_BIT(RCC->MP_AHB2ENSETR, i2c_config[i].dma_rx->dma_rcc); - tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, i2c_config[i].dma_rx->dma_rcc); -#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0) */ - UNUSED(tmpreg); /* To avoid compiler warnings */ - } - } - if (i2c_objs[i].i2c_dma_flag & I2C_USING_TX_DMA_FLAG) { i2c_objs[i].dma.handle_tx.Instance = i2c_config[i].dma_tx->Instance; @@ -395,27 +354,53 @@ int RT_hw_i2c_bus_init(void) i2c_objs[i].dma.handle_tx.Init.Request = i2c_config[i].dma_tx->request; #endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */ #ifndef SOC_SERIES_STM32U5 - i2c_objs[i].dma.handle_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; - i2c_objs[i].dma.handle_tx.Init.PeriphInc = DMA_PINC_DISABLE; - i2c_objs[i].dma.handle_tx.Init.MemInc = DMA_MINC_ENABLE; + i2c_objs[i].dma.handle_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + i2c_objs[i].dma.handle_tx.Init.PeriphInc = DMA_PINC_DISABLE; + i2c_objs[i].dma.handle_tx.Init.MemInc = DMA_MINC_ENABLE; i2c_objs[i].dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - i2c_objs[i].dma.handle_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - i2c_objs[i].dma.handle_tx.Init.Mode = DMA_NORMAL; - i2c_objs[i].dma.handle_tx.Init.Priority = DMA_PRIORITY_LOW; + i2c_objs[i].dma.handle_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + i2c_objs[i].dma.handle_tx.Init.Mode = DMA_NORMAL; + i2c_objs[i].dma.handle_tx.Init.Priority = DMA_PRIORITY_LOW; #endif #if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) - i2c_objs[i].dma.handle_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - i2c_objs[i].dma.handle_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; - i2c_objs[i].dma.handle_tx.Init.MemBurst = DMA_MBURST_INC4; - i2c_objs[i].dma.handle_tx.Init.PeriphBurst = DMA_PBURST_INC4; + i2c_objs[i].dma.handle_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + i2c_objs[i].dma.handle_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + i2c_objs[i].dma.handle_tx.Init.MemBurst = DMA_MBURST_INC4; + i2c_objs[i].dma.handle_tx.Init.PeriphBurst = DMA_PBURST_INC4; #endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) */ - { - rt_uint32_t tmpreg = 0x00U; + } + if ((i2c_objs[i].i2c_dma_flag & I2C_USING_RX_DMA_FLAG)) + { + i2c_objs[i].dma.handle_rx.Instance = i2c_config[i].dma_rx->Instance; +#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) + i2c_objs[i].dma.handle_rx.Init.Channel = i2c_config[i].dma_rx->channel; +#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7) + i2c_objs[i].dma.handle_rx.Init.Request = i2c_config[i].dma_rx->request; +#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) */ +#ifndef SOC_SERIES_STM32U5 + i2c_objs[i].dma.handle_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + i2c_objs[i].dma.handle_rx.Init.PeriphInc = DMA_PINC_DISABLE; + i2c_objs[i].dma.handle_rx.Init.MemInc = DMA_MINC_ENABLE; + i2c_objs[i].dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + i2c_objs[i].dma.handle_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + i2c_objs[i].dma.handle_rx.Init.Mode = DMA_NORMAL; + i2c_objs[i].dma.handle_rx.Init.Priority = DMA_PRIORITY_LOW; +#endif /* SOC_SERIES_STM32U5 */ +#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) + + i2c_objs[i].dma.handle_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + i2c_objs[i].dma.handle_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + i2c_objs[i].dma.handle_tx.Init.MemBurst = DMA_MBURST_INC4; + i2c_objs[i].dma.handle_tx.Init.PeriphBurst = DMA_PBURST_INC4; + } +#endif /* defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) */ + { + rt_uint32_t tmpreg = 0x00U; #if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0) - /* enable DMA clock && Delay after an RCC peripheral clock enabling*/ - SET_BIT(RCC->AHBENR, i2c_config[i].dma_tx->dma_rcc); - tmpreg = READ_BIT(RCC->AHBENR, i2c_config[i].dma_tx->dma_rcc); + /* enable DMA clock && Delay after an RCC peripheral clock enabling*/ + SET_BIT(RCC->AHBENR, i2c_config[i].dma_tx->dma_rcc); + tmpreg = READ_BIT(RCC->AHBENR, i2c_config[i].dma_tx->dma_rcc); #elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32H7) SET_BIT(RCC->AHB1ENR, i2c_config[i].dma_tx->dma_rcc); /* Delay after an RCC peripheral clock enabling */ @@ -425,10 +410,8 @@ int RT_hw_i2c_bus_init(void) SET_BIT(RCC->MP_AHB2ENSETR, i2c_config[i].dma_tx->dma_rcc); tmpreg = READ_BIT(RCC->MP_AHB2ENSETR, i2c_config[i].dma_tx->dma_rcc); #endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32F0) */ - UNUSED(tmpreg); /* To avoid compiler warnings */ - } + UNUSED(tmpreg); /* To avoid compiler warnings */ } - rt_completion_init(&i2c_objs[i].completion); stm32_i2c_configure(&i2c_objs[i].i2c_bus); ret = rt_i2c_bus_device_register(&i2c_objs[i].i2c_bus, i2c_objs[i].config->name); @@ -711,11 +694,47 @@ void I2C3_DMA_TX_IRQHandler(void) } #endif /* defined(BSP_USING_HARD_I2C3) && defined(BSP_I2C3_TX_USING_DMA) */ +#if defined(BSP_USING_I2C4) && defined(BSP_I2C4_RX_USING_DMA) +/** + * @brief This function handles DMA Rx interrupt request. + * @param None + * @retval None + */ +void I2C4_DMA_RX_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + HAL_DMA_IRQHandler(&i2c_objs[I2C4_INDEX].dma.handle_rx); + + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* defined(BSP_USING_I2C4) && defined(BSP_I2C4_RX_USING_DMA) */ + +#if defined(BSP_USING_I2C4) && defined(BSP_I2C4_TX_USING_DMA) +/** + * @brief This function handles DMA Rx interrupt request. + * @param None + * @retval None + */ +void I2C4_DMA_TX_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + HAL_DMA_IRQHandler(&i2c_objs[I2C4_INDEX].dma.handle_tx); + + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* defined(BSP_USING_I2C4) && defined(BSP_I2C4_TX_USING_DMA) */ + int rt_hw_hw_i2c_init(void) { stm32_get_dma_info(); return RT_hw_i2c_bus_init(); } -INIT_BOARD_EXPORT(rt_hw_hw_i2c_init); +INIT_CORE_EXPORT(rt_hw_hw_i2c_init); #endif /* defined(BSP_USING_HARD_I2C1) || defined(BSP_USING_HARD_I2C2) || defined(BSP_USING_HARD_I2C3) */ diff --git a/libraries/HAL_Drivers/drivers/drv_hard_i2c.h b/libraries/HAL_Drivers/drivers/drv_hard_i2c.h index 0604651..5e91a26 100644 --- a/libraries/HAL_Drivers/drivers/drv_hard_i2c.h +++ b/libraries/HAL_Drivers/drivers/drv_hard_i2c.h @@ -11,10 +11,14 @@ #ifndef __DRV_HARD_I2C_H__ #define __DRV_HARD_I2C_H__ +#include "drv_config.h" +#include +#include "rtdevice.h" +#include #include #include "drv_dma.h" -#include "drv_config.h" #include +#if defined(RT_USING_I2C) && defined(BSP_USING_I2C) /* C binding of definitions if building with C++ compiler */ #ifdef __cplusplus @@ -24,28 +28,29 @@ extern "C" struct stm32_i2c_config { - const char *name; - I2C_TypeDef *Instance; - rt_uint32_t timing; - rt_uint32_t timeout; - IRQn_Type evirq_type; - IRQn_Type erirq_type; - struct dma_config *dma_rx; - struct dma_config *dma_tx; + const char *name; + I2C_TypeDef *Instance; + rt_uint32_t timing; + rt_uint32_t timeout; + IRQn_Type evirq_type; + IRQn_Type erirq_type; + + struct dma_config *dma_rx, *dma_tx; }; struct stm32_i2c { - I2C_HandleTypeDef handle; - struct stm32_i2c_config *config; + I2C_HandleTypeDef handle; struct { - DMA_HandleTypeDef handle_rx; - DMA_HandleTypeDef handle_tx; + DMA_HandleTypeDef handle_rx; + DMA_HandleTypeDef handle_tx; } dma; - rt_uint8_t i2c_dma_flag; - struct rt_i2c_bus_device i2c_bus; - struct rt_completion completion; + struct stm32_i2c_config *config; + struct rt_i2c_bus_device i2c_bus; + rt_uint8_t i2c_dma_flag; + struct rt_completion completion; + }; #define I2C_USING_TX_DMA_FLAG (1U) @@ -55,4 +60,6 @@ struct stm32_i2c } #endif +#endif /* BSP_USING_I2C */ + #endif /* __DRV_I2C_H__ */ diff --git a/libraries/HAL_Drivers/drivers/drv_lptim.c b/libraries/HAL_Drivers/drivers/drv_lptim.c index 192343f..60b8b36 100644 --- a/libraries/HAL_Drivers/drivers/drv_lptim.c +++ b/libraries/HAL_Drivers/drivers/drv_lptim.c @@ -1,320 +1,123 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2019-05-06 Zero-Free first version - * 2024-07-04 wdfk-prog lptimer is register with hwtimer, only supports pm calls,the timer function is not supported */ #include #include -#include -#include "drv_config.h" -/*#define DRV_DEBUG*/ -#define LOG_TAG "drv.lptim" -#include +static LPTIM_HandleTypeDef LptimHandle; -#ifdef BSP_USING_LPTIM - -#define LPTIM_REG_MAX_VALUE (0xFFFF) - -enum -{ -#ifdef BSP_USING_LPTIM1 - LPTIM1_INDEX, -#endif -#ifdef BSP_USING_LPTIM2 - LPTIM2_INDEX, -#endif -#ifdef BSP_USING_LPTIM3 - LPTIM3_INDEX, -#endif -}; - -struct stm32_hw_lptimer -{ - rt_hwtimer_t time_device; - LPTIM_HandleTypeDef tim_handle; - IRQn_Type tim_irqn; - char *name; -}; - -static struct stm32_hw_lptimer stm32_hw_lptimer_obj[] = -{ -#ifdef BSP_USING_LPTIM1 - LPTIM1_CONFIG, -#endif -#ifdef BSP_USING_LPTIM2 - LPTIM2_CONFIG, -#endif -#ifdef BSP_USING_LPTIM3 - LPTIM3_CONFIG, -#endif -}; - -static const struct rt_hwtimer_info _info = LPTIM_DEV_INFO_CONFIG; - -static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state) -{ - if(timer == RT_NULL) - { - LOG_E("init timer is NULL"); - return; - } - - if (state) - { - struct stm32_hw_lptimer *tim_device = rt_container_of(timer, struct stm32_hw_lptimer, time_device); - LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data; - - if(tim_device == RT_NULL) - { - LOG_E("start tim_device is NULL"); - return; - } - if(tim == RT_NULL) - { - LOG_E("start %s LPTIM_Handle is NULL", tim_device->name); - return; - } - - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct = {0}; - - /* Enable LSI clock */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; - RCC_OscInitStruct.LSIState = RCC_LSI_ON; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; - HAL_RCC_OscConfig(&RCC_OscInitStruct); - - /* Select the LSI clock as LPTIM peripheral clock */ - RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1; - RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSI; - HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct); - - tim->Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC; - tim->Init.Clock.Prescaler = LPTIM_PRESCALER_DIV32; - tim->Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE; - tim->Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH; - tim->Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE; - tim->Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL; - - HAL_StatusTypeDef ret = HAL_LPTIM_Init(tim); - if (ret != HAL_OK) - { - LOG_E("%s init failed %d", tim_device->name, ret); - } - else - { - NVIC_ClearPendingIRQ(LPTIM1_IRQn); - NVIC_SetPriority(LPTIM1_IRQn, 0); - NVIC_EnableIRQ(LPTIM1_IRQn); - LOG_D("%s init success", tim_device->name); - } - } -} - -static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode) -{ - if(timer == RT_NULL) - { - LOG_E("start timer is NULL"); - return -RT_EINVAL; - } - - struct stm32_hw_lptimer *tim_device = rt_container_of(timer, struct stm32_hw_lptimer, time_device); - LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data; - - if(tim_device == RT_NULL) - { - LOG_E("start tim_device is NULL"); - return -RT_EINVAL; - } - if(tim == RT_NULL) - { - LOG_E("start %s LPTIM_Handle is NULL", tim_device->name); - return -RT_EINVAL; - } - - HAL_StatusTypeDef ret = HAL_LPTIM_TimeOut_Start_IT(tim, LPTIM_REG_MAX_VALUE, t); - if(ret != HAL_OK) - { - LOG_E("start %s failed %d", tim_device->name, ret); - return -RT_ERROR; - } - else - { - LOG_D("start %s success", tim_device->name); - return RT_EOK; - } -} - -static void timer_stop(rt_hwtimer_t *timer) -{ - if(timer == RT_NULL) - { - LOG_E("stop timer is NULL"); - return; - } - - struct stm32_hw_lptimer *tim_device = rt_container_of(timer, struct stm32_hw_lptimer, time_device); - LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data; - - if(tim_device == RT_NULL) - { - LOG_E("stop tim_device is NULL"); - return; - } - if(tim == RT_NULL) - { - LOG_E("stop %s LPTIM_Handle is NULL", tim_device->name); - return; - } - - HAL_StatusTypeDef ret = HAL_LPTIM_TimeOut_Stop_IT(tim); - if(ret != HAL_OK) - { - LOG_E("stop %s failed %d", tim_device->name, ret); - } - else - { - LOG_D("stop %s success", tim_device->name); - } -} - -static rt_uint32_t timer_get_freq(LPTIM_HandleTypeDef *tim) -{ - /*No calculation is performed. The default initial configuration is 1000hz*/ - return 1000; -} - - -static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer) -{ - LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data; - return HAL_LPTIM_ReadCounter(tim); -} - -static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg) -{ - if(timer == RT_NULL) - { - LOG_E("start timer is NULL"); - return -RT_EINVAL; - } - - struct stm32_hw_lptimer *tim_device = rt_container_of(timer, struct stm32_hw_lptimer, time_device); - LPTIM_HandleTypeDef *tim = (LPTIM_HandleTypeDef *)timer->parent.user_data; - - if(tim_device == RT_NULL) - { - LOG_E("start tim_device is NULL"); - return -RT_EINVAL; - } - if(tim == RT_NULL) - { - LOG_E("start %s LPTIM_Handle is NULL", tim_device->name); - return -RT_EINVAL; - } - - rt_err_t result = RT_EOK; - switch (cmd) - { - case DRV_HW_LPTIMER_CTRL_GET_TICK_MAX: - { - *(rt_uint32_t *)arg = LPTIM_REG_MAX_VALUE; - break; - } - case DRV_HW_LPTIMER_CTRL_GET_FREQ: - { - *(rt_uint32_t *)arg = timer_get_freq(tim); - break; - } - case DRV_HW_LPTIMER_CTRL_START: - { - timer_start(timer, *(rt_uint32_t *)arg, HWTIMER_MODE_ONESHOT); - break; - } - case DRV_HW_LPTIMER_CTRL_GET_COUNT: - { - *(rt_uint32_t *)arg = timer_counter_get(timer); - break; - } - default: - { - result = -RT_ENOSYS; - } - break; - } - - return result; -} - -#ifdef BSP_USING_LPTIM1 void LPTIM1_IRQHandler(void) { + HAL_LPTIM_IRQHandler(&LptimHandle); +} + +void HAL_LPTIM_CompareMatchCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* enter interrupt */ rt_interrupt_enter(); - HAL_LPTIM_IRQHandler(&stm32_hw_lptimer_obj[LPTIM1_INDEX].tim_handle); + + /* leave interrupt */ rt_interrupt_leave(); } -#endif -#ifdef BSP_USING_LPTIM2 -void LPTIM2_IRQHandler(void) +/** + * This function get current count value of LPTIM + * + * @return the count vlaue + */ +rt_uint32_t stm32l4_lptim_get_current_tick(void) { - rt_interrupt_enter(); - HAL_LPTIM_IRQHandler(&stm32_hw_lptimer_obj[LPTIM2_INDEX].tim_handle); - rt_interrupt_leave(); + return HAL_LPTIM_ReadCounter(&LptimHandle); } -#endif -#ifdef BSP_USING_LPTIM3 -void LPTIM3_IRQHandler(void) +/** + * This function get the max value that LPTIM can count + * + * @return the max count + */ +rt_uint32_t stm32l4_lptim_get_tick_max(void) { - rt_interrupt_enter(); - HAL_LPTIM_IRQHandler(&stm32_hw_lptimer_obj[LPTIM3_INDEX].tim_handle); - rt_interrupt_leave(); + return (0xFFFF); } -#endif -static const struct rt_hwtimer_ops _ops = +/** + * This function start LPTIM with reload value + * + * @param reload The value that LPTIM count down from + * + * @return RT_EOK + */ +rt_err_t stm32l4_lptim_start(rt_uint32_t reload) { - .init = timer_init, - .start = timer_start, - .stop = timer_stop, - .count_get = timer_counter_get, - .control = timer_ctrl, -}; + HAL_LPTIM_TimeOut_Start_IT(&LptimHandle, 0xFFFF, reload); + + return (RT_EOK); +} + +/** + * This function stop LPTIM + */ +void stm32l4_lptim_stop(void) +{ + rt_uint32_t _ier; + + _ier = LptimHandle.Instance->IER; + LptimHandle.Instance->ICR = LptimHandle.Instance->ISR & _ier; +} + +/** + * This function get the count clock of LPTIM + * + * @return the count clock frequency in Hz + */ +rt_uint32_t stm32l4_lptim_get_countfreq(void) +{ + return 32000 / 32; +} /** * This function initialize the lptim */ -static int stm32_hw_lptim_init(void) +int stm32l4_hw_lptim_init(void) { - int i = 0; - int result = RT_EOK; + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct = {0}; - for (i = 0; i < sizeof(stm32_hw_lptimer_obj) / sizeof(stm32_hw_lptimer_obj[0]); i++) + /* Enable LSI clock */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select the LSI clock as LPTIM peripheral clock */ + RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1; + RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSI; + HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct); + + LptimHandle.Instance = LPTIM1; + LptimHandle.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC; + LptimHandle.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV32; + LptimHandle.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE; + LptimHandle.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH; + LptimHandle.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE; + LptimHandle.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL; + if (HAL_LPTIM_Init(&LptimHandle) != HAL_OK) { - stm32_hw_lptimer_obj[i].time_device.info = &_info; - stm32_hw_lptimer_obj[i].time_device.ops = &_ops; - if (rt_device_hwtimer_register(&stm32_hw_lptimer_obj[i].time_device, stm32_hw_lptimer_obj[i].name, &stm32_hw_lptimer_obj[i].tim_handle) == RT_EOK) - { - LOG_D("%s register success", stm32_hw_lptimer_obj[i].name); - } - else - { - LOG_E("%s register failed", stm32_hw_lptimer_obj[i].name); - result = -RT_ERROR; - } + return -1; } - return result; + NVIC_ClearPendingIRQ(LPTIM1_IRQn); + NVIC_SetPriority(LPTIM1_IRQn, 0); + NVIC_EnableIRQ(LPTIM1_IRQn); + + return 0; } -INIT_BOARD_EXPORT(stm32_hw_lptim_init); -#endif /* BSP_USING_LPTIM */ +INIT_DEVICE_EXPORT(stm32l4_hw_lptim_init); diff --git a/libraries/HAL_Drivers/drivers/drv_lptim.h b/libraries/HAL_Drivers/drivers/drv_lptim.h index 124242a..79f3e11 100644 --- a/libraries/HAL_Drivers/drivers/drv_lptim.h +++ b/libraries/HAL_Drivers/drivers/drv_lptim.h @@ -1,12 +1,11 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2019-05-06 Zero-Free first version - * 2024-07-04 wdfk-prog lptimer is register with hwtimer, only supports pm calls,the timer function is not supported */ #ifndef __DRV_PMTIMER_H__ @@ -14,13 +13,11 @@ #include -/* 0x20 - 0x3F udevice control commands*/ -typedef enum -{ - DRV_HW_LPTIMER_CTRL_GET_TICK_MAX = 0x20, /* get the maximum tick value*/ - DRV_HW_LPTIMER_CTRL_GET_FREQ = 0X21, /* get the timer frequency*/ - DRV_HW_LPTIMER_CTRL_START = 0X22, /* set the timeout value*/ - DRV_HW_LPTIMER_CTRL_GET_COUNT = 0X23, /* get the current count value*/ -} drv_hw_lptimer_ctrl_t; +rt_uint32_t stm32l4_lptim_get_countfreq(void); +rt_uint32_t stm32l4_lptim_get_tick_max(void); +rt_uint32_t stm32l4_lptim_get_current_tick(void); + +rt_err_t stm32l4_lptim_start(rt_uint32_t load); +void stm32l4_lptim_stop(void); #endif /* __DRV_PMTIMER_H__ */ diff --git a/libraries/HAL_Drivers/drivers/drv_pm.c b/libraries/HAL_Drivers/drivers/drv_pm.c index 2b93c30..9d336a3 100644 --- a/libraries/HAL_Drivers/drivers/drv_pm.c +++ b/libraries/HAL_Drivers/drivers/drv_pm.c @@ -1,50 +1,22 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2019-05-06 Zero-Free first version - * 2024-07-04 wdfk-prog lptimer is supported */ #include #include #include -/*#define DRV_DEBUG*/ -#define LOG_TAG "drv.pm" -#include - -#ifdef RT_USING_PM - -#ifndef BSP_USING_PM_TIMER -/* -! Using LPTIM timer, the maximum sleep time is 65535, less than 1 min. Use RTC alarm timers for longer periods. -! For example: packages can be used :https://packages.rt-thread.org/detail.html?package=multi_rtimer -*/ -#ifdef BSP_USING_LPTIM1 -#define BSP_USING_PM_TIMER "lptim1" -#elif BSP_USING_LPTIM2 -#define BSP_USING_PM_TIMER "lptim2" -#elif BSP_USING_LPTIM3 -#define BSP_USING_PM_TIMER "lptim3" -#else -#error "Please define BSP_USING_PM_TIMER" -#endif - -static rt_device_t timer = RT_NULL; - -/* Re-configure the system clock */ -rt_weak void SystemClock_ReConfig(uint8_t run_mode) +static void uart_console_reconfig(void) { - /*todo add your code here*/ -} + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; -rt_weak void stm32_pm_device_run(struct rt_pm *pm, uint8_t mode) -{ - /*todo add your code here*/ + rt_device_control(rt_console_get_device(), RT_DEVICE_CTRL_CONFIG, &config); } /** @@ -60,6 +32,7 @@ static void sleep(struct rt_pm *pm, uint8_t mode) break; case PM_SLEEP_MODE_IDLE: + // __WFI(); break; case PM_SLEEP_MODE_LIGHT: @@ -76,12 +49,10 @@ static void sleep(struct rt_pm *pm, uint8_t mode) break; case PM_SLEEP_MODE_DEEP: -#if defined(SOC_SERIES_STM32L4) /* Enter STOP 2 mode */ HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI); /* Re-configure the system clock */ SystemClock_ReConfig(pm->run_mode); -#endif /* defined(SOC_SERIES_STM32L4) */ break; case PM_SLEEP_MODE_STANDBY: @@ -90,17 +61,74 @@ static void sleep(struct rt_pm *pm, uint8_t mode) break; case PM_SLEEP_MODE_SHUTDOWN: -#if defined(SOC_SERIES_STM32L4) /* Enter SHUTDOWNN mode */ HAL_PWREx_EnterSHUTDOWNMode(); -#endif /* defined(SOC_SERIES_STM32L4) */ break; default: + RT_ASSERT(0); break; } } +static uint8_t run_speed[PM_RUN_MODE_MAX][2] = +{ + {80, 0}, + {80, 1}, + {24, 2}, + {2, 3}, +}; + +static void run(struct rt_pm *pm, uint8_t mode) +{ + static uint8_t last_mode; + static char *run_str[] = PM_RUN_MODE_NAMES; + + if (mode == last_mode) + return; + last_mode = mode; + + /* 1. 设置 MSI 作为 SYSCLK 时钟源,以修改 PLL */ + SystemClock_MSI_ON(); + + /* 2. 根据RUN模式切换时钟频率(HSI) */ + switch (mode) + { + case PM_RUN_MODE_HIGH_SPEED: + case PM_RUN_MODE_NORMAL_SPEED: + HAL_PWREx_DisableLowPowerRunMode(); + SystemClock_80M(); + /* Configure the main internal regulator output voltage (Range1 by default)*/ + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); + break; + case PM_RUN_MODE_MEDIUM_SPEED: + HAL_PWREx_DisableLowPowerRunMode(); + SystemClock_24M(); + /* Configure the main internal regulator output voltage */ + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2); + break; + case PM_RUN_MODE_LOW_SPEED: + SystemClock_2M(); + /* Enter LP RUN mode */ + HAL_PWREx_EnableLowPowerRunMode(); + break; + default: + break; + } + + /* 3. 关闭 MSI 时钟 */ + // SystemClock_MSI_OFF(); + + /* 4. 更新外设时钟 */ + uart_console_reconfig(); + /* Re-Configure the Systick time */ + HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / RT_TICK_PER_SECOND); + /* Re-Configure the Systick */ + HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); + + rt_kprintf("switch to %s mode, frequency = %d MHz\n", run_str[mode], run_speed[mode][0]); +} + /** * This function caculate the PM tick from OS tick * @@ -108,19 +136,9 @@ static void sleep(struct rt_pm *pm, uint8_t mode) * * @return the PM tick */ -static rt_tick_t stm32_pm_tick_from_os_tick(rt_tick_t tick) +static rt_tick_t stm32l4_pm_tick_from_os_tick(rt_tick_t tick) { - rt_uint32_t freq = 0; - rt_err_t ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_GET_FREQ, &freq); - if(ret != RT_EOK) - { - LOG_E("Get PM timer %s frequency failed %d", timer->parent.name, ret); - return 0; - } - else - { - LOG_D("Get PM timer %s frequency %d", timer->parent.name, freq); - } + rt_uint32_t freq = stm32l4_lptim_get_countfreq(); return (freq * tick / RT_TICK_PER_SECOND); } @@ -132,25 +150,18 @@ static rt_tick_t stm32_pm_tick_from_os_tick(rt_tick_t tick) * * @return the OS tick */ -static rt_tick_t stm32_os_tick_from_pm_tick(rt_uint32_t tick) +static rt_tick_t stm32l4_os_tick_from_pm_tick(rt_uint32_t tick) { static rt_uint32_t os_tick_remain = 0; - rt_tick_t os_tick = 0; - rt_uint32_t freq = 0; + rt_uint32_t ret, freq; - rt_err_t ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_GET_FREQ, &freq); - if(ret != RT_EOK) - { - LOG_E("Get PM timer %s frequency failed %d", timer->parent.name, ret); - return 0; - } - - os_tick = (tick * RT_TICK_PER_SECOND + os_tick_remain) / freq; + freq = stm32l4_lptim_get_countfreq(); + ret = (tick * RT_TICK_PER_SECOND + os_tick_remain) / freq; os_tick_remain += (tick * RT_TICK_PER_SECOND); os_tick_remain %= freq; - return os_tick; + return ret; } /** @@ -163,33 +174,18 @@ static void pm_timer_start(struct rt_pm *pm, rt_uint32_t timeout) { RT_ASSERT(pm != RT_NULL); RT_ASSERT(timeout > 0); - RT_ASSERT(timer != RT_NULL); if (timeout != RT_TICK_MAX) { - rt_uint32_t max_tick = 0; - rt_err_t ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_GET_TICK_MAX, &max_tick); - if(ret != RT_EOK) - { - LOG_E("Get PM timer %s max tick failed %d", timer->parent.name, ret); - return; - } - /* Convert OS Tick to pmtimer timeout value */ - timeout = stm32_pm_tick_from_os_tick(timeout); - - if (timeout > max_tick) + timeout = stm32l4_pm_tick_from_os_tick(timeout); + if (timeout > stm32l4_lptim_get_tick_max()) { - timeout = max_tick; + timeout = stm32l4_lptim_get_tick_max(); } /* Enter PM_TIMER_MODE */ - ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_START, &timeout); - if(ret != RT_EOK) - { - LOG_E("Get PM timer %s max tick failed %d", timer->parent.name, ret); - return; - } + stm32l4_lptim_start(timeout); } } @@ -203,7 +199,7 @@ static void pm_timer_stop(struct rt_pm *pm) RT_ASSERT(pm != RT_NULL); /* Reset pmtimer status */ - rt_device_control(timer, HWTIMER_CTRL_STOP, RT_NULL); + stm32l4_lptim_stop(); } /** @@ -219,42 +215,29 @@ static rt_tick_t pm_timer_get_tick(struct rt_pm *pm) RT_ASSERT(pm != RT_NULL); - rt_err_t ret = rt_device_control(timer, DRV_HW_LPTIMER_CTRL_GET_COUNT, &timer_tick); + timer_tick = stm32l4_lptim_get_current_tick(); - if(ret != RT_EOK) - { - LOG_E("Get PM timer %s count failed %d", timer->parent.name, ret); - return 0; - } - else - { - return stm32_os_tick_from_pm_tick(timer_tick); - } + return stm32l4_os_tick_from_pm_tick(timer_tick); } -static const struct rt_pm_ops _ops = -{ - sleep, - stm32_pm_device_run, - pm_timer_start, - pm_timer_stop, - pm_timer_get_tick -}; - /** * This function initialize the power manager */ int drv_pm_hw_init(void) { + static const struct rt_pm_ops _ops = + { + sleep, + run, + pm_timer_start, + pm_timer_stop, + pm_timer_get_tick + }; + rt_uint8_t timer_mask = 0; /* Enable Power Clock */ -#if !defined(SOC_SERIES_STM32H7) && !defined(SOC_SERIES_STM32WL) && !defined(SOC_SERIES_STM32WB) __HAL_RCC_PWR_CLK_ENABLE(); -#ifdef SOC_SERIES_STM32F1 - __HAL_RCC_BKP_CLK_ENABLE(); -#endif -#endif /* initialize timer mask */ timer_mask = 1UL << PM_SLEEP_MODE_DEEP; @@ -262,18 +245,7 @@ int drv_pm_hw_init(void) /* initialize system pm module */ rt_system_pm_init(&_ops, timer_mask, RT_NULL); - timer = rt_device_find(BSP_USING_PM_TIMER); - - if(timer == RT_NULL) - { - LOG_E("Can't find PM timer device"); - return -RT_ERROR; - } - else - { - return rt_device_init(timer); - } + return 0; } -INIT_CORE_EXPORT(drv_pm_hw_init); -#endif /* RT_USING_PM */ +INIT_BOARD_EXPORT(drv_pm_hw_init); diff --git a/libraries/HAL_Drivers/drivers/drv_pwm.c b/libraries/HAL_Drivers/drivers/drv_pwm.c index d097e68..478d1d8 100644 --- a/libraries/HAL_Drivers/drivers/drv_pwm.c +++ b/libraries/HAL_Drivers/drivers/drv_pwm.c @@ -15,7 +15,7 @@ #ifdef BSP_USING_PWM #include "drv_config.h" #include "drv_tim.h" -#include +#include //#define DRV_DEBUG #define LOG_TAG "drv.pwm" diff --git a/libraries/HAL_Drivers/drivers/drv_rtc.c b/libraries/HAL_Drivers/drivers/drv_rtc.c index 41097fe..d5bc350 100644 --- a/libraries/HAL_Drivers/drivers/drv_rtc.c +++ b/libraries/HAL_Drivers/drivers/drv_rtc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -22,7 +22,7 @@ #define RTC_BKP_DR1 RT_NULL #endif -/* #define DRV_DEBUG*/ +//#define DRV_DEBUG #define LOG_TAG "drv.rtc" #include @@ -393,7 +393,7 @@ static rt_err_t rtc_alarm_time_set(struct rtc_device_object* p_dev) void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) { - /*LOG_D("rtc alarm isr.\n");*/ + //LOG_D("rtc alarm isr.\n"); rt_alarm_update(&rtc_device.rtc_dev.parent, 1); } @@ -424,5 +424,5 @@ static int rt_hw_rtc_init(void) return RT_EOK; } -INIT_BOARD_EXPORT(rt_hw_rtc_init); +INIT_DEVICE_EXPORT(rt_hw_rtc_init); #endif /* BSP_USING_ONCHIP_RTC */ diff --git a/libraries/HAL_Drivers/drivers/drv_sdio.h b/libraries/HAL_Drivers/drivers/drv_sdio.h index 2da9026..9a122e4 100644 --- a/libraries/HAL_Drivers/drivers/drv_sdio.h +++ b/libraries/HAL_Drivers/drivers/drv_sdio.h @@ -17,8 +17,8 @@ #include #include "drv_dma.h" #include -#include -#include +#include +#include #if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) #define SDCARD_INSTANCE_TYPE SDIO_TypeDef @@ -35,6 +35,10 @@ #define SDIO_BUFF_SIZE 4096 #define SDIO_ALIGN_LEN 32 +#ifndef SDIO_MAX_FREQ +#define SDIO_MAX_FREQ (1000000) +#endif + #ifndef SDIO_BASE_ADDRESS #define SDIO_BASE_ADDRESS (0x40012800U) #endif diff --git a/libraries/HAL_Drivers/drivers/drv_sdmmc.h b/libraries/HAL_Drivers/drivers/drv_sdmmc.h index 3e5631c..6b388d4 100644 --- a/libraries/HAL_Drivers/drivers/drv_sdmmc.h +++ b/libraries/HAL_Drivers/drivers/drv_sdmmc.h @@ -18,8 +18,8 @@ #include #include #include -#include -#include +#include +#include #define SDIO_BUFF_SIZE 4096 #define SDIO_ALIGN_LEN 32 diff --git a/libraries/HAL_Drivers/drivers/drv_soft_spi.c b/libraries/HAL_Drivers/drivers/drv_soft_spi.c index ff9e124..912e709 100644 --- a/libraries/HAL_Drivers/drivers/drv_soft_spi.c +++ b/libraries/HAL_Drivers/drivers/drv_soft_spi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -156,6 +156,36 @@ void stm32_dir_miso(void *data, rt_int32_t state) } } +static void stm32_udelay(rt_uint32_t us) +{ + rt_uint32_t ticks; + rt_uint32_t told, tnow, tcnt = 0; + rt_uint32_t reload = SysTick->LOAD; + + ticks = us * reload / (1000000UL / RT_TICK_PER_SECOND); + told = SysTick->VAL; + while (1) + { + tnow = SysTick->VAL; + if (tnow != told) + { + if (tnow < told) + { + tcnt += told - tnow; + } + else + { + tcnt += reload - tnow + told; + } + told = tnow; + if (tcnt >= ticks) + { + break; + } + } + } +} + static void stm32_pin_init(void) { rt_size_t obj_num = sizeof(spi_obj) / sizeof(struct stm32_soft_spi); @@ -179,7 +209,7 @@ static struct rt_spi_bit_ops stm32_soft_spi_ops = .get_miso = stm32_get_miso, .dir_mosi = stm32_dir_mosi, .dir_miso = stm32_dir_miso, - .udelay = rt_hw_us_delay, + .udelay = stm32_udelay, .delay_us = 1, }; diff --git a/libraries/HAL_Drivers/drivers/drv_soft_spi.h b/libraries/HAL_Drivers/drivers/drv_soft_spi.h index 2b1a5c6..d641587 100644 --- a/libraries/HAL_Drivers/drivers/drv_soft_spi.h +++ b/libraries/HAL_Drivers/drivers/drv_soft_spi.h @@ -13,7 +13,7 @@ #include #include -#include +#include /* stm32 soft spi config */ struct stm32_soft_spi_config diff --git a/libraries/HAL_Drivers/drivers/drv_usart.c b/libraries/HAL_Drivers/drivers/drv_usart.c index ca344d9..5c41bf2 100644 --- a/libraries/HAL_Drivers/drivers/drv_usart.c +++ b/libraries/HAL_Drivers/drivers/drv_usart.c @@ -357,7 +357,7 @@ static int stm32_putc(struct rt_serial_device *serial, char c) #else uart->handle.Instance->DR = c; #endif - while (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) == RESET && --block_timeout); + while (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) == RESET && block_timeout--); return (block_timeout != 0) ? 1 : -1; } diff --git a/rt-thread/README.md b/rt-thread/README.md index f0e7d25..070c2fc 100644 --- a/rt-thread/README.md +++ b/rt-thread/README.md @@ -11,8 +11,7 @@ [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/RT-Thread/rt-thread?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![GitHub pull-requests](https://img.shields.io/github/issues-pr/RT-Thread/rt-thread.svg)](https://github.com/RT-Thread/rt-thread/pulls) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](https://github.com/RT-Thread/rt-thread/pulls) -[![RT-Thread BSP Static Build Check](https://github.com/RT-Thread/rt-thread/actions/workflows/bsp_buildings.yml/badge.svg)](https://github.com/RT-Thread/rt-thread/actions/workflows/bsp_buildings.yml) -Featured|HelloGitHub + # RT-Thread RT-Thread was born in 2006, it is an open source, neutral, and community-based real-time operating system (RTOS). diff --git a/rt-thread/components/dfs/Kconfig b/rt-thread/components/dfs/Kconfig index 9b2f1b4..2c822cf 100644 --- a/rt-thread/components/dfs/Kconfig +++ b/rt-thread/components/dfs/Kconfig @@ -162,32 +162,20 @@ endif bool "Using devfs for device objects" default y -if RT_USING_DFS_V1 - config RT_USING_DFS_ISO9660 - bool "Using ISO9660 filesystem" - depends on RT_USING_MEMHEAP - default n -endif - - menuconfig RT_USING_DFS_ROMFS + config RT_USING_DFS_ROMFS bool "Enable ReadOnly file system on flash" default n - if RT_USING_DFS_ROMFS - config RT_USING_DFS_ROMFS_USER_ROOT - bool "Use user's romfs root" - depends on RT_USING_DFS_V1 - default n - endif + config RT_USING_DFS_ROMFS_USER_ROOT + bool "Use user's romfs root" + depends on RT_USING_DFS_ROMFS + default n if RT_USING_SMART config RT_USING_DFS_PTYFS bool "Using Pseudo-Teletype Filesystem (UNIX98 PTY)" depends on RT_USING_DFS_DEVFS default y - config RT_USING_DFS_PROCFS - bool "Enable proc file system" - default n endif config RT_USING_DFS_CROMFS diff --git a/rt-thread/components/dfs/dfs_v1/SConscript b/rt-thread/components/dfs/dfs_v1/SConscript index 42f8b95..181cf67 100644 --- a/rt-thread/components/dfs/dfs_v1/SConscript +++ b/rt-thread/components/dfs/dfs_v1/SConscript @@ -1,6 +1,4 @@ from building import * -from gcc import * -import rtconfig import os # The set of source files associated with this SConscript file. @@ -8,7 +6,6 @@ src = [] cwd = GetCurrentDir() CPPPATH = [cwd + "/include"] group = [] -LOCAL_CFLAGS = '' if GetDepend('RT_USING_DFS') and not GetDepend('RT_USING_DFS_V2'): src = ['src/dfs.c', 'src/dfs_file.c', 'src/dfs_fs.c'] @@ -16,12 +13,7 @@ if GetDepend('RT_USING_DFS') and not GetDepend('RT_USING_DFS_V2'): if GetDepend('DFS_USING_POSIX'): src += ['src/dfs_posix.c'] - if rtconfig.PLATFORM in GetGCCLikePLATFORM(): - LOCAL_CFLAGS += ' -std=c99' - elif rtconfig.PLATFORM in ['armcc']: - LOCAL_CFLAGS += ' --c99' - - group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS'], CPPPATH = CPPPATH, LOCAL_CFLAGS = LOCAL_CFLAGS) + group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS'], CPPPATH = CPPPATH) # search in the file system implementation list = os.listdir(cwd) diff --git a/rt-thread/components/dfs/dfs_v1/filesystems/iso9660/SConscript b/rt-thread/components/dfs/dfs_v1/filesystems/iso9660/SConscript deleted file mode 100644 index d3d8e8c..0000000 --- a/rt-thread/components/dfs/dfs_v1/filesystems/iso9660/SConscript +++ /dev/null @@ -1,11 +0,0 @@ -# RT-Thread building script for component - -from building import * - -cwd = GetCurrentDir() -src = Glob('*.c') -CPPPATH = [cwd] - -group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_ISO9660'], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/dfs/dfs_v1/filesystems/iso9660/dfs_iso9660.c b/rt-thread/components/dfs/dfs_v1/filesystems/iso9660/dfs_iso9660.c deleted file mode 100644 index 612b68c..0000000 --- a/rt-thread/components/dfs/dfs_v1/filesystems/iso9660/dfs_iso9660.c +++ /dev/null @@ -1,698 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#include -#include -#include - -#define DBG_TAG "dfs.iso9660" -#define DBG_LVL DBG_INFO -#include - -#include "dfs_iso9660.h" -#include -#include -#include -#include -#include -#include - -#include - -#define ISO9660_FSTYPE_DIR 0040000 -#define ISO9660_FSTYPE_REG 0100000 -#define ISO9660_FSTYPE_SYMLINK 0120000 -#define ISO9660_FSTYPE_MASK 0170000 - -#define ISO9660_BLKSZ 2048 - -#define ISO9660_VOLDESC_BOOT 0 -#define ISO9660_VOLDESC_PRIMARY 1 -#define ISO9660_VOLDESC_SUPP 2 -#define ISO9660_VOLDESC_PART 3 -#define ISO9660_VOLDESC_END 255 - -rt_packed(struct iso9660_voldesc -{ - rt_uint8_t type; - rt_uint8_t magic[5]; - rt_uint8_t version; -}); - -rt_packed(struct iso9660_date2 -{ - rt_uint8_t year; - rt_uint8_t month; - rt_uint8_t day; - rt_uint8_t hour; - rt_uint8_t minute; - rt_uint8_t second; - rt_uint8_t offset; -}); - -/* Directory entry */ -rt_packed(struct iso9660_dir -{ - rt_uint8_t len; - rt_uint8_t ext_sectors; - rt_le32_t first_sector; - rt_le32_t first_sector_be; - rt_le32_t size; - rt_le32_t size_be; - struct iso9660_date2 mtime; -#define FLAG_TYPE_PLAIN 0 -#define FLAG_TYPE_DIR 2 -#define FLAG_TYPE 3 -#define FLAG_MORE_EXTENTS 0x80 - rt_uint8_t flags; - rt_uint8_t file_unit_size; - rt_uint8_t interleave_gap_size; - rt_le16_t vol_seq_num; - rt_le16_t vol_seq_num_be; -#define MAX_NAMELEN 255 - rt_uint8_t namelen; - char name[0]; -}); - -rt_packed(struct iso9660_date -{ - rt_uint8_t year[4]; - rt_uint8_t month[2]; - rt_uint8_t day[2]; - rt_uint8_t hour[2]; - rt_uint8_t minute[2]; - rt_uint8_t second[2]; - rt_uint8_t hundredth[2]; - rt_uint8_t offset; -}); - -/* Common volume descriptor */ -rt_packed(struct iso9660_common_voldesc -{ - struct iso9660_voldesc voldesc; - rt_uint8_t sysname[33]; - rt_uint8_t volname[32]; - rt_uint8_t unused2[8]; - rt_le32_t vol_space_size_le; - rt_le32_t vol_space_size_be; - rt_uint8_t escape[32]; - rt_le16_t vol_set_size_le; - rt_le16_t vol_set_size_be; - rt_le16_t vol_seq_num_le; - rt_le16_t vol_seq_num_be; - rt_le16_t logical_block_size_le; - rt_le16_t logical_block_size_be; - rt_le32_t path_table_size; - rt_le32_t path_table_size_be; - rt_le32_t path_table; - rt_le32_t path_table_be; - rt_uint8_t unused3[8]; - struct iso9660_dir rootdir; - rt_uint8_t unused4[624]; - struct iso9660_date created; - struct iso9660_date modified; - rt_uint8_t unused5[0 /* 1201 */]; -}); - -struct iso9660 -{ - struct rt_device *dev; - - rt_uint8_t joliet; - rt_uint8_t swap[ISO9660_BLKSZ]; - - struct iso9660_common_voldesc primary, supp; -}; - -struct iso9660_fd -{ - struct iso9660 *iso; - - struct iso9660_dir dirent; -}; - -struct iso9660_iterate -{ - struct iso9660_fd *fd; - - int i, index, count; - struct dirent *dirp; -}; - -static void iso9660_convert_string(char *dest, rt_uint16_t *src, int len) -{ - /* UTF16 to ASCII */ - len >>= 1; - - for (int i = 0; i < len; ++i) - { - rt_uint16_t utf16 = rt_be16_to_cpu(*src++); - - if (utf16 < 0x80) - { - *dest++ = (rt_uint8_t)utf16; - } - else - { - *dest++ = '?'; - } - } - *dest = '\0'; -} - -static void iso9660_convert_lower(char *dest, rt_uint8_t *src, int len) -{ - for (int i = 0; i < len; ++i, ++src) - { - if (*src >= 'A' && *src <= 'Z') - { - *dest++ = *src - ('A' - 'a'); - } - else - { - *dest++ = *src; - } - } - - *dest = '\0'; -} - -static time_t iso9660_convert_unixtime(struct iso9660_date *date) -{ - struct tm tm; - - tm.tm_sec = (date->second[0] - '0') * 10 + (date->second[1] - '0'); - tm.tm_min = (date->minute[0] - '0') * 10 + (date->minute[1] - '0'); - tm.tm_hour = (date->hour[0] - '0') * 10 + (date->hour[1] - '0'); - tm.tm_mday = (date->day[0] - '0') * 10 + (date->day[1] - '0'); - tm.tm_mon = (date->month[0] - '0') * 10 + (date->month[1] - '0'); - tm.tm_year = (date->year[0] - '0') * 1000 + (date->year[1] - '0') * 100 + - (date->year[2] - '0') * 10 + (date->year[3] - '0'); - tm.tm_wday = 0; - - return mktime(&tm); -} - -static time_t iso9660_convert_unixtime2(struct iso9660_date2 *date) -{ - struct tm tm; - - tm.tm_sec = date->second; - tm.tm_min = date->minute; - tm.tm_hour = date->hour; - tm.tm_mday = date->day; - tm.tm_mon = date->month; - tm.tm_year = date->year + 1900; - tm.tm_wday = 0; - - return mktime(&tm); -} - -static struct iso9660_fd *iso9660_lookup(struct iso9660 *iso, const char *path, - struct iso9660_iterate *it) -{ - rt_uint32_t lba; - rt_size_t sz, len, namelen; - char sname[MAX_NAMELEN]; - struct iso9660_fd *fd; - struct iso9660_dir *dirent; - - if (it) - { - fd = it->fd; - iso = fd->iso; - dirent = &fd->dirent; - - /* No next entry, always goon */ - len = 1; - } - else - { - if (!(fd = rt_malloc(sizeof(*fd)))) - { - return fd; - } - - fd->iso = iso; - dirent = iso->joliet ? &iso->supp.rootdir : &iso->primary.rootdir; - - if (!rt_strcmp(path, "/")) - { - rt_memcpy(&fd->dirent, dirent, sizeof(*dirent)); - return fd; - } - - /* Skip the first '/' */ - ++path; - len = strchrnul(path, '/') - path; - } - - lba = rt_le32_to_cpu(dirent->first_sector); - if (rt_device_read(iso->dev, lba, iso->swap, 1) <= 0) - { - goto _fail; - } - dirent = (void *)iso->swap; - sz = 0; - - do { - /* Ignore "." and ".." */ - do { - rt_uint32_t dlen = rt_le32_to_cpu(dirent->len); - - dirent = (void *)dirent + dlen; - sz += dlen; - - if (ISO9660_BLKSZ - sz < sizeof(*dirent)) - { - /* Sector end, goto the next sector */ - if (rt_device_read(iso->dev, ++lba, iso->swap, 1) <= 0) - { - goto _fail; - } - dirent = (void *)iso->swap; - sz = 0; - } - - if (rt_le32_to_cpu(dirent->first_sector) == 0) - { - /* Is end, no found. */ - goto _fail; - } - } while (dirent->name[0] >> 1 == 0 && rt_le32_to_cpu(dirent->namelen) == 1); - - namelen = rt_le32_to_cpu(dirent->namelen); - - if (iso->joliet) - { - iso9660_convert_string(sname, (rt_uint16_t *)dirent->name, namelen); - } - else - { - if (!(rt_le32_to_cpu(dirent->flags) & FLAG_TYPE_DIR)) - { - /* Remove ";1" */ - namelen -= 2; - } - - iso9660_convert_lower(sname, (rt_uint8_t *)dirent->name, namelen); - } - - if (it) - { - if (it->i < it->index) - { - goto _next; - } - - if ((rt_le32_to_cpu(dirent->flags) & FLAG_TYPE) == FLAG_TYPE_DIR) - { - it->dirp->d_type = DT_DIR; - } - else - { - it->dirp->d_type = DT_REG; - } - - it->dirp->d_namlen = namelen; - rt_strncpy(it->dirp->d_name, sname, namelen); - it->dirp->d_name[namelen] = '\0'; - it->dirp->d_reclen = (rt_uint16_t)sizeof(struct dirent); - - ++it->dirp; - - _next: - ++it->i; - - if (it->i - it->index >= it->count) - { - /* Iterate end */ - return RT_NULL; - } - - /* No next entry */ - continue; - } - - if (!rt_strncmp(sname, path, len)) - { - /* The end of path, found ok */ - if (!path[len]) - { - rt_memcpy(&fd->dirent, dirent, sizeof(*dirent)); - return fd; - } - - /* Next entry */ - lba = rt_le32_to_cpu(dirent->first_sector); - if (rt_device_read(iso->dev, lba, iso->swap, 1) <= 0) - { - goto _fail; - } - dirent = (void *)iso->swap; - sz = 0; - - path += len + 1; - len = strchrnul(path, '/') - path; - } - } while (len); - -_fail: - if (!it) - { - rt_free(fd); - } - - return RT_NULL; -} - -static int dfs_iso9660_open(struct dfs_file *fd) -{ - struct iso9660 *iso = fd->vnode->fs->data; - - fd->vnode->data = iso9660_lookup(iso, fd->vnode->path, RT_NULL); - - return fd->vnode->data ? 0 : -EINVAL; -} - -static int dfs_iso9660_close(struct dfs_file *fd) -{ - struct iso9660_fd *iso_fd = fd->vnode->data; - - rt_free(iso_fd); - - return 0; -} - -static int dfs_iso9660_read(struct dfs_file *fd, void *buf, size_t count) -{ - rt_uint32_t pos; - void *buf_ptr; - ssize_t read_blk, toread_blk; - size_t rcount = 0, remain, size; - struct iso9660_fd *iso_fd = fd->vnode->data; - struct iso9660 *iso = iso_fd->iso; - - if (fd->pos + count > rt_le32_to_cpu(iso_fd->dirent.size)) - { - count = rt_le32_to_cpu(iso_fd->dirent.size) - fd->pos; - } - pos = rt_le32_to_cpu(iso_fd->dirent.first_sector); - - /* Align to a sector */ - if (fd->pos) - { - pos += fd->pos / ISO9660_BLKSZ; - remain = fd->pos & (ISO9660_BLKSZ - 1); - - if (rt_device_read(iso->dev, pos, iso->swap, 1) <= 0) - { - return -EIO; - } - - size = rt_min_t(size_t, ISO9660_BLKSZ - remain, count); - rt_memcpy(buf, &iso->swap[remain], size); - rcount += size; - count -= size; - buf += size; - pos += 1; - fd->pos += size; - - if (!count) - { - goto _end; - } - } - - remain = count & (ISO9660_BLKSZ - 1); - count = rt_max_t(size_t, count / ISO9660_BLKSZ, 1); - - while ((ssize_t)count > 0) - { - if (count == 1) - { - buf_ptr = iso->swap; - toread_blk = 1; - } - else - { - buf_ptr = buf; - toread_blk = count; - } - - read_blk = rt_device_read(iso->dev, pos, buf_ptr, toread_blk); - - if (read_blk <= 0) - { - return (int)read_blk; - } - - if (count == 1) - { - size = remain; - rt_memcpy(buf, iso->swap, size); - } - else - { - size = read_blk * ISO9660_BLKSZ; - } - - rcount += size; - count -= read_blk; - buf += size; - pos += read_blk; - fd->pos += size; - } - -_end: - return rcount; -} - -static off_t dfs_iso9660_lseek(struct dfs_file *fd, off_t offset) -{ - int ret = -EIO; - - if (offset <= fd->vnode->size) - { - fd->pos = offset; - ret = fd->pos; - } - - return ret; -} - -static int dfs_iso9660_getdents(struct dfs_file *fd, struct dirent *dirp, uint32_t count) -{ - struct iso9660_iterate it; - struct iso9660_fd *iso_fd = fd->vnode->data; - - count = (count / sizeof(struct dirent)); - - if (!count) - { - return -EINVAL; - } - - it.fd = iso_fd; - it.i = 0; - it.index = fd->pos; - it.count = count; - it.dirp = dirp; - - iso9660_lookup(RT_NULL, RT_NULL, &it); - - count = it.i - it.index; - if (count > 0) - { - fd->pos += count; - } - - count *= sizeof(struct dirent); - - return count; -} - -static const struct dfs_file_ops _iso9660_fops = -{ - .open = dfs_iso9660_open, - .close = dfs_iso9660_close, - .read = dfs_iso9660_read, - .lseek = dfs_iso9660_lseek, - .getdents = dfs_iso9660_getdents, -}; - -static int dfs_iso9660_mount(struct dfs_filesystem *fs, - unsigned long rwflag, const void *data) -{ - int err; - struct iso9660 *iso; - struct iso9660_voldesc *voldesc; - struct rt_device_blk_geometry geometry; - - if (!(iso = rt_malloc(sizeof(*iso)))) - { - return -RT_ENOMEM; - } - - iso->dev = fs->dev_id; - rt_device_control(iso->dev, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry); - - if (geometry.bytes_per_sector != ISO9660_BLKSZ) - { - LOG_E("%s: Logical block size = %d is not supported", - iso->dev->parent.name, geometry.bytes_per_sector); - - err = -EINVAL; - goto _fail; - } - - iso->primary.rootdir.first_sector = 0; - iso->supp.rootdir.first_sector = 0; - - /* LBA 0-15 is the bootloader's information */ - for (int lba = 16; ; ++lba) - { - if (rt_device_read(iso->dev, lba, &iso->swap, 1) <= 0) - { - err = -EIO; - goto _fail; - } - - voldesc = (void *)iso->swap; - - if (rt_strncmp((char *)voldesc->magic, "CD001", 5)) - { - LOG_E("%s: Invalid magic \"%s\"", voldesc->magic); - - err = -EINVAL; - goto _fail; - } - - if (voldesc->type == ISO9660_VOLDESC_BOOT) - { - LOG_D("System Name: %s", ((struct iso9660_common_voldesc *)voldesc)->sysname); - LOG_D("Volume Name: %s", ((struct iso9660_common_voldesc *)voldesc)->volname); - } - else if (voldesc->type == ISO9660_VOLDESC_PRIMARY) - { - iso->joliet = 0; - rt_memcpy(&iso->primary, &iso->swap, sizeof(iso->primary)); - } - else if (voldesc->type == ISO9660_VOLDESC_SUPP) - { - rt_memcpy(&iso->supp, &iso->swap, sizeof(iso->supp)); - - if (iso->supp.escape[0] == 0x25 && iso->supp.escape[1] == 0x2f) - { - if (iso->supp.escape[2] == 0x40) - { - iso->joliet = 1; - } - else if (iso->supp.escape[2] == 0x43) - { - iso->joliet = 2; - } - else if (iso->supp.escape[2] == 0x45) - { - iso->joliet = 3; - } - else - { - continue; - } - } - } - else if (voldesc->type == ISO9660_VOLDESC_PART) - { - LOG_D("System Name: %s", ((struct iso9660_common_voldesc *)voldesc)->sysname); - LOG_D("Volume Name: %s", ((struct iso9660_common_voldesc *)voldesc)->volname); - } - else if (voldesc->type == ISO9660_VOLDESC_END) - { - break; - } - } - - if (!iso->primary.rootdir.first_sector || !iso->supp.rootdir.first_sector) - { - LOG_E("No primary or secondary partition found"); - - err = -EINVAL; - goto _fail; - } - - fs->data = iso; - - return 0; - -_fail: - rt_free(iso); - - return err; -} - -static int dfs_iso9660_unmount(struct dfs_filesystem *fs) -{ - struct iso9660 *iso = fs->data; - - rt_free(iso); - - return 0; -} - -static int dfs_iso9660_stat(struct dfs_filesystem *fs, - const char *filename, struct stat *st) -{ - struct iso9660 *iso = fs->data; - struct iso9660_fd *fd = iso9660_lookup(iso, filename, RT_NULL); - - if (!fd) - { - return -EINVAL; - } - - st->st_dev = 0; - st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | - S_IWUSR | S_IWGRP | S_IWOTH; - - if ((fd->dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR) - { - st->st_mode &= ~S_IFREG; - st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - } - - st->st_atime = iso9660_convert_unixtime(iso->joliet ? - &iso->supp.created : &iso->primary.created); - st->st_mtime = iso9660_convert_unixtime2(&fd->dirent.mtime); - st->st_size = rt_le32_to_cpu(fd->dirent.size); - - rt_free(fd); - - return 0; -} - -static const struct dfs_filesystem_ops _iso9660 = -{ - .name = "iso9660", - .flags = DFS_FS_FLAG_DEFAULT, - .fops = &_iso9660_fops, - - .mount = dfs_iso9660_mount, - .unmount = dfs_iso9660_unmount, - - .stat = dfs_iso9660_stat, -}; - -int dfs_iso9660_init(void) -{ - /* register iso9660 file system */ - return dfs_register(&_iso9660); -} -INIT_COMPONENT_EXPORT(dfs_iso9660_init); diff --git a/rt-thread/components/dfs/dfs_v1/filesystems/iso9660/dfs_iso9660.h b/rt-thread/components/dfs/dfs_v1/filesystems/iso9660/dfs_iso9660.h deleted file mode 100644 index d4e524e..0000000 --- a/rt-thread/components/dfs/dfs_v1/filesystems/iso9660/dfs_iso9660.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#ifndef __DFS_ISO9660_H__ -#define __DFS_ISO9660_H__ - -int dfs_iso9660_init(void); - -#endif /* __DFS_ISO9660_H__ */ diff --git a/rt-thread/components/dfs/dfs_v1/filesystems/ramfs/dfs_ramfs.c b/rt-thread/components/dfs/dfs_v1/filesystems/ramfs/dfs_ramfs.c index 92807a2..fd7326b 100644 --- a/rt-thread/components/dfs/dfs_v1/filesystems/ramfs/dfs_ramfs.c +++ b/rt-thread/components/dfs/dfs_v1/filesystems/ramfs/dfs_ramfs.c @@ -92,7 +92,7 @@ struct ramfs_dirent *dfs_ramfs_lookup(struct dfs_ramfs *ramfs, return NULL; } -ssize_t dfs_ramfs_read(struct dfs_file *file, void *buf, size_t count) +int dfs_ramfs_read(struct dfs_file *file, void *buf, size_t count) { rt_size_t length; struct ramfs_dirent *dirent; @@ -114,7 +114,7 @@ ssize_t dfs_ramfs_read(struct dfs_file *file, void *buf, size_t count) return length; } -ssize_t dfs_ramfs_write(struct dfs_file *fd, const void *buf, size_t count) +int dfs_ramfs_write(struct dfs_file *fd, const void *buf, size_t count) { struct ramfs_dirent *dirent; struct dfs_ramfs *ramfs; @@ -151,7 +151,7 @@ ssize_t dfs_ramfs_write(struct dfs_file *fd, const void *buf, size_t count) return count; } -off_t dfs_ramfs_lseek(struct dfs_file *file, off_t offset) +int dfs_ramfs_lseek(struct dfs_file *file, off_t offset) { if (offset <= (off_t)file->vnode->size) { diff --git a/rt-thread/components/dfs/dfs_v1/src/dfs.c b/rt-thread/components/dfs/dfs_v1/src/dfs.c index fdaf93d..8d2e9b1 100644 --- a/rt-thread/components/dfs/dfs_v1/src/dfs.c +++ b/rt-thread/components/dfs/dfs_v1/src/dfs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -107,8 +107,7 @@ int dfs_init(void) INIT_PREV_EXPORT(dfs_init); /** - * @brief this function will lock device file system. - * this lock (fslock) is used for protecting filesystem_operation_table and filesystem_table. + * this function will lock device file system. * * @note please don't invoke it on ISR. */ @@ -127,12 +126,6 @@ void dfs_lock(void) } } -/** - * @brief this function will lock file descriptors. - * this lock (fdlock) is used for protecting fd table (_fdtab). - * - * @note please don't invoke it on ISR. - */ void dfs_file_lock(void) { rt_err_t result = -RT_EBUSY; @@ -149,7 +142,7 @@ void dfs_file_lock(void) } /** - * @brief this function will unlock device file system. + * this function will lock device file system. * * @note please don't invoke it on ISR. */ @@ -158,56 +151,33 @@ void dfs_unlock(void) rt_mutex_release(&fslock); } -/** - * @brief this function will unlock fd table. - */ +#ifdef DFS_USING_POSIX + void dfs_file_unlock(void) { rt_mutex_release(&fdlock); } -#ifdef DFS_USING_POSIX -/** - * @brief Expand the file descriptor table to accommodate a specific file descriptor. - * - * This function ensures that the file descriptor table in the given `dfs_fdtable` structure - * has sufficient capacity to include the specified file descriptor `fd`. If the table - * needs to be expanded, it reallocates memory and initializes new slots to `NULL`. - * - * @param fdt Pointer to the `dfs_fdtable` structure representing the file descriptor table. - * @param fd The file descriptor that the table must accommodate. - * @return int - * - The input file descriptor `fd` if it is within the current or newly expanded table's capacity. - * - `-1` if the requested file descriptor exceeds `DFS_FD_MAX` or memory allocation fails. - */ static int fd_slot_expand(struct dfs_fdtable *fdt, int fd) { int nr; int index; struct dfs_file **fds = NULL; - /* If the file descriptor is already within the current capacity, no expansion is needed.*/ if (fd < fdt->maxfd) { return fd; } - - /* If the file descriptor exceeds the maximum allowable limit, return an error.*/ if (fd >= DFS_FD_MAX) { return -1; } - /* Calculate the new capacity, rounding up to the nearest multiple of 4.*/ nr = ((fd + 4) & ~3); - - /* Ensure the new capacity does not exceed the maximum limit.*/ if (nr > DFS_FD_MAX) { nr = DFS_FD_MAX; } - - /* Attempt to reallocate the file descriptor table to the new capacity.*/ fds = (struct dfs_file **)rt_realloc(fdt->fds, nr * sizeof(struct dfs_file *)); if (!fds) { @@ -219,23 +189,12 @@ static int fd_slot_expand(struct dfs_fdtable *fdt, int fd) { fds[index] = NULL; } - - /* Update the file descriptor table and its capacity.*/ fdt->fds = fds; fdt->maxfd = nr; return fd; } -/** - * @brief Allocate a file descriptor slot starting from a specified index. - * - * @param fdt fdt Pointer to the `dfs_fdtable` structure representing the file descriptor table. - * @param startfd The starting index for the search for an empty slot. - * @return int - * - The index of the first available slot if successful. - * - `-1` if no slot is available or if table expansion fails - */ static int fd_slot_alloc(struct dfs_fdtable *fdt, int startfd) { int idx; @@ -260,17 +219,6 @@ static int fd_slot_alloc(struct dfs_fdtable *fdt, int startfd) } return idx; } - -/** - * @brief Allocate a new file descriptor and associate it with a newly allocated `struct dfs_file`. - * - * @param fdt Pointer to the `dfs_fdtable` structure representing the file descriptor table. - * @param startfd The starting index for searching an available file descriptor slot. - * - * @return - * - The index of the allocated file descriptor if successful. - * - `-1` if no slot is available or memory allocation fails. - */ static int fd_alloc(struct dfs_fdtable *fdt, int startfd) { int idx; @@ -375,11 +323,7 @@ struct dfs_file *fd_get(int fd) /** * @ingroup Fd * - * @brief This function will release the file descriptor. - * - * This function releases a file descriptor slot in the file descriptor table, decrements reference - * counts, and cleans up resources associated with the `dfs_file` and `dfs_vnode` structures when applicable. - * + * This function will put the file descriptor. */ void fdt_fd_release(struct dfs_fdtable* fdt, int fd) { @@ -434,20 +378,6 @@ void fd_release(int fd) fdt_fd_release(fdt, fd); } -/** - * @brief Duplicates a file descriptor. - * - * This function duplicates an existing file descriptor (`oldfd`) and returns - * a new file descriptor that refers to the same underlying file object. - * - * @param oldfd The file descriptor to duplicate. It must be a valid file - * descriptor within the range of allocated descriptors. - * - * @return The new file descriptor if successful, or a negative value - * (e.g., -1) if an error occurs. - * - * @see sys_dup2() - */ rt_err_t sys_dup(int oldfd) { int newfd = -1; @@ -540,23 +470,6 @@ int fd_is_open(const char *pathname) return -1; } -/** - * @brief Duplicates a file descriptor to a specified file descriptor. - * - * This function duplicates an existing file descriptor (`oldfd`) and assigns it - * to the specified file descriptor (`newfd`). - * - * @param oldfd The file descriptor to duplicate. It must be a valid and open file - * descriptor within the range of allocated descriptors. - * @param newfd The target file descriptor. If `newfd` is already in use, it will - * be closed before duplication. If `newfd` exceeds the current file - * descriptor table size, the table will be expanded to accommodate it. - * - * @return The value of `newfd` on success, or a negative value (e.g., -1) if an - * error occurs. - * - * @see sys_dup() - */ rt_err_t sys_dup2(int oldfd, int newfd) { struct dfs_fdtable *fdt = NULL; @@ -637,10 +550,6 @@ static int fd_get_fd_index_form_fdt(struct dfs_fdtable *fdt, struct dfs_file *fi return fd; } -/** - * @brief get fd (index) by dfs file object. - * - */ int fd_get_fd_index(struct dfs_file *file) { struct dfs_fdtable *fdt; @@ -649,21 +558,6 @@ int fd_get_fd_index(struct dfs_file *file) return fd_get_fd_index_form_fdt(fdt, file); } -/** - * @brief Associates a file descriptor with a file object. - * - * This function associates a given file descriptor (`fd`) with a specified - * file object (`file`) in the file descriptor table (`fdt`). - * - * @param fdt The file descriptor table to operate on. It must be a valid - * and initialized `dfs_fdtable` structure. - * @param fd The file descriptor to associate. It must be within the range - * of allocated file descriptors and currently unoccupied. - * @param file The file object to associate with the file descriptor. It must - * be a valid and initialized `dfs_file` structure. - * - * @return The value of `fd` on success, or -1 if an error occurs. - */ int fd_associate(struct dfs_fdtable *fdt, int fd, struct dfs_file *file) { int retfd = -1; @@ -697,10 +591,6 @@ exit: return retfd; } -/** - * @brief initialize a dfs file object. - * - */ void fd_init(struct dfs_file *fd) { if (fd) diff --git a/rt-thread/components/dfs/dfs_v1/src/dfs_file.c b/rt-thread/components/dfs/dfs_v1/src/dfs_file.c index be5747a..acdc124 100644 --- a/rt-thread/components/dfs/dfs_v1/src/dfs_file.c +++ b/rt-thread/components/dfs/dfs_v1/src/dfs_file.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -18,12 +18,10 @@ #define DFS_VNODE_HASH_NR 128 -/*dfs vnode manager, for saving and searching vnodes.*/ struct dfs_vnode_mgr { - struct rt_mutex lock; /* mutex for protecting dfs vnode lists */ - rt_list_t head[DFS_VNODE_HASH_NR]; /* a group of dfs vnode lists, the dfs vnode is inserted to one of the lists - according to path string's hash-value mod DFS_VNODE_HASH_NR. */ + struct rt_mutex lock; + rt_list_t head[DFS_VNODE_HASH_NR]; }; static struct dfs_vnode_mgr dfs_fm; @@ -38,10 +36,6 @@ void dfs_fm_unlock(void) rt_mutex_release(&dfs_fm.lock); } -/** - * @brief Initialize dfs vnode manager structure, including a lock and hash tables for vnode. - * - */ void dfs_vnode_mgr_init(void) { int i = 0; @@ -53,23 +47,6 @@ void dfs_vnode_mgr_init(void) } } -/** - * @brief Initialize a DFS vnode structure. - * - * @param vnode Pointer to the DFS vnode structure to be initialized. - * The caller must ensure this is a valid, allocated structure. - * @param type The type of the vnode, representing its role or category (e.g., regular file, directory). - * @param fops Pointer to the file operations structure associated with this vnode. - * This structure defines the behavior of the vnode for operations such as open, read, write, etc. - * If `fops` is NULL, the vnode will have no associated file operations. - * - * @return 0 on success, or a negative error code on failure. - * - * @note The caller should ensure that: - * - The `vnode` pointer is valid and properly allocated. - * - The `fops` pointer (if not NULL) points to a valid `struct dfs_file_ops` - * instance, where all necessary function pointers are properly set. - */ int dfs_vnode_init(struct dfs_vnode *vnode, int type, const struct dfs_file_ops *fops) { if (vnode) @@ -87,7 +64,7 @@ int dfs_vnode_init(struct dfs_vnode *vnode, int type, const struct dfs_file_ops /* BKDR Hash Function */ static unsigned int bkdr_hash(const char *str) { - unsigned int seed = 131; /* 31 131 1313 13131 131313 etc..*/ + unsigned int seed = 131; // 31 131 1313 13131 131313 etc.. unsigned int hash = 0; while (*str) @@ -98,22 +75,6 @@ static unsigned int bkdr_hash(const char *str) return (hash % DFS_VNODE_HASH_NR); } -/** - * @brief Find a DFS vnode by its path. - * - * This function searches for a vnode in the vnode hash table using the specified path. - * If found, it returns a pointer to the vnode and updates the hash head if required. - * - * @param path The file path to search for. This should be a valid null-terminated string. - * @param hash_head Pointer to a location where the hash table head associated with the vnode - * can be stored. This can be NULL if the hash head is not needed. - * - * @return Pointer to the DFS vnode if found, or NULL if no vnode matches the specified path. - * - * @note The caller must ensure that: - * - The `path` pointer is valid and points to a properly null-terminated string. - * - If `hash_head` is not NULL, it points to a valid location to store the hash head. - */ static struct dfs_vnode *dfs_vnode_find(const char *path, rt_list_t **hash_head) { struct dfs_vnode *vnode = NULL; @@ -368,12 +329,11 @@ int dfs_file_close(struct dfs_file *fd) } /** - * this function will perform an io control on a file descriptor. + * this function will perform a io control on a file descriptor. * * @param fd the file descriptor. * @param cmd the command to send to file descriptor. * @param args the argument to send to file descriptor. - * - When `cmd` is `F_SETFL`, an additional integer argument specifies the new status flags. * * @return 0 on successful, -1 on failed. */ @@ -886,7 +846,7 @@ void cat(const char *filename) { buffer[length] = '\0'; rt_device_t out_device = rt_console_get_device(); - rt_device_write(out_device, 0, (void *)buffer, length); + rt_device_write(out_device, 0, (void *)buffer, sizeof(buffer)); } } while (length > 0); rt_kprintf("\n"); @@ -1066,14 +1026,14 @@ void copy(const char *src, const char *dst) flag |= FLAG_DST_IS_FILE; } - /*2. check status*/ + //2. check status if ((flag & FLAG_SRC_IS_DIR) && (flag & FLAG_DST_IS_FILE)) { rt_kprintf("cp faild, cp dir to file is not permitted!\n"); return ; } - /*3. do copy*/ + //3. do copy if (flag & FLAG_SRC_IS_FILE) { if (flag & FLAG_DST_IS_DIR) @@ -1093,7 +1053,7 @@ void copy(const char *src, const char *dst) copyfile(src, dst); } } - else /*flag & FLAG_SRC_IS_DIR*/ + else //flag & FLAG_SRC_IS_DIR { if (flag & FLAG_DST_IS_DIR) { diff --git a/rt-thread/components/dfs/dfs_v1/src/dfs_fs.c b/rt-thread/components/dfs/dfs_v1/src/dfs_fs.c index 3d35c5f..4240736 100644 --- a/rt-thread/components/dfs/dfs_v1/src/dfs_fs.c +++ b/rt-thread/components/dfs/dfs_v1/src/dfs_fs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -322,8 +322,8 @@ int dfs_mount(const char *device_name, /* open device, but do not check the status of device */ if (dev_id != NULL) { - if (rt_device_open(fs->dev_id, RT_DEVICE_OFLAG_RDWR) != RT_EOK && - rt_device_open(fs->dev_id, RT_DEVICE_OFLAG_RDONLY) != RT_EOK) + if (rt_device_open(fs->dev_id, + RT_DEVICE_OFLAG_RDWR) != RT_EOK) { /* The underlying device has error, clear the entry. */ dfs_lock(); @@ -529,8 +529,7 @@ int dfs_mount_device(rt_device_t dev) { int index = 0; - if(dev == RT_NULL) - { + if(dev == RT_NULL) { rt_kprintf("the device is NULL to be mounted.\n"); return -RT_ERROR; } @@ -539,8 +538,7 @@ int dfs_mount_device(rt_device_t dev) { if (mount_table[index].path == NULL) break; - if(strcmp(mount_table[index].device_name, dev->parent.name) == 0) - { + if(strcmp(mount_table[index].device_name, dev->parent.name) == 0) { if (dfs_mount(mount_table[index].device_name, mount_table[index].path, mount_table[index].filesystemtype, diff --git a/rt-thread/components/dfs/dfs_v1/src/dfs_posix.c b/rt-thread/components/dfs/dfs_v1/src/dfs_posix.c index d4ac04a..07276a8 100644 --- a/rt-thread/components/dfs/dfs_v1/src/dfs_posix.c +++ b/rt-thread/components/dfs/dfs_v1/src/dfs_posix.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -28,17 +28,7 @@ * return a file descriptor according specified flags. * * @param file the path name of file. - * @param flags the file open flags. Common values include: - * - Access modes (mutually exclusive): - * - `O_RDONLY`: Open for read-only access. - * - `O_WRONLY`: Open for write-only access. - * - `O_RDWR`: Open for both reading and writing. - * - File status flags (can be combined with bitwise OR `|`): - * - `O_CREAT`: Create the file if it does not exist. Requires a `mode` argument. - * - `O_TRUNC`: Truncate the file to zero length if it already exists. - * - `O_APPEND`: Append writes to the end of the file. - * - `O_EXCL`: Ensure that `O_CREAT` creates the file exclusively. - * - Other platform-specific flags + * @param flags the file open flags. * * @return the non-negative integer on successful open, others for failed. */ @@ -75,22 +65,6 @@ RTM_EXPORT(open); #ifndef AT_FDCWD #define AT_FDCWD (-100) #endif - -/** - * @brief Opens a file relative to a directory file descriptor. - * - * @param dirfd The file descriptor of the directory to base the relative path on. - * @param pathname The path to the file to be opened, relative to the directory specified by `dirfd`. - * Can be an absolute path (in which case `dirfd` is ignored). - * @param flags File access and status flags (e.g., `O_RDONLY`, `O_WRONLY`, `O_CREAT`). - * - * @return On success, returns a new file descriptor for the opened file. - * On failure, returns `-1` and sets `errno` to indicate the error. - * - * @note When using relative paths, ensure `dirfd` is a valid directory descriptor. - * When `pathname` is absolute, the `dirfd` argument is ignored. - * - */ int openat(int dirfd, const char *path, int flag, ...) { struct dfs_file *d; @@ -267,22 +241,14 @@ ssize_t write(int fd, const void *buf, size_t len) RTM_EXPORT(write); /** - * this function is a POSIX compliant version, which will Reposition the file offset for + * this function is a POSIX compliant version, which will seek the offset for * an open file descriptor. * - * The `lseek` function sets the file offset for the file descriptor `fd` - * to a new value, determined by the `offset` and `whence` parameters. - * It can be used to seek to specific positions in a file for reading or writing. - * * @param fd the file descriptor. - * @param offset The offset, in bytes, to set the file position. - * The meaning of `offset` depends on the value of `whence`. - * @param whence the directive of seek. It can be one of: - * - `SEEK_SET`: Set the offset to `offset` bytes from the beginning of the file. - * - `SEEK_CUR`: Set the offset to its current location plus `offset` bytes. - * - `SEEK_END`: Set the offset to the size of the file plus `offset` bytes. + * @param offset the offset to be seeked. + * @param whence the directory of seek. * - * @return the resulting read/write position in the file, or -1 on failed. + * @return the current read/write position in the file, or -1 on failed. */ off_t lseek(int fd, off_t offset, int whence) { @@ -470,15 +436,9 @@ RTM_EXPORT(fsync); * control functions on devices. * * @param fildes the file description - * @param cmd the specified command, Common values include: - * - `F_DUPFD`: Duplicate a file descriptor. - * - `F_GETFD`: Get the file descriptor flags. - * - `F_SETFD`: Set the file descriptor flags. - * - `F_GETFL`: Get the file status flags. - * - `F_SETFL`: Set the file status flags. + * @param cmd the specified command * @param ... represents the additional information that is needed by this - * specific device to perform the requested function. For example: - * - When `cmd` is `F_SETFL`, an additional integer argument specifies the new status flags. + * specific device to perform the requested function. * * @return 0 on successful completion. Otherwise, -1 shall be returned and errno * set to indicate the error. @@ -635,7 +595,7 @@ RTM_EXPORT(fstatfs); * this function is a POSIX compliant version, which will make a directory * * @param path the directory path to be made. - * @param mode The permission mode for the new directory (unused here, can be set to 0). + * @param mode * * @return 0 on successful, others on failed. */ diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.c b/rt-thread/components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.c index ae67887..0d82914 100644 --- a/rt-thread/components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.c +++ b/rt-thread/components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.c @@ -786,18 +786,18 @@ static ssize_t dfs_cromfs_read(struct dfs_file *file, void *buf, size_t count, o rt_err_t result = RT_EOK; file_info *fi = NULL; cromfs_info *ci = NULL; - ssize_t length = 0; + uint32_t length = 0; ci = (cromfs_info *)file->dentry->mnt->data; fi = (file_info *)file->vnode->data; - if ((off_t)count < (off_t)file->vnode->size - *pos) + if (count < file->vnode->size - *pos) { length = count; } else { - length = (off_t)file->vnode->size - *pos; + length = file->vnode->size - *pos; } if (length > 0) diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.h b/rt-thread/components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.h index a22bd5e..97339bc 100644 --- a/rt-thread/components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.h +++ b/rt-thread/components/dfs/dfs_v2/filesystems/cromfs/dfs_cromfs.h @@ -11,9 +11,6 @@ #ifndef __DFS_CROMFS_H__ #define __DFS_CROMFS_H__ -#include - int dfs_cromfs_init(void); -uint8_t *cromfs_get_partition_data(uint32_t *len); #endif /*__DFS_CROMFS_H__*/ diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/devfs/devfs.c b/rt-thread/components/dfs/dfs_v2/filesystems/devfs/devfs.c index 38e9a2e..6db468f 100644 --- a/rt-thread/components/dfs/dfs_v2/filesystems/devfs/devfs.c +++ b/rt-thread/components/dfs/dfs_v2/filesystems/devfs/devfs.c @@ -77,7 +77,6 @@ static int dfs_devfs_open(struct dfs_file *file) } } } - rt_free(device_name); } return ret; @@ -114,29 +113,6 @@ static int dfs_devfs_close(struct dfs_file *file) return ret; } -static rt_ubase_t _get_unit_shift(rt_device_t device) -{ - rt_ubase_t shift = 0; - - /** - * transfer unit size from POSIX RW(in bytes) to rt_device_R/W - * (block size for blk device, otherwise in bytes). - */ - if (device->type == RT_Device_Class_Block) - { - struct rt_device_blk_geometry geometry = {0}; - - /* default to 512 */ - shift = 9; - if (!rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry)) - { - shift = __rt_ffs(geometry.block_size) - 1; - } - } - - return shift; -} - static ssize_t dfs_devfs_read(struct dfs_file *file, void *buf, size_t count, off_t *pos) { ssize_t ret = -RT_EIO; @@ -159,14 +135,9 @@ static ssize_t dfs_devfs_read(struct dfs_file *file, void *buf, size_t count, of if (device->ops) #endif /* RT_USING_POSIX_DEVIO */ { - rt_ubase_t shift = _get_unit_shift(device); - - ret = rt_device_read(device, *pos, buf, count >> shift); - if (ret > 0) - { - ret <<= shift; - *pos += ret; - } + /* read device data */ + ret = rt_device_read(device, *pos, buf, count); + *pos += ret; } } @@ -198,15 +169,9 @@ static ssize_t dfs_devfs_write(struct dfs_file *file, const void *buf, size_t co if (device->ops) #endif /* RT_USING_POSIX_DEVIO */ { - rt_ubase_t shift = _get_unit_shift(device); - /* read device data */ - ret = rt_device_write(device, *pos, buf, count >> shift); - if (ret > 0) - { - ret <<= shift; - *pos += ret; - } + ret = rt_device_write(device, *pos, buf, count); + *pos += ret; } } @@ -300,7 +265,7 @@ static int dfs_devfs_flush(struct dfs_file *file) static off_t dfs_devfs_lseek(struct dfs_file *file, off_t offset, int wherece) { - off_t ret = -EPERM; + off_t ret = 0; rt_device_t device; RT_ASSERT(file != RT_NULL); @@ -443,16 +408,16 @@ mode_t dfs_devfs_device_to_mode(struct rt_device *device) switch (device->type) { case RT_Device_Class_Char: - mode = S_IFCHR | 0666; + mode = S_IFCHR | 0777; break; case RT_Device_Class_Block: - mode = S_IFBLK | 0666; + mode = S_IFBLK | 0777; break; case RT_Device_Class_Pipe: - mode = S_IFIFO | 0666; + mode = S_IFIFO | 0777; break; default: - mode = S_IFCHR | 0666; + mode = S_IFCHR | 0777; break; } diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/devfs/devtmpfs.c b/rt-thread/components/dfs/dfs_v2/filesystems/devfs/devtmpfs.c index 82ab422..3bea0c1 100644 --- a/rt-thread/components/dfs/dfs_v2/filesystems/devfs/devtmpfs.c +++ b/rt-thread/components/dfs/dfs_v2/filesystems/devfs/devtmpfs.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -35,9 +34,10 @@ struct devtmpfs_file char name[DIRENT_NAME_MAX]; /* file name */ rt_uint32_t type; /* file type */ - struct dfs_vfs_node node; /* file node in the devtmpfs */ + rt_list_t subdirs; /* file subdir list */ + rt_list_t sibling; /* file sibling list */ - struct devtmpfs_sb *sb; /* superblock ptr */ + struct devtmpfs_sb *sb; /* superblock ptr */ rt_uint32_t mode; char *link; @@ -48,6 +48,7 @@ struct devtmpfs_sb rt_uint32_t magic; /* TMPFS_MAGIC */ struct devtmpfs_file root; /* root dir */ rt_size_t df_size; /* df size */ + rt_list_t sibling; /* sb sibling list */ struct rt_spinlock lock; /* tmpfs lock */ }; @@ -110,13 +111,15 @@ static int _get_subdir(const char *path, char *name) #if 0 static int _free_subdir(struct devtmpfs_file *dfile) { - struct devtmpfs_file *file, *tmp; + struct devtmpfs_file *file; + rt_list_t *list, *temp_list; struct devtmpfs_sb *superblock; RT_ASSERT(dfile->type == TMPFS_TYPE_DIR); - dfs_vfs_for_each_subnode(file, tmp, dfile, node) + rt_list_for_each_safe(list, temp_list, &dfile->subdirs) { + file = rt_list_entry(list, struct devtmpfs_file, sibling); if (file->type == TMPFS_TYPE_DIR) { _free_subdir(file); @@ -131,7 +134,7 @@ static int _free_subdir(struct devtmpfs_file *dfile) RT_ASSERT(superblock); rt_spin_lock(&superblock->lock); - dfs_vfs_remove_node(&file->node); + rt_list_remove(&(file->sibling)); rt_spin_unlock(&superblock->lock); rt_free(file); @@ -149,12 +152,14 @@ static int devtmpfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void { superblock->df_size = sizeof(struct devtmpfs_sb); superblock->magic = TMPFS_MAGIC; + rt_list_init(&superblock->sibling); superblock->root.name[0] = '/'; superblock->root.sb = superblock; superblock->root.type = TMPFS_TYPE_DIR; superblock->root.mode = S_IFDIR | (S_IRUSR | S_IRGRP | S_IROTH) | (S_IXUSR | S_IXGRP | S_IXOTH); - dfs_vfs_init_node(&superblock->root.node); + rt_list_init(&superblock->root.sibling); + rt_list_init(&superblock->root.subdirs); rt_spin_lock_init(&superblock->lock); @@ -188,7 +193,8 @@ static struct devtmpfs_file *devtmpfs_file_lookup(struct devtmpfs_sb *superblock { const char *subpath, *curpath, *filename = RT_NULL; char subdir_name[DIRENT_NAME_MAX]; - struct devtmpfs_file *file, *curfile, *tmp; + struct devtmpfs_file *file, *curfile; + rt_list_t *list; subpath = path; while (*subpath == '/' && *subpath) @@ -216,8 +222,9 @@ find_subpath: rt_spin_lock(&superblock->lock); - dfs_vfs_for_each_subnode(file, tmp, curfile, node) + rt_list_for_each(list, &curfile->subdirs) { + file = rt_list_entry(list, struct devtmpfs_file, sibling); if (filename) /* find file */ { if (rt_strcmp(file->name, filename) == 0) @@ -286,9 +293,7 @@ static int devtmpfs_stat(struct dfs_dentry *dentry, struct stat *st) static int devtmpfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count) { - rt_size_t index, end; - struct dirent *d; - struct devtmpfs_file *d_file, *n_file = RT_NULL, *tmp; + struct devtmpfs_file *d_file; struct devtmpfs_sb *superblock; RT_ASSERT(file); @@ -301,6 +306,11 @@ static int devtmpfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_ d_file = devtmpfs_file_lookup(superblock, file->dentry->pathname); if (d_file) { + rt_size_t index, end; + struct dirent *d; + struct devtmpfs_file *n_file; + rt_list_t *list; + /* make integer count */ count = (count / sizeof(struct dirent)); if (count == 0) @@ -312,10 +322,12 @@ static int devtmpfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_ index = 0; count = 0; - dfs_vfs_for_each_subnode(n_file, tmp, d_file, node) + rt_list_for_each(list, &d_file->subdirs) { if (index >= (rt_size_t)file->fpos) { + n_file = rt_list_entry(list, struct devtmpfs_file, sibling); + d = dirp + count; if (n_file->type == TMPFS_TYPE_FILE) { @@ -366,7 +378,8 @@ static int devtmpfs_symlink(struct dfs_dentry *parent_dentry, const char *target strncpy(l_file->name, linkpath, DIRENT_NAME_MAX - 1); - dfs_vfs_init_node(&l_file->node); + rt_list_init(&(l_file->subdirs)); + rt_list_init(&(l_file->sibling)); l_file->sb = superblock; l_file->type = TMPFS_TYPE_FILE; l_file->mode = p_file->mode; @@ -375,7 +388,7 @@ static int devtmpfs_symlink(struct dfs_dentry *parent_dentry, const char *target l_file->link = rt_strdup(target); rt_spin_lock(&superblock->lock); - dfs_vfs_append_node(&p_file->node, &l_file->node); + rt_list_insert_after(&(p_file->subdirs), &(l_file->sibling)); rt_spin_unlock(&superblock->lock); } } @@ -447,7 +460,7 @@ static int devtmpfs_unlink(struct dfs_dentry *dentry) } rt_spin_lock(&superblock->lock); - dfs_vfs_remove_node(&d_file->node); + rt_list_remove(&(d_file->sibling)); rt_spin_unlock(&superblock->lock); rt_free(d_file); @@ -524,7 +537,8 @@ static struct dfs_vnode *devtmpfs_create_vnode(struct dfs_dentry *dentry, int ty strncpy(d_file->name, file_name, DIRENT_NAME_MAX); - dfs_vfs_init_node(&d_file->node); + rt_list_init(&(d_file->subdirs)); + rt_list_init(&(d_file->sibling)); d_file->sb = superblock; vnode->nlink = 1; @@ -549,7 +563,7 @@ static struct dfs_vnode *devtmpfs_create_vnode(struct dfs_dentry *dentry, int ty d_file->mode = vnode->mode; rt_spin_lock(&superblock->lock); - dfs_vfs_append_node(&p_file->node, &d_file->node); + rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling)); rt_spin_unlock(&superblock->lock); } diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/README.md b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/README.md deleted file mode 100644 index 7ab0127..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/README.md +++ /dev/null @@ -1,166 +0,0 @@ -# 进程文件系统 (procfs) - -## 数据结构 - -```c -struct proc_dentry -{ - rt_uint32_t mode; - rt_atomic_t ref_count; - - struct proc_dentry *parent; - struct dfs_vfs_node node; - - const struct dfs_file_ops *fops; - const struct proc_ops *ops; - - char *name; - void *data; -}; -``` - -```log -root { mode: S_IFDIR, ref_count: 1, parent: root, name: /, child->next: file1->node } - | - |—— file1 { mode: S_IFREG, ref_count: 1, parent: root, name: file1, node->next: link1->node } - |—— link1 { mode: S_IFLNK, ref_count: 1, parent: root, name: link1, data: fullpath, node->next: dir1->node } - |—— dir1 { mode: S_IFDIR, ref_count: 1, parent: root, name: dir1, node->next: file3->node, child->next: file2->node } - | | - | |—— dir2 { mode: S_IFDIR, ref_count: 1, parent: dir1, name: dir2, node->next: link2->node } - | |—— link2 { mode: S_IFLNK, ref_count: 1, parent: dir1, name: link2, data: fullpath, node->next: file2->node } - | |—— file2 { mode: S_IFREG, ref_count: 1, parent: dir1, name: file2 } - | - |—— file3 { mode: S_IFREG, ref_count: 1, parent: root, name: file3 } -``` - -## API 介绍 - -```c -struct proc_dentry *dfs_proc_find(const char *name); - -struct proc_dentry *proc_mkdir_data(const char *name, mode_t mode, struct proc_dentry *parent, - const struct dfs_file_ops *fops, void *data); -struct proc_dentry *proc_mkdir_mode(const char *name, mode_t mode, struct proc_dentry *parent); -struct proc_dentry *proc_mkdir(const char *name, struct proc_dentry *parent); - -struct proc_dentry *proc_create_data(const char *name, mode_t mode, struct proc_dentry *parent, - const struct dfs_file_ops *fops, void *data); - -struct proc_dentry *proc_symlink(const char *name, struct proc_dentry *parent, const char *dest); - -struct proc_dentry *proc_acquire(struct proc_dentry *dentry); -void proc_release(struct proc_dentry *dentry); - -void proc_remove(struct proc_dentry *dentry); -``` - -- dfs_proc_find - - 查找指定节点,并返回节点数据指针 - - | 入参 | 说明 | - | ---- | ---------------------------------------------------- | - | name | 从 procfs 的 root 起始的完整路径,比如 “/dir1/file2” | - -- proc_mkdir_data - - 创建一个目录,并返回节点数据指针 - - | 入参 | 说明 | - | ------ | ------------------------------------------------------------ | - | name | 从 procfs 的 root 起始的完整路径,比如 “/dir1/file2”
从 parent 起始的完整路径 | - | mode | 权限配置 | - | parent | 指定创建目录的起始节点 | - | fops | 文件操作接口配置 | - | data | 私有数据 | - -- proc_mkdir_mode - - 创建一个目录,并返回节点数据指针 - - | 入参 | 说明 | - | ------ | ------------------------------------------------------------ | - | name | 从 procfs 的 root 起始的完整路径,比如 “/dir1/file2”
从 parent 起始的完整路径 | - | mode | 权限配置 | - | parent | 指定创建目录的起始节点 | - -- proc_mkdir - - 创建一个目录,并返回节点数据指针 - - | 入参 | 说明 | - | ---- | ------------------------------------------------------------ | - | name | 从 procfs 的 root 起始的完整路径,比如 “/dir1/file2”
从 parent 起始的完整路径 | - | mode | 权限配置 | - -- proc_create_data - - 创建一个文件,并返回节点数据指针 - - | 入参 | 说明 | - | ------ | ------------------------------------------------------------ | - | name | 从 procfs 的 root 起始的完整路径,比如 “/dir1/file2”
从 parent 起始的完整路径 | - | mode | 权限配置 | - | parent | 指定创建文件的起始节点 | - | fops | 文件操作接口配置 | - | data | 私有数据 | - -- proc_symlink - - 创建一个符号链接,并返回节点数据指针 - - | 入参 | 说明 | - | ------ | ------------------------------------------------------------ | - | name | 从 procfs 的 root 起始的完整路径,比如 “/dir1/file2”
从 parent 起始的完整路径 | - | parent | 指定创建文件的起始节点 | - | dest | 链接的目标文件完整路径 | - -- proc_acquire - - 引用一个节点,并返回节点数据指针 - - | 入参 | 说明 | - | ------ | -------------- | - | dentry | 需要引用的节点 | - -- proc_release - - 释放一个节点 - - | 入参 | 说明 | - | ------ | -------------- | - | dentry | 需要释放的节点 | - -- proc_remove - - 删除一个节点包含子节点 - - | 入参 | 说明 | - | ------ | -------------- | - | dentry | 需要删除的节点 | - -## msh 调试命令 - -- proc_dump - - 遍历打印指定节点含子节点的信息(名称、引用计数),比如 `proc_dump /dir1` 或者 `proc_dump` - -- proc_remove - - 删除指定节点含子节点,比如 `proc_remove /dir1` 或者 `proc_remove /file3` - -- proc_symlink - - 创建一个符号链接,`proc_symlink /link3 /mnt` - -- proc_echo - - 创建一个空文件,`proc_echo /file4` - -- proc_mkdir - - 创建一个空目录,`proc_mkdir /dir3` - -- proc_pid - - 创建一个 pid 目录,`proc_pid /101` diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/SConscript b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/SConscript deleted file mode 100644 index 4af49a1..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/SConscript +++ /dev/null @@ -1,11 +0,0 @@ -# RT-Thread building script for component - -from building import * - -cwd = GetCurrentDir() -src = Glob('*.c') -CPPPATH = [cwd] - -group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_PROCFS'], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc.c deleted file mode 100644 index 0e0d202..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc.c +++ /dev/null @@ -1,733 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -/* - * This is the root in the proc tree.. - */ -static struct proc_dentry _proc_root = { - .mode = S_IFDIR | (S_IRUSR | S_IRGRP | S_IROTH) | (S_IXUSR | S_IXGRP | S_IXOTH), - .ref_count = 1, - - .parent = &_proc_root, - .node.sibling = RT_LIST_OBJECT_INIT(_proc_root.node.sibling), - .node.subnode = RT_LIST_OBJECT_INIT(_proc_root.node.subnode), - - .fops = RT_NULL, - - .name = "/", - .data = RT_NULL, -}; - -static int _proc_find(struct proc_dentry **parent, const char *name) -{ - struct proc_dentry *dentry = RT_NULL, *tmp; - - dfs_vfs_for_each_subnode(dentry, tmp, (*parent), node) - { - if (dentry == RT_NULL) - { - break; - } - - if (rt_strcmp(dentry->name, name) == 0) - { - *parent = dentry; - return 0; - } - } - - return -1; -} - -static int proc_find(struct proc_dentry **parent, const char **name, rt_bool_t force_lookup) -{ - int ret = 0; - char *tmp = RT_NULL; - - if (!(*parent)) - { - *parent = &_proc_root; - } - - tmp = rt_strdup(*name); - if (tmp) - { - char *begin = tmp, *end = RT_NULL; - if (*begin == '/') - { - begin++; - if (*begin == '\0') - { - rt_free(tmp); - *parent = proc_acquire(*parent); - return ret; - } - } - - while (1) - { - end = rt_strstr(begin, "/"); - if (end) - { - *end = '\0'; - ret = _proc_find(parent, begin); - if (ret < 0 || !S_ISDIR((*parent)->mode)) - { - *parent = RT_NULL; - ret = -1; - break; - } - begin = end + 1; - } - else if (force_lookup) - { - ret = _proc_find(parent, begin); - if (ret < 0) - { - if ((*parent)->ops && (*parent)->ops->lookup) - { - *parent = (*parent)->ops->lookup(*parent, begin); - if (*parent == RT_NULL) - { - ret = -1; - } - } - else - { - *parent = RT_NULL; - } - } - else - { - *parent = proc_acquire(*parent); - } - break; - } - else - { - *parent = proc_acquire(*parent); - break; - } - } - - *name = *name + (begin - tmp); - - rt_free(tmp); - } - - return ret; -} - -static void *single_start(struct dfs_seq_file *seq, off_t *index) -{ - return NULL + (*index == 0); -} - -static void *single_next(struct dfs_seq_file *seq, void *data, off_t *index) -{ - ++*index; - return NULL; -} - -static void single_stop(struct dfs_seq_file *seq, void *data) -{ -} - -static int proc_open(struct dfs_file *file) -{ - struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data; - - if (entry->single_show) - { - struct dfs_seq_ops *seq_ops = (struct dfs_seq_ops *)rt_calloc(1, sizeof(struct dfs_seq_ops)); - if (seq_ops) - { - int ret = 0; - - seq_ops->start = single_start; - seq_ops->next = single_next; - seq_ops->stop = single_stop; - seq_ops->show = entry->single_show; - - ret = dfs_seq_open(file, seq_ops); - if (ret != 0) - { - rt_free(seq_ops); - } - return ret; - } - } - - return dfs_seq_open(file, entry->seq_ops); -} - -static int proc_close(struct dfs_file *file) -{ - struct dfs_seq_file *seq = file->data; - struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data; - - if (seq && entry->single_show && seq->ops) - { - rt_free((void *)seq->ops); - seq->ops = RT_NULL; - } - - return dfs_seq_release(file); -} - -static const struct dfs_file_ops proc_file_ops = { - .open = proc_open, - .read = dfs_seq_read, - .lseek = dfs_seq_lseek, - .close = proc_close, -}; - -static struct proc_dentry *proc_create(struct proc_dentry **parent, const char *name, mode_t mode) -{ - int ret = 0; - struct proc_dentry *dentry = RT_NULL; - - ret = proc_find(parent, &name, 0); - if (ret >= 0) - { - dentry = *parent; - ret = proc_find(&dentry, &name, 1); - if (ret < 0) - { - dentry = rt_calloc(1, sizeof(struct proc_dentry)); - if (dentry) - { - dentry->mode = mode; - dentry->ref_count = 1; - dentry->name = rt_strdup(name); - dfs_vfs_init_node(&dentry->node); - } - } - else - { - proc_release(dentry); - dentry = RT_NULL; - } - } - - return dentry; -} - -/** - * @brief The dentry reference count is incremented by one - * - * @param dentry - * - * @return dentry - */ -struct proc_dentry *proc_acquire(struct proc_dentry *dentry) -{ - if (dentry) - { - dentry->ref_count += 1; - } - - return dentry; -} - -/** - * @brief The dentry reference count is minus one, or release - * - * @param dentry - * - * @return none - */ -void proc_release(struct proc_dentry *dentry) -{ - if (dentry) - { - if (dentry->ref_count == 1) - { - if (dentry->name) - { - rt_free(dentry->name); - } - - if (S_ISLNK(dentry->mode) && dentry->data) - { - rt_free(dentry->data); - } - - rt_free(dentry); - } - else - { - dentry->ref_count -= 1; - } - } -} - -static struct proc_dentry *proc_register(struct proc_dentry *parent, struct proc_dentry *child) -{ - child->parent = parent; - dfs_vfs_append_node(&parent->node, &child->node); - child->ref_count += 1; - child->pid = parent->pid; - - return child; -} - -/** - * @brief Make a dir - * - * @param name fullpath based on _proc_root or parent - * @param mode permission configuration - * @param parent can be empty - * @param fops - * @param data - * - * @return dentry - */ -struct proc_dentry *proc_mkdir_data(const char *name, mode_t mode, struct proc_dentry *parent, - const struct dfs_file_ops *fops, void *data) -{ - struct proc_dentry *dentry, *_parent = parent; - - if (mode == 0) - mode = (S_IRUSR | S_IRGRP | S_IROTH) | (S_IXUSR | S_IXGRP | S_IXOTH); - - dentry = proc_create(&_parent, name, S_IFDIR | mode); - if (dentry) - { - dentry->fops = fops; - dentry->data = data; - - dentry = proc_register(_parent, dentry); - } - proc_release(_parent); - - return dentry; -} - -/** - * @brief Make a dir - * - * @param name fullpath based on _proc_root or parent - * @param mode permission configuration - * @param parent can be empty - * - * @return dentry - */ -struct proc_dentry *proc_mkdir_mode(const char *name, mode_t mode, struct proc_dentry *parent) -{ - return proc_mkdir_data(name, mode, parent, NULL, NULL); -} - -/** - * @brief Make a dir - * - * @param name fullpath based on _proc_root or parent - * @param parent can be empty - * - * @return dentry - */ -struct proc_dentry *proc_mkdir(const char *name, struct proc_dentry *parent) -{ - return proc_mkdir_data(name, 0, parent, NULL, NULL); -} - -static struct proc_dentry *proc_create_reg(const char *name, mode_t mode, struct proc_dentry **parent) -{ - struct proc_dentry *dentry = RT_NULL; - - if ((mode & S_IFMT) == 0) - mode |= S_IFREG; - if ((mode & (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)) == 0) - mode |= S_IRUSR | S_IRGRP | S_IROTH; - - if (!S_ISREG(mode)) - { - *parent = RT_NULL; - return dentry; - } - - return proc_create(parent, name, mode); -} - -/** - * @brief Make a file - * - * @param name fullpath based on _proc_root or parent - * @param mode permission configuration - * @param parent can be empty - * @param fops - * @param data - * - * @return dentry - */ -struct proc_dentry *proc_create_data(const char *name, mode_t mode, struct proc_dentry *parent, - const struct dfs_file_ops *fops, void *data) -{ - struct proc_dentry *dentry, *_parent = parent; - - dentry = proc_create_reg(name, mode, &_parent); - if (dentry) - { - dentry->fops = fops ? fops : &proc_file_ops; - dentry->data = data; - - dentry = proc_register(_parent, dentry); - } - proc_release(_parent); - - return dentry; -} - -/** - * @brief Make a file - * - * @param name fullpath based on _proc_root or parent - * @param mode permission configuration - * @param parent can be empty - * @param show - * @param data - * - * @return dentry - */ -struct proc_dentry *proc_create_single_data(const char *name, mode_t mode, struct proc_dentry *parent, - int (*show)(struct dfs_seq_file *, void *), void *data) -{ - struct proc_dentry *dentry, *_parent = parent; - - dentry = proc_create_reg(name, mode, &_parent); - if (dentry) - { - dentry->fops = &proc_file_ops; - dentry->single_show = show; - dentry->data = data; - - dentry = proc_register(_parent, dentry); - } - proc_release(_parent); - - return dentry; -} - -/** - * @brief Make a symlink - * - * @param name fullpath based on _proc_root or parent - * @param parent can be empty - * @param dest link file fullpath - * - * @return dentry - */ -struct proc_dentry *proc_symlink(const char *name, struct proc_dentry *parent, const char *dest) -{ - struct proc_dentry *dentry, *_parent = parent; - - dentry = proc_create(&_parent, name, (S_IFLNK | (S_IRUSR | S_IRGRP | S_IROTH) - | (S_IWUSR | S_IWGRP | S_IWOTH) | (S_IXUSR | S_IXGRP | S_IXOTH))); - if (dentry) - { - dentry->data = (void *)rt_strdup(dest); - if (dentry->data) - { - dentry = proc_register(_parent, dentry); - } - else - { - proc_release(dentry); - dentry = NULL; - } - } - proc_release(_parent); - - return dentry; -} - -static void remove_proc_subtree(struct proc_dentry *dentry) -{ - struct proc_dentry *iter = RT_NULL, *iter_tmp, *tmp = RT_NULL; - - dfs_vfs_for_each_subnode(iter, iter_tmp, dentry, node) - { - if (iter == RT_NULL) - { - break; - } - - if (tmp) - { - proc_release(tmp); - tmp = RT_NULL; - } - - tmp = iter; - - if (S_ISDIR(dentry->mode)) - { - remove_proc_subtree(iter); - } - } - - if (tmp) - { - proc_release(tmp); - tmp = RT_NULL; - } -} - -/** - * @brief remove a dentry - * - * @param dentry - * - * @return none - */ -void proc_remove(struct proc_dentry *dentry) -{ - if (dentry && dentry != &_proc_root) - { - if (S_ISDIR(dentry->mode)) - { - remove_proc_subtree(dentry); - } - - dfs_vfs_remove_node(&dentry->node); - proc_release(dentry); - } -} - -/** - * @brief find dentry exist - * - * @param name fullpath based on _proc_root - * - * @return dentry - */ -struct proc_dentry *dfs_proc_find(const char *name) -{ - struct proc_dentry *dentry = RT_NULL; - - proc_find(&dentry, &name, 1); - - return dentry; -} - -/** - * @brief remove a dentry on parent - * - * @param name fullpath based on parent - * @param parent - * - * @return none - */ -void proc_remove_dentry(const char *name, struct proc_dentry *parent) -{ - struct proc_dentry *dentry = parent; - - if (proc_find(&dentry, &name, 1) >= 0) - { - proc_remove(dentry); - proc_release(dentry); - } -} - -#define _COLOR_RED "\033[31m" -#define _COLOR_GREEN "\033[32m" -#define _COLOR_BLUE "\033[34m" -#define _COLOR_CYAN "\033[36m" -#define _COLOR_WHITE "\033[37m" -#define _COLOR_NORMAL "\033[0m" - -static void dump_proc_subtree(struct proc_dentry *dentry, int tab) -{ - struct proc_dentry *iter = RT_NULL, *tmp; - - dfs_vfs_for_each_subnode(iter, tmp, dentry, node) - { - if (iter == RT_NULL) - { - break; - } - - for(int i = 0; i < tab; i ++) - { - rt_kprintf("%-4s", i + 1 >= tab ? "|-" : " "); - } - - if (S_ISDIR(iter->mode)) - { - rt_kprintf(_COLOR_BLUE "%-20s" _COLOR_NORMAL " %d\n", iter->name, iter->ref_count); - dump_proc_subtree(iter, tab + 1); - } - else if (S_ISLNK(iter->mode)) - { - rt_kprintf(_COLOR_CYAN "%-20s" _COLOR_NORMAL " %d\n", iter->name, iter->ref_count); - } - else - { - rt_kprintf("%-20s %d\n", iter->name, iter->ref_count); - } - } -} - -static void proc_dump(struct proc_dentry *dentry) -{ - if (dentry) - { - if (S_ISDIR(dentry->mode)) - { - rt_kprintf(_COLOR_BLUE "%-20s" _COLOR_NORMAL " %d\n", dentry->name, dentry->ref_count); - dump_proc_subtree(dentry, 1); - } - else if (S_ISLNK(dentry->mode)) - { - rt_kprintf(_COLOR_CYAN "%-20s" _COLOR_NORMAL " %d\n", dentry->name, dentry->ref_count); - } - else - { - rt_kprintf("%-20s %d\n", dentry->name, dentry->ref_count); - } - } -} - -static int msh_proc_dump(int argc, char** argv) -{ - const char *name = argc > 1 ? argv[1] : "/"; - struct proc_dentry *dentry = RT_NULL; - - int ret = proc_find(&dentry, &name, 1); - if (ret >= 0) - { - proc_dump(dentry); - } - proc_release(dentry); - - return 0; -} -MSH_CMD_EXPORT_ALIAS(msh_proc_dump, proc_dump, proc dump); - -static int msh_proc_remove(int argc, char** argv) -{ - if (argc > 1) - { - const char *name = argv[1]; - struct proc_dentry *dentry = RT_NULL; - - int ret = proc_find(&dentry, &name, 1); - if (ret >= 0) - { - if (dentry != &_proc_root) - { - proc_remove(dentry); - } - else - { - struct proc_dentry *iter = RT_NULL, *iter_tmp, *tmp = RT_NULL; - - dfs_vfs_for_each_subnode(iter, iter_tmp, dentry, node) - { - if (iter == RT_NULL) - { - break; - } - - if (tmp) - { - proc_remove(tmp); - } - - tmp = iter; - } - - if (tmp) - { - proc_remove(tmp); - } - } - } - proc_release(dentry); - } - else - { - rt_kprintf("proc_remove path\n"); - } - - return 0; -} -MSH_CMD_EXPORT_ALIAS(msh_proc_remove, proc_remove, proc remove); - -static int msh_proc_symlink(int argc, char** argv) -{ - if (argc > 2) - { - struct proc_dentry *entry = proc_symlink(argv[1], 0, argv[2]); - if (entry) - { - proc_release(entry); - } - } - else - { - rt_kprintf("proc_symlink path dest\n"); - } - - return 0; -} -MSH_CMD_EXPORT_ALIAS(msh_proc_symlink, proc_symlink, proc symlink); - -static int msh_proc_echo(int argc, char** argv) -{ - if (argc > 1) - { - for(int i = 1; i <= argc - 1; i ++) - { - struct proc_dentry *entry = proc_create_data(argv[i], 0, 0, 0, 0); - if (entry) - { - proc_release(entry); - } - } - } - else - { - rt_kprintf("proc_echo path\n"); - } - - return 0; -} -MSH_CMD_EXPORT_ALIAS(msh_proc_echo, proc_echo, proc echo); - -static int msh_proc_mkdir(int argc, char** argv) -{ - if (argc > 1) - { - for(int i = 1; i <= argc - 1; i ++) - { - struct proc_dentry *entry = proc_mkdir(argv[i], 0); - if (entry) - { - proc_release(entry); - } - } - } - else - { - rt_kprintf("proc_mkdir path\n"); - } - - return 0; -} -MSH_CMD_EXPORT_ALIAS(msh_proc_mkdir, proc_mkdir, proc mkdir); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc.h b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc.h deleted file mode 100644 index e697860..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#ifndef __PROC_H__ -#define __PROC_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -struct proc_dentry; - -struct proc_ops -{ - struct proc_dentry *(*lookup)(struct proc_dentry *parent, const char *name); - int (*readlink)(struct proc_dentry *dentry, char *buf, int len); -}; - -struct proc_dentry -{ - rt_uint32_t mode; - rt_atomic_t ref_count; - - struct proc_dentry *parent; - struct dfs_vfs_node node; - - const struct dfs_file_ops *fops; - const struct proc_ops *ops; - const struct dfs_seq_ops *seq_ops; - int (*single_show)(struct dfs_seq_file *seq, void *data); - - int pid; - - char *name; - void *data; -}; - -struct proc_dentry *dfs_proc_find(const char *name); - -struct proc_dentry *proc_mkdir_data(const char *name, mode_t mode, struct proc_dentry *parent, - const struct dfs_file_ops *fops, void *data); -struct proc_dentry *proc_mkdir_mode(const char *name, mode_t mode, struct proc_dentry *parent); -struct proc_dentry *proc_mkdir(const char *name, struct proc_dentry *parent); - -struct proc_dentry *proc_create_data(const char *name, mode_t mode, struct proc_dentry *parent, - const struct dfs_file_ops *fops, void *data); -struct proc_dentry *proc_create_single_data(const char *name, mode_t mode, struct proc_dentry *parent, - int (*show)(struct dfs_seq_file *, void *), void *data); - -struct proc_dentry *proc_symlink(const char *name, struct proc_dentry *parent, const char *dest); - -struct proc_dentry *proc_acquire(struct proc_dentry *dentry); -void proc_release(struct proc_dentry *dentry); - -void proc_remove(struct proc_dentry *dentry); -void proc_remove_dentry(const char *name, struct proc_dentry *parent); - -int proc_pid(int pid); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_cmdline.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_cmdline.c deleted file mode 100644 index 5845b5f..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_cmdline.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include - -static char *__proc_cmdline = NULL; - -int proc_cmdline_save(const char *cmdline) -{ - if (__proc_cmdline) - { - free(__proc_cmdline); - __proc_cmdline = NULL; - } - - __proc_cmdline = strdup(cmdline); - - return 0; -} - -static int single_show(struct dfs_seq_file *seq, void *data) -{ - if (__proc_cmdline) - { - dfs_seq_puts(seq, __proc_cmdline); - } - - return 0; -} - -int proc_cmdline_init(void) -{ - struct proc_dentry *dentry = proc_create_single_data("cmdline", 0, NULL, single_show, NULL); - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_cmdline_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_cpuinfo.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_cpuinfo.c deleted file mode 100644 index 6f49832..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_cpuinfo.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include - -static void *seq_start(struct dfs_seq_file *seq, off_t *index) -{ - off_t i = *index; // seq->index - - return NULL + (i == 0); -} - -static void seq_stop(struct dfs_seq_file *seq, void *data) -{ -} - -static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index) -{ - /* data: The return value of the start or next*/ - off_t i = *index + 1; // seq->index - - *index = i; - - return NULL; -} - -static int seq_show(struct dfs_seq_file *seq, void *data) -{ - /* data: The return value of the start or next*/ - dfs_seq_puts(seq, "rt_weak const struct dfs_seq_ops *cpuinfo_get_seq_ops(void)\n--need your own function--\n"); - - return 0; -} - -static const struct dfs_seq_ops seq_ops = { - .start = seq_start, - .stop = seq_stop, - .next = seq_next, - .show = seq_show, -}; - -rt_weak const struct dfs_seq_ops *cpuinfo_get_seq_ops(void) -{ - return &seq_ops; -} - -static int proc_open(struct dfs_file *file) -{ - return dfs_seq_open(file, cpuinfo_get_seq_ops()); -} - -static int proc_close(struct dfs_file *file) -{ - return dfs_seq_release(file); -} - -static const struct dfs_file_ops file_ops = { - .open = proc_open, - .read = dfs_seq_read, - .lseek = dfs_seq_lseek, - .close = proc_close, -}; - -int proc_cpuinfo_init(void) -{ - struct proc_dentry *dentry = proc_create_data("cpuinfo", 0, NULL, &file_ops, NULL); - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_cpuinfo_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_devices.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_devices.c deleted file mode 100644 index 7bd0718..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_devices.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include -#include -#include -#include - - -#define LIST_FIND_OBJ_NR 8 - -struct device_show -{ - char *buf; - int size; - int len; - int index; -}; - -typedef struct -{ - rt_list_t *list; - rt_list_t **array; - rt_uint8_t type; - int nr; /* input: max nr, can't be 0 */ - int nr_out; /* out: got nr */ -} list_get_next_t; - -static void list_find_init(list_get_next_t *p, rt_uint8_t type, rt_list_t **array, int nr) -{ - struct rt_object_information *info; - rt_list_t *list; - - info = rt_object_get_information((enum rt_object_class_type)type); - list = &info->object_list; - - p->list = list; - p->type = type; - p->array = array; - p->nr = nr; - p->nr_out = 0; -} - -static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg) -{ - int first_flag = 0; - rt_base_t level; - rt_list_t *node, *list; - rt_list_t **array; - struct rt_object_information *info; - int nr; - - arg->nr_out = 0; - - if (!arg->nr || !arg->type) - { - return (rt_list_t *)RT_NULL; - } - - list = arg->list; - info = rt_list_entry(list, struct rt_object_information, object_list); - - if (!current) /* find first */ - { - node = list; - first_flag = 1; - } - else - { - node = current; - } - - level = rt_spin_lock_irqsave(&info->spinlock); - - if (!first_flag) - { - struct rt_object *obj; - /* The node in the list? */ - obj = rt_list_entry(node, struct rt_object, list); - if ((obj->type & ~RT_Object_Class_Static) != arg->type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - return (rt_list_t *)RT_NULL; - } - } - - nr = 0; - array = arg->array; - while (1) - { - node = node->next; - - if (node == list) - { - node = (rt_list_t *)RT_NULL; - break; - } - nr++; - *array++ = node; - if (nr == arg->nr) - { - break; - } - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - arg->nr_out = nr; - return node; -} - -static char *const device_type_str[RT_Device_Class_Unknown] = -{ - "Character Device", - "Block Device", - "Network Interface", - "MTD Device", - "CAN Device", - "RTC", - "Sound Device", - "Graphic Device", - "I2C Bus", - "USB Slave Device", - "USB Host Bus", - "USB OTG Bus", - "SPI Bus", - "SPI Device", - "SDIO Bus", - "PM Pseudo Device", - "Pipe", - "Portal Device", - "Timer Device", - "Miscellaneous Device", - "Sensor Device", - "Touch Device", - "Phy Device", - "Security Device", - "WLAN Device", - "Pin Device", - "ADC Device", - "DAC Device", - "WDT Device", - "PWM Device", - "Bus Device", -}; - -static void save_info(struct device_show *dev, char *dev_name) -{ - char tmp[256] = {0}; - int len; - - dev->index ++; - - rt_snprintf(tmp, 256, "%d %s\n", dev->index, dev_name); - tmp[255] = 0; - - len = rt_strlen(tmp); - if (dev->size > dev->len + len) - { - strcat(dev->buf, tmp); - dev->len += len; - } - else - { - if (dev->buf == RT_NULL) - { - dev->buf = rt_calloc(1, 4096); - } - else - { - dev->buf = rt_realloc(dev->buf, dev->size + 4096); - } - if (dev->buf) - { - dev->size += 4096; - strcat(dev->buf, tmp); - dev->len += len; - } - } -} - -static void list_device(struct device_show *dev) -{ - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; - - list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); - - do - { - next = list_get_next(next, &find_arg); - { - int i; - for (i = 0; i < find_arg.nr_out; i++) - { - struct rt_object *obj; - struct rt_device *device; - - obj = rt_list_entry(obj_list[i], struct rt_object, list); - level = rt_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - - device = (struct rt_device *)obj; - - if (device->type < RT_Device_Class_Unknown) - { - save_info(dev + device->type, device->parent.name); - } - } - } - } - while (next != (rt_list_t *)RT_NULL); -} - -static int show_info(struct dfs_seq_file *seq) -{ - struct device_show _show[RT_Device_Class_Unknown] = {0}; - - list_device(_show); - - for (int i = 0; i < RT_Device_Class_Unknown; i++) - { - if (_show[i].buf) - { - dfs_seq_printf(seq, "%s:\n", device_type_str[i]); - dfs_seq_write(seq, _show[i].buf, _show[i].len); - dfs_seq_putc(seq, '\n'); - - rt_free(_show[i].buf); - } - } - - return 0; -} - -static void *seq_start(struct dfs_seq_file *seq, off_t *index) -{ - off_t i = *index; // seq->index - - return NULL + (i == 0); -} - -static void seq_stop(struct dfs_seq_file *seq, void *data) -{ -} - -static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index) -{ - /* data: The return value of the start or next*/ - off_t i = *index + 1; // seq->index - - *index = i; - - return NULL; -} - -static int seq_show(struct dfs_seq_file *seq, void *data) -{ - /* data: The return value of the start or next*/ - show_info(seq); - - return 0; -} - -static const struct dfs_seq_ops seq_ops = { - .start = seq_start, - .stop = seq_stop, - .next = seq_next, - .show = seq_show, -}; - -int proc_devices_init(void) -{ - struct proc_dentry *dentry = proc_create_data("devices", 0, NULL, NULL, NULL); - if (dentry) - { - dentry->seq_ops = &seq_ops; - } - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_devices_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_filesystems.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_filesystems.c deleted file mode 100644 index 94e7a85..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_filesystems.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include -#include - -static void *seq_start(struct dfs_seq_file *seq, off_t *index) -{ - off_t i = *index; // seq->index - struct dfs_filesystem_type *fs = dfs_filesystems(); - - if (fs) - { - while (i--) - { - fs = fs->next; - if (!fs) - { - break; - } - } - } - - return fs; -} - -static void seq_stop(struct dfs_seq_file *seq, void *data) -{ -} - -static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index) -{ - /* data: The return value of the start or next*/ - off_t i = *index + 1; // seq->index - struct dfs_filesystem_type *fs = (struct dfs_filesystem_type *)data; - - *index = i; - - return fs->next; -} - -static int seq_show(struct dfs_seq_file *seq, void *data) -{ - /* data: The return value of the start or next*/ - struct dfs_filesystem_type *fs = (struct dfs_filesystem_type *)data; - - dfs_seq_printf(seq, "%-9s%s\n", (fs->fs_ops->flags == FS_NEED_DEVICE) ? "" : "nodev", fs->fs_ops->name); - - return 0; -} - -static const struct dfs_seq_ops seq_ops = { - .start = seq_start, - .stop = seq_stop, - .next = seq_next, - .show = seq_show, -}; - -int proc_filesystems_init(void) -{ - struct proc_dentry *dentry = proc_create_data("filesystems", 0, NULL, NULL, NULL); - if (dentry) - { - dentry->seq_ops = &seq_ops; - } - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_filesystems_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_loadavg.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_loadavg.c deleted file mode 100644 index 6ce1bc4..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_loadavg.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include -#include - - -extern void rt_memory_info(rt_size_t *total, - rt_size_t *used, - rt_size_t *max_used); - -static int single_show(struct dfs_seq_file *seq, void *data) -{ - dfs_seq_printf(seq, "0.13 0.16 0.17 1/1035 380436\n"); - - return 0; -} - -int proc_loadavg_init(void) -{ - struct proc_dentry *dentry = proc_create_single_data("loadavg", 0, NULL, single_show, NULL); - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_loadavg_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_meminfo.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_meminfo.c deleted file mode 100644 index b6ae562..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_meminfo.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include -#include - - -extern void rt_memory_info(rt_size_t *total, - rt_size_t *used, - rt_size_t *max_used); - -static int single_show(struct dfs_seq_file *seq, void *data) -{ - rt_size_t total, used, max_used, freed; - rt_size_t total_sum = 0; - rt_size_t total_freed = 0; - - rt_memory_info(&total, &used, &max_used); - total_sum = total_sum + total; - total_freed = total_freed + total - used; - - dfs_seq_printf(seq, "%-16s%8d KB\n", "MemMaxUsed:", max_used / 1024); - dfs_seq_printf(seq, "%-16s%8d KB\n", "MemAvailable:", (total - used) / 1024); - dfs_seq_printf(seq, "%-16s%8d KB\n", "Cached:", 0); - dfs_seq_printf(seq, "%-16s%8d KB\n", "SReclaimable:", 0); - - rt_page_get_info(&total, &freed); - total_sum = total_sum + total * RT_MM_PAGE_SIZE; - total_freed = total_freed + freed * RT_MM_PAGE_SIZE; - - dfs_seq_printf(seq, "%-16s%8d KB\n", "MemTotal:", total_sum / 1024); - dfs_seq_printf(seq, "%-16s%8d KB\n", "MemFree:", total_freed / 1024); - dfs_seq_printf(seq, "%-16s%8d KB\n", "LowPageTotal:", total * RT_MM_PAGE_SIZE / 1024); - dfs_seq_printf(seq, "%-16s%8d KB\n", "lowPageFree:", freed * RT_MM_PAGE_SIZE/ 1024); - - rt_page_high_get_info(&total, &freed); - - dfs_seq_printf(seq, "%-16s%8d KB\n", "HighPageTotal:", total * RT_MM_PAGE_SIZE / 1024); - dfs_seq_printf(seq, "%-16s%8d KB\n", "HighPageFree:", freed * RT_MM_PAGE_SIZE / 1024); - - return 0; -} - -int proc_meminfo_init(void) -{ - struct proc_dentry *dentry = proc_create_single_data("meminfo", 0, NULL, single_show, NULL); - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_meminfo_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_mounts.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_mounts.c deleted file mode 100644 index 49a6ba9..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_mounts.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include -#include - - -const char *mnt_flag(int flag) -{ - /*if (flag & MNT_READONLY) - { - return "ro"; - }*/ - - return "rw"; -} - -static struct dfs_mnt* mnt_show(struct dfs_mnt *mnt, void *parameter) -{ - struct dfs_seq_file *seq = (struct dfs_seq_file *)parameter; - - if (mnt) - { - if (mnt->dev_id) - { - dfs_seq_printf(seq, "%s %s %s %s 0 0\n", mnt->dev_id->parent.name, mnt->fullpath, - mnt->fs_ops->name, mnt_flag(mnt->flags)); - } - else - { - dfs_seq_printf(seq, "%s %s %s %s 0 0\n", mnt->fs_ops->name, mnt->fullpath, - mnt->fs_ops->name, mnt_flag(mnt->flags)); - } - } - - return RT_NULL; -} - -static void *seq_start(struct dfs_seq_file *seq, off_t *index) -{ - off_t i = *index; // seq->index - - return NULL + (i == 0); -} - -static void seq_stop(struct dfs_seq_file *seq, void *data) -{ -} - -static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index) -{ - /* data: The return value of the start or next*/ - off_t i = *index + 1; // seq->index - - *index = i; - - return NULL; -} - -static int seq_show(struct dfs_seq_file *seq, void *data) -{ - /* data: The return value of the start or next*/ - dfs_mnt_foreach(mnt_show, seq); - - return 0; -} - -static const struct dfs_seq_ops seq_ops = { - .start = seq_start, - .stop = seq_stop, - .next = seq_next, - .show = seq_show, -}; - -int proc_mounts_init(void) -{ - struct proc_dentry *dentry = proc_create_data("mounts", 0, NULL, NULL, NULL); - if (dentry) - { - dentry->seq_ops = &seq_ops; - } - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_mounts_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_net.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_net.c deleted file mode 100644 index e2b38e0..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_net.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include - -#ifdef RT_USING_LWIP -#include "lwip/opt.h" -#endif - -#if LWIP_ROUTE -extern int inet_route_foreach(void (*func)(const char *name, uint32_t ip_addr, uint32_t netmask, void *parameter), void *parameter); -#endif - -static void *seq_start(struct dfs_seq_file *seq, off_t *index) -{ - off_t i = *index; // seq->index - - return NULL + (i == 0); -} - -static void seq_stop(struct dfs_seq_file *seq, void *data) -{ -} - -static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index) -{ - /* data: The return value of the start or next*/ - off_t i = *index + 1; // seq->index - - *index = i; - - return NULL; -} - -static void route_show(const char *name, uint32_t ip_addr, uint32_t netmask, void *parameter) -{ - struct dfs_seq_file *seq = (struct dfs_seq_file *)parameter; - /* "Iface\tDestination\tGateway " - "\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU" - "\tWindow\tIRTT"); */ - /* "%63s%lx%lx%X%d%d%d%lx%d%d%d\n" */ - dfs_seq_printf(seq, "%s ", name); - dfs_seq_printf(seq, "%lx ", ip_addr); - dfs_seq_printf(seq, "%lx ", 0); - dfs_seq_printf(seq, "%X ", 1); - dfs_seq_printf(seq, "%d ", 0); - dfs_seq_printf(seq, "%d ", 0); - dfs_seq_printf(seq, "%d ", 0); - dfs_seq_printf(seq, "%lx ", netmask); - dfs_seq_printf(seq, "%d ", 0); - dfs_seq_printf(seq, "%d ", 0); - dfs_seq_printf(seq, "%d\n", 0); -} - -static int seq_show(struct dfs_seq_file *seq, void *data) -{ - /* data: The return value of the start or next*/ - dfs_seq_printf(seq, "\n"); -#if LWIP_ROUTE - inet_route_foreach(route_show, seq); -#endif - - return 0; -} - -static const struct dfs_seq_ops seq_ops = { - .start = seq_start, - .stop = seq_stop, - .next = seq_next, - .show = seq_show, -}; - -int proc_net_init(void) -{ - struct proc_dentry *dentry; - - dentry = proc_mkdir("net", NULL); - if (!dentry) - return -1; - - proc_release(dentry); - - dentry = proc_create_data("net/route", 0, NULL, NULL, NULL); - if (dentry) - { - dentry->seq_ops = &seq_ops; - } - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_net_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c deleted file mode 100644 index 1c7a48a..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_partitions.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include -#include -#include -#include - - -#define LIST_FIND_OBJ_NR 8 - -typedef struct -{ - rt_list_t *list; - rt_list_t **array; - rt_uint8_t type; - int nr; /* input: max nr, can't be 0 */ - int nr_out; /* out: got nr */ -} list_get_next_t; - -static void list_find_init(list_get_next_t *p, rt_uint8_t type, rt_list_t **array, int nr) -{ - struct rt_object_information *info; - rt_list_t *list; - - info = rt_object_get_information((enum rt_object_class_type)type); - list = &info->object_list; - - p->list = list; - p->type = type; - p->array = array; - p->nr = nr; - p->nr_out = 0; -} - -static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg) -{ - int first_flag = 0; - rt_base_t level; - rt_list_t *node, *list; - rt_list_t **array; - struct rt_object_information *info; - int nr; - - arg->nr_out = 0; - - if (!arg->nr || !arg->type) - { - return (rt_list_t *)RT_NULL; - } - - list = arg->list; - info = rt_list_entry(list, struct rt_object_information, object_list); - - if (!current) /* find first */ - { - node = list; - first_flag = 1; - } - else - { - node = current; - } - - level = rt_spin_lock_irqsave(&info->spinlock); - - if (!first_flag) - { - struct rt_object *obj; - /* The node in the list? */ - obj = rt_list_entry(node, struct rt_object, list); - if ((obj->type & ~RT_Object_Class_Static) != arg->type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - return (rt_list_t *)RT_NULL; - } - } - - nr = 0; - array = arg->array; - while (1) - { - node = node->next; - - if (node == list) - { - node = (rt_list_t *)RT_NULL; - break; - } - nr++; - *array++ = node; - if (nr == arg->nr) - { - break; - } - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - arg->nr_out = nr; - return node; -} - -static int show_info(struct dfs_seq_file *seq) -{ - rt_base_t level; - list_get_next_t find_arg; - struct rt_object_information *info; - rt_list_t *obj_list[LIST_FIND_OBJ_NR]; - rt_list_t *next = (rt_list_t *)RT_NULL; - - list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list) / sizeof(obj_list[0])); - info = rt_list_entry(find_arg.list, struct rt_object_information, object_list); - - do - { - next = list_get_next(next, &find_arg); - { - int i; - for (i = 0; i < find_arg.nr_out; i++) - { - struct rt_object *obj; - struct rt_device *device; - - obj = rt_list_entry(obj_list[i], struct rt_object, list); - level = rt_spin_lock_irqsave(&info->spinlock); - if ((obj->type & ~RT_Object_Class_Static) != find_arg.type) - { - rt_spin_unlock_irqrestore(&info->spinlock, level); - continue; - } - - rt_spin_unlock_irqrestore(&info->spinlock, level); - - device = (struct rt_device *)obj; - - if (device->type == RT_Device_Class_Block) - { - struct rt_device_blk_geometry geometry = { 0 }; - - rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry); - - dfs_seq_printf(seq, "%4d %7d %14llu %s\n", 0, 0, - geometry.sector_count, device->parent.name); - } - } - } - } while (next != (rt_list_t *)RT_NULL); - - return 0; -} - -static void *seq_start(struct dfs_seq_file *seq, off_t *index) -{ - off_t i = *index; // seq->index - - return NULL + (i == 0); -} - -static void seq_stop(struct dfs_seq_file *seq, void *data) -{ -} - -static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index) -{ - /* data: The return value of the start or next*/ - off_t i = *index + 1; // seq->index - - *index = i; - - return NULL; -} - -static int seq_show(struct dfs_seq_file *seq, void *data) -{ - dfs_seq_puts(seq, "major minor #blocks name\n\n"); - /* data: The return value of the start or next*/ - show_info(seq); - - return 0; -} - -static const struct dfs_seq_ops seq_ops = { - .start = seq_start, - .stop = seq_stop, - .next = seq_next, - .show = seq_show, -}; - -int proc_partitions_init(void) -{ - struct proc_dentry *dentry = proc_create_data("partitions", 0, NULL, NULL, NULL); - if (dentry) - { - dentry->seq_ops = &seq_ops; - } - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_partitions_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_pid.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_pid.c deleted file mode 100644 index a413f64..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_pid.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#define __RT_IPC_SOURCE__ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include "lwp_internal.h" -#include -#include "lwp_internal.h" - -#if defined(RT_USING_SMART) - -#include "lwp.h" -#include "lwp_pid.h" -#include - -struct pid_dentry -{ - const char *name; - mode_t mode; - const struct dfs_file_ops *fops; - const struct proc_ops *ops; - const struct dfs_seq_ops *seq_ops; - int (*single_show)(struct dfs_seq_file *seq, void *data); - void *data; -}; - -static char stat_transform(int __stat) -{ - switch (__stat) - { - case RT_THREAD_RUNNING: - return 'R'; - default: - return 'T'; - } -} - -static int stat_single_show(struct dfs_seq_file *seq, void *data) -{ - struct proc_dentry *dentry = (struct proc_dentry *)seq->file->vnode->data; - rt_list_t *list; - int mask = 0; - rt_thread_t thread; - rt_uint64_t user_time_lwp = 0; - rt_uint64_t system_time_lwp = 0; - int lwp_oncpu = RT_CPUS_NR; - int lwp_oncpu_ok = 0; - struct rt_lwp *lwp = RT_NULL; - char** argv = RT_NULL; - char *filename = RT_NULL; - char *dot = RT_NULL; - - lwp_pid_lock_take(); - - lwp = lwp_from_pid_locked(dentry->pid); - argv = lwp_get_command_line_args(lwp); - - if (lwp) - { - dfs_seq_printf(seq,"%d ",dentry->pid); - if (argv) - { - filename = strrchr(argv[0], '/'); - dot = strchr(argv[0], '.'); - - if (filename != NULL) - { - filename++; - } - else - { - filename = argv[0]; - } - - if (dot != NULL) - { - *dot = '\0'; - } - - if (filename != NULL) - { - dfs_seq_printf(seq,"(%s) ", filename); - } - else - { - dfs_seq_printf(seq,"(%s) ", argv[0]); - } - - lwp_free_command_line_args(argv); - } - else - { - dfs_seq_printf(seq,"(%s) ", ""); - } - - if (lwp->terminated) - { - dfs_seq_printf(seq,"%c ",'Z'); - } - else - { - list = lwp->t_grp.next; - while (list != &lwp->t_grp) - { - thread = rt_list_entry(list, struct rt_thread, sibling); - user_time_lwp = user_time_lwp + thread->user_time; - system_time_lwp = system_time_lwp + thread->system_time; - - #if RT_CPUS_NR > 1 - #define ONCPU(thread) RT_SCHED_CTX(thread).oncpu - #else - #define ONCPU(thread) 0 - #endif - if (lwp_oncpu_ok == 0) - { - lwp_oncpu = ONCPU(thread); - lwp_oncpu_ok = 1; - } - if (stat_transform(RT_SCHED_CTX(thread).stat) == 'R') - { - lwp_oncpu = ONCPU(thread); - mask = 1; - } - list = list->next; - } - - if (mask == 1) - { - dfs_seq_printf(seq,"%c ",'R'); - } - else - { - dfs_seq_printf(seq,"%c ",'S'); - } - } - lwp_pid_lock_release(); - - if (lwp->parent != NULL) - dfs_seq_printf(seq,"%d ",lwp->parent->pid); - else - dfs_seq_printf(seq,"0 "); - - dfs_seq_printf(seq, "1 1 0 -1 4194560 48245 133976064 732 425574 "); - dfs_seq_printf(seq,"%llu ",user_time_lwp);//utime - dfs_seq_printf(seq,"%llu ",system_time_lwp);//stime - dfs_seq_printf(seq, "1204291 518742 20 0 1 0 50 "); - dfs_seq_printf(seq, "%d ",rt_aspace_count_vsz(lwp->aspace));//VSZ - dfs_seq_printf(seq, "1422 18446744073709551615 "); - dfs_seq_printf(seq, "1 1 0 0 0 0 671173123 4096 1260 0 0 0 17 "); - dfs_seq_printf(seq, "%d ", lwp_oncpu);//CPU - dfs_seq_printf(seq, "0 0 0 0 0 0 0 0 0 0 0 0 0"); - dfs_seq_printf(seq,"\n"); - } - else - { - lwp_pid_lock_release(); - } - - return 0; -} - -static int cmdline_single_show(struct dfs_seq_file *seq, void *data) -{ - struct proc_dentry *dentry = (struct proc_dentry *)seq->file->vnode->data; - struct rt_lwp *lwp; - char** argv; - - lwp_pid_lock_take(); - lwp = lwp_from_pid_locked(dentry->pid); - argv = lwp_get_command_line_args(lwp); - lwp_pid_lock_release(); - - if (argv) - { - for (int i = 0; argv[i] != NULL; i++) - { - dfs_seq_printf(seq, "%s ", argv[i]); - } - dfs_seq_puts(seq, "\n"); - - lwp_free_command_line_args(argv); - } - else - { - dfs_seq_puts(seq, "error\n"); - } - - return 0; -} - -struct proc_dentry *proc_pid_fd_lookup(struct proc_dentry *parent, const char *name) -{ - struct proc_dentry *dentry = RT_NULL; - char num[DIRENT_NAME_MAX]; - struct rt_lwp *lwp; - struct dfs_fdtable *table; - - lwp_pid_lock_take(); - lwp = lwp_from_pid_locked(parent->pid); - table = lwp ? &lwp->fdt : RT_NULL; - lwp_pid_lock_release(); - - if (!table) - { - return RT_NULL; - } - - dfs_file_lock(); - for (int i = 0; i < table->maxfd; i++) - { - struct dfs_file *file = table->fds[i]; - if (file) - { - rt_snprintf(num, DIRENT_NAME_MAX, "%d", i); - if (rt_strcmp(num, name) == 0) - { - dentry = rt_calloc(1, sizeof(struct proc_dentry)); - if (dentry) - { - dentry->mode = (S_IFLNK | (S_IRUSR | S_IRGRP | S_IROTH) | (S_IWUSR | S_IWGRP | S_IWOTH) | (S_IXUSR | S_IXGRP | S_IXOTH)); - dentry->ref_count = 1; - dentry->name = rt_strdup(name); - dentry->data = (void *)dfs_dentry_full_path(file->dentry); - - if (dentry->data == RT_NULL) - { - //todo add vnode->data - if (file->vnode->type == FT_SOCKET) - dentry->data = (void *)rt_strdup("socket"); - else if (file->vnode->type == FT_USER) - dentry->data = (void *)rt_strdup("user"); - else if (file->vnode->type == FT_DEVICE) - dentry->data = (void *)rt_strdup("device"); - else - dentry->data = (void *)rt_strdup("unknown"); - } - - dentry->pid = parent->pid; - break; - } - } - } - } - dfs_file_unlock(); - - return dentry; -} - -int proc_pid_fd_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count) -{ - int ret = 0, index = 0; - struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data; - struct rt_lwp *lwp; - struct dfs_fdtable *table; - - lwp_pid_lock_take(); - lwp = lwp_from_pid_locked(entry->pid); - LWP_LOCK(lwp); - table = lwp ? &lwp->fdt : RT_NULL; - - if (!table->fds) - { - LWP_UNLOCK(lwp); - lwp_pid_lock_release(); - return 0; - } - - count = (count / sizeof(struct dirent)); - if (count == 0) - { - LWP_UNLOCK(lwp); - lwp_pid_lock_release(); - return -EINVAL; - } - - dfs_file_lock(); - for (int i = 0; i < table->maxfd; i++) - { - struct dfs_file *df = table->fds[i]; - if (df) - { - if (index >= file->fpos) - { - struct dirent *d = dirp + index - file->fpos; - - d->d_type = DT_SYMLINK; - d->d_reclen = (rt_uint16_t)sizeof(struct dirent); - rt_snprintf(d->d_name, DIRENT_NAME_MAX, "%d", i); - d->d_namlen = rt_strlen(d->d_name); - - ret++; - } - - index++; - if (index - file->fpos >= count) - { - break; - } - } - } - dfs_file_unlock(); - LWP_UNLOCK(lwp); - lwp_pid_lock_release(); - - if (ret > 0) - { - file->fpos = index; - ret = ret * sizeof(struct dirent); - } - - return ret; -} - -static const struct proc_ops proc_pid_fd_ops = { - .lookup = proc_pid_fd_lookup, -}; - -static const struct dfs_file_ops proc_pid_fd_fops = { - .getdents = proc_pid_fd_getdents, -}; - -int proc_pid_exe_readlink(struct proc_dentry *dentry, char *buf, int len) -{ - struct rt_lwp *lwp; - - lwp = lwp_self(); - len = rt_snprintf(buf, len, "%s", lwp ? lwp->exe_file : "null"); - - return len; -} - -static const struct proc_ops proc_pid_exe_ops = { - .readlink = proc_pid_exe_readlink, -}; - -int proc_pid_cwd_readlink(struct proc_dentry *dentry, char *buf, int len) -{ - struct rt_lwp *lwp; - - lwp = lwp_self(); - len = rt_snprintf(buf, len, "%s", lwp ? lwp->working_directory : "null"); - - return len; -} - -static const struct proc_ops proc_pid_cwd_ops = { - .readlink = proc_pid_cwd_readlink, -}; - -static struct pid_dentry pid_dentry_base[] = { - {"cmdline", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 0, 0, 0, cmdline_single_show, 0}, - {"cwd", S_IFLNK | S_IRUSR | S_IXUSR, 0, &proc_pid_cwd_ops, 0, 0}, - {"exe", S_IFLNK | S_IRUSR | S_IXUSR, 0, &proc_pid_exe_ops, 0, 0}, - {"fd", S_IFDIR | S_IRUSR | S_IXUSR, &proc_pid_fd_fops, &proc_pid_fd_ops, 0, 0, 0}, - {"mounts", S_IFLNK | S_IRUSR | S_IXUSR, 0, 0, 0, 0, "/proc/mounts"}, - {"stat", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 0, 0, 0, stat_single_show, 0}, -}; - -int proc_pid(int pid) -{ - char pid_str[64] = {0}; - struct proc_dentry *dentry; - - rt_snprintf(pid_str, 64, "%d", pid); - pid_str[63] = 0; - - dentry = proc_mkdir(pid_str, 0); - if (dentry) - { - struct proc_dentry *ent; - - dentry->pid = pid; - for (int j = 0; j < sizeof(pid_dentry_base) / sizeof(struct pid_dentry); j++) - { - if (S_ISDIR(pid_dentry_base[j].mode)) - { - ent = proc_mkdir_data(pid_dentry_base[j].name, pid_dentry_base[j].mode, dentry, - pid_dentry_base[j].fops, pid_dentry_base[j].data); - } - else if (S_ISLNK(pid_dentry_base[j].mode)) - { - if (pid_dentry_base[j].data == RT_NULL) - { - pid_dentry_base[j].data = "NULL"; - } - - ent = proc_symlink(pid_dentry_base[j].name, dentry, pid_dentry_base[j].data); - } - else - { - ent = proc_create_data(pid_dentry_base[j].name, pid_dentry_base[j].mode, dentry, - pid_dentry_base[j].fops, pid_dentry_base[j].data); - } - - if (ent) - { - if (pid_dentry_base[j].ops) - { - ent->ops = pid_dentry_base[j].ops; - } - - if (pid_dentry_base[j].seq_ops) - { - ent->seq_ops = pid_dentry_base[j].seq_ops; - } - - if (pid_dentry_base[j].single_show) - { - ent->single_show = pid_dentry_base[j].single_show; - } - - proc_release(ent); - } - } - proc_release(dentry); - } - - return 0; -} - -int msh_proc_pid(int argc, char **argv) -{ - if (argc > 1) - { - for (int i = 1; i <= argc - 1; i++) - { - proc_pid(atoi(argv[i])); - } - } - - return 0; -} -MSH_CMD_EXPORT_ALIAS(msh_proc_pid, proc_pid, proc pid); - -#endif diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_self.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_self.c deleted file mode 100644 index a1082ea..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_self.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include - -#if defined(RT_USING_SMART) - -#include - - -int proc_self_readlink(struct proc_dentry *dentry, char *buf, int len) -{ - struct rt_lwp *lwp = RT_NULL; - - lwp = lwp_self(); - if (lwp) - { - rt_snprintf(buf, len, "%d", lwp_to_pid(lwp)); - buf[len - 1] = 0; - return rt_strlen(buf); - } - else - { - rt_snprintf(buf, len, "null"); - buf[len - 1] = 0; - return rt_strlen(buf); - } - - return -1; -} - -static const struct proc_ops proc_pid_fd_ops = { - .readlink = proc_self_readlink, -}; - -int proc_self_init(void) -{ - struct proc_dentry *ent; - - ent = proc_symlink("self", NULL, "NULL"); - if (ent) - { - ent->ops = &proc_pid_fd_ops; - } - proc_release(ent); - - return 0; -} -INIT_ENV_EXPORT(proc_self_init); - -#endif diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_stat.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_stat.c deleted file mode 100644 index aeba99d..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_stat.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include - - -static void *seq_start(struct dfs_seq_file *seq, off_t *index) -{ - off_t i = *index; // seq->index - - return NULL + (i == 0); -} - -static void seq_stop(struct dfs_seq_file *seq, void *data) -{ -} - -static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index) -{ - /* data: The return value of the start or next*/ - off_t i = *index + 1; // seq->index - - *index = i; - - return NULL; -} - -static int seq_show(struct dfs_seq_file *seq, void *data) -{ - int i; - rt_cpu_t pcpu; - rt_uint64_t user_total = 0; - rt_uint64_t system_total = 0; - rt_uint64_t idle_total = 0; - - for (i = 0; i < RT_CPUS_NR; i++) - { - pcpu = rt_cpu_index(i); - user_total = user_total + pcpu->cpu_stat.user; - system_total = system_total + pcpu->cpu_stat.system; - idle_total = idle_total + pcpu->cpu_stat.idle; - } - dfs_seq_printf(seq, "cpu %llu 0 %llu %llu 0 0 0 0 0 0\n", user_total, system_total, idle_total); - - for (i = 0; i < RT_CPUS_NR; i++) - { - pcpu = rt_cpu_index(i); - dfs_seq_printf(seq, "cpu%d ",i); - dfs_seq_printf(seq, "%llu ",pcpu->cpu_stat.user);//user - dfs_seq_printf(seq, "0 ");//nice - dfs_seq_printf(seq, "%llu ",pcpu->cpu_stat.system);//system - dfs_seq_printf(seq, "%llu ",pcpu->cpu_stat.idle);//idle - dfs_seq_printf(seq, "0 ");//iowait - dfs_seq_printf(seq, "0 ");//irq - dfs_seq_printf(seq, "0 ");//softirq - dfs_seq_printf(seq, "0 0 0\n");//steal,guest,guest_nice - - } - - return 0; -} - -static const struct dfs_seq_ops seq_ops = { - .start = seq_start, - .stop = seq_stop, - .next = seq_next, - .show = seq_show, -}; - -rt_weak const struct dfs_seq_ops *stat_get_seq_ops(void) -{ - return &seq_ops; -} - -static int proc_open(struct dfs_file *file) -{ - return dfs_seq_open(file, stat_get_seq_ops()); -} - -static int proc_close(struct dfs_file *file) -{ - return dfs_seq_release(file); -} - -static const struct dfs_file_ops file_ops = { - .open = proc_open, - .read = dfs_seq_read, - .lseek = dfs_seq_lseek, - .close = proc_close, -}; - -int proc_stat_init(void) -{ - struct proc_dentry *dentry = proc_create_data("stat", 0, NULL, &file_ops, NULL); - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_stat_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_tty.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_tty.c deleted file mode 100644 index dc77e4c..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_tty.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include - - -static void *seq_start(struct dfs_seq_file *seq, off_t *index) -{ - off_t i = *index; // seq->index - - return NULL + (i == 0); -} - -static void seq_stop(struct dfs_seq_file *seq, void *data) -{ -} - -static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index) -{ - /* data: The return value of the start or next*/ - off_t i = *index + 1; // seq->index - - *index = i; - - return NULL; -} - -static int seq_show(struct dfs_seq_file *seq, void *data) -{ - /* data: The return value of the start or next*/ - dfs_seq_puts(seq, "todo\n"); - - return 0; -} - -static const struct dfs_seq_ops seq_ops = { - .start = seq_start, - .stop = seq_stop, - .next = seq_next, - .show = seq_show, -}; - -void proc_tty_register_driver(void *driver) -{ - //todo -} - -void proc_tty_unregister_driver(void *driver) -{ - //todo -} - -int proc_tty_init(void) -{ - struct proc_dentry *dentry; - - dentry = proc_mkdir("tty", NULL); - if (!dentry) - return -1; - - proc_release(dentry); - - dentry = proc_mkdir("tty/ldisc", NULL); - proc_release(dentry); - - dentry = proc_mkdir_mode("tty/driver", S_IRUSR|S_IXUSR, NULL); - proc_release(dentry); - - dentry = proc_create_data("tty/ldiscs", 0, NULL, NULL, NULL); - if (dentry) - { - dentry->seq_ops = &seq_ops; - } - proc_release(dentry); - - dentry = proc_create_data("tty/drivers", 0, NULL, NULL, NULL); - if (dentry) - { - dentry->seq_ops = &seq_ops; - } - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_tty_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_uptime.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_uptime.c deleted file mode 100644 index f16ab72..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_uptime.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include - - -static int single_show(struct dfs_seq_file *seq, void *data) -{ - dfs_seq_printf(seq, "%lu.%02lu %lu.%02lu\n", - (unsigned long)rt_tick_get_millisecond() / 1000, (unsigned long)(rt_tick_get_millisecond() % 1000) / 100, - (unsigned long)rt_tick_get_millisecond() / 1000, (unsigned long)(rt_tick_get_millisecond() % 1000) / 100); - - return 0; -} - -int proc_uptime_init(void) -{ - struct proc_dentry *dentry = proc_create_single_data("uptime", 0, NULL, single_show, NULL); - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_uptime_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_version.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_version.c deleted file mode 100644 index 1ca8035..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/proc_version.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include "proc.h" -#include "procfs.h" - -#include -#include - -#include -#include - -#include - - -static int single_show(struct dfs_seq_file *seq, void *data) -{ - dfs_seq_puts(seq, "\n \\ | /\n"); -#ifdef RT_USING_SMART - dfs_seq_puts(seq, "- RT - Thread Smart Operating System\n"); -#else - dfs_seq_puts(seq, "- RT - Thread Operating System\n"); -#endif - dfs_seq_printf(seq, " / | \\ %d.%d.%d build %s %s\n", - (rt_int32_t)RT_VERSION_MAJOR, (rt_int32_t)RT_VERSION_MINOR, (rt_int32_t)RT_VERSION_PATCH, - __DATE__, __TIME__); - dfs_seq_puts(seq, " 2006 - 2022 Copyright by RT-Thread team\n"); - - return 0; -} - -int proc_version_init(void) -{ - struct proc_dentry *dentry = proc_create_single_data("version", 0, NULL, single_show, NULL); - proc_release(dentry); - - return 0; -} -INIT_ENV_EXPORT(proc_version_init); diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/procfs.c b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/procfs.c deleted file mode 100644 index c8b5c14..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/procfs.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "proc.h" -#include "procfs.h" - -#define PROC_DEBUG(...) //rt_kprintf - -static int dfs_procfs_open(struct dfs_file *file) -{ - rt_err_t ret = RT_EOK; - struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data; - - - RT_ASSERT(file->ref_count > 0); - - // this file is opened and in an fdtable - if (file->ref_count > 1) - { - file->fpos = 0; - return ret; - } - - if (entry->fops && entry->fops->open) - { - ret = entry->fops->open(file); - } - - PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret); - - return ret; -} - -static int dfs_procfs_close(struct dfs_file *file) -{ - rt_err_t ret = RT_EOK; - struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data; - - RT_ASSERT(file->vnode->ref_count > 0); - if (file->vnode->ref_count > 1) - { - return ret; - } - - if (entry && entry->fops && entry->fops->close) - { - ret = entry->fops->close(file); - } - - PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret); - - return ret; -} - -static ssize_t dfs_procfs_read(struct dfs_file *file, void *buf, size_t count, off_t *pos) -{ - ssize_t ret = -RT_ERROR; - struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data; - - if (entry && entry->fops && entry->fops->read) - { - ret = entry->fops->read(file, buf, count, pos); - } - - PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret); - - return ret; -} - -static ssize_t dfs_procfs_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos) -{ - ssize_t ret = -RT_ERROR; - struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data; - - if (entry && entry->fops && entry->fops->write) - { - ret = entry->fops->write(file, buf, count, pos); - } - - PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret); - - return ret; -} - -static int dfs_procfs_ioctl(struct dfs_file *file, int cmd, void *args) -{ - int ret = -RT_ERROR; - struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data; - - if (entry && entry->fops && entry->fops->ioctl) - { - ret = entry->fops->ioctl(file, cmd, args); - } - - PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret); - - return ret; -} - -static int dfs_procfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count) -{ - int ret = 0; - rt_uint32_t index = 0; - struct dirent *d; - struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data; - - if (entry) - { - struct proc_dentry *iter = RT_NULL, *tmp; - - /* make integer count */ - count = (count / sizeof(struct dirent)); - if (count == 0) - { - return -EINVAL; - } - - dfs_vfs_for_each_subnode(iter, tmp, entry, node) - { - if (iter == RT_NULL) - { - break; - } - - if (index >= file->fpos) - { - d = dirp + index - file->fpos; - - if (S_ISDIR(entry->mode)) - { - d->d_type = DT_DIR; - } - else if (S_ISLNK(entry->mode)) - { - d->d_type = DT_SYMLINK; - } - else - { - d->d_type = DT_REG; - } - - d->d_namlen = rt_strlen(iter->name); - d->d_reclen = (rt_uint16_t)sizeof(struct dirent); - rt_strncpy(d->d_name, iter->name, rt_strlen(iter->name) + 1); - - ret ++; - } - - index++; - if (index - file->fpos >= count) - { - break; - } - } - - if (ret > 0) - { - file->fpos = index; - } - - if (entry->fops && entry->fops->getdents && ret < count) - { - int r; - - file->fpos -= index; - - r = entry->fops->getdents(file, dirp + ret, (count - ret) * sizeof(struct dirent)); - - ret = ret * sizeof(struct dirent); - - if (r > 0) - { - ret += r; - } - - file->fpos += index; - } - else - { - ret = ret * sizeof(struct dirent); - } - } - - PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret); - - return ret; -} - -static int dfs_procfs_poll(struct dfs_file *file, struct rt_pollreq *req) -{ - int ret = -RT_ERROR; - struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data; - - if (entry && entry->fops && entry->fops->poll) - { - ret = entry->fops->poll(file, req); - } - - PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret); - - return ret; -} - -static int dfs_procfs_flush(struct dfs_file *file) -{ - int ret = -RT_ERROR; - struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data; - - if (entry && entry->fops && entry->fops->flush) - { - ret = entry->fops->flush(file); - } - - PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret); - - return ret; -} - -static int dfs_procfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data) -{ - RT_ASSERT(mnt != RT_NULL); - - return RT_EOK; -} - -static int dfs_procfs_umount(struct dfs_mnt *mnt) -{ - RT_ASSERT(mnt != RT_NULL); - - return RT_EOK; -} - -static int dfs_procfs_readlink(struct dfs_dentry *dentry, char *buf, int len) -{ - int ret = 0; - struct proc_dentry *entry = dfs_proc_find(dentry->pathname); - - if (entry) - { - if (S_ISLNK(entry->mode) && entry->data) - { - if (entry->ops && entry->ops->readlink) - { - ret = entry->ops->readlink(entry, buf, len); - } - else - { - rt_strncpy(buf, (const char *)entry->data, len); - buf[len - 1] = '\0'; - ret = rt_strlen(buf); - } - } - - proc_release(entry); - } - - PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, dentry->pathname, ret); - - return ret; -} - -static int dfs_procfs_unlink(struct dfs_dentry *dentry) -{ - PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, dentry->pathname, -1); - return -RT_ERROR; -} - -static int dfs_procfs_stat(struct dfs_dentry *dentry, struct stat *st) -{ - int ret = RT_EOK; - struct dfs_vnode *vnode; - - if (dentry && dentry->vnode) - { - vnode = dentry->vnode; - - st->st_dev = (dev_t)(dentry->mnt->dev_id); - st->st_ino = (ino_t)dfs_dentry_full_path_crc32(dentry); - - st->st_gid = vnode->gid; - st->st_uid = vnode->uid; - st->st_mode = vnode->mode; - st->st_nlink = vnode->nlink; - st->st_size = vnode->size; - st->st_mtim.tv_nsec = vnode->mtime.tv_nsec; - st->st_mtim.tv_sec = vnode->mtime.tv_sec; - st->st_ctim.tv_nsec = vnode->ctime.tv_nsec; - st->st_ctim.tv_sec = vnode->ctime.tv_sec; - st->st_atim.tv_nsec = vnode->atime.tv_nsec; - st->st_atim.tv_sec = vnode->atime.tv_sec; - } - - PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, dentry->pathname, ret); - - return ret; -} - -static int dfs_procfs_statfs(struct dfs_mnt *mnt, struct statfs *buf) -{ - if (mnt && buf) - { - buf->f_bsize = 512; - buf->f_blocks = 2048 * 64; // 64M - buf->f_bfree = buf->f_blocks; - buf->f_bavail = buf->f_bfree; - } - - PROC_DEBUG(" %s %d\n", __func__, __LINE__); - - return RT_EOK; -} - -static struct dfs_vnode *dfs_procfs_lookup(struct dfs_dentry *dentry) -{ - struct dfs_vnode *vnode = RT_NULL; - struct proc_dentry *entry = dfs_proc_find(dentry->pathname); - - if (entry) - { - vnode = dfs_vnode_create(); - if (vnode) - { - vnode->nlink = 1; - vnode->size = 0; - if (S_ISDIR(entry->mode)) - { - vnode->mode = entry->mode; - vnode->type = FT_DIRECTORY; - } - else if (S_ISLNK(entry->mode)) - { - vnode->mode = entry->mode; - vnode->type = FT_SYMLINK; - } - else - { - vnode->mode = entry->mode; - vnode->type = FT_REGULAR; - } - - vnode->data = entry; - vnode->mnt = dentry->mnt; - } - - proc_release(entry); - } - - PROC_DEBUG(" %s %d >> %s\n", __func__, __LINE__, dentry->pathname); - - return vnode; -} - -static struct dfs_vnode *dfs_procfs_create_vnode(struct dfs_dentry *dentry, int type, mode_t mode) -{ - return RT_NULL; -} - -static int dfs_procfs_free_vnode(struct dfs_vnode *vnode) -{ - return 0; -} - -static const struct dfs_file_ops _procfs_fops = -{ - .open = dfs_procfs_open, - .close = dfs_procfs_close, - .lseek = generic_dfs_lseek, - .read = dfs_procfs_read, - .write = dfs_procfs_write, - .ioctl = dfs_procfs_ioctl, - .getdents = dfs_procfs_getdents, - .poll = dfs_procfs_poll, - .flush = dfs_procfs_flush, -}; - -static const struct dfs_filesystem_ops _procfs_ops = -{ - .name = "procfs", - - .default_fops = &_procfs_fops, - - .mount = dfs_procfs_mount, - .umount = dfs_procfs_umount, - .readlink = dfs_procfs_readlink, - .unlink = dfs_procfs_unlink, - .stat = dfs_procfs_stat, - .statfs = dfs_procfs_statfs, - .lookup = dfs_procfs_lookup, - .create_vnode = dfs_procfs_create_vnode, - .free_vnode = dfs_procfs_free_vnode, -}; - -static struct dfs_filesystem_type _procfs = -{ - .fs_ops = &_procfs_ops, -}; - -int dfs_procfs_init(void) -{ - /* register procfs file system */ - dfs_register(&_procfs); - - return 0; -} -INIT_COMPONENT_EXPORT(dfs_procfs_init); - -int proc_read_data(struct dfs_file *file, void *buf, size_t count, off_t *pos) -{ - if (file->fpos >= file->vnode->size) - { - return 0; - } - - if (file->data) - { - count = file->vnode->size - file->fpos >= count ? count : file->vnode->size - file->fpos; - rt_strncpy(buf, file->data + file->fpos, count); - - file->fpos += count; - *pos = file->fpos; - } - else - { - return 0; - } - - return count; -} diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/procfs.h b/rt-thread/components/dfs/dfs_v2/filesystems/procfs/procfs.h deleted file mode 100644 index 6e921ae..0000000 --- a/rt-thread/components/dfs/dfs_v2/filesystems/procfs/procfs.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#ifndef __PROC_FS_H__ -#define __PROC_FS_H__ - -#include - -int dfs_procfs_init(void); - -int proc_read_data(struct dfs_file *file, void *buf, size_t count, off_t *pos); - -#endif diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/ptyfs/ptyfs.c b/rt-thread/components/dfs/dfs_v2/filesystems/ptyfs/ptyfs.c index 75bffdf..c6f4f3d 100644 --- a/rt-thread/components/dfs/dfs_v2/filesystems/ptyfs/ptyfs.c +++ b/rt-thread/components/dfs/dfs_v2/filesystems/ptyfs/ptyfs.c @@ -262,7 +262,7 @@ ptsno_t ptyfs_register_pts(rt_device_t ptmx, rt_device_t pts) pts_file = rt_calloc(1, sizeof(struct ptyfs_file)); if (pts_file) { - snprintf(pts_file->basename, DIRENT_NAME_MAX, "%lu", (unsigned long)rc); + snprintf(pts_file->basename, DIRENT_NAME_MAX, "%lu", rc); ptyfile_init(pts_file, sb, 0, PTYFS_TYPE_FILE_SLAVE, PTS_DEFAULT_FILE_MODE, pts); ptyfile_add_to_root(sb, pts_file); @@ -296,7 +296,7 @@ rt_err_t ptyfs_unregister_pts(rt_device_t ptmx, ptsno_t ptsno) else { /* get path and findout device */ - snprintf(path_buf, sizeof(path_buf), "%lu", (unsigned long)ptsno); + snprintf(path_buf, sizeof(path_buf), "%lu", ptsno); pts_file = ptyfile_lookup(sb, path_buf); if (pts_file) { diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/romfs/dfs_romfs.c b/rt-thread/components/dfs/dfs_v2/filesystems/romfs/dfs_romfs.c index 6350ad7..7cb30b3 100644 --- a/rt-thread/components/dfs/dfs_v2/filesystems/romfs/dfs_romfs.c +++ b/rt-thread/components/dfs/dfs_v2/filesystems/romfs/dfs_romfs.c @@ -365,7 +365,6 @@ static const struct dfs_file_ops _rom_fops = { .open = dfs_romfs_open, .close = dfs_romfs_close, - .ioctl = dfs_romfs_ioctl, .lseek = generic_dfs_lseek, .read = dfs_romfs_read, .getdents = dfs_romfs_getdents, diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c b/rt-thread/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c index c1ff4a1..1c2a509 100644 --- a/rt-thread/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c +++ b/rt-thread/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c @@ -99,13 +99,15 @@ static int _get_subdir(const char *path, char *name) static int _free_subdir(struct tmpfs_file *dfile) { - struct tmpfs_file *file = RT_NULL, *tmp; + struct tmpfs_file *file; + rt_list_t *list, *temp_list; struct tmpfs_sb *superblock; RT_ASSERT(dfile->type == TMPFS_TYPE_DIR); - dfs_vfs_for_each_subnode(file, tmp, dfile, node) + rt_list_for_each_safe(list, temp_list, &dfile->subdirs) { + file = rt_list_entry(list, struct tmpfs_file, sibling); if (file->type == TMPFS_TYPE_DIR) { _free_subdir(file); @@ -120,7 +122,7 @@ static int _free_subdir(struct tmpfs_file *dfile) RT_ASSERT(superblock != NULL); rt_spin_lock(&superblock->lock); - dfs_vfs_remove_node(&file->node); + rt_list_remove(&(file->sibling)); rt_spin_unlock(&superblock->lock); rt_free(file); @@ -139,11 +141,13 @@ static int dfs_tmpfs_mount(struct dfs_mnt *mnt, { superblock->df_size = sizeof(struct tmpfs_sb); superblock->magic = TMPFS_MAGIC; + rt_list_init(&superblock->sibling); superblock->root.name[0] = '/'; superblock->root.sb = superblock; superblock->root.type = TMPFS_TYPE_DIR; - dfs_vfs_init_node(&superblock->root.node); + rt_list_init(&superblock->root.sibling); + rt_list_init(&superblock->root.subdirs); rt_spin_lock_init(&superblock->lock); @@ -232,7 +236,8 @@ struct tmpfs_file *dfs_tmpfs_lookup(struct tmpfs_sb *superblock, { const char *subpath, *curpath, *filename = RT_NULL; char subdir_name[TMPFS_NAME_MAX]; - struct tmpfs_file *file, *curfile, *tmp; + struct tmpfs_file *file, *curfile; + rt_list_t *list; subpath = path; while (*subpath == '/' && *subpath) @@ -260,8 +265,9 @@ find_subpath: rt_spin_lock(&superblock->lock); - dfs_vfs_for_each_subnode(file, tmp, curfile, node) + rt_list_for_each(list, &curfile->subdirs) { + file = rt_list_entry(list, struct tmpfs_file, sibling); if (filename) /* find file */ { if (rt_strcmp(file->name, filename) == 0) @@ -497,7 +503,8 @@ static int dfs_tmpfs_getdents(struct dfs_file *file, { rt_size_t index, end; struct dirent *d; - struct tmpfs_file *d_file, *n_file, *tmp; + struct tmpfs_file *d_file, *n_file; + rt_list_t *list; struct tmpfs_sb *superblock; d_file = (struct tmpfs_file *)file->vnode->data; @@ -520,8 +527,9 @@ static int dfs_tmpfs_getdents(struct dfs_file *file, index = 0; count = 0; - dfs_vfs_for_each_subnode(n_file, tmp, d_file, node) + rt_list_for_each(list, &d_file->subdirs) { + n_file = rt_list_entry(list, struct tmpfs_file, sibling); if (index >= (rt_size_t)file->fpos) { d = dirp + count; @@ -565,7 +573,7 @@ static int dfs_tmpfs_unlink(struct dfs_dentry *dentry) return -ENOENT; rt_spin_lock(&superblock->lock); - dfs_vfs_remove_node(&d_file->node); + rt_list_remove(&(d_file->sibling)); rt_spin_unlock(&superblock->lock); if (rt_atomic_load(&(dentry->ref_count)) == 1) @@ -623,13 +631,13 @@ static int dfs_tmpfs_rename(struct dfs_dentry *old_dentry, struct dfs_dentry *ne RT_ASSERT(p_file != NULL); rt_spin_lock(&superblock->lock); - dfs_vfs_remove_node(&d_file->node); + rt_list_remove(&(d_file->sibling)); rt_spin_unlock(&superblock->lock); strncpy(d_file->name, file_name, TMPFS_NAME_MAX); rt_spin_lock(&superblock->lock); - dfs_vfs_append_node(&p_file->node, &d_file->node); + rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling)); rt_spin_unlock(&superblock->lock); rt_free(parent_path); @@ -737,7 +745,8 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t strncpy(d_file->name, file_name, TMPFS_NAME_MAX); - dfs_vfs_init_node(&d_file->node); + rt_list_init(&(d_file->subdirs)); + rt_list_init(&(d_file->sibling)); d_file->data = NULL; d_file->size = 0; d_file->sb = superblock; @@ -758,7 +767,7 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t #endif } rt_spin_lock(&superblock->lock); - dfs_vfs_append_node(&p_file->node, &d_file->node); + rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling)); rt_spin_unlock(&superblock->lock); vnode->mnt = dentry->mnt; diff --git a/rt-thread/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h b/rt-thread/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h index 8f822c6..365f1e0 100644 --- a/rt-thread/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h +++ b/rt-thread/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h @@ -12,7 +12,6 @@ #define __DFS_TMPFS_H__ #include -#include #define TMPFS_NAME_MAX 32 #define TMPFS_MAGIC 0x0B0B0B0B @@ -26,7 +25,8 @@ struct tmpfs_file { rt_uint32_t type; /* file type */ char name[TMPFS_NAME_MAX]; /* file name */ - struct dfs_vfs_node node; /* file node in the tmpfs */ + rt_list_t subdirs; /* file subdir list */ + rt_list_t sibling; /* file sibling list */ struct tmpfs_sb *sb; /* superblock ptr */ rt_uint8_t *data; /* file date ptr */ rt_size_t size; /* file size */ diff --git a/rt-thread/components/dfs/dfs_v2/include/dfs_fs.h b/rt-thread/components/dfs/dfs_v2/include/dfs_fs.h index dcf2fa2..d30967a 100644 --- a/rt-thread/components/dfs/dfs_v2/include/dfs_fs.h +++ b/rt-thread/components/dfs/dfs_v2/include/dfs_fs.h @@ -20,38 +20,6 @@ extern "C" { #endif -#define MS_RDONLY 1 -#define MS_NOSUID 2 -#define MS_NODEV 4 -#define MS_NOEXEC 8 -#define MS_SYNCHRONOUS 16 -#define MS_REMOUNT 32 -#define MS_MANDLOCK 64 -#define MS_DIRSYNC 128 -#define MS_NOATIME 1024 -#define MS_NODIRATIME 2048 -#define MS_BIND 4096 -#define MS_MOVE 8192 -#define MS_REC 16384 -#define MS_SILENT 32768 -#define MS_POSIXACL (1<<16) -#define MS_UNBINDABLE (1<<17) -#define MS_PRIVATE (1<<18) -#define MS_SLAVE (1<<19) -#define MS_SHARED (1<<20) -#define MS_RELATIME (1<<21) -#define MS_KERNMOUNT (1<<22) -#define MS_I_VERSION (1<<23) -#define MS_STRICTATIME (1<<24) -#define MS_LAZYTIME (1<<25) -#define MS_NOREMOTELOCK (1<<27) -#define MS_NOSEC (1<<28) -#define MS_BORN (1<<29) -#define MS_ACTIVE (1<<30) -#define MS_NOUSER (1U<<31) - -#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|MS_LAZYTIME) - /* file system partition table */ struct dfs_partition { @@ -119,7 +87,6 @@ int dfs_unregister(struct dfs_filesystem_type *fs); int dfs_register(struct dfs_filesystem_type *fs); const char *dfs_filesystem_get_mounted_path(struct rt_device *device); -int dfs_remount(const char *path, rt_ubase_t flags, void *data); int dfs_mount(const char *device_name, const char *path, const char *filesystemtype, diff --git a/rt-thread/components/dfs/dfs_v2/include/dfs_mnt.h b/rt-thread/components/dfs/dfs_v2/include/dfs_mnt.h index da99ec2..207c9b6 100644 --- a/rt-thread/components/dfs/dfs_v2/include/dfs_mnt.h +++ b/rt-thread/components/dfs/dfs_v2/include/dfs_mnt.h @@ -39,8 +39,6 @@ struct dfs_mnt #define MNT_IS_UMOUNT 0x8 /* the mnt is unmount */ #define MNT_IS_LOCKED 0x10 /* the mnt is locked */ #define MNT_FORCE 0x20 /* the mnt force unmount */ -#define MNT_LAZY_UMNT 0x40 /* the mnt has pending umount */ -#define MNT_RDONLY 0x80 /* the mnt is read only */ rt_atomic_t ref_count; /* reference count */ @@ -62,16 +60,9 @@ const char *dfs_mnt_get_mounted_path(struct rt_device *device); struct dfs_mnt* dfs_mnt_ref(struct dfs_mnt* mnt); int dfs_mnt_unref(struct dfs_mnt* mnt); -int dfs_mnt_umount(struct dfs_mnt *mnt, int flags); -int dfs_mnt_setflags(struct dfs_mnt *mnt, int flags); - rt_bool_t dfs_mnt_has_child_mnt(struct dfs_mnt *mnt, const char* fullpath); int dfs_mnt_foreach(struct dfs_mnt* (*func)(struct dfs_mnt *mnt, void *parameter), void *parameter); -int dfs_mnt_umount_iter(rt_bool_t (*filter)(struct dfs_mnt *mnt, void *parameter), void *parameter); - -typedef void (*dfs_mnt_umnt_cb_t)(struct dfs_mnt *mnt); -RT_OBJECT_HOOKLIST_DECLARE(dfs_mnt_umnt_cb_t, dfs_mnt_umnt); #ifdef __cplusplus } diff --git a/rt-thread/components/dfs/dfs_v2/include/dfs_pcache.h b/rt-thread/components/dfs/dfs_v2/include/dfs_pcache.h index 5452196..01abfe3 100644 --- a/rt-thread/components/dfs/dfs_v2/include/dfs_pcache.h +++ b/rt-thread/components/dfs/dfs_v2/include/dfs_pcache.h @@ -118,7 +118,6 @@ int dfs_aspace_mmap_write(struct dfs_file *file, struct rt_varea *varea, void *d void dfs_pcache_release(size_t count); void dfs_pcache_unmount(struct dfs_mnt *mnt); -void dfs_pcache_clean(struct dfs_mnt *mnt); #ifdef __cplusplus } diff --git a/rt-thread/components/dfs/dfs_v2/include/dfs_seq_file.h b/rt-thread/components/dfs/dfs_v2/include/dfs_seq_file.h index f0c1de7..6dbc30f 100644 --- a/rt-thread/components/dfs/dfs_v2/include/dfs_seq_file.h +++ b/rt-thread/components/dfs/dfs_v2/include/dfs_seq_file.h @@ -56,7 +56,7 @@ static inline void dfs_seq_setwidth(struct dfs_seq_file *seq, size_t size) int dfs_seq_open(struct dfs_file *file, const struct dfs_seq_ops *ops); ssize_t dfs_seq_read(struct dfs_file *file, void *buf, size_t size, off_t *pos); -off_t dfs_seq_lseek(struct dfs_file *file, off_t offset, int whence); +ssize_t dfs_seq_lseek(struct dfs_file *file, off_t offset, int whence); int dfs_seq_release(struct dfs_file *file); int dfs_seq_write(struct dfs_seq_file *seq, const void *data, size_t len); diff --git a/rt-thread/components/dfs/dfs_v2/include/dfs_vfs.h b/rt-thread/components/dfs/dfs_v2/include/dfs_vfs.h deleted file mode 100644 index 3674192..0000000 --- a/rt-thread/components/dfs/dfs_v2/include/dfs_vfs.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#ifndef __DFS_VFS_H__ -#define __DFS_VFS_H__ - -#include "dfs_file.h" -#include "dfs_fs.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -struct dfs_vfs_node -{ - rt_list_t subnode; /* file subnode list */ - rt_list_t sibling; /* file sibling list */ -}; - -rt_inline void dfs_vfs_init_node(struct dfs_vfs_node *node) -{ - rt_list_init(&node->subnode); - rt_list_init(&node->sibling); -} - -rt_inline void dfs_vfs_append_node(struct dfs_vfs_node *dir, struct dfs_vfs_node *node) -{ - rt_list_insert_after(&(dir->subnode), &(node->sibling)); -} - -rt_inline void dfs_vfs_remove_node(struct dfs_vfs_node *node) -{ - rt_list_remove(&(node->sibling)); -} - -#define dfs_vfs_for_each_subnode(node, tmp, dir, member) \ - rt_list_for_each_entry_safe(node, tmp, &dir->member.subnode, member.sibling) - -#ifdef __cplusplus -} -#endif - -#endif /*__DFS_VFS_H__*/ diff --git a/rt-thread/components/dfs/dfs_v2/src/dfs.c b/rt-thread/components/dfs/dfs_v2/src/dfs.c index 527ba89..939e4dd 100644 --- a/rt-thread/components/dfs/dfs_v2/src/dfs.c +++ b/rt-thread/components/dfs/dfs_v2/src/dfs.c @@ -537,7 +537,6 @@ int dfs_dup(int oldfd, int startfd) fdt = dfs_fdtable_get(); if ((oldfd < 0) || (oldfd >= fdt->maxfd)) { - rt_set_errno(-EBADF); goto exit; } if (!fdt->fds[oldfd]) @@ -669,17 +668,12 @@ sysret_t sys_dup(int oldfd) int sys_dup(int oldfd) #endif { - int err = 0; int newfd = dfs_dup(oldfd, (dfs_fdtable_get() == &_fdtab) ? DFS_STDIO_OFFSET : 0); - if(newfd < 0) - { - err = rt_get_errno(); - } #ifdef RT_USING_SMART - return err < 0 ? err : newfd; + return (sysret_t)newfd; #else - return err < 0 ? err : newfd; + return newfd; #endif } diff --git a/rt-thread/components/dfs/dfs_v2/src/dfs_file.c b/rt-thread/components/dfs/dfs_v2/src/dfs_file.c index 57ff2e9..53e110e 100644 --- a/rt-thread/components/dfs/dfs_v2/src/dfs_file.c +++ b/rt-thread/components/dfs/dfs_v2/src/dfs_file.c @@ -1379,7 +1379,6 @@ int dfs_file_link(const char *oldname, const char *newname) if (dfs_file_isdir(oldname) == 0) { - rt_set_errno(-EPERM); return ret; } @@ -1568,10 +1567,6 @@ int dfs_file_symlink(const char *target, const char *linkpath) rt_free(parent); } } - else - { - rt_set_errno(-EPERM); - } if (fullpath != linkpath) rt_free(fullpath); diff --git a/rt-thread/components/dfs/dfs_v2/src/dfs_fs.c b/rt-thread/components/dfs/dfs_v2/src/dfs_fs.c index ee077cd..e65ccee 100644 --- a/rt-thread/components/dfs/dfs_v2/src/dfs_fs.c +++ b/rt-thread/components/dfs/dfs_v2/src/dfs_fs.c @@ -95,52 +95,6 @@ int dfs_unregister(struct dfs_filesystem_type *fs) return ret; } -#define REMNT_UNSUPP_FLAGS (~(MS_REMOUNT | MS_RMT_MASK)) -int dfs_remount(const char *path, rt_ubase_t flags, void *data) -{ - int rc = 0; - char *fullpath = RT_NULL; - struct dfs_mnt *mnt = RT_NULL; - - if (flags & REMNT_UNSUPP_FLAGS) - { - return -EINVAL; - } - - fullpath = dfs_normalize_path(RT_NULL, path); - if (!fullpath) - { - rc = -ENOENT; - } - else - { - DLOG(msg, "dfs", "mnt", DLOG_MSG, "mnt = dfs_mnt_lookup(%s)", fullpath); - mnt = dfs_mnt_lookup(fullpath); - if (mnt) - { - dfs_lock(); - dfs_mnt_setflags(mnt, flags); - dfs_unlock(); - } - else - { - struct stat buf = {0}; - if (dfs_file_stat(fullpath, &buf) == 0 && S_ISBLK(buf.st_mode)) - { - /* path was not already mounted on target */ - rc = -EINVAL; - } - else - { - /* path is not a directory */ - rc = -ENOTDIR; - } - } - } - - return rc; -} - /* * parent(mount path) * mnt_parent <- - - - - - - + @@ -173,7 +127,7 @@ int dfs_mount(const char *device_name, } else { - rt_set_errno(ENODEV); + rt_set_errno(ENOENT); ret = -1; } @@ -346,7 +300,7 @@ int dfs_mount(const char *device_name, int dfs_umount(const char *specialfile, int flags) { - int ret = -1; + int ret = -RT_ERROR; char *fullpath = RT_NULL; struct dfs_mnt *mnt = RT_NULL; @@ -360,7 +314,7 @@ int dfs_umount(const char *specialfile, int flags) if (strcmp(mnt->fullpath, fullpath) == 0) { /* is the mount point */ - rt_base_t ref_count = rt_atomic_load(&(mnt->ref_count)); + rt_atomic_t ref_count = rt_atomic_load(&(mnt->ref_count)); if (!(mnt->flags & MNT_IS_LOCKED) && rt_list_isempty(&mnt->child) && (ref_count == 1 || (flags & MNT_FORCE))) { @@ -373,19 +327,17 @@ int dfs_umount(const char *specialfile, int flags) } else { - LOG_I("the file system is busy!"); - ret = -EBUSY; + LOG_E("the file system is busy!"); } } else { - LOG_I("the path:%s is not a mountpoint!", fullpath); - ret = -EINVAL; + LOG_E("the path:%s is not a mountpoint!", fullpath); } } else { - LOG_I("no filesystem found."); + LOG_E("no filesystem found."); } rt_free(fullpath); } diff --git a/rt-thread/components/dfs/dfs_v2/src/dfs_mnt.c b/rt-thread/components/dfs/dfs_v2/src/dfs_mnt.c index a207072..4ad73c6 100644 --- a/rt-thread/components/dfs/dfs_v2/src/dfs_mnt.c +++ b/rt-thread/components/dfs/dfs_v2/src/dfs_mnt.c @@ -10,21 +10,17 @@ #include +#include "dfs.h" +#include "dfs_mnt.h" +#include "dfs_dentry.h" #include "dfs_private.h" -#include -#include -#include -#include - #define DBG_TAG "DFS.mnt" #define DBG_LVL DBG_WARNING #include static struct dfs_mnt *_root_mnt = RT_NULL; -RT_OBJECT_HOOKLIST_DEFINE(dfs_mnt_umnt); - /* * mnt tree structure * @@ -79,7 +75,6 @@ int dfs_mnt_insert(struct dfs_mnt* mnt, struct dfs_mnt* child) child = _root_mnt; rt_atomic_sub(&(_root_mnt->parent->ref_count), 1); rt_atomic_sub(&(_root_mnt->ref_count), 1); - _root_mnt->flags &= ~MNT_IS_LOCKED; _root_mnt = dfs_mnt_ref(mnt); mnt->parent = dfs_mnt_ref(mnt); @@ -247,24 +242,21 @@ struct dfs_mnt* dfs_mnt_ref(struct dfs_mnt* mnt) return mnt; } -int dfs_mnt_unref(struct dfs_mnt *mnt) +int dfs_mnt_unref(struct dfs_mnt* mnt) { rt_err_t ret = RT_EOK; - rt_base_t ref_count; if (mnt) { - ref_count = rt_atomic_sub(&(mnt->ref_count), 1) - 1; + rt_atomic_sub(&(mnt->ref_count), 1); - if (ref_count == 0) + if (rt_atomic_load(&(mnt->ref_count)) == 0) { dfs_lock(); if (mnt->flags & MNT_IS_UMOUNT) { mnt->fs_ops->umount(mnt); - - RT_OBJECT_HOOKLIST_CALL(dfs_mnt_umnt, (mnt)); } /* free full path */ @@ -286,21 +278,6 @@ int dfs_mnt_unref(struct dfs_mnt *mnt) return ret; } -int dfs_mnt_setflags(struct dfs_mnt *mnt, int flags) -{ - int error = 0; - - if (flags & MS_RDONLY) - { - mnt->flags |= MNT_RDONLY; -#ifdef RT_USING_PAGECACHE - dfs_pcache_clean(mnt); -#endif - } - - return error; -} - int dfs_mnt_destroy(struct dfs_mnt* mnt) { rt_err_t ret = RT_EOK; diff --git a/rt-thread/components/dfs/dfs_v2/src/dfs_pcache.c b/rt-thread/components/dfs/dfs_v2/src/dfs_pcache.c index cba36d8..350ad1f 100644 --- a/rt-thread/components/dfs/dfs_v2/src/dfs_pcache.c +++ b/rt-thread/components/dfs/dfs_v2/src/dfs_pcache.c @@ -13,19 +13,17 @@ #define DBG_LVL DBG_WARNING #include -#include -#include -#include +#include "dfs_pcache.h" +#include "dfs_dentry.h" +#include "dfs_mnt.h" +#include "mm_page.h" +#include +#include #include #ifdef RT_USING_PAGECACHE -#include -#include -#include -#include - #ifndef RT_PAGECACHE_COUNT #define RT_PAGECACHE_COUNT 4096 #endif @@ -162,7 +160,7 @@ void dfs_pcache_release(size_t count) dfs_pcache_unlock(); } -static void _pcache_clean(struct dfs_mnt *mnt, int (*cb)(struct dfs_aspace *aspace)) +void dfs_pcache_unmount(struct dfs_mnt *mnt) { rt_list_t *node = RT_NULL; struct dfs_aspace *aspace = RT_NULL; @@ -177,7 +175,7 @@ static void _pcache_clean(struct dfs_mnt *mnt, int (*cb)(struct dfs_aspace *aspa if (aspace && aspace->mnt == mnt) { dfs_aspace_clean(aspace); - cb(aspace); + dfs_aspace_release(aspace); } } @@ -189,28 +187,13 @@ static void _pcache_clean(struct dfs_mnt *mnt, int (*cb)(struct dfs_aspace *aspa if (aspace && aspace->mnt == mnt) { dfs_aspace_clean(aspace); - cb(aspace); + dfs_aspace_release(aspace); } } dfs_pcache_unlock(); } -void dfs_pcache_unmount(struct dfs_mnt *mnt) -{ - _pcache_clean(mnt, dfs_aspace_release); -} - -static int _dummy_cb(struct dfs_aspace *mnt) -{ - return 0; -} - -void dfs_pcache_clean(struct dfs_mnt *mnt) -{ - _pcache_clean(mnt, _dummy_cb); -} - static int dfs_pcache_limit_check(void) { int index = 4; @@ -1155,21 +1138,14 @@ int dfs_aspace_write(struct dfs_file *file, const void *buf, size_t count, off_t if (file && file->vnode && file->vnode->aspace) { + if (!(file->vnode->aspace->ops->write)) + return ret; struct dfs_vnode *vnode = file->vnode; struct dfs_aspace *aspace = vnode->aspace; struct dfs_page *page; char *ptr = (char *)buf; - if (!(aspace->ops->write)) - { - return ret; - } - else if (aspace->mnt && (aspace->mnt->flags & MNT_RDONLY)) - { - return -EROFS; - } - ret = 0; while (count) @@ -1404,8 +1380,7 @@ int dfs_aspace_unmap(struct dfs_file *file, struct rt_varea *varea) rt_varea_unmap_page(map_varea, vaddr); - if (!rt_varea_is_private_locked(varea) && - page->fpos < page->aspace->vnode->size) + if (varea->attr == MMU_MAP_U_RWCB && page->fpos < page->aspace->vnode->size) { dfs_page_dirty(page); } @@ -1450,7 +1425,7 @@ int dfs_aspace_page_unmap(struct dfs_file *file, struct rt_varea *varea, void *v if (map && varea->aspace == map->aspace && vaddr == map->vaddr) { - if (!rt_varea_is_private_locked(varea)) + if (varea->attr == MMU_MAP_U_RWCB) { dfs_page_dirty(page); } diff --git a/rt-thread/components/dfs/dfs_v2/src/dfs_posix.c b/rt-thread/components/dfs/dfs_v2/src/dfs_posix.c index 38e17c3..ef6e8e7 100644 --- a/rt-thread/components/dfs/dfs_v2/src/dfs_posix.c +++ b/rt-thread/components/dfs/dfs_v2/src/dfs_posix.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -31,17 +31,7 @@ * return a file descriptor according specified flags. * * @param file the path name of file. - * @param flags the file open flags. Common values include: - * - Access modes (mutually exclusive): - * - `O_RDONLY`: Open for read-only access. - * - `O_WRONLY`: Open for write-only access. - * - `O_RDWR`: Open for both reading and writing. - * - File status flags (can be combined with bitwise OR `|`): - * - `O_CREAT`: Create the file if it does not exist. Requires a `mode` argument. - * - `O_TRUNC`: Truncate the file to zero length if it already exists. - * - `O_APPEND`: Append writes to the end of the file. - * - `O_EXCL`: Ensure that `O_CREAT` creates the file exclusively. - * - Other platform-specific flags + * @param flags the file open flags. * * @return the non-negative integer on successful open, others for failed. */ @@ -91,22 +81,6 @@ RTM_EXPORT(open); #ifndef AT_FDCWD #define AT_FDCWD (-100) #endif - -/** - * @brief Opens a file relative to a directory file descriptor. - * - * @param dirfd The file descriptor of the directory to base the relative path on. - * @param path The path to the file to be opened, relative to the directory specified by `dirfd`. - * Can be an absolute path (in which case `dirfd` is ignored). - * @param flag File access and status flags (e.g., `O_RDONLY`, `O_WRONLY`, `O_CREAT`). - * - * @return On success, returns a new file descriptor for the opened file. - * On failure, returns `-1` and sets `errno` to indicate the error. - * - * @note When using relative paths, ensure `dirfd` is a valid directory descriptor. - * When `pathname` is absolute, the `dirfd` argument is ignored. - * - */ int openat(int dirfd, const char *path, int flag, ...) { struct dfs_file *d; @@ -197,7 +171,7 @@ int utimensat(int __fd, const char *__path, const struct timespec __times[2], in } } - /*update time*/ + //update time attr.ia_valid = ATTR_ATIME_SET | ATTR_MTIME_SET; time(¤t_time); if (UTIME_NOW == __times[0].tv_nsec) @@ -400,22 +374,14 @@ ssize_t write(int fd, const void *buf, size_t len) RTM_EXPORT(write); /** - * this function is a POSIX compliant version, which will Reposition the file offset for + * this function is a POSIX compliant version, which will seek the offset for * an open file descriptor. * - * The `lseek` function sets the file offset for the file descriptor `fd` - * to a new value, determined by the `offset` and `whence` parameters. - * It can be used to seek to specific positions in a file for reading or writing. - * * @param fd the file descriptor. - * @param offset The offset, in bytes, to set the file position. - * The meaning of `offset` depends on the value of `whence`. - * @param whence the directive of seek. It can be one of: - * - `SEEK_SET`: Set the offset to `offset` bytes from the beginning of the file. - * - `SEEK_CUR`: Set the offset to its current location plus `offset` bytes. - * - `SEEK_END`: Set the offset to the size of the file plus `offset` bytes. + * @param offset the offset to be seeked. + * @param whence the directory of seek. * - * @return the resulting read/write position in the file, or -1 on failed. + * @return the current read/write position in the file, or -1 on failed. */ off_t lseek(int fd, off_t offset, int whence) { @@ -433,7 +399,7 @@ off_t lseek(int fd, off_t offset, int whence) result = dfs_file_lseek(file, offset, whence); if (result < 0) { - rt_set_errno(-EPERM); + rt_set_errno(result); return -1; } @@ -615,15 +581,9 @@ RTM_EXPORT(fsync); * control functions on devices. * * @param fildes the file description - * @param cmd the specified command, Common values include: - * - `F_DUPFD`: Duplicate a file descriptor. - * - `F_GETFD`: Get the file descriptor flags. - * - `F_SETFD`: Set the file descriptor flags. - * - `F_GETFL`: Get the file status flags. - * - `F_SETFL`: Set the file status flags. + * @param cmd the specified command * @param ... represents the additional information that is needed by this - * specific device to perform the requested function. For example: - * - When `cmd` is `F_SETFL`, an additional integer argument specifies the new status flags. + * specific device to perform the requested function. * * @return 0 on successful completion. Otherwise, -1 shall be returned and errno * set to indicate the error. @@ -805,7 +765,7 @@ RTM_EXPORT(fstatfs); * this function is a POSIX compliant version, which will make a directory * * @param path the directory path to be made. - * @param mode The permission mode for the new directory (unused here, can be set to 0). + * @param mode * * @return 0 on successful, others on failed. */ @@ -867,7 +827,7 @@ int rmdir(const char *pathname) if (!pathname) { - rt_set_errno(-EPERM); + rt_set_errno(-RT_ERROR); return -1; } @@ -892,7 +852,7 @@ int rmdir(const char *pathname) if (dirent) { - rt_set_errno(-EPERM); + rt_set_errno(-RT_ERROR); return -1; } } @@ -901,7 +861,7 @@ int rmdir(const char *pathname) { if (S_ISLNK(stat.st_mode)) { - rt_set_errno(-EPERM); + rt_set_errno(-RT_ERROR); return -1; } } diff --git a/rt-thread/components/dfs/dfs_v2/src/dfs_seq_file.c b/rt-thread/components/dfs/dfs_v2/src/dfs_seq_file.c index 2980b03..9521f53 100644 --- a/rt-thread/components/dfs/dfs_v2/src/dfs_seq_file.c +++ b/rt-thread/components/dfs/dfs_v2/src/dfs_seq_file.c @@ -256,7 +256,7 @@ Enomem: goto Done; } -off_t dfs_seq_lseek(struct dfs_file *file, off_t offset, int whence) +ssize_t dfs_seq_lseek(struct dfs_file *file, off_t offset, int whence) { struct dfs_seq_file *seq = file->data; off_t retval = -EINVAL; diff --git a/rt-thread/components/drivers/Kconfig b/rt-thread/components/drivers/Kconfig index 3ffa4c3..24856d5 100644 --- a/rt-thread/components/drivers/Kconfig +++ b/rt-thread/components/drivers/Kconfig @@ -21,21 +21,8 @@ rsource "touch/Kconfig" rsource "graphic/Kconfig" rsource "hwcrypto/Kconfig" rsource "wlan/Kconfig" -rsource "led/Kconfig" -rsource "mailbox/Kconfig" -rsource "phye/Kconfig" -rsource "ata/Kconfig" -rsource "nvme/Kconfig" -rsource "block/Kconfig" -rsource "scsi/Kconfig" -rsource "regulator/Kconfig" -rsource "reset/Kconfig" -rsource "thermal/Kconfig" rsource "virtio/Kconfig" -rsource "dma/Kconfig" -rsource "mfd/Kconfig" rsource "ofw/Kconfig" -rsource "pci/Kconfig" rsource "pic/Kconfig" rsource "pin/Kconfig" rsource "pinctrl/Kconfig" diff --git a/rt-thread/components/drivers/ata/Kconfig b/rt-thread/components/drivers/ata/Kconfig deleted file mode 100644 index 4b5cee5..0000000 --- a/rt-thread/components/drivers/ata/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -menuconfig RT_USING_ATA - bool "Using Advanced Technology Attachment (ATA) device drivers" - depends on RT_USING_DM - depends on RT_USING_BLK - depends on RT_USING_DMA - default n - -config RT_ATA_AHCI - bool "Advanced Host Controller Interface (AHCI)" - depends on RT_USING_ATA - depends on RT_USING_SCSI - default y - -config RT_ATA_AHCI_PCI - bool "AHCI support on PCI bus" - depends on RT_ATA_AHCI - depends on RT_USING_PCI - default n - -if RT_USING_ATA - osource "$(SOC_DM_ATA_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/ata/SConscript b/rt-thread/components/drivers/ata/SConscript deleted file mode 100644 index f4a0922..0000000 --- a/rt-thread/components/drivers/ata/SConscript +++ /dev/null @@ -1,21 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_USING_ATA']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../include'] - -src = [] - -if GetDepend(['RT_ATA_AHCI']): - src += ['ahci.c'] - - if GetDepend(['RT_ATA_AHCI_PCI']): - src += ['ahci-pci.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/ata/ahci-pci.c b/rt-thread/components/drivers/ata/ahci-pci.c deleted file mode 100644 index 0bbec3e..0000000 --- a/rt-thread/components/drivers/ata/ahci-pci.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#include -#include - -#define AHCI_REG_BAR 5 - -struct pci_ahci_quirk -{ - int bar_idx; - rt_bool_t bar_offset; - - const struct rt_ahci_ops *ops; -}; - -struct pci_ahci_host -{ - struct rt_ahci_host parent; - const struct pci_ahci_quirk *quirk; - - rt_bool_t is_msi; -}; - -#define raw_to_pci_ahci_host(raw) rt_container_of(raw, struct pci_ahci_host, parent) - -static rt_err_t pci_ahci_init(struct rt_ahci_host *host) -{ - struct rt_pci_device *pdev; - - pdev = rt_container_of(host->parent.dev, struct rt_pci_device, parent); - - if (pdev->vendor == PCI_VENDOR_ID_JMICRON) - { - rt_pci_write_config_u8(pdev, 0x41, 0xa1); - } - - return RT_EOK; -} - -static const struct rt_ahci_ops pci_ahci_ops = -{ - .host_init = pci_ahci_init, -}; - -static rt_err_t pci_ahci_intel_init(struct rt_ahci_host *host) -{ - rt_uint16_t val; - struct rt_pci_device *pdev; - - pdev = rt_container_of(host->parent.dev, struct rt_pci_device, parent); - - rt_pci_read_config_u16(pdev, 0x92, &val); - rt_pci_write_config_u16(pdev, 0x92, val & ~0xf); - - rt_thread_mdelay(10); - rt_pci_write_config_u16(pdev, 0x92, val | 0xf); - - return RT_EOK; -} - -static const struct rt_ahci_ops pci_ahci_intel_ops = -{ - .host_init = pci_ahci_intel_init, -}; - -static rt_err_t pci_ahci_probe(struct rt_pci_device *pdev) -{ - rt_err_t err; - int bar_idx; - struct rt_ahci_host *ahci; - struct pci_ahci_host *pci_ahci = rt_calloc(1, sizeof(*pci_ahci)); - const struct pci_ahci_quirk *quirk = pdev->id->data; - - if (!pci_ahci) - { - return -RT_ENOMEM; - } - - pci_ahci->quirk = quirk; - ahci = &pci_ahci->parent; - ahci->parent.dev = &pdev->parent; - - bar_idx = quirk && quirk->bar_offset ? quirk->bar_idx : AHCI_REG_BAR; - - ahci->regs = rt_pci_iomap(pdev, bar_idx); - - if (!ahci->regs) - { - err = -RT_EIO; - goto _fail; - } - - ahci->ops = quirk && quirk->ops ? quirk->ops : &pci_ahci_ops; - - if (rt_pci_msi_enable(pdev) > 0) - { - pci_ahci->is_msi = RT_TRUE; - } - else - { - rt_pci_irq_unmask(pdev); - } - ahci->irq = pdev->irq; - - rt_pci_set_master(pdev); - - if ((err = rt_ahci_host_register(ahci))) - { - goto _disable; - } - - pdev->parent.user_data = pci_ahci; - - return RT_EOK; - -_disable: - if (pci_ahci->is_msi) - { - rt_pci_msix_disable(pdev); - } - else - { - rt_pci_irq_mask(pdev); - } - rt_pci_clear_master(pdev); - rt_iounmap(ahci->regs); - -_fail: - rt_free(pci_ahci); - - return err; -} - -static rt_err_t pci_ahci_remove(struct rt_pci_device *pdev) -{ - struct rt_ahci_host *ahci; - struct pci_ahci_host *pci_ahci = pdev->parent.user_data; - - ahci = &pci_ahci->parent; - - rt_ahci_host_unregister(ahci); - - if (pci_ahci->is_msi) - { - rt_pci_msi_disable(pdev); - } - else - { - /* INTx is shared, don't mask all */ - rt_hw_interrupt_umask(pdev->irq); - rt_pci_irq_mask(pdev); - } - - rt_pci_clear_master(pdev); - - rt_iounmap(ahci->regs); - rt_free(pci_ahci); - - return RT_EOK; -} - -static rt_err_t pci_ahci_shutdown(struct rt_pci_device *pdev) -{ - return pci_ahci_remove(pdev); -} - -static struct pci_ahci_quirk intel_quirk = -{ - .ops = &pci_ahci_intel_ops, -}; - -static struct pci_ahci_quirk cavium_sata_quirk = -{ - .bar_idx = 0, - .bar_offset = RT_TRUE, -}; - -static const struct rt_pci_device_id pci_ahci_ids[] = -{ - { RT_PCI_DEVICE_ID(PCI_VENDOR_ID_INTEL, 0x2922), .data = &intel_quirk }, - { RT_PCI_DEVICE_ID(PCI_VENDOR_ID_ASMEDIA, 0x0611) }, - { RT_PCI_DEVICE_ID(PCI_VENDOR_ID_MARVELL, 0x6121) }, - { RT_PCI_DEVICE_ID(PCI_VENDOR_ID_MARVELL, 0x6145) }, - { RT_PCI_DEVICE_ID(PCI_VENDOR_ID_CAVIUM, 0xa01c), .data = &cavium_sata_quirk }, - { RT_PCI_DEVICE_CLASS(PCIS_STORAGE_SATA_AHCI, ~0) }, - { /* sentinel */ } -}; - -static struct rt_pci_driver pci_ahci_driver = -{ - .name = "ahci-pci", - - .ids = pci_ahci_ids, - .probe = pci_ahci_probe, - .remove = pci_ahci_remove, - .shutdown = pci_ahci_shutdown, -}; -RT_PCI_DRIVER_EXPORT(pci_ahci_driver); diff --git a/rt-thread/components/drivers/ata/ahci.c b/rt-thread/components/drivers/ata/ahci.c deleted file mode 100644 index c8a191b..0000000 --- a/rt-thread/components/drivers/ata/ahci.c +++ /dev/null @@ -1,896 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#include -#include -#include - -#define DBG_TAG "rtdm.ahci" -#define DBG_LVL DBG_INFO -#include - -#define HWREG32_FLUSH(base, value) \ -do { \ - rt_uint32_t __value = value; \ - HWREG32(base) = __value; \ - __value = HWREG32(base); \ -} while (0) - -static void ahci_fill_cmd_slot(struct rt_ahci_port *port, rt_uint32_t opts) -{ - rt_ubase_t dma_addr = port->cmd_tbl_dma; - struct rt_ahci_cmd_hdr *cmd_slot = port->cmd_slot; - - cmd_slot->opts = rt_cpu_to_le32(opts); - cmd_slot->status = 0; - cmd_slot->tbl_addr_lo = rt_cpu_to_le32(rt_lower_32_bits(dma_addr)); - cmd_slot->tbl_addr_hi = rt_cpu_to_le32(rt_upper_32_bits(dma_addr)); -} - -static int ahci_fill_sg(struct rt_ahci_host *host, int id, - void *buffer, rt_size_t buffer_size) -{ - int sg_count; - rt_ubase_t dma_addr; - struct rt_ahci_port *port = &host->ports[id]; - struct rt_ahci_sg *ahci_sg = port->cmd_tbl_sg; - - sg_count = ((buffer_size - 1) / RT_ACHI_PRDT_BYTES_MAX) + 1; - - if (sg_count > RT_AHCI_MAX_SG) - { - return -1; - } - - dma_addr = (rt_ubase_t)rt_kmem_v2p(buffer); - - for (int i = 0; i < sg_count; ++i, ++ahci_sg) - { - ahci_sg->addr_lo = rt_cpu_to_le32(rt_lower_32_bits(dma_addr)); - ahci_sg->addr_hi = rt_cpu_to_le32(rt_upper_32_bits(dma_addr)); - - if (ahci_sg->addr_hi && !(host->cap & RT_AHCI_CAP_64)) - { - return -1; - } - - ahci_sg->flags_size = rt_cpu_to_le32(0x3fffff & - (rt_min_t(rt_uint32_t, buffer_size, RT_ACHI_PRDT_BYTES_MAX) - 1)); - - dma_addr += RT_ACHI_PRDT_BYTES_MAX; - buffer_size -= RT_ACHI_PRDT_BYTES_MAX; - } - - return sg_count; -} - -static rt_err_t ahci_request_io(struct rt_ahci_host *host, int id, - void *fis, rt_size_t fis_size, - void *buffer, rt_size_t buffer_size, rt_bool_t is_read) -{ - int sg_count; - rt_err_t err; - struct rt_ahci_port *port = &host->ports[id]; - - if ((HWREG32(port->regs + RT_AHCI_PORT_SSTS) & 0xf) != RT_AHCI_PORT_SSTS_DET_PHYRDY) - { - return -RT_EIO; - } - - if ((sg_count = ahci_fill_sg(host, id, buffer, buffer_size)) <= 0) - { - return -RT_EINVAL; - } - - rt_memcpy(port->cmd_tbl, fis, fis_size); - ahci_fill_cmd_slot(port, (fis_size >> 2) | (sg_count << 16) | (!is_read << 6)); - - if (!is_read) - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, buffer, buffer_size); - } - - HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CI, 1); - - err = rt_completion_wait(&port->done, rt_tick_from_millisecond(10000)); - - if (!err && is_read) - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, buffer, buffer_size); - } - - return err; -} - -static rt_err_t ahci_scsi_cmd_rw(struct rt_ahci_host *host, int id, - rt_off_t lba, void *buffer, rt_ssize_t size, rt_bool_t is_read) -{ - rt_err_t err; - rt_uint8_t fis[20]; - struct rt_ahci_port *port = &host->ports[id]; - - rt_memset(fis, 0, sizeof(fis)); - fis[0] = RT_AHCI_FIS_TYPE_REG_H2D; - fis[1] = 1 << 7; /* Command */ - fis[2] = is_read ? RT_AHCI_ATA_CMD_READ_EXT : RT_AHCI_ATA_CMD_WRITE_EXT; - - while (size > 0) - { - rt_size_t t_size, t_lba; - - t_lba = rt_min_t(rt_size_t, host->max_blocks, size); - t_size = port->block_size * t_lba; - - fis[3] = 0xe0; /* Features */ - fis[4] = (lba >> 0) & 0xff; /* LBA low register */ - fis[5] = (lba >> 8) & 0xff; /* LBA mid register */ - fis[6] = (lba >> 16) & 0xff; /* LBA high register */ - fis[7] = 1 << 6; /* Device */ - fis[8] = ((lba >> 24) & 0xff); /* LBA register, 31:24 */ - fis[9] = ((lba >> 32) & 0xff); /* LBA register, 39:32 */ - fis[10] = ((lba >> 40) & 0xff); /* LBA register, 47:40 */ - fis[12] = (t_lba >> 0) & 0xff; /* Count register, 7:0 */ - fis[13] = (t_lba >> 8) & 0xff; /* Count register, 15:8 */ - - if ((err = ahci_request_io(host, id, fis, sizeof(fis), buffer, t_size, is_read))) - { - return err; - } - - size -= t_lba; - lba += t_lba; - buffer += t_size; - } - - return RT_EOK; -} - -static rt_err_t ahci_scsi_synchronize_cache(struct rt_ahci_host *host, int id, - rt_off_t lba, rt_size_t size) -{ - rt_uint8_t fis[20]; - rt_uint16_t *ataid; - struct rt_ahci_port *port = &host->ports[id]; - - ataid = port->ataid; - - if (!rt_ahci_ata_id_wcache_enabled(ataid) && - !rt_ahci_ata_id_has_flush(ataid) && - !rt_ahci_ata_id_has_flush_ext(ataid)) - { - return -RT_ENOSYS; - } - - rt_memset(fis, 0, sizeof(fis)); - fis[0] = RT_AHCI_FIS_TYPE_REG_H2D; - fis[1] = 1 << 7; /* Command */ - - if (rt_ahci_ata_id_has_flush_ext(ataid)) - { - fis[2] = RT_AHCI_ATA_CMD_FLUSH_EXT; - } - else - { - fis[2] = RT_AHCI_ATA_CMD_FLUSH; - } - - rt_memcpy(port->cmd_tbl, fis, 20); - ahci_fill_cmd_slot(port, 5); - - HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CI, 1); - - return rt_completion_wait(&port->done, rt_tick_from_millisecond(5000)); -} - -static rt_err_t ahci_scsi_cmd_write_same(struct rt_ahci_host *host, int id, - rt_off_t lba, rt_size_t size) -{ - rt_uint8_t fis[20]; - struct rt_ahci_port *port = &host->ports[id]; - - rt_memset(fis, 0, sizeof(fis)); - fis[0] = RT_AHCI_FIS_TYPE_REG_H2D; - fis[1] = 1 << 7; /* Command */ - fis[2] = RT_AHCI_ATA_CMD_DSM; - fis[3] = RT_AHCI_ATA_DSM_TRIM; /* Features */ - fis[4] = (lba >> 0) & 0xff; /* LBA low register */ - fis[5] = (lba >> 8) & 0xff; /* LBA mid register */ - fis[6] = (lba >> 16) & 0xff; /* LBA high register */ - fis[7] = 1 << 6; /* Device */ - fis[8] = ((lba >> 24) & 0xff); /* LBA register, 31:24 */ - fis[9] = ((lba >> 32) & 0xff); /* LBA register, 39:32 */ - fis[10] = ((lba >> 40) & 0xff); /* LBA register, 47:40 */ - fis[12] = (size >> 0) & 0xff; /* Count register, 7:0 */ - fis[13] = (size >> 8) & 0xff; /* Count register, 15:8 */ - - HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CI, 1); - - return rt_completion_wait(&port->done, rt_tick_from_millisecond(5000)); -} - -static rt_err_t ahci_scsi_cmd_read_capacity(struct rt_ahci_host *host, int id, - rt_size_t *out_last_block, rt_size_t *out_block_size) -{ - struct rt_ahci_port *port = &host->ports[id]; - - if (!port->ataid) - { - return -RT_EIO; - } - - *out_last_block = rt_ahci_ata_id_n_sectors(port->ataid) - 1; - *out_block_size = port->block_size; - - return RT_EOK; -} - -static rt_err_t ahci_scsi_cmd_test_unit_ready(struct rt_ahci_host *host, int id) -{ - struct rt_ahci_port *port = &host->ports[id]; - - return port->ataid ? RT_EOK : -RT_EIO; -} - -static rt_err_t ahci_scsi_cmd_inquiry(struct rt_ahci_host *host, int id, - char *prodid, rt_size_t prodid_len, char *prodrev, rt_size_t prodrev_len) -{ - rt_err_t err; - rt_uint8_t fis[20]; - rt_uint16_t *ataid; - struct rt_ahci_port *port = &host->ports[id]; - - if (!port->link) - { - return -RT_EIO; - } - - if (!port->ataid && !(port->ataid = rt_malloc(RT_AHCI_ATA_ID_WORDS * 2))) - { - return -RT_ENOMEM; - } - ataid = port->ataid; - - rt_memset(fis, 0, sizeof(fis)); - fis[0] = RT_AHCI_FIS_TYPE_REG_H2D; - fis[1] = 1 << 7; /* Command */ - fis[2] = RT_AHCI_ATA_CMD_ID_ATA; - - if ((err = ahci_request_io(host, id, fis, sizeof(fis), - ataid, RT_AHCI_ATA_ID_WORDS * 2, RT_TRUE))) - { - return err; - } - - for (int i = 0; i < RT_AHCI_ATA_ID_WORDS; ++i) - { - ataid[i] = rt_le16_to_cpu(ataid[i]); - } - - for (int i = 0; i < prodid_len / 2; ++i) - { - rt_uint16_t src = ataid[RT_AHCI_ATA_ID_PROD + i]; - - prodid[i] = (src & 0x00ff) << 8 | (src & 0xff00) >> 8; - } - - for (int i = 0; i < prodrev_len / 2; ++i) - { - rt_uint16_t src = ataid[RT_AHCI_ATA_ID_FW_REV + i]; - - prodrev[i] = (src & 0x00ff) << 8 | (src & 0xff00) >> 8; - } - - return err; -} - -static rt_err_t ahci_scsi_transfer(struct rt_scsi_device *sdev, - struct rt_scsi_cmd *cmd) -{ - rt_err_t err; - struct rt_ahci_host *host; - - host = rt_container_of(sdev->host, struct rt_ahci_host, parent); - - switch (cmd->op.unknow.opcode) - { - case RT_SCSI_CMD_REQUEST_SENSE: - { - struct rt_scsi_request_sense_data *request_sense = &cmd->data.request_sense; - - request_sense->error_code = 0x72; - - err = RT_EOK; - } - break; - - case RT_SCSI_CMD_READ10: - { - struct rt_scsi_read10 *read10 = &cmd->op.read10; - - err = ahci_scsi_cmd_rw(host, sdev->id, - rt_be32_to_cpu(read10->lba), - cmd->data.ptr, - rt_be16_to_cpu(read10->size), - RT_TRUE); - } - break; - - case RT_SCSI_CMD_READ16: - { - struct rt_scsi_read16 *read16 = &cmd->op.read16; - - err = ahci_scsi_cmd_rw(host, sdev->id, - rt_be64_to_cpu(read16->lba), - cmd->data.ptr, - rt_be32_to_cpu(read16->size), - RT_TRUE); - } - break; - - case RT_SCSI_CMD_READ12: - { - struct rt_scsi_read12 *read12 = &cmd->op.read12; - - err = ahci_scsi_cmd_rw(host, sdev->id, - rt_be32_to_cpu(read12->lba), - cmd->data.ptr, - rt_be32_to_cpu(read12->size), - RT_TRUE); - } - break; - - case RT_SCSI_CMD_WRITE10: - { - struct rt_scsi_write10 *write10 = &cmd->op.write10; - - err = ahci_scsi_cmd_rw(host, sdev->id, - rt_be32_to_cpu(write10->lba), - cmd->data.ptr, - rt_be16_to_cpu(write10->size), - RT_FALSE); - } - break; - - case RT_SCSI_CMD_WRITE16: - { - struct rt_scsi_write16 *write16 = &cmd->op.write16; - - err = ahci_scsi_cmd_rw(host, sdev->id, - rt_be64_to_cpu(write16->lba), - cmd->data.ptr, - rt_be32_to_cpu(write16->size), - RT_FALSE); - } - break; - - case RT_SCSI_CMD_WRITE12: - { - struct rt_scsi_write12 *write12 = &cmd->op.write12; - - err = ahci_scsi_cmd_rw(host, sdev->id, - rt_be32_to_cpu(write12->lba), - cmd->data.ptr, - rt_be32_to_cpu(write12->size), - RT_FALSE); - } - break; - - case RT_SCSI_CMD_SYNCHRONIZE_CACHE10: - { - struct rt_scsi_synchronize_cache10 *synchronize_cache10 = &cmd->op.synchronize_cache10; - - err = ahci_scsi_synchronize_cache(host, sdev->id, - rt_be32_to_cpu(synchronize_cache10->lba), - rt_be16_to_cpu(synchronize_cache10->size)); - } - break; - - case RT_SCSI_CMD_SYNCHRONIZE_CACHE16: - { - struct rt_scsi_synchronize_cache16 *synchronize_cache16 = &cmd->op.synchronize_cache16; - - err = ahci_scsi_synchronize_cache(host, sdev->id, - rt_be64_to_cpu(synchronize_cache16->lba), - rt_be32_to_cpu(synchronize_cache16->size)); - } - break; - - case RT_SCSI_CMD_WRITE_SAME10: - { - struct rt_scsi_write_same10 *write_same10 = &cmd->op.write_same10; - - err = ahci_scsi_cmd_write_same(host, sdev->id, - rt_be32_to_cpu(write_same10->lba), rt_be16_to_cpu(write_same10->size)); - } - break; - - case RT_SCSI_CMD_WRITE_SAME16: - { - struct rt_scsi_write_same16 *write_same16 = &cmd->op.write_same16; - - err = ahci_scsi_cmd_write_same(host, sdev->id, - rt_be64_to_cpu(write_same16->lba), rt_be32_to_cpu(write_same16->size)); - } - break; - - case RT_SCSI_CMD_READ_CAPACITY10: - { - rt_size_t last_block, block_size; - struct rt_scsi_read_capacity10_data *data = &cmd->data.read_capacity10; - - err = ahci_scsi_cmd_read_capacity(host, sdev->id, &last_block, &block_size); - - if (!err) - { - if (last_block > 0x100000000ULL) - { - last_block = 0xffffffff; - } - - data->last_block = rt_cpu_to_be32(last_block); - data->block_size = rt_cpu_to_be32(block_size); - } - } - break; - - case RT_SCSI_CMD_READ_CAPACITY16: - { - rt_size_t last_block, block_size; - struct rt_scsi_read_capacity16_data *data = &cmd->data.read_capacity16; - - err = ahci_scsi_cmd_read_capacity(host, sdev->id, &last_block, &block_size); - - if (!err) - { - data->last_block = rt_cpu_to_be64(last_block); - data->block_size = rt_cpu_to_be32(block_size); - } - } - break; - - case RT_SCSI_CMD_TEST_UNIT_READY: - err = ahci_scsi_cmd_test_unit_ready(host, sdev->id); - break; - - case RT_SCSI_CMD_INQUIRY: - { - struct rt_ahci_port *port = &host->ports[sdev->id]; - struct rt_scsi_inquiry_data *inquiry = &cmd->data.inquiry; - - err = ahci_scsi_cmd_inquiry(host, sdev->id, - inquiry->prodid, sizeof(inquiry->prodid), - inquiry->prodrev, sizeof(inquiry->prodrev)); - - if (!err) - { - rt_memcpy(inquiry->vendor, "ATA ", sizeof(inquiry->vendor)); - - if (HWREG32(port->regs + RT_AHCI_PORT_SIG) != RT_AHCI_PORT_SIG_SATA_CDROM) - { - port->block_size = 512; - inquiry->devtype = SCSI_DEVICE_TYPE_DIRECT; - } - else - { - port->block_size = 2048; - inquiry->devtype = SCSI_DEVICE_TYPE_CDROM; - } - inquiry->rmb = 0; - inquiry->length = 95 - 4; - } - } - break; - - case RT_SCSI_CMD_MODE_SENSE: - case RT_SCSI_CMD_MODE_SENSE10: - case RT_SCSI_CMD_MODE_SELECT: - case RT_SCSI_CMD_MODE_SELECT10: - return -RT_ENOSYS; - - default: - return -RT_EINVAL; - } - - return err; -} - -static struct rt_scsi_ops ahci_scsi_ops = -{ - .transfer = ahci_scsi_transfer, -}; - -static void ahci_isr(int irqno, void *param) -{ - int id; - rt_uint32_t isr; - rt_bitmap_t int_map; - struct rt_ahci_port *port; - struct rt_ahci_host *host = param; - - int_map = HWREG32(host->regs + RT_AHCI_HBA_INTS); - - rt_bitmap_for_each_set_bit(&int_map, id, host->ports_nr) - { - port = &host->ports[id]; - - isr = HWREG32(port->regs + RT_AHCI_PORT_INTS); - - if (port->link) - { - if (host->ops->port_isr) - { - host->ops->port_isr(host, port, isr); - } - - rt_completion_done(&port->done); - } - - HWREG32(port->regs + RT_AHCI_PORT_INTS) = isr; - } - - HWREG32(host->regs + RT_AHCI_HBA_INTS) = int_map; -} - -rt_err_t rt_ahci_host_register(struct rt_ahci_host *host) -{ - rt_err_t err; - rt_uint32_t value; - char dev_name[RT_NAME_MAX]; - struct rt_scsi_host *scsi; - - if (!host || !host->parent.dev || !host->ops) - { - return -RT_EINVAL; - } - - host->max_blocks = host->max_blocks ? : 0x80; - - /* - * 1. Reset HBA. - */ - err = -RT_EIO; - value = HWREG32(host->regs + RT_AHCI_HBA_GHC); - - if (!(value & RT_AHCI_GHC_RESET)) - { - HWREG32_FLUSH(host->regs + RT_AHCI_HBA_GHC, value | RT_AHCI_GHC_RESET); - } - - for (int i = 0; i < 5; ++i) - { - rt_thread_mdelay(200); - - if (!(HWREG32(host->regs + RT_AHCI_HBA_GHC) & RT_AHCI_GHC_RESET)) - { - err = RT_EOK; - break; - } - } - - if (err) - { - goto _fail; - } - - /* - * 2. Enable AHCI and get the ports' information. - */ - HWREG32_FLUSH(host->regs + RT_AHCI_HBA_GHC, RT_AHCI_GHC_AHCI_EN); - - host->cap = HWREG32(host->regs + RT_AHCI_HBA_CAP); - host->cap &= RT_AHCI_CAP_SPM | RT_AHCI_CAP_SSS | RT_AHCI_CAP_SIS; - HWREG32(host->regs + RT_AHCI_HBA_CAP) = host->cap; - host->cap = HWREG32(host->regs + RT_AHCI_HBA_CAP); - - HWREG32_FLUSH(host->regs + RT_AHCI_HBA_PI, 0xf); - - if (host->ops->host_init && (err = host->ops->host_init(host))) - { - goto _fail; - } - - host->ports_nr = (host->cap & RT_AHCI_CAP_NP) + 1; - host->ports_map = HWREG32(host->regs + RT_AHCI_HBA_PI); - - /* Check implemented in firmware */ - rt_dm_dev_prop_read_u32(host->parent.dev, "ports-implemented", &host->ports_map); - - for (int i = 0; i < host->ports_nr; ++i) - { - struct rt_ahci_port *port; - - if (!(host->ports_map & RT_BIT(i))) - { - continue; - } - port = &host->ports[i]; - - /* - * 3. Alloc port io memory. - */ - port->regs = host->regs + 0x100 + (i * 0x80); - - /* - * 4. Make port stop. - */ - value = HWREG32(port->regs + RT_AHCI_PORT_CMD); - if (value & (RT_AHCI_PORT_CMD_LIST_ON | RT_AHCI_PORT_CMD_FIS_ON | - RT_AHCI_PORT_CMD_FIS_RX | RT_AHCI_PORT_CMD_START)) - { - value &= ~(RT_AHCI_PORT_CMD_LIST_ON | RT_AHCI_PORT_CMD_FIS_ON | - RT_AHCI_PORT_CMD_FIS_RX | RT_AHCI_PORT_CMD_START); - - HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CMD, value); - - rt_thread_mdelay(500); - } - - if (host->ops->port_init && (err = host->ops->port_init(host, port))) - { - LOG_E("Init port[%d] error = %s", rt_strerror(err)); - continue; - } - - value = HWREG32(port->regs + RT_AHCI_PORT_CMD); - value |= RT_AHCI_PORT_CMD_SPIN_UP; - HWREG32(port->regs + RT_AHCI_PORT_CMD) = value; - - /* - * 5. Enable port's SATA link. - */ - if (host->ops->port_link_up) - { - err = host->ops->port_link_up(host, port); - } - else - { - err = -RT_ETIMEOUT; - - for (int retry = 0; retry < 5; ++retry) - { - value = HWREG32(port->regs + RT_AHCI_PORT_SSTS); - - if ((value & RT_AHCI_PORT_SSTS_DET_MASK) == RT_AHCI_PORT_SSTS_DET_PHYRDY) - { - err = RT_EOK; - break; - } - - rt_thread_mdelay(2); - } - } - - if (err) - { - if (HWREG32(port->regs + RT_AHCI_PORT_SSTS) & RT_AHCI_PORT_SSTS_DET_MASK) - { - LOG_E("SATA[%d] link error = %s", i, rt_strerror(err)); - } - else - { - LOG_D("SATA[%d] not device", i); - } - - continue; - } - - /* Clear error status */ - if ((value = HWREG32(port->regs + RT_AHCI_PORT_SERR))) - { - HWREG32(port->regs + RT_AHCI_PORT_SERR) = value; - } - - for (int retry = 0; retry < 5; ++retry) - { - value = HWREG32(port->regs + RT_AHCI_PORT_TFD); - if (!(value & (RT_AHCI_PORT_TFDATA_BSY | RT_AHCI_PORT_TFDATA_DRQ))) - { - break; - } - - rt_thread_mdelay(2); - - value = HWREG32(port->regs + RT_AHCI_PORT_SSTS); - if ((value & RT_AHCI_PORT_SSTS_DET_MASK) == RT_AHCI_PORT_SSTS_DET_PHYRDY) - { - break; - } - } - - value = HWREG32(port->regs + RT_AHCI_PORT_SSTS) & RT_AHCI_PORT_SSTS_DET_MASK; - if (value == RT_AHCI_PORT_SSTS_DET_COMINIT) - { - /* Retry to setup */ - --i; - continue; - } - - /* Clear error */ - value = HWREG32(port->regs + RT_AHCI_PORT_SERR); - HWREG32(port->regs + RT_AHCI_PORT_SERR) = value; - - /* Clear pending IRQ */ - if ((value = HWREG32(port->regs + RT_AHCI_PORT_INTS))) - { - HWREG32(port->regs + RT_AHCI_PORT_INTS) = value; - } - - HWREG32(host->regs + RT_AHCI_HBA_INTS) = RT_BIT(i); - - value = HWREG32(port->regs + RT_AHCI_PORT_SSTS); - if ((value & RT_AHCI_PORT_SSTS_DET_MASK) == RT_AHCI_PORT_SSTS_DET_PHYRDY) - { - port->link = RT_TRUE; - } - } - - HWREG32(host->regs + RT_AHCI_HBA_GHC) |= RT_AHCI_GHC_IRQ_EN; - - for (int i = 0; i < host->ports_nr; ++i) - { - void *dma; - rt_ubase_t dma_addr; - rt_tick_t timeout; - struct rt_ahci_port *port = &host->ports[i]; - - if (!port->link) - { - continue; - } - - /* - * 6. Alloc transport memory, Port x Command List and FIS Base Address. - */ - port->dma = rt_dma_alloc_coherent(host->parent.dev, - RT_AHCI_DMA_SIZE, &port->dma_handle); - - if (!port->dma) - { - LOG_E("No memory to setup port[%d]", i); - break; - } - dma = port->dma; - - rt_memset(dma, 0, RT_AHCI_DMA_SIZE); - - port->cmd_slot = dma; - dma += (RT_AHCI_CMD_SLOT_SIZE + 224); - - port->rx_fis = dma; - dma += RT_AHCI_RX_FIS_SIZE; - - port->cmd_tbl = dma; - port->cmd_tbl_dma = (rt_ubase_t)rt_kmem_v2p(dma); - dma += RT_AHCI_CMD_TBL_HDR; - - port->cmd_tbl_sg = dma; - - dma_addr = (rt_ubase_t)rt_kmem_v2p(port->cmd_slot); - HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CLB, rt_lower_32_bits(dma_addr)); - HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CLBU, rt_upper_32_bits(dma_addr)); - - dma_addr = (rt_ubase_t)rt_kmem_v2p(port->rx_fis); - HWREG32_FLUSH(port->regs + RT_AHCI_PORT_FB, rt_lower_32_bits(dma_addr)); - HWREG32_FLUSH(port->regs + RT_AHCI_PORT_FBU, rt_upper_32_bits(dma_addr)); - - if (host->ops->port_dma_init && (err = host->ops->port_dma_init(host, port))) - { - LOG_E("Init port[%d] DMA error = %s", rt_strerror(err)); - } - - HWREG32_FLUSH(port->regs + RT_AHCI_PORT_CMD, RT_AHCI_PORT_CMD_ACTIVE | - RT_AHCI_PORT_CMD_FIS_RX | RT_AHCI_PORT_CMD_POWER_ON | - RT_AHCI_PORT_CMD_SPIN_UP | RT_AHCI_PORT_CMD_START); - - /* Wait spinup */ - err = -RT_ETIMEOUT; - timeout = rt_tick_from_millisecond(20000); - timeout += rt_tick_get(); - do { - if (!(HWREG32(port->regs + RT_AHCI_PORT_TFD) & RT_AHCI_PORT_TFDATA_BSY)) - { - err = RT_EOK; - break; - } - - rt_hw_cpu_relax(); - } while (rt_tick_get() < timeout); - - if (err) - { - rt_dma_free_coherent(host->parent.dev, RT_AHCI_DMA_SIZE, port->dma, - port->dma_handle); - port->dma = RT_NULL; - - LOG_E("Start up port[%d] fail", i); - continue; - } - - port->int_enabled |= RT_AHCI_PORT_INTE_HBUS_ERR | RT_AHCI_PORT_INTE_IF_ERR | - RT_AHCI_PORT_INTE_CONNECT | RT_AHCI_PORT_INTE_PHYRDY | - RT_AHCI_PORT_INTE_UNK_FIS | RT_AHCI_PORT_INTE_BAD_PMP | - RT_AHCI_PORT_INTE_TF_ERR | RT_AHCI_PORT_INTE_HBUS_DATA_ERR | - RT_AHCI_PORT_INTE_SG_DONE | RT_AHCI_PORT_INTE_SDB_FIS | - RT_AHCI_PORT_INTE_DMAS_FIS | RT_AHCI_PORT_INTE_PIOS_FIS | - RT_AHCI_PORT_INTE_D2H_REG_FIS; - - HWREG32(port->regs + RT_AHCI_PORT_INTE) = port->int_enabled; - - rt_completion_init(&port->done); - } - - rt_snprintf(dev_name, sizeof(dev_name), "ahci-%s", - rt_dm_dev_get_name(host->parent.dev)); - - rt_hw_interrupt_install(host->irq, ahci_isr, host, dev_name); - rt_hw_interrupt_umask(host->irq); - - scsi = &host->parent; - scsi->max_lun = rt_max_t(rt_size_t, scsi->max_lun, 1); - scsi->max_id = host->ports_nr; - scsi->ops = &ahci_scsi_ops; - - if ((err = rt_scsi_host_register(scsi))) - { - goto _fail; - } - - return RT_EOK; - -_fail: - rt_hw_interrupt_mask(host->irq); - rt_pic_detach_irq(host->irq, host); - - return err; -} - -rt_err_t rt_ahci_host_unregister(struct rt_ahci_host *host) -{ - rt_err_t err; - struct rt_scsi_host *scsi; - - if (!host) - { - return -RT_EINVAL; - } - - scsi = &host->parent; - - if ((err = rt_scsi_host_unregister(scsi))) - { - return err; - } - - rt_hw_interrupt_mask(host->irq); - rt_pic_detach_irq(host->irq, host); - - for (int i = 0; i < host->ports_nr; ++i) - { - struct rt_ahci_port *port = &host->ports[i]; - - if (port->ataid) - { - rt_free(port->ataid); - } - - HWREG32(port->regs) &= ~(RT_AHCI_PORT_CMD_ACTIVE | RT_AHCI_PORT_CMD_POWER_ON | - RT_AHCI_PORT_CMD_SPIN_UP | RT_AHCI_PORT_CMD_START); - - if (port->dma) - { - rt_dma_free_coherent(host->parent.dev, RT_AHCI_DMA_SIZE, port->dma, - port->dma_handle); - } - } - - HWREG32(host->regs + RT_AHCI_HBA_GHC) &= ~(RT_AHCI_GHC_AHCI_EN | RT_AHCI_GHC_IRQ_EN); - - return RT_EOK; -} diff --git a/rt-thread/components/drivers/audio/dev_audio.c b/rt-thread/components/drivers/audio/dev_audio.c deleted file mode 100644 index 22ee81e..0000000 --- a/rt-thread/components/drivers/audio/dev_audio.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2017-05-09 Urey first version - * 2019-07-09 Zero-Free improve device ops interface and data flows - */ - -#include -#include -#include -#include - -#define DBG_TAG "audio" -#define DBG_LVL DBG_INFO -#include - -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif - -enum -{ - REPLAY_EVT_NONE = 0x00, - REPLAY_EVT_START = 0x01, - REPLAY_EVT_STOP = 0x02, -}; - -static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio) -{ - rt_err_t result = RT_EOK; - rt_uint8_t *data; - rt_size_t dst_size, src_size; - rt_uint16_t position, remain_bytes = 0, index = 0; - struct rt_audio_buf_info *buf_info; - - RT_ASSERT(audio != RT_NULL); - - buf_info = &audio->replay->buf_info; - /* save current pos */ - position = audio->replay->pos; - dst_size = buf_info->block_size; - - /* check replay queue is empty */ - if (rt_data_queue_peek(&audio->replay->queue, (const void **)&data, &src_size) != RT_EOK) - { - /* ack stop event */ - if (audio->replay->event & REPLAY_EVT_STOP) - rt_completion_done(&audio->replay->cmp); - - /* send zero frames */ - rt_memset(&buf_info->buffer[audio->replay->pos], 0, dst_size); - - audio->replay->pos += dst_size; - audio->replay->pos %= buf_info->total_size; - } - else - { - rt_memset(&buf_info->buffer[audio->replay->pos], 0, dst_size); - - /* copy data from memory pool to hardware device fifo */ - while (index < dst_size) - { - result = rt_data_queue_peek(&audio->replay->queue, (const void **)&data, &src_size); - if (result != RT_EOK) - { - LOG_D("under run %d, remain %d", audio->replay->pos, remain_bytes); - audio->replay->pos -= remain_bytes; - audio->replay->pos += dst_size; - audio->replay->pos %= buf_info->total_size; - audio->replay->read_index = 0; - result = -RT_EEMPTY; - break; - } - - remain_bytes = MIN((dst_size - index), (src_size - audio->replay->read_index)); - rt_memcpy(&buf_info->buffer[audio->replay->pos], - &data[audio->replay->read_index], remain_bytes); - - index += remain_bytes; - audio->replay->read_index += remain_bytes; - audio->replay->pos += remain_bytes; - audio->replay->pos %= buf_info->total_size; - - if (audio->replay->read_index == src_size) - { - /* free memory */ - audio->replay->read_index = 0; - rt_data_queue_pop(&audio->replay->queue, (const void **)&data, &src_size, RT_WAITING_NO); - rt_mp_free(data); - - /* notify transmitted complete. */ - if (audio->parent.tx_complete != RT_NULL) - audio->parent.tx_complete(&audio->parent, (void *)data); - } - } - } - - if (audio->ops->transmit != RT_NULL) - { - if (audio->ops->transmit(audio, &buf_info->buffer[position], RT_NULL, dst_size) != dst_size) - result = -RT_ERROR; - } - - return result; -} - -static rt_err_t _audio_flush_replay_frame(struct rt_audio_device *audio) -{ - rt_err_t result = RT_EOK; - - if (audio->replay->write_index) - { - result = rt_data_queue_push(&audio->replay->queue, - (const void **)audio->replay->write_data, - audio->replay->write_index, - RT_WAITING_FOREVER); - - audio->replay->write_index = 0; - } - - return result; -} - -static rt_err_t _aduio_replay_start(struct rt_audio_device *audio) -{ - rt_err_t result = RT_EOK; - - if (audio->replay->activated != RT_TRUE) - { - /* start playback hardware device */ - if (audio->ops->start) - result = audio->ops->start(audio, AUDIO_STREAM_REPLAY); - - audio->replay->activated = RT_TRUE; - LOG_D("start audio replay device"); - } - - return result; -} - -static rt_err_t _aduio_replay_stop(struct rt_audio_device *audio) -{ - rt_err_t result = RT_EOK; - - if (audio->replay->activated == RT_TRUE) - { - /* flush replay remian frames */ - _audio_flush_replay_frame(audio); - - /* notify irq(or thread) to stop the data transmission */ - audio->replay->event |= REPLAY_EVT_STOP; - - /* waiting for the remaining data transfer to complete */ - rt_completion_init(&audio->replay->cmp); - rt_completion_wait(&audio->replay->cmp, RT_WAITING_FOREVER); - audio->replay->event &= ~REPLAY_EVT_STOP; - - /* stop playback hardware device */ - if (audio->ops->stop) - result = audio->ops->stop(audio, AUDIO_STREAM_REPLAY); - - audio->replay->activated = RT_FALSE; - LOG_D("stop audio replay device"); - } - - return result; -} - -static rt_err_t _audio_record_start(struct rt_audio_device *audio) -{ - rt_err_t result = RT_EOK; - - if (audio->record->activated != RT_TRUE) - { - /* open audio record pipe */ - rt_device_open(RT_DEVICE(&audio->record->pipe), RT_DEVICE_OFLAG_RDONLY); - - /* start record hardware device */ - if (audio->ops->start) - result = audio->ops->start(audio, AUDIO_STREAM_RECORD); - - audio->record->activated = RT_TRUE; - LOG_D("start audio record device"); - } - - return result; -} - -static rt_err_t _audio_record_stop(struct rt_audio_device *audio) -{ - rt_err_t result = RT_EOK; - - if (audio->record->activated == RT_TRUE) - { - /* stop record hardware device */ - if (audio->ops->stop) - result = audio->ops->stop(audio, AUDIO_STREAM_RECORD); - - /* close audio record pipe */ - rt_device_close(RT_DEVICE(&audio->record->pipe)); - - audio->record->activated = RT_FALSE; - LOG_D("stop audio record device"); - } - - return result; -} - -static rt_err_t _audio_dev_init(struct rt_device *dev) -{ - rt_err_t result = RT_EOK; - struct rt_audio_device *audio; - - RT_ASSERT(dev != RT_NULL); - audio = (struct rt_audio_device *) dev; - - /* initialize replay & record */ - audio->replay = RT_NULL; - audio->record = RT_NULL; - - /* initialize replay */ - if (dev->flag & RT_DEVICE_FLAG_WRONLY) - { - struct rt_audio_replay *replay = (struct rt_audio_replay *) rt_malloc(sizeof(struct rt_audio_replay)); - - if (replay == RT_NULL) - return -RT_ENOMEM; - rt_memset(replay, 0, sizeof(struct rt_audio_replay)); - - /* init memory pool for replay */ - replay->mp = rt_mp_create("adu_mp", RT_AUDIO_REPLAY_MP_BLOCK_COUNT, RT_AUDIO_REPLAY_MP_BLOCK_SIZE); - if (replay->mp == RT_NULL) - { - rt_free(replay); - LOG_E("create memory pool for replay failed"); - return -RT_ENOMEM; - } - - /* init queue for audio replay */ - rt_data_queue_init(&replay->queue, CFG_AUDIO_REPLAY_QUEUE_COUNT, 0, RT_NULL); - - /* init mutex lock for audio replay */ - rt_mutex_init(&replay->lock, "replay", RT_IPC_FLAG_PRIO); - - replay->activated = RT_FALSE; - audio->replay = replay; - } - - /* initialize record */ - if (dev->flag & RT_DEVICE_FLAG_RDONLY) - { - struct rt_audio_record *record = (struct rt_audio_record *) rt_malloc(sizeof(struct rt_audio_record)); - rt_uint8_t *buffer; - - if (record == RT_NULL) - return -RT_ENOMEM; - rt_memset(record, 0, sizeof(struct rt_audio_record)); - - /* init pipe for record*/ - buffer = rt_malloc(RT_AUDIO_RECORD_PIPE_SIZE); - if (buffer == RT_NULL) - { - rt_free(record); - LOG_E("malloc memory for for record pipe failed"); - return -RT_ENOMEM; - } - rt_audio_pipe_init(&record->pipe, "record", - (rt_int32_t)(RT_PIPE_FLAG_FORCE_WR | RT_PIPE_FLAG_BLOCK_RD), - buffer, - RT_AUDIO_RECORD_PIPE_SIZE); - - record->activated = RT_FALSE; - audio->record = record; - } - - /* initialize hardware configuration */ - if (audio->ops->init) - audio->ops->init(audio); - - /* get replay buffer information */ - if (audio->ops->buffer_info) - audio->ops->buffer_info(audio, &audio->replay->buf_info); - - return result; -} - -static rt_err_t _audio_dev_open(struct rt_device *dev, rt_uint16_t oflag) -{ - struct rt_audio_device *audio; - - RT_ASSERT(dev != RT_NULL); - audio = (struct rt_audio_device *) dev; - - /* check device flag with the open flag */ - if ((oflag & RT_DEVICE_OFLAG_RDONLY) && !(dev->flag & RT_DEVICE_FLAG_RDONLY)) - return -RT_EIO; - if ((oflag & RT_DEVICE_OFLAG_WRONLY) && !(dev->flag & RT_DEVICE_FLAG_WRONLY)) - return -RT_EIO; - - /* get open flags */ - dev->open_flag = oflag & 0xff; - - /* initialize the Rx/Tx structure according to open flag */ - if (oflag & RT_DEVICE_OFLAG_WRONLY) - { - if (audio->replay->activated != RT_TRUE) - { - LOG_D("open audio replay device, oflag = %x\n", oflag); - audio->replay->write_index = 0; - audio->replay->read_index = 0; - audio->replay->pos = 0; - audio->replay->event = REPLAY_EVT_NONE; - } - dev->open_flag |= RT_DEVICE_OFLAG_WRONLY; - } - - if (oflag & RT_DEVICE_OFLAG_RDONLY) - { - /* open record pipe */ - if (audio->record->activated != RT_TRUE) - { - LOG_D("open audio record device ,oflag = %x\n", oflag); - - _audio_record_start(audio); - audio->record->activated = RT_TRUE; - } - dev->open_flag |= RT_DEVICE_OFLAG_RDONLY; - } - - return RT_EOK; -} - -static rt_err_t _audio_dev_close(struct rt_device *dev) -{ - struct rt_audio_device *audio; - RT_ASSERT(dev != RT_NULL); - audio = (struct rt_audio_device *) dev; - - if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY) - { - /* stop replay stream */ - _aduio_replay_stop(audio); - dev->open_flag &= ~RT_DEVICE_OFLAG_WRONLY; - } - - if (dev->open_flag & RT_DEVICE_OFLAG_RDONLY) - { - /* stop record stream */ - _audio_record_stop(audio); - dev->open_flag &= ~RT_DEVICE_OFLAG_RDONLY; - } - - return RT_EOK; -} - -static rt_ssize_t _audio_dev_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - struct rt_audio_device *audio; - RT_ASSERT(dev != RT_NULL); - audio = (struct rt_audio_device *) dev; - - if (!(dev->open_flag & RT_DEVICE_OFLAG_RDONLY) || (audio->record == RT_NULL)) - return 0; - - return rt_device_read(RT_DEVICE(&audio->record->pipe), pos, buffer, size); -} - -static rt_ssize_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - - struct rt_audio_device *audio; - rt_uint8_t *ptr; - rt_uint16_t block_size, remain_bytes, index = 0; - - RT_ASSERT(dev != RT_NULL); - audio = (struct rt_audio_device *) dev; - - if (!(dev->open_flag & RT_DEVICE_OFLAG_WRONLY) || (audio->replay == RT_NULL)) - return 0; - - /* push a new frame to replay data queue */ - ptr = (rt_uint8_t *)buffer; - block_size = RT_AUDIO_REPLAY_MP_BLOCK_SIZE; - - rt_mutex_take(&audio->replay->lock, RT_WAITING_FOREVER); - while (index < size) - { - /* request buffer from replay memory pool */ - if (audio->replay->write_index % block_size == 0) - { - audio->replay->write_data = rt_mp_alloc(audio->replay->mp, RT_WAITING_FOREVER); - rt_memset(audio->replay->write_data, 0, block_size); - } - - /* copy data to replay memory pool */ - remain_bytes = MIN((block_size - audio->replay->write_index), (size - index)); - rt_memcpy(&audio->replay->write_data[audio->replay->write_index], &ptr[index], remain_bytes); - - index += remain_bytes; - audio->replay->write_index += remain_bytes; - audio->replay->write_index %= block_size; - - if (audio->replay->write_index == 0) - { - rt_data_queue_push(&audio->replay->queue, - audio->replay->write_data, - block_size, - RT_WAITING_FOREVER); - } - } - rt_mutex_release(&audio->replay->lock); - - /* check replay state */ - if (audio->replay->activated != RT_TRUE) - { - _aduio_replay_start(audio); - audio->replay->activated = RT_TRUE; - } - - return index; -} - -static rt_err_t _audio_dev_control(struct rt_device *dev, int cmd, void *args) -{ - rt_err_t result = RT_EOK; - struct rt_audio_device *audio; - RT_ASSERT(dev != RT_NULL); - audio = (struct rt_audio_device *) dev; - - /* dev stat...*/ - switch (cmd) - { - case AUDIO_CTL_GETCAPS: - { - struct rt_audio_caps *caps = (struct rt_audio_caps *) args; - - LOG_D("AUDIO_CTL_GETCAPS: main_type = %d,sub_type = %d", caps->main_type, caps->sub_type); - if (audio->ops->getcaps != RT_NULL) - { - result = audio->ops->getcaps(audio, caps); - } - - break; - } - - case AUDIO_CTL_CONFIGURE: - { - struct rt_audio_caps *caps = (struct rt_audio_caps *) args; - - LOG_D("AUDIO_CTL_CONFIGURE: main_type = %d,sub_type = %d", caps->main_type, caps->sub_type); - if (audio->ops->configure != RT_NULL) - { - result = audio->ops->configure(audio, caps); - } - - break; - } - - case AUDIO_CTL_START: - { - int stream = *(int *) args; - - LOG_D("AUDIO_CTL_START: stream = %d", stream); - if (stream == AUDIO_STREAM_REPLAY) - { - result = _aduio_replay_start(audio); - } - else - { - result = _audio_record_start(audio); - } - - break; - } - - case AUDIO_CTL_STOP: - { - int stream = *(int *) args; - - LOG_D("AUDIO_CTL_STOP: stream = %d", stream); - if (stream == AUDIO_STREAM_REPLAY) - { - result = _aduio_replay_stop(audio); - } - else - { - result = _audio_record_stop(audio); - } - - break; - } - - default: - break; - } - - return result; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops audio_ops = -{ - _audio_dev_init, - _audio_dev_open, - _audio_dev_close, - _audio_dev_read, - _audio_dev_write, - _audio_dev_control -}; -#endif - -rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data) -{ - rt_err_t result = RT_EOK; - struct rt_device *device; - - RT_ASSERT(audio != RT_NULL); - device = &(audio->parent); - - device->type = RT_Device_Class_Sound; - device->rx_indicate = RT_NULL; - device->tx_complete = RT_NULL; - -#ifdef RT_USING_DEVICE_OPS - device->ops = &audio_ops; -#else - device->init = _audio_dev_init; - device->open = _audio_dev_open; - device->close = _audio_dev_close; - device->read = _audio_dev_read; - device->write = _audio_dev_write; - device->control = _audio_dev_control; -#endif - device->user_data = data; - - /* register a character device */ - result = rt_device_register(device, name, flag | RT_DEVICE_FLAG_REMOVABLE); - - /* initialize audio device */ - if (result == RT_EOK) - result = rt_device_init(device); - - return result; -} - -int rt_audio_samplerate_to_speed(rt_uint32_t bitValue) -{ - int speed = 0; - switch (bitValue) - { - case AUDIO_SAMP_RATE_8K: - speed = 8000; - break; - case AUDIO_SAMP_RATE_11K: - speed = 11052; - break; - case AUDIO_SAMP_RATE_16K: - speed = 16000; - break; - case AUDIO_SAMP_RATE_22K: - speed = 22050; - break; - case AUDIO_SAMP_RATE_32K: - speed = 32000; - break; - case AUDIO_SAMP_RATE_44K: - speed = 44100; - break; - case AUDIO_SAMP_RATE_48K: - speed = 48000; - break; - case AUDIO_SAMP_RATE_96K: - speed = 96000; - break; - case AUDIO_SAMP_RATE_128K: - speed = 128000; - break; - case AUDIO_SAMP_RATE_160K: - speed = 160000; - break; - case AUDIO_SAMP_RATE_172K: - speed = 176400; - break; - case AUDIO_SAMP_RATE_192K: - speed = 192000; - break; - default: - break; - } - - return speed; -} - -void rt_audio_tx_complete(struct rt_audio_device *audio) -{ - /* try to send next frame */ - _audio_send_replay_frame(audio); -} - -void rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t len) -{ - /* save data to record pipe */ - rt_device_write(RT_DEVICE(&audio->record->pipe), 0, pbuf, len); - - /* invoke callback */ - if (audio->parent.rx_indicate != RT_NULL) - audio->parent.rx_indicate(&audio->parent, len); -} diff --git a/rt-thread/components/drivers/audio/dev_audio_pipe.c b/rt-thread/components/drivers/audio/dev_audio_pipe.c deleted file mode 100644 index 24c0f26..0000000 --- a/rt-thread/components/drivers/audio/dev_audio_pipe.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-09-30 Bernard first version. - */ - -#include -#include -#include "dev_audio_pipe.h" - -static void _rt_audio_pipe_resume_writer(struct rt_audio_pipe *pipe) -{ - if (!rt_list_isempty(&pipe->suspended_write_list)) - { - rt_thread_t thread; - - RT_ASSERT(pipe->flag & RT_PIPE_FLAG_BLOCK_WR); - - /* get suspended thread */ - thread = RT_THREAD_LIST_NODE_ENTRY(pipe->suspended_write_list.next); - - /* resume the write thread */ - rt_thread_resume(thread); - - rt_schedule(); - } -} - -static rt_ssize_t rt_audio_pipe_read(rt_device_t dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - rt_base_t level; - rt_thread_t thread; - struct rt_audio_pipe *pipe; - rt_size_t read_nbytes; - - pipe = (struct rt_audio_pipe *)dev; - RT_ASSERT(pipe != RT_NULL); - - if (!(pipe->flag & RT_PIPE_FLAG_BLOCK_RD)) - { - level = rt_hw_interrupt_disable(); - read_nbytes = rt_ringbuffer_get(&(pipe->ringbuffer), (rt_uint8_t *)buffer, size); - - /* if the ringbuffer is empty, there won't be any writer waiting */ - if (read_nbytes) - _rt_audio_pipe_resume_writer(pipe); - - rt_hw_interrupt_enable(level); - - return read_nbytes; - } - - thread = rt_thread_self(); - - /* current context checking */ - RT_DEBUG_NOT_IN_INTERRUPT; - - do - { - level = rt_hw_interrupt_disable(); - read_nbytes = rt_ringbuffer_get(&(pipe->ringbuffer), (rt_uint8_t *)buffer, size); - if (read_nbytes == 0) - { - rt_thread_suspend(thread); - /* waiting on suspended read list */ - rt_list_insert_before(&(pipe->suspended_read_list), - &RT_THREAD_LIST_NODE(thread)); - rt_hw_interrupt_enable(level); - - rt_schedule(); - } - else - { - _rt_audio_pipe_resume_writer(pipe); - rt_hw_interrupt_enable(level); - break; - } - } - while (read_nbytes == 0); - - return read_nbytes; -} - -static void _rt_audio_pipe_resume_reader(struct rt_audio_pipe *pipe) -{ - if (pipe->parent.rx_indicate) - pipe->parent.rx_indicate(&pipe->parent, - rt_ringbuffer_data_len(&pipe->ringbuffer)); - - if (!rt_list_isempty(&pipe->suspended_read_list)) - { - rt_thread_t thread; - - RT_ASSERT(pipe->flag & RT_PIPE_FLAG_BLOCK_RD); - - /* get suspended thread */ - thread = RT_THREAD_LIST_NODE_ENTRY(pipe->suspended_read_list.next); - - /* resume the read thread */ - rt_thread_resume(thread); - - rt_schedule(); - } -} - -static rt_ssize_t rt_audio_pipe_write(rt_device_t dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - rt_base_t level; - rt_thread_t thread; - struct rt_audio_pipe *pipe; - rt_size_t write_nbytes; - - pipe = (struct rt_audio_pipe *)dev; - RT_ASSERT(pipe != RT_NULL); - - if ((pipe->flag & RT_PIPE_FLAG_FORCE_WR) || - !(pipe->flag & RT_PIPE_FLAG_BLOCK_WR)) - { - level = rt_hw_interrupt_disable(); - - if (pipe->flag & RT_PIPE_FLAG_FORCE_WR) - write_nbytes = rt_ringbuffer_put_force(&(pipe->ringbuffer), - (const rt_uint8_t *)buffer, size); - else - write_nbytes = rt_ringbuffer_put(&(pipe->ringbuffer), - (const rt_uint8_t *)buffer, size); - - _rt_audio_pipe_resume_reader(pipe); - - rt_hw_interrupt_enable(level); - - return write_nbytes; - } - - thread = rt_thread_self(); - - /* current context checking */ - RT_DEBUG_NOT_IN_INTERRUPT; - - do - { - level = rt_hw_interrupt_disable(); - write_nbytes = rt_ringbuffer_put(&(pipe->ringbuffer), (const rt_uint8_t *)buffer, size); - if (write_nbytes == 0) - { - /* pipe full, waiting on suspended write list */ - rt_thread_suspend(thread); - /* waiting on suspended read list */ - rt_list_insert_before(&(pipe->suspended_write_list), - &RT_THREAD_LIST_NODE(thread)); - rt_hw_interrupt_enable(level); - - rt_schedule(); - } - else - { - _rt_audio_pipe_resume_reader(pipe); - rt_hw_interrupt_enable(level); - break; - } - } - while (write_nbytes == 0); - - return write_nbytes; -} - -static rt_err_t rt_audio_pipe_control(rt_device_t dev, int cmd, void *args) -{ - struct rt_audio_pipe *pipe; - - pipe = (struct rt_audio_pipe *)dev; - - if (cmd == PIPE_CTRL_GET_SPACE && args) - *(rt_size_t *)args = rt_ringbuffer_space_len(&pipe->ringbuffer); - return RT_EOK; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops audio_pipe_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - rt_audio_pipe_read, - rt_audio_pipe_write, - rt_audio_pipe_control -}; -#endif - -/** - * This function will initialize a pipe device and put it under control of - * resource management. - * - * @param pipe the pipe device - * @param name the name of pipe device - * @param flag the attribute of the pipe device - * @param buf the buffer of pipe device - * @param size the size of pipe device buffer - * - * @return the operation status, RT_EOK on successful - */ -rt_err_t rt_audio_pipe_init(struct rt_audio_pipe *pipe, - const char *name, - rt_int32_t flag, - rt_uint8_t *buf, - rt_size_t size) -{ - RT_ASSERT(pipe); - RT_ASSERT(buf); - - /* initialize suspended list */ - rt_list_init(&pipe->suspended_read_list); - rt_list_init(&pipe->suspended_write_list); - - /* initialize ring buffer */ - rt_ringbuffer_init(&pipe->ringbuffer, buf, size); - - pipe->flag = flag; - - /* create pipe */ - pipe->parent.type = RT_Device_Class_Pipe; -#ifdef RT_USING_DEVICE_OPS - pipe->parent.ops = &audio_pipe_ops; -#else - pipe->parent.init = RT_NULL; - pipe->parent.open = RT_NULL; - pipe->parent.close = RT_NULL; - pipe->parent.read = rt_audio_pipe_read; - pipe->parent.write = rt_audio_pipe_write; - pipe->parent.control = rt_audio_pipe_control; -#endif - - return rt_device_register(&(pipe->parent), name, RT_DEVICE_FLAG_RDWR); -} - -/** - * This function will detach a pipe device from resource management - * - * @param pipe the pipe device - * - * @return the operation status, RT_EOK on successful - */ -rt_err_t rt_audio_pipe_detach(struct rt_audio_pipe *pipe) -{ - return rt_device_unregister(&pipe->parent); -} - -#ifdef RT_USING_HEAP -rt_err_t rt_audio_pipe_create(const char *name, rt_int32_t flag, rt_size_t size) -{ - rt_uint8_t *rb_memptr = RT_NULL; - struct rt_audio_pipe *pipe = RT_NULL; - - /* get aligned size */ - size = RT_ALIGN(size, RT_ALIGN_SIZE); - pipe = (struct rt_audio_pipe *)rt_calloc(1, sizeof(struct rt_audio_pipe)); - if (pipe == RT_NULL) - return -RT_ENOMEM; - - /* create ring buffer of pipe */ - rb_memptr = (rt_uint8_t *)rt_malloc(size); - if (rb_memptr == RT_NULL) - { - rt_free(pipe); - return -RT_ENOMEM; - } - - return rt_audio_pipe_init(pipe, name, flag, rb_memptr, size); -} - -void rt_audio_pipe_destroy(struct rt_audio_pipe *pipe) -{ - if (pipe == RT_NULL) - return; - - /* un-register pipe device */ - rt_audio_pipe_detach(pipe); - - /* release memory */ - rt_free(pipe->ringbuffer.buffer_ptr); - rt_free(pipe); - - return; -} - -#endif /* RT_USING_HEAP */ diff --git a/rt-thread/components/drivers/audio/dev_audio_pipe.h b/rt-thread/components/drivers/audio/dev_audio_pipe.h deleted file mode 100644 index f22fd14..0000000 --- a/rt-thread/components/drivers/audio/dev_audio_pipe.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#ifndef __DEV_AUDIO_PIPE_H__ -#define __DEV_AUDIO_PIPE_H__ - -/** - * Pipe Device - */ -#include - -#ifndef RT_PIPE_BUFSZ -#define PIPE_BUFSZ 512 -#else -#define PIPE_BUFSZ RT_PIPE_BUFSZ -#endif - -/* portal device */ -struct rt_audio_portal_device -{ - struct rt_device parent; - struct rt_device *write_dev; - struct rt_device *read_dev; -}; - -enum rt_audio_pipe_flag -{ - /* both read and write won't block */ - RT_PIPE_FLAG_NONBLOCK_RDWR = 0x00, - /* read would block */ - RT_PIPE_FLAG_BLOCK_RD = 0x01, - /* write would block */ - RT_PIPE_FLAG_BLOCK_WR = 0x02, - /* write to this pipe will discard some data when the pipe is full. - * When this flag is set, RT_PIPE_FLAG_BLOCK_WR will be ignored since write - * operation will always be success. */ - RT_PIPE_FLAG_FORCE_WR = 0x04, -}; - -struct rt_audio_pipe -{ - struct rt_device parent; - - /* ring buffer in pipe device */ - struct rt_ringbuffer ringbuffer; - - rt_int32_t flag; - - /* suspended list */ - rt_list_t suspended_read_list; - rt_list_t suspended_write_list; - - struct rt_audio_portal_device *write_portal; - struct rt_audio_portal_device *read_portal; -}; - -#define PIPE_CTRL_GET_SPACE 0x14 /**< get the remaining size of a pipe device */ - -rt_err_t rt_audio_pipe_init(struct rt_audio_pipe *pipe, - const char *name, - rt_int32_t flag, - rt_uint8_t *buf, - rt_size_t size); -rt_err_t rt_audio_pipe_detach(struct rt_audio_pipe *pipe); -#ifdef RT_USING_HEAP -rt_err_t rt_audio_pipe_create(const char *name, rt_int32_t flag, rt_size_t size); -void rt_audio_pipe_destroy(struct rt_audio_pipe *pipe); -#endif /* RT_USING_HEAP */ - -#endif /* __DEV_AUDIO_PIPE_H__ */ diff --git a/rt-thread/components/drivers/block/Kconfig b/rt-thread/components/drivers/block/Kconfig deleted file mode 100644 index 865df5e..0000000 --- a/rt-thread/components/drivers/block/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -menuconfig RT_USING_BLK - bool "Using Block device drivers" - default n - -if RT_USING_BLK - rsource "partitions/Kconfig" -endif diff --git a/rt-thread/components/drivers/block/SConscript b/rt-thread/components/drivers/block/SConscript deleted file mode 100644 index 4aff1a8..0000000 --- a/rt-thread/components/drivers/block/SConscript +++ /dev/null @@ -1,23 +0,0 @@ -from building import * - -group = [] -objs = [] - -if not GetDepend(['RT_USING_BLK']): - Return('group') - -cwd = GetCurrentDir() -list = os.listdir(cwd) -CPPPATH = [cwd + '/../include'] - -src = ['blk.c', 'blk_dev.c', 'blk_dfs.c', 'blk_partition.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -for d in list: - path = os.path.join(cwd, d) - if os.path.isfile(os.path.join(path, 'SConscript')): - objs = objs + SConscript(os.path.join(d, 'SConscript')) -objs = objs + group - -Return('objs') diff --git a/rt-thread/components/drivers/block/blk.c b/rt-thread/components/drivers/block/blk.c deleted file mode 100644 index 9f2659d..0000000 --- a/rt-thread/components/drivers/block/blk.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#define DBG_TAG "rtdm.blk" -#define DBG_LVL DBG_INFO -#include - -#include "blk_dev.h" -#include "blk_dfs.h" - -static void blk_remove_all(struct rt_blk_disk *disk) -{ - struct rt_blk_device *blk, *blk_next; - - /* Remove all partitions */ - rt_list_for_each_entry_safe(blk, blk_next, &disk->part_nodes, list) - { - disk_remove_blk_dev(blk, RT_TRUE); - } -} - -static rt_err_t blk_open(rt_device_t dev, rt_uint16_t oflag) -{ - struct rt_blk_disk *disk = to_blk_disk(dev); - - if (disk->read_only && (oflag & RT_DEVICE_OFLAG_WRONLY)) - { - return -RT_EINVAL; - } - - return RT_EOK; -} - -static rt_err_t blk_close(rt_device_t dev) -{ - return RT_EOK; -} - -static rt_ssize_t blk_read(rt_device_t dev, rt_off_t sector, - void *buffer, rt_size_t sector_count) -{ - rt_ssize_t res; - struct rt_blk_disk *disk = to_blk_disk(dev); - - rt_sem_take(&disk->usr_lock, RT_WAITING_FOREVER); - - res = disk->ops->read(disk, sector, buffer, sector_count); - - rt_sem_release(&disk->usr_lock); - - return res; -} - -static rt_ssize_t blk_write(rt_device_t dev, rt_off_t sector, - const void *buffer, rt_size_t sector_count) -{ - rt_ssize_t res; - struct rt_blk_disk *disk = to_blk_disk(dev); - - if (!disk->read_only) - { - rt_sem_take(&disk->usr_lock, RT_WAITING_FOREVER); - - res = disk->ops->write(disk, sector, buffer, sector_count); - - rt_sem_release(&disk->usr_lock); - - return res; - } - - return -RT_ENOSYS; -} - -static rt_ssize_t blk_parallel_read(rt_device_t dev, rt_off_t sector, - void *buffer, rt_size_t sector_count) -{ - struct rt_blk_disk *disk = to_blk_disk(dev); - - return disk->ops->read(disk, sector, buffer, sector_count); -} - -static rt_ssize_t blk_parallel_write(rt_device_t dev, rt_off_t sector, - const void *buffer, rt_size_t sector_count) -{ - struct rt_blk_disk *disk = to_blk_disk(dev); - - if (!disk->read_only) - { - return disk->ops->write(disk, sector, buffer, sector_count); - } - - return -RT_ENOSYS; -} - -static rt_err_t blk_control(rt_device_t dev, int cmd, void *args) -{ - rt_err_t err; - struct rt_blk_disk *disk = to_blk_disk(dev); - - switch (cmd) - { - case RT_DEVICE_CTRL_BLK_GETGEOME: - if (args) - { - err = disk->ops->getgeome(disk, args); - } - else - { - err = -RT_EINVAL; - } - - break; - - case RT_DEVICE_CTRL_BLK_SYNC: - if (disk->ops->sync) - { - rt_sem_take(&disk->usr_lock, RT_WAITING_FOREVER); - - spin_lock(&disk->lock); - - err = disk->ops->sync(disk); - - spin_unlock(&disk->lock); - - rt_sem_release(&disk->usr_lock); - } - else - { - err = -RT_ENOSYS; - } - break; - - case RT_DEVICE_CTRL_BLK_ERASE: - if (disk->ops->erase) - { - rt_sem_take(&disk->usr_lock, RT_WAITING_FOREVER); - - spin_lock(&disk->lock); - - if (disk->parent.ref_count != 1) - { - err = -RT_EBUSY; - goto _unlock; - } - - blk_remove_all(disk); - - err = disk->ops->erase(disk); - - _unlock: - spin_unlock(&disk->lock); - - rt_sem_release(&disk->usr_lock); - } - else - { - err = -RT_ENOSYS; - } - break; - - case RT_DEVICE_CTRL_BLK_AUTOREFRESH: - if (disk->ops->autorefresh) - { - err = disk->ops->autorefresh(disk, !!args); - } - else - { - err = -RT_ENOSYS; - } - break; - - case RT_DEVICE_CTRL_BLK_PARTITION: - err = -RT_EINVAL; - break; - - case RT_DEVICE_CTRL_BLK_SSIZEGET: - device_get_blk_ssize(dev, args); - err = RT_EOK; - break; - - case RT_DEVICE_CTRL_ALL_BLK_SSIZEGET: - device_get_all_blk_ssize(dev, args); - err = RT_EOK; - break; - - default: - if (disk->ops->control) - { - err = disk->ops->control(disk, RT_NULL, cmd, args); - } - else - { - err = -RT_ENOSYS; - } - break; - } - - return err; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops blk_ops = -{ - .open = blk_open, - .close = blk_close, - .read = blk_read, - .write = blk_write, - .control = blk_control, -}; - -const static struct rt_device_ops blk_parallel_ops = -{ - .open = blk_open, - .close = blk_close, - .read = blk_parallel_read, - .write = blk_parallel_write, - .control = blk_control, -}; -#endif /* RT_USING_DEVICE_OPS */ - -rt_err_t rt_hw_blk_disk_register(struct rt_blk_disk *disk) -{ - rt_err_t err; -#ifdef RT_USING_DM - int device_id; -#endif - const char *disk_name; - rt_uint16_t flags = RT_DEVICE_FLAG_RDONLY; - - if (!disk || !disk->ops) - { - return -RT_EINVAL; - } - -#ifdef RT_USING_DM - if (!disk->ida) - { - return -RT_EINVAL; - } -#endif - -#if RT_NAME_MAX > 0 - if (disk->parent.parent.name[0] == '\0') -#else - if (disk->parent.parent.name) -#endif - { - return -RT_EINVAL; - } - -#ifdef RT_USING_DM - if ((device_id = rt_dm_ida_alloc(disk->ida)) < 0) - { - return -RT_EFULL; - } -#endif - - disk->__magic = RT_BLK_DISK_MAGIC; - disk_name = to_disk_name(disk); - - err = rt_sem_init(&disk->usr_lock, disk_name, 1, RT_IPC_FLAG_PRIO); - - if (err) - { - #ifdef RT_USING_DM - rt_dm_ida_free(disk->ida, device_id); - #endif - - LOG_E("%s: Init user mutex error = %s", rt_strerror(err)); - - return err; - } - - rt_list_init(&disk->part_nodes); - rt_spin_lock_init(&disk->lock); - - disk->parent.type = RT_Device_Class_Block; -#ifdef RT_USING_DEVICE_OPS - if (disk->parallel_io) - { - disk->parent.ops = &blk_parallel_ops; - } - else - { - disk->parent.ops = &blk_ops; - } -#else - disk->parent.open = blk_open; - disk->parent.close = blk_close; - - if (disk->parallel_io) - { - disk->parent.read = blk_parallel_read; - disk->parent.write = blk_parallel_write; - } - else - { - disk->parent.read = blk_read; - disk->parent.write = blk_write; - } - disk->parent.control = blk_control; -#endif - - if (!disk->ops->write) - { - disk->read_only = RT_TRUE; - } - - if (!disk->read_only) - { - flags |= RT_DEVICE_FLAG_WRONLY; - } - -#ifdef RT_USING_DM - disk->parent.master_id = disk->ida->master_id; - disk->parent.device_id = device_id; -#endif - device_set_blk_fops(&disk->parent); - - err = rt_device_register(&disk->parent, disk_name, flags); - - if (err) - { - rt_sem_detach(&disk->usr_lock); - } - - /* Ignore partition scanning errors */ - rt_blk_disk_probe_partition(disk); - - return err; -} - -rt_err_t rt_hw_blk_disk_unregister(struct rt_blk_disk *disk) -{ - rt_err_t err; - - if (!disk) - { - return -RT_EINVAL; - } - - spin_lock(&disk->lock); - - if (disk->parent.ref_count > 0) - { - err = -RT_EBUSY; - goto _unlock; - } - - /* Flush all data */ - if (disk->ops->sync) - { - err = disk->ops->sync(disk); - - if (err) - { - LOG_E("%s: Sync error = %s", to_disk_name(disk), rt_strerror(err)); - - goto _unlock; - } - } - - rt_sem_detach(&disk->usr_lock); - - blk_remove_all(disk); - -#ifdef RT_USING_DM - rt_dm_ida_free(disk->ida, disk->parent.device_id); -#endif - - err = rt_device_unregister(&disk->parent); - -_unlock: - spin_unlock(&disk->lock); - - return err; -} - -rt_ssize_t rt_blk_disk_get_capacity(struct rt_blk_disk *disk) -{ - rt_ssize_t res; - struct rt_device_blk_geometry geometry; - - if (!disk) - { - return -RT_EINVAL; - } - - res = disk->ops->getgeome(disk, &geometry); - - if (!res) - { - return geometry.sector_count; - } - - return res; -} - -rt_ssize_t rt_blk_disk_get_logical_block_size(struct rt_blk_disk *disk) -{ - rt_ssize_t res; - struct rt_device_blk_geometry geometry; - - if (!disk) - { - return -RT_EINVAL; - } - - res = disk->ops->getgeome(disk, &geometry); - - if (!res) - { - return geometry.bytes_per_sector; - } - - return res; -} - -#ifdef RT_USING_DFS_MNTTABLE -static int blk_dfs_mnt_table(void) -{ - rt_ubase_t level; - struct rt_object *obj; - struct rt_device *dev; - struct rt_blk_disk *disk; - struct rt_blk_device *blk_dev; - struct rt_object_information *info = rt_object_get_information(RT_Object_Class_Device); - - level = rt_hw_interrupt_disable(); - - rt_list_for_each_entry(obj, &info->object_list, list) - { - dev = rt_container_of(obj, struct rt_device, parent); - - if (dev->type != RT_Device_Class_Block) - { - continue; - } - - disk = to_blk_disk(dev); - - if (disk->__magic != RT_BLK_DISK_MAGIC) - { - continue; - } - - if (disk->max_partitions == RT_BLK_PARTITION_NONE) - { - dfs_mount_device(&disk->parent); - continue; - } - - rt_list_for_each_entry(blk_dev, &disk->part_nodes, list) - { - dfs_mount_device(&blk_dev->parent); - } - } - - rt_hw_interrupt_enable(level); - - return 0; -} -INIT_ENV_EXPORT(blk_dfs_mnt_table); -#endif /* RT_USING_DFS_MNTTABLE */ - -#if defined(RT_USING_CONSOLE) && defined(RT_USING_MSH) -const char *convert_size(struct rt_device_blk_geometry *geome, - rt_size_t sector_count, rt_size_t *out_cap, rt_size_t *out_minor) -{ - rt_size_t cap, minor = 0; - int size_index = 0; - const char *size_name[] = { "B", "K", "M", "G", "T", "P", "E" }; - - cap = geome->bytes_per_sector * sector_count; - - for (size_index = 0; size_index < RT_ARRAY_SIZE(size_name) - 1; ++size_index) - { - if (cap < 1024) - { - break; - } - - /* Only one decimal point */ - minor = (cap % 1024) * 10 / 1024; - cap = cap / 1024; - } - - *out_cap = cap; - *out_minor = minor; - - return size_name[size_index]; -} - -static int list_blk(int argc, char**argv) -{ - rt_ubase_t level; - rt_size_t cap, minor; - const char *size_name; - struct rt_object *obj; - struct rt_device *dev; - struct rt_blk_disk *disk; - struct rt_blk_device *blk_dev; - struct rt_device_blk_geometry geome; - struct rt_object_information *info = rt_object_get_information(RT_Object_Class_Device); - - level = rt_hw_interrupt_disable(); - - rt_kprintf("%-*.s MAJ:MIN RM SIZE\tRO TYPE MOUNTPOINT\n", RT_NAME_MAX, "NAME"); - - rt_list_for_each_entry(obj, &info->object_list, list) - { - dev = rt_container_of(obj, struct rt_device, parent); - - if (dev->type != RT_Device_Class_Block) - { - continue; - } - - disk = to_blk_disk(dev); - - if (disk->__magic != RT_BLK_DISK_MAGIC) - { - continue; - } - - if (disk->ops->getgeome(disk, &geome)) - { - continue; - } - - size_name = convert_size(&geome, geome.sector_count, &cap, &minor); - - rt_kprintf("%-*.s %3u.%-3u %u %u.%u%s\t%u disk %s\n", - RT_NAME_MAX, to_disk_name(disk), - #ifdef RT_USING_DM - disk->parent.master_id, disk->parent.device_id, - #else - 0, 0, - #endif - disk->removable, cap, minor, size_name, disk->read_only, - disk->max_partitions != RT_BLK_PARTITION_NONE ? "\b" : - (dfs_filesystem_get_mounted_path(&disk->parent) ? : "\b")); - - rt_list_for_each_entry(blk_dev, &disk->part_nodes, list) - { - size_name = convert_size(&geome, blk_dev->sector_count, &cap, &minor); - - rt_kprintf("%c--%-*.s %3u.%-3u %u %u.%u%s\t%u part %s\n", - blk_dev->list.next != &disk->part_nodes ? '|' : '`', - RT_NAME_MAX - 3, to_blk_name(blk_dev), - #ifdef RT_USING_DM - blk_dev->parent.master_id, blk_dev->parent.device_id, - #else - 0, 0, - #endif - disk->removable, cap, minor, size_name, disk->read_only, - dfs_filesystem_get_mounted_path(&blk_dev->parent) ? : ""); - } - } - - rt_hw_interrupt_enable(level); - - return 0; -} -MSH_CMD_EXPORT(list_blk, dump all of blks information); -#endif /* RT_USING_CONSOLE && RT_USING_MSH */ diff --git a/rt-thread/components/drivers/block/blk_dev.c b/rt-thread/components/drivers/block/blk_dev.c deleted file mode 100644 index 5c45aa5..0000000 --- a/rt-thread/components/drivers/block/blk_dev.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI first version - */ - -#include "blk_dev.h" -#include "blk_dfs.h" - -#define DBG_TAG "blk.dm" -#define DBG_LVL DBG_INFO -#include - -#ifdef RT_USING_DFS -#include -#endif - -static rt_err_t blk_dev_open(rt_device_t dev, rt_uint16_t oflag) -{ - struct rt_blk_device *blk = to_blk(dev); - - return rt_device_open(&blk->disk->parent, oflag); -} - -static rt_err_t blk_dev_close(rt_device_t dev) -{ - struct rt_blk_device *blk = to_blk(dev); - - return rt_device_close(&blk->disk->parent); -} - -static rt_ssize_t blk_dev_read(rt_device_t dev, rt_off_t sector, - void *buffer, rt_size_t sector_count) -{ - struct rt_blk_device *blk = to_blk(dev); - - if (sector <= blk->sector_start + blk->sector_count && - sector_count <= blk->sector_count) - { - return rt_device_read(&blk->disk->parent, - blk->sector_start + sector, buffer, sector_count); - } - - return -RT_EINVAL; -} - -static rt_ssize_t blk_dev_write(rt_device_t dev, rt_off_t sector, - const void *buffer, rt_size_t sector_count) -{ - struct rt_blk_device *blk = to_blk(dev); - - if (sector <= blk->sector_start + blk->sector_count && - sector_count <= blk->sector_count) - { - return rt_device_write(&blk->disk->parent, - blk->sector_start + sector, buffer, sector_count); - } - - return -RT_EINVAL; -} - -static rt_err_t blk_dev_control(rt_device_t dev, int cmd, void *args) -{ - rt_err_t err = -RT_EINVAL; - struct rt_blk_device *blk = to_blk(dev); - struct rt_blk_disk *disk = blk->disk; - struct rt_device_blk_geometry disk_geometry, *geometry; - - switch (cmd) - { - case RT_DEVICE_CTRL_BLK_GETGEOME: - if ((geometry = args)) - { - if (!(err = disk->ops->getgeome(disk, &disk_geometry))) - { - geometry->bytes_per_sector = disk_geometry.bytes_per_sector; - geometry->block_size = disk_geometry.block_size; - geometry->sector_count = blk->sector_count; - } - } - else - { - err = -RT_EINVAL; - } - - break; - - case RT_DEVICE_CTRL_BLK_SYNC: - rt_device_control(&disk->parent, cmd, args); - break; - - case RT_DEVICE_CTRL_BLK_ERASE: - case RT_DEVICE_CTRL_BLK_AUTOREFRESH: - if (disk->partitions <= 1) - { - rt_device_control(&disk->parent, cmd, args); - } - else - { - err = -RT_EIO; - } - break; - - case RT_DEVICE_CTRL_BLK_PARTITION: - if (args) - { - rt_memcpy(args, &blk->partition, sizeof(blk->partition)); - } - else - { - err = -RT_EINVAL; - } - - break; - - case RT_DEVICE_CTRL_BLK_SSIZEGET: - device_get_blk_ssize(dev, args); - err = RT_EOK; - break; - - case RT_DEVICE_CTRL_ALL_BLK_SSIZEGET: - device_get_all_blk_ssize(dev, args); - err = RT_EOK; - break; - - default: - if (disk->ops->control) - { - err = disk->ops->control(disk, blk, cmd, args); - } - break; - } - - return err; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops blk_dev_ops = -{ - .open = blk_dev_open, - .close = blk_dev_close, - .read = blk_dev_read, - .write = blk_dev_write, - .control = blk_dev_control, -}; -#endif - -rt_err_t blk_dev_initialize(struct rt_blk_device *blk) -{ - struct rt_device *dev; - - if (!blk) - { - return -RT_EINVAL; - } - - dev = &blk->parent; - dev->type = RT_Device_Class_Block; -#ifdef RT_USING_DEVICE_OPS - dev->ops = &blk_dev_ops; -#else - dev->open = blk_dev_open; - dev->close = blk_dev_close; - dev->read = blk_dev_read; - dev->write = blk_dev_write; - dev->control = blk_dev_control; -#endif - - return RT_EOK; -} - -rt_err_t disk_add_blk_dev(struct rt_blk_disk *disk, struct rt_blk_device *blk) -{ - rt_err_t err; -#ifdef RT_USING_DM - int device_id; -#endif - const char *disk_name, *name_fmt; - - if (!disk || !blk) - { - return -RT_EINVAL; - } - -#ifdef RT_USING_DM - if ((device_id = rt_dm_ida_alloc(disk->ida)) < 0) - { - return -RT_EFULL; - } -#endif - - blk->disk = disk; - rt_list_init(&blk->list); - - disk_name = to_disk_name(disk); - - /* End is [a-zA-Z] or [0-9] */ - if (disk_name[rt_strlen(disk_name) - 1] < 'a') - { - name_fmt = "%sp%d"; - } - else - { - name_fmt = "%s%d"; - } - -#ifdef RT_USING_DM - rt_dm_dev_set_name(&blk->parent, name_fmt, disk_name, blk->partno); - blk->parent.master_id = disk->ida->master_id; - blk->parent.device_id = device_id; -#else - rt_snprintf(blk->parent.parent.name, RT_NAME_MAX, name_fmt, disk_name, blk->partno); -#endif - device_set_blk_fops(&blk->parent); - - err = rt_device_register(&blk->parent, to_blk_name(blk), - disk->parent.flag & RT_DEVICE_FLAG_RDWR); - - if (err) - { - #ifdef RT_USING_DM - rt_dm_ida_free(disk->ida, device_id); - #endif - return err; - } - - spin_lock(&disk->lock); - - rt_list_insert_before(&disk->part_nodes, &blk->list); - - spin_unlock(&disk->lock); - - return RT_EOK; -} - -rt_err_t disk_remove_blk_dev(struct rt_blk_device *blk, rt_bool_t lockless) -{ - struct rt_blk_disk *disk; - - if (!blk) - { - return -RT_EINVAL; - } - - disk = blk->disk; - - if (!disk) - { - return -RT_EINVAL; - } - else - { - #ifdef RT_USING_DFS - const char *mountpath; - - if ((mountpath = dfs_filesystem_get_mounted_path(&blk->parent))) - { - dfs_unmount(mountpath); - LOG_D("%s: Unmount file system on %s", - to_blk_name(blk), mountpath); - } - #endif - } - -#ifdef RT_USING_DM - rt_dm_ida_free(disk->ida, blk->parent.device_id); -#endif - - rt_device_unregister(&blk->parent); - - if (!lockless) - { - spin_lock(&disk->lock); - } - - rt_list_remove(&blk->list); - - if (!lockless) - { - spin_unlock(&disk->lock); - } - - --disk->partitions; - - return RT_EOK; -} - -rt_uint32_t blk_request_ioprio(void) -{ - struct rt_thread *task = rt_thread_self(); - - return task ? RT_SCHED_PRIV(task).current_priority : 0; -} diff --git a/rt-thread/components/drivers/block/blk_dev.h b/rt-thread/components/drivers/block/blk_dev.h deleted file mode 100644 index b433f57..0000000 --- a/rt-thread/components/drivers/block/blk_dev.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI first version - */ - -#ifndef __BLK_DEV_H__ -#define __BLK_DEV_H__ - -#include -#include -#include -#include - -#define to_blk_disk(dev) rt_container_of(dev, struct rt_blk_disk, parent) -#define to_blk(dev) rt_container_of(dev, struct rt_blk_device, parent) - -#ifdef RT_USING_DM -#define to_disk_name(disk) rt_dm_dev_get_name(&(disk)->parent) -#define to_blk_name(blk) rt_dm_dev_get_name(&(blk)->parent) -#else -#define to_disk_name(disk) (disk)->parent.parent.name -#define to_blk_name(blk) (blk)->parent.parent.name -#endif - -/* %c%c name */ -#define letter_name(n) ('a' + (n) / ((n) >= 26 ? (26 * 2) : 1)), ((n) >= 26 ? 'a' + (n) % 26 : '\0') - -rt_inline void spin_lock(struct rt_spinlock *spinlock) -{ - rt_hw_spin_lock(&spinlock->lock); -} - -rt_inline void spin_unlock(struct rt_spinlock *spinlock) -{ - rt_hw_spin_unlock(&spinlock->lock); -} - -rt_err_t blk_dev_initialize(struct rt_blk_device *blk); -rt_err_t disk_add_blk_dev(struct rt_blk_disk *disk, struct rt_blk_device *blk); -rt_err_t disk_remove_blk_dev(struct rt_blk_device *blk, rt_bool_t lockless); - -rt_uint32_t blk_request_ioprio(void); - -#endif /* __BLK_DEV_H__ */ diff --git a/rt-thread/components/drivers/block/blk_dfs.c b/rt-thread/components/drivers/block/blk_dfs.c deleted file mode 100644 index 96800e1..0000000 --- a/rt-thread/components/drivers/block/blk_dfs.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-08-08 GuEe-GUI first version - */ - -#include "blk_dfs.h" - -#include -#include - -#if defined(RT_USING_POSIX_DEVIO) && defined(RT_USING_DFS_V2) -struct blk_fops_data -{ - struct rt_device_blk_geometry geometry; -}; - -static int blk_fops_open(struct dfs_file *file) -{ - struct rt_device *dev = file->vnode->data; - struct blk_fops_data *data = rt_malloc(sizeof(*data)); - - if (!data) - { - return (int)-RT_ENOMEM; - } - - dev->user_data = data; - rt_device_control(dev, RT_DEVICE_CTRL_BLK_GETGEOME, &data->geometry); - rt_device_control(dev, RT_DEVICE_CTRL_ALL_BLK_SSIZEGET, &file->vnode->size); - - return 0; -} - -static int blk_fops_close(struct dfs_file *file) -{ - struct rt_device *dev = file->vnode->data; - - rt_free(dev->user_data); - dev->user_data = RT_NULL; - - return 0; -} - -static int blk_fops_ioctl(struct dfs_file *file, int cmd, void *arg) -{ - struct rt_device *dev = file->vnode->data; - - return (int)rt_device_control(dev, cmd, arg); -} - -static ssize_t blk_fops_read(struct dfs_file *file, void *buf, size_t count, off_t *pos) -{ - void *rbuf; - rt_ssize_t res = 0; - int bytes_per_sector, blk_pos, first_offs, rsize = 0; - struct rt_device *dev = file->vnode->data; - struct blk_fops_data *data = dev->user_data; - - bytes_per_sector = data->geometry.bytes_per_sector; - blk_pos = *pos / bytes_per_sector; - first_offs = *pos % bytes_per_sector; - - if ((rbuf = rt_malloc(bytes_per_sector))) - { - /* - ** #1: read first unalign block size. - */ - res = rt_device_read(dev, blk_pos, rbuf, 1); - - if (res == 1) - { - if (count > bytes_per_sector - first_offs) - { - rsize = bytes_per_sector - first_offs; - } - else - { - rsize = count; - } - rt_memcpy(buf, rbuf + first_offs, rsize); - ++blk_pos; - - /* - ** #2: read continuous block size. - */ - while (rsize < count) - { - res = rt_device_read(dev, blk_pos++, rbuf, 1); - - if (res != 1) - { - break; - } - - if (count - rsize >= bytes_per_sector) - { - rt_memcpy(buf + rsize, rbuf, bytes_per_sector); - rsize += bytes_per_sector; - } - else - { - rt_memcpy(buf + rsize, rbuf, count - rsize); - rsize = count; - } - } - - *pos += rsize; - } - - rt_free(rbuf); - } - - return rsize; -} - -static ssize_t blk_fops_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos) -{ - void *rbuf; - rt_ssize_t res = 0; - int bytes_per_sector, blk_pos, first_offs, wsize = 0; - struct rt_device *dev = file->vnode->data; - struct blk_fops_data *data = dev->user_data; - - bytes_per_sector = data->geometry.bytes_per_sector; - blk_pos = *pos / bytes_per_sector; - first_offs = *pos % bytes_per_sector; - - /* - ** #1: write first unalign block size. - */ - if (first_offs != 0) - { - if (count > bytes_per_sector - first_offs) - { - wsize = bytes_per_sector - first_offs; - } - else - { - wsize = count; - } - - if ((rbuf = rt_malloc(bytes_per_sector))) - { - res = rt_device_read(dev, blk_pos, rbuf, 1); - - if (res == 1) - { - rt_memcpy(rbuf + first_offs, buf, wsize); - res = rt_device_write(dev, blk_pos, (const void *)rbuf, 1); - - if (res == 1) - { - blk_pos += 1; - rt_free(rbuf); - - goto _goon; - } - } - - rt_free(rbuf); - } - - return 0; - } - -_goon: - /* - ** #2: write continuous block size. - */ - if ((count - wsize) / bytes_per_sector != 0) - { - res = rt_device_write(dev, blk_pos, buf + wsize, (count - wsize) / bytes_per_sector); - wsize += res * bytes_per_sector; - blk_pos += res; - - if (res != (count - wsize) / bytes_per_sector) - { - *pos += wsize; - return wsize; - } - } - - /* - ** # 3: write last unalign block size. - */ - if ((count - wsize) != 0) - { - if ((rbuf = rt_malloc(bytes_per_sector))) - { - res = rt_device_read(dev, blk_pos, rbuf, 1); - - if (res == 1) - { - rt_memcpy(rbuf, buf + wsize, count - wsize); - res = rt_device_write(dev, blk_pos, (const void *)rbuf, 1); - - if (res == 1) - { - wsize += count - wsize; - } - } - - rt_free(rbuf); - } - } - - *pos += wsize; - return wsize; -} - -static int blk_fops_flush(struct dfs_file *file) -{ - struct rt_device *dev = file->vnode->data; - - return (int)rt_device_control(dev, RT_DEVICE_CTRL_BLK_SYNC, RT_NULL); -} - -static int blk_fops_poll(struct dfs_file *file, struct rt_pollreq *req) -{ - int mask = 0; - - return mask; -} - -const static struct dfs_file_ops blk_fops = -{ - .open = blk_fops_open, - .close = blk_fops_close, - .ioctl = blk_fops_ioctl, - .read = blk_fops_read, - .write = blk_fops_write, - .flush = blk_fops_flush, - .lseek = generic_dfs_lseek, - .poll = blk_fops_poll -}; - -void device_set_blk_fops(struct rt_device *dev) -{ - dev->fops = &blk_fops; -} -#else -void device_set_blk_fops(struct rt_device *dev) -{ -} -#endif /* RT_USING_POSIX_DEVIO && RT_USING_DFS_V2 */ - -void device_get_blk_ssize(struct rt_device *dev, void *args) -{ - rt_uint32_t bytes_per_sector; - struct rt_device_blk_geometry geometry; - - rt_device_control(dev, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry); - bytes_per_sector = geometry.bytes_per_sector; - - RT_ASSERT(sizeof(bytes_per_sector) == sizeof(geometry.bytes_per_sector)); - - rt_memcpy(args, &bytes_per_sector, sizeof(bytes_per_sector)); -} - -void device_get_all_blk_ssize(struct rt_device *dev, void *args) -{ - rt_uint64_t count_mul_per; - struct rt_device_blk_geometry geometry; - - rt_device_control(dev, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry); - count_mul_per = geometry.bytes_per_sector * geometry.sector_count; - - rt_memcpy(args, &count_mul_per, sizeof(count_mul_per)); -} diff --git a/rt-thread/components/drivers/block/blk_dfs.h b/rt-thread/components/drivers/block/blk_dfs.h deleted file mode 100644 index c532869..0000000 --- a/rt-thread/components/drivers/block/blk_dfs.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-08-08 GuEe-GUI first version - */ - -#ifndef __BLK_DFS_H__ -#define __BLK_DFS_H__ - -#include - -#define RT_DEVICE_CTRL_BLK_SSIZEGET 0x00001268 /**< get number of bytes per sector */ -#define RT_DEVICE_CTRL_ALL_BLK_SSIZEGET 0x80081272 /**< get number of bytes per sector * sector counts */ - -void device_set_blk_fops(struct rt_device *dev); -void device_get_blk_ssize(struct rt_device *dev, void *args); -void device_get_all_blk_ssize(struct rt_device *dev, void *args); - -#endif /* __BLK_DFS_H__ */ diff --git a/rt-thread/components/drivers/block/blk_partition.c b/rt-thread/components/drivers/block/blk_partition.c deleted file mode 100644 index 5a9e39d..0000000 --- a/rt-thread/components/drivers/block/blk_partition.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#define DBG_TAG "blk.part" -#define DBG_LVL DBG_INFO -#include - -#include "blk_partition.h" - -static rt_err_t (*partition_list[])(struct rt_blk_disk *) = -{ -#ifdef RT_BLK_PARTITION_EFI - efi_partition, -#endif -#ifdef RT_BLK_PARTITION_DFS - dfs_partition, -#endif -}; - -rt_err_t blk_put_partition(struct rt_blk_disk *disk, const char *type, - rt_size_t start, rt_size_t count, int partno) -{ - rt_err_t err; - - struct rt_blk_device *blk = rt_calloc(1, sizeof(*blk)); - - if (type && rt_strcmp(type, "dfs")) - { - rt_uint32_t ssz = rt_blk_disk_get_logical_block_size(disk); - - rt_kprintf("found part[%u], begin: %lu, size: ", partno, start * ssz); - - if ((count >> 11) == 0) - { - rt_kprintf("%u%cB\n", count >> 1, 'K'); /* KB */ - } - else - { - rt_uint32_t size_mb = count >> 11; /* MB */ - - if ((size_mb >> 10) == 0) - { - rt_kprintf("%u.%u%cB\n", size_mb, (count >> 1) & 0x3ff, 'M'); - } - else - { - rt_kprintf("%u.%u%cB\n", size_mb >> 10, size_mb & 0x3ff, 'G'); - } - } - } - - if (!blk) - { - err = -RT_ENOMEM; - goto _fail; - } - - err = blk_dev_initialize(blk); - - if (err) - { - goto _fail; - } - - blk->partno = partno; - blk->sector_start = start; - blk->sector_count = count; - - blk->partition.offset = start; - blk->partition.size = count; - blk->partition.lock = &disk->usr_lock; - - err = disk_add_blk_dev(disk, blk); - - if (err) - { - goto _fail; - } - - ++disk->partitions; - - return RT_EOK; - -_fail: - LOG_E("%s: Put partition.%s[%u] start = %lu count = %lu error = %s", - to_disk_name(disk), type, partno, start, count, rt_strerror(err)); - - if (blk) - { - rt_free(blk); - } - - return err; -} - -rt_err_t rt_blk_disk_probe_partition(struct rt_blk_disk *disk) -{ - rt_err_t err = RT_EOK; - - if (!disk) - { - return -RT_EINVAL; - } - - LOG_D("%s: Probing disk partitions", to_disk_name(disk)); - - if (disk->partitions) - { - return err; - } - - err = -RT_EEMPTY; - - if (disk->max_partitions == RT_BLK_PARTITION_NONE) - { - LOG_D("%s: Unsupported partitions", to_disk_name(disk)); - - return err; - } - - for (int i = 0; i < RT_ARRAY_SIZE(partition_list); ++i) - { - rt_err_t part_err = partition_list[i](disk); - - if (part_err == -RT_ENOMEM) - { - err = part_err; - break; - } - - if (!part_err) - { - err = RT_EOK; - break; - } - } - - if ((err && err != -RT_ENOMEM) || disk->partitions == 0) - { - /* No partition found */ - rt_size_t total_sectors = rt_blk_disk_get_capacity(disk); - - err = blk_put_partition(disk, RT_NULL, 0, total_sectors, 0); - } - - return err; -} diff --git a/rt-thread/components/drivers/block/blk_partition.h b/rt-thread/components/drivers/block/blk_partition.h deleted file mode 100644 index fb7158f..0000000 --- a/rt-thread/components/drivers/block/blk_partition.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI first version - */ - -#ifndef __BLK_PARTITION_H__ -#define __BLK_PARTITION_H__ - -#include "blk_dev.h" - -rt_err_t blk_put_partition(struct rt_blk_disk *disk, const char *type, - rt_size_t start, rt_size_t count, int partno); - -rt_err_t dfs_partition(struct rt_blk_disk *disk); -rt_err_t efi_partition(struct rt_blk_disk *disk); - -#endif /* __BLK_PARTITION_H__ */ diff --git a/rt-thread/components/drivers/block/partitions/Kconfig b/rt-thread/components/drivers/block/partitions/Kconfig deleted file mode 100644 index 6df5e71..0000000 --- a/rt-thread/components/drivers/block/partitions/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -menu "Partition Types" - -config RT_BLK_PARTITION_DFS - bool "DFS Partition support" - depends on RT_USING_DFS - default y - -config RT_BLK_PARTITION_EFI - bool "EFI Globally Unique Identifier (GUID) Partition support" - default y - -endmenu diff --git a/rt-thread/components/drivers/block/partitions/SConscript b/rt-thread/components/drivers/block/partitions/SConscript deleted file mode 100644 index 06b320b..0000000 --- a/rt-thread/components/drivers/block/partitions/SConscript +++ /dev/null @@ -1,18 +0,0 @@ -from building import * - -group = [] - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../../include'] - -src = [] - -if GetDepend(['RT_BLK_PARTITION_DFS']): - src += ['dfs.c'] - -if GetDepend(['RT_BLK_PARTITION_EFI']): - src += ['efi.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/block/partitions/dfs.c b/rt-thread/components/drivers/block/partitions/dfs.c deleted file mode 100644 index 3fdad1a..0000000 --- a/rt-thread/components/drivers/block/partitions/dfs.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-07-25 weety first version - * 2023-02-25 GuEe-GUI make blk interface - */ - -#include "efi.h" - -#define DBG_TAG "blk.part.dfs" -#define DBG_LVL DBG_INFO -#include - -rt_err_t dfs_partition(struct rt_blk_disk *disk) -{ - rt_ssize_t res; - struct dfs_partition part; - rt_uint8_t *sector = rt_malloc(rt_blk_disk_get_logical_block_size(disk)); - - if (!sector) - { - return -RT_ENOMEM; - } - - res = disk->ops->read(disk, 0, sector, 1); - - if (res < 0) - { - rt_free(sector); - return res; - } - - for (rt_size_t i = 0; i < disk->max_partitions; ++i) - { - res = dfs_filesystem_get_partition(&part, sector, i); - - if (res) - { - break; - } - - if (blk_put_partition(disk, "dfs", part.offset, part.size, i) == -RT_ENOMEM) - { - break; - } - } - - rt_free(sector); - - return RT_EOK; -} diff --git a/rt-thread/components/drivers/block/partitions/efi.c b/rt-thread/components/drivers/block/partitions/efi.c deleted file mode 100644 index a68a147..0000000 --- a/rt-thread/components/drivers/block/partitions/efi.c +++ /dev/null @@ -1,738 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-05-05 linzhenxing first version - * 2023-02-25 GuEe-GUI make blk interface - */ - -#include "efi.h" - -#define DBG_TAG "blk.part.efi" -#define DBG_LVL DBG_INFO -#include - -static rt_bool_t force_gpt = 0; - -static int force_gpt_setup(void) -{ -#ifdef RT_USING_OFW - force_gpt = !!rt_ofw_bootargs_select("gpt", 0); -#endif - - return 0; -} -INIT_CORE_EXPORT(force_gpt_setup); - -/** - * @brief This function is EFI version of crc32 function. - * - * @param buf the buffer to calculate crc32 of. - * @param len the length of buf. - * @return EFI-style CRC32 value for @buf. - */ -rt_inline rt_uint32_t efi_crc32(const rt_uint8_t *buf, rt_size_t len) -{ - rt_ubase_t crc = 0xffffffffUL; - - for (rt_size_t i = 0; i < len; ++i) - { - crc ^= buf[i]; - - for (int j = 0; j < 8; ++j) - { - crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320L : 0); - } - } - - return ~crc; -} - -/** - * @brief This function get number of last logical block of device. - * - * @param disk the blk of disk. - * @return last LBA value on success, 0 on error. - * This is stored (by sd and ide-geometry) in - * the part[0] entry for this disk, and is the number of - * physical sectors available on the disk. - */ -static rt_size_t last_lba(struct rt_blk_disk *disk) -{ - return rt_blk_disk_get_capacity(disk) - 1ULL; -} - -rt_inline int pmbr_part_valid(gpt_mbr_record *part) -{ - if (part->os_type != EFI_PMBR_OSTYPE_EFI_GPT) - { - return 0; - } - - /* set to 0x00000001 (i.e., the LBA of the GPT Partition Header) */ - if (rt_le32_to_cpu(part->starting_lba) != GPT_PRIMARY_PARTITION_TABLE_LBA) - { - return 0; - } - - return GPT_MBR_PROTECTIVE; -} - -/** - * @brief This function test Protective MBR for validity. - * - * @param mbr the pointer to a legacy mbr structure. - * @param total_sectors the amount of sectors in the device - * @return - * 0 -> Invalid MBR - * 1 -> GPT_MBR_PROTECTIVE - * 2 -> GPT_MBR_HYBRID - */ -static int is_pmbr_valid(legacy_mbr *mbr, rt_size_t total_sectors) -{ - rt_uint32_t sz = 0; - int part = 0, ret = 0; /* invalid by default */ - - if (!mbr || rt_le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE) - { - goto _done; - } - - for (int i = 0; i < 4; ++i) - { - ret = pmbr_part_valid(&mbr->partition_record[i]); - - if (ret == GPT_MBR_PROTECTIVE) - { - part = i; - /* - * Ok, we at least know that there's a protective MBR, - * now check if there are other partition types for - * hybrid MBR. - */ - goto _check_hybrid; - } - } - - if (ret != GPT_MBR_PROTECTIVE) - { - goto _done; - } - -_check_hybrid: - for (int i = 0; i < 4; i++) - { - if (mbr->partition_record[i].os_type != EFI_PMBR_OSTYPE_EFI_GPT && - mbr->partition_record[i].os_type != 0x00) - { - ret = GPT_MBR_HYBRID; - } - } - - /* - * Protective MBRs take up the lesser of the whole disk - * or 2 TiB (32bit LBA), ignoring the rest of the disk. - * Some partitioning programs, nonetheless, choose to set - * the size to the maximum 32-bit limitation, disregarding - * the disk size. - * - * Hybrid MBRs do not necessarily comply with this. - * - * Consider a bad value here to be a warning to support dd'ing - * an image from a smaller disk to a larger disk. - */ - if (ret == GPT_MBR_PROTECTIVE) - { - sz = rt_le32_to_cpu(mbr->partition_record[part].size_in_lba); - - if (sz != (rt_uint32_t)total_sectors - 1 && sz != 0xffffffff) - { - LOG_W("GPT: mbr size in lba (%u) different than whole disk (%u)", - sz, rt_min_t(rt_uint32_t, total_sectors - 1, 0xffffffff)); - } - } - -_done: - return ret; -} - -/** - * @brief This function read bytes from disk, starting at given LBA. - * - * @param disk the blk of disk. - * @param lba the Logical Block Address of the partition table. - * @param buffer the destination buffer. - * @param count the bytes to read. - * @return number of bytes read on success, 0 on error. - */ -static rt_size_t read_lba(struct rt_blk_disk *disk, - rt_uint64_t lba, rt_uint8_t *buffer, rt_size_t count) -{ - rt_size_t totalreadcount = 0; - - if (!buffer || lba > last_lba(disk)) - { - return 0; - } - - for (rt_uint64_t n = lba; count; ++n) - { - int copied = 512; - - disk->ops->read(disk, n, buffer, 1); - - if (copied > count) - { - copied = count; - } - - buffer += copied; - totalreadcount += copied; - count -= copied; - } - - return totalreadcount; -} - -/** - * @brief This function reads partition entries from disk. - * - * @param disk the blk of disk. - * @param gpt the GPT header - * @return ptes on success, null on error. - */ -static gpt_entry *alloc_read_gpt_entries(struct rt_blk_disk *disk, - gpt_header *gpt) -{ - rt_size_t count; - gpt_entry *pte; - rt_uint64_t entry_lba; - - if (!gpt) - { - return RT_NULL; - } - - count = (rt_size_t)rt_le32_to_cpu(gpt->num_partition_entries) * - rt_le32_to_cpu(gpt->sizeof_partition_entry); - - if (!count) - { - return RT_NULL; - } - - pte = rt_malloc(count); - - if (!pte) - { - return RT_NULL; - } - - entry_lba = rt_le64_to_cpu(gpt->partition_entry_lba); - - if (read_lba(disk, entry_lba, (rt_uint8_t *)pte, count) < count) - { - rt_free(pte); - pte = RT_NULL; - - return RT_NULL; - } - - /* Remember to free pte when done */ - return pte; -} - -/** - * @brief This function allocates GPT header, reads into it from disk. - * - * @param disk the blk of disk. - * @param lba the Logical Block Address of the partition table - * @return GPT header on success, null on error. - */ -static gpt_header *alloc_read_gpt_header(struct rt_blk_disk *disk, rt_uint64_t lba) -{ - gpt_header *gpt; - rt_uint32_t ssz = rt_blk_disk_get_logical_block_size(disk); - - gpt = rt_malloc(ssz); - - if (!gpt) - { - return RT_NULL; - } - - if (read_lba(disk, lba, (rt_uint8_t *)gpt, ssz) < ssz) - { - rt_free(gpt); - gpt = RT_NULL; - - return RT_NULL; - } - - /* Remember to free gpt when finished with it */ - return gpt; -} - -/** - * @brief This function tests one GPT header and PTEs for validity. - * - * @param disk the blk of disk. - * @param lba the Logical Block Address of the GPT header to test. - * @param gpt the GPT header ptr, filled on return. - * @param ptes the PTEs ptr, filled on return. - * @returns true if valid, false on error. - * If valid, returns pointers to newly allocated GPT header and PTEs. - */ -static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk, - rt_uint64_t lba, gpt_header **gpt, gpt_entry **ptes) -{ - rt_uint32_t crc, origcrc; - rt_uint64_t lastlba, pt_size; - rt_ssize_t logical_block_size; - - if (!ptes) - { - return RT_FALSE; - } - - if (!(*gpt = alloc_read_gpt_header(disk, lba))) - { - return RT_FALSE; - } - - /* Check the GUID Partition Table signature */ - if (rt_le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) - { - LOG_D("%s: GUID Partition Table Header signature is wrong: %lld != %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu((*gpt)->signature), - (rt_uint64_t)GPT_HEADER_SIGNATURE); - - goto _fail; - } - - /* Check the GUID Partition Table header size is too big */ - logical_block_size = rt_blk_disk_get_logical_block_size(disk); - - if (rt_le32_to_cpu((*gpt)->header_size) > logical_block_size) - { - LOG_D("%s: GUID Partition Table Header size is too large: %u > %u", - to_disk_name(disk), - rt_le32_to_cpu((*gpt)->header_size), - logical_block_size); - - goto _fail; - } - - /* Check the GUID Partition Table header size is too small */ - if (rt_le32_to_cpu((*gpt)->header_size) < sizeof(gpt_header)) - { - LOG_D("%s: GUID Partition Table Header size is too small: %u < %u", - to_disk_name(disk), - rt_le32_to_cpu((*gpt)->header_size), - sizeof(gpt_header)); - - goto _fail; - } - - /* Check the GUID Partition Table CRC */ - origcrc = rt_le32_to_cpu((*gpt)->header_crc32); - (*gpt)->header_crc32 = 0; - crc = efi_crc32((const rt_uint8_t *)(*gpt), rt_le32_to_cpu((*gpt)->header_size)); - - if (crc != origcrc) - { - LOG_D("%s: GUID Partition Table Header CRC is wrong: %x != %x", - to_disk_name(disk), crc, origcrc); - - goto _fail; - } - - (*gpt)->header_crc32 = rt_cpu_to_le32(origcrc); - - /* - * Check that the start_lba entry points to the LBA that contains - * the GUID Partition Table - */ - if (rt_le64_to_cpu((*gpt)->start_lba) != lba) - { - LOG_D("%s: GPT start_lba incorrect: %lld != %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu((*gpt)->start_lba), - (rt_uint64_t)lba); - - goto _fail; - } - - /* Check the first_usable_lba and last_usable_lba are within the disk */ - lastlba = last_lba(disk); - - if (rt_le64_to_cpu((*gpt)->first_usable_lba) > lastlba) - { - LOG_D("%s: GPT: first_usable_lba incorrect: %lld > %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu((*gpt)->first_usable_lba), - (rt_uint64_t)lastlba); - - goto _fail; - } - - if (rt_le64_to_cpu((*gpt)->last_usable_lba) > lastlba) - { - LOG_D("%s: GPT: last_usable_lba incorrect: %lld > %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu((*gpt)->last_usable_lba), - (rt_uint64_t)lastlba); - - goto _fail; - } - if (rt_le64_to_cpu((*gpt)->last_usable_lba) < rt_le64_to_cpu((*gpt)->first_usable_lba)) - { - LOG_D("%s: GPT: last_usable_lba incorrect: %lld > %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu((*gpt)->last_usable_lba), - (rt_uint64_t)rt_le64_to_cpu((*gpt)->first_usable_lba)); - - goto _fail; - } - - /* Check that sizeof_partition_entry has the correct value */ - if (rt_le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) - { - LOG_D("%s: GUID Partition Entry Size check failed", to_disk_name(disk)); - - goto _fail; - } - - /* Sanity check partition table size */ - pt_size = (rt_uint64_t)rt_le32_to_cpu((*gpt)->num_partition_entries) * - rt_le32_to_cpu((*gpt)->sizeof_partition_entry); - - if (!(*ptes = alloc_read_gpt_entries(disk, *gpt))) - { - goto _fail; - } - - /* Check the GUID Partition Entry Array CRC */ - crc = efi_crc32((const rt_uint8_t *)(*ptes), pt_size); - - if (crc != rt_le32_to_cpu((*gpt)->partition_entry_array_crc32)) - { - LOG_D("%s: GUID Partition Entry Array CRC check failed", to_disk_name(disk)); - - goto _fail_ptes; - } - - /* We're done, all's well */ - return RT_TRUE; - -_fail_ptes: - rt_free(*ptes); - *ptes = RT_NULL; - -_fail: - rt_free(*gpt); - *gpt = RT_NULL; - - return RT_FALSE; -} - -/** - * @brief This function tests one PTE for validity. - * - * @param pte the pte to check. - * @param lastlba the last lba of the disk. - * @return valid boolean of pte. - */ -rt_inline rt_bool_t is_pte_valid(const gpt_entry *pte, const rt_size_t lastlba) -{ - if ((!efi_guidcmp(pte->partition_type_guid, NULL_GUID)) || - rt_le64_to_cpu(pte->starting_lba) > lastlba || - rt_le64_to_cpu(pte->ending_lba) > lastlba) - { - return RT_FALSE; - } - - return RT_TRUE; -} - -/** - * @brief This function search disk for valid GPT headers and PTEs. - * - * @param disk the blk of disk. - * @param pgpt the primary GPT header. - * @param agpt the alternate GPT header. - * @param lastlba the last LBA number. - */ -static void compare_gpts(struct rt_blk_disk *disk, - gpt_header *pgpt, gpt_header *agpt, rt_uint64_t lastlba) -{ - int error_found = 0; - - if (!pgpt || !agpt) - { - return; - } - - if (rt_le64_to_cpu(pgpt->start_lba) != rt_le64_to_cpu(agpt->alternate_lba)) - { - LOG_W("%s: GPT:Primary header LBA(%lld) != Alt(%lld), header alternate_lba", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu(pgpt->start_lba), - (rt_uint64_t)rt_le64_to_cpu(agpt->alternate_lba)); - - ++error_found; - } - - if (rt_le64_to_cpu(pgpt->alternate_lba) != rt_le64_to_cpu(agpt->start_lba)) - { - LOG_W("%s: GPT:Primary header alternate_lba(%lld) != Alt(%lld), header start_lba", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu(pgpt->alternate_lba), - (rt_uint64_t)rt_le64_to_cpu(agpt->start_lba)); - - ++error_found; - } - - if (rt_le64_to_cpu(pgpt->first_usable_lba) != rt_le64_to_cpu(agpt->first_usable_lba)) - { - LOG_W("%s: GPT:first_usable_lbas don't match %lld != %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu(pgpt->first_usable_lba), - (rt_uint64_t)rt_le64_to_cpu(agpt->first_usable_lba)); - - ++error_found; - } - - if (rt_le64_to_cpu(pgpt->last_usable_lba) != rt_le64_to_cpu(agpt->last_usable_lba)) - { - LOG_W("%s: GPT:last_usable_lbas don't match %lld != %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu(pgpt->last_usable_lba), - (rt_uint64_t)rt_le64_to_cpu(agpt->last_usable_lba)); - - ++error_found; - } - - if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) - { - LOG_W("%s: GPT:disk_guids don't match", to_disk_name(disk)); - - ++error_found; - } - - if (rt_le32_to_cpu(pgpt->num_partition_entries) != - rt_le32_to_cpu(agpt->num_partition_entries)) - { - LOG_W("%s: GPT:num_partition_entries don't match: 0x%x != 0x%x", - to_disk_name(disk), - rt_le32_to_cpu(pgpt->num_partition_entries), - rt_le32_to_cpu(agpt->num_partition_entries)); - - ++error_found; - } - - if (rt_le32_to_cpu(pgpt->sizeof_partition_entry) != - rt_le32_to_cpu(agpt->sizeof_partition_entry)) - { - LOG_W("%s: GPT:sizeof_partition_entry values don't match: 0x%x != 0x%x", - to_disk_name(disk), - rt_le32_to_cpu(pgpt->sizeof_partition_entry), - rt_le32_to_cpu(agpt->sizeof_partition_entry)); - - ++error_found; - } - - if (rt_le32_to_cpu(pgpt->partition_entry_array_crc32) != - rt_le32_to_cpu(agpt->partition_entry_array_crc32)) - { - LOG_W("%s: GPT:partition_entry_array_crc32 values don't match: 0x%x != 0x%x", - to_disk_name(disk), - rt_le32_to_cpu(pgpt->partition_entry_array_crc32), - rt_le32_to_cpu(agpt->partition_entry_array_crc32)); - - ++error_found; - } - - if (rt_le64_to_cpu(pgpt->alternate_lba) != lastlba) - { - LOG_W("%s: GPT:Primary header thinks Alt. header is not at the end of the disk: %lld != %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu(pgpt->alternate_lba), - (rt_uint64_t)lastlba); - - ++error_found; - } - - if (rt_le64_to_cpu(agpt->start_lba) != lastlba) - { - LOG_W("%s: GPT:Alternate GPT header not at the end of the disk: %lld != %lld", - to_disk_name(disk), - (rt_uint64_t)rt_le64_to_cpu(agpt->start_lba), - (rt_uint64_t)lastlba); - - ++error_found; - } - - if (error_found) - { - LOG_W("GPT: Use GNU Parted to correct GPT errors"); - } -} - -/** - * @brief This function search disk for valid GPT headers and PTEs. - * - * @param disk the disk parsed partitions. - * @param gpt the GPT header ptr, filled on return. - * @param ptes the PTEs ptr, filled on return. - * @return 1 if valid, 0 on error. - * If valid, returns pointers to newly allocated GPT header and PTEs. - * Validity depends on PMBR being valid (or being overridden by the - * 'gpt' kernel command line option) and finding either the Primary - * GPT header and PTEs valid, or the Alternate GPT header and PTEs - * valid. If the Primary GPT header is not valid, the Alternate GPT header - * is not checked unless the 'gpt' kernel command line option is passed. - * This protects against devices which misreport their size, and forces - * the user to decide to use the Alternate GPT. - */ -static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk, - gpt_header **gpt, gpt_entry **ptes) -{ - int good_pgpt = 0, good_agpt = 0, good_pmbr = 0; - gpt_header *pgpt = RT_NULL, *agpt = RT_NULL; - gpt_entry *pptes = RT_NULL, *aptes = RT_NULL; - legacy_mbr *legacymbr; - rt_size_t total_sectors = rt_blk_disk_get_capacity(disk); - rt_size_t lastlba; - - if (!ptes) - { - return RT_FALSE; - } - - lastlba = last_lba(disk); - - if (!force_gpt) - { - /* This will be added to the EFI Spec. per Intel after v1.02. */ - legacymbr = rt_malloc(sizeof(*legacymbr)); - - if (!legacymbr) - { - return RT_FALSE; - } - - read_lba(disk, 0, (rt_uint8_t *)legacymbr, sizeof(*legacymbr)); - good_pmbr = is_pmbr_valid(legacymbr, total_sectors); - rt_free(legacymbr); - - if (!good_pmbr) - { - return RT_FALSE; - } - - LOG_D("%s: Device has a %s MBR", to_disk_name(disk), - good_pmbr == GPT_MBR_PROTECTIVE ? "protective" : "hybrid"); - } - - good_pgpt = is_gpt_valid(disk, GPT_PRIMARY_PARTITION_TABLE_LBA, &pgpt, &pptes); - - if (good_pgpt) - { - good_agpt = is_gpt_valid(disk, rt_le64_to_cpu(pgpt->alternate_lba), &agpt, &aptes); - } - - if (!good_agpt && force_gpt) - { - good_agpt = is_gpt_valid(disk, lastlba, &agpt, &aptes); - } - - /* The obviously unsuccessful case */ - if (!good_pgpt && !good_agpt) - { - goto _fail; - } - - compare_gpts(disk, pgpt, agpt, lastlba); - - /* The good cases */ - if (good_pgpt) - { - *gpt = pgpt; - *ptes = pptes; - rt_free(agpt); - rt_free(aptes); - - if (!good_agpt) - { - LOG_D("%s: Alternate GPT is invalid, using primary GPT", to_disk_name(disk)); - } - - return RT_TRUE; - } - else if (good_agpt) - { - *gpt = agpt; - *ptes = aptes; - rt_free(pgpt); - rt_free(pptes); - - LOG_D("%s: Primary GPT is invalid, using alternate GPT", to_disk_name(disk)); - - return RT_TRUE; - } - -_fail: - rt_free(pgpt); - rt_free(agpt); - rt_free(pptes); - rt_free(aptes); - - *gpt = RT_NULL; - *ptes = RT_NULL; - - return RT_FALSE; -} - -rt_err_t efi_partition(struct rt_blk_disk *disk) -{ - rt_uint32_t entries_nr; - gpt_header *gpt = RT_NULL; - gpt_entry *ptes = RT_NULL; - - if (!find_valid_gpt(disk, &gpt, &ptes) || !gpt || !ptes) - { - rt_free(gpt); - rt_free(ptes); - - return -RT_EINVAL; - } - - entries_nr = rt_le32_to_cpu(gpt->num_partition_entries); - - for (int i = 0; i < entries_nr && i < disk->max_partitions; ++i) - { - rt_uint64_t start = rt_le64_to_cpu(ptes[i].starting_lba); - rt_uint64_t size = rt_le64_to_cpu(ptes[i].ending_lba) - - rt_le64_to_cpu(ptes[i].starting_lba) + 1ULL; - - if (!is_pte_valid(&ptes[i], last_lba(disk))) - { - continue; - } - - if (blk_put_partition(disk, "gpt", start, size, i) == -RT_ENOMEM) - { - break; - } - } - - rt_free(gpt); - rt_free(ptes); - - return RT_EOK; -} diff --git a/rt-thread/components/drivers/block/partitions/efi.h b/rt-thread/components/drivers/block/partitions/efi.h deleted file mode 100644 index 6a10ec8..0000000 --- a/rt-thread/components/drivers/block/partitions/efi.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-05-05 linzhenxing first version - * 2023-02-25 GuEe-GUI make blk interface - */ - -#ifndef __PARTITIONS_EFI_H__ -#define __PARTITIONS_EFI_H__ - -#include "../blk_partition.h" -#include -#include - -#define MSDOS_MBR_SIGNATURE 0xaa55 -#define EFI_PMBR_OSTYPE_EFI 0xef -#define EFI_PMBR_OSTYPE_EFI_GPT 0xee - -#define GPT_MBR_PROTECTIVE 1 -#define GPT_MBR_HYBRID 2 - -#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL -#define GPT_HEADER_REVISION_V1 0x00010000 -#define GPT_PRIMARY_PARTITION_TABLE_LBA 1 - -#ifndef __UUID_H__ -#define UUID_SIZE 16 - -typedef struct -{ - rt_uint8_t b[UUID_SIZE]; -} guid_t; -#endif /* __UUID_H__ */ - -#ifndef __EFI_H__ -typedef guid_t efi_guid_t rt_align(4); - -#define EFI_GUID(a, b, c, d...) (efi_guid_t) \ -{{ \ - (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ - (b) & 0xff, ((b) >> 8) & 0xff, \ - (c) & 0xff, ((c) >> 8) & 0xff, \ - d \ -}} - -#define NULL_GUID \ - EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) - -rt_inline int efi_guidcmp(efi_guid_t left, efi_guid_t right) -{ - return rt_memcmp(&left, &right, sizeof (efi_guid_t)); -} -#endif /* __EFI_H__ */ - -#define PARTITION_SYSTEM_GUID \ - EFI_GUID(0xc12a7328, 0xf81f, 0x11d2, 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b) - -#define LEGACY_MBR_PARTITION_GUID \ - EFI_GUID(0x024dee41, 0x33e7, 0x11d3, 0x9d, 0x69, 0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f) - -#define PARTITION_MSFT_RESERVED_GUID \ - EFI_GUID(0xe3c9e316, 0x0b5c, 0x4db8, 0x81, 0x7d, 0xf9, 0x2d, 0xf0, 0x02, 0x15, 0xae) - -#define PARTITION_BASIC_DATA_GUID \ - EFI_GUID(0xebd0a0a2, 0xb9e5, 0x4433, 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7) - -rt_packed(struct _gpt_header -{ - rt_le64_t signature; - rt_le32_t revision; - rt_le32_t header_size; - rt_le32_t header_crc32; - rt_le32_t reserved1; - rt_le64_t start_lba; - rt_le64_t alternate_lba; - rt_le64_t first_usable_lba; - rt_le64_t last_usable_lba; - efi_guid_t disk_guid; - rt_le64_t partition_entry_lba; - rt_le32_t num_partition_entries; - rt_le32_t sizeof_partition_entry; - rt_le32_t partition_entry_array_crc32; - - /* - * The rest of the logical block is reserved by UEFI and must be zero. - * EFI standard handles this by: - * - * uint8_t reserved2[BlockSize - 92]; - */ -}); -typedef struct _gpt_header gpt_header; - -rt_packed(struct _gpt_entry_attributes -{ - rt_uint64_t required_to_function:1; - rt_uint64_t reserved:47; - rt_uint64_t type_guid_specific:16; -}); -typedef struct _gpt_entry_attributes gpt_entry_attributes; - -rt_packed(struct _gpt_entry -{ - efi_guid_t partition_type_guid; - efi_guid_t unique_partition_guid; - rt_le64_t starting_lba; - rt_le64_t ending_lba; - gpt_entry_attributes attributes; - rt_le16_t partition_name[72/sizeof(rt_le16_t)]; -}); -typedef struct _gpt_entry gpt_entry; - -rt_packed(struct _gpt_mbr_record -{ - rt_uint8_t boot_indicator; /* unused by EFI, set to 0x80 for bootable */ - rt_uint8_t start_head; /* unused by EFI, pt start in CHS */ - rt_uint8_t start_sector; /* unused by EFI, pt start in CHS */ - rt_uint8_t start_track; - rt_uint8_t os_type; /* EFI and legacy non-EFI OS types */ - rt_uint8_t end_head; /* unused by EFI, pt end in CHS */ - rt_uint8_t end_sector; /* unused by EFI, pt end in CHS */ - rt_uint8_t end_track; /* unused by EFI, pt end in CHS */ - rt_le32_t starting_lba; /* used by EFI - start addr of the on disk pt */ - rt_le32_t size_in_lba; /* used by EFI - size of pt in LBA */ -}); -typedef struct _gpt_mbr_record gpt_mbr_record; - -rt_packed(struct _legacy_mbr -{ - rt_uint8_t boot_code[440]; - rt_le32_t unique_mbr_signature; - rt_le16_t unknown; - gpt_mbr_record partition_record[4]; - rt_le16_t signature; -}); -typedef struct _legacy_mbr legacy_mbr; - -#endif /* __PARTITIONS_EFI_H__ */ diff --git a/rt-thread/components/drivers/can/dev_can.c b/rt-thread/components/drivers/can/dev_can.c deleted file mode 100644 index 186f113..0000000 --- a/rt-thread/components/drivers/can/dev_can.c +++ /dev/null @@ -1,974 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2015-05-14 aubrcool@qq.com first version - * 2015-07-06 Bernard code cleanup and remove RT_CAN_USING_LED; - */ - -#include -#include -#include - -#define CAN_LOCK(can) rt_mutex_take(&(can->lock), RT_WAITING_FOREVER) -#define CAN_UNLOCK(can) rt_mutex_release(&(can->lock)) - -static rt_err_t rt_can_init(struct rt_device *dev) -{ - rt_err_t result = RT_EOK; - struct rt_can_device *can; - - RT_ASSERT(dev != RT_NULL); - can = (struct rt_can_device *)dev; - - /* initialize rx/tx */ - can->can_rx = RT_NULL; - can->can_tx = RT_NULL; -#ifdef RT_CAN_USING_HDR - can->hdr = RT_NULL; -#endif - - /* apply configuration */ - if (can->ops->configure) - result = can->ops->configure(can, &can->config); - else - result = -RT_ENOSYS; - - return result; -} - -/* - * can interrupt routines - */ -rt_inline rt_ssize_t _can_int_rx(struct rt_can_device *can, struct rt_can_msg *data, rt_ssize_t msgs) -{ - rt_ssize_t size; - struct rt_can_rx_fifo *rx_fifo; - RT_ASSERT(can != RT_NULL); - size = msgs; - - rx_fifo = (struct rt_can_rx_fifo *) can->can_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - /* read from software FIFO */ - while (msgs / sizeof(struct rt_can_msg) > 0) - { - rt_base_t level; -#ifdef RT_CAN_USING_HDR - rt_int8_t hdr; -#endif /*RT_CAN_USING_HDR*/ - struct rt_can_msg_list *listmsg = RT_NULL; - - /* disable interrupt */ - level = rt_hw_interrupt_disable(); -#ifdef RT_CAN_USING_HDR - hdr = data->hdr_index; - - if (hdr >= 0 && can->hdr && hdr < can->config.maxhdr && !rt_list_isempty(&can->hdr[hdr].list)) - { - listmsg = rt_list_entry(can->hdr[hdr].list.next, struct rt_can_msg_list, hdrlist); - rt_list_remove(&listmsg->list); - rt_list_remove(&listmsg->hdrlist); - if (can->hdr[hdr].msgs) - { - can->hdr[hdr].msgs--; - } - listmsg->owner = RT_NULL; - } - else if (hdr == -1) -#endif /*RT_CAN_USING_HDR*/ - { - if (!rt_list_isempty(&rx_fifo->uselist)) - { - listmsg = rt_list_entry(rx_fifo->uselist.next, struct rt_can_msg_list, list); - rt_list_remove(&listmsg->list); -#ifdef RT_CAN_USING_HDR - rt_list_remove(&listmsg->hdrlist); - if (listmsg->owner != RT_NULL && listmsg->owner->msgs) - { - listmsg->owner->msgs--; - } - listmsg->owner = RT_NULL; -#endif /*RT_CAN_USING_HDR*/ - } - else - { - /* no data, enable interrupt and break out */ - rt_hw_interrupt_enable(level); - break; - } - } - - /* enable interrupt */ - rt_hw_interrupt_enable(level); - if (listmsg != RT_NULL) - { - rt_memcpy(data, &listmsg->data, sizeof(struct rt_can_msg)); - - level = rt_hw_interrupt_disable(); - rt_list_insert_before(&rx_fifo->freelist, &listmsg->list); - rx_fifo->freenumbers++; - RT_ASSERT(rx_fifo->freenumbers <= can->config.msgboxsz); - rt_hw_interrupt_enable(level); - - listmsg = RT_NULL; - } - else - { - break; - } - data ++; - msgs -= sizeof(struct rt_can_msg); - } - - return (size - msgs); -} - -rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *data, int msgs) -{ - int size; - struct rt_can_tx_fifo *tx_fifo; - - RT_ASSERT(can != RT_NULL); - - size = msgs; - tx_fifo = (struct rt_can_tx_fifo *) can->can_tx; - RT_ASSERT(tx_fifo != RT_NULL); - - while (msgs) - { - rt_base_t level; - rt_uint32_t no; - rt_uint32_t result; - struct rt_can_sndbxinx_list *tx_tosnd = RT_NULL; - - rt_sem_take(&(tx_fifo->sem), RT_WAITING_FOREVER); - level = rt_hw_interrupt_disable(); - tx_tosnd = rt_list_entry(tx_fifo->freelist.next, struct rt_can_sndbxinx_list, list); - RT_ASSERT(tx_tosnd != RT_NULL); - rt_list_remove(&tx_tosnd->list); - rt_hw_interrupt_enable(level); - - no = ((rt_ubase_t)tx_tosnd - (rt_ubase_t)tx_fifo->buffer) / sizeof(struct rt_can_sndbxinx_list); - tx_tosnd->result = RT_CAN_SND_RESULT_WAIT; - rt_completion_init(&tx_tosnd->completion); - if (can->ops->sendmsg(can, data, no) != RT_EOK) - { - /* send failed. */ - level = rt_hw_interrupt_disable(); - rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list); - rt_hw_interrupt_enable(level); - rt_sem_release(&(tx_fifo->sem)); - goto err_ret; - } - - can->status.sndchange = 1; - rt_completion_wait(&(tx_tosnd->completion), RT_WAITING_FOREVER); - - level = rt_hw_interrupt_disable(); - result = tx_tosnd->result; - if (!rt_list_isempty(&tx_tosnd->list)) - { - rt_list_remove(&tx_tosnd->list); - } - rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list); - rt_hw_interrupt_enable(level); - rt_sem_release(&(tx_fifo->sem)); - - if (result == RT_CAN_SND_RESULT_OK) - { - level = rt_hw_interrupt_disable(); - can->status.sndpkg++; - rt_hw_interrupt_enable(level); - - data ++; - msgs -= sizeof(struct rt_can_msg); - if (!msgs) break; - } - else - { -err_ret: - level = rt_hw_interrupt_disable(); - can->status.dropedsndpkg++; - rt_hw_interrupt_enable(level); - break; - } - } - - return (size - msgs); -} - -rt_inline int _can_int_tx_priv(struct rt_can_device *can, const struct rt_can_msg *data, int msgs) -{ - int size; - rt_base_t level; - rt_uint32_t no, result; - struct rt_can_tx_fifo *tx_fifo; - - RT_ASSERT(can != RT_NULL); - - size = msgs; - tx_fifo = (struct rt_can_tx_fifo *) can->can_tx; - RT_ASSERT(tx_fifo != RT_NULL); - - while (msgs) - { - no = data->priv; - if (no >= can->config.sndboxnumber) - { - break; - } - - level = rt_hw_interrupt_disable(); - if ((tx_fifo->buffer[no].result != RT_CAN_SND_RESULT_OK)) - { - rt_hw_interrupt_enable(level); - - rt_completion_wait(&(tx_fifo->buffer[no].completion), RT_WAITING_FOREVER); - continue; - } - tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_WAIT; - rt_hw_interrupt_enable(level); - - if (can->ops->sendmsg(can, data, no) != RT_EOK) - { - continue; - } - can->status.sndchange = 1; - rt_completion_wait(&(tx_fifo->buffer[no].completion), RT_WAITING_FOREVER); - - result = tx_fifo->buffer[no].result; - if (result == RT_CAN_SND_RESULT_OK) - { - level = rt_hw_interrupt_disable(); - can->status.sndpkg++; - rt_hw_interrupt_enable(level); - data ++; - msgs -= sizeof(struct rt_can_msg); - if (!msgs) break; - } - else - { - level = rt_hw_interrupt_disable(); - can->status.dropedsndpkg++; - rt_hw_interrupt_enable(level); - break; - } - } - - return (size - msgs); -} - -static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag) -{ - struct rt_can_device *can; - char tmpname[16]; - RT_ASSERT(dev != RT_NULL); - can = (struct rt_can_device *)dev; - - CAN_LOCK(can); - - /* get open flags */ - dev->open_flag = oflag & 0xff; - if (can->can_rx == RT_NULL) - { - if (oflag & RT_DEVICE_FLAG_INT_RX) - { - int i = 0; - struct rt_can_rx_fifo *rx_fifo; - - rx_fifo = (struct rt_can_rx_fifo *) rt_malloc(sizeof(struct rt_can_rx_fifo) + - can->config.msgboxsz * sizeof(struct rt_can_msg_list)); - RT_ASSERT(rx_fifo != RT_NULL); - - rx_fifo->buffer = (struct rt_can_msg_list *)(rx_fifo + 1); - rt_memset(rx_fifo->buffer, 0, can->config.msgboxsz * sizeof(struct rt_can_msg_list)); - rt_list_init(&rx_fifo->freelist); - rt_list_init(&rx_fifo->uselist); - rx_fifo->freenumbers = can->config.msgboxsz; - for (i = 0; i < can->config.msgboxsz; i++) - { - rt_list_insert_before(&rx_fifo->freelist, &rx_fifo->buffer[i].list); -#ifdef RT_CAN_USING_HDR - rt_list_init(&rx_fifo->buffer[i].hdrlist); - rx_fifo->buffer[i].owner = RT_NULL; -#endif - } - can->can_rx = rx_fifo; - - dev->open_flag |= RT_DEVICE_FLAG_INT_RX; - /* open can rx interrupt */ - can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX); - } - } - - if (can->can_tx == RT_NULL) - { - if (oflag & RT_DEVICE_FLAG_INT_TX) - { - int i = 0; - struct rt_can_tx_fifo *tx_fifo; - - tx_fifo = (struct rt_can_tx_fifo *) rt_malloc(sizeof(struct rt_can_tx_fifo) + - can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list)); - RT_ASSERT(tx_fifo != RT_NULL); - - tx_fifo->buffer = (struct rt_can_sndbxinx_list *)(tx_fifo + 1); - rt_memset(tx_fifo->buffer, 0, - can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list)); - rt_list_init(&tx_fifo->freelist); - for (i = 0; i < can->config.sndboxnumber; i++) - { - rt_list_insert_before(&tx_fifo->freelist, &tx_fifo->buffer[i].list); - rt_completion_init(&(tx_fifo->buffer[i].completion)); - tx_fifo->buffer[i].result = RT_CAN_SND_RESULT_OK; - } - - rt_sprintf(tmpname, "%stl", dev->parent.name); - rt_sem_init(&(tx_fifo->sem), tmpname, can->config.sndboxnumber, RT_IPC_FLAG_FIFO); - can->can_tx = tx_fifo; - - dev->open_flag |= RT_DEVICE_FLAG_INT_TX; - /* open can tx interrupt */ - can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX); - } - } - - can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_CAN_INT_ERR); - -#ifdef RT_CAN_USING_HDR - if (can->hdr == RT_NULL) - { - int i = 0; - struct rt_can_hdr *phdr; - - phdr = (struct rt_can_hdr *) rt_malloc(can->config.maxhdr * sizeof(struct rt_can_hdr)); - RT_ASSERT(phdr != RT_NULL); - rt_memset(phdr, 0, can->config.maxhdr * sizeof(struct rt_can_hdr)); - for (i = 0; i < can->config.maxhdr; i++) - { - rt_list_init(&phdr[i].list); - } - - can->hdr = phdr; - } -#endif - - if (!can->timerinitflag) - { - can->timerinitflag = 1; - - rt_timer_start(&can->timer); - } - - CAN_UNLOCK(can); - - return RT_EOK; -} - -static rt_err_t rt_can_close(struct rt_device *dev) -{ - struct rt_can_device *can; - - RT_ASSERT(dev != RT_NULL); - can = (struct rt_can_device *)dev; - - CAN_LOCK(can); - - /* this device has more reference count */ - if (dev->ref_count > 1) - { - CAN_UNLOCK(can); - return RT_EOK; - } - - if (can->timerinitflag) - { - can->timerinitflag = 0; - - rt_timer_stop(&can->timer); - } - - can->status_indicate.ind = RT_NULL; - can->status_indicate.args = RT_NULL; - -#ifdef RT_CAN_USING_HDR - if (can->hdr != RT_NULL) - { - rt_free(can->hdr); - can->hdr = RT_NULL; - } -#endif - - if (dev->open_flag & RT_DEVICE_FLAG_INT_RX) - { - struct rt_can_rx_fifo *rx_fifo; - - /* clear can rx interrupt */ - can->ops->control(can, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_RX); - - rx_fifo = (struct rt_can_rx_fifo *)can->can_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_free(rx_fifo); - dev->open_flag &= ~RT_DEVICE_FLAG_INT_RX; - can->can_rx = RT_NULL; - } - - if (dev->open_flag & RT_DEVICE_FLAG_INT_TX) - { - struct rt_can_tx_fifo *tx_fifo; - - /* clear can tx interrupt */ - can->ops->control(can, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_TX); - - tx_fifo = (struct rt_can_tx_fifo *)can->can_tx; - RT_ASSERT(tx_fifo != RT_NULL); - - rt_sem_detach(&(tx_fifo->sem)); - rt_free(tx_fifo); - dev->open_flag &= ~RT_DEVICE_FLAG_INT_TX; - can->can_tx = RT_NULL; - } - - can->ops->control(can, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_CAN_INT_ERR); - can->ops->control(can, RT_CAN_CMD_START, RT_FALSE); - CAN_UNLOCK(can); - - return RT_EOK; -} - -static rt_ssize_t rt_can_read(struct rt_device *dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - struct rt_can_device *can; - - RT_ASSERT(dev != RT_NULL); - if (size == 0) return 0; - - can = (struct rt_can_device *)dev; - - if ((dev->open_flag & RT_DEVICE_FLAG_INT_RX) && (dev->ref_count > 0)) - { - return _can_int_rx(can, buffer, size); - } - - return 0; -} - -static rt_ssize_t rt_can_write(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct rt_can_device *can; - - RT_ASSERT(dev != RT_NULL); - if (size == 0) return 0; - - can = (struct rt_can_device *)dev; - - if ((dev->open_flag & RT_DEVICE_FLAG_INT_TX) && (dev->ref_count > 0)) - { - if (can->config.privmode) - { - return _can_int_tx_priv(can, buffer, size); - } - else - { - return _can_int_tx(can, buffer, size); - } - } - return 0; -} - -static rt_err_t rt_can_control(struct rt_device *dev, - int cmd, - void *args) -{ - struct rt_can_device *can; - rt_err_t res; - - res = RT_EOK; - RT_ASSERT(dev != RT_NULL); - can = (struct rt_can_device *)dev; - - switch (cmd) - { - case RT_DEVICE_CTRL_SUSPEND: - /* suspend device */ - dev->flag |= RT_DEVICE_FLAG_SUSPENDED; - break; - - case RT_DEVICE_CTRL_RESUME: - /* resume device */ - dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED; - break; - - case RT_DEVICE_CTRL_CONFIG: - /* configure device */ - res = can->ops->configure(can, (struct can_configure *)args); - break; - - case RT_CAN_CMD_SET_PRIV: - /* configure device */ - if ((rt_uint32_t)(rt_ubase_t)args != can->config.privmode) - { - int i; - rt_base_t level; - struct rt_can_tx_fifo *tx_fifo; - - res = can->ops->control(can, cmd, args); - if (res != RT_EOK) return res; - tx_fifo = (struct rt_can_tx_fifo *) can->can_tx; - if (can->config.privmode) - { - for (i = 0; i < can->config.sndboxnumber; i++) - { - level = rt_hw_interrupt_disable(); - if(rt_list_isempty(&tx_fifo->buffer[i].list)) - { - rt_sem_release(&(tx_fifo->sem)); - } - else - { - rt_list_remove(&tx_fifo->buffer[i].list); - } - rt_hw_interrupt_enable(level); - } - - } - else - { - for (i = 0; i < can->config.sndboxnumber; i++) - { - level = rt_hw_interrupt_disable(); - if (tx_fifo->buffer[i].result == RT_CAN_SND_RESULT_OK) - { - rt_list_insert_before(&tx_fifo->freelist, &tx_fifo->buffer[i].list); - } - rt_hw_interrupt_enable(level); - } - } - } - break; - - case RT_CAN_CMD_SET_STATUS_IND: - can->status_indicate.ind = ((rt_can_status_ind_type_t)args)->ind; - can->status_indicate.args = ((rt_can_status_ind_type_t)args)->args; - break; - -#ifdef RT_CAN_USING_HDR - case RT_CAN_CMD_SET_FILTER: - res = can->ops->control(can, cmd, args); - if (res != RT_EOK || can->hdr == RT_NULL) - { - return res; - } - - struct rt_can_filter_config *pfilter; - struct rt_can_filter_item *pitem; - rt_uint32_t count; - rt_base_t level; - - pfilter = (struct rt_can_filter_config *)args; - RT_ASSERT(pfilter); - count = pfilter->count; - pitem = pfilter->items; - if (pfilter->actived) - { - while (count) - { - if (pitem->hdr_bank >= can->config.maxhdr || pitem->hdr_bank < 0) - { - count--; - pitem++; - continue; - } - - level = rt_hw_interrupt_disable(); - if (!can->hdr[pitem->hdr_bank].connected) - { - rt_hw_interrupt_enable(level); - rt_memcpy(&can->hdr[pitem->hdr_bank].filter, pitem, - sizeof(struct rt_can_filter_item)); - level = rt_hw_interrupt_disable(); - can->hdr[pitem->hdr_bank].connected = 1; - can->hdr[pitem->hdr_bank].msgs = 0; - rt_list_init(&can->hdr[pitem->hdr_bank].list); - } - rt_hw_interrupt_enable(level); - - count--; - pitem++; - } - } - else - { - while (count) - { - if (pitem->hdr_bank >= can->config.maxhdr || pitem->hdr_bank < 0) - { - count--; - pitem++; - continue; - } - level = rt_hw_interrupt_disable(); - - if (can->hdr[pitem->hdr_bank].connected) - { - can->hdr[pitem->hdr_bank].connected = 0; - can->hdr[pitem->hdr_bank].msgs = 0; - if (!rt_list_isempty(&can->hdr[pitem->hdr_bank].list)) - { - rt_list_remove(can->hdr[pitem->hdr_bank].list.next); - } - rt_hw_interrupt_enable(level); - rt_memset(&can->hdr[pitem->hdr_bank].filter, 0, - sizeof(struct rt_can_filter_item)); - } - else - { - rt_hw_interrupt_enable(level); - } - count--; - pitem++; - } - } - break; -#endif /*RT_CAN_USING_HDR*/ -#ifdef RT_CAN_USING_BUS_HOOK - case RT_CAN_CMD_SET_BUS_HOOK: - can->bus_hook = (rt_can_bus_hook) args; - break; -#endif /*RT_CAN_USING_BUS_HOOK*/ - default : - /* control device */ - if (can->ops->control != RT_NULL) - { - res = can->ops->control(can, cmd, args); - } - else - { - res = -RT_ENOSYS; - } - break; - } - - return res; -} - -/* - * can timer - */ -static void cantimeout(void *arg) -{ - rt_can_t can; - - can = (rt_can_t)arg; - RT_ASSERT(can); - rt_device_control((rt_device_t)can, RT_CAN_CMD_GET_STATUS, (void *)&can->status); - - if (can->status_indicate.ind != RT_NULL) - { - can->status_indicate.ind(can, can->status_indicate.args); - } -#ifdef RT_CAN_USING_BUS_HOOK - if(can->bus_hook) - { - can->bus_hook(can); - } -#endif /*RT_CAN_USING_BUS_HOOK*/ - if (can->timerinitflag == 1) - { - can->timerinitflag = 0xFF; - } -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops can_device_ops = -{ - rt_can_init, - rt_can_open, - rt_can_close, - rt_can_read, - rt_can_write, - rt_can_control -}; -#endif - -/* - * can register - */ -rt_err_t rt_hw_can_register(struct rt_can_device *can, - const char *name, - const struct rt_can_ops *ops, - void *data) -{ - struct rt_device *device; - RT_ASSERT(can != RT_NULL); - - device = &(can->parent); - - device->type = RT_Device_Class_CAN; - device->rx_indicate = RT_NULL; - device->tx_complete = RT_NULL; -#ifdef RT_CAN_USING_HDR - can->hdr = RT_NULL; -#endif - can->can_rx = RT_NULL; - can->can_tx = RT_NULL; - rt_mutex_init(&(can->lock), "can", RT_IPC_FLAG_PRIO); -#ifdef RT_CAN_USING_BUS_HOOK - can->bus_hook = RT_NULL; -#endif /*RT_CAN_USING_BUS_HOOK*/ - -#ifdef RT_USING_DEVICE_OPS - device->ops = &can_device_ops; -#else - device->init = rt_can_init; - device->open = rt_can_open; - device->close = rt_can_close; - device->read = rt_can_read; - device->write = rt_can_write; - device->control = rt_can_control; -#endif - can->ops = ops; - - can->status_indicate.ind = RT_NULL; - can->status_indicate.args = RT_NULL; - rt_memset(&can->status, 0, sizeof(can->status)); - - device->user_data = data; - - can->timerinitflag = 0; - rt_timer_init(&can->timer, - name, - cantimeout, - (void *)can, - can->config.ticks, - RT_TIMER_FLAG_PERIODIC); - /* register a character device */ - return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); -} - -/* ISR for can interrupt */ -void rt_hw_can_isr(struct rt_can_device *can, int event) -{ - switch (event & 0xff) - { - case RT_CAN_EVENT_RXOF_IND: - { - rt_base_t level; - level = rt_hw_interrupt_disable(); - can->status.dropedrcvpkg++; - rt_hw_interrupt_enable(level); - } - case RT_CAN_EVENT_RX_IND: - { - struct rt_can_msg tmpmsg; - struct rt_can_rx_fifo *rx_fifo; - struct rt_can_msg_list *listmsg = RT_NULL; -#ifdef RT_CAN_USING_HDR - rt_int8_t hdr; -#endif - int ch = -1; - rt_base_t level; - rt_uint32_t no; - - rx_fifo = (struct rt_can_rx_fifo *)can->can_rx; - RT_ASSERT(rx_fifo != RT_NULL); - /* interrupt mode receive */ - RT_ASSERT(can->parent.open_flag & RT_DEVICE_FLAG_INT_RX); - - no = event >> 8; - ch = can->ops->recvmsg(can, &tmpmsg, no); - if (ch == -1) break; - - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - can->status.rcvpkg++; - can->status.rcvchange = 1; - if (!rt_list_isempty(&rx_fifo->freelist)) - { - listmsg = rt_list_entry(rx_fifo->freelist.next, struct rt_can_msg_list, list); - rt_list_remove(&listmsg->list); -#ifdef RT_CAN_USING_HDR - rt_list_remove(&listmsg->hdrlist); - if (listmsg->owner != RT_NULL && listmsg->owner->msgs) - { - listmsg->owner->msgs--; - } - listmsg->owner = RT_NULL; -#endif /*RT_CAN_USING_HDR*/ - RT_ASSERT(rx_fifo->freenumbers > 0); - rx_fifo->freenumbers--; - } - else if (!rt_list_isempty(&rx_fifo->uselist)) - { - listmsg = rt_list_entry(rx_fifo->uselist.next, struct rt_can_msg_list, list); - can->status.dropedrcvpkg++; - rt_list_remove(&listmsg->list); -#ifdef RT_CAN_USING_HDR - rt_list_remove(&listmsg->hdrlist); - if (listmsg->owner != RT_NULL && listmsg->owner->msgs) - { - listmsg->owner->msgs--; - } - listmsg->owner = RT_NULL; -#endif - } - /* enable interrupt */ - rt_hw_interrupt_enable(level); - - if (listmsg != RT_NULL) - { - rt_memcpy(&listmsg->data, &tmpmsg, sizeof(struct rt_can_msg)); - level = rt_hw_interrupt_disable(); - rt_list_insert_before(&rx_fifo->uselist, &listmsg->list); -#ifdef RT_CAN_USING_HDR - hdr = tmpmsg.hdr_index; - if (can->hdr != RT_NULL) - { - RT_ASSERT(hdr < can->config.maxhdr && hdr >= 0); - if (can->hdr[hdr].connected) - { - rt_list_insert_before(&can->hdr[hdr].list, &listmsg->hdrlist); - listmsg->owner = &can->hdr[hdr]; - can->hdr[hdr].msgs++; - } - - } -#endif - rt_hw_interrupt_enable(level); - } - - /* invoke callback */ -#ifdef RT_CAN_USING_HDR - if (can->hdr != RT_NULL && can->hdr[hdr].connected && can->hdr[hdr].filter.ind) - { - rt_size_t rx_length; - RT_ASSERT(hdr < can->config.maxhdr && hdr >= 0); - - level = rt_hw_interrupt_disable(); - rx_length = can->hdr[hdr].msgs * sizeof(struct rt_can_msg); - rt_hw_interrupt_enable(level); - if (rx_length) - { - can->hdr[hdr].filter.ind(&can->parent, can->hdr[hdr].filter.args, hdr, rx_length); - } - } - else -#endif - { - if (can->parent.rx_indicate != RT_NULL) - { - rt_size_t rx_length; - - level = rt_hw_interrupt_disable(); - /* get rx length */ - rx_length = rt_list_len(&rx_fifo->uselist)* sizeof(struct rt_can_msg); - rt_hw_interrupt_enable(level); - - if (rx_length) - { - can->parent.rx_indicate(&can->parent, rx_length); - } - } - } - break; - } - - case RT_CAN_EVENT_TX_DONE: - case RT_CAN_EVENT_TX_FAIL: - { - struct rt_can_tx_fifo *tx_fifo; - rt_uint32_t no; - no = event >> 8; - tx_fifo = (struct rt_can_tx_fifo *) can->can_tx; - RT_ASSERT(tx_fifo != RT_NULL); - - if ((event & 0xff) == RT_CAN_EVENT_TX_DONE) - { - tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_OK; - } - else - { - tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_ERR; - } - rt_completion_done(&(tx_fifo->buffer[no].completion)); - break; - } - } -} - -#ifdef RT_USING_FINSH -#include -int cmd_canstat(int argc, void **argv) -{ - static const char *ErrCode[] = - { - "No Error!", - "Warning !", - "Passive !", - "Bus Off !" - }; - - if (argc >= 2) - { - struct rt_can_status status; - rt_device_t candev = rt_device_find(argv[1]); - if (!candev) - { - rt_kprintf(" Can't find can device %s\n", argv[1]); - return -1; - } - rt_kprintf(" Found can device: %s...", argv[1]); - - rt_device_control(candev, RT_CAN_CMD_GET_STATUS, &status); - rt_kprintf("\n Receive...error..count: %010ld. Send.....error....count: %010ld.", - status.rcverrcnt, status.snderrcnt); - rt_kprintf("\n Bit..pad..error..count: %010ld. Format...error....count: %010ld", - status.bitpaderrcnt, status.formaterrcnt); - rt_kprintf("\n Ack.......error..count: %010ld. Bit......error....count: %010ld.", - status.ackerrcnt, status.biterrcnt); - rt_kprintf("\n CRC.......error..count: %010ld. Error.code.[%010ld]: ", - status.crcerrcnt, status.errcode); - switch (status.errcode) - { - case 0: - rt_kprintf("%s.", ErrCode[0]); - break; - case 1: - rt_kprintf("%s.", ErrCode[1]); - break; - case 2: - case 3: - rt_kprintf("%s.", ErrCode[2]); - break; - case 4: - case 5: - case 6: - case 7: - rt_kprintf("%s.", ErrCode[3]); - break; - } - rt_kprintf("\n Total.receive.packages: %010ld. Dropped.receive.packages: %010ld.", - status.rcvpkg, status.dropedrcvpkg); - rt_kprintf("\n Total..send...packages: %010ld. Dropped...send..packages: %010ld.\n", - status.sndpkg + status.dropedsndpkg, status.dropedsndpkg); - } - else - { - rt_kprintf(" Invalid Call %s\n", argv[0]); - rt_kprintf(" Please using %s cannamex .Here canname is driver name and x is candrive number.\n", argv[0]); - } - return 0; -} -MSH_CMD_EXPORT_ALIAS(cmd_canstat, canstat, stat can device status); -#endif diff --git a/rt-thread/components/drivers/clk/Kconfig b/rt-thread/components/drivers/clk/Kconfig index c13ccbf..3c34d38 100644 --- a/rt-thread/components/drivers/clk/Kconfig +++ b/rt-thread/components/drivers/clk/Kconfig @@ -3,7 +3,3 @@ menuconfig RT_USING_CLK depends on RT_USING_DM select RT_USING_ADT_REF default y - -if RT_USING_CLK - osource "$(SOC_DM_CLK_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/clk/clk.c b/rt-thread/components/drivers/clk/clk.c index 2bb45f8..053c67d 100644 --- a/rt-thread/components/drivers/clk/clk.c +++ b/rt-thread/components/drivers/clk/clk.c @@ -55,10 +55,6 @@ static struct rt_clk *clk_alloc(struct rt_clk_node *clk_np, const char *dev_id, clk->fw_node = fw_node; } - else - { - clk = rt_err_ptr(-RT_ENOMEM); - } return clk; } @@ -80,7 +76,7 @@ static struct rt_clk *clk_create(struct rt_clk_node *clk_np, const char *dev_id, { struct rt_clk *clk = clk_alloc(clk_np, dev_id, con_id, fw_node); - if (!rt_is_err(clk)) + if (clk) { clk_get(clk_np); @@ -139,6 +135,15 @@ rt_err_t rt_clk_register(struct rt_clk_node *clk_np, struct rt_clk_node *parent_ struct rt_clk *clk = RT_NULL; if (clk_np) + { + clk = clk_alloc(clk_np, RT_NULL, RT_NULL, RT_NULL); + } + else + { + err = -RT_EINVAL; + } + + if (!err && clk_np) { clk_np->clk = clk; @@ -147,12 +152,6 @@ rt_err_t rt_clk_register(struct rt_clk_node *clk_np, struct rt_clk_node *parent_ clk_np->ops = &unused_clk_ops; } - #if RT_NAME_MAX > 0 - rt_strncpy(clk_np->rt_parent.name, RT_CLK_NODE_OBJ_NAME, RT_NAME_MAX); - #else - clk_np->rt_parent.name = RT_CLK_NODE_OBJ_NAME; - #endif - rt_ref_init(&clk_np->ref); rt_list_init(&clk_np->list); rt_list_init(&clk_np->children_nodes); @@ -160,16 +159,7 @@ rt_err_t rt_clk_register(struct rt_clk_node *clk_np, struct rt_clk_node *parent_ if (parent_np) { - clk_np->clk = clk_alloc(clk_np, RT_NULL, RT_NULL, RT_NULL); - - if (clk_np->clk) - { - clk_set_parent(clk_np, parent_np); - } - else - { - err = -RT_ENOMEM; - } + clk_set_parent(clk_np, parent_np); } else { @@ -275,16 +265,11 @@ static rt_err_t clk_prepare(struct rt_clk *clk, struct rt_clk_node *clk_np) clk_prepare(clk_np->clk, clk_np->parent); } - if (clk->prepare_count == 0 && clk_np->ops->prepare) + if (clk_np->ops->prepare) { err = clk_np->ops->prepare(clk); } - if (!err) - { - ++clk->prepare_count; - } - return err; } @@ -302,6 +287,10 @@ rt_err_t rt_clk_prepare(struct rt_clk *clk) rt_hw_spin_unlock(&_clk_lock.lock); } + else + { + err = -RT_EINVAL; + } return err; } @@ -313,14 +302,10 @@ static void clk_unprepare(struct rt_clk *clk, struct rt_clk_node *clk_np) clk_unprepare(clk_np->clk, clk_np->parent); } - if (clk->prepare_count == 1 && clk_np->ops->unprepare) + if (clk_np->ops->unprepare) { clk_np->ops->unprepare(clk); } - if (clk->prepare_count) - { - --clk->prepare_count; - } } rt_err_t rt_clk_unprepare(struct rt_clk *clk) @@ -337,6 +322,10 @@ rt_err_t rt_clk_unprepare(struct rt_clk *clk) rt_hw_spin_unlock(&_clk_lock.lock); } + else + { + err = -RT_EINVAL; + } return err; } @@ -350,16 +339,11 @@ static rt_err_t clk_enable(struct rt_clk *clk, struct rt_clk_node *clk_np) clk_enable(clk_np->clk, clk_np->parent); } - if (clk->enable_count == 0 && clk_np->ops->enable) + if (clk_np->ops->enable) { err = clk_np->ops->enable(clk); } - if (!err) - { - ++clk->enable_count; - } - return err; } @@ -375,6 +359,10 @@ rt_err_t rt_clk_enable(struct rt_clk *clk) rt_hw_spin_unlock(&_clk_lock.lock); } + else + { + err = -RT_EINVAL; + } return err; } @@ -386,14 +374,10 @@ static void clk_disable(struct rt_clk *clk, struct rt_clk_node *clk_np) clk_disable(clk_np->clk, clk_np->parent); } - if (clk->enable_count == 1 && clk_np->ops->disable) + if (clk_np->ops->disable) { clk_np->ops->disable(clk); } - if (clk->enable_count) - { - --clk->enable_count; - } } void rt_clk_disable(struct rt_clk *clk) @@ -410,7 +394,7 @@ void rt_clk_disable(struct rt_clk *clk) rt_err_t rt_clk_prepare_enable(struct rt_clk *clk) { - rt_err_t err = RT_EOK; + rt_err_t err; RT_DEBUG_NOT_IN_INTERRUPT; @@ -428,6 +412,10 @@ rt_err_t rt_clk_prepare_enable(struct rt_clk *clk) } } } + else + { + err = -RT_EINVAL; + } return err; } @@ -465,6 +453,10 @@ rt_err_t rt_clk_array_prepare(struct rt_clk_array *clk_arr) } } } + else + { + err = -RT_EINVAL; + } return err; } @@ -486,6 +478,10 @@ rt_err_t rt_clk_array_unprepare(struct rt_clk_array *clk_arr) } } } + else + { + err = -RT_EINVAL; + } return err; } @@ -512,6 +508,10 @@ rt_err_t rt_clk_array_enable(struct rt_clk_array *clk_arr) } } } + else + { + err = -RT_EINVAL; + } return err; } @@ -529,16 +529,29 @@ void rt_clk_array_disable(struct rt_clk_array *clk_arr) rt_err_t rt_clk_array_prepare_enable(struct rt_clk_array *clk_arr) { - rt_err_t err; + rt_err_t err = RT_EOK; - if ((err = rt_clk_array_prepare(clk_arr))) + if (clk_arr) { - return err; + for (int i = 0; i < clk_arr->count; ++i) + { + if ((err = rt_clk_prepare_enable(clk_arr->clks[i]))) + { + LOG_E("CLK Array[%d] %s failed error = %s", i, + "prepare_enable", rt_strerror(err)); + + while (i --> 0) + { + rt_clk_disable_unprepare(clk_arr->clks[i]); + } + + break; + } + } } - - if ((err = rt_clk_array_enable(clk_arr))) + else { - rt_clk_array_unprepare(clk_arr); + err = -RT_EINVAL; } return err; @@ -546,8 +559,13 @@ rt_err_t rt_clk_array_prepare_enable(struct rt_clk_array *clk_arr) void rt_clk_array_disable_unprepare(struct rt_clk_array *clk_arr) { - rt_clk_array_disable(clk_arr); - rt_clk_array_unprepare(clk_arr); + if (clk_arr) + { + for (int i = 0; i < clk_arr->count; ++i) + { + rt_clk_disable_unprepare(clk_arr->clks[i]); + } + } } rt_err_t rt_clk_set_rate_range(struct rt_clk *clk, rt_ubase_t min, rt_ubase_t max) @@ -586,6 +604,10 @@ rt_err_t rt_clk_set_rate_range(struct rt_clk *clk, rt_ubase_t min, rt_ubase_t ma rt_hw_spin_unlock(&_clk_lock.lock); } + else + { + err = -RT_EINVAL; + } return err; } @@ -600,6 +622,10 @@ rt_err_t rt_clk_set_min_rate(struct rt_clk *clk, rt_ubase_t rate) err = rt_clk_set_rate_range(clk, rate, clk_np->max_rate); } + else + { + err = -RT_EINVAL; + } return err; } @@ -614,6 +640,10 @@ rt_err_t rt_clk_set_max_rate(struct rt_clk *clk, rt_ubase_t rate) err = rt_clk_set_rate_range(clk, clk_np->min_rate, rate); } + else + { + err = -RT_EINVAL; + } return err; } @@ -622,9 +652,7 @@ rt_err_t rt_clk_set_rate(struct rt_clk *clk, rt_ubase_t rate) { rt_err_t err = RT_EOK; - rate = rt_clk_round_rate(clk, rate); - - if (clk && clk->clk_np && rate > 0) + if (clk && clk->clk_np) { struct rt_clk_node *clk_np = clk->clk_np; @@ -662,13 +690,17 @@ rt_err_t rt_clk_set_rate(struct rt_clk *clk, rt_ubase_t rate) rt_hw_spin_unlock(&_clk_lock.lock); } + else + { + err = -RT_EINVAL; + } return err; } rt_ubase_t rt_clk_get_rate(struct rt_clk *clk) { - rt_ubase_t rate = 0; + rt_ubase_t rate = -1UL; if (clk) { @@ -697,6 +729,10 @@ rt_err_t rt_clk_set_phase(struct rt_clk *clk, int degrees) rt_hw_spin_unlock(&_clk_lock.lock); } + else + { + err = -RT_EINVAL; + } return err; } @@ -713,49 +749,38 @@ rt_base_t rt_clk_get_phase(struct rt_clk *clk) rt_hw_spin_unlock(&_clk_lock.lock); } + else + { + res = -RT_EINVAL; + } return res; } rt_base_t rt_clk_round_rate(struct rt_clk *clk, rt_ubase_t rate) { - rt_base_t res = -RT_EINVAL; + rt_base_t res = RT_EOK; - if (clk && clk->clk_np) + if (clk && clk->clk_np && clk->clk_np->ops->round_rate) { + rt_ubase_t best_parent_rate; struct rt_clk_node *clk_np = clk->clk_np; - if (clk_np->ops->round_rate) + rt_hw_spin_lock(&_clk_lock.lock); + + if (clk_np->min_rate && clk_np->max_rate) { - rt_ubase_t best_parent_rate; - - rt_hw_spin_lock(&_clk_lock.lock); - - if (clk_np->min_rate && clk_np->max_rate) - { - rate = rt_clamp(rate, clk_np->min_rate, clk_np->max_rate); - } - - res = clk_np->ops->round_rate(clk, rate, &best_parent_rate); - (void)best_parent_rate; - - rt_hw_spin_unlock(&_clk_lock.lock); - } - else - { - if (rate < clk_np->min_rate) - { - res = clk_np->min_rate; - } - else if (rate > clk_np->max_rate) - { - res = clk_np->max_rate; - } - else - { - res = rate; - } + rate = rt_clamp(rate, clk_np->min_rate, clk_np->max_rate); } + + res = clk->clk_np->ops->round_rate(clk, rate, &best_parent_rate); + (void)best_parent_rate; + + rt_hw_spin_unlock(&_clk_lock.lock); + } + else + { + res = -RT_EINVAL; } return res; @@ -773,6 +798,10 @@ rt_err_t rt_clk_set_parent(struct rt_clk *clk, struct rt_clk *clk_parent) rt_hw_spin_unlock(&_clk_lock.lock); } + else + { + err = -RT_EINVAL; + } return err; } @@ -858,7 +887,7 @@ void rt_clk_put(struct rt_clk *clk) } #ifdef RT_USING_OFW -static struct rt_clk *ofw_get_clk_no_lock(struct rt_ofw_node *np, int index, const char *name, rt_bool_t locked) +static struct rt_clk *ofw_get_clk_no_lock(struct rt_ofw_node *np, int index, const char *name) { struct rt_clk *clk = RT_NULL; struct rt_ofw_cell_args clk_args; @@ -866,32 +895,10 @@ static struct rt_clk *ofw_get_clk_no_lock(struct rt_ofw_node *np, int index, con if (!rt_ofw_parse_phandle_cells(np, "clocks", "#clock-cells", index, &clk_args)) { int count; - struct rt_object *obj; - struct rt_clk_node *clk_np = RT_NULL; struct rt_ofw_node *clk_ofw_np = clk_args.data; + struct rt_clk_node *clk_np = rt_ofw_data(clk_ofw_np); - if (!rt_ofw_data(clk_ofw_np)) - { - if (locked) - { - rt_hw_spin_unlock(&_clk_lock.lock); - } - - rt_platform_ofw_request(clk_ofw_np); - - if (locked) - { - rt_hw_spin_lock(&_clk_lock.lock); - } - } - - if (rt_ofw_data(clk_ofw_np) && (obj = rt_ofw_parse_object(clk_ofw_np, - RT_CLK_NODE_OBJ_NAME, "#clock-cells"))) - { - clk_np = rt_container_of(obj, struct rt_clk_node, rt_parent); - - count = rt_ofw_count_of_clk(clk_ofw_np); - } + count = rt_ofw_count_of_clk(clk_ofw_np); rt_ofw_node_put(clk_ofw_np); @@ -905,10 +912,6 @@ static struct rt_clk *ofw_get_clk_no_lock(struct rt_ofw_node *np, int index, con clk = clk_create(clk_np, np->full_name, name, &clk_args, np); } - else - { - clk = rt_err_ptr(-RT_ERROR); - } } return clk; @@ -920,7 +923,7 @@ static struct rt_clk *ofw_get_clk(struct rt_ofw_node *np, int index, const char rt_hw_spin_lock(&_clk_lock.lock); - clk = ofw_get_clk_no_lock(np, index, name, RT_TRUE); + clk = ofw_get_clk_no_lock(np, index, name); rt_hw_spin_unlock(&_clk_lock.lock); @@ -932,11 +935,6 @@ struct rt_clk_array *rt_ofw_get_clk_array(struct rt_ofw_node *np) int count; struct rt_clk_array *clk_arr = RT_NULL; - if (!np) - { - return rt_err_ptr(-RT_EINVAL); - } - if ((count = rt_ofw_count_phandle_cells(np, "clocks", "#clock-cells")) > 0) { clk_arr = rt_calloc(1, sizeof(*clk_arr) + sizeof(clk_arr->clks[0]) * count); @@ -944,7 +942,6 @@ struct rt_clk_array *rt_ofw_get_clk_array(struct rt_ofw_node *np) if (clk_arr) { int i; - rt_err_t err = RT_EOK; rt_bool_t has_name = rt_ofw_prop_read_bool(np, "clock-names"); clk_arr->count = count; @@ -960,12 +957,10 @@ struct rt_clk_array *rt_ofw_get_clk_array(struct rt_ofw_node *np) rt_ofw_prop_read_string_index(np, "clock-names", i, &name); } - clk_arr->clks[i] = ofw_get_clk_no_lock(np, i, name, RT_FALSE); + clk_arr->clks[i] = ofw_get_clk_no_lock(np, i, name); - if (rt_is_err(clk_arr->clks[i])) + if (!clk_arr->clks[i]) { - err = rt_ptr_err(clk_arr->clks[i]); - --i; break; } @@ -976,7 +971,7 @@ struct rt_clk_array *rt_ofw_get_clk_array(struct rt_ofw_node *np) if (i > 0 && i < count) { rt_clk_array_put(clk_arr); - clk_arr = rt_err_ptr(err); + clk_arr = RT_NULL; } } } diff --git a/rt-thread/components/drivers/core/bus.c b/rt-thread/components/drivers/core/bus.c index a1d6d7e..13e154f 100644 --- a/rt-thread/components/drivers/core/bus.c +++ b/rt-thread/components/drivers/core/bus.c @@ -360,9 +360,9 @@ rt_err_t rt_bus_remove_device(rt_device_t dev) } else if (drv) { - if (drv->remove) + if (drv->shutdown) { - err = drv->remove(dev); + err = drv->shutdown(dev); } /* device and driver are in the same bus */ diff --git a/rt-thread/components/drivers/core/device.c b/rt-thread/components/drivers/core/device.c index 751b662..c99cddf 100644 --- a/rt-thread/components/drivers/core/device.c +++ b/rt-thread/components/drivers/core/device.c @@ -13,8 +13,6 @@ * 2013-07-09 Grissiom add ref_count support * 2016-04-02 Bernard fix the open_flag initialization issue. * 2021-03-19 Meco Man remove rt_device_init_all() - * 2024-09-15 milo fix log format issue - * fix reopen with a different oflag issue */ #include @@ -31,9 +29,9 @@ #include /* for wqueue_init */ #endif /* RT_USING_POSIX_DEVIO */ -#if defined (RT_USING_DFS_V2) && defined (RT_USING_DFS_DEVFS) +#ifdef RT_USING_DFS_V2 #include -#endif /* RT_USING_DFS_V2 RT_USING_DFS_DEVFS */ +#endif /* RT_USING_DFS_V2 */ #ifdef RT_USING_DEVICE @@ -84,7 +82,7 @@ rt_err_t rt_device_register(rt_device_t dev, rt_wqueue_init(&(dev->wait_queue)); #endif /* RT_USING_POSIX_DEVIO */ -#if defined (RT_USING_DFS_V2) && defined (RT_USING_DFS_DEVFS) +#ifdef RT_USING_DFS_V2 dfs_devfs_device_add(dev); #endif /* RT_USING_DFS_V2 */ @@ -165,7 +163,7 @@ void rt_device_destroy(rt_device_t dev) { /* parameter check */ RT_ASSERT(dev != RT_NULL); - RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Null); + RT_ASSERT(rt_object_get_type(&dev->parent) == RT_Object_Class_Device); RT_ASSERT(rt_object_is_systemobject(&dev->parent) == RT_FALSE); rt_object_detach(&(dev->parent)); @@ -197,8 +195,8 @@ rt_err_t rt_device_init(rt_device_t dev) result = device_init(dev); if (result != RT_EOK) { - LOG_E("To initialize device:%.*s failed. The error code is %d", - RT_NAME_MAX, dev->parent.name, result); + LOG_E("To initialize device:%s failed. The error code is %d", + dev->parent.name, result); } else { @@ -235,8 +233,8 @@ rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflag) result = device_init(dev); if (result != RT_EOK) { - LOG_E("To initialize device:%.*s failed. The error code is %d", - RT_NAME_MAX, dev->parent.name, result); + LOG_E("To initialize device:%s failed. The error code is %d", + dev->parent.name, result); return result; } @@ -254,7 +252,7 @@ rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflag) /* device is not opened or opened by other oflag, call device_open interface */ if (!(dev->open_flag & RT_DEVICE_OFLAG_OPEN) || - ((dev->open_flag & RT_DEVICE_OFLAG_MASK) != ((oflag & RT_DEVICE_OFLAG_MASK) | RT_DEVICE_OFLAG_OPEN))) + ((dev->open_flag & RT_DEVICE_OFLAG_MASK) != (oflag & RT_DEVICE_OFLAG_MASK))) { if (device_open != RT_NULL) { diff --git a/rt-thread/components/drivers/core/dm.c b/rt-thread/components/drivers/core/dm.c index 9d9f93f..8c87cae 100644 --- a/rt-thread/components/drivers/core/dm.c +++ b/rt-thread/components/drivers/core/dm.c @@ -53,137 +53,6 @@ void rt_dm_secondary_cpu_init(void) } #endif /* RT_USING_SMP */ -/** - * @brief This function will alloc an id in an IDA object - * - * @param ida is the IDA object - * - * @return the id or -RT_EEMPTY - */ -int rt_dm_ida_alloc(struct rt_dm_ida *ida) -{ - int id; - RT_ASSERT(ida != RT_NULL); - - rt_spin_lock(&ida->lock); - - id = rt_bitmap_next_clear_bit(ida->map, 0, RT_DM_IDA_NUM); - - if (id != RT_DM_IDA_NUM) - { - rt_bitmap_set_bit(ida->map, id); - } - - rt_spin_unlock(&ida->lock); - - if (id != RT_DM_IDA_NUM) - { - return id; - } - - return -RT_EEMPTY; -} - -/** - * @brief This function will take (force) an id in an IDA object - * - * @param ida is the IDA object - * - * @param id is the id that want to take - * - * @return the result of taking - */ -rt_bool_t rt_dm_ida_take(struct rt_dm_ida *ida, int id) -{ - RT_ASSERT(ida != RT_NULL); - RT_ASSERT(id >= 0); - - rt_spin_lock(&ida->lock); - - if (!rt_bitmap_test_bit(ida->map, id)) - { - rt_bitmap_set_bit(ida->map, id); - } - else - { - id = RT_DM_IDA_NUM; - } - - rt_spin_unlock(&ida->lock); - - return id != RT_DM_IDA_NUM; -} - -/** - * @brief This function will release an id in an IDA object - * - * @param ida is the IDA object - * - * @param id is the id of IDA object - */ -void rt_dm_ida_free(struct rt_dm_ida *ida, int id) -{ - RT_ASSERT(ida != RT_NULL); - RT_ASSERT(id >= 0); - - rt_spin_lock(&ida->lock); - - rt_bitmap_clear_bit(ida->map, id); - - rt_spin_unlock(&ida->lock); -} - -/** - * @brief This function will return the specified master id and device id of device. - * - * @param master_id is the master id (0, 255] of device - * - * @param device_id is the device id [-1, 255] of device, when device_id is -1, - * the function will end when find the first device. - * - * @return the device object or RT_NULL - */ -rt_device_t rt_dm_device_find(int master_id, int device_id) -{ - struct rt_device *dev, *ret_dev = RT_NULL; - struct rt_object_information *information = RT_NULL; - - if (master_id <= 0 || device_id > 255) - { - return RT_NULL; - } - - information = rt_object_get_information(RT_Object_Class_Device); - - /* parameter check */ - if (!information) - { - return RT_NULL; - } - - /* which is invoke in interrupt status */ - RT_DEBUG_NOT_IN_INTERRUPT; - - /* enter critical */ - rt_enter_critical(); - - /* try to find object */ - rt_list_for_each_entry(dev, &information->object_list, parent.list) - { - if (master_id == dev->master_id && - (device_id == -1 || device_id == dev->device_id)) - { - ret_dev = dev; - break; - } - } - - /* leave critical */ - rt_exit_critical(); - - return ret_dev; -} - struct prefix_track { rt_list_t list; diff --git a/rt-thread/components/drivers/core/platform.c b/rt-thread/components/drivers/core/platform.c index c3a1416..d8c6679 100644 --- a/rt-thread/components/drivers/core/platform.c +++ b/rt-thread/components/drivers/core/platform.c @@ -78,21 +78,21 @@ static rt_bool_t platform_match(rt_driver_t drv, rt_device_t dev) { struct rt_platform_driver *pdrv = rt_container_of(drv, struct rt_platform_driver, parent); struct rt_platform_device *pdev = rt_container_of(dev, struct rt_platform_device, parent); + +#ifdef RT_USING_OFW struct rt_ofw_node *np = dev->ofw_node; /* 1、match with ofw node */ if (np) { - #ifdef RT_USING_OFW pdev->id = rt_ofw_node_match(np, pdrv->ids); - #else - pdev->id = RT_NULL; - #endif + if (pdev->id) { return RT_TRUE; } } +#endif /* 2、match with name */ if (pdev->name && pdrv->name) @@ -123,13 +123,7 @@ static rt_err_t platform_probe(rt_device_t dev) if (err && err != -RT_EEMPTY) { - LOG_E("Attach power domain error = %s in device %s", rt_strerror(err), - #ifdef RT_USING_OFW - (pdev->name && pdev->name[0]) ? pdev->name : rt_ofw_node_full_name(np) - #else - pdev->name - #endif - ); + LOG_E("Attach power domain error = %s in device %s", pdev->name, rt_strerror(err)); return err; } diff --git a/rt-thread/components/drivers/core/platform_ofw.c b/rt-thread/components/drivers/core/platform_ofw.c index 1b1aa27..f305fde 100644 --- a/rt-thread/components/drivers/core/platform_ofw.c +++ b/rt-thread/components/drivers/core/platform_ofw.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include "../ofw/ofw_internal.h" @@ -162,7 +161,6 @@ static rt_err_t platform_ofw_device_probe_once(struct rt_ofw_node *parent_np) } pdev->dev_id = ofw_alias_node_id(np); - np->dev = &pdev->parent; LOG_D("%s register to bus", np->full_name); rt_platform_device_register(pdev); @@ -201,53 +199,6 @@ rt_err_t rt_platform_ofw_device_probe_child(struct rt_ofw_node *np) return err; } -rt_err_t rt_platform_ofw_request(struct rt_ofw_node *np) -{ - rt_err_t err; - - if (np) - { - struct rt_device *dev = np->dev; - - if (dev) - { - /* Was create */ - if (dev->drv) - { - /* Was probe OK */ - err = RT_EOK; - } - else - { - err = rt_bus_reload_driver_device(dev->bus, dev); - } - } - else - { - struct rt_platform_device *pdev = alloc_ofw_platform_device(np); - - if (pdev) - { - pdev->dev_id = ofw_alias_node_id(np); - np->dev = &pdev->parent; - LOG_D("%s register to bus", np->full_name); - - err = rt_platform_device_register(pdev); - } - else - { - err = -RT_ENOMEM; - } - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - static int platform_ofw_device_probe(void) { rt_err_t err = RT_EOK; @@ -255,8 +206,6 @@ static int platform_ofw_device_probe(void) if (ofw_node_root) { - rt_ofw_node_get(ofw_node_root); - err = platform_ofw_device_probe_once(ofw_node_root); rt_ofw_node_put(ofw_node_root); @@ -267,19 +216,11 @@ static int platform_ofw_device_probe(void) rt_ofw_node_put(node); } - if ((node = rt_ofw_find_node_by_path("/clocks"))) - { - platform_ofw_device_probe_once(node); - rt_ofw_node_put(node); - } - - rt_ofw_node_get(ofw_node_chosen); if ((node = rt_ofw_get_child_by_compatible(ofw_node_chosen, "simple-framebuffer"))) { platform_ofw_device_probe_once(node); rt_ofw_node_put(node); } - rt_ofw_node_get(ofw_node_chosen); } else { @@ -303,7 +244,7 @@ rt_err_t rt_platform_ofw_free(struct rt_platform_device *pdev) rt_ofw_node_clear_flag(np, RT_OFW_F_PLATFORM); rt_ofw_node_put(np); - rt_free(pdev); + pdev->parent.ofw_node = RT_NULL; } } else diff --git a/rt-thread/components/drivers/dma/Kconfig b/rt-thread/components/drivers/dma/Kconfig deleted file mode 100644 index 7bf9d59..0000000 --- a/rt-thread/components/drivers/dma/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -menuconfig RT_USING_DMA - bool "Using Direct Memory Access (DMA)" - depends on RT_USING_DM - select RT_USING_ADT - select RT_USING_ADT_BITMAP - default n - -if RT_USING_DMA - osource "$(SOC_DM_DMA_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/dma/SConscript b/rt-thread/components/drivers/dma/SConscript deleted file mode 100644 index ea3500c..0000000 --- a/rt-thread/components/drivers/dma/SConscript +++ /dev/null @@ -1,15 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_USING_DMA']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../include'] - -src = ['dma.c', 'dma_pool.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/dma/dma.c b/rt-thread/components/drivers/dma/dma.c deleted file mode 100644 index da2d80a..0000000 --- a/rt-thread/components/drivers/dma/dma.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#include -#include -#include - -#define DBG_TAG "rtdm.dma" -#define DBG_LVL DBG_INFO -#include - -static rt_list_t dmac_nodes = RT_LIST_OBJECT_INIT(dmac_nodes); -static struct rt_spinlock dmac_nodes_lock = {}; - -rt_err_t rt_dma_controller_register(struct rt_dma_controller *ctrl) -{ - const char *dev_name; - char dma_name[RT_NAME_MAX]; - - if (!ctrl || !ctrl->dev || !ctrl->ops) - { - return -RT_EINVAL; - } - - dev_name = rt_dm_dev_get_name(ctrl->dev); - - if (rt_bitmap_next_set_bit(ctrl->dir_cap, 0, RT_DMA_DIR_MAX) == RT_DMA_DIR_MAX) - { - LOG_E("%s: Not direction capability", dev_name); - - return -RT_EINVAL; - } - - rt_snprintf(dma_name, sizeof(dma_name), "%s-dmac", dev_name); - - rt_list_init(&ctrl->list); - - rt_spin_lock(&dmac_nodes_lock); - rt_list_insert_before(&dmac_nodes, &ctrl->list); - rt_spin_unlock(&dmac_nodes_lock); - - rt_list_init(&ctrl->channels_nodes); - rt_mutex_init(&ctrl->mutex, dma_name, RT_IPC_FLAG_PRIO); - - if (ctrl->dev->ofw_node) - { - rt_dm_dev_bind_fwdata(ctrl->dev, RT_NULL, ctrl); - } - - return RT_EOK; -} - -rt_err_t rt_dma_controller_unregister(struct rt_dma_controller *ctrl) -{ - if (!ctrl) - { - return -RT_EINVAL; - } - - rt_mutex_take(&ctrl->mutex, RT_WAITING_FOREVER); - - if (!rt_list_isempty(&ctrl->channels_nodes)) - { - rt_mutex_release(&ctrl->mutex); - return -RT_EBUSY; - } - - if (ctrl->dev->ofw_node) - { - rt_dm_dev_unbind_fwdata(ctrl->dev, RT_NULL); - } - - rt_mutex_release(&ctrl->mutex); - rt_mutex_detach(&ctrl->mutex); - - rt_spin_lock(&dmac_nodes_lock); - rt_list_remove(&ctrl->list); - rt_spin_unlock(&dmac_nodes_lock); - - return RT_EOK; -} - -rt_err_t rt_dma_chan_start(struct rt_dma_chan *chan) -{ - rt_err_t err; - struct rt_dma_controller *ctrl; - - if (!chan) - { - return -RT_EINVAL; - } - - if (chan->prep_err) - { - LOG_D("%s: Not config done", rt_dm_dev_get_name(chan->slave)); - - return chan->prep_err; - } - - ctrl = chan->ctrl; - - rt_mutex_take(&ctrl->mutex, RT_WAITING_FOREVER); - - err = ctrl->ops->start(chan); - - rt_mutex_release(&ctrl->mutex); - - return err; -} - -rt_err_t rt_dma_chan_stop(struct rt_dma_chan *chan) -{ - rt_err_t err; - struct rt_dma_controller *ctrl; - - if (!chan) - { - return -RT_EINVAL; - } - - if (chan->prep_err) - { - LOG_D("%s: Not prepare done", rt_dm_dev_get_name(chan->slave)); - - return chan->prep_err; - } - - ctrl = chan->ctrl; - - rt_mutex_take(&ctrl->mutex, RT_WAITING_FOREVER); - - err = ctrl->ops->stop(chan); - - rt_mutex_release(&ctrl->mutex); - - return err; -} - -rt_err_t rt_dma_chan_config(struct rt_dma_chan *chan, - struct rt_dma_slave_config *conf) -{ - rt_err_t err; - struct rt_dma_controller *ctrl; - enum rt_dma_transfer_direction dir; - - if (!chan || !conf) - { - err = -RT_EINVAL; - goto _end; - } - - dir = conf->direction; - - if (dir >= RT_DMA_DIR_MAX) - { - err = -RT_EINVAL; - goto _end; - } - - if (conf->src_addr_width >= RT_DMA_SLAVE_BUSWIDTH_BYTES_MAX || - conf->dst_addr_width >= RT_DMA_SLAVE_BUSWIDTH_BYTES_MAX) - { - err = -RT_EINVAL; - goto _end; - } - - ctrl = chan->ctrl; - - if (!rt_bitmap_test_bit(ctrl->dir_cap, dir)) - { - err = -RT_ENOSYS; - goto _end; - } - - if (!chan->name && dir != RT_DMA_MEM_TO_MEM) - { - LOG_E("%s: illegal config for uname channels", - rt_dm_dev_get_name(ctrl->dev)); - - err = -RT_EINVAL; - goto _end; - } - - rt_mutex_take(&ctrl->mutex, RT_WAITING_FOREVER); - - err = ctrl->ops->config(chan, conf); - - rt_mutex_release(&ctrl->mutex); - - if (!err) - { - rt_memcpy(&chan->conf, conf, sizeof(*conf)); - } - -_end: - chan->conf_err = err; - - return err; -} - -rt_err_t rt_dma_chan_done(struct rt_dma_chan *chan, rt_size_t size) -{ - if (!chan) - { - return -RT_EINVAL; - } - - if (chan->callback) - { - chan->callback(chan, size); - } - - return RT_EOK; -} - -static rt_bool_t range_is_illegal(const char *name, const char *desc, - rt_ubase_t addr0, rt_ubase_t addr1) -{ - rt_bool_t illegal = addr0 < addr1; - - if (illegal) - { - LOG_E("%s: %s %p is out of config %p", name, desc, addr0, addr1); - } - - return illegal; -} - -rt_err_t rt_dma_prep_memcpy(struct rt_dma_chan *chan, - struct rt_dma_slave_transfer *transfer) -{ - rt_err_t err; - rt_size_t len; - rt_ubase_t dma_addr_src, dma_addr_dst; - struct rt_dma_controller *ctrl; - struct rt_dma_slave_config *conf; - - if (!chan || !transfer) - { - return -RT_EINVAL; - } - - ctrl = chan->ctrl; - conf = &chan->conf; - - if (chan->conf_err) - { - LOG_D("%s: Not config done", rt_dm_dev_get_name(chan->slave)); - - return chan->conf_err; - } - - RT_ASSERT(chan->conf.direction == RT_DMA_MEM_TO_MEM); - dma_addr_src = transfer->src_addr; - dma_addr_dst = transfer->dst_addr; - len = transfer->buffer_len; - - if (range_is_illegal(rt_dm_dev_get_name(ctrl->dev), "source", - dma_addr_src, conf->src_addr)) - { - return -RT_EINVAL; - } - - if (range_is_illegal(rt_dm_dev_get_name(ctrl->dev), "dest", - dma_addr_dst, conf->dst_addr)) - { - return -RT_EINVAL; - } - - if (ctrl->ops->prep_memcpy) - { - rt_mutex_take(&ctrl->mutex, RT_WAITING_FOREVER); - - err = ctrl->ops->prep_memcpy(chan, dma_addr_dst, dma_addr_src, len); - - rt_mutex_release(&ctrl->mutex); - } - else - { - err = -RT_ENOSYS; - } - - if (!err) - { - rt_memcpy(&chan->transfer, transfer, sizeof(*transfer)); - } - - chan->prep_err = err; - - return err; -} - -rt_err_t rt_dma_prep_cyclic(struct rt_dma_chan *chan, - struct rt_dma_slave_transfer *transfer) -{ - rt_err_t err; - rt_ubase_t dma_buf_addr; - struct rt_dma_controller *ctrl; - struct rt_dma_slave_config *conf; - enum rt_dma_transfer_direction dir; - - if (!chan || !transfer) - { - return -RT_EINVAL; - } - - ctrl = chan->ctrl; - conf = &chan->conf; - - if (chan->conf_err) - { - LOG_D("%s: Not config done", rt_dm_dev_get_name(chan->slave)); - - return chan->conf_err; - } - - dir = chan->conf.direction; - - if (dir == RT_DMA_MEM_TO_DEV || dir == RT_DMA_MEM_TO_MEM) - { - dma_buf_addr = transfer->src_addr; - - if (range_is_illegal(rt_dm_dev_get_name(ctrl->dev), "source", - dma_buf_addr, conf->src_addr)) - { - return -RT_EINVAL; - } - } - else if (dir == RT_DMA_DEV_TO_MEM) - { - dma_buf_addr = transfer->dst_addr; - - if (range_is_illegal(rt_dm_dev_get_name(ctrl->dev), "dest", - dma_buf_addr, conf->dst_addr)) - { - return -RT_EINVAL; - } - } - else - { - dma_buf_addr = ~0UL; - } - - if (ctrl->ops->prep_cyclic) - { - rt_mutex_take(&ctrl->mutex, RT_WAITING_FOREVER); - - err = ctrl->ops->prep_cyclic(chan, dma_buf_addr, - transfer->buffer_len, transfer->period_len, dir); - - rt_mutex_release(&ctrl->mutex); - } - else - { - err = -RT_ENOSYS; - } - - if (!err) - { - rt_memcpy(&chan->transfer, transfer, sizeof(*transfer)); - } - - chan->prep_err = err; - - return err; -} - -rt_err_t rt_dma_prep_single(struct rt_dma_chan *chan, - struct rt_dma_slave_transfer *transfer) -{ - rt_err_t err; - rt_ubase_t dma_buf_addr; - struct rt_dma_controller *ctrl; - struct rt_dma_slave_config *conf; - enum rt_dma_transfer_direction dir; - - if (!chan || !transfer) - { - return -RT_EINVAL; - } - - ctrl = chan->ctrl; - conf = &chan->conf; - - if (chan->conf_err) - { - LOG_D("%s: Not config done", rt_dm_dev_get_name(chan->slave)); - - return chan->conf_err; - } - - dir = chan->conf.direction; - - if (dir == RT_DMA_MEM_TO_DEV || dir == RT_DMA_MEM_TO_MEM) - { - dma_buf_addr = transfer->src_addr; - - if (range_is_illegal(rt_dm_dev_get_name(ctrl->dev), "source", - dma_buf_addr, conf->src_addr)) - { - return -RT_EINVAL; - } - } - else if (dir == RT_DMA_DEV_TO_MEM) - { - dma_buf_addr = transfer->dst_addr; - - if (range_is_illegal(rt_dm_dev_get_name(ctrl->dev), "dest", - dma_buf_addr, conf->dst_addr)) - { - return -RT_EINVAL; - } - } - else - { - dma_buf_addr = ~0UL; - } - - if (ctrl->ops->prep_single) - { - rt_mutex_take(&ctrl->mutex, RT_WAITING_FOREVER); - - err = ctrl->ops->prep_single(chan, dma_buf_addr, - transfer->buffer_len, dir); - - rt_mutex_release(&ctrl->mutex); - } - else - { - err = -RT_ENOSYS; - } - - if (!err) - { - rt_memcpy(&chan->transfer, transfer, sizeof(*transfer)); - } - - chan->prep_err = err; - - return err; -} - -static struct rt_dma_controller *ofw_find_dma_controller(struct rt_device *dev, - const char *name, struct rt_ofw_cell_args *args) -{ - struct rt_dma_controller *ctrl = RT_NULL; -#ifdef RT_USING_OFW - int index; - struct rt_ofw_node *np = dev->ofw_node, *ctrl_np; - - if (!np) - { - return RT_NULL; - } - - index = rt_ofw_prop_index_of_string(np, "dma-names", name); - - if (index < 0) - { - return RT_NULL; - } - - if (!rt_ofw_parse_phandle_cells(np, "dmas", "#dma-cells", index, args)) - { - ctrl_np = args->data; - - if (!rt_ofw_data(ctrl_np)) - { - rt_platform_ofw_request(ctrl_np); - } - - ctrl = rt_ofw_data(ctrl_np); - rt_ofw_node_put(ctrl_np); - } -#endif /* RT_USING_OFW */ - return ctrl; -} - -struct rt_dma_chan *rt_dma_chan_request(struct rt_device *dev, const char *name) -{ - void *fw_data = RT_NULL; - struct rt_dma_chan *chan; - struct rt_ofw_cell_args dma_args; - struct rt_dma_controller *ctrl = RT_NULL; - - if (!dev) - { - return rt_err_ptr(-RT_EINVAL); - } - - if (name) - { - fw_data = &dma_args; - ctrl = ofw_find_dma_controller(dev, name, &dma_args); - } - else - { - struct rt_dma_controller *ctrl_tmp; - - rt_spin_lock(&dmac_nodes_lock); - rt_list_for_each_entry(ctrl_tmp, &dmac_nodes, list) - { - /* Only memory to memory for uname request */ - if (rt_bitmap_test_bit(ctrl_tmp->dir_cap, RT_DMA_MEM_TO_MEM)) - { - ctrl = ctrl_tmp; - break; - } - } - rt_spin_unlock(&dmac_nodes_lock); - } - - if (rt_is_err_or_null(ctrl)) - { - return ctrl ? ctrl : rt_err_ptr(-RT_ENOSYS); - } - - if (ctrl->ops->request_chan) - { - chan = ctrl->ops->request_chan(ctrl, dev, fw_data); - } - else - { - chan = rt_calloc(1, sizeof(*chan)); - - if (!chan) - { - chan = rt_err_ptr(-RT_ENOMEM); - } - } - - if (rt_is_err(chan)) - { - return chan; - } - - if (!chan) - { - LOG_E("%s: unset request channels error", rt_dm_dev_get_name(ctrl->dev)); - - return rt_err_ptr(-RT_ERROR); - } - - chan->name = name; - chan->ctrl = ctrl; - chan->slave = dev; - - rt_list_init(&chan->list); - chan->conf_err = -RT_ERROR; - chan->prep_err = -RT_ERROR; - - rt_mutex_take(&ctrl->mutex, RT_WAITING_FOREVER); - rt_list_insert_before(&ctrl->channels_nodes, &chan->list); - rt_mutex_release(&ctrl->mutex); - - return chan; -} - -rt_err_t rt_dma_chan_release(struct rt_dma_chan *chan) -{ - rt_err_t err = RT_EOK; - - if (!chan) - { - return -RT_EINVAL; - } - - rt_mutex_take(&chan->ctrl->mutex, RT_WAITING_FOREVER); - rt_list_remove(&chan->list); - rt_mutex_release(&chan->ctrl->mutex); - - if (chan->ctrl->ops->release_chan) - { - err = chan->ctrl->ops->release_chan(chan); - } - else - { - rt_free(chan); - } - - return err; -} diff --git a/rt-thread/components/drivers/dma/dma_pool.c b/rt-thread/components/drivers/dma/dma_pool.c deleted file mode 100644 index 8bd5291..0000000 --- a/rt-thread/components/drivers/dma/dma_pool.c +++ /dev/null @@ -1,691 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#include -#include -#include - -#define DBG_TAG "dma.pool" -#define DBG_LVL DBG_INFO -#include - -#include -#include - -static struct rt_spinlock dma_pools_lock = {}; -static rt_list_t dma_pool_nodes = RT_LIST_OBJECT_INIT(dma_pool_nodes); - -static struct rt_dma_pool *dma_pool_install(rt_region_t *region); - -static void *dma_alloc(struct rt_device *dev, rt_size_t size, - rt_ubase_t *dma_handle, rt_ubase_t flags); -static void dma_free(struct rt_device *dev, rt_size_t size, - void *cpu_addr, rt_ubase_t dma_handle, rt_ubase_t flags); - -rt_inline void region_pool_lock(void) -{ - rt_hw_spin_lock(&dma_pools_lock.lock); -} - -rt_inline void region_pool_unlock(void) -{ - rt_hw_spin_unlock(&dma_pools_lock.lock); -} - -static rt_err_t dma_map_coherent_sync_out_data(struct rt_device *dev, - void *data, rt_size_t size, rt_ubase_t *dma_handle, rt_ubase_t flags) -{ - if (dma_handle) - { - *dma_handle = (rt_ubase_t)rt_kmem_v2p(data); - } - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, data, size); - - return RT_EOK; -} - -static rt_err_t dma_map_coherent_sync_in_data(struct rt_device *dev, - void *out_data, rt_size_t size, rt_ubase_t dma_handle, rt_ubase_t flags) -{ - rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, out_data, size); - - return RT_EOK; -} - -static const struct rt_dma_map_ops dma_map_coherent_ops = -{ - .sync_out_data = dma_map_coherent_sync_out_data, - .sync_in_data = dma_map_coherent_sync_in_data, -}; - -static rt_err_t dma_map_nocoherent_sync_out_data(struct rt_device *dev, - void *data, rt_size_t size, rt_ubase_t *dma_handle, rt_ubase_t flags) -{ - if (dma_handle) - { - *dma_handle = (rt_ubase_t)rt_kmem_v2p(data); - } - - return RT_EOK; -} - -static rt_err_t dma_map_nocoherent_sync_in_data(struct rt_device *dev, - void *out_data, rt_size_t size, rt_ubase_t dma_handle, rt_ubase_t flags) -{ - return RT_EOK; -} - -static const struct rt_dma_map_ops dma_map_nocoherent_ops = -{ - .sync_out_data = dma_map_nocoherent_sync_out_data, - .sync_in_data = dma_map_nocoherent_sync_in_data, -}; - -#ifdef RT_USING_OFW -rt_inline rt_ubase_t ofw_addr_cpu2dma(struct rt_device *dev, rt_ubase_t addr) -{ - return (rt_ubase_t)rt_ofw_translate_cpu2dma(dev->ofw_node, addr); -} - -rt_inline rt_ubase_t ofw_addr_dma2cpu(struct rt_device *dev, rt_ubase_t addr) -{ - return (rt_ubase_t)rt_ofw_translate_dma2cpu(dev->ofw_node, addr); -} - -static void *ofw_dma_map_alloc(struct rt_device *dev, rt_size_t size, - rt_ubase_t *dma_handle, rt_ubase_t flags) -{ - void *cpu_addr = dma_alloc(dev, size, dma_handle, flags); - - if (cpu_addr && dma_handle) - { - *dma_handle = ofw_addr_cpu2dma(dev, *dma_handle); - } - - return cpu_addr; -} - -static void ofw_dma_map_free(struct rt_device *dev, rt_size_t size, - void *cpu_addr, rt_ubase_t dma_handle, rt_ubase_t flags) -{ - dma_handle = ofw_addr_dma2cpu(dev, dma_handle); - - dma_free(dev, size, cpu_addr, dma_handle, flags); -} - -static rt_err_t ofw_dma_map_sync_out_data(struct rt_device *dev, - void *data, rt_size_t size, - rt_ubase_t *dma_handle, rt_ubase_t flags) -{ - rt_err_t err; - - if (flags & RT_DMA_F_NOCACHE) - { - err = dma_map_nocoherent_sync_out_data(dev, data, size, dma_handle, flags); - } - else - { - err = dma_map_coherent_sync_out_data(dev, data, size, dma_handle, flags); - } - - if (!err && dma_handle) - { - *dma_handle = ofw_addr_cpu2dma(dev, *dma_handle); - } - - return err; -} - -static rt_err_t ofw_dma_map_sync_in_data(struct rt_device *dev, - void *out_data, rt_size_t size, - rt_ubase_t dma_handle, rt_ubase_t flags) -{ - dma_handle = ofw_addr_dma2cpu(dev, dma_handle); - - if (flags & RT_DMA_F_NOCACHE) - { - return dma_map_nocoherent_sync_in_data(dev, out_data, size, dma_handle, flags); - } - - return dma_map_coherent_sync_in_data(dev, out_data, size, dma_handle, flags); -} - -static const struct rt_dma_map_ops ofw_dma_map_ops = -{ - .alloc = ofw_dma_map_alloc, - .free = ofw_dma_map_free, - .sync_out_data = ofw_dma_map_sync_out_data, - .sync_in_data = ofw_dma_map_sync_in_data, -}; - -static const struct rt_dma_map_ops *ofw_device_dma_ops(struct rt_device *dev) -{ - rt_err_t err; - int region_nr = 0; - const fdt32_t *cell; - rt_phandle phandle; - rt_region_t region; - struct rt_ofw_prop *prop; - struct rt_dma_pool *dma_pool; - const struct rt_dma_map_ops *ops = RT_NULL; - struct rt_ofw_node *mem_np, *np = dev->ofw_node; - - rt_ofw_foreach_prop_u32(np, "memory-region", prop, cell, phandle) - { - rt_uint64_t addr, size; - - if (!(mem_np = rt_ofw_find_node_by_phandle(phandle))) - { - if (region_nr == 0) - { - return RT_NULL; - } - - break; - } - - if ((err = rt_ofw_get_address(mem_np, 0, &addr, &size))) - { - LOG_E("%s: Read '%s' error = %s", rt_ofw_node_full_name(mem_np), - "memory-region", rt_strerror(err)); - - rt_ofw_node_put(mem_np); - continue; - } - - region.start = addr; - region.end = addr + size; - region.name = rt_dm_dev_get_name(dev); - - rt_ofw_node_put(mem_np); - - if (!(dma_pool = dma_pool_install(®ion))) - { - return RT_NULL; - } - - if (rt_ofw_prop_read_bool(mem_np, "no-map")) - { - dma_pool->flags |= RT_DMA_F_NOMAP; - } - - if (!rt_dma_device_is_coherent(dev)) - { - dma_pool->flags |= RT_DMA_F_NOCACHE; - } - - dma_pool->dev = dev; - ++region_nr; - } - - if (region_nr) - { - ops = &ofw_dma_map_ops; - } - - return ops; -} -#endif /* RT_USING_OFW */ - -static const struct rt_dma_map_ops *device_dma_ops(struct rt_device *dev) -{ - const struct rt_dma_map_ops *ops = dev->dma_ops; - - if (ops) - { - return ops; - } - -#ifdef RT_USING_OFW - if (dev->ofw_node && (ops = ofw_device_dma_ops(dev))) - { - return ops; - } -#endif - - if (rt_dma_device_is_coherent(dev)) - { - ops = &dma_map_coherent_ops; - } - else - { - ops = &dma_map_nocoherent_ops; - } - - dev->dma_ops = ops; - - return ops; -} - -static rt_ubase_t dma_pool_alloc(struct rt_dma_pool *pool, rt_size_t size) -{ - rt_size_t bit, next_bit, end_bit, max_bits; - - size = RT_DIV_ROUND_UP(size, ARCH_PAGE_SIZE); - max_bits = pool->bits - size; - - rt_bitmap_for_each_clear_bit(pool->map, bit, max_bits) - { - end_bit = bit + size; - - for (next_bit = bit + 1; next_bit < end_bit; ++next_bit) - { - if (rt_bitmap_test_bit(pool->map, next_bit)) - { - bit = next_bit; - goto _next; - } - } - - if (next_bit == end_bit) - { - while (next_bit --> bit) - { - rt_bitmap_set_bit(pool->map, next_bit); - } - - return pool->start + bit * ARCH_PAGE_SIZE; - } - _next: - } - - return RT_NULL; -} - -static void dma_pool_free(struct rt_dma_pool *pool, rt_ubase_t offset, rt_size_t size) -{ - rt_size_t bit = (offset - pool->start) / ARCH_PAGE_SIZE, end_bit; - - size = RT_DIV_ROUND_UP(size, ARCH_PAGE_SIZE); - end_bit = bit + size; - - for (; bit < end_bit; ++bit) - { - rt_bitmap_clear_bit(pool->map, bit); - } -} - -static void *dma_alloc(struct rt_device *dev, rt_size_t size, - rt_ubase_t *dma_handle, rt_ubase_t flags) -{ - void *dma_buffer = RT_NULL; - struct rt_dma_pool *pool; - - region_pool_lock(); - - rt_list_for_each_entry(pool, &dma_pool_nodes, list) - { - if (pool->flags & RT_DMA_F_DEVICE) - { - if (!(flags & RT_DMA_F_DEVICE) || pool->dev != dev) - { - continue; - } - } - else if ((flags & RT_DMA_F_DEVICE)) - { - continue; - } - - if ((flags & RT_DMA_F_NOMAP) && !((pool->flags & RT_DMA_F_NOMAP))) - { - continue; - } - - if ((flags & RT_DMA_F_32BITS) && !((pool->flags & RT_DMA_F_32BITS))) - { - continue; - } - - if ((flags & RT_DMA_F_LINEAR) && !((pool->flags & RT_DMA_F_LINEAR))) - { - continue; - } - - *dma_handle = dma_pool_alloc(pool, size); - - if (*dma_handle && !(flags & RT_DMA_F_NOMAP)) - { - if (flags & RT_DMA_F_NOCACHE) - { - dma_buffer = rt_ioremap_nocache((void *)*dma_handle, size); - } - else - { - dma_buffer = rt_ioremap_cached((void *)*dma_handle, size); - } - - if (!dma_buffer) - { - dma_pool_free(pool, *dma_handle, size); - - continue; - } - - break; - } - else if (*dma_handle) - { - dma_buffer = (void *)*dma_handle; - - break; - } - } - - region_pool_unlock(); - - return dma_buffer; -} - -static void dma_free(struct rt_device *dev, rt_size_t size, - void *cpu_addr, rt_ubase_t dma_handle, rt_ubase_t flags) -{ - struct rt_dma_pool *pool; - - region_pool_lock(); - - rt_list_for_each_entry(pool, &dma_pool_nodes, list) - { - if (dma_handle >= pool->region.start && - dma_handle <= pool->region.end) - { - rt_iounmap(cpu_addr); - - dma_pool_free(pool, dma_handle, size); - - break; - } - } - - region_pool_unlock(); -} - -void *rt_dma_alloc(struct rt_device *dev, rt_size_t size, - rt_ubase_t *dma_handle, rt_ubase_t flags) -{ - void *dma_buffer = RT_NULL; - rt_ubase_t dma_handle_s = 0; - const struct rt_dma_map_ops *ops; - - if (!dev || !size) - { - return RT_NULL; - } - - ops = device_dma_ops(dev); - - if (ops->alloc) - { - dma_buffer = ops->alloc(dev, size, &dma_handle_s, flags); - } - else - { - dma_buffer = dma_alloc(dev, size, &dma_handle_s, flags); - } - - if (!dma_buffer) - { - return dma_buffer; - } - - if (dma_handle) - { - *dma_handle = dma_handle_s; - } - - return dma_buffer; -} - -void rt_dma_free(struct rt_device *dev, rt_size_t size, - void *cpu_addr, rt_ubase_t dma_handle, rt_ubase_t flags) -{ - const struct rt_dma_map_ops *ops; - - if (!dev || !size || !cpu_addr) - { - return; - } - - ops = device_dma_ops(dev); - - if (ops->free) - { - ops->free(dev, size, cpu_addr, dma_handle, flags); - } - else - { - dma_free(dev, size, cpu_addr, dma_handle, flags); - } -} - -rt_err_t rt_dma_sync_out_data(struct rt_device *dev, void *data, rt_size_t size, - rt_ubase_t *dma_handle, rt_ubase_t flags) -{ - rt_err_t err; - rt_ubase_t dma_handle_s = 0; - const struct rt_dma_map_ops *ops; - - if (!data || !size) - { - return -RT_EINVAL; - } - - ops = device_dma_ops(dev); - err = ops->sync_out_data(dev, data, size, &dma_handle_s, flags); - - if (dma_handle) - { - *dma_handle = dma_handle_s; - } - - return err; -} - -rt_err_t rt_dma_sync_in_data(struct rt_device *dev, void *out_data, rt_size_t size, - rt_ubase_t dma_handle, rt_ubase_t flags) -{ - rt_err_t err; - const struct rt_dma_map_ops *ops; - - if (!out_data || !size) - { - return -RT_EINVAL; - } - - ops = device_dma_ops(dev); - err = ops->sync_in_data(dev, out_data, size, dma_handle, flags); - - return err; -} - -static struct rt_dma_pool *dma_pool_install(rt_region_t *region) -{ - rt_err_t err; - struct rt_dma_pool *pool; - - if (!(pool = rt_calloc(1, sizeof(*pool)))) - { - LOG_E("Install pool[%p, %p] error = %s", - region->start, region->end, rt_strerror(-RT_ENOMEM)); - - return RT_NULL; - } - - rt_memcpy(&pool->region, region, sizeof(*region)); - - pool->flags |= RT_DMA_F_LINEAR; - - if (region->end < 4UL * SIZE_GB) - { - pool->flags |= RT_DMA_F_32BITS; - } - - pool->start = RT_ALIGN(pool->region.start, ARCH_PAGE_SIZE); - pool->bits = (pool->region.end - pool->start) / ARCH_PAGE_SIZE; - - if (!pool->bits) - { - err = -RT_EINVAL; - goto _fail; - } - - pool->map = rt_calloc(RT_BITMAP_LEN(pool->bits), sizeof(*pool->map)); - - if (!pool->map) - { - err = -RT_ENOMEM; - goto _fail; - } - - rt_list_init(&pool->list); - - region_pool_lock(); - rt_list_insert_before(&dma_pool_nodes, &pool->list); - region_pool_unlock(); - - return pool; - -_fail: - rt_free(pool); - - LOG_E("Install pool[%p, %p] error = %s", - region->start, region->end, rt_strerror(err)); - - return RT_NULL; -} - -struct rt_dma_pool *rt_dma_pool_install(rt_region_t *region) -{ - struct rt_dma_pool *pool; - - if (!region) - { - return RT_NULL; - } - - if ((pool = dma_pool_install(region))) - { - region = &pool->region; - - LOG_I("%s: Reserved %u.%u MiB at %p", - region->name, - (region->end - region->start) / SIZE_MB, - (region->end - region->start) / SIZE_KB & (SIZE_KB - 1), - region->start); - } - - return pool; -} - -rt_err_t rt_dma_pool_extract(rt_region_t *region_list, rt_size_t list_len, - rt_size_t cma_size, rt_size_t coherent_pool_size) -{ - struct rt_dma_pool *pool; - rt_region_t *region = region_list, *region_high = RT_NULL, cma, coherent_pool; - - if (!region_list || !list_len || cma_size < coherent_pool_size) - { - return -RT_EINVAL; - } - - for (rt_size_t i = 0; i < list_len; ++i, ++region) - { - if (!region->name) - { - continue; - } - - /* Always use low address in 4G */ - if (region->end - region->start >= cma_size) - { - if ((rt_ssize_t)((4UL * SIZE_GB) - region->start) < cma_size) - { - region_high = region; - continue; - } - - goto _found; - } - } - - if (region_high) - { - region = region_high; - LOG_W("No available DMA zone in 4G"); - - goto _found; - } - - return -RT_EEMPTY; - -_found: - if (region->end - region->start != cma_size) - { - cma.start = region->start; - cma.end = cma.start + cma_size; - - /* Update input region */ - region->start += cma_size; - } - else - { - rt_memcpy(&cma, region, sizeof(cma)); - } - - coherent_pool.name = "coherent-pool"; - coherent_pool.start = cma.start; - coherent_pool.end = coherent_pool.start + coherent_pool_size; - - cma.name = "cma"; - cma.start += coherent_pool_size; - - if (!(pool = rt_dma_pool_install(&coherent_pool))) - { - return -RT_ENOMEM; - } - - /* Use: CMA > coherent-pool */ - if (!(pool = rt_dma_pool_install(&cma))) - { - return -RT_ENOMEM; - } - - return RT_EOK; -} - -#if defined(RT_USING_CONSOLE) && defined(RT_USING_MSH) -static int list_dma_pool(int argc, char**argv) -{ - int count = 0; - rt_region_t *region; - struct rt_dma_pool *pool; - - rt_kprintf("%-*.s Region\n", RT_NAME_MAX, "Name"); - - region_pool_lock(); - - rt_list_for_each_entry(pool, &dma_pool_nodes, list) - { - region = &pool->region; - - rt_kprintf("%-*.s [%p, %p]\n", RT_NAME_MAX, region->name, - region->start, region->end); - - ++count; - } - - rt_kprintf("%d DMA memory found\n", count); - - region_pool_unlock(); - - return 0; -} -MSH_CMD_EXPORT(list_dma_pool, dump all dma memory pool); -#endif /* RT_USING_CONSOLE && RT_USING_MSH */ diff --git a/rt-thread/components/drivers/hwtimer/hwtimer.c b/rt-thread/components/drivers/hwtimer/hwtimer.c index 1b27925..bcf9ea9 100644 --- a/rt-thread/components/drivers/hwtimer/hwtimer.c +++ b/rt-thread/components/drivers/hwtimer/hwtimer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -320,14 +320,7 @@ static rt_err_t rt_hwtimer_control(struct rt_device *dev, int cmd, void *args) break; default: { - if (timer->ops->control != RT_NULL) - { - result = timer->ops->control(timer, cmd, args); - } - else - { - result = -RT_ENOSYS; - } + result = -RT_ENOSYS; } break; } diff --git a/rt-thread/components/drivers/i2c/Kconfig b/rt-thread/components/drivers/i2c/Kconfig index bb4c90d..40f04d1 100644 --- a/rt-thread/components/drivers/i2c/Kconfig +++ b/rt-thread/components/drivers/i2c/Kconfig @@ -17,227 +17,203 @@ if RT_USING_I2C default n endif - menuconfig RT_USING_SOFT_I2C + config RT_USING_SOFT_I2C bool "Use GPIO to soft simulate I2C" default n select RT_USING_PIN select RT_USING_I2C_BITOPS - if RT_USING_SOFT_I2C - menuconfig RT_USING_SOFT_I2C0 - bool "Enable I2C0 Bus (software simulation)" - default y - if RT_USING_SOFT_I2C0 - config RT_SOFT_I2C0_SCL_PIN - int "SCL pin number" - range 0 32767 - default 1 - config RT_SOFT_I2C0_SDA_PIN - int "SDA pin number" - range 0 32767 - default 2 - config RT_SOFT_I2C0_BUS_NAME - string "Bus name" - default "i2c0" - config RT_SOFT_I2C0_TIMING_DELAY - int "Timing delay (us)" - range 0 32767 - default 10 - config RT_SOFT_I2C0_TIMING_TIMEOUT - int "Timing timeout (tick)" - range 0 32767 - default 10 - endif - menuconfig RT_USING_SOFT_I2C1 - bool "Enable I2C1 Bus (software simulation)" - default y - if RT_USING_SOFT_I2C1 - config RT_SOFT_I2C1_SCL_PIN - int "SCL pin number" - range 0 32767 - default 3 - config RT_SOFT_I2C1_SDA_PIN - int "SDA pin number" - range 0 32767 - default 4 - config RT_SOFT_I2C1_BUS_NAME - string "Bus name" - default "i2c1" - config RT_SOFT_I2C1_TIMING_DELAY - int "Timing delay (us)" - range 0 32767 - default 10 - config RT_SOFT_I2C1_TIMING_TIMEOUT - int "Timing timeout (tick)" - range 0 32767 - default 10 - endif - menuconfig RT_USING_SOFT_I2C2 - bool "Enable I2C2 Bus (software simulation)" - default n - if RT_USING_SOFT_I2C2 - config RT_SOFT_I2C2_SCL_PIN - int "SCL pin number" - range 0 32767 - default 5 - config RT_SOFT_I2C2_SDA_PIN - int "SDA pin number" - range 0 32767 - default 6 - config RT_SOFT_I2C2_BUS_NAME - string "Bus name" - default "i2c2" - config RT_SOFT_I2C2_TIMING_DELAY - int "Timing delay (us)" - range 0 32767 - default 10 - config RT_SOFT_I2C2_TIMING_TIMEOUT - int "Timing timeout (tick)" - range 0 32767 - default 10 - endif - menuconfig RT_USING_SOFT_I2C3 - bool "Enable I2C3 Bus (software simulation)" - default n - if RT_USING_SOFT_I2C3 - config RT_SOFT_I2C3_SCL_PIN - int "SCL pin number" - range 0 32767 - default 7 - config RT_SOFT_I2C3_SDA_PIN - int "SDA pin number" - range 0 32767 - default 8 - config RT_SOFT_I2C3_BUS_NAME - string "Bus name" - default "i2c3" - config RT_SOFT_I2C3_TIMING_DELAY - int "Timing delay (us)" - range 0 32767 - default 10 - config RT_SOFT_I2C3_TIMING_TIMEOUT - int "Timing timeout (tick)" - range 0 32767 - default 10 - endif - menuconfig RT_USING_SOFT_I2C4 - bool "Enable I2C4 Bus (software simulation)" - default n - if RT_USING_SOFT_I2C4 - config RT_SOFT_I2C4_SCL_PIN - int "SCL pin number" - range 0 32767 - default 9 - config RT_SOFT_I2C4_SDA_PIN - int "SDA pin number" - range 0 32767 - default 10 - config RT_SOFT_I2C4_BUS_NAME - string "Bus name" - default "i2c4" - config RT_SOFT_I2C4_TIMING_DELAY - int "Timing delay (us)" - range 0 32767 - default 10 - config RT_SOFT_I2C4_TIMING_TIMEOUT - int "Timing timeout (tick)" - range 0 32767 - default 10 - endif - menuconfig RT_USING_SOFT_I2C5 - bool "Enable I2C5 Bus (software simulation)" - default n - if RT_USING_SOFT_I2C5 - config RT_SOFT_I2C5_SCL_PIN - int "SCL pin number" - range 0 32767 - default 11 - config RT_SOFT_I2C5_SDA_PIN - int "SDA pin number" - range 0 32767 - default 12 - config RT_SOFT_I2C5_BUS_NAME - string "Bus name" - default "i2c5" - config RT_SOFT_I2C5_TIMING_DELAY - int "Timing delay (us)" - range 0 32767 - default 10 - config RT_SOFT_I2C5_TIMING_TIMEOUT - int "Timing timeout (tick)" - range 0 32767 - default 10 - endif - menuconfig RT_USING_SOFT_I2C6 - bool "Enable I2C6 Bus (software simulation)" - default n - if RT_USING_SOFT_I2C6 - config RT_SOFT_I2C6_SCL_PIN - int "SCL pin number" - range 0 32767 - default 13 - config RT_SOFT_I2C6_SDA_PIN - int "SDA pin number" - range 0 32767 - default 14 - config RT_SOFT_I2C6_BUS_NAME - string "Bus name" - default "i2c6" - config RT_SOFT_I2C6_TIMING_DELAY - int "Timing delay (us)" - range 0 32767 - default 10 - config RT_SOFT_I2C6_TIMING_TIMEOUT - int "Timing timeout (tick)" - range 0 32767 - default 10 - endif - menuconfig RT_USING_SOFT_I2C7 - bool "Enable I2C7 Bus (software simulation)" - default n - if RT_USING_SOFT_I2C7 - config RT_SOFT_I2C7_SCL_PIN - int "SCL pin number" - range 0 32767 - default 15 - config RT_SOFT_I2C7_SDA_PIN - int "SDA pin number" - range 0 32767 - default 16 - config RT_SOFT_I2C7_BUS_NAME - string "Bus name" - default "i2c7" - config RT_SOFT_I2C7_TIMING_DELAY - int "Timing delay (us)" - range 0 32767 - default 10 - config RT_SOFT_I2C7_TIMING_TIMEOUT - int "Timing timeout (tick)" - range 0 32767 - default 10 - endif - menuconfig RT_USING_SOFT_I2C8 - bool "Enable I2C8 Bus (software simulation)" - default n - if RT_USING_SOFT_I2C8 - config RT_SOFT_I2C8_SCL_PIN - int "SCL pin number" - range 0 32767 - default 17 - config RT_SOFT_I2C8_SDA_PIN - int "SDA pin number" - range 0 32767 - default 18 - config RT_SOFT_I2C8_BUS_NAME - string "Bus name" - default "i2c8" - config RT_SOFT_I2C8_TIMING_DELAY - int "Timing delay (us)" - range 0 32767 - default 10 - config RT_SOFT_I2C8_TIMING_TIMEOUT - int "Timing timeout (tick)" - range 0 32767 - default 10 - endif - endif + if RT_USING_SOFT_I2C + config RT_USING_SOFT_I2C1 + bool "Enable I2C1 Bus (software simulation)" + default y + if RT_USING_SOFT_I2C1 + config RT_SOFT_I2C1_SCL_PIN + int "SCL pin number" + range 0 32767 + default 1 + config RT_SOFT_I2C1_SDA_PIN + int "SDA pin number" + range 0 32767 + default 2 + config RT_SOFT_I2C1_BUS_NAME + string "Bus name" + default "i2c1" + config RT_SOFT_I2C1_TIMING_DELAY + int "Timing delay (us)" + range 0 32767 + default 10 + config RT_SOFT_I2C1_TIMING_TIMEOUT + int "Timing timeout (tick)" + range 0 32767 + default 10 + endif + config RT_USING_SOFT_I2C2 + bool "Enable I2C2 Bus (software simulation)" + default n + if RT_USING_SOFT_I2C2 + config RT_SOFT_I2C2_SCL_PIN + int "SCL pin number" + range 0 32767 + default 3 + config RT_SOFT_I2C2_SDA_PIN + int "SDA pin number" + range 0 32767 + default 4 + config RT_SOFT_I2C2_BUS_NAME + string "Bus name" + default "i2c2" + config RT_SOFT_I2C2_TIMING_DELAY + int "Timing delay (us)" + range 0 32767 + default 10 + config RT_SOFT_I2C2_TIMING_TIMEOUT + int "Timing timeout (tick)" + range 0 32767 + default 10 + endif + config RT_USING_SOFT_I2C3 + bool "Enable I2C3 Bus (software simulation)" + default n + if RT_USING_SOFT_I2C3 + config RT_SOFT_I2C3_SCL_PIN + int "SCL pin number" + range 0 32767 + default 5 + config RT_SOFT_I2C3_SDA_PIN + int "SDA pin number" + range 0 32767 + default 6 + config RT_SOFT_I2C3_BUS_NAME + string "Bus name" + default "i2c3" + config RT_SOFT_I2C3_TIMING_DELAY + int "Timing delay (us)" + range 0 32767 + default 10 + config RT_SOFT_I2C3_TIMING_TIMEOUT + int "Timing timeout (tick)" + range 0 32767 + default 10 + endif + config RT_USING_SOFT_I2C4 + bool "Enable I2C4 Bus (software simulation)" + default n + if RT_USING_SOFT_I2C4 + config RT_SOFT_I2C4_SCL_PIN + int "SCL pin number" + range 0 32767 + default 7 + config RT_SOFT_I2C4_SDA_PIN + int "SDA pin number" + range 0 32767 + default 8 + config RT_SOFT_I2C4_BUS_NAME + string "Bus name" + default "i2c4" + config RT_SOFT_I2C4_TIMING_DELAY + int "Timing delay (us)" + range 0 32767 + default 10 + config RT_SOFT_I2C4_TIMING_TIMEOUT + int "Timing timeout (tick)" + range 0 32767 + default 10 + endif + config RT_USING_SOFT_I2C5 + bool "Enable I2C5 Bus (software simulation)" + default n + if RT_USING_SOFT_I2C5 + config RT_SOFT_I2C5_SCL_PIN + int "SCL pin number" + range 0 32767 + default 9 + config RT_SOFT_I2C5_SDA_PIN + int "SDA pin number" + range 0 32767 + default 10 + config RT_SOFT_I2C5_BUS_NAME + string "Bus name" + default "i2c5" + config RT_SOFT_I2C5_TIMING_DELAY + int "Timing delay (us)" + range 0 32767 + default 10 + config RT_SOFT_I2C5_TIMING_TIMEOUT + int "Timing timeout (tick)" + range 0 32767 + default 10 + endif + config RT_USING_SOFT_I2C6 + bool "Enable I2C6 Bus (software simulation)" + default n + if RT_USING_SOFT_I2C6 + config RT_SOFT_I2C6_SCL_PIN + int "SCL pin number" + range 0 32767 + default 11 + config RT_SOFT_I2C6_SDA_PIN + int "SDA pin number" + range 0 32767 + default 12 + config RT_SOFT_I2C6_BUS_NAME + string "Bus name" + default "i2c6" + config RT_SOFT_I2C6_TIMING_DELAY + int "Timing delay (us)" + range 0 32767 + default 10 + config RT_SOFT_I2C6_TIMING_TIMEOUT + int "Timing timeout (tick)" + range 0 32767 + default 10 + endif + config RT_USING_SOFT_I2C7 + bool "Enable I2C7 Bus (software simulation)" + default n + if RT_USING_SOFT_I2C7 + config RT_SOFT_I2C7_SCL_PIN + int "SCL pin number" + range 0 32767 + default 13 + config RT_SOFT_I2C7_SDA_PIN + int "SDA pin number" + range 0 32767 + default 14 + config RT_SOFT_I2C7_BUS_NAME + string "Bus name" + default "i2c7" + config RT_SOFT_I2C7_TIMING_DELAY + int "Timing delay (us)" + range 0 32767 + default 10 + config RT_SOFT_I2C7_TIMING_TIMEOUT + int "Timing timeout (tick)" + range 0 32767 + default 10 + endif + config RT_USING_SOFT_I2C8 + bool "Enable I2C8 Bus (software simulation)" + default n + if RT_USING_SOFT_I2C8 + config RT_SOFT_I2C8_SCL_PIN + int "SCL pin number" + range 0 32767 + default 15 + config RT_SOFT_I2C8_SDA_PIN + int "SDA pin number" + range 0 32767 + default 16 + config RT_SOFT_I2C8_BUS_NAME + string "Bus name" + default "i2c8" + config RT_SOFT_I2C8_TIMING_DELAY + int "Timing delay (us)" + range 0 32767 + default 10 + config RT_SOFT_I2C8_TIMING_TIMEOUT + int "Timing timeout (tick)" + range 0 32767 + default 10 + endif + endif endif diff --git a/rt-thread/components/drivers/i2c/SConscript b/rt-thread/components/drivers/i2c/SConscript index 269c6f5..3685e44 100644 --- a/rt-thread/components/drivers/i2c/SConscript +++ b/rt-thread/components/drivers/i2c/SConscript @@ -3,16 +3,16 @@ from building import * cwd = GetCurrentDir() src = Split(""" -dev_i2c_core.c -dev_i2c_dev.c +i2c_core.c +i2c_dev.c """) if GetDepend('RT_USING_I2C_BITOPS'): - src = src + ['dev_i2c_bit_ops.c'] + src = src + ['i2c-bit-ops.c'] if GetDepend('RT_USING_SOFT_I2C'): - src = src + ['dev_soft_i2c.c'] + src = src + ['soft_i2c.c'] if GetDepend(['RT_USING_DM']): - src += ['dev_i2c_bus.c', 'dev_i2c_dm.c'] + src += ['i2c_bus.c', 'i2c_dm.c'] # The set of source files associated with this SConscript file. path = [cwd + '/../include'] diff --git a/rt-thread/components/drivers/i2c/dev_i2c_bit_ops.c b/rt-thread/components/drivers/i2c/dev_i2c_bit_ops.c deleted file mode 100644 index 005cf90..0000000 --- a/rt-thread/components/drivers/i2c/dev_i2c_bit_ops.c +++ /dev/null @@ -1,464 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-04-25 weety first version - */ - -#include - -#define DBG_TAG "I2C" -#ifdef RT_I2C_BITOPS_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif -#include - -#define SET_SDA(ops, val) ops->set_sda(ops->data, val) -#define SET_SCL(ops, val) ops->set_scl(ops->data, val) -#define GET_SDA(ops) ops->get_sda(ops->data) -#define GET_SCL(ops) ops->get_scl(ops->data) - -rt_inline void i2c_delay(struct rt_i2c_bit_ops *ops) -{ - ops->udelay((ops->delay_us + 1) >> 1); -} - -rt_inline void i2c_delay2(struct rt_i2c_bit_ops *ops) -{ - ops->udelay(ops->delay_us); -} - -#define SDA_L(ops) SET_SDA(ops, 0) -#define SDA_H(ops) SET_SDA(ops, 1) -#define SCL_L(ops) SET_SCL(ops, 0) - -/** - * release scl line, and wait scl line to high. - */ -static rt_err_t SCL_H(struct rt_i2c_bit_ops *ops) -{ - rt_tick_t start; - - SET_SCL(ops, 1); - - if (!ops->get_scl) - goto done; - - start = rt_tick_get(); - while (!GET_SCL(ops)) - { - if ((rt_tick_get() - start) > ops->timeout) - return -RT_ETIMEOUT; - i2c_delay(ops); - } -#ifdef RT_I2C_BITOPS_DEBUG - if (rt_tick_get() != start) - { - LOG_D("wait %ld tick for SCL line to go high", - rt_tick_get() - start); - } -#endif - -done: - i2c_delay(ops); - - return RT_EOK; -} - -static void i2c_start(struct rt_i2c_bit_ops *ops) -{ -#ifdef RT_I2C_BITOPS_DEBUG - if (ops->get_scl && !GET_SCL(ops)) - { - LOG_E("I2C bus error, SCL line low"); - } - if (ops->get_sda && !GET_SDA(ops)) - { - LOG_E("I2C bus error, SDA line low"); - } -#endif - SDA_L(ops); - i2c_delay(ops); - SCL_L(ops); -} - -static void i2c_restart(struct rt_i2c_bit_ops *ops) -{ - SDA_H(ops); - SCL_H(ops); - i2c_delay(ops); - SDA_L(ops); - i2c_delay(ops); - SCL_L(ops); -} - -static void i2c_stop(struct rt_i2c_bit_ops *ops) -{ - SDA_L(ops); - i2c_delay(ops); - SCL_H(ops); - i2c_delay(ops); - SDA_H(ops); - i2c_delay2(ops); -} - -rt_inline rt_bool_t i2c_waitack(struct rt_i2c_bit_ops *ops) -{ - rt_bool_t ack; - - SDA_H(ops); - i2c_delay(ops); - - if (SCL_H(ops) < 0) - { - LOG_W("wait ack timeout"); - - return -RT_ETIMEOUT; - } - - ack = !GET_SDA(ops); /* ACK : SDA pin is pulled low */ - LOG_D("%s", ack ? "ACK" : "NACK"); - - SCL_L(ops); - - return ack; -} - -static rt_int32_t i2c_writeb(struct rt_i2c_bus_device *bus, rt_uint8_t data) -{ - rt_int32_t i; - rt_uint8_t bit; - - struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv; - - for (i = 7; i >= 0; i--) - { - SCL_L(ops); - bit = (data >> i) & 1; - SET_SDA(ops, bit); - i2c_delay(ops); - if (SCL_H(ops) < 0) - { - LOG_D("i2c_writeb: 0x%02x, " - "wait scl pin high timeout at bit %d", - data, i); - - return -RT_ETIMEOUT; - } - } - SCL_L(ops); - i2c_delay(ops); - - return i2c_waitack(ops); -} - -static rt_int32_t i2c_readb(struct rt_i2c_bus_device *bus) -{ - rt_uint8_t i; - rt_uint8_t data = 0; - struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv; - - SDA_H(ops); - i2c_delay(ops); - for (i = 0; i < 8; i++) - { - data <<= 1; - - if (SCL_H(ops) < 0) - { - LOG_D("i2c_readb: wait scl pin high " - "timeout at bit %d", 7 - i); - - return -RT_ETIMEOUT; - } - - if (GET_SDA(ops)) - data |= 1; - SCL_L(ops); - i2c_delay2(ops); - } - - return data; -} - -static rt_ssize_t i2c_send_bytes(struct rt_i2c_bus_device *bus, - struct rt_i2c_msg *msg) -{ - rt_int32_t ret; - rt_size_t bytes = 0; - const rt_uint8_t *ptr = msg->buf; - rt_int32_t count = msg->len; - rt_uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK; - - while (count > 0) - { - ret = i2c_writeb(bus, *ptr); - - if ((ret > 0) || (ignore_nack && (ret == 0))) - { - count --; - ptr ++; - bytes ++; - } - else if (ret == 0) - { - LOG_D("send bytes: NACK."); - - return 0; - } - else - { - LOG_E("send bytes: error %d", ret); - - return ret; - } - } - - return bytes; -} - -static rt_err_t i2c_send_ack_or_nack(struct rt_i2c_bus_device *bus, int ack) -{ - struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv; - - if (ack) - SET_SDA(ops, 0); - i2c_delay(ops); - if (SCL_H(ops) < 0) - { - LOG_E("ACK or NACK timeout."); - - return -RT_ETIMEOUT; - } - SCL_L(ops); - - return RT_EOK; -} - -static rt_ssize_t i2c_recv_bytes(struct rt_i2c_bus_device *bus, - struct rt_i2c_msg *msg) -{ - rt_int32_t val; - rt_int32_t bytes = 0; /* actual bytes */ - rt_uint8_t *ptr = msg->buf; - rt_int32_t count = msg->len; - const rt_uint32_t flags = msg->flags; - - while (count > 0) - { - val = i2c_readb(bus); - if (val >= 0) - { - *ptr = val; - bytes ++; - } - else - { - break; - } - - ptr ++; - count --; - - LOG_D("recieve bytes: 0x%02x, %s", - val, (flags & RT_I2C_NO_READ_ACK) ? - "(No ACK/NACK)" : (count ? "ACK" : "NACK")); - - if (!(flags & RT_I2C_NO_READ_ACK)) - { - val = i2c_send_ack_or_nack(bus, count); - if (val < 0) - return val; - } - } - - return bytes; -} - -static rt_int32_t i2c_send_address(struct rt_i2c_bus_device *bus, - rt_uint8_t addr, - rt_int32_t retries) -{ - struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv; - rt_int32_t i; - rt_err_t ret = 0; - - for (i = 0; i <= retries; i++) - { - ret = i2c_writeb(bus, addr); - if (ret == 1 || i == retries) - break; - LOG_D("send stop condition"); - i2c_stop(ops); - i2c_delay2(ops); - LOG_D("send start condition"); - i2c_start(ops); - } - - return ret; -} - -static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus, - struct rt_i2c_msg *msg) -{ - rt_uint16_t flags = msg->flags; - rt_uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK; - struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv; - - rt_uint8_t addr1, addr2; - rt_int32_t retries; - rt_err_t ret; - - retries = ignore_nack ? 0 : bus->retries; - - if (flags & RT_I2C_ADDR_10BIT) - { - addr1 = 0xf0 | ((msg->addr >> 7) & 0x06); - addr2 = msg->addr & 0xff; - - LOG_D("addr1: %d, addr2: %d", addr1, addr2); - - ret = i2c_send_address(bus, addr1, retries); - if ((ret != 1) && !ignore_nack) - { - LOG_W("NACK: sending first addr"); - - return -RT_EIO; - } - - ret = i2c_writeb(bus, addr2); - if ((ret != 1) && !ignore_nack) - { - LOG_W("NACK: sending second addr"); - - return -RT_EIO; - } - if (flags & RT_I2C_RD) - { - LOG_D("send repeated start condition"); - i2c_restart(ops); - addr1 |= 0x01; - ret = i2c_send_address(bus, addr1, retries); - if ((ret != 1) && !ignore_nack) - { - LOG_E("NACK: sending repeated addr"); - - return -RT_EIO; - } - } - } - else - { - /* 7-bit addr */ - addr1 = msg->addr << 1; - if (flags & RT_I2C_RD) - addr1 |= 1; - ret = i2c_send_address(bus, addr1, retries); - if ((ret != 1) && !ignore_nack) - return -RT_EIO; - } - - return RT_EOK; -} - -static rt_ssize_t i2c_bit_xfer(struct rt_i2c_bus_device *bus, - struct rt_i2c_msg msgs[], - rt_uint32_t num) -{ - struct rt_i2c_msg *msg; - struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv; - rt_int32_t ret; - rt_uint32_t i; - rt_uint16_t ignore_nack; - - if((ops->i2c_pin_init_flag == RT_FALSE) && (ops->pin_init != RT_NULL)) - { - ops->pin_init(); - ops->i2c_pin_init_flag = RT_TRUE; - } - - if (num == 0) return 0; - - for (i = 0; i < num; i++) - { - msg = &msgs[i]; - ignore_nack = msg->flags & RT_I2C_IGNORE_NACK; - if (!(msg->flags & RT_I2C_NO_START)) - { - if (i) - { - i2c_restart(ops); - } - else - { - LOG_D("send start condition"); - i2c_start(ops); - } - ret = i2c_bit_send_address(bus, msg); - if ((ret != RT_EOK) && !ignore_nack) - { - LOG_D("receive NACK from device addr 0x%02x msg %d", - msgs[i].addr, i); - goto out; - } - } - if (msg->flags & RT_I2C_RD) - { - ret = i2c_recv_bytes(bus, msg); - if (ret >= 1) - { - LOG_D("read %d byte%s", ret, ret == 1 ? "" : "s"); - } - if (ret < msg->len) - { - if (ret >= 0) - ret = -RT_EIO; - goto out; - } - } - else - { - ret = i2c_send_bytes(bus, msg); - if (ret >= 1) - { - LOG_D("write %d byte%s", ret, ret == 1 ? "" : "s"); - } - if (ret < msg->len) - { - if (ret >= 0) - ret = -RT_ERROR; - goto out; - } - } - } - ret = i; - -out: - if (!(msg->flags & RT_I2C_NO_STOP)) - { - LOG_D("send stop condition"); - i2c_stop(ops); - } - - return ret; -} - -static const struct rt_i2c_bus_device_ops i2c_bit_bus_ops = -{ - i2c_bit_xfer, - RT_NULL, - RT_NULL -}; - -rt_err_t rt_i2c_bit_add_bus(struct rt_i2c_bus_device *bus, - const char *bus_name) -{ - bus->ops = &i2c_bit_bus_ops; - - return rt_i2c_bus_device_register(bus, bus_name); -} diff --git a/rt-thread/components/drivers/i2c/dev_i2c_bus.c b/rt-thread/components/drivers/i2c/dev_i2c_bus.c deleted file mode 100644 index 8a52471..0000000 --- a/rt-thread/components/drivers/i2c/dev_i2c_bus.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-12-06 GuEe-GUI first version - */ - -#include - -#define DBG_TAG "dev.i2c.bus" -#define DBG_LVL DBG_INFO -#include - -static struct rt_bus i2c_bus; - -void i2c_bus_scan_clients(struct rt_i2c_bus_device *bus) -{ -#ifdef RT_USING_OFW - if (bus->parent.ofw_node) - { - struct rt_ofw_node *np = bus->parent.ofw_node, *child_np, *i2c_client_np; - - rt_ofw_foreach_available_child_node(np, child_np) - { - rt_uint32_t client_addr; - struct rt_i2c_client *client; - - if (rt_ofw_prop_read_bool(child_np, "compatible")) - { - i2c_client_np = child_np; - } - else - { - /* Maybe in i2c-mux */ - i2c_client_np = rt_ofw_get_next_child(child_np, RT_NULL); - - if (!rt_ofw_prop_read_bool(i2c_client_np, "compatible")) - { - continue; - } - } - - client = rt_calloc(1, sizeof(*client)); - - if (!client) - { - rt_ofw_node_put(i2c_client_np); - LOG_E("Not memory to create i2c client: %s", - rt_ofw_node_full_name(i2c_client_np)); - - return; - } - - rt_ofw_prop_read_u32(i2c_client_np, "reg", &client_addr); - - client->parent.ofw_node = i2c_client_np; - client->name = rt_ofw_node_name(i2c_client_np); - client->bus = bus; - client->client_addr = client_addr; - - rt_i2c_device_register(client); - - if (i2c_client_np != child_np) - { - rt_ofw_node_put(i2c_client_np); - } - } - } -#endif /* RT_USING_OFW */ -} - -rt_err_t rt_i2c_driver_register(struct rt_i2c_driver *driver) -{ - RT_ASSERT(driver != RT_NULL); - - driver->parent.bus = &i2c_bus; - - return rt_driver_register(&driver->parent); -} - -rt_err_t rt_i2c_device_register(struct rt_i2c_client *client) -{ - RT_ASSERT(client != RT_NULL); - - return rt_bus_add_device(&i2c_bus, &client->parent); -} - -static rt_bool_t i2c_match(rt_driver_t drv, rt_device_t dev) -{ - const struct rt_i2c_device_id *id; - struct rt_i2c_driver *driver = rt_container_of(drv, struct rt_i2c_driver, parent); - struct rt_i2c_client *client = rt_container_of(dev, struct rt_i2c_client, parent); - - if ((id = driver->ids)) - { - for (; id->name[0]; ++id) - { - if (!rt_strcmp(id->name, client->name)) - { - client->id = id; - client->ofw_id = RT_NULL; - - return RT_TRUE; - } - } - } - -#ifdef RT_USING_OFW - client->ofw_id = rt_ofw_node_match(client->parent.ofw_node, driver->ofw_ids); - - if (client->ofw_id) - { - client->id = RT_NULL; - - return RT_TRUE; - } -#endif - - return RT_FALSE; -} - -static rt_err_t i2c_probe(rt_device_t dev) -{ - rt_err_t err; - struct rt_i2c_driver *driver = rt_container_of(dev->drv, struct rt_i2c_driver, parent); - struct rt_i2c_client *client = rt_container_of(dev, struct rt_i2c_client, parent); - - if (!client->bus) - { - return -RT_EINVAL; - } - - err = driver->probe(client); - - return err; -} - -static rt_err_t i2c_remove(rt_device_t dev) -{ - struct rt_i2c_driver *driver = rt_container_of(dev->drv, struct rt_i2c_driver, parent); - struct rt_i2c_client *client = rt_container_of(dev, struct rt_i2c_client, parent); - - if (driver && driver->remove) - { - driver->remove(client); - } - - return RT_EOK; -} - -static rt_err_t i2c_shutdown(rt_device_t dev) -{ - struct rt_i2c_driver *driver = rt_container_of(dev->drv, struct rt_i2c_driver, parent); - struct rt_i2c_client *client = rt_container_of(dev, struct rt_i2c_client, parent); - - if (driver && driver->shutdown) - { - driver->shutdown(client); - } - - return RT_EOK; -} - -static struct rt_bus i2c_bus = -{ - .name = "i2c", - .match = i2c_match, - .probe = i2c_probe, - .remove = i2c_remove, - .shutdown = i2c_shutdown, -}; - -static int i2c_bus_init(void) -{ - rt_bus_register(&i2c_bus); - - return 0; -} -INIT_CORE_EXPORT(i2c_bus_init); diff --git a/rt-thread/components/drivers/i2c/dev_i2c_core.c b/rt-thread/components/drivers/i2c/dev_i2c_core.c deleted file mode 100644 index 9d9bf6b..0000000 --- a/rt-thread/components/drivers/i2c/dev_i2c_core.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-04-25 weety first version - * 2021-04-20 RiceChen added support for bus control api - */ - -#include - -#define DBG_TAG "I2C" -#ifdef RT_I2C_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif -#include - -rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus, - const char *bus_name) -{ - rt_err_t res = RT_EOK; - - rt_mutex_init(&bus->lock, "i2c_bus_lock", RT_IPC_FLAG_PRIO); - - if (bus->timeout == 0) bus->timeout = RT_TICK_PER_SECOND; - - res = rt_i2c_bus_device_device_init(bus, bus_name); - - LOG_D("I2C bus [%s] registered", bus_name); - -#ifdef RT_USING_DM - if (!res) - { - i2c_bus_scan_clients(bus); - } -#endif - - return res; -} - -struct rt_i2c_bus_device *rt_i2c_bus_device_find(const char *bus_name) -{ - struct rt_i2c_bus_device *bus; - rt_device_t dev = rt_device_find(bus_name); - if (dev == RT_NULL || dev->type != RT_Device_Class_I2CBUS) - { - LOG_E("I2C bus %s not exist", bus_name); - - return RT_NULL; - } - - bus = (struct rt_i2c_bus_device *)dev->user_data; - - return bus; -} - -rt_ssize_t rt_i2c_transfer(struct rt_i2c_bus_device *bus, - struct rt_i2c_msg msgs[], - rt_uint32_t num) -{ - rt_ssize_t ret; - rt_err_t err; - - if (bus->ops->master_xfer) - { -#ifdef RT_I2C_DEBUG - for (ret = 0; ret < num; ret++) - { - LOG_D("msgs[%d] %c, addr=0x%02x, len=%d", ret, - (msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W', - msgs[ret].addr, msgs[ret].len); - } -#endif - err = rt_mutex_take(&bus->lock, RT_WAITING_FOREVER); - if (err != RT_EOK) - { - return (rt_ssize_t)err; - } - ret = bus->ops->master_xfer(bus, msgs, num); - err = rt_mutex_release(&bus->lock); - if (err != RT_EOK) - { - return (rt_ssize_t)err; - } - return ret; - } - else - { - LOG_E("I2C bus operation not supported"); - return -RT_EINVAL; - } -} - -rt_err_t rt_i2c_control(struct rt_i2c_bus_device *bus, - int cmd, - void *args) -{ - rt_err_t ret; - - if(bus->ops->i2c_bus_control) - { - ret = bus->ops->i2c_bus_control(bus, cmd, args); - return ret; - } - else - { - LOG_E("I2C bus operation not supported"); - return -RT_EINVAL; - } -} - -rt_ssize_t rt_i2c_master_send(struct rt_i2c_bus_device *bus, - rt_uint16_t addr, - rt_uint16_t flags, - const rt_uint8_t *buf, - rt_uint32_t count) -{ - rt_ssize_t ret; - struct rt_i2c_msg msg; - - msg.addr = addr; - msg.flags = flags; - msg.len = count; - msg.buf = (rt_uint8_t *)buf; - - ret = rt_i2c_transfer(bus, &msg, 1); - - return (ret == 1) ? count : ret; -} - -rt_ssize_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus, - rt_uint16_t addr, - rt_uint16_t flags, - rt_uint8_t *buf, - rt_uint32_t count) -{ - rt_ssize_t ret; - struct rt_i2c_msg msg; - RT_ASSERT(bus != RT_NULL); - - msg.addr = addr; - msg.flags = flags | RT_I2C_RD; - msg.len = count; - msg.buf = buf; - - ret = rt_i2c_transfer(bus, &msg, 1); - - return (ret == 1) ? count : ret; -} diff --git a/rt-thread/components/drivers/i2c/dev_i2c_dev.c b/rt-thread/components/drivers/i2c/dev_i2c_dev.c deleted file mode 100644 index 96110b9..0000000 --- a/rt-thread/components/drivers/i2c/dev_i2c_dev.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-04-25 weety first version - * 2014-08-03 bernard fix some compiling warning - * 2021-04-20 RiceChen added support for bus clock control - */ - -#include - -#define DBG_TAG "I2C" -#ifdef RT_I2C_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif -#include - -static rt_ssize_t i2c_bus_device_read(rt_device_t dev, - rt_off_t pos, - void *buffer, - rt_size_t count) -{ - rt_uint16_t addr; - rt_uint16_t flags; - struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data; - - RT_ASSERT(bus != RT_NULL); - RT_ASSERT(buffer != RT_NULL); - - LOG_D("I2C bus dev [%s] reading %u bytes.", dev->parent.name, count); - - addr = pos & 0xffff; - flags = (pos >> 16) & 0xffff; - - return rt_i2c_master_recv(bus, addr, flags, (rt_uint8_t *)buffer, count); -} - -static rt_ssize_t i2c_bus_device_write(rt_device_t dev, - rt_off_t pos, - const void *buffer, - rt_size_t count) -{ - rt_uint16_t addr; - rt_uint16_t flags; - struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data; - - RT_ASSERT(bus != RT_NULL); - RT_ASSERT(buffer != RT_NULL); - - LOG_D("I2C bus dev [%s] writing %u bytes.", dev->parent.name, count); - - addr = pos & 0xffff; - flags = (pos >> 16) & 0xffff; - - return rt_i2c_master_send(bus, addr, flags, (const rt_uint8_t *)buffer, count); -} - -static rt_err_t i2c_bus_device_control(rt_device_t dev, - int cmd, - void *args) -{ - rt_err_t ret; - struct rt_i2c_priv_data *priv_data; - struct rt_i2c_bus_device *bus = (struct rt_i2c_bus_device *)dev->user_data; - - RT_ASSERT(bus != RT_NULL); - - switch (cmd) - { - /* set 10-bit addr mode */ - case RT_I2C_DEV_CTRL_10BIT: - bus->flags |= RT_I2C_ADDR_10BIT; - break; - case RT_I2C_DEV_CTRL_TIMEOUT: - bus->timeout = *(rt_uint32_t *)args; - break; - case RT_I2C_DEV_CTRL_RW: - priv_data = (struct rt_i2c_priv_data *)args; - ret = rt_i2c_transfer(bus, priv_data->msgs, priv_data->number); - if (ret < 0) - { - return -RT_EIO; - } - break; - default: - return rt_i2c_control(bus, cmd, args); - } - - return RT_EOK; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops i2c_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - i2c_bus_device_read, - i2c_bus_device_write, - i2c_bus_device_control -}; -#endif - -rt_err_t rt_i2c_bus_device_device_init(struct rt_i2c_bus_device *bus, - const char *name) -{ - struct rt_device *device; - RT_ASSERT(bus != RT_NULL); - - device = &bus->parent; - - device->user_data = bus; - - /* set device type */ - device->type = RT_Device_Class_I2CBUS; - /* initialize device interface */ -#ifdef RT_USING_DEVICE_OPS - device->ops = &i2c_ops; -#else - device->init = RT_NULL; - device->open = RT_NULL; - device->close = RT_NULL; - device->read = i2c_bus_device_read; - device->write = i2c_bus_device_write; - device->control = i2c_bus_device_control; -#endif - - /* register to device manager */ - rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); - - return RT_EOK; -} diff --git a/rt-thread/components/drivers/i2c/dev_i2c_dm.c b/rt-thread/components/drivers/i2c/dev_i2c_dm.c deleted file mode 100644 index 5701dd5..0000000 --- a/rt-thread/components/drivers/i2c/dev_i2c_dm.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-12-06 GuEe-GUI first version - */ - -#include - -#define DBG_TAG "dev.i2c.dm" -#define DBG_LVL DBG_INFO -#include - -#ifdef RT_USING_OFW -static void i2c_parse_timing(struct rt_ofw_node *dev_np, const char *propname, - rt_uint32_t *out_value, rt_uint32_t def_value, rt_bool_t use_defaults) -{ - if (rt_ofw_prop_read_u32(dev_np, propname, out_value) && use_defaults) - { - *out_value = def_value; - } -} - -rt_err_t i2c_timings_ofw_parse(struct rt_ofw_node *dev_np, struct i2c_timings *timings, - rt_bool_t use_defaults) -{ - rt_ubase_t def; - rt_bool_t udef = use_defaults; - struct i2c_timings *t = timings; - - i2c_parse_timing(dev_np, "clock-frequency", &t->bus_freq_hz, I2C_MAX_STANDARD_MODE_FREQ, udef); - - def = t->bus_freq_hz <= I2C_MAX_STANDARD_MODE_FREQ ? 1000 : t->bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ ? 300 : 120; - i2c_parse_timing(dev_np, "i2c-scl-rising-time-ns", &t->scl_rise_ns, def, udef); - - def = t->bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ ? 300 : 120; - i2c_parse_timing(dev_np, "i2c-scl-falling-time-ns", &t->scl_fall_ns, def, udef); - - i2c_parse_timing(dev_np, "i2c-scl-internal-delay-ns", &t->scl_int_delay_ns, 0, udef); - i2c_parse_timing(dev_np, "i2c-sda-falling-time-ns", &t->sda_fall_ns, t->scl_fall_ns, udef); - i2c_parse_timing(dev_np, "i2c-sda-hold-time-ns", &t->sda_hold_ns, 0, udef); - i2c_parse_timing(dev_np, "i2c-digital-filter-width-ns", &t->digital_filter_width_ns, 0, udef); - i2c_parse_timing(dev_np, "i2c-analog-filter-cutoff-frequency", &t->analog_filter_cutoff_freq_hz, 0, udef); - - return RT_EOK; -} -#endif /* RT_USING_OFW */ diff --git a/rt-thread/components/drivers/i2c/dev_soft_i2c.c b/rt-thread/components/drivers/i2c/dev_soft_i2c.c deleted file mode 100644 index a9c661e..0000000 --- a/rt-thread/components/drivers/i2c/dev_soft_i2c.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-07-30 sp-cai first version - */ - -#include - -#ifdef RT_USING_SOFT_I2C -#if !defined(RT_USING_SOFT_I2C0) &&\ - !defined(RT_USING_SOFT_I2C1) && !defined(RT_USING_SOFT_I2C2) &&\ - !defined(RT_USING_SOFT_I2C3) && !defined(RT_USING_SOFT_I2C4) &&\ - !defined(RT_USING_SOFT_I2C5) && !defined(RT_USING_SOFT_I2C6) &&\ - !defined(RT_USING_SOFT_I2C7) && !defined(RT_USING_SOFT_I2C8) - #error "Please define at least one RT_USING_SOFT_I2Cx" - /* - This driver can be disabled at: - menuconfig -> RT-Thread Components -> Device Drivers -> Using I2C device drivers - */ -#endif - -#define DBG_ENABLE -#define DBG_TAG "I2C_S" -#ifdef RT_I2C_BITOPS_DEBUG - #define DBG_LEVEL DBG_LOG -#endif -#include - -/* i2c config class */ -struct soft_i2c_config -{ - rt_base_t scl_pin; - rt_base_t sda_pin; - const char *bus_name; - rt_uint16_t timing_delay; /* scl and sda line delay */ - rt_uint16_t timing_timeout; /* in tick */ -}; - -/* i2c dirver class */ -struct rt_soft_i2c -{ - struct rt_i2c_bus_device i2c_bus; - struct rt_i2c_bit_ops ops; -}; - -struct soft_i2c_config i2c_cfg[] = -{ - #ifdef RT_USING_SOFT_I2C0 - { - .scl_pin = RT_SOFT_I2C0_SCL_PIN, - .sda_pin = RT_SOFT_I2C0_SDA_PIN, - .bus_name = RT_SOFT_I2C0_BUS_NAME, - .timing_delay = RT_SOFT_I2C0_TIMING_DELAY, - .timing_timeout = RT_SOFT_I2C0_TIMING_TIMEOUT, - }, - #endif //RT_USING_SOFT_I2C0 - #ifdef RT_USING_SOFT_I2C1 - { - .scl_pin = RT_SOFT_I2C1_SCL_PIN, - .sda_pin = RT_SOFT_I2C1_SDA_PIN, - .bus_name = RT_SOFT_I2C1_BUS_NAME, - .timing_delay = RT_SOFT_I2C1_TIMING_DELAY, - .timing_timeout = RT_SOFT_I2C1_TIMING_TIMEOUT, - }, - #endif //RT_USING_SOFT_I2C1 - #ifdef RT_USING_SOFT_I2C2 - { - .scl_pin = RT_SOFT_I2C2_SCL_PIN, - .sda_pin = RT_SOFT_I2C2_SDA_PIN, - .bus_name = RT_SOFT_I2C2_BUS_NAME, - .timing_delay = RT_SOFT_I2C2_TIMING_DELAY, - .timing_timeout = RT_SOFT_I2C2_TIMING_TIMEOUT, - }, - #endif //RT_USING_SOFT_I2C2 - #ifdef RT_USING_SOFT_I2C3 - { - .scl_pin = RT_SOFT_I2C3_SCL_PIN, - .sda_pin = RT_SOFT_I2C3_SDA_PIN, - .bus_name = RT_SOFT_I2C3_BUS_NAME, - .timing_delay = RT_SOFT_I2C3_TIMING_DELAY, - .timing_timeout = RT_SOFT_I2C3_TIMING_TIMEOUT, - }, - #endif //RT_USING_SOFT_I2C3 - #ifdef RT_USING_SOFT_I2C4 - { - .scl_pin = RT_SOFT_I2C4_SCL_PIN, - .sda_pin = RT_SOFT_I2C4_SDA_PIN, - .bus_name = RT_SOFT_I2C4_BUS_NAME, - .timing_delay = RT_SOFT_I2C4_TIMING_DELAY, - .timing_timeout = RT_SOFT_I2C4_TIMING_TIMEOUT, - }, - #endif //RT_USING_SOFT_I2C4 - #ifdef RT_USING_SOFT_I2C5 - { - .scl_pin = RT_SOFT_I2C5_SCL_PIN, - .sda_pin = RT_SOFT_I2C5_SDA_PIN, - .bus_name = RT_SOFT_I2C5_BUS_NAME, - .timing_delay = RT_SOFT_I2C5_TIMING_DELAY, - .timing_timeout = RT_SOFT_I2C5_TIMING_TIMEOUT, - }, - #endif //RT_USING_SOFT_I2C5 - #ifdef RT_USING_SOFT_I2C6 - { - .scl_pin = RT_SOFT_I2C6_SCL_PIN, - .sda_pin = RT_SOFT_I2C6_SDA_PIN, - .bus_name = RT_SOFT_I2C6_BUS_NAME, - .timing_delay = RT_SOFT_I2C6_TIMING_DELAY, - .timing_timeout = RT_SOFT_I2C6_TIMING_TIMEOUT, - }, - #endif //RT_USING_SOFT_I2C6 - #ifdef RT_USING_SOFT_I2C7 - { - .scl_pin = RT_SOFT_I2C7_SCL_PIN, - .sda_pin = RT_SOFT_I2C7_SDA_PIN, - .bus_name = RT_SOFT_I2C7_BUS_NAME, - .timing_delay = RT_SOFT_I2C7_TIMING_DELAY, - .timing_timeout = RT_SOFT_I2C7_TIMING_TIMEOUT, - }, - #endif //RT_USING_SOFT_I2C7 - #ifdef RT_USING_SOFT_I2C8 - { - .scl_pin = RT_SOFT_I2C8_SCL_PIN, - .sda_pin = RT_SOFT_I2C8_SDA_PIN, - .bus_name = RT_SOFT_I2C8_BUS_NAME, - .timing_delay = RT_SOFT_I2C8_TIMING_DELAY, - .timing_timeout = RT_SOFT_I2C8_TIMING_TIMEOUT, - }, - #endif //RT_USING_SOFT_I2C8 -}; - - -static struct rt_soft_i2c i2c_bus_obj[sizeof(i2c_cfg) / sizeof(i2c_cfg[0])] = -{ 0 }; - -/** -* This function initializes the i2c pin. -* @param i2c config class. -*/ -static void pin_init(const struct soft_i2c_config *cfg) -{ - rt_pin_mode(cfg->scl_pin, PIN_MODE_OUTPUT_OD); - rt_pin_mode(cfg->sda_pin, PIN_MODE_OUTPUT_OD); - rt_pin_write(cfg->scl_pin, PIN_HIGH); - rt_pin_write(cfg->sda_pin, PIN_HIGH); -} - - -/** -* This function sets the sda pin. -* @param i2c config class. -* @param The sda pin state. -*/ -static void set_sda(void *cfg, rt_int32_t value) -{ - rt_pin_write(((const struct soft_i2c_config*)cfg)->sda_pin, value); -} - -/** -* This function sets the scl pin. -* @param i2c config class. -* @param The sda pin state. -*/ -static void set_scl(void *cfg, rt_int32_t value) -{ - rt_pin_write(((const struct soft_i2c_config*)cfg)->scl_pin, value); -} - -/** -* This function gets the sda pin state. -* @param i2c config class. -*/ -static rt_int32_t get_sda(void *cfg) -{ - return rt_pin_read(((const struct soft_i2c_config*)cfg)->sda_pin); -} - -/** -* This function gets the scl pin state. -* @param i2c config class. -*/ -static rt_int32_t get_scl(void *cfg) -{ - return rt_pin_read(((const struct soft_i2c_config*)cfg)->scl_pin); -} - - -static const struct rt_i2c_bit_ops soft_i2c_ops = -{ - .set_sda = set_sda, - .set_scl = set_scl, - .get_sda = get_sda, - .get_scl = get_scl, - .udelay = rt_hw_us_delay, -}; - -/** -* if i2c is locked, this function will unlock it -* -* @param i2c config class. -* -* @return RT_EOK indicates successful unlock. -*/ -static rt_err_t i2c_bus_unlock(const struct soft_i2c_config *cfg) -{ - rt_ubase_t i = 0; - - if(PIN_LOW == rt_pin_read(cfg->sda_pin)) - { - while(i++ < 9) - { - rt_pin_write(cfg->scl_pin, PIN_HIGH); - rt_hw_us_delay(cfg->timing_delay); - rt_pin_write(cfg->scl_pin, PIN_LOW); - rt_hw_us_delay(cfg->timing_delay); - } - } - if(PIN_LOW == rt_pin_read(cfg->sda_pin)) - { - return -RT_ERROR; - } - - return RT_EOK; -} - -/* I2C initialization function */ -int rt_soft_i2c_init(void) -{ - int err = RT_EOK; - struct rt_soft_i2c *obj; - int i; - - for(i = 0; i < sizeof(i2c_bus_obj) / sizeof(i2c_bus_obj[0]); i++) - { - struct soft_i2c_config *cfg = &i2c_cfg[i]; - - pin_init(cfg); - - obj = &i2c_bus_obj[i]; - obj->ops = soft_i2c_ops; - obj->ops.data = cfg; - obj->i2c_bus.priv = &obj->ops; - obj->ops.delay_us = cfg->timing_delay; - obj->ops.timeout = cfg->timing_timeout; - if(rt_i2c_bit_add_bus(&obj->i2c_bus, cfg->bus_name) == RT_EOK) - { - i2c_bus_unlock(cfg); - LOG_D("Software simulation %s init done" - ", SCL pin: 0x%02X, SDA pin: 0x%02X" - , cfg->bus_name - , cfg->scl_pin - , cfg->sda_pin - ); - } - else - { - err++; - LOG_E("Software simulation %s init fail" - ", SCL pin: 0x%02X, SDA pin: 0x%02X" - , cfg->bus_name - , cfg->scl_pin - , cfg->sda_pin - ); - } - } - - return err; -} -INIT_PREV_EXPORT(rt_soft_i2c_init); - -#endif // RT_USING_SOFT_I2C diff --git a/rt-thread/components/drivers/iio/SConscript b/rt-thread/components/drivers/iio/SConscript deleted file mode 100644 index 577dab2..0000000 --- a/rt-thread/components/drivers/iio/SConscript +++ /dev/null @@ -1,15 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_USING_DM']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../include'] - -src = ['iio.c',] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/iio/iio.c b/rt-thread/components/drivers/iio/iio.c deleted file mode 100644 index 548308d..0000000 --- a/rt-thread/components/drivers/iio/iio.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#include -#include - -static void *ofw_iio_channel_get_by_index(struct rt_ofw_node *np, int index, int *out_channel) -{ - void *iio = RT_NULL; -#ifdef RT_USING_OFW - struct rt_ofw_node *iio_np; - struct rt_ofw_cell_args iio_args; - - if (!rt_ofw_parse_phandle_cells(np, "io-channels", "#io-channel-cells", index, &iio_args)) - { - iio_np = iio_args.data; - - if (!rt_ofw_data(iio_np)) - { - rt_platform_ofw_request(iio_np); - } - - iio = rt_ofw_data(iio_np); - rt_ofw_node_put(iio_np); - - if (out_channel) - { - *out_channel = iio_args.args[0]; - } - } -#endif /* RT_USING_OFW */ - return iio; -} - -void *rt_iio_channel_get_by_index(struct rt_device *dev, int index, int *out_channel) -{ - void *iio = RT_NULL; - - if (!dev || index < 0) - { - return RT_NULL; - } - - if (dev->ofw_node) - { - iio = ofw_iio_channel_get_by_index(dev->ofw_node, index, out_channel); - } - - return iio; -} - -void *rt_iio_channel_get_by_name(struct rt_device *dev, const char *name, int *out_channel) -{ - int index; - - if (!dev || !name) - { - return RT_NULL; - } - - index = rt_dm_dev_prop_index_of_string(dev, "io-channel-names", name); - - return rt_iio_channel_get_by_index(dev, index, out_channel); -} diff --git a/rt-thread/components/drivers/include/drivers/adc.h b/rt-thread/components/drivers/include/drivers/adc.h index 7189ae5..7c35f1e 100644 --- a/rt-thread/components/drivers/include/drivers/adc.h +++ b/rt-thread/components/drivers/include/drivers/adc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -14,65 +14,12 @@ #define __ADC_H__ #include -/** - * @addtogroup Drivers RTTHREAD Driver - * @defgroup ADC ADC - * - * @brief ADC driver api - * - * Example - * @code {.c} - * #define ADC_DEV_NAME "adc1" - * #define ADC_DEV_CHANNEL 5 - * #define REFER_VOLTAGE 330 - * #define CONVERT_BITS (1 << 12) - * - * static int adc_vol_sample(int argc, char *argv[]) - * { - * rt_adc_device_t adc_dev; - * rt_uint32_t value, vol; - * - * rt_err_t ret = RT_EOK; - * - * adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME); - * if (adc_dev == RT_NULL) - * { - * rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME); - * return -RT_ERROR; - * } - * - * ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL); - * - * value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL); - * rt_kprintf("the value is :%d \n", value); - * - * vol = value * REFER_VOLTAGE / CONVERT_BITS; - * rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100); - * - * ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL); - * - * return ret; - * } - * MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample); - * - * @endcode - * - * @ingroup Drivers - */ - -/*! - * @addtogroup ADC - * @{ - */ #define RT_ADC_INTERN_CH_TEMPER (-1) #define RT_ADC_INTERN_CH_VREF (-2) #define RT_ADC_INTERN_CH_VBAT (-3) struct rt_adc_device; -/** - * @brief Configure the adc device - */ struct rt_adc_ops { rt_err_t (*enabled)(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled); @@ -80,9 +27,7 @@ struct rt_adc_ops rt_uint8_t (*get_resolution)(struct rt_adc_device *device); rt_int16_t (*get_vref) (struct rt_adc_device *device); }; -/** - * @brief adc device - */ + struct rt_adc_device { struct rt_device parent; @@ -98,53 +43,10 @@ typedef enum RT_ADC_CMD_GET_VREF = RT_DEVICE_CTRL_BASE(ADC) + 4, /* get reference voltage */ } rt_adc_cmd_t; -/** - * @brief register the adc device - * @param adc adc device - * @param name device name - * @param ops device ops - * @param user_data device private data - * @return rt_err_t error code - * @ingroup ADC - */ rt_err_t rt_hw_adc_register(rt_adc_device_t adc,const char *name, const struct rt_adc_ops *ops, const void *user_data); - -/** - * @brief read the adc value - * @param dev adc device - * @param channel adc channel - * @return rt_uint32_t adc value - * @ingroup ADC - */ rt_uint32_t rt_adc_read(rt_adc_device_t dev, rt_int8_t channel); - -/** - * @brief enable the adc channel - * @param dev adc device - * @param channel adc channel - * @return rt_err_t error code - * @ingroup ADC - */ rt_err_t rt_adc_enable(rt_adc_device_t dev, rt_int8_t channel); - -/** - * @brief disable the adc channel - * @param dev adc device - * @param channel adc channel - * @return rt_err_t error code - * @ingroup ADC - */ rt_err_t rt_adc_disable(rt_adc_device_t dev, rt_int8_t channel); - -/** - * @brief get the adc resolution - * @param dev adc device - * @param channel adc channel - * @return rt_int16_t adc resolution - * @ingroup ADC - */ rt_int16_t rt_adc_voltage(rt_adc_device_t dev, rt_int8_t channel); -/*! @}*/ - #endif /* __ADC_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/ahci.h b/rt-thread/components/drivers/include/drivers/ahci.h deleted file mode 100644 index 45e47a8..0000000 --- a/rt-thread/components/drivers/include/drivers/ahci.h +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#ifndef __AHCI_H__ -#define __AHCI_H__ - -#include -#include -#include -#include - -struct rt_ahci_ops; - -/* Generic Host Control */ -#define RT_AHCI_HBA_CAP 0x00 /* Host capability*/ -#define RT_AHCI_CAP_NP RT_GENMASK(4, 0) /* Number of Ports */ -#define RT_AHCI_CAP_NCS RT_GENMASK(8, 12) /* Number of Command Slots */ -#define RT_AHCI_CAP_PSC RT_BIT(13) /* Partial State Capable */ -#define RT_AHCI_CAP_SSC RT_BIT(14) /* Slumber capable */ -#define RT_AHCI_CAP_PMD RT_BIT(15) /* PIO Multiple DRQ Block */ -#define RT_AHCI_CAP_SPM RT_BIT(17) /* Port Multiplier */ -#define RT_AHCI_CAP_AHCI RT_BIT(18) /* AHCI only */ -#define RT_AHCI_CAP_SNZO RT_BIT(19) /* Non-Zero DMA Offsets */ -#define RT_AHCI_CAP_ISS RT_GENMASK(23, 20) /* Interface Speed Support */ -#define RT_AHCI_CAP_CLO RT_BIT(24) /* Command List Override support */ -#define RT_AHCI_CAP_SAL RT_BIT(25) /* Activity LED */ -#define RT_AHCI_CAP_SALP RT_BIT(26) /* Aggressive Link Power Management */ -#define RT_AHCI_CAP_SSS RT_BIT(27) /* Staggered Spin-up */ -#define RT_AHCI_CAP_SIS RT_BIT(28) /* Interlock Switch */ -#define RT_AHCI_CAP_NCQ RT_BIT(30) /* Native Command Queueing */ -#define RT_AHCI_CAP_64 RT_BIT(31) /* PCI DAC (64-bit DMA) support */ -#define RT_AHCI_HBA_GHC 0x04 /* Global host control */ -#define RT_AHCI_GHC_RESET RT_BIT(0) /* Reset controller; self-clear */ -#define RT_AHCI_GHC_IRQ_EN RT_BIT(1) /* Global IRQ enable */ -#define RT_AHCI_GHC_AHCI_EN RT_BIT(31) /* AHCI enabled */ -#define RT_AHCI_HBA_INTS 0x08 /* Interrupt status */ -#define RT_AHCI_HBA_PI 0x0c /* Port implemented */ -#define RT_AHCI_HBA_VS 0x10 /* Version */ -#define RT_AHCI_HBA_CCC_CTL 0x14 /* Command completion coalescing control */ -#define RT_AHCI_HBA_CCC_PTS 0x18 /* Command completion coalescing ports */ -#define RT_AHCI_HBA_EM_LOC 0x1c /* Enclosure management location */ -#define RT_AHCI_HBA_EM_CTL 0x20 /* Enclosure management control */ -#define RT_AHCI_HBA_CAP2 0x24 /* Host capabilities extended */ -#define RT_AHCI_HBA_BOHC 0x28 /* BIOS/OS handoff control and status */ -#define RT_AHCI_HBA_VENDOR 0xa0 /* Vendor specific registers (0xa0 - 0xff) */ - -#define RT_AHCI_PORT_CLB 0x00 /* Command list base address, 1K-byte aligned */ -#define RT_AHCI_PORT_CLBU 0x04 /* Command list base address upper 32 bits */ -#define RT_AHCI_PORT_FB 0x08 /* FIS base address, 256-byte aligned */ -#define RT_AHCI_PORT_FBU 0x0C /* FIS base address upper 32 bits */ -#define RT_AHCI_PORT_INTS 0x10 /* Interrupt status */ -#define RT_AHCI_PORT_INTE 0x14 /* Interrupt enable */ -#define RT_AHCI_PORT_INTE_D2H_REG_FIS RT_BIT(0) /* D2H Register FIS rx'd */ -#define RT_AHCI_PORT_INTE_PIOS_FIS RT_BIT(1) /* PIO Setup FIS rx'd */ -#define RT_AHCI_PORT_INTE_DMAS_FIS RT_BIT(2) /* DMA Setup FIS rx'd */ -#define RT_AHCI_PORT_INTE_SDB_FIS RT_BIT(3) /* Set Device Bits FIS rx'd */ -#define RT_AHCI_PORT_INTE_UNK_FIS RT_BIT(4) /* Unknown FIS rx'd */ -#define RT_AHCI_PORT_INTE_SG_DONE RT_BIT(5) /* Descriptor processed */ -#define RT_AHCI_PORT_INTE_CONNECT RT_BIT(6) /* Port connect change status */ -#define RT_AHCI_PORT_INTE_DMPS RT_BIT(7) /* Mechanical presence status */ -#define RT_AHCI_PORT_INTE_PHYRDY RT_BIT(22) /* PhyRdy changed */ -#define RT_AHCI_PORT_INTE_BAD_PMP RT_BIT(23) /* Incorrect port multiplier */ -#define RT_AHCI_PORT_INTE_OVERFLOW RT_BIT(24) /* Xfer exhausted available S/G */ -#define RT_AHCI_PORT_INTE_IF_NONFATAL RT_BIT(26) /* Interface non-fatal error */ -#define RT_AHCI_PORT_INTE_IF_ERR RT_BIT(27) /* Interface fatal error */ -#define RT_AHCI_PORT_INTE_HBUS_DATA_ERR RT_BIT(28) /* Host bus data error */ -#define RT_AHCI_PORT_INTE_HBUS_ERR RT_BIT(29) /* Host bus fatal error */ -#define RT_AHCI_PORT_INTE_TF_ERR RT_BIT(30) /* Task file error */ -#define RT_AHCI_PORT_INTE_COLD_PRES RT_BIT(31) /* Cold presence detect */ -#define RT_AHCI_PORT_CMD 0x18 /* Command and status */ -#define RT_AHCI_PORT_CMD_START RT_BIT(0) /* Enable port DMA engine */ -#define RT_AHCI_PORT_CMD_SPIN_UP RT_BIT(1) /* Spin up device */ -#define RT_AHCI_PORT_CMD_POWER_ON RT_BIT(2) /* Power up device */ -#define RT_AHCI_PORT_CMD_CLO RT_BIT(3) /* Command list override */ -#define RT_AHCI_PORT_CMD_FIS_RX RT_BIT(4) /* Enable FIS receive DMA engine */ -#define RT_AHCI_PORT_CMD_FIS_ON RT_BIT(14) /* FIS DMA engine running */ -#define RT_AHCI_PORT_CMD_LIST_ON RT_BIT(15) /* cmd list DMA engine running */ -#define RT_AHCI_PORT_CMD_ATAPI RT_BIT(24) /* Device is ATAPI */ -#define RT_AHCI_PORT_CMD_ACTIVE RT_BIT(28) /* Active state */ -#define RT_AHCI_PORT_TFD 0x20 /* Task file data */ -#define RT_AHCI_PORT_TFDATA_ERR RT_BIT(0) /* Indicates an error during the transfer */ -#define RT_AHCI_PORT_TFDATA_DRQ RT_BIT(3) /* Indicates a data transfer is requested */ -#define RT_AHCI_PORT_TFDATA_BSY RT_BIT(7) /* Indicates the interface is busy */ -#define RT_AHCI_PORT_SIG 0x24 /* Signature */ -#define RT_AHCI_PORT_SIG_REG_MASK 0xff -#define RT_AHCI_PORT_SIG_SECTOR_NR_SHIFT 0 /* Sector Count Register */ -#define RT_AHCI_PORT_SIG_LBA_LOW_SHIFT 8 /* LBA Low Register */ -#define RT_AHCI_PORT_SIG_LBA_MID_SHIFT 16 /* LBA Mid Register */ -#define RT_AHCI_PORT_SIG_LBA_HIGH_SHIFT 24 /* LBA High Register */ -#define RT_AHCI_PORT_SIG_SATA_CDROM 0xeb140101 -#define RT_AHCI_PORT_SIG_SATA_DISK 0x00000101 -#define RT_AHCI_PORT_SSTS 0x28 /* SATA status (SCR0:SStatus) */ -#define RT_AHCI_PORT_SSTS_DET_MASK 0x3 -#define RT_AHCI_PORT_SSTS_DET_COMINIT 0x1 -#define RT_AHCI_PORT_SSTS_DET_PHYRDY 0x3 -#define RT_AHCI_PORT_SCTL 0x2c /* SATA control (SCR2:SControl) */ -#define RT_AHCI_PORT_SERR 0x30 /* SATA error (SCR1:SError) */ -#define RT_AHCI_PORT_SERR_ERR_I RT_BIT(0) /* Recovered Data Integrity Error */ -#define RT_AHCI_PORT_SERR_ERR_M RT_BIT(1) /* Recovered Communications Error */ -#define RT_AHCI_PORT_SERR_ERR_T RT_BIT(8) /* Transient Data Integrity Error */ -#define RT_AHCI_PORT_SERR_ERR_C RT_BIT(9) /* Persistent Communication or Data Integrity Error */ -#define RT_AHCI_PORT_SERR_ERR_P RT_BIT(10) /* Protocol Error */ -#define RT_AHCI_PORT_SERR_ERR_E RT_BIT(11) /* Internal Error */ -#define RT_AHCI_PORT_SERR_DIAG_N RT_BIT(16) /* PhyRdy Change */ -#define RT_AHCI_PORT_SERR_DIAG_I RT_BIT(17) /* Phy Internal Error */ -#define RT_AHCI_PORT_SERR_DIAG_W RT_BIT(18) /* Comm Wake */ -#define RT_AHCI_PORT_SERR_DIAG_B RT_BIT(19) /* 10B to 8B Decode Error */ -#define RT_AHCI_PORT_SERR_DIAG_D RT_BIT(20) /* Disparity Error */ -#define RT_AHCI_PORT_SERR_DIAG_C RT_BIT(21) /* CRC Error */ -#define RT_AHCI_PORT_SERR_DIAG_H RT_BIT(22) /* Handshake Error */ -#define RT_AHCI_PORT_SERR_DIAG_S RT_BIT(23) /* Link Sequence Error */ -#define RT_AHCI_PORT_SERR_DIAG_T RT_BIT(24) /* Transport state transition error */ -#define RT_AHCI_PORT_SERR_DIAG_F RT_BIT(25) /* Unknown FIS Type */ -#define RT_AHCI_PORT_SERR_DIAG_X RT_BIT(26) /* Exchanged */ -#define RT_AHCI_PORT_SACT 0x34 /* SATA active (SCR3:SActive) */ -#define RT_AHCI_PORT_CI 0x38 /* Command issue */ -#define RT_AHCI_PORT_SNTF 0x3c /* SATA notification (SCR4:SNotification) */ -#define RT_AHCI_PORT_FBS 0x40 /* FIS-based switch control */ -#define RT_AHCI_PORT_VENDOR 0x70 /* Vendor specific (0x70 - 0x7f) */ - -#define RT_AHCI_MAX_SG 56 -#define RT_AHCI_CMD_SLOT_SIZE 32 -#define RT_AHCI_MAX_CMD_SLOT 32 -#define RT_AHCI_RX_FIS_SIZE 256 -#define RT_AHCI_CMD_TBL_HDR 0x80 -#define RT_AHCI_CMD_TBL_CDB 0x40 -#define RT_AHCI_CMD_TBL_SIZE RT_AHCI_CMD_TBL_HDR + (RT_AHCI_MAX_SG * 16) -#define RT_AHCI_DMA_SIZE (RT_AHCI_CMD_SLOT_SIZE * RT_AHCI_MAX_CMD_SLOT + RT_AHCI_CMD_TBL_SIZE + RT_AHCI_RX_FIS_SIZE) -#define RT_ACHI_PRDT_BYTES_MAX (4 * 1024 * 1024) - -#define RT_AHCI_FIS_TYPE_REG_H2D 0x27 /* Register FIS - host to device */ -#define RT_AHCI_FIS_TYPE_REG_D2H 0x34 /* Register FIS - device to host */ -#define RT_AHCI_FIS_TYPE_DMA_ACT 0x39 /* DMA activate FIS - device to host */ -#define RT_AHCI_FIS_TYPE_DMA_SETUP 0x41 /* DMA setup FIS - bidirectional */ -#define RT_AHCI_FIS_TYPE_DATA 0x46 /* Data FIS - bidirectional */ -#define RT_AHCI_FIS_TYPE_BIST 0x58 /* BIST activate FIS - bidirectional */ -#define RT_AHCI_FIS_TYPE_PIO_SETUP 0x5f /* PIO setup FIS - device to host */ -#define RT_AHCI_FIS_TYPE_DEV_BITS 0xa1 /* Set device bits FIS - device to host */ - -#define RT_AHCI_ATA_ID_WORDS 256 -#define RT_AHCI_ATA_ID_CONFIG 0 -#define RT_AHCI_ATA_ID_CYLS 1 -#define RT_AHCI_ATA_ID_HEADS 3 -#define RT_AHCI_ATA_ID_SECTORS 6 -#define RT_AHCI_ATA_ID_SERNO 10 -#define RT_AHCI_ATA_ID_BUF_SIZE 21 -#define RT_AHCI_ATA_ID_FW_REV 23 -#define RT_AHCI_ATA_ID_PROD 27 -#define RT_AHCI_ATA_ID_MAX_MULTSECT 47 -#define RT_AHCI_ATA_ID_DWORD_IO 48 -#define RT_AHCI_ATA_ID_TRUSTED 48 -#define RT_AHCI_ATA_ID_CAPABILITY 49 -#define RT_AHCI_ATA_ID_OLD_PIO_MODES 51 -#define RT_AHCI_ATA_ID_OLD_DMA_MODES 52 -#define RT_AHCI_ATA_ID_FIELD_VALID 53 -#define RT_AHCI_ATA_ID_CUR_CYLS 54 -#define RT_AHCI_ATA_ID_CUR_HEADS 55 -#define RT_AHCI_ATA_ID_CUR_SECTORS 56 -#define RT_AHCI_ATA_ID_MULTSECT 59 -#define RT_AHCI_ATA_ID_LBA_CAPACITY 60 -#define RT_AHCI_ATA_ID_SWDMA_MODES 62 -#define RT_AHCI_ATA_ID_MWDMA_MODES 63 -#define RT_AHCI_ATA_ID_PIO_MODES 64 -#define RT_AHCI_ATA_ID_EIDE_DMA_MIN 65 -#define RT_AHCI_ATA_ID_EIDE_DMA_TIME 66 -#define RT_AHCI_ATA_ID_EIDE_PIO 67 -#define RT_AHCI_ATA_ID_EIDE_PIO_IORDY 68 -#define RT_AHCI_ATA_ID_ADDITIONAL_SUPP 69 -#define RT_AHCI_ATA_ID_QUEUE_DEPTH 75 -#define RT_AHCI_ATA_ID_SATA_CAPABILITY 76 -#define RT_AHCI_ATA_ID_SATA_CAPABILITY_2 77 -#define RT_AHCI_ATA_ID_FEATURE_SUPP 78 -#define RT_AHCI_ATA_ID_MAJOR_VER 80 -#define RT_AHCI_ATA_ID_COMMAND_SET_1 82 -#define RT_AHCI_ATA_ID_COMMAND_SET_2 83 -#define RT_AHCI_ATA_ID_CFSSE 84 -#define RT_AHCI_ATA_ID_CFS_ENABLE_1 85 -#define RT_AHCI_ATA_ID_CFS_ENABLE_2 86 -#define RT_AHCI_ATA_ID_CSF_DEFAULT 87 -#define RT_AHCI_ATA_ID_UDMA_MODES 88 -#define RT_AHCI_ATA_ID_HW_CONFIG 93 -#define RT_AHCI_ATA_ID_SPG 98 -#define RT_AHCI_ATA_ID_LBA_CAPACITY_2 100 -#define RT_AHCI_ATA_ID_SECTOR_SIZE 106 -#define RT_AHCI_ATA_ID_WWN 108 -#define RT_AHCI_ATA_ID_LOGICAL_SECTOR_SIZE 117 -#define RT_AHCI_ATA_ID_COMMAND_SET_3 119 -#define RT_AHCI_ATA_ID_COMMAND_SET_4 120 -#define RT_AHCI_ATA_ID_LAST_LUN 126 -#define RT_AHCI_ATA_ID_DLF 128 -#define RT_AHCI_ATA_ID_CSFO 129 -#define RT_AHCI_ATA_ID_CFA_POWER 160 -#define RT_AHCI_ATA_ID_CFA_KEY_MGMT 162 -#define RT_AHCI_ATA_ID_CFA_MODES 163 -#define RT_AHCI_ATA_ID_DATA_SET_MGMT 169 -#define RT_AHCI_ATA_ID_SCT_CMD_XPORT 206 -#define RT_AHCI_ATA_ID_ROT_SPEED 217 -#define RT_AHCI_ATA_ID_PIO4 (1 << 1) -#define RT_AHCI_ATA_ID_SERNO_LEN 20 -#define RT_AHCI_ATA_ID_FW_REV_LEN 8 -#define RT_AHCI_ATA_ID_PROD_LEN 40 -#define RT_AHCI_ATA_ID_WWN_LEN 8 - -#define RT_AHCI_ATA_CMD_DSM 0x06 -#define RT_AHCI_ATA_CMD_DEV_RESET 0x08 /* ATAPI device reset */ -#define RT_AHCI_ATA_CMD_PIO_READ 0x20 /* Read sectors with retry */ -#define RT_AHCI_ATA_CMD_PIO_READ_EXT 0x24 -#define RT_AHCI_ATA_CMD_READ_EXT 0x25 -#define RT_AHCI_ATA_CMD_READ_NATIVE_MAX_EXT 0x27 -#define RT_AHCI_ATA_CMD_READ_MULTI_EXT 0x29 -#define RT_AHCI_ATA_CMD_READ_LOG_EXT 0x2f -#define RT_AHCI_ATA_CMD_PIO_WRITE 0x30 /* Write sectors with retry */ -#define RT_AHCI_ATA_CMD_PIO_WRITE_EXT 0x34 -#define RT_AHCI_ATA_CMD_WRITE_EXT 0x35 -#define RT_AHCI_ATA_CMD_SET_MAX_EXT 0x37 -#define RT_AHCI_ATA_CMD_WRITE_MULTI_EXT 0x39 -#define RT_AHCI_ATA_CMD_WRITE_FUA_EXT 0x3d -#define RT_AHCI_ATA_CMD_VERIFY 0x40 /* Read verify sectors with retry */ -#define RT_AHCI_ATA_CMD_VERIFY_EXT 0x42 -#define RT_AHCI_ATA_CMD_FPDMA_READ 0x60 -#define RT_AHCI_ATA_CMD_FPDMA_WRITE 0x61 -#define RT_AHCI_ATA_CMD_EDD 0x90 /* Execute device diagnostic */ -#define RT_AHCI_ATA_CMD_INIT_DEV_PARAMS 0x91 /* Initialize device parameters */ -#define RT_AHCI_ATA_CMD_PACKET 0xa0 /* ATAPI packet */ -#define RT_AHCI_ATA_CMD_ID_ATAPI 0xa1 /* ATAPI identify device */ -#define RT_AHCI_ATA_CMD_CONF_OVERLAY 0xb1 -#define RT_AHCI_ATA_CMD_READ_MULTI 0xc4 /* Read multiple */ -#define RT_AHCI_ATA_CMD_WRITE_MULTI 0xc5 /* Write multiple */ -#define RT_AHCI_ATA_CMD_SET_MULTI 0xc6 /* Set multiple mode */ -#define RT_AHCI_ATA_CMD_READ 0xc8 /* Read DMA with retry */ -#define RT_AHCI_ATA_CMD_WRITE 0xca /* Write DMA with retry */ -#define RT_AHCI_ATA_CMD_WRITE_MULTI_FUA_EXT 0xce -#define RT_AHCI_ATA_CMD_STANDBYNOW1 0xe0 /* Standby immediate */ -#define RT_AHCI_ATA_CMD_IDLEIMMEDIATE 0xe1 /* Idle immediate */ -#define RT_AHCI_ATA_CMD_STANDBY 0xe2 /* Place in standby power mode */ -#define RT_AHCI_ATA_CMD_IDLE 0xe3 /* Place in idle power mode */ -#define RT_AHCI_ATA_CMD_PMP_READ 0xe4 /* Read buffer */ -#define RT_AHCI_ATA_CMD_CHK_POWER 0xe5 /* Check power mode */ -#define RT_AHCI_ATA_CMD_SLEEP 0xe6 /* Sleep */ -#define RT_AHCI_ATA_CMD_FLUSH 0xe7 -#define RT_AHCI_ATA_CMD_PMP_WRITE 0xe8 /* Write buffer */ -#define RT_AHCI_ATA_CMD_FLUSH_EXT 0xea -#define RT_AHCI_ATA_CMD_ID_ATA 0xec /* Identify device */ -#define RT_AHCI_ATA_CMD_SET_FEATURES 0xef /* Set features */ -#define RT_AHCI_ATA_CMD_SEC_FREEZE_LOCK 0xf5 /* Security freeze */ -#define RT_AHCI_ATA_CMD_READ_NATIVE_MAX 0xf8 -#define RT_AHCI_ATA_CMD_SET_MAX 0xf9 - -#define RT_AHCI_ATA_DSM_TRIM 0x01 - -#define RT_AHCI_ATA_PROT_FLAG_PIO RT_BIT(0) -#define RT_AHCI_ATA_PROT_FLAG_DMA RT_BIT(1) -#define RT_AHCI_ATA_PROT_FLAG_NCQ RT_BIT(2) -#define RT_AHCI_ATA_PROT_FLAG_ATAPI RT_BIT(3) - -#define rt_ahci_ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0) -#define rt_ahci_ata_id_has_lba(id) ((id)[49] & (1 << 9)) -#define rt_ahci_ata_id_has_dma(id) ((id)[49] & (1 << 8)) -#define rt_ahci_ata_id_has_ncq(id) ((id)[76] & (1 << 8)) -#define rt_ahci_ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1) -#define rt_ahci_ata_id_removeable(id) ((id)[0] & (1 << 7)) -#define rt_ahci_ata_id_iordy_disable(id) ((id)[49] & (1 << 10)) -#define rt_ahci_ata_id_has_iordy(id) ((id)[49] & (1 << 11)) - -#define rt_ahci_ata_id_u32(id, n) (((rt_uint32_t)(id)[(n) + 1] << 16) | ((rt_uint32_t) (id)[(n)])) -#define rt_ahci_ata_id_u64(id, n) (((rt_uint64_t)(id)[(n) + 3] << 48) | ((rt_uint64_t)(id)[(n) + 2] << 32) | \ - ((rt_uint64_t)(id)[(n) + 1] << 16) | ((rt_uint64_t)(id)[(n) + 0]) ) - -rt_inline rt_bool_t rt_ahci_ata_id_has_lba48(const rt_uint16_t *id) -{ - if ((id[RT_AHCI_ATA_ID_COMMAND_SET_2] & 0xc000) != 0x4000 || - !rt_ahci_ata_id_u64(id, RT_AHCI_ATA_ID_LBA_CAPACITY_2)) - { - return 0; - } - - return !!(id[RT_AHCI_ATA_ID_COMMAND_SET_2] & (1 << 10)); -} - -rt_inline rt_uint64_t rt_ahci_ata_id_n_sectors(rt_uint16_t *id) -{ - if (rt_ahci_ata_id_has_lba(id)) - { - if (rt_ahci_ata_id_has_lba48(id)) - { - return rt_ahci_ata_id_u64(id, RT_AHCI_ATA_ID_LBA_CAPACITY_2); - } - - return rt_ahci_ata_id_u32(id, RT_AHCI_ATA_ID_LBA_CAPACITY); - } - - return 0; -} - -rt_inline rt_bool_t rt_ahci_ata_id_wcache_enabled(const rt_uint16_t *id) -{ - if ((id[RT_AHCI_ATA_ID_CSF_DEFAULT] & 0xc000) != 0x4000) - { - return RT_FALSE; - } - return id[RT_AHCI_ATA_ID_CFS_ENABLE_1] & (1 << 5); -} - -rt_inline rt_bool_t rt_ahci_ata_id_has_flush(const rt_uint16_t *id) -{ - if ((id[RT_AHCI_ATA_ID_COMMAND_SET_2] & 0xc000) != 0x4000) - { - return RT_FALSE; - } - return id[RT_AHCI_ATA_ID_COMMAND_SET_2] & (1 << 12); -} - -rt_inline rt_bool_t rt_ahci_ata_id_has_flush_ext(const rt_uint16_t *id) -{ - if ((id[RT_AHCI_ATA_ID_COMMAND_SET_2] & 0xc000) != 0x4000) - { - return RT_FALSE; - } - return id[RT_AHCI_ATA_ID_COMMAND_SET_2] & (1 << 13); -} - -struct rt_ahci_cmd_hdr -{ - rt_uint32_t opts; - rt_uint32_t status; - rt_uint32_t tbl_addr_lo; - rt_uint32_t tbl_addr_hi; - rt_uint32_t reserved[4]; -}; - -struct rt_ahci_sg -{ - rt_uint32_t addr_lo; - rt_uint32_t addr_hi; - rt_uint32_t reserved; - rt_uint32_t flags_size; -}; - -struct rt_ahci_port -{ - void *regs; - - void *dma; - rt_ubase_t dma_handle; - - struct rt_ahci_cmd_hdr *cmd_slot; - struct rt_ahci_sg *cmd_tbl_sg; - void *cmd_tbl; - rt_ubase_t cmd_tbl_dma; - void *rx_fis; - - rt_uint32_t int_enabled; - rt_size_t block_size; - - rt_uint16_t *ataid; - - rt_bool_t link; - struct rt_completion done; -}; - -struct rt_ahci_host -{ - struct rt_scsi_host parent; - - int irq; - void *regs; - - rt_size_t ports_nr; - rt_uint32_t ports_map; - struct rt_ahci_port ports[32]; - - rt_uint32_t cap; - rt_uint32_t max_blocks; - - const struct rt_ahci_ops *ops; -}; - -struct rt_ahci_ops -{ - rt_err_t (*host_init)(struct rt_ahci_host *host); - rt_err_t (*port_init)(struct rt_ahci_host *host, struct rt_ahci_port *port); - rt_err_t (*port_link_up)(struct rt_ahci_host *host, struct rt_ahci_port *port); - rt_err_t (*port_dma_init)(struct rt_ahci_host *host, struct rt_ahci_port *port); - rt_err_t (*port_isr)(struct rt_ahci_host *host, struct rt_ahci_port *port, rt_uint32_t isr); -}; - -rt_err_t rt_ahci_host_register(struct rt_ahci_host *host); -rt_err_t rt_ahci_host_unregister(struct rt_ahci_host *host); - -#endif /* __AHCI_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/blk.h b/rt-thread/components/drivers/include/drivers/blk.h deleted file mode 100644 index 42159c4..0000000 --- a/rt-thread/components/drivers/include/drivers/blk.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI first version - */ - -#ifndef __BLK_H__ -#define __BLK_H__ - -#include -#include -#include - -struct rt_dm_ida; -struct rt_blk_device; -struct rt_blk_disk_ops; - -struct rt_blk_disk -{ - struct rt_device parent; - - const struct rt_blk_disk_ops *ops; -#ifdef RT_USING_DM - struct rt_dm_ida *ida; -#endif - - rt_uint32_t read_only:1; - rt_uint32_t parallel_io:1; - rt_uint32_t removable:1; -#define RT_BLK_DISK_MAGIC 0xbdaabdaa - rt_uint32_t __magic; - - rt_uint32_t partitions; -#define RT_BLK_PARTITION_NONE (-1) -#define RT_BLK_PARTITION_MAX (RT_UINT32_MAX >> 1) - rt_int32_t max_partitions; - rt_list_t part_nodes; - - struct rt_spinlock lock; - struct rt_semaphore usr_lock; -}; - -struct rt_blk_disk_ops -{ - rt_ssize_t (*read)(struct rt_blk_disk *disk, rt_off_t sector, void *buffer, - rt_size_t sector_count); - rt_ssize_t (*write)(struct rt_blk_disk *disk, rt_off_t sector, const void *buffer, - rt_size_t sector_count); - rt_err_t (*getgeome)(struct rt_blk_disk *disk, struct rt_device_blk_geometry *geometry); - rt_err_t (*sync)(struct rt_blk_disk *disk); - rt_err_t (*erase)(struct rt_blk_disk *disk); - rt_err_t (*autorefresh)(struct rt_blk_disk *disk, rt_bool_t is_auto); - rt_err_t (*control)(struct rt_blk_disk *disk, struct rt_blk_device *blk, int cmd, void *args); -}; - -#ifndef __DFS_H__ -#include - -struct rt_blk_device -{ - struct rt_device parent; - - int partno; - struct dfs_partition partition; - - rt_list_t list; - struct rt_blk_disk *disk; - - rt_size_t sector_start; - rt_size_t sector_count; -}; -#else -struct rt_blk_device; -#endif /* __DFS_H__ */ - -rt_err_t rt_hw_blk_disk_register(struct rt_blk_disk *disk); -rt_err_t rt_hw_blk_disk_unregister(struct rt_blk_disk *disk); - -rt_err_t rt_blk_disk_probe_partition(struct rt_blk_disk *disk); -rt_ssize_t rt_blk_disk_get_capacity(struct rt_blk_disk *disk); -rt_ssize_t rt_blk_disk_get_logical_block_size(struct rt_blk_disk *disk); - -#endif /* __BLK_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/clk.h b/rt-thread/components/drivers/include/drivers/clk.h index 97491bf..83662d7 100644 --- a/rt-thread/components/drivers/include/drivers/clk.h +++ b/rt-thread/components/drivers/include/drivers/clk.h @@ -16,8 +16,6 @@ #include #include -#define RT_CLK_NODE_OBJ_NAME "CLKNP" - struct rt_clk_ops; struct rt_reset_control_node; @@ -39,8 +37,6 @@ struct rt_clk_node * }; * We assume the 'N' is the max value of element in 'clock-indices' if OFW. */ - struct rt_object rt_parent; - rt_list_t list; rt_list_t children_nodes; @@ -78,8 +74,6 @@ struct rt_clk const char *con_id; rt_ubase_t rate; - int prepare_count; - int enable_count; void *fw_node; void *priv; diff --git a/rt-thread/components/drivers/include/drivers/core/dm.h b/rt-thread/components/drivers/include/drivers/core/dm.h index 1a3723a..94821fe 100644 --- a/rt-thread/components/drivers/include/drivers/core/dm.h +++ b/rt-thread/components/drivers/include/drivers/core/dm.h @@ -13,11 +13,9 @@ #include #include -#include #include #include #include -#include #ifndef RT_CPUS_NR #define RT_CPUS_NR 1 @@ -29,24 +27,6 @@ extern int rt_hw_cpu_id(void); void rt_dm_secondary_cpu_init(void); -/* ID Allocation */ -struct rt_dm_ida -{ - rt_uint8_t master_id; - -#define RT_DM_IDA_NUM 256 - RT_BITMAP_DECLARE(map, RT_DM_IDA_NUM); - struct rt_spinlock lock; -}; - -#define RT_DM_IDA_INIT(id) { .master_id = MASTER_ID_##id } - -int rt_dm_ida_alloc(struct rt_dm_ida *ida); -rt_bool_t rt_dm_ida_take(struct rt_dm_ida *ida, int id); -void rt_dm_ida_free(struct rt_dm_ida *ida, int id); - -rt_device_t rt_dm_device_find(int master_id, int device_id); - int rt_dm_dev_set_name_auto(rt_device_t dev, const char *prefix); int rt_dm_dev_get_name_id(rt_device_t dev); diff --git a/rt-thread/components/drivers/include/drivers/core/master_id.h b/rt-thread/components/drivers/include/drivers/core/master_id.h deleted file mode 100644 index 90f2699..0000000 --- a/rt-thread/components/drivers/include/drivers/core/master_id.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-04-20 GuEe-GUI the first version - */ - -#ifndef __RT_DM_MASTER_ID_H__ -#define __RT_DM_MASTER_ID_H__ - -#define MASTER_ID_CUSTOM 0 - -/* Block */ -#define MASTER_ID_NVME 1 -#define MASTER_ID_SCSI_SD 2 -#define MASTER_ID_SCSI_CDROM 3 -#define MASTER_ID_SDIO 4 -#define MASTER_ID_VIRTUAL_BLOCK 5 - -/* Char */ -#define MASTER_ID_RPMSG_EPT 11 -#define MASTER_ID_RPMSG_CHAR 12 -#define MASTER_ID_SERIAL 13 - -/* Clock Timer */ -#define MASTER_ID_HWTIMER 21 -#define MASTER_ID_PTP 22 -#define MASTER_ID_RTC 23 - -/* Graphic Display */ -#define MASTER_ID_GRAPHIC_BACKLIGHT 31 -#define MASTER_ID_GRAPHIC_FRAMEBUFFER 32 -#define MASTER_ID_LED 33 - -/* Hardware Monitor */ -#define MASTER_ID_DVFS 41 -#define MASTER_ID_SENSOR 42 -#define MASTER_ID_THERMAL 43 -#define MASTER_ID_WATCHDOG 44 - -/* I2C */ -#define MASTER_ID_I2C_BUS 51 -#define MASTER_ID_I2C_DEV 52 - -/* IO Contorl */ -#define MASTER_ID_ADC 61 -#define MASTER_ID_DAC 62 -#define MASTER_ID_PIN 63 -#define MASTER_ID_PWM 64 - -/* Memory */ -#define MASTER_ID_MEM 71 -#define MASTER_ID_MTD 72 - -/* MISC */ -#define MASTER_ID_MISC 81 - -/* Multimedia */ -#define MASTER_ID_AUDIO 91 - -/* Net */ -#define MASTER_ID_CAN 101 -#define MASTER_ID_ETH 102 -#define MASTER_ID_PHY 103 -#define MASTER_ID_WLAN 104 - -/* Input */ -#define MASTER_ID_INPUT 111 -#define MASTER_ID_TOUCH 112 - -/* Security */ -#define MASTER_ID_HWCRYPTO 121 -#define MASTER_ID_RNG 122 -#define MASTER_ID_TEE 123 - -/* SPI */ -#define MASTER_ID_SPI_BUS 131 -#define MASTER_ID_SPI_DEV 132 - -/* TTY */ -#define MASTER_ID_TTY 141 -#define MASTER_ID_TTY_SLAVES 142 -#define MASTER_ID_TTY_ALTERNATE 143 -#define MASTER_ID_PTMX 144 - -/* USB */ -#define MASTER_ID_USB_DEV 151 -#define MASTER_ID_USB_BUS 152 -#define MASTER_ID_USB_OTG 153 - -#endif /* __RT_DM_MASTER_ID_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/cputime.h b/rt-thread/components/drivers/include/drivers/cputime.h index 478ccfd..3b1eb2a 100644 --- a/rt-thread/components/drivers/include/drivers/cputime.h +++ b/rt-thread/components/drivers/include/drivers/cputime.h @@ -31,8 +31,4 @@ uint64_t clock_cpu_millisecond(uint64_t cpu_tick); int clock_cpu_setops(const struct rt_clock_cputime_ops *ops); -#ifdef RT_USING_CPUTIME_RISCV -int riscv_cputime_init(void); -#endif /* RT_USING_CPUTIME_RISCV */ - #endif diff --git a/rt-thread/components/drivers/include/drivers/dac.h b/rt-thread/components/drivers/include/drivers/dac.h index b1360c3..c03fa10 100644 --- a/rt-thread/components/drivers/include/drivers/dac.h +++ b/rt-thread/components/drivers/include/drivers/dac.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -11,66 +11,8 @@ #ifndef __DAC_H__ #define __DAC_H__ #include -/** - * @addtogroup Drivers RTTHREAD Driver - * @defgroup DAC DAC - * - * @brief DAC driver api - * - * Example - * @code {.c} - * - * #include - * #include - * #include - * #define DAC_DEV_NAME "dac1" - * #define DAC_DEV_CHANNEL 1 - * #define REFER_VOLTAGE 330 - * #define CONVERT_BITS (1 << 12) - * - * static int dac_vol_sample(int argc, char *argv[]) - * { - * rt_dac_device_t dac_dev; - * rt_uint32_t value, vol; - * rt_err_t ret = RT_EOK; - * - * dac_dev = (rt_dac_device_t)rt_device_find(DAC_DEV_NAME); - * if (dac_dev == RT_NULL) - * { - * rt_kprintf("dac sample run failed! can't find %s device!\n", DAC_DEV_NAME); - * return -RT_ERROR; - * } - * - * ret = rt_dac_enable(dac_dev, DAC_DEV_CHANNEL); - * - * value = atoi(argv[1]); - * rt_dac_write(dac_dev, DAC_DEV_NAME, DAC_DEV_CHANNEL, value); - * rt_kprintf("the value is :%d \n", value); - * - * vol = value * REFER_VOLTAGE / CONVERT_BITS; - * rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100); - * - * rt_thread_mdelay(500); - * - * ret = rt_dac_disable(dac_dev, DAC_DEV_CHANNEL); - * - * return ret; - * } - * MSH_CMD_EXPORT(dac_vol_sample, dac voltage convert sample); - * - * @endcode - * - * @ingroup Drivers - */ -/*! - * @addtogroup DAC - * @{ - */ struct rt_dac_device; -/** - * @brief Configuration of DAC device - */ struct rt_dac_ops { rt_err_t (*disabled)(struct rt_dac_device *device, rt_uint32_t channel); @@ -78,10 +20,7 @@ struct rt_dac_ops rt_err_t (*convert)(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value); rt_uint8_t (*get_resolution)(struct rt_dac_device *device); }; -/** - * @brief DAC device structure - * - */ + struct rt_dac_device { struct rt_device parent; @@ -96,41 +35,10 @@ typedef enum RT_DAC_CMD_GET_RESOLUTION = RT_DEVICE_CTRL_BASE(DAC) + 2, } rt_dac_cmd_t; -/** - * @brief Register a DAC device - * @param dac DAC device - * @param name DAC name - * @param ops the operations of DAC device - * @param user_data device private data - * @return rt_err_t error code - */ rt_err_t rt_hw_dac_register(rt_dac_device_t dac,const char *name, const struct rt_dac_ops *ops, const void *user_data); -/** - * @brief set the value of DAC - * @param dev DAC device - * @param channel DAC channel - * @param value the value of DAC - * @return rt_err_t error code - */ rt_err_t rt_dac_write(rt_dac_device_t dev, rt_uint32_t channel, rt_uint32_t value); - -/** - * @brief enable the DAC channel - * @param dev DAC device - * @param channel DAC channel - * @return rt_err_t error code - */ rt_err_t rt_dac_enable(rt_dac_device_t dev, rt_uint32_t channel); - -/** - * @brief disable the DAC channel - * @param dev DAC device - * @param channel DAC channel - * @return rt_err_t error code - */ rt_err_t rt_dac_disable(rt_dac_device_t dev, rt_uint32_t channel); -/*! @}*/ - #endif /* __dac_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/dev_alarm.h b/rt-thread/components/drivers/include/drivers/dev_alarm.h deleted file mode 100644 index 4553569..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_alarm.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-10-27 heyuanjie87 first version. - * 2013-05-17 aozima initial alarm event & mutex in system init. - * 2020-10-15 zhangsz add alarm flags hour minute second. - */ - -#ifndef __DEV_ALARM_H__ -#define __DEV_ALARM_H__ - -#include -#include - -#define RT_ALARM_TM_NOW -1 /* set the alarm tm_day,tm_mon,tm_sec,etc. - to now.we also call it "don't care" value */ - -/* alarm flags */ -#define RT_ALARM_ONESHOT 0x000 /* only alarm once */ -#define RT_ALARM_DAILY 0x100 /* alarm everyday */ -#define RT_ALARM_WEEKLY 0x200 /* alarm weekly at Monday or Friday etc. */ -#define RT_ALARM_MONTHLY 0x400 /* alarm monthly at someday */ -#define RT_ALARM_YAERLY 0x800 /* alarm yearly at a certain date */ -#define RT_ALARM_HOUR 0x1000 /* alarm each hour at a certain min:second */ -#define RT_ALARM_MINUTE 0x2000 /* alarm each minute at a certain second */ -#define RT_ALARM_SECOND 0x4000 /* alarm each second */ - -#define RT_ALARM_STATE_INITED 0x02 -#define RT_ALARM_STATE_START 0x01 -#define RT_ALARM_STATE_STOP 0x00 - -/* alarm control cmd */ -#define RT_ALARM_CTRL_MODIFY 1 /* modify alarm time or alarm flag */ - -typedef struct rt_alarm *rt_alarm_t; -typedef void (*rt_alarm_callback_t)(rt_alarm_t alarm, time_t timestamp); - -struct rt_alarm -{ - rt_list_t list; - rt_uint32_t flag; - rt_alarm_callback_t callback; - struct tm wktime; - - void *user_data; -}; - -struct rt_alarm_setup -{ - rt_uint32_t flag; /* alarm flag */ - struct tm wktime; /* when will the alarm wake up user */ -}; - -struct rt_alarm_container -{ - rt_list_t head; - struct rt_mutex mutex; - struct rt_event event; - struct rt_alarm *current; -}; - -rt_alarm_t rt_alarm_create(rt_alarm_callback_t callback, - struct rt_alarm_setup *setup); -rt_err_t rt_alarm_control(rt_alarm_t alarm, int cmd, void *arg); -void rt_alarm_update(rt_device_t dev, rt_uint32_t event); -rt_err_t rt_alarm_delete(rt_alarm_t alarm); -rt_err_t rt_alarm_start(rt_alarm_t alarm); -rt_err_t rt_alarm_stop(rt_alarm_t alarm); -int rt_alarm_system_init(void); - -#endif /* __DEV_ALARM_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/dev_audio.h b/rt-thread/components/drivers/include/drivers/dev_audio.h deleted file mode 100644 index ef92a93..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_audio.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2017-05-09 Urey first version - * 2019-07-09 Zero-Free improve device ops interface and data flows - * - */ - -#ifndef __DEV_AUDIO_H__ -#define __DEV_AUDIO_H__ - -#include "dev_audio_pipe.h" - -/* AUDIO command */ -#define _AUDIO_CTL(a) (RT_DEVICE_CTRL_BASE(Sound) + a) - -#define AUDIO_CTL_GETCAPS _AUDIO_CTL(1) -#define AUDIO_CTL_CONFIGURE _AUDIO_CTL(2) -#define AUDIO_CTL_START _AUDIO_CTL(3) -#define AUDIO_CTL_STOP _AUDIO_CTL(4) -#define AUDIO_CTL_GETBUFFERINFO _AUDIO_CTL(5) - -/* Audio Device Types */ -#define AUDIO_TYPE_QUERY 0x00 -#define AUDIO_TYPE_INPUT 0x01 -#define AUDIO_TYPE_OUTPUT 0x02 -#define AUDIO_TYPE_MIXER 0x04 - -/* Supported Sampling Rates */ -#define AUDIO_SAMP_RATE_8K 0x0001 -#define AUDIO_SAMP_RATE_11K 0x0002 -#define AUDIO_SAMP_RATE_16K 0x0004 -#define AUDIO_SAMP_RATE_22K 0x0008 -#define AUDIO_SAMP_RATE_32K 0x0010 -#define AUDIO_SAMP_RATE_44K 0x0020 -#define AUDIO_SAMP_RATE_48K 0x0040 -#define AUDIO_SAMP_RATE_96K 0x0080 -#define AUDIO_SAMP_RATE_128K 0x0100 -#define AUDIO_SAMP_RATE_160K 0x0200 -#define AUDIO_SAMP_RATE_172K 0x0400 -#define AUDIO_SAMP_RATE_192K 0x0800 - -/* Supported Bit Rates */ -#define AUDIO_BIT_RATE_22K 0x01 -#define AUDIO_BIT_RATE_44K 0x02 -#define AUDIO_BIT_RATE_48K 0x04 -#define AUDIO_BIT_RATE_96K 0x08 -#define AUDIO_BIT_RATE_128K 0x10 -#define AUDIO_BIT_RATE_160K 0x20 -#define AUDIO_BIT_RATE_172K 0x40 -#define AUDIO_BIT_RATE_192K 0x80 - -/* Support Dsp(input/output) Units controls */ -#define AUDIO_DSP_PARAM 0 /* get/set all params */ -#define AUDIO_DSP_SAMPLERATE 1 /* samplerate */ -#define AUDIO_DSP_CHANNELS 2 /* channels */ -#define AUDIO_DSP_SAMPLEBITS 3 /* sample bits width */ - -/* Supported Mixer Units controls */ -#define AUDIO_MIXER_QUERY 0x0000 -#define AUDIO_MIXER_MUTE 0x0001 -#define AUDIO_MIXER_VOLUME 0x0002 -#define AUDIO_MIXER_BASS 0x0004 -#define AUDIO_MIXER_MID 0x0008 -#define AUDIO_MIXER_TREBLE 0x0010 -#define AUDIO_MIXER_EQUALIZER 0x0020 -#define AUDIO_MIXER_LINE 0x0040 -#define AUDIO_MIXER_DIGITAL 0x0080 -#define AUDIO_MIXER_MIC 0x0100 -#define AUDIO_MIXER_VITURAL 0x0200 -#define AUDIO_MIXER_EXTEND 0x8000 /* extend mixer command */ - -#define AUDIO_VOLUME_MAX (100) -#define AUDIO_VOLUME_MIN (0) - -#define CFG_AUDIO_REPLAY_QUEUE_COUNT 4 - -enum -{ - AUDIO_STREAM_REPLAY = 0, - AUDIO_STREAM_RECORD, - AUDIO_STREAM_LAST = AUDIO_STREAM_RECORD, -}; - -/* the preferred number and size of audio pipeline buffer for the audio device */ -struct rt_audio_buf_info -{ - rt_uint8_t *buffer; - rt_uint16_t block_size; - rt_uint16_t block_count; - rt_uint32_t total_size; -}; - -struct rt_audio_device; -struct rt_audio_caps; -struct rt_audio_configure; -struct rt_audio_ops -{ - rt_err_t (*getcaps)(struct rt_audio_device *audio, struct rt_audio_caps *caps); - rt_err_t (*configure)(struct rt_audio_device *audio, struct rt_audio_caps *caps); - rt_err_t (*init)(struct rt_audio_device *audio); - rt_err_t (*start)(struct rt_audio_device *audio, int stream); - rt_err_t (*stop)(struct rt_audio_device *audio, int stream); - rt_ssize_t (*transmit)(struct rt_audio_device *audio, const void *writeBuf, void *readBuf, rt_size_t size); - /* get page size of codec or private buffer's info */ - void (*buffer_info)(struct rt_audio_device *audio, struct rt_audio_buf_info *info); -}; - -struct rt_audio_configure -{ - rt_uint32_t samplerate; - rt_uint16_t channels; - rt_uint16_t samplebits; -}; - -struct rt_audio_caps -{ - int main_type; - int sub_type; - - union - { - rt_uint32_t mask; - int value; - struct rt_audio_configure config; - } udata; -}; - -struct rt_audio_replay -{ - struct rt_mempool *mp; - struct rt_data_queue queue; - struct rt_mutex lock; - struct rt_completion cmp; - struct rt_audio_buf_info buf_info; - rt_uint8_t *write_data; - rt_uint16_t write_index; - rt_uint16_t read_index; - rt_uint32_t pos; - rt_uint8_t event; - rt_bool_t activated; -}; - -struct rt_audio_record -{ - struct rt_audio_pipe pipe; - rt_bool_t activated; -}; - -struct rt_audio_device -{ - struct rt_device parent; - struct rt_audio_ops *ops; - struct rt_audio_replay *replay; - struct rt_audio_record *record; -}; - -rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data); -void rt_audio_tx_complete(struct rt_audio_device *audio); -void rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t len); - -/* Device Control Commands */ -#define CODEC_CMD_RESET 0 -#define CODEC_CMD_SET_VOLUME 1 -#define CODEC_CMD_GET_VOLUME 2 -#define CODEC_CMD_SAMPLERATE 3 -#define CODEC_CMD_EQ 4 -#define CODEC_CMD_3D 5 - -#define CODEC_VOLUME_MAX (63) - -#endif /* __DEV_AUDIO_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/dev_can.h b/rt-thread/components/drivers/include/drivers/dev_can.h deleted file mode 100644 index aed78b2..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_can.h +++ /dev/null @@ -1,547 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2015-05-14 aubrcool@qq.com first version - * 2015-07-06 Bernard remove RT_CAN_USING_LED. - * 2022-05-08 hpmicro add CANFD support, fixed typos - */ - -#ifndef __DEV_CAN_H_ -#define __DEV_CAN_H_ - -#include - -#ifndef RT_CANMSG_BOX_SZ -#define RT_CANMSG_BOX_SZ 16 -#endif -#ifndef RT_CANSND_BOX_NUM -#define RT_CANSND_BOX_NUM 1 -#endif - -enum CAN_DLC -{ - CAN_MSG_0BYTE = 0, - CAN_MSG_1BYTE, - CAN_MSG_2BYTES, - CAN_MSG_3BYTES, - CAN_MSG_4BYTES, - CAN_MSG_5BYTES, - CAN_MSG_6BYTES, - CAN_MSG_7BYTES, - CAN_MSG_8BYTES, - CAN_MSG_12BYTES, - CAN_MSG_16BYTES, - CAN_MSG_20BYTES, - CAN_MSG_24BYTES, - CAN_MSG_32BYTES, - CAN_MSG_48BYTES, - CAN_MSG_64BYTES, -}; - -enum CANBAUD -{ - CAN1MBaud = 1000UL * 1000,/* 1 MBit/sec */ - CAN800kBaud = 1000UL * 800, /* 800 kBit/sec */ - CAN500kBaud = 1000UL * 500, /* 500 kBit/sec */ - CAN250kBaud = 1000UL * 250, /* 250 kBit/sec */ - CAN125kBaud = 1000UL * 125, /* 125 kBit/sec */ - CAN100kBaud = 1000UL * 100, /* 100 kBit/sec */ - CAN50kBaud = 1000UL * 50, /* 50 kBit/sec */ - CAN20kBaud = 1000UL * 20, /* 20 kBit/sec */ - CAN10kBaud = 1000UL * 10 /* 10 kBit/sec */ -}; - -#define RT_CAN_MODE_NORMAL 0 -#define RT_CAN_MODE_LISTEN 1 -#define RT_CAN_MODE_LOOPBACK 2 -#define RT_CAN_MODE_LOOPBACKANLISTEN 3 - -#define RT_CAN_MODE_PRIV 0x01 -#define RT_CAN_MODE_NOPRIV 0x00 - -/** - * @addtogroup Drivers RTTHREAD Driver - * @defgroup CAN_Device CAN Driver - * - * @brief CAN driver api - * - * Example - * @code {.c} - * #include - * #include "rtdevice.h" - * - * #define CAN_DEV_NAME "can1" // CAN 设备名称 - * - * static struct rt_semaphore rx_sem; // 用于接收消息的信号量 - * static rt_device_t can_dev; // CAN 设备句柄 - * - * // 接收数据回调函数 - * static rt_err_t can_rx_call(rt_device_t dev, rt_size_t size) - * { - * // CAN 接收到数据后产生中断,调用此回调函数,然后发送接收信号量 - * rt_sem_release(&rx_sem); - * - * return RT_EOK; - * } - * - * static void can_rx_thread(void *parameter) - * { - * int i; - * rt_err_t res; - * struct rt_can_msg rxmsg = {0}; - * - * // 设置接收回调函数 - * rt_device_set_rx_indicate(can_dev, can_rx_call); - * - * #ifdef RT_CAN_USING_HDR - * struct rt_can_filter_item items[5] = - * { - * RT_CAN_FILTER_ITEM_INIT(0x100, 0, 0, 0, 0x700, RT_NULL, RT_NULL), // std,match ID:0x100~0x1ff,hdr 为 - 1,设置默认过滤表 - * RT_CAN_FILTER_ITEM_INIT(0x300, 0, 0, 0, 0x700, RT_NULL, RT_NULL), // std,match ID:0x300~0x3ff,hdr 为 - 1 - * RT_CAN_FILTER_ITEM_INIT(0x211, 0, 0, 0, 0x7ff, RT_NULL, RT_NULL), // std,match ID:0x211,hdr 为 - 1 - * RT_CAN_FILTER_STD_INIT(0x486, RT_NULL, RT_NULL), // std,match ID:0x486,hdr 为 - 1 - * {0x555, 0, 0, 0, 0x7ff, 7,} // std,match ID:0x555,hdr 为 7,指定设置 7 号过滤表 - * }; - * struct rt_can_filter_config cfg = {5, 1, items}; // 一共有 5 个过滤表 - * // 设置硬件过滤表 - * res = rt_device_control(can_dev, RT_CAN_CMD_SET_FILTER, &cfg); - * RT_ASSERT(res == RT_EOK); - * #endif - * res = RT_TRUE; - * res = rt_device_control(can_dev, RT_CAN_CMD_START, &res); - * while (1) - * { - * // hdr 值为 - 1,表示直接从 uselist 链表读取数据 - * rxmsg.hdr = -1; - * // 阻塞等待接收信号量 - * rt_sem_take(&rx_sem, RT_WAITING_FOREVER); - * // 从 CAN 读取一帧数据 - * rt_device_read(can_dev, 0, &rxmsg, sizeof(rxmsg)); - * // 打印数据 ID 及内容 - * rt_kprintf("ID:%x", rxmsg.id); - * for (i = 0; i < 8; i++) - * { - * rt_kprintf("%2x", rxmsg.data[i]); - * } - * - * rt_kprintf("\n"); - * } - * } - * - * int can_sample(int argc, char *argv[]) - * { - * struct rt_can_msg msg = {0}; - * rt_err_t res; - * rt_size_t size; - * rt_thread_t thread; - * char can_name[RT_NAME_MAX]; - * - * if (argc == 2) - * { - * rt_strncpy(can_name, argv[1], RT_NAME_MAX); - * } - * else - * { - * rt_strncpy(can_name, CAN_DEV_NAME, RT_NAME_MAX); - * } - * // 查找 CAN 设备 - * can_dev = rt_device_find(can_name); - * if (!can_dev) - * { - * rt_kprintf("find %s failed!\n", can_name); - * return -RT_ERROR; - * } - * - * // 初始化 CAN 接收信号量 - * rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); - * - * // 以中断接收及发送方式打开 CAN 设备 - * res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX); - * RT_ASSERT(res == RT_EOK); - * // 创建数据接收线程 - * thread = rt_thread_create("can_rx", can_rx_thread, RT_NULL, 1024, 25, 10); - * if (thread != RT_NULL) - * { - * rt_thread_startup(thread); - * } - * else - * { - * rt_kprintf("create can_rx thread failed!\n"); - * } - * - * msg.id = 0x78; // ID 为 0x78 - * msg.ide = RT_CAN_STDID; // 标准格式 - * msg.rtr = RT_CAN_DTR; // 数据帧 - * msg.len = 8; // 数据长度为 8 - * // 待发送的 8 字节数据 - * msg.data[0] = 0x00; - * msg.data[1] = 0x11; - * msg.data[2] = 0x22; - * msg.data[3] = 0x33; - * msg.data[4] = 0x44; - * msg.data[5] = 0x55; - * msg.data[6] = 0x66; - * msg.data[7] = 0x77; - * // 发送一帧 CAN 数据 - * size = rt_device_write(can_dev, 0, &msg, sizeof(msg)); - * if (size == 0) - * { - * rt_kprintf("can dev write data failed!\n"); - * } - * - * return res; - * } - * // 导出到 msh 命令列表中 - * MSH_CMD_EXPORT(can_sample, can device sample); - * @endcode - * - * @ingroup Drivers - * - */ - - -/*! - * @addtogroup CAN_Device - * @{ - */ -#define CAN_RX_FIFO0 (0x00000000U) /*!< CAN receive FIFO 0 */ -#define CAN_RX_FIFO1 (0x00000001U) /*!< CAN receive FIFO 1 */ - -/** - * @brief CAN filter item - */ -struct rt_can_filter_item -{ - rt_uint32_t id : 29; - rt_uint32_t ide : 1; - rt_uint32_t rtr : 1; - rt_uint32_t mode : 1; - rt_uint32_t mask; - rt_int32_t hdr_bank;/*Should be defined as:rx.FilterBank,which should be changed to rt_int32_t hdr_bank*/ - rt_uint32_t rxfifo;/*Add a configuration item that CAN_RX_FIFO0/CAN_RX_FIFO1*/ -#ifdef RT_CAN_USING_HDR - rt_err_t (*ind)(rt_device_t dev, void *args , rt_int32_t hdr, rt_size_t size); - void *args; -#endif /*RT_CAN_USING_HDR*/ -}; - - -#ifdef RT_CAN_USING_HDR -#define RT_CAN_FILTER_ITEM_INIT(id,ide,rtr,mode,mask,ind,args) \ - {(id), (ide), (rtr), (mode),(mask), -1, CAN_RX_FIFO0,(ind), (args)}/*0:CAN_RX_FIFO0*/ -#define RT_CAN_FILTER_STD_INIT(id,ind,args) \ - RT_CAN_FILTER_ITEM_INIT(id,0,0,0,0xFFFFFFFF,ind,args) -#define RT_CAN_FILTER_EXT_INIT(id,ind,args) \ - RT_CAN_FILTER_ITEM_INIT(id,1,0,0,0xFFFFFFFF,ind,args) -#define RT_CAN_STD_RMT_FILTER_INIT(id,ind,args) \ - RT_CAN_FILTER_ITEM_INIT(id,0,1,0,0xFFFFFFFF,ind,args) -#define RT_CAN_EXT_RMT_FILTER_INIT(id,ind,args) \ - RT_CAN_FILTER_ITEM_INIT(id,1,1,0,0xFFFFFFFF,ind,args) -#define RT_CAN_STD_RMT_DATA_FILTER_INIT(id,ind,args) \ - RT_CAN_FILTER_ITEM_INIT(id,0,0,1,0xFFFFFFFF,ind,args) -#define RT_CAN_EXT_RMT_DATA_FILTER_INIT(id,ind,args) \ - RT_CAN_FILTER_ITEM_INIT(id,1,0,1,0xFFFFFFFF,ind,args) -#else - -#define RT_CAN_FILTER_ITEM_INIT(id,ide,rtr,mode,mask) \ - {(id), (ide), (rtr), (mode), (mask), -1, CAN_RX_FIFO0 }/*0:CAN_RX_FIFO0*/ -#define RT_CAN_FILTER_STD_INIT(id) \ - RT_CAN_FILTER_ITEM_INIT(id,0,0,0,0xFFFFFFFF) -#define RT_CAN_FILTER_EXT_INIT(id) \ - RT_CAN_FILTER_ITEM_INIT(id,1,0,0,0xFFFFFFFF) -#define RT_CAN_STD_RMT_FILTER_INIT(id) \ - RT_CAN_FILTER_ITEM_INIT(id,0,1,0,0xFFFFFFFF) -#define RT_CAN_EXT_RMT_FILTER_INIT(id) \ - RT_CAN_FILTER_ITEM_INIT(id,1,1,0,0xFFFFFFFF) -#define RT_CAN_STD_RMT_DATA_FILTER_INIT(id) \ - RT_CAN_FILTER_ITEM_INIT(id,0,0,1,0xFFFFFFFF) -#define RT_CAN_EXT_RMT_DATA_FILTER_INIT(id) \ - RT_CAN_FILTER_ITEM_INIT(id,1,0,1,0xFFFFFFFF) -#endif - - -/** - * @brief CAN filter configuration - */ -struct rt_can_filter_config -{ - rt_uint32_t count; - rt_uint32_t actived; - struct rt_can_filter_item *items; -}; - -/** - * @brief CAN timing configuration - */ -struct rt_can_bit_timing -{ - rt_uint16_t prescaler; /* Pre-scaler */ - rt_uint16_t num_seg1; /* Bit Timing Segment 1, in terms of Tq */ - rt_uint16_t num_seg2; /* Bit Timing Segment 2, in terms of Tq */ - rt_uint8_t num_sjw; /* Synchronization Jump Width, in terms of Tq */ - rt_uint8_t num_sspoff; /* Secondary Sample Point Offset, in terms of Tq */ -}; - -/** - * @brief CAN bit timing configuration list - * @note - * items[0] always for CAN2.0/CANFD Arbitration Phase - * items[1] always for CANFD (if it exists) - */ -struct rt_can_bit_timing_config -{ - rt_uint32_t count; - struct rt_can_bit_timing *items; -}; - - -/** - * @brief CAN configuration - */ -struct can_configure -{ - rt_uint32_t baud_rate; - rt_uint32_t msgboxsz; - rt_uint32_t sndboxnumber; - rt_uint32_t mode : 8; - rt_uint32_t privmode : 8; - rt_uint32_t reserved : 16; - rt_uint32_t ticks; -#ifdef RT_CAN_USING_HDR - rt_uint32_t maxhdr; -#endif - -#ifdef RT_CAN_USING_CANFD - rt_uint32_t baud_rate_fd; /* CANFD data bit rate*/ - rt_uint32_t use_bit_timing: 8; /* Use the bit timing for CAN timing configuration */ - rt_uint32_t enable_canfd : 8; /* Enable CAN-FD mode */ - rt_uint32_t reserved1 : 16; - - /* The below fields take effect only if use_bit_timing is non-zero */ - struct rt_can_bit_timing can_timing; /* CAN bit-timing /CANFD bit-timing for arbitration phase */ - struct rt_can_bit_timing canfd_timing; /* CANFD bit-timing for datat phase */ -#endif -}; - -#define CANDEFAULTCONFIG \ -{\ - CAN1MBaud,\ - RT_CANMSG_BOX_SZ,\ - RT_CANSND_BOX_NUM,\ - RT_CAN_MODE_NORMAL,\ -}; - -struct rt_can_ops; -#define RT_CAN_CMD_SET_FILTER 0x13 -#define RT_CAN_CMD_SET_BAUD 0x14 -#define RT_CAN_CMD_SET_MODE 0x15 -#define RT_CAN_CMD_SET_PRIV 0x16 -#define RT_CAN_CMD_GET_STATUS 0x17 -#define RT_CAN_CMD_SET_STATUS_IND 0x18 -#define RT_CAN_CMD_SET_BUS_HOOK 0x19 -#define RT_CAN_CMD_SET_CANFD 0x1A -#define RT_CAN_CMD_SET_BAUD_FD 0x1B -#define RT_CAN_CMD_SET_BITTIMING 0x1C -#define RT_CAN_CMD_START 0x1D - -#define RT_DEVICE_CAN_INT_ERR 0x1000 - -enum RT_CAN_STATUS_MODE -{ - NORMAL = 0, - ERRWARNING = 1, - ERRPASSIVE = 2, - BUSOFF = 4, -}; -enum RT_CAN_BUS_ERR -{ - RT_CAN_BUS_NO_ERR = 0, - RT_CAN_BUS_BIT_PAD_ERR = 1, - RT_CAN_BUS_FORMAT_ERR = 2, - RT_CAN_BUS_ACK_ERR = 3, - RT_CAN_BUS_IMPLICIT_BIT_ERR = 4, - RT_CAN_BUS_EXPLICIT_BIT_ERR = 5, - RT_CAN_BUS_CRC_ERR = 6, -}; - -/** - * @brief CAN status - */ -struct rt_can_status -{ - rt_uint32_t rcverrcnt; - rt_uint32_t snderrcnt; - rt_uint32_t errcode; - rt_uint32_t rcvpkg; - rt_uint32_t dropedrcvpkg; - rt_uint32_t sndpkg; - rt_uint32_t dropedsndpkg; - rt_uint32_t bitpaderrcnt; - rt_uint32_t formaterrcnt; - rt_uint32_t ackerrcnt; - rt_uint32_t biterrcnt; - rt_uint32_t crcerrcnt; - rt_uint32_t rcvchange; - rt_uint32_t sndchange; - rt_uint32_t lasterrtype; -}; - -#ifdef RT_CAN_USING_HDR -struct rt_can_hdr -{ - rt_uint32_t connected; - rt_uint32_t msgs; - struct rt_can_filter_item filter; - struct rt_list_node list; -}; -#endif -struct rt_can_device; -typedef rt_err_t (*rt_canstatus_ind)(struct rt_can_device *, void *); - -typedef struct rt_can_status_ind_type -{ - rt_canstatus_ind ind; - void *args; -} *rt_can_status_ind_type_t; -typedef void (*rt_can_bus_hook)(struct rt_can_device *); -struct rt_can_device -{ - struct rt_device parent; - - const struct rt_can_ops *ops; - struct can_configure config; - struct rt_can_status status; - - rt_uint32_t timerinitflag; - struct rt_timer timer; - - struct rt_can_status_ind_type status_indicate; -#ifdef RT_CAN_USING_HDR - struct rt_can_hdr *hdr; -#endif -#ifdef RT_CAN_USING_BUS_HOOK - rt_can_bus_hook bus_hook; -#endif /*RT_CAN_USING_BUS_HOOK*/ - struct rt_mutex lock; - void *can_rx; - void *can_tx; -}; -typedef struct rt_can_device *rt_can_t; - -#define RT_CAN_STDID 0 -#define RT_CAN_EXTID 1 -#define RT_CAN_DTR 0 -#define RT_CAN_RTR 1 - -typedef struct rt_can_status *rt_can_status_t; - -struct rt_can_msg -{ - rt_uint32_t id : 29; - rt_uint32_t ide : 1; - rt_uint32_t rtr : 1; - rt_uint32_t rsv : 1; - rt_uint32_t len : 8; - rt_uint32_t priv : 8; - rt_int32_t hdr_index : 8;/*Should be defined as:rx.FilterMatchIndex,which should be changed to rt_int32_t hdr_index : 8*/ -#ifdef RT_CAN_USING_CANFD - rt_uint32_t fd_frame : 1; - rt_uint32_t brs : 1; - rt_uint32_t rxfifo : 2;/*Redefined to return :CAN RX FIFO0/CAN RX FIFO1*/ - rt_uint32_t reserved : 4; -#else - rt_uint32_t rxfifo : 2;/*Redefined to return :CAN RX FIFO0/CAN RX FIFO1*/ - rt_uint32_t reserved : 6; -#endif -#ifdef RT_CAN_USING_CANFD - rt_uint8_t data[64]; -#else - rt_uint8_t data[8]; -#endif -}; -typedef struct rt_can_msg *rt_can_msg_t; - -struct rt_can_msg_list -{ - struct rt_list_node list; -#ifdef RT_CAN_USING_HDR - struct rt_list_node hdrlist; - struct rt_can_hdr *owner; -#endif - struct rt_can_msg data; -}; - -struct rt_can_rx_fifo -{ - /* software fifo */ - struct rt_can_msg_list *buffer; - rt_uint32_t freenumbers; - struct rt_list_node freelist; - struct rt_list_node uselist; -}; - -#define RT_CAN_SND_RESULT_OK 0 -#define RT_CAN_SND_RESULT_ERR 1 -#define RT_CAN_SND_RESULT_WAIT 2 - -#define RT_CAN_EVENT_RX_IND 0x01 /* Rx indication */ -#define RT_CAN_EVENT_TX_DONE 0x02 /* Tx complete */ -#define RT_CAN_EVENT_TX_FAIL 0x03 /* Tx fail */ -#define RT_CAN_EVENT_RX_TIMEOUT 0x05 /* Rx timeout */ -#define RT_CAN_EVENT_RXOF_IND 0x06 /* Rx overflow */ - -struct rt_can_sndbxinx_list -{ - struct rt_list_node list; - struct rt_completion completion; - rt_uint32_t result; -}; - -struct rt_can_tx_fifo -{ - struct rt_can_sndbxinx_list *buffer; - struct rt_semaphore sem; - struct rt_list_node freelist; -}; - -/** - * @brief CAN operators - */ -struct rt_can_ops -{ - rt_err_t (*configure)(struct rt_can_device *can, struct can_configure *cfg); - rt_err_t (*control)(struct rt_can_device *can, int cmd, void *arg); - rt_ssize_t (*sendmsg)(struct rt_can_device *can, const void *buf, rt_uint32_t boxno); - rt_ssize_t (*recvmsg)(struct rt_can_device *can, void *buf, rt_uint32_t boxno); -}; - -/** - * @brief Register a CAN device to device list - * - * @param can the CAN device object - * @param name the name of CAN device - * @param ops the CAN device operators - * @param data the private data of CAN device - * - * @return the error code, RT_EOK on successfully - */ -rt_err_t rt_hw_can_register(struct rt_can_device *can, - const char *name, - const struct rt_can_ops *ops, - void *data); - -/** - * @brief CAN interrupt service routine - * - * @param can the CAN device - * @param event the event mask - */ -void rt_hw_can_isr(struct rt_can_device *can, int event); - -/*! @}*/ - -#endif /*__DEV_CAN_H*/ diff --git a/rt-thread/components/drivers/include/drivers/dev_i2c.h b/rt-thread/components/drivers/include/drivers/dev_i2c.h deleted file mode 100644 index dea75d2..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_i2c.h +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-04-25 weety first version - * 2021-04-20 RiceChen added support for bus control api - */ - -#ifndef __DEV_I2C_H__ -#define __DEV_I2C_H__ - -#include -/** - * @addtogroup Drivers RTTHREAD Driver - * @defgroup I2C I2C - * - * @brief I2C driver api - * - * Example - * @code {.c} - * #include - * #include - * - * #define AHT10_I2C_BUS_NAME "i2c1" // 传感器连接的I2C总线设备名称 - * #define AHT10_ADDR 0x38 // 从机地址 - * #define AHT10_CALIBRATION_CMD 0xE1 // 校准命令 - * #define AHT10_NORMAL_CMD 0xA8 // 一般命令 - * #define AHT10_GET_DATA 0xAC // 获取数据命令 - * - * static struct rt_i2c_bus_device *i2c_bus = RT_NULL; // I2C总线设备句柄 - * static rt_bool_t initialized = RT_FALSE; // 传感器初始化状态 - * - * // 写传感器寄存器 - * static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t *data) - * { - * rt_uint8_t buf[3]; - * struct rt_i2c_msg msgs; - * rt_uint32_t buf_size = 1; - * - * buf[0] = reg; //cmd - * if (data != RT_NULL) - * { - * buf[1] = data[0]; - * buf[2] = data[1]; - * buf_size = 3; - * } - * - * msgs.addr = AHT10_ADDR; - * msgs.flags = RT_I2C_WR; - * msgs.buf = buf; - * msgs.len = buf_size; - * - * // 调用I2C设备接口传输数据 - * if (rt_i2c_transfer(bus, &msgs, 1) == 1) - * { - * return RT_EOK; - * } - * else - * { - * return -RT_ERROR; - * } - * } - * - * // 读传感器寄存器数据 - * static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t len, rt_uint8_t *buf) - * { - * struct rt_i2c_msg msgs; - * - * msgs.addr = AHT10_ADDR; - * msgs.flags = RT_I2C_RD; - * msgs.buf = buf; - * msgs.len = len; - * - * // 调用I2C设备接口传输数据 - * if (rt_i2c_transfer(bus, &msgs, 1) == 1) - * { - * return RT_EOK; - * } - * else - * { - * return -RT_ERROR; - * } - * } - * - * static void read_temp_humi(float *cur_temp, float *cur_humi) - * { - * rt_uint8_t temp[6]; - * - * write_reg(i2c_bus, AHT10_GET_DATA, RT_NULL); // 发送命令 - * rt_thread_mdelay(400); - * read_regs(i2c_bus, 6, temp); // 获取传感器数据 - * - * // 湿度数据转换 - * *cur_humi = (temp[1] << 12 | temp[2] << 4 | (temp[3] & 0xf0) >> 4) * 100.0 / (1 << 20); - * // 温度数据转换 - * *cur_temp = ((temp[3] & 0xf) << 16 | temp[4] << 8 | temp[5]) * 200.0 / (1 << 20) - 50; - * } - * - * static void aht10_init(const char *name) - * { - * rt_uint8_t temp[2] = {0, 0}; - * - * // 查找I2C总线设备,获取I2C总线设备句柄 - * i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name); - * - * if (i2c_bus == RT_NULL) - * { - * rt_kprintf("can't find %s device!\n", name); - * } - * else - * { - * write_reg(i2c_bus, AHT10_NORMAL_CMD, temp); - * rt_thread_mdelay(400); - * - * temp[0] = 0x08; - * temp[1] = 0x00; - * write_reg(i2c_bus, AHT10_CALIBRATION_CMD, temp); - * rt_thread_mdelay(400); - * initialized = RT_TRUE; - * } - * } - * - * static void i2c_aht10_sample(int argc, char *argv[]) - * { - * float humidity, temperature; - * char name[RT_NAME_MAX]; - * - * humidity = 0.0; - * temperature = 0.0; - * - * if (argc == 2) - * { - * rt_strncpy(name, argv[1], RT_NAME_MAX); - * } - * else - * { - * rt_strncpy(name, AHT10_I2C_BUS_NAME, RT_NAME_MAX); - * } - * - * if (!initialized) - * { - * // 传感器初始化 - * aht10_init(name); - * } - * if (initialized) - * { - * // 读取温湿度数据 - * read_temp_humi(&temperature, &humidity); - * - * rt_kprintf("read aht10 sensor humidity : %d.%d %%\n", (int)humidity, (int)(humidity * 10) % 10); - * if( temperature >= 0 ) - * { - * rt_kprintf("read aht10 sensor temperature: %d.%d°C\n", (int)temperature, (int)(temperature * 10) % 10); - * } - * else - * { - * rt_kprintf("read aht10 sensor temperature: %d.%d°C\n", (int)temperature, (int)(-temperature * 10) % 10); - * } - * } - * else - * { - * rt_kprintf("initialize sensor failed!\n"); - * } - * } - * // 导出到 msh 命令列表中 - * MSH_CMD_EXPORT(i2c_aht10_sample, i2c aht10 sample); - * @endcode - * - * @ingroup Drivers - */ - -/*! - * @addtogroup I2C - * @{ - */ -#ifdef __cplusplus -extern "C" { -#endif - -#define RT_I2C_WR 0x0000 /*!< i2c wirte flag */ -#define RT_I2C_RD (1u << 0) /*!< i2c read flag */ -#define RT_I2C_ADDR_10BIT (1u << 2) /*!< this is a ten bit chip address */ -#define RT_I2C_NO_START (1u << 4) /*!< do not generate START condition */ -#define RT_I2C_IGNORE_NACK (1u << 5) /*!< ignore NACK from slave */ -#define RT_I2C_NO_READ_ACK (1u << 6) /* when I2C reading, we do not ACK */ -#define RT_I2C_NO_STOP (1u << 7) /*!< do not generate STOP condition */ - -#define RT_I2C_DEV_CTRL_10BIT (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x01) -#define RT_I2C_DEV_CTRL_ADDR (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x02) -#define RT_I2C_DEV_CTRL_TIMEOUT (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x03) -#define RT_I2C_DEV_CTRL_RW (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x04) -#define RT_I2C_DEV_CTRL_CLK (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x05) -#define RT_I2C_DEV_CTRL_UNLOCK (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x06) -#define RT_I2C_DEV_CTRL_GET_STATE (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x07) -#define RT_I2C_DEV_CTRL_GET_MODE (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x08) -#define RT_I2C_DEV_CTRL_GET_ERROR (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x09) - -/** - * @brief I2C Private Data - */ -struct rt_i2c_priv_data -{ - struct rt_i2c_msg *msgs; - rt_size_t number; -}; - -/** - * @brief I2C Message - */ -struct rt_i2c_msg -{ - rt_uint16_t addr; - rt_uint16_t flags; - rt_uint16_t len; - rt_uint8_t *buf; -}; - -struct rt_i2c_bus_device; - -/** - * @brief I2C Bus Device Operations - */ -struct rt_i2c_bus_device_ops -{ - rt_ssize_t (*master_xfer)(struct rt_i2c_bus_device *bus, - struct rt_i2c_msg msgs[], - rt_uint32_t num); - rt_ssize_t (*slave_xfer)(struct rt_i2c_bus_device *bus, - struct rt_i2c_msg msgs[], - rt_uint32_t num); - rt_err_t (*i2c_bus_control)(struct rt_i2c_bus_device *bus, - int cmd, - void *args); -}; - -/** - * @brief I2C Bus Device - */ -struct rt_i2c_bus_device -{ - struct rt_device parent; - const struct rt_i2c_bus_device_ops *ops; - rt_uint16_t flags; - struct rt_mutex lock; - rt_uint32_t timeout; - rt_uint32_t retries; - void *priv; -}; - -/** - * @brief I2C Client - */ -struct rt_i2c_client -{ -#ifdef RT_USING_DM - struct rt_device parent; - - const char *name; - const struct rt_i2c_device_id *id; - const struct rt_ofw_node_id *ofw_id; -#endif - struct rt_i2c_bus_device *bus; - rt_uint16_t client_addr; -}; - -#ifdef RT_USING_DM -struct rt_i2c_device_id -{ - char name[20]; - void *data; -}; - -struct rt_i2c_driver -{ - struct rt_driver parent; - - const struct rt_i2c_device_id *ids; - const struct rt_ofw_node_id *ofw_ids; - - rt_err_t (*probe)(struct rt_i2c_client *client); - rt_err_t (*remove)(struct rt_i2c_client *client); - rt_err_t (*shutdown)(struct rt_i2c_client *client); -}; - -rt_err_t rt_i2c_driver_register(struct rt_i2c_driver *driver); -rt_err_t rt_i2c_device_register(struct rt_i2c_client *client); - -#define RT_I2C_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, i2c, BUILIN) -#endif /* RT_USING_DM */ - -/** - * @brief I2C Bus Device Initialization - * - * @param bus the I2C bus device - * @param name the name of I2C bus device - * - * @return rt_err_t error code - */ -rt_err_t rt_i2c_bus_device_device_init(struct rt_i2c_bus_device *bus, - const char *name); - -/** - * @brief I2C Bus Device Register - * - * @param bus the I2C bus device - * @param bus_name the name of I2C bus device - * - * @return rt_err_t error code - */ -rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus, - const char *bus_name); - -/** - * @brief I2C Bus Device Find - * - * @param bus_name the name of I2C bus device - * - * @return rt_i2c_bus_device the I2C bus device - */ -struct rt_i2c_bus_device *rt_i2c_bus_device_find(const char *bus_name); - -/** - * @brief I2C data transmission. - * - * @param bus the I2C bus device - * @param msgs the I2C message list - * @param num the number of I2C message - * - * @return rt_ssize_t the actual length of transmitted - */ -rt_ssize_t rt_i2c_transfer(struct rt_i2c_bus_device *bus, - struct rt_i2c_msg msgs[], - rt_uint32_t num); - -/** - * @brief I2C Control - * - * @param bus the I2C bus device - * @param cmd the I2C control command - * @param args the I2C control arguments - * - * @return rt_err_t error code - */ -rt_err_t rt_i2c_control(struct rt_i2c_bus_device *bus, - int cmd, - void *args); - -/** - * @brief I2C Master Send - * - * @param bus the I2C bus device - * @param addr the I2C slave address - * @param flags the I2C flags - * @param buf the I2C send buffer - * @param count the I2C send buffer length - * - * @return rt_ssize_t the actual length of transmitted - */ -rt_ssize_t rt_i2c_master_send(struct rt_i2c_bus_device *bus, - rt_uint16_t addr, - rt_uint16_t flags, - const rt_uint8_t *buf, - rt_uint32_t count); - -/** - * @brief I2C Master Receive - * - * @param bus the I2C bus device - * @param addr the I2C slave address - * @param flags the I2C flags - * @param buf the I2C receive buffer - * @param count the I2C receive buffer length - * - * @return rt_ssize_t the actual length of received - */ -rt_ssize_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus, - rt_uint16_t addr, - rt_uint16_t flags, - rt_uint8_t *buf, - rt_uint32_t count); - -rt_inline rt_err_t rt_i2c_bus_lock(struct rt_i2c_bus_device *bus, rt_tick_t timeout) -{ - return rt_mutex_take(&bus->lock, timeout); -} - -rt_inline rt_err_t rt_i2c_bus_unlock(struct rt_i2c_bus_device *bus) -{ - return rt_mutex_release(&bus->lock); -} - -#ifdef __cplusplus -} -#endif - -/*! @}*/ - -#endif diff --git a/rt-thread/components/drivers/include/drivers/dev_i2c_bit_ops.h b/rt-thread/components/drivers/include/drivers/dev_i2c_bit_ops.h deleted file mode 100644 index 3c28714..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_i2c_bit_ops.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-04-25 weety first version - */ - -#ifndef __DEV_I2C_BIT_OPS_H__ -#define __DEV_I2C_BIT_OPS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -struct rt_i2c_bit_ops -{ - void *data; /* private data for lowlevel routines */ - void (*set_sda)(void *data, rt_int32_t state); - void (*set_scl)(void *data, rt_int32_t state); - rt_int32_t (*get_sda)(void *data); - rt_int32_t (*get_scl)(void *data); - - void (*udelay)(rt_uint32_t us); - - rt_uint32_t delay_us; /* scl and sda line delay */ - rt_uint32_t timeout; /* in tick */ - - void (*pin_init)(void); - rt_bool_t i2c_pin_init_flag; -}; - -rt_err_t rt_i2c_bit_add_bus(struct rt_i2c_bus_device *bus, - const char *bus_name); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/components/drivers/include/drivers/dev_i2c_dm.h b/rt-thread/components/drivers/include/drivers/dev_i2c_dm.h deleted file mode 100644 index c59d6e9..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_i2c_dm.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-26 GuEe-GUI first version - */ - -#ifndef __DEV_I2C_DM_H__ -#define __DEV_I2C_DM_H__ - -#include -#include -#include - -/* I2C Frequency Modes */ -#define I2C_MAX_STANDARD_MODE_FREQ 100000 -#define I2C_MAX_FAST_MODE_FREQ 400000 -#define I2C_MAX_FAST_MODE_PLUS_FREQ 1000000 -#define I2C_MAX_TURBO_MODE_FREQ 1400000 -#define I2C_MAX_HIGH_SPEED_MODE_FREQ 3400000 -#define I2C_MAX_ULTRA_FAST_MODE_FREQ 5000000 - -struct i2c_timings -{ - rt_uint32_t bus_freq_hz; /* the bus frequency in Hz */ - rt_uint32_t scl_rise_ns; /* time SCL signal takes to rise in ns; t(r) in the I2C specification */ - rt_uint32_t scl_fall_ns; /* time SCL signal takes to fall in ns; t(f) in the I2C specification */ - rt_uint32_t scl_int_delay_ns; /* time IP core additionally needs to setup SCL in ns */ - rt_uint32_t sda_fall_ns; /* time SDA signal takes to fall in ns; t(f) in the I2C specification */ - rt_uint32_t sda_hold_ns; /* time IP core additionally needs to hold SDA in ns */ - rt_uint32_t digital_filter_width_ns; /* width in ns of spikes on i2c lines that the IP core digital filter can filter out */ - rt_uint32_t analog_filter_cutoff_freq_hz; /* threshold frequency for the low pass IP core analog filter */ -}; - -#ifdef RT_USING_OFW -rt_err_t i2c_timings_ofw_parse(struct rt_ofw_node *dev_np, struct i2c_timings *timings, - rt_bool_t use_defaults); -#else -rt_inline rt_err_t i2c_timings_ofw_parse(struct rt_ofw_node *dev_np, struct i2c_timings *timings, - rt_bool_t use_defaults) -{ - return RT_EOK; -} -#endif /* RT_USING_OFW */ - -void i2c_bus_scan_clients(struct rt_i2c_bus_device *bus); - -#endif /* __DEV_I2C_DM_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/dev_mmc.h b/rt-thread/components/drivers/include/drivers/dev_mmc.h deleted file mode 100644 index a537287..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_mmc.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2015-06-15 hichard first version - * 2024-05-25 HPMicro add strobe support - */ - -#ifndef __DEV_MMC_H__ -#define __DEV_MMC_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * EXT_CSD fields - */ - -#define EXT_CSD_FLUSH_CACHE 32 /* W */ -#define EXT_CSD_CACHE_CTRL 33 /* R/W */ -#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */ -#define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */ -#define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */ -#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */ -#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */ -#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */ -#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ -#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */ -#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */ -#define EXT_CSD_HPI_MGMT 161 /* R/W */ -#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */ -#define EXT_CSD_BKOPS_EN 163 /* R/W */ -#define EXT_CSD_BKOPS_START 164 /* W */ -#define EXT_CSD_SANITIZE_START 165 /* W */ -#define EXT_CSD_WR_REL_PARAM 166 /* RO */ -#define EXT_CSD_RPMB_MULT 168 /* RO */ -#define EXT_CSD_BOOT_WP 173 /* R/W */ -#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ -#define EXT_CSD_PART_CONFIG 179 /* R/W */ -#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */ -#define EXT_CSD_BUS_WIDTH 183 /* R/W */ -#define EXT_CSD_STROBE_SUPPORT 184 /* RO */ -#define EXT_CSD_HS_TIMING 185 /* R/W */ -#define EXT_CSD_POWER_CLASS 187 /* R/W */ -#define EXT_CSD_REV 192 /* RO */ -#define EXT_CSD_STRUCTURE 194 /* RO */ -#define EXT_CSD_CARD_TYPE 196 /* RO */ -#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */ -#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */ -#define EXT_CSD_PWR_CL_52_195 200 /* RO */ -#define EXT_CSD_PWR_CL_26_195 201 /* RO */ -#define EXT_CSD_PWR_CL_52_360 202 /* RO */ -#define EXT_CSD_PWR_CL_26_360 203 /* RO */ -#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ -#define EXT_CSD_S_A_TIMEOUT 217 /* RO */ -#define EXT_CSD_REL_WR_SEC_C 222 /* RO */ -#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ -#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */ -#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ -#define EXT_CSD_BOOT_MULT 226 /* RO */ -#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */ -#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */ -#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */ -#define EXT_CSD_TRIM_MULT 232 /* RO */ -#define EXT_CSD_PWR_CL_200_195 236 /* RO */ -#define EXT_CSD_PWR_CL_200_360 237 /* RO */ -#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */ -#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */ -#define EXT_CSD_BKOPS_STATUS 246 /* RO */ -#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */ -#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */ -#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ -#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */ -#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ -#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */ -#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */ -#define EXT_CSD_MAX_PACKED_READS 501 /* RO */ -#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */ -#define EXT_CSD_HPI_FEATURES 503 /* RO */ - -/* - * EXT_CSD field definitions - */ - -#define EXT_CSD_WR_REL_PARAM_EN (1<<2) - -#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40) -#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10) -#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04) -#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01) - -#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7) -#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1) -#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3) -#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4) - -#define EXT_CSD_PART_SUPPORT_PART_EN (0x1) - -#define EXT_CSD_CMD_SET_NORMAL (1<<0) -#define EXT_CSD_CMD_SET_SECURE (1<<1) -#define EXT_CSD_CMD_SET_CPSECURE (1<<2) - -#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */ -#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */ -#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \ - EXT_CSD_CARD_TYPE_HS_52) -#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */ - /* DDR mode @1.8V or 3V I/O */ -#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */ - /* DDR mode @1.2V I/O */ -#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \ - | EXT_CSD_CARD_TYPE_DDR_1_2V) -#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */ -#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */ - /* SDR mode @1.2V I/O */ -#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \ - EXT_CSD_CARD_TYPE_HS200_1_2V) -#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */ -#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */ -#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \ - EXT_CSD_CARD_TYPE_HS400_1_2V) - -#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ -#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ -#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ -#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */ -#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */ -#define EXT_CSD_DDR_BUS_WIDTH_8_EH_DS 0x86/* Card is in 8 bit DDR mode with Enhanced Data Strobe */ - -#define EXT_CSD_TIMING_BC 0 /* Backwards compatibility */ -#define EXT_CSD_TIMING_HS 1 /* High speed */ -#define EXT_CSD_TIMING_HS200 2 /* HS200 */ -#define EXT_CSD_TIMING_HS400 3 /* HS400 */ - -#define EXT_CSD_SEC_ER_EN BIT(0) -#define EXT_CSD_SEC_BD_BLK_EN BIT(2) -#define EXT_CSD_SEC_GB_CL_EN BIT(4) -#define EXT_CSD_SEC_SANITIZE BIT(6) /* v4.5 only */ - -#define EXT_CSD_RST_N_EN_MASK 0x3 -#define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */ - -#define EXT_CSD_NO_POWER_NOTIFICATION 0 -#define EXT_CSD_POWER_ON 1 -#define EXT_CSD_POWER_OFF_SHORT 2 -#define EXT_CSD_POWER_OFF_LONG 3 - -#define EXT_CSD_PWR_CL_8BIT_MASK 0xF0 /* 8 bit PWR CLS */ -#define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */ -#define EXT_CSD_PWR_CL_8BIT_SHIFT 4 -#define EXT_CSD_PWR_CL_4BIT_SHIFT 0 - -#define EXT_CSD_PACKED_EVENT_EN BIT(3) - -/* - * EXCEPTION_EVENT_STATUS field - */ -#define EXT_CSD_URGENT_BKOPS BIT(0) -#define EXT_CSD_DYNCAP_NEEDED BIT(1) -#define EXT_CSD_SYSPOOL_EXHAUSTED BIT(2) -#define EXT_CSD_PACKED_FAILURE BIT(3) - -#define EXT_CSD_PACKED_GENERIC_ERROR BIT(0) -#define EXT_CSD_PACKED_INDEXED_ERROR BIT(1) - -/* - * BKOPS status level - */ -#define EXT_CSD_BKOPS_LEVEL_2 0x2 -/* - * MMC_SWITCH access modes - */ -#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ -#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */ -#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */ -#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ - -/* - * extern function - */ -rt_err_t mmc_send_op_cond(struct rt_mmcsd_host *host, rt_uint32_t ocr, rt_uint32_t *rocr); -rt_int32_t init_mmc(struct rt_mmcsd_host *host, rt_uint32_t ocr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/components/drivers/include/drivers/dev_mmcsd_core.h b/rt-thread/components/drivers/include/drivers/dev_mmcsd_core.h deleted file mode 100644 index c86e9dd..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_mmcsd_core.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-07-25 weety first version - */ - -#ifndef __DEV_MMCSD_CORE_H__ -#define __DEV_MMCSD_CORE_H__ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef RT_MMCSD_DBG -#define mmcsd_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__) -#else -#define mmcsd_dbg(fmt, ...) -#endif - -struct rt_mmcsd_data -{ - rt_uint32_t blksize; - rt_uint32_t blks; - rt_uint32_t *buf; - rt_int32_t err; - rt_uint32_t flags; -#define DATA_DIR_WRITE (1 << 0) -#define DATA_DIR_READ (1 << 1) -#define DATA_STREAM (1 << 2) - - unsigned int bytes_xfered; - - struct rt_mmcsd_cmd *stop; /* stop command */ - struct rt_mmcsd_req *mrq; /* associated request */ - - rt_uint32_t timeout_ns; - rt_uint32_t timeout_clks; - - void *sg; /* scatter list */ - rt_uint16_t sg_len; /* size of scatter list */ - rt_int16_t sg_count; /* mapped sg entries */ - rt_ubase_t host_cookie; /* host driver private data */ -}; - -struct rt_mmcsd_cmd -{ - rt_uint32_t cmd_code; - rt_uint32_t arg; - rt_uint32_t resp[4]; - rt_uint32_t flags; -/*rsponse types - *bits:0~3 - */ -#define RESP_MASK (0xF) -#define RESP_NONE (0) -#define RESP_R1 (1 << 0) -#define RESP_R1B (2 << 0) -#define RESP_R2 (3 << 0) -#define RESP_R3 (4 << 0) -#define RESP_R4 (5 << 0) -#define RESP_R6 (6 << 0) -#define RESP_R7 (7 << 0) -#define RESP_R5 (8 << 0) /*SDIO command response type*/ -/*command types - *bits:4~5 - */ -#define CMD_MASK (3 << 4) /* command type */ -#define CMD_AC (0 << 4) -#define CMD_ADTC (1 << 4) -#define CMD_BC (2 << 4) -#define CMD_BCR (3 << 4) - -#define resp_type(cmd) ((cmd)->flags & RESP_MASK) - -/*spi rsponse types - *bits:6~8 - */ -#define RESP_SPI_MASK (0x7 << 6) -#define RESP_SPI_R1 (1 << 6) -#define RESP_SPI_R1B (2 << 6) -#define RESP_SPI_R2 (3 << 6) -#define RESP_SPI_R3 (4 << 6) -#define RESP_SPI_R4 (5 << 6) -#define RESP_SPI_R5 (6 << 6) -#define RESP_SPI_R7 (7 << 6) - -#define spi_resp_type(cmd) ((cmd)->flags & RESP_SPI_MASK) -/* - * These are the command types. - */ -#define cmd_type(cmd) ((cmd)->flags & CMD_MASK) - - rt_int32_t retries; /* max number of retries */ - rt_int32_t err; - unsigned int busy_timeout; /* busy detect timeout in ms */ - - struct rt_mmcsd_data *data; - struct rt_mmcsd_req *mrq; /* associated request */ -}; - -struct rt_mmcsd_req -{ - struct rt_mmcsd_data *data; - struct rt_mmcsd_cmd *cmd; - struct rt_mmcsd_cmd *stop; - struct rt_mmcsd_cmd *sbc; /* SET_BLOCK_COUNT for multiblock */ - /* Allow other commands during this ongoing data transfer or busy wait */ - int cap_cmd_during_tfr; -}; - -/*the following is response bit*/ -#define R1_OUT_OF_RANGE (1 << 31) /* er, c */ -#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */ -#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */ -#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */ -#define R1_ERASE_PARAM (1 << 27) /* ex, c */ -#define R1_WP_VIOLATION (1 << 26) /* erx, c */ -#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */ -#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */ -#define R1_COM_CRC_ERROR (1 << 23) /* er, b */ -#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */ -#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */ -#define R1_CC_ERROR (1 << 20) /* erx, c */ -#define R1_ERROR (1 << 19) /* erx, c */ -#define R1_UNDERRUN (1 << 18) /* ex, c */ -#define R1_OVERRUN (1 << 17) /* ex, c */ -#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */ -#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */ -#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */ -#define R1_ERASE_RESET (1 << 13) /* sr, c */ -#define R1_STATUS(x) (x & 0xFFFFE000) -#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ -#define R1_READY_FOR_DATA (1 << 8) /* sx, a */ -#define R1_APP_CMD (1 << 5) /* sr, c */ - - -#define R1_SPI_IDLE (1 << 0) -#define R1_SPI_ERASE_RESET (1 << 1) -#define R1_SPI_ILLEGAL_COMMAND (1 << 2) -#define R1_SPI_COM_CRC (1 << 3) -#define R1_SPI_ERASE_SEQ (1 << 4) -#define R1_SPI_ADDRESS (1 << 5) -#define R1_SPI_PARAMETER (1 << 6) -/* R1 bit 7 is always zero */ -#define R2_SPI_CARD_LOCKED (1 << 8) -#define R2_SPI_WP_ERASE_SKIP (1 << 9) /* or lock/unlock fail */ -#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP -#define R2_SPI_ERROR (1 << 10) -#define R2_SPI_CC_ERROR (1 << 11) -#define R2_SPI_CARD_ECC_ERROR (1 << 12) -#define R2_SPI_WP_VIOLATION (1 << 13) -#define R2_SPI_ERASE_PARAM (1 << 14) -#define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */ -#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE - -#define CARD_BUSY 0x80000000 /* Card Power up status bit */ - -/* R5 response bits */ -#define R5_COM_CRC_ERROR (1 << 15) -#define R5_ILLEGAL_COMMAND (1 << 14) -#define R5_ERROR (1 << 11) -#define R5_FUNCTION_NUMBER (1 << 9) -#define R5_OUT_OF_RANGE (1 << 8) -#define R5_STATUS(x) (x & 0xCB00) -#define R5_IO_CURRENT_STATE(x) ((x & 0x3000) >> 12) - - - -/** - * fls - find last (most-significant) bit set - * @x: the word to search - * - * This is defined the same way as ffs. - * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. - */ - -rt_inline rt_uint32_t __rt_fls(rt_uint32_t val) -{ - rt_uint32_t bit = 32; - - if (!val) - return 0; - if (!(val & 0xffff0000u)) - { - val <<= 16; - bit -= 16; - } - if (!(val & 0xff000000u)) - { - val <<= 8; - bit -= 8; - } - if (!(val & 0xf0000000u)) - { - val <<= 4; - bit -= 4; - } - if (!(val & 0xc0000000u)) - { - val <<= 2; - bit -= 2; - } - if (!(val & 0x80000000u)) - { - bit -= 1; - } - - return bit; -} - -#define MMCSD_HOST_PLUGED 0 -#define MMCSD_HOST_UNPLUGED 1 - -rt_int32_t mmcsd_excute_tuning(struct rt_mmcsd_card *card); -int mmcsd_wait_cd_changed(rt_int32_t timeout); -void mmcsd_host_lock(struct rt_mmcsd_host *host); -void mmcsd_host_unlock(struct rt_mmcsd_host *host); -void mmcsd_req_complete(struct rt_mmcsd_host *host); -void mmcsd_send_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req); -rt_int32_t mmcsd_send_cmd(struct rt_mmcsd_host *host, struct rt_mmcsd_cmd *cmd, int retries); -rt_int32_t mmcsd_go_idle(struct rt_mmcsd_host *host); -rt_int32_t mmcsd_spi_read_ocr(struct rt_mmcsd_host *host, rt_int32_t high_capacity, rt_uint32_t *ocr); -rt_int32_t mmcsd_all_get_cid(struct rt_mmcsd_host *host, rt_uint32_t *cid); -rt_int32_t mmcsd_get_cid(struct rt_mmcsd_host *host, rt_uint32_t *cid); -rt_int32_t mmcsd_get_csd(struct rt_mmcsd_card *card, rt_uint32_t *csd); -rt_int32_t mmcsd_select_card(struct rt_mmcsd_card *card); -rt_int32_t mmcsd_deselect_cards(struct rt_mmcsd_card *host); -rt_int32_t mmcsd_spi_use_crc(struct rt_mmcsd_host *host, rt_int32_t use_crc); -void mmcsd_set_chip_select(struct rt_mmcsd_host *host, rt_int32_t mode); -void mmcsd_set_clock(struct rt_mmcsd_host *host, rt_uint32_t clk); -void mmcsd_set_bus_mode(struct rt_mmcsd_host *host, rt_uint32_t mode); -void mmcsd_set_bus_width(struct rt_mmcsd_host *host, rt_uint32_t width); -void mmcsd_set_timing(struct rt_mmcsd_host *host, rt_uint32_t timing); -void mmcsd_set_data_timeout(struct rt_mmcsd_data *data, const struct rt_mmcsd_card *card); -rt_uint32_t mmcsd_select_voltage(struct rt_mmcsd_host *host, rt_uint32_t ocr); -void mmcsd_change(struct rt_mmcsd_host *host); -void mmcsd_detect(void *param); -void mmcsd_host_init(struct rt_mmcsd_host *host); -struct rt_mmcsd_host *mmcsd_alloc_host(void); -void mmcsd_free_host(struct rt_mmcsd_host *host); -int rt_mmcsd_core_init(void); - -rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card); -void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/components/drivers/include/drivers/dev_pin.h b/rt-thread/components/drivers/include/drivers/dev_pin.h deleted file mode 100644 index b1705ae..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_pin.h +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2015-01-20 Bernard the first version - * 2017-10-20 ZYH add mode open drain and input pull down - */ - -#ifndef DEV_PIN_H__ -#define DEV_PIN_H__ - -#include - -/** - * @addtogroup Drivers RTTHREAD Driver - * @defgroup Pin Pin - * - * @brief Pin driver api - * - * Example - * @code {.c} - * #include - * #include - * - * - * #ifndef BEEP_PIN_NUM - * #define BEEP_PIN_NUM 35 // PB0 - * #endif - * #ifndef KEY0_PIN_NUM - * #define KEY0_PIN_NUM 55 // PD8 - * #endif - * #ifndef KEY1_PIN_NUM - * #define KEY1_PIN_NUM 56 // PD9 - * #endif - * - * void beep_on(void *args) - * { - * rt_kprintf("turn on beep!\n"); - * - * rt_pin_write(BEEP_PIN_NUM, PIN_HIGH); - * } - * - * void beep_off(void *args) - * { - * rt_kprintf("turn off beep!\n"); - * - * rt_pin_write(BEEP_PIN_NUM, PIN_LOW); - * } - * - * static void pin_beep_sample(void) - * { - * rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT); - * rt_pin_write(BEEP_PIN_NUM, PIN_LOW); - * - * rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP); - * rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL); - * rt_pin_irq_enable(KEY0_PIN_NUM, PIN_IRQ_ENABLE); - * - * - * rt_pin_mode(KEY1_PIN_NUM, PIN_MODE_INPUT_PULLUP); - * rt_pin_attach_irq(KEY1_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_off, RT_NULL); - * rt_pin_irq_enable(KEY1_PIN_NUM, PIN_IRQ_ENABLE); - * } - * - * MSH_CMD_EXPORT(pin_beep_sample, pin beep sample); - * @endcode - * - * @ingroup Drivers - */ - -/*! - * @addtogroup Pin - * @{ - */ -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef RT_USING_DM -#include - -struct rt_pin_irqchip -{ - struct rt_pic parent; - - int irq; - rt_base_t pin_range[2]; -}; - -struct rt_pin_irq_hdr; -#endif /* RT_USING_DM */ - -/** - * @brief pin device structure - */ -struct rt_device_pin -{ - struct rt_device parent; -#ifdef RT_USING_DM - /* MUST keep the order member after parent */ - struct rt_pin_irqchip irqchip; - /* Fill by DM */ - rt_base_t pin_start; - rt_size_t pin_nr; - rt_list_t list; - struct rt_pin_irq_hdr *legacy_isr; -#endif /* RT_USING_DM */ - const struct rt_pin_ops *ops; -}; - -#define PIN_NONE (-1) - -#define PIN_LOW 0x00 /*!< low level */ -#define PIN_HIGH 0x01 /*!< high level */ - -#define PIN_MODE_OUTPUT 0x00 /*!< output mode */ -#define PIN_MODE_INPUT 0x01 /*!< input mode */ -#define PIN_MODE_INPUT_PULLUP 0x02 /*!< input mode with pull-up */ -#define PIN_MODE_INPUT_PULLDOWN 0x03 /*!< input mode with pull-down */ -#define PIN_MODE_OUTPUT_OD 0x04 /*!< output mode with open-drain */ - -#ifdef RT_USING_PINCTRL -enum -{ - PIN_CONFIG_BIAS_BUS_HOLD, - PIN_CONFIG_BIAS_DISABLE, - PIN_CONFIG_BIAS_HIGH_IMPEDANCE, - PIN_CONFIG_BIAS_PULL_DOWN, - PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, - PIN_CONFIG_BIAS_PULL_UP, - PIN_CONFIG_DRIVE_OPEN_DRAIN, - PIN_CONFIG_DRIVE_OPEN_SOURCE, - PIN_CONFIG_DRIVE_PUSH_PULL, - PIN_CONFIG_DRIVE_STRENGTH, - PIN_CONFIG_DRIVE_STRENGTH_UA, - PIN_CONFIG_INPUT_DEBOUNCE, - PIN_CONFIG_INPUT_ENABLE, - PIN_CONFIG_INPUT_SCHMITT, - PIN_CONFIG_INPUT_SCHMITT_ENABLE, - PIN_CONFIG_MODE_LOW_POWER, - PIN_CONFIG_MODE_PWM, - PIN_CONFIG_OUTPUT, - PIN_CONFIG_OUTPUT_ENABLE, - PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS, - PIN_CONFIG_PERSIST_STATE, - PIN_CONFIG_POWER_SOURCE, - PIN_CONFIG_SKEW_DELAY, - PIN_CONFIG_SLEEP_HARDWARE_STATE, - PIN_CONFIG_SLEW_RATE, - PIN_CONFIG_END = 0x7f, - PIN_CONFIG_MAX = 0xff, -}; -#endif /* RT_USING_PINCTRL */ - -#define PIN_IRQ_MODE_RISING 0x00 /*!< rising edge trigger */ -#define PIN_IRQ_MODE_FALLING 0x01 /*!< falling edge trigger */ -#define PIN_IRQ_MODE_RISING_FALLING 0x02 /*!< rising and falling edge trigger */ -#define PIN_IRQ_MODE_HIGH_LEVEL 0x03 /*!< high level trigger */ -#define PIN_IRQ_MODE_LOW_LEVEL 0x04 /*!< low level trigger */ - -#define PIN_IRQ_DISABLE 0x00 /*!< disable irq */ -#define PIN_IRQ_ENABLE 0x01 /*!< enable irq */ - -#define PIN_IRQ_PIN_NONE PIN_NONE /*!< no pin irq */ - -/** - * @brief pin mode structure - */ -struct rt_device_pin_mode -{ - rt_base_t pin; - rt_uint8_t mode; /* e.g. PIN_MODE_OUTPUT */ -}; - -/** - * @brief pin value structure - */ -struct rt_device_pin_value -{ - rt_base_t pin; - rt_uint8_t value; /* PIN_LOW or PIN_HIGH */ -}; - -/** - * @brief pin irq structure - */ -struct rt_pin_irq_hdr -{ - rt_base_t pin; - rt_uint8_t mode; /* e.g. PIN_IRQ_MODE_RISING */ - void (*hdr)(void *args); - void *args; -}; - -#ifdef RT_USING_PINCTRL -/** - * @brief pin control configure structure - */ -struct rt_pin_ctrl_conf_params -{ - const char *propname; - rt_uint32_t param; - rt_uint32_t default_value; -}; -#endif /* RT_USING_PINCTRL */ - -/** - * @brief pin device operations - */ -struct rt_pin_ops -{ - void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_uint8_t mode); - void (*pin_write)(struct rt_device *device, rt_base_t pin, rt_uint8_t value); - rt_ssize_t (*pin_read)(struct rt_device *device, rt_base_t pin); - rt_err_t (*pin_attach_irq)(struct rt_device *device, rt_base_t pin, - rt_uint8_t mode, void (*hdr)(void *args), void *args); - rt_err_t (*pin_detach_irq)(struct rt_device *device, rt_base_t pin); - rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled); - rt_base_t (*pin_get)(const char *name); - rt_err_t (*pin_debounce)(struct rt_device *device, rt_base_t pin, rt_uint32_t debounce); -#ifdef RT_USING_DM - rt_err_t (*pin_irq_mode)(struct rt_device *device, rt_base_t pin, rt_uint8_t mode); - rt_ssize_t (*pin_parse)(struct rt_device *device, struct rt_ofw_cell_args *args, rt_uint32_t *flags); -#endif -#ifdef RT_USING_PINCTRL - rt_err_t (*pin_ctrl_confs_apply)(struct rt_device *device, void *fw_conf_np); -#endif /* RT_USING_PINCTRL */ -}; - -/** - * @brief register a pin device - * @param name the name of pin device - * @param ops the operations of pin device - * @param user_data the user data of pin device - * @return int error code - */ -int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data); - -/** - * @brief set pin mode - * @param pin the pin number - * @param mode the pin mode - */ -void rt_pin_mode(rt_base_t pin, rt_uint8_t mode); - -/** - * @brief write pin value - * @param pin the pin number - * @param value the pin value - */ -void rt_pin_write(rt_base_t pin, rt_ssize_t value); - -/** - * @brief read pin value - * @param pin the pin number - * @return rt_ssize_t the pin value - */ -rt_ssize_t rt_pin_read(rt_base_t pin); - -/** - * @brief get pin number by name - * @param name the pin name - * @return rt_base_t the pin number - */ -rt_base_t rt_pin_get(const char *name); - -/** - * @brief bind the pin interrupt callback function - * @param pin the pin number - * @param mode the irq mode - * @param hdr the irq callback function - * @param args the argument of the callback function - * @return rt_err_t error code - */ -rt_err_t rt_pin_attach_irq(rt_base_t pin, rt_uint8_t mode, - void (*hdr)(void *args), void *args); - -/** - * @brief detach the pin interrupt callback function - * @param pin the pin number - * @return rt_err_t error code - */ -rt_err_t rt_pin_detach_irq(rt_base_t pin); - -/** - * @brief enable or disable the pin interrupt - * @param pin the pin number - * @param enabled PIN_IRQ_ENABLE or PIN_IRQ_DISABLE - * @return rt_err_t error code - */ -rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint8_t enabled); - -/** - * @brief set the pin's debounce time - * @param pin the pin number - * @param debounce time - * @return rt_err_t error code - */ -rt_err_t rt_pin_debounce(rt_base_t pin, rt_uint32_t debounce); - -#ifdef RT_USING_DM -rt_ssize_t rt_pin_get_named_pin(struct rt_device *dev, const char *propname, int index, - rt_uint8_t *out_mode, rt_uint8_t *out_value); -rt_ssize_t rt_pin_get_named_pin_count(struct rt_device *dev, const char *propname); - -#ifdef RT_USING_OFW -rt_ssize_t rt_ofw_get_named_pin(struct rt_ofw_node *np, const char *propname, int index, - rt_uint8_t *out_mode, rt_uint8_t *out_value); -rt_ssize_t rt_ofw_get_named_pin_count(struct rt_ofw_node *np, const char *propname); -#endif -#endif /* RT_USING_DM */ - -#ifdef RT_USING_PINCTRL -rt_ssize_t rt_pin_ctrl_confs_lookup(struct rt_device *device, const char *name); -rt_err_t rt_pin_ctrl_confs_apply(struct rt_device *device, int index); -rt_err_t rt_pin_ctrl_confs_apply_by_name(struct rt_device *device, const char *name); -#endif /* RT_USING_PINCTRL */ - -#ifdef __cplusplus -} -#endif - -/*! @}*/ - -#endif diff --git a/rt-thread/components/drivers/include/drivers/dev_pwm.h b/rt-thread/components/drivers/include/drivers/dev_pwm.h deleted file mode 100644 index 1e0970f..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_pwm.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-05-07 aozima the first version - * 2022-09-24 yuqi add phase and dead time configuration - */ - -#ifndef __DEV_PWM_H__ -#define __DEV_PWM_H__ - -#include -/** - * @addtogroup Drivers RTTHREAD Driver - * @defgroup PWM PWM - * - * @brief PWM driver api - * - * Example - * @code {.c} - * #include - * #include - * - * #define PWM_DEV_NAME "pwm3" // PWM设备名称 - * #define PWM_DEV_CHANNEL 4 // PWM通道 - * - * struct rt_device_pwm *pwm_dev; // PWM设备句柄 - * - * static int pwm_led_sample(int argc, char *argv[]) - * { - * rt_uint32_t period, pulse, dir; - * - * period = 500000; // 周期为0.5ms,单位为纳秒ns - * dir = 1; // PWM脉冲宽度值的增减方向 - * pulse = 0; // PWM脉冲宽度值,单位为纳秒ns - * - * // 查找设备 - * pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME); - * if (pwm_dev == RT_NULL) - * { - * rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME); - * return -RT_ERROR; - * } - * - * // 设置PWM周期和脉冲宽度默认值 - * rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse); - * // 使能设备 - * rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL); - * - * while (1) - * { - * rt_thread_mdelay(50); - * if (dir) - * { - * pulse += 5000; // 从0值开始每次增加5000ns - * } - * else - * { - * pulse -= 5000; // 从最大值开始每次减少5000ns - * } - * if (pulse >= period) - * { - * dir = 0; - * } - * if (0 == pulse) - * { - * dir = 1; - * } - * - * // 设置PWM周期和脉冲宽度 - * rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse); - * } - * } - * - * MSH_CMD_EXPORT(pwm_led_sample, pwm sample); - * @endcode - * - * @ingroup Drivers - */ - -/*! - * @addtogroup PWM - * @{ - */ -#define PWM_CMD_ENABLE (RT_DEVICE_CTRL_BASE(PWM) + 0) -#define PWM_CMD_DISABLE (RT_DEVICE_CTRL_BASE(PWM) + 1) -#define PWM_CMD_SET (RT_DEVICE_CTRL_BASE(PWM) + 2) -#define PWM_CMD_GET (RT_DEVICE_CTRL_BASE(PWM) + 3) -#define PWMN_CMD_ENABLE (RT_DEVICE_CTRL_BASE(PWM) + 4) -#define PWMN_CMD_DISABLE (RT_DEVICE_CTRL_BASE(PWM) + 5) -#define PWM_CMD_SET_PERIOD (RT_DEVICE_CTRL_BASE(PWM) + 6) -#define PWM_CMD_SET_PULSE (RT_DEVICE_CTRL_BASE(PWM) + 7) -#define PWM_CMD_SET_DEAD_TIME (RT_DEVICE_CTRL_BASE(PWM) + 8) -#define PWM_CMD_SET_PHASE (RT_DEVICE_CTRL_BASE(PWM) + 9) -#define PWM_CMD_ENABLE_IRQ (RT_DEVICE_CTRL_BASE(PWM) + 10) -#define PWM_CMD_DISABLE_IRQ (RT_DEVICE_CTRL_BASE(PWM) + 11) - -/** - * @brief PWM configuration - */ -struct rt_pwm_configuration -{ - rt_uint32_t channel; /* 0 ~ n or 0 ~ -n, which depends on specific MCU requirements */ - rt_uint32_t period; /* unit:ns 1ns~4.29s:1Ghz~0.23hz */ - rt_uint32_t pulse; /* unit:ns (pulse<=period) */ - rt_uint32_t dead_time; /* unit:ns */ - rt_uint32_t phase; /*unit: degree, 0~360, which is the phase of pwm output, */ - /* - * RT_TRUE : The channel of pwm is complememtary. - * RT_FALSE : The channel of pwm is nomal. - */ - rt_bool_t complementary; -}; - -struct rt_device_pwm; -/** - * @brief PWM operations - */ -struct rt_pwm_ops -{ - rt_err_t (*control)(struct rt_device_pwm *device, int cmd, void *arg); -}; - -/** - * @brief PWM device - */ -struct rt_device_pwm -{ - struct rt_device parent; - const struct rt_pwm_ops *ops; -}; -/** - * @brief register a PWM device - * @param device the PWM device - * @param name the name of PWM device - * @param ops the operations of PWM device - * @param user_data the user data of PWM device - * @return rt_err_t error code - */ -rt_err_t rt_device_pwm_register(struct rt_device_pwm *device, const char *name, const struct rt_pwm_ops *ops, const void *user_data); - -/** - * @brief enable the PWM channel - * @param device the PWM device - * @param channel the channel of PWM - * @return rt_err_t error code - */ -rt_err_t rt_pwm_enable(struct rt_device_pwm *device, int channel); - -/** - * @brief disable the PWM channel - * @param device the PWM device - * @param channel the channel of PWM - * @return rt_err_t error code - */ -rt_err_t rt_pwm_disable(struct rt_device_pwm *device, int channel); - -/** - * @brief set the PWM channel - * @param device the PWM device - * @param channel the channel of PWM - * @param period the period of PWM - * @param pulse the pulse of PWM - * @return rt_err_t error code - */ -rt_err_t rt_pwm_set(struct rt_device_pwm *device, int channel, rt_uint32_t period, rt_uint32_t pulse); - -/** - * @brief set the PWM channel period - * @param device the PWM device - * @param channel the channel of PWM - * @param period the period of PWM - * @return rt_err_t error code -*/ -rt_err_t rt_pwm_set_period(struct rt_device_pwm *device, int channel, rt_uint32_t period); - -/** - * @brief set the PWM channel pulse - * @param device the PWM device - * @param channel the channel of PWM - * @param pulse the period of PWM - * @return rt_err_t error code -*/ -rt_err_t rt_pwm_set_pulse(struct rt_device_pwm *device, int channel, rt_uint32_t pulse); - -/** - * @brief set the dead zone time of PWM - * @param device the PWM device - * @param channel the channel of PWM - * @param dead_time dead zone time - * @return rt_err_t error code -*/ -rt_err_t rt_pwm_set_dead_time(struct rt_device_pwm *device, int channel, rt_uint32_t dead_time); - -/** - * @brief set the phase of PWM - * @param device the PWM device - * @param channel the channel of PWM - * @param phase phase - * @return rt_err_t error code -*/ -rt_err_t rt_pwm_set_phase(struct rt_device_pwm *device, int channel, rt_uint32_t phase); - -/*! @}*/ - -#endif /* __DEV_PWM_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/dev_rtc.h b/rt-thread/components/drivers/include/drivers/dev_rtc.h deleted file mode 100644 index 740142d..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_rtc.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-10-10 aozima first version. - * 2021-06-11 iysheng implement RTC framework V2.0 - * 2021-07-30 Meco Man move rtc_core.h to rtc.h - * 2022-04-05 tyx add timestamp function - */ - -#ifndef __DEV_RTC_H__ -#define __DEV_RTC_H__ - -#include -#include -/** - * @addtogroup Drivers RTTHREAD Driver - * @defgroup RTC RTC - * - * @brief RTC driver api - * - * Example - * @code {.c} - * - * #include - * #include - * - * #define RTC_NAME "rtc" - * - * static int rtc_sample(int argc, char *argv[]) - * { - * rt_err_t ret = RT_EOK; - * time_t now; - * rt_device_t device = RT_NULL; - * - * device = rt_device_find(RTC_NAME); - * if (!device) - * { - * LOG_E("find %s failed!", RTC_NAME); - * return RT_ERROR; - * } - * - * if(rt_device_open(device, 0) != RT_EOK) - * { - * LOG_E("open %s failed!", RTC_NAME); - * return RT_ERROR; - * } - * - * ret = set_date(2018, 12, 3); - * if (ret != RT_EOK) - * { - * rt_kprintf("set RTC date failed\n"); - * return ret; - * } - * - * ret = set_time(11, 15, 50); - * if (ret != RT_EOK) - * { - * rt_kprintf("set RTC time failed\n"); - * return ret; - * } - * - * rt_thread_mdelay(3000); - * - * now = time(RT_NULL); - * rt_kprintf("%s\n", ctime(&now)); - * - * return ret; - * } - * MSH_CMD_EXPORT(rtc_sample, rtc sample); - * @endcode - * - * @ingroup Drivers - */ - -/*! - * @addtogroup RTC - * @{ - */ -#ifdef __cplusplus -extern "C" { -#endif - -#define RT_DEVICE_CTRL_RTC_GET_TIME (RT_DEVICE_CTRL_BASE(RTC) + 0x01) /**< get second time */ -#define RT_DEVICE_CTRL_RTC_SET_TIME (RT_DEVICE_CTRL_BASE(RTC) + 0x02) /**< set second time */ -#define RT_DEVICE_CTRL_RTC_GET_TIMEVAL (RT_DEVICE_CTRL_BASE(RTC) + 0x03) /**< get timeval for gettimeofday */ -#define RT_DEVICE_CTRL_RTC_SET_TIMEVAL (RT_DEVICE_CTRL_BASE(RTC) + 0x04) /**< set timeval for gettimeofday */ -#define RT_DEVICE_CTRL_RTC_GET_ALARM (RT_DEVICE_CTRL_BASE(RTC) + 0x05) /**< get alarm */ -#define RT_DEVICE_CTRL_RTC_SET_ALARM (RT_DEVICE_CTRL_BASE(RTC) + 0x06) /**< set alarm */ -#define RT_DEVICE_CTRL_RTC_GET_TIMESPEC (RT_DEVICE_CTRL_BASE(RTC) + 0x07) /**< get timespec for clock_gettime */ -#define RT_DEVICE_CTRL_RTC_SET_TIMESPEC (RT_DEVICE_CTRL_BASE(RTC) + 0x08) /**< set timespec for clock_settime */ -#define RT_DEVICE_CTRL_RTC_GET_TIMERES (RT_DEVICE_CTRL_BASE(RTC) + 0x09) /**< get resolution for clock_getres */ - -/** - * @brief RTC alarm structure - */ -struct rt_rtc_wkalarm -{ - rt_bool_t enable; /* 0 = alarm disabled, 1 = alarm enabled */ - rt_int32_t tm_sec; /* alarm at tm_sec */ - rt_int32_t tm_min; /* alarm at tm_min */ - rt_int32_t tm_hour; /* alarm at tm_hour */ - rt_int32_t tm_mday; /* alarm at tm_mday */ - rt_int32_t tm_mon; /* alarm at tm_mon */ - rt_int32_t tm_year; /* alarm at tm_year */ -}; -/** - * @brief RTC operations - */ -struct rt_rtc_ops -{ - rt_err_t (*init)(void); - rt_err_t (*get_secs)(time_t *sec); - rt_err_t (*set_secs)(time_t *sec); - rt_err_t (*get_alarm)(struct rt_rtc_wkalarm *alarm); - rt_err_t (*set_alarm)(struct rt_rtc_wkalarm *alarm); - rt_err_t (*get_timeval)(struct timeval *tv); - rt_err_t (*set_timeval)(struct timeval *tv); -}; - -/** - * @brief RTC device structure - */ -typedef struct rt_rtc_device -{ - struct rt_device parent; - const struct rt_rtc_ops *ops; -} rt_rtc_dev_t; - -/** - * @brief Register a RTC device - * - * @param rtc RTC device - * @param name RTC device name - * @param flag RTC device flag - * @param data RTC device data - * @return rt_err_t error code - */ -rt_err_t rt_hw_rtc_register(rt_rtc_dev_t *rtc, - const char *name, - rt_uint32_t flag, - void *data); - -/** - * @brief set date - * - * @param year year - * @param month month - * @param day day - * @return rt_err_t error code - */ -rt_err_t set_date(rt_uint32_t year, rt_uint32_t month, rt_uint32_t day); - -/** - * @brief set time - * - * @param hour hour - * @param minute minute - * @param second second - * @return rt_err_t error code -*/ -rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second); - -/** - * @brief set timestamp - * - * @param timestamp A pointer to time - * @return rt_err_t error code - */ -rt_err_t set_timestamp(time_t timestamp); - -/** - * @brief get timestamp - * - * @param timestamp A secondary pointer to time - * @return rt_err_t error code - */ -rt_err_t get_timestamp(time_t *timestamp); - -#ifdef RT_USING_SYSTEM_WORKQUEUE -rt_err_t rt_soft_rtc_sync(void); -rt_err_t rt_soft_rtc_set_source(const char *name); -#endif - -#ifdef __cplusplus -} -#endif - -/*! @}*/ - -#endif /* __DEV_RTC_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/dev_sd.h b/rt-thread/components/drivers/include/drivers/dev_sd.h deleted file mode 100644 index ca8bb0c..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_sd.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-07-25 weety first version - * 2024-05-26 HPMicro Add UHS-I support - */ - -#ifndef __DEV_SD_H__ -#define __DEV_SD_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * SWITCH_FUNC timing - */ -#define SD_SWITCH_FUNC_TIMING_DEFAULT 0 -#define SD_SWITCH_FUNC_TIMING_HS 1 -#define SD_SWITCH_FUNC_TIMING_SDR50 2 -#define SD_SWITCH_FUNC_TIMING_SDR104 3 -#define SD_SWITCH_FUNC_TIMING_DDR50 4 - - -rt_err_t mmcsd_send_if_cond(struct rt_mmcsd_host *host, rt_uint32_t ocr); -rt_err_t mmcsd_send_app_op_cond(struct rt_mmcsd_host *host, rt_uint32_t ocr, rt_uint32_t *rocr); - -rt_err_t mmcsd_get_card_addr(struct rt_mmcsd_host *host, rt_uint32_t *rca); -rt_int32_t mmcsd_get_scr(struct rt_mmcsd_card *card, rt_uint32_t *scr); - -rt_int32_t init_sd(struct rt_mmcsd_host *host, rt_uint32_t ocr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/components/drivers/include/drivers/dev_sdio.h b/rt-thread/components/drivers/include/drivers/dev_sdio.h deleted file mode 100644 index a8d30fd..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_sdio.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-01-15 weety first version - */ - -#ifndef __DEV_SDIO_H__ -#define __DEV_SDIO_H__ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Card Common Control Registers (CCCR) - */ - -#define SDIO_REG_CCCR_CCCR_REV 0x00 - -#define SDIO_CCCR_REV_1_00 0 /* CCCR/FBR Version 1.00 */ -#define SDIO_CCCR_REV_1_10 1 /* CCCR/FBR Version 1.10 */ -#define SDIO_CCCR_REV_1_20 2 /* CCCR/FBR Version 1.20 */ -#define SDIO_CCCR_REV_3_00 3 /* CCCR/FBR Version 2.00 */ - -#define SDIO_SDIO_REV_1_00 0 /* SDIO Spec Version 1.00 */ -#define SDIO_SDIO_REV_1_10 1 /* SDIO Spec Version 1.10 */ -#define SDIO_SDIO_REV_1_20 2 /* SDIO Spec Version 1.20 */ -#define SDIO_SDIO_REV_2_00 3 /* SDIO Spec Version 2.00 */ - -#define SDIO_REG_CCCR_SD_REV 0x01 - -#define SDIO_SD_REV_1_01 0 /* SD Physical Spec Version 1.01 */ -#define SDIO_SD_REV_1_10 1 /* SD Physical Spec Version 1.10 */ -#define SDIO_SD_REV_2_00 2 /* SD Physical Spec Version 2.00 */ - -#define SDIO_REG_CCCR_IO_EN 0x02 -#define SDIO_REG_CCCR_IO_RDY 0x03 - -#define SDIO_REG_CCCR_INT_EN 0x04 /* Function/Master Interrupt Enable */ -#define SDIO_REG_CCCR_INT_PEND 0x05 /* Function Interrupt Pending */ - -#define SDIO_REG_CCCR_IO_ABORT 0x06 /* function abort/card reset */ - -#define SDIO_REG_CCCR_BUS_IF 0x07 /* bus interface controls */ - -#define SDIO_BUS_WIDTH_1BIT 0x00 -#define SDIO_BUS_WIDTH_4BIT 0x02 -#define SDIO_BUS_ECSI 0x20 /* Enable continuous SPI interrupt */ -#define SDIO_BUS_SCSI 0x40 /* Support continuous SPI interrupt */ - -#define SDIO_BUS_ASYNC_INT 0x20 - -#define SDIO_BUS_CD_DISABLE 0x80 /* disable pull-up on DAT3 (pin 1) */ - -#define SDIO_REG_CCCR_CARD_CAPS 0x08 - -#define SDIO_CCCR_CAP_SDC 0x01 /* can do CMD52 while data transfer */ -#define SDIO_CCCR_CAP_SMB 0x02 /* can do multi-block xfers (CMD53) */ -#define SDIO_CCCR_CAP_SRW 0x04 /* supports read-wait protocol */ -#define SDIO_CCCR_CAP_SBS 0x08 /* supports suspend/resume */ -#define SDIO_CCCR_CAP_S4MI 0x10 /* interrupt during 4-bit CMD53 */ -#define SDIO_CCCR_CAP_E4MI 0x20 /* enable ints during 4-bit CMD53 */ -#define SDIO_CCCR_CAP_LSC 0x40 /* low speed card */ -#define SDIO_CCCR_CAP_4BLS 0x80 /* 4 bit low speed card */ - -#define SDIO_REG_CCCR_CIS_PTR 0x09 /* common CIS pointer (3 bytes) */ - -/* Following 4 regs are valid only if SBS is set */ -#define SDIO_REG_CCCR_BUS_SUSPEND 0x0c -#define SDIO_REG_CCCR_FUNC_SEL 0x0d -#define SDIO_REG_CCCR_EXEC_FLAG 0x0e -#define SDIO_REG_CCCR_READY_FLAG 0x0f - -#define SDIO_REG_CCCR_FN0_BLKSIZE 0x10 /* 2bytes, 0x10~0x11 */ - -#define SDIO_REG_CCCR_POWER_CTRL 0x12 - -#define SDIO_POWER_SMPC 0x01 /* Supports Master Power Control */ -#define SDIO_POWER_EMPC 0x02 /* Enable Master Power Control */ - -#define SDIO_REG_CCCR_SPEED 0x13 - -#define SDIO_SPEED_SHS 0x01 /* Supports High-Speed mode */ -#define SDIO_SPEED_EHS 0x02 /* Enable High-Speed mode */ - -/* - * Function Basic Registers (FBR) - */ - -#define SDIO_REG_FBR_BASE(f) ((f) * 0x100) /* base of function f's FBRs */ - -#define SDIO_REG_FBR_STD_FUNC_IF 0x00 - -#define SDIO_FBR_SUPPORTS_CSA 0x40 /* supports Code Storage Area */ -#define SDIO_FBR_ENABLE_CSA 0x80 /* enable Code Storage Area */ - -#define SDIO_REG_FBR_STD_IF_EXT 0x01 - -#define SDIO_REG_FBR_POWER 0x02 - -#define SDIO_FBR_POWER_SPS 0x01 /* Supports Power Selection */ -#define SDIO_FBR_POWER_EPS 0x02 /* Enable (low) Power Selection */ - -#define SDIO_REG_FBR_CIS 0x09 /* CIS pointer (3 bytes) */ - - -#define SDIO_REG_FBR_CSA 0x0C /* CSA pointer (3 bytes) */ - -#define SDIO_REG_FBR_CSA_DATA 0x0F - -#define SDIO_REG_FBR_BLKSIZE 0x10 /* block size (2 bytes) */ - -/* SDIO CIS Tuple code */ -#define CISTPL_NULL 0x00 -#define CISTPL_CHECKSUM 0x10 -#define CISTPL_VERS_1 0x15 -#define CISTPL_ALTSTR 0x16 -#define CISTPL_MANFID 0x20 -#define CISTPL_FUNCID 0x21 -#define CISTPL_FUNCE 0x22 -#define CISTPL_SDIO_STD 0x91 -#define CISTPL_SDIO_EXT 0x92 -#define CISTPL_END 0xff - -/* SDIO device id */ -#define SDIO_ANY_FUNC_ID 0xff -#define SDIO_ANY_MAN_ID 0xffff -#define SDIO_ANY_PROD_ID 0xffff - -struct rt_sdio_device_id -{ - rt_uint8_t func_code; - rt_uint16_t manufacturer; - rt_uint16_t product; -}; - -struct rt_sdio_driver -{ - char *name; - rt_int32_t (*probe)(struct rt_mmcsd_card *card); - rt_int32_t (*remove)(struct rt_mmcsd_card *card); - struct rt_sdio_device_id *id; -}; - -rt_int32_t sdio_io_send_op_cond(struct rt_mmcsd_host *host, - rt_uint32_t ocr, - rt_uint32_t *cmd5_resp); -rt_int32_t sdio_io_rw_direct(struct rt_mmcsd_card *card, - rt_int32_t rw, - rt_uint32_t fn, - rt_uint32_t reg_addr, - rt_uint8_t *pdata, - rt_uint8_t raw); -rt_int32_t sdio_io_rw_extended(struct rt_mmcsd_card *card, - rt_int32_t rw, - rt_uint32_t fn, - rt_uint32_t addr, - rt_int32_t op_code, - rt_uint8_t *buf, - rt_uint32_t blocks, - rt_uint32_t blksize); -rt_int32_t sdio_io_rw_extended_block(struct rt_sdio_function *func, - rt_int32_t rw, - rt_uint32_t addr, - rt_int32_t op_code, - rt_uint8_t *buf, - rt_uint32_t len); -rt_uint8_t sdio_io_readb(struct rt_sdio_function *func, - rt_uint32_t reg, - rt_int32_t *err); -rt_int32_t sdio_io_writeb(struct rt_sdio_function *func, - rt_uint32_t reg, - rt_uint8_t data); -rt_uint16_t sdio_io_readw(struct rt_sdio_function *func, - rt_uint32_t addr, - rt_int32_t *err); -rt_int32_t sdio_io_writew(struct rt_sdio_function *func, - rt_uint16_t data, - rt_uint32_t addr); -rt_uint32_t sdio_io_readl(struct rt_sdio_function *func, - rt_uint32_t addr, - rt_int32_t *err); -rt_int32_t sdio_io_writel(struct rt_sdio_function *func, - rt_uint32_t data, - rt_uint32_t addr); -rt_int32_t sdio_io_read_multi_fifo_b(struct rt_sdio_function *func, - rt_uint32_t addr, - rt_uint8_t *buf, - rt_uint32_t len); -rt_int32_t sdio_io_write_multi_fifo_b(struct rt_sdio_function *func, - rt_uint32_t addr, - rt_uint8_t *buf, - rt_uint32_t len); -rt_int32_t sdio_io_read_multi_incr_b(struct rt_sdio_function *func, - rt_uint32_t addr, - rt_uint8_t *buf, - rt_uint32_t len); -rt_int32_t sdio_io_write_multi_incr_b(struct rt_sdio_function *func, - rt_uint32_t addr, - rt_uint8_t *buf, - rt_uint32_t len); -rt_int32_t init_sdio(struct rt_mmcsd_host *host, rt_uint32_t ocr); -rt_int32_t sdio_attach_irq(struct rt_sdio_function *func, - rt_sdio_irq_handler_t *handler); -rt_int32_t sdio_detach_irq(struct rt_sdio_function *func); -void sdio_irq_wakeup(struct rt_mmcsd_host *host); -rt_int32_t sdio_enable_func(struct rt_sdio_function *func); -rt_int32_t sdio_disable_func(struct rt_sdio_function *func); -void sdio_set_drvdata(struct rt_sdio_function *func, void *data); -void* sdio_get_drvdata(struct rt_sdio_function *func); -rt_int32_t sdio_set_block_size(struct rt_sdio_function *func, - rt_uint32_t blksize); -rt_int32_t sdio_register_driver(struct rt_sdio_driver *driver); -rt_int32_t sdio_unregister_driver(struct rt_sdio_driver *driver); -void rt_sdio_init(void); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/rt-thread/components/drivers/include/drivers/dev_serial.h b/rt-thread/components/drivers/include/drivers/dev_serial.h deleted file mode 100644 index b7f627e..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_serial.h +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-05-15 lgnq first version. - * 2012-05-28 bernard change interfaces - * 2013-02-20 bernard use RT_SERIAL_RB_BUFSZ to define - * the size of ring buffer. - */ - -#ifndef __DEV_SERIAL_H__ -#define __DEV_SERIAL_H__ - -#include -/** - * @addtogroup Drivers RTTHREAD Driver - * @defgroup Serial Serial - * - * @brief Serial driver api - * - * Example - * @code {.c} - * - * #include - * - * #define SAMPLE_UART_NAME "uart2" - * static struct rt_semaphore rx_sem; - * static rt_device_t serial; - * - * static rt_err_t uart_input(rt_device_t dev, rt_size_t size) - * { - * - * rt_sem_release(&rx_sem); - * - * return RT_EOK; - * } - * - * static void serial_thread_entry(void *parameter) - * { - * char ch; - * - * while (1) - * { - * - * while (rt_device_read(serial, -1, &ch, 1) != 1) - * { - * - * rt_sem_take(&rx_sem, RT_WAITING_FOREVER); - * } - * - * ch = ch + 1; - * rt_device_write(serial, 0, &ch, 1); - * } - * } - * - * static int uart_sample(int argc, char *argv[]) - * { - * rt_err_t ret = RT_EOK; - * char uart_name[RT_NAME_MAX]; - * char str[] = "hello RT-Thread!\r\n"; - * - * if (argc == 2) - * { - * rt_strncpy(uart_name, argv[1], RT_NAME_MAX); - * } - * else - * { - * rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX); - * } - * - * - * serial = rt_device_find(uart_name); - * if (!serial) - * { - * rt_kprintf("find %s failed!\n", uart_name); - * return -RT_ERROR; - * } - * - * - * rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); - * - * rt_device_open(serial, RT_DEVICE_FLAG_INT_RX); - * - * rt_device_set_rx_indicate(serial, uart_input); - * - * rt_device_write(serial, 0, str, (sizeof(str) - 1)); - * - * - * rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10); - * - * if (thread != RT_NULL) - * { - * rt_thread_startup(thread); - * } - * else - * { - * ret = -RT_ERROR; - * } - * - * return ret; - * } - * - * MSH_CMD_EXPORT(uart_sample, uart device sample); - * @endcode - * - * @ingroup Drivers - */ - - -/*! - * @addtogroup Serial - * @{ - */ -#define BAUD_RATE_2400 2400 -#define BAUD_RATE_4800 4800 -#define BAUD_RATE_9600 9600 -#define BAUD_RATE_19200 19200 -#define BAUD_RATE_38400 38400 -#define BAUD_RATE_57600 57600 -#define BAUD_RATE_115200 115200 -#define BAUD_RATE_230400 230400 -#define BAUD_RATE_460800 460800 -#define BAUD_RATE_500000 500000 -#define BAUD_RATE_576000 576000 -#define BAUD_RATE_921600 921600 -#define BAUD_RATE_1000000 1000000 -#define BAUD_RATE_1152000 1152000 -#define BAUD_RATE_1500000 1500000 -#define BAUD_RATE_2000000 2000000 -#define BAUD_RATE_2500000 2500000 -#define BAUD_RATE_3000000 3000000 -#define BAUD_RATE_3500000 3500000 -#define BAUD_RATE_4000000 4000000 - -#define DATA_BITS_5 5 -#define DATA_BITS_6 6 -#define DATA_BITS_7 7 -#define DATA_BITS_8 8 -#define DATA_BITS_9 9 - -#define STOP_BITS_1 0 -#define STOP_BITS_2 1 -#define STOP_BITS_3 2 -#define STOP_BITS_4 3 - -#ifdef _WIN32 -#include -#else -#define PARITY_NONE 0 -#define PARITY_ODD 1 -#define PARITY_EVEN 2 -#endif - -#define BIT_ORDER_LSB 0 -#define BIT_ORDER_MSB 1 - -#define NRZ_NORMAL 0 /* Non Return to Zero : normal mode */ -#define NRZ_INVERTED 1 /* Non Return to Zero : inverted mode */ - -#ifndef RT_SERIAL_RB_BUFSZ -#define RT_SERIAL_RB_BUFSZ 64 -#endif - -#define RT_SERIAL_EVENT_RX_IND 0x01 /* Rx indication */ -#define RT_SERIAL_EVENT_TX_DONE 0x02 /* Tx complete */ -#define RT_SERIAL_EVENT_RX_DMADONE 0x03 /* Rx DMA transfer done */ -#define RT_SERIAL_EVENT_TX_DMADONE 0x04 /* Tx DMA transfer done */ -#define RT_SERIAL_EVENT_RX_TIMEOUT 0x05 /* Rx timeout */ - -#define RT_SERIAL_DMA_RX 0x01 -#define RT_SERIAL_DMA_TX 0x02 - -#define RT_SERIAL_RX_INT 0x01 -#define RT_SERIAL_TX_INT 0x02 - -#define RT_SERIAL_ERR_OVERRUN 0x01 -#define RT_SERIAL_ERR_FRAMING 0x02 -#define RT_SERIAL_ERR_PARITY 0x03 - -#define RT_SERIAL_TX_DATAQUEUE_SIZE 2048 -#define RT_SERIAL_TX_DATAQUEUE_LWM 30 - -#define RT_SERIAL_FLOWCONTROL_CTSRTS 1 -#define RT_SERIAL_FLOWCONTROL_NONE 0 - -/* Default config for serial_configure structure */ -#define RT_SERIAL_CONFIG_DEFAULT \ -{ \ - BAUD_RATE_115200, /* 115200 bits/s */ \ - DATA_BITS_8, /* 8 databits */ \ - STOP_BITS_1, /* 1 stopbit */ \ - PARITY_NONE, /* No parity */ \ - BIT_ORDER_LSB, /* LSB first sent */ \ - NRZ_NORMAL, /* Normal mode */ \ - RT_SERIAL_RB_BUFSZ, /* Buffer size */ \ - RT_SERIAL_FLOWCONTROL_NONE, /* Off flowcontrol */ \ - 0 \ -} - -/** - * @brief Sets a hook function when RX indicate is called - * - */ -typedef void (*rt_hw_serial_rxind_hookproto_t)(rt_device_t dev, rt_size_t size); -RT_OBJECT_HOOKLIST_DECLARE(rt_hw_serial_rxind_hookproto_t, rt_hw_serial_rxind); - -struct serial_configure -{ - rt_uint32_t baud_rate; - - rt_uint32_t data_bits :4; - rt_uint32_t stop_bits :2; - rt_uint32_t parity :2; - rt_uint32_t bit_order :1; - rt_uint32_t invert :1; - rt_uint32_t bufsz :16; - rt_uint32_t flowcontrol :1; - rt_uint32_t reserved :5; -}; - -/* - * Serial FIFO mode - */ -struct rt_serial_rx_fifo -{ - /* software fifo */ - rt_uint8_t *buffer; - - rt_uint16_t put_index, get_index; - - rt_bool_t is_full; -}; - -struct rt_serial_tx_fifo -{ - struct rt_completion completion; -}; - -/* - * Serial DMA mode - */ -struct rt_serial_rx_dma -{ - rt_bool_t activated; -}; - -struct rt_serial_tx_dma -{ - rt_bool_t activated; - struct rt_data_queue data_queue; -}; - -struct rt_serial_device -{ - struct rt_device parent; - - const struct rt_uart_ops *ops; - struct serial_configure config; - - void *serial_rx; - void *serial_tx; - - struct rt_spinlock spinlock; -#ifdef RT_USING_SERIAL_BYPASS - struct rt_serial_bypass* bypass; -#endif - struct rt_device_notify rx_notify; -}; -typedef struct rt_serial_device rt_serial_t; - -/** - * @brief Configure the serial device - */ -struct rt_uart_ops -{ - rt_err_t (*configure)(struct rt_serial_device *serial, struct serial_configure *cfg); - rt_err_t (*control)(struct rt_serial_device *serial, int cmd, void *arg); - - int (*putc)(struct rt_serial_device *serial, char c); - int (*getc)(struct rt_serial_device *serial); - - rt_ssize_t (*dma_transmit)(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction); -}; - -/** - * @brief Serial interrupt service routine - * @param serial serial device - * @param event event mask - * @ingroup Serial - */ -void rt_hw_serial_isr(struct rt_serial_device *serial, int event); - -/** - * @brief Register a serial device to device list - * - * @param serial serial device - * @param name device name - * @param flag device flag - * @param data device private data - * @return rt_err_t error code - * @note This function will register a serial device to system device list, - * and add a device object to system object list. - * @ingroup Serial - */ -rt_err_t rt_hw_serial_register(struct rt_serial_device *serial, - const char *name, - rt_uint32_t flag, - void *data); - -/** - * @brief register a serial device to system device list and add a device object to system object list - * - * @param serial serial device - * @return rt_err_t error code - * - * @ingroup Serial - */ -rt_err_t rt_hw_serial_register_tty(struct rt_serial_device *serial); - -/*! @}*/ - -#endif diff --git a/rt-thread/components/drivers/include/drivers/dev_serial_v2.h b/rt-thread/components/drivers/include/drivers/dev_serial_v2.h deleted file mode 100644 index 0bdc51b..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_serial_v2.h +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-06-01 KyleChan first version - */ - -#ifndef __DEV_SERIAL_V2_H__ -#define __DEV_SERIAL_V2_H__ - -#include - - -/** - * @addtogroup Drivers RTTHREAD Driver - * @defgroup Serial_v2 Serial v2 - * - * @brief Serial v2 driver api - * - * Example - * @code {.c} - * - * #include - * #include - * - * #define SAMPLE_UART_NAME "uart1" - * - * struct rx_msg - * { - * rt_device_t dev; - * rt_size_t size; - * }; - * static rt_device_t serial; - * static struct rt_messagequeue rx_mq; - * - * static rt_err_t uart_input(rt_device_t dev, rt_size_t size) - * { - * struct rx_msg msg; - * rt_err_t result; - * msg.dev = dev; - * msg.size = size; - * - * result = rt_mq_send(&rx_mq, &msg, sizeof(msg)); - * if (result == -RT_EFULL) - * { - * rt_kprintf("message queue full!\n"); - * } - * return result; - * } - * - * static void serial_thread_entry(void *parameter) - * { - * struct rx_msg msg; - * rt_err_t result; - * rt_uint32_t rx_length; - * static char rx_buffer[BSP_UART1_RX_BUFSIZE + 1]; - * - * while (1) - * { - * rt_memset(&msg, 0, sizeof(msg)); - * result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER); - * if (result > 0) - * { - * rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size); - * rx_buffer[rx_length] = '\0'; - * rt_device_write(serial, 0, rx_buffer, rx_length); - * rt_kprintf("%s\n",rx_buffer); - * } - * } - * } - * - * static int uart_dma_sample(int argc, char *argv[]) - * { - * rt_err_t ret = RT_EOK; - * char uart_name[RT_NAME_MAX]; - * static char msg_pool[256]; - * char str[] = "hello RT-Thread!\r\n"; - * - * if (argc == 2) - * { - * rt_strncpy(uart_name, argv[1], RT_NAME_MAX); - * } - * else - * { - * rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX); - * } - * - * serial = rt_device_find(uart_name); - * if (!serial) - * { - * rt_kprintf("find %s failed!\n", uart_name); - * return RT_ERROR; - * } - * - * rt_mq_init(&rx_mq, "rx_mq", - * msg_pool, - * sizeof(struct rx_msg), - * sizeof(msg_pool), - * RT_IPC_FLAG_FIFO); - * - * rt_device_open(serial, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING); - * rt_device_set_rx_indicate(serial, uart_input); - * rt_device_write(serial, 0, str, (sizeof(str) - 1)); - * - * rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10); - * if (thread != RT_NULL) - * { - * rt_thread_startup(thread); - * } - * else - * { - * ret = RT_ERROR; - * } - * - * return ret; - * } - * MSH_CMD_EXPORT(uart_dma_sample, uart device dma sample); - * @endcode - * - * @ingroup Drivers - */ - - -/*! - * @addtogroup Serial_v2 - * @{ - */ - -#define BAUD_RATE_2400 2400 -#define BAUD_RATE_4800 4800 -#define BAUD_RATE_9600 9600 -#define BAUD_RATE_19200 19200 -#define BAUD_RATE_38400 38400 -#define BAUD_RATE_57600 57600 -#define BAUD_RATE_115200 115200 -#define BAUD_RATE_230400 230400 -#define BAUD_RATE_460800 460800 -#define BAUD_RATE_500000 500000 -#define BAUD_RATE_921600 921600 -#define BAUD_RATE_2000000 2000000 -#define BAUD_RATE_2500000 2500000 -#define BAUD_RATE_3000000 3000000 - -#define DATA_BITS_5 5 -#define DATA_BITS_6 6 -#define DATA_BITS_7 7 -#define DATA_BITS_8 8 -#define DATA_BITS_9 9 - -#define STOP_BITS_1 0 -#define STOP_BITS_2 1 -#define STOP_BITS_3 2 -#define STOP_BITS_4 3 - -#ifdef _WIN32 -#include -#else -#define PARITY_NONE 0 -#define PARITY_ODD 1 -#define PARITY_EVEN 2 -#endif - -#define BIT_ORDER_LSB 0 -#define BIT_ORDER_MSB 1 - -#define NRZ_NORMAL 0 /* Non Return to Zero : normal mode */ -#define NRZ_INVERTED 1 /* Non Return to Zero : inverted mode */ - -#define RT_DEVICE_FLAG_RX_BLOCKING 0x1000 -#define RT_DEVICE_FLAG_RX_NON_BLOCKING 0x2000 - -#define RT_DEVICE_FLAG_TX_BLOCKING 0x4000 -#define RT_DEVICE_FLAG_TX_NON_BLOCKING 0x8000 - -#define RT_SERIAL_RX_BLOCKING RT_DEVICE_FLAG_RX_BLOCKING -#define RT_SERIAL_RX_NON_BLOCKING RT_DEVICE_FLAG_RX_NON_BLOCKING -#define RT_SERIAL_TX_BLOCKING RT_DEVICE_FLAG_TX_BLOCKING -#define RT_SERIAL_TX_NON_BLOCKING RT_DEVICE_FLAG_TX_NON_BLOCKING - -#define RT_DEVICE_CHECK_OPTMODE 0x20 - -#define RT_SERIAL_EVENT_RX_IND 0x01 /* Rx indication */ -#define RT_SERIAL_EVENT_TX_DONE 0x02 /* Tx complete */ -#define RT_SERIAL_EVENT_RX_DMADONE 0x03 /* Rx DMA transfer done */ -#define RT_SERIAL_EVENT_TX_DMADONE 0x04 /* Tx DMA transfer done */ -#define RT_SERIAL_EVENT_RX_TIMEOUT 0x05 /* Rx timeout */ - -#define RT_SERIAL_ERR_OVERRUN 0x01 -#define RT_SERIAL_ERR_FRAMING 0x02 -#define RT_SERIAL_ERR_PARITY 0x03 - -#define RT_SERIAL_TX_DATAQUEUE_SIZE 2048 -#define RT_SERIAL_TX_DATAQUEUE_LWM 30 - -#define RT_SERIAL_RX_MINBUFSZ 64 -#define RT_SERIAL_TX_MINBUFSZ 64 - -#define RT_SERIAL_TX_BLOCKING_BUFFER 1 -#define RT_SERIAL_TX_BLOCKING_NO_BUFFER 0 - -#define RT_SERIAL_FLOWCONTROL_CTSRTS 1 -#define RT_SERIAL_FLOWCONTROL_NONE 0 - -/* Default config for serial_configure structure */ -#define RT_SERIAL_CONFIG_DEFAULT \ -{ \ - BAUD_RATE_115200, /* 115200 bits/s */ \ - DATA_BITS_8, /* 8 databits */ \ - STOP_BITS_1, /* 1 stopbit */ \ - PARITY_NONE, /* No parity */ \ - BIT_ORDER_LSB, /* LSB first sent */ \ - NRZ_NORMAL, /* Normal mode */ \ - RT_SERIAL_RX_MINBUFSZ, /* rxBuf size */ \ - RT_SERIAL_TX_MINBUFSZ, /* txBuf size */ \ - RT_SERIAL_FLOWCONTROL_NONE, /* Off flowcontrol */ \ - 0 \ -} - -/** - * @brief Serial receive indicate hook function type - * - */ -typedef void (*rt_hw_serial_rxind_hookproto_t)(rt_device_t dev, rt_size_t size); -RT_OBJECT_HOOKLIST_DECLARE(rt_hw_serial_rxind_hookproto_t, rt_hw_serial_rxind); - -struct serial_configure -{ - rt_uint32_t baud_rate; - - rt_uint32_t data_bits :4; - rt_uint32_t stop_bits :2; - rt_uint32_t parity :2; - rt_uint32_t bit_order :1; - rt_uint32_t invert :1; - rt_uint32_t rx_bufsz :16; - rt_uint32_t tx_bufsz :16; - rt_uint32_t flowcontrol :1; - rt_uint32_t reserved :5; -}; - -/** - * @brief Serial Receive FIFO mode - */ -struct rt_serial_rx_fifo -{ - struct rt_ringbuffer rb; - - struct rt_completion rx_cpt; - - rt_uint16_t rx_cpt_index; - - /* software fifo */ - rt_uint8_t buffer[]; -}; - -/** - * @brief Serial Transmit FIFO mode - * - */ -struct rt_serial_tx_fifo -{ - struct rt_ringbuffer rb; - - rt_size_t put_size; - - rt_bool_t activated; - - struct rt_completion tx_cpt; - - /* software fifo */ - rt_uint8_t buffer[]; -}; - -/** - * @brief serial device structure - * - */ -struct rt_serial_device -{ - struct rt_device parent; - - const struct rt_uart_ops *ops; - struct serial_configure config; - - void *serial_rx; - void *serial_tx; - - struct rt_device_notify rx_notify; -}; - -/** - * @brief uart device operations - * - */ -struct rt_uart_ops -{ - rt_err_t (*configure)(struct rt_serial_device *serial, - struct serial_configure *cfg); - - rt_err_t (*control)(struct rt_serial_device *serial, - int cmd, - void *arg); - - int (*putc)(struct rt_serial_device *serial, char c); - int (*getc)(struct rt_serial_device *serial); - - rt_ssize_t (*transmit)(struct rt_serial_device *serial, - rt_uint8_t *buf, - rt_size_t size, - rt_uint32_t tx_flag); -}; - -/** - * @brief Serial interrupt service routine - * @param serial serial device - * @param event event mask - * @ingroup Serial_v2 - */ -void rt_hw_serial_isr(struct rt_serial_device *serial, int event); - - -/** - * @brief Register a serial device to device list - * - * @param serial serial device - * @param name device name - * @param flag device flag - * @param data device private data - * @return rt_err_t error code - * @note This function will register a serial device to system device list, - * and add a device object to system object list. - * @ingroup Serial_v2 - */ -rt_err_t rt_hw_serial_register(struct rt_serial_device *serial, - const char *name, - rt_uint32_t flag, - void *data); - -/** - * @brief register a serial device to system device list and add a device object to system object list - * - * @param serial serial device - * @return rt_err_t error code - * - * @ingroup Serial_v2 - */ -rt_err_t rt_hw_serial_register_tty(struct rt_serial_device *serial); - - -/*! @}*/ - -#endif diff --git a/rt-thread/components/drivers/include/drivers/dev_spi.h b/rt-thread/components/drivers/include/drivers/dev_spi.h deleted file mode 100644 index 0aa08c4..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_spi.h +++ /dev/null @@ -1,633 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-11-23 Bernard Add extern "C" - * 2020-06-13 armink fix the 3 wires issue - * 2022-09-01 liYony fix api rt_spi_sendrecv16 about MSB and LSB bug - */ - -#ifndef __DEV_SPI_H__ -#define __DEV_SPI_H__ - -#include -#include -#include -#include - -/** - * @addtogroup Drivers RTTHREAD Driver - * @defgroup SPI SPI - * - * @brief SPI driver api - * - * Example - * @code {.c} - * #include - * #include - * - * #define W25Q_SPI_DEVICE_NAME "qspi10" - * - * static void spi_w25q_sample(int argc, char *argv[]) - * { - * struct rt_spi_device *spi_dev_w25q; - * char name[RT_NAME_MAX]; - * rt_uint8_t w25x_read_id = 0x90; - * rt_uint8_t id[5] = {0}; - * - * if (argc == 2) - * { - * rt_strncpy(name, argv[1], RT_NAME_MAX); - * } - * else - * { - * rt_strncpy(name, W25Q_SPI_DEVICE_NAME, RT_NAME_MAX); - * } - * - * // 查找 spi 设备获取设备句柄 - * spi_dev_w25q = (struct rt_spi_device *)rt_device_find(name); - * if (!spi_dev_w25q) - * { - * rt_kprintf("spi sample run failed! can't find %s device!\n", name); - * } - * else - * { - * // 方式1:使用 rt_spi_send_then_recv()发送命令读取ID - * rt_spi_send_then_recv(spi_dev_w25q, &w25x_read_id, 1, id, 5); - * rt_kprintf("use rt_spi_send_then_recv() read w25q ID is:%x%x\n", id[3], id[4]); - * - * // 方式2:使用 rt_spi_transfer_message()发送命令读取ID - * struct rt_spi_message msg1, msg2; - * - * msg1.send_buf = &w25x_read_id; - * msg1.recv_buf = RT_NULL; - * msg1.length = 1; - * msg1.cs_take = 1; - * msg1.cs_release = 0; - * msg1.next = &msg2; - * - * msg2.send_buf = RT_NULL; - * msg2.recv_buf = id; - * msg2.length = 5; - * msg2.cs_take = 0; - * msg2.cs_release = 1; - * msg2.next = RT_NULL; - * - * rt_spi_transfer_message(spi_dev_w25q, &msg1); - * rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x\n", id[3], id[4]); - * - * } - * } - * // 导出到 msh 命令列表中 - * MSH_CMD_EXPORT(spi_w25q_sample, spi w25q sample); - * @endcode - * - * @ingroup Drivers - */ - -/*! - * @addtogroup SPI - * @{ - */ -#ifdef __cplusplus -extern "C"{ -#endif - -/** - * At CPOL=0 the base value of the clock is zero - * - For CPHA=0, data are captured on the clock's rising edge (low->high transition) - * and data are propagated on a falling edge (high->low clock transition). - * - For CPHA=1, data are captured on the clock's falling edge and data are - * propagated on a rising edge. - * At CPOL=1 the base value of the clock is one (inversion of CPOL=0) - * - For CPHA=0, data are captured on clock's falling edge and data are propagated - * on a rising edge. - * - For CPHA=1, data are captured on clock's rising edge and data are propagated - * on a falling edge. - */ -#define RT_SPI_CPHA (1<<0) /*!< bit[0]:CPHA, clock phase */ -#define RT_SPI_CPOL (1<<1) /*!< bit[1]:CPOL, clock polarity */ - -#define RT_SPI_LSB (0<<2) /*!< bit[2]: 0-LSB */ -#define RT_SPI_MSB (1<<2) /*!< bit[2]: 1-MSB */ - -#define RT_SPI_MASTER (0<<3) /*!< SPI master device */ -#define RT_SPI_SLAVE (1<<3) /*!< SPI slave device */ - -#define RT_SPI_CS_HIGH (1<<4) /*!< Chipselect active high */ -#define RT_SPI_NO_CS (1<<5) /*!< No chipselect */ -#define RT_SPI_3WIRE (1<<6) /*!< SI/SO pin shared */ -#define RT_SPI_READY (1<<7) /*!< Slave pulls low to pause */ - -#define RT_SPI_MODE_MASK (RT_SPI_CPHA | RT_SPI_CPOL | RT_SPI_MSB | RT_SPI_SLAVE | RT_SPI_CS_HIGH | RT_SPI_NO_CS | RT_SPI_3WIRE | RT_SPI_READY) - -#define RT_SPI_MODE_0 (0 | 0) /*!< CPOL = 0, CPHA = 0 */ -#define RT_SPI_MODE_1 (0 | RT_SPI_CPHA) /*!< CPOL = 0, CPHA = 1 */ -#define RT_SPI_MODE_2 (RT_SPI_CPOL | 0) /*!< CPOL = 1, CPHA = 0 */ -#define RT_SPI_MODE_3 (RT_SPI_CPOL | RT_SPI_CPHA) /*!< CPOL = 1, CPHA = 1 */ - -#define RT_SPI_BUS_MODE_SPI (1<<0) -#define RT_SPI_BUS_MODE_QSPI (1<<1) - -/** - * @brief SPI message structure - */ -struct rt_spi_message -{ - const void *send_buf; - void *recv_buf; - rt_size_t length; - struct rt_spi_message *next; - - unsigned cs_take : 1; - unsigned cs_release : 1; -}; - -/** - * @brief SPI configuration structure - */ -struct rt_spi_configuration -{ - rt_uint8_t mode; - rt_uint8_t data_width; -#ifdef RT_USING_DM - rt_uint8_t data_width_tx; - rt_uint8_t data_width_rx; -#else - rt_uint16_t reserved; -#endif - - rt_uint32_t max_hz; -}; - -struct rt_spi_ops; - -/** - * @brief SPI bus structure - */ -struct rt_spi_bus -{ - struct rt_device parent; - rt_uint8_t mode; - const struct rt_spi_ops *ops; - -#ifdef RT_USING_DM - rt_base_t *pins; - rt_bool_t slave; - int num_chipselect; -#endif /* RT_USING_DM */ - - struct rt_mutex lock; - struct rt_spi_device *owner; -}; - -/** - * @brief SPI operators - */ -struct rt_spi_ops -{ - rt_err_t (*configure)(struct rt_spi_device *device, struct rt_spi_configuration *configuration); - rt_ssize_t (*xfer)(struct rt_spi_device *device, struct rt_spi_message *message); -}; - -#ifdef RT_USING_DM -/** - * @brief SPI delay info - */ -struct rt_spi_delay -{ -#define RT_SPI_DELAY_UNIT_USECS 0 -#define RT_SPI_DELAY_UNIT_NSECS 1 -#define RT_SPI_DELAY_UNIT_SCK 2 - rt_uint16_t value; - rt_uint8_t unit; -}; -#endif /* RT_USING_DM */ - -/** - * @brief SPI Virtual BUS, one device must connected to a virtual BUS - */ -struct rt_spi_device -{ - struct rt_device parent; - struct rt_spi_bus *bus; - -#ifdef RT_USING_DM - const char *name; - const struct rt_spi_device_id *id; - const struct rt_ofw_node_id *ofw_id; - - rt_uint8_t chip_select; - struct rt_spi_delay cs_setup; - struct rt_spi_delay cs_hold; - struct rt_spi_delay cs_inactive; -#endif - - struct rt_spi_configuration config; - rt_base_t cs_pin; - void *user_data; -}; - -/** - * @brief QSPI message structure - */ -struct rt_qspi_message -{ - struct rt_spi_message parent; - - /* instruction stage */ - struct - { - rt_uint8_t content; - rt_uint8_t qspi_lines; - } instruction; - - /* address and alternate_bytes stage */ - struct - { - rt_uint32_t content; - rt_uint8_t size; - rt_uint8_t qspi_lines; - } address, alternate_bytes; - - /* dummy_cycles stage */ - rt_uint32_t dummy_cycles; - - /* number of lines in qspi data stage, the other configuration items are in parent */ - rt_uint8_t qspi_data_lines; -}; - -/** - * @brief QSPI configuration structure - */ -struct rt_qspi_configuration -{ - struct rt_spi_configuration parent; - /* The size of medium */ - rt_uint32_t medium_size; - /* double data rate mode */ - rt_uint8_t ddr_mode; - /* the data lines max width which QSPI bus supported, such as 1, 2, 4 */ - rt_uint8_t qspi_dl_width ; -}; - -/** - * @brief QSPI operators - */ -struct rt_qspi_device -{ - struct rt_spi_device parent; - - struct rt_qspi_configuration config; - - void (*enter_qspi_mode)(struct rt_qspi_device *device); - - void (*exit_qspi_mode)(struct rt_qspi_device *device); -}; - -#define SPI_DEVICE(dev) ((struct rt_spi_device *)(dev)) - -#ifdef RT_USING_DM -struct rt_spi_device_id -{ - char name[20]; - void *data; -}; - -struct rt_spi_driver -{ - struct rt_driver parent; - - const struct rt_spi_device_id *ids; - const struct rt_ofw_node_id *ofw_ids; - - rt_err_t (*probe)(struct rt_spi_device *device); - rt_err_t (*remove)(struct rt_spi_device *device); - rt_err_t (*shutdown)(struct rt_spi_device *device); -}; - -rt_err_t rt_spi_driver_register(struct rt_spi_driver *driver); -rt_err_t rt_spi_device_register(struct rt_spi_device *device); - -#define RT_SPI_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, spi, BUILIN) -#endif /* RT_USING_DM */ - -/** - * @brief register a SPI bus - * - * @param bus the SPI bus - * @param name the name of SPI bus - * @param ops the operations of SPI bus - * - * @return rt_err_t error code - */ -rt_err_t rt_spi_bus_register(struct rt_spi_bus *bus, - const char *name, - const struct rt_spi_ops *ops); - - -/** - * @brief attach a device on SPI bus - * - * @param device the SPI device - * @param name the name of SPI device - * @param bus_name the name of SPI bus - * @param user_data the user data of SPI device - * - * @return rt_err_t error code - */ -rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device, - const char *name, - const char *bus_name, - void *user_data); - - -/** - * @brief attach a device on SPI bus with CS pin - * - * @param device the SPI device - * @param name the name of SPI device - * @param bus_name the name of SPI bus - * @param cs_pin the CS pin of SPI device - * @param user_data the user data of SPI device - * - * @return rt_err_t error code - */ -rt_err_t rt_spi_bus_attach_device_cspin(struct rt_spi_device *device, - const char *name, - const char *bus_name, - rt_base_t cs_pin, - void *user_data); - -/** - * @brief Reconfigure the SPI bus for the specified device. - * - * @param device: Pointer to the SPI device attached to the SPI bus. - * @retval RT_EOK if the SPI device was successfully released and the bus was configured. - * RT_EBUSY if the SPI bus is currently in use; the new configuration will take effect once the device releases the bus. - * Other return values indicate failure to configure the SPI bus due to various reasons. - * @note If the configuration of the SPI device has been updated and requires bus re-initialization, - * call this function directly. This function will reconfigure the SPI bus for the specified device. - * If this is the first time to initialize the SPI device, please call rt_spi_configure or rt_qspi_configure. - * This function is used to reconfigure the SPI bus when the SPI device is already in use. - * For further details, refer to: - * https://github.com/RT-Thread/rt-thread/pull/8528 - */ -rt_err_t rt_spi_bus_configure(struct rt_spi_device *device); - -/** - * @brief This function takes SPI bus. - * - * @param device the SPI device attached to SPI bus - * - * @return RT_EOK on taken SPI bus successfully. others on taken SPI bus failed. - */ -rt_err_t rt_spi_take_bus(struct rt_spi_device *device); - -/** - * @brief This function releases SPI bus. - * - * @param device the SPI device attached to SPI bus - * - * @return RT_EOK on release SPI bus successfully. - */ -rt_err_t rt_spi_release_bus(struct rt_spi_device *device); - -/** - * @brief This function take SPI device (takes CS of SPI device). - * - * @param device the SPI device attached to SPI bus - * - * @return RT_EOK on release SPI bus successfully. others on taken SPI bus failed. - */ -rt_err_t rt_spi_take(struct rt_spi_device *device); - -/** - * @brief This function releases SPI device (releases CS of SPI device). - * - * @param device the SPI device attached to SPI bus - * - * @return RT_EOK on release SPI device successfully. - */ -rt_err_t rt_spi_release(struct rt_spi_device *device); - -/** - * @brief This function can set configuration on SPI device. - * - * @param device: the SPI device attached to SPI bus - * @param cfg: the configuration pointer. - * - * @retval RT_EOK on release SPI device successfully. - * RT_EBUSY is not an error condition and the configuration will take effect once the device has the bus - * others on taken SPI bus failed. - */ -rt_err_t rt_spi_configure(struct rt_spi_device *device, - struct rt_spi_configuration *cfg); - - -/** - * @brief This function can send data then receive data from SPI device. - * - * @param device the SPI device attached to SPI bus - * @param send_buf the buffer to be transmitted to SPI device. - * @param send_length the number of data to be transmitted. - * @param recv_buf the buffer to be recivied from SPI device. - * @param recv_length the data to be recivied. - * - * @return rt_err_t error code - */ -rt_err_t rt_spi_send_then_recv(struct rt_spi_device *device, - const void *send_buf, - rt_size_t send_length, - void *recv_buf, - rt_size_t recv_length); - -/** - * @brief This function can send data then send data from SPI device. - * - * @param device the SPI device attached to SPI bus - * @param send_buf1 the buffer to be transmitted to SPI device. - * @param send_length1 the number of data to be transmitted. - * @param send_buf2 the buffer to be transmitted to SPI device. - * @param send_length2 the number of data to be transmitted. - * - * @return the status of transmit. - */ -rt_err_t rt_spi_send_then_send(struct rt_spi_device *device, - const void *send_buf1, - rt_size_t send_length1, - const void *send_buf2, - rt_size_t send_length2); - -/** - * @brief This function transmits data to SPI device. - * - * @param device the SPI device attached to SPI bus - * @param send_buf the buffer to be transmitted to SPI device. - * @param recv_buf the buffer to save received data from SPI device. - * @param length the length of transmitted data. - * - * @return the actual length of transmitted. - */ -rt_ssize_t rt_spi_transfer(struct rt_spi_device *device, - const void *send_buf, - void *recv_buf, - rt_size_t length); - -/** - * @brief The SPI device transmits 8 bytes of data - * - * @param device the SPI device attached to SPI bus - * @param senddata send data buffer - * @param recvdata receive data buffer - * - * @return rt_err_t error code - */ -rt_err_t rt_spi_sendrecv8(struct rt_spi_device *device, - rt_uint8_t senddata, - rt_uint8_t *recvdata); - -/** - * @brief The SPI device transmits 16 bytes of data - * - * @param device the SPI device attached to SPI bus - * @param senddata send data buffer - * @param recvdata receive data buffer - * - * @return rt_err_t error code - */ -rt_err_t rt_spi_sendrecv16(struct rt_spi_device *device, - rt_uint16_t senddata, - rt_uint16_t *recvdata); - -/** - * @brief This function transfers a message list to the SPI device. - * - * @param device the SPI device attached to SPI bus - * @param message the message list to be transmitted to SPI device - * - * @return RT_NULL if transmits message list successfully, - * SPI message which be transmitted failed. - */ -struct rt_spi_message *rt_spi_transfer_message(struct rt_spi_device *device, - struct rt_spi_message *message); - -/** - * @brief This function receives data from SPI device. - * - * @param device the SPI device attached to SPI bus - * @param recv_buf the buffer to be recivied from SPI device. - * @param length the data to be recivied. - * - * @return the actual length of received. -*/ -rt_inline rt_size_t rt_spi_recv(struct rt_spi_device *device, - void *recv_buf, - rt_size_t length) -{ - return rt_spi_transfer(device, RT_NULL, recv_buf, length); -} - -/** - * @brief This function sends data to SPI device. - * - * @param device the SPI device attached to SPI bus - * @param send_buf the buffer to be transmitted to SPI device. - * @param length the number of data to be transmitted. - * - * @return the actual length of send. - */ -rt_inline rt_size_t rt_spi_send(struct rt_spi_device *device, - const void *send_buf, - rt_size_t length) -{ - return rt_spi_transfer(device, send_buf, RT_NULL, length); -} - -/** - * @brief This function appends a message to the SPI message list. - * - * @param list the SPI message list header. - * @param message the message pointer to be appended to the message list. - */ -rt_inline void rt_spi_message_append(struct rt_spi_message *list, - struct rt_spi_message *message) -{ - RT_ASSERT(list != RT_NULL); - if (message == RT_NULL) - return; /* not append */ - - while (list->next != RT_NULL) - { - list = list->next; - } - - list->next = message; - message->next = RT_NULL; -} - -/** - * @brief This function can set configuration on QSPI device. - * - * @param device the QSPI device attached to QSPI bus. - * @param cfg the configuration pointer. - * - * @return the actual length of transmitted. - */ -rt_err_t rt_qspi_configure(struct rt_qspi_device *device, struct rt_qspi_configuration *cfg); - -/** - * @brief This function can register a SPI bus for QSPI mode. - * - * @param bus the SPI bus for QSPI mode. - * @param name The name of the spi bus. - * @param ops the SPI bus instance to be registered. - * - * @return the actual length of transmitted. - */ -rt_err_t rt_qspi_bus_register(struct rt_spi_bus *bus, const char *name, const struct rt_spi_ops *ops); - -/** - * @brief This function transmits data to QSPI device. - * - * @param device the QSPI device attached to QSPI bus. - * @param message the message pointer. - * - * @return the actual length of transmitted. - */ -rt_size_t rt_qspi_transfer_message(struct rt_qspi_device *device, struct rt_qspi_message *message); - -/** - * @brief This function can send data then receive data from QSPI device - * - * @param device the QSPI device attached to QSPI bus. - * @param send_buf the buffer to be transmitted to QSPI device. - * @param send_length the number of data to be transmitted. - * @param recv_buf the buffer to be recivied from QSPI device. - * @param recv_length the data to be recivied. - * - * @return the status of transmit. - */ -rt_err_t rt_qspi_send_then_recv(struct rt_qspi_device *device, const void *send_buf, rt_size_t send_length,void *recv_buf, rt_size_t recv_length); - -/** - * @brief This function can send data to QSPI device - * - * @param device the QSPI device attached to QSPI bus. - * @param send_buf the buffer to be transmitted to QSPI device. - * @param length the number of data to be transmitted. - * - * @return the status of transmit. - */ -rt_err_t rt_qspi_send(struct rt_qspi_device *device, const void *send_buf, rt_size_t length); - -#ifdef __cplusplus -} -#endif - -/*! @}*/ - -#endif diff --git a/rt-thread/components/drivers/include/drivers/dev_touch.h b/rt-thread/components/drivers/include/drivers/dev_touch.h deleted file mode 100644 index ba01ae4..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_touch.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2019-05-20 tyustli the first version - */ - -#ifndef __DEV_TOUCH_H__ -#define __DEV_TOUCH_H__ - -#include -#include "dev_pin.h" -/** - * @addtogroup Drivers RTTHREAD Driver - * @defgroup Touch Touch - * - * @brief Touch driver api - * - * Example - * @code {.c} - * #include - * #include "rtdevice.h" - * - * static rt_thread_t gt9147_thread = RT_NULL; - * static rt_sem_t gt9147_sem = RT_NULL; - * static rt_device_t dev = RT_NULL; - * static struct rt_touch_data *read_data; - * - * // 读取数据线程入口函数 - * static void gt9147_entry(void *parameter) - * { - * struct rt_touch_data *read_data; - * read_data = (struct rt_touch_data *)rt_malloc(sizeof(struct rt_touch_data) * 5); - * - * while (1) - * { - * // 请求信号量 - * rt_sem_take(gt9147_sem, RT_WAITING_FOREVER); - * // 读取五个点的触摸信息 - * if (rt_device_read(dev, 0, read_data, 5) == 5) - * { - * for (rt_uint8_t i = 0; i < 5; i++) - * { - * if (read_data[i].event == RT_TOUCH_EVENT_DOWN || read_data[i].event == RT_TOUCH_EVENT_MOVE) - * { - * rt_kprintf("%d %d %d %d %d\n", - * read_data[i].track_id, - * read_data[i].x_coordinate, - * read_data[i].y_coordinate, - * read_data[i].timestamp, - * read_data[i].width); - * } - * } - * } - * // 打开中断 - * rt_device_control(dev, RT_TOUCH_CTRL_ENABLE_INT, RT_NULL); - * } - * } - * - * // 接收回调函数 - * static rt_err_t rx_callback(rt_device_t dev, rt_size_t size) - * { - * // 关闭中断 - * rt_device_control(dev, RT_TOUCH_CTRL_DISABLE_INT, RT_NULL); - * // 释放信号量 - * rt_sem_release(gt9147_sem); - * return 0; - * } - * - * static int gt9147_sample(void) - * { - * // 查找 Touch 设备 - * dev = rt_device_find("touch"); - * - * if (dev == RT_NULL) - * { - * rt_kprintf("can't find device:%s\n", "touch"); - * return -1; - * } - * // 以中断的方式打开设备 - * if (rt_device_open(dev, RT_DEVICE_FLAG_INT_RX) != RT_EOK) - * { - * rt_kprintf("open device failed!"); - * return -1; - * } - * // 设置接收回调 - * rt_device_set_rx_indicate(dev, rx_callback); - * // 创建信号量 - * gt9147_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_PRIO); - * - * if (gt9147_sem == RT_NULL) - * { - * rt_kprintf("create dynamic semaphore failed.\n"); - * return -1; - * } - * // 创建读取数据线程 - * gt9147_thread = rt_thread_create("thread1", - * gt9147_entry, - * RT_NULL, - * THREAD_STACK_SIZE, - * THREAD_PRIORITY, - * THREAD_TIMESLICE); - * // 启动线程 - * if (gt9147_thread != RT_NULL) - * rt_thread_startup(gt9147_thread); - * - * return 0; - * } - * MSH_CMD_EXPORT(gt9147_sample, gt9147 sample); - * @endcode - * - * @ingroup Drivers - */ - -/*! - * @addtogroup Touch - * @{ - */ -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef RT_USING_RTC -#define rt_touch_get_ts() time(RT_NULL) /* API for the touch to get the timestamp */ -#else -#define rt_touch_get_ts() rt_tick_get() /* API for the touch to get the timestamp */ -#endif - -/* Touch vendor types */ -#define RT_TOUCH_VENDOR_UNKNOWN (0) /* unknown */ -#define RT_TOUCH_VENDOR_GT (1) /* GTxx series */ -#define RT_TOUCH_VENDOR_FT (2) /* FTxx series */ - -/* Touch ic type*/ -#define RT_TOUCH_TYPE_NONE (0) /* touch ic none */ -#define RT_TOUCH_TYPE_CAPACITANCE (1) /* capacitance ic */ -#define RT_TOUCH_TYPE_RESISTANCE (2) /* resistance ic */ - -/* Touch control cmd types */ -#define RT_TOUCH_CTRL_GET_ID (RT_DEVICE_CTRL_BASE(Touch) + 0) /* Get device id */ -#define RT_TOUCH_CTRL_GET_INFO (RT_DEVICE_CTRL_BASE(Touch) + 1) /* Get touch info */ -#define RT_TOUCH_CTRL_SET_MODE (RT_DEVICE_CTRL_BASE(Touch) + 2) /* Set touch's work mode. ex. RT_TOUCH_MODE_POLLING,RT_TOUCH_MODE_INT */ -#define RT_TOUCH_CTRL_SET_X_RANGE (RT_DEVICE_CTRL_BASE(Touch) + 3) /* Set x coordinate range */ -#define RT_TOUCH_CTRL_SET_Y_RANGE (RT_DEVICE_CTRL_BASE(Touch) + 4) /* Set y coordinate range */ -#define RT_TOUCH_CTRL_SET_X_TO_Y (RT_DEVICE_CTRL_BASE(Touch) + 5) /* Set X Y coordinate exchange */ -#define RT_TOUCH_CTRL_DISABLE_INT (RT_DEVICE_CTRL_BASE(Touch) + 6) /* Disable interrupt */ -#define RT_TOUCH_CTRL_ENABLE_INT (RT_DEVICE_CTRL_BASE(Touch) + 7) /* Enable interrupt */ -#define RT_TOUCH_CTRL_POWER_ON (RT_DEVICE_CTRL_BASE(Touch) + 8) /* Touch Power On */ -#define RT_TOUCH_CTRL_POWER_OFF (RT_DEVICE_CTRL_BASE(Touch) + 9) /* Touch Power Off */ -#define RT_TOUCH_CTRL_GET_STATUS (RT_DEVICE_CTRL_BASE(Touch) + 10) /* Get Touch Power Status */ - -/* Touch event */ -#define RT_TOUCH_EVENT_NONE (0) /* Touch none */ -#define RT_TOUCH_EVENT_UP (1) /* Touch up event */ -#define RT_TOUCH_EVENT_DOWN (2) /* Touch down event */ -#define RT_TOUCH_EVENT_MOVE (3) /* Touch move event */ - -/** - * @brief Touch information -*/ -struct rt_touch_info -{ - rt_uint8_t type; /* The touch type */ - rt_uint8_t vendor; /* Vendor of touchs */ - rt_uint8_t point_num; /* Support point num */ - rt_int32_t range_x; /* X coordinate range */ - rt_int32_t range_y; /* Y coordinate range */ -}; - -/** - * @brief Touch configuration -*/ -struct rt_touch_config -{ -#ifdef RT_TOUCH_PIN_IRQ - struct rt_device_pin_mode irq_pin; /* Interrupt pin, The purpose of this pin is to notification read data */ -#endif - char *dev_name; /* The name of the communication device */ - void *user_data; -}; - -typedef struct rt_touch_device *rt_touch_t; -/** - * @brief Touch device -*/ -struct rt_touch_device -{ - struct rt_device parent; /* The standard device */ - struct rt_touch_info info; /* The touch info data */ - struct rt_touch_config config; /* The touch config data */ - - const struct rt_touch_ops *ops; /* The touch ops */ - rt_err_t (*irq_handle)(rt_touch_t touch); /* Called when an interrupt is generated, registered by the driver */ -}; - -/** - * @brief Touch data -*/ -struct rt_touch_data -{ - rt_uint8_t event; /* The touch event of the data */ - rt_uint8_t track_id; /* Track id of point */ - rt_uint8_t width; /* Point of width */ - rt_uint16_t x_coordinate; /* Point of x coordinate */ - rt_uint16_t y_coordinate; /* Point of y coordinate */ - rt_tick_t timestamp; /* The timestamp when the data was received */ -}; - -/** - * @brief Touch device operations -*/ -struct rt_touch_ops -{ - rt_size_t (*touch_readpoint)(struct rt_touch_device *touch, void *buf, rt_size_t touch_num); - rt_err_t (*touch_control)(struct rt_touch_device *touch, int cmd, void *arg); -}; - -/** - * @brief register a touch device - * @param touch the touch device - * @param name the name of touch device - * @param flag the flag of touch device - * @param data the user data of touch device - * @return rt_err_t error code - */ -int rt_hw_touch_register(rt_touch_t touch, - const char *name, - rt_uint32_t flag, - void *data); - -/** - * @brief Touch irq handle - * @param touch the touch device - * - * @note If you doesn't use pin device. you must call this function in your touch irq callback - */ -void rt_hw_touch_isr(rt_touch_t touch); - -#ifdef __cplusplus -} -#endif - -/*! @}*/ - -#endif /* __DEV_TOUCH_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/dev_watchdog.h b/rt-thread/components/drivers/include/drivers/dev_watchdog.h deleted file mode 100644 index 4b5614f..0000000 --- a/rt-thread/components/drivers/include/drivers/dev_watchdog.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * COPYRIGHT (C) 2011-2023, Real-Thread Information Technology Ltd - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-09-12 heyuanjie87 first version. - */ - -#ifndef __DEV_WATCHDOG_H__ -#define __DEV_WATCHDOG_H__ - -#include - -#define RT_DEVICE_CTRL_WDT_GET_TIMEOUT (RT_DEVICE_CTRL_BASE(WDT) + 1) /* get timeout(in seconds) */ -#define RT_DEVICE_CTRL_WDT_SET_TIMEOUT (RT_DEVICE_CTRL_BASE(WDT) + 2) /* set timeout(in seconds) */ -#define RT_DEVICE_CTRL_WDT_GET_TIMELEFT (RT_DEVICE_CTRL_BASE(WDT) + 3) /* get the left time before reboot(in seconds) */ -#define RT_DEVICE_CTRL_WDT_KEEPALIVE (RT_DEVICE_CTRL_BASE(WDT) + 4) /* refresh watchdog */ -#define RT_DEVICE_CTRL_WDT_START (RT_DEVICE_CTRL_BASE(WDT) + 5) /* start watchdog */ -#define RT_DEVICE_CTRL_WDT_STOP (RT_DEVICE_CTRL_BASE(WDT) + 6) /* stop watchdog */ - -struct rt_watchdog_ops; -struct rt_watchdog_device -{ - struct rt_device parent; - const struct rt_watchdog_ops *ops; -}; -typedef struct rt_watchdog_device rt_watchdog_t; - -struct rt_watchdog_ops -{ - rt_err_t (*init)(rt_watchdog_t *wdt); - rt_err_t (*control)(rt_watchdog_t *wdt, int cmd, void *arg); -}; - -rt_err_t rt_hw_watchdog_register(rt_watchdog_t *wdt, - const char *name, - rt_uint32_t flag, - void *data); - -#endif /* __DEV_WATCHDOG_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/dma.h b/rt-thread/components/drivers/include/drivers/dma.h deleted file mode 100644 index 3128c67..0000000 --- a/rt-thread/components/drivers/include/drivers/dma.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#ifndef __DMA_H__ -#define __DMA_H__ - -#include -#include -#include -#include - -#include -#include -#include - -struct rt_dma_chan; -struct rt_dma_controller_ops; - -enum rt_dma_transfer_direction -{ - RT_DMA_MEM_TO_MEM, - RT_DMA_MEM_TO_DEV, - RT_DMA_DEV_TO_MEM, - RT_DMA_DEV_TO_DEV, - - RT_DMA_DIR_MAX, -}; - -enum rt_dma_slave_buswidth -{ - RT_DMA_SLAVE_BUSWIDTH_UNDEFINED = 0, - RT_DMA_SLAVE_BUSWIDTH_1_BYTE = 1, - RT_DMA_SLAVE_BUSWIDTH_2_BYTES = 2, - RT_DMA_SLAVE_BUSWIDTH_3_BYTES = 3, - RT_DMA_SLAVE_BUSWIDTH_4_BYTES = 4, - RT_DMA_SLAVE_BUSWIDTH_8_BYTES = 8, - RT_DMA_SLAVE_BUSWIDTH_16_BYTES = 16, - RT_DMA_SLAVE_BUSWIDTH_32_BYTES = 32, - RT_DMA_SLAVE_BUSWIDTH_64_BYTES = 64, - RT_DMA_SLAVE_BUSWIDTH_128_BYTES = 128, - - RT_DMA_SLAVE_BUSWIDTH_BYTES_MAX, -}; - -struct rt_dma_slave_config -{ - enum rt_dma_transfer_direction direction; - enum rt_dma_slave_buswidth src_addr_width; - enum rt_dma_slave_buswidth dst_addr_width; - - rt_ubase_t src_addr; - rt_ubase_t dst_addr; - - rt_uint32_t src_maxburst; - rt_uint32_t dst_maxburst; - rt_uint32_t src_port_window_size; - rt_uint32_t dst_port_window_size; -}; - -struct rt_dma_slave_transfer -{ - rt_ubase_t src_addr; - rt_ubase_t dst_addr; - - void *buffer; - rt_ubase_t dma_handle; - rt_size_t buffer_len; - rt_size_t period_len; -}; - -struct rt_dma_controller -{ - rt_list_t list; - - struct rt_device *dev; - - RT_BITMAP_DECLARE(dir_cap, RT_DMA_DIR_MAX); - const struct rt_dma_controller_ops *ops; - - rt_list_t channels_nodes; - struct rt_mutex mutex; -}; - -struct rt_dma_controller_ops -{ - struct rt_dma_chan *(*request_chan)(struct rt_dma_controller *ctrl, - struct rt_device *slave, void *fw_data); - rt_err_t (*release_chan)(struct rt_dma_chan *chan); - - rt_err_t (*start)(struct rt_dma_chan *chan); - rt_err_t (*stop)(struct rt_dma_chan *chan); - rt_err_t (*config)(struct rt_dma_chan *chan, struct rt_dma_slave_config *conf); - - rt_err_t (*prep_memcpy)(struct rt_dma_chan *chan, - rt_ubase_t dma_addr_src, rt_ubase_t dma_addr_dst, rt_size_t len); - - rt_err_t (*prep_cyclic)(struct rt_dma_chan *chan, - rt_ubase_t dma_buf_addr, rt_size_t buf_len, rt_size_t period_len, - enum rt_dma_transfer_direction dir); - - rt_err_t (*prep_single)(struct rt_dma_chan *chan, - rt_ubase_t dma_buf_addr, rt_size_t buf_len, - enum rt_dma_transfer_direction dir); -}; - -struct rt_dma_chan -{ - const char *name; - - struct rt_dma_controller *ctrl; - struct rt_device *slave; - - rt_list_t list; - rt_err_t conf_err; - rt_err_t prep_err; - struct rt_dma_slave_config conf; - struct rt_dma_slave_transfer transfer; - - void (*callback)(struct rt_dma_chan *chan, rt_size_t size); - - void *priv; -}; - -struct rt_dma_pool -{ - rt_region_t region; - - rt_list_t list; - - rt_ubase_t flags; - - rt_bitmap_t *map; - rt_size_t bits; - rt_ubase_t start; - - struct rt_device *dev; -}; - -struct rt_dma_map_ops -{ - void *(*alloc)(struct rt_device *dev, rt_size_t size, - rt_ubase_t *dma_handle, rt_ubase_t flags); - void (*free)(struct rt_device *dev, rt_size_t size, - void *cpu_addr, rt_ubase_t dma_handle, rt_ubase_t flags); - rt_err_t (*sync_out_data)(struct rt_device *dev, void *data, rt_size_t size, - rt_ubase_t *dma_handle, rt_ubase_t flags); - rt_err_t (*sync_in_data)(struct rt_device *dev, void *out_data, rt_size_t size, - rt_ubase_t dma_handle, rt_ubase_t flags); -}; - -rt_inline void rt_dma_controller_add_direction(struct rt_dma_controller *ctrl, - enum rt_dma_transfer_direction dir) -{ - RT_ASSERT(ctrl != RT_NULL); - RT_ASSERT(dir < RT_DMA_DIR_MAX); - - rt_bitmap_set_bit(ctrl->dir_cap, dir); -} - -rt_err_t rt_dma_controller_register(struct rt_dma_controller *ctrl); -rt_err_t rt_dma_controller_unregister(struct rt_dma_controller *ctrl); - -rt_err_t rt_dma_chan_start(struct rt_dma_chan *chan); -rt_err_t rt_dma_chan_stop(struct rt_dma_chan *chan); -rt_err_t rt_dma_chan_config(struct rt_dma_chan *chan, - struct rt_dma_slave_config *conf); -rt_err_t rt_dma_chan_done(struct rt_dma_chan *chan, rt_size_t size); - -rt_err_t rt_dma_prep_memcpy(struct rt_dma_chan *chan, - struct rt_dma_slave_transfer *transfer); -rt_err_t rt_dma_prep_cyclic(struct rt_dma_chan *chan, - struct rt_dma_slave_transfer *transfer); -rt_err_t rt_dma_prep_single(struct rt_dma_chan *chan, - struct rt_dma_slave_transfer *transfer); - -struct rt_dma_chan *rt_dma_chan_request(struct rt_device *dev, const char *name); -rt_err_t rt_dma_chan_release(struct rt_dma_chan *chan); - -#define RT_DMA_F_LINEAR RT_BIT(0) -#define RT_DMA_F_32BITS RT_BIT(1) -#define RT_DMA_F_NOCACHE RT_BIT(2) -#define RT_DMA_F_DEVICE RT_BIT(3) -#define RT_DMA_F_NOMAP RT_BIT(4) - -#define RT_DMA_PAGE_SIZE ARCH_PAGE_SIZE - -void *rt_dma_alloc(struct rt_device *dev, rt_size_t size, - rt_ubase_t *dma_handle, rt_ubase_t flags); - -void rt_dma_free(struct rt_device *dev, rt_size_t size, - void *cpu_addr, rt_ubase_t dma_handle, rt_ubase_t flags); - -rt_inline void *rt_dma_alloc_coherent(struct rt_device *dev, rt_size_t size, - rt_ubase_t *dma_handle) -{ - return rt_dma_alloc(dev, size, dma_handle, - RT_DMA_F_NOCACHE | RT_DMA_F_LINEAR); -} - -rt_inline void rt_dma_free_coherent(struct rt_device *dev, rt_size_t size, - void *cpu_addr, rt_ubase_t dma_handle) -{ - rt_dma_free(dev, size, cpu_addr, dma_handle, - RT_DMA_F_NOCACHE | RT_DMA_F_LINEAR); -} - -rt_err_t rt_dma_sync_out_data(struct rt_device *dev, void *data, rt_size_t size, - rt_ubase_t *dma_handle, rt_ubase_t flags); -rt_err_t rt_dma_sync_in_data(struct rt_device *dev, void *out_data, rt_size_t size, - rt_ubase_t dma_handle, rt_ubase_t flags); - -rt_inline rt_bool_t rt_dma_device_is_coherent(struct rt_device *dev) -{ - return rt_dm_dev_prop_read_bool(dev, "dma-coherent"); -} - -rt_inline void rt_dma_device_set_ops(struct rt_device *dev, - const struct rt_dma_map_ops *ops) -{ - dev->dma_ops = ops; -} - -struct rt_dma_pool *rt_dma_pool_install(rt_region_t *region); -rt_err_t rt_dma_pool_extract(rt_region_t *region_list, rt_size_t list_len, - rt_size_t cma_size, rt_size_t coherent_pool_size); - -#endif /* __DMA_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/iio.h b/rt-thread/components/drivers/include/drivers/iio.h deleted file mode 100644 index c69f507..0000000 --- a/rt-thread/components/drivers/include/drivers/iio.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#ifndef __IIO_H__ -#define __IIO_H__ - -void *rt_iio_channel_get_by_index(struct rt_device *dev, int index, int *out_channel); -void *rt_iio_channel_get_by_name(struct rt_device *dev, const char *name, int *out_channel); - -#endif /* __IIO_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/led.h b/rt-thread/components/drivers/include/drivers/led.h deleted file mode 100644 index aeb80a6..0000000 --- a/rt-thread/components/drivers/include/drivers/led.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#ifndef __LED_H__ -#define __LED_H__ - -#include -#include - -struct rt_led_ops; - -enum rt_led_state -{ - RT_LED_S_OFF, - RT_LED_S_ON, - RT_LED_S_TOGGLE, - RT_LED_S_BLINK, - - RT_LED_STATE_NR, -}; - -struct rt_led_device -{ - struct rt_device parent; - - const struct rt_led_ops *ops; - - struct rt_spinlock spinlock; - - void *sysdata; - void *priv; -}; - -struct rt_led_ops -{ - rt_err_t (*set_state)(struct rt_led_device *led, enum rt_led_state state); - rt_err_t (*get_state)(struct rt_led_device *led, enum rt_led_state *out_state); - rt_err_t (*set_period)(struct rt_led_device *led, rt_uint32_t period_ms); - rt_err_t (*set_brightness)(struct rt_led_device *led, rt_uint32_t brightness); -}; - -rt_err_t rt_hw_led_register(struct rt_led_device *led); -rt_err_t rt_hw_led_unregister(struct rt_led_device *led); - -rt_err_t rt_led_set_state(struct rt_led_device *led, enum rt_led_state state); -rt_err_t rt_led_get_state(struct rt_led_device *led, enum rt_led_state *out_state); -rt_err_t rt_led_set_period(struct rt_led_device *led, rt_uint32_t period_ms); -rt_err_t rt_led_set_brightness(struct rt_led_device *led, rt_uint32_t brightness); - -#endif /* __LED_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/mailbox.h b/rt-thread/components/drivers/include/drivers/mailbox.h deleted file mode 100644 index 954cd62..0000000 --- a/rt-thread/components/drivers/include/drivers/mailbox.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#ifndef __MAILBOX_H__ -#define __MAILBOX_H__ - -#include -#include - -struct rt_mbox_chan; -struct rt_mbox_client; -struct rt_mbox_controller_ops; - -struct rt_mbox_controller -{ - rt_list_t list; - - struct rt_device *dev; - - const struct rt_mbox_controller_ops *ops; - - rt_size_t num_chans; - struct rt_mbox_chan *chans; -}; - -struct rt_mbox_controller_ops -{ - rt_err_t (*request)(struct rt_mbox_chan *); - void (*release)(struct rt_mbox_chan *); - rt_err_t (*send)(struct rt_mbox_chan *, const void *data); - rt_bool_t (*peek)(struct rt_mbox_chan *); - int (*ofw_parse)(struct rt_mbox_controller *, struct rt_ofw_cell_args *); -}; - -struct rt_mbox_chan -{ - struct rt_mbox_controller *ctrl; - struct rt_mbox_client *client; - - void *data; - rt_bool_t complete; - struct rt_timer timer; - struct rt_spinlock lock; - - void *priv; -}; - -struct rt_mbox_client -{ - struct rt_device *dev; - - void (*rx_callback)(struct rt_mbox_client *, void *data); - void (*tx_prepare)(struct rt_mbox_client *, const void *data); - void (*tx_done)(struct rt_mbox_client *, const void *data, rt_err_t err); -}; - -rt_err_t rt_mbox_controller_register(struct rt_mbox_controller *ctrl); -rt_err_t rt_mbox_controller_unregister(struct rt_mbox_controller *ctrl); - -rt_err_t rt_mbox_send(struct rt_mbox_chan *chan, const void *data, - rt_uint32_t timeout_ms); -void rt_mbox_send_done(struct rt_mbox_chan *chan, rt_err_t err); -rt_bool_t rt_mbox_peek(struct rt_mbox_chan *chan); -rt_err_t rt_mbox_recv(struct rt_mbox_chan *chan, void *data); - -struct rt_mbox_chan *rt_mbox_request_by_index(struct rt_mbox_client *client, int index); -struct rt_mbox_chan *rt_mbox_request_by_name(struct rt_mbox_client *client, char *name); -rt_err_t rt_mbox_release(struct rt_mbox_chan *chan); - -#endif /* __MAILBOX_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/misc.h b/rt-thread/components/drivers/include/drivers/misc.h index ea962a2..aa2b715 100644 --- a/rt-thread/components/drivers/include/drivers/misc.h +++ b/rt-thread/components/drivers/include/drivers/misc.h @@ -12,7 +12,6 @@ #define __MISC_H__ #include -#include #ifdef ARCH_CPU_64BIT #define RT_BITS_PER_LONG 64 @@ -34,15 +33,6 @@ (((__x) - ((__d) / 2)) / (__d)); \ }) -#define __KEY_PLACEHOLDER_1 0, -#define ____KEY_ENABLED(__ignored, val, ...) val -#define ___KEY_ENABLED(arg1_or_junk) ____KEY_ENABLED(arg1_or_junk 1, 0) -#define __KEY_ENABLED(value) ___KEY_ENABLED(__KEY_PLACEHOLDER_##value) -#define RT_KEY_ENABLED(key) __KEY_ENABLED(key) - -#define RT_FIELD_PREP(mask, val) (((rt_uint64_t)(val) << (__rt_ffsl((mask)) - 1)) & (mask)) -#define RT_FIELD_GET(mask, val) (((val) & (mask)) >> (__rt_ffsl((mask)) - 1)) - #define RT_BIT(n) (1UL << (n)) #define RT_BIT_ULL(n) (1ULL << (n)) #define RT_BIT_MASK(nr) (1UL << ((nr) % RT_BITS_PER_LONG)) @@ -58,19 +48,6 @@ #define RT_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) -#define rt_offsetof(s, field) ((rt_size_t)&((s *)0)->field) - -#define rt_err_ptr(err) ((void *)(rt_base_t)(err)) -#define rt_ptr_err(ptr) ((rt_err_t)(rt_base_t)(ptr)) -#define rt_is_err_value(ptr) ((rt_ubase_t)(void *)(ptr) >= (rt_ubase_t)-4095) -#define rt_is_err(ptr) rt_is_err_value(ptr) -#define rt_is_err_or_null(ptr) (!(ptr) || rt_is_err_value((rt_ubase_t)(ptr))) - -#define rt_upper_32_bits(n) ((rt_uint32_t)(((n) >> 16) >> 16)) -#define rt_lower_32_bits(n) ((rt_uint32_t)((n) & 0xffffffff)) -#define rt_upper_16_bits(n) ((rt_uint16_t)((n) >> 16)) -#define rt_lower_16_bits(n) ((rt_uint16_t)((n) & 0xffff)) - #define rt_min(x, y) \ ({ \ typeof(x) _x = (x); \ @@ -94,13 +71,6 @@ _x < _y ? _x: _y; \ }) -#define rt_max_t(type, x, y) \ -({ \ - type _x = (x); \ - type _y = (y); \ - _x > _y ? _x: _y; \ -}) - #define rt_clamp(val, lo, hi) rt_min((typeof(val))rt_max(val, lo), hi) #define rt_do_div(n, base) \ @@ -113,34 +83,4 @@ _rem; \ }) -#define rt_abs(x) \ -({ \ - long ret; \ - if (sizeof(x) == sizeof(long)) \ - { \ - long __x = (x); \ - ret = (__x < 0) ? -__x : __x; \ - } \ - else \ - { \ - int __x = (x); \ - ret = (__x < 0) ? -__x : __x; \ - } \ - ret; \ -}) - -#ifndef rt_ilog2 -rt_inline int rt_ilog2(rt_ubase_t v) -{ - int l = 0; - - while ((1UL << l) < v) - { - l++; - } - - return l; -} -#endif /* !rt_ilog2 */ - #endif /* __MISC_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/mmcsd_card.h b/rt-thread/components/drivers/include/drivers/mmcsd_card.h index 6d86760..13173f1 100644 --- a/rt-thread/components/drivers/include/drivers/mmcsd_card.h +++ b/rt-thread/components/drivers/include/drivers/mmcsd_card.h @@ -218,7 +218,7 @@ struct rt_mmcsd_card { struct rt_sdio_cccr cccr; /* common card info */ struct rt_sdio_cis cis; /* common tuple info */ struct rt_sdio_function *sdio_function[SDIO_MAX_FUNCTIONS + 1]; /* SDIO functions (devices) */ - void *blk_dev; + rt_list_t blk_devices; /* for block device list */ struct rt_mmc_ext_csd ext_csd; }; diff --git a/rt-thread/components/drivers/include/drivers/mmcsd_host.h b/rt-thread/components/drivers/include/drivers/mmcsd_host.h index 5632ee1..73c1b97 100644 --- a/rt-thread/components/drivers/include/drivers/mmcsd_host.h +++ b/rt-thread/components/drivers/include/drivers/mmcsd_host.h @@ -134,7 +134,6 @@ struct rt_mmcsd_host #define MMCSD_SUP_HS200_1V2 (1 << 10) #define MMCSD_SUP_HS200 (MMCSD_SUP_HS200_1V2 | MMCSD_SUP_HS200_1V8) /* hs200 sdr */ #define MMCSD_SUP_NONREMOVABLE (1 << 11) -#define controller_is_removable(host) (!(host->flags & MMCSD_SUP_NONREMOVABLE)) #define MMCSD_SUP_HS400_1V8 (1 << 12) #define MMCSD_SUP_HS400_1V2 (1 << 13) #define MMCSD_SUP_HS400 (MMCSD_SUP_HS400_1V2 | MMCSD_SUP_HS400_1V8) /* hs400 ddr */ diff --git a/rt-thread/components/drivers/include/drivers/nvme.h b/rt-thread/components/drivers/include/drivers/nvme.h deleted file mode 100644 index 1eca5d9..0000000 --- a/rt-thread/components/drivers/include/drivers/nvme.h +++ /dev/null @@ -1,899 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#ifndef __NVME_H__ -#define __NVME_H__ - -#include -#include -#include - -#define NVME_RSVD(offset, bytes_size) rt_uint8_t __rsvd##offset[bytes_size] - -enum -{ - /* - * Generic Command Status: - */ - RT_NVME_SC_SUCCESS = 0x0, - RT_NVME_SC_INVALID_OPCODE = 0x1, - RT_NVME_SC_INVALID_FIELD = 0x2, - RT_NVME_SC_CMDID_CONFLICT = 0x3, - RT_NVME_SC_DATA_XFER_ERROR = 0x4, - RT_NVME_SC_POWER_LOSS = 0x5, - RT_NVME_SC_INTERNAL = 0x6, - RT_NVME_SC_ABORT_REQ = 0x7, - RT_NVME_SC_ABORT_QUEUE = 0x8, - RT_NVME_SC_FUSED_FAIL = 0x9, - RT_NVME_SC_FUSED_MISSING = 0xa, - RT_NVME_SC_INVALID_NS = 0xb, - RT_NVME_SC_CMD_SEQ_ERROR = 0xc, - RT_NVME_SC_SGL_INVALID_LAST = 0xd, - RT_NVME_SC_SGL_INVALID_COUNT = 0xe, - RT_NVME_SC_SGL_INVALID_DATA = 0xf, - RT_NVME_SC_SGL_INVALID_METADATA = 0x10, - RT_NVME_SC_SGL_INVALID_TYPE = 0x11, - RT_NVME_SC_CMB_INVALID_USE = 0x12, - RT_NVME_SC_PRP_INVALID_OFFSET = 0x13, - RT_NVME_SC_ATOMIC_WU_EXCEEDED = 0x14, - RT_NVME_SC_OP_DENIED = 0x15, - RT_NVME_SC_SGL_INVALID_OFFSET = 0x16, - RT_NVME_SC_RESERVED = 0x17, - RT_NVME_SC_HOST_ID_INCONSIST = 0x18, - RT_NVME_SC_KA_TIMEOUT_EXPIRED = 0x19, - RT_NVME_SC_KA_TIMEOUT_INVALID = 0x1a, - RT_NVME_SC_ABORTED_PREEMPT_ABORT = 0x1b, - RT_NVME_SC_SANITIZE_FAILED = 0x1c, - RT_NVME_SC_SANITIZE_IN_PROGRESS = 0x1d, - RT_NVME_SC_SGL_INVALID_GRANULARITY = 0x1e, - RT_NVME_SC_CMD_NOT_SUP_CMB_QUEUE = 0x1f, - RT_NVME_SC_NS_WRITE_PROTECTED = 0x20, - RT_NVME_SC_CMD_INTERRUPTED = 0x21, - RT_NVME_SC_TRANSIENT_TR_ERR = 0x22, - RT_NVME_SC_ADMIN_COMMAND_MEDIA_NOT_READY = 0x24, - RT_NVME_SC_INVALID_IO_CMD_SET = 0x2c, - - RT_NVME_SC_LBA_RANGE = 0x80, - RT_NVME_SC_CAP_EXCEEDED = 0x81, - RT_NVME_SC_NS_NOT_READY = 0x82, - RT_NVME_SC_RESERVATION_CONFLICT = 0x83, - RT_NVME_SC_FORMAT_IN_PROGRESS = 0x84, - - /* - * Command Specific Status: - */ - RT_NVME_SC_CQ_INVALID = 0x100, - RT_NVME_SC_QID_INVALID = 0x101, - RT_NVME_SC_QUEUE_SIZE = 0x102, - RT_NVME_SC_ABORT_LIMIT = 0x103, - RT_NVME_SC_ABORT_MISSING = 0x104, - RT_NVME_SC_ASYNC_LIMIT = 0x105, - RT_NVME_SC_FIRMWARE_SLOT = 0x106, - RT_NVME_SC_FIRMWARE_IMAGE = 0x107, - RT_NVME_SC_INVALID_VECTOR = 0x108, - RT_NVME_SC_INVALID_LOG_PAGE = 0x109, - RT_NVME_SC_INVALID_FORMAT = 0x10a, - RT_NVME_SC_FW_NEEDS_CONV_RESET = 0x10b, - RT_NVME_SC_INVALID_QUEUE = 0x10c, - RT_NVME_SC_FEATURE_NOT_SAVEABLE = 0x10d, - RT_NVME_SC_FEATURE_NOT_CHANGEABLE = 0x10e, - RT_NVME_SC_FEATURE_NOT_PER_NS = 0x10f, - RT_NVME_SC_FW_NEEDS_SUBSYS_RESET = 0x110, - RT_NVME_SC_FW_NEEDS_RESET = 0x111, - RT_NVME_SC_FW_NEEDS_MAX_TIME = 0x112, - RT_NVME_SC_FW_ACTIVATE_PROHIBITED = 0x113, - RT_NVME_SC_OVERLAPPING_RANGE = 0x114, - RT_NVME_SC_NS_INSUFFICIENT_CAP = 0x115, - RT_NVME_SC_NS_ID_UNAVAILABLE = 0x116, - RT_NVME_SC_NS_ALREADY_ATTACHED = 0x118, - RT_NVME_SC_NS_IS_PRIVATE = 0x119, - RT_NVME_SC_NS_NOT_ATTACHED = 0x11a, - RT_NVME_SC_THIN_PROV_NOT_SUPP = 0x11b, - RT_NVME_SC_CTRL_LIST_INVALID = 0x11c, - RT_NVME_SC_SELT_TEST_IN_PROGRESS = 0x11d, - RT_NVME_SC_BP_WRITE_PROHIBITED = 0x11e, - RT_NVME_SC_CTRL_ID_INVALID = 0x11f, - RT_NVME_SC_SEC_CTRL_STATE_INVALID = 0x120, - RT_NVME_SC_CTRL_RES_NUM_INVALID = 0x121, - RT_NVME_SC_RES_ID_INVALID = 0x122, - RT_NVME_SC_PMR_SAN_PROHIBITED = 0x123, - RT_NVME_SC_ANA_GROUP_ID_INVALID = 0x124, - RT_NVME_SC_ANA_ATTACH_FAILED = 0x125, - - /* - * I/O Command Set Specific - NVM commands: - */ - RT_NVME_SC_BAD_ATTRIBUTES = 0x180, - RT_NVME_SC_INVALID_PI = 0x181, - RT_NVME_SC_READ_ONLY = 0x182, - RT_NVME_SC_ONCS_NOT_SUPPORTED = 0x183, - - /* - * I/O Command Set Specific - Fabrics commands: - */ - RT_NVME_SC_CONNECT_FORMAT = 0x180, - RT_NVME_SC_CONNECT_CTRL_BUSY = 0x181, - RT_NVME_SC_CONNECT_INVALID_PARAM = 0x182, - RT_NVME_SC_CONNECT_RESTART_DISC = 0x183, - RT_NVME_SC_CONNECT_INVALID_HOST = 0x184, - - RT_NVME_SC_DISCOVERY_RESTART = 0x190, - RT_NVME_SC_AUTH_REQUIRED = 0x191, - - /* - * I/O Command Set Specific - Zoned commands: - */ - RT_NVME_SC_ZONE_BOUNDARY_ERROR = 0x1b8, - RT_NVME_SC_ZONE_FULL = 0x1b9, - RT_NVME_SC_ZONE_READ_ONLY = 0x1ba, - RT_NVME_SC_ZONE_OFFLINE = 0x1bb, - RT_NVME_SC_ZONE_INVALID_WRITE = 0x1bc, - RT_NVME_SC_ZONE_TOO_MANY_ACTIVE = 0x1bd, - RT_NVME_SC_ZONE_TOO_MANY_OPEN = 0x1be, - RT_NVME_SC_ZONE_INVALID_TRANSITION = 0x1bf, - - /* - * Media and Data Integrity Errors: - */ - RT_NVME_SC_WRITE_FAULT = 0x280, - RT_NVME_SC_READ_ERROR = 0x281, - RT_NVME_SC_GUARD_CHECK = 0x282, - RT_NVME_SC_APPTAG_CHECK = 0x283, - RT_NVME_SC_REFTAG_CHECK = 0x284, - RT_NVME_SC_COMPARE_FAILED = 0x285, - RT_NVME_SC_ACCESS_DENIED = 0x286, - RT_NVME_SC_UNWRITTEN_BLOCK = 0x287, - - /* - * Path-related Errors: - */ - RT_NVME_SC_INTERNAL_PATH_ERROR = 0x300, - RT_NVME_SC_ANA_PERSISTENT_LOSS = 0x301, - RT_NVME_SC_ANA_INACCESSIBLE = 0x302, - RT_NVME_SC_ANA_TRANSITION = 0x303, - RT_NVME_SC_CTRL_PATH_ERROR = 0x360, - RT_NVME_SC_HOST_PATH_ERROR = 0x370, - RT_NVME_SC_HOST_ABORTED_CMD = 0x371, - - RT_NVME_SC_CRD = 0x1800, - RT_NVME_SC_MORE = 0x2000, - RT_NVME_SC_DNR = 0x4000, -}; - -/* Admin commands */ -enum -{ - RT_NVME_ADMIN_OPCODE_DELETE_SQ = 0x00, - RT_NVME_ADMIN_OPCODE_CREATE_SQ = 0x01, - RT_NVME_ADMIN_OPCODE_GET_LOG_PAGE = 0x02, - RT_NVME_ADMIN_OPCODE_DELETE_CQ = 0x04, - RT_NVME_ADMIN_OPCODE_CREATE_CQ = 0x05, - RT_NVME_ADMIN_OPCODE_IDENTIFY = 0x06, - RT_NVME_ADMIN_OPCODE_ABORT_CMD = 0x08, - RT_NVME_ADMIN_OPCODE_SET_FEATURES = 0x09, - RT_NVME_ADMIN_OPCODE_GET_FEATURES = 0x0a, - RT_NVME_ADMIN_OPCODE_ASYNC_EVENT = 0x0c, - RT_NVME_ADMIN_OPCODE_NS_MGMT = 0x0d, - RT_NVME_ADMIN_OPCODE_ACTIVATE_FW = 0x10, - RT_NVME_ADMIN_OPCODE_DOWNLOAD_FW = 0x11, - RT_NVME_ADMIN_OPCODE_DEV_SELF_TEST = 0x14, - RT_NVME_ADMIN_OPCODE_NS_ATTACH = 0x15, - RT_NVME_ADMIN_OPCODE_KEEP_ALIVE = 0x18, - RT_NVME_ADMIN_OPCODE_DIRECTIVE_SEND = 0x19, - RT_NVME_ADMIN_OPCODE_DIRECTIVE_RECV = 0x1a, - RT_NVME_ADMIN_OPCODE_VIRTUAL_MGMT = 0x1c, - RT_NVME_ADMIN_OPCODE_NVME_MI_SEND = 0x1d, - RT_NVME_ADMIN_OPCODE_NVME_MI_RECV = 0x1e, - RT_NVME_ADMIN_OPCODE_DBBUF = 0x7c, - RT_NVME_ADMIN_OPCODE_FORMAT_NVM = 0x80, - RT_NVME_ADMIN_OPCODE_SECURITY_SEND = 0x81, - RT_NVME_ADMIN_OPCODE_SECURITY_RECV = 0x82, - RT_NVME_ADMIN_OPCODE_SANITIZE_NVM = 0x84, - RT_NVME_ADMIN_OPCODE_GET_LBA_STATUS = 0x86, - RT_NVME_ADMIN_OPCODE_VENDOR_START = 0xc0, -}; - -/* I/O commands */ -enum -{ - RT_NVME_CMD_FLUSH = 0x00, - RT_NVME_CMD_WRITE = 0x01, - RT_NVME_CMD_READ = 0x02, - RT_NVME_CMD_WRITE_UNCOR = 0x04, - RT_NVME_CMD_COMPARE = 0x05, - RT_NVME_CMD_WRITE_ZEROES = 0x08, - RT_NVME_CMD_DSM = 0x09, - RT_NVME_CMD_VERIFY = 0x0c, - RT_NVME_CMD_RESV_REGISTER = 0x0d, - RT_NVME_CMD_RESV_REPORT = 0x0e, - RT_NVME_CMD_RESV_ACQUIRE = 0x11, - RT_NVME_CMD_RESV_RELEASE = 0x15, - RT_NVME_CMD_ZONE_MGMT_SEND = 0x79, - RT_NVME_CMD_ZONE_MGMT_RECV = 0x7a, - RT_NVME_CMD_ZONE_APPEND = 0x7d, - RT_NVME_CMD_VENDOR_START = 0x80, -}; - -enum -{ - RT_NVME_PSDT_PRP = 0x0, - RT_NVME_PSDT_SGL_MPTR_CONTIGUOUS = 0x1, - RT_NVME_PSDT_SGL_MPTR_SGL = 0x2, -}; - -/* Commands flags */ -enum -{ - RT_NVME_CMD_FLAGS_FUSE_SHIFT = 0x00, - RT_NVME_CMD_FLAGS_PSDT_SHIFT = 0x06, -}; - -struct rt_nvme_command_common -{ - rt_uint8_t opcode; - rt_uint8_t flags; - rt_uint16_t cmdid; - rt_le32_t nsid; - rt_le32_t cmd_dw2[2]; - rt_le64_t metadata; - rt_le64_t prp1; - rt_le64_t prp2; - rt_le32_t cmd_dw10[6]; -}; - -rt_packed(struct rt_nvme_sgl_desc -{ - rt_le64_t adddress; - rt_le32_t length; - rt_uint8_t reserved[3]; -#define SGL_DESC_TYPE_DATA_BLOCK 0x0 -#define SGL_DESC_TYPE_BIT_BUCKET 0x1 -#define SGL_DESC_TYPE_SEGMENT 0x2 -#define SGL_DESC_TYPE_LAST_SEGMENT 0x3 -#define SGL_DESC_TYPE_KEYED_DATA_BLOCK 0x4 -#define SGL_DESC_TYPE_VENDOR_SPECIFIC 0xf - rt_uint8_t sgl_identify; -}); - -struct rt_nvme_command_rw -{ - rt_uint8_t opcode; - rt_uint8_t flags; - rt_uint16_t cmdid; - rt_le32_t nsid; - NVME_RSVD(8, 8); - rt_le64_t metadata; - union - { - struct - { - rt_le64_t prp1; - rt_le64_t prp2; - }; - struct rt_nvme_sgl_desc sgl; - }; - rt_le64_t slba; - rt_le16_t length; - rt_le16_t control; - rt_le32_t dsmgmt; - rt_le32_t reftag; - rt_le16_t apptag; - rt_le16_t appmask; -}; - -enum -{ - RT_NVME_RW_LR = 1 << 15, - RT_NVME_RW_FUA = 1 << 14, - RT_NVME_RW_APPEND_PIREMAP = 1 << 9, - RT_NVME_RW_DSM_FREQ_UNSPEC = 0, - RT_NVME_RW_DSM_FREQ_TYPICAL = 1, - RT_NVME_RW_DSM_FREQ_RARE = 2, - RT_NVME_RW_DSM_FREQ_READS = 3, - RT_NVME_RW_DSM_FREQ_WRITES = 4, - RT_NVME_RW_DSM_FREQ_RW = 5, - RT_NVME_RW_DSM_FREQ_ONCE = 6, - RT_NVME_RW_DSM_FREQ_PREFETCH = 7, - RT_NVME_RW_DSM_FREQ_TEMP = 8, - RT_NVME_RW_DSM_LATENCY_NONE = 0 << 4, - RT_NVME_RW_DSM_LATENCY_IDLE = 1 << 4, - RT_NVME_RW_DSM_LATENCY_NORM = 2 << 4, - RT_NVME_RW_DSM_LATENCY_LOW = 3 << 4, - RT_NVME_RW_DSM_SEQ_REQ = 1 << 6, - RT_NVME_RW_DSM_COMPRESSED = 1 << 7, - RT_NVME_RW_PRINFO_PRCHK_REF = 1 << 10, - RT_NVME_RW_PRINFO_PRCHK_APP = 1 << 11, - RT_NVME_RW_PRINFO_PRCHK_GUARD = 1 << 12, - RT_NVME_RW_PRINFO_PRACT = 1 << 13, - RT_NVME_RW_DTYPE_STREAMS = 1 << 4, - RT_NVME_WZ_DEAC = 1 << 9, -}; - -enum -{ - RT_NVME_QUEUE_PHYS_CONTIG = (1 << 0), - RT_NVME_CQ_IRQ_ENABLED = (1 << 1), - RT_NVME_SQ_PRIO_URGENT = (0 << 1), - RT_NVME_SQ_PRIO_HIGH = (1 << 1), - RT_NVME_SQ_PRIO_MEDIUM = (2 << 1), - RT_NVME_SQ_PRIO_LOW = (3 << 1), - RT_NVME_FEAT_ARBITRATION = 0x01, - RT_NVME_FEAT_POWER_MGMT = 0x02, - RT_NVME_FEAT_LBA_RANGE = 0x03, - RT_NVME_FEAT_TEMP_THRESH = 0x04, - RT_NVME_FEAT_ERR_RECOVERY = 0x05, - RT_NVME_FEAT_VOLATILE_WC = 0x06, - RT_NVME_FEAT_NUM_QUEUES = 0x07, - RT_NVME_FEAT_IRQ_COALESCE = 0x08, - RT_NVME_FEAT_IRQ_CONFIG = 0x09, - RT_NVME_FEAT_WRITE_ATOMIC = 0x0a, - RT_NVME_FEAT_ASYNC_EVENT = 0x0b, - RT_NVME_FEAT_AUTO_PST = 0x0c, - RT_NVME_FEAT_SW_PROGRESS = 0x80, - RT_NVME_FEAT_HOST_ID = 0x81, - RT_NVME_FEAT_RESV_MASK = 0x82, - RT_NVME_FEAT_RESV_PERSIST = 0x83, - RT_NVME_LOG_ERROR = 0x01, - RT_NVME_LOG_SMART = 0x02, - RT_NVME_LOG_FW_SLOT = 0x03, - RT_NVME_LOG_RESERVATION = 0x80, - RT_NVME_FWACT_REPL = (0 << 3), - RT_NVME_FWACT_REPL_ACTV = (1 << 3), - RT_NVME_FWACT_ACTV = (2 << 3), -}; - -struct rt_nvme_command_identify -{ - rt_uint8_t opcode; - rt_uint8_t flags; - rt_uint16_t cmdid; - rt_le32_t nsid; - NVME_RSVD(8, 16); - rt_le64_t prp1; - rt_le64_t prp2; - rt_le32_t cns; - NVME_RSVD(64, 20); -}; - -struct rt_nvme_command_features -{ - rt_uint8_t opcode; - rt_uint8_t flags; - rt_uint16_t cmdid; - rt_le32_t nsid; - NVME_RSVD(8, 16); - rt_le64_t prp1; - rt_le64_t prp2; - rt_le32_t fid; - rt_le32_t dword11; - NVME_RSVD(68, 16); -}; - -struct rt_nvme_command_create_cq -{ - rt_uint8_t opcode; - rt_uint8_t flags; - rt_uint16_t cmdid; - NVME_RSVD(4, 20); - rt_le64_t prp1; - NVME_RSVD(32, 8); - rt_le16_t cqid; - rt_le16_t qsize; - rt_le16_t cq_flags; - rt_le16_t irq_vector; - NVME_RSVD(104, 16); -}; - -struct rt_nvme_command_create_sq -{ - rt_uint8_t opcode; - rt_uint8_t flags; - rt_uint16_t cmdid; - NVME_RSVD(4, 20); - rt_le64_t prp1; - NVME_RSVD(32, 8); - rt_le16_t sqid; - rt_le16_t qsize; - rt_le16_t sq_flags; - rt_le16_t cqid; - NVME_RSVD(104, 16); -}; - -struct rt_nvme_command_delete_queue -{ - rt_uint8_t opcode; - rt_uint8_t flags; - rt_uint16_t cmdid; - NVME_RSVD(4, 36); - rt_le16_t qid; - NVME_RSVD(42, 22); -}; - -struct rt_nvme_command_write_zeroes -{ - rt_uint8_t opcode; - rt_uint8_t flags; - rt_uint16_t cmdid; - rt_le32_t nsid; - NVME_RSVD(8, 8); - rt_le64_t metadata; - rt_le64_t prp1; - rt_le64_t prp2; - rt_le64_t slba; - rt_le16_t length; - rt_le16_t control; - rt_le32_t dsmgmt; - rt_le32_t reftag; - rt_le16_t apptag; - rt_le16_t appmask; -}; - -struct rt_nvme_command -{ - union - { - struct rt_nvme_command_common common; - struct rt_nvme_command_rw rw; - struct rt_nvme_command_identify identify; - struct rt_nvme_command_features features; - struct rt_nvme_command_create_cq create_cq; - struct rt_nvme_command_create_sq create_sq; - struct rt_nvme_command_delete_queue delete_queue; - struct rt_nvme_command_write_zeroes write_zeroes; - }; -}; - -struct rt_nvme_completion -{ - union - { - rt_le16_t u16; - rt_le32_t u32; - rt_le64_t u64; - } result; - rt_le16_t sq_head; /* How much of this queue may be reclaimed */ - rt_le16_t sq_id; /* Submission queue that generated this entry */ - rt_uint16_t cmdid; /* Which command completed */ - rt_le16_t status; /* Command status */ -}; - -enum -{ - RT_NVME_REG_CAP = 0x0000, /* Controller Capabilities */ - RT_NVME_REG_VS = 0x0008, /* Version */ - RT_NVME_REG_INTMS = 0x000c, /* Interrupt Mask Set */ - RT_NVME_REG_INTMC = 0x0010, /* Interrupt Mask Clear */ - RT_NVME_REG_CC = 0x0014, /* Controller Configuration */ - RT_NVME_REG_CSTS = 0x001c, /* Controller Status */ - RT_NVME_REG_NSSR = 0x0020, /* NVM Subsystem Reset */ - RT_NVME_REG_AQA = 0x0024, /* Admin Queue Attributes */ - RT_NVME_REG_ASQ = 0x0028, /* Admin SQ Base Address */ - RT_NVME_REG_ACQ = 0x0030, /* Admin CQ Base Address */ - RT_NVME_REG_CMBLOC = 0x0038, /* Controller Memory Buffer Location */ - RT_NVME_REG_CMBSZ = 0x003c, /* Controller Memory Buffer Size */ - RT_NVME_REG_BPINFO = 0x0040, /* Boot Partition Information */ - RT_NVME_REG_BPRSEL = 0x0044, /* Boot Partition Read Select */ - RT_NVME_REG_BPMBL = 0x0048, /* Boot Partition Memory Buffer Location */ - RT_NVME_REG_CMBMSC = 0x0050, /* Controller Memory Buffer Memory Space Control */ - RT_NVME_REG_CRTO = 0x0068, /* Controller Ready Timeouts */ - RT_NVME_REG_PMRCAP = 0x0e00, /* Persistent Memory Capabilities */ - RT_NVME_REG_PMRCTL = 0x0e04, /* Persistent Memory Region Control */ - RT_NVME_REG_PMRSTS = 0x0e08, /* Persistent Memory Region Status */ - RT_NVME_REG_PMREBS = 0x0e0c, /* Persistent Memory Region Elasticity Buffer Size */ - RT_NVME_REG_PMRSWTP = 0x0e10, /* Persistent Memory Region Sustained Write Throughput */ - RT_NVME_REG_DBS = 0x1000, /* SQ 0 Tail Doorbell */ -}; - -#define RT_NVME_CAP_MQES(cap) ((cap) & 0xffff) -#define RT_NVME_CAP_TIMEOUT(cap) (((cap) >> 24) & 0xff) -#define RT_NVME_CAP_STRIDE(cap) (((cap) >> 32) & 0xf) -#define RT_NVME_CAP_MPSMIN(cap) (((cap) >> 48) & 0xf) -#define RT_NVME_CAP_MPSMAX(cap) (((cap) >> 52) & 0xf) - -#define RT_NVME_VS(major, minor) (((major) << 16) | ((minor) << 8)) - -#define RT_NVME_AQ_DEPTH 32 -#define RT_NVME_NR_AEN_COMMANDS 1 -#define RT_NVME_AQ_BLK_MQ_DEPTH (RT_NVME_AQ_DEPTH - RT_NVME_NR_AEN_COMMANDS) -#define RT_NVME_AQ_MQ_TAG_DEPTH (RT_NVME_AQ_BLK_MQ_DEPTH - 1) - -enum -{ - RT_NVME_CC_ENABLE = 1 << 0, - RT_NVME_CC_CSS_NVM = 0 << 4, - RT_NVME_CC_MPS_SHIFT = 7, - RT_NVME_CC_ARB_RR = 0 << 11, - RT_NVME_CC_ARB_WRRU = 1 << 11, - RT_NVME_CC_ARB_VS = 7 << 11, - RT_NVME_CC_SHN_NONE = 0 << 14, - RT_NVME_CC_SHN_NORMAL = 1 << 14, - RT_NVME_CC_SHN_ABRUPT = 2 << 14, - RT_NVME_CC_SHN_MASK = 3 << 14, - RT_NVME_CC_IOSQES = 6 << 16, - RT_NVME_CC_IOCQES = 4 << 20, - RT_NVME_CSTS_RDY = 1 << 0, - RT_NVME_CSTS_CFS = 1 << 1, - RT_NVME_CSTS_SHST_NORMAL = 0 << 2, - RT_NVME_CSTS_SHST_OCCUR = 1 << 2, - RT_NVME_CSTS_SHST_CMPLT = 2 << 2, - RT_NVME_CSTS_SHST_MASK = 3 << 2, -}; - -rt_packed(struct rt_nvme_id_power_state -{ - rt_le16_t mp; /* Maximum Power */ - NVME_RSVD(1, 1); - rt_uint8_t mxps_nops; /* Max Power Scale, Non-Operational State */ - rt_le32_t enlat; /* Entry Latency: microseconds */ - rt_le32_t exlat; /* Exit Latency: microseconds */ - rt_uint8_t rrt; /* Relative Read Throughput */ - rt_uint8_t rrl; /* Relative Read Latency */ - rt_uint8_t rwt; /* Relative Write Throughput */ - rt_uint8_t rwl; /* Relative Write Latency */ - rt_le16_t idlp; /* Idle Power */ - rt_uint8_t ips; /* Idle Power Scale */ - NVME_RSVD(19, 1); - rt_le16_t actp; /* Active Power */ - rt_uint8_t apw_aps; /* Active Power Workload, Active Power Scale */ - NVME_RSVD(23, 9); -}); - -rt_packed(struct rt_nvme_id_ctrl -{ - /* Controller Capabilities and Features */ - rt_le16_t vid; /* PCI Vendor ID */ - rt_le16_t ssvid; /* PCI Subsystem Vendor */ - char sn[20]; /* Serial Number */ - char mn[40]; /* Model Number */ - char fr[8]; /* Firmware Revision */ - rt_uint8_t rab; /* Recommended Arbitration Burst */ - rt_uint8_t ieee[3]; /* IEEE OUI Identifier */ - rt_uint8_t mic; /* Controller Multi-Path I/O and Namespace Sharing Capabilities */ - rt_uint8_t mdts; /* Maximum Data Transfer Size */ - rt_uint16_t cntlid; /* Controller ID */ - rt_uint32_t ver; /* Version */ - rt_uint32_t rtd3r; /* RTD3 Resume Latency */ - rt_uint32_t rtd3e; /* RTD3 Entry Latency */ - rt_uint32_t oaes; /* Optional Asynchronous Events Supported */ -#define RT_NVME_ID_CTRATT_ELBAS 15 /* Extended LBA Formats Supported */ -#define RT_NVME_ID_CTRATT_DNVMS 14 /* Delete NVM Set */ -#define RT_NVME_ID_CTRATT_DEG 13 /* Delete Endurance Group */ -#define RT_NVME_ID_CTRATT_VCM 12 /* Variable Capacity Management */ -#define RT_NVME_ID_CTRATT_FCM 11 /* Fixed Capacity Management */ -#define RT_NVME_ID_CTRATT_MDS 10 /* Multi-Domain Subsystem */ -#define RT_NVME_ID_CTRATT_UUIDL 9 /* UUID List */ -#define RT_NVME_ID_CTRATT_SQA 8 /* SQ Associations */ -#define RT_NVME_ID_CTRATT_NG 7 /* Namespace Granularity */ -#define RT_NVME_ID_CTRATT_TBKAS 6 /* Traffic Based Keep Alive Support */ -#define RT_NVME_ID_CTRATT_PLM 5 /* Predictable Latency Mode */ -#define RT_NVME_ID_CTRATT_EG 4 /* Endurance Groups */ -#define RT_NVME_ID_CTRATT_RRL 3 /* Read Recovery Levels */ -#define RT_NVME_ID_CTRATT_NVMS 2 /* NVM Sets */ -#define RT_NVME_ID_CTRATT_NOPSPM 1 /* Non-Operational Power State Permissive Mode */ -#define RT_NVME_ID_CTRATT_HIS 0 /* Host Identifier Support */ - rt_uint32_t ctratt; /* Controller Attributes */ - rt_uint16_t rrls; /* Read Recovery Levels Supported */ - NVME_RSVD(102, 9); - rt_uint8_t cntrltype; /* Controller Type */ - rt_uint8_t fguid[16]; /* FRU Globally Unique Identifier */ - rt_uint16_t crdt1; /* Command Retry Delay Time 1 */ - rt_uint16_t crdt2; /* Command Retry Delay Time 2 */ - rt_uint16_t crdt3; /* Command Retry Delay Time 3 */ - NVME_RSVD(134, 119); -#define RT_NVME_ID_NVMSR_NVMEE 1 /* NVMe Enclosure */ -#define RT_NVME_ID_NVMSR_NVMESD 0 /* NVMe Storage Device */ - rt_uint8_t nvmsr; /* NVM Subsystem Report */ - -#define RT_NVME_ID_VWCI_VWCRV 7 /* VPD Write Cycles Remaining Valid */ -#define RT_NVME_ID_VWCI_VWCR 0 /* VPD Write Cycles Remaining */ - rt_uint8_t vwci; /* VPD Write Cycle Information */ -#define RT_NVME_ID_MEC_PCIEME 1 /* PCIe Port Management Endpoint */ -#define RT_NVME_ID_MEC_SMBUSME 0 /* SMBus/I2C Port Management Endpoint */ - rt_uint8_t mec; /* Management Endpoint Capabilities */ - - /* Admin Command Set Attributes & Optional Controller Capabilities */ - rt_le16_t oacs; /* Optional Admin Command Support */ - rt_uint8_t acl; /* Abort Command Limit */ - rt_uint8_t aerl; /* Asynchronous Event Request Limit */ -#define RT_NVME_ID_FRMW_SMUD 5 /* Support Multiple Update Detection */ -#define RT_NVME_ID_FRMW_FAWR 4 /* Firmware Activation Without Reset */ -#define RT_NVME_ID_FRMW_NOFS 1 /* Number Of Firmware Slots */ -#define RT_NVME_ID_FRMW_FFSRO 0 /* First Firmware Slot Read Only */ - rt_uint8_t frmw; /* Firmware Updates */ - rt_uint8_t lpa; /* Log Page Attributes */ - rt_uint8_t elpe; /* Error Log Page Entries */ - rt_uint8_t npss; /* Number of Power States Support */ - rt_uint8_t avscc; /* Admin Vendor Specific Command Configuration */ - rt_uint8_t apsta; /* Autonomous Power State Transition Attributes */ - rt_le16_t wctemp; /* Warning Composite Temperature Threshold */ - rt_le16_t cctemp; /* Critical Composite Temperature Threshold */ - rt_uint16_t mtfa; /* Maximum Time for Firmware Activation */ - rt_uint32_t hmpre; /* Host Memory Buffer Preferred Size */ - rt_uint32_t hmmin; /* Host Memory Buffer Minimum Size */ - rt_uint8_t tnvmcap[16]; /* Total NVM Capacity */ - rt_uint8_t unvmcap[16]; /* Unallocated NVM Capacity */ -#define RT_NVME_ID_RPMBS_ASZ 24 /* Access Size */ -#define RT_NVME_ID_RPMBS_TSZ 16 /* Total Size */ -#define RT_NVME_ID_RPMBS_AM 3 /* Authentication Method */ -#define RT_NVME_ID_RPMBS_NORPMBU 2 /* Number of RPMB Units */ - rt_uint32_t rpmbs; /* Replay Protected Memory Block Support */ - rt_uint16_t edstt; /* Extended Device Self-test Time */ - rt_uint8_t dsto; /* Device Self-test Options */ - rt_uint8_t fwug; /* Firmware Update Granularity */ - rt_uint16_t kas; /* Keep Alive Support */ - rt_uint16_t hctma; /* Host Controlled Thermal Management Attributes */ - rt_uint16_t mntmt; /* Minimum Thermal Management Temperature */ - rt_uint16_t mxtmt; /* Maximum Thermal Management Temperature */ -#define RT_NVME_ID_SANICAP_NODMMAS 30 /* No-Deallocate Modifies Media After Sanitize */ -#define RT_NVME_ID_SANICAP_NDI 29 /* No-Deallocate Inhibited */ -#define RT_NVME_ID_SANICAP_OWS 2 /* Overwrite Support */ -#define RT_NVME_ID_SANICAP_BES 1 /* Block Erase Support */ -#define RT_NVME_ID_SANICAP_CES 0 /* Crypto Erase Support */ - rt_uint32_t sanicap; /* Sanitize Capabilities */ - rt_uint32_t hmminds; /* Host Memory Buffer Minimum Descriptor Entry Size */ - rt_uint16_t hmmaxd; /* Host Memory Maximum Descriptors Entries */ - rt_uint16_t nsetidmax; /* NVM Set Identifier Maximum */ - rt_uint16_t endgidmax; /* Endurance Group Identifier Maximum */ - rt_uint8_t anatt; /* ANA Transition Time */ - rt_uint8_t anacap; /* Asymmetric Namespace Access Capabilities */ - rt_uint32_t anagrpmax; /* ANA Group Identifier Maximum */ - rt_uint32_t nanagrpid; /* Number of ANA Group Identifiers */ - rt_uint32_t pels; /* Persistent Event Log Size */ - rt_uint16_t dmid; /* Domain Identifier */ - NVME_RSVD(358, 10); - rt_uint8_t megcap[16]; /* Max Endurance Group Capacity */ - NVME_RSVD(384, 128); - - /* NVM Command Set Attributes */ - rt_uint8_t sqes; /* Submission Queue Entry Size */ - rt_uint8_t cqes; /* Completion Queue Entry Size */ - rt_le16_t maxcmd; /* Maximum Outstanding Commands */ - rt_le32_t nn; /* Number of Namespaces */ - rt_le16_t oncs; /* Optional NVM Command Support */ - rt_le16_t fuses; /* Fused Operation Support */ - rt_uint8_t fna; /* Format NVM Attributes */ - rt_uint8_t vwc; /* Volatile Write Cache */ - rt_le16_t awun; /* Atomic Write Unit Normal */ - rt_le16_t awupf; /* Atomic Write Unit Power Fail */ - rt_uint8_t nvscc; /* I/O Command Set Vendor Specific Command Configuration */ - rt_uint8_t nwpc; /* Namespace Write Protection Capabilities */ - rt_le16_t acwu; /* Atomic Compare & Write Unit */ - rt_le16_t cdfs; /* Copy Descriptor Formats Supported */ -#define RT_NVME_ID_SGL_SUPPORT_MASK 0x3 - rt_le32_t sgls; /* SGL Support */ - rt_uint32_t mnan; /* Maximum Number of Allowed Namespaces */ - char maxdna[16]; /* Maximum Domain Namespace Attachments */ - rt_le32_t maxcna; /* Maximum I/O Controller Namespace Attachments */ - NVME_RSVD(564, 204); - rt_uint8_t subnqn[256]; /* NVM Subsystem NVMe Qualified Name */ - NVME_RSVD(1024, 768); - rt_le32_t ioccsz; /* I/O Queue Command Capsule Supported Size */ - rt_le32_t iorcsz; /* I/O Queue Response Capsule Supported Size */ - rt_le16_t icdoff; /* In Capsule Data Offset */ - rt_uint8_t ctrattr; /* Fabrics Controller Attributes */ - rt_uint8_t msdbd; /* Maximum SGL Data Block Descriptors */ - rt_le16_t ofcs; /* Optional Fabric Commands Support */ - rt_uint8_t dctype; - NVME_RSVD(1807, 241); - - /* Power State Descriptors */ - struct rt_nvme_id_power_state psd[32]; - - /* Vendor Specific */ - rt_uint8_t vs[1024]; -}); - -enum -{ - RT_NVME_CTRL_CMIC_MULTI_PORT = 1 << 0, - RT_NVME_CTRL_CMIC_MULTI_CTRL = 1 << 1, - RT_NVME_CTRL_CMIC_ANA = 1 << 3, - RT_NVME_CTRL_ONCS_COMPARE = 1 << 0, - RT_NVME_CTRL_ONCS_WRITE_UNCORRECTABLE = 1 << 1, - RT_NVME_CTRL_ONCS_DSM = 1 << 2, - RT_NVME_CTRL_ONCS_WRITE_ZEROES = 1 << 3, - RT_NVME_CTRL_ONCS_RESERVATIONS = 1 << 5, - RT_NVME_CTRL_ONCS_TIMESTAMP = 1 << 6, - RT_NVME_CTRL_VWC_PRESENT = 1 << 0, - RT_NVME_CTRL_OACS_SEC_SUPP = 1 << 0, - RT_NVME_CTRL_OACS_NS_MNGT_SUPP = 1 << 3, - RT_NVME_CTRL_OACS_DIRECTIVES = 1 << 5, - RT_NVME_CTRL_OACS_DBBUF_SUPP = 1 << 8, - RT_NVME_CTRL_LPA_CMD_EFFECTS_LOG = 1 << 1, - RT_NVME_CTRL_CTRATT_128_ID = 1 << 0, - RT_NVME_CTRL_CTRATT_NON_OP_PSP = 1 << 1, - RT_NVME_CTRL_CTRATT_NVM_SETS = 1 << 2, - RT_NVME_CTRL_CTRATT_READ_RECV_LVLS = 1 << 3, - RT_NVME_CTRL_CTRATT_ENDURANCE_GROUPS = 1 << 4, - RT_NVME_CTRL_CTRATT_PREDICTABLE_LAT = 1 << 5, - RT_NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY = 1 << 7, - RT_NVME_CTRL_CTRATT_UUID_LIST = 1 << 9, -}; - -struct rt_nvme_lba_format -{ - rt_le16_t ms; /* Metadata size */ - rt_uint8_t ds; /* Data size */ - rt_uint8_t rp; /* Relative performance */ -}; - -rt_packed(struct rt_nvme_id_ns -{ - rt_le64_t nsze; /* Namespace size */ - rt_le64_t ncap; /* Namespace capacity */ - rt_le64_t nuse; /* Namespace utilization */ - rt_uint8_t nsfeat; /* Namespace features */ - rt_uint8_t nlbaf; /* Number of lba formats */ - rt_uint8_t flbas; /* Formatted lba size */ - rt_uint8_t mc; /* Metadata capabilities */ - rt_uint8_t dpc; /* End-to-end data protection capabilities */ - rt_uint8_t dps; /* End-to-end data protection type settings */ - rt_uint8_t nmic; /* Namespace Multi-path I/O and Namespace Sharing Capabilities */ - rt_uint8_t rescap; /* Reservation Capabilities */ - rt_uint8_t fpi; /* Format Progress Indicator */ - rt_uint8_t dlfeat; /* Deallocate Logical Block Features */ - rt_le16_t nawun; /* Namespace Atomic Write Unit Normal */ - rt_le16_t nawupf; /* Namespace Atomic Write Unit Power Fail */ - rt_le16_t nacwu; /* Namespace Atomic Compare & Write Unit */ - rt_le16_t nabsn; /* Namespace Atomic Boundary Size Normal */ - rt_le16_t nabo; /* Namespace Atomic Boundary Offset */ - rt_le16_t nabspf; /* Namespace Atomic Boundary Size Power Fail */ - rt_uint16_t noiob; /* Namespace Optimal IO Boundary */ - rt_le64_t nvmcap[2]; /* NVMe Capacity */ - rt_uint16_t npwg; /* Namespace Preferred Write Granularity */ - rt_uint16_t npwa; /* Namespace Preferred Write Alignment */ - rt_uint16_t npdg; /* Namespace Preferred Deallocate Granularity */ - rt_uint16_t npda; /* Namespace Preferred Deallocate Alignment */ - rt_uint16_t nows; /* Namespace Optimal Write Size */ - NVME_RSVD(118, 18); - rt_uint32_t anagrpid; /* ANA Group Identifier */ - NVME_RSVD(139, 3); - rt_uint8_t nsattr; /* Namespace Attributes */ - rt_uint16_t nvmsetid; /* NVMe Set Identifier */ - rt_uint16_t endgid; /* Endurance Group Identifier */ - rt_uint8_t nguid[16]; /* Namespace Globally Unique Identifier */ - rt_uint8_t eui64[8]; /* IEEE Extended Unique Identifier */ - - /* Logical Block Address Format */ - struct rt_nvme_lba_format lbaf[16]; - NVME_RSVD(171, 192); - - /* Vendor specific */ - rt_uint8_t vs[3712]; -}); - -enum -{ - RT_NVME_NS_FEAT_THIN = 1 << 0, - RT_NVME_NS_FLBAS_LBA_MASK = 0xf, - RT_NVME_NS_FLBAS_LBA_UMASK = 0x60, - RT_NVME_NS_FLBAS_LBA_SHIFT = 1, - RT_NVME_NS_FLBAS_META_EXT = 0x10, - RT_NVME_LBAF_RP_BEST = 0, - RT_NVME_LBAF_RP_BETTER = 1, - RT_NVME_LBAF_RP_GOOD = 2, - RT_NVME_LBAF_RP_DEGRADED = 3, - RT_NVME_NS_DPC_PI_LAST = 1 << 4, - RT_NVME_NS_DPC_PI_FIRST = 1 << 3, - RT_NVME_NS_DPC_PI_TYPE3 = 1 << 2, - RT_NVME_NS_DPC_PI_TYPE2 = 1 << 1, - RT_NVME_NS_DPC_PI_TYPE1 = 1 << 0, - RT_NVME_NS_DPS_PI_FIRST = 1 << 3, - RT_NVME_NS_DPS_PI_MASK = 0x7, - RT_NVME_NS_DPS_PI_TYPE1 = 1, - RT_NVME_NS_DPS_PI_TYPE2 = 2, - RT_NVME_NS_DPS_PI_TYPE3 = 3, -}; - -struct rt_nvme_ops; -struct rt_nvme_controller; - -/* - * An NVM Express queue. Each device has at least two (one for admin commands - * and one for I/O commands). - */ -struct rt_nvme_queue -{ - struct rt_nvme_controller *nvme; - struct rt_nvme_command *sq_cmds; - struct rt_nvme_completion *cq_entry; - - rt_ubase_t sq_cmds_phy; - rt_ubase_t cq_entry_phy; - - rt_uint32_t *doorbell; - rt_uint16_t qid; - rt_uint16_t depth; - rt_uint16_t sq_head; - rt_uint16_t sq_tail; - rt_uint16_t cq_head; - rt_uint16_t cq_phase; - - rt_err_t err; - struct rt_nvme_command *cmd; - - struct rt_completion done; - struct rt_spinlock lock; -}; - -struct rt_nvme_controller -{ - rt_list_t list; - struct rt_device *dev; - - int nvme_id; - char name[RT_NAME_MAX]; - - void *regs; - rt_uint64_t cap; - rt_uint32_t page_shift; - rt_uint32_t page_size; - rt_uint32_t queue_depth; - rt_uint32_t io_queue_max; - rt_uint32_t ctrl_config; - rt_uint32_t max_transfer_shift:8; - rt_uint32_t volatile_write_cache:8; - rt_uint32_t write_zeroes:1; - rt_uint32_t sgl_mode:2; - rt_uint32_t doorbell_stride; - rt_uint32_t *doorbell_tbl; - - const struct rt_nvme_ops *ops; - -#define RT_USING_NVME_QUEUE (1 + (RT_USING_NVME_IO_QUEUE * RT_CPUS_NR)) - int irqs_nr; - int irqs[RT_USING_NVME_QUEUE]; - union - { - struct - { - struct rt_nvme_queue admin_queue; - struct rt_nvme_queue io_queues[RT_USING_NVME_IO_QUEUE * RT_CPUS_NR]; - }; - struct rt_nvme_queue queue[RT_USING_NVME_QUEUE]; - }; - - volatile rt_atomic_t cmdid; - volatile rt_atomic_t ioqid[RT_CPUS_NR]; - - rt_list_t ns_nodes; -}; - -struct rt_nvme_device -{ - struct rt_blk_disk parent; - struct rt_nvme_controller *ctrl; - - rt_list_t list; - - rt_uint32_t nsid; - rt_uint32_t lba_shift; - struct rt_nvme_id_ns id; -}; -#define rt_disk_to_nvme_device(disk) rt_container_of(disk, struct rt_nvme_device, parent) - -struct rt_nvme_ops -{ - const char *name; - - /* Controller-specific NVM Express queue setup */ - rt_err_t (*setup_queue)(struct rt_nvme_queue *queue); - /* Controller-specific NVM Express queue cleanup */ - rt_err_t (*cleanup_queue)(struct rt_nvme_queue *queue); - /* Controller-specific NVM Express command submission */ - rt_err_t (*submit_cmd)(struct rt_nvme_queue *queue, struct rt_nvme_command *cmd); - /* Controller-specific NVM Express command completion */ - void (*complete_cmd)(struct rt_nvme_queue *queue, struct rt_nvme_command *cmd); -}; - -rt_err_t rt_nvme_controller_register(struct rt_nvme_controller *nvme); -rt_err_t rt_nvme_controller_unregister(struct rt_nvme_controller *nvme); - -#endif /* __NVME_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/ofw.h b/rt-thread/components/drivers/include/drivers/ofw.h index 3f23017..7531dfe 100644 --- a/rt-thread/components/drivers/include/drivers/ofw.h +++ b/rt-thread/components/drivers/include/drivers/ofw.h @@ -37,7 +37,6 @@ struct rt_ofw_node /* phandles range from 1 to 2^32-2 (0xfffffffe) */ rt_phandle phandle; - struct rt_device *dev; struct rt_ofw_prop *props; struct rt_ofw_node *parent; struct rt_ofw_node *child; @@ -377,9 +376,9 @@ rt_inline rt_bool_t rt_ofw_node_is_type(const struct rt_ofw_node *np, const char for (np = rt_ofw_find_node_by_type(RT_NULL, type); np; \ np = rt_ofw_find_node_by_type(np, type)) -#define rt_ofw_foreach_node_by_compatible(np, compatible) \ - for (np = rt_ofw_find_node_by_compatible(RT_NULL, compatible); np; \ - np = rt_ofw_find_node_by_compatible(np, compatible)) +#define rt_ofw_foreach_node_by_compatible(np, type, compatible) \ + for (np = rt_ofw_find_node_by_compatible(RT_NULL, type, compatible); np; \ + np = rt_ofw_find_node_by_compatible(np, type, compatible)) #define rt_ofw_foreach_node_by_ids_r(np, id, ids) \ for (np = rt_ofw_find_node_by_ids_r(RT_NULL, ids, id); \ diff --git a/rt-thread/components/drivers/include/drivers/ofw_fdt.h b/rt-thread/components/drivers/include/drivers/ofw_fdt.h index 7aeec71..4db4ece 100644 --- a/rt-thread/components/drivers/include/drivers/ofw_fdt.h +++ b/rt-thread/components/drivers/include/drivers/ofw_fdt.h @@ -70,7 +70,6 @@ rt_err_t rt_fdt_boot_dump(void); void rt_fdt_earlycon_output(const char *str); void rt_fdt_earlycon_kick(int why); rt_err_t rt_fdt_scan_chosen_stdout(void); -rt_err_t rt_fdt_bootargs_select(const char *key, int index, const char **out_result); rt_err_t rt_fdt_unflatten(void); struct rt_ofw_node *rt_fdt_unflatten_single(void *fdt); diff --git a/rt-thread/components/drivers/include/drivers/ofw_io.h b/rt-thread/components/drivers/include/drivers/ofw_io.h index f458435..4ebfbe2 100644 --- a/rt-thread/components/drivers/include/drivers/ofw_io.h +++ b/rt-thread/components/drivers/include/drivers/ofw_io.h @@ -26,27 +26,6 @@ rt_err_t rt_ofw_get_address_by_name(struct rt_ofw_node *np, const char *name, int rt_ofw_get_address_array(struct rt_ofw_node *np, int nr, rt_uint64_t *out_regs); rt_uint64_t rt_ofw_translate_address(struct rt_ofw_node *np, const char *range_type, rt_uint64_t address); -rt_uint64_t rt_ofw_reverse_address(struct rt_ofw_node *np, const char *range_type, rt_uint64_t address); - -rt_inline rt_uint64_t rt_ofw_translate_dma2cpu(struct rt_ofw_node *np, rt_uint64_t address) -{ - rt_uint64_t bus_addr, cpu_addr; - - bus_addr = rt_ofw_reverse_address(np, "dma-ranges", address); - cpu_addr = rt_ofw_translate_address(np, "ranges", bus_addr); - - return cpu_addr != ~0ULL ? cpu_addr : address; -} - -rt_inline rt_uint64_t rt_ofw_translate_cpu2dma(struct rt_ofw_node *np, rt_uint64_t address) -{ - rt_uint64_t bus_addr, dma_addr; - - bus_addr = rt_ofw_reverse_address(np, "ranges", address); - dma_addr = rt_ofw_translate_address(np, "dma-ranges", bus_addr); - - return dma_addr != ~0ULL ? dma_addr : address; -} void *rt_ofw_iomap(struct rt_ofw_node *np, int index); void *rt_ofw_iomap_by_name(struct rt_ofw_node *np, const char *name); diff --git a/rt-thread/components/drivers/include/drivers/pci.h b/rt-thread/components/drivers/include/drivers/pci.h deleted file mode 100644 index 1ae4393..0000000 --- a/rt-thread/components/drivers/include/drivers/pci.h +++ /dev/null @@ -1,604 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-08-25 GuEe-GUI first version - */ - -#ifndef __PCI_H__ -#define __PCI_H__ - -#include -#include -#include -#include -#include -#include -#include - -#include "../../pci/pci_ids.h" -#include "../../pci/pci_regs.h" - -#define RT_PCI_INTX_PIN_MAX 4 -#define RT_PCI_BAR_NR_MAX 6 -#define RT_PCI_DEVICE_MAX 32 -#define RT_PCI_FUNCTION_MAX 8 - -#define RT_PCI_FIND_CAP_TTL 48 - -/* - * The PCI interface treats multi-function devices as independent - * devices. The slot/function address of each device is encoded - * in a single byte as follows: - * - * 7:3 = slot - * 2:0 = function - */ -#define RT_PCI_DEVID(bus, devfn) ((((rt_uint16_t)(bus)) << 8) | (devfn)) -#define RT_PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) -#define RT_PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) -#define RT_PCI_FUNC(devfn) ((devfn) & 0x07) - -#define PCIE_LINK_STATE_L0S RT_BIT(0) -#define PCIE_LINK_STATE_L1 RT_BIT(1) -#define PCIE_LINK_STATE_CLKPM RT_BIT(2) -#define PCIE_LINK_STATE_L1_1 RT_BIT(3) -#define PCIE_LINK_STATE_L1_2 RT_BIT(4) -#define PCIE_LINK_STATE_L1_1_PCIPM RT_BIT(5) -#define PCIE_LINK_STATE_L1_2_PCIPM RT_BIT(6) -#define PCIE_LINK_STATE_ALL \ -( \ - PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | \ - PCIE_LINK_STATE_CLKPM | \ - PCIE_LINK_STATE_L1_1 | PCIE_LINK_STATE_L1_2 | \ - PCIE_LINK_STATE_L1_1_PCIPM | PCIE_LINK_STATE_L1_2_PCIPM \ -) - -struct rt_pci_bus_region -{ - rt_uint64_t phy_addr; - rt_uint64_t cpu_addr; - rt_uint64_t size; - - rt_uint64_t bus_start; - -#define PCI_BUS_REGION_F_NONE 0xffffffff /* PCI no memory */ -#define PCI_BUS_REGION_F_MEM 0x00000000 /* PCI memory space */ -#define PCI_BUS_REGION_F_IO 0x00000001 /* PCI IO space */ -#define PCI_BUS_REGION_F_PREFETCH 0x00000008 /* Prefetchable PCI memory */ - rt_ubase_t flags; -}; - -struct rt_pci_bus_resource -{ - rt_ubase_t base; - rt_size_t size; - - rt_ubase_t flags; -}; - -/* - * PCI topology: - * - * +-----+-----+ +-------------+ PCI Bus 0 +------------+ PCI Bus 1 - * | RAM | CPU |---------| Host Bridge |--------+-----| PCI Bridge |-----+ - * +-----+-----+ +-------------+ | +------------+ | +-------------+ - * | +----| End Point 2 | - * +-------------+ +-------------+ | +-------------+ | +-------------+ - * | End Point 5 |----+ | End Point 0 |-------+ | End Point 3 |----+ - * +-------------+ | +-------------+ | +-------------+ | - * | | | - * +-------------+ | +-------------+ | +-------------+ | +-------------+ - * | End Point 6 |----+----| ISA Bridge |-------+-----| End Point 1 | +----| End Point 4 | - * +-------------+ +-------------+ | +-------------+ +-------------+ - * | - * +------+ +----------------+ | - * | Port |---------| CardBus Bridge |----+ - * +------+ +----------------+ - */ - -struct rt_pci_bus; - -struct rt_pci_device_id -{ -#define PCI_ANY_ID (~0) -#define RT_PCI_DEVICE_ID(vend, dev) \ - .vendor = (vend), \ - .device = (dev), \ - .subsystem_vendor = PCI_ANY_ID, \ - .subsystem_device = PCI_ANY_ID - -#define RT_PCI_DEVICE_CLASS(dev_class, dev_class_mask) \ - .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \ - .subsystem_vendor = PCI_ANY_ID, \ - .subsystem_device = PCI_ANY_ID, \ - .class = (dev_class), .class_mask = (dev_class_mask), - - rt_uint32_t vendor, device; /* Vendor and device ID or PCI_ANY_ID */ - rt_uint32_t subsystem_vendor; /* Subsystem ID's or PCI_ANY_ID */ - rt_uint32_t subsystem_device; /* Subsystem ID's or PCI_ANY_ID */ - rt_uint32_t class, class_mask; /* (class, subclass, prog-if) triplet */ - - const void *data; -}; - -struct rt_pci_device -{ - struct rt_device parent; - const char *name; - - rt_list_t list; - struct rt_pci_bus *bus; - struct rt_pci_bus *subbus; /* In PCI-to-PCI bridge, 'End Point' or 'Port' is NULL */ - - const struct rt_pci_device_id *id; - - rt_uint32_t devfn; /* Encoded device & function index */ - rt_uint16_t vendor; - rt_uint16_t device; - rt_uint16_t subsystem_vendor; - rt_uint16_t subsystem_device; - rt_uint32_t class; /* 3 bytes: (base, sub, prog-if) */ - rt_uint8_t revision; - rt_uint8_t hdr_type; - rt_uint8_t max_latency; - rt_uint8_t min_grantl; - rt_uint8_t int_pin; - rt_uint8_t int_line; - rt_uint16_t exp_flags; - rt_uint32_t cfg_size; - - void *sysdata; - - int irq; - rt_uint8_t pin; - struct rt_pic *intx_pic; - - struct rt_pci_bus_resource resource[RT_PCI_BAR_NR_MAX]; - - rt_uint8_t pme_cap; - rt_uint8_t msi_cap; - rt_uint8_t msix_cap; - rt_uint8_t pcie_cap; - - rt_uint8_t busmaster:1; /* Is the bus master */ - rt_uint8_t multi_function:1; /* Multi-function device */ - rt_uint8_t ari_enabled:1; /* Alternative Routing-ID Interpretation */ - rt_uint8_t no_msi:1; /* May not use MSI */ - rt_uint8_t no_64bit_msi:1; /* May only use 32-bit MSIs */ - rt_uint8_t msi_enabled:1; /* MSI enable */ - rt_uint8_t msix_enabled:1; /* MSIx enable */ - rt_uint8_t broken_intx_masking:1; /* INTx masking can't be used */ - rt_uint8_t pme_support:5; /* Bitmask of states from which PME# can be generated */ - -#ifdef RT_PCI_MSI - void *msix_base; - struct rt_pic *msi_pic; - rt_list_t msi_desc_nodes; - struct rt_spinlock msi_lock; -#endif -}; - -struct rt_pci_host_bridge -{ - struct rt_device parent; - - rt_uint32_t domain; - - struct rt_pci_bus *root_bus; - const struct rt_pci_ops *ops; - const struct rt_pci_ops *child_ops; - - rt_uint32_t bus_range[2]; - rt_size_t bus_regions_nr; - struct rt_pci_bus_region *bus_regions; - rt_size_t dma_regions_nr; - struct rt_pci_bus_region *dma_regions; - - rt_uint8_t (*irq_slot)(struct rt_pci_device *pdev, rt_uint8_t *pinp); - int (*irq_map)(struct rt_pci_device *pdev, rt_uint8_t slot, rt_uint8_t pin); - - void *sysdata; - rt_uint8_t priv[0]; -}; -#define rt_device_to_pci_host_bridge(dev) rt_container_of(dev, struct rt_pci_host_bridge, parent) - -struct rt_pci_ops -{ - rt_err_t (*add)(struct rt_pci_bus *bus); - rt_err_t (*remove)(struct rt_pci_bus *bus); - - void *(*map)(struct rt_pci_bus *bus, rt_uint32_t devfn, int reg); - - rt_err_t (*read)(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, int width, rt_uint32_t *value); - rt_err_t (*write)(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, int width, rt_uint32_t value); -}; - -struct rt_pci_bus -{ - rt_list_t list; - rt_list_t children_nodes; - rt_list_t devices_nodes; - struct rt_pci_bus *parent; - - union - { - /* In PCI-to-PCI bridge, parent is not NULL */ - struct rt_pci_device *self; - /* In Host bridge, this is Root bus ('PCI Bus 0') */ - struct rt_pci_host_bridge *host_bridge; - }; - - const struct rt_pci_ops *ops; - - char name[48]; - char number; - struct rt_spinlock lock; - - void *sysdata; -}; - -struct rt_pci_driver -{ - struct rt_driver parent; - - const char *name; - const struct rt_pci_device_id *ids; - - rt_err_t (*probe)(struct rt_pci_device *pdev); - rt_err_t (*remove)(struct rt_pci_device *pdev); - rt_err_t (*shutdown)(struct rt_pci_device *pdev); -}; - -struct rt_pci_msix_entry -{ - int irq; - int index; -}; - -enum rt_pci_power -{ - RT_PCI_D0, - RT_PCI_D1, - RT_PCI_D2, - RT_PCI_D3HOT, - RT_PCI_D3COLD, - - RT_PCI_PME_MAX, -}; - -void rt_pci_pme_init(struct rt_pci_device *pdev); -void rt_pci_pme_active(struct rt_pci_device *pdev, rt_bool_t enable); -rt_err_t rt_pci_enable_wake(struct rt_pci_device *pci_dev, - enum rt_pci_power state, rt_bool_t enable); -rt_inline rt_bool_t rt_pci_pme_capable(struct rt_pci_device *pdev, - enum rt_pci_power state) -{ - if (!pdev->pme_cap) - { - return RT_FALSE; - } - - return !!(pdev->pme_support & (1 << state)); -} - -void rt_pci_msi_init(struct rt_pci_device *pdev); -void rt_pci_msix_init(struct rt_pci_device *pdev); - -void rt_pci_set_master(struct rt_pci_device *pdev); -void rt_pci_clear_master(struct rt_pci_device *pdev); - -struct rt_pci_host_bridge *rt_pci_host_bridge_alloc(rt_size_t priv_size); -rt_err_t rt_pci_host_bridge_free(struct rt_pci_host_bridge *); -rt_err_t rt_pci_host_bridge_init(struct rt_pci_host_bridge *host_bridge); -rt_err_t rt_pci_host_bridge_probe(struct rt_pci_host_bridge *host_bridge); - -struct rt_pci_device *rt_pci_alloc_device(struct rt_pci_bus *bus); -struct rt_pci_device *rt_pci_scan_single_device(struct rt_pci_bus *bus, rt_uint32_t devfn); -rt_err_t rt_pci_setup_device(struct rt_pci_device *pdev); -rt_size_t rt_pci_scan_slot(struct rt_pci_bus *bus, rt_uint32_t devfn); -rt_uint32_t rt_pci_scan_child_buses(struct rt_pci_bus *bus, rt_size_t buses); -rt_uint32_t rt_pci_scan_child_bus(struct rt_pci_bus *bus); - -rt_err_t rt_pci_host_bridge_register(struct rt_pci_host_bridge *host_bridge); -rt_err_t rt_pci_scan_root_bus_bridge(struct rt_pci_host_bridge *host_bridge); - -rt_err_t rt_pci_host_bridge_remove(struct rt_pci_host_bridge *host_bridge); -rt_err_t rt_pci_bus_remove(struct rt_pci_bus *bus); -rt_err_t rt_pci_device_remove(struct rt_pci_device *pdev); - -rt_uint32_t rt_pci_domain(struct rt_pci_device *pdev); - -rt_uint8_t rt_pci_bus_find_capability(struct rt_pci_bus *bus, rt_uint32_t devfn, int cap); -rt_uint8_t rt_pci_find_capability(struct rt_pci_device *pdev, int cap); -rt_uint8_t rt_pci_find_next_capability(struct rt_pci_device *pdev, rt_uint8_t pos, int cap); - -rt_uint16_t rt_pci_find_ext_capability(struct rt_pci_device *pdev, int cap); -rt_uint16_t rt_pci_find_ext_next_capability(struct rt_pci_device *pdev, rt_uint16_t pos, int cap); - -struct rt_pci_bus *rt_pci_find_root_bus(struct rt_pci_bus *bus); -struct rt_pci_host_bridge *rt_pci_find_host_bridge(struct rt_pci_bus *bus); - -rt_inline rt_uint16_t rt_pci_dev_id(struct rt_pci_device *pdev) -{ - return RT_PCI_DEVID(pdev->bus->number, pdev->devfn); -} - -rt_inline rt_bool_t rt_pci_is_root_bus(struct rt_pci_bus *bus) -{ - return bus->parent ? RT_FALSE : RT_TRUE; -} - -rt_inline rt_bool_t rt_pci_is_bridge(struct rt_pci_device *pdev) -{ - return pdev->hdr_type == PCIM_HDRTYPE_BRIDGE || - pdev->hdr_type == PCIM_HDRTYPE_CARDBUS; -} - -rt_inline rt_bool_t rt_pci_is_pcie(struct rt_pci_device *pdev) -{ - return !!pdev->pcie_cap; -} - -#define rt_pci_foreach_bridge(pdev, bus) \ - rt_list_for_each_entry(pdev, &bus->devices_nodes, list) \ - if (rt_pci_is_bridge(pdev)) - -rt_err_t rt_pci_bus_read_config_u8(struct rt_pci_bus *bus, - rt_uint32_t devfn, int pos, rt_uint8_t *value); -rt_err_t rt_pci_bus_read_config_u16(struct rt_pci_bus *bus, - rt_uint32_t devfn, int pos, rt_uint16_t *value); -rt_err_t rt_pci_bus_read_config_u32(struct rt_pci_bus *bus, - rt_uint32_t devfn, int pos, rt_uint32_t *value); - -rt_err_t rt_pci_bus_write_config_u8(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, rt_uint8_t value); -rt_err_t rt_pci_bus_write_config_u16(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, rt_uint16_t value); -rt_err_t rt_pci_bus_write_config_u32(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, rt_uint32_t value); - -rt_err_t rt_pci_bus_read_config_uxx(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, int width, rt_uint32_t *value); -rt_err_t rt_pci_bus_write_config_uxx(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, int width, rt_uint32_t value); - -rt_err_t rt_pci_bus_read_config_generic_u32(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, int width, rt_uint32_t *value); -rt_err_t rt_pci_bus_write_config_generic_u32(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, int width, rt_uint32_t value); - -rt_inline rt_err_t rt_pci_read_config_u8(const struct rt_pci_device *pdev, - int reg, rt_uint8_t *value) -{ - return rt_pci_bus_read_config_u8(pdev->bus, pdev->devfn, reg, value); -} - -rt_inline rt_err_t rt_pci_read_config_u16(const struct rt_pci_device *pdev, - int reg, rt_uint16_t *value) -{ - return rt_pci_bus_read_config_u16(pdev->bus, pdev->devfn, reg, value); -} - -rt_inline rt_err_t rt_pci_read_config_u32(const struct rt_pci_device *pdev, - int reg, rt_uint32_t *value) -{ - return rt_pci_bus_read_config_u32(pdev->bus, pdev->devfn, reg, value); -} - -rt_inline rt_err_t rt_pci_write_config_u8(const struct rt_pci_device *pdev, - int reg, rt_uint8_t value) -{ - return rt_pci_bus_write_config_u8(pdev->bus, pdev->devfn, reg, value); -} - -rt_inline rt_err_t rt_pci_write_config_u16(const struct rt_pci_device *pdev, - int reg, rt_uint16_t value) -{ - return rt_pci_bus_write_config_u16(pdev->bus, pdev->devfn, reg, value); -} - -rt_inline rt_err_t rt_pci_write_config_u32(const struct rt_pci_device *pdev, - int reg, rt_uint32_t value) -{ - return rt_pci_bus_write_config_u32(pdev->bus, pdev->devfn, reg, value); -} - -#ifdef RT_USING_OFW -int rt_pci_ofw_irq_parse_and_map(struct rt_pci_device *pdev, - rt_uint8_t slot, rt_uint8_t pin); - -rt_err_t rt_pci_ofw_parse_ranges(struct rt_ofw_node *dev_np, - struct rt_pci_host_bridge *host_bridge); - -rt_err_t rt_pci_ofw_host_bridge_init(struct rt_ofw_node *dev_np, - struct rt_pci_host_bridge *host_bridge); - -rt_err_t rt_pci_ofw_bus_init(struct rt_pci_bus *bus); -rt_err_t rt_pci_ofw_bus_free(struct rt_pci_bus *bus); -rt_err_t rt_pci_ofw_device_init(struct rt_pci_device *pdev); -rt_err_t rt_pci_ofw_device_free(struct rt_pci_device *pdev); -#else -rt_inline rt_err_t rt_pci_ofw_host_bridge_init(struct rt_ofw_node *dev_np, - struct rt_pci_host_bridge *host_bridge) -{ - return RT_EOK; -} -rt_inline rt_err_t rt_pci_ofw_bus_init(struct rt_pci_bus *bus) -{ - return RT_EOK; -} -rt_inline rt_err_t rt_pci_ofw_bus_free(struct rt_pci_bus *bus) -{ - return RT_EOK; -} -rt_inline rt_err_t rt_pci_ofw_device_init(struct rt_pci_device *pdev) -{ - return RT_EOK; -} -rt_inline rt_err_t rt_pci_ofw_device_free(struct rt_pci_device *pdev) -{ - return RT_EOK; -} -rt_inline int rt_pci_ofw_irq_parse_and_map(struct rt_pci_device *pdev, - rt_uint8_t slot, rt_uint8_t pin) -{ - return -1; -} -rt_inline rt_err_t rt_pci_ofw_parse_ranges(struct rt_ofw_node *dev_np, - struct rt_pci_host_bridge *host_bridge) -{ - return -RT_ENOSYS; -} -#endif /* RT_USING_OFW */ - -rt_inline void *rt_pci_iomap(struct rt_pci_device *pdev, int bar_idx) -{ - struct rt_pci_bus_resource *res = &pdev->resource[bar_idx]; - - RT_ASSERT(bar_idx < RT_ARRAY_SIZE(pdev->resource)); - - return rt_ioremap((void *)res->base, res->size); -} - -rt_uint8_t rt_pci_irq_intx(struct rt_pci_device *pdev, rt_uint8_t pin); -rt_uint8_t rt_pci_irq_slot(struct rt_pci_device *pdev, rt_uint8_t *pinp); - -void rt_pci_assign_irq(struct rt_pci_device *pdev); - -void rt_pci_intx(struct rt_pci_device *pdev, rt_bool_t enable); -rt_bool_t rt_pci_check_and_mask_intx(struct rt_pci_device *pdev); -rt_bool_t rt_pci_check_and_unmask_intx(struct rt_pci_device *pdev); - -void rt_pci_irq_mask(struct rt_pci_device *pdev); -void rt_pci_irq_unmask(struct rt_pci_device *pdev); - -#define RT_PCI_IRQ_F_LEGACY RT_BIT(0) /* Allow legacy interrupts */ -#define RT_PCI_IRQ_F_MSI RT_BIT(1) /* Allow MSI interrupts */ -#define RT_PCI_IRQ_F_MSIX RT_BIT(2) /* Allow MSI-X interrupts */ -#define RT_PCI_IRQ_F_AFFINITY RT_BIT(3) /* Auto-assign affinity */ -#define RT_PCI_IRQ_F_ALL_TYPES (RT_PCI_IRQ_F_LEGACY | RT_PCI_IRQ_F_MSI | RT_PCI_IRQ_F_MSIX) - -#ifdef RT_PCI_MSI -rt_ssize_t rt_pci_alloc_vector(struct rt_pci_device *pdev, int min, int max, - rt_uint32_t flags, RT_IRQ_AFFINITY_DECLARE((*affinities))); -void rt_pci_free_vector(struct rt_pci_device *pdev); - -rt_ssize_t rt_pci_msi_vector_count(struct rt_pci_device *pdev); -rt_err_t rt_pci_msi_disable(struct rt_pci_device *pdev); -rt_ssize_t rt_pci_msi_enable_range_affinity(struct rt_pci_device *pdev, - int min, int max, RT_IRQ_AFFINITY_DECLARE((*affinities))); - -rt_ssize_t rt_pci_msix_vector_count(struct rt_pci_device *pdev); -rt_err_t rt_pci_msix_disable(struct rt_pci_device *pdev); -rt_ssize_t rt_pci_msix_enable_range_affinity(struct rt_pci_device *pdev, - struct rt_pci_msix_entry *entries, int min, int max, - RT_IRQ_AFFINITY_DECLARE((*affinities))); -#else -rt_inline rt_ssize_t rt_pci_alloc_vector(struct rt_pci_device *pdev, int min, int max, - rt_uint32_t flags, RT_IRQ_AFFINITY_DECLARE((*affinities))) -{ - return -RT_ENOSYS; -} - -rt_inline void rt_pci_free_vector(struct rt_pci_device *pdev) -{ - return; -} - -rt_inline rt_ssize_t rt_pci_msi_vector_count(struct rt_pci_device *pdev) -{ - return 0; -} - -rt_inline rt_err_t rt_pci_msi_disable(struct rt_pci_device *pdev) -{ - return RT_EOK; -} - -rt_inline rt_ssize_t rt_pci_msi_enable_range_affinity(struct rt_pci_device *pdev, - int min, int max, RT_IRQ_AFFINITY_DECLARE((*affinities))) -{ - return -RT_ENOSYS; -} - -rt_inline rt_ssize_t rt_pci_msix_vector_count(struct rt_pci_device *pdev) -{ - return 0; -} - -rt_inline rt_err_t rt_pci_msix_disable(struct rt_pci_device *pdev) -{ - return RT_EOK; -} - -rt_inline rt_ssize_t rt_pci_msix_enable_range_affinity(struct rt_pci_device *pdev, - struct rt_pci_msix_entry *entries, int min, int max, - RT_IRQ_AFFINITY_DECLARE((*affinities))) -{ - return -RT_ENOSYS; -} -#endif /* RT_PCI_MSI */ - -rt_inline void rt_pci_msix_entry_index_linear(struct rt_pci_msix_entry *entries, - rt_size_t nvectors) -{ - for (int i = 0; i < nvectors; ++i) - { - entries[i].index = i; - } -} - -rt_inline rt_ssize_t rt_pci_msi_enable_range(struct rt_pci_device *pdev, - int min, int max) -{ - return rt_pci_msi_enable_range_affinity(pdev, min, max, RT_NULL); -} - -rt_inline rt_err_t rt_pci_msi_enable(struct rt_pci_device *pdev) -{ - rt_ssize_t res = rt_pci_msi_enable_range(pdev, 1, 1); - return res == 1 ? res : RT_EOK; -} - -rt_inline rt_ssize_t rt_pci_msix_enable_range(struct rt_pci_device *pdev, - struct rt_pci_msix_entry *entries, int min, int max) -{ - return rt_pci_msix_enable_range_affinity(pdev, entries, min, max, RT_NULL); -} - -rt_inline rt_ssize_t rt_pci_msix_enable(struct rt_pci_device *pdev, - struct rt_pci_msix_entry *entries, int count) -{ - return rt_pci_msix_enable_range(pdev, entries, count, count); -} - -rt_err_t rt_pci_region_setup(struct rt_pci_host_bridge *host_bridge); -struct rt_pci_bus_region *rt_pci_region_alloc(struct rt_pci_host_bridge *host_bridge, - void **out_addr, rt_size_t size, rt_ubase_t flags, rt_bool_t mem64); - -rt_err_t rt_pci_device_alloc_resource(struct rt_pci_host_bridge *host_bridge, - struct rt_pci_device *pdev); - -void rt_pci_enum_device(struct rt_pci_bus *bus, - rt_bool_t (callback(struct rt_pci_device *, void *)), void *data); - -const struct rt_pci_device_id *rt_pci_match_id(struct rt_pci_device *pdev, - const struct rt_pci_device_id *id); - -const struct rt_pci_device_id *rt_pci_match_ids(struct rt_pci_device *pdev, - const struct rt_pci_device_id *ids); - -rt_err_t rt_pci_driver_register(struct rt_pci_driver *pdrv); -rt_err_t rt_pci_device_register(struct rt_pci_device *pdev); -struct rt_pci_bus_resource *rt_pci_find_bar(struct rt_pci_device* pdev,rt_ubase_t flags,int index); -#define RT_PCI_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, pci, BUILIN) - -extern struct rt_spinlock rt_pci_lock; - -#endif /* __PCI_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/pci_endpoint.h b/rt-thread/components/drivers/include/drivers/pci_endpoint.h deleted file mode 100644 index c43c182..0000000 --- a/rt-thread/components/drivers/include/drivers/pci_endpoint.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-08-25 GuEe-GUI first version - */ - -#ifndef __PCI_ENDPOINT_H__ -#define __PCI_ENDPOINT_H__ - -#include - -enum rt_pci_ep_pin -{ - RT_PCI_EP_PIN_UNKNOWN, - RT_PCI_EP_PIN_INTA, - RT_PCI_EP_PIN_INTB, - RT_PCI_EP_PIN_INTC, - RT_PCI_EP_PIN_INTD, -}; - -enum rt_pci_ep_irq -{ - RT_PCI_EP_IRQ_UNKNOWN, - RT_PCI_EP_IRQ_LEGACY, - RT_PCI_EP_IRQ_MSI, - RT_PCI_EP_IRQ_MSIX, -}; - -struct rt_pci_ep_header -{ - rt_uint16_t vendor; - rt_uint16_t device; - rt_uint8_t revision; - rt_uint8_t progif; - rt_uint8_t subclass; - rt_uint8_t class_code; - rt_uint8_t cache_line_size; - rt_uint16_t subsystem_vendor; - rt_uint16_t subsystem_device; - - enum rt_pci_ep_pin intx; -}; - -struct rt_pci_ep_bar -{ - /* To PCI Bus */ - struct rt_pci_bus_resource bus; - /* To CPU */ - rt_ubase_t cpu_addr; -}; - -/* - * Type of MSI-X table, For more format detail, - * please read `components/drivers/include/drivers/pci_msi.h` - */ -struct rt_pci_ep_msix_tbl -{ - union - { - rt_uint64_t msg_addr; - struct - { - rt_uint32_t msg_addr_upper; - rt_uint32_t msg_addr_lower; - }; - }; - rt_uint32_t msg_data; - rt_uint32_t vector_ctrl; -}; - -struct rt_pci_ep_ops; -struct rt_pci_ep_mem; - -struct rt_pci_ep -{ - rt_list_t list; - const char *name; - - struct rt_ref ref; - - const struct rt_device *rc_dev; - const struct rt_pci_ep_ops *ops; - - rt_size_t mems_nr; - struct rt_pci_ep_mem *mems; - - rt_uint8_t max_functions; - RT_BITMAP_DECLARE(functions_map, 8); - rt_list_t epf_nodes; - struct rt_mutex lock; - - void *priv; -}; - -struct rt_pci_ep_mem -{ - rt_ubase_t cpu_addr; - rt_size_t size; - rt_size_t page_size; - - rt_bitmap_t *map; - rt_size_t bits; -}; - -struct rt_pci_epf -{ - rt_list_t list; - const char *name; - - struct rt_pci_ep_header *header; - struct rt_pci_ep_bar bar[PCI_STD_NUM_BARS]; - - rt_uint8_t msi_interrupts; - rt_uint16_t msix_interrupts; - rt_uint8_t func_no; - - struct rt_pci_ep *ep; -}; - -struct rt_pci_ep_ops -{ - rt_err_t (*write_header)(struct rt_pci_ep *ep, rt_uint8_t func_no, - struct rt_pci_ep_header *hdr); - - rt_err_t (*set_bar)(struct rt_pci_ep *ep, rt_uint8_t func_no, - struct rt_pci_ep_bar *bar, int bar_idx); - rt_err_t (*clear_bar)(struct rt_pci_ep *ep, rt_uint8_t func_no, - struct rt_pci_ep_bar *bar, int bar_idx); - - rt_err_t (*map_addr)(struct rt_pci_ep *ep, rt_uint8_t func_no, - rt_ubase_t addr, rt_uint64_t pci_addr, rt_size_t size); - rt_err_t (*unmap_addr)(struct rt_pci_ep *ep, rt_uint8_t func_no, rt_ubase_t addr); - - rt_err_t (*set_msi)(struct rt_pci_ep *ep, rt_uint8_t func_no, - unsigned irq_nr); - rt_err_t (*get_msi)(struct rt_pci_ep *ep, rt_uint8_t func_no, - unsigned *out_irq_nr); - - rt_err_t (*set_msix)(struct rt_pci_ep *ep, rt_uint8_t func_no, - unsigned irq_nr, int bar_idx, rt_off_t offset); - rt_err_t (*get_msix)(struct rt_pci_ep *ep, rt_uint8_t func_no, - unsigned *out_irq_nr); - - rt_err_t (*raise_irq)(struct rt_pci_ep *ep, rt_uint8_t func_no, - enum rt_pci_ep_irq type, unsigned irq); - - rt_err_t (*start)(struct rt_pci_ep *ep); - rt_err_t (*stop)(struct rt_pci_ep *ep); -}; - -rt_err_t rt_pci_ep_write_header(struct rt_pci_ep *ep, rt_uint8_t func_no, - struct rt_pci_ep_header *hdr); - -rt_err_t rt_pci_ep_set_bar(struct rt_pci_ep *ep, rt_uint8_t func_no, - struct rt_pci_ep_bar *bar, int bar_idx); -rt_err_t rt_pci_ep_clear_bar(struct rt_pci_ep *ep, rt_uint8_t func_no, - struct rt_pci_ep_bar *bar, int bar_idx); - -rt_err_t rt_pci_ep_map_addr(struct rt_pci_ep *ep, rt_uint8_t func_no, - rt_ubase_t addr, rt_uint64_t pci_addr, rt_size_t size); -rt_err_t rt_pci_ep_unmap_addr(struct rt_pci_ep *ep, rt_uint8_t func_no, - rt_ubase_t addr); - -rt_err_t rt_pci_ep_set_msi(struct rt_pci_ep *ep, rt_uint8_t func_no, - unsigned irq_nr); -rt_err_t rt_pci_ep_get_msi(struct rt_pci_ep *ep, rt_uint8_t func_no, - unsigned *out_irq_nr); - -rt_err_t rt_pci_ep_set_msix(struct rt_pci_ep *ep, rt_uint8_t func_no, - unsigned irq_nr, int bar_idx, rt_off_t offset); -rt_err_t rt_pci_ep_get_msix(struct rt_pci_ep *ep, rt_uint8_t func_no, - unsigned *out_irq_nr); - -rt_err_t rt_pci_ep_raise_irq(struct rt_pci_ep *ep, rt_uint8_t func_no, - enum rt_pci_ep_irq type, unsigned irq); - -rt_err_t rt_pci_ep_start(struct rt_pci_ep *ep); -rt_err_t rt_pci_ep_stop(struct rt_pci_ep *ep); - -rt_err_t rt_pci_ep_register(struct rt_pci_ep *ep); -rt_err_t rt_pci_ep_unregister(struct rt_pci_ep *ep); - -rt_err_t rt_pci_ep_mem_array_init(struct rt_pci_ep *ep, - struct rt_pci_ep_mem *mems, rt_size_t mems_nr); -rt_err_t rt_pci_ep_mem_init(struct rt_pci_ep *ep, - rt_ubase_t cpu_addr, rt_size_t size, rt_size_t page_size); - -void *rt_pci_ep_mem_alloc(struct rt_pci_ep *ep, - rt_ubase_t *out_cpu_addr, rt_size_t size); -void rt_pci_ep_mem_free(struct rt_pci_ep *ep, - void *vaddr, rt_ubase_t cpu_addr, rt_size_t size); - -rt_err_t rt_pci_ep_add_epf(struct rt_pci_ep *ep, struct rt_pci_epf *epf); -rt_err_t rt_pci_ep_remove_epf(struct rt_pci_ep *ep, struct rt_pci_epf *epf); - -struct rt_pci_ep *rt_pci_ep_get(const char *name); -void rt_pci_ep_put(struct rt_pci_ep *ep); - -#endif /* __PCI_ENDPOINT_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/pci_msi.h b/rt-thread/components/drivers/include/drivers/pci_msi.h deleted file mode 100644 index b8238e6..0000000 --- a/rt-thread/components/drivers/include/drivers/pci_msi.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-08-25 GuEe-GUI first version - */ - -#ifndef __PCI_MSI_H__ -#define __PCI_MSI_H__ - -#include - -/* - * MSI Format: - * T0: 32-bit Address - * T1: 64-bit Address - * T2: 32-bit Address with Per-Vector Masking - * T3: 64-bit Address with Per-Vector Masking - * - * 31 16 15 8 7 0 - * +---------------------------+-----------------+---------------+ - * | Message Control | Next Capability | Capability ID | DW0 - * | | Pointer | (05h) | - * +---------------------------+-----------------+---------------+ - * | Message Address [31:0] | DW1 - * +-------------------------------------------------------------+ - * | Message Address [63:32] | DW2 (T1: only 64-bit) - * +---------------------------+---------------------------------+ - * | Reserved | Message Data | DW3 - * +---------------------------+---------------------------------+ - * | Mask Bits | DW4 (T2/T3: only with Per-Vector Masking) - * +-------------------------------------------------------------+ - * | Pending Bits | DW5 (T2/T3: only with Per-Vector Masking) - * +-------------------------------------------------------------+ - * - * MSI Message Control: - * - * 15 9 8 7 6 4 3 1 0 - * +----------------------+---+---+---------------+----------+---+ - * | Reserved | | | | | | - * +----------------------+---+---+---------------+----------+---+ - * ^ ^ ^ ^ ^ - * | | | | | - * | | | | +---- MSI Enable (RW) - * | | | +----------- Multiple Message Capable (RO, log2n, [n <= 5]) - * | | +------------------------- Multiple Message Enable (RW, log2n, [n <= 5]) - * | +----------------------------------- 64-bit Address Capable - * +--------------------------------------- Per-Vector Masking Capable - */ - -struct rt_pci_msi_conf -{ - rt_uint32_t mask; - rt_uint8_t mask_pos; - int default_irq; - - struct - { - rt_uint8_t is_masking:1; - rt_uint8_t is_64bit:1; - rt_uint8_t multi_msg_max:3; /* log2 num of messages allocated */ - rt_uint8_t multi_msg_use:3; /* log2 num of messages supported */ - } cap; -}; - -/* - * MSI-X Format: - * - * 31 16 15 8 7 0 - * +---------------------------+-----------------+---------------+ - * | Message Control | Next Capability | Capability ID | DW0 - * | | Pointer | (11h) | - * +---------------------------+-----------------+---+-----------+ - * | MSI-X Table Offset | Table BIR | DW1 (BIR: BAR Index Register) - * +-------------------------------------------------+-----------+ | - * | Pending Bit Array (PBA) Offset | PBA BIR | DW2 --------+ | - * +-------------------------------------------------+-----------+ | | - * | | - * MSI-X Message Control: | | - * | | - * 15 14 13 11 10 0 | | - * +---+---+----------+------------------------------------------+ | | - * | | | Reserved | Table Size in N-1 (RO) | | | - * +---+---+----------+------------------------------------------+ | | - * ^ ^ | | - * | | | | - * | +---- Function Mask (RW) | | - * +-------- MSI-X Enable (RW) | | - * | | - * MSI-X Table (BAR[Table BIR] + MSI-X Table Offset): | | - * | | - * DW3 DW2 DW1 DW0 | | - * +----------------+--------------+---------------+---------------+ <---------|-+ - * | Vector Control | Message Data | Upper Address | Lower Address | Entry 0 | - * +----------------+--------------+---------------+---------------+ | - * | Vector Control | Message Data | Upper Address | Lower Address | Entry 1 | - * +----------------+--------------+---------------+---------------+ | - * | ...... | ...... | ...... | ...... | | - * +----------------+--------------+---------------+---------------+ | - * | Vector Control | Message Data | Upper Address | Lower Address | Entry N-1 | - * +----------------+--------------+---------------+---------------+ | - * ^ | - * | | - * +---- Bit 0 is vector Mask Bit (R/W) | - * | - * MSI-X Pending Bit Array (BAR[PBA BIR] + Pending Bit Array Offset): | - * | - * DW1 DW0 | - * +-------------------------------+ <-----------------------------------------+ - * | Pending Bits 0 - 63 | QW 0 - * +-------------------------------+ - * | Pending Bits 64 - 127 | QW 1 - * +-------------------------------+ - * | ...... | - * +-------------------------------+ - * | Pending Bits | QW (N-1)/64 - * +-------------------------------+ - */ - -struct rt_pci_msix_conf -{ - int index; - - rt_uint32_t msg_ctrl; - void *table_base; -}; - -struct rt_pci_msi_msg -{ - rt_uint32_t address_lo; - rt_uint32_t address_hi; - rt_uint32_t data; -}; - -struct rt_pci_msi_desc -{ - rt_list_t list; - - int irq; - rt_size_t vector_used; - rt_size_t vector_count; - - union - { - /* For MSI-X */ - rt_bitmap_t *affinity; - /* For MSI */ - rt_bitmap_t **affinities; - }; - - struct rt_pci_device *pdev; - struct rt_pci_msi_msg msg; - - void *write_msi_msg_data; - void (*write_msi_msg)(struct rt_pci_msi_desc *, void *); - - rt_bool_t is_msix; - union - { - struct rt_pci_msi_conf msi; - struct rt_pci_msix_conf msix; - }; - - void *priv; -}; - -#define rt_pci_msi_first_desc(pdev) \ - (rt_list_isempty(&(pdev)->msi_desc_nodes) ? RT_NULL : \ - rt_list_first_entry(&(pdev)->msi_desc_nodes, struct rt_pci_msi_desc, list)) - -#define rt_pci_msi_for_each_desc(pdev, desc) \ - rt_list_for_each_entry(desc, &(pdev)->msi_desc_nodes, list) - -#define rt_pci_msix_table_size(flags) ((flags & PCIM_MSIXCTRL_TABLE_SIZE) + 1) - -rt_err_t rt_pci_msi_setup_irqs(struct rt_pci_device *pdev, int nvec, int type); - -void rt_pci_msi_shutdown(struct rt_pci_device *pdev); -void rt_pci_msix_shutdown(struct rt_pci_device *pdev); -void rt_pci_msi_free_irqs(struct rt_pci_device *pdev); -void rt_pci_msi_write_msg(struct rt_pci_msi_desc *desc, struct rt_pci_msi_msg *msg); - -void rt_pci_msi_mask_irq(struct rt_pic_irq *pirq); -void rt_pci_msi_unmask_irq(struct rt_pic_irq *pirq); - -#endif /* __PCI_MSI_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/phy.h b/rt-thread/components/drivers/include/drivers/phy.h index a8dcd08..c51c494 100644 --- a/rt-thread/components/drivers/include/drivers/phy.h +++ b/rt-thread/components/drivers/include/drivers/phy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -7,172 +7,18 @@ * Date Author Notes * 2020-10-14 wangqiang the first version * 2022-08-17 xjy198903 add 1000M definition - * 2024-10-08 zhujiale add phy v2.0 */ -#ifndef __NET_PHY_H__ -#define __NET_PHY_H__ + +#ifndef __PHY_H__ +#define __PHY_H__ + #include -#include -#ifdef RT_USING_PHY_V2 -#include -#include -#include -#define RT_PHY_FIXED_ID 0xa5a55a5a -#define RT_PHY_NCSI_ID 0xbeefcafe - - -/* Indicates what features are supported by the interface. */ -#define RT_SUPPORTED_10baseT_Half (1 << 0) -#define RT_SUPPORTED_10baseT_Full (1 << 1) -#define RT_SUPPORTED_100baseT_Half (1 << 2) -#define RT_SUPPORTED_100baseT_Full (1 << 3) -#define RT_SUPPORTED_1000baseT_Half (1 << 4) -#define RT_SUPPORTED_1000baseT_Full (1 << 5) -#define RT_SUPPORTED_Autoneg (1 << 6) -#define RT_SUPPORTED_TP (1 << 7) -#define RT_SUPPORTED_AUI (1 << 8) -#define RT_SUPPORTED_MII (1 << 9) -#define RT_SUPPORTED_FIBRE (1 << 10) -#define RT_SUPPORTED_BNC (1 << 11) -#define RT_SUPPORTED_10000baseT_Full (1 << 12) -#define RT_SUPPORTED_Pause (1 << 13) -#define RT_SUPPORTED_Asym_Pause (1 << 14) -#define RT_SUPPORTED_2500baseX_Full (1 << 15) -#define RT_SUPPORTED_Backplane (1 << 16) -#define RT_SUPPORTED_1000baseKX_Full (1 << 17) -#define RT_SUPPORTED_10000baseKX4_Full (1 << 18) -#define RT_SUPPORTED_10000baseKR_Full (1 << 19) -#define RT_SUPPORTED_10000baseR_FEC (1 << 20) -#define RT_SUPPORTED_1000baseX_Half (1 << 21) -#define RT_SUPPORTED_1000baseX_Full (1 << 22) - -#define RT_PHY_FLAG_BROKEN_RESET (1 << 0) /* soft reset not supported */ -#define RT_PHY_DEFAULT_FEATURES (RT_SUPPORTED_Autoneg | RT_SUPPORTED_TP | RT_SUPPORTED_MII) - -#define RT_PHY_10BT_FEATURES (RT_SUPPORTED_10baseT_Half | RT_SUPPORTED_10baseT_Full) - -#define RT_PHY_100BT_FEATURES (RT_SUPPORTED_100baseT_Half | RT_SUPPORTED_100baseT_Full) - -#define RT_PHY_1000BT_FEATURES (RT_SUPPORTED_1000baseT_Half | RT_SUPPORTED_1000baseT_Full) - -#define RT_PHY_BASIC_FEATURES (RT_PHY_10BT_FEATURES | RT_PHY_100BT_FEATURES | RT_PHY_DEFAULT_FEATURES) - -#define RT_PHY_GBIT_FEATURES (RT_PHY_BASIC_FEATURES | RT_PHY_1000BT_FEATURES) - -#define RT_PHY_10G_FEATURES (RT_PHY_GBIT_FEATURES | RT_SUPPORTED_10000baseT_Full) -struct rt_phy_device -{ - struct rt_device parent; - struct mii_bus *bus; - struct rt_phy_driver *drv; - rt_uint32_t phy_id; - rt_uint32_t mmds; - int speed; - int duplex; - int link; - int port; - rt_uint32_t advertising; - rt_uint32_t supported; - rt_bool_t autoneg; - int pause; - rt_ubase_t addr; - rt_bool_t is_c45; - rt_uint32_t flags; - rt_phy_interface interface; - -#ifdef RT_USING_OFW - struct rt_ofw_node *node; -#endif - void *priv; -}; - -struct rt_phy_driver -{ - struct rt_driver parent; - char name[RT_NAME_MAX]; - rt_uint64_t uid; - rt_uint64_t mask; - rt_uint64_t mmds; - rt_uint32_t features; - - int (*probe)(struct rt_phy_device *phydev); - int (*config)(struct rt_phy_device *phydev); - int (*startup)(struct rt_phy_device *phydev); - int (*shutdown)(struct rt_phy_device *phydev); - int (*read)(struct rt_phy_device *phydev, int addr, int devad, int reg); - int (*write)(struct rt_phy_device *phydev, int addr, int devad, int reg, - rt_uint16_t val); - int (*read_mmd)(struct rt_phy_device *phydev, int devad, int reg); - int (*write_mmd)(struct rt_phy_device *phydev, int devad, int reg, - rt_uint16_t val); - - /* driver private data */ - void *data; -}; - -int rt_phy_read(struct rt_phy_device *phydev, int devad, int regnum); -int rt_phy_write(struct rt_phy_device *phydev, int devad, int regnum, rt_uint16_t val); -int rt_phy_read_mmd(struct rt_phy_device *phydev, int devad, int regnum); -int rt_phy_write_mmd(struct rt_phy_device *phydev, int devad, int regnum, rt_uint16_t val); -int rt_phy_reset(struct rt_phy_device *phydev); -int rt_phy_startup(struct rt_phy_device *phydev); -int rt_phy_config(struct rt_phy_device *phydev); -int rt_phy_shutdown(struct rt_phy_device *phydev); -int rt_phy_read_mmd(struct rt_phy_device *phydev, int devad, int regnum); -int rt_phy_set_supported(struct rt_phy_device *phydev, rt_uint32_t max_speed); - -void rt_phy_mmd_start_indirect(struct rt_phy_device *phydev, int devad, int regnum); - -rt_err_t rt_phy_device_register(struct rt_phy_device *pdev); -rt_err_t rt_phy_driver_register(struct rt_phy_driver *pdrv); -rt_err_t rt_ofw_get_phyid(struct rt_ofw_node *np,rt_uint32_t *id); - -struct rt_phy_device *rt_phy_device_create(struct mii_bus *bus, int addr, rt_uint32_t phy_id, rt_bool_t is_c45); -struct rt_phy_device *rt_phy_find_by_mask(struct mii_bus *bus, unsigned int phy_mask); -struct rt_phy_device *rt_ofw_create_phy(struct mii_bus *bus, struct rt_ofw_node *np, int phyaddr); -struct rt_phy_device *rt_phy_get_device(struct mii_bus *bus, struct rt_ofw_node *np, int addr, rt_phy_interface interface); - -#define RT_PHY_DEVICE_REGISTER(phy_dev) \ -static int rt_##phy_dev##_register(void) \ -{ \ - rt_phy_device_register(&phy_dev); \ - return 0; \ -} \ -INIT_PREV_EXPORT(rt_##phy_dev##_register); - -#define RT_PHY_DRIVER_REGISTER(phy_drv) \ -static int rt_##phy_drv##_register(void) \ -{ \ - rt_phy_driver_register(&phy_drv); \ - return 0; \ -} \ -INIT_PREV_EXPORT(rt_##phy_drv##_register); -#endif - -#ifdef RT_USING_PHY #ifdef __cplusplus extern "C" { #endif -struct rt_mdio_bus_ops -{ - rt_bool_t (*init)(void *bus, rt_uint32_t src_clock_hz); - rt_size_t (*read)(void *bus, rt_uint32_t addr, rt_uint32_t reg, void *data, rt_uint32_t size); - rt_size_t (*write)(void *bus, rt_uint32_t addr, rt_uint32_t reg, void *data, rt_uint32_t size); - rt_bool_t (*uninit)(void *bus); -}; - -struct rt_mdio_bus -{ - void *hw_obj; - char *name; - struct rt_mdio_bus_ops *ops; -}; - -typedef struct rt_mdio_bus rt_mdio_t; - /* Defines the PHY link speed. This is align with the speed for MAC. */ #define PHY_SPEED_10M 0U /* PHY 10M speed. */ #define PHY_SPEED_100M 1U /* PHY 100M speed. */ @@ -221,5 +67,5 @@ rt_err_t rt_hw_phy_register(struct rt_phy_device *phy, const char *name); #ifdef __cplusplus } #endif -#endif -#endif + +#endif /* __PHY_H__*/ diff --git a/rt-thread/components/drivers/include/drivers/phye.h b/rt-thread/components/drivers/include/drivers/phye.h deleted file mode 100644 index 3776cde..0000000 --- a/rt-thread/components/drivers/include/drivers/phye.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#ifndef __PHYE_H__ -#define __PHYE_H__ - -#include -#include - -enum rt_phye_mode -{ - RT_PHYE_MODE_INVALID, - RT_PHYE_MODE_USB_HOST, - RT_PHYE_MODE_USB_HOST_LS, - RT_PHYE_MODE_USB_HOST_FS, - RT_PHYE_MODE_USB_HOST_HS, - RT_PHYE_MODE_USB_HOST_SS, - RT_PHYE_MODE_USB_DEVICE, - RT_PHYE_MODE_USB_DEVICE_LS, - RT_PHYE_MODE_USB_DEVICE_FS, - RT_PHYE_MODE_USB_DEVICE_HS, - RT_PHYE_MODE_USB_DEVICE_SS, - RT_PHYE_MODE_USB_OTG, - RT_PHYE_MODE_UFS_HS_A, - RT_PHYE_MODE_UFS_HS_B, - RT_PHYE_MODE_PCIE, - RT_PHYE_MODE_ETHERNET, - RT_PHYE_MODE_MIPI_DPHY, - RT_PHYE_MODE_SATA, - RT_PHYE_MODE_LVDS, - RT_PHYE_MODE_DP, - - RT_PHYE_MODE_MAX, - - /* PCIe */ - RT_PHYE_MODE_PCIE_RC = RT_PHYE_MODE_MAX, - RT_PHYE_MODE_PCIE_EP, - RT_PHYE_MODE_PCIE_BIFURCATION, -}; - -struct rt_phye_ops; - -struct rt_phye -{ - struct rt_device *dev; - - const struct rt_phye_ops *ops; - - int init_count; - int power_count; - struct rt_spinlock lock; -}; - -struct rt_phye_ops -{ - rt_err_t (*init)(struct rt_phye *phye); - rt_err_t (*exit)(struct rt_phye *phye); - rt_err_t (*reset)(struct rt_phye *phye); - rt_err_t (*power_on)(struct rt_phye *phye); - rt_err_t (*power_off)(struct rt_phye *phye); - rt_err_t (*set_mode)(struct rt_phye *phye, enum rt_phye_mode mode, int submode); - rt_err_t (*ofw_parse)(struct rt_phye *phye, struct rt_ofw_cell_args *phye_args); -}; - -rt_err_t rt_phye_register(struct rt_phye *phye); -rt_err_t rt_phye_unregister(struct rt_phye *phye); - -rt_err_t rt_phye_init(struct rt_phye *phye); -rt_err_t rt_phye_exit(struct rt_phye *phye); -rt_err_t rt_phye_reset(struct rt_phye *phye); -rt_err_t rt_phye_power_on(struct rt_phye *phye); -rt_err_t rt_phye_power_off(struct rt_phye *phye); -rt_err_t rt_phye_set_mode(struct rt_phye *phye, enum rt_phye_mode mode, int submode); - -rt_inline rt_err_t rt_phye_set_mode_simple(struct rt_phye *phye, enum rt_phye_mode mode) -{ - return rt_phye_set_mode(phye, mode, RT_PHYE_MODE_INVALID); -} - -struct rt_phye *rt_phye_get_by_index(struct rt_device *dev, int index); -struct rt_phye *rt_phye_get_by_name(struct rt_device *dev, const char *id); -void rt_phye_put(struct rt_phye *phye); - -#endif /* __PHYE_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/pic.h b/rt-thread/components/drivers/include/drivers/pic.h index c624d24..fa1941a 100644 --- a/rt-thread/components/drivers/include/drivers/pic.h +++ b/rt-thread/components/drivers/include/drivers/pic.h @@ -148,7 +148,6 @@ void rt_pic_default_name(struct rt_pic *pic); struct rt_pic *rt_pic_dynamic_cast(void *ptr); rt_err_t rt_pic_linear_irq(struct rt_pic *pic, rt_size_t irq_nr); -rt_err_t rt_pic_cancel_irq(struct rt_pic *pic); int rt_pic_config_ipi(struct rt_pic *pic, int ipi_index, int hwirq); int rt_pic_config_irq(struct rt_pic *pic, int irq_index, int hwirq); diff --git a/rt-thread/components/drivers/include/drivers/platform.h b/rt-thread/components/drivers/include/drivers/platform.h index c4a497d..5dac676 100644 --- a/rt-thread/components/drivers/include/drivers/platform.h +++ b/rt-thread/components/drivers/include/drivers/platform.h @@ -12,7 +12,10 @@ #ifndef __PLATFORM_H__ #define __PLATFORM_H__ +#ifdef RT_USING_OFW #include +#endif + #include struct rt_platform_device @@ -22,7 +25,10 @@ struct rt_platform_device int dev_id; const char *name; + +#ifdef RT_USING_OFW const struct rt_ofw_node_id *id; +#endif void *priv; }; @@ -32,7 +38,10 @@ struct rt_platform_driver struct rt_driver parent; const char *name; + +#ifdef RT_USING_OFW const struct rt_ofw_node_id *ids; +#endif rt_err_t (*probe)(struct rt_platform_device *pdev); rt_err_t (*remove)(struct rt_platform_device *pdev); @@ -45,7 +54,6 @@ rt_err_t rt_platform_driver_register(struct rt_platform_driver *pdrv); rt_err_t rt_platform_device_register(struct rt_platform_device *pdev); rt_err_t rt_platform_ofw_device_probe_child(struct rt_ofw_node *np); -rt_err_t rt_platform_ofw_request(struct rt_ofw_node *np); rt_err_t rt_platform_ofw_free(struct rt_platform_device *pdev); #define RT_PLATFORM_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, platform, BUILIN) diff --git a/rt-thread/components/drivers/include/drivers/pm.h b/rt-thread/components/drivers/include/drivers/pm.h index f625782..45b3ae0 100644 --- a/rt-thread/components/drivers/include/drivers/pm.h +++ b/rt-thread/components/drivers/include/drivers/pm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -10,7 +10,6 @@ * 2019-04-28 Zero-Free improve PM mode and device ops interface * 2020-11-23 zhangsz update pm mode select * 2020-11-27 zhangsz update pm 2.0 - * 2024-07-04 wdfk-prog The device is registered and uninstalled by linked list */ #ifndef __PM_H__ @@ -135,16 +134,15 @@ struct rt_pm_ops struct rt_device_pm_ops { - rt_err_t (*suspend)(const struct rt_device *device, rt_uint8_t mode); + int (*suspend)(const struct rt_device *device, rt_uint8_t mode); void (*resume)(const struct rt_device *device, rt_uint8_t mode); - rt_err_t (*frequency_change)(const struct rt_device *device, rt_uint8_t mode); + int (*frequency_change)(const struct rt_device *device, rt_uint8_t mode); }; struct rt_device_pm { const struct rt_device *device; const struct rt_device_pm_ops *ops; - rt_slist_t list; }; struct rt_pm_module @@ -174,7 +172,7 @@ struct rt_pm rt_uint32_t sleep_status[PM_SLEEP_MODE_MAX - 1][(PM_MODULE_MAX_ID + 31) / 32]; /* the list of device, which has PM feature */ - rt_slist_t device_list; + rt_uint8_t device_pm_number; struct rt_device_pm *device_pm; /* if the mode has timer, the corresponding bit is 1*/ @@ -196,10 +194,10 @@ struct rt_pm_notify void *data; }; -rt_err_t rt_pm_request(rt_uint8_t sleep_mode); -rt_err_t rt_pm_release(rt_uint8_t sleep_mode); -rt_err_t rt_pm_release_all(rt_uint8_t sleep_mode); -rt_err_t rt_pm_run_enter(rt_uint8_t run_mode); +void rt_pm_request(rt_uint8_t sleep_mode); +void rt_pm_release(rt_uint8_t sleep_mode); +void rt_pm_release_all(rt_uint8_t sleep_mode); +int rt_pm_run_enter(rt_uint8_t run_mode); void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops); void rt_pm_device_unregister(struct rt_device *device); @@ -210,22 +208,22 @@ void rt_pm_default_set(rt_uint8_t sleep_mode); void rt_system_pm_init(const struct rt_pm_ops *ops, rt_uint8_t timer_mask, void *user_data); -rt_err_t rt_pm_module_request(uint8_t module_id, rt_uint8_t sleep_mode); -rt_err_t rt_pm_module_release(uint8_t module_id, rt_uint8_t sleep_mode); -rt_err_t rt_pm_module_release_all(uint8_t module_id, rt_uint8_t sleep_mode); +void rt_pm_module_request(uint8_t module_id, rt_uint8_t sleep_mode); +void rt_pm_module_release(uint8_t module_id, rt_uint8_t sleep_mode); +void rt_pm_module_release_all(uint8_t module_id, rt_uint8_t sleep_mode); void rt_pm_module_delay_sleep(rt_uint8_t module_id, rt_tick_t timeout); rt_uint32_t rt_pm_module_get_status(void); rt_uint8_t rt_pm_get_sleep_mode(void); struct rt_pm *rt_pm_get_handle(void); /* sleep : request or release */ -rt_err_t rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode); -rt_err_t rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode); -rt_err_t rt_pm_sleep_none_request(rt_uint16_t module_id); -rt_err_t rt_pm_sleep_none_release(rt_uint16_t module_id); -rt_err_t rt_pm_sleep_idle_request(rt_uint16_t module_id); -rt_err_t rt_pm_sleep_idle_release(rt_uint16_t module_id); -rt_err_t rt_pm_sleep_light_request(rt_uint16_t module_id); -rt_err_t rt_pm_sleep_light_release(rt_uint16_t module_id); +void rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode); +void rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode); +void rt_pm_sleep_none_request(rt_uint16_t module_id); +void rt_pm_sleep_none_release(rt_uint16_t module_id); +void rt_pm_sleep_idle_request(rt_uint16_t module_id); +void rt_pm_sleep_idle_release(rt_uint16_t module_id); +void rt_pm_sleep_light_request(rt_uint16_t module_id); +void rt_pm_sleep_light_release(rt_uint16_t module_id); #endif /* __PM_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/regulator.h b/rt-thread/components/drivers/include/drivers/regulator.h deleted file mode 100644 index d74fc64..0000000 --- a/rt-thread/components/drivers/include/drivers/regulator.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#ifndef __REGULATOR_H__ -#define __REGULATOR_H__ - -#include -#include -#include - -#include - -#define RT_REGULATOR_UVOLT_INVALID (((int)(RT_UINT32_MAX >> 1))) - -struct rt_regulator_param -{ - const char *name; - - int min_uvolt; /* In uV */ - int max_uvolt; /* In uV */ - int min_uamp; /* In uA */ - int max_uamp; /* In uA */ - int ramp_delay; /* In uV/usec */ - int enable_delay; /* In usec */ - int off_on_delay; /* In usec */ - - rt_uint32_t enable_active_high:1; - rt_uint32_t boot_on:1; /* Is enabled on boot */ - rt_uint32_t always_on:1; /* Must be enabled */ - rt_uint32_t soft_start:1; /* Ramp voltage slowly */ - rt_uint32_t pull_down:1; /* Pull down resistor when regulator off */ - rt_uint32_t over_current_protection:1; /* Auto disable on over current */ -}; - -struct rt_regulator_ops; - -struct rt_regulator_node -{ - rt_list_t list; - rt_list_t children_nodes; - - struct rt_device *dev; - struct rt_regulator_node *parent; - - const char *supply_name; - const struct rt_regulator_ops *ops; - - struct rt_ref ref; - rt_atomic_t enabled_count; - - const struct rt_regulator_param *param; - - rt_list_t notifier_nodes; - - void *priv; -}; - -/* - * NOTE: Power regulator control is dangerous work. We don't want non-internal - * consumer could access the power regulator tree without regulator's API. So - * we defined the `rt_regulator` member in core instead of here. - */ -struct rt_regulator; - -#define RT_REGULATOR_MODE_INVALID 0 -#define RT_REGULATOR_MODE_FAST RT_BIT(0) -#define RT_REGULATOR_MODE_NORMAL RT_BIT(1) -#define RT_REGULATOR_MODE_IDLE RT_BIT(2) -#define RT_REGULATOR_MODE_STANDBY RT_BIT(3) - -struct rt_regulator_ops -{ - rt_err_t (*enable)(struct rt_regulator_node *reg); - rt_err_t (*disable)(struct rt_regulator_node *reg); - rt_bool_t (*is_enabled)(struct rt_regulator_node *reg); - rt_err_t (*set_voltage)(struct rt_regulator_node *reg, int min_uvolt, int max_uvolt); - int (*get_voltage)(struct rt_regulator_node *reg); - rt_err_t (*set_mode)(struct rt_regulator_node *reg, rt_uint32_t mode); - rt_int32_t (*get_mode)(struct rt_regulator_node *reg); - rt_err_t (*set_ramp_delay)(struct rt_regulator_node *reg, int ramp); - rt_uint32_t (*enable_time)(struct rt_regulator_node *reg); -}; - -struct rt_regulator_notifier; - -#define RT_REGULATOR_MSG_ENABLE RT_BIT(0) -#define RT_REGULATOR_MSG_DISABLE RT_BIT(1) -#define RT_REGULATOR_MSG_VOLTAGE_CHANGE RT_BIT(2) -#define RT_REGULATOR_MSG_VOLTAGE_CHANGE_ERR RT_BIT(3) - -union rt_regulator_notifier_args -{ - struct - { - int old_uvolt; - int min_uvolt; - int max_uvolt; - }; -}; - -typedef rt_err_t (*rt_regulator_notifier_callback)(struct rt_regulator_notifier *notifier, - rt_ubase_t msg, void *data); - -struct rt_regulator_notifier -{ - rt_list_t list; - - struct rt_regulator *regulator; - rt_regulator_notifier_callback callback; - void *priv; -}; - -rt_err_t rt_regulator_register(struct rt_regulator_node *reg_np); -rt_err_t rt_regulator_unregister(struct rt_regulator_node *reg_np); - -rt_err_t rt_regulator_notifier_register(struct rt_regulator *reg, - struct rt_regulator_notifier *notifier); -rt_err_t rt_regulator_notifier_unregister(struct rt_regulator *reg, - struct rt_regulator_notifier *notifier); - -struct rt_regulator *rt_regulator_get(struct rt_device *dev, const char *id); -void rt_regulator_put(struct rt_regulator *reg); - -rt_err_t rt_regulator_enable(struct rt_regulator *reg); -rt_err_t rt_regulator_disable(struct rt_regulator *reg); -rt_bool_t rt_regulator_is_enabled(struct rt_regulator *reg); - -rt_bool_t rt_regulator_is_supported_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt); -rt_err_t rt_regulator_set_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt); -int rt_regulator_get_voltage(struct rt_regulator *reg); - -rt_err_t rt_regulator_set_mode(struct rt_regulator *reg, rt_uint32_t mode); -rt_int32_t rt_regulator_get_mode(struct rt_regulator *reg); - -rt_inline rt_err_t rt_regulator_set_voltage_triplet(struct rt_regulator *reg, - int min_uvolt, int target_uvolt, int max_uvolt) -{ - if (!rt_regulator_set_voltage(reg, target_uvolt, max_uvolt)) - { - return RT_EOK; - } - - return rt_regulator_set_voltage(reg, min_uvolt, max_uvolt); -} - -#endif /* __REGULATOR_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/reset.h b/rt-thread/components/drivers/include/drivers/reset.h deleted file mode 100644 index 6339fe9..0000000 --- a/rt-thread/components/drivers/include/drivers/reset.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-26 GuEe-GUI first version - */ - -#ifndef __RESET_H__ -#define __RESET_H__ - -#include -#include -#include - -#define RT_RESET_CONTROLLER_OBJ_NAME "RSTC" - -struct rt_reset_control_ops; - -struct rt_reset_controller -{ - struct rt_object parent; - - rt_list_t rstc_nodes; - - const char *name; - const struct rt_reset_control_ops *ops; - - struct rt_ofw_node *ofw_node; - void *priv; - - struct rt_spinlock spinlock; -}; - -struct rt_reset_control -{ - rt_list_t list; - - struct rt_reset_controller *rstcer; - - int id; - const char *con_id; - rt_bool_t is_array; - - void *priv; -}; - -struct rt_reset_control_ops -{ - /* - * rt_ofw_cell_args return: - * args[0] = rstc.id - */ - rt_err_t (*ofw_parse)(struct rt_reset_control *rstc, struct rt_ofw_cell_args *args); - /* API */ - rt_err_t (*reset)(struct rt_reset_control *rstc); - rt_err_t (*assert)(struct rt_reset_control *rstc); - rt_err_t (*deassert)(struct rt_reset_control *rstc); - int (*status)(struct rt_reset_control *rstc); -}; - -rt_err_t rt_reset_controller_register(struct rt_reset_controller *rstcer); -rt_err_t rt_reset_controller_unregister(struct rt_reset_controller *rstcer); - -rt_err_t rt_reset_control_reset(struct rt_reset_control *rstc); -rt_err_t rt_reset_control_assert(struct rt_reset_control *rstc); -rt_err_t rt_reset_control_deassert(struct rt_reset_control *rstc); -int rt_reset_control_status(struct rt_reset_control *rstc); - -rt_ssize_t rt_reset_control_get_count(struct rt_device *dev); -struct rt_reset_control *rt_reset_control_get_array(struct rt_device *dev); -struct rt_reset_control *rt_reset_control_get_by_index(struct rt_device *dev, int index); -struct rt_reset_control *rt_reset_control_get_by_name(struct rt_device *dev, const char *name); -void rt_reset_control_put(struct rt_reset_control *rstc); - -struct rt_reset_control *rt_ofw_get_reset_control_array(struct rt_ofw_node *np); -struct rt_reset_control *rt_ofw_get_reset_control_by_index(struct rt_ofw_node *np, int index); -struct rt_reset_control *rt_ofw_get_reset_control_by_name(struct rt_ofw_node *np, const char *name); - -#endif /* __RESET_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/scsi.h b/rt-thread/components/drivers/include/drivers/scsi.h deleted file mode 100644 index 7b6baaf..0000000 --- a/rt-thread/components/drivers/include/drivers/scsi.h +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#ifndef __SCSI_H__ -#define __SCSI_H__ - -#include -#include -#include - -#define RT_SCSI_LUN_SHIFT 5 - -rt_packed(struct rt_scsi_unknow -{ - rt_uint8_t opcode; -}); - -rt_packed(struct rt_scsi_test_unit_ready -{ - rt_uint8_t opcode; - rt_uint8_t reserved[4]; - rt_uint8_t control; - rt_uint8_t pad[6]; /* To be ATAPI compatible */ -}); - -rt_packed(struct rt_scsi_inquiry -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-2 Reserved, 1 Obsolete Formerly CMDDT, 0 EVPD */ - rt_uint8_t page; /* Page code if EVPD=1 */ - rt_uint8_t reserved; - rt_uint8_t alloc_length; - rt_uint8_t control; - rt_uint8_t pad[6]; /* To be ATAPI compatible */ -}); - -rt_packed(struct rt_scsi_inquiry_data -{ -#define RT_SCSI_DEVTYPE_MASK 31 - rt_uint8_t devtype; -#define RT_SCSI_REMOVABLE_BIT 7 - rt_uint8_t rmb; - rt_uint8_t reserved[2]; - rt_uint8_t length; - rt_uint8_t reserved1[3]; - char vendor[8]; - char prodid[16]; - char prodrev[4]; -}); - -rt_packed(struct rt_scsi_request_sense -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-2 Reserved, 1 Obsolete, 0 SP */ - rt_uint8_t reserved[2]; - rt_uint8_t alloc_length; - rt_uint8_t control; - rt_uint8_t pad[6]; /* To be ATAPI compatible */ -}); - -rt_packed(struct rt_scsi_request_sense_data -{ - rt_uint8_t error_code; /* 7 Valid, 6-0 Err. code */ - rt_uint8_t segment_number; - rt_uint8_t sense_key; /* 7 FileMark, 6 EndOfMedia, 5 ILI, 4-0 sense key */ - rt_be32_t information; - rt_uint8_t additional_sense_length; - rt_be32_t cmd_specific_info; - rt_uint8_t additional_sense_code; - rt_uint8_t additional_sense_code_qualifier; - rt_uint8_t field_replaceable_unit_code; - rt_uint8_t sense_key_specific[3]; -}); - -rt_packed(struct rt_scsi_read_capacity10 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-1 Reserved, 0 Obsolete */ - rt_be32_t logical_block_addr; /* only if PMI=1 */ - rt_uint8_t reserved[2]; - rt_uint8_t pmi; - rt_uint8_t control; - rt_be16_t pad; /* To be ATAPI compatible */ -}); - -rt_packed(struct rt_scsi_read_capacity10_data -{ - rt_be32_t last_block; - rt_be32_t block_size; -}); - -rt_packed(struct rt_scsi_read_capacity16 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-5 Reserved, 4-0 SERVICE ACTION 0x10 */ - rt_be64_t logical_block_addr; /* only if PMI=1 */ - rt_be32_t alloc_len; - rt_uint8_t pmi; - rt_uint8_t control; -}); - -rt_packed(struct rt_scsi_read_capacity16_data -{ - rt_be64_t last_block; - rt_be32_t block_size; - rt_uint8_t pad[20]; -}); - -rt_packed(struct rt_scsi_read10 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-5 RDPROTECT, 4 DPO, 3 FUA, 2 RARC, 1 Obsolete, 0 Obsolete */ - rt_be32_t lba; - rt_uint8_t reserved; - rt_be16_t size; - rt_uint8_t reserved2; - rt_be16_t pad; -}); - -rt_packed(struct rt_scsi_read12 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-5 RDPROTECT, 4 DPO, 3 FUA, 2 RARC, 1 Obsolete, 0 Obsolete */ - rt_be32_t lba; - rt_be32_t size; - rt_uint8_t reserved; - rt_uint8_t control; -}); - -rt_packed(struct rt_scsi_read16 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-5 RDPROTECT, 4 DPO, 3 FUA, 2 RARC, 1 Obsolete, 0 DLD2 */ - rt_be64_t lba; - rt_be32_t size; - rt_uint8_t reserved; - rt_uint8_t control; -}); - -rt_packed(struct rt_scsi_write10 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-5 WRPROTECT, 4 DPO, 3 FUA, 2 Reserved, 1 Obsolete, 0 Obsolete */ - rt_be32_t lba; - rt_uint8_t reserved; - rt_be16_t size; - rt_uint8_t reserved2; - rt_be16_t pad; -}); - -rt_packed(struct rt_scsi_write12 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-5 WRPROTECT, 4 DPO, 3 FUA, 2 Reserved, 1 Obsolete, 0 Obsolete */ - rt_be32_t lba; - rt_be32_t size; - rt_uint8_t reserved; - rt_uint8_t control; -}); - -rt_packed(struct rt_scsi_write16 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-5 WRPROTECT, 4 DPO, 3 FUA, 2 Reserved, 1 Obsolete, 0 DLD2 */ - rt_be64_t lba; - rt_be32_t size; - rt_uint8_t reserved; - rt_uint8_t control; -}); - -rt_packed(struct rt_scsi_synchronize_cache10 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-3 Reserved, 2 Obsolete, 1 IMMED, 0 Obsolete */ - rt_be32_t lba; - rt_uint8_t reserved; - rt_be16_t size; - rt_uint8_t control; -}); - -rt_packed(struct rt_scsi_synchronize_cache16 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-3 Reserved, 2 Obsolete, 1 IMMED, 0 Obsolete */ - rt_be64_t lba; - rt_be32_t size; - rt_uint8_t reserved; - rt_uint8_t control; -}); - -#define RT_SCSI_UNMAP_SHIFT 3 - -rt_packed(struct rt_scsi_write_same10 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-5 WRPROTECT, 4 ANCHOR, 3 UNMAP, 2 Obsolete, 1 Obsolete, 0 Obsolete */ - rt_be32_t lba; - rt_uint8_t reserved; - rt_be16_t size; - rt_uint8_t control; -}); - -rt_packed(struct rt_scsi_write_same16 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-5 WRPROTECT, 4 ANCHOR, 3 UNMAP, 2 Obsolete, 1 Obsolete, 0 NDOB */ - rt_be64_t lba; - rt_be32_t size; - rt_uint8_t reserved; - rt_uint8_t control; -}); - -#define RT_SCSI_PF_SHIFT 4 -#define RT_SCSI_RTD_SHIFT 1 -#define RT_SCSI_SP_SHIFT 0 - -rt_packed(struct rt_scsi_mode_select6 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-5 Reserved, 4 PF, 3-2 Reserved, 1 RTD, 0 SP */ - rt_uint8_t reserved[2]; - rt_uint8_t param_list_len; - rt_uint8_t control; -}); - -rt_packed(struct rt_scsi_mode_select10 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-5 Reserved, 4 PF, 3-1 Reserved, 0 SP */ - rt_uint8_t reserved[5]; - rt_be16_t param_list_len; - rt_uint8_t control; -}); - -struct rt_scsi_mode_select_data -{ - rt_uint32_t length; - rt_uint16_t block_descriptor_length; - rt_uint8_t medium_type; - rt_uint8_t device_specific; - rt_uint8_t header_length; - rt_uint8_t longlba:1; -}; - -#define RT_SCSI_DBD_SHIFT 3 -#define RT_SCSI_LLBAA_SHIFT 4 -#define RT_SCSI_PC_SHIFT 6 -#define RT_SCSI_PAGE_CODE_SHIFT 0 - -rt_packed(struct rt_scsi_mode_sense6 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-4 Reserved, 3 DBD, 2-0 Reserved */ - rt_uint8_t page_control_code; - rt_uint8_t subpage_code; - rt_uint8_t allocation_len; - rt_uint8_t control; -}); - -rt_packed(struct rt_scsi_mode_sense10 -{ - rt_uint8_t opcode; - rt_uint8_t config; /* 7-5 Reserved, 4 LLBAA, 3 DBD, 2-0 Reserved */ - rt_uint8_t page_control_code; - rt_uint8_t subpage_code; - rt_uint8_t reserved[3]; - rt_be16_t allocation_len; - rt_uint8_t control; -}); - -#define RT_SCSI_CMD_TEST_UNIT_READY 0x00 -#define RT_SCSI_CMD_REQUEST_SENSE 0x03 -#define RT_SCSI_CMD_INQUIRY 0x12 -#define RT_SCSI_CMD_MODE_SELECT 0x15 -#define RT_SCSI_CMD_MODE_SENSE 0x1a -#define RT_SCSI_CMD_READ_CAPACITY10 0x25 -#define RT_SCSI_CMD_READ10 0x28 -#define RT_SCSI_CMD_WRITE10 0x2a -#define RT_SCSI_CMD_SYNCHRONIZE_CACHE10 0x35 -#define RT_SCSI_CMD_WRITE_SAME10 0x41 -#define RT_SCSI_CMD_MODE_SELECT10 0x55 -#define RT_SCSI_CMD_MODE_SENSE10 0x5a -#define RT_SCSI_CMD_READ16 0x88 -#define RT_SCSI_CMD_WRITE16 0x8a -#define RT_SCSI_CMD_SYNCHRONIZE_CACHE16 0x91 -#define RT_SCSI_CMD_WRITE_SAME16 0x93 -#define RT_SCSI_CMD_READ_CAPACITY16 0x9e -#define RT_SCSI_CMD_READ12 0xa8 -#define RT_SCSI_CMD_WRITE12 0xaa - -struct rt_scsi_cmd -{ - union - { - struct rt_scsi_unknow unknow; - struct rt_scsi_test_unit_ready test_unit_ready; - struct rt_scsi_inquiry inquiry; - struct rt_scsi_request_sense request_sense; - struct rt_scsi_read_capacity10 read_capacity10; - struct rt_scsi_read_capacity16 read_capacity16; - struct rt_scsi_read10 read10; - struct rt_scsi_read12 read12; - struct rt_scsi_read16 read16; - struct rt_scsi_write10 write10; - struct rt_scsi_write12 write12; - struct rt_scsi_write16 write16; - struct rt_scsi_synchronize_cache10 synchronize_cache10; - struct rt_scsi_synchronize_cache16 synchronize_cache16; - struct rt_scsi_write_same10 write_same10; - struct rt_scsi_write_same16 write_same16; - struct rt_scsi_mode_select6 mode_select6; - struct rt_scsi_mode_select10 mode_select10; - struct rt_scsi_mode_sense6 mode_sense6; - struct rt_scsi_mode_sense10 mode_sense10; - } op; - rt_size_t op_size; - - union - { - struct - { - struct rt_scsi_inquiry_data inquiry; - struct rt_scsi_request_sense_data request_sense; - struct rt_scsi_read_capacity10_data read_capacity10; - struct rt_scsi_read_capacity16_data read_capacity16; - }; - struct - { - void *ptr; - rt_size_t size; - }; - } data; -}; - -enum -{ - SCSI_DEVICE_TYPE_DIRECT = 0x00, /* DiskPeripheral (GenDisk) */ - SCSI_DEVICE_TYPE_SEQUENTIAL = 0x01, /* TapePeripheral */ - SCSI_DEVICE_TYPE_PRINTER = 0x02, /* PrinterPeripheral (GenPrinter) */ - SCSI_DEVICE_TYPE_PROCESSOR = 0x03, /* OtherPeripheral */ - SCSI_DEVICE_TYPE_WRITE_ONCE_READ_MULTIPLE = 0x04, /* WormPeripheral (GenWorm) */ - SCSI_DEVICE_TYPE_CDROM = 0x05, /* CdRomPeripheral (GenCdRom) */ - SCSI_DEVICE_TYPE_SCANNER = 0x06, /* ScannerPeripheral (GenScanner) */ - SCSI_DEVICE_TYPE_OPTICAL = 0x07, /* OpticalDiskPeripheral (GenOptical) */ - SCSI_DEVICE_TYPE_MEDIUM_CHANGER = 0x08, /* MediumChangerPeripheral (ScsiChanger) */ - SCSI_DEVICE_TYPE_COMMUNICATION = 0x09, /* CommunicationsPeripheral (ScsiNet) */ - SCSI_DEVICE_TYPE_ASC_PREPRESS_GRAPHICS10 = 0x0a, /* ASCPrePressGraphicsPeripheral (ScsiASCIT8) */ - SCSI_DEVICE_TYPE_ASC_PREPRESS_GRAPHICS11 = 0x0b, /* ASCPrePressGraphicsPeripheral (ScsiASCIT8) */ - SCSI_DEVICE_TYPE_ARRAY = 0x0c, /* ArrayPeripheral (ScsiArray) */ - SCSI_DEVICE_TYPE_ENCLOSURE = 0x0d, /* EnclosurePeripheral (ScsiEnclosure) */ - SCSI_DEVICE_TYPE_RBC = 0x0e, /* RBCPeripheral (ScsiRBC) */ - SCSI_DEVICE_TYPE_CARDREADER = 0x0f, /* CardReaderPeripheral (ScsiCardReader) */ - SCSI_DEVICE_TYPE_BRIDGE = 0x10, /* BridgePeripheral (ScsiBridge) */ - SCSI_DEVICE_TYPE_OTHER = 0x11, /* OtherPeripheral (ScsiOther) */ - SCSI_DEVICE_TYPE_MAX, -}; - -struct rt_scsi_ops; - -struct rt_scsi_host -{ - struct rt_device *dev; - - const struct rt_scsi_ops *ops; - - rt_size_t max_id; - rt_size_t max_lun; - - rt_list_t lun_nodes; -}; - -struct rt_scsi_device -{ - struct rt_scsi_host *host; - - rt_list_t list; - - rt_size_t id; - rt_size_t lun; - rt_uint32_t devtype; - rt_uint32_t removable; - rt_size_t last_block; - rt_size_t block_size; - - void *priv; -}; - -struct rt_scsi_ops -{ - rt_err_t (*reset)(struct rt_scsi_device *sdev); - rt_err_t (*transfer)(struct rt_scsi_device *sdev, struct rt_scsi_cmd *cmd); -}; - -rt_err_t rt_scsi_host_register(struct rt_scsi_host *scsi); -rt_err_t rt_scsi_host_unregister(struct rt_scsi_host *scsi); - -rt_inline rt_bool_t rt_scsi_cmd_is_write(struct rt_scsi_cmd *cmd) -{ - return cmd->op.write10.opcode == RT_SCSI_CMD_WRITE10 || - cmd->op.write12.opcode == RT_SCSI_CMD_WRITE16 || - cmd->op.write16.opcode == RT_SCSI_CMD_WRITE12; -} - -rt_err_t rt_scsi_request_sense(struct rt_scsi_device *sdev, - struct rt_scsi_request_sense_data *out_data); - -rt_err_t rt_scsi_test_unit_ready(struct rt_scsi_device *sdev); -rt_err_t rt_scsi_inquiry(struct rt_scsi_device *sdev, - struct rt_scsi_inquiry_data *out_data); - -rt_err_t rt_scsi_read_capacity10(struct rt_scsi_device *sdev, - struct rt_scsi_read_capacity10_data *out_data); -rt_err_t rt_scsi_read_capacity16(struct rt_scsi_device *sdev, - struct rt_scsi_read_capacity16_data *out_data); - -rt_err_t rt_scsi_read10(struct rt_scsi_device *sdev, - rt_off_t lba, void *buffer, rt_size_t size); -rt_err_t rt_scsi_read12(struct rt_scsi_device *sdev, - rt_off_t lba, void *buffer, rt_size_t size); -rt_err_t rt_scsi_read16(struct rt_scsi_device *sdev, - rt_off_t lba, void *buffer, rt_size_t size); - -rt_err_t rt_scsi_write10(struct rt_scsi_device *sdev, - rt_off_t lba, const void *buffer, rt_size_t size); -rt_err_t rt_scsi_write12(struct rt_scsi_device *sdev, - rt_off_t lba, const void *buffer, rt_size_t size); -rt_err_t rt_scsi_write16(struct rt_scsi_device *sdev, - rt_off_t lba, const void *buffer, rt_size_t size); - -rt_err_t rt_scsi_synchronize_cache10(struct rt_scsi_device *sdev, - rt_off_t lba, rt_size_t size); -rt_err_t rt_scsi_synchronize_cache16(struct rt_scsi_device *sdev, - rt_off_t lba, rt_size_t size); - -rt_err_t rt_scsi_write_same10(struct rt_scsi_device *sdev, - rt_off_t lba, rt_size_t size); -rt_err_t rt_scsi_write_same16(struct rt_scsi_device *sdev, - rt_off_t lba, rt_size_t size); - -rt_err_t rt_scsi_mode_select6(struct rt_scsi_device *sdev, - rt_uint8_t pf, rt_uint8_t sp, void *buffer, rt_size_t size, - struct rt_scsi_mode_select_data *data); -rt_err_t rt_scsi_mode_select10(struct rt_scsi_device *sdev, - rt_uint8_t pf, rt_uint8_t sp, void *buffer, rt_size_t size, - struct rt_scsi_mode_select_data *data); - -rt_err_t rt_scsi_mode_sense6(struct rt_scsi_device *sdev, - rt_uint8_t dbd, rt_uint8_t modepage, rt_uint8_t subpage, void *buffer, rt_size_t size, - struct rt_scsi_mode_select_data *data); -rt_err_t rt_scsi_mode_sense10(struct rt_scsi_device *sdev, - rt_uint8_t dbd, rt_uint8_t modepage, rt_uint8_t subpage, void *buffer, rt_size_t size, - struct rt_scsi_mode_select_data *data); - -#endif /* __SCSI_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/sensor.h b/rt-thread/components/drivers/include/drivers/sensor.h index ca1c84e..6c8b78e 100644 --- a/rt-thread/components/drivers/include/drivers/sensor.h +++ b/rt-thread/components/drivers/include/drivers/sensor.h @@ -12,7 +12,7 @@ #define __SENSOR_H__ #include -#include "dev_pin.h" +#include "pin.h" #ifdef __cplusplus extern "C" { @@ -53,9 +53,6 @@ extern "C" { #define RT_SENSOR_CLASS_IAQ (19) /* IAQ sensor. */ #define RT_SENSOR_CLASS_ETOH (20) /* EtOH sensor. */ #define RT_SENSOR_CLASS_BP (21) /* Blood Pressure */ -#define RT_SENSOR_CLASS_VOLTAGE (22) /* Voltage sensor */ -#define RT_SENSOR_CLASS_CURRENT (23) /* Current sensor */ -#define RT_SENSOR_CLASS_POWER (24) /* Power sensor */ /* Sensor vendor types */ @@ -98,9 +95,6 @@ extern "C" { #define RT_SENSOR_UNIT_DD (17) /* Coordinates unit: DD */ #define RT_SENSOR_UNIT_MGM3 (18) /* Concentration unit: mg/m3 */ #define RT_SENSOR_UNIT_MMHG (19) /* Blood Pressure unit: mmHg */ -#define RT_SENSOR_UNIT_MV (20) /* Voltage unit: mV */ -#define RT_SENSOR_UNIT_MA (21) /* Current unit: mA */ -#define RT_SENSOR_UNIT_MW (22) /* Power unit: mW */ /* Sensor communication interface types */ #define RT_SENSOR_INTF_I2C (1 << 0) @@ -236,12 +230,9 @@ struct rt_sensor_data rt_uint32_t dust; /* Dust sensor. unit: ug/m3 */ rt_uint32_t eco2; /* eCO2 sensor. unit: ppm */ rt_uint32_t spo2; /* SpO2 sensor. unit: permillage */ - rt_uint32_t iaq; /* IAQ sensor. unit: 1 */ - rt_uint32_t etoh; /* EtOH sensor. unit: ppm */ + rt_uint32_t iaq; /* IAQ sensor. unit: 1 */ + rt_uint32_t etoh; /* EtOH sensor. unit: ppm */ struct sensor_bp bp; /* BloodPressure. unit: mmHg */ - float mv; /* Voltage sensor. unit: mv */ - float ma; /* Current sensor. unit: ma */ - float mw; /* Power sensor. unit: mw */ } data; }; diff --git a/rt-thread/components/drivers/include/drivers/sensor_v2.h b/rt-thread/components/drivers/include/drivers/sensor_v2.h index 3cb00ca..d90cef8 100644 --- a/rt-thread/components/drivers/include/drivers/sensor_v2.h +++ b/rt-thread/components/drivers/include/drivers/sensor_v2.h @@ -13,7 +13,7 @@ #define __SENSOR_H__ #include -#include "dev_pin.h" +#include "pin.h" #ifdef __cplusplus extern "C" { diff --git a/rt-thread/components/drivers/include/drivers/serial_bypass.h b/rt-thread/components/drivers/include/drivers/serial_bypass.h deleted file mode 100644 index 890c894..0000000 --- a/rt-thread/components/drivers/include/drivers/serial_bypass.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-11-20 zhujiale the first version - */ - -#ifndef __RTT_BYPASS_H__ -#define __RTT_BYPASS_H__ -#include -#include -#include -typedef rt_err_t(*bypass_function_t)(struct rt_serial_device* serial, char buf, void* data); - -#define RT_BYPASS_LEVEL_MAX 4 -#define RT_BYPASS_LEVEL_1 0 -#define RT_BYPASS_LEVEL_2 1 -#define RT_BYPASS_LEVEL_3 2 -#define RT_BYPASS_LEVEL_4 3 -#define RT_BYPASS_MAX_LEVEL 4 - -/*The protect level can be register but can not be unregister we should use it carefully*/ -#define RT_BYPASS_PROTECT_LEVEL_1 10 -#define RT_BYPASS_PROTECT_LEVEL_2 11 -#define RT_BYPASS_PROTECT_LEVEL_3 12 -#define RT_BYPASS_PROTECT_LEVEL_4 13 - -struct rt_serial_bypass_func { - /*The function pointer of the bypassed data processing*/ - bypass_function_t bypass; - /*The smaller the array of levels, the higher the priority of execution*/ - rt_uint8_t level; - rt_list_t node; - char name[RT_NAME_MAX]; - void* data; -}; - -struct rt_serial_bypass_head -{ - rt_list_t head; - struct rt_spinlock spinlock; -}; - -struct rt_serial_bypass { - struct rt_work work; - - struct rt_spinlock spinlock; - struct rt_workqueue* lower_workq; - struct rt_serial_bypass_head* upper_h; - struct rt_serial_bypass_head* lower_h; - rt_mutex_t mutex; - struct rt_ringbuffer* pipe; -}; - -int serial_bypass_list(int argc, char** argv); - -void rt_bypass_work_straight(struct rt_serial_device* serial); -void rt_bypass_putchar(struct rt_serial_device* serial, rt_uint8_t ch); -rt_size_t rt_bypass_getchar(struct rt_serial_device* serial, rt_uint8_t* ch); - -rt_err_t rt_bypass_upper_unregister(struct rt_serial_device* serial, rt_uint8_t level); -rt_err_t rt_bypass_lower_unregister(struct rt_serial_device* serial, rt_uint8_t level); - -rt_err_t rt_bypass_upper_register(struct rt_serial_device* serial, const char* name, rt_uint8_t level, bypass_function_t func, void* data); -rt_err_t rt_bypass_lower_register(struct rt_serial_device* serial, const char* name, rt_uint8_t level, bypass_function_t func, void* data); -#endif diff --git a/rt-thread/components/drivers/include/drivers/syscon.h b/rt-thread/components/drivers/include/drivers/syscon.h deleted file mode 100644 index 15bb98b..0000000 --- a/rt-thread/components/drivers/include/drivers/syscon.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#ifndef __SYSCON_H__ -#define __SYSCON_H__ - -#include - -struct rt_syscon -{ - rt_list_t list; - - struct rt_ofw_node *np; - - void *iomem_base; - rt_size_t iomem_size; - struct rt_spinlock rw_lock; -}; - -rt_err_t rt_syscon_read(struct rt_syscon *syscon, rt_off_t offset, rt_uint32_t *out_val); -rt_err_t rt_syscon_write(struct rt_syscon *syscon, rt_off_t offset, rt_uint32_t val); -rt_err_t rt_syscon_update_bits(struct rt_syscon *syscon, rt_off_t offset, rt_uint32_t mask, rt_uint32_t val); - -struct rt_syscon *rt_syscon_find_by_ofw_node(struct rt_ofw_node *np); -struct rt_syscon *rt_syscon_find_by_ofw_compatible(const char *compatible); -struct rt_syscon *rt_syscon_find_by_ofw_phandle(struct rt_ofw_node *np, const char *propname); - -#endif /* __SYSCON_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/thermal.h b/rt-thread/components/drivers/include/drivers/thermal.h deleted file mode 100644 index 0770c5c..0000000 --- a/rt-thread/components/drivers/include/drivers/thermal.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#ifndef __THERMAL_H__ -#define __THERMAL_H__ - -#include -#include - -/* No upper/lower limit requirement */ -#define RT_THERMAL_NO_LIMIT ((rt_uint32_t)THERMAL_NO_LIMIT) -#define RT_THERMAL_TEMP_INVALID (-274000) - -struct rt_thermal_zone_ops; -struct rt_thermal_cooling_device; -struct rt_thermal_cooling_device_ops; -struct rt_thermal_cooling_governor; - -enum rt_thermal_trip_type -{ - RT_THERMAL_TRIP_ACTIVE = 0, - RT_THERMAL_TRIP_PASSIVE, - RT_THERMAL_TRIP_HOT, - RT_THERMAL_TRIP_CRITICAL, - - RT_THERMAL_TRIP_TYPE_MAX, -}; - -struct rt_thermal_trip -{ - /* Temperature value in millidegree celsius */ - int temperature; - /* Relative hysteresis in millidegree celsius */ - int hysteresis; - enum rt_thermal_trip_type type; - - void *priv; -}; - -struct rt_thermal_zone_params -{ - /* Sustainable power (heat) that this thermal zone can dissipate in mW */ - int sustainable_power; - /* Slope of a linear temperature adjustment curve */ - int slope; - /* Offset of a linear temperature adjustment curve */ - int offset; -}; - -struct rt_thermal_cooling_cell -{ - struct rt_thermal_cooling_device *cooling_devices; - - rt_uint32_t level_range[2]; -}; - -struct rt_thermal_cooling_map -{ - rt_uint32_t contribution; - - rt_size_t cells_nr; - struct rt_thermal_cooling_cell *cells; - struct rt_thermal_trip *trips; -}; - -struct rt_thermal_zone_device -{ - struct rt_device parent; - - int zone_id; - const struct rt_thermal_zone_ops *ops; - - rt_bool_t trips_free; - rt_size_t trips_nr; - struct rt_thermal_trip *trips; - struct rt_thermal_zone_params params; - - rt_bool_t enabled; - rt_bool_t cooling; - int temperature; - int last_temperature; - int prev_low_trip; - int prev_high_trip; - - rt_list_t notifier_nodes; - struct rt_spinlock nodes_lock; - - rt_size_t cooling_maps_nr; - struct rt_thermal_cooling_map *cooling_maps; - - rt_tick_t passive_delay, polling_delay; - struct rt_work poller; - - struct rt_mutex mutex; - - void *priv; -}; - -struct rt_thermal_zone_ops -{ - rt_err_t (*get_temp)(struct rt_thermal_zone_device *zdev, int *out_temp); - rt_err_t (*set_trips)(struct rt_thermal_zone_device *zdev, int low_temp, int high_temp); - rt_err_t (*set_trip_temp)(struct rt_thermal_zone_device *zdev, int trip_id, int temp); - rt_err_t (*set_trip_hyst)(struct rt_thermal_zone_device *zdev, int trip_id, int hyst); - void (*hot)(struct rt_thermal_zone_device *zdev); - void (*critical)(struct rt_thermal_zone_device *zdev); -}; - -/* - * We don't want to make a temperature control system - * that is finer than an air conditioner's temperature control, - * just ensure get a reliable heat dissipation under high-load task - * or when the SoC temperature is too high. - */ -struct rt_thermal_cooling_device -{ - struct rt_device parent; - - const struct rt_thermal_cooling_device_ops *ops; - - /* The cooling capacity indicator */ - rt_ubase_t max_level; - rt_list_t governor_node; - struct rt_thermal_cooling_governor *gov; - - void *priv; -}; - -struct rt_thermal_cooling_device_ops -{ - rt_err_t (*bind)(struct rt_thermal_cooling_device *cdev, struct rt_thermal_zone_device *zdev); - rt_err_t (*unbind)(struct rt_thermal_cooling_device *cdev, struct rt_thermal_zone_device *zdev); - rt_err_t (*get_max_level)(struct rt_thermal_cooling_device *cdev, rt_ubase_t *out_level); - rt_err_t (*get_cur_level)(struct rt_thermal_cooling_device *cdev, rt_ubase_t *out_level); - rt_err_t (*set_cur_level)(struct rt_thermal_cooling_device *cdev, rt_ubase_t level); -}; - -struct rt_thermal_cooling_governor -{ - rt_list_t list; - - const char *name; - rt_list_t cdev_nodes; - - void (*tuning)(struct rt_thermal_zone_device *zdev, - int map_idx, int cell_idx, rt_ubase_t *level); -}; - -struct rt_thermal_notifier; - -#define RT_THERMAL_MSG_EVENT_UNSPECIFIED RT_BIT(0) /* Unspecified event */ -#define RT_THERMAL_MSG_EVENT_TEMP_SAMPLE RT_BIT(1) /* New Temperature sample */ -#define RT_THERMAL_MSG_TRIP_VIOLATED RT_BIT(2) /* TRIP Point violation */ -#define RT_THERMAL_MSG_TRIP_CHANGED RT_BIT(3) /* TRIP Point temperature changed */ -#define RT_THERMAL_MSG_DEVICE_DOWN RT_BIT(4) /* Thermal device is down */ -#define RT_THERMAL_MSG_DEVICE_UP RT_BIT(5) /* Thermal device is up after a down event */ -#define RT_THERMAL_MSG_DEVICE_POWER_CAPABILITY_CHANGED RT_BIT(6) /* Power capability changed */ -#define RT_THERMAL_MSG_TABLE_CHANGED RT_BIT(7) /* Thermal table(s) changed */ -#define RT_THERMAL_MSG_EVENT_KEEP_ALIVE RT_BIT(8) /* Request for user space handler to respond */ - -typedef rt_err_t (*rt_thermal_notifier_callback)(struct rt_thermal_notifier *notifier, - rt_ubase_t msg); - -struct rt_thermal_notifier -{ - rt_list_t list; - - struct rt_thermal_zone_device *zdev; - rt_thermal_notifier_callback callback; - void *priv; -}; - -rt_err_t rt_thermal_zone_device_register(struct rt_thermal_zone_device *zdev); -rt_err_t rt_thermal_zone_device_unregister(struct rt_thermal_zone_device *zdev); - -rt_err_t rt_thermal_cooling_device_register(struct rt_thermal_cooling_device *cdev); -rt_err_t rt_thermal_cooling_device_unregister(struct rt_thermal_cooling_device *cdev); - -rt_err_t rt_thermal_cooling_governor_register(struct rt_thermal_cooling_governor *gov); -rt_err_t rt_thermal_cooling_governor_unregister(struct rt_thermal_cooling_governor *gov); - -rt_err_t rt_thermal_cooling_device_change_governor(struct rt_thermal_cooling_device *cdev, - const char *name); - -rt_err_t rt_thermal_zone_notifier_register(struct rt_thermal_zone_device *zdev, - struct rt_thermal_notifier *notifier); -rt_err_t rt_thermal_zone_notifier_unregister(struct rt_thermal_zone_device *zdev, - struct rt_thermal_notifier *notifier); - -void rt_thermal_zone_device_update(struct rt_thermal_zone_device *zdev, rt_ubase_t msg); -void rt_thermal_cooling_device_kick(struct rt_thermal_zone_device *zdev); - -rt_err_t rt_thermal_zone_set_trip(struct rt_thermal_zone_device *zdev, int trip_id, - const struct rt_thermal_trip *trip); -rt_err_t rt_thermal_zone_get_trip(struct rt_thermal_zone_device *zdev, int trip_id, - struct rt_thermal_trip *out_trip); - -#endif /* __THERMAL_H__ */ diff --git a/rt-thread/components/drivers/include/drivers/wlan.h b/rt-thread/components/drivers/include/drivers/wlan.h index 4a1ab5b..9468518 100644 --- a/rt-thread/components/drivers/include/drivers/wlan.h +++ b/rt-thread/components/drivers/include/drivers/wlan.h @@ -12,10 +12,10 @@ #define __WLAN_H__ #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #endif diff --git a/rt-thread/components/drivers/include/dt-bindings/phye/phye.h b/rt-thread/components/drivers/include/dt-bindings/phye/phye.h deleted file mode 100644 index 54a9cce..0000000 --- a/rt-thread/components/drivers/include/dt-bindings/phye/phye.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __DT_BINDINGS_PHYE_H__ -#define __DT_BINDINGS_PHYE_H__ - -#define PHY_NONE 0 -#define PHY_TYPE_SATA 1 -#define PHY_TYPE_PCIE 2 -#define PHY_TYPE_USB2 3 -#define PHY_TYPE_USB3 4 -#define PHY_TYPE_UFS 5 -#define PHY_TYPE_DP 6 -#define PHY_TYPE_XPCS 7 -#define PHY_TYPE_SGMII 8 -#define PHY_TYPE_QSGMII 9 -#define PHY_TYPE_DPHY 10 -#define PHY_TYPE_CPHY 11 -#define PHY_TYPE_USXGMII 12 - -#endif /* __DT_BINDINGS_PHYE_H__ */ diff --git a/rt-thread/components/drivers/include/dt-bindings/thermal/thermal.h b/rt-thread/components/drivers/include/dt-bindings/thermal/thermal.h deleted file mode 100644 index 60414cf..0000000 --- a/rt-thread/components/drivers/include/dt-bindings/thermal/thermal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __DT_BINDINGS_THERMAL_THERMAL_H__ -#define __DT_BINDINGS_THERMAL_THERMAL_H__ - -/* On cooling devices upper and lower limits */ -#define THERMAL_NO_LIMIT (~0) - -#endif /* __DT_BINDINGS_THERMAL_THERMAL_H__ */ diff --git a/rt-thread/components/drivers/include/ipc/completion.h b/rt-thread/components/drivers/include/ipc/completion.h index 25581f6..30f4acf 100644 --- a/rt-thread/components/drivers/include/ipc/completion.h +++ b/rt-thread/components/drivers/include/ipc/completion.h @@ -6,7 +6,6 @@ * Change Logs: * Date Author Notes * 2024-04-28 Shell Add new wait_flags() & wakeup_by_errno() API - * 2024-10-24 yekai Add C++ support */ #ifndef COMPLETION_H_ #define COMPLETION_H_ @@ -15,9 +14,9 @@ #include /** - * RT-Completion - A Tiny(resource-constrained) & Rapid(lockless) IPC Primitive + * Completion - A tiny & rapid IPC primitive for resource-constrained scenarios * - * It's an IPC using one pointer word with the encoding: + * It's an IPC using one CPU word with the encoding: * * BIT | MAX-1 ----------------- 1 | 0 | * CONTENT | suspended_thread & ~1 | completed flag | @@ -31,25 +30,12 @@ struct rt_completion #define RT_COMPLETION_INIT(comp) {0} -#ifdef __cplusplus -extern "C" { -#endif - void rt_completion_init(struct rt_completion *completion); rt_err_t rt_completion_wait(struct rt_completion *completion, rt_int32_t timeout); -rt_err_t rt_completion_wait_noisr(struct rt_completion *completion, - rt_int32_t timeout); rt_err_t rt_completion_wait_flags(struct rt_completion *completion, rt_int32_t timeout, int suspend_flag); -rt_err_t rt_completion_wait_flags_noisr(struct rt_completion *completion, - rt_int32_t timeout, int suspend_flag); void rt_completion_done(struct rt_completion *completion); rt_err_t rt_completion_wakeup(struct rt_completion *completion); rt_err_t rt_completion_wakeup_by_errno(struct rt_completion *completion, rt_err_t error); - -#ifdef __cplusplus -} -#endif - #endif diff --git a/rt-thread/components/drivers/include/ipc/workqueue.h b/rt-thread/components/drivers/include/ipc/workqueue.h index 8d0c986..e05a7ab 100644 --- a/rt-thread/components/drivers/include/ipc/workqueue.h +++ b/rt-thread/components/drivers/include/ipc/workqueue.h @@ -13,7 +13,6 @@ #include #include -#include "completion.h" #ifdef __cplusplus extern "C" { @@ -43,7 +42,6 @@ struct rt_workqueue struct rt_semaphore sem; rt_thread_t work_thread; struct rt_spinlock spinlock; - struct rt_completion wakeup_completion; }; struct rt_work @@ -54,7 +52,7 @@ struct rt_work void *work_data; rt_uint16_t flags; rt_uint16_t type; - rt_tick_t timeout_tick; + struct rt_timer timer; struct rt_workqueue *workqueue; }; diff --git a/rt-thread/components/drivers/include/rtdevice.h b/rt-thread/components/drivers/include/rtdevice.h index fd4d316..5b080fc 100644 --- a/rt-thread/components/drivers/include/rtdevice.h +++ b/rt-thread/components/drivers/include/rtdevice.h @@ -45,34 +45,6 @@ extern "C" { #include "drivers/core/power_domain.h" #include "drivers/platform.h" -#ifdef RT_USING_ATA -#ifdef RT_ATA_AHCI -#include "drivers/ahci.h" -#endif /* RT_ATA_AHCI */ -#endif /* RT_USING_ATA */ - -#ifdef RT_USING_LED -#include "drivers/led.h" -#endif - -#ifdef RT_USING_MBOX -#include "drivers/mailbox.h" -#endif /* RT_USING_MBOX */ - -#ifdef RT_USING_BLK -#include "drivers/blk.h" -#endif /* RT_USING_BLK */ - -#ifdef RT_USING_DMA -#include "drivers/dma.h" -#endif /* RT_USING_DMA */ - -#include "drivers/iio.h" - -#ifdef RT_USING_NVME -#include "drivers/nvme.h" -#endif /* RT_USING_NVME */ - #ifdef RT_USING_OFW #include "drivers/ofw.h" #include "drivers/ofw_fdt.h" @@ -81,54 +53,20 @@ extern "C" { #include "drivers/ofw_raw.h" #endif /* RT_USING_OFW */ -#ifdef RT_USING_PHYE -#include "drivers/phye.h" -#endif /* RT_USING_PHYE */ - #ifdef RT_USING_PIC #include "drivers/pic.h" -#endif /* RT_USING_PIC */ - -#ifdef RT_USING_PCI -#include "drivers/pci.h" -#ifdef RT_PCI_MSI -#include "drivers/pci_msi.h" -#endif /* RT_PCI_MSI */ -#ifdef RT_PCI_ENDPOINT -#include "drivers/pci_endpoint.h" -#endif /* RT_PCI_ENDPOINT */ -#endif /* RT_USING_PCI */ - -#ifdef RT_USING_REGULATOR -#include "drivers/regulator.h" -#endif /* RT_USING_REGULATOR */ - -#ifdef RT_USING_RESET -#include "drivers/reset.h" -#endif /* RT_USING_RESET */ - -#ifdef RT_USING_SCSI -#include "drivers/scsi.h" -#endif /* RT_USING_SCSI */ - -#ifdef RT_MFD_SYSCON -#include "drivers/syscon.h" -#endif /* RT_MFD_SYSCON */ - -#ifdef RT_USING_THERMAL -#include "drivers/thermal.h" -#endif /* RT_USING_THERMAL */ +#endif #endif /* RT_USING_DM */ #ifdef RT_USING_RTC -#include "drivers/dev_rtc.h" +#include "drivers/rtc.h" #ifdef RT_USING_ALARM -#include "drivers/dev_alarm.h" -#endif /* RT_USING_ALARM */ +#include "drivers/alarm.h" +#endif #endif /* RT_USING_RTC */ #ifdef RT_USING_SPI -#include "drivers/dev_spi.h" +#include "drivers/spi.h" #endif /* RT_USING_SPI */ #ifdef RT_USING_MTD_NOR @@ -149,44 +87,43 @@ extern "C" { #ifdef RT_USING_SERIAL #ifdef RT_USING_SERIAL_V2 -#include "drivers/dev_serial_v2.h" +#include "drivers/serial_v2.h" #else -#include "drivers/dev_serial.h" -#ifdef RT_USING_SERIAL_BYPASS -#include "drivers/serial_bypass.h" -#endif /* RT_USING_SERIAL_BYPASS */ +#include "drivers/serial.h" #endif #endif /* RT_USING_SERIAL */ #ifdef RT_USING_I2C -#include "drivers/dev_i2c.h" +#include "drivers/i2c.h" +#include "drivers/i2c_dev.h" #ifdef RT_USING_I2C_BITOPS -#include "drivers/dev_i2c_bit_ops.h" +#include "drivers/i2c-bit-ops.h" #endif /* RT_USING_I2C_BITOPS */ #ifdef RT_USING_DM -#include "drivers/dev_i2c_dm.h" +#include "drivers/i2c_dm.h" #endif /* RT_USING_DM */ #endif /* RT_USING_I2C */ #ifdef RT_USING_PHY #include "drivers/phy.h" +#include "drivers/phy_mdio.h" #endif /* RT_USING_PHY */ #ifdef RT_USING_SDIO -#include "drivers/dev_mmcsd_core.h" -#include "drivers/dev_sd.h" -#include "drivers/dev_sdio.h" +#include "drivers/mmcsd_core.h" +#include "drivers/sd.h" +#include "drivers/sdio.h" #endif /* RT_USING_SDIO */ #ifdef RT_USING_WDT -#include "drivers/dev_watchdog.h" +#include "drivers/watchdog.h" #endif /* RT_USING_WDT */ #ifdef RT_USING_PIN -#include "drivers/dev_pin.h" +#include "drivers/pin.h" #endif /* RT_USING_PIN */ #ifdef RT_USING_SENSOR @@ -198,7 +135,7 @@ extern "C" { #endif /* RT_USING_SENSOR */ #ifdef RT_USING_CAN -#include "drivers/dev_can.h" +#include "drivers/can.h" #endif /* RT_USING_CAN */ #ifdef RT_USING_HWTIMER @@ -206,7 +143,7 @@ extern "C" { #endif /* RT_USING_HWTIMER */ #ifdef RT_USING_AUDIO -#include "drivers/dev_audio.h" +#include "drivers/audio.h" #endif /* RT_USING_AUDIO */ #ifdef RT_USING_CPUTIME @@ -222,7 +159,7 @@ extern "C" { #endif /* RT_USING_DAC */ #ifdef RT_USING_PWM -#include "drivers/dev_pwm.h" +#include "drivers/rt_drv_pwm.h" #endif /* RT_USING_PWM */ #ifdef RT_USING_PM @@ -254,7 +191,7 @@ extern "C" { #endif /* RT_USING_INPUT_CAPTURE */ #ifdef RT_USING_TOUCH -#include "drivers/dev_touch.h" +#include "drivers/touch.h" #endif #ifdef RT_USING_DEV_BUS diff --git a/rt-thread/components/drivers/ipc/completion_comm.c b/rt-thread/components/drivers/ipc/completion_comm.c index 67c00b4..6828714 100644 --- a/rt-thread/components/drivers/ipc/completion_comm.c +++ b/rt-thread/components/drivers/ipc/completion_comm.c @@ -35,28 +35,6 @@ rt_err_t rt_completion_wakeup(struct rt_completion *completion) return rt_completion_wakeup_by_errno(completion, -1); } -/** - * @brief This is same as rt_completion_wait(), except that this API is NOT - * ISR-safe (you can NOT call completion_done() on isr routine). - * - * @param completion is a pointer to a completion object. - * - * @param timeout is a timeout period (unit: OS ticks). If the completion is unavailable, the thread will wait for - * the completion done up to the amount of time specified by the argument. - * NOTE: Generally, we use the macro RT_WAITING_FOREVER to set this parameter, which means that when the - * completion is unavailable, the thread will be waitting forever. - * - * @return Return the operation status. ONLY when the return value is RT_EOK, the operation is successful. - * If the return value is any other values, it means that the completion wait failed. - * - * @warning This function can ONLY be called in the thread context. It MUST NOT be called in interrupt context. - */ -rt_err_t rt_completion_wait_noisr(struct rt_completion *completion, - rt_int32_t timeout) -{ - return rt_completion_wait_flags_noisr(completion, timeout, RT_UNINTERRUPTIBLE); -} - /** * @brief This function will wait for a completion, if the completion is unavailable, the thread shall wait for * the completion up to a specified time. diff --git a/rt-thread/components/drivers/ipc/completion_mp.c b/rt-thread/components/drivers/ipc/completion_mp.c index 38ffc6f..21627e0 100644 --- a/rt-thread/components/drivers/ipc/completion_mp.c +++ b/rt-thread/components/drivers/ipc/completion_mp.c @@ -65,10 +65,11 @@ void rt_completion_init(struct rt_completion *completion) RTM_EXPORT(rt_completion_init); /** - * @brief This is same as rt_completion_wait_flags(), except that this API is NOT - * ISR-safe (you can NOT call completion_done() on isr routine). + * @brief This function will wait for a completion, if the completion is unavailable, the thread shall wait for + * the completion up to a specified time. * * @param completion is a pointer to a completion object. + * * @param timeout is a timeout period (unit: OS ticks). If the completion is unavailable, the thread will wait for * the completion done up to the amount of time specified by the argument. * NOTE: Generally, we use the macro RT_WAITING_FOREVER to set this parameter, which means that when the @@ -80,8 +81,8 @@ RTM_EXPORT(rt_completion_init); * * @warning This function can ONLY be called in the thread context. It MUST NOT be called in interrupt context. */ -rt_err_t rt_completion_wait_flags_noisr(struct rt_completion *completion, - rt_int32_t timeout, int suspend_flag) +rt_err_t rt_completion_wait_flags(struct rt_completion *completion, + rt_int32_t timeout, int suspend_flag) { rt_err_t result = -RT_ERROR; rt_thread_t thread; @@ -158,33 +159,6 @@ rt_err_t rt_completion_wait_flags_noisr(struct rt_completion *completion, return result; } -/** - * @brief This function will wait for a completion, if the completion is unavailable, the thread shall wait for - * the completion up to a specified time. - * - * @param completion is a pointer to a completion object. - * @param timeout is a timeout period (unit: OS ticks). If the completion is unavailable, the thread will wait for - * the completion done up to the amount of time specified by the argument. - * NOTE: Generally, we use the macro RT_WAITING_FOREVER to set this parameter, which means that when the - * completion is unavailable, the thread will be waitting forever. - * @param suspend_flag suspend flags. See rt_thread_suspend_with_flag() - * - * @return Return the operation status. ONLY when the return value is RT_EOK, the operation is successful. - * If the return value is any other values, it means that the completion wait failed. - * - * @warning This function can ONLY be called in the thread context. It MUST NOT be called in interrupt context. - */ -rt_err_t rt_completion_wait_flags(struct rt_completion *completion, - rt_int32_t timeout, int suspend_flag) -{ - rt_err_t error; - rt_ubase_t level; - level = rt_hw_local_irq_disable(); - error = rt_completion_wait_flags_noisr(completion, timeout, suspend_flag); - rt_hw_local_irq_enable(level); - return error; -} - static rt_base_t _wait_until_update(struct rt_completion *completion, rt_base_t expected) { rt_base_t current_value; diff --git a/rt-thread/components/drivers/ipc/completion_up.c b/rt-thread/components/drivers/ipc/completion_up.c index 8c3bbbf..5c8e546 100644 --- a/rt-thread/components/drivers/ipc/completion_up.c +++ b/rt-thread/components/drivers/ipc/completion_up.c @@ -148,28 +148,6 @@ __exit: return result; } -/** - * @brief This is same as rt_completion_wait_flags(), except that this API is NOT - * ISR-safe (you can NOT call completion_done() on isr routine). - * - * @param completion is a pointer to a completion object. - * @param timeout is a timeout period (unit: OS ticks). If the completion is unavailable, the thread will wait for - * the completion done up to the amount of time specified by the argument. - * NOTE: Generally, we use the macro RT_WAITING_FOREVER to set this parameter, which means that when the - * completion is unavailable, the thread will be waitting forever. - * @param suspend_flag suspend flags. See rt_thread_suspend_with_flag() - * - * @return Return the operation status. ONLY when the return value is RT_EOK, the operation is successful. - * If the return value is any other values, it means that the completion wait failed. - * - * @warning This function can ONLY be called in the thread context. It MUST NOT be called in interrupt context. - */ -rt_err_t rt_completion_wait_flags_noisr(struct rt_completion *completion, - rt_int32_t timeout, int suspend_flag) -{ - return rt_completion_wait_flags(completion, timeout, suspend_flag); -} - /** * @brief This function indicates a completion has done and wakeup the thread * and update its errno. No update is applied if it's a negative value. diff --git a/rt-thread/components/drivers/ipc/workqueue.c b/rt-thread/components/drivers/ipc/workqueue.c index 30b779e..fb3657b 100644 --- a/rt-thread/components/drivers/ipc/workqueue.c +++ b/rt-thread/components/drivers/ipc/workqueue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2022, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -10,7 +10,6 @@ * 2021-08-14 Jackistang add comments for function interface * 2022-01-16 Meco Man add rt_work_urgent() * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable - * 2024-12-21 yuqingli delete timer, using list */ #include @@ -18,6 +17,8 @@ #ifdef RT_USING_HEAP +static void _delayed_work_timeout_handler(void *parameter); + rt_inline rt_err_t _workqueue_work_completion(struct rt_workqueue *queue) { rt_err_t result; @@ -49,61 +50,38 @@ rt_inline rt_err_t _workqueue_work_completion(struct rt_workqueue *queue) static void _workqueue_thread_entry(void *parameter) { - rt_base_t level; - struct rt_work *work; + rt_base_t level; + struct rt_work *work; struct rt_workqueue *queue; - rt_tick_t current_tick; - rt_int32_t delay_tick; - void (*work_func)(struct rt_work *work, void *work_data); - void *work_data; - queue = (struct rt_workqueue *)parameter; + queue = (struct rt_workqueue *) parameter; RT_ASSERT(queue != RT_NULL); while (1) { level = rt_spin_lock_irqsave(&(queue->spinlock)); - - /* timer check */ - current_tick = rt_tick_get(); - delay_tick = RT_WAITING_FOREVER; - while (!rt_list_isempty(&(queue->delayed_list))) - { - work = rt_list_entry(queue->delayed_list.next, struct rt_work, list); - if ((current_tick - work->timeout_tick) < RT_TICK_MAX / 2) - { - rt_list_remove(&(work->list)); - rt_list_insert_after(queue->work_list.prev, &(work->list)); - work->flags &= ~RT_WORK_STATE_SUBMITTING; - work->flags |= RT_WORK_STATE_PENDING; - } - else - { - delay_tick = work->timeout_tick - current_tick; - break; - } - } - if (rt_list_isempty(&(queue->work_list))) { + /* no software timer exist, suspend self. */ + rt_thread_suspend_with_flag(rt_thread_self(), RT_UNINTERRUPTIBLE); + + /* release lock after suspend so we will not lost any wakeups */ rt_spin_unlock_irqrestore(&(queue->spinlock), level); - /* wait for work completion */ - rt_completion_wait(&(queue->wakeup_completion), delay_tick); + + rt_schedule(); continue; } /* we have work to do with. */ work = rt_list_entry(queue->work_list.next, struct rt_work, list); rt_list_remove(&(work->list)); - queue->work_current = work; - work->flags &= ~RT_WORK_STATE_PENDING; - work->workqueue = RT_NULL; - work_func = work->work_func; - work_data = work->work_data; + queue->work_current = work; + work->flags &= ~RT_WORK_STATE_PENDING; + work->workqueue = RT_NULL; rt_spin_unlock_irqrestore(&(queue->spinlock), level); /* do work */ - work_func(work, work_data); + work->work_func(work, work->work_data); /* clean current work */ queue->work_current = RT_NULL; @@ -115,52 +93,52 @@ static void _workqueue_thread_entry(void *parameter) static rt_err_t _workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *work, rt_tick_t ticks) { - rt_base_t level; - rt_err_t err = RT_EOK; - struct rt_work *work_tmp; - rt_list_t *list_tmp; + rt_base_t level; + rt_err_t err = RT_EOK; level = rt_spin_lock_irqsave(&(queue->spinlock)); + /* remove list */ rt_list_remove(&(work->list)); - work->flags = 0; + work->flags &= ~RT_WORK_STATE_PENDING; if (ticks == 0) { rt_list_insert_after(queue->work_list.prev, &(work->list)); - work->flags |= RT_WORK_STATE_PENDING; - work->workqueue = queue; + work->flags |= RT_WORK_STATE_PENDING; + work->workqueue = queue; - rt_completion_done(&(queue->wakeup_completion)); - err = RT_EOK; + /* whether the workqueue is doing work */ + if (queue->work_current == RT_NULL) + { + /* resume work thread, and do a re-schedule if succeed */ + rt_thread_resume(queue->work_thread); + } } else if (ticks < RT_TICK_MAX / 2) { - /* insert delay work list */ - work->flags |= RT_WORK_STATE_SUBMITTING; - work->workqueue = queue; - work->timeout_tick = rt_tick_get() + ticks; - - list_tmp = &(queue->delayed_list); - for (work_tmp = rt_list_entry(list_tmp->next, struct rt_work, list); - &work_tmp->list != list_tmp; - work_tmp = rt_list_entry(work_tmp->list.next, struct rt_work, list)) + /* Timer started */ + if (work->flags & RT_WORK_STATE_SUBMITTING) { - if ((work_tmp->timeout_tick - work->timeout_tick) < RT_TICK_MAX / 2) - { - list_tmp = &(work_tmp->list); - break; - } + rt_timer_control(&work->timer, RT_TIMER_CTRL_SET_TIME, &ticks); } - rt_list_insert_before(list_tmp, &(work->list)); + else + { + rt_timer_init(&(work->timer), "work", _delayed_work_timeout_handler, + work, ticks, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER); + work->flags |= RT_WORK_STATE_SUBMITTING; + } + work->workqueue = queue; + /* insert delay work list */ + rt_list_insert_after(queue->delayed_list.prev, &(work->list)); - rt_completion_done(&(queue->wakeup_completion)); - err = RT_EOK; + err = rt_timer_start(&(work->timer)); } else { - err = -RT_ERROR; + err = - RT_ERROR; } + rt_spin_unlock_irqrestore(&(queue->spinlock), level); return err; } @@ -168,17 +146,61 @@ static rt_err_t _workqueue_submit_work(struct rt_workqueue *queue, static rt_err_t _workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *work) { rt_base_t level; - rt_err_t err; + rt_err_t err; level = rt_spin_lock_irqsave(&(queue->spinlock)); rt_list_remove(&(work->list)); - work->flags = 0; - err = queue->work_current != work ? RT_EOK : -RT_EBUSY; + work->flags &= ~RT_WORK_STATE_PENDING; + /* Timer started */ + if (work->flags & RT_WORK_STATE_SUBMITTING) + { + if ((err = rt_timer_stop(&(work->timer))) != RT_EOK) + { + goto exit; + } + rt_timer_detach(&(work->timer)); + work->flags &= ~RT_WORK_STATE_SUBMITTING; + } + err = queue->work_current != work ? RT_EOK : -RT_EBUSY; work->workqueue = RT_NULL; +exit: rt_spin_unlock_irqrestore(&(queue->spinlock), level); return err; } +static void _delayed_work_timeout_handler(void *parameter) +{ + struct rt_work *work; + struct rt_workqueue *queue; + rt_base_t level; + + work = (struct rt_work *)parameter; + queue = work->workqueue; + + RT_ASSERT(work->flags & RT_WORK_STATE_SUBMITTING); + RT_ASSERT(queue != RT_NULL); + + level = rt_spin_lock_irqsave(&(queue->spinlock)); + rt_timer_detach(&(work->timer)); + work->flags &= ~RT_WORK_STATE_SUBMITTING; + /* remove delay list */ + rt_list_remove(&(work->list)); + /* insert work queue */ + if (queue->work_current != work) + { + rt_list_insert_after(queue->work_list.prev, &(work->list)); + work->flags |= RT_WORK_STATE_PENDING; + } + /* whether the workqueue is doing work */ + if (queue->work_current == RT_NULL) + { + /* resume work thread, and do a re-schedule if succeed */ + rt_thread_resume(queue->work_thread); + } + + rt_spin_unlock_irqrestore(&(queue->spinlock), level); +} + /** * @brief Initialize a work item, binding with a callback function. * @@ -199,8 +221,8 @@ void rt_work_init(struct rt_work *work, work->work_func = work_func; work->work_data = work_data; work->workqueue = RT_NULL; - work->flags = 0; - work->type = 0; + work->flags = 0; + work->type = 0; } /** @@ -226,7 +248,6 @@ struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_siz rt_list_init(&(queue->delayed_list)); queue->work_current = RT_NULL; rt_sem_init(&(queue->sem), "wqueue", 0, RT_IPC_FLAG_FIFO); - rt_completion_init(&(queue->wakeup_completion)); /* create the work thread */ queue->work_thread = rt_thread_create(name, _workqueue_thread_entry, queue, stack_size, priority, 10); @@ -271,6 +292,7 @@ rt_err_t rt_workqueue_destroy(struct rt_workqueue *queue) * @param work is a pointer to the work item object. * * @return RT_EOK Success. + * -RT_EBUSY This work item is executing. */ rt_err_t rt_workqueue_dowork(struct rt_workqueue *queue, struct rt_work *work) { @@ -292,6 +314,7 @@ rt_err_t rt_workqueue_dowork(struct rt_workqueue *queue, struct rt_work *work) * NOTE: The max timeout tick should be no more than (RT_TICK_MAX/2 - 1) * * @return RT_EOK Success. + * -RT_EBUSY This work item is executing. * -RT_ERROR The ticks parameter is invalid. */ rt_err_t rt_workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *work, rt_tick_t ticks) @@ -323,10 +346,14 @@ rt_err_t rt_workqueue_urgent_work(struct rt_workqueue *queue, struct rt_work *wo /* NOTE: the work MUST be initialized firstly */ rt_list_remove(&(work->list)); rt_list_insert_after(&queue->work_list, &(work->list)); + /* whether the workqueue is doing work */ + if (queue->work_current == RT_NULL) + { + /* resume work thread, and do a re-schedule if succeed */ + rt_thread_resume(queue->work_thread); + } - rt_completion_done(&(queue->wakeup_completion)); rt_spin_unlock_irqrestore(&(queue->spinlock), level); - return RT_EOK; } @@ -421,6 +448,7 @@ static struct rt_workqueue *sys_workq; /* system work queue */ * NOTE: The max timeout tick should be no more than (RT_TICK_MAX/2 - 1) * * @return RT_EOK Success. + * -RT_EBUSY This work item is executing. * -RT_ERROR The ticks parameter is invalid. */ rt_err_t rt_work_submit(struct rt_work *work, rt_tick_t ticks) diff --git a/rt-thread/components/drivers/led/Kconfig b/rt-thread/components/drivers/led/Kconfig deleted file mode 100644 index 462aa0b..0000000 --- a/rt-thread/components/drivers/led/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -menuconfig RT_USING_LED - bool "Using Light Emitting Diode (LED) device drivers" - depends on RT_USING_DM - default n - -config RT_LED_GPIO - bool "GPIO connected LEDs Support" - depends on RT_USING_LED - depends on RT_USING_PINCTRL - depends on RT_USING_OFW - default n - -if RT_USING_LED - osource "$(SOC_DM_LED_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/led/SConscript b/rt-thread/components/drivers/led/SConscript deleted file mode 100644 index 276ca0b..0000000 --- a/rt-thread/components/drivers/led/SConscript +++ /dev/null @@ -1,18 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_USING_DM', 'RT_USING_LED']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../include'] - -src = ['led.c'] - -if GetDepend(['RT_LED_GPIO']): - src += ['led-gpio.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/led/led-gpio.c b/rt-thread/components/drivers/led/led-gpio.c deleted file mode 100644 index 0b6bd68..0000000 --- a/rt-thread/components/drivers/led/led-gpio.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#include -#include - -#define DBG_TAG "led.gpio" -#define DBG_LVL DBG_INFO -#include - -struct gpio_led -{ - struct rt_led_device parent; - - rt_base_t pin; - rt_uint8_t active_val; -}; - -#define raw_to_gpio_led(raw) rt_container_of(raw, struct gpio_led, parent); - -static rt_err_t gpio_led_set_state(struct rt_led_device *led, enum rt_led_state state) -{ - rt_err_t err = RT_EOK; - struct gpio_led *gled = raw_to_gpio_led(led); - - rt_pin_mode(gled->pin, PIN_MODE_OUTPUT); - - switch (state) - { - case RT_LED_S_OFF: - rt_pin_write(gled->pin, !gled->active_val); - break; - - case RT_LED_S_ON: - rt_pin_write(gled->pin, gled->active_val); - break; - - case RT_LED_S_TOGGLE: - err = led->ops->get_state(led, &state); - - if (!err) - { - err = led->ops->set_state(led, state == RT_LED_S_OFF ? RT_LED_S_ON : RT_LED_S_OFF); - } - break; - - default: - return -RT_ENOSYS; - } - - return err; -} - -static rt_err_t gpio_led_get_state(struct rt_led_device *led, enum rt_led_state *out_state) -{ - struct gpio_led *gled = raw_to_gpio_led(led); - - switch (rt_pin_read(gled->pin)) - { - case PIN_LOW: - *out_state = RT_LED_S_OFF; - break; - - case PIN_HIGH: - *out_state = RT_LED_S_ON; - break; - - default: - return -RT_ERROR; - } - - return RT_EOK; -} - -const static struct rt_led_ops gpio_led_ops = -{ - .set_state = gpio_led_set_state, - .get_state = gpio_led_get_state, -}; - -static rt_err_t ofw_append_gpio_led(struct rt_ofw_node *np) -{ - rt_err_t err; - enum rt_led_state led_state = RT_LED_S_OFF; - const char *propname, *state, *trigger; - struct gpio_led *gled = rt_malloc(sizeof(*gled)); - - if (!gled) - { - return -RT_ENOMEM; - } - - gled->pin = rt_ofw_get_named_pin(np, RT_NULL, 0, RT_NULL, &gled->active_val); - - if (gled->pin < 0) - { - err = gled->pin; - - goto _fail; - } - - gled->parent.ops = &gpio_led_ops; - - if ((err = rt_hw_led_register(&gled->parent))) - { - goto _fail; - } - - if (!rt_ofw_prop_read_string(np, "default-state", &state)) - { - if (!rt_strcmp(state, "on")) - { - led_state = RT_LED_S_ON; - } - } - - if ((propname = rt_ofw_get_prop_fuzzy_name(np, "default-trigger$"))) - { - if (!rt_ofw_prop_read_string(np, propname, &trigger)) - { - if (!rt_strcmp(trigger, "heartbeat") || - !rt_strcmp(trigger, "timer")) - { - led_state = RT_LED_S_BLINK; - } - } - } - - rt_led_set_state(&gled->parent, led_state); - - rt_ofw_data(np) = &gled->parent; - - return RT_EOK; - -_fail: - rt_free(gled); - - return err; -} - -static rt_err_t gpio_led_probe(struct rt_platform_device *pdev) -{ - rt_bool_t pinctrl_apply = RT_FALSE; - struct rt_ofw_node *led_np, *np = pdev->parent.ofw_node; - - if (rt_ofw_prop_read_bool(np, "pinctrl-0")) - { - pinctrl_apply = RT_TRUE; - rt_pin_ctrl_confs_apply_by_name(&pdev->parent, RT_NULL); - } - - rt_ofw_foreach_available_child_node(np, led_np) - { - rt_err_t err = ofw_append_gpio_led(led_np); - - if (err == -RT_ENOMEM) - { - rt_ofw_node_put(led_np); - - return err; - } - else if (err) - { - LOG_E("%s: create LED fail", rt_ofw_node_full_name(led_np)); - continue; - } - - if (!pinctrl_apply) - { - struct rt_device dev_tmp; - - dev_tmp.ofw_node = led_np; - rt_pin_ctrl_confs_apply_by_name(&dev_tmp, RT_NULL); - } - } - - return RT_EOK; -} - -static rt_err_t gpio_led_remove(struct rt_platform_device *pdev) -{ - struct gpio_led *gled; - struct rt_led_device *led_dev; - struct rt_ofw_node *led_np, *np = pdev->parent.ofw_node; - - rt_ofw_foreach_available_child_node(np, led_np) - { - led_dev = rt_ofw_data(led_np); - - if (!led_dev) - { - continue; - } - - gled = rt_container_of(led_dev, struct gpio_led, parent); - - rt_ofw_data(led_np) = RT_NULL; - - rt_hw_led_unregister(&gled->parent); - - rt_free(gled); - } - - return RT_EOK; -} - -static const struct rt_ofw_node_id gpio_led_ofw_ids[] = -{ - { .compatible = "gpio-leds" }, - { /* sentinel */ } -}; - -static struct rt_platform_driver gpio_led_driver = -{ - .name = "led-gpio", - .ids = gpio_led_ofw_ids, - - .probe = gpio_led_probe, - .remove = gpio_led_remove, -}; -RT_PLATFORM_DRIVER_EXPORT(gpio_led_driver); diff --git a/rt-thread/components/drivers/led/led.c b/rt-thread/components/drivers/led/led.c deleted file mode 100644 index 611a16d..0000000 --- a/rt-thread/components/drivers/led/led.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#include - -#define DBG_TAG "rtdm.led" -#define DBG_LVL DBG_INFO -#include - -#include -#include - -struct blink_timer -{ - rt_bool_t toggle; - rt_bool_t enabled; - struct rt_timer timer; -}; - -static struct rt_dm_ida led_ida = RT_DM_IDA_INIT(LED); - -static const char * const _led_states[] = -{ - [RT_LED_S_OFF] = "off", - [RT_LED_S_ON] = "on", - [RT_LED_S_TOGGLE] = "toggle", - [RT_LED_S_BLINK] = "blink", -}; - -static rt_ssize_t _led_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - rt_ssize_t res; - rt_size_t state_len; - enum rt_led_state state; - struct rt_led_device *led = rt_container_of(dev, struct rt_led_device, parent); - - if ((res = rt_led_get_state(led, &state))) - { - return res; - } - - state_len = rt_strlen(_led_states[state]); - - if (pos < state_len) - { - size = rt_min_t(rt_size_t, size, size - pos); - ((char *)buffer)[size - 1] = '\0'; - rt_strncpy(buffer, &_led_states[state][pos], size); - - return size; - } - else - { - return 0; - } -} - -static rt_ssize_t _led_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - rt_uint32_t brightness = 0; - const char *value = buffer; - struct rt_led_device *led = rt_container_of(dev, struct rt_led_device, parent); - - for (int i = 0; i < RT_ARRAY_SIZE(_led_states); ++i) - { - if (!rt_strncpy((char *)_led_states[i], buffer, size)) - { - return rt_led_set_state(led, i) ? : size; - } - } - - while (*value) - { - if (*value < '0' || *value > '9') - { - return -RT_EINVAL; - } - - brightness *= 10; - brightness += *value - '0'; - - ++value; - } - - rt_led_set_brightness(led, brightness); - - return size; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops _led_ops = -{ - .read = _led_read, - .write = _led_write, -}; -#endif - -static void _led_blink_timerout(void *param) -{ - struct rt_led_device *led = param; - struct blink_timer *btimer = led->sysdata; - - if (btimer->toggle) - { - led->ops->set_state(led, RT_LED_S_OFF); - } - else - { - led->ops->set_state(led, RT_LED_S_ON); - } - - btimer->toggle = !btimer->toggle; -} - -rt_err_t rt_hw_led_register(struct rt_led_device *led) -{ - rt_err_t err; - int device_id; - const char *dev_name; - struct blink_timer *btimer = RT_NULL; - - if (!led || !led->ops) - { - return -RT_EINVAL; - } - - if ((device_id = rt_dm_ida_alloc(&led_ida)) < 0) - { - return -RT_EFULL; - } - - rt_dm_dev_set_name(&led->parent, "led%u", device_id); - dev_name = rt_dm_dev_get_name(&led->parent); - - led->sysdata = RT_NULL; - rt_spin_lock_init(&led->spinlock); - - if (!led->ops->set_period && led->ops->set_state) - { - btimer = rt_malloc(sizeof(*btimer)); - - if (!btimer) - { - LOG_E("%s create blink timer failed", dev_name); - - err = -RT_ENOMEM; - goto _fail; - } - - led->sysdata = btimer; - - btimer->toggle = RT_FALSE; - btimer->enabled = RT_FALSE; - rt_timer_init(&btimer->timer, dev_name, _led_blink_timerout, led, - rt_tick_from_millisecond(500), RT_TIMER_FLAG_PERIODIC); - } - - led->parent.type = RT_Device_Class_Char; -#ifdef RT_USING_DEVICE_OPS - led->parent.ops = &_led_ops; -#else - led->parent.read = _led_read; - led->parent.write = _led_write; -#endif - led->parent.master_id = led_ida.master_id; - led->parent.device_id = device_id; - - if ((err = rt_device_register(&led->parent, dev_name, RT_DEVICE_FLAG_RDWR))) - { - goto _fail; - } - - return RT_EOK; - -_fail: - rt_dm_ida_free(&led_ida, device_id); - - if (btimer) - { - rt_timer_detach(&btimer->timer); - rt_free(btimer); - - led->sysdata = RT_NULL; - } - - return err; -} - -rt_err_t rt_hw_led_unregister(struct rt_led_device *led) -{ - if (!led) - { - return -RT_EINVAL; - } - - rt_led_set_state(led, RT_LED_S_OFF); - - if (led->sysdata) - { - struct blink_timer *btimer = led->sysdata; - - rt_timer_detach(&btimer->timer); - - rt_free(btimer); - } - - rt_dm_ida_free(&led_ida, led->parent.device_id); - - rt_device_unregister(&led->parent); - - return RT_EOK; -} - -rt_err_t rt_led_set_state(struct rt_led_device *led, enum rt_led_state state) -{ - rt_err_t err; - struct blink_timer *btimer; - - if (!led) - { - return -RT_EINVAL; - } - - if (!led->ops->set_state) - { - return -RT_ENOSYS; - } - - rt_spin_lock(&led->spinlock); - - btimer = led->sysdata; - - if (btimer && btimer->enabled) - { - rt_timer_stop(&btimer->timer); - } - - err = led->ops->set_state(led, state); - - if (state == RT_LED_S_BLINK) - { - if (err == -RT_ENOSYS && btimer && !btimer->enabled) - { - btimer->enabled = RT_TRUE; - rt_timer_start(&btimer->timer); - } - } - else if (btimer && btimer->enabled) - { - if (err) - { - rt_timer_start(&btimer->timer); - } - else - { - btimer->enabled = RT_FALSE; - } - } - - rt_spin_unlock(&led->spinlock); - - return err; -} - -rt_err_t rt_led_get_state(struct rt_led_device *led, enum rt_led_state *out_state) -{ - rt_err_t err; - - if (!led || !out_state) - { - return -RT_EINVAL; - } - - if (!led->ops->get_state) - { - return -RT_ENOSYS; - } - - rt_spin_lock(&led->spinlock); - - err = led->ops->get_state(led, out_state); - - rt_spin_unlock(&led->spinlock); - - return err; -} - -rt_err_t rt_led_set_period(struct rt_led_device *led, rt_uint32_t period_ms) -{ - rt_err_t err; - - if (!led) - { - return -RT_EINVAL; - } - - if (!led->ops->set_period && !led->sysdata) - { - return -RT_ENOSYS; - } - - rt_spin_lock(&led->spinlock); - - if (led->ops->set_period) - { - err = led->ops->set_period(led, period_ms); - } - else - { - struct blink_timer *btimer = led->sysdata; - rt_tick_t tick = rt_tick_from_millisecond(period_ms); - - err = rt_timer_control(&btimer->timer, RT_TIMER_CTRL_SET_TIME, &tick); - } - - rt_spin_unlock(&led->spinlock); - - return err; -} - -rt_err_t rt_led_set_brightness(struct rt_led_device *led, rt_uint32_t brightness) -{ - rt_err_t err; - - if (!led) - { - return -RT_EINVAL; - } - - if (!led->ops->set_brightness) - { - return -RT_ENOSYS; - } - - rt_spin_lock(&led->spinlock); - - err = led->ops->set_brightness(led, brightness); - - rt_spin_unlock(&led->spinlock); - - return err; -} diff --git a/rt-thread/components/drivers/mailbox/Kconfig b/rt-thread/components/drivers/mailbox/Kconfig deleted file mode 100644 index 9531d3a..0000000 --- a/rt-thread/components/drivers/mailbox/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -menuconfig RT_USING_MBOX - bool "Using Hardware Mailbox device drivers" - depends on RT_USING_DM - depends on RT_USING_OFW - default n - -config RT_MBOX_PIC - bool "RT-Thread PIC Mailbox" - depends on RT_USING_MBOX - default y - -if RT_USING_MBOX - osource "$(SOC_DM_MBOX_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/mailbox/SConscript b/rt-thread/components/drivers/mailbox/SConscript deleted file mode 100644 index f26a44b..0000000 --- a/rt-thread/components/drivers/mailbox/SConscript +++ /dev/null @@ -1,18 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_USING_MBOX']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../include'] - -src = ['mailbox.c'] - -if GetDepend(['RT_MBOX_PIC']): - src += ['mailbox-pic.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/mailbox/mailbox-pic.c b/rt-thread/components/drivers/mailbox/mailbox-pic.c deleted file mode 100644 index dbc90f0..0000000 --- a/rt-thread/components/drivers/mailbox/mailbox-pic.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#include -#include - -#define DBG_TAG "mailbox.pic" -#define DBG_LVL DBG_INFO -#include - -/* - * RT-Thread PIC Mailbox device driver - * - * The mailbox device(s) may be instantiated in one of three equivalent way: - * - * Device Tree node, eg.: - * - * interrupt-controller@0 { - * interrupt-controller; - * #interrupt-cells = <1>; - * }; - * - * pic_mailbox@10000 { - * compatible = "rt-thread,pic-mailbox"; - * reg = <0x10000 0x100>; - * position = <0>; - * interrupts = <34>; - * peer-interrupts = <35>; - * uid = <0>; - * #mbox-cells = <1>; - * }; - */ - -#define MAILBOX_IMASK 0x00 -#define MAILBOX_ISTATE 0x04 -#define MAILBOX_MSG(n) (0x08 + (n) * 4) - -struct pic_mbox -{ - struct rt_mbox_controller parent; - - void *regs; - void *peer_regs; - - int position; - int chans_nr; - int irq; - int peer_hwirq; - struct rt_pic *pic; - - struct rt_spinlock lock; -}; - -#define raw_to_pic_mbox(raw) rt_container_of(raw, struct pic_mbox, parent) - -static rt_err_t pic_mbox_request(struct rt_mbox_chan *chan) -{ - int index = chan - chan->ctrl->chans; - struct pic_mbox *pic_mbox = raw_to_pic_mbox(chan->ctrl); - - HWREG32(pic_mbox->regs + MAILBOX_IMASK) &= ~RT_BIT(index); - HWREG32(pic_mbox->regs + MAILBOX_ISTATE) = 0; - - return RT_EOK; -} - -static void pic_mbox_release(struct rt_mbox_chan *chan) -{ - int index = chan - chan->ctrl->chans; - struct pic_mbox *pic_mbox = raw_to_pic_mbox(chan->ctrl); - - HWREG32(pic_mbox->regs + MAILBOX_IMASK) |= RT_BIT(index); -} - -static rt_err_t pic_mbox_send(struct rt_mbox_chan *chan, const void *data) -{ - rt_ubase_t level; - int index = chan - chan->ctrl->chans; - struct pic_mbox *pic_mbox = raw_to_pic_mbox(chan->ctrl); - - while (HWREG32(pic_mbox->peer_regs + MAILBOX_ISTATE) & RT_BIT(index)) - { - rt_thread_yield(); - } - - if (HWREG32(pic_mbox->peer_regs + MAILBOX_IMASK) & RT_BIT(index)) - { - return -RT_ERROR; - } - - level = rt_spin_lock_irqsave(&pic_mbox->lock); - - HWREG32(pic_mbox->regs + MAILBOX_MSG(index)) = *(rt_uint32_t *)data; - HWREG32(pic_mbox->peer_regs + MAILBOX_ISTATE) |= RT_BIT(index); - rt_hw_wmb(); - - rt_pic_irq_set_state_raw(pic_mbox->pic, pic_mbox->peer_hwirq, - RT_IRQ_STATE_PENDING, RT_TRUE); - - rt_spin_unlock_irqrestore(&pic_mbox->lock, level); - - return RT_EOK; -} - -static const struct rt_mbox_controller_ops pic_mbox_ops = -{ - .request = pic_mbox_request, - .release = pic_mbox_release, - .send = pic_mbox_send, -}; - -static void pic_mbox_isr(int irqno, void *param) -{ - rt_uint32_t isr; - struct pic_mbox *pic_mbox = param; - - isr = HWREG32(pic_mbox->regs + MAILBOX_ISTATE); - - for (int idx = 0; idx < 32; ++idx) - { - rt_uint32_t msg; - - if (!(RT_BIT(idx) & isr)) - { - continue; - } - - rt_hw_rmb(); - msg = HWREG32(pic_mbox->peer_regs + MAILBOX_MSG(idx)); - - rt_mbox_recv(&pic_mbox->parent.chans[idx], &msg); - } - - HWREG32(pic_mbox->regs + MAILBOX_ISTATE) &= ~isr; -} - -static void pic_mbox_free_resource(struct pic_mbox *pic_mbox) -{ - if (pic_mbox->regs && pic_mbox->peer_regs) - { - if (pic_mbox->peer_regs > pic_mbox->regs) - { - rt_iounmap(pic_mbox->regs); - } - else - { - rt_iounmap(pic_mbox->peer_regs); - } - } - - rt_free(pic_mbox); -} - -static rt_err_t pic_mbox_probe(struct rt_platform_device *pdev) -{ - rt_err_t err; - rt_uint64_t size; - rt_uint32_t value; - char dev_name[RT_NAME_MAX]; - struct rt_ofw_node *pic_np; - struct rt_device *dev = &pdev->parent; - struct pic_mbox *pic_mbox = rt_calloc(1, sizeof(*pic_mbox)); - - if (!pic_mbox) - { - return -RT_ENOMEM; - } - - if ((err = rt_dm_dev_get_address(dev, 0, RT_NULL, &size))) - { - goto _fail; - } - - if ((err = rt_dm_dev_prop_read_u32(dev, "position", &value))) - { - goto _fail; - } - - if (!value) - { - pic_mbox->regs = rt_dm_dev_iomap(dev, 0); - - if (!pic_mbox->regs) - { - goto _fail; - } - - pic_mbox->peer_regs = pic_mbox->regs + size / 2; - - /* Init by the captain */ - HWREG32(pic_mbox->regs + MAILBOX_IMASK) = 0xffffffff; - HWREG32(pic_mbox->regs + MAILBOX_ISTATE) = 0; - HWREG32(pic_mbox->peer_regs + MAILBOX_IMASK) = 0xffffffff; - HWREG32(pic_mbox->peer_regs + MAILBOX_ISTATE) = 0; - } - else - { - pic_mbox->peer_regs = rt_dm_dev_iomap(dev, 0); - - if (!pic_mbox->peer_regs) - { - goto _fail; - } - - pic_mbox->regs = pic_mbox->peer_regs + size / 2; - } - - pic_mbox->irq = rt_dm_dev_get_irq(dev, 0); - - if (pic_mbox->irq < 0) - { - err = pic_mbox->irq; - - goto _fail; - } - - if ((err = rt_dm_dev_prop_read_u32(dev, "peer-interrupts", &value))) - { - goto _fail; - } - pic_mbox->peer_hwirq = value; - - if ((err = rt_dm_dev_prop_read_u32(dev, "uid", &value))) - { - goto _fail; - } - - if (!(pic_np = rt_ofw_find_irq_parent(dev->ofw_node, RT_NULL))) - { - goto _fail; - } - pic_mbox->pic = rt_ofw_data(pic_np); - rt_ofw_node_put(pic_np); - - rt_spin_lock_init(&pic_mbox->lock); - - pic_mbox->parent.dev = dev; - pic_mbox->parent.num_chans = 32; - pic_mbox->parent.ops = &pic_mbox_ops; - - if ((err = rt_mbox_controller_register(&pic_mbox->parent))) - { - goto _fail; - } - - rt_snprintf(dev_name, sizeof(dev_name), "pic-mbox%d", value); - rt_hw_interrupt_install(pic_mbox->irq, pic_mbox_isr, pic_mbox, dev_name); - rt_hw_interrupt_umask(pic_mbox->irq); - - return RT_EOK; - -_fail: - pic_mbox_free_resource(pic_mbox); - - return err; -} - -static rt_err_t pic_mbox_remove(struct rt_platform_device *pdev) -{ - struct pic_mbox *pic_mbox = pdev->parent.user_data; - - rt_pic_detach_irq(pic_mbox->irq, pic_mbox); - - rt_mbox_controller_unregister(&pic_mbox->parent); - - pic_mbox_free_resource(pic_mbox); - - return RT_EOK; -} - -static const struct rt_ofw_node_id pic_mbox_ofw_ids[] = -{ - { .compatible = "rt-thread,pic-mailbox" }, - { /* sentinel */ } -}; - -static struct rt_platform_driver pic_mbox_driver = -{ - .name = "mailbox-pic", - .ids = pic_mbox_ofw_ids, - - .probe = pic_mbox_probe, - .remove = pic_mbox_remove, -}; -RT_PLATFORM_DRIVER_EXPORT(pic_mbox_driver); diff --git a/rt-thread/components/drivers/mailbox/mailbox.c b/rt-thread/components/drivers/mailbox/mailbox.c deleted file mode 100644 index 5e94241..0000000 --- a/rt-thread/components/drivers/mailbox/mailbox.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#include -#include - -#define DBG_TAG "rtdm.mailbox" -#define DBG_LVL DBG_INFO -#include - -#include -#include -#include -#include - -static struct rt_spinlock mbox_ops_lock = {}; -static rt_list_t mbox_nodes = RT_LIST_OBJECT_INIT(mbox_nodes); - -static void mbox_chan_timeout(void *param); - -rt_err_t rt_mbox_controller_register(struct rt_mbox_controller *ctrl) -{ - int len; - struct rt_mbox_chan *chan; - char timer_name[RT_NAME_MAX]; - - if (!ctrl || !ctrl->dev || !ctrl->ops || !ctrl->num_chans) - { - return -RT_EINVAL; - } - - ctrl->chans = rt_calloc(ctrl->num_chans, sizeof(struct rt_mbox_chan)); - - if (!ctrl->chans) - { - return -RT_ENOMEM; - } - - len = rt_snprintf(timer_name, sizeof(timer_name), "%s-", - rt_dm_dev_get_name(ctrl->dev)); - - RT_ASSERT(len < sizeof(timer_name)); - - chan = &ctrl->chans[0]; - - for (int i = 0; i < ctrl->num_chans; ++i, ++chan) - { - chan->ctrl = ctrl; - rt_spin_lock_init(&chan->lock); - - rt_snprintf(&timer_name[len], sizeof(timer_name) - len, "%d", i); - rt_timer_init(&chan->timer, timer_name, mbox_chan_timeout, chan, - 0, RT_TIMER_FLAG_ONE_SHOT); - } - - rt_list_init(&ctrl->list); - rt_dm_dev_bind_fwdata(ctrl->dev, RT_NULL, ctrl); - - rt_spin_lock(&mbox_ops_lock); - - rt_list_insert_after(&mbox_nodes, &ctrl->list); - - rt_spin_unlock(&mbox_ops_lock); - - return RT_EOK; -} - -rt_err_t rt_mbox_controller_unregister(struct rt_mbox_controller *ctrl) -{ - struct rt_mbox_chan *chan; - - if (!ctrl) - { - return -RT_EINVAL; - } - - rt_spin_lock(&mbox_ops_lock); - - rt_dm_dev_unbind_fwdata(ctrl->dev, RT_NULL); - rt_list_remove(&ctrl->list); - - rt_spin_unlock(&mbox_ops_lock); - - chan = &ctrl->chans[0]; - - for (int i = ctrl->num_chans - 1; i >= 0; --i, ++chan) - { - rt_mbox_release(&ctrl->chans[i]); - } - - rt_free(ctrl->chans); - - return RT_EOK; -} - -rt_err_t rt_mbox_send(struct rt_mbox_chan *chan, const void *data, - rt_uint32_t timeout_ms) -{ - rt_err_t err; - rt_ubase_t level; - rt_bool_t timer_go = RT_FALSE; - struct rt_mbox_client *client; - struct rt_mbox_controller *ctrl; - - if (!chan || !data) - { - return -RT_EINVAL; - } - - ctrl = chan->ctrl; - client = chan->client; - - level = rt_spin_lock_irqsave(&chan->lock); - - if (client->tx_prepare) - { - client->tx_prepare(client, data); - } - - chan->complete = RT_FALSE; - err = ctrl->ops->send(chan, data); - - if (!err) - { - chan->data = (void *)data; - - if (timeout_ms != RT_WAITING_FOREVER) - { - rt_tick_t tick = rt_tick_from_millisecond(timeout_ms); - - rt_timer_control(&chan->timer, RT_TIMER_CTRL_SET_TIME, &tick); - - timer_go = RT_TRUE; - } - } - else - { - chan->complete = RT_TRUE; - } - - rt_spin_unlock_irqrestore(&chan->lock, level); - - if (timer_go) - { - rt_timer_start(&chan->timer); - } - - return err; -} - -void rt_mbox_send_done(struct rt_mbox_chan *chan, rt_err_t err) -{ - void *data; - rt_ubase_t level; - - level = rt_spin_lock_irqsave(&chan->lock); - - data = chan->data; - chan->data = RT_NULL; - - rt_spin_unlock_irqrestore(&chan->lock, level); - - if (chan->client->tx_done) - { - chan->client->tx_done(chan->client, data, err); - } - - chan->complete = RT_TRUE; -} - -static void mbox_chan_timeout(void *param) -{ - rt_err_t err = RT_EOK; - struct rt_mbox_chan *chan = param; - - if (!chan->complete) - { - err = -RT_ETIMEOUT; - } - - rt_mbox_send_done(chan, err); -} - -rt_bool_t rt_mbox_peek(struct rt_mbox_chan *chan) -{ - if (chan && chan->ctrl->ops->peek) - { - return chan->ctrl->ops->peek(chan); - } - - return RT_FALSE; -} - -rt_err_t rt_mbox_recv(struct rt_mbox_chan *chan, void *data) -{ - if (!chan || !data) - { - return -RT_EINVAL; - } - - if (chan->client->rx_callback) - { - chan->client->rx_callback(chan->client, data); - } - - return RT_EOK; -} - -static int mbox_controller_ofw_parse_default(struct rt_mbox_controller *ctrl, - struct rt_ofw_cell_args *args) -{ - if (args->args_count != 1) - { - return -RT_EINVAL; - } - - return args->args[0]; -} - -struct rt_mbox_chan *rt_mbox_request_by_index(struct rt_mbox_client *client, int index) -{ - rt_err_t err; - struct rt_ofw_cell_args args; - struct rt_ofw_node *np, *ctrl_np; - struct rt_mbox_controller *ctrl; - struct rt_mbox_chan *chan = RT_NULL; - - if (!client && index < 0) - { - return rt_err_ptr(-RT_EINVAL); - } - - np = client->dev->ofw_node; - - rt_spin_lock(&mbox_ops_lock); - - err = rt_ofw_parse_phandle_cells(np, "mboxes", "#mbox-cells", index, &args); - - if (err) - { - chan = rt_err_ptr(err); - goto _out_lock; - } - - ctrl_np = args.data; - - if (!rt_ofw_data(ctrl_np)) - { - rt_spin_unlock(&mbox_ops_lock); - - rt_platform_ofw_request(ctrl_np); - - rt_spin_lock(&mbox_ops_lock); - } - - ctrl = rt_ofw_data(ctrl_np); - rt_ofw_node_put(ctrl_np); - - if (ctrl) - { - int index; - - if (ctrl->ops->ofw_parse) - { - index = ctrl->ops->ofw_parse(ctrl, &args); - } - else - { - index = mbox_controller_ofw_parse_default(ctrl, &args); - } - - if (index >= 0) - { - chan = &ctrl->chans[index]; - } - else - { - LOG_E("Parse chan from %s error = %s", - rt_dm_dev_get_name(ctrl->dev), rt_strerror(index)); - - chan = rt_err_ptr(index); - goto _out_lock; - } - - if (ctrl->ops->request) - { - rt_err_t err = ctrl->ops->request(chan); - - if (err) - { - LOG_E("Request chan[%d] from %s error = %s", - index, rt_dm_dev_get_name(ctrl->dev), rt_strerror(err)); - - rt_mbox_release(chan); - chan = rt_err_ptr(err); - } - } - - chan->client = client; - } - else - { - chan = rt_err_ptr(-RT_ENOSYS); - } - -_out_lock: - rt_spin_unlock(&mbox_ops_lock); - - return chan; -} - -struct rt_mbox_chan *rt_mbox_request_by_name(struct rt_mbox_client *client, char *name) -{ - int index; - struct rt_ofw_node *np; - - if (!client || !name) - { - return rt_err_ptr(-RT_EINVAL); - } - - np = client->dev->ofw_node; - index = rt_ofw_prop_index_of_string(np, "mbox-names", name); - - if (index < 0) - { - return RT_NULL; - } - - return rt_mbox_request_by_index(client, index); -} - -rt_err_t rt_mbox_release(struct rt_mbox_chan *chan) -{ - if (chan) - { - chan->ctrl->ops->release(chan); - } - else - { - return -RT_EINVAL; - } - - return RT_EOK; -} diff --git a/rt-thread/components/drivers/mfd/Kconfig b/rt-thread/components/drivers/mfd/Kconfig deleted file mode 100644 index 0b12ca4..0000000 --- a/rt-thread/components/drivers/mfd/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -menuconfig RT_USING_MFD - bool "Using Multifunction device drivers" - depends on RT_USING_DM - default n - -config RT_MFD_SYSCON - bool "System Controller Register R/W" - depends on RT_USING_MFD - depends on RT_USING_OFW - default y diff --git a/rt-thread/components/drivers/mfd/SConscript b/rt-thread/components/drivers/mfd/SConscript deleted file mode 100644 index f952f68..0000000 --- a/rt-thread/components/drivers/mfd/SConscript +++ /dev/null @@ -1,17 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_USING_MFD']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../include'] -src = [] - -if GetDepend(['RT_MFD_SYSCON']): - src += ['mfd-syscon.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/mfd/mfd-syscon.c b/rt-thread/components/drivers/mfd/mfd-syscon.c deleted file mode 100644 index 1778906..0000000 --- a/rt-thread/components/drivers/mfd/mfd-syscon.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#include -#include - -#include -#include -#include -#include -#include - -static struct rt_spinlock _syscon_nodes_lock = { 0 }; -static rt_list_t _syscon_nodes = RT_LIST_OBJECT_INIT(_syscon_nodes); - -rt_err_t rt_syscon_read(struct rt_syscon *syscon, rt_off_t offset, rt_uint32_t *out_val) -{ - if (offset < syscon->iomem_size) - { - rt_ubase_t level = rt_spin_lock_irqsave(&syscon->rw_lock); - - *out_val = HWREG32(syscon->iomem_base + offset); - - rt_spin_unlock_irqrestore(&syscon->rw_lock, level); - - return RT_EOK; - } - else - { - return -RT_EINVAL; - } -} - -rt_err_t rt_syscon_write(struct rt_syscon *syscon, rt_off_t offset, rt_uint32_t val) -{ - if (offset < syscon->iomem_size) - { - rt_ubase_t level = rt_spin_lock_irqsave(&syscon->rw_lock); - - HWREG32(syscon->iomem_base + offset) = val; - - rt_spin_unlock_irqrestore(&syscon->rw_lock, level); - - return RT_EOK; - } - else - { - return -RT_EINVAL; - } -} - -rt_err_t rt_syscon_update_bits(struct rt_syscon *syscon, rt_off_t offset, rt_uint32_t mask, rt_uint32_t val) -{ - rt_err_t err; - rt_ubase_t level = rt_spin_lock_irqsave(&syscon->rw_lock); - - if (offset < syscon->iomem_size) - { - rt_uint32_t old_val = HWREG32(syscon->iomem_base + offset); - - old_val &= ~mask; - - HWREG32(syscon->iomem_base + offset) = old_val | val; - - err = RT_EOK; - } - else - { - err = -RT_EINVAL; - } - - rt_spin_unlock_irqrestore(&syscon->rw_lock, level); - - return err; -} - -static rt_err_t syscon_probe(struct rt_platform_device *pdev); - -struct rt_syscon *rt_syscon_find_by_ofw_node(struct rt_ofw_node *np) -{ - rt_ubase_t level; - struct rt_syscon *syscon = RT_NULL, *syscon_tmp; - struct rt_platform_device syscon_pdev; - - if (!np) - { - goto _exit; - } - - level = rt_spin_lock_irqsave(&_syscon_nodes_lock); - - /* ofw_data is not safety */ - rt_list_for_each_entry(syscon_tmp, &_syscon_nodes, list) - { - if (syscon_tmp->np == np) - { - syscon = syscon_tmp; - break; - } - } - - rt_spin_unlock_irqrestore(&_syscon_nodes_lock, level); - - if (syscon) - { - goto _exit; - } - - /* Not found, try probe this node */ - if (!rt_ofw_node_is_compatible(np, "syscon") && - !rt_ofw_node_is_compatible(np, "simple-mfd")) - { - goto _exit; - } - - syscon_pdev.parent.ofw_node = np; - - if (!syscon_probe(&syscon_pdev)) - { - syscon = rt_ofw_data(np); - } - -_exit: - return syscon; -} - -struct rt_syscon *rt_syscon_find_by_ofw_compatible(const char *compatible) -{ - struct rt_syscon *syscon = RT_NULL; - struct rt_ofw_node *syscon_np = rt_ofw_find_node_by_compatible(RT_NULL, compatible); - - if (syscon_np) - { - syscon = rt_syscon_find_by_ofw_node(syscon_np); - - rt_ofw_node_put(syscon_np); - } - - return syscon; -} - -struct rt_syscon *rt_syscon_find_by_ofw_phandle(struct rt_ofw_node *np, const char *propname) -{ - struct rt_syscon *syscon = RT_NULL; - struct rt_ofw_node *syscon_np = rt_ofw_parse_phandle(np, propname, 0); - - if (syscon_np) - { - syscon = rt_syscon_find_by_ofw_node(syscon_np); - - rt_ofw_node_put(syscon_np); - } - - return syscon; -} - -static rt_err_t syscon_probe(struct rt_platform_device *pdev) -{ - rt_err_t err; - rt_ubase_t level; - struct rt_ofw_node *np; - rt_uint64_t iomem_range[2]; - struct rt_syscon *syscon = rt_calloc(1, sizeof(*syscon)); - - if (!syscon) - { - return -RT_ENOMEM; - } - - np = pdev->parent.ofw_node; - - if ((err = rt_ofw_get_address(np, 0, &iomem_range[0], &iomem_range[1]))) - { - goto _fail; - } - - syscon->iomem_size = (rt_size_t)iomem_range[1]; - syscon->iomem_base = rt_ioremap((void *)iomem_range[0], syscon->iomem_size); - - if (!syscon->iomem_base) - { - goto _fail; - } - - rt_list_init(&syscon->list); - level = rt_spin_lock_irqsave(&_syscon_nodes_lock); - rt_list_insert_after(&_syscon_nodes, &syscon->list); - rt_spin_unlock_irqrestore(&_syscon_nodes_lock, level); - - rt_spin_lock_init(&syscon->rw_lock); - - pdev->parent.user_data = syscon; - - syscon->np = pdev->parent.ofw_node; - rt_ofw_data(np) = syscon; - - return RT_EOK; - -_fail: - rt_free(syscon); - - return err; -} - -static rt_err_t syscon_remove(struct rt_platform_device *pdev) -{ - struct rt_syscon *syscon = pdev->parent.user_data; - - rt_iounmap(syscon->iomem_base); - - rt_free(syscon); - - return RT_EOK; -} - -static const struct rt_ofw_node_id syscon_ofw_ids[] = -{ - { .compatible = "syscon" }, - { /* sentinel */ } -}; - -static struct rt_platform_driver syscon_driver = -{ - .name = "mfd-syscon", - .ids = syscon_ofw_ids, - - .probe = syscon_probe, - .remove = syscon_remove, -}; - -static int syscon_drv_register(void) -{ - rt_platform_driver_register(&syscon_driver); - - return 0; -} -INIT_SUBSYS_EXPORT(syscon_drv_register); diff --git a/rt-thread/components/drivers/misc/rt_random.c b/rt-thread/components/drivers/misc/rt_random.c index 9f4be20..da6b312 100644 --- a/rt-thread/components/drivers/misc/rt_random.c +++ b/rt-thread/components/drivers/misc/rt_random.c @@ -46,7 +46,7 @@ static rt_ssize_t random_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_si static rt_ssize_t random_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) { - ssize_t ret = sizeof(seed) < size ? sizeof(seed) : size; + ssize_t ret = sizeof(seed); rt_memcpy(&seed, buffer, ret); return ret; } @@ -137,7 +137,7 @@ static rt_ssize_t random_uread(rt_device_t dev, rt_off_t pos, void *buffer, rt_s static rt_ssize_t random_uwrite(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) { - ssize_t ret = sizeof(useed) < size ? sizeof(useed) : size; + ssize_t ret = sizeof(useed); rt_memcpy(&useed, buffer, ret); return ret; } diff --git a/rt-thread/components/drivers/nvme/Kconfig b/rt-thread/components/drivers/nvme/Kconfig deleted file mode 100644 index 83c731c..0000000 --- a/rt-thread/components/drivers/nvme/Kconfig +++ /dev/null @@ -1,23 +0,0 @@ -menuconfig RT_USING_NVME - bool "Using Non-Volatile Memory Express (NVME) device drivers" - depends on RT_USING_DM - depends on RT_USING_BLK - depends on RT_USING_DMA - default n - -config RT_USING_NVME_IO_QUEUE - int "Number of I/O Command queue" - depends on RT_USING_NVME - default 2 if RT_THREAD_PRIORITY_8 - default 4 if RT_THREAD_PRIORITY_32 - default 8 if RT_THREAD_PRIORITY_256 - -config RT_NVME_PCI - bool "NVME support on PCI bus" - depends on RT_USING_NVME - depends on RT_USING_PCI - default y - -if RT_USING_NVME - osource "$(SOC_DM_NVME_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/nvme/SConscript b/rt-thread/components/drivers/nvme/SConscript deleted file mode 100644 index 6fc699b..0000000 --- a/rt-thread/components/drivers/nvme/SConscript +++ /dev/null @@ -1,18 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_USING_NVME']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../include'] - -src = ['nvme.c'] - -if GetDepend(['RT_NVME_PCI']): - src += ['nvme-pci.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/nvme/nvme-pci.c b/rt-thread/components/drivers/nvme/nvme-pci.c deleted file mode 100644 index d73260f..0000000 --- a/rt-thread/components/drivers/nvme/nvme-pci.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#include -#include - -#define NVME_REG_BAR 0 - -struct pci_nvme_quirk -{ - const struct rt_nvme_ops *ops; -}; - -struct pci_nvme_controller -{ - struct rt_nvme_controller parent; - const struct pci_nvme_quirk *quirk; - - rt_bool_t is_msi; - struct rt_pci_msix_entry msix_entries[RT_USING_NVME_QUEUE]; -}; - -static const struct rt_nvme_ops pci_nvme_std_ops = -{ - .name = "PCI", -}; - -static rt_err_t pci_nvme_probe(struct rt_pci_device *pdev) -{ - rt_err_t err; - rt_ssize_t msi_nr; - struct rt_nvme_controller *nvme; - struct pci_nvme_controller *pci_nvme = rt_calloc(1, sizeof(*pci_nvme)); - const struct pci_nvme_quirk *quirk = pdev->id->data; - - if (!pci_nvme) - { - return -RT_ENOMEM; - } - - pci_nvme->quirk = quirk; - nvme = &pci_nvme->parent; - nvme->dev = &pdev->parent; - nvme->regs = rt_pci_iomap(pdev, NVME_REG_BAR); - - if (!nvme->regs) - { - err = -RT_EIO; - goto _fail; - } - - nvme->ops = quirk && quirk->ops ? quirk->ops : &pci_nvme_std_ops; - - if ((msi_nr = rt_pci_msix_vector_count(pdev)) <= 0) - { - msi_nr = rt_pci_msi_vector_count(pdev); - } - if (msi_nr > 0) - { - nvme->irqs_nr = RT_ARRAY_SIZE(pci_nvme->msix_entries); - nvme->irqs_nr = rt_min_t(rt_size_t, msi_nr, nvme->irqs_nr); - } - - if (nvme->irqs_nr > 0) - { - rt_pci_msix_entry_index_linear(pci_nvme->msix_entries, nvme->irqs_nr); - - if (rt_pci_msix_enable(pdev, pci_nvme->msix_entries, nvme->irqs_nr) > 0) - { - pci_nvme->is_msi = RT_TRUE; - - for (int i = 0; i < nvme->irqs_nr; ++i) - { - nvme->irqs[i] = pci_nvme->msix_entries[i].irq; - } - } - } - - if (!pci_nvme->is_msi) - { - nvme->irqs_nr = 1; - nvme->irqs[0] = pdev->irq; - rt_pci_irq_unmask(pdev); - } - - rt_pci_set_master(pdev); - - if ((err = rt_nvme_controller_register(nvme))) - { - goto _disable; - } - - pdev->parent.user_data = pci_nvme; - - return RT_EOK; - -_disable: - if (pci_nvme->is_msi) - { - rt_pci_msix_disable(pdev); - } - else - { - rt_pci_irq_mask(pdev); - } - rt_pci_clear_master(pdev); - rt_iounmap(nvme->regs); - -_fail: - rt_free(pci_nvme); - - return err; -} - -static rt_err_t pci_nvme_remove(struct rt_pci_device *pdev) -{ - struct rt_nvme_controller *nvme; - struct pci_nvme_controller *pci_nvme = pdev->parent.user_data; - - nvme = &pci_nvme->parent; - - rt_nvme_controller_unregister(nvme); - - if (pci_nvme->is_msi) - { - rt_pci_msix_disable(pdev); - } - else - { - /* INTx is shared, don't mask all */ - rt_hw_interrupt_umask(pdev->irq); - rt_pci_irq_mask(pdev); - } - - rt_pci_clear_master(pdev); - - rt_iounmap(nvme->regs); - rt_free(pci_nvme); - - return RT_EOK; -} - -static rt_err_t pci_nvme_shutdown(struct rt_pci_device *pdev) -{ - return pci_nvme_remove(pdev); -} - -static const struct rt_pci_device_id pci_nvme_ids[] = -{ - { RT_PCI_DEVICE_ID(PCI_VENDOR_ID_REDHAT, 0x0010) }, - { RT_PCI_DEVICE_CLASS(PCIS_STORAGE_EXPRESS, ~0) }, - { /* sentinel */ } -}; - -static struct rt_pci_driver pci_nvme_driver = -{ - .name = "nvme-pci", - - .ids = pci_nvme_ids, - .probe = pci_nvme_probe, - .remove = pci_nvme_remove, - .shutdown = pci_nvme_shutdown, -}; -RT_PCI_DRIVER_EXPORT(pci_nvme_driver); diff --git a/rt-thread/components/drivers/nvme/nvme.c b/rt-thread/components/drivers/nvme/nvme.c deleted file mode 100644 index dc00714..0000000 --- a/rt-thread/components/drivers/nvme/nvme.c +++ /dev/null @@ -1,1302 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#include -#include -#include - -#define DBG_TAG "rtdm.nvme" -#define DBG_LVL DBG_INFO -#include - -static struct rt_dm_ida nvme_controller_ida = RT_DM_IDA_INIT(CUSTOM); -static struct rt_dm_ida nvme_ida = RT_DM_IDA_INIT(NVME); - -static struct rt_spinlock nvme_lock = {}; -static rt_list_t nvme_nodes = RT_LIST_OBJECT_INIT(nvme_nodes); - -rt_inline rt_uint32_t nvme_readl(struct rt_nvme_controller *nvme, int offset) -{ - return HWREG32(nvme->regs + offset); -} - -rt_inline void nvme_writel(struct rt_nvme_controller *nvme, int offset, rt_uint32_t value) -{ - HWREG32(nvme->regs + offset) = value; -} - -rt_inline rt_uint64_t nvme_readq(struct rt_nvme_controller *nvme, int offset) -{ - rt_uint32_t lo32, hi32; - - lo32 = HWREG32(nvme->regs + offset); - hi32 = HWREG32(nvme->regs + offset + 4); - - return ((rt_uint64_t)hi32 << 32) + lo32; -} - -rt_inline void nvme_writeq(struct rt_nvme_controller *nvme, int offset, rt_uint64_t value) -{ - nvme_writel(nvme, offset, (rt_uint32_t)(value & 0xffffffff)); - nvme_writel(nvme, offset + 4, (rt_uint32_t)(value >> 32)); -} - -static rt_err_t nvme_poll_csts(struct rt_nvme_controller *nvme, - rt_uint32_t mask, rt_uint32_t value) -{ - rt_tick_t timeout; - - timeout = rt_tick_from_millisecond(RT_NVME_CAP_TIMEOUT(nvme->cap) * 500); - timeout += rt_tick_get(); - - do { - if ((nvme_readl(nvme, RT_NVME_REG_CSTS) & mask) == value) - { - return RT_EOK; - } - - rt_hw_cpu_relax(); - } while (rt_tick_get() < timeout); - - return -RT_ETIMEOUT; -} - -static rt_err_t nvme_enable_ctrl(struct rt_nvme_controller *nvme) -{ - nvme->ctrl_config &= ~RT_NVME_CC_SHN_MASK; - nvme->ctrl_config |= RT_NVME_CC_ENABLE; - nvme_writel(nvme, RT_NVME_REG_CC, nvme->ctrl_config); - - return nvme_poll_csts(nvme, RT_NVME_CSTS_RDY, RT_NVME_CSTS_RDY); -} - -static rt_err_t nvme_disable_ctrl(struct rt_nvme_controller *nvme) -{ - nvme->ctrl_config &= ~RT_NVME_CC_SHN_MASK; - nvme->ctrl_config &= ~RT_NVME_CC_ENABLE; - nvme_writel(nvme, RT_NVME_REG_CC, nvme->ctrl_config); - - return nvme_poll_csts(nvme, RT_NVME_CSTS_RDY, 0); -} - -static rt_err_t nvme_shutdown_ctrl(struct rt_nvme_controller *nvme) -{ - nvme->ctrl_config &= ~RT_NVME_CC_SHN_MASK; - nvme->ctrl_config |= RT_NVME_CC_SHN_NORMAL; - nvme_writel(nvme, RT_NVME_REG_CC, nvme->ctrl_config); - - return nvme_poll_csts(nvme, RT_NVME_CSTS_SHST_MASK, RT_NVME_CSTS_SHST_CMPLT); -} - -rt_inline rt_le16_t nvme_next_cmdid(struct rt_nvme_controller *nvme) -{ - return rt_cpu_to_le16((rt_uint16_t)rt_atomic_add(&nvme->cmdid, 1)); -} - -static rt_err_t nvme_submit_cmd(struct rt_nvme_queue *queue, - struct rt_nvme_command *cmd) -{ - rt_ubase_t level; - rt_err_t err = RT_EOK; - rt_uint16_t tail, head; - struct rt_nvme_controller *nvme = queue->nvme; - -_retry: - level = rt_spin_lock_irqsave(&queue->lock); - - tail = queue->sq_tail; - head = queue->cq_head; - - if (tail + 1 == head) - { - /* IO queue is full, waiting for the last IO command to complete. */ - rt_spin_unlock_irqrestore(&queue->lock, level); - - rt_thread_yield(); - - goto _retry; - } - - cmd->common.cmdid = nvme_next_cmdid(nvme); - rt_memcpy(&queue->sq_cmds[tail], cmd, sizeof(*cmd)); - - if (nvme->ops->submit_cmd) - { - if ((err = nvme->ops->submit_cmd(queue, cmd))) - { - return err; - } - } - - if (++tail == queue->depth) - { - tail = 0; - } - HWREG32(queue->doorbell) = tail; - queue->sq_tail = tail; - - queue->cmd = cmd; - queue->err = RT_EOK; - - rt_spin_unlock_irqrestore(&queue->lock, level); - - err = rt_completion_wait(&queue->done, - rt_tick_from_millisecond(queue->qid != 0 ? RT_WAITING_FOREVER : 60)); - - return err ? : queue->err; -} - -static rt_err_t nvme_set_features_simple(struct rt_nvme_controller *nvme, - rt_uint32_t fid, rt_uint32_t dword11) -{ - struct rt_nvme_command cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.features.opcode = RT_NVME_ADMIN_OPCODE_SET_FEATURES; - cmd.features.fid = rt_cpu_to_le32(fid); - cmd.features.dword11 = rt_cpu_to_le32(dword11); - - return nvme_submit_cmd(&nvme->admin_queue, &cmd); -} - -static rt_err_t nvme_submit_io_cmd(struct rt_nvme_controller *nvme, - struct rt_nvme_command *cmd) -{ - rt_uint16_t qid; - - qid = rt_atomic_add(&nvme->ioqid[rt_hw_cpu_id()], RT_CPUS_NR); - qid %= nvme->io_queue_max; - - return nvme_submit_cmd(&nvme->io_queues[qid], cmd); -} - -/* - * PRP Mode: - * - * |63 n+1|n 0| - * +----------------------------------------+----------+---+---+ - * | Page Base Address | Offset | 0 | 0 | - * +----------------------------------------+----------+---+---+ - * | - * v - * Host Physical Pages - * +----------------------------+ - * +--------------+----------+ | Page k | - * | PRP Entry1 | Offset +---------->+----------------------------+ - * +--------------+----------+ | Page k + 1 | - * +----------------------------+ - * ... - * +----------------------------+ - * +--------------+----------+ | Page k + m | - * | PRP Entry2 | 0 +---------->+----------------------------+ - * +--------------+----------+ | Page k + m + 1 | - * +----------------------------+ - * PRP List (In PRP Entry2): - * - * |63 n+1|n 0| - * +----------------------------------------+------------------+ - * | Page Base Address k | 0h | - * +----------------------------------------+------------------+ - * | Page Base Address k + 1 | 0h | - * +----------------------------------------+------------------+ - * | ... | - * +----------------------------------------+------------------+ - * | Page Base Address k + m | 0h | - * +----------------------------------------+------------------+ - * | Page Base Address k + m + 1 | 0h | - * +----------------------------------------+------------------+ - * - * SGL Mode: - * +----- Non-transport - * LBA / - * +---------------+---------------+-------/-------+---------------+ - * | 3KB | 4KB | 2KB | 4KB | - * +-------+-------+-------+-------+---------------+--------+------+ - * | +-------------------------+ | - * | | | - * | +--------------------|------+ - * | | | - * +-------v-------+ +-------v-------+ +-------v-------+ - * | A MEM BLOCK | | B MEM BLOCK | | C MEM BLOCK | - * +-------^-------+ +-------^-------+ +-------^-------+ - * | | | - * +----------------+ | | - * | | | - * Segment(0) | | | - * +----------+----------+ | | | - * | Address: A +--+ | | - * +----------+----------+ | | - * | Type: 0h | Len: 3KB | | | - * +----------+----------+ | | - * | Address: Segment(1) +--+ | | - * +----------+----------+ | | | - * | Type: 2h | Len: 48 | | | | - * +----------+----------+ | | | - * | | | - * +------------------------+ | | - * | | | - * v | | - * Segment(1) | | - * +----------+----------+ | | - * | Address: B +------+ | - * +----------+----------+ | - * | Type: 0h | Len: 4KB | | - * +----------+----------+ | - * | Address: | | - * +----------+----------+ | - * | Type: 1h | Len: 2KB | | - * +----------+----------+ | - * | Address: Segment(2) +--+ | - * +----------+----------+ | | - * | Type: 0h | Len: 16 | | | - * +----------+----------+ | | - * | | - * +------------------------+ | - * | | - * v | - * Segment(2) | - * +----------+----------+ | - * | Address: C +---------------------------+ - * +----------+----------+ - * | Type: 0h | Len: 4KB | - * +----------+----------+ - */ - -static rt_ssize_t nvme_blk_rw(struct rt_nvme_device *ndev, rt_off_t slba, - rt_ubase_t buffer_dma, rt_size_t lbas, rt_uint8_t opcode) -{ - rt_err_t err; - rt_uint16_t max_lbas; - rt_uint32_t lba_shift; - rt_size_t tlbas; - rt_ssize_t data_length; - struct rt_nvme_command cmd; - struct rt_nvme_controller *nvme = ndev->ctrl; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.rw.opcode = opcode; - cmd.rw.flags = nvme->sgl_mode << RT_NVME_CMD_FLAGS_PSDT_SHIFT; - cmd.rw.nsid = rt_cpu_to_le32(ndev->nsid); - - tlbas = lbas; - lba_shift = ndev->lba_shift; - max_lbas = 1 << (nvme->max_transfer_shift - lba_shift); - - if (nvme->sgl_mode) - { - while ((rt_ssize_t)lbas > 0) - { - if (lbas < max_lbas) - { - max_lbas = (rt_uint16_t)lbas; - } - - data_length = max_lbas << lba_shift; - - cmd.rw.sgl.adddress = rt_cpu_to_le64(buffer_dma); - cmd.rw.sgl.length = rt_cpu_to_le32(data_length); - cmd.rw.sgl.sgl_identify = SGL_DESC_TYPE_DATA_BLOCK; - cmd.rw.slba = rt_cpu_to_le16(slba); - cmd.rw.length = rt_cpu_to_le16(max_lbas - 1); - - if ((err = nvme_submit_io_cmd(nvme, &cmd))) - { - tlbas -= lbas; - break; - } - - lbas -= max_lbas; - slba += max_lbas; - buffer_dma += data_length; - } - } - else - { - void *prp_list = RT_NULL; - rt_size_t prp_list_size = 0, page_size; - - page_size = nvme->page_size; - - while ((rt_ssize_t)lbas > 0) - { - rt_uint64_t prp2_addr, dma_addr; - rt_ssize_t remain_length, page_offset; - - if (lbas < max_lbas) - { - max_lbas = (rt_uint16_t)lbas; - } - - /* - * PRP transfer: - * 1. data_length <= 4KB: - * prp1 = buffer_dma - * prp2 = 0 - * - * 2. 4KB < data_length <= 8KB: - * prp1 = buffer_dma - * prp2 = buffer_dma - * - * 3. 8KB < data_length: - * prp1 = buffer_dma(0, 4k) - * prp2 = buffer_dma(4k, ~) - */ - dma_addr = buffer_dma; - page_offset = buffer_dma & (page_size - 1); - data_length = max_lbas << lba_shift; - remain_length = data_length - (page_size - page_offset); - - do { - rt_size_t prps_per_page, prps, pages; - rt_uint64_t *prp_list_ptr, prp_list_dma; - - if (remain_length <= 0) - { - prp2_addr = 0; - break; - } - - if (remain_length) - { - dma_addr += (page_size - page_offset); - } - - if (remain_length <= page_size) - { - prp2_addr = dma_addr; - break; - } - - prps_per_page = page_size / sizeof(rt_uint64_t); - prps = RT_DIV_ROUND_UP(remain_length, page_size); - pages = RT_DIV_ROUND_UP(prps - 1, prps_per_page - 1); - - if (prps > prp_list_size) - { - if (prp_list) - { - rt_free_align(prp_list); - } - - prp_list = rt_malloc_align(pages * page_size, page_size); - - if (!prp_list) - { - LOG_D("No memory to create a PRP List"); - /* Ask user to try again */ - return tlbas - lbas; - } - - prp_list_size = pages * (prps_per_page - 1) + 1; - } - prp_list_ptr = prp_list; - prp_list_dma = (rt_uint64_t)rt_kmem_v2p(prp_list_ptr); - - prp2_addr = prp_list_dma; - - for (int i = 0; prps; --prps, ++i) - { - /* End of the entry, fill the next entry addr if remain */ - if ((i == (prps_per_page - 1)) && prps > 1) - { - prp_list_dma += page_size; - *prp_list_ptr = rt_cpu_to_le64(prp_list_dma); - - /* Start to fill the next PRP */ - i = 0; - } - - *prp_list_ptr = rt_cpu_to_le64(dma_addr); - dma_addr += page_size; - } - - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, prp_list_ptr, prp_list_size); - } while (0); - - cmd.rw.prp1 = rt_cpu_to_le64(buffer_dma); - cmd.rw.prp2 = rt_cpu_to_le64(prp2_addr); - cmd.rw.slba = rt_cpu_to_le16(slba); - cmd.rw.length = rt_cpu_to_le16(max_lbas - 1); - - if ((err = nvme_submit_io_cmd(nvme, &cmd))) - { - tlbas -= lbas; - break; - } - - lbas -= max_lbas; - slba += max_lbas; - buffer_dma += data_length; - } - - if (prp_list) - { - rt_free_align(prp_list); - } - } - - return tlbas; -} - -static rt_ssize_t nvme_blk_read(struct rt_blk_disk *disk, rt_off_t sector, - void *buffer, rt_size_t sector_count) -{ - rt_ssize_t res; - rt_uint32_t page_bits; - rt_size_t buffer_size; - rt_ubase_t buffer_dma; - void *temp_buffer = RT_NULL; - struct rt_nvme_device *ndev = rt_disk_to_nvme_device(disk); - struct rt_nvme_controller *nvme = ndev->ctrl; - - buffer_size = (1 << ndev->lba_shift) * sector_count; - buffer_dma = (rt_ubase_t)rt_kmem_v2p(buffer); - - if ((nvme->sgl_mode && (buffer_dma & RT_GENMASK(1, 0))) || - (!nvme->sgl_mode && (buffer_dma & ARCH_PAGE_MASK))) - { - LOG_D("DMA PRP direct %s buffer MUST 4-bytes or page aligned", "read"); - - page_bits = rt_page_bits(buffer_size); - temp_buffer = rt_pages_alloc(page_bits); - - if (!temp_buffer) - { - return -RT_ENOMEM; - } - - buffer_dma = (rt_ubase_t)rt_kmem_v2p(temp_buffer); - } - - res = nvme_blk_rw(ndev, sector, buffer_dma, sector_count, RT_NVME_CMD_READ); - - if (res > 0) - { - if (res != sector_count) - { - /* - * Don't always aim for optimization, checking for equality - * is much faster than multiplication calculation. - */ - buffer_size = res * (1 << ndev->lba_shift); - } - - if (temp_buffer) - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, temp_buffer, buffer_size); - rt_memcpy(buffer, temp_buffer, buffer_size); - } - else - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, buffer, buffer_size); - } - } - - if (temp_buffer) - { - rt_pages_free(temp_buffer, page_bits); - } - - return res; -} - -static rt_ssize_t nvme_blk_write(struct rt_blk_disk *disk, rt_off_t sector, - const void *buffer, rt_size_t sector_count) -{ - rt_ssize_t res; - rt_uint32_t page_bits; - rt_size_t buffer_size; - rt_ubase_t buffer_dma; - void *temp_buffer = RT_NULL; - struct rt_nvme_device *ndev = rt_disk_to_nvme_device(disk); - struct rt_nvme_controller *nvme = ndev->ctrl; - - buffer_size = (1 << ndev->lba_shift) * sector_count; - buffer_dma = (rt_ubase_t)rt_kmem_v2p((void *)buffer); - - if ((nvme->sgl_mode && (buffer_dma & RT_GENMASK(1, 0))) || - (!nvme->sgl_mode && (buffer_dma & ARCH_PAGE_MASK))) - { - LOG_D("DMA PRP direct %s buffer MUST 4-bytes or page aligned", "write"); - - page_bits = rt_page_bits(buffer_size); - temp_buffer = rt_pages_alloc(page_bits); - - if (!temp_buffer) - { - return -RT_ENOMEM; - } - - buffer_dma = (rt_ubase_t)rt_kmem_v2p(temp_buffer); - - rt_memcpy(temp_buffer, buffer, buffer_size); - buffer = temp_buffer; - } - - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)buffer, buffer_size); - - res = nvme_blk_rw(ndev, sector, buffer_dma, sector_count, RT_NVME_CMD_WRITE); - - if (temp_buffer) - { - rt_pages_free(temp_buffer, page_bits); - } - - return res; -} - -static rt_err_t nvme_blk_getgeome(struct rt_blk_disk *disk, - struct rt_device_blk_geometry *geometry) -{ - struct rt_nvme_device *ndev = rt_disk_to_nvme_device(disk); - - geometry->bytes_per_sector = 1 << ndev->lba_shift; - geometry->block_size = 1 << ndev->lba_shift; - geometry->sector_count = rt_le64_to_cpu(ndev->id.nsze); - - return RT_EOK; -} - -static rt_err_t nvme_blk_sync(struct rt_blk_disk *disk) -{ - struct rt_nvme_command cmd; - struct rt_nvme_device *ndev = rt_disk_to_nvme_device(disk); - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.common.opcode = RT_NVME_CMD_FLUSH; - cmd.common.nsid = rt_cpu_to_le32(ndev->nsid); - - return nvme_submit_io_cmd(ndev->ctrl, &cmd); -} - -static rt_err_t nvme_blk_erase(struct rt_blk_disk *disk) -{ - rt_err_t err = RT_EOK; - rt_ssize_t slba, lbas, max_lbas; - struct rt_nvme_command cmd; - struct rt_nvme_device *ndev = rt_disk_to_nvme_device(disk); - struct rt_nvme_controller *nvme = ndev->ctrl; - - if (!nvme->write_zeroes) - { - return -RT_ENOSYS; - } - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.write_zeroes.opcode = RT_NVME_CMD_WRITE_ZEROES; - cmd.write_zeroes.nsid = rt_cpu_to_le32(ndev->nsid); - - slba = 0; - lbas = rt_le64_to_cpu(ndev->id.nsze); - max_lbas = 1 << (nvme->max_transfer_shift - ndev->lba_shift); - - while ((rt_ssize_t)lbas > 0) - { - if (lbas < max_lbas) - { - max_lbas = (rt_uint16_t)lbas; - } - - cmd.write_zeroes.slba = rt_cpu_to_le16(slba); - cmd.write_zeroes.length = rt_cpu_to_le16(max_lbas - 1); - - if ((err = nvme_submit_io_cmd(nvme, &cmd))) - { - break; - } - - lbas -= max_lbas; - slba += max_lbas; - } - - return err; -} - -static rt_err_t nvme_blk_autorefresh(struct rt_blk_disk *disk, rt_bool_t is_auto) -{ - struct rt_nvme_device *ndev = rt_disk_to_nvme_device(disk); - struct rt_nvme_controller *nvme = ndev->ctrl; - - if (nvme->volatile_write_cache & RT_NVME_CTRL_VWC_PRESENT) - { - return nvme_set_features_simple(nvme, RT_NVME_FEAT_VOLATILE_WC, !!is_auto); - } - else if (!is_auto) - { - return RT_EOK; - } - - return -RT_ENOSYS; -} - -static const struct rt_blk_disk_ops nvme_blk_ops = -{ - .read = nvme_blk_read, - .write = nvme_blk_write, - .getgeome = nvme_blk_getgeome, - .sync = nvme_blk_sync, - .erase = nvme_blk_erase, - .autorefresh = nvme_blk_autorefresh, -}; - -static void nvme_queue_isr(int irqno, void *param) -{ - rt_ubase_t level; - rt_uint16_t head, phase, status; - struct rt_nvme_queue *queue = param; - struct rt_nvme_controller *nvme = queue->nvme; - - level = rt_spin_lock_irqsave(&queue->lock); - - head = queue->cq_head; - phase = queue->cq_phase; - status = HWREG16(&queue->cq_entry[head].status); - status = rt_le16_to_cpu(status); - - if ((status & 0x01) == phase) - { - if ((status >> 1)) - { - queue->err = -RT_EIO; - goto _end_cmd; - } - - if (nvme->ops->complete_cmd) - { - nvme->ops->complete_cmd(queue, queue->cmd); - } - - _end_cmd: - if (++head == queue->depth) - { - head = 0; - phase = !phase; - } - - HWREG32(queue->doorbell + nvme->doorbell_stride) = head; - queue->cq_head = head; - queue->cq_phase = phase; - - rt_completion_done(&queue->done); - } - - rt_spin_unlock_irqrestore(&queue->lock, level); -} - -static rt_err_t nvme_identify(struct rt_nvme_controller *nvme, - rt_uint32_t nsid, rt_uint32_t cns, void *data) -{ - rt_err_t err; - rt_uint32_t page_size = nvme->page_size; - rt_ubase_t data_phy = (rt_ubase_t)rt_kmem_v2p(data); - int offset = data_phy & (page_size - 1); - struct rt_nvme_command cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.identify.opcode = RT_NVME_ADMIN_OPCODE_IDENTIFY; - cmd.identify.nsid = rt_cpu_to_le32(nsid); - cmd.identify.prp1 = rt_cpu_to_le64(data_phy); - - if (sizeof(struct rt_nvme_id_ctrl) <= page_size - offset) - { - cmd.identify.prp2 = 0; - } - else - { - data_phy += (page_size - offset); - cmd.identify.prp2 = rt_cpu_to_le64(data_phy); - } - cmd.identify.cns = rt_cpu_to_le32(cns); - - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, data, sizeof(struct rt_nvme_id_ctrl)); - - if (!(err = nvme_submit_cmd(&nvme->admin_queue, &cmd))) - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, data, sizeof(struct rt_nvme_id_ctrl)); - } - - return err; -} - -static rt_err_t nvme_attach_queue(struct rt_nvme_queue *queue, rt_uint8_t opcode) -{ - struct rt_nvme_command cmd; - struct rt_nvme_controller *nvme = queue->nvme; - rt_uint16_t flags = RT_NVME_QUEUE_PHYS_CONTIG; - - rt_memset(&cmd, 0, sizeof(cmd)); - - if (opcode == RT_NVME_ADMIN_OPCODE_CREATE_CQ) - { - cmd.create_cq.opcode = opcode; - cmd.create_cq.prp1 = rt_cpu_to_le64(queue->cq_entry_phy); - cmd.create_cq.cqid = rt_cpu_to_le16(queue->qid); - cmd.create_cq.qsize = rt_cpu_to_le16(queue->depth - 1); - cmd.create_cq.cq_flags = rt_cpu_to_le16(flags | RT_NVME_CQ_IRQ_ENABLED); - cmd.create_cq.irq_vector = rt_cpu_to_le16(nvme->irqs_nr > 1 ? queue->qid : 0); - } - else if (opcode == RT_NVME_ADMIN_OPCODE_CREATE_SQ) - { - cmd.create_sq.opcode = opcode; - cmd.create_sq.prp1 = rt_cpu_to_le64(queue->sq_cmds_phy); - cmd.create_sq.sqid = rt_cpu_to_le16(queue->qid); - cmd.create_sq.qsize = rt_cpu_to_le16(queue->depth - 1); - cmd.create_sq.sq_flags = rt_cpu_to_le16(flags | RT_NVME_SQ_PRIO_MEDIUM); - cmd.create_sq.cqid = rt_cpu_to_le16(queue->qid); - } - else - { - LOG_E("What the fuck opcode = %x", opcode); - RT_ASSERT(0); - } - - return nvme_submit_cmd(&nvme->admin_queue, &cmd); -} - -rt_inline rt_err_t nvme_attach_queue_sq(struct rt_nvme_queue *queue) -{ - return nvme_attach_queue(queue, RT_NVME_ADMIN_OPCODE_CREATE_SQ); -} - -rt_inline rt_err_t nvme_attach_queue_cq(struct rt_nvme_queue *queue) -{ - return nvme_attach_queue(queue, RT_NVME_ADMIN_OPCODE_CREATE_CQ); -} - -static rt_err_t nvme_detach_queue(struct rt_nvme_queue *queue, - rt_uint8_t opcode) -{ - struct rt_nvme_command cmd; - struct rt_nvme_controller *nvme = queue->nvme; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.delete_queue.opcode = opcode; - cmd.delete_queue.qid = rt_cpu_to_le16(queue->qid); - - return nvme_submit_cmd(&nvme->admin_queue, &cmd); -} - -rt_inline rt_ubase_t nvme_queue_dma_flags(void) -{ - return RT_DMA_F_NOCACHE | RT_DMA_F_LINEAR; -} - -static void nvme_free_queue(struct rt_nvme_queue *queue) -{ - rt_ubase_t dma_flags; - struct rt_nvme_controller *nvme = queue->nvme; - - if (nvme->ops->cleanup_queue) - { - rt_err_t err; - - if (!(err = nvme->ops->cleanup_queue(queue))) - { - LOG_W("Cleanup[%s] queue error = %s", nvme->ops->name, rt_strerror(err)); - } - } - - dma_flags = nvme_queue_dma_flags(); - - if (queue->sq_cmds) - { - rt_dma_free(nvme->dev, sizeof(*queue->sq_cmds) * queue->depth, - queue->sq_cmds, queue->sq_cmds_phy, dma_flags); - } - - if (queue->cq_entry) - { - rt_dma_free(nvme->dev, sizeof(*queue->cq_entry) * queue->depth, - queue->cq_entry, queue->cq_entry_phy, dma_flags); - } -} - -static struct rt_nvme_queue *nvme_alloc_queue(struct rt_nvme_controller *nvme, - int qid, int depth) -{ - rt_err_t err; - rt_ubase_t dma_flags; - struct rt_nvme_queue *queue = &nvme->queue[qid]; - - rt_memset(queue, 0, sizeof(*queue)); - - queue->nvme = nvme; - queue->doorbell = &nvme->doorbell_tbl[qid * 2 * nvme->doorbell_stride]; - queue->qid = qid; - queue->depth = depth; - queue->cq_head = 0; - queue->cq_phase = 1; - rt_completion_init(&queue->done); - rt_spin_lock_init(&queue->lock); - - dma_flags = nvme_queue_dma_flags(); - - /* struct rt_nvme_command */ - queue->sq_cmds = rt_dma_alloc(nvme->dev, - sizeof(*queue->sq_cmds) * depth, &queue->sq_cmds_phy, dma_flags); - - if (!queue->sq_cmds) - { - err = -RT_ENOMEM; - goto _fail; - } - - /* struct rt_nvme_completion */ - queue->cq_entry = rt_dma_alloc(nvme->dev, - sizeof(*queue->cq_entry) * depth, &queue->cq_entry_phy, dma_flags); - - if (!queue->cq_entry) - { - err = -RT_ENOMEM; - goto _fail; - } - - rt_memset(queue->sq_cmds, 0, sizeof(struct rt_nvme_command) * depth); - rt_memset(queue->cq_entry, 0, sizeof(struct rt_nvme_completion) * depth); - - if (nvme->ops->setup_queue) - { - if (!(err = nvme->ops->setup_queue(queue))) - { - LOG_E("Setup[%s] queue error = %s", nvme->ops->name, rt_strerror(err)); - - goto _fail; - } - } - - return queue; - -_fail: - nvme_free_queue(queue); - - return rt_err_ptr(err); -} - -static rt_err_t nvme_configure_admin_queue(struct rt_nvme_controller *nvme) -{ - rt_err_t err; - int irq; - char name[RT_NAME_MAX]; - rt_uint32_t aqa; - rt_uint32_t page_shift = ARCH_PAGE_SHIFT; - rt_uint32_t page_min = RT_NVME_CAP_MPSMIN(nvme->cap) + 12; - rt_uint32_t page_max = RT_NVME_CAP_MPSMAX(nvme->cap) + 12; - struct rt_nvme_queue *admin_queue; - - if (page_shift < page_min) - { - LOG_E("Device %s page size (%u) %s than host (%u)", - "minimum", 1 << page_min, "larger", 1 << page_shift); - return -RT_EINVAL; - } - - if (page_shift > page_max) - { - LOG_W("Device %s page size (%u) %s than host (%u)", - "maximum", 1 << page_max, "smaller", 1 << page_shift); - page_shift = page_max; - } - - if ((err = nvme_disable_ctrl(nvme))) - { - return err; - } - - admin_queue = nvme_alloc_queue(nvme, 0, RT_NVME_AQ_DEPTH); - - if (rt_is_err(admin_queue)) - { - return rt_ptr_err(admin_queue); - } - - aqa = admin_queue->depth - 1; - aqa |= aqa << 16; - - nvme->page_shift = page_shift; - nvme->page_size = 1U << page_shift; - - nvme->ctrl_config = RT_NVME_CC_CSS_NVM; - nvme->ctrl_config |= (page_shift - 12) << RT_NVME_CC_MPS_SHIFT; - nvme->ctrl_config |= RT_NVME_CC_ARB_RR | RT_NVME_CC_SHN_NONE; - nvme->ctrl_config |= RT_NVME_CC_IOSQES | RT_NVME_CC_IOCQES; - - nvme_writel(nvme, RT_NVME_REG_AQA, aqa); - nvme_writeq(nvme, RT_NVME_REG_ASQ, admin_queue->sq_cmds_phy); - nvme_writeq(nvme, RT_NVME_REG_ACQ, admin_queue->cq_entry_phy); - - if ((err = nvme_enable_ctrl(nvme))) - { - nvme_free_queue(admin_queue); - - return err; - } - - irq = nvme->irqs[0]; - - rt_snprintf(name, RT_NAME_MAX, "%s-admin-queue", nvme->name); - - rt_hw_interrupt_install(irq, nvme_queue_isr, &nvme->admin_queue, name); - rt_hw_interrupt_umask(irq); - - return RT_EOK; -} - -static rt_err_t nvme_setup_io_queues(struct rt_nvme_controller *nvme) -{ - rt_err_t err; - rt_uint32_t value; - int irq, cpuid = 0; - char name[RT_NAME_MAX]; - rt_bool_t affinity_fixup = RT_FALSE; - RT_IRQ_AFFINITY_DECLARE(affinity) = { 0 }; - struct rt_nvme_queue *queue; - - nvme->io_queue_max = nvme->irqs_nr > 1 ? nvme->irqs_nr - 1 : 1; - value = (nvme->io_queue_max - 1) | ((nvme->io_queue_max - 1) << 16); - - if ((err = nvme_set_features_simple(nvme, RT_NVME_FEAT_NUM_QUEUES, value))) - { - return err; - } - - for (int i = 0, q_idx = 1; i < nvme->io_queue_max; ++i, ++q_idx) - { - queue = nvme_alloc_queue(nvme, q_idx, nvme->queue_depth); - - if (!queue) - { - return -RT_ENOMEM; - } - - if ((err = nvme_attach_queue_cq(queue)) || - (err = nvme_attach_queue_sq(queue))) - { - return err; - } - } - - for (int i = 0, irq_idx = 1; i < nvme->io_queue_max; ++i, ++irq_idx) - { - irq = nvme->irqs[irq_idx % nvme->irqs_nr]; - - rt_snprintf(name, RT_NAME_MAX, "%s-io-queue%d", nvme->name, i); - - if (!affinity_fixup) - { - RT_IRQ_AFFINITY_SET(affinity, cpuid % RT_CPUS_NR); - if (rt_pic_irq_set_affinity(irq, affinity)) - { - /* Fixup in secondary CPU startup */ - affinity_fixup = RT_TRUE; - } - RT_IRQ_AFFINITY_CLEAR(affinity, cpuid++ % RT_CPUS_NR); - } - - rt_hw_interrupt_install(irq, nvme_queue_isr, &nvme->io_queues[i], name); - rt_hw_interrupt_umask(irq); - } - - return RT_EOK; -} - -static void nvme_remove_io_queues(struct rt_nvme_controller *nvme) -{ - int irq; - struct rt_nvme_queue *queue; - - for (int i = 0, irq_idx = 1; i < nvme->io_queue_max; ++i, ++irq_idx) - { - queue = &nvme->io_queues[i]; - - nvme_detach_queue(queue, RT_NVME_ADMIN_OPCODE_DELETE_SQ); - nvme_detach_queue(queue, RT_NVME_ADMIN_OPCODE_DELETE_CQ); - nvme_free_queue(queue); - - irq = nvme->irqs[irq_idx % nvme->irqs_nr]; - - rt_hw_interrupt_mask(irq); - rt_pic_detach_irq(irq, queue); - } -} - -static void nvme_remove_admin_queues(struct rt_nvme_controller *nvme) -{ - int irq = nvme->irqs[0]; - - rt_hw_interrupt_mask(irq); - rt_pic_detach_irq(irq, &nvme->admin_queue); - - nvme_free_queue(&nvme->admin_queue); -} - -static void nvme_remove_devices(struct rt_nvme_controller *nvme) -{ - struct rt_nvme_device *ndev, *next_ndev; - - rt_list_for_each_entry_safe(ndev, next_ndev, &nvme->ns_nodes, list) - { - rt_list_remove(&ndev->list); - - rt_hw_blk_disk_unregister(&ndev->parent); - rt_free(ndev); - } -} - -static rt_err_t nvme_scan_device(struct rt_nvme_controller *nvme, - rt_size_t number_of_ns) -{ - rt_err_t err = RT_EOK; - rt_uint32_t lbaf; - struct rt_nvme_id_ns *id = RT_NULL; - - if (!(id = rt_malloc_align(sizeof(*id), nvme->page_size))) - { - return -RT_ENOMEM; - } - - /* NVME Namespace is start with "1" */ - for (rt_uint32_t nsid = 1; nsid <= number_of_ns; ++nsid) - { - struct rt_nvme_device *ndev = rt_calloc(1, sizeof(*ndev)); - - if (!ndev) - { - err = -RT_ENOMEM; - goto _free_res; - } - - rt_memset(id, 0, sizeof(*id)); - if ((err = nvme_identify(nvme, nsid, 0, id))) - { - goto _free_res; - } - - if (!id->nsze) - { - continue; - } - - ndev->ctrl = nvme; - - rt_memcpy(&ndev->id, id, sizeof(ndev->id)); - lbaf = id->flbas & RT_NVME_NS_FLBAS_LBA_MASK; - lbaf |= ((id->flbas & RT_NVME_NS_FLBAS_LBA_UMASK) >> RT_NVME_NS_FLBAS_LBA_SHIFT); - - ndev->nsid = nsid; - ndev->lba_shift = id->lbaf[lbaf].ds; - - ndev->parent.ida = &nvme_ida; - ndev->parent.parallel_io = RT_TRUE; - ndev->parent.ops = &nvme_blk_ops; - ndev->parent.max_partitions = RT_BLK_PARTITION_MAX; - rt_dm_dev_set_name(&ndev->parent.parent, "%sn%u", nvme->name, nsid); - - if ((err = rt_hw_blk_disk_register(&ndev->parent))) - { - goto _free_res; - } - - rt_list_init(&ndev->list); - rt_list_insert_before(&nvme->ns_nodes, &ndev->list); - } - -_free_res: - rt_free_align(id); - - return err; -} - -rt_inline rt_size_t strip_len(const char *str, rt_size_t max_len) -{ - rt_size_t size = 0; - - for (int i = 0; *str && i < max_len; ++i, ++str) - { - if (*str != ' ') - { - size = i + 1; - } - } - - return size; -} - -rt_err_t rt_nvme_controller_register(struct rt_nvme_controller *nvme) -{ - rt_err_t err; - struct rt_nvme_id_ctrl *ctrl = RT_NULL; - - if (!nvme || !nvme->ops) - { - return -RT_EINVAL; - } - - if (nvme_readl(nvme, RT_NVME_REG_CSTS) == (rt_uint32_t)-1) - { - LOG_E("Out of memory"); - - return -RT_EINVAL; - } - - if ((nvme->nvme_id = rt_dm_ida_alloc(&nvme_controller_ida)) < 0) - { - return -RT_EFULL; - } - - rt_snprintf(nvme->name, RT_NAME_MAX, "nvme%u", nvme->nvme_id); - - nvme->cap = nvme_readq(nvme, RT_NVME_REG_CAP); - nvme->queue_depth = RT_NVME_CAP_MQES(nvme->cap) + 1; - nvme->doorbell_stride = 1 << RT_NVME_CAP_STRIDE(nvme->cap); - nvme->doorbell_tbl = nvme->regs + RT_NVME_REG_DBS; - - if ((err = nvme_configure_admin_queue(nvme))) - { - LOG_E("Configure admin queue error = %s", rt_strerror(err)); - goto _free_admin_queue; - } - - if ((err = nvme_setup_io_queues(nvme))) - { - LOG_E("Unable to setup I/O queues error = %s", rt_strerror(err)); - goto _free_admin_queue; - } - - if (!(ctrl = rt_malloc_align(sizeof(*ctrl), nvme->page_size))) - { - err = -RT_ENOMEM; - goto _fail; - } - - if ((err = nvme_identify(nvme, 0, 1, ctrl))) - { - goto _fail; - } - - if (ctrl->mdts) - { - nvme->max_transfer_shift = ctrl->mdts + (RT_NVME_CAP_MPSMIN(nvme->cap) + 12); - } - else - { - /* 1MB is recommended. */ - nvme->max_transfer_shift = 20; - } - nvme->volatile_write_cache = ctrl->vwc; - nvme->write_zeroes = !!(rt_le64_to_cpu(ctrl->oncs) & RT_NVME_CTRL_ONCS_WRITE_ZEROES); - - if ((rt_le32_to_cpu(ctrl->sgls) & RT_NVME_ID_SGL_SUPPORT_MASK)) - { - nvme->sgl_mode = RT_NVME_PSDT_SGL_MPTR_SGL; - } - - LOG_I("NVM Express v%d.%d (%s, %-*.s, %-*.s)", - nvme_readl(nvme, RT_NVME_REG_VS) >> 16, - nvme_readl(nvme, RT_NVME_REG_VS) & 0xff, - nvme->ops->name, - strip_len(ctrl->mn, sizeof(ctrl->mn)), ctrl->mn, - strip_len(ctrl->fr, sizeof(ctrl->fr)), ctrl->fr); - - rt_list_init(&nvme->ns_nodes); - if ((err = nvme_scan_device(nvme, rt_le32_to_cpu(ctrl->nn)))) - { - goto _fail; - } - - rt_free_align(ctrl); - - rt_spin_lock(&nvme_lock); - rt_list_insert_after(&nvme_nodes, &nvme->list); - rt_spin_unlock(&nvme_lock); - - return RT_EOK; - -_fail: - if (ctrl) - { - rt_free_align(ctrl); - } - nvme_remove_devices(nvme); - nvme_remove_io_queues(nvme); -_free_admin_queue: - nvme_remove_admin_queues(nvme); - - rt_dm_ida_free(&nvme_controller_ida, nvme->nvme_id); - - return err; -} - -rt_err_t rt_nvme_controller_unregister(struct rt_nvme_controller *nvme) -{ - rt_err_t err; - - if (!nvme) - { - return -RT_EINVAL; - } - - rt_spin_lock(&nvme_lock); - rt_list_remove(&nvme->list); - rt_spin_unlock(&nvme_lock); - - nvme_remove_devices(nvme); - nvme_remove_io_queues(nvme); - nvme_remove_admin_queues(nvme); - - rt_dm_ida_free(&nvme_controller_ida, nvme->nvme_id); - - if (!(err = nvme_shutdown_ctrl(nvme))) - { - err = nvme_disable_ctrl(nvme); - } - else - { - LOG_E("%s: shutdown error = %s", nvme->name, rt_strerror(err)); - } - - return err; -} - -/* - * NVME's IO queue should be Per-CPU, fixup the affinity after the secondary CPU - * startup, this stage can make sure the affinity setting success as possible. - */ -static int nvme_queue_affinify_fixup(void) -{ - int cpuid = rt_hw_cpu_id(); - struct rt_nvme_controller *nvme; - RT_IRQ_AFFINITY_DECLARE(affinity) = { 0 }; - RT_IRQ_AFFINITY_DECLARE(current_affinity) = { 0 }; - - RT_IRQ_AFFINITY_SET(affinity, cpuid); - - rt_hw_spin_lock(&nvme_lock.lock); - rt_list_for_each_entry(nvme, &nvme_nodes, list) - { - for (int i = cpuid % RT_CPUS_NR; i < nvme->io_queue_max; i += RT_CPUS_NR) - { - int irq = nvme->irqs[i]; - - if (!rt_pic_irq_get_affinity(irq, current_affinity) && - !rt_bitmap_test_bit(current_affinity, cpuid)) - { - rt_ubase_t level = rt_hw_interrupt_disable(); - - rt_pic_irq_set_affinity(irq, affinity); - - rt_hw_interrupt_enable(level); - } - } - } - rt_hw_spin_unlock(&nvme_lock.lock); - - return 0; -} -INIT_SECONDARY_CPU_EXPORT(nvme_queue_affinify_fixup); diff --git a/rt-thread/components/drivers/ofw/base.c b/rt-thread/components/drivers/ofw/base.c index 78a2e9f..c2d2f8f 100644 --- a/rt-thread/components/drivers/ofw/base.c +++ b/rt-thread/components/drivers/ofw/base.c @@ -333,6 +333,8 @@ static int ofw_prop_index_of_string(struct rt_ofw_prop *prop, const char *string static rt_int32_t ofw_strcasecmp(const char *cs, const char *ct) { + extern rt_int32_t strcasecmp(const char *cs, const char *ct); + return rt_strcasecmp(cs, ct); } @@ -1410,7 +1412,7 @@ struct rt_ofw_node *rt_ofw_append_child(struct rt_ofw_node *parent, const char * } } - return rt_ofw_node_get(np); + return np; } rt_err_t rt_ofw_append_prop(struct rt_ofw_node *np, const char *name, int length, void *value) diff --git a/rt-thread/components/drivers/ofw/fdt.c b/rt-thread/components/drivers/ofw/fdt.c index cca4cdd..419f392 100644 --- a/rt-thread/components/drivers/ofw/fdt.c +++ b/rt-thread/components/drivers/ofw/fdt.c @@ -37,12 +37,6 @@ static rt_phandle _phandle_max; static rt_size_t _root_size_cells; static rt_size_t _root_addr_cells; -#ifdef ARCH_CPU_64BIT -#define MIN_BIT 16 -#else -#define MIN_BIT 8 -#endif - const char *rt_fdt_node_name(const char *full_name) { const char *node_name = strrchr(full_name, '/'); @@ -91,15 +85,15 @@ rt_uint64_t rt_fdt_translate_address(void *fdt, int nodeoffset, rt_uint64_t addr if (parent >= 0) { - ranges = fdt_getprop(fdt, parent, "ranges", &length); + ranges = fdt_getprop(fdt, nodeoffset, "ranges", &length); } if (ranges && length > 0) { - local.addr_cells = fdt_address_cells(fdt, parent); - local.size_cells = fdt_size_cells(fdt, parent); - cpu.addr_cells = fdt_io_addr_cells(fdt, parent); - cpu.size_cells = fdt_io_size_cells(fdt, parent); + local.addr_cells = fdt_address_cells(fdt, nodeoffset); + local.size_cells = fdt_size_cells(fdt, nodeoffset); + cpu.addr_cells = fdt_io_addr_cells(fdt, nodeoffset); + cpu.size_cells = fdt_io_size_cells(fdt, nodeoffset); group_len = local.addr_cells + cpu.addr_cells + local.size_cells; @@ -111,7 +105,7 @@ rt_uint64_t rt_fdt_translate_address(void *fdt, int nodeoffset, rt_uint64_t addr if (local.addr <= address && local.addr + local.size > address) { - ret = address - local.addr + cpu.addr; + ret += address - cpu.addr; break; } @@ -253,9 +247,9 @@ static rt_err_t fdt_reserved_memory_reg(int nodeoffset, const char *uname) rt_bool_t is_nomap = fdt_getprop(_fdt, nodeoffset, "no-map", RT_NULL) ? RT_TRUE : RT_FALSE; base = rt_fdt_translate_address(_fdt, nodeoffset, base); + rt_memblock_reserve_memory(uname, base, base + size, is_nomap); - rt_memblock_reserve_memory(fdt_get_name(_fdt, nodeoffset, RT_NULL), - base, base + size, is_nomap); + len -= t_len; } } } @@ -364,11 +358,11 @@ static rt_err_t fdt_scan_memory(void) if (!err) { - LOG_I("Memory node(%d) ranges: 0x%.*lx - 0x%.*lx%s", no, MIN_BIT, base, MIN_BIT, base + size, ""); + LOG_I("Memory node(%d) ranges: %p - %p%s", no, base, base + size, ""); } else { - LOG_W("Memory node(%d) ranges: 0x%.*lx - 0x%.*lx%s", no, MIN_BIT, base, MIN_BIT, base + size, " unable to record"); + LOG_W("Memory node(%d) ranges: %p - %p%s", no, base, base + size, " unable to record"); } } } @@ -799,55 +793,6 @@ rt_err_t rt_fdt_scan_chosen_stdout(void) return err; } -rt_err_t rt_fdt_bootargs_select(const char *key, int index, const char **out_result) -{ - rt_err_t err; - - if (key && index >= 0 && out_result) - { - int offset = fdt_path_offset(_fdt, "/chosen"); - - if (offset >= 0) - { - int len, key_len = rt_strlen(key); - const char *bootargs = fdt_getprop(_fdt, offset, "bootargs", &len), *end; - - end = bootargs + len; - err = -RT_EEMPTY; - - for (int i = 0; bootargs < end; ++i) - { - bootargs = rt_strstr(bootargs, key); - - if (!bootargs) - { - break; - } - - bootargs += key_len; - - if (i == index) - { - *out_result = bootargs; - - err = -RT_EOK; - break; - } - } - } - else - { - err = -RT_ERROR; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - static void system_node_init_flag(struct rt_ofw_node *np) { if (np) diff --git a/rt-thread/components/drivers/ofw/io.c b/rt-thread/components/drivers/ofw/io.c index b0a7526..d9065c0 100644 --- a/rt-thread/components/drivers/ofw/io.c +++ b/rt-thread/components/drivers/ofw/io.c @@ -407,75 +407,6 @@ rt_uint64_t rt_ofw_translate_address(struct rt_ofw_node *np, const char *range_t return cpu_addr; } -rt_uint64_t rt_ofw_reverse_address(struct rt_ofw_node *np, const char *range_type, rt_uint64_t address) -{ - rt_uint64_t bus_addr = address; - - if (!range_type) - { - range_type = "ranges"; - } - - rt_ofw_foreach_parent_node(np) - { - rt_ssize_t len; - struct rt_ofw_prop *prop; - struct bus_ranges *ranges = RT_NULL; - - prop = rt_ofw_get_prop(np, range_type, &len); - - if (!prop || !len) - { - continue; - } - - for (int i = 0; i < RT_ARRAY_SIZE(_bus_ranges); ++i) - { - if (!_bus_ranges[i]) - { - break; - } - - if (_bus_ranges[i]->np == np) - { - ranges = _bus_ranges[i]; - break; - } - } - - if (!ranges) - { - ranges = ofw_bus_ranges(np, prop); - } - - if (ranges) - { - for (int i = 0; i < ranges->nr; ++i) - { - rt_uint64_t parent_addr = ranges->parent_addr[i]; - rt_uint64_t child_size = ranges->child_size[i]; - - if (address >= parent_addr && address < parent_addr + child_size) - { - bus_addr = ranges->child_addr[i] + (address - parent_addr); - - break; - } - } - } - else - { - bus_addr = ~0ULL; - } - - rt_ofw_node_put(np); - - break; - } - - return bus_addr; -} - #ifdef ARCH_CPU_64BIT #define ofw_address_cpu_cast(np, address) (void *)(address) #else diff --git a/rt-thread/components/drivers/ofw/ofw.c b/rt-thread/components/drivers/ofw/ofw.c index 76389f3..d09fb4e 100644 --- a/rt-thread/components/drivers/ofw/ofw.c +++ b/rt-thread/components/drivers/ofw/ofw.c @@ -69,12 +69,6 @@ struct ofw_obj_cmp_list static const struct ofw_obj_cmp_list ofw_obj_cmp_list[] = { -#ifdef RT_USING_CLK - { "#clock-cells", RT_CLK_NODE_OBJ_NAME, sizeof(struct rt_clk_node) }, -#endif -#ifdef RT_USING_RESET - { "#reset-cells", RT_RESET_CONTROLLER_OBJ_NAME, sizeof(struct rt_reset_controller) }, -#endif { "#power-domain-cells", RT_POWER_DOMAIN_PROXY_OBJ_NAME, sizeof(struct rt_dm_power_domain_proxy) }, { "#power-domain-cells", RT_POWER_DOMAIN_OBJ_NAME, sizeof(struct rt_dm_power_domain) }, }; @@ -109,14 +103,14 @@ static struct rt_object *ofw_parse_object(struct rt_ofw_node *np, const char *ce { item = &ofw_obj_cmp_list[i]; + if (!rt_strcmp(item->cells_name, cells_name)) + { + ret_obj = obj; + break; + } + if (!rt_strncmp(item->obj_name, obj->name, RT_NAME_MAX)) { - if (!rt_strcmp(item->cells_name, cells_name)) - { - ret_obj = obj; - break; - } - obj = (struct rt_object *)((rt_ubase_t)obj + item->obj_size); break; } @@ -140,7 +134,7 @@ struct rt_object *rt_ofw_parse_object(struct rt_ofw_node *np, const char *obj_na if (np && (test_obj = rt_ofw_data(np)) && cells_name) { /* The composite object is rare, so we try to find this object as much as possible at once. */ - if (obj_name && !rt_strcmp(test_obj->name, obj_name)) + if (obj_name && rt_strcmp(test_obj->name, obj_name)) { obj = test_obj; } @@ -392,11 +386,6 @@ const char *rt_ofw_bootargs_select(const char *key, int index) { *(char *)ch++ = '\0'; } - if (*ch == '\0') - { - /* space in the end */ - --bootargs_nr; - } --ch; } @@ -647,14 +636,7 @@ void rt_ofw_node_dump_dts(struct rt_ofw_node *np, rt_bool_t sibling_too) struct fdt_info *header = (struct fdt_info *)np->name; struct fdt_reserve_entry *rsvmap = header->rsvmap; - /* - * Shall be present to identify the file as a version 1 DTS - * (dts files without this tag will be treated by dtc - * as being in the obsolete version 0, which uses - * a different format for integers in addition to - * other small but incompatible changes). - */ - rt_kprintf("/dts-v1/;\n\n"); + rt_kprintf("/dts-v%x/;\n\n", fdt_version(header->fdt)); for (int i = header->rsvmap_nr - 1; i >= 0; --i) { diff --git a/rt-thread/components/drivers/pci/Kconfig b/rt-thread/components/drivers/pci/Kconfig deleted file mode 100644 index f25fce6..0000000 --- a/rt-thread/components/drivers/pci/Kconfig +++ /dev/null @@ -1,49 +0,0 @@ -menuconfig RT_USING_PCI - bool "Using Peripheral Component Interconnect Express (PCIe/PCI)" - depends on RT_USING_DM - depends on RT_USING_PIC - select RT_USING_ADT - select RT_USING_ADT_BITMAP - default n - -config RT_PCI_MSI - bool "PCI MSI/MSI-X" - depends on RT_USING_PCI - default y - -config RT_PCI_ENDPOINT - bool "PCI Endpoint" - depends on RT_USING_PCI - select RT_USING_ADT_REF - default n - -config RT_PCI_SYS_64BIT - bool "PCI System 64bit" - depends on RT_USING_PCI - depends on ARCH_CPU_64BIT - default y - -config RT_PCI_CACHE_LINE_SIZE - int "PCI Cache line size" - depends on RT_USING_PCI - default 8 if ARCH_CPU_64BIT - default 4 - -config RT_PCI_LOCKLESS - bool "PCI Lock less in options" - depends on RT_USING_PCI - default n - -if RT_USING_PCI - -comment "PCI Device Drivers" - -config RT_PCI_ECAM - bool "PCIe ECAM" - depends on RT_USING_PCI - default y - help - PCIe Express Enhanced Configuration Access Mechanism - -rsource "host/Kconfig" -endif diff --git a/rt-thread/components/drivers/pci/SConscript b/rt-thread/components/drivers/pci/SConscript deleted file mode 100644 index dfe3797..0000000 --- a/rt-thread/components/drivers/pci/SConscript +++ /dev/null @@ -1,28 +0,0 @@ -from building import * - -objs = [] - -if not GetDepend(['RT_USING_PCI']): - Return('objs') - -cwd = GetCurrentDir() -list = os.listdir(cwd) -CPPPATH = [cwd + '/../include'] - -src = ['access.c', 'host-bridge.c', 'irq.c', 'pci.c', 'pme.c', 'probe.c'] - -if GetDepend(['RT_USING_OFW']): - src += ['ofw.c'] - -if GetDepend(['RT_PCI_ECAM']): - src += ['ecam.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -for d in list: - path = os.path.join(cwd, d) - if os.path.isfile(os.path.join(path, 'SConscript')): - objs = objs + SConscript(os.path.join(d, 'SConscript')) -objs = objs + group - -Return('objs') diff --git a/rt-thread/components/drivers/pci/access.c b/rt-thread/components/drivers/pci/access.c deleted file mode 100644 index 7b026c8..0000000 --- a/rt-thread/components/drivers/pci/access.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#include -#include - -#include - -struct rt_spinlock rt_pci_lock = { 0 }; - -#ifdef RT_PCI_LOCKLESS -#define pci_lock_config(l) do { (void)(l); } while (0) -#define pci_unlock_config(l) do { (void)(l); } while (0) -#else -#define pci_lock_config(l) l = rt_spin_lock_irqsave(&rt_pci_lock) -#define pci_unlock_config(l) rt_spin_unlock_irqrestore(&rt_pci_lock, l) -#endif - -#define PCI_OPS_READ(name, type) \ -rt_err_t rt_pci_bus_read_config_##name(struct rt_pci_bus *bus, rt_uint32_t devfn, int reg, type *value) \ -{ \ - rt_err_t err; \ - rt_ubase_t level; \ - rt_uint32_t data = 0; \ - pci_lock_config(level); \ - err = bus->ops->read(bus, devfn, reg, sizeof(type), &data); \ - *value = err ? (type)(~0) : (type)data; \ - pci_unlock_config(level); \ - return err; \ -} - -#define PCI_OPS_WRITE(name, type) \ -rt_err_t rt_pci_bus_write_config_##name(struct rt_pci_bus *bus, rt_uint32_t devfn, int reg, type value) \ -{ \ - rt_err_t err; \ - rt_ubase_t level; \ - pci_lock_config(level); \ - err = bus->ops->write(bus, devfn, reg, sizeof(type), value); \ - pci_unlock_config(level); \ - return err; \ -} - -#define PCI_OPS(name, type) \ - PCI_OPS_READ(name, type) \ - PCI_OPS_WRITE(name, type) - -PCI_OPS(u8, rt_uint8_t) -PCI_OPS(u16, rt_uint16_t) -PCI_OPS(u32, rt_uint32_t) - -#undef PCI_OP_WRITE -#undef PCI_OP_READ -#undef PCI_OPS - -rt_err_t rt_pci_bus_read_config_uxx(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, int width, rt_uint32_t *value) -{ - void *base; - - if ((base = bus->ops->map(bus, devfn, reg))) - { - if (width == 1) - { - *value = HWREG8(base); - } - else if (width == 2) - { - *value = HWREG16(base); - } - else - { - *value = HWREG32(base); - } - - return RT_EOK; - } - - return -RT_ERROR; -} - -rt_err_t rt_pci_bus_write_config_uxx(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, int width, rt_uint32_t value) -{ - void *base; - - if ((base = bus->ops->map(bus, devfn, reg))) - { - if (width == 1) - { - HWREG8(base) = value; - } - else if (width == 2) - { - HWREG16(base) = value; - } - else - { - HWREG32(base) = value; - } - - return RT_EOK; - } - - return -RT_ERROR; -} - -rt_err_t rt_pci_bus_read_config_generic_u32(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, int width, rt_uint32_t *value) -{ - void *base; - - if ((base = bus->ops->map(bus, devfn, reg))) - { - *value = HWREG32(base); - - if (width <= 2) - { - *value = (*value >> (8 * (reg & 3))) & ((1 << (width * 8)) - 1); - } - - return RT_EOK; - } - - return -RT_ERROR; -} - -rt_err_t rt_pci_bus_write_config_generic_u32(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, int width, rt_uint32_t value) -{ - void *base; - - if ((base = bus->ops->map(bus, devfn, reg & ~0x3))) - { - if (width == 4) - { - HWREG32(base) = value; - } - else - { - rt_uint32_t mask, tmp; - - mask = ~(((1 << (width * 8)) - 1) << ((reg & 0x3) * 8)); - tmp = HWREG32(base) & mask; - tmp |= value << ((reg & 0x3) * 8); - HWREG32(base) = tmp; - } - - return RT_EOK; - } - - return -RT_ERROR; -} diff --git a/rt-thread/components/drivers/pci/ecam.c b/rt-thread/components/drivers/pci/ecam.c deleted file mode 100644 index f5813f3..0000000 --- a/rt-thread/components/drivers/pci/ecam.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#include -#include - -#define DBG_TAG "pci.ecam" -#define DBG_LVL DBG_INFO -#include - -#include "ecam.h" - -struct pci_ecam_config_window *pci_ecam_create(struct rt_pci_host_bridge *host_bridge, - const struct pci_ecam_ops *ops) -{ - struct pci_ecam_config_window *conf_win = rt_calloc(1, sizeof(*conf_win)); - - if (!conf_win) - { - return RT_NULL; - } - - conf_win->bus_range = host_bridge->bus_range; - conf_win->bus_shift = ops->bus_shift; - conf_win->ops = ops; - - host_bridge->ops = (const struct rt_pci_ops *)&ops->pci_ops; - - return conf_win; -} - -void *pci_ecam_map(struct rt_pci_bus *bus, rt_uint32_t devfn, int where) -{ - struct pci_ecam_config_window *conf_win = bus->sysdata; - const struct pci_ecam_ops *eops = conf_win->ops; - void *win = conf_win->win, *map; - rt_uint32_t busn = bus->number, bus_shift = eops->bus_shift, devfn_shift = bus_shift - 8; - - busn -= conf_win->bus_range[0]; - - if (bus_shift) - { - rt_uint32_t bus_offset = (busn & PCIE_ECAM_BUS_MASK) << bus_shift; - rt_uint32_t devfn_offset = (devfn & PCIE_ECAM_DEVFN_MASK) << devfn_shift; - - where &= PCIE_ECAM_REG_MASK; - map = win + (bus_offset | devfn_offset | where); - } - else - { - map = win + PCIE_ECAM_OFFSET(busn, devfn, where); - } - - return map; -} - -const struct pci_ecam_ops pci_generic_ecam_ops = -{ - .pci_ops = - { - .map = pci_ecam_map, - .read = rt_pci_bus_read_config_uxx, - .write = rt_pci_bus_write_config_uxx, - } -}; diff --git a/rt-thread/components/drivers/pci/ecam.h b/rt-thread/components/drivers/pci/ecam.h deleted file mode 100644 index 98fa3eb..0000000 --- a/rt-thread/components/drivers/pci/ecam.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#ifndef __RT_PCI_ECAM_H__ -#define __RT_PCI_ECAM_H__ - -#include -#include -#include -#include - -/* - * Memory address shift values for the byte-level address that - * can be used when accessing the PCI Express Configuration Space. - */ - -/* - * Enhanced Configuration Access Mechanism (ECAM) - * - * See PCI Express Base Specification, Revision 5.0, Version 1.0, - * Section 7.2.2, Table 7-1, p. 677. - */ -#define PCIE_ECAM_BUS_SHIFT 20 /* Bus number */ -#define PCIE_ECAM_DEVFN_SHIFT 12 /* Device and Function number */ - -#define PCIE_ECAM_BUS_MASK 0xff -#define PCIE_ECAM_DEVFN_MASK 0xff -#define PCIE_ECAM_REG_MASK 0xfff /* Limit offset to a maximum of 4K */ - -#define PCIE_ECAM_BUS(x) (((x) & PCIE_ECAM_BUS_MASK) << PCIE_ECAM_BUS_SHIFT) -#define PCIE_ECAM_DEVFN(x) (((x) & PCIE_ECAM_DEVFN_MASK) << PCIE_ECAM_DEVFN_SHIFT) -#define PCIE_ECAM_REG(x) ((x) & PCIE_ECAM_REG_MASK) - -#define PCIE_ECAM_OFFSET(bus, devfn, where) \ - (PCIE_ECAM_BUS(bus) | PCIE_ECAM_DEVFN(devfn) | PCIE_ECAM_REG(where)) - -struct pci_ecam_ops -{ - rt_uint32_t bus_shift; - const struct rt_pci_ops pci_ops; -}; - -struct pci_ecam_config_window -{ - rt_uint32_t *bus_range; - rt_uint32_t bus_shift; - - void *win; - void *priv; - const struct pci_ecam_ops *ops; -}; - -/* Default ECAM ops */ -extern const struct pci_ecam_ops pci_generic_ecam_ops; - -void *pci_ecam_map(struct rt_pci_bus *bus, rt_uint32_t devfn, int where); -struct pci_ecam_config_window *pci_ecam_create(struct rt_pci_host_bridge *host_bridge, - const struct pci_ecam_ops *ops); -rt_err_t pci_host_common_probe(struct rt_platform_device *pdev); -rt_err_t pci_host_common_remove(struct rt_platform_device *pdev); - -#endif /* __RT_PCI_ECAM_H__ */ diff --git a/rt-thread/components/drivers/pci/endpoint/SConscript b/rt-thread/components/drivers/pci/endpoint/SConscript deleted file mode 100644 index 9b76a96..0000000 --- a/rt-thread/components/drivers/pci/endpoint/SConscript +++ /dev/null @@ -1,15 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_PCI_ENDPOINT']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../../include'] - -src = ['endpoint.c', 'mem.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/pci/endpoint/endpoint.c b/rt-thread/components/drivers/pci/endpoint/endpoint.c deleted file mode 100644 index 3783f4e..0000000 --- a/rt-thread/components/drivers/pci/endpoint/endpoint.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-08-25 GuEe-GUI first version - */ - -#include - -#define DBG_TAG "pci.ep" -#define DBG_LVL DBG_INFO -#include - -static rt_list_t _ep_nodes = RT_LIST_OBJECT_INIT(_ep_nodes); -static struct rt_spinlock _ep_lock = { 0 }; - -rt_err_t rt_pci_ep_write_header(struct rt_pci_ep *ep, rt_uint8_t func_no, - struct rt_pci_ep_header *hdr) -{ - rt_err_t err; - - if (ep && ep->ops && hdr && func_no < ep->max_functions) - { - if (ep->ops->write_header) - { - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - err = ep->ops->write_header(ep, func_no, hdr); - rt_mutex_release(&ep->lock); - } - else - { - err = -RT_ENOSYS; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_ep_set_bar(struct rt_pci_ep *ep, rt_uint8_t func_no, - struct rt_pci_ep_bar *bar, int bar_idx) -{ - rt_err_t err = RT_EOK; - - if (ep && ep->ops && func_no < ep->max_functions && bar && - bar_idx < PCI_STD_NUM_BARS) - { - struct rt_pci_bus_resource *bus_bar = &bar->bus; - - if (bar_idx == (PCI_STD_NUM_BARS - 1) && - (bus_bar->flags & PCIM_BAR_MEM_TYPE_64)) - { - err = -RT_EINVAL; - LOG_E("%s: Set BAR[%d] can't not 64bit", ep->name, bar_idx); - } - - if (rt_upper_32_bits(bus_bar->size) && - !(bus_bar->flags & PCIM_BAR_MEM_TYPE_64)) - { - err = -RT_EINVAL; - LOG_E("%s: Set BAR[%d] size is no support 64bit", ep->name, bar_idx); - } - - if ((bus_bar->flags & PCIM_BAR_SPACE_IO) && - (bus_bar->flags & PCIM_BAR_IO_MASK)) - { - err = -RT_EINVAL; - LOG_E("%s: Set BAR[%d] io flags is invalid", ep->name, bar_idx); - } - - if (!err) - { - if (ep->ops->set_bar) - { - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - err = ep->ops->set_bar(ep, func_no, bar, bar_idx); - rt_mutex_release(&ep->lock); - } - else - { - err = -RT_ENOSYS; - } - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_ep_clear_bar(struct rt_pci_ep *ep, rt_uint8_t func_no, - struct rt_pci_ep_bar *bar, int bar_idx) -{ - rt_err_t err; - - if (ep && ep->ops && func_no < ep->max_functions && bar && - bar_idx < PCI_STD_NUM_BARS) - { - if (ep->ops->clear_bar) - { - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - err = ep->ops->clear_bar(ep, func_no, bar, bar_idx); - rt_mutex_release(&ep->lock); - } - else - { - err = -RT_ENOSYS; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_ep_map_addr(struct rt_pci_ep *ep, rt_uint8_t func_no, - rt_ubase_t addr, rt_uint64_t pci_addr, rt_size_t size) -{ - rt_err_t err; - - if (ep && ep->ops && func_no < ep->max_functions && size) - { - if (ep->ops->map_addr) - { - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - err = ep->ops->map_addr(ep, func_no, addr, pci_addr, size); - rt_mutex_release(&ep->lock); - } - else - { - err = -RT_ENOSYS; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_ep_unmap_addr(struct rt_pci_ep *ep, rt_uint8_t func_no, - rt_ubase_t addr) -{ - rt_err_t err; - - if (ep && ep->ops && func_no < ep->max_functions) - { - if (ep->ops->unmap_addr) - { - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - err = ep->ops->unmap_addr(ep, func_no, addr); - rt_mutex_release(&ep->lock); - } - else - { - err = -RT_ENOSYS; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_ep_set_msi(struct rt_pci_ep *ep, rt_uint8_t func_no, - unsigned irq_nr) -{ - rt_err_t err; - - if (ep && ep->ops && func_no < ep->max_functions) - { - if (ep->ops->set_msix) - { - err = -RT_EINVAL; - - for (int log2 = 0; log2 < 5; ++log2) - { - if (irq_nr <= (1 << log2)) - { - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - err = ep->ops->set_msi(ep, func_no, log2); - rt_mutex_release(&ep->lock); - } - } - } - else - { - err = -RT_ENOSYS; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_ep_get_msi(struct rt_pci_ep *ep, rt_uint8_t func_no, - unsigned *out_irq_nr) -{ - rt_err_t err; - - if (ep && ep->ops && func_no < ep->max_functions && out_irq_nr) - { - if (ep->ops->get_msi) - { - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - err = ep->ops->get_msi(ep, func_no, out_irq_nr); - rt_mutex_release(&ep->lock); - } - else - { - err = -RT_ENOSYS; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_ep_set_msix(struct rt_pci_ep *ep, rt_uint8_t func_no, - unsigned irq_nr, int bar_idx, rt_off_t offset) -{ - rt_err_t err; - - if (ep && ep->ops && func_no < ep->max_functions && irq_nr < 2048 && - bar_idx < PCI_STD_NUM_BARS) - { - if (ep->ops->set_msix) - { - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - err = ep->ops->set_msix(ep, func_no, irq_nr, bar_idx, offset); - rt_mutex_release(&ep->lock); - } - else - { - err = -RT_ENOSYS; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_ep_get_msix(struct rt_pci_ep *ep, rt_uint8_t func_no, - unsigned *out_irq_nr) -{ - rt_err_t err; - - if (ep && ep->ops && func_no < ep->max_functions && out_irq_nr) - { - if (ep->ops->get_msix) - { - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - err = ep->ops->get_msix(ep, func_no, out_irq_nr); - rt_mutex_release(&ep->lock); - } - else - { - err = -RT_ENOSYS; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_ep_raise_irq(struct rt_pci_ep *ep, rt_uint8_t func_no, - enum rt_pci_ep_irq type, unsigned irq) -{ - rt_err_t err; - - if (ep && ep->ops && func_no < ep->max_functions) - { - if (ep->ops->raise_irq) - { - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - err = ep->ops->raise_irq(ep, func_no, type, irq); - rt_mutex_release(&ep->lock); - } - else - { - err = -RT_ENOSYS; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_ep_start(struct rt_pci_ep *ep) -{ - rt_err_t err; - - if (ep && ep->ops) - { - if (ep->ops->start) - { - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - err = ep->ops->start(ep); - rt_mutex_release(&ep->lock); - } - else - { - err = -RT_ENOSYS; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_ep_stop(struct rt_pci_ep *ep) -{ - rt_err_t err; - - if (ep && ep->ops) - { - if (ep->ops->stop) - { - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - err = ep->ops->stop(ep); - rt_mutex_release(&ep->lock); - } - else - { - err = -RT_ENOSYS; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_ep_register(struct rt_pci_ep *ep) -{ - rt_ubase_t level; - - if (!ep || !ep->ops) - { - return -RT_EINVAL; - } - - rt_list_init(&ep->list); - rt_ref_init(&ep->ref); - - rt_list_init(&ep->epf_nodes); - rt_mutex_init(&ep->lock, ep->name, RT_IPC_FLAG_PRIO); - - level = rt_spin_lock_irqsave(&_ep_lock); - rt_list_insert_before(&_ep_nodes, &ep->list); - rt_spin_unlock_irqrestore(&_ep_lock, level); - - return RT_EOK; -} - -rt_err_t rt_pci_ep_unregister(struct rt_pci_ep *ep) -{ - rt_ubase_t level; - rt_err_t err = RT_EOK; - - if (!ep) - { - return -RT_EINVAL; - } - - level = rt_spin_lock_irqsave(&_ep_lock); - - if (rt_ref_read(&ep->ref) > 1) - { - err = -RT_EBUSY; - } - else - { - rt_list_remove(&ep->list); - rt_mutex_detach(&ep->lock); - } - - rt_spin_unlock_irqrestore(&_ep_lock, level); - - return err; -} - -rt_err_t rt_pci_ep_add_epf(struct rt_pci_ep *ep, struct rt_pci_epf *epf) -{ - rt_err_t err = RT_EOK; - - if (!ep || !epf || !epf->name) - { - return -RT_EINVAL; - } - - if (epf->func_no > ep->max_functions - 1) - { - LOG_E("%s function No(%d) > %s max function No(%d - 1)", - epf->name, epf->func_no, ep->name, ep->max_functions); - - return -RT_EINVAL; - } - - epf->ep = ep; - rt_list_init(&epf->list); - - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - - if (!rt_bitmap_test_bit(ep->functions_map, epf->func_no)) - { - rt_bitmap_set_bit(ep->functions_map, epf->func_no); - rt_list_insert_before(&ep->epf_nodes, &epf->list); - } - else - { - err = -RT_EINVAL; - LOG_E("%s function No(%d) is repeating", epf->name, epf->func_no); - } - - rt_mutex_release(&ep->lock); - - return err; -} - -rt_err_t rt_pci_ep_remove_epf(struct rt_pci_ep *ep, struct rt_pci_epf *epf) -{ - if (!ep || !epf) - { - return -RT_EINVAL; - } - - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - rt_bitmap_clear_bit(ep->functions_map, epf->func_no); - rt_list_remove(&epf->list); - rt_mutex_release(&ep->lock); - - return RT_EOK; -} - -struct rt_pci_ep *rt_pci_ep_get(const char *name) -{ - rt_ubase_t level; - struct rt_pci_ep *ep = RT_NULL, *ep_tmp; - - level = rt_spin_lock_irqsave(&_ep_lock); - - rt_list_for_each_entry(ep_tmp, &_ep_nodes, list) - { - if (!name || !rt_strcmp(ep_tmp->name, name)) - { - ep = ep_tmp; - rt_ref_get(&ep->ref); - break; - } - } - - rt_spin_unlock_irqrestore(&_ep_lock, level); - - return ep; -} - -static void pci_ep_release(struct rt_ref *ref) -{ - struct rt_pci_ep *ep = rt_container_of(ref, struct rt_pci_ep, ref); - - rt_pci_ep_unregister(ep); -} - -void rt_pci_ep_put(struct rt_pci_ep *ep) -{ - if (ep) - { - rt_ref_put(&ep->ref, &pci_ep_release); - } -} diff --git a/rt-thread/components/drivers/pci/endpoint/mem.c b/rt-thread/components/drivers/pci/endpoint/mem.c deleted file mode 100644 index 297db16..0000000 --- a/rt-thread/components/drivers/pci/endpoint/mem.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-08-25 GuEe-GUI first version - */ - -#include - -#define DBG_TAG "pci.ep.mem" -#define DBG_LVL DBG_INFO -#include - -rt_err_t rt_pci_ep_mem_array_init(struct rt_pci_ep *ep, - struct rt_pci_ep_mem *mems, rt_size_t mems_nr) -{ - rt_size_t idx; - rt_err_t err = RT_EOK; - - if (!ep || !mems) - { - return -RT_EINVAL; - } - - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - - ep->mems_nr = mems_nr; - ep->mems = rt_calloc(mems_nr, sizeof(*ep->mems)); - - if (!ep->mems) - { - return -RT_ENOMEM; - } - - for (idx = 0; idx < mems_nr; ++idx) - { - struct rt_pci_ep_mem *mem = &ep->mems[idx]; - - mem->cpu_addr = mems->cpu_addr; - mem->size = mems->size; - mem->page_size = mems->page_size; - mem->bits = mems->size / mems->page_size; - mem->map = rt_calloc(RT_BITMAP_LEN(mem->bits), sizeof(*mem->map)); - - if (!mem->map) - { - err = -RT_ENOMEM; - goto _out_lock; - } - } - -_out_lock: - if (err) - { - while (idx --> 0) - { - rt_free(ep->mems[idx].map); - } - rt_free(ep->mems); - - ep->mems_nr = 0; - ep->mems = RT_NULL; - } - - rt_mutex_release(&ep->lock); - - return err; -} - -rt_err_t rt_pci_ep_mem_init(struct rt_pci_ep *ep, - rt_ubase_t cpu_addr, rt_size_t size, rt_size_t page_size) -{ - struct rt_pci_ep_mem mem; - - if (!ep) - { - return -RT_EINVAL; - } - - mem.cpu_addr = cpu_addr; - mem.size = size; - mem.page_size = page_size; - - return rt_pci_ep_mem_array_init(ep, &mem, 1); -} - -static rt_ubase_t bitmap_region_alloc(struct rt_pci_ep_mem *mem, rt_size_t size) -{ - rt_size_t bit, next_bit, end_bit, max_bits; - - size /= mem->page_size; - max_bits = mem->bits - size; - - rt_bitmap_for_each_clear_bit(mem->map, bit, max_bits) - { - end_bit = bit + size; - - for (next_bit = bit + 1; next_bit < end_bit; ++next_bit) - { - if (rt_bitmap_test_bit(mem->map, next_bit)) - { - bit = next_bit; - goto _next; - } - } - - if (next_bit == end_bit) - { - while (next_bit --> bit) - { - rt_bitmap_set_bit(mem->map, next_bit); - } - - return mem->cpu_addr + bit * mem->page_size; - } - _next: - } - - return ~0ULL; -} - -static void bitmap_region_free(struct rt_pci_ep_mem *mem, - rt_ubase_t cpu_addr, rt_size_t size) -{ - rt_size_t bit = (cpu_addr - mem->cpu_addr) / mem->page_size, end_bit; - - size /= mem->page_size; - end_bit = bit + size; - - for (; bit < end_bit; ++bit) - { - rt_bitmap_clear_bit(mem->map, bit); - } -} - -void *rt_pci_ep_mem_alloc(struct rt_pci_ep *ep, - rt_ubase_t *out_cpu_addr, rt_size_t size) -{ - void *vaddr = RT_NULL; - - if (!ep || !out_cpu_addr) - { - return vaddr; - } - - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - - for (rt_size_t idx = 0; idx < ep->mems_nr; ++idx) - { - rt_ubase_t cpu_addr; - struct rt_pci_ep_mem *mem = &ep->mems[idx]; - - cpu_addr = bitmap_region_alloc(mem, size); - - if (cpu_addr != ~0ULL) - { - vaddr = rt_ioremap((void *)cpu_addr, size); - - if (!vaddr) - { - bitmap_region_free(mem, cpu_addr, size); - - /* Try next memory */ - continue; - } - - *out_cpu_addr = cpu_addr; - break; - } - } - - rt_mutex_release(&ep->lock); - - return vaddr; -} - -void rt_pci_ep_mem_free(struct rt_pci_ep *ep, - void *vaddr, rt_ubase_t cpu_addr, rt_size_t size) -{ - if (!ep || !vaddr || !size) - { - return; - } - - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - - for (rt_size_t idx = 0; idx < ep->mems_nr; ++idx) - { - struct rt_pci_ep_mem *mem = &ep->mems[idx]; - - if (mem->cpu_addr > cpu_addr && - mem->cpu_addr + mem->size >= cpu_addr + size) - { - rt_iounmap(mem); - bitmap_region_free(mem, cpu_addr, size); - - break; - } - } - - rt_mutex_release(&ep->lock); -} diff --git a/rt-thread/components/drivers/pci/host-bridge.c b/rt-thread/components/drivers/pci/host-bridge.c deleted file mode 100644 index ada7ef6..0000000 --- a/rt-thread/components/drivers/pci/host-bridge.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#include - -#include -#include - -#ifdef RT_USING_PM -struct host_bridge_pm_status -{ - rt_uint8_t mode; - rt_bool_t enable; -}; - -static const enum rt_pci_power system_pci_pm_mode[] = -{ - [PM_SLEEP_MODE_NONE] = RT_PCI_D0, - [PM_SLEEP_MODE_IDLE] = RT_PCI_D3HOT, - [PM_SLEEP_MODE_LIGHT] = RT_PCI_D1, - [PM_SLEEP_MODE_DEEP] = RT_PCI_D1, - [PM_SLEEP_MODE_STANDBY] = RT_PCI_D2, - [PM_SLEEP_MODE_SHUTDOWN] = RT_PCI_D3COLD, -}; - -static rt_bool_t pci_device_pm_ops(struct rt_pci_device *pdev, void *data) -{ - struct host_bridge_pm_status *status = data; - - rt_pci_enable_wake(pdev, system_pci_pm_mode[status->mode], status->enable); - - /* To find all devices, always return false */ - return RT_FALSE; -} - -static rt_err_t host_bridge_pm_suspend(const struct rt_device *device, rt_uint8_t mode) -{ - struct host_bridge_pm_status status; - struct rt_pci_device *pdev = rt_container_of(device, struct rt_pci_device, parent); - - status.mode = mode; - status.enable = RT_FALSE; - rt_pci_enum_device(pdev->bus, pci_device_pm_ops, &status); - - return RT_EOK; -} - -static void host_bridge_pm_resume(const struct rt_device *device, rt_uint8_t mode) -{ - struct host_bridge_pm_status status; - struct rt_pci_device *pdev = rt_container_of(device, struct rt_pci_device, parent); - - status.mode = mode; - status.enable = RT_TRUE; - rt_pci_enum_device(pdev->bus, pci_device_pm_ops, &status); -} - -static const struct rt_device_pm_ops host_bridge_pm_ops = -{ - .suspend = host_bridge_pm_suspend, - .resume = host_bridge_pm_resume, -}; -#endif /* RT_USING_PM */ - -static void host_bridge_free(struct rt_pci_device *pdev) -{ -#ifdef RT_USING_PM - rt_pm_device_unregister(&pdev->parent); -#endif -} - -static rt_err_t host_bridge_probe(struct rt_pci_device *pdev) -{ - rt_err_t err = RT_EOK; - - rt_pci_set_master(pdev); - -#ifdef RT_USING_PM - rt_pm_device_register(&pdev->parent, &host_bridge_pm_ops); -#endif - - return err; -} - -static rt_err_t host_bridge_remove(struct rt_pci_device *pdev) -{ - host_bridge_free(pdev); - rt_pci_clear_master(pdev); - - return RT_EOK; -} - -static rt_err_t host_bridge_shutdown(struct rt_pci_device *pdev) -{ - host_bridge_free(pdev); - - return RT_EOK; -} - -static const struct rt_pci_device_id host_bridge_pci_ids[] = -{ - /* PCI host bridges */ - { RT_PCI_DEVICE_ID(PCI_VENDOR_ID_REDHAT, 0x0008) }, - /* Any PCI-Express port */ - { RT_PCI_DEVICE_CLASS(PCIS_BRIDGE_PCI_NORMAL, ~0) }, - /* PCI-to-PCI bridge */ - { RT_PCI_DEVICE_CLASS(PCIS_BRIDGE_PCI_SUBTRACTIVE, ~0) }, - /* Any Root Complex Event Collector */ - { RT_PCI_DEVICE_CLASS(((PCIS_SYSTEM_RCEC << 8) | 0x00), ~0) }, - { /* sentinel */ } -}; - -static struct rt_pci_driver host_bridge_driver = -{ - .name = "host-bridge", - - .ids = host_bridge_pci_ids, - .probe = host_bridge_probe, - .remove = host_bridge_remove, - .shutdown = host_bridge_shutdown, -}; -RT_PCI_DRIVER_EXPORT(host_bridge_driver); diff --git a/rt-thread/components/drivers/pci/host/Kconfig b/rt-thread/components/drivers/pci/host/Kconfig deleted file mode 100644 index 221c997..0000000 --- a/rt-thread/components/drivers/pci/host/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -config RT_PCI_HOST_COMMON - bool "Common PCI host controller" - depends on RT_PCI_ECAM - default y - -config RT_PCI_HOST_GENERIC - bool "Generic PCI host controller" - depends on RT_PCI_ECAM - select RT_PCI_HOST_COMMON - default y - -rsource "dw/Kconfig" diff --git a/rt-thread/components/drivers/pci/host/SConscript b/rt-thread/components/drivers/pci/host/SConscript deleted file mode 100644 index 91555f8..0000000 --- a/rt-thread/components/drivers/pci/host/SConscript +++ /dev/null @@ -1,25 +0,0 @@ -from building import * - -objs = [] - -cwd = GetCurrentDir() -list = os.listdir(cwd) -CPPPATH = [cwd + '/../../include'] - -src = [] - -if GetDepend(['RT_PCI_HOST_COMMON']): - src += ['pci-host-common.c'] - -if GetDepend(['RT_PCI_HOST_GENERIC']): - src += ['pci-host-generic.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -for d in list: - path = os.path.join(cwd, d) - if os.path.isfile(os.path.join(path, 'SConscript')): - objs = objs + SConscript(os.path.join(d, 'SConscript')) -objs = objs + group - -Return('objs') diff --git a/rt-thread/components/drivers/pci/host/dw/Kconfig b/rt-thread/components/drivers/pci/host/dw/Kconfig deleted file mode 100644 index e76011b..0000000 --- a/rt-thread/components/drivers/pci/host/dw/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -config RT_PCI_DW - bool "DesignWare-based PCIe" - depends on RT_MFD_SYSCON - depends on RT_USING_DMA - default n - -config RT_PCI_DW_HOST - bool - depends on RT_PCI_DW - -config RT_PCI_DW_EP - bool - depends on RT_PCI_DW diff --git a/rt-thread/components/drivers/pci/host/dw/SConscript b/rt-thread/components/drivers/pci/host/dw/SConscript deleted file mode 100644 index ca6c031..0000000 --- a/rt-thread/components/drivers/pci/host/dw/SConscript +++ /dev/null @@ -1,21 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_PCI_DW']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../../../include'] - -src = ['pcie-dw.c', 'pcie-dw_platfrom.c'] - -if GetDepend(['RT_PCI_DW_HOST']): - src += ['pcie-dw_host.c'] - -if GetDepend(['RT_PCI_DW_EP']): - src += ['pcie-dw_ep.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/pci/host/dw/pcie-dw.c b/rt-thread/components/drivers/pci/host/dw/pcie-dw.c deleted file mode 100644 index 2cca6f1..0000000 --- a/rt-thread/components/drivers/pci/host/dw/pcie-dw.c +++ /dev/null @@ -1,645 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#define DBG_TAG "pcie.dw" -#define DBG_LVL DBG_INFO -#include - -#include "pcie-dw.h" - -static rt_uint8_t __dw_pcie_find_next_cap(struct dw_pcie *pci, - rt_uint8_t cap_ptr, rt_uint8_t cap) -{ - rt_uint16_t reg; - rt_uint8_t cap_id, next_cap_ptr; - - if (!cap_ptr) - { - return 0; - } - - reg = dw_pcie_readw_dbi(pci, cap_ptr); - cap_id = (reg & 0x00ff); - - if (cap_id > PCIY_MAX) - { - return 0; - } - - if (cap_id == cap) - { - return cap_ptr; - } - - next_cap_ptr = (reg & 0xff00) >> 8; - return __dw_pcie_find_next_cap(pci, next_cap_ptr, cap); -} - -rt_uint8_t dw_pcie_find_capability(struct dw_pcie *pci, rt_uint8_t cap) -{ - rt_uint16_t reg; - rt_uint8_t next_cap_ptr; - - reg = dw_pcie_readw_dbi(pci, PCIR_CAP_PTR); - next_cap_ptr = (reg & 0x00ff); - - return __dw_pcie_find_next_cap(pci, next_cap_ptr, cap); -} - -static rt_uint16_t dw_pcie_find_next_ext_capability(struct dw_pcie *pci, - rt_uint16_t start, rt_uint8_t cap) -{ - rt_uint32_t header; - int ttl, pos = PCI_REGMAX + 1; - - /* minimum 8 bytes per capability */ - ttl = ((PCIE_REGMAX + 1) - (PCI_REGMAX + 1)) / 8; - - if (start) - { - pos = start; - } - - header = dw_pcie_readl_dbi(pci, pos); - /* - * If we have no capabilities, this is indicated by cap ID, - * cap version and next pointer all being 0. - */ - if (header == 0) - { - return 0; - } - - while (ttl-- > 0) - { - if (PCI_EXTCAP_ID(header) == cap && pos != start) - { - return pos; - } - - pos = PCI_EXTCAP_NEXTPTR(header); - - if (pos < PCI_REGMAX + 1) - { - break; - } - - header = dw_pcie_readl_dbi(pci, pos); - } - - return 0; -} - -rt_uint16_t dw_pcie_find_ext_capability(struct dw_pcie *pci, rt_uint8_t cap) -{ - return dw_pcie_find_next_ext_capability(pci, 0, cap); -} - -rt_err_t dw_pcie_read(void *addr, rt_size_t size, rt_uint32_t *out_val) -{ - /* Check aligned */ - if ((rt_ubase_t)addr & ((rt_ubase_t)size - 1)) - { - *out_val = 0; - return -RT_EINVAL; - } - - if (size == 4) - { - *out_val = HWREG32(addr); - } - else if (size == 2) - { - *out_val = HWREG16(addr); - } - else if (size == 1) - { - *out_val = HWREG8(addr); - } - else - { - *out_val = 0; - return -RT_EINVAL; - } - - return RT_EOK; -} - -rt_err_t dw_pcie_write(void *addr, rt_size_t size, rt_uint32_t val) -{ - /* Check aligned */ - if ((rt_ubase_t)addr & ((rt_ubase_t)size - 1)) - { - return -RT_EINVAL; - } - - if (size == 4) - { - HWREG32(addr) = val; - } - else if (size == 2) - { - HWREG16(addr) = val; - } - else if (size == 1) - { - HWREG8(addr) = val; - } - else - { - return -RT_EINVAL; - } - - return RT_EOK; -} - -rt_uint32_t dw_pcie_read_dbi(struct dw_pcie *pci, rt_uint32_t reg, rt_size_t size) -{ - rt_err_t err; - rt_uint32_t val = 0; - - if (pci->ops->read_dbi) - { - return pci->ops->read_dbi(pci, pci->dbi_base, reg, size); - } - - if ((err = dw_pcie_read(pci->dbi_base + reg, size, &val))) - { - LOG_E("Read DBI address error = %s", rt_strerror(err)); - } - - return val; -} - -void dw_pcie_write_dbi(struct dw_pcie *pci, rt_uint32_t reg, rt_size_t size, rt_uint32_t val) -{ - rt_err_t err; - - if (pci->ops->write_dbi) - { - pci->ops->write_dbi(pci, pci->dbi_base, reg, size, val); - return; - } - - if ((err = dw_pcie_write(pci->dbi_base + reg, size, val))) - { - LOG_E("Write DBI address error = %s", rt_strerror(err)); - } -} - -void dw_pcie_write_dbi2(struct dw_pcie *pci, rt_uint32_t reg, rt_size_t size, rt_uint32_t val) -{ - rt_err_t err; - - if (pci->ops && pci->ops->write_dbi2) - { - pci->ops->write_dbi2(pci, pci->dbi_base2, reg, size, val); - return; - } - - if ((err = dw_pcie_write(pci->dbi_base2 + reg, size, val))) - { - LOG_E("Write DBI2 address error = %s", rt_strerror(err)); - } -} - -rt_uint32_t dw_pcie_readl_atu(struct dw_pcie *pci, rt_uint32_t reg) -{ - rt_err_t err; - rt_uint32_t val = 0; - - if (pci->ops->read_dbi) - { - return pci->ops->read_dbi(pci, pci->atu_base, reg, 4); - } - - if ((err = dw_pcie_read(pci->atu_base + reg, 4, &val))) - { - LOG_E("Read ATU address error = %s", rt_strerror(err)); - } - - return val; -} - -void dw_pcie_writel_atu(struct dw_pcie *pci, rt_uint32_t reg, rt_uint32_t val) -{ - rt_err_t err; - - if (pci->ops->write_dbi) - { - pci->ops->write_dbi(pci, pci->atu_base, reg, 4, val); - return; - } - - if ((err = dw_pcie_write(pci->atu_base + reg, 4, val))) - { - LOG_E("Write ATU address error = %s", rt_strerror(err)); - } -} - -static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, rt_uint8_t func_no, - int index, int type, rt_uint64_t cpu_addr, rt_uint64_t pci_addr, rt_size_t size) -{ - rt_uint64_t limit_addr = cpu_addr + size - 1; - - dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_BASE, - rt_lower_32_bits(cpu_addr)); - dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_BASE, - rt_upper_32_bits(cpu_addr)); - dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_LIMIT, - rt_lower_32_bits(limit_addr)); - dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_LIMIT, - rt_upper_32_bits(limit_addr)); - dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_TARGET, - rt_lower_32_bits(pci_addr)); - dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET, - rt_upper_32_bits(pci_addr)); - dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, - type | PCIE_ATU_FUNC_NUM(func_no)); - dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2, - PCIE_ATU_ENABLE); - - /* - * Make sure ATU enable takes effect before any subsequent config - * and I/O accesses. - */ - for (int retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; ++retries) - { - if (dw_pcie_readl_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2) & PCIE_ATU_ENABLE) - { - return; - } - - rt_thread_mdelay(LINK_WAIT_IATU); - } - - LOG_E("Outbound iATU is not being enabled"); -} - -static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, rt_uint8_t func_no, - int index, int type, rt_uint64_t cpu_addr, rt_uint64_t pci_addr, rt_size_t size) -{ - if (pci->ops->cpu_addr_fixup) - { - cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr); - } - - if (pci->iatu_unroll_enabled & DWC_IATU_UNROLL_EN) - { - dw_pcie_prog_outbound_atu_unroll(pci, func_no, - index, type, cpu_addr, pci_addr, size); - - return; - } - - dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, PCIE_ATU_REGION_OUTBOUND | index); - dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_BASE, rt_lower_32_bits(cpu_addr)); - dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_BASE, rt_upper_32_bits(cpu_addr)); - dw_pcie_writel_dbi(pci, PCIE_ATU_LIMIT, rt_lower_32_bits(cpu_addr + size - 1)); - dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET, rt_lower_32_bits(pci_addr)); - dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET, rt_upper_32_bits(pci_addr)); - dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type | PCIE_ATU_FUNC_NUM(func_no)); - dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE); - - /* - * Make sure ATU enable takes effect before any subsequent config - * and I/O accesses. - */ - for (int retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; ++retries) - { - if (dw_pcie_readl_dbi(pci, PCIE_ATU_CR2) & PCIE_ATU_ENABLE) - { - return; - } - - rt_thread_mdelay(LINK_WAIT_IATU); - } - - LOG_E("Outbound iATU is not being enabled"); -} - -void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, - int index, int type, rt_uint64_t cpu_addr, rt_uint64_t pci_addr, rt_size_t size) -{ - __dw_pcie_prog_outbound_atu(pci, 0, index, type, cpu_addr, pci_addr, size); -} - -void dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, rt_uint8_t func_no, - int index, int type, rt_uint64_t cpu_addr, rt_uint64_t pci_addr, rt_size_t size) -{ - __dw_pcie_prog_outbound_atu(pci, func_no, index, type, cpu_addr, pci_addr, size); -} - -static rt_err_t dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, - rt_uint8_t func_no, int index, int bar, rt_uint64_t cpu_addr, - enum dw_pcie_aspace_type aspace_type) -{ - int type; - - dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_LOWER_TARGET, - rt_lower_32_bits(cpu_addr)); - dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET, - rt_upper_32_bits(cpu_addr)); - - switch (aspace_type) - { - case DW_PCIE_ASPACE_MEM: - type = PCIE_ATU_TYPE_MEM; - break; - - case DW_PCIE_ASPACE_IO: - type = PCIE_ATU_TYPE_IO; - break; - - default: - return -RT_EINVAL; - } - - dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, - type | PCIE_ATU_FUNC_NUM(func_no)); - dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2, - PCIE_ATU_FUNC_NUM_MATCH_EN | PCIE_ATU_ENABLE | - PCIE_ATU_BAR_MODE_ENABLE | (bar << 8)); - - /* - * Make sure ATU enable takes effect before any subsequent config - * and I/O accesses. - */ - for (int retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; ++retries) - { - if (dw_pcie_readl_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2) & PCIE_ATU_ENABLE) - { - return RT_EOK; - } - - rt_thread_mdelay(LINK_WAIT_IATU); - } - - LOG_E("Inbound iATU is not being enabled"); - - return -RT_EBUSY; -} - -rt_err_t dw_pcie_prog_inbound_atu(struct dw_pcie *pci, - rt_uint8_t func_no, int index, int bar, rt_uint64_t cpu_addr, - enum dw_pcie_aspace_type aspace_type) -{ - int type; - - if (pci->iatu_unroll_enabled & DWC_IATU_UNROLL_EN) - { - return dw_pcie_prog_inbound_atu_unroll(pci, func_no, - index, bar, cpu_addr, aspace_type); - } - - dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, PCIE_ATU_REGION_INBOUND | index); - dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET, rt_lower_32_bits(cpu_addr)); - dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET, rt_upper_32_bits(cpu_addr)); - - switch (aspace_type) - { - case DW_PCIE_ASPACE_MEM: - type = PCIE_ATU_TYPE_MEM; - break; - - case DW_PCIE_ASPACE_IO: - type = PCIE_ATU_TYPE_IO; - break; - - default: - return -RT_EINVAL; - } - - dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type | PCIE_ATU_FUNC_NUM(func_no)); - dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE | - PCIE_ATU_FUNC_NUM_MATCH_EN | PCIE_ATU_BAR_MODE_ENABLE | (bar << 8)); - - /* - * Make sure ATU enable takes effect before any subsequent config - * and I/O accesses. - */ - for (int retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; ++retries) - { - if (dw_pcie_readl_dbi(pci, PCIE_ATU_CR2) & PCIE_ATU_ENABLE) - { - return RT_EOK; - } - - rt_thread_mdelay(LINK_WAIT_IATU); - } - - LOG_E("Inbound iATU is not being enabled"); - - return -RT_EBUSY; -} - -void dw_pcie_disable_atu(struct dw_pcie *pci, int index, enum dw_pcie_region_type type) -{ - rt_uint32_t region; - - switch (type) - { - case DW_PCIE_REGION_INBOUND: - region = PCIE_ATU_REGION_INBOUND; - break; - - case DW_PCIE_REGION_OUTBOUND: - region = PCIE_ATU_REGION_OUTBOUND; - break; - - default: - return; - } - - if (pci->iatu_unroll_enabled) - { - if (region == PCIE_ATU_REGION_INBOUND) - { - dw_pcie_writel_ib_unroll(pci, index, - PCIE_ATU_UNR_REGION_CTRL2, ~(rt_uint32_t)PCIE_ATU_ENABLE); - } - else - { - dw_pcie_writel_ob_unroll(pci, index, - PCIE_ATU_UNR_REGION_CTRL2, ~(rt_uint32_t)PCIE_ATU_ENABLE); - } - } - else - { - dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index); - dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, ~(rt_uint32_t)PCIE_ATU_ENABLE); - } -} - -rt_err_t dw_pcie_wait_for_link(struct dw_pcie *pci) -{ - /* Check if the link is up or not */ - for (int retries = 0; retries < LINK_WAIT_MAX_RETRIES; ++retries) - { - if (dw_pcie_link_up(pci)) - { - LOG_I("%s: Link up", rt_dm_dev_get_name(pci->dev)); - - return RT_EOK; - } - - rt_hw_us_delay((LINK_WAIT_USLEEP_MIN + LINK_WAIT_USLEEP_MAX) >> 1); - } - - LOG_I("PHY link never came up"); - - return -RT_ETIMEOUT; -} - -rt_bool_t dw_pcie_link_up(struct dw_pcie *pci) -{ - rt_uint32_t val; - - if (pci->ops->link_up) - { - return pci->ops->link_up(pci); - } - - val = HWREG32(pci->dbi_base + PCIE_PORT_DEBUG1); - - return (val & PCIE_PORT_DEBUG1_LINK_UP) && (!(val & PCIE_PORT_DEBUG1_LINK_IN_TRAINING)); -} - -void dw_pcie_upconfig_setup(struct dw_pcie *pci) -{ - rt_uint32_t val; - - val = dw_pcie_readl_dbi(pci, PCIE_PORT_MULTI_LANE_CTRL); - val |= PORT_MLTI_UPCFG_SUPPORT; - dw_pcie_writel_dbi(pci, PCIE_PORT_MULTI_LANE_CTRL, val); -} - -static void dw_pcie_link_set_max_speed(struct dw_pcie *pci, rt_uint32_t link_gen) -{ - rt_uint32_t cap, ctrl2, link_speed; - rt_uint8_t offset = dw_pcie_find_capability(pci, PCIY_EXPRESS); - - cap = dw_pcie_readl_dbi(pci, offset + PCIER_LINK_CAP); - ctrl2 = dw_pcie_readl_dbi(pci, offset + PCIER_LINK_CTL2); - ctrl2 &= ~PCIEM_LNKCTL2_TLS; - - switch (link_gen) - { - case 1: link_speed = PCIEM_LNKCTL2_TLS_2_5GT; break; - case 2: link_speed = PCIEM_LNKCTL2_TLS_5_0GT; break; - case 3: link_speed = PCIEM_LNKCTL2_TLS_8_0GT; break; - case 4: link_speed = PCIEM_LNKCTL2_TLS_16_0GT; break; - default: - /* Use hardware capability */ - link_speed = RT_FIELD_GET(PCIEM_LINK_CAP_MAX_SPEED, cap); - ctrl2 &= ~PCIEM_LNKCTL2_HASD; - break; - } - - dw_pcie_writel_dbi(pci, offset + PCIER_LINK_CTL2, ctrl2 | link_speed); - - cap &= ~((rt_uint32_t)PCIEM_LINK_CAP_MAX_SPEED); - dw_pcie_writel_dbi(pci, offset + PCIER_LINK_CAP, cap | link_speed); -} - -void dw_pcie_setup(struct dw_pcie *pci) -{ - rt_uint32_t val; - struct rt_device *dev = pci->dev; - - if (pci->version >= 0x480a || (!pci->version && dw_pcie_iatu_unroll_enabled(pci))) - { - pci->iatu_unroll_enabled |= DWC_IATU_UNROLL_EN; - - if (!pci->atu_base) - { - pci->atu_base = rt_dm_dev_iomap_by_name(dev, "atu"); - } - - if (!pci->atu_base) - { - pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET; - } - } - - LOG_D("iATU unroll is %sabled", pci->iatu_unroll_enabled & DWC_IATU_UNROLL_EN ? "en" : "dis"); - - if (pci->link_gen > 0) - { - dw_pcie_link_set_max_speed(pci, pci->link_gen); - } - - /* Configure Gen1 N_FTS */ - if (pci->fts_number[0]) - { - val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR); - val &= ~(PORT_AFR_N_FTS_MASK | PORT_AFR_CC_N_FTS_MASK); - val |= PORT_AFR_N_FTS(pci->fts_number[0]); - val |= PORT_AFR_CC_N_FTS(pci->fts_number[0]); - dw_pcie_writel_dbi(pci, PCIE_PORT_AFR, val); - } - - /* Configure Gen2+ N_FTS */ - if (pci->fts_number[1]) - { - val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL); - val &= ~PORT_LOGIC_N_FTS_MASK; - val |= pci->fts_number[1]; - dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val); - } - - val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL); - val &= ~PORT_LINK_FAST_LINK_MODE; - val |= PORT_LINK_DLL_LINK_EN; - dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val); - - if (rt_dm_dev_prop_read_bool(dev, "snps,enable-cdm-check")) - { - val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS); - val |= PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS | PCIE_PL_CHK_REG_CHK_REG_START; - dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val); - } - - rt_dm_dev_prop_read_u32(dev, "num-lanes", &pci->num_lanes); - - if (!pci->num_lanes) - { - LOG_D("Using h/w default number of lanes"); - return; - } - - /* Set the number of lanes */ - val &= ~PORT_LINK_FAST_LINK_MODE; - val &= ~PORT_LINK_MODE_MASK; - switch (pci->num_lanes) - { - case 1: val |= PORT_LINK_MODE_1_LANES; break; - case 2: val |= PORT_LINK_MODE_2_LANES; break; - case 4: val |= PORT_LINK_MODE_4_LANES; break; - case 8: val |= PORT_LINK_MODE_8_LANES; break; - default: - LOG_E("Invail num-lanes = %d", pci->num_lanes); - return; - } - dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val); - - /* Set link width speed control register */ - val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL); - val &= ~PORT_LOGIC_LINK_WIDTH_MASK; - switch (pci->num_lanes) - { - case 1: val |= PORT_LOGIC_LINK_WIDTH_1_LANES; break; - case 2: val |= PORT_LOGIC_LINK_WIDTH_2_LANES; break; - case 4: val |= PORT_LOGIC_LINK_WIDTH_4_LANES; break; - case 8: val |= PORT_LOGIC_LINK_WIDTH_8_LANES; break; - } - val |= pci->user_speed; - dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val); -} diff --git a/rt-thread/components/drivers/pci/host/dw/pcie-dw.h b/rt-thread/components/drivers/pci/host/dw/pcie-dw.h deleted file mode 100644 index 0a1183f..0000000 --- a/rt-thread/components/drivers/pci/host/dw/pcie-dw.h +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#ifndef __PCIE_DESIGNWARE_H__ -#define __PCIE_DESIGNWARE_H__ - -#include -#include - -/* Parameters for the waiting for link up routine */ -#define LINK_WAIT_MAX_RETRIES 10 -#define LINK_WAIT_USLEEP_MIN 90000 -#define LINK_WAIT_USLEEP_MAX 100000 - -/* Parameters for the waiting for iATU enabled routine */ -#define LINK_WAIT_MAX_IATU_RETRIES 5 -#define LINK_WAIT_IATU 9 - -/* Synopsys-specific PCIe configuration registers */ -#define PCIE_PORT_AFR 0x70c -#define PORT_AFR_N_FTS_MASK RT_GENMASK(15, 8) -#define PORT_AFR_N_FTS(n) RT_FIELD_PREP(PORT_AFR_N_FTS_MASK, n) -#define PORT_AFR_CC_N_FTS_MASK RT_GENMASK(23, 16) -#define PORT_AFR_CC_N_FTS(n) RT_FIELD_PREP(PORT_AFR_CC_N_FTS_MASK, n) -#define PORT_AFR_ENTER_ASPM RT_BIT(30) -#define PORT_AFR_L0S_ENTRANCE_LAT_SHIFT 24 -#define PORT_AFR_L0S_ENTRANCE_LAT_MASK RT_GENMASK(26, 24) -#define PORT_AFR_L1_ENTRANCE_LAT_SHIFT 27 -#define PORT_AFR_L1_ENTRANCE_LAT_MASK RT_GENMASK(29, 27) - -#define PCIE_PORT_LINK_CONTROL 0x710 -#define PORT_LINK_LPBK_ENABLE RT_BIT(2) -#define PORT_LINK_DLL_LINK_EN RT_BIT(5) -#define PORT_LINK_FAST_LINK_MODE RT_BIT(7) -#define PORT_LINK_MODE_MASK RT_GENMASK(21, 16) -#define PORT_LINK_MODE(n) RT_FIELD_PREP(PORT_LINK_MODE_MASK, n) -#define PORT_LINK_MODE_1_LANES PORT_LINK_MODE(0x1) -#define PORT_LINK_MODE_2_LANES PORT_LINK_MODE(0x3) -#define PORT_LINK_MODE_4_LANES PORT_LINK_MODE(0x7) -#define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf) - -#define PCIE_PORT_DEBUG0 0x728 -#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f -#define PORT_LOGIC_LTSSM_STATE_L0 0x11 -#define PCIE_PORT_DEBUG1 0x72c -#define PCIE_PORT_DEBUG1_LINK_UP RT_BIT(4) -#define PCIE_PORT_DEBUG1_LINK_IN_TRAINING RT_BIT(29) - -#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80c -#define PORT_LOGIC_N_FTS_MASK RT_GENMASK(7, 0) -#define PORT_LOGIC_SPEED_CHANGE RT_BIT(17) -#define PORT_LOGIC_LINK_WIDTH_MASK RT_GENMASK(12, 8) -#define PORT_LOGIC_LINK_WIDTH(n) RT_FIELD_PREP(PORT_LOGIC_LINK_WIDTH_MASK, n) -#define PORT_LOGIC_LINK_WIDTH_1_LANES PORT_LOGIC_LINK_WIDTH(0x1) -#define PORT_LOGIC_LINK_WIDTH_2_LANES PORT_LOGIC_LINK_WIDTH(0x2) -#define PORT_LOGIC_LINK_WIDTH_4_LANES PORT_LOGIC_LINK_WIDTH(0x4) -#define PORT_LOGIC_LINK_WIDTH_8_LANES PORT_LOGIC_LINK_WIDTH(0x8) - -#define PCIE_MSI_ADDR_LO 0x820 -#define PCIE_MSI_ADDR_HI 0x824 -#define PCIE_MSI_INTR0_ENABLE 0x828 -#define PCIE_MSI_INTR0_MASK 0x82c -#define PCIE_MSI_INTR0_STATUS 0x830 - -#define PCIE_PORT_MULTI_LANE_CTRL 0x8c0 -#define PORT_MLTI_UPCFG_SUPPORT RT_BIT(7) - -#define PCIE_ATU_VIEWPORT 0x900 -#define PCIE_ATU_REGION_INBOUND RT_BIT(31) -#define PCIE_ATU_REGION_OUTBOUND 0 -#define PCIE_ATU_CR1 0x904 -#define PCIE_ATU_TYPE_MEM 0x0 -#define PCIE_ATU_TYPE_IO 0x2 -#define PCIE_ATU_TYPE_CFG0 0x4 -#define PCIE_ATU_TYPE_CFG1 0x5 -#define PCIE_ATU_FUNC_NUM(pf) ((pf) << 20) -#define PCIE_ATU_CR2 0x908 -#define PCIE_ATU_ENABLE RT_BIT(31) -#define PCIE_ATU_BAR_MODE_ENABLE RT_BIT(30) -#define PCIE_ATU_FUNC_NUM_MATCH_EN RT_BIT(19) -#define PCIE_ATU_LOWER_BASE 0x90c -#define PCIE_ATU_UPPER_BASE 0x910 -#define PCIE_ATU_LIMIT 0x914 -#define PCIE_ATU_LOWER_TARGET 0x918 -#define PCIE_ATU_BUS(x) RT_FIELD_PREP(RT_GENMASK(31, 24), x) -#define PCIE_ATU_DEV(x) RT_FIELD_PREP(RT_GENMASK(23, 19), x) -#define PCIE_ATU_FUNC(x) RT_FIELD_PREP(RT_GENMASK(18, 16), x) -#define PCIE_ATU_UPPER_TARGET 0x91c - -#define PCIE_MISC_CONTROL_1_OFF 0x8bc -#define PCIE_DBI_RO_WR_EN RT_BIT(0) - -#define PCIE_MSIX_DOORBELL 0x948 -#define PCIE_MSIX_DOORBELL_PF_SHIFT 24 - -#define PCIE_PL_CHK_REG_CONTROL_STATUS 0xb20 -#define PCIE_PL_CHK_REG_CHK_REG_START RT_BIT(0) -#define PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS RT_BIT(1) -#define PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR RT_BIT(16) -#define PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR RT_BIT(17) -#define PCIE_PL_CHK_REG_CHK_REG_COMPLETE RT_BIT(18) - -#define PCIE_PL_CHK_REG_ERR_ADDR 0xb28 - -/* - * iATU Unroll-specific register definitions - * From 4.80 core version the address translation will be made by unroll - */ -#define PCIE_ATU_UNR_REGION_CTRL1 0x00 -#define PCIE_ATU_UNR_REGION_CTRL2 0x04 -#define PCIE_ATU_UNR_LOWER_BASE 0x08 -#define PCIE_ATU_UNR_UPPER_BASE 0x0C -#define PCIE_ATU_UNR_LOWER_LIMIT 0x10 -#define PCIE_ATU_UNR_LOWER_TARGET 0x14 -#define PCIE_ATU_UNR_UPPER_TARGET 0x18 -#define PCIE_ATU_UNR_UPPER_LIMIT 0x20 - -/* - * The default address offset between dbi_base and atu_base. Root controller - * drivers are not required to initialize atu_base if the offset matches this - * default; the driver core automatically derives atu_base from dbi_base using - * this offset, if atu_base not set. - */ -#define DEFAULT_DBI_ATU_OFFSET (0x3 << 20) - -/* Register address builder */ -#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) ((region) << 9) -#define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) (((region) << 9) | RT_BIT(8)) - -#define MAX_MSI_IRQS 256 -#define MAX_MSI_IRQS_PER_CTRL 32 -#define MAX_MSI_CTRLS (MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL) -#define MSI_REG_CTRL_BLOCK_SIZE 12 -#define MSI_DEF_NUM_VECTORS 32 - -/* Maximum number of inbound/outbound iATUs */ -#define MAX_IATU_IN 256 -#define MAX_IATU_OUT 256 - -#define DWC_IATU_UNROLL_EN RT_BIT(0) -#define DWC_IATU_IOCFG_SHARED RT_BIT(1) - -struct dw_pcie_host_ops; -struct dw_pcie_ep_ops; -struct dw_pcie_ops; - -enum dw_pcie_region_type -{ - DW_PCIE_REGION_UNKNOWN, - DW_PCIE_REGION_INBOUND, - DW_PCIE_REGION_OUTBOUND, -}; - -enum dw_pcie_device_mode -{ - DW_PCIE_UNKNOWN_TYPE, - DW_PCIE_EP_TYPE, - DW_PCIE_LEG_EP_TYPE, - DW_PCIE_RC_TYPE, -}; - -enum dw_pcie_aspace_type -{ - DW_PCIE_ASPACE_UNKNOWN, - DW_PCIE_ASPACE_MEM, - DW_PCIE_ASPACE_IO, -}; - -struct dw_pcie_port -{ - void *cfg0_base; - rt_uint64_t cfg0_addr; - rt_uint64_t cfg0_size; - - rt_ubase_t io_addr; - rt_ubase_t io_bus_addr; - rt_size_t io_size; - - const struct dw_pcie_host_ops *ops; - - int sys_irq; - int msi_irq; - struct rt_pic *irq_pic; - struct rt_pic *msi_pic; - - void *msi_data; - rt_ubase_t msi_data_phy; - - rt_uint32_t irq_count; - rt_uint32_t irq_mask[MAX_MSI_CTRLS]; - - struct rt_pci_host_bridge *bridge; - const struct rt_pci_ops *bridge_child_ops; - - struct rt_spinlock lock; - RT_BITMAP_DECLARE(msi_map, MAX_MSI_IRQS); -}; - -struct dw_pcie_host_ops -{ - rt_err_t (*host_init)(struct dw_pcie_port *port); - rt_err_t (*msi_host_init)(struct dw_pcie_port *port); - void (*set_irq_count)(struct dw_pcie_port *port); -}; - -struct dw_pcie_ep_func -{ - rt_list_t list; - - rt_uint8_t func_no; - rt_uint8_t msi_cap; /* MSI capability offset */ - rt_uint8_t msix_cap; /* MSI-X capability offset */ -}; - -struct dw_pcie_ep -{ - struct rt_pci_ep *epc; - struct rt_pci_ep_bar *epc_bar[PCI_STD_NUM_BARS]; - - rt_list_t func_nodes; - - const struct dw_pcie_ep_ops *ops; - - rt_uint64_t aspace; - rt_uint64_t aspace_size; - rt_size_t page_size; - - rt_uint8_t bar_to_atu[PCI_STD_NUM_BARS]; - rt_ubase_t *outbound_addr; - - rt_bitmap_t *ib_window_map; - rt_bitmap_t *ob_window_map; - rt_uint32_t num_ib_windows; - rt_uint32_t num_ob_windows; - - void *msi_mem; - rt_ubase_t msi_mem_phy; -}; - -struct dw_pcie_ep_ops -{ - rt_err_t (*ep_init)(struct dw_pcie_ep *ep); - rt_err_t (*raise_irq)(struct dw_pcie_ep *ep, rt_uint8_t func_no, enum rt_pci_ep_irq type, unsigned irq); - rt_off_t (*func_select)(struct dw_pcie_ep *ep, rt_uint8_t func_no); -}; - -struct dw_pcie -{ - struct rt_device *dev; - - void *dbi_base; - void *dbi_base2; - void *atu_base; - - rt_uint32_t version; - rt_uint32_t num_viewport; - rt_uint32_t num_lanes; - rt_uint32_t link_gen; - rt_uint32_t user_speed; - rt_uint8_t iatu_unroll_enabled; /* Internal Address Translation Unit */ - rt_uint8_t fts_number[2]; /* Fast Training Sequences */ - - struct dw_pcie_port port; - struct dw_pcie_ep endpoint; - const struct dw_pcie_ops *ops; - - void *priv; -}; - -struct dw_pcie_ops -{ - rt_uint64_t (*cpu_addr_fixup)(struct dw_pcie *pcie, rt_uint64_t cpu_addr); - rt_uint32_t (*read_dbi)(struct dw_pcie *pcie, void *base, rt_uint32_t reg, rt_size_t size); - void (*write_dbi)(struct dw_pcie *pcie, void *base, rt_uint32_t reg, rt_size_t size, rt_uint32_t val); - void (*write_dbi2)(struct dw_pcie *pcie, void *base, rt_uint32_t reg, rt_size_t size, rt_uint32_t val); - rt_bool_t (*link_up)(struct dw_pcie *pcie); - rt_err_t (*start_link)(struct dw_pcie *pcie); - void (*stop_link)(struct dw_pcie *pcie); -}; - -#define to_dw_pcie_from_port(ptr) rt_container_of((ptr), struct dw_pcie, port) -#define to_dw_pcie_from_endpoint(ptr) rt_container_of((ptr), struct dw_pcie, endpoint) - -#ifdef RT_PCI_DW_HOST -#undef RT_PCI_DW_HOST -#define RT_PCI_DW_HOST 1 -#define HOST_API -#define HOST_RET(...) ; -#else -#define HOST_API rt_inline -#define HOST_RET(...) { return __VA_ARGS__; } -#endif - -#ifdef RT_PCI_DW_EP -#undef RT_PCI_DW_EP -#define RT_PCI_DW_EP 1 -#define EP_API -#define EP_RET(...) ; -#else -#define EP_API rt_inline -#define EP_RET(...) { return __VA_ARGS__; } -#endif - -rt_uint8_t dw_pcie_find_capability(struct dw_pcie *pci, rt_uint8_t cap); -rt_uint16_t dw_pcie_find_ext_capability(struct dw_pcie *pci, rt_uint8_t cap); - -rt_err_t dw_pcie_read(void *addr, rt_size_t size, rt_uint32_t *out_val); -rt_err_t dw_pcie_write(void *addr, rt_size_t size, rt_uint32_t val); - -rt_uint32_t dw_pcie_read_dbi(struct dw_pcie *pci, rt_uint32_t reg, rt_size_t size); -void dw_pcie_write_dbi(struct dw_pcie *pci, rt_uint32_t reg, rt_size_t size, rt_uint32_t val); -void dw_pcie_write_dbi2(struct dw_pcie *pci, rt_uint32_t reg, rt_size_t size, rt_uint32_t val); -rt_uint32_t dw_pcie_readl_atu(struct dw_pcie *pci, rt_uint32_t reg); -void dw_pcie_writel_atu(struct dw_pcie *pci, rt_uint32_t reg, rt_uint32_t val); -rt_bool_t dw_pcie_link_up(struct dw_pcie *pci); -void dw_pcie_upconfig_setup(struct dw_pcie *pci); -rt_err_t dw_pcie_wait_for_link(struct dw_pcie *pci); -void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type, rt_uint64_t cpu_addr, rt_uint64_t pci_addr, rt_size_t size); -void dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, rt_uint8_t func_no, int index, int type, rt_uint64_t cpu_addr, rt_uint64_t pci_addr, rt_size_t size); -rt_err_t dw_pcie_prog_inbound_atu(struct dw_pcie *pci, rt_uint8_t func_no, int index, int bar, rt_uint64_t cpu_addr, enum dw_pcie_aspace_type aspace_type); -void dw_pcie_disable_atu(struct dw_pcie *pci, int index, enum dw_pcie_region_type type); -void dw_pcie_setup(struct dw_pcie *pci); - -rt_inline void dw_pcie_writel_dbi(struct dw_pcie *pci, rt_uint32_t reg, rt_uint32_t val) -{ - dw_pcie_write_dbi(pci, reg, 0x4, val); -} - -rt_inline rt_uint32_t dw_pcie_readl_dbi(struct dw_pcie *pci, rt_uint32_t reg) -{ - return dw_pcie_read_dbi(pci, reg, 0x4); -} - -rt_inline void dw_pcie_writew_dbi(struct dw_pcie *pci, rt_uint32_t reg, rt_uint16_t val) -{ - dw_pcie_write_dbi(pci, reg, 0x2, val); -} - -rt_inline rt_uint16_t dw_pcie_readw_dbi(struct dw_pcie *pci, rt_uint32_t reg) -{ - return dw_pcie_read_dbi(pci, reg, 0x2); -} - -rt_inline void dw_pcie_writeb_dbi(struct dw_pcie *pci, rt_uint32_t reg, rt_uint8_t val) -{ - dw_pcie_write_dbi(pci, reg, 0x1, val); -} - -rt_inline rt_uint8_t dw_pcie_readb_dbi(struct dw_pcie *pci, rt_uint32_t reg) -{ - return dw_pcie_read_dbi(pci, reg, 0x1); -} - -rt_inline void dw_pcie_writel_dbi2(struct dw_pcie *pci, rt_uint32_t reg, rt_uint32_t val) -{ - dw_pcie_write_dbi2(pci, reg, 0x4, val); -} - -rt_inline void dw_pcie_dbi_ro_writable_enable(struct dw_pcie *pci, rt_bool_t enable) -{ - const rt_uint32_t reg = PCIE_MISC_CONTROL_1_OFF; - - if (enable) - { - dw_pcie_writel_dbi(pci, reg, dw_pcie_readl_dbi(pci, reg) | PCIE_DBI_RO_WR_EN); - } - else - { - dw_pcie_writel_dbi(pci, reg, dw_pcie_readl_dbi(pci, reg) & ~PCIE_DBI_RO_WR_EN); - } -} - -rt_inline rt_uint8_t dw_pcie_iatu_unroll_enabled(struct dw_pcie *pci) -{ - return dw_pcie_readl_dbi(pci, PCIE_ATU_VIEWPORT) == 0xffffffff ? 1 : 0; -} - -rt_inline rt_uint32_t dw_pcie_readl_ob_unroll(struct dw_pcie *pci, - rt_uint32_t index, rt_uint32_t reg) -{ - return dw_pcie_readl_atu(pci, PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index) + reg); -} - -rt_inline void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, - rt_uint32_t index, rt_uint32_t reg, rt_uint32_t val) -{ - dw_pcie_writel_atu(pci, PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index) + reg, val); -} - -rt_inline rt_uint32_t dw_pcie_readl_ib_unroll(struct dw_pcie *pci, - rt_uint32_t index, rt_uint32_t reg) -{ - return dw_pcie_readl_atu(pci, PCIE_GET_ATU_INB_UNR_REG_OFFSET(index) + reg); -} - -rt_inline void dw_pcie_writel_ib_unroll(struct dw_pcie *pci, - rt_uint32_t index, rt_uint32_t reg, rt_uint32_t val) -{ - dw_pcie_writel_atu(pci, reg + PCIE_GET_ATU_INB_UNR_REG_OFFSET(index), val); -} - -HOST_API rt_err_t dw_handle_msi_irq(struct dw_pcie_port *port) HOST_RET(-RT_ENOSYS) -HOST_API void dw_pcie_msi_init(struct dw_pcie_port *port) HOST_RET() -HOST_API void dw_pcie_free_msi(struct dw_pcie_port *port) HOST_RET() - -HOST_API void dw_pcie_setup_rc(struct dw_pcie_port *port) HOST_RET() - -HOST_API rt_err_t dw_pcie_host_init(struct dw_pcie_port *port) HOST_RET(-RT_ENOSYS) -HOST_API void dw_pcie_host_deinit(struct dw_pcie_port *port) HOST_RET() - -HOST_API void dw_pcie_host_free(struct dw_pcie_port *port) HOST_RET() - -HOST_API void *dw_pcie_own_conf_map(struct rt_pci_bus *bus, rt_uint32_t devfn, int reg) HOST_RET(RT_NULL) - -EP_API rt_err_t dw_pcie_ep_init(struct dw_pcie_ep *ep) EP_RET(-RT_ENOSYS) -EP_API rt_err_t dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) EP_RET(-RT_ENOSYS) -EP_API void dw_pcie_ep_exit(struct dw_pcie_ep *ep) EP_RET() - -EP_API rt_err_t dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, rt_uint8_t func_no) EP_RET(-RT_ENOSYS) -EP_API rt_err_t dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, rt_uint8_t func_no, unsigned irq) EP_RET(-RT_ENOSYS) -EP_API rt_err_t dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, rt_uint8_t func_no, unsigned irq) EP_RET(-RT_ENOSYS) -EP_API rt_err_t dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, rt_uint8_t func_no, unsigned irq) EP_RET(-RT_ENOSYS) - -EP_API void dw_pcie_ep_reset_bar(struct dw_pcie *pci, int bar_idx) EP_RET() - -EP_API rt_err_t dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, rt_uint8_t func_no, - int bar_idx, rt_ubase_t cpu_addr, enum dw_pcie_aspace_type aspace_type) EP_RET(-RT_ENOSYS) -EP_API rt_err_t dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, rt_uint8_t func_no, - rt_ubase_t phys_addr, rt_uint64_t pci_addr, rt_size_t size) EP_RET(-RT_ENOSYS) - -EP_API struct dw_pcie_ep_func *dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, rt_uint8_t func_no) EP_RET(RT_NULL) - -#endif /* __PCIE_DESIGNWARE_H__ */ diff --git a/rt-thread/components/drivers/pci/host/dw/pcie-dw_ep.c b/rt-thread/components/drivers/pci/host/dw/pcie-dw_ep.c deleted file mode 100644 index b52f6b5..0000000 --- a/rt-thread/components/drivers/pci/host/dw/pcie-dw_ep.c +++ /dev/null @@ -1,863 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#define DBG_TAG "pcie.dw-ep" -#define DBG_LVL DBG_INFO -#include - -#include "pcie-dw.h" - -struct dw_pcie_ep_func *dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, rt_uint8_t func_no) -{ - struct dw_pcie_ep_func *ep_func; - - rt_list_for_each_entry(ep_func, &ep->func_nodes, list) - { - if (ep_func->func_no == func_no) - { - return ep_func; - } - } - - return RT_NULL; -} - -static rt_uint8_t dw_pcie_ep_func_select(struct dw_pcie_ep *ep, rt_uint8_t func_no) -{ - rt_uint8_t func_offset = 0; - - if (ep->ops->func_select) - { - func_offset = ep->ops->func_select(ep, func_no); - } - - return func_offset; -} - -static void __dw_pcie_ep_reset_bar(struct dw_pcie *pci, rt_uint8_t func_no, - int bar_idx, int flags) -{ - rt_uint32_t reg; - rt_uint8_t func_offset = 0; - struct dw_pcie_ep *ep = &pci->endpoint; - - func_offset = dw_pcie_ep_func_select(ep, func_no); - reg = func_offset + PCIR_BAR(bar_idx); - - dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE); - - dw_pcie_writel_dbi2(pci, reg, 0x0); - dw_pcie_writel_dbi(pci, reg, 0x0); - - if (flags & PCIM_BAR_MEM_TYPE_64) - { - dw_pcie_writel_dbi2(pci, reg + 4, 0x0); - dw_pcie_writel_dbi(pci, reg + 4, 0x0); - } - - dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE); -} - -void dw_pcie_ep_reset_bar(struct dw_pcie *pci, int bar_idx) -{ - rt_uint8_t func_no, funcs = pci->endpoint.epc->max_functions; - - for (func_no = 0; func_no < funcs; ++func_no) - { - __dw_pcie_ep_reset_bar(pci, func_no, bar_idx, 0); - } -} - -static rt_uint8_t __dw_pcie_ep_find_next_cap(struct dw_pcie_ep *ep, rt_uint8_t func_no, - rt_uint8_t cap_ptr, rt_uint8_t cap) -{ - rt_uint16_t reg; - rt_uint8_t func_offset = 0, cap_id, next_cap_ptr; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - if (!cap_ptr) - { - return 0; - } - - func_offset = dw_pcie_ep_func_select(ep, func_no); - reg = dw_pcie_readw_dbi(pci, func_offset + cap_ptr); - cap_id = (reg & 0x00ff); - - if (cap_id > PCIY_MAX) - { - return 0; - } - - if (cap_id == cap) - { - return cap_ptr; - } - - next_cap_ptr = (reg & 0xff00) >> 8; - return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap); -} - -static rt_uint8_t dw_pcie_ep_find_capability(struct dw_pcie_ep *ep, rt_uint8_t func_no, - rt_uint8_t cap) -{ - rt_uint16_t reg; - rt_uint8_t func_offset = 0, next_cap_ptr; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - func_offset = dw_pcie_ep_func_select(ep, func_no); - reg = dw_pcie_readw_dbi(pci, func_offset + PCIR_CAP_PTR); - next_cap_ptr = reg & 0x00ff; - - return __dw_pcie_ep_find_next_cap(ep, func_no, next_cap_ptr, cap); -} - -rt_err_t dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, rt_uint8_t func_no, - int bar_idx, rt_ubase_t cpu_addr, enum dw_pcie_aspace_type aspace_type) -{ - rt_err_t err; - rt_uint32_t free_win; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - free_win = rt_bitmap_next_clear_bit(ep->ib_window_map, 0, ep->num_ib_windows); - if (free_win >= ep->num_ib_windows) - { - LOG_E("No free inbound window"); - return -RT_EEMPTY; - } - - err = dw_pcie_prog_inbound_atu(pci, func_no, free_win, bar_idx, cpu_addr, aspace_type); - if (err) - { - LOG_E("Failed to program IB window error = %s", rt_strerror(err)); - return err; - } - - ep->bar_to_atu[bar_idx] = free_win; - rt_bitmap_set_bit(ep->ib_window_map, free_win); - - return RT_EOK; -} - -rt_err_t dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, rt_uint8_t func_no, - rt_ubase_t phys_addr, rt_uint64_t pci_addr, rt_size_t size) -{ - rt_uint32_t free_win; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - free_win = rt_bitmap_next_clear_bit(ep->ob_window_map, 0, ep->num_ob_windows); - if (free_win >= ep->num_ob_windows) - { - LOG_E("No free outbound window"); - return -RT_EEMPTY; - } - - dw_pcie_prog_ep_outbound_atu(pci, func_no, free_win, PCIE_ATU_TYPE_MEM, - phys_addr, pci_addr, size); - - ep->outbound_addr[free_win] = phys_addr; - rt_bitmap_set_bit(ep->ob_window_map, free_win); - - return RT_EOK; -} - -static rt_err_t dw_pcie_ep_write_header(struct rt_pci_ep *epc, rt_uint8_t func_no, - struct rt_pci_ep_header *hdr) -{ - rt_uint8_t func_offset = 0; - struct dw_pcie_ep *ep = epc->priv; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - func_offset = dw_pcie_ep_func_select(ep, func_no); - - dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE); - - dw_pcie_writew_dbi(pci, func_offset + PCIR_VENDOR, hdr->vendor); - dw_pcie_writew_dbi(pci, func_offset + PCIR_DEVICE, hdr->device); - dw_pcie_writeb_dbi(pci, func_offset + PCIR_REVID, hdr->revision); - dw_pcie_writeb_dbi(pci, func_offset + PCIR_PROGIF, hdr->progif); - dw_pcie_writew_dbi(pci, func_offset + PCIR_SUBCLASS, hdr->subclass | hdr->class_code << 8); - dw_pcie_writeb_dbi(pci, func_offset + PCIR_CACHELNSZ, hdr->cache_line_size); - dw_pcie_writew_dbi(pci, func_offset + PCIR_SUBVEND_0, hdr->subsystem_vendor); - dw_pcie_writew_dbi(pci, func_offset + PCIR_SUBDEV_0, hdr->subsystem_device); - dw_pcie_writeb_dbi(pci, func_offset + PCIR_INTPIN, hdr->intx); - - dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE); - - return 0; -} - -static rt_err_t dw_pcie_ep_clear_bar(struct rt_pci_ep *epc, rt_uint8_t func_no, - struct rt_pci_ep_bar *bar, int bar_idx) -{ - rt_uint32_t atu_index; - struct dw_pcie_ep *ep = epc->priv; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - atu_index = ep->bar_to_atu[bar_idx]; - __dw_pcie_ep_reset_bar(pci, func_no, bar_idx, ep->epc_bar[bar_idx]->bus.flags); - - dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND); - rt_bitmap_clear_bit(ep->ib_window_map, atu_index); - ep->epc_bar[bar_idx] = RT_NULL; - - return RT_EOK; -} - -static rt_err_t dw_pcie_ep_set_bar(struct rt_pci_ep *epc, rt_uint8_t func_no, - struct rt_pci_ep_bar *bar, int bar_idx) -{ - rt_err_t err; - rt_uint32_t reg; - rt_uint8_t func_offset = 0; - rt_size_t size = bar->bus.size; - rt_ubase_t flags = bar->bus.flags; - enum dw_pcie_aspace_type aspace_type; - struct dw_pcie_ep *ep = epc->priv; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - func_offset = dw_pcie_ep_func_select(ep, func_no); - reg = PCIR_BAR(bar_idx) + func_offset; - - if (!(flags & PCIM_BAR_SPACE)) - { - aspace_type = DW_PCIE_ASPACE_MEM; - } - else - { - aspace_type = DW_PCIE_ASPACE_IO; - } - - err = dw_pcie_ep_inbound_atu(ep, func_no, bar_idx, bar->bus.base, aspace_type); - if (err) - { - return err; - } - - dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE); - - dw_pcie_writel_dbi2(pci, reg, rt_lower_32_bits(size - 1)); - dw_pcie_writel_dbi(pci, reg, flags); - - if (flags & PCIM_BAR_MEM_TYPE_64) - { - dw_pcie_writel_dbi2(pci, reg + 4, rt_upper_32_bits(size - 1)); - dw_pcie_writel_dbi(pci, reg + 4, 0); - } - - ep->epc_bar[bar_idx] = bar; - dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE); - - return 0; -} - -static rt_err_t dw_pcie_find_index(struct dw_pcie_ep *ep, - rt_ubase_t addr, rt_uint32_t *atu_index) -{ - for (rt_uint32_t index = 0; index < ep->num_ob_windows; ++index) - { - if (ep->outbound_addr[index] != addr) - { - continue; - } - - *atu_index = index; - - return RT_EOK; - } - - return -RT_EINVAL; -} - -static rt_err_t dw_pcie_ep_unmap_addr(struct rt_pci_ep *epc, rt_uint8_t func_no, - rt_ubase_t addr) -{ - rt_err_t err; - rt_uint32_t atu_index; - struct dw_pcie_ep *ep = epc->priv; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - if ((err = dw_pcie_find_index(ep, addr, &atu_index))) - { - return err; - } - - dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_OUTBOUND); - rt_bitmap_clear_bit(ep->ob_window_map, atu_index); - - return RT_EOK; -} - -static rt_err_t dw_pcie_ep_map_addr(struct rt_pci_ep *epc, rt_uint8_t func_no, - rt_ubase_t addr, rt_uint64_t pci_addr, rt_size_t size) -{ - rt_err_t err; - struct dw_pcie_ep *ep = epc->priv; - - err = dw_pcie_ep_outbound_atu(ep, func_no, addr, pci_addr, size); - if (err) - { - LOG_E("Failed to enable address error = %s", rt_strerror(err)); - return err; - } - - return RT_EOK; -} - -static rt_err_t dw_pcie_ep_set_msi(struct rt_pci_ep *epc, rt_uint8_t func_no, - unsigned irq_nr) -{ - rt_uint32_t val, reg; - rt_uint8_t func_offset = 0; - struct dw_pcie_ep_func *ep_func; - struct dw_pcie_ep *ep = epc->priv; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); - if (!ep_func || !ep_func->msi_cap) - { - return -RT_EINVAL; - } - - func_offset = dw_pcie_ep_func_select(ep, func_no); - reg = ep_func->msi_cap + func_offset + PCIR_MSI_CTRL; - - val = dw_pcie_readw_dbi(pci, reg); - val &= ~PCIM_MSICTRL_MMC_MASK; - val |= (irq_nr << 1) & PCIM_MSICTRL_MMC_MASK; - - dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE); - dw_pcie_writew_dbi(pci, reg, val); - dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE); - - return RT_EOK; -} - -static rt_err_t dw_pcie_ep_get_msi(struct rt_pci_ep *epc, rt_uint8_t func_no, - unsigned *out_irq_nr) -{ - rt_uint32_t val, reg; - rt_uint8_t func_offset = 0; - struct dw_pcie_ep *ep = epc->priv; - struct dw_pcie_ep_func *ep_func; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); - if (!ep_func || !ep_func->msi_cap) - { - return -RT_EINVAL; - } - - func_offset = dw_pcie_ep_func_select(ep, func_no); - reg = ep_func->msi_cap + func_offset + PCIR_MSI_CTRL; - - val = dw_pcie_readw_dbi(pci, reg); - if (!(val & PCIM_MSICTRL_MSI_ENABLE)) - { - return -RT_EINVAL; - } - - *out_irq_nr = (val & PCIM_MSICTRL_MME_MASK) >> 4; - - return RT_EOK; -} - -static rt_err_t dw_pcie_ep_set_msix(struct rt_pci_ep *epc, rt_uint8_t func_no, - unsigned irq_nr, int bar_idx, rt_off_t offset) -{ - rt_uint32_t val, reg; - rt_uint8_t func_offset = 0; - struct dw_pcie_ep_func *ep_func; - struct dw_pcie_ep *ep = epc->priv; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); - if (!ep_func || !ep_func->msix_cap) - { - return -RT_EINVAL; - } - - dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE); - - func_offset = dw_pcie_ep_func_select(ep, func_no); - reg = ep_func->msix_cap + func_offset + PCIR_MSIX_CTRL; - - val = dw_pcie_readw_dbi(pci, reg); - val &= ~PCIM_MSIXCTRL_TABLE_SIZE; - val |= irq_nr; - dw_pcie_writew_dbi(pci, reg, val); - - reg = ep_func->msix_cap + func_offset + PCIR_MSIX_TABLE; - val = offset | bar_idx; - dw_pcie_writel_dbi(pci, reg, val); - - reg = ep_func->msix_cap + func_offset + PCIR_MSIX_PBA; - val = (offset + (irq_nr * PCIM_MSIX_ENTRY_SIZE)) | bar_idx; - dw_pcie_writel_dbi(pci, reg, val); - - dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE); - - return RT_EOK; -} - -static rt_err_t dw_pcie_ep_get_msix(struct rt_pci_ep *epc, rt_uint8_t func_no, - unsigned *out_irq_nr) -{ - rt_uint32_t val, reg; - rt_uint8_t func_offset = 0; - struct dw_pcie_ep_func *ep_func; - struct dw_pcie_ep *ep = epc->priv; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); - if (!ep_func || !ep_func->msix_cap) - { - return -RT_EINVAL; - } - - func_offset = dw_pcie_ep_func_select(ep, func_no); - reg = ep_func->msix_cap + func_offset + PCIR_MSIX_CTRL; - - val = dw_pcie_readw_dbi(pci, reg); - if (!(val & PCIM_MSIXCTRL_MSIX_ENABLE)) - { - return -RT_EINVAL; - } - - *out_irq_nr = val & PCIM_MSIXCTRL_TABLE_SIZE; - - return RT_EOK; -} - -static rt_err_t dw_pcie_ep_raise_irq(struct rt_pci_ep *epc, rt_uint8_t func_no, - enum rt_pci_ep_irq type, unsigned irq) -{ - struct dw_pcie_ep *ep = epc->priv; - - if (!ep->ops->raise_irq) - { - return -RT_ENOSYS; - } - - return ep->ops->raise_irq(ep, func_no, type, irq); -} - -static rt_err_t dw_pcie_ep_stop(struct rt_pci_ep *epc) -{ - struct dw_pcie_ep *ep = epc->priv; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - if (pci->ops->stop_link) - { - pci->ops->stop_link(pci); - } - - return RT_EOK; -} - -static rt_err_t dw_pcie_ep_start(struct rt_pci_ep *epc) -{ - struct dw_pcie_ep *ep = epc->priv; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - if (pci->ops->start_link) - { - return pci->ops->start_link(pci); - } - - return RT_EOK; -} - -static const struct rt_pci_ep_ops dw_pcie_ep_ops = -{ - .write_header = dw_pcie_ep_write_header, - .set_bar = dw_pcie_ep_set_bar, - .clear_bar = dw_pcie_ep_clear_bar, - .map_addr = dw_pcie_ep_map_addr, - .unmap_addr = dw_pcie_ep_unmap_addr, - .set_msi = dw_pcie_ep_set_msi, - .get_msi = dw_pcie_ep_get_msi, - .set_msix = dw_pcie_ep_set_msix, - .get_msix = dw_pcie_ep_get_msix, - .raise_irq = dw_pcie_ep_raise_irq, - .start = dw_pcie_ep_start, - .stop = dw_pcie_ep_stop, -}; - -rt_err_t dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, rt_uint8_t func_no) -{ - LOG_E("EP cannot trigger legacy IRQs"); - - return -RT_EINVAL; -} - -rt_err_t dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, rt_uint8_t func_no, - unsigned irq) -{ - rt_err_t err; - rt_off_t aligned_offset; - rt_uint8_t func_offset = 0; - rt_uint64_t msg_addr; - rt_uint16_t msg_ctrl, msg_data; - rt_uint32_t msg_addr_lower, msg_addr_upper, reg; - struct rt_pci_ep *epc = ep->epc; - struct dw_pcie_ep_func *ep_func; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); - if (!ep_func || !ep_func->msi_cap) - { - return -RT_EINVAL; - } - - func_offset = dw_pcie_ep_func_select(ep, func_no); - - /* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */ - reg = ep_func->msi_cap + func_offset + PCIR_MSI_CTRL; - msg_ctrl = dw_pcie_readw_dbi(pci, reg); - reg = ep_func->msi_cap + func_offset + PCIR_MSI_ADDR; - msg_addr_lower = dw_pcie_readl_dbi(pci, reg); - - if (!!(msg_ctrl & PCIM_MSICTRL_64BIT)) - { - reg = ep_func->msi_cap + func_offset + PCIR_MSI_ADDR_HIGH; - msg_addr_upper = dw_pcie_readl_dbi(pci, reg); - reg = ep_func->msi_cap + func_offset + PCIR_MSI_DATA_64BIT; - msg_data = dw_pcie_readw_dbi(pci, reg); - } - else - { - msg_addr_upper = 0; - reg = ep_func->msi_cap + func_offset + PCIR_MSI_DATA; - msg_data = dw_pcie_readw_dbi(pci, reg); - } - - aligned_offset = msg_addr_lower & (ep->page_size - 1); - msg_addr = ((rt_uint64_t)msg_addr_upper << 32) | (msg_addr_lower & ~aligned_offset); - - if ((err = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phy, msg_addr, ep->page_size))) - { - return err; - } - - HWREG32(ep->msi_mem + aligned_offset) = msg_data | (irq - 1); - dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phy); - - return RT_EOK; -} - -rt_err_t dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, rt_uint8_t func_no, - unsigned irq) -{ - rt_uint32_t msg_data; - struct dw_pcie_ep_func *ep_func; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); - if (!ep_func || !ep_func->msix_cap) - { - return -RT_EINVAL; - } - - msg_data = (func_no << PCIE_MSIX_DOORBELL_PF_SHIFT) | (irq - 1); - dw_pcie_writel_dbi(pci, PCIE_MSIX_DOORBELL, msg_data); - - return RT_EOK; -} - -rt_err_t dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, rt_uint8_t func_no, - unsigned irq) -{ - rt_err_t err; - int bar_idx; - rt_uint64_t msg_addr; - rt_uint32_t tbl_offset; - rt_off_t aligned_offset; - rt_uint8_t func_offset = 0; - rt_uint32_t reg, msg_data, vec_ctrl; - struct rt_pci_ep *epc = ep->epc; - struct rt_pci_ep_msix_tbl *msix_tbl; - struct dw_pcie_ep_func *ep_func; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - ep_func = dw_pcie_ep_get_func_from_ep(ep, func_no); - if (!ep_func || !ep_func->msix_cap) - { - return -RT_EINVAL; - } - - func_offset = dw_pcie_ep_func_select(ep, func_no); - reg = ep_func->msix_cap + func_offset + PCIR_MSIX_TABLE; - - tbl_offset = dw_pcie_readl_dbi(pci, reg); - bar_idx = (tbl_offset & PCIM_MSIX_BIR_MASK); - tbl_offset &= PCIM_MSIX_TABLE_OFFSET; - - msix_tbl = (void *)ep->epc_bar[bar_idx]->cpu_addr + tbl_offset; - msg_addr = msix_tbl[(irq - 1)].msg_addr; - msg_data = msix_tbl[(irq - 1)].msg_data; - vec_ctrl = msix_tbl[(irq - 1)].vector_ctrl; - - if (vec_ctrl & PCIM_MSIX_ENTRYVECTOR_CTRL_MASK) - { - return -RT_EINVAL; - } - - aligned_offset = msg_addr & (ep->page_size - 1); - - if ((err = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phy, msg_addr, ep->page_size))) - { - return err; - } - - HWREG32(ep->msi_mem + aligned_offset) = msg_data; - dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phy); - - return RT_EOK; -} - -void dw_pcie_ep_exit(struct dw_pcie_ep *ep) -{ - struct rt_pci_ep *epc = ep->epc; - - if (ep->msi_mem) - { - rt_pci_ep_mem_free(epc, ep->msi_mem, ep->msi_mem_phy, ep->page_size); - } - - if (!rt_list_isempty(&ep->func_nodes)) - { - struct dw_pcie_ep_func *ep_func, *ep_func_next; - - rt_list_for_each_entry_safe(ep_func, ep_func_next, &ep->func_nodes, list) - { - rt_list_remove(&ep_func->list); - rt_free(ep_func); - } - } - - if (ep->ib_window_map) - { - rt_free(ep->ib_window_map); - } - - if (ep->ob_window_map) - { - rt_free(ep->ob_window_map); - } - - if (ep->outbound_addr) - { - rt_free(ep->outbound_addr); - } - - if (epc) - { - rt_free(epc); - } -} - -static rt_uint32_t dw_pcie_ep_find_ext_capability(struct dw_pcie *pci, int cap) -{ - rt_uint32_t header; - int pos = (PCI_REGMAX + 1); - - while (pos) - { - header = dw_pcie_readl_dbi(pci, pos); - - if (PCI_EXTCAP_ID(header) == cap) - { - return pos; - } - - if (!(pos = PCI_EXTCAP_NEXTPTR(header))) - { - break; - } - } - - return 0; -} - -rt_err_t dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) -{ - rt_off_t offset; - rt_size_t bar_nr; - rt_uint32_t reg; - rt_uint8_t hdr_type; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - hdr_type = dw_pcie_readb_dbi(pci, PCIR_HDRTYPE) & PCIM_HDRTYPE; - if (hdr_type != PCIM_HDRTYPE_NORMAL) - { - LOG_E("PCIe controller is not set to EP mode hdr_type = %x", hdr_type); - return -RT_EIO; - } - - offset = dw_pcie_ep_find_ext_capability(pci, PCIZ_RESIZE_BAR); - - dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE); - - if (offset) - { - reg = dw_pcie_readl_dbi(pci, offset + PCIM_REBAR_CTRL); - bar_nr = (reg & PCIM_REBAR_CTRL_NBAR_MASK) >> PCIM_REBAR_CTRL_NBAR_SHIFT; - - for (int i = 0; i < bar_nr; ++i, offset += PCIM_REBAR_CTRL) - { - dw_pcie_writel_dbi(pci, offset + PCIM_REBAR_CAP, 0x0); - } - } - - dw_pcie_setup(pci); - dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE); - - return RT_EOK; -} - -rt_err_t dw_pcie_ep_init(struct dw_pcie_ep *ep) -{ - rt_err_t err; - struct rt_pci_ep *epc = RT_NULL; - struct dw_pcie_ep_func *ep_func; - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - struct rt_device *dev = pci->dev; - - rt_list_init(&ep->func_nodes); - - if (!pci->dbi_base || !pci->dbi_base2) - { - LOG_E("dbi_base/dbi_base2 is not populated"); - return -RT_EINVAL; - } - - if ((err = rt_dm_dev_prop_read_u32(dev, "num-ib-windows", &ep->num_ib_windows))) - { - LOG_E("Unable to read 'num-ib-windows' property"); - return err; - } - - if (ep->num_ib_windows > MAX_IATU_IN) - { - LOG_E("Invalid 'num-ib-windows'"); - return -RT_EINVAL; - } - - if ((err = rt_dm_dev_prop_read_u32(dev, "num-ob-windows", &ep->num_ob_windows))) - { - LOG_E("Unable to read 'num-ob-windows' property"); - return err; - } - - if (ep->num_ob_windows > MAX_IATU_OUT) - { - LOG_E("Invalid 'num-ob-windows'"); - return -RT_EINVAL; - } - - ep->ib_window_map = rt_calloc(RT_BITMAP_LEN(ep->num_ib_windows), sizeof(rt_bitmap_t)); - if (!ep->ib_window_map) - { - return -RT_ENOMEM; - } - - ep->ob_window_map = rt_calloc(RT_BITMAP_LEN(ep->num_ob_windows), sizeof(rt_bitmap_t)); - if (!ep->ob_window_map) - { - err = -RT_ENOMEM; - goto _fail; - } - - ep->outbound_addr = rt_calloc(ep->num_ob_windows, sizeof(rt_ubase_t)); - if (!ep->outbound_addr) - { - err = -RT_ENOMEM; - goto _fail; - } - - if (pci->link_gen < 1) - { - pci->link_gen = -1; - rt_dm_dev_prop_read_u32(dev, "max-link-speed", &pci->link_gen); - } - - epc = rt_calloc(1, sizeof(*epc)); - if (!epc) - { - err = -RT_ENOMEM; - goto _fail; - } - - epc->name = rt_dm_dev_get_name(dev); - epc->rc_dev = dev; - epc->ops = &dw_pcie_ep_ops; - epc->priv = ep; - - if ((err = rt_pci_ep_register(epc))) - { - goto _fail; - } - ep->epc = epc; - - if (rt_dm_dev_prop_read_u8(dev, "max-functions", &epc->max_functions)) - { - epc->max_functions = 1; - } - - for (rt_uint8_t func_no = 0; func_no < epc->max_functions; ++func_no) - { - ep_func = rt_calloc(1, sizeof(*ep_func)); - - if (!ep_func) - { - err = -RT_ENOMEM; - goto _fail; - } - - ep_func->func_no = func_no; - ep_func->msi_cap = dw_pcie_ep_find_capability(ep, func_no, PCIY_MSI); - ep_func->msix_cap = dw_pcie_ep_find_capability(ep, func_no, PCIY_MSIX); - - rt_list_init(&ep_func->list); - rt_list_insert_after(&ep->func_nodes, &ep_func->list); - } - - if (ep->ops->ep_init) - { - ep->ops->ep_init(ep); - } - - if ((err = rt_pci_ep_mem_init(epc, ep->aspace, ep->aspace_size, ep->page_size))) - { - goto _fail; - } - - ep->msi_mem = rt_pci_ep_mem_alloc(epc, &ep->msi_mem_phy, ep->page_size); - - if (!ep->msi_mem) - { - LOG_E("Failed to reserve memory for MSI/MSI-X"); - err = -RT_ENOMEM; - goto _fail; - } - - if ((err = dw_pcie_ep_init_complete(ep))) - { - goto _fail; - } - - return RT_EOK; - -_fail: - dw_pcie_ep_exit(ep); - - return err; -} diff --git a/rt-thread/components/drivers/pci/host/dw/pcie-dw_host.c b/rt-thread/components/drivers/pci/host/dw/pcie-dw_host.c deleted file mode 100644 index 05a3dc7..0000000 --- a/rt-thread/components/drivers/pci/host/dw/pcie-dw_host.c +++ /dev/null @@ -1,644 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#define DBG_TAG "pcie.dw-host" -#define DBG_LVL DBG_INFO -#include - -#include "pcie-dw.h" - -static void dw_pcie_irq_ack(struct rt_pic_irq *pirq) -{ - int hwirq = pirq->hwirq; - rt_uint32_t res, bit, ctrl; - struct dw_pcie_port *port = pirq->pic->priv_data; - struct dw_pcie *pci = to_dw_pcie_from_port(port); - - ctrl = hwirq / MAX_MSI_IRQS_PER_CTRL; - res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; - bit = hwirq % MAX_MSI_IRQS_PER_CTRL; - - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_STATUS + res, RT_BIT(bit)); -} - -static void dw_pcie_irq_mask(struct rt_pic_irq *pirq) -{ - rt_ubase_t level; - int hwirq = pirq->hwirq; - rt_uint32_t res, bit, ctrl; - struct dw_pcie_port *port = pirq->pic->priv_data; - struct dw_pcie *pci = to_dw_pcie_from_port(port); - - rt_pci_msi_mask_irq(pirq); - - level = rt_spin_lock_irqsave(&port->lock); - - ctrl = hwirq / MAX_MSI_IRQS_PER_CTRL; - res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; - bit = hwirq % MAX_MSI_IRQS_PER_CTRL; - - port->irq_mask[ctrl] |= RT_BIT(bit); - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res, port->irq_mask[ctrl]); - - rt_spin_unlock_irqrestore(&port->lock, level); -} - -static void dw_pcie_irq_unmask(struct rt_pic_irq *pirq) -{ - rt_ubase_t level; - int hwirq = pirq->hwirq; - rt_uint32_t res, bit, ctrl; - struct dw_pcie_port *port = pirq->pic->priv_data; - struct dw_pcie *pci = to_dw_pcie_from_port(port); - - rt_pci_msi_unmask_irq(pirq); - - level = rt_spin_lock_irqsave(&port->lock); - - ctrl = hwirq / MAX_MSI_IRQS_PER_CTRL; - res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; - bit = hwirq % MAX_MSI_IRQS_PER_CTRL; - - port->irq_mask[ctrl] &= ~RT_BIT(bit); - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res, port->irq_mask[ctrl]); - - rt_spin_unlock_irqrestore(&port->lock, level); -} - -static void dw_pcie_compose_msi_msg(struct rt_pic_irq *pirq, struct rt_pci_msi_msg *msg) -{ - rt_uint64_t msi_target; - struct dw_pcie_port *port = pirq->pic->priv_data; - - msi_target = (rt_uint64_t)port->msi_data_phy; - - msg->address_lo = rt_lower_32_bits(msi_target); - msg->address_hi = rt_upper_32_bits(msi_target); - - msg->data = pirq->hwirq; -} - -static int dw_pcie_irq_alloc_msi(struct rt_pic *pic, struct rt_pci_msi_desc *msi_desc) -{ - rt_ubase_t level; - int irq, hwirq; - struct rt_pic_irq *pirq; - struct dw_pcie_port *port = pic->priv_data; - - level = rt_spin_lock_irqsave(&port->lock); - hwirq = rt_bitmap_next_clear_bit(port->msi_map, 0, port->irq_count); - - if (hwirq >= port->irq_count) - { - irq = -RT_EEMPTY; - goto _out_lock; - } - - pirq = rt_pic_find_irq(pic, hwirq); - - irq = rt_pic_config_irq(pic, hwirq, hwirq); - pirq->mode = RT_IRQ_MODE_EDGE_RISING; - - rt_bitmap_set_bit(port->msi_map, hwirq); - -_out_lock: - rt_spin_unlock_irqrestore(&port->lock, level); - - return irq; -} - -static void dw_pcie_irq_free_msi(struct rt_pic *pic, int irq) -{ - rt_ubase_t level; - struct rt_pic_irq *pirq; - struct dw_pcie_port *port = pic->priv_data; - - pirq = rt_pic_find_pirq(pic, irq); - - if (!pirq) - { - return; - } - - level = rt_spin_lock_irqsave(&port->lock); - rt_bitmap_clear_bit(port->msi_map, pirq->hwirq); - rt_spin_unlock_irqrestore(&port->lock, level); -} - -const static struct rt_pic_ops dw_pci_msi_ops = -{ - .name = "DWPCI-MSI", - .irq_ack = dw_pcie_irq_ack, - .irq_mask = dw_pcie_irq_mask, - .irq_unmask = dw_pcie_irq_unmask, - .irq_compose_msi_msg = dw_pcie_compose_msi_msg, - .irq_alloc_msi = dw_pcie_irq_alloc_msi, - .irq_free_msi = dw_pcie_irq_free_msi, - .flags = RT_PIC_F_IRQ_ROUTING, -}; - -/* MSI int handler */ -rt_err_t dw_handle_msi_irq(struct dw_pcie_port *port) -{ - rt_err_t err; - int i, pos; - rt_bitmap_t status; - rt_uint32_t num_ctrls; - struct rt_pic_irq *pirq; - struct dw_pcie *pci = to_dw_pcie_from_port(port); - struct rt_pic *msi_pic = port->msi_pic; - - err = -RT_EEMPTY; - num_ctrls = RT_DIV_ROUND_UP(port->irq_count, MAX_MSI_IRQS_PER_CTRL); - - for (i = 0; i < num_ctrls; ++i) - { - status = dw_pcie_readl_dbi(pci, PCIE_MSI_INTR0_STATUS + - (i * MSI_REG_CTRL_BLOCK_SIZE)); - - if (!status) - { - continue; - } - - err = RT_EOK; - - rt_bitmap_for_each_set_bit(&status, pos, MAX_MSI_IRQS_PER_CTRL) - { - pirq = rt_pic_find_irq(msi_pic, pos + i * MAX_MSI_IRQS_PER_CTRL); - - dw_pcie_irq_ack(pirq); - - rt_pic_handle_isr(pirq); - } - } - - return err; -} - -static void dw_pcie_msi_isr(int irqno, void *param) -{ - struct dw_pcie_port *port = param; - - dw_handle_msi_irq(port); -} - -void dw_pcie_free_msi(struct dw_pcie_port *port) -{ - if (port->msi_irq >= 0) - { - rt_hw_interrupt_mask(port->msi_irq); - rt_pic_detach_irq(port->msi_irq, port); - } - - if (port->msi_data) - { - struct dw_pcie *pci = to_dw_pcie_from_port(port); - - rt_dma_free_coherent(pci->dev, sizeof(rt_uint64_t), port->msi_data, - port->msi_data_phy); - } -} - -void dw_pcie_msi_init(struct dw_pcie_port *port) -{ -#ifdef RT_PCI_MSI - struct dw_pcie *pci = to_dw_pcie_from_port(port); - rt_uint64_t msi_target = (rt_uint64_t)port->msi_data_phy; - - /* Program the msi_data_phy */ - dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_LO, rt_lower_32_bits(msi_target)); - dw_pcie_writel_dbi(pci, PCIE_MSI_ADDR_HI, rt_upper_32_bits(msi_target)); -#endif -} - -static const struct rt_pci_ops dw_child_pcie_ops; -static const struct rt_pci_ops dw_pcie_ops; - -rt_err_t dw_pcie_host_init(struct dw_pcie_port *port) -{ - rt_err_t err; - struct dw_pcie *pci = to_dw_pcie_from_port(port); - struct rt_device *dev = pci->dev; - struct rt_pci_host_bridge *bridge; - - rt_spin_lock_init(&port->lock); - - rt_dm_dev_get_address_by_name(dev, "config", &port->cfg0_addr, &port->cfg0_size); - - if (port->cfg0_addr) - { - port->cfg0_base = rt_ioremap((void *)port->cfg0_addr, port->cfg0_size); - - if (!port->cfg0_base) - { - return -RT_EIO; - } - } - else if (!port->cfg0_base) - { - LOG_E("Missing 'config' reg space"); - } - - if (!(bridge = rt_pci_host_bridge_alloc(0))) - { - return -RT_ENOMEM; - } - - bridge->parent.ofw_node = dev->ofw_node; - - if ((err = rt_pci_host_bridge_init(bridge))) - { - goto _err_free_bridge; - } - - port->bridge = bridge; - - for (int i = 0; i < bridge->bus_regions_nr; ++i) - { - struct rt_pci_bus_region *region = &bridge->bus_regions[i]; - - switch (region->flags) - { - case PCI_BUS_REGION_F_IO: - port->io_addr = region->cpu_addr; - port->io_bus_addr = region->phy_addr; - port->io_size = region->size; - break; - - case PCI_BUS_REGION_F_NONE: - port->cfg0_size = region->size; - port->cfg0_addr = region->cpu_addr; - - if (!pci->dbi_base) - { - pci->dbi_base = rt_ioremap((void *)port->cfg0_addr, port->cfg0_size); - - if (!pci->dbi_base) - { - LOG_E("Error with ioremap"); - return -RT_ENOMEM; - } - } - break; - - default: - break; - } - } - - if (!port->cfg0_base && port->cfg0_addr) - { - port->cfg0_base = rt_ioremap((void *)port->cfg0_addr, port->cfg0_size); - - if (!port->cfg0_base) - { - return -RT_ENOMEM; - } - } - - if (rt_dm_dev_prop_read_u32(dev, "num-viewport", &pci->num_viewport)) - { - pci->num_viewport = 2; - } - - if (pci->link_gen < 1) - { - pci->link_gen = -1; - rt_dm_dev_prop_read_u32(dev, "max-link-speed", &pci->link_gen); - } - - /* - * If a specific SoC driver needs to change the default number of vectors, - * it needs to implement the set_irq_count callback. - */ - if (!port->ops->set_irq_count) - { - port->irq_count = MSI_DEF_NUM_VECTORS; - } - else - { - port->ops->set_irq_count(port); - - if (port->irq_count > MAX_MSI_IRQS || port->irq_count == 0) - { - LOG_E("Invalid count of irq = %d", port->irq_count); - - return -RT_EINVAL; - } - } - - if (!port->ops->msi_host_init) - { - port->msi_pic = rt_calloc(1, sizeof(*port->msi_pic)); - - if (!port->msi_pic) - { - return -RT_ENOMEM; - } - - port->msi_pic->priv_data = port; - port->msi_pic->ops = &dw_pci_msi_ops; - rt_pic_linear_irq(port->msi_pic, port->irq_count); - rt_pic_user_extends(port->msi_pic); - - if (port->msi_irq) - { - rt_hw_interrupt_install(port->msi_irq, dw_pcie_msi_isr, port, "dwc-pci-msi"); - rt_hw_interrupt_umask(port->msi_irq); - } - - port->msi_data = rt_dma_alloc_coherent(pci->dev, sizeof(rt_uint64_t), - &port->msi_data_phy); - - if (!port->msi_data) - { - err = -RT_ENOMEM; - goto _err_free_msi; - } - } - else - { - if ((err = port->ops->msi_host_init(port))) - { - return err; - } - } - - /* Set default bus ops */ - bridge->ops = &dw_pcie_ops; - bridge->child_ops = &dw_child_pcie_ops; - - if (port->ops->host_init && (err = port->ops->host_init(port))) - { - goto _err_free_msi; - } - - bridge->sysdata = port; - - if ((err = rt_pci_host_bridge_probe(bridge))) - { - goto _err_free_msi; - } - - return RT_EOK; - -_err_free_msi: - if (!port->ops->msi_host_init) - { - dw_pcie_free_msi(port); - - rt_pic_cancel_irq(port->msi_pic); - rt_free(port->msi_pic); - port->msi_pic = RT_NULL; - } - -_err_free_bridge: - rt_pci_host_bridge_free(bridge); - port->bridge = RT_NULL; - - return err; -} - -void dw_pcie_host_deinit(struct dw_pcie_port *port) -{ - if (!port->ops->msi_host_init) - { - dw_pcie_free_msi(port); - } -} - -void dw_pcie_host_free(struct dw_pcie_port *port) -{ - if (!port->ops->msi_host_init) - { - dw_pcie_free_msi(port); - - rt_pic_cancel_irq(port->msi_pic); - rt_free(port->msi_pic); - } - - if (port->bridge) - { - rt_pci_host_bridge_free(port->bridge); - } -} - -static void *dw_pcie_other_conf_map(struct rt_pci_bus *bus, rt_uint32_t devfn, int reg) -{ - int type; - rt_uint32_t busdev; - struct dw_pcie_port *port = bus->sysdata; - struct dw_pcie *pci = to_dw_pcie_from_port(port); - - /* - * Checking whether the link is up here is a last line of defense - * against platforms that forward errors on the system bus as - * SError upon PCI configuration transactions issued when the link is down. - * This check is racy by definition and does not stop the system from - * triggering an SError if the link goes down after this check is performed. - */ - if (!dw_pcie_link_up(pci)) - { - return RT_NULL; - } - - busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(RT_PCI_SLOT(devfn)) | - PCIE_ATU_FUNC(RT_PCI_FUNC(devfn)); - - if (rt_pci_is_root_bus(bus->parent)) - { - type = PCIE_ATU_TYPE_CFG0; - } - else - { - type = PCIE_ATU_TYPE_CFG1; - } - - dw_pcie_prog_outbound_atu(pci, 0, type, port->cfg0_addr, busdev, port->cfg0_size); - - return port->cfg0_base + reg; -} - -static rt_err_t dw_pcie_other_read_conf(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, int width, rt_uint32_t *value) -{ - rt_err_t err; - struct dw_pcie_port *port = bus->sysdata; - struct dw_pcie *pci = to_dw_pcie_from_port(port); - - err = rt_pci_bus_read_config_uxx(bus, devfn, reg, width, value); - - if (!err && (pci->iatu_unroll_enabled & DWC_IATU_IOCFG_SHARED)) - { - dw_pcie_prog_outbound_atu(pci, 0, PCIE_ATU_TYPE_IO, - port->io_addr, port->io_bus_addr, port->io_size); - } - - return err; -} - -static rt_err_t dw_pcie_other_write_conf(struct rt_pci_bus *bus, - rt_uint32_t devfn, int reg, int width, rt_uint32_t value) -{ - rt_err_t err; - struct dw_pcie_port *port = bus->sysdata; - struct dw_pcie *pci = to_dw_pcie_from_port(port); - - err = rt_pci_bus_write_config_uxx(bus, devfn, reg, width, value); - - if (!err && (pci->iatu_unroll_enabled & DWC_IATU_IOCFG_SHARED)) - { - dw_pcie_prog_outbound_atu(pci, 0, PCIE_ATU_TYPE_IO, - port->io_addr, port->io_bus_addr, port->io_size); - } - - return err; -} - -static const struct rt_pci_ops dw_child_pcie_ops = -{ - .map = dw_pcie_other_conf_map, - .read = dw_pcie_other_read_conf, - .write = dw_pcie_other_write_conf, -}; - -void *dw_pcie_own_conf_map(struct rt_pci_bus *bus, rt_uint32_t devfn, int reg) -{ - struct dw_pcie_port *port = bus->sysdata; - struct dw_pcie *pci = to_dw_pcie_from_port(port); - - if (RT_PCI_SLOT(devfn) > 0) - { - return RT_NULL; - } - - return pci->dbi_base + reg; -} - -static const struct rt_pci_ops dw_pcie_ops = -{ - .map = dw_pcie_own_conf_map, - .read = rt_pci_bus_read_config_uxx, - .write = rt_pci_bus_write_config_uxx, -}; - -void dw_pcie_setup_rc(struct dw_pcie_port *port) -{ - rt_uint32_t val, num_ctrls; - struct dw_pcie *pci = to_dw_pcie_from_port(port); - - /* - * Enable DBI read-only registers for writing/updating configuration. - * Write permission gets disabled towards the end of this function. - */ - dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE); - - dw_pcie_setup(pci); - - if (!port->ops->msi_host_init) - { - num_ctrls = RT_DIV_ROUND_UP(port->irq_count, MAX_MSI_IRQS_PER_CTRL); - - /* Initialize IRQ Status array */ - for (int ctrl = 0; ctrl < num_ctrls; ++ctrl) - { - port->irq_mask[ctrl] = ~0; - - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + - (ctrl * MSI_REG_CTRL_BLOCK_SIZE), port->irq_mask[ctrl]); - dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_ENABLE + - (ctrl * MSI_REG_CTRL_BLOCK_SIZE), ~0); - } - } - - /* Setup RC BARs */ - dw_pcie_writel_dbi(pci, PCIR_BAR(0), PCIM_BAR_MEM_TYPE_64); - dw_pcie_writel_dbi(pci, PCIR_BAR(1), PCIM_BAR_MEM_TYPE_32); - - /* Setup interrupt pins */ - val = dw_pcie_readl_dbi(pci, PCIR_INTLINE); - val &= 0xffff00ff; - val |= 0x00000100; - dw_pcie_writel_dbi(pci, PCIR_INTLINE, val); - - /* Setup bus numbers */ - val = dw_pcie_readl_dbi(pci, PCIR_PRIBUS_1); - val &= 0xff000000; - val |= 0x00ff0100; - dw_pcie_writel_dbi(pci, PCIR_PRIBUS_1, val); - - /* Setup command register */ - val = dw_pcie_readl_dbi(pci, PCIR_COMMAND); - val &= 0xffff0000; - val |= PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_SERRESPEN; - dw_pcie_writel_dbi(pci, PCIR_COMMAND, val); - - /* - * If the platform provides its own child bus config accesses, it means - * the platform uses its own address translation component rather than - * ATU, so we should not program the ATU here. - */ - if (pci->port.bridge->child_ops == &dw_child_pcie_ops) - { - int atu_idx = 0; - struct rt_pci_host_bridge *bridge = port->bridge; - - /* Get last memory resource entry */ - for (int i = 0; i < bridge->bus_regions_nr; ++i) - { - struct rt_pci_bus_region *region = &bridge->bus_regions[i]; - - if (region->flags != PCI_BUS_REGION_F_MEM) - { - continue; - } - - if (pci->num_viewport <= ++atu_idx) - { - break; - } - - dw_pcie_prog_outbound_atu(pci, atu_idx, - PCIE_ATU_TYPE_MEM, region->cpu_addr, - region->phy_addr, region->size); - } - - if (port->io_size) - { - if (pci->num_viewport > ++atu_idx) - { - dw_pcie_prog_outbound_atu(pci, atu_idx, - PCIE_ATU_TYPE_IO, port->io_addr, - port->io_bus_addr, port->io_size); - } - else - { - pci->iatu_unroll_enabled |= DWC_IATU_IOCFG_SHARED; - } - } - - if (pci->num_viewport <= atu_idx) - { - LOG_W("Resources exceed number of ATU entries (%d)", pci->num_viewport); - } - } - - dw_pcie_writel_dbi(pci, PCIR_BAR(0), 0); - - /* Program correct class for RC */ - dw_pcie_writew_dbi(pci, PCIR_SUBCLASS, PCIS_BRIDGE_PCI); - - val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL); - val |= PORT_LOGIC_SPEED_CHANGE; - dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val); - - dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE); -} diff --git a/rt-thread/components/drivers/pci/host/dw/pcie-dw_platfrom.c b/rt-thread/components/drivers/pci/host/dw/pcie-dw_platfrom.c deleted file mode 100644 index 878ac41..0000000 --- a/rt-thread/components/drivers/pci/host/dw/pcie-dw_platfrom.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#include -#include - -#define DBG_TAG "pcie.dw.platfrom" -#define DBG_LVL DBG_INFO -#include - -#include "pcie-dw.h" - -struct dw_dw_platform_pcie_soc_data -{ - enum dw_pcie_device_mode mode; -}; - -struct dw_platform_pcie -{ - struct dw_pcie *pci; - struct rt_syscon *regmap; - const struct dw_dw_platform_pcie_soc_data *soc_data; -}; - -static rt_err_t dw_platform_pcie_host_init(struct dw_pcie_port *port) -{ - struct dw_pcie *pci = to_dw_pcie_from_port(port); - - dw_pcie_setup_rc(port); - dw_pcie_wait_for_link(pci); - dw_pcie_msi_init(port); - - return RT_EOK; -} - -static void dw_platform_set_irq_count(struct dw_pcie_port *pp) -{ - pp->irq_count = MAX_MSI_IRQS; -} - -static const struct dw_pcie_host_ops dw_platform_pcie_host_ops = -{ - .host_init = dw_platform_pcie_host_init, - .set_irq_count = dw_platform_set_irq_count, -}; - -static rt_err_t dw_platform_pcie_establish_link(struct dw_pcie *pci) -{ - return RT_EOK; -} - -static const struct dw_pcie_ops dw_platform_pcie_ops = -{ - .start_link = dw_platform_pcie_establish_link, -}; - -static rt_err_t dw_platform_pcie_ep_init(struct dw_pcie_ep *ep) -{ - struct dw_pcie *pci = to_dw_pcie_from_endpoint(ep); - - for (int bar = 0; bar < PCI_STD_NUM_BARS; ++bar) - { - dw_pcie_ep_reset_bar(pci, bar); - } - - return RT_EOK; -} - -static rt_err_t dw_platform_pcie_ep_raise_irq(struct dw_pcie_ep *ep, - rt_uint8_t func_no, enum rt_pci_ep_irq type, unsigned irq) -{ - switch (type) - { - case RT_PCI_EP_IRQ_LEGACY: - return dw_pcie_ep_raise_legacy_irq(ep, func_no); - - case RT_PCI_EP_IRQ_MSI: - return dw_pcie_ep_raise_msi_irq(ep, func_no, irq); - - case RT_PCI_EP_IRQ_MSIX: - return dw_pcie_ep_raise_msix_irq(ep, func_no, irq); - - default: - LOG_E("Unknown IRQ type = %d", type); - } - - return RT_EOK; -} - -static const struct dw_pcie_ep_ops dw_platform_pcie_ep_ops = -{ - .ep_init = dw_platform_pcie_ep_init, - .raise_irq = dw_platform_pcie_ep_raise_irq, -}; - -static rt_err_t dw_platform_add_pcie_port(struct dw_platform_pcie *plat_pcie, - struct rt_device *dev) -{ - rt_err_t err; - struct dw_pcie *pci = plat_pcie->pci; - struct dw_pcie_port *port = &pci->port; - - port->sys_irq = rt_dm_dev_get_irq(dev, 1); - - if (port->sys_irq < 0) - { - return port->sys_irq; - } - -#ifdef RT_PCI_MSI - port->msi_irq = rt_dm_dev_get_irq(dev, 0); - - if (port->msi_irq < 0) - { - return port->msi_irq; - } -#endif - - port->ops = &dw_platform_pcie_host_ops; - - if ((err = dw_pcie_host_init(port))) - { - LOG_E("Failed to initialize host"); - return err; - } - - return RT_EOK; -} - -static rt_err_t dw_platform_add_pcie_ep(struct dw_platform_pcie *plat_pcie, - struct rt_device *dev) -{ - rt_err_t err; - struct dw_pcie *pci = plat_pcie->pci; - struct dw_pcie_ep *ep = &pci->endpoint; - - pci->dbi_base2 = rt_dm_dev_iomap_by_name(dev, "dbi2"); - - if (!pci->dbi_base2) - { - return -RT_EIO; - } - - err = rt_dm_dev_get_address_by_name(dev, "addr_space", &ep->aspace, &ep->aspace_size); - - if (err) - { - rt_iounmap(pci->dbi_base2); - return err; - } - - ep->ops = &dw_platform_pcie_ep_ops; - - if ((err = dw_pcie_ep_init(ep))) - { - LOG_E("Failed to initialize endpoint"); - return err; - } - - return RT_EOK; -} - -static rt_err_t dw_platform_pcie_probe(struct rt_platform_device *pdev) -{ - rt_err_t err; - struct dw_pcie *pci = RT_NULL; - struct dw_platform_pcie *plat_pcie; - struct rt_device *dev = &pdev->parent; - - if (!(plat_pcie = rt_calloc(1, sizeof(*plat_pcie)))) - { - return -RT_ENOMEM; - } - - if (!(pci = rt_calloc(1, sizeof(*pci)))) - { - err = -RT_ENOMEM; - goto _fail; - } - - plat_pcie->pci = pci; - plat_pcie->soc_data = pdev->id->data; - - pci->dev = dev; - pci->ops = &dw_platform_pcie_ops; - pci->dbi_base = rt_dm_dev_iomap_by_name(dev, "dbi"); - - if (!pci->dbi_base) - { - err = -RT_EIO; - goto _fail; - } - - dev->user_data = plat_pcie; - - switch (plat_pcie->soc_data->mode) - { - case DW_PCIE_RC_TYPE: - if (!RT_KEY_ENABLED(RT_PCI_DW_HOST)) - { - err = -RT_ENOSYS; - goto _fail; - } - - if ((err = dw_platform_add_pcie_port(plat_pcie, dev))) - { - goto _fail; - } - break; - - case DW_PCIE_EP_TYPE: - if (!RT_KEY_ENABLED(RT_PCI_DW_EP)) - { - err = -RT_ENOSYS; - goto _fail; - } - - if ((err = dw_platform_add_pcie_ep(plat_pcie, dev))) - { - goto _fail; - } - break; - - default: - LOG_E("Invalid device type %d", plat_pcie->soc_data->mode); - err = -RT_EINVAL; - goto _fail; - } - - return RT_EOK; - -_fail: - if (pci) - { - if (pci->dbi_base) - { - rt_iounmap(pci->dbi_base); - } - - rt_free(pci); - } - - rt_free(plat_pcie); - - return err; -} - -static rt_err_t dw_platform_pcie_remove(struct rt_platform_device *pdev) -{ - struct dw_platform_pcie *plat_pcie = pdev->parent.user_data; - - rt_pci_host_bridge_remove(plat_pcie->pci->port.bridge); - dw_pcie_host_free(&plat_pcie->pci->port); - - rt_iounmap(plat_pcie->pci->dbi_base); - rt_free(plat_pcie->pci); - - rt_free(plat_pcie); - - return RT_EOK; -} - -static const struct dw_dw_platform_pcie_soc_data dw_platform_pcie_rc_soc_data = -{ - .mode = DW_PCIE_RC_TYPE, -}; - -static const struct dw_dw_platform_pcie_soc_data dw_platform_pcie_ep_soc_data = -{ - .mode = DW_PCIE_EP_TYPE, -}; - -static const struct rt_ofw_node_id dw_platform_pcie_ofw_ids[] = -{ - { .compatible = "snps,dw-pcie", .data = &dw_platform_pcie_rc_soc_data }, - { .compatible = "snps,dw-pcie-ep", .data = &dw_platform_pcie_ep_soc_data }, - { /* sentinel */ } -}; - -static struct rt_platform_driver dw_platform_pcie_driver = -{ - .name = "dw-pcie", - .ids = dw_platform_pcie_ofw_ids, - - .probe = dw_platform_pcie_probe, - .remove = dw_platform_pcie_remove, -}; -RT_PLATFORM_DRIVER_EXPORT(dw_platform_pcie_driver); diff --git a/rt-thread/components/drivers/pci/host/pci-host-common.c b/rt-thread/components/drivers/pci/host/pci-host-common.c deleted file mode 100644 index 776c020..0000000 --- a/rt-thread/components/drivers/pci/host/pci-host-common.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#include - -#include "../ecam.h" - -rt_err_t pci_host_common_probe(struct rt_platform_device *pdev) -{ - void *base; - rt_err_t err; - struct rt_device *dev = &pdev->parent; - struct pci_ecam_config_window *conf_win; - struct rt_pci_host_bridge *host_bridge = rt_pci_host_bridge_alloc(0); - - if (!host_bridge) - { - return -RT_ENOMEM; - } - - if (!(base = rt_dm_dev_iomap(dev, 0))) - { - err = -RT_EIO; - goto _fail; - } - - host_bridge->parent.ofw_node = dev->ofw_node; - - if ((err = rt_pci_host_bridge_init(host_bridge))) - { - goto _fail; - } - - host_bridge->sysdata = conf_win = pci_ecam_create(host_bridge, - (const struct pci_ecam_ops *)pdev->id->data); - - if (!conf_win) - { - err = -RT_ENOMEM; - goto _fail; - } - - conf_win->win = base; - conf_win->priv = host_bridge; - - if ((err = rt_pci_host_bridge_probe(host_bridge))) - { - goto _fail; - } - - dev->user_data = host_bridge; - - return RT_EOK; - -_fail: - if (base) - { - rt_iounmap(base); - } - rt_pci_host_bridge_free(host_bridge); - - return err; -} - -rt_err_t pci_host_common_remove(struct rt_platform_device *pdev) -{ - struct pci_ecam_config_window *conf_win; - struct rt_pci_host_bridge *host_bridge = pdev->parent.user_data; - - rt_pci_host_bridge_remove(host_bridge); - - conf_win = host_bridge->sysdata; - - rt_iounmap(conf_win->win); - rt_pci_host_bridge_free(host_bridge); - - return RT_EOK; -} diff --git a/rt-thread/components/drivers/pci/host/pci-host-generic.c b/rt-thread/components/drivers/pci/host/pci-host-generic.c deleted file mode 100644 index 7496d52..0000000 --- a/rt-thread/components/drivers/pci/host/pci-host-generic.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#include - -#include "../ecam.h" - -static const struct pci_ecam_ops gen_pci_cfg_cam_bus_ops = -{ - .bus_shift = 16, - .pci_ops = - { - .map = pci_ecam_map, - .read = rt_pci_bus_read_config_uxx, - .write = rt_pci_bus_write_config_uxx, - } -}; - -static void *pci_dw_ecam_map_bus(struct rt_pci_bus *bus, rt_uint32_t devfn, int where) -{ - struct pci_ecam_config_window *conf_win = bus->sysdata; - - if (bus->number == conf_win->bus_range[0] && RT_PCI_SLOT(devfn) > 0) - { - return RT_NULL; - } - - return pci_ecam_map(bus, devfn, where); -} - -static const struct pci_ecam_ops pci_dw_ecam_bus_ops = -{ - .pci_ops = - { - .map = pci_dw_ecam_map_bus, - .read = rt_pci_bus_read_config_uxx, - .write = rt_pci_bus_write_config_uxx, - } -}; - -static const struct rt_ofw_node_id gen_pci_ofw_ids[] = -{ - { .compatible = "pci-host-cam-generic", .data = &gen_pci_cfg_cam_bus_ops }, - { .compatible = "pci-host-ecam-generic", .data = &pci_generic_ecam_ops }, - { .compatible = "marvell,armada8k-pcie-ecam", .data = &pci_dw_ecam_bus_ops }, - { .compatible = "socionext,synquacer-pcie-ecam", .data = &pci_dw_ecam_bus_ops }, - { .compatible = "snps,dw-pcie-ecam", .data = &pci_dw_ecam_bus_ops }, - { /* sentinel */ } -}; - -static struct rt_platform_driver gen_pci_driver = -{ - .name = "pci-host-generic", - .ids = gen_pci_ofw_ids, - - .probe = pci_host_common_probe, - .remove = pci_host_common_remove, -}; -RT_PLATFORM_DRIVER_EXPORT(gen_pci_driver); diff --git a/rt-thread/components/drivers/pci/irq.c b/rt-thread/components/drivers/pci/irq.c deleted file mode 100644 index c7bd1a8..0000000 --- a/rt-thread/components/drivers/pci/irq.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-07 GuEe-GUI first version - */ - -#include - -#define DBG_TAG "pci.irq" -#define DBG_LVL DBG_INFO -#include - -#include - -void rt_pci_assign_irq(struct rt_pci_device *pdev) -{ - int irq = 0; - rt_uint8_t pin, slot = -1; - struct rt_pci_host_bridge *host_bridge = rt_pci_find_host_bridge(pdev->bus); - - if (!host_bridge->irq_map) - { - LOG_D("PCI-Device<%s> runtime IRQ mapping not provided by platform", - rt_dm_dev_get_name(&pdev->parent)); - - return; - } - - /* Must try the swizzle when interrupt line passes through a P2P bridge */ - rt_pci_read_config_u8(pdev, PCIR_INTPIN, &pin); - - if (pin > RT_PCI_INTX_PIN_MAX) - { - pin = 1; - } - - if (pin) - { - if (host_bridge->irq_slot) - { - slot = host_bridge->irq_slot(pdev, &pin); - } - - /* Map IRQ */ - if ((irq = host_bridge->irq_map(pdev, slot, pin)) == -1) - { - irq = 0; - } - } - pdev->irq = irq; - - LOG_D("PCI-Device<%s> assign IRQ: got %d", rt_dm_dev_get_name(&pdev->parent), pdev->irq); - - /* Save IRQ */ - rt_pci_write_config_u8(pdev, PCIR_INTLINE, irq); -} diff --git a/rt-thread/components/drivers/pci/msi/SConscript b/rt-thread/components/drivers/pci/msi/SConscript deleted file mode 100644 index 4def41c..0000000 --- a/rt-thread/components/drivers/pci/msi/SConscript +++ /dev/null @@ -1,15 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_PCI_MSI']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../../include'] - -src = ['device.c', 'irq.c', 'msi.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/pci/msi/device.c b/rt-thread/components/drivers/pci/msi/device.c deleted file mode 100644 index 36d0d0d..0000000 --- a/rt-thread/components/drivers/pci/msi/device.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#include - -void rt_pci_msi_init(struct rt_pci_device *pdev) -{ - if (pdev && (pdev->msi_cap = rt_pci_find_capability(pdev, PCIY_MSI))) - { - rt_uint16_t ctrl; - - rt_pci_read_config_u16(pdev, pdev->msi_cap + PCIR_MSI_CTRL, &ctrl); - - if (ctrl & PCIM_MSICTRL_MSI_ENABLE) - { - rt_pci_write_config_u16(pdev, pdev->msi_cap + PCIR_MSI_CTRL, ctrl & ~PCIM_MSICTRL_MSI_ENABLE); - } - - if (!(ctrl & PCIM_MSICTRL_64BIT)) - { - pdev->no_64bit_msi = RT_TRUE; - } - } -} - -void rt_pci_msix_init(struct rt_pci_device *pdev) -{ - if (pdev && (pdev->msix_cap = rt_pci_find_capability(pdev, PCIY_MSIX))) - { - rt_uint16_t ctrl; - - rt_pci_read_config_u16(pdev, pdev->msix_cap + PCIR_MSIX_CTRL, &ctrl); - - if (ctrl & PCIM_MSIXCTRL_MSIX_ENABLE) - { - rt_pci_write_config_u16(pdev, pdev->msix_cap + PCIR_MSIX_CTRL, ctrl & ~PCIM_MSIXCTRL_MSIX_ENABLE); - } - } -} diff --git a/rt-thread/components/drivers/pci/msi/irq.c b/rt-thread/components/drivers/pci/msi/irq.c deleted file mode 100644 index 8e81e5d..0000000 --- a/rt-thread/components/drivers/pci/msi/irq.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#include - -#define DBG_TAG "pci.msi.irq" -#define DBG_LVL DBG_INFO -#include - -static struct rt_spinlock msi_irq_map_lock = {}; -static RT_BITMAP_DECLARE(msi_irq_map, MAX_HANDLERS) = {}; - -rt_err_t rt_pci_msi_setup_irqs(struct rt_pci_device *pdev, int nvec, int type) -{ - int irq, index = 0, irq_nr = 0; - rt_err_t err = RT_EOK; - struct rt_pic_irq *pirq; - struct rt_pic *msi_pic; - struct rt_pci_msi_desc *desc; - - if (!pdev) - { - return -RT_EINVAL; - } - - msi_pic = pdev->msi_pic; - - if (type == PCIY_MSI) - { - int last_irq = -1, irq_idx; - rt_size_t irq_nr; - - desc = rt_pci_msi_first_desc(pdev); - irq_nr = 1 << desc->msi.cap.multi_msg_use; - - rt_hw_spin_lock(&msi_irq_map_lock.lock); - - _retry: - for (int i = 0; i < irq_nr; ++i) - { - if ((irq = msi_pic->ops->irq_alloc_msi(msi_pic, desc)) < 0) - { - err = irq; - - LOG_E("Setup %s[%d] IRQ error = %s", "MSI", i, rt_strerror(err)); - - break; - } - - if (last_irq >= 0 && last_irq + 1 != irq) - { - for (int idx = 0; idx < i; ++i, --last_irq) - { - rt_bitmap_set_bit(msi_irq_map, last_irq); - } - - last_irq = irq; - goto _retry; - } - - last_irq = irq; - } - - if (!err) - { - /* Get the first irq */ - desc->irq = irq - (irq_nr - 1); - } - - rt_bitmap_for_each_set_bit(msi_irq_map, irq_idx, MAX_HANDLERS) - { - msi_pic->ops->irq_free_msi(msi_pic, irq_idx); - - /* Free bit so the next user doesn't need to bzero */ - rt_bitmap_clear_bit(msi_irq_map, irq_idx); - } - - rt_hw_spin_unlock(&msi_irq_map_lock.lock); - - if (!err) - { - for (int idx = 0; idx < nvec; ++idx) - { - pirq = rt_pic_find_pirq(msi_pic, irq + idx); - pirq->msi_desc = desc; - - msi_pic->ops->irq_compose_msi_msg(pirq, &desc->msg); - - rt_pci_msi_write_msg(desc, &desc->msg); - } - } - } - else if (type == PCIY_MSIX) - { - rt_pci_msi_for_each_desc(pdev, desc) - { - if ((irq = msi_pic->ops->irq_alloc_msi(msi_pic, desc)) < 0) - { - err = irq; - - LOG_E("Setup %s[%d] IRQ error = %s", "MSI-X", - desc->msix.index, rt_strerror(err)); - - break; - } - - desc->irq = irq; - pirq = rt_pic_find_pirq(msi_pic, irq); - pirq->msi_desc = desc; - - msi_pic->ops->irq_compose_msi_msg(pirq, &desc->msg); - - rt_pci_msi_write_msg(desc, &desc->msg); - - ++irq_nr; - } - - if (err) - { - rt_pci_msi_for_each_desc(pdev, desc) - { - if (index >= irq_nr) - { - break; - } - - msi_pic->ops->irq_free_msi(msi_pic, desc->irq); - - ++index; - } - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} diff --git a/rt-thread/components/drivers/pci/msi/msi.c b/rt-thread/components/drivers/pci/msi/msi.c deleted file mode 100644 index eb0d578..0000000 --- a/rt-thread/components/drivers/pci/msi/msi.c +++ /dev/null @@ -1,949 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-07 GuEe-GUI first version - */ - -#include -#include - -#define DBG_TAG "pci.msi" -#define DBG_LVL DBG_INFO -#include - -/* PCI has 2048 max IRQs in MSI-X */ -static RT_IRQ_AFFINITY_DECLARE(msi_affinity_default[2048]) rt_section(".bss.noclean.pci.msi"); - -rt_inline void spin_lock(struct rt_spinlock *lock) -{ - rt_hw_spin_lock(&lock->lock); -} - -rt_inline void spin_unlock(struct rt_spinlock *lock) -{ - rt_hw_spin_unlock(&lock->lock); -} - -rt_inline void *msix_table_base(struct rt_pci_msix_conf *msix) -{ - return msix->table_base + msix->index * PCIM_MSIX_ENTRY_SIZE; -} - -rt_inline void *msix_vector_ctrl_base(struct rt_pci_msix_conf *msix) -{ - return msix_table_base(msix) + PCIM_MSIX_ENTRY_VECTOR_CTRL; -} - -rt_inline void msix_write_vector_ctrl(struct rt_pci_msix_conf *msix, - rt_uint32_t ctrl) -{ - void *vc_addr = msix_vector_ctrl_base(msix); - - HWREG32(vc_addr) = ctrl; -} - -rt_inline void msix_mask(struct rt_pci_msix_conf *msix) -{ - msix->msg_ctrl |= PCIM_MSIX_ENTRYVECTOR_CTRL_MASK; - msix_write_vector_ctrl(msix, msix->msg_ctrl); - - /* Flush write to device */ - HWREG32(msix->table_base); -} - -static void msix_update_ctrl(struct rt_pci_device *pdev, - rt_uint16_t clear, rt_uint16_t set) -{ - rt_uint16_t msgctl; - - rt_pci_read_config_u16(pdev, pdev->msix_cap + PCIR_MSIX_CTRL, &msgctl); - msgctl &= ~clear; - msgctl |= set; - rt_pci_write_config_u16(pdev, pdev->msix_cap + PCIR_MSIX_CTRL, msgctl); -} - -rt_inline void msix_unmask(struct rt_pci_msix_conf *msix) -{ - msix->msg_ctrl &= ~PCIM_MSIX_ENTRYVECTOR_CTRL_MASK; - msix_write_vector_ctrl(msix, msix->msg_ctrl); -} - -rt_inline rt_uint32_t msi_multi_mask(struct rt_pci_msi_conf *msi) -{ - if (msi->cap.multi_msg_max >= 5) - { - return 0xffffffff; - } - - return (1 << (1 << msi->cap.multi_msg_max)) - 1; -} - -static void msi_write_mask(struct rt_pci_msi_conf *msi, - rt_uint32_t clear, rt_uint32_t set, struct rt_pci_device *pdev) -{ - if (msi->cap.is_masking) - { - rt_ubase_t level = rt_spin_lock_irqsave(&pdev->msi_lock); - - msi->mask &= ~clear; - msi->mask |= set; - rt_pci_write_config_u32(pdev, msi->mask_pos, msi->mask); - - rt_spin_unlock_irqrestore(&pdev->msi_lock, level); - } -} - -rt_inline void msi_mask(struct rt_pci_msi_conf *msi, - rt_uint32_t mask, struct rt_pci_device *pdev) -{ - msi_write_mask(msi, 0, mask, pdev); -} - -rt_inline void msi_unmask(struct rt_pci_msi_conf *msi, - rt_uint32_t mask, struct rt_pci_device *pdev) -{ - msi_write_mask(msi, mask, 0, pdev); -} - -static void msi_write_enable(struct rt_pci_device *pdev, rt_bool_t enable) -{ - rt_uint16_t msgctl; - - rt_pci_read_config_u16(pdev, pdev->msi_cap + PCIR_MSI_CTRL, &msgctl); - - msgctl &= ~PCIM_MSICTRL_MSI_ENABLE; - - if (enable) - { - msgctl |= PCIM_MSICTRL_MSI_ENABLE; - } - - rt_pci_write_config_u16(pdev, pdev->msi_cap + PCIR_MSI_CTRL, msgctl); -} - -static void msi_affinity_init(struct rt_pci_msi_desc *desc, int msi_index, - rt_bitmap_t *cpumasks) -{ - int irq; - struct rt_pic_irq *pirq; - struct rt_pci_device *pdev = desc->pdev; - struct rt_pic *msi_pic = pdev->msi_pic; - - irq = desc->irq + desc->is_msix ? 0 : msi_index; - pirq = rt_pic_find_pirq(msi_pic, irq); - - /* Save affinity */ - if (desc->is_msix) - { - desc->affinity = pirq->affinity; - } - else - { - desc->affinities[msi_index] = pirq->affinity; - } - - if ((void *)cpumasks > (void *)msi_affinity_default && - (void *)cpumasks < (void *)msi_affinity_default + sizeof(msi_affinity_default)) - { - rt_uint64_t data_address; - - /* Get MSI/MSI-X write data adddress */ - data_address = desc->msg.address_hi; - data_address <<= 32; - data_address |= desc->msg.address_lo; - - /* Prepare affinity */ - cpumasks = pirq->affinity; - - rt_numa_memory_affinity(data_address, cpumasks); - } - else if (rt_bitmap_next_set_bit(cpumasks, 0, RT_CPUS_NR) >= RT_CPUS_NR) - { - /* No affinity info found, give up */ - return; - } - - if (!rt_pic_irq_set_affinity(irq, cpumasks)) - { - if (msi_pic->ops->irq_write_msi_msg) - { - msi_pic->ops->irq_write_msi_msg(pirq, &desc->msg); - } - } -} - -void rt_pci_msi_shutdown(struct rt_pci_device *pdev) -{ - struct rt_pci_msi_desc *desc; - - if (!pdev) - { - return; - } - - msi_write_enable(pdev, RT_FALSE); - rt_pci_intx(pdev, RT_TRUE); - - if ((desc = rt_pci_msi_first_desc(pdev))) - { - msi_unmask(&desc->msi, msi_multi_mask(&desc->msi), pdev); - } - - /* Restore pdev->irq to its default pin-assertion IRQ */ - pdev->irq = desc->msi.default_irq; - pdev->msi_enabled = RT_FALSE; -} - -void rt_pci_msix_shutdown(struct rt_pci_device *pdev) -{ - struct rt_pci_msi_desc *desc; - - if (!pdev) - { - return; - } - - rt_pci_msi_for_each_desc(pdev, desc) - { - msix_mask(&desc->msix); - } - - msix_update_ctrl(pdev, PCIM_MSIXCTRL_MSIX_ENABLE, 0); - - rt_pci_intx(pdev, RT_TRUE); - pdev->msix_enabled = RT_FALSE; -} - -void rt_pci_msi_free_irqs(struct rt_pci_device *pdev) -{ - struct rt_pci_msi_desc *desc, *last_desc = RT_NULL; - - if (!pdev) - { - return; - } - - if (pdev->msix_base) - { - rt_iounmap(pdev->msix_base); - pdev->msix_base = RT_NULL; - } - - rt_pci_msi_for_each_desc(pdev, desc) - { - /* To safety */ - if (last_desc) - { - rt_list_remove(&last_desc->list); - rt_free(last_desc); - } - last_desc = desc; - } - - /* The last one */ - if (last_desc) - { - rt_list_remove(&last_desc->list); - rt_free(last_desc); - } -} - -void rt_pci_msi_write_msg(struct rt_pci_msi_desc *desc, struct rt_pci_msi_msg *msg) -{ - struct rt_pci_device *pdev = desc->pdev; - - if (desc->is_msix) - { - void *msix_entry; - rt_bool_t unmasked; - rt_uint32_t msgctl; - struct rt_pci_msix_conf *msix = &desc->msix; - - msgctl = msix->msg_ctrl; - unmasked = !(msgctl & PCIM_MSIX_ENTRYVECTOR_CTRL_MASK); - msix_entry = msix_table_base(msix); - - if (unmasked) - { - msix_write_vector_ctrl(msix, msgctl | PCIM_MSIX_ENTRYVECTOR_CTRL_MASK); - } - - HWREG32(msix_entry + PCIM_MSIX_ENTRY_LOWER_ADDR) = msg->address_lo; - HWREG32(msix_entry + PCIM_MSIX_ENTRY_UPPER_ADDR) = msg->address_hi; - HWREG32(msix_entry + PCIM_MSIX_ENTRY_DATA) = msg->data; - - if (unmasked) - { - msix_write_vector_ctrl(msix, msgctl); - } - - /* Ensure that the writes are visible in the device */ - HWREG32(msix_entry + PCIM_MSIX_ENTRY_DATA); - } - else - { - rt_uint16_t msgctl; - int pos = pdev->msi_cap; - struct rt_pci_msi_conf *msi = &desc->msi; - - rt_pci_read_config_u16(pdev, pos + PCIR_MSI_CTRL, &msgctl); - msgctl &= ~PCIM_MSICTRL_MME_MASK; - msgctl |= msi->cap.multi_msg_use << PCIM_MSICTRL_MME_SHIFT; - rt_pci_write_config_u16(pdev, pos + PCIR_MSI_CTRL, msgctl); - - rt_pci_write_config_u32(pdev, pos + PCIR_MSI_ADDR, msg->address_lo); - - /* - * The value stored in this field is related to the processor system, - * the processor will initialize this field - * when the PCIe device is initialized, and the rules for filling - * in this field are not the same for different processors. - * If the Multiple Message Enable field is not 0b000 (multiple IRQs), - * the PCIe device can send different interrupt requests - * by changing the low data in the Message Data field - */ - if (msi->cap.is_64bit) - { - rt_pci_write_config_u32(pdev, pos + PCIR_MSI_ADDR_HIGH, msg->address_hi); - rt_pci_write_config_u16(pdev, pos + PCIR_MSI_DATA_64BIT, msg->data); - } - else - { - rt_pci_write_config_u16(pdev, pos + PCIR_MSI_DATA, msg->data); - } - - /* Ensure that the writes are visible in the device */ - rt_pci_read_config_u16(pdev, pos + PCIR_MSI_CTRL, &msgctl); - } - - desc->msg = *msg; - - if (desc->write_msi_msg) - { - desc->write_msi_msg(desc, desc->write_msi_msg_data); - } -} - -void rt_pci_msi_mask_irq(struct rt_pic_irq *pirq) -{ - struct rt_pci_msi_desc *desc; - - if (pirq && (desc = pirq->msi_desc)) - { - if (desc->is_msix) - { - msix_mask(&desc->msix); - } - else - { - msi_mask(&desc->msi, RT_BIT(pirq->irq - desc->irq), desc->pdev); - } - } -} - -void rt_pci_msi_unmask_irq(struct rt_pic_irq *pirq) -{ - struct rt_pci_msi_desc *desc; - - if (pirq && (desc = pirq->msi_desc)) - { - if (desc->is_msix) - { - msix_unmask(&desc->msix); - } - else - { - msi_unmask(&desc->msi, RT_BIT(pirq->irq - desc->irq), desc->pdev); - } - } -} - -rt_ssize_t rt_pci_alloc_vector(struct rt_pci_device *pdev, int min, int max, - rt_uint32_t flags, RT_IRQ_AFFINITY_DECLARE((*affinities))) -{ - rt_ssize_t res = -RT_ENOSYS; - - if (!pdev || min > max) - { - return -RT_EINVAL; - } - - if (flags & RT_PCI_IRQ_F_AFFINITY) - { - if (!affinities) - { - affinities = msi_affinity_default; - } - } - else - { - affinities = RT_NULL; - } - - if (flags & RT_PCI_IRQ_F_MSIX) - { - res = rt_pci_msix_enable_range_affinity(pdev, RT_NULL, min, max, affinities); - - if (res > 0) - { - return res; - } - } - - if (flags & RT_PCI_IRQ_F_MSI) - { - res = rt_pci_msi_enable_range_affinity(pdev, min, max, affinities); - - if (res > 0) - { - return res; - } - } - - if (flags & RT_PCI_IRQ_F_LEGACY) - { - if (min == 1 && pdev->irq >= 0) - { - if (affinities) - { - int cpuid; - RT_IRQ_AFFINITY_DECLARE(old_affinity); - - /* INTx is shared, we should update it */ - rt_pic_irq_get_affinity(pdev->irq, old_affinity); - - rt_bitmap_for_each_set_bit(affinities[0], cpuid, RT_CPUS_NR) - { - RT_IRQ_AFFINITY_SET(old_affinity, cpuid); - } - - rt_pic_irq_set_affinity(pdev->irq, old_affinity); - } - - rt_pci_intx(pdev, RT_TRUE); - - return min; - } - } - - return res; -} - -void rt_pci_free_vector(struct rt_pci_device *pdev) -{ - if (!pdev) - { - return; - } - - rt_pci_msi_disable(pdev); - rt_pci_msix_disable(pdev); - rt_pci_irq_mask(pdev); -} - -static rt_err_t msi_verify_entries(struct rt_pci_device *pdev) -{ - if (pdev->no_64bit_msi) - { - struct rt_pci_msi_desc *desc; - - rt_pci_msi_for_each_desc(pdev, desc) - { - if (desc->msg.address_hi) - { - LOG_D("%s: Arch assigned 64-bit MSI address %08x%08x" - "but device only supports 32 bits", - rt_dm_dev_get_name(&pdev->parent), - desc->msg.address_hi, desc->msg.address_lo); - - return -RT_EIO; - } - } - } - - return RT_EOK; -} - -static rt_err_t msi_insert_desc(struct rt_pci_device *pdev, - struct rt_pci_msi_desc *init_desc) -{ - rt_size_t msi_affinity_ptr_size = 0; - struct rt_pci_msi_desc *msi_desc; - - if (!init_desc->is_msix) - { - msi_affinity_ptr_size += sizeof(msi_desc->affinities[0]) * 32; - } - - msi_desc = rt_calloc(1, sizeof(*msi_desc) + msi_affinity_ptr_size); - - if (!msi_desc) - { - return -RT_ENOMEM; - } - - rt_memcpy(msi_desc, init_desc, sizeof(*msi_desc)); - - if (!init_desc->is_msix) - { - msi_desc->affinities = (void *)msi_desc + sizeof(*msi_desc); - } - - msi_desc->pdev = pdev; - rt_list_init(&msi_desc->list); - rt_list_insert_before(&pdev->msi_desc_nodes, &msi_desc->list); - - return RT_EOK; -} - -rt_ssize_t rt_pci_msi_vector_count(struct rt_pci_device *pdev) -{ - rt_uint16_t msgctl; - - if (!pdev) - { - return -RT_EINVAL; - } - - if (!pdev->msi_cap) - { - return -RT_EINVAL; - } - - rt_pci_read_config_u16(pdev, pdev->msi_cap + PCIR_MSI_CTRL, &msgctl); - - return 1 << ((msgctl & PCIM_MSICTRL_MMC_MASK) >> 1); -} - -rt_err_t rt_pci_msi_disable(struct rt_pci_device *pdev) -{ - if (!pdev) - { - return -RT_EINVAL; - } - - if (!pdev->msi_enabled) - { - return -RT_EINVAL; - } - - spin_lock(&pdev->msi_lock); - - rt_pci_msi_shutdown(pdev); - rt_pci_msi_free_irqs(pdev); - - spin_unlock(&pdev->msi_lock); - - return RT_EOK; -} - -static rt_err_t msi_setup_msi_desc(struct rt_pci_device *pdev, int nvec) -{ - rt_uint16_t msgctl; - struct rt_pci_msi_desc desc; - - rt_memset(&desc, 0, sizeof(desc)); - - desc.vector_used = nvec; - desc.vector_count = rt_pci_msi_vector_count(pdev); - desc.is_msix = RT_FALSE; - - rt_pci_read_config_u16(pdev, pdev->msi_cap + PCIR_MSI_CTRL, &msgctl); - - desc.msi.cap.is_64bit = !!(msgctl & PCIM_MSICTRL_64BIT); - desc.msi.cap.is_masking = !!(msgctl & PCIM_MSICTRL_VECTOR); - desc.msi.cap.multi_msg_max = (msgctl & PCIM_MSICTRL_MMC_MASK) >> 1; - - for (int log2 = 0; log2 < 5; ++log2) - { - if (nvec <= (1 << log2)) - { - desc.msi.cap.multi_msg_use = log2; - break; - } - } - - if (desc.msi.cap.is_64bit) - { - desc.msi.mask_pos = pdev->msi_cap + PCIR_MSI_MASK_64BIT; - } - else - { - desc.msi.mask_pos = pdev->msi_cap + PCIR_MSI_MASK; - } - - /* Save pdev->irq for its default pin-assertion IRQ */ - desc.msi.default_irq = pdev->irq; - - if (desc.msi.cap.is_masking) - { - /* Get the old mask status */ - rt_pci_read_config_u32(pdev, desc.msi.mask_pos, &desc.msi.mask); - } - - return msi_insert_desc(pdev, &desc); -} - -static rt_ssize_t msi_capability_init(struct rt_pci_device *pdev, - int nvec, RT_IRQ_AFFINITY_DECLARE((*affinities))) -{ - rt_err_t err; - struct rt_pci_msi_desc *desc; - - msi_write_enable(pdev, RT_FALSE); - - spin_lock(&pdev->msi_lock); - - if (!(err = msi_setup_msi_desc(pdev, nvec))) - { - /* All MSIs are unmasked by default; mask them all */ - desc = rt_pci_msi_first_desc(pdev); - msi_mask(&desc->msi, msi_multi_mask(&desc->msi), pdev); - - if (!(err = rt_pci_msi_setup_irqs(pdev, nvec, PCIY_MSI))) - { - err = msi_verify_entries(pdev); - } - - if (err) - { - msi_unmask(&desc->msi, msi_multi_mask(&desc->msi), pdev); - } - } - - spin_unlock(&pdev->msi_lock); - - if (err) - { - rt_pci_msi_free_irqs(pdev); - - LOG_E("%s: Setup %s interrupts(%d) error = %s", - rt_dm_dev_get_name(&pdev->parent), "MSI", nvec, rt_strerror(err)); - - return err; - } - - if (affinities) - { - for (int idx = 0; idx < nvec; ++idx) - { - msi_affinity_init(desc, idx, affinities[idx]); - } - } - - /* Disable INTX */ - rt_pci_intx(pdev, RT_FALSE); - - /* Set MSI enabled bits */ - msi_write_enable(pdev, RT_TRUE); - - pdev->irq = desc->irq; - - pdev->msi_enabled = RT_TRUE; - - return nvec; -} - -rt_ssize_t rt_pci_msi_enable_range_affinity(struct rt_pci_device *pdev, - int min, int max, RT_IRQ_AFFINITY_DECLARE((*affinities))) -{ - int nvec = max; - rt_size_t entries_nr; - - if (!pdev || min > max) - { - return -RT_EINVAL; - } - - if (pdev->no_msi) - { - return -RT_ENOSYS; - } - - if (!pdev->msi_pic) - { - return -RT_ENOSYS; - } - - if (pdev->msi_enabled) - { - LOG_W("%s: MSI is enabled", rt_dm_dev_get_name(&pdev->parent)); - - return -RT_EINVAL; - } - - entries_nr = rt_pci_msi_vector_count(pdev); - - if (entries_nr < 0) - { - return entries_nr; - } - - if (nvec > entries_nr) - { - return -RT_EEMPTY; - } - - return msi_capability_init(pdev, nvec, affinities); -} - -rt_ssize_t rt_pci_msix_vector_count(struct rt_pci_device *pdev) -{ - rt_uint16_t msgctl; - - if (!pdev) - { - return -RT_EINVAL; - } - - if (!pdev->msix_cap) - { - return -RT_EINVAL; - } - - rt_pci_read_config_u16(pdev, pdev->msix_cap + PCIR_MSIX_CTRL, &msgctl); - - return rt_pci_msix_table_size(msgctl); -} - -rt_err_t rt_pci_msix_disable(struct rt_pci_device *pdev) -{ - if (!pdev) - { - return -RT_EINVAL; - } - - if (!pdev->msix_enabled) - { - return -RT_EINVAL; - } - - spin_lock(&pdev->msi_lock); - - rt_pci_msix_shutdown(pdev); - rt_pci_msi_free_irqs(pdev); - - spin_unlock(&pdev->msi_lock); - - return RT_EOK; -} - -static void *msix_table_remap(struct rt_pci_device *pdev, rt_size_t entries_nr) -{ - rt_uint8_t bir; - rt_uint32_t table_offset; - rt_ubase_t table_base_phys; - - rt_pci_read_config_u32(pdev, pdev->msix_cap + PCIR_MSIX_TABLE, &table_offset); - bir = (rt_uint8_t)(table_offset & PCIM_MSIX_BIR_MASK); - - if (pdev->resource[bir].flags & PCI_BUS_REGION_F_NONE) - { - LOG_E("%s: BAR[bir = %d] is invalid", rt_dm_dev_get_name(&pdev->parent), bir); - - return RT_NULL; - } - - table_base_phys = pdev->resource[bir].base + (table_offset & ~PCIM_MSIX_BIR_MASK); - - return rt_ioremap((void *)table_base_phys, entries_nr * PCIM_MSIX_ENTRY_SIZE); -} - -static rt_err_t msix_setup_msi_descs(struct rt_pci_device *pdev, - void *table_base, struct rt_pci_msix_entry *entries, int nvec) -{ - rt_err_t err; - struct rt_pci_msi_desc desc; - - rt_memset(&desc, 0, sizeof(desc)); - - desc.vector_used = 1; - desc.vector_count = rt_pci_msix_vector_count(pdev); - - desc.is_msix = RT_TRUE; - desc.msix.table_base = table_base; - - for (int i = 0; i < nvec; ++i) - { - void *table_entry; - int index = entries ? entries[i].index : i; - - desc.msix.index = index; - table_entry = msix_table_base(&desc.msix); - - desc.msix.msg_ctrl = HWREG32(table_entry + PCIM_MSIX_ENTRY_VECTOR_CTRL); - - if ((err = msi_insert_desc(pdev, &desc))) - { - break; - } - } - - return err; -} - -static rt_ssize_t msix_capability_init(struct rt_pci_device *pdev, - struct rt_pci_msix_entry *entries, int nvec, - RT_IRQ_AFFINITY_DECLARE((*affinities))) -{ - rt_err_t err; - rt_uint16_t msgctl; - rt_size_t table_size; - void *table_base, *table_entry; - struct rt_pci_msi_desc *desc; - struct rt_pci_msix_entry *entry; - - /* - * Some devices require MSI-X to be enabled before the MSI-X - * registers can be accessed. - * Mask all the vectors to prevent interrupts coming in before - * they're fully set up. - */ - msix_update_ctrl(pdev, 0, PCIM_MSIXCTRL_FUNCTION_MASK | PCIM_MSIXCTRL_MSIX_ENABLE); - - rt_pci_read_config_u16(pdev, pdev->msix_cap + PCIR_MSIX_CTRL, &msgctl); - /* Request & Map MSI-X table region */ - table_size = rt_pci_msix_table_size(msgctl); - table_base = msix_table_remap(pdev, table_size); - - if (!table_base) - { - LOG_E("%s: Remap MSI-X table fail", rt_dm_dev_get_name(&pdev->parent)); - - err = -RT_ENOMEM; - goto _out_disbale_msix; - } - - pdev->msix_base = table_base; - - spin_lock(&pdev->msi_lock); - - if (!(err = msix_setup_msi_descs(pdev, table_base, entries, nvec))) - { - if (!(err = rt_pci_msi_setup_irqs(pdev, nvec, PCIY_MSIX))) - { - /* Check if all MSI entries honor device restrictions */ - err = msi_verify_entries(pdev); - } - } - - spin_unlock(&pdev->msi_lock); - - if (err) - { - rt_pci_msi_free_irqs(pdev); - - LOG_E("%s: Setup %s interrupts(%d) error = %s", - rt_dm_dev_get_name(&pdev->parent), "MSI-X", nvec, rt_strerror(err)); - - goto _out_disbale_msix; - } - - entry = entries; - rt_pci_msi_for_each_desc(pdev, desc) - { - if (affinities) - { - msi_affinity_init(desc, desc->msix.index, affinities[entry->index]); - } - - entry->irq = desc->irq; - ++entry; - } - - /* Disable INTX */ - rt_pci_intx(pdev, RT_FALSE); - - /* Maske all table entries */ - table_entry = table_base; - for (int i = 0; i < table_size; ++i, table_entry += PCIM_MSIX_ENTRY_SIZE) - { - HWREG32(table_entry + PCIM_MSIX_ENTRY_VECTOR_CTRL) = PCIM_MSIX_ENTRYVECTOR_CTRL_MASK; - } - msix_update_ctrl(pdev, PCIM_MSIXCTRL_FUNCTION_MASK, 0); - - pdev->msix_enabled = RT_TRUE; - - return nvec; - -_out_disbale_msix: - msix_update_ctrl(pdev, PCIM_MSIXCTRL_FUNCTION_MASK | PCIM_MSIXCTRL_MSIX_ENABLE, 0); - - return err; -} - -rt_ssize_t rt_pci_msix_enable_range_affinity(struct rt_pci_device *pdev, - struct rt_pci_msix_entry *entries, int min, int max, - RT_IRQ_AFFINITY_DECLARE((*affinities))) -{ - int nvec = max; - rt_size_t entries_nr; - - if (!pdev || min > max) - { - return -RT_EINVAL; - } - - if (pdev->no_msi) - { - return -RT_ENOSYS; - } - - if (!pdev->msi_pic) - { - return -RT_ENOSYS; - } - - if (pdev->msix_enabled) - { - LOG_W("%s: MSI-X is enabled", rt_dm_dev_get_name(&pdev->parent)); - - return -RT_EINVAL; - } - - entries_nr = rt_pci_msix_vector_count(pdev); - - if (entries_nr < 0) - { - return entries_nr; - } - - if (nvec > entries_nr) - { - return -RT_EEMPTY; - } - - if (!entries) - { - return 0; - } - - /* Check if entries is valid */ - for (int i = 0; i < nvec; ++i) - { - struct rt_pci_msix_entry *target = &entries[i]; - - if (target->index >= entries_nr) - { - return -RT_EINVAL; - } - - for (int j = i + 1; j < nvec; ++j) - { - /* Check duplicate */ - if (target->index == entries[j].index) - { - LOG_E("%s: msix entry[%d].index = entry[%d].index", - rt_dm_dev_get_name(&pdev->parent), i, j); - - return -RT_EINVAL; - } - } - } - - return msix_capability_init(pdev, entries, nvec, affinities); -} diff --git a/rt-thread/components/drivers/pci/ofw.c b/rt-thread/components/drivers/pci/ofw.c deleted file mode 100644 index 0207e7a..0000000 --- a/rt-thread/components/drivers/pci/ofw.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#include -#include - -#define DBG_TAG "pci.ofw" -#define DBG_LVL DBG_INFO -#include - -#include -#include -#include -#include -#include - -static rt_err_t pci_ofw_irq_parse(struct rt_pci_device *pdev, struct rt_ofw_cell_args *out_irq) -{ - rt_err_t err = RT_EOK; - rt_uint8_t pin; - fdt32_t map_addr[4]; - struct rt_pci_device *p2pdev; - struct rt_ofw_node *dev_np, *p2pnode = RT_NULL; - - /* Parse device tree if dev have a device node */ - dev_np = pdev->parent.ofw_node; - - if (dev_np) - { - err = rt_ofw_parse_irq_cells(dev_np, 0, out_irq); - - if (err) - { - return err; - } - } - - /* Assume #interrupt-cells is 1 */ - if ((err = rt_pci_read_config_u8(pdev, PCIR_INTPIN, &pin))) - { - goto _err; - } - - /* No pin, exit with no error message. */ - if (pin == 0) - { - return -RT_ENOSYS; - } - - /* Try local interrupt-map in the device node */ - if (rt_ofw_prop_read_raw(dev_np, "interrupt-map", RT_NULL)) - { - pin = rt_pci_irq_intx(pdev, pin); - p2pnode = dev_np; - } - - /* Walk up the PCI tree */ - while (!p2pnode) - { - p2pdev = pdev->bus->self; - - /* Is the root bus -> host bridge */ - if (rt_pci_is_root_bus(pdev->bus)) - { - struct rt_pci_host_bridge *host_bridge = pdev->bus->host_bridge; - - p2pnode = host_bridge->parent.ofw_node; - - if (!p2pnode) - { - err = -RT_EINVAL; - - goto _err; - } - } - else - { - /* Is P2P bridge */ - p2pnode = p2pdev->parent.ofw_node; - } - - if (p2pnode) - { - break; - } - - /* Try get INTx in P2P */ - pin = rt_pci_irq_intx(pdev, pin); - pdev = p2pdev; - } - - /* For more format detail, please read `components/drivers/ofw/irq.c:ofw_parse_irq_map` */ - out_irq->data = map_addr; - out_irq->args_count = 2; - out_irq->args[0] = 3; - out_irq->args[1] = 1; - - /* In addr cells */ - map_addr[0] = cpu_to_fdt32((pdev->bus->number << 16) | (pdev->devfn << 8)); - map_addr[1] = cpu_to_fdt32(0); - map_addr[2] = cpu_to_fdt32(0); - /* In pin cells */ - map_addr[3] = cpu_to_fdt32(pin); - - err = rt_ofw_parse_irq_map(p2pnode, out_irq); - -_err: - if (err == -RT_EEMPTY) - { - LOG_W("PCI-Device<%s> no interrupt-map found, INTx interrupts not available", - rt_dm_dev_get_name(&pdev->parent)); - LOG_W("PCI-Device<%s> possibly some PCI slots don't have level triggered interrupts capability", - rt_dm_dev_get_name(&pdev->parent)); - } - else if (err && err != -RT_ENOSYS) - { - LOG_E("PCI-Device<%s> irq parse failed with err = %s", - rt_dm_dev_get_name(&pdev->parent), rt_strerror(err)); - } - - return err; -} - -int rt_pci_ofw_irq_parse_and_map(struct rt_pci_device *pdev, - rt_uint8_t slot, rt_uint8_t pin) -{ - int irq = -1; - rt_err_t status; - struct rt_ofw_cell_args irq_args; - - if (!pdev) - { - goto _end; - } - - status = pci_ofw_irq_parse(pdev, &irq_args); - - if (status) - { - goto _end; - } - - irq = rt_ofw_map_irq(&irq_args); - - if (irq >= 0) - { - pdev->intx_pic = rt_pic_dynamic_cast(rt_ofw_data(irq_args.data)); - } - -_end: - return irq; -} - -static rt_err_t pci_ofw_parse_ranges(struct rt_ofw_node *dev_np, const char *propname, - int phy_addr_cells, int phy_size_cells, int cpu_addr_cells, - struct rt_pci_bus_region **out_regions, rt_size_t *out_regions_nr) -{ - const fdt32_t *cell; - rt_ssize_t total_cells; - int groups, space_code; - rt_uint32_t phy_addr[3]; - rt_uint64_t cpu_addr, phy_addr_size; - - *out_regions = RT_NULL; - *out_regions_nr = 0; - cell = rt_ofw_prop_read_raw(dev_np, propname, &total_cells); - - if (!cell) - { - return -RT_EEMPTY; - } - - groups = total_cells / sizeof(*cell) / (phy_addr_cells + phy_size_cells + cpu_addr_cells); - *out_regions = rt_malloc(groups * sizeof(struct rt_pci_bus_region)); - - if (!*out_regions) - { - return -RT_ENOMEM; - } - - for (int i = 0; i < groups; ++i) - { - /* - * ranges: - * phys.hi cell: npt000ss bbbbbbbb dddddfff rrrrrrrr - * phys.low cell: llllllll llllllll llllllll llllllll - * phys.mid cell: hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh - * - * n: relocatable region flag (doesn't play a role here) - * p: prefetchable (cacheable) region flag - * t: aliased address flag (doesn't play a role here) - * ss: space code - * 00: configuration space - * 01: I/O space - * 10: 32 bit memory space - * 11: 64 bit memory space - * bbbbbbbb: The PCI bus number - * ddddd: The device number - * fff: The function number. Used for multifunction PCI devices. - * rrrrrrrr: Register number; used for configuration cycles. - */ - - for (int j = 0; j < phy_addr_cells; ++j) - { - phy_addr[j] = rt_fdt_read_number(cell++, 1); - } - - space_code = (phy_addr[0] >> 24) & 0x3; - - cpu_addr = rt_fdt_read_number(cell, cpu_addr_cells); - cell += cpu_addr_cells; - phy_addr_size = rt_fdt_read_number(cell, phy_size_cells); - cell += phy_size_cells; - - (*out_regions)[i].phy_addr = ((rt_uint64_t)phy_addr[1] << 32) | phy_addr[2]; - (*out_regions)[i].cpu_addr = cpu_addr; - (*out_regions)[i].size = phy_addr_size; - - (*out_regions)[i].bus_start = (*out_regions)[i].phy_addr; - - if (space_code & 2) - { - (*out_regions)[i].flags = phy_addr[0] & (1U << 30) ? - PCI_BUS_REGION_F_PREFETCH : PCI_BUS_REGION_F_MEM; - } - else if (space_code & 1) - { - (*out_regions)[i].flags = PCI_BUS_REGION_F_IO; - } - else - { - (*out_regions)[i].flags = PCI_BUS_REGION_F_NONE; - } - - ++*out_regions_nr; - } - - return RT_EOK; -} - -rt_err_t rt_pci_ofw_parse_ranges(struct rt_ofw_node *dev_np, - struct rt_pci_host_bridge *host_bridge) -{ - rt_err_t err; - int phy_addr_cells = -1, phy_size_cells = -1, cpu_addr_cells; - - if (!dev_np || !host_bridge) - { - return -RT_EINVAL; - } - - cpu_addr_cells = rt_ofw_io_addr_cells(dev_np); - rt_ofw_prop_read_s32(dev_np, "#address-cells", &phy_addr_cells); - rt_ofw_prop_read_s32(dev_np, "#size-cells", &phy_size_cells); - - if (phy_addr_cells != 3 || phy_size_cells < 1 || cpu_addr_cells < 1) - { - return -RT_EINVAL; - } - - if (pci_ofw_parse_ranges(dev_np, "ranges", - phy_addr_cells, phy_size_cells, cpu_addr_cells, - &host_bridge->bus_regions, &host_bridge->bus_regions_nr)) - { - return -RT_EINVAL; - } - - if ((err = rt_pci_region_setup(host_bridge))) - { - rt_free(host_bridge->bus_regions); - host_bridge->bus_regions_nr = 0; - - return err; - } - - err = pci_ofw_parse_ranges(dev_np, "dma-ranges", - phy_addr_cells, phy_size_cells, cpu_addr_cells, - &host_bridge->dma_regions, &host_bridge->dma_regions_nr); - - if (err != -RT_EEMPTY) - { - rt_free(host_bridge->bus_regions); - host_bridge->bus_regions_nr = 0; - - LOG_E("%s: Read dma-ranges error = %s", rt_ofw_node_full_name(dev_np), - rt_strerror(err)); - - return err; - } - - return RT_EOK; -} - -rt_err_t rt_pci_ofw_host_bridge_init(struct rt_ofw_node *dev_np, - struct rt_pci_host_bridge *host_bridge) -{ - rt_err_t err; - const char *propname; - - if (!dev_np || !host_bridge) - { - return -RT_EINVAL; - } - - host_bridge->irq_slot = rt_pci_irq_slot; - host_bridge->irq_map = rt_pci_ofw_irq_parse_and_map; - - if (rt_ofw_prop_read_u32_array_index(dev_np, "bus-range", 0, 2, host_bridge->bus_range) < 0) - { - return -RT_EIO; - } - - propname = rt_ofw_get_prop_fuzzy_name(dev_np, ",pci-domain$"); - rt_ofw_prop_read_u32(dev_np, propname, &host_bridge->domain); - - err = rt_pci_ofw_parse_ranges(dev_np, host_bridge); - - return err; -} - -rt_err_t rt_pci_ofw_bus_init(struct rt_pci_bus *bus) -{ - rt_err_t err = RT_EOK; - - return err; -} - -rt_err_t rt_pci_ofw_bus_free(struct rt_pci_bus *bus) -{ - rt_err_t err = RT_EOK; - - return err; -} - -/* - * RID (Requester ID) is formatted such that: - * Bits [15:8] are the Bus number. - * Bits [7:3] are the Device number. - * Bits [2:0] are the Function number. - * - * msi-map: Maps a Requester ID to an MSI controller and associated - * msi-specifier data. The property is an arbitrary number of tuples of - * (rid-base,msi-controller,msi-base,length), where: - * - * - rid-base is a single cell describing the first RID matched by the entry. - * - * - msi-controller is a single phandle to an MSI controller - * - * - msi-base is an msi-specifier describing the msi-specifier produced for - * the first RID matched by the entry. - * - * - length is a single cell describing how many consecutive RIDs are matched - * following the rid-base. - * - * Any RID r in the interval [rid-base, rid-base + length) is associated with - * the listed msi-controller, with the msi-specifier (r - rid-base + msi-base). - * - * msi-map-mask: A mask to be applied to each Requester ID prior to being mapped - * to an msi-specifier per the msi-map property. - * - * msi-parent: Describes the MSI parent of the root complex itself. Where - * the root complex and MSI controller do not pass sideband data with MSI - * writes, this property may be used to describe the MSI controller(s) - * used by PCI devices under the root complex, if defined as such in the - * binding for the root complex. - * - * / { - * #address-cells = <1>; - * #size-cells = <1>; - * - * msi_a: msi-controller@a { - * reg = <0xa 0x1>; - * msi-controller; - * #msi-cells = <1>; - * }; - * - * msi_b: msi-controller@b { - * reg = <0xb 0x1>; - * msi-controller; - * #msi-cells = <1>; - * }; - * - * msi_c: msi-controller@c { - * reg = <0xc 0x1>; - * msi-controller; - * #msi-cells = <1>; - * }; - * - * Example (1) - * =========== - * pci: pci@f { - * reg = <0xf 0x1>; - * device_type = "pci"; - * - * // The sideband data provided to the MSI controller is - * // the RID, identity-mapped. - * msi-map = <0x0 &msi_a 0x0 0x10000>; - * }; - * - * Example (2) - * =========== - * pci: pci@ff { - * reg = <0xff 0x1>; - * device_type = "pci"; - * - * // The sideband data provided to the MSI controller is - * // the RID, masked to only the device and function bits. - * msi-map = <0x0 &msi_a 0x0 0x100>; - * msi-map-mask = <0xff> - * }; - * - * Example (3) - * =========== - * pci: pci@fff { - * reg = <0xfff 0x1>; - * device_type = "pci"; - * - * // The sideband data provided to the MSI controller is - * // the RID, but the high bit of the bus number is ignored. - * msi-map = <0x0000 &msi_a 0x0000 0x8000>, - * <0x8000 &msi_a 0x0000 0x8000>; - * }; - * - * Example (4) - * =========== - * pci: pci@f { - * reg = <0xf 0x1>; - * device_type = "pci"; - * - * // The sideband data provided to the MSI controller is - * // the RID, but the high bit of the bus number is negated. - * msi-map = <0x0000 &msi 0x8000 0x8000>, - * <0x8000 &msi 0x0000 0x8000>; - * }; - * - * Example (5) - * =========== - * pci: pci@f { - * reg = <0xf 0x1>; - * device_type = "pci"; - * - * // The sideband data provided to MSI controller a is the - * // RID, but the high bit of the bus number is negated. - * // The sideband data provided to MSI controller b is the - * // RID, identity-mapped. - * // MSI controller c is not addressable. - * msi-map = <0x0000 &msi_a 0x8000 0x08000>, - * <0x8000 &msi_a 0x0000 0x08000>, - * <0x0000 &msi_b 0x0000 0x10000>; - * }; - * }; - */ -static void ofw_msi_pic_init(struct rt_pci_device *pdev) -{ -#ifdef RT_PCI_MSI - rt_uint32_t rid; - struct rt_pci_host_bridge *bridge; - struct rt_ofw_node *np, *msi_ic_np = RT_NULL; - - /* - * NOTE: Typically, a device's RID is equal to the PCI device's ID. - * However, in complex bus management scenarios such as servers and PCs, - * the RID needs to be associated with DMA. In these cases, - * the RID should be equal to the DMA alias assigned to the - * PCI device by the system bus. - */ - rid = rt_pci_dev_id(pdev); - - bridge = rt_pci_find_host_bridge(pdev->bus); - RT_ASSERT(bridge != RT_NULL); - - np = bridge->parent.ofw_node; - - if (!(msi_ic_np = rt_ofw_parse_phandle(np, "msi-parent", 0))) - { - rt_ofw_map_id(np, rid, "msi-map", "msi-map-mask", &msi_ic_np, RT_NULL); - } - - if (!msi_ic_np) - { - LOG_W("%s: MSI PIC not found", rt_dm_dev_get_name(&pdev->parent)); - - return; - } - - pdev->msi_pic = rt_pic_dynamic_cast(rt_ofw_data(msi_ic_np)); - - if (!pdev->msi_pic) - { - LOG_W("%s: '%s' not supported", rt_dm_dev_get_name(&pdev->parent), "msi-parent"); - - goto _out_put_msi_parent_node; - } - - if (!pdev->msi_pic->ops->irq_compose_msi_msg) - { - LOG_E("%s: MSI pic MUST implemented %s", - rt_ofw_node_full_name(msi_ic_np), "irq_compose_msi_msg"); - RT_ASSERT(0); - } - - if (!pdev->msi_pic->ops->irq_alloc_msi) - { - LOG_E("%s: MSI pic MUST implemented %s", - rt_ofw_node_full_name(msi_ic_np), "irq_alloc_msi"); - RT_ASSERT(0); - } - - if (!pdev->msi_pic->ops->irq_free_msi) - { - LOG_E("%s: MSI pic MUST implemented %s", - rt_ofw_node_full_name(msi_ic_np), "irq_free_msi"); - RT_ASSERT(0); - } - -_out_put_msi_parent_node: - rt_ofw_node_put(msi_ic_np); -#endif -} - -static rt_int32_t ofw_pci_devfn(struct rt_ofw_node *np) -{ - rt_int32_t res; - rt_uint32_t reg[5]; - - res = rt_ofw_prop_read_u32_array_index(np, "reg", 0, RT_ARRAY_SIZE(reg), reg); - - return res > 0 ? ((reg[0] >> 8) & 0xff) : res; -} - -static struct rt_ofw_node *ofw_find_device(struct rt_ofw_node *np, rt_uint32_t devfn) -{ - struct rt_ofw_node *dev_np, *mfd_np; - - rt_ofw_foreach_child_node(np, dev_np) - { - if (ofw_pci_devfn(dev_np) == devfn) - { - return dev_np; - } - - if (rt_ofw_node_tag_equ(dev_np, "multifunc-device")) - { - rt_ofw_foreach_child_node(dev_np, mfd_np) - { - if (ofw_pci_devfn(mfd_np) == devfn) - { - rt_ofw_node_put(dev_np); - - return mfd_np; - } - } - } - } - - return RT_NULL; -} - -rt_err_t rt_pci_ofw_device_init(struct rt_pci_device *pdev) -{ - struct rt_ofw_node *np = RT_NULL; - - if (!pdev) - { - return -RT_EINVAL; - } - - ofw_msi_pic_init(pdev); - - if (rt_pci_is_root_bus(pdev->bus) || !pdev->bus->self) - { - struct rt_pci_host_bridge *host_bridge; - - host_bridge = rt_pci_find_host_bridge(pdev->bus); - RT_ASSERT(host_bridge != RT_NULL); - - np = host_bridge->parent.ofw_node; - } - else - { - np = pdev->bus->self->parent.ofw_node; - } - - if (np) - { - pdev->parent.ofw_node = ofw_find_device(np, pdev->devfn); - } - - return RT_EOK; -} - -rt_err_t rt_pci_ofw_device_free(struct rt_pci_device *pdev) -{ - if (!pdev) - { - return -RT_EINVAL; - } - - rt_ofw_node_put(pdev->parent.ofw_node); - - return RT_EOK; -} diff --git a/rt-thread/components/drivers/pci/pci.c b/rt-thread/components/drivers/pci/pci.c deleted file mode 100644 index 369856e..0000000 --- a/rt-thread/components/drivers/pci/pci.c +++ /dev/null @@ -1,1018 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#include -#include - -#define DBG_TAG "rtdm.pci" -#define DBG_LVL DBG_INFO -#include - -#include -#include -#include - -rt_inline void spin_lock(struct rt_spinlock *spinlock) -{ - rt_hw_spin_lock(&spinlock->lock); -} - -rt_inline void spin_unlock(struct rt_spinlock *spinlock) -{ - rt_hw_spin_unlock(&spinlock->lock); -} - -rt_uint32_t rt_pci_domain(struct rt_pci_device *pdev) -{ - struct rt_pci_host_bridge *host_bridge; - - if (!pdev) - { - return RT_UINT32_MAX; - } - - if ((host_bridge = rt_pci_find_host_bridge(pdev->bus))) - { - return host_bridge->domain; - } - - return RT_UINT32_MAX; -} - -static rt_uint8_t pci_find_next_cap_ttl(struct rt_pci_bus *bus, - rt_uint32_t devfn, rt_uint8_t pos, int cap, int *ttl) -{ - rt_uint8_t ret = 0, id; - rt_uint16_t ent; - - rt_pci_bus_read_config_u8(bus, devfn, pos, &pos); - - while ((*ttl)--) - { - if (pos < 0x40) - { - break; - } - - pos &= ~3; - rt_pci_bus_read_config_u16(bus, devfn, pos, &ent); - - id = ent & 0xff; - if (id == 0xff) - { - break; - } - if (id == cap) - { - ret = pos; - break; - } - pos = (ent >> 8); - } - - return ret; -} - -static rt_uint8_t pci_find_next_cap(struct rt_pci_bus *bus, - rt_uint32_t devfn, rt_uint8_t pos, int cap) -{ - int ttl = RT_PCI_FIND_CAP_TTL; - - return pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl); -} - -static rt_uint8_t pci_bus_find_cap_start(struct rt_pci_bus *bus, - rt_uint32_t devfn, rt_uint8_t hdr_type) -{ - rt_uint8_t res = 0; - rt_uint16_t status; - - rt_pci_bus_read_config_u16(bus, devfn, PCIR_STATUS, &status); - - if (status & PCIM_STATUS_CAPPRESENT) - { - switch (hdr_type) - { - case PCIM_HDRTYPE_NORMAL: - case PCIM_HDRTYPE_BRIDGE: - res = PCIR_CAP_PTR; - break; - - case PCIM_HDRTYPE_CARDBUS: - res = PCIR_CAP_PTR_2; - break; - } - } - - return res; -} - -rt_uint8_t rt_pci_bus_find_capability(struct rt_pci_bus *bus, rt_uint32_t devfn, int cap) -{ - rt_uint8_t hdr_type, ret = RT_UINT8_MAX; - - if (bus) - { - rt_pci_bus_read_config_u8(bus, devfn, PCIR_HDRTYPE, &hdr_type); - - ret = pci_bus_find_cap_start(bus, devfn, hdr_type & PCIM_HDRTYPE); - - if (ret) - { - ret = pci_find_next_cap(bus, devfn, ret, cap); - } - } - - return ret; -} - -rt_uint8_t rt_pci_find_capability(struct rt_pci_device *pdev, int cap) -{ - rt_uint8_t res = RT_UINT8_MAX; - - if (pdev) - { - res = pci_bus_find_cap_start(pdev->bus, pdev->devfn, pdev->hdr_type); - - if (res) - { - res = pci_find_next_cap(pdev->bus, pdev->devfn, res, cap); - } - } - - return res; -} - -rt_uint8_t rt_pci_find_next_capability(struct rt_pci_device *pdev, rt_uint8_t pos, int cap) -{ - rt_uint8_t res = RT_UINT8_MAX; - - if (pdev) - { - res = pci_find_next_cap(pdev->bus, pdev->devfn, pos + PCICAP_NEXTPTR, cap); - } - - return res; -} - -rt_uint16_t rt_pci_find_ext_capability(struct rt_pci_device *pdev, int cap) -{ - return rt_pci_find_ext_next_capability(pdev, 0, cap); -} - -rt_uint16_t rt_pci_find_ext_next_capability(struct rt_pci_device *pdev, rt_uint16_t pos, int cap) -{ - int ttl; - rt_uint32_t header; - rt_uint16_t start = pos; - - /* minimum 8 bytes per capability */ - ttl = ((PCIE_REGMAX + 1) - (PCI_REGMAX + 1)) / 8; - - if (pdev->cfg_size <= PCI_REGMAX + 1) - { - return 0; - } - - if (!pos) - { - pos = PCI_REGMAX + 1; - } - - if (rt_pci_read_config_u32(pdev, pos, &header)) - { - return 0; - } - - /* - * If we have no capabilities, this is indicated by cap ID, - * cap version and next pointer all being 0. - */ - if (header == 0) - { - return 0; - } - - while (ttl-- > 0) - { - if (PCI_EXTCAP_ID(header) == cap && pos != start) - { - return pos; - } - - pos = PCI_EXTCAP_NEXTPTR(header); - - if (pos < PCI_REGMAX + 1) - { - break; - } - - if (rt_pci_read_config_u32(pdev, pos, &header)) - { - break; - } - } - - return 0; -} - -static void pci_set_master(struct rt_pci_device *pdev, rt_bool_t enable) -{ - rt_uint16_t old_cmd, cmd; - - rt_pci_read_config_u16(pdev, PCIR_COMMAND, &old_cmd); - - if (enable) - { - cmd = old_cmd | PCIM_CMD_BUSMASTEREN; - } - else - { - cmd = old_cmd & ~PCIM_CMD_BUSMASTEREN; - } - - if (cmd != old_cmd) - { - rt_pci_write_config_u16(pdev, PCIR_COMMAND, cmd); - } - - pdev->busmaster = !!enable; -} - -void rt_pci_set_master(struct rt_pci_device *pdev) -{ - if (pdev) - { - pci_set_master(pdev, RT_TRUE); - } -} - -void rt_pci_clear_master(struct rt_pci_device *pdev) -{ - if (pdev) - { - pci_set_master(pdev, RT_FALSE); - } -} - -void rt_pci_intx(struct rt_pci_device *pdev, rt_bool_t enable) -{ - rt_uint16_t pci_command, new; - - if (!pdev) - { - return; - } - - rt_pci_read_config_u16(pdev, PCIR_COMMAND, &pci_command); - - if (enable) - { - new = pci_command & ~PCIM_CMD_INTxDIS; - } - else - { - new = pci_command | PCIM_CMD_INTxDIS; - } - - if (new != pci_command) - { - rt_pci_write_config_u16(pdev, PCIR_COMMAND, new); - } -} - -static rt_bool_t pci_check_and_set_intx_mask(struct rt_pci_device *pdev, rt_bool_t mask) -{ - rt_ubase_t level; - rt_bool_t irq_pending; - rt_bool_t res = RT_TRUE; - rt_uint16_t origcmd, newcmd; - rt_uint32_t cmd_status_dword; - struct rt_pci_bus *bus = pdev->bus; - - level = rt_spin_lock_irqsave(&rt_pci_lock); - - bus->ops->read(bus, pdev->devfn, PCIR_COMMAND, 4, &cmd_status_dword); - - irq_pending = (cmd_status_dword >> 16) & PCIM_STATUS_INTxSTATE; - - /* - * Check interrupt status register to see whether our device - * triggered the interrupt (when masking) or the next IRQ is - * already pending (when unmasking). - */ - if (mask != irq_pending) - { - res = RT_FALSE; - } - else - { - origcmd = cmd_status_dword; - newcmd = origcmd & ~PCIM_CMD_INTxDIS; - - if (mask) - { - newcmd |= PCIM_CMD_INTxDIS; - } - if (newcmd != origcmd) - { - bus->ops->write(bus, pdev->devfn, PCIR_COMMAND, 2, newcmd); - } - } - - rt_spin_unlock_irqrestore(&rt_pci_lock, level); - - return res; -} - -rt_bool_t rt_pci_check_and_mask_intx(struct rt_pci_device *pdev) -{ - rt_bool_t res = RT_FALSE; - - if (pdev) - { - res = pci_check_and_set_intx_mask(pdev, RT_TRUE); - } - - return res; -} - -rt_bool_t rt_pci_check_and_unmask_intx(struct rt_pci_device *pdev) -{ - rt_bool_t res = RT_FALSE; - - if (pdev) - { - res = pci_check_and_set_intx_mask(pdev, RT_FALSE); - } - - return res; -} - -void rt_pci_irq_mask(struct rt_pci_device *pdev) -{ - if (pdev) - { - rt_bool_t unused; - struct rt_pic_irq *pirq; - - rt_pci_intx(pdev, RT_FALSE); - - pirq = rt_pic_find_pirq(pdev->intx_pic, pdev->irq); - RT_ASSERT(pirq != RT_NULL); - - rt_hw_spin_lock(&pirq->rw_lock.lock); - unused = rt_list_isempty(&pirq->isr.list); - rt_hw_spin_unlock(&pirq->rw_lock.lock); - - if (unused) - { - rt_hw_interrupt_mask(pdev->irq); - } - } -} - -void rt_pci_irq_unmask(struct rt_pci_device *pdev) -{ - if (pdev) - { - rt_hw_interrupt_umask(pdev->irq); - rt_pci_intx(pdev, RT_TRUE); - } -} - -struct rt_pci_bus *rt_pci_find_root_bus(struct rt_pci_bus *bus) -{ - if (!bus) - { - return RT_NULL; - } - - while (bus->parent) - { - bus = bus->parent; - } - - return bus; -} - -struct rt_pci_host_bridge *rt_pci_find_host_bridge(struct rt_pci_bus *bus) -{ - if (!bus) - { - return RT_NULL; - } - - if ((bus = rt_pci_find_root_bus(bus))) - { - return rt_container_of(bus->host_bridge, struct rt_pci_host_bridge, parent); - } - - return RT_NULL; -} - -rt_uint8_t rt_pci_irq_intx(struct rt_pci_device *pdev, rt_uint8_t pin) -{ - int slot = 0; - - if (!pdev->ari_enabled) - { - slot = RT_PCI_SLOT(pdev->devfn); - } - - return (((pin - 1) + slot) % 4) + 1; -} - -rt_uint8_t rt_pci_irq_slot(struct rt_pci_device *pdev, rt_uint8_t *pinp) -{ - rt_uint8_t pin = *pinp; - - while (!rt_pci_is_root_bus(pdev->bus)) - { - pin = rt_pci_irq_intx(pdev, pin); - pdev = pdev->bus->self; - } - - *pinp = pin; - - return RT_PCI_SLOT(pdev->devfn); -} - -rt_err_t rt_pci_region_setup(struct rt_pci_host_bridge *host_bridge) -{ - rt_err_t err = host_bridge->bus_regions_nr == 0 ? -RT_EEMPTY : RT_EOK; - - for (int i = 0; i < host_bridge->bus_regions_nr; ++i) - { - struct rt_pci_bus_region *region = &host_bridge->bus_regions[i]; - /* - * Avoid allocating PCI resources from address 0 -- this is illegal - * according to PCI 2.1 and moreover. Use a reasonable starting value of - * 0x1000 instead if the bus start address is below 0x1000. - */ - region->bus_start = rt_max_t(rt_size_t, 0x1000, region->phy_addr); - - LOG_I("Bus %s region(%d):", - region->flags == PCI_BUS_REGION_F_MEM ? "Memory" : - (region->flags == PCI_BUS_REGION_F_PREFETCH ? "Prefetchable Mem" : - (region->flags == PCI_BUS_REGION_F_IO ? "I/O" : "Unknown")), i); - LOG_I(" cpu: [%p, %p]", region->cpu_addr, (region->cpu_addr + region->size - 1)); - LOG_I(" physical: [%p, %p]", region->phy_addr, (region->phy_addr + region->size - 1)); - } - - return err; -} - -struct rt_pci_bus_region *rt_pci_region_alloc(struct rt_pci_host_bridge *host_bridge, - void **out_addr, rt_size_t size, rt_ubase_t flags, rt_bool_t mem64) -{ - struct rt_pci_bus_region *bus_region, *region = RT_NULL; - - bus_region = &host_bridge->bus_regions[0]; - - for (int i = 0; i < host_bridge->bus_regions_nr; ++i, ++bus_region) - { - if (bus_region->flags == flags && bus_region->size > 0) - { - void *addr; - - region = bus_region; - addr = (void *)(((region->bus_start - 1) | (size - 1)) + 1); - - if ((rt_uint64_t)addr - region->phy_addr + size <= region->size) - { - rt_bool_t addr64 = !!rt_upper_32_bits((rt_ubase_t)addr); - - if (mem64) - { - if (!addr64) - { - region = RT_NULL; - - /* Try again */ - continue; - } - } - else if (addr64) - { - region = RT_NULL; - - /* Try again */ - continue; - } - - region->bus_start = ((rt_uint64_t)addr + size); - *out_addr = addr; - } - - break; - } - } - - if (!region && mem64) - { - /* Retry */ - region = rt_pci_region_alloc(host_bridge, out_addr, size, flags, RT_FALSE); - } - - return region; -} - -rt_err_t rt_pci_device_alloc_resource(struct rt_pci_host_bridge *host_bridge, - struct rt_pci_device *pdev) -{ - rt_err_t err = RT_EOK; - rt_size_t size; - rt_ubase_t addr = 0; - rt_uint32_t cfg; - rt_size_t bars_nr; - rt_uint8_t hdr_type; - rt_bool_t prefetch = RT_FALSE; - rt_uint16_t class, command = 0; - - for (int i = 0; i < host_bridge->bus_regions_nr; ++i) - { - if (host_bridge->bus_regions[i].flags == PCI_BUS_REGION_F_PREFETCH) - { - prefetch = RT_TRUE; - break; - } - } - - rt_pci_read_config_u16(pdev, PCIR_COMMAND, &command); - command = (command & ~(PCIM_CMD_PORTEN | PCIM_CMD_MEMEN)) | PCIM_CMD_BUSMASTEREN; - rt_pci_read_config_u8(pdev, PCIR_HDRTYPE, &hdr_type); - - if (pdev->hdr_type != hdr_type) - { - LOG_W("%s may not initialized", rt_dm_dev_get_name(&pdev->parent)); - } - - switch (hdr_type) - { - case PCIM_HDRTYPE_NORMAL: - bars_nr = PCI_STD_NUM_BARS; - break; - - case PCIM_HDRTYPE_BRIDGE: - bars_nr = 2; - break; - - case PCIM_HDRTYPE_CARDBUS: - bars_nr = 0; - break; - - default: - bars_nr = 0; - break; - } - - for (int i = 0; i < bars_nr; ++i) - { - rt_ubase_t flags; - rt_ubase_t bar_base; - rt_bool_t mem64 = RT_FALSE; - struct rt_pci_bus_region *region; - - cfg = 0; - bar_base = PCIR_BAR(i); - - rt_pci_write_config_u32(pdev, bar_base, RT_UINT32_MAX); - rt_pci_read_config_u32(pdev, bar_base, &cfg); - - if (!cfg) - { - continue; - } - else if (cfg == RT_UINT32_MAX) - { - rt_pci_write_config_u32(pdev, bar_base, 0UL); - continue; - } - - if (cfg & PCIM_BAR_SPACE) - { - mem64 = RT_FALSE; - flags = PCI_BUS_REGION_F_IO; - - size = cfg & PCIM_BAR_IO_MASK; - size &= ~(size - 1); - } - else - { - /* memory */ - if ((cfg & PCIM_BAR_MEM_TYPE_MASK) == PCIM_BAR_MEM_TYPE_64) - { - /* 64bits */ - rt_uint32_t cfg64; - rt_uint64_t bar64; - - mem64 = RT_TRUE; - - rt_pci_write_config_u32(pdev, bar_base + sizeof(rt_uint32_t), RT_UINT32_MAX); - rt_pci_read_config_u32(pdev, bar_base + sizeof(rt_uint32_t), &cfg64); - - bar64 = ((rt_uint64_t)cfg64 << 32) | cfg; - - size = ~(bar64 & PCIM_BAR_MEM_MASK) + 1; - } - else - { - /* 32bits */ - mem64 = RT_FALSE; - size = (rt_uint32_t)(~(cfg & PCIM_BAR_MEM_MASK) + 1); - } - - if (prefetch && (cfg & PCIM_BAR_MEM_PREFETCH)) - { - flags = PCI_BUS_REGION_F_PREFETCH; - } - else - { - flags = PCI_BUS_REGION_F_MEM; - } - } - - region = rt_pci_region_alloc(host_bridge, (void **)&addr, size, flags, mem64); - - if (region) - { - rt_pci_write_config_u32(pdev, bar_base, addr); - - if (mem64) - { - bar_base += sizeof(rt_uint32_t); - #ifdef RT_PCI_SYS_64BIT - rt_pci_write_config_u32(pdev, bar_base, (rt_uint32_t)(addr >> 32)); - #else - /* - * If we are a 64-bit decoder then increment to the upper 32 bits - * of the bar and force it to locate in the lower 4GB of memory. - */ - rt_pci_write_config_u32(pdev, bar_base, 0UL); - #endif - } - - pdev->resource[i].size = size; - pdev->resource[i].base = region->cpu_addr + (addr - region->phy_addr); - pdev->resource[i].flags = flags; - - if (mem64) - { - ++i; - pdev->resource[i].flags = PCI_BUS_REGION_F_NONE; - } - } - else - { - err = -RT_ERROR; - LOG_W("%s alloc bar(%d) address fail", rt_dm_dev_get_name(&pdev->parent), i); - } - - command |= (cfg & PCIM_BAR_SPACE) ? PCIM_CMD_PORTEN : PCIM_CMD_MEMEN; - } - - if (hdr_type == PCIM_HDRTYPE_NORMAL || hdr_type == PCIM_HDRTYPE_BRIDGE) - { - int rom_addr = (hdr_type == PCIM_HDRTYPE_NORMAL) ? PCIR_BIOS : PCIR_BIOS_1; - - rt_pci_write_config_u32(pdev, rom_addr, 0xfffffffe); - rt_pci_read_config_u32(pdev, rom_addr, &cfg); - - if (cfg) - { - size = -(cfg & ~1); - - if (rt_pci_region_alloc(host_bridge, (void **)&addr, size, PCI_BUS_REGION_F_MEM, RT_FALSE)) - { - rt_pci_write_config_u32(pdev, rom_addr, addr); - } - command |= PCIM_CMD_MEMEN; - } - } - - rt_pci_read_config_u16(pdev, PCIR_SUBCLASS, &class); - - if (class == PCIS_DISPLAY_VGA) - { - command |= PCIM_CMD_PORTEN; - } - - rt_pci_write_config_u16(pdev, PCIR_COMMAND, command); - rt_pci_write_config_u8(pdev, PCIR_CACHELNSZ, RT_PCI_CACHE_LINE_SIZE); - rt_pci_write_config_u8(pdev, PCIR_LATTIMER, 0x80); - - return err; -} - -struct rt_pci_bus_resource *rt_pci_find_bar(struct rt_pci_device* pdev,rt_ubase_t flags,int index) -{ - for (int i = 0; i < RT_PCI_BAR_NR_MAX; i++) - { - if (pdev->resource[i].flags == flags) - { - index--; - if (index == 0) - return &pdev->resource[i]; - } - } - return RT_NULL; -} - -void rt_pci_enum_device(struct rt_pci_bus *bus, - rt_bool_t (callback(struct rt_pci_device *, void *)), void *data) -{ - rt_bool_t is_end = RT_FALSE; - struct rt_spinlock *lock; - struct rt_pci_bus *parent; - struct rt_pci_device *pdev, *last_pdev = RT_NULL; - - /* Walk tree */ - while (bus && !is_end) - { - /* Goto bottom */ - for (;;) - { - lock = &bus->lock; - - spin_lock(lock); - if (rt_list_isempty(&bus->children_nodes)) - { - parent = bus->parent; - break; - } - bus = rt_list_entry(&bus->children_nodes, struct rt_pci_bus, list); - spin_unlock(lock); - } - - rt_list_for_each_entry(pdev, &bus->devices_nodes, list) - { - if (last_pdev) - { - spin_unlock(lock); - - if (callback(last_pdev, data)) - { - spin_lock(lock); - --last_pdev->parent.ref_count; - - is_end = RT_TRUE; - break; - } - - spin_lock(lock); - --last_pdev->parent.ref_count; - } - ++pdev->parent.ref_count; - last_pdev = pdev; - } - - if (!is_end && last_pdev) - { - spin_unlock(lock); - - if (callback(last_pdev, data)) - { - is_end = RT_TRUE; - } - - spin_lock(lock); - --last_pdev->parent.ref_count; - } - last_pdev = RT_NULL; - spin_unlock(lock); - - /* Up a level or goto next */ - while (!is_end) - { - lock = &bus->lock; - - if (!parent) - { - /* Root bus, is end */ - bus = RT_NULL; - break; - } - - spin_lock(lock); - if (bus->list.next != &parent->children_nodes) - { - /* Has next sibling */ - bus = rt_list_entry(bus->list.next, struct rt_pci_bus, list); - spin_unlock(lock); - break; - } - - /* All device on this buss' parent */ - rt_list_for_each_entry(pdev, &parent->devices_nodes, list) - { - if (last_pdev) - { - spin_unlock(lock); - - if (callback(last_pdev, data)) - { - spin_lock(lock); - --last_pdev->parent.ref_count; - - is_end = RT_TRUE; - break; - } - - spin_lock(lock); - --last_pdev->parent.ref_count; - } - ++pdev->parent.ref_count; - last_pdev = pdev; - } - - if (!is_end && last_pdev) - { - spin_unlock(lock); - - if (callback(last_pdev, data)) - { - is_end = RT_TRUE; - } - - spin_lock(lock); - --last_pdev->parent.ref_count; - } - last_pdev = RT_NULL; - - bus = parent; - parent = parent->parent; - spin_unlock(lock); - } - } -} - -const struct rt_pci_device_id *rt_pci_match_id(struct rt_pci_device *pdev, - const struct rt_pci_device_id *id) -{ - if ((id->vendor == PCI_ANY_ID || id->vendor == pdev->vendor) && - (id->device == PCI_ANY_ID || id->device == pdev->device) && - (id->subsystem_vendor == PCI_ANY_ID || id->subsystem_vendor == pdev->subsystem_vendor) && - (id->subsystem_device == PCI_ANY_ID || id->subsystem_device == pdev->subsystem_device) && - !((id->class ^ pdev->class) & id->class_mask)) - { - return id; - } - - return RT_NULL; -} - -const struct rt_pci_device_id *rt_pci_match_ids(struct rt_pci_device *pdev, - const struct rt_pci_device_id *ids) -{ - while (ids->vendor || ids->subsystem_vendor || ids->class_mask) - { - if (rt_pci_match_id(pdev, ids)) - { - return ids; - } - - ++ids; - } - - return RT_NULL; -} - -static struct rt_bus pci_bus; - -rt_err_t rt_pci_driver_register(struct rt_pci_driver *pdrv) -{ - RT_ASSERT(pdrv != RT_NULL); - - pdrv->parent.bus = &pci_bus; -#if RT_NAME_MAX > 0 - rt_strcpy(pdrv->parent.parent.name, pdrv->name); -#else - pdrv->parent.parent.name = pdrv->name; -#endif - - return rt_driver_register(&pdrv->parent); -} - -rt_err_t rt_pci_device_register(struct rt_pci_device *pdev) -{ - rt_err_t err; - RT_ASSERT(pdev != RT_NULL); - - if ((err = rt_bus_add_device(&pci_bus, &pdev->parent))) - { - return err; - } - - return RT_EOK; -} - -static rt_bool_t pci_match(rt_driver_t drv, rt_device_t dev) -{ - rt_bool_t match = RT_FALSE; - struct rt_pci_driver *pdrv = rt_container_of(drv, struct rt_pci_driver, parent); - struct rt_pci_device *pdev = rt_container_of(dev, struct rt_pci_device, parent); - - if (pdrv->name && pdev->name) - { - match = rt_strcmp(pdrv->name, pdev->name) ? RT_FALSE : RT_TRUE; - } - - if (!match) - { - pdev->id = rt_pci_match_ids(pdev, pdrv->ids); - - match = pdev->id ? RT_TRUE : RT_FALSE; - } - - return match; -} - -static rt_err_t pci_probe(rt_device_t dev) -{ - rt_err_t err = RT_EOK; - struct rt_pci_driver *pdrv = rt_container_of(dev->drv, struct rt_pci_driver, parent); - struct rt_pci_device *pdev = rt_container_of(dev, struct rt_pci_device, parent); - - rt_pci_assign_irq(pdev); - rt_pci_enable_wake(pdev, RT_PCI_D0, RT_TRUE); - - err = pdrv->probe(pdev); - - if (err) - { - rt_pci_enable_wake(pdev, RT_PCI_D0, RT_FALSE); - } - - return err; -} - -static rt_err_t pci_remove(rt_device_t dev) -{ - rt_err_t err = RT_EOK; - struct rt_pci_bus *bus; - struct rt_pci_driver *pdrv = rt_container_of(dev->drv, struct rt_pci_driver, parent); - struct rt_pci_device *pdev = rt_container_of(dev, struct rt_pci_device, parent); - - if (pdrv && pdrv->remove) - { - if ((err = pdrv->remove(pdev))) - { - return err; - } - } - - rt_pci_enable_wake(pdev, RT_PCI_D0, RT_FALSE); - - bus = pdev->bus; - rt_pci_device_remove(pdev); - /* Just try to remove */ - rt_pci_bus_remove(bus); - - return err; -} - -static rt_err_t pci_shutdown(rt_device_t dev) -{ - struct rt_pci_bus *bus; - struct rt_pci_driver *pdrv = rt_container_of(dev->drv, struct rt_pci_driver, parent); - struct rt_pci_device *pdev = rt_container_of(dev, struct rt_pci_device, parent); - - if (pdrv && pdrv->shutdown) - { - pdrv->shutdown(pdev); - } - - rt_pci_enable_wake(pdev, RT_PCI_D0, RT_FALSE); - - bus = pdev->bus; - rt_pci_device_remove(pdev); - /* Just try to remove */ - rt_pci_bus_remove(bus); - - return RT_EOK; -} - -static struct rt_bus pci_bus = -{ - .name = "pci", - .match = pci_match, - .probe = pci_probe, - .remove = pci_remove, - .shutdown = pci_shutdown, -}; - -static int pci_bus_init(void) -{ - rt_bus_register(&pci_bus); - - return 0; -} -INIT_CORE_EXPORT(pci_bus_init); diff --git a/rt-thread/components/drivers/pci/pci_ids.h b/rt-thread/components/drivers/pci/pci_ids.h deleted file mode 100644 index 2dab735..0000000 --- a/rt-thread/components/drivers/pci/pci_ids.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __PCI_IDS_H__ -#define __PCI_IDS_H__ - -#define PCI_VENDOR_ID_LOONGSON 0x0014 -#define PCI_VENDOR_ID_TTTECH 0x0357 -#define PCI_VENDOR_ID_DYNALINK 0x0675 -#define PCI_VENDOR_ID_UBIQUITI 0x0777 -#define PCI_VENDOR_ID_BERKOM 0x0871 -#define PCI_VENDOR_ID_COMPAQ 0x0e11 -#define PCI_VENDOR_ID_NCR 0x1000 -#define PCI_VENDOR_ID_ATI 0x1002 -#define PCI_VENDOR_ID_VLSI 0x1004 -#define PCI_VENDOR_ID_ADL 0x1005 -#define PCI_VENDOR_ID_NS 0x100b -#define PCI_VENDOR_ID_TSENG 0x100c -#define PCI_VENDOR_ID_WEITEK 0x100e -#define PCI_VENDOR_ID_DEC 0x1011 -#define PCI_VENDOR_ID_CIRRUS 0x1013 -#define PCI_VENDOR_ID_IBM 0x1014 -#define PCI_VENDOR_ID_UNISYS 0x1018 -#define PCI_VENDOR_ID_COMPEX2 0x101a -#define PCI_VENDOR_ID_WD 0x101c -#define PCI_VENDOR_ID_AMI 0x101e -#define PCI_VENDOR_ID_AMD 0x1022 -#define PCI_VENDOR_ID_TRIDENT 0x1023 -#define PCI_VENDOR_ID_AI 0x1025 -#define PCI_VENDOR_ID_DELL 0x1028 -#define PCI_VENDOR_ID_MATROX 0x102b -#define PCI_VENDOR_ID_MOBILITY_ELECTRONICS 0x14f2 -#define PCI_VENDOR_ID_CT 0x102c -#define PCI_VENDOR_ID_MIRO 0x1031 -#define PCI_VENDOR_ID_NEC 0x1033 -#define PCI_VENDOR_ID_FD 0x1036 -#define PCI_VENDOR_ID_SI 0x1039 -#define PCI_VENDOR_ID_HP 0x103c -#define PCI_VENDOR_ID_PCTECH 0x1042 -#define PCI_VENDOR_ID_ASUSTEK 0x1043 -#define PCI_VENDOR_ID_DPT 0x1044 -#define PCI_VENDOR_ID_OPTI 0x1045 -#define PCI_VENDOR_ID_ELSA 0x1048 -#define PCI_VENDOR_ID_STMICRO 0x104a -#define PCI_VENDOR_ID_BUSLOGIC 0x104b -#define PCI_VENDOR_ID_TI 0x104c -#define PCI_VENDOR_ID_SONY 0x104d -#define PCI_VENDOR_ID_ANIGMA 0x1051 -#define PCI_VENDOR_ID_EFAR 0x1055 -#define PCI_VENDOR_ID_MOTOROLA 0x1057 -#define PCI_VENDOR_ID_PROMISE 0x105a -#define PCI_VENDOR_ID_FOXCONN 0x105b -#define PCI_VENDOR_ID_UMC 0x1060 -#define PCI_VENDOR_ID_PICOPOWER 0x1066 -#define PCI_VENDOR_ID_MYLEX 0x1069 -#define PCI_VENDOR_ID_APPLE 0x106b -#define PCI_VENDOR_ID_YAMAHA 0x1073 -#define PCI_VENDOR_ID_QLOGIC 0x1077 -#define PCI_VENDOR_ID_CYRIX 0x1078 -#define PCI_VENDOR_ID_CONTAQ 0x1080 -#define PCI_VENDOR_ID_OLICOM 0x108d -#define PCI_VENDOR_ID_SUN 0x108e -#define PCI_VENDOR_ID_NI 0x1093 -#define PCI_VENDOR_ID_CMD 0x1095 -#define PCI_VENDOR_ID_BROOKTREE 0x109e -#define PCI_VENDOR_ID_SGI 0x10a9 -#define PCI_VENDOR_ID_WINBOND 0x10ad -#define PCI_VENDOR_ID_PLX 0x10b5 -#define PCI_VENDOR_ID_MADGE 0x10b6 -#define PCI_VENDOR_ID_3COM 0x10b7 -#define PCI_VENDOR_ID_AL 0x10b9 -#define PCI_VENDOR_ID_NEOMAGIC 0x10c8 -#define PCI_VENDOR_ID_TCONRAD 0x10da -#define PCI_VENDOR_ID_ROHM 0x10db -#define PCI_VENDOR_ID_NVIDIA 0x10de -#define PCI_VENDOR_ID_IMS 0x10e0 -#define PCI_VENDOR_ID_AMCC 0x10e8 -#define PCI_VENDOR_ID_INTERG 0x10ea -#define PCI_VENDOR_ID_REALTEK 0x10ec -#define PCI_VENDOR_ID_XILINX 0x10ee -#define PCI_VENDOR_ID_INIT 0x1101 -#define PCI_VENDOR_ID_CREATIVE 0x1102 -#define PCI_VENDOR_ID_ECTIVA PCI_VENDOR_ID_CREATIVE -#define PCI_VENDOR_ID_TTI 0x1103 -#define PCI_VENDOR_ID_SIGMA 0x1105 -#define PCI_VENDOR_ID_VIA 0x1106 -#define PCI_VENDOR_ID_SIEMENS 0x110a -#define PCI_VENDOR_ID_VORTEX 0x1119 -#define PCI_VENDOR_ID_EF 0x111a -#define PCI_VENDOR_ID_IDT 0x111d -#define PCI_VENDOR_ID_FORE 0x1127 -#define PCI_VENDOR_ID_PHILIPS 0x1131 -#define PCI_VENDOR_ID_EICON 0x1133 -#define PCI_VENDOR_ID_CISCO 0x1137 -#define PCI_VENDOR_ID_ZIATECH 0x1138 -#define PCI_VENDOR_ID_SYSKONNECT 0x1148 -#define PCI_VENDOR_ID_DIGI 0x114f -#define PCI_VENDOR_ID_XIRCOM 0x115d -#define PCI_VENDOR_ID_SERVERWORKS 0x1166 -#define PCI_VENDOR_ID_ALTERA 0x1172 -#define PCI_VENDOR_ID_SBE 0x1176 -#define PCI_VENDOR_ID_TOSHIBA 0x1179 -#define PCI_VENDOR_ID_TOSHIBA_2 0x102f -#define PCI_VENDOR_ID_ATTO 0x117c -#define PCI_VENDOR_ID_RICOH 0x1180 -#define PCI_VENDOR_ID_DLINK 0x1186 -#define PCI_VENDOR_ID_ARTOP 0x1191 -#define PCI_VENDOR_ID_ZEITNET 0x1193 -#define PCI_VENDOR_ID_FUJITSU_ME 0x119e -#define PCI_VENDOR_ID_MARVELL 0x11ab -#define PCI_VENDOR_ID_V3 0x11b0 -#define PCI_VENDOR_ID_ATT 0x11c1 -#define PCI_VENDOR_ID_SPECIALIX 0x11cb -#define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4 -#define PCI_VENDOR_ID_ZORAN 0x11de -#define PCI_VENDOR_ID_COMPEX 0x11f6 -#define PCI_VENDOR_ID_PMC_Sierra 0x11f8 -#define PCI_VENDOR_ID_RP 0x11fe -#define PCI_VENDOR_ID_CYCLADES 0x120e -#define PCI_VENDOR_ID_ESSENTIAL 0x120f -#define PCI_VENDOR_ID_O2 0x1217 -#define PCI_VENDOR_ID_3DFX 0x121a -#define PCI_VENDOR_ID_QEMU 0x1234 -#define PCI_VENDOR_ID_AVM 0x1244 -#define PCI_VENDOR_ID_STALLION 0x124d -#define PCI_VENDOR_ID_ESS 0x125d -#define PCI_VENDOR_ID_SATSAGEM 0x1267 -#define PCI_VENDOR_ID_ENSONIQ 0x1274 -#define PCI_VENDOR_ID_TRANSMETA 0x1279 -#define PCI_VENDOR_ID_ROCKWELL 0x127a -#define PCI_VENDOR_ID_ITE 0x1283 -#define PCI_VENDOR_ID_ALTEON 0x12ae -#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2 -#define PCI_VENDOR_ID_PERICOM 0x12d8 -#define PCI_VENDOR_ID_AUREAL 0x12eb -#define PCI_VENDOR_ID_ELECTRONICDESIGNGMBH 0x12f8 -#define PCI_VENDOR_ID_ESDGMBH 0x12fe -#define PCI_VENDOR_ID_CB 0x1307 -#define PCI_VENDOR_ID_SIIG 0x131f -#define PCI_VENDOR_ID_RADISYS 0x1331 -#define PCI_VENDOR_ID_MICRO_MEMORY 0x1332 -#define PCI_VENDOR_ID_DOMEX 0x134a -#define PCI_VENDOR_ID_INTASHIELD 0x135a -#define PCI_VENDOR_ID_QUATECH 0x135c -#define PCI_VENDOR_ID_SEALEVEL 0x135e -#define PCI_VENDOR_ID_HYPERCOPE 0x1365 -#define PCI_VENDOR_ID_DIGIGRAM 0x1369 -#define PCI_VENDOR_ID_KAWASAKI 0x136b -#define PCI_VENDOR_ID_CNET 0x1371 -#define PCI_VENDOR_ID_LMC 0x1376 -#define PCI_VENDOR_ID_NETGEAR 0x1385 -#define PCI_VENDOR_ID_APPLICOM 0x1389 -#define PCI_VENDOR_ID_MOXA 0x1393 -#define PCI_VENDOR_ID_CCD 0x1397 -#define PCI_VENDOR_ID_EXAR 0x13a8 -#define PCI_VENDOR_ID_MICROGATE 0x13c0 -#define PCI_VENDOR_ID_3WARE 0x13c1 -#define PCI_VENDOR_ID_IOMEGA 0x13ca -#define PCI_VENDOR_ID_ABOCOM 0x13d1 -#define PCI_VENDOR_ID_SUNDANCE 0x13f0 -#define PCI_VENDOR_ID_CMEDIA 0x13f6 -#define PCI_VENDOR_ID_ADVANTECH 0x13fe -#define PCI_VENDOR_ID_MEILHAUS 0x1402 -#define PCI_VENDOR_ID_LAVA 0x1407 -#define PCI_VENDOR_ID_TIMEDIA 0x1409 -#define PCI_VENDOR_ID_ICE 0x1412 -#define PCI_VENDOR_ID_MICROSOFT 0x1414 -#define PCI_VENDOR_ID_OXSEMI 0x1415 -#define PCI_VENDOR_ID_CHELSIO 0x1425 -#define PCI_VENDOR_ID_ADLINK 0x144a -#define PCI_VENDOR_ID_SAMSUNG 0x144d -#define PCI_VENDOR_ID_GIGABYTE 0x1458 -#define PCI_VENDOR_ID_AMBIT 0x1468 -#define PCI_VENDOR_ID_MYRICOM 0x14c1 -#define PCI_VENDOR_ID_MEDIATEK 0x14c3 -#define PCI_VENDOR_ID_TITAN 0x14d2 -#define PCI_VENDOR_ID_PANACOM 0x14d4 -#define PCI_VENDOR_ID_SIPACKETS 0x14d9 -#define PCI_VENDOR_ID_AFAVLAB 0x14db -#define PCI_VENDOR_ID_AMPLICON 0x14dc -#define PCI_VENDOR_ID_BCM_GVC 0x14a4 -#define PCI_VENDOR_ID_TOPIC 0x151f -#define PCI_VENDOR_ID_MAINPINE 0x1522 -#define PCI_VENDOR_ID_SYBA 0x1592 -#define PCI_VENDOR_ID_MORETON 0x15aa -#define PCI_VENDOR_ID_VMWARE 0x15ad -#define PCI_VENDOR_ID_ZOLTRIX 0x15b0 -#define PCI_VENDOR_ID_MELLANOX 0x15b3 -#define PCI_VENDOR_ID_DFI 0x15bd -#define PCI_VENDOR_ID_QUICKNET 0x15e2 -#define PCI_VENDOR_ID_PDC 0x15e9 -#define PCI_VENDOR_ID_FARSITE 0x1619 -#define PCI_VENDOR_ID_ARIMA 0x161f -#define PCI_VENDOR_ID_BROCADE 0x1657 -#define PCI_VENDOR_ID_SIBYTE 0x166d -#define PCI_VENDOR_ID_ATHEROS 0x168c -#define PCI_VENDOR_ID_NETCELL 0x169c -#define PCI_VENDOR_ID_CENATEK 0x16ca -#define PCI_VENDOR_ID_SYNOPSYS 0x16c3 -#define PCI_VENDOR_ID_USR 0x16ec -#define PCI_VENDOR_ID_VITESSE 0x1725 -#define PCI_VENDOR_ID_LINKSYS 0x1737 -#define PCI_VENDOR_ID_ALTIMA 0x173b -#define PCI_VENDOR_ID_CAVIUM 0x177d -#define PCI_VENDOR_ID_TECHWELL 0x1797 -#define PCI_VENDOR_ID_BELKIN 0x1799 -#define PCI_VENDOR_ID_RDC 0x17f3 -#define PCI_VENDOR_ID_GLI 0x17a0 -#define PCI_VENDOR_ID_LENOVO 0x17aa -#define PCI_VENDOR_ID_QCOM 0x17cb -#define PCI_VENDOR_ID_CDNS 0x17cd -#define PCI_VENDOR_ID_ARECA 0x17d3 -#define PCI_VENDOR_ID_S2IO 0x17d5 -#define PCI_VENDOR_ID_SITECOM 0x182d -#define PCI_VENDOR_ID_TOPSPIN 0x1867 -#define PCI_VENDOR_ID_COMMTECH 0x18f7 -#define PCI_VENDOR_ID_SILAN 0x1904 -#define PCI_VENDOR_ID_RENESAS 0x1912 -#define PCI_VENDOR_ID_SOLARFLARE 0x1924 -#define PCI_VENDOR_ID_TDI 0x192e -#define PCI_VENDOR_ID_FREESCALE 0x1957 -#define PCI_VENDOR_ID_NXP PCI_VENDOR_ID_FREESCALE -#define PCI_VENDOR_ID_PASEMI 0x1959 -#define PCI_VENDOR_ID_ATTANSIC 0x1969 -#define PCI_VENDOR_ID_JMICRON 0x197b -#define PCI_VENDOR_ID_KORENIX 0x1982 -#define PCI_VENDOR_ID_HUAWEI 0x19e5 -#define PCI_VENDOR_ID_NETRONOME 0x19ee -#define PCI_VENDOR_ID_QMI 0x1a32 -#define PCI_VENDOR_ID_AZWAVE 0x1a3b -#define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4 -#define PCI_VENDOR_ID_ASMEDIA 0x1b21 -#define PCI_VENDOR_ID_REDHAT 0x1b36 -#define PCI_VENDOR_ID_SILICOM_DENMARK 0x1c2c -#define PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS 0x1c36 -#define PCI_VENDOR_ID_CIRCUITCO 0x1cc8 -#define PCI_VENDOR_ID_AMAZON 0x1d0f -#define PCI_VENDOR_ID_ZHAOXIN 0x1d17 -#define PCI_VENDOR_ID_HYGON 0x1d94 -#define PCI_VENDOR_ID_FUNGIBLE 0x1dad -#define PCI_VENDOR_ID_HXT 0x1dbf -#define PCI_VENDOR_ID_TEKRAM 0x1de1 -#define PCI_VENDOR_ID_TEHUTI 0x1fc9 -#define PCI_VENDOR_ID_SUNIX 0x1fd4 -#define PCI_VENDOR_ID_HINT 0x3388 -#define PCI_VENDOR_ID_3DLABS 0x3d3d -#define PCI_VENDOR_ID_NETXEN 0x4040 -#define PCI_VENDOR_ID_AKS 0x416c -#define PCI_VENDOR_ID_ACCESSIO 0x494f -#define PCI_VENDOR_ID_S3 0x5333 -#define PCI_VENDOR_ID_DUNORD 0x5544 -#define PCI_VENDOR_ID_DCI 0x6666 -#define PCI_VENDOR_ID_INTEL 0x8086 -#define PCI_VENDOR_ID_SCALEMP 0x8686 -#define PCI_VENDOR_ID_COMPUTONE 0x8e0e -#define PCI_VENDOR_ID_KTI 0x8e2e -#define PCI_VENDOR_ID_ADAPTEC 0x9004 -#define PCI_VENDOR_ID_ADAPTEC2 0x9005 -#define PCI_VENDOR_ID_HOLTEK 0x9412 -#define PCI_VENDOR_ID_NETMOS 0x9710 -#define PCI_VENDOR_ID_3COM_2 0xa727 -#define PCI_VENDOR_ID_DIGIUM 0xd161 -#define PCI_VENDOR_ID_TIGERJET 0xe159 -#define PCI_VENDOR_ID_XILINX_RME 0xea60 -#define PCI_VENDOR_ID_XEN 0x5853 -#define PCI_VENDOR_ID_OCZ 0x1b85 -#define PCI_VENDOR_ID_NCUBE 0x10ff - -#endif /* __PCI_IDS_H__ */ diff --git a/rt-thread/components/drivers/pci/pci_regs.h b/rt-thread/components/drivers/pci/pci_regs.h deleted file mode 100644 index 5a8822c..0000000 --- a/rt-thread/components/drivers/pci/pci_regs.h +++ /dev/null @@ -1,1090 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __PCI_REGS_H__ -#define __PCI_REGS_H__ - -#include - -/* - * PCI standard defines - * Copyright 1994, Drew Eckhardt - * Copyright 1997--1999 Martin Mares - * - * For more information, please consult the following manuals (look at - * http://www.pcisig.com/ for how to get them): - * - * PCI BIOS Specification - * PCI Local Bus Specification - * PCI to PCI Bridge Specification - * PCI System Design Guide - * - * For HyperTransport information, please consult the following manuals - * from http://www.hypertransport.org : - * - * The HyperTransport I/O Link Specification - * - * Mean of prefix: - * - * PCIM_xxx: mask to locate subfield in register - * PCIR_xxx: config register offset - * PCIC_xxx: device class - * PCIS_xxx: device subclass - * PCIP_xxx: device programming interface - * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices) - * PCID_xxx: device ID - * PCIY_xxx: capability identification number - * PCIZ_xxx: extended capability identification number - */ - -/* some PCI bus constants */ -#define PCI_DOMAINMAX 65535 /* highest supported domain number */ -#define PCI_BUSMAX 255 /* highest supported bus number */ -#define PCI_SLOTMAX 31 /* highest supported slot number */ -#define PCI_FUNCMAX 7 /* highest supported function number */ -#define PCI_REGMAX 255 /* highest supported config register addr */ -#define PCIE_REGMAX 4095 /* highest supported config register addr */ -#define PCI_MAXHDRTYPE 2 -#define PCI_STD_HEADER_SIZEOF 64 -#define PCI_STD_NUM_BARS 6 /* number of standard BARs */ - -/* PCI config header registers for all devices */ - -#define PCIR_DEVVENDOR 0x00 -#define PCIR_VENDOR 0x00 -#define PCIR_DEVICE 0x02 -#define PCIR_COMMAND 0x04 -#define PCIM_CMD_PORTEN 0x0001 -#define PCIM_CMD_MEMEN 0x0002 -#define PCIM_CMD_BUSMASTEREN 0x0004 -#define PCIM_CMD_SPECIALEN 0x0008 -#define PCIM_CMD_MWRICEN 0x0010 -#define PCIM_CMD_PERRESPEN 0x0040 -#define PCIM_CMD_SERRESPEN 0x0100 -#define PCIM_CMD_BACKTOBACK 0x0200 -#define PCIM_CMD_INTxDIS 0x0400 -#define PCIR_STATUS 0x06 -#define PCIM_STATUS_INTxSTATE 0x0008 -#define PCIM_STATUS_CAPPRESENT 0x0010 -#define PCIM_STATUS_66CAPABLE 0x0020 -#define PCIM_STATUS_BACKTOBACK 0x0080 -#define PCIM_STATUS_MDPERR 0x0100 -#define PCIM_STATUS_SEL_FAST 0x0000 -#define PCIM_STATUS_SEL_MEDIMUM 0x0200 -#define PCIM_STATUS_SEL_SLOW 0x0400 -#define PCIM_STATUS_SEL_MASK 0x0600 -#define PCIM_STATUS_STABORT 0x0800 -#define PCIM_STATUS_RTABORT 0x1000 -#define PCIM_STATUS_RMABORT 0x2000 -#define PCIM_STATUS_SERR 0x4000 -#define PCIM_STATUS_PERR 0x8000 -#define PCIR_REVID 0x08 -#define PCIR_PROGIF 0x09 -#define PCIR_SUBCLASS 0x0a -#define PCIR_CLASS 0x0b -#define PCIR_CACHELNSZ 0x0c -#define PCIR_LATTIMER 0x0d -#define PCIR_HDRTYPE 0x0e -#define PCIM_HDRTYPE 0x7f -#define PCIM_HDRTYPE_NORMAL 0x00 -#define PCIM_HDRTYPE_BRIDGE 0x01 -#define PCIM_HDRTYPE_CARDBUS 0x02 -#define PCIM_MFDEV 0x80 -#define PCIR_BIST 0x0f - -/* PCI Spec rev 2.2: 0FFFFh is an invalid value for Vendor ID. */ -#define PCIV_INVALID 0xffff - -/* Capability Register Offsets */ - -#define PCICAP_ID 0x0 -#define PCICAP_NEXTPTR 0x1 - -/* Capability Identification Numbers */ - -#define PCIY_PMG 0x01 /* PCI Power Management */ -#define PCIY_AGP 0x02 /* AGP */ -#define PCIY_VPD 0x03 /* Vital Product Data */ -#define PCIY_SLOTID 0x04 /* Slot Identification */ -#define PCIY_MSI 0x05 /* Message Signaled Interrupts */ -#define PCIY_CHSWP 0x06 /* CompactPCI Hot Swap */ -#define PCIY_PCIX 0x07 /* PCI-X */ -#define PCIY_HT 0x08 /* HyperTransport */ -#define PCIY_VENDOR 0x09 /* Vendor Unique */ -#define PCIY_DEBUG 0x0a /* Debug port */ -#define PCIY_CRES 0x0b /* CompactPCI central resource control */ -#define PCIY_HOTPLUG 0x0c /* PCI Hot-Plug */ -#define PCIY_SUBVENDOR 0x0d /* PCI-PCI bridge subvendor ID */ -#define PCIY_AGP8X 0x0e /* AGP 8x */ -#define PCIY_SECDEV 0x0f /* Secure Device */ -#define PCIY_EXPRESS 0x10 /* PCI Express */ -#define PCIY_MSIX 0x11 /* MSI-X */ -#define PCIY_SATA 0x12 /* SATA */ -#define PCIY_PCIAF 0x13 /* PCI Advanced Features */ -#define PCIY_EA 0x14 /* PCI Extended Allocation */ -#define PCIY_FPB 0x15 /* Flattening Portal Bridge */ -#define PCIY_MAX PCIY_FPB - -/* Extended Capability Register Fields */ - -#define PCIR_EXTCAP 0x100 -#define PCIM_EXTCAP_ID 0x0000ffff -#define PCIM_EXTCAP_VER 0x000f0000 -#define PCIM_EXTCAP_NEXTPTR 0xfff00000 -#define PCI_EXTCAP_ID(ecap) ((ecap) & PCIM_EXTCAP_ID) -#define PCI_EXTCAP_VER(ecap) (((ecap) & PCIM_EXTCAP_VER) >> 16) -#define PCI_EXTCAP_NEXTPTR(ecap) (((ecap) & PCIM_EXTCAP_NEXTPTR) >> 20) - -/* Extended Capability Identification Numbers */ - -#define PCIZ_AER 0x0001 /* Advanced Error Reporting */ -#define PCIZ_VC 0x0002 /* Virtual Channel if MFVC Ext Cap not set */ -#define PCIZ_SERNUM 0x0003 /* Device Serial Number */ -#define PCIZ_PWRBDGT 0x0004 /* Power Budgeting */ -#define PCIZ_RCLINK_DCL 0x0005 /* Root Complex Link Declaration */ -#define PCIZ_RCLINK_CTL 0x0006 /* Root Complex Internal Link Control */ -#define PCIZ_RCEC_ASSOC 0x0007 /* Root Complex Event Collector Association */ -#define PCIZ_MFVC 0x0008 /* Multi-Function Virtual Channel */ -#define PCIZ_VC2 0x0009 /* Virtual Channel if MFVC Ext Cap set */ -#define PCIZ_RCRB 0x000a /* RCRB Header */ -#define PCIZ_VENDOR 0x000b /* Vendor Unique */ -#define PCIZ_CAC 0x000c /* Configuration Access Correction -- obsolete */ -#define PCIZ_ACS 0x000d /* Access Control Services */ -#define PCIZ_ARI 0x000e /* Alternative Routing-ID Interpretation */ -#define PCIZ_ATS 0x000f /* Address Translation Services */ -#define PCIZ_SRIOV 0x0010 /* Single Root IO Virtualization */ -#define PCIZ_MRIOV 0x0011 /* Multiple Root IO Virtualization */ -#define PCIZ_MULTICAST 0x0012 /* Multicast */ -#define PCIZ_PAGE_REQ 0x0013 /* Page Request */ -#define PCIZ_AMD 0x0014 /* Reserved for AMD */ -#define PCIZ_RESIZE_BAR 0x0015 /* Resizable BAR */ -#define PCIZ_DPA 0x0016 /* Dynamic Power Allocation */ -#define PCIZ_TPH_REQ 0x0017 /* TPH Requester */ -#define PCIZ_LTR 0x0018 /* Latency Tolerance Reporting */ -#define PCIZ_SEC_PCIE 0x0019 /* Secondary PCI Express */ -#define PCIZ_PMUX 0x001a /* Protocol Multiplexing */ -#define PCIZ_PASID 0x001b /* Process Address Space ID */ -#define PCIZ_LN_REQ 0x001c /* LN Requester */ -#define PCIZ_DPC 0x001d /* Downstream Port Containment */ -#define PCIZ_L1PM 0x001e /* L1 PM Substates */ -#define PCIZ_PTM 0x001f /* Precision Time Measurement */ -#define PCIZ_M_PCIE 0x0020 /* PCIe over M-PHY */ -#define PCIZ_FRS 0x0021 /* FRS Queuing */ -#define PCIZ_RTR 0x0022 /* Readiness Time Reporting */ -#define PCIZ_DVSEC 0x0023 /* Designated Vendor-Specific */ -#define PCIZ_VF_REBAR 0x0024 /* VF Resizable BAR */ -#define PCIZ_DLNK 0x0025 /* Data Link Feature */ -#define PCIZ_16GT 0x0026 /* Physical Layer 16.0 GT/s */ -#define PCIZ_LMR 0x0027 /* Lane Margining at Receiver */ -#define PCIZ_HIER_ID 0x0028 /* Hierarchy ID */ -#define PCIZ_NPEM 0x0029 /* Native PCIe Enclosure Management */ -#define PCIZ_PL32 0x002a /* Physical Layer 32.0 GT/s */ -#define PCIZ_AP 0x002b /* Alternate Protocol */ -#define PCIZ_SFI 0x002c /* System Firmware Intermediary */ - -/* Resizable BARs */ -#define PCIM_REBAR_CAP 4 /* Capability register */ -#define PCIM_REBAR_CAP_SIZES 0x00fffff0 /* Supported BAR sizes */ -#define PCIM_REBAR_CTRL 8 /* Control register */ -#define PCIM_REBAR_CTRL_BAR_IDX 0x00000007 /* BAR index */ -#define PCIM_REBAR_CTRL_NBAR_MASK 0x000000e0 -#define PCIM_REBAR_CTRL_NBAR_SHIFT 5 /* Shift for # of BARs */ -#define PCIM_REBAR_CTRL_BAR_SIZE 0x00001f00 /* BAR size */ -#define PCIM_REBAR_CTRL_BAR_SHIFT 8 /* Shift for BAR size */ - -/* config registers for header type 0 devices */ - -#define PCIR_BARS 0x10 -#define PCIR_BAR(x) (PCIR_BARS + (x) * 4) -#define PCI_RID2BAR(rid) (((rid) - PCIR_BARS) / 4) -#define PCI_BAR_IO(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_IO_SPACE) -#define PCI_BAR_MEM(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_MEM_SPACE) -#define PCIM_BAR_SPACE 0x01 /* 0 = memory, 1 = I/O */ -#define PCIM_BAR_SPACE_IO 0x01 -#define PCIM_BAR_SPACE_MEMORY 0x00 -#define PCIM_BAR_MEM_TYPE_MASK 0x06 -#define PCIM_BAR_MEM_TYPE_32 0x00 /* 32 bit address */ -#define PCIM_BAR_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */ -#define PCIM_BAR_MEM_TYPE_64 0x04 /* 64 bit address */ -#define PCIM_BAR_MEM_PREFETCH 0x08 /* prefetchable? */ -#define PCIM_BAR_MEM_MASK (~0x0fUL) -#define PCIM_BAR_IO_MASK (~0x03UL) -#define PCIR_CIS 0x28 -#define PCIM_CIS_ASI_MASK 0x00000007 -#define PCIM_CIS_ASI_CONFIG 0 -#define PCIM_CIS_ASI_BAR0 1 -#define PCIM_CIS_ASI_BAR1 2 -#define PCIM_CIS_ASI_BAR2 3 -#define PCIM_CIS_ASI_BAR3 4 -#define PCIM_CIS_ASI_BAR4 5 -#define PCIM_CIS_ASI_BAR5 6 -#define PCIM_CIS_ASI_ROM 7 -#define PCIM_CIS_ADDR_MASK 0x0ffffff8 -#define PCIM_CIS_ROM_MASK 0xf0000000 -#define PCIM_CIS_CONFIG_MASK 0xff -#define PCIR_SUBVEND_0 0x2c -#define PCIR_SUBDEV_0 0x2e -#define PCIR_BIOS 0x30 -#define PCIM_BIOS_ENABLE 0x01 -#define PCIM_BIOS_ADDR_MASK 0xfffff800 -#define PCIR_CAP_PTR 0x34 -#define PCIR_INTLINE 0x3c -#define PCIR_INTPIN 0x3d -#define PCIR_MINGNT 0x3e -#define PCIR_MAXLAT 0x3f - -/* config registers for header type 1 (PCI-to-PCI bridge) devices */ - -#define PCIR_MAX_BAR_1 1 -#define PCIR_SECSTAT_1 0x1e - -#define PCIR_PRIBUS_1 0x18 -#define PCIR_SECBUS_1 0x19 -#define PCIR_SUBBUS_1 0x1a -#define PCIR_SECLAT_1 0x1b - -#define PCIR_IOBASEL_1 0x1c -#define PCIR_IOLIMITL_1 0x1d -#define PCIR_IOBASEH_1 0x30 -#define PCIR_IOLIMITH_1 0x32 -#define PCIM_BRIO_16 0x0 -#define PCIM_BRIO_32 0x1 -#define PCIM_BRIO_MASK 0xf - -#define PCIR_MEMBASE_1 0x20 -#define PCIR_MEMLIMIT_1 0x22 - -#define PCIR_PMBASEL_1 0x24 -#define PCIR_PMLIMITL_1 0x26 -#define PCIR_PMBASEH_1 0x28 -#define PCIR_PMLIMITH_1 0x2c -#define PCIM_BRPM_32 0x0 -#define PCIM_BRPM_64 0x1 -#define PCIM_BRPM_MASK 0xf - -#define PCIR_BIOS_1 0x38 -#define PCIR_BRIDGECTL_1 0x3e - -#define PCI_PPBMEMBASE(h, l) ((((rt_uint64_t)(h) << 32) + ((l) << 16)) & ~0xfffff) -#define PCI_PPBMEMLIMIT(h, l) ((((rt_uint64_t)(h) << 32) + ((l) << 16)) | 0xfffff) -#define PCI_PPBIOBASE(h, l) ((((h) << 16) + ((l) << 8)) & ~0xfff) -#define PCI_PPBIOLIMIT(h, l) ((((h) << 16) + ((l) << 8)) | 0xfff) - -/* config registers for header t ype 2 (CardBus) devices */ - -#define PCIR_MAX_BAR_2 0 -#define PCIR_CAP_PTR_2 0x14 -#define PCIR_SECSTAT_2 0x16 - -#define PCIR_PRIBUS_2 0x18 -#define PCIR_SECBUS_2 0x19 -#define PCIR_SUBBUS_2 0x1a -#define PCIR_SECLAT_2 0x1b - -#define PCIR_MEMBASE0_2 0x1c -#define PCIR_MEMLIMIT0_2 0x20 -#define PCIR_MEMBASE1_2 0x24 -#define PCIR_MEMLIMIT1_2 0x28 -#define PCIR_IOBASE0_2 0x2c -#define PCIR_IOLIMIT0_2 0x30 -#define PCIR_IOBASE1_2 0x34 -#define PCIR_IOLIMIT1_2 0x38 -#define PCIM_CBBIO_16 0x0 -#define PCIM_CBBIO_32 0x1 -#define PCIM_CBBIO_MASK 0x3 - -#define PCIR_BRIDGECTL_2 0x3e - -#define PCIR_SUBVEND_2 0x40 -#define PCIR_SUBDEV_2 0x42 - -#define PCIR_PCCARDIF_2 0x44 - -#define PCI_CBBMEMBASE(l) ((l) & ~0xfffff) -#define PCI_CBBMEMLIMIT(l) ((l) | 0xfffff) -#define PCI_CBBIOBASE(l) ((l) & ~0x3) -#define PCI_CBBIOLIMIT(l) ((l) | 0x3) - -/* PCI device class, subclass and programming interface definitions */ -#define PCIC_NOT_DEFINED 0x0000 -#define PCIS_NOT_DEFINED_VGA 0x0001 - -#define PCIC_STORAGE 0x01 -#define PCIS_STORAGE_SCSI 0x0100 -#define PCIS_STORAGE_IDE 0x0101 -#define PCIS_STORAGE_FLOPPY 0x0102 -#define PCIS_STORAGE_IPI 0x0103 -#define PCIS_STORAGE_RAID 0x0104 -#define PCIS_STORAGE_SATA 0x0106 -#define PCIS_STORAGE_SATA_AHCI 0x010601 -#define PCIS_STORAGE_SAS 0x0107 -#define PCIS_STORAGE_EXPRESS 0x010802 -#define PCIS_STORAGE_OTHER 0x0180 - -#define PCIC_NETWORK 0x02 -#define PCIS_NETWORK_ETHERNET 0x0200 -#define PCIS_NETWORK_TOKEN_RING 0x0201 -#define PCIS_NETWORK_FDDI 0x0202 -#define PCIS_NETWORK_ATM 0x0203 -#define PCIS_NETWORK_OTHER 0x0280 - -#define PCIC_DISPLAY 0x03 -#define PCIS_DISPLAY_VGA 0x0300 -#define PCIS_DISPLAY_XGA 0x0301 -#define PCIS_DISPLAY_3D 0x0302 -#define PCIS_DISPLAY_OTHER 0x0380 - -#define PCIC_MULTIMEDIA 0x04 -#define PCIS_MULTIMEDIA_VIDEO 0x0400 -#define PCIS_MULTIMEDIA_AUDIO 0x0401 -#define PCIS_MULTIMEDIA_PHONE 0x0402 -#define PCIS_MULTIMEDIA_HD_AUDIO 0x0403 -#define PCIS_MULTIMEDIA_OTHER 0x0480 - -#define PCIC_MEMORY 0x05 -#define PCIS_MEMORY_RAM 0x0500 -#define PCIS_MEMORY_FLASH 0x0501 -#define PCIS_MEMORY_CXL 0x0502 -#define PCIS_MEMORY_OTHER 0x0580 - -#define PCIC_BRIDGE 0x06 -#define PCIS_BRIDGE_HOST 0x0600 -#define PCIS_BRIDGE_ISA 0x0601 -#define PCIS_BRIDGE_EISA 0x0602 -#define PCIS_BRIDGE_MC 0x0603 -#define PCIS_BRIDGE_PCI 0x0604 -#define PCIS_BRIDGE_PCI_NORMAL 0x060400 -#define PCIS_BRIDGE_PCI_SUBTRACTIVE 0x060401 -#define PCIS_BRIDGE_PCMCIA 0x0605 -#define PCIS_BRIDGE_NUBUS 0x0606 -#define PCIS_BRIDGE_CARDBUS 0x0607 -#define PCIS_BRIDGE_RACEWAY 0x0608 -#define PCIS_BRIDGE_OTHER 0x0680 - -#define PCIC_COMMUNICATION 0x07 -#define PCIS_COMMUNICATION_SERIAL 0x0700 -#define PCIS_COMMUNICATION_PARALLEL 0x0701 -#define PCIS_COMMUNICATION_MULTISERIAL 0x0702 -#define PCIS_COMMUNICATION_MODEM 0x0703 -#define PCIS_COMMUNICATION_OTHER 0x0780 - -#define PCIC_SYSTEM 0x08 -#define PCIS_SYSTEM_PIC 0x0800 -#define PCIS_SYSTEM_PIC_IOAPIC 0x080010 -#define PCIS_SYSTEM_PIC_IOXAPIC 0x080020 -#define PCIS_SYSTEM_DMA 0x0801 -#define PCIS_SYSTEM_TIMER 0x0802 -#define PCIS_SYSTEM_RTC 0x0803 -#define PCIS_SYSTEM_PCI_HOTPLUG 0x0804 -#define PCIS_SYSTEM_SDHCI 0x0805 -#define PCIS_SYSTEM_RCEC 0x0807 -#define PCIS_SYSTEM_OTHER 0x0880 - -#define PCIC_INPUT 0x09 -#define PCIS_INPUT_KEYBOARD 0x0900 -#define PCIS_INPUT_PEN 0x0901 -#define PCIS_INPUT_MOUSE 0x0902 -#define PCIS_INPUT_SCANNER 0x0903 -#define PCIS_INPUT_GAMEPORT 0x0904 -#define PCIS_INPUT_OTHER 0x0980 - -#define PCIC_DOCKING 0x0a -#define PCIS_DOCKING_GENERIC 0x0a00 -#define PCIS_DOCKING_OTHER 0x0a80 - -#define PCIC_PROCESSOR 0x0b -#define PCIS_PROCESSOR_386 0x0b00 -#define PCIS_PROCESSOR_486 0x0b01 -#define PCIS_PROCESSOR_PENTIUM 0x0b02 -#define PCIS_PROCESSOR_ALPHA 0x0b10 -#define PCIS_PROCESSOR_POWERPC 0x0b20 -#define PCIS_PROCESSOR_MIPS 0x0b30 -#define PCIS_PROCESSOR_CO 0x0b40 - -#define PCIC_SERIAL 0x0c -#define PCIS_SERIAL_FIREWIRE 0x0c00 -#define PCIS_SERIAL_FIREWIRE_OHCI 0x0c0010 -#define PCIS_SERIAL_ACCESS 0x0c01 -#define PCIS_SERIAL_SSA 0x0c02 -#define PCIS_SERIAL_USB 0x0c03 -#define PCIS_SERIAL_USB_UHCI 0x0c0300 -#define PCIS_SERIAL_USB_OHCI 0x0c0310 -#define PCIS_SERIAL_USB_EHCI 0x0c0320 -#define PCIS_SERIAL_USB_XHCI 0x0c0330 -#define PCIS_SERIAL_USB_DEVICE 0x0c03fe -#define PCIS_SERIAL_FIBER 0x0c04 -#define PCIS_SERIAL_SMBUS 0x0c05 -#define PCIS_SERIAL_IPMI 0x0c07 -#define PCIS_SERIAL_IPMI_SMIC 0x0c0700 -#define PCIS_SERIAL_IPMI_KCS 0x0c0701 -#define PCIS_SERIAL_IPMI_BT 0x0c0702 - -#define PCIC_WIRELESS 0x0d -#define PCIS_WIRELESS_RF_CONTROLLER 0x0d10 -#define PCIS_WIRELESS_WHCI 0x0d1010 - -#define PCIC_INTELLIGENT 0x0e -#define PCIS_INTELLIGENT_I2O 0x0e00 - -#define PCIC_SATELLITE 0x0f -#define PCIS_SATELLITE_TV 0x0f00 -#define PCIS_SATELLITE_AUDIO 0x0f01 -#define PCIS_SATELLITE_VOICE 0x0f03 -#define PCIS_SATELLITE_DATA 0x0f04 - -#define PCIC_CRYPT 0x10 -#define PCIS_CRYPT_NETWORK 0x1000 -#define PCIS_CRYPT_ENTERTAINMENT 0x1001 -#define PCIS_CRYPT_OTHER 0x1080 - -#define PCIC_SIGNAL_PROCESSING 0x11 -#define PCIS_SP_DPIO 0x1100 -#define PCIS_SP_OTHER 0x1180 - -#define PCIS_OTHERS 0xff - -/* Bridge Control Values. */ -#define PCIB_BCR_PERR_ENABLE 0x0001 -#define PCIB_BCR_SERR_ENABLE 0x0002 -#define PCIB_BCR_ISA_ENABLE 0x0004 -#define PCIB_BCR_VGA_ENABLE 0x0008 -#define PCIB_BCR_MASTER_ABORT_MODE 0x0020 -#define PCIB_BCR_SECBUS_RESET 0x0040 -#define PCIB_BCR_SECBUS_BACKTOBACK 0x0080 -#define PCIB_BCR_PRI_DISCARD_TIMEOUT 0x0100 -#define PCIB_BCR_SEC_DISCARD_TIMEOUT 0x0200 -#define PCIB_BCR_DISCARD_TIMER_STATUS 0x0400 -#define PCIB_BCR_DISCARD_TIMER_SERREN 0x0800 - -#define CBB_BCR_PERR_ENABLE 0x0001 -#define CBB_BCR_SERR_ENABLE 0x0002 -#define CBB_BCR_ISA_ENABLE 0x0004 -#define CBB_BCR_VGA_ENABLE 0x0008 -#define CBB_BCR_MASTER_ABORT_MODE 0x0020 -#define CBB_BCR_CARDBUS_RESET 0x0040 -#define CBB_BCR_IREQ_INT_ENABLE 0x0080 -#define CBB_BCR_PREFETCH_0_ENABLE 0x0100 -#define CBB_BCR_PREFETCH_1_ENABLE 0x0200 -#define CBB_BCR_WRITE_POSTING_ENABLE 0x0400 - -/* PCI power manangement */ -#define PCIR_POWER_CAP 0x2 -#define PCIM_PCAP_SPEC 0x0007 -#define PCIM_PCAP_PMEREQCLK 0x0008 -#define PCIM_PCAP_DEVSPECINIT 0x0020 -#define PCIM_PCAP_AUXPWR_0 0x0000 -#define PCIM_PCAP_AUXPWR_55 0x0040 -#define PCIM_PCAP_AUXPWR_100 0x0080 -#define PCIM_PCAP_AUXPWR_160 0x00c0 -#define PCIM_PCAP_AUXPWR_220 0x0100 -#define PCIM_PCAP_AUXPWR_270 0x0140 -#define PCIM_PCAP_AUXPWR_320 0x0180 -#define PCIM_PCAP_AUXPWR_375 0x01c0 -#define PCIM_PCAP_AUXPWRMASK 0x01c0 -#define PCIM_PCAP_D1SUPP 0x0200 -#define PCIM_PCAP_D2SUPP 0x0400 -#define PCIM_PCAP_PMEMASK 0xf800 -#define PCIM_PCAP_D0PME 0x0800 -#define PCIM_PCAP_D1PME 0x1000 -#define PCIM_PCAP_D2PME 0x2000 -#define PCIM_PCAP_D3PME_HOT 0x4000 -#define PCIM_PCAP_D3PME_COLD 0x8000 - -#define PCIR_POWER_STATUS 0x4 -#define PCIM_PSTAT_D0 0x0000 -#define PCIM_PSTAT_D1 0x0001 -#define PCIM_PSTAT_D2 0x0002 -#define PCIM_PSTAT_D3 0x0003 -#define PCIM_PSTAT_DMASK 0x0003 -#define PCIM_PSTAT_NOSOFTRESET 0x0008 -#define PCIM_PSTAT_PMEENABLE 0x0100 -#define PCIM_PSTAT_D0POWER 0x0000 -#define PCIM_PSTAT_D1POWER 0x0200 -#define PCIM_PSTAT_D2POWER 0x0400 -#define PCIM_PSTAT_D3POWER 0x0600 -#define PCIM_PSTAT_D0HEAT 0x0800 -#define PCIM_PSTAT_D1HEAT 0x0a00 -#define PCIM_PSTAT_D2HEAT 0x0c00 -#define PCIM_PSTAT_D3HEAT 0x0e00 -#define PCIM_PSTAT_DATASELMASK 0x1e00 -#define PCIM_PSTAT_DATAUNKN 0x0000 -#define PCIM_PSTAT_DATADIV10 0x2000 -#define PCIM_PSTAT_DATADIV100 0x4000 -#define PCIM_PSTAT_DATADIV1000 0x6000 -#define PCIM_PSTAT_DATADIVMASK 0x6000 -#define PCIM_PSTAT_PME 0x8000 - -#define PCIR_POWER_BSE 0x6 -#define PCIM_PMCSR_BSE_D3B3 0x00 -#define PCIM_PMCSR_BSE_D3B2 0x40 -#define PCIM_PMCSR_BSE_BPCCE 0x80 - -#define PCIR_POWER_DATA 0x7 - -/* VPD capability registers */ -#define PCIR_VPD_ADDR 0x2 -#define PCIR_VPD_DATA 0x4 - -/* PCI Message Signalled Interrupts (MSI) */ -#define PCIR_MSI_CTRL 0x2 -#define PCIM_MSICTRL_VECTOR 0x0100 -#define PCIM_MSICTRL_64BIT 0x0080 -#define PCIM_MSICTRL_MME_MASK 0x0070 -#define PCIM_MSICTRL_MME_SHIFT 0x4 -#define PCIM_MSICTRL_MME_1 0x0000 -#define PCIM_MSICTRL_MME_2 0x0010 -#define PCIM_MSICTRL_MME_4 0x0020 -#define PCIM_MSICTRL_MME_8 0x0030 -#define PCIM_MSICTRL_MME_16 0x0040 -#define PCIM_MSICTRL_MME_32 0x0050 -#define PCIM_MSICTRL_MMC_MASK 0x000e -#define PCIM_MSICTRL_MMC_SHIFT 0x1 -#define PCIM_MSICTRL_MMC_1 0x0000 -#define PCIM_MSICTRL_MMC_2 0x0002 -#define PCIM_MSICTRL_MMC_4 0x0004 -#define PCIM_MSICTRL_MMC_8 0x0006 -#define PCIM_MSICTRL_MMC_16 0x0008 -#define PCIM_MSICTRL_MMC_32 0x000a -#define PCIM_MSICTRL_MSI_ENABLE 0x0001 -#define PCIR_MSI_ADDR 0x4 -#define PCIR_MSI_ADDR_HIGH 0x8 -#define PCIR_MSI_DATA 0x8 -#define PCIR_MSI_DATA_64BIT 0xc -#define PCIR_MSI_MASK 0xc -#define PCIR_MSI_MASK_64BIT 0x10 -#define PCIR_MSI_PENDING 0x14 - -/* PCI Enhanced Allocation registers */ -#define PCIR_EA_NUM_ENT 2 /* Number of Capability Entries */ -#define PCIM_EA_NUM_ENT_MASK 0x3f /* Num Entries Mask */ -#define PCIR_EA_FIRST_ENT 4 /* First EA Entry in List */ -#define PCIR_EA_FIRST_ENT_BRIDGE 8 /* First EA Entry for Bridges */ -#define PCIM_EA_ES 0x00000007 /* Entry Size */ -#define PCIM_EA_BEI 0x000000f0 /* BAR Equivalent Indicator */ -#define PCIM_EA_BEI_OFFSET 4 -/* 0-5 map to BARs 0-5 respectively */ -#define PCIM_EA_BEI_BAR_0 0 -#define PCIM_EA_BEI_BAR_5 5 -#define PCIM_EA_BEI_BAR(x) (((x) >> PCIM_EA_BEI_OFFSET) & 0xf) -#define PCIM_EA_BEI_BRIDGE 0x6 /* Resource behind bridge */ -#define PCIM_EA_BEI_ENI 0x7 /* Equivalent Not Indicated */ -#define PCIM_EA_BEI_ROM 0x8 /* Expansion ROM */ -/* 9-14 map to VF BARs 0-5 respectively */ -#define PCIM_EA_BEI_VF_BAR_0 9 -#define PCIM_EA_BEI_VF_BAR_5 14 -#define PCIM_EA_BEI_RESERVED 0xf /* Reserved - Treat like ENI */ -#define PCIM_EA_PP 0x0000ff00 /* Primary Properties */ -#define PCIM_EA_PP_OFFSET 8 -#define PCIM_EA_SP_OFFSET 16 -#define PCIM_EA_SP 0x00ff0000 /* Secondary Properties */ -#define PCIM_EA_P_MEM 0x00 /* Non-Prefetch Memory */ -#define PCIM_EA_P_MEM_PREFETCH 0x01 /* Prefetchable Memory */ -#define PCIM_EA_P_IO 0x02 /* I/O Space */ -#define PCIM_EA_P_VF_MEM_PREFETCH 0x03 /* VF Prefetchable Memory */ -#define PCIM_EA_P_VF_MEM 0x04 /* VF Non-Prefetch Memory */ -#define PCIM_EA_P_BRIDGE_MEM 0x05 /* Bridge Non-Prefetch Memory */ -#define PCIM_EA_P_BRIDGE_MEM_PREFETCH 0x06 /* Bridge Prefetchable Memory */ -#define PCIM_EA_P_BRIDGE_IO 0x07 /* Bridge I/O Space */ -/* 0x08-0xfc reserved */ -#define PCIM_EA_P_MEM_RESERVED 0xfd /* Reserved Memory */ -#define PCIM_EA_P_IO_RESERVED 0xfe /* Reserved I/O Space */ -#define PCIM_EA_P_UNAVAILABLE 0xff /* Entry Unavailable */ -#define PCIM_EA_WRITABLE 0x40000000 /* Writable: 1 = RW, 0 = HwInit */ -#define PCIM_EA_ENABLE 0x80000000 /* Enable for this entry */ -#define PCIM_EA_BASE 4 /* Base Address Offset */ -#define PCIM_EA_MAX_OFFSET 8 /* MaxOffset (resource length) */ -/* bit 0 is reserved */ -#define PCIM_EA_IS_64 0x00000002 /* 64-bit field flag */ -#define PCIM_EA_FIELD_MASK 0xfffffffc /* For Base & Max Offset */ -/* Bridge config register */ -#define PCIM_EA_SEC_NR(reg) ((reg) & 0xff) -#define PCIM_EA_SUB_NR(reg) (((reg) >> 8) & 0xff) - -/* PCI-X definitions */ - -/* For header type 0 devices */ -#define PCIXR_COMMAND 0x2 -#define PCIXM_COMMAND_DPERR_E 0x0001 /* Data Parity Error Recovery */ -#define PCIXM_COMMAND_ERO 0x0002 /* Enable Relaxed Ordering */ -#define PCIXM_COMMAND_MAX_READ 0x000c /* Maximum Burst Read Count */ -#define PCIXM_COMMAND_MAX_READ_512 0x0000 -#define PCIXM_COMMAND_MAX_READ_1024 0x0004 -#define PCIXM_COMMAND_MAX_READ_2048 0x0008 -#define PCIXM_COMMAND_MAX_READ_4096 0x000c -#define PCIXM_COMMAND_MAX_SPLITS 0x0070 /* Maximum Split Transactions */ -#define PCIXM_COMMAND_MAX_SPLITS_1 0x0000 -#define PCIXM_COMMAND_MAX_SPLITS_2 0x0010 -#define PCIXM_COMMAND_MAX_SPLITS_3 0x0020 -#define PCIXM_COMMAND_MAX_SPLITS_4 0x0030 -#define PCIXM_COMMAND_MAX_SPLITS_8 0x0040 -#define PCIXM_COMMAND_MAX_SPLITS_12 0x0050 -#define PCIXM_COMMAND_MAX_SPLITS_16 0x0060 -#define PCIXM_COMMAND_MAX_SPLITS_32 0x0070 -#define PCIXM_COMMAND_VERSION 0x3000 -#define PCIXR_STATUS 0x4 -#define PCIXM_STATUS_DEVFN 0x000000ff -#define PCIXM_STATUS_BUS 0x0000ff00 -#define PCIXM_STATUS_64BIT 0x00010000 -#define PCIXM_STATUS_133CAP 0x00020000 -#define PCIXM_STATUS_SC_DISCARDED 0x00040000 -#define PCIXM_STATUS_UNEXP_SC 0x00080000 -#define PCIXM_STATUS_COMPLEX_DEV 0x00100000 -#define PCIXM_STATUS_MAX_READ 0x00600000 -#define PCIXM_STATUS_MAX_READ_512 0x00000000 -#define PCIXM_STATUS_MAX_READ_1024 0x00200000 -#define PCIXM_STATUS_MAX_READ_2048 0x00400000 -#define PCIXM_STATUS_MAX_READ_4096 0x00600000 -#define PCIXM_STATUS_MAX_SPLITS 0x03800000 -#define PCIXM_STATUS_MAX_SPLITS_1 0x00000000 -#define PCIXM_STATUS_MAX_SPLITS_2 0x00800000 -#define PCIXM_STATUS_MAX_SPLITS_3 0x01000000 -#define PCIXM_STATUS_MAX_SPLITS_4 0x01800000 -#define PCIXM_STATUS_MAX_SPLITS_8 0x02000000 -#define PCIXM_STATUS_MAX_SPLITS_12 0x02800000 -#define PCIXM_STATUS_MAX_SPLITS_16 0x03000000 -#define PCIXM_STATUS_MAX_SPLITS_32 0x03800000 -#define PCIXM_STATUS_MAX_CUM_READ 0x1c000000 -#define PCIXM_STATUS_RCVD_SC_ERR 0x20000000 -#define PCIXM_STATUS_266CAP 0x40000000 -#define PCIXM_STATUS_533CAP 0x80000000 - -/* For header type 1 devices (PCI-X bridges) */ -#define PCIXR_SEC_STATUS 0x2 -#define PCIXM_SEC_STATUS_64BIT 0x0001 -#define PCIXM_SEC_STATUS_133CAP 0x0002 -#define PCIXM_SEC_STATUS_SC_DISC 0x0004 -#define PCIXM_SEC_STATUS_UNEXP_SC 0x0008 -#define PCIXM_SEC_STATUS_SC_OVERRUN 0x0010 -#define PCIXM_SEC_STATUS_SR_DELAYED 0x0020 -#define PCIXM_SEC_STATUS_BUS_MODE 0x03c0 -#define PCIXM_SEC_STATUS_VERSION 0x3000 -#define PCIXM_SEC_STATUS_266CAP 0x4000 -#define PCIXM_SEC_STATUS_533CAP 0x8000 -#define PCIXR_BRIDGE_STATUS 0x4 -#define PCIXM_BRIDGE_STATUS_DEVFN 0x000000ff -#define PCIXM_BRIDGE_STATUS_BUS 0x0000ff00 -#define PCIXM_BRIDGE_STATUS_64BIT 0x00010000 -#define PCIXM_BRIDGE_STATUS_133CAP 0x00020000 -#define PCIXM_BRIDGE_STATUS_SC_DISCARDED 0x00040000 -#define PCIXM_BRIDGE_STATUS_UNEXP_SC 0x00080000 -#define PCIXM_BRIDGE_STATUS_SC_OVERRUN 0x00100000 -#define PCIXM_BRIDGE_STATUS_SR_DELAYED 0x00200000 -#define PCIXM_BRIDGE_STATUS_DEVID_MSGCAP 0x20000000 -#define PCIXM_BRIDGE_STATUS_266CAP 0x40000000 -#define PCIXM_BRIDGE_STATUS_533CAP 0x80000000 - -/* HT (HyperTransport) Capability definitions */ -#define PCIR_HT_COMMAND 0x2 -#define PCIM_HTCMD_CAP_MASK 0xf800 /* Capability type. */ -#define PCIM_HTCAP_SLAVE 0x0000 /* 000xx */ -#define PCIM_HTCAP_HOST 0x2000 /* 001xx */ -#define PCIM_HTCAP_SWITCH 0x4000 /* 01000 */ -#define PCIM_HTCAP_INTERRUPT 0x8000 /* 10000 */ -#define PCIM_HTCAP_REVISION_ID 0x8800 /* 10001 */ -#define PCIM_HTCAP_UNITID_CLUMPING 0x9000 /* 10010 */ -#define PCIM_HTCAP_EXT_CONFIG_SPACE 0x9800 /* 10011 */ -#define PCIM_HTCAP_ADDRESS_MAPPING 0xa000 /* 10100 */ -#define PCIM_HTCAP_MSI_MAPPING 0xa800 /* 10101 */ -#define PCIM_HTCAP_DIRECT_ROUTE 0xb000 /* 10110 */ -#define PCIM_HTCAP_VCSET 0xb800 /* 10111 */ -#define PCIM_HTCAP_RETRY_MODE 0xc000 /* 11000 */ -#define PCIM_HTCAP_X86_ENCODING 0xc800 /* 11001 */ -#define PCIM_HTCAP_GEN3 0xd000 /* 11010 */ -#define PCIM_HTCAP_FLE 0xd800 /* 11011 */ -#define PCIM_HTCAP_PM 0xe000 /* 11100 */ -#define PCIM_HTCAP_HIGH_NODE_COUNT 0xe800 /* 11101 */ - -/* HT MSI Mapping Capability definitions. */ -#define PCIM_HTCMD_MSI_ENABLE 0x0001 -#define PCIM_HTCMD_MSI_FIXED 0x0002 -#define PCIR_HTMSI_ADDRESS_LO 0x4 -#define PCIR_HTMSI_ADDRESS_HI 0x8 - -/* PCI Vendor capability definitions */ -#define PCIR_VENDOR_LENGTH 0x2 -#define PCIR_VENDOR_DATA 0x3 - -/* PCI Device capability definitions */ -#define PCIR_DEVICE_LENGTH 0x2 - -/* PCI EHCI Debug Port definitions */ -#define PCIR_DEBUG_PORT 0x2 -#define PCIM_DEBUG_PORT_OFFSET 0x1fff -#define PCIM_DEBUG_PORT_BAR 0xe000 - -/* PCI-PCI Bridge Subvendor definitions */ -#define PCIR_SUBVENDCAP_ID 0x4 -#define PCIR_SUBVENDCAP 0x4 -#define PCIR_SUBDEVCAP 0x6 - -/* PCI Express definitions */ -#define PCIER_FLAGS 0x2 -#define PCIEM_FLAGS_VERSION 0x000f -#define PCIEM_FLAGS_TYPE 0x00f0 -#define PCIEM_TYPE_ENDPOINT 0x0000 -#define PCIEM_TYPE_LEGACY_ENDPOINT 0x0010 -#define PCIEM_TYPE_ROOT_PORT 0x0040 -#define PCIEM_TYPE_UPSTREAM_PORT 0x0050 -#define PCIEM_TYPE_DOWNSTREAM_PORT 0x0060 -#define PCIEM_TYPE_PCI_BRIDGE 0x0070 -#define PCIEM_TYPE_PCIE_BRIDGE 0x0080 -#define PCIEM_TYPE_ROOT_INT_EP 0x0090 -#define PCIEM_TYPE_ROOT_EC 0x00a0 -#define PCIEM_FLAGS_SLOT 0x0100 -#define PCIEM_FLAGS_IRQ 0x3e00 -#define PCIER_DEVICE_CAP 0x4 -#define PCIEM_CAP_MAX_PAYLOAD 0x00000007 -#define PCIEM_CAP_PHANTHOM_FUNCS 0x00000018 -#define PCIEM_CAP_EXT_TAG_FIELD 0x00000020 -#define PCIEM_CAP_L0S_LATENCY 0x000001c0 -#define PCIEM_CAP_L1_LATENCY 0x00000e00 -#define PCIEM_CAP_ROLE_ERR_RPT 0x00008000 -#define PCIEM_CAP_SLOT_PWR_LIM_VAL 0x03fc0000 -#define PCIEM_CAP_SLOT_PWR_LIM_SCALE 0x0c000000 -#define PCIEM_CAP_FLR 0x10000000 -#define PCIER_DEVICE_CTL 0x8 -#define PCIEM_CTL_COR_ENABLE 0x0001 -#define PCIEM_CTL_NFER_ENABLE 0x0002 -#define PCIEM_CTL_FER_ENABLE 0x0004 -#define PCIEM_CTL_URR_ENABLE 0x0008 -#define PCIEM_CTL_RELAXED_ORD_ENABLE 0x0010 -#define PCIEM_CTL_MAX_PAYLOAD 0x00e0 -#define PCIEM_CTL_EXT_TAG_FIELD 0x0100 -#define PCIEM_CTL_PHANTHOM_FUNCS 0x0200 -#define PCIEM_CTL_AUX_POWER_PM 0x0400 -#define PCIEM_CTL_NOSNOOP_ENABLE 0x0800 -#define PCIEM_CTL_MAX_READ_REQUEST 0x7000 -#define PCIEM_CTL_BRDG_CFG_RETRY 0x8000 /* PCI-E - PCI/PCI-X bridges */ -#define PCIEM_CTL_INITIATE_FLR 0x8000 /* FLR capable endpoints */ -#define PCIER_DEVICE_STA 0xa -#define PCIEM_STA_CORRECTABLE_ERROR 0x0001 -#define PCIEM_STA_NON_FATAL_ERROR 0x0002 -#define PCIEM_STA_FATAL_ERROR 0x0004 -#define PCIEM_STA_UNSUPPORTED_REQ 0x0008 -#define PCIEM_STA_AUX_POWER 0x0010 -#define PCIEM_STA_TRANSACTION_PND 0x0020 -#define PCIER_LINK_CAP 0xc -#define PCIEM_LINK_CAP_MAX_SPEED 0x0000000f -#define PCIEM_LINK_CAP_MAX_WIDTH 0x000003f0 -#define PCIEM_LINK_CAP_ASPM 0x00000c00 -#define PCIEM_LINK_CAP_L0S_EXIT 0x00007000 -#define PCIEM_LINK_CAP_L1_EXIT 0x00038000 -#define PCIEM_LINK_CAP_CLOCK_PM 0x00040000 -#define PCIEM_LINK_CAP_SURPRISE_DOWN 0x00080000 -#define PCIEM_LINK_CAP_DL_ACTIVE 0x00100000 -#define PCIEM_LINK_CAP_LINK_BW_NOTIFY 0x00200000 -#define PCIEM_LINK_CAP_ASPM_COMPLIANCE 0x00400000 -#define PCIEM_LINK_CAP_PORT 0xff000000 -#define PCIER_LINK_CTL 0x10 -#define PCIEM_LINK_CTL_ASPMC_DIS 0x0000 -#define PCIEM_LINK_CTL_ASPMC_L0S 0x0001 -#define PCIEM_LINK_CTL_ASPMC_L1 0x0002 -#define PCIEM_LINK_CTL_ASPMC 0x0003 -#define PCIEM_LINK_CTL_RCB 0x0008 -#define PCIEM_LINK_CTL_LINK_DIS 0x0010 -#define PCIEM_LINK_CTL_RETRAIN_LINK 0x0020 -#define PCIEM_LINK_CTL_COMMON_CLOCK 0x0040 -#define PCIEM_LINK_CTL_EXTENDED_SYNC 0x0080 -#define PCIEM_LINK_CTL_ECPM 0x0100 -#define PCIEM_LINK_CTL_HAWD 0x0200 -#define PCIEM_LINK_CTL_LBMIE 0x0400 -#define PCIEM_LINK_CTL_LABIE 0x0800 -#define PCIER_LINK_STA 0x12 -#define PCIEM_LINK_STA_SPEED 0x000f -#define PCIEM_LINK_STA_WIDTH 0x03f0 -#define PCIEM_LINK_STA_TRAINING_ERROR 0x0400 -#define PCIEM_LINK_STA_TRAINING 0x0800 -#define PCIEM_LINK_STA_SLOT_CLOCK 0x1000 -#define PCIEM_LINK_STA_DL_ACTIVE 0x2000 -#define PCIEM_LINK_STA_LINK_BW_MGMT 0x4000 -#define PCIEM_LINK_STA_LINK_AUTO_BW 0x8000 -#define PCIER_SLOT_CAP 0x14 -#define PCIEM_SLOT_CAP_APB 0x00000001 -#define PCIEM_SLOT_CAP_PCP 0x00000002 -#define PCIEM_SLOT_CAP_MRLSP 0x00000004 -#define PCIEM_SLOT_CAP_AIP 0x00000008 -#define PCIEM_SLOT_CAP_PIP 0x00000010 -#define PCIEM_SLOT_CAP_HPS 0x00000020 -#define PCIEM_SLOT_CAP_HPC 0x00000040 -#define PCIEM_SLOT_CAP_SPLV 0x00007f80 -#define PCIEM_SLOT_CAP_SPLS 0x00018000 -#define PCIEM_SLOT_CAP_EIP 0x00020000 -#define PCIEM_SLOT_CAP_NCCS 0x00040000 -#define PCIEM_SLOT_CAP_PSN 0xfff80000 -#define PCIER_SLOT_CTL 0x18 -#define PCIEM_SLOT_CTL_ABPE 0x0001 -#define PCIEM_SLOT_CTL_PFDE 0x0002 -#define PCIEM_SLOT_CTL_MRLSCE 0x0004 -#define PCIEM_SLOT_CTL_PDCE 0x0008 -#define PCIEM_SLOT_CTL_CCIE 0x0010 -#define PCIEM_SLOT_CTL_HPIE 0x0020 -#define PCIEM_SLOT_CTL_AIC 0x00c0 -#define PCIEM_SLOT_CTL_AI_ON 0x0040 -#define PCIEM_SLOT_CTL_AI_BLINK 0x0080 -#define PCIEM_SLOT_CTL_AI_OFF 0x00c0 -#define PCIEM_SLOT_CTL_PIC 0x0300 -#define PCIEM_SLOT_CTL_PI_ON 0x0100 -#define PCIEM_SLOT_CTL_PI_BLINK 0x0200 -#define PCIEM_SLOT_CTL_PI_OFF 0x0300 -#define PCIEM_SLOT_CTL_PCC 0x0400 -#define PCIEM_SLOT_CTL_PC_ON 0x0000 -#define PCIEM_SLOT_CTL_PC_OFF 0x0400 -#define PCIEM_SLOT_CTL_EIC 0x0800 -#define PCIEM_SLOT_CTL_DLLSCE 0x1000 -#define PCIER_SLOT_STA 0x1a -#define PCIEM_SLOT_STA_ABP 0x0001 -#define PCIEM_SLOT_STA_PFD 0x0002 -#define PCIEM_SLOT_STA_MRLSC 0x0004 -#define PCIEM_SLOT_STA_PDC 0x0008 -#define PCIEM_SLOT_STA_CC 0x0010 -#define PCIEM_SLOT_STA_MRLSS 0x0020 -#define PCIEM_SLOT_STA_PDS 0x0040 -#define PCIEM_SLOT_STA_EIS 0x0080 -#define PCIEM_SLOT_STA_DLLSC 0x0100 -#define PCIER_ROOT_CTL 0x1c -#define PCIEM_ROOT_CTL_SERR_CORR 0x0001 -#define PCIEM_ROOT_CTL_SERR_NONFATAL 0x0002 -#define PCIEM_ROOT_CTL_SERR_FATAL 0x0004 -#define PCIEM_ROOT_CTL_PME 0x0008 -#define PCIEM_ROOT_CTL_CRS_VIS 0x0010 -#define PCIER_ROOT_CAP 0x1e -#define PCIEM_ROOT_CAP_CRS_VIS 0x0001 -#define PCIER_ROOT_STA 0x20 -#define PCIEM_ROOT_STA_PME_REQID_MASK 0x0000ffff -#define PCIEM_ROOT_STA_PME_STATUS 0x00010000 -#define PCIEM_ROOT_STA_PME_PEND 0x00020000 -#define PCIER_DEVICE_CAP2 0x24 -#define PCIEM_CAP2_COMP_TIMO_RANGES 0x0000000f -#define PCIEM_CAP2_COMP_TIMO_RANGE_A 0x00000001 -#define PCIEM_CAP2_COMP_TIMO_RANGE_B 0x00000002 -#define PCIEM_CAP2_COMP_TIMO_RANGE_C 0x00000004 -#define PCIEM_CAP2_COMP_TIMO_RANGE_D 0x00000008 -#define PCIEM_CAP2_COMP_TIMO_DISABLE 0x00000010 -#define PCIEM_CAP2_ARI 0x00000020 -#define PCIER_DEVICE_CTL2 0x28 -#define PCIEM_CTL2_COMP_TIMO_VAL 0x000f -#define PCIEM_CTL2_COMP_TIMO_50MS 0x0000 -#define PCIEM_CTL2_COMP_TIMO_100US 0x0001 -#define PCIEM_CTL2_COMP_TIMO_10MS 0x0002 -#define PCIEM_CTL2_COMP_TIMO_55MS 0x0005 -#define PCIEM_CTL2_COMP_TIMO_210MS 0x0006 -#define PCIEM_CTL2_COMP_TIMO_900MS 0x0009 -#define PCIEM_CTL2_COMP_TIMO_3500MS 0x000a -#define PCIEM_CTL2_COMP_TIMO_13S 0x000d -#define PCIEM_CTL2_COMP_TIMO_64S 0x000e -#define PCIEM_CTL2_COMP_TIMO_DISABLE 0x0010 -#define PCIEM_CTL2_ARI 0x0020 -#define PCIEM_CTL2_ATOMIC_REQ_ENABLE 0x0040 -#define PCIEM_CTL2_ATOMIC_EGR_BLOCK 0x0080 -#define PCIEM_CTL2_ID_ORDERED_REQ_EN 0x0100 -#define PCIEM_CTL2_ID_ORDERED_CMP_EN 0x0200 -#define PCIEM_CTL2_LTR_ENABLE 0x0400 -#define PCIEM_CTL2_OBFF 0x6000 -#define PCIEM_OBFF_DISABLE 0x0000 -#define PCIEM_OBFF_MSGA_ENABLE 0x2000 -#define PCIEM_OBFF_MSGB_ENABLE 0x4000 -#define PCIEM_OBFF_WAKE_ENABLE 0x6000 -#define PCIEM_CTL2_END2END_TLP 0x8000 -#define PCIER_DEVICE_STA2 0x2a -#define PCIER_LINK_CAP2 0x2c -#define PCIER_LINK_CTL2 0x30 -#define PCIEM_LNKCTL2_TLS 0x000f -#define PCIEM_LNKCTL2_TLS_2_5GT 0x0001 -#define PCIEM_LNKCTL2_TLS_5_0GT 0x0002 -#define PCIEM_LNKCTL2_TLS_8_0GT 0x0003 -#define PCIEM_LNKCTL2_TLS_16_0GT 0x0004 -#define PCIEM_LNKCTL2_TLS_32_0GT 0x0005 -#define PCIEM_LNKCTL2_TLS_64_0GT 0x0006 -#define PCIEM_LNKCTL2_ENTER_COMP 0x0010 -#define PCIEM_LNKCTL2_TX_MARGIN 0x0380 -#define PCIEM_LNKCTL2_HASD 0x0020 -#define PCIER_LINK_STA2 0x32 -#define PCIER_SLOT_CAP2 0x34 -#define PCIER_SLOT_CTL2 0x38 -#define PCIER_SLOT_STA2 0x3a - -/* MSI-X definitions */ -#define PCIR_MSIX_CTRL 0x2 -#define PCIM_MSIXCTRL_MSIX_ENABLE 0x8000 -#define PCIM_MSIXCTRL_FUNCTION_MASK 0x4000 -#define PCIM_MSIXCTRL_TABLE_SIZE 0x07ff -#define PCIR_MSIX_TABLE 0x4 -#define PCIR_MSIX_PBA 0x8 -#define PCIM_MSIX_BIR_MASK 0x7 -#define PCIM_MSIX_TABLE_OFFSET 0xfffffff8 -#define PCIM_MSIX_BIR_BAR_10 0 -#define PCIM_MSIX_BIR_BAR_14 1 -#define PCIM_MSIX_BIR_BAR_18 2 -#define PCIM_MSIX_BIR_BAR_1C 3 -#define PCIM_MSIX_BIR_BAR_20 4 -#define PCIM_MSIX_BIR_BAR_24 5 -#define PCIM_MSIX_ENTRY_SIZE 16 -#define PCIM_MSIX_ENTRY_LOWER_ADDR 0x0 /* Message Address */ -#define PCIM_MSIX_ENTRY_UPPER_ADDR 0x4 /* Message Upper Address */ -#define PCIM_MSIX_ENTRY_DATA 0x8 /* Message Data */ -#define PCIM_MSIX_ENTRY_VECTOR_CTRL 0xc /* Vector Control */ -#define PCIM_MSIX_ENTRYVECTOR_CTRL_MASK 0x1 - -/* PCI Advanced Features definitions */ -#define PCIR_PCIAF_CAP 0x3 -#define PCIM_PCIAFCAP_TP 0x01 -#define PCIM_PCIAFCAP_FLR 0x02 -#define PCIR_PCIAF_CTRL 0x4 -#define PCIR_PCIAFCTRL_FLR 0x01 -#define PCIR_PCIAF_STATUS 0x5 -#define PCIR_PCIAFSTATUS_TP 0x01 - -/* Advanced Error Reporting */ -#define PCIR_AER_UC_STATUS 0x04 -#define PCIM_AER_UC_TRAINING_ERROR 0x00000001 -#define PCIM_AER_UC_DL_PROTOCOL_ERROR 0x00000010 -#define PCIM_AER_UC_SURPRISE_LINK_DOWN 0x00000020 -#define PCIM_AER_UC_POISONED_TLP 0x00001000 -#define PCIM_AER_UC_FC_PROTOCOL_ERROR 0x00002000 -#define PCIM_AER_UC_COMPLETION_TIMEOUT 0x00004000 -#define PCIM_AER_UC_COMPLETER_ABORT 0x00008000 -#define PCIM_AER_UC_UNEXPECTED_COMPLETION 0x00010000 -#define PCIM_AER_UC_RECEIVER_OVERFLOW 0x00020000 -#define PCIM_AER_UC_MALFORMED_TLP 0x00040000 -#define PCIM_AER_UC_ECRC_ERROR 0x00080000 -#define PCIM_AER_UC_UNSUPPORTED_REQUEST 0x00100000 -#define PCIM_AER_UC_ACS_VIOLATION 0x00200000 -#define PCIM_AER_UC_INTERNAL_ERROR 0x00400000 -#define PCIM_AER_UC_MC_BLOCKED_TLP 0x00800000 -#define PCIM_AER_UC_ATOMIC_EGRESS_BLK 0x01000000 -#define PCIM_AER_UC_TLP_PREFIX_BLOCKED 0x02000000 -#define PCIR_AER_UC_MASK 0x08 /* Shares bits with UC_STATUS */ -#define PCIR_AER_UC_SEVERITY 0x0c /* Shares bits with UC_STATUS */ -#define PCIR_AER_COR_STATUS 0x10 -#define PCIM_AER_COR_RECEIVER_ERROR 0x00000001 -#define PCIM_AER_COR_BAD_TLP 0x00000040 -#define PCIM_AER_COR_BAD_DLLP 0x00000080 -#define PCIM_AER_COR_REPLAY_ROLLOVER 0x00000100 -#define PCIM_AER_COR_REPLAY_TIMEOUT 0x00001000 -#define PCIM_AER_COR_ADVISORY_NF_ERROR 0x00002000 -#define PCIM_AER_COR_INTERNAL_ERROR 0x00004000 -#define PCIM_AER_COR_HEADER_LOG_OVFLOW 0x00008000 -#define PCIR_AER_COR_MASK 0x14 /* Shares bits with COR_STATUS */ -#define PCIR_AER_CAP_CONTROL 0x18 -#define PCIM_AER_FIRST_ERROR_PTR 0x0000001f -#define PCIM_AER_ECRC_GEN_CAPABLE 0x00000020 -#define PCIM_AER_ECRC_GEN_ENABLE 0x00000040 -#define PCIM_AER_ECRC_CHECK_CAPABLE 0x00000080 -#define PCIM_AER_ECRC_CHECK_ENABLE 0x00000100 -#define PCIM_AER_MULT_HDR_CAPABLE 0x00000200 -#define PCIM_AER_MULT_HDR_ENABLE 0x00000400 -#define PCIM_AER_TLP_PREFIX_LOG_PRESENT 0x00000800 -#define PCIR_AER_HEADER_LOG 0x1c -#define PCIR_AER_ROOTERR_CMD 0x2c /* Only for root complex ports */ -#define PCIM_AER_ROOTERR_COR_ENABLE 0x00000001 -#define PCIM_AER_ROOTERR_NF_ENABLE 0x00000002 -#define PCIM_AER_ROOTERR_F_ENABLE 0x00000004 -#define PCIR_AER_ROOTERR_STATUS 0x30 /* Only for root complex ports */ -#define PCIM_AER_ROOTERR_COR_ERR 0x00000001 -#define PCIM_AER_ROOTERR_MULTI_COR_ERR 0x00000002 -#define PCIM_AER_ROOTERR_UC_ERR 0x00000004 -#define PCIM_AER_ROOTERR_MULTI_UC_ERR 0x00000008 -#define PCIM_AER_ROOTERR_FIRST_UC_FATAL 0x00000010 -#define PCIM_AER_ROOTERR_NF_ERR 0x00000020 -#define PCIM_AER_ROOTERR_F_ERR 0x00000040 -#define PCIM_AER_ROOTERR_INT_MESSAGE 0xf8000000 -#define PCIR_AER_COR_SOURCE_ID 0x34 /* Only for root complex ports */ -#define PCIR_AER_ERR_SOURCE_ID 0x36 /* Only for root complex ports */ -#define PCIR_AER_TLP_PREFIX_LOG 0x38 /* Only for TLP prefix functions */ - -/* Virtual Channel definitions */ -#define PCIR_VC_CAP1 0x04 -#define PCIM_VC_CAP1_EXT_COUNT 0x00000007 -#define PCIM_VC_CAP1_LOWPRI_EXT_COUNT 0x00000070 -#define PCIR_VC_CAP2 0x08 -#define PCIR_VC_CONTROL 0x0c -#define PCIR_VC_STATUS 0x0e -#define PCIR_VC_RESOURCE_CAP(n) (0x10 + (n) * 0x0c) -#define PCIR_VC_RESOURCE_CTL(n) (0x14 + (n) * 0x0c) -#define PCIR_VC_RESOURCE_STA(n) (0x18 + (n) * 0x0c) - -/* Serial Number definitions */ -#define PCIR_SERIAL_LOW 0x04 -#define PCIR_SERIAL_HIGH 0x08 - -/* SR-IOV definitions */ -#define PCIR_SRIOV_CTL 0x08 -#define PCIM_SRIOV_VF_EN 0x01 -#define PCIM_SRIOV_VF_MSE 0x08 /* Memory space enable. */ -#define PCIM_SRIOV_ARI_EN 0x10 -#define PCIR_SRIOV_TOTAL_VFS 0x0e -#define PCIR_SRIOV_NUM_VFS 0x10 -#define PCIR_SRIOV_VF_OFF 0x14 -#define PCIR_SRIOV_VF_STRIDE 0x16 -#define PCIR_SRIOV_VF_DID 0x1a -#define PCIR_SRIOV_PAGE_CAP 0x1c -#define PCIR_SRIOV_PAGE_SIZE 0x20 - -#define PCI_SRIOV_BASE_PAGE_SHIFT 12 - -#define PCIR_SRIOV_BARS 0x24 -#define PCIR_SRIOV_BAR(x) (PCIR_SRIOV_BARS + (x) * 4) - -/* Extended Capability Vendor-Specific definitions */ -#define PCIR_VSEC_HEADER 0x04 -#define PCIR_VSEC_ID(hdr) ((hdr) & 0xffff) -#define PCIR_VSEC_REV(hdr) (((hdr) & 0xf0000) >> 16) -#define PCIR_VSEC_LENGTH(hdr) (((hdr) & 0xfff00000) >> 20) -#define PCIR_VSEC_DATA 0x08 - -/* ASPM L1 PM Substates */ -#define PCIR_L1SS_CAP 0x04 /* Capabilities Register */ -#define PCIM_L1SS_CAP_PCIPM_L1_2 0x00000001 /* PCI-PM L1.2 Supported */ -#define PCIM_L1SS_CAP_PCIPM_L1_1 0x00000002 /* PCI-PM L1.1 Supported */ -#define PCIM_L1SS_CAP_ASPM_L1_2 0x00000004 /* ASPM L1.2 Supported */ -#define PCIM_L1SS_CAP_ASPM_L1_1 0x00000008 /* ASPM L1.1 Supported */ -#define PCIM_L1SS_CAP_L1_PM_SS 0x00000010 /* L1 PM Substates Supported */ -#define PCIM_L1SS_CAP_CM_RESTORE_TIME 0x0000ff00 /* Port Common_Mode_Restore_Time */ -#define PCIM_L1SS_CAP_P_PWR_ON_SCALE 0x00030000 /* Port T_POWER_ON scale */ -#define PCIM_L1SS_CAP_P_PWR_ON_VALUE 0x00f80000 /* Port T_POWER_ON value */ -#define PCIR_L1SS_CTL1 0x08 /* Control 1 Register */ -#define PCIM_L1SS_CTL1_PCIPM_L1_2 0x00000001 /* PCI-PM L1.2 Enable */ -#define PCIM_L1SS_CTL1_PCIPM_L1_1 0x00000002 /* PCI-PM L1.1 Enable */ -#define PCIM_L1SS_CTL1_ASPM_L1_2 0x00000004 /* ASPM L1.2 Enable */ -#define PCIM_L1SS_CTL1_ASPM_L1_1 0x00000008 /* ASPM L1.1 Enable */ -#define PCIM_L1SS_CTL1_L1_2_MASK 0x00000005 -#define PCIM_L1SS_CTL1_L1SS_MASK 0x0000000f -#define PCIM_L1SS_CTL1_CM_RESTORE_TIME 0x0000ff00 /* Common_Mode_Restore_Time */ -#define PCIM_L1SS_CTL1_LTR_L12_TH_VALUE 0x03ff0000 /* LTR_L1.2_THRESHOLD_Value */ -#define PCIM_L1SS_CTL1_LTR_L12_TH_SCALE 0xe0000000 /* LTR_L1.2_THRESHOLD_Scale */ -#define PCIR_L1SS_CTL2 0x0c /* Control 2 Register */ -#define PCIM_L1SS_CTL2_T_PWR_ON_SCALE 0x00000003 /* T_POWER_ON Scale */ -#define PCIM_L1SS_CTL2_T_PWR_ON_VALUE 0x000000f8 /* T_POWER_ON Value */ - -/* Alternative Routing-ID Interpretation */ -#define PCIR_ARI_CAP 0x04 /* Capabilities Register */ -#define PCIM_ARI_CAP_MFVC 0x0001 /* MFVC Function Groups Capability */ -#define PCIM_ARI_CAP_ACS 0x0002 /* ACS Function Groups Capability */ -#define PCIM_ARI_CAP_NFN(x) (((x) >> 8) & 0xff) /* Next Function Number */ -#define PCIR_ARI_CTRL 0x06 /* ARI Control Register */ -#define PCIM_ARI_CTRL_MFVC 0x0001 /* MFVC Function Groups Enable */ -#define PCIM_ARI_CTRL_ACS 0x0002 /* ACS Function Groups Enable */ -#define PCIM_ARI_CTRL_FG(x) (((x) >> 4) & 7) /* Function Group */ -#define PCIR_EXT_CAP_ARI_SIZEOF 8 - -/* - * PCI Express Firmware Interface definitions - */ -#define PCI_OSC_STATUS 0 -#define PCI_OSC_SUPPORT 1 -#define PCIM_OSC_SUPPORT_EXT_PCI_CONF 0x01 /* Extended PCI Config Space */ -#define PCIM_OSC_SUPPORT_ASPM 0x02 /* Active State Power Management */ -#define PCIM_OSC_SUPPORT_CPMC 0x04 /* Clock Power Management Cap */ -#define PCIM_OSC_SUPPORT_SEG_GROUP 0x08 /* PCI Segment Groups supported */ -#define PCIM_OSC_SUPPORT_MSI 0x10 /* MSI signalling supported */ -#define PCI_OSC_CTL 2 -#define PCIM_OSC_CTL_PCIE_HP 0x01 /* PCIe Native Hot Plug */ -#define PCIM_OSC_CTL_SHPC_HP 0x02 /* SHPC Native Hot Plug */ -#define PCIM_OSC_CTL_PCIE_PME 0x04 /* PCIe Native Power Mgt Events */ -#define PCIM_OSC_CTL_PCIE_AER 0x08 /* PCIe Advanced Error Reporting */ -#define PCIM_OSC_CTL_PCIE_CAP_STRUCT 0x10 /* Various Capability Structures */ - -#endif /* __PCI_REGS_H__ */ diff --git a/rt-thread/components/drivers/pci/pme.c b/rt-thread/components/drivers/pci/pme.c deleted file mode 100644 index b4278d3..0000000 --- a/rt-thread/components/drivers/pci/pme.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#include -#include - -#define DBG_TAG "pci.pme" -#define DBG_LVL DBG_INFO -#include - -/* - * Power Management Capability Register: - * - * 31 27 26 25 24 22 21 20 19 18 16 15 8 7 0 - * +---------+---+---+--------+---+---+---+------+-----------+----------------+ - * | | | | | | | | | | Capabilitiy ID | - * +---------+---+---+--------+---+---+---+------+-----------+----------------+ - * ^ ^ ^ ^ ^ ^ ^ ^ ^ - * | | | | | | | | | - * | | | | | | | | +---- Next Capabilitiy Pointer - * | | | | | | | +------------- Version - * | | | | | | +------------------- PME Clock - * | | | | | +----------------------- Immediate Readiness on Return to D0 - * | | | | +--------------------------- Device Specifiic Initializtion - * | | | +--------------------------------- Aux Current - * | | +---------------------------------------- D1 Support - * | +-------------------------------------------- D2 Support - * +--------------------------------------------------- PME Support - */ - -void rt_pci_pme_init(struct rt_pci_device *pdev) -{ - rt_uint16_t pmc; - - if (!pdev || !(pdev->pme_cap = rt_pci_find_capability(pdev, PCIY_PMG))) - { - return; - } - - rt_pci_read_config_u16(pdev, pdev->pme_cap + PCIR_POWER_CAP, &pmc); - - if ((pmc & PCIM_PCAP_SPEC) > 3) - { - LOG_E("%s: Unsupported PME CAP regs spec %u", - rt_dm_dev_get_name(&pdev->parent), pmc & PCIM_PCAP_SPEC); - - return; - } - - pmc &= PCIM_PCAP_PMEMASK; - - if (pmc) - { - pdev->pme_support = RT_FIELD_GET(PCIM_PCAP_PMEMASK, pmc); - - rt_pci_pme_active(pdev, RT_FALSE); - } -} - -rt_err_t rt_pci_enable_wake(struct rt_pci_device *pdev, - enum rt_pci_power state, rt_bool_t enable) -{ - if (!pdev || state >= RT_PCI_PME_MAX) - { - return -RT_EINVAL; - } - - if (enable) - { - if (rt_pci_pme_capable(pdev, state) || - rt_pci_pme_capable(pdev, RT_PCI_D3COLD)) - { - rt_pci_pme_active(pdev, RT_EOK); - } - } - else - { - rt_pci_pme_active(pdev, RT_FALSE); - } - - return RT_EOK; -} - -static void pci_pme_active(struct rt_pci_device *pdev, rt_bool_t enable) -{ - rt_uint16_t pmcsr; - - if (!pdev->pme_support) - { - return; - } - - rt_pci_read_config_u16(pdev, pdev->pme_cap + PCIR_POWER_STATUS, &pmcsr); - /* Clear PME_Status by writing 1 to it and enable PME# */ - pmcsr |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE; - - if (!enable) - { - pmcsr &= ~PCIM_PSTAT_PMEENABLE; - } - - rt_pci_write_config_u16(pdev, pdev->pme_cap + PCIR_POWER_STATUS, pmcsr); -} - -void rt_pci_pme_active(struct rt_pci_device *pdev, rt_bool_t enable) -{ - if (!pdev) - { - return; - } - - pci_pme_active(pdev, enable); - rt_dm_power_domain_attach(&pdev->parent, enable); -} diff --git a/rt-thread/components/drivers/pci/probe.c b/rt-thread/components/drivers/pci/probe.c deleted file mode 100644 index fc15eaa..0000000 --- a/rt-thread/components/drivers/pci/probe.c +++ /dev/null @@ -1,926 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#include - -#define DBG_TAG "pci.probe" -#define DBG_LVL DBG_INFO -#include - -#include -#include - -rt_inline void spin_lock(struct rt_spinlock *spinlock) -{ - rt_hw_spin_lock(&spinlock->lock); -} - -rt_inline void spin_unlock(struct rt_spinlock *spinlock) -{ - rt_hw_spin_unlock(&spinlock->lock); -} - -struct rt_pci_host_bridge *rt_pci_host_bridge_alloc(rt_size_t priv_size) -{ - struct rt_pci_host_bridge *bridge = rt_calloc(1, sizeof(*bridge) + priv_size); - - return bridge; -} - -rt_err_t rt_pci_host_bridge_free(struct rt_pci_host_bridge *bridge) -{ - if (!bridge) - { - return -RT_EINVAL; - } - - if (bridge->bus_regions) - { - rt_free(bridge->bus_regions); - } - - if (bridge->dma_regions) - { - rt_free(bridge->dma_regions); - } - - rt_free(bridge); - - return RT_EOK; -} - -rt_err_t rt_pci_host_bridge_init(struct rt_pci_host_bridge *host_bridge) -{ - rt_err_t err = RT_EOK; - - if (host_bridge->parent.ofw_node) - { - err = rt_pci_ofw_host_bridge_init(host_bridge->parent.ofw_node, host_bridge); - } - - return err; -} - -struct rt_pci_device *rt_pci_alloc_device(struct rt_pci_bus *bus) -{ - struct rt_pci_device *pdev = rt_calloc(1, sizeof(*pdev)); - - if (!pdev) - { - return RT_NULL; - } - - rt_list_init(&pdev->list); - pdev->bus = bus; - - if (bus) - { - spin_lock(&bus->lock); - rt_list_insert_before(&bus->devices_nodes, &pdev->list); - spin_unlock(&bus->lock); - } - - pdev->subsystem_vendor = PCI_ANY_ID; - pdev->subsystem_device = PCI_ANY_ID; - - pdev->irq = -1; - - for (int i = 0; i < RT_ARRAY_SIZE(pdev->resource); ++i) - { - pdev->resource[i].flags = PCI_BUS_REGION_F_NONE; - } - -#ifdef RT_PCI_MSI - rt_list_init(&pdev->msi_desc_nodes); - rt_spin_lock_init(&pdev->msi_lock); -#endif - - return pdev; -} - -struct rt_pci_device *rt_pci_scan_single_device(struct rt_pci_bus *bus, rt_uint32_t devfn) -{ - rt_err_t err; - struct rt_pci_device *pdev = RT_NULL; - rt_uint16_t vendor = PCI_ANY_ID, device = PCI_ANY_ID; - - if (!bus) - { - goto _end; - } - - err = rt_pci_bus_read_config_u16(bus, devfn, PCIR_VENDOR, &vendor); - rt_pci_bus_read_config_u16(bus, devfn, PCIR_DEVICE, &device); - - if (vendor == (typeof(vendor))PCI_ANY_ID || - vendor == (typeof(vendor))0x0000 || err) - { - goto _end; - } - - if (!(pdev = rt_pci_alloc_device(bus))) - { - goto _end; - } - - pdev->devfn = devfn; - pdev->vendor = vendor; - pdev->device = device; - - rt_dm_dev_set_name(&pdev->parent, "%04x:%02x:%02x.%u", - rt_pci_domain(pdev), pdev->bus->number, - RT_PCI_SLOT(pdev->devfn), RT_PCI_FUNC(pdev->devfn)); - - if (rt_pci_setup_device(pdev)) - { - rt_free(pdev); - pdev = RT_NULL; - - goto _end; - } - - rt_pci_device_register(pdev); - -_end: - return pdev; -} - -static rt_bool_t pci_intx_mask_broken(struct rt_pci_device *pdev) -{ - rt_bool_t res = RT_FALSE; - rt_uint16_t orig, toggle, new; - - rt_pci_read_config_u16(pdev, PCIR_COMMAND, &orig); - toggle = orig ^ PCIM_CMD_INTxDIS; - rt_pci_write_config_u16(pdev, PCIR_COMMAND, toggle); - rt_pci_read_config_u16(pdev, PCIR_COMMAND, &new); - - rt_pci_write_config_u16(pdev, PCIR_COMMAND, orig); - - if (new != toggle) - { - res = RT_TRUE; - } - - return res; -} - -static void pci_read_irq(struct rt_pci_device *pdev) -{ - rt_uint8_t irq = 0; - - rt_pci_read_config_u8(pdev, PCIR_INTPIN, &irq); - pdev->pin = irq; - - if (irq) - { - rt_pci_read_config_u8(pdev, PCIR_INTLINE, &irq); - } - pdev->irq = irq; -} - -static void pcie_set_port_type(struct rt_pci_device *pdev) -{ - int pos; - - if (!(pos = rt_pci_find_capability(pdev, PCIY_EXPRESS))) - { - return; - } - - pdev->pcie_cap = pos; -} - -static void pci_configure_ari(struct rt_pci_device *pdev) -{ - rt_uint32_t cap, ctl2_ari; - struct rt_pci_device *bridge; - - if (!rt_pci_is_pcie(pdev) || pdev->devfn) - { - return; - } - - bridge = pdev->bus->self; - - if (rt_pci_is_root_bus(pdev->bus) || !bridge) - { - return; - } - - rt_pci_read_config_u32(bridge, bridge->pcie_cap + PCIER_DEVICE_CAP2, &cap); - if (!(cap & PCIEM_CAP2_ARI)) - { - return; - } - - rt_pci_read_config_u32(bridge, bridge->pcie_cap + PCIER_DEVICE_CTL2, &ctl2_ari); - - if (rt_pci_find_ext_capability(pdev, PCIZ_ARI)) - { - ctl2_ari |= PCIEM_CTL2_ARI; - bridge->ari_enabled = RT_TRUE; - } - else - { - ctl2_ari &= ~PCIEM_CTL2_ARI; - bridge->ari_enabled = RT_FALSE; - } - - rt_pci_write_config_u32(bridge, bridge->pcie_cap + PCIER_DEVICE_CTL2, ctl2_ari); -} - -static rt_uint16_t pci_cfg_space_size_ext(struct rt_pci_device *pdev) -{ - rt_uint32_t status; - - if (rt_pci_read_config_u32(pdev, PCI_REGMAX + 1, &status)) - { - return PCI_REGMAX + 1; - } - - return PCIE_REGMAX + 1; -} - -static rt_uint16_t pci_cfg_space_size(struct rt_pci_device *pdev) -{ - int pos; - rt_uint32_t status; - rt_uint16_t class = pdev->class >> 8; - - if (class == PCIS_BRIDGE_HOST) - { - return pci_cfg_space_size_ext(pdev); - } - - if (rt_pci_is_pcie(pdev)) - { - return pci_cfg_space_size_ext(pdev); - } - - pos = rt_pci_find_capability(pdev, PCIY_PCIX); - if (!pos) - { - return PCI_REGMAX + 1; - } - - rt_pci_read_config_u32(pdev, pos + PCIXR_STATUS, &status); - if (status & (PCIXM_STATUS_266CAP | PCIXM_STATUS_533CAP)) - { - return pci_cfg_space_size_ext(pdev); - } - - return PCI_REGMAX + 1; -} - -static void pci_init_capabilities(struct rt_pci_device *pdev) -{ - rt_pci_pme_init(pdev); - -#ifdef RT_PCI_MSI - rt_pci_msi_init(pdev); /* Disable MSI */ - rt_pci_msix_init(pdev); /* Disable MSI-X */ -#endif - - pcie_set_port_type(pdev); - pdev->cfg_size = pci_cfg_space_size(pdev); - pci_configure_ari(pdev); - - pdev->no_msi = RT_FALSE; - pdev->msi_enabled = RT_FALSE; - pdev->msix_enabled = RT_FALSE; -} - -rt_err_t rt_pci_setup_device(struct rt_pci_device *pdev) -{ - rt_uint8_t pos; - rt_uint32_t class = 0; - struct rt_pci_host_bridge *host_bridge; - - if (!pdev) - { - return -RT_EINVAL; - } - - if (!(host_bridge = rt_pci_find_host_bridge(pdev->bus))) - { - return -RT_EINVAL; - } - - rt_pci_ofw_device_init(pdev); - - rt_pci_read_config_u32(pdev, PCIR_REVID, &class); - - pdev->revision = class & 0xff; - pdev->class = class >> 8; /* Upper 3 bytes */ - rt_pci_read_config_u8(pdev, PCIR_HDRTYPE, &pdev->hdr_type); - - /* Clear errors left from system firmware */ - rt_pci_write_config_u16(pdev, PCIR_STATUS, 0xffff); - - if (pdev->hdr_type & 0x80) - { - pdev->multi_function = RT_TRUE; - } - pdev->hdr_type &= PCIM_HDRTYPE; - - if (pci_intx_mask_broken(pdev)) - { - pdev->broken_intx_masking = RT_TRUE; - } - - rt_dm_dev_set_name(&pdev->parent, "%04x:%02x:%02x.%u", rt_pci_domain(pdev), - pdev->bus->number, RT_PCI_SLOT(pdev->devfn), RT_PCI_FUNC(pdev->devfn)); - - switch (pdev->hdr_type) - { - case PCIM_HDRTYPE_NORMAL: - if (class == PCIS_BRIDGE_PCI) - { - goto error; - } - pci_read_irq(pdev); - rt_pci_device_alloc_resource(host_bridge, pdev); - rt_pci_read_config_u16(pdev, PCIR_SUBVEND_0, &pdev->subsystem_vendor); - rt_pci_read_config_u16(pdev, PCIR_SUBDEV_0, &pdev->subsystem_device); - break; - - case PCIM_HDRTYPE_BRIDGE: - pci_read_irq(pdev); - rt_pci_device_alloc_resource(host_bridge, pdev); - pos = rt_pci_find_capability(pdev, PCIY_SUBVENDOR); - if (pos) - { - rt_pci_read_config_u16(pdev, PCIR_SUBVENDCAP, &pdev->subsystem_vendor); - rt_pci_read_config_u16(pdev, PCIR_SUBDEVCAP, &pdev->subsystem_device); - } - break; - - case PCIM_HDRTYPE_CARDBUS: - if (class != PCIS_BRIDGE_CARDBUS) - { - goto error; - } - pci_read_irq(pdev); - rt_pci_device_alloc_resource(host_bridge, pdev); - rt_pci_read_config_u16(pdev, PCIR_SUBVEND_2, &pdev->subsystem_vendor); - rt_pci_read_config_u16(pdev, PCIR_SUBDEV_2, &pdev->subsystem_device); - break; - - default: - LOG_E("Ignoring device unknown header type %02x", pdev->hdr_type); - return -RT_EIO; - - error: - LOG_E("Ignoring class %08x (doesn't match header type %02x)", pdev->class, pdev->hdr_type); - pdev->class = PCIC_NOT_DEFINED << 8; - } - - pci_init_capabilities(pdev); - - if (rt_pci_is_pcie(pdev)) - { - rt_pci_read_config_u16(pdev, pdev->pcie_cap + PCIER_FLAGS, &pdev->exp_flags); - } - - return RT_EOK; -} - -static struct rt_pci_bus *pci_alloc_bus(struct rt_pci_bus *parent); - -static rt_err_t pci_child_bus_init(struct rt_pci_bus *bus, rt_uint32_t bus_no, - struct rt_pci_host_bridge *host_bridge, struct rt_pci_device *pdev) -{ - rt_err_t err; - struct rt_pci_bus *parent_bus = bus->parent; - - bus->sysdata = parent_bus->sysdata; - bus->self = pdev; - bus->ops = host_bridge->child_ops ? : parent_bus->ops; - - bus->number = bus_no; - rt_sprintf(bus->name, "%04x:%02x", host_bridge->domain, bus_no); - - rt_pci_ofw_bus_init(bus); - - if (bus->ops->add) - { - if ((err = bus->ops->add(bus))) - { - rt_pci_ofw_bus_free(bus); - - LOG_E("PCI-Bus<%s> add bus failed with err = %s", - bus->name, rt_strerror(err)); - - return err; - } - } - - return RT_EOK; -} - -static rt_bool_t pci_ea_fixed_busnrs(struct rt_pci_device *pdev, - rt_uint8_t *sec, rt_uint8_t *sub) -{ - int pos, offset; - rt_uint32_t dw; - rt_uint8_t ea_sec, ea_sub; - - pos = rt_pci_find_capability(pdev, PCIY_EA); - if (!pos) - { - return RT_FALSE; - } - - offset = pos + PCIR_EA_FIRST_ENT; - rt_pci_read_config_u32(pdev, offset, &dw); - ea_sec = PCIM_EA_SEC_NR(dw); - ea_sub = PCIM_EA_SUB_NR(dw); - if (ea_sec == 0 || ea_sub < ea_sec) - { - return RT_FALSE; - } - - *sec = ea_sec; - *sub = ea_sub; - - return RT_TRUE; -} - -static void pcie_fixup_link(struct rt_pci_device *pdev) -{ - int pos = pdev->pcie_cap; - rt_uint16_t exp_lnkctl, exp_lnkctl2, exp_lnksta; - rt_uint16_t exp_type = pdev->exp_flags & PCIEM_FLAGS_TYPE; - - if ((pdev->exp_flags & PCIEM_FLAGS_VERSION) < 2) - { - return; - } - - if (exp_type != PCIEM_TYPE_ROOT_PORT && - exp_type != PCIEM_TYPE_DOWNSTREAM_PORT && - exp_type != PCIEM_TYPE_PCIE_BRIDGE) - { - return; - } - - rt_pci_read_config_u16(pdev, pos + PCIER_LINK_CTL, &exp_lnkctl); - rt_pci_read_config_u16(pdev, pos + PCIER_LINK_CTL2, &exp_lnkctl2); - - rt_pci_write_config_u16(pdev, pos + PCIER_LINK_CTL2, - (exp_lnkctl2 & ~PCIEM_LNKCTL2_TLS) | PCIEM_LNKCTL2_TLS_2_5GT); - rt_pci_write_config_u16(pdev, pos + PCIER_LINK_CTL, - exp_lnkctl | PCIEM_LINK_CTL_RETRAIN_LINK); - - for (int i = 0; i < 20; ++i) - { - rt_pci_read_config_u16(pdev, pos + PCIER_LINK_STA, &exp_lnksta); - - if (!!(exp_lnksta & PCIEM_LINK_STA_DL_ACTIVE)) - { - goto _status_sync; - } - - rt_thread_mdelay(10); - } - - /* Fail, restore */ - rt_pci_write_config_u16(pdev, pos + PCIER_LINK_CTL2, exp_lnkctl2); - rt_pci_write_config_u16(pdev, pos + PCIER_LINK_CTL, - exp_lnkctl | PCIEM_LINK_CTL_RETRAIN_LINK); - -_status_sync: - /* Wait a while for success or failure */ - rt_thread_mdelay(100); -} - -static rt_uint32_t pci_scan_bridge_extend(struct rt_pci_bus *bus, struct rt_pci_device *pdev, - rt_uint32_t bus_no_start, rt_uint32_t buses, rt_bool_t reconfigured) -{ - rt_bool_t fixed_buses; - rt_uint8_t fixed_sub, fixed_sec; - rt_uint8_t primary, secondary, subordinate; - rt_uint32_t value, bus_no = bus_no_start; - struct rt_pci_bus *next_bus; - struct rt_pci_host_bridge *host_bridge; - - /* We not supported init CardBus, it always used in the PC servers. */ - if (pdev->hdr_type == PCIM_HDRTYPE_CARDBUS) - { - LOG_E("CardBus is not supported in system"); - - goto _end; - } - - rt_pci_read_config_u32(pdev, PCIR_PRIBUS_1, &value); - primary = value & 0xff; - secondary = (value >> 8) & 0xff; - subordinate = (value >> 16) & 0xff; - - if (primary == bus->number && bus->number > secondary && secondary > subordinate) - { - if (!reconfigured) - { - goto _end; - } - - LOG_I("Bridge configuration: primary(%02x) secondary(%02x) subordinate(%02x)", - primary, secondary, subordinate); - } - - if (pdev->pcie_cap) - { - pcie_fixup_link(pdev); - } - - ++bus_no; - /* Count of subordinate */ - buses -= !!buses; - - host_bridge = rt_pci_find_host_bridge(bus); - RT_ASSERT(host_bridge != RT_NULL); - - /* Clear errors */ - rt_pci_write_config_u16(pdev, PCIR_STATUS, RT_UINT16_MAX); - - fixed_buses = pci_ea_fixed_busnrs(pdev, &fixed_sec, &fixed_sub); - - if (!(next_bus = pci_alloc_bus(bus))) - { - goto _end; - } - - /* Clear bus info */ - rt_pci_write_config_u32(pdev, PCIR_PRIBUS_1, value & ~0xffffff); - - if (!(next_bus = pci_alloc_bus(bus))) - { - LOG_E("Alloc bus(%02x) fail", bus_no); - goto _end; - } - - if (pci_child_bus_init(next_bus, bus_no, host_bridge, pdev)) - { - goto _end; - } - - /* Fill primary, secondary */ - value = (buses & 0xff000000) | (bus->number << 0) | (next_bus->number << 8); - rt_pci_write_config_u32(pdev, PCIR_PRIBUS_1, value); - - bus_no = rt_pci_scan_child_buses(next_bus, buses); - - /* Fill subordinate */ - value |= next_bus->number + rt_list_len(&next_bus->children_nodes); - rt_pci_write_config_u32(pdev, PCIR_PRIBUS_1, value); - - if (fixed_buses) - { - bus_no = fixed_sub; - } - rt_pci_write_config_u8(pdev, PCIR_SUBBUS_1, bus_no); - -_end: - return bus_no; -} - -rt_uint32_t rt_pci_scan_bridge(struct rt_pci_bus *bus, struct rt_pci_device *pdev, - rt_uint32_t bus_no_start, rt_bool_t reconfigured) -{ - if (!bus || !pdev) - { - return RT_UINT32_MAX; - } - - return pci_scan_bridge_extend(bus, pdev, bus_no_start, 0, reconfigured); -} - -rt_inline rt_bool_t only_one_child(struct rt_pci_bus *bus) -{ - struct rt_pci_device *pdev; - - if (rt_pci_is_root_bus(bus)) - { - return RT_FALSE; - } - - pdev = bus->self; - - if (rt_pci_is_pcie(pdev)) - { - rt_uint16_t exp_type = pdev->exp_flags & PCIEM_FLAGS_TYPE; - - if (exp_type == PCIEM_TYPE_ROOT_PORT || - exp_type == PCIEM_TYPE_DOWNSTREAM_PORT || - exp_type == PCIEM_TYPE_PCIE_BRIDGE) - { - return RT_TRUE; - } - } - - return RT_FALSE; -} - -static int next_fn(struct rt_pci_bus *bus, struct rt_pci_device *pdev, int fn) -{ - if (!rt_pci_is_root_bus(bus) && bus->self->ari_enabled) - { - int pos, next_fn; - rt_uint16_t cap = 0; - - if (!pdev) - { - return -RT_EINVAL; - } - - pos = rt_pci_find_ext_capability(pdev, PCIZ_ARI); - - if (!pos) - { - return -RT_EINVAL; - } - - rt_pci_read_config_u16(pdev, pos + PCIR_ARI_CAP, &cap); - next_fn = PCIM_ARI_CAP_NFN(cap); - - if (next_fn <= fn) - { - return -RT_EINVAL; - } - - return next_fn; - } - - if (fn >= RT_PCI_FUNCTION_MAX - 1) - { - return -RT_EINVAL; - } - - if (pdev && !pdev->multi_function) - { - return -RT_EINVAL; - } - - return fn + 1; -} - -rt_size_t rt_pci_scan_slot(struct rt_pci_bus *bus, rt_uint32_t devfn) -{ - rt_size_t nr = 0; - struct rt_pci_device *pdev = RT_NULL; - - if (!bus) - { - return nr; - } - - if (devfn > 0 && only_one_child(bus)) - { - return nr; - } - - for (int func = 0; func >= 0; func = next_fn(bus, pdev, func)) - { - pdev = rt_pci_scan_single_device(bus, devfn + func); - - if (pdev) - { - ++nr; - - if (func > 0) - { - pdev->multi_function = RT_TRUE; - } - } - else if (func == 0) - { - break; - } - } - - return nr; -} - -rt_uint32_t rt_pci_scan_child_buses(struct rt_pci_bus *bus, rt_size_t buses) -{ - rt_uint32_t bus_no; - struct rt_pci_device *pdev = RT_NULL; - - if (!bus) - { - bus_no = RT_UINT32_MAX; - - goto _end; - } - - bus_no = bus->number; - - for (rt_uint32_t devfn = 0; - devfn < RT_PCI_DEVFN(RT_PCI_DEVICE_MAX - 1, RT_PCI_FUNCTION_MAX - 1); - devfn += RT_PCI_FUNCTION_MAX) - { - rt_pci_scan_slot(bus, devfn); - } - - rt_pci_foreach_bridge(pdev, bus) - { - int offset; - - bus_no = pci_scan_bridge_extend(bus, pdev, bus_no, buses, RT_TRUE); - offset = bus_no - bus->number; - - if (buses > offset) - { - buses -= offset; - } - else - { - break; - } - } - -_end: - return bus_no; -} - -rt_uint32_t rt_pci_scan_child_bus(struct rt_pci_bus *bus) -{ - return rt_pci_scan_child_buses(bus, 0); -} - -static struct rt_pci_bus *pci_alloc_bus(struct rt_pci_bus *parent) -{ - struct rt_pci_bus *bus = rt_calloc(1, sizeof(*bus)); - - if (!bus) - { - return RT_NULL; - } - - bus->parent = parent; - - rt_list_init(&bus->list); - rt_list_init(&bus->children_nodes); - rt_list_init(&bus->devices_nodes); - - rt_spin_lock_init(&bus->lock); - - return bus; -} - -rt_err_t rt_pci_host_bridge_register(struct rt_pci_host_bridge *host_bridge) -{ - struct rt_pci_bus *bus = pci_alloc_bus(RT_NULL); - - if (!bus) - { - return -RT_ENOMEM; - } - - host_bridge->root_bus = bus; - - bus->sysdata = host_bridge->sysdata; - bus->host_bridge = host_bridge; - bus->ops = host_bridge->ops; - - bus->number = host_bridge->bus_range[0]; - rt_sprintf(bus->name, "%04x:%02x", host_bridge->domain, bus->number); - - if (bus->ops->add) - { - rt_err_t err = bus->ops->add(bus); - - if (err) - { - LOG_E("PCI-Bus<%s> add bus failed with err = %s", bus->name, rt_strerror(err)); - } - } - - return RT_EOK; -} - -rt_err_t rt_pci_scan_root_bus_bridge(struct rt_pci_host_bridge *host_bridge) -{ - rt_err_t err; - - if ((err = rt_pci_host_bridge_register(host_bridge))) - { - return err; - } - - rt_pci_scan_child_bus(host_bridge->root_bus); - - return err; -} - -rt_err_t rt_pci_host_bridge_probe(struct rt_pci_host_bridge *host_bridge) -{ - rt_err_t err; - - err = rt_pci_scan_root_bus_bridge(host_bridge); - - return err; -} - -static rt_bool_t pci_remove_bus_device(struct rt_pci_device *pdev, void *data) -{ - /* Bus will free if this is the last device */ - rt_bus_remove_device(&pdev->parent); - - /* To find all devices, always return false */ - return RT_FALSE; -} - -rt_err_t rt_pci_host_bridge_remove(struct rt_pci_host_bridge *host_bridge) -{ - rt_err_t err = RT_EOK; - - if (host_bridge && host_bridge->root_bus) - { - rt_pci_enum_device(host_bridge->root_bus, pci_remove_bus_device, RT_NULL); - host_bridge->root_bus = RT_NULL; - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_bus_remove(struct rt_pci_bus *bus) -{ - rt_err_t err = RT_EOK; - - if (bus) - { - spin_lock(&bus->lock); - - if (rt_list_isempty(&bus->children_nodes) && - rt_list_isempty(&bus->devices_nodes)) - { - rt_list_remove(&bus->list); - spin_unlock(&bus->lock); - - if (bus->ops->remove) - { - bus->ops->remove(bus); - } - - rt_pci_ofw_bus_free(bus); - rt_free(bus); - } - else - { - spin_unlock(&bus->lock); - - err = -RT_EBUSY; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_pci_device_remove(struct rt_pci_device *pdev) -{ - rt_err_t err = RT_EOK; - - if (pdev) - { - struct rt_pci_bus *bus = pdev->bus; - - spin_lock(&bus->lock); - - while (pdev->parent.ref_count > 1) - { - spin_unlock(&bus->lock); - - rt_thread_yield(); - - spin_lock(&bus->lock); - } - rt_list_remove(&pdev->list); - - spin_unlock(&bus->lock); - - rt_free(pdev); - } - else - { - err = -RT_EINVAL; - } - - return err; -} diff --git a/rt-thread/components/drivers/phy/Kconfig b/rt-thread/components/drivers/phy/Kconfig index 92dcba8..bb88a41 100644 --- a/rt-thread/components/drivers/phy/Kconfig +++ b/rt-thread/components/drivers/phy/Kconfig @@ -1,8 +1,3 @@ config RT_USING_PHY bool "Using ethernet phy device drivers" default n - -config RT_USING_PHY_V2 - bool "Using phy device and mii bus v2" - depends on !RT_USING_PHY - default n diff --git a/rt-thread/components/drivers/phy/SConscript b/rt-thread/components/drivers/phy/SConscript index ba227c7..5b6effc 100644 --- a/rt-thread/components/drivers/phy/SConscript +++ b/rt-thread/components/drivers/phy/SConscript @@ -1,18 +1,8 @@ from building import * cwd = GetCurrentDir() -CPPPATH = [cwd, cwd + '/../include'] src = Glob('*.c') -if GetDepend('RT_USING_OFW') == False: - SrcRemove(src, ['ofw.c']) - -if GetDepend('RT_USING_PHY_V2') == False: - SrcRemove(src, ['general.c','mdio.c','ofw.c']) - -if GetDepend('RT_USING_PHY_V2') == False: - if GetDepend('RT_USING_PHY') == False: - SrcRemove(src, ['phy.c']) - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) +CPPPATH = [cwd + '/../include'] +group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_PHY'], CPPPATH = CPPPATH) Return('group') diff --git a/rt-thread/components/drivers/phy/general.c b/rt-thread/components/drivers/phy/general.c deleted file mode 100644 index 969c38c..0000000 --- a/rt-thread/components/drivers/phy/general.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-10-08 zhujiale the first version - */ -#include -#include -#include "general_phy.h" -#define DBG_TAG "rtdm.phy" -#define DBG_LVL DBG_INFO -#include - -static int __genphy_set_adv(int adv,int advertise) -{ - adv &= ~(RT_ADVERTISE_ALL | RT_ADVERTISE_100BASE4 | RT_ADVERTISE_PAUSE_CAP | - RT_ADVERTISE_PAUSE_ASYM); - if (advertise & RT_ADVERTISED__10baseT_Half) - adv |= RT_ADVERTISE_10HALF; - if (advertise & RT_ADVERTISED__10baseT_Full) - adv |= RT_ADVERTISE_10FULL; - if (advertise & RT_ADVERTISED__100baseT_Half) - adv |= RT_ADVERTISE_100HALF; - if (advertise & RT_ADVERTISED__100baseT_Full) - adv |= RT_ADVERTISE_100FULL; - if (advertise & RT_ADVERTISED__Pause) - adv |= RT_ADVERTISE_PAUSE_CAP; - if (advertise & RT_ADVERTISED__Asym_Pause) - adv |= RT_ADVERTISE_PAUSE_ASYM; - if (advertise & RT_ADVERTISED__1000baseX_Half) - adv |= RT_ADVERTISE_1000XHALF; - if (advertise & RT_ADVERTISED__1000baseX_Full) - adv |= RT_ADVERTISE_1000XFULL; - - return adv; -} -static int __genphy_config_advert(struct rt_phy_device *phydev) -{ - rt_uint32_t advertise; - int oldadv, adv, bmsr; - int err, changed = 0; - - phydev->advertising &= phydev->supported; - advertise = phydev->advertising; - - adv = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_ADVERTISE); - oldadv = adv; - - if (adv < 0) - return adv; - - adv = __genphy_set_adv(adv, advertise); - - if (adv != oldadv) - { - err = rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, RT_MII_ADVERTISE, adv); - - if (err < 0) - return err; - changed = 1; - } - - bmsr = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMSR); - if (bmsr < 0) - return bmsr; - - if (!(bmsr & RT_BMSR_ESTATEN)) - return changed; - - adv = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_CTRL1000); - oldadv = adv; - - if (adv < 0) - return adv; - - adv &= ~(RT_ADVERTISE_1000FULL | RT_ADVERTISE_1000HALF); - - if (phydev->supported & (RT_SUPPORTED_1000baseT_Half | - RT_SUPPORTED_1000baseT_Full)) - { - if (advertise & RT_SUPPORTED_1000baseT_Half) - adv |= RT_ADVERTISE_1000HALF; - if (advertise & RT_SUPPORTED_1000baseT_Full) - adv |= RT_ADVERTISE_1000FULL; - } - - if (adv != oldadv) - changed = 1; - - err = rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, RT_MII_CTRL1000, adv); - if (err < 0) - return err; - - return changed; -} - -int __genphy_restart_aneg(struct rt_phy_device *phydev) -{ - int ctl; - - ctl = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMCR); - - if (ctl < 0) - return ctl; - - ctl |= (RT_BMCR_ANENABLE | RT_BMCR_ANRESTART); - - ctl &= ~(RT_BMCR_ISOLATE); - - ctl = rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMCR, ctl); - - return ctl; -} - -int rt_genphy_config_aneg(struct rt_phy_device *phydev) -{ - int result; - int err; - int ctl = RT_BMCR_ANRESTART; - if (phydev->autoneg != AUTONEG_ENABLE) - { - phydev->pause = 0; - - if (phydev->speed == SPEED_1000) - ctl |= RT_BMCR_SPEED1000; - else if (phydev->speed == SPEED_100) - ctl |= RT_BMCR_SPEED100; - - if (phydev->duplex == DUPLEX_FULL) - ctl |= RT_BMCR_FULLDPLX; - - err = rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMCR, ctl); - - return err; - } - - result = __genphy_config_advert(phydev); - - if (result < 0) - return result; - - if (result == 0) - { - int ctl = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMCR); - - if (ctl < 0) - return ctl; - - if (!(ctl & RT_BMCR_ANENABLE) || (ctl & RT_BMCR_ISOLATE)) - result = 1; - } - - if (result > 0) - result = __genphy_restart_aneg(phydev); - - return result; -} - -int rt_genphy_update_link(struct rt_phy_device *phydev) -{ - unsigned int mii_reg; - - mii_reg = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMSR); - - if (phydev->link && mii_reg & RT_BMSR_LSTATUS) - return 0; - - if ((phydev->autoneg == AUTONEG_ENABLE) && - !(mii_reg & RT_BMSR_ANEGCOMPLETE)) - { - int i = 0; - rt_kprintf("Waiting for PHY auto negotiation to complete"); - while (!(mii_reg & RT_BMSR_ANEGCOMPLETE)) - { - - if (i > (RT_PHY_ANEG_TIMEOUT)) - { - LOG_E(" TIMEOUT !\n"); - phydev->link = 0; - return -ETIMEDOUT; - } - - mii_reg = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMSR); - - rt_thread_delay(100); - } - LOG_D(" done\n"); - phydev->link = 1; - } else { - mii_reg = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMSR); - - if (mii_reg & RT_BMSR_LSTATUS) - phydev->link = 1; - else - phydev->link = 0; - } - - return 0; -} - -static void __genphy_auto_neg(struct rt_phy_device *phydev,int mii_reg) -{ - rt_uint32_t lpa = 0; - int gblpa = 0; - rt_uint32_t estatus = 0; - - if (phydev->supported & (RT_SUPPORTED_1000baseT_Full | - RT_SUPPORTED_1000baseT_Half)) - { - - gblpa = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_STAT1000); - if (gblpa < 0) - { - LOG_D("Could not read RT_MII_STAT1000. Ignoring gigabit capability\n"); - gblpa = 0; - } - gblpa &= rt_phy_read(phydev, - RT_MDIO_DEVAD_NONE, RT_MII_CTRL1000) << 2; - } - - phydev->speed = SPEED_10; - phydev->duplex = DUPLEX_HALF; - - if (gblpa & (RT_PHY_1000BTSR_1000FD | RT_PHY_1000BTSR_1000HD)) - { - phydev->speed = SPEED_1000; - - if (gblpa & RT_PHY_1000BTSR_1000FD) - phydev->duplex = DUPLEX_FULL; - - return ; - } - - lpa = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_ADVERTISE); - lpa &= rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_LPA); - - if (lpa & (RT_LINK_PARTNER__100FULL | RT_LINK_PARTNER__100HALF)) - { - phydev->speed = SPEED_100; - - if (lpa & RT_LINK_PARTNER__100FULL) - phydev->duplex = DUPLEX_FULL; - - } else if (lpa & RT_LINK_PARTNER__10FULL) - { - phydev->duplex = DUPLEX_FULL; - } - - if ((mii_reg & RT_BMSR_ESTATEN) && !(mii_reg & RT_BMSR_ERCAP)) - estatus = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, - RT_MII_ESTATUS); - - if (estatus & (RT_SUPORT_1000B_XFULL | RT_SUPORT_1000B_XHALF | - RT_SUPORT_1000B_TFULL | RT_SUPORT_1000B_THALF)) - { - phydev->speed = SPEED_1000; - if (estatus & (RT_SUPORT_1000B_XFULL | RT_SUPORT_1000B_TFULL)) - phydev->duplex = DUPLEX_FULL; - } -} -int rt_genphy_parse_link(struct rt_phy_device *phydev) -{ - int mii_reg = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMSR); - - if (phydev->autoneg == AUTONEG_ENABLE) - { - __genphy_auto_neg(phydev, mii_reg); - } else { - rt_uint32_t bmcr = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMCR); - - phydev->speed = SPEED_10; - phydev->duplex = DUPLEX_HALF; - - if (bmcr & RT_BMCR_FULLDPLX) - phydev->duplex = DUPLEX_FULL; - - if (bmcr & RT_BMCR_SPEED1000) - phydev->speed = SPEED_1000; - else if (bmcr & RT_BMCR_SPEED100) - phydev->speed = SPEED_100; - } - - return 0; -} - -int rt_genphy_config(struct rt_phy_device *phydev) -{ - int val; - rt_uint32_t features; - - features = (RT_SUPPORTED_TP | RT_SUPPORTED_MII - | RT_SUPPORTED_AUI | RT_SUPPORTED_FIBRE | - RT_SUPPORTED_BNC); - - val = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_BMSR); - - if (val < 0) - return val; - - if (val & RT_BMSR_ANEGCAPABLE) - features |= RT_SUPPORTED_Autoneg; - - if (val & RT_BMSR_100FULL) - features |= RT_SUPPORTED_100baseT_Full; - if (val & RT_BMSR_100HALF) - features |= RT_SUPPORTED_100baseT_Half; - if (val & RT_BMSR_10FULL) - features |= RT_SUPPORTED_10baseT_Full; - if (val & RT_BMSR_10HALF) - features |= RT_SUPPORTED_10baseT_Half; - - if (val & RT_BMSR_ESTATEN) - { - val = rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_ESTATUS); - - if (val < 0) - return val; - - if (val & RT_SUPORT_1000B_TFULL) - features |= RT_SUPPORTED_1000baseT_Full; - if (val & RT_SUPORT_1000B_THALF) - features |= RT_SUPPORTED_1000baseT_Half; - if (val & RT_SUPORT_1000B_XFULL) - features |= RT_SUPPORTED_1000baseX_Full; - if (val & RT_SUPORT_1000B_XHALF) - features |= RT_SUPPORTED_1000baseX_Half; - } - - phydev->supported &= features; - phydev->advertising &= features; - - rt_genphy_config_aneg(phydev); - - return 0; -} - -int rt_genphy_startup(struct rt_phy_device *phydev) -{ - int ret; - - ret = rt_genphy_update_link(phydev); - if (ret) - return ret; - - return rt_genphy_parse_link(phydev); -} diff --git a/rt-thread/components/drivers/phy/general_phy.h b/rt-thread/components/drivers/phy/general_phy.h deleted file mode 100644 index 37acb3e..0000000 --- a/rt-thread/components/drivers/phy/general_phy.h +++ /dev/null @@ -1,143 +0,0 @@ - -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-10-08 zhujiale the first version - */ -#ifndef __PHY_GENERAL_H__ -#define __PHY_GENERAL_H__ -/* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */ -#define SPEED_10 10 -#define SPEED_100 100 -#define SPEED_1000 1000 -#define SPEED_2500 2500 -#define SPEED_10000 10000 -/* Advertisement control register. */ -#define RT_ADVERTISE_SLCT 0x001f /* Selector bits */ -#define RT_ADVERTISE_CSMA 0x0001 /* Only selector supported */ -#define RT_ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ -#define RT_ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */ -#define RT_ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ -#define RT_ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */ -#define RT_ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ -#define RT_ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */ -#define RT_ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ -#define RT_ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */ -#define RT_ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */ -#define RT_ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */ -#define RT_ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */ -#define RT_ADVERTISE_RESV 0x1000 /* Unused... */ -#define RT_ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */ -#define RT_ADVERTISE_LPACK 0x4000 /* Ack link partners response */ -#define RT_ADVERTISE_NPAGE 0x8000 /* Next page bit */ - -#define RT_ADVERTISE_FULL (RT_ADVERTISE_100FULL | RT_ADVERTISE_10FULL | \ - RT_ADVERTISE_CSMA) -#define RT_ADVERTISE_ALL (RT_ADVERTISE_10HALF | RT_ADVERTISE_10FULL | \ - RT_ADVERTISE_100HALF | RT_ADVERTISE_100FULL) - -/* Indicates what features are advertised by the interface. */ -#define RT_ADVERTISED__10baseT_Half (1 << 0) -#define RT_ADVERTISED__10baseT_Full (1 << 1) -#define RT_ADVERTISED__100baseT_Half (1 << 2) -#define RT_ADVERTISED__100baseT_Full (1 << 3) -#define RT_ADVERTISED__1000baseT_Half (1 << 4) -#define RT_ADVERTISED__1000baseT_Full (1 << 5) -#define RT_ADVERTISED__Autoneg (1 << 6) -#define RT_ADVERTISED__TP (1 << 7) -#define RT_ADVERTISED__AUI (1 << 8) -#define RT_ADVERTISED__MII (1 << 9) -#define RT_ADVERTISED__FIBRE (1 << 10) -#define RT_ADVERTISED__BNC (1 << 11) -#define RT_ADVERTISED__10000baseT_Full (1 << 12) -#define RT_ADVERTISED__Pause (1 << 13) -#define RT_ADVERTISED__Asym_Pause (1 << 14) -#define RT_ADVERTISED__2500baseX_Full (1 << 15) -#define RT_ADVERTISED__Backplane (1 << 16) -#define RT_ADVERTISED__1000baseKX_Full (1 << 17) -#define RT_ADVERTISED__10000baseKX4_Full (1 << 18) -#define RT_ADVERTISED__10000baseKR_Full (1 << 19) -#define RT_ADVERTISED__10000baseR_FEC (1 << 20) -#define RT_ADVERTISED__1000baseX_Half (1 << 21) -#define RT_ADVERTISED__1000baseX_Full (1 << 22) - -/* Basic mode status register. */ -#define RT_BMSR_ERCAP 0x0001 /* Ext-reg capability */ -#define RT_BMSR_JCD 0x0002 /* Jabber detected */ -#define RT_BMSR_LSTATUS 0x0004 /* Link status */ -#define RT_BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ -#define RT_BMSR_RFAULT 0x0010 /* Remote fault detected */ -#define RT_BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ -#define RT_BMSR_RESV 0x00c0 /* Unused... */ -#define RT_BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ -#define RT_BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */ -#define RT_BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */ -#define RT_BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ -#define RT_BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ -#define RT_BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ -#define RT_BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ -#define RT_BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ -/* 1000BASE-T Control register */ -#define RT_ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ -#define RT_ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ -#define CTL1000_AS_MASTER 0x0800 -#define CTL1000_ENABLE_MASTER 0x1000 - -/* Duplex, half or full. */ -#define DUPLEX_HALF 0x00 -#define DUPLEX_FULL 0x01 - -#define AUTONEG_DISABLE 0x00 -#define AUTONEG_ENABLE 0x01 -#define RT_PHY_1000BTSR_MSCF 0x8000 -#define RT_PHY_1000BTSR_MSCR 0x4000 -#define RT_PHY_1000BTSR_LRS 0x2000 -#define RT_PHY_1000BTSR_RRS 0x1000 -#define RT_PHY_1000BTSR_1000FD 0x0800 -#define RT_PHY_1000BTSR_1000HD 0x0400 - -/* Link partner ability register. */ -#define RT_LINK_PARTNER__SLCT 0x001f /* Same as advertise selector */ -#define RT_LINK_PARTNER__10HALF 0x0020 /* Can do 10mbps half-duplex */ -#define RT_LINK_PARTNER__1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */ -#define RT_LINK_PARTNER__10FULL 0x0040 /* Can do 10mbps full-duplex */ -#define RT_LINK_PARTNER__1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */ -#define RT_LINK_PARTNER__100HALF 0x0080 /* Can do 100mbps half-duplex */ -#define RT_LINK_PARTNER__1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */ -#define RT_LINK_PARTNER__100FULL 0x0100 /* Can do 100mbps full-duplex */ -#define RT_LINK_PARTNER__1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/ -#define RT_LINK_PARTNER__100BASE4 0x0200 /* Can do 100mbps 4k packets */ -#define RT_LINK_PARTNER__PAUSE_CAP 0x0400 /* Can pause */ -#define RT_LINK_PARTNER__PAUSE_ASYM 0x0800 /* Can pause asymetrically */ -#define RT_LINK_PARTNER__RESV 0x1000 /* Unused... */ -#define RT_LINK_PARTNER__RFAULT 0x2000 /* Link partner faulted */ -#define RT_LINK_PARTNER__LPACK 0x4000 /* Link partner acked us */ -#define RT_LINK_PARTNER__NPAGE 0x8000 /* Next page bit */ - -#define RT_LINK_PARTNER__DUPLEX (RT_LINK_PARTNER__10FULL | RT_LINK_PARTNER__100FULL) -#define RT_LINK_PARTNER__100 (RT_LINK_PARTNER__100FULL | RT_LINK_PARTNER__100HALF | RT_LINK_PARTNER__100BASE4) -/* Expansion register for auto-negotiation. */ -#define RT_EXPANSION_REG_NWAY 0x0001 /* Can do N-way auto-nego */ -#define RT_EXPANSION_REG_LCWP 0x0002 /* Got new RX page code word */ -#define RT_EXPANSION_REG_ENABLENPAGE 0x0004 /* This enables npage words */ -#define RT_EXPANSION_REG_NPCAPABLE 0x0008 /* Link partner supports npage */ -#define RT_EXPANSION_REG_MFAULTS 0x0010 /* Multiple faults detected */ -#define RT_EXPANSION_REG_RESV 0xffe0 /* Unused... */ - -#define RT_SUPORT_1000B_XFULL 0x8000 /* Can do 1000BX Full */ -#define RT_SUPORT_1000B_XHALF 0x4000 /* Can do 1000BX Half */ -#define RT_SUPORT_1000B_TFULL 0x2000 /* Can do 1000BT Full */ -#define RT_SUPORT_1000B_THALF 0x1000 /* Can do 1000BT Half */ -#define RT_PHY_ANEG_TIMEOUT 4000 -struct rt_phy_device; - -int rt_genphy_parse_link(struct rt_phy_device *phydev); -int rt_genphy_config_aneg(struct rt_phy_device *phydev); -int rt_genphy_update_link(struct rt_phy_device *phydev); -int rt_genphy_startup(struct rt_phy_device *phydev); -int rt_genphy_config(struct rt_phy_device *phydev); -#endif diff --git a/rt-thread/components/drivers/phy/mdio.c b/rt-thread/components/drivers/phy/mdio.c deleted file mode 100644 index 7f9be35..0000000 --- a/rt-thread/components/drivers/phy/mdio.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-10-08 zhujiale the first version - */ -#include "mdio.h" - -static struct rt_list_node mdio_list; - -struct mii_bus *rt_mdio_get_bus_by_name(const char *busname) -{ - struct rt_list_node *entry; - struct mii_bus *bus; - - if (!busname) - { - rt_kprintf("NULL bus name!\n"); - return RT_NULL; - } - - rt_list_for_each(entry, &mdio_list) - { - bus = rt_container_of(entry, struct mii_bus, node); - if (!strcmp(bus->name, busname)) - return bus; - } - - return RT_NULL; -} - -struct mii_bus *rt_mdio_alloc(void) -{ - struct mii_bus *mii; - mii = rt_malloc(sizeof(struct mii_bus)); - if (!mii) - return RT_NULL; - - rt_list_init(&mii->node); - return mii; -} - -rt_err_t rt_mdio_register(struct mii_bus *bus) -{ - if (!bus) - return -RT_ERROR; - - if(rt_mdio_get_bus_by_name(bus->name)) - { - rt_kprintf("mdio bus %s already exist!\n", bus->name); - return -RT_ERROR; - } - - rt_list_insert_before(&mdio_list, &bus->node); - return RT_EOK; -} - -rt_err_t rt_mdio_unregister(struct mii_bus *bus) -{ - if (!bus) - return -RT_ERROR; - - rt_list_remove(&bus->node); - return RT_EOK; -} - -static int mdio_init(void) -{ - rt_list_init(&mdio_list); - return 0; -} -INIT_CORE_EXPORT(mdio_init); diff --git a/rt-thread/components/drivers/phy/mdio.h b/rt-thread/components/drivers/phy/mdio.h deleted file mode 100644 index 89e98d4..0000000 --- a/rt-thread/components/drivers/phy/mdio.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-10-08 zhujiale the first version - */ -#ifndef __PHY_MDIO_H__ -#define __PHY_MDIO_H__ -#include -#include - -#define RT_MDIO_DEVAD_NONE (-1) -#define RT_MDIO_MMD_PMAPMD 1 /* Physical Medium Attachment/ - * Physical Medium Dependent */ -#define RT_MDIO_MMD_WIS 2 /* WAN Interface Sublayer */ -#define RT_MDIO_MMD_PCS 3 /* Physical Coding Sublayer */ -#define RT_MDIO_MMD_PHYXS 4 /* PHY Extender Sublayer */ -#define RT_MDIO_MMD_DTEXS 5 /* DTE Extender Sublayer */ -#define RT_MDIO_MMD_TC 6 /* Transmission Convergence */ -#define RT_MDIO_MMD_AN 7 /* Auto-Negotiation */ -#define RT_MDIO_MMD_C22EXT 29 /* Clause 22 extension */ -#define RT_MDIO_MMD_VEND1 30 /* Vendor specific 1 */ -#define RT_MDIO_MMD_VEND2 31 /* Vendor specific 2 */ - -#define RT_MII_BMCR 0x00 /* Basic mode control register */ -#define RT_MII_BMSR 0x01 /* Basic mode status register */ -#define RT_MII_PHYSID1 0x02 /* PHYS ID 1 */ -#define RT_MII_PHYSID2 0x03 /* PHYS ID 2 */ -#define RT_MII_ADVERTISE 0x04 /* Advertisement control reg */ -#define RT_MII_LPA 0x05 /* Link partner ability reg */ -#define RT_MII_EXPANSION 0x06 /* Expansion register */ -#define RT_MII_CTRL1000 0x09 /* 1000BASE-T control */ -#define RT_MII_STAT1000 0x0a /* 1000BASE-T status */ -#define RT_MII_MMD_CTRL 0x0d /* MMD Access Control Register */ -#define RT_MII_MMD_DATA 0x0e /* MMD Access Data Register */ -#define RT_MII_ESTATUS 0x0f /* Extended Status */ -#define RT_MII_DCOUNTER 0x12 /* Disconnect counter */ -#define RT_MII_FCSCOUNTER 0x13 /* False carrier counter */ -#define RT_MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ -#define RT_MII_RERRCOUNTER 0x15 /* Receive error counter */ -#define RT_MII_SREVISION 0x16 /* Silicon revision */ -#define RT_MII_RESV1 0x17 /* Reserved... */ -#define RT_MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ -#define RT_MII_PHYADDR 0x19 /* PHY address */ -#define RT_MII_RESV2 0x1a /* Reserved... */ -#define RT_MII_TPISTATUS 0x1b /* TPI status for 10mbps */ -#define RT_MII_NCONFIG 0x1c /* Network interface config */ - -/* Basic mode control register. */ -#define RT_BMCR_RESV 0x003f /* Unused... */ -#define RT_BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ -#define RT_BMCR_CTST 0x0080 /* Collision test */ -#define RT_BMCR_FULLDPLX 0x0100 /* Full duplex */ -#define RT_BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ -#define RT_BMCR_ISOLATE 0x0400 /* Isolate data paths from MII */ -#define RT_BMCR_PDOWN 0x0800 /* Enable low power state */ -#define RT_BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ -#define RT_BMCR_SPEED100 0x2000 /* Select 100Mbps */ -#define RT_BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ -#define RT_BMCR_RESET 0x8000 /* Reset to default state */ -#define RT_BMCR_SPEED10 0x0000 /* Select 10Mbps */ - -#define RT_MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/ -#define RT_MII_MMD_CTRL_ADDR 0x0000 /* Address */ -#define RT_MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */ -#define RT_MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */ -#define RT_MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */ - - -#define RT_PHY_MAX 32 - -struct mii_bus -{ - struct rt_list_node node; - char name[RT_NAME_MAX]; - void* priv; - int (*read)(struct mii_bus* bus, int addr, int devad, int reg); - int (*write)(struct mii_bus* bus, int addr, int devad, int reg, rt_uint16_t val); - /** @read_c45: Perform a C45 read transfer on the bus */ - int (*read_c45)(struct mii_bus* bus, int addr, int devad, int reg); - /** @write_c45: Perform a C45 write transfer on the bus */ - int (*write_c45)(struct mii_bus* bus, int addr, int devad, int reg, rt_uint16_t val); - int (*reset)(struct mii_bus* bus); - struct rt_phy_device* phymap[RT_PHY_MAX]; - rt_uint32_t phy_mask; - int reset_delay_us; - int reset_post_delay_us; -}; - -rt_err_t rt_mdio_register(struct mii_bus* bus); -rt_err_t rt_mdio_unregister(struct mii_bus* bus); - -struct mii_bus* rt_mdio_get_bus_by_name(const char* busname); -struct mii_bus* rt_mdio_alloc(void); -#endif diff --git a/rt-thread/components/drivers/phy/ofw.c b/rt-thread/components/drivers/phy/ofw.c deleted file mode 100644 index 316bbc2..0000000 --- a/rt-thread/components/drivers/phy/ofw.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-09-25 zhujiale the first version - */ -#include -#include -#include -#define DBG_TAG "rtdm.phy" -#define DBG_LVL DBG_INFO -#include -#include "ofw.h" - -static const char* const rt_phy_modes[] = -{ - [RT_PHY_INTERFACE_MODE_NA] = "", - [RT_PHY_INTERFACE_MODE_INTERNAL] = "internal", - [RT_PHY_INTERFACE_MODE_MII] = "mii", - [RT_PHY_INTERFACE_MODE_GMII] = "gmii", - [RT_PHY_INTERFACE_MODE_SGMII] = "sgmii", - [RT_PHY_INTERFACE_MODE_TBI] = "tbi", - [RT_PHY_INTERFACE_MODE_REVMII] = "rev-mii", - [RT_PHY_INTERFACE_MODE_RMII] = "rmii", - [RT_PHY_INTERFACE_MODE_REVRMII] = "rev-rmii", - [RT_PHY_INTERFACE_MODE_RGMII] = "rgmii", - [RT_PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id", - [RT_PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid", - [RT_PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid", - [RT_PHY_INTERFACE_MODE_RTBI] = "rtbi", - [RT_PHY_INTERFACE_MODE_SMII] = "smii", - [RT_PHY_INTERFACE_MODE_XGMII] = "xgmii", - [RT_PHY_INTERFACE_MODE_XLGMII] = "xlgmii", - [RT_PHY_INTERFACE_MODE_MOCA] = "moca", - [RT_PHY_INTERFACE_MODE_PSGMII] = "psgmii", - [RT_PHY_INTERFACE_MODE_QSGMII] = "qsgmii", - [RT_PHY_INTERFACE_MODE_TRGMII] = "trgmii", - [RT_PHY_INTERFACE_MODE_1000BASEX] = "1000base-x", - [RT_PHY_INTERFACE_MODE_1000BASEKX] = "1000base-kx", - [RT_PHY_INTERFACE_MODE_2500BASEX] = "2500base-x", - [RT_PHY_INTERFACE_MODE_5GBASER] = "5gbase-r", - [RT_PHY_INTERFACE_MODE_RXAUI] = "rxaui", - [RT_PHY_INTERFACE_MODE_XAUI] = "xaui", - [RT_PHY_INTERFACE_MODE_10GBASER] = "10gbase-r", - [RT_PHY_INTERFACE_MODE_25GBASER] = "25gbase-r", - [RT_PHY_INTERFACE_MODE_USXGMII] = "usxgmii", - [RT_PHY_INTERFACE_MODE_10GKR] = "10gbase-kr", - [RT_PHY_INTERFACE_MODE_100BASEX] = "100base-x", - [RT_PHY_INTERFACE_MODE_QUSGMII] = "qusgmii", - [RT_PHY_INTERFACE_MODE_MAX] = "", -}; - -static rt_err_t _get_interface_by_name(const char *name, rt_phy_interface *interface) -{ - for (int i = 0; i < RT_PHY_INTERFACE_MODE_MAX; i++) - { - if (!strcmp(name, rt_phy_modes[i])) - { - *interface = i; - return RT_EOK; - } - } - return -RT_ERROR; -} - -rt_err_t rt_ofw_get_interface(struct rt_ofw_node *np, rt_phy_interface *interface) -{ - const char *phy_mode = RT_NULL; - - if (rt_ofw_prop_read_string(np, "phy-mode", &phy_mode)) - rt_ofw_prop_read_string(np, "phy-connection-type", &phy_mode); - if (!phy_mode) - return -RT_ERROR; - - return _get_interface_by_name(phy_mode, interface); -} - -rt_err_t rt_ofw_get_mac_addr_by_name(struct rt_ofw_node *np, const char *name, rt_uint8_t *addr) -{ - rt_ssize_t len; - const void *p; - p = rt_ofw_prop_read_raw(np, name, &len); - if (p) - { - rt_memcpy(addr, p, len); - return RT_EOK; - } - - return -RT_ERROR; -} - -rt_err_t rt_ofw_get_mac_addr(struct rt_ofw_node *np, rt_uint8_t *addr) -{ - if (!rt_ofw_get_mac_addr_by_name(np, "mac-address", addr)) - return RT_EOK; - - if (!rt_ofw_get_mac_addr_by_name(np, "local-mac-address", addr)) - return RT_EOK; - - if (!rt_ofw_get_mac_addr_by_name(np, "address", addr)) - return RT_EOK; - - return -RT_ERROR; -} - -rt_err_t rt_ofw_get_phyid(struct rt_ofw_node *np,rt_uint32_t *id) -{ - const char *phy_id; - unsigned int upper, lower; - int ret; - - ret = rt_ofw_prop_read_string(np,"compatible",&phy_id); - if (ret) - return ret; - - ret = rt_sscanf(phy_id,"ethernet-phy-id%4x.%4x",&upper, &lower); - if(ret != 2) - return -RT_ERROR; - - *id = ((upper & 0xffff) << 16) | (lower & 0xffff); - return RT_EOK; - -} -struct rt_phy_device *rt_ofw_create_phy(struct mii_bus *bus,struct rt_ofw_node *np,int phyaddr) -{ - struct rt_phy_device *dev = RT_NULL; - struct rt_ofw_node *phy_node; - int ret; - rt_uint32_t id = 0xffff; - - phy_node = rt_ofw_parse_phandle(np, "phy-handle", 0); - if (!phy_node) - { - LOG_D("Failed to find phy-handle"); - return RT_NULL; - } - - ret = rt_ofw_get_phyid(np, &id); - if (ret) - { - LOG_D("Failed to read eth PHY id, err: %d\n", ret); - return RT_NULL; - } - - LOG_D("Found a PHY id: 0x%x\n", id); - - dev = rt_phy_device_create(bus, phyaddr, id, RT_FALSE); - - if(dev) - dev->node = phy_node; - - return dev; -} diff --git a/rt-thread/components/drivers/phy/ofw.h b/rt-thread/components/drivers/phy/ofw.h deleted file mode 100644 index d846aa4..0000000 --- a/rt-thread/components/drivers/phy/ofw.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-09-25 zhujiale the first version - */ -#ifndef __NET_OFW_H__ -#define __NET_OFW_H__ -#include -#include -typedef enum -{ - RT_PHY_INTERFACE_MODE_NA, - RT_PHY_INTERFACE_MODE_INTERNAL, - RT_PHY_INTERFACE_MODE_MII, - RT_PHY_INTERFACE_MODE_GMII, - RT_PHY_INTERFACE_MODE_SGMII, - RT_PHY_INTERFACE_MODE_TBI, - RT_PHY_INTERFACE_MODE_REVMII, - RT_PHY_INTERFACE_MODE_RMII, - RT_PHY_INTERFACE_MODE_REVRMII, - RT_PHY_INTERFACE_MODE_RGMII, - RT_PHY_INTERFACE_MODE_RGMII_ID, - RT_PHY_INTERFACE_MODE_RGMII_RXID, - RT_PHY_INTERFACE_MODE_RGMII_TXID, - RT_PHY_INTERFACE_MODE_RTBI, - RT_PHY_INTERFACE_MODE_SMII, - RT_PHY_INTERFACE_MODE_XGMII, - RT_PHY_INTERFACE_MODE_XLGMII, - RT_PHY_INTERFACE_MODE_MOCA, - RT_PHY_INTERFACE_MODE_PSGMII, - RT_PHY_INTERFACE_MODE_QSGMII, - RT_PHY_INTERFACE_MODE_TRGMII, - RT_PHY_INTERFACE_MODE_100BASEX, - RT_PHY_INTERFACE_MODE_1000BASEX, - RT_PHY_INTERFACE_MODE_2500BASEX, - RT_PHY_INTERFACE_MODE_5GBASER, - RT_PHY_INTERFACE_MODE_RXAUI, - RT_PHY_INTERFACE_MODE_XAUI, - /* 10GBASE-R, XFI, SFI - single lane 10G Serdes */ - RT_PHY_INTERFACE_MODE_10GBASER, - RT_PHY_INTERFACE_MODE_25GBASER, - RT_PHY_INTERFACE_MODE_USXGMII, - /* 10GBASE-KR - with Clause 73 AN */ - RT_PHY_INTERFACE_MODE_10GKR, - RT_PHY_INTERFACE_MODE_QUSGMII, - RT_PHY_INTERFACE_MODE_1000BASEKX, - RT_PHY_INTERFACE_MODE_MAX, -} rt_phy_interface; - -rt_err_t rt_ofw_get_mac_addr(struct rt_ofw_node *np, rt_uint8_t *addr); -rt_err_t rt_ofw_get_mac_addr_by_name(struct rt_ofw_node *np, const char *name, rt_uint8_t *addr); -rt_err_t rt_ofw_get_interface(struct rt_ofw_node *np, rt_phy_interface *interface); - -#endif diff --git a/rt-thread/components/drivers/phy/phy.c b/rt-thread/components/drivers/phy/phy.c index 47c35c2..363b483 100644 --- a/rt-thread/components/drivers/phy/phy.c +++ b/rt-thread/components/drivers/phy/phy.c @@ -1,21 +1,22 @@ + /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: - * Date Author Notes - * 2020-09-27 wangqiang first version - * 2024-10-08 zhujiale add phy v2.0 + * Date Author Notes + * 2020-09-27 wangqiang first version */ #include #include +#include #include -#define DBG_TAG "rtdm.phy" + +#define DBG_TAG "PHY" #define DBG_LVL DBG_INFO #include -#ifdef RT_USING_PHY static rt_ssize_t phy_device_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t count) { @@ -73,503 +74,3 @@ rt_err_t rt_hw_phy_register(struct rt_phy_device *phy, const char *name) return ret; } -#endif - -#ifdef RT_USING_PHY_V2 -int rt_phy_set_supported(struct rt_phy_device *phydev, rt_uint32_t max_speed) -{ - phydev->supported &= RT_PHY_DEFAULT_FEATURES; - - switch (max_speed) - { - default: - return -ENOTSUP; - case SPEED_1000: - phydev->supported |= RT_PHY_1000BT_FEATURES; - case SPEED_100: - phydev->supported |= RT_PHY_100BT_FEATURES; - case SPEED_10: - phydev->supported |= RT_PHY_10BT_FEATURES; - } - - return 0; -} - -int rt_phy_read(struct rt_phy_device *phydev, int devad, int regnum) -{ - struct mii_bus *bus = phydev->bus; - if(phydev->is_c45) - { - if(bus->read_c45) - return bus->read_c45(bus, phydev->addr, devad, regnum); - } - - if( bus && bus->read ) - return bus->read(bus, phydev->addr, devad, regnum); - - LOG_D("no read function\n"); - return -1; -} - -int rt_phy_write(struct rt_phy_device *phydev, int devad, int regnum, rt_uint16_t val) -{ - struct mii_bus *bus = phydev->bus; - if(phydev->is_c45) - { - if(bus->write_c45) - return bus->write_c45(bus, phydev->addr, devad, regnum, val); - } - if( bus && bus->write ) - return bus->write(bus, phydev->addr, devad, regnum, val); - - LOG_D("no write function\n"); - return -1; -} - -int rt_phy_startup(struct rt_phy_device *phydev) -{ - if(!phydev->drv) - { - LOG_D("PHY device hace no driver\n"); - return -1; - } - - if (phydev->drv->startup) - return phydev->drv->startup(phydev); - - LOG_D("phy startup err\n"); - return -1; -} - -int rt_phy_config(struct rt_phy_device *phydev) -{ - if(!phydev->drv) - { - LOG_D("PHY device hace no driver\n"); - return -1; - } - - if (phydev->drv->config) - return phydev->drv->config(phydev); - - LOG_D("no config function\n"); - return -1; -} - -int rt_phy_shutdown(struct rt_phy_device *phydev) -{ - if(!phydev->drv) - { - LOG_D("PHY device hace no driver\n"); - return -1; - } - - if (phydev->drv->shutdown) - phydev->drv->shutdown(phydev); - - LOG_D("no shutdown function\n"); - return -1; -} - -void rt_phy_mmd_start_indirect(struct rt_phy_device *phydev, int devad, int regnum) -{ - /* Write the desired MMD Devad */ - rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, RT_MII_MMD_CTRL, devad); - - /* Write the desired MMD register address */ - rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, RT_MII_MMD_DATA, regnum); - - /* Select the Function : DATA with no post increment */ - rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, RT_MII_MMD_CTRL, - (devad | RT_MII_MMD_CTRL_NOINCR)); -} - -int rt_phy_read_mmd(struct rt_phy_device *phydev, int devad, int regnum) -{ - struct rt_phy_driver *drv = phydev->drv; - - if (regnum > (rt_uint16_t)~0 || devad > 32 || !drv) - return -EINVAL; - - if (drv->read_mmd) - return drv->read_mmd(phydev, devad, regnum); - - if ((drv->features & RT_PHY_10G_FEATURES) == RT_PHY_10G_FEATURES || - devad == RT_MDIO_DEVAD_NONE || !devad) - return rt_phy_read(phydev, devad, regnum); - - rt_phy_mmd_start_indirect(phydev, devad, regnum); - - return rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_MMD_DATA); -} - -int rt_phy_write_mmd(struct rt_phy_device *phydev, int devad, int regnum, rt_uint16_t val) -{ - struct rt_phy_driver *drv = phydev->drv; - - if (regnum > (rt_uint16_t)~0 || devad > 32 || !drv) - return -EINVAL; - - if (drv->write_mmd) - return drv->write_mmd(phydev, devad, regnum, val); - - if ((drv->features & RT_PHY_10G_FEATURES) == RT_PHY_10G_FEATURES || - devad == RT_MDIO_DEVAD_NONE || !devad) - return rt_phy_write(phydev, devad, regnum, val); - - rt_phy_mmd_start_indirect(phydev, devad, regnum); - - return rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, RT_MII_MMD_DATA, val); -} - -int rt_phy_reset(struct rt_phy_device *phydev) -{ - int reg; - int timeout = 500; - int devad = RT_MDIO_DEVAD_NONE; - - if (phydev->flags & RT_PHY_FLAG_BROKEN_RESET) - return 0; - - if (rt_phy_write(phydev, devad, RT_MII_BMCR, RT_BMCR_RESET) < 0) - { - LOG_D("PHY reset failed\n"); - return -1; - } - - reg = rt_phy_read(phydev, devad, RT_MII_BMCR); - while ((reg & RT_BMCR_RESET) && timeout--) - { - reg = rt_phy_read(phydev, devad, RT_MII_BMCR); - - if (reg < 0) - { - LOG_D("PHY status read failed\n"); - return -1; - } - rt_thread_mdelay(1); - } - - if (reg & RT_BMCR_RESET) - { - LOG_D("PHY reset timed out\n"); - return -1; - } - - return 0; -} - -static struct rt_bus rt_phy_bus; - -/** - * @brief create a phy device - * - * Creates a new PHY device based on the given bus, address, PHY ID, and whether Clause 45 is supported. - * - * @param bus the pointer to the bus - * @param addr PHY device address - * @param phy_id PHY device id - * @param is_c45 if suport Clause 45 - * - * @return if create success return the phy device pointer,else return RT_NULL - */ -struct rt_phy_device *rt_phy_device_create(struct mii_bus *bus, int addr, - rt_uint32_t phy_id, rt_bool_t is_c45) -{ - struct rt_phy_device *dev = rt_malloc(sizeof(struct rt_phy_device)); - - if (!dev) - { - LOG_E("Failed to allocate PHY device for %s:%d\n", - bus ? bus->name : "(null bus)", addr); - return RT_NULL; - } - - memset(dev, 0, sizeof(*dev)); - - dev->duplex = -1; - dev->link = 0; - dev->interface = RT_PHY_INTERFACE_MODE_NA; -#ifdef RT_USING_OFW - dev->node = RT_NULL; -#endif - dev->autoneg = RT_TRUE; - - dev->addr = addr; - dev->phy_id = phy_id; - dev->is_c45 = is_c45; - dev->bus = bus; - - if(rt_phy_device_register(dev)) - { - LOG_D("register phy device filed") - } - - if (addr >= 0 && addr < RT_PHY_MAX && phy_id != RT_PHY_FIXED_ID && - phy_id != RT_PHY_NCSI_ID) - bus->phymap[addr] = dev; - - return dev; -} - -/** - * @brief get phy id - * - * get phy id by read the register 2 and 3 of PHY device, - * Register of the MII management interface stipulates that - * register 2 contains thehigh 16 bits of the PHY’s identifier - * the register 3 contains the low 16 bits of the PHY’s identifier - * - * @param bus MII bus pointer - * @param addr PHY device address - * @param devad dev addr if be set to zero it means c22 mode,else it means c45 mode - * @param phy_id the phy id which will be read - * - * @return if read success return 0,else return -RT_EIO - */ -static int get_phy_id(struct mii_bus *bus, int addr, int devad, rt_uint32_t *phy_id) -{ - int phy_reg; - - phy_reg = bus->read(bus, addr, devad, RT_MII_PHYSID1); - - if (phy_reg < 0) - return -RT_EIO; - - *phy_id = (phy_reg & 0xffff) << 16; - - phy_reg = bus->read(bus, addr, devad, RT_MII_PHYSID2); - - if (phy_reg < 0) - return -RT_EIO; - - *phy_id |= (phy_reg & 0xffff); - - return 0; -} - -/** - * @brief create phy device by mask - * - * @param bus MII bus pointer - * @param phy_mask the mask which phy addr corresponding will be set 1 - * @param devad dev addr if be set to zero it means c22 mode,else it means c45 mode - * - * @return if create success return the phy device pointer,if create fail return NULL - */ -static struct rt_phy_device *create_phy_by_mask(struct mii_bus *bus, unsigned int phy_mask,int devad) -{ - rt_uint32_t id = 0xffffffff; - rt_bool_t is_c45; - - while (phy_mask) - { - int addr = __rt_ffs(phy_mask) - 1; - int r = get_phy_id(bus, addr, devad, &id); - - if (r == 0 && id == 0) - { - phy_mask &= ~(1 << addr); - continue; - } - - if (r == 0 && (id & 0x1fffffff) != 0x1fffffff) - { - is_c45 = (devad == RT_MDIO_DEVAD_NONE) ? RT_FALSE : RT_TRUE; - return rt_phy_device_create(bus, addr, id, is_c45); - } - - } - return RT_NULL; -} - -/** - * @brief create phy device by mask - * - * it will create phy device by c22 mode or c45 mode - * - * @param bus mii bus pointer - * @param phy_mask PHY mask it depend on the phy addr, the phy addr corresponding will be set 1 - * - * @return if create success return the phy device pointer,if create fail return NULL - */ -static struct rt_phy_device *rt_phydev_create_by_mask(struct mii_bus *bus, unsigned int phy_mask) -{ - struct rt_phy_device *phy; - /* - *The bit of devad is dev addr which is the new features in c45 - *so if devad equal to zero it means it is c22 mode ,and if not - *equal to zero it means it is c45 mode,which include PMD/PMA , - *WIS ,PCS,PHY XS,PHY XS .... - */ - int devad[] = { - /* Clause-22 */ - RT_MDIO_DEVAD_NONE, - /* Clause-45 */ - RT_MDIO_MMD_PMAPMD, - RT_MDIO_MMD_WIS, - RT_MDIO_MMD_PCS, - RT_MDIO_MMD_PHYXS, - RT_MDIO_MMD_VEND1, - }; - - for (int i = 0; i < sizeof(devad)/sizeof(devad[0]); i++) - { - phy = create_phy_by_mask(bus, phy_mask, devad[i]); - if(phy) - return phy; - } - - return RT_NULL; -} - -struct rt_phy_device *rt_phy_find_by_mask(struct mii_bus *bus, unsigned int phy_mask) -{ - struct rt_phy_device *phy; - unsigned int mask = phy_mask; - unsigned int addr; - if (bus->reset) - { - bus->reset(bus); - - rt_thread_mdelay(15); - } - - while (mask) - { - /* - *Whichever bit of the mask is the 1, - *which bit is the addr as the array subscript to search - *such as mask = 1110 ,this loop will search for subscript - *1,2,3,if the array subscript is not null then return it, - *if the array subscript is null then continue to search - */ - addr = __rt_ffs(mask) - 1; - - if (bus->phymap[addr]) - return bus->phymap[addr]; - - mask &= ~(1U << addr); - } - /*ifcan't find phy device, create a new phy device*/ - phy = rt_phydev_create_by_mask(bus, phy_mask); - - return phy; - -} - -/** - * @brief get phy device by given mii bus, node and address - * @param bus MII bus pointer - * @param np the dtb node of device which need to get phy device - * @param addr address of phy device - * @param interface interface of phy device - * - * @return phy device pointer or NULL if not found - */ -struct rt_phy_device *rt_phy_get_device(struct mii_bus *bus,struct rt_ofw_node *np, int addr,rt_phy_interface interface) -{ - struct rt_phy_device *phy = RT_NULL; - unsigned int phy_mask = addr? 1 << addr:0xffffffff; - -#ifdef RT_USING_OFW - if(np) - phy = rt_ofw_create_phy(bus,np,addr); -#endif - if(!phy) - phy = rt_phy_find_by_mask(bus,phy_mask); - - if(phy) - { - rt_phy_reset(phy); - phy->interface = interface; - return phy; - } - - LOG_D("PHY device get failed"); - return RT_NULL; -} - -static struct rt_phy_driver genphy = { - .uid = 0xffffffff, - .mask = 0xffffffff, - .name = "Generic PHY", - .features = RT_PHY_GBIT_FEATURES | RT_SUPPORTED_MII | - RT_SUPPORTED_AUI | RT_SUPPORTED_FIBRE | - RT_SUPPORTED_BNC, - .config = rt_genphy_config, - .startup = rt_genphy_startup, -}; -RT_PHY_DRIVER_REGISTER(genphy); - -rt_err_t rt_phy_device_register(struct rt_phy_device *pdev) -{ - rt_err_t err; - RT_ASSERT(pdev != RT_NULL); - err = rt_bus_add_device(&rt_phy_bus, &pdev->parent); - if (err) - { - return err; - } - if(!pdev->drv) - pdev->drv = &genphy; - - return RT_EOK; -} - -rt_err_t rt_phy_driver_register(struct rt_phy_driver *pdrv) -{ - RT_ASSERT(pdrv != RT_NULL); - - pdrv->parent.bus = &rt_phy_bus; -#if RT_NAME_MAX > 0 - rt_strcpy(pdrv->parent.parent.name, pdrv->name); -#else - pdrv->parent.parent.name = pdrv->name; -#endif - - return rt_driver_register(&pdrv->parent); -} - -static rt_bool_t phy_match(rt_driver_t drv, rt_device_t dev) -{ - struct rt_phy_device *pdev = rt_container_of(dev, struct rt_phy_device, parent); - struct rt_phy_driver *pdrv = rt_container_of(drv, struct rt_phy_driver, parent); - if ((pdrv->uid & pdrv->mask) == (pdev->phy_id & pdrv->mask)) - return RT_TRUE; - - return RT_FALSE; - -} - -static rt_err_t phy_probe(rt_device_t dev) -{ - rt_err_t err = RT_EOK; - struct rt_phy_driver *pdrv = rt_container_of(dev->drv, struct rt_phy_driver, parent); - struct rt_phy_device *pdev = rt_container_of(dev, struct rt_phy_device, parent); - pdev->drv = pdrv; - pdev->advertising = pdev->drv->features; - pdev->supported = pdev->drv->features; - - pdev->mmds = pdev->drv->mmds; - if(pdrv->probe) - err = pdrv->probe(pdev); - - return err; -} - -static struct rt_bus rt_phy_bus = -{ - .name = "phy", - .match = phy_match, - .probe = phy_probe, -}; - -static int rt_phy_bus_init(void) -{ - rt_bus_register(&rt_phy_bus); - - return 0; -} -INIT_CORE_EXPORT(rt_phy_bus_init); -#endif diff --git a/rt-thread/components/drivers/phye/Kconfig b/rt-thread/components/drivers/phye/Kconfig deleted file mode 100644 index c6672ee..0000000 --- a/rt-thread/components/drivers/phye/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -menuconfig RT_USING_PHYE - bool "Using External Port Physical Layer (PHY) device drivers" - depends on RT_USING_DM - default n - help - This framework will be of use only to devices that use - external PHY (PHY functionality is not embedded within the controller). - -if RT_USING_PHYE - osource "$(SOC_DM_PHYE_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/phye/SConscript b/rt-thread/components/drivers/phye/SConscript deleted file mode 100644 index 23deafe..0000000 --- a/rt-thread/components/drivers/phye/SConscript +++ /dev/null @@ -1,15 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_USING_PHYE']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../include'] - -src = ['phye.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/phye/phye.c b/rt-thread/components/drivers/phye/phye.c deleted file mode 100644 index 7dc6709..0000000 --- a/rt-thread/components/drivers/phye/phye.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-10-24 GuEe-GUI first version - */ - -#define DBG_TAG "rtdm.phye" -#define DBG_LVL DBG_INFO -#include - -#include -#include - -rt_err_t rt_phye_register(struct rt_phye *phye) -{ - rt_err_t err; - - if (phye && phye->dev && phye->ops) - { - err = RT_EOK; - - rt_spin_lock_init(&phye->lock); - rt_dm_dev_bind_fwdata(phye->dev, RT_NULL, phye); - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_phye_unregister(struct rt_phye *phye) -{ - rt_err_t err; - - if (phye) - { - err = RT_EOK; - - rt_spin_lock(&phye->lock); - - if (phye->dev->ref_count) - { - err = -RT_EBUSY; - LOG_E("%s is busy in unregister", rt_dm_dev_get_name(phye->dev)); - } - - rt_dm_dev_unbind_fwdata(phye->dev, RT_NULL); - - rt_spin_unlock(&phye->lock); - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t rt_phye_init(struct rt_phye *phye) -{ - rt_err_t err; - - if (!phye) - { - return RT_EOK; - } - - err = RT_EOK; - - rt_spin_lock(&phye->lock); - - if (phye->init_count == 0 && phye->ops->init) - { - if ((err = phye->ops->init(phye))) - { - goto _out_lock; - } - } - ++phye->init_count; - -_out_lock: - rt_spin_unlock(&phye->lock); - - return err; -} - -rt_err_t rt_phye_exit(struct rt_phye *phye) -{ - rt_err_t err; - - if (!phye) - { - return RT_EOK; - } - - err = RT_EOK; - - rt_spin_lock(&phye->lock); - - if (phye->init_count == 1 && phye->ops->exit) - { - if ((err = phye->ops->exit(phye))) - { - goto _out_lock; - } - } - if (phye->init_count) - { - --phye->init_count; - } - -_out_lock: - rt_spin_unlock(&phye->lock); - - return err; -} - -rt_err_t rt_phye_reset(struct rt_phye *phye) -{ - rt_err_t err; - - if (!phye) - { - return RT_EOK; - } - - err = RT_EOK; - - rt_spin_lock(&phye->lock); - - if (phye->ops->reset) - { - err = phye->ops->reset(phye); - } - - rt_spin_unlock(&phye->lock); - - return err; -} - -rt_err_t rt_phye_power_on(struct rt_phye *phye) -{ - rt_err_t err; - - if (!phye) - { - return RT_EOK; - } - - err = RT_EOK; - - rt_spin_lock(&phye->lock); - - if (phye->power_count == 0 && phye->ops->power_on) - { - if ((err = phye->ops->power_on(phye))) - { - goto _out_lock; - } - } - ++phye->power_count; - -_out_lock: - rt_spin_unlock(&phye->lock); - - return err; -} - -rt_err_t rt_phye_power_off(struct rt_phye *phye) -{ - rt_err_t err; - - if (!phye) - { - return RT_EOK; - } - - err = RT_EOK; - - rt_spin_lock(&phye->lock); - - if (phye->power_count == 1 && phye->ops->power_off) - { - if ((err = phye->ops->power_off(phye))) - { - goto _out_lock; - } - } - if (phye->power_count) - { - --phye->power_count; - } - -_out_lock: - rt_spin_unlock(&phye->lock); - - return err; -} - -rt_err_t rt_phye_set_mode(struct rt_phye *phye, enum rt_phye_mode mode, int submode) -{ - rt_err_t err; - - if (!phye) - { - return RT_EOK; - } - - if (mode < RT_PHYE_MODE_MAX && - (submode == RT_PHYE_MODE_INVALID || submode >= RT_PHYE_MODE_MAX)) - { - err = RT_EOK; - - rt_spin_lock(&phye->lock); - - if (phye->ops->set_mode) - { - err = phye->ops->set_mode(phye, mode, submode); - } - - rt_spin_unlock(&phye->lock); - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -static struct rt_phye *ofw_phye_get_by_index(struct rt_ofw_node *np, int index) -{ - struct rt_phye *phye = RT_NULL; -#ifdef RT_USING_OFW - rt_err_t err; - struct rt_ofw_node *phye_np; - struct rt_ofw_cell_args phye_args; - - if (!rt_ofw_parse_phandle_cells(np, "phys", "#phy-cells", index, &phye_args)) - { - phye_np = phye_args.data; - - if (!rt_ofw_data(phye_np)) - { - rt_platform_ofw_request(phye_np); - } - - phye = rt_ofw_data(phye_np); - rt_ofw_node_put(phye_np); - - if (phye && phye->ops->ofw_parse) - { - if ((err = phye->ops->ofw_parse(phye, &phye_args))) - { - phye = rt_err_ptr(err); - } - } - } -#endif /* RT_USING_OFW */ - return phye; -} - -struct rt_phye *rt_phye_get_by_index(struct rt_device *dev, int index) -{ - struct rt_phye *phye = RT_NULL; - - if (!dev || index < 0) - { - return rt_err_ptr(-RT_EINVAL); - } - - if (dev->ofw_node) - { - phye = ofw_phye_get_by_index(dev->ofw_node, index); - } - - if (!rt_is_err_or_null(phye)) - { - rt_spin_lock(&phye->lock); - ++phye->dev->ref_count; - rt_spin_unlock(&phye->lock); - } - - return phye; -} - -struct rt_phye *rt_phye_get_by_name(struct rt_device *dev, const char *id) -{ - int index; - - if (!dev || !id) - { - return rt_err_ptr(-RT_EINVAL); - } - - index = rt_dm_dev_prop_index_of_string(dev, "phy-names", id); - - if (index >= 0) - { - return rt_phye_get_by_index(dev, index); - } - - return RT_NULL; -} - -void rt_phye_put(struct rt_phye *phye) -{ - if (phye) - { - rt_spin_lock(&phye->lock); - --phye->dev->ref_count; - rt_spin_unlock(&phye->lock); - } -} diff --git a/rt-thread/components/drivers/pic/Kconfig b/rt-thread/components/drivers/pic/Kconfig index 3cf00c0..16c1410 100644 --- a/rt-thread/components/drivers/pic/Kconfig +++ b/rt-thread/components/drivers/pic/Kconfig @@ -1,14 +1,12 @@ menuconfig RT_USING_PIC bool "Using Programmable Interrupt Controller (PIC)" - select RT_USING_ADT - select RT_USING_ADT_BITMAP + select RT_USING_BITMAP depends on RT_USING_DM default n config RT_USING_PIC_STATISTICS bool "Enable ISR execution time statistics" depends on RT_USING_PIC - depends on RT_USING_KTIME depends on RT_USING_INTERRUPT_INFO default n @@ -24,31 +22,12 @@ config RT_PIC_ARM_GIC select RT_USING_OFW default n -config RT_PIC_ARM_GIC_V2M - bool "ARM GIC V2M" if RT_PIC_ARM_GIC && RT_PCI_MSI - depends on RT_USING_OFW - default n - config RT_PIC_ARM_GIC_V3 bool "ARM GICv3" depends on RT_USING_PIC select RT_USING_OFW default n -config RT_PIC_ARM_GIC_V3_ITS - bool "ARM GICv3 ITS (Interrupt Translation Service)" if RT_PIC_ARM_GIC_V3 && RT_PCI_MSI - depends on RT_USING_OFW - select RT_USING_ADT_REF - default n - -config RT_PIC_ARM_GIC_V3_ITS_IRQ_MAX - int "IRQ maximum used" - depends on RT_PIC_ARM_GIC_V3_ITS - default 127 if ARCH_CPU_64BIT - default 63 - help - Recommended to be based on the bit length (full bits) of maximum usage. - config RT_PIC_ARM_GIC_MAX_NR int depends on RT_USING_PIC diff --git a/rt-thread/components/drivers/pic/SConscript b/rt-thread/components/drivers/pic/SConscript index 53cb66e..e820792 100644 --- a/rt-thread/components/drivers/pic/SConscript +++ b/rt-thread/components/drivers/pic/SConscript @@ -16,15 +16,9 @@ if GetDepend(['RT_PIC_ARM_GIC']) or GetDepend(['RT_PIC_ARM_GIC_V3']): if GetDepend(['RT_PIC_ARM_GIC']): src += ['pic-gicv2.c'] -if GetDepend(['RT_PIC_ARM_GIC_V2M']): - src += ['pic-gicv2m.c'] - if GetDepend(['RT_PIC_ARM_GIC_V3']): src += ['pic-gicv3.c'] -if GetDepend(['RT_PIC_ARM_GIC_V3_ITS']): - src += ['pic-gicv3-its.c'] - group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) Return('group') diff --git a/rt-thread/components/drivers/pic/pic-gic-common.c b/rt-thread/components/drivers/pic/pic-gic-common.c index 5c6dc03..07e5f0b 100644 --- a/rt-thread/components/drivers/pic/pic-gic-common.c +++ b/rt-thread/components/drivers/pic/pic-gic-common.c @@ -71,9 +71,8 @@ void gic_common_sgi_config(void *base, void *data, int irq_base) pirq = rt_pic_find_ipi(data, ipi); \ pirq->mode = RT_IRQ_MODE_EDGE_RISING; \ - DECLARE_GIC_IPI(RT_SCHEDULE_IPI, RT_SCHEDULE_IPI); - DECLARE_GIC_IPI(RT_STOP_IPI, RT_STOP_IPI); - DECLARE_GIC_IPI(RT_SMP_CALL_IPI, RT_SMP_CALL_IPI); + DECLARE_GIC_IPI(RT_SCHEDULE_IPI, 0); + DECLARE_GIC_IPI(RT_STOP_IPI, 1); #undef DECLARE_GIC_IPI } diff --git a/rt-thread/components/drivers/pic/pic-gic-common.h b/rt-thread/components/drivers/pic/pic-gic-common.h index d78e068..46841e8 100644 --- a/rt-thread/components/drivers/pic/pic-gic-common.h +++ b/rt-thread/components/drivers/pic/pic-gic-common.h @@ -8,14 +8,10 @@ * 2023-01-30 GuEe-GUI first version */ -#ifndef __PIC_GIC_COMMON_H__ -#define __PIC_GIC_COMMON_H__ +#ifndef __IRQ_GIC_COMMON_H__ +#define __IRQ_GIC_COMMON_H__ #include - -#ifdef RT_PCI_MSI -#include -#endif #include #define GIC_SGI_NR 16 @@ -56,4 +52,4 @@ rt_err_t gicv2m_ofw_probe(struct rt_ofw_node *ic_np, const struct rt_ofw_node_id rt_err_t gicv3_its_ofw_probe(struct rt_ofw_node *ic_np, const struct rt_ofw_node_id *id); #endif -#endif /* __PIC_GIC_COMMON_H__ */ +#endif /* __IRQ_GIC_COMMON_H__ */ diff --git a/rt-thread/components/drivers/pic/pic-gicv2.c b/rt-thread/components/drivers/pic/pic-gicv2.c index dbfd443..adce046 100644 --- a/rt-thread/components/drivers/pic/pic-gicv2.c +++ b/rt-thread/components/drivers/pic/pic-gicv2.c @@ -83,11 +83,6 @@ static void gicv2_dist_init(struct gicv2 *gic) LOG_D("Max irq = %d", gic->max_irq); - if (gic->skip_init) - { - return; - } - HWREG32(base + GIC_DIST_CTRL) = GICD_DISABLE; /* Set all global (unused) interrupts to this CPU only. */ @@ -133,8 +128,6 @@ static void gicv2_cpu_init(struct gicv2 *gic) #ifdef ARCH_SUPPORT_HYP _gicv2_eoi_mode_ns = RT_TRUE; -#else - _gicv2_eoi_mode_ns = !!rt_ofw_bootargs_select("pic.gicv2_eoimode", 0); #endif if (_gicv2_eoi_mode_ns) @@ -625,8 +618,6 @@ static rt_err_t gicv2_ofw_init(struct rt_ofw_node *np, const struct rt_ofw_node_ break; } - gic->skip_init = rt_ofw_prop_read_bool(np, "skip-init"); - gic_common_init_quirk_ofw(np, _gicv2_quirks, gic); gicv2_init(gic); diff --git a/rt-thread/components/drivers/pic/pic-gicv2.h b/rt-thread/components/drivers/pic/pic-gicv2.h index 5fa9f2a..69f9651 100644 --- a/rt-thread/components/drivers/pic/pic-gicv2.h +++ b/rt-thread/components/drivers/pic/pic-gicv2.h @@ -78,8 +78,6 @@ struct gicv2 rt_size_t hyp_size; void *vcpu_base; rt_size_t vcpu_size; - - rt_bool_t skip_init; }; #endif /* __IRQ_GICV2_H__ */ diff --git a/rt-thread/components/drivers/pic/pic-gicv2m.c b/rt-thread/components/drivers/pic/pic-gicv2m.c deleted file mode 100644 index ae60137..0000000 --- a/rt-thread/components/drivers/pic/pic-gicv2m.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-07 GuEe-GUI first version - */ - -#include -#include -#include - -#define DBG_TAG "pic.gicv2m" -#define DBG_LVL DBG_INFO -#include - -#include -#include -#include "pic-gic-common.h" - -/* -* MSI_TYPER: -* [31:26] Reserved -* [25:16] lowest SPI assigned to MSI -* [15:10] Reserved -* [9:0] Numer of SPIs assigned to MSI -*/ -#define V2M_MSI_TYPER 0x008 -#define V2M_MSI_TYPER_BASE_SHIFT 16 -#define V2M_MSI_TYPER_BASE_MASK 0x3ff -#define V2M_MSI_TYPER_NUM_MASK 0x3ff -#define V2M_MSI_SETSPI_NS 0x040 -#define V2M_MIN_SPI 32 -#define V2M_MAX_SPI 1019 -#define V2M_MSI_IIDR 0xfcc - -#define V2M_MSI_TYPER_BASE_SPI(x) (((x) >> V2M_MSI_TYPER_BASE_SHIFT) & V2M_MSI_TYPER_BASE_MASK) -#define V2M_MSI_TYPER_NUM_SPI(x) ((x) & V2M_MSI_TYPER_NUM_MASK) - -/* APM X-Gene with GICv2m MSI_IIDR register value */ -#define XGENE_GICV2M_MSI_IIDR 0x06000170 -/* Broadcom NS2 GICv2m MSI_IIDR register value */ -#define BCM_NS2_GICV2M_MSI_IIDR 0x0000013f - -/* List of flags for specific v2m implementation */ -#define GICV2M_NEEDS_SPI_OFFSET 0x00000001 -#define GICV2M_GRAVITON_ADDRESS_ONLY 0x00000002 - -struct gicv2m -{ - struct rt_pic parent; - - void *base; - void *base_phy; - rt_uint32_t spi_start; /* The SPI number that MSIs start */ - rt_uint32_t spis_nr; /* The number of SPIs for MSIs */ - rt_uint32_t spi_offset; /* Offset to be subtracted from SPI number */ - - rt_bitmap_t *vectors; /* MSI vector bitmap */ - rt_uint32_t flags; /* Flags for v2m's specific implementation */ - - void *gic; - struct rt_spinlock lock; -}; - -#define raw_to_gicv2m(raw) rt_container_of(raw, struct gicv2m, parent) - -static rt_ubase_t gicv2m_get_msi_addr(struct gicv2m *v2m, int hwirq) -{ - rt_ubase_t addr; - - if (v2m->flags & GICV2M_GRAVITON_ADDRESS_ONLY) - { - addr = (rt_ubase_t)v2m->base_phy | ((hwirq - 32) << 3); - } - else - { - addr = (rt_ubase_t)v2m->base_phy + V2M_MSI_SETSPI_NS; - } - - return addr; -} - -static rt_bool_t is_msi_spi_valid(rt_uint32_t base, rt_uint32_t num) -{ - if (base < V2M_MIN_SPI) - { - LOG_E("Invalid MSI base SPI (base: %u)", base); - - return RT_FALSE; - } - else if ((num == 0) || (base + num > V2M_MAX_SPI)) - { - LOG_E("Number of SPIs (%u) exceed maximum (%u)", num, V2M_MAX_SPI - V2M_MIN_SPI + 1); - - return RT_FALSE; - } - - return RT_TRUE; -} - -static void gicv2m_irq_mask(struct rt_pic_irq *pirq) -{ - rt_pci_msi_mask_irq(pirq); - rt_pic_irq_parent_mask(pirq); -} - -static void gicv2m_irq_unmask(struct rt_pic_irq *pirq) -{ - rt_pci_msi_unmask_irq(pirq); - rt_pic_irq_parent_unmask(pirq); -} - -static void gicv2m_compose_msi_msg(struct rt_pic_irq *pirq, struct rt_pci_msi_msg *msg) -{ - rt_ubase_t addr; - struct gicv2m *v2m = raw_to_gicv2m(pirq->pic); - - addr = gicv2m_get_msi_addr(v2m, pirq->hwirq); - - msg->address_hi = rt_upper_32_bits(addr); - msg->address_lo = rt_lower_32_bits(addr); - - if (v2m->flags & GICV2M_GRAVITON_ADDRESS_ONLY) - { - msg->data = 0; - } - else - { - msg->data = pirq->hwirq; - } - - if (v2m->flags & GICV2M_NEEDS_SPI_OFFSET) - { - msg->data -= v2m->spi_offset; - } -} - -static int gicv2m_irq_alloc_msi(struct rt_pic *pic, struct rt_pci_msi_desc *msi_desc) -{ - rt_ubase_t level; - int irq, parent_irq, hwirq, hwirq_index; - struct rt_pic_irq *pirq; - struct gicv2m *v2m = raw_to_gicv2m(pic); - struct rt_pic *ppic = v2m->gic; - - level = rt_spin_lock_irqsave(&v2m->lock); - hwirq_index = rt_bitmap_next_clear_bit(v2m->vectors, 0, v2m->spis_nr); - - if (hwirq_index >= v2m->spis_nr) - { - irq = -RT_EEMPTY; - goto _out_lock; - } - - hwirq = v2m->spi_start + v2m->spi_offset + hwirq_index; - - parent_irq = ppic->ops->irq_map(ppic, hwirq, RT_IRQ_MODE_EDGE_RISING); - if (parent_irq < 0) - { - irq = parent_irq; - goto _out_lock; - } - - irq = rt_pic_config_irq(pic, hwirq_index, hwirq); - if (irq < 0) - { - goto _out_lock; - } - pirq = rt_pic_find_irq(pic, hwirq_index); - - pirq->mode = RT_IRQ_MODE_EDGE_RISING; - rt_pic_cascade(pirq, parent_irq); - - rt_bitmap_set_bit(v2m->vectors, hwirq_index); - -_out_lock: - rt_spin_unlock_irqrestore(&v2m->lock, level); - - return irq; -} - -static void gicv2m_irq_free_msi(struct rt_pic *pic, int irq) -{ - rt_ubase_t level; - struct rt_pic_irq *pirq; - struct gicv2m *v2m = raw_to_gicv2m(pic); - - pirq = rt_pic_find_pirq(pic, irq); - - if (!pirq) - { - return; - } - - rt_pic_uncascade(pirq); - - level = rt_spin_lock_irqsave(&v2m->lock); - rt_bitmap_clear_bit(v2m->vectors, pirq->hwirq - (v2m->spi_start + v2m->spi_offset)); - rt_spin_unlock_irqrestore(&v2m->lock, level); -} - -static rt_err_t gicv2m_irq_set_state(struct rt_pic *pic, int hwirq, int type, rt_bool_t state) -{ - struct gicv2m *v2m = raw_to_gicv2m(pic); - struct rt_pic *ppic = v2m->gic; - - return ppic->ops->irq_set_state(ppic, hwirq, type, state); -} - -static rt_err_t gicv2m_irq_get_state(struct rt_pic *pic, int hwirq, int type, rt_bool_t *out_state) -{ - struct gicv2m *v2m = raw_to_gicv2m(pic); - struct rt_pic *ppic = v2m->gic; - - return ppic->ops->irq_get_state(ppic, hwirq, type, out_state); -} - -const static struct rt_pic_ops gicv2m_ops = -{ - .name = "GICv2m", - .irq_ack = rt_pic_irq_parent_ack, - .irq_mask = gicv2m_irq_mask, - .irq_unmask = gicv2m_irq_unmask, - .irq_eoi = rt_pic_irq_parent_eoi, - .irq_set_priority = rt_pic_irq_parent_set_priority, - .irq_set_affinity = rt_pic_irq_parent_set_affinity, - .irq_compose_msi_msg = gicv2m_compose_msi_msg, - .irq_alloc_msi = gicv2m_irq_alloc_msi, - .irq_free_msi = gicv2m_irq_free_msi, - .irq_set_state = gicv2m_irq_set_state, - .irq_get_state = gicv2m_irq_get_state, - .flags = RT_PIC_F_IRQ_ROUTING, -}; - -static const struct rt_ofw_node_id gicv2m_ofw_match[] = -{ - { .compatible = "arm,gic-v2m-frame" }, - { /* sentinel */ } -}; - -rt_err_t gicv2m_ofw_probe(struct rt_ofw_node *np, const struct rt_ofw_node_id *id) -{ - rt_err_t err = RT_EOK; - struct rt_ofw_node *v2m_np; - - rt_ofw_foreach_available_child_node(np, v2m_np) - { - struct gicv2m *v2m; - rt_size_t bitmap_size; - rt_uint32_t spi_start = 0, spis_nr = 0; - - if (!rt_ofw_node_match(v2m_np, gicv2m_ofw_match)) - { - continue; - } - - if (!rt_ofw_prop_read_bool(v2m_np, "msi-controller")) - { - continue; - } - - if (!(v2m = rt_malloc(sizeof(*v2m)))) - { - rt_ofw_node_put(v2m_np); - - err = -RT_ENOMEM; - break; - } - - v2m->base = rt_ofw_iomap(v2m_np, 0); - - if (!v2m->base) - { - LOG_E("%s: IO map failed", rt_ofw_node_full_name(v2m_np)); - continue; - } - - v2m->base_phy = rt_kmem_v2p(v2m->base); - v2m->flags = 0; - - if (!rt_ofw_prop_read_u32(v2m_np, "arm,msi-base-spi", &spi_start) && - !rt_ofw_prop_read_u32(v2m_np, "arm,msi-num-spis", &spis_nr)) - { - LOG_I("DT overriding V2M MSI_TYPER (base:%u, num:%u)", spi_start, spis_nr); - } - - if (spi_start && spis_nr) - { - v2m->spi_start = spi_start; - v2m->spis_nr = spis_nr; - } - else - { - rt_uint32_t typer; - - /* Graviton should always have explicit spi_start/spis_nr */ - if (v2m->flags & GICV2M_GRAVITON_ADDRESS_ONLY) - { - goto _fail; - } - typer = HWREG32(v2m->base + V2M_MSI_TYPER); - - v2m->spi_start = V2M_MSI_TYPER_BASE_SPI(typer); - v2m->spis_nr = V2M_MSI_TYPER_NUM_SPI(typer); - } - - if (!is_msi_spi_valid(v2m->spi_start, v2m->spis_nr)) - { - goto _fail; - } - - /* - * APM X-Gene GICv2m implementation has an erratum where - * the MSI data needs to be the offset from the spi_start - * in order to trigger the correct MSI interrupt. This is - * different from the standard GICv2m implementation where - * the MSI data is the absolute value within the range from - * spi_start to (spi_start + num_spis). - * - * Broadcom NS2 GICv2m implementation has an erratum where the MSI data - * is 'spi_number - 32' - * - * Reading that register fails on the Graviton implementation - */ - if (!(v2m->flags & GICV2M_GRAVITON_ADDRESS_ONLY)) - { - switch (HWREG32(v2m->base + V2M_MSI_IIDR)) - { - case XGENE_GICV2M_MSI_IIDR: - v2m->flags |= GICV2M_NEEDS_SPI_OFFSET; - v2m->spi_offset = v2m->spi_start; - break; - - case BCM_NS2_GICV2M_MSI_IIDR: - v2m->flags |= GICV2M_NEEDS_SPI_OFFSET; - v2m->spi_offset = 32; - break; - } - } - - bitmap_size = RT_BITMAP_LEN(v2m->spis_nr) * sizeof(rt_bitmap_t); - - if (!(v2m->vectors = rt_calloc(1, bitmap_size))) - { - err = -RT_ENOMEM; - goto _fail; - } - - rt_spin_lock_init(&v2m->lock); - - v2m->parent.priv_data = v2m; - v2m->parent.ops = &gicv2m_ops; - v2m->gic = rt_ofw_data(np); - - rt_pic_linear_irq(&v2m->parent, v2m->spis_nr); - rt_pic_user_extends(&v2m->parent); - - rt_ofw_data(v2m_np) = &v2m->parent; - rt_ofw_node_set_flag(v2m_np, RT_OFW_F_READLY); - - continue; - - _fail: - rt_iounmap(v2m->base); - rt_free(v2m); - - if (err) - { - rt_ofw_node_put(v2m_np); - break; - } - } - - return err; -} diff --git a/rt-thread/components/drivers/pic/pic-gicv3-its.c b/rt-thread/components/drivers/pic/pic-gicv3-its.c deleted file mode 100644 index f0772d9..0000000 --- a/rt-thread/components/drivers/pic/pic-gicv3-its.c +++ /dev/null @@ -1,1584 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-01-30 GuEe-GUI first version - */ - -#include -#include -#include - -#define DBG_TAG "pic.gicv3-its" -#define DBG_LVL DBG_INFO -#include - -#include -#include -#include -#include -#include "pic-gicv3.h" -#include "pic-gic-common.h" - -#define ITS_CMD_QUEUE_SIZE (64 * SIZE_KB) -#define ITS_CMD_QUEUE_ALIGN (64 * SIZE_KB) -#define ITS_CMD_QUEUE_NR (ITS_CMD_QUEUE_SIZE / sizeof(struct its_command)) - -#define ITS_ITT_ALIGN (256 * SIZE_KB) - -#define ITS_LPI_CONFIG_TABLE_ALIGN (64 * SIZE_KB) -#define ITS_LPI_CONFIG_PROP_DEFAULT_PRIO GICD_INT_DEF_PRI -#define ITS_LPI_CONFIG_PROP_SHIFT 2 -#define ITS_LPI_CONFIG_PROP_MASK RT_GENMASK(7, ITS_LPI_CONFIG_PROP_SHIFT) -#define ITS_LPI_PENDING_TABLE_ALIGN (64 * SIZE_KB) - -#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING RT_BIT(0) -#define RDIST_FLAGS_RD_TABLES_PREALLOCATED RT_BIT(1) -#define RDIST_FLAGS_FORCE_NON_SHAREABLE RT_BIT(2) - -#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING RT_BIT(0) -#define ITS_FLAGS_WORKAROUND_CAVIUM_22375 RT_BIT(1) -#define ITS_FLAGS_FORCE_NON_SHAREABLE RT_BIT(2) - -#define RD_LOCAL_LPI_ENABLED RT_BIT(0) -#define RD_LOCAL_PENDTABLE_PREALLOCATED RT_BIT(1) -#define RD_LOCAL_MEMRESERVE_DONE RT_BIT(2) - -struct its_command -{ - union - { - rt_le64_t code_raw[4]; - rt_uint64_t code[4]; - }; -}; - -struct its_table -{ - void *base; - rt_uint64_t val; - rt_uint32_t size_bits; - rt_uint32_t page_size; - union - { - struct - { - rt_uint32_t itt_entries; - rt_uint32_t lvl2_bits; - }; - }; -}; - -struct its_collection -{ - rt_uint64_t target_address; - rt_uint16_t id; -}; - -struct gicv3_its; - -struct its_map -{ - rt_list_t list; - struct rt_ref ref; - struct gicv3_its *its; - - int device_id; - int lpi_base; - int cpu_id; - - void *itt; - void *lvl2_dte; -}; - -struct gicv3_its -{ - struct rt_pic parent; - rt_list_t list; - - void *base; - void *base_phy; - - void *cmd_base; - rt_ubase_t cmd_idx; - rt_uint32_t flags; - struct rt_spinlock cmd_lock; - - struct its_table tbls[GITS_BASER_NR_REGS]; - struct its_collection collections[RT_CPUS_NR]; - - struct gicv3 *gic; - struct rt_ofw_node *np; -}; - -#define raw_to_gicv3_its(raw) rt_container_of(raw, struct gicv3_its, parent) - -static rt_size_t lpi_nr; -static rt_uint32_t lpi_id_bits; -static void *lpi_table; -static void *lpi_pending_table; -static rt_bitmap_t *lpis_vectors = RT_NULL; -static struct rt_spinlock lpis_lock = {}, map_lock = {}; -static rt_list_t its_nodes = RT_LIST_OBJECT_INIT(its_nodes); -static rt_list_t map_nodes = RT_LIST_OBJECT_INIT(map_nodes); - -rt_inline rt_uint64_t its_readq(struct gicv3_its *its, int off) -{ - return HWREG32(its->base + off) | - (rt_uint64_t)HWREG32(its->base + off + 4) << 32; -} - -rt_inline void its_writeq(struct gicv3_its *its, int off, rt_uint64_t value) -{ - HWREG32(its->base + off) = (rt_uint32_t)value; - HWREG32(its->base + off + 4) = (rt_uint32_t)(value >> 32); -} - -rt_inline rt_uint32_t its_readl(struct gicv3_its *its, int off) -{ - return HWREG32(its->base + off); -} - -rt_inline void its_writel(struct gicv3_its *its, int off, rt_uint32_t value) -{ - HWREG32(its->base + off) = value; -} - -rt_inline rt_uint32_t its_pirq_event_id(struct gicv3_its *its, struct rt_pic_irq *pirq) -{ - return pirq->hwirq - 8192; -} - -rt_inline rt_uint32_t its_pirq_device_id(struct gicv3_its *its, struct rt_pic_irq *pirq) -{ - struct its_map *map = pirq->msi_desc->priv; - - return map->device_id; -} - -rt_inline rt_size_t its_device_id_bits(struct gicv3_its *its) -{ - return RT_FIELD_GET(GITS_TYPER_DEVBITS, HWREG64(its->base + GITS_TYPER)) + 1; -} - -rt_inline void *lpi_base_config(int index) -{ - return &((rt_uint8_t *)lpi_table)[index - 8192]; -} - -static void its_mask_encode(rt_uint64_t *raw_code, rt_uint64_t val, int h, int l) -{ - rt_uint64_t mask = RT_GENMASK_ULL(h, l); - *raw_code &= ~mask; - *raw_code |= (val << l) & mask; -} - -rt_inline void its_encode_cmd(struct its_command *cmd, rt_uint8_t cmd_nr) -{ - its_mask_encode(&cmd->code[0], cmd_nr, 7, 0); -} - -rt_inline void its_encode_valid(struct its_command *cmd, rt_bool_t valid) -{ - its_mask_encode(&cmd->code[2], !!valid, 63, 63); -} - -rt_inline void its_encode_phys_id(struct its_command *cmd, rt_uint32_t phys_id) -{ - its_mask_encode(&cmd->code[1], phys_id, 63, 32); -} - -rt_inline void its_encode_size(struct its_command *cmd, rt_uint8_t size) -{ - its_mask_encode(&cmd->code[1], size, 4, 0); -} - -rt_inline void its_encode_itt(struct its_command *cmd, rt_uint64_t itt_addr) -{ - its_mask_encode(&cmd->code[2], itt_addr >> 8, 51, 8); -} - -rt_inline void its_encode_target(struct its_command *cmd, rt_uint64_t target_addr) -{ - its_mask_encode(&cmd->code[2], target_addr >> 16, 51, 16); -} - -rt_inline void its_encode_device_id(struct its_command *cmd, rt_uint32_t device_id) -{ - its_mask_encode(&cmd->code[0], device_id, 63, 32); -} - -rt_inline void its_encode_event_id(struct its_command *cmd, rt_uint32_t event_id) -{ - its_mask_encode(&cmd->code[1], event_id, 31, 0); -} - -rt_inline void its_encode_collection(struct its_command *cmd, rt_uint16_t collection_id) -{ - its_mask_encode(&cmd->code[2], collection_id, 15, 0); -} - -static struct its_table *its_baser_type(struct gicv3_its *its, int type) -{ - for (int i = 0; i < RT_ARRAY_SIZE(its->tbls); ++i) - { - if (GITS_BASER_TYPE(its->tbls[i].val) == type) - { - return &its->tbls[i]; - } - } - - return RT_NULL; -} - -static struct its_command *its_cmd_alloc(struct gicv3_its *its) -{ - struct its_command *cmd = RT_NULL; - - for (rt_uint32_t count = 0; count <= 10000; ++count) - { - if ((its->cmd_idx + 1) % ITS_CMD_QUEUE_NR != its_readl(its, GITS_CREADR) / sizeof(*cmd)) - { - struct its_command *cmds = its->cmd_base; - - cmd = &cmds[its->cmd_idx++]; - its->cmd_idx %= ITS_CMD_QUEUE_NR; - - rt_memset(cmd, 0, sizeof(*cmd)); - - break; - } - - rt_hw_us_delay(10); - } - - return cmd; -} - -static rt_err_t its_cmd_submit_raw(struct gicv3_its *its, struct its_command *cmd) -{ - rt_uint64_t cwriter; - rt_bool_t retry = RT_FALSE; - - cwriter = (void *)(cmd + 1) - its->cmd_base; - rt_hw_rmb(); - -#ifdef ARCH_CPU_BIG_ENDIAN - cmd->code_raw[0] = rt_cpu_to_le64(cmd->code[0]); - cmd->code_raw[1] = rt_cpu_to_le64(cmd->code[1]); - cmd->code_raw[2] = rt_cpu_to_le64(cmd->code[2]); - cmd->code_raw[3] = rt_cpu_to_le64(cmd->code[3]); -#endif /* ARCH_CPU_BIG_ENDIAN */ - - /* Make sure the commands written to memory are observable by the ITS */ - if (its->flags & ITS_FLAGS_CMDQ_NEEDS_FLUSHING) - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, cmd, sizeof(*cmd)); - } - else - { - rt_hw_wmb(); - } - - its_writel(its, GITS_CWRITER, cwriter); - - for (rt_uint32_t count = 0; count < 10000; ++count) - { - if (its_readl(its, GITS_CREADR) == cwriter) - { - return RT_EOK; - } - - /* Stalled */ - if (!retry && its_readl(its, GITS_CREADR) & 1) - { - /* Retry */ - its_writel(its, GITS_CWRITER, cwriter); - retry = RT_TRUE; - } - else if (retry) - { - LOG_E("Retry command 0x%02x fail", cmd->code[0] & 0xff); - - return -RT_EIO; - } - - rt_hw_us_delay(10); - } - - return -RT_ETIMEOUT; -} - -static rt_err_t its_cmd_submit_nomap(struct gicv3_its *its, struct its_command *cmd, - int cpu_id, rt_bool_t sync) -{ - rt_err_t err; - struct its_command *hw_cmd; - - rt_hw_spin_lock(&its->cmd_lock.lock); - - if (!(hw_cmd = its_cmd_alloc(its))) - { - err = -RT_EBUSY; - goto _out_lock; - } - - rt_memcpy(hw_cmd, cmd, sizeof(*hw_cmd)); - - if ((err = its_cmd_submit_raw(its, hw_cmd))) - { - goto _out_lock; - } - - if (sync) - { - if (!(hw_cmd = its_cmd_alloc(its))) - { - err = -RT_EBUSY; - goto _out_lock; - } - - its_encode_cmd(hw_cmd, GITS_CMD_SYNC); - its_encode_target(hw_cmd, its->collections[cpu_id].target_address); - - err = its_cmd_submit_raw(its, hw_cmd); - } - -_out_lock: - rt_hw_spin_unlock(&its->cmd_lock.lock); - - return err; -} - -static rt_err_t its_cmd_submit(struct gicv3_its *its, struct its_command *cmd, - struct its_map *map, rt_bool_t sync) -{ - return its_cmd_submit_nomap(its, cmd, map->cpu_id, sync); -} - -static rt_err_t lpi_flush_config(struct gicv3_its *its, rt_uint8_t *conf, - struct rt_pic_irq *pirq) -{ - struct its_command cmd; - struct its_map *map = pirq->msi_desc->priv; - - if (its->gic->redist_flags & RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING) - { - /* Clean D-cache under command */ - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, conf, sizeof(*conf)); - } - else - { - /* DSB inner shareable, store */ - rt_hw_wmb(); - } - - rt_memset(&cmd, 0, sizeof(cmd)); - its_encode_cmd(&cmd, GITS_CMD_INV); - its_encode_device_id(&cmd, its_pirq_device_id(its, pirq)); - its_encode_event_id(&cmd, its_pirq_event_id(its, pirq)); - - return its_cmd_submit(its, &cmd, map, RT_FALSE); -} - -rt_inline void *gicr_rd_base_percpu(struct gicv3 *gic) -{ - return gic->redist_regions[rt_hw_cpu_id()].base; -} - -rt_inline void *gicr_rd_base(struct gicv3_its *its) -{ - return its->gic->redist_percpu_base[rt_hw_cpu_id()]; -} - -rt_inline rt_uint64_t *gicr_rd_flags(struct gicv3_its *its) -{ - return &its->gic->redist_percpu_flags[rt_hw_cpu_id()]; -} - -static rt_bool_t gicr_supports_plpis(struct gicv3_its *its) -{ - return !!(HWREG64(gicr_rd_base(its) + GICR_TYPER) & GICR_TYPER_PLPIS); -} - -static rt_err_t redist_disable_lpis(struct gicv3_its *its) -{ - void *gicr = gicr_rd_base(its); - rt_uint64_t timeout = 1000000L, val; - - if (!gicr_supports_plpis(its)) - { - LOG_E("CPU#%d: LPIs not supported", rt_hw_cpu_id()); - return -RT_ENOSYS; - } - - val = HWREG32(gicr + GICR_CTLR); - if (!(val & GICR_CTLR_ENABLE_LPIS)) - { - return RT_EOK; - } - - /* - * If coming via a CPU hotplug event, we don't need to disable - * LPIs before trying to re-enable them. They are already - * configured and all is well in the world. - * - * If running with preallocated tables, there is nothing to do. - */ - if ((*gicr_rd_flags(its) & RD_LOCAL_LPI_ENABLED) || - (its->gic->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED)) - { - return RT_EOK; - } - - /* From that point on, we only try to do some damage control */ - LOG_W("CPU%d: Booted with LPIs enabled, memory probably corrupted", rt_hw_cpu_id()); - - /* Disable LPIs */ - val &= ~GICR_CTLR_ENABLE_LPIS; - HWREG32(gicr + GICR_CTLR) = val; - - /* Make sure any change to GICR_CTLR is observable by the GIC */ - rt_hw_barrier(dsb, sy); - - /* - * Software must observe RWP==0 after clearing GICR_CTLR.EnableLPIs - * from 1 to 0 before programming GICR_PEND{PROP}BASER registers. - * Error out if we time out waiting for RWP to clear. - */ - while (HWREG32(gicr + GICR_CTLR) & GICR_CTLR_RWP) - { - if (!timeout) - { - LOG_E("CPU#%d: Timeout while disabling LPIs", rt_hw_cpu_id()); - - return -RT_ETIMEOUT; - } - - rt_hw_us_delay(1); - --timeout; - } - - /* - * After it has been written to 1, it is IMPLEMENTATION - * DEFINED whether GICR_CTLR.EnableLPI becomes RES1 or can be - * cleared to 0. Error out if clearing the bit failed. - */ - if (HWREG32(gicr + GICR_CTLR) & GICR_CTLR_ENABLE_LPIS) - { - LOG_E("CPU#%d: Failed to disable LPIs", rt_hw_cpu_id()); - - return -RT_EBUSY; - } - - return RT_EOK; -} - -static void gicv3_its_cpu_init_lpis(struct gicv3_its *its) -{ - void *gicr; - rt_ubase_t paddr; - rt_uint64_t val, tmp; - - if (*gicr_rd_flags(its) & RD_LOCAL_LPI_ENABLED) - { - return; - } - - gicr = gicr_rd_base(its); - - val = HWREG32(gicr + GICR_CTLR); - - if ((its->gic->redist_flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED) && - (val & GICR_CTLR_ENABLE_LPIS)) - { - *gicr_rd_flags(its) |= RD_LOCAL_PENDTABLE_PREALLOCATED; - - goto _out; - } - - paddr = (rt_ubase_t)rt_kmem_v2p(lpi_pending_table); - - /* Set PROPBASE */ - val = ((rt_ubase_t)rt_kmem_v2p(lpi_table) | - GITS_CBASER_InnerShareable | - GITS_CBASER_RaWaWb | - ((lpi_id_bits - 1) & GICR_PROPBASER_IDBITS_MASK)); - - HWREG64(gicr + GICR_PROPBASER) = val; - tmp = HWREG64(gicr + GICR_PROPBASER); - - if (its->gic->redist_flags & RDIST_FLAGS_FORCE_NON_SHAREABLE) - { - tmp &= ~GICR_PBASER_SHARE_MASK_ALL; - } - - if ((tmp ^ val) & GICR_PBASER_SHARE_MASK_ALL) - { - if (!(tmp & GICR_PBASER_SHARE_MASK_ALL)) - { - /* - * The HW reports non-shareable, - * we must remove the cacheability attributes as well. - */ - val &= ~(GICR_PBASER_SHARE_MASK_ALL | GICR_PBASER_INNER_MASK_ALL); - val |= GICR_PBASER_nC; - HWREG64(gicr + GICR_PROPBASER) = val; - } - - if (!rt_hw_cpu_id()) - { - LOG_I("Using cache flushing for LPI property table"); - } - its->gic->redist_flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING; - } - - val = (paddr | GICR_PBASER_InnerShareable | GICR_PBASER_RaWaWb); - - HWREG64(gicr + GICR_PENDBASER) = val; - tmp = HWREG64(gicr + GICR_PENDBASER); - - if (its->gic->redist_flags & RDIST_FLAGS_FORCE_NON_SHAREABLE) - { - tmp &= ~GICR_PBASER_SHARE_MASK_ALL; - } - - if (!(tmp & GICR_PBASER_SHARE_MASK_ALL)) - { - /* - * The HW reports non-shareable, we must remove the - * cacheability attributes as well. - */ - val &= ~(GICR_PBASER_SHARE_MASK_ALL | GICR_PBASER_INNER_MASK_ALL); - val |= GICR_PBASER_nC; - HWREG64(gicr + GICR_PENDBASER) = val; - } - - /* Enable LPIs */ - val = HWREG32(gicr + GICR_CTLR); - val |= GICR_CTLR_ENABLE_LPIS; - HWREG32(gicr + GICR_CTLR) = val; - - rt_hw_barrier(dsb, sy); - -_out: - *gicr_rd_flags(its) |= RD_LOCAL_LPI_ENABLED; -} - -static void gicv3_its_cpu_init_collection(struct gicv3_its *its) -{ - rt_uint64_t target; - int cpu_id = rt_hw_cpu_id(); - struct its_command cmd; - struct its_collection *collection; - - if (HWREG64(its->base + GITS_TYPER) & GITS_TYPER_PTA) - { - target = (rt_uint64_t)rt_kmem_v2p(gicr_rd_base(its)); - } - else - { - /* Linear by GICR processor number */ - target = HWREG64(gicr_rd_base(its) + GICR_TYPER); - target = GICR_TYPER_CPU_NO(target) << 16; - } - - collection = &its->collections[cpu_id]; - collection->target_address = target; - collection->id = cpu_id; - - rt_memset(&cmd, 0, sizeof(cmd)); - its_encode_cmd(&cmd, GITS_CMD_MAPC); - its_encode_collection(&cmd, collection->id); - its_encode_target(&cmd, target); - its_encode_valid(&cmd, RT_TRUE); - its_cmd_submit_nomap(its, &cmd, cpu_id, RT_TRUE); - - rt_memset(&cmd, 0, sizeof(cmd)); - its_encode_cmd(&cmd, GITS_CMD_INVALL); - its_encode_collection(&cmd, collection->id); - its_cmd_submit_nomap(its, &cmd, cpu_id, RT_TRUE); -} - -static rt_err_t gicv3_its_irq_init(struct rt_pic *pic) -{ - rt_err_t err; - struct gicv3_its *its = raw_to_gicv3_its(pic); - - if ((err = redist_disable_lpis(its))) - { - return err; - } - - gicv3_its_cpu_init_lpis(its); - gicv3_its_cpu_init_collection(its); - - return RT_EOK; -} - -static void gicv3_its_irq_mask(struct rt_pic_irq *pirq) -{ - rt_uint8_t *conf = lpi_base_config(pirq->hwirq); - struct gicv3_its *its = raw_to_gicv3_its(pirq->pic); - - *conf &= ~GITS_LPI_CFG_ENABLED; - lpi_flush_config(its, conf, pirq); - - rt_pci_msi_mask_irq(pirq); -} - -static void gicv3_its_irq_unmask(struct rt_pic_irq *pirq) -{ - rt_uint8_t *conf = lpi_base_config(pirq->hwirq); - struct gicv3_its *its = raw_to_gicv3_its(pirq->pic); - - *conf |= GITS_LPI_CFG_ENABLED; - lpi_flush_config(its, conf, pirq); - - rt_pci_msi_unmask_irq(pirq); -} - -static rt_err_t gicv3_its_irq_set_priority(struct rt_pic_irq *pirq, rt_uint32_t priority) -{ - rt_uint8_t *conf = lpi_base_config(pirq->hwirq); - struct gicv3_its *its = raw_to_gicv3_its(pirq->pic); - - *conf = (priority << ITS_LPI_CONFIG_PROP_SHIFT) | (*conf & (~ITS_LPI_CONFIG_PROP_MASK)); - - return lpi_flush_config(its, conf, pirq); -} - -static rt_err_t gicv3_its_irq_set_affinity(struct rt_pic_irq *pirq, rt_bitmap_t *affinity) -{ - int cpu_id; - rt_err_t err; - struct its_map *map; - struct its_command cmd; - struct its_collection *collection; - struct gicv3_its *its = raw_to_gicv3_its(pirq->pic); - - map = pirq->msi_desc->priv; - cpu_id = rt_bitmap_next_set_bit(affinity, 0, RT_CPUS_NR); - collection = &its->collections[cpu_id]; - - if (collection->target_address == ~0ULL) - { - return -RT_EIO; - } - - if (map->cpu_id == cpu_id) - { - return RT_EOK; - } - - rt_memset(&cmd, 0, sizeof(cmd)); - its_encode_cmd(&cmd, GITS_CMD_MOVI); - its_encode_device_id(&cmd, map->device_id); - its_encode_event_id(&cmd, its_pirq_event_id(its, pirq)); - its_encode_collection(&cmd, collection->id); - - if (!(err = its_cmd_submit(its, &cmd, map, RT_TRUE))) - { - map->cpu_id = cpu_id; - } - - return err; -} - -static void gicv3_its_irq_compose_msi_msg(struct rt_pic_irq *pirq, struct rt_pci_msi_msg *msg) -{ - rt_ubase_t addr; - struct gicv3_its *its = raw_to_gicv3_its(pirq->pic); - - addr = (rt_ubase_t)its->base_phy + GITS_TRANSLATER; - - msg->address_hi = rt_upper_32_bits(addr); - msg->address_lo = rt_lower_32_bits(addr); - msg->data = its_pirq_event_id(its, pirq); -} - -static int gicv3_its_irq_alloc_msi(struct rt_pic *pic, struct rt_pci_msi_desc *msi_desc) -{ - rt_ubase_t level; - rt_uint32_t device_id = -1; - int irq = -1, hwirq, parent_irq, hwirq_index, lpi_base = 0; - struct its_map *map = RT_NULL, *map_tmp; - struct its_table *tbl; - struct its_command cmd; - struct rt_pic_irq *pirq; - struct rt_pci_device *pdev = msi_desc->pdev; - struct gicv3_its *its = raw_to_gicv3_its(pic); - struct rt_pic *ppic = &its->gic->parent; - - tbl = its_baser_type(its, GITS_BASER_TYPE_DEVICE); - RT_ASSERT(tbl != RT_NULL); - - if (!pdev->parent.ofw_node) - { - device_id = rt_pci_dev_id(pdev); - } - else - { - struct rt_ofw_cell_args args; - - for (int index = 0; ; ++index) - { - rt_err_t err = rt_ofw_parse_phandle_cells(pdev->parent.ofw_node, - "msi-parent", "#msi-cells", index, &args); - - if (err) - { - return (int)err; - } - - if (args.data == its->np) - { - device_id = args.args[0]; - } - - rt_ofw_node_put(args.data); - - if ((rt_int32_t)device_id >= 0) - { - break; - } - } - } - - if (device_id >= (1 << tbl->size_bits)) - { - LOG_E("Device ID = is %x not supported", device_id); - - return -RT_EINVAL; - } - - /* Find old map info */ - level = rt_spin_lock_irqsave(&map_lock); - rt_list_for_each_entry(map_tmp, &map_nodes, list) - { - if (map_tmp->device_id == device_id) - { - map = map_tmp; - lpi_base = map->lpi_base - 8192; - break; - } - } - rt_spin_unlock_irqrestore(&map_lock, level); - - if (!map) - { - rt_size_t itt_size; - - if (!(map = rt_calloc(1, sizeof(*map)))) - { - return -RT_ENOMEM; - } - - itt_size = tbl->itt_entries * (RT_FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, - HWREG64(its->base + GITS_TYPER)) + 1); - itt_size = rt_max_t(rt_size_t, itt_size, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; - - map->itt = rt_malloc_align(itt_size, ITS_ITT_ALIGN); - - if (!map->itt) - { - rt_free(map); - return -RT_ENOMEM; - } - - if (tbl->lvl2_bits) - { - void *lvl2_dte; - rt_uint64_t *entry; - - entry = tbl->base; - entry += device_id / (tbl->page_size / GITS_LVL1_ENTRY_SIZE); - - if (*entry) - { - lvl2_dte = (void *)(*entry - PV_OFFSET); - rt_page_ref_inc(lvl2_dte, tbl->lvl2_bits); - } - else - { - rt_size_t dte_size; - - lvl2_dte = rt_pages_alloc(tbl->lvl2_bits); - - if (!lvl2_dte) - { - rt_free_align(map->itt); - rt_free(map); - return -RT_ENOMEM; - } - - dte_size = rt_page_bits(tbl->lvl2_bits); - rt_memset(lvl2_dte, 0, dte_size); - - if (!(tbl->val & GITS_BASER_SHARE_MASK_ALL)) - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, lvl2_dte, dte_size); - } - - *entry = rt_cpu_to_le64((rt_uint64_t)rt_kmem_v2p(lvl2_dte) | GITS_BASER_VALID); - - if (!(tbl->val & GITS_BASER_SHARE_MASK_ALL)) - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, entry, sizeof(*entry)); - } - - rt_hw_dsb(); - } - - map->lvl2_dte = lvl2_dte; - } - - rt_memset(map->itt, 0, itt_size); - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, map->itt, itt_size); - } - msi_desc->priv = map; - - /* Alloc the LPI base on the first LPI */ - level = rt_spin_lock_irqsave(&lpis_lock); - hwirq_index = rt_bitmap_next_clear_bit(lpis_vectors, lpi_base, lpi_nr); - - if (hwirq_index >= lpi_nr) - { - irq = -RT_EEMPTY; - goto _out_lock; - } - - hwirq = 8192 + hwirq_index; - parent_irq = ppic->ops->irq_map(ppic, hwirq, RT_IRQ_MODE_EDGE_RISING); - if (parent_irq < 0) - { - irq = parent_irq; - goto _out_lock; - } - - irq = rt_pic_config_irq(pic, hwirq_index, hwirq); - if (irq < 0) - { - goto _out_lock; - } - pirq = rt_pic_find_irq(pic, hwirq_index); - - pirq->mode = RT_IRQ_MODE_EDGE_RISING; - rt_pic_cascade(pirq, parent_irq); - - rt_bitmap_set_bit(lpis_vectors, hwirq_index); - -_out_lock: - rt_spin_unlock_irqrestore(&lpis_lock, level); - - if (irq < 0) - { - return irq; - } - - if (map->its) - { - rt_ref_get(&map->ref); - } - else - { - rt_list_init(&map->list); - rt_ref_init(&map->ref); - map->its = its; - map->device_id = device_id; - map->lpi_base = hwirq; - - level = rt_spin_lock_irqsave(&map_lock); - rt_list_insert_before(&map_nodes, &map->list); - rt_spin_unlock_irqrestore(&map_lock, level); - } - - /* Default to CPU#0 */ - map->cpu_id = 0; - RT_IRQ_AFFINITY_SET(pirq->affinity, map->cpu_id); - - rt_memset(&cmd, 0, sizeof(cmd)); - its_encode_cmd(&cmd, GITS_CMD_MAPD); - its_encode_device_id(&cmd, device_id); - its_encode_size(&cmd, rt_ilog2(tbl->itt_entries) - 1); - its_encode_itt(&cmd, (rt_uint64_t)rt_kmem_v2p(map->itt)); - its_encode_valid(&cmd, RT_TRUE); - its_cmd_submit(its, &cmd, map, RT_FALSE); - - rt_memset(&cmd, 0, sizeof(cmd)); - its_encode_cmd(&cmd, GITS_CMD_MAPTI); - its_encode_device_id(&cmd, device_id); - its_encode_event_id(&cmd, its_pirq_event_id(its, pirq)); - its_encode_phys_id(&cmd, hwirq); - its_encode_collection(&cmd, its->collections[map->cpu_id].id); - its_cmd_submit(its, &cmd, map, RT_TRUE); - - return irq; -} - -static void its_map_release(struct rt_ref *r) -{ - rt_ubase_t level; - struct gicv3_its *its; - struct its_table *tbl; - struct its_command cmd; - struct its_map *map = rt_container_of(r, struct its_map, ref); - - its = map->its; - tbl = its_baser_type(its, GITS_BASER_TYPE_DEVICE); - - rt_memset(&cmd, 0, sizeof(cmd)); - its_encode_cmd(&cmd, GITS_CMD_MAPD); - its_encode_device_id(&cmd, map->device_id); - its_encode_size(&cmd, rt_ilog2(tbl->itt_entries) - 1); - its_encode_itt(&cmd, (rt_uint64_t)rt_kmem_v2p(map->itt)); - its_encode_valid(&cmd, RT_FALSE); - its_cmd_submit(its, &cmd, map, RT_TRUE); - - level = rt_spin_lock_irqsave(&map_lock); - rt_list_insert_before(&map_nodes, &map->list); - rt_spin_unlock_irqrestore(&map_lock, level); - - if (map->itt) - { - rt_free_align(map->itt); - } - if (map->lvl2_dte) - { - if (rt_page_ref_get(map->lvl2_dte, tbl->lvl2_bits) == 1) - { - rt_uint64_t *entry; - - entry = tbl->base + (map->device_id / (tbl->page_size / GITS_LVL1_ENTRY_SIZE)); - *entry = rt_cpu_to_le64(0); - - if (!(tbl->val & GITS_BASER_SHARE_MASK_ALL)) - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, entry, sizeof(*entry)); - } - } - rt_pages_free(map->lvl2_dte, tbl->lvl2_bits); - } - rt_free(map); -} - -static void gicv3_its_irq_free_msi(struct rt_pic *pic, int irq) -{ - rt_ubase_t level; - struct its_map *map; - struct its_command cmd; - struct rt_pic_irq *pirq; - struct gicv3_its *its = raw_to_gicv3_its(pic); - - pirq = rt_pic_find_pirq(pic, irq); - - if (!pirq) - { - return; - } - - map = pirq->msi_desc->priv; - - rt_memset(&cmd, 0, sizeof(cmd)); - its_encode_cmd(&cmd, GITS_CMD_DISCARD); - its_encode_device_id(&cmd, map->device_id); - its_encode_event_id(&cmd, its_pirq_event_id(its, pirq)); - its_cmd_submit(its, &cmd, map, RT_TRUE); - - rt_pic_uncascade(pirq); - - level = rt_spin_lock_irqsave(&lpis_lock); - rt_bitmap_clear_bit(lpis_vectors, pirq->hwirq - 8192); - rt_spin_unlock_irqrestore(&lpis_lock, level); - - rt_ref_put(&map->ref, its_map_release); -} - -static rt_err_t gicv3_its_irq_set_state(struct rt_pic *pic, int hwirq, int type, rt_bool_t state) -{ - struct its_map *map; - struct its_command cmd; - struct rt_pic_irq *pirq; - struct gicv3_its *its = raw_to_gicv3_its(pic); - - if (type != RT_IRQ_STATE_PENDING || hwirq > 8192 + lpi_nr) - { - return -RT_ENOSYS; - } - - if (!(pirq = rt_pic_find_irq(pic, hwirq - 8192))) - { - return -RT_ENOSYS; - } - - map = pirq->msi_desc->priv; - rt_memset(&cmd, 0, sizeof(cmd)); - - if (state) - { - its_encode_cmd(&cmd, GITS_CMD_INT); - its_encode_device_id(&cmd, map->device_id); - its_encode_event_id(&cmd, its_pirq_event_id(its, pirq)); - } - else - { - its_encode_cmd(&cmd, GITS_CMD_CLEAR); - its_encode_device_id(&cmd, map->device_id); - its_encode_event_id(&cmd, its_pirq_event_id(its, pirq)); - } - - its_cmd_submit(its, &cmd, map, RT_TRUE); - - return RT_EOK; -} - -const static struct rt_pic_ops gicv3_its_ops = -{ - .name = "GICv3-ITS", - .irq_init = gicv3_its_irq_init, - .irq_ack = rt_pic_irq_parent_ack, - .irq_mask = gicv3_its_irq_mask, - .irq_unmask = gicv3_its_irq_unmask, - .irq_eoi = rt_pic_irq_parent_eoi, - .irq_set_priority = gicv3_its_irq_set_priority, - .irq_set_affinity = gicv3_its_irq_set_affinity, - .irq_compose_msi_msg = gicv3_its_irq_compose_msi_msg, - .irq_alloc_msi = gicv3_its_irq_alloc_msi, - .irq_free_msi = gicv3_its_irq_free_msi, - .irq_set_state = gicv3_its_irq_set_state, - .flags = RT_PIC_F_IRQ_ROUTING, -}; - -static rt_ssize_t its_baser_page_size(struct gicv3_its *its, struct its_table *tbl) -{ - rt_size_t page_size = 64 * SIZE_KB; - - while (page_size) - { - rt_uint64_t val, baser_page_size; - rt_off_t baser = GITS_BASERn((int)(tbl - its->tbls)); - - val = its_readq(its, baser); - val &= ~GITS_BASER_PAGE_SIZE_MASK; - - switch (page_size) - { - case 64 * SIZE_KB: - baser_page_size = GITS_BASER_PAGE_SIZE_64K; - break; - case 16 * SIZE_KB: - baser_page_size = GITS_BASER_PAGE_SIZE_16K; - break; - case 4 * SIZE_KB: - default: - baser_page_size = GITS_BASER_PAGE_SIZE_4K; - break; - } - - baser_page_size >>= GITS_BASER_PAGE_SIZE_SHIFT; - - val |= RT_FIELD_PREP(GITS_BASER_PAGE_SIZE_MASK, baser_page_size); - its_writeq(its, baser, val); - tbl->val = its_readq(its, baser); - - if (RT_FIELD_GET(GITS_BASER_PAGE_SIZE_MASK, tbl->val) == baser_page_size) - { - break; - } - - switch (page_size) - { - case 64 * SIZE_KB: - page_size = 16 * SIZE_KB; - break; - case 16 * SIZE_KB: - page_size = 4 * SIZE_KB; - break; - case 4 * SIZE_KB: - default: - return -RT_EINVAL; - } - } - - return page_size; -} - -static rt_err_t its_table_init(struct gicv3_its *its) -{ - int inited = 0; - rt_off_t baser; - rt_bool_t indirect = RT_FALSE; - rt_size_t pages_nr, alloc_size; - rt_uint64_t val, type, entry_size, share, cache; - struct its_table *tbl; - - share = GITS_BASER_InnerShareable; - cache = GITS_BASER_RaWaWb; - - for (int i = 0; i < RT_ARRAY_SIZE(its->tbls); ++i) - { - tbl = &its->tbls[i]; - - val = its_readq(its, GITS_BASERn(i)); - type = GITS_BASER_TYPE(val); - - if (type != GITS_BASER_TYPE_DEVICE && - type != GITS_BASER_TYPE_COLLECTION) - { - continue; - } - - tbl->page_size = its_baser_page_size(its, tbl); - - if (tbl->page_size < 0) - { - continue; - } - - baser = GITS_BASERn((int)(tbl - its->tbls)); - entry_size = GITS_BASER_ENTRY_SIZE(val); - - if (type == GITS_BASER_TYPE_DEVICE) - { - tbl->size_bits = its_device_id_bits(its); - LOG_D("Device Max IDs = %lu", 1UL << tbl->size_bits); - - /* For MSI-X */ - tbl->itt_entries = 2048; - while (MAX_HANDLERS / tbl->itt_entries < (1 << tbl->size_bits) && - tbl->itt_entries > 32) - { - tbl->itt_entries >>= 1; - } - } - - its_writeq(its, baser, tbl->val | GITS_BASER_INDIRECT); - tbl->val = its_readq(its, baser); - - indirect = !!(tbl->val & GITS_BASER_INDIRECT); - if (indirect && type == GITS_BASER_TYPE_DEVICE) - { - /* The size of the level 2 table is equal to ITS page size */ - tbl->lvl2_bits = tbl->size_bits - rt_ilog2(tbl->page_size / (int)entry_size); - - /* Get level 1 entries count */ - alloc_size = (1 << tbl->size_bits) / (tbl->page_size / entry_size); - alloc_size *= GITS_LVL1_ENTRY_SIZE; - } - else - { - alloc_size = (1 << tbl->size_bits) * entry_size; - indirect = RT_FALSE; - } - - tbl->base = rt_malloc_align(alloc_size, tbl->page_size); - pages_nr = alloc_size / tbl->page_size; - - if (!tbl->base) - { - return -RT_ENOMEM; - } - - if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_22375) - { - cache = GITS_BASER_nCnB; - } - - if (its->flags & ITS_FLAGS_FORCE_NON_SHAREABLE) - { - cache = GITS_BASER_nC; - share = 0; - } - - val = ((rt_ubase_t)rt_kmem_v2p(tbl->base) | - (type << GITS_BASER_TYPE_SHIFT) | - ((entry_size - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) | - (pages_nr << GITS_BASER_PAGES_SHIFT) | - cache | share | GITS_BASER_VALID); - val |= indirect ? GITS_BASER_INDIRECT : 0; - - switch (tbl->page_size) - { - case 4 * SIZE_KB: - val |= GITS_BASER_PAGE_SIZE_4K; - break; - case 16 * SIZE_KB: - val |= GITS_BASER_PAGE_SIZE_16K; - break; - case 64 * SIZE_KB: - val |= GITS_BASER_PAGE_SIZE_64K; - break; - } - - its_writeq(its, baser, val); - tbl->val = its_readq(its, baser); - - rt_memset(tbl->base, 0, alloc_size); - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, tbl->base, alloc_size); - - cache = tbl->val & GITS_BASER_INNER_MASK_ALL; - share = tbl->val & GITS_BASER_SHARE_MASK_ALL; - - ++inited; - } - - return inited == 2 ? RT_EOK : -RT_ENOSYS; -} - -static rt_err_t its_cmd_queue_init(struct gicv3_its *its) -{ - void *cmd_phy_base; - rt_uint64_t baser, tmp; - - its->cmd_base = rt_malloc_align(ITS_CMD_QUEUE_SIZE, ITS_CMD_QUEUE_ALIGN); - - if (!its->cmd_base) - { - return -RT_ENOMEM; - } - - its->cmd_idx = 0; - rt_memset(its->cmd_base, 0, ITS_CMD_QUEUE_SIZE); - - cmd_phy_base = rt_kmem_v2p(its->cmd_base); - - baser = GITS_CBASER_VALID | GITS_CBASER_RaWaWb | GITS_CBASER_InnerShareable | \ - ((rt_uint64_t)cmd_phy_base) | (ITS_CMD_QUEUE_SIZE / (4 * SIZE_KB) - 1); - - its_writeq(its, GITS_CBASER, baser); - tmp = its_readq(its, GITS_CBASER); - - if (its->flags & ITS_FLAGS_FORCE_NON_SHAREABLE) - { - tmp &= ~GITS_CBASER_SHARE_MASK_ALL; - } - - if ((tmp ^ baser) & GITS_CBASER_SHARE_MASK_ALL) - { - if (!(tmp & GITS_CBASER_SHARE_MASK_ALL)) - { - /* The HW reports non-shareable, we must remove the cacheability attributes as well */ - baser &= ~(GITS_CBASER_SHARE_MASK_ALL | GITS_CBASER_INNER_MASK_ALL); - baser |= GITS_CBASER_nC; - - its_writeq(its, GITS_CBASER, baser); - } - - LOG_I("Using cache flushing for CMD queue"); - its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING; - - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, its->cmd_base, ITS_CMD_QUEUE_SIZE); - } - - /* Get the next command from the start of the buffer */ - its_writeq(its, GITS_CWRITER, 0); - - return RT_EOK; -} - -static rt_err_t its_lpi_table_init(struct gicv3 *gic) -{ - rt_size_t lpi_table_size, lpi_pending_table_size; - rt_uint32_t numlpis = 1UL << GICD_TYPER_NUM_LPIS(gic->gicd_typer); - - if (HWREG32(gicr_rd_base_percpu(gic) + GICR_CTLR) & GICR_CTLR_ENABLE_LPIS) - { - gic->redist_flags |= RDIST_FLAGS_RD_TABLES_PREALLOCATED; - gic->redist_flags |= RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING; - - LOG_I("Using preallocated redistributor tables"); - } - - lpi_id_bits = GICD_TYPER_ID_BITS(gic->gicd_typer); - - if (gic->redist_flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED) - { - rt_uint64_t val = HWREG64(gicr_rd_base_percpu(gic) + GICR_PROPBASER); - lpi_id_bits = rt_min_t(rt_uint32_t, lpi_id_bits, (val & GICR_PROPBASER_IDBITS_MASK) + 1); - } - - lpi_nr = rt_min_t(rt_size_t, (1UL << lpi_id_bits) - 8192, gic->lpi_nr); - lpi_id_bits = __rt_clz(lpi_nr + 8192); - - if (numlpis > 2 && numlpis > lpi_nr) - { - lpi_nr = numlpis; - LOG_W("Using hypervisor restricted LPI range [%u]", lpi_nr); - } - - gic->lpi_nr = lpi_nr; - - /* LPI Configuration table entry is 1 byte, Pending table bytes is N / 8. */ - lpi_table_size = RT_GENMASK(lpi_id_bits, 0); - lpi_pending_table_size = lpi_table_size / 8; - - lpi_table = rt_malloc_align(lpi_table_size, ITS_LPI_CONFIG_TABLE_ALIGN); - lpi_pending_table = rt_malloc_align(lpi_pending_table_size, ITS_LPI_PENDING_TABLE_ALIGN); - lpis_vectors = rt_calloc(1, RT_BITMAP_LEN(lpi_nr) * sizeof(rt_bitmap_t)); - - if (!lpi_table || !lpi_pending_table || !lpis_vectors) - { - if (lpi_table) - { - rt_free_align(lpi_table); - } - if (lpi_pending_table) - { - rt_free_align(lpi_pending_table); - } - if (lpis_vectors) - { - rt_free_align(lpis_vectors); - } - - lpi_table = RT_NULL; - lpi_pending_table = RT_NULL; - lpis_vectors = RT_NULL; - - return -RT_ENOMEM; - } - - /* Set the default configuration */ - rt_memset(lpi_table, ITS_LPI_CONFIG_PROP_DEFAULT_PRIO | GITS_LPI_CFG_GROUP1, lpi_table_size); - /* - * We should make a full mask size with lpi_id_bits, - * otherwise 'undefined' LPI will occur. - */ - rt_memset(lpi_pending_table, 0, lpi_pending_table_size); - - /* Flush the table to memory */ - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, lpi_table, lpi_table_size); - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, lpi_pending_table, lpi_pending_table_size); - - LOG_D("ITS: Allocator initialized for %u LPIs", lpi_nr); - - return RT_EOK; -} - -static void its_init_fail(struct gicv3_its *its) -{ - if (its->base) - { - rt_iounmap(its->base); - } - - if (its->cmd_base) - { - rt_free_align(its->cmd_base); - } - - for (int i = 0; i < RT_ARRAY_SIZE(its->tbls); ++i) - { - struct its_table *tbl = &its->tbls[i]; - - if (tbl->base) - { - rt_free_align(tbl->base); - } - } - - rt_list_remove(&its->list); - rt_free(its); -} - -static rt_err_t its_quirk_cavium_22375(void *data) -{ - struct gicv3_its *its = data; - - its->flags |= ITS_FLAGS_WORKAROUND_CAVIUM_22375; - - return RT_EOK; -} - -static rt_err_t its_enable_rockchip(void *data) -{ - struct gicv3_its *its = data; - struct gicv3 *gic = its->gic; - - if (!rt_ofw_machine_is_compatible("rockchip,rk3566") && - !rt_ofw_machine_is_compatible("rockchip,rk3567") && - !rt_ofw_machine_is_compatible("rockchip,rk3568") && - !rt_ofw_machine_is_compatible("rockchip,rk3588") && - !rt_ofw_machine_is_compatible("rockchip,rk3588s")) - { - return -RT_EINVAL; - } - - its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE; - gic->redist_flags |= RDIST_FLAGS_FORCE_NON_SHAREABLE; - - return RT_EOK; -} - -static rt_err_t its_set_non_coherent(void *data) -{ - struct gicv3_its *its = data; - - if (!rt_ofw_prop_read_bool(its->np, "dma-noncoherent")) - { - return -RT_EINVAL; - } - - its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE; - - return RT_EOK; -} - -static const struct gic_quirk _its_quirks[] = -{ - { - .desc = "ITS: Cavium ThunderX errata: 22375, 24313", - .iidr = 0xa100034c, - .iidr_mask = 0xffff0fff, - .init = its_quirk_cavium_22375, - }, - { - .desc = "ITS: Rockchip erratum RK3566 ~ RK3588", - .iidr = 0x0201743b, - .iidr_mask = 0xffffffff, - .init = its_enable_rockchip, - }, - { - .desc = "ITS: non-coherent attribute", - .compatible = "arm,gic-v3-its", - .init = its_set_non_coherent, - }, - { /* sentinel */ } -}; - -static const struct rt_ofw_node_id gicv3_its_ofw_match[] = -{ - { .compatible = "arm,gic-v3-its" }, - { /* sentinel */ } -}; - -rt_err_t gicv3_its_ofw_probe(struct rt_ofw_node *np, const struct rt_ofw_node_id *id) -{ - rt_err_t err = -RT_EEMPTY; - struct rt_ofw_node *its_np; - struct gicv3_its *its, *its_next; - - rt_ofw_foreach_available_child_node(np, its_np) - { - if (!rt_ofw_node_match(its_np, gicv3_its_ofw_match)) - { - continue; - } - - if (!rt_ofw_prop_read_bool(its_np, "msi-controller")) - { - continue; - } - - if (!(its = rt_calloc(1, sizeof(struct gicv3_its)))) - { - rt_ofw_node_put(its_np); - - err = -RT_ENOMEM; - goto _free_all; - } - - its->base = rt_ofw_iomap(its_np, 0); - - if (!its->base) - { - LOG_E("%s: IO map failed", rt_ofw_node_full_name(its_np)); - its_init_fail(its); - continue; - } - - /* - * Make sure ALL the ITS are reset before we probe any, - * as they may be sharing memory - */ - for (int i = 0; i < GITS_BASER_NR_REGS; ++i) - { - its_writeq(its, GITS_BASER + (i << 3), 0); - } - - its->np = its_np; - rt_list_init(&its->list); - rt_list_insert_before(&its_nodes, &its->list); - } - - if (!rt_list_isempty(&its_nodes)) - { - if ((err = its_lpi_table_init(rt_ofw_data(np)))) - { - goto _free_all; - } - } - - rt_list_for_each_entry_safe(its, its_next, &its_nodes, list) - { - rt_uint32_t ctlr; - - its->base_phy = rt_kmem_v2p(its->base); - its->gic = rt_ofw_data(np); - - gic_common_init_quirk_hw(HWREG32(its->base + GITS_IIDR), _its_quirks, its); - gic_common_init_quirk_ofw(its->np, _its_quirks, its); - - if ((err = its_cmd_queue_init(its))) - { - goto _fail; - } - rt_spin_lock_init(&its->cmd_lock); - - if ((err = its_table_init(its))) - { - goto _fail; - } - - for (int i = 0; i < RT_CPUS_NR; ++i) - { - its->collections[i].target_address = ~0ULL; - } - - ctlr = its_readl(its, GITS_CTLR); - ctlr |= GITS_CTLR_ENABLE; - its_writel(its, GITS_CTLR, ctlr); - - its->parent.priv_data = its; - its->parent.ops = &gicv3_its_ops; - - rt_pic_linear_irq(&its->parent, its->gic->lpi_nr); - rt_pic_user_extends(&its->parent); - - its_np = its->np; - rt_ofw_data(its_np) = &its->parent; - rt_ofw_node_set_flag(its_np, RT_OFW_F_READLY); - - continue; - - _fail: - its_init_fail(its); - - if (err == -RT_ENOMEM) - { - break; - } - } - - if (rt_list_isempty(&its_nodes) && lpis_vectors) - { - rt_free(lpis_vectors); - rt_free_align(lpi_table); - rt_free_align(lpi_pending_table); - lpis_vectors = RT_NULL; - } - - return err; - -_free_all: - rt_list_for_each_entry_safe(its, its_next, &its_nodes, list) - { - rt_free(its); - rt_list_remove(&its->list); - } - - return err; -} diff --git a/rt-thread/components/drivers/pic/pic-gicv3.c b/rt-thread/components/drivers/pic/pic-gicv3.c index 7a11f35..c5e4bc7 100644 --- a/rt-thread/components/drivers/pic/pic-gicv3.c +++ b/rt-thread/components/drivers/pic/pic-gicv3.c @@ -216,11 +216,6 @@ static void gicv3_dist_init(void) LOG_D("%d SPIs implemented", _gic.line_nr - 32); LOG_D("%d Extended SPIs implemented", _gic.espi_nr); - if (_gic.skip_init) - { - goto _get_max_irq; - } - /* Disable the distributor */ HWREG32(base + GICD_CTLR) = 0; gicv3_dist_wait_for_rwp(); @@ -271,26 +266,20 @@ static void gicv3_dist_init(void) HWREG64(base + GICD_IROUTERnE + i * 8) = affinity; } -_get_max_irq: - if (GICD_TYPER_NUM_LPIS(_gic.gicd_typer) > 1) + if (GICD_TYPER_NUM_LPIS(_gic.gicd_typer)) { /* Max LPI = 8192 + Math.pow(2, num_LPIs + 1) - 1 */ - rt_size_t num_lpis = 1UL << (GICD_TYPER_NUM_LPIS(_gic.gicd_typer) + 1); + rt_size_t num_lpis = (1 << (GICD_TYPER_NUM_LPIS(_gic.gicd_typer) + 1)) + 1; - _gic.lpi_nr = rt_min_t(int, num_lpis, 1UL << GICD_TYPER_ID_BITS(_gic.gicd_typer)); + _gic.lpi_nr = rt_min_t(int, num_lpis, 1 << GICD_TYPER_ID_BITS(_gic.gicd_typer)); } else { - _gic.lpi_nr = 1UL << GICD_TYPER_ID_BITS(_gic.gicd_typer); + _gic.lpi_nr = 1 << GICD_TYPER_ID_BITS(_gic.gicd_typer); } /* SPI + eSPI + LPIs */ - _gic.irq_nr = _gic.line_nr - 32 + _gic.espi_nr; -#ifdef RT_PIC_ARM_GIC_V3_ITS - /* ITS will allocate the same number of lpi PIRQs */ - _gic.lpi_nr = rt_min_t(rt_size_t, RT_PIC_ARM_GIC_V3_ITS_IRQ_MAX, _gic.lpi_nr); - _gic.irq_nr += _gic.lpi_nr; -#endif + _gic.irq_nr = _gic.line_nr - 32 + _gic.espi_nr + _gic.lpi_nr; } static void gicv3_redist_enable(rt_bool_t enable) @@ -400,8 +389,6 @@ static void gicv3_cpu_init(void) int cpu_id = rt_hw_cpu_id(); #ifdef ARCH_SUPPORT_HYP _gicv3_eoi_mode_ns = RT_TRUE; -#else - _gicv3_eoi_mode_ns = !!rt_ofw_bootargs_select("pic.gicv3_eoimode", 0); #endif base = gicv3_percpu_redist_sgi_base(); @@ -713,7 +700,6 @@ static int gicv3_irq_map(struct rt_pic *pic, int hwirq, rt_uint32_t mode) if (pirq && hwirq >= GIC_SGI_NR) { pirq->mode = mode; - pirq->priority = GICD_INT_DEF_PRI; switch (gicv3_hwirq_type(hwirq)) { @@ -722,6 +708,7 @@ static int gicv3_irq_map(struct rt_pic *pic, int hwirq, rt_uint32_t mode) break; case SPI_TYPE: case ESPI_TYPE: + pirq->priority = GICD_INT_DEF_PRI; RT_IRQ_AFFINITY_SET(pirq->affinity, _init_cpu_id); default: break; @@ -836,18 +823,7 @@ static rt_bool_t gicv3_handler(void *data) } else { - int irq_index; - - if (hwirq < 8192) - { - irq_index = hwirq - GIC_SGI_NR; - } - else - { - irq_index = gic->irq_nr - gic->lpi_nr + hwirq - 8192; - } - - pirq = rt_pic_find_irq(&gic->parent, irq_index); + pirq = rt_pic_find_irq(&gic->parent, hwirq - GIC_SGI_NR); } gicv3_irq_ack(pirq); @@ -1069,7 +1045,6 @@ static rt_err_t gicv3_ofw_init(struct rt_ofw_node *np, const struct rt_ofw_node_ redist_stride = 0; } _gic.redist_stride = redist_stride; - _gic.skip_init = rt_ofw_prop_read_bool(np, "skip-init"); gic_common_init_quirk_ofw(np, _gicv3_quirks, &_gic.parent); gicv3_init(); diff --git a/rt-thread/components/drivers/pic/pic-gicv3.h b/rt-thread/components/drivers/pic/pic-gicv3.h index 61c5ae1..6046d9b 100644 --- a/rt-thread/components/drivers/pic/pic-gicv3.h +++ b/rt-thread/components/drivers/pic/pic-gicv3.h @@ -12,8 +12,8 @@ * 2023-02-01 GuEe-GUI move macros to header */ -#ifndef __PIC_GICV3_H__ -#define __PIC_GICV3_H__ +#ifndef __IRQ_GICV3_H__ +#define __IRQ_GICV3_H__ #include @@ -101,8 +101,6 @@ #define GICR_CTLR_IR (1UL << 2) #define GICR_CTLR_RWP (1UL << 3) -#define GICR_TYPER_CPU_NO(r) (((r) >> 8) & 0xffff) - #define GICR_RD_BASE_SIZE (64 * SIZE_KB) #define GICR_SGI_OFFSET (64 * SIZE_KB) #define GICR_SGI_BASE_SIZE GICR_SGI_OFFSET @@ -154,142 +152,66 @@ #define GITS_CTLR 0x0000 #define GITS_IIDR 0x0004 #define GITS_TYPER 0x0008 +#define GITS_MPAMIDR 0x0010 +#define GITS_PARTIDR 0x0014 #define GITS_MPIDR 0x0018 -#define GITS_CBASER 0x0080 +#define GITS_STATUSR 0x0040 +#define GITS_UMSIR 0x0048 +#define GITS_CBASER 0x0048 #define GITS_CWRITER 0x0088 #define GITS_CREADR 0x0090 -#define GITS_BASER 0x0100 -#define GITS_IDREGS_BASE 0xffd0 -#define GITS_PIDR0 0xffe0 -#define GITS_PIDR1 0xffe4 -#define GITS_PIDR2 GICR_PIDR2 -#define GITS_PIDR4 0xffd0 -#define GITS_CIDR0 0xfff0 -#define GITS_CIDR1 0xfff4 -#define GITS_CIDR2 0xfff8 -#define GITS_CIDR3 0xfffc - -#define GITS_TRANSLATER 0x10040 - -#define GITS_SGIR 0x20020 - -#define GITS_SGIR_VPEID RT_GENMASK_ULL(47, 32) -#define GITS_SGIR_VINTID RT_GENMASK_ULL(3, 0) - -#define GITS_CTLR_ENABLE (1U << 0) -#define GITS_CTLR_ImDe (1U << 1) -#define GITS_CTLR_ITS_NUMBER_SHIFT 4 -#define GITS_CTLR_ITS_NUMBER (0xFU << GITS_CTLR_ITS_NUMBER_SHIFT) -#define GITS_CTLR_QUIESCENT (1U << 31) - -#define GITS_TYPER_PLPIS (1UL << 0) -#define GITS_TYPER_VLPIS (1UL << 1) -#define GITS_TYPER_ITT_ENTRY_SIZE_SHIFT 4 -#define GITS_TYPER_ITT_ENTRY_SIZE RT_GENMASK_ULL(7, 4) -#define GITS_TYPER_IDBITS_SHIFT 8 -#define GITS_TYPER_DEVBITS_SHIFT 13 -#define GITS_TYPER_DEVBITS RT_GENMASK_ULL(17, 13) -#define GITS_TYPER_PTA (1UL << 19) -#define GITS_TYPER_HCC_SHIFT 24 -#define GITS_TYPER_HCC(r) (((r) >> GITS_TYPER_HCC_SHIFT) & 0xff) -#define GITS_TYPER_VMOVP (1ULL << 37) -#define GITS_TYPER_VMAPP (1ULL << 40) -#define GITS_TYPER_SVPET RT_GENMASK_ULL(42, 41) +#define GITS_BASER 0x0100 /* 0x0100~0x0138 */ /* * ITS commands */ -#define GITS_CMD_MAPD 0x08 -#define GITS_CMD_MAPC 0x09 -#define GITS_CMD_MAPTI 0x0a -#define GITS_CMD_MAPI 0x0b -#define GITS_CMD_MOVI 0x01 -#define GITS_CMD_DISCARD 0x0f -#define GITS_CMD_INV 0x0c -#define GITS_CMD_MOVALL 0x0e -#define GITS_CMD_INVALL 0x0d -#define GITS_CMD_INT 0x03 -#define GITS_CMD_CLEAR 0x04 -#define GITS_CMD_SYNC 0x05 +#define GITS_CMD_MAPD 0x08 +#define GITS_CMD_MAPC 0x09 +#define GITS_CMD_MAPTI 0x0a +#define GITS_CMD_MAPI 0x0b +#define GITS_CMD_MOVI 0x01 +#define GITS_CMD_DISCARD 0x0f +#define GITS_CMD_INV 0x0c +#define GITS_CMD_MOVALL 0x0e +#define GITS_CMD_INVALL 0x0d +#define GITS_CMD_INT 0x03 +#define GITS_CMD_CLEAR 0x04 +#define GITS_CMD_SYNC 0x05 /* ITS Config Area */ -#define GITS_LPI_CFG_GROUP1 (1 << 1) -#define GITS_LPI_CFG_ENABLED (1 << 0) +#define GITS_LPI_CFG_GROUP1 (1 << 1) +#define GITS_LPI_CFG_ENABLED (1 << 0) /* ITS Command Queue Descriptor */ -#define GITS_BASER_SHAREABILITY_SHIFT 10 -#define GITS_BASER_INNER_CACHEABILITY_SHIFT 59 -#define GITS_BASER_OUTER_CACHEABILITY_SHIFT 53 #define GITS_CBASER_VALID (1UL << 63) -#define GITS_CBASER_SHAREABILITY_SHIFT 10 -#define GITS_CBASER_INNER_CACHEABILITY_SHIFT 59 -#define GITS_CBASER_OUTER_CACHEABILITY_SHIFT 53 -#define GICR_PBASER_SHAREABILITY_SHIFT 10 -#define GICR_PBASER_INNER_CACHEABILITY_SHIFT 7 -#define GICR_PBASER_OUTER_CACHEABILITY_SHIFT 56 +#define GITS_CBASER_SHAREABILITY_SHIFT (10) +#define GITS_CBASER_INNER_CACHEABILITY_SHIFT (59) +#define GITS_CBASER_OUTER_CACHEABILITY_SHIFT (53) -#define GITS_BASER_NR_REGS 8 -#define GITS_BASERn(idx) (GITS_BASER + sizeof(rt_uint64_t) * idx) - -#define GITS_BASER_VALID (1ULL << 63) -#define GITS_BASER_INDIRECT (1ULL << 62) -#define GITS_BASER_TYPE_SHIFT 56 -#define GITS_BASER_TYPE(r) (((r) >> GITS_BASER_TYPE_SHIFT) & 7) -#define GITS_BASER_ENTRY_SIZE_SHIFT 48 -#define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1) -#define GITS_BASER_PAGE_SIZE_SHIFT 8 -#define GITS_BASER_PAGE_SIZE_4K (0ULL << GITS_BASER_PAGE_SIZE_SHIFT) -#define GITS_BASER_PAGE_SIZE_16K (1ULL << GITS_BASER_PAGE_SIZE_SHIFT) -#define GITS_BASER_PAGE_SIZE_64K (2ULL << GITS_BASER_PAGE_SIZE_SHIFT) -#define GITS_BASER_PAGE_SIZE_MASK (3ULL << GITS_BASER_PAGE_SIZE_SHIFT) -#define GITS_BASER_PAGES_SHIFT 0 - -#define GITS_LVL1_ENTRY_SIZE 8UL - -#define GITS_BASER_TYPE_NONE 0 -#define GITS_BASER_TYPE_DEVICE 1 -#define GITS_BASER_TYPE_VPE 2 -#define GITS_BASER_TYPE_RESERVED3 3 -#define GITS_BASER_TYPE_COLLECTION 4 -#define GITS_BASER_TYPE_RESERVED5 5 -#define GITS_BASER_TYPE_RESERVED6 6 -#define GITS_BASER_TYPE_RESERVED7 7 +#define GITS_TRANSLATION_TABLE_DESCRIPTORS_NR 8 #define GITS_BASER_CACHEABILITY(reg, inner_outer, type) \ - (GIC_BASER_CACHE_##type << reg##_##inner_outer##_CACHEABILITY_SHIFT) + (GITS_CBASER_CACHE_##type << reg##_##inner_outer##_CACHEABILITY_SHIFT) #define GITS_BASER_SHAREABILITY(reg, type) \ - (GIC_BASER_##type << reg##_SHAREABILITY_SHIFT) + (GITS_CBASER_##type << reg##_SHAREABILITY_SHIFT) -#define GIC_BASER_CACHE_DnGnRnE 0x0UL /* Device-nGnRnE. */ -#define GIC_BASER_CACHE_NIN 0x1UL /* Normal Inner Non-cacheable. */ -#define GIC_BASER_CACHE_NIRAWT 0x2UL /* Normal Inner Cacheable Read-allocate, Write-through. */ -#define GIC_BASER_CACHE_NIRAWB 0x3UL /* Normal Inner Cacheable Read-allocate, Write-back. */ -#define GIC_BASER_CACHE_NIWAWT 0x4UL /* Normal Inner Cacheable Write-allocate, Write-through. */ -#define GIC_BASER_CACHE_NIWAWB 0x5UL /* Normal Inner Cacheable Write-allocate, Write-back. */ -#define GIC_BASER_CACHE_NIRAWAWT 0x6UL /* Normal Inner Cacheable Read-allocate, Write-allocate, Write-through. */ -#define GIC_BASER_CACHE_NIRAWAWB 0x7UL /* Normal Inner Cacheable Read-allocate, Write-allocate, Write-back. */ -#define GIC_BASER_CACHE_MASK 0x7UL -#define GIC_BASER_SHARE_NS 0x0UL /* Non-shareable. */ -#define GIC_BASER_SHARE_IS 0x1UL /* Inner Shareable. */ -#define GIC_BASER_SHARE_OS 0x2UL /* Outer Shareable. */ -#define GIC_BASER_SHARE_RES 0x3UL /* Reserved. Treated as 0b00 */ -#define GIC_BASER_SHARE_MASK 0x3UL - -#define GITS_BASER_InnerShareable GITS_BASER_SHAREABILITY(GITS_BASER, SHARE_IS) -#define GITS_BASER_SHARE_MASK_ALL GITS_BASER_SHAREABILITY(GITS_BASER, SHARE_MASK) -#define GITS_BASER_INNER_MASK_ALL GITS_BASER_CACHEABILITY(GITS_BASER, INNER, MASK) -#define GITS_BASER_nCnB GITS_BASER_CACHEABILITY(GITS_BASER, INNER, DnGnRnE) -#define GITS_BASER_nC GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIN) -#define GITS_BASER_RaWt GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIRAWT) -#define GITS_BASER_RaWb GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIRAWB) -#define GITS_BASER_WaWt GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIWAWT) -#define GITS_BASER_WaWb GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIWAWB) -#define GITS_BASER_RaWaWt GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIRAWAWT) -#define GITS_BASER_RaWaWb GITS_BASER_CACHEABILITY(GITS_BASER, INNER, NIRAWAWB) +#define GITS_CBASER_CACHE_DnGnRnE 0x0UL /* Device-nGnRnE. */ +#define GITS_CBASER_CACHE_NIN 0x1UL /* Normal Inner Non-cacheable. */ +#define GITS_CBASER_CACHE_NIRAWT 0x2UL /* Normal Inner Cacheable Read-allocate, Write-through. */ +#define GITS_CBASER_CACHE_NIRAWB 0x3UL /* Normal Inner Cacheable Read-allocate, Write-back. */ +#define GITS_CBASER_CACHE_NIWAWT 0x4UL /* Normal Inner Cacheable Write-allocate, Write-through. */ +#define GITS_CBASER_CACHE_NIWAWB 0x5UL /* Normal Inner Cacheable Write-allocate, Write-back. */ +#define GITS_CBASER_CACHE_NIRAWAWT 0x6UL /* Normal Inner Cacheable Read-allocate, Write-allocate, Write-through. */ +#define GITS_CBASER_CACHE_NIRAWAWB 0x7UL /* Normal Inner Cacheable Read-allocate, Write-allocate, Write-back. */ +#define GITS_CBASER_CACHE_MASK 0x7UL +#define GITS_CBASER_SHARE_NS 0x0UL /* Non-shareable. */ +#define GITS_CBASER_SHARE_IS 0x1UL /* Inner Shareable. */ +#define GITS_CBASER_SHARE_OS 0x2UL /* Outer Shareable. */ +#define GITS_CBASER_SHARE_RES 0x3UL /* Reserved. Treated as 0b00 */ +#define GITS_CBASER_SHARE_MASK 0x3UL #define GITS_CBASER_InnerShareable GITS_BASER_SHAREABILITY(GITS_CBASER, SHARE_IS) #define GITS_CBASER_SHARE_MASK_ALL GITS_BASER_SHAREABILITY(GITS_CBASER, SHARE_MASK) -#define GITS_CBASER_INNER_MASK_ALL GITS_BASER_CACHEABILITY(GITS_CBASER, INNER, MASK) #define GITS_CBASER_nCnB GITS_BASER_CACHEABILITY(GITS_CBASER, INNER, DnGnRnE) #define GITS_CBASER_nC GITS_BASER_CACHEABILITY(GITS_CBASER, INNER, NIN) #define GITS_CBASER_RaWt GITS_BASER_CACHEABILITY(GITS_CBASER, INNER, NIRAWT) @@ -299,18 +221,6 @@ #define GITS_CBASER_RaWaWt GITS_BASER_CACHEABILITY(GITS_CBASER, INNER, NIRAWAWT) #define GITS_CBASER_RaWaWb GITS_BASER_CACHEABILITY(GITS_CBASER, INNER, NIRAWAWB) -#define GICR_PBASER_InnerShareable GITS_BASER_SHAREABILITY(GICR_PBASER, SHARE_IS) -#define GICR_PBASER_SHARE_MASK_ALL GITS_BASER_SHAREABILITY(GICR_PBASER, SHARE_MASK) -#define GICR_PBASER_INNER_MASK_ALL GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, MASK) -#define GICR_PBASER_nCnB GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, DnGnRnE) -#define GICR_PBASER_nC GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIN) -#define GICR_PBASER_RaWt GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIRAWT) -#define GICR_PBASER_RaWb GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIRAWB) -#define GICR_PBASER_WaWt GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIWAWT) -#define GICR_PBASER_WaWb GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIWAWB) -#define GICR_PBASER_RaWaWt GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIRAWAWT) -#define GICR_PBASER_RaWaWb GITS_BASER_CACHEABILITY(GICR_PBASER, INNER, NIRAWAWB) - #define GIC_EPPI_BASE_INTID 1056 #define GIC_ESPI_BASE_INTID 4096 @@ -373,7 +283,6 @@ struct gicv3 rt_size_t dist_size; void *redist_percpu_base[RT_CPUS_NR]; - rt_uint64_t redist_percpu_flags[RT_CPUS_NR]; rt_size_t percpu_ppi_nr[RT_CPUS_NR]; struct @@ -385,8 +294,6 @@ struct gicv3 rt_uint64_t redist_flags; rt_size_t redist_stride; rt_size_t redist_regions_nr; - - rt_bool_t skip_init; }; -#endif /* __PIC_GICV3_H__ */ +#endif /* __IRQ_GICV3_H__ */ diff --git a/rt-thread/components/drivers/pic/pic.c b/rt-thread/components/drivers/pic/pic.c index 032c965..4525c7d 100644 --- a/rt-thread/components/drivers/pic/pic.c +++ b/rt-thread/components/drivers/pic/pic.c @@ -16,9 +16,7 @@ #include #include -#ifdef RT_USING_PIC_STATISTICS #include -#endif struct irq_traps { @@ -33,7 +31,6 @@ static int _ipi_hash[] = #ifdef RT_USING_SMP [RT_SCHEDULE_IPI] = RT_SCHEDULE_IPI, [RT_STOP_IPI] = RT_STOP_IPI, - [RT_SMP_CALL_IPI] = RT_SMP_CALL_IPI, #endif }; @@ -176,52 +173,19 @@ rt_err_t rt_pic_linear_irq(struct rt_pic *pic, rt_size_t irq_nr) return err; } -rt_err_t rt_pic_cancel_irq(struct rt_pic *pic) -{ - rt_err_t err = RT_EOK; - - if (pic && pic->pirqs) - { - rt_ubase_t level = rt_spin_lock_irqsave(&_pic_lock); - - /* - * This is only to make system runtime safely, - * we don't recommend PICs to unregister. - */ - rt_list_remove(&pic->list); - - rt_spin_unlock_irqrestore(&_pic_lock, level); - } - else - { - err = -RT_EINVAL; - } - - return err; -} - static void config_pirq(struct rt_pic *pic, struct rt_pic_irq *pirq, int irq, int hwirq) { rt_ubase_t level = rt_spin_lock_irqsave(&pirq->rw_lock); - if (pirq->irq < 0) - { - rt_list_init(&pirq->list); - rt_list_init(&pirq->children_nodes); - rt_list_init(&pirq->isr.list); - } - else if (pirq->pic != pic) - { - RT_ASSERT(rt_list_isempty(&pirq->list) == RT_TRUE); - RT_ASSERT(rt_list_isempty(&pirq->children_nodes) == RT_TRUE); - RT_ASSERT(rt_list_isempty(&pirq->isr.list) == RT_TRUE); - } - pirq->irq = irq; pirq->hwirq = hwirq; pirq->pic = pic; + rt_list_init(&pirq->list); + rt_list_init(&pirq->children_nodes); + rt_list_init(&pirq->isr.list); + rt_spin_unlock_irqrestore(&pirq->rw_lock, level); } @@ -530,8 +494,6 @@ rt_err_t rt_pic_do_traps(void) rt_err_t err = -RT_ERROR; struct irq_traps *traps; - rt_interrupt_enter(); - rt_list_for_each_entry(traps, &_traps_nodes, list) { if (traps->handler(traps->data)) @@ -542,8 +504,6 @@ rt_err_t rt_pic_do_traps(void) } } - rt_interrupt_leave(); - return err; } @@ -575,17 +535,11 @@ rt_err_t rt_pic_handle_isr(struct rt_pic_irq *pirq) rt_list_for_each_entry(child, &pirq->children_nodes, list) { - if (child->pic->ops->irq_ack) - { - child->pic->ops->irq_ack(child); - } + rt_pic_irq_ack(child->irq); err = rt_pic_handle_isr(child); - if (child->pic->ops->irq_eoi) - { - child->pic->ops->irq_eoi(child); - } + rt_pic_irq_eoi(child->irq); } } diff --git a/rt-thread/components/drivers/pin/Kconfig b/rt-thread/components/drivers/pin/Kconfig index 2520897..24a2c02 100644 --- a/rt-thread/components/drivers/pin/Kconfig +++ b/rt-thread/components/drivers/pin/Kconfig @@ -1,7 +1,3 @@ menuconfig RT_USING_PIN bool "Using Generic GPIO device drivers" default y - -if RT_USING_PIN - osource "$(SOC_DM_PIN_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/pin/SConscript b/rt-thread/components/drivers/pin/SConscript index 69e3b53..bdad848 100644 --- a/rt-thread/components/drivers/pin/SConscript +++ b/rt-thread/components/drivers/pin/SConscript @@ -8,13 +8,13 @@ if not GetDepend(['RT_USING_PIN']): cwd = GetCurrentDir() CPPPATH = [cwd + '/../include'] -src = ['dev_pin.c'] +src = ['pin.c'] if GetDepend(['RT_USING_DM']): - src += ['dev_pin_dm.c'] + src += ['pin_dm.c'] if GetDepend(['RT_USING_OFW']): - src += ['dev_pin_ofw.c'] + src += ['pin_ofw.c'] group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) diff --git a/rt-thread/components/drivers/pin/dev_pin.c b/rt-thread/components/drivers/pin/dev_pin.c deleted file mode 100644 index 4403557..0000000 --- a/rt-thread/components/drivers/pin/dev_pin.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2015-01-20 Bernard the first version - * 2021-02-06 Meco Man fix RT_ENOSYS code in negative - * 2022-04-29 WangQiang add pin operate command in MSH - */ - -#include - -static struct rt_device_pin _hw_pin; -static rt_ssize_t _pin_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - struct rt_device_pin_value *value; - struct rt_device_pin *pin = (struct rt_device_pin *)dev; - - /* check parameters */ - RT_ASSERT(pin != RT_NULL); - - value = (struct rt_device_pin_value *)buffer; - if (value == RT_NULL || size != sizeof(*value)) - return 0; - - value->value = pin->ops->pin_read(dev, value->pin); - return size; -} - -static rt_ssize_t _pin_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - struct rt_device_pin_value *value; - struct rt_device_pin *pin = (struct rt_device_pin *)dev; - - /* check parameters */ - RT_ASSERT(pin != RT_NULL); - - value = (struct rt_device_pin_value *)buffer; - if (value == RT_NULL || size != sizeof(*value)) - return 0; - - pin->ops->pin_write(dev, (rt_base_t)value->pin, (rt_base_t)value->value); - - return size; -} - -static rt_err_t _pin_control(rt_device_t dev, int cmd, void *args) -{ - struct rt_device_pin_mode *mode; - struct rt_device_pin *pin = (struct rt_device_pin *)dev; - - /* check parameters */ - RT_ASSERT(pin != RT_NULL); - - mode = (struct rt_device_pin_mode *)args; - if (mode == RT_NULL) - return -RT_ERROR; - - pin->ops->pin_mode(dev, (rt_base_t)mode->pin, (rt_base_t)mode->mode); - - return 0; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops pin_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - _pin_read, - _pin_write, - _pin_control -}; -#endif - -int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data) -{ - _hw_pin.parent.type = RT_Device_Class_Pin; - _hw_pin.parent.rx_indicate = RT_NULL; - _hw_pin.parent.tx_complete = RT_NULL; - -#ifdef RT_USING_DEVICE_OPS - _hw_pin.parent.ops = &pin_ops; -#else - _hw_pin.parent.init = RT_NULL; - _hw_pin.parent.open = RT_NULL; - _hw_pin.parent.close = RT_NULL; - _hw_pin.parent.read = _pin_read; - _hw_pin.parent.write = _pin_write; - _hw_pin.parent.control = _pin_control; -#endif - - _hw_pin.ops = ops; - _hw_pin.parent.user_data = user_data; - - /* register a character device */ - rt_device_register(&_hw_pin.parent, name, RT_DEVICE_FLAG_RDWR); - - return 0; -} - -rt_err_t rt_pin_attach_irq(rt_base_t pin, rt_uint8_t mode, - void (*hdr)(void *args), void *args) -{ - RT_ASSERT(_hw_pin.ops != RT_NULL); - if (_hw_pin.ops->pin_attach_irq) - { - return _hw_pin.ops->pin_attach_irq(&_hw_pin.parent, pin, mode, hdr, args); - } - return -RT_ENOSYS; -} - -rt_err_t rt_pin_detach_irq(rt_base_t pin) -{ - RT_ASSERT(_hw_pin.ops != RT_NULL); - if (_hw_pin.ops->pin_detach_irq) - { - return _hw_pin.ops->pin_detach_irq(&_hw_pin.parent, pin); - } - return -RT_ENOSYS; -} - -rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint8_t enabled) -{ - RT_ASSERT(_hw_pin.ops != RT_NULL); - if (_hw_pin.ops->pin_irq_enable) - { - return _hw_pin.ops->pin_irq_enable(&_hw_pin.parent, pin, enabled); - } - return -RT_ENOSYS; -} - -rt_err_t rt_pin_debounce(rt_base_t pin, rt_uint32_t debounce) -{ - RT_ASSERT(_hw_pin.ops != RT_NULL); - if (_hw_pin.ops->pin_debounce) - { - return _hw_pin.ops->pin_debounce(&_hw_pin.parent, pin, debounce); - } - return -RT_ENOSYS; -} - -/* RT-Thread Hardware PIN APIs */ -void rt_pin_mode(rt_base_t pin, rt_uint8_t mode) -{ - RT_ASSERT(_hw_pin.ops != RT_NULL); - _hw_pin.ops->pin_mode(&_hw_pin.parent, pin, mode); -} - -void rt_pin_write(rt_base_t pin, rt_ssize_t value) -{ - RT_ASSERT(_hw_pin.ops != RT_NULL); - _hw_pin.ops->pin_write(&_hw_pin.parent, pin, value); -} - -rt_ssize_t rt_pin_read(rt_base_t pin) -{ - RT_ASSERT(_hw_pin.ops != RT_NULL); - return _hw_pin.ops->pin_read(&_hw_pin.parent, pin); -} - -/* Get pin number by name, such as PA.0, P0.12 */ -rt_base_t rt_pin_get(const char *name) -{ - RT_ASSERT(_hw_pin.ops != RT_NULL); - - if (_hw_pin.ops->pin_get == RT_NULL) - { - return -RT_ENOSYS; - } - return _hw_pin.ops->pin_get(name); -} - -#ifdef RT_USING_FINSH -#include -#include -#include -#include -#include - -/* - * convert function for port name - */ -static rt_base_t _pin_cmd_conv(const char *name) -{ - return rt_pin_get(name); -} - -static void _pin_cmd_print_usage(void) -{ - rt_kprintf("pin [option] GPIO\n"); - rt_kprintf(" num: get pin number from hardware pin\n"); - rt_kprintf(" mode: set pin mode to output/input/input_pullup/input_pulldown/output_od\n"); - rt_kprintf(" e.g. MSH >pin mode GPIO output\n"); - rt_kprintf(" read: read pin level of hardware pin\n"); - rt_kprintf(" e.g. MSH >pin read GPIO\n"); - rt_kprintf(" write: write pin level(high/low or on/off) to hardware pin\n"); - rt_kprintf(" e.g. MSH >pin write GPIO high\n"); - rt_kprintf(" help: this help list\n"); - rt_kprintf("GPIO e.g.:"); - rt_pin_get(" "); -} - -/* e.g. MSH >pin num PA.16 */ -static void _pin_cmd_get(int argc, char *argv[]) -{ - rt_base_t pin; - if (argc < 3) - { - _pin_cmd_print_usage(); - return; - } - pin = _pin_cmd_conv(argv[2]); - if (pin < 0) - { - rt_kprintf("Parameter invalid : %s!\n", argv[2]); - _pin_cmd_print_usage(); - return ; - } - rt_kprintf("%s : %d\n", argv[2], pin); -} - -/* e.g. MSH >pin mode PA.16 output */ -static void _pin_cmd_mode(int argc, char *argv[]) -{ - rt_base_t pin; - rt_base_t mode; - if (argc < 4) - { - _pin_cmd_print_usage(); - return; - } - if (!msh_isint(argv[2])) - { - pin = _pin_cmd_conv(argv[2]); - if (pin < 0) - { - rt_kprintf("Parameter invalid : %s!\n", argv[2]); - _pin_cmd_print_usage(); - return; - } - } - else - { - pin = atoi(argv[2]); - } - if (0 == rt_strcmp("output", argv[3])) - { - mode = PIN_MODE_OUTPUT; - } - else if (0 == rt_strcmp("input", argv[3])) - { - mode = PIN_MODE_INPUT; - } - else if (0 == rt_strcmp("input_pullup", argv[3])) - { - mode = PIN_MODE_INPUT_PULLUP; - } - else if (0 == rt_strcmp("input_pulldown", argv[3])) - { - mode = PIN_MODE_INPUT_PULLDOWN; - } - else if (0 == rt_strcmp("output_od", argv[3])) - { - mode = PIN_MODE_OUTPUT_OD; - } - else - { - _pin_cmd_print_usage(); - return; - } - - rt_pin_mode(pin, mode); -} - -/* e.g. MSH >pin read PA.16 */ -static void _pin_cmd_read(int argc, char *argv[]) -{ - rt_base_t pin; - rt_uint8_t value; - if (argc < 3) - { - _pin_cmd_print_usage(); - return; - } - if (!msh_isint(argv[2])) - { - pin = _pin_cmd_conv(argv[2]); - if (pin < 0) - { - rt_kprintf("Parameter invalid : %s!\n", argv[2]); - _pin_cmd_print_usage(); - return; - } - } - else - { - pin = atoi(argv[2]); - } - value = rt_pin_read(pin); - if (value == PIN_HIGH) - { - rt_kprintf("pin[%d] = high\n", pin); - } - else - { - rt_kprintf("pin[%d] = low\n", pin); - } -} - -/* e.g. MSH >pin write PA.16 high */ -static void _pin_cmd_write(int argc, char *argv[]) -{ - rt_base_t pin; - rt_uint8_t value; - if (argc < 4) - { - _pin_cmd_print_usage(); - return; - } - if (!msh_isint(argv[2])) - { - pin = _pin_cmd_conv(argv[2]); - if (pin < 0) - { - rt_kprintf("Parameter invalid : %s!\n", argv[2]); - _pin_cmd_print_usage(); - return; - } - } - else - { - pin = atoi(argv[2]); - } - if ((0 == rt_strcmp("high", argv[3])) || (0 == rt_strcmp("on", argv[3]))) - { - value = PIN_HIGH; - } - else if ((0 == rt_strcmp("low", argv[3])) || (0 == rt_strcmp("off", argv[3]))) - { - value = PIN_LOW; - } - else - { - _pin_cmd_print_usage(); - return; - } - rt_pin_write(pin, value); -} - -static void _pin_cmd(int argc, char *argv[]) -{ - if (argc < 3) - { - _pin_cmd_print_usage(); - return ; - } - if (0 == rt_strcmp("num", argv[1])) - { - _pin_cmd_get(argc, argv); - } - else if (0 == rt_strcmp("mode", argv[1])) - { - _pin_cmd_mode(argc, argv); - } - else if (0 == rt_strcmp("read", argv[1])) - { - _pin_cmd_read(argc, argv); - } - else if (0 == rt_strcmp("write", argv[1])) - { - _pin_cmd_write(argc, argv); - } - else - { - _pin_cmd_print_usage(); - return; - } -} -MSH_CMD_EXPORT_ALIAS(_pin_cmd, pin, pin [option]); -#endif /* RT_USING_FINSH */ diff --git a/rt-thread/components/drivers/pin/dev_pin_dm.c b/rt-thread/components/drivers/pin/dev_pin_dm.c deleted file mode 100644 index 90cca94..0000000 --- a/rt-thread/components/drivers/pin/dev_pin_dm.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-26 GuEe-GUI first version - */ - -#include "dev_pin_dm.h" - -static rt_size_t pin_total_nr = 0; -static struct rt_spinlock pin_lock = {}; -static rt_list_t pin_nodes = RT_LIST_OBJECT_INIT(pin_nodes); - -static struct rt_device_pin *pin_device_find(rt_ubase_t pin) -{ - struct rt_device_pin *gpio = RT_NULL, *gpio_tmp; - - rt_spin_lock(&pin_lock); - - rt_list_for_each_entry(gpio_tmp, &pin_nodes, list) - { - if (pin >= gpio_tmp->pin_start && - pin - gpio_tmp->pin_start < gpio_tmp->pin_nr) - { - gpio = gpio_tmp; - break; - } - } - - rt_spin_unlock(&pin_lock); - - return gpio; -} - -static void pin_api_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode) -{ - struct rt_device_pin *gpio = pin_device_find(pin); - - if (gpio && gpio->ops->pin_mode) - { - gpio->ops->pin_mode(&gpio->parent, pin - gpio->pin_start, mode); - } -} - -static void pin_api_write(struct rt_device *device, rt_base_t pin, rt_uint8_t value) -{ - struct rt_device_pin *gpio = pin_device_find(pin); - - if (gpio && gpio->ops->pin_write) - { - gpio->ops->pin_write(&gpio->parent, pin - gpio->pin_start, value); - } -} - -static rt_ssize_t pin_api_read(struct rt_device *device, rt_base_t pin) -{ - struct rt_device_pin *gpio = pin_device_find(pin); - - if (gpio && gpio->ops->pin_read) - { - return gpio->ops->pin_read(&gpio->parent, pin - gpio->pin_start); - } - - return -RT_EINVAL; -} - -static rt_err_t pin_api_attach_irq(struct rt_device *device, rt_base_t pin, - rt_uint8_t mode, void (*hdr)(void *args), void *args) -{ - struct rt_device_pin *gpio = pin_device_find(pin); - - if (gpio) - { - rt_base_t pin_index = pin - gpio->pin_start; - - if (!gpio->ops->pin_attach_irq) - { - rt_err_t err; - struct rt_pin_irq_hdr *legacy_isr; - - if ((err = gpio->ops->pin_irq_mode(&gpio->parent, pin_index, mode))) - { - return err; - } - - legacy_isr = &gpio->legacy_isr[pin_index]; - legacy_isr->pin = pin_index; - legacy_isr->mode = mode; - legacy_isr->hdr = hdr; - legacy_isr->args = args; - - return RT_EOK; - } - else - { - return gpio->ops->pin_attach_irq(&gpio->parent, pin_index, mode, hdr, args); - } - } - - return -RT_EINVAL; -} - -static rt_err_t pin_api_detach_irq(struct rt_device *device, rt_base_t pin) -{ - struct rt_device_pin *gpio = pin_device_find(pin); - - if (gpio) - { - rt_base_t pin_index = pin - gpio->pin_start; - - if (!gpio->ops->pin_detach_irq) - { - struct rt_pin_irq_hdr *legacy_isr; - - legacy_isr = &gpio->legacy_isr[pin_index]; - rt_memset(legacy_isr, 0, sizeof(*legacy_isr)); - - return RT_EOK; - } - else - { - return gpio->ops->pin_detach_irq(&gpio->parent, pin); - } - } - - return -RT_EINVAL; -} - -static rt_err_t pin_api_irq_enable(struct rt_device *device, rt_base_t pin, - rt_uint8_t enabled) -{ - struct rt_device_pin *gpio = pin_device_find(pin); - - if (gpio && gpio->ops->pin_irq_enable) - { - return gpio->ops->pin_irq_enable(&gpio->parent, pin - gpio->pin_start, enabled); - } - - return -RT_EINVAL; -} - -static rt_base_t pin_api_get(const char *name) -{ - rt_base_t res = -RT_EINVAL; - struct rt_device_pin *gpio; - - rt_spin_lock(&pin_lock); - - rt_list_for_each_entry(gpio, &pin_nodes, list) - { - if (gpio->ops->pin_get && !(res = gpio->ops->pin_get(name))) - { - break; - } - } - - rt_spin_unlock(&pin_lock); - - return res; -} - -static rt_err_t pin_api_debounce(struct rt_device *device, rt_base_t pin, - rt_uint32_t debounce) -{ - struct rt_device_pin *gpio = pin_device_find(pin); - - if (gpio && gpio->ops->pin_debounce) - { - return gpio->ops->pin_debounce(&gpio->parent, pin - gpio->pin_start, debounce); - } - - return -RT_EINVAL; -} - -static rt_err_t pin_api_irq_mode(struct rt_device *device, rt_base_t pin, - rt_uint8_t mode) -{ - struct rt_device_pin *gpio = pin_device_find(pin); - - if (gpio && gpio->ops->pin_irq_mode) - { - return gpio->ops->pin_irq_mode(&gpio->parent, pin - gpio->pin_start, mode); - } - - return -RT_EINVAL; -} - -static const struct rt_pin_ops pin_api_dm_ops = -{ - .pin_mode = pin_api_mode, - .pin_write = pin_api_write, - .pin_read = pin_api_read, - .pin_attach_irq = pin_api_attach_irq, - .pin_detach_irq = pin_api_detach_irq, - .pin_irq_enable = pin_api_irq_enable, - .pin_get = pin_api_get, - .pin_debounce = pin_api_debounce, - .pin_irq_mode = pin_api_irq_mode, -}; - -rt_err_t pin_api_init(struct rt_device_pin *gpio, rt_size_t pin_nr) -{ - rt_err_t err = RT_EOK; - - if (!gpio || !gpio->ops) - { - return -RT_EINVAL; - } - - rt_spin_lock(&pin_lock); - - if (rt_list_isempty(&pin_nodes)) - { - rt_spin_unlock(&pin_lock); - rt_device_pin_register("gpio", &pin_api_dm_ops, RT_NULL); - rt_spin_lock(&pin_lock); - } - - gpio->pin_start = pin_total_nr; - gpio->pin_nr = pin_nr; - pin_total_nr += pin_nr; - - rt_list_init(&gpio->list); - rt_list_insert_before(&pin_nodes, &gpio->list); - - rt_spin_unlock(&pin_lock); - - return err; -} - -static void pin_dm_irq_mask(struct rt_pic_irq *pirq) -{ - struct rt_device_pin *gpio = pirq->pic->priv_data; - - gpio->ops->pin_irq_enable(&gpio->parent, pirq->hwirq, 0); -} - -static void pin_dm_irq_unmask(struct rt_pic_irq *pirq) -{ - struct rt_device_pin *gpio = pirq->pic->priv_data; - - gpio->ops->pin_irq_enable(&gpio->parent, pirq->hwirq, 1); -} - -static rt_err_t pin_dm_irq_set_triger_mode(struct rt_pic_irq *pirq, rt_uint32_t mode) -{ - rt_uint8_t pin_mode; - struct rt_device_pin *gpio = pirq->pic->priv_data; - - switch (mode) - { - case RT_IRQ_MODE_EDGE_RISING: - pin_mode = PIN_IRQ_MODE_RISING; - break; - - case RT_IRQ_MODE_EDGE_FALLING: - pin_mode = PIN_IRQ_MODE_FALLING; - break; - - case RT_IRQ_MODE_EDGE_BOTH: - pin_mode = PIN_IRQ_MODE_RISING_FALLING; - break; - - case RT_IRQ_MODE_LEVEL_HIGH: - pin_mode = PIN_IRQ_MODE_HIGH_LEVEL; - break; - - case RT_IRQ_MODE_LEVEL_LOW: - pin_mode = PIN_IRQ_MODE_LOW_LEVEL; - break; - - default: - return -RT_ENOSYS; - } - - return gpio->ops->pin_irq_mode(&gpio->parent, pirq->hwirq, pin_mode); -} - -static int pin_dm_irq_map(struct rt_pic *pic, int hwirq, rt_uint32_t mode) -{ - int irq = -1; - struct rt_device_pin *gpio = pic->priv_data; - struct rt_pic_irq *pirq = rt_pic_find_irq(pic, hwirq); - - if (pirq) - { - irq = rt_pic_config_irq(pic, hwirq, hwirq); - - if (irq >= 0) - { - rt_pic_cascade(pirq, gpio->irqchip.irq); - rt_pic_irq_set_triger_mode(irq, mode); - } - } - - return irq; -} - -static rt_err_t pin_dm_irq_parse(struct rt_pic *pic, - struct rt_ofw_cell_args *args, struct rt_pic_irq *out_pirq) -{ - rt_err_t err = RT_EOK; - - if (args->args_count == 2) - { - out_pirq->hwirq = args->args[0]; - out_pirq->mode = args->args[1] & RT_IRQ_MODE_MASK; - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -const static struct rt_pic_ops pin_dm_ops = -{ - .name = "GPIO", - .irq_enable = pin_dm_irq_mask, - .irq_disable = pin_dm_irq_unmask, - .irq_mask = pin_dm_irq_mask, - .irq_unmask = pin_dm_irq_unmask, - .irq_set_triger_mode = pin_dm_irq_set_triger_mode, - .irq_map = pin_dm_irq_map, - .irq_parse = pin_dm_irq_parse, -}; - -rt_err_t pin_pic_handle_isr(struct rt_device_pin *gpio, rt_base_t pin) -{ - rt_err_t err; - - if (gpio) - { - rt_ubase_t pin_index = pin; - struct rt_pin_irqchip *irqchip = &gpio->irqchip; - - if (pin_index < gpio->pin_nr) - { - struct rt_pic_irq *pirq; - struct rt_pin_irq_hdr *legacy_isr; - - pirq = rt_pic_find_irq(&irqchip->parent, pin_index); - - if (pirq->irq >= 0) - { - err = rt_pic_handle_isr(pirq); - } - else - { - err = -RT_EINVAL; - } - - legacy_isr = &gpio->legacy_isr[pin_index]; - - if (legacy_isr->hdr) - { - legacy_isr->hdr(legacy_isr->args); - } - } - else - { - err = -RT_EINVAL; - } - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_err_t pin_pic_init(struct rt_device_pin *gpio, int pin_irq) -{ - rt_err_t err; - - if (gpio) - { - struct rt_pin_irqchip *irqchip = &gpio->irqchip; - struct rt_pic *pic = &irqchip->parent; - - irqchip->irq = pin_irq; - - if (!gpio->pin_nr) - { - return -RT_EINVAL; - } - - gpio->legacy_isr = rt_calloc(gpio->pin_nr, sizeof(*gpio->legacy_isr)); - - if (!gpio->legacy_isr) - { - return -RT_ENOMEM; - } - - pic->priv_data = gpio; - pic->ops = &pin_dm_ops; - /* Make sure the type of gpio for pic */ - gpio->parent.parent.type = RT_Object_Class_Device; - rt_pic_default_name(&irqchip->parent); - - err = rt_pic_linear_irq(pic, gpio->pin_nr); - rt_pic_user_extends(pic); - - err = RT_EOK; - } - else - { - err = -RT_EINVAL; - } - - return err; -} - -rt_ssize_t rt_pin_get_named_pin(struct rt_device *dev, const char *propname, int index, - rt_uint8_t *out_mode, rt_uint8_t *out_value) -{ - rt_ssize_t res = -RT_ENOSYS; - - RT_ASSERT(dev != RT_NULL); - -#ifdef RT_USING_OFW - if (dev->ofw_node) - { - res = rt_ofw_get_named_pin(dev->ofw_node, propname, index, out_mode, out_value); - } - else - { - res = -RT_EINVAL; - } -#endif /* RT_USING_OFW */ - - return res; -} - -rt_ssize_t rt_pin_get_named_pin_count(struct rt_device *dev, const char *propname) -{ - rt_ssize_t count = -RT_ENOSYS; - - RT_ASSERT(dev != RT_NULL); - -#ifdef RT_USING_OFW - if (dev->ofw_node) - { - count = rt_ofw_get_named_pin_count(dev->ofw_node, propname); - } - else - { - count = -RT_EINVAL; - } -#endif /* RT_USING_OFW */ - - return count; -} diff --git a/rt-thread/components/drivers/pin/dev_pin_dm.h b/rt-thread/components/drivers/pin/dev_pin_dm.h deleted file mode 100644 index 09374ca..0000000 --- a/rt-thread/components/drivers/pin/dev_pin_dm.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-26 GuEe-GUI first version - */ - -#ifndef __PIN_DM_H__ -#define __PIN_DM_H__ - -#include -#include -#include - -rt_err_t pin_api_init(struct rt_device_pin *gpio, rt_size_t pin_nr); - -rt_err_t pin_pic_init(struct rt_device_pin *gpio, int pin_irq); -rt_err_t pin_pic_handle_isr(struct rt_device_pin *gpio, rt_base_t pin); - -#endif /* __DEV_PIN_DM_H__ */ diff --git a/rt-thread/components/drivers/pin/dev_pin_ofw.c b/rt-thread/components/drivers/pin/dev_pin_ofw.c deleted file mode 100644 index fbf0538..0000000 --- a/rt-thread/components/drivers/pin/dev_pin_ofw.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-26 GuEe-GUI first version - */ - -#include - -#include "dev_pin_dm.h" - -static const char * const gpio_suffixes[] = -{ - "gpios", "gpio" -}; - -rt_ssize_t rt_ofw_get_named_pin(struct rt_ofw_node *np, const char *propname, int index, - rt_uint8_t *out_mode, rt_uint8_t *out_value) -{ - rt_ssize_t pin = -1; - rt_uint8_t mode; - rt_uint8_t value; - rt_uint32_t flags; - char gpios_name[64]; - struct rt_device_pin *pin_dev = 0; - struct rt_ofw_node *pin_dev_np = 0; - struct rt_ofw_cell_args pin_args = {0}; - - if (!np && index < 0) - { - return -RT_EINVAL; - } - - for (int i = 0; i < RT_ARRAY_SIZE(gpio_suffixes); ++i) - { - if (propname) - { - rt_snprintf(gpios_name, sizeof(gpios_name), "%s-%s", propname, gpio_suffixes[i]); - } - else - { - rt_snprintf(gpios_name, sizeof(gpios_name), "%s", gpio_suffixes[i]); - } - - pin = rt_ofw_parse_phandle_cells(np, gpios_name, "#gpio-cells", index, &pin_args); - - if (pin >= 0) - { - break; - } - } - - if (pin < 0) - { - return pin; - } - - pin_dev_np = pin_args.data; - - if (!rt_ofw_data(pin_dev_np)) - { - rt_platform_ofw_request(pin_dev_np); - } - - pin_dev = rt_ofw_data(pin_dev_np); - - if (!pin_dev) - { - pin = -RT_ERROR; - - goto _out_converts; - } - - value = PIN_LOW; - mode = PIN_MODE_OUTPUT; - - if (pin_dev->ops->pin_parse) - { - pin = pin_dev->ops->pin_parse(&pin_dev->parent, &pin_args, &flags); - } - else - { - /* - * We always assume that the args[0] is the pin number if driver not - * implemented `pin_parse`. - */ - pin = pin_args.args[0]; - - goto _out_converts; - } - - if (out_mode) - { - if (flags & PIN_OPEN_DRAIN) - { - mode = PIN_MODE_OUTPUT_OD; - } - - switch (flags & RT_GENMASK(6, 4)) - { - case PIN_PULL_UP: - mode = PIN_MODE_INPUT_PULLUP; - break; - - case PIN_PULL_DOWN: - mode = PIN_MODE_INPUT_PULLDOWN; - break; - - case PIN_PULL_DISABLE: - mode = PIN_MODE_INPUT; - break; - } - } - - if (out_value) - { - if ((flags & 1) == PIN_ACTIVE_HIGH) - { - value = PIN_HIGH; - } - else if ((flags & 1) == PIN_ACTIVE_LOW) - { - value = PIN_LOW; - } - } - -_out_converts: - rt_ofw_node_put(pin_dev_np); - - if (pin >= 0) - { - /* Get virtual pin */ - pin += pin_dev->pin_start; - - if (out_mode) - { - *out_mode = mode; - } - - if (out_value) - { - *out_value = value; - } - } - - return pin; -} - -rt_ssize_t rt_ofw_get_named_pin_count(struct rt_ofw_node *np, const char *propname) -{ - char gpios_name[64]; - rt_ssize_t count = 0; - - if (!np) - { - return -RT_EINVAL; - } - - for (int i = 0; i < RT_ARRAY_SIZE(gpio_suffixes); ++i) - { - if (propname) - { - rt_snprintf(gpios_name, sizeof(gpios_name), "%s-%s", propname, gpio_suffixes[i]); - } - else - { - rt_snprintf(gpios_name, sizeof(gpios_name), "%s", gpio_suffixes[i]); - } - - count = rt_ofw_count_phandle_cells(np, propname, "#gpio-cells"); - - if (count > 0) - { - break; - } - } - - return count; -} diff --git a/rt-thread/components/drivers/pinctrl/Kconfig b/rt-thread/components/drivers/pinctrl/Kconfig index 536049b..227c8a9 100644 --- a/rt-thread/components/drivers/pinctrl/Kconfig +++ b/rt-thread/components/drivers/pinctrl/Kconfig @@ -4,6 +4,3 @@ menuconfig RT_USING_PINCTRL depends on RT_USING_PIN default n -if RT_USING_PINCTRL - osource "$(SOC_DM_PINCTRL_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/pinctrl/pinctrl.c b/rt-thread/components/drivers/pinctrl/pinctrl.c index 2fbfa7a..f327492 100644 --- a/rt-thread/components/drivers/pinctrl/pinctrl.c +++ b/rt-thread/components/drivers/pinctrl/pinctrl.c @@ -92,11 +92,6 @@ static rt_err_t ofw_pin_ctrl_confs_apply(struct rt_ofw_node *np, int index) if (pinctrl_np) { - if (!rt_ofw_data(pinctrl_np)) - { - rt_platform_ofw_request(pinctrl_np); - } - pinctrl = rt_ofw_data(pinctrl_np); rt_ofw_node_put(pinctrl_np); @@ -222,8 +217,6 @@ rt_err_t rt_pin_ctrl_confs_apply_by_name(struct rt_device *device, const char *n err = ofw_pin_ctrl_confs_apply_by_name(device->ofw_node, name); } #endif /* RT_USING_OFW */ - - RT_UNUSED(name); } else { diff --git a/rt-thread/components/drivers/pm/pm.c b/rt-thread/components/drivers/pm/pm.c index b4ad3b2..024e301 100644 --- a/rt-thread/components/drivers/pm/pm.c +++ b/rt-thread/components/drivers/pm/pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -10,7 +10,6 @@ * 2019-04-28 Zero-Free improve PM mode and device ops interface * 2020-11-23 zhangsz update pm mode select * 2020-11-27 zhangsz update pm 2.0 - * 2024-07-04 wdfk-prog The device is registered and uninstalled by linked list */ #include @@ -78,6 +77,9 @@ rt_weak void rt_pm_exit_critical(rt_uint32_t ctx, rt_uint8_t sleep_mode) /* lptimer start */ static void pm_lptimer_start(struct rt_pm *pm, uint32_t timeout) { + if (_pm.ops == RT_NULL) + return; + if (_pm.ops->timer_start != RT_NULL) _pm.ops->timer_start(pm, timeout); } @@ -85,6 +87,9 @@ static void pm_lptimer_start(struct rt_pm *pm, uint32_t timeout) /* lptimer stop */ static void pm_lptimer_stop(struct rt_pm *pm) { + if (_pm.ops == RT_NULL) + return; + if (_pm.ops->timer_stop != RT_NULL) _pm.ops->timer_stop(pm); } @@ -92,6 +97,9 @@ static void pm_lptimer_stop(struct rt_pm *pm) /* lptimer get timeout tick */ static rt_tick_t pm_lptimer_get_timeout(struct rt_pm *pm) { + if (_pm.ops == RT_NULL) + return RT_TICK_MAX; + if (_pm.ops->timer_get_tick != RT_NULL) return _pm.ops->timer_get_tick(pm); @@ -101,6 +109,9 @@ static rt_tick_t pm_lptimer_get_timeout(struct rt_pm *pm) /* enter sleep mode */ static void pm_sleep(struct rt_pm *pm, uint8_t sleep_mode) { + if (_pm.ops == RT_NULL) + return; + if (_pm.ops->sleep != RT_NULL) _pm.ops->sleep(pm, sleep_mode); } @@ -108,22 +119,17 @@ static void pm_sleep(struct rt_pm *pm, uint8_t sleep_mode) /** * This function will suspend all registered devices */ -static rt_err_t _pm_device_suspend(rt_uint8_t mode) +static int _pm_device_suspend(rt_uint8_t mode) { - rt_err_t ret = RT_EOK; - struct rt_device_pm *device_pm = RT_NULL; - rt_slist_t *node = RT_NULL; + int index, ret = RT_EOK; - for (node = rt_slist_first(&_pm.device_list); node; node = rt_slist_next(node)) + for (index = 0; index < _pm.device_pm_number; index++) { - device_pm = rt_slist_entry(node, struct rt_device_pm, list); - if (device_pm->ops != RT_NULL && device_pm->ops->suspend != RT_NULL) + if (_pm.device_pm[index].ops->suspend != RT_NULL) { - ret = device_pm->ops->suspend(device_pm->device, mode); + ret = _pm.device_pm[index].ops->suspend(_pm.device_pm[index].device, mode); if(ret != RT_EOK) - { break; - } } } @@ -135,15 +141,13 @@ static rt_err_t _pm_device_suspend(rt_uint8_t mode) */ static void _pm_device_resume(rt_uint8_t mode) { - struct rt_device_pm *device_pm = RT_NULL; - rt_slist_t *node = RT_NULL; + int index; - for (node = rt_slist_first(&_pm.device_list); node; node = rt_slist_next(node)) + for (index = 0; index < _pm.device_pm_number; index++) { - device_pm = rt_slist_entry(node, struct rt_device_pm, list); - if (device_pm->ops != RT_NULL && device_pm->ops->resume != RT_NULL) + if (_pm.device_pm[index].ops->resume != RT_NULL) { - device_pm->ops->resume(device_pm->device, mode); + _pm.device_pm[index].ops->resume(_pm.device_pm[index].device, mode); } } } @@ -153,16 +157,13 @@ static void _pm_device_resume(rt_uint8_t mode) */ static void _pm_device_frequency_change(rt_uint8_t mode) { - struct rt_device_pm *device_pm = RT_NULL; - rt_slist_t *node = RT_NULL; + rt_uint32_t index; - for (node = rt_slist_first(&_pm.device_list); node; node = rt_slist_next(node)) + /* make the frequency change */ + for (index = 0; index < _pm.device_pm_number; index ++) { - device_pm = rt_slist_entry(node, struct rt_device_pm, list); - if (device_pm->ops->frequency_change != RT_NULL) - { - device_pm->ops->frequency_change(device_pm->device, mode); - } + if (_pm.device_pm[index].ops->frequency_change != RT_NULL) + _pm.device_pm[index].ops->frequency_change(_pm.device_pm[index].device, mode); } } @@ -171,16 +172,13 @@ static void _pm_device_frequency_change(rt_uint8_t mode) */ static void _pm_frequency_scaling(struct rt_pm *pm) { - rt_base_t level = 0; + rt_base_t level; if (pm->flags & RT_PM_FREQUENCY_PENDING) { level = rt_hw_interrupt_disable(); /* change system runing mode */ - if(pm->ops->run != RT_NULL) - { - pm->ops->run(pm, pm->run_mode); - } + pm->ops->run(pm, pm->run_mode); /* changer device frequency */ _pm_device_frequency_change(pm->run_mode); pm->flags &= ~RT_PM_FREQUENCY_PENDING; @@ -290,12 +288,6 @@ static rt_bool_t _pm_device_check_idle(void) return RT_TRUE; } -/** - * @brief Get the next system wake-up time - * @note When used by default, it goes into STANDBY mode and sleeps forever. tickless external rewriting is required - * @param mode: sleep mode - * @retval timeout_tick - */ rt_weak rt_tick_t pm_timer_next_timeout_tick(rt_uint8_t mode) { switch (mode) @@ -352,7 +344,6 @@ rt_weak rt_uint8_t pm_get_sleep_threshold_mode(rt_uint8_t cur_mode, rt_tick_t ti else if (timeout_tick < PM_STANDBY_THRESHOLD_TIME) sleep_mode = PM_SLEEP_MODE_DEEP; } - cur_mode = sleep_mode; #else if (timeout_tick < PM_TICKLESS_THRESHOLD_TIME) { @@ -368,8 +359,8 @@ rt_weak rt_uint8_t pm_get_sleep_threshold_mode(rt_uint8_t cur_mode, rt_tick_t ti */ static void _pm_change_sleep_mode(struct rt_pm *pm) { - rt_tick_t timeout_tick = 0, delta_tick = 0; - rt_base_t level = 0; + rt_tick_t timeout_tick, delta_tick; + rt_base_t level; uint8_t sleep_mode = PM_SLEEP_MODE_DEEP; level = rt_pm_enter_critical(pm->sleep_mode); @@ -389,27 +380,23 @@ static void _pm_change_sleep_mode(struct rt_pm *pm) if (_pm.sleep_mode == PM_SLEEP_MODE_NONE) { - pm_sleep(pm, PM_SLEEP_MODE_NONE); + pm->ops->sleep(pm, PM_SLEEP_MODE_NONE); rt_pm_exit_critical(level, pm->sleep_mode); } else { /* Notify app will enter sleep mode */ if (_pm_notify.notify) - { _pm_notify.notify(RT_PM_ENTER_SLEEP, pm->sleep_mode, _pm_notify.data); - } /* Suspend all peripheral device */ #ifdef PM_ENABLE_SUSPEND_SLEEP_MODE - rt_err_t ret = _pm_device_suspend(pm->sleep_mode); + int ret = _pm_device_suspend(pm->sleep_mode); if (ret != RT_EOK) { _pm_device_resume(pm->sleep_mode); if (_pm_notify.notify) - { _pm_notify.notify(RT_PM_EXIT_SLEEP, pm->sleep_mode, _pm_notify.data); - } if (pm->sleep_mode > PM_SUSPEND_SLEEP_MODE) { pm->sleep_mode = PM_SUSPEND_SLEEP_MODE; @@ -432,7 +419,14 @@ static void _pm_change_sleep_mode(struct rt_pm *pm) if (pm->timer_mask & (0x01 << pm->sleep_mode)) { - pm_lptimer_start(pm, timeout_tick); + if (timeout_tick == RT_TICK_MAX) + { + pm_lptimer_start(pm, RT_TICK_MAX); + } + else + { + pm_lptimer_start(pm, timeout_tick); + } } } @@ -446,9 +440,7 @@ static void _pm_change_sleep_mode(struct rt_pm *pm) pm_lptimer_stop(pm); if (delta_tick) { - rt_interrupt_enter(); - rt_tick_increase_tick(delta_tick); - rt_interrupt_leave(); + rt_tick_set(rt_tick_get() + delta_tick); } } @@ -459,6 +451,14 @@ static void _pm_change_sleep_mode(struct rt_pm *pm) _pm_notify.notify(RT_PM_EXIT_SLEEP, pm->sleep_mode, _pm_notify.data); rt_pm_exit_critical(level, pm->sleep_mode); + + if (pm->timer_mask & (0x01 << pm->sleep_mode)) + { + if (delta_tick) + { + rt_timer_check(); + } + } } } @@ -467,10 +467,8 @@ static void _pm_change_sleep_mode(struct rt_pm *pm) */ void rt_system_power_manager(void) { - if (_pm_init_flag == 0 || _pm.ops == RT_NULL) - { + if (_pm_init_flag == 0) return; - } /* CPU frequency scaling according to the runing mode settings */ _pm_frequency_scaling(&_pm); @@ -485,28 +483,22 @@ void rt_system_power_manager(void) * * @param parameter the parameter of run mode or sleep mode */ -rt_err_t rt_pm_request(rt_uint8_t mode) +void rt_pm_request(rt_uint8_t mode) { rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) - { - return -RT_EPERM; - } + return; if (mode > (PM_SLEEP_MODE_MAX - 1)) - { - return -RT_EINVAL; - } + return; level = rt_hw_interrupt_disable(); pm = &_pm; if (pm->modes[mode] < 255) pm->modes[mode] ++; rt_hw_interrupt_enable(level); - - return RT_EOK; } /** @@ -516,28 +508,22 @@ rt_err_t rt_pm_request(rt_uint8_t mode) * @param parameter the parameter of run mode or sleep mode * */ -rt_err_t rt_pm_release(rt_uint8_t mode) +void rt_pm_release(rt_uint8_t mode) { rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) - { - return -RT_EPERM; - } + return; if (mode > (PM_SLEEP_MODE_MAX - 1)) - { - return -RT_EINVAL; - } + return; level = rt_hw_interrupt_disable(); pm = &_pm; if (pm->modes[mode] > 0) pm->modes[mode] --; rt_hw_interrupt_enable(level); - - return RT_EOK; } /** @@ -547,27 +533,21 @@ rt_err_t rt_pm_release(rt_uint8_t mode) * @param parameter the parameter of run mode or sleep mode * */ -rt_err_t rt_pm_release_all(rt_uint8_t mode) +void rt_pm_release_all(rt_uint8_t mode) { rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) - { - return -RT_EPERM; - } + return; if (mode > (PM_SLEEP_MODE_MAX - 1)) - { - return -RT_EINVAL; - } + return; level = rt_hw_interrupt_disable(); pm = &_pm; pm->modes[mode] = 0; rt_hw_interrupt_enable(level); - - return RT_EOK; } /** @@ -577,25 +557,19 @@ rt_err_t rt_pm_release_all(rt_uint8_t mode) * @param module_id the application or device module id * @param mode the system power sleep mode */ -rt_err_t rt_pm_module_request(uint8_t module_id, rt_uint8_t mode) +void rt_pm_module_request(uint8_t module_id, rt_uint8_t mode) { rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) - { - return -RT_EPERM; - } + return; if (mode > (PM_SLEEP_MODE_MAX - 1)) - { - return -RT_EINVAL; - } + return; if (module_id > (PM_MODULE_MAX_ID - 1)) - { - return -RT_EINVAL; - } + return; level = rt_hw_interrupt_disable(); pm = &_pm; @@ -603,8 +577,6 @@ rt_err_t rt_pm_module_request(uint8_t module_id, rt_uint8_t mode) if (pm->modes[mode] < 255) pm->modes[mode] ++; rt_hw_interrupt_enable(level); - - return RT_EOK; } /** @@ -615,25 +587,19 @@ rt_err_t rt_pm_module_request(uint8_t module_id, rt_uint8_t mode) * @param mode the system power sleep mode * */ -rt_err_t rt_pm_module_release(uint8_t module_id, rt_uint8_t mode) +void rt_pm_module_release(uint8_t module_id, rt_uint8_t mode) { rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) - { - return -RT_EPERM; - } + return; if (mode > (PM_SLEEP_MODE_MAX - 1)) - { - return -RT_EINVAL; - } + return; if (module_id > (PM_MODULE_MAX_ID - 1)) - { - return -RT_EINVAL; - } + return; level = rt_hw_interrupt_disable(); pm = &_pm; @@ -642,8 +608,6 @@ rt_err_t rt_pm_module_release(uint8_t module_id, rt_uint8_t mode) if (pm->modes[mode] == 0) pm->module_status[module_id].req_status = 0x00; rt_hw_interrupt_enable(level); - - return RT_EOK; } /** @@ -654,28 +618,22 @@ rt_err_t rt_pm_module_release(uint8_t module_id, rt_uint8_t mode) * @param mode the system power sleep mode * */ -rt_err_t rt_pm_module_release_all(uint8_t module_id, rt_uint8_t mode) +void rt_pm_module_release_all(uint8_t module_id, rt_uint8_t mode) { rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) - { - return -RT_EPERM; - } + return; if (mode > (PM_SLEEP_MODE_MAX - 1)) - { - return -RT_EINVAL; - } + return; level = rt_hw_interrupt_disable(); pm = &_pm; pm->modes[mode] = 0; pm->module_status[module_id].req_status = 0x00; rt_hw_interrupt_enable(level); - - return RT_EOK; } /** @@ -686,24 +644,23 @@ rt_err_t rt_pm_module_release_all(uint8_t module_id, rt_uint8_t mode) * * @return none */ -rt_err_t rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode) +void rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode) { rt_base_t level; if (module_id >= PM_MODULE_MAX_ID) { - return -RT_EINVAL; + return; } if (mode >= (PM_SLEEP_MODE_MAX - 1)) { - return -RT_EINVAL; + return; } level = rt_hw_interrupt_disable(); _pm.sleep_status[mode][module_id / 32] |= 1 << (module_id % 32); rt_hw_interrupt_enable(level); - return RT_EOK; } /** @@ -713,9 +670,9 @@ rt_err_t rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode) * * @return NULL */ -rt_err_t rt_pm_sleep_none_request(rt_uint16_t module_id) +void rt_pm_sleep_none_request(rt_uint16_t module_id) { - return rt_pm_sleep_request(module_id, PM_SLEEP_MODE_NONE); + rt_pm_sleep_request(module_id, PM_SLEEP_MODE_NONE); } /** @@ -725,9 +682,9 @@ rt_err_t rt_pm_sleep_none_request(rt_uint16_t module_id) * * @return NULL */ -rt_err_t rt_pm_sleep_idle_request(rt_uint16_t module_id) +void rt_pm_sleep_idle_request(rt_uint16_t module_id) { - return rt_pm_sleep_request(module_id, PM_SLEEP_MODE_IDLE); + rt_pm_sleep_request(module_id, PM_SLEEP_MODE_IDLE); } /** @@ -737,9 +694,9 @@ rt_err_t rt_pm_sleep_idle_request(rt_uint16_t module_id) * * @return NULL */ -rt_err_t rt_pm_sleep_light_request(rt_uint16_t module_id) +void rt_pm_sleep_light_request(rt_uint16_t module_id) { - return rt_pm_sleep_request(module_id, PM_SLEEP_MODE_LIGHT); + rt_pm_sleep_request(module_id, PM_SLEEP_MODE_LIGHT); } /** @@ -750,24 +707,23 @@ rt_err_t rt_pm_sleep_light_request(rt_uint16_t module_id) * * @return NULL */ -rt_err_t rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode) +void rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode) { rt_base_t level; if (module_id >= PM_MODULE_MAX_ID) { - return -RT_EINVAL; + return; } if (mode >= (PM_SLEEP_MODE_MAX - 1)) { - return -RT_EINVAL; + return; } level = rt_hw_interrupt_disable(); _pm.sleep_status[mode][module_id / 32] &= ~(1 << (module_id % 32)); rt_hw_interrupt_enable(level); - return RT_EOK; } /** @@ -777,9 +733,9 @@ rt_err_t rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode) * * @return none */ -rt_err_t rt_pm_sleep_none_release(rt_uint16_t module_id) +void rt_pm_sleep_none_release(rt_uint16_t module_id) { - return rt_pm_sleep_release(module_id, PM_SLEEP_MODE_NONE); + rt_pm_sleep_release(module_id, PM_SLEEP_MODE_NONE); } /** @@ -789,9 +745,9 @@ rt_err_t rt_pm_sleep_none_release(rt_uint16_t module_id) * * @return none */ -rt_err_t rt_pm_sleep_idle_release(rt_uint16_t module_id) +void rt_pm_sleep_idle_release(rt_uint16_t module_id) { - return rt_pm_sleep_release(module_id, PM_SLEEP_MODE_IDLE); + rt_pm_sleep_release(module_id, PM_SLEEP_MODE_IDLE); } /** @@ -801,9 +757,9 @@ rt_err_t rt_pm_sleep_idle_release(rt_uint16_t module_id) * * @return none */ -rt_err_t rt_pm_sleep_light_release(rt_uint16_t module_id) +void rt_pm_sleep_light_release(rt_uint16_t module_id) { - return rt_pm_sleep_release(module_id, PM_SLEEP_MODE_LIGHT); + rt_pm_sleep_release(module_id, PM_SLEEP_MODE_LIGHT); } /** @@ -814,15 +770,24 @@ rt_err_t rt_pm_sleep_light_release(rt_uint16_t module_id) */ void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops) { + rt_base_t level; struct rt_device_pm *device_pm; - device_pm = RT_KERNEL_MALLOC(sizeof(struct rt_device_pm)); + RT_DEBUG_NOT_IN_INTERRUPT; + + level = rt_hw_interrupt_disable(); + + device_pm = (struct rt_device_pm *)RT_KERNEL_REALLOC(_pm.device_pm, + (_pm.device_pm_number + 1) * sizeof(struct rt_device_pm)); if (device_pm != RT_NULL) { - rt_slist_append(&_pm.device_list, &device_pm->list); - device_pm->device = device; - device_pm->ops = ops; + _pm.device_pm = device_pm; + _pm.device_pm[_pm.device_pm_number].device = device; + _pm.device_pm[_pm.device_pm_number].ops = ops; + _pm.device_pm_number += 1; } + + rt_hw_interrupt_enable(level); } /** @@ -832,18 +797,32 @@ void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_o */ void rt_pm_device_unregister(struct rt_device *device) { - struct rt_device_pm *device_pm = RT_NULL; - rt_slist_t *node = RT_NULL; - for (node = rt_slist_first(&_pm.device_list); node; node = rt_slist_next(node)) + rt_base_t level; + rt_uint32_t index; + RT_DEBUG_NOT_IN_INTERRUPT; + + level = rt_hw_interrupt_disable(); + + for (index = 0; index < _pm.device_pm_number; index ++) { - device_pm = rt_slist_entry(node, struct rt_device_pm, list); - if (device_pm->device == device) + if (_pm.device_pm[index].device == device) { - rt_slist_remove(&_pm.device_list, &device_pm->list); - RT_KERNEL_FREE(device_pm); + /* remove current entry */ + for (; index < _pm.device_pm_number - 1; index ++) + { + _pm.device_pm[index] = _pm.device_pm[index + 1]; + } + + _pm.device_pm[_pm.device_pm_number - 1].device = RT_NULL; + _pm.device_pm[_pm.device_pm_number - 1].ops = RT_NULL; + + _pm.device_pm_number -= 1; + /* break out and not touch memory */ break; } } + + rt_hw_interrupt_enable(level); } /** @@ -935,11 +914,10 @@ static rt_err_t _rt_pm_device_control(rt_device_t dev, return RT_EOK; } -rt_err_t rt_pm_run_enter(rt_uint8_t mode) +int rt_pm_run_enter(rt_uint8_t mode) { - rt_base_t level = 0; - struct rt_pm *pm = RT_NULL; - rt_err_t ret = RT_EOK; + rt_base_t level; + struct rt_pm *pm; if (_pm_init_flag == 0) return -RT_EIO; @@ -947,16 +925,12 @@ rt_err_t rt_pm_run_enter(rt_uint8_t mode) if (mode > PM_RUN_MODE_MAX) return -RT_EINVAL; - pm = &_pm; - level = rt_hw_interrupt_disable(); + pm = &_pm; if (mode < pm->run_mode) { /* change system runing mode */ - if(pm->ops != RT_NULL && pm->ops->run != RT_NULL) - { - pm->ops->run(pm, mode); - } + pm->ops->run(pm, mode); /* changer device frequency */ _pm_device_frequency_change(mode); } @@ -967,7 +941,7 @@ rt_err_t rt_pm_run_enter(rt_uint8_t mode) pm->run_mode = mode; rt_hw_interrupt_enable(level); - return ret; + return RT_EOK; } #ifdef RT_USING_DEVICE_OPS @@ -1030,8 +1004,7 @@ void rt_system_pm_init(const struct rt_pm_ops *ops, pm->ops = ops; pm->device_pm = RT_NULL; - - rt_slist_init(&pm->device_list); + pm->device_pm_number = 0; #if IDLE_THREAD_STACK_SIZE <= 256 #error "[pm.c ERR] IDLE Stack Size Too Small!" diff --git a/rt-thread/components/drivers/regulator/Kconfig b/rt-thread/components/drivers/regulator/Kconfig deleted file mode 100644 index 99bfdac..0000000 --- a/rt-thread/components/drivers/regulator/Kconfig +++ /dev/null @@ -1,23 +0,0 @@ -menuconfig RT_USING_REGULATOR - bool "Using Voltage and Current Regulator" - select RT_USING_ADT - select RT_USING_ADT_REF - depends on RT_USING_DM - default n - -config RT_REGULATOR_FIXED - bool "Fixed regulator support" - depends on RT_USING_REGULATOR - depends on RT_USING_PIN - depends on RT_USING_PINCTRL - default y - -config RT_REGULATOR_GPIO - bool "GPIO regulator support" - depends on RT_USING_REGULATOR - depends on RT_USING_PIN - default y - -if RT_USING_REGULATOR - osource "$(SOC_DM_REGULATOR_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/regulator/SConscript b/rt-thread/components/drivers/regulator/SConscript deleted file mode 100644 index 29b567f..0000000 --- a/rt-thread/components/drivers/regulator/SConscript +++ /dev/null @@ -1,21 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_USING_REGULATOR']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../include'] - -src = ['regulator.c', 'regulator_dm.c'] - -if GetDepend(['RT_REGULATOR_FIXED']): - src += ['regulator-fixed.c'] - -if GetDepend(['RT_REGULATOR_GPIO']): - src += ['regulator-gpio.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/regulator/regulator-fixed.c b/rt-thread/components/drivers/regulator/regulator-fixed.c deleted file mode 100644 index 5f5773b..0000000 --- a/rt-thread/components/drivers/regulator/regulator-fixed.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#include "regulator_dm.h" - -struct regulator_fixed -{ - struct rt_regulator_node parent; - struct rt_regulator_param param; - - rt_base_t enable_pin; - const char *input_supply; -}; - -#define raw_to_regulator_fixed(raw) rt_container_of(raw, struct regulator_fixed, parent) - -static rt_err_t regulator_fixed_enable(struct rt_regulator_node *reg_np) -{ - struct regulator_fixed *rf = raw_to_regulator_fixed(reg_np); - struct rt_regulator_param *param = &rf->param; - - if (rf->enable_pin < 0 || param->always_on) - { - return RT_EOK; - } - - rt_pin_mode(rf->enable_pin, PIN_MODE_OUTPUT); - rt_pin_write(rf->enable_pin, param->enable_active_high ? PIN_HIGH : PIN_LOW); - - return RT_EOK; -} - -static rt_err_t regulator_fixed_disable(struct rt_regulator_node *reg_np) -{ - struct regulator_fixed *rf = raw_to_regulator_fixed(reg_np); - struct rt_regulator_param *param = &rf->param; - - if (rf->enable_pin < 0 || param->always_on) - { - return RT_EOK; - } - - rt_pin_mode(rf->enable_pin, PIN_MODE_OUTPUT); - rt_pin_write(rf->enable_pin, param->enable_active_high ? PIN_LOW: PIN_HIGH); - - return RT_EOK; -} - -static rt_bool_t regulator_fixed_is_enabled(struct rt_regulator_node *reg_np) -{ - rt_uint8_t active; - struct regulator_fixed *rf = raw_to_regulator_fixed(reg_np); - struct rt_regulator_param *param = &rf->param; - - if (rf->enable_pin < 0 || param->always_on) - { - return RT_TRUE; - } - - rt_pin_mode(rf->enable_pin, PIN_MODE_INPUT); - active = rt_pin_read(rf->enable_pin); - - if (param->enable_active_high) - { - return active == PIN_HIGH; - } - - return active == PIN_LOW; -} - -static int regulator_fixed_get_voltage(struct rt_regulator_node *reg_np) -{ - struct regulator_fixed *rf = raw_to_regulator_fixed(reg_np); - - return rf->param.min_uvolt + (rf->param.max_uvolt - rf->param.min_uvolt) / 2; -} - -static const struct rt_regulator_ops regulator_fixed_ops = -{ - .enable = regulator_fixed_enable, - .disable = regulator_fixed_disable, - .is_enabled = regulator_fixed_is_enabled, - .get_voltage = regulator_fixed_get_voltage, -}; - -static rt_err_t regulator_fixed_probe(struct rt_platform_device *pdev) -{ - rt_err_t err; - rt_uint32_t val; - struct rt_device *dev = &pdev->parent; - struct regulator_fixed *rf = rt_calloc(1, sizeof(*rf)); - struct rt_regulator_node *rnp; - - if (!rf) - { - return -RT_ENOMEM; - } - - regulator_ofw_parse(dev->ofw_node, &rf->param); - - rnp = &rf->parent; - rnp->supply_name = rf->param.name; - rnp->ops = ®ulator_fixed_ops; - rnp->param = &rf->param; - rnp->dev = &pdev->parent; - - rf->enable_pin = rt_pin_get_named_pin(dev, "enable", 0, RT_NULL, RT_NULL); - - if (rf->enable_pin < 0) - { - rf->enable_pin = rt_pin_get_named_pin(dev, RT_NULL, 0, RT_NULL, RT_NULL); - } - - if (rf->enable_pin < 0) - { - rf->enable_pin = -1; - } - - rt_pin_ctrl_confs_apply(dev, 0); - - if (!rt_dm_dev_prop_read_u32(dev, "startup-delay-us", &val)) - { - rf->param.enable_delay = val; - } - - if (!rt_dm_dev_prop_read_u32(dev, "off-on-delay-us", &val)) - { - rf->param.off_on_delay = val; - } - - if ((err = rt_regulator_register(rnp))) - { - goto _fail; - } - - return RT_EOK; - -_fail: - rt_free(rf); - - return err; -} - -static const struct rt_ofw_node_id regulator_fixed_ofw_ids[] = -{ - { .compatible = "regulator-fixed" }, - { /* sentinel */ } -}; - -static struct rt_platform_driver regulator_fixed_driver = -{ - .name = "reg-fixed-voltage", - .ids = regulator_fixed_ofw_ids, - - .probe = regulator_fixed_probe, -}; - -static int regulator_fixed_register(void) -{ - rt_platform_driver_register(®ulator_fixed_driver); - - return 0; -} -INIT_SUBSYS_EXPORT(regulator_fixed_register); diff --git a/rt-thread/components/drivers/regulator/regulator-gpio.c b/rt-thread/components/drivers/regulator/regulator-gpio.c deleted file mode 100644 index 0698318..0000000 --- a/rt-thread/components/drivers/regulator/regulator-gpio.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#include - -#include "regulator_dm.h" - -struct regulator_gpio_state -{ - rt_uint32_t value; - rt_uint32_t gpios; -}; - -struct regulator_gpio_desc -{ - rt_base_t pin; - rt_uint32_t flags; -}; - -struct regulator_gpio -{ - struct rt_regulator_node parent; - - rt_base_t enable_pin; - - rt_size_t pins_nr; - struct regulator_gpio_desc *pins_desc; - - int state; - rt_size_t states_nr; - struct regulator_gpio_state *states; - - const char *input_supply; - rt_uint32_t startup_delay; - rt_uint32_t off_on_delay; - rt_bool_t enabled_at_boot; - struct rt_regulator_param param; -}; - -#define raw_to_regulator_gpio(raw) rt_container_of(raw, struct regulator_gpio, parent) - -static rt_err_t regulator_gpio_enable(struct rt_regulator_node *reg_np) -{ - struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np); - struct rt_regulator_param *param = &rg->param; - - if (param->always_on) - { - return RT_EOK; - } - - if (rg->enable_pin >= 0) - { - rt_pin_mode(rg->enable_pin, PIN_MODE_OUTPUT); - rt_pin_write(rg->enable_pin, param->enable_active_high ? PIN_HIGH : PIN_LOW); - } - - return RT_EOK; -} - -static rt_err_t regulator_gpio_disable(struct rt_regulator_node *reg_np) -{ - struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np); - struct rt_regulator_param *param = &rg->param; - - if (param->always_on) - { - return RT_EOK; - } - - if (rg->enable_pin >= 0) - { - rt_pin_mode(rg->enable_pin, PIN_MODE_OUTPUT); - rt_pin_write(rg->enable_pin, param->enable_active_high ? PIN_LOW : PIN_HIGH); - } - - return RT_EOK; -} - -static rt_bool_t regulator_gpio_is_enabled(struct rt_regulator_node *reg_np) -{ - struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np); - struct rt_regulator_param *param = &rg->param; - - if (param->always_on) - { - return RT_TRUE; - } - - if (rg->enable_pin >= 0) - { - rt_uint8_t active_val = param->enable_active_high ? PIN_LOW : PIN_HIGH; - - rt_pin_mode(rg->enable_pin, PIN_MODE_INPUT); - return rt_pin_read(rg->enable_pin) == active_val; - } - - return RT_TRUE; -} - -static rt_err_t regulator_gpio_set_voltage(struct rt_regulator_node *reg_np, - int min_uvolt, int max_uvolt) -{ - int target = 0, best_val = RT_REGULATOR_UVOLT_INVALID; - struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np); - - for (int i = 0; i < rg->states_nr; ++i) - { - struct regulator_gpio_state *state = &rg->states[i]; - - if (state->value < best_val && - state->value >= min_uvolt && - state->value <= max_uvolt) - { - target = state->gpios; - best_val = state->value; - } - } - - if (best_val == RT_REGULATOR_UVOLT_INVALID) - { - return -RT_EINVAL; - } - - for (int i = 0; i < rg->pins_nr; ++i) - { - int state = (target >> i) & 1; - struct regulator_gpio_desc *gpiod = &rg->pins_desc[i]; - - rt_pin_mode(gpiod->pin, PIN_MODE_OUTPUT); - rt_pin_write(gpiod->pin, gpiod->flags == PIND_OUT_HIGH ? state : !state); - } - - rg->state = target; - - return RT_EOK; -} - -static int regulator_gpio_get_voltage(struct rt_regulator_node *reg_np) -{ - struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np); - - for (int i = 0; i < rg->states_nr; ++i) - { - if (rg->states[i].gpios == rg->state) - { - return rg->states[i].value; - } - } - - return -RT_EINVAL; -} - -static const struct rt_regulator_ops regulator_gpio_ops = -{ - .enable = regulator_gpio_enable, - .disable = regulator_gpio_disable, - .is_enabled = regulator_gpio_is_enabled, - .set_voltage = regulator_gpio_set_voltage, - .get_voltage = regulator_gpio_get_voltage, -}; - -static rt_err_t regulator_gpio_probe(struct rt_platform_device *pdev) -{ - rt_err_t err; - struct rt_device *dev = &pdev->parent; - struct regulator_gpio *rg = rt_calloc(1, sizeof(*rg)); - struct rt_regulator_node *rgp; - - if (!rg) - { - return -RT_ENOMEM; - } - - regulator_ofw_parse(dev->ofw_node, &rg->param); - - rgp = &rg->parent; - rgp->supply_name = rg->param.name; - rgp->ops = ®ulator_gpio_ops; - rgp->param = &rg->param; - rgp->dev = &pdev->parent; - - rt_dm_dev_prop_read_u32(dev, "startup-delay-us", &rg->startup_delay); - rt_dm_dev_prop_read_u32(dev, "off-on-delay-us", &rg->off_on_delay); - - /* GPIO flags are ignored, we check by enable-active-high */ - rg->enable_pin = rt_pin_get_named_pin(dev, "enable", 0, RT_NULL, RT_NULL); - - if (rg->enable_pin < 0 && rg->enable_pin != -RT_EEMPTY) - { - err = rg->enable_pin; - goto _fail; - } - - rg->pins_nr = rt_pin_get_named_pin_count(dev, "gpios"); - - if (rg->pins_nr > 0) - { - rg->pins_desc = rt_malloc(sizeof(*rg->pins_desc) * rg->pins_nr); - - if (!rg->pins_desc) - { - err = -RT_ENOMEM; - - goto _fail; - } - - for (int i = 0; i < rg->pins_nr; ++i) - { - rt_uint32_t val; - struct regulator_gpio_desc *gpiod = &rg->pins_desc[i]; - - gpiod->pin = rt_pin_get_named_pin(dev, RT_NULL, i, RT_NULL, RT_NULL); - - if (gpiod->pin < 0) - { - err = gpiod->pin; - goto _fail; - } - - if (rt_dm_dev_prop_read_u32_index(dev, "gpios-states", i, &val) < 0) - { - gpiod->flags = PIND_OUT_HIGH; - } - else - { - gpiod->flags = val ? PIND_OUT_HIGH : PIND_OUT_LOW; - } - - if (gpiod->flags == PIND_OUT_HIGH) - { - rg->state |= 1 << i; - } - } - } - - rg->states_nr = rt_dm_dev_prop_count_of_u32(dev, "states") / 2; - - if (rg->states_nr < 0) - { - err = -RT_EIO; - - goto _fail; - } - - rg->states = rt_malloc(sizeof(*rg->states) * rg->states_nr); - - if (!rg->states) - { - err = -RT_ENOMEM; - - goto _fail; - } - - for (int i = 0; i < rg->states_nr; ++i) - { - rt_dm_dev_prop_read_u32_index(dev, "states", i * 2, &rg->states[i].value); - rt_dm_dev_prop_read_u32_index(dev, "states", i * 2 + 1, &rg->states[i].gpios); - } - - if ((err = rt_regulator_register(rgp))) - { - goto _fail; - } - - return RT_EOK; - -_fail: - if (rg->pins_desc) - { - rt_free(rg->pins_desc); - } - if (rg->states) - { - rt_free(rg->states); - } - rt_free(rg); - - return err; -} - -static const struct rt_ofw_node_id regulator_gpio_ofw_ids[] = -{ - { .compatible = "regulator-gpio" }, - { /* sentinel */ } -}; - -static struct rt_platform_driver regulator_gpio_driver = -{ - .name = "regulator-gpio", - .ids = regulator_gpio_ofw_ids, - - .probe = regulator_gpio_probe, -}; - -static int regulator_gpio_register(void) -{ - rt_platform_driver_register(®ulator_gpio_driver); - - return 0; -} -INIT_SUBSYS_EXPORT(regulator_gpio_register); diff --git a/rt-thread/components/drivers/regulator/regulator.c b/rt-thread/components/drivers/regulator/regulator.c deleted file mode 100644 index 29071e9..0000000 --- a/rt-thread/components/drivers/regulator/regulator.c +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#include -#include - -#define DBG_TAG "rtdm.regulator" -#define DBG_LVL DBG_INFO -#include - -#include -#include -#include - -struct rt_regulator -{ - struct rt_regulator_node *reg_np; -}; - -static struct rt_spinlock _regulator_lock = { 0 }; - -static rt_err_t regulator_enable(struct rt_regulator_node *reg_np); -static rt_err_t regulator_disable(struct rt_regulator_node *reg_np); - -rt_err_t rt_regulator_register(struct rt_regulator_node *reg_np) -{ - const struct rt_regulator_param *param; - - if (!reg_np || !reg_np->dev || !reg_np->param || !reg_np->ops) - { - return -RT_EINVAL; - } - - rt_list_init(®_np->list); - rt_list_init(®_np->children_nodes); - rt_list_init(®_np->notifier_nodes); - rt_ref_init(®_np->ref); - rt_atomic_store(®_np->enabled_count, 0); - - param = reg_np->param; - - reg_np->parent = RT_NULL; - -#ifdef RT_USING_OFW - if (reg_np->dev->ofw_node) - { - rt_ofw_data(reg_np->dev->ofw_node) = reg_np; - } -#endif /* RT_USING_OFW */ - - if (param->boot_on || param->always_on) - { - regulator_enable(reg_np); - } - - return RT_EOK; -} - -rt_err_t rt_regulator_unregister(struct rt_regulator_node *reg_np) -{ - rt_err_t err = RT_EOK; - - if (!reg_np) - { - return -RT_EINVAL; - } - - rt_hw_spin_lock(&_regulator_lock.lock); - - if (rt_atomic_load(®_np->enabled_count) != 0) - { - err = -RT_EBUSY; - - LOG_E("%s was enabled by consumer", reg_np->supply_name); - - goto _unlock; - } - - if (!(reg_np->param->boot_on || reg_np->param->always_on)) - { - regulator_disable(reg_np); - } - - if (!rt_list_isempty(®_np->children_nodes) || rt_ref_read(®_np->ref) > 1) - { - err = -RT_EBUSY; - - goto _unlock; - } - - reg_np->parent = RT_NULL; - rt_list_remove(®_np->list); - -_unlock: - rt_hw_spin_unlock(&_regulator_lock.lock); - - return err; -} - -rt_err_t rt_regulator_notifier_register(struct rt_regulator *reg, - struct rt_regulator_notifier *notifier) -{ - struct rt_regulator_node *reg_np; - - if (!reg || !notifier) - { - return -RT_EINVAL; - } - - rt_hw_spin_lock(&_regulator_lock.lock); - - reg_np = reg->reg_np; - notifier->regulator = reg; - - rt_list_init(¬ifier->list); - rt_list_insert_after(®_np->notifier_nodes, ¬ifier->list); - - rt_hw_spin_unlock(&_regulator_lock.lock); - - return RT_EOK; -} - -rt_err_t rt_regulator_notifier_unregister(struct rt_regulator *reg, - struct rt_regulator_notifier *notifier) -{ - if (!reg || !notifier) - { - return -RT_EINVAL; - } - - rt_hw_spin_lock(&_regulator_lock.lock); - - rt_list_remove(¬ifier->list); - - rt_hw_spin_unlock(&_regulator_lock.lock); - - return RT_EOK; -} - -static rt_err_t regulator_notifier_call_chain(struct rt_regulator_node *reg_np, - rt_ubase_t msg, void *data) -{ - rt_err_t err = RT_EOK; - struct rt_regulator_notifier *notifier; - rt_list_t *head = ®_np->notifier_nodes; - - if (rt_list_isempty(head)) - { - return err; - } - - rt_list_for_each_entry(notifier, head, list) - { - err = notifier->callback(notifier, msg, data); - - if (err == -RT_EIO) - { - break; - } - } - - return err; -} - -static rt_uint32_t regulator_get_enable_time(struct rt_regulator_node *reg_np) -{ - if (reg_np->param->enable_delay) - { - return reg_np->param->enable_delay; - } - - if (reg_np->ops->enable_time) - { - return reg_np->ops->enable_time(reg_np); - } - - return 0; -} - -static void regulator_delay(rt_uint32_t delay) -{ - rt_uint32_t ms = delay / 1000; - rt_uint32_t us = delay % 1000; - - if (ms > 0) - { - /* - * For small enough values, handle super-millisecond - * delays in the usleep_range() call below. - */ - if (ms < 20) - { - us += ms * 1000; - } - else if (rt_thread_self()) - { - rt_thread_mdelay(ms); - } - else - { - rt_hw_us_delay(ms * 1000); - } - } - - /* - * Give the scheduler some room to coalesce with any other - * wakeup sources. For delays shorter than 10 us, don't even - * bother setting up high-resolution timers and just busy-loop. - */ - if (us >= 10) - { - rt_hw_us_delay((us + 100) >> 1); - } - else - { - rt_hw_us_delay(us); - } -} - -static rt_err_t regulator_enable(struct rt_regulator_node *reg_np) -{ - rt_err_t err = RT_EOK; - rt_uint32_t enable_delay = regulator_get_enable_time(reg_np); - - if (reg_np->ops->enable) - { - err = reg_np->ops->enable(reg_np); - - if (!err) - { - if (enable_delay) - { - regulator_delay(enable_delay); - } - - rt_atomic_add(®_np->enabled_count, 1); - err = regulator_notifier_call_chain(reg_np, RT_REGULATOR_MSG_ENABLE, RT_NULL); - } - } - - if (!err && reg_np->parent) - { - err = regulator_enable(reg_np->parent); - } - - return err; -} - -rt_err_t rt_regulator_enable(struct rt_regulator *reg) -{ - rt_err_t err; - - if (!reg) - { - return -RT_EINVAL; - } - - if (rt_regulator_is_enabled(reg)) - { - return RT_EOK; - } - - rt_hw_spin_lock(&_regulator_lock.lock); - - err = regulator_enable(reg->reg_np); - - rt_hw_spin_unlock(&_regulator_lock.lock); - - return err; -} - -static rt_err_t regulator_disable(struct rt_regulator_node *reg_np) -{ - rt_err_t err = RT_EOK; - - if (reg_np->ops->disable) - { - err = reg_np->ops->disable(reg_np); - - if (!err) - { - if (reg_np->param->off_on_delay) - { - regulator_delay(reg_np->param->off_on_delay); - } - - err = regulator_notifier_call_chain(reg_np, RT_REGULATOR_MSG_DISABLE, RT_NULL); - } - } - - if (!err && reg_np->parent) - { - err = regulator_disable(reg_np->parent); - } - - return err; -} - -rt_err_t rt_regulator_disable(struct rt_regulator *reg) -{ - rt_err_t err; - - if (!reg) - { - return -RT_EINVAL; - } - - if (!rt_regulator_is_enabled(reg)) - { - return RT_EOK; - } - - if (rt_atomic_load(®->reg_np->enabled_count) != 0) - { - rt_atomic_sub(®->reg_np->enabled_count, 1); - - return RT_EOK; - } - - rt_hw_spin_lock(&_regulator_lock.lock); - - err = regulator_disable(reg->reg_np); - - rt_hw_spin_unlock(&_regulator_lock.lock); - - return err; -} - -rt_bool_t rt_regulator_is_enabled(struct rt_regulator *reg) -{ - if (!reg) - { - return -RT_EINVAL; - } - - if (reg->reg_np->ops->is_enabled) - { - return reg->reg_np->ops->is_enabled(reg->reg_np); - } - - return rt_atomic_load(®->reg_np->enabled_count) > 0; -} - -static rt_err_t regulator_set_voltage(struct rt_regulator_node *reg_np, int min_uvolt, int max_uvolt) -{ - rt_err_t err = RT_EOK; - - if (reg_np->ops->set_voltage) - { - union rt_regulator_notifier_args args; - - RT_ASSERT(reg_np->ops->get_voltage != RT_NULL); - - args.old_uvolt = reg_np->ops->get_voltage(reg_np); - args.min_uvolt = min_uvolt; - args.max_uvolt = max_uvolt; - - err = regulator_notifier_call_chain(reg_np, RT_REGULATOR_MSG_VOLTAGE_CHANGE, &args); - - if (!err) - { - err = reg_np->ops->set_voltage(reg_np, min_uvolt, max_uvolt); - } - - if (err) - { - regulator_notifier_call_chain(reg_np, RT_REGULATOR_MSG_VOLTAGE_CHANGE_ERR, - (void *)(rt_base_t)args.old_uvolt); - } - } - - if (!err && reg_np->parent) - { - err = regulator_set_voltage(reg_np->parent, min_uvolt, max_uvolt); - } - - return err; -} - -rt_bool_t rt_regulator_is_supported_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt) -{ - const struct rt_regulator_param *param; - - RT_ASSERT(reg != RT_NULL); - - param = reg->reg_np->param; - - if (!param) - { - return RT_FALSE; - } - - return param->min_uvolt <= min_uvolt && param->max_uvolt >= max_uvolt; -} - -rt_err_t rt_regulator_set_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt) -{ - rt_err_t err; - - if (!reg) - { - return -RT_EINVAL; - } - - rt_hw_spin_lock(&_regulator_lock.lock); - - err = regulator_set_voltage(reg->reg_np, min_uvolt, max_uvolt); - - rt_hw_spin_unlock(&_regulator_lock.lock); - - return err; -} - -int rt_regulator_get_voltage(struct rt_regulator *reg) -{ - int uvolt = RT_REGULATOR_UVOLT_INVALID; - struct rt_regulator_node *reg_np; - - if (!reg) - { - return -RT_EINVAL; - } - - rt_hw_spin_lock(&_regulator_lock.lock); - - reg_np = reg->reg_np; - - if (reg_np->ops->get_voltage) - { - uvolt = reg_np->ops->get_voltage(reg->reg_np); - } - else - { - uvolt = -RT_ENOSYS; - } - - rt_hw_spin_unlock(&_regulator_lock.lock); - - return uvolt; -} - -rt_err_t rt_regulator_set_mode(struct rt_regulator *reg, rt_uint32_t mode) -{ - rt_err_t err; - struct rt_regulator_node *reg_np; - - if (!reg) - { - return -RT_EINVAL; - } - - rt_hw_spin_lock(&_regulator_lock.lock); - - reg_np = reg->reg_np; - - if (reg_np->ops->set_mode) - { - err = reg_np->ops->set_mode(reg_np, mode); - } - else - { - err = -RT_ENOSYS; - } - - rt_hw_spin_unlock(&_regulator_lock.lock); - - return err; -} - -rt_int32_t rt_regulator_get_mode(struct rt_regulator *reg) -{ - rt_int32_t mode; - struct rt_regulator_node *reg_np; - - if (!reg) - { - return -RT_EINVAL; - } - - rt_hw_spin_lock(&_regulator_lock.lock); - - reg_np = reg->reg_np; - - if (reg_np->ops->get_mode) - { - mode = reg_np->ops->get_mode(reg_np); - } - else - { - mode = -RT_ENOSYS; - } - - rt_hw_spin_unlock(&_regulator_lock.lock); - - return mode; -} - -static void regulator_check_parent(struct rt_regulator_node *reg_np) -{ - if (reg_np->parent) - { - return; - } - else - { - #ifdef RT_USING_OFW - rt_phandle parent_phandle = 0; - struct rt_ofw_node *np = reg_np->dev->ofw_node; - - while (np) - { - if (rt_ofw_prop_read_u32(np, "vin-supply", &parent_phandle)) - { - break; - } - - if (!(np = rt_ofw_find_node_by_phandle(parent_phandle))) - { - break; - } - - if (!(reg_np->parent = rt_ofw_data(np))) - { - LOG_W("%s parent ofw node = %s not init", - reg_np->supply_name, rt_ofw_node_full_name(np)); - - rt_ofw_node_put(np); - break; - } - - rt_list_insert_after(®_np->parent->children_nodes, ®_np->list); - rt_ofw_node_put(np); - } - #endif - } -} - -struct rt_regulator *rt_regulator_get(struct rt_device *dev, const char *id) -{ - struct rt_regulator *reg = RT_NULL; - struct rt_regulator_node *reg_np = RT_NULL; - - if (!dev || !id) - { - reg = rt_err_ptr(-RT_EINVAL); - goto _end; - } - -#ifdef RT_USING_OFW - if (dev->ofw_node) - { - rt_phandle supply_phandle; - struct rt_ofw_node *np = dev->ofw_node; - char supply_name[64]; - - rt_snprintf(supply_name, sizeof(supply_name), "%s-supply", id); - - if (rt_ofw_prop_read_u32(np, supply_name, &supply_phandle)) - { - goto _end; - } - - if (!(np = rt_ofw_find_node_by_phandle(supply_phandle))) - { - reg = rt_err_ptr(-RT_EIO); - goto _end; - } - - if (!rt_ofw_data(np)) - { - rt_platform_ofw_request(np); - } - - reg_np = rt_ofw_data(np); - rt_ofw_node_put(np); - } -#endif - - if (!reg_np) - { - reg = rt_err_ptr(-RT_ENOSYS); - goto _end; - } - - rt_hw_spin_lock(&_regulator_lock.lock); - - regulator_check_parent(reg_np); - - rt_hw_spin_unlock(&_regulator_lock.lock); - - reg = rt_calloc(1, sizeof(*reg)); - - if (!reg) - { - reg = rt_err_ptr(-RT_ENOMEM); - goto _end; - } - - reg->reg_np = reg_np; - rt_ref_get(®_np->ref); - -_end: - return reg; -} - -static void regulator_release(struct rt_ref *r) -{ - struct rt_regulator_node *reg_np = rt_container_of(r, struct rt_regulator_node, ref); - - rt_regulator_unregister(reg_np); -} - -void rt_regulator_put(struct rt_regulator *reg) -{ - if (!reg) - { - return; - } - - rt_ref_put(®->reg_np->ref, ®ulator_release); - rt_free(reg); -} diff --git a/rt-thread/components/drivers/regulator/regulator_dm.c b/rt-thread/components/drivers/regulator/regulator_dm.c deleted file mode 100644 index d8096c4..0000000 --- a/rt-thread/components/drivers/regulator/regulator_dm.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#include "regulator_dm.h" - -#ifdef RT_USING_OFW -rt_err_t regulator_ofw_parse(struct rt_ofw_node *np, struct rt_regulator_param *param) -{ - rt_uint32_t pval; - - param->name = rt_ofw_prop_read_raw(np, "regulator-name", RT_NULL); - - if (!rt_ofw_prop_read_u32(np, "regulator-min-microvolt", &pval)) - { - param->min_uvolt = pval; - } - - if (!rt_ofw_prop_read_u32(np, "regulator-max-microvolt", &pval)) - { - param->max_uvolt = pval; - } - - if (!rt_ofw_prop_read_u32(np, "regulator-min-microamp", &pval)) - { - param->min_uamp = pval; - } - - if (!rt_ofw_prop_read_u32(np, "regulator-max-microamp", &pval)) - { - param->max_uamp = pval; - } - - if (!rt_ofw_prop_read_u32(np, "regulator-ramp-delay", &pval)) - { - param->ramp_delay = pval; - } - - if (!rt_ofw_prop_read_u32(np, "regulator-enable-ramp-delay", &pval)) - { - param->enable_delay = pval; - } - - param->enable_active_high = rt_ofw_prop_read_bool(np, "enable-active-high"); - param->boot_on = rt_ofw_prop_read_bool(np, "regulator-boot-on"); - param->always_on = rt_ofw_prop_read_bool(np, "regulator-always-on"); - param->soft_start = rt_ofw_prop_read_bool(np, "regulator-soft-start"); - param->pull_down = rt_ofw_prop_read_bool(np, "regulator-pull-down"); - param->over_current_protection = rt_ofw_prop_read_bool(np, "regulator-over-current-protection"); - - return RT_EOK; -} -#endif /* RT_USING_OFW */ diff --git a/rt-thread/components/drivers/regulator/regulator_dm.h b/rt-thread/components/drivers/regulator/regulator_dm.h deleted file mode 100644 index 207bb12..0000000 --- a/rt-thread/components/drivers/regulator/regulator_dm.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-09-23 GuEe-GUI first version - */ - -#ifndef __REGULATOR_DM_H__ -#define __REGULATOR_DM_H__ - -#include -#include - -#ifdef RT_USING_OFW -rt_err_t regulator_ofw_parse(struct rt_ofw_node *np, struct rt_regulator_param *param); -#else -rt_inline rt_err_t regulator_ofw_parse(struct rt_ofw_node *np, struct rt_regulator_param *param); -{ - return RT_EOK; -} -#endif /* RT_USING_OFW */ - -#endif /* __REGULATOR_DM_H__ */ diff --git a/rt-thread/components/drivers/reset/Kconfig b/rt-thread/components/drivers/reset/Kconfig deleted file mode 100644 index ccba575..0000000 --- a/rt-thread/components/drivers/reset/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -menuconfig RT_USING_RESET - bool "Using Reset Controller support" - depends on RT_USING_DM - depends on RT_USING_OFW - default n - -config RT_RESET_SIMPLE - bool "Simple Reset Controller Driver" - depends on RT_USING_RESET - default n - -if RT_USING_RESET - osource "$(SOC_DM_RESET_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/reset/SConscript b/rt-thread/components/drivers/reset/SConscript deleted file mode 100644 index 8e64f78..0000000 --- a/rt-thread/components/drivers/reset/SConscript +++ /dev/null @@ -1,18 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_USING_RESET']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../include'] - -src = ['reset.c'] - -if GetDepend(['RT_RESET_SIMPLE']): - src += ['reset-simple.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/reset/reset-simple.c b/rt-thread/components/drivers/reset/reset-simple.c deleted file mode 100644 index e66cb8e..0000000 --- a/rt-thread/components/drivers/reset/reset-simple.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-26 GuEe-GUI first version - */ - -#include "reset-simple.h" - -struct reset_simple_data -{ - rt_uint32_t reg_offset; - rt_bool_t active_low; - rt_bool_t status_active_low; -}; - -#define raw_to_reset_simple(raw) rt_container_of(raw, struct reset_simple, parent) - -static rt_err_t reset_simple_update(struct reset_simple *rsts, int id, rt_bool_t assert) -{ - rt_uint32_t reg; - rt_ubase_t level; - int reg_width = sizeof(rt_uint32_t); - int bank = id / (reg_width * 8); - int offset = id % (reg_width * 8); - - level = rt_spin_lock_irqsave(&rsts->lock); - - reg = HWREG32(rsts->mmio_base + (bank * reg_width)); - - if (assert ^ rsts->active_low) - { - reg |= RT_BIT(offset); - } - else - { - reg &= ~RT_BIT(offset); - } - - HWREG32(rsts->mmio_base + (bank * reg_width)) = reg; - - rt_spin_unlock_irqrestore(&rsts->lock, level); - - return RT_EOK; -} - -static rt_err_t reset_simple_assert(struct rt_reset_control *rstc) -{ - struct reset_simple *rsts = raw_to_reset_simple(rstc); - - return reset_simple_update(rsts, rstc->id, RT_TRUE); -} - -static rt_err_t reset_simple_deassert(struct rt_reset_control *rstc) -{ - struct reset_simple *rsts = raw_to_reset_simple(rstc); - - return reset_simple_update(rsts, rstc->id, RT_FALSE); -} - -static rt_err_t reset_simple_reset(struct rt_reset_control *rstc) -{ - rt_err_t err; - struct reset_simple *rsts = raw_to_reset_simple(rstc); - - if (!rsts->reset_us) - { - return -RT_ENOSYS; - } - - if ((err = reset_simple_assert(rstc))) - { - return err; - } - - rt_hw_us_delay(rsts->reset_us + (rsts->reset_us >> 1)); - - return reset_simple_deassert(rstc); -} - -static int reset_simple_status(struct rt_reset_control *rstc) -{ - rt_uint32_t value; - int reg_width = sizeof(rt_uint32_t); - int bank = rstc->id / (reg_width * 8); - int offset = rstc->id % (reg_width * 8); - struct reset_simple *rsts = raw_to_reset_simple(rstc); - - value = HWREG32(rsts->mmio_base + (bank * reg_width)); - - return !(value & RT_BIT(offset)) ^ !rsts->status_active_low; -} - -const struct rt_reset_control_ops reset_simple_ops = -{ - .reset = reset_simple_reset, - .assert = reset_simple_assert, - .deassert = reset_simple_deassert, - .status = reset_simple_status, -}; - -static rt_err_t reset_simple_probe(struct rt_platform_device *pdev) -{ - rt_err_t err; - struct rt_reset_controller *rstcer; - struct rt_device *dev = &pdev->parent; - const struct reset_simple_data *rsts_data = pdev->id->data; - struct reset_simple *rsts = rt_calloc(1, sizeof(*rsts)); - - if (!rsts) - { - return -RT_ENOMEM; - } - - rsts->mmio_base = rt_dm_dev_iomap(dev, 0); - - if (!rsts->mmio_base) - { - err = -RT_EIO; - goto _fail; - } - - rt_spin_lock_init(&rsts->lock); - - rstcer = &rsts->parent; - - rstcer->priv = rsts; - rstcer->ofw_node = dev->ofw_node; - rstcer->ops = &reset_simple_ops; - - if ((err = rt_reset_controller_register(rstcer))) - { - goto _fail; - } - - if (rsts_data) - { - rsts->mmio_base += rsts_data->reg_offset; - rsts->active_low = rsts_data->active_low; - rsts->status_active_low = rsts_data->status_active_low; - } - - return RT_EOK; - -_fail: - if (rsts->mmio_base) - { - rt_iounmap(rsts->mmio_base); - } - - rt_free(rsts); - - return err; -} - -static const struct reset_simple_data reset_simple_socfpga = -{ - .reg_offset = 0x20, - .status_active_low = RT_TRUE, -}; - -static const struct reset_simple_data reset_simple_active_low = -{ - .active_low = RT_TRUE, - .status_active_low = RT_TRUE, -}; - -static const struct rt_ofw_node_id reset_simple_ofw_ids[] = -{ - { .compatible = "altr,stratix10-rst-mgr", .data = &reset_simple_socfpga }, - { .compatible = "st,stm32-rcc", }, - { .compatible = "allwinner,sun6i-a31-clock-reset", .data = &reset_simple_active_low }, - { .compatible = "zte,zx296718-reset", .data = &reset_simple_active_low }, - { .compatible = "aspeed,ast2400-lpc-reset" }, - { .compatible = "aspeed,ast2500-lpc-reset" }, - { .compatible = "aspeed,ast2600-lpc-reset" }, - { .compatible = "bitmain,bm1880-reset", .data = &reset_simple_active_low }, - { .compatible = "brcm,bcm4908-misc-pcie-reset", .data = &reset_simple_active_low }, - { .compatible = "snps,dw-high-reset" }, - { .compatible = "snps,dw-low-reset", .data = &reset_simple_active_low }, - { .compatible = "sophgo,sg2042-reset", .data = &reset_simple_active_low }, - { /* sentinel */ } -}; - -static struct rt_platform_driver reset_simple_driver = -{ - .name = "reset-simple", - .ids = reset_simple_ofw_ids, - - .probe = reset_simple_probe, -}; - -static int reset_simple_register(void) -{ - rt_platform_driver_register(&reset_simple_driver); - - return 0; -} -INIT_SUBSYS_EXPORT(reset_simple_register); diff --git a/rt-thread/components/drivers/reset/reset-simple.h b/rt-thread/components/drivers/reset/reset-simple.h deleted file mode 100644 index 8223d69..0000000 --- a/rt-thread/components/drivers/reset/reset-simple.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-26 GuEe-GUI first version - */ - -#ifndef __RESET_SIMPLE_H__ -#define __RESET_SIMPLE_H__ - -#include -#include - -struct reset_simple -{ - struct rt_reset_controller parent; - - void *mmio_base; - - /* - * If true, bits are cleared to assert the reset. - * Otherwise, bits are set to assert the reset. - */ - rt_bool_t active_low; - /* - * If true, bits read back as cleared while the reset is asserted. - * Otherwise, bits read back as set while the reset is asserted. - */ - rt_bool_t status_active_low; - - /* - * Minimum delay in microseconds needed that needs to be - * waited for between an assert and a deassert to reset the device. - * If multiple consumers with different delay - * requirements are connected to this controller, it must - * be the largest minimum delay. 0 means that such a delay is - * unknown and the reset operation is unsupported. - */ - rt_uint32_t reset_us; - - /* protect registers during read-modify-write cycles */ - struct rt_spinlock lock; -}; - -extern const struct rt_reset_control_ops reset_simple_ops; - -#endif /* __RESET_SIMPLE_H__ */ diff --git a/rt-thread/components/drivers/reset/reset.c b/rt-thread/components/drivers/reset/reset.c deleted file mode 100644 index 290d2a7..0000000 --- a/rt-thread/components/drivers/reset/reset.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-26 GuEe-GUI first version - */ - -#include -#include - -#define DBG_TAG "rtdm.reset" -#define DBG_LVL DBG_INFO -#include - -#include -#include -#include -#include - -struct reset_control_array -{ - struct rt_reset_control captain; - - rt_size_t count; - struct rt_reset_control *rstcs[]; -}; - -#define reset_control_to_array(rstc) rt_container_of(rstc, struct reset_control_array, captain) - -rt_err_t rt_reset_controller_register(struct rt_reset_controller *rstcer) -{ - if (!rstcer) - { - return -RT_EINVAL; - } - -#if RT_NAME_MAX > 0 - rt_strncpy(rstcer->parent.name, RT_RESET_CONTROLLER_OBJ_NAME, RT_NAME_MAX); -#else - rstcer->parent.name = RT_RESET_CONTROLLER_OBJ_NAME; -#endif - - rt_list_init(&rstcer->rstc_nodes); - rt_spin_lock_init(&rstcer->spinlock); - - if (rstcer->ofw_node) - { - if (!rt_ofw_data(rstcer->ofw_node)) - { - rt_ofw_data(rstcer->ofw_node) = rstcer; - } - } - - return RT_EOK; -} - -rt_err_t rt_reset_controller_unregister(struct rt_reset_controller *rstcer) -{ - rt_err_t err = RT_EOK; - - if (!rstcer) - { - return -RT_EINVAL; - } - - rt_spin_lock(&rstcer->spinlock); - - if (!rt_list_isempty(&rstcer->rstc_nodes)) - { - err = -RT_EBUSY; - goto _out_lock; - } - -_out_lock: - rt_spin_unlock(&rstcer->spinlock); - - return err; -} - -rt_err_t rt_reset_control_reset(struct rt_reset_control *rstc) -{ - rt_err_t err; - - if (!rstc) - { - return RT_EOK; - } - - if (rstc->rstcer->ops->reset) - { - if ((err = rstc->rstcer->ops->reset(rstc))) - { - return err; - } - } - - if (rstc->is_array) - { - struct reset_control_array *rstc_arr = reset_control_to_array(rstc); - - for (int i = 0; i < rstc_arr->count; ++i) - { - if ((err = rt_reset_control_reset(rstc_arr->rstcs[i]))) - { - return err; - } - } - } - - return RT_EOK; -} - -rt_err_t rt_reset_control_assert(struct rt_reset_control *rstc) -{ - rt_err_t err; - - if (!rstc) - { - return RT_EOK; - } - - if (rstc->rstcer->ops->assert) - { - if ((err = rstc->rstcer->ops->assert(rstc))) - { - return err; - } - } - - if (rstc->is_array) - { - struct reset_control_array *rstc_arr = reset_control_to_array(rstc); - - for (int i = 0; i < rstc_arr->count; ++i) - { - if ((err = rt_reset_control_assert(rstc_arr->rstcs[i]))) - { - if (rstc->rstcer->ops->deassert) - { - rstc->rstcer->ops->deassert(rstc); - } - - while (i --> 0) - { - rt_reset_control_deassert(rstc_arr->rstcs[i]); - } - - return err; - } - } - } - - return RT_EOK; -} - -rt_err_t rt_reset_control_deassert(struct rt_reset_control *rstc) -{ - rt_err_t err; - - if (!rstc) - { - return RT_EOK; - } - - if (rstc->rstcer->ops->deassert) - { - if ((err = rstc->rstcer->ops->deassert(rstc))) - { - return err; - } - } - - if (rstc->is_array) - { - struct reset_control_array *rstc_arr = reset_control_to_array(rstc); - - for (int i = 0; i < rstc_arr->count; ++i) - { - if ((err = rt_reset_control_deassert(rstc_arr->rstcs[i]))) - { - if (rstc->rstcer->ops->assert) - { - rstc->rstcer->ops->assert(rstc); - } - - while (i --> 0) - { - rt_reset_control_assert(rstc_arr->rstcs[i]); - } - - return err; - } - } - } - - return RT_EOK; -} - -int rt_reset_control_status(struct rt_reset_control *rstc) -{ - if (!rstc) - { - return RT_EOK; - } - - if (rstc->rstcer->ops->status) - { - return rstc->rstcer->ops->status(rstc); - } - - return -RT_ENOSYS; -} - -static void reset_free(struct rt_reset_control *rstc) -{ - if (rstc->is_array) - { - struct reset_control_array *rstc_arr = reset_control_to_array(rstc); - - for (int i = 0; i < rstc_arr->count; ++i) - { - rt_reset_control_put(rstc_arr->rstcs[i]); - } - } - - rt_free(rstc); -} - -struct rt_reset_control *rt_reset_control_get_array(struct rt_device *dev) -{ - return rt_ofw_get_reset_control_array(dev->ofw_node); -} - -struct rt_reset_control *rt_reset_control_get_by_index(struct rt_device *dev, int index) -{ - return rt_ofw_get_reset_control_by_index(dev->ofw_node, index); -} - -struct rt_reset_control *rt_reset_control_get_by_name(struct rt_device *dev, const char *name) -{ - return rt_ofw_get_reset_control_by_name(dev->ofw_node, name); -} - -void rt_reset_control_put(struct rt_reset_control *rstc) -{ - struct rt_reset_controller *rstcer; - - if (!rstc) - { - return; - } - - rstcer = rstc->rstcer; - - rt_spin_lock(&rstcer->spinlock); - - rt_list_remove(&rstc->list); - - rt_spin_unlock(&rstcer->spinlock); - - reset_free(rstc); -} - -static struct rt_reset_control *ofw_get_reset_control(struct rt_ofw_node *np, int index, - const char *name, rt_bool_t is_array) -{ - rt_err_t err = RT_EOK; - struct rt_reset_control *rstc; - struct rt_ofw_cell_args reset_args = {}; - struct rt_reset_controller *rstcer = RT_NULL; - - if (is_array) - { - rt_size_t rstc_nr; - struct reset_control_array *rstc_arr; - - rstc_nr = rt_ofw_count_phandle_cells(np, "resets", "#reset-cells"); - - if (!rstc_nr) - { - return RT_NULL; - } - - rstc_arr = rt_calloc(1, sizeof(*rstc_arr) + sizeof(struct rt_reset_control *) * rstc_nr); - - if (!rstc_arr) - { - LOG_E("No memory to create %s[%d] reset control", - rt_ofw_node_full_name(np), index); - - return rt_err_ptr(-RT_ENOMEM); - } - - rstc_arr->count = rstc_nr - 1; - - for (int i = 0; i < rstc_arr->count; ++i) - { - rstc_arr->rstcs[i] = ofw_get_reset_control(np, i + 1, RT_NULL, RT_FALSE); - - if (rt_is_err(rstc_arr->rstcs[i])) - { - err = rt_ptr_err(rstc_arr->rstcs[i]); - - while (i --> 0) - { - rt_reset_control_put(rstc_arr->rstcs[i]); - } - - rt_free(rstc_arr); - - return rt_err_ptr(err); - } - } - - rstc = &rstc_arr->captain; - rstc->is_array = RT_TRUE; - } - else - { - rstc = rt_calloc(1, sizeof(*rstc)); - - if (!rstc) - { - LOG_E("No memory to create %s[%d] reset control", - rt_ofw_node_full_name(np), index); - - return rt_err_ptr(-RT_ENOMEM); - } - } - - if (!rt_ofw_parse_phandle_cells(np, "resets", "#reset-cells", index, &reset_args)) - { - void *rt_data; - struct rt_object *obj; - struct rt_ofw_node *reset_np = reset_args.data; - - if (!rt_ofw_data(reset_np)) - { - rt_platform_ofw_request(reset_np); - } - - rt_data = rt_ofw_data(reset_np); - - if (rt_data && (obj = rt_ofw_parse_object(reset_args.data, - RT_RESET_CONTROLLER_OBJ_NAME, "#reset-cells"))) - { - rstcer = rt_container_of(obj, struct rt_reset_controller, parent); - } - - rt_ofw_node_put(reset_np); - - if (!rstcer) - { - err = -RT_EINVAL; - goto _fail; - } - } - else - { - /* Not reset */ - goto _fail; - } - - if (!name && rt_ofw_prop_read_bool(np, "reset-names")) - { - rt_ofw_prop_read_string_index(np, "reset-names", index, &name); - } - - rstc->con_id = name; - rstc->rstcer = rstcer; - - if (rstcer->ops->ofw_parse) - { - err = rstcer->ops->ofw_parse(rstc, &reset_args); - - if (err) - { - LOG_E("Parse %s reset control error = %s", - rt_ofw_node_full_name(np), rt_strerror(err)); - - goto _fail; - } - } - - rstc->id = reset_args.args[0]; - - rt_list_init(&rstc->list); - - rt_spin_lock(&rstcer->spinlock); - - rt_list_insert_after(&rstcer->rstc_nodes, &rstc->list); - - rt_spin_unlock(&rstcer->spinlock); - - return rstc; - -_fail: - if (rstc && !rstc->is_array) - { - rt_free(rstc); - } - - return rt_err_ptr(err); -} - -struct rt_reset_control *rt_ofw_get_reset_control_array(struct rt_ofw_node *np) -{ - return ofw_get_reset_control(np, 0, RT_NULL, RT_TRUE); -} - -struct rt_reset_control *rt_ofw_get_reset_control_by_index(struct rt_ofw_node *np, int index) -{ - return ofw_get_reset_control(np, index, RT_NULL, RT_FALSE); -} - -struct rt_reset_control *rt_ofw_get_reset_control_by_name(struct rt_ofw_node *np, const char *name) -{ - if (np) - { - int index = rt_ofw_prop_index_of_string(np, "reset-names", name); - - if (index >= 0) - { - return ofw_get_reset_control(np, index, name, RT_FALSE); - } - } - - return RT_NULL; -} diff --git a/rt-thread/components/drivers/rtc/Kconfig b/rt-thread/components/drivers/rtc/Kconfig index a8b3366..e4310cb 100644 --- a/rt-thread/components/drivers/rtc/Kconfig +++ b/rt-thread/components/drivers/rtc/Kconfig @@ -7,20 +7,6 @@ config RT_USING_RTC bool "Using RTC alarm" default n - if RT_USING_ALARM - config RT_ALARM_STACK_SIZE - int "stack size for alarm thread" - default 2048 - - config RT_ALARM_TIMESLICE - int "timeslice for alarm thread" - default 5 - - config RT_ALARM_PRIORITY - int "priority for alarm thread" - default 10 - endif - config RT_USING_SOFT_RTC bool "Using software simulation RTC device" default n diff --git a/rt-thread/components/drivers/rtc/SConscript b/rt-thread/components/drivers/rtc/SConscript index f1e180f..fe0d5e9 100644 --- a/rt-thread/components/drivers/rtc/SConscript +++ b/rt-thread/components/drivers/rtc/SConscript @@ -7,11 +7,11 @@ CPPPATH = [cwd + '/../include'] group = [] if GetDepend(['RT_USING_RTC']): - src = src + ['dev_rtc.c'] + src = src + ['rtc.c'] if GetDepend(['RT_USING_ALARM']): - src = src + ['dev_alarm.c'] + src = src + ['alarm.c'] if GetDepend(['RT_USING_SOFT_RTC']): - src = src + ['dev_soft_rtc.c'] + src = src + ['soft_rtc.c'] group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_RTC'], CPPPATH = CPPPATH) diff --git a/rt-thread/components/drivers/rtc/dev_alarm.c b/rt-thread/components/drivers/rtc/dev_alarm.c deleted file mode 100644 index aabc415..0000000 --- a/rt-thread/components/drivers/rtc/dev_alarm.c +++ /dev/null @@ -1,812 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-10-27 heyuanjie87 first version. - * 2013-05-17 aozima initial alarm event & mutex in system init. - * 2020-10-15 zhangsz add alarm flags hour minute second. - * 2020-11-09 zhangsz fix alarm set when modify rtc time. - * 2024-09-29 milo make internal thread's attributes configurable. - */ - -#include -#include -#include - -#define RT_RTC_YEARS_MAX 137 -#ifdef RT_USING_SOFT_RTC -#define RT_ALARM_DELAY 0 -#else -#define RT_ALARM_DELAY 2 -#endif - -#if (defined(RT_USING_RTC) && defined(RT_USING_ALARM)) -#ifndef RT_ALARM_STACK_SIZE -#define RT_ALARM_STACK_SIZE 2048 -#endif -#ifndef RT_ALARM_TIMESLICE -#define RT_ALARM_TIMESLICE 5 -#endif -#ifndef RT_ALARM_PRIORITY -#define RT_ALARM_PRIORITY 10 -#endif -static struct rt_alarm_container _container; - -rt_inline rt_uint32_t alarm_mkdaysec(struct tm *time) -{ - rt_uint32_t sec; - - sec = time->tm_sec; - sec += time->tm_min * 60; - sec += time->tm_hour * 3600; - - return (sec); -} - -static rt_err_t alarm_set(struct rt_alarm *alarm) -{ - rt_device_t device; - struct rt_rtc_wkalarm wkalarm; - rt_err_t ret; - - device = rt_device_find("rtc"); - - if (device == RT_NULL) - { - return (RT_ERROR); - } - - if (alarm->flag & RT_ALARM_STATE_START) - wkalarm.enable = RT_TRUE; - else - wkalarm.enable = RT_FALSE; - - wkalarm.tm_sec = alarm->wktime.tm_sec; - wkalarm.tm_min = alarm->wktime.tm_min; - wkalarm.tm_hour = alarm->wktime.tm_hour; - wkalarm.tm_mday = alarm->wktime.tm_mday; - wkalarm.tm_mon = alarm->wktime.tm_mon; - wkalarm.tm_year = alarm->wktime.tm_year; - - ret = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_ALARM, &wkalarm); - if ((ret == RT_EOK) && wkalarm.enable) - { - ret = rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_ALARM, &wkalarm); - if (ret == RT_EOK) - { - /* - some RTC device like RX8025,it's alarms precision is 1 minute. - in this case,low level RTC driver should set wkalarm->tm_sec to 0. - */ - alarm->wktime.tm_sec = wkalarm.tm_sec; - alarm->wktime.tm_min = wkalarm.tm_min; - alarm->wktime.tm_hour = wkalarm.tm_hour; - alarm->wktime.tm_mday = wkalarm.tm_mday; - alarm->wktime.tm_mon = wkalarm.tm_mon; - alarm->wktime.tm_year = wkalarm.tm_year; - } - } - - return (ret); -} - -static void alarm_wakeup(struct rt_alarm *alarm, struct tm *now) -{ - rt_uint32_t sec_alarm, sec_now; - rt_bool_t wakeup = RT_FALSE; - time_t timestamp; - - sec_alarm = alarm_mkdaysec(&alarm->wktime); - sec_now = alarm_mkdaysec(now); - - if (alarm->flag & RT_ALARM_STATE_START) - { - switch (alarm->flag & 0xFF00) - { - case RT_ALARM_ONESHOT: - { - sec_alarm = timegm(&alarm->wktime); - sec_now = timegm(now); - if (((sec_now - sec_alarm) <= RT_ALARM_DELAY) && (sec_now >= sec_alarm)) - { - /* stop alarm */ - alarm->flag &= ~RT_ALARM_STATE_START; - alarm_set(alarm); - wakeup = RT_TRUE; - } - } - break; - case RT_ALARM_SECOND: - { - alarm->wktime.tm_hour = now->tm_hour; - alarm->wktime.tm_min = now->tm_min; - alarm->wktime.tm_sec = now->tm_sec + 1; - if (alarm->wktime.tm_sec > 59) - { - alarm->wktime.tm_sec = 0; - alarm->wktime.tm_min = alarm->wktime.tm_min + 1; - if (alarm->wktime.tm_min > 59) - { - alarm->wktime.tm_min = 0; - alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1; - if (alarm->wktime.tm_hour > 23) - { - alarm->wktime.tm_hour = 0; - } - } - } - wakeup = RT_TRUE; - } - break; - case RT_ALARM_MINUTE: - { - alarm->wktime.tm_hour = now->tm_hour; - if (alarm->wktime.tm_sec == now->tm_sec) - { - alarm->wktime.tm_min = now->tm_min + 1; - if (alarm->wktime.tm_min > 59) - { - alarm->wktime.tm_min = 0; - alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1; - if (alarm->wktime.tm_hour > 23) - { - alarm->wktime.tm_hour = 0; - } - } - wakeup = RT_TRUE; - } - } - break; - case RT_ALARM_HOUR: - { - if ((alarm->wktime.tm_min == now->tm_min) && - (alarm->wktime.tm_sec == now->tm_sec)) - { - alarm->wktime.tm_hour = now->tm_hour + 1; - if (alarm->wktime.tm_hour > 23) - { - alarm->wktime.tm_hour = 0; - } - wakeup = RT_TRUE; - } - } - break; - case RT_ALARM_DAILY: - { - if (((sec_now - sec_alarm) <= RT_ALARM_DELAY) && (sec_now >= sec_alarm)) - wakeup = RT_TRUE; - } - break; - case RT_ALARM_WEEKLY: - { - /* alarm at wday */ - if (alarm->wktime.tm_wday == now->tm_wday) - { - sec_alarm += alarm->wktime.tm_wday * 24 * 3600; - sec_now += now->tm_wday * 24 * 3600; - - if (sec_now == sec_alarm) - wakeup = RT_TRUE; - } - } - break; - case RT_ALARM_MONTHLY: - { - /* monthly someday generate alarm signals */ - if (alarm->wktime.tm_mday == now->tm_mday) - { - if ((sec_now - sec_alarm) <= RT_ALARM_DELAY) - wakeup = RT_TRUE; - } - } - break; - case RT_ALARM_YAERLY: - { - if ((alarm->wktime.tm_mday == now->tm_mday) && \ - (alarm->wktime.tm_mon == now->tm_mon)) - { - if ((sec_now - sec_alarm) <= RT_ALARM_DELAY) - wakeup = RT_TRUE; - } - } - break; - } - - if ((wakeup == RT_TRUE) && (alarm->callback != RT_NULL)) - { - timestamp = (time_t)0; - get_timestamp(×tamp); - alarm->callback(alarm, timestamp); - } - } -} - -static void alarm_update(rt_uint32_t event) -{ - struct rt_alarm *alm_prev = RT_NULL, *alm_next = RT_NULL; - struct rt_alarm *alarm; - rt_int32_t sec_now, sec_alarm, sec_tmp; - rt_int32_t sec_next = 24 * 3600, sec_prev = 0; - time_t timestamp = (time_t)0; - struct tm now; - rt_list_t *next; - - rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER); - if (!rt_list_isempty(&_container.head)) - { - /* get time of now */ - get_timestamp(×tamp); - gmtime_r(×tamp, &now); - - for (next = _container.head.next; next != &_container.head; next = next->next) - { - alarm = rt_list_entry(next, struct rt_alarm, list); - /* check the overtime alarm */ - alarm_wakeup(alarm, &now); - } - - /* get time of now */ - get_timestamp(×tamp); - gmtime_r(×tamp, &now); - sec_now = alarm_mkdaysec(&now); - - for (next = _container.head.next; next != &_container.head; next = next->next) - { - alarm = rt_list_entry(next, struct rt_alarm, list); - /* calculate seconds from 00:00:00 */ - sec_alarm = alarm_mkdaysec(&alarm->wktime); - if (alarm->flag & RT_ALARM_STATE_START) - { - sec_tmp = sec_alarm - sec_now; - if (sec_tmp > 0) - { - /* find alarm after now(now to 23:59:59) and the most recent */ - if (sec_tmp < sec_next) - { - sec_next = sec_tmp; - alm_next = alarm; - } - } - else - { - /* find alarm before now(00:00:00 to now) and furthest from now */ - if (sec_tmp < sec_prev) - { - sec_prev = sec_tmp; - alm_prev = alarm; - } - } - } - } - - /* enable the alarm after now first */ - if (sec_next < 24 * 3600) - { - if (alarm_set(alm_next) == RT_EOK) - _container.current = alm_next; - } - else if (sec_prev < 0) - { - /* enable the alarm before now */ - if (alarm_set(alm_prev) == RT_EOK) - _container.current = alm_prev; - } - else - { - if (_container.current != RT_NULL) - { - alarm_set(_container.current); - if (!(_container.current->flag & RT_ALARM_STATE_START)) - _container.current = RT_NULL; - } - } - } - rt_mutex_release(&_container.mutex); -} - -static int days_of_year_month(int tm_year, int tm_mon) -{ - int ret, year; - - year = tm_year + 1900; - if (tm_mon == 1) - { - ret = 28 + ((!(year % 4) && (year % 100)) || !(year % 400)); - } - else if (((tm_mon <= 6) && (tm_mon % 2 == 0)) || ((tm_mon > 6) && (tm_mon % 2 == 1))) - { - ret = 31; - } - else - { - ret = 30; - } - - return (ret); -} - -static rt_bool_t is_valid_date(struct tm *date) -{ - if ((date->tm_year < 0) || (date->tm_year > RT_RTC_YEARS_MAX)) - { - return (RT_FALSE); - } - - if ((date->tm_mon < 0) || (date->tm_mon > 11)) - { - return (RT_FALSE); - } - - if ((date->tm_mday < 1) || \ - (date->tm_mday > days_of_year_month(date->tm_year, date->tm_mon))) - { - return (RT_FALSE); - } - - return (RT_TRUE); -} - -static rt_err_t alarm_setup(rt_alarm_t alarm, struct tm *wktime) -{ - rt_err_t ret = -RT_ERROR; - time_t timestamp = (time_t)0; - struct tm *setup, now; - - setup = &alarm->wktime; - *setup = *wktime; - /* get time of now */ - get_timestamp(×tamp); - gmtime_r(×tamp, &now); - - /* if these are a "don't care" value,we set them to now*/ - if ((setup->tm_sec > 59) || (setup->tm_sec < 0)) - setup->tm_sec = now.tm_sec; - if ((setup->tm_min > 59) || (setup->tm_min < 0)) - setup->tm_min = now.tm_min; - if ((setup->tm_hour > 23) || (setup->tm_hour < 0)) - setup->tm_hour = now.tm_hour; - - switch (alarm->flag & 0xFF00) - { - case RT_ALARM_SECOND: - { - alarm->wktime.tm_hour = now.tm_hour; - alarm->wktime.tm_min = now.tm_min; - alarm->wktime.tm_sec = now.tm_sec + 1; - if (alarm->wktime.tm_sec > 59) - { - alarm->wktime.tm_sec = 0; - alarm->wktime.tm_min = alarm->wktime.tm_min + 1; - if (alarm->wktime.tm_min > 59) - { - alarm->wktime.tm_min = 0; - alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1; - if (alarm->wktime.tm_hour > 23) - { - alarm->wktime.tm_hour = 0; - } - } - } - } - break; - case RT_ALARM_MINUTE: - { - alarm->wktime.tm_hour = now.tm_hour; - alarm->wktime.tm_min = now.tm_min + 1; - if (alarm->wktime.tm_min > 59) - { - alarm->wktime.tm_min = 0; - alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1; - if (alarm->wktime.tm_hour > 23) - { - alarm->wktime.tm_hour = 0; - } - } - } - break; - case RT_ALARM_HOUR: - { - alarm->wktime.tm_hour = now.tm_hour + 1; - if (alarm->wktime.tm_hour > 23) - { - alarm->wktime.tm_hour = 0; - } - } - break; - case RT_ALARM_DAILY: - { - /* do nothing but needed */ - } - break; - case RT_ALARM_ONESHOT: - { - /* if these are "don't care" value we set them to now */ - if (setup->tm_year == RT_ALARM_TM_NOW) - setup->tm_year = now.tm_year; - if (setup->tm_mon == RT_ALARM_TM_NOW) - setup->tm_mon = now.tm_mon; - if (setup->tm_mday == RT_ALARM_TM_NOW) - setup->tm_mday = now.tm_mday; - /* make sure the setup is valid */ - if (!is_valid_date(setup)) - goto _exit; - } - break; - case RT_ALARM_WEEKLY: - { - /* if tm_wday is a "don't care" value we set it to now */ - if ((setup->tm_wday < 0) || (setup->tm_wday > 6)) - setup->tm_wday = now.tm_wday; - } - break; - case RT_ALARM_MONTHLY: - { - /* if tm_mday is a "don't care" value we set it to now */ - if ((setup->tm_mday < 1) || (setup->tm_mday > 31)) - setup->tm_mday = now.tm_mday; - } - break; - case RT_ALARM_YAERLY: - { - /* if tm_mon is a "don't care" value we set it to now */ - if ((setup->tm_mon < 0) || (setup->tm_mon > 11)) - setup->tm_mon = now.tm_mon; - - if (setup->tm_mon == 1) - { - /* tm_mon is February */ - - /* tm_mday should be 1~29.otherwise,it's a "don't care" value */ - if ((setup->tm_mday < 1) || (setup->tm_mday > 29)) - setup->tm_mday = now.tm_mday; - } - else if (((setup->tm_mon <= 6) && (setup->tm_mon % 2 == 0)) || \ - ((setup->tm_mon > 6) && (setup->tm_mon % 2 == 1))) - { - /* Jan,Mar,May,Jul,Aug,Oct,Dec */ - - /* tm_mday should be 1~31.otherwise,it's a "don't care" value */ - if ((setup->tm_mday < 1) || (setup->tm_mday > 31)) - setup->tm_mday = now.tm_mday; - } - else - { - /* tm_mday should be 1~30.otherwise,it's a "don't care" value */ - if ((setup->tm_mday < 1) || (setup->tm_mday > 30)) - setup->tm_mday = now.tm_mday; - } - } - break; - default: - { - goto _exit; - } - } - - if ((setup->tm_hour == 23) && (setup->tm_min == 59) && (setup->tm_sec == 59)) - { - /* - for insurance purposes, we will generate an alarm - signal two seconds ahead of. - */ - setup->tm_sec = 60 - RT_ALARM_DELAY; - } - /* set initialized state */ - alarm->flag |= RT_ALARM_STATE_INITED; - ret = RT_EOK; - -_exit: - - return (ret); -} - -/** \brief send a rtc alarm event - * - * \param dev pointer to RTC device(currently unused,you can ignore it) - * \param event RTC event(currently unused) - * \return none - */ -void rt_alarm_update(rt_device_t dev, rt_uint32_t event) -{ - rt_event_send(&_container.event, 1); -} - -/** \brief modify the alarm setup - * - * \param alarm pointer to alarm - * \param cmd control command - * \param arg argument - */ -rt_err_t rt_alarm_control(rt_alarm_t alarm, int cmd, void *arg) -{ - rt_err_t ret = -RT_ERROR; - - RT_ASSERT(alarm != RT_NULL); - - rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER); - switch (cmd) - { - case RT_ALARM_CTRL_MODIFY: - { - struct rt_alarm_setup *setup; - - RT_ASSERT(arg != RT_NULL); - setup = arg; - rt_alarm_stop(alarm); - alarm->flag = setup->flag & 0xFF00; - alarm->wktime = setup->wktime; - ret = alarm_setup(alarm, &alarm->wktime); - } - break; - } - - rt_mutex_release(&_container.mutex); - - return (ret); -} - -/** \brief start an alarm - * - * \param alarm pointer to alarm - * \return RT_EOK - */ -rt_err_t rt_alarm_start(rt_alarm_t alarm) -{ - rt_int32_t sec_now, sec_old, sec_new; - rt_err_t ret = RT_EOK; - time_t timestamp = (time_t)0; - struct tm now; - - if (alarm == RT_NULL) - return (RT_ERROR); - rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER); - - if (!(alarm->flag & RT_ALARM_STATE_START)) - { - if (alarm_setup(alarm, &alarm->wktime) != RT_EOK) - { - ret = -RT_ERROR; - goto _exit; - } - - /* get time of now */ - get_timestamp(×tamp); - gmtime_r(×tamp, &now); - - alarm->flag |= RT_ALARM_STATE_START; - - /* set alarm */ - if (_container.current == RT_NULL) - { - ret = alarm_set(alarm); - } - else - { - sec_now = alarm_mkdaysec(&now); - sec_old = alarm_mkdaysec(&_container.current->wktime); - sec_new = alarm_mkdaysec(&alarm->wktime); - - if ((sec_new < sec_old) && (sec_new > sec_now)) - { - ret = alarm_set(alarm); - } - else if ((sec_new > sec_now) && (sec_old < sec_now)) - { - ret = alarm_set(alarm); - } - else if ((sec_new < sec_old) && (sec_old < sec_now)) - { - ret = alarm_set(alarm); - } - else - { - ret = RT_EOK; - goto _exit; - } - } - - if (ret == RT_EOK) - { - _container.current = alarm; - } - } - -_exit: - rt_mutex_release(&_container.mutex); - - return (ret); -} - -/** \brief stop an alarm - * - * \param alarm pointer to alarm - * \return RT_EOK - */ -rt_err_t rt_alarm_stop(rt_alarm_t alarm) -{ - rt_err_t ret = RT_EOK; - - if (alarm == RT_NULL) - return (RT_ERROR); - rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER); - if (!(alarm->flag & RT_ALARM_STATE_START)) - goto _exit; - /* stop alarm */ - alarm->flag &= ~RT_ALARM_STATE_START; - - if (_container.current == alarm) - { - ret = alarm_set(alarm); - _container.current = RT_NULL; - } - - if (ret == RT_EOK) - alarm_update(0); - -_exit: - rt_mutex_release(&_container.mutex); - - return (ret); -} - -/** \brief delete an alarm - * - * \param alarm pointer to alarm - * \return RT_EOK - */ -rt_err_t rt_alarm_delete(rt_alarm_t alarm) -{ - rt_err_t ret = RT_EOK; - - if (alarm == RT_NULL) - return -RT_ERROR; - rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER); - /* stop the alarm */ - alarm->flag &= ~RT_ALARM_STATE_START; - if (_container.current == alarm) - { - ret = alarm_set(alarm); - _container.current = RT_NULL; - /* set new alarm if necessary */ - alarm_update(0); - } - rt_list_remove(&alarm->list); - rt_free(alarm); - - rt_mutex_release(&_container.mutex); - - return (ret); -} - -/** \brief create an alarm - * - * \param flag set alarm mode e.g: RT_ALARM_DAILY - * \param setup pointer to setup infomation - */ -rt_alarm_t rt_alarm_create(rt_alarm_callback_t callback, struct rt_alarm_setup *setup) -{ - struct rt_alarm *alarm; - - if (setup == RT_NULL) - return (RT_NULL); - - alarm = rt_malloc(sizeof(struct rt_alarm)); - if (alarm == RT_NULL) - return (RT_NULL); - - rt_list_init(&alarm->list); - - alarm->wktime = setup->wktime; - alarm->flag = setup->flag & 0xFF00; - alarm->callback = callback; - rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER); - rt_list_insert_after(&_container.head, &alarm->list); - rt_mutex_release(&_container.mutex); - - return (alarm); -} - -/** \brief rtc alarm service thread entry - * - */ -static void rt_alarmsvc_thread_init(void *param) -{ - rt_uint32_t recv; - - _container.current = RT_NULL; - - while (1) - { - if (rt_event_recv(&_container.event, 0xFFFF, - RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, - RT_WAITING_FOREVER, &recv) == RT_EOK) - { - alarm_update(recv); - } - } -} - -struct _alarm_flag -{ - const char* name; - rt_uint32_t flag; -}; - -static const struct _alarm_flag _alarm_flag_tbl[] = -{ - {"N", 0xffff}, /* none */ - {"O", RT_ALARM_ONESHOT}, /* only alarm once */ - {"D", RT_ALARM_DAILY}, /* alarm everyday */ - {"W", RT_ALARM_WEEKLY}, /* alarm weekly at Monday or Friday etc. */ - {"Mo", RT_ALARM_MONTHLY}, /* alarm monthly at someday */ - {"Y", RT_ALARM_YAERLY}, /* alarm yearly at a certain date */ - {"H", RT_ALARM_HOUR}, /* alarm each hour at a certain min:second */ - {"M", RT_ALARM_MINUTE}, /* alarm each minute at a certain second */ - {"S", RT_ALARM_SECOND}, /* alarm each second */ -}; - -static rt_uint8_t _alarm_flag_tbl_size = sizeof(_alarm_flag_tbl) / sizeof(_alarm_flag_tbl[0]); - -static rt_uint8_t get_alarm_flag_index(rt_uint32_t alarm_flag) -{ - for (rt_uint8_t index = 0; index < _alarm_flag_tbl_size; index++) - { - alarm_flag &= 0xff00; - if (alarm_flag == _alarm_flag_tbl[index].flag) - { - return index; - } - } - - return 0; -} - -void rt_alarm_dump(void) -{ - rt_list_t *next; - rt_alarm_t alarm; - - rt_kprintf("| hh:mm:ss | week | flag | en |\n"); - rt_kprintf("+----------+------+------+----+\n"); - for (next = _container.head.next; next != &_container.head; next = next->next) - { - alarm = rt_list_entry(next, struct rt_alarm, list); - rt_uint8_t flag_index = get_alarm_flag_index(alarm->flag); - rt_kprintf("| %02d:%02d:%02d | %2d | %2s | %2d |\n", - alarm->wktime.tm_hour, alarm->wktime.tm_min, alarm->wktime.tm_sec, - alarm->wktime.tm_wday, _alarm_flag_tbl[flag_index].name, alarm->flag & RT_ALARM_STATE_START); - } - rt_kprintf("+----------+------+------+----+\n"); -} - -MSH_CMD_EXPORT_ALIAS(rt_alarm_dump, list_alarm, list alarm info); - -/** \brief initialize alarm service system - * - * \param none - * \return none - */ -int rt_alarm_system_init(void) -{ - rt_thread_t tid; - - rt_list_init(&_container.head); - rt_event_init(&_container.event, "alarmsvc", RT_IPC_FLAG_FIFO); - rt_mutex_init(&_container.mutex, "alarmsvc", RT_IPC_FLAG_PRIO); - - tid = rt_thread_create("alarmsvc", - rt_alarmsvc_thread_init, RT_NULL, - RT_ALARM_STACK_SIZE, - RT_ALARM_PRIORITY, - RT_ALARM_TIMESLICE); - if (tid != RT_NULL) - rt_thread_startup(tid); - - return 0; -} - -INIT_PREV_EXPORT(rt_alarm_system_init); -#endif diff --git a/rt-thread/components/drivers/rtc/dev_rtc.c b/rt-thread/components/drivers/rtc/dev_rtc.c deleted file mode 100644 index f789036..0000000 --- a/rt-thread/components/drivers/rtc/dev_rtc.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-01-29 aozima first version. - * 2012-04-12 aozima optimization: find rtc device only first. - * 2012-04-16 aozima add scheduler lock for set_date and set_time. - * 2018-02-16 armink add auto sync time by NTP - * 2021-05-09 Meco Man remove NTP - * 2021-06-11 iysheng implement RTC framework V2.0 - * 2021-07-30 Meco Man move rtc_core.c to rtc.c - */ - -#include -#include -#include -#include - -#ifdef RT_USING_RTC - -static rt_device_t _rtc_device; -/* - * This function initializes rtc_core - */ -static rt_err_t rt_rtc_init(struct rt_device *dev) -{ - rt_rtc_dev_t *rtc_core; - - RT_ASSERT(dev != RT_NULL); - rtc_core = (rt_rtc_dev_t *)dev; - if (rtc_core->ops->init) - { - return (rtc_core->ops->init()); - } - - return -RT_ENOSYS; -} - -static rt_err_t rt_rtc_open(struct rt_device *dev, rt_uint16_t oflag) -{ - return RT_EOK; -} - -static rt_err_t rt_rtc_close(struct rt_device *dev) -{ - /* Add close member function in rt_rtc_ops when need, - * then call that function here. - * */ - return RT_EOK; -} - -static rt_err_t rt_rtc_control(struct rt_device *dev, int cmd, void *args) -{ -#define TRY_DO_RTC_FUNC(rt_rtc_dev, func_name, args) \ - rt_rtc_dev->ops->func_name ? rt_rtc_dev->ops->func_name(args) : -RT_EINVAL; - - rt_rtc_dev_t *rtc_device; - rt_err_t ret = -RT_EINVAL; - - RT_ASSERT(dev != RT_NULL); - rtc_device = (rt_rtc_dev_t *)dev; - - switch (cmd) - { - case RT_DEVICE_CTRL_RTC_GET_TIME: - ret = TRY_DO_RTC_FUNC(rtc_device, get_secs, args); - break; - case RT_DEVICE_CTRL_RTC_SET_TIME: - ret = TRY_DO_RTC_FUNC(rtc_device, set_secs, args); - break; - case RT_DEVICE_CTRL_RTC_GET_TIMEVAL: - ret = TRY_DO_RTC_FUNC(rtc_device, get_timeval, args); - break; - case RT_DEVICE_CTRL_RTC_SET_TIMEVAL: - ret = TRY_DO_RTC_FUNC(rtc_device, set_timeval, args); - break; - case RT_DEVICE_CTRL_RTC_GET_ALARM: - ret = TRY_DO_RTC_FUNC(rtc_device, get_alarm, args); - break; - case RT_DEVICE_CTRL_RTC_SET_ALARM: - ret = TRY_DO_RTC_FUNC(rtc_device, set_alarm, args); - break; - default: - break; - } - - return ret; - -#undef TRY_DO_RTC_FUNC -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops rtc_core_ops = -{ - rt_rtc_init, - rt_rtc_open, - rt_rtc_close, - RT_NULL, - RT_NULL, - rt_rtc_control, -}; -#endif /* RT_USING_DEVICE_OPS */ - -rt_err_t rt_hw_rtc_register(rt_rtc_dev_t *rtc, - const char *name, - rt_uint32_t flag, - void *data) -{ - struct rt_device *device; - RT_ASSERT(rtc != RT_NULL); - - device = &(rtc->parent); - - device->type = RT_Device_Class_RTC; - device->rx_indicate = RT_NULL; - device->tx_complete = RT_NULL; - -#ifdef RT_USING_DEVICE_OPS - device->ops = &rtc_core_ops; -#else - device->init = rt_rtc_init; - device->open = rt_rtc_open; - device->close = rt_rtc_close; - device->read = RT_NULL; - device->write = RT_NULL; - device->control = rt_rtc_control; -#endif /* RT_USING_DEVICE_OPS */ - device->user_data = data; - - /* register a character device */ - return rt_device_register(device, name, flag); -} - -/** - * Set system date(time not modify, local timezone). - * - * @param rt_uint32_t year e.g: 2012. - * @param rt_uint32_t month e.g: 12 (1~12). - * @param rt_uint32_t day e.g: 31. - * - * @return rt_err_t if set success, return RT_EOK. - */ -rt_err_t set_date(rt_uint32_t year, rt_uint32_t month, rt_uint32_t day) -{ - time_t now, old_timestamp = 0; - struct tm tm_new = {0}; - rt_err_t ret = -RT_ERROR; - - if (_rtc_device == RT_NULL) - { - _rtc_device = rt_device_find("rtc"); - if (_rtc_device == RT_NULL) - { - return -RT_ERROR; - } - } - - /* get current time */ - ret = rt_device_control(_rtc_device, RT_DEVICE_CTRL_RTC_GET_TIME, &old_timestamp); - if (ret != RT_EOK) - { - return ret; - } - - /* converts calendar time into local time. */ - localtime_r(&old_timestamp, &tm_new); - - /* update date. */ - tm_new.tm_year = year - 1900; - tm_new.tm_mon = month - 1; /* tm_mon: 0~11 */ - tm_new.tm_mday = day; - - /* converts the local time into the calendar time. */ - now = mktime(&tm_new); - - /* update to RTC device. */ - ret = rt_device_control(_rtc_device, RT_DEVICE_CTRL_RTC_SET_TIME, &now); - return ret; -} - -/** - * Set system time(date not modify, local timezone). - * - * @param rt_uint32_t hour e.g: 0~23. - * @param rt_uint32_t minute e.g: 0~59. - * @param rt_uint32_t second e.g: 0~59. - * - * @return rt_err_t if set success, return RT_EOK. - */ -rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second) -{ - time_t now, old_timestamp = 0; - struct tm tm_new = {0}; - rt_err_t ret = -RT_ERROR; - - if (_rtc_device == RT_NULL) - { - _rtc_device = rt_device_find("rtc"); - if (_rtc_device == RT_NULL) - { - return -RT_ERROR; - } - } - - /* get current time */ - ret = rt_device_control(_rtc_device, RT_DEVICE_CTRL_RTC_GET_TIME, &old_timestamp); - if (ret != RT_EOK) - { - return ret; - } - - /* converts calendar time into local time. */ - localtime_r(&old_timestamp, &tm_new); - - /* update time. */ - tm_new.tm_hour = hour; - tm_new.tm_min = minute; - tm_new.tm_sec = second; - - /* converts the local time into the calendar time. */ - now = mktime(&tm_new); - - /* update to RTC device. */ - ret = rt_device_control(_rtc_device, RT_DEVICE_CTRL_RTC_SET_TIME, &now); - return ret; -} - -/** - * Set timestamp(UTC). - * - * @param time_t timestamp - * - * @return rt_err_t if set success, return RT_EOK. - */ -rt_err_t set_timestamp(time_t timestamp) -{ - if (_rtc_device == RT_NULL) - { - _rtc_device = rt_device_find("rtc"); - if (_rtc_device == RT_NULL) - { - return -RT_ERROR; - } - } - - /* update to RTC device. */ - return rt_device_control(_rtc_device, RT_DEVICE_CTRL_RTC_SET_TIME, ×tamp); -} - -/** - * Get timestamp(UTC). - * - * @param time_t* timestamp - * - * @return rt_err_t if set success, return RT_EOK. - */ -rt_err_t get_timestamp(time_t *timestamp) -{ - if (_rtc_device == RT_NULL) - { - _rtc_device = rt_device_find("rtc"); - if (_rtc_device == RT_NULL) - { - return -RT_ERROR; - } - } - - /* Get timestamp from RTC device. */ - return rt_device_control(_rtc_device, RT_DEVICE_CTRL_RTC_GET_TIME, timestamp); -} - -#ifdef RT_USING_FINSH -#include -/** - * get date and time or set (local timezone) [year month day hour min sec] - */ -static void date(int argc, char **argv) -{ - time_t now = (time_t)0; - - if (argc == 1) - { - struct timeval tv = { 0 }; - int32_t tz_offset_sec = 0; - uint32_t abs_tz_offset_sec = 0U; - -#if defined(RT_LIBC_USING_LIGHT_TZ_DST) - tz_offset_sec = rt_tz_get(); -#endif /* RT_LIBC_USING_LIGHT_TZ_DST */ - - gettimeofday(&tv, RT_NULL); - now = tv.tv_sec; - - abs_tz_offset_sec = tz_offset_sec > 0 ? tz_offset_sec : -tz_offset_sec; - /* output current time */ - rt_kprintf("local time: %.*s", 25U, ctime(&now)); - rt_kprintf("timestamps: %ld\n", (long)tv.tv_sec); - rt_kprintf("timezone: UTC%c%02d:%02d:%02d\n", - tz_offset_sec > 0 ? '+' : '-', abs_tz_offset_sec / 3600U, abs_tz_offset_sec % 3600U / 60U, abs_tz_offset_sec % 3600U % 60U); - } - else if (argc >= 7) - { - /* set time and date */ - struct tm tm_new = {0}; - time_t old = (time_t)0; - rt_err_t err; - - tm_new.tm_year = atoi(argv[1]) - 1900; - tm_new.tm_mon = atoi(argv[2]) - 1; /* .tm_min's range is [0-11] */ - tm_new.tm_mday = atoi(argv[3]); - tm_new.tm_hour = atoi(argv[4]); - tm_new.tm_min = atoi(argv[5]); - tm_new.tm_sec = atoi(argv[6]); - if (tm_new.tm_year <= 0) - { - rt_kprintf("year is out of range [1900-]\n"); - return; - } - if (tm_new.tm_mon > 11) /* .tm_min's range is [0-11] */ - { - rt_kprintf("month is out of range [1-12]\n"); - return; - } - if (tm_new.tm_mday == 0 || tm_new.tm_mday > 31) - { - rt_kprintf("day is out of range [1-31]\n"); - return; - } - if (tm_new.tm_hour > 23) - { - rt_kprintf("hour is out of range [0-23]\n"); - return; - } - if (tm_new.tm_min > 59) - { - rt_kprintf("minute is out of range [0-59]\n"); - return; - } - if (tm_new.tm_sec > 60) - { - rt_kprintf("second is out of range [0-60]\n"); - return; - } - /* save old timestamp */ - err = get_timestamp(&old); - if (err != RT_EOK) - { - rt_kprintf("Get current timestamp failed. %d\n", err); - return; - } - /* converts the local time into the calendar time. */ - now = mktime(&tm_new); - err = set_timestamp(now); - if (err != RT_EOK) - { - rt_kprintf("set date failed. %d\n", err); - return; - } - get_timestamp(&now); /* get new timestamp */ - rt_kprintf("old: %.*s", 25, ctime(&old)); - rt_kprintf("now: %.*s", 25, ctime(&now)); - } - else - { - rt_kprintf("please input: date [year month day hour min sec] or date\n"); - rt_kprintf("e.g: date 2018 01 01 23 59 59 or date\n"); - } -} -MSH_CMD_EXPORT(date, get date and time or set (local timezone) [year month day hour min sec]) -#endif /* RT_USING_FINSH */ - -#endif /* RT_USING_RTC */ diff --git a/rt-thread/components/drivers/rtc/dev_soft_rtc.c b/rt-thread/components/drivers/rtc/dev_soft_rtc.c deleted file mode 100644 index cd5a37e..0000000 --- a/rt-thread/components/drivers/rtc/dev_soft_rtc.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-01-30 armink the first version - */ - -#include -#include -#include -#include - -#ifdef RT_USING_KTIME -#include -#endif - -#ifdef RT_USING_SOFT_RTC - -/* 2018-01-30 14:44:50 = RTC_TIME_INIT(2018, 1, 30, 14, 44, 50) */ -#define RTC_TIME_INIT(year, month, day, hour, minute, second) \ - {.tm_year = year - 1900, .tm_mon = month - 1, .tm_mday = day, .tm_hour = hour, .tm_min = minute, .tm_sec = second} - -#ifndef SOFT_RTC_TIME_DEFAULT -#define SOFT_RTC_TIME_DEFAULT RTC_TIME_INIT(2018, 1, 1, 0, 0 ,0) -#endif - -#ifndef RTC_AUTO_SYNC_FIRST_DELAY -#define RTC_AUTO_SYNC_FIRST_DELAY 25 -#endif -#ifndef RTC_AUTO_SYNC_PERIOD -#define RTC_AUTO_SYNC_PERIOD 3600 -#endif - -static struct rt_work rtc_sync_work; - -static struct rt_device soft_rtc_dev; -static rt_tick_t init_tick; -static time_t init_time; -static struct timeval init_tv = {0}; - -#ifdef RT_USING_KTIME -static struct timespec init_ts = {0}; -#endif - -#ifdef RT_USING_ALARM - -static struct rt_rtc_wkalarm wkalarm; -static struct rt_timer alarm_time; - -static void alarm_timeout(void *param) -{ - rt_alarm_update(param, 1); -} - -static void soft_rtc_alarm_update(struct rt_rtc_wkalarm *palarm) -{ - rt_tick_t next_tick; - - if (palarm->enable) - { - next_tick = RT_TICK_PER_SECOND; - rt_timer_control(&alarm_time, RT_TIMER_CTRL_SET_TIME, &next_tick); - rt_timer_start(&alarm_time); - } - else - { - rt_timer_stop(&alarm_time); - } -} - -#endif - -static void set_rtc_time(time_t t) -{ - init_time = t - (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND; -#ifdef RT_USING_ALARM - soft_rtc_alarm_update(&wkalarm); -#endif -} - -static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args) -{ - time_t *t; - struct tm time_temp; - - RT_ASSERT(dev != RT_NULL); - rt_memset(&time_temp, 0, sizeof(struct tm)); - - switch (cmd) - { - case RT_DEVICE_CTRL_RTC_GET_TIME: - { - t = (time_t *) args; - *t = init_time + (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND; - break; - } - case RT_DEVICE_CTRL_RTC_SET_TIME: - { - t = (time_t *) args; - set_rtc_time(*t); - break; - } -#ifdef RT_USING_ALARM - case RT_DEVICE_CTRL_RTC_GET_ALARM: - *((struct rt_rtc_wkalarm *)args) = wkalarm; - break; - case RT_DEVICE_CTRL_RTC_SET_ALARM: - wkalarm = *((struct rt_rtc_wkalarm *)args); - soft_rtc_alarm_update(&wkalarm); - break; -#endif -#ifdef RT_USING_KTIME - case RT_DEVICE_CTRL_RTC_GET_TIMEVAL: - { - struct timeval _tv; - struct timeval *tv = (struct timeval *)args; - rt_ktime_boottime_get_us(&_tv); - tv->tv_sec = init_time + _tv.tv_sec; - tv->tv_usec = init_tv.tv_usec + _tv.tv_usec; - break; - } - case RT_DEVICE_CTRL_RTC_SET_TIMEVAL: - { - struct timeval _tv; - struct timeval *tv = (struct timeval *)args; - rt_ktime_boottime_get_us(&_tv); - set_rtc_time(tv->tv_sec); - init_tv.tv_usec = tv->tv_usec - _tv.tv_usec; - break; - } - case RT_DEVICE_CTRL_RTC_GET_TIMESPEC: - { - struct timespec _ts; - struct timespec *ts = (struct timespec *)args; - rt_ktime_boottime_get_ns(&_ts); - ts->tv_sec = init_time + _ts.tv_sec; - ts->tv_nsec = init_ts.tv_nsec + _ts.tv_nsec; - break; - } - case RT_DEVICE_CTRL_RTC_SET_TIMESPEC: - { - struct timespec _ts; - struct timespec *ts = (struct timespec *)args; - rt_ktime_boottime_get_ns(&_ts); - set_rtc_time(ts->tv_sec); - init_ts.tv_nsec = ts->tv_nsec - _ts.tv_nsec; - break; - } - case RT_DEVICE_CTRL_RTC_GET_TIMERES: - { - struct timespec *ts = (struct timespec *)args; - ts->tv_sec = 0; - ts->tv_nsec = (rt_ktime_cputimer_getres() / RT_KTIME_RESMUL); - break; - } -#else - case RT_DEVICE_CTRL_RTC_GET_TIMEVAL: - { - struct timeval *tv = (struct timeval *)args; - rt_tick_t tick = rt_tick_get() - init_tick; - tv->tv_sec = init_time + tick / RT_TICK_PER_SECOND; - tv->tv_usec = init_tv.tv_usec + ((tick % RT_TICK_PER_SECOND) * (1000000 / RT_TICK_PER_SECOND)); - break; - } - case RT_DEVICE_CTRL_RTC_SET_TIMEVAL: - { - struct timeval *tv = (struct timeval *)args; - rt_tick_t tick = rt_tick_get() - init_tick; - set_rtc_time(tv->tv_sec); - init_tv.tv_usec = tv->tv_usec - ((tick % RT_TICK_PER_SECOND) * (1000000 / RT_TICK_PER_SECOND)); - break; - } - case RT_DEVICE_CTRL_RTC_GET_TIMERES: - { - struct timespec *ts = (struct timespec *)args; - ts->tv_sec = 0; - ts->tv_nsec = (1000UL * 1000 * 1000) / RT_TICK_PER_SECOND; - break; - } -#endif /* RT_USING_KTIME */ - default: - return -RT_EINVAL; - } - - return RT_EOK; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops soft_rtc_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - RT_NULL, - RT_NULL, - soft_rtc_control -}; -#endif - -static int rt_soft_rtc_init(void) -{ - static rt_bool_t init_ok = RT_FALSE; - struct tm time_new = SOFT_RTC_TIME_DEFAULT; - - if (init_ok) - { - return 0; - } - /* make sure only one 'rtc' device */ -#if defined(RT_USING_SOFT_RTC) && defined(BSP_USING_ONCHIP_RTC) -#warning "Please note: Currently only one RTC device is allowed in the system, and the name is "rtc"." -#endif - RT_ASSERT(!rt_device_find("rtc")); - -#ifdef RT_USING_ALARM - rt_timer_init(&alarm_time, - "alarm", - alarm_timeout, - &soft_rtc_dev, - 0, - RT_TIMER_FLAG_SOFT_TIMER|RT_TIMER_FLAG_ONE_SHOT); -#endif - - init_tick = rt_tick_get(); - init_time = timegm(&time_new); - - soft_rtc_dev.type = RT_Device_Class_RTC; - - /* register rtc device */ -#ifdef RT_USING_DEVICE_OPS - soft_rtc_dev.ops = &soft_rtc_ops; -#else - soft_rtc_dev.init = RT_NULL; - soft_rtc_dev.open = RT_NULL; - soft_rtc_dev.close = RT_NULL; - soft_rtc_dev.read = RT_NULL; - soft_rtc_dev.write = RT_NULL; - soft_rtc_dev.control = soft_rtc_control; -#endif - - /* no private */ - soft_rtc_dev.user_data = RT_NULL; - - rt_device_register(&soft_rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR); - - init_ok = RT_TRUE; - - return 0; -} -INIT_DEVICE_EXPORT(rt_soft_rtc_init); - -#ifdef RT_USING_SYSTEM_WORKQUEUE - -rt_err_t rt_soft_rtc_sync(void) -{ - time_t time = 0; - - rt_device_control(&soft_rtc_dev, RT_DEVICE_CTRL_RTC_GET_TIME, &time); - set_rtc_time(time); - return RT_EOK; -} - -static void rtc_sync_work_func(struct rt_work *work, void *work_data) -{ - rt_soft_rtc_sync(); - rt_work_submit(work, rt_tick_from_millisecond(RTC_AUTO_SYNC_PERIOD * 1000)); -} - -rt_err_t rt_soft_rtc_set_source(const char *name) -{ - RT_ASSERT(name != RT_NULL); - RT_ASSERT(rt_device_find(name)); /* make sure source is exist*/ - - rt_work_init(&rtc_sync_work, rtc_sync_work_func, RT_NULL); - rt_work_submit(&rtc_sync_work, rt_tick_from_millisecond(RTC_AUTO_SYNC_FIRST_DELAY * 1000)); - - return RT_EOK; -} - -#ifdef FINSH_USING_MSH -#include -static void cmd_rtc_sync(int argc, char **argv) -{ - struct timeval tv = {0}; - struct timezone tz = {0}; - time_t now = (time_t)0; - - rt_soft_rtc_sync(); - - gettimeofday(&tv, &tz); - now = tv.tv_sec; - /* output current time */ - rt_kprintf("local time: %.*s", 25, ctime(&now)); - rt_kprintf("timestamps: %ld\n", (long)tv.tv_sec); -} -MSH_CMD_EXPORT_ALIAS(cmd_rtc_sync, rtc_sync, Update time by soft rtc); -#endif - -#endif /* RT_USING_SYSTEM_WORKQUEUE */ - -#endif /* RT_USING_SOFT_RTC */ diff --git a/rt-thread/components/drivers/scsi/Kconfig b/rt-thread/components/drivers/scsi/Kconfig deleted file mode 100644 index ba22188..0000000 --- a/rt-thread/components/drivers/scsi/Kconfig +++ /dev/null @@ -1,20 +0,0 @@ -menuconfig RT_USING_SCSI - bool "Using Small Computer System Interface (SCSI)" - depends on RT_USING_DM - default n - -config RT_SCSI_SD - bool "SD device on SCSI" - depends on RT_USING_SCSI - depends on RT_USING_BLK - default y - -config RT_SCSI_CDROM - bool "CD-ROM device on SCSI" - depends on RT_USING_SCSI - depends on RT_USING_BLK - default y - -if RT_USING_SCSI - osource "$(SOC_DM_SCSI_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/scsi/SConscript b/rt-thread/components/drivers/scsi/SConscript deleted file mode 100644 index 328d929..0000000 --- a/rt-thread/components/drivers/scsi/SConscript +++ /dev/null @@ -1,21 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_USING_SCSI']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../include'] - -src = ['scsi.c'] - -if GetDepend(['RT_SCSI_SD']): - src += ['scsi_sd.c'] - -if GetDepend(['RT_SCSI_CDROM']): - src += ['scsi_cdrom.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/scsi/scsi.c b/rt-thread/components/drivers/scsi/scsi.c deleted file mode 100644 index f5ac977..0000000 --- a/rt-thread/components/drivers/scsi/scsi.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#include -#include -#include - -#define DBG_TAG "rtdm.scsi" -#define DBG_LVL DBG_INFO -#include - -/* - * Since SCSI is used for storage (almost), - * we do not want to implement SCSI as a system DM bus. - */ -struct scsi_driver -{ - rt_err_t (*probe)(struct rt_scsi_device *sdev); - rt_err_t (*remove)(struct rt_scsi_device *sdev); -}; - -extern rt_err_t scsi_sd_probe(struct rt_scsi_device *sdev); -extern rt_err_t scsi_sd_remove(struct rt_scsi_device *sdev); - -extern rt_err_t scsi_cdrom_probe(struct rt_scsi_device *sdev); -extern rt_err_t scsi_cdrom_remove(struct rt_scsi_device *sdev); - -static struct scsi_driver driver_table[SCSI_DEVICE_TYPE_MAX] = -{ -#ifdef RT_SCSI_SD - [SCSI_DEVICE_TYPE_DIRECT] = - { - .probe = scsi_sd_probe, - .remove = scsi_sd_remove, - }, -#endif /* RT_SCSI_SD */ -#ifdef RT_SCSI_CDROM - [SCSI_DEVICE_TYPE_CDROM] = - { - .probe = scsi_cdrom_probe, - .remove = scsi_cdrom_remove, - }, -#endif /* RT_SCSI_CDROM */ -}; - -static rt_err_t scsi_device_setup(struct rt_scsi_device *sdev) -{ - rt_err_t err; - rt_tick_t timeout; - - if (sdev->host->ops->reset) - { - if ((err = sdev->host->ops->reset(sdev))) - { - return err; - } - } - - if (!driver_table[sdev->devtype].probe) - { - LOG_E("Device type %x is not supported", sdev->devtype); - - return -RT_ENOSYS; - } - - timeout = rt_tick_from_millisecond(5000); - timeout += rt_tick_get(); - - while ((err = rt_scsi_test_unit_ready(sdev))) - { - if (rt_tick_get() >= timeout) - { - return -RT_ETIMEOUT; - } - } - - return driver_table[sdev->devtype].probe(sdev); -} - -rt_err_t rt_scsi_host_register(struct rt_scsi_host *scsi) -{ - struct rt_scsi_device tmp_sdev, *sdev; - - if (!scsi || !scsi->dev || !scsi->ops) - { - return -RT_EINVAL; - } - - if (!scsi->max_id || !scsi->max_lun) - { - return -RT_EINVAL; - } - - rt_list_init(&scsi->lun_nodes); - - rt_memset(&tmp_sdev, 0, sizeof(tmp_sdev)); - tmp_sdev.host = scsi; - - for (rt_size_t id = 0; id < scsi->max_id; ++id) - { - for (rt_size_t lun = 0; lun < scsi->max_lun; ++lun) - { - tmp_sdev.id = id; - tmp_sdev.lun = lun; - - if (rt_scsi_inquiry(&tmp_sdev, RT_NULL)) - { - continue; - } - - if (tmp_sdev.devtype >= SCSI_DEVICE_TYPE_MAX) - { - /* - * This might seem odd, but we're only aiming to - * support simple SCSI. - * If devices appear on the bus out of order, - * we won't perform additional scans. - */ - scsi->max_id = id; - scsi->max_lun = lun; - - LOG_D("Scan is end of ID: %u LUN: %u", id, lun); - break; - } - - if (!(sdev = rt_malloc(sizeof(*sdev)))) - { - if (!rt_list_isempty(&scsi->lun_nodes)) - { - LOG_E("No memory to create device ID: %u, LUN: %u", id, lun); - - return RT_EOK; - } - - return -RT_ENOMEM; - } - - rt_memcpy(sdev, &tmp_sdev, sizeof(*sdev)); - rt_list_init(&sdev->list); - - if (scsi_device_setup(sdev)) - { - rt_free(sdev); - continue; - } - - rt_list_insert_before(&scsi->lun_nodes, &sdev->list); - } - } - - return rt_list_isempty(&scsi->lun_nodes) ? -RT_EEMPTY : RT_EOK; -} - -rt_err_t rt_scsi_host_unregister(struct rt_scsi_host *scsi) -{ - struct rt_scsi_device *sdev, *next_sdev; - - if (!scsi) - { - return -RT_EINVAL; - } - - rt_list_for_each_entry_safe(sdev, next_sdev, &scsi->lun_nodes, list) - { - rt_list_remove(&sdev->list); - - if (sdev->host->ops->reset) - { - sdev->host->ops->reset(sdev); - } - - if (!driver_table[sdev->devtype].remove) - { - driver_table[sdev->devtype].remove(sdev); - } - - rt_free(sdev); - } - - return RT_EOK; -} - -rt_inline rt_err_t scsi_transfer(struct rt_scsi_device *sdev, struct rt_scsi_cmd *cmd) -{ - return sdev->host->ops->transfer(sdev, cmd); -} - -rt_err_t rt_scsi_request_sense(struct rt_scsi_device *sdev, - struct rt_scsi_request_sense_data *out_data) -{ - rt_err_t err; - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.request_sense.opcode = RT_SCSI_CMD_REQUEST_SENSE; - cmd.op.request_sense.config = 0; - cmd.op.request_sense.alloc_length = 0x12; - cmd.op.request_sense.control = 0; - cmd.op_size = sizeof(cmd.op.request_sense); - cmd.data.ptr = &cmd.data.request_sense; - cmd.data.size = sizeof(cmd.data.request_sense); - - err = scsi_transfer(sdev, &cmd); - - if (!err && out_data) - { - rt_memcpy(out_data, &cmd.data.request_sense, sizeof(*out_data)); - } - - return err; -} - -rt_err_t rt_scsi_test_unit_ready(struct rt_scsi_device *sdev) -{ - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.test_unit_ready.opcode = RT_SCSI_CMD_TEST_UNIT_READY; - cmd.op.test_unit_ready.control = 0; - cmd.op_size = sizeof(cmd.op.test_unit_ready); - - return scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); -} - -rt_err_t rt_scsi_inquiry(struct rt_scsi_device *sdev, - struct rt_scsi_inquiry_data *out_data) -{ - rt_err_t err; - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.inquiry.opcode = RT_SCSI_CMD_INQUIRY; - cmd.op.inquiry.config = 0; - cmd.op.inquiry.page = 0; - cmd.op.inquiry.alloc_length = 0x24; - cmd.op.inquiry.control = 0; - cmd.op_size = sizeof(cmd.op.inquiry); - cmd.data.ptr = &cmd.data.inquiry; - cmd.data.size = sizeof(cmd.data.inquiry); - - err = scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); - - if (!err) - { - sdev->devtype = cmd.data.inquiry.devtype & RT_SCSI_DEVTYPE_MASK; - sdev->removable = cmd.data.inquiry.rmb >> RT_SCSI_REMOVABLE_BIT; - - if (out_data) - { - rt_memcpy(out_data, &cmd.data.inquiry, sizeof(*out_data)); - } - } - - return err; -} - -rt_err_t rt_scsi_read_capacity10(struct rt_scsi_device *sdev, - struct rt_scsi_read_capacity10_data *out_data) -{ - rt_err_t err; - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.read_capacity10.opcode = RT_SCSI_CMD_READ_CAPACITY10; - cmd.op.read_capacity10.config = 0; - cmd.op.read_capacity10.logical_block_addr = 0; - cmd.op.read_capacity10.pmi = 0; - cmd.op.read_capacity10.control = 0; - cmd.op_size = sizeof(cmd.op.read_capacity10); - cmd.data.ptr = &cmd.data.read_capacity10; - cmd.data.size = sizeof(cmd.data.read_capacity10); - - err = scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); - - if (!err) - { - sdev->last_block = rt_be32_to_cpu(cmd.data.read_capacity10.last_block); - sdev->block_size = rt_be32_to_cpu(cmd.data.read_capacity10.block_size); - - if (out_data) - { - rt_memcpy(out_data, &cmd.data.read_capacity10, sizeof(*out_data)); - } - } - - return err; -} - -rt_err_t rt_scsi_read_capacity16(struct rt_scsi_device *sdev, - struct rt_scsi_read_capacity16_data *out_data) -{ - rt_err_t err; - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.read_capacity16.opcode = RT_SCSI_CMD_READ_CAPACITY16; - cmd.op.read_capacity16.config = 0x10; - cmd.op.read_capacity16.logical_block_addr = 0; - cmd.op.read_capacity16.alloc_len = rt_cpu_to_be32(sizeof(cmd.data.read_capacity16)); - cmd.op.read_capacity16.pmi = 0; - cmd.op.read_capacity16.control = 0; - cmd.op_size = sizeof(cmd.op.read_capacity16); - cmd.data.ptr = &cmd.data.read_capacity16; - cmd.data.size = sizeof(cmd.data.read_capacity16); - - err = scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); - - if (!err) - { - sdev->last_block = rt_be64_to_cpu(cmd.data.read_capacity16.last_block); - sdev->block_size = rt_be32_to_cpu(cmd.data.read_capacity16.block_size); - - if (out_data) - { - rt_memcpy(out_data, &cmd.data.read_capacity16, sizeof(*out_data)); - } - } - - return err; -} - -rt_err_t rt_scsi_read10(struct rt_scsi_device *sdev, - rt_off_t lba, void *buffer, rt_size_t size) -{ - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.read10.opcode = RT_SCSI_CMD_READ10; - cmd.op.read10.config = 0; - cmd.op.read10.lba = rt_cpu_to_be32(lba); - cmd.op.read10.size = rt_cpu_to_be16(size); - cmd.op_size = sizeof(cmd.op.read10); - cmd.data.ptr = buffer; - cmd.data.size = size * sdev->block_size; - - return scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); -} - -rt_err_t rt_scsi_read12(struct rt_scsi_device *sdev, - rt_off_t lba, void *buffer, rt_size_t size) -{ - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.read12.opcode = RT_SCSI_CMD_READ12; - cmd.op.read12.config = 0; - cmd.op.read12.lba = rt_cpu_to_be32(lba); - cmd.op.read12.size = rt_cpu_to_be32(size); - cmd.op.read12.control = 0; - cmd.op_size = sizeof(cmd.op.read12); - cmd.data.ptr = buffer; - cmd.data.size = size * sdev->block_size; - - return scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); -} - -rt_err_t rt_scsi_read16(struct rt_scsi_device *sdev, - rt_off_t lba, void *buffer, rt_size_t size) -{ - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.read16.opcode = RT_SCSI_CMD_READ16; - cmd.op.read16.config = 0; - cmd.op.read16.lba = rt_cpu_to_be64(lba); - cmd.op.read16.size = rt_cpu_to_be32(size); - cmd.op.read16.control = 0; - cmd.op_size = sizeof(cmd.op.read16); - cmd.data.ptr = buffer; - cmd.data.size = size * sdev->block_size; - - return scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); -} - -rt_err_t rt_scsi_write10(struct rt_scsi_device *sdev, - rt_off_t lba, const void *buffer, rt_size_t size) -{ - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.write10.opcode = RT_SCSI_CMD_WRITE10; - cmd.op.write10.config = 0; - cmd.op.write10.lba = rt_cpu_to_be32(lba); - cmd.op.write10.size = rt_cpu_to_be16(size); - cmd.op_size = sizeof(cmd.op.write10); - cmd.data.ptr = (void *)buffer; - cmd.data.size = size * sdev->block_size; - - return scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); -} - -rt_err_t rt_scsi_write12(struct rt_scsi_device *sdev, - rt_off_t lba, const void *buffer, rt_size_t size) -{ - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.write12.opcode = RT_SCSI_CMD_WRITE12; - cmd.op.write12.config = 0; - cmd.op.write12.lba = rt_cpu_to_be32(lba); - cmd.op.write12.size = rt_cpu_to_be32(size); - cmd.op.write12.control = 0; - cmd.op_size = sizeof(cmd.op.write12); - cmd.data.ptr = (void *)buffer; - cmd.data.size = size * sdev->block_size; - - return scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); -} - -rt_err_t rt_scsi_write16(struct rt_scsi_device *sdev, - rt_off_t lba, const void *buffer, rt_size_t size) -{ - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.write16.opcode = RT_SCSI_CMD_WRITE16; - cmd.op.write16.config = 0; - cmd.op.write16.lba = rt_cpu_to_be64(lba); - cmd.op.write16.size = rt_cpu_to_be32(size); - cmd.op.write16.control = 0; - cmd.op_size = sizeof(cmd.op.write16); - cmd.data.ptr = (void *)buffer; - cmd.data.size = size * sdev->block_size; - - return scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); -} - -rt_err_t rt_scsi_synchronize_cache10(struct rt_scsi_device *sdev, - rt_off_t lba, rt_size_t size) -{ - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.synchronize_cache10.opcode = RT_SCSI_CMD_SYNCHRONIZE_CACHE10; - cmd.op.synchronize_cache10.config = 0; - cmd.op.synchronize_cache10.lba = rt_cpu_to_be32(lba); - cmd.op.synchronize_cache10.size = rt_cpu_to_be16(size); - cmd.op.synchronize_cache10.control = 0; - cmd.op_size = sizeof(cmd.op.synchronize_cache10); - - return scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); -} - -rt_err_t rt_scsi_synchronize_cache16(struct rt_scsi_device *sdev, - rt_off_t lba, rt_size_t size) -{ - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.synchronize_cache16.opcode = RT_SCSI_CMD_SYNCHRONIZE_CACHE16; - cmd.op.synchronize_cache16.config = 0; - cmd.op.synchronize_cache16.lba = rt_cpu_to_be64(lba); - cmd.op.synchronize_cache16.size = rt_cpu_to_be32(size); - cmd.op.synchronize_cache16.control = 0; - cmd.op_size = sizeof(cmd.op.synchronize_cache16); - - return scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); -} - -rt_err_t rt_scsi_write_same10(struct rt_scsi_device *sdev, - rt_off_t lba, rt_size_t size) -{ - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.write_same10.opcode = RT_SCSI_CMD_WRITE_SAME10; - cmd.op.write_same10.config = RT_BIT(RT_SCSI_UNMAP_SHIFT); - cmd.op.write_same10.lba = rt_cpu_to_be32(lba); - cmd.op.write_same10.size = rt_cpu_to_be16(size); - cmd.op.write_same10.control = 0; - cmd.op_size = sizeof(cmd.op.write_same10); - - return scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); -} - -rt_err_t rt_scsi_write_same16(struct rt_scsi_device *sdev, - rt_off_t lba, rt_size_t size) -{ - struct rt_scsi_cmd cmd; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.write_same16.opcode = RT_SCSI_CMD_WRITE_SAME16; - cmd.op.write_same16.config = RT_BIT(RT_SCSI_UNMAP_SHIFT); - cmd.op.write_same16.lba = rt_cpu_to_be64(lba); - cmd.op.write_same16.size = rt_cpu_to_be32(size); - cmd.op.write_same16.control = 0; - cmd.op_size = sizeof(cmd.op.write_same16); - - return scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); -} - -rt_err_t rt_scsi_mode_select6(struct rt_scsi_device *sdev, - rt_uint8_t pf, rt_uint8_t sp, void *buffer, rt_size_t size, - struct rt_scsi_mode_select_data *data) -{ - rt_err_t err; - rt_uint8_t *real_buffer; - struct rt_scsi_cmd cmd; - - real_buffer = rt_malloc(4 + size); - - if (!real_buffer) - { - return -RT_ENOMEM; - } - - rt_memcpy(real_buffer + 4, buffer, size); - size += 4; - real_buffer[0] = 0; - real_buffer[1] = data->medium_type; - real_buffer[2] = data->device_specific; - real_buffer[3] = data->block_descriptor_length; - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.mode_select6.opcode = RT_SCSI_CMD_MODE_SELECT; - cmd.op.mode_select6.config = pf ? RT_BIT(RT_SCSI_PF_SHIFT) : 0; - cmd.op.mode_select6.config |= sp ? RT_BIT(RT_SCSI_SP_SHIFT) : 0; - cmd.op.mode_select6.param_list_len = (rt_uint8_t)size; - cmd.op.mode_select6.control = 0; - cmd.op_size = sizeof(cmd.op.mode_select6); - cmd.data.ptr = real_buffer; - cmd.data.size = size; - - err = scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); - - rt_free(real_buffer); - - return err; -} - -rt_err_t rt_scsi_mode_select10(struct rt_scsi_device *sdev, - rt_uint8_t pf, rt_uint8_t sp, void *buffer, rt_size_t size, - struct rt_scsi_mode_select_data *data) -{ - rt_err_t err; - rt_uint8_t *real_buffer; - struct rt_scsi_cmd cmd; - - real_buffer = rt_malloc(8 + size); - - if (!real_buffer) - { - return -RT_ENOMEM; - } - - rt_memcpy(real_buffer + 8, buffer, size); - size += 8; - real_buffer[0] = 0; - real_buffer[1] = 0; - real_buffer[2] = data->medium_type; - real_buffer[3] = data->device_specific; - real_buffer[4] = data->longlba ? 0x01 : 0; - real_buffer[5] = 0; - real_buffer[6] = rt_cpu_to_be16(data->block_descriptor_length); - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.mode_select10.opcode = RT_SCSI_CMD_MODE_SELECT10; - cmd.op.mode_select10.config = pf ? RT_BIT(RT_SCSI_PF_SHIFT) : 0; - cmd.op.mode_select10.config |= sp ? RT_BIT(RT_SCSI_SP_SHIFT) : 0; - cmd.op.mode_select10.param_list_len = rt_cpu_to_be16(size); - cmd.op.mode_select10.control = 0; - cmd.op_size = sizeof(cmd.op.mode_select10); - cmd.data.ptr = real_buffer; - cmd.data.size = size; - - err = scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); - - rt_free(real_buffer); - - return err; -} - -static void scsi_mode_sense_fill(struct rt_scsi_mode_select_data *data, - rt_uint8_t modepage, rt_uint8_t *buffer, rt_bool_t use10) -{ - if (buffer[0] == 0x86 && buffer[1] == 0x0b && (modepage == 6 || modepage == 8)) - { - data->header_length = 0; - data->length = 13; - data->medium_type = 0; - data->device_specific = 0; - data->longlba = 0; - data->block_descriptor_length = 0; - } - else if (use10) - { - data->length = rt_be16_to_cpu(buffer[0]) + 2; - data->medium_type = buffer[2]; - data->device_specific = buffer[3]; - data->longlba = buffer[4] & 0x01; - data->block_descriptor_length = rt_be16_to_cpu(buffer[6]); - } - else - { - data->length = buffer[0] + 1; - data->medium_type = buffer[1]; - data->device_specific = buffer[2]; - data->block_descriptor_length = buffer[3]; - } -} - -rt_err_t rt_scsi_mode_sense6(struct rt_scsi_device *sdev, - rt_uint8_t dbd, rt_uint8_t modepage, rt_uint8_t subpage, void *buffer, rt_size_t size, - struct rt_scsi_mode_select_data *data) -{ - rt_err_t err; - struct rt_scsi_cmd cmd; - - rt_memset(buffer, 0, size); - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.mode_sense6.opcode = RT_SCSI_CMD_MODE_SENSE; - cmd.op.mode_sense6.config = dbd & 0x18; - cmd.op.mode_sense6.page_control_code = modepage; - cmd.op.mode_sense6.subpage_code = subpage; - cmd.op.mode_sense6.allocation_len = (rt_uint8_t)size; - cmd.op.mode_sense6.control = 0; - cmd.op_size = sizeof(cmd.op.mode_sense6); - cmd.data.ptr = buffer; - cmd.data.size = size; - - err = scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); - - if (!err) - { - data->header_length = 4; - scsi_mode_sense_fill(data, modepage, buffer, RT_FALSE); - } - - return err; -} - -rt_err_t rt_scsi_mode_sense10(struct rt_scsi_device *sdev, - rt_uint8_t dbd, rt_uint8_t modepage, rt_uint8_t subpage, void *buffer, rt_size_t size, - struct rt_scsi_mode_select_data *data) -{ - rt_err_t err; - struct rt_scsi_cmd cmd; - - rt_memset(buffer, 0, size); - - rt_memset(&cmd, 0, sizeof(cmd)); - cmd.op.mode_sense6.opcode = RT_SCSI_CMD_MODE_SENSE10; - cmd.op.mode_sense6.config = dbd & 0x18; - cmd.op.mode_sense6.page_control_code = modepage; - cmd.op.mode_sense6.subpage_code = subpage; - cmd.op.mode_sense6.allocation_len = rt_cpu_to_be16(size); - cmd.op.mode_sense6.control = 0; - cmd.op_size = sizeof(cmd.op.mode_sense6); - cmd.data.ptr = buffer; - cmd.data.size = size; - - err = scsi_transfer(sdev, &cmd) ? : rt_scsi_request_sense(sdev, RT_NULL); - - if (!err) - { - data->header_length = 8; - scsi_mode_sense_fill(data, modepage, buffer, RT_FALSE); - } - - return err; -} diff --git a/rt-thread/components/drivers/scsi/scsi_cdrom.c b/rt-thread/components/drivers/scsi/scsi_cdrom.c deleted file mode 100644 index 93608d1..0000000 --- a/rt-thread/components/drivers/scsi/scsi_cdrom.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#include -#include -#include - -#define DBG_TAG "scsi.blk" -#define DBG_LVL DBG_INFO -#include - -struct scsi_cdrom -{ - struct rt_blk_disk parent; - struct rt_scsi_device *sdev; - - int cdrom_id; - struct rt_device_blk_geometry geometry; -}; - -#define raw_to_scsi_cdrom(raw) rt_container_of(raw, struct scsi_cdrom, parent) - -static struct rt_dm_ida cdrom_ida = RT_DM_IDA_INIT(CUSTOM); -static struct rt_dm_ida scsi_cdrom_ida = RT_DM_IDA_INIT(SCSI_CDROM); - -static rt_ssize_t scsi_cdrom_read(struct rt_blk_disk *disk, rt_off_t sector, - void *buffer, rt_size_t sector_count) -{ - rt_err_t err; - struct scsi_cdrom *scdrom = raw_to_scsi_cdrom(disk); - struct rt_scsi_device *sdev = scdrom->sdev; - - sector_count &= RT_UINT32_MAX; - - if (sector >> 32) - { - err = rt_scsi_read16(sdev, sector, buffer, sector_count); - } - else - { - err = rt_scsi_read12(sdev, sector, buffer, sector_count); - } - - return !err ? sector_count : (rt_ssize_t)err; -} - -static rt_err_t scsi_cdrom_getgeome(struct rt_blk_disk *disk, - struct rt_device_blk_geometry *geometry) -{ - struct scsi_cdrom *scdrom = raw_to_scsi_cdrom(disk); - - rt_memcpy(geometry, &scdrom->geometry, sizeof(scdrom->geometry)); - - return RT_EOK; -} - -static const struct rt_blk_disk_ops scsi_cdrom_ops = -{ - .read = scsi_cdrom_read, - .getgeome = scsi_cdrom_getgeome, -}; - -rt_err_t scsi_cdrom_probe(struct rt_scsi_device *sdev) -{ - rt_err_t err; - union - { - struct rt_scsi_read_capacity10_data capacity10; - struct rt_scsi_read_capacity16_data capacity16; - } data; - struct scsi_cdrom *scdrom = rt_calloc(1, sizeof(*scdrom)); - - if (!scdrom) - { - return -RT_ENOMEM; - } - - if ((scdrom->cdrom_id = rt_dm_ida_alloc(&cdrom_ida)) < 0) - { - return -RT_EFULL; - } - - sdev->priv = scdrom; - scdrom->sdev = sdev; - scdrom->parent.ida = &scsi_cdrom_ida; - scdrom->parent.read_only = RT_TRUE; - scdrom->parent.parallel_io = RT_FALSE; - scdrom->parent.ops = &scsi_cdrom_ops; - scdrom->parent.max_partitions = RT_BLK_PARTITION_NONE; - - if ((err = rt_scsi_read_capacity10(sdev, &data.capacity10))) - { - goto _fail; - } - if (data.capacity10.last_block == 0xffffffff) - { - if ((err = rt_scsi_read_capacity16(sdev, &data.capacity16))) - { - goto _fail; - } - } - scdrom->geometry.bytes_per_sector = sdev->block_size; - scdrom->geometry.block_size = sdev->block_size; - scdrom->geometry.sector_count = sdev->last_block + 1; - - rt_dm_dev_set_name(&scdrom->parent.parent, "cdrom%u", scdrom->cdrom_id); - - if ((err = rt_hw_blk_disk_register(&scdrom->parent))) - { - goto _fail; - } - - return RT_EOK; - -_fail: - rt_dm_ida_free(&cdrom_ida, scdrom->cdrom_id); - rt_free(scdrom); - - return err; -} - -rt_err_t scsi_cdrom_remove(struct rt_scsi_device *sdev) -{ - struct scsi_cdrom *scdrom = sdev->priv; - - rt_dm_ida_free(&cdrom_ida, scdrom->cdrom_id); - - return rt_hw_blk_disk_unregister(&scdrom->parent); -} diff --git a/rt-thread/components/drivers/scsi/scsi_sd.c b/rt-thread/components/drivers/scsi/scsi_sd.c deleted file mode 100644 index cc509a7..0000000 --- a/rt-thread/components/drivers/scsi/scsi_sd.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2023-02-25 GuEe-GUI the first version - */ - -#include -#include -#include - -#define DBG_TAG "scsi.blk" -#define DBG_LVL DBG_INFO -#include - -#include "../block/blk_dev.h" - -struct scsi_sd -{ - struct rt_blk_disk parent; - struct rt_scsi_device *sdev; - - int sd_id; - rt_bool_t use16; - struct rt_device_blk_geometry geometry; -}; - -#define raw_to_scsi_sd(raw) rt_container_of(raw, struct scsi_sd, parent) - -static struct rt_dm_ida sd_ida = RT_DM_IDA_INIT(CUSTOM); -static struct rt_dm_ida scsi_sd_ida = RT_DM_IDA_INIT(SCSI_SD); - -static rt_ssize_t scsi_sd_read(struct rt_blk_disk *disk, rt_off_t sector, - void *buffer, rt_size_t sector_count) -{ - rt_err_t err; - struct scsi_sd *ssd = raw_to_scsi_sd(disk); - struct rt_scsi_device *sdev = ssd->sdev; - - sector_count &= RT_UINT32_MAX; - - if (sector >> 32) - { - err = rt_scsi_read16(sdev, sector, buffer, sector_count); - } - else - { - err = rt_scsi_read10(sdev, sector, buffer, sector_count); - } - - return !err ? sector_count : (rt_ssize_t)err; -} - -static rt_ssize_t scsi_sd_write(struct rt_blk_disk *disk, rt_off_t sector, - const void *buffer, rt_size_t sector_count) -{ - rt_err_t err; - struct scsi_sd *ssd = raw_to_scsi_sd(disk); - struct rt_scsi_device *sdev = ssd->sdev; - - sector_count &= RT_UINT32_MAX; - - if (sector >> 32) - { - err = rt_scsi_write16(sdev, sector, buffer, sector_count); - } - else - { - err = rt_scsi_write10(sdev, sector, buffer, sector_count); - } - - return !err ? sector_count : (rt_ssize_t)err; -} - -static rt_err_t scsi_sd_getgeome(struct rt_blk_disk *disk, - struct rt_device_blk_geometry *geometry) -{ - struct scsi_sd *ssd = raw_to_scsi_sd(disk); - - rt_memcpy(geometry, &ssd->geometry, sizeof(ssd->geometry)); - - return RT_EOK; -} - -static rt_err_t scsi_sd_sync(struct rt_blk_disk *disk) -{ - rt_err_t err; - rt_size_t lba_count; - struct scsi_sd *ssd = raw_to_scsi_sd(disk); - struct rt_scsi_device *sdev = ssd->sdev; - - lba_count = ssd->geometry.sector_count; - - if (ssd->use16) - { - err = rt_scsi_synchronize_cache16(sdev, 0, lba_count); - } - else - { - err = rt_scsi_synchronize_cache10(sdev, 0, lba_count); - } - - return err; -} - -static rt_err_t scsi_sd_erase(struct rt_blk_disk *disk) -{ - rt_err_t err; - rt_size_t lba_count; - struct scsi_sd *ssd = raw_to_scsi_sd(disk); - struct rt_scsi_device *sdev = ssd->sdev; - - lba_count = ssd->geometry.sector_count; - - if (ssd->use16) - { - err = rt_scsi_write_same16(sdev, 0, lba_count); - } - else - { - err = rt_scsi_write_same10(sdev, 0, lba_count); - } - - return err; -} - -static rt_err_t scsi_sd_autorefresh(struct rt_blk_disk *disk, rt_bool_t is_auto) -{ - rt_err_t err; - int sp; - rt_size_t size; - rt_uint8_t buffer[64]; - rt_uint8_t *buffer_data; - rt_bool_t use6 = RT_TRUE; - struct scsi_sd *ssd = raw_to_scsi_sd(disk); - struct rt_scsi_device *sdev = ssd->sdev; - struct rt_scsi_mode_select_data data; - - err = rt_scsi_mode_sense6(sdev, 0x08, 8, 0, buffer, sizeof(buffer), &data); - - if (err && err != -RT_ENOMEM) - { - use6 = RT_FALSE; - err = rt_scsi_mode_sense10(sdev, 0x08, 8, 0, buffer, sizeof(buffer), &data); - } - if (err) - { - return err; - } - - size = rt_min_t(rt_size_t, sizeof(buffer), - data.length - data.header_length - data.block_descriptor_length); - buffer_data = buffer + data.header_length + data.block_descriptor_length; - buffer_data[2] &= ~0x05; - buffer_data[2] |= (!!is_auto) << 2 | (!!is_auto); - sp = buffer_data[0] & 0x80 ? 1 : 0; - buffer_data[0] &= ~0x80; - data.device_specific = 0; - - if (use6) - { - err = rt_scsi_mode_select6(sdev, 1, sp, buffer_data, size, &data); - } - else - { - err = rt_scsi_mode_select10(sdev, 1, sp, buffer_data, size, &data); - } - - return err; -} - -static const struct rt_blk_disk_ops scsi_sd_ops = -{ - .read = scsi_sd_read, - .write = scsi_sd_write, - .getgeome = scsi_sd_getgeome, - .sync = scsi_sd_sync, - .erase = scsi_sd_erase, - .autorefresh = scsi_sd_autorefresh, -}; - -rt_err_t scsi_sd_probe(struct rt_scsi_device *sdev) -{ - rt_err_t err; - union - { - struct rt_scsi_read_capacity10_data capacity10; - struct rt_scsi_read_capacity16_data capacity16; - } data; - struct scsi_sd *ssd = rt_calloc(1, sizeof(*ssd)); - - if (!ssd) - { - return -RT_ENOMEM; - } - - if ((ssd->sd_id = rt_dm_ida_alloc(&sd_ida)) < 0) - { - return -RT_EFULL; - } - - sdev->priv = ssd; - ssd->sdev = sdev; - ssd->parent.ida = &scsi_sd_ida; - ssd->parent.parallel_io = RT_FALSE; - ssd->parent.ops = &scsi_sd_ops; - ssd->parent.max_partitions = RT_BLK_PARTITION_MAX; - - if ((err = rt_scsi_read_capacity10(sdev, &data.capacity10))) - { - goto _fail; - } - if (data.capacity10.last_block == 0xffffffff) - { - if ((err = rt_scsi_read_capacity16(sdev, &data.capacity16))) - { - goto _fail; - } - ssd->use16 = RT_TRUE; - } - ssd->geometry.bytes_per_sector = sdev->block_size; - ssd->geometry.block_size = sdev->block_size; - ssd->geometry.sector_count = sdev->last_block + 1; - - rt_dm_dev_set_name(&ssd->parent.parent, "sd%c%c", letter_name(ssd->sd_id)); - - if ((err = rt_hw_blk_disk_register(&ssd->parent))) - { - goto _fail; - } - - return RT_EOK; - -_fail: - rt_dm_ida_free(&sd_ida, ssd->sd_id); - rt_free(ssd); - - return err; -} - -rt_err_t scsi_sd_remove(struct rt_scsi_device *sdev) -{ - struct scsi_sd *ssd = sdev->priv; - - rt_dm_ida_free(&sd_ida, ssd->sd_id); - - return rt_hw_blk_disk_unregister(&ssd->parent); -} diff --git a/rt-thread/components/drivers/sdio/Kconfig b/rt-thread/components/drivers/sdio/Kconfig index dd1fe0a..e5bff45 100644 --- a/rt-thread/components/drivers/sdio/Kconfig +++ b/rt-thread/components/drivers/sdio/Kconfig @@ -1,6 +1,5 @@ config RT_USING_SDIO bool "Using SD/MMC device drivers" - select RT_USING_BLK default n if RT_USING_SDIO @@ -25,8 +24,5 @@ config RT_USING_SDIO default 16 config RT_SDIO_DEBUG bool "Enable SDIO debug log output" - default n - config RT_USING_SDHCI - bool "Using sdhci for sd/mmc drivers" - default n - endif + default n + endif diff --git a/rt-thread/components/drivers/sdio/SConscript b/rt-thread/components/drivers/sdio/SConscript index 98d71d1..d5b6eb1 100644 --- a/rt-thread/components/drivers/sdio/SConscript +++ b/rt-thread/components/drivers/sdio/SConscript @@ -3,20 +3,16 @@ from building import * cwd = GetCurrentDir() src = Split(""" -dev_block.c -dev_mmcsd_core.c -dev_sd.c -dev_sdio.c -dev_mmc.c +block_dev.c +mmcsd_core.c +sd.c +sdio.c +gpt.c +mmc.c """) # The set of source files associated with this SConscript file. -path = [cwd + '/../include' , cwd + '/sdhci/include'] - -if GetDepend('RT_USING_SDHCI'): - src += [os.path.join('sdhci', 'sdhci.c')] - src += [os.path.join('sdhci', 'fit-mmc.c')] - src += [os.path.join('sdhci', 'sdhci-platform.c')] +path = [cwd + '/../include'] group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SDIO'], CPPPATH = path) diff --git a/rt-thread/components/drivers/sdio/dev_block.c b/rt-thread/components/drivers/sdio/dev_block.c deleted file mode 100644 index d4f8f62..0000000 --- a/rt-thread/components/drivers/sdio/dev_block.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-07-25 weety first version - * 2023-08-08 GuEe-GUI port to the block - */ - -#include -#include -#include -#include - -#define DBG_TAG "SDIO" -#ifdef RT_SDIO_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif /* RT_SDIO_DEBUG */ -#include - -#ifndef RT_MMCSD_MAX_PARTITION -#define RT_MMCSD_MAX_PARTITION 16 -#endif - -struct mmcsd_blk_device -{ - struct rt_blk_disk parent; - struct rt_mmcsd_card *card; - - rt_size_t max_req_size; - struct rt_device_blk_geometry geometry; -}; - -#define raw_to_mmcsd_blk(raw) rt_container_of(raw, struct mmcsd_blk_device, parent) - -#ifdef RT_USING_DM -static struct rt_dm_ida sdio_ida = RT_DM_IDA_INIT(SDIO); -#endif - -static int __send_status(struct rt_mmcsd_card *card, rt_uint32_t *status, unsigned retries) -{ - int err; - struct rt_mmcsd_cmd cmd; - - cmd.busy_timeout = 0; - cmd.cmd_code = SEND_STATUS; - cmd.arg = card->rca << 16; - cmd.flags = RESP_R1 | CMD_AC; - err = mmcsd_send_cmd(card->host, &cmd, retries); - if (err) - return err; - - if (status) - *status = cmd.resp[0]; - - return 0; -} - -static int card_busy_detect(struct rt_mmcsd_card *card, unsigned int timeout_ms, - rt_uint32_t *resp_errs) -{ - int timeout = rt_tick_from_millisecond(timeout_ms); - int err = 0; - rt_uint32_t status; - rt_tick_t start; - - start = rt_tick_get(); - do - { - rt_bool_t out = (int)(rt_tick_get() - start) > timeout; - - err = __send_status(card, &status, 5); - if (err) - { - LOG_E("error %d requesting status", err); - return err; - } - - /* Accumulate any response error bits seen */ - if (resp_errs) - *resp_errs |= status; - - if (out) - { - LOG_E("wait card busy timeout"); - return -RT_ETIMEOUT; - } - /* - * Some cards mishandle the status bits, - * so make sure to check both the busy - * indication and the card state. - */ - } - while (!(status & R1_READY_FOR_DATA) || - (R1_CURRENT_STATE(status) == 7)); - - return err; -} - -rt_int32_t mmcsd_num_wr_blocks(struct rt_mmcsd_card *card) -{ - rt_int32_t err; - rt_uint32_t blocks; - - struct rt_mmcsd_req req; - struct rt_mmcsd_cmd cmd; - struct rt_mmcsd_data data; - rt_uint32_t timeout_us; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = APP_CMD; - cmd.arg = card->rca << 16; - cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_AC; - - err = mmcsd_send_cmd(card->host, &cmd, 0); - if (err) - return -RT_ERROR; - if (!controller_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD)) - return -RT_ERROR; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SD_APP_SEND_NUM_WR_BLKS; - cmd.arg = 0; - cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC; - - rt_memset(&data, 0, sizeof(struct rt_mmcsd_data)); - - data.timeout_ns = card->tacc_ns * 100; - data.timeout_clks = card->tacc_clks * 100; - - timeout_us = data.timeout_ns / 1000; - timeout_us += data.timeout_clks * 1000 / - (card->host->io_cfg.clock / 1000); - - if (timeout_us > 100000) - { - data.timeout_ns = 100000000; - data.timeout_clks = 0; - } - - data.blksize = 4; - data.blks = 1; - data.flags = DATA_DIR_READ; - data.buf = &blocks; - - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - - req.cmd = &cmd; - req.data = &data; - - mmcsd_send_request(card->host, &req); - - if (cmd.err || data.err) - return -RT_ERROR; - - return blocks; -} - -static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, - rt_uint32_t sector, - void *buf, - rt_size_t blks, - rt_uint8_t dir) -{ - struct rt_mmcsd_cmd cmd, stop; - struct rt_mmcsd_data data; - struct rt_mmcsd_req req; - struct rt_mmcsd_host *host = card->host; - rt_uint32_t r_cmd, w_cmd; - - mmcsd_host_lock(host); - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - rt_memset(&stop, 0, sizeof(struct rt_mmcsd_cmd)); - rt_memset(&data, 0, sizeof(struct rt_mmcsd_data)); - req.cmd = &cmd; - req.data = &data; - - cmd.arg = sector; - if (!(card->flags & CARD_FLAG_SDHC)) - { - cmd.arg <<= 9; - } - cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC; - - data.blksize = SECTOR_SIZE; - data.blks = blks; - - if (blks > 1) - { - if (!controller_is_spi(card->host) || !dir) - { - req.stop = &stop; - stop.cmd_code = STOP_TRANSMISSION; - stop.arg = 0; - stop.flags = RESP_SPI_R1B | RESP_R1B | CMD_AC; - } - r_cmd = READ_MULTIPLE_BLOCK; - w_cmd = WRITE_MULTIPLE_BLOCK; - } - else - { - req.stop = RT_NULL; - r_cmd = READ_SINGLE_BLOCK; - w_cmd = WRITE_BLOCK; - } - - if (!controller_is_spi(card->host) && (card->flags & 0x8000)) - { - /* last request is WRITE,need check busy */ - card_busy_detect(card, 10000, RT_NULL); - } - - if (!dir) - { - cmd.cmd_code = r_cmd; - data.flags |= DATA_DIR_READ; - card->flags &= 0x7fff; - } - else - { - cmd.cmd_code = w_cmd; - data.flags |= DATA_DIR_WRITE; - card->flags |= 0x8000; - } - - mmcsd_set_data_timeout(&data, card); - data.buf = buf; - - mmcsd_send_request(host, &req); - - mmcsd_host_unlock(host); - - if (cmd.err || data.err || stop.err) - { - LOG_E("mmcsd request blocks error"); - LOG_E("%d,%d,%d, 0x%08x,0x%08x", - cmd.err, data.err, stop.err, data.flags, sector); - - return -RT_ERROR; - } - - return RT_EOK; -} - -static rt_int32_t mmcsd_set_blksize(struct rt_mmcsd_card *card) -{ - struct rt_mmcsd_cmd cmd; - int err; - - /* Block-addressed cards ignore MMC_SET_BLOCKLEN. */ - if (card->flags & CARD_FLAG_SDHC) - return 0; - - mmcsd_host_lock(card->host); - cmd.cmd_code = SET_BLOCKLEN; - cmd.arg = 512; - cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_AC; - err = mmcsd_send_cmd(card->host, &cmd, 5); - mmcsd_host_unlock(card->host); - - if (err) - { - LOG_E("MMCSD: unable to set block size to %d: %d", cmd.arg, err); - - return -RT_ERROR; - } - - return 0; -} - -static rt_ssize_t mmcsd_blk_read(struct rt_blk_disk *disk, rt_off_t sector, - void *buffer, rt_size_t sector_count) -{ - rt_err_t err; - rt_size_t offset = 0; - rt_size_t req_size = 0; - rt_size_t remain_size = sector_count; - void *rd_ptr = (void *)buffer; - struct mmcsd_blk_device *blk_dev = raw_to_mmcsd_blk(disk); - - while (remain_size) - { - req_size = rt_min_t(rt_size_t, remain_size, blk_dev->max_req_size); - - err = rt_mmcsd_req_blk(blk_dev->card, sector + offset, rd_ptr, req_size, 0); - - if (err) - { - return err; - } - - offset += req_size; - rd_ptr = (void *)((rt_uint8_t *)rd_ptr + (req_size << 9)); - remain_size -= req_size; - } - - return sector_count - remain_size; -} - -static rt_ssize_t mmcsd_blk_write(struct rt_blk_disk *disk, rt_off_t sector, - const void *buffer, rt_size_t sector_count) -{ - rt_err_t err; - rt_size_t offset = 0; - rt_size_t req_size = 0; - rt_size_t remain_size = sector_count; - void *wr_ptr = (void *)buffer; - struct mmcsd_blk_device *blk_dev = raw_to_mmcsd_blk(disk); - - while (remain_size) - { - req_size = rt_min_t(rt_size_t, remain_size, blk_dev->max_req_size); - - err = rt_mmcsd_req_blk(blk_dev->card, sector + offset, wr_ptr, req_size, 1); - - if (err) - { - return err; - } - - offset += req_size; - wr_ptr = (void *)((rt_uint8_t *)wr_ptr + (req_size << 9)); - remain_size -= req_size; - } - - return sector_count - remain_size; -} - -static rt_err_t mmcsd_blk_getgeome(struct rt_blk_disk *disk, - struct rt_device_blk_geometry *geometry) -{ - struct mmcsd_blk_device *blk_dev = raw_to_mmcsd_blk(disk); - - rt_memcpy(geometry, &blk_dev->geometry, sizeof(*geometry)); - - return RT_EOK; -} - -static const struct rt_blk_disk_ops mmcsd_blk_ops = -{ - .read = mmcsd_blk_read, - .write = mmcsd_blk_write, - .getgeome = mmcsd_blk_getgeome, -}; - -rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card) -{ - rt_err_t err; - struct rt_mmcsd_host *host = card->host; - struct mmcsd_blk_device *blk_dev = rt_calloc(1, sizeof(*blk_dev)); - - if (!blk_dev) - { - return -RT_ENOMEM; - } - card->blk_dev = blk_dev; - -#ifdef RT_USING_DM - blk_dev->parent.ida = &sdio_ida; -#endif - blk_dev->parent.parallel_io = RT_FALSE; - blk_dev->parent.removable = controller_is_removable(host); - blk_dev->parent.ops = &mmcsd_blk_ops; - blk_dev->parent.max_partitions = RT_MMCSD_MAX_PARTITION; - - blk_dev->card = card; - blk_dev->max_req_size = rt_min_t(rt_size_t, - host->max_dma_segs * host->max_seg_size, - host->max_blk_count * host->max_blk_size) >> 9; - blk_dev->geometry.bytes_per_sector = 1 << 9; - blk_dev->geometry.block_size = card->card_blksize; - blk_dev->geometry.sector_count = card->card_capacity * (1024 / 512); - - /* Set blk size before partitions probe, Why? */ - if ((err = mmcsd_set_blksize(card))) - { - goto _fail; - } - rt_thread_mdelay(1); - -#ifdef RT_USING_DM - rt_dm_dev_set_name(&blk_dev->parent.parent, host->name); -#else - rt_strncpy(blk_dev->parent.parent.parent.name, host->name, RT_NAME_MAX); -#endif - - if ((err = rt_hw_blk_disk_register(&blk_dev->parent))) - { - goto _fail; - } - - return RT_EOK; - -_fail: - card->blk_dev = RT_NULL; - free(blk_dev); - - return err; -} - -void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card) -{ - struct mmcsd_blk_device *blk_dev = card->blk_dev; - - if (!blk_dev) - { - return; - } - - if (!rt_hw_blk_disk_unregister(&blk_dev->parent)) - { - card->blk_dev = RT_NULL; - rt_free(blk_dev); - } -} diff --git a/rt-thread/components/drivers/sdio/dev_mmc.c b/rt-thread/components/drivers/sdio/dev_mmc.c deleted file mode 100644 index 6e1cdce..0000000 --- a/rt-thread/components/drivers/sdio/dev_mmc.c +++ /dev/null @@ -1,792 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2015-06-15 hichard first version - * 2024-05-25 HPMicro add HS400 support - */ - -#include -#include - -#define DBG_TAG "SDIO" -#ifdef RT_SDIO_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif /* RT_SDIO_DEBUG */ -#include - -static const rt_uint32_t tran_unit[] = -{ - 10000, 100000, 1000000, 10000000, - 0, 0, 0, 0 -}; - -static const rt_uint8_t tran_value[] = -{ - 0, 10, 12, 13, 15, 20, 25, 30, - 35, 40, 45, 50, 55, 60, 70, 80, -}; - -static const rt_uint32_t tacc_uint[] = -{ - 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, -}; - -static const rt_uint8_t tacc_value[] = -{ - 0, 10, 12, 13, 15, 20, 25, 30, - 35, 40, 45, 50, 55, 60, 70, 80, -}; - -rt_inline rt_uint32_t GET_BITS(rt_uint32_t *resp, - rt_uint32_t start, - rt_uint32_t size) -{ - const rt_int32_t __size = size; - const rt_uint32_t __mask = (__size < 32 ? 1 << __size : 0) - 1; - const rt_int32_t __off = 3 - ((start) / 32); - const rt_int32_t __shft = (start) & 31; - rt_uint32_t __res; - - __res = resp[__off] >> __shft; - if (__size + __shft > 32) - __res |= resp[__off - 1] << ((32 - __shft) % 32); - - return __res & __mask; -} - -/* - * Given a 128-bit response, decode to our card CSD structure. - */ -static rt_int32_t mmcsd_parse_csd(struct rt_mmcsd_card *card) -{ - rt_uint32_t a, b; - struct rt_mmcsd_csd *csd = &card->csd; - rt_uint32_t *resp = card->resp_csd; - - /* - * We only understand CSD structure v1.1 and v1.2. - * v1.2 has extra information in bits 15, 11 and 10. - * We also support eMMC v4.4 & v4.41. - */ - csd->csd_structure = GET_BITS(resp, 126, 2); - if (csd->csd_structure == 0) - { - LOG_E("unrecognised CSD structure version %d!", csd->csd_structure); - - return -RT_ERROR; - } - - csd->taac = GET_BITS(resp, 112, 8); - csd->nsac = GET_BITS(resp, 104, 8); - csd->tran_speed = GET_BITS(resp, 96, 8); - csd->card_cmd_class = GET_BITS(resp, 84, 12); - csd->rd_blk_len = GET_BITS(resp, 80, 4); - csd->rd_blk_part = GET_BITS(resp, 79, 1); - csd->wr_blk_misalign = GET_BITS(resp, 78, 1); - csd->rd_blk_misalign = GET_BITS(resp, 77, 1); - csd->dsr_imp = GET_BITS(resp, 76, 1); - csd->c_size = GET_BITS(resp, 62, 12); - csd->c_size_mult = GET_BITS(resp, 47, 3); - csd->r2w_factor = GET_BITS(resp, 26, 3); - csd->wr_blk_len = GET_BITS(resp, 22, 4); - csd->wr_blk_partial = GET_BITS(resp, 21, 1); - csd->csd_crc = GET_BITS(resp, 1, 7); - - card->card_blksize = 1 << csd->rd_blk_len; - card->tacc_clks = csd->nsac * 100; - card->tacc_ns = (tacc_uint[csd->taac & 0x07] * tacc_value[(csd->taac & 0x78) >> 3] + 9) / 10; - card->max_data_rate = tran_unit[csd->tran_speed & 0x07] * tran_value[(csd->tran_speed & 0x78) >> 3]; - if (csd->wr_blk_len >= 9) - { - a = GET_BITS(resp, 42, 5); - b = GET_BITS(resp, 37, 5); - card->erase_size = (a + 1) * (b + 1); - card->erase_size <<= csd->wr_blk_len - 9; - } - - return 0; -} - -/* - * Read extended CSD. - */ -static int mmc_get_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t **new_ext_csd) -{ - void *ext_csd; - struct rt_mmcsd_req req; - struct rt_mmcsd_cmd cmd; - struct rt_mmcsd_data data; - - *new_ext_csd = RT_NULL; - if (GET_BITS(card->resp_csd, 122, 4) < 4) - return 0; - - /* - * As the ext_csd is so large and mostly unused, we don't store the - * raw block in mmc_card. - */ - ext_csd = rt_malloc(512); - if (!ext_csd) - { - LOG_E("alloc memory failed when get ext csd!"); - return -RT_ENOMEM; - } - - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - rt_memset(&data, 0, sizeof(struct rt_mmcsd_data)); - - req.cmd = &cmd; - req.data = &data; - - cmd.cmd_code = SEND_EXT_CSD; - cmd.arg = 0; - - /* NOTE HACK: the RESP_SPI_R1 is always correct here, but we - * rely on callers to never use this with "native" calls for reading - * CSD or CID. Native versions of those commands use the R2 type, - * not R1 plus a data block. - */ - cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC; - - data.blksize = 512; - data.blks = 1; - data.flags = DATA_DIR_READ; - data.buf = ext_csd; - - /* - * Some cards require longer data read timeout than indicated in CSD. - * Address this by setting the read timeout to a "reasonably high" - * value. For the cards tested, 300ms has proven enough. If necessary, - * this value can be increased if other problematic cards require this. - */ - data.timeout_ns = 300000000; - data.timeout_clks = 0; - - mmcsd_send_request(card->host, &req); - - if (cmd.err) - return cmd.err; - if (data.err) - return data.err; - - *new_ext_csd = ext_csd; - return 0; -} - -/* - * Decode extended CSD. - */ -static int mmc_parse_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd) -{ - rt_uint64_t card_capacity = 0; - struct rt_mmcsd_host *host; - if (card == RT_NULL || ext_csd == RT_NULL) - { - LOG_E("emmc parse ext csd fail, invaild args"); - return -1; - } - - host = card->host; - - uint8_t device_type = ext_csd[EXT_CSD_CARD_TYPE]; - if ((host->flags & MMCSD_SUP_HS400) && (device_type & EXT_CSD_CARD_TYPE_HS400)) - { - card->flags |= CARD_FLAG_HS400; - card->max_data_rate = 200000000; - } - else if ((host->flags & MMCSD_SUP_HS200) && (device_type & EXT_CSD_CARD_TYPE_HS200)) - { - card->flags |= CARD_FLAG_HS200; - card->max_data_rate = 200000000; - } - else if ((host->flags & MMCSD_SUP_HIGHSPEED_DDR) && (device_type & EXT_CSD_CARD_TYPE_DDR_52)) - { - card->flags |= CARD_FLAG_HIGHSPEED_DDR; - card->hs_max_data_rate = 52000000; - } - else - { - card->flags |= CARD_FLAG_HIGHSPEED; - card->hs_max_data_rate = 52000000; - } - - if (ext_csd[EXT_CSD_STROBE_SUPPORT] != 0) - { - card->ext_csd.enhanced_data_strobe = 1; - } - - card->ext_csd.cache_size = - ext_csd[EXT_CSD_CACHE_SIZE + 0] << 0 | - ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 | - ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 | - ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24; - - card_capacity = *((rt_uint32_t *)&ext_csd[EXT_CSD_SEC_CNT]); - card->card_sec_cnt = card_capacity; - card_capacity *= card->card_blksize; - card_capacity >>= 10; /* unit:KB */ - card->card_capacity = card_capacity; - LOG_I("emmc card capacity %d KB, card sec count:%d.", card->card_capacity, card->card_sec_cnt); - - return 0; -} - -/** - * mmc_switch - modify EXT_CSD register - * @card: the MMC card associated with the data transfer - * @set: cmd set values - * @index: EXT_CSD register index - * @value: value to program into EXT_CSD register - * - * Modifies the EXT_CSD register for selected card. - */ -static int mmc_switch(struct rt_mmcsd_card *card, rt_uint8_t set, - rt_uint8_t index, rt_uint8_t value) -{ - int err; - struct rt_mmcsd_host *host = card->host; - struct rt_mmcsd_cmd cmd = {0}; - - cmd.cmd_code = SWITCH; - cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | - (index << 16) | (value << 8) | set; - cmd.flags = RESP_R1B | CMD_AC; - - err = mmcsd_send_cmd(host, &cmd, 3); - if (err) - return err; - - return 0; -} - -static int mmc_compare_ext_csds(struct rt_mmcsd_card *card, - rt_uint8_t *ext_csd, rt_uint32_t bus_width) -{ - rt_uint8_t *bw_ext_csd; - int err; - - if (bus_width == MMCSD_BUS_WIDTH_1) - return 0; - - err = mmc_get_ext_csd(card, &bw_ext_csd); - - if (err || bw_ext_csd == RT_NULL) - { - err = -RT_ERROR; - goto out; - } - - /* only compare read only fields */ - err = !((ext_csd[EXT_CSD_PARTITION_SUPPORT] == bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) && - (ext_csd[EXT_CSD_ERASED_MEM_CONT] == bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) && - (ext_csd[EXT_CSD_REV] == bw_ext_csd[EXT_CSD_REV]) && - (ext_csd[EXT_CSD_STRUCTURE] == bw_ext_csd[EXT_CSD_STRUCTURE]) && - (ext_csd[EXT_CSD_CARD_TYPE] == bw_ext_csd[EXT_CSD_CARD_TYPE]) && - (ext_csd[EXT_CSD_S_A_TIMEOUT] == bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) && - (ext_csd[EXT_CSD_HC_WP_GRP_SIZE] == bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) && - (ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT] == bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) && - (ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] == bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) && - (ext_csd[EXT_CSD_SEC_TRIM_MULT] == bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) && - (ext_csd[EXT_CSD_SEC_ERASE_MULT] == bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) && - (ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] == bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) && - (ext_csd[EXT_CSD_TRIM_MULT] == bw_ext_csd[EXT_CSD_TRIM_MULT]) && - (ext_csd[EXT_CSD_SEC_CNT + 0] == bw_ext_csd[EXT_CSD_SEC_CNT + 0]) && - (ext_csd[EXT_CSD_SEC_CNT + 1] == bw_ext_csd[EXT_CSD_SEC_CNT + 1]) && - (ext_csd[EXT_CSD_SEC_CNT + 2] == bw_ext_csd[EXT_CSD_SEC_CNT + 2]) && - (ext_csd[EXT_CSD_SEC_CNT + 3] == bw_ext_csd[EXT_CSD_SEC_CNT + 3]) && - (ext_csd[EXT_CSD_PWR_CL_52_195] == bw_ext_csd[EXT_CSD_PWR_CL_52_195]) && - (ext_csd[EXT_CSD_PWR_CL_26_195] == bw_ext_csd[EXT_CSD_PWR_CL_26_195]) && - (ext_csd[EXT_CSD_PWR_CL_52_360] == bw_ext_csd[EXT_CSD_PWR_CL_52_360]) && - (ext_csd[EXT_CSD_PWR_CL_26_360] == bw_ext_csd[EXT_CSD_PWR_CL_26_360]) && - (ext_csd[EXT_CSD_PWR_CL_200_195] == bw_ext_csd[EXT_CSD_PWR_CL_200_195]) && - (ext_csd[EXT_CSD_PWR_CL_200_360] == bw_ext_csd[EXT_CSD_PWR_CL_200_360]) && - (ext_csd[EXT_CSD_PWR_CL_DDR_52_195] == bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) && - (ext_csd[EXT_CSD_PWR_CL_DDR_52_360] == bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360]) && - (ext_csd[EXT_CSD_PWR_CL_DDR_200_360] == bw_ext_csd[EXT_CSD_PWR_CL_DDR_200_360])); - - if (err) - err = -RT_ERROR; - -out: - rt_free(bw_ext_csd); - return err; -} - -/* - * Select the bus width among 4-bit and 8-bit(SDR). - * If the bus width is changed successfully, return the selected width value. - * Zero is returned instead of error value if the wide width is not supported. - */ -static int mmc_select_bus_width(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd) -{ - rt_uint32_t ext_csd_bits[][2] = - { - {EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8}, - {EXT_CSD_BUS_WIDTH_4, EXT_CSD_DDR_BUS_WIDTH_4}, - {EXT_CSD_BUS_WIDTH_1, EXT_CSD_BUS_WIDTH_1}, - }; - rt_uint32_t bus_widths[] = - { - MMCSD_BUS_WIDTH_8, - MMCSD_BUS_WIDTH_4, - MMCSD_BUS_WIDTH_1 - }; - struct rt_mmcsd_host *host = card->host; - unsigned idx, bus_width = 0; - int err = 0, ddr = 0; - - if (GET_BITS(card->resp_csd, 122, 4) < 4) - return 0; - - if (card->flags & CARD_FLAG_HIGHSPEED_DDR) - { - ddr = 2; - } - /* - * Unlike SD, MMC cards don't have a configuration register to notify - * supported bus width. So bus test command should be run to identify - * the supported bus width or compare the EXT_CSD values of current - * bus width and EXT_CSD values of 1 bit mode read earlier. - */ - for (idx = 0; idx < sizeof(bus_widths) / sizeof(rt_uint32_t); idx++) - { - /* - * Determine BUS WIDTH mode according to the capability of host - */ - if (((ext_csd_bits[idx][0] == EXT_CSD_BUS_WIDTH_8) && ((host->flags & MMCSD_BUSWIDTH_8) == 0)) || - ((ext_csd_bits[idx][0] == EXT_CSD_BUS_WIDTH_4) && ((host->flags & MMCSD_BUSWIDTH_4) == 0))) - { - continue; - } - bus_width = bus_widths[idx]; - if (bus_width == MMCSD_BUS_WIDTH_1) - { - ddr = 0; - } - - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, - ext_csd_bits[idx][0]); - - if (err) - continue; - - mmcsd_set_bus_width(host, bus_width); - err = mmc_compare_ext_csds(card, ext_csd, bus_width); - if (!err) - { - break; - } - else - { - switch (ext_csd_bits[idx][0]) - { - case 0: - LOG_E("switch to bus width 1 bit failed!"); - break; - case 1: - LOG_E("switch to bus width 4 bit failed!"); - break; - case 2: - LOG_E("switch to bus width 8 bit failed!"); - break; - default: - break; - } - } - } - - if (!err && ddr) - { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, - ext_csd_bits[idx][1]); - } - - if (!err) - { - if (card->flags & (CARD_FLAG_HIGHSPEED | CARD_FLAG_HIGHSPEED_DDR)) - { - - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_HS_TIMING, - 1); - } - } - - return err; -} - -rt_err_t mmc_send_op_cond(struct rt_mmcsd_host *host, - rt_uint32_t ocr, rt_uint32_t *rocr) -{ - struct rt_mmcsd_cmd cmd; - rt_uint32_t i; - rt_err_t err = RT_EOK; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SEND_OP_COND; - cmd.arg = controller_is_spi(host) ? 0 : ocr; - cmd.flags = RESP_SPI_R1 | RESP_R3 | CMD_BCR; - - for (i = 100; i; i--) - { - err = mmcsd_send_cmd(host, &cmd, 3); - if (err) - break; - - /* if we're just probing, do a single pass */ - if (ocr == 0) - break; - - /* otherwise wait until reset completes */ - if (controller_is_spi(host)) - { - if (!(cmd.resp[0] & R1_SPI_IDLE)) - break; - } - else - { - if (cmd.resp[0] & CARD_BUSY) - break; - } - - err = -RT_ETIMEOUT; - - rt_thread_mdelay(10); //delay 10ms - } - - if (rocr && !controller_is_spi(host)) - *rocr = cmd.resp[0]; - - return err; -} - -static rt_err_t mmc_set_card_addr(struct rt_mmcsd_host *host, rt_uint32_t rca) -{ - rt_err_t err; - struct rt_mmcsd_cmd cmd; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SET_RELATIVE_ADDR; - cmd.arg = rca << 16; - cmd.flags = RESP_R1 | CMD_AC; - - err = mmcsd_send_cmd(host, &cmd, 3); - if (err) - return err; - - return 0; -} - -static int mmc_select_hs200(struct rt_mmcsd_card *card) -{ - int ret; - - ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS200); - if (ret) - return ret; - - mmcsd_set_timing(card->host, MMCSD_TIMING_MMC_HS200); - mmcsd_set_clock(card->host, card->max_data_rate); - - ret = mmcsd_excute_tuning(card); - - return ret; -} - -static int mmc_switch_to_hs400(struct rt_mmcsd_card *card) -{ - struct rt_mmcsd_host *host = card->host; - int err; - rt_uint8_t ext_csd_bus_width; - rt_uint32_t hs_timing; - - /* Switch to HS_TIMING to 0x01 (High Speed) */ - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS); - if (err != RT_EOK) - { - return err; - } - mmcsd_set_timing(card->host, MMCSD_TIMING_MMC_HS); - /* Host changes frequency to <= 52MHz */ - mmcsd_set_clock(card->host, 52000000); - - rt_bool_t support_enhanced_ds = ((card->ext_csd.enhanced_data_strobe != 0) && - ((host->flags & MMCSD_SUP_ENH_DS) != 0)); - - /* Set the bus width to: - * 0x86 if enhanced data strobe is supported, or - * 0x06 if enhanced data strobe is not supported - */ - ext_csd_bus_width = support_enhanced_ds ? - EXT_CSD_DDR_BUS_WIDTH_8_EH_DS : - EXT_CSD_DDR_BUS_WIDTH_8; - - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, - ext_csd_bus_width); - if (err != RT_EOK) - { - return err; - } - - /* Set HS_TIMING to 0x03 (HS400) */ - err = mmc_switch(card, - EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_HS_TIMING, - EXT_CSD_TIMING_HS400); - if (err != RT_EOK) - { - return err; - } - - /* Change the Host timing accordingly */ - hs_timing = support_enhanced_ds ? - MMCSD_TIMING_MMC_HS400_ENH_DS : - MMCSD_TIMING_MMC_HS400; - mmcsd_set_timing(host, hs_timing); - - /* Host may changes frequency to <= 200MHz */ - mmcsd_set_clock(card->host, card->max_data_rate); - - return RT_EOK; -} - -static int mmc_select_hs400(struct rt_mmcsd_card *card) -{ - int ret; - struct rt_mmcsd_host *host = card->host; - /* if the card or host doesn't support enhanced data strobe, switch to HS200 and perform tuning process first */ - if ((card->ext_csd.enhanced_data_strobe == 0) || ((host->flags & MMCSD_SUP_ENH_DS) == 0)) - { - ret = mmc_select_hs200(card); - if (ret != RT_EOK) - { - return ret; - } - } - return mmc_switch_to_hs400(card); -} - -static int mmc_select_timing(struct rt_mmcsd_card *card) -{ - int ret = 0; - - if (card->flags & CARD_FLAG_HS400) - { - LOG_I("emmc: switch to HS400 mode\n"); - ret = mmc_select_hs400(card); - } - else if (card->flags & CARD_FLAG_HS200) - { - LOG_I("emmc: switch to HS200 mode\n"); - ret = mmc_select_hs200(card); - } - else if (card->flags & CARD_FLAG_HIGHSPEED_DDR) - { - LOG_I("emmc: switch to HIGH Speed DDR mode\n"); - mmcsd_set_timing(card->host, MMCSD_TIMING_MMC_DDR52); - mmcsd_set_clock(card->host, card->hs_max_data_rate); - } - else - { - LOG_I("emmc: switch to HIGH Speed mode\n"); - mmcsd_set_timing(card->host, MMCSD_TIMING_MMC_HS); - mmcsd_set_clock(card->host, card->hs_max_data_rate); - } - - return ret; -} - -static rt_int32_t mmcsd_mmc_init_card(struct rt_mmcsd_host *host, - rt_uint32_t ocr) -{ - rt_int32_t err; - rt_uint32_t resp[4]; - rt_uint32_t rocr = 0; - rt_uint8_t *ext_csd = RT_NULL; - struct rt_mmcsd_card *card = RT_NULL; - - mmcsd_go_idle(host); - - /* The extra bit indicates that we support high capacity */ - err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr); - if (err) - goto err; - - if (controller_is_spi(host)) - { - err = mmcsd_spi_use_crc(host, 1); - if (err) - goto err1; - } - - if (controller_is_spi(host)) - err = mmcsd_get_cid(host, resp); - else - err = mmcsd_all_get_cid(host, resp); - if (err) - goto err; - - card = rt_malloc(sizeof(struct rt_mmcsd_card)); - if (!card) - { - LOG_E("malloc card failed!"); - err = -RT_ENOMEM; - goto err; - } - rt_memset(card, 0, sizeof(struct rt_mmcsd_card)); - - card->card_type = CARD_TYPE_MMC; - card->host = host; - card->rca = 1; - rt_memcpy(card->resp_cid, resp, sizeof(card->resp_cid)); - - /* - * For native busses: get card RCA and quit open drain mode. - */ - if (!controller_is_spi(host)) - { - err = mmc_set_card_addr(host, card->rca); - if (err) - goto err1; - - mmcsd_set_bus_mode(host, MMCSD_BUSMODE_PUSHPULL); - } - - err = mmcsd_get_csd(card, card->resp_csd); - if (err) - goto err1; - - err = mmcsd_parse_csd(card); - if (err) - goto err1; - - if (!controller_is_spi(host)) - { - err = mmcsd_select_card(card); - if (err) - goto err1; - } - - /* - * Fetch and process extended CSD. - */ - - err = mmc_get_ext_csd(card, &ext_csd); - if (err) - goto err1; - err = mmc_parse_ext_csd(card, ext_csd); - if (err) - goto err1; - - /* If doing byte addressing, check if required to do sector - * addressing. Handle the case of <2GB cards needing sector - * addressing. See section 8.1 JEDEC Standard JED84-A441; - * ocr register has bit 30 set for sector addressing. - */ - if (!(card->flags & CARD_FLAG_SDHC) && (rocr & (1 << 30))) - card->flags |= CARD_FLAG_SDHC; - - /*switch bus width and bus mode*/ - err = mmc_select_bus_width(card, ext_csd); - if (err) - { - LOG_E("mmc select buswidth fail"); - goto err0; - } - - err = mmc_select_timing(card); - if (err) - { - LOG_E("mmc select timing fail"); - goto err0; - } - - if (card->ext_csd.cache_size > 0) - { - mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_CACHE_CTRL, 1); - } - - host->card = card; - - rt_free(ext_csd); - return 0; - -err0: - rt_free(ext_csd); -err1: - rt_free(card); -err: - - return err; -} - -/* - * Starting point for mmc card init. - */ -rt_int32_t init_mmc(struct rt_mmcsd_host *host, rt_uint32_t ocr) -{ - rt_int32_t err; - rt_uint32_t current_ocr; - /* - * We need to get OCR a different way for SPI. - */ - if (controller_is_spi(host)) - { - err = mmcsd_spi_read_ocr(host, 0, &ocr); - if (err) - goto err; - } - - current_ocr = mmcsd_select_voltage(host, ocr); - - /* - * Can we support the voltage(s) of the card(s)? - */ - if (!current_ocr) - { - err = -RT_ERROR; - goto err; - } - - /* - * Detect and init the card. - */ - err = mmcsd_mmc_init_card(host, current_ocr); - if (err) - goto err; - - mmcsd_host_unlock(host); - - err = rt_mmcsd_blk_probe(host->card); - if (err) - goto remove_card; - mmcsd_host_lock(host); - - return 0; - -remove_card: - mmcsd_host_lock(host); - rt_mmcsd_blk_remove(host->card); - rt_free(host->card); - host->card = RT_NULL; -err: - - LOG_E("init MMC card failed!"); - - return err; -} diff --git a/rt-thread/components/drivers/sdio/dev_mmcsd_core.c b/rt-thread/components/drivers/sdio/dev_mmcsd_core.c deleted file mode 100644 index 33072c1..0000000 --- a/rt-thread/components/drivers/sdio/dev_mmcsd_core.c +++ /dev/null @@ -1,781 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-07-25 weety first version - */ - -#include -#include -#include -#include -#include -#include - -#define DBG_TAG "SDIO" -#ifdef RT_SDIO_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif /* RT_SDIO_DEBUG */ -#include - -#ifndef RT_MMCSD_STACK_SIZE -#define RT_MMCSD_STACK_SIZE 1024 -#endif -#ifndef RT_MMCSD_THREAD_PREORITY -#if (RT_THREAD_PRIORITY_MAX == 32) -#define RT_MMCSD_THREAD_PREORITY 0x16 -#else -#define RT_MMCSD_THREAD_PREORITY 0x40 -#endif -#endif - -//static struct rt_semaphore mmcsd_sem; -static struct rt_thread mmcsd_detect_thread; -static rt_uint8_t mmcsd_stack[RT_MMCSD_STACK_SIZE]; -static struct rt_mailbox mmcsd_detect_mb; -static rt_uint32_t mmcsd_detect_mb_pool[4]; -static struct rt_mailbox mmcsd_hotpluge_mb; -static rt_uint32_t mmcsd_hotpluge_mb_pool[4]; - -void mmcsd_host_lock(struct rt_mmcsd_host *host) -{ - rt_mutex_take(&host->bus_lock, RT_WAITING_FOREVER); -} - -void mmcsd_host_unlock(struct rt_mmcsd_host *host) -{ - rt_mutex_release(&host->bus_lock); -} - -void mmcsd_req_complete(struct rt_mmcsd_host *host) -{ - rt_sem_release(&host->sem_ack); -} - -void mmcsd_send_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req) -{ - do - { - req->cmd->retries--; - req->cmd->err = 0; - req->cmd->mrq = req; - if (req->data) - { - req->cmd->data = req->data; - req->data->err = 0; - req->data->mrq = req; - if (req->stop) - { - req->data->stop = req->stop; - req->stop->err = 0; - req->stop->mrq = req; - } - } - host->ops->request(host, req); - - rt_sem_take(&host->sem_ack, RT_WAITING_FOREVER); - - } - while (req->cmd->err && (req->cmd->retries > 0)); - - -} - -rt_int32_t mmcsd_send_cmd(struct rt_mmcsd_host *host, - struct rt_mmcsd_cmd *cmd, - int retries) -{ - struct rt_mmcsd_req req; - - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - rt_memset(cmd->resp, 0, sizeof(cmd->resp)); - cmd->retries = retries; - - req.cmd = cmd; - cmd->data = RT_NULL; - - mmcsd_send_request(host, &req); - - return cmd->err; -} - -rt_int32_t mmcsd_go_idle(struct rt_mmcsd_host *host) -{ - rt_int32_t err; - struct rt_mmcsd_cmd cmd; - - if (!controller_is_spi(host)) - { - mmcsd_set_chip_select(host, MMCSD_CS_HIGH); - rt_thread_mdelay(1); - } - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = GO_IDLE_STATE; - cmd.arg = 0; - cmd.flags = RESP_SPI_R1 | RESP_NONE | CMD_BC; - - err = mmcsd_send_cmd(host, &cmd, 0); - - rt_thread_mdelay(1); - - if (!controller_is_spi(host)) - { - mmcsd_set_chip_select(host, MMCSD_CS_IGNORE); - rt_thread_mdelay(1); - } - - return err; -} - -rt_int32_t mmcsd_spi_read_ocr(struct rt_mmcsd_host *host, - rt_int32_t high_capacity, - rt_uint32_t *ocr) -{ - struct rt_mmcsd_cmd cmd; - rt_int32_t err; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SPI_READ_OCR; - cmd.arg = high_capacity ? (1 << 30) : 0; - cmd.flags = RESP_SPI_R3; - - err = mmcsd_send_cmd(host, &cmd, 0); - - *ocr = cmd.resp[1]; - - return err; -} - -rt_int32_t mmcsd_all_get_cid(struct rt_mmcsd_host *host, rt_uint32_t *cid) -{ - rt_int32_t err; - struct rt_mmcsd_cmd cmd; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = ALL_SEND_CID; - cmd.arg = 0; - cmd.flags = RESP_R2 | CMD_BCR; - - err = mmcsd_send_cmd(host, &cmd, 3); - if (err) - return err; - - rt_memcpy(cid, cmd.resp, sizeof(rt_uint32_t) * 4); - - return 0; -} - -rt_int32_t mmcsd_get_cid(struct rt_mmcsd_host *host, rt_uint32_t *cid) -{ - rt_int32_t err, i; - struct rt_mmcsd_req req; - struct rt_mmcsd_cmd cmd; - struct rt_mmcsd_data data; - rt_uint32_t *buf = RT_NULL; - - if (!controller_is_spi(host)) - { - if (!host->card) - return -RT_ERROR; - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SEND_CID; - cmd.arg = host->card->rca << 16; - cmd.flags = RESP_R2 | CMD_AC; - err = mmcsd_send_cmd(host, &cmd, 3); - if (err) - return err; - - rt_memcpy(cid, cmd.resp, sizeof(rt_uint32_t) * 4); - - return 0; - } - - buf = (rt_uint32_t *)rt_malloc(16); - if (!buf) - { - LOG_E("allocate memory failed!"); - - return -RT_ENOMEM; - } - - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - rt_memset(&data, 0, sizeof(struct rt_mmcsd_data)); - - req.cmd = &cmd; - req.data = &data; - - cmd.cmd_code = SEND_CID; - cmd.arg = 0; - - /* NOTE HACK: the RESP_SPI_R1 is always correct here, but we - * rely on callers to never use this with "native" calls for reading - * CSD or CID. Native versions of those commands use the R2 type, - * not R1 plus a data block. - */ - cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC; - - data.blksize = 16; - data.blks = 1; - data.flags = DATA_DIR_READ; - data.buf = buf; - /* - * The spec states that CSR and CID accesses have a timeout - * of 64 clock cycles. - */ - data.timeout_ns = 0; - data.timeout_clks = 64; - - mmcsd_send_request(host, &req); - - if (cmd.err || data.err) - { - rt_free(buf); - - return -RT_ERROR; - } - - for (i = 0; i < 4; i++) - cid[i] = buf[i]; - rt_free(buf); - - return 0; -} - -rt_int32_t mmcsd_get_csd(struct rt_mmcsd_card *card, rt_uint32_t *csd) -{ - rt_int32_t err, i; - struct rt_mmcsd_req req; - struct rt_mmcsd_cmd cmd; - struct rt_mmcsd_data data; - rt_uint32_t *buf = RT_NULL; - - if (!controller_is_spi(card->host)) - { - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SEND_CSD; - cmd.arg = card->rca << 16; - cmd.flags = RESP_R2 | CMD_AC; - err = mmcsd_send_cmd(card->host, &cmd, 3); - if (err) - return err; - - rt_memcpy(csd, cmd.resp, sizeof(rt_uint32_t) * 4); - - return 0; - } - - buf = (rt_uint32_t *)rt_malloc(16); - if (!buf) - { - LOG_E("allocate memory failed!"); - - return -RT_ENOMEM; - } - - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - rt_memset(&data, 0, sizeof(struct rt_mmcsd_data)); - - req.cmd = &cmd; - req.data = &data; - - cmd.cmd_code = SEND_CSD; - cmd.arg = 0; - - /* NOTE HACK: the RESP_SPI_R1 is always correct here, but we - * rely on callers to never use this with "native" calls for reading - * CSD or CID. Native versions of those commands use the R2 type, - * not R1 plus a data block. - */ - cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC; - - data.blksize = 16; - data.blks = 1; - data.flags = DATA_DIR_READ; - data.buf = buf; - - /* - * The spec states that CSR and CID accesses have a timeout - * of 64 clock cycles. - */ - data.timeout_ns = 0; - data.timeout_clks = 64; - - mmcsd_send_request(card->host, &req); - - if (cmd.err || data.err) - { - rt_free(buf); - - return -RT_ERROR; - } - - for (i = 0; i < 4; i++) - csd[i] = buf[i]; - rt_free(buf); - - return 0; -} - -static rt_int32_t _mmcsd_select_card(struct rt_mmcsd_host *host, - struct rt_mmcsd_card *card) -{ - rt_int32_t err; - struct rt_mmcsd_cmd cmd; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SELECT_CARD; - - if (card) - { - cmd.arg = card->rca << 16; - cmd.flags = RESP_R1 | CMD_AC; - } - else - { - cmd.arg = 0; - cmd.flags = RESP_NONE | CMD_AC; - } - - err = mmcsd_send_cmd(host, &cmd, 3); - if (err) - return err; - - return 0; -} - -rt_int32_t mmcsd_select_card(struct rt_mmcsd_card *card) -{ - return _mmcsd_select_card(card->host, card); -} - -rt_int32_t mmcsd_deselect_cards(struct rt_mmcsd_card *card) -{ - return _mmcsd_select_card(card->host, RT_NULL); -} - -rt_int32_t mmcsd_spi_use_crc(struct rt_mmcsd_host *host, rt_int32_t use_crc) -{ - struct rt_mmcsd_cmd cmd; - rt_int32_t err; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SPI_CRC_ON_OFF; - cmd.flags = RESP_SPI_R1; - cmd.arg = use_crc; - - err = mmcsd_send_cmd(host, &cmd, 0); - if (!err) - host->spi_use_crc = use_crc; - - return err; -} - -rt_inline void mmcsd_set_iocfg(struct rt_mmcsd_host *host) -{ - struct rt_mmcsd_io_cfg *io_cfg = &host->io_cfg; - - mmcsd_dbg("clock %uHz busmode %u powermode %u cs %u Vdd %u " - "width %u \n", - io_cfg->clock, io_cfg->bus_mode, - io_cfg->power_mode, io_cfg->chip_select, io_cfg->vdd, - io_cfg->bus_width); - - host->ops->set_iocfg(host, io_cfg); -} - -/* - * Control chip select pin on a host. - */ -void mmcsd_set_chip_select(struct rt_mmcsd_host *host, rt_int32_t mode) -{ - host->io_cfg.chip_select = mode; - mmcsd_set_iocfg(host); -} - -/* - * Sets the host clock to the highest possible frequency that - * is below "hz". - */ -void mmcsd_set_clock(struct rt_mmcsd_host *host, rt_uint32_t clk) -{ - if (clk < host->freq_min) - { - LOG_W("clock too low!"); - } - - host->io_cfg.clock = clk; - mmcsd_set_iocfg(host); -} - -/* - * Change the bus mode (open drain/push-pull) of a host. - */ -void mmcsd_set_bus_mode(struct rt_mmcsd_host *host, rt_uint32_t mode) -{ - host->io_cfg.bus_mode = mode; - mmcsd_set_iocfg(host); -} - -/* - * Change data bus width of a host. - */ -void mmcsd_set_bus_width(struct rt_mmcsd_host *host, rt_uint32_t width) -{ - host->io_cfg.bus_width = width; - mmcsd_set_iocfg(host); -} - -void mmcsd_set_timing(struct rt_mmcsd_host *host, rt_uint32_t timing) -{ - host->io_cfg.timing = timing; - mmcsd_set_iocfg(host); -} - -void mmcsd_set_data_timeout(struct rt_mmcsd_data *data, - const struct rt_mmcsd_card *card) -{ - rt_uint32_t mult; - - if (card->card_type == CARD_TYPE_SDIO) - { - data->timeout_ns = 1000000000; /* SDIO card 1s */ - data->timeout_clks = 0; - - return; - } - - /* - * SD cards use a 100 multiplier rather than 10 - */ - mult = (card->card_type == CARD_TYPE_SD) ? 100 : 10; - - /* - * Scale up the multiplier (and therefore the timeout) by - * the r2w factor for writes. - */ - if (data->flags & DATA_DIR_WRITE) - mult <<= card->csd.r2w_factor; - - data->timeout_ns = card->tacc_ns * mult; - data->timeout_clks = card->tacc_clks * mult; - - /* - * SD cards also have an upper limit on the timeout. - */ - if (card->card_type == CARD_TYPE_SD) - { - rt_uint32_t timeout_us, limit_us; - - timeout_us = data->timeout_ns / 1000; - timeout_us += data->timeout_clks * 1000 / - (card->host->io_cfg.clock / 1000); - - if (data->flags & DATA_DIR_WRITE) - /* - * The limit is really 250 ms, but that is - * insufficient for some crappy cards. - */ - limit_us = 300000; - else - limit_us = 100000; - - /* - * SDHC cards always use these fixed values. - */ - if (timeout_us > limit_us || card->flags & CARD_FLAG_SDHC) - { - data->timeout_ns = limit_us * 1000; /* SDHC card fixed 250ms */ - data->timeout_clks = 0; - } - } - - if (controller_is_spi(card->host)) - { - if (data->flags & DATA_DIR_WRITE) - { - if (data->timeout_ns < 1000000000) - data->timeout_ns = 1000000000; /* 1s */ - } - else - { - if (data->timeout_ns < 100000000) - data->timeout_ns = 100000000; /* 100ms */ - } - } -} - -/* - * Mask off any voltages we don't support and select - * the lowest voltage - */ -rt_uint32_t mmcsd_select_voltage(struct rt_mmcsd_host *host, rt_uint32_t ocr) -{ - int bit; - extern int __rt_ffs(int value); - - ocr &= host->valid_ocr; - - bit = __rt_ffs(ocr); - if (bit) - { - bit -= 1; - - ocr &= 3 << bit; - - host->io_cfg.vdd = bit; - mmcsd_set_iocfg(host); - } - else - { - LOG_W("host doesn't support card's voltages!"); - ocr = 0; - } - - return ocr; -} - -static void mmcsd_power_up(struct rt_mmcsd_host *host) -{ - int bit = __rt_fls(host->valid_ocr) - 1; - - host->io_cfg.vdd = bit; - if (controller_is_spi(host)) - { - host->io_cfg.chip_select = MMCSD_CS_HIGH; - host->io_cfg.bus_mode = MMCSD_BUSMODE_PUSHPULL; - } - else - { - host->io_cfg.chip_select = MMCSD_CS_IGNORE; - host->io_cfg.bus_mode = MMCSD_BUSMODE_OPENDRAIN; - } - host->io_cfg.power_mode = MMCSD_POWER_UP; - host->io_cfg.bus_width = MMCSD_BUS_WIDTH_1; - mmcsd_set_iocfg(host); - - /* - * This delay should be sufficient to allow the power supply - * to reach the minimum voltage. - */ - rt_thread_mdelay(10); - - host->io_cfg.clock = host->freq_min; - host->io_cfg.power_mode = MMCSD_POWER_ON; - mmcsd_set_iocfg(host); - - /* - * This delay must be at least 74 clock sizes, or 1 ms, or the - * time required to reach a stable voltage. - */ - rt_thread_mdelay(10); -} - -static void mmcsd_power_off(struct rt_mmcsd_host *host) -{ - host->io_cfg.clock = 0; - host->io_cfg.vdd = 0; - if (!controller_is_spi(host)) - { - host->io_cfg.bus_mode = MMCSD_BUSMODE_OPENDRAIN; - host->io_cfg.chip_select = MMCSD_CS_IGNORE; - } - host->io_cfg.power_mode = MMCSD_POWER_OFF; - host->io_cfg.bus_width = MMCSD_BUS_WIDTH_1; - mmcsd_set_iocfg(host); -} - -int mmcsd_wait_cd_changed(rt_int32_t timeout) -{ - struct rt_mmcsd_host *host; - if (rt_mb_recv(&mmcsd_hotpluge_mb, (rt_ubase_t *)&host, timeout) == RT_EOK) - { - if (host->card == RT_NULL) - { - return MMCSD_HOST_UNPLUGED; - } - else - { - return MMCSD_HOST_PLUGED; - } - } - return -RT_ETIMEOUT; -} -RTM_EXPORT(mmcsd_wait_cd_changed); - -void mmcsd_change(struct rt_mmcsd_host *host) -{ - rt_mb_send(&mmcsd_detect_mb, (rt_ubase_t)host); -} - -void mmcsd_detect(void *param) -{ - struct rt_mmcsd_host *host; - rt_uint32_t ocr; - rt_int32_t err; - - while (1) - { - if (rt_mb_recv(&mmcsd_detect_mb, (rt_ubase_t *)&host, RT_WAITING_FOREVER) == RT_EOK) - { - if (host->card == RT_NULL) - { - mmcsd_host_lock(host); - mmcsd_power_up(host); - mmcsd_go_idle(host); - - mmcsd_send_if_cond(host, host->valid_ocr); - - err = sdio_io_send_op_cond(host, 0, &ocr); - if (!err) - { - if (init_sdio(host, ocr)) - mmcsd_power_off(host); - mmcsd_host_unlock(host); - continue; - } - - /* - * detect SD card - */ - err = mmcsd_send_app_op_cond(host, 0, &ocr); - if (!err) - { - if (init_sd(host, ocr)) - mmcsd_power_off(host); - mmcsd_host_unlock(host); - rt_mb_send(&mmcsd_hotpluge_mb, (rt_ubase_t)host); - continue; - } - - /* - * detect mmc card - */ - err = mmc_send_op_cond(host, 0, &ocr); - if (!err) - { - if (init_mmc(host, ocr)) - mmcsd_power_off(host); - mmcsd_host_unlock(host); - rt_mb_send(&mmcsd_hotpluge_mb, (rt_ubase_t)host); - continue; - } - mmcsd_host_unlock(host); - } - else - { - /* card removed */ - mmcsd_host_lock(host); - if (host->card->sdio_function_num != 0) - { - LOG_W("unsupport sdio card plug out!"); - } - else - { - rt_mmcsd_blk_remove(host->card); - rt_free(host->card); - - host->card = RT_NULL; - } - mmcsd_host_unlock(host); - rt_mb_send(&mmcsd_hotpluge_mb, (rt_ubase_t)host); - } - } - } -} - -void mmcsd_host_init(struct rt_mmcsd_host *host) -{ - rt_memset(host, 0, sizeof(struct rt_mmcsd_host)); - strncpy(host->name, "sd", sizeof(host->name) - 1); - host->max_seg_size = 65535; - host->max_dma_segs = 1; - host->max_blk_size = 512; - host->max_blk_count = 4096; - - rt_mutex_init(&host->bus_lock, "sd_bus_lock", RT_IPC_FLAG_FIFO); - rt_sem_init(&host->sem_ack, "sd_ack", 0, RT_IPC_FLAG_FIFO); -} - -struct rt_mmcsd_host *mmcsd_alloc_host(void) -{ - struct rt_mmcsd_host *host; - - host = rt_malloc(sizeof(struct rt_mmcsd_host)); - if (!host) - { - LOG_E("alloc host failed"); - - return RT_NULL; - } - - mmcsd_host_init(host); - - return host; -} - -void mmcsd_free_host(struct rt_mmcsd_host *host) -{ - rt_mutex_detach(&host->bus_lock); - rt_sem_detach(&host->sem_ack); - rt_free(host); -} - -rt_int32_t mmcsd_excute_tuning(struct rt_mmcsd_card *card) -{ - struct rt_mmcsd_host *host = card->host; - rt_int32_t opcode; - - if (!host->ops->execute_tuning) - return RT_EOK; - - if (card->card_type == CARD_TYPE_MMC) - opcode = SEND_TUNING_BLOCK_HS200; - else - opcode = SEND_TUNING_BLOCK; - - return host->ops->execute_tuning(host, opcode);; -} - -int rt_mmcsd_core_init(void) -{ - rt_err_t ret; - - /* initialize detect SD cart thread */ - /* initialize mailbox and create detect SD card thread */ - ret = rt_mb_init(&mmcsd_detect_mb, "mmcsdmb", - &mmcsd_detect_mb_pool[0], sizeof(mmcsd_detect_mb_pool) / sizeof(mmcsd_detect_mb_pool[0]), - RT_IPC_FLAG_FIFO); - RT_ASSERT(ret == RT_EOK); - - ret = rt_mb_init(&mmcsd_hotpluge_mb, "mmcsdhotplugmb", - &mmcsd_hotpluge_mb_pool[0], sizeof(mmcsd_hotpluge_mb_pool) / sizeof(mmcsd_hotpluge_mb_pool[0]), - RT_IPC_FLAG_FIFO); - RT_ASSERT(ret == RT_EOK); - ret = rt_thread_init(&mmcsd_detect_thread, "mmcsd_detect", mmcsd_detect, RT_NULL, - &mmcsd_stack[0], RT_MMCSD_STACK_SIZE, RT_MMCSD_THREAD_PREORITY, 20); - if (ret == RT_EOK) - { - rt_thread_startup(&mmcsd_detect_thread); - } - - rt_sdio_init(); - - return 0; -} -INIT_PREV_EXPORT(rt_mmcsd_core_init); - diff --git a/rt-thread/components/drivers/sdio/dev_sd.c b/rt-thread/components/drivers/sdio/dev_sd.c deleted file mode 100644 index 22725db..0000000 --- a/rt-thread/components/drivers/sdio/dev_sd.c +++ /dev/null @@ -1,869 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-07-25 weety first version - * 2024-05-26 HPMicro add UHS-I support - */ - -#include -#include - -#define DBG_TAG "SDIO" -#ifdef RT_SDIO_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif /* RT_SDIO_DEBUG */ -#include - -static const rt_uint32_t tran_unit[] = -{ - 10000, 100000, 1000000, 10000000, - 0, 0, 0, 0 -}; - -static const rt_uint8_t tran_value[] = -{ - 0, 10, 12, 13, 15, 20, 25, 30, - 35, 40, 45, 50, 55, 60, 70, 80, -}; - -static const rt_uint32_t tacc_uint[] = -{ - 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, -}; - -static const rt_uint8_t tacc_value[] = -{ - 0, 10, 12, 13, 15, 20, 25, 30, - 35, 40, 45, 50, 55, 60, 70, 80, -}; - -rt_inline rt_uint32_t GET_BITS(rt_uint32_t *resp, - rt_uint32_t start, - rt_uint32_t size) -{ - const rt_int32_t __size = size; - const rt_uint32_t __mask = (__size < 32 ? 1 << __size : 0) - 1; - const rt_int32_t __off = 3 - ((start) / 32); - const rt_int32_t __shft = (start) & 31; - rt_uint32_t __res; - - __res = resp[__off] >> __shft; - if (__size + __shft > 32) - __res |= resp[__off-1] << ((32 - __shft) % 32); - - return __res & __mask; -} - -static rt_int32_t mmcsd_parse_csd(struct rt_mmcsd_card *card) -{ - struct rt_mmcsd_csd *csd = &card->csd; - rt_uint32_t *resp = card->resp_csd; - - csd->csd_structure = GET_BITS(resp, 126, 2); - - switch (csd->csd_structure) - { - case 0: - csd->taac = GET_BITS(resp, 112, 8); - csd->nsac = GET_BITS(resp, 104, 8); - csd->tran_speed = GET_BITS(resp, 96, 8); - csd->card_cmd_class = GET_BITS(resp, 84, 12); - csd->rd_blk_len = GET_BITS(resp, 80, 4); - csd->rd_blk_part = GET_BITS(resp, 79, 1); - csd->wr_blk_misalign = GET_BITS(resp, 78, 1); - csd->rd_blk_misalign = GET_BITS(resp, 77, 1); - csd->dsr_imp = GET_BITS(resp, 76, 1); - csd->c_size = GET_BITS(resp, 62, 12); - csd->c_size_mult = GET_BITS(resp, 47, 3); - csd->r2w_factor = GET_BITS(resp, 26, 3); - csd->wr_blk_len = GET_BITS(resp, 22, 4); - csd->wr_blk_partial = GET_BITS(resp, 21, 1); - csd->csd_crc = GET_BITS(resp, 1, 7); - - card->card_blksize = 1 << csd->rd_blk_len; - card->card_capacity = (csd->c_size + 1) << (csd->c_size_mult + 2); - card->card_capacity *= card->card_blksize; - card->card_capacity >>= 10; /* unit:KB */ - card->tacc_clks = csd->nsac * 100; - card->tacc_ns = (tacc_uint[csd->taac&0x07] * tacc_value[(csd->taac&0x78)>>3] + 9) / 10; - card->max_data_rate = tran_unit[csd->tran_speed&0x07] * tran_value[(csd->tran_speed&0x78)>>3]; - - break; - case 1: - card->flags |= CARD_FLAG_SDHC; - - /*This field is fixed to 0Eh, which indicates 1 ms. - The host should not use TAAC, NSAC, and R2W_FACTOR - to calculate timeout and should uses fixed timeout - values for read and write operations*/ - csd->taac = GET_BITS(resp, 112, 8); - csd->nsac = GET_BITS(resp, 104, 8); - csd->tran_speed = GET_BITS(resp, 96, 8); - csd->card_cmd_class = GET_BITS(resp, 84, 12); - csd->rd_blk_len = GET_BITS(resp, 80, 4); - csd->rd_blk_part = GET_BITS(resp, 79, 1); - csd->wr_blk_misalign = GET_BITS(resp, 78, 1); - csd->rd_blk_misalign = GET_BITS(resp, 77, 1); - csd->dsr_imp = GET_BITS(resp, 76, 1); - csd->c_size = GET_BITS(resp, 48, 22); - - csd->r2w_factor = GET_BITS(resp, 26, 3); - csd->wr_blk_len = GET_BITS(resp, 22, 4); - csd->wr_blk_partial = GET_BITS(resp, 21, 1); - csd->csd_crc = GET_BITS(resp, 1, 7); - - card->card_blksize = 512; - card->card_capacity = (csd->c_size + 1) * 512; /* unit:KB */ - card->card_sec_cnt = card->card_capacity * 2; - card->tacc_clks = 0; - card->tacc_ns = 0; - card->max_data_rate = tran_unit[csd->tran_speed&0x07] * tran_value[(csd->tran_speed&0x78)>>3]; - - break; - default: - LOG_E("unrecognised CSD structure version %d!", csd->csd_structure); - - return -RT_ERROR; - } - LOG_I("SD card capacity %d KB.", card->card_capacity); - - return 0; -} - -static rt_int32_t mmcsd_parse_scr(struct rt_mmcsd_card *card) -{ - struct rt_sd_scr *scr = &card->scr; - rt_uint32_t resp[4]; - - resp[3] = card->resp_scr[1]; - resp[2] = card->resp_scr[0]; - scr->sd_version = GET_BITS(resp, 56, 4); - scr->sd_bus_widths = GET_BITS(resp, 48, 4); - - return 0; -} - -static rt_int32_t mmcsd_switch(struct rt_mmcsd_card *card) -{ - rt_int32_t err; - struct rt_mmcsd_host *host = card->host; - struct rt_mmcsd_req req; - struct rt_mmcsd_cmd cmd; - struct rt_mmcsd_data data; - rt_uint8_t *buf; - - buf = (rt_uint8_t*)rt_malloc(64); - if (!buf) - { - LOG_E("alloc memory failed!"); - - return -RT_ENOMEM; - } - - if (card->card_type != CARD_TYPE_SD) - goto err; - if (card->scr.sd_version < SCR_SPEC_VER_1) - goto err; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SD_SWITCH; - cmd.arg = 0x00FFFFF1; - cmd.flags = RESP_R1 | CMD_ADTC; - - rt_memset(&data, 0, sizeof(struct rt_mmcsd_data)); - - mmcsd_set_data_timeout(&data, card); - - data.blksize = 64; - data.blks = 1; - data.flags = DATA_DIR_READ; - data.buf = (rt_uint32_t *)buf; - - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - - req.cmd = &cmd; - req.data = &data; - - mmcsd_send_request(host, &req); - - if (cmd.err || data.err) - { - goto err1; - } - - if (buf[13] & 0x02) - card->hs_max_data_rate = 50000000; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SD_SWITCH; - - rt_uint32_t switch_func_timing; - if ((card->flags & CARD_FLAG_SDR104) && (card->host->flags & MMCSD_SUP_SDR104)) - { - switch_func_timing = SD_SWITCH_FUNC_TIMING_SDR104; - } - else if ((card->flags & CARD_FLAG_SDR50) && (card->host->flags & MMCSD_SUP_SDR50)) - { - switch_func_timing = SD_SWITCH_FUNC_TIMING_SDR50; - } - else if ((card->flags & CARD_FLAG_DDR50) && (card->host->flags & MMCSD_SUP_DDR50)) - { - switch_func_timing = SD_SWITCH_FUNC_TIMING_DDR50; - } - else - { - switch_func_timing = SD_SWITCH_FUNC_TIMING_HS; - } - cmd.arg = 0x80FFFFF0 | switch_func_timing; - cmd.flags = RESP_R1 | CMD_ADTC; - - rt_memset(&data, 0, sizeof(struct rt_mmcsd_data)); - - mmcsd_set_data_timeout(&data, card); - - data.blksize = 64; - data.blks = 1; - data.flags = DATA_DIR_READ; - data.buf = (rt_uint32_t *)buf; - - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - - req.cmd = &cmd; - req.data = &data; - - mmcsd_send_request(host, &req); - - if (cmd.err || data.err) - { - goto err1; - } - - if ((buf[16] & 0xF) != switch_func_timing) - { - LOG_E("switching card to timing mode %d failed!", switch_func_timing); - goto err; - } - - switch(switch_func_timing) - { - case SD_SWITCH_FUNC_TIMING_SDR104: - card->flags |= CARD_FLAG_SDR104; - break; - case SD_SWITCH_FUNC_TIMING_SDR50: - card->flags |= CARD_FLAG_SDR50; - break; - case SD_SWITCH_FUNC_TIMING_DDR50: - card->flags |= CARD_FLAG_DDR50; - break; - case SD_SWITCH_FUNC_TIMING_HS: - card->flags |= CARD_FLAG_HIGHSPEED; - break; - default: - /* Default speed */ - break; - } - - card->max_data_rate = 50000000; - if (switch_func_timing == SD_SWITCH_FUNC_TIMING_SDR104) - { - LOG_I("sd: switch to SDR104 mode\n"); - mmcsd_set_timing(card->host, MMCSD_TIMING_UHS_SDR104); - mmcsd_set_clock(card->host, 208000000); - err = mmcsd_excute_tuning(card); - card->max_data_rate = 208000000; - } - else if (switch_func_timing == SD_SWITCH_FUNC_TIMING_SDR50) - { - LOG_I("sd: switch to SDR50 mode\n"); - mmcsd_set_timing(card->host, MMCSD_TIMING_UHS_SDR50); - mmcsd_set_clock(card->host, 100000000); - err = mmcsd_excute_tuning(card); - card->max_data_rate = 10000000; - } - else if (switch_func_timing == SD_SWITCH_FUNC_TIMING_DDR50) - { - LOG_I("sd: switch to DDR50 mode\n"); - mmcsd_set_timing(card->host, MMCSD_TIMING_UHS_DDR50); - mmcsd_set_clock(card->host, 50000000); - } - else - { - LOG_I("sd: switch to High Speed / SDR25 mode \n"); - mmcsd_set_timing(card->host, MMCSD_TIMING_SD_HS); - mmcsd_set_clock(card->host, 50000000); - } - -err: - rt_free(buf); - return 0; - -err1: - if (cmd.err) - err = cmd.err; - if (data.err) - err = data.err; - - return err; -} - -static rt_err_t mmcsd_app_cmd(struct rt_mmcsd_host *host, - struct rt_mmcsd_card *card) -{ - rt_err_t err; - struct rt_mmcsd_cmd cmd = {0}; - - cmd.cmd_code = APP_CMD; - - if (card) - { - cmd.arg = card->rca << 16; - cmd.flags = RESP_R1 | CMD_AC; - } - else - { - cmd.arg = 0; - cmd.flags = RESP_R1 | CMD_BCR; - } - - err = mmcsd_send_cmd(host, &cmd, 0); - if (err) - return err; - - /* Check that card supported application commands */ - if (!controller_is_spi(host) && !(cmd.resp[0] & R1_APP_CMD)) - return -RT_ERROR; - - return RT_EOK; -} - - -rt_err_t mmcsd_send_app_cmd(struct rt_mmcsd_host *host, - struct rt_mmcsd_card *card, - struct rt_mmcsd_cmd *cmd, - int retry) -{ - struct rt_mmcsd_req req; - int i; - rt_err_t err; - - err = -RT_ERROR; - - /* - * We have to resend MMC_APP_CMD for each attempt so - * we cannot use the retries field in mmc_command. - */ - for (i = 0; i <= retry; i++) - { - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - - err = mmcsd_app_cmd(host, card); - if (err) - { - /* no point in retrying; no APP commands allowed */ - if (controller_is_spi(host)) - { - if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND) - break; - } - continue; - } - - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - - rt_memset(cmd->resp, 0, sizeof(cmd->resp)); - - req.cmd = cmd; - //cmd->data = NULL; - - mmcsd_send_request(host, &req); - - err = cmd->err; - if (!cmd->err) - break; - - /* no point in retrying illegal APP commands */ - if (controller_is_spi(host)) - { - if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND) - break; - } - } - - return err; -} - -rt_err_t mmcsd_app_set_bus_width(struct rt_mmcsd_card *card, rt_int32_t width) -{ - rt_err_t err; - struct rt_mmcsd_cmd cmd; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SD_APP_SET_BUS_WIDTH; - cmd.flags = RESP_R1 | CMD_AC; - - switch (width) - { - case MMCSD_BUS_WIDTH_1: - cmd.arg = MMCSD_BUS_WIDTH_1; - break; - case MMCSD_BUS_WIDTH_4: - cmd.arg = MMCSD_BUS_WIDTH_4; - break; - default: - return -RT_ERROR; - } - - err = mmcsd_send_app_cmd(card->host, card, &cmd, 3); - if (err) - return err; - - return RT_EOK; -} - -rt_err_t mmcsd_send_app_op_cond(struct rt_mmcsd_host *host, - rt_uint32_t ocr, - rt_uint32_t *rocr) -{ - struct rt_mmcsd_cmd cmd; - rt_uint32_t i; - rt_err_t err = RT_EOK; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SD_APP_OP_COND; - if (controller_is_spi(host)) - cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */ - else - cmd.arg = ocr; - cmd.flags = RESP_SPI_R1 | RESP_R3 | CMD_BCR; - - for (i = 1000; i; i--) - { - err = mmcsd_send_app_cmd(host, RT_NULL, &cmd, 3); - if (err) - break; - - /* if we're just probing, do a single pass */ - if (ocr == 0) - break; - - /* otherwise wait until reset completes */ - if (controller_is_spi(host)) - { - if (!(cmd.resp[0] & R1_SPI_IDLE)) - break; - } - else - { - if (cmd.resp[0] & CARD_BUSY) - break; - } - - err = -RT_ETIMEOUT; - - rt_thread_mdelay(10); //delay 10ms - } - - if (rocr && !controller_is_spi(host)) - *rocr = cmd.resp[0]; - - return err; -} - -/* - * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND - * before SD_APP_OP_COND. This command will harmlessly fail for - * SD 1.0 cards. - */ -rt_err_t mmcsd_send_if_cond(struct rt_mmcsd_host *host, rt_uint32_t ocr) -{ - struct rt_mmcsd_cmd cmd; - rt_err_t err; - rt_uint8_t pattern; - - cmd.cmd_code = SD_SEND_IF_COND; - cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | 0xAA; - cmd.flags = RESP_SPI_R7 | RESP_R7 | CMD_BCR; - - err = mmcsd_send_cmd(host, &cmd, 0); - if (err) - return err; - - if (controller_is_spi(host)) - pattern = cmd.resp[1] & 0xFF; - else - pattern = cmd.resp[0] & 0xFF; - - if (pattern != 0xAA) - return -RT_ERROR; - - return RT_EOK; -} - -rt_err_t mmcsd_get_card_addr(struct rt_mmcsd_host *host, rt_uint32_t *rca) -{ - rt_err_t err; - struct rt_mmcsd_cmd cmd; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SD_SEND_RELATIVE_ADDR; - cmd.arg = 0; - cmd.flags = RESP_R6 | CMD_BCR; - - err = mmcsd_send_cmd(host, &cmd, 3); - if (err) - return err; - - *rca = cmd.resp[0] >> 16; - - return RT_EOK; -} - -#define be32_to_cpu(x) ((rt_uint32_t)( \ - (((rt_uint32_t)(x) & (rt_uint32_t)0x000000ffUL) << 24) | \ - (((rt_uint32_t)(x) & (rt_uint32_t)0x0000ff00UL) << 8) | \ - (((rt_uint32_t)(x) & (rt_uint32_t)0x00ff0000UL) >> 8) | \ - (((rt_uint32_t)(x) & (rt_uint32_t)0xff000000UL) >> 24))) - -rt_int32_t mmcsd_get_scr(struct rt_mmcsd_card *card, rt_uint32_t *scr) -{ - rt_int32_t err; - struct rt_mmcsd_req req; - struct rt_mmcsd_cmd cmd; - struct rt_mmcsd_data data; - - err = mmcsd_app_cmd(card->host, card); - if (err) - return err; - - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - rt_memset(&data, 0, sizeof(struct rt_mmcsd_data)); - - req.cmd = &cmd; - req.data = &data; - - cmd.cmd_code = SD_APP_SEND_SCR; - cmd.arg = 0; - cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC; - - data.blksize = 8; - data.blks = 1; - data.flags = DATA_DIR_READ; - data.buf = scr; - - mmcsd_set_data_timeout(&data, card); - - mmcsd_send_request(card->host, &req); - - if (cmd.err) - return cmd.err; - if (data.err) - return data.err; - - scr[0] = be32_to_cpu(scr[0]); - scr[1] = be32_to_cpu(scr[1]); - - return 0; -} - -static rt_err_t mmcsd_read_sd_status(struct rt_mmcsd_card *card, rt_uint32_t *sd_status) -{ - rt_int32_t err; - struct rt_mmcsd_req req; - struct rt_mmcsd_cmd cmd; - struct rt_mmcsd_data data; - - err = mmcsd_app_cmd(card->host, card); - if (err) - return err; - - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - rt_memset(&data, 0, sizeof(struct rt_mmcsd_data)); - - req.cmd = &cmd; - req.data = &data; - - cmd.cmd_code = SEND_STATUS; - cmd.arg = 0; - cmd.flags = RESP_SPI_R1 | RESP_R1 | CMD_ADTC; - - data.blksize = 64; - data.blks = 1; - data.flags = DATA_DIR_READ; - data.buf = sd_status; - - mmcsd_set_data_timeout(&data, card); - - mmcsd_send_request(card->host, &req); - - if (cmd.err) - return cmd.err; - if (data.err) - return data.err; - - /* Convert endian */ - for (uint32_t i=0; i < 8; i++) - { - uint32_t tmp = sd_status[i]; - sd_status[i] = sd_status[15 - i]; - sd_status[15 - i] = tmp; - } - for (uint32_t i=0; i < 16; i++) - { - sd_status[i] = be32_to_cpu(sd_status[i]); - } - - - return 0; -} - -static rt_err_t sd_switch_voltage(struct rt_mmcsd_host *host) -{ - rt_err_t err; - struct rt_mmcsd_cmd cmd = { 0 }; - - cmd.cmd_code = VOLTAGE_SWITCH; - cmd.arg = 0; - cmd.flags = RESP_R1 | CMD_AC; - - err = mmcsd_send_cmd(host, &cmd, 0); - if (err) - return err; - - return RT_EOK; -} - -static rt_err_t sd_switch_uhs_voltage(struct rt_mmcsd_host *host) -{ - if (host->ops->switch_uhs_voltage != RT_NULL) - { - return host->ops->switch_uhs_voltage(host); - } - return -ENOSYS; -} - -static rt_int32_t mmcsd_sd_init_card(struct rt_mmcsd_host *host, - rt_uint32_t ocr) -{ - struct rt_mmcsd_card *card; - rt_int32_t err; - rt_uint32_t resp[4]; - rt_uint32_t max_data_rate; - - mmcsd_go_idle(host); - - /* - * If SD_SEND_IF_COND indicates an SD 2.0 - * compliant card and we should set bit 30 - * of the ocr to indicate that we can handle - * block-addressed SDHC cards. - */ - err = mmcsd_send_if_cond(host, ocr); - if (!err) - ocr |= 1 << 30; - - /* Switch to UHS voltage if both Host and the Card support this feature */ - if (((host->valid_ocr & VDD_165_195) != 0) && (host->ops->switch_uhs_voltage != RT_NULL)) - { - ocr |= OCR_S18R; - } - err = mmcsd_send_app_op_cond(host, ocr, &ocr); - if (err) - goto err2; - - /* Select voltage */ - if (ocr & OCR_S18R) - { - ocr = VDD_165_195; - err = sd_switch_voltage(host); - if (err) - goto err2; - err = sd_switch_uhs_voltage(host); - if (err) - goto err2; - } - - if (controller_is_spi(host)) - err = mmcsd_get_cid(host, resp); - else - err = mmcsd_all_get_cid(host, resp); - if (err) - goto err2; - - card = rt_malloc(sizeof(struct rt_mmcsd_card)); - if (!card) - { - LOG_E("malloc card failed!"); - err = -RT_ENOMEM; - goto err2; - } - rt_memset(card, 0, sizeof(struct rt_mmcsd_card)); - - card->card_type = CARD_TYPE_SD; - card->host = host; - rt_memcpy(card->resp_cid, resp, sizeof(card->resp_cid)); - - /* - * For native busses: get card RCA and quit open drain mode. - */ - if (!controller_is_spi(host)) - { - err = mmcsd_get_card_addr(host, &card->rca); - if (err) - goto err1; - - mmcsd_set_bus_mode(host, MMCSD_BUSMODE_PUSHPULL); - } - - err = mmcsd_get_csd(card, card->resp_csd); - if (err) - goto err1; - - err = mmcsd_parse_csd(card); - if (err) - goto err1; - - if (!controller_is_spi(host)) - { - err = mmcsd_select_card(card); - if (err) - goto err1; - } - - err = mmcsd_get_scr(card, card->resp_scr); - if (err) - goto err1; - - mmcsd_parse_scr(card); - - if (controller_is_spi(host)) - { - err = mmcsd_spi_use_crc(host, 1); - if (err) - goto err1; - } - - mmcsd_set_timing(host, MMCSD_TIMING_LEGACY); - mmcsd_set_clock(host, 25000000); - /*switch bus width*/ - if ((host->flags & MMCSD_BUSWIDTH_4) && (card->scr.sd_bus_widths & SD_SCR_BUS_WIDTH_4)) - { - err = mmcsd_app_set_bus_width(card, MMCSD_BUS_WIDTH_4); - if (err) - goto err1; - - mmcsd_set_bus_width(host, MMCSD_BUS_WIDTH_4); - } - - /* Read and decode SD Status and check whether UHS mode is supported */ - union rt_sd_status sd_status; - err = mmcsd_read_sd_status(card, sd_status.status_words); - if (err) - goto err1; - if ((sd_status.uhs_speed_grade > 0) && (ocr & VDD_165_195)) - { - /* Assume the card supports all UHS-I modes because we cannot find any mainstreaming card - * that can support only part of the following modes. - */ - card->flags |= CARD_FLAG_SDR50 | CARD_FLAG_SDR104 | CARD_FLAG_DDR50; - } - - /* - * change SD card to the highest supported speed - */ - err = mmcsd_switch(card); - if (err) - goto err1; - - /* set bus speed */ - max_data_rate = 0U; - if (max_data_rate < card->hs_max_data_rate) - { - max_data_rate = card->hs_max_data_rate; - } - if (max_data_rate < card->max_data_rate) - { - max_data_rate = card->max_data_rate; - } - - mmcsd_set_clock(host, max_data_rate); - host->card = card; - - return 0; - -err1: - rt_free(card); -err2: - - return err; -} - -/* - * Starting point for SD card init. - */ -rt_int32_t init_sd(struct rt_mmcsd_host *host, rt_uint32_t ocr) -{ - rt_int32_t err = -RT_EINVAL; - rt_uint32_t current_ocr; - /* - * We need to get OCR a different way for SPI. - */ - if (controller_is_spi(host)) - { - mmcsd_go_idle(host); - - err = mmcsd_spi_read_ocr(host, 0, &ocr); - if (err) - goto _err; - } - - current_ocr = mmcsd_select_voltage(host, ocr); - - /* - * Can we support the voltage(s) of the card(s)? - */ - if (!current_ocr) - { - err = -RT_ERROR; - goto _err; - } - - /* - * Detect and init the card. - */ - err = mmcsd_sd_init_card(host, current_ocr); - if (err) - goto _err; - - mmcsd_host_unlock(host); - - err = rt_mmcsd_blk_probe(host->card); - if (err) - goto remove_card; - mmcsd_host_lock(host); - - return 0; - -remove_card: - mmcsd_host_lock(host); - rt_mmcsd_blk_remove(host->card); - rt_free(host->card); - host->card = RT_NULL; -_err: - - LOG_D("init SD card failed!"); - - return err; -} diff --git a/rt-thread/components/drivers/sdio/dev_sdio.c b/rt-thread/components/drivers/sdio/dev_sdio.c deleted file mode 100644 index 013753a..0000000 --- a/rt-thread/components/drivers/sdio/dev_sdio.c +++ /dev/null @@ -1,1411 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-01-13 weety first version - * 2024-07-04 Evlers fix an issue where repeated remove of card resulted in assertions - * 2024-07-05 Evlers fix a bug that read members in non-existent functions - */ - -#include -#include -#include - -#define DBG_TAG "SDIO" -#ifdef RT_SDIO_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif /* RT_SDIO_DEBUG */ -#include - -#ifndef RT_SDIO_STACK_SIZE -#define RT_SDIO_STACK_SIZE 512 -#endif -#ifndef RT_SDIO_THREAD_PRIORITY -#define RT_SDIO_THREAD_PRIORITY 0x40 -#endif - -static rt_list_t sdio_cards = RT_LIST_OBJECT_INIT(sdio_cards); -static rt_list_t sdio_drivers = RT_LIST_OBJECT_INIT(sdio_drivers); - -struct sdio_card -{ - struct rt_mmcsd_card *card; - rt_list_t list; -}; - -struct sdio_driver -{ - struct rt_sdio_driver *drv; - rt_list_t list; -}; - -#define MIN(a, b) (a < b ? a : b) - -static const rt_uint8_t speed_value[16] = -{ - 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 -}; - -static const rt_uint32_t speed_unit[8] = -{ - 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 -}; - -rt_inline rt_int32_t sdio_match_card(struct rt_mmcsd_card *card, - const struct rt_sdio_device_id *id); - - -rt_int32_t sdio_io_send_op_cond(struct rt_mmcsd_host *host, - rt_uint32_t ocr, - rt_uint32_t *cmd5_resp) -{ - struct rt_mmcsd_cmd cmd; - rt_int32_t i, err = 0; - - RT_ASSERT(host != RT_NULL); - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SD_IO_SEND_OP_COND; - cmd.arg = ocr; - cmd.flags = RESP_SPI_R4 | RESP_R4 | CMD_BCR; - - for (i = 100; i; i--) - { - err = mmcsd_send_cmd(host, &cmd, 0); - if (err) - break; - - /* if we're just probing, do a single pass */ - if (ocr == 0) - break; - - /* otherwise wait until reset completes */ - if (controller_is_spi(host)) - { - /* - * Both R1_SPI_IDLE and MMC_CARD_BUSY indicate - * an initialized card under SPI, but some cards - * (Marvell's) only behave when looking at this - * one. - */ - if (cmd.resp[1] & CARD_BUSY) - break; - } - else - { - if (cmd.resp[0] & CARD_BUSY) - break; - } - - err = -RT_ETIMEOUT; - - rt_thread_mdelay(10); - } - - if (cmd5_resp) - *cmd5_resp = cmd.resp[controller_is_spi(host) ? 1 : 0]; - - return err; -} - -rt_int32_t sdio_io_rw_direct(struct rt_mmcsd_card *card, - rt_int32_t rw, - rt_uint32_t fn, - rt_uint32_t reg_addr, - rt_uint8_t *pdata, - rt_uint8_t raw) -{ - struct rt_mmcsd_cmd cmd; - rt_int32_t err; - - RT_ASSERT(card != RT_NULL); - RT_ASSERT(fn <= SDIO_MAX_FUNCTIONS); - RT_ASSERT(pdata != RT_NULL); - - if (reg_addr & ~SDIO_ARG_CMD53_REG_MASK) - return -RT_ERROR; - - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - - cmd.cmd_code = SD_IO_RW_DIRECT; - cmd.arg = rw ? SDIO_ARG_CMD52_WRITE : SDIO_ARG_CMD52_READ; - cmd.arg |= fn << SDIO_ARG_CMD52_FUNC_SHIFT; - cmd.arg |= raw ? SDIO_ARG_CMD52_RAW_FLAG : 0x00000000; - cmd.arg |= reg_addr << SDIO_ARG_CMD52_REG_SHIFT; - cmd.arg |= *pdata; - cmd.flags = RESP_SPI_R5 | RESP_R5 | CMD_AC; - - err = mmcsd_send_cmd(card->host, &cmd, 0); - if (err) - return err; - - if (!controller_is_spi(card->host)) - { - if (cmd.resp[0] & R5_ERROR) - return -RT_EIO; - if (cmd.resp[0] & R5_FUNCTION_NUMBER) - return -RT_ERROR; - if (cmd.resp[0] & R5_OUT_OF_RANGE) - return -RT_ERROR; - } - - if (!rw || raw) - { - if (controller_is_spi(card->host)) - *pdata = (cmd.resp[0] >> 8) & 0xFF; - else - *pdata = cmd.resp[0] & 0xFF; - } - - return 0; -} - -rt_int32_t sdio_io_rw_extended(struct rt_mmcsd_card *card, - rt_int32_t rw, - rt_uint32_t fn, - rt_uint32_t addr, - rt_int32_t op_code, - rt_uint8_t *buf, - rt_uint32_t blocks, - rt_uint32_t blksize) -{ - struct rt_mmcsd_req req; - struct rt_mmcsd_cmd cmd; - struct rt_mmcsd_data data; - - RT_ASSERT(card != RT_NULL); - RT_ASSERT(fn <= SDIO_MAX_FUNCTIONS); - RT_ASSERT(blocks != 1 || blksize <= 512); - RT_ASSERT(blocks != 0); - RT_ASSERT(blksize != 0); - - if (addr & ~SDIO_ARG_CMD53_REG_MASK) - return -RT_ERROR; - - rt_memset(&req, 0, sizeof(struct rt_mmcsd_req)); - rt_memset(&cmd, 0, sizeof(struct rt_mmcsd_cmd)); - rt_memset(&data, 0, sizeof(struct rt_mmcsd_data)); - - req.cmd = &cmd; - req.data = &data; - - cmd.cmd_code = SD_IO_RW_EXTENDED; - cmd.arg = rw ? SDIO_ARG_CMD53_WRITE : SDIO_ARG_CMD53_READ; - cmd.arg |= fn << SDIO_ARG_CMD53_FUNC_SHIFT; - cmd.arg |= op_code ? SDIO_ARG_CMD53_INCREMENT : 0x00000000; - cmd.arg |= addr << SDIO_ARG_CMD53_REG_SHIFT; - if (blocks == 1 && blksize <= 512) - cmd.arg |= (blksize == 512) ? 0 : blksize; /* byte mode */ - else - cmd.arg |= SDIO_ARG_CMD53_BLOCK_MODE | blocks; /* block mode */ - cmd.flags = RESP_SPI_R5 | RESP_R5 | CMD_ADTC; - - data.blksize = blksize; - data.blks = blocks; - data.flags = rw ? DATA_DIR_WRITE : DATA_DIR_READ; - data.buf = (rt_uint32_t *)buf; - - mmcsd_set_data_timeout(&data, card); - - mmcsd_send_request(card->host, &req); - - if (cmd.err) - return cmd.err; - if (data.err) - return data.err; - - if (!controller_is_spi(card->host)) - { - if (cmd.resp[0] & R5_ERROR) - return -RT_EIO; - if (cmd.resp[0] & R5_FUNCTION_NUMBER) - return -RT_ERROR; - if (cmd.resp[0] & R5_OUT_OF_RANGE) - return -RT_ERROR; - } - - return 0; -} - -rt_inline rt_uint32_t sdio_max_block_size(struct rt_sdio_function *func) -{ - rt_uint32_t size = MIN(func->card->host->max_seg_size, - func->card->host->max_blk_size); - size = MIN(size, func->max_blk_size); - - return MIN(size, 512u); /* maximum size for byte mode */ -} - -rt_int32_t sdio_io_rw_extended_block(struct rt_sdio_function *func, - rt_int32_t rw, - rt_uint32_t addr, - rt_int32_t op_code, - rt_uint8_t *buf, - rt_uint32_t len) -{ - rt_int32_t ret; - rt_uint32_t left_size; - rt_uint32_t max_blks, blks; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->card != RT_NULL); - - left_size = len; - - /* Do the bulk of the transfer using block mode (if supported). */ - if (func->card->cccr.multi_block && (len > sdio_max_block_size(func))) - { - max_blks = MIN(func->card->host->max_blk_count, - func->card->host->max_seg_size / func->cur_blk_size); - max_blks = MIN(max_blks, 511u); - - while (left_size > func->cur_blk_size) - { - blks = left_size / func->cur_blk_size; - if (blks > max_blks) - blks = max_blks; - len = blks * func->cur_blk_size; - - ret = sdio_io_rw_extended(func->card, rw, func->num, - addr, op_code, buf, blks, func->cur_blk_size); - if (ret) - return ret; - - left_size -= len; - buf += len; - if (op_code) - addr += len; - } - } - - while (left_size > 0) - { - len = MIN(left_size, sdio_max_block_size(func)); - - ret = sdio_io_rw_extended(func->card, rw, func->num, - addr, op_code, buf, 1, len); - if (ret) - return ret; - - left_size -= len; - buf += len; - if (op_code) - addr += len; - } - - return 0; -} - -rt_uint8_t sdio_io_readb(struct rt_sdio_function *func, - rt_uint32_t reg, - rt_int32_t *err) -{ - rt_uint8_t data = 0; - rt_int32_t ret; - - ret = sdio_io_rw_direct(func->card, 0, func->num, reg, &data, 0); - - if (err) - { - *err = ret; - } - - return data; -} - -rt_int32_t sdio_io_writeb(struct rt_sdio_function *func, - rt_uint32_t reg, - rt_uint8_t data) -{ - return sdio_io_rw_direct(func->card, 1, func->num, reg, &data, 0); -} - -rt_uint16_t sdio_io_readw(struct rt_sdio_function *func, - rt_uint32_t addr, - rt_int32_t *err) -{ - rt_int32_t ret; - rt_uint32_t dmabuf; - - if (err) - *err = 0; - - ret = sdio_io_rw_extended_block(func, 0, addr, 1, (rt_uint8_t *)&dmabuf, 2); - if (ret) - { - if (err) - *err = ret; - } - - return (rt_uint16_t)dmabuf; -} - -rt_int32_t sdio_io_writew(struct rt_sdio_function *func, - rt_uint16_t data, - rt_uint32_t addr) -{ - rt_uint32_t dmabuf = data; - - return sdio_io_rw_extended_block(func, 1, addr, 1, (rt_uint8_t *)&dmabuf, 2); -} - -rt_uint32_t sdio_io_readl(struct rt_sdio_function *func, - rt_uint32_t addr, - rt_int32_t *err) -{ - rt_int32_t ret; - rt_uint32_t dmabuf; - - if (err) - *err = 0; - - ret = sdio_io_rw_extended_block(func, 0, addr, 1, (rt_uint8_t *)&dmabuf, 4); - if (ret) - { - if (err) - *err = ret; - } - - return dmabuf; -} - -rt_int32_t sdio_io_writel(struct rt_sdio_function *func, - rt_uint32_t data, - rt_uint32_t addr) -{ - rt_uint32_t dmabuf = data; - - return sdio_io_rw_extended_block(func, 1, addr, 1, (rt_uint8_t *)&dmabuf, 4); -} - -rt_int32_t sdio_io_read_multi_fifo_b(struct rt_sdio_function *func, - rt_uint32_t addr, - rt_uint8_t *buf, - rt_uint32_t len) -{ - return sdio_io_rw_extended_block(func, 0, addr, 0, buf, len); -} - -rt_int32_t sdio_io_write_multi_fifo_b(struct rt_sdio_function *func, - rt_uint32_t addr, - rt_uint8_t *buf, - rt_uint32_t len) -{ - return sdio_io_rw_extended_block(func, 1, addr, 0, buf, len); -} - -rt_int32_t sdio_io_read_multi_incr_b(struct rt_sdio_function *func, - rt_uint32_t addr, - rt_uint8_t *buf, - rt_uint32_t len) -{ - return sdio_io_rw_extended_block(func, 0, addr, 1, buf, len); -} - -rt_int32_t sdio_io_write_multi_incr_b(struct rt_sdio_function *func, - rt_uint32_t addr, - rt_uint8_t *buf, - rt_uint32_t len) -{ - return sdio_io_rw_extended_block(func, 1, addr, 1, buf, len); -} - -static rt_int32_t sdio_read_cccr(struct rt_mmcsd_card *card) -{ - rt_int32_t ret; - rt_int32_t cccr_version; - rt_uint8_t data; - - rt_memset(&card->cccr, 0, sizeof(struct rt_sdio_cccr)); - - data = sdio_io_readb(card->sdio_function[0], SDIO_REG_CCCR_CCCR_REV, &ret); - if (ret) - goto out; - - cccr_version = data & 0x0f; - - if (cccr_version > SDIO_CCCR_REV_3_00) - { - LOG_E("unrecognised CCCR structure version %d", cccr_version); - - return -RT_ERROR; - } - - card->cccr.sdio_version = (data & 0xf0) >> 4; - - data = sdio_io_readb(card->sdio_function[0], SDIO_REG_CCCR_CARD_CAPS, &ret); - if (ret) - goto out; - - if (data & SDIO_CCCR_CAP_SMB) - card->cccr.multi_block = 1; - if (data & SDIO_CCCR_CAP_LSC) - card->cccr.low_speed = 1; - if (data & SDIO_CCCR_CAP_4BLS) - card->cccr.low_speed_4 = 1; - if (data & SDIO_CCCR_CAP_4BLS) - card->cccr.bus_width = 1; - - if (cccr_version >= SDIO_CCCR_REV_1_10) - { - data = sdio_io_readb(card->sdio_function[0], SDIO_REG_CCCR_POWER_CTRL, &ret); - if (ret) - goto out; - - if (data & SDIO_POWER_SMPC) - card->cccr.power_ctrl = 1; - } - - if (cccr_version >= SDIO_CCCR_REV_1_20) - { - data = sdio_io_readb(card->sdio_function[0], SDIO_REG_CCCR_SPEED, &ret); - if (ret) - goto out; - - if (data & SDIO_SPEED_SHS) - card->cccr.high_speed = 1; - } - -out: - return ret; -} - -static rt_int32_t cistpl_funce_func0(struct rt_mmcsd_card *card, - const rt_uint8_t *buf, - rt_uint32_t size) -{ - if (size < 0x04 || buf[0] != 0) - return -RT_ERROR; - - /* TPLFE_FN0_BLK_SIZE */ - card->cis.func0_blk_size = buf[1] | (buf[2] << 8); - - /* TPLFE_MAX_TRAN_SPEED */ - card->cis.max_tran_speed = speed_value[(buf[3] >> 3) & 15] * - speed_unit[buf[3] & 7]; - - return 0; -} - -static rt_int32_t cistpl_funce_func(struct rt_sdio_function *func, - const rt_uint8_t *buf, - rt_uint32_t size) -{ - rt_uint32_t version; - rt_uint32_t min_size; - - version = func->card->cccr.sdio_version; - min_size = (version == SDIO_SDIO_REV_1_00) ? 28 : 42; - - if (size < min_size || buf[0] != 1) - return -RT_ERROR; - - /* TPLFE_MAX_BLK_SIZE */ - func->max_blk_size = buf[12] | (buf[13] << 8); - - /* TPLFE_ENABLE_TIMEOUT_VAL, present in ver 1.1 and above */ - if (version > SDIO_SDIO_REV_1_00) - func->enable_timeout_val = (buf[28] | (buf[29] << 8)) * 10; - else - func->enable_timeout_val = 1000; /* 1000ms */ - - return 0; -} - -static rt_int32_t sdio_read_cis(struct rt_sdio_function *func) -{ - rt_int32_t ret; - struct rt_sdio_function_tuple *curr, **prev; - rt_uint32_t i, cisptr = 0; - rt_uint8_t data; - rt_uint8_t tpl_code, tpl_link; - - struct rt_mmcsd_card *card = func->card; - struct rt_sdio_function *func0 = card->sdio_function[0]; - - RT_ASSERT(func0 != RT_NULL); - - for (i = 0; i < 3; i++) - { - data = sdio_io_readb(func0, - SDIO_REG_FBR_BASE(func->num) + SDIO_REG_FBR_CIS + i, &ret); - if (ret) - return ret; - cisptr |= data << (i * 8); - } - - prev = &func->tuples; - - do { - tpl_code = sdio_io_readb(func0, cisptr++, &ret); - if (ret) - break; - tpl_link = sdio_io_readb(func0, cisptr++, &ret); - if (ret) - break; - - if ((tpl_code == CISTPL_END) || (tpl_link == 0xff)) - break; - - if (tpl_code == CISTPL_NULL) - continue; - - - curr = rt_malloc(sizeof(struct rt_sdio_function_tuple) + tpl_link); - if (!curr) - return -RT_ENOMEM; - curr->data = (rt_uint8_t *)curr + sizeof(struct rt_sdio_function_tuple); - - for (i = 0; i < tpl_link; i++) - { - curr->data[i] = sdio_io_readb(func0, cisptr + i, &ret); - if (ret) - break; - } - if (ret) - { - rt_free(curr); - break; - } - - switch (tpl_code) - { - case CISTPL_MANFID: - if (tpl_link < 4) - { - LOG_D("bad CISTPL_MANFID length"); - } - else - { - if (func->num != 0) - { - func->manufacturer = curr->data[0]; - func->manufacturer |= curr->data[1] << 8; - func->product = curr->data[2]; - func->product |= curr->data[3] << 8; - } - else - { - card->cis.manufacturer = curr->data[0]; - card->cis.manufacturer |= curr->data[1] << 8; - card->cis.product = curr->data[2]; - card->cis.product |= curr->data[3] << 8; - } - } - - rt_free(curr); - break; - case CISTPL_FUNCE: - if (func->num != 0) - ret = cistpl_funce_func(func, curr->data, tpl_link); - else - ret = cistpl_funce_func0(card, curr->data, tpl_link); - - if (ret) - { - LOG_D("bad CISTPL_FUNCE size %u " - "type %u", tpl_link, curr->data[0]); - } - - break; - case CISTPL_VERS_1: - if (tpl_link < 2) - { - LOG_D("CISTPL_VERS_1 too short"); - } - break; - default: - /* this tuple is unknown to the core */ - curr->next = RT_NULL; - curr->code = tpl_code; - curr->size = tpl_link; - *prev = curr; - prev = &curr->next; - LOG_D( "function %d, CIS tuple code %#x, length %d", - func->num, tpl_code, tpl_link); - break; - } - - cisptr += tpl_link; - } while (1); - - /* - * Link in all unknown tuples found in the common CIS so that - * drivers don't have to go digging in two places. - */ - if (func->num != 0) - *prev = func0->tuples; - - return ret; -} - - -void sdio_free_cis(struct rt_sdio_function *func) -{ - struct rt_sdio_function_tuple *tuple, *tmp; - struct rt_mmcsd_card *card = func->card; - - tuple = func->tuples; - - while (tuple && ((tuple != card->sdio_function[0]->tuples) || (!func->num))) - { - tmp = tuple; - tuple = tuple->next; - rt_free(tmp); - } - - func->tuples = RT_NULL; -} - -static rt_int32_t sdio_read_fbr(struct rt_sdio_function *func) -{ - rt_int32_t ret; - rt_uint8_t data; - struct rt_sdio_function *func0 = func->card->sdio_function[0]; - - data = sdio_io_readb(func0, - SDIO_REG_FBR_BASE(func->num) + SDIO_REG_FBR_STD_FUNC_IF, &ret); - if (ret) - goto err; - - data &= 0x0f; - - if (data == 0x0f) - { - data = sdio_io_readb(func0, - SDIO_REG_FBR_BASE(func->num) + SDIO_REG_FBR_STD_IF_EXT, &ret); - if (ret) - goto err; - } - - func->func_code = data; - -err: - return ret; -} - -static rt_int32_t sdio_initialize_function(struct rt_mmcsd_card *card, - rt_uint32_t func_num) -{ - rt_int32_t ret; - struct rt_sdio_function *func; - - RT_ASSERT(func_num <= SDIO_MAX_FUNCTIONS); - - func = rt_malloc(sizeof(struct rt_sdio_function)); - if (!func) - { - LOG_E("malloc rt_sdio_function failed"); - ret = -RT_ENOMEM; - goto err; - } - rt_memset(func, 0, sizeof(struct rt_sdio_function)); - - func->card = card; - func->num = func_num; - - ret = sdio_read_fbr(func); - if (ret) - goto err1; - - ret = sdio_read_cis(func); - if (ret) - goto err1; - - /* - * product/manufacturer id is optional for function CIS, so - * copy it from the card structure as needed. - */ - if (func->product == 0) - { - func->manufacturer = card->cis.manufacturer; - func->product = card->cis.product; - } - - card->sdio_function[func_num] = func; - - return 0; - -err1: - sdio_free_cis(func); - rt_free(func); - card->sdio_function[func_num] = RT_NULL; -err: - return ret; -} - -static rt_int32_t sdio_set_highspeed(struct rt_mmcsd_card *card) -{ - rt_int32_t ret; - rt_uint8_t speed; - - if (!(card->host->flags & MMCSD_SUP_HIGHSPEED)) - return 0; - - if (!card->cccr.high_speed) - return 0; - - speed = sdio_io_readb(card->sdio_function[0], SDIO_REG_CCCR_SPEED, &ret); - if (ret) - return ret; - - speed |= SDIO_SPEED_EHS; - - ret = sdio_io_writeb(card->sdio_function[0], SDIO_REG_CCCR_SPEED, speed); - if (ret) - return ret; - - card->flags |= CARD_FLAG_HIGHSPEED; - - return 0; -} - -static rt_int32_t sdio_set_bus_wide(struct rt_mmcsd_card *card) -{ - rt_int32_t ret; - rt_uint8_t busif; - - if (!(card->host->flags & MMCSD_BUSWIDTH_4)) - return 0; - - if (card->cccr.low_speed && !card->cccr.bus_width) - return 0; - - busif = sdio_io_readb(card->sdio_function[0], SDIO_REG_CCCR_BUS_IF, &ret); - if (ret) - return ret; - - busif |= SDIO_BUS_WIDTH_4BIT; - - ret = sdio_io_writeb(card->sdio_function[0], SDIO_REG_CCCR_BUS_IF, busif); - if (ret) - return ret; - - mmcsd_set_bus_width(card->host, MMCSD_BUS_WIDTH_4); - - return 0; -} - -static rt_int32_t sdio_register_card(struct rt_mmcsd_card *card) -{ - struct sdio_card *sc; - struct sdio_driver *sd; - rt_list_t *l; - - sc = rt_malloc(sizeof(struct sdio_card)); - if (sc == RT_NULL) - { - LOG_E("malloc sdio card failed"); - return -RT_ENOMEM; - } - - sc->card = card; - rt_list_insert_after(&sdio_cards, &sc->list); - - if (rt_list_isempty(&sdio_drivers)) - { - goto out; - } - - for (l = (&sdio_drivers)->next; l != &sdio_drivers; l = l->next) - { - sd = (struct sdio_driver *)rt_list_entry(l, struct sdio_driver, list); - if (sdio_match_card(card, sd->drv->id)) - { - sd->drv->probe(card); - } - } - -out: - return 0; -} - -static rt_int32_t sdio_init_card(struct rt_mmcsd_host *host, rt_uint32_t ocr) -{ - rt_int32_t err = 0; - rt_int32_t i, function_num; - rt_uint32_t cmd5_resp; - struct rt_mmcsd_card *card; - - err = sdio_io_send_op_cond(host, ocr, &cmd5_resp); - if (err) - goto err; - - if (controller_is_spi(host)) - { - err = mmcsd_spi_use_crc(host, host->spi_use_crc); - if (err) - goto err; - } - - function_num = (cmd5_resp & 0x70000000) >> 28; - - card = rt_malloc(sizeof(struct rt_mmcsd_card)); - if (!card) - { - LOG_E("malloc card failed"); - err = -RT_ENOMEM; - goto err; - } - rt_memset(card, 0, sizeof(struct rt_mmcsd_card)); - - card->card_type = CARD_TYPE_SDIO; - card->sdio_function_num = function_num; - card->host = host; - host->card = card; - - card->sdio_function[0] = rt_malloc(sizeof(struct rt_sdio_function)); - if (!card->sdio_function[0]) - { - LOG_E("malloc sdio_func0 failed"); - err = -RT_ENOMEM; - goto err1; - } - rt_memset(card->sdio_function[0], 0, sizeof(struct rt_sdio_function)); - card->sdio_function[0]->card = card; - card->sdio_function[0]->num = 0; - - if (!controller_is_spi(host)) - { - err = mmcsd_get_card_addr(host, &card->rca); - if (err) - goto err2; - - mmcsd_set_bus_mode(host, MMCSD_BUSMODE_PUSHPULL); - } - - if (!controller_is_spi(host)) - { - err = mmcsd_select_card(card); - if (err) - goto err2; - } - - err = sdio_read_cccr(card); - if (err) - goto err2; - - err = sdio_read_cis(card->sdio_function[0]); - if (err) - goto err2; - - err = sdio_set_highspeed(card); - if (err) - goto err2; - - if (card->flags & CARD_FLAG_HIGHSPEED) - { - mmcsd_set_clock(host, card->host->freq_max > 50000000 ? 50000000 : card->host->freq_max); - } - else - { - mmcsd_set_clock(host, card->cis.max_tran_speed); - } - - err = sdio_set_bus_wide(card); - if (err) - goto err2; - - for (i = 1; i < function_num + 1; i++) - { - err = sdio_initialize_function(card, i); - if (err) - goto err3; - } - - - /* register sdio card */ - err = sdio_register_card(card); - if (err) - { - goto err3; - } - - return 0; - -err3: - if (host->card) - { - for (i = 1; i < host->card->sdio_function_num + 1; i++) - { - if (host->card->sdio_function[i]) - { - sdio_free_cis(host->card->sdio_function[i]); - rt_free(host->card->sdio_function[i]); - host->card->sdio_function[i] = RT_NULL; - } - } - } -err2: - if (host->card && host->card->sdio_function[0]) - { - sdio_free_cis(host->card->sdio_function[0]); - rt_free(host->card->sdio_function[0]); - host->card->sdio_function[0] = RT_NULL; - } -err1: - if (host->card) - { - rt_free(host->card); - host->card = RT_NULL; - } -err: - LOG_E("error %d while initialising SDIO card", err); - - return err; -} - -rt_int32_t init_sdio(struct rt_mmcsd_host *host, rt_uint32_t ocr) -{ - rt_int32_t err; - rt_uint32_t current_ocr; - - RT_ASSERT(host != RT_NULL); - - if (ocr & 0x7F) - { - LOG_W("Card ocr below the defined voltage rang."); - ocr &= ~0x7F; - } - - if (ocr & VDD_165_195) - { - LOG_W("Can't support the low voltage SDIO card."); - ocr &= ~VDD_165_195; - } - - current_ocr = mmcsd_select_voltage(host, ocr); - - if (!current_ocr) - { - err = -RT_ERROR; - goto err; - } - - err = sdio_init_card(host, current_ocr); - if (err) - goto err; - - return 0; - -err: - - LOG_E("init SDIO card failed"); - - return err; -} - -static void sdio_irq_thread(void *param) -{ - rt_int32_t i, ret; - rt_uint8_t pending; - struct rt_mmcsd_card *card; - struct rt_mmcsd_host *host = (struct rt_mmcsd_host *)param; - RT_ASSERT(host != RT_NULL); - card = host->card; - RT_ASSERT(card != RT_NULL); - - while (1) - { - if (rt_sem_take(host->sdio_irq_sem, RT_WAITING_FOREVER) == RT_EOK) - { - mmcsd_host_lock(host); - pending = sdio_io_readb(host->card->sdio_function[0], - SDIO_REG_CCCR_INT_PEND, &ret); - if (ret) - { - mmcsd_dbg("error %d reading SDIO_REG_CCCR_INT_PEND\n", ret); - goto out; - } - - for (i = 1; i <= 7; i++) - { - if (pending & (1 << i)) - { - struct rt_sdio_function *func = card->sdio_function[i]; - if (!func) - { - mmcsd_dbg("pending IRQ for non-existant function\n"); - goto out; - } - else if (func->irq_handler) - { - func->irq_handler(func); - } - else - { - mmcsd_dbg("pending IRQ with no register handler\n"); - goto out; - } - } - } - - out: - mmcsd_host_unlock(host); - if (host->flags & MMCSD_SUP_SDIO_IRQ) - host->ops->enable_sdio_irq(host, 1); - continue; - } - } -} - -static rt_int32_t sdio_irq_thread_create(struct rt_mmcsd_card *card) -{ - struct rt_mmcsd_host *host = card->host; - - /* init semaphore and create sdio irq processing thread */ - if (!host->sdio_irq_num) - { - host->sdio_irq_num++; - host->sdio_irq_sem = rt_sem_create("sdio_irq", 0, RT_IPC_FLAG_FIFO); - RT_ASSERT(host->sdio_irq_sem != RT_NULL); - - host->sdio_irq_thread = rt_thread_create("sdio_irq", sdio_irq_thread, host, - RT_SDIO_STACK_SIZE, RT_SDIO_THREAD_PRIORITY, 20); - if (host->sdio_irq_thread != RT_NULL) - { - rt_thread_startup(host->sdio_irq_thread); - } - } - - return 0; -} - -static rt_int32_t sdio_irq_thread_delete(struct rt_mmcsd_card *card) -{ - struct rt_mmcsd_host *host = card->host; - - RT_ASSERT(host->sdio_irq_num > 0); - - host->sdio_irq_num--; - if (!host->sdio_irq_num) - { - if (host->flags & MMCSD_SUP_SDIO_IRQ) - host->ops->enable_sdio_irq(host, 0); - rt_sem_delete(host->sdio_irq_sem); - host->sdio_irq_sem = RT_NULL; - rt_thread_delete(host->sdio_irq_thread); - host->sdio_irq_thread = RT_NULL; - } - - return 0; -} - -rt_int32_t sdio_attach_irq(struct rt_sdio_function *func, - rt_sdio_irq_handler_t *handler) -{ - rt_int32_t ret; - rt_uint8_t reg; - struct rt_sdio_function *func0; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->card != RT_NULL); - - func0 = func->card->sdio_function[0]; - - mmcsd_dbg("SDIO: enabling IRQ for function %d\n", func->num); - - if (func->irq_handler) - { - mmcsd_dbg("SDIO: IRQ for already in use.\n"); - - return -RT_EBUSY; - } - - reg = sdio_io_readb(func0, SDIO_REG_CCCR_INT_EN, &ret); - if (ret) - return ret; - - reg |= 1 << func->num; - - reg |= 1; /* Master interrupt enable */ - - ret = sdio_io_writeb(func0, SDIO_REG_CCCR_INT_EN, reg); - if (ret) - return ret; - - func->irq_handler = handler; - - ret = sdio_irq_thread_create(func->card); - if (ret) - func->irq_handler = RT_NULL; - - return ret; -} - -rt_int32_t sdio_detach_irq(struct rt_sdio_function *func) -{ - rt_int32_t ret; - rt_uint8_t reg; - struct rt_sdio_function *func0; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->card != RT_NULL); - - func0 = func->card->sdio_function[0]; - - mmcsd_dbg("SDIO: disabling IRQ for function %d\n", func->num); - - if (func->irq_handler) - { - func->irq_handler = RT_NULL; - sdio_irq_thread_delete(func->card); - } - - reg = sdio_io_readb(func0, SDIO_REG_CCCR_INT_EN, &ret); - if (ret) - return ret; - - reg &= ~(1 << func->num); - - /* Disable master interrupt with the last function interrupt */ - if (!(reg & 0xFE)) - reg = 0; - - ret = sdio_io_writeb(func0, SDIO_REG_CCCR_INT_EN, reg); - if (ret) - return ret; - - return 0; -} - -void sdio_irq_wakeup(struct rt_mmcsd_host *host) -{ - if (host->flags & MMCSD_SUP_SDIO_IRQ) - host->ops->enable_sdio_irq(host, 0); - if (host->sdio_irq_sem) - rt_sem_release(host->sdio_irq_sem); -} - -rt_int32_t sdio_enable_func(struct rt_sdio_function *func) -{ - rt_int32_t ret; - rt_uint8_t reg; - rt_uint32_t timeout; - struct rt_sdio_function *func0; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->card != RT_NULL); - - func0 = func->card->sdio_function[0]; - - mmcsd_dbg("SDIO: enabling function %d\n", func->num); - - reg = sdio_io_readb(func0, SDIO_REG_CCCR_IO_EN, &ret); - if (ret) - goto err; - - reg |= 1 << func->num; - - ret = sdio_io_writeb(func0, SDIO_REG_CCCR_IO_EN, reg); - if (ret) - goto err; - - timeout = rt_tick_get() + func->enable_timeout_val * RT_TICK_PER_SECOND / 1000; - - while (1) - { - reg = sdio_io_readb(func0, SDIO_REG_CCCR_IO_RDY, &ret); - if (ret) - goto err; - if (reg & (1 << func->num)) - break; - ret = -RT_ETIMEOUT; - if (rt_tick_get() > timeout) - goto err; - } - - mmcsd_dbg("SDIO: enabled function successfull\n"); - - return 0; - -err: - mmcsd_dbg("SDIO: failed to enable function %d\n", func->num); - return ret; -} - -rt_int32_t sdio_disable_func(struct rt_sdio_function *func) -{ - rt_int32_t ret; - rt_uint8_t reg; - struct rt_sdio_function *func0; - - RT_ASSERT(func != RT_NULL); - RT_ASSERT(func->card != RT_NULL); - - func0 = func->card->sdio_function[0]; - - mmcsd_dbg("SDIO: disabling function %d\n", func->num); - - reg = sdio_io_readb(func0, SDIO_REG_CCCR_IO_EN, &ret); - if (ret) - goto err; - - reg &= ~(1 << func->num); - - ret = sdio_io_writeb(func0, SDIO_REG_CCCR_IO_EN, reg); - if (ret) - goto err; - - mmcsd_dbg("SDIO: disabled function successfull\n"); - - return 0; - -err: - mmcsd_dbg("SDIO: failed to disable function %d\n", func->num); - return -RT_EIO; -} - -void sdio_set_drvdata(struct rt_sdio_function *func, void *data) -{ - func->priv = data; -} - -void* sdio_get_drvdata(struct rt_sdio_function *func) -{ - return func->priv; -} - -rt_int32_t sdio_set_block_size(struct rt_sdio_function *func, - rt_uint32_t blksize) -{ - rt_int32_t ret; - struct rt_sdio_function *func0 = func->card->sdio_function[0]; - - if (blksize > func->card->host->max_blk_size) - return -RT_ERROR; - - if (blksize == 0) - { - blksize = MIN(func->max_blk_size, func->card->host->max_blk_size); - blksize = MIN(blksize, 512u); - } - - ret = sdio_io_writeb(func0, SDIO_REG_FBR_BASE(func->num) + SDIO_REG_FBR_BLKSIZE, - blksize & 0xff); - if (ret) - return ret; - ret = sdio_io_writeb(func0, SDIO_REG_FBR_BASE(func->num) + SDIO_REG_FBR_BLKSIZE + 1, - (blksize >> 8) & 0xff); - if (ret) - return ret; - func->cur_blk_size = blksize; - - return 0; -} - -rt_inline rt_int32_t sdio_match_card(struct rt_mmcsd_card *card, - const struct rt_sdio_device_id *id) -{ - rt_uint8_t num = 1; - - if ((id->manufacturer != SDIO_ANY_MAN_ID) && - (id->manufacturer != card->cis.manufacturer)) - return 0; - - while (num <= card->sdio_function_num) - { - if ((id->product != SDIO_ANY_PROD_ID) && - (id->product == card->sdio_function[num]->product)) - return 1; - num++; - } - - return 0; -} - - -static struct rt_mmcsd_card *sdio_match_driver(struct rt_sdio_device_id *id) -{ - rt_list_t *l; - struct sdio_card *sc; - struct rt_mmcsd_card *card; - - for (l = (&sdio_cards)->next; l != &sdio_cards; l = l->next) - { - sc = (struct sdio_card *)rt_list_entry(l, struct sdio_card, list); - card = sc->card; - - if (sdio_match_card(card, id)) - { - return card; - } - } - - return RT_NULL; -} - -rt_int32_t sdio_register_driver(struct rt_sdio_driver *driver) -{ - struct sdio_driver *sd; - struct rt_mmcsd_card *card; - - sd = rt_malloc(sizeof(struct sdio_driver)); - if (sd == RT_NULL) - { - LOG_E("malloc sdio driver failed"); - - return -RT_ENOMEM; - } - - sd->drv = driver; - rt_list_insert_after(&sdio_drivers, &sd->list); - - if (!rt_list_isempty(&sdio_cards)) - { - card = sdio_match_driver(driver->id); - if (card != RT_NULL) - { - return driver->probe(card); - } - } - - return -RT_EEMPTY; -} - -rt_int32_t sdio_unregister_driver(struct rt_sdio_driver *driver) -{ - rt_list_t *l; - struct sdio_driver *sd = RT_NULL; - struct rt_mmcsd_card *card; - - for (l = (&sdio_drivers)->next; l != &sdio_drivers; l = l->next) - { - sd = (struct sdio_driver *)rt_list_entry(l, struct sdio_driver, list); - if (sd->drv != driver) - { - sd = RT_NULL; - } - } - - if (sd == RT_NULL) - { - LOG_E("SDIO driver %s not register", driver->name); - return -RT_ERROR; - } - - if (!rt_list_isempty(&sdio_cards)) - { - card = sdio_match_driver(driver->id); - if (card != RT_NULL) - { - driver->remove(card); - rt_list_remove(&sd->list); - rt_free(sd); - } - } - - return 0; -} - -void rt_sdio_init(void) -{ - -} - diff --git a/rt-thread/components/drivers/sdio/sdhci/fit-mmc.c b/rt-thread/components/drivers/sdio/sdhci/fit-mmc.c deleted file mode 100644 index a3fe063..0000000 --- a/rt-thread/components/drivers/sdio/sdhci/fit-mmc.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-08-16 zhujiale first version - */ -#include -#include "sdhci.h" -#include -#include -#include - - -static void rt_plat_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req) -{ - struct rt_mmc_host *mmc = (struct rt_mmc_host *)host; - rt_uint32_t flags = req->cmd->flags; - - switch (flags & RESP_MASK) - { - case RESP_NONE: - flags |= MMC_RSP_NONE; - break; - case RESP_R1: - flags |= MMC_RSP_R1; - break; - case RESP_R1B: - flags |= MMC_RSP_R1B; - break; - case RESP_R2: - flags |= MMC_RSP_R2; - break; - case RESP_R3: - flags |= MMC_RSP_R3; - break; - case RESP_R4: - flags |= MMC_RSP_R4; - break; - case RESP_R5: - flags |= MMC_RSP_R5; - break; - case RESP_R6: - flags |= MMC_RSP_R6; - break; - case RESP_R7: - flags |= MMC_RSP_R7; - break; - } - if (req->data) - { - if ((rt_uint64_t)rt_kmem_v2p(req->data->buf) > 0xffffffff) - { - void *dma_buffer = rt_malloc(req->data->blks * req->data->blksize); - void *req_buf = NULL; - - if (req->data->flags & DATA_DIR_WRITE) - { - rt_memcpy(dma_buffer, req->data->buf, req->data->blks * req->data->blksize); - req_buf = req->data->buf; - req->data->buf = dma_buffer; - } - else if (req->data->flags & DATA_DIR_READ) - { - req_buf = req->data->buf; - req->data->buf = dma_buffer; - } - req->cmd->flags |= flags; - mmc->ops->request(mmc, req); - - rt_sem_take(&host->sem_ack, RT_WAITING_FOREVER); - - if (req->data->flags & DATA_DIR_READ) - { - rt_memcpy(req_buf, dma_buffer, req->data->blksize * req->data->blks); - req->data->buf = req_buf; - }else{ - req->data->buf = req_buf; - } - - rt_free(dma_buffer); - rt_sem_release(&host->sem_ack); - } - else - { - req->cmd->flags |= flags; - mmc->ops->request(mmc, req); - } - } - else - { - req->cmd->flags |= flags; - mmc->ops->request(mmc, req); - } -} - -static void rt_plat_set_ioconfig(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *iocfg) -{ - struct rt_mmc_host *mmc = (struct rt_mmc_host *)host; - - LOG_D("clock:%d,width:%d,power:%d,vdd:%d,timing:%d\n", - iocfg->clock, iocfg->bus_width, - iocfg->power_mode, iocfg->vdd, iocfg->timing); - - mmc->ops->set_ios(mmc, iocfg); -} - -static rt_int32_t rt_plat_get_card_status(struct rt_mmcsd_host *host) -{ - struct rt_mmc_host *mmc = (struct rt_mmc_host *)host; - - return mmc->ops->get_cd(mmc); -} - -static rt_int32_t rt_plat_execute_tuning(struct rt_mmcsd_host *host, rt_int32_t opcode) -{ - struct rt_mmc_host *mmc = (struct rt_mmc_host *)host; - - return mmc->ops->execute_tuning(mmc, opcode); -} - -static void rt_plat_enable_sdio_irq(struct rt_mmcsd_host *host, rt_int32_t en) -{ - struct rt_mmc_host *mmc = (struct rt_mmc_host *)host; - - return mmc->ops->enable_sdio_irq(mmc, en); -} - - -static const struct rt_mmcsd_host_ops rt_mmcsd_ops = { - .request = rt_plat_request, - .set_iocfg = rt_plat_set_ioconfig, - .get_card_status = rt_plat_get_card_status, - .enable_sdio_irq = rt_plat_enable_sdio_irq, - .execute_tuning = rt_plat_execute_tuning, -}; - - -void rt_mmc_request_done(struct rt_mmc_host *host, struct rt_mmcsd_req *mrq) -{ - mmcsd_req_complete(&host->rthost); -} - -/*add host in rtt while sdhci complete*/ -int rt_mmc_add_host(struct rt_mmc_host *mmc) -{ - mmc->rthost.ops = &rt_mmcsd_ops; - mmc->rthost.flags = mmc->caps; - mmc->rthost.freq_max = mmc->f_max; - mmc->rthost.freq_min = 400000; - mmc->rthost.max_dma_segs = mmc->max_segs; - mmc->rthost.max_seg_size = mmc->max_seg_size; - mmc->rthost.max_blk_size = mmc->max_blk_size; - mmc->rthost.max_blk_count = mmc->max_blk_count; - mmc->rthost.valid_ocr = VDD_165_195|VDD_20_21|VDD_21_22|VDD_22_23|VDD_24_25|VDD_25_26|VDD_26_27|VDD_27_28|VDD_28_29|VDD_29_30|VDD_30_31|VDD_32_33|VDD_33_34|VDD_34_35|VDD_35_36; - - - mmcsd_change(&mmc->rthost); - return 0; -} - -struct rt_mmc_host *rt_mmc_alloc_host(int extra, struct rt_device *dev) -{ - struct rt_mmc_host *mmc; - - mmc = rt_malloc(sizeof(*mmc) + extra); - if (mmc) - { - rt_memset(mmc, 0, sizeof(*mmc) + extra); - mmc->parent = dev; - mmcsd_host_init(&mmc->rthost); - } - - return mmc; -} - -void rt_mmc_remove_host(struct rt_mmc_host *host) -{ - rt_free(host); -} - -int rt_mmc_abort_tuning(struct rt_mmc_host *host, rt_uint32_t opcode) -{ - return 0; -} - - -int rt_mmc_gpio_get_cd(struct rt_mmc_host *host) -{ - return -ENOSYS; -} - -void rt_mmc_detect_change(struct rt_mmc_host *host, unsigned long delay) -{ -} - - -int rt_mmc_regulator_set_vqmmc(struct rt_mmc_host *mmc, struct rt_mmcsd_io_cfg *ios) -{ - return 0; -} - -rt_bool_t rt_mmc_can_gpio_ro(struct rt_mmc_host *host) -{ - return RT_FALSE; -} - -int rt_mmc_gpio_get_ro(struct rt_mmc_host *host) -{ - return 0; -} - -int rt_mmc_send_abort_tuning(struct rt_mmc_host *host, rt_uint32_t opcode) -{ - return 0; -} -int rt_mmc_of_parse(struct rt_mmc_host *host) -{ - struct rt_device *dev = host->parent; - rt_uint32_t bus_width; - - if (!dev || !dev->ofw_node) - return 0; - - /* "bus-width" is translated to MMC_CAP_*_BIT_DATA flags */ - if (rt_dm_dev_prop_read_u32(dev, "bus-width", &bus_width) < 0) - { - bus_width = 1; - } - - switch (bus_width) - { - case 8: - host->caps |= MMC_CAP_8_BIT_DATA; - break; /* Hosts capable of 8-bit can also do 4 bits */ - case 4: - host->caps |= MMC_CAP_4_BIT_DATA; - break; - case 1: - break; - default: - return -EINVAL; - } - - /* f_max is obtained from the optional "max-frequency" property */ - rt_dm_dev_prop_read_u32(dev, "max-frequency", &host->f_max); - - if (rt_dm_dev_prop_read_bool(dev, "cap-mmc-highspeed")) - { - host->caps |= MMC_CAP_MMC_HIGHSPEED; - } - - if (rt_dm_dev_prop_read_bool(dev, "mmc-hs200-1_8v")) - { - host->caps |= MMC_CAP2_HS200_1_8V_SDR; - } - - if (rt_dm_dev_prop_read_bool(dev, "non-removable")) - { - host->caps |= MMC_CAP_NONREMOVABLE; - } - - if (rt_dm_dev_prop_read_bool(dev, "no-sdio")) - { - host->caps2 |= MMC_CAP2_NO_SDIO; - } - - if (rt_dm_dev_prop_read_bool(dev, "no-sd")) - { - host->caps2 |= MMC_CAP2_NO_SD; - } - - if (rt_dm_dev_prop_read_bool(dev, "mmc-ddr-3_3v")) - { - host->caps |= MMC_CAP_3_3V_DDR; - } - - if (rt_dm_dev_prop_read_bool(dev, "mmc-ddr-1_8v")) - { - host->caps |= MMC_CAP_1_8V_DDR; - } - - if (rt_dm_dev_prop_read_bool(dev, "mmc-ddr-1_2v")) - { - host->caps |= MMC_CAP_1_2V_DDR; - } - - return 0; -} - - -void rt_mmc_free_host(struct rt_mmc_host *host) -{ -} - -rt_bool_t rt_mmc_can_gpio_cd(struct rt_mmc_host *host) -{ - return RT_FALSE; -} - -int mmc_regulator_get_supply(struct rt_mmc_host *mmc) -{ - mmc->supply.vmmc = -RT_NULL; - mmc->supply.vqmmc = -RT_NULL; - - return 0; -} -int regulator_get_current_limit(struct regulator *regulator) -{ - return 0; -} - -int regulator_is_supported_voltage(struct regulator *regulator, - - int min_uV, int max_uV) -{ - return 0; -} diff --git a/rt-thread/components/drivers/sdio/sdhci/include/sdhci-platform.h b/rt-thread/components/drivers/sdio/sdhci/include/sdhci-platform.h deleted file mode 100644 index f8d9644..0000000 --- a/rt-thread/components/drivers/sdio/sdhci/include/sdhci-platform.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-08-16 zhujiale first version - */ - -#ifndef _DRIVERS_MMC_RT_SDHCI_PLTFM_H -#define _DRIVERS_MMC_RT_SDHCI_PLTFM_H -#include -#include -#include -#include -#include -#include "sdhci.h" - -struct rt_sdhci_pltfm_data -{ - const struct rt_sdhci_ops *ops; - unsigned int quirks; - unsigned int quirks2; -}; - -struct rt_sdhci_pltfm_host -{ - struct rt_clk *clk; - unsigned int clock; - rt_uint64_t xfer_mode_shadow; - - unsigned long private[]; -}; -void rt_sdhci_get_property(struct rt_platform_device *pdev); - -static inline void sdhci_get_of_property(struct rt_platform_device *pdev) -{ - return rt_sdhci_get_property(pdev); -} -extern struct rt_sdhci_host *rt_sdhci_pltfm_init(struct rt_platform_device *pdev, - const struct rt_sdhci_pltfm_data *pdata, - size_t priv_size); -extern void rt_sdhci_pltfm_free(struct rt_platform_device *pdev); - -extern int rt_sdhci_pltfm_init_and_add_host(struct rt_platform_device *pdev, - const struct rt_sdhci_pltfm_data *pdata, - size_t priv_size); -extern void rt_sdhci_pltfm_remove(struct rt_platform_device *pdev); - -extern unsigned int rt_sdhci_pltfm_clk_get_max_clock(struct rt_sdhci_host *host); - -static inline void *sdhci_pltfm_priv(struct rt_sdhci_pltfm_host *host) -{ - return host->private; -} - -static inline int sdhci_pltfm_suspend(struct rt_device *dev) -{ - return 0; -} -static inline int sdhci_pltfm_resume(struct rt_device *dev) -{ - return 0; -} -#endif diff --git a/rt-thread/components/drivers/sdio/sdhci/include/sdhci.h b/rt-thread/components/drivers/sdio/sdhci/include/sdhci.h deleted file mode 100644 index 1ad3db1..0000000 --- a/rt-thread/components/drivers/sdio/sdhci/include/sdhci.h +++ /dev/null @@ -1,677 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-08-16 zhujiale first version - */ -#ifndef __RT_SDHCI_HW_H -#define __RT_SDHCI_HW_H - -#include "sdhci_host.h" -#include "sdhci_misc.h" -#include "sdhci-platform.h" -#include -#include -#include -#include - -#define lower_32_bits(n) ((rt_uint32_t)((n) & 0xffffffff)) -#define upper_32_bits(n) ((rt_uint32_t)(((n) >> 16) >> 16)) - -#define MAX_TUNING_LOOP 40 -/* - * Controller registers - */ -#define RT_SDHCI_DMA_ADDRESS 0x00 -#define RT_SDHCI_ARGUMENT2 RT_SDHCI_DMA_ADDRESS -#define RT_SDHCI_32BIT_BLK_CNT RT_SDHCI_DMA_ADDRESS - -#define RT_SDHCI_BLOCK_SIZE 0x04 -#define RT_SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF)) - -#define RT_SDHCI_BLOCK_COUNT 0x06 - -#define RT_SDHCI_ARGUMENT 0x08 - -#define RT_SDHCI_TRANSFER_MODE 0x0C -#define RT_SDHCI_TRNS_DMA 0x01 -#define RT_SDHCI_TRNS_BLK_CNT_EN 0x02 -#define RT_SDHCI_TRNS_AUTO_CMD12 0x04 -#define RT_SDHCI_TRNS_AUTO_CMD23 0x08 -#define RT_SDHCI_TRNS_AUTO_SEL 0x0C -#define RT_SDHCI_TRNS_READ 0x10 -#define RT_SDHCI_TRNS_MULTI 0x20 - -#define RT_SDHCI_COMMAND 0x0E -#define RT_SDHCI_CMD_RESP_MASK 0x03 -#define RT_SDHCI_CMD_CRC 0x08 -#define RT_SDHCI_CMD_INDEX 0x10 -#define RT_SDHCI_CMD_DATA 0x20 -#define RT_SDHCI_CMD_ABORTCMD 0xC0 - -#define RT_SDHCI_CMD_RESP_NONE 0x00 -#define RT_SDHCI_CMD_RESP_LONG 0x01 -#define RT_SDHCI_CMD_RESP_SHORT 0x02 -#define RT_SDHCI_CMD_RESP_SHORT_BUSY 0x03 - -#define RT_SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff)) -#define RT_SDHCI_GET_CMD(c) ((c >> 8) & 0x3f) - -#define RT_SDHCI_RESPONSE 0x10 - -#define RT_SDHCI_BUFFER 0x20 - -#define RT_SDHCI_PRESENT_STATE 0x24 -#define RT_SDHCI_CMD_INHIBIT 0x00000001 -#define RT_SDHCI_DATA_INHIBIT 0x00000002 -#define RT_SDHCI_DOING_WRITE 0x00000100 -#define RT_SDHCI_DOING_READ 0x00000200 -#define RT_SDHCI_SPACE_AVAILABLE 0x00000400 -#define RT_SDHCI_DATA_AVAILABLE 0x00000800 -#define RT_SDHCI_CARD_PRESENT 0x00010000 -#define RT_SDHCI_CARD_PRES_SHIFT 16 -#define RT_SDHCI_CD_STABLE 0x00020000 -#define RT_SDHCI_CD_LVL 0x00040000 -#define RT_SDHCI_CD_LVL_SHIFT 18 -#define RT_SDHCI_WRITE_PROTECT 0x00080000 -#define RT_SDHCI_DATA_LVL_MASK 0x00F00000 -#define RT_SDHCI_DATA_LVL_SHIFT 20 -#define RT_SDHCI_DATA_0_LVL_MASK 0x00100000 -#define RT_SDHCI_CMD_LVL 0x01000000 - -#define RT_SDHCI_HOST_CONTROL 0x28 -#define RT_SDHCI_CTRL_LED 0x01 -#define RT_SDHCI_CTRL_4BITBUS 0x02 -#define RT_SDHCI_CTRL_HISPD 0x04 -#define RT_SDHCI_CTRL_DMA_MASK 0x18 -#define RT_SDHCI_CTRL_SDMA 0x00 -#define RT_SDHCI_CTRL_ADMA1 0x08 -#define RT_SDHCI_CTRL_ADMA32 0x10 -#define RT_SDHCI_CTRL_ADMA64 0x18 -#define RT_SDHCI_CTRL_ADMA3 0x18 -#define RT_SDHCI_CTRL_8BITBUS 0x20 -#define RT_SDHCI_CTRL_CDTEST_INS 0x40 -#define RT_SDHCI_CTRL_CDTEST_EN 0x80 - -#define RT_SDHCI_POWER_CONTROL 0x29 -#define RT_SDHCI_POWER_ON 0x01 -#define RT_SDHCI_POWER_180 0x0A -#define RT_SDHCI_POWER_300 0x0C -#define RT_SDHCI_POWER_330 0x0E -/* - * VDD2 - UHS2 or PCIe/NVMe - * VDD2 power on/off and voltage select - */ -#define RT_SDHCI_VDD2_POWER_ON 0x10 -#define RT_SDHCI_VDD2_POWER_120 0x80 -#define RT_SDHCI_VDD2_POWER_180 0xA0 - -#define RT_SDHCI_BLOCK_GAP_CONTROL 0x2A - -#define RT_SDHCI_WAKE_UP_CONTROL 0x2B -#define RT_SDHCI_WAKE_ON_INT 0x01 -#define RT_SDHCI_WAKE_ON_INSERT 0x02 -#define RT_SDHCI_WAKE_ON_REMOVE 0x04 - -#define RT_SDHCI_CLOCK_CONTROL 0x2C -#define RT_SDHCI_DIVIDER_SHIFT 8 -#define RT_SDHCI_DIVIDER_HI_SHIFT 6 -#define RT_SDHCI_DIV_MASK 0xFF -#define RT_SDHCI_DIV_MASK_LEN 8 -#define RT_SDHCI_DIV_HI_MASK 0x300 -#define RT_SDHCI_PROG_CLOCK_MODE 0x0020 -#define RT_SDHCI_CLOCK_CARD_EN 0x0004 -#define RT_SDHCI_CLOCK_PLL_EN 0x0008 -#define RT_SDHCI_CLOCK_INT_STABLE 0x0002 -#define RT_SDHCI_CLOCK_INT_EN 0x0001 - -#define RT_SDHCI_TIMEOUT_CONTROL 0x2E - -#define RT_SDHCI_SOFTWARE_RESET 0x2F -#define RT_SDHCI_RESET_ALL 0x01 -#define RT_SDHCI_RESET_CMD 0x02 -#define RT_SDHCI_RESET_DATA 0x04 - -#define RT_SDHCI_INT_STATUS 0x30 -#define RT_SDHCI_INT_ENABLE 0x34 -#define RT_SDHCI_SIGNAL_ENABLE 0x38 -#define RT_SDHCI_INT_RESPONSE 0x00000001 -#define RT_SDHCI_INT_DATA_END 0x00000002 -#define RT_SDHCI_INT_BLK_GAP 0x00000004 -#define RT_SDHCI_INT_DMA_END 0x00000008 -#define RT_SDHCI_INT_SPACE_AVAIL 0x00000010 -#define RT_SDHCI_INT_DATA_AVAIL 0x00000020 -#define RT_SDHCI_INT_CARD_INSERT 0x00000040 -#define RT_SDHCI_INT_CARD_REMOVE 0x00000080 -#define RT_SDHCI_INT_CARD_INT 0x00000100 -#define RT_SDHCI_INT_RETUNE 0x00001000 -#define RT_SDHCI_INT_CQE 0x00004000 -#define RT_SDHCI_INT_ERROR 0x00008000 -#define RT_SDHCI_INT_TIMEOUT 0x00010000 -#define RT_SDHCI_INT_CRC 0x00020000 -#define RT_SDHCI_INT_END_BIT 0x00040000 -#define RT_SDHCI_INT_INDEX 0x00080000 -#define RT_SDHCI_INT_DATA_TIMEOUT 0x00100000 -#define RT_SDHCI_INT_DATA_CRC 0x00200000 -#define RT_SDHCI_INT_DATA_END_BIT 0x00400000 -#define RT_SDHCI_INT_BUS_POWER 0x00800000 -#define RT_SDHCI_INT_AUTO_CMD_ERR 0x01000000 -#define RT_SDHCI_INT_ADMA_ERROR 0x02000000 - -#define RT_SDHCI_INT_NORMAL_MASK 0x00007FFF -#define RT_SDHCI_INT_ERROR_MASK 0xFFFF8000 - -#define RT_SDHCI_INT_CMD_MASK (RT_SDHCI_INT_RESPONSE | RT_SDHCI_INT_TIMEOUT | RT_SDHCI_INT_CRC | RT_SDHCI_INT_END_BIT | RT_SDHCI_INT_INDEX | RT_SDHCI_INT_AUTO_CMD_ERR) -#define RT_SDHCI_INT_DATA_MASK (RT_SDHCI_INT_DATA_END | RT_SDHCI_INT_DMA_END | RT_SDHCI_INT_DATA_AVAIL | RT_SDHCI_INT_SPACE_AVAIL | RT_SDHCI_INT_DATA_TIMEOUT | RT_SDHCI_INT_DATA_CRC | RT_SDHCI_INT_DATA_END_BIT | RT_SDHCI_INT_ADMA_ERROR | RT_SDHCI_INT_BLK_GAP) -#define RT_SDHCI_INT_ALL_MASK ((unsigned int)-1) - -#define RT_SDHCI_CQE_INT_ERR_MASK ( \ - RT_SDHCI_INT_ADMA_ERROR | RT_SDHCI_INT_BUS_POWER | RT_SDHCI_INT_DATA_END_BIT | RT_SDHCI_INT_DATA_CRC | RT_SDHCI_INT_DATA_TIMEOUT | RT_SDHCI_INT_INDEX | RT_SDHCI_INT_END_BIT | RT_SDHCI_INT_CRC | RT_SDHCI_INT_TIMEOUT) - -#define RT_SDHCI_CQE_INT_MASK (RT_SDHCI_CQE_INT_ERR_MASK | RT_SDHCI_INT_CQE) - -#define RT_SDHCI_AUTO_CMD_STATUS 0x3C -#define RT_SDHCI_AUTO_CMD_TIMEOUT 0x00000002 -#define RT_SDHCI_AUTO_CMD_CRC 0x00000004 -#define RT_SDHCI_AUTO_CMD_END_BIT 0x00000008 -#define RT_SDHCI_AUTO_CMD_INDEX 0x00000010 - -#define RT_SDHCI_HOST_CONTROL2 0x3E -#define RT_SDHCI_CTRL_UHS_MASK 0x0007 -#define RT_SDHCI_CTRL_UHS_SDR12 0x0000 -#define RT_SDHCI_CTRL_UHS_SDR25 0x0001 -#define RT_SDHCI_CTRL_UHS_SDR50 0x0002 -#define RT_SDHCI_CTRL_UHS_SDR104 0x0003 -#define RT_SDHCI_CTRL_UHS_DDR50 0x0004 -#define RT_SDHCI_CTRL_HS400 0x0005 /* Non-standard */ -#define RT_SDHCI_CTRL_VDD_180 0x0008 -#define RT_SDHCI_CTRL_DRV_TYPE_MASK 0x0030 -#define RT_SDHCI_CTRL_DRV_TYPE_B 0x0000 -#define RT_SDHCI_CTRL_DRV_TYPE_A 0x0010 -#define RT_SDHCI_CTRL_DRV_TYPE_C 0x0020 -#define RT_SDHCI_CTRL_DRV_TYPE_D 0x0030 -#define RT_SDHCI_CTRL_EXEC_TUNING 0x0040 -#define RT_SDHCI_CTRL_TUNED_CLK 0x0080 -#define RT_SDHCI_CMD23_ENABLE 0x0800 -#define RT_SDHCI_CTRL_V4_MODE 0x1000 -#define RT_SDHCI_CTRL_64BIT_ADDR 0x2000 -#define RT_SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000 - -#define RT_SDHCI_CAPABILITIES 0x40 -#define RT_SDHCI_TIMEOUT_CLK_MASK RT_GENMASK(5, 0) -#define RT_SDHCI_TIMEOUT_CLK_SHIFT 0 -#define RT_SDHCI_TIMEOUT_CLK_UNIT 0x00000080 -#define RT_SDHCI_CLOCK_BASE_MASK RT_GENMASK(13, 8) -#define RT_SDHCI_CLOCK_BASE_SHIFT 8 -#define RT_SDHCI_CLOCK_V3_BASE_MASK RT_GENMASK(15, 8) -#define RT_SDHCI_MAX_BLOCK_MASK 0x00030000 -#define RT_SDHCI_MAX_BLOCK_SHIFT 16 -#define RT_SDHCI_CAN_DO_8BIT 0x00040000 -#define RT_SDHCI_CAN_DO_ADMA2 0x00080000 -#define RT_SDHCI_CAN_DO_ADMA1 0x00100000 -#define RT_SDHCI_CAN_DO_HISPD 0x00200000 -#define RT_SDHCI_CAN_DO_SDMA 0x00400000 -#define RT_SDHCI_CAN_DO_SUSPEND 0x00800000 -#define RT_SDHCI_CAN_VDD_330 0x01000000 -#define RT_SDHCI_CAN_VDD_300 0x02000000 -#define RT_SDHCI_CAN_VDD_180 0x04000000 -#define RT_SDHCI_CAN_64BIT_V4 0x08000000 -#define RT_SDHCI_CAN_64BIT 0x10000000 - -#define RT_SDHCI_CAPABILITIES_1 0x44 -#define RT_SDHCI_SUPPORT_SDR50 0x00000001 -#define RT_SDHCI_SUPPORT_SDR104 0x00000002 -#define RT_SDHCI_SUPPORT_DDR50 0x00000004 -#define RT_SDHCI_DRIVER_TYPE_A 0x00000010 -#define RT_SDHCI_DRIVER_TYPE_C 0x00000020 -#define RT_SDHCI_DRIVER_TYPE_D 0x00000040 -#define RT_SDHCI_RETUNING_TIMER_COUNT_MASK RT_GENMASK(11, 8) -#define RT_SDHCI_USE_SDR50_TUNING 0x00002000 -#define RT_SDHCI_RETUNING_MODE_MASK RT_GENMASK(15, 14) -#define RT_SDHCI_CLOCK_MUL_MASK RT_GENMASK(23, 16) -#define RT_SDHCI_CAN_DO_ADMA3 0x08000000 -#define RT_SDHCI_SUPPORT_HS400 0x80000000 /* Non-standard */ - -#define RT_SDHCI_MAX_CURRENT 0x48 -#define RT_SDHCI_MAX_CURRENT_LIMIT RT_GENMASK(7, 0) -#define RT_SDHCI_MAX_CURRENT_330_MASK RT_GENMASK(7, 0) -#define RT_SDHCI_MAX_CURRENT_300_MASK RT_GENMASK(15, 8) -#define RT_SDHCI_MAX_CURRENT_180_MASK RT_GENMASK(23, 16) -#define RT_SDHCI_MAX_CURRENT_MULTIPLIER 4 - -/* 4C-4F reserved for more max current */ - -#define RT_SDHCI_SET_ACMD12_ERROR 0x50 -#define RT_SDHCI_SET_INT_ERROR 0x52 - -#define RT_SDHCI_ADMA_ERROR 0x54 - -/* 55-57 reserved */ - -#define RT_SDHCI_ADMA_ADDRESS 0x58 -#define RT_SDHCI_ADMA_ADDRESS_HI 0x5C - -/* 60-FB reserved */ - -#define RT_SDHCI_PRESET_FOR_HIGH_SPEED 0x64 -#define RT_SDHCI_PRESET_FOR_SDR12 0x66 -#define RT_SDHCI_PRESET_FOR_SDR25 0x68 -#define RT_SDHCI_PRESET_FOR_SDR50 0x6A -#define RT_SDHCI_PRESET_FOR_SDR104 0x6C -#define RT_SDHCI_PRESET_FOR_DDR50 0x6E -#define RT_SDHCI_PRESET_FOR_HS400 0x74 /* Non-standard */ -#define RT_SDHCI_PRESET_DRV_MASK RT_GENMASK(15, 14) -#define BIT(nr) ((1) << (nr)) - -#define RT_SDHCI_PRESET_CLKGEN_SEL BIT(10) -#define RT_SDHCI_PRESET_SDCLK_FREQ_MASK RT_GENMASK(9, 0) - -#define RT_SDHCI_SLOT_INT_STATUS 0xFC - -#define RT_SDHCI_HOST_VERSION 0xFE -#define RT_SDHCI_VENDOR_VER_MASK 0xFF00 -#define RT_SDHCI_VENDOR_VER_SHIFT 8 -#define RT_SDHCI_SPEC_VER_MASK 0x00FF -#define RT_SDHCI_SPEC_VER_SHIFT 0 -#define RT_SDHCI_SPEC_100 0 -#define RT_SDHCI_SPEC_200 1 -#define RT_SDHCI_SPEC_300 2 -#define RT_SDHCI_SPEC_400 3 -#define RT_SDHCI_SPEC_410 4 -#define RT_SDHCI_SPEC_420 5 - -/* - * End of controller registers. - */ - -#define RT_SDHCI_MAX_DIV_SPEC_200 256 -#define RT_SDHCI_MAX_DIV_SPEC_300 2046 - -/* - * Host SDMA buffer boundary. Valid values from 4K to 512K in powers of 2. - */ -#define RT_SDHCI_DEFAULT_BOUNDARY_SIZE (512 * 1024) -#define ilog2(v) __rt_ffs(v) -#define RT_SDHCI_DEFAULT_BOUNDARY_ARG (ilog2(RT_SDHCI_DEFAULT_BOUNDARY_SIZE) - 12) -#define RT_SDHCI_MAX_SEGS 128 - -/* Allow for a command request and a data request at the same time */ -#define RT_SDHCI_MAX_MRQS 2 -#define MMC_CMD_TRANSFER_TIME (10 * 1000000L) /* max 10 ms */ - - -enum rt_sdhci_cookie -{ - COOKIE_UNMAPPED, - COOKIE_PRE_MAPPED, /* mapped by sdhci_pre_req() */ - COOKIE_MAPPED, /* mapped by sdhci_prepare_data() */ -}; - -struct rt_sdhci_host -{ - const char *hw_name; /* Hardware bus name */ - - unsigned int quirks; /* Deviations from spec. */ - - void *data_buf; -/* Controller doesn't honor resets unless we touch the clock register */ -#define RT_SDHCI_QUIRK_CLOCK_BEFORE_RESET (1 << 0) -/* Controller has bad caps bits, but really supports DMA */ -#define RT_SDHCI_QUIRK_FORCE_DMA (1 << 1) -/* Controller doesn't like to be reset when there is no card inserted. */ -#define RT_SDHCI_QUIRK_NO_CARD_NO_RESET (1 << 2) -/* Controller doesn't like clearing the power reg before a change */ -#define RT_SDHCI_QUIRK_SINGLE_POWER_WRITE (1 << 3) -/* Controller has an unusable DMA engine */ -#define RT_SDHCI_QUIRK_BROKEN_DMA (1 << 5) -/* Controller has an unusable ADMA engine */ -#define RT_SDHCI_QUIRK_BROKEN_ADMA (1 << 6) -/* Controller can only DMA from 32-bit aligned addresses */ -#define RT_SDHCI_QUIRK_32BIT_DMA_ADDR (1 << 7) -/* Controller can only DMA chunk sizes that are a multiple of 32 bits */ -#define RT_SDHCI_QUIRK_32BIT_DMA_SIZE (1 << 8) -/* Controller can only ADMA chunks that are a multiple of 32 bits */ -#define RT_SDHCI_QUIRK_32BIT_ADMA_SIZE (1 << 9) -/* Controller needs to be reset after each request to stay stable */ -#define RT_SDHCI_QUIRK_RESET_AFTER_REQUEST (1 << 10) -/* Controller needs voltage and power writes to happen separately */ -#define RT_SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1 << 11) -/* Controller provides an incorrect timeout value for transfers */ -#define RT_SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1 << 12) -/* Controller has an issue with buffer bits for small transfers */ -#define RT_SDHCI_QUIRK_BROKEN_SMALL_PIO (1 << 13) -/* Controller does not provide transfer-complete interrupt when not busy */ -#define RT_SDHCI_QUIRK_NO_BUSY_IRQ (1 << 14) -/* Controller has unreliable card detection */ -#define RT_SDHCI_QUIRK_BROKEN_CARD_DETECTION (1 << 15) -/* Controller reports inverted write-protect state */ -#define RT_SDHCI_QUIRK_INVERTED_WRITE_PROTECT (1 << 16) -/* Controller has unusable command queue engine */ -#define RT_SDHCI_QUIRK_BROKEN_CQE (1 << 17) -/* Controller does not like fast PIO transfers */ -#define RT_SDHCI_QUIRK_PIO_NEEDS_DELAY (1 << 18) -/* Controller does not have a LED */ -#define RT_SDHCI_QUIRK_NO_LED (1 << 19) -/* Controller has to be forced to use block size of 2048 bytes */ -#define RT_SDHCI_QUIRK_FORCE_BLK_SZ_2048 (1 << 20) -/* Controller cannot do multi-block transfers */ -#define RT_SDHCI_QUIRK_NO_MULTIBLOCK (1 << 21) -/* Controller can only handle 1-bit data transfers */ -#define RT_SDHCI_QUIRK_FORCE_1_BIT_DATA (1 << 22) -/* Controller needs 10ms delay between applying power and clock */ -#define RT_SDHCI_QUIRK_DELAY_AFTER_POWER (1 << 23) -/* Controller uses SDCLK instead of TMCLK for data timeouts */ -#define RT_SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK (1 << 24) -/* Controller reports wrong base clock capability */ -#define RT_SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN (1 << 25) -/* Controller cannot support End Attribute in NOP ADMA descriptor */ -#define RT_SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC (1 << 26) -/* Controller uses Auto CMD12 command to stop the transfer */ -#define RT_SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 (1 << 28) -/* Controller doesn't have HISPD bit field in HI-SPEED SD card */ -#define RT_SDHCI_QUIRK_NO_HISPD_BIT (1 << 29) -/* Controller treats ADMA descriptors with length 0000h incorrectly */ -#define RT_SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC (1 << 30) -/* The read-only detection via RT_SDHCI_PRESENT_STATE register is unstable */ -#define RT_SDHCI_QUIRK_UNSTABLE_RO_DETECT (1 << 31) - - unsigned int quirks2; /* More deviations from spec. */ - -#define RT_SDHCI_QUIRK2_HOST_OFF_CARD_ON (1 << 0) -#define RT_SDHCI_QUIRK2_HOST_NO_CMD23 (1 << 1) -/* The system physically doesn't support 1.8v, even if the host does */ -#define RT_SDHCI_QUIRK2_NO_1_8_V (1 << 2) -#define RT_SDHCI_QUIRK2_PRESET_VALUE_BROKEN (1 << 3) -#define RT_SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON (1 << 4) -/* Controller has a non-standard host control register */ -#define RT_SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1 << 5) -/* Controller does not support HS200 */ -#define RT_SDHCI_QUIRK2_BROKEN_HS200 (1 << 6) -/* Controller does not support DDR50 */ -#define RT_SDHCI_QUIRK2_BROKEN_DDR50 (1 << 7) -/* Stop command (CMD12) can set Transfer Complete when not using MMC_RSP_BUSY */ -#define RT_SDHCI_QUIRK2_STOP_WITH_TC (1 << 8) -/* Controller does not support 64-bit DMA */ -#define RT_SDHCI_QUIRK2_BROKEN_64_BIT_DMA (1 << 9) -/* need clear transfer mode register before send cmd */ -#define RT_SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD (1 << 10) -/* Capability register bit-63 indicates HS400 support */ -#define RT_SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 (1 << 11) -/* forced tuned clock */ -#define RT_SDHCI_QUIRK2_TUNING_WORK_AROUND (1 << 12) -/* disable the block count for single block transactions */ -#define RT_SDHCI_QUIRK2_SUPPORT_SINGLE (1 << 13) -/* Controller broken with using ACMD23 */ -#define RT_SDHCI_QUIRK2_ACMD23_BROKEN (1 << 14) -/* Broken Clock divider zero in controller */ -#define RT_SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1 << 15) -/* Controller has CRC in 136 bit Command Response */ -#define RT_SDHCI_QUIRK2_RSP_136_HAS_CRC (1 << 16) - -#define RT_SDHCI_QUIRK2_DISABLE_HW_TIMEOUT (1 << 17) - -#define RT_SDHCI_QUIRK2_USE_32BIT_BLK_CNT (1 << 18) -/* Issue CMD and DATA reset together */ -#define RT_SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER (1 << 19) - - int irq; /* Device IRQ */ - void *ioaddr; /* Mapped address */ - char *bounce_buffer; /* For packing SDMA reads/writes */ - rt_uint64_t bounce_addr; - unsigned int bounce_buffer_size; - - const struct rt_sdhci_ops *ops; /* Low level hw interface */ - - /* Internal data */ - struct rt_mmc_host *mmc; /* MMC structure */ - struct mmc_host_ops mmc_host_ops; /* MMC host ops */ - rt_uint64_t dma_mask; /* custom DMA mask */ - - rt_spinlock_t lock; - int flags; /* Host attributes */ -#define RT_SDHCI_USE_SDMA (1 << 0) /* Host is SDMA capable */ -#define RT_SDHCI_USE_ADMA (1 << 1) /* Host is ADMA capable */ -#define RT_SDHCI_REQ_USE_DMA (1 << 2) /* Use DMA for this req. */ -#define RT_SDHCI_DEVICE_DEAD (1 << 3) /* Device unresponsive */ -#define RT_SDHCI_SDR50_NEEDS_TUNING (1 << 4) /* SDR50 needs tuning */ -#define RT_SDHCI_AUTO_CMD12 (1 << 6) /* Auto CMD12 support */ -#define RT_SDHCI_AUTO_CMD23 (1 << 7) /* Auto CMD23 support */ -#define RT_SDHCI_PV_ENABLED (1 << 8) /* Preset value enabled */ -#define RT_SDHCI_USE_64_BIT_DMA (1 << 12) /* Use 64-bit DMA */ -#define RT_SDHCI_HS400_TUNING (1 << 13) /* Tuning for HS400 */ -#define RT_SDHCI_SIGNALING_330 (1 << 14) /* Host is capable of 3.3V signaling */ -#define RT_SDHCI_SIGNALING_180 (1 << 15) /* Host is capable of 1.8V signaling */ -#define RT_SDHCI_SIGNALING_120 (1 << 16) /* Host is capable of 1.2V signaling */ - - unsigned int version; /* RT_SDHCI spec. version */ - - unsigned int max_clk; /* Max possible freq (MHz) */ - unsigned int timeout_clk; /* Timeout freq (KHz) */ - rt_uint8_t max_timeout_count; /* Vendor specific max timeout count */ - unsigned int clk_mul; /* Clock Muliplier value */ - - unsigned int clock; /* Current clock (MHz) */ - rt_uint8_t pwr; /* Current voltage */ - rt_uint8_t drv_type; /* Current UHS-I driver type */ - rt_bool_t reinit_uhs; /* Force UHS-related re-initialization */ - - rt_bool_t runtime_suspended; /* Host is runtime suspended */ - rt_bool_t bus_on; /* Bus power prevents runtime suspend */ - rt_bool_t preset_enabled; /* Preset is enabled */ - rt_bool_t pending_reset; /* Cmd/data reset is pending */ - rt_bool_t irq_wake_enabled; /* IRQ wakeup is enabled */ - rt_bool_t v4_mode; /* Host Version 4 Enable */ - rt_bool_t always_defer_done; /* Always defer to complete requests */ - - struct rt_mmcsd_req *mrqs_done[RT_SDHCI_MAX_MRQS]; /* Requests done */ - struct rt_mmcsd_cmd *cmd; /* Current command */ - struct rt_mmcsd_cmd *data_cmd; /* Current data command */ - struct rt_mmcsd_cmd *deferred_cmd; /* Deferred command */ - struct rt_mmcsd_data *data; /* Current data request */ - unsigned int data_early : 1; /* Data finished before cmd */ - - unsigned int blocks; /* remaining PIO blocks */ - size_t align_buffer_sz; /* Bounce buffer size */ - rt_uint64_t align_addr; /* Mapped bounce buffer */ - - struct rt_workqueue *complete_wq; /* Request completion wq */ - struct rt_work complete_work; /* Request completion work */ - - struct rt_workqueue *irq_wq; - struct rt_work irq_work; - - struct rt_timer timer; /* Timer for timeouts */ - struct rt_timer data_timer; /* Timer for data timeouts */ - - rt_uint32_t caps; /* CAPABILITY_0 */ - rt_uint32_t caps1; /* CAPABILITY_1 */ - rt_bool_t read_caps; /* Capability flags have been read */ - - rt_bool_t sdhci_core_to_disable_vqmmc; /* sdhci core can disable vqmmc */ - unsigned int ocr_avail_sdio; /* OCR bit masks */ - unsigned int ocr_avail_sd; - unsigned int ocr_avail_mmc; - rt_uint32_t ocr_mask; /* available voltages */ - - unsigned timing; /* Current timing */ - - rt_uint32_t thread_isr; - - /* cached registers */ - rt_uint32_t ier; - - rt_bool_t cqe_on; /* CQE is operating */ - rt_uint32_t cqe_ier; /* CQE interrupt mask */ - rt_uint32_t cqe_err_ier; /* CQE error interrupt mask */ - - rt_wqueue_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */ - unsigned int tuning_done; /* Condition flag set when CMD19 succeeds */ - - unsigned int tuning_count; /* Timer count for re-tuning */ - unsigned int tuning_mode; /* Re-tuning mode supported by host */ - unsigned int tuning_err; /* Error code for re-tuning */ -#define RT_SDHCI_TUNING_MODE_1 0 -#define RT_SDHCI_TUNING_MODE_2 1 -#define RT_SDHCI_TUNING_MODE_3 2 - /* Delay (ms) between tuning commands */ - int tuning_delay; - int tuning_loop_count; - - /* Host SDMA buffer boundary. */ - rt_uint32_t sdma_boundary; - rt_uint64_t data_timeout; - - unsigned long private[]; -}; - -static inline rt_uint8_t u8_read(const volatile void *addr) -{ - return *(const volatile rt_uint8_t *)addr; -} - -static inline rt_uint16_t u16_read(const volatile void *addr) -{ - return *(const volatile rt_uint16_t *)addr; -} - -static inline rt_uint32_t u32_read(const volatile void *addr) -{ - return *(const volatile rt_uint32_t *)addr; -} - -static inline void u8_write(rt_uint8_t value, volatile void *addr) -{ - *(volatile rt_uint8_t *)addr = value; -} - -static inline void u16_write(rt_uint16_t value, volatile void *addr) -{ - *(volatile rt_uint16_t *)addr = value; -} - -static inline void u32_write(rt_uint32_t value, volatile void *addr) -{ - *(volatile rt_uint32_t *)addr = value; -} - -#define readb(c) u8_read(c) -#define readw(c) u16_read(c) -#define readl(c) u32_read(c) -#define readsb(p, d, l) ({ __raw_readsb(p,d,l); __iormb(); }) -#define readsw(p, d, l) ({ __raw_readsw(p,d,l); __iormb(); }) -#define readsl(p, d, l) ({ __raw_readsl(p,d,l); __iormb(); }) - -#define writeb(v, c) u8_write(v, c) -#define writew(v, c) u16_write(v, c) -#define writel(v, c) u32_write(v, c) -#define writesb(p, d, l) ({ __iowmb(); __raw_writesb(p,d,l); }) -#define writesw(p, d, l) ({ __iowmb(); __raw_writesw(p,d,l); }) -#define writesl(p, d, l) ({ __iowmb(); __raw_writesl(p,d,l); }) - -static inline void rt_sdhci_writel(struct rt_sdhci_host *host, rt_uint32_t val, int reg) -{ - writel(val, host->ioaddr + reg); -} - -static inline void rt_sdhci_writew(struct rt_sdhci_host *host, rt_uint16_t val, int reg) -{ - writew(val, host->ioaddr + reg); -} - -static inline void rt_sdhci_writeb(struct rt_sdhci_host *host, rt_uint8_t val, int reg) -{ - writeb(val, host->ioaddr + reg); -} - -static inline rt_uint32_t rt_sdhci_readl(struct rt_sdhci_host *host, int reg) -{ - return readl(host->ioaddr + reg); -} - -static inline rt_uint16_t rt_sdhci_readw(struct rt_sdhci_host *host, int reg) -{ - return readw(host->ioaddr + reg); -} - -static inline rt_uint8_t rt_sdhci_readb(struct rt_sdhci_host *host, int reg) -{ - return readb(host->ioaddr + reg); -} - - -struct rt_sdhci_ops -{ - void (*set_clock)(struct rt_sdhci_host *host, unsigned int clock); - void (*set_power)(struct rt_sdhci_host *host, unsigned char mode, - unsigned short vdd); - rt_uint32_t (*irq)(struct rt_sdhci_host *host, rt_uint32_t intmask); - int (*set_dma_mask)(struct rt_sdhci_host *host); - int (*enable_dma)(struct rt_sdhci_host *host); - unsigned int (*get_max_clock)(struct rt_sdhci_host *host); - unsigned int (*get_min_clock)(struct rt_sdhci_host *host); - unsigned int (*get_timeout_clock)(struct rt_sdhci_host *host); - unsigned int (*get_max_timeout_count)(struct rt_sdhci_host *host); - void (*set_timeout)(struct rt_sdhci_host *host, - struct rt_mmcsd_cmd *cmd); - void (*set_bus_width)(struct rt_sdhci_host *host, int width); - unsigned int (*get_ro)(struct rt_sdhci_host *host); - void (*reset)(struct rt_sdhci_host *host, rt_uint8_t mask); - int (*platform_execute_tuning)(struct rt_sdhci_host *host, rt_uint32_t opcode); - void (*set_uhs_signaling)(struct rt_sdhci_host *host, unsigned int uhs); - void (*hw_reset)(struct rt_sdhci_host *host); - void (*card_event)(struct rt_sdhci_host *host); - void (*voltage_switch)(struct rt_sdhci_host *host); - void (*request_done)(struct rt_sdhci_host *host, - struct rt_mmcsd_req *mrq); -}; - - -struct rt_sdhci_host *rt_sdhci_alloc_host(struct rt_device *dev, size_t priv_size); -void rt_sdhci_free_host(struct rt_sdhci_host *host); - -static inline void *sdhci_priv(struct rt_sdhci_host *host) -{ - return host->private; -} - -void rt_sdhci_read_caps(struct rt_sdhci_host *host, const rt_uint16_t *ver, - const rt_uint32_t *caps, const rt_uint32_t *caps1); -int rt_sdhci_setup_host(struct rt_sdhci_host *host); -void rt_sdhci_cleanup_host(struct rt_sdhci_host *host); -int rt_sdhci_set_and_add_host(struct rt_sdhci_host *host); -int rt_sdhci_init_host(struct rt_sdhci_host *host); -void rt_sdhci_uninit_host(struct rt_sdhci_host *host, int dead); - -rt_uint16_t rt_sdhci_clk_set(struct rt_sdhci_host *host, unsigned int clock, - unsigned int *actual_clock); -void rt_sdhci_set_clock(struct rt_sdhci_host *host, unsigned int clock); -void rt_sdhci_clk_enable(struct rt_sdhci_host *host, rt_uint16_t clk); -void rt_sdhci_set_power(struct rt_sdhci_host *host, unsigned char mode,unsigned short vdd); -void rt_read_reg(struct rt_sdhci_host* host); - -void rt_sdhci_set_power_with_noreg(struct rt_sdhci_host *host, unsigned char mode, - unsigned short vdd); -void rt_sdhci_start_request(struct rt_mmc_host *mmc, struct rt_mmcsd_req *mrq); -int rt_sdhci_start_request_atomic(struct rt_mmc_host *mmc, struct rt_mmcsd_req *mrq); -void rt_sdhci_set_bus_width(struct rt_sdhci_host *host, int width); -void rt_sdhci_reset(struct rt_sdhci_host *host, rt_uint8_t mask); -void rt_sdhci_set_uhs(struct rt_sdhci_host *host, unsigned timing); -int rt_sdhci_execute_tuning(struct rt_mmc_host *mmc, rt_uint32_t opcode); -int __sdhci_execute_tuning(struct rt_sdhci_host *host, rt_uint32_t opcode); -void rt_sdhci_ios_set(struct rt_mmc_host *mmc, struct rt_mmcsd_io_cfg *ios); -int rt_sdhci_start_signal_voltage_switch(struct rt_mmc_host *mmc, - struct rt_mmcsd_io_cfg *ios); -void rt_sdhci_enable_io_irq(struct rt_mmc_host *mmc, int enable); -void rt_sdhci_start_tuning(struct rt_sdhci_host *host); -void rt_sdhci_end_tuning(struct rt_sdhci_host *host); -void rt_sdhci_reset_tuning(struct rt_sdhci_host *host); -void rt_sdhci_send_tuning(struct rt_sdhci_host *host, rt_uint32_t opcode); -void rt_sdhci_abort_tuning(struct rt_sdhci_host *host, rt_uint32_t opcode); -void rt_sdhci_data_irq_timeout(struct rt_sdhci_host *host, rt_bool_t enable); -void rt_sdhci_timeout_set(struct rt_sdhci_host *host, struct rt_mmcsd_cmd *cmd); -void rt_read_reg_debug(struct rt_sdhci_host* host); - -#endif /* __RT_SDHCI_HW_H */ diff --git a/rt-thread/components/drivers/sdio/sdhci/include/sdhci_host.h b/rt-thread/components/drivers/sdio/sdhci/include/sdhci_host.h deleted file mode 100644 index 8584ab4..0000000 --- a/rt-thread/components/drivers/sdio/sdhci/include/sdhci_host.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-08-16 zhujiale first version - */ -#ifndef __RT_SDHCI_MMC_H__ -#define __RT_SDHCI_MMC_H__ - -#include -#include -#include -#include -#include -#define mmc_dev(x) ((x)->parent) - -#define MMC_SEND_TUNING_BLOCK_HS200 SEND_TUNING_BLOCK_HS200 -#define MMC_SEND_TUNING_BLOCK SEND_TUNING_BLOCK -#define MMC_STOP_TRANSMISSION STOP_TRANSMISSION -#define MMC_BUS_TEST_R 14 /* adtc R1 */ -#define MMC_WRITE_MULTIPLE_BLOCK WRITE_MULTIPLE_BLOCK -#define MMC_READ_MULTIPLE_BLOCK READ_MULTIPLE_BLOCK - -#define MMC_TIMING_UHS_DDR50 MMCSD_TIMING_UHS_DDR50 -#define MMC_TIMING_UHS_SDR50 MMCSD_TIMING_UHS_SDR50 -#define MMC_TIMING_MMC_HS200 MMCSD_TIMING_MMC_HS200 -#define MMC_TIMING_MMC_HS400 MMCSD_TIMING_MMC_HS400 -#define MMC_TIMING_UHS_SDR104 MMCSD_TIMING_UHS_SDR104 -#define MMC_TIMING_UHS_SDR25 MMCSD_TIMING_UHS_SDR25 -#define MMC_TIMING_MMC_DDR52 MMCSD_TIMING_MMC_DDR52 -#define MMC_TIMING_UHS_SDR12 MMCSD_TIMING_UHS_SDR12 -#define MMC_TIMING_SD_HS MMCSD_TIMING_SD_HS -#define MMC_TIMING_MMC_HS MMCSD_TIMING_MMC_HS - -#define MMC_POWER_OFF MMCSD_POWER_OFF -#define MMC_POWER_UP MMCSD_POWER_UP -#define MMC_POWER_ON MMCSD_POWER_ON -#define MMC_POWER_UNDEFINED 3 - -#define MMC_SET_DRIVER_TYPE_B 0 -#define MMC_SET_DRIVER_TYPE_A 1 -#define MMC_SET_DRIVER_TYPE_C 2 -#define MMC_SET_DRIVER_TYPE_D 3 - -#define MMC_SIGNAL_VOLTAGE_330 0 -#define MMC_SIGNAL_VOLTAGE_180 1 -#define MMC_SIGNAL_VOLTAGE_120 2 - -#define MMC_RSP_PRESENT (1 << 16) -#define MMC_RSP_136 (1 << 17) /* 136 bit response */ -#define MMC_RSP_CRC (1 << 18) /* expect valid crc */ -#define MMC_RSP_BUSY (1 << 19) /* card may send busy */ -#define MMC_RSP_OPCODE (1 << 20) /* response contains opcode */ - -#define MMC_RSP_NONE (0) -#define MMC_RSP_R1 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) -#define MMC_RSP_R1B (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY) -#define MMC_RSP_R2 (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC) -#define MMC_RSP_R3 (MMC_RSP_PRESENT) -#define MMC_RSP_R4 (MMC_RSP_PRESENT) -#define MMC_RSP_R5 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) -#define MMC_RSP_R6 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) -#define MMC_RSP_R7 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE) - -#define MMC_CMD_ADTC CMD_ADTC - -#define MMC_BUS_WIDTH_8 MMCSD_BUS_WIDTH_8 -#define MMC_BUS_WIDTH_4 MMCSD_BUS_WIDTH_4 -#define MMC_BUS_WIDTH_1 MMCSD_BUS_WIDTH_1 - -#define MMC_PM_KEEP_POWER (1 << 0) /* preserve card power during suspend */ -#define MMC_PM_WAKE_SDIO_IRQ (1 << 1) /* wake up host system on SDIO IRQ assertion */ -enum mmc_blk_status -{ - MMC_BLK_SUCCESS = 0, - MMC_BLK_PARTIAL, - MMC_BLK_CMD_ERR, - MMC_BLK_RETRY, - MMC_BLK_ABORT, - MMC_BLK_DATA_ERR, - MMC_BLK_ECC_ERR, - MMC_BLK_NOMEDIUM, - MMC_BLK_NEW_REQUEST, -}; - -#define MMC_NUM_CLK_PHASES (MMC_TIMING_MMC_HS400 + 1) - -struct rt_mmc_host ; - -struct mmc_host_ops -{ - void (*request)(struct rt_mmc_host *host, struct rt_mmcsd_req *req); - void (*set_ios)(struct rt_mmc_host *host, struct rt_mmcsd_io_cfg *ios); - int (*get_ro)(struct rt_mmc_host *host); - int (*get_cd)(struct rt_mmc_host *host); - void (*enable_sdio_irq)(struct rt_mmc_host *host, int enable); - void (*ack_sdio_irq)(struct rt_mmc_host *host); - int (*start_signal_voltage_switch)(struct rt_mmc_host *host, struct rt_mmcsd_io_cfg *ios); - int (*card_busy)(struct rt_mmc_host *host); - int (*execute_tuning)(struct rt_mmc_host *host, unsigned opcode); - int (*prepare_hs400_tuning)(struct rt_mmc_host *host, struct rt_mmcsd_io_cfg *ios); - int (*hs400_prepare_ddr)(struct rt_mmc_host *host); - void (*hs400_downgrade)(struct rt_mmc_host *host); - void (*hs400_complete)(struct rt_mmc_host *host); - void (*hs400_enhanced_strobe)(struct rt_mmc_host *host, - struct rt_mmcsd_io_cfg* ios); - void (*hw_reset)(struct rt_mmc_host* host); - void (*card_event)(struct rt_mmc_host* host); -}; - -struct regulator; -struct mmc_pwrseq; - -struct mmc_supply -{ - struct regulator *vmmc; /* Card power supply */ - struct regulator *vqmmc; /* Optional Vccq supply */ -}; - -struct mmc_ctx -{ - struct task_struct *task; -}; - -/* VDD voltage 3.3 ~ 3.4 */ -#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ -#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ - -#define MMC_CAP2_HS200_1_8V_SDR MMCSD_SUP_HS200_1V8 -#define MMC_CAP_4_BIT_DATA MMCSD_BUSWIDTH_4 -#define MMC_CAP_8_BIT_DATA MMCSD_BUSWIDTH_8 -#define MMC_CAP2_HS200 MMCSD_SUP_HS200 -#define MMC_CAP_MMC_HIGHSPEED MMCSD_SUP_HIGHSPEED -#define MMC_CAP_SD_HIGHSPEED MMCSD_SUP_HIGHSPEED -#define MMC_CAP_1_8V_DDR MMCSD_SUP_DDR_1V8 -#define MMC_CAP_3_3V_DDR MMCSD_SUP_DDR_3V3 -#define MMC_CAP_1_2V_DDR MMCSD_SUP_DDR_1V2 -#define MMC_CAP_NONREMOVABLE MMCSD_SUP_NONREMOVABLE - - -#define MMC_CAP_UHS_DDR50 0 -#define MMC_CAP2_HS400 0 -#define MMC_CAP_UHS_SDR50 0 -#define MMC_CAP_UHS_SDR25 0 -#define MMC_CAP_UHS_SDR12 0 -#define MMC_CAP_UHS_SDR104 0 -#define MMC_CAP_UHS 0 -#define MMC_CAP2_HSX00_1_8V 0 -#define MMC_CAP2_HS400_ES 0 -#define MMC_CAP_NEEDS_POLL 0 -#define MMC_CAP2_HSX00_1_2V 0 -#define MMC_CAP2_HS400_1_8V 0 -#define MMC_CAP_DRIVER_TYPE_D 0 -#define MMC_CAP_DRIVER_TYPE_C 0 -#define MMC_SET_DRIVER_TYPE_B 0 -#define MMC_CAP_DRIVER_TYPE_A 0 -#define MMC_CAP2_SDIO_IRQ_NOTHREAD 0 -#define MMC_CAP_CMD23 0 -#define MMC_CAP_SDIO_IRQ 0 - -#define MMC_CAP2_NO_SDIO (1 << 19) -#define MMC_CAP2_NO_SD (1 << 21) -#define MMC_CAP2_NO_MMC (1 << 22) -#define MMC_CAP2_CQE (1 << 23) - -#define MMC_VDD_165_195 VDD_165_195 -#define MMC_VDD_20_21 VDD_20_21 -#define MMC_VDD_29_30 VDD_29_30 -#define MMC_VDD_30_31 VDD_30_31 -#define MMC_VDD_32_33 VDD_32_33 -#define MMC_VDD_33_34 VDD_33_34 - - -struct rt_mmc_host -{ - struct rt_mmcsd_host rthost; - struct rt_device *parent; - int index; - const struct mmc_host_ops *ops; - unsigned int f_min; - unsigned int f_max; - unsigned int f_init; - rt_uint32_t ocr_avail; - rt_uint32_t ocr_avail_sdio; /* SDIO-specific OCR */ - rt_uint32_t ocr_avail_sd; /* SD-specific OCR */ - rt_uint32_t ocr_avail_mmc; /* MMC-specific OCR */ - struct wakeup_source *ws; /* Enable consume of uevents */ - rt_uint32_t max_current_330; - rt_uint32_t max_current_300; - rt_uint32_t max_current_180; - rt_uint32_t caps; /* Host capabilities */ - - rt_uint32_t caps2; /* More host capabilities */ - - - /* host specific block data */ - unsigned int max_seg_size; /* see blk_queue_max_segment_size */ - unsigned short max_segs; /* see blk_queue_max_segments */ - unsigned short unused; - unsigned int max_req_size; /* maximum number of bytes in one req */ - unsigned int max_blk_size; /* maximum size of one mmc block */ - unsigned int max_blk_count; /* maximum number of blocks in one req */ - unsigned int max_busy_timeout; /* max busy timeout in ms */ - struct rt_mmcsd_io_cfg ios; /* current io bus settings */ - unsigned int retune_period; - /* group bitfields together to minimize padding */ - unsigned int use_spi_crc : 1; - unsigned int claimed : 1; /* host exclusively claimed */ - unsigned int doing_init_tune : 1; /* initial tuning in progress */ - unsigned int can_retune : 1; /* re-tuning can be used */ - unsigned int doing_retune : 1; /* re-tuning in progress */ - unsigned int retune_now : 1; /* do re-tuning at next req */ - unsigned int retune_paused : 1; /* re-tuning is temporarily disabled */ - unsigned int retune_crc_disable : 1; /* don't trigger retune upon crc */ - unsigned int can_dma_map_merge : 1; /* merging can be used */ - unsigned int vqmmc_enabled : 1; /* vqmmc regulator is enabled */ - - int need_retune; /* re-tuning is needed */ - int hold_retune; /* hold off re-tuning */ - rt_bool_t trigger_card_event; /* card_event necessary */ - unsigned int sdio_irqs; - rt_bool_t sdio_irq_pending; - - struct led_trigger *led; /* activity led */ - - struct mmc_supply supply; - - - /* Ongoing data transfer that allows commands during transfer */ - struct rt_mmcsd_req *ongoing_mrq; - - - unsigned int actual_clock; /* Actual HC clock rate */ - rt_uint32_t pm_caps; - unsigned long private[]; -}; - - -static inline int mmc_card_is_removable(struct rt_mmc_host *host) -{ - return !(host->caps & MMC_CAP_NONREMOVABLE); -} - -struct device_node; -struct rt_mmc_host *rt_mmc_alloc_host(int extra, struct rt_device *); -int rt_mmc_add_host(struct rt_mmc_host *); -void rt_mmc_remove_host(struct rt_mmc_host *); -void rt_mmc_free_host(struct rt_mmc_host *); -int rt_mmc_of_parse(struct rt_mmc_host *host); -int rt_mmc_of_parse_voltage(struct rt_mmc_host *host, rt_uint32_t *mask); - -static inline void *mmc_priv(struct rt_mmc_host *host) -{ - return (void *)host->private; -} - - -#define mmc_host_is_spi(host) ((host)->caps & MMC_CAP_SPI) - -#define mmc_dev(x) ((x)->parent) -#define mmc_classdev(x) (&(x)->class_dev) -#define mmc_hostname(x) (x->parent->parent.name) - -void rt_mmc_detect_change(struct rt_mmc_host *, unsigned long delay); -void rt_mmc_request_done(struct rt_mmc_host *, struct rt_mmcsd_req *); -void mmc_command_done(struct rt_mmc_host *host, struct rt_mmcsd_req *mrq); - -void mmc_cqe_request_done(struct rt_mmc_host *host, struct rt_mmcsd_req *mrq); - -static inline rt_bool_t sdio_irq_claimed(struct rt_mmc_host *host) -{ - return host->sdio_irqs > 0; -} - -static inline int mmc_regulator_set_ocr(struct rt_mmc_host *mmc, - struct regulator *supply, - unsigned short vdd_bit) -{ - return 0; -} - -int mmc_regulator_get_supply(struct rt_mmc_host *mmc); -int mmc_regulator_enable_vqmmc(struct rt_mmc_host *mmc); -void mmc_regulator_disable_vqmmc(struct rt_mmc_host *mmc); - -void mmc_retune_timer_stop(struct rt_mmc_host* host); - -enum dma_data_direction -{ - DMA_BIDIRECTIONAL = 0, - DMA_TO_DEVICE = 1, - DMA_FROM_DEVICE = 2, - DMA_NONE = 3, -}; -#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL << (n)) - 1)) -static inline void mmc_retune_needed(struct rt_mmc_host *host) -{ - if (host->can_retune) - host->need_retune = 1; -} - -static inline rt_bool_t mmc_can_retune(struct rt_mmc_host *host) -{ - return host->can_retune == 1; -} - -static inline rt_bool_t mmc_doing_retune(struct rt_mmc_host *host) -{ - return host->doing_retune == 1; -} - -static inline rt_bool_t mmc_doing_tune(struct rt_mmc_host *host) -{ - return host->doing_retune == 1 || host->doing_init_tune == 1; -} - -static inline int mmc_get_dma_dir(struct rt_mmcsd_data *data) -{ - return data->flags & DATA_DIR_WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE; -} - -static inline rt_bool_t mmc_op_multi(rt_uint32_t opcode) -{ - return opcode == MMC_WRITE_MULTIPLE_BLOCK || opcode == MMC_READ_MULTIPLE_BLOCK; -} - -static inline rt_bool_t mmc_op_tuning(rt_uint32_t opcode) -{ - return opcode == MMC_SEND_TUNING_BLOCK || opcode == MMC_SEND_TUNING_BLOCK_HS200; -} - -int rt_mmc_gpio_get_cd(struct rt_mmc_host *host); -void rt_mmc_detect_change(struct rt_mmc_host *host, unsigned long delay); -int rt_mmc_regulator_set_vqmmc(struct rt_mmc_host *mmc, struct rt_mmcsd_io_cfg *ios); -rt_bool_t rt_mmc_can_gpio_ro(struct rt_mmc_host *host); -int rt_mmc_gpio_get_ro(struct rt_mmc_host *host); - -int rt_mmc_send_abort_tuning(struct rt_mmc_host *host, rt_uint32_t opcode); -int rt_mmc_of_parse(struct rt_mmc_host *host); - - -#endif diff --git a/rt-thread/components/drivers/sdio/sdhci/include/sdhci_misc.h b/rt-thread/components/drivers/sdio/sdhci/include/sdhci_misc.h deleted file mode 100644 index 4614458..0000000 --- a/rt-thread/components/drivers/sdio/sdhci/include/sdhci_misc.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-08-16 zhujiale first version - */ -#ifndef __RT_SDHCI_MISC_H__ -#define __RT_SDHCI_MISC_H__ - - -#define __BF_FIELD_CHECK(...) -#define __bf_shf(x) (__builtin_ffsll(x) - 1) -#define FIELD_GET(_mask, _reg) \ - ({ \ - __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \ - (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ - }) - -#define FIELD_PREP(_mask, _val) \ - ({ \ - __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \ - ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ - }) - -#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) - -#define min_t(type, x, y) (((type)x < (type)y) ? x : y) -#define max_t(type, x, y) (((type)x > (type)y) ? x : y) -#define min(x, y) ((x) < (y) ? (x) : (y)) - -#define from_timer(var, callback_timer, timer_fieldname) \ - container_of(callback_timer, typeof(*var), timer_fieldname) - - -#define le32_to_cpu(x) (x) -#define le16_to_cpu(x) (x) -#define cpu_to_le16(x) (x) -#define cpu_to_le32(x) (x) -#define lower_32_bits(n) ((rt_uint32_t)((n) & 0xffffffff)) -#define upper_32_bits(n) ((rt_uint32_t)(((n) >> 16) >> 16)) - -#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) - -#define do_div(n, base) ({ \ - uint32_t __base = (base); \ - uint32_t __rem; \ - __rem = ((uint64_t)(n)) % __base; \ - (n) = ((uint64_t)(n)) / __base; \ - __rem; \ -}) - -#define fallthrough \ - do { \ - } while (0) - -int regulator_is_supported_voltage(struct regulator *regulator, - int min_uV, int max_uV); -rt_bool_t rt_mmc_can_gpio_cd(struct rt_mmc_host *host); - -struct regulator -{ - const char *supply_name; -}; - -int regulator_get_current_limit(struct regulator *regulator); - -#endif diff --git a/rt-thread/components/drivers/sdio/sdhci/sdhci-platform.c b/rt-thread/components/drivers/sdio/sdhci/sdhci-platform.c deleted file mode 100644 index d6cf4ed..0000000 --- a/rt-thread/components/drivers/sdio/sdhci/sdhci-platform.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-08-16 zhujiale first version - */ -#include "sdhci-platform.h" - -static const struct rt_sdhci_ops sdhci_pltfm_ops = { - .set_clock = rt_sdhci_set_clock, - .set_bus_width = rt_sdhci_set_bus_width, - .reset = rt_sdhci_reset, - .set_uhs_signaling = rt_sdhci_set_uhs, -}; - -void rt_sdhci_get_property(struct rt_platform_device *pdev) -{ - struct rt_device *dev = &pdev->parent; - struct rt_sdhci_host *host = pdev->priv; - struct rt_sdhci_pltfm_host *pltfm_host = sdhci_priv(host); - rt_uint32_t bus_width; - - if (rt_dm_dev_prop_read_bool(dev, "sdhci,auto-cmd12")) - host->quirks |= RT_SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; - - if (rt_dm_dev_prop_read_bool(dev, "sdhci,1-bit-only") || (rt_dm_dev_prop_read_u32(dev, "bus-width", &bus_width) == 0 && bus_width == 1)) - host->quirks |= RT_SDHCI_QUIRK_FORCE_1_BIT_DATA; - - if (rt_dm_dev_prop_read_bool(dev, "broken-cd")) - host->quirks |= RT_SDHCI_QUIRK_BROKEN_CARD_DETECTION; - - if (rt_dm_dev_prop_read_bool(dev, "no-1-8-v")) - host->quirks2 |= RT_SDHCI_QUIRK2_NO_1_8_V; - - rt_dm_dev_prop_read_u32(dev, "clock-frequency", &pltfm_host->clock); - - if (rt_dm_dev_prop_read_bool(dev, "keep-power-in-suspend")) - host->mmc->pm_caps |= MMC_PM_KEEP_POWER; - - if (rt_dm_dev_prop_read_bool(dev, "wakeup-source") || rt_dm_dev_prop_read_bool(dev, "enable-sdio-wakeup")) /* legacy */ - host->mmc->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; -} - -struct rt_sdhci_host *rt_sdhci_pltfm_init(struct rt_platform_device *pdev, - const struct rt_sdhci_pltfm_data *pdata, - size_t priv_size) -{ - struct rt_sdhci_host *host; - struct rt_device *dev = &pdev->parent; - void *ioaddr; - int irq; - - ioaddr = rt_dm_dev_iomap(dev, 0); - if (!ioaddr) - { - return RT_NULL; - } - - irq = rt_dm_dev_get_irq(dev, 0); - if (irq < 0) - { - return RT_NULL; - } - host = rt_sdhci_alloc_host(dev,sizeof(struct rt_sdhci_pltfm_host) + priv_size); - if (!host) - { - return RT_NULL; - } - host->irq = irq; - host->ioaddr = ioaddr; - host->hw_name = rt_dm_dev_get_name(dev); - - if (pdata && pdata->ops) - host->ops = pdata->ops; - else - host->ops = &sdhci_pltfm_ops; - if (pdata) - { - host->quirks = pdata->quirks; - host->quirks2 = pdata->quirks2; - } - - pdev->priv = host; - - return host; -} - -int rt_sdhci_pltfm_init_and_add_host(struct rt_platform_device *pdev, - const struct rt_sdhci_pltfm_data *pdata, - size_t priv_size) -{ - struct rt_sdhci_host *host; - int ret = 0; - - host = rt_sdhci_pltfm_init(pdev, pdata, priv_size); - if (!host) - return -RT_ERROR; - - rt_sdhci_get_property(pdev); - - ret = rt_sdhci_init_host(host); - if (ret) - rt_sdhci_pltfm_free(pdev); - - return ret; -} - -void rt_sdhci_pltfm_free(struct rt_platform_device *pdev) -{ - struct rt_sdhci_host *host = pdev->priv; - - rt_sdhci_free_host(host); -} - -void rt_sdhci_pltfm_remove(struct rt_platform_device *pdev) -{ - struct rt_sdhci_host *host = pdev->priv; - int dead = (readl(host->ioaddr + RT_SDHCI_INT_STATUS) == 0xffffffff); - - rt_sdhci_uninit_host(host, dead); - rt_sdhci_pltfm_free(pdev); -} diff --git a/rt-thread/components/drivers/sdio/sdhci/sdhci.c b/rt-thread/components/drivers/sdio/sdhci/sdhci.c deleted file mode 100644 index 6f52b5e..0000000 --- a/rt-thread/components/drivers/sdio/sdhci/sdhci.c +++ /dev/null @@ -1,3152 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-08-16 zhujiale first version - */ - -#include -#include -#include "sdhci.h" -#include -#define DBG_TAG "RT_SDHCI" -#ifdef DRV_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif /* DRV_DEBUG */ -#include -static unsigned int debug_quirks = 0; -static unsigned int debug_quirks2; -/********************************************************* */ -/* cmd */ -/********************************************************* */ - - -void rt_read_reg_debug(struct rt_sdhci_host *host) -{ - rt_kprintf("0x00 addddddddddddd = %x \n", rt_sdhci_readl(host, 0x00)); - rt_kprintf("0x04 EMMC_BLOCKSIZE = %x \n", rt_sdhci_readw(host, 0x04)); - rt_kprintf("0x06 EMMC_BLOCKCOUNT = %x \n", rt_sdhci_readw(host, 0x06)); - rt_kprintf("0x08 RT_SDHCI_ARGUMENT = %x \n", rt_sdhci_readl(host, 0x08)); - rt_kprintf("0x0c EMMC_XFER_MODE = %x \n", rt_sdhci_readw(host, 0x0c)); - rt_kprintf("0x0e RT_SDHCI_COMMAND = %x \n", rt_sdhci_readw(host, 0x0e)); - rt_kprintf("0x24 RT_SDHCI_PRESENT_STATE = %x \n", rt_sdhci_readl(host, 0x24)); - rt_kprintf("0x28 RT_SDHCI_HOST_CONTROL = %x \n", rt_sdhci_readb(host, 0x28)); - rt_kprintf("0x29 RT_SDHCI_POWER_CONTROL = %x \n", rt_sdhci_readb(host, 0x29)); - rt_kprintf("0x2a EMMC_BGAP_CTRL = %x \n", rt_sdhci_readb(host, 0x2a)); - rt_kprintf("0x2c EMMC_CLK_CTRL = %x \n", rt_sdhci_readw(host, 0x2c)); - rt_kprintf("0x2e EMMC_TOUT_CTRL = %x \n", rt_sdhci_readb(host, 0x2e)); - rt_kprintf("0x2f EMMC_SW_RST = %x \n", rt_sdhci_readb(host, 0x2f)); - rt_kprintf("0x30 RT_SDHCI_INT_STATUS = %x \n", rt_sdhci_readw(host, 0x30)); - rt_kprintf("0x32 RT_SDHCI_ERR_INT_STATUS = %x \n", rt_sdhci_readw(host, 0x32)); - rt_kprintf("0x34 RT_SDHCI_INT_ENABLE = %x \n", rt_sdhci_readw(host, 0x34)); - rt_kprintf("0x36 EMMC ERROR INT STATEN = %x \n", rt_sdhci_readw(host, 0x36)); - rt_kprintf("0x38 EMMC NORMAL INT SIGNAL EN = %x \n", rt_sdhci_readw(host, 0x38)); - rt_kprintf("0x3a EMMC ERROR INT SIGNAL EN = %x \n", rt_sdhci_readw(host, 0x3a)); - rt_kprintf("0x3c EMMC_AUTO_CMD_STAT = %x \n", rt_sdhci_readw(host, 0x3c)); - rt_kprintf("0x3e EMMC_HOST_CTRL2 = %x \n", rt_sdhci_readw(host, 0x3e)); - rt_kprintf("0x40 EMMC_CAPABILITIES1 = %x \n", rt_sdhci_readl(host, 0x40)); - rt_kprintf("0x44 EMMC_CAPABILITIES2 = %x \n", rt_sdhci_readl(host, 0x44)); - rt_kprintf("0x52 EMMC_FORC_ERR_INT_STAT = %x \n", rt_sdhci_readw(host, 0x52)); - rt_kprintf("0x54 EMMC_ADMA_ERR_STAT = %x \n", rt_sdhci_readb(host, 0x54)); - rt_kprintf("0x58 EMMC_ADMA_SA = %x \n", rt_sdhci_readl(host, 0x58)); - rt_kprintf("0x66 EMMC_PRESET_SDR12 = %x \n", rt_sdhci_readw(host, 0x66)); - rt_kprintf("0x68 EMMC_PRESET_SDR25 = %x \n", rt_sdhci_readw(host, 0x68)); - rt_kprintf("0x6a EMMC_PRESET_SDR50 = %x \n", rt_sdhci_readw(host, 0x6a)); - rt_kprintf("0x6c EMMC_PRESET_SDR104 = %x \n", rt_sdhci_readw(host, 0x6c)); - rt_kprintf("0x6e EMMC_PRESET_DDR50 = %x \n", rt_sdhci_readw(host, 0x6e)); - rt_kprintf("0x78 EMMC_ADMA_ID = %x \n", rt_sdhci_readl(host, 0x78)); - rt_kprintf("0xfe EMMC_HOST_CNTRL_VERS = %x \n", rt_sdhci_readw(host, 0xfe)); - -} -static inline rt_bool_t sdhci_has_requests(struct rt_sdhci_host *host) -{ - return host->cmd || host->data_cmd; -} - -static inline rt_bool_t sdhci_auto_cmd23(struct rt_sdhci_host *host, - struct rt_mmcsd_req *mrq) -{ - return mrq->sbc && (host->flags & RT_SDHCI_AUTO_CMD23); -} - -static inline rt_bool_t sdhci_auto_cmd12(struct rt_sdhci_host *host, - struct rt_mmcsd_req *mrq) -{ - return !mrq->sbc && (host->flags & RT_SDHCI_AUTO_CMD12) && !mrq->cap_cmd_during_tfr; -} - -static inline rt_bool_t sdhci_manual_cmd23(struct rt_sdhci_host *host, - struct rt_mmcsd_req *mrq) -{ - return mrq->sbc && !(host->flags & RT_SDHCI_AUTO_CMD23); -} - -static inline rt_bool_t sdhci_data_line_cmd(struct rt_mmcsd_cmd *cmd) -{ - return cmd->data || cmd->flags & MMC_RSP_BUSY; -} - -void rt_sdhci_data_irq_timeout(struct rt_sdhci_host *host, rt_bool_t enable) -{ - if (enable) - host->ier |= RT_SDHCI_INT_DATA_TIMEOUT; - else - host->ier &= ~RT_SDHCI_INT_DATA_TIMEOUT; - rt_sdhci_writel(host, host->ier, RT_SDHCI_INT_ENABLE); - rt_sdhci_writel(host, host->ier, RT_SDHCI_SIGNAL_ENABLE); -} - -void rt_sdhci_set_uhs(struct rt_sdhci_host *host, unsigned timing) -{ - rt_uint16_t ctrl_2; - - ctrl_2 = rt_sdhci_readw(host, RT_SDHCI_HOST_CONTROL2); - - ctrl_2 &= ~RT_SDHCI_CTRL_UHS_MASK; - if ((timing == MMC_TIMING_MMC_HS200) || (timing == MMC_TIMING_UHS_SDR104)) - ctrl_2 |= RT_SDHCI_CTRL_UHS_SDR104; - else if (timing == MMC_TIMING_UHS_SDR12) - ctrl_2 |= RT_SDHCI_CTRL_UHS_SDR12; - else if (timing == MMC_TIMING_UHS_SDR25) - ctrl_2 |= RT_SDHCI_CTRL_UHS_SDR25; - else if (timing == MMC_TIMING_UHS_SDR50) - ctrl_2 |= RT_SDHCI_CTRL_UHS_SDR50; - else if ((timing == MMC_TIMING_UHS_DDR50) || (timing == MMC_TIMING_MMC_DDR52)) - ctrl_2 |= RT_SDHCI_CTRL_UHS_DDR50; - else if (timing == MMC_TIMING_MMC_HS400) - ctrl_2 |= RT_SDHCI_CTRL_HS400; /* Non-standard */ - rt_sdhci_writew(host, ctrl_2, RT_SDHCI_HOST_CONTROL2); -} - -void rt_sdhci_set_bus_width(struct rt_sdhci_host *host, int width) -{ - rt_uint8_t ctrl; - - ctrl = rt_sdhci_readb(host, RT_SDHCI_HOST_CONTROL); - if (width == MMC_BUS_WIDTH_8) - { - ctrl &= ~RT_SDHCI_CTRL_4BITBUS; - ctrl |= RT_SDHCI_CTRL_8BITBUS; - } - else - { - if (host->mmc->caps & MMC_CAP_8_BIT_DATA) - ctrl &= ~RT_SDHCI_CTRL_8BITBUS; - if (width == MMC_BUS_WIDTH_4) - ctrl |= RT_SDHCI_CTRL_4BITBUS; - else - ctrl &= ~RT_SDHCI_CTRL_4BITBUS; - } - rt_sdhci_writeb(host, ctrl, RT_SDHCI_HOST_CONTROL); -} - -static inline rt_bool_t sdhci_can_64bit_dma(struct rt_sdhci_host *host) -{ - if (host->version >= RT_SDHCI_SPEC_410 && host->v4_mode) - return host->caps & RT_SDHCI_CAN_64BIT_V4; - - return host->caps & RT_SDHCI_CAN_64BIT; -} - -static void sdhci_do_enable_v4_mode(struct rt_sdhci_host *host) -{ - rt_uint16_t ctrl2; - - ctrl2 = rt_sdhci_readw(host, RT_SDHCI_HOST_CONTROL2); - if (ctrl2 & RT_SDHCI_CTRL_V4_MODE) - return; - - ctrl2 |= RT_SDHCI_CTRL_V4_MODE; - rt_sdhci_writew(host, ctrl2, RT_SDHCI_HOST_CONTROL2); -} - -void rt_sdhci_cleanup_host(struct rt_sdhci_host *host) -{ - return; -} - -static void sdhci_set_default_irqs(struct rt_sdhci_host *host) -{ - host->ier = RT_SDHCI_INT_BUS_POWER | RT_SDHCI_INT_DATA_END_BIT | RT_SDHCI_INT_DATA_CRC | RT_SDHCI_INT_DATA_TIMEOUT | RT_SDHCI_INT_INDEX | RT_SDHCI_INT_END_BIT | RT_SDHCI_INT_CRC | RT_SDHCI_INT_TIMEOUT | RT_SDHCI_INT_DATA_END | RT_SDHCI_INT_RESPONSE; - - if (host->tuning_mode == RT_SDHCI_TUNING_MODE_2 || host->tuning_mode == RT_SDHCI_TUNING_MODE_3) - host->ier |= RT_SDHCI_INT_RETUNE; - - rt_sdhci_writel(host, host->ier, RT_SDHCI_INT_ENABLE); - rt_sdhci_writel(host, host->ier, RT_SDHCI_SIGNAL_ENABLE); -} - - -static inline void sdhci_auto_cmd_select(struct rt_sdhci_host *host, - struct rt_mmcsd_cmd *cmd, - rt_uint16_t *mode) -{ - rt_bool_t use_cmd12 = sdhci_auto_cmd12(host, cmd->mrq) && (cmd->cmd_code != SD_IO_RW_EXTENDED); - rt_bool_t use_cmd23 = sdhci_auto_cmd23(host, cmd->mrq); - rt_uint16_t ctrl2; - - if (host->version >= RT_SDHCI_SPEC_410 && host->v4_mode && (use_cmd12 || use_cmd23)) - { - *mode |= RT_SDHCI_TRNS_AUTO_SEL; - - ctrl2 = rt_sdhci_readw(host, RT_SDHCI_HOST_CONTROL2); - if (use_cmd23) - ctrl2 |= RT_SDHCI_CMD23_ENABLE; - else - ctrl2 &= ~RT_SDHCI_CMD23_ENABLE; - rt_sdhci_writew(host, ctrl2, RT_SDHCI_HOST_CONTROL2); - - return; - } - - if (use_cmd12) - *mode |= RT_SDHCI_TRNS_AUTO_CMD12; - else if (use_cmd23) - *mode |= RT_SDHCI_TRNS_AUTO_CMD23; -} - - -static rt_bool_t sdhci_present_error(struct rt_sdhci_host *host, - struct rt_mmcsd_cmd *cmd, rt_bool_t present) -{ - if (!present || host->flags & RT_SDHCI_DEVICE_DEAD) - { - cmd->err = -ENOMEDIUM; - return RT_TRUE; - } - - return RT_FALSE; -} - -static rt_uint16_t sdhci_get_preset_value(struct rt_sdhci_host *host) -{ - rt_uint16_t preset = 0; - - switch (host->timing) - { - case MMC_TIMING_MMC_HS: - case MMC_TIMING_SD_HS: - preset = rt_sdhci_readw(host, RT_SDHCI_PRESET_FOR_HIGH_SPEED); - break; - case MMC_TIMING_UHS_SDR12: - preset = rt_sdhci_readw(host, RT_SDHCI_PRESET_FOR_SDR12); - break; - case MMC_TIMING_UHS_SDR25: - preset = rt_sdhci_readw(host, RT_SDHCI_PRESET_FOR_SDR25); - break; - case MMC_TIMING_UHS_SDR50: - preset = rt_sdhci_readw(host, RT_SDHCI_PRESET_FOR_SDR50); - break; - case MMC_TIMING_UHS_SDR104: - case MMC_TIMING_MMC_HS200: - preset = rt_sdhci_readw(host, RT_SDHCI_PRESET_FOR_SDR104); - break; - case MMC_TIMING_UHS_DDR50: - case MMC_TIMING_MMC_DDR52: - preset = rt_sdhci_readw(host, RT_SDHCI_PRESET_FOR_DDR50); - break; - case MMC_TIMING_MMC_HS400: - preset = rt_sdhci_readw(host, RT_SDHCI_PRESET_FOR_HS400); - break; - default: - preset = rt_sdhci_readw(host, RT_SDHCI_PRESET_FOR_SDR12); - break; - } - return preset; -} - -static void sdhci_set_card_detection(struct rt_sdhci_host *host, rt_bool_t enable) -{ - rt_uint32_t present; - - if ((host->quirks & RT_SDHCI_QUIRK_BROKEN_CARD_DETECTION) || !mmc_card_is_removable(host->mmc)) - return; - - if (enable) - { - present = rt_sdhci_readl(host, RT_SDHCI_PRESENT_STATE) & RT_SDHCI_CARD_PRESENT; - - host->ier |= present ? RT_SDHCI_INT_CARD_REMOVE : RT_SDHCI_INT_CARD_INSERT; - } - else - { - host->ier &= ~(RT_SDHCI_INT_CARD_REMOVE | RT_SDHCI_INT_CARD_INSERT); - } - - rt_sdhci_writel(host, host->ier, RT_SDHCI_INT_ENABLE); - rt_sdhci_writel(host, host->ier, RT_SDHCI_SIGNAL_ENABLE); -} - -static void sdhci_enable_card_detection(struct rt_sdhci_host *host) -{ - sdhci_set_card_detection(host, RT_TRUE); -} - -/********************************************************* */ -/* reset */ -/********************************************************* */ -enum sdhci_reset_reason -{ - RT_SDHCI_RESET_FOR_INIT, - RT_SDHCI_RESET_FOR_REQUEST_ERROR, - RT_SDHCI_RESET_FOR_REQUEST_ERROR_DATA_ONLY, - RT_SDHCI_RESET_FOR_TUNING_ABORT, - RT_SDHCI_RESET_FOR_CARD_REMOVED, - RT_SDHCI_RESET_FOR_CQE_RECOVERY, -}; - -static rt_bool_t sdhci_needs_reset(struct rt_sdhci_host *host, struct rt_mmcsd_req *mrq) -{ - return (!(host->flags & RT_SDHCI_DEVICE_DEAD) && ((mrq->cmd && mrq->cmd->err) || (mrq->sbc && mrq->sbc->err) || (mrq->data && mrq->data->stop && mrq->data->stop->err) || (host->quirks & RT_SDHCI_QUIRK_RESET_AFTER_REQUEST))); -} - -static rt_bool_t sdhci_do_reset(struct rt_sdhci_host *host, rt_uint8_t mask) -{ - if (host->quirks & RT_SDHCI_QUIRK_NO_CARD_NO_RESET) - { - struct rt_mmc_host *mmc = host->mmc; - - if (!mmc->ops->get_cd(mmc)) - return RT_FALSE; - } - if (host->ops->reset) - { - host->ops->reset(host, mask); - } - return RT_TRUE; -} - -static void sdhci_reset_for_reason(struct rt_sdhci_host *host, enum sdhci_reset_reason reason) -{ - if (host->quirks2 & RT_SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER) - { - sdhci_do_reset(host, RT_SDHCI_RESET_CMD | RT_SDHCI_RESET_DATA); - return; - } - - switch (reason) - { - case RT_SDHCI_RESET_FOR_INIT: - sdhci_do_reset(host, RT_SDHCI_RESET_CMD | RT_SDHCI_RESET_DATA); - break; - case RT_SDHCI_RESET_FOR_REQUEST_ERROR: - case RT_SDHCI_RESET_FOR_TUNING_ABORT: - case RT_SDHCI_RESET_FOR_CARD_REMOVED: - case RT_SDHCI_RESET_FOR_CQE_RECOVERY: - sdhci_do_reset(host, RT_SDHCI_RESET_CMD); - sdhci_do_reset(host, RT_SDHCI_RESET_DATA); - break; - case RT_SDHCI_RESET_FOR_REQUEST_ERROR_DATA_ONLY: - sdhci_do_reset(host, RT_SDHCI_RESET_DATA); - break; - } -} - -#define sdhci_reset_for(h, r) sdhci_reset_for_reason((h), RT_SDHCI_RESET_FOR_##r) - -static void sdhci_reset_for_all(struct rt_sdhci_host *host) -{ - if (sdhci_do_reset(host, RT_SDHCI_RESET_ALL)) - { - if (host->flags & (RT_SDHCI_USE_SDMA)) - { - if (host->ops->enable_dma) - host->ops->enable_dma(host); - } - host->preset_enabled = RT_FALSE; - } -} - - -static void sdhci_runtime_pm_bus_on(struct rt_sdhci_host *host) -{ - if (host->bus_on) - return; - host->bus_on = RT_TRUE; -} - -static void sdhci_runtime_pm_bus_off(struct rt_sdhci_host *host) -{ - if (!host->bus_on) - return; - host->bus_on = RT_FALSE; -} - -void rt_sdhci_reset(struct rt_sdhci_host *host, rt_uint8_t mask) -{ - ssize_t timeout; - - rt_sdhci_writeb(host, mask, RT_SDHCI_SOFTWARE_RESET); - - if (mask & RT_SDHCI_RESET_ALL) - { - host->clock = 0; - if (host->quirks2 & RT_SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) - sdhci_runtime_pm_bus_off(host); - } - - timeout = rt_tick_from_millisecond(150); - while (1) - { - timeout = timeout - rt_tick_get(); - - - if (!(rt_sdhci_readb(host, RT_SDHCI_SOFTWARE_RESET) & mask)) - break; - if (timeout < 0) - { - rt_kprintf("%s: Reset 0x%x never completed.\n", - mmc_hostname(host->mmc), (int)mask); - rt_read_reg_debug(host); - return; - } - rt_hw_us_delay(10); - } -} - -/********************************************************* */ -/* data */ -/********************************************************* */ -static rt_ubase_t sdhci_sdma_address(struct rt_sdhci_host *host) -{ - return (rt_ubase_t)rt_kmem_v2p(host->data->buf); -} - -static void sdhci_set_adma_addr(struct rt_sdhci_host *host, rt_uint32_t addr) -{ - rt_sdhci_writel(host, lower_32_bits(addr), RT_SDHCI_ADMA_ADDRESS); - if (host->flags & RT_SDHCI_USE_64_BIT_DMA) - rt_sdhci_writel(host, upper_32_bits(addr), RT_SDHCI_ADMA_ADDRESS_HI); -} - -static void sdhci_set_sdma_addr(struct rt_sdhci_host *host, rt_uint32_t addr) -{ - if (host->v4_mode) - sdhci_set_adma_addr(host, addr); - else - rt_sdhci_writel(host, addr, RT_SDHCI_DMA_ADDRESS); -} - -static void sdhci_config_dma(struct rt_sdhci_host *host) -{ - rt_uint8_t ctrl; - rt_uint16_t ctrl2; - - if (host->version < RT_SDHCI_SPEC_200) - return; - - ctrl = rt_sdhci_readb(host, RT_SDHCI_HOST_CONTROL); - - ctrl &= ~RT_SDHCI_CTRL_DMA_MASK; - if (!(host->flags & RT_SDHCI_REQ_USE_DMA)) - goto out; - - /* Note if DMA Select is zero then SDMA is selected */ - if (host->flags & RT_SDHCI_USE_64_BIT_DMA) - { - - if (host->v4_mode) - { - ctrl2 = rt_sdhci_readw(host, RT_SDHCI_HOST_CONTROL2); - ctrl2 |= RT_SDHCI_CTRL_64BIT_ADDR; - rt_sdhci_writew(host, ctrl2, RT_SDHCI_HOST_CONTROL2); - } - } - -out: - rt_sdhci_writeb(host, ctrl, RT_SDHCI_HOST_CONTROL); -} - -static inline void sdhci_set_block_info(struct rt_sdhci_host *host, - struct rt_mmcsd_data *data) -{ - int boundary; - size_t total_size = data->blks * data->blksize; - - if (total_size <= 512) - boundary = 0; /* 4k bytes*/ - else if (total_size <= 1024) - boundary = 1; /* 8 KB*/ - else if (total_size <= 2048) - boundary = 2; /* 16 KB*/ - else if (total_size <= 4096) - boundary = 3; /* 32 KB*/ - else if (total_size <= 8192) - boundary = 4; /* 64 KB*/ - else if (total_size <= 16384) - boundary = 5; /* 128 KB*/ - else if (total_size <= 32768) - boundary = 6; /* 256 KB*/ - else - boundary = 7; /* 512 KB*/ - rt_sdhci_writew(host, - RT_SDHCI_MAKE_BLKSZ(boundary, data->blksize), - RT_SDHCI_BLOCK_SIZE); - - if (host->version >= RT_SDHCI_SPEC_410 && host->v4_mode && (host->quirks2 & RT_SDHCI_QUIRK2_USE_32BIT_BLK_CNT)) - { - if (rt_sdhci_readw(host, RT_SDHCI_BLOCK_COUNT)) - rt_sdhci_writew(host, 0, RT_SDHCI_BLOCK_COUNT); - rt_sdhci_writew(host, data->blks, RT_SDHCI_32BIT_BLK_CNT); - } - else - { - rt_sdhci_writew(host, data->blks, RT_SDHCI_BLOCK_COUNT); - } -} - -static void sdhci_set_transfer_irqs(struct rt_sdhci_host *host) -{ - rt_uint32_t pio_irqs = RT_SDHCI_INT_DATA_AVAIL | RT_SDHCI_INT_SPACE_AVAIL; - rt_uint32_t dma_irqs = RT_SDHCI_INT_DMA_END; - - if (host->flags & RT_SDHCI_REQ_USE_DMA) - host->ier = (host->ier & ~pio_irqs) | dma_irqs; - else - host->ier = (host->ier & ~dma_irqs) | pio_irqs; - - if (host->flags & (RT_SDHCI_AUTO_CMD23 | RT_SDHCI_AUTO_CMD12)) - host->ier |= RT_SDHCI_INT_AUTO_CMD_ERR; - else - host->ier &= ~RT_SDHCI_INT_AUTO_CMD_ERR; - rt_sdhci_writel(host, host->ier, RT_SDHCI_INT_ENABLE); - rt_sdhci_writel(host, host->ier, RT_SDHCI_SIGNAL_ENABLE); -} - -static void sdhci_prepare_data(struct rt_sdhci_host *host, struct rt_mmcsd_cmd *cmd) -{ - struct rt_mmcsd_data *data = cmd->data; - - LOG_D(data->blksize * data->blks > 524288); - LOG_D(data->blksize > host->mmc->max_blk_size); - LOG_D(data->blks > 65535); - - host->data = data; - host->data_early = 0; - host->data->bytes_xfered = 0; - - if (host->flags & RT_SDHCI_USE_SDMA) - { - unsigned int length_mask, offset_mask; - - host->flags |= RT_SDHCI_REQ_USE_DMA; - - length_mask = 0; - offset_mask = 0; - if (host->quirks & RT_SDHCI_QUIRK_32BIT_DMA_SIZE) - length_mask = 3; - if (host->quirks & RT_SDHCI_QUIRK_32BIT_DMA_ADDR) - offset_mask = 3; - - if ((data->blks * data->blksize) & length_mask) - { - host->flags &= ~RT_SDHCI_REQ_USE_DMA; - } - else if ((rt_ubase_t)rt_kmem_v2p(data->buf) & offset_mask) - { - host->flags &= ~RT_SDHCI_REQ_USE_DMA; - } - } - - sdhci_config_dma(host); - - if (host->flags & RT_SDHCI_REQ_USE_DMA) - { - if (mmc_get_dma_dir(data) == DMA_FROM_DEVICE) - rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, data->buf, data->blks * data->blksize); - else - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, data->buf, data->blks * data->blksize); - - sdhci_set_sdma_addr(host, sdhci_sdma_address(host)); - } - - if (!(host->flags & RT_SDHCI_REQ_USE_DMA)) - { - host->blocks = data->blks; - } - - sdhci_set_transfer_irqs(host); - - sdhci_set_block_info(host, data); -} - -static void sdhci_set_mrq_done(struct rt_sdhci_host *host, struct rt_mmcsd_req *mrq) -{ - int i; - - for (i = 0; i < RT_SDHCI_MAX_MRQS; i++) - { - if (host->mrqs_done[i] == mrq) - { - LOG_D(1); - return; - } - } - - for (i = 0; i < RT_SDHCI_MAX_MRQS; i++) - { - if (!host->mrqs_done[i]) - { - host->mrqs_done[i] = mrq; - break; - } - } - - LOG_D(i >= RT_SDHCI_MAX_MRQS); -} - -static inline rt_bool_t sdhci_defer_done(struct rt_sdhci_host *host, - struct rt_mmcsd_req *mrq) -{ - struct rt_mmcsd_data *data = mrq->data; - - return host->pending_reset || host->always_defer_done || ((host->flags & RT_SDHCI_REQ_USE_DMA) && data && data->host_cookie == COOKIE_MAPPED); -} - - -/********************************************************* */ -/* pio */ -/********************************************************* */ - -static void rt_sdhci_read_block_pio(struct rt_sdhci_host *host,void **buf) -{ - rt_uint32_t scratch; - size_t len; - - rt_uint32_t blksize = host->data->blksize; - while (blksize) - { - len = min(4U, blksize); - - scratch = rt_sdhci_readl(host, RT_SDHCI_BUFFER); - rt_memcpy(*buf, &scratch, len); - - *buf += len; - blksize -= len; - } -} - -static void rt_sdhci_write_block_pio(struct rt_sdhci_host *host,void **buf) -{ - size_t blksize, len; - rt_uint32_t scratch; - LOG_D("PIO writing\n"); - - blksize = host->data->blksize; - scratch = 0; - - while (blksize) - { - len = min(4U, blksize); - rt_memcpy(&scratch, *buf, len); - *buf += len; - blksize -= len; - rt_sdhci_writel(host, scratch, RT_SDHCI_BUFFER); - } -} - -static void sdhci_transfer_pio(struct rt_sdhci_host *host) -{ - rt_uint32_t mask; - - if (host->blocks == 0) - return; - - if (host->data->flags & DATA_DIR_READ) - mask = RT_SDHCI_DATA_AVAILABLE; - else - mask = RT_SDHCI_SPACE_AVAILABLE; - - if ((host->quirks & RT_SDHCI_QUIRK_BROKEN_SMALL_PIO) && (host->data->blks == 1)) - { - mask = ~0; - } - void *buf = (void *)host->data->buf; - while (rt_sdhci_readl(host, RT_SDHCI_PRESENT_STATE) & mask) - { - if (host->quirks & RT_SDHCI_QUIRK_PIO_NEEDS_DELAY) - rt_hw_us_delay(100); - - if (host->data->flags & DATA_DIR_READ) - rt_sdhci_read_block_pio(host,&buf); - else - rt_sdhci_write_block_pio(host,&buf); - - host->data->blks--; - if (host->data->blks == 0) - break; - } -} - -/********************************************************* */ -/* config */ -/********************************************************* */ - - -static rt_bool_t sdhci_timing_has_preset(unsigned char timing) -{ - switch (timing) - { - case MMC_TIMING_UHS_SDR12: - case MMC_TIMING_UHS_SDR25: - case MMC_TIMING_UHS_SDR50: - case MMC_TIMING_UHS_SDR104: - case MMC_TIMING_UHS_DDR50: - case MMC_TIMING_MMC_DDR52: - return RT_TRUE; - } - return RT_FALSE; -} - -static rt_bool_t sdhci_preset_needed(struct rt_sdhci_host *host, unsigned char timing) -{ - return !(host->quirks2 & RT_SDHCI_QUIRK2_PRESET_VALUE_BROKEN) && sdhci_timing_has_preset(timing); -} - -static rt_bool_t sdhci_presetable_values_change(struct rt_sdhci_host *host, struct rt_mmcsd_io_cfg *ios) -{ - return !host->preset_enabled && (sdhci_preset_needed(host, ios->timing) || host->drv_type != ios->drv_type); -} - - -static void sdhci_preset_value_enable(struct rt_sdhci_host *host, rt_bool_t enable) -{ - if (host->version < RT_SDHCI_SPEC_300) - return; - - if (host->preset_enabled != enable) - { - rt_uint16_t ctrl = rt_sdhci_readw(host, RT_SDHCI_HOST_CONTROL2); - - if (enable) - ctrl |= RT_SDHCI_CTRL_PRESET_VAL_ENABLE; - else - ctrl &= ~RT_SDHCI_CTRL_PRESET_VAL_ENABLE; - - rt_sdhci_writew(host, ctrl, RT_SDHCI_HOST_CONTROL2); - - if (enable) - host->flags |= RT_SDHCI_PV_ENABLED; - else - host->flags &= ~RT_SDHCI_PV_ENABLED; - - host->preset_enabled = enable; - } -} - -static void sdhci_set_power_reg(struct rt_sdhci_host *host, unsigned char mode, - unsigned short vdd) -{ - struct rt_mmc_host *mmc = host->mmc; - - mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); - - if (mode != MMC_POWER_OFF) - rt_sdhci_writeb(host, RT_SDHCI_POWER_ON, RT_SDHCI_POWER_CONTROL); - else - rt_sdhci_writeb(host, 0, RT_SDHCI_POWER_CONTROL); -} - -void rt_sdhci_set_power_with_noreg(struct rt_sdhci_host *host, unsigned char mode, - unsigned short vdd) -{ - rt_uint8_t pwr = 0; - - if (mode != MMC_POWER_OFF) - { - switch (1 << vdd) - { - case MMC_VDD_165_195: - case MMC_VDD_20_21: - pwr = RT_SDHCI_POWER_180; - break; - case MMC_VDD_29_30: - case MMC_VDD_30_31: - pwr = RT_SDHCI_POWER_300; - break; - case MMC_VDD_32_33: - case MMC_VDD_33_34: - case MMC_VDD_34_35: - case MMC_VDD_35_36: - pwr = RT_SDHCI_POWER_330; - break; - default: - break; - } - } - - if (host->pwr == pwr) - return; - - host->pwr = pwr; - - if (pwr == 0) - { - rt_sdhci_writeb(host, 0, RT_SDHCI_POWER_CONTROL); - if (host->quirks2 & RT_SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) - sdhci_runtime_pm_bus_off(host); - } - else - { - if (!(host->quirks & RT_SDHCI_QUIRK_SINGLE_POWER_WRITE)) - rt_sdhci_writeb(host, 0, RT_SDHCI_POWER_CONTROL); - - if (host->quirks & RT_SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER) - rt_sdhci_writeb(host, pwr, RT_SDHCI_POWER_CONTROL); - - pwr |= RT_SDHCI_POWER_ON; - - rt_sdhci_writeb(host, pwr, RT_SDHCI_POWER_CONTROL); - - if (host->quirks2 & RT_SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) - sdhci_runtime_pm_bus_on(host); - - if (host->quirks & RT_SDHCI_QUIRK_DELAY_AFTER_POWER) - rt_thread_mdelay(10); - } -} - -void rt_sdhci_set_power(struct rt_sdhci_host *host, unsigned char mode, - unsigned short vdd) -{ - if (!host->mmc->supply.vmmc) - rt_sdhci_set_power_with_noreg(host, mode, vdd); - else - sdhci_set_power_reg(host, mode, vdd); -} - - -int rt_sdhci_start_signal_voltage_switch(struct rt_mmc_host *mmc, - struct rt_mmcsd_io_cfg *ios) -{ - struct rt_sdhci_host *host = mmc_priv(mmc); - rt_uint16_t ctrl; - int ret; - - if (host->version < RT_SDHCI_SPEC_300) - return 0; - - ctrl = rt_sdhci_readw(host, RT_SDHCI_HOST_CONTROL2); - - switch (ios->signal_voltage) - { - case MMC_SIGNAL_VOLTAGE_330: - if (!(host->flags & RT_SDHCI_SIGNALING_330)) - return -EINVAL; - ctrl &= ~RT_SDHCI_CTRL_VDD_180; - rt_sdhci_writew(host, ctrl, RT_SDHCI_HOST_CONTROL2); - - if (!mmc->supply.vqmmc) - { - ret = rt_mmc_regulator_set_vqmmc(mmc, ios); - if (ret < 0) - { - return -EIO; - } - } - rt_thread_mdelay(5); - - ctrl = rt_sdhci_readw(host, RT_SDHCI_HOST_CONTROL2); - if (!(ctrl & RT_SDHCI_CTRL_VDD_180)) - return 0; - return -EAGAIN; - case MMC_SIGNAL_VOLTAGE_180: - if (!(host->flags & RT_SDHCI_SIGNALING_180)) - return -EINVAL; - if (!mmc->supply.vqmmc) - { - ret = rt_mmc_regulator_set_vqmmc(mmc, ios); - if (ret < 0) - { - LOG_D("%s: Switching to 1.8V signalling voltage failed\n", - mmc_hostname(mmc)); - return -EIO; - } - } - - ctrl |= RT_SDHCI_CTRL_VDD_180; - rt_sdhci_writew(host, ctrl, RT_SDHCI_HOST_CONTROL2); - - if (host->ops->voltage_switch) - host->ops->voltage_switch(host); - - ctrl = rt_sdhci_readw(host, RT_SDHCI_HOST_CONTROL2); - if (ctrl & RT_SDHCI_CTRL_VDD_180) - return 0; - - LOG_D("%s: 1.8V regulator output did not become stable\n", - mmc_hostname(mmc)); - - return -EAGAIN; - case MMC_SIGNAL_VOLTAGE_120: - if (!(host->flags & RT_SDHCI_SIGNALING_120)) - return -EINVAL; - if (!mmc->supply.vqmmc) - { - ret = rt_mmc_regulator_set_vqmmc(mmc, ios); - if (ret < 0) - { - LOG_D("%s: Switching to 1.2V signalling voltage failed\n", - mmc_hostname(mmc)); - return -EIO; - } - } - return 0; - default: - return 0; - } -} - - -static int sdhci_get_cd(struct rt_mmc_host *mmc) -{ - struct rt_sdhci_host *host = mmc_priv(mmc); - int gpio_cd = rt_mmc_gpio_get_cd(mmc); - - if (host->flags & RT_SDHCI_DEVICE_DEAD) - return 0; - - if (!mmc_card_is_removable(mmc)) - return 1; - - if (gpio_cd >= 0) - return !!gpio_cd; - - if (host->quirks & RT_SDHCI_QUIRK_BROKEN_CARD_DETECTION) - return 1; - - return !!(rt_sdhci_readl(host, RT_SDHCI_PRESENT_STATE) & RT_SDHCI_CARD_PRESENT); -} - -static int sdhci_check_ro(struct rt_sdhci_host *host) -{ - int is_readonly; - rt_base_t flags; - flags = rt_spin_lock_irqsave(&host->lock); - - if (host->flags & RT_SDHCI_DEVICE_DEAD) - is_readonly = 0; - else if (host->ops->get_ro) - is_readonly = host->ops->get_ro(host); - else if (rt_mmc_can_gpio_ro(host->mmc)) - is_readonly = rt_mmc_gpio_get_ro(host->mmc); - else - is_readonly = !(rt_sdhci_readl(host, RT_SDHCI_PRESENT_STATE) - & RT_SDHCI_WRITE_PROTECT); - - rt_spin_unlock_irqrestore(&host->lock, flags); - - return host->quirks & RT_SDHCI_QUIRK_INVERTED_WRITE_PROTECT ? !is_readonly : is_readonly; -} - -#define SAMPLE_COUNT 5 -static int rt_sdhci_ro_get(struct rt_mmc_host *mmc) -{ - struct rt_sdhci_host *host = mmc_priv(mmc); - int i, ro_count; - - if (!(host->quirks & RT_SDHCI_QUIRK_UNSTABLE_RO_DETECT)) - return sdhci_check_ro(host); - - ro_count = 0; - for (i = 0; i < SAMPLE_COUNT; i++) - { - if (sdhci_check_ro(host)) - { - if (++ro_count > SAMPLE_COUNT / 2) - return 1; - } - rt_thread_mdelay(30); - } - return 0; -} - -static void rt_sdhci_enable_io_irq_nolock(struct rt_sdhci_host *host, int enable) -{ - if (!(host->flags & RT_SDHCI_DEVICE_DEAD)) - { - if (enable) - host->ier |= RT_SDHCI_INT_CARD_INT; - else - host->ier &= ~RT_SDHCI_INT_CARD_INT; - - rt_sdhci_writel(host, host->ier, RT_SDHCI_INT_ENABLE); - rt_sdhci_writel(host, host->ier, RT_SDHCI_SIGNAL_ENABLE); - } -} - -static void sdhci_ack_sdio_irq(struct rt_mmc_host *mmc) -{ - rt_base_t flags; - struct rt_sdhci_host *host = mmc_priv(mmc); - flags = rt_spin_lock_irqsave(&host->lock); - rt_sdhci_enable_io_irq_nolock(host, RT_TRUE); - rt_spin_unlock_irqrestore(&host->lock, flags); -} - -static void sdhci_del_timer(struct rt_sdhci_host *host, struct rt_mmcsd_req *mrq) -{ - if (sdhci_data_line_cmd(mrq->cmd)) - rt_timer_stop(&host->data_timer); - else - rt_timer_stop(&host->timer); -} - -static unsigned int sdhci_target_timeout(struct rt_sdhci_host *host, - struct rt_mmcsd_cmd *cmd, - struct rt_mmcsd_data *data) -{ - unsigned int target_timeout; - - if (!data) - { - target_timeout = cmd->busy_timeout * 1000; - } - else - { - target_timeout = DIV_ROUND_UP(data->timeout_ns, 1000); - if (host->clock && data->timeout_clks) - { - rt_uint32_t val; - - val = 1000000ULL * data->timeout_clks; - if (do_div(val, host->clock)) - target_timeout++; - target_timeout += val; - } - } - - return target_timeout; -} - -static rt_uint8_t sdhci_calc_timeout(struct rt_sdhci_host *host, struct rt_mmcsd_cmd *cmd, - rt_bool_t *too_big) -{ - rt_uint8_t count; - struct rt_mmcsd_data *data; - unsigned target_timeout, current_timeout; - - *too_big = RT_FALSE; - - if (host->quirks & RT_SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) - return host->max_timeout_count; - - if (cmd == NULL) - return host->max_timeout_count; - - data = cmd->data; - if (!data && !cmd->busy_timeout) - return host->max_timeout_count; - - target_timeout = sdhci_target_timeout(host, cmd, data); - - count = 0; - current_timeout = (1 << 13) * 1000 / host->timeout_clk; - while (current_timeout < target_timeout) - { - count++; - current_timeout <<= 1; - if (count > host->max_timeout_count) - { - if (!(host->quirks2 & RT_SDHCI_QUIRK2_DISABLE_HW_TIMEOUT)) - LOG_D("Too large timeout 0x%x requested for CMD%d!\n", - count, cmd->cmd_code); - count = host->max_timeout_count; - *too_big = RT_TRUE; - break; - } - } - - return count; -} - -static void sdhci_calc_sw_timeout(struct rt_sdhci_host *host, - struct rt_mmcsd_cmd *cmd) -{ - struct rt_mmcsd_data *data = cmd->data; - struct rt_mmc_host *mmc = host->mmc; - struct rt_mmcsd_io_cfg *ios = &mmc->ios; - unsigned char bus_width = 1 << ios->bus_width; - unsigned int blksz; - unsigned int freq; - rt_uint64_t target_timeout; - rt_uint64_t transfer_time; - - target_timeout = sdhci_target_timeout(host, cmd, data); - target_timeout *= 1000L; - - if (data) - { - blksz = data->blksize; - freq = mmc->actual_clock ?: host->clock; - transfer_time = (rt_uint64_t)blksz * 1000000000L * (8 / bus_width); - do_div(transfer_time, freq); - transfer_time = transfer_time * 2; - host->data_timeout = data->blks * target_timeout + transfer_time; - } - else - { - host->data_timeout = target_timeout; - } - - if (host->data_timeout) - host->data_timeout += MMC_CMD_TRANSFER_TIME; -} - - -void rt_sdhci_timeout_set(struct rt_sdhci_host *host, struct rt_mmcsd_cmd *cmd) -{ - rt_bool_t too_big = RT_FALSE; - rt_uint8_t count = sdhci_calc_timeout(host, cmd, &too_big); - - if (too_big && host->quirks2 & RT_SDHCI_QUIRK2_DISABLE_HW_TIMEOUT) - { - sdhci_calc_sw_timeout(host, cmd); - rt_sdhci_data_irq_timeout(host, RT_FALSE); - } - else if (!(host->ier & RT_SDHCI_INT_DATA_TIMEOUT)) - { - rt_sdhci_data_irq_timeout(host, RT_FALSE); - } - - rt_sdhci_writeb(host, count, RT_SDHCI_TIMEOUT_CONTROL); -} - -static void sdhci_set_timeout(struct rt_sdhci_host *host, struct rt_mmcsd_cmd *cmd) -{ - if (host->ops->set_timeout) - host->ops->set_timeout(host, cmd); - else - rt_sdhci_timeout_set(host, cmd); -} - -static void sdhci_start_timer(struct rt_sdhci_host *host, struct rt_mmcsd_req *mrq, - unsigned long timeout) -{ - if (sdhci_data_line_cmd(mrq->cmd)) - { - rt_tick_t tick = rt_tick_get(); - - if (timeout < tick) - { - timeout = tick; - } - tick = timeout - tick; - - rt_timer_stop(&host->data_timer); - rt_timer_control(&host->data_timer, RT_TIMER_CTRL_SET_TIME, &tick); - rt_timer_start(&host->data_timer); - } - else - { - rt_tick_t tick = rt_tick_get(); - - if (timeout < tick) - { - timeout = tick; - } - tick = timeout - tick; - - rt_timer_stop(&host->timer); - rt_timer_control(&host->timer, RT_TIMER_CTRL_SET_TIME, &tick); - rt_timer_start(&host->timer); - } -} - -static void __sdhci_finish_mrq(struct rt_sdhci_host *host, struct rt_mmcsd_req *mrq) -{ - if (host->cmd && host->cmd->mrq == mrq) - host->cmd = NULL; - - if (host->data_cmd && host->data_cmd->mrq == mrq) - host->data_cmd = NULL; - - if (host->deferred_cmd && host->deferred_cmd->mrq == mrq) - host->deferred_cmd = NULL; - - if (host->data && host->data->mrq == mrq) - host->data = NULL; - - if (sdhci_needs_reset(host, mrq)) - host->pending_reset = RT_TRUE; - - sdhci_set_mrq_done(host, mrq); - - sdhci_del_timer(host, mrq); -} - -static void sdhci_finish_mrq(struct rt_sdhci_host *host, struct rt_mmcsd_req *mrq) -{ - __sdhci_finish_mrq(host, mrq); - - rt_workqueue_submit_work(host->complete_wq, &host->complete_work, 0); -} - -static void sdhci_error_out_mrqs(struct rt_sdhci_host *host, int err) -{ - if (host->data_cmd) - { - host->data_cmd->err = err; - sdhci_finish_mrq(host, host->data_cmd->mrq); - } - - if (host->cmd) - { - host->cmd->err = err; - sdhci_finish_mrq(host, host->cmd->mrq); - } -} - -static void sdhci_card_event(struct rt_mmc_host *mmc) -{ - struct rt_sdhci_host *host = mmc_priv(mmc); - rt_uint32_t flags; - int present; - - if (host->ops->card_event) - host->ops->card_event(host); - - present = mmc->ops->get_cd(mmc); - - flags = rt_spin_lock_irqsave(&host->lock); - - if (sdhci_has_requests(host) && !present) - { - rt_kprintf("%s: Card removed during transfer!\n", - mmc_hostname(mmc)); - rt_kprintf("%s: Resetting controller.\n", - mmc_hostname(mmc)); - - sdhci_do_reset(host, RT_SDHCI_RESET_CMD); - sdhci_do_reset(host, RT_SDHCI_RESET_DATA); - sdhci_error_out_mrqs(host, -ENOMEDIUM); - } - - rt_spin_unlock_irqrestore(&host->lock, flags); -} - -static int sdhci_card_busy(struct rt_mmc_host *mmc) -{ - struct rt_sdhci_host *host = mmc_priv(mmc); - rt_uint32_t present_state; - - present_state = rt_sdhci_readl(host, RT_SDHCI_PRESENT_STATE); - - return !(present_state & RT_SDHCI_DATA_0_LVL_MASK); -} - - -static int sdhci_prepare_hs400_tuning(struct rt_mmc_host *mmc, struct rt_mmcsd_io_cfg *ios) -{ - struct rt_sdhci_host *host = mmc_priv(mmc); - rt_uint32_t flags; - - flags = rt_spin_lock_irqsave(&host->lock); - host->flags |= RT_SDHCI_HS400_TUNING; - rt_spin_unlock_irqrestore(&host->lock, flags); - - return 0; -} - - -static void sdhci_set_transfer_mode(struct rt_sdhci_host *host, - struct rt_mmcsd_cmd *cmd) -{ - rt_uint16_t mode = 0; - struct rt_mmcsd_data *data = cmd->data; - - if (data == NULL) - { - if (host->quirks2 & RT_SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD) - { - if (!mmc_op_tuning(cmd->cmd_code)) - rt_sdhci_writew(host, 0x0, RT_SDHCI_TRANSFER_MODE); - } - else - { - mode = rt_sdhci_readw(host, RT_SDHCI_TRANSFER_MODE); - rt_sdhci_writew(host, mode & ~(RT_SDHCI_TRNS_AUTO_CMD12 | RT_SDHCI_TRNS_AUTO_CMD23), RT_SDHCI_TRANSFER_MODE); - } - return; - } - - if (!(host->quirks2 & RT_SDHCI_QUIRK2_SUPPORT_SINGLE)) - mode = RT_SDHCI_TRNS_BLK_CNT_EN; - - if (mmc_op_multi(cmd->cmd_code) || data->blks > 1) - { - mode = RT_SDHCI_TRNS_BLK_CNT_EN | RT_SDHCI_TRNS_MULTI; - sdhci_auto_cmd_select(host, cmd, &mode); - if (sdhci_auto_cmd23(host, cmd->mrq)) - rt_sdhci_writel(host, cmd->mrq->sbc->arg, RT_SDHCI_ARGUMENT2); - } - - if (data->flags & DATA_DIR_READ) - mode |= RT_SDHCI_TRNS_READ; - if (host->flags & RT_SDHCI_REQ_USE_DMA) - mode |= RT_SDHCI_TRNS_DMA; - - rt_sdhci_writew(host, mode, RT_SDHCI_TRANSFER_MODE); -} - -static rt_bool_t sdhci_send_command(struct rt_sdhci_host *host, struct rt_mmcsd_cmd *cmd) -{ - int flags; - rt_uint32_t mask; - unsigned long timeout; - cmd->err = 0; - - if ((host->quirks2 & RT_SDHCI_QUIRK2_STOP_WITH_TC) && cmd->cmd_code == MMC_STOP_TRANSMISSION) - cmd->flags |= MMC_RSP_BUSY; - - mask = RT_SDHCI_CMD_INHIBIT; - if (sdhci_data_line_cmd(cmd)) - mask |= RT_SDHCI_DATA_INHIBIT; - - if (cmd->mrq->data && (cmd == cmd->mrq->data->stop)) - mask &= ~RT_SDHCI_DATA_INHIBIT; - - if (rt_sdhci_readl(host, RT_SDHCI_PRESENT_STATE) & mask) - return RT_FALSE; - - host->cmd = cmd; - host->data_timeout = 0; - if (sdhci_data_line_cmd(cmd)) - { - host->data_cmd = cmd; - sdhci_set_timeout(host, cmd); - } - - if (cmd->data) - { - sdhci_prepare_data(host, cmd); - } - rt_sdhci_writel(host, cmd->arg, RT_SDHCI_ARGUMENT); - - sdhci_set_transfer_mode(host, cmd); - - if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) - { - cmd->flags &= ~MMC_RSP_BUSY; - } - - if (!(cmd->flags & MMC_RSP_PRESENT)) - flags = RT_SDHCI_CMD_RESP_NONE; - else if (cmd->flags & MMC_RSP_136) - flags = RT_SDHCI_CMD_RESP_LONG; - else if (cmd->flags & MMC_RSP_BUSY) - flags = RT_SDHCI_CMD_RESP_SHORT_BUSY; - else - flags = RT_SDHCI_CMD_RESP_SHORT; - - if (cmd->flags & MMC_RSP_CRC) - flags |= RT_SDHCI_CMD_CRC; - if (cmd->flags & MMC_RSP_OPCODE) - flags |= RT_SDHCI_CMD_INDEX; - - if (cmd->data || mmc_op_tuning(cmd->cmd_code)) - flags |= RT_SDHCI_CMD_DATA; - - timeout = rt_tick_get(); - if (host->data_timeout) - timeout += rt_tick_from_millisecond(host->data_timeout * 1000); - else if (!cmd->data && cmd->busy_timeout > 9000) - timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * RT_TICK_PER_SECOND + RT_TICK_PER_SECOND; - else - timeout += 10 * RT_TICK_PER_SECOND; - sdhci_start_timer(host, cmd->mrq, timeout); - - rt_sdhci_writew(host, RT_SDHCI_MAKE_CMD(cmd->cmd_code, flags), RT_SDHCI_COMMAND); - return RT_TRUE; -} - -/********************************************************* */ -/* dma */ -/********************************************************* */ -static void __sdhci_finish_data(struct rt_sdhci_host *host, rt_bool_t sw_data_timeout) -{ - struct rt_mmcsd_cmd *data_cmd = host->data_cmd; - struct rt_mmcsd_data *data = host->data; - - host->data = NULL; - host->data_cmd = NULL; - - if (data->err) - { - if (!host->cmd || host->cmd == data_cmd) - sdhci_reset_for(host, REQUEST_ERROR); - else - sdhci_reset_for(host, REQUEST_ERROR_DATA_ONLY); - } - - if (data->err) - { - data->bytes_xfered = 0; - } - else - { - data->bytes_xfered = data->blksize * data->blks; - } - - if (data->stop && ((!data->mrq->sbc && !sdhci_auto_cmd12(host, data->mrq)) || data->err)) - { - if (data->mrq->cap_cmd_during_tfr) - { - __sdhci_finish_mrq(host, data->mrq); - } - else - { - host->cmd = NULL; - if (!sdhci_send_command(host, data->stop)) - { - if (sw_data_timeout) - { - data->stop->err = -EIO; - __sdhci_finish_mrq(host, data->mrq); - } - else - { - host->deferred_cmd = data->stop; - } - } - } - } - else - { - __sdhci_finish_mrq(host, data->mrq); - } -} - -static void sdhci_finish_data(struct rt_sdhci_host *host) -{ - __sdhci_finish_data(host, RT_FALSE); -} - - -/********************************************************* */ -/* irq */ -/********************************************************* */ -static void sdhci_data_irq(struct rt_sdhci_host *host, rt_uint32_t intmask) -{ - rt_uint32_t command; - - if (intmask & RT_SDHCI_INT_DATA_AVAIL && !host->data) - { - command = RT_SDHCI_GET_CMD(rt_sdhci_readw(host, RT_SDHCI_COMMAND)); - if (command == MMC_SEND_TUNING_BLOCK || command == MMC_SEND_TUNING_BLOCK_HS200) - { - host->tuning_done = 1; - rt_wqueue_wakeup(&host->buf_ready_int, 0); - return; - } - } - - if (!host->data) - { - struct rt_mmcsd_cmd *data_cmd = host->data_cmd; - - if (data_cmd && (data_cmd->flags & MMC_RSP_BUSY)) - { - if (intmask & RT_SDHCI_INT_DATA_TIMEOUT) - { - host->data_cmd = NULL; - data_cmd->err = -ETIMEDOUT; - __sdhci_finish_mrq(host, data_cmd->mrq); - return; - } - if (intmask & RT_SDHCI_INT_DATA_END) - { - host->data_cmd = NULL; - - if (host->cmd == data_cmd) - return; - - __sdhci_finish_mrq(host, data_cmd->mrq); - return; - } - } - - - if (host->pending_reset) - return; - rt_kprintf("%s: Got data interrupt 0x%08x even though no data operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - rt_read_reg_debug(host); - - return; - } - - if (intmask & RT_SDHCI_INT_DATA_TIMEOUT) - host->data->err = -ETIMEDOUT; - else if (intmask & RT_SDHCI_INT_DATA_END_BIT) - host->data->err = -EILSEQ; - else if ((intmask & RT_SDHCI_INT_DATA_CRC) && RT_SDHCI_GET_CMD(rt_sdhci_readw(host, RT_SDHCI_COMMAND)) != MMC_BUS_TEST_R) - { - host->data->err = -EILSEQ; - } - - - if (host->data->err) - { - sdhci_finish_data(host); - } - else - { - if (intmask & (RT_SDHCI_INT_DATA_AVAIL | RT_SDHCI_INT_SPACE_AVAIL)) - sdhci_transfer_pio(host); - - if (intmask & RT_SDHCI_INT_DMA_END) - { - rt_uint32_t dmastart, dmanow; - - dmastart = sdhci_sdma_address(host); - dmanow = dmastart + host->data->bytes_xfered; - dmanow = (dmanow & ~((rt_uint32_t)RT_SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) + RT_SDHCI_DEFAULT_BOUNDARY_SIZE; - host->data->bytes_xfered = dmanow - dmastart; - LOG_D("DMA base %pad, transferred 0x%06x bytes, next %pad\n", - &dmastart, host->data->bytes_xfered, &dmanow); - sdhci_set_sdma_addr(host, dmanow); - } - - if (intmask & RT_SDHCI_INT_DATA_END) - { - struct rt_mmcsd_data *data = host->data; - if (data->buf) - { - if (mmc_get_dma_dir(data) == DMA_FROM_DEVICE) - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, data->buf, data->blks * data->blksize); - } else { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, data->buf, data->blks * data->blksize); - } - } - if (host->cmd == host->data_cmd) - { - host->data_early = 1; - } - else - { - sdhci_finish_data(host); - } - } - } -} - -static void rt_sdhci_read_rsp_136(struct rt_sdhci_host *host, struct rt_mmcsd_cmd *cmd) -{ - int i, reg; - - for (i = 0; i < 4; i++) - { - reg = RT_SDHCI_RESPONSE + (3 - i) * 4; - cmd->resp[i] = rt_sdhci_readl(host, reg); - } - - if (host->quirks2 & RT_SDHCI_QUIRK2_RSP_136_HAS_CRC) - return; - - for (i = 0; i < 4; i++) - { - cmd->resp[i] <<= 8; - if (i != 3) - cmd->resp[i] |= cmd->resp[i + 1] >> 24; - } -} - -static void sdhci_command_end(struct rt_sdhci_host *host) -{ - struct rt_mmcsd_cmd *cmd = host->cmd; - - host->cmd = NULL; - - if (cmd->flags & MMC_RSP_PRESENT) - { - if (cmd->flags & MMC_RSP_136) - { - rt_sdhci_read_rsp_136(host, cmd); - } - else - { - cmd->resp[0] = rt_sdhci_readl(host, RT_SDHCI_RESPONSE); - } - } - - if (cmd->flags & MMC_RSP_BUSY) - { - if (cmd->data) - { - LOG_D("Cannot wait for busy signal when also doing a data transfer"); - } - else if (!(host->quirks & RT_SDHCI_QUIRK_NO_BUSY_IRQ) && cmd == host->data_cmd) - { - return; - } - } - - if (cmd == cmd->mrq->sbc) - { - if (!sdhci_send_command(host, cmd->mrq->cmd)) - { - host->deferred_cmd = cmd->mrq->cmd; - } - } - else - { - if (host->data && host->data_early) - sdhci_finish_data(host); - - if (!cmd->data) - __sdhci_finish_mrq(host, cmd->mrq); - } -} - - -static void sdhci_cmd_irq(struct rt_sdhci_host *host, rt_uint32_t intmask, rt_uint32_t *intmask_p) -{ - if (intmask & RT_SDHCI_INT_AUTO_CMD_ERR && host->data_cmd) - { - struct rt_mmcsd_req *mrq = host->data_cmd->mrq; - rt_uint16_t auto_cmd_status = rt_sdhci_readw(host, RT_SDHCI_AUTO_CMD_STATUS); - int data_err_bit = (auto_cmd_status & RT_SDHCI_AUTO_CMD_TIMEOUT) ? RT_SDHCI_INT_DATA_TIMEOUT : RT_SDHCI_INT_DATA_CRC; - - if (!mrq->sbc && (host->flags & RT_SDHCI_AUTO_CMD12)) - { - *intmask_p |= data_err_bit; - return; - } - } - - if (!host->cmd) - { - if (host->pending_reset) - return; - rt_kprintf("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); - rt_read_reg_debug(host); - return; - } - if (intmask & (RT_SDHCI_INT_TIMEOUT | RT_SDHCI_INT_CRC | RT_SDHCI_INT_END_BIT | RT_SDHCI_INT_INDEX)) - { - if (intmask & RT_SDHCI_INT_TIMEOUT) - host->cmd->err = -ETIMEDOUT; - else - host->cmd->err = -EILSEQ; - - /* Treat data command CRC error the same as data CRC error */ - if (host->cmd->data && (intmask & (RT_SDHCI_INT_CRC | RT_SDHCI_INT_TIMEOUT)) == RT_SDHCI_INT_CRC) - { - host->cmd = NULL; - *intmask_p |= RT_SDHCI_INT_DATA_CRC; - return; - } - - __sdhci_finish_mrq(host, host->cmd->mrq); - return; - } - - if (intmask & RT_SDHCI_INT_AUTO_CMD_ERR) - { - struct rt_mmcsd_req *mrq = host->cmd->mrq; - rt_uint16_t auto_cmd_status = rt_sdhci_readw(host, RT_SDHCI_AUTO_CMD_STATUS); - int err = (auto_cmd_status & RT_SDHCI_AUTO_CMD_TIMEOUT) ? -ETIMEDOUT : -EILSEQ; - - if (mrq->sbc && (host->flags & RT_SDHCI_AUTO_CMD23)) - { - mrq->sbc->err = err; - __sdhci_finish_mrq(host, mrq); - return; - } - } - - if (intmask & RT_SDHCI_INT_RESPONSE) - sdhci_command_end(host); -} - -static void sdhci_irq(int irq, void *dev_id) -{ -#define IRQ_NONE 0 -#define IRQ_WAIT 1 -#define IRQ_DONE 2 - - struct rt_mmcsd_req* mrqs_done[RT_SDHCI_MAX_MRQS] = { 0 }; - struct rt_sdhci_host *host = dev_id; - rt_uint32_t intmask, mask, unexpected = 0; - int max_loops = 16; - int i, result= IRQ_NONE ; - rt_spin_lock(&host->lock); - - if (host->runtime_suspended) - { - rt_spin_unlock(&host->lock); - return; - } - - intmask = rt_sdhci_readl(host, RT_SDHCI_INT_STATUS); - if (!intmask || intmask == 0xffffffff) - { - result = IRQ_NONE; - goto out; - } - - do { - LOG_D("IRQ status 0x%08x\n", intmask); - - if (host->ops->irq) - { - intmask = host->ops->irq(host, intmask); - if (!intmask) - goto cont; - } - - /* Clear selected interrupts. */ - mask = intmask & (RT_SDHCI_INT_CMD_MASK | RT_SDHCI_INT_DATA_MASK | RT_SDHCI_INT_BUS_POWER); - rt_sdhci_writel(host, mask, RT_SDHCI_INT_STATUS); - - if (intmask & (RT_SDHCI_INT_CARD_INSERT | RT_SDHCI_INT_CARD_REMOVE)) - { - rt_uint32_t present = rt_sdhci_readl(host, RT_SDHCI_PRESENT_STATE) & RT_SDHCI_CARD_PRESENT; - - host->ier &= ~(RT_SDHCI_INT_CARD_INSERT | RT_SDHCI_INT_CARD_REMOVE); - host->ier |= present ? RT_SDHCI_INT_CARD_REMOVE : RT_SDHCI_INT_CARD_INSERT; - rt_sdhci_writel(host, host->ier, RT_SDHCI_INT_ENABLE); - rt_sdhci_writel(host, host->ier, RT_SDHCI_SIGNAL_ENABLE); - - rt_sdhci_writel(host, intmask & (RT_SDHCI_INT_CARD_INSERT | RT_SDHCI_INT_CARD_REMOVE), RT_SDHCI_INT_STATUS); - - host->thread_isr |= intmask & (RT_SDHCI_INT_CARD_INSERT | RT_SDHCI_INT_CARD_REMOVE); - result = IRQ_WAIT; - } - - if (intmask & RT_SDHCI_INT_CMD_MASK) - sdhci_cmd_irq(host, intmask & RT_SDHCI_INT_CMD_MASK, &intmask); - - if (intmask & RT_SDHCI_INT_DATA_MASK) - sdhci_data_irq(host, intmask & RT_SDHCI_INT_DATA_MASK); - - if (intmask & RT_SDHCI_INT_BUS_POWER) - rt_kprintf("%s: Card is consuming too much power!\n", - mmc_hostname(host->mmc)); - - intmask &= ~(RT_SDHCI_INT_CARD_INSERT | RT_SDHCI_INT_CARD_REMOVE | RT_SDHCI_INT_CMD_MASK | RT_SDHCI_INT_DATA_MASK | RT_SDHCI_INT_ERROR | RT_SDHCI_INT_BUS_POWER | RT_SDHCI_INT_RETUNE | RT_SDHCI_INT_CARD_INT); - - if (intmask) - { - unexpected |= intmask; - rt_sdhci_writel(host, intmask, RT_SDHCI_INT_STATUS); - } - cont: - if (result == IRQ_NONE) - result = IRQ_WAIT; - intmask = rt_sdhci_readl(host, RT_SDHCI_INT_STATUS); - } while (intmask && --max_loops); - - for (i = 0; i < RT_SDHCI_MAX_MRQS; i++) - { - struct rt_mmcsd_req *mrq = host->mrqs_done[i]; - - if (!mrq) - continue; - - if (sdhci_defer_done(host, mrq)) - { - result = IRQ_WAIT; - } - else - { - mrqs_done[i] = mrq; - host->mrqs_done[i] = NULL; - } - } -out: - if (host->deferred_cmd) - result = IRQ_WAIT; - - rt_spin_unlock(&host->lock); - - for (i = 0; i < RT_SDHCI_MAX_MRQS; i++) - { - if (!mrqs_done[i]) - continue; - - if (host->ops->request_done) - host->ops->request_done(host, mrqs_done[i]); - else - rt_mmc_request_done(host->mmc, mrqs_done[i]); - } - - if (unexpected) - { - rt_kprintf("%s: Unexpected interrupt 0x%08x.\n", - mmc_hostname(host->mmc), unexpected); - rt_read_reg_debug(host); - } - - if (result == IRQ_WAIT) - { - rt_workqueue_submit_work(host->irq_wq, &host->irq_work, 0); - } -} - -static rt_bool_t sdhci_send_command_retry(struct rt_sdhci_host *host, - struct rt_mmcsd_cmd *cmd, - unsigned long flags) -{ - struct rt_mmcsd_cmd *deferred_cmd = host->deferred_cmd; - int timeout = 10; /* Approx. 10 ms */ - rt_bool_t present; - while (!sdhci_send_command(host, cmd)) - { - if (!timeout--) - { - rt_kprintf("%s: Controller never released inhibit bit(s).\n", - mmc_hostname(host->mmc)); - rt_read_reg_debug(host); - cmd->err = -EIO; - return RT_FALSE; - } - - rt_spin_unlock_irqrestore(&host->lock, flags); - - rt_thread_mdelay(1); - - present = host->mmc->ops->get_cd(host->mmc); - - flags = rt_spin_lock_irqsave(&host->lock); - - if (cmd == deferred_cmd && cmd != host->deferred_cmd) - return RT_TRUE; - - if (sdhci_present_error(host, cmd, present)) - return RT_FALSE; - } - - if (cmd == host->deferred_cmd) - host->deferred_cmd = NULL; - - return RT_TRUE; -} - -static rt_bool_t rt_sdhci_start_request_done(struct rt_sdhci_host *host) -{ - rt_base_t flags; - struct rt_mmcsd_req *mrq; - int i; - - flags = rt_spin_lock_irqsave(&host->lock); - - for (i = 0; i < RT_SDHCI_MAX_MRQS; i++) - { - mrq = host->mrqs_done[i]; - if (mrq) - break; - } - - if (!mrq) - { - rt_spin_unlock_irqrestore(&host->lock, flags); - return RT_TRUE; - } - - if (sdhci_needs_reset(host, mrq)) - { - if (host->cmd || host->data_cmd) - { - rt_spin_unlock_irqrestore(&host->lock, flags); - return RT_TRUE; - } - - /* Some controllers need this kick or reset won't work here */ - if (host->quirks & RT_SDHCI_QUIRK_CLOCK_BEFORE_RESET) - /* This is to force an update */ - host->ops->set_clock(host, host->clock); - - sdhci_reset_for(host, REQUEST_ERROR); - - host->pending_reset = RT_FALSE; - } - - if (host->flags & RT_SDHCI_REQ_USE_DMA) - { - struct rt_mmcsd_data *data = mrq->data; - - if (data && data->host_cookie == COOKIE_MAPPED) - { - if (host->bounce_buffer) - { - /* - * On reads, copy the bounced data into the - * sglist - */ - if (mmc_get_dma_dir(data) == DMA_FROM_DEVICE) - { - unsigned int length = data->bytes_xfered; - - if (length > host->bounce_buffer_size) - { - LOG_E("%s: bounce buffer is %u bytes but DMA claims to have transferred %u bytes\n", - mmc_hostname(host->mmc), - host->bounce_buffer_size, - data->bytes_xfered); - /* Cap it down and continue */ - length = host->bounce_buffer_size; - } - rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, data->buf, data->blks * data->blksize); - } else { - /* No copying, just switch ownership */ - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, data->buf, data->blks * data->blksize); - } - } - data->host_cookie = COOKIE_UNMAPPED; - } - else { - if (mmc_get_dma_dir(data) == DMA_FROM_DEVICE) - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, data->buf, data->blks * data->blksize); - } else { - /* No copying, just switch ownership */ - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, data->buf, data->blks * data->blksize); - } - } - } - - host->mrqs_done[i] = NULL; - - rt_spin_unlock_irqrestore(&host->lock, flags); - - if (host->ops->request_done) - host->ops->request_done(host, mrq); - else - rt_mmc_request_done(host->mmc, mrq); - - return RT_FALSE; -} - - -static void sdhci_thread_irq(struct rt_work *work, void *work_data) -{ - struct rt_sdhci_host* host = work_data; - struct rt_mmcsd_cmd *cmd; - rt_base_t flags; - rt_uint32_t isr; - - while (!rt_sdhci_start_request_done(host)); - - flags = rt_spin_lock_irqsave(&host->lock); - - isr = host->thread_isr; - host->thread_isr = 0; - - cmd = host->deferred_cmd; - if (cmd && !sdhci_send_command_retry(host, cmd, flags)) - sdhci_finish_mrq(host, cmd->mrq); - - rt_spin_unlock_irqrestore(&host->lock, flags); - - if (isr & (RT_SDHCI_INT_CARD_INSERT | RT_SDHCI_INT_CARD_REMOVE)) - { - struct rt_mmc_host *mmc = host->mmc; - - mmc->ops->card_event(mmc); - } -} - - -void rt_sdhci_enable_io_irq(struct rt_mmc_host *mmc, int enable) -{ - struct rt_sdhci_host *host = mmc_priv(mmc); - rt_uint32_t flags; - - flags = rt_spin_lock_irqsave(&host->lock); - rt_sdhci_enable_io_irq_nolock(host, enable); - rt_spin_unlock_irqrestore(&host->lock, flags); -} - - -/********************************************************* */ -/* request */ -/********************************************************* */ - -void rt_sdhci_start_request(struct rt_mmc_host *mmc, struct rt_mmcsd_req *mrq) -{ - struct rt_sdhci_host *host = mmc_priv(mmc); - struct rt_mmcsd_cmd *cmd; - rt_base_t flags; - rt_bool_t present; - - /* Firstly check card presence */ - present = mmc->ops->get_cd(mmc); - - flags = rt_spin_lock_irqsave(&host->lock); - - if (sdhci_present_error(host, mrq->cmd, present)) - goto out_finish; - - cmd = sdhci_manual_cmd23(host, mrq) ? mrq->sbc : mrq->cmd; - - if (!sdhci_send_command_retry(host, cmd, flags)) - goto out_finish; - - rt_spin_unlock_irqrestore(&host->lock, flags); - - return; - -out_finish: - sdhci_finish_mrq(host, mrq); - rt_spin_unlock_irqrestore(&host->lock, flags); -} - - -static void sdhci_complete_work(struct rt_work *work, void *work_data) -{ - struct rt_sdhci_host *host = work_data; - - while (!rt_sdhci_start_request_done(host)); -} - - -/********************************************************* */ -/* timer */ -/********************************************************* */ -static void sdhci_timeout_timer(void *parameter) -{ - struct rt_sdhci_host *host = parameter; - rt_base_t flags; - - flags = rt_spin_lock_irqsave(&host->lock); - - if (host->cmd && !sdhci_data_line_cmd(host->cmd)) - { - rt_kprintf("%s: Timeout waiting for hardware cmd interrupt.\n", - mmc_hostname(host->mmc)); - rt_read_reg_debug(host); - - host->cmd->err = -ETIMEDOUT; - sdhci_finish_mrq(host, host->cmd->mrq); - } - - rt_spin_unlock_irqrestore(&host->lock, flags); -} - -static void sdhci_timeout_data_timer(void *parameter) -{ - struct rt_sdhci_host *host = parameter; - rt_base_t flags; - - flags = rt_spin_lock_irqsave(&host->lock); - - if (host->data || host->data_cmd || (host->cmd && sdhci_data_line_cmd(host->cmd))) - { - rt_kprintf("%s: Timeout waiting for hardware interrupt.\n", - mmc_hostname(host->mmc)); - rt_read_reg_debug(host); - - if (host->data) - { - host->data->err = -ETIMEDOUT; - __sdhci_finish_data(host, RT_TRUE); - rt_workqueue_submit_work(host->complete_wq, &host->complete_work, 0); - } - else if (host->data_cmd) - { - host->data_cmd->err = -ETIMEDOUT; - sdhci_finish_mrq(host, host->data_cmd->mrq); - } - else - { - host->cmd->err = -ETIMEDOUT; - sdhci_finish_mrq(host, host->cmd->mrq); - } - } - - rt_spin_unlock_irqrestore(&host->lock, flags); -} - - -/********************************************************* */ -/* tuning */ -/********************************************************* */ -int rt_sdhci_execute_tuning(struct rt_mmc_host *mmc, rt_uint32_t opcode) -{ - struct rt_sdhci_host *host = mmc_priv(mmc); - int err = 0; - unsigned int tuning_count = 0; - rt_bool_t hs400_tuning; - - hs400_tuning = host->flags & RT_SDHCI_HS400_TUNING; - - if (host->tuning_mode == RT_SDHCI_TUNING_MODE_1) - tuning_count = host->tuning_count; - - switch (host->timing) - { - /* HS400 tuning is done in HS200 mode */ - case MMC_TIMING_MMC_HS400: - err = -EINVAL; - goto out; - - case MMC_TIMING_MMC_HS200: - if (hs400_tuning) - tuning_count = 0; - break; - - case MMC_TIMING_UHS_SDR104: - case MMC_TIMING_UHS_DDR50: - break; - - case MMC_TIMING_UHS_SDR50: - if (host->flags & RT_SDHCI_SDR50_NEEDS_TUNING) - break; - fallthrough; - - default: - goto out; - } - - if (host->ops->platform_execute_tuning) - { - err = host->ops->platform_execute_tuning(host, opcode); - goto out; - } - - mmc->retune_period = tuning_count; - - if (host->tuning_delay < 0) - host->tuning_delay = opcode == MMC_SEND_TUNING_BLOCK; - - rt_sdhci_start_tuning(host); - - host->tuning_err = __sdhci_execute_tuning(host, opcode); - - rt_sdhci_end_tuning(host); -out: - host->flags &= ~RT_SDHCI_HS400_TUNING; - - return err; -} - -int __sdhci_execute_tuning(struct rt_sdhci_host *host, rt_uint32_t opcode) -{ - int i; - - for (i = 0; i < host->tuning_loop_count; i++) - { - rt_uint16_t ctrl; - - rt_sdhci_send_tuning(host, opcode); - - if (!host->tuning_done) - { - rt_sdhci_abort_tuning(host, opcode); - return -ETIMEDOUT; - } - - if (host->tuning_delay > 0) - rt_thread_mdelay(host->tuning_delay); - - ctrl = rt_sdhci_readw(host, RT_SDHCI_HOST_CONTROL2); - if (!(ctrl & RT_SDHCI_CTRL_EXEC_TUNING)) - { - if (ctrl & RT_SDHCI_CTRL_TUNED_CLK) - return 0; /* Success! */ - break; - } - } - - LOG_D("%s: Tuning failed, falling back to fixed sampling clock\n", - mmc_hostname(host->mmc)); - rt_sdhci_reset_tuning(host); - return -EAGAIN; -} - -void rt_sdhci_start_tuning(struct rt_sdhci_host *host) -{ - rt_uint16_t ctrl; - - ctrl = rt_sdhci_readw(host, RT_SDHCI_HOST_CONTROL2); - ctrl |= RT_SDHCI_CTRL_EXEC_TUNING; - if (host->quirks2 & RT_SDHCI_QUIRK2_TUNING_WORK_AROUND) - ctrl |= RT_SDHCI_CTRL_TUNED_CLK; - rt_sdhci_writew(host, ctrl, RT_SDHCI_HOST_CONTROL2); - - rt_sdhci_writel(host, RT_SDHCI_INT_DATA_AVAIL, RT_SDHCI_INT_ENABLE); - rt_sdhci_writel(host, RT_SDHCI_INT_DATA_AVAIL, RT_SDHCI_SIGNAL_ENABLE); -} - -void rt_sdhci_end_tuning(struct rt_sdhci_host *host) -{ - rt_sdhci_writel(host, host->ier, RT_SDHCI_INT_ENABLE); - rt_sdhci_writel(host, host->ier, RT_SDHCI_SIGNAL_ENABLE); -} - -void rt_sdhci_abort_tuning(struct rt_sdhci_host *host, rt_uint32_t opcode) -{ - rt_sdhci_reset_tuning(host); - - sdhci_reset_for(host, TUNING_ABORT); - - rt_sdhci_end_tuning(host); -} - -void rt_sdhci_send_tuning(struct rt_sdhci_host *host, rt_uint32_t opcode) -{ - struct rt_mmc_host *mmc = host->mmc; - struct rt_mmcsd_cmd cmd = {}; - struct rt_mmcsd_req mrq = {}; - unsigned long flags; - rt_uint32_t b = host->sdma_boundary; - - flags = rt_spin_lock_irqsave(&host->lock); - - cmd.cmd_code = opcode; - cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; - cmd.mrq = &mrq; - - mrq.cmd = &cmd; - - if (cmd.cmd_code == MMC_SEND_TUNING_BLOCK_HS200 && mmc->ios.bus_width == MMC_BUS_WIDTH_8) - rt_sdhci_writew(host, RT_SDHCI_MAKE_BLKSZ(b, 128), RT_SDHCI_BLOCK_SIZE); - else - rt_sdhci_writew(host, RT_SDHCI_MAKE_BLKSZ(b, 64), RT_SDHCI_BLOCK_SIZE); - - rt_sdhci_writew(host, RT_SDHCI_TRNS_READ, RT_SDHCI_TRANSFER_MODE); - - if (!sdhci_send_command_retry(host, &cmd, flags)) - { - rt_spin_unlock_irqrestore(&host->lock, flags); - host->tuning_done = 0; - return; - } - - host->cmd = NULL; - - sdhci_del_timer(host, &mrq); - - host->tuning_done = 0; - - rt_spin_unlock_irqrestore(&host->lock, flags); -} - -void rt_sdhci_reset_tuning(struct rt_sdhci_host *host) -{ - rt_uint16_t ctrl; - - ctrl = rt_sdhci_readw(host, RT_SDHCI_HOST_CONTROL2); - ctrl &= ~RT_SDHCI_CTRL_TUNED_CLK; - ctrl &= ~RT_SDHCI_CTRL_EXEC_TUNING; - rt_sdhci_writew(host, ctrl, RT_SDHCI_HOST_CONTROL2); -} - - -/********************************************************* */ -/* error */ -/********************************************************* */ -static const struct mmc_host_ops rt_sdhci_ops = { - .request = rt_sdhci_start_request, - .set_ios = rt_sdhci_ios_set, - .get_cd = sdhci_get_cd, - .get_ro = rt_sdhci_ro_get, - .enable_sdio_irq = rt_sdhci_enable_io_irq, - .ack_sdio_irq = sdhci_ack_sdio_irq, - .start_signal_voltage_switch = rt_sdhci_start_signal_voltage_switch, - .prepare_hs400_tuning = sdhci_prepare_hs400_tuning, - .execute_tuning = rt_sdhci_execute_tuning, - .card_event = sdhci_card_event, - .card_busy = sdhci_card_busy, -}; - - -void rt_sdhci_uninit_host(struct rt_sdhci_host *host, int dead) -{ - struct rt_mmc_host *mmc = host->mmc; - unsigned long flags; - - if (dead) - { - flags = rt_spin_lock_irqsave(&host->lock); - - host->flags |= RT_SDHCI_DEVICE_DEAD; - - if (sdhci_has_requests(host)) - { - rt_kprintf("%s: Controller removed during " - " transfer!\n", - mmc_hostname(mmc)); - sdhci_error_out_mrqs(host, -ENOMEDIUM); - } - - rt_spin_unlock_irqrestore(&host->lock, flags); - } - - sdhci_set_card_detection(host, RT_FALSE); - - rt_mmc_remove_host(mmc); - - - if (!dead) - sdhci_reset_for_all(host); - - rt_sdhci_writel(host, 0, RT_SDHCI_INT_ENABLE); - rt_sdhci_writel(host, 0, RT_SDHCI_SIGNAL_ENABLE); - - rt_timer_delete(&host->timer); - rt_timer_delete(&host->data_timer); - - rt_workqueue_destroy(host->complete_wq); - -} - -rt_uint16_t rt_sdhci_clk_set(struct rt_sdhci_host *host, unsigned int clock, - unsigned int *actual_clock) -{ - int div = 0; /* Initialized for compiler warning */ - int real_div = div, clk_mul = 1; - rt_uint16_t clk = 0; - rt_bool_t switch_base_clk = RT_FALSE; - - if (host->version >= RT_SDHCI_SPEC_300) - { - if (host->preset_enabled) - { - rt_uint16_t pre_val; - - clk = rt_sdhci_readw(host, RT_SDHCI_CLOCK_CONTROL); - pre_val = sdhci_get_preset_value(host); - div = FIELD_GET(RT_SDHCI_PRESET_SDCLK_FREQ_MASK, pre_val); - if (host->clk_mul && (pre_val & RT_SDHCI_PRESET_CLKGEN_SEL)) - { - clk = RT_SDHCI_PROG_CLOCK_MODE; - real_div = div + 1; - clk_mul = host->clk_mul; - } - else - { - real_div = max_t(int, 1, div << 1); - } - goto clock_set; - } - - if (host->clk_mul) - { - for (div = 1; div <= 1024; div++) - { - if ((host->max_clk * host->clk_mul / div) - <= clock) - break; - } - if ((host->max_clk * host->clk_mul / div) <= clock) - { - - clk = RT_SDHCI_PROG_CLOCK_MODE; - real_div = div; - clk_mul = host->clk_mul; - div--; - } - else - { - - switch_base_clk = RT_TRUE; - } - } - - if (!host->clk_mul || switch_base_clk) - { - if (host->max_clk <= clock) - div = 1; - else - { - for (div = 2; div < RT_SDHCI_MAX_DIV_SPEC_300; - div += 2) - { - if ((host->max_clk / div) <= clock) - break; - } - } - real_div = div; - div >>= 1; - if ((host->quirks2 & RT_SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN) - && !div && host->max_clk <= 25000000) - div = 1; - } - } - else - { - for (div = 1; div < RT_SDHCI_MAX_DIV_SPEC_200; div *= 2) - { - if ((host->max_clk / div) <= clock) - break; - } - real_div = div; - div >>= 1; - } - -clock_set: - if (real_div) - *actual_clock = (host->max_clk * clk_mul) / real_div; - clk |= (div & RT_SDHCI_DIV_MASK) << RT_SDHCI_DIVIDER_SHIFT; - clk |= ((div & RT_SDHCI_DIV_HI_MASK) >> RT_SDHCI_DIV_MASK_LEN) - << RT_SDHCI_DIVIDER_HI_SHIFT; - - return clk; -} - -void rt_sdhci_clk_enable(struct rt_sdhci_host *host, rt_uint16_t clk) -{ - long timeout; - - clk |= RT_SDHCI_CLOCK_INT_EN; - rt_sdhci_writew(host, clk, RT_SDHCI_CLOCK_CONTROL); - - timeout = rt_tick_from_millisecond(150); - while (1) - { - timeout = timeout - rt_tick_get(); - - clk = rt_sdhci_readw(host, RT_SDHCI_CLOCK_CONTROL); - if (clk & RT_SDHCI_CLOCK_INT_STABLE) - break; - if (timeout < 0) - { - rt_kprintf("%s: Internal clock never stabilised.\n", - mmc_hostname(host->mmc)); - rt_read_reg_debug(host); - return; - } - rt_hw_us_delay(10); - } - - if (host->version >= RT_SDHCI_SPEC_410 && host->v4_mode) - { - clk |= RT_SDHCI_CLOCK_PLL_EN; - clk &= ~RT_SDHCI_CLOCK_INT_STABLE; - rt_sdhci_writew(host, clk, RT_SDHCI_CLOCK_CONTROL); - - timeout = rt_tick_from_millisecond(150); - while (1) - { - timeout = timeout - rt_tick_get(); - - clk = rt_sdhci_readw(host, RT_SDHCI_CLOCK_CONTROL); - if (clk & RT_SDHCI_CLOCK_INT_STABLE) - break; - if (timeout < 0) - { - rt_kprintf("%s: PLL clock never stabilised.\n", - mmc_hostname(host->mmc)); - rt_read_reg_debug(host); - return; - } - rt_hw_us_delay(10); - } - } - - clk |= RT_SDHCI_CLOCK_CARD_EN; - rt_sdhci_writew(host, clk, RT_SDHCI_CLOCK_CONTROL); -} - -void rt_sdhci_set_clock(struct rt_sdhci_host *host, unsigned int clock) -{ - rt_uint16_t clk; - - host->mmc->actual_clock = 0; - - rt_sdhci_writew(host, 0, RT_SDHCI_CLOCK_CONTROL); - - if (clock == 0) - return; - - clk = rt_sdhci_clk_set(host, clock, &host->mmc->actual_clock); - rt_sdhci_clk_enable(host, clk); -} - -void rt_sdhci_read_caps(struct rt_sdhci_host *host, const rt_uint16_t *ver, - const rt_uint32_t *caps, const rt_uint32_t *caps1) -{ - rt_uint16_t v; - rt_uint64_t dt_caps_mask = 0; - rt_uint64_t dt_caps = 0; - - if (host->read_caps) - return; - - host->read_caps = RT_TRUE; - - if (debug_quirks) - host->quirks = debug_quirks; - - if (debug_quirks2) - host->quirks2 = debug_quirks2; - - sdhci_reset_for_all(host); - - if (host->v4_mode) - sdhci_do_enable_v4_mode(host); -#ifdef RT_USING_OFW - rt_ofw_prop_read_u64(mmc_dev(host->mmc)->ofw_node, - "sdhci-caps-mask", &dt_caps_mask); - rt_ofw_prop_read_u64(mmc_dev(host->mmc)->ofw_node, - "sdhci-caps", &dt_caps); -#endif - v = ver ? *ver : rt_sdhci_readw(host, RT_SDHCI_HOST_VERSION); - host->version = (v & RT_SDHCI_SPEC_VER_MASK) >> RT_SDHCI_SPEC_VER_SHIFT; - - if (caps) - { - host->caps = *caps; - } - else - { - host->caps = rt_sdhci_readl(host, RT_SDHCI_CAPABILITIES); - host->caps &= ~lower_32_bits(dt_caps_mask); - host->caps |= lower_32_bits(dt_caps); - } - - if (host->version < RT_SDHCI_SPEC_300) - return; - - if (caps1) - { - host->caps1 = *caps1; - } - else - { - host->caps1 = rt_sdhci_readl(host, RT_SDHCI_CAPABILITIES_1); - host->caps1 &= ~upper_32_bits(dt_caps_mask); - host->caps1 |= upper_32_bits(dt_caps); - } -} - -struct rt_sdhci_host *rt_sdhci_alloc_host(struct rt_device *dev, - size_t priv_size) -{ - struct rt_mmc_host *mmc; - struct rt_sdhci_host *host; - - mmc = rt_mmc_alloc_host(sizeof(struct rt_sdhci_host) + priv_size, dev); - if (!mmc) - return NULL; - - host = mmc_priv(mmc); - host->mmc = mmc; - host->mmc_host_ops = rt_sdhci_ops; - mmc->ops = &host->mmc_host_ops; - - host->flags = RT_SDHCI_SIGNALING_330; - - host->cqe_ier = RT_SDHCI_CQE_INT_MASK; - host->cqe_err_ier = RT_SDHCI_CQE_INT_ERR_MASK; - - host->tuning_delay = -1; - host->tuning_loop_count = MAX_TUNING_LOOP; - - host->sdma_boundary = RT_SDHCI_DEFAULT_BOUNDARY_ARG; - - host->max_timeout_count = 0xE; - - return host; -} - -int rt_sdhci_setup_host(struct rt_sdhci_host *host) -{ - struct rt_mmc_host *mmc; - size_t max_current_caps; - unsigned int ocr_avail; - unsigned int override_timeout_clk; - size_t max_clk; - int ret = 0; - bool enable_vqmmc = RT_FALSE; - - RT_ASSERT(host != NULL); - - - mmc = host->mmc; - - if (!mmc->supply.vqmmc) - { - if (ret) - return ret; - enable_vqmmc = RT_TRUE; - } - - LOG_D("Version: 0x%08x | Present: 0x%08x\n", - rt_sdhci_readw(host, RT_SDHCI_HOST_VERSION), - rt_sdhci_readl(host, RT_SDHCI_PRESENT_STATE)); - LOG_D("Caps: 0x%08x | Caps_1: 0x%08x\n", - rt_sdhci_readl(host, RT_SDHCI_CAPABILITIES), - rt_sdhci_readl(host, RT_SDHCI_CAPABILITIES_1)); - - rt_sdhci_read_caps(host,RT_NULL,RT_NULL,RT_NULL); - - override_timeout_clk = host->timeout_clk; - - if (host->version > RT_SDHCI_SPEC_420) - { - rt_kprintf("%s: Unknown controller version (%d). You may experience problems.\n", - mmc_hostname(mmc), host->version); - } - - if (host->quirks & RT_SDHCI_QUIRK_FORCE_DMA) - host->flags |= RT_SDHCI_USE_SDMA; - else if (!(host->caps & RT_SDHCI_CAN_DO_SDMA)) - LOG_D("Controller doesn't have SDMA capability\n"); - else - host->flags |= RT_SDHCI_USE_SDMA; - - if ((host->quirks & RT_SDHCI_QUIRK_BROKEN_DMA) && (host->flags & RT_SDHCI_USE_SDMA)) - { - LOG_D("Disabling DMA as it is marked broken\n"); - host->flags &= ~RT_SDHCI_USE_SDMA; - } - - if (sdhci_can_64bit_dma(host)) - host->flags |= RT_SDHCI_USE_64_BIT_DMA; - - if (host->flags & RT_SDHCI_USE_SDMA) - { - if (host->ops->set_dma_mask) - ret = host->ops->set_dma_mask(host); - - if (!ret && host->ops->enable_dma) - ret = host->ops->enable_dma(host); - - if (ret) - { - rt_kprintf("%s: No suitable DMA available - falling back to PIO\n", - mmc_hostname(mmc)); - host->flags &= ~RT_SDHCI_USE_SDMA; - - ret = 0; - } - } - - if ((host->flags & RT_SDHCI_USE_64_BIT_DMA) && !host->v4_mode) - host->flags &= ~RT_SDHCI_USE_SDMA; - - if (!(host->flags & RT_SDHCI_USE_SDMA)) - { - host->dma_mask = DMA_BIT_MASK(64); - } - if (host->version >= RT_SDHCI_SPEC_300) - host->max_clk = FIELD_GET(RT_SDHCI_CLOCK_V3_BASE_MASK, host->caps); - else - host->max_clk = FIELD_GET(RT_SDHCI_CLOCK_BASE_MASK, host->caps); - - host->max_clk *= 1000000; - if (host->max_clk == 0 || host->quirks & RT_SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN) - { - if (!host->ops->get_max_clock) - { - rt_kprintf("%s: Hardware doesn't specify base clock frequency. %p \n", - mmc_hostname(mmc), host->ops->get_max_clock); - ret = -ENODEV; - goto undma; - } - host->max_clk = host->ops->get_max_clock(host); - } - - host->clk_mul = FIELD_GET(RT_SDHCI_CLOCK_MUL_MASK, host->caps1); - - if (host->clk_mul) - host->clk_mul += 1; - - max_clk = host->max_clk; - - if (host->ops->get_min_clock) - mmc->f_min = host->ops->get_min_clock(host); - else if (host->version >= RT_SDHCI_SPEC_300) - { - if (host->clk_mul) - max_clk = host->max_clk * host->clk_mul; - - mmc->f_min = host->max_clk / RT_SDHCI_MAX_DIV_SPEC_300; - } - else - mmc->f_min = host->max_clk / RT_SDHCI_MAX_DIV_SPEC_200; - - if (!mmc->f_max || mmc->f_max > max_clk) - mmc->f_max = max_clk; - - if (!(host->quirks & RT_SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) - { - host->timeout_clk = FIELD_GET(RT_SDHCI_TIMEOUT_CLK_MASK, host->caps); - - if (host->caps & RT_SDHCI_TIMEOUT_CLK_UNIT) - host->timeout_clk *= 1000; - - if (host->timeout_clk == 0) - { - if (!host->ops->get_timeout_clock) - { - rt_kprintf("%s: Hardware doesn't specify timeout clock frequency.\n", - mmc_hostname(mmc)); - ret = -ENODEV; - goto undma; - } - - host->timeout_clk = - DIV_ROUND_UP(host->ops->get_timeout_clock(host), - 1000); - } - - if (override_timeout_clk) - host->timeout_clk = override_timeout_clk; - - mmc->max_busy_timeout = host->ops->get_max_timeout_count ? host->ops->get_max_timeout_count(host) : 1 << 27; - mmc->max_busy_timeout /= host->timeout_clk; - } - - if (host->quirks2 & RT_SDHCI_QUIRK2_DISABLE_HW_TIMEOUT && !host->ops->get_max_timeout_count) - mmc->max_busy_timeout = 0; - - mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_CMD23; - mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; - - if (host->quirks & RT_SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) - host->flags |= RT_SDHCI_AUTO_CMD12; - - if ((host->version >= RT_SDHCI_SPEC_300) && (!(host->flags & RT_SDHCI_USE_SDMA) || host->v4_mode) && !(host->quirks2 & RT_SDHCI_QUIRK2_ACMD23_BROKEN)) - { - host->flags |= RT_SDHCI_AUTO_CMD23; - LOG_D("Auto-CMD23 available\n"); - } - else - { - LOG_D("Auto-CMD23 unavailable\n"); - } - - if (!(host->quirks & RT_SDHCI_QUIRK_FORCE_1_BIT_DATA)) - mmc->caps |= MMC_CAP_4_BIT_DATA; - - if (host->quirks2 & RT_SDHCI_QUIRK2_HOST_NO_CMD23) - mmc->caps &= ~MMC_CAP_CMD23; - - if (host->caps & RT_SDHCI_CAN_DO_HISPD) - mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; - if ((host->quirks & RT_SDHCI_QUIRK_BROKEN_CARD_DETECTION) && mmc_card_is_removable(mmc) && rt_mmc_gpio_get_cd(mmc) < 0) - mmc->caps |= MMC_CAP_NEEDS_POLL; - - if (mmc->supply.vqmmc) - { - if (enable_vqmmc) - { - host->sdhci_core_to_disable_vqmmc = !ret; - } - - if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 1700000, - 1950000)) - host->caps1 &= ~(RT_SDHCI_SUPPORT_SDR104 | RT_SDHCI_SUPPORT_SDR50 | RT_SDHCI_SUPPORT_DDR50); - - if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 2700000, - 3600000)) - host->flags &= ~RT_SDHCI_SIGNALING_330; - - if (ret) - { - rt_kprintf("%s: Failed to enable vqmmc regulator: %d\n", - mmc_hostname(mmc), ret); - mmc->supply.vqmmc = (void *)-EINVAL; - } - } - if (host->quirks2 & RT_SDHCI_QUIRK2_NO_1_8_V) - { - host->caps1 &= ~(RT_SDHCI_SUPPORT_SDR104 | RT_SDHCI_SUPPORT_SDR50 | RT_SDHCI_SUPPORT_DDR50); - mmc->caps2 &= ~(MMC_CAP2_HSX00_1_8V | MMC_CAP2_HS400_ES); - mmc->caps &= ~(MMC_CAP_1_8V_DDR | MMC_CAP_UHS); - } - - if (host->caps1 & (RT_SDHCI_SUPPORT_SDR104 | RT_SDHCI_SUPPORT_SDR50 | RT_SDHCI_SUPPORT_DDR50)) - mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25; - - if (host->caps1 & RT_SDHCI_SUPPORT_SDR104) - { - mmc->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50; - - if (!(host->quirks2 & RT_SDHCI_QUIRK2_BROKEN_HS200)) - mmc->caps2 |= MMC_CAP2_HS200; - } - else if (host->caps1 & RT_SDHCI_SUPPORT_SDR50) - { - mmc->caps |= MMC_CAP_UHS_SDR50; - } - - if (host->quirks2 & RT_SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 && (host->caps1 & RT_SDHCI_SUPPORT_HS400)) - mmc->caps2 |= MMC_CAP2_HS400; - if ((mmc->caps2 & MMC_CAP2_HSX00_1_2V) && (!mmc->supply.vqmmc || !regulator_is_supported_voltage(mmc->supply.vqmmc, 1100000, 1300000))) - mmc->caps2 &= ~MMC_CAP2_HSX00_1_2V; - if ((host->caps1 & RT_SDHCI_SUPPORT_DDR50) && !(host->quirks2 & RT_SDHCI_QUIRK2_BROKEN_DDR50)) - mmc->caps |= MMC_CAP_UHS_DDR50; - - if (host->caps1 & RT_SDHCI_USE_SDR50_TUNING) - host->flags |= RT_SDHCI_SDR50_NEEDS_TUNING; - - if (host->caps1 & RT_SDHCI_DRIVER_TYPE_A) - mmc->caps |= MMC_CAP_DRIVER_TYPE_A; - if (host->caps1 & RT_SDHCI_DRIVER_TYPE_C) - mmc->caps |= MMC_CAP_DRIVER_TYPE_C; - if (host->caps1 & RT_SDHCI_DRIVER_TYPE_D) - mmc->caps |= MMC_CAP_DRIVER_TYPE_D; - - host->tuning_count = FIELD_GET(RT_SDHCI_RETUNING_TIMER_COUNT_MASK, - host->caps1); - - if (host->tuning_count) - host->tuning_count = 1 << (host->tuning_count - 1); - - /* Re-tuning mode supported by the Host Controller */ - host->tuning_mode = FIELD_GET(RT_SDHCI_RETUNING_MODE_MASK, host->caps1); - - ocr_avail = 0; - - max_current_caps = rt_sdhci_readl(host, RT_SDHCI_MAX_CURRENT); - - if (!max_current_caps && mmc->supply.vmmc) - { - int curr = regulator_get_current_limit(mmc->supply.vmmc); - if (curr > 0) - { - curr = curr / 1000; /* convert to mA */ - curr = curr / RT_SDHCI_MAX_CURRENT_MULTIPLIER; - - curr = min_t(rt_uint32_t, curr, RT_SDHCI_MAX_CURRENT_LIMIT); - max_current_caps = - FIELD_PREP(RT_SDHCI_MAX_CURRENT_330_MASK, curr) | FIELD_PREP(RT_SDHCI_MAX_CURRENT_300_MASK, curr) | FIELD_PREP(RT_SDHCI_MAX_CURRENT_180_MASK, curr); - } - } - - if (host->caps & RT_SDHCI_CAN_VDD_330) - { - ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34; - - mmc->max_current_330 = FIELD_GET(RT_SDHCI_MAX_CURRENT_330_MASK, - max_current_caps) - * RT_SDHCI_MAX_CURRENT_MULTIPLIER; - } - if (host->caps & RT_SDHCI_CAN_VDD_300) - { - ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31; - - mmc->max_current_300 = FIELD_GET(RT_SDHCI_MAX_CURRENT_300_MASK, - max_current_caps) - * RT_SDHCI_MAX_CURRENT_MULTIPLIER; - } - if (host->caps & RT_SDHCI_CAN_VDD_180) - { - ocr_avail |= MMC_VDD_165_195; - - mmc->max_current_180 = FIELD_GET(RT_SDHCI_MAX_CURRENT_180_MASK, - max_current_caps) - * RT_SDHCI_MAX_CURRENT_MULTIPLIER; - } - - if (host->ocr_mask) - ocr_avail = host->ocr_mask; - - if (mmc->ocr_avail) - ocr_avail = mmc->ocr_avail; - - mmc->ocr_avail = ocr_avail; - mmc->ocr_avail_sdio = ocr_avail; - if (host->ocr_avail_sdio) - mmc->ocr_avail_sdio &= host->ocr_avail_sdio; - mmc->ocr_avail_sd = ocr_avail; - if (host->ocr_avail_sd) - mmc->ocr_avail_sd &= host->ocr_avail_sd; - else - mmc->ocr_avail_sd &= ~MMC_VDD_165_195; - mmc->ocr_avail_mmc = ocr_avail; - if (host->ocr_avail_mmc) - mmc->ocr_avail_mmc &= host->ocr_avail_mmc; - - if (mmc->ocr_avail == 0) - { - rt_kprintf("%s: Hardware doesn't report any support voltages.\n", - mmc_hostname(mmc)); - ret = -ENODEV; - goto unreg; - } - - if ((mmc->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR)) || (mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS400_1_8V))) - host->flags |= RT_SDHCI_SIGNALING_180; - - if (mmc->caps2 & MMC_CAP2_HSX00_1_2V) - host->flags |= RT_SDHCI_SIGNALING_120; - - rt_spin_lock_init(&host->lock); - - mmc->max_req_size = 524288; - if (host->flags & RT_SDHCI_USE_SDMA) - { - mmc->max_segs = 1; - } - else - { /* PIO */ - mmc->max_segs = RT_SDHCI_MAX_SEGS; - } - - mmc->max_seg_size = mmc->max_req_size; - - if (host->quirks & RT_SDHCI_QUIRK_FORCE_BLK_SZ_2048) - { - mmc->max_blk_size = 2; - } - else - { - mmc->max_blk_size = (host->caps & RT_SDHCI_MAX_BLOCK_MASK) >> RT_SDHCI_MAX_BLOCK_SHIFT; - if (mmc->max_blk_size >= 3) - { - rt_kprintf("%s: Invalid maximum block size, assuming 512 bytes\n", - mmc_hostname(mmc)); - mmc->max_blk_size = 0; - } - } - - mmc->max_blk_size = 512 << mmc->max_blk_size; - - /* - * Maximum block count. - */ - mmc->max_blk_count = (host->quirks & RT_SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535; - return 0; - -unreg: -undma: - return ret; -} - -static void sdhci_init(struct rt_sdhci_host *host, int soft) -{ - struct rt_mmc_host *mmc = host->mmc; - rt_base_t flags; - - if (soft) - { - sdhci_do_reset(host, RT_SDHCI_RESET_CMD | RT_SDHCI_RESET_DATA); - } - else - { - sdhci_do_reset(host, RT_SDHCI_RESET_ALL); - } - if (host->v4_mode) - { - sdhci_do_enable_v4_mode(host); - } - flags = rt_spin_lock_irqsave(&host->lock); - sdhci_set_default_irqs(host); - rt_spin_unlock_irqrestore(&host->lock, flags); - - host->cqe_on = RT_FALSE; - - if (soft) - { - /* force clock reconfiguration */ - host->clock = 0; - host->reinit_uhs = RT_TRUE; - mmc->ops->set_ios(mmc, &mmc->ios); - } -} - -static void sdhci_reinit(struct rt_sdhci_host *host) -{ - rt_uint32_t cd = host->ier & (RT_SDHCI_INT_CARD_REMOVE | RT_SDHCI_INT_CARD_INSERT); - - sdhci_init(host, 0); - sdhci_enable_card_detection(host); - - if (cd != (host->ier & (RT_SDHCI_INT_CARD_REMOVE | RT_SDHCI_INT_CARD_INSERT))) - rt_mmc_detect_change(host->mmc, rt_tick_from_millisecond(200)); -} - -int rt_sdhci_init_host(struct rt_sdhci_host *host) -{ - struct rt_mmc_host *mmc = host->mmc; - int ret; - - if ((mmc->caps2 & MMC_CAP2_CQE) && (host->quirks & RT_SDHCI_QUIRK_BROKEN_CQE)) - { - mmc->caps2 &= ~MMC_CAP2_CQE; - } - - host->complete_wq = rt_workqueue_create("sdhci", 4096, 20); - if (!host->complete_wq) - return -ENOMEM; - - rt_work_init(&host->complete_work, sdhci_complete_work, host); - - rt_timer_init(&host->timer, "sdhci_timer", sdhci_timeout_timer, host, 0, RT_TIMER_FLAG_SOFT_TIMER); - rt_timer_init(&host->data_timer, "sdhci_data_timer", sdhci_timeout_data_timer, host, 0, RT_TIMER_FLAG_SOFT_TIMER); - - rt_wqueue_init(&host->buf_ready_int); - - sdhci_init(host, 0); - - host->irq_wq = rt_workqueue_create("sdhci_irq", 8192, 1); - rt_work_init(&host->irq_work, sdhci_thread_irq, host); - rt_hw_interrupt_install(host->irq, sdhci_irq, host, mmc_hostname(mmc)); - rt_pic_irq_unmask(host->irq); - ret = rt_mmc_add_host(mmc); - if (ret) - goto unirq; - - LOG_D("%s: RT_SDHCI controller on %s [%s] using %s\n", - mmc_hostname(mmc), host->hw_name, mmc_dev(mmc)->parent.name, - (host->flags & RT_SDHCI_USE_SDMA) ? "DMA" : "PIO"); - - sdhci_enable_card_detection(host); - - return 0; - -unirq: - sdhci_reset_for_all(host); - rt_sdhci_writel(host, 0, RT_SDHCI_INT_ENABLE); - rt_sdhci_writel(host, 0, RT_SDHCI_SIGNAL_ENABLE); - - return ret; -} - -int rt_sdhci_set_and_add_host(struct rt_sdhci_host *host) -{ - int ret; - ret = rt_sdhci_setup_host(host); - if (ret) - return ret; - - ret = rt_sdhci_init_host(host); - if (ret) - goto cleanup; - - return 0; - -cleanup: - rt_sdhci_cleanup_host(host); - - return ret; -} - -void rt_sdhci_ios_set(struct rt_mmc_host *mmc, struct rt_mmcsd_io_cfg *ios) -{ - struct rt_sdhci_host *host = mmc_priv(mmc); - rt_bool_t reinit_uhs = host->reinit_uhs; - rt_bool_t turning_on_clk = RT_FALSE; - rt_uint8_t ctrl; - - host->reinit_uhs = RT_FALSE; - - if (ios->power_mode == MMC_POWER_UNDEFINED) - return; - - if (host->flags & RT_SDHCI_DEVICE_DEAD) - { - if (mmc->supply.vmmc && ios->power_mode == MMC_POWER_OFF) - mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); - return; - } - - if (ios->power_mode == MMC_POWER_OFF) - { - rt_sdhci_writel(host, 0, RT_SDHCI_SIGNAL_ENABLE); - sdhci_reinit(host); - } - - if (host->version >= RT_SDHCI_SPEC_300 && (ios->power_mode == MMC_POWER_UP) && !(host->quirks2 & RT_SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) - sdhci_preset_value_enable(host, RT_FALSE); - - if (!ios->clock || ios->clock != host->clock) - { - turning_on_clk = ios->clock && !host->clock; - - host->ops->set_clock(host, ios->clock); - host->clock = ios->clock; - - if (host->quirks & RT_SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK && host->clock) - { - host->timeout_clk = mmc->actual_clock ? mmc->actual_clock / 1000 : host->clock / 1000; - mmc->max_busy_timeout = - host->ops->get_max_timeout_count ? host->ops->get_max_timeout_count(host) : 1 << 27; - mmc->max_busy_timeout /= host->timeout_clk; - } - } - - if (host->ops->set_power) - host->ops->set_power(host, ios->power_mode, ios->vdd); - else - rt_sdhci_set_power(host, ios->power_mode, ios->vdd); - - host->ops->set_bus_width(host, ios->bus_width); - - if (!reinit_uhs && turning_on_clk && host->timing == ios->timing && host->version >= RT_SDHCI_SPEC_300 && !sdhci_presetable_values_change(host, ios)) - return; - - ctrl = rt_sdhci_readb(host, RT_SDHCI_HOST_CONTROL); - - if (!(host->quirks & RT_SDHCI_QUIRK_NO_HISPD_BIT)) - { - if (ios->timing == MMC_TIMING_SD_HS || ios->timing == MMC_TIMING_MMC_HS || ios->timing == MMC_TIMING_MMC_HS400 || ios->timing == MMC_TIMING_MMC_HS200 || ios->timing == MMC_TIMING_MMC_DDR52 || ios->timing == MMC_TIMING_UHS_SDR50 || ios->timing == MMC_TIMING_UHS_SDR104 || ios->timing == MMC_TIMING_UHS_DDR50 || ios->timing == MMC_TIMING_UHS_SDR25) - ctrl |= RT_SDHCI_CTRL_HISPD; - else - ctrl &= ~RT_SDHCI_CTRL_HISPD; - } - - if (host->version >= RT_SDHCI_SPEC_300) - { - rt_uint16_t clk, ctrl_2; - - clk = rt_sdhci_readw(host, RT_SDHCI_CLOCK_CONTROL); - if (clk & RT_SDHCI_CLOCK_CARD_EN) - { - clk &= ~RT_SDHCI_CLOCK_CARD_EN; - rt_sdhci_writew(host, clk, RT_SDHCI_CLOCK_CONTROL); - } - - rt_sdhci_writeb(host, ctrl, RT_SDHCI_HOST_CONTROL); - - if (!host->preset_enabled) - { - ctrl_2 = rt_sdhci_readw(host, RT_SDHCI_HOST_CONTROL2); - ctrl_2 &= ~RT_SDHCI_CTRL_DRV_TYPE_MASK; - if (ios->drv_type == MMC_SET_DRIVER_TYPE_A) - ctrl_2 |= RT_SDHCI_CTRL_DRV_TYPE_A; - else if (ios->drv_type == MMC_SET_DRIVER_TYPE_B) - ctrl_2 |= RT_SDHCI_CTRL_DRV_TYPE_B; - else if (ios->drv_type == MMC_SET_DRIVER_TYPE_C) - ctrl_2 |= RT_SDHCI_CTRL_DRV_TYPE_C; - else if (ios->drv_type == MMC_SET_DRIVER_TYPE_D) - ctrl_2 |= RT_SDHCI_CTRL_DRV_TYPE_D; - else - { - LOG_D("%s: invalid driver type, default to driver type B\n", - mmc_hostname(mmc)); - ctrl_2 |= RT_SDHCI_CTRL_DRV_TYPE_B; - } - - rt_sdhci_writew(host, ctrl_2, RT_SDHCI_HOST_CONTROL2); - host->drv_type = ios->drv_type; - } - - host->ops->set_uhs_signaling(host, ios->timing); - host->timing = ios->timing; - - if (sdhci_preset_needed(host, ios->timing)) - { - rt_uint16_t preset; - - sdhci_preset_value_enable(host, RT_TRUE); - preset = sdhci_get_preset_value(host); - ios->drv_type = FIELD_GET(RT_SDHCI_PRESET_DRV_MASK, - preset); - host->drv_type = ios->drv_type; - } - - host->ops->set_clock(host, host->clock); - } - else - rt_sdhci_writeb(host, ctrl, RT_SDHCI_HOST_CONTROL); -} -void rt_sdhci_free_host(struct rt_sdhci_host *host) -{ - rt_sdhci_cleanup_host(host); - rt_free(host); -} diff --git a/rt-thread/components/drivers/sensor/Kconfig b/rt-thread/components/drivers/sensor/Kconfig index 976e6a7..86f8711 100644 --- a/rt-thread/components/drivers/sensor/Kconfig +++ b/rt-thread/components/drivers/sensor/Kconfig @@ -10,6 +10,6 @@ if RT_USING_SENSOR config RT_USING_SENSOR_CMD bool "Using Sensor cmd" - select RT_KLIBC_USING_VSNPRINTF_STANDARD if RT_USING_SENSOR_V2 + select PKG_USING_RT_VSNPRINTF_FULL if RT_USING_SENSOR_V2 default y endif diff --git a/rt-thread/components/drivers/sensor/v1/sensor.c b/rt-thread/components/drivers/sensor/v1/sensor.c index 479cf83..6da12f9 100644 --- a/rt-thread/components/drivers/sensor/v1/sensor.c +++ b/rt-thread/components/drivers/sensor/v1/sensor.c @@ -40,10 +40,7 @@ static char *const sensor_name_str[] = "spo2_", /* SpO2 sensor */ "iaq_", /* IAQ sensor */ "etoh_", /* EtOH sensor */ - "bp_", /* Blood Pressure */ - "volt_", /* Voltage sensor */ - "curr_", /* Current sensor */ - "pow_" /* Power sensor */ + "bp_" /* Blood Pressure */ }; /* Sensor interrupt correlation function */ diff --git a/rt-thread/components/drivers/sensor/v1/sensor_cmd.c b/rt-thread/components/drivers/sensor/v1/sensor_cmd.c index 486bd0b..0410af4 100644 --- a/rt-thread/components/drivers/sensor/v1/sensor_cmd.c +++ b/rt-thread/components/drivers/sensor/v1/sensor_cmd.c @@ -83,15 +83,6 @@ static void sensor_show_data(rt_size_t num, rt_sensor_t sensor, struct rt_sensor case RT_SENSOR_CLASS_BP: LOG_I("num:%3d, bp.sbp:%5d mmHg, bp.dbp:%5d mmHg, timestamp:%5d", num, sensor_data->data.bp.sbp, sensor_data->data.bp.dbp, sensor_data->timestamp); break; - case RT_SENSOR_CLASS_VOLTAGE: - LOG_I("num:%3d, voltage:%5d mV, timestamp:%5d", num, sensor_data->data.mv, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_CURRENT: - LOG_I("num:%3d, current:%5d mA, timestamp:%5d", num, sensor_data->data.ma, sensor_data->timestamp); - break; - case RT_SENSOR_CLASS_POWER: - LOG_I("num:%3d, power:%5d mW, timestamp:%5d", num, sensor_data->data.mv, sensor_data->timestamp); - break; default: break; } @@ -290,7 +281,7 @@ static void sensor_polling(int argc, char **argv) MSH_CMD_EXPORT(sensor_polling, Sensor polling mode test function); #endif -static int sensor(int argc, char **argv) +static void sensor(int argc, char **argv) { static rt_device_t dev = RT_NULL; struct rt_sensor_data data; @@ -311,7 +302,7 @@ static int sensor(int argc, char **argv) rt_kprintf(" sodr Set output date rate to var\n"); rt_kprintf(" read [num] Read [num] times sensor\n"); rt_kprintf(" num default 5\n"); - return -RT_EINVAL; + return ; } else if (!strcmp(argv[1], "info")) { @@ -319,7 +310,7 @@ static int sensor(int argc, char **argv) if (dev == RT_NULL) { LOG_W("Please probe sensor device first!"); - return -RT_ERROR; + return ; } rt_device_control(dev, RT_SENSOR_CTRL_GET_INFO, &info); switch (info.vendor) @@ -427,15 +418,6 @@ static int sensor(int argc, char **argv) case RT_SENSOR_UNIT_MMHG: rt_kprintf("unit :mmHg\n"); break; - case RT_SENSOR_UNIT_MV: - rt_kprintf("unit :mV\n"); - break; - case RT_SENSOR_UNIT_MA: - rt_kprintf("unit :mA\n"); - break; - case RT_SENSOR_UNIT_MW: - rt_kprintf("unit :mW\n"); - break; } rt_kprintf("range_max :%d\n", info.range_max); rt_kprintf("range_min :%d\n", info.range_min); @@ -449,7 +431,7 @@ static int sensor(int argc, char **argv) if (dev == RT_NULL) { LOG_W("Please probe sensor device first!"); - return -RT_ERROR; + return ; } if (argc == 3) { @@ -487,12 +469,12 @@ static int sensor(int argc, char **argv) if (dev == RT_NULL) { LOG_E("Can't find device:%s", argv[2]); - return -RT_ERROR; + return; } if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK) { LOG_E("open device failed!"); - return -RT_ERROR; + return; } rt_device_control(dev, RT_SENSOR_CTRL_GET_ID, ®); LOG_I("device id: 0x%x!", reg); @@ -501,7 +483,7 @@ static int sensor(int argc, char **argv) else if (dev == RT_NULL) { LOG_W("Please probe sensor first!"); - return -RT_ERROR; + return ; } else if (!strcmp(argv[1], "sr")) { @@ -528,8 +510,6 @@ static int sensor(int argc, char **argv) { LOG_W("Unknown command, please enter 'sensor' get help information!"); } - - return RT_EOK; } #ifdef RT_USING_FINSH MSH_CMD_EXPORT(sensor, sensor test function); diff --git a/rt-thread/components/drivers/sensor/v2/sensor_cmd.c b/rt-thread/components/drivers/sensor/v2/sensor_cmd.c index 1b65c00..e278f34 100644 --- a/rt-thread/components/drivers/sensor/v2/sensor_cmd.c +++ b/rt-thread/components/drivers/sensor/v2/sensor_cmd.c @@ -550,7 +550,7 @@ static void sensor_cmd_warning_probe(void) LOG_W("Please probe sensor device first!"); } -static int sensor(int argc, char **argv) +static void sensor(int argc, char **argv) { static rt_device_t dev = RT_NULL; struct rt_sensor_data data; @@ -562,14 +562,14 @@ static int sensor(int argc, char **argv) if (argc < 2) { sensor_cmd_warning_unknown(); - return -RT_ERROR; + return; } else if (!rt_strcmp(argv[1], "info")) { if (dev == RT_NULL) { sensor_cmd_warning_probe(); - return -RT_ERROR; + return ; } sensor = (rt_sensor_t)dev; rt_kprintf("name :%s\n", sensor->info.name); @@ -595,7 +595,7 @@ static int sensor(int argc, char **argv) if (dev == RT_NULL) { sensor_cmd_warning_probe(); - return -RT_ERROR; + return; } if (argc == 3) { @@ -628,7 +628,7 @@ static int sensor(int argc, char **argv) information = rt_object_get_information(RT_Object_Class_Device); if(information == RT_NULL) - return -RT_ERROR; + return; rt_kprintf("device name sensor name sensor type mode resolution range\n"); rt_kprintf("----------- ------------- ------------------ ---- ---------- ----------\n"); @@ -655,7 +655,7 @@ static int sensor(int argc, char **argv) if (dev == RT_NULL) { sensor_cmd_warning_probe(); - return -RT_ERROR; + return; } if (rt_device_control(dev, RT_SENSOR_CTRL_SOFT_RESET, RT_NULL) != RT_EOK) @@ -671,19 +671,19 @@ static int sensor(int argc, char **argv) if (argc < 3) { sensor_cmd_warning_unknown(); - return -RT_ERROR; + return; } new_dev = rt_device_find(argv[2]); if (new_dev == RT_NULL) { LOG_E("Can't find device:%s", argv[2]); - return -RT_ERROR; + return; } if (rt_device_open(new_dev, RT_DEVICE_FLAG_RDWR) != RT_EOK) { LOG_E("open device failed!"); - return -RT_ERROR; + return; } if (rt_device_control(new_dev, RT_SENSOR_CTRL_GET_ID, ®) == RT_EOK) { @@ -702,7 +702,7 @@ static int sensor(int argc, char **argv) if (dev == RT_NULL) { sensor_cmd_warning_probe(); - return -RT_ERROR; + return; } sensor = (rt_sensor_t)dev; @@ -734,7 +734,7 @@ static int sensor(int argc, char **argv) if (dev == RT_NULL) { sensor_cmd_warning_probe(); - return -RT_ERROR; + return; } sensor = (rt_sensor_t)dev; @@ -766,7 +766,7 @@ static int sensor(int argc, char **argv) if (dev == RT_NULL) { sensor_cmd_warning_probe(); - return -RT_ERROR; + return; } sensor = (rt_sensor_t)dev; @@ -795,7 +795,5 @@ static int sensor(int argc, char **argv) { sensor_cmd_warning_unknown(); } - - return RT_EOK; } MSH_CMD_EXPORT(sensor, sensor test function); diff --git a/rt-thread/components/drivers/serial/Kconfig b/rt-thread/components/drivers/serial/Kconfig index 349aaea..00fcfb6 100644 --- a/rt-thread/components/drivers/serial/Kconfig +++ b/rt-thread/components/drivers/serial/Kconfig @@ -21,7 +21,4 @@ menuconfig RT_USING_SERIAL int "Set RX buffer size" depends on !RT_USING_SERIAL_V2 default 64 - config RT_USING_SERIAL_BYPASS - bool "Using serial bypass" - default n - endif + endif diff --git a/rt-thread/components/drivers/serial/SConscript b/rt-thread/components/drivers/serial/SConscript index 04fa37e..7ee41a4 100644 --- a/rt-thread/components/drivers/serial/SConscript +++ b/rt-thread/components/drivers/serial/SConscript @@ -12,12 +12,9 @@ if GetDepend(['RT_USING_SMART']): src += Glob('serial_tty.c') if GetDepend(['RT_USING_SERIAL_V2']): - src += ['dev_serial_v2.c'] + src += ['serial_v2.c'] else: - src += ['dev_serial.c'] - -if GetDepend(['RT_USING_SERIAL_BYPASS']): - src += ['bypass.c'] + src += ['serial.c'] if GetDepend(['RT_USING_DM']): src += ['serial_dm.c'] diff --git a/rt-thread/components/drivers/serial/bypass.c b/rt-thread/components/drivers/serial/bypass.c deleted file mode 100644 index 04ed71a..0000000 --- a/rt-thread/components/drivers/serial/bypass.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-11-20 zhujiale the first version - */ - -#include -#define DBG_TAG "UART" -#define DBG_LVL DBG_INFO -#include - -static struct rt_serial_bypass_func* rt_bypass_alloc_func(const char* name, rt_uint8_t level, bypass_function_t func, void* data) -{ - struct rt_serial_bypass_func* bypass; - - if (!func) - return RT_NULL; - - bypass = rt_malloc(sizeof(struct rt_serial_bypass_func)); - rt_memset(bypass, 0, sizeof(struct rt_serial_bypass_func)); - - if (rt_strlen(name) > RT_NAME_MAX - 1) - rt_memcpy(bypass->name, name, RT_NAME_MAX); - else - rt_memcpy(bypass->name, name, rt_strlen(name) + 1); - - bypass->level = level; - - rt_list_init(&bypass->node); - bypass->bypass = func; - bypass->data = data; - - return bypass; -} - -rt_err_t rt_serial_bypass_init(struct rt_serial_device* serial) -{ - serial->bypass = rt_malloc(sizeof(struct rt_serial_bypass)); - rt_memset(serial->bypass, 0, sizeof(struct rt_serial_bypass)); - serial->bypass->pipe = rt_ringbuffer_create(serial->config.bufsz); - serial->bypass->mutex = rt_mutex_create("serial_bypass", RT_IPC_FLAG_FIFO); - - return RT_EOK; -} - -static rt_err_t rt_bypass_register(struct rt_serial_bypass_head* bypass, const char* name, rt_uint8_t level, bypass_function_t func, void* data) -{ - struct rt_serial_bypass_func* pass = RT_NULL; - struct rt_list_node* node; - int flags; - - RT_DEBUG_NOT_IN_INTERRUPT; - - pass = rt_bypass_alloc_func(name, level, func, data); - - RT_ASSERT(bypass != RT_NULL); - - node = bypass->head.next; - - if (node == &bypass->head) - { - rt_list_insert_before(&pass->node, node); - return RT_EOK; - } - flags = rt_spin_lock_irqsave(&(bypass->spinlock)); - do { - struct rt_serial_bypass_func* temp_curr; - temp_curr = rt_container_of(node, struct rt_serial_bypass_func, node); - - if (level < temp_curr->level) - { - rt_list_insert_before(node, &pass->node); - - rt_spin_unlock_irqrestore(&(bypass->spinlock), flags); - return RT_EOK; - } - else if (level == temp_curr->level) - { - rt_spin_unlock_irqrestore(&(bypass->spinlock), flags); - LOG_E("Conflict: bypass [%s] level conflicts with [%s] at level [%d]\n", name, temp_curr->name, level); - rt_free(pass); - return -RT_ERROR; - } - - node = node->next; - - } while (node != &bypass->head); - - rt_list_insert_before(&bypass->head, &pass->node); - - rt_spin_unlock_irqrestore(&(bypass->spinlock), flags); - return RT_EOK; - -} - -rt_err_t rt_bypass_upper_register(struct rt_serial_device* serial, const char* name, rt_uint8_t level, bypass_function_t func, void* data) -{ - if (!serial->bypass) - rt_serial_bypass_init(serial); - - if (!serial->bypass->upper_h) - { - serial->bypass->upper_h = rt_malloc(sizeof(struct rt_serial_bypass_head)); - rt_spin_lock_init(&serial->bypass->upper_h->spinlock); - rt_list_init(&serial->bypass->upper_h->head); - - } - - return rt_bypass_register(serial->bypass->upper_h, name, level, func, data); -} - - - -void rt_bypass_putchar(struct rt_serial_device* serial, rt_uint8_t ch) -{ - rt_mutex_take(serial->bypass->mutex, RT_WAITING_FOREVER); - rt_ringbuffer_putchar(serial->bypass->pipe, ch); - rt_mutex_release(serial->bypass->mutex); -} - -rt_size_t rt_bypass_getchar(struct rt_serial_device* serial, rt_uint8_t* ch) -{ - int flags; - rt_mutex_take(serial->bypass->mutex, RT_WAITING_FOREVER); - flags = rt_ringbuffer_getchar(serial->bypass->pipe, ch); - rt_mutex_release(serial->bypass->mutex); - return flags; -} - -static inline rt_err_t _bypass_getchar_form_serial_fifo(struct rt_serial_device* serial, char* ch) -{ - rt_base_t level; - struct rt_serial_rx_fifo* rx_fifo; - rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx; - /* disable interrupt */ - level = rt_spin_lock_irqsave(&(serial->spinlock)); - - /* there's no data: */ - if ((rx_fifo->get_index == rx_fifo->put_index) && (rx_fifo->is_full == RT_FALSE)) - { - /* no data, enable interrupt and break out */ - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - return -RT_EEMPTY; - } - - /* otherwise there's the data: */ - *ch = rx_fifo->buffer[rx_fifo->get_index]; - rx_fifo->get_index += 1; - if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0; - - if (rx_fifo->is_full == RT_TRUE) - { - rx_fifo->is_full = RT_FALSE; - } - - /* enable interrupt */ - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - - return RT_EOK; -} - -static void _lower_work(struct rt_serial_device* serial) -{ - struct rt_list_node* node; - struct rt_serial_bypass_func* temp_curr = RT_NULL; - if (serial->bypass && serial->bypass->lower_h) - { - while (1) - { - char ch; - if (_bypass_getchar_form_serial_fifo(serial, &ch)) - return; - - node = serial->bypass->lower_h->head.next; - - while (node != &serial->bypass->lower_h->head) - { - temp_curr = rt_container_of(node, struct rt_serial_bypass_func, node); - - if (!temp_curr->bypass(serial, ch, temp_curr->data)) - { - break; - } - - node = node->next; - } - if (node == &serial->bypass->lower_h->head) - { - rt_bypass_putchar(serial, ch); - } - } - } -} - - -static void rt_lower_work(struct rt_work* work, void* work_data) -{ - struct rt_serial_device* serial = (struct rt_serial_device*)work_data; - - RT_ASSERT(serial != RT_NULL); - - _lower_work(serial); -} - -rt_err_t rt_bypass_lower_register(struct rt_serial_device* serial, const char* name, rt_uint8_t level, bypass_function_t func, void* data) -{ - if (!serial->bypass) - rt_serial_bypass_init(serial); - - if (!serial->bypass->lower_h) - { - serial->bypass->lower_workq = rt_workqueue_create("serial bypass", RT_SYSTEM_WORKQUEUE_STACKSIZE, - RT_SYSTEM_WORKQUEUE_PRIORITY); - rt_work_init(&serial->bypass->work, rt_lower_work, (void*)serial); - - serial->bypass->lower_h = rt_malloc(sizeof(struct rt_serial_bypass_head)); - rt_spin_lock_init(&serial->bypass->lower_h->spinlock); - rt_list_init(&serial->bypass->lower_h->head); - - } - - return rt_bypass_register(serial->bypass->lower_h, name, level, func, data); -} - -void rt_bypass_work_straight(struct rt_serial_device* serial) -{ - if (serial->bypass && serial->bypass->lower_h) - { - _lower_work(serial); - return; - } - - while (1) - { - char ch; - if (_bypass_getchar_form_serial_fifo(serial, &ch)) - return; - - rt_bypass_putchar(serial, ch); - } - -} - -rt_err_t rt_bypass_unregister(struct rt_serial_bypass_head* bypass, rt_uint8_t level) -{ - struct rt_list_node* node; - struct rt_serial_bypass_func* temp_curr = RT_NULL; - int flags; - - /*Can not unregister protect level in bypass it general be msh or tty*/ - if (level > RT_BYPASS_PROTECT_LEVEL_1) - return -RT_ERROR; - - if (!bypass) - return -RT_ERROR; - - node = bypass->head.next; - flags = rt_spin_lock_irqsave(&(bypass->spinlock)); - - do { - temp_curr = rt_container_of(node, struct rt_serial_bypass_func, node); - - if (level == temp_curr->level) - { - rt_list_remove(node); - rt_spin_unlock_irqrestore(&(bypass->spinlock), flags); - rt_free(temp_curr); - return RT_EOK; - } - - node = node->next; - } while (node != &bypass->head); - - LOG_E("Can't find bypass with level [%d]", level); - rt_spin_unlock_irqrestore(&(bypass->spinlock), flags); - return -RT_ERROR; -} - -rt_err_t rt_bypass_upper_unregister(struct rt_serial_device* serial, rt_uint8_t level) -{ - if (!serial->bypass || !serial->bypass->upper_h) - return -RT_ERROR; - return rt_bypass_unregister(serial->bypass->upper_h, level); -} - -rt_err_t rt_bypass_lower_unregister(struct rt_serial_device* serial, rt_uint8_t level) -{ - if (!serial->bypass || !serial->bypass->lower_h) - return -RT_ERROR; - return rt_bypass_unregister(serial->bypass->lower_h, level); -} - -int serial_bypass_list(int argc, char** argv) -{ - struct rt_serial_device* serial = RT_NULL; - struct rt_serial_bypass_func* current; - struct rt_list_node* node; - int flags; - - serial = (struct rt_serial_device*)rt_console_get_device(); - if (!serial || !serial->bypass) - { - rt_kprintf("Serial bypass not initialized.\n"); - return -1; - } - - /* 遍历 Upper Bypass 链表 */ - if (serial->bypass->upper_h) - { - rt_kprintf("Upper bypass chain:\n"); - node = serial->bypass->upper_h->head.next; - - flags = rt_spin_lock_irqsave(&(serial->bypass->upper_h->spinlock)); /* 加锁*/ - while (node != &serial->bypass->upper_h->head) - { - current = rt_container_of(node, struct rt_serial_bypass_func, node); - rt_kprintf(" - Name: [%s], Level: [%d]\n", current->name, current->level); - node = node->next; - } - rt_spin_unlock_irqrestore(&(serial->bypass->upper_h->spinlock), flags); /* 解锁*/ - } - else - { - rt_kprintf("Upper bypass chain is empty.\n"); - } - - /* 遍历 Lower Bypass 链表 */ - if (serial->bypass->lower_h) - { - rt_kprintf("Lower bypass chain:\n"); - node = serial->bypass->lower_h->head.next; - - flags = rt_spin_lock_irqsave(&(serial->bypass->lower_h->spinlock)); /* 加锁*/ - while (node != &serial->bypass->lower_h->head) - { - current = rt_container_of(node, struct rt_serial_bypass_func, node); - rt_kprintf(" - Name: [%s], Level: [%d]\n", current->name, current->level); - node = node->next; - } - rt_spin_unlock_irqrestore(&(serial->bypass->lower_h->spinlock), flags); /* 解锁*/ - } - else - { - rt_kprintf("Lower bypass chain is empty.\n"); - } - - return 0; -} - - -MSH_CMD_EXPORT(serial_bypass_list, serial bypass list) diff --git a/rt-thread/components/drivers/serial/dev_serial.c b/rt-thread/components/drivers/serial/dev_serial.c deleted file mode 100644 index 458a5b7..0000000 --- a/rt-thread/components/drivers/serial/dev_serial.c +++ /dev/null @@ -1,1575 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2006-03-13 bernard first version - * 2012-05-15 lgnq modified according bernard's implementation. - * 2012-05-28 bernard code cleanup - * 2012-11-23 bernard fix compiler warning. - * 2013-02-20 bernard use RT_SERIAL_RB_BUFSZ to define - * the size of ring buffer. - * 2014-07-10 bernard rewrite serial framework - * 2014-12-31 bernard use open_flag for poll_tx stream mode. - * 2015-05-19 Quintin fix DMA tx mod tx_dma->activated flag !=RT_FALSE BUG - * in open function. - * 2015-11-10 bernard fix the poll rx issue when there is no data. - * 2016-05-10 armink add fifo mode to DMA rx when serial->config.bufsz != 0. - * 2017-01-19 aubr.cool prevent change serial rx bufsz when serial is opened. - * 2017-11-07 JasonJia fix data bits error issue when using tcsetattr. - * 2017-11-15 JasonJia fix poll rx issue when data is full. - * add TCFLSH and FIONREAD support. - * 2018-12-08 Ernest Chen add DMA choice - * 2020-09-14 WillianChan add a line feed to the carriage return character - * when using interrupt tx - * 2020-12-14 Meco Man implement function of setting window's size(TIOCSWINSZ) - * 2021-08-22 Meco Man implement function of getting window's size(TIOCGWINSZ) - * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable - * 2024-11-25 zhujiale add bypass mode - */ - -#include -#include -#include - -#define DBG_TAG "UART" -#define DBG_LVL DBG_INFO -#include - -#ifdef RT_USING_POSIX_STDIO -#include -#include -#include -#include -#include - -#ifdef RT_USING_POSIX_TERMIOS -#include -#endif - -/* it's possible the 'getc/putc' is defined by stdio.h in gcc/newlib. */ -#ifdef getc -#undef getc -#endif - -#ifdef putc -#undef putc -#endif - -RT_OBJECT_HOOKLIST_DEFINE(rt_hw_serial_rxind); - -static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size) -{ - rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN); - - RT_OBJECT_HOOKLIST_CALL(rt_hw_serial_rxind, (dev, size)); - - return RT_EOK; -} - -/* fops for serial */ -static int serial_fops_open(struct dfs_file *fd) -{ - rt_err_t ret = 0; - rt_uint16_t flags = 0; - rt_device_t device; - - device = (rt_device_t)fd->vnode->data; - RT_ASSERT(device != RT_NULL); - - switch (fd->flags & O_ACCMODE) - { - case O_RDONLY: - LOG_D("fops open: O_RDONLY!"); - flags = RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_RDONLY; - break; - case O_WRONLY: - LOG_D("fops open: O_WRONLY!"); - flags = RT_DEVICE_FLAG_WRONLY; - break; - case O_RDWR: - LOG_D("fops open: O_RDWR!"); - flags = RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_RDWR; - break; - default: - LOG_E("fops open: unknown mode - %d!", fd->flags & O_ACCMODE); - break; - } - - if ((fd->flags & O_ACCMODE) != O_WRONLY) - rt_device_set_rx_indicate(device, serial_fops_rx_ind); - ret = rt_device_open(device, flags); - if (ret == RT_EOK) return 0; - - return ret; -} - -static int serial_fops_close(struct dfs_file *fd) -{ - rt_device_t device; - - device = (rt_device_t)fd->vnode->data; - - rt_device_set_rx_indicate(device, RT_NULL); - rt_device_close(device); - - return 0; -} - -static int serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args) -{ - rt_device_t device; - int flags = (int)(rt_base_t)args; - int mask = O_NONBLOCK | O_APPEND; - - device = (rt_device_t)fd->vnode->data; - switch (cmd) - { - case FIONREAD: - break; - case FIONWRITE: - break; - case F_SETFL: - flags &= mask; - fd->flags &= ~mask; - fd->flags |= flags; - break; - } - - return rt_device_control(device, cmd, args); -} - -#ifdef RT_USING_DFS_V2 -static ssize_t serial_fops_read(struct dfs_file *fd, void *buf, size_t count, off_t *pos) -#else -static ssize_t serial_fops_read(struct dfs_file *fd, void *buf, size_t count) -#endif -{ - int size = 0; - rt_device_t device; - int wait_ret; - - device = (rt_device_t)fd->vnode->data; - - do - { - size = rt_device_read(device, -1, buf, count); - if (size <= 0) - { - if (fd->flags & O_NONBLOCK) - { - size = -EAGAIN; - break; - } - - wait_ret = rt_wqueue_wait_interruptible(&(device->wait_queue), 0, RT_WAITING_FOREVER); - if (wait_ret != RT_EOK) - { - break; - } - } - }while (size <= 0); - - if (size < 0) - { - size = 0; - } - return size; -} - -#ifdef RT_USING_DFS_V2 -static ssize_t serial_fops_write(struct dfs_file *fd, const void *buf, size_t count, off_t *pos) -#else -static ssize_t serial_fops_write(struct dfs_file *fd, const void *buf, size_t count) -#endif -{ - rt_device_t device; - - device = (rt_device_t)fd->vnode->data; - return rt_device_write(device, -1, buf, count); -} - -static int serial_fops_poll(struct dfs_file *fd, struct rt_pollreq *req) -{ - int mask = 0; - int flags = 0; - rt_device_t device; - struct rt_serial_device *serial; - - device = (rt_device_t)fd->vnode->data; - RT_ASSERT(device != RT_NULL); - - serial = (struct rt_serial_device *)device; - - /* only support POLLIN */ - flags = fd->flags & O_ACCMODE; - if (flags == O_RDONLY || flags == O_RDWR) - { - rt_base_t level; - struct rt_serial_rx_fifo* rx_fifo; - - rt_poll_add(&(device->wait_queue), req); - - rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx; - - level = rt_spin_lock_irqsave(&(serial->spinlock)); - if ((rx_fifo->get_index != rx_fifo->put_index) || (rx_fifo->get_index == rx_fifo->put_index && rx_fifo->is_full == RT_TRUE)) - mask |= POLLIN; - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - } - - return mask; -} - -static const struct dfs_file_ops _serial_fops = -{ - .open = serial_fops_open, - .close = serial_fops_close, - .ioctl = serial_fops_ioctl, - .read = serial_fops_read, - .write = serial_fops_write, - .poll = serial_fops_poll, -}; -#endif /* RT_USING_POSIX_STDIO */ - -/* - * Serial poll routines - */ -rt_inline int _serial_poll_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length) -{ - int ch; - int size; - - RT_ASSERT(serial != RT_NULL); - size = length; - - while (length) - { - ch = serial->ops->getc(serial); - if (ch == -1) break; - - *data = ch; - data ++; length --; - - if(serial->parent.open_flag & RT_DEVICE_FLAG_STREAM) - { - if (ch == '\n') break; - } - } - - return size - length; -} - -rt_inline int _serial_poll_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length) -{ - int size; - RT_ASSERT(serial != RT_NULL); - - size = length; - while (length) - { - /* - * to be polite with serial console add a line feed - * to the carriage return character - */ - if (*data == '\n' && (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)) - { - serial->ops->putc(serial, '\r'); - } - - if(serial->ops->putc(serial, *data) < 0) { - break; - } - - ++ data; - -- length; - } - - return size - length; -} - -/* - * Serial interrupt routines - */ -rt_inline int _serial_int_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length) -{ - int size; - struct rt_serial_rx_fifo* rx_fifo; - - RT_ASSERT(serial != RT_NULL); - size = length; - - rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - -#ifdef RT_USING_SERIAL_BYPASS - if (serial->bypass) - { - rt_bypass_work_straight(serial); - while (length) - { - rt_uint8_t ch; - if (!rt_bypass_getchar(serial, &ch)) - break; - - *data = ch & 0xff; - data++; length--; - } - - return size - length; - } -#endif - /* read from software FIFO */ - while (length) - { - int ch; - rt_base_t level; - - /* disable interrupt */ - level = rt_spin_lock_irqsave(&(serial->spinlock)); - - /* there's no data: */ - if ((rx_fifo->get_index == rx_fifo->put_index) && (rx_fifo->is_full == RT_FALSE)) - { - /* no data, enable interrupt and break out */ - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - break; - } - - /* otherwise there's the data: */ - ch = rx_fifo->buffer[rx_fifo->get_index]; - rx_fifo->get_index += 1; - if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0; - - if (rx_fifo->is_full == RT_TRUE) - { - rx_fifo->is_full = RT_FALSE; - } - - /* enable interrupt */ - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - - *data = ch & 0xff; - data ++; length --; - } - - return size - length; -} - -rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length) -{ - int size; - struct rt_serial_tx_fifo *tx; - - RT_ASSERT(serial != RT_NULL); - - size = length; - tx = (struct rt_serial_tx_fifo*) serial->serial_tx; - RT_ASSERT(tx != RT_NULL); - - while (length) - { - /* - * to be polite with serial console add a line feed - * to the carriage return character - */ - if (*data == '\n' && (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)) - { - if (serial->ops->putc(serial, '\r') == -1) - { - rt_completion_wait(&(tx->completion), RT_WAITING_FOREVER); - continue; - } - } - - while (serial->ops->putc(serial, *(char*)data) == -1) - { - rt_completion_wait(&(tx->completion), RT_WAITING_FOREVER); - } - - data ++; length --; - } - - return size - length; -} - -static void _serial_check_buffer_size(void) -{ - static rt_bool_t already_output = RT_FALSE; - - if (already_output == RT_FALSE) - { -#if !defined(RT_USING_ULOG) || defined(ULOG_USING_ISR_LOG) - LOG_W("Warning: There is no enough buffer for saving data," - " please increase the RT_SERIAL_RB_BUFSZ option."); -#endif - already_output = RT_TRUE; - } -} - -#if defined(RT_USING_POSIX_STDIO) || defined(RT_SERIAL_USING_DMA) -static rt_ssize_t _serial_fifo_calc_recved_len(struct rt_serial_device *serial) -{ - struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - - RT_ASSERT(rx_fifo != RT_NULL); - - if (rx_fifo->put_index == rx_fifo->get_index) - { - return (rx_fifo->is_full == RT_FALSE ? 0 : serial->config.bufsz); - } - else - { - if (rx_fifo->put_index > rx_fifo->get_index) - { - return rx_fifo->put_index - rx_fifo->get_index; - } - else - { - return serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index); - } - } -} -#endif /* RT_USING_POSIX_STDIO || RT_SERIAL_USING_DMA */ - -#ifdef RT_SERIAL_USING_DMA -/** - * Calculate DMA received data length. - * - * @param serial serial device - * - * @return length - */ -static rt_ssize_t rt_dma_calc_recved_len(struct rt_serial_device *serial) -{ - return _serial_fifo_calc_recved_len(serial); -} - -/** - * Read data finish by DMA mode then update the get index for receive fifo. - * - * @param serial serial device - * @param len get data length for this operate - */ -static void rt_dma_recv_update_get_index(struct rt_serial_device *serial, rt_size_t len) -{ - struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - - RT_ASSERT(rx_fifo != RT_NULL); - RT_ASSERT(len <= rt_dma_calc_recved_len(serial)); - - if (rx_fifo->is_full && len != 0) rx_fifo->is_full = RT_FALSE; - - rx_fifo->get_index += (rt_uint16_t)len; - if (rx_fifo->get_index >= serial->config.bufsz) - { - rx_fifo->get_index %= serial->config.bufsz; - } -} - -/** - * DMA received finish then update put index for receive fifo. - * - * @param serial serial device - * @param len received length for this transmit - */ -static void rt_dma_recv_update_put_index(struct rt_serial_device *serial, rt_size_t len) -{ - struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; - - RT_ASSERT(rx_fifo != RT_NULL); - - if (rx_fifo->get_index <= rx_fifo->put_index) - { - rx_fifo->put_index += (rt_uint16_t)len; - /* beyond the fifo end */ - if (rx_fifo->put_index >= serial->config.bufsz) - { - rx_fifo->put_index %= serial->config.bufsz; - /* force overwrite get index */ - if (rx_fifo->put_index >= rx_fifo->get_index) - { - rx_fifo->is_full = RT_TRUE; - } - } - } - else - { - rx_fifo->put_index += (rt_uint16_t)len; - if (rx_fifo->put_index >= rx_fifo->get_index) - { - /* beyond the fifo end */ - if (rx_fifo->put_index >= serial->config.bufsz) - { - rx_fifo->put_index %= serial->config.bufsz; - } - /* force overwrite get index */ - rx_fifo->is_full = RT_TRUE; - } - } - - if(rx_fifo->is_full == RT_TRUE) - { - _serial_check_buffer_size(); - rx_fifo->get_index = rx_fifo->put_index; - } -} - -/* - * Serial DMA routines - */ -rt_inline int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length) -{ - rt_base_t level; - - RT_ASSERT((serial != RT_NULL) && (data != RT_NULL)); - - level = rt_spin_lock_irqsave(&(serial->spinlock)); - - if (serial->config.bufsz == 0) - { - int result = RT_EOK; - struct rt_serial_rx_dma *rx_dma; - - rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx; - RT_ASSERT(rx_dma != RT_NULL); - - if (rx_dma->activated != RT_TRUE) - { - rx_dma->activated = RT_TRUE; - RT_ASSERT(serial->ops->dma_transmit != RT_NULL); - serial->ops->dma_transmit(serial, data, length, RT_SERIAL_DMA_RX); - } - else result = -RT_EBUSY; - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - - if (result == RT_EOK) return length; - - rt_set_errno(result); - return 0; - } - else - { - struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - rt_size_t recv_len = 0, fifo_recved_len = rt_dma_calc_recved_len(serial); - - RT_ASSERT(rx_fifo != RT_NULL); - - if (length < (int)fifo_recved_len) - recv_len = length; - else - recv_len = fifo_recved_len; - - if (rx_fifo->get_index + recv_len < serial->config.bufsz) - rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index, recv_len); - else - { - rt_memcpy(data, rx_fifo->buffer + rx_fifo->get_index, - serial->config.bufsz - rx_fifo->get_index); - rt_memcpy(data + serial->config.bufsz - rx_fifo->get_index, rx_fifo->buffer, - recv_len + rx_fifo->get_index - serial->config.bufsz); - } - rt_dma_recv_update_get_index(serial, recv_len); - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - return recv_len; - } -} - -rt_inline int _serial_dma_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length) -{ - rt_base_t level; - rt_err_t result; - struct rt_serial_tx_dma *tx_dma; - - tx_dma = (struct rt_serial_tx_dma*)(serial->serial_tx); - - result = rt_data_queue_push(&(tx_dma->data_queue), data, length, RT_WAITING_FOREVER); - if (result == RT_EOK) - { - level = rt_spin_lock_irqsave(&(serial->spinlock)); - if (tx_dma->activated != RT_TRUE) - { - tx_dma->activated = RT_TRUE; - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - - /* make a DMA transfer */ - serial->ops->dma_transmit(serial, (rt_uint8_t *)data, length, RT_SERIAL_DMA_TX); - } - else - { - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - } - - return length; - } - else - { - rt_set_errno(result); - return 0; - } -} -#endif /* RT_SERIAL_USING_DMA */ - -/* RT-Thread Device Interface */ -/* - * This function initializes serial device. - */ -static rt_err_t rt_serial_init(struct rt_device *dev) -{ - rt_err_t result = RT_EOK; - struct rt_serial_device *serial; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - - /* initialize rx/tx */ - serial->serial_rx = RT_NULL; - serial->serial_tx = RT_NULL; - - rt_memset(&serial->rx_notify, 0, sizeof(struct rt_device_notify)); - - /* apply configuration */ - if (serial->ops->configure) - result = serial->ops->configure(serial, &serial->config); - - return result; -} - -static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag) -{ - rt_uint16_t stream_flag = 0; - struct rt_serial_device *serial; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - - LOG_D("open serial device: 0x%08x with open flag: 0x%04x", - dev, oflag); - /* check device flag with the open flag */ - if ((oflag & RT_DEVICE_FLAG_DMA_RX) && !(dev->flag & RT_DEVICE_FLAG_DMA_RX)) - return -RT_EIO; - if ((oflag & RT_DEVICE_FLAG_DMA_TX) && !(dev->flag & RT_DEVICE_FLAG_DMA_TX)) - return -RT_EIO; - if ((oflag & RT_DEVICE_FLAG_INT_RX) && !(dev->flag & RT_DEVICE_FLAG_INT_RX)) - return -RT_EIO; - if ((oflag & RT_DEVICE_FLAG_INT_TX) && !(dev->flag & RT_DEVICE_FLAG_INT_TX)) - return -RT_EIO; - - /* keep steam flag */ - if ((oflag & RT_DEVICE_FLAG_STREAM) || (dev->open_flag & RT_DEVICE_FLAG_STREAM)) - stream_flag = RT_DEVICE_FLAG_STREAM; - - /* get open flags */ - dev->open_flag = oflag & 0xff; - -#ifdef RT_USING_PINCTRL - /* initialize iomux in DM */ - rt_pin_ctrl_confs_apply_by_name(dev, RT_NULL); -#endif - - /* initialize the Rx/Tx structure according to open flag */ - if (serial->serial_rx == RT_NULL) - { - if (oflag & RT_DEVICE_FLAG_INT_RX) - { - struct rt_serial_rx_fifo* rx_fifo; - - rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) + - serial->config.bufsz); - RT_ASSERT(rx_fifo != RT_NULL); - rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1); - rt_memset(rx_fifo->buffer, 0, serial->config.bufsz); - rx_fifo->put_index = 0; - rx_fifo->get_index = 0; - rx_fifo->is_full = RT_FALSE; - - serial->serial_rx = rx_fifo; - dev->open_flag |= RT_DEVICE_FLAG_INT_RX; - /* configure low level device */ - serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX); - } -#ifdef RT_SERIAL_USING_DMA - else if (oflag & RT_DEVICE_FLAG_DMA_RX) - { - if (serial->config.bufsz == 0) { - struct rt_serial_rx_dma* rx_dma; - - rx_dma = (struct rt_serial_rx_dma*) rt_malloc (sizeof(struct rt_serial_rx_dma)); - RT_ASSERT(rx_dma != RT_NULL); - rx_dma->activated = RT_FALSE; - - serial->serial_rx = rx_dma; - } else { - struct rt_serial_rx_fifo* rx_fifo; - - rx_fifo = (struct rt_serial_rx_fifo*) rt_malloc (sizeof(struct rt_serial_rx_fifo) + - serial->config.bufsz); - RT_ASSERT(rx_fifo != RT_NULL); - rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1); - rt_memset(rx_fifo->buffer, 0, serial->config.bufsz); - rx_fifo->put_index = 0; - rx_fifo->get_index = 0; - rx_fifo->is_full = RT_FALSE; - serial->serial_rx = rx_fifo; - /* configure fifo address and length to low level device */ - serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *) RT_DEVICE_FLAG_DMA_RX); - } - dev->open_flag |= RT_DEVICE_FLAG_DMA_RX; - } -#endif /* RT_SERIAL_USING_DMA */ - else - { - serial->serial_rx = RT_NULL; - } - } - else - { - if (oflag & RT_DEVICE_FLAG_INT_RX) - dev->open_flag |= RT_DEVICE_FLAG_INT_RX; -#ifdef RT_SERIAL_USING_DMA - else if (oflag & RT_DEVICE_FLAG_DMA_RX) - dev->open_flag |= RT_DEVICE_FLAG_DMA_RX; -#endif /* RT_SERIAL_USING_DMA */ - } - - if (serial->serial_tx == RT_NULL) - { - if (oflag & RT_DEVICE_FLAG_INT_TX) - { - struct rt_serial_tx_fifo *tx_fifo; - - tx_fifo = (struct rt_serial_tx_fifo*) rt_malloc(sizeof(struct rt_serial_tx_fifo)); - RT_ASSERT(tx_fifo != RT_NULL); - - rt_completion_init(&(tx_fifo->completion)); - serial->serial_tx = tx_fifo; - - dev->open_flag |= RT_DEVICE_FLAG_INT_TX; - /* configure low level device */ - serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX); - } -#ifdef RT_SERIAL_USING_DMA - else if (oflag & RT_DEVICE_FLAG_DMA_TX) - { - struct rt_serial_tx_dma* tx_dma; - - tx_dma = (struct rt_serial_tx_dma*) rt_malloc (sizeof(struct rt_serial_tx_dma)); - RT_ASSERT(tx_dma != RT_NULL); - tx_dma->activated = RT_FALSE; - - rt_data_queue_init(&(tx_dma->data_queue), 8, 4, RT_NULL); - serial->serial_tx = tx_dma; - - dev->open_flag |= RT_DEVICE_FLAG_DMA_TX; - /* configure low level device */ - serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *)RT_DEVICE_FLAG_DMA_TX); - } -#endif /* RT_SERIAL_USING_DMA */ - else - { - serial->serial_tx = RT_NULL; - } - } - else - { - if (oflag & RT_DEVICE_FLAG_INT_TX) - dev->open_flag |= RT_DEVICE_FLAG_INT_TX; -#ifdef RT_SERIAL_USING_DMA - else if (oflag & RT_DEVICE_FLAG_DMA_TX) - dev->open_flag |= RT_DEVICE_FLAG_DMA_TX; -#endif /* RT_SERIAL_USING_DMA */ - } - - /* set stream flag */ - dev->open_flag |= stream_flag; - - return RT_EOK; -} - -static rt_err_t rt_serial_close(struct rt_device *dev) -{ - struct rt_serial_device *serial; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - - /* this device has more reference count */ - if (dev->ref_count > 1) return RT_EOK; - - if (dev->open_flag & RT_DEVICE_FLAG_INT_RX) - { - struct rt_serial_rx_fifo* rx_fifo; - - /* configure low level device */ - serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_RX); - dev->open_flag &= ~RT_DEVICE_FLAG_INT_RX; - - rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_free(rx_fifo); - serial->serial_rx = RT_NULL; - - } -#ifdef RT_SERIAL_USING_DMA - else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX) - { - /* configure low level device */ - serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *) RT_DEVICE_FLAG_DMA_RX); - dev->open_flag &= ~RT_DEVICE_FLAG_DMA_RX; - - if (serial->config.bufsz == 0) - { - struct rt_serial_rx_dma* rx_dma; - - rx_dma = (struct rt_serial_rx_dma*)serial->serial_rx; - RT_ASSERT(rx_dma != RT_NULL); - - rt_free(rx_dma); - } - else - { - struct rt_serial_rx_fifo* rx_fifo; - - rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - rt_free(rx_fifo); - } - serial->serial_rx = RT_NULL; - - } -#endif /* RT_SERIAL_USING_DMA */ - - if (dev->open_flag & RT_DEVICE_FLAG_INT_TX) - { - struct rt_serial_tx_fifo* tx_fifo; - - serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_TX); - dev->open_flag &= ~RT_DEVICE_FLAG_INT_TX; - - tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); - - rt_free(tx_fifo); - serial->serial_tx = RT_NULL; - - /* configure low level device */ - } -#ifdef RT_SERIAL_USING_DMA - else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX) - { - struct rt_serial_tx_dma* tx_dma; - - /* configure low level device */ - serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *) RT_DEVICE_FLAG_DMA_TX); - dev->open_flag &= ~RT_DEVICE_FLAG_DMA_TX; - - tx_dma = (struct rt_serial_tx_dma*)serial->serial_tx; - RT_ASSERT(tx_dma != RT_NULL); - - rt_data_queue_deinit(&(tx_dma->data_queue)); - - rt_free(tx_dma); - serial->serial_tx = RT_NULL; - - } -#endif /* RT_SERIAL_USING_DMA */ - - serial->ops->control(serial, RT_DEVICE_CTRL_CLOSE, RT_NULL); - dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED; - - return RT_EOK; -} - -static rt_ssize_t rt_serial_read(struct rt_device *dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - struct rt_serial_device *serial; - - RT_ASSERT(dev != RT_NULL); - if (size == 0) return 0; - - serial = (struct rt_serial_device *)dev; - - if (dev->open_flag & RT_DEVICE_FLAG_INT_RX) - { - return _serial_int_rx(serial, (rt_uint8_t *)buffer, size); - } -#ifdef RT_SERIAL_USING_DMA - else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX) - { - return _serial_dma_rx(serial, (rt_uint8_t *)buffer, size); - } -#endif /* RT_SERIAL_USING_DMA */ - - return _serial_poll_rx(serial, (rt_uint8_t *)buffer, size); -} - -static rt_ssize_t rt_serial_write(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct rt_serial_device *serial; - - RT_ASSERT(dev != RT_NULL); - if (size == 0) return 0; - - serial = (struct rt_serial_device *)dev; - - if (dev->open_flag & RT_DEVICE_FLAG_INT_TX) - { - return _serial_int_tx(serial, (const rt_uint8_t *)buffer, size); - } -#ifdef RT_SERIAL_USING_DMA - else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX) - { - return _serial_dma_tx(serial, (const rt_uint8_t *)buffer, size); - } -#endif /* RT_SERIAL_USING_DMA */ - else - { - return _serial_poll_tx(serial, (const rt_uint8_t *)buffer, size); - } -} - -#if defined(RT_USING_POSIX_TERMIOS) -struct speed_baudrate_item -{ - speed_t speed; - int baudrate; -}; - -static const struct speed_baudrate_item _tbl[] = -{ - {B2400, BAUD_RATE_2400}, - {B4800, BAUD_RATE_4800}, - {B9600, BAUD_RATE_9600}, - {B19200, BAUD_RATE_19200}, - {B38400, BAUD_RATE_38400}, - {B57600, BAUD_RATE_57600}, - {B115200, BAUD_RATE_115200}, - {B230400, BAUD_RATE_230400}, - {B460800, BAUD_RATE_460800}, - {B500000, BAUD_RATE_500000}, - {B576000, BAUD_RATE_576000}, - {B921600, BAUD_RATE_921600}, - {B1000000, BAUD_RATE_1000000}, - {B1152000, BAUD_RATE_1152000}, - {B1500000, BAUD_RATE_1500000}, - {B2000000, BAUD_RATE_2000000}, - {B2500000, BAUD_RATE_2500000}, - {B3000000, BAUD_RATE_3000000}, - {B3500000, BAUD_RATE_3500000}, - {B4000000, BAUD_RATE_4000000}, -}; - -static speed_t _get_speed(int baudrate) -{ - size_t index; - - for (index = 0; index < sizeof(_tbl)/sizeof(_tbl[0]); index ++) - { - if (_tbl[index].baudrate == baudrate) - return _tbl[index].speed; - } - - return B0; -} - -static int _get_baudrate(speed_t speed) -{ - size_t index; - - for (index = 0; index < sizeof(_tbl)/sizeof(_tbl[0]); index ++) - { - if (_tbl[index].speed == speed) - return _tbl[index].baudrate; - } - - return 0; -} - -static void _tc_flush(struct rt_serial_device *serial, int queue) -{ - rt_base_t level; - int ch = -1; - struct rt_serial_rx_fifo *rx_fifo = RT_NULL; - struct rt_device *device = RT_NULL; - - RT_ASSERT(serial != RT_NULL); - - device = &(serial->parent); - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - - switch(queue) - { - case TCIFLUSH: - case TCIOFLUSH: - - RT_ASSERT(rx_fifo != RT_NULL); - - if((device->open_flag & RT_DEVICE_FLAG_INT_RX) || (device->open_flag & RT_DEVICE_FLAG_DMA_RX)) - { - RT_ASSERT(RT_NULL != rx_fifo); - level = rt_spin_lock_irqsave(&(serial->spinlock)); - rx_fifo->get_index = rx_fifo->put_index; - rx_fifo->is_full = RT_FALSE; - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - } - else - { - while (1) - { - ch = serial->ops->getc(serial); - if (ch == -1) break; - } - } - - break; - - case TCOFLUSH: - break; - } - -} - -static inline int _termio_to_termios(const struct termio *termio, struct termios *termios) -{ - termios->c_iflag = termio->c_iflag; - termios->c_oflag = termio->c_oflag; - termios->c_cflag = termio->c_cflag; - termios->c_lflag = termio->c_lflag; - termios->c_line = termio->c_line; - rt_memcpy(termios->c_cc, termio->c_cc, NCC); - - return 0; -} - -static inline int _termios_to_termio(const struct termios *termios, struct termio *termio) -{ - termio->c_iflag = (unsigned short)termios->c_iflag; - termio->c_oflag = (unsigned short)termios->c_oflag; - termio->c_cflag = (unsigned short)termios->c_cflag; - termio->c_lflag = (unsigned short)termios->c_lflag; - termio->c_line = termios->c_line; - rt_memcpy(termio->c_cc, termios->c_cc, NCC); - - return 0; -} -#endif /* RT_USING_POSIX_TERMIOS */ - -static rt_err_t rt_serial_control(struct rt_device *dev, - int cmd, - void *args) -{ - rt_err_t ret = RT_EOK; - struct rt_serial_device *serial; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - - switch (cmd) - { - case RT_DEVICE_CTRL_SUSPEND: - /* suspend device */ - dev->flag |= RT_DEVICE_FLAG_SUSPENDED; - break; - - case RT_DEVICE_CTRL_RESUME: - /* resume device */ - dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED; - break; - - case RT_DEVICE_CTRL_CONFIG: - if (args) - { - struct serial_configure *pconfig = (struct serial_configure *) args; - if (pconfig->bufsz != serial->config.bufsz && serial->parent.ref_count) - { - /*can not change buffer size*/ - return -RT_EBUSY; - } - /* set serial configure */ - serial->config = *pconfig; - if (serial->parent.ref_count) - { - /* serial device has been opened, to configure it */ - serial->ops->configure(serial, (struct serial_configure *) args); - } - } - break; - case RT_DEVICE_CTRL_NOTIFY_SET: - if (args) - { - rt_memcpy(&serial->rx_notify, args, sizeof(struct rt_device_notify)); - } - break; - - case RT_DEVICE_CTRL_CONSOLE_OFLAG: - if (args) - { - *(rt_uint16_t*)args = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM; - } - break; -#ifdef RT_USING_POSIX_STDIO -#if defined(RT_USING_POSIX_TERMIOS) - case TCGETA: - case TCGETS: - { - struct termios *tio, tmp; - - if (cmd == TCGETS) - { - tio = (struct termios*)args; - } - else - { - tio = &tmp; - } - - if (tio == RT_NULL) return -RT_EINVAL; - - tio->c_iflag = 0; - tio->c_oflag = 0; - tio->c_lflag = 0; - - /* update oflag for console device */ - if (rt_console_get_device() == dev) - tio->c_oflag = OPOST | ONLCR; - - /* set cflag */ - tio->c_cflag = 0; - if (serial->config.data_bits == DATA_BITS_5) - tio->c_cflag = CS5; - else if (serial->config.data_bits == DATA_BITS_6) - tio->c_cflag = CS6; - else if (serial->config.data_bits == DATA_BITS_7) - tio->c_cflag = CS7; - else if (serial->config.data_bits == DATA_BITS_8) - tio->c_cflag = CS8; - - if (serial->config.stop_bits == STOP_BITS_2) - tio->c_cflag |= CSTOPB; - - if (serial->config.parity == PARITY_EVEN) - tio->c_cflag |= PARENB; - else if (serial->config.parity == PARITY_ODD) - tio->c_cflag |= (PARODD | PARENB); - - cfsetospeed(tio, _get_speed(serial->config.baud_rate)); - - if (cmd == TCGETA) - { - _termios_to_termio(tio, args); - } - } - break; - case TCSETAW: - case TCSETAF: - case TCSETA: - case TCSETSW: - case TCSETSF: - case TCSETS: - { - int baudrate; - struct serial_configure config; - struct termios *tio, tmp; - - if ((cmd >= TCSETA) && (cmd <= TCSETA + 2)) - { - _termio_to_termios(args, &tmp); - tio = &tmp; - } - else - { - tio = (struct termios*)args; - } - - if (tio == RT_NULL) return -RT_EINVAL; - - config = serial->config; - baudrate = _get_baudrate(cfgetospeed(tio)); - config.baud_rate = baudrate; - - switch (tio->c_cflag & CSIZE) - { - case CS5: - config.data_bits = DATA_BITS_5; - break; - case CS6: - config.data_bits = DATA_BITS_6; - break; - case CS7: - config.data_bits = DATA_BITS_7; - break; - default: - config.data_bits = DATA_BITS_8; - break; - } - - if (tio->c_cflag & CSTOPB) config.stop_bits = STOP_BITS_2; - else config.stop_bits = STOP_BITS_1; - - if (tio->c_cflag & PARENB) - { - if (tio->c_cflag & PARODD) config.parity = PARITY_ODD; - else config.parity = PARITY_EVEN; - } - else config.parity = PARITY_NONE; - - serial->ops->configure(serial, &config); - } - break; -#ifndef RT_USING_TTY - case TCFLSH: - { - int queue = (int)(rt_ubase_t)args; - - _tc_flush(serial, queue); - } - - break; - case TCXONC: - break; -#endif /*RT_USING_TTY*/ -#endif /*RT_USING_POSIX_TERMIOS*/ - case TIOCSWINSZ: - { - struct winsize* p_winsize; - - p_winsize = (struct winsize*)args; - rt_kprintf("\x1b[8;%d;%dt", p_winsize->ws_col, p_winsize->ws_row); - } - break; - case TIOCGWINSZ: - { - struct winsize* p_winsize; - p_winsize = (struct winsize*)args; - - if(rt_thread_self() != rt_thread_find("tshell")) - { - /* only can be used in tshell thread; otherwise, return default size */ - p_winsize->ws_col = 80; - p_winsize->ws_row = 24; - } - else - { - #include - #define _TIO_BUFLEN 20 - char _tio_buf[_TIO_BUFLEN]; - unsigned char cnt1, cnt2, cnt3, i; - char row_s[4], col_s[4]; - char *p; - - rt_memset(_tio_buf, 0, _TIO_BUFLEN); - - /* send the command to terminal for getting the window size of the terminal */ - rt_kprintf("\033[18t"); - - /* waiting for the response from the terminal */ - i = 0; - while(i < _TIO_BUFLEN) - { - _tio_buf[i] = finsh_getchar(); - if(_tio_buf[i] != 't') - { - i ++; - } - else - { - break; - } - } - if(i == _TIO_BUFLEN) - { - /* buffer overloaded, and return default size */ - p_winsize->ws_col = 80; - p_winsize->ws_row = 24; - break; - } - - /* interpreting data eg: "\033[8;1;15t" which means row is 1 and col is 15 (unit: size of ONE character) */ - rt_memset(row_s,0,4); - rt_memset(col_s,0,4); - cnt1 = 0; - while(cnt1 < _TIO_BUFLEN && _tio_buf[cnt1] != ';') - { - cnt1++; - } - cnt2 = ++cnt1; - while(cnt2 < _TIO_BUFLEN && _tio_buf[cnt2] != ';') - { - cnt2++; - } - p = row_s; - while(cnt1 < cnt2) - { - *p++ = _tio_buf[cnt1++]; - } - p = col_s; - cnt2++; - cnt3 = rt_strlen(_tio_buf) - 1; - while(cnt2 < cnt3) - { - *p++ = _tio_buf[cnt2++]; - } - - /* load the window size date */ - p_winsize->ws_col = atoi(col_s); - p_winsize->ws_row = atoi(row_s); - #undef _TIO_BUFLEN - } - - p_winsize->ws_xpixel = 0;/* unused */ - p_winsize->ws_ypixel = 0;/* unused */ - } - break; - case FIONREAD: - { - rt_size_t recved = 0; - rt_base_t level; - - level = rt_spin_lock_irqsave(&(serial->spinlock)); - recved = _serial_fifo_calc_recved_len(serial); - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - - *(rt_size_t *)args = recved; - } - break; -#endif /* RT_USING_POSIX_STDIO */ - default : - /* control device */ - ret = serial->ops->control(serial, cmd, args); - break; - } - - return ret; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops serial_ops = -{ - rt_serial_init, - rt_serial_open, - rt_serial_close, - rt_serial_read, - rt_serial_write, - rt_serial_control -}; -#endif - -/* - * serial register - */ -rt_err_t rt_hw_serial_register(struct rt_serial_device *serial, - const char *name, - rt_uint32_t flag, - void *data) -{ - rt_err_t ret; - struct rt_device *device; - RT_ASSERT(serial != RT_NULL); - - rt_spin_lock_init(&(serial->spinlock)); - - device = &(serial->parent); - - device->type = RT_Device_Class_Char; - device->rx_indicate = RT_NULL; - device->tx_complete = RT_NULL; - -#ifdef RT_USING_DEVICE_OPS - device->ops = &serial_ops; -#else - device->init = rt_serial_init; - device->open = rt_serial_open; - device->close = rt_serial_close; - device->read = rt_serial_read; - device->write = rt_serial_write; - device->control = rt_serial_control; -#endif - device->user_data = data; - - /* register a character device */ - ret = rt_device_register(device, name, flag); - -#ifdef RT_USING_POSIX_STDIO - /* set fops */ - device->fops = &_serial_fops; -#endif - -#if defined(RT_USING_SMART) - rt_hw_serial_register_tty(serial); -#endif - - return ret; -} - -/* ISR for serial interrupt */ -void rt_hw_serial_isr(struct rt_serial_device *serial, int event) -{ - switch (event & 0xff) - { - case RT_SERIAL_EVENT_RX_IND: - { - int ch = -1; - rt_base_t level; - struct rt_serial_rx_fifo* rx_fifo; - - /* interrupt mode receive */ - rx_fifo = (struct rt_serial_rx_fifo*)serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - - while (1) - { - ch = serial->ops->getc(serial); - if (ch == -1) break; - - /* disable interrupt */ -#ifdef RT_USING_SERIAL_BYPASS - if (serial->bypass && serial->bypass->upper_h && (serial->bypass->upper_h->head.next != &serial->bypass->upper_h->head)) - { - rt_bool_t skip = RT_FALSE; - char buf = (char)ch; - int ret; - rt_list_t* node = serial->bypass->upper_h->head.next; - do { - struct rt_serial_bypass_func* bypass_run = rt_container_of(node, struct rt_serial_bypass_func, node); - ret = bypass_run->bypass(serial, buf, bypass_run->data); - if (!ret) - { - skip = RT_TRUE; - break; - } - node = node->next; - } while (node != &serial->bypass->upper_h->head); - - if (skip) - continue; - } - -#endif - level = rt_spin_lock_irqsave(&(serial->spinlock)); - rx_fifo->buffer[rx_fifo->put_index] = ch; - rx_fifo->put_index += 1; - if (rx_fifo->put_index >= serial->config.bufsz) rx_fifo->put_index = 0; - - /* if the next position is read index, discard this 'read char' */ - if (rx_fifo->put_index == rx_fifo->get_index) - { - rx_fifo->get_index += 1; - rx_fifo->is_full = RT_TRUE; - if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0; - - _serial_check_buffer_size(); - } - - /* enable interrupt */ - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - } - -#ifdef RT_USING_SERIAL_BYPASS - if (serial->bypass && serial->bypass->lower_h) - rt_workqueue_dowork(serial->bypass->lower_workq, &serial->bypass->work); -#endif - - if (serial->parent.rx_indicate != RT_NULL) - { - rt_size_t rx_length; - - /* get rx length */ - level = rt_spin_lock_irqsave(&(serial->spinlock)); - rx_length = (rx_fifo->put_index >= rx_fifo->get_index)? (rx_fifo->put_index - rx_fifo->get_index): - (serial->config.bufsz - (rx_fifo->get_index - rx_fifo->put_index)); - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - - if (rx_length) - { - serial->parent.rx_indicate(&serial->parent, rx_length); - } - } - break; - } - case RT_SERIAL_EVENT_TX_DONE: - { - struct rt_serial_tx_fifo* tx_fifo; - - tx_fifo = (struct rt_serial_tx_fifo*)serial->serial_tx; - rt_completion_done(&(tx_fifo->completion)); - break; - } -#ifdef RT_SERIAL_USING_DMA - case RT_SERIAL_EVENT_TX_DMADONE: - { - const void *data_ptr; - rt_size_t data_size; - const void *last_data_ptr; - struct rt_serial_tx_dma *tx_dma; - - tx_dma = (struct rt_serial_tx_dma*) serial->serial_tx; - - rt_data_queue_pop(&(tx_dma->data_queue), &last_data_ptr, &data_size, 0); - if (rt_data_queue_peek(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK) - { - /* transmit next data node */ - tx_dma->activated = RT_TRUE; - serial->ops->dma_transmit(serial, (rt_uint8_t *)data_ptr, data_size, RT_SERIAL_DMA_TX); - } - else - { - tx_dma->activated = RT_FALSE; - } - - /* invoke callback */ - if (serial->parent.tx_complete != RT_NULL) - { - serial->parent.tx_complete(&serial->parent, (void*)last_data_ptr); - } - break; - } - case RT_SERIAL_EVENT_RX_DMADONE: - { - int length; - rt_base_t level; - - /* get DMA rx length */ - length = (event & (~0xff)) >> 8; - - if (serial->config.bufsz == 0) - { - struct rt_serial_rx_dma* rx_dma; - - rx_dma = (struct rt_serial_rx_dma*) serial->serial_rx; - RT_ASSERT(rx_dma != RT_NULL); - - RT_ASSERT(serial->parent.rx_indicate != RT_NULL); - serial->parent.rx_indicate(&(serial->parent), length); - rx_dma->activated = RT_FALSE; - } - else - { - /* disable interrupt */ - level = rt_spin_lock_irqsave(&(serial->spinlock)); - /* update fifo put index */ - rt_dma_recv_update_put_index(serial, length); - /* calculate received total length */ - length = rt_dma_calc_recved_len(serial); - /* enable interrupt */ - rt_spin_unlock_irqrestore(&(serial->spinlock), level); - /* invoke callback */ - if (serial->parent.rx_indicate != RT_NULL) - { - serial->parent.rx_indicate(&(serial->parent), length); - } - } - break; - } -#endif /* RT_SERIAL_USING_DMA */ - } -} diff --git a/rt-thread/components/drivers/serial/dev_serial_v2.c b/rt-thread/components/drivers/serial/dev_serial_v2.c deleted file mode 100644 index 18f9c89..0000000 --- a/rt-thread/components/drivers/serial/dev_serial_v2.c +++ /dev/null @@ -1,1642 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-06-01 KyleChan first version - */ - -#include -#include -#include - -#define DBG_TAG "Serial" -#define DBG_LVL DBG_INFO -#include - -#ifdef RT_USING_POSIX_STDIO -#include -#include -#include -#include -#include - -#ifdef RT_USING_POSIX_TERMIOS -#include -#endif - -#ifdef getc -#undef getc -#endif - -#ifdef putc -#undef putc -#endif - -RT_OBJECT_HOOKLIST_DEFINE(rt_hw_serial_rxind); - -static rt_err_t serial_fops_rx_ind(rt_device_t dev, rt_size_t size) -{ - rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN); - - RT_OBJECT_HOOKLIST_CALL(rt_hw_serial_rxind, (dev, size)); - - return RT_EOK; -} - -/* fops for serial */ -static int serial_fops_open(struct dfs_file *fd) -{ - rt_err_t ret = 0; - rt_uint16_t flags = 0; - rt_device_t device; - - device = (rt_device_t)fd->vnode->data; - RT_ASSERT(device != RT_NULL); - - switch (fd->flags & O_ACCMODE) - { - case O_RDONLY: - LOG_D("fops open: O_RDONLY!"); - flags = RT_DEVICE_FLAG_RDONLY; - break; - case O_WRONLY: - LOG_D("fops open: O_WRONLY!"); - flags = RT_DEVICE_FLAG_WRONLY; - break; - case O_RDWR: - LOG_D("fops open: O_RDWR!"); - flags = RT_DEVICE_FLAG_RDWR; - break; - default: - LOG_E("fops open: unknown mode - %d!", fd->flags & O_ACCMODE); - break; - } - - if ((fd->flags & O_ACCMODE) != O_WRONLY) - rt_device_set_rx_indicate(device, serial_fops_rx_ind); - ret = rt_device_open(device, flags); - if (ret == RT_EOK) return 0; - - return ret; -} - -static int serial_fops_close(struct dfs_file *fd) -{ - rt_device_t device; - - device = (rt_device_t)fd->vnode->data; - - rt_device_set_rx_indicate(device, RT_NULL); - rt_device_close(device); - - return 0; -} - -static int serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args) -{ - rt_device_t device; - int flags = (int)(rt_base_t)args; - int mask = O_NONBLOCK | O_APPEND; - - device = (rt_device_t)fd->vnode->data; - switch (cmd) - { - case FIONREAD: - break; - case FIONWRITE: - break; - case F_SETFL: - flags &= mask; - fd->flags &= ~mask; - fd->flags |= flags; - break; - } - - return rt_device_control(device, cmd, args); -} - -#ifdef RT_USING_DFS_V2 -static ssize_t serial_fops_read(struct dfs_file *fd, void *buf, size_t count, off_t *pos) -#else -static ssize_t serial_fops_read(struct dfs_file *fd, void *buf, size_t count) -#endif -{ - int size = 0; - rt_device_t device; - - device = (rt_device_t)fd->vnode->data; - - do - { - size = rt_device_read(device, -1, buf, count); - if (size <= 0) - { - if (fd->flags & O_NONBLOCK) - { - size = -EAGAIN; - break; - } - - rt_wqueue_wait(&(device->wait_queue), 0, RT_WAITING_FOREVER); - } - }while (size <= 0); - - return size; -} - -#ifdef RT_USING_DFS_V2 -static ssize_t serial_fops_write(struct dfs_file *fd, const void *buf, size_t count, off_t *pos) -#else -static ssize_t serial_fops_write(struct dfs_file *fd, const void *buf, size_t count) -#endif -{ - rt_device_t device; - - device = (rt_device_t)fd->vnode->data; - return rt_device_write(device, -1, buf, count); -} - -static int serial_fops_poll(struct dfs_file *fd, struct rt_pollreq *req) -{ - int mask = 0; - int flags = 0; - rt_device_t device; - struct rt_serial_device *serial; - - device = (rt_device_t)fd->vnode->data; - RT_ASSERT(device != RT_NULL); - - serial = (struct rt_serial_device *)device; - - /* only support POLLIN */ - flags = fd->flags & O_ACCMODE; - if (flags == O_RDONLY || flags == O_RDWR) - { - rt_base_t level; - struct rt_serial_rx_fifo* rx_fifo; - - rt_poll_add(&(device->wait_queue), req); - - rx_fifo = (struct rt_serial_rx_fifo*) serial->serial_rx; - - level = rt_hw_interrupt_disable(); - - if (rt_ringbuffer_data_len(&rx_fifo->rb)) - mask |= POLLIN; - rt_hw_interrupt_enable(level); - } - // mask|=POLLOUT; - return mask; -} - -const static struct dfs_file_ops _serial_fops = -{ - .open = serial_fops_open, - .close = serial_fops_close, - .ioctl = serial_fops_ioctl, - .read = serial_fops_read, - .write = serial_fops_write, - .poll = serial_fops_poll, -}; -#endif /* RT_USING_POSIX_STDIO */ - -static rt_ssize_t rt_serial_get_linear_buffer(struct rt_ringbuffer *rb, - rt_uint8_t **ptr) -{ - rt_size_t size; - - RT_ASSERT(rb != RT_NULL); - - *ptr = RT_NULL; - - /* whether has enough data */ - size = rt_ringbuffer_data_len(rb); - - /* no data */ - if (size == 0) - return 0; - - *ptr = &rb->buffer_ptr[rb->read_index]; - - if(rb->buffer_size - rb->read_index > size) - { - return size; - } - - return rb->buffer_size - rb->read_index; -} - -static rt_ssize_t rt_serial_update_read_index(struct rt_ringbuffer *rb, - rt_uint16_t read_index) -{ - rt_size_t size; - - RT_ASSERT(rb != RT_NULL); - - /* whether has enough data */ - size = rt_ringbuffer_data_len(rb); - - /* no data */ - if (size == 0) - return 0; - - /* less data */ - if(size < read_index) - read_index = size; - - if(rb->buffer_size - rb->read_index > read_index) - { - rb->read_index += read_index; - return read_index; - } - - read_index = rb->buffer_size - rb->read_index; - - /* we are going into the other side of the mirror */ - rb->read_mirror = ~rb->read_mirror; - rb->read_index = 0; - - return read_index; -} - -static rt_ssize_t rt_serial_update_write_index(struct rt_ringbuffer *rb, - rt_uint16_t write_size) -{ - rt_uint16_t size; - RT_ASSERT(rb != RT_NULL); - - /* whether has enough space */ - size = rt_ringbuffer_space_len(rb); - - /* no space, drop some data */ - if (size < write_size) - { - write_size = size; -#if !defined(RT_USING_ULOG) || defined(ULOG_USING_ISR_LOG) - LOG_W("The serial buffer (len %d) is overflow.", rb->buffer_size); -#endif - } - - if (rb->buffer_size - rb->write_index > write_size) - { - /* this should not cause overflow because there is enough space for - * length of data in current mirror */ - rb->write_index += write_size; - return write_size; - } - - /* we are going into the other side of the mirror */ - rb->write_mirror = ~rb->write_mirror; - rb->write_index = write_size - (rb->buffer_size - rb->write_index); - - return write_size; -} - - -/** - * @brief Serial polling receive data routine, This function will receive data - * in a continuous loop by one by one byte. - * @param dev The pointer of device driver structure - * @param pos Empty parameter. - * @param buffer Receive data buffer. - * @param size Receive data buffer length. - * @return Return the final length of data received. - */ -rt_ssize_t _serial_poll_rx(struct rt_device *dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - struct rt_serial_device *serial; - rt_size_t getc_size; - int getc_element; /* Gets one byte of data received */ - rt_uint8_t *getc_buffer; /* Pointer to the receive data buffer */ - - RT_ASSERT(dev != RT_NULL); - - serial = (struct rt_serial_device *)dev; - RT_ASSERT(serial != RT_NULL); - getc_buffer = (rt_uint8_t *)buffer; - getc_size = size; - - while(size) - { - getc_element = serial->ops->getc(serial); - if (getc_element == -1) break; - - *getc_buffer = getc_element; - - ++ getc_buffer; - -- size; - - if (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM) - { - /* If open_flag satisfies RT_DEVICE_FLAG_STREAM - * and the received character is '\n', exit the loop directly */ - if (getc_element == '\n') break; - } - } - - return getc_size - size; -} - -/** - * @brief Serial polling transmit data routines, This function will transmit - * data in a continuous loop by one by one byte. - * @param dev The pointer of device driver structure - * @param pos Empty parameter. - * @param buffer Transmit data buffer. - * @param size Transmit data buffer length. - * @return Return the final length of data received. - */ -rt_ssize_t _serial_poll_tx(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct rt_serial_device *serial; - rt_size_t putc_size; - rt_uint8_t *putc_buffer; /* Pointer to the transmit data buffer */ - RT_ASSERT(dev != RT_NULL); - - serial = (struct rt_serial_device *)dev; - RT_ASSERT(serial != RT_NULL); - - putc_buffer = (rt_uint8_t *)buffer; - putc_size = size; - - while (size) - { - if (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM) - { - /* If open_flag satisfies RT_DEVICE_FLAG_STREAM and the received character is '\n', - * inserts '\r' character before '\n' character for the effect of carriage return newline */ - if (*putc_buffer == '\n') - serial->ops->putc(serial, '\r'); - } - serial->ops->putc(serial, *putc_buffer); - - ++ putc_buffer; - -- size; - } - - return putc_size - size; -} - -/** - * @brief Serial receive data routines, This function will receive - * data by using fifo - * @param dev The pointer of device driver structure - * @param pos Empty parameter. - * @param buffer Receive data buffer. - * @param size Receive data buffer length. - * @return Return the final length of data received. - */ -static rt_ssize_t _serial_fifo_rx(struct rt_device *dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - struct rt_serial_device *serial; - struct rt_serial_rx_fifo *rx_fifo; - rt_base_t level; - rt_size_t recv_len; /* The length of data from the ringbuffer */ - - RT_ASSERT(dev != RT_NULL); - if (size == 0) return 0; - - serial = (struct rt_serial_device *)dev; - - RT_ASSERT((serial != RT_NULL) && (buffer != RT_NULL)); - - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - - if (dev->open_flag & RT_SERIAL_RX_BLOCKING) - { - if (size > serial->config.rx_bufsz) - { - LOG_W("(%s) serial device received data:[%d] larger than " - "rx_bufsz:[%d], please increase the BSP_UARTx_RX_BUFSIZE option", - dev->parent.name, size, serial->config.rx_bufsz); - - return 0; - } - /* Get the length of the data from the ringbuffer */ - recv_len = rt_ringbuffer_data_len(&(rx_fifo->rb)); - - if (recv_len < size) - { - /* When recv_len is less than size, rx_cpt_index is updated to the size - * and rt_current_thread is suspend until rx_cpt_index is equal to 0 */ - rx_fifo->rx_cpt_index = size; - rt_completion_wait(&(rx_fifo->rx_cpt), RT_WAITING_FOREVER); - } - } - - /* This part of the code is open_flag as RT_SERIAL_RX_NON_BLOCKING */ - - level = rt_hw_interrupt_disable(); - /* When open_flag is RT_SERIAL_RX_NON_BLOCKING, - * the data is retrieved directly from the ringbuffer and returned */ - recv_len = rt_ringbuffer_get(&(rx_fifo->rb), buffer, size); - - rt_hw_interrupt_enable(level); - - return recv_len; -} - -/** - * @brief Serial transmit data routines, This function will transmit - * data by using blocking_nbuf. - * @param dev The pointer of device driver structure - * @param pos Empty parameter. - * @param buffer Transmit data buffer. - * @param size Transmit data buffer length. - * @return Return the final length of data transmit. - */ -static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct rt_serial_device *serial; - struct rt_serial_tx_fifo *tx_fifo = RT_NULL; - rt_ssize_t rst; - - RT_ASSERT(dev != RT_NULL); - if (size == 0) return 0; - - serial = (struct rt_serial_device *)dev; - RT_ASSERT((serial != RT_NULL) && (buffer != RT_NULL)); - tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); - - if (rt_thread_self() == RT_NULL || (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)) - { - /* using poll tx when the scheduler not startup or in stream mode */ - return _serial_poll_tx(dev, pos, buffer, size); - } - - /* When serial transmit in tx_blocking mode, - * if the activated mode is RT_TRUE, it will return directly */ - if (tx_fifo->activated == RT_TRUE) return 0; - - tx_fifo->activated = RT_TRUE; - /* Call the transmit interface for transmission */ - rst = serial->ops->transmit(serial, - (rt_uint8_t *)buffer, - size, - RT_SERIAL_TX_BLOCKING); - /* Waiting for the transmission to complete */ - rt_completion_wait(&(tx_fifo->tx_cpt), RT_WAITING_FOREVER); - /* Inactive tx mode flag */ - tx_fifo->activated = RT_FALSE; - return rst; -} - -/** - * @brief Serial transmit data routines, This function will transmit - * data by using blocking_buf. - * @param dev The pointer of device driver structure - * @param pos Empty parameter. - * @param buffer Transmit data buffer. - * @param size Transmit data buffer length. - * @return Return the final length of data transmit. - */ -static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct rt_serial_device *serial; - struct rt_serial_tx_fifo *tx_fifo = RT_NULL; - rt_size_t length = size; - rt_size_t offset = 0; - - if (size == 0) return 0; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - RT_ASSERT((serial != RT_NULL) && (buffer != RT_NULL)); - - tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); - - if (rt_thread_self() == RT_NULL || (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)) - { - /* using poll tx when the scheduler not startup or in stream mode */ - return _serial_poll_tx(dev, pos, buffer, size); - } - /* When serial transmit in tx_blocking mode, - * if the activated mode is RT_TRUE, it will return directly */ - if (tx_fifo->activated == RT_TRUE) return 0; - tx_fifo->activated = RT_TRUE; - - while (size) - { - /* Copy one piece of data into the ringbuffer at a time - * until the length of the data is equal to size */ - tx_fifo->put_size = rt_ringbuffer_put(&(tx_fifo->rb), - (rt_uint8_t *)buffer + offset, - size); - - /* Call the transmit interface for transmission */ - serial->ops->transmit(serial, - (rt_uint8_t *)buffer + offset, - tx_fifo->put_size, - RT_SERIAL_TX_BLOCKING); - - offset += tx_fifo->put_size; - size -= tx_fifo->put_size; - /* Waiting for the transmission to complete */ - rt_completion_wait(&(tx_fifo->tx_cpt), RT_WAITING_FOREVER); - } - /* Finally Inactivate the tx->fifo */ - tx_fifo->activated = RT_FALSE; - - return length; -} - -/** - * @brief Serial transmit data routines, This function will transmit - * data by using nonblocking. - * @param dev The pointer of device driver structure - * @param pos Empty parameter. - * @param buffer Transmit data buffer. - * @param size Transmit data buffer length. - * @return Return the final length of data transmit. - */ -static rt_ssize_t _serial_fifo_tx_nonblocking(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct rt_serial_device *serial; - struct rt_serial_tx_fifo *tx_fifo; - rt_base_t level; - rt_size_t length; - - RT_ASSERT(dev != RT_NULL); - if (size == 0) return 0; - - serial = (struct rt_serial_device *)dev; - RT_ASSERT((serial != RT_NULL) && (buffer != RT_NULL)); - tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx; - - level = rt_hw_interrupt_disable(); - - if (tx_fifo->activated == RT_FALSE) - { - /* When serial transmit in tx_non_blocking mode, if the activated mode is RT_FALSE, - * start copying data into the ringbuffer */ - tx_fifo->activated = RT_TRUE; - /* Copying data into the ringbuffer */ - length = rt_ringbuffer_put(&(tx_fifo->rb), buffer, size); - - rt_hw_interrupt_enable(level); - - rt_uint8_t *put_ptr = RT_NULL; - /* Get the linear length buffer from ringbuffer */ - tx_fifo->put_size = rt_serial_get_linear_buffer(&(tx_fifo->rb), &put_ptr); - /* Call the transmit interface for transmission */ - serial->ops->transmit(serial, - put_ptr, - tx_fifo->put_size, - RT_SERIAL_TX_NON_BLOCKING); - /* In tx_nonblocking mode, there is no need to call rt_completion_wait() APIs to wait - * for the rt_current_thread to resume */ - return length; - } - - /* If the activated mode is RT_TRUE, it means that serial device is transmitting, - * where only the data in the ringbuffer and there is no need to call the transmit() API. - * Note that this part of the code requires disable interrupts - * to prevent multi thread reentrant */ - - /* Copying data into the ringbuffer */ - length = rt_ringbuffer_put(&(tx_fifo->rb), buffer, size); - - rt_hw_interrupt_enable(level); - - return length; -} - - -/** - * @brief Enable serial transmit mode. - * @param dev The pointer of device driver structure - * @param rx_oflag The flag of that the serial port opens. - * @return Return the status of the operation. - */ -static rt_err_t rt_serial_tx_enable(struct rt_device *dev, - rt_uint16_t tx_oflag) -{ - struct rt_serial_device *serial; - struct rt_serial_tx_fifo *tx_fifo = RT_NULL; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - - if (serial->config.tx_bufsz == 0) - { - /* Cannot use RT_SERIAL_TX_NON_BLOCKING when tx_bufsz is 0 */ - if (tx_oflag == RT_SERIAL_TX_NON_BLOCKING) - { - LOG_E("(%s) serial device with misconfigure: tx_bufsz = 0", - dev->parent.name); - return -RT_EINVAL; - } - -#ifndef RT_USING_DEVICE_OPS - dev->write = _serial_poll_tx; -#endif - - dev->open_flag |= RT_SERIAL_TX_BLOCKING; - return RT_EOK; - } - /* Limits the minimum value of tx_bufsz */ - if (serial->config.tx_bufsz < RT_SERIAL_TX_MINBUFSZ) - serial->config.tx_bufsz = RT_SERIAL_TX_MINBUFSZ; - - if (tx_oflag == RT_SERIAL_TX_BLOCKING) - { - /* When using RT_SERIAL_TX_BLOCKING, it is necessary to determine - * whether serial device needs to use buffer */ - rt_err_t optmode; /* The operating mode used by serial device */ - /* Call the Control() API to get the operating mode */ - optmode = serial->ops->control(serial, - RT_DEVICE_CHECK_OPTMODE, - (void *)RT_DEVICE_FLAG_TX_BLOCKING); - if (optmode == RT_SERIAL_TX_BLOCKING_BUFFER) - { - /* If use RT_SERIAL_TX_BLOCKING_BUFFER, the ringbuffer is initialized */ - tx_fifo = (struct rt_serial_tx_fifo *) rt_malloc - (sizeof(struct rt_serial_tx_fifo) + serial->config.tx_bufsz); - RT_ASSERT(tx_fifo != RT_NULL); - - rt_ringbuffer_init(&(tx_fifo->rb), - tx_fifo->buffer, - serial->config.tx_bufsz); - serial->serial_tx = tx_fifo; - -#ifndef RT_USING_DEVICE_OPS - dev->write = _serial_fifo_tx_blocking_buf; -#endif - } - else - { - /* If not use RT_SERIAL_TX_BLOCKING_BUFFER, - * the control() API is called to configure the serial device */ - tx_fifo = (struct rt_serial_tx_fifo*) rt_malloc - (sizeof(struct rt_serial_tx_fifo)); - RT_ASSERT(tx_fifo != RT_NULL); - - /* Init rb.buffer_ptr to RT_NULL, in rt_serial_write() need check it - * otherwise buffer_ptr maybe a random value, as rt_malloc not init memory */ - tx_fifo->rb.buffer_ptr = RT_NULL; - serial->serial_tx = tx_fifo; - -#ifndef RT_USING_DEVICE_OPS - dev->write = _serial_fifo_tx_blocking_nbuf; -#endif - - /* Call the control() API to configure the serial device by RT_SERIAL_TX_BLOCKING*/ - serial->ops->control(serial, - RT_DEVICE_CTRL_CONFIG, - (void *)RT_SERIAL_TX_BLOCKING); - rt_memset(&tx_fifo->rb, RT_NULL, sizeof(tx_fifo->rb)); - } - - tx_fifo->activated = RT_FALSE; - tx_fifo->put_size = 0; - rt_completion_init(&(tx_fifo->tx_cpt)); - dev->open_flag |= RT_SERIAL_TX_BLOCKING; - - return RT_EOK; - } - /* When using RT_SERIAL_TX_NON_BLOCKING, ringbuffer needs to be initialized, - * and initialize the tx_fifo->activated value is RT_FALSE. - */ - tx_fifo = (struct rt_serial_tx_fifo *) rt_malloc - (sizeof(struct rt_serial_tx_fifo) + serial->config.tx_bufsz); - RT_ASSERT(tx_fifo != RT_NULL); - - tx_fifo->activated = RT_FALSE; - tx_fifo->put_size = 0; - rt_ringbuffer_init(&(tx_fifo->rb), - tx_fifo->buffer, - serial->config.tx_bufsz); - serial->serial_tx = tx_fifo; - -#ifndef RT_USING_DEVICE_OPS - dev->write = _serial_fifo_tx_nonblocking; -#endif - - dev->open_flag |= RT_SERIAL_TX_NON_BLOCKING; - /* Call the control() API to configure the serial device by RT_SERIAL_TX_NON_BLOCKING*/ - serial->ops->control(serial, - RT_DEVICE_CTRL_CONFIG, - (void *)RT_SERIAL_TX_NON_BLOCKING); - - return RT_EOK; -} - - -/** - * @brief Enable serial receive mode. - * @param dev The pointer of device driver structure - * @param rx_oflag The flag of that the serial port opens. - * @return Return the status of the operation. - */ -static rt_err_t rt_serial_rx_enable(struct rt_device *dev, - rt_uint16_t rx_oflag) -{ - struct rt_serial_device *serial; - struct rt_serial_rx_fifo *rx_fifo = RT_NULL; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - - if (serial->config.rx_bufsz == 0) - { - /* Cannot use RT_SERIAL_RX_NON_BLOCKING when rx_bufsz is 0 */ - if (rx_oflag == RT_SERIAL_RX_NON_BLOCKING) - { - LOG_E("(%s) serial device with misconfigure: rx_bufsz = 0", - dev->parent.name); - return -RT_EINVAL; - } - -#ifndef RT_USING_DEVICE_OPS - dev->read = _serial_poll_rx; -#endif - - dev->open_flag |= RT_SERIAL_RX_BLOCKING; - return RT_EOK; - } - /* Limits the minimum value of rx_bufsz */ - if (serial->config.rx_bufsz < RT_SERIAL_RX_MINBUFSZ) - serial->config.rx_bufsz = RT_SERIAL_RX_MINBUFSZ; - - rx_fifo = (struct rt_serial_rx_fifo *) rt_malloc - (sizeof(struct rt_serial_rx_fifo) + serial->config.rx_bufsz); - - RT_ASSERT(rx_fifo != RT_NULL); - rt_ringbuffer_init(&(rx_fifo->rb), rx_fifo->buffer, serial->config.rx_bufsz); - - serial->serial_rx = rx_fifo; - -#ifndef RT_USING_DEVICE_OPS - dev->read = _serial_fifo_rx; -#endif - - if (rx_oflag == RT_SERIAL_RX_NON_BLOCKING) - { - dev->open_flag |= RT_SERIAL_RX_NON_BLOCKING; - /* Call the control() API to configure the serial device by RT_SERIAL_RX_NON_BLOCKING*/ - serial->ops->control(serial, - RT_DEVICE_CTRL_CONFIG, - (void *) RT_SERIAL_RX_NON_BLOCKING); - - return RT_EOK; - } - /* When using RT_SERIAL_RX_BLOCKING, rt_completion_init() and rx_cpt_index are initialized */ - rx_fifo->rx_cpt_index = 0; - rt_completion_init(&(rx_fifo->rx_cpt)); - dev->open_flag |= RT_SERIAL_RX_BLOCKING; - /* Call the control() API to configure the serial device by RT_SERIAL_RX_BLOCKING*/ - serial->ops->control(serial, - RT_DEVICE_CTRL_CONFIG, - (void *) RT_SERIAL_RX_BLOCKING); - - return RT_EOK; -} - -/** - * @brief Disable serial receive mode. - * @param dev The pointer of device driver structure - * @param rx_oflag The flag of that the serial port opens. - * @return Return the status of the operation. - */ -static rt_err_t rt_serial_rx_disable(struct rt_device *dev, - rt_uint16_t rx_oflag) -{ - struct rt_serial_device *serial; - struct rt_serial_rx_fifo *rx_fifo; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - -#ifndef RT_USING_DEVICE_OPS - dev->read = RT_NULL; -#endif - - if (serial->serial_rx == RT_NULL) return RT_EOK; - - do - { - if (rx_oflag == RT_SERIAL_RX_NON_BLOCKING) - { - dev->open_flag &= ~ RT_SERIAL_RX_NON_BLOCKING; - serial->ops->control(serial, - RT_DEVICE_CTRL_CLR_INT, - (void *)RT_SERIAL_RX_NON_BLOCKING); - break; - } - - dev->open_flag &= ~ RT_SERIAL_RX_BLOCKING; - serial->ops->control(serial, - RT_DEVICE_CTRL_CLR_INT, - (void *)RT_SERIAL_RX_BLOCKING); - } while (0); - - rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; - RT_ASSERT(rx_fifo != RT_NULL); - rt_free(rx_fifo); - serial->serial_rx = RT_NULL; - - return RT_EOK; -} - -/** - * @brief Disable serial tranmit mode. - * @param dev The pointer of device driver structure - * @param rx_oflag The flag of that the serial port opens. - * @return Return the status of the operation. - */ -static rt_err_t rt_serial_tx_disable(struct rt_device *dev, - rt_uint16_t tx_oflag) -{ - struct rt_serial_device *serial; - struct rt_serial_tx_fifo *tx_fifo; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - -#ifndef RT_USING_DEVICE_OPS - dev->write = RT_NULL; -#endif - - if (serial->serial_tx == RT_NULL) return RT_EOK; - - tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); - - do - { - if (tx_oflag == RT_SERIAL_TX_NON_BLOCKING) - { - dev->open_flag &= ~ RT_SERIAL_TX_NON_BLOCKING; - - serial->ops->control(serial, - RT_DEVICE_CTRL_CLR_INT, - (void *)RT_SERIAL_TX_NON_BLOCKING); - break; - } - - rt_completion_done(&(tx_fifo->tx_cpt)); - dev->open_flag &= ~ RT_SERIAL_TX_BLOCKING; - serial->ops->control(serial, - RT_DEVICE_CTRL_CLR_INT, - (void *)RT_SERIAL_TX_BLOCKING); - } while (0); - - rt_free(tx_fifo); - serial->serial_tx = RT_NULL; - - rt_memset(&serial->rx_notify, 0, sizeof(struct rt_device_notify)); - - return RT_EOK; -} - -/** - * @brief Initialize the serial device. - * @param dev The pointer of device driver structure - * @return Return the status of the operation. - */ -static rt_err_t rt_serial_init(struct rt_device *dev) -{ - rt_err_t result = RT_EOK; - struct rt_serial_device *serial; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - RT_ASSERT(serial->ops->transmit != RT_NULL); - - /* initialize rx/tx */ - serial->serial_rx = RT_NULL; - serial->serial_tx = RT_NULL; - - /* apply configuration */ - if (serial->ops->configure) - result = serial->ops->configure(serial, &serial->config); - - return result; -} - -/** - * @brief Open the serial device. - * @param dev The pointer of device driver structure - * @param oflag The flag of that the serial port opens. - * @return Return the status of the operation. - */ -static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag) -{ - struct rt_serial_device *serial; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - - /* Check that the device has been turned on */ - if ((dev->open_flag) & (15 << 12)) - { - LOG_D("(%s) serial device has already been opened, it will run in its original configuration", dev->parent.name); - return RT_EOK; - } - - LOG_D("open serial device: 0x%08x with open flag: 0x%04x", - dev, oflag); - - /* By default, the receive mode of a serial devide is RT_SERIAL_RX_NON_BLOCKING */ - if ((oflag & RT_SERIAL_RX_BLOCKING) == RT_SERIAL_RX_BLOCKING) - dev->open_flag |= RT_SERIAL_RX_BLOCKING; - else - dev->open_flag |= RT_SERIAL_RX_NON_BLOCKING; - - /* By default, the transmit mode of a serial devide is RT_SERIAL_TX_BLOCKING */ - if ((oflag & RT_SERIAL_TX_NON_BLOCKING) == RT_SERIAL_TX_NON_BLOCKING) - dev->open_flag |= RT_SERIAL_TX_NON_BLOCKING; - else - dev->open_flag |= RT_SERIAL_TX_BLOCKING; - - /* set steam flag */ - if ((oflag & RT_DEVICE_FLAG_STREAM) || - (dev->open_flag & RT_DEVICE_FLAG_STREAM)) - dev->open_flag |= RT_DEVICE_FLAG_STREAM; - - /* initialize the Rx structure according to open flag */ - if (serial->serial_rx == RT_NULL) - rt_serial_rx_enable(dev, dev->open_flag & - (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING)); - - /* initialize the Tx structure according to open flag */ - if (serial->serial_tx == RT_NULL) - rt_serial_tx_enable(dev, dev->open_flag & - (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING)); - - return RT_EOK; -} - - -/** - * @brief Close the serial device. - * @param dev The pointer of device driver structure - * @return Return the status of the operation. - */ -static rt_err_t rt_serial_close(struct rt_device *dev) -{ - struct rt_serial_device *serial; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - - /* this device has more reference count */ - if (dev->ref_count > 1) return -RT_ERROR; - /* Disable serial receive mode. */ - rt_serial_rx_disable(dev, dev->open_flag & - (RT_SERIAL_RX_BLOCKING | RT_SERIAL_RX_NON_BLOCKING)); - /* Disable serial tranmit mode. */ - rt_serial_tx_disable(dev, dev->open_flag & - (RT_SERIAL_TX_BLOCKING | RT_SERIAL_TX_NON_BLOCKING)); - - /* Clear the callback function */ - serial->parent.rx_indicate = RT_NULL; - serial->parent.tx_complete = RT_NULL; - - /* Call the control() API to close the serial device */ - serial->ops->control(serial, RT_DEVICE_CTRL_CLOSE, RT_NULL); - dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED; - - return RT_EOK; -} - -#ifdef RT_USING_POSIX_TERMIOS -struct speed_baudrate_item -{ - speed_t speed; - int baudrate; -}; - -const static struct speed_baudrate_item _tbl[] = -{ - {B2400, BAUD_RATE_2400}, - {B4800, BAUD_RATE_4800}, - {B9600, BAUD_RATE_9600}, - {B19200, BAUD_RATE_19200}, - {B38400, BAUD_RATE_38400}, - {B57600, BAUD_RATE_57600}, - {B115200, BAUD_RATE_115200}, - {B230400, BAUD_RATE_230400}, - {B460800, BAUD_RATE_460800}, - {B500000, BAUD_RATE_500000}, - {B921600, BAUD_RATE_921600}, - {B2000000, BAUD_RATE_2000000}, - {B3000000, BAUD_RATE_3000000}, -}; - -static speed_t _get_speed(int baudrate) -{ - int index; - - for (index = 0; index < sizeof(_tbl)/sizeof(_tbl[0]); index ++) - { - if (_tbl[index].baudrate == baudrate) - return _tbl[index].speed; - } - - return B0; -} - -static int _get_baudrate(speed_t speed) -{ - int index; - - for (index = 0; index < sizeof(_tbl)/sizeof(_tbl[0]); index ++) - { - if (_tbl[index].speed == speed) - return _tbl[index].baudrate; - } - - return 0; -} - -static void _tc_flush(struct rt_serial_device *serial, int queue) -{ - rt_base_t level; - int ch = -1; - struct rt_serial_rx_fifo *rx_fifo = RT_NULL; - struct rt_device *device = RT_NULL; - - RT_ASSERT(serial != RT_NULL); - - device = &(serial->parent); - rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - - switch(queue) - { - case TCIFLUSH: - case TCIOFLUSH: - RT_ASSERT(rx_fifo != RT_NULL); - - if((device->open_flag & RT_DEVICE_FLAG_INT_RX) || (device->open_flag & RT_DEVICE_FLAG_DMA_RX)) - { - RT_ASSERT(RT_NULL != rx_fifo); - level = rt_hw_interrupt_disable(); - rx_fifo->rx_cpt_index = 0; - rt_hw_interrupt_enable(level); - } - else - { - while (1) - { - ch = serial->ops->getc(serial); - if (ch == -1) break; - } - } - - break; - - case TCOFLUSH: - break; - } - -} -#endif /* RT_USING_POSIX_TERMIOS */ - -/** - * @brief Control the serial device. - * @param dev The pointer of device driver structure - * @param cmd The command value that controls the serial device - * @param args The parameter value that controls the serial device - * @return Return the status of the operation. - */ -static rt_err_t rt_serial_control(struct rt_device *dev, - int cmd, - void *args) -{ - rt_err_t ret = RT_EOK; - struct rt_serial_device *serial; - - RT_ASSERT(dev != RT_NULL); - serial = (struct rt_serial_device *)dev; - - switch (cmd) - { - case RT_DEVICE_CTRL_SUSPEND: - /* suspend device */ - dev->flag |= RT_DEVICE_FLAG_SUSPENDED; - break; - - case RT_DEVICE_CTRL_RESUME: - /* resume device */ - dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED; - break; - - case RT_DEVICE_CTRL_CONFIG: - if (args != RT_NULL) - { - struct serial_configure *pconfig = (struct serial_configure *) args; - if (((pconfig->rx_bufsz != serial->config.rx_bufsz) || (pconfig->tx_bufsz != serial->config.tx_bufsz)) - && serial->parent.ref_count) - { - /*can not change buffer size*/ - return -RT_EBUSY; - } - /* set serial configure */ - serial->config = *pconfig; - serial->ops->configure(serial, (struct serial_configure *) args); - } - break; - case RT_DEVICE_CTRL_NOTIFY_SET: - if (args) - { - rt_memcpy(&serial->rx_notify, args, sizeof(struct rt_device_notify)); - } - break; - - case RT_DEVICE_CTRL_CONSOLE_OFLAG: - if (args) - { - *(rt_uint16_t*)args = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM; - } - break; -#ifdef RT_USING_POSIX_STDIO -#ifdef RT_USING_POSIX_TERMIOS - case TCGETA: - { - struct termios *tio = (struct termios*)args; - if (tio == RT_NULL) return -RT_EINVAL; - - tio->c_iflag = 0; - tio->c_oflag = 0; - tio->c_lflag = 0; - - /* update oflag for console device */ - if (rt_console_get_device() == dev) - tio->c_oflag = OPOST | ONLCR; - - /* set cflag */ - tio->c_cflag = 0; - if (serial->config.data_bits == DATA_BITS_5) - tio->c_cflag = CS5; - else if (serial->config.data_bits == DATA_BITS_6) - tio->c_cflag = CS6; - else if (serial->config.data_bits == DATA_BITS_7) - tio->c_cflag = CS7; - else if (serial->config.data_bits == DATA_BITS_8) - tio->c_cflag = CS8; - - if (serial->config.stop_bits == STOP_BITS_2) - tio->c_cflag |= CSTOPB; - - if (serial->config.parity == PARITY_EVEN) - tio->c_cflag |= PARENB; - else if (serial->config.parity == PARITY_ODD) - tio->c_cflag |= (PARODD | PARENB); - - if (serial->config.flowcontrol == RT_SERIAL_FLOWCONTROL_CTSRTS) - tio->c_cflag |= CRTSCTS; - - cfsetospeed(tio, _get_speed(serial->config.baud_rate)); - } - break; - - case TCSETAW: - case TCSETAF: - case TCSETA: - { - int baudrate; - struct serial_configure config; - - struct termios *tio = (struct termios*)args; - if (tio == RT_NULL) return -RT_EINVAL; - - config = serial->config; - - baudrate = _get_baudrate(cfgetospeed(tio)); - config.baud_rate = baudrate; - - switch (tio->c_cflag & CSIZE) - { - case CS5: - config.data_bits = DATA_BITS_5; - break; - case CS6: - config.data_bits = DATA_BITS_6; - break; - case CS7: - config.data_bits = DATA_BITS_7; - break; - default: - config.data_bits = DATA_BITS_8; - break; - } - - if (tio->c_cflag & CSTOPB) config.stop_bits = STOP_BITS_2; - else config.stop_bits = STOP_BITS_1; - - if (tio->c_cflag & PARENB) - { - if (tio->c_cflag & PARODD) config.parity = PARITY_ODD; - else config.parity = PARITY_EVEN; - } - else config.parity = PARITY_NONE; - - if (tio->c_cflag & CRTSCTS) config.flowcontrol = RT_SERIAL_FLOWCONTROL_CTSRTS; - else config.flowcontrol = RT_SERIAL_FLOWCONTROL_NONE; - - /* set serial configure */ - serial->config = config; - serial->ops->configure(serial, &config); - } - break; - case TCFLSH: - { - int queue = (int)args; - - _tc_flush(serial, queue); - } - - break; - case TCXONC: - break; -#endif /*RT_USING_POSIX_TERMIOS*/ - case TIOCSWINSZ: - { - struct winsize* p_winsize; - - p_winsize = (struct winsize*)args; - rt_kprintf("\x1b[8;%d;%dt", p_winsize->ws_col, p_winsize->ws_row); - } - break; - case TIOCGWINSZ: - { - struct winsize* p_winsize; - p_winsize = (struct winsize*)args; - - if(rt_thread_self() != rt_thread_find(FINSH_THREAD_NAME)) - { - /* only can be used in tshell thread; otherwise, return default size */ - p_winsize->ws_col = 80; - p_winsize->ws_row = 24; - } - else - { - #include - #define _TIO_BUFLEN 20 - char _tio_buf[_TIO_BUFLEN]; - unsigned char cnt1, cnt2, cnt3, i; - char row_s[4], col_s[4]; - char *p; - - rt_memset(_tio_buf, 0, _TIO_BUFLEN); - - /* send the command to terminal for getting the window size of the terminal */ - rt_kprintf("\033[18t"); - - /* waiting for the response from the terminal */ - i = 0; - while(i < _TIO_BUFLEN) - { - _tio_buf[i] = finsh_getchar(); - if(_tio_buf[i] != 't') - { - i ++; - } - else - { - break; - } - } - if(i == _TIO_BUFLEN) - { - /* buffer overloaded, and return default size */ - p_winsize->ws_col = 80; - p_winsize->ws_row = 24; - break; - } - - /* interpreting data eg: "\033[8;1;15t" which means row is 1 and col is 15 (unit: size of ONE character) */ - rt_memset(row_s,0,4); - rt_memset(col_s,0,4); - cnt1 = 0; - while(cnt1 < _TIO_BUFLEN && _tio_buf[cnt1] != ';') - { - cnt1++; - } - cnt2 = ++cnt1; - while(cnt2 < _TIO_BUFLEN && _tio_buf[cnt2] != ';') - { - cnt2++; - } - p = row_s; - while(cnt1 < cnt2) - { - *p++ = _tio_buf[cnt1++]; - } - p = col_s; - cnt2++; - cnt3 = rt_strlen(_tio_buf) - 1; - while(cnt2 < cnt3) - { - *p++ = _tio_buf[cnt2++]; - } - - /* load the window size date */ - p_winsize->ws_col = atoi(col_s); - p_winsize->ws_row = atoi(row_s); - #undef _TIO_BUFLEN - } - - p_winsize->ws_xpixel = 0;/* unused */ - p_winsize->ws_ypixel = 0;/* unused */ - } - break; - case FIONREAD: - { - rt_size_t recved = 0; - rt_base_t level; - struct rt_serial_rx_fifo * rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx; - - level = rt_hw_interrupt_disable(); - recved = rt_ringbuffer_data_len(&(rx_fifo->rb)); - rt_hw_interrupt_enable(level); - - *(rt_size_t *)args = recved; - } - break; -#endif /* RT_USING_POSIX_STDIO */ - default : - /* control device */ - ret = serial->ops->control(serial, cmd, args); - break; - } - - return ret; -} - -#ifdef RT_USING_DEVICE_OPS -static rt_ssize_t rt_serial_read(struct rt_device *dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - struct rt_serial_device *serial; - - RT_ASSERT(dev != RT_NULL); - if (size == 0) return 0; - - serial = (struct rt_serial_device *)dev; - - if (serial->config.rx_bufsz) - { - return _serial_fifo_rx(dev, pos, buffer, size); - } - - return _serial_poll_rx(dev, pos, buffer, size); -} - - -static rt_ssize_t rt_serial_write(struct rt_device *dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct rt_serial_device *serial; - struct rt_serial_tx_fifo *tx_fifo; - - RT_ASSERT(dev != RT_NULL); - if (size == 0) return 0; - - serial = (struct rt_serial_device *)dev; - RT_ASSERT((serial != RT_NULL) && (buffer != RT_NULL)); - tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx; - - if (serial->config.tx_bufsz == 0) - { - return _serial_poll_tx(dev, pos, buffer, size); - } - - if (dev->open_flag & RT_SERIAL_TX_BLOCKING) - { - if ((tx_fifo->rb.buffer_ptr) == RT_NULL) - { - return _serial_fifo_tx_blocking_nbuf(dev, pos, buffer, size); - } - - return _serial_fifo_tx_blocking_buf(dev, pos, buffer, size); - } - - return _serial_fifo_tx_nonblocking(dev, pos, buffer, size); -} - -const static struct rt_device_ops serial_ops = -{ - rt_serial_init, - rt_serial_open, - rt_serial_close, - rt_serial_read, - rt_serial_write, - rt_serial_control -}; -#endif - -/** - * @brief Register the serial device. - * @param serial RT-thread serial device. - * @param name The device driver's name - * @param flag The capabilities flag of device. - * @param data The device driver's data. - * @return Return the status of the operation. - */ -rt_err_t rt_hw_serial_register(struct rt_serial_device *serial, - const char *name, - rt_uint32_t flag, - void *data) -{ - rt_err_t ret; - struct rt_device *device; - RT_ASSERT(serial != RT_NULL); - - device = &(serial->parent); - - device->type = RT_Device_Class_Char; - device->rx_indicate = RT_NULL; - device->tx_complete = RT_NULL; - -#ifdef RT_USING_DEVICE_OPS - device->ops = &serial_ops; -#else - device->init = rt_serial_init; - device->open = rt_serial_open; - device->close = rt_serial_close; - device->read = RT_NULL; - device->write = RT_NULL; - device->control = rt_serial_control; -#endif - device->user_data = data; - - /* register a character device */ - ret = rt_device_register(device, name, flag); - -#ifdef RT_USING_POSIX_STDIO - /* set fops */ - device->fops = &_serial_fops; -#endif - return ret; -} - -/** - * @brief ISR for serial interrupt - * @param serial RT-thread serial device. - * @param event ISR event type. - */ -void rt_hw_serial_isr(struct rt_serial_device *serial, int event) -{ - RT_ASSERT(serial != RT_NULL); - - switch (event & 0xff) - { - /* Interrupt receive event */ - case RT_SERIAL_EVENT_RX_IND: - case RT_SERIAL_EVENT_RX_DMADONE: - { - struct rt_serial_rx_fifo *rx_fifo; - rt_size_t rx_length = 0; - rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; - rt_base_t level; - RT_ASSERT(rx_fifo != RT_NULL); - - /* If the event is RT_SERIAL_EVENT_RX_IND, rx_length is equal to 0 */ - rx_length = (event & (~0xff)) >> 8; - - if (rx_length) - { /* RT_SERIAL_EVENT_RX_DMADONE MODE */ - level = rt_hw_interrupt_disable(); - rt_serial_update_write_index(&(rx_fifo->rb), rx_length); - rt_hw_interrupt_enable(level); - } - - /* Get the length of the data from the ringbuffer */ - rx_length = rt_ringbuffer_data_len(&rx_fifo->rb); - if (rx_length == 0) break; - - if (serial->parent.open_flag & RT_SERIAL_RX_BLOCKING) - { - if (rx_fifo->rx_cpt_index && rx_length >= rx_fifo->rx_cpt_index ) - { - rx_fifo->rx_cpt_index = 0; - rt_completion_done(&(rx_fifo->rx_cpt)); - } - } - /* Trigger the receiving completion callback */ - if (serial->parent.rx_indicate != RT_NULL) - serial->parent.rx_indicate(&(serial->parent), rx_length); - - if (serial->rx_notify.notify) - { - serial->rx_notify.notify(serial->rx_notify.dev); - } - break; - } - - /* Interrupt transmit event */ - case RT_SERIAL_EVENT_TX_DONE: - { - struct rt_serial_tx_fifo *tx_fifo; - rt_size_t tx_length = 0; - tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); - - /* Get the length of the data from the ringbuffer */ - tx_length = rt_ringbuffer_data_len(&tx_fifo->rb); - /* If there is no data in tx_ringbuffer, - * then the transmit completion callback is triggered*/ - if (tx_length == 0) - { - /* Trigger the transmit completion callback */ - if (serial->parent.tx_complete != RT_NULL) - serial->parent.tx_complete(&serial->parent, RT_NULL); - - /* Maybe some datas left in the buffer still need to be sent in block mode, - * so tx_fifo->activated should be RT_TRUE */ - if (serial->parent.open_flag & RT_SERIAL_TX_BLOCKING) - { - rt_completion_done(&(tx_fifo->tx_cpt)); - } - else - { - tx_fifo->activated = RT_FALSE; - } - - break; - } - - /* Call the transmit interface for transmission again */ - /* Note that in interrupt mode, tx_fifo->buffer and tx_length - * are inactive parameters */ - serial->ops->transmit(serial, - tx_fifo->buffer, - tx_length, - serial->parent.open_flag & ( \ - RT_SERIAL_TX_BLOCKING | \ - RT_SERIAL_TX_NON_BLOCKING)); - break; - } - - case RT_SERIAL_EVENT_TX_DMADONE: - { - struct rt_serial_tx_fifo *tx_fifo; - tx_fifo = (struct rt_serial_tx_fifo *)serial->serial_tx; - RT_ASSERT(tx_fifo != RT_NULL); - - tx_fifo->activated = RT_FALSE; - - /* Trigger the transmit completion callback */ - if (serial->parent.tx_complete != RT_NULL) - serial->parent.tx_complete(&serial->parent, RT_NULL); - - if (serial->parent.open_flag & RT_SERIAL_TX_BLOCKING) - { - rt_completion_done(&(tx_fifo->tx_cpt)); - break; - } - - rt_serial_update_read_index(&tx_fifo->rb, tx_fifo->put_size); - /* Get the length of the data from the ringbuffer. - * If there is some data in tx_ringbuffer, - * then call the transmit interface for transmission again */ - if (rt_ringbuffer_data_len(&tx_fifo->rb)) - { - tx_fifo->activated = RT_TRUE; - - rt_uint8_t *put_ptr = RT_NULL; - /* Get the linear length buffer from ringbuffer */ - tx_fifo->put_size = rt_serial_get_linear_buffer(&(tx_fifo->rb), &put_ptr); - /* Call the transmit interface for transmission again */ - serial->ops->transmit(serial, - put_ptr, - tx_fifo->put_size, - RT_SERIAL_TX_NON_BLOCKING); - } - - break; - } - - default: - break; - } -} diff --git a/rt-thread/components/drivers/serial/serial_tty.c b/rt-thread/components/drivers/serial/serial_tty.c index dae668a..bbf61f8 100644 --- a/rt-thread/components/drivers/serial/serial_tty.c +++ b/rt-thread/components/drivers/serial/serial_tty.c @@ -114,24 +114,59 @@ static void _setup_debug_rxind_hook(void) #endif /* LWP_DEBUG_INIT */ -static rt_err_t _serial_ty_bypass(struct rt_serial_device* serial, char ch,void *data) +static void _tty_rx_notify(struct rt_device *device) { lwp_tty_t tp; - tp = (lwp_tty_t)data; + struct serial_tty_context *softc; - tty_lock(tp); - ttydisc_rint(tp, ch, 0); - ttydisc_rint_done(tp); - tty_unlock(tp); + tp = rt_container_of(device, struct lwp_tty, parent); + RT_ASSERT(tp); - return RT_EOK; + softc = tty_softc(tp); + if (_ttyworkq) + rt_workqueue_submit_work(_ttyworkq, &softc->work, 0); } -rt_inline void _setup_serial(struct rt_serial_device* serial, lwp_tty_t tp, +static void _tty_rx_worker(struct rt_work *work, void *data) +{ + char input; + rt_ssize_t readbytes; + lwp_tty_t tp = data; + struct serial_tty_context *softc; + struct rt_serial_device *serial; + + tty_lock(tp); + + while (1) + { + softc = tty_softc(tp); + serial = softc->parent; + readbytes = rt_device_read(&serial->parent, -1, &input, 1); + if (readbytes != 1) + { + break; + } + + ttydisc_rint(tp, input, 0); + } + + ttydisc_rint_done(tp); + tty_unlock(tp); +} + +rt_inline void _setup_serial(struct rt_serial_device *serial, lwp_tty_t tp, struct serial_tty_context *softc) { - rt_bypass_lower_register(serial, "tty",RT_BYPASS_PROTECT_LEVEL_1, _serial_ty_bypass,(void *)tp); + struct rt_device_notify notify; + + softc->backup_notify = serial->rx_notify; + notify.dev = &tp->parent; + notify.notify = _tty_rx_notify; + + rt_device_init(&serial->parent); + + rt_device_control(&serial->parent, RT_DEVICE_CTRL_NOTIFY_SET, ¬ify); } rt_inline void _restore_serial(struct rt_serial_device *serial, lwp_tty_t tp, @@ -310,6 +345,7 @@ rt_err_t rt_hw_serial_register_tty(struct rt_serial_device *serial) { _serial_tty_set_speed(tty); rc = lwp_tty_register(tty, dev_name); + rt_work_init(&softc->work, _tty_rx_worker, tty); if (rc != RT_EOK) { diff --git a/rt-thread/components/drivers/smp_call/SConscript b/rt-thread/components/drivers/smp_call/SConscript deleted file mode 100644 index 2f4fe0b..0000000 --- a/rt-thread/components/drivers/smp_call/SConscript +++ /dev/null @@ -1,10 +0,0 @@ -from building import * - -cwd = GetCurrentDir() -src = [] -if GetDepend("RT_USING_SMP"): - src += Glob('*.c') -CPPPATH = [cwd] -group = DefineGroup('smp', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/smp_call/smp_call.c b/rt-thread/components/drivers/smp_call/smp_call.c deleted file mode 100644 index 6c65e82..0000000 --- a/rt-thread/components/drivers/smp_call/smp_call.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024/9/12 zhujiale the first version - * 2024/10/24 Shell added non-blocking IPI calling method; - * fixup data racing - */ - -#include "smp_call.h" - -#define DBG_TAG "SMP" -#define DBG_LVL DBG_INFO -#include - -static struct smp_data -{ - /* call request data to each cores */ - struct rt_smp_call_req call_req_cores[RT_CPUS_NR]; - - /* call queue of this core */ - rt_ll_slist_t call_queue; -} _smp_data_cores[RT_CPUS_NR]; - -#define _CALL_REQ_USAGE_FREED 0 -#define _CALL_REQ_USAGE_BUSY 1 -static void _call_req_take(struct rt_smp_call_req *req) -{ - rt_base_t exp; - do - { - exp = _CALL_REQ_USAGE_FREED; - } - while (!rt_atomic_compare_exchange_strong(&req->event.typed.usage_tracer, &exp, _CALL_REQ_USAGE_BUSY)); -} - -static void _call_req_release(struct rt_smp_call_req *req) -{ - rt_atomic_store(&req->event.typed.usage_tracer, _CALL_REQ_USAGE_FREED); -} - -void rt_smp_request_wait_freed(struct rt_smp_call_req *req) -{ - rt_base_t usage_tracer; - - RT_DEBUG_IN_THREAD_CONTEXT; - - usage_tracer = rt_atomic_load(&req->event.typed.usage_tracer); - while (usage_tracer != _CALL_REQ_USAGE_FREED) - { - rt_thread_yield(); - usage_tracer = rt_atomic_load(&req->event.typed.usage_tracer); - } -} - -static void _mask_out_cpu(struct rt_smp_event *event, int oncpu) -{ - rt_base_t new_mask, old_mask; - rt_atomic_t *maskp = event->typed.calling_cpu_mask; - do - { - old_mask = rt_atomic_load(maskp); - new_mask = old_mask & ~(1ul << oncpu); - } while (!rt_atomic_compare_exchange_strong(maskp, &old_mask, new_mask)); -} - -static void _do_glob_request(struct rt_smp_call_req *req_global, - struct rt_smp_call_req *req_local) -{ - struct rt_smp_event *event; - - /* release the global request data */ - rt_memcpy(req_local, req_global, sizeof(struct rt_smp_call_req)); - rt_hw_spin_unlock(&req_global->freed_lock); - - event = &req_local->event; - RT_ASSERT(!!event->func); - event->func(event->data); - - return ; -} - -static void _do_request(struct rt_smp_call_req *req) -{ - struct rt_smp_event *event; - - event = &req->event; - RT_ASSERT(!!event->func); - event->func(event->data); - - _call_req_release(req); - return ; -} - -static rt_err_t _smp_call_handler(struct rt_smp_call_req *req, int oncpu) -{ - switch (req->event.event_id) - { - case SMP_CALL_EVENT_GLOB_SYNC: - { - struct rt_smp_call_req req_local; - _do_glob_request(req, &req_local); - _mask_out_cpu(&req_local.event, oncpu); - break; - } - case SMP_CALL_EVENT_GLOB_ASYNC: - { - struct rt_smp_call_req req_local; - _do_glob_request(req, &req_local); - break; - } - case SMP_CALL_EVENT_REQUEST: - { - _do_request(req); - break; - } - default: - LOG_E("error event id\n"); - return -RT_ERROR; - } - return RT_EOK; -} - -void rt_smp_call_ipi_handler(int vector, void *param) -{ - int oncpu = rt_hw_cpu_id(); - struct rt_smp_call_req *request; - - RT_ASSERT(rt_interrupt_get_nest()); - - while (1) - { - rt_ll_slist_t *node = rt_ll_slist_dequeue(&_smp_data_cores[oncpu].call_queue); - if (node) - { - request = rt_list_entry(node, struct rt_smp_call_req, slist_node); - - _smp_call_handler(request, oncpu); - } - else - { - break; - } - } -} - -static void _smp_call_remote_request(int callcpu, rt_smp_call_cb_t func, - void *data, rt_uint8_t flags, - struct rt_smp_call_req *call_req) -{ - rt_base_t cpu_mask = 1ul << callcpu; - - _call_req_take(call_req); - - rt_ll_slist_enqueue(&_smp_data_cores[callcpu].call_queue, &call_req->slist_node); - - rt_hw_ipi_send(RT_SMP_CALL_IPI, cpu_mask); -} - -/** - * @brief SMP call request with user provided @call_req. Compare to - * rt_smp_call_func* family, you can call it in ISR or IRQ-masked - * environment. - * - * @param callcpu the logical core id of the target - * @param flags control flags of your request - * @param call_req the pre-initialized request data - * @return rt_err_t RT_EOK on succeed, otherwise the errno to failure - */ -rt_err_t rt_smp_call_request(int callcpu, rt_uint8_t flags, struct rt_smp_call_req *call_req) -{ - rt_ubase_t clvl; - int oncpu; - - if (rt_atomic_load(&call_req->event.typed.usage_tracer) == - _CALL_REQ_USAGE_BUSY) - { - return -RT_EBUSY; - } - - if (flags & SMP_CALL_WAIT_ALL) - { - return -RT_EINVAL; - } - - clvl = rt_enter_critical(); - oncpu = rt_hw_cpu_id(); - - if (oncpu == callcpu && !(flags & SMP_CALL_NO_LOCAL)) - { - rt_ubase_t level; - - /* handle IPI on irq-masked environment */ - level = rt_hw_local_irq_disable(); - call_req->event.func(call_req->event.data); - rt_hw_local_irq_enable(level); - } - else if (callcpu < RT_CPUS_NR) - { - _smp_call_remote_request(callcpu, call_req->event.func, call_req->event.data, flags, call_req); - } - - rt_exit_critical_safe(clvl); - - return RT_EOK; -} - -void rt_smp_call_req_init(struct rt_smp_call_req *call_req, - rt_smp_call_cb_t func, void *data) -{ - call_req->event.typed.usage_tracer = 0; - call_req->event.data = data; - call_req->event.func = func; - call_req->event.event_id = SMP_CALL_EVENT_REQUEST; -} - -static void _smp_call_func_cond(int oncpu, rt_ubase_t cpu_mask, - rt_smp_call_cb_t func, void *data, - rt_uint8_t flags, rt_smp_cond_t cond) -{ - rt_ubase_t tmp_mask; - rt_bool_t sync_call = RT_FALSE; - rt_ubase_t oncpu_mask = 1 << oncpu; - rt_atomic_t calling_cpu_mask, *maskp; - int tmp_id = 0, rcpu_cnt = 0, event_id, call_local; - - if (!(flags & SMP_CALL_NO_LOCAL) && (oncpu_mask & cpu_mask)) - { - call_local = RT_TRUE; - cpu_mask = cpu_mask & (~oncpu_mask); - } - else - { - call_local = RT_FALSE; - } - - if (cpu_mask) - { - tmp_mask = cpu_mask; - - if (flags & SMP_CALL_WAIT_ALL) - { - sync_call = RT_TRUE; - maskp = &calling_cpu_mask; - event_id = SMP_CALL_EVENT_GLOB_SYNC; - rt_atomic_store(maskp, cpu_mask); - } - else - { - event_id = SMP_CALL_EVENT_GLOB_ASYNC; - maskp = RT_NULL; - } - - while (tmp_mask) - { - struct rt_smp_call_req *call_req; - struct rt_smp_event *event; - int lz_bit = __rt_ffsl(tmp_mask); - - tmp_id = lz_bit - 1; - tmp_mask &= ~(1ul << tmp_id); - - if (cond && !cond(tmp_id, data)) - { - cpu_mask &= ~(1ul << tmp_id); - continue; - } - - /* need to wait one more */ - rcpu_cnt++; - - call_req = &_smp_data_cores[oncpu].call_req_cores[tmp_id]; - - /* very careful here, spinning wait on previous occupation */ - rt_hw_spin_lock(&call_req->freed_lock); - - event = &call_req->event; - event->event_id = event_id; - event->func = func; - event->data = data; - event->typed.calling_cpu_mask = maskp; - - rt_ll_slist_enqueue(&_smp_data_cores[tmp_id].call_queue, &call_req->slist_node); - } - - if (cpu_mask) - { - RT_ASSERT(rcpu_cnt); - - rt_hw_ipi_send(RT_SMP_CALL_IPI, cpu_mask); - } - } - - if (call_local && (!cond || cond(tmp_id, data))) - { - rt_ubase_t level; - - /* callback on local with sims ISR */ - level = rt_hw_local_irq_disable(); - func(data); - rt_hw_local_irq_enable(level); - } - - if (sync_call && rcpu_cnt) - { - while (rt_atomic_load(maskp) & cpu_mask) - ; - } -} - -/** - * @brief call function on specified CPU , - * - * @param cpu_mask cpu mask for call - * @param func the function pointer - * @param data the data pointer - * @param flag call flag if you set SMP_CALL_WAIT_ALL - * then it will wait all cpu call finish and return - * else it will call function on specified CPU and return immediately - * @param cond the condition function pointer,if you set it then it will call function only when cond return true - */ -void rt_smp_call_func_cond(rt_ubase_t cpu_mask, rt_smp_call_cb_t func, void *data, rt_uint8_t flag, rt_smp_cond_t cond) -{ - int oncpu; - rt_ubase_t clvl; - - RT_ASSERT(!rt_hw_interrupt_is_disabled()); - - clvl = rt_enter_critical(); - oncpu = rt_hw_cpu_id(); - - if (cpu_mask <= RT_ALL_CPU) - { - _smp_call_func_cond(oncpu, cpu_mask, func, data, flag, cond); - } - - rt_exit_critical_safe(clvl); -} - -void rt_smp_call_each_cpu(rt_smp_call_cb_t func, void *data, rt_uint8_t flag) -{ - rt_smp_call_func_cond(RT_ALL_CPU, func, data, flag, RT_NULL); -} - -void rt_smp_call_each_cpu_cond(rt_smp_call_cb_t func, void *data, rt_uint8_t flag, rt_smp_cond_t cond_func) -{ - rt_smp_call_func_cond(RT_ALL_CPU, func, data, flag, cond_func); -} - -void rt_smp_call_cpu_mask(rt_ubase_t cpu_mask, rt_smp_call_cb_t func, void *data, rt_uint8_t flag) -{ - rt_smp_call_func_cond(cpu_mask, func, data, flag, RT_NULL); -} - -void rt_smp_call_cpu_mask_cond(rt_ubase_t cpu_mask, rt_smp_call_cb_t func, void *data, rt_uint8_t flag, rt_smp_cond_t cond_func) -{ - rt_smp_call_func_cond(cpu_mask, func, data, flag, cond_func); -} - -void rt_smp_call_init(void) -{ - rt_memset(&_smp_data_cores, 0, sizeof(_smp_data_cores)); - - for (int i = 0; i < RT_CPUS_NR; i++) - { - for (int j = 0; j < RT_CPUS_NR; j++) - { - rt_hw_spin_lock_init(&_smp_data_cores[i].call_req_cores[j].freed_lock); - } - } -} diff --git a/rt-thread/components/drivers/smp_call/smp_call.h b/rt-thread/components/drivers/smp_call/smp_call.h deleted file mode 100644 index 0ff9dd3..0000000 --- a/rt-thread/components/drivers/smp_call/smp_call.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024/9/12 zhujiale the first version - * 2024/10/24 Shell added non-blocking IPI calling method - */ - -#ifndef __SMP_IPI_H__ -#define __SMP_IPI_H__ -#include - -#ifdef RT_USING_SMP - -/* callback of smp call */ -typedef void (*rt_smp_call_cb_t)(void *data); -typedef rt_bool_t (*rt_smp_cond_t)(int cpu, void *info); - -#define SMP_CALL_EVENT_GLOB_ASYNC 0x1 -#define SMP_CALL_EVENT_GLOB_SYNC 0x2 -#define SMP_CALL_EVENT_REQUEST 0x4 - -#define SMP_CALL_WAIT_ALL (1ul << 0) -#define SMP_CALL_NO_LOCAL (1ul << 1) -#define SMP_CALL_SIGNAL (1ul << 2) - -#define RT_ALL_CPU ((1 << RT_CPUS_NR) - 1) -struct rt_smp_event -{ - int event_id; - void *data; - rt_smp_call_cb_t func; - - union - { - rt_atomic_t *calling_cpu_mask; - rt_atomic_t usage_tracer; - } typed; -}; - -struct rt_smp_call_req -{ - /* handle the busy status synchronization */ - rt_hw_spinlock_t freed_lock; - struct rt_smp_event event; - rt_ll_slist_t slist_node; -}; - -void rt_smp_call_ipi_handler(int vector, void *param); -void rt_smp_call_each_cpu(rt_smp_call_cb_t func, void *data, rt_uint8_t flags); -void rt_smp_call_each_cpu_cond(rt_smp_call_cb_t func, void *data, rt_uint8_t flag, rt_smp_cond_t cond_func); -void rt_smp_call_cpu_mask(rt_ubase_t cpu_mask, rt_smp_call_cb_t func, void *data, rt_uint8_t flags); -void rt_smp_call_cpu_mask_cond(rt_ubase_t cpu_mask, rt_smp_call_cb_t func, void *data, rt_uint8_t flag, rt_smp_cond_t cond_func); -void rt_smp_call_init(void); - -rt_err_t rt_smp_call_request(int callcpu, rt_uint8_t flags, struct rt_smp_call_req *call_req); -void rt_smp_call_req_init(struct rt_smp_call_req *call_req, - rt_smp_call_cb_t func, void *data); -void rt_smp_request_wait_freed(struct rt_smp_call_req *req); - -#define rt_smp_for_each_cpu(_iter) for (_iter = 0; (_iter) < RT_CPUS_NR; (_iter)++) -rt_inline size_t rt_smp_get_next_remote(size_t iter, size_t cpuid) -{ - iter++; - return iter == cpuid ? iter + 1 : iter; -} -#define rt_smp_for_each_remote_cpu(_iter, _cpuid) for (_iter = rt_smp_get_next_remote(-1, _cpuid); (_iter) < RT_CPUS_NR; _iter=rt_smp_get_next_remote(_iter, _cpuid)) - -#endif // RT_USING_SMP - -#endif // __SMP_IPI_H__ diff --git a/rt-thread/components/drivers/spi/SConscript b/rt-thread/components/drivers/spi/SConscript index 6897dab..cea447f 100644 --- a/rt-thread/components/drivers/spi/SConscript +++ b/rt-thread/components/drivers/spi/SConscript @@ -3,29 +3,29 @@ from gcc import * import rtconfig cwd = GetCurrentDir() -src = ['dev_spi_core.c', 'dev_spi.c'] +src = ['spi_core.c', 'spi_dev.c'] CPPPATH = [cwd, cwd + '/../include'] LOCAL_CFLAGS = '' if GetDepend('RT_USING_SPI_BITOPS'): - src += ['dev_spi_bit_ops.c'] + src += ['spi-bit-ops.c'] if GetDepend('RT_USING_QSPI'): - src += ['dev_qspi_core.c'] + src += ['qspi_core.c'] src_device = [] if GetDepend('RT_USING_SPI_WIFI'): - src_device += ['dev_spi_wifi_rw009.c'] + src_device += ['spi_wifi_rw009.c'] if GetDepend('RT_USING_ENC28J60'): src_device += ['enc28j60.c'] if GetDepend('RT_USING_SPI_MSD'): - src_device += ['dev_spi_msd.c'] + src_device += ['spi_msd.c'] if GetDepend('RT_USING_SFUD'): - src_device += ['dev_spi_flash_sfud.c', 'sfud/src/sfud.c'] + src_device += ['spi_flash_sfud.c', 'sfud/src/sfud.c'] CPPPATH += [cwd + '/sfud/inc'] if GetDepend('RT_SFUD_USING_SFDP'): src_device += ['sfud/src/sfud_sfdp.c'] @@ -35,9 +35,6 @@ if GetDepend('RT_USING_SFUD'): elif rtconfig.PLATFORM in ['armcc']: LOCAL_CFLAGS += ' --c99' -if GetDepend('RT_USING_DM'): - src += ['dev_spi_dm.c', 'dev_spi_bus.c'] - src += src_device group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SPI'], CPPPATH = CPPPATH, LOCAL_CFLAGS = LOCAL_CFLAGS) diff --git a/rt-thread/components/drivers/spi/dev_qspi_core.c b/rt-thread/components/drivers/spi/dev_qspi_core.c deleted file mode 100644 index 9dd2c5f..0000000 --- a/rt-thread/components/drivers/spi/dev_qspi_core.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-11-16 zylx first version. - */ - -#include "drivers/dev_spi.h" - -rt_err_t rt_qspi_configure(struct rt_qspi_device *device, struct rt_qspi_configuration *cfg) -{ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(cfg != RT_NULL); - - /* reset the CS pin */ - if (device->parent.cs_pin != PIN_NONE) - { - rt_err_t result = rt_mutex_take(&(device->parent.bus->lock), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - if (cfg->parent.mode & RT_SPI_CS_HIGH) - { - rt_pin_write(device->parent.cs_pin, PIN_LOW); - } - else - { - rt_pin_write(device->parent.cs_pin, PIN_HIGH); - } - rt_mutex_release(&(device->parent.bus->lock)); - } - else - { - return result; - } - } - - /* If the configurations are the same, we don't need to set again. */ - if (device->config.medium_size == cfg->medium_size && - device->config.ddr_mode == cfg->ddr_mode && - device->config.qspi_dl_width == cfg->qspi_dl_width && - device->config.parent.data_width == cfg->parent.data_width && - device->config.parent.mode == (cfg->parent.mode & RT_SPI_MODE_MASK) && - device->config.parent.max_hz == cfg->parent.max_hz) - { - return RT_EOK; - } - - /* copy configuration items */ - device->config.parent.mode = cfg->parent.mode; - device->config.parent.max_hz = cfg->parent.max_hz; - device->config.parent.data_width = cfg->parent.data_width; - device->config.parent.reserved = cfg->parent.reserved; - device->config.medium_size = cfg->medium_size; - device->config.ddr_mode = cfg->ddr_mode; - device->config.qspi_dl_width = cfg->qspi_dl_width; - - return rt_spi_bus_configure(&device->parent); -} - -rt_err_t rt_qspi_bus_register(struct rt_spi_bus *bus, const char *name, const struct rt_spi_ops *ops) -{ - rt_err_t result = RT_EOK; - - result = rt_spi_bus_register(bus, name, ops); - if(result == RT_EOK) - { - /* set SPI bus to qspi modes */ - bus->mode = RT_SPI_BUS_MODE_QSPI; - } - - return result; -} - -rt_size_t rt_qspi_transfer_message(struct rt_qspi_device *device, struct rt_qspi_message *message) -{ - rt_err_t result; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(message != RT_NULL); - - result = rt_mutex_take(&(device->parent.bus->lock), RT_WAITING_FOREVER); - if (result != RT_EOK) - { - rt_set_errno(-RT_EBUSY); - - return 0; - } - - /* reset errno */ - rt_set_errno(RT_EOK); - - /* configure SPI bus */ - if (device->parent.bus->owner != &device->parent) - { - /* not the same owner as current, re-configure SPI bus */ - result = device->parent.bus->ops->configure(&device->parent, &device->parent.config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - device->parent.bus->owner = &device->parent; - } - else - { - /* configure SPI bus failed */ - rt_set_errno(-RT_EIO); - goto __exit; - } - } - - /* transmit each SPI message */ - - result = device->parent.bus->ops->xfer(&device->parent, &message->parent); - if (result == 0) - { - rt_set_errno(-RT_EIO); - } - -__exit: - /* release bus lock */ - rt_mutex_release(&(device->parent.bus->lock)); - - return result; -} - -rt_err_t rt_qspi_send_then_recv(struct rt_qspi_device *device, const void *send_buf, rt_size_t send_length, void *recv_buf, rt_size_t recv_length) -{ - RT_ASSERT(send_buf); - RT_ASSERT(recv_buf); - RT_ASSERT(send_length != 0); - - struct rt_qspi_message message; - unsigned char *ptr = (unsigned char *)send_buf; - rt_size_t count = 0; - rt_err_t result = 0; - - message.instruction.content = ptr[0]; - message.instruction.qspi_lines = 1; - count++; - - /* get address */ - if (send_length > 1) - { - if (device->config.medium_size > 0x1000000 && send_length >= 5) - { - /* medium size greater than 16Mb, address size is 4 Byte */ - message.address.content = (ptr[1] << 24) | (ptr[2] << 16) | (ptr[3] << 8) | (ptr[4]); - message.address.size = 32; - count += 4; - } - else if (send_length >= 4) - { - /* address size is 3 Byte */ - message.address.content = (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]); - message.address.size = 24; - count += 3; - } - else - { - return -RT_ERROR; - } - message.address.qspi_lines = 1; - } - else - { - /* no address stage */ - message.address.content = 0 ; - message.address.qspi_lines = 0; - message.address.size = 0; - } - - message.alternate_bytes.content = 0; - message.alternate_bytes.size = 0; - message.alternate_bytes.qspi_lines = 0; - - /* set dummy cycles */ - if (count != send_length) - { - message.dummy_cycles = (send_length - count) * 8; - - } - else - { - message.dummy_cycles = 0; - } - - /* set recv buf and recv size */ - message.parent.recv_buf = recv_buf; - message.parent.send_buf = RT_NULL; - message.parent.length = recv_length; - message.parent.cs_take = 1; - message.parent.cs_release = 1; - - message.qspi_data_lines = 1; - - result = rt_qspi_transfer_message(device, &message); - if (result == 0) - { - result = -RT_EIO; - } - else - { - result = recv_length; - } - - return result; -} - -rt_err_t rt_qspi_send(struct rt_qspi_device *device, const void *send_buf, rt_size_t length) -{ - RT_ASSERT(send_buf); - RT_ASSERT(length != 0); - - struct rt_qspi_message message; - unsigned char *ptr = (unsigned char *)send_buf; - rt_size_t count = 0; - rt_err_t result = 0; - - message.instruction.content = ptr[0]; - message.instruction.qspi_lines = 1; - count++; - - /* get address */ - if (length > 1) - { - if (device->config.medium_size > 0x1000000 && length >= 5) - { - /* medium size greater than 16Mb, address size is 4 Byte */ - message.address.content = (ptr[1] << 24) | (ptr[2] << 16) | (ptr[3] << 8) | (ptr[4]); - message.address.size = 32; - message.address.qspi_lines = 1; - count += 4; - } - else if (length >= 4) - { - /* address size is 3 Byte */ - message.address.content = (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]); - message.address.size = 24; - message.address.qspi_lines = 1; - count += 3; - } - else - { - return -RT_ERROR; - } - - } - else - { - /* no address stage */ - message.address.content = 0 ; - message.address.qspi_lines = 0; - message.address.size = 0; - } - - message.alternate_bytes.content = 0; - message.alternate_bytes.size = 0; - message.alternate_bytes.qspi_lines = 0; - - message.dummy_cycles = 0; - - /* determine if there is data to send */ - if (length - count > 0) - { - message.qspi_data_lines = 1; - } - else - { - message.qspi_data_lines = 0; - } - - /* set send buf and send size */ - message.parent.send_buf = ptr + count; - message.parent.recv_buf = RT_NULL; - message.parent.length = length - count; - message.parent.cs_take = 1; - message.parent.cs_release = 1; - - result = rt_qspi_transfer_message(device, &message); - if (result == 0) - { - result = -RT_EIO; - } - else - { - result = length; - } - - return result; -} diff --git a/rt-thread/components/drivers/spi/dev_spi.c b/rt-thread/components/drivers/spi/dev_spi.c deleted file mode 100644 index 3f55fd0..0000000 --- a/rt-thread/components/drivers/spi/dev_spi.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include -#include "drivers/dev_spi.h" - -#define DBG_TAG "spi.dev" -#define DBG_LVL DBG_INFO -#include - -#ifdef RT_USING_DM -#include "dev_spi_dm.h" -#endif - -/* SPI bus device interface, compatible with RT-Thread 0.3.x/1.0.x */ -static rt_ssize_t _spi_bus_device_read(rt_device_t dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - struct rt_spi_bus *bus; - - bus = (struct rt_spi_bus *)dev; - RT_ASSERT(bus != RT_NULL); - RT_ASSERT(bus->owner != RT_NULL); - - return rt_spi_transfer(bus->owner, RT_NULL, buffer, size); -} - -static rt_ssize_t _spi_bus_device_write(rt_device_t dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct rt_spi_bus *bus; - - bus = (struct rt_spi_bus *)dev; - RT_ASSERT(bus != RT_NULL); - RT_ASSERT(bus->owner != RT_NULL); - - return rt_spi_transfer(bus->owner, buffer, RT_NULL, size); -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops spi_bus_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - _spi_bus_device_read, - _spi_bus_device_write, - RT_NULL -}; -#endif - -rt_err_t rt_spi_bus_device_init(struct rt_spi_bus *bus, const char *name) -{ - struct rt_device *device; - RT_ASSERT(bus != RT_NULL); - - device = &bus->parent; - - /* set device type */ - device->type = RT_Device_Class_SPIBUS; - /* initialize device interface */ -#ifdef RT_USING_DEVICE_OPS - device->ops = &spi_bus_ops; -#else - device->init = RT_NULL; - device->open = RT_NULL; - device->close = RT_NULL; - device->read = _spi_bus_device_read; - device->write = _spi_bus_device_write; - device->control = RT_NULL; -#endif - - /* register to device manager */ - return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); -} - -/* SPI Dev device interface, compatible with RT-Thread 0.3.x/1.0.x */ -static rt_ssize_t _spidev_device_read(rt_device_t dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - struct rt_spi_device *device; - - device = (struct rt_spi_device *)dev; - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - return rt_spi_transfer(device, RT_NULL, buffer, size); -} - -static rt_ssize_t _spidev_device_write(rt_device_t dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct rt_spi_device *device; - - device = (struct rt_spi_device *)dev; - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - return rt_spi_transfer(device, buffer, RT_NULL, size); -} - -static rt_err_t _spidev_device_control(rt_device_t dev, - int cmd, - void *args) -{ - switch (cmd) - { - case 0: /* set device */ - break; - case 1: - break; - } - - return RT_EOK; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops spi_device_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - _spidev_device_read, - _spidev_device_write, - _spidev_device_control -}; -#endif - -rt_err_t rt_spidev_device_init(struct rt_spi_device *dev, const char *name) -{ - struct rt_device *device; - RT_ASSERT(dev != RT_NULL); - - device = &(dev->parent); - - /* set device type */ - device->type = RT_Device_Class_SPIDevice; -#ifdef RT_USING_DEVICE_OPS - device->ops = &spi_device_ops; -#else - device->init = RT_NULL; - device->open = RT_NULL; - device->close = RT_NULL; - device->read = _spidev_device_read; - device->write = _spidev_device_write; - device->control = _spidev_device_control; -#endif - - /* register to device manager */ - return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); -} - -#ifdef RT_USING_DM -static rt_err_t spidev_probe(struct rt_spi_device *spi_dev) -{ - const char *bus_name; - struct rt_device *dev = &spi_dev->parent; - - if (spi_dev->parent.ofw_node) - { - if (rt_dm_dev_prop_index_of_string(dev, "compatible", "spidev") >= 0) - { - LOG_E("spidev is not supported in OFW"); - - return -RT_EINVAL; - } - } - - bus_name = rt_dm_dev_get_name(&spi_dev->bus->parent); - rt_dm_dev_set_name(dev, "%s_%d", bus_name, spi_dev->chip_select); - - return RT_EOK; -} - -static const struct rt_spi_device_id spidev_ids[] = -{ - { .name = "dh2228fv" }, - { .name = "ltc2488" }, - { .name = "sx1301" }, - { .name = "bk4" }, - { .name = "dhcom-board" }, - { .name = "m53cpld" }, - { .name = "spi-petra" }, - { .name = "spi-authenta" }, - { .name = "em3581" }, - { .name = "si3210" }, - { /* sentinel */ }, -}; - -static const struct rt_ofw_node_id spidev_ofw_ids[] = -{ - { .compatible = "cisco,spi-petra" }, - { .compatible = "dh,dhcom-board" }, - { .compatible = "lineartechnology,ltc2488" }, - { .compatible = "lwn,bk4" }, - { .compatible = "menlo,m53cpld" }, - { .compatible = "micron,spi-authenta" }, - { .compatible = "rohm,dh2228fv" }, - { .compatible = "semtech,sx1301" }, - { .compatible = "silabs,em3581" }, - { .compatible = "silabs,si3210" }, - { .compatible = "rockchip,spidev" }, - { /* sentinel */ }, -}; - -static struct rt_spi_driver spidev_driver = -{ - .ids = spidev_ids, - .ofw_ids = spidev_ofw_ids, - - .probe = spidev_probe, -}; -RT_SPI_DRIVER_EXPORT(spidev_driver); -#endif /* RT_USING_DM */ diff --git a/rt-thread/components/drivers/spi/dev_spi_bit_ops.c b/rt-thread/components/drivers/spi/dev_spi_bit_ops.c deleted file mode 100644 index d2a26a7..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_bit_ops.c +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-10-11 kyle first version - */ - -#include -#include - -#define DBG_TAG "SPI" -#ifdef RT_SPI_BITOPS_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_ERROR -#endif -#include - -#define TOG_SCLK(ops) ops->tog_sclk(ops->data) -#define SET_SCLK(ops, val) ops->set_sclk(ops->data, val) -#define SET_MOSI(ops, val) ops->set_mosi(ops->data, val) -#define SET_MISO(ops, val) ops->set_miso(ops->data, val) -#define GET_SCLK(ops) ops->get_sclk(ops->data) -#define GET_MOSI(ops) ops->get_mosi(ops->data) -#define GET_MISO(ops) ops->get_miso(ops->data) -#define DIR_MOSI(ops, val) ops->dir_mosi(ops->data, val) -#define DIR_MISO(ops, val) ops->dir_miso(ops->data, val) - -rt_inline void spi_delay(struct rt_spi_bit_ops *ops) -{ - ops->udelay((ops->delay_us + 1) >> 1); -} - -rt_inline void spi_delay2(struct rt_spi_bit_ops *ops) -{ - ops->udelay(ops->delay_us); -} - -#define SCLK_H(ops) SET_SCLK(ops, 1) -#define SCLK_L(ops) SET_SCLK(ops, 0) -#define MOSI_H(ops) SET_MOSI(ops, 1) -#define MOSI_L(ops) SET_MOSI(ops, 0) -#define MOSI_IN(ops) DIR_MOSI(ops, 1) -#define MOSI_OUT(ops) DIR_MOSI(ops, 0) -#define MISO_IN(ops) DIR_MISO(ops, 1) -#define MISO_OUT(ops) DIR_MISO(ops, 0) - -rt_inline rt_ssize_t spi_xfer_4line_data8(struct rt_spi_bit_ops *ops, - struct rt_spi_configuration *config, - const void *send_buf, - void *recv_buf, - rt_size_t length) -{ - int i = 0; - - RT_ASSERT(ops != RT_NULL); - RT_ASSERT(length != 0); - - { - const rt_uint8_t *send_ptr = send_buf; - rt_uint8_t *recv_ptr = recv_buf; - rt_uint32_t size = length; - - while (size--) - { - rt_uint8_t tx_data = 0xFF; - rt_uint8_t rx_data = 0xFF; - rt_uint8_t bit = 0; - - if (send_buf != RT_NULL) - { - tx_data = *send_ptr++; - } - - for (i = 0; i < 8; i++) - { - if (config->mode & RT_SPI_MSB) { bit = tx_data & (0x1 << (7 - i)); } - else { bit = tx_data & (0x1 << i); } - - if (bit) MOSI_H(ops); - else MOSI_L(ops); - - spi_delay2(ops); - - TOG_SCLK(ops); - - if (config->mode & RT_SPI_MSB) { rx_data <<= 1; bit = 0x01; } - else { rx_data >>= 1; bit = 0x80; } - - if (GET_MISO(ops)) { rx_data |= bit; } - else { rx_data &= ~bit; } - - spi_delay2(ops); - - if (!(config->mode & RT_SPI_CPHA) || (size != 0) || (i < 7)) - { - TOG_SCLK(ops); - } - } - - if (recv_buf != RT_NULL) - { - *recv_ptr++ = rx_data; - } - } - } - - return length; -} - -rt_inline rt_ssize_t spi_xfer_4line_data16(struct rt_spi_bit_ops *ops, - struct rt_spi_configuration *config, - const void *send_buf, - void *recv_buf, - rt_size_t length) -{ - int i = 0; - - RT_ASSERT(ops != RT_NULL); - RT_ASSERT(length != 0); - - { - const rt_uint16_t *send_ptr = send_buf; - rt_uint16_t *recv_ptr = recv_buf; - rt_uint32_t size = length; - - while (size--) - { - rt_uint16_t tx_data = 0xFFFF; - rt_uint16_t rx_data = 0xFFFF; - rt_uint16_t bit = 0; - - if (send_buf != RT_NULL) - { - tx_data = *send_ptr++; - } - - for (i = 0; i < 16; i++) - { - if (config->mode & RT_SPI_MSB) { bit = tx_data & (0x1 << (15 - i)); } - else { bit = tx_data & (0x1 << i); } - - if (bit) MOSI_H(ops); - else MOSI_L(ops); - - spi_delay2(ops); - - TOG_SCLK(ops); - - if (config->mode & RT_SPI_MSB) { rx_data <<= 1; bit = 0x0001; } - else { rx_data >>= 1; bit = 0x8000; } - - if (GET_MISO(ops)) { rx_data |= bit; } - else { rx_data &= ~bit; } - - spi_delay2(ops); - - if (!(config->mode & RT_SPI_CPHA) || (size != 0) || (i < 15)) - { - TOG_SCLK(ops); - } - } - - if (recv_buf != RT_NULL) - { - *recv_ptr++ = rx_data; - } - } - } - - return length; -} - -rt_inline rt_ssize_t spi_xfer_3line_data8(struct rt_spi_bit_ops *ops, - struct rt_spi_configuration *config, - const void *send_buf, - void *recv_buf, - rt_size_t length) -{ - int i = 0; - - RT_ASSERT(ops != RT_NULL); - RT_ASSERT(length != 0); - - { - const rt_uint8_t *send_ptr = send_buf; - rt_uint8_t *recv_ptr = recv_buf; - rt_uint32_t size = length; - rt_uint8_t send_flg = 0; - - if ((send_buf != RT_NULL) || (recv_buf == RT_NULL)) - { - MOSI_OUT(ops); - send_flg = 1; - } - else - { - MOSI_IN(ops); - } - - while (size--) - { - rt_uint8_t tx_data = 0xFF; - rt_uint8_t rx_data = 0xFF; - rt_uint8_t bit = 0; - - if (send_buf != RT_NULL) - { - tx_data = *send_ptr++; - } - - if (send_flg) - { - for (i = 0; i < 8; i++) - { - if (config->mode & RT_SPI_MSB) { bit = tx_data & (0x1 << (7 - i)); } - else { bit = tx_data & (0x1 << i); } - - if (bit) MOSI_H(ops); - else MOSI_L(ops); - - spi_delay2(ops); - - TOG_SCLK(ops); - - spi_delay2(ops); - - if (!(config->mode & RT_SPI_CPHA) || (size != 0) || (i < 7)) - { - TOG_SCLK(ops); - } - } - - rx_data = tx_data; - } - else - { - for (i = 0; i < 8; i++) - { - spi_delay2(ops); - - TOG_SCLK(ops); - - if (config->mode & RT_SPI_MSB) { rx_data <<= 1; bit = 0x01; } - else { rx_data >>= 1; bit = 0x80; } - - if (GET_MOSI(ops)) { rx_data |= bit; } - else { rx_data &= ~bit; } - - spi_delay2(ops); - - if (!(config->mode & RT_SPI_CPHA) || (size != 0) || (i < 7)) - { - TOG_SCLK(ops); - } - } - - } - - if (recv_buf != RT_NULL) - { - *recv_ptr++ = rx_data; - } - } - - if (!send_flg) - { - MOSI_OUT(ops); - } - } - - return length; -} - -rt_inline rt_ssize_t spi_xfer_3line_data16(struct rt_spi_bit_ops *ops, - struct rt_spi_configuration *config, - const void *send_buf, - void *recv_buf, - rt_size_t length) -{ - int i = 0; - - RT_ASSERT(ops != RT_NULL); - RT_ASSERT(length != 0); - - { - const rt_uint16_t *send_ptr = send_buf; - rt_uint16_t *recv_ptr = recv_buf; - rt_uint32_t size = length; - rt_uint8_t send_flg = 0; - - if ((send_buf != RT_NULL) || (recv_buf == RT_NULL)) - { - MOSI_OUT(ops); - send_flg = 1; - } - else - { - MOSI_IN(ops); - } - - while (size--) - { - rt_uint16_t tx_data = 0xFFFF; - rt_uint16_t rx_data = 0xFFFF; - rt_uint16_t bit = 0; - - if (send_buf != RT_NULL) - { - tx_data = *send_ptr++; - } - - if (send_flg) - { - for (i = 0; i < 16; i++) - { - if (config->mode & RT_SPI_MSB) { bit = tx_data & (0x1 << (15 - i)); } - else { bit = tx_data & (0x1 << i); } - - if (bit) MOSI_H(ops); - else MOSI_L(ops); - - spi_delay2(ops); - - TOG_SCLK(ops); - - spi_delay2(ops); - - if (!(config->mode & RT_SPI_CPHA) || (size != 0) || (i < 15)) - { - TOG_SCLK(ops); - } - } - - rx_data = tx_data; - } - else - { - for (i = 0; i < 16; i++) - { - spi_delay2(ops); - - TOG_SCLK(ops); - - if (config->mode & RT_SPI_MSB) { rx_data <<= 1; bit = 0x0001; } - else { rx_data >>= 1; bit = 0x8000; } - - if (GET_MOSI(ops)) { rx_data |= bit; } - else { rx_data &= ~bit; } - - spi_delay2(ops); - - if (!(config->mode & RT_SPI_CPHA) || (size != 0) || (i < 15)) - { - TOG_SCLK(ops); - } - } - - } - - if (recv_buf != RT_NULL) - { - *recv_ptr++ = rx_data; - } - } - - if (!send_flg) - { - MOSI_OUT(ops); - } - } - - return length; -} - -rt_err_t spi_bit_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration) -{ - struct rt_spi_bit_obj *obj = rt_container_of(device->bus, struct rt_spi_bit_obj, bus); - struct rt_spi_bit_ops *ops = obj->ops; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(configuration != RT_NULL); - - if(ops->pin_init != RT_NULL) - { - ops->pin_init(); - } - - if (configuration->mode & RT_SPI_SLAVE) - { - return -RT_EIO; - } - - if (configuration->mode & RT_SPI_CPOL) - { - SCLK_H(ops); - } - else - { - SCLK_L(ops); - } - - if (configuration->max_hz < 200000) - { - ops->delay_us = 1; - } - else - { - ops->delay_us = 0; - } - - rt_memcpy(&obj->config, configuration, sizeof(struct rt_spi_configuration)); - - return RT_EOK; -} - -rt_ssize_t spi_bit_xfer(struct rt_spi_device *device, struct rt_spi_message *message) -{ - struct rt_spi_bit_obj *obj = rt_container_of(device->bus, struct rt_spi_bit_obj, bus); - struct rt_spi_bit_ops *ops = obj->ops; - struct rt_spi_configuration *config = &obj->config; - rt_base_t cs_pin = device->cs_pin; - rt_ssize_t length = 0; - - RT_ASSERT(device != NULL); - RT_ASSERT(message != NULL); - -#ifdef RT_SPI_BITOPS_DEBUG - if (!ops->tog_sclk || !ops->set_sclk || !ops->get_sclk) - { - LOG_E("SPI bus error, SCLK line not defined"); - } - if (!ops->set_mosi || !ops->get_mosi) - { - LOG_E("SPI bus error, MOSI line not defined"); - } - if (!ops->set_miso || !ops->get_miso) - { - LOG_E("SPI bus error, MISO line not defined"); - } -#endif - - /* take CS */ - if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (cs_pin != PIN_NONE)) - { - LOG_I("spi take cs\n"); - if (device->config.mode & RT_SPI_CS_HIGH) - { - rt_pin_write(cs_pin, PIN_HIGH); - } - else - { - rt_pin_write(cs_pin, PIN_LOW); - } - spi_delay(ops); - - /* spi phase */ - if (config->mode & RT_SPI_CPHA) - { - spi_delay(ops); - TOG_SCLK(ops); - } - } - - if (config->mode & RT_SPI_3WIRE) - { - if (config->data_width <= 8) - { - length = spi_xfer_3line_data8(ops, config, message->send_buf, message->recv_buf, message->length); - } - else if (config->data_width <= 16) - { - length = spi_xfer_3line_data16(ops, config, message->send_buf, message->recv_buf, message->length); - } - } - else - { - if (config->data_width <= 8) - { - length = spi_xfer_4line_data8(ops, config, message->send_buf, message->recv_buf, message->length); - } - else if (config->data_width <= 16) - { - length = spi_xfer_4line_data16(ops, config, message->send_buf, message->recv_buf, message->length); - } - } - - /* release CS */ - if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (cs_pin != PIN_NONE)) - { - spi_delay(ops); - if (device->config.mode & RT_SPI_CS_HIGH) - { - rt_pin_write(cs_pin, PIN_LOW); - } - else - { - rt_pin_write(cs_pin, PIN_HIGH); - } - LOG_I("spi release cs\n"); - } - - return length; -} - -static const struct rt_spi_ops spi_bit_bus_ops = -{ - .configure = spi_bit_configure, - .xfer = spi_bit_xfer, -}; - -rt_err_t rt_spi_bit_add_bus(struct rt_spi_bit_obj *obj, - const char *bus_name, - struct rt_spi_bit_ops *ops) -{ - obj->ops = ops; - obj->config.data_width = 8; - obj->config.max_hz = 1 * 1000 * 1000; - obj->config.mode = RT_SPI_MASTER | RT_SPI_MSB | RT_SPI_MODE_0; - - return rt_spi_bus_register(&obj->bus, bus_name, &spi_bit_bus_ops); -} diff --git a/rt-thread/components/drivers/spi/dev_spi_bit_ops.h b/rt-thread/components/drivers/spi/dev_spi_bit_ops.h deleted file mode 100644 index cf2335e..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_bit_ops.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-10-11 kyle first version - * 2022-6-14 solar Remove the const attribute of private data in ops - */ - -#ifndef __DEV_SPI_BIT_OPS_H__ -#define __DEV_SPI_BIT_OPS_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct rt_spi_bit_ops -{ - void *data; /* private data for lowlevel routines */ - void (*const pin_init)(void); - void (*const tog_sclk)(void *data); - void (*const set_sclk)(void *data, rt_int32_t state); - void (*const set_mosi)(void *data, rt_int32_t state); - void (*const set_miso)(void *data, rt_int32_t state); - rt_int32_t (*const get_sclk)(void *data); - rt_int32_t (*const get_mosi)(void *data); - rt_int32_t (*const get_miso)(void *data); - - void (*const dir_mosi)(void *data, rt_int32_t state); - void (*const dir_miso)(void *data, rt_int32_t state); - - void (*const udelay)(rt_uint32_t us); - rt_uint32_t delay_us; /* sclk, mosi and miso line delay */ -}; - -struct rt_spi_bit_obj -{ - struct rt_spi_bus bus; - struct rt_spi_bit_ops *ops; - struct rt_spi_configuration config; -}; - -rt_err_t rt_spi_bit_add_bus(struct rt_spi_bit_obj *obj, - const char *bus_name, - struct rt_spi_bit_ops *ops); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/components/drivers/spi/dev_spi_bus.c b/rt-thread/components/drivers/spi/dev_spi_bus.c deleted file mode 100644 index 34aa298..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_bus.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-12-06 GuEe-GUI first version - */ - -#include "dev_spi_dm.h" - -#define DBG_TAG "spi.bus" -#define DBG_LVL DBG_INFO -#include - -extern rt_err_t rt_spidev_device_init(struct rt_spi_device *dev, const char *name); - -static struct rt_bus spi_bus; - -void spi_bus_scan_devices(struct rt_spi_bus *bus) -{ -#ifdef RT_USING_OFW - if (bus->parent.ofw_node) - { - struct rt_ofw_node *np = bus->parent.ofw_node, *spi_dev_np; - - rt_ofw_foreach_available_child_node(np, spi_dev_np) - { - rt_uint64_t reg_offset; - struct rt_spi_device *spi_dev; - - if (!rt_ofw_prop_read_bool(spi_dev_np, "compatible")) - { - continue; - } - - spi_dev = rt_calloc(1, sizeof(*spi_dev)); - - if (!spi_dev) - { - rt_ofw_node_put(spi_dev_np); - LOG_E("Not memory to create spi device: %s", - rt_ofw_node_full_name(spi_dev_np)); - - return; - } - - rt_ofw_get_address(spi_dev_np, 0, ®_offset, RT_NULL); - - spi_dev->parent.ofw_node = spi_dev_np; - spi_dev->parent.type = RT_Device_Class_Unknown; - spi_dev->name = rt_ofw_node_name(spi_dev_np); - spi_dev->bus = bus; - - rt_dm_dev_set_name(&spi_dev->parent, rt_ofw_node_full_name(spi_dev_np)); - - if (spi_device_ofw_parse(spi_dev)) - { - continue; - } - - rt_spi_device_register(spi_dev); - } - } -#endif /* RT_USING_OFW */ -} - -rt_err_t rt_spi_driver_register(struct rt_spi_driver *driver) -{ - RT_ASSERT(driver != RT_NULL); - - driver->parent.bus = &spi_bus; - - return rt_driver_register(&driver->parent); -} - -rt_err_t rt_spi_device_register(struct rt_spi_device *device) -{ - RT_ASSERT(device != RT_NULL); - - return rt_bus_add_device(&spi_bus, &device->parent); -} - -static rt_bool_t spi_match(rt_driver_t drv, rt_device_t dev) -{ - const struct rt_spi_device_id *id; - struct rt_spi_driver *driver = rt_container_of(drv, struct rt_spi_driver, parent); - struct rt_spi_device *device = rt_container_of(dev, struct rt_spi_device, parent); - - if ((id = driver->ids)) - { - for (; id->name[0]; ++id) - { - if (!rt_strcmp(id->name, device->name)) - { - device->id = id; - device->ofw_id = RT_NULL; - - return RT_TRUE; - } - } - } - -#ifdef RT_USING_OFW - device->ofw_id = rt_ofw_node_match(device->parent.ofw_node, driver->ofw_ids); - - if (device->ofw_id) - { - device->id = RT_NULL; - - return RT_TRUE; - } -#endif - - return RT_FALSE; -} - -static rt_err_t spi_probe(rt_device_t dev) -{ - rt_err_t err; - struct rt_spi_bus *bus; - struct rt_spi_driver *driver = rt_container_of(dev->drv, struct rt_spi_driver, parent); - struct rt_spi_device *device = rt_container_of(dev, struct rt_spi_device, parent); - - if (!device->bus) - { - return -RT_EINVAL; - } - - err = driver->probe(device); - - if (err) - { - return err; - } - - bus = device->bus; - - if (bus->pins) - { - device->cs_pin = bus->pins[device->chip_select]; - - rt_pin_mode(device->cs_pin, PIN_MODE_OUTPUT); - } - else - { - device->cs_pin = PIN_NONE; - } - - /* Driver not register SPI device to system */ - if (device->parent.type == RT_Device_Class_Unknown) - { - rt_spidev_device_init(device, rt_dm_dev_get_name(&device->parent)); - } - - return err; -} - -static rt_err_t spi_remove(rt_device_t dev) -{ - struct rt_spi_driver *driver = rt_container_of(dev->drv, struct rt_spi_driver, parent); - struct rt_spi_device *device = rt_container_of(dev, struct rt_spi_device, parent); - - if (driver && driver->remove) - { - driver->remove(device); - } - rt_free(device); - - return RT_EOK; -} - -static rt_err_t spi_shutdown(rt_device_t dev) -{ - struct rt_spi_driver *driver = rt_container_of(dev->drv, struct rt_spi_driver, parent); - struct rt_spi_device *device = rt_container_of(dev, struct rt_spi_device, parent); - - if (driver && driver->shutdown) - { - driver->shutdown(device); - } - rt_free(device); - - return RT_EOK; -} - -static struct rt_bus spi_bus = -{ - .name = "spi", - .match = spi_match, - .probe = spi_probe, - .remove = spi_remove, - .shutdown = spi_shutdown, -}; - -static int spi_bus_init(void) -{ - rt_bus_register(&spi_bus); - - return 0; -} -INIT_CORE_EXPORT(spi_bus_init); diff --git a/rt-thread/components/drivers/spi/dev_spi_core.c b/rt-thread/components/drivers/spi/dev_spi_core.c deleted file mode 100644 index d84aaac..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_core.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-01-08 bernard first version. - * 2012-02-03 bernard add const attribute to the ops. - * 2012-05-15 dzzxzz fixed the return value in attach_device. - * 2012-05-18 bernard Changed SPI message to message list. - * Added take/release SPI device/bus interface. - * 2012-09-28 aozima fixed rt_spi_release_bus assert error. - */ - -#include "drivers/dev_spi.h" - -#define DBG_TAG "spi.core" -#define DBG_LVL DBG_INFO -#include - -#ifdef RT_USING_DM -#include "dev_spi_dm.h" -#endif - -extern rt_err_t rt_spi_bus_device_init(struct rt_spi_bus *bus, const char *name); -extern rt_err_t rt_spidev_device_init(struct rt_spi_device *dev, const char *name); - -rt_err_t rt_spi_bus_register(struct rt_spi_bus *bus, - const char *name, - const struct rt_spi_ops *ops) -{ - rt_err_t result; - - result = rt_spi_bus_device_init(bus, name); - if (result != RT_EOK) - return result; - - /* initialize mutex lock */ - rt_mutex_init(&(bus->lock), name, RT_IPC_FLAG_PRIO); - /* set ops */ - bus->ops = ops; - /* initialize owner */ - bus->owner = RT_NULL; - /* set bus mode */ - bus->mode = RT_SPI_BUS_MODE_SPI; - -#ifdef RT_USING_DM - if (!bus->slave) - { - int pin_count = rt_pin_get_named_pin_count(&bus->parent, "cs"); - - if (pin_count > 0) - { - pin_count = rt_max_t(int, pin_count, bus->num_chipselect); - bus->pins = rt_malloc(sizeof(bus->pins[0]) * pin_count); - - if (!bus->pins) - { - rt_device_unregister(&bus->parent); - return -RT_ENOMEM; - } - - for (int i = 0; i < pin_count; ++i) - { - bus->pins[i] = rt_pin_get_named_pin(&bus->parent, "cs", i, - RT_NULL, RT_NULL); - } - } - else if (pin_count == 0) - { - bus->pins = RT_NULL; - } - else - { - result = pin_count; - - LOG_E("CS PIN find error = %s", rt_strerror(result)); - - rt_device_unregister(&bus->parent); - return result; - } - } - - spi_bus_scan_devices(bus); -#endif - - return RT_EOK; -} - -rt_err_t rt_spi_bus_attach_device_cspin(struct rt_spi_device *device, - const char *name, - const char *bus_name, - rt_base_t cs_pin, - void *user_data) -{ - rt_err_t result; - rt_device_t bus; - - /* get physical spi bus */ - bus = rt_device_find(bus_name); - if (bus != RT_NULL && bus->type == RT_Device_Class_SPIBUS) - { - device->bus = (struct rt_spi_bus *)bus; - - /* initialize spidev device */ - result = rt_spidev_device_init(device, name); - if (result != RT_EOK) - return result; - - if(cs_pin != PIN_NONE) - { - rt_pin_mode(cs_pin, PIN_MODE_OUTPUT); - } - - rt_memset(&device->config, 0, sizeof(device->config)); - device->parent.user_data = user_data; - device->cs_pin = cs_pin; - return RT_EOK; - } - - /* not found the host bus */ - return -RT_ERROR; -} - -rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device, - const char *name, - const char *bus_name, - void *user_data) -{ - return rt_spi_bus_attach_device_cspin(device, name, bus_name, PIN_NONE, user_data); -} - -rt_err_t rt_spi_bus_configure(struct rt_spi_device *device) -{ - rt_err_t result = -RT_ERROR; - - if (device->bus != RT_NULL) - { - result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - if (device->bus->owner == device) - { - /* current device is using, re-configure SPI bus */ - result = device->bus->ops->configure(device, &device->config); - if (result != RT_EOK) - { - /* configure SPI bus failed */ - LOG_E("SPI device %s configuration failed", device->parent.parent.name); - } - } - else - { - /* RT_EBUSY is not an error condition and - * the configuration will take effect once the device has the bus - */ - result = -RT_EBUSY; - } - - /* release lock */ - rt_mutex_release(&(device->bus->lock)); - } - } - else - { - result = RT_EOK; - } - - return result; -} - -rt_err_t rt_spi_configure(struct rt_spi_device *device, - struct rt_spi_configuration *cfg) -{ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(cfg != RT_NULL); - - /* reset the CS pin */ - if (device->cs_pin != PIN_NONE) - { - rt_err_t result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - if (cfg->mode & RT_SPI_CS_HIGH) - { - rt_pin_write(device->cs_pin, PIN_LOW); - } - else - { - rt_pin_write(device->cs_pin, PIN_HIGH); - } - rt_mutex_release(&(device->bus->lock)); - } - else - { - return result; - } - } - - /* If the configurations are the same, we don't need to set again. */ - if (device->config.data_width == cfg->data_width && - device->config.mode == (cfg->mode & RT_SPI_MODE_MASK) && - device->config.max_hz == cfg->max_hz) - { - return RT_EOK; - } - - /* set configuration */ - device->config.data_width = cfg->data_width; - device->config.mode = cfg->mode & RT_SPI_MODE_MASK; - device->config.max_hz = cfg->max_hz; - - return rt_spi_bus_configure(device); -} - -rt_err_t rt_spi_send_then_send(struct rt_spi_device *device, - const void *send_buf1, - rt_size_t send_length1, - const void *send_buf2, - rt_size_t send_length2) -{ - rt_err_t result; - struct rt_spi_message message; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - if (device->bus->owner != device) - { - /* not the same owner as current, re-configure SPI bus */ - result = device->bus->ops->configure(device, &device->config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - device->bus->owner = device; - } - else - { - /* configure SPI bus failed */ - LOG_E("SPI device %s configuration failed", device->parent.parent.name); - goto __exit; - } - } - - /* send data1 */ - message.send_buf = send_buf1; - message.recv_buf = RT_NULL; - message.length = send_length1; - message.cs_take = 1; - message.cs_release = 0; - message.next = RT_NULL; - - result = device->bus->ops->xfer(device, &message); - if (result < 0) - { - LOG_E("SPI device %s transfer failed", device->parent.parent.name); - goto __exit; - } - - /* send data2 */ - message.send_buf = send_buf2; - message.recv_buf = RT_NULL; - message.length = send_length2; - message.cs_take = 0; - message.cs_release = 1; - message.next = RT_NULL; - - result = device->bus->ops->xfer(device, &message); - if (result < 0) - { - LOG_E("SPI device %s transfer failed", device->parent.parent.name); - goto __exit; - } - - result = RT_EOK; - } - else - { - return -RT_EIO; - } - -__exit: - rt_mutex_release(&(device->bus->lock)); - - return result; -} - -rt_err_t rt_spi_send_then_recv(struct rt_spi_device *device, - const void *send_buf, - rt_size_t send_length, - void *recv_buf, - rt_size_t recv_length) -{ - rt_err_t result; - struct rt_spi_message message; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - if (device->bus->owner != device) - { - /* not the same owner as current, re-configure SPI bus */ - result = device->bus->ops->configure(device, &device->config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - device->bus->owner = device; - } - else - { - /* configure SPI bus failed */ - LOG_E("SPI device %s configuration failed", device->parent.parent.name); - goto __exit; - } - } - - /* send data */ - message.send_buf = send_buf; - message.recv_buf = RT_NULL; - message.length = send_length; - message.cs_take = 1; - message.cs_release = 0; - message.next = RT_NULL; - - result = device->bus->ops->xfer(device, &message); - if (result < 0) - { - LOG_E("SPI device %s transfer failed", device->parent.parent.name); - goto __exit; - } - - /* recv data */ - message.send_buf = RT_NULL; - message.recv_buf = recv_buf; - message.length = recv_length; - message.cs_take = 0; - message.cs_release = 1; - message.next = RT_NULL; - - result = device->bus->ops->xfer(device, &message); - if (result < 0) - { - LOG_E("SPI device %s transfer failed", device->parent.parent.name); - goto __exit; - } - - result = RT_EOK; - } - else - { - return -RT_EIO; - } - -__exit: - rt_mutex_release(&(device->bus->lock)); - - return result; -} - -rt_ssize_t rt_spi_transfer(struct rt_spi_device *device, - const void *send_buf, - void *recv_buf, - rt_size_t length) -{ - rt_ssize_t result; - struct rt_spi_message message; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - if (device->bus->owner != device) - { - /* not the same owner as current, re-configure SPI bus */ - result = device->bus->ops->configure(device, &device->config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - device->bus->owner = device; - } - else - { - /* configure SPI bus failed */ - LOG_E("SPI device %s configuration failed", device->parent.parent.name); - goto __exit; - } - } - - /* initial message */ - message.send_buf = send_buf; - message.recv_buf = recv_buf; - message.length = length; - message.cs_take = 1; - message.cs_release = 1; - message.next = RT_NULL; - - /* transfer message */ - result = device->bus->ops->xfer(device, &message); - if (result < 0) - { - LOG_E("SPI device %s transfer failed", device->parent.parent.name); - goto __exit; - } - } - else - { - return -RT_EIO; - } - -__exit: - rt_mutex_release(&(device->bus->lock)); - - return result; -} - -rt_err_t rt_spi_sendrecv8(struct rt_spi_device *device, - rt_uint8_t senddata, - rt_uint8_t *recvdata) -{ - rt_ssize_t len = rt_spi_transfer(device, &senddata, recvdata, 1); - if (len < 0) - { - return (rt_err_t)len; - } - else - { - return RT_EOK; - } -} - -rt_err_t rt_spi_sendrecv16(struct rt_spi_device *device, - rt_uint16_t senddata, - rt_uint16_t *recvdata) -{ - rt_ssize_t len; - rt_uint16_t tmp; - - if (device->config.mode & RT_SPI_MSB) - { - tmp = ((senddata & 0xff00) >> 8) | ((senddata & 0x00ff) << 8); - senddata = tmp; - } - - len = rt_spi_transfer(device, &senddata, recvdata, 2); - if(len < 0) - { - return (rt_err_t)len; - } - - if (device->config.mode & RT_SPI_MSB) - { - tmp = ((*recvdata & 0xff00) >> 8) | ((*recvdata & 0x00ff) << 8); - *recvdata = tmp; - } - - return RT_EOK; -} - -struct rt_spi_message *rt_spi_transfer_message(struct rt_spi_device *device, - struct rt_spi_message *message) -{ - rt_err_t result; - struct rt_spi_message *index; - - RT_ASSERT(device != RT_NULL); - - /* get first message */ - index = message; - if (index == RT_NULL) - return index; - - result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result != RT_EOK) - { - return index; - } - - /* configure SPI bus */ - if (device->bus->owner != device) - { - /* not the same owner as current, re-configure SPI bus */ - result = device->bus->ops->configure(device, &device->config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - device->bus->owner = device; - } - else - { - /* configure SPI bus failed */ - goto __exit; - } - } - - /* transmit each SPI message */ - while (index != RT_NULL) - { - /* transmit SPI message */ - result = device->bus->ops->xfer(device, index); - if (result < 0) - { - break; - } - - index = index->next; - } - -__exit: - /* release bus lock */ - rt_mutex_release(&(device->bus->lock)); - - return index; -} - -rt_err_t rt_spi_take_bus(struct rt_spi_device *device) -{ - rt_err_t result = RT_EOK; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result != RT_EOK) - { - return -RT_EBUSY; - } - - /* configure SPI bus */ - if (device->bus->owner != device) - { - /* not the same owner as current, re-configure SPI bus */ - result = device->bus->ops->configure(device, &device->config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - device->bus->owner = device; - } - else - { - /* configure SPI bus failed */ - rt_mutex_release(&(device->bus->lock)); - - return result; - } - } - - return result; -} - -rt_err_t rt_spi_release_bus(struct rt_spi_device *device) -{ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - RT_ASSERT(device->bus->owner == device); - - /* release lock */ - return rt_mutex_release(&(device->bus->lock)); -} - -rt_err_t rt_spi_take(struct rt_spi_device *device) -{ - rt_ssize_t result; - struct rt_spi_message message; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - rt_memset(&message, 0, sizeof(message)); - message.cs_take = 1; - - result = device->bus->ops->xfer(device, &message); - if(result < 0) - { - return (rt_err_t)result; - } - - return RT_EOK; -} - -rt_err_t rt_spi_release(struct rt_spi_device *device) -{ - rt_ssize_t result; - struct rt_spi_message message; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - rt_memset(&message, 0, sizeof(message)); - message.cs_release = 1; - - result = device->bus->ops->xfer(device, &message); - if(result < 0) - { - return (rt_err_t)result; - } - - return RT_EOK; -} diff --git a/rt-thread/components/drivers/spi/dev_spi_dm.c b/rt-thread/components/drivers/spi/dev_spi_dm.c deleted file mode 100644 index 063615c..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_dm.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-12-06 GuEe-GUI first version - */ - -#include "dev_spi_dm.h" - -#define DBG_TAG "spi.dm" -#define DBG_LVL DBG_INFO -#include - -#ifdef RT_USING_OFW -static void ofw_parse_delay(struct rt_ofw_node *np, struct rt_spi_delay *delay, - const char *prop) -{ - rt_uint32_t value; - - if (!rt_ofw_prop_read_u32(np, prop, &value)) - { - if (value > RT_UINT16_MAX) - { - delay->value = RT_DIV_ROUND_UP(value, 1000); - delay->unit = RT_SPI_DELAY_UNIT_USECS; - } - else - { - delay->value = value; - delay->unit = RT_SPI_DELAY_UNIT_NSECS; - } - } -} - -rt_err_t spi_device_ofw_parse(struct rt_spi_device *spi_dev) -{ - rt_err_t err; - rt_uint32_t value; - struct rt_spi_bus *spi_bus = spi_dev->bus; - struct rt_ofw_node *np = spi_dev->parent.ofw_node; - struct rt_spi_configuration *conf = &spi_dev->config; - - if (rt_ofw_prop_read_bool(np, "spi-cpha")) - { - conf->mode |= RT_SPI_CPHA; - } - if (rt_ofw_prop_read_bool(np, "spi-cpol")) - { - conf->mode |= RT_SPI_CPOL; - } - if (rt_ofw_prop_read_bool(np, "spi-3wire")) - { - conf->mode |= RT_SPI_3WIRE; - } - if (rt_ofw_prop_read_bool(np, "spi-lsb-first")) - { - conf->mode |= RT_SPI_LSB; - } - if (rt_ofw_prop_read_bool(np, "spi-cs-high")) - { - conf->mode |= RT_SPI_CS_HIGH; - } - - value = 1; - rt_ofw_prop_read_u32(np, "spi-tx-bus-width", &value); - conf->data_width_tx = value; - - value = 1; - rt_ofw_prop_read_u32(np, "spi-rx-bus-width", &value); - conf->data_width_rx = value; - - if (spi_bus->slave) - { - if (!rt_ofw_node_tag_equ(np, "slave")) - { - LOG_E("Invalid SPI device = %s", rt_ofw_node_full_name(np)); - - return -RT_EINVAL; - } - - return RT_EOK; - } - - if ((err = rt_ofw_prop_read_u32(np, "reg", &value))) - { - LOG_E("Find 'reg' failed"); - - return err; - } - spi_dev->chip_select = value; - - if (!rt_ofw_prop_read_u32(np, "spi-max-frequency", &value)) - { - conf->max_hz = value; - } - - ofw_parse_delay(np, &spi_dev->cs_setup, "spi-cs-setup-delay-ns"); - ofw_parse_delay(np, &spi_dev->cs_hold, "spi-cs-hold-delay-ns"); - ofw_parse_delay(np, &spi_dev->cs_inactive, "spi-cs-inactive-delay-ns"); - - return RT_EOK; -} -#endif /* RT_USING_OFW */ diff --git a/rt-thread/components/drivers/spi/dev_spi_dm.h b/rt-thread/components/drivers/spi/dev_spi_dm.h deleted file mode 100644 index c124295..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_dm.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-11-26 GuEe-GUI first version - */ - -#ifndef __DEV_SPI_DM_H__ -#define __DEV_SPI_DM_H__ - -#include -#include -#include - -#ifdef RT_USING_OFW -rt_err_t spi_device_ofw_parse(struct rt_spi_device *spi_dev); -#else -rt_inline rt_err_t spi_device_ofw_parse(struct rt_spi_device *spi_dev) -{ - return RT_EOK; -} -#endif /* RT_USING_OFW */ - -void spi_bus_scan_devices(struct rt_spi_bus *bus); - -#endif /* __DEV_SPI_DM_H__ */ diff --git a/rt-thread/components/drivers/spi/dev_spi_flash.h b/rt-thread/components/drivers/spi/dev_spi_flash.h deleted file mode 100644 index 5ae54c4..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_flash.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2016/5/20 bernard the first version - * 2020/1/7 redoc add include - */ - -#ifndef __DEV_SPI_FLASH_H__ -#define __DEV_SPI_FLASH_H__ - -#include - -struct spi_flash_device -{ - struct rt_device flash_device; - struct rt_device_blk_geometry geometry; - struct rt_spi_device * rt_spi_device; - struct rt_mutex lock; - void * user_data; -}; - -typedef struct spi_flash_device *rt_spi_flash_device_t; - -#ifdef RT_USING_MTD_NOR -struct spi_flash_mtd -{ - struct rt_mtd_nor_device mtd_device; - struct rt_spi_device * rt_spi_device; - struct rt_mutex lock; - void * user_data; -}; -#endif - -#endif diff --git a/rt-thread/components/drivers/spi/dev_spi_flash_sfud.c b/rt-thread/components/drivers/spi/dev_spi_flash_sfud.c deleted file mode 100644 index e1c90db..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_flash_sfud.c +++ /dev/null @@ -1,779 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2016-09-28 armink first version. - */ - -#include -#include -#include -#include "dev_spi_flash.h" -#include "dev_spi_flash_sfud.h" - -#ifdef RT_USING_SFUD - -#ifndef RT_SFUD_DEFAULT_SPI_CFG - -#ifndef RT_SFUD_SPI_MAX_HZ -#define RT_SFUD_SPI_MAX_HZ 50000000 -#endif - -/* read the JEDEC SFDP command must run at 50 MHz or less */ -#define RT_SFUD_DEFAULT_SPI_CFG \ -{ \ - .mode = RT_SPI_MODE_0 | RT_SPI_MSB, \ - .data_width = 8, \ - .max_hz = RT_SFUD_SPI_MAX_HZ, \ -} -#endif /* RT_SFUD_DEFAULT_SPI_CFG */ - -#ifdef SFUD_USING_QSPI -#define RT_SFUD_DEFAULT_QSPI_CFG \ -{ \ - RT_SFUD_DEFAULT_SPI_CFG, \ - .medium_size = 0x800000, \ - .ddr_mode = 0, \ - .qspi_dl_width = 4, \ -} -#endif /* SFUD_USING_QSPI */ - -static rt_err_t rt_sfud_control(rt_device_t dev, int cmd, void *args) { - RT_ASSERT(dev); - - switch (cmd) { - case RT_DEVICE_CTRL_BLK_GETGEOME: { - struct rt_device_blk_geometry *geometry = (struct rt_device_blk_geometry *) args; - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (dev->user_data); - - if (rtt_dev == RT_NULL || geometry == RT_NULL) { - return -RT_ERROR; - } - - geometry->bytes_per_sector = rtt_dev->geometry.bytes_per_sector; - geometry->sector_count = rtt_dev->geometry.sector_count; - geometry->block_size = rtt_dev->geometry.block_size; - break; - } - case RT_DEVICE_CTRL_BLK_ERASE: { - rt_uint32_t *addrs = (rt_uint32_t *) args, start_addr = addrs[0], end_addr = addrs[1], phy_start_addr; - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (dev->user_data); - sfud_flash *sfud_dev = (sfud_flash *) (rtt_dev->user_data); - rt_size_t phy_size; - - if (addrs == RT_NULL || start_addr > end_addr || rtt_dev == RT_NULL || sfud_dev == RT_NULL) { - return -RT_ERROR; - } - - if (end_addr == start_addr) { - end_addr ++; - } - - phy_start_addr = start_addr * rtt_dev->geometry.bytes_per_sector; - phy_size = (end_addr - start_addr) * rtt_dev->geometry.bytes_per_sector; - - if (sfud_erase(sfud_dev, phy_start_addr, phy_size) != SFUD_SUCCESS) { - return -RT_ERROR; - } - break; - } - } - - return RT_EOK; -} - - -static rt_ssize_t rt_sfud_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) { - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (dev->user_data); - sfud_flash *sfud_dev = (sfud_flash *) (rtt_dev->user_data); - - RT_ASSERT(dev); - RT_ASSERT(rtt_dev); - RT_ASSERT(sfud_dev); - /* change the block device's logic address to physical address */ - rt_off_t phy_pos = pos * rtt_dev->geometry.bytes_per_sector; - rt_size_t phy_size = size * rtt_dev->geometry.bytes_per_sector; - - if (sfud_read(sfud_dev, phy_pos, phy_size, buffer) != SFUD_SUCCESS) { - return 0; - } else { - return size; - } -} - -static rt_ssize_t rt_sfud_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) { - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (dev->user_data); - sfud_flash *sfud_dev = (sfud_flash *) (rtt_dev->user_data); - - RT_ASSERT(dev); - RT_ASSERT(rtt_dev); - RT_ASSERT(sfud_dev); - /* change the block device's logic address to physical address */ - rt_off_t phy_pos = pos * rtt_dev->geometry.bytes_per_sector; - rt_size_t phy_size = size * rtt_dev->geometry.bytes_per_sector; - - if (sfud_erase_write(sfud_dev, phy_pos, phy_size, buffer) != SFUD_SUCCESS) { - return 0; - } else { - return size; - } -} - -/** - * SPI write data then read data - */ -static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf, - size_t read_size) { - sfud_err result = SFUD_SUCCESS; - sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data); - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data); - - RT_ASSERT(spi); - RT_ASSERT(sfud_dev); - RT_ASSERT(rtt_dev); -#ifdef SFUD_USING_QSPI - struct rt_qspi_device *qspi_dev = RT_NULL; -#endif - if (write_size) { - RT_ASSERT(write_buf); - } - if (read_size) { - RT_ASSERT(read_buf); - } -#ifdef SFUD_USING_QSPI - if(rtt_dev->rt_spi_device->bus->mode & RT_SPI_BUS_MODE_QSPI) { - qspi_dev = (struct rt_qspi_device *) (rtt_dev->rt_spi_device); - if (write_size && read_size) { - if (rt_qspi_send_then_recv(qspi_dev, write_buf, write_size, read_buf, read_size) <= 0) { - result = SFUD_ERR_TIMEOUT; - } - } else if (write_size) { - if (rt_qspi_send(qspi_dev, write_buf, write_size) <= 0) { - result = SFUD_ERR_TIMEOUT; - } - } - } - else -#endif - { - if (write_size && read_size) { - if (rt_spi_send_then_recv(rtt_dev->rt_spi_device, write_buf, write_size, read_buf, read_size) != RT_EOK) { - result = SFUD_ERR_TIMEOUT; - } - } else if (write_size) { - if (rt_spi_send(rtt_dev->rt_spi_device, write_buf, write_size) <= 0) { - result = SFUD_ERR_TIMEOUT; - } - } else { - if (rt_spi_recv(rtt_dev->rt_spi_device, read_buf, read_size) <= 0) { - result = SFUD_ERR_TIMEOUT; - } - } - } - - return result; -} - -#ifdef SFUD_USING_QSPI -/** - * QSPI fast read data - */ -static sfud_err qspi_read(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format, uint8_t *read_buf, size_t read_size) { - struct rt_qspi_message message; - sfud_err result = SFUD_SUCCESS; - - sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data); - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data); - struct rt_qspi_device *qspi_dev = (struct rt_qspi_device *) (rtt_dev->rt_spi_device); - - RT_ASSERT(spi); - RT_ASSERT(sfud_dev); - RT_ASSERT(rtt_dev); - RT_ASSERT(qspi_dev); - - /* set message struct */ - message.instruction.content = qspi_read_cmd_format->instruction; - message.instruction.qspi_lines = qspi_read_cmd_format->instruction_lines; - - message.address.content = addr; - message.address.size = qspi_read_cmd_format->address_size; - message.address.qspi_lines = qspi_read_cmd_format->address_lines; - - message.alternate_bytes.content = 0; - message.alternate_bytes.size = 0; - message.alternate_bytes.qspi_lines = 0; - - message.dummy_cycles = qspi_read_cmd_format->dummy_cycles; - - message.parent.send_buf = RT_NULL; - message.parent.recv_buf = read_buf; - message.parent.length = read_size; - message.parent.cs_release = 1; - message.parent.cs_take = 1; - message.qspi_data_lines = qspi_read_cmd_format->data_lines; - - if (rt_qspi_transfer_message(qspi_dev, &message) != read_size) { - result = SFUD_ERR_TIMEOUT; - } - - return result; -} -#endif - -static void spi_lock(const sfud_spi *spi) { - sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data); - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data); - - RT_ASSERT(spi); - RT_ASSERT(sfud_dev); - RT_ASSERT(rtt_dev); - - rt_mutex_take(&(rtt_dev->lock), RT_WAITING_FOREVER); -} - -static void spi_unlock(const sfud_spi *spi) { - sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data); - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data); - - RT_ASSERT(spi); - RT_ASSERT(sfud_dev); - RT_ASSERT(rtt_dev); - - rt_mutex_release(&(rtt_dev->lock)); -} - -static void retry_delay_100us(void) { - /* 100 microsecond delay */ - rt_thread_delay((RT_TICK_PER_SECOND * 1 + 9999) / 10000); -} - -sfud_err sfud_spi_port_init(sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - - RT_ASSERT(flash); - - /* port SPI device interface */ - flash->spi.wr = spi_write_read; -#ifdef SFUD_USING_QSPI - flash->spi.qspi_read = qspi_read; -#endif - flash->spi.lock = spi_lock; - flash->spi.unlock = spi_unlock; - flash->spi.user_data = flash; - if (RT_TICK_PER_SECOND < 1000) { - LOG_W("[SFUD] Warning: The OS tick(%d) is less than 1000. So the flash write will take more time.", RT_TICK_PER_SECOND); - } - /* 100 microsecond delay */ - flash->retry.delay = retry_delay_100us; - /* 60 seconds timeout */ - flash->retry.times = 60 * 10000; - - return result; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops flash_device_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - rt_sfud_read, - rt_sfud_write, - rt_sfud_control -}; -#endif - -/** - * Probe SPI flash by SFUD (Serial Flash Universal Driver) driver library and though SPI device by specified configuration. - * - * @param spi_flash_dev_name the name which will create SPI flash device - * @param spi_dev_name using SPI device name - * @param spi_cfg SPI device configuration - * @param qspi_cfg QSPI device configuration - * - * @return probed SPI flash device, probe failed will return RT_NULL - */ -rt_spi_flash_device_t rt_sfud_flash_probe_ex(const char *spi_flash_dev_name, const char *spi_dev_name, - struct rt_spi_configuration *spi_cfg, struct rt_qspi_configuration *qspi_cfg) -{ - rt_spi_flash_device_t rtt_dev = RT_NULL; - sfud_flash *sfud_dev = RT_NULL; - char *spi_flash_dev_name_bak = RT_NULL, *spi_dev_name_bak = RT_NULL; - extern sfud_err sfud_device_init(sfud_flash *flash); -#ifdef SFUD_USING_QSPI - struct rt_qspi_device *qspi_dev = RT_NULL; -#endif - - RT_ASSERT(spi_flash_dev_name); - RT_ASSERT(spi_dev_name); - - rtt_dev = (rt_spi_flash_device_t) rt_malloc(sizeof(struct spi_flash_device)); - sfud_dev = (sfud_flash_t) rt_malloc(sizeof(sfud_flash)); - spi_flash_dev_name_bak = (char *) rt_malloc(rt_strlen(spi_flash_dev_name) + 1); - spi_dev_name_bak = (char *) rt_malloc(rt_strlen(spi_dev_name) + 1); - - if (rtt_dev) { - rt_memset(rtt_dev, 0, sizeof(struct spi_flash_device)); - /* initialize lock */ - rt_mutex_init(&(rtt_dev->lock), spi_flash_dev_name, RT_IPC_FLAG_PRIO); - } - - if (rtt_dev && sfud_dev && spi_flash_dev_name_bak && spi_dev_name_bak) { - rt_memset(sfud_dev, 0, sizeof(sfud_flash)); - rt_strncpy(spi_flash_dev_name_bak, spi_flash_dev_name, rt_strlen(spi_flash_dev_name)); - rt_strncpy(spi_dev_name_bak, spi_dev_name, rt_strlen(spi_dev_name)); - /* make string end sign */ - spi_flash_dev_name_bak[rt_strlen(spi_flash_dev_name)] = '\0'; - spi_dev_name_bak[rt_strlen(spi_dev_name)] = '\0'; - /* SPI configure */ - { - /* RT-Thread SPI device initialize */ - rtt_dev->rt_spi_device = (struct rt_spi_device *) rt_device_find(spi_dev_name); - if (rtt_dev->rt_spi_device == RT_NULL || rtt_dev->rt_spi_device->parent.type != RT_Device_Class_SPIDevice) { - LOG_E("ERROR: SPI device %s not found!", spi_dev_name); - goto error; - } - sfud_dev->spi.name = spi_dev_name_bak; - -#ifdef SFUD_USING_QSPI - /* set the qspi line number and configure the QSPI bus */ - if(rtt_dev->rt_spi_device->bus->mode &RT_SPI_BUS_MODE_QSPI) { - qspi_dev = (struct rt_qspi_device *)rtt_dev->rt_spi_device; - qspi_cfg->qspi_dl_width = qspi_dev->config.qspi_dl_width; - rt_qspi_configure(qspi_dev, qspi_cfg); - } - else -#endif - rt_spi_configure(rtt_dev->rt_spi_device, spi_cfg); - } - /* SFUD flash device initialize */ - { - sfud_dev->name = spi_flash_dev_name_bak; - /* accessed each other */ - rtt_dev->user_data = sfud_dev; - rtt_dev->rt_spi_device->user_data = rtt_dev; - rtt_dev->flash_device.user_data = rtt_dev; - sfud_dev->user_data = rtt_dev; - /* initialize SFUD device */ - if (sfud_device_init(sfud_dev) != SFUD_SUCCESS) { - LOG_E("ERROR: SPI flash probe failed by SPI device %s.", spi_dev_name); - goto error; - } - /* when initialize success, then copy SFUD flash device's geometry to RT-Thread SPI flash device */ - rtt_dev->geometry.sector_count = sfud_dev->chip.capacity / sfud_dev->chip.erase_gran; - rtt_dev->geometry.bytes_per_sector = sfud_dev->chip.erase_gran; - rtt_dev->geometry.block_size = sfud_dev->chip.erase_gran; -#ifdef SFUD_USING_QSPI - /* reconfigure the QSPI bus for medium size */ - if(rtt_dev->rt_spi_device->bus->mode &RT_SPI_BUS_MODE_QSPI) { - qspi_cfg->medium_size = sfud_dev->chip.capacity; - rt_qspi_configure(qspi_dev, qspi_cfg); - if(qspi_dev->enter_qspi_mode != RT_NULL) - qspi_dev->enter_qspi_mode(qspi_dev); - - /* set data lines width */ - sfud_qspi_fast_read_enable(sfud_dev, qspi_dev->config.qspi_dl_width); - } -#endif /* SFUD_USING_QSPI */ - } - - /* register device */ - rtt_dev->flash_device.type = RT_Device_Class_Block; -#ifdef RT_USING_DEVICE_OPS - rtt_dev->flash_device.ops = &flash_device_ops; -#else - rtt_dev->flash_device.init = RT_NULL; - rtt_dev->flash_device.open = RT_NULL; - rtt_dev->flash_device.close = RT_NULL; - rtt_dev->flash_device.read = rt_sfud_read; - rtt_dev->flash_device.write = rt_sfud_write; - rtt_dev->flash_device.control = rt_sfud_control; -#endif - - rt_device_register(&(rtt_dev->flash_device), spi_flash_dev_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE); - - LOG_I("Probe SPI flash %s by SPI device %s success.",spi_flash_dev_name, spi_dev_name); - return rtt_dev; - } else { - LOG_E("ERROR: Low memory."); - goto error; - } - -error: - - if (rtt_dev) { - rt_mutex_detach(&(rtt_dev->lock)); - } - /* may be one of objects memory was malloc success, so need free all */ - rt_free(rtt_dev); - rt_free(sfud_dev); - rt_free(spi_flash_dev_name_bak); - rt_free(spi_dev_name_bak); - - return RT_NULL; -} - -/** - * Probe SPI flash by SFUD(Serial Flash Universal Driver) driver library and though SPI device. - * - * @param spi_flash_dev_name the name which will create SPI flash device - * @param spi_dev_name using SPI device name - * - * @return probed SPI flash device, probe failed will return RT_NULL - */ -rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name) -{ - struct rt_spi_configuration cfg = RT_SFUD_DEFAULT_SPI_CFG; -#ifndef SFUD_USING_QSPI - return rt_sfud_flash_probe_ex(spi_flash_dev_name, spi_dev_name, &cfg, RT_NULL); -#else - struct rt_qspi_configuration qspi_cfg = RT_SFUD_DEFAULT_QSPI_CFG; - - return rt_sfud_flash_probe_ex(spi_flash_dev_name, spi_dev_name, &cfg, &qspi_cfg); -#endif -} - -/** - * Delete SPI flash device - * - * @param spi_flash_dev SPI flash device - * - * @return the operation status, RT_EOK on successful - */ -rt_err_t rt_sfud_flash_delete(rt_spi_flash_device_t spi_flash_dev) { - sfud_flash *sfud_flash_dev = (sfud_flash *) (spi_flash_dev->user_data); - - RT_ASSERT(spi_flash_dev); - RT_ASSERT(sfud_flash_dev); - - rt_device_unregister(&(spi_flash_dev->flash_device)); - - rt_mutex_detach(&(spi_flash_dev->lock)); - - rt_free(sfud_flash_dev->spi.name); - rt_free(sfud_flash_dev->name); - rt_free(sfud_flash_dev); - rt_free(spi_flash_dev); - - return RT_EOK; -} - -sfud_flash_t rt_sfud_flash_find(const char *spi_dev_name) -{ - rt_spi_flash_device_t rtt_dev = RT_NULL; - struct rt_spi_device *rt_spi_device = RT_NULL; - sfud_flash_t sfud_dev = RT_NULL; - - rt_spi_device = (struct rt_spi_device *) rt_device_find(spi_dev_name); - if (rt_spi_device == RT_NULL || rt_spi_device->parent.type != RT_Device_Class_SPIDevice) { - LOG_E("ERROR: SPI device %s not found!", spi_dev_name); - goto __error; - } - - rtt_dev = (rt_spi_flash_device_t) (rt_spi_device->user_data); - if (rtt_dev && rtt_dev->user_data) { - sfud_dev = (sfud_flash_t) (rtt_dev->user_data); - return sfud_dev; - } else { - LOG_E("ERROR: SFUD flash device not found!"); - goto __error; - } - -__error: - return RT_NULL; -} - -sfud_flash_t rt_sfud_flash_find_by_dev_name(const char *flash_dev_name) -{ - rt_spi_flash_device_t rtt_dev = RT_NULL; - sfud_flash_t sfud_dev = RT_NULL; - - rtt_dev = (rt_spi_flash_device_t) rt_device_find(flash_dev_name); - if (rtt_dev == RT_NULL || rtt_dev->flash_device.type != RT_Device_Class_Block) { - LOG_E("ERROR: Flash device %s not found!", flash_dev_name); - goto __error; - } - - if (rtt_dev->user_data) { - sfud_dev = (sfud_flash_t) (rtt_dev->user_data); - return sfud_dev; - } else { - LOG_E("ERROR: SFUD flash device not found!"); - goto __error; - } - -__error: - return RT_NULL; -} - -#if defined(RT_USING_FINSH) - -#include - -static void sf(uint8_t argc, char **argv) { - -#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ') -#define HEXDUMP_WIDTH 16 -#define CMD_PROBE_INDEX 0 -#define CMD_READ_INDEX 1 -#define CMD_WRITE_INDEX 2 -#define CMD_ERASE_INDEX 3 -#define CMD_RW_STATUS_INDEX 4 -#define CMD_BENCH_INDEX 5 - - sfud_err result = SFUD_SUCCESS; - static const sfud_flash *sfud_dev = NULL; - static rt_spi_flash_device_t rtt_dev = NULL, rtt_dev_bak = NULL; - size_t i = 0, j = 0; - - const char* sf_help_info[] = { - [CMD_PROBE_INDEX] = "sf probe [spi_device] - probe and init SPI flash by given 'spi_device'", - [CMD_READ_INDEX] = "sf read addr size - read 'size' bytes starting at 'addr'", - [CMD_WRITE_INDEX] = "sf write addr data1 ... dataN - write some bytes 'data' to flash starting at 'addr'", - [CMD_ERASE_INDEX] = "sf erase addr size - erase 'size' bytes starting at 'addr'", - [CMD_RW_STATUS_INDEX] = "sf status [ ] - read or write '1:volatile|0:non-volatile' 'status'", - [CMD_BENCH_INDEX] = "sf bench - full chip benchmark. DANGER: It will erase full chip!", - }; - - if (argc < 2) { - rt_kprintf("Usage:\n"); - for (i = 0; i < sizeof(sf_help_info) / sizeof(char*); i++) { - rt_kprintf("%s\n", sf_help_info[i]); - } - rt_kprintf("\n"); - } else { - const char *operator = argv[1]; - uint32_t addr, size; - - if (!strcmp(operator, "probe")) { - if (argc < 3) { - rt_kprintf("Usage: %s.\n", sf_help_info[CMD_PROBE_INDEX]); - } else { - char *spi_dev_name = argv[2]; - rtt_dev_bak = rtt_dev; - - /* delete the old SPI flash device */ - if(rtt_dev_bak) { - rt_sfud_flash_delete(rtt_dev_bak); - } - - rtt_dev = rt_sfud_flash_probe("sf_cmd", spi_dev_name); - if (!rtt_dev) { - return; - } - - sfud_dev = (sfud_flash_t)rtt_dev->user_data; - if (sfud_dev->chip.capacity < 1024 * 1024) { - rt_kprintf("%d KB %s is current selected device.\n", sfud_dev->chip.capacity / 1024, sfud_dev->name); - } else { - rt_kprintf("%d MB %s is current selected device.\n", sfud_dev->chip.capacity / 1024 / 1024, - sfud_dev->name); - } - } - } else { - if (!sfud_dev) { - rt_kprintf("No flash device selected. Please run 'sf probe'.\n"); - return; - } - if (!rt_strcmp(operator, "read")) { - if (argc < 4) { - rt_kprintf("Usage: %s.\n", sf_help_info[CMD_READ_INDEX]); - return; - } else { - addr = strtol(argv[2], NULL, 0); - size = strtol(argv[3], NULL, 0); - uint8_t *data = rt_malloc(size); - if (data) { - result = sfud_read(sfud_dev, addr, size, data); - if (result == SFUD_SUCCESS) { - rt_kprintf("Read the %s flash data success. Start from 0x%08X, size is %ld. The data is:\n", - sfud_dev->name, addr, size); - rt_kprintf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n"); - for (i = 0; i < size; i += HEXDUMP_WIDTH) - { - rt_kprintf("[%08X] ", addr + i); - /* dump hex */ - for (j = 0; j < HEXDUMP_WIDTH; j++) { - if (i + j < size) { - rt_kprintf("%02X ", data[i + j]); - } else { - rt_kprintf(" "); - } - } - /* dump char for hex */ - for (j = 0; j < HEXDUMP_WIDTH; j++) { - if (i + j < size) { - rt_kprintf("%c", __is_print(data[i + j]) ? data[i + j] : '.'); - } - } - rt_kprintf("\n"); - } - rt_kprintf("\n"); - } - rt_free(data); - } else { - rt_kprintf("Low memory!\n"); - } - } - } else if (!rt_strcmp(operator, "write")) { - if (argc < 4) { - rt_kprintf("Usage: %s.\n", sf_help_info[CMD_WRITE_INDEX]); - return; - } else { - addr = strtol(argv[2], NULL, 0); - size = argc - 3; - uint8_t *data = rt_malloc(size); - if (data) { - for (i = 0; i < size; i++) { - data[i] = strtol(argv[3 + i], NULL, 0); - } - result = sfud_write(sfud_dev, addr, size, data); - if (result == SFUD_SUCCESS) { - rt_kprintf("Write the %s flash data success. Start from 0x%08X, size is %ld.\n", - sfud_dev->name, addr, size); - rt_kprintf("Write data: "); - for (i = 0; i < size; i++) { - rt_kprintf("%d ", data[i]); - } - rt_kprintf(".\n"); - } - rt_free(data); - } else { - rt_kprintf("Low memory!\n"); - } - } - } else if (!rt_strcmp(operator, "erase")) { - if (argc < 4) { - rt_kprintf("Usage: %s.\n", sf_help_info[CMD_ERASE_INDEX]); - return; - } else { - addr = strtol(argv[2], NULL, 0); - size = strtol(argv[3], NULL, 0); - result = sfud_erase(sfud_dev, addr, size); - if (result == SFUD_SUCCESS) { - rt_kprintf("Erase the %s flash data success. Start from 0x%08X, size is %ld.\n", sfud_dev->name, - addr, size); - } - } - } else if (!rt_strcmp(operator, "status")) { - if (argc < 3) { - uint8_t status; - result = sfud_read_status(sfud_dev, &status); - if (result == SFUD_SUCCESS) { - rt_kprintf("The %s flash status register current value is 0x%02X.\n", sfud_dev->name, status); - } - } else if (argc == 4) { - bool is_volatile = strtol(argv[2], NULL, 0); - uint8_t status = strtol(argv[3], NULL, 0); - result = sfud_write_status(sfud_dev, is_volatile, status); - if (result == SFUD_SUCCESS) { - rt_kprintf("Write the %s flash status register to 0x%02X success.\n", sfud_dev->name, status); - } - } else { - rt_kprintf("Usage: %s.\n", sf_help_info[CMD_RW_STATUS_INDEX]); - return; - } - } else if (!rt_strcmp(operator, "bench")) { - if ((argc > 2 && rt_strcmp(argv[2], "yes")) || argc < 3) { - rt_kprintf("DANGER: It will erase full chip! Please run 'sf bench yes'.\n"); - return; - } - /* full chip benchmark test */ - addr = 0; - size = sfud_dev->chip.capacity; - uint32_t start_time, time_cast; - size_t write_size = SFUD_WRITE_MAX_PAGE_SIZE, read_size = SFUD_WRITE_MAX_PAGE_SIZE, cur_op_size; - uint8_t *write_data = rt_malloc(write_size), *read_data = rt_malloc(read_size); - - if (write_data && read_data) { - for (i = 0; i < write_size; i ++) { - write_data[i] = i & 0xFF; - } - /* benchmark testing */ - rt_kprintf("Erasing the %s %ld bytes data, waiting...\n", sfud_dev->name, size); - start_time = rt_tick_get(); - result = sfud_erase(sfud_dev, addr, size); - if (result == SFUD_SUCCESS) { - time_cast = rt_tick_get() - start_time; - rt_kprintf("Erase benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND, - time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000)); - } else { - rt_kprintf("Erase benchmark has an error. Error code: %d.\n", result); - } - /* write test */ - rt_kprintf("Writing the %s %ld bytes data, waiting...\n", sfud_dev->name, size); - start_time = rt_tick_get(); - for (i = 0; i < size; i += write_size) { - if (i + write_size <= size) { - cur_op_size = write_size; - } else { - cur_op_size = size - i; - } - result = sfud_write(sfud_dev, addr + i, cur_op_size, write_data); - if (result != SFUD_SUCCESS) { - rt_kprintf("Writing %s failed, already wr for %lu bytes, write %d each time\n", sfud_dev->name, i, write_size); - break; - } - } - if (result == SFUD_SUCCESS) { - time_cast = rt_tick_get() - start_time; - rt_kprintf("Write benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND, - time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000)); - } else { - rt_kprintf("Write benchmark has an error. Error code: %d.\n", result); - } - /* read test */ - rt_kprintf("Reading the %s %ld bytes data, waiting...\n", sfud_dev->name, size); - start_time = rt_tick_get(); - for (i = 0; i < size; i += read_size) { - if (i + read_size <= size) { - cur_op_size = read_size; - } else { - cur_op_size = size - i; - } - result = sfud_read(sfud_dev, addr + i, cur_op_size, read_data); - /* data check */ - if (memcmp(write_data, read_data, cur_op_size)) - { - rt_kprintf("Data check ERROR! Please check you flash by other command.\n"); - result = SFUD_ERR_READ; - } - - if (result != SFUD_SUCCESS) { - rt_kprintf("Read %s failed, already rd for %lu bytes, read %d each time\n", sfud_dev->name, i, read_size); - break; - } - } - if (result == SFUD_SUCCESS) { - time_cast = rt_tick_get() - start_time; - rt_kprintf("Read benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND, - time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000)); - } else { - rt_kprintf("Read benchmark has an error. Error code: %d.\n", result); - } - } else { - rt_kprintf("Low memory!\n"); - } - rt_free(write_data); - rt_free(read_data); - } else { - rt_kprintf("Usage:\n"); - for (i = 0; i < sizeof(sf_help_info) / sizeof(char*); i++) { - rt_kprintf("%s\n", sf_help_info[i]); - } - rt_kprintf("\n"); - return; - } - if (result != SFUD_SUCCESS) { - rt_kprintf("This flash operate has an error. Error code: %d.\n", result); - } - } - } -} -MSH_CMD_EXPORT(sf, SPI Flash operate.); -#endif /* defined(RT_USING_FINSH) */ - -#endif /* RT_USING_SFUD */ diff --git a/rt-thread/components/drivers/spi/dev_spi_flash_sfud.h b/rt-thread/components/drivers/spi/dev_spi_flash_sfud.h deleted file mode 100644 index 5c3236f..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_flash_sfud.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2016-09-28 armink first version. - * 2024-10-24 yekai Add C++ support - */ - -#ifndef __DEV_SPI_FLASH_SFUD_H__ -#define __DEV_SPI_FLASH_SFUD_H__ - -#include -#include -#include "./sfud/inc/sfud.h" -#include "dev_spi_flash.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Probe SPI flash by SFUD(Serial Flash Universal Driver) driver library and though SPI device. - * - * @param spi_flash_dev_name the name which will create SPI flash device - * @param spi_dev_name using SPI device name - * - * @return probed SPI flash device, probe failed will return RT_NULL - */ -rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name); - -/** - * Probe SPI flash by SFUD (Serial Flash Universal Driver) driver library and though SPI device by specified configuration. - * - * @param spi_flash_dev_name the name which will create SPI flash device - * @param spi_dev_name using SPI device name - * @param spi_cfg SPI device configuration - * @param qspi_cfg QSPI device configuration - * - * @return probed SPI flash device, probe failed will return RT_NULL - */ -rt_spi_flash_device_t rt_sfud_flash_probe_ex(const char *spi_flash_dev_name, const char *spi_dev_name, - struct rt_spi_configuration *spi_cfg, struct rt_qspi_configuration *qspi_cfg); - -/** - * Delete SPI flash device - * - * @param spi_flash_dev SPI flash device - * - * @return the operation status, RT_EOK on successful - */ -rt_err_t rt_sfud_flash_delete(rt_spi_flash_device_t spi_flash_dev); - -/** - * Find sfud flash device by SPI device name - * - * @param spi_dev_name using SPI device name - * - * @return sfud flash device if success, otherwise return RT_NULL - */ -sfud_flash_t rt_sfud_flash_find(const char *spi_dev_name); - -/** - * Find sfud flash device by flash device name - * - * @param flash_dev_name using flash device name - * - * @return sfud flash device if success, otherwise return RT_NULL - */ -sfud_flash_t rt_sfud_flash_find_by_dev_name(const char *flash_dev_name); - -#ifdef __cplusplus -} -#endif - -#endif /* __DEV_SPI_FLASH_SFUD_H__ */ diff --git a/rt-thread/components/drivers/spi/dev_spi_msd.c b/rt-thread/components/drivers/spi/dev_spi_msd.c deleted file mode 100644 index 8d81e34..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_msd.c +++ /dev/null @@ -1,1660 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2009-04-17 Bernard first version. - * 2010-07-15 aozima Modify read/write according new block driver interface. - * 2012-02-01 aozima use new RT-Thread SPI drivers. - * 2012-04-11 aozima get max. data transfer rate from CSD[TRAN_SPEED]. - * 2012-05-21 aozima update MMC card support. - * 2018-03-09 aozima fixed CSD Version 2.0 sector count calc. - */ - -#include -#include "dev_spi_msd.h" - -//#define MSD_TRACE - -#ifdef MSD_TRACE - #define MSD_DEBUG(...) rt_kprintf("[MSD] %d ", rt_tick_get()); rt_kprintf(__VA_ARGS__); -#else - #define MSD_DEBUG(...) -#endif /* #ifdef MSD_TRACE */ - -#define DUMMY 0xFF - -#define CARD_NCR_MAX 9 - -#define CARD_NRC 1 -#define CARD_NCR 1 - -static struct msd_device _msd_device; - -/* function define */ -static rt_bool_t rt_tick_timeout(rt_tick_t tick_start, rt_tick_t tick_long); - -static rt_err_t MSD_take_owner(struct rt_spi_device *spi_device); - -static rt_err_t _wait_token(struct rt_spi_device *device, uint8_t token); -static rt_err_t _wait_ready(struct rt_spi_device *device); -static rt_err_t rt_msd_init(rt_device_t dev); -static rt_err_t rt_msd_open(rt_device_t dev, rt_uint16_t oflag); -static rt_err_t rt_msd_close(rt_device_t dev); -static rt_ssize_t rt_msd_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size); -static rt_ssize_t rt_msd_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); -static rt_ssize_t rt_msd_sdhc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); -static rt_ssize_t rt_msd_sdhc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size); -static rt_err_t rt_msd_control(rt_device_t dev, int cmd, void *args); - -static rt_err_t MSD_take_owner(struct rt_spi_device *spi_device) -{ - rt_err_t result; - - result = rt_mutex_take(&(spi_device->bus->lock), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - if (spi_device->bus->owner != spi_device) - { - /* not the same owner as current, re-configure SPI bus */ - result = spi_device->bus->ops->configure(spi_device, &spi_device->config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - spi_device->bus->owner = spi_device; - } - } - } - - return result; -} - -static rt_bool_t rt_tick_timeout(rt_tick_t tick_start, rt_tick_t tick_long) -{ - rt_tick_t tick_end = tick_start + tick_long; - rt_tick_t tick_now = rt_tick_get(); - rt_bool_t result = RT_FALSE; - - if (tick_end >= tick_start) - { - if (tick_now >= tick_end) - { - result = RT_TRUE; - } - else - { - result = RT_FALSE; - } - } - else - { - if ((tick_now < tick_start) && (tick_now >= tick_end)) - { - result = RT_TRUE; - } - else - { - result = RT_FALSE; - } - } - - return result; -} - -static uint8_t crc7(const uint8_t *buf, int len) -{ - unsigned char i, j, crc, ch, ch2, ch3; - - crc = 0; - - for (i = 0; i < len; i ++) - { - ch = buf[i]; - - for (j = 0; j < 8; j ++, ch <<= 1) - { - ch2 = (crc & 0x40) ? 1 : 0; - ch3 = (ch & 0x80) ? 1 : 0; - - if (ch2 ^ ch3) - { - crc ^= 0x04; - crc <<= 1; - crc |= 0x01; - } - else - { - crc <<= 1; - } - } - } - - return crc; -} - -static rt_err_t _send_cmd( - struct rt_spi_device *device, - uint8_t cmd, - uint32_t arg, - uint8_t crc, - response_type type, - uint8_t *response -) -{ - struct rt_spi_message message; - uint8_t cmd_buffer[8]; - uint8_t recv_buffer[sizeof(cmd_buffer)]; - uint32_t i; - - cmd_buffer[0] = DUMMY; - cmd_buffer[1] = (cmd | 0x40); - cmd_buffer[2] = (uint8_t)(arg >> 24); - cmd_buffer[3] = (uint8_t)(arg >> 16); - cmd_buffer[4] = (uint8_t)(arg >> 8); - cmd_buffer[5] = (uint8_t)(arg); - - if (crc == 0x00) - { - crc = crc7(&cmd_buffer[1], 5); - crc = (crc << 1) | 0x01; - } - cmd_buffer[6] = (crc); - - cmd_buffer[7] = DUMMY; - - /* initial message */ - message.send_buf = cmd_buffer; - message.recv_buf = recv_buffer; - message.length = sizeof(cmd_buffer); - message.cs_take = message.cs_release = 0; - - _wait_ready(device); - - /* transfer message */ - device->bus->ops->xfer(device, &message); - - for (i = CARD_NCR; i < (CARD_NCR_MAX + 1); i++) - { - uint8_t send = DUMMY; - - /* initial message */ - message.send_buf = &send; - message.recv_buf = response; - message.length = 1; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - - if (0 == (response[0] & 0x80)) - { - break; - } - } /* wait response */ - - if ((CARD_NCR_MAX + 1) == i) - { - return -RT_ERROR;//fail - } - - //recieve other byte - if (type == response_r1) - { - return RT_EOK; - } - else if (type == response_r1b) - { - rt_tick_t tick_start = rt_tick_get(); - uint8_t recv; - - while (1) - { - /* initial message */ - message.send_buf = RT_NULL; - message.recv_buf = &recv; - message.length = 1; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - - if (recv == DUMMY) - { - return RT_EOK; - } - - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(2000))) - { - return -RT_ETIMEOUT; - } - } - } - else if (type == response_r2) - { - /* initial message */ - /* Prevent non-aligned address access, use recv_buffer to receive data */ - message.send_buf = RT_NULL; - message.recv_buf = recv_buffer; - message.length = 1; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - response[1] = recv_buffer[0]; - } - else if ((type == response_r3) || (type == response_r7)) - { - /* initial message */ - message.send_buf = RT_NULL; - message.recv_buf = recv_buffer; - message.length = 4; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - response[1] = recv_buffer[0]; - response[2] = recv_buffer[1]; - response[3] = recv_buffer[2]; - response[4] = recv_buffer[3]; - } - else - { - return -RT_ERROR; // unknow type? - } - - return RT_EOK; -} - -static rt_err_t _wait_token(struct rt_spi_device *device, uint8_t token) -{ - struct rt_spi_message message; - rt_tick_t tick_start; - uint8_t send, recv; - - tick_start = rt_tick_get(); - - /* wati token */ - /* initial message */ - send = DUMMY; - message.send_buf = &send; - message.recv_buf = &recv; - message.length = 1; - message.cs_take = message.cs_release = 0; - - while (1) - { - /* transfer message */ - device->bus->ops->xfer(device, &message); - - if (recv == token) - { - return RT_EOK; - } - - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_WAIT_TOKEN_TIMES))) - { - MSD_DEBUG("[err] wait data start token timeout!\r\n"); - return -RT_ETIMEOUT; - } - } /* wati token */ -} - -static rt_err_t _wait_ready(struct rt_spi_device *device) -{ - struct rt_spi_message message; - rt_tick_t tick_start; - uint8_t send, recv; - - tick_start = rt_tick_get(); - - send = DUMMY; - /* initial message */ - message.send_buf = &send; - message.recv_buf = &recv; - message.length = 1; - message.cs_take = message.cs_release = 0; - - while (1) - { - /* transfer message */ - device->bus->ops->xfer(device, &message); - - if (recv == DUMMY) - { - return RT_EOK; - } - - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(1000))) - { - MSD_DEBUG("[err] wait ready timeout!\r\n"); - return -RT_ETIMEOUT; - } - } -} - -static rt_err_t _read_block(struct rt_spi_device *device, void *buffer, uint32_t block_size) -{ - struct rt_spi_message message; - rt_err_t result; - - /* wati token */ - result = _wait_token(device, MSD_TOKEN_READ_START); - if (result != RT_EOK) - { - return result; - } - - /* read data */ - { - /* initial message */ - message.send_buf = RT_NULL; - message.recv_buf = buffer; - message.length = block_size; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - } /* read data */ - - /* get crc */ - { - uint8_t recv_buffer[2]; - - /* initial message */ - message.send_buf = RT_NULL; - message.recv_buf = recv_buffer; - message.length = 2; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - } /* get crc */ - - return RT_EOK; -} - -static rt_err_t _write_block(struct rt_spi_device *device, const void *buffer, uint32_t block_size, uint8_t token) -{ - struct rt_spi_message message; - uint8_t send_buffer[16]; - - rt_memset(send_buffer, DUMMY, sizeof(send_buffer)); - send_buffer[sizeof(send_buffer) - 1] = token; - - /* send start block token */ - { - /* initial message */ - message.send_buf = send_buffer; - message.recv_buf = RT_NULL; - message.length = sizeof(send_buffer); - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - } - - /* send data */ - { - /* initial message */ - message.send_buf = buffer; - message.recv_buf = RT_NULL; - message.length = block_size; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - } - - /* put crc and get data response */ - { - uint8_t recv_buffer[3]; - uint8_t response; - - /* initial message */ - message.send_buf = send_buffer; - message.recv_buf = recv_buffer; - message.length = sizeof(recv_buffer); - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - -// response = 0x0E & recv_buffer[2]; - response = MSD_GET_DATA_RESPONSE(recv_buffer[2]); - if (response != MSD_DATA_OK) - { - MSD_DEBUG("[err] write block fail! data response : 0x%02X\r\n", response); - return -RT_ERROR; - } - } - - /* wati ready */ - return _wait_ready(device); -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops msd_ops = -{ - rt_msd_init, - rt_msd_open, - rt_msd_close, - rt_msd_read, - rt_msd_write, - rt_msd_control -}; - -const static struct rt_device_ops msd_sdhc_ops = -{ - rt_msd_init, - rt_msd_open, - rt_msd_close, - rt_msd_sdhc_read, - rt_msd_sdhc_write, - rt_msd_control -}; -#endif - -/* RT-Thread Device Driver Interface */ -static rt_err_t rt_msd_init(rt_device_t dev) -{ - struct msd_device *msd = (struct msd_device *)dev; - uint8_t response[MSD_RESPONSE_MAX_LEN]; - rt_err_t result = RT_EOK; - rt_tick_t tick_start; - uint32_t OCR; - - if (msd->spi_device == RT_NULL) - { - MSD_DEBUG("[err] the SPI SD device has no SPI!\r\n"); - return -RT_EIO; - } - - /* config spi */ - { - struct rt_spi_configuration cfg; - cfg.data_width = 8; - cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 */ - cfg.max_hz = 1000 * 400; /* 400kbit/s */ - rt_spi_configure(msd->spi_device, &cfg); - } /* config spi */ - - /* init SD card */ - { - struct rt_spi_message message; - - result = MSD_take_owner(msd->spi_device); - - if (result != RT_EOK) - { - goto _exit; - } - - rt_spi_release(msd->spi_device); - - /* The host shall supply power to the card so that the voltage is reached to Vdd_min within 250ms and - start to supply at least 74 SD clocks to the SD card with keeping CMD line to high. - In case of SPI mode, CS shall be held to high during 74 clock cycles. */ - { - uint8_t send_buffer[100]; /* 100byte > 74 clock */ - - /* initial message */ - rt_memset(send_buffer, DUMMY, sizeof(send_buffer)); - message.send_buf = send_buffer; - message.recv_buf = RT_NULL; - message.length = sizeof(send_buffer); - message.cs_take = message.cs_release = 0; - - /* transfer message */ - msd->spi_device->bus->ops->xfer(msd->spi_device, &message); - } /* send 74 clock */ - - /* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */ - { - tick_start = rt_tick_get(); - - while (1) - { - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, GO_IDLE_STATE, 0x00, 0x95, response_r1, response); - rt_spi_release(msd->spi_device); - - if ((result == RT_EOK) && (response[0] == MSD_IN_IDLE_STATE)) - { - break; - } - - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES))) - { - MSD_DEBUG("[err] SD card goto IDLE mode timeout!\r\n"); - result = -RT_ETIMEOUT; - goto _exit; - } - } - - MSD_DEBUG("[info] SD card goto IDLE mode OK!\r\n"); - } /* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */ - - /* CMD8 */ - { - tick_start = rt_tick_get(); - - do - { - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, SEND_IF_COND, 0x01AA, 0x87, response_r7, response); - rt_spi_release(msd->spi_device); - - if (result == RT_EOK) - { - MSD_DEBUG("[info] CMD8 response : 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\r\n", - response[0], response[1], response[2], response[3], response[4]); - - if (response[0] & (1 << 2)) - { - /* illegal command, SD V1.x or MMC card */ - MSD_DEBUG("[info] CMD8 is illegal command.\r\n"); - MSD_DEBUG("[info] maybe Ver1.X SD Memory Card or MMC card!\r\n"); - msd->card_type = MSD_CARD_TYPE_SD_V1_X; - break; - } - else - { - /* SD V2.0 or later or SDHC or SDXC memory card! */ - MSD_DEBUG("[info] Ver2.00 or later or SDHC or SDXC memory card!\r\n"); - msd->card_type = MSD_CARD_TYPE_SD_V2_X; - } - - if ((0xAA == response[4]) && (0x00 == response[3])) - { - /* SD2.0 not support current voltage */ - MSD_DEBUG("[err] VCA = 0, SD2.0 not surpport current operation voltage range\r\n"); - result = -RT_ERROR; - goto _exit; - } - } - else - { - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(200))) - { - MSD_DEBUG("[err] CMD8 SEND_IF_COND timeout!\r\n"); - result = -RT_ETIMEOUT; - goto _exit; - } - } - } - while (0xAA != response[4]); - } /* CMD8 */ - - /* Ver1.X SD Memory Card or MMC card */ - if (msd->card_type == MSD_CARD_TYPE_SD_V1_X) - { - rt_bool_t is_sd_v1_x = RT_FALSE; - rt_tick_t tick_start; - - /* try SD Ver1.x */ - while (1) - { - rt_spi_take(msd->spi_device); - - result = _send_cmd(msd->spi_device, READ_OCR, 0x00, 0x00, response_r3, response); - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[info] It maybe SD1.x or MMC But it is Not response to CMD58!\r\n"); - goto _exit; - } - - if (0 != (response[0] & 0xFE)) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[info] It look CMD58 as illegal command so it is not SD card!\r\n"); - break; - } - rt_spi_release(msd->spi_device); - - OCR = response[1]; - OCR = (OCR << 8) + response[2]; - OCR = (OCR << 8) + response[3]; - OCR = (OCR << 8) + response[4]; - MSD_DEBUG("[info] OCR is 0x%08X\r\n", OCR); - - if (0 == (OCR & (0x1 << 15))) - { - MSD_DEBUG(("[err] SD 1.x But not surpport current voltage\r\n")); - result = -RT_ERROR; - goto _exit; - } - - /* --Send ACMD41 to make card ready */ - tick_start = rt_tick_get(); - - /* try CMD55 + ACMD41 */ - while (1) - { - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES_ACMD41))) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[info] try CMD55 + ACMD41 timeout! mabey MMC card!\r\n"); - break; - } - - rt_spi_take(msd->spi_device); - - /* CMD55 APP_CMD */ - result = _send_cmd(msd->spi_device, APP_CMD, 0x00, 0x00, response_r1, response); - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - continue; - } - - if (0 != (response[0] & 0xFE)) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[info] Not SD card2 , may be MMC\r\n"); - break; - } - - /* ACMD41 SD_SEND_OP_COND */ - result = _send_cmd(msd->spi_device, SD_SEND_OP_COND, 0x00, 0x00, response_r1, response); - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - continue; - } - - if (0 != (response[0] & 0xFE)) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[info] Not SD card4 , may be MMC\r\n"); - break; - } - - if (0 == (response[0] & 0xFF)) - { - rt_spi_release(msd->spi_device); - is_sd_v1_x = RT_TRUE; - MSD_DEBUG("[info] It is Ver1.X SD Memory Card!!!\r\n"); - break; - } - } /* try CMD55 + ACMD41 */ - - break; - } /* try SD Ver1.x */ - - /* try MMC */ - if (is_sd_v1_x != RT_TRUE) - { - uint32_t i; - - MSD_DEBUG("[info] try MMC card!\r\n"); - rt_spi_release(msd->spi_device); - - /* send dummy clock */ - { - uint8_t send_buffer[100]; - - /* initial message */ - rt_memset(send_buffer, DUMMY, sizeof(send_buffer)); - message.send_buf = send_buffer; - message.recv_buf = RT_NULL; - message.length = sizeof(send_buffer); - message.cs_take = message.cs_release = 0; - - for (i = 0; i < 10; i++) - { - /* transfer message */ - msd->spi_device->bus->ops->xfer(msd->spi_device, &message); - } - } /* send dummy clock */ - - /* send CMD0 goto IDLE state */ - tick_start = rt_tick_get(); - while (1) - { - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, GO_IDLE_STATE, 0x00, 0x95, response_r1, response); - rt_spi_release(msd->spi_device); - - if ((result == RT_EOK) && (response[0] == MSD_IN_IDLE_STATE)) - { - break; - } - - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES))) - { - MSD_DEBUG("[err] SD card goto IDLE mode timeout!\r\n"); - result = -RT_ETIMEOUT; - goto _exit; - } - } /* send CMD0 goto IDLE stat */ - - /* send CMD1 */ - tick_start = rt_tick_get(); - while (1) - { - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, SEND_OP_COND, 0x00, 0x00, response_r1, response); - rt_spi_release(msd->spi_device); - - if ((result == RT_EOK) && (response[0] == MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[info] It is MMC card!!!\r\n"); - msd->card_type = MSD_CARD_TYPE_MMC; - break; - } - - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES))) - { - MSD_DEBUG("[err] SD card goto IDLE mode timeout!\r\n"); - result = -RT_ETIMEOUT; - goto _exit; - } - } /* send CMD1 */ - } /* try MMC */ - } - else if (msd->card_type == MSD_CARD_TYPE_SD_V2_X) - { - rt_spi_take(msd->spi_device); - - result = _send_cmd(msd->spi_device, READ_OCR, 0x00, 0x00, response_r3, response); - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] It maybe SD2.0 But it is Not response to CMD58!\r\n"); - goto _exit; - } - - if ((response[0] & 0xFE) != 0) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] It look CMD58 as illegal command so it is not SD card!\r\n"); - result = -RT_ERROR; - goto _exit; - } - - rt_spi_release(msd->spi_device); - - OCR = response[1]; - OCR = (OCR << 8) + response[2]; - OCR = (OCR << 8) + response[3]; - OCR = (OCR << 8) + response[4]; - MSD_DEBUG("[info] OCR is 0x%08X\r\n", OCR); - - if (0 == (OCR & (0x1 << 15))) - { - MSD_DEBUG(("[err] SD 1.x But not surpport current voltage\r\n")); - result = -RT_ERROR; - goto _exit; - } - - /* --Send ACMD41 to make card ready */ - tick_start = rt_tick_get(); - - /* try CMD55 + ACMD41 */ - do - { - rt_spi_take(msd->spi_device); - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES_ACMD41))) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] SD Ver2.x or later try CMD55 + ACMD41 timeout!\r\n"); - result = -RT_ERROR; - goto _exit; - } - - /* CMD55 APP_CMD */ - result = _send_cmd(msd->spi_device, APP_CMD, 0x00, 0x65, response_r1, response); -// if((result != RT_EOK) || (response[0] == 0x01)) - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - continue; - } - - if ((response[0] & 0xFE) != 0) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] Not SD ready!\r\n"); - result = -RT_ERROR; - goto _exit; - } - - /* ACMD41 SD_SEND_OP_COND */ - result = _send_cmd(msd->spi_device, SD_SEND_OP_COND, 0x40000000, 0x77, response_r1, response); - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] ACMD41 fail!\r\n"); - result = -RT_ERROR; - goto _exit; - } - - if ((response[0] & 0xFE) != 0) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[info] Not SD card4 , response : 0x%02X\r\n", response[0]); -// break; - } - } - while (response[0] != MSD_RESPONSE_NO_ERROR); - rt_spi_release(msd->spi_device); - /* try CMD55 + ACMD41 */ - - /* --Read OCR again */ - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, READ_OCR, 0x00, 0x00, response_r3, response); - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] It maybe SD2.0 But it is Not response to 2nd CMD58!\r\n"); - goto _exit; - } - - if ((response[0] & 0xFE) != 0) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] It look 2nd CMD58 as illegal command so it is not SD card!\r\n"); - result = -RT_ERROR; - goto _exit; - } - rt_spi_release(msd->spi_device); - - OCR = response[1]; - OCR = (OCR << 8) + response[2]; - OCR = (OCR << 8) + response[3]; - OCR = (OCR << 8) + response[4]; - MSD_DEBUG("[info] OCR 2nd read is 0x%08X\r\n", OCR); - - if ((OCR & 0x40000000) != 0) - { - MSD_DEBUG("[info] It is SD2.0 SDHC Card!!!\r\n"); - msd->card_type = MSD_CARD_TYPE_SD_SDHC; - } - else - { - MSD_DEBUG("[info] It is SD2.0 standard capacity Card!!!\r\n"); - } - } /* MSD_CARD_TYPE_SD_V2_X */ - else - { - MSD_DEBUG("[err] SD card type unkonw!\r\n"); - result = -RT_ERROR; - goto _exit; - } - } /* init SD card */ - - if (msd->card_type == MSD_CARD_TYPE_SD_SDHC) - { -#ifdef RT_USING_DEVICE_OPS - dev->ops = &msd_sdhc_ops; -#else - dev->read = rt_msd_sdhc_read; - dev->write = rt_msd_sdhc_write; -#endif - } - else - { -#ifdef RT_USING_DEVICE_OPS - dev->ops = &msd_ops; -#else - dev->read = rt_msd_read; - dev->write = rt_msd_write; -#endif - } - - /* set CRC */ - { - rt_spi_release(msd->spi_device); - rt_spi_take(msd->spi_device); -#ifdef MSD_USE_CRC - result = _send_cmd(msd->spi_device, CRC_ON_OFF, 0x01, 0x83, response_r1, response); -#else - result = _send_cmd(msd->spi_device, CRC_ON_OFF, 0x00, 0x91, response_r1, response); -#endif - rt_spi_release(msd->spi_device); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD59 CRC_ON_OFF fail! response : 0x%02X\r\n", response[0]); - result = -RT_ERROR; - goto _exit; - } - } /* set CRC */ - - /* CMD16 SET_BLOCKLEN */ - { - rt_spi_release(msd->spi_device); - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, SET_BLOCKLEN, SECTOR_SIZE, 0x00, response_r1, response); - rt_spi_release(msd->spi_device); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD16 SET_BLOCKLEN fail! response : 0x%02X\r\n", response[0]); - result = -RT_ERROR; - goto _exit; - } - msd->geometry.block_size = SECTOR_SIZE; - msd->geometry.bytes_per_sector = SECTOR_SIZE; - } - - /* read CSD */ - { - uint8_t CSD_buffer[MSD_CSD_LEN]; - - rt_spi_take(msd->spi_device); -// result = _send_cmd(msd->spi_device, SEND_CSD, 0x00, 0xAF, response_r1, response); - result = _send_cmd(msd->spi_device, SEND_CSD, 0x00, 0x00, response_r1, response); - - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] CMD9 SEND_CSD timeout!\r\n"); - goto _exit; - } - - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] CMD9 SEND_CSD fail! response : 0x%02X\r\n", response[0]); - result = -RT_ERROR; - goto _exit; - } - - result = _read_block(msd->spi_device, CSD_buffer, MSD_CSD_LEN); - rt_spi_release(msd->spi_device); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read CSD fail!\r\n"); - goto _exit; - } - - /* Analyze CSD */ - { - uint8_t CSD_STRUCTURE; - uint32_t C_SIZE; - uint32_t card_capacity; - - uint8_t tmp8; - uint16_t tmp16; - uint32_t tmp32; - - /* get CSD_STRUCTURE */ - tmp8 = CSD_buffer[0] & 0xC0; /* 0b11000000 */ - CSD_STRUCTURE = tmp8 >> 6; - - /* MMC CSD Analyze. */ - if (msd->card_type == MSD_CARD_TYPE_MMC) - { - uint8_t C_SIZE_MULT; - uint8_t READ_BL_LEN; - - if (CSD_STRUCTURE > 2) - { - MSD_DEBUG("[err] bad CSD Version : %d\r\n", CSD_STRUCTURE); - result = -RT_ERROR; - goto _exit; - } - - if (CSD_STRUCTURE == 0) - { - MSD_DEBUG("[info] CSD version No. 1.0\r\n"); - } - else if (CSD_STRUCTURE == 1) - { - MSD_DEBUG("[info] CSD version No. 1.1\r\n"); - } - else if (CSD_STRUCTURE == 2) - { - MSD_DEBUG("[info] CSD version No. 1.2\r\n"); - } - - /* get TRAN_SPEED 8bit [103:96] */ - tmp8 = CSD_buffer[3]; - tmp8 &= 0x03; /* [2:0] transfer rate unit.*/ - if (tmp8 == 0) - { - msd->max_clock = 100 * 1000; /* 0=100kbit/s. */ - } - else if (tmp8 == 1) - { - msd->max_clock = 1 * 1000 * 1000; /* 1=1Mbit/s. */ - } - else if (tmp8 == 2) - { - msd->max_clock = 10 * 1000 * 1000; /* 2=10Mbit/s. */ - } - else if (tmp8 == 3) - { - msd->max_clock = 100 * 1000 * 1000; /* 3=100Mbit/s. */ - } - if (tmp8 == 0) - { - MSD_DEBUG("[info] TRAN_SPEED: 0x%02X, %dkbit/s.\r\n", tmp8, msd->max_clock / 1000); - } - else - { - MSD_DEBUG("[info] TRAN_SPEED: 0x%02X, %dMbit/s.\r\n", tmp8, msd->max_clock / 1000 / 1000); - } - - /* get READ_BL_LEN 4bit [83:80] */ - tmp8 = CSD_buffer[5] & 0x0F; /* 0b00001111; */ - READ_BL_LEN = tmp8; /* 4 bit */ - MSD_DEBUG("[info] CSD : READ_BL_LEN : %d %dbyte\r\n", READ_BL_LEN, (1 << READ_BL_LEN)); - - /* get C_SIZE 12bit [73:62] */ - tmp16 = CSD_buffer[6] & 0x03; /* get [73:72] 0b00000011 */ - tmp16 = tmp16 << 8; - tmp16 += CSD_buffer[7]; /* get [71:64] */ - tmp16 = tmp16 << 2; - tmp8 = CSD_buffer[8] & 0xC0; /* get [63:62] 0b11000000 */ - tmp8 = tmp8 >> 6; - tmp16 = tmp16 + tmp8; - C_SIZE = tmp16; //12 bit - MSD_DEBUG("[info] CSD : C_SIZE : %d\r\n", C_SIZE); - - /* get C_SIZE_MULT 3bit [49:47] */ - tmp8 = CSD_buffer[9] & 0x03;//0b00000011; - tmp8 = tmp8 << 1; - tmp8 = tmp8 + ((CSD_buffer[10] & 0x80/*0b10000000*/) >> 7); - C_SIZE_MULT = tmp8; // 3 bit - MSD_DEBUG("[info] CSD : C_SIZE_MULT : %d\r\n", C_SIZE_MULT); - - /* memory capacity = BLOCKNR * BLOCK_LEN */ - /* BLOCKNR = (C_SIZE+1) * MULT */ - /* MULT = 2^(C_SIZE_MULT+2) */ - /* BLOCK_LEN = 2^READ_BL_LEN */ - card_capacity = (1 << READ_BL_LEN) * ((C_SIZE + 1) * (1 << (C_SIZE_MULT + 2))); - msd->geometry.sector_count = card_capacity / msd->geometry.bytes_per_sector; - MSD_DEBUG("[info] card capacity : %d Mbyte\r\n", card_capacity / (1024 * 1024)); - } - else /* SD CSD Analyze. */ - { - if (CSD_STRUCTURE == 0) - { - uint8_t C_SIZE_MULT; - uint8_t READ_BL_LEN; - - MSD_DEBUG("[info] CSD Version 1.0\r\n"); - - /* get TRAN_SPEED 8bit [103:96] */ - tmp8 = CSD_buffer[3]; - if (tmp8 == 0x32) - { - msd->max_clock = 1000 * 1000 * 10; /* 10Mbit/s. */ - } - else if (tmp8 == 0x5A) - { - msd->max_clock = 1000 * 1000 * 50; /* 50Mbit/s. */ - } - else - { - msd->max_clock = 1000 * 1000 * 1; /* 1Mbit/s default. */ - } - MSD_DEBUG("[info] TRAN_SPEED: 0x%02X, %dMbit/s.\r\n", tmp8, msd->max_clock / 1000 / 1000); - - /* get READ_BL_LEN 4bit [83:80] */ - tmp8 = CSD_buffer[5] & 0x0F; /* 0b00001111; */ - READ_BL_LEN = tmp8; /* 4 bit */ - MSD_DEBUG("[info] CSD : READ_BL_LEN : %d %dbyte\r\n", READ_BL_LEN, (1 << READ_BL_LEN)); - - /* get C_SIZE 12bit [73:62] */ - tmp16 = CSD_buffer[6] & 0x03; /* get [73:72] 0b00000011 */ - tmp16 = tmp16 << 8; - tmp16 += CSD_buffer[7]; /* get [71:64] */ - tmp16 = tmp16 << 2; - tmp8 = CSD_buffer[8] & 0xC0; /* get [63:62] 0b11000000 */ - tmp8 = tmp8 >> 6; - tmp16 = tmp16 + tmp8; - C_SIZE = tmp16; //12 bit - MSD_DEBUG("[info] CSD : C_SIZE : %d\r\n", C_SIZE); - - /* get C_SIZE_MULT 3bit [49:47] */ - tmp8 = CSD_buffer[9] & 0x03;//0b00000011; - tmp8 = tmp8 << 1; - tmp8 = tmp8 + ((CSD_buffer[10] & 0x80/*0b10000000*/) >> 7); - C_SIZE_MULT = tmp8; // 3 bit - MSD_DEBUG("[info] CSD : C_SIZE_MULT : %d\r\n", C_SIZE_MULT); - - /* memory capacity = BLOCKNR * BLOCK_LEN */ - /* BLOCKNR = (C_SIZE+1) * MULT */ - /* MULT = 2^(C_SIZE_MULT+2) */ - /* BLOCK_LEN = 2^READ_BL_LEN */ - card_capacity = (1 << READ_BL_LEN) * ((C_SIZE + 1) * (1 << (C_SIZE_MULT + 2))); - msd->geometry.sector_count = card_capacity / msd->geometry.bytes_per_sector; - MSD_DEBUG("[info] card capacity : %d Mbyte\r\n", card_capacity / (1024 * 1024)); - } - else if (CSD_STRUCTURE == 1) - { - MSD_DEBUG("[info] CSD Version 2.0\r\n"); - - /* get TRAN_SPEED 8bit [103:96] */ - tmp8 = CSD_buffer[3]; - if (tmp8 == 0x32) - { - msd->max_clock = 1000 * 1000 * 10; /* 10Mbit/s. */ - } - else if (tmp8 == 0x5A) - { - msd->max_clock = 1000 * 1000 * 50; /* 50Mbit/s. */ - } - else if (tmp8 == 0x0B) - { - msd->max_clock = 1000 * 1000 * 100; /* 100Mbit/s. */ - /* UHS50 Card sets TRAN_SPEED to 0Bh (100Mbit/sec), */ - /* for both SDR50 and DDR50 modes. */ - } - else if (tmp8 == 0x2B) - { - msd->max_clock = 1000 * 1000 * 200; /* 200Mbit/s. */ - /* UHS104 Card sets TRAN_SPEED to 2Bh (200Mbit/sec). */ - } - else - { - msd->max_clock = 1000 * 1000 * 1; /* 1Mbit/s default. */ - } - MSD_DEBUG("[info] TRAN_SPEED: 0x%02X, %dMbit/s.\r\n", tmp8, msd->max_clock / 1000 / 1000); - - /* get C_SIZE 22bit [69:48] */ - tmp32 = CSD_buffer[7] & 0x3F; /* 0b00111111 */ - tmp32 = tmp32 << 8; - tmp32 += CSD_buffer[8]; - tmp32 = tmp32 << 8; - tmp32 += CSD_buffer[9]; - C_SIZE = tmp32; - MSD_DEBUG("[info] CSD : C_SIZE : %d\r\n", C_SIZE); - - /* memory capacity = (C_SIZE+1) * 512K byte */ - card_capacity = (C_SIZE + 1) / 2; /* unit : Mbyte */ - msd->geometry.sector_count = (C_SIZE + 1) * 1024; /* 512KB = 1024sector */ - MSD_DEBUG("[info] card capacity : %d.%d Gbyte\r\n", card_capacity / 1024, (card_capacity % 1024) * 100 / 1024); - MSD_DEBUG("[info] sector_count : %d\r\n", msd->geometry.sector_count); - } - else - { - MSD_DEBUG("[err] bad CSD Version : %d\r\n", CSD_STRUCTURE); - result = -RT_ERROR; - goto _exit; - } - } /* SD CSD Analyze. */ - } /* Analyze CSD */ - - } /* read CSD */ - - /* config spi to high speed */ - { - struct rt_spi_configuration cfg; - cfg.data_width = 8; - cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 */ - cfg.max_hz = msd->max_clock; - rt_spi_configure(msd->spi_device, &cfg); - } /* config spi */ - -_exit: - rt_spi_release(msd->spi_device); - rt_mutex_release(&(msd->spi_device->bus->lock)); - return result; -} - -static rt_err_t rt_msd_open(rt_device_t dev, rt_uint16_t oflag) -{ -// struct msd_device * msd = (struct msd_device *)dev; - return RT_EOK; -} - -static rt_err_t rt_msd_close(rt_device_t dev) -{ -// struct msd_device * msd = (struct msd_device *)dev; - return RT_EOK; -} - -static rt_ssize_t rt_msd_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - struct msd_device *msd = (struct msd_device *)dev; - uint8_t response[MSD_RESPONSE_MAX_LEN]; - rt_err_t result = RT_EOK; - - result = MSD_take_owner(msd->spi_device); - - if (result != RT_EOK) - { - goto _exit; - } - - /* SINGLE_BLOCK? */ - if (size == 1) - { - rt_spi_take(msd->spi_device); - - result = _send_cmd(msd->spi_device, READ_SINGLE_BLOCK, pos * msd->geometry.bytes_per_sector, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] read SINGLE_BLOCK #%d fail!\r\n", pos); - size = 0; - goto _exit; - } - - result = _read_block(msd->spi_device, buffer, msd->geometry.bytes_per_sector); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read SINGLE_BLOCK #%d fail!\r\n", pos); - size = 0; - } - } - else if (size > 1) - { - uint32_t i; - - rt_spi_take(msd->spi_device); - - result = _send_cmd(msd->spi_device, READ_MULTIPLE_BLOCK, pos * msd->geometry.bytes_per_sector, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK #%d fail!\r\n", pos); - size = 0; - goto _exit; - } - - for (i = 0; i < size; i++) - { - result = _read_block(msd->spi_device, - (uint8_t *)buffer + msd->geometry.bytes_per_sector * i, - msd->geometry.bytes_per_sector); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK #%d fail!\r\n", pos); - size = i; - break; - } - } - - /* send CMD12 stop transfer */ - result = _send_cmd(msd->spi_device, STOP_TRANSMISSION, 0x00, 0x00, response_r1b, response); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK, send stop token fail!\r\n"); - } - } /* READ_MULTIPLE_BLOCK */ - -_exit: - /* release and exit */ - rt_spi_release(msd->spi_device); - rt_mutex_release(&(msd->spi_device->bus->lock)); - - return size; -} - -static rt_ssize_t rt_msd_sdhc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - struct msd_device *msd = (struct msd_device *)dev; - uint8_t response[MSD_RESPONSE_MAX_LEN]; - rt_err_t result = RT_EOK; - - result = MSD_take_owner(msd->spi_device); - - if (result != RT_EOK) - { - goto _exit; - } - - /* SINGLE_BLOCK? */ - if (size == 1) - { - rt_spi_take(msd->spi_device); - - result = _send_cmd(msd->spi_device, READ_SINGLE_BLOCK, pos, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] read SINGLE_BLOCK #%d fail!\r\n", pos); - size = 0; - goto _exit; - } - - result = _read_block(msd->spi_device, buffer, msd->geometry.bytes_per_sector); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read SINGLE_BLOCK #%d fail!\r\n", pos); - size = 0; - } - } - else if (size > 1) - { - uint32_t i; - - rt_spi_take(msd->spi_device); - - result = _send_cmd(msd->spi_device, READ_MULTIPLE_BLOCK, pos, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK #%d fail!\r\n", pos); - size = 0; - goto _exit; - } - - for (i = 0; i < size; i++) - { - result = _read_block(msd->spi_device, - (uint8_t *)buffer + msd->geometry.bytes_per_sector * i, - msd->geometry.bytes_per_sector); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK #%d fail!\r\n", pos); - size = i; - break; - } - } - - /* send CMD12 stop transfer */ - result = _send_cmd(msd->spi_device, STOP_TRANSMISSION, 0x00, 0x00, response_r1b, response); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK, send stop token fail!\r\n"); - } - } /* READ_MULTIPLE_BLOCK */ - -_exit: - /* release and exit */ - rt_spi_release(msd->spi_device); - rt_mutex_release(&(msd->spi_device->bus->lock)); - - return size; -} - -static rt_ssize_t rt_msd_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - struct msd_device *msd = (struct msd_device *)dev; - uint8_t response[MSD_RESPONSE_MAX_LEN]; - rt_err_t result; - - result = MSD_take_owner(msd->spi_device); - - if (result != RT_EOK) - { - MSD_DEBUG("[err] get SPI owner fail!\r\n"); - goto _exit; - } - - - /* SINGLE_BLOCK? */ - if (size == 1) - { - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, WRITE_BLOCK, pos * msd->geometry.bytes_per_sector, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD WRITE_BLOCK fail!\r\n"); - size = 0; - goto _exit; - } - - result = _write_block(msd->spi_device, buffer, msd->geometry.bytes_per_sector, MSD_TOKEN_WRITE_SINGLE_START); - if (result != RT_EOK) - { - MSD_DEBUG("[err] write SINGLE_BLOCK #%d fail!\r\n", pos); - size = 0; - } - } - else if (size > 1) - { - struct rt_spi_message message; - uint32_t i; - - rt_spi_take(msd->spi_device); - -#ifdef MSD_USE_PRE_ERASED - if (msd->card_type != MSD_CARD_TYPE_MMC) - { - /* CMD55 APP_CMD */ - result = _send_cmd(msd->spi_device, APP_CMD, 0x00, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD55 APP_CMD fail!\r\n"); - size = 0; - goto _exit; - } - - /* ACMD23 Pre-erased */ - result = _send_cmd(msd->spi_device, SET_WR_BLK_ERASE_COUNT, size, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] ACMD23 SET_BLOCK_COUNT fail!\r\n"); - size = 0; - goto _exit; - } - } -#endif - - result = _send_cmd(msd->spi_device, WRITE_MULTIPLE_BLOCK, pos * msd->geometry.bytes_per_sector, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD WRITE_MULTIPLE_BLOCK fail!\r\n"); - size = 0; - goto _exit; - } - - /* write all block */ - for (i = 0; i < size; i++) - { - result = _write_block(msd->spi_device, - (const uint8_t *)buffer + msd->geometry.bytes_per_sector * i, - msd->geometry.bytes_per_sector, - MSD_TOKEN_WRITE_MULTIPLE_START); - if (result != RT_EOK) - { - MSD_DEBUG("[err] write SINGLE_BLOCK #%d fail!\r\n", pos); - size = i; - break; - } - } /* write all block */ - - /* send stop token */ - { - uint8_t send_buffer[18]; - - rt_memset(send_buffer, DUMMY, sizeof(send_buffer)); - send_buffer[sizeof(send_buffer) - 1] = MSD_TOKEN_WRITE_MULTIPLE_STOP; - - /* initial message */ - message.send_buf = send_buffer; - message.recv_buf = RT_NULL; - message.length = sizeof(send_buffer); - message.cs_take = message.cs_release = 0; - - /* transfer message */ - msd->spi_device->bus->ops->xfer(msd->spi_device, &message); - } - - /* wait ready */ - result = _wait_ready(msd->spi_device); - if (result != RT_EOK) - { - MSD_DEBUG("[warning] wait WRITE_MULTIPLE_BLOCK stop token ready timeout!\r\n"); - } - } /* size > 1 */ - -_exit: - /* release and exit */ - rt_spi_release(msd->spi_device); - rt_mutex_release(&(msd->spi_device->bus->lock)); - - return size; -} - -static rt_ssize_t rt_msd_sdhc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - struct msd_device *msd = (struct msd_device *)dev; - uint8_t response[MSD_RESPONSE_MAX_LEN]; - rt_err_t result; - - result = MSD_take_owner(msd->spi_device); - - if (result != RT_EOK) - { - goto _exit; - } - - /* SINGLE_BLOCK? */ - if (size == 1) - { - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, WRITE_BLOCK, pos, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD WRITE_BLOCK fail!\r\n"); - size = 0; - goto _exit; - } - - result = _write_block(msd->spi_device, buffer, msd->geometry.bytes_per_sector, MSD_TOKEN_WRITE_SINGLE_START); - if (result != RT_EOK) - { - MSD_DEBUG("[err] write SINGLE_BLOCK #%d fail!\r\n", pos); - size = 0; - } - } - else if (size > 1) - { - struct rt_spi_message message; - uint32_t i; - - rt_spi_take(msd->spi_device); - -#ifdef MSD_USE_PRE_ERASED - /* CMD55 APP_CMD */ - result = _send_cmd(msd->spi_device, APP_CMD, 0x00, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD55 APP_CMD fail!\r\n"); - size = 0; - goto _exit; - } - - /* ACMD23 Pre-erased */ - result = _send_cmd(msd->spi_device, SET_WR_BLK_ERASE_COUNT, size, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] ACMD23 SET_BLOCK_COUNT fail!\r\n"); - size = 0; - goto _exit; - } -#endif - - result = _send_cmd(msd->spi_device, WRITE_MULTIPLE_BLOCK, pos, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD WRITE_MULTIPLE_BLOCK fail!\r\n"); - size = 0; - goto _exit; - } - - /* write all block */ - for (i = 0; i < size; i++) - { - result = _write_block(msd->spi_device, - (const uint8_t *)buffer + msd->geometry.bytes_per_sector * i, - msd->geometry.bytes_per_sector, - MSD_TOKEN_WRITE_MULTIPLE_START); - if (result != RT_EOK) - { - MSD_DEBUG("[err] write MULTIPLE_BLOCK #%d fail!\r\n", pos); - size = i; - break; - } - } /* write all block */ - - /* send stop token */ - { - uint8_t send_buffer[18]; - - rt_memset(send_buffer, DUMMY, sizeof(send_buffer)); - send_buffer[sizeof(send_buffer) - 1] = MSD_TOKEN_WRITE_MULTIPLE_STOP; - - /* initial message */ - message.send_buf = send_buffer; - message.recv_buf = RT_NULL; - message.length = sizeof(send_buffer); - message.cs_take = message.cs_release = 0; - - /* transfer message */ - msd->spi_device->bus->ops->xfer(msd->spi_device, &message); - } - - result = _wait_ready(msd->spi_device); - if (result != RT_EOK) - { - MSD_DEBUG("[warning] wait WRITE_MULTIPLE_BLOCK stop token ready timeout!\r\n"); - } - } /* size > 1 */ - -_exit: - /* release and exit */ - rt_spi_release(msd->spi_device); - rt_mutex_release(&(msd->spi_device->bus->lock)); - - return size; -} - -static rt_err_t rt_msd_control(rt_device_t dev, int cmd, void *args) -{ - struct msd_device *msd = (struct msd_device *)dev; - - RT_ASSERT(dev != RT_NULL); - - if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME) - { - struct rt_device_blk_geometry *geometry; - - geometry = (struct rt_device_blk_geometry *)args; - if (geometry == RT_NULL) return -RT_ERROR; - - geometry->bytes_per_sector = msd->geometry.bytes_per_sector; - geometry->block_size = msd->geometry.block_size; - geometry->sector_count = msd->geometry.sector_count; - } - - return RT_EOK; -} - -rt_err_t msd_init(const char *sd_device_name, const char *spi_device_name) -{ - rt_err_t result = RT_EOK; - struct rt_spi_device *spi_device; - - spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name); - if (spi_device == RT_NULL) - { - MSD_DEBUG("spi device %s not found!\r\n", spi_device_name); - return -RT_ENOSYS; - } - rt_memset(&_msd_device, 0, sizeof(_msd_device)); - _msd_device.spi_device = spi_device; - - /* register sdcard device */ - _msd_device.parent.type = RT_Device_Class_Block; - - _msd_device.geometry.bytes_per_sector = 0; - _msd_device.geometry.sector_count = 0; - _msd_device.geometry.block_size = 0; - -#ifdef RT_USING_DEVICE_OPS - _msd_device.parent.ops = &msd_ops; -#else - _msd_device.parent.init = rt_msd_init; - _msd_device.parent.open = rt_msd_open; - _msd_device.parent.close = rt_msd_close; - _msd_device.parent.read = RT_NULL; - _msd_device.parent.write = RT_NULL; - _msd_device.parent.control = rt_msd_control; -#endif - - /* no private, no callback */ - _msd_device.parent.user_data = RT_NULL; - _msd_device.parent.rx_indicate = RT_NULL; - _msd_device.parent.tx_complete = RT_NULL; - - result = rt_device_register(&_msd_device.parent, sd_device_name, - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); - - return result; -} diff --git a/rt-thread/components/drivers/spi/dev_spi_msd.h b/rt-thread/components/drivers/spi/dev_spi_msd.h deleted file mode 100644 index 7304b13..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_msd.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2009-04-17 Bernard first version. - */ - -#ifndef __DEV_SPI_MSD_H_INCLUDED__ -#define __DEV_SPI_MSD_H_INCLUDED__ - -#include -#include -#include "drivers/dev_spi.h" - -/* SD command (SPI mode) */ -#define GO_IDLE_STATE 0 /* CMD0 R1 */ -#define SEND_OP_COND 1 /* CMD1 R1 */ -#define SWITCH_FUNC 6 /* CMD6 R1 */ -#define SEND_IF_COND 8 /* CMD8 R7 */ -#define SEND_CSD 9 /* CMD9 R1 */ -#define SEND_CID 10 /* CMD10 R1 */ -#define STOP_TRANSMISSION 12 /* CMD12 R1B */ -#define SEND_STATUS 13 /* CMD13 R2 */ -#define SET_BLOCKLEN 16 /* CMD16 R1 */ -#define READ_SINGLE_BLOCK 17 /* CMD17 R1 */ -#define READ_MULTIPLE_BLOCK 18 /* CMD18 R1 */ -#define WRITE_BLOCK 24 /* CMD24 R1 */ -#define WRITE_MULTIPLE_BLOCK 25 /* CMD25 R1 */ -#define PROGRAM_CSD 27 /* CMD27 R1 */ -#define SET_WRITE_PROT 28 /* CMD28 R1B */ -#define CLR_WRITE_PROT 29 /* CMD29 R1B */ -#define SEND_WRITE_PROT 30 /* CMD30 R1 */ -#define ERASE_WR_BLK_START_ADDR 32 /* CMD32 R1 */ -#define ERASE_WR_BLK_END_ADDR 33 /* CMD33 R1 */ -#define ERASE 38 /* CMD38 R1B */ -#define LOCK_UNLOCK 42 /* CMD42 R1 */ -#define APP_CMD 55 /* CMD55 R1 */ -#define GEN_CMD 56 /* CMD56 R1 */ -#define READ_OCR 58 /* CMD58 R3 */ -#define CRC_ON_OFF 59 /* CMD59 R1 */ - -/* Application-Specific Command */ -#define SD_STATUS 13 /* ACMD13 R2 */ -#define SEND_NUM_WR_BLOCKS 22 /* ACMD22 R1 */ -#define SET_WR_BLK_ERASE_COUNT 23 /* ACMD23 R1 */ -#define SD_SEND_OP_COND 41 /* ACMD41 R1 */ -#define SET_CLR_CARD_DETECT 42 /* ACMD42 R1 */ -#define SEND_SCR 51 /* ACMD51 R1 */ - -/* Start Data tokens */ -/* Tokens (necessary because at nop/idle (and CS active) only 0xff is on the data/command line) */ -#define MSD_TOKEN_READ_START 0xFE /* Data token start byte, Start Single Block Read */ -#define MSD_TOKEN_WRITE_SINGLE_START 0xFE /* Data token start byte, Start Single Block Write */ - -#define MSD_TOKEN_WRITE_MULTIPLE_START 0xFC /* Data token start byte, Start Multiple Block Write */ -#define MSD_TOKEN_WRITE_MULTIPLE_STOP 0xFD /* Data toke stop byte, Stop Multiple Block Write */ - -/* MSD reponses and error flags */ -#define MSD_RESPONSE_NO_ERROR 0x00 -#define MSD_IN_IDLE_STATE 0x01 -#define MSD_ERASE_RESET 0x02 -#define MSD_ILLEGAL_COMMAND 0x04 -#define MSD_COM_CRC_ERROR 0x08 -#define MSD_ERASE_SEQUENCE_ERROR 0x10 -#define MSD_ADDRESS_ERROR 0x20 -#define MSD_PARAMETER_ERROR 0x40 -#define MSD_RESPONSE_FAILURE 0xFF - -/* Data response error */ -#define MSD_DATA_OK 0x05 -#define MSD_DATA_CRC_ERROR 0x0B -#define MSD_DATA_WRITE_ERROR 0x0D -#define MSD_DATA_OTHER_ERROR 0xFF -#define MSD_DATA_RESPONSE_MASK 0x1F -#define MSD_GET_DATA_RESPONSE(res) (res & MSD_DATA_RESPONSE_MASK) - -#define MSD_CMD_LEN 6 /**< command, arg and crc. */ -#define MSD_RESPONSE_MAX_LEN 5 /**< response max len */ -#define MSD_CSD_LEN 16 /**< SD crad CSD register len */ -#define SECTOR_SIZE 512 /**< sector size, default 512byte */ - -/* card try timeout, unit: ms */ -#define CARD_TRY_TIMES 3000 -#define CARD_TRY_TIMES_ACMD41 800 -#define CARD_WAIT_TOKEN_TIMES 800 - -#define MSD_USE_PRE_ERASED /**< id define MSD_USE_PRE_ERASED, before CMD25, send ACMD23 */ - -/** - * SD/MMC card type - */ -typedef enum -{ - MSD_CARD_TYPE_UNKNOWN = 0, /**< unknown */ - MSD_CARD_TYPE_MMC, /**< MultiMedia Card */ - MSD_CARD_TYPE_SD_V1_X, /**< Ver 1.X Standard Capacity SD Memory Card */ - MSD_CARD_TYPE_SD_V2_X, /**< Ver 2.00 or later Standard Capacity SD Memory Card */ - MSD_CARD_TYPE_SD_SDHC, /**< High Capacity SD Memory Card */ - MSD_CARD_TYPE_SD_SDXC, /**< later Extended Capacity SD Memory Card */ -}msd_card_type; - -typedef enum -{ - response_type_unknown = 0, - response_r1, - response_r1b, - response_r2, - response_r3, - response_r4, - response_r5, - response_r7, -}response_type; - -struct msd_device -{ - struct rt_device parent; /**< RT-Thread device struct */ - struct rt_device_blk_geometry geometry; /**< sector size, sector count */ - struct rt_spi_device * spi_device; /**< SPI interface */ - msd_card_type card_type; /**< card type: MMC SD1.x SD2.0 SDHC SDXC */ - uint32_t max_clock; /**< MAX SPI clock */ -}; - -extern rt_err_t msd_init(const char * sd_device_name, const char * spi_device_name); - -#endif // __DEV_SPI_MSD_H_INCLUDED diff --git a/rt-thread/components/drivers/spi/dev_spi_wifi_rw009.c b/rt-thread/components/drivers/spi/dev_spi_wifi_rw009.c deleted file mode 100644 index b3bd807..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_wifi_rw009.c +++ /dev/null @@ -1,852 +0,0 @@ -/* - * COPYRIGHT (C) 2011-2023, Real-Thread Information Technology Ltd - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2014-07-31 aozima the first version - * 2014-09-18 aozima update command & response. - * 2017-07-28 armink fix auto reconnect feature - */ - -#include -#include "drivers/dev_spi.h" - -#include -#include -#include -#include "lwipopts.h" - -#define WIFI_DEBUG_ON -// #define ETH_RX_DUMP -// #define ETH_TX_DUMP - -#ifdef WIFI_DEBUG_ON -#define WIFI_DEBUG rt_kprintf("[RW009] ");rt_kprintf -//#define SPI_DEBUG rt_kprintf("[SPI] ");rt_kprintf -#define SPI_DEBUG(...) -#else -#define WIFI_DEBUG(...) -#define SPI_DEBUG(...) -#endif /* #ifdef WIFI_DEBUG_ON */ - -/********************************* RW009 **************************************/ -#include "dev_spi_wifi_rw009.h" - -/* tools */ -#define node_entry(node, type, member) \ - ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member))) -#define member_offset(type, member) \ - ((unsigned long)(&((type *)0)->member)) - -#define MAX_SPI_PACKET_SIZE (member_offset(struct spi_data_packet, buffer) + SPI_MAX_DATA_LEN) -#define MAX_SPI_BUFFER_SIZE (sizeof(struct spi_response) + MAX_SPI_PACKET_SIZE) -#define MAX_ADDR_LEN 6 - -struct rw009_wifi -{ - /* inherit from ethernet device */ - struct eth_device parent; - - struct rt_spi_device *rt_spi_device; - - /* interface address info. */ - rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ - rt_uint8_t active; - - struct rt_mempool spi_tx_mp; - struct rt_mempool spi_rx_mp; - - struct rt_mailbox spi_tx_mb; - struct rt_mailbox eth_rx_mb; - - int spi_tx_mb_pool[SPI_TX_POOL_SIZE + 1]; - int eth_rx_mb_pool[SPI_RX_POOL_SIZE + 1]; - - int rw009_cmd_mb_pool[3]; - struct rt_mailbox rw009_cmd_mb; - uint32_t last_cmd; - - rt_align(4) - rt_uint8_t spi_tx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_TX_POOL_SIZE]; - rt_align(4) - rt_uint8_t spi_rx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_RX_POOL_SIZE]; - - rt_align(4) - uint8_t spi_hw_rx_buffer[MAX_SPI_BUFFER_SIZE]; - - /* status for RW009 */ - rw009_ap_info ap_info; /* AP info for conn. */ - rw009_ap_info *ap_scan; /* AP list for SCAN. */ - uint32_t ap_scan_count; -}; -static struct rw009_wifi rw009_wifi_device; -static struct rt_event spi_wifi_data_event; - -static void resp_handler(struct rw009_wifi *wifi_device, struct rw009_resp *resp) -{ - struct rw009_resp *resp_return = RT_NULL; - - switch (resp->cmd) - { - case RW009_CMD_INIT: - WIFI_DEBUG("resp_handler RW009_CMD_INIT\n"); - resp_return = (struct rw009_resp *)rt_malloc(member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_init)); //TODO: - if(resp_return == RT_NULL) break; - rt_memcpy(resp_return, resp, member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_init)); - - WIFI_DEBUG("sn:%-*.*s\n", sizeof(resp->resp.init.sn), sizeof(resp->resp.init.sn), resp->resp.init.sn); - WIFI_DEBUG("version:%-*.*s\n", sizeof(resp->resp.init.version), sizeof(resp->resp.init.version), resp->resp.init.version); - - rt_memcpy(wifi_device->dev_addr, resp->resp.init.mac, 6); - break; - - case RW009_CMD_SCAN: - if( resp->len == sizeof(rw009_ap_info) ) - { - rw009_ap_info *ap_scan = rt_realloc(wifi_device->ap_scan, sizeof(rw009_ap_info) * (wifi_device->ap_scan_count + 1) ); - if(ap_scan != RT_NULL) - { - rt_memcpy( &ap_scan[wifi_device->ap_scan_count], &resp->resp.ap_info, sizeof(rw009_ap_info) ); - - //dump - if(1) - { -#ifdef WIFI_DEBUG_ON - rw009_ap_info *ap_info = &resp->resp.ap_info; - WIFI_DEBUG("SCAN SSID:%-32.32s\n", ap_info->ssid); - WIFI_DEBUG("SCAN BSSID:%02X-%02X-%02X-%02X-%02X-%02X\n", - ap_info->bssid[0], - ap_info->bssid[1], - ap_info->bssid[2], - ap_info->bssid[3], - ap_info->bssid[4], - ap_info->bssid[5]); - WIFI_DEBUG("SCAN rssi:%ddBm\n", ap_info->rssi); - WIFI_DEBUG("SCAN rate:%dMbps\n", ap_info->max_data_rate/1000); - WIFI_DEBUG("SCAN channel:%d\n", ap_info->channel); - WIFI_DEBUG("SCAN security:%08X\n\n", ap_info->security); -#endif /* WIFI_DEBUG_ON */ - } - - wifi_device->ap_scan_count++; - wifi_device->ap_scan = ap_scan; - } - - return; /* wait for next ap */ - } - break; - case RW009_CMD_JOIN: - case RW009_CMD_EASY_JOIN: - WIFI_DEBUG("resp_handler RW009_CMD_EASY_JOIN\n"); - resp_return = (struct rw009_resp *)rt_malloc(member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_join)); //TODO: - if(resp_return == RT_NULL) break; - rt_memcpy(resp_return, resp, member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_join)); - - if( resp->result == 0 ) - { - rt_memcpy(&wifi_device->ap_info, &resp_return->resp.ap_info, sizeof(rw009_resp_join)); - wifi_device->active = 1; - eth_device_linkchange(&wifi_device->parent, RT_TRUE); - } - else - { - wifi_device->active = 1; - eth_device_linkchange(&wifi_device->parent, RT_FALSE); - WIFI_DEBUG("RW009_CMD_EASY_JOIN result: %d\n", resp->result ); - } - - //dupm - if(1) - { -#ifdef WIFI_DEBUG_ON - rw009_ap_info *ap_info = &resp->resp.ap_info; - WIFI_DEBUG("JOIN SSID:%-32.32s\n", ap_info->ssid); - WIFI_DEBUG("JOIN BSSID:%02X-%02X-%02X-%02X-%02X-%02X\n", - ap_info->bssid[0], - ap_info->bssid[1], - ap_info->bssid[2], - ap_info->bssid[3], - ap_info->bssid[4], - ap_info->bssid[5]); - WIFI_DEBUG("JOIN rssi:%ddBm\n", ap_info->rssi); - WIFI_DEBUG("JOIN rate:%dMbps\n", ap_info->max_data_rate/1000); - WIFI_DEBUG("JOIN channel:%d\n", ap_info->channel); - WIFI_DEBUG("JOIN security:%08X\n\n", ap_info->security); -#endif /* WIFI_DEBUG_ON */ - } - break; - - case RW009_CMD_RSSI: - // TODO: client RSSI. - { - rw009_ap_info *ap_info = &resp->resp.ap_info; - wifi_device->ap_info.rssi = ap_info->rssi; - WIFI_DEBUG("current RSSI: %d\n", wifi_device->ap_info.rssi); - } - break; - - case RW009_CMD_SOFTAP: - { - if( resp->result == 0 ) - { - ; - wifi_device->active = 1; - eth_device_linkchange(&wifi_device->parent, RT_TRUE); - } - else - { - WIFI_DEBUG("RW009_CMD_EASY_JOIN result: %d\n", resp->result ); - } - - } - break; - - default: - WIFI_DEBUG("resp_handler %d\n", resp->cmd); - break; - } - - - if(resp->cmd == wifi_device->last_cmd) - { - rt_mb_send(&wifi_device->rw009_cmd_mb, (rt_uint32_t)resp_return); - return; - } - else - { - rt_free(resp_return); - } -} - -static rt_err_t rw009_cmd(struct rw009_wifi *wifi_device, uint32_t cmd, void *args) -{ - rt_err_t result = RT_EOK; - rt_int32_t timeout = RW009_CMD_TIMEOUT; - - struct spi_data_packet *data_packet; - struct rw009_cmd *wifi_cmd = RT_NULL; - struct rw009_resp *resp = RT_NULL; - - wifi_device->last_cmd = cmd; - - data_packet = (struct spi_data_packet *)rt_mp_alloc(&wifi_device->spi_tx_mp, RT_WAITING_FOREVER); - wifi_cmd = (struct rw009_cmd *)data_packet->buffer; - - wifi_cmd->cmd = cmd; - wifi_cmd->len = 0; - - if( cmd == RW009_CMD_INIT ) - { - wifi_cmd->len = sizeof(rw009_cmd_init); - } - else if( cmd == RW009_CMD_SCAN ) - { - wifi_cmd->len = 0; - timeout += RT_TICK_PER_SECOND*10; - - if(wifi_device->ap_scan) - { - rt_free(wifi_device->ap_scan); - wifi_device->ap_scan = RT_NULL; - wifi_device->ap_scan_count = 0; - } - } - else if( cmd == RW009_CMD_JOIN ) - { - wifi_cmd->len = sizeof(rw009_cmd_join); - } - else if( cmd == RW009_CMD_EASY_JOIN ) - { - wifi_cmd->len = sizeof(rw009_cmd_easy_join); - timeout += RT_TICK_PER_SECOND*5; - } - else if( cmd == RW009_CMD_RSSI ) - { - wifi_cmd->len = sizeof(rw009_cmd_rssi); - } - else if( cmd == RW009_CMD_SOFTAP ) - { - wifi_cmd->len = sizeof(rw009_cmd_softap); - } - else - { - WIFI_DEBUG("unkown RW009 CMD %d\n", cmd); - result = -RT_ENOSYS; - rt_mp_free(data_packet); - data_packet = RT_NULL; - } - - if(data_packet == RT_NULL) - { - goto _exit; - } - - if(wifi_cmd->len) - rt_memcpy(&wifi_cmd->params, args, wifi_cmd->len); - - data_packet->data_type = data_type_cmd; - data_packet->data_len = member_offset(struct rw009_cmd, params) + wifi_cmd->len; - - rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet); - rt_event_send(&spi_wifi_data_event, 1); - - result = rt_mb_recv(&wifi_device->rw009_cmd_mb, - (rt_uint32_t *)&resp, - timeout); - - if ( result != RT_EOK ) - { - WIFI_DEBUG("CMD %d error, resultL %d\n", cmd, result ); - } - - if(resp != RT_NULL) - result = resp->result; - -_exit: - wifi_device->last_cmd = 0; - if(resp) rt_free(resp); - return result; -} - -static rt_err_t spi_wifi_transfer(struct rw009_wifi *dev) -{ - struct pbuf *p = RT_NULL; - struct spi_cmd_request cmd; - struct spi_response resp; - - rt_err_t result; - const struct spi_data_packet *data_packet = RT_NULL; - - struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev; - struct rt_spi_device *rt_spi_device = wifi_device->rt_spi_device; - - spi_wifi_int_cmd(0); - while (spi_wifi_is_busy()); - SPI_DEBUG("sequence start!\n"); - - rt_memset(&cmd, 0, sizeof(struct spi_cmd_request)); - cmd.magic1 = CMD_MAGIC1; - cmd.magic2 = CMD_MAGIC2; - - cmd.flag |= CMD_FLAG_MRDY; - - result = rt_mb_recv(&wifi_device->spi_tx_mb, - (rt_uint32_t *)&data_packet, - 0); - if ((result == RT_EOK) && (data_packet != RT_NULL) && (data_packet->data_len > 0)) - { - cmd.M2S_len = data_packet->data_len + member_offset(struct spi_data_packet, buffer); - //SPI_DEBUG("cmd.M2S_len = %d\n", cmd.M2S_len); - } - - rt_spi_send(rt_spi_device, &cmd, sizeof(cmd)); - while (spi_wifi_is_busy()); - - { - struct rt_spi_message message; - uint32_t max_data_len = 0; - - /* setup message */ - message.send_buf = RT_NULL; - message.recv_buf = &resp; - message.length = sizeof(resp); - message.cs_take = 1; - message.cs_release = 0; - - rt_spi_take_bus(rt_spi_device); - - /* transfer message */ - rt_spi_device->bus->ops->xfer(rt_spi_device, &message); - - if ((resp.magic1 != RESP_MAGIC1) || (resp.magic2 != RESP_MAGIC2)) - { - SPI_DEBUG("bad resp magic, abort!\n"); - goto _bad_resp_magic; - } - - if (resp.flag & RESP_FLAG_SRDY) - { - SPI_DEBUG("RESP_FLAG_SRDY\n"); - max_data_len = cmd.M2S_len; - } - - if (resp.S2M_len) - { - SPI_DEBUG("resp.S2M_len: %d\n", resp.S2M_len); - if (resp.S2M_len > MAX_SPI_PACKET_SIZE) - { - SPI_DEBUG("resp.S2M_len %d > %d(MAX_SPI_PACKET_SIZE), drop!\n", resp.S2M_len, MAX_SPI_PACKET_SIZE); - resp.S2M_len = 0;//drop - } - - if (resp.S2M_len > max_data_len) - max_data_len = resp.S2M_len; - } - - if (max_data_len == 0) - { - SPI_DEBUG("no rx or tx data!\n"); - } - - //SPI_DEBUG("max_data_len = %d\n", max_data_len); - -_bad_resp_magic: - /* setup message */ - message.send_buf = data_packet;//&tx_buffer; - message.recv_buf = wifi_device->spi_hw_rx_buffer;//&rx_buffer; - message.length = max_data_len; - message.cs_take = 0; - message.cs_release = 1; - - /* transfer message */ - rt_spi_device->bus->ops->xfer(rt_spi_device, &message); - - rt_spi_release_bus(rt_spi_device); - - if (cmd.M2S_len && (resp.flag & RESP_FLAG_SRDY)) - { - rt_mp_free((void *)data_packet); - } - - if ((resp.S2M_len) && (resp.S2M_len <= MAX_SPI_PACKET_SIZE)) - { - data_packet = (struct spi_data_packet *)wifi_device->spi_hw_rx_buffer; - if (data_packet->data_type == data_type_eth_data) - { - - if (wifi_device->active) - { - p = pbuf_alloc(PBUF_LINK, data_packet->data_len, PBUF_RAM); - pbuf_take(p, (rt_uint8_t *)data_packet->buffer, data_packet->data_len); - - rt_mb_send(&wifi_device->eth_rx_mb, (rt_uint32_t)p); - eth_device_ready((struct eth_device *)dev); - } - else - { - SPI_DEBUG("!active, RX drop.\n"); - } - } - else if (data_packet->data_type == data_type_resp) - { - SPI_DEBUG("data_type_resp\n"); - resp_handler(dev, (struct rw009_resp *)data_packet->buffer); - } - else - { - SPI_DEBUG("data_type: %d, %dbyte\n", - data_packet->data_type, - data_packet->data_len); - } - } - } - spi_wifi_int_cmd(1); - - SPI_DEBUG("sequence finish!\n\n"); - - if ((cmd.M2S_len == 0) && (resp.S2M_len == 0)) - { - return -RT_ERROR; - } - - return RT_EOK; -} - -#if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP) -static void packet_dump(const char *msg, const struct pbuf *p) -{ - const struct pbuf* q; - rt_uint32_t i,j; - rt_uint8_t *ptr = p->payload; - - rt_kprintf("%s %d byte\n", msg, p->tot_len); - - i=0; - for(q=p; q != RT_NULL; q= q->next) - { - ptr = q->payload; - - for(j=0; jlen; j++) - { - if( (i%8) == 0 ) - { - rt_kprintf(" "); - } - if( (i%16) == 0 ) - { - rt_kprintf("\r\n"); - } - rt_kprintf("%02x ",*ptr); - - i++; - ptr++; - } - } - rt_kprintf("\n\n"); -} -#endif /* dump */ - -/********************************* RT-Thread Ethernet interface begin **************************************/ -static rt_err_t rw009_wifi_init(rt_device_t dev) -{ - return RT_EOK; -} - -static rt_err_t rw009_wifi_open(rt_device_t dev, rt_uint16_t oflag) -{ - return RT_EOK; -} - -static rt_err_t rw009_wifi_close(rt_device_t dev) -{ - return RT_EOK; -} - -static rt_ssize_t rw009_wifi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - rt_set_errno(-RT_ENOSYS); - return 0; -} - -static rt_ssize_t rw009_wifi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - rt_set_errno(-RT_ENOSYS); - return 0; -} - -static rt_err_t rw009_wifi_control(rt_device_t dev, int cmd, void *args) -{ - struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev; - rt_err_t result = RT_EOK; - - if (cmd == NIOCTL_GADDR) - { - rt_memcpy(args, wifi_device->dev_addr, 6); - } - else - { - result = rw009_cmd(wifi_device, cmd, args); - } - - return result; -} - -/* transmit packet. */ -rt_err_t rw009_wifi_tx(rt_device_t dev, struct pbuf *p) -{ - rt_err_t result = RT_EOK; - struct spi_data_packet *data_packet; - struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev; - - if (!wifi_device->active) - { - WIFI_DEBUG("!active, TX drop!\n"); - return RT_EOK; - } - - /* get free tx buffer */ - data_packet = (struct spi_data_packet *)rt_mp_alloc(&wifi_device->spi_tx_mp, RT_WAITING_FOREVER); - if (data_packet != RT_NULL) - { - data_packet->data_type = data_type_eth_data; - data_packet->data_len = p->tot_len; - - pbuf_copy_partial(p, data_packet->buffer, data_packet->data_len, 0); - - rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet); - rt_event_send(&spi_wifi_data_event, 1); - } - else - return -RT_ERROR; - -#ifdef ETH_TX_DUMP - packet_dump("TX dump", p); -#endif /* ETH_TX_DUMP */ - - /* Return SUCCESS */ - return result; -} - -/* reception packet. */ -struct pbuf *rw009_wifi_rx(rt_device_t dev) -{ - struct pbuf *p = RT_NULL; - struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev; - - if (rt_mb_recv(&wifi_device->eth_rx_mb, (rt_uint32_t *)&p, 0) != RT_EOK) - { - return RT_NULL; - } - -#ifdef ETH_RX_DUMP - if(p) - packet_dump("RX dump", p); -#endif /* ETH_RX_DUMP */ - - return p; -} -/********************************* RT-Thread Ethernet interface end **************************************/ - -static void spi_wifi_data_thread_entry(void *parameter) -{ - rt_uint32_t e; - rt_err_t result; - - while (1) - { - /* receive first event */ - if (rt_event_recv(&spi_wifi_data_event, - 1, - RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, - RT_WAITING_FOREVER, - &e) != RT_EOK) - { - continue; - } - - result = spi_wifi_transfer(&rw009_wifi_device); - - if (result == RT_EOK) - { - rt_event_send(&spi_wifi_data_event, 1); - } - } -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops rw009_ops = -{ - rw009_wifi_init, - rw009_wifi_open, - rw009_wifi_close, - rw009_wifi_read, - rw009_wifi_write, - rw009_wifi_control -}; -#endif - -rt_err_t rt_hw_wifi_init(const char *spi_device_name, wifi_mode_t mode) -{ - /* align and struct size check. */ - RT_ASSERT( (SPI_MAX_DATA_LEN & 0x03) == 0); - RT_ASSERT( sizeof(struct rw009_resp) <= SPI_MAX_DATA_LEN); - - rt_memset(&rw009_wifi_device, 0, sizeof(struct rw009_wifi)); - - rw009_wifi_device.rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name); - - if (rw009_wifi_device.rt_spi_device == RT_NULL) - { - SPI_DEBUG("spi device %s not found!\r\n", spi_device_name); - return -RT_ENOSYS; - } - - /* config spi */ - { - struct rt_spi_configuration cfg; - cfg.data_width = 8; - cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0. */ - cfg.max_hz = 15 * 1000000; /* 10M */ - rt_spi_configure(rw009_wifi_device.rt_spi_device, &cfg); - } - -#ifdef RT_USING_DEVICE_OPS - rw009_wifi_device.parent.parent.ops = &rw009_ops; -#else - rw009_wifi_device.parent.parent.init = rw009_wifi_init; - rw009_wifi_device.parent.parent.open = rw009_wifi_open; - rw009_wifi_device.parent.parent.close = rw009_wifi_close; - rw009_wifi_device.parent.parent.read = rw009_wifi_read; - rw009_wifi_device.parent.parent.write = rw009_wifi_write; - rw009_wifi_device.parent.parent.control = rw009_wifi_control; -#endif - rw009_wifi_device.parent.parent.user_data = RT_NULL; - - rw009_wifi_device.parent.eth_rx = rw009_wifi_rx; - rw009_wifi_device.parent.eth_tx = rw009_wifi_tx; - - rt_mp_init(&rw009_wifi_device.spi_tx_mp, - "spi_tx", - &rw009_wifi_device.spi_tx_mempool[0], - sizeof(rw009_wifi_device.spi_tx_mempool), - sizeof(struct spi_data_packet)); - - rt_mp_init(&rw009_wifi_device.spi_rx_mp, - "spi_rx", - &rw009_wifi_device.spi_rx_mempool[0], - sizeof(rw009_wifi_device.spi_rx_mempool), - sizeof(struct spi_data_packet)); - - rt_mb_init(&rw009_wifi_device.spi_tx_mb, - "spi_tx", - &rw009_wifi_device.spi_tx_mb_pool[0], - SPI_TX_POOL_SIZE, - RT_IPC_FLAG_PRIO); - - rt_mb_init(&rw009_wifi_device.eth_rx_mb, - "eth_rx", - &rw009_wifi_device.eth_rx_mb_pool[0], - SPI_TX_POOL_SIZE, - RT_IPC_FLAG_PRIO); - - rt_mb_init(&rw009_wifi_device.rw009_cmd_mb, - "wifi_cmd", - &rw009_wifi_device.rw009_cmd_mb_pool[0], - sizeof(rw009_wifi_device.rw009_cmd_mb_pool) / 4, - RT_IPC_FLAG_PRIO); - rt_event_init(&spi_wifi_data_event, "wifi", RT_IPC_FLAG_FIFO); - - spi_wifi_hw_init(); - - { - rt_thread_t tid; - - - tid = rt_thread_create("wifi", - spi_wifi_data_thread_entry, - RT_NULL, - 2048, - RT_THREAD_PRIORITY_MAX - 2, - 20); - - if (tid != RT_NULL) - rt_thread_startup(tid); - } - - /* init: get mac address */ - { - rw009_cmd_init init; - init.mode = mode; - WIFI_DEBUG("wifi_control RW009_CMD_INIT\n"); - rw009_wifi_control((rt_device_t)&rw009_wifi_device, - RW009_CMD_INIT, - (void *)&init); // 0: firmware, 1: STA, 2:AP - - } - - /* register eth device */ - eth_device_init(&(rw009_wifi_device.parent), "w0"); - eth_device_linkchange(&rw009_wifi_device.parent, RT_FALSE); - - return RT_EOK; -} - -void spi_wifi_isr(int vector) -{ - /* enter interrupt */ - rt_interrupt_enter(); - - SPI_DEBUG("spi_wifi_isr\n"); - rt_event_send(&spi_wifi_data_event, 1); - - /* leave interrupt */ - rt_interrupt_leave(); -} - -/********************************* RW009 tools **************************************/ -rt_err_t rw009_join(const char * SSID, const char * passwd) -{ - rt_err_t result; - rt_device_t wifi_device; - rw009_cmd_easy_join easy_join; - - wifi_device = rt_device_find("w0"); - if(wifi_device == RT_NULL) - return -RT_ENOSYS; - - strncpy( easy_join.ssid, SSID, sizeof(easy_join.ssid) ); - strncpy( easy_join.passwd, passwd, sizeof(easy_join.passwd) ); - - result = rt_device_control(wifi_device, - RW009_CMD_EASY_JOIN, - (void *)&easy_join); - - return result; -} - -rt_err_t rw009_softap(const char * SSID, const char * passwd,uint32_t security,uint32_t channel) -{ - rt_err_t result; - rt_device_t wifi_device; - rw009_cmd_softap softap; - - wifi_device = rt_device_find("w0"); - if(wifi_device == RT_NULL) - return -RT_ENOSYS; - - strncpy( softap.ssid, SSID, sizeof(softap.ssid) ); - strncpy( softap.passwd, passwd, sizeof(softap.passwd) ); - - softap.security = security; - softap.channel = channel; - result = rt_device_control(wifi_device, - RW009_CMD_SOFTAP, - (void *)&softap); - - return result; -} - -int32_t rw009_rssi(void) -{ - rt_err_t result; - struct rw009_wifi * wifi_device; - - wifi_device = (struct rw009_wifi *)rt_device_find("w0"); - - if(wifi_device == RT_NULL) - return 0; - - if(wifi_device->active == 0) - return 0; - - // SCAN - result = rt_device_control((rt_device_t)wifi_device, - RW009_CMD_RSSI, - RT_NULL); - - if(result == RT_EOK) - { - return wifi_device->ap_info.rssi; - } - - return 0; -} - -#ifdef RT_USING_FINSH -#include - -static rt_err_t rw009_scan(void) -{ - rt_err_t result; - struct rw009_wifi * wifi_device; - - wifi_device = (struct rw009_wifi *)rt_device_find("w0"); - - rt_kprintf("\nCMD RW009_CMD_SCAN \n"); - result = rt_device_control((rt_device_t)wifi_device, - RW009_CMD_SCAN, - RT_NULL); - - rt_kprintf("CMD RW009_CMD_SCAN result:%d\n", result); - - if(result == RT_EOK) - { - uint32_t i; - rw009_ap_info *ap_info; - - for(i=0; iap_scan_count; i++) - { - ap_info = &wifi_device->ap_scan[i]; - rt_kprintf("AP #%02d SSID: %-32.32s\n", i, ap_info->ssid ); - } - } - - return result; -} -FINSH_FUNCTION_EXPORT(rw009_scan, SACN and list AP.); -FINSH_FUNCTION_EXPORT(rw009_join, RW009 join to AP.); -FINSH_FUNCTION_EXPORT(rw009_rssi, get RW009 current AP rssi.); - -#endif // RT_USING_FINSH diff --git a/rt-thread/components/drivers/spi/dev_spi_wifi_rw009.h b/rt-thread/components/drivers/spi/dev_spi_wifi_rw009.h deleted file mode 100644 index 5aecbce..0000000 --- a/rt-thread/components/drivers/spi/dev_spi_wifi_rw009.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * COPYRIGHT (C) 2011-2023, Real-Thread Information Technology Ltd - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2014-07-31 aozima the first version - * 2014-09-18 aozima update command & response. - */ - -#ifndef __DEV_SPI_WIFI_H_INCLUDED__ -#define __DEV_SPI_WIFI_H_INCLUDED__ - -#include - -// little-endian -struct spi_cmd_request -{ - uint32_t flag; - uint32_t M2S_len; // master to slave data len. - uint32_t magic1; - uint32_t magic2; -}; - -#define CMD_MAGIC1 (0x67452301) -#define CMD_MAGIC2 (0xEFCDAB89) - -#define CMD_FLAG_MRDY (0x01) - -// little-endian -struct spi_response -{ - uint32_t flag; - uint32_t S2M_len; // slave to master data len. - uint32_t magic1; - uint32_t magic2; -}; - -#define RESP_FLAG_SRDY (0x01) -#define RESP_MAGIC1 (0x98BADCFE) -#define RESP_MAGIC2 (0x10325476) - -/* spi slave configure. */ -#define SPI_MAX_DATA_LEN 1520 -#define SPI_TX_POOL_SIZE 2 -#define SPI_RX_POOL_SIZE 2 - -typedef enum -{ - data_type_eth_data = 0, - data_type_cmd, - data_type_resp, - data_type_status, -} -app_data_type_typedef; - -struct spi_data_packet -{ - uint32_t data_len; - uint32_t data_type; - char buffer[SPI_MAX_DATA_LEN]; -}; - -/********************************* RW009 **************************************/ - -/* option */ -#define RW009_CMD_TIMEOUT (RT_TICK_PER_SECOND*3) -#define SSID_NAME_LENGTH_MAX (32) -#define PASSWORD_LENGTH_MAX (64) - -typedef enum -{ - MODE_STATION=0, - MODE_SOFTAP=1, -} wifi_mode_t; - -typedef struct _rw009_ap_info -{ - char ssid[SSID_NAME_LENGTH_MAX]; - uint8_t bssid[8]; // 6byte + 2byte PAD. - int rssi; /* Receive Signal Strength Indication in dBm. */ - uint32_t max_data_rate; /* Maximum data rate in kilobits/s */ - uint32_t security; /* Security type */ - uint32_t channel; /* Radio channel that the AP beacon was received on */ -} rw009_ap_info; - -typedef struct _rw009_cmd_init -{ - uint32_t mode; -} rw009_cmd_init; - -typedef struct _rw009_resp_init -{ - uint8_t mac[8]; // 6byte + 2byte PAD. - uint8_t sn[24]; // serial. - char version[16]; // firmware version. -} rw009_resp_init; - -typedef struct _rw009_cmd_easy_join -{ - char ssid[SSID_NAME_LENGTH_MAX]; - char passwd[PASSWORD_LENGTH_MAX]; -} rw009_cmd_easy_join; - -typedef struct _rw009_cmd_join -{ - uint8_t bssid[8]; // 6byte + 2byte PAD. - char passwd[PASSWORD_LENGTH_MAX]; -} rw009_cmd_join; - -typedef struct _rw009_cmd_rssi -{ - uint8_t bssid[8]; // 6byte + 2byte PAD. -} rw009_cmd_rssi; - -typedef struct _rw009_cmd_softap -{ - char ssid[SSID_NAME_LENGTH_MAX]; - char passwd[PASSWORD_LENGTH_MAX]; - - uint32_t security; /* Security type. */ - uint32_t channel; /* Radio channel that the AP beacon was received on */ -} rw009_cmd_softap; - -typedef struct _rw009_resp_join -{ - rw009_ap_info ap_info; -} rw009_resp_join; - -struct rw009_cmd -{ - uint32_t cmd; - uint32_t len; - - /** command body */ - union - { - rw009_cmd_init init; - rw009_cmd_easy_join easy_join; - rw009_cmd_join join; - rw009_cmd_rssi rssi; - rw009_cmd_softap softap; - } params; -}; - -struct rw009_resp -{ - uint32_t cmd; - uint32_t len; - - int32_t result; // result for CMD. - - /** resp Body */ - union - { - rw009_resp_init init; - rw009_ap_info ap_info; - } resp; -}; - -#define RW009_CMD_INIT 128 -#define RW009_CMD_SCAN 129 -#define RW009_CMD_JOIN 130 -#define RW009_CMD_EASY_JOIN 131 -#define RW009_CMD_RSSI 132 -#define RW009_CMD_SOFTAP 133 - -/** cond !ADDTHIS*/ -#define SHARED_ENABLED 0x00008000 -#define WPA_SECURITY 0x00200000 -#define WPA2_SECURITY 0x00400000 -#define WPS_ENABLED 0x10000000 -#define WEP_ENABLED 0x0001 -#define TKIP_ENABLED 0x0002 -#define AES_ENABLED 0x0004 -#define WSEC_SWFLAG 0x0008 -/** endcond */ -/** - * Enumeration of Wi-Fi security modes - */ -typedef enum -{ - SECURITY_OPEN = 0, /**< Open security */ - SECURITY_WEP_PSK = WEP_ENABLED, /**< WEP Security with open authentication */ - SECURITY_WEP_SHARED = ( WEP_ENABLED | SHARED_ENABLED ), /**< WEP Security with shared authentication */ - SECURITY_WPA_TKIP_PSK = ( WPA_SECURITY | TKIP_ENABLED ), /**< WPA Security with TKIP */ - SECURITY_WPA_AES_PSK = ( WPA_SECURITY | AES_ENABLED ), /**< WPA Security with AES */ - SECURITY_WPA2_AES_PSK = ( WPA2_SECURITY | AES_ENABLED ), /**< WPA2 Security with AES */ - SECURITY_WPA2_TKIP_PSK = ( WPA2_SECURITY | TKIP_ENABLED ), /**< WPA2 Security with TKIP */ - SECURITY_WPA2_MIXED_PSK = ( WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED ), /**< WPA2 Security with AES & TKIP */ - - SECURITY_WPS_OPEN = WPS_ENABLED, /**< WPS with open security */ - SECURITY_WPS_SECURE = (WPS_ENABLED | AES_ENABLED), /**< WPS with AES security */ - - SECURITY_UNKNOWN = -1, /**< May be returned by scan function if security is unknown. Do not pass this to the join function! */ - - SECURITY_FORCE_32_BIT = 0x7fffffff /**< Exists only to force wiced_security_t type to 32 bits */ -} security_t; - -/* porting */ -extern void spi_wifi_hw_init(void); -extern void spi_wifi_int_cmd(rt_bool_t cmd); -extern rt_bool_t spi_wifi_is_busy(void); - -/* export API. */ -extern rt_err_t rt_hw_wifi_init(const char *spi_device_name,wifi_mode_t mode); -extern int32_t rw009_rssi(void); -extern rt_err_t rw009_join(const char * SSID, const char * passwd); -extern rt_err_t rw009_softap(const char * SSID, const char * passwd,uint32_t security,uint32_t channel); - -#endif // __DEV_SPI_WIFI_H_INCLUDED__ diff --git a/rt-thread/components/drivers/spi/enc28j60.h b/rt-thread/components/drivers/spi/enc28j60.h index 013222c..017877a 100644 --- a/rt-thread/components/drivers/spi/enc28j60.h +++ b/rt-thread/components/drivers/spi/enc28j60.h @@ -6,13 +6,13 @@ * Change Logs: * Date Author Notes */ -#ifndef __EN28J60_H_INCLUDED__ -#define __EN28J60_H_INCLUDED__ +#ifndef EN28J60_H_INCLUDED +#define EN28J60_H_INCLUDED #include #include -#include "drivers/dev_spi.h" +#include #include // ENC28J60 Control Registers @@ -340,4 +340,4 @@ struct net_device extern rt_err_t enc28j60_attach(const char *spi_device_name); extern void enc28j60_isr(void); -#endif // __EN28J60_H_INCLUDED__ +#endif // EN28J60_H_INCLUDED diff --git a/rt-thread/components/drivers/thermal/Kconfig b/rt-thread/components/drivers/thermal/Kconfig deleted file mode 100644 index b993aaf..0000000 --- a/rt-thread/components/drivers/thermal/Kconfig +++ /dev/null @@ -1,28 +0,0 @@ -menuconfig RT_USING_THERMAL - bool "Using Thermal Management device drivers" - depends on RT_USING_DM - default n - -if RT_USING_THERMAL - comment "Thermal Sensors Drivers" -endif - -if RT_USING_THERMAL - osource "$(SOC_DM_THERMAL_DIR)/Kconfig" -endif - -if RT_USING_THERMAL - comment "Thermal Cool Drivers" -endif - -config RT_THERMAL_COOL_PWM_FAN - bool "PWM Fan" - depends on RT_USING_THERMAL - depends on RT_USING_PWM - depends on RT_USING_REGULATOR - depends on RT_USING_OFW - default n - -if RT_USING_THERMAL - osource "$(SOC_DM_THERMAL_COOL_DIR)/Kconfig" -endif diff --git a/rt-thread/components/drivers/thermal/SConscript b/rt-thread/components/drivers/thermal/SConscript deleted file mode 100644 index d33d2d2..0000000 --- a/rt-thread/components/drivers/thermal/SConscript +++ /dev/null @@ -1,18 +0,0 @@ -from building import * - -group = [] - -if not GetDepend(['RT_USING_THERMAL']): - Return('group') - -cwd = GetCurrentDir() -CPPPATH = [cwd + '/../include'] - -src = ['thermal.c', 'thermal_dm.c'] - -if GetDepend(['RT_THERMAL_COOL_PWM_FAN']): - src += ['thermal-cool-pwm-fan.c'] - -group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/rt-thread/components/drivers/thermal/thermal-cool-pwm-fan.c b/rt-thread/components/drivers/thermal/thermal-cool-pwm-fan.c deleted file mode 100644 index d6c2539..0000000 --- a/rt-thread/components/drivers/thermal/thermal-cool-pwm-fan.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#include -#include -#include - -#define DBG_TAG "thermal.cool.pwm-fan" -#define DBG_LVL DBG_INFO -#include - -#define MAX_PWM 255 - -struct pwm_fan_cool -{ - struct rt_thermal_cooling_device parent; - - rt_uint32_t pwm_fan_level; - rt_uint32_t pwm_fan_max_level; - rt_uint32_t *pwm_fan_cooling_levels; - - struct rt_device_pwm *pwm_dev; - struct rt_pwm_configuration pwm_conf; - - struct rt_regulator *supply; - struct rt_spinlock lock; -}; - -#define raw_to_pwm_fan_cool(raw) rt_container_of(raw, struct pwm_fan_cool, parent) - -static rt_err_t pwm_fan_power_on(struct pwm_fan_cool *pf_cool) -{ - rt_err_t err = RT_EOK; - - if ((err = rt_pwm_enable(pf_cool->pwm_dev, pf_cool->pwm_conf.channel))) - { - return err; - } - - if (pf_cool->supply && (err = rt_regulator_enable(pf_cool->supply))) - { - rt_pwm_disable(pf_cool->pwm_dev, pf_cool->pwm_conf.channel); - - return err; - } - - return err; -} - -static rt_err_t pwm_fan_power_off(struct pwm_fan_cool *pf_cool) -{ - rt_err_t err = RT_EOK; - - if (pf_cool->supply && (err = rt_regulator_disable(pf_cool->supply))) - { - return err; - } - - if ((err = rt_pwm_disable(pf_cool->pwm_dev, pf_cool->pwm_conf.channel))) - { - rt_regulator_enable(pf_cool->supply); - - return err; - } - - return err; -} - -static rt_err_t pwm_fan_cool_get_max_level(struct rt_thermal_cooling_device *cdev, - rt_ubase_t *out_level) -{ - struct pwm_fan_cool *pf_cool = raw_to_pwm_fan_cool(cdev); - - *out_level = pf_cool->pwm_fan_max_level; - - return RT_EOK; -} - -static rt_err_t pwm_fan_cool_get_cur_level(struct rt_thermal_cooling_device *cdev, - rt_ubase_t *out_level) -{ - struct pwm_fan_cool *pf_cool = raw_to_pwm_fan_cool(cdev); - - *out_level = pf_cool->pwm_fan_level; - - return RT_EOK; -} - -static rt_err_t pwm_fan_cool_set_cur_level(struct rt_thermal_cooling_device *cdev, - rt_ubase_t level) -{ - rt_ubase_t pwm; - rt_err_t err = RT_EOK; - struct pwm_fan_cool *pf_cool = raw_to_pwm_fan_cool(cdev); - - if (pf_cool->pwm_fan_level == level) - { - return RT_EOK; - } - - rt_spin_lock(&pf_cool->lock); - - if ((pwm = pf_cool->pwm_fan_cooling_levels[level])) - { - rt_ubase_t period; - struct rt_pwm_configuration *pwm_conf = &pf_cool->pwm_conf; - - period = pwm_conf->period; - pwm_conf->pulse = RT_DIV_ROUND_UP(pwm * (period - 1), MAX_PWM); - - err = rt_pwm_set(pf_cool->pwm_dev, - pwm_conf->channel, pwm_conf->period, pwm_conf->pulse); - - if (!err && pf_cool->pwm_fan_level == 0) - { - err = pwm_fan_power_on(pf_cool); - } - } - else if (pf_cool->pwm_fan_level > 0) - { - err = pwm_fan_power_off(pf_cool); - } - - rt_spin_unlock(&pf_cool->lock); - - if (!err) - { - pf_cool->pwm_fan_level = level; - } - - return RT_EOK; -} - -const static struct rt_thermal_cooling_device_ops pwm_fan_cool_ops = -{ - .get_max_level = pwm_fan_cool_get_max_level, - .get_cur_level = pwm_fan_cool_get_cur_level, - .set_cur_level = pwm_fan_cool_set_cur_level, -}; - -static void pwm_fan_cool_free(struct pwm_fan_cool *pf_cool) -{ - if (!rt_is_err_or_null(pf_cool->supply)) - { - rt_regulator_put(pf_cool->supply); - } - - if (pf_cool->pwm_fan_cooling_levels) - { - rt_free(pf_cool->pwm_fan_cooling_levels); - } - - rt_free(pf_cool); -} - -static rt_err_t pwm_fan_cool_probe(struct rt_platform_device *pdev) -{ - rt_err_t err; - int levels_nr; - struct rt_ofw_cell_args pwm_args; - struct rt_device *dev = &pdev->parent; - struct rt_ofw_node *np = dev->ofw_node, *pwm_np; - struct pwm_fan_cool *pf_cool = rt_calloc(1, sizeof(*pf_cool)); - - if (!pf_cool) - { - return -RT_ENOMEM; - } - - if (rt_ofw_parse_phandle_cells(np, "pwms", "#pwm-cells", 0, &pwm_args)) - { - err = -RT_EINVAL; - goto _fail; - } - - pwm_np = pwm_args.data; - - if (!rt_ofw_data(pwm_np)) - { - rt_platform_ofw_request(pwm_np); - } - - pf_cool->pwm_dev = rt_ofw_data(pwm_np); - rt_ofw_node_put(pwm_np); - - if (!pf_cool->pwm_dev) - { - err = -RT_EINVAL; - goto _fail; - } - - pf_cool->pwm_conf.channel = pwm_args.args[0]; - pf_cool->pwm_conf.period = pwm_args.args[1]; - - pf_cool->supply = rt_regulator_get(dev, "fan"); - - if (rt_is_err(pf_cool->supply)) - { - err = rt_ptr_err(pf_cool->supply); - goto _fail; - } - - if ((levels_nr = rt_dm_dev_prop_count_of_u32(dev, "cooling-levels")) <= 0) - { - err = -RT_EINVAL; - goto _fail; - } - - pf_cool->pwm_fan_cooling_levels = rt_calloc(levels_nr, sizeof(rt_uint32_t)); - - if (!pf_cool->pwm_fan_cooling_levels) - { - err = -RT_ENOMEM; - goto _fail; - } - - if (rt_dm_dev_prop_read_u32_array_index(dev, "cooling-levels", - 0, levels_nr, pf_cool->pwm_fan_cooling_levels) <= 0) - { - err = -RT_EINVAL; - goto _fail; - } - - pf_cool->pwm_fan_level = MAX_PWM; - pf_cool->pwm_fan_max_level = levels_nr - 1; - - rt_spin_lock_init(&pf_cool->lock); - pwm_fan_cool_set_cur_level(&pf_cool->parent, 0); - - rt_dm_dev_set_name(&pf_cool->parent.parent, "%s", rt_dm_dev_get_name(&pdev->parent)); - pf_cool->parent.parent.ofw_node = dev->ofw_node; - pf_cool->parent.ops = &pwm_fan_cool_ops; - - if ((err = rt_thermal_cooling_device_register(&pf_cool->parent))) - { - goto _fail; - } - - dev->user_data = pf_cool; - - return RT_EOK; - -_fail: - pwm_fan_cool_free(pf_cool); - - return err; -} - -static rt_err_t pwm_fan_cool_remove(struct rt_platform_device *pdev) -{ - struct pwm_fan_cool *pf_cool = pdev->parent.ofw_node; - - rt_thermal_cooling_device_unregister(&pf_cool->parent); - - pwm_fan_power_off(pf_cool); - pwm_fan_cool_free(pf_cool); - - return RT_EOK; -} - -static rt_err_t pwm_fan_cool_shutdown(struct rt_platform_device *pdev) -{ - return pwm_fan_cool_remove(pdev); -} - -static const struct rt_ofw_node_id pwm_fan_cool_ofw_ids[] = -{ - { .compatible = "pwm-fan" }, - { /* sentinel */ } -}; - -static struct rt_platform_driver pwm_fan_cool_driver = -{ - .name = "pwm-fan-cool", - .ids = pwm_fan_cool_ofw_ids, - - .probe = pwm_fan_cool_probe, - .remove = pwm_fan_cool_remove, - .shutdown = pwm_fan_cool_shutdown, -}; -RT_PLATFORM_DRIVER_EXPORT(pwm_fan_cool_driver); diff --git a/rt-thread/components/drivers/thermal/thermal.c b/rt-thread/components/drivers/thermal/thermal.c deleted file mode 100644 index e9765c8..0000000 --- a/rt-thread/components/drivers/thermal/thermal.c +++ /dev/null @@ -1,917 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#include - -#define DBG_TAG "rtdm.thermal" -#define DBG_LVL DBG_INFO -#include - -#include "thermal_dm.h" - -#ifndef INT_MAX -#define INT_MAX (RT_UINT32_MAX >> 1) -#endif - -#define device_list(dev) (dev)->parent.parent.list -#define device_foreach(dev, nodes) rt_list_for_each_entry(dev, nodes, parent.parent.list) - -static struct rt_spinlock nodes_lock = {}; -static rt_list_t thermal_zone_device_nodes = RT_LIST_OBJECT_INIT(thermal_zone_device_nodes); -static rt_list_t thermal_cooling_device_nodes = RT_LIST_OBJECT_INIT(thermal_cooling_device_nodes); -static rt_list_t thermal_cooling_governor_nodes = RT_LIST_OBJECT_INIT(thermal_cooling_governor_nodes); - -#ifdef RT_USING_OFW -static void thermal_ofw_params_parse(struct rt_ofw_node *np, - struct rt_thermal_zone_params *tz_params) -{ - rt_uint32_t coef[2], prop; - - if (!np) - { - return; - } - - if (!rt_ofw_prop_read_u32(np, "sustainable-power", &prop)) - { - tz_params->sustainable_power = prop; - } - - /* - * For now, the thermal framework supports only one sensor per thermal zone. - * Thus, we are considering only the first two values as slope and offset. - */ - if (rt_ofw_prop_read_u32_array_index(np, "coefficients", 0, 1, coef) < 0) - { - coef[0] = 1; - coef[1] = 0; - } - - tz_params->slope = coef[0]; - tz_params->offset = coef[1]; -} - -static void thermal_ofw_setup(struct rt_ofw_node *np, struct rt_thermal_zone_device *zdev) -{ - int i = 0; - rt_uint32_t delay, pdelay; - struct rt_ofw_cell_args args; - struct rt_ofw_node *tmp_np, *tz_np, *trip_np, *cm_np, *cdev_np; - - if (!np || !zdev) - { - return; - } - - tmp_np = rt_ofw_find_node_by_path("/thermal-zones"); - - if (!tmp_np) - { - return; - } - - rt_ofw_foreach_child_node(tmp_np, tz_np) - { - if (!rt_ofw_parse_phandle_cells(tz_np, "thermal-sensors", "#thermal-sensor-cells", 0, &args)) - { - if (args.data == np && (!args.args_count || args.args[0] == zdev->zone_id)) - { - rt_ofw_node_put(args.data); - - goto _found; - } - rt_ofw_node_put(args.data); - } - } - - return; - -_found: - rt_ofw_prop_read_u32(tz_np, "polling-delay-passive", &pdelay); - rt_ofw_prop_read_u32(tz_np, "polling-delay", &delay); - - zdev->passive_delay = rt_tick_from_millisecond(pdelay); - zdev->polling_delay = rt_tick_from_millisecond(delay); - - thermal_ofw_params_parse(tz_np, &zdev->params); - - if (zdev->trips_nr) - { - goto _scan_cooling; - } - - tmp_np = rt_ofw_get_child_by_tag(tz_np, "trips"); - if (!tmp_np) - { - goto _scan_cooling; - } - - zdev->trips_nr = rt_ofw_get_child_count(tmp_np); - if (!zdev->trips_nr) - { - goto _scan_cooling; - } - zdev->trips = rt_calloc(zdev->trips_nr, sizeof(*zdev->trips)); - zdev->trips_free = RT_TRUE; - - if (!zdev->trips) - { - LOG_E("%s: No memory to create %s", rt_ofw_node_full_name(np), "trips"); - RT_ASSERT(0); - } - - rt_ofw_foreach_child_node(tmp_np, trip_np) - { - const char *type; - - rt_ofw_prop_read_u32(trip_np, "temperature", (rt_uint32_t *)&zdev->trips[i].temperature); - rt_ofw_prop_read_u32(trip_np, "hysteresis", (rt_uint32_t *)&zdev->trips[i].hysteresis); - rt_ofw_prop_read_string(trip_np, "type", &type); - zdev->trips[i].type = thermal_type(type); - - rt_ofw_data(trip_np) = &zdev->trips[i]; - - ++i; - } - -_scan_cooling: - i = 0; - tmp_np = rt_ofw_get_child_by_tag(tz_np, "cooling-maps"); - if (!tmp_np) - { - goto _end; - } - - zdev->cooling_maps_nr = rt_ofw_get_child_count(tmp_np); - if (!zdev->cooling_maps_nr) - { - goto _end; - } - zdev->cooling_maps = rt_calloc(zdev->cooling_maps_nr, sizeof(*zdev->cooling_maps)); - - if (!zdev->cooling_maps) - { - LOG_E("%s: No memory to create %s", rt_ofw_node_full_name(np), "cooling_maps"); - RT_ASSERT(0); - } - - rt_ofw_foreach_child_node(tmp_np, cm_np) - { - struct rt_thermal_cooling_device *cdev; - struct rt_thermal_cooling_map *map = &zdev->cooling_maps[i++]; - - map->cells_nr = rt_ofw_count_phandle_cells(cm_np, "cooling-device", "#cooling-cells"); - map->cells = rt_calloc(sizeof(*map->cells), map->cells_nr); - - if (!map->cells) - { - LOG_E("%s: No memory to create %s", rt_ofw_node_full_name(np), "cells"); - RT_ASSERT(0); - } - - trip_np = rt_ofw_parse_phandle(cm_np, "trip", 0); - map->trips = rt_ofw_data(trip_np); - rt_ofw_node_put(trip_np); - - if (!map->trips) - { - LOG_E("%s: trips(%s) not found", rt_ofw_node_full_name(np), - rt_ofw_node_full_name(trip_np)); - RT_ASSERT(0); - } - - rt_ofw_prop_read_u32(cm_np, "contribution", &map->contribution); - - for (int c = 0; c < map->cells_nr; ++c) - { - struct rt_thermal_cooling_cell *cell = &map->cells[c]; - - if (rt_ofw_parse_phandle_cells(cm_np, "cooling-device", "#cooling-cells", c, &args)) - { - continue; - } - - cdev_np = args.data; - - rt_spin_lock(&nodes_lock); - device_foreach(cdev, &thermal_cooling_device_nodes) - { - if (cdev->parent.ofw_node == cdev_np) - { - cell->cooling_devices = cdev; - break; - } - } - rt_spin_unlock(&nodes_lock); - - cell->level_range[0] = args.args[0]; - cell->level_range[1] = args.args[1]; - - if (cell->cooling_devices) - { - thermal_bind(cell->cooling_devices, zdev); - } - - rt_ofw_node_put(cdev_np); - } - } -_end: -} -#else -rt_inline void thermal_ofw_setup(struct rt_ofw_node *np, struct rt_thermal_zone_device *zdev) -{ -} -#endif /* RT_USING_OFW */ - -static void thermal_zone_poll(struct rt_work *work, void *work_data) -{ - struct rt_thermal_zone_device *zdev = work_data; - - rt_thermal_zone_device_update(zdev, RT_THERMAL_MSG_EVENT_UNSPECIFIED); -} - -rt_err_t rt_thermal_zone_device_register(struct rt_thermal_zone_device *zdev) -{ - if (!zdev || !zdev->ops || !zdev->ops->get_temp) - { - return -RT_EINVAL; - } - - zdev->ops->get_temp(zdev, &zdev->temperature); - zdev->last_temperature = zdev->temperature; - - if (!zdev->trips) - { - zdev->trips_nr = 0; - } - - rt_spin_lock_init(&zdev->nodes_lock); - rt_list_init(&zdev->notifier_nodes); - rt_list_init(&device_list(zdev)); - rt_mutex_init(&zdev->mutex, rt_dm_dev_get_name(&zdev->parent), RT_IPC_FLAG_PRIO); - - zdev->temperature = RT_THERMAL_TEMP_INVALID; - zdev->prev_low_trip = -INT_MAX; - zdev->prev_high_trip = INT_MAX; - - rt_spin_lock(&nodes_lock); - rt_list_insert_before(&thermal_zone_device_nodes, &device_list(zdev)); - rt_spin_unlock(&nodes_lock); - - thermal_ofw_setup(zdev->parent.ofw_node, zdev); - - rt_work_init(&zdev->poller, thermal_zone_poll, zdev); - zdev->enabled = RT_TRUE; - - /* Start to poll */ - rt_work_submit(&zdev->poller, zdev->polling_delay); - - return RT_EOK; -} - -rt_err_t rt_thermal_zone_device_unregister(struct rt_thermal_zone_device *zdev) -{ - if (!zdev) - { - return -RT_EINVAL; - } - - rt_spin_lock(&zdev->nodes_lock); - if (rt_list_isempty(&zdev->notifier_nodes)) - { - LOG_E("%s: there is %u user", rt_dm_dev_get_name(&zdev->parent), - rt_list_len(&zdev->notifier_nodes)); - - rt_spin_unlock(&zdev->nodes_lock); - - return -RT_EBUSY; - } - rt_spin_unlock(&zdev->nodes_lock); - - rt_work_cancel(&zdev->poller); - - rt_spin_lock(&nodes_lock); - rt_list_remove(&device_list(zdev)); - rt_spin_unlock(&nodes_lock); - - if (zdev->trips_free && zdev->trips) - { - rt_free(zdev->trips); - } - - if (zdev->cooling_maps_nr && zdev->cooling_maps_nr) - { - for (int i = 0; i < zdev->cooling_maps_nr; ++i) - { - struct rt_thermal_cooling_device *cdev; - struct rt_thermal_cooling_map *map = &zdev->cooling_maps[i]; - - for (int c = 0; c < map->cells_nr; ++c) - { - cdev = map->cells[i].cooling_devices; - - if (cdev) - { - thermal_unbind(cdev, zdev); - } - } - - rt_free(map->cells); - } - - rt_free(zdev->cooling_maps); - } - - rt_mutex_detach(&zdev->mutex); - - return RT_EOK; -} - -rt_err_t rt_thermal_cooling_device_register(struct rt_thermal_cooling_device *cdev) -{ - rt_err_t err; - - if (!cdev || !cdev->ops || - !cdev->ops->get_max_level || !cdev->ops->get_cur_level || !cdev->ops->set_cur_level) - { - return -RT_EINVAL; - } - - if ((err = cdev->ops->get_max_level(cdev, &cdev->max_level))) - { - return err; - } - - rt_list_init(&device_list(cdev)); - rt_list_init(&cdev->governor_node); - - rt_spin_lock(&nodes_lock); - rt_list_insert_before(&thermal_cooling_device_nodes, &device_list(cdev)); - rt_spin_unlock(&nodes_lock); - - err = rt_thermal_cooling_device_change_governor(cdev, RT_NULL); - - return err; -} - -rt_err_t rt_thermal_cooling_device_unregister(struct rt_thermal_cooling_device *cdev) -{ - if (!cdev) - { - return -RT_EINVAL; - } - - if (cdev->parent.ref_count) - { - LOG_E("%s: there is %u user", - rt_dm_dev_get_name(&cdev->parent), cdev->parent.ref_count); - return -RT_EINVAL; - } - - rt_spin_lock(&nodes_lock); - rt_list_remove(&device_list(cdev)); - rt_spin_unlock(&nodes_lock); - - return RT_EOK; -} - -static void dumb_governor_tuning(struct rt_thermal_zone_device *zdev, - int map_idx, int cell_idx, rt_ubase_t *level) -{ - struct rt_thermal_cooling_map *map = &zdev->cooling_maps[map_idx]; - - if (zdev->cooling && zdev->temperature > map->trips->temperature) - { - if (zdev->temperature - zdev->last_temperature > map->trips->hysteresis) - { - ++*level; - } - else if (zdev->last_temperature - zdev->temperature > map->trips->hysteresis) - { - --*level; - } - } - else - { - *level = 0; - } -} - -static struct rt_thermal_cooling_governor dumb_governor = -{ - .name = "dumb", - .tuning = dumb_governor_tuning, -}; - -static int system_thermal_cooling_governor_init(void) -{ - rt_thermal_cooling_governor_register(&dumb_governor); - - return 0; -} -INIT_CORE_EXPORT(system_thermal_cooling_governor_init); - -rt_err_t rt_thermal_cooling_governor_register(struct rt_thermal_cooling_governor *gov) -{ - rt_err_t err = RT_EOK; - struct rt_thermal_cooling_governor *gov_tmp; - - if (!gov || !gov->name || !gov->tuning) - { - return -RT_EINVAL; - } - - rt_list_init(&gov->list); - rt_list_init(&gov->cdev_nodes); - - rt_spin_lock(&nodes_lock); - - rt_list_for_each_entry(gov_tmp, &thermal_cooling_governor_nodes, list) - { - if (!rt_strcmp(gov_tmp->name, gov->name)) - { - err = -RT_ERROR; - goto _out_unlock; - } - } - - rt_list_insert_before(&thermal_cooling_governor_nodes, &gov->list); - -_out_unlock: - rt_spin_unlock(&nodes_lock); - - return err; -} - -rt_err_t rt_thermal_cooling_governor_unregister(struct rt_thermal_cooling_governor *gov) -{ - if (!gov) - { - return -RT_EINVAL; - } - - if (gov == &dumb_governor) - { - return -RT_EINVAL; - } - - rt_spin_lock(&nodes_lock); - - if (!rt_list_isempty(&gov->cdev_nodes)) - { - goto _out_unlock; - } - - rt_list_remove(&gov->list); - -_out_unlock: - rt_spin_unlock(&nodes_lock); - - return RT_EOK; -} - -rt_err_t rt_thermal_cooling_device_change_governor(struct rt_thermal_cooling_device *cdev, - const char *name) -{ - rt_err_t err; - struct rt_thermal_cooling_governor *gov; - - if (!cdev) - { - return -RT_EINVAL; - } - - name = name ? : dumb_governor.name; - err = -RT_ENOSYS; - - rt_spin_lock(&nodes_lock); - - rt_list_for_each_entry(gov, &thermal_cooling_governor_nodes, list) - { - if (!rt_strcmp(gov->name, name)) - { - if (cdev->gov) - { - rt_list_remove(&cdev->governor_node); - } - - cdev->gov = gov; - rt_list_insert_before(&cdev->governor_node, &gov->cdev_nodes); - - err = RT_EOK; - break; - } - } - - rt_spin_unlock(&nodes_lock); - - return err; -} - -rt_err_t rt_thermal_zone_notifier_register(struct rt_thermal_zone_device *zdev, - struct rt_thermal_notifier *notifier) -{ - if (!zdev || !notifier) - { - return -RT_EINVAL; - } - - notifier->zdev = zdev; - rt_list_init(¬ifier->list); - - rt_spin_lock(&zdev->nodes_lock); - rt_list_insert_after(&zdev->notifier_nodes, ¬ifier->list); - rt_spin_unlock(&zdev->nodes_lock); - - return RT_EOK; -} - -rt_err_t rt_thermal_zone_notifier_unregister(struct rt_thermal_zone_device *zdev, - struct rt_thermal_notifier *notifier) -{ - if (!zdev || !notifier) - { - return -RT_EINVAL; - } - - rt_spin_lock(&zdev->nodes_lock); - rt_list_remove(¬ifier->list); - rt_spin_unlock(&zdev->nodes_lock); - - return RT_EOK; -} - -void rt_thermal_zone_device_update(struct rt_thermal_zone_device *zdev, rt_ubase_t msg) -{ - rt_err_t err; - rt_bool_t passive = RT_FALSE, need_cool = RT_FALSE; - struct rt_thermal_notifier *notifier, *next_notifier; - - RT_ASSERT(zdev != RT_NULL); - - if (!rt_interrupt_get_nest()) - { - rt_mutex_take(&zdev->mutex, RT_WAITING_FOREVER); - } - - /* Check thermal zone status */ - if (msg == RT_THERMAL_MSG_DEVICE_DOWN) - { - zdev->enabled = RT_FALSE; - } - else if (msg == RT_THERMAL_MSG_DEVICE_UP) - { - zdev->enabled = RT_TRUE; - } - - /* Read temperature */ - zdev->last_temperature = zdev->temperature; - zdev->ops->get_temp(zdev, &zdev->temperature); - - for (int i = 0; i < zdev->trips_nr; ++i) - { - struct rt_thermal_trip *tmp_trip = &zdev->trips[i]; - - if (zdev->temperature <= tmp_trip->temperature) - { - continue; - } - - switch (tmp_trip->type) - { - case RT_THERMAL_TRIP_PASSIVE: - passive = RT_TRUE; - goto cooling; - - case RT_THERMAL_TRIP_CRITICAL: - if (zdev->ops->critical) - { - zdev->ops->critical(zdev); - } - else if (zdev->last_temperature > tmp_trip->temperature) - { - /* Tried to cool already, but failed */ - rt_hw_cpu_reset(); - } - else - { - goto cooling; - } - break; - - case RT_THERMAL_TRIP_HOT: - if (zdev->ops->hot) - { - zdev->ops->hot(zdev); - break; - } - - default: - cooling: - zdev->cooling = need_cool = RT_TRUE; - rt_thermal_cooling_device_kick(zdev); - break; - } - } - - if (!need_cool && zdev->cooling) - { - rt_thermal_cooling_device_kick(zdev); - } - - /* Set the new trips */ - if (zdev->ops->set_trips) - { - rt_bool_t same_trip = RT_FALSE; - int low = -INT_MAX, high = INT_MAX; - struct rt_thermal_trip trip; - - for (int i = 0; i < zdev->trips_nr; ++i) - { - int trip_low; - rt_bool_t low_set = RT_FALSE; - - if (i >= zdev->trips_nr) - { - goto _call_notifier; - } - rt_memcpy(&trip, &zdev->trips[i], sizeof(trip)); - - trip_low = trip.temperature - trip.hysteresis; - - if (trip_low < zdev->temperature && trip_low > low) - { - low = trip_low; - low_set = RT_TRUE; - same_trip = RT_FALSE; - } - - if (trip.temperature > zdev->temperature && trip.temperature < high) - { - high = trip.temperature; - same_trip = low_set; - } - } - - /* No need to change trip points */ - if (zdev->prev_low_trip == low && zdev->prev_high_trip == high) - { - goto _call_notifier; - } - - if (same_trip && - (zdev->prev_low_trip != -INT_MAX || zdev->prev_high_trip != INT_MAX)) - { - goto _call_notifier; - } - - zdev->prev_low_trip = low; - zdev->prev_high_trip = high; - - if ((err = zdev->ops->set_trips(zdev, low, high))) - { - LOG_E("%s: Set trips error = %s", rt_dm_dev_get_name(&zdev->parent), - rt_strerror(err)); - } - } - - /* Call all notifier, maybe have governor */ -_call_notifier: - rt_spin_lock(&zdev->nodes_lock); - - rt_list_for_each_entry_safe(notifier, next_notifier, &zdev->notifier_nodes, list) - { - rt_spin_unlock(&zdev->nodes_lock); - - notifier->callback(notifier, msg); - - rt_spin_lock(&zdev->nodes_lock); - } - - rt_spin_unlock(&zdev->nodes_lock); - - /* Prepare for the next report */ - if (!zdev->enabled) - { - rt_work_cancel(&zdev->poller); - } - else if (passive && zdev->passive_delay) - { - rt_work_submit(&zdev->poller, zdev->passive_delay); - } - else if (zdev->polling_delay) - { - rt_work_submit(&zdev->poller, zdev->polling_delay); - } - - if (!rt_interrupt_get_nest()) - { - rt_mutex_release(&zdev->mutex); - } -} - -void rt_thermal_cooling_device_kick(struct rt_thermal_zone_device *zdev) -{ - RT_ASSERT(zdev != RT_NULL); - - for (int i = 0; i < zdev->cooling_maps_nr; ++i) - { - rt_ubase_t level; - struct rt_thermal_cooling_device *cdev; - struct rt_thermal_cooling_cell *cell; - struct rt_thermal_cooling_map *map = &zdev->cooling_maps[i]; - - for (int c = 0; c < map->cells_nr; ++c) - { - cell = &map->cells[c]; - cdev = cell->cooling_devices; - - if (!cdev) - { - continue; - } - - /* Update status */ - if (cdev->ops->get_max_level(cdev, &cdev->max_level)) - { - continue; - } - - if (cdev->ops->get_cur_level(cdev, &level) || level > cdev->max_level) - { - continue; - } - - /* Check if cooling is required */ - if (level >= cell->level_range[0] && level <= cell->level_range[1]) - { - /* Is cooling, not call */ - continue; - } - - cdev->gov->tuning(zdev, i, c, &level); - level = rt_min_t(rt_ubase_t, level, cdev->max_level); - - cdev->ops->set_cur_level(cdev, level); - } - } -} - -rt_err_t rt_thermal_zone_set_trip(struct rt_thermal_zone_device *zdev, int trip_id, - const struct rt_thermal_trip *trip) -{ - rt_err_t err; - struct rt_thermal_trip tmp_trip; - - if (!zdev || !trip) - { - return -RT_EINVAL; - } - - rt_mutex_take(&zdev->mutex, RT_WAITING_FOREVER); - - if (!zdev->ops->set_trip_temp && !zdev->ops->set_trip_hyst && !zdev->trips) - { - err = -RT_EINVAL; - goto _out_unlock; - } - - if (trip_id >= zdev->trips_nr) - { - err = -RT_EINVAL; - goto _out_unlock; - } - - rt_memcpy(&tmp_trip, &zdev->trips[trip_id], sizeof(tmp_trip)); - - if (tmp_trip.type != trip->type) - { - err = -RT_EINVAL; - goto _out_unlock; - } - - if (tmp_trip.temperature != trip->temperature && zdev->ops->set_trip_temp) - { - if ((err = zdev->ops->set_trip_temp(zdev, trip_id, trip->temperature))) - { - goto _out_unlock; - } - } - - if (tmp_trip.hysteresis != trip->hysteresis && zdev->ops->set_trip_hyst) - { - if ((err = zdev->ops->set_trip_hyst(zdev, trip_id, trip->hysteresis))) - { - goto _out_unlock; - } - } - - if (zdev->trips && - (tmp_trip.temperature != trip->temperature || tmp_trip.hysteresis != trip->hysteresis)) - { - zdev->trips[trip_id] = *trip; - } - -_out_unlock: - rt_mutex_release(&zdev->mutex); - - if (!err) - { - rt_thermal_zone_device_update(zdev, RT_THERMAL_MSG_TRIP_CHANGED); - } - - return err; -} - -rt_err_t rt_thermal_zone_get_trip(struct rt_thermal_zone_device *zdev, int trip_id, - struct rt_thermal_trip *out_trip) -{ - rt_err_t err = RT_EOK; - - if (!zdev || !out_trip) - { - return -RT_EINVAL; - } - - rt_mutex_take(&zdev->mutex, RT_WAITING_FOREVER); - - if (!zdev->trips_nr) - { - err = -RT_ENOSYS; - goto _out_unlock; - } - - if (trip_id >= zdev->trips_nr) - { - err = -RT_EINVAL; - goto _out_unlock; - } - - *out_trip = zdev->trips[trip_id]; - -_out_unlock: - rt_mutex_release(&zdev->mutex); - - return err; -} - -#if defined(RT_USING_CONSOLE) && defined(RT_USING_MSH) -static int list_thermal(int argc, char**argv) -{ - struct rt_thermal_zone_device *zdev; - - /* Thermal is an important subsystem, please do not output too much. */ - rt_spin_lock(&nodes_lock); - device_foreach(zdev, &thermal_zone_device_nodes) - { - int temperature = zdev->temperature; - - rt_kprintf("%s-%d\n", rt_dm_dev_get_name(&zdev->parent), zdev->zone_id); - rt_kprintf("temperature:\t%+d.%u C\n", temperature / 1000, rt_abs(temperature) % 1000); - - for (int i = 0, id = 0; i < zdev->cooling_maps_nr; ++i) - { - rt_ubase_t level; - struct rt_thermal_trip *trips; - struct rt_thermal_cooling_device *cdev; - struct rt_thermal_cooling_cell *cell; - struct rt_thermal_cooling_map *map = &zdev->cooling_maps[i]; - - for (int c = 0; c < map->cells_nr; ++c, ++id) - { - trips = map->trips; - cell = &map->cells[c]; - cdev = cell->cooling_devices; - - if (cdev) - { - cdev->ops->get_cur_level(cdev, &level); - - rt_kprintf("cooling%u:\t%s[%+d.%u C] %d\n", id, - rt_dm_dev_get_name(&cdev->parent), - trips->temperature / 1000, rt_abs(trips->temperature) % 1000, - level); - } - else - { - rt_kprintf("cooling%u:\t%s[%+d.%u C] %d\n", id, - "(not supported)", - trips->temperature / 1000, rt_abs(trips->temperature) % 1000, - 0); - } - } - } - } - rt_spin_unlock(&nodes_lock); - - return 0; -} -MSH_CMD_EXPORT(list_thermal, dump all of thermal information); -#endif /* RT_USING_CONSOLE && RT_USING_MSH */ diff --git a/rt-thread/components/drivers/thermal/thermal_dm.c b/rt-thread/components/drivers/thermal/thermal_dm.c deleted file mode 100644 index 9c1d81f..0000000 --- a/rt-thread/components/drivers/thermal/thermal_dm.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#define DBG_TAG "rtdm.thermal" -#define DBG_LVL DBG_INFO -#include - -#include "thermal_dm.h" - -enum rt_thermal_trip_type thermal_type(const char *type) -{ - if (!type) - { - return RT_THERMAL_TRIP_TYPE_MAX; - } - - if (!rt_strcmp(type, "active")) - { - return RT_THERMAL_TRIP_ACTIVE; - } - else if (!rt_strcmp(type, "passive")) - { - return RT_THERMAL_TRIP_PASSIVE; - } - else if (!rt_strcmp(type, "hot")) - { - return RT_THERMAL_TRIP_HOT; - } - else if (!rt_strcmp(type, "critical")) - { - return RT_THERMAL_TRIP_CRITICAL; - } - - return RT_THERMAL_TRIP_TYPE_MAX; -} - -rt_err_t thermal_bind(struct rt_thermal_cooling_device *cdev, - struct rt_thermal_zone_device *zdev) -{ - if (cdev->ops->bind) - { - return cdev->ops->bind(cdev, zdev); - } - - return RT_EOK; -} - -rt_err_t thermal_unbind(struct rt_thermal_cooling_device *cdev, - struct rt_thermal_zone_device *zdev) -{ - if (cdev->ops->unbind) - { - return cdev->ops->unbind(cdev, zdev); - } - - return RT_EOK; -} diff --git a/rt-thread/components/drivers/thermal/thermal_dm.h b/rt-thread/components/drivers/thermal/thermal_dm.h deleted file mode 100644 index 15d3314..0000000 --- a/rt-thread/components/drivers/thermal/thermal_dm.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#ifndef __THERMAL_DM_H__ -#define __THERMAL_DM_H__ - -#include -#include -#include - -#include - -enum rt_thermal_trip_type thermal_type(const char *type); - -rt_err_t thermal_bind(struct rt_thermal_cooling_device *cdev, - struct rt_thermal_zone_device *zdev); -rt_err_t thermal_unbind(struct rt_thermal_cooling_device *cdev, - struct rt_thermal_zone_device *zdev); - -#endif /* __THERMAL_DM_H__ */ diff --git a/rt-thread/components/drivers/touch/SConscript b/rt-thread/components/drivers/touch/SConscript index ba646b0..df698c7 100644 --- a/rt-thread/components/drivers/touch/SConscript +++ b/rt-thread/components/drivers/touch/SConscript @@ -3,7 +3,7 @@ from building import * cwd = GetCurrentDir() -src = ['dev_touch.c'] +src = ['touch.c'] CPPPATH = [cwd, cwd + '/../include'] group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_TOUCH', 'RT_USING_DEVICE'], CPPPATH = CPPPATH) diff --git a/rt-thread/components/drivers/touch/dev_touch.c b/rt-thread/components/drivers/touch/dev_touch.c deleted file mode 100644 index 713a6bb..0000000 --- a/rt-thread/components/drivers/touch/dev_touch.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2019-05-20 tyustli the first version - */ - -#include -#include - -#define DBG_TAG "touch" -#define DBG_LVL DBG_INFO -#include - -/* ISR for touch interrupt */ -void rt_hw_touch_isr(rt_touch_t touch) -{ - RT_ASSERT(touch); - if (touch->parent.rx_indicate == RT_NULL) - { - return; - } - - if (touch->irq_handle != RT_NULL) - { - touch->irq_handle(touch); - } - - touch->parent.rx_indicate(&touch->parent, 1); -} - -#ifdef RT_TOUCH_PIN_IRQ -static void touch_irq_callback(void *param) -{ - rt_hw_touch_isr((rt_touch_t)param); -} -#endif - -/* touch interrupt initialization function */ -static rt_err_t rt_touch_irq_init(rt_touch_t touch) -{ -#ifdef RT_TOUCH_PIN_IRQ - if (touch->config.irq_pin.pin == PIN_IRQ_PIN_NONE) - { - return -RT_EINVAL; - } - - rt_pin_mode(touch->config.irq_pin.pin, touch->config.irq_pin.mode); - - if (touch->config.irq_pin.mode == PIN_MODE_INPUT_PULLDOWN) - { - rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_RISING, touch_irq_callback, (void *)touch); - } - else if (touch->config.irq_pin.mode == PIN_MODE_INPUT_PULLUP) - { - rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_FALLING, touch_irq_callback, (void *)touch); - } - else if (touch->config.irq_pin.mode == PIN_MODE_INPUT) - { - rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_RISING_FALLING, touch_irq_callback, (void *)touch); - } - - rt_pin_irq_enable(touch->config.irq_pin.pin, PIN_IRQ_ENABLE); -#endif - - return RT_EOK; -} - -/* touch interrupt enable */ -static void rt_touch_irq_enable(rt_touch_t touch) -{ -#ifdef RT_TOUCH_PIN_IRQ - if (touch->config.irq_pin.pin != PIN_IRQ_PIN_NONE) - { - rt_pin_irq_enable(touch->config.irq_pin.pin, RT_TRUE); - } -#else - touch->ops->touch_control(touch, RT_TOUCH_CTRL_ENABLE_INT, RT_NULL); -#endif -} - -/* touch interrupt disable */ -static void rt_touch_irq_disable(rt_touch_t touch) -{ -#ifdef RT_TOUCH_PIN_IRQ - if (touch->config.irq_pin.pin != PIN_IRQ_PIN_NONE) - { - rt_pin_irq_enable(touch->config.irq_pin.pin, RT_FALSE); - } -#else - touch->ops->touch_control(touch, RT_TOUCH_CTRL_DISABLE_INT, RT_NULL); -#endif -} - -static rt_err_t rt_touch_open(rt_device_t dev, rt_uint16_t oflag) -{ - rt_touch_t touch; - RT_ASSERT(dev != RT_NULL); - touch = (rt_touch_t)dev; - - if (oflag & RT_DEVICE_FLAG_INT_RX && dev->flag & RT_DEVICE_FLAG_INT_RX) - { - /* Initialization touch interrupt */ - rt_touch_irq_init(touch); - } - - return RT_EOK; -} - -static rt_err_t rt_touch_close(rt_device_t dev) -{ - rt_touch_t touch; - RT_ASSERT(dev != RT_NULL); - touch = (rt_touch_t)dev; - - /* touch disable interrupt */ - rt_touch_irq_disable(touch); - - return RT_EOK; -} - -static rt_ssize_t rt_touch_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t len) -{ - rt_touch_t touch; - rt_size_t result = 0; - RT_ASSERT(dev != RT_NULL); - touch = (rt_touch_t)dev; - - if (buf == NULL || len == 0) - { - return 0; - } - - result = touch->ops->touch_readpoint(touch, buf, len); - - return result; -} - -static rt_err_t rt_touch_control(rt_device_t dev, int cmd, void *args) -{ - rt_touch_t touch; - rt_err_t result = RT_EOK; - RT_ASSERT(dev != RT_NULL); - touch = (rt_touch_t)dev; - - switch (cmd) - { - case RT_TOUCH_CTRL_SET_MODE: - result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_SET_MODE, args); - - if (result == RT_EOK) - { - rt_uint16_t mode; - mode = *(rt_uint16_t*)args; - if (mode == RT_DEVICE_FLAG_INT_RX) - { - rt_touch_irq_enable(touch); /* enable interrupt */ - } - } - - break; - case RT_TOUCH_CTRL_SET_X_RANGE: - result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_SET_X_RANGE, args); - - if (result == RT_EOK) - { - touch->info.range_x = *(rt_int32_t *)args; - LOG_D("set x coordinate range :%d\n", touch->info.range_x); - } - - break; - case RT_TOUCH_CTRL_SET_Y_RANGE: - result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_SET_Y_RANGE, args); - - if (result == RT_EOK) - { - touch->info.range_y = *(rt_uint32_t *)args; - LOG_D("set y coordinate range :%d \n", touch->info.range_x); - } - - break; - case RT_TOUCH_CTRL_DISABLE_INT: - rt_touch_irq_disable(touch); - break; - case RT_TOUCH_CTRL_ENABLE_INT: - rt_touch_irq_enable(touch); - break; - - case RT_TOUCH_CTRL_GET_ID: - case RT_TOUCH_CTRL_GET_INFO: - default: - return touch->ops->touch_control(touch, cmd, args); - } - - return result; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops rt_touch_ops = -{ - RT_NULL, - rt_touch_open, - rt_touch_close, - rt_touch_read, - RT_NULL, - rt_touch_control -}; -#endif - -/* - * touch register - */ -int rt_hw_touch_register(rt_touch_t touch, - const char *name, - rt_uint32_t flag, - void *data) -{ - rt_err_t result; - rt_device_t device; - RT_ASSERT(touch != RT_NULL); - - device = &touch->parent; - -#ifdef RT_USING_DEVICE_OPS - device->ops = &rt_touch_ops; -#else - device->init = RT_NULL; - device->open = rt_touch_open; - device->close = rt_touch_close; - device->read = rt_touch_read; - device->write = RT_NULL; - device->control = rt_touch_control; -#endif - device->type = RT_Device_Class_Touch; - device->rx_indicate = RT_NULL; - device->tx_complete = RT_NULL; - device->user_data = data; - - result = rt_device_register(device, name, flag | RT_DEVICE_FLAG_STANDALONE); - - if (result != RT_EOK) - { - LOG_E("rt_touch register err code: %d", result); - return result; - } - - LOG_I("rt_touch init success"); - - return RT_EOK; -} diff --git a/rt-thread/components/drivers/usb/cherryusb/CherryUSB.svg b/rt-thread/components/drivers/usb/cherryusb/CherryUSB.svg index 91de329..c1ed478 100644 --- a/rt-thread/components/drivers/usb/cherryusb/CherryUSB.svg +++ b/rt-thread/components/drivers/usb/cherryusb/CherryUSB.svg @@ -1,3 +1,3 @@ -
CherryUSB
CherryUSB
Hardware
Hardware
CDNS3
CDNS3
CHIPIDEA
CHIPIDEA
XHCI
XHCI
EHCI
EHCI
OHCI
OHCI
DWC2
DWC2
MUSB
MUSB
FOTG
FOTG
Device Controller Driver (DCD)
Device Controller Driver (DCD)
Host Controller Driver (HCD)
Host Controller Driver (HCD)
OS Abstraction Layer (OSAL)
OS Abstraction Layer (OSAL)
USB Host
USB Host
USB Host Core
USB Host Core
HID
HID
MSC
MSC
CDC
CDC
UAC
UAC
UVC
UVC
RNDIS
RNDIS
VENDOR
VENDOR
HUB
HUB
USB Device
USB Device
USB Device Core
USB Device Core
HID
HID
MSC
MSC
CDC
CDC
UAC
UAC
UVC
UVC
RNDIS
RNDIS
VENDOR
VENDOR
DFU
DFU
optional
optional
required
required
\ No newline at end of file +
CherryUSB
CherryUSB
Hardware
Hardware
BL
BL
DWC2
DWC2
OHCI
OHCI
EHCI
EHCI
XHCI
XHCI
MUSB
MUSB
FSDEV
FSDEV
HPM
HPM
Device Controller Driver (DCD)
Device Controller Driver (DCD)
Host Controller Driver (HCD)
Host Controller Driver (HCD)
OS Abstraction Layer (OSAL)
OS Abstraction Layer (OSAL)
USB Host
USB Host
USB Host Core
USB Host Core
HID
HID
MSC
MSC
CDC
CDC
UAC
UAC
UVC
UVC
RNDIS
RNDIS
VENDOR
VENDOR
HUB
HUB
USB Device
USB Device
USB Device Core
USB Device Core
HID
HID
MSC
MSC
CDC
CDC
UAC
UAC
UVC
UVC
RNDIS
RNDIS
VENDOR
VENDOR
DFU
DFU
optional
optional
required
required
Text is not SVG - cannot display
\ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/Kconfig b/rt-thread/components/drivers/usb/cherryusb/Kconfig index 67c6ad5..3e9ce5f 100644 --- a/rt-thread/components/drivers/usb/cherryusb/Kconfig +++ b/rt-thread/components/drivers/usb/cherryusb/Kconfig @@ -38,8 +38,6 @@ if RT_USING_CHERRYUSB bool "dwc2_gd" config RT_CHERRYUSB_DEVICE_DWC2_HC bool "dwc2_hc" - config RT_CHERRYUSB_DEVICE_DWC2_KENDRYTE - bool "dwc2_kendryte" config RT_CHERRYUSB_DEVICE_DWC2_CUSTOM bool "dwc2_custom" config RT_CHERRYUSB_DEVICE_MUSB_ES @@ -50,14 +48,6 @@ if RT_USING_CHERRYUSB bool "musb_bk" config RT_CHERRYUSB_DEVICE_MUSB_CUSTOM bool "musb_custom" - config RT_CHERRYUSB_DEVICE_KINETIS_MCX - bool "kinetis_mcx" - config RT_CHERRYUSB_DEVICE_KINETIS_CUSTOM - bool "kinetis_custom" - config RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX - bool "chipidea_mcx" - config RT_CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM - bool "chipidea_custom" config RT_CHERRYUSB_DEVICE_BL bool "bouffalo" config RT_CHERRYUSB_DEVICE_CH32 @@ -117,7 +107,7 @@ if RT_USING_CHERRYUSB choice prompt "Select usb device template" - default RT_CHERRYUSB_DEVICE_TEMPLATE_NONE + default RT_CHERRYUSB_DEVICE_TEMPLATE config RT_CHERRYUSB_DEVICE_TEMPLATE_NONE bool "none (Implement it yourself)" config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM @@ -172,20 +162,16 @@ if RT_USING_CHERRYUSB bool "ehci_hpm" config RT_CHERRYUSB_HOST_EHCI_AIC bool "ehci_aic" - config RT_CHERRYUSB_HOST_EHCI_MCX - bool "ehci_mcx" - config RT_CHERRYUSB_HOST_EHCI_NUC980 - bool "ehci_nuc980" - config RT_CHERRYUSB_HOST_EHCI_MA35D0 - bool "ehci_ma35d0" + config RT_CHERRYUSB_HOST_EHCI_NUVOTON_NUC980 + bool "ehci_nuvoton_nuc980" + config RT_CHERRYUSB_HOST_EHCI_NUVOTON_MA35D0 + bool "ehci_nuvoton_ma35d0" config RT_CHERRYUSB_HOST_EHCI_CUSTOM bool "ehci_custom" config RT_CHERRYUSB_HOST_DWC2_ST bool "dwc2_st" config RT_CHERRYUSB_HOST_DWC2_ESP bool "dwc2_esp" - config RT_CHERRYUSB_HOST_DWC2_KENDRYTE - bool "dwc2_kendryte" config RT_CHERRYUSB_HOST_DWC2_CUSTOM bool "dwc2_custom" config RT_CHERRYUSB_HOST_MUSB_ES @@ -200,10 +186,6 @@ if RT_USING_CHERRYUSB bool "pusb2" config RT_CHERRYUSB_HOST_XHCI bool "xhci" - config RT_CHERRYUSB_HOST_KINETIS_MCX - bool "kinetis_mcx" - config RT_CHERRYUSB_HOST_KINETIS_CUSTOM - bool "kinetis_custom" endchoice config RT_CHERRYUSB_HOST_CDC_ACM @@ -221,7 +203,6 @@ if RT_USING_CHERRYUSB prompt "Enable usb msc driver" default n select RT_USING_DFS - select RT_USING_DFS_ELMFAT config RT_CHERRYUSB_HOST_CDC_ECM bool @@ -313,12 +294,7 @@ if RT_USING_CHERRYUSB config CONFIG_USBHOST_PLATFORM_RTL8152 bool - config RT_LWIP_PBUF_POOL_BUFSIZE - int "The size of each pbuf in the pbuf pool" - range 1500 2000 - default 1600 - - config RT_CHERRYUSB_HOST_TEMPLATE + config CHERRYUSB_HOST_TEMPLATE bool prompt "Use usb host template" default n diff --git a/rt-thread/components/drivers/usb/cherryusb/README.md b/rt-thread/components/drivers/usb/cherryusb/README.md index e56946a..d79df88 100644 --- a/rt-thread/components/drivers/usb/cherryusb/README.md +++ b/rt-thread/components/drivers/usb/cherryusb/README.md @@ -1,16 +1,6 @@ -

CherryUSB

-

- - - - -

+# CherryUSB -

- 中文 - | - English -

+[中文版](./README_zh.md) CherryUSB is a tiny, beautiful and portable USB host and device stack for embedded system with USB IP. @@ -27,12 +17,12 @@ In order to make it easier for users to learn USB basics, enumeration, driver lo - Class-drivers and porting-drivers are templating and simplification - Clear API classification (slave: initialisation, registration api, command callback api, data sending and receiving api; host: initialisation, lookup api, data sending and receiving api) -### Easy to use USB +### Easy to use USB In order to facilitate the use of the USB interface and to take into account the fact that users have learned about uart and dma, the following advantages have been designed for the data sending and receiving class of interface: - Equivalent to using uart tx dma/uart rx dma -- There is no limit to the length of send and receive, the user does not need to care about the USB packetization process (the porting driver does it) +- There is no limit to the length of send and receive, the user does not need to care about the USB packetization process (the porting driver does the packetization process) ### Easy to bring out USB performance @@ -42,9 +32,9 @@ Taking into account USB performance issues and trying to achieve the theoretical - Memory zero copy - If IP has DMA then uses DMA mode (DMA with hardware packetization) - Unlimited length make it easier to interface with hardware DMA and take advantage of DMA -- Packetization is handled in interrupt +- Subcontracting function is handled in interrupt -## Directory Structure +## Directoy Structure | Directory | Description | |:-------------:|:---------------------------:| @@ -75,23 +65,21 @@ CherryUSB Device Stack has the following functions: - Support Device Firmware Upgrade CLASS (DFU) - Support USB MIDI CLASS (MIDI) - Support Remote NDIS (RNDIS) -- Support WINUSB1.0、WINUSB2.0、WEBUSB、BOS +- Support WINUSB1.0、WINUSB2.0(with BOS) - Support Vendor class -- Support UF2 -- Support Android Debug Bridge (Only support shell) - Support multi device with the same USB IP CherryUSB Device Stack resource usage (GCC 10.2 with -O2): | file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) | |:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:| -|usbd_core.c | ~4400 | 512(default) + 320 | 0 | 0 | -|usbd_cdc_acm.c | ~400 | 0 | 0 | 0 | -|usbd_msc.c | ~3800 | 128 + 512(default) | 16 | 0 | -|usbd_hid.c | ~360 | 0 | 0 | 0 | -|usbd_audio.c | ~1500 | 0 | 0 | 0 | -|usbd_video.c | ~2600 | 0 | 84 | 0 | -|usbd_rndis.c | ~2100 | 2 * 1580(default)+156+8 | 76 | 0 | +|usbd_core.c | 3516 | 256(default) + 320 | 0 | 0 | +|usbd_cdc.c | 392 | 0 | 0 | 0 | +|usbd_msc.c | 2839 | 128 + 512(default) | 16 | 0 | +|usbd_hid.c | 364 | 0 | 0 | 0 | +|usbd_audio.c | 1455 | 0 | 0 | 0 | +|usbd_video.c | 2494 | 0 | 84 | 0 | +|usbd_rndis.c | 2109 | 3340 | 76 | 0 | ## Host Stack Overview @@ -99,7 +87,6 @@ The CherryUSB Host Stack has a standard enumeration implementation for devices m CherryUSB Host Stack has the following functions: -- Support low speed, full speed, high speed and super speed devices - Automatic loading of supported Class drivers - Support blocking transfers and asynchronous transfers - Support Composite Device @@ -111,9 +98,8 @@ CherryUSB Host Stack has the following functions: - Support USB Audio CLASS (UAC1.0) - Support Remote NDIS (RNDIS) - Support USB Bluetooth class (support nimble and zephyr bluetooth stack, support **CLASS:0xE0** or vendor class like cdc acm) -- Support Vendor class (serial, net, wifi) +- Support Vendor class - Support USB modeswitch -- Support Android Open Accessory - Support multi host with the same USB IP The CherryUSB Host stack also provides the lsusb function, which allows you to view information about all mounted devices, including those on external hubs, with the help of a shell plugin. @@ -122,17 +108,16 @@ CherryUSB Host Stack resource usage (GCC 10.2 with -O2): | file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) | |:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:------------:| -|usbh_core.c | ~9000 | 512 + 8 * (1+x) *n | 28 | raw_config_desc | -|usbh_hub.c | ~6000 | 32 + 4 * (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 | -|usbh_cdc_acm.c | ~900 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 | -|usbh_msc.c | ~2700 | 64 | 4 + sizeof(struct usbh_msc) * x | 0 | -|usbh_hid.c | ~1400 | 256 | 4 + sizeof(struct usbh_hid) * x | 0 | -|usbh_video.c | ~3800 | 128 | 4 + sizeof(struct usbh_video) * x | 0 | -|usbh_audio.c | ~4100 | 128 | 4 + sizeof(struct usbh_audio) * x | 0 | -|usbh_rndis.c | ~4200 | 512 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 | -|usbh_cdc_ecm.c | ~2200 | 2 * 1514 + 16 | sizeof(struct usbh_cdc_ecm) * 1 | 0 | -|usbh_cdc_ncm.c | ~3300 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_cdc_ncm) * 1 | 0 | -|usbh_bluetooth.c | ~1000 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 | +|usbh_core.c | ~7700 | 512 + 8 * (1+x) *n | 28 | 0 | +|usbh_hub.c | ~5600 | 32 + 4* (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 | +|usbh_cdc_acm.c | ~1200 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 | +|usbh_msc.c | ~2500 | 32 | 4 + sizeof(struct usbh_msc) * x | 0 | +|usbh_hid.c | ~1000 | 128 | 4 + sizeof(struct usbh_hid) * x | 0 | +|usbh_video.c | ~3700 | 128 | 4 + sizeof(struct usbh_video) * x | 0 | +|usbh_audio.c | ~3100 | 128 | 4 + sizeof(struct usbh_audio) * x | 0 | +|usbh_rndis.c | ~3900 | 4096 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 | +|usbh_cdc_ecm.c | ~2500 | 2 * 1514 | sizeof(struct usbh_cdc_ecm) * 1 | 0 | +|usbh_bluetooth.c | ~2300 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 | Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affected by the following macros: @@ -160,14 +145,13 @@ Only standard and commercial USB IP are listed. | IP | device | host | Support status | |:----------------:|:----------:|:--------:|:--------------:| -| OHCI(intel) | none | OHCI | √ | +| OHCI(intel) | none | OHCI | × | | EHCI(intel) | none | EHCI | √ | | XHCI(intel) | none | XHCI | √ | | UHCI(intel) | none | UHCI | × | | DWC2(synopsys) | DWC2 | DWC2 | √ | | MUSB(mentor) | MUSB | MUSB | √ | | FOTG210(faraday)| FOTG210 | EHCI | √ | -| CHIPIDEA(synopsys)| CHIPIDEA | EHCI | √ | | CDNS2(cadence) | CDNS2 | CDNS2 | √ | | CDNS3(cadence) | CDNS3 | XHCI | × | | DWC3(synopsys) | DWC3 | XHCI | × | @@ -191,27 +175,17 @@ USB basic concepts and how the CherryUSB Device stack is implemented, see [Cherr |Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term | |ST | STM32F1x | fsdev |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term | |ST | STM32F4/STM32H7 | dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term | -|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term | +|HPMicro | HPM6750 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term | |Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term | -|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term | +|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|v0.10.2 | Long-term | |Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term | -|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term | -|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term | -|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/canmv_k230)|v1.2.0 | Long-term | -|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb | -|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb | -|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD | +|Espressif | esp32s2/esp32s3 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | the same with ST | +|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with Essemi | +|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with Essemi | +|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | the same with ST | |WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD | |Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= v0.10.2 | No more updated | -## Package Support - -CherryUSB package is available as follows: - -- [RT-Thread](https://packages.rt-thread.org/detail.html?package=CherryUSB) -- [YOC](https://www.xrvm.cn/document?temp=usb-host-protocol-stack-device-driver-adaptation-instructions&slug=yocbook) -- [ESP-Registry](https://components.espressif.com/components/cherry-embedded/cherryusb) - ## Commercial Support Refer to https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html. @@ -224,4 +198,4 @@ CherryUSB discord: https://discord.com/invite/wFfvrSAey8. Thanks to the following companies for their support (in no particular order). - + \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/README_zh.md b/rt-thread/components/drivers/usb/cherryusb/README_zh.md index 50d2b6f..0aee5a7 100644 --- a/rt-thread/components/drivers/usb/cherryusb/README_zh.md +++ b/rt-thread/components/drivers/usb/cherryusb/README_zh.md @@ -1,16 +1,6 @@ -

CherryUSB

-

- - - - -

+# CherryUSB -

- 中文 - | - English -

+[English](./README.md) CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 USB IP)的 USB 主从协议栈。 @@ -32,7 +22,7 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 为了方便用户使用 USB 接口,考虑到用户学习过 uart 和 dma,因此,设计的数据收发类接口具备以下优点: - 等价于使用 uart tx dma/uart rx dma -- 收发长度没有限制,用户不需要关心 USB 分包过程(分包过程在 porting 中处理) +- 收发长度没有限制,用户不需要关心 USB 分包过程(porting 驱动做分包过程) ### 易于发挥 USB 性能 @@ -42,7 +32,7 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 - Memory zero copy - IP 如果带 DMA 则使用 DMA 模式(DMA 带硬件分包功能) - 长度无限制,方便对接硬件 DMA 并且发挥 DMA 的优势 -- 分包过程在中断中执行 +- 分包功能在中断中处理 ## 目录结构 @@ -75,23 +65,21 @@ CherryUSB Device 协议栈当前实现以下功能: - 支持 Device Firmware Upgrade CLASS (DFU) - 支持 USB MIDI CLASS (MIDI) - 支持 Remote NDIS (RNDIS) -- 支持 WINUSB1.0、WINUSB2.0、WEBUSB、BOS +- 支持 WINUSB1.0、WINUSB2.0(带 BOS ) - 支持 Vendor 类 class -- 支持 UF2 -- 支持 Android Debug Bridge (Only support shell) - 支持相同 USB IP 的多从机 CherryUSB Device 协议栈资源占用说明(GCC 10.2 with -O2): | file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) | |:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:| -|usbd_core.c | ~4400 | 512(default) + 320 | 0 | 0 | -|usbd_cdc_acm.c | ~400 | 0 | 0 | 0 | -|usbd_msc.c | ~3800 | 128 + 512(default) | 16 | 0 | -|usbd_hid.c | ~360 | 0 | 0 | 0 | -|usbd_audio.c | ~1500 | 0 | 0 | 0 | -|usbd_video.c | ~2600 | 0 | 84 | 0 | -|usbd_rndis.c | ~2100 | 2 * 1580(default)+156+8 | 76 | 0 | +|usbd_core.c | 3516 | 256(default) + 320 | 0 | 0 | +|usbd_cdc.c | 392 | 0 | 0 | 0 | +|usbd_msc.c | 2839 | 128 + 512(default) | 16 | 0 | +|usbd_hid.c | 364 | 0 | 0 | 0 | +|usbd_audio.c | 1455 | 0 | 0 | 0 | +|usbd_video.c | 2494 | 0 | 84 | 0 | +|usbd_rndis.c | 2109 | 3340 | 76 | 0 | ## Host 协议栈简介 @@ -99,7 +87,6 @@ CherryUSB Host 协议栈对挂载在 roothub、外部 hub 上的设备规范了 CherryUSB Host 协议栈当前实现以下功能: -- 支持 low speed, full speed, high speed 和 super speed 设备 - 自动加载支持的Class 驱动 - 支持阻塞式传输和异步传输 - 支持复合设备 @@ -111,9 +98,8 @@ CherryUSB Host 协议栈当前实现以下功能: - Support USB Audio CLASS (UAC1.0) - 支持 Remote NDIS (RNDIS) - 支持 USB Bluetooth (支持 nimble and zephyr bluetooth 协议栈,支持 **CLASS: 0xE0** 或者厂家自定义类,类似于 cdc acm 功能) -- 支持 Vendor 类 class (serial, net, wifi) +- 支持 Vendor 类 class - 支持 USB modeswitch -- 支持 Android Open Accessory - 支持相同 USB IP 的多主机 同时,CherryUSB Host 协议栈还提供了 lsusb 的功能,借助 shell 插件可以查看所有挂载设备的信息,包括外部 hub 上的设备的信息。 @@ -122,17 +108,16 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2): | file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) | |:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:------------:| -|usbh_core.c | ~9000 | 512 + 8 * (1+x) *n | 28 | raw_config_desc | -|usbh_hub.c | ~6000 | 32 + 4 * (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 | -|usbh_cdc_acm.c | ~900 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 | -|usbh_msc.c | ~2700 | 64 | 4 + sizeof(struct usbh_msc) * x | 0 | -|usbh_hid.c | ~1400 | 256 | 4 + sizeof(struct usbh_hid) * x | 0 | -|usbh_video.c | ~3800 | 128 | 4 + sizeof(struct usbh_video) * x | 0 | -|usbh_audio.c | ~4100 | 128 | 4 + sizeof(struct usbh_audio) * x | 0 | -|usbh_rndis.c | ~4200 | 512 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 | -|usbh_cdc_ecm.c | ~2200 | 2 * 1514 + 16 | sizeof(struct usbh_cdc_ecm) * 1 | 0 | -|usbh_cdc_ncm.c | ~3300 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_cdc_ncm) * 1 | 0 | -|usbh_bluetooth.c | ~1000 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 | +|usbh_core.c | ~7700 | 512 + 8 * (1+x) *n | 28 | 0 | +|usbh_hub.c | ~5600 | 32 + 4* (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 | +|usbh_cdc_acm.c | ~1200 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 | +|usbh_msc.c | ~2500 | 32 | 4 + sizeof(struct usbh_msc) * x | 0 | +|usbh_hid.c | ~1000 | 128 | 4 + sizeof(struct usbh_hid) * x | 0 | +|usbh_video.c | ~3700 | 128 | 4 + sizeof(struct usbh_video) * x | 0 | +|usbh_audio.c | ~3100 | 128 | 4 + sizeof(struct usbh_audio) * x | 0 | +|usbh_rndis.c | ~3900 | 4096 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 | +|usbh_cdc_ecm.c | ~2500 | 2 * 1514 | sizeof(struct usbh_cdc_ecm) * 1 | 0 | +|usbh_bluetooth.c | ~2300 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 | 其中,`sizeof(struct usbh_hub)` 和 `sizeof(struct usbh_hubport)` 受以下宏影响: @@ -160,14 +145,13 @@ x 受以下宏影响: | IP | device | host | Support status | |:----------------:|:----------:|:--------:|:--------------:| -| OHCI(intel) | none | OHCI | √ | +| OHCI(intel) | none | OHCI | × | | EHCI(intel) | none | EHCI | √ | | XHCI(intel) | none | XHCI | √ | | UHCI(intel) | none | UHCI | × | | DWC2(synopsys) | DWC2 | DWC2 | √ | | MUSB(mentor) | MUSB | MUSB | √ | | FOTG210(faraday)| FOTG210 | EHCI | √ | -| CHIPIDEA(synopsys)| CHIPIDEA | EHCI | √ | | CDNS2(cadence) | CDNS2 | CDNS2 | √ | | CDNS3(cadence) | CDNS3 | XHCI | × | | DWC3(synopsys) | DWC3 | XHCI | × | @@ -192,30 +176,20 @@ CherryUSB 快速入门、USB 基本概念,API 手册,Class 基本概念和 |Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term | |ST | STM32F1x | fsdev |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term | |ST | STM32F4/STM32H7 | dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term | -|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term | +|HPMicro | HPM6750 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term | |Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term | -|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term | +|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|v0.10.2 | Long-term | |Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term | -|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term | -|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term | -|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/canmv_k230)|v1.2.0 | Long-term | -|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb | -|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb | -|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD | +|Espressif | esp32s2/esp32s3 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | the same with ST | +|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with Essemi | +|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with Essemi | +|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | the same with ST | |WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD | |Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= v0.10.2 | No more updated | -## 软件包支持 - -CherryUSB 软件包可以通过以下方式获取: - -- [RT-Thread](https://packages.rt-thread.org/detail.html?package=CherryUSB) -- [YOC](https://www.xrvm.cn/document?temp=usb-host-protocol-stack-device-driver-adaptation-instructions&slug=yocbook) -- [ESP-Registry](https://components.espressif.com/components/cherry-embedded/cherryusb) - ## 商业支持 -参考 https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html 。 +参考 https://cherryusb.readthedocs.io/zh-cn/latest/support/index.html。 ## 联系 @@ -226,4 +200,4 @@ CherryUSB 微信群:与我联系后邀请加入 感谢以下企业支持(顺序不分先后)。 - + diff --git a/rt-thread/components/drivers/usb/cherryusb/SConscript b/rt-thread/components/drivers/usb/cherryusb/SConscript index 58d0aa0..ee4dc91 100644 --- a/rt-thread/components/drivers/usb/cherryusb/SConscript +++ b/rt-thread/components/drivers/usb/cherryusb/SConscript @@ -15,8 +15,6 @@ path += [cwd + '/class/vendor/net'] path += [cwd + '/class/vendor/serial'] src = [] -LIBS = [] -LIBPATH = [] CPPDEFINES = [] # USB DEVICE @@ -45,9 +43,6 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']): if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_HC']): src += Glob('port/dwc2/usb_dc_dwc2.c') src += Glob('port/dwc2/usb_glue_hc.c') - if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_KENDRYTE']): - src += Glob('port/dwc2/usb_dc_dwc2.c') - src += Glob('port/dwc2/usb_glue_kendryte.c') if GetDepend(['RT_CHERRYUSB_DEVICE_DWC2_CUSTOM']): src += Glob('port/dwc2/usb_dc_dwc2.c') if GetDepend(['RT_CHERRYUSB_DEVICE_MUSB_ES']): @@ -61,14 +56,6 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']): src += Glob('port/musb/usb_glue_bk.c') if GetDepend(['RT_CHERRYUSB_DEVICE_MUSB_CUSTOM']): src += Glob('port/musb/usb_dc_musb.c') - if GetDepend(['RT_CHERRYUSB_DEVICE_KINETIS_MCX']): - src += Glob('port/kinetis/usb_dc_kinetis.c') - src += Glob('port/kinetis/usb_glue_mcx.c') - if GetDepend(['RT_CHERRYUSB_DEVICE_KINETIS_CUSTOM']): - src += Glob('port/kinetis/usb_dc_kinetis.c') - if GetDepend(['RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX']): - src += Glob('port/chipidea/usb_dc_chipidea.c') - src += Glob('port/chipidea/usb_glue_mcx.c') if GetDepend(['RT_CHERRYUSB_DEVICE_BL']): src += Glob('port/bouffalolab/usb_dc_bl.c') if GetDepend(['RT_CHERRYUSB_DEVICE_HPM']): @@ -81,18 +68,9 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']): src += Glob('port/ch32/usb_dc_usbhs.c') else: src += Glob('port/ch32/usb_dc_usbfs.c') - if GetDepend(['RT_CHERRYUSB_DEVICE_PUSB2']): - path += [cwd + '/port/xhci/rt-thread'] - src += Glob('port/pusb2/rt-thread/usb_dc_glue_phytium.c') - if GetDepend(['ARCH_ARMV8']): - LIBPATH = [cwd + '/port/pusb2'] - LIBS = ['libpusb2_dc_a64.a'] - if GetDepend(['ARCH_ARM_CORTEX_A']): - LIBPATH = [cwd + '/port/pusb2'] - LIBS = ['libpusb2_dc_a32_softfp_neon.a'] if GetDepend(['RT_CHERRYUSB_DEVICE_CDC_ACM']): - src += Glob('class/cdc/usbd_cdc_acm.c') + src += Glob('class/cdc/usbd_cdc.c') if GetDepend(['RT_CHERRYUSB_DEVICE_HID']): src += Glob('class/hid/usbd_hid.c') if GetDepend(['RT_CHERRYUSB_DEVICE_MSC']): @@ -162,14 +140,10 @@ if GetDepend(['RT_CHERRYUSB_HOST']): src += Glob('port/ehci/usb_hc_ehci.c') src += Glob('port/ehci/usb_glue_aic.c') src += Glob('port/ohci/usb_hc_ohci.c') - if GetDepend(['RT_CHERRYUSB_HOST_EHCI_MCX']): - path += [cwd + '/port/chipidea'] - src += Glob('port/ehci/usb_hc_ehci.c') - src += Glob('port/ehci/usb_glue_mcx.c') - if GetDepend(['RT_CHERRYUSB_HOST_EHCI_NUC980']): + if GetDepend(['RT_CHERRYUSB_HOST_EHCI_NUVOTON_NUC980']): src += Glob('port/ehci/usb_hc_ehci.c') src += Glob('port/ehci/usb_glue_nuc980.c') - if GetDepend(['RT_CHERRYUSB_HOST_EHCI_MA35D0']): + if GetDepend(['RT_CHERRYUSB_HOST_EHCI_NUVOTON_MA35D0']): src += Glob('port/ehci/usb_hc_ehci.c') src += Glob('port/ehci/usb_glue_ma35d0.c') if GetDepend(['RT_CHERRYUSB_HOST_EHCI_CUSTOM']): @@ -180,9 +154,6 @@ if GetDepend(['RT_CHERRYUSB_HOST']): if GetDepend(['RT_CHERRYUSB_HOST_DWC2_ESP']): src += Glob('port/dwc2/usb_hc_dwc2.c') src += Glob('port/dwc2/usb_glue_esp.c') - if GetDepend(['RT_CHERRYUSB_HOST_DWC2_KENDRYTE']): - src += Glob('port/dwc2/usb_hc_dwc2.c') - src += Glob('port/dwc2/usb_glue_kendryte.c') if GetDepend(['RT_CHERRYUSB_HOST_DWC2_CUSTOM']): src += Glob('port/dwc2/usb_hc_dwc2.c') if GetDepend(['RT_CHERRYUSB_HOST_MUSB_STANDARD']): @@ -198,31 +169,6 @@ if GetDepend(['RT_CHERRYUSB_HOST']): src += Glob('port/musb/usb_glue_bk.c') if GetDepend(['RT_CHERRYUSB_HOST_MUSB_CUSTOM']): src += Glob('port/musb/usb_hc_musb.c') - if GetDepend(['RT_CHERRYUSB_HOST_KINETIS_MCX']): - src += Glob('port/kinetis/usb_hc_kinetis.c') - src += Glob('port/kinetis/usb_glue_mcx.c') - if GetDepend(['RT_CHERRYUSB_HOST_KINETIS_CUSTOM']): - src += Glob('port/kinetis/usb_hc_kinetis.c') - if GetDepend(['RT_CHERRYUSB_HOST_PUSB2']): - path += [cwd + '/port/pusb2/rt-thread'] - src += Glob('port/pusb2/rt-thread/usb_hc_glue_phytium.c') - if GetDepend(['ARCH_ARMV8']): - LIBPATH = [cwd + '/port/pusb2'] - LIBS = ['libpusb2_hc_a64.a'] - if GetDepend(['ARCH_ARM_CORTEX_A']): - LIBPATH = [cwd + '/port/pusb2'] - LIBS = ['libpusb2_hc_a32_softfp_neon.a'] - - if GetDepend(['RT_CHERRYUSB_HOST_XHCI']): - path += [cwd + '/port/xhci/phytium/rt-thread'] - src += Glob('port/xhci/phytium/rt-thread/usb_glue_phytium_plat.c') - src += Glob('port/xhci/phytium/rt-thread/usb_glue_phytium.c') - if GetDepend(['ARCH_ARMV8']): - LIBPATH = [cwd + '/port/xhci/phytium'] - LIBS = ['libxhci_a64.a'] - if GetDepend(['ARCH_ARM_CORTEX_A']): - LIBPATH = [cwd + '/port/xhci/phytium'] - LIBS = ['libxhci_a32_softfp_neon.a'] if GetDepend(['RT_CHERRYUSB_HOST_CDC_ACM']): src += Glob('class/cdc/usbh_cdc_acm.c') @@ -271,7 +217,7 @@ if GetDepend(['RT_CHERRYUSB_HOST']): src += Glob('platform/rtthread/usb_msh.c') src += Glob('platform/rtthread/usb_check.c') -group = DefineGroup('CherryUSB', src, depend = ['RT_USING_CHERRYUSB'], LIBS = LIBS, LIBPATH=LIBPATH, CPPPATH = path, CPPDEFINES = CPPDEFINES) +group = DefineGroup('CherryUSB', src, depend = ['RT_USING_CHERRYUSB'], CPPPATH = path, CPPDEFINES = CPPDEFINES) Return('group') diff --git a/rt-thread/components/drivers/usb/cherryusb/VERSION b/rt-thread/components/drivers/usb/cherryusb/VERSION index 340d4ae..8a0bfa8 100644 --- a/rt-thread/components/drivers/usb/cherryusb/VERSION +++ b/rt-thread/components/drivers/usb/cherryusb/VERSION @@ -1,5 +1,5 @@ VERSION_MAJOR = 1 -VERSION_MINOR = 4 -PATCHLEVEL = 2 +VERSION_MINOR = 3 +PATCHLEVEL = 1 VERSION_TWEAK = 0 EXTRAVERSION = 0 diff --git a/rt-thread/components/drivers/usb/cherryusb/cherryusb.cmake b/rt-thread/components/drivers/usb/cherryusb/cherryusb.cmake index 2717170..d8451d2 100644 --- a/rt-thread/components/drivers/usb/cherryusb/cherryusb.cmake +++ b/rt-thread/components/drivers/usb/cherryusb/cherryusb.cmake @@ -36,17 +36,14 @@ ${CMAKE_CURRENT_LIST_DIR}/class/audio ${CMAKE_CURRENT_LIST_DIR}/class/video ${CMAKE_CURRENT_LIST_DIR}/class/wireless ${CMAKE_CURRENT_LIST_DIR}/class/midi -${CMAKE_CURRENT_LIST_DIR}/class/adb ${CMAKE_CURRENT_LIST_DIR}/class/vendor/net ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial -${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi -${CMAKE_CURRENT_LIST_DIR}/class/aoa ) if(CONFIG_CHERRYUSB_DEVICE) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/core/usbd_core.c) - if(CONFIG_CHERRYUSB_DEVICE_CDC_ACM) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbd_cdc_acm.c) + if(CONFIG_CHERRYUSB_DEVICE_CDC) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbd_cdc.c) endif() if(CONFIG_CHERRYUSB_DEVICE_HID) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/hid/usbd_hid.c) @@ -72,9 +69,6 @@ if(CONFIG_CHERRYUSB_DEVICE) if(CONFIG_CHERRYUSB_DEVICE_DFU) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/dfu/usbd_dfu.c) endif() - if(CONFIG_CHERRYUSB_DEVICE_ADB) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/adb/usbd_adb.c) - endif() if(DEFINED CONFIG_CHERRYUSB_DEVICE_DCD) if("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "fsdev") @@ -103,12 +97,6 @@ if(CONFIG_CHERRYUSB_DEVICE) elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "musb_bk") list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_bk.c) - elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "chipidea_mcx") - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/chipidea/usb_dc_chipidea.c) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/chipidea/usb_glue_mcx.c) - elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "kinetis_mcx") - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/kinetis/usb_dc_kinetis.c) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/kinetis/usb_glue_mcx.c) elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "hpm") list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/hpm/usb_dc_hpm.c) elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "bl") @@ -133,9 +121,6 @@ if(CONFIG_CHERRYUSB_HOST) if(CONFIG_CHERRYUSB_HOST_CDC_ECM) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbh_cdc_ecm.c) endif() - if(CONFIG_CHERRYUSB_HOST_CDC_RNDIS) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/wireless/usbh_rndis.c) - endif() if(CONFIG_CHERRYUSB_HOST_CDC_NCM) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/cdc/usbh_cdc_ncm.c) endif() @@ -157,10 +142,18 @@ if(CONFIG_CHERRYUSB_HOST) endif() if(CONFIG_CHERRYUSB_HOST_VIDEO) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/video/usbh_video.c) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb/chry_ringbuffer.c) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrypool/chry_pool.c) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrypool/usbh_uvc_queue.c) + list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb) + list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrypool) endif() if(CONFIG_CHERRYUSB_HOST_AUDIO) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/audio/usbh_audio.c) endif() + if(CONFIG_CHERRYUSB_HOST_CDC_RNDIS) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/wireless/usbh_rndis.c) + endif() if(CONFIG_CHERRYUSB_HOST_BLUETOOTH) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/wireless/usbh_bluetooth.c) @@ -216,12 +209,6 @@ if(CONFIG_CHERRYUSB_HOST) if(CONFIG_CHERRYUSB_HOST_PL2303) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial/usbh_pl2303.c) endif() - if(CONFIG_CHERRYUSB_HOST_BL616) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi/usbh_bl616.c) - endif() - if(CONFIG_CHERRYUSB_HOST_AOA) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/class/aoa/usbh_aoa.c) - endif() if(DEFINED CONFIG_CHERRYUSB_HOST_HCD) if("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_bouffalo") @@ -239,12 +226,6 @@ if(CONFIG_CHERRYUSB_HOST) #list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_glue_aic.c) list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/ehci) - elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_mcx") - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci.c) - #list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_glue_mcx.c) - list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/ehci) - list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/port/chipidea) elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "ehci_nuvoton") list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci.c) #list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/ehci/usb_hc_ehci_iso.c) @@ -267,9 +248,6 @@ if(CONFIG_CHERRYUSB_HOST) elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "musb_bk") list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_hc_musb.c) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_bk.c) - elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "kinetis_mcx") - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/kinetis/usb_hc_kinetis.c) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/kinetis/usb_glue_mcx.c) endif() endif() @@ -282,25 +260,5 @@ if(DEFINED CONFIG_CHERRYUSB_OSAL) list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_rtthread.c) elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "yoc") list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_yoc.c) - elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "idf") - list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/osal/idf) - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/idf/usb_osal_idf.c) - elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "threadx") - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/osal/usb_osal_threadx.c) - endif() -endif() - -if(CONFIG_CHERRYRB) -list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb/chry_ringbuffer.c) -list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherryrb) -endif() - -if(CONFIG_CHERRYMP) -list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/chry_mempool.c) -list(APPEND cherryusb_incs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp) - if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "freertos") - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/chry_mempool_osal_freertos.c) - elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "rtthread") - list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/third_party/cherrymp/chry_mempool_osal_rtthread.c) endif() endif() \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/cherryusb_config_template.h b/rt-thread/components/drivers/usb/cherryusb/cherryusb_config_template.h index e7d5230..493f8a4 100644 --- a/rt-thread/components/drivers/usb/cherryusb/cherryusb_config_template.h +++ b/rt-thread/components/drivers/usb/cherryusb/cherryusb_config_template.h @@ -6,10 +6,16 @@ #ifndef CHERRYUSB_CONFIG_H #define CHERRYUSB_CONFIG_H +#define CHERRYUSB_VERSION 0x010301 +#define CHERRYUSB_VERSION_STR "v1.3.1" + /* ================ USB common Configuration ================ */ #define CONFIG_USB_PRINTF(...) printf(__VA_ARGS__) +#define usb_malloc(size) malloc(size) +#define usb_free(ptr) free(ptr) + #ifndef CONFIG_USB_DBG_LEVEL #define CONFIG_USB_DBG_LEVEL USB_DBG_INFO #endif @@ -66,10 +72,6 @@ #define CONFIG_USBDEV_MSC_VERSION_STRING "0.01" #endif -/* move msc read & write from isr to while(1), you should call usbd_msc_polling in while(1) */ -// #define CONFIG_USBDEV_MSC_POLLING - -/* move msc read & write from isr to thread */ // #define CONFIG_USBDEV_MSC_THREAD #ifndef CONFIG_USBDEV_MSC_PRIO @@ -208,9 +210,6 @@ #define CONFIG_USBDEV_EP_NUM 8 #endif -/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode, the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS. */ -// #define CONFIG_USB_HS - /* ---------------- FSDEV Configuration ---------------- */ //#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference @@ -221,7 +220,7 @@ // #define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4) /* IN Endpoints Max packet Size / 4 */ // #define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4) -// #define CONFIG_USB_DWC2_TX1_FIFO_SIZE (1024 / 4) +// #define CONFIG_USB_DWC2_TX1_FIFO_SIZE (512 / 4) // #define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4) // #define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4) // #define CONFIG_USB_DWC2_TX4_FIFO_SIZE (0 / 4) @@ -230,8 +229,6 @@ // #define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4) // #define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4) -// #define CONFIG_USB_DWC2_DMA_ENABLE - /* ---------------- MUSB Configuration ---------------- */ // #define CONFIG_USB_MUSB_SUNXI @@ -271,7 +268,7 @@ * (largest USB packet used / 4) + 1 for status information + 1 transfer complete + * 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario */ -// #define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE)) +// #define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE) / 4) /* ---------------- MUSB Configuration ---------------- */ // #define CONFIG_USB_MUSB_SUNXI diff --git a/rt-thread/components/drivers/usb/cherryusb/class/adb/usbd_adb.c b/rt-thread/components/drivers/usb/cherryusb/class/adb/usbd_adb.c deleted file mode 100644 index 7629ea3..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/class/adb/usbd_adb.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbd_core.h" -#include "usbd_adb.h" - -#define ADB_OUT_EP_IDX 0 -#define ADB_IN_EP_IDX 1 - -#define ADB_STATE_READ_MSG 0 -#define ADB_STATE_READ_DATA 1 -#define ADB_STATE_WRITE_MSG 2 -#define ADB_STATE_WRITE_DATA 3 -#define ADB_STATE_AWRITE_MSG 4 -#define ADB_STATE_AWRITE_DATA 5 - -#define MAX_PAYLOAD_V1 (4 * 1024) -#define MAX_PAYLOAD_V2 (256 * 1024) -#define MAX_PAYLOAD MAX_PAYLOAD_V1 -#define A_VERSION 0x01000000 - -#define A_SYNC 0x434e5953 -#define A_CNXN 0x4e584e43 -#define A_OPEN 0x4e45504f -#define A_OKAY 0x59414b4f -#define A_CLSE 0x45534c43 -#define A_WRTE 0x45545257 -#define A_AUTH 0x48545541 - -struct adb_msg { - uint32_t command; /* command identifier constant (A_CNXN, ...) */ - uint32_t arg0; /* first argument */ - uint32_t arg1; /* second argument */ - uint32_t data_length; /* length of payload (0 is allowed) */ - uint32_t data_crc32; /* crc32 of data payload */ - uint32_t magic; /* command ^ 0xffffffff */ -}; - -struct adb_packet { - struct adb_msg msg; - uint8_t payload[MAX_PAYLOAD]; -}; - -struct usbd_adb { - uint8_t state; - uint8_t common_state; - uint8_t write_state; - bool writable; - uint32_t localid; - uint32_t shell_remoteid; - uint32_t file_remoteid; -} adb_client; - -static struct usbd_endpoint adb_ep_data[2]; - -USB_NOCACHE_RAM_SECTION struct adb_packet tx_packet; -USB_NOCACHE_RAM_SECTION struct adb_packet rx_packet; - -static inline uint32_t adb_packet_checksum(struct adb_packet *packet) -{ - uint32_t sum = 0; - uint32_t i; - - for (i = 0; i < packet->msg.data_length; ++i) { - sum += (uint32_t)(packet->payload[i]); - } - - return sum; -} - -static uint32_t usbd_adb_get_remoteid(uint32_t localid) -{ - if (localid == ADB_SHELL_LOALID) { - return adb_client.shell_remoteid; - } else { - return adb_client.file_remoteid; - } -} - -static void adb_send_msg(struct adb_packet *packet) -{ - adb_client.common_state = ADB_STATE_WRITE_MSG; - - packet->msg.data_crc32 = adb_packet_checksum(packet); - packet->msg.magic = packet->msg.command ^ 0xffffffff; - - usbd_ep_start_write(0, adb_ep_data[ADB_IN_EP_IDX].ep_addr, (uint8_t *)&packet->msg, sizeof(struct adb_msg)); -} - -static void adb_send_okay(struct adb_packet *packet, uint32_t localid) -{ - packet->msg.command = A_OKAY; - packet->msg.arg0 = localid; - packet->msg.arg1 = usbd_adb_get_remoteid(localid); - packet->msg.data_length = 0; - - adb_send_msg(&tx_packet); -} - -static void adb_send_close(struct adb_packet *packet, uint32_t localid, uint32_t remoteid) -{ - packet->msg.command = A_CLSE; - packet->msg.arg0 = localid; - packet->msg.arg1 = remoteid; - packet->msg.data_length = 0; - - adb_send_msg(&tx_packet); -} - -void usbd_adb_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) -{ - (void)ep; - - if (adb_client.common_state == ADB_STATE_READ_MSG) { - if (nbytes != sizeof(struct adb_msg)) { - USB_LOG_ERR("invalid adb msg size:%d\r\n", nbytes); - return; - } - - USB_LOG_DBG("command:%x arg0:%x arg1:%x len:%d\r\n", - rx_packet.msg.command, - rx_packet.msg.arg0, - rx_packet.msg.arg1, - rx_packet.msg.data_length); - - if (rx_packet.msg.data_length) { - /* setup next out ep read transfer */ - adb_client.common_state = ADB_STATE_READ_DATA; - usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, rx_packet.payload, rx_packet.msg.data_length); - } else { - if (rx_packet.msg.command == A_CLSE) { - adb_client.writable = false; - usbd_adb_notify_write_done(); - USB_LOG_INFO("Close remoteid:%x\r\n", rx_packet.msg.arg0); - } - adb_client.common_state = ADB_STATE_READ_MSG; - /* setup first out ep read transfer */ - usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg)); - } - } else if (adb_client.common_state == ADB_STATE_READ_DATA) { - switch (rx_packet.msg.command) { - case A_SYNC: - - break; - case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */ - char *support_feature = "device::" - "ro.product.name=cherryadb;" - "ro.product.model=cherrysh;" - "ro.product.device=cherryadb;" - "features=cmd,shell_v1"; - - tx_packet.msg.command = A_CNXN; - tx_packet.msg.arg0 = A_VERSION; - tx_packet.msg.arg1 = MAX_PAYLOAD; - tx_packet.msg.data_length = strlen(support_feature); - memcpy(tx_packet.payload, support_feature, strlen(support_feature)); - - adb_send_msg(&tx_packet); - - adb_client.writable = false; - break; - case A_OPEN: /* OPEN(local-id, 0, "destination") */ - rx_packet.payload[rx_packet.msg.data_length] = '\0'; - - if (strncmp((const char *)rx_packet.payload, "shell:", 6) == 0) { - adb_client.localid = ADB_SHELL_LOALID; - adb_client.shell_remoteid = rx_packet.msg.arg0; - adb_send_okay(&tx_packet, ADB_SHELL_LOALID); - - USB_LOG_INFO("Open shell service, remoteid:%x\r\n", rx_packet.msg.arg0); - } else if (strncmp((const char *)rx_packet.payload, "sync:", 5) == 0) { - adb_client.localid = ADB_FILE_LOALID; - adb_client.file_remoteid = rx_packet.msg.arg0; - adb_send_okay(&tx_packet, ADB_FILE_LOALID); - USB_LOG_INFO("Open file service, remoteid:%x\r\n", rx_packet.msg.arg0); - } - break; - case A_OKAY: - - break; - case A_CLSE: - - break; - case A_WRTE: /* WRITE(local-id, remote-id, "data") */ - if ((rx_packet.msg.arg0 == adb_client.shell_remoteid) && (rx_packet.msg.arg1 == ADB_SHELL_LOALID)) { - adb_send_okay(&tx_packet, rx_packet.msg.arg1); - } else if ((rx_packet.msg.arg0 == adb_client.file_remoteid) && (rx_packet.msg.arg1 == ADB_FILE_LOALID)) { - adb_send_okay(&tx_packet, rx_packet.msg.arg1); - } else { - adb_send_close(&tx_packet, 0, rx_packet.msg.arg0); - } - break; - case A_AUTH: - - break; - - default: - break; - } - } -} - -void usbd_adb_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) -{ - (void)ep; - (void)nbytes; - - if (adb_client.common_state == ADB_STATE_WRITE_MSG) { - if (tx_packet.msg.data_length) { - adb_client.common_state = ADB_STATE_WRITE_DATA; - usbd_ep_start_write(busid, adb_ep_data[ADB_IN_EP_IDX].ep_addr, tx_packet.payload, tx_packet.msg.data_length); - } else { - if (rx_packet.msg.command == A_WRTE) { - adb_client.writable = true; - if (adb_client.localid == ADB_SHELL_LOALID) { - usbd_adb_notify_shell_read(rx_packet.payload, rx_packet.msg.data_length); - } else { - } - } - adb_client.common_state = ADB_STATE_READ_MSG; - /* setup first out ep read transfer */ - usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg)); - } - } else if (adb_client.common_state == ADB_STATE_WRITE_DATA) { - adb_client.common_state = ADB_STATE_READ_MSG; - /* setup first out ep read transfer */ - usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg)); - } else if (adb_client.write_state == ADB_STATE_AWRITE_MSG) { - if (tx_packet.msg.data_length) { - adb_client.write_state = ADB_STATE_AWRITE_DATA; - usbd_ep_start_write(busid, adb_ep_data[ADB_IN_EP_IDX].ep_addr, tx_packet.payload, tx_packet.msg.data_length); - } else { - } - } else if (adb_client.write_state == ADB_STATE_AWRITE_DATA) { - usbd_adb_notify_write_done(); - } -} - -void adb_notify_handler(uint8_t busid, uint8_t event, void *arg) -{ - (void)arg; - - switch (event) { - case USBD_EVENT_INIT: - break; - case USBD_EVENT_DEINIT: - break; - case USBD_EVENT_RESET: - break; - case USBD_EVENT_CONFIGURED: - adb_client.common_state = ADB_STATE_READ_MSG; - /* setup first out ep read transfer */ - usbd_ep_start_read(busid, adb_ep_data[ADB_OUT_EP_IDX].ep_addr, (uint8_t *)&rx_packet.msg, sizeof(struct adb_msg)); - break; - - default: - break; - } -} - -struct usbd_interface *usbd_adb_init_intf(uint8_t busid, struct usbd_interface *intf, uint8_t in_ep, uint8_t out_ep) -{ - (void)busid; - - intf->class_interface_handler = NULL; - intf->class_endpoint_handler = NULL; - intf->vendor_handler = NULL; - intf->notify_handler = adb_notify_handler; - - adb_ep_data[ADB_OUT_EP_IDX].ep_addr = out_ep; - adb_ep_data[ADB_OUT_EP_IDX].ep_cb = usbd_adb_bulk_out; - adb_ep_data[ADB_IN_EP_IDX].ep_addr = in_ep; - adb_ep_data[ADB_IN_EP_IDX].ep_cb = usbd_adb_bulk_in; - - usbd_add_endpoint(busid, &adb_ep_data[ADB_OUT_EP_IDX]); - usbd_add_endpoint(busid, &adb_ep_data[ADB_IN_EP_IDX]); - - return intf; -} - -bool usbd_adb_can_write(void) -{ - return adb_client.writable; -} - -int usbd_abd_write(uint32_t localid, const uint8_t *data, uint32_t len) -{ - struct adb_packet *packet; - - packet = &tx_packet; - packet->msg.command = A_WRTE; - packet->msg.arg0 = localid; - packet->msg.arg1 = usbd_adb_get_remoteid(localid); - packet->msg.data_length = len; - memcpy(packet->payload, data, len); - - packet->msg.data_crc32 = adb_packet_checksum(packet); - packet->msg.magic = packet->msg.command ^ 0xffffffff; - - adb_client.write_state = ADB_STATE_AWRITE_MSG; - usbd_ep_start_write(0, adb_ep_data[ADB_IN_EP_IDX].ep_addr, (uint8_t *)&packet->msg, sizeof(struct adb_msg)); - return 0; -} - -void usbd_adb_close(uint32_t localid) -{ - adb_send_close(&tx_packet, 0, usbd_adb_get_remoteid(localid)); -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/adb/usbd_adb.h b/rt-thread/components/drivers/usb/cherryusb/class/adb/usbd_adb.h deleted file mode 100644 index 4dbc730..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/class/adb/usbd_adb.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USBD_ADB_H -#define USBD_ADB_H - -#include - -#define ADB_SHELL_LOALID 0x01 -#define ADB_FILE_LOALID 0x02 - -// clang-format off -#define ADB_DESCRIPTOR_INIT(bFirstInterface, in_ep, out_ep, wMaxPacketSize) \ - USB_INTERFACE_DESCRIPTOR_INIT(bFirstInterface, 0x00, 0x02, 0xff, 0x42, 0x01, 0x02), \ - USB_ENDPOINT_DESCRIPTOR_INIT(in_ep, 0x02, wMaxPacketSize, 0x00), \ - USB_ENDPOINT_DESCRIPTOR_INIT(out_ep, 0x02, wMaxPacketSize, 0x00) -// clang-format on - -#ifdef __cplusplus -extern "C" { -#endif - -struct usbd_interface *usbd_adb_init_intf(uint8_t busid, struct usbd_interface *intf, uint8_t in_ep, uint8_t out_ep); - -void usbd_adb_notify_shell_read(uint8_t *data, uint32_t len); -void usbd_adb_notify_file_read(uint8_t *data, uint32_t len); -void usbd_adb_notify_write_done(void); -bool usbd_adb_can_write(void); -int usbd_abd_write(uint32_t localid, const uint8_t *data, uint32_t len); -void usbd_adb_close(uint32_t localid); - -#ifdef __cplusplus -} -#endif - -#endif /* USBD_ADB_H */ \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/aoa/usb_aoa.h b/rt-thread/components/drivers/usb/cherryusb/class/aoa/usb_aoa.h deleted file mode 100644 index 6b6c715..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/class/aoa/usb_aoa.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USB_AOA_H -#define USB_AOA_H - -//AOA 1.0 -#define AOA_ACCESSORY_VENDOR_ID 0x18D1 -#define AOA_ACCESSORY_PRODUCT_ID 0x2D00 -#define AOA_ACCESSORY_ADB_PRODUCT_ID 0x2D01 - -//AOA 2.0 -#define AOA_AUDIO_PRODUCT_ID 0x2D02 -#define AOA_AUDIO_ADB_PRODUCT_ID 0x2D03 -#define AOA_ACCESSORY_AUDIO_PRODUCT_ID 0x2D04 -#define AOA_ACCESSORY_AUDIO_ADB_PRODUCT_ID 0x2D05 - -//AOA 1.0 -#define AOA_ACCESSORY_GET_PROTOCOL 51 -#define AOA_ACCESSORY_SEND_STRING 52 -#define AOA_ACCESSORY_START 53 - -//AOA 2.0 -#define AOA_ACCESSORY_REGISTER_HID 54 -#define AOA_ACCESSORY_UNREGISTER_HID 55 -#define AOA_ACCESSORY_SET_HID_REPORT_DESC 56 -#define AOA_ACCESSORY_SEND_HID_EVENT 57 -#define AOA_ACCESSORY_SET_AUDIO_MODE 58 - -#define AOA_ACCESSORY_STRING_MANUFACTURER 0 -#define AOA_ACCESSORY_STRING_MODEL 1 -#define AOA_ACCESSORY_STRING_DESCRIPTION 2 -#define AOA_ACCESSORY_STRING_VERSION 3 -#define AOA_ACCESSORY_STRING_URI 4 -#define AOA_ACCESSORY_STRING_SERIAL 5 - -struct aoa_string_info { - char acc_manufacturer[64]; - char acc_model[64]; - char acc_description[64]; - char acc_version[64]; - char acc_uri[64]; - char acc_serial[64]; -}; - -#endif /* USB_AOA_H */ \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.c b/rt-thread/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.c deleted file mode 100644 index 20cef52..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbh_core.h" -#include "usbh_aoa.h" - -#undef USB_DBG_TAG -#define USB_DBG_TAG "usbh_aoa" -#include "usb_log.h" - -#define DEV_FORMAT "/dev/aoa" - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_aoa_buffer[128]; - -static struct usbh_aoa g_aoa_class; - -int usbh_aoa_switch(struct usbh_hubport *hport, struct aoa_string_info *info) -{ - struct usb_setup_packet *setup; - int ret; - - setup = hport->setup; - - if (setup == NULL) { - return -USB_ERR_INVAL; - } - - USB_LOG_INFO("Try switch into aoa mode\r\n"); - - setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = AOA_ACCESSORY_GET_PROTOCOL; - setup->wValue = 0; - setup->wIndex = 0; - setup->wLength = 2; - - ret = usbh_control_transfer(hport, setup, g_aoa_buffer); - if (ret < 0) { - return ret; - } - - USB_LOG_INFO("AOA version: v%d.%d\r\n", g_aoa_buffer[0], g_aoa_buffer[1]); - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = AOA_ACCESSORY_SEND_STRING; - setup->wValue = 0; - setup->wIndex = AOA_ACCESSORY_STRING_MANUFACTURER; - setup->wLength = strlen(info->acc_manufacturer) + 1; - - memcpy(g_aoa_buffer, info->acc_manufacturer, strlen(info->acc_manufacturer)); - ret = usbh_control_transfer(hport, setup, g_aoa_buffer); - if (ret < 0) { - return ret; - } - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = AOA_ACCESSORY_SEND_STRING; - setup->wValue = 0; - setup->wIndex = AOA_ACCESSORY_STRING_MODEL; - setup->wLength = strlen(info->acc_model) + 1; - - memcpy(g_aoa_buffer, info->acc_model, strlen(info->acc_model)); - ret = usbh_control_transfer(hport, setup, g_aoa_buffer); - if (ret < 0) { - return ret; - } - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = AOA_ACCESSORY_SEND_STRING; - setup->wValue = 0; - setup->wIndex = AOA_ACCESSORY_STRING_DESCRIPTION; - setup->wLength = strlen(info->acc_description) + 1; - - memcpy(g_aoa_buffer, info->acc_description, strlen(info->acc_description)); - ret = usbh_control_transfer(hport, setup, g_aoa_buffer); - if (ret < 0) { - return ret; - } - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = AOA_ACCESSORY_SEND_STRING; - setup->wValue = 0; - setup->wIndex = AOA_ACCESSORY_STRING_VERSION; - setup->wLength = strlen(info->acc_version) + 1; - - memcpy(g_aoa_buffer, info->acc_version, strlen(info->acc_version)); - ret = usbh_control_transfer(hport, setup, g_aoa_buffer); - if (ret < 0) { - return ret; - } - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = AOA_ACCESSORY_SEND_STRING; - setup->wValue = 0; - setup->wIndex = AOA_ACCESSORY_STRING_URI; - setup->wLength = strlen(info->acc_uri) + 1; - - memcpy(g_aoa_buffer, info->acc_uri, strlen(info->acc_uri)); - ret = usbh_control_transfer(hport, setup, g_aoa_buffer); - if (ret < 0) { - return ret; - } - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = AOA_ACCESSORY_SEND_STRING; - setup->wValue = 0; - setup->wIndex = AOA_ACCESSORY_STRING_SERIAL; - setup->wLength = strlen(info->acc_serial) + 1; - - memcpy(g_aoa_buffer, info->acc_serial, strlen(info->acc_serial)); - ret = usbh_control_transfer(hport, setup, g_aoa_buffer); - if (ret < 0) { - return ret; - } - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = AOA_ACCESSORY_START; - setup->wValue = 0; - setup->wIndex = 0; - setup->wLength = 0; - - ret = usbh_control_transfer(hport, setup, NULL); - if (ret < 0) { - return ret; - } - - USB_LOG_INFO("Switch into aoa mode success, wait usb device restart...\r\n"); - return 0; -} - -int usbh_aoa_register_hid(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *report, uint32_t report_len) -{ - struct usb_setup_packet *setup; - int ret; - uint8_t len; - uint32_t offset; - - if (!aoa_class || !aoa_class->hport) { - return -USB_ERR_INVAL; - } - setup = aoa_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = AOA_ACCESSORY_REGISTER_HID; - setup->wValue = id; - setup->wIndex = report_len; - setup->wLength = 0; - - ret = usbh_control_transfer(aoa_class->hport, setup, NULL); - if (ret < 0) { - return ret; - } - - offset = 0; - while (report_len > 0) { - len = report_len > 64 ? 64 : report_len; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = AOA_ACCESSORY_SET_HID_REPORT_DESC; - setup->wValue = id; - setup->wIndex = offset; - setup->wLength = len; - - memcpy(g_aoa_buffer, report + offset, len); - ret = usbh_control_transfer(aoa_class->hport, setup, g_aoa_buffer); - if (ret < 0) { - return ret; - } - offset += len; - report_len -= len; - } - return ret; -} - -int usbh_aoa_send_hid_event(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *event, uint32_t event_len) -{ - struct usb_setup_packet *setup; - int ret; - uint8_t len; - uint32_t offset; - - if (!aoa_class || !aoa_class->hport) { - return -USB_ERR_INVAL; - } - setup = aoa_class->hport->setup; - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = AOA_ACCESSORY_SEND_HID_EVENT; - setup->wValue = id; - setup->wIndex = 0; - setup->wLength = event_len; - - memcpy(g_aoa_buffer, event, event_len); - return usbh_control_transfer(aoa_class->hport, setup, event); -} - -static int usbh_aoa_connect(struct usbh_hubport *hport, uint8_t intf) -{ - struct usb_endpoint_descriptor *ep_desc; - int ret = 0; - - struct usbh_aoa *aoa_class = &g_aoa_class; - - memset(aoa_class, 0, sizeof(struct usbh_aoa)); - - aoa_class->hport = hport; - aoa_class->intf = intf; - - hport->config.intf[intf].priv = aoa_class; - - for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { - ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; - - if (ep_desc->bEndpointAddress & 0x80) { - USBH_EP_INIT(aoa_class->bulkin, ep_desc); - } else { - USBH_EP_INIT(aoa_class->bulkout, ep_desc); - } - } - - strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN); - - USB_LOG_INFO("Register AOA Class:%s\r\n", hport->config.intf[intf].devname); - - usbh_aoa_run(aoa_class); - return 0; -} - -static int usbh_aoa_disconnect(struct usbh_hubport *hport, uint8_t intf) -{ - int ret = 0; - - struct usbh_aoa *aoa_class = (struct usbh_aoa *)hport->config.intf[intf].priv; - - if (aoa_class) { - if (aoa_class->bulkin) { - usbh_kill_urb(&aoa_class->bulkin_urb); - } - - if (aoa_class->bulkout) { - usbh_kill_urb(&aoa_class->bulkout_urb); - } - - if (hport->config.intf[intf].devname[0] != '\0') { - USB_LOG_INFO("Unregister AOA Class:%s\r\n", hport->config.intf[intf].devname); - usbh_aoa_stop(aoa_class); - } - - memset(aoa_class, 0, sizeof(struct usbh_aoa)); - } - - return ret; -} - -__WEAK void usbh_aoa_run(struct usbh_aoa *aoa_class) -{ - (void)aoa_class; -} - -__WEAK void usbh_aoa_stop(struct usbh_aoa *aoa_class) -{ - (void)aoa_class; -} - -static const uint16_t aoa_id_table[][2] = { - { AOA_ACCESSORY_VENDOR_ID, AOA_ACCESSORY_PRODUCT_ID }, - { AOA_ACCESSORY_VENDOR_ID, AOA_ACCESSORY_ADB_PRODUCT_ID }, - { AOA_ACCESSORY_VENDOR_ID, AOA_AUDIO_PRODUCT_ID }, - { AOA_ACCESSORY_VENDOR_ID, AOA_AUDIO_ADB_PRODUCT_ID }, - { AOA_ACCESSORY_VENDOR_ID, AOA_ACCESSORY_AUDIO_PRODUCT_ID }, - { AOA_ACCESSORY_VENDOR_ID, AOA_ACCESSORY_AUDIO_ADB_PRODUCT_ID }, - { 0, 0 }, -}; - -const struct usbh_class_driver aoa_class_driver = { - .driver_name = "aoa", - .connect = usbh_aoa_connect, - .disconnect = usbh_aoa_disconnect -}; - -CLASS_INFO_DEFINE const struct usbh_class_info aoa_intf_class_info = { - .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0xff, - .bInterfaceProtocol = 0x00, - .id_table = aoa_id_table, - .class_driver = &aoa_class_driver -}; \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.h b/rt-thread/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.h deleted file mode 100644 index 3b184e8..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/class/aoa/usbh_aoa.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USBH_AOA_H -#define USBH_AOA_H - -#include "usb_aoa.h" - -struct usbh_aoa { - struct usbh_hubport *hport; - struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ - struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ - - struct usbh_urb bulkout_urb; - struct usbh_urb bulkin_urb; - - uint8_t intf; - uint8_t minor; - - void *user_data; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -int usbh_aoa_switch(struct usbh_hubport *hport, struct aoa_string_info *info); -int usbh_aoa_register_hid(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *report, uint32_t report_len); -int usbh_aoa_send_hid_event(struct usbh_aoa *aoa_class, uint16_t id, uint8_t *event, uint32_t event_len); - -void usbh_aoa_run(struct usbh_aoa *aoa_class); -void usbh_aoa_stop(struct usbh_aoa *aoa_class); - -#ifdef __cplusplus -} -#endif - -#endif /* USBH_AOA_H */ \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/audio/usb_audio.h b/rt-thread/components/drivers/usb/cherryusb/class/audio/usb_audio.h index ff7a9fe..2b3cdaf 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/audio/usb_audio.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/audio/usb_audio.h @@ -132,11 +132,11 @@ #define AUDIO_FORMAT_ALAW 0x0004 #define AUDIO_FORMAT_MULAW 0x0005 -#define AUDIO_V2_FORMAT_PCM 0x00000001 -#define AUDIO_V2_FORMAT_PCM8 0x00000002 -#define AUDIO_V2_FORMAT_IEEE_FLOAT 0x00000004 -#define AUDIO_V2_FORMAT_ALAW 0x00000008 -#define AUDIO_V2_FORMAT_MULAW 0x00000010 +#define AUDIO_V2_FORMAT_PCM 0x00000001 +#define AUDIO_V2_FORMAT_PCM8 0x00000002 +#define AUDIO_V2_FORMAT_IEEE_FLOAT 0x00000004 +#define AUDIO_V2_FORMAT_ALAW 0x00000008 +#define AUDIO_V2_FORMAT_MULAW 0x00000010 /* bmChannelConfig: a bitmap field that indicates which spatial locations * are occupied by the channels present in the cluster. The bit allocations @@ -648,18 +648,6 @@ struct audio_cs_if_ac_feature_unit_descriptor { #define AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(ch, n) (7 + (ch + 1) * n) -struct audio_cs_if_ac_selector_unit_descriptor { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDescriptorSubtype; - uint8_t bUnitID; - uint8_t bNrInPins; - uint8_t baSourceID[1]; - uint8_t iSelector; -} __PACKED; - -#define AUDIO_SIZEOF_AC_SELECTOR_UNIT_DESC(n) (6 + n) - struct audio_cs_if_as_general_descriptor { uint8_t bLength; uint8_t bDescriptorType; @@ -824,60 +812,6 @@ struct audio_cs_ep_ep_general_descriptor { #define AUDIO_AS_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07) -#define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval, ...) \ - 0x09, /* bLength */ \ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ - bInterfaceNumber, /* bInterfaceNumber */ \ - bAlternateSetting, /* bAlternateSetting */ \ - 0x01, /* bNumEndpoints */ \ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \ - 0x00, /* iInterface */ \ - 0x07, /* bLength */ \ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ - AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ \ - bTerminalLink, /* bTerminalLink : Unit ID of the Output Terminal*/ \ - 0x01, /* bDelay */ \ - WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag : AUDIO_FORMAT_PCM */ \ - 0x08 + PP_NARG(__VA_ARGS__), /* bLength */ \ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ - AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ \ - AUDIO_FORMAT_TYPE_I, /* bFormatType */ \ - bNrChannels, /* bNrChannels */ \ - bSubFrameSize, /* bSubFrameSize : Bytes per audio subframe */ \ - bBitResolution, /* bBitResolution : bits per sample */ \ - (PP_NARG(__VA_ARGS__)/3), /* bSamFreqType : only one frequency supported */ \ - __VA_ARGS__, /* tSamFreq : Audio sampling frequency coded on 3 bytes */ \ - 0x09, /* bLength */ \ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ - bEndpointAddress, /* bEndpointAddress : IN endpoint 1 */ \ - bmAttributes, /* bmAttributes */ \ - WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \ - bInterval, /* bInterval : one packet per frame */ \ - 0x00, /* bRefresh */ \ - 0x00, /* bSynchAddress */ \ - 0x07, /* bLength */ \ - AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \ - AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ \ - AUDIO_EP_CONTROL_SAMPLING_FEQ, /* bmAttributes AUDIO_SAMPLING_FREQ_CONTROL */ \ - 0x00, /* bLockDelayUnits */ \ - 0x00, /* wLockDelay */ \ - 0x00 - -#define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07) - -#define AUDIO_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \ - 0x09, /* bLength */ \ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ - bInterfaceNumber, /* bInterfaceNumber */ \ - 0x00, /* bAlternateSetting */ \ - 0x01, /* bNumEndpoints */ \ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \ - 0x00 /* iInterface */ - #define AUDIO_MS_STANDARD_DESCRIPTOR_INIT(bInterfaceNumber, bNumEndpoints) \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ @@ -1162,58 +1096,6 @@ struct audio_v2_control_range3_param_block { 0x00, /* wLockDelay */ \ 0x00 -#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bTerminalLink, bNrChannels, bmChannelConfig, bSubslotSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval) \ - 0x09, /* bLength */ \ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ - bInterfaceNumber, /* bInterfaceNumber */ \ - bAlternateSetting, /* bAlternateSetting */ \ - 0x01, /* bNumEndpoints */ \ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \ - AUDIO_PROTOCOLv20, /* bInterfaceProtocol */ \ - 0x00, /* iInterface */ \ - 0x10, /* bLength */ \ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ - AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ \ - bTerminalLink, /* bTerminalLink : Unit ID of the Output or Input Terminal*/ \ - 0x00, /* bmControls */ \ - AUDIO_FORMAT_TYPE_I, /* bFormatType : AUDIO_FORMAT_TYPE_I */ \ - DBVAL(AUDIO_V2_FORMAT_PCM), /* bmFormats PCM */ \ - bNrChannels, /* bNrChannels */ \ - DBVAL(bmChannelConfig), /* bmChannelConfig */ \ - 0x00, /* iChannelNames */ \ - 0x06, /* bLength */ \ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \ - AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ \ - AUDIO_FORMAT_TYPE_I, /* bFormatType */ \ - bSubslotSize, /* bSubslotSize */ \ - bBitResolution, /* bBitResolution */ \ - 0x07, /* bLength */ \ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ - bEndpointAddress, /* bEndpointAddress 3 out endpoint for Audio */ \ - bmAttributes, /* bmAttributes */ \ - WBVAL(wMaxPacketSize), /* XXXX wMaxPacketSize in Bytes (SampleRate * SlotByteSize * NumChannels) */ \ - bInterval, /* bInterval */ \ - 0x08, /* bLength */ \ - AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \ - AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ \ - 0x00, /* bmAttributes */ \ - 0x00, /* bmControls */ \ - 0x00, /* bLockDelayUnits */ \ - 0x00, /* wLockDelay */ \ - 0x00 - -#define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_INIT(bInterfaceNumber) \ - 0x09, /* bLength */ \ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ - bInterfaceNumber, /* bInterfaceNumber */ \ - 0x00, /* bAlternateSetting */ \ - 0x01, /* bNumEndpoints */ \ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \ - AUDIO_PROTOCOLv20, /* bInterfaceProtocol */ \ - 0x00 /* iInterface */ - #define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bmChannelConfig, bSubslotSize, bBitResolution, bEndpointAddress, wMaxPacketSize, bInterval, bFeedbackEndpointAddress) \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ @@ -1268,13 +1150,12 @@ struct audio_v2_control_range3_param_block { bFeedbackEndpointAddress, /* bFeedbackEndpointAddress Revise Dir to bEndpointAddress */ \ 0x11, /* bmAttributes: TransferType=Isochronous SyncType=None EndpointType=Feedback */ \ WBVAL(4), /* XXXX wMaxPacketSize in Bytes */ \ - bInterval /* bInterval */ + bInterval /* bInterval */ \ // clang-format on -#define AUDIO_V2_AS_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08) -#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_INIT_LEN (0x09 + 0x10 + 0x06 + 0x07 + 0x08) -#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07) +#define AUDIO_V2_AS_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08) +#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07) #define AUDIO_SAMPLE_FREQ_NUM(num) (uint8_t)(num), (uint8_t)((num >> 8)) #define AUDIO_SAMPLE_FREQ_3B(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16)) diff --git a/rt-thread/components/drivers/usb/cherryusb/class/audio/usbd_audio.c b/rt-thread/components/drivers/usb/cherryusb/class/audio/usbd_audio.c index 458f1c1..c78c8ed 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/audio/usbd_audio.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/audio/usbd_audio.c @@ -62,7 +62,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup setup->bRequest); uint8_t entity_id; - uint8_t ep = 0; + uint8_t ep; uint8_t subtype = 0x01; uint8_t control_selector; uint8_t ch; @@ -136,26 +136,27 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup memcpy(&volume, *data, *len); if (volume < 0x8000) { volume_db = volume / 256; - } else { - volume_db = (volume - 0x10000) / 256; + } else if (volume > 0x8000) { + volume_db = (0xffff - volume + 1) / -256; } - USB_LOG_DBG("Set ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db); + volume_db += 128; /* 0 ~ 255 */ + USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%04x\r\n", ep, ch, volume); usbd_audio_set_volume(busid, ep, ch, volume_db); break; case AUDIO_REQUEST_GET_CUR: volume_db = usbd_audio_get_volume(busid, ep, ch); + volume_db -= 128; if (volume_db >= 0) { volume = volume_db * 256; } else { - volume = volume_db * 256 + 0x10000; + volume = volume_db * 256 + 0xffff + 1; } - USB_LOG_DBG("Get ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db); memcpy(*data, &volume, 2); *len = 2; break; case AUDIO_REQUEST_GET_MIN: - (*data)[0] = 0x00; /* -100 dB */ - (*data)[1] = 0x9c; + (*data)[0] = 0x00; /* -2560/256 dB */ + (*data)[1] = 0xdb; *len = 2; break; case AUDIO_REQUEST_GET_MAX: @@ -164,7 +165,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup *len = 2; break; case AUDIO_REQUEST_GET_RES: - (*data)[0] = 0x00; /* 1 dB */ + (*data)[0] = 0x00; /* -256/256 dB */ (*data)[1] = 0x01; *len = 2; break; @@ -177,31 +178,22 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup case AUDIO_REQUEST_CUR: if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { volume_db = usbd_audio_get_volume(busid, ep, ch); - if (volume_db >= 0) { - volume = volume_db * 256; - } else { - volume = volume_db * 256 + 0x10000; - } - USB_LOG_DBG("Get ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db); + volume = volume_db; memcpy(*data, &volume, 2); *len = 2; } else { memcpy(&volume, *data, *len); - if (volume < 0x8000) { - volume_db = volume / 256; - } else { - volume_db = (volume - 0x10000) / 256; - } - USB_LOG_DBG("Set ep:0x%02x ch:%d vol_hex:0x%04x, vol_db:%d dB\r\n", ep, ch, volume, volume_db); + volume_db = volume; + USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%02x\r\n", ep, ch, volume); usbd_audio_set_volume(busid, ep, ch, volume_db); } break; case AUDIO_REQUEST_RANGE: if (setup->bmRequestType & USB_REQUEST_DIR_MASK) { *((uint16_t *)(*data + 0)) = 1; - *((uint16_t *)(*data + 2)) = 0x9c00; /* MIN -100 dB */ - *((uint16_t *)(*data + 4)) = 0x0000; /* MAX 0 dB */ - *((uint16_t *)(*data + 6)) = 0x100; /* RES 1 dB */ + *((uint16_t *)(*data + 2)) = 0; + *((uint16_t *)(*data + 4)) = 100; + *((uint16_t *)(*data + 6)) = 1; *len = 8; } else { } @@ -295,7 +287,7 @@ static void audio_notify_handler(uint8_t busid, uint8_t event, void *arg) } } -struct usbd_interface *usbd_audio_init_intf(uint8_t busid, +struct usbd_interface *usbd_audio_init_intf(uint8_t busid, struct usbd_interface *intf, uint16_t uac_version, struct audio_entity_info *table, @@ -320,58 +312,33 @@ struct usbd_interface *usbd_audio_init_intf(uint8_t busid, return intf; } -__WEAK void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume_db) +__WEAK void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume) { - (void)busid; - (void)ep; - (void)ch; - (void)volume_db; } __WEAK int usbd_audio_get_volume(uint8_t busid, uint8_t ep, uint8_t ch) { - (void)busid; - (void)ep; - (void)ch; - return 0; } __WEAK void usbd_audio_set_mute(uint8_t busid, uint8_t ep, uint8_t ch, bool mute) { - (void)busid; - (void)ep; - (void)ch; - (void)mute; } __WEAK bool usbd_audio_get_mute(uint8_t busid, uint8_t ep, uint8_t ch) { - (void)busid; - (void)ep; - (void)ch; - return 0; } __WEAK void usbd_audio_set_sampling_freq(uint8_t busid, uint8_t ep, uint32_t sampling_freq) { - (void)busid; - (void)ep; - (void)sampling_freq; } __WEAK uint32_t usbd_audio_get_sampling_freq(uint8_t busid, uint8_t ep) { - (void)busid; - (void)ep; - return 0; } __WEAK void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sampling_freq_table) { - (void)busid; - (void)ep; - (void)sampling_freq_table; } diff --git a/rt-thread/components/drivers/usb/cherryusb/class/audio/usbd_audio.h b/rt-thread/components/drivers/usb/cherryusb/class/audio/usbd_audio.h index 75a0b17..442405a 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/audio/usbd_audio.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/audio/usbd_audio.h @@ -27,7 +27,7 @@ struct usbd_interface *usbd_audio_init_intf(uint8_t busid, struct usbd_interface void usbd_audio_open(uint8_t busid, uint8_t intf); void usbd_audio_close(uint8_t busid, uint8_t intf); -void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume_db); +void usbd_audio_set_volume(uint8_t busid, uint8_t ep, uint8_t ch, int volume); int usbd_audio_get_volume(uint8_t busid, uint8_t ep, uint8_t ch); void usbd_audio_set_mute(uint8_t busid, uint8_t ep, uint8_t ch, bool mute); bool usbd_audio_get_mute(uint8_t busid, uint8_t ep, uint8_t ch); diff --git a/rt-thread/components/drivers/usb/cherryusb/class/audio/usbh_audio.c b/rt-thread/components/drivers/usb/cherryusb/class/audio/usbh_audio.c index 6d8b455..223c340 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/audio/usbh_audio.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/audio/usbh_audio.c @@ -21,6 +21,10 @@ #define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */ #define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */ +#ifndef CONFIG_USBHOST_MAX_AUDIO_CLASS +#define CONFIG_USBHOST_MAX_AUDIO_CLASS 4 +#endif + USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_audio_buf[128]; static struct usbh_audio g_audio_class[CONFIG_USBHOST_MAX_AUDIO_CLASS]; @@ -28,11 +32,11 @@ static uint32_t g_devinuse = 0; static struct usbh_audio *usbh_audio_class_alloc(void) { - uint8_t devno; + int devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_AUDIO_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); + if ((g_devinuse & (1 << devno)) == 0) { + g_devinuse |= (1 << devno); memset(&g_audio_class[devno], 0, sizeof(struct usbh_audio)); g_audio_class[devno].minor = devno; return &g_audio_class[devno]; @@ -43,15 +47,15 @@ static struct usbh_audio *usbh_audio_class_alloc(void) static void usbh_audio_class_free(struct usbh_audio *audio_class) { - uint8_t devno = audio_class->minor; + int devno = audio_class->minor; - if (devno < 32) { - g_devinuse &= ~(1U << devno); + if (devno >= 0 && devno < 32) { + g_devinuse &= ~(1 << devno); } memset(audio_class, 0, sizeof(struct usbh_audio)); } -int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq, uint8_t bitresolution) +int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq) { struct usb_setup_packet *setup; struct usb_endpoint_descriptor *ep_desc; @@ -70,24 +74,20 @@ int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t s return 0; } - for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { - if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) { - intf = audio_class->as_msg_table[i].stream_intf; - for (uint8_t j = 1; j < audio_class->as_msg_table[i].num_of_altsetting; j++) { - if (audio_class->as_msg_table[i].as_format[j].bBitResolution == bitresolution) { - for (uint8_t k = 0; k < audio_class->as_msg_table[i].as_format[j].bSamFreqType; k++) { - uint32_t freq = 0; - - memcpy(&freq, &audio_class->as_msg_table[i].as_format[j].tSamFreq[3 * k], 3); - if (freq == samp_freq) { - altsetting = j; - goto freq_found; - } + for (uint8_t i = 0; i < audio_class->module_num; i++) { + if (strcmp(name, audio_class->module[i].name) == 0) { + for (uint8_t j = 0; j < audio_class->num_of_intf_altsettings; j++) { + for (uint8_t k = 0; k < audio_class->module[i].altsetting[j].sampfreq_num; k++) { + if (audio_class->module[i].altsetting[j].sampfreq[k] == samp_freq) { + intf = audio_class->module[i].data_intf; + altsetting = j; + goto freq_found; } } } } } + return -USB_ERR_NODEV; freq_found: @@ -105,18 +105,16 @@ freq_found: ep_desc = &audio_class->hport->config.intf[intf].altsetting[altsetting].ep[0].ep_desc; - if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].ep_attr & AUDIO_EP_CONTROL_SAMPLING_FEQ) { - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_ENDPOINT; - setup->bRequest = AUDIO_REQUEST_SET_CUR; - setup->wValue = (AUDIO_EP_CONTROL_SAMPLING_FEQ << 8) | 0x00; - setup->wIndex = ep_desc->bEndpointAddress; - setup->wLength = 3; + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_ENDPOINT; + setup->bRequest = AUDIO_REQUEST_SET_CUR; + setup->wValue = (AUDIO_EP_CONTROL_SAMPLING_FEQ << 8) | 0x00; + setup->wIndex = ep_desc->bEndpointAddress; + setup->wLength = 3; - memcpy(g_audio_buf, &samp_freq, 3); - ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); - if (ret < 0) { - return ret; - } + memcpy(g_audio_buf, &samp_freq, 3); + ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); + if (ret < 0) { + return ret; } mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT; @@ -129,7 +127,7 @@ freq_found: USBH_EP_INIT(audio_class->isoout, ep_desc); } - USB_LOG_INFO("Open audio stream :%s, altsetting: %u\r\n", name, altsetting); + USB_LOG_INFO("Open audio module :%s, altsetting: %u\r\n", name, altsetting); audio_class->is_opened = true; return ret; } @@ -147,9 +145,9 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name) } setup = audio_class->hport->setup; - for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { - if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) { - intf = audio_class->as_msg_table[i].stream_intf; + for (size_t i = 0; i < audio_class->module_num; i++) { + if (strcmp(name, audio_class->module[i].name) == 0) { + intf = audio_class->module[i].data_intf; } } @@ -157,17 +155,7 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name) return -USB_ERR_NODEV; } - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = USB_REQUEST_SET_INTERFACE; - setup->wValue = 0; - setup->wIndex = intf; - setup->wLength = 0; - - ret = usbh_control_transfer(audio_class->hport, setup, NULL); - if (ret < 0) { - return ret; - } - USB_LOG_INFO("Close audio stream :%s\r\n", name); + USB_LOG_INFO("Close audio module :%s\r\n", name); audio_class->is_opened = false; ep_desc = &audio_class->hport->config.intf[intf].altsetting[altsetting].ep[0].ep_desc; @@ -181,128 +169,52 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name) } } + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = USB_REQUEST_SET_INTERFACE; + setup->wValue = 0; + setup->wIndex = intf; + setup->wLength = 0; + + ret = usbh_control_transfer(audio_class->hport, setup, NULL); + return ret; } -int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, int volume_db) +int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume) { struct usb_setup_packet *setup; int ret; + uint8_t intf = 0xff; uint8_t feature_id = 0xff; - uint8_t intf; uint16_t volume_hex; - int volume_min_db; - int volume_max_db; if (!audio_class || !audio_class->hport) { return -USB_ERR_INVAL; } - - if ((volume_db > 127) || (volume_db < -127)) { - return -USB_ERR_INVAL; - } - setup = audio_class->hport->setup; - for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { - if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) { - feature_id = audio_class->as_msg_table[i].feature_terminal_id; - intf = audio_class->as_msg_table[i].stream_intf; + for (size_t i = 0; i < audio_class->module_num; i++) { + if (strcmp(name, audio_class->module[i].name) == 0) { + intf = audio_class->ctrl_intf; + feature_id = audio_class->module[i].feature_unit_id; } } - if (feature_id == 0xff) { + if (intf == 0xff) { return -USB_ERR_NODEV; } - setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = AUDIO_REQUEST_GET_CUR; - setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch; - setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; - setup->wLength = 2; - - ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); - if (ret < 0) { - return ret; - } - - memcpy(&audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_cur, g_audio_buf, 2); - - setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = AUDIO_REQUEST_GET_MIN; - setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch; - setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; - setup->wLength = 2; - - ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); - if (ret < 0) { - return ret; - } - - memcpy(&audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min, g_audio_buf, 2); - - setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = AUDIO_REQUEST_GET_MAX; - setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch; - setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; - setup->wLength = 2; - - ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); - if (ret < 0) { - return ret; - } - memcpy(&audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max, g_audio_buf, 2); - - setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = AUDIO_REQUEST_GET_RES; - setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch; - setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; - setup->wLength = 2; - - ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); - if (ret < 0) { - return ret; - } - memcpy(&audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_res, g_audio_buf, 2); - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; setup->bRequest = AUDIO_REQUEST_SET_CUR; setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch; - setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; + setup->wIndex = (feature_id << 8) | intf; setup->wLength = 2; - if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min < 0x8000) { - volume_min_db = audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min / 256; - } else { - volume_min_db = (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min - 0x10000) / 256; - } - - if (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max < 0x8000) { - volume_max_db = audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max / 256; - } else { - volume_max_db = (audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max - 0x10000) / 256; - } - - USB_LOG_INFO("Get ch:%d dB range: %d dB ~ %d dB\r\n", volume_min_db, volume_max_db); - - if (volume_db >= 0) { - volume_hex = volume_db * 256; - if (volume_hex > audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_max) { - return -USB_ERR_RANGE; - } - } else { - volume_hex = volume_db * 256 + 0x10000; - if (volume_hex < audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_min) { - return -USB_ERR_RANGE; - } - } + volume_hex = -0xDB00 / 100 * volume + 0xdb00; memcpy(g_audio_buf, &volume_hex, 2); - ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); - if (ret < 0) { - return ret; - } - audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].volume_cur = volume_hex; + ret = usbh_control_transfer(audio_class->hport, setup, NULL); + return ret; } @@ -310,37 +222,34 @@ int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_ { struct usb_setup_packet *setup; int ret; - uint8_t feature_id = 0xff; uint8_t intf = 0xff; + uint8_t feature_id = 0xff; if (!audio_class || !audio_class->hport) { return -USB_ERR_INVAL; } setup = audio_class->hport->setup; - for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { - if (strcmp(name, audio_class->as_msg_table[i].stream_name) == 0) { - feature_id = audio_class->as_msg_table[i].feature_terminal_id; - intf = audio_class->as_msg_table[i].stream_intf; + for (size_t i = 0; i < audio_class->module_num; i++) { + if (strcmp(name, audio_class->module[i].name) == 0) { + intf = audio_class->ctrl_intf; + feature_id = audio_class->module[i].feature_unit_id; } } - if (feature_id == 0xff) { + if (intf == 0xff) { return -USB_ERR_NODEV; } setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; setup->bRequest = AUDIO_REQUEST_SET_CUR; setup->wValue = (AUDIO_FU_CONTROL_MUTE << 8) | ch; - setup->wIndex = (feature_id << 8) | audio_class->ctrl_intf; + setup->wIndex = (feature_id << 8) | intf; setup->wLength = 1; memcpy(g_audio_buf, &mute, 1); ret = usbh_control_transfer(audio_class->hport, setup, g_audio_buf); - if (ret < 0) { - return ret; - } - audio_class->as_msg_table[intf - audio_class->ctrl_intf - 1].mute = mute; + return ret; } @@ -348,28 +257,26 @@ void usbh_audio_list_module(struct usbh_audio *audio_class) { USB_LOG_INFO("============= Audio module information ===================\r\n"); USB_LOG_RAW("bcdADC :%04x\r\n", audio_class->bcdADC); - USB_LOG_RAW("Num of audio stream :%u\r\n", audio_class->stream_intf_num); + USB_LOG_RAW("Num of modules :%u\r\n", audio_class->module_num); + USB_LOG_RAW("Num of altsettings:%u\r\n", audio_class->num_of_intf_altsettings); - for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { - USB_LOG_RAW("\tstream name :%s\r\n", audio_class->as_msg_table[i].stream_name); - USB_LOG_RAW("\tstream intf :%u\r\n", audio_class->as_msg_table[i].stream_intf); - USB_LOG_RAW("\tNum of altsetting :%u\r\n", audio_class->as_msg_table[i].num_of_altsetting); + for (uint8_t i = 0; i < audio_class->module_num; i++) { + USB_LOG_RAW(" module name :%s\r\n", audio_class->module[i].name); + USB_LOG_RAW(" module feature unit id :%d\r\n", audio_class->module[i].feature_unit_id); - for (uint8_t j = 0; j < audio_class->as_msg_table[i].num_of_altsetting; j++) { + for (uint8_t j = 0; j < audio_class->num_of_intf_altsettings; j++) { if (j == 0) { - USB_LOG_RAW("\t\tIngore altsetting 0\r\n"); + USB_LOG_RAW(" Ingore altsetting 0\r\n"); continue; } - USB_LOG_RAW("\t\tAltsetting :%u\r\n", j); - USB_LOG_RAW("\t\t\tbNrChannels :%u\r\n", audio_class->as_msg_table[i].as_format[j].bNrChannels); - USB_LOG_RAW("\t\t\tbBitResolution :%u\r\n", audio_class->as_msg_table[i].as_format[j].bBitResolution); - USB_LOG_RAW("\t\t\tbSamFreqType :%u\r\n", audio_class->as_msg_table[i].as_format[j].bSamFreqType); + USB_LOG_RAW(" Altsetting %u\r\n", j); + USB_LOG_RAW(" module channels :%u\r\n", audio_class->module[i].altsetting[j].channels); + //USB_LOG_RAW(" module format_type :%u\r\n",audio_class->module[i].altsetting[j].format_type); + USB_LOG_RAW(" module bitresolution :%u\r\n", audio_class->module[i].altsetting[j].bitresolution); + USB_LOG_RAW(" module sampfreq num :%u\r\n", audio_class->module[i].altsetting[j].sampfreq_num); - for (uint8_t k = 0; k < audio_class->as_msg_table[i].as_format[j].bSamFreqType; k++) { - uint32_t freq = 0; - - memcpy(&freq, &audio_class->as_msg_table[i].as_format[j].tSamFreq[3 * k], 3); - USB_LOG_RAW("\t\t\t\tSampleFreq :%u\r\n", freq); + for (uint8_t k = 0; k < audio_class->module[i].altsetting[j].sampfreq_num; k++) { + USB_LOG_RAW(" module sampfreq :%d hz\r\n", audio_class->module[i].altsetting[j].sampfreq[k]); } } } @@ -380,14 +287,14 @@ void usbh_audio_list_module(struct usbh_audio *audio_class) static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) { int ret; - uint8_t cur_iface = 0; - uint8_t cur_iface_count = 0; - uint8_t cur_alt_setting = 0; + uint8_t cur_iface = 0xff; + uint8_t cur_iface_count = 0xff; + uint8_t cur_alt_setting = 0xff; uint8_t input_offset = 0; uint8_t output_offset = 0; uint8_t feature_unit_offset = 0; + uint8_t format_offset = 0; uint8_t *p; - struct usbh_audio_ac_msg ac_msg_table[CONFIG_USBHOST_AUDIO_MAX_STREAMS]; struct usbh_audio *audio_class = usbh_audio_class_alloc(); if (audio_class == NULL) { @@ -397,6 +304,8 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) audio_class->hport = hport; audio_class->ctrl_intf = intf; + audio_class->num_of_intf_altsettings = hport->config.intf[intf + 1].altsetting_num; + hport->config.intf[intf].priv = audio_class; p = hport->raw_config_desc; @@ -422,49 +331,72 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) case AUDIO_CONTROL_INPUT_TERMINAL: { struct audio_cs_if_ac_input_terminal_descriptor *desc = (struct audio_cs_if_ac_input_terminal_descriptor *)p; - memcpy(&ac_msg_table[input_offset].ac_input, desc, sizeof(struct audio_cs_if_ac_input_terminal_descriptor)); + audio_class->module[input_offset].input_terminal_id = desc->bTerminalID; + audio_class->module[input_offset].input_terminal_type = desc->wTerminalType; + audio_class->module[input_offset].input_channel_config = desc->wChannelConfig; + + if (desc->wTerminalType == AUDIO_TERMINAL_STREAMING) { + audio_class->module[input_offset].terminal_link_id = desc->bTerminalID; + } + if (desc->wTerminalType == AUDIO_INTERM_MIC) { + audio_class->module[input_offset].name = "mic"; + } input_offset++; } break; + break; case AUDIO_CONTROL_OUTPUT_TERMINAL: { struct audio_cs_if_ac_output_terminal_descriptor *desc = (struct audio_cs_if_ac_output_terminal_descriptor *)p; - - memcpy(&ac_msg_table[output_offset].ac_output, desc, sizeof(struct audio_cs_if_ac_output_terminal_descriptor)); + audio_class->module[output_offset].output_terminal_id = desc->bTerminalID; + audio_class->module[output_offset].output_terminal_type = desc->wTerminalType; + if (desc->wTerminalType == AUDIO_TERMINAL_STREAMING) { + audio_class->module[output_offset].terminal_link_id = desc->bTerminalID; + } + if (desc->wTerminalType == AUDIO_OUTTERM_SPEAKER) { + audio_class->module[output_offset].name = "speaker"; + } output_offset++; } break; case AUDIO_CONTROL_FEATURE_UNIT: { struct audio_cs_if_ac_feature_unit_descriptor *desc = (struct audio_cs_if_ac_feature_unit_descriptor *)p; + audio_class->module[feature_unit_offset].feature_unit_id = desc->bUnitID; + audio_class->module[feature_unit_offset].feature_unit_controlsize = desc->bControlSize; - memcpy(&ac_msg_table[feature_unit_offset].ac_feature_unit, desc, desc->bLength); + for (uint8_t j = 0; j < desc->bControlSize; j++) { + audio_class->module[feature_unit_offset].feature_unit_controls[j] = p[6 + j]; + } feature_unit_offset++; } break; - default: - USB_LOG_ERR("Do not support %02x subtype\r\n", p[DESC_bDescriptorSubType]); - return -USB_ERR_NOTSUPP; - } - } else if ((cur_iface > audio_class->ctrl_intf) && (cur_iface < (audio_class->ctrl_intf + cur_iface_count))) { - switch (p[DESC_bDescriptorSubType]) { - case AUDIO_STREAMING_GENERAL: { - struct audio_cs_if_as_general_descriptor *desc = (struct audio_cs_if_as_general_descriptor *)p; + case AUDIO_CONTROL_PROCESSING_UNIT: - /* all altsetting have the same general */ - audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].stream_intf = cur_iface; - memcpy(&audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].as_general, desc, sizeof(struct audio_cs_if_as_general_descriptor)); - } break; - case AUDIO_STREAMING_FORMAT_TYPE: { - struct audio_cs_if_as_format_type_descriptor *desc = (struct audio_cs_if_as_format_type_descriptor *)p; - audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].num_of_altsetting = (cur_alt_setting + 1); - memcpy(&audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].as_format[cur_alt_setting], desc, desc->bLength); - } break; + break; default: break; } - } - break; - case AUDIO_ENDPOINT_DESCRIPTOR_TYPE: - if ((cur_iface > audio_class->ctrl_intf) && (cur_iface < (audio_class->ctrl_intf + cur_iface_count))) { - if (p[DESC_bDescriptorSubType] == AUDIO_ENDPOINT_GENERAL) { - struct audio_cs_ep_ep_general_descriptor *desc = (struct audio_cs_ep_ep_general_descriptor *)p; - audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].ep_attr = desc->bmAttributes; + } else if ((cur_iface < (audio_class->ctrl_intf + cur_iface_count)) && (cur_iface > audio_class->ctrl_intf)) { + switch (p[DESC_bDescriptorSubType]) { + case AUDIO_STREAMING_GENERAL: + + break; + case AUDIO_STREAMING_FORMAT_TYPE: { + struct audio_cs_if_as_format_type_descriptor *desc = (struct audio_cs_if_as_format_type_descriptor *)p; + + audio_class->module[format_offset].data_intf = cur_iface; + audio_class->module[format_offset].altsetting[cur_alt_setting].channels = desc->bNrChannels; + audio_class->module[format_offset].altsetting[cur_alt_setting].format_type = desc->bFormatType; + audio_class->module[format_offset].altsetting[cur_alt_setting].bitresolution = desc->bBitResolution; + audio_class->module[format_offset].altsetting[cur_alt_setting].sampfreq_num = desc->bSamFreqType; + + for (uint8_t j = 0; j < desc->bSamFreqType; j++) { + audio_class->module[format_offset].altsetting[cur_alt_setting].sampfreq[j] = (uint32_t)(p[10 + j * 3] << 16) | + (uint32_t)(p[9 + j * 3] << 8) | + (uint32_t)(p[8 + j * 3] << 0); + } + if (cur_alt_setting == (hport->config.intf[intf + 1].altsetting_num - 1)) { + format_offset++; + } + } break; + default: + break; } } break; @@ -475,98 +407,16 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) p += p[DESC_bLength]; } - if ((input_offset != output_offset) && (input_offset != feature_unit_offset)) { - USB_LOG_ERR("Audio control descriptor is invalid\r\n"); + if ((input_offset != output_offset) && (input_offset != feature_unit_offset) && (input_offset != format_offset)) { return -USB_ERR_INVAL; } - if (cur_iface_count == 0xff) { - USB_LOG_ERR("Audio descriptor must have iad descriptor\r\n"); - return -USB_ERR_INVAL; - } + audio_class->module_num = input_offset; - audio_class->stream_intf_num = input_offset; - - for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { - /* Search 0x0101 in input or output desc */ - for (uint8_t streamidx = 0; streamidx < audio_class->stream_intf_num; streamidx++) { - if (audio_class->as_msg_table[i].as_general.bTerminalLink == ac_msg_table[streamidx].ac_input.bTerminalID) { - /* INPUT --> FEATURE UNIT --> OUTPUT */ - audio_class->as_msg_table[i].input_terminal_id = ac_msg_table[streamidx].ac_input.bTerminalID; - - /* Search input terminal id in feature desc */ - for (uint8_t featureidx = 0; featureidx < audio_class->stream_intf_num; featureidx++) { - if (ac_msg_table[streamidx].ac_input.bTerminalID == ac_msg_table[featureidx].ac_feature_unit.bSourceID) { - audio_class->as_msg_table[i].feature_terminal_id = ac_msg_table[featureidx].ac_feature_unit.bUnitID; - - /* Search feature unit id in output desc */ - for (uint8_t outputid = 0; outputid < audio_class->stream_intf_num; outputid++) { - if (ac_msg_table[featureidx].ac_feature_unit.bUnitID == ac_msg_table[outputid].ac_output.bSourceID) { - audio_class->as_msg_table[i].output_terminal_id = ac_msg_table[outputid].ac_output.bTerminalID; - - switch (ac_msg_table[outputid].ac_output.wTerminalType) { - case AUDIO_OUTTERM_SPEAKER: - audio_class->as_msg_table[i].stream_name = "speaker"; - break; - case AUDIO_OUTTERM_HEADPHONES: - audio_class->as_msg_table[i].stream_name = "headphoens"; - break; - case AUDIO_OUTTERM_HEADDISPLAY: - audio_class->as_msg_table[i].stream_name = "headdisplay"; - break; - default: - audio_class->as_msg_table[i].stream_name = "unknown"; - break; - } - break; - } - } - break; - } - } - } else if (audio_class->as_msg_table[i].as_general.bTerminalLink == ac_msg_table[streamidx].ac_output.bTerminalID) { - /* OUTPUT --> FEATURE UNIT --> INPUT */ - audio_class->as_msg_table[i].output_terminal_id = ac_msg_table[streamidx].ac_output.bTerminalID; - - /* Search output terminal id in feature desc */ - for (uint8_t featureidx = 0; featureidx < audio_class->stream_intf_num; featureidx++) { - if (ac_msg_table[streamidx].ac_output.bSourceID == ac_msg_table[featureidx].ac_feature_unit.bUnitID) { - audio_class->as_msg_table[i].feature_terminal_id = ac_msg_table[featureidx].ac_feature_unit.bUnitID; - - /* Search feature unit id in input desc */ - for (uint8_t inputid = 0; inputid < audio_class->stream_intf_num; inputid++) { - if (ac_msg_table[featureidx].ac_feature_unit.bSourceID == ac_msg_table[inputid].ac_input.bTerminalID) { - audio_class->as_msg_table[i].input_terminal_id = ac_msg_table[inputid].ac_input.bTerminalID; - - switch (ac_msg_table[inputid].ac_input.wTerminalType) { - case AUDIO_INTERM_MIC: - audio_class->as_msg_table[i].stream_name = "mic"; - break; - default: - audio_class->as_msg_table[i].stream_name = "unknown"; - break; - } - break; - } - } - break; - } - } - } - } - } - - for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { - if (audio_class->as_msg_table[i].stream_name == NULL) { - USB_LOG_ERR("Audio stream search fail\r\n"); - return -USB_ERR_NODEV; - } - } - - for (uint8_t i = 0; i < audio_class->stream_intf_num; i++) { - ret = usbh_audio_close(audio_class, audio_class->as_msg_table[i].stream_name); + for (size_t i = 0; i < audio_class->module_num; i++) { + ret = usbh_audio_close(audio_class, audio_class->module[i].name); if (ret < 0) { - USB_LOG_ERR("Fail to close audio stream :%s\r\n", audio_class->as_msg_table[i].stream_name); + USB_LOG_ERR("Fail to close audio module :%s\r\n", audio_class->module[i].name); return ret; } } @@ -606,26 +456,20 @@ static int usbh_audio_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf) static int usbh_audio_data_connect(struct usbh_hubport *hport, uint8_t intf) { - (void)hport; - (void)intf; return 0; } static int usbh_audio_data_disconnect(struct usbh_hubport *hport, uint8_t intf) { - (void)hport; - (void)intf; return 0; } __WEAK void usbh_audio_run(struct usbh_audio *audio_class) { - (void)audio_class; } __WEAK void usbh_audio_stop(struct usbh_audio *audio_class) { - (void)audio_class; } const struct usbh_class_driver audio_ctrl_class_driver = { @@ -642,18 +486,18 @@ const struct usbh_class_driver audio_streaming_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info audio_ctrl_intf_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS, - .bInterfaceClass = USB_DEVICE_CLASS_AUDIO, - .bInterfaceSubClass = AUDIO_SUBCLASS_AUDIOCONTROL, - .bInterfaceProtocol = 0x00, + .class = USB_DEVICE_CLASS_AUDIO, + .subclass = AUDIO_SUBCLASS_AUDIOCONTROL, + .protocol = 0x00, .id_table = NULL, .class_driver = &audio_ctrl_class_driver }; CLASS_INFO_DEFINE const struct usbh_class_info audio_streaming_intf_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS, - .bInterfaceClass = USB_DEVICE_CLASS_AUDIO, - .bInterfaceSubClass = AUDIO_SUBCLASS_AUDIOSTREAMING, - .bInterfaceProtocol = 0x00, + .class = USB_DEVICE_CLASS_AUDIO, + .subclass = AUDIO_SUBCLASS_AUDIOSTREAMING, + .protocol = 0x00, .id_table = NULL, .class_driver = &audio_streaming_class_driver }; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/audio/usbh_audio.h b/rt-thread/components/drivers/usb/cherryusb/class/audio/usbh_audio.h index 2e583ac..038a8f7 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/audio/usbh_audio.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/audio/usbh_audio.h @@ -8,31 +8,34 @@ #include "usb_audio.h" -#ifndef CONFIG_USBHOST_AUDIO_MAX_STREAMS -#define CONFIG_USBHOST_AUDIO_MAX_STREAMS 3 -#endif - -struct usbh_audio_ac_msg { - struct audio_cs_if_ac_input_terminal_descriptor ac_input; - struct audio_cs_if_ac_feature_unit_descriptor ac_feature_unit; - struct audio_cs_if_ac_output_terminal_descriptor ac_output; +struct usbh_audio_format_type { + uint8_t channels; + uint8_t format_type; + uint8_t bitresolution; + uint8_t sampfreq_num; + uint32_t sampfreq[3]; }; -struct usbh_audio_as_msg { - const char *stream_name; - uint8_t stream_intf; +/** + * bSourceID in feature_unit = input_terminal_id + * bSourceID in output_terminal = feature_unit_id + * terminal_link_id = input_terminal_id or output_terminal_id (if input_terminal_type or output_terminal_type is 0x0101) + * + * +*/ +struct usbh_audio_module { + const char *name; + uint8_t data_intf; uint8_t input_terminal_id; - uint8_t feature_terminal_id; + uint16_t input_terminal_type; + uint16_t input_channel_config; uint8_t output_terminal_id; - uint8_t ep_attr; - uint8_t num_of_altsetting; - uint16_t volume_min; - uint16_t volume_max; - uint16_t volume_res; - uint16_t volume_cur; - bool mute; - struct audio_cs_if_as_general_descriptor as_general; - struct audio_cs_if_as_format_type_descriptor as_format[CONFIG_USBHOST_MAX_INTF_ALTSETTINGS]; + uint16_t output_terminal_type; + uint8_t feature_unit_id; + uint8_t feature_unit_controlsize; + uint8_t feature_unit_controls[8]; + uint8_t terminal_link_id; + struct usbh_audio_format_type altsetting[CONFIG_USBHOST_MAX_INTF_ALTSETTINGS]; }; struct usbh_audio { @@ -47,8 +50,9 @@ struct usbh_audio { bool is_opened; uint16_t bcdADC; uint8_t bInCollection; - uint8_t stream_intf_num; - struct usbh_audio_as_msg as_msg_table[CONFIG_USBHOST_AUDIO_MAX_STREAMS]; + uint8_t num_of_intf_altsettings; + struct usbh_audio_module module[2]; + uint8_t module_num; void *user_data; }; @@ -57,9 +61,9 @@ struct usbh_audio { extern "C" { #endif -int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq, uint8_t bitresolution); +int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq); int usbh_audio_close(struct usbh_audio *audio_class, const char *name); -int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, int volume_db); +int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume); int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_t ch, bool mute); void usbh_audio_run(struct usbh_audio *audio_class); diff --git a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h index d1546ee..2bf0a17 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usb_cdc.h @@ -421,7 +421,7 @@ struct cdc_ncm_ndp16 { 0x02, /* bInterfaceCount */ \ USB_DEVICE_CLASS_CDC, /* bFunctionClass */ \ CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */ \ - CDC_COMMON_PROTOCOL_NONE, /* bFunctionProtocol */ \ + CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bFunctionProtocol */ \ 0x00, /* iFunction */ \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ @@ -430,7 +430,7 @@ struct cdc_ncm_ndp16 { 0x01, /* bNumEndpoints */ \ USB_DEVICE_CLASS_CDC, /* bInterfaceClass */ \ CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass */ \ - CDC_COMMON_PROTOCOL_NONE, /* bInterfaceProtocol */ \ + CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bInterfaceProtocol */ \ str_idx, /* iInterface */ \ 0x05, /* bLength */ \ CDC_CS_INTERFACE, /* bDescriptorType */ \ @@ -489,8 +489,8 @@ struct cdc_ncm_ndp16 { bFirstInterface, /* bFirstInterface */ \ 0x02, /* bInterfaceCount */ \ USB_DEVICE_CLASS_WIRELESS, /* bFunctionClass */ \ - 0x01, /* bFunctionSubClass */ \ - 0x03, /* bFunctionProtocol */ \ + CDC_DIRECT_LINE_CONTROL_MODEL, /* bFunctionSubClass */ \ + CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bFunctionProtocol */ \ 0x00, /* iFunction */ \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ @@ -498,8 +498,8 @@ struct cdc_ncm_ndp16 { 0x00, /* bAlternateSetting */ \ 0x01, /* bNumEndpoints */ \ USB_DEVICE_CLASS_WIRELESS, /* bInterfaceClass */ \ - 0x01, /* bInterfaceSubClass */ \ - 0x03, /* bInterfaceProtocol */ \ + CDC_DIRECT_LINE_CONTROL_MODEL, /* bInterfaceSubClass */ \ + CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bInterfaceProtocol */ \ str_idx, /* iInterface */ \ 0x05, /* bLength */ \ CDC_CS_INTERFACE, /* bDescriptorType */ \ @@ -524,7 +524,7 @@ struct cdc_ncm_ndp16 { int_ep, /* bEndpointAddress */ \ 0x03, /* bmAttributes */ \ 0x08, 0x00, /* wMaxPacketSize */ \ - 0x05, /* bInterval */ \ + 0x10, /* bInterval */ \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \ @@ -596,7 +596,7 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx) int_ep, /* bEndpointAddress */ \ 0x03, /* bmAttributes */ \ 0x10, 0x00, /* wMaxPacketSize */ \ - 0x05, /* bInterval */ \ + 0x10, /* bInterval */ \ 0x09, /* bLength */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \ diff --git a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc.h b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc.h index 2cf3df1..ebf3d02 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc.h @@ -1,13 +1,29 @@ /* - * Copyright (c) 2024, sakumisu + * Copyright (c) 2022, sakumisu * * SPDX-License-Identifier: Apache-2.0 */ #ifndef USBD_CDC_H #define USBD_CDC_H -// legacy for old version +#include "usb_cdc.h" -#include "usbd_cdc_acm.h" +#ifdef __cplusplus +extern "C" { +#endif -#endif \ No newline at end of file +/* Init cdc acm interface driver */ +struct usbd_interface *usbd_cdc_acm_init_intf(uint8_t busid, struct usbd_interface *intf); + +/* Setup request command callback api */ +void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding); +void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding); +void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr); +void usbd_cdc_acm_set_rts(uint8_t busid, uint8_t intf, bool rts); +void usbd_cdc_acm_send_break(uint8_t busid, uint8_t intf); + +#ifdef __cplusplus +} +#endif + +#endif /* USBD_CDC_H */ diff --git a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c deleted file mode 100644 index cf7c3c0..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2022, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbd_core.h" -#include "usbd_cdc_acm.h" - -const char *stop_name[] = { "1", "1.5", "2" }; -const char *parity_name[] = { "N", "O", "E", "M", "S" }; - -static int cdc_acm_class_interface_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) -{ - USB_LOG_DBG("CDC Class request: " - "bRequest 0x%02x\r\n", - setup->bRequest); - - struct cdc_line_coding line_coding; - bool dtr, rts; - uint8_t intf_num = LO_BYTE(setup->wIndex); - - switch (setup->bRequest) { - case CDC_REQUEST_SET_LINE_CODING: - - /*******************************************************************************/ - /* Line Coding Structure */ - /*-----------------------------------------------------------------------------*/ - /* Offset | Field | Size | Value | Description */ - /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/ - /* 4 | bCharFormat | 1 | Number | Stop bits */ - /* 0 - 1 Stop bit */ - /* 1 - 1.5 Stop bits */ - /* 2 - 2 Stop bits */ - /* 5 | bParityType | 1 | Number | Parity */ - /* 0 - None */ - /* 1 - Odd */ - /* 2 - Even */ - /* 3 - Mark */ - /* 4 - Space */ - /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */ - /*******************************************************************************/ - memcpy(&line_coding, *data, setup->wLength); - USB_LOG_DBG("Set intf:%d linecoding <%d %d %s %s>\r\n", - intf_num, - line_coding.dwDTERate, - line_coding.bDataBits, - parity_name[line_coding.bParityType], - stop_name[line_coding.bCharFormat]); - - usbd_cdc_acm_set_line_coding(busid, intf_num, &line_coding); - break; - - case CDC_REQUEST_SET_CONTROL_LINE_STATE: - dtr = (setup->wValue & 0x0001); - rts = (setup->wValue & 0x0002); - USB_LOG_DBG("Set intf:%d DTR 0x%x,RTS 0x%x\r\n", - intf_num, - dtr, - rts); - usbd_cdc_acm_set_dtr(busid, intf_num, dtr); - usbd_cdc_acm_set_rts(busid, intf_num, rts); - break; - - case CDC_REQUEST_GET_LINE_CODING: - usbd_cdc_acm_get_line_coding(busid, intf_num, &line_coding); - memcpy(*data, &line_coding, 7); - *len = 7; - USB_LOG_DBG("Get intf:%d linecoding %d %d %d %d\r\n", - intf_num, - line_coding.dwDTERate, - line_coding.bCharFormat, - line_coding.bParityType, - line_coding.bDataBits); - break; - case CDC_REQUEST_SEND_BREAK: - usbd_cdc_acm_send_break(busid, intf_num); - break; - default: - USB_LOG_WRN("Unhandled CDC Class bRequest 0x%02x\r\n", setup->bRequest); - return -1; - } - - return 0; -} - -struct usbd_interface *usbd_cdc_acm_init_intf(uint8_t busid, struct usbd_interface *intf) -{ - (void)busid; - - intf->class_interface_handler = cdc_acm_class_interface_request_handler; - intf->class_endpoint_handler = NULL; - intf->vendor_handler = NULL; - intf->notify_handler = NULL; - - return intf; -} - -__WEAK void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding) -{ - (void)busid; - (void)intf; - (void)line_coding; -} - -__WEAK void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding) -{ - (void)busid; - (void)intf; - - line_coding->dwDTERate = 2000000; - line_coding->bDataBits = 8; - line_coding->bParityType = 0; - line_coding->bCharFormat = 0; -} - -__WEAK void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr) -{ - (void)busid; - (void)intf; - (void)dtr; -} - -__WEAK void usbd_cdc_acm_set_rts(uint8_t busid, uint8_t intf, bool rts) -{ - (void)busid; - (void)intf; - (void)rts; -} - -__WEAK void usbd_cdc_acm_send_break(uint8_t busid, uint8_t intf) -{ - (void)busid; - (void)intf; -} diff --git a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.h b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.h deleted file mode 100644 index 662c238..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2022, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USBD_CDC_ACM_H -#define USBD_CDC_ACM_H - -#include "usb_cdc.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Init cdc acm interface driver */ -struct usbd_interface *usbd_cdc_acm_init_intf(uint8_t busid, struct usbd_interface *intf); - -/* Setup request command callback api */ -void usbd_cdc_acm_set_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding); -void usbd_cdc_acm_get_line_coding(uint8_t busid, uint8_t intf, struct cdc_line_coding *line_coding); -void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr); -void usbd_cdc_acm_set_rts(uint8_t busid, uint8_t intf, bool rts); -void usbd_cdc_acm_send_break(uint8_t busid, uint8_t intf); - -#ifdef __cplusplus -} -#endif - -#endif /* USBD_CDC_ACM_H */ diff --git a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c index 5ae10a2..b0c1217 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.c @@ -7,21 +7,17 @@ #include "usbd_cdc_ecm.h" #define CDC_ECM_OUT_EP_IDX 0 -#define CDC_ECM_IN_EP_IDX 1 -#define CDC_ECM_INT_EP_IDX 2 - -/* Ethernet Maximum Segment size, typically 1514 bytes */ -#define CONFIG_CDC_ECM_ETH_MAX_SEGSZE 1536U +#define CDC_ECM_IN_EP_IDX 1 +#define CDC_ECM_INT_EP_IDX 2 /* Describe EndPoints configuration */ static struct usbd_endpoint cdc_ecm_ep_data[3]; -#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE]; static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE]; -#endif static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_notify_buf[16]; +volatile uint8_t *g_cdc_ecm_rx_data_buffer = NULL; volatile uint32_t g_cdc_ecm_rx_data_length = 0; volatile uint32_t g_cdc_ecm_tx_data_length = 0; @@ -72,10 +68,8 @@ void usbd_cdc_ecm_send_notify(uint8_t notifycode, uint8_t value, uint32_t *speed break; } - if (usb_device_is_configured(0)) { - if (bytes2send) { - usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_INT_EP_IDX].ep_addr, g_cdc_ecm_notify_buf, bytes2send); - } + if (bytes2send) { + usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_INT_EP_IDX].ep_addr, g_cdc_ecm_notify_buf, bytes2send); } } @@ -85,10 +79,6 @@ static int cdc_ecm_class_interface_request_handler(uint8_t busid, struct usb_set "bRequest 0x%02x\r\n", setup->bRequest); - (void)busid; - (void)data; - (void)len; - g_cmd_intf = LO_BYTE(setup->wIndex); switch (setup->bRequest) { @@ -99,11 +89,11 @@ static int cdc_ecm_class_interface_request_handler(uint8_t busid, struct usb_set * bit3 Broadcast * bit4 Multicast */ -#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP - g_connect_speed_table[0] = 100000000; /* 100 Mbps */ - g_connect_speed_table[1] = 100000000; /* 100 Mbps */ - usbd_cdc_ecm_set_connect(true, g_connect_speed_table); -#endif + if (g_current_net_status == 0) { + g_current_net_status = 1; + usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, NULL); + } + break; default: USB_LOG_WRN("Unhandled CDC ECM Class bRequest 0x%02x\r\n", setup->bRequest); @@ -115,19 +105,15 @@ static int cdc_ecm_class_interface_request_handler(uint8_t busid, struct usb_set void cdc_ecm_notify_handler(uint8_t busid, uint8_t event, void *arg) { - (void)busid; - (void)arg; - switch (event) { case USBD_EVENT_RESET: g_current_net_status = 0; g_cdc_ecm_rx_data_length = 0; g_cdc_ecm_tx_data_length = 0; + g_cdc_ecm_rx_data_buffer = NULL; break; case USBD_EVENT_CONFIGURED: -#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP - usbd_cdc_ecm_start_read(g_cdc_ecm_rx_buffer, CONFIG_CDC_ECM_ETH_MAX_SEGSZE); -#endif + usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(busid, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr)); break; default: @@ -137,45 +123,36 @@ void cdc_ecm_notify_handler(uint8_t busid, uint8_t event, void *arg) void cdc_ecm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) { - (void)busid; + g_cdc_ecm_rx_data_length += nbytes; - g_cdc_ecm_rx_data_length = nbytes; - usbd_cdc_ecm_data_recv_done(g_cdc_ecm_rx_data_length); + if (nbytes < usbd_get_ep_mps(busid, ep)) { + g_cdc_ecm_rx_data_buffer = g_cdc_ecm_rx_buffer; + usbd_cdc_ecm_data_recv_done(g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length); + } else { + usbd_ep_start_read(0, ep, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(busid, ep)); + } } void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) { - (void)busid; - - if ((nbytes % usbd_get_ep_mps(0, ep)) == 0 && nbytes) { + if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) { /* send zlp */ usbd_ep_start_write(0, ep, NULL, 0); } else { - usbd_cdc_ecm_data_send_done(g_cdc_ecm_tx_data_length); g_cdc_ecm_tx_data_length = 0; } } void cdc_ecm_int_in(uint8_t busid, uint8_t ep, uint32_t nbytes) { - (void)busid; - (void)ep; - (void)nbytes; - - if (g_current_net_status == 2) { - g_current_net_status = 3; - usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_CONNECTION_SPEED_CHANGE, 0, g_connect_speed_table); - } else { - g_current_net_status = 0; + if (g_current_net_status == 1) { + g_current_net_status = 2; + usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, g_connect_speed_table); } } int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len) { - if (!usb_device_is_configured(0)) { - return -USB_ERR_NODEV; - } - if (g_cdc_ecm_tx_data_length > 0) { return -USB_ERR_BUSY; } @@ -183,17 +160,14 @@ int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len) g_cdc_ecm_tx_data_length = len; USB_LOG_DBG("txlen:%d\r\n", g_cdc_ecm_tx_data_length); - return usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_IN_EP_IDX].ep_addr, buf, len); + return usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_IN_EP_IDX].ep_addr, buf, g_cdc_ecm_tx_data_length); } -int usbd_cdc_ecm_start_read(uint8_t *buf, uint32_t len) +void usbd_cdc_ecm_start_read_next(void) { - if (!usb_device_is_configured(0)) { - return -USB_ERR_NODEV; - } - g_cdc_ecm_rx_data_length = 0; - return usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, buf, len); + g_cdc_ecm_rx_data_buffer = NULL; + usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, g_cdc_ecm_rx_buffer, usbd_get_ep_mps(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr)); } #ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP @@ -201,19 +175,19 @@ struct pbuf *usbd_cdc_ecm_eth_rx(void) { struct pbuf *p; - if (g_cdc_ecm_rx_data_length == 0) { + if (g_cdc_ecm_rx_data_buffer == NULL) { return NULL; } p = pbuf_alloc(PBUF_RAW, g_cdc_ecm_rx_data_length, PBUF_POOL); if (p == NULL) { - usbd_cdc_ecm_start_read(g_cdc_ecm_rx_buffer, CONFIG_CDC_ECM_ETH_MAX_SEGSZE); + usbd_cdc_ecm_start_read_next(); return NULL; } usb_memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length); p->len = g_cdc_ecm_rx_data_length; USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_data_length); - usbd_cdc_ecm_start_read(g_cdc_ecm_rx_buffer, CONFIG_CDC_ECM_ETH_MAX_SEGSZE); + usbd_cdc_ecm_start_read_next(); return p; } @@ -261,24 +235,11 @@ struct usbd_interface *usbd_cdc_ecm_init_intf(struct usbd_interface *intf, const return intf; } -void usbd_cdc_ecm_set_connect(bool connect, uint32_t speed[2]) +void usbd_cdc_ecm_set_connect_speed(uint32_t speed[2]) { - if (connect) { - g_current_net_status = 2; - memcpy(g_connect_speed_table, speed, 8); - usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, NULL); - } else { - g_current_net_status = 1; - usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_DISCONNECTED, NULL); - } + memcpy(g_connect_speed_table, speed, 8); } -__WEAK void usbd_cdc_ecm_data_recv_done(uint32_t len) +__WEAK void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len) { - (void)len; -} - -__WEAK void usbd_cdc_ecm_data_send_done(uint32_t len) -{ - (void)len; } diff --git a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.h b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.h index 3e0284e..8d9e5c9 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_ecm.h @@ -12,15 +12,21 @@ extern "C" { #endif +/* Ethernet Maximum Segment size, typically 1514 bytes */ +#define CONFIG_CDC_ECM_ETH_MAX_SEGSZE 1514U + /* Init cdc ecm interface driver */ struct usbd_interface *usbd_cdc_ecm_init_intf(struct usbd_interface *intf, const uint8_t int_ep, const uint8_t out_ep, const uint8_t in_ep); -void usbd_cdc_ecm_set_connect(bool connect, uint32_t speed[2]); +/* Setup request command callback api */ +void usbd_cdc_ecm_set_connect_speed(uint32_t speed[2]); -void usbd_cdc_ecm_data_recv_done(uint32_t len); -void usbd_cdc_ecm_data_send_done(uint32_t len); +/* Api for eth only without any net stack */ +uint8_t *usbd_cdc_ecm_get_tx_buffer(void); +void usbd_cdc_ecm_send_done(void); int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len); -int usbd_cdc_ecm_start_read(uint8_t *buf, uint32_t len); +void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len); +void usbd_cdc_ecm_start_read_next(void); #ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP #include "lwip/netif.h" diff --git a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c index 53666b3..c2c953a 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_acm.c @@ -12,18 +12,18 @@ #define DEV_FORMAT "/dev/ttyACM%d" -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_acm_buf[CONFIG_USBHOST_MAX_CDC_ACM_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_acm_buf[64]; static struct usbh_cdc_acm g_cdc_acm_class[CONFIG_USBHOST_MAX_CDC_ACM_CLASS]; static uint32_t g_devinuse = 0; static struct usbh_cdc_acm *usbh_cdc_acm_class_alloc(void) { - uint8_t devno; + int devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_CDC_ACM_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); + if ((g_devinuse & (1 << devno)) == 0) { + g_devinuse |= (1 << devno); memset(&g_cdc_acm_class[devno], 0, sizeof(struct usbh_cdc_acm)); g_cdc_acm_class[devno].minor = devno; return &g_cdc_acm_class[devno]; @@ -34,10 +34,10 @@ static struct usbh_cdc_acm *usbh_cdc_acm_class_alloc(void) static void usbh_cdc_acm_class_free(struct usbh_cdc_acm *cdc_acm_class) { - uint8_t devno = cdc_acm_class->minor; + int devno = cdc_acm_class->minor; - if (devno < 32) { - g_devinuse &= ~(1U << devno); + if (devno >= 0 && devno < 32) { + g_devinuse &= ~(1 << devno); } memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm)); } @@ -57,9 +57,9 @@ int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_ setup->wIndex = cdc_acm_class->intf; setup->wLength = 7; - memcpy(g_cdc_acm_buf[cdc_acm_class->minor], line_coding, sizeof(struct cdc_line_coding)); + memcpy(g_cdc_acm_buf, line_coding, sizeof(struct cdc_line_coding)); - return usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf[cdc_acm_class->minor]); + return usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf); } int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding) @@ -78,11 +78,11 @@ int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_ setup->wIndex = cdc_acm_class->intf; setup->wLength = 7; - ret = usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf[cdc_acm_class->minor]); + ret = usbh_control_transfer(cdc_acm_class->hport, setup, g_cdc_acm_buf); if (ret < 0) { return ret; } - memcpy(line_coding, g_cdc_acm_buf[cdc_acm_class->minor], sizeof(struct cdc_line_coding)); + memcpy(line_coding, g_cdc_acm_buf, sizeof(struct cdc_line_coding)); return ret; } @@ -231,26 +231,20 @@ int usbh_cdc_acm_bulk_out_transfer(struct usbh_cdc_acm *cdc_acm_class, uint8_t * static int usbh_cdc_data_connect(struct usbh_hubport *hport, uint8_t intf) { - (void)hport; - (void)intf; return 0; } static int usbh_cdc_data_disconnect(struct usbh_hubport *hport, uint8_t intf) { - (void)hport; - (void)intf; return 0; } __WEAK void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class) { - (void)cdc_acm_class; } __WEAK void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class) { - (void)cdc_acm_class; } const struct usbh_class_driver cdc_acm_class_driver = { @@ -266,19 +260,19 @@ const struct usbh_class_driver cdc_data_class_driver = { }; CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_class_info = { - .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS, - .bInterfaceClass = USB_DEVICE_CLASS_CDC, - .bInterfaceSubClass = CDC_ABSTRACT_CONTROL_MODEL, - .bInterfaceProtocol = 0x00, + .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, + .class = USB_DEVICE_CLASS_CDC, + .subclass = CDC_ABSTRACT_CONTROL_MODEL, + .protocol = CDC_COMMON_PROTOCOL_AT_COMMANDS, .id_table = NULL, .class_driver = &cdc_acm_class_driver }; CLASS_INFO_DEFINE const struct usbh_class_info cdc_data_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = USB_DEVICE_CLASS_CDC_DATA, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, + .class = USB_DEVICE_CLASS_CDC_DATA, + .subclass = 0x00, + .protocol = 0x00, .id_table = NULL, .class_driver = &cdc_data_class_driver }; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c index c4743e5..ad05d51 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ecm.c @@ -236,7 +236,6 @@ void usbh_cdc_ecm_rx_thread(void *argument) uint32_t g_cdc_ecm_rx_length; int ret; - (void)argument; USB_LOG_INFO("Create cdc ecm rx thread\r\n"); // clang-format off find_class: @@ -307,12 +306,10 @@ int usbh_cdc_ecm_eth_output(uint32_t buflen) __WEAK void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class) { - (void)cdc_ecm_class; } __WEAK void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class) { - (void)cdc_ecm_class; } const struct usbh_class_driver cdc_ecm_class_driver = { @@ -323,9 +320,9 @@ const struct usbh_class_driver cdc_ecm_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info cdc_ecm_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, - .bInterfaceClass = USB_DEVICE_CLASS_CDC, - .bInterfaceSubClass = CDC_ETHERNET_NETWORKING_CONTROL_MODEL, - .bInterfaceProtocol = CDC_COMMON_PROTOCOL_NONE, + .class = USB_DEVICE_CLASS_CDC, + .subclass = CDC_ETHERNET_NETWORKING_CONTROL_MODEL, + .protocol = CDC_COMMON_PROTOCOL_NONE, .id_table = NULL, .class_driver = &cdc_ecm_class_driver }; \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c index f9f3c53..99e8871 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/cdc/usbh_cdc_ncm.c @@ -48,7 +48,7 @@ static int usbh_cdc_ncm_get_ntb_parameters(struct usbh_cdc_ncm *cdc_ncm_class, s setup->wLength = 28; ret = usbh_control_transfer(cdc_ncm_class->hport, setup, g_cdc_ncm_buf); - if (ret < 8) { + if (ret < 0) { return ret; } @@ -259,7 +259,6 @@ void usbh_cdc_ncm_rx_thread(void *argument) uint32_t transfer_size = (16 * 1024); #endif - (void)argument; USB_LOG_INFO("Create cdc ncm rx thread\r\n"); // clang-format off find_class: @@ -331,7 +330,7 @@ find_class: #else if ((g_cdc_ncm_rx_length + (16 * 1024)) > CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE) { #endif - USB_LOG_ERR("Rx packet is overflow, please reduce tcp window size or increase CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE\r\n"); + USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE\r\n"); while (1) { } } @@ -387,12 +386,10 @@ int usbh_cdc_ncm_eth_output(uint32_t buflen) __WEAK void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class) { - (void)cdc_ncm_class; } __WEAK void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class) { - (void)cdc_ncm_class; } const struct usbh_class_driver cdc_ncm_class_driver = { @@ -403,9 +400,9 @@ const struct usbh_class_driver cdc_ncm_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info cdc_ncm_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, - .bInterfaceClass = USB_DEVICE_CLASS_CDC, - .bInterfaceSubClass = CDC_NETWORK_CONTROL_MODEL, - .bInterfaceProtocol = CDC_COMMON_PROTOCOL_NONE, + .class = USB_DEVICE_CLASS_CDC, + .subclass = CDC_NETWORK_CONTROL_MODEL, + .protocol = CDC_COMMON_PROTOCOL_NONE, .id_table = NULL, .class_driver = &cdc_ncm_class_driver }; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/hid/usb_hid.h b/rt-thread/components/drivers/usb/cherryusb/class/hid/usb_hid.h index b244d11..5a88a34 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/hid/usb_hid.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/hid/usb_hid.h @@ -558,24 +558,26 @@ struct usb_hid_kbd_report }; /* Keyboard output report (1 byte) (HID B.1), - * see HID_KBD_OUTPUT_* definitions + * see USBHID_KBDOUT_* definitions */ /* Mouse input report (HID B.2) */ struct usb_hid_mouse_report { uint8_t buttons; /* See HID_MOUSE_INPUT_BUTTON_* definitions */ - int8_t xdisp; /* X displacement */ - int8_t ydisp; /* y displacement */ + uint8_t xdisp; /* X displacement */ + uint8_t ydisp; /* y displacement */ /* Device specific additional bytes may follow */ +#ifdef CONFIG_INPUT_MOUSE_WHEEL uint8_t wdisp; /* Wheel displacement */ +#endif }; /* Joystick input report (1 bytes) (HID D.1) */ struct usb_hid_js_report { - int8_t xpos; /* X position */ - int8_t ypos; /* X position */ + uint8_t xpos; /* X position */ + uint8_t ypos; /* X position */ uint8_t buttons; /* See USBHID_JSIN_* definitions */ uint8_t throttle; /* Throttle */ }; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/hid/usbd_hid.c b/rt-thread/components/drivers/usb/cherryusb/class/hid/usbd_hid.c index fed749f..d98b82e 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/hid/usbd_hid.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/hid/usbd_hid.c @@ -50,8 +50,6 @@ static int hid_class_interface_request_handler(uint8_t busid, struct usb_setup_p struct usbd_interface *usbd_hid_init_intf(uint8_t busid, struct usbd_interface *intf, const uint8_t *desc, uint32_t desc_len) { - (void)busid; - intf->class_interface_handler = hid_class_interface_request_handler; intf->class_endpoint_handler = NULL; intf->vendor_handler = NULL; @@ -62,65 +60,30 @@ struct usbd_interface *usbd_hid_init_intf(uint8_t busid, struct usbd_interface * return intf; } -/* - * Appendix G: HID Request Support Requirements - * - * The following table enumerates the requests that need to be supported by various types of HID class devices. - * Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol - * ------------------------------------------------------------------------------------------ - * Boot Mouse Required Optional Optional Optional Required Required - * Non-Boot Mouse Required Optional Optional Optional Optional Optional - * Boot Keyboard Required Optional Required Required Required Required - * Non-Boot Keybrd Required Optional Required Required Optional Optional - * Other Device Required Optional Optional Optional Optional Optional - */ - __WEAK void usbd_hid_get_report(uint8_t busid, uint8_t intf, uint8_t report_id, uint8_t report_type, uint8_t **data, uint32_t *len) { - (void)busid; - (void)intf; - (void)report_id; - (void)report_type; (*data[0]) = 0; *len = 1; } __WEAK uint8_t usbd_hid_get_idle(uint8_t busid, uint8_t intf, uint8_t report_id) { - (void)busid; - (void)intf; - (void)report_id; return 0; } __WEAK uint8_t usbd_hid_get_protocol(uint8_t busid, uint8_t intf) { - (void)busid; - (void)intf; return 0; } __WEAK void usbd_hid_set_report(uint8_t busid, uint8_t intf, uint8_t report_id, uint8_t report_type, uint8_t *report, uint32_t report_len) { - (void)busid; - (void)intf; - (void)report_id; - (void)report_type; - (void)report; - (void)report_len; } __WEAK void usbd_hid_set_idle(uint8_t busid, uint8_t intf, uint8_t report_id, uint8_t duration) { - (void)busid; - (void)intf; - (void)report_id; - (void)duration; } __WEAK void usbd_hid_set_protocol(uint8_t busid, uint8_t intf, uint8_t protocol) { - (void)busid; - (void)intf; - (void)protocol; } \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/hid/usbh_hid.c b/rt-thread/components/drivers/usb/cherryusb/class/hid/usbh_hid.c index 0fd58ab..1761ba6 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/hid/usbh_hid.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/hid/usbh_hid.c @@ -12,26 +12,18 @@ #define DEV_FORMAT "/dev/input%d" -/* general descriptor field offsets */ -#define DESC_bLength 0 /** Length offset */ -#define DESC_bDescriptorType 1 /** Descriptor type offset */ - -/* interface descriptor field offsets */ -#define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */ -#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */ - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[CONFIG_USBHOST_MAX_HID_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[128]; static struct usbh_hid g_hid_class[CONFIG_USBHOST_MAX_HID_CLASS]; static uint32_t g_devinuse = 0; static struct usbh_hid *usbh_hid_class_alloc(void) { - uint8_t devno; + int devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_HID_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); + if ((g_devinuse & (1 << devno)) == 0) { + g_devinuse |= (1 << devno); memset(&g_hid_class[devno], 0, sizeof(struct usbh_hid)); g_hid_class[devno].minor = devno; return &g_hid_class[devno]; @@ -42,17 +34,18 @@ static struct usbh_hid *usbh_hid_class_alloc(void) static void usbh_hid_class_free(struct usbh_hid *hid_class) { - uint8_t devno = hid_class->minor; + int devno = hid_class->minor; - if (devno < 32) { - g_devinuse &= ~(1U << devno); + if (devno >= 0 && devno < 32) { + g_devinuse &= ~(1 << devno); } memset(hid_class, 0, sizeof(struct usbh_hid)); } -int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer, uint32_t buflen) +static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer) { struct usb_setup_packet *setup; + int ret; if (!hid_class || !hid_class->hport) { return -USB_ERR_INVAL; @@ -63,9 +56,14 @@ int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer, setup->bRequest = USB_REQUEST_GET_DESCRIPTOR; setup->wValue = HID_DESCRIPTOR_TYPE_HID_REPORT << 8; setup->wIndex = hid_class->intf; - setup->wLength = buflen; + setup->wLength = 128; - return usbh_control_transfer(hid_class->hport, setup, buffer); + ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf); + if (ret < 0) { + return ret; + } + memcpy(buffer, g_hid_buf, ret - 8); + return ret; } int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t duration) @@ -102,11 +100,11 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer) setup->wIndex = hid_class->intf; setup->wLength = 1; - ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]); - if (ret < 8) { + ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf); + if (ret < 0) { return ret; } - memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8); + memcpy(buffer, g_hid_buf, 1); return ret; } @@ -149,7 +147,6 @@ int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen) { struct usb_setup_packet *setup; - int ret; if (!hid_class || !hid_class->hport) { return -USB_ERR_INVAL; @@ -162,21 +159,13 @@ int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t setup->wIndex = 0; setup->wLength = buflen; - ret = usbh_control_transfer(hid_class->hport, setup, g_hid_buf[hid_class->minor]); - if (ret < 8) { - return ret; - } - memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8); - return ret; + return usbh_control_transfer(hid_class->hport, setup, buffer); } int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf) { struct usb_endpoint_descriptor *ep_desc; int ret; - uint8_t cur_iface = 0xff; - uint8_t *p; - bool found = false; struct usbh_hid *hid_class = usbh_hid_class_alloc(); if (hid_class == NULL) { @@ -189,42 +178,6 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf) hport->config.intf[intf].priv = hid_class; - p = hport->raw_config_desc; - while (p[DESC_bLength]) { - switch (p[DESC_bDescriptorType]) { - case USB_DESCRIPTOR_TYPE_INTERFACE: - cur_iface = p[INTF_DESC_bInterfaceNumber]; - if (cur_iface == intf) { - hid_class->protocol = p[7]; - struct usb_hid_descriptor *desc = (struct usb_hid_descriptor *)(p + 9); - - if (desc->bDescriptorType != HID_DESCRIPTOR_TYPE_HID) { - USB_LOG_ERR("HID descriptor not found\r\n"); - return -USB_ERR_INVAL; - } - - if (desc->subdesc[0].bDescriptorType != HID_DESCRIPTOR_TYPE_HID_REPORT) { - USB_LOG_ERR("HID report descriptor not found\r\n"); - return -USB_ERR_INVAL; - } - - hid_class->report_size = desc->subdesc[0].wDescriptorLength; - found = true; - goto found; - } - break; - default: - break; - } - /* skip to next descriptor */ - p += p[DESC_bLength]; - } - - if (found == false) { - USB_LOG_ERR("HID interface not found\r\n"); - return -USB_ERR_INVAL; - } -found: // /* 0x0 = boot protocol, 0x1 = report protocol */ // ret = usbh_hid_set_protocol(hid_class, 0x1); // if (ret < 0) { @@ -236,8 +189,7 @@ found: USB_LOG_WRN("Do not support set idle\r\n"); } - /* We read report desc but do nothing (because of too much memory usage for parsing report desc, parsed by users) */ - ret = usbh_hid_get_report_descriptor(hid_class, g_hid_buf[hid_class->minor], MIN(sizeof(g_hid_buf[hid_class->minor]), hid_class->report_size)); + ret = usbh_hid_get_report_descriptor(hid_class, hid_class->report_desc); if (ret < 0) { return ret; } @@ -287,12 +239,10 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf) __WEAK void usbh_hid_run(struct usbh_hid *hid_class) { - (void)hid_class; } __WEAK void usbh_hid_stop(struct usbh_hid *hid_class) { - (void)hid_class; } const struct usbh_class_driver hid_class_driver = { @@ -303,9 +253,9 @@ const struct usbh_class_driver hid_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info hid_custom_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = USB_DEVICE_CLASS_HID, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, + .class = USB_DEVICE_CLASS_HID, + .subclass = 0x00, + .protocol = 0x00, .id_table = NULL, .class_driver = &hid_class_driver }; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/hid/usbh_hid.h b/rt-thread/components/drivers/usb/cherryusb/class/hid/usbh_hid.h index 5e8fce6..17caaba 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/hid/usbh_hid.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/hid/usbh_hid.h @@ -15,9 +15,7 @@ struct usbh_hid { struct usbh_urb intin_urb; /* INTR IN urb */ struct usbh_urb intout_urb; /* INTR OUT urb */ - uint16_t report_size; - - uint8_t protocol; + uint8_t report_desc[256]; uint8_t intf; /* interface number */ uint8_t minor; @@ -28,7 +26,6 @@ struct usbh_hid { extern "C" { #endif -int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer, uint32_t buflen); int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t duration); int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer); int usbh_hid_set_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t report_id, uint8_t *buffer, uint32_t buflen); diff --git a/rt-thread/components/drivers/usb/cherryusb/class/hub/usb_hub.h b/rt-thread/components/drivers/usb/cherryusb/class/hub/usb_hub.h index 68e0ecf..7956b16 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/hub/usb_hub.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/hub/usb_hub.h @@ -10,12 +10,6 @@ #define HUB_DESCRIPTOR_TYPE_HUB 0x29 #define HUB_DESCRIPTOR_TYPE_HUB3 0x2A -#define HUB_MAX_DEPTH 5 - -#define HUB_SUBCLASS 0x00 -#define HUB_PROTOCOL_STT 0x01 -#define HUB_PROTOCOL_MTT 0x02 - /* Hub class requests */ #define HUB_REQUEST_GET_STATUS USB_REQUEST_GET_STATUS #define HUB_REQUEST_CLEAR_FEATURE USB_REQUEST_CLEAR_FEATURE @@ -33,31 +27,23 @@ #define HUB_FEATURE_HUB_C_OVERCURRENT (0x1) /* Port features */ -#define HUB_PORT_FEATURE_CONNECTION (0x00) -#define HUB_PORT_FEATURE_ENABLE (0x01) -#define HUB_PORT_FEATURE_SUSPEND (0x02) -#define HUB_PORT_FEATURE_OVERCURRENT (0x03) -#define HUB_PORT_FEATURE_RESET (0x04) -#define HUB_PORT_FEATURE_L1 (0x05) /* USB 2.0 only */ - -#define HUB_PORT_FEATURE_POWER (0x08) /* USB 2.0 only */ -#define HUB_PORT_FEATURE_POWER_SS (0x09) /* USB 3.0 only */ -/* This is a bit tricky because HUB_PORT_FEATURE_POWER_SS and - HUB_PORT_FEATURE_LOWSPEED share the same bit. */ -#define HUB_PORT_FEATURE_LOWSPEED (0x09) /* USB 2.0 only */ -#define HUB_PORT_FEATURE_HIGHSPEED (0x0a) /* USB 2.0 only */ -#define HUB_PORT_FEATURE_TEST (0x0b) /* USB 2.0 only */ -#define HUB_PORT_FEATURE_INDICATOR (0x0c) /* USB 2.0 only */ - -/* Port status change (wPortChange) */ +#define HUB_PORT_FEATURE_CONNECTION (0x00) +#define HUB_PORT_FEATURE_ENABLE (0x01) +#define HUB_PORT_FEATURE_SUSPEND (0x02) +#define HUB_PORT_FEATURE_OVERCURRENT (0x03) +#define HUB_PORT_FEATURE_RESET (0x04) +#define HUB_PORT_FEATURE_L1 (0x05) +#define HUB_PORT_FEATURE_POWER (0x08) +#define HUB_PORT_FEATURE_LOWSPEED (0x09) +#define HUB_PORT_FEATURE_HIGHSPEED (0x0a) #define HUB_PORT_FEATURE_C_CONNECTION (0x10) -#define HUB_PORT_FEATURE_C_ENABLE (0x11) /* USB 2.0 only */ -#define HUB_PORT_FEATURE_C_SUSPEND (0x12) /* USB 2.0 only */ +#define HUB_PORT_FEATURE_C_ENABLE (0x11) +#define HUB_PORT_FEATURE_C_SUSPEND (0x12) #define HUB_PORT_FEATURE_C_OVER_CURREN (0x13) #define HUB_PORT_FEATURE_C_RESET (0x14) -#define HUB_PORT_FEATURE_C_BH_RESET (0x15) /* USB 3.0 only */ -#define HUB_PORT_FEATURE_C_LINK_STATE (0x16) /* USB 3.0 only */ -#define HUB_PORT_FEATURE_C_CONFIG_ERR (0x17) /* USB 3.0 only */ +#define HUB_PORT_FEATURE_TEST (0x15) +#define HUB_PORT_FEATURE_INDICATOR (0x16) +#define HUB_PORT_FEATURE_C_PORTL1 (0x17) /* Hub status */ #define HUB_STATUS_LOCALPOWER (1 << 0) @@ -70,42 +56,23 @@ /* Hub port status */ #define HUB_PORT_STATUS_CONNECTION (1 << 0) #define HUB_PORT_STATUS_ENABLE (1 << 1) -#define HUB_PORT_STATUS_SUSPEND (1 << 2) /* USB 2.0 only */ +#define HUB_PORT_STATUS_SUSPEND (1 << 2) #define HUB_PORT_STATUS_OVERCURRENT (1 << 3) #define HUB_PORT_STATUS_RESET (1 << 4) -#define HUB_PORT_STATUS_L1 (1 << 5) /* USB 2.0 only */ - -/* Port Link State (PORT_LINK_STATE), USB 3.0 only */ -#define HUB_PORT_STATUS_LS_U0 (0x00 << 5) -#define HUB_PORT_STATUS_LS_U1 (0x01 << 5) -#define HUB_PORT_STATUS_LS_U2 (0x02 << 5) -#define HUB_PORT_STATUS_LS_U3 (0x03 << 5) -#define HUB_PORT_STATUS_LS_SS_DISABLED (0x04 << 5) -#define HUB_PORT_STATUS_LS_RX_DETECT (0x05 << 5) -#define HUB_PORT_STATUS_LS_SS_INACTIVE (0x06 << 5) -#define HUB_PORT_STATUS_LS_POLLING (0x07 << 5) -#define HUB_PORT_STATUS_LS_RECOVERY (0x08 << 5) -#define HUB_PORT_STATUS_LS_HOT_RESET (0x09 << 5) -#define HUB_PORT_STATUS_LS_COMP_MOD (0x0a << 5) -#define HUB_PORT_STATUS_LS_LOOPBACK (0x0b << 5) - -#define HUB_PORT_STATUS_POWER (1 << 8) -#define HUB_PORT_STATUS_POWER_SS (1 << 9) /* USB 3.0 only */ -#define HUB_PORT_STATUS_LOW_SPEED (1 << 9) /* USB 2.0 only */ -#define HUB_PORT_STATUS_HIGH_SPEED (1 << 10) /* USB 2.0 only */ -#define HUB_PORT_STATUS_TEST (1 << 11) /* USB 2.0 only */ -#define HUB_PORT_STATUS_INDICATOR (1 << 12) /* USB 2.0 only */ +#define HUB_PORT_STATUS_L1 (1 << 5) +#define HUB_PORT_STATUS_POWER (1 << 8) +#define HUB_PORT_STATUS_LOW_SPEED (1 << 9) +#define HUB_PORT_STATUS_HIGH_SPEED (1 << 10) +#define HUB_PORT_STATUS_TEST (1 << 11) +#define HUB_PORT_STATUS_INDICATOR (1 << 12) /* Hub port status change */ #define HUB_PORT_STATUS_C_CONNECTION (1 << 0) -#define HUB_PORT_STATUS_C_ENABLE (1 << 1) /* USB 2.0 only */ -#define HUB_PORT_STATUS_C_SUSPEND (1 << 2) /* USB 2.0 only */ +#define HUB_PORT_STATUS_C_ENABLE (1 << 1) +#define HUB_PORT_STATUS_C_SUSPEND (1 << 2) #define HUB_PORT_STATUS_C_OVERCURRENT (1 << 3) #define HUB_PORT_STATUS_C_RESET (1 << 4) -#define HUB_PORT_STATUS_C_L1 (1 << 5) /* USB 2.0 only */ -#define HUB_PORT_STATUS_C_BH_RESET (1 << 5) /* USB 3.0 only */ -#define HUB_PORT_STATUS_C_PORTLINK (1 << 6) /* USB 3.0 only */ -#define HUB_PORT_STATUS_C_CONFIGERR (1 << 7) /* USB 3.0 only */ +#define HUB_PORT_STATUS_C_L1 (1 << 5) /* Hub characteristics */ #define HUB_CHAR_LPSM_SHIFT (0) /* Bits 0-1: Logical Power Switching Mode */ @@ -139,21 +106,6 @@ struct usb_hub_descriptor { #define USB_SIZEOF_HUB_DESC 9 -/* Super speed Hub descriptor */ -struct usb_hub_ss_descriptor { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bNbrPorts; - uint16_t wHubCharacteristics; - uint8_t bPwrOn2PwrGood; - uint8_t bHubContrCurrent; - uint8_t bHubHdrDecLat; - uint16_t wHubDelay; - uint8_t DeviceRemovable; -} __PACKED; - -#define USB_SIZEOF_HUB_SS_DESC 11 - /* Hub status */ struct hub_status { uint16_t wPortStatus; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/hub/usbh_hub.c b/rt-thread/components/drivers/usb/cherryusb/class/hub/usbh_hub.c index 9dae396..1745d8c 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/hub/usbh_hub.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/hub/usbh_hub.c @@ -33,11 +33,11 @@ static uint32_t g_devinuse = 0; static struct usbh_hub *usbh_hub_class_alloc(void) { - uint8_t devno; + int devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_EXTHUBS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); + if ((g_devinuse & (1 << devno)) == 0) { + g_devinuse |= (1 << devno); memset(&g_hub_class[devno], 0, sizeof(struct usbh_hub)); g_hub_class[devno].index = EXTHUB_FIRST_INDEX + devno; return &g_hub_class[devno]; @@ -48,14 +48,16 @@ static struct usbh_hub *usbh_hub_class_alloc(void) static void usbh_hub_class_free(struct usbh_hub *hub_class) { - uint8_t devno = hub_class->index - EXTHUB_FIRST_INDEX; + int devno = hub_class->index - EXTHUB_FIRST_INDEX; - if (devno < 32) { - g_devinuse &= ~(1U << devno); + if (devno >= 0 && devno < 32) { + g_devinuse &= ~(1 << devno); } memset(hub_class, 0, sizeof(struct usbh_hub)); } +#endif +#if CONFIG_USBHOST_MAX_EXTHUBS > 0 static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer) { struct usb_setup_packet *setup; @@ -65,7 +67,15 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer) setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE; setup->bRequest = USB_REQUEST_GET_DESCRIPTOR; - setup->wValue = HUB_DESCRIPTOR_TYPE_HUB << 8; + + /* TODO: hub descriptor has some difference between USB 2.0 and USB 3.x, + and we havn't handle the difference here */ + if ((hub->parent->speed == USB_SPEED_SUPER) || + (hub->parent->speed == USB_SPEED_SUPER_PLUS)) { + setup->wValue = HUB_DESCRIPTOR_TYPE_HUB3 << 8; + } else { + setup->wValue = HUB_DESCRIPTOR_TYPE_HUB << 8; + } setup->wIndex = 0; setup->wLength = USB_SIZEOF_HUB_DESC; @@ -77,8 +87,8 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer) memcpy(buffer, g_hub_buf[hub->bus->busid], USB_SIZEOF_HUB_DESC); return ret; } - -static int _usbh_hub_get_hub_ss_descriptor(struct usbh_hub *hub, uint8_t *buffer) +#if 0 +static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer) { struct usb_setup_packet *setup; int ret; @@ -86,20 +96,20 @@ static int _usbh_hub_get_hub_ss_descriptor(struct usbh_hub *hub, uint8_t *buffer setup = hub->parent->setup; setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE; - setup->bRequest = USB_REQUEST_GET_DESCRIPTOR; - setup->wValue = HUB_DESCRIPTOR_TYPE_HUB3 << 8; - + setup->bRequest = HUB_REQUEST_GET_STATUS; + setup->wValue = 0; setup->wIndex = 0; - setup->wLength = USB_SIZEOF_HUB_SS_DESC; + setup->wLength = 2; ret = usbh_control_transfer(hub->parent, setup, g_hub_buf[hub->bus->busid]); if (ret < 0) { return ret; } - memcpy(buffer, g_hub_buf[hub->bus->busid], USB_SIZEOF_HUB_SS_DESC); + memcpy(buffer, g_hub_buf[hub->bus->busid], 2); return ret; } #endif +#endif static int _usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_status *port_status) { @@ -170,8 +180,6 @@ static int _usbh_hub_set_depth(struct usbh_hub *hub, uint16_t depth) #if CONFIG_USBHOST_MAX_EXTHUBS > 0 static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length) { - (void)length; - if (desc->bLength != USB_SIZEOF_HUB_DESC) { USB_LOG_ERR("invalid device bLength 0x%02x\r\n", desc->bLength); return -1; @@ -191,29 +199,6 @@ static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length } return 0; } - -static int parse_hub_ss_descriptor(struct usb_hub_ss_descriptor *desc, uint16_t length) -{ - (void)length; - - if (desc->bLength < USB_SIZEOF_HUB_SS_DESC) { - USB_LOG_ERR("invalid device bLength 0x%02x\r\n", desc->bLength); - return -1; - } else if (desc->bDescriptorType != HUB_DESCRIPTOR_TYPE_HUB3) { - USB_LOG_ERR("unexpected descriptor 0x%02x\r\n", desc->bDescriptorType); - return -2; - } else { - USB_LOG_RAW("SuperSpeed Hub Descriptor:\r\n"); - USB_LOG_RAW("bLength: 0x%02x \r\n", desc->bLength); - USB_LOG_RAW("bDescriptorType: 0x%02x \r\n", desc->bDescriptorType); - USB_LOG_RAW("bNbrPorts: 0x%02x \r\n", desc->bNbrPorts); - USB_LOG_RAW("wHubCharacteristics: 0x%04x \r\n", desc->wHubCharacteristics); - USB_LOG_RAW("bPwrOn2PwrGood: 0x%02x \r\n", desc->bPwrOn2PwrGood); - USB_LOG_RAW("bHubContrCurrent: 0x%02x \r\n", desc->bHubContrCurrent); - USB_LOG_RAW("DeviceRemovable: 0x%02x \r\n", desc->DeviceRemovable); - } - return 0; -} #endif static int usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_status *port_status) @@ -326,65 +311,22 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf) hub->hub_addr = hport->dev_addr; hub->parent = hport; hub->bus = hport->bus; - hub->speed = hport->speed; - hport->self = hub; hport->config.intf[intf].priv = hub; - if (hport->depth > HUB_MAX_DEPTH) { - USB_LOG_ERR("Hub depth(%d) is overflow\r\n", hport->depth); - return -USB_ERR_INVAL; + ret = _usbh_hub_get_hub_descriptor(hub, (uint8_t *)&hub->hub_desc); + if (ret < 0) { + return ret; } - /* - * Super-Speed hubs need to know their depth to be able to - * parse the bits of the route-string that correspond to - * their downstream port number. - * - */ - if ((hport->depth != 0) && (hport->speed == USB_SPEED_SUPER)) { - ret = usbh_hub_set_depth(hub, hport->depth - 1); - if (ret < 0) { - USB_LOG_ERR("Unable to set hub depth \r\n"); - return ret; - } - } + parse_hub_descriptor(&hub->hub_desc, USB_SIZEOF_HUB_DESC); - /* Get hub descriptor. */ - if (hport->speed == USB_SPEED_SUPER) { - ret = _usbh_hub_get_hub_ss_descriptor(hub, (uint8_t *)&hub->hub_ss_desc); - if (ret < 0) { - return ret; - } - - parse_hub_ss_descriptor(&hub->hub_ss_desc, USB_SIZEOF_HUB_SS_DESC); - hub->nports = hub->hub_ss_desc.bNbrPorts; - hub->powerdelay = hub->hub_ss_desc.bPwrOn2PwrGood * 2; - hub->tt_think = 0U; - } else { - ret = _usbh_hub_get_hub_descriptor(hub, (uint8_t *)&hub->hub_desc); - if (ret < 0) { - return ret; - } - - parse_hub_descriptor(&hub->hub_desc, USB_SIZEOF_HUB_DESC); - hub->nports = hub->hub_desc.bNbrPorts; - hub->powerdelay = hub->hub_desc.bPwrOn2PwrGood * 2; - hub->tt_think = ((hub->hub_desc.wHubCharacteristics & HUB_CHAR_TTTT_MASK) >> 5); - } - - for (uint8_t port = 0; port < hub->nports; port++) { + for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { hub->child[port].port = port + 1; hub->child[port].parent = hub; hub->child[port].bus = hport->bus; } - if (hport->device_desc.bDeviceProtocol == HUB_PROTOCOL_MTT) { - hub->ismtt = 1; - } else { - hub->ismtt = 0; - } - ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc; if (ep_desc->bEndpointAddress & 0x80) { USBH_EP_INIT(hub->intin, ep_desc); @@ -392,16 +334,28 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf) return -1; } - for (uint8_t port = 0; port < hub->nports; port++) { + if (hport->speed == USB_SPEED_SUPER) { + uint16_t depth = 0; + struct usbh_hubport *parent = hport->parent->parent; + while (parent) { + depth++; + parent = parent->parent->parent; + } + + ret = usbh_hub_set_depth(hub, depth); + if (ret < 0) { + return ret; + } + } + + for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_POWER); if (ret < 0) { return ret; } } - usb_osal_msleep(hub->powerdelay); - - for (uint8_t port = 0; port < hub->nports; port++) { + for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { ret = usbh_hub_get_portstatus(hub, port + 1, &port_status); USB_LOG_INFO("port %u, status:0x%02x, change:0x%02x\r\n", port + 1, port_status.wPortStatus, port_status.wPortChange); if (ret < 0) { @@ -441,7 +395,7 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf) usb_osal_timer_delete(hub->int_timer); } - for (uint8_t port = 0; port < hub->nports; port++) { + for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { child = &hub->child[port]; usbh_hubport_release(child); child->parent = NULL; @@ -461,7 +415,7 @@ static void usbh_hub_events(struct usbh_hub *hub) { struct usbh_hubport *child; struct hub_port_status port_status; - uint16_t portchange_index; + uint8_t portchange_index; uint16_t portstatus; uint16_t portchange; uint16_t mask; @@ -475,10 +429,11 @@ static void usbh_hub_events(struct usbh_hub *hub) } flags = usb_osal_enter_critical_section(); - memcpy(&portchange_index, hub->int_buffer, 2); + portchange_index = hub->int_buffer[0]; + hub->int_buffer[0] &= ~portchange_index; usb_osal_leave_critical_section(flags); - for (uint8_t port = 0; port < hub->nports; port++) { + for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { USB_LOG_DBG("Port change:0x%02x\r\n", portchange_index); if (!(portchange_index & (1 << (port + 1)))) { @@ -584,23 +539,12 @@ static void usbh_hub_events(struct usbh_hub *hub) } } - /* - * Figure out device speed. This is a bit tricky because - * HUB_PORT_STATUS_POWER_SS and HUB_PORT_STATUS_LOW_SPEED share the same bit. - */ - if (portstatus & HUB_PORT_STATUS_POWER) { - if (portstatus & HUB_PORT_STATUS_HIGH_SPEED) { - speed = USB_SPEED_HIGH; - } else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) { - speed = USB_SPEED_LOW; - } else { - speed = USB_SPEED_FULL; - } - } else if (portstatus & HUB_PORT_STATUS_POWER_SS) { - speed = USB_SPEED_SUPER; + if (portstatus & HUB_PORT_STATUS_HIGH_SPEED) { + speed = USB_SPEED_HIGH; + } else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) { + speed = USB_SPEED_LOW; } else { - USB_LOG_WRN("Port %u does not enable power\r\n", port + 1); - continue; + speed = USB_SPEED_FULL; } child = &hub->child[port]; @@ -609,7 +553,6 @@ static void usbh_hub_events(struct usbh_hub *hub) memset(child, 0, sizeof(struct usbh_hubport)); child->parent = hub; - child->depth = (hub->parent ? hub->parent->depth : 0) + 1; child->connected = true; child->port = port + 1; child->speed = speed; @@ -681,7 +624,7 @@ int usbh_hub_initialize(struct usbh_bus *bus) hub->is_roothub = true; hub->parent = NULL; hub->hub_addr = 1; - hub->nports = CONFIG_USBHOST_MAX_RHPORTS; + hub->hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS; hub->int_buffer = bus->hcd.roothub_intbuf; hub->bus = bus; @@ -709,7 +652,7 @@ int usbh_hub_deinitialize(struct usbh_bus *bus) flags = usb_osal_enter_critical_section(); hub = &bus->hcd.roothub; - for (uint8_t port = 0; port < hub->nports; port++) { + for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { hport = &hub->child[port]; usbh_hubport_release(hport); @@ -734,9 +677,9 @@ const struct usbh_class_driver hub_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info hub_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = USB_DEVICE_CLASS_HUB, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, + .class = USB_DEVICE_CLASS_HUB, + .subclass = 0, + .protocol = 0, .id_table = NULL, .class_driver = &hub_class_driver }; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/hub/usbh_hub.h b/rt-thread/components/drivers/usb/cherryusb/class/hub/usbh_hub.h index dcce660..1f34c53 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/hub/usbh_hub.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/hub/usbh_hub.h @@ -10,6 +10,10 @@ struct usbh_hub; +#define USBH_HUB_MAX_PORTS 4 +/* Maximum size of an interrupt IN transfer */ +#define USBH_HUB_INTIN_BUFSIZE ((USBH_HUB_MAX_PORTS + 8) >> 3) + #ifdef __cplusplus extern "C" { #endif diff --git a/rt-thread/components/drivers/usb/cherryusb/class/msc/usbd_msc.c b/rt-thread/components/drivers/usb/cherryusb/class/msc/usbd_msc.c index 1f84d02..055cdc4 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/msc/usbd_msc.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/msc/usbd_msc.c @@ -9,8 +9,6 @@ #include "usb_scsi.h" #if defined(CONFIG_USBDEV_MSC_THREAD) #include "usb_osal.h" -#elif defined(CONFIG_USBDEV_MSC_POLLING) -#include "chry_ringbuffer.h" #endif #define MSD_OUT_EP_IDX 0 @@ -52,10 +50,6 @@ USB_NOCACHE_RAM_SECTION struct usbd_msc_priv { usb_osal_mq_t usbd_msc_mq; usb_osal_thread_t usbd_msc_thread; uint32_t nbytes; -#elif defined(CONFIG_USBDEV_MSC_POLLING) - chry_ringbuffer_t msc_rb; - uint8_t msc_rb_pool[2]; - uint32_t nbytes; #endif } g_usbd_msc[CONFIG_USBDEV_MAX_BUS]; @@ -100,25 +94,21 @@ static int msc_storage_class_interface_request_handler(uint8_t busid, struct usb void msc_storage_notify_handler(uint8_t busid, uint8_t event, void *arg) { - (void)arg; - switch (event) { case USBD_EVENT_INIT: -#if defined(CONFIG_USBDEV_MSC_THREAD) +#ifdef CONFIG_USBDEV_MSC_THREAD g_usbd_msc[busid].usbd_msc_mq = usb_osal_mq_create(1); if (g_usbd_msc[busid].usbd_msc_mq == NULL) { USB_LOG_ERR("No memory to alloc for g_usbd_msc[busid].usbd_msc_mq\r\n"); } - g_usbd_msc[busid].usbd_msc_thread = usb_osal_thread_create("usbd_msc", CONFIG_USBDEV_MSC_STACKSIZE, CONFIG_USBDEV_MSC_PRIO, usbdev_msc_thread, (void *)(uint32_t)busid); + g_usbd_msc[busid].usbd_msc_thread = usb_osal_thread_create("usbd_msc", CONFIG_USBDEV_MSC_STACKSIZE, CONFIG_USBDEV_MSC_PRIO, usbdev_msc_thread, (void *)busid); if (g_usbd_msc[busid].usbd_msc_thread == NULL) { USB_LOG_ERR("No memory to alloc for g_usbd_msc[busid].usbd_msc_thread\r\n"); } -#elif defined(CONFIG_USBDEV_MSC_POLLING) - chry_ringbuffer_init(&g_usbd_msc[busid].msc_rb, g_usbd_msc[busid].msc_rb_pool, sizeof(g_usbd_msc[busid].msc_rb_pool)); #endif break; case USBD_EVENT_DEINIT: -#if defined(CONFIG_USBDEV_MSC_THREAD) +#ifdef CONFIG_USBDEV_MSC_THREAD if (g_usbd_msc[busid].usbd_msc_mq) { usb_osal_mq_delete(g_usbd_msc[busid].usbd_msc_mq); } @@ -510,9 +500,6 @@ static bool SCSI_readCapacity10(uint8_t busid, uint8_t **data, uint32_t *len) static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len) { - (void)data; - (void)len; - if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x80U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) { SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND); return false; @@ -535,12 +522,9 @@ static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len) return false; } g_usbd_msc[busid].stage = MSC_DATA_IN; -#if defined(CONFIG_USBDEV_MSC_THREAD) +#ifdef CONFIG_USBDEV_MSC_THREAD usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN); return true; -#elif defined(CONFIG_USBDEV_MSC_POLLING) - chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_IN); - return true; #else return SCSI_processRead(busid); #endif @@ -548,9 +532,6 @@ static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len) static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len) { - (void)data; - (void)len; - if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x80U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) { SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND); return false; @@ -573,12 +554,9 @@ static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len) return false; } g_usbd_msc[busid].stage = MSC_DATA_IN; -#if defined(CONFIG_USBDEV_MSC_THREAD) +#ifdef CONFIG_USBDEV_MSC_THREAD usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN); return true; -#elif defined(CONFIG_USBDEV_MSC_POLLING) - chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_IN); - return true; #else return SCSI_processRead(busid); #endif @@ -587,10 +565,6 @@ static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len) static bool SCSI_write10(uint8_t busid, uint8_t **data, uint32_t *len) { uint32_t data_len = 0; - - (void)data; - (void)len; - if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) { SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND); return false; @@ -620,10 +594,6 @@ static bool SCSI_write10(uint8_t busid, uint8_t **data, uint32_t *len) static bool SCSI_write12(uint8_t busid, uint8_t **data, uint32_t *len) { uint32_t data_len = 0; - - (void)data; - (void)len; - if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) { SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND); return false; @@ -833,8 +803,6 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes) void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) { - (void)ep; - switch (g_usbd_msc[busid].stage) { case MSC_READ_CBW: if (SCSI_CBWDecode(busid, nbytes) == false) { @@ -847,12 +815,9 @@ void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) switch (g_usbd_msc[busid].cbw.CB[0]) { case SCSI_CMD_WRITE10: case SCSI_CMD_WRITE12: -#if defined(CONFIG_USBDEV_MSC_THREAD) +#ifdef CONFIG_USBDEV_MSC_THREAD g_usbd_msc[busid].nbytes = nbytes; usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_OUT); -#elif defined(CONFIG_USBDEV_MSC_POLLING) - g_usbd_msc[busid].nbytes = nbytes; - chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_OUT); #else if (SCSI_processWrite(busid, nbytes) == false) { usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/ @@ -870,18 +835,13 @@ void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) void mass_storage_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) { - (void)ep; - (void)nbytes; - switch (g_usbd_msc[busid].stage) { case MSC_DATA_IN: switch (g_usbd_msc[busid].cbw.CB[0]) { case SCSI_CMD_READ10: case SCSI_CMD_READ12: -#if defined(CONFIG_USBDEV_MSC_THREAD) +#ifdef CONFIG_USBDEV_MSC_THREAD usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN); -#elif defined(CONFIG_USBDEV_MSC_POLLING) - chry_ringbuffer_write_byte(&g_usbd_msc[busid].msc_rb, MSC_DATA_IN); #else if (SCSI_processRead(busid) == false) { usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/ @@ -910,38 +870,19 @@ void mass_storage_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) } } -#if defined(CONFIG_USBDEV_MSC_THREAD) +#ifdef CONFIG_USBDEV_MSC_THREAD static void usbdev_msc_thread(void *argument) { uintptr_t event; int ret; - uint8_t busid = (uint8_t)(uint32_t)argument; + uint8_t busid = (uint8_t)argument; while (1) { ret = usb_osal_mq_recv(g_usbd_msc[busid].usbd_msc_mq, (uintptr_t *)&event, USB_OSAL_WAITING_FOREVER); if (ret < 0) { continue; } - USB_LOG_DBG("event:%d\r\n", event); - if (event == MSC_DATA_OUT) { - if (SCSI_processWrite(busid, g_usbd_msc[busid].nbytes) == false) { - usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/ - } - } else if (event == MSC_DATA_IN) { - if (SCSI_processRead(busid) == false) { - usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/ - } - } else { - } - } -} -#elif defined(CONFIG_USBDEV_MSC_POLLING) -void usbd_msc_polling(uint8_t busid) -{ - uint8_t event; - - if (chry_ringbuffer_read_byte(&g_usbd_msc[busid].msc_rb, &event)) { - USB_LOG_DBG("event:%d\r\n", event); + USB_LOG_DBG("%d\r\n", event); if (event == MSC_DATA_OUT) { if (SCSI_processWrite(busid, g_usbd_msc[busid].nbytes) == false) { usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/ @@ -977,9 +918,9 @@ struct usbd_interface *usbd_msc_init_intf(uint8_t busid, struct usbd_interface * for (uint8_t i = 0u; i <= g_usbd_msc[busid].max_lun; i++) { usbd_msc_get_cap(busid, i, &g_usbd_msc[busid].scsi_blk_nbr[i], &g_usbd_msc[busid].scsi_blk_size[i]); - if (CONFIG_USBDEV_MSC_MAX_BUFSIZE % g_usbd_msc[busid].scsi_blk_size[i]) { - USB_LOG_ERR("CONFIG_USBDEV_MSC_MAX_BUFSIZE must be a multiple of block size\r\n"); - while(1){} + if (g_usbd_msc[busid].scsi_blk_size[i] > CONFIG_USBDEV_MSC_MAX_BUFSIZE) { + USB_LOG_ERR("msc block buffer overflow\r\n"); + return NULL; } } @@ -991,7 +932,7 @@ void usbd_msc_set_readonly(uint8_t busid, bool readonly) g_usbd_msc[busid].readonly = readonly; } -bool usbd_msc_get_popup(uint8_t busid) +bool usbd_msc_set_popup(uint8_t busid) { return g_usbd_msc[busid].popup; } diff --git a/rt-thread/components/drivers/usb/cherryusb/class/msc/usbd_msc.h b/rt-thread/components/drivers/usb/cherryusb/class/msc/usbd_msc.h index 63a8752..c71f64a 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/msc/usbd_msc.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/msc/usbd_msc.h @@ -23,9 +23,7 @@ int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *b int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length); void usbd_msc_set_readonly(uint8_t busid, bool readonly); -bool usbd_msc_get_popup(uint8_t busid); - -void usbd_msc_polling(uint8_t busid); +bool usbd_msc_set_popup(uint8_t busid); #ifdef __cplusplus } diff --git a/rt-thread/components/drivers/usb/cherryusb/class/msc/usbh_msc.c b/rt-thread/components/drivers/usb/cherryusb/class/msc/usbh_msc.c index 96cb53d..42e12d9 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/msc/usbh_msc.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/msc/usbh_msc.c @@ -15,7 +15,7 @@ #define MSC_INQUIRY_TIMEOUT 500 -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_buf[CONFIG_USBHOST_MAX_MSC_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_buf[64]; static struct usbh_msc g_msc_class[CONFIG_USBHOST_MAX_MSC_CLASS]; static uint32_t g_devinuse = 0; @@ -23,11 +23,11 @@ static struct usbh_msc_modeswitch_config *g_msc_modeswitch_config = NULL; static struct usbh_msc *usbh_msc_class_alloc(void) { - uint8_t devno; + int devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_MSC_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); + if ((g_devinuse & (1 << devno)) == 0) { + g_devinuse |= (1 << devno); memset(&g_msc_class[devno], 0, sizeof(struct usbh_msc)); g_msc_class[devno].sdchar = 'a' + devno; return &g_msc_class[devno]; @@ -38,10 +38,10 @@ static struct usbh_msc *usbh_msc_class_alloc(void) static void usbh_msc_class_free(struct usbh_msc *msc_class) { - uint8_t devno = msc_class->sdchar - 'a'; + int devno = msc_class->sdchar - 'a'; - if (devno < 32) { - g_devinuse &= ~(1U << devno); + if (devno >= 0 && devno < 32) { + g_devinuse &= ~(1 << devno); } memset(msc_class, 0, sizeof(struct usbh_msc)); } @@ -87,8 +87,6 @@ static void usbh_msc_cbw_dump(struct CBW *cbw) static void usbh_msc_csw_dump(struct CSW *csw) { - (void)csw; - USB_LOG_DBG("CSW:\r\n"); USB_LOG_DBG(" signature: 0x%08x\r\n", (unsigned int)csw->dSignature); USB_LOG_DBG(" tag: 0x%08x\r\n", (unsigned int)csw->dTag); @@ -184,14 +182,14 @@ static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class) struct CBW *cbw; /* Construct the CBW */ - cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a']; + cbw = (struct CBW *)g_msc_buf; memset(cbw, 0, USB_SIZEOF_MSC_CBW); cbw->dSignature = MSC_CBW_Signature; cbw->bCBLength = SCSICMD_TESTUNITREADY_SIZEOF; cbw->CB[0] = SCSI_CMD_TESTUNITREADY; - return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], NULL, MSC_INQUIRY_TIMEOUT); + return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, NULL, MSC_INQUIRY_TIMEOUT); } static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class) @@ -199,7 +197,7 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class) struct CBW *cbw; /* Construct the CBW */ - cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a']; + cbw = (struct CBW *)g_msc_buf; memset(cbw, 0, USB_SIZEOF_MSC_CBW); cbw->dSignature = MSC_CBW_Signature; @@ -209,7 +207,7 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class) cbw->CB[0] = SCSI_CMD_REQUESTSENSE; cbw->CB[4] = SCSIRESP_FIXEDSENSEDATA_SIZEOF; - return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT); + return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf, MSC_INQUIRY_TIMEOUT); } static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class) @@ -217,7 +215,7 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class) struct CBW *cbw; /* Construct the CBW */ - cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a']; + cbw = (struct CBW *)g_msc_buf; memset(cbw, 0, USB_SIZEOF_MSC_CBW); cbw->dSignature = MSC_CBW_Signature; @@ -227,7 +225,7 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class) cbw->CB[0] = SCSI_CMD_INQUIRY; cbw->CB[4] = SCSIRESP_INQUIRY_SIZEOF; - return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT); + return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf, MSC_INQUIRY_TIMEOUT); } static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class) @@ -235,7 +233,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class) struct CBW *cbw; /* Construct the CBW */ - cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a']; + cbw = (struct CBW *)g_msc_buf; memset(cbw, 0, USB_SIZEOF_MSC_CBW); cbw->dSignature = MSC_CBW_Signature; @@ -244,7 +242,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class) cbw->bCBLength = SCSICMD_READCAPACITY10_SIZEOF; cbw->CB[0] = SCSI_CMD_READCAPACITY10; - return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT); + return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf, MSC_INQUIRY_TIMEOUT); } static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t *message) @@ -252,11 +250,11 @@ static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t struct CBW *cbw; /* Construct the CBW */ - cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a']; + cbw = (struct CBW *)g_msc_buf; - memcpy(g_msc_buf[msc_class->sdchar - 'a'], message, 31); + memcpy(g_msc_buf, message, 31); - usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], NULL, MSC_INQUIRY_TIMEOUT); + usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, NULL, MSC_INQUIRY_TIMEOUT); } static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf) @@ -276,17 +274,12 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf) hport->config.intf[intf].priv = msc_class; - ret = usbh_msc_get_maxlun(msc_class, g_msc_buf[msc_class->sdchar - 'a']); + ret = usbh_msc_get_maxlun(msc_class, g_msc_buf); if (ret < 0) { - if (ret == -USB_ERR_STALL) { - USB_LOG_WRN("Device does not support multiple LUNs\r\n"); - g_msc_buf[msc_class->sdchar - 'a'][0] = 0; - } else { - return ret; - } + return ret; } - USB_LOG_INFO("Get max LUN:%u\r\n", g_msc_buf[msc_class->sdchar - 'a'][0] + 1); + USB_LOG_INFO("Get max LUN:%u\r\n", g_msc_buf[0] + 1); for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; @@ -377,12 +370,13 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf) return ret; } + int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors) { struct CBW *cbw; /* Construct the CBW */ - cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a']; + cbw = (struct CBW *)g_msc_buf; memset(cbw, 0, USB_SIZEOF_MSC_CBW); cbw->dSignature = MSC_CBW_Signature; @@ -393,7 +387,7 @@ int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, con SET_BE32(&cbw->CB[2], start_sector); SET_BE16(&cbw->CB[7], nsectors); - return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT); + return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT); } int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors) @@ -401,7 +395,7 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons struct CBW *cbw; /* Construct the CBW */ - cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a']; + cbw = (struct CBW *)g_msc_buf; memset(cbw, 0, USB_SIZEOF_MSC_CBW); cbw->dSignature = MSC_CBW_Signature; @@ -413,7 +407,7 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons SET_BE32(&cbw->CB[2], start_sector); SET_BE16(&cbw->CB[7], nsectors); - return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT); + return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT); } void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config) @@ -427,12 +421,10 @@ void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config) __WEAK void usbh_msc_run(struct usbh_msc *msc_class) { - (void)msc_class; } __WEAK void usbh_msc_stop(struct usbh_msc *msc_class) { - (void)msc_class; } const struct usbh_class_driver msc_class_driver = { @@ -443,9 +435,9 @@ const struct usbh_class_driver msc_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info msc_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, - .bInterfaceClass = USB_DEVICE_CLASS_MASS_STORAGE, - .bInterfaceSubClass = MSC_SUBCLASS_SCSI, - .bInterfaceProtocol = MSC_PROTOCOL_BULK_ONLY, + .class = USB_DEVICE_CLASS_MASS_STORAGE, + .subclass = MSC_SUBCLASS_SCSI, + .protocol = MSC_PROTOCOL_BULK_ONLY, .id_table = NULL, .class_driver = &msc_class_driver }; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/template/usbh_xxx.c b/rt-thread/components/drivers/usb/cherryusb/class/template/usbh_xxx.c index 4456b3c..22b3636 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/template/usbh_xxx.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/template/usbh_xxx.c @@ -9,11 +9,11 @@ static uint32_t g_devinuse = 0; static struct usbh_xxx *usbh_xxx_class_alloc(void) { - uint8_t devno; + int devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_CUSTOM_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); + if ((g_devinuse & (1 << devno)) == 0) { + g_devinuse |= (1 << devno); memset(&g_xxx_class[devno], 0, sizeof(struct usbh_xxx)); g_xxx_class[devno].minor = devno; return &g_xxx_class[devno]; @@ -24,10 +24,10 @@ static struct usbh_xxx *usbh_xxx_class_alloc(void) static void usbh_xxx_class_free(struct usbh_xxx *xxx_class) { - uint8_t devno = xxx_class->minor; + int devno = xxx_class->minor; - if (devno < 32) { - g_devinuse &= ~(1U << devno); + if (devno >= 0 && devno < 32) { + g_devinuse &= ~(1 << devno); } memset(xxx_class, 0, sizeof(struct usbh_xxx)); } @@ -89,9 +89,9 @@ static const struct usbh_class_driver xxx_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info xxx_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, - .bInterfaceClass = 0, - .bInterfaceSubClass = 0, - .bInterfaceProtocol = 0, + .class = 0, + .subclass = 0, + .protocol = 0, .id_table = NULL, .class_driver = &xxx_class_driver }; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c b/rt-thread/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c index 66c1f07..9d3e973 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/vendor/net/usbh_asix.c @@ -70,7 +70,7 @@ static int usbh_asix_read_cmd(struct usbh_asix *asix_class, setup->wLength = size; ret = usbh_control_transfer(asix_class->hport, setup, g_asix_buf); - if (ret < 8) { + if (ret < 0) { return ret; } memcpy(data, g_asix_buf, ret - 8); @@ -98,12 +98,9 @@ static int usbh_asix_write_cmd(struct usbh_asix *asix_class, setup->wIndex = index; setup->wLength = size; - if (data && size) { - memcpy(g_asix_buf, data, size); - return usbh_control_transfer(asix_class->hport, setup, g_asix_buf); - } else { - return usbh_control_transfer(asix_class->hport, setup, NULL); - } + memcpy(g_asix_buf, data, size); + + return usbh_control_transfer(asix_class->hport, setup, g_asix_buf); } static int usbh_asix_mdio_write(struct usbh_asix *asix_class, int phy_id, int loc, int val) @@ -683,7 +680,6 @@ void usbh_asix_rx_thread(void *argument) uint32_t transfer_size = (16 * 1024); #endif - (void)argument; USB_LOG_INFO("Create asix rx thread\r\n"); // clang-format off find_class: @@ -746,7 +742,7 @@ find_class: #else if ((g_asix_rx_length + (16 * 1024)) > CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE) { #endif - USB_LOG_ERR("Rx packet is overflow, please reduce tcp window size or increase CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE\r\n"); + USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE\r\n"); while (1) { } } @@ -795,12 +791,10 @@ int usbh_asix_eth_output(uint32_t buflen) __WEAK void usbh_asix_run(struct usbh_asix *asix_class) { - (void)asix_class; } __WEAK void usbh_asix_stop(struct usbh_asix *asix_class) { - (void)asix_class; } static const uint16_t asix_id_table[][2] = { @@ -817,9 +811,9 @@ static const struct usbh_class_driver asix_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info asix_class_info = { .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, + .class = 0xff, + .subclass = 0x00, + .protocol = 0x00, .id_table = asix_id_table, .class_driver = &asix_class_driver }; \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c b/rt-thread/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c index 10fc048..dde665d 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/vendor/net/usbh_rtl8152.c @@ -961,7 +961,7 @@ static int usbh_rtl8152_read_regs(struct usbh_rtl8152 *rtl8152_class, setup->wLength = size; ret = usbh_control_transfer(rtl8152_class->hport, setup, g_rtl8152_buf); - if (ret < 8) { + if (ret < 0) { return ret; } memcpy(data, g_rtl8152_buf, ret - 8); @@ -997,10 +997,9 @@ static int generic_ocp_read(struct usbh_rtl8152 *tp, uint16_t index, uint16_t si { uint16_t limit = 64; int ret = 0; - uint8_t *buf = data; /* both size and indix must be 4 bytes align */ - if ((size & 3) || !size || (index & 3) || !buf) + if ((size & 3) || !size || (index & 3) || !data) return -USB_ERR_INVAL; if ((uint32_t)index + (uint32_t)size > 0xffff) @@ -1008,20 +1007,20 @@ static int generic_ocp_read(struct usbh_rtl8152 *tp, uint16_t index, uint16_t si while (size) { if (size > limit) { - ret = usbh_rtl8152_read_regs(tp, index, type, limit, buf); + ret = usbh_rtl8152_read_regs(tp, index, type, limit, data); if (ret < 0) break; index += limit; - buf += limit; + data += limit; size -= limit; } else { - ret = usbh_rtl8152_read_regs(tp, index, type, size, buf); + ret = usbh_rtl8152_read_regs(tp, index, type, size, data); if (ret < 0) break; index += size; - buf += size; + data += size; size = 0; break; } @@ -1036,10 +1035,9 @@ static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t b int ret; uint16_t byteen_start, byteen_end, byen; uint16_t limit = 512; - uint8_t *buf = data; /* both size and indix must be 4 bytes align */ - if ((size & 3) || !size || (index & 3) || !buf) + if ((size & 3) || !size || (index & 3) || !data) return -USB_ERR_INVAL; if ((uint32_t)index + (uint32_t)size > 0xffff) @@ -1052,12 +1050,12 @@ static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t b /* Split the first DWORD if the byte_en is not 0xff */ if (byen != BYTE_EN_DWORD) { - ret = usbh_rtl8152_write_regs(tp, index, type | byen, 4, buf); + ret = usbh_rtl8152_write_regs(tp, index, type | byen, 4, data); if (ret < 0) goto error1; index += 4; - buf += 4; + data += 4; size -= 4; } @@ -1072,22 +1070,22 @@ static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t b if (size > limit) { ret = usbh_rtl8152_write_regs(tp, index, type | BYTE_EN_DWORD, - limit, buf); + limit, data); if (ret < 0) goto error1; index += limit; - buf += limit; + data += limit; size -= limit; } else { ret = usbh_rtl8152_write_regs(tp, index, type | BYTE_EN_DWORD, - size, buf); + size, data); if (ret < 0) goto error1; index += size; - buf += size; + data += size; size = 0; break; } @@ -1095,7 +1093,7 @@ static int generic_ocp_write(struct usbh_rtl8152 *tp, uint16_t index, uint16_t b /* Set the last DWORD */ if (byen != BYTE_EN_DWORD) - ret = usbh_rtl8152_write_regs(tp, index, type | byen, 4, buf); + ret = usbh_rtl8152_write_regs(tp, index, type | byen, 4, data); } error1: @@ -2142,7 +2140,6 @@ void usbh_rtl8152_rx_thread(void *argument) uint32_t transfer_size = (16 * 1024); #endif - (void)argument; USB_LOG_INFO("Create rtl8152 rx thread\r\n"); // clang-format off find_class: @@ -2213,7 +2210,7 @@ find_class: #else if ((g_rtl8152_rx_length + (16 * 1024)) > CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE) { #endif - USB_LOG_ERR("Rx packet is overflow, please reduce tcp window size or increase CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE\r\n"); + USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE\r\n"); while (1) { } } @@ -2251,12 +2248,10 @@ int usbh_rtl8152_eth_output(uint32_t buflen) __WEAK void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class) { - (void)rtl8152_class; } __WEAK void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class) { - (void)rtl8152_class; } static const uint16_t rtl_id_table[][2] = { @@ -2272,9 +2267,9 @@ static const struct usbh_class_driver rtl8152_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info rtl8152_class_info = { .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, + .class = 0xff, + .subclass = 0x00, + .protocol = 0x00, .id_table = rtl_id_table, .class_driver = &rtl8152_class_driver }; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c b/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c index 3bee462..7c275e1 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ch34x.c @@ -17,11 +17,11 @@ static uint32_t g_devinuse = 0; static struct usbh_ch34x *usbh_ch34x_class_alloc(void) { - uint8_t devno; + int devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_CP210X_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); + if ((g_devinuse & (1 << devno)) == 0) { + g_devinuse |= (1 << devno); memset(&g_ch34x_class[devno], 0, sizeof(struct usbh_ch34x)); g_ch34x_class[devno].minor = devno; return &g_ch34x_class[devno]; @@ -32,10 +32,10 @@ static struct usbh_ch34x *usbh_ch34x_class_alloc(void) static void usbh_ch34x_class_free(struct usbh_ch34x *ch34x_class) { - uint8_t devno = ch34x_class->minor; + int devno = ch34x_class->minor; - if (devno < 32) { - g_devinuse &= ~(1U << devno); + if (devno >= 0 && devno < 32) { + g_devinuse &= ~(1 << devno); } memset(ch34x_class, 0, sizeof(struct usbh_ch34x)); } @@ -349,12 +349,10 @@ int usbh_ch34x_bulk_out_transfer(struct usbh_ch34x *ch34x_class, uint8_t *buffer __WEAK void usbh_ch34x_run(struct usbh_ch34x *ch34x_class) { - (void)ch34x_class; } __WEAK void usbh_ch34x_stop(struct usbh_ch34x *ch34x_class) { - (void)ch34x_class; } static const uint16_t ch34x_id_table[][2] = { @@ -370,9 +368,9 @@ const struct usbh_class_driver ch34x_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info ch34x_class_info = { .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, + .class = 0xff, + .subclass = 0x00, + .protocol = 0x00, .id_table = ch34x_id_table, .class_driver = &ch34x_class_driver }; \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c b/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c index 6f41b41..ae882fb 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_cp210x.c @@ -10,18 +10,18 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cp210x_buf[64]; -#define CONFIG_USBHOST_MAX_CP210X_CLASS 1 +#define CONFIG_USBHOST_MAX_CP210X_CLASS 4 static struct usbh_cp210x g_cp210x_class[CONFIG_USBHOST_MAX_CP210X_CLASS]; static uint32_t g_devinuse = 0; static struct usbh_cp210x *usbh_cp210x_class_alloc(void) { - uint8_t devno; + int devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_CP210X_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); + if ((g_devinuse & (1 << devno)) == 0) { + g_devinuse |= (1 << devno); memset(&g_cp210x_class[devno], 0, sizeof(struct usbh_cp210x)); g_cp210x_class[devno].minor = devno; return &g_cp210x_class[devno]; @@ -32,10 +32,10 @@ static struct usbh_cp210x *usbh_cp210x_class_alloc(void) static void usbh_cp210x_class_free(struct usbh_cp210x *cp210x_class) { - uint8_t devno = cp210x_class->minor; + int devno = cp210x_class->minor; - if (devno < 32) { - g_devinuse &= ~(1U << devno); + if (devno >= 0 && devno < 32) { + g_devinuse &= ~(1 << devno); } memset(cp210x_class, 0, sizeof(struct usbh_cp210x)); } @@ -298,12 +298,10 @@ int usbh_cp210x_bulk_out_transfer(struct usbh_cp210x *cp210x_class, uint8_t *buf __WEAK void usbh_cp210x_run(struct usbh_cp210x *cp210x_class) { - (void)cp210x_class; } __WEAK void usbh_cp210x_stop(struct usbh_cp210x *cp210x_class) { - (void)cp210x_class; } static const uint16_t cp210x_id_table[][2] = { @@ -319,9 +317,9 @@ const struct usbh_class_driver cp210x_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info cp210x_class_info = { .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, + .class = 0xff, + .subclass = 0x00, + .protocol = 0x00, .id_table = cp210x_id_table, .class_driver = &cp210x_class_driver }; \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c b/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c index 82defaa..ba5aae5 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_ftdi.c @@ -10,18 +10,18 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_ftdi_buf[64]; -#define CONFIG_USBHOST_MAX_FTDI_CLASS 1 +#define CONFIG_USBHOST_MAX_FTDI_CLASS 4 static struct usbh_ftdi g_ftdi_class[CONFIG_USBHOST_MAX_FTDI_CLASS]; static uint32_t g_devinuse = 0; static struct usbh_ftdi *usbh_ftdi_class_alloc(void) { - uint8_t devno; + int devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_FTDI_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); + if ((g_devinuse & (1 << devno)) == 0) { + g_devinuse |= (1 << devno); memset(&g_ftdi_class[devno], 0, sizeof(struct usbh_ftdi)); g_ftdi_class[devno].minor = devno; return &g_ftdi_class[devno]; @@ -32,10 +32,10 @@ static struct usbh_ftdi *usbh_ftdi_class_alloc(void) static void usbh_ftdi_class_free(struct usbh_ftdi *ftdi_class) { - uint8_t devno = ftdi_class->minor; + int devno = ftdi_class->minor; - if (devno < 32) { - g_devinuse &= ~(1U << devno); + if (devno >= 0 && devno < 32) { + g_devinuse &= ~(1 << devno); } memset(ftdi_class, 0, sizeof(struct usbh_ftdi)); } @@ -57,7 +57,7 @@ static void usbh_ftdi_caculate_baudrate(uint32_t *itdf_divisor, uint32_t actual_ } int divisor = FTDI_USB_CLK / baudrate; int frac_bits = 0; - for (uint8_t i = 0; i < sizeof(frac) / sizeof(frac[0]); i++) { + for (int i = 0; i < sizeof(frac) / sizeof(frac[0]); i++) { if ((divisor & 0xF) == frac[i]) { frac_bits = i; break; @@ -370,12 +370,10 @@ int usbh_ftdi_bulk_out_transfer(struct usbh_ftdi *ftdi_class, uint8_t *buffer, u __WEAK void usbh_ftdi_run(struct usbh_ftdi *ftdi_class) { - (void)ftdi_class; } __WEAK void usbh_ftdi_stop(struct usbh_ftdi *ftdi_class) { - (void)ftdi_class; } static const uint16_t ftdi_id_table[][2] = { @@ -392,9 +390,9 @@ const struct usbh_class_driver ftdi_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info ftdi_class_info = { .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, + .class = 0xff, + .subclass = 0x00, + .protocol = 0x00, .id_table = ftdi_id_table, .class_driver = &ftdi_class_driver }; \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c b/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c index 01ee700..c64a1c3 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/vendor/serial/usbh_pl2303.c @@ -15,7 +15,7 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_pl2303_buf[64]; -#define CONFIG_USBHOST_MAX_PL2303_CLASS 1 +#define CONFIG_USBHOST_MAX_PL2303_CLASS 4 #define UT_WRITE_VENDOR_DEVICE (USB_REQUEST_DIR_OUT | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE) #define UT_READ_VENDOR_DEVICE (USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE) @@ -25,11 +25,11 @@ static uint32_t g_devinuse = 0; static struct usbh_pl2303 *usbh_pl2303_class_alloc(void) { - uint8_t devno; + int devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_PL2303_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); + if ((g_devinuse & (1 << devno)) == 0) { + g_devinuse |= (1 << devno); memset(&g_pl2303_class[devno], 0, sizeof(struct usbh_pl2303)); g_pl2303_class[devno].minor = devno; return &g_pl2303_class[devno]; @@ -40,10 +40,10 @@ static struct usbh_pl2303 *usbh_pl2303_class_alloc(void) static void usbh_pl2303_class_free(struct usbh_pl2303 *pl2303_class) { - uint8_t devno = pl2303_class->minor; + int devno = pl2303_class->minor; - if (devno < 32) { - g_devinuse &= ~(1U << devno); + if (devno >= 0 && devno < 32) { + g_devinuse &= ~(1 << devno); } memset(pl2303_class, 0, sizeof(struct usbh_pl2303)); } @@ -413,12 +413,10 @@ int usbh_pl2303_bulk_out_transfer(struct usbh_pl2303 *pl2303_class, uint8_t *buf __WEAK void usbh_pl2303_run(struct usbh_pl2303 *pl2303_class) { - (void)pl2303_class; } __WEAK void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class) { - (void)pl2303_class; } static const uint16_t pl2303_id_table[][2] = { @@ -440,9 +438,9 @@ const struct usbh_class_driver pl2303_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info pl2303_class_info = { .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, + .class = 0xff, + .subclass = 0x00, + .protocol = 0x00, .id_table = pl2303_id_table, .class_driver = &pl2303_class_driver }; \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/vendor/wifi/README.md b/rt-thread/components/drivers/usb/cherryusb/class/vendor/wifi/README.md deleted file mode 100644 index 18384f6..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/class/vendor/wifi/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# BL616 USB WIFI - -Usbwifi firmware please contact bouffalolab. You can purchase a module in the following ways: - -- https://iot.mi.com/moduleBrowser.html -- https://docs.ai-thinker.com/ai_m61 \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c b/rt-thread/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c deleted file mode 100644 index 9275faa..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbh_core.h" -#include "usbh_bl616.h" - -#undef USB_DBG_TAG -#define USB_DBG_TAG "usbh_bl616" -#include "usb_log.h" - -#define DEV_FORMAT "/dev/wifi/bl616" - -#define MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X" -#define ARR_ELE_6(e) (e)[0], (e)[1], (e)[2], (e)[3], (e)[4], (e)[5] - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_bl616_tx_buffer[2048 + 512]; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_bl616_rx_buffer[2048 + 512]; - -static struct usbh_bl616 g_bl616_class; - -static const char *auth_to_str(uint8_t auth) -{ - const char *table[RNM_WIFI_AUTH_MAX] = { - [RNM_WIFI_AUTH_UNKNOWN] = "UNKNOWN", - [RNM_WIFI_AUTH_OPEN] = "OPEN", - [RNM_WIFI_AUTH_WEP] = "WEP", - [RNM_WIFI_AUTH_WPA_PSK] = "WPA-PSK", - [RNM_WIFI_AUTH_WPA2_PSK] = "WPA2-PSK", - [RNM_WIFI_AUTH_WPA_WPA2_PSK] = "WPA2-PSK/WPA-PSK", - [RNM_WIFI_AUTH_WPA_ENTERPRISE] = "WPA-ENT", - [RNM_WIFI_AUTH_WPA3_SAE] = "WPA3-SAE", - [RNM_WIFI_AUTH_WPA2_PSK_WPA3_SAE] = "WPA2-PSK/WPA3-SAE", - }; - if (auth < RNM_WIFI_AUTH_MAX) - return table[auth]; - else - return table[RNM_WIFI_AUTH_UNKNOWN]; -} - -static const char *cipher_to_str(uint8_t cipher) -{ - const char *table[RNM_WIFI_CIPHER_MAX] = { - [RNM_WIFI_CIPHER_UNKNOWN] = "UNKNOWN", - [RNM_WIFI_CIPHER_NONE] = "NONE", - [RNM_WIFI_CIPHER_WEP] = "WEP", - [RNM_WIFI_CIPHER_AES] = "AES", - [RNM_WIFI_CIPHER_TKIP] = "TKIP", - [RNM_WIFI_CIPHER_TKIP_AES] = "TKIP/AES", - }; - if (cipher < RNM_WIFI_CIPHER_MAX) - return table[cipher]; - else - return table[RNM_WIFI_CIPHER_UNKNOWN]; -} - -static int parse_get_mac_rsp_msg(struct usbh_bl616 *bl616_class, void *buf, int buf_len) -{ - usb_data_t *usb_hdr = buf; - rnm_mac_addr_ind_msg_t *rsp = buf + sizeof(usb_data_t); - - if (buf_len != sizeof(usb_data_t) + sizeof(rnm_mac_addr_ind_msg_t)) { - return -1; - } - if (usb_hdr->type != USBWIFI_DATA_TYPE_CMD || usb_hdr->length != sizeof(rnm_mac_addr_ind_msg_t)) { - return -1; - } - if (rsp->hdr.cmd != BFLB_CMD_GET_MAC_ADDR || !(rsp->hdr.flags & RNM_MSG_FLAG_ACK)) { - return -1; - } - memcpy(bl616_class->sta_mac, rsp->sta_mac, 6); - memcpy(bl616_class->ap_mac, rsp->ap_mac, 6); - - return 0; -} - -static int usbh_bl616_bulk_in_transfer(struct usbh_bl616 *bl616_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &bl616_class->bulkin_urb; - - usbh_bulk_urb_fill(urb, bl616_class->hport, bl616_class->bulkin, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -static int usbh_bl616_bulk_out_transfer(struct usbh_bl616 *bl616_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout) -{ - int ret; - struct usbh_urb *urb = &bl616_class->bulkout_urb; - - usbh_bulk_urb_fill(urb, bl616_class->hport, bl616_class->bulkout, buffer, buflen, timeout, NULL, NULL); - ret = usbh_submit_urb(urb); - if (ret == 0) { - ret = urb->actual_length; - } - return ret; -} - -static int usbh_bl616_get_wifi_mac(struct usbh_bl616 *bl616_class) -{ - int ret; - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_base_msg_t *rnm_msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(rnm_msg, 0, sizeof(rnm_base_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_base_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - rnm_msg->cmd = BFLB_CMD_GET_MAC_ADDR; - - msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t); - - ret = usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500); - if (ret < 0) { - return ret; - } - ret = usbh_bl616_bulk_in_transfer(bl616_class, g_bl616_rx_buffer, sizeof(g_bl616_rx_buffer), 500); - if (ret < 0) { - return ret; - } - - ret = parse_get_mac_rsp_msg(bl616_class, g_bl616_rx_buffer, ret); - return ret; -} - -static int usbh_bl616_wifi_open(struct usbh_bl616 *bl616_class) -{ - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(msg, 0, sizeof(rnm_base_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_base_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - msg->cmd = BFLB_CMD_HELLO; - - msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t); - - return usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500); -} - -static int usbh_bl616_wifi_close(struct usbh_bl616 *bl616_class) -{ - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(msg, 0, sizeof(rnm_base_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_base_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - msg->cmd = BFLB_CMD_UNLOAD_DRV; - - msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t); - - return usbh_bl616_bulk_out_transfer(bl616_class, g_bl616_tx_buffer, msg_len, 500); -} - -int usbh_bl616_wifi_sta_connect(const char *ssid, - const int ssid_len, - const char *password, - const int pwd_len) -{ - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_sta_connect_msg_t *msg = (rnm_sta_connect_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(msg, 0, sizeof(rnm_sta_connect_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_sta_connect_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - msg->hdr.cmd = BFLB_CMD_STA_CONNECT; - msg->hdr.msg_id = 0x0001; - msg->hdr.session_id = 0x0002; - msg->ssid_len = ssid_len; - memcpy(msg->ssid, ssid, ssid_len); - if (password) { - memcpy(msg->password, password, pwd_len); - } - - msg_len = sizeof(usb_data_t) + sizeof(rnm_sta_connect_msg_t); - - return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500); -} - -int usbh_bl616_wifi_sta_disconnect(void) -{ - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(msg, 0, sizeof(rnm_base_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_base_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - msg->cmd = BFLB_CMD_STA_DISCONNECT; - - msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t); - - return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500); -} - -int usbh_bl616_get_wifi_scan_result(void) -{ - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(msg, 0, sizeof(rnm_base_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_base_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - msg->cmd = BFLB_CMD_SCAN_RESULTS; - - msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t); - - return usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500); -} - -int usbh_bl616_wifi_scan(void) -{ - int ret; - uint32_t msg_len; - usb_data_t *usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - rnm_base_msg_t *msg = (rnm_base_msg_t *)(g_bl616_tx_buffer + sizeof(usb_data_t)); - - memset(usb_hdr, 0, sizeof(usb_data_t)); - memset(msg, 0, sizeof(rnm_base_msg_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_CMD; - usb_hdr->length = sizeof(rnm_base_msg_t); - usb_hdr->payload_offset = sizeof(usb_data_t); - - msg->cmd = BFLB_CMD_SCAN; - - msg_len = sizeof(usb_data_t) + sizeof(rnm_base_msg_t); - - ret = usbh_bl616_bulk_out_transfer(&g_bl616_class, g_bl616_tx_buffer, msg_len, 500); - if (ret < 0) { - return ret; - } - - usb_osal_msleep(500); - return usbh_bl616_get_wifi_scan_result(); -} - -static int usbh_bl616_connect(struct usbh_hubport *hport, uint8_t intf) -{ - struct usb_endpoint_descriptor *ep_desc; - int ret = 0; - - struct usbh_bl616 *bl616_class = &g_bl616_class; - - memset(bl616_class, 0, sizeof(struct usbh_bl616)); - - bl616_class->hport = hport; - bl616_class->intf = intf; - - hport->config.intf[intf].priv = bl616_class; - - for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { - ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; - - if (ep_desc->bEndpointAddress & 0x80) { - USBH_EP_INIT(bl616_class->bulkin, ep_desc); - } else { - USBH_EP_INIT(bl616_class->bulkout, ep_desc); - } - } - - usbh_bl616_get_wifi_mac(bl616_class); - usbh_bl616_wifi_close(bl616_class); - usbh_bl616_wifi_open(bl616_class); - - USB_LOG_INFO("BL616 WIFI STA MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n", - bl616_class->sta_mac[0], - bl616_class->sta_mac[1], - bl616_class->sta_mac[2], - bl616_class->sta_mac[3], - bl616_class->sta_mac[4], - bl616_class->sta_mac[5]); - - USB_LOG_INFO("BL616 WIFI AP MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n", - bl616_class->ap_mac[0], - bl616_class->ap_mac[1], - bl616_class->ap_mac[2], - bl616_class->ap_mac[3], - bl616_class->ap_mac[4], - bl616_class->ap_mac[5]); - - strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN); - - USB_LOG_INFO("Register BL616 WIFI Class:%s\r\n", hport->config.intf[intf].devname); - - usbh_bl616_run(bl616_class); - return ret; -} - -static int usbh_bl616_disconnect(struct usbh_hubport *hport, uint8_t intf) -{ - int ret = 0; - - struct usbh_bl616 *bl616_class = (struct usbh_bl616 *)hport->config.intf[intf].priv; - - if (bl616_class) { - if (bl616_class->bulkin) { - usbh_kill_urb(&bl616_class->bulkin_urb); - } - - if (bl616_class->bulkout) { - usbh_kill_urb(&bl616_class->bulkout_urb); - } - - if (hport->config.intf[intf].devname[0] != '\0') { - USB_LOG_INFO("Unregister BL616 WIFI Class:%s\r\n", hport->config.intf[intf].devname); - usbh_bl616_stop(bl616_class); - } - - memset(bl616_class, 0, sizeof(struct usbh_bl616)); - } - - return ret; -} - -void usbh_bl616_rx_thread(void *argument) -{ - int ret; - usb_data_t *usb_hdr; - rnm_base_msg_t *msg; - rnm_sta_ip_update_ind_msg_t *ipmsg; - rnm_scan_ind_msg_t *scanmsg; - uint8_t *data; - - (void)argument; - USB_LOG_INFO("Create bl616 wifi rx thread\r\n"); - - while (1) { - ret = usbh_bl616_bulk_in_transfer(&g_bl616_class, g_bl616_rx_buffer, sizeof(g_bl616_rx_buffer), USB_OSAL_WAITING_FOREVER); - if (ret < 0) { - break; - } - - usb_hdr = (usb_data_t *)g_bl616_rx_buffer; - - if (usb_hdr->type == USBWIFI_DATA_TYPE_CMD) { - msg = (rnm_base_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset); - - switch (msg->cmd) { - case BFLB_CMD_STA_CONNECTED_IND: - USB_LOG_INFO("AP connected\n"); - g_bl616_class.connect_status = true; - usbh_bl616_sta_connect_callback(); - - break; - case BFLB_CMD_STA_DISCONNECTED_IND: - if (g_bl616_class.connect_status == true) { - g_bl616_class.connect_status = false; - USB_LOG_INFO("AP disconnected\n"); - usbh_bl616_sta_disconnect_callback(); - } - break; - case BFLB_CMD_STA_IP_UPDATE_IND: - ipmsg = (rnm_sta_ip_update_ind_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset); - - USB_LOG_INFO("WIFI IP update\r\n"); - USB_LOG_INFO("WIFI IPv4 Address : %d:%d:%d:%d\r\n", - ipmsg->ip4_addr[0], - ipmsg->ip4_addr[1], - ipmsg->ip4_addr[2], - ipmsg->ip4_addr[3]); - USB_LOG_INFO("WIFI IPv4 Mask : %d:%d:%d:%d\r\n", - ipmsg->ip4_mask[0], - ipmsg->ip4_mask[1], - ipmsg->ip4_mask[2], - ipmsg->ip4_mask[3]); - USB_LOG_INFO("WIFI IPv4 Gateway : %d:%d:%d:%d\r\n\r\n", - ipmsg->ip4_gw[0], - ipmsg->ip4_gw[1], - ipmsg->ip4_gw[2], - ipmsg->ip4_gw[3]); - - g_bl616_class.mode = BL_MODE_STA; - usbh_bl616_sta_update_ip(ipmsg->ip4_addr, ipmsg->ip4_mask, ipmsg->ip4_gw); - break; - case BFLB_CMD_SCAN_RESULTS: - scanmsg = (rnm_scan_ind_msg_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset); - USB_LOG_INFO("WIFI scan result:\r\n"); - for (uint32_t i = 0; i < scanmsg->num; ++i) { - struct bf1b_wifi_scan_record *r = &scanmsg->records[i]; - USB_LOG_INFO("BSSID " MAC_FMT ", channel %u, rssi %d, auth %s, cipher %s, SSID %s\r\n", - ARR_ELE_6(r->bssid), r->channel, r->rssi, - auth_to_str(r->auth_mode), cipher_to_str(r->cipher), r->ssid); - } - break; - default: - break; - } - } else if (usb_hdr->type == USBWIFI_DATA_TYPE_PKT) { - data = (uint8_t *)(g_bl616_rx_buffer + usb_hdr->payload_offset); - usbh_bl616_eth_input(data, usb_hdr->length); - } else { - } - } - - USB_LOG_INFO("Delete bl616 wifi rx thread\r\n"); - usb_osal_thread_delete(NULL); -} - -uint8_t *usbh_bl616_get_eth_txbuf(void) -{ - return (g_bl616_tx_buffer + sizeof(usb_data_t)); -} - -int usbh_bl616_eth_output(uint32_t buflen) -{ - usb_data_t *usb_hdr; - uint32_t txlen; - - if (g_bl616_class.connect_status == false) { - return -USB_ERR_NOTCONN; - } - - usb_hdr = (usb_data_t *)g_bl616_tx_buffer; - memset(usb_hdr, 0, sizeof(usb_data_t)); - - usb_hdr->type = USBWIFI_DATA_TYPE_PKT; - usb_hdr->length = buflen; - usb_hdr->payload_offset = sizeof(usb_data_t); - - txlen = buflen + sizeof(usb_data_t); - if (!(txlen % USB_GET_MAXPACKETSIZE(g_bl616_class.bulkout->wMaxPacketSize))) { - txlen += 1; - } - USB_LOG_DBG("txlen:%d\r\n", txlen); - - usbh_bulk_urb_fill(&g_bl616_class.bulkout_urb, g_bl616_class.hport, g_bl616_class.bulkout, g_bl616_tx_buffer, txlen, USB_OSAL_WAITING_FOREVER, NULL, NULL); - return usbh_submit_urb(&g_bl616_class.bulkout_urb); -} - -int wifi_sta_connect(int argc, char **argv) -{ - if (argc < 3) { - USB_LOG_ERR("Usage: %s \r\n", argv[0]); - return -1; - } - usbh_bl616_wifi_sta_connect(argv[1], strlen(argv[1]), argv[2], strlen(argv[2])); - return 0; -} - -int wifi_scan(int argc, char **argv) -{ - (void)argc; - (void)argv; - - usbh_bl616_wifi_scan(); - return 0; -} - -__WEAK void usbh_bl616_run(struct usbh_bl616 *bl616_class) -{ - (void)bl616_class; -} - -__WEAK void usbh_bl616_stop(struct usbh_bl616 *bl616_class) -{ - (void)bl616_class; -} - -static const uint16_t bl616_id_table[][2] = { - { 0x349b, 0x616f }, - { 0, 0 }, -}; - -static const struct usbh_class_driver bl616_class_driver = { - .driver_name = "bl616_wifi", - .connect = usbh_bl616_connect, - .disconnect = usbh_bl616_disconnect -}; - -CLASS_INFO_DEFINE const struct usbh_class_info bl616_class_info = { - .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, - .id_table = bl616_id_table, - .class_driver = &bl616_class_driver -}; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h b/rt-thread/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h deleted file mode 100644 index 6ec5a7a..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/class/vendor/wifi/usbh_bl616.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USBH_BL616_H -#define USBH_BL616_H - -#define USBWIFI_DATA_TYPE_CMD 0xA55A -#define USBWIFI_DATA_TYPE_PKT 0x6996 - -#define USB_DATA_FLAG_AP_PKT (1u << 0) - -typedef enum { - BFLB_CMD_REBOOT = 0, - BFLB_CMD_RESET, - BFLB_CMD_HELLO, - BFLB_CMD_PING, - - BFLB_CMD_GET_MAC_ADDR, - - // Scan - BFLB_CMD_SCAN, - BFLB_CMD_SCAN_RESULTS, - - // STA - BFLB_CMD_STA_CONNECT, - BFLB_CMD_STA_DISCONNECT, - BFLB_CMD_STA_CONNECTED_IND, - BFLB_CMD_STA_DISCONNECTED_IND, - BFLB_CMD_STA_IP_UPDATE_IND, - BFLB_CMD_STA_SET_AUTO_RECONNECT, - BFLB_CMD_STA_GET_LINK_STATUS, - - // AP - BFLB_CMD_AP_START, - BFLB_CMD_AP_STOP, - BFLB_CMD_AP_STARTED_IND, - BFLB_CMD_AP_STOPPED_IND, - BFLB_CMD_AP_GET_STA_LIST, - - // Monitor - BFLB_CMD_MONITOR_START, - BFLB_CMD_MONITOR_STOP, - BFLB_CMD_MONITOR_SET_CHANNEL, - BFLB_CMD_MONITOR_GET_CHANNEL, - - BFLB_CMD_SET_LPM_MODE, - - // OTA - BFLB_CMD_GET_DEV_VERSION, - BFLB_CMD_OTA, - - BFLB_CMD_EXT, - - BFLB_CMD_USER_EXT, - BFLB_CMD_UNLOAD_DRV, - - BFLB_CMD_MAX, -} bflb_cmd_t; - -typedef enum { - STATUS_OK, - STATUS_NOMEM = 128, - STATUS_INVALID_INPUT, - STATUS_INVALID_MODE, - STATUS_ERR_UNSPECIFIED, - STATUS_NOT_IMPLEMENTED, -} cmd_status_t; - -typedef enum { - RNM_WIFI_AUTH_UNKNOWN = 0, - RNM_WIFI_AUTH_OPEN, - RNM_WIFI_AUTH_WEP, - RNM_WIFI_AUTH_WPA_PSK, - RNM_WIFI_AUTH_WPA2_PSK, - RNM_WIFI_AUTH_WPA_WPA2_PSK, - RNM_WIFI_AUTH_WPA_ENTERPRISE, - RNM_WIFI_AUTH_WPA3_SAE, - RNM_WIFI_AUTH_WPA2_PSK_WPA3_SAE, - RNM_WIFI_AUTH_MAX, -} rnm_wifi_auth_mode_t; - -typedef enum { - RNM_WIFI_CIPHER_UNKNOWN = 0, - RNM_WIFI_CIPHER_NONE, - RNM_WIFI_CIPHER_WEP, - RNM_WIFI_CIPHER_AES, - RNM_WIFI_CIPHER_TKIP, - RNM_WIFI_CIPHER_TKIP_AES, - RNM_WIFI_CIPHER_MAX, -} rnm_wifi_cipher_t; - -/* common header */ -typedef struct { - uint16_t cmd; - // flag ACK is used by server to indicate a response to client -#define RNM_MSG_FLAG_ACK (1 << 0) - // flag TRANSPARENT is never transfered to peer but used locally -#define RNM_MSG_FLAG_TRANSPARENT (1 << 1) - // flag ASYNC is used by server to notify client events such as STA_CONNECTED -#define RNM_MSG_FLAG_ASYNC (1 << 2) - uint16_t flags; - uint16_t status; - uint16_t msg_id; - uint16_t session_id; - uint16_t msg_id_replying; -} rnm_base_msg_t; - -typedef struct { - rnm_base_msg_t hdr; -} rnm_ack_msg_t; - -typedef struct { - rnm_base_msg_t hdr; - uint8_t sta_mac[6]; - uint8_t ap_mac[6]; -} rnm_mac_addr_ind_msg_t; - -typedef struct { - rnm_base_msg_t hdr; - uint16_t ssid_len; - uint8_t ssid[32]; - uint8_t password[64]; -} rnm_sta_connect_msg_t; - -typedef struct { - rnm_base_msg_t hdr; - uint8_t ip4_addr[4]; - uint8_t ip4_mask[4]; - uint8_t ip4_gw[4]; - uint8_t ip4_dns1[4]; - uint8_t ip4_dns2[4]; - uint8_t gw_mac[6]; -} rnm_sta_ip_update_ind_msg_t; - -struct bf1b_wifi_scan_record { - uint8_t bssid[6]; - // TODO use compressed SSID encoding to save room - uint8_t ssid[32 + 1]; - uint16_t channel; - int8_t rssi; - uint8_t auth_mode; - uint8_t cipher; -} __PACKED; - -typedef struct { - rnm_base_msg_t hdr; - uint16_t num; - struct bf1b_wifi_scan_record records[]; -} rnm_scan_ind_msg_t; - -typedef enum { - BL_MODE_NONE, - BL_MODE_STA, // card is STA - BL_MODE_AP, // card is AP - BL_MODE_STA_AP, // card is STA&AP - BL_MODE_SNIFFER, // card is sniffer - BL_MODE_MAX, -} bl_wifi_mode_t; - -typedef struct { - uint16_t type; - uint16_t length; - uint16_t flags; - uint16_t payload_offset; - uint32_t rsvd[8]; - uint8_t payload[]; -} __attribute__((aligned(4))) usb_data_t; - -struct usbh_bl616 { - struct usbh_hubport *hport; - struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ - struct usb_endpoint_descriptor *bulkout; /* Bulk OUT endpoint */ - - struct usbh_urb bulkout_urb; - struct usbh_urb bulkin_urb; - - uint8_t intf; - - uint8_t sta_mac[6]; - uint8_t ap_mac[6]; - uint8_t mode; - bool connect_status; - - void *user_data; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -int usbh_bl616_wifi_sta_connect(const char *ssid, - const int ssid_len, - const char *password, - const int pwd_len); - -int usbh_bl616_wifi_sta_disconnect(void); -int usbh_bl616_wifi_scan(void); - -void usbh_bl616_sta_connect_callback(void); -void usbh_bl616_sta_disconnect_callback(void); -void usbh_bl616_sta_update_ip(uint8_t ip4_addr[4], uint8_t ip4_mask[4], uint8_t ip4_gw[4]); - -uint8_t *usbh_bl616_get_eth_txbuf(void); -int usbh_bl616_eth_output(uint32_t buflen); -void usbh_bl616_eth_input(uint8_t *buf, uint32_t buflen); -void usbh_bl616_rx_thread(void *argument); - -void usbh_bl616_run(struct usbh_bl616 *bl616_class); -void usbh_bl616_stop(struct usbh_bl616 *bl616_class); - -int wifi_sta_connect(int argc, char **argv); -int wifi_scan(int argc, char **argv); - -#ifdef __cplusplus -} -#endif - -#endif /* USBH_BL616_H */ diff --git a/rt-thread/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c b/rt-thread/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c deleted file mode 100644 index 0c3339c..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2024 Till Harbaum - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbh_core.h" -#include "usbh_xbox.h" - -#define DEV_FORMAT "/dev/xbox%d" - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_xbox_buf[128]; - -static struct usbh_xbox g_xbox_class[CONFIG_USBHOST_MAX_XBOX_CLASS]; -static uint32_t g_devinuse = 0; - -static struct usbh_xbox *usbh_xbox_class_alloc(void) -{ - uint8_t devno; - - for (devno = 0; devno < CONFIG_USBHOST_MAX_XBOX_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); - memset(&g_xbox_class[devno], 0, sizeof(struct usbh_xbox)); - g_xbox_class[devno].minor = devno; - return &g_xbox_class[devno]; - } - } - return NULL; -} - -static void usbh_xbox_class_free(struct usbh_xbox *xbox_class) -{ - uint8_t devno = xbox_class->minor; - - if (devno < 32) { - g_devinuse &= ~(1U << devno); - } - memset(xbox_class, 0, sizeof(struct usbh_xbox)); -} - -int usbh_xbox_connect(struct usbh_hubport *hport, uint8_t intf) -{ - struct usb_endpoint_descriptor *ep_desc; - - struct usbh_xbox *xbox_class = usbh_xbox_class_alloc(); - if (xbox_class == NULL) { - USB_LOG_ERR("Fail to alloc xbox_class\r\n"); - return -USB_ERR_NOMEM; - } - - xbox_class->hport = hport; - xbox_class->intf = intf; - - hport->config.intf[intf].priv = xbox_class; - - for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) { - ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc; - if (ep_desc->bEndpointAddress & 0x80) { - USBH_EP_INIT(xbox_class->intin, ep_desc); - } else { - USBH_EP_INIT(xbox_class->intout, ep_desc); - } - } - - snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, xbox_class->minor); - - USB_LOG_INFO("Register XBOX Class:%s\r\n", hport->config.intf[intf].devname); - - usbh_xbox_run(xbox_class); - return 0; -} - -int usbh_xbox_disconnect(struct usbh_hubport *hport, uint8_t intf) -{ - int ret = 0; - - struct usbh_xbox *xbox_class = (struct usbh_xbox *)hport->config.intf[intf].priv; - - if (xbox_class) { - if (xbox_class->intin) { - usbh_kill_urb(&xbox_class->intin_urb); - } - - if (xbox_class->intout) { - usbh_kill_urb(&xbox_class->intout_urb); - } - - if (hport->config.intf[intf].devname[0] != '\0') { - USB_LOG_INFO("Unregister XBOX Class:%s\r\n", hport->config.intf[intf].devname); - usbh_xbox_stop(xbox_class); - } - - usbh_xbox_class_free(xbox_class); - } - - return ret; -} - -__WEAK void usbh_xbox_run(struct usbh_xbox *xbox_class) -{ -} - -__WEAK void usbh_xbox_stop(struct usbh_xbox *xbox_class) -{ -} - -const struct usbh_class_driver xbox_class_driver = { - .driver_name = "xbox", - .connect = usbh_xbox_connect, - .disconnect = usbh_xbox_disconnect -}; - -static const uint16_t xbox_id_table[][2] = { - { 0x0079, 0x18d4 }, // GPD Win 2 X-Box Controller - { 0x03eb, 0xff01 }, // Wooting One (Legacy) - { 0x03eb, 0xff02 }, // Wooting Two (Legacy) - { 0x044f, 0xb326 }, // Thrustmaster Gamepad GP XID - { 0x045e, 0x028e }, // Microsoft X-Box 360 pad - { 0x045e, 0x028f }, // Microsoft X-Box 360 pad v2 - { 0x046d, 0xc21d }, // Logitech Gamepad F310 - { 0x046d, 0xc21e }, // Logitech Gamepad F510 - { 0x046d, 0xc21f }, // Logitech Gamepad F710 - { 0x046d, 0xc242 }, // Logitech Chillstream Controller - { 0x046d, 0xcaa3 }, // Logitech DriveFx Racing Wheel - { 0x056e, 0x2004 }, // Elecom JC-U3613M - { 0x06a3, 0xf51a }, // Saitek P3600 - { 0x0738, 0x4716 }, // Mad Catz Wired Xbox 360 Controller - { 0x0738, 0x4718 }, // Mad Catz Street Fighter IV FightStick SE - { 0x0738, 0x4726 }, // Mad Catz Xbox 360 Controller - { 0x0738, 0x4736 }, // Mad Catz MicroCon Gamepad - { 0x0738, 0x4740 }, // Mad Catz Beat Pad - { 0x0738, 0x9871 }, // Mad Catz Portable Drum - { 0x0738, 0xb726 }, // Mad Catz Xbox controller - MW2 - { 0x0738, 0xbeef }, // Mad Catz JOYTECH NEO SE Advanced GamePad - { 0x0738, 0xcb02 }, // Saitek Cyborg Rumble Pad - PC/Xbox 360 - { 0x0738, 0xcb03 }, // Saitek P3200 Rumble Pad - PC/Xbox 360 - { 0x0738, 0xcb29 }, // Saitek Aviator Stick AV8R02 - { 0x0738, 0xf738 }, // Super SFIV FightStick TE S - { 0x07ff, 0xffff }, // Mad Catz GamePad - { 0x0e6f, 0x0113 }, // Afterglow AX.1 Gamepad for Xbox 360 - { 0x0e6f, 0x011f }, // Rock Candy Gamepad Wired Controller - { 0x0e6f, 0x0131 }, // PDP EA Sports Controller - { 0x0e6f, 0x0133 }, // Xbox 360 Wired Controller - { 0x0e6f, 0x0201 }, // Pelican PL-3601 'TSZ' Wired Xbox 360 Controller - { 0x0e6f, 0x0213 }, // Afterglow Gamepad for Xbox 360 - { 0x0e6f, 0x021f }, // Rock Candy Gamepad for Xbox 360 - { 0x0e6f, 0x0301 }, // Logic3 Controller - { 0x0e6f, 0x0401 }, // Logic3 Controller - { 0x0e6f, 0x0413 }, // Afterglow AX.1 Gamepad for Xbox 360 - { 0x0e6f, 0x0501 }, // PDP Xbox 360 Controller - { 0x0e6f, 0xf900 }, // PDP Afterglow AX.1 - { 0x0f0d, 0x000a }, // Hori Co. DOA4 FightStick - { 0x0f0d, 0x000c }, // Hori PadEX Turbo - { 0x1038, 0x1430 }, // SteelSeries Stratus Duo - { 0x1038, 0x1431 }, // SteelSeries Stratus Duo - { 0x11c9, 0x55f0 }, // Nacon GC-100XF - { 0x1209, 0x2882 }, // Ardwiino Controller - { 0x12ab, 0x0301 }, // PDP AFTERGLOW AX.1 - { 0x1430, 0x4748 }, // RedOctane Guitar Hero X-plorer - { 0x1430, 0xf801 }, // RedOctane Controller - { 0x146b, 0x0601 }, // BigBen Interactive XBOX 360 Controller - { 0x1532, 0x0037 }, // Razer Sabertooth - { 0x15e4, 0x3f00 }, // Power A Mini Pro Elite - { 0x15e4, 0x3f0a }, // Xbox Airflo wired controller - { 0x15e4, 0x3f10 }, // Batarang Xbox 360 controller - { 0x162e, 0xbeef }, // Joytech Neo-Se Take2 - { 0x1689, 0xfd00 }, // Razer Onza Tournament Edition - { 0x1689, 0xfd01 }, // Razer Onza Classic Edition - { 0x1689, 0xfe00 }, // Razer Sabertooth - { 0x1949, 0x041a }, // Amazon Game Controller - { 0x1bad, 0x0002 }, // Harmonix Rock Band Guitar - { 0x1bad, 0xf016 }, // Mad Catz Xbox 360 Controller - { 0x1bad, 0xf021 }, // Mad Cats Ghost Recon FS GamePad - { 0x1bad, 0xf023 }, // MLG Pro Circuit Controller (Xbox) - { 0x1bad, 0xf025 }, // Mad Catz Call Of Duty - { 0x1bad, 0xf027 }, // Mad Catz FPS Pro - { 0x1bad, 0xf028 }, // Street Fighter IV FightPad - { 0x1bad, 0xf030 }, // Mad Catz Xbox 360 MC2 MicroCon Racing Wheel - { 0x1bad, 0xf036 }, // Mad Catz MicroCon GamePad Pro - { 0x1bad, 0xf038 }, // Street Fighter IV FightStick TE - { 0x1bad, 0xf501 }, // HoriPad EX2 Turbo - { 0x1bad, 0xf506 }, // Hori Real Arcade Pro.EX Premium VLX - { 0x1bad, 0xf900 }, // Harmonix Xbox 360 Controller - { 0x1bad, 0xf901 }, // Gamestop Xbox 360 Controller - { 0x1bad, 0xf903 }, // Tron Xbox 360 controller - { 0x1bad, 0xf904 }, // PDP Versus Fighting Pad - { 0x1bad, 0xfa01 }, // MadCatz GamePad - { 0x1bad, 0xfd00 }, // Razer Onza TE - { 0x1bad, 0xfd01 }, // Razer Onza - { 0x20d6, 0x2001 }, // BDA Xbox Series X Wired Controller - { 0x20d6, 0x281f }, // PowerA Wired Controller For Xbox 360 - { 0x24c6, 0x5300 }, // PowerA MINI PROEX Controller - { 0x24c6, 0x5303 }, // Xbox Airflo wired controller - { 0x24c6, 0x530a }, // Xbox 360 Pro EX Controller - { 0x24c6, 0x531a }, // PowerA Pro Ex - { 0x24c6, 0x5397 }, // FUS1ON Tournament Controller - { 0x24c6, 0x5500 }, // Hori XBOX 360 EX 2 with Turbo - { 0x24c6, 0x5501 }, // Hori Real Arcade Pro VX-SA - { 0x24c6, 0x5506 }, // Hori SOULCALIBUR V Stick - { 0x24c6, 0x550d }, // Hori GEM Xbox controller - { 0x24c6, 0x5b00 }, // ThrustMaster Ferrari 458 Racing Wheel - { 0x24c6, 0x5b02 }, // Thrustmaster, Inc. GPX Controller - { 0x24c6, 0x5b03 }, // Thrustmaster Ferrari 458 Racing Wheel - { 0x24c6, 0x5d04 }, // Razer Sabertooth - { 0x24c6, 0xfafe }, // Rock Candy Gamepad for Xbox 360 - { 0x2563, 0x058d }, // OneXPlayer Gamepad - { 0x2dc8, 0x3106 }, // 8BitDo Ultimate Wireless / Pro 2 Wired Controller - { 0x2dc8, 0x3109 }, // 8BitDo Ultimate Wireless Bluetooth - { 0x31e3, 0x1100 }, // Wooting One - { 0x31e3, 0x1200 }, // Wooting Two - { 0x31e3, 0x1210 }, // Wooting Lekker - { 0x31e3, 0x1220 }, // Wooting Two HE - { 0x31e3, 0x1230 }, // Wooting Two HE (ARM) - { 0x31e3, 0x1300 }, // Wooting 60HE (AVR) - { 0x31e3, 0x1310 }, // Wooting 60HE (ARM) - { 0x3285, 0x0607 }, // Nacon GC-100 - { 0x413d, 0x2104 }, // Black Shark Green Ghost Gamepad - { 0x0000, 0x0000 } // end of list -}; - -CLASS_INFO_DEFINE const struct usbh_class_info xbox_custom_class_info = { - .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, - .bInterfaceClass = USB_DEVICE_CLASS_VEND_SPECIFIC, - .bInterfaceSubClass = 0x5d, - .bInterfaceProtocol = 0x01, - .id_table = xbox_id_table, - .class_driver = &xbox_class_driver -}; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.h b/rt-thread/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.h deleted file mode 100644 index 85d4672..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/class/vendor/xbox/usbh_xbox.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2024, Till Harbaum - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USBH_XBOX_H -#define USBH_XBOX_H - -struct usbh_xbox { - struct usbh_hubport *hport; - struct usb_endpoint_descriptor *intin; /* INTR IN endpoint */ - struct usb_endpoint_descriptor *intout; /* INTR OUT endpoint */ - struct usbh_urb intin_urb; /* INTR IN urb */ - struct usbh_urb intout_urb; /* INTR OUT urb */ - - uint8_t intf; /* interface number */ - uint8_t minor; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -void usbh_xbox_run(struct usbh_xbox *xbox_class); -void usbh_xbox_stop(struct usbh_xbox *xbox_class); - -#ifdef __cplusplus -} -#endif - -#endif /* USBH_XBOX_H */ diff --git a/rt-thread/components/drivers/usb/cherryusb/class/video/usbd_video.c b/rt-thread/components/drivers/usb/cherryusb/class/video/usbd_video.c index dae28eb..b11fa6a 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/video/usbd_video.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/video/usbd_video.c @@ -18,28 +18,12 @@ struct usbd_video_priv { uint8_t power_mode; uint8_t error_code; struct video_entity_info info[3]; - uint8_t *ep_buf0; - uint8_t *ep_buf1; - bool ep_buf0_ready; - bool ep_buf1_ready; - uint32_t ep_buf0_len; - uint32_t ep_buf1_len; - uint8_t ep_buf_idx; - bool stream_finish; - uint32_t max_packets; - uint8_t *stream_buf; - uint32_t stream_len; - uint32_t stream_offset; - uint8_t stream_frameid; - uint32_t stream_headerlen; } g_usbd_video[CONFIG_USBDEV_MAX_BUS]; static int usbd_video_control_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) { uint8_t control_selector = (uint8_t)(setup->wValue >> 8); - (void)busid; - switch (control_selector) { case VIDEO_VC_VIDEO_POWER_MODE_CONTROL: switch (setup->bRequest) { @@ -685,7 +669,7 @@ static int video_class_interface_request_handler(uint8_t busid, struct usb_setup } else { return usbd_video_control_unit_terminal_request_handler(busid, setup, data, len); /* Unit and Terminal Requests */ } - } else if (intf_num == 1) { /* Video Stream Inteface */ + } else if (intf_num == 1) { /* Video Stream Inteface */ return usbd_video_stream_request_handler(busid, setup, data, len); /* Interface Stream Requests */ } return -1; @@ -714,7 +698,7 @@ static void video_notify_handler(uint8_t busid, uint8_t event, void *arg) } } -static void usbd_video_probe_and_commit_controls_init(uint8_t busid, uint32_t dwFrameInterval, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize) +void usbd_video_probe_and_commit_controls_init(uint8_t busid, uint32_t dwFrameInterval, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize) { g_usbd_video[busid].probe.hintUnion.bmHint = 0x01; g_usbd_video[busid].probe.hintUnion1.bmHint = 0; @@ -751,47 +735,9 @@ static void usbd_video_probe_and_commit_controls_init(uint8_t busid, uint32_t dw g_usbd_video[busid].commit.bPreferedVersion = 0; g_usbd_video[busid].commit.bMinVersion = 0; g_usbd_video[busid].commit.bMaxVersion = 0; - - g_usbd_video[busid].stream_frameid = 0; - g_usbd_video[busid].stream_headerlen = 2; } -static uint32_t usbd_video_prepare_ep_buf_data(uint8_t busid, uint32_t remain, uint8_t *ep_buf) -{ - struct video_payload_header *header; - uint32_t len; - uint32_t offset; - - len = MIN(remain, (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - g_usbd_video[busid].stream_headerlen) * g_usbd_video[busid].max_packets); - offset = 0; - while (len > 0) { - header = (struct video_payload_header *)&ep_buf[offset]; - header->bHeaderLength = g_usbd_video[busid].stream_headerlen; - header->headerInfoUnion.bmheaderInfo = 0; - header->headerInfoUnion.headerInfoBits.endOfHeader = 1; - header->headerInfoUnion.headerInfoBits.endOfFrame = 0; - header->headerInfoUnion.headerInfoBits.frameIdentifier = g_usbd_video[busid].stream_frameid; - - uint32_t len2 = MIN(len, g_usbd_video[busid].probe.dwMaxPayloadTransferSize - g_usbd_video[busid].stream_headerlen); - - usb_memcpy(&ep_buf[offset + g_usbd_video[busid].stream_headerlen], - &g_usbd_video[busid].stream_buf[g_usbd_video[busid].stream_offset], - len2); - - g_usbd_video[busid].stream_offset += len2; - len -= len2; - offset += (len2 + g_usbd_video[busid].stream_headerlen); - - if (g_usbd_video[busid].stream_offset == g_usbd_video[busid].stream_len) { - header->headerInfoUnion.headerInfoBits.endOfFrame = 1; - } - } - - return offset; -} - -struct usbd_interface *usbd_video_init_intf(uint8_t busid, - struct usbd_interface *intf, +struct usbd_interface *usbd_video_init_intf(uint8_t busid, struct usbd_interface *intf, uint32_t dwFrameInterval, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize) @@ -815,70 +761,28 @@ struct usbd_interface *usbd_video_init_intf(uint8_t busid, return intf; } -bool usbd_video_stream_split_transfer(uint8_t busid, uint8_t ep) +uint32_t usbd_video_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_len, uint8_t *output, uint32_t *out_len) { - uint32_t remain; + uint32_t packets; + uint32_t last_packet_size; + uint32_t picture_pos = 0; + static uint8_t uvc_header[2] = { 0x02, 0x80 }; - if (g_usbd_video[busid].ep_buf1_ready && (g_usbd_video[busid].ep_buf_idx == 0)) { /* callback: buf1 ready and buf0 was sent */ - g_usbd_video[busid].ep_buf0_ready = false; - g_usbd_video[busid].ep_buf_idx = 1; - usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buf1, g_usbd_video[busid].ep_buf1_len); - } else if (g_usbd_video[busid].ep_buf0_ready && (g_usbd_video[busid].ep_buf_idx == 1)) { /* callback: buf0 ready and buf1 was sent */ - g_usbd_video[busid].ep_buf1_ready = false; - g_usbd_video[busid].ep_buf_idx = 0; - usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buf0, g_usbd_video[busid].ep_buf0_len); - } else { - if (g_usbd_video[busid].stream_finish) { - return true; - } - } + packets = (input_len + (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2) ) / (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2); + last_packet_size = input_len - ((packets - 1) * (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2)); - if (!g_usbd_video[busid].ep_buf0_ready) { - remain = g_usbd_video[busid].stream_len - g_usbd_video[busid].stream_offset; - if (remain == 0) { - g_usbd_video[busid].stream_frameid ^= 1; - g_usbd_video[busid].stream_finish = true; + for (size_t i = 0; i < packets; i++) { + output[g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i] = uvc_header[0]; + output[g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i + 1] = uvc_header[1]; + if (i == (packets - 1)) { + memcpy(&output[2 + g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i], &input[picture_pos], last_packet_size); + output[g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i + 1] |= (1 << 1); } else { - g_usbd_video[busid].ep_buf0_len = usbd_video_prepare_ep_buf_data(busid, remain, g_usbd_video[busid].ep_buf0); - g_usbd_video[busid].ep_buf0_ready = true; - if (!g_usbd_video[busid].ep_buf1_ready) { - g_usbd_video[busid].ep_buf_idx = 0; - usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buf0, g_usbd_video[busid].ep_buf0_len); - } + memcpy(&output[2 + g_usbd_video[busid].probe.dwMaxPayloadTransferSize * i], &input[picture_pos], g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2); + picture_pos += g_usbd_video[busid].probe.dwMaxPayloadTransferSize - 2; } } - - if (!g_usbd_video[busid].ep_buf1_ready) { - remain = g_usbd_video[busid].stream_len - g_usbd_video[busid].stream_offset; - if (remain == 0) { - g_usbd_video[busid].stream_frameid ^= 1; - g_usbd_video[busid].stream_finish = true; - } else { - g_usbd_video[busid].ep_buf1_len = usbd_video_prepare_ep_buf_data(busid, remain, g_usbd_video[busid].ep_buf1); - g_usbd_video[busid].ep_buf1_ready = true; - } - } - - return false; -} - -int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buf0, uint8_t *ep_buf1, uint32_t ep_bufsize, uint8_t *stream_buf, uint32_t stream_len) -{ - if ((usb_device_is_configured(busid) == 0) || (stream_len == 0)) { - return -1; - } - - g_usbd_video[busid].ep_buf0 = ep_buf0; - g_usbd_video[busid].ep_buf1 = ep_buf1; - g_usbd_video[busid].ep_buf0_ready = false; - g_usbd_video[busid].ep_buf1_ready = false; - g_usbd_video[busid].ep_buf_idx = 0; - g_usbd_video[busid].stream_finish = false; - g_usbd_video[busid].max_packets = ep_bufsize / g_usbd_video[busid].probe.dwMaxPayloadTransferSize; - g_usbd_video[busid].stream_buf = stream_buf; - g_usbd_video[busid].stream_len = stream_len; - g_usbd_video[busid].stream_offset = 0; - - usbd_video_stream_split_transfer(busid, ep); - return 0; -} + uvc_header[1] ^= 1; + *out_len = (input_len + 2 * packets); + return packets; +} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/video/usbd_video.h b/rt-thread/components/drivers/usb/cherryusb/class/video/usbd_video.h index a2a98bb..14636fb 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/video/usbd_video.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/video/usbd_video.h @@ -20,9 +20,7 @@ struct usbd_interface *usbd_video_init_intf(uint8_t busid, struct usbd_interface void usbd_video_open(uint8_t busid, uint8_t intf); void usbd_video_close(uint8_t busid, uint8_t intf); - -bool usbd_video_stream_split_transfer(uint8_t busid, uint8_t ep); -int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buf0, uint8_t *ep_buf1, uint32_t ep_bufsize, uint8_t *stream_buf, uint32_t stream_len); +uint32_t usbd_video_payload_fill(uint8_t busid, uint8_t *input, uint32_t input_len, uint8_t *output, uint32_t *out_len); #ifdef __cplusplus } diff --git a/rt-thread/components/drivers/usb/cherryusb/class/video/usbh_video.c b/rt-thread/components/drivers/usb/cherryusb/class/video/usbh_video.c index 7379151..0d3f79f 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/video/usbh_video.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/video/usbh_video.c @@ -34,11 +34,11 @@ static uint32_t g_devinuse = 0; static struct usbh_video *usbh_video_class_alloc(void) { - uint8_t devno; + int devno; for (devno = 0; devno < CONFIG_USBHOST_MAX_VIDEO_CLASS; devno++) { - if ((g_devinuse & (1U << devno)) == 0) { - g_devinuse |= (1U << devno); + if ((g_devinuse & (1 << devno)) == 0) { + g_devinuse |= (1 << devno); memset(&g_video_class[devno], 0, sizeof(struct usbh_video)); g_video_class[devno].minor = devno; return &g_video_class[devno]; @@ -49,10 +49,10 @@ static struct usbh_video *usbh_video_class_alloc(void) static void usbh_video_class_free(struct usbh_video *video_class) { - uint8_t devno = video_class->minor; + int devno = video_class->minor; - if (devno < 32) { - g_devinuse &= ~(1U << devno); + if (devno >= 0 && devno < 32) { + g_devinuse &= ~(1 << devno); } memset(video_class, 0, sizeof(struct usbh_video)); } @@ -495,26 +495,20 @@ static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf) static int usbh_video_streaming_connect(struct usbh_hubport *hport, uint8_t intf) { - (void)hport; - (void)intf; return 0; } static int usbh_video_streaming_disconnect(struct usbh_hubport *hport, uint8_t intf) { - (void)hport; - (void)intf; return 0; } __WEAK void usbh_video_run(struct usbh_video *video_class) { - (void)video_class; } __WEAK void usbh_video_stop(struct usbh_video *video_class) { - (void)video_class; } const struct usbh_class_driver video_ctrl_class_driver = { @@ -531,18 +525,18 @@ const struct usbh_class_driver video_streaming_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info video_ctrl_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, - .bInterfaceClass = USB_DEVICE_CLASS_VIDEO, - .bInterfaceSubClass = VIDEO_SC_VIDEOCONTROL, - .bInterfaceProtocol = VIDEO_PC_PROTOCOL_UNDEFINED, + .class = USB_DEVICE_CLASS_VIDEO, + .subclass = VIDEO_SC_VIDEOCONTROL, + .protocol = VIDEO_PC_PROTOCOL_UNDEFINED, .id_table = NULL, .class_driver = &video_ctrl_class_driver }; CLASS_INFO_DEFINE const struct usbh_class_info video_streaming_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, - .bInterfaceClass = USB_DEVICE_CLASS_VIDEO, - .bInterfaceSubClass = VIDEO_SC_VIDEOSTREAMING, - .bInterfaceProtocol = VIDEO_PC_PROTOCOL_UNDEFINED, + .class = USB_DEVICE_CLASS_VIDEO, + .subclass = VIDEO_SC_VIDEOSTREAMING, + .protocol = VIDEO_PC_PROTOCOL_UNDEFINED, .id_table = NULL, .class_driver = &video_streaming_class_driver }; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c b/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c index 4384970..c357b25 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.c @@ -102,8 +102,6 @@ static void rndis_notify_rsp(void) static int rndis_class_interface_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len) { - (void)busid; - switch (setup->bRequest) { case CDC_REQUEST_SEND_ENCAPSULATED_COMMAND: rndis_encapsulated_cmd_handler(*data, setup->wLength); @@ -154,8 +152,6 @@ static int rndis_init_cmd_handler(uint8_t *data, uint32_t len) rndis_initialize_msg_t *cmd = (rndis_initialize_msg_t *)data; rndis_initialize_cmplt_t *resp; - (void)len; - resp = ((rndis_initialize_cmplt_t *)rndis_encapsulated_resp_buffer); resp->RequestId = cmd->RequestId; resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT; @@ -181,9 +177,6 @@ static int rndis_halt_cmd_handler(uint8_t *data, uint32_t len) { rndis_halt_msg_t *resp; - (void)data; - (void)len; - resp = ((rndis_halt_msg_t *)rndis_encapsulated_resp_buffer); resp->MessageLength = 0; @@ -199,8 +192,6 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len) uint8_t *infomation_buffer; uint32_t infomation_len = 0; - (void)len; - resp = ((rndis_query_cmplt_t *)rndis_encapsulated_resp_buffer); resp->MessageType = REMOTE_NDIS_QUERY_CMPLT; resp->RequestId = cmd->RequestId; @@ -347,8 +338,6 @@ static int rndis_set_cmd_handler(uint8_t *data, uint32_t len) rndis_set_cmplt_t *resp; rndis_config_parameter_t *param; - (void)len; - resp = ((rndis_set_cmplt_t *)rndis_encapsulated_resp_buffer); resp->RequestId = cmd->RequestId; resp->MessageType = REMOTE_NDIS_SET_CMPLT; @@ -405,9 +394,6 @@ static int rndis_reset_cmd_handler(uint8_t *data, uint32_t len) // rndis_reset_msg_t *cmd = (rndis_reset_msg_t *)data; rndis_reset_cmplt_t *resp; - (void)data; - (void)len; - resp = ((rndis_reset_cmplt_t *)rndis_encapsulated_resp_buffer); resp->MessageType = REMOTE_NDIS_RESET_CMPLT; resp->MessageLength = sizeof(rndis_reset_cmplt_t); @@ -426,8 +412,6 @@ static int rndis_keepalive_cmd_handler(uint8_t *data, uint32_t len) rndis_keepalive_msg_t *cmd = (rndis_keepalive_msg_t *)data; rndis_keepalive_cmplt_t *resp; - (void)len; - resp = ((rndis_keepalive_cmplt_t *)rndis_encapsulated_resp_buffer); resp->RequestId = cmd->RequestId; resp->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT; @@ -441,9 +425,6 @@ static int rndis_keepalive_cmd_handler(uint8_t *data, uint32_t len) static void rndis_notify_handler(uint8_t busid, uint8_t event, void *arg) { - (void)busid; - (void)arg; - switch (event) { case USBD_EVENT_RESET: g_usbd_rndis.link_status = NDIS_MEDIA_STATE_DISCONNECTED; @@ -464,9 +445,6 @@ void rndis_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) { rndis_data_packet_t *hdr; - (void)busid; - (void)ep; - hdr = (rndis_data_packet_t *)g_rndis_rx_buffer; g_rndis_rx_data_buffer = g_rndis_rx_buffer; if ((hdr->MessageType != REMOTE_NDIS_PACKET_MSG) || (nbytes < hdr->MessageLength)) { @@ -478,28 +456,21 @@ void rndis_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) g_rndis_rx_data_buffer += hdr->DataOffset + sizeof(rndis_generic_msg_t); g_rndis_rx_data_length = hdr->DataLength; - usbd_rndis_data_recv_done(g_rndis_rx_data_length); + usbd_rndis_data_recv_done(); } void rndis_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) { - (void)busid; - - if ((nbytes % usbd_get_ep_mps(0, ep)) == 0 && nbytes) { + if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) { /* send zlp */ usbd_ep_start_write(0, ep, NULL, 0); } else { - usbd_rndis_data_send_done(g_rndis_tx_data_length); g_rndis_tx_data_length = 0; } } void rndis_int_in(uint8_t busid, uint8_t ep, uint32_t nbytes) { - (void)busid; - (void)ep; - (void)nbytes; - //USB_LOG_DBG("len:%d\r\n", nbytes); } @@ -593,13 +564,3 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf, return intf; } - -__WEAK void usbd_rndis_data_recv_done(uint32_t len) -{ - (void)len; -} - -__WEAK void usbd_rndis_data_send_done(uint32_t len) -{ - (void)len; -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.h b/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.h index 72b89ea..8a9581f 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.h +++ b/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbd_rndis.h @@ -18,8 +18,7 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf, const uint8_t in_ep, const uint8_t int_ep, uint8_t mac[6]); -void usbd_rndis_data_recv_done(uint32_t len); -void usbd_rndis_data_send_done(uint32_t len); +void usbd_rndis_data_recv_done(void); #ifdef CONFIG_USBDEV_RNDIS_USING_LWIP struct pbuf *usbd_rndis_eth_rx(void); diff --git a/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c b/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c index 991f095..e73eeb0 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbh_bluetooth.c @@ -365,18 +365,14 @@ delete : __WEAK void usbh_bluetooth_hci_read_callback(uint8_t *data, uint32_t len) { - (void)data; - (void)len; } __WEAK void usbh_bluetooth_run(struct usbh_bluetooth *bluetooth_class) { - (void)bluetooth_class; } __WEAK void usbh_bluetooth_stop(struct usbh_bluetooth *bluetooth_class) { - (void)bluetooth_class; } static const struct usbh_class_driver bluetooth_class_driver = { @@ -393,18 +389,18 @@ static const uint16_t bluetooth_id_table[][2] = { CLASS_INFO_DEFINE const struct usbh_class_info bluetooth_h4_nrf_class_info = { .match_flags = USB_CLASS_MATCH_VID_PID | USB_CLASS_MATCH_INTF_CLASS, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0x00, - .bInterfaceProtocol = 0x00, + .class = 0xff, + .subclass = 0x00, + .protocol = 0x00, .id_table = bluetooth_id_table, .class_driver = &bluetooth_class_driver }; #else CLASS_INFO_DEFINE const struct usbh_class_info bluetooth_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, - .bInterfaceClass = USB_DEVICE_CLASS_WIRELESS, - .bInterfaceSubClass = 0x01, - .bInterfaceProtocol = 0x01, + .class = USB_DEVICE_CLASS_WIRELESS, + .subclass = 0x01, + .protocol = 0x01, .id_table = NULL, .class_driver = &bluetooth_class_driver }; diff --git a/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c b/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c index e9eaff0..e722e50 100644 --- a/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c +++ b/rt-thread/components/drivers/usb/cherryusb/class/wireless/usbh_rndis.c @@ -13,7 +13,7 @@ #define DEV_FORMAT "/dev/rndis" -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_buf[512]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_buf[4096]; #define CONFIG_USBHOST_RNDIS_ETH_MAX_FRAME_SIZE 1514 #define CONFIG_USBHOST_RNDIS_ETH_MSG_SIZE (CONFIG_USBHOST_RNDIS_ETH_MAX_FRAME_SIZE + 44) @@ -26,7 +26,6 @@ static struct usbh_rndis g_rndis_class; static int usbh_rndis_get_notification(struct usbh_rndis *rndis_class) { - (void)rndis_class; // int ret; // struct usbh_urb *urb = &rndis_class->intin_urb; @@ -80,7 +79,7 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class) setup->bRequest = CDC_REQUEST_GET_ENCAPSULATED_RESPONSE; setup->wValue = 0; setup->wIndex = 0; - setup->wLength = sizeof(g_rndis_buf); + setup->wLength = 4096; ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp); if (ret < 0) { @@ -138,7 +137,7 @@ int usbh_rndis_query_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid, setup->bRequest = CDC_REQUEST_GET_ENCAPSULATED_RESPONSE; setup->wValue = 0; setup->wIndex = 0; - setup->wLength = sizeof(g_rndis_buf); + setup->wLength = 4096; ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp); if (ret < 0) { @@ -195,7 +194,7 @@ static int usbh_rndis_set_msg_transfer(struct usbh_rndis *rndis_class, uint32_t setup->bRequest = CDC_REQUEST_GET_ENCAPSULATED_RESPONSE; setup->wValue = 0; setup->wIndex = 0; - setup->wLength = sizeof(g_rndis_buf); + setup->wLength = 4096; ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp); if (ret < 0) { @@ -262,7 +261,7 @@ int usbh_rndis_keepalive(struct usbh_rndis *rndis_class) setup->bRequest = CDC_REQUEST_GET_ENCAPSULATED_RESPONSE; setup->wValue = 0; setup->wIndex = 0; - setup->wLength = sizeof(g_rndis_buf); + setup->wLength = 4096; ret = usbh_control_transfer(rndis_class->hport, setup, (uint8_t *)resp); if (ret < 0) { @@ -387,14 +386,14 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf) } uint32_t packet_filter = 0x0f; - ret = usbh_rndis_set_msg_transfer(rndis_class, OID_GEN_CURRENT_PACKET_FILTER, (uint8_t *)&packet_filter, 4); + usbh_rndis_set_msg_transfer(rndis_class, OID_GEN_CURRENT_PACKET_FILTER, (uint8_t *)&packet_filter, 4); if (ret < 0) { return ret; } USB_LOG_INFO("rndis set OID_GEN_CURRENT_PACKET_FILTER success\r\n"); uint8_t multicast_list[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x01 }; - ret = usbh_rndis_set_msg_transfer(rndis_class, OID_802_3_MULTICAST_LIST, multicast_list, 6); + usbh_rndis_set_msg_transfer(rndis_class, OID_802_3_MULTICAST_LIST, multicast_list, 6); if (ret < 0) { return ret; } @@ -461,8 +460,6 @@ void usbh_rndis_rx_thread(void *argument) uint32_t transfer_size = (16 * 1024); #endif - (void)argument; - USB_LOG_INFO("Create rndis rx thread\r\n"); // clang-format off find_class: @@ -534,7 +531,7 @@ find_class: #else if ((g_rndis_rx_length + (16 * 1024)) > CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE) { #endif - USB_LOG_ERR("Rx packet is overflow, please reduce tcp window size or increase CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE\r\n"); + USB_LOG_ERR("Rx packet is overflow, please ruduce tcp window size or increase CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE\r\n"); while (1) { } } @@ -584,12 +581,10 @@ int usbh_rndis_eth_output(uint32_t buflen) __WEAK void usbh_rndis_run(struct usbh_rndis *rndis_class) { - (void)rndis_class; } __WEAK void usbh_rndis_stop(struct usbh_rndis *rndis_class) { - (void)rndis_class; } static const struct usbh_class_driver rndis_class_driver = { @@ -600,9 +595,9 @@ static const struct usbh_class_driver rndis_class_driver = { CLASS_INFO_DEFINE const struct usbh_class_info rndis_class_info = { .match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL, - .bInterfaceClass = USB_DEVICE_CLASS_WIRELESS, - .bInterfaceSubClass = 0x01, - .bInterfaceProtocol = 0x03, + .class = USB_DEVICE_CLASS_WIRELESS, + .subclass = 0x01, + .protocol = 0x03, .id_table = NULL, .class_driver = &rndis_class_driver }; diff --git a/rt-thread/components/drivers/usb/cherryusb/common/usb_dc.h b/rt-thread/components/drivers/usb/cherryusb/common/usb_dc.h index 1f2fddd..a10869a 100644 --- a/rt-thread/components/drivers/usb/cherryusb/common/usb_dc.h +++ b/rt-thread/components/drivers/usb/cherryusb/common/usb_dc.h @@ -33,13 +33,6 @@ int usb_dc_deinit(uint8_t busid); */ int usbd_set_address(uint8_t busid, const uint8_t addr); -/** - * @brief Set remote wakeup feature - * - * @return On success will return 0, and others indicate fail. - */ -int usbd_set_remote_wakeup(uint8_t busid); - /** * @brief Get USB device speed * diff --git a/rt-thread/components/drivers/usb/cherryusb/common/usb_def.h b/rt-thread/components/drivers/usb/cherryusb/common/usb_def.h index 27b4d82..aea3d6a 100644 --- a/rt-thread/components/drivers/usb/cherryusb/common/usb_def.h +++ b/rt-thread/components/drivers/usb/cherryusb/common/usb_def.h @@ -614,7 +614,7 @@ struct usb_webusb_url_descriptor { char URL[]; } __PACKED; -struct usb_webusb_descriptor { +struct usb_webusb_url_ex_descriptor { uint8_t vendor_code; const uint8_t *string; uint32_t string_len; diff --git a/rt-thread/components/drivers/usb/cherryusb/common/usb_log.h b/rt-thread/components/drivers/usb/cherryusb/common/usb_log.h index 8c798c7..923e800 100644 --- a/rt-thread/components/drivers/usb/cherryusb/common/usb_log.h +++ b/rt-thread/components/drivers/usb/cherryusb/common/usb_log.h @@ -82,33 +82,4 @@ void usb_assert(const char *filename, int linenum); usb_assert(__FILE__, __LINE__); \ } while (0) -#define ___is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ') -static inline void usb_hexdump(const void *ptr, uint32_t buflen) -{ - unsigned char *buf = (unsigned char *)ptr; - uint32_t i, j; - - (void)buf; - - for (i = 0; i < buflen; i += 16) { - CONFIG_USB_PRINTF("%08X:", i); - - for (j = 0; j < 16; j++) - if (i + j < buflen) { - if ((j % 8) == 0) { - CONFIG_USB_PRINTF(" "); - } - - CONFIG_USB_PRINTF("%02X ", buf[i + j]); - } else - CONFIG_USB_PRINTF(" "); - CONFIG_USB_PRINTF(" "); - - for (j = 0; j < 16; j++) - if (i + j < buflen) - CONFIG_USB_PRINTF("%c", ___is_print(buf[i + j]) ? buf[i + j] : '.'); - CONFIG_USB_PRINTF("\n"); - } -} - #endif /* USB_LOG_H */ diff --git a/rt-thread/components/drivers/usb/cherryusb/common/usb_osal.h b/rt-thread/components/drivers/usb/cherryusb/common/usb_osal.h index a3380d1..f487c48 100644 --- a/rt-thread/components/drivers/usb/cherryusb/common/usb_osal.h +++ b/rt-thread/components/drivers/usb/cherryusb/common/usb_osal.h @@ -58,7 +58,4 @@ void usb_osal_leave_critical_section(size_t flag); void usb_osal_msleep(uint32_t delay); -void *usb_osal_malloc(size_t size); -void usb_osal_free(void *ptr); - #endif /* USB_OSAL_H */ diff --git a/rt-thread/components/drivers/usb/cherryusb/common/usb_version.h b/rt-thread/components/drivers/usb/cherryusb/common/usb_version.h deleted file mode 100644 index d207af9..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/common/usb_version.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef USB_VERSION_H -#define USB_VERSION_H - -#ifdef CHERRYUSB_VERSION -#warning "Please do not define CHERRYUSB_VERSION in usb_config.h" -#undef CHERRYUSB_VERSION -#endif -#ifdef CHERRYUSB_VERSION_STR -#warning "Please do not define CHERRYUSB_VERSION_STR in usb_config.h" -#undef CHERRYUSB_VERSION_STR -#endif - -#define CHERRYUSB_VERSION 0x010402 -#define CHERRYUSB_VERSION_STR "v1.4.2" - -#endif \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/core/usbd_core.c b/rt-thread/components/drivers/usb/cherryusb/core/usbd_core.c index d7fb351..e072d8a 100644 --- a/rt-thread/components/drivers/usb/cherryusb/core/usbd_core.c +++ b/rt-thread/components/drivers/usb/cherryusb/core/usbd_core.c @@ -45,18 +45,12 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv { struct usb_msosv1_descriptor *msosv1_desc; struct usb_msosv2_descriptor *msosv2_desc; struct usb_bos_descriptor *bos_desc; - struct usb_webusb_descriptor *webusb_url_desc; #endif /* Buffer used for storing standard, class and vendor request data */ USB_MEM_ALIGNX uint8_t req_data[CONFIG_USBDEV_REQUEST_BUFFER_LEN]; /** Currently selected configuration */ uint8_t configuration; - uint8_t device_address; - bool self_powered; - bool remote_wakeup_support; - bool remote_wakeup_enabled; - bool is_suspend; #ifdef CONFIG_USBDEV_ADVANCE_DESC uint8_t speed; #endif @@ -64,7 +58,6 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv { bool test_req; #endif struct usbd_interface *intf[16]; - uint8_t intf_altsetting[16]; uint8_t intf_offset; struct usbd_tx_rx_msg tx_msg[CONFIG_USBDEV_EP_NUM]; @@ -99,7 +92,6 @@ static bool is_device_configured(uint8_t busid) * This function sets endpoint configuration according to one specified in USB * endpoint descriptor and then enables it for data transfers. * - * @param [in] busid busid * @param [in] ep Endpoint descriptor byte array * * @return true if successfully configured and enabled @@ -107,9 +99,9 @@ static bool is_device_configured(uint8_t busid) static bool usbd_set_endpoint(uint8_t busid, const struct usb_endpoint_descriptor *ep) { USB_LOG_DBG("Open ep:0x%02x type:%u mps:%u\r\n", - ep->bEndpointAddress, - USB_GET_ENDPOINT_TYPE(ep->bmAttributes), - USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize)); + ep->bEndpointAddress, + USB_GET_ENDPOINT_TYPE(ep->bmAttributes), + USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize)); if (ep->bEndpointAddress & 0x80) { g_usbd_core[busid].tx_msg[ep->bEndpointAddress & 0x7f].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); @@ -127,7 +119,6 @@ static bool usbd_set_endpoint(uint8_t busid, const struct usb_endpoint_descripto * This function cancels transfers that are associated with endpoint and * disabled endpoint itself. * - * @param [in] busid busid * @param [in] ep Endpoint descriptor byte array * * @return true if successfully deconfigured and disabled @@ -135,8 +126,8 @@ static bool usbd_set_endpoint(uint8_t busid, const struct usb_endpoint_descripto static bool usbd_reset_endpoint(uint8_t busid, const struct usb_endpoint_descriptor *ep) { USB_LOG_DBG("Close ep:0x%02x type:%u\r\n", - ep->bEndpointAddress, - USB_GET_ENDPOINT_TYPE(ep->bmAttributes)); + ep->bEndpointAddress, + USB_GET_ENDPOINT_TYPE(ep->bmAttributes)); return usbd_ep_close(busid, ep->bEndpointAddress) == 0 ? true : false; } @@ -147,7 +138,6 @@ static bool usbd_reset_endpoint(uint8_t busid, const struct usb_endpoint_descrip * This function parses the list of installed USB descriptors and attempts * to find the specified USB descriptor. * - * @param [in] busid busid * @param [in] type_index Type and index of the descriptor * @param [out] data Descriptor data * @param [out] len Descriptor length @@ -184,9 +174,6 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da break; } desc_len = ((desc[CONF_DESC_wTotalLength]) | (desc[CONF_DESC_wTotalLength + 1] << 8)); - - g_usbd_core[busid].self_powered = (desc[7] & USB_CONFIG_POWERED_MASK) ? true : false; - g_usbd_core[busid].remote_wakeup_support = (desc[7] & USB_CONFIG_REMOTE_WAKEUP) ? true : false; break; case USB_DESCRIPTOR_TYPE_STRING: if (index == USB_OSDESC_STRING_DESC_INDEX) { @@ -349,9 +336,6 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da */ *len = (p[CONF_DESC_wTotalLength]) | (p[CONF_DESC_wTotalLength + 1] << 8); - - g_usbd_core[busid].self_powered = (p[7] & USB_CONFIG_POWERED_MASK) ? true : false; - g_usbd_core[busid].remote_wakeup_support = (p[7] & USB_CONFIG_REMOTE_WAKEUP) ? true : false; } else { /* normally length is at offset 0 */ *len = p[DESC_bLength]; @@ -374,7 +358,6 @@ static bool usbd_get_descriptor(uint8_t busid, uint16_t type_index, uint8_t **da * index and alternate setting by parsing the installed USB descriptor list. * A configuration index of 0 unconfigures the device. * - * @param [in] busid busid * @param [in] config_index Configuration index * @param [in] alt_setting Alternate setting number * @@ -444,7 +427,6 @@ static bool usbd_set_configuration(uint8_t busid, uint8_t config_index, uint8_t /** * @brief set USB interface * - * @param [in] busid busid * @param [in] iface Interface index * @param [in] alt_setting Alternate setting number * @@ -495,12 +477,10 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting if (cur_iface == iface) { ep_desc = (struct usb_endpoint_descriptor *)p; - if (alt_setting == 0) { + if (cur_alt_setting != alt_setting) { ret = usbd_reset_endpoint(busid, ep_desc); - goto find_end; - } else if (cur_alt_setting == alt_setting) { - ret = usbd_set_endpoint(busid, ep_desc); } else { + ret = usbd_set_endpoint(busid, ep_desc); } } @@ -518,7 +498,6 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting } } -find_end: usbd_class_event_notify_handler(busid, USBD_EVENT_SET_INTERFACE, (void *)if_desc); return ret; @@ -527,7 +506,6 @@ find_end: /** * @brief handle a standard device request * - * @param [in] busid busid * @param [in] setup The setup packet * @param [in,out] data Data buffer * @param [in,out] len Pointer to data length @@ -544,12 +522,6 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet * /* bit 0: self-powered */ /* bit 1: remote wakeup */ (*data)[0] = 0x00; - if (g_usbd_core[busid].self_powered) { - (*data)[0] |= USB_GETSTATUS_SELF_POWERED; - } - if (g_usbd_core[busid].remote_wakeup_enabled) { - (*data)[0] |= USB_GETSTATUS_REMOTE_WAKEUP; - } (*data)[1] = 0x00; *len = 2; break; @@ -558,10 +530,8 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet * case USB_REQUEST_SET_FEATURE: if (value == USB_FEATURE_REMOTE_WAKEUP) { if (setup->bRequest == USB_REQUEST_SET_FEATURE) { - g_usbd_core[busid].remote_wakeup_enabled = true; g_usbd_core[busid].event_handler(busid, USBD_EVENT_SET_REMOTE_WAKEUP); } else { - g_usbd_core[busid].remote_wakeup_enabled = false; g_usbd_core[busid].event_handler(busid, USBD_EVENT_CLR_REMOTE_WAKEUP); } } else if (value == USB_FEATURE_TEST_MODE) { @@ -573,7 +543,6 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet * break; case USB_REQUEST_SET_ADDRESS: - g_usbd_core[busid].device_address = value; usbd_set_address(busid, value); *len = 0; break; @@ -587,20 +556,17 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet * break; case USB_REQUEST_GET_CONFIGURATION: - (*data)[0] = g_usbd_core[busid].configuration; + *data = (uint8_t *)&g_usbd_core[busid].configuration; *len = 1; break; case USB_REQUEST_SET_CONFIGURATION: value &= 0xFF; - if (value == 0) { - g_usbd_core[busid].configuration = 0; - } else if (!usbd_set_configuration(busid, value, 0)) { + if (!usbd_set_configuration(busid, value, 0)) { ret = false; } else { g_usbd_core[busid].configuration = value; - g_usbd_core[busid].is_suspend = false; usbd_class_event_notify_handler(busid, USBD_EVENT_CONFIGURED, NULL); g_usbd_core[busid].event_handler(busid, USBD_EVENT_CONFIGURED); } @@ -623,7 +589,6 @@ static bool usbd_std_device_req_handler(uint8_t busid, struct usb_setup_packet * /** * @brief handle a standard interface request * - * @param [in] busid busid * @param [in] setup The setup packet * @param [in,out] data Data buffer * @param [in,out] len Pointer to data length @@ -635,16 +600,6 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe uint8_t type = HI_BYTE(setup->wValue); uint8_t intf_num = LO_BYTE(setup->wIndex); bool ret = true; - const uint8_t *p; - uint32_t desc_len = 0; - uint32_t current_desc_len = 0; - uint8_t cur_iface = 0xFF; - -#ifdef CONFIG_USBDEV_ADVANCE_DESC - p = g_usbd_core[busid].descriptors->config_descriptor_callback(g_usbd_core[busid].speed); -#else - p = (uint8_t *)g_usbd_core[busid].descriptors; -#endif /* Only when device is configured, then interface requests can be valid. */ if (!is_device_configured(busid)) { @@ -659,39 +614,7 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe break; case USB_REQUEST_GET_DESCRIPTOR: - if (type == 0x21) { /* HID_DESCRIPTOR_TYPE_HID */ - while (p[DESC_bLength] != 0U) { - switch (p[DESC_bDescriptorType]) { - case USB_DESCRIPTOR_TYPE_CONFIGURATION: - current_desc_len = 0; - desc_len = (p[CONF_DESC_wTotalLength]) | - (p[CONF_DESC_wTotalLength + 1] << 8); - - break; - - case USB_DESCRIPTOR_TYPE_INTERFACE: - cur_iface = p[INTF_DESC_bInterfaceNumber]; - break; - case 0x21: - if (cur_iface == intf_num) { - *data = (uint8_t *)p; - //memcpy(*data, p, p[DESC_bLength]); - *len = p[DESC_bLength]; - return true; - } - break; - default: - break; - } - - /* skip to next descriptor */ - p += p[DESC_bLength]; - current_desc_len += p[DESC_bLength]; - if (current_desc_len >= desc_len && desc_len) { - break; - } - } - } else if (type == 0x22) { /* HID_DESCRIPTOR_TYPE_HID_REPORT */ + if (type == 0x22) { /* HID_DESCRIPTOR_TYPE_HID_REPORT */ for (uint8_t i = 0; i < g_usbd_core[busid].intf_offset; i++) { struct usbd_interface *intf = g_usbd_core[busid].intf[i]; @@ -710,12 +633,11 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe ret = false; break; case USB_REQUEST_GET_INTERFACE: - (*data)[0] = g_usbd_core[busid].intf_altsetting[intf_num]; + (*data)[0] = 0; *len = 1; break; case USB_REQUEST_SET_INTERFACE: - g_usbd_core[busid].intf_altsetting[intf_num] = LO_BYTE(setup->wValue); usbd_set_interface(busid, setup->wIndex, setup->wValue); *len = 0; break; @@ -731,7 +653,6 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe /** * @brief handle a standard endpoint request * - * @param [in] busid busid * @param [in] setup The setup packet * @param [in,out] data Data buffer * @param [in,out] len Pointer to data length @@ -742,7 +663,6 @@ static bool usbd_std_endpoint_req_handler(uint8_t busid, struct usb_setup_packet { uint8_t ep = (uint8_t)setup->wIndex; bool ret = true; - uint8_t stalled; /* Only when device is configured, then endpoint requests can be valid. */ if (!is_device_configured(busid)) { @@ -751,12 +671,7 @@ static bool usbd_std_endpoint_req_handler(uint8_t busid, struct usb_setup_packet switch (setup->bRequest) { case USB_REQUEST_GET_STATUS: - usbd_ep_is_stalled(busid, ep, &stalled); - if (stalled) { - (*data)[0] = 0x01; - } else { - (*data)[0] = 0x00; - } + (*data)[0] = 0x00; (*data)[1] = 0x00; *len = 2; break; @@ -796,7 +711,6 @@ static bool usbd_std_endpoint_req_handler(uint8_t busid, struct usb_setup_packet /** * @brief handle standard requests (list in chapter 9) * - * @param [in] busid busid * @param [in] setup The setup packet * @param [in,out] data Data buffer * @param [in,out] len Pointer to data length @@ -840,7 +754,8 @@ static int usbd_standard_request_handler(uint8_t busid, struct usb_setup_packet /** * @brief handler for class requests * - * @param [in] busid busid + * If a custom request handler was installed, this handler is called first. + * * @param [in] setup The setup packet * @param [in,out] data Data buffer * @param [in,out] len Pointer to data length @@ -872,7 +787,8 @@ static int usbd_class_request_handler(uint8_t busid, struct usb_setup_packet *se /** * @brief handler for vendor requests * - * @param [in] busid busid + * If a custom request handler was installed, this handler is called first. + * * @param [in] setup The setup packet * @param [in,out] data Data buffer * @param [in,out] len Pointer to data length @@ -925,12 +841,10 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s return -1; } } - } - - if (g_usbd_core[busid].descriptors->webusb_url_descriptor) { + } else if (g_usbd_core[busid].descriptors->webusb_url_descriptor) { if (setup->bRequest == g_usbd_core[busid].descriptors->webusb_url_descriptor->vendor_code) { switch (setup->wIndex) { - case WEBUSB_REQUEST_GET_URL: + case WINUSB_REQUEST_GET_DESCRIPTOR_SET: desclen = g_usbd_core[busid].descriptors->webusb_url_descriptor->string_len; *data = (uint8_t *)g_usbd_core[busid].descriptors->webusb_url_descriptor->string; //memcpy(*data, g_usbd_core[busid].descriptors->webusb_url_descriptor->string, desclen); @@ -983,22 +897,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s } } } - - if (g_usbd_core[busid].webusb_url_desc) { - if (setup->bRequest == g_usbd_core[busid].webusb_url_desc->vendor_code) { - switch (setup->wIndex) { - case WEBUSB_REQUEST_GET_URL: - desclen = g_usbd_core[busid].webusb_url_desc->string_len; - *data = (uint8_t *)g_usbd_core[busid].webusb_url_desc->string; - //memcpy(*data, g_usbd_core[busid].webusb_url_desc->string, desclen); - *len = desclen; - return 0; - default: - USB_LOG_ERR("unknown vendor code\r\n"); - return -1; - } - } - } #endif for (uint8_t i = 0; i < g_usbd_core[busid].intf_offset; i++) { struct usbd_interface *intf = g_usbd_core[busid].intf[i]; @@ -1014,7 +912,6 @@ static int usbd_vendor_request_handler(uint8_t busid, struct usb_setup_packet *s /** * @brief handle setup request( standard/class/vendor/other) * - * @param [in] busid busid * @param [in] setup The setup packet * @param [in,out] data Data buffer * @param [in,out] len Pointer to data length @@ -1088,22 +985,17 @@ void usbd_event_disconnect_handler(uint8_t busid) void usbd_event_resume_handler(uint8_t busid) { - g_usbd_core[busid].is_suspend = false; g_usbd_core[busid].event_handler(busid, USBD_EVENT_RESUME); } void usbd_event_suspend_handler(uint8_t busid) { - if (g_usbd_core[busid].device_address > 0) { - g_usbd_core[busid].is_suspend = true; - g_usbd_core[busid].event_handler(busid, USBD_EVENT_SUSPEND); - } + g_usbd_core[busid].event_handler(busid, USBD_EVENT_SUSPEND); } void usbd_event_reset_handler(uint8_t busid) { usbd_set_address(busid, 0); - g_usbd_core[busid].device_address = 0; g_usbd_core[busid].configuration = 0; #ifdef CONFIG_USBDEV_ADVANCE_DESC g_usbd_core[busid].speed = USB_SPEED_UNKNOWN; @@ -1176,7 +1068,7 @@ void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup) #ifdef CONFIG_USBDEV_EP0_INDATA_NO_COPY g_usbd_core[busid].ep0_data_buf = buf; #else - usb_memcpy(g_usbd_core[busid].ep0_data_buf, buf, g_usbd_core[busid].ep0_data_buf_residue); + memcpy(g_usbd_core[busid].ep0_data_buf, buf, g_usbd_core[busid].ep0_data_buf_residue); #endif } else { /* use memcpy(*data, xxx, len); has copied into ep0 buffer, we do nothing */ @@ -1199,8 +1091,6 @@ void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt { struct usb_setup_packet *setup = &g_usbd_core[busid].setup; - (void)ep; - g_usbd_core[busid].ep0_data_buf += nbytes; g_usbd_core[busid].ep0_data_buf_residue -= nbytes; @@ -1240,8 +1130,6 @@ void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nby { struct usb_setup_packet *setup = &g_usbd_core[busid].setup; - (void)ep; - if (nbytes > 0) { g_usbd_core[busid].ep0_data_buf += nbytes; g_usbd_core[busid].ep0_data_buf_residue -= nbytes; @@ -1325,11 +1213,6 @@ void usbd_bos_desc_register(uint8_t busid, struct usb_bos_descriptor *desc) { g_usbd_core[busid].bos_desc = desc; } - -void usbd_webusb_desc_register(uint8_t busid, struct usb_webusb_descriptor *desc) -{ - g_usbd_core[busid].webusb_url_desc = desc; -} #endif void usbd_add_interface(uint8_t busid, struct usbd_interface *intf) @@ -1373,30 +1256,7 @@ bool usb_device_is_configured(uint8_t busid) return g_usbd_core[busid].configuration; } -bool usb_device_is_suspend(uint8_t busid) -{ - return g_usbd_core[busid].is_suspend; -} - -int usbd_send_remote_wakeup(uint8_t busid) -{ - if (g_usbd_core[busid].remote_wakeup_support && g_usbd_core[busid].remote_wakeup_enabled && g_usbd_core[busid].is_suspend) { - return usbd_set_remote_wakeup(busid); - } else { - if (!g_usbd_core[busid].remote_wakeup_support) { - USB_LOG_ERR("device does not support remote wakeup\r\n"); - } - if (!g_usbd_core[busid].remote_wakeup_enabled) { - USB_LOG_ERR("device remote wakeup is not enabled\r\n"); - } - if (!g_usbd_core[busid].is_suspend) { - USB_LOG_ERR("device is not in suspend state\r\n"); - } - return -1; - } -} - -int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event)) +int usbd_initialize(uint8_t busid, uint32_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event)) { int ret; struct usbd_bus *bus; @@ -1419,15 +1279,9 @@ int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uin int usbd_deinitialize(uint8_t busid) { - if (busid >= CONFIG_USBDEV_MAX_BUS) { - USB_LOG_ERR("bus overflow\r\n"); - while (1) { - } - } - - g_usbd_core[busid].event_handler(busid, USBD_EVENT_DEINIT); - usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL); - usb_dc_deinit(busid); g_usbd_core[busid].intf_offset = 0; + usb_dc_deinit(busid); + usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL); + g_usbd_core[busid].event_handler(busid, USBD_EVENT_DEINIT); return 0; } diff --git a/rt-thread/components/drivers/usb/cherryusb/core/usbd_core.h b/rt-thread/components/drivers/usb/cherryusb/core/usbd_core.h index 71bdb29..01335f2 100644 --- a/rt-thread/components/drivers/usb/cherryusb/core/usbd_core.h +++ b/rt-thread/components/drivers/usb/cherryusb/core/usbd_core.h @@ -23,7 +23,6 @@ extern "C" { #include "usb_log.h" #include "usb_dc.h" #include "usb_memcpy.h" -#include "usb_version.h" enum usbd_event_type { /* USB DCD IRQ */ @@ -72,13 +71,13 @@ struct usb_descriptor { const char *(*string_descriptor_callback)(uint8_t speed, uint8_t index); const struct usb_msosv1_descriptor *msosv1_descriptor; const struct usb_msosv2_descriptor *msosv2_descriptor; - const struct usb_webusb_descriptor *webusb_url_descriptor; + const struct usb_webusb_url_ex_descriptor *webusb_url_descriptor; const struct usb_bos_descriptor *bos_descriptor; }; struct usbd_bus { uint8_t busid; - uintptr_t reg_base; + uint32_t reg_base; }; extern struct usbd_bus g_usbdev_bus[]; @@ -94,7 +93,6 @@ void usbd_desc_register(uint8_t busid, const uint8_t *desc); void usbd_msosv1_desc_register(uint8_t busid, struct usb_msosv1_descriptor *desc); void usbd_msosv2_desc_register(uint8_t busid, struct usb_msosv2_descriptor *desc); void usbd_bos_desc_register(uint8_t busid, struct usb_bos_descriptor *desc); -void usbd_webusb_desc_register(uint8_t busid, struct usb_webusb_descriptor *desc); #endif void usbd_add_interface(uint8_t busid, struct usbd_interface *intf); @@ -103,10 +101,8 @@ void usbd_add_endpoint(uint8_t busid, struct usbd_endpoint *ep); uint16_t usbd_get_ep_mps(uint8_t busid, uint8_t ep); uint8_t usbd_get_ep_mult(uint8_t busid, uint8_t ep); bool usb_device_is_configured(uint8_t busid); -bool usb_device_is_suspend(uint8_t busid); -int usbd_send_remote_wakeup(uint8_t busid); -int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event)); +int usbd_initialize(uint8_t busid, uint32_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event)); int usbd_deinitialize(uint8_t busid); #ifdef __cplusplus diff --git a/rt-thread/components/drivers/usb/cherryusb/core/usbh_core.c b/rt-thread/components/drivers/usb/cherryusb/core/usbh_core.c index cb36f97..d1fc769 100644 --- a/rt-thread/components/drivers/usb/cherryusb/core/usbh_core.c +++ b/rt-thread/components/drivers/usb/cherryusb/core/usbh_core.c @@ -93,22 +93,19 @@ static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uin struct usbh_class_info *index = NULL; for (index = usbh_class_info_table_begin; index < usbh_class_info_table_end; index++) { - if ((index->match_flags & USB_CLASS_MATCH_INTF_CLASS) && !(index->bInterfaceClass == class)) { + if ((index->match_flags & USB_CLASS_MATCH_INTF_CLASS) && !(index->class == class)) { continue; } - if ((index->match_flags & USB_CLASS_MATCH_INTF_SUBCLASS) && !(index->bInterfaceSubClass == subclass)) { + if ((index->match_flags & USB_CLASS_MATCH_INTF_SUBCLASS) && !(index->subclass == subclass)) { continue; } - if ((index->match_flags & USB_CLASS_MATCH_INTF_PROTOCOL) && !(index->bInterfaceProtocol == protocol)) { + if ((index->match_flags & USB_CLASS_MATCH_INTF_PROTOCOL) && !(index->protocol == protocol)) { continue; } if (index->match_flags & USB_CLASS_MATCH_VID_PID && index->id_table) { /* scan id table */ uint32_t i; - for (i = 0; index->id_table[i][0]; i++) { - if (index->id_table[i][0] == vid && index->id_table[i][1] == pid) { - break; - } + for (i = 0; index->id_table[i][0] && index->id_table[i][0] != vid && index->id_table[i][1] != pid; i++) { } /* do not match, continue next */ if (!index->id_table[i][0]) { @@ -489,7 +486,7 @@ int usbh_enumerate(struct usbh_hubport *hport) goto errout; } USB_LOG_INFO("The device has %d interfaces\r\n", ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->bNumInterfaces); - hport->raw_config_desc = usb_osal_malloc(wTotalLength + 1); + hport->raw_config_desc = usb_malloc(wTotalLength); if (hport->raw_config_desc == NULL) { ret = -USB_ERR_NOMEM; USB_LOG_ERR("No memory to alloc for raw_config_desc\r\n"); @@ -498,8 +495,6 @@ int usbh_enumerate(struct usbh_hubport *hport) config_value = ((struct usb_configuration_descriptor *)ep0_request_buffer[hport->bus->busid])->bConfigurationValue; memcpy(hport->raw_config_desc, ep0_request_buffer[hport->bus->busid], wTotalLength); - hport->raw_config_desc[wTotalLength] = '\0'; - #ifdef CONFIG_USBHOST_GET_STRING_DESC uint8_t string_buffer[128]; @@ -554,7 +549,7 @@ int usbh_enumerate(struct usbh_hubport *hport) setup->wLength = 16; ret = usbh_control_transfer(hport, setup, ep0_request_buffer[hport->bus->busid]); - if (ret < 0 && (ret != -USB_ERR_STALL)) { + if (ret < 0 && (ret != -EPERM)) { USB_LOG_ERR("Failed to get msosv1 compat id,errorcode:%d\r\n", ret); goto errout; } @@ -581,7 +576,7 @@ int usbh_enumerate(struct usbh_hubport *hport) errout: if (hport->raw_config_desc) { - usb_osal_free(hport->raw_config_desc); + usb_free(hport->raw_config_desc); hport->raw_config_desc = NULL; } return ret; @@ -605,7 +600,7 @@ void usbh_hubport_release(struct usbh_hubport *hport) } } -static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uintptr_t reg_base) +static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uint32_t reg_base) { memset(bus, 0, sizeof(struct usbh_bus)); bus->busid = busid; @@ -618,7 +613,7 @@ static void usbh_bus_init(struct usbh_bus *bus, uint8_t busid, uintptr_t reg_bas usb_slist_add_tail(&g_bus_head, &bus->list); } -int usbh_initialize(uint8_t busid, uintptr_t reg_base) +int usbh_initialize(uint8_t busid, uint32_t reg_base) { struct usbh_bus *bus; @@ -654,12 +649,6 @@ int usbh_deinitialize(uint8_t busid) { struct usbh_bus *bus; - if (busid >= CONFIG_USBHOST_MAX_BUS) { - USB_LOG_ERR("bus overflow\r\n"); - while (1) { - } - } - bus = &g_usbhost_bus[busid]; usbh_hub_deinitialize(bus); @@ -742,7 +731,7 @@ static void *usbh_list_all_interface_name(struct usbh_hub *hub, const char *devn struct usbh_hub *hub_next; void *priv; - for (uint8_t port = 0; port < hub->nports; port++) { + for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { hport = &hub->child[port]; if (hport->connected) { for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) { @@ -771,9 +760,8 @@ static void usbh_list_all_interface_driver(struct usbh_hub *hub) { struct usbh_hubport *hport; struct usbh_hub *hub_next; - const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" }; - for (uint8_t port = 0; port < hub->nports; port++) { + for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { hport = &hub->child[port]; if (hport->connected) { for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) { @@ -782,12 +770,11 @@ static void usbh_list_all_interface_driver(struct usbh_hub *hub) USB_LOG_RAW("\t"); } - USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s, %s\r\n", + USB_LOG_RAW("|__Port %u, dev addr:0x%02x, If %u, ClassDriver=%s\r\n", hport->port, hport->dev_addr, itf, - hport->config.intf[itf].class_driver->driver_name, - speed_table[hport->speed]); + hport->config.intf[itf].class_driver->driver_name); if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) { hub_next = hport->config.intf[itf].priv; @@ -807,7 +794,7 @@ static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub * struct usbh_hubport *hport; struct usbh_hub *hub_next; - for (uint8_t port = 0; port < hub->nports; port++) { + for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) { hport = &hub->child[port]; if (hport->connected) { USB_LOG_RAW("\r\nBus %u, Hub %u, Port %u, dev addr:0x%02x, VID:PID 0x%04x:0x%04x\r\n", @@ -834,37 +821,6 @@ static void usbh_list_all_interface_desc(struct usbh_bus *bus, struct usbh_hub * } } -static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t hub_index, uint8_t hub_port) -{ - struct usbh_hubport *hport; - struct usbh_hub *hub_next; - - if (hub->index == hub_index) { - hport = &hub->child[hub_port - 1]; - return hport; - } else { - for (uint8_t port = 0; port < hub->nports; port++) { - hport = &hub->child[port]; - if (hport->connected) { - for (uint8_t itf = 0; itf < hport->config.config_desc.bNumInterfaces; itf++) { - if (hport->config.intf[itf].class_driver && hport->config.intf[itf].class_driver->driver_name) { - if (strcmp(hport->config.intf[itf].class_driver->driver_name, "hub") == 0) { - hub_next = hport->config.intf[itf].priv; - - if (hub_next && hub_next->connected) { - hport = usbh_list_all_hubport(hub_next, hub_index, hub_port); - if (hport) { - return hport; - } - } - } - } - } - } - } - } - return NULL; -} void *usbh_find_class_instance(const char *devname) { usb_slist_t *bus_list; @@ -889,23 +845,6 @@ void *usbh_find_class_instance(const char *devname) return NULL; } -struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t hub_port) -{ - struct usbh_hub *hub; - struct usbh_bus *bus; - struct usbh_hubport *hport; - size_t flags; - - flags = usb_osal_enter_critical_section(); - - bus = &g_usbhost_bus[busid]; - hub = &bus->hcd.roothub; - - hport = usbh_list_all_hubport(hub, hub_index, hub_port); - usb_osal_leave_critical_section(flags); - return hport; -} - int lsusb(int argc, char **argv) { usb_slist_t *bus_list; @@ -949,7 +888,7 @@ int lsusb(int argc, char **argv) USB_LOG_RAW("/: Bus %u, Hub %u, ports=%u, is roothub\r\n", bus->busid, hub->index, - hub->nports); + hub->hub_desc.bNbrPorts); usbh_list_all_interface_driver(hub); } } diff --git a/rt-thread/components/drivers/usb/cherryusb/core/usbh_core.h b/rt-thread/components/drivers/usb/cherryusb/core/usbh_core.h index eaddb30..3210988 100644 --- a/rt-thread/components/drivers/usb/cherryusb/core/usbh_core.h +++ b/rt-thread/components/drivers/usb/cherryusb/core/usbh_core.h @@ -21,7 +21,6 @@ #include "usb_osal.h" #include "usbh_hub.h" #include "usb_memcpy.h" -#include "usb_version.h" #ifdef __cplusplus extern "C" { @@ -61,9 +60,9 @@ extern "C" { struct usbh_class_info { uint8_t match_flags; /* Used for product specific matches; range is inclusive */ - uint8_t bInterfaceClass; /* Base device class code */ - uint8_t bInterfaceSubClass; /* Sub-class, depends on base class. Eg. */ - uint8_t bInterfaceProtocol; /* Protocol, depends on base class. Eg. */ + uint8_t class; /* Base device class code */ + uint8_t subclass; /* Sub-class, depends on base class. Eg. */ + uint8_t protocol; /* Protocol, depends on base class. Eg. */ const uint16_t (*id_table)[2]; /* List of Vendor/Product ID pairs */ const struct usbh_class_driver *class_driver; }; @@ -102,9 +101,6 @@ struct usbh_hubport { uint8_t port; /* Hub port index */ uint8_t dev_addr; /* device address */ uint8_t speed; /* device speed */ - uint8_t depth; /* distance from root hub */ - uint8_t route; /* route string */ - uint8_t slot_id; /* slot id */ struct usb_device_descriptor device_desc; struct usbh_configuration config; const char *iManufacturer; @@ -113,7 +109,6 @@ struct usbh_hubport { uint8_t *raw_config_desc; struct usb_setup_packet *setup; struct usbh_hub *parent; - struct usbh_hub *self; /* if this hubport is a hub */ struct usbh_bus *bus; struct usb_endpoint_descriptor ep0; struct usbh_urb ep0_urb; @@ -125,13 +120,7 @@ struct usbh_hub { bool is_roothub; uint8_t index; uint8_t hub_addr; - uint8_t speed; - uint8_t nports; - uint8_t powerdelay; - uint8_t tt_think; - bool ismtt; - struct usb_hub_descriptor hub_desc; /* USB 2.0 only */ - struct usb_hub_ss_descriptor hub_ss_desc; /* USB 3.0 only */ + struct usb_hub_descriptor hub_desc; struct usbh_hubport child[CONFIG_USBHOST_MAX_EHPORTS]; struct usbh_hubport *parent; struct usbh_bus *bus; @@ -154,9 +143,9 @@ struct usbh_devaddr_map { }; struct usbh_hcd { - uintptr_t reg_base; + uint32_t reg_base; uint8_t hcd_id; - uint8_t roothub_intbuf[2]; /* at most 15 roothub ports */ + uint8_t roothub_intbuf[1]; struct usbh_hub roothub; }; @@ -272,10 +261,9 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out */ int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting); -int usbh_initialize(uint8_t busid, uintptr_t reg_base); +int usbh_initialize(uint8_t busid, uint32_t reg_base); int usbh_deinitialize(uint8_t busid); void *usbh_find_class_instance(const char *devname); -struct usbh_hubport *usbh_find_hubport(uint8_t busid, uint8_t hub_index, uint8_t hub_port); int lsusb(int argc, char **argv); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/adb/cherryadb.png b/rt-thread/components/drivers/usb/cherryusb/demo/adb/cherryadb.png deleted file mode 100644 index 512586b..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/demo/adb/cherryadb.png and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/adb/cherrysh_port.c b/rt-thread/components/drivers/usb/cherryusb/demo/adb/cherrysh_port.c deleted file mode 100644 index 8597172..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/demo/adb/cherrysh_port.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "FreeRTOS.h" -#include "task.h" -#include "event_groups.h" -#include "csh.h" -#include "usbd_core.h" -#include "usbd_adb.h" -#include "chry_ringbuffer.h" - -static chry_ringbuffer_t shell_rb; -static uint8_t mempool[1024]; - -#ifndef task_repl_PRIORITY -#define task_repl_PRIORITY (configMAX_PRIORITIES - 4U) -#endif - -#ifndef task_exec_PRIORITY -#define task_exec_PRIORITY (configMAX_PRIORITIES - 5U) -#endif - -static chry_shell_t csh; -static volatile bool login = false; - -static StaticTask_t task_buffer_repl; -static StaticTask_t task_buffer_exec; - -static StackType_t task_stack_repl[1024]; -static StackType_t task_stack_exec[1024]; - -static TaskHandle_t task_hdl_repl = NULL; -static TaskHandle_t task_hdl_exec = NULL; - -static EventGroupHandle_t event_hdl; -static StaticEventGroup_t event_grp; - -void usbd_adb_notify_shell_read(uint8_t *data, uint32_t len) -{ - chry_ringbuffer_write(&shell_rb, data, len); - - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - xEventGroupSetBitsFromISR(event_hdl, 0x10, &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); -} - -void usbd_adb_notify_write_done(void) -{ - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - xEventGroupSetBitsFromISR(event_hdl, 0x20, &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); -} - -static uint16_t csh_sput_cb(chry_readline_t *rl, const void *data, uint16_t size) -{ - (void)rl; - - if (!usb_device_is_configured(0)) { - return size; - } - - if (usbd_adb_can_write() && size) { - usbd_abd_write(ADB_SHELL_LOALID, data, size); - xEventGroupWaitBits(event_hdl, 0x20, pdTRUE, pdFALSE, portMAX_DELAY); - } - - return size; -} - -static uint16_t csh_sget_cb(chry_readline_t *rl, void *data, uint16_t size) -{ - (void)rl; - - return chry_ringbuffer_read(&shell_rb, data, size); -} - -static void wait_char(void) -{ - EventBits_t event; -wait: - /* In order to lock the log from being disrupted , wait for REPL task execution to complete */ - event = xEventGroupWaitBits(event_hdl, (0x10 | 0x01 | 0x04), pdTRUE, pdFALSE, portMAX_DELAY); - if ((event & 0x10) == 0) { - if (event & 0x01) { - chry_readline_erase_line(&csh.rl); - xEventGroupSetBits(event_hdl, 0x02); - } - if (event & 0x04) { - chry_readline_edit_refresh(&csh.rl); - xEventGroupSetBits(event_hdl, 0x08); - } - - goto wait; - } -} - -static void task_repl(void *param) -{ - (void)param; - int ret; - volatile uint8_t *pexec = (void *)&csh.exec; - - for (;;) { - restart: - if (login) { - goto repl; - } else { - } - - ret = csh_login(&csh); - if (ret == 0) { - login = true; - } else if (ret == 1) { - /*!< no enough char */ - wait_char(); - continue; - } else { - continue; - } - - repl: - ret = chry_shell_task_repl(&csh); - - if (ret == -1) { - /*!< error */ - goto restart; - } else if (ret == 1) { - /*!< no enough char */ - wait_char(); - } else { - /*!< restart */ - } - - /*!< check flag */ - if (*pexec == CSH_STATUS_EXEC_DONE) { - *pexec = CSH_STATUS_EXEC_IDLE; - chry_readline_auto_refresh(&csh.rl, true); - chry_readline_ignore(&csh.rl, false); - chry_readline_edit_refresh(&csh.rl); - } - - if (login == false) { - chry_readline_erase_line(&csh.rl); - csh.rl.noblock = false; - } - } -} - -static void task_exec(void *param) -{ - (void)param; - - /*!< execute shell command */ - chry_shell_task_exec(&csh); - - /*!< notify REPL task execute done */ - xEventGroupSetBits(event_hdl, 0x10); - - /*!< wait for REPL task delete */ - vTaskSuspend(NULL); -} - -int chry_shell_port_create_context(chry_shell_t *csh, int argc, const char **argv) -{ - volatile TaskHandle_t *p_task_hdl_exec = (void *)&task_hdl_exec; - (void)csh; - (void)argc; - (void)argv; - - if (*p_task_hdl_exec != NULL) { - vTaskDelete(*p_task_hdl_exec); - } - - *p_task_hdl_exec = xTaskCreateStatic(task_exec, "task_exec", 1024U, NULL, task_exec_PRIORITY, task_stack_exec, &task_buffer_exec); - return 0; -} - -void chry_shell_port_default_handler(chry_shell_t *csh, int sig) -{ - volatile uint8_t *pexec = (void *)&csh->exec; - volatile TaskHandle_t *p_task_hdl_exec = (void *)&task_hdl_exec; - - switch (sig) { - case CSH_SIGINT: - case CSH_SIGQUIT: - case CSH_SIGKILL: - case CSH_SIGTERM: - break; - default: - return; - } - - /*!< force delete task */ - if (*p_task_hdl_exec != NULL) { - vTaskDelete(task_hdl_exec); - *p_task_hdl_exec = NULL; - } - - switch (sig) { - case CSH_SIGINT: - csh->rl.sput(&csh->rl, "^SIGINT" CONFIG_CSH_NEWLINE, sizeof("^SIGINT" CONFIG_CSH_NEWLINE) - 1); - break; - case CSH_SIGQUIT: - csh->rl.sput(&csh->rl, "^SIGQUIT" CONFIG_CSH_NEWLINE, sizeof("^SIGQUIT" CONFIG_CSH_NEWLINE) - 1); - break; - case CSH_SIGKILL: - csh->rl.sput(&csh->rl, "^SIGKILL" CONFIG_CSH_NEWLINE, sizeof("^SIGKILL" CONFIG_CSH_NEWLINE) - 1); - break; - case CSH_SIGTERM: - csh->rl.sput(&csh->rl, "^SIGTERM" CONFIG_CSH_NEWLINE, sizeof("^SIGTERM" CONFIG_CSH_NEWLINE) - 1); - break; - default: - return; - } - - *pexec = CSH_STATUS_EXEC_IDLE; - chry_readline_auto_refresh(&csh->rl, true); - chry_readline_ignore(&csh->rl, false); - chry_readline_edit_refresh(&csh->rl); -} - -int shell_init(bool need_login) -{ - chry_shell_init_t csh_init; - - if (chry_ringbuffer_init(&shell_rb, mempool, sizeof(mempool))) { - return -1; - } - - if (need_login) { - login = false; - } else { - login = true; - } - - /*!< I/O callback */ - csh_init.sput = csh_sput_cb; - csh_init.sget = csh_sget_cb; - -#if defined(CONFIG_CSH_SYMTAB) && CONFIG_CSH_SYMTAB - extern const int __fsymtab_start; - extern const int __fsymtab_end; - extern const int __vsymtab_start; - extern const int __vsymtab_end; - - /*!< get table from ld symbol */ - csh_init.command_table_beg = &__fsymtab_start; - csh_init.command_table_end = &__fsymtab_end; - csh_init.variable_table_beg = &__vsymtab_start; - csh_init.variable_table_end = &__vsymtab_end; -#endif - -#if defined(CONFIG_CSH_PROMPTEDIT) && CONFIG_CSH_PROMPTEDIT - static char csh_prompt_buffer[128]; - - /*!< set prompt buffer */ - csh_init.prompt_buffer = csh_prompt_buffer; - csh_init.prompt_buffer_size = sizeof(csh_prompt_buffer); -#endif - -#if defined(CONFIG_CSH_HISTORY) && CONFIG_CSH_HISTORY - static char csh_history_buffer[128]; - - /*!< set history buffer */ - csh_init.history_buffer = csh_history_buffer; - csh_init.history_buffer_size = sizeof(csh_history_buffer); -#endif - -#if defined(CONFIG_CSH_LNBUFF_STATIC) && CONFIG_CSH_LNBUFF_STATIC - static char csh_line_buffer[128]; - - /*!< set linebuffer */ - csh_init.line_buffer = csh_line_buffer; - csh_init.line_buffer_size = sizeof(csh_line_buffer); -#endif - - csh_init.uid = 0; - csh_init.user[0] = "cherry"; - - /*!< The port hash function is required, - and the strcmp attribute is used weakly by default, - int chry_shell_port_hash_strcmp(const char *hash, const char *str); */ - csh_init.hash[0] = "12345678"; /*!< If there is no password, set to NULL */ - csh_init.host = "cherryadb"; - csh_init.user_data = NULL; - - int ret = chry_shell_init(&csh, &csh_init); - if (ret) { - return -1; - } - - task_hdl_exec = NULL; - event_hdl = xEventGroupCreateStatic(&event_grp); - task_hdl_repl = xTaskCreateStatic(task_repl, "task_repl", 1024U, NULL, task_repl_PRIORITY, task_stack_repl, &task_buffer_repl); - - return 0; -} - -void shell_lock(void) -{ - xEventGroupSetBits(event_hdl, 0x01); - xEventGroupWaitBits(event_hdl, 0x02, pdTRUE, pdTRUE, portMAX_DELAY); -} - -void shell_unlock(void) -{ - xEventGroupSetBits(event_hdl, 0x04); - xEventGroupWaitBits(event_hdl, 0x08, pdTRUE, pdTRUE, portMAX_DELAY); -} - -static int csh_exit(int argc, char **argv) -{ - (void)argc; - (void)argv; - - usbd_adb_close(ADB_SHELL_LOALID); - - return 0; -} -CSH_SCMD_EXPORT_ALIAS(csh_exit, exit, ); - -#define __ENV_PATH "/sbin:/bin" -const char ENV_PATH[] = __ENV_PATH; -CSH_RVAR_EXPORT(ENV_PATH, PATH, sizeof(__ENV_PATH)); - -#define __ENV_ZERO "" -const char ENV_ZERO[] = __ENV_ZERO; -CSH_RVAR_EXPORT(ENV_ZERO, ZERO, sizeof(__ENV_ZERO)); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c deleted file mode 100644 index 2090dae..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/demo/adb/usbd_adb_template.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbd_core.h" -#include "usbd_adb.h" - -/*!< endpoint address */ -#define WINUSB_IN_EP 0x81 -#define WINUSB_OUT_EP 0x02 - -#define USBD_VID 0xFFFF -#define USBD_PID 0xFFFF -#define USBD_MAX_POWER 100 -#define USBD_LANGID_STRING 1033 - -/*!< config descriptor size */ -#define USB_CONFIG_SIZE (9 + 9 + 7 + 7) - -#ifdef CONFIG_USB_HS -#define WINUSB_MAX_MPS 512 -#else -#define WINUSB_MAX_MPS 64 -#endif - -#define WCID_VENDOR_CODE 0x17 -#define ADB_INTF_NUM 0 - -__ALIGN_BEGIN const uint8_t WCID_StringDescriptor_MSOS[18] __ALIGN_END = { - /////////////////////////////////////// - /// MS OS string descriptor - /////////////////////////////////////// - 0x12, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - /* MSFT100 */ - 'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, /* wcChar_7 */ - '1', 0x00, '0', 0x00, '0', 0x00, /* wcChar_7 */ - WCID_VENDOR_CODE, /* bVendorCode */ - 0x00, /* bReserved */ -}; - -__ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[40] __ALIGN_END = { - /////////////////////////////////////// - /// WCID descriptor - /////////////////////////////////////// - 0x28, 0x00, 0x00, 0x00, /* dwLength */ - 0x00, 0x01, /* bcdVersion */ - 0x04, 0x00, /* wIndex */ - 0x01, /* bCount */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */ - - /////////////////////////////////////// - /// WCID function descriptor - /////////////////////////////////////// - ADB_INTF_NUM, /* bFirstInterfaceNumber */ - 0x01, /* bReserved */ - /* Compatible ID */ - 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8: WINUSB */ - /* */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */ -}; - -__ALIGN_BEGIN const uint8_t WINUSB_IF0_WCIDProperties[142] __ALIGN_END = { - /////////////////////////////////////// - /// WCID property descriptor - /////////////////////////////////////// - 0x8e, 0x00, 0x00, 0x00, /* dwLength */ - 0x00, 0x01, /* bcdVersion */ - 0x05, 0x00, /* wIndex */ - 0x01, 0x00, /* wCount */ - - /////////////////////////////////////// - /// registry propter descriptor - /////////////////////////////////////// - 0x84, 0x00, 0x00, 0x00, /* dwSize */ - 0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */ - 0x28, 0x00, /* wPropertyNameLength */ - /* DeviceInterfaceGUID */ - 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */ - 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */ - 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */ - 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */ - 'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */ - 0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */ - /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */ - '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */ - 'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */ - '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */ - '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */ - '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */ - 'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */ - '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */ - 'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */ - 'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */ - '6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */ -}; - -const uint8_t *WINUSB_IFx_WCIDProperties[] = { - WINUSB_IF0_WCIDProperties, -}; - -struct usb_msosv1_descriptor msosv1_desc = { - .string = WCID_StringDescriptor_MSOS, - .vendor_code = WCID_VENDOR_CODE, - .compat_id = WINUSB_WCIDDescriptor, - .comp_id_property = WINUSB_IFx_WCIDProperties, -}; - -/*!< global descriptor */ -static const uint8_t adb_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - ADB_DESCRIPTOR_INIT(ADB_INTF_NUM, WINUSB_IN_EP, WINUSB_OUT_EP, WINUSB_MAX_MPS), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'A', 0x00, /* wcChar6 */ - 'D', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x1C, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'A', 0x00, /* wcChar6 */ - 'D', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - '2', 0x00, /* wcChar9 */ - '0', 0x00, /* wcChar10 */ - '2', 0x00, /* wcChar11 */ - '4', 0x00, /* wcChar12 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x02, - 0x02, - 0x01, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; - -static void usbd_event_handler(uint8_t busid, uint8_t event) -{ - switch (event) { - case USBD_EVENT_RESET: - break; - case USBD_EVENT_CONNECTED: - break; - case USBD_EVENT_DISCONNECTED: - break; - case USBD_EVENT_RESUME: - break; - case USBD_EVENT_SUSPEND: - break; - case USBD_EVENT_CONFIGURED: - - break; - case USBD_EVENT_SET_REMOTE_WAKEUP: - break; - case USBD_EVENT_CLR_REMOTE_WAKEUP: - break; - - default: - break; - } -} - -static struct usbd_interface intf0; - -extern int shell_init(bool need_login); -void cherryadb_init(uint8_t busid, uint32_t reg_base) -{ - /* default password is : 12345678 */ - /* shell_init() must be called in-task */ - if (0 != shell_init(false)) { - /* shell failed to be initialized */ - printf("Failed to initialize shell\r\n"); - for (;;) { - ; - } - } - - usbd_desc_register(busid, adb_descriptor); - usbd_add_interface(busid, usbd_adb_init_intf(busid, &intf0, WINUSB_IN_EP, WINUSB_OUT_EP)); - usbd_initialize(busid, reg_base, usbd_event_handler); -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c index 56684e4..a80a221 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/audio_v1_mic_multichan_template.c @@ -144,7 +144,7 @@ const uint8_t audio_v1_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -212,7 +212,7 @@ struct audio_entity_info audio_entity_table[] = { .ep = AUDIO_IN_EP }, }; -void audio_v1_init(uint8_t busid, uintptr_t reg_base) +void audio_v1_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, audio_v1_descriptor); usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 1)); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c index 4beccc6..fbd53e3 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/audio_v1_mic_speaker_multichan_template.c @@ -139,7 +139,7 @@ const uint8_t audio_v1_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -238,7 +238,7 @@ struct audio_entity_info audio_entity_table[] = { .ep = AUDIO_OUT_EP }, }; -void audio_v1_init(uint8_t busid, uintptr_t reg_base) +void audio_v1_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, audio_v1_descriptor); usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 2)); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c index c00fffa..bf85762 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/audio_v2_mic_multichan_template.c @@ -149,7 +149,7 @@ const uint8_t audio_v2_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -229,7 +229,7 @@ struct audio_entity_info audio_entity_table[] = { .ep = AUDIO_IN_EP }, }; -void audio_v2_init(uint8_t busid, uintptr_t reg_base) +void audio_v2_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, audio_v2_descriptor); usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2)); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c index 0aebe57..e8afabe 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/audio_v2_mic_speaker_multichan_template.c @@ -196,7 +196,7 @@ uint8_t audio_v2_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -346,7 +346,7 @@ struct audio_entity_info audio_entity_table[] = { .ep = AUDIO_IN_EP }, }; -void audio_v2_init(uint8_t busid, uintptr_t reg_base) +void audio_v2_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, audio_v2_descriptor); usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 4)); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c index 0abb677..3fc7a48 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/audio_v2_speaker_multichan_template.c @@ -149,7 +149,7 @@ const uint8_t audio_v2_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -247,7 +247,7 @@ struct audio_entity_info audio_entity_table[] = { .ep = AUDIO_OUT_EP }, }; -void audio_v2_init(uint8_t busid, uintptr_t reg_base) +void audio_v2_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, audio_v2_descriptor); usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2)); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2.c b/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2.c deleted file mode 100644 index c4c6ee5..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * Copyright (c) 2024, Egahp - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "bootuf2.h" -#include "usbd_core.h" - -char file_INFO[] = { - "CherryUSB UF2 BOOT\r\n" - "Model: " CONFIG_PRODUCT "\r\n" - "Board-ID: " CONFIG_BOARD "\r\n" -}; - -const char file_IDEX[] = { - "\n" - "" - "" - "" - "" - "\n" -}; - -const char file_JOIN[] = { - "\n" - "" - "" - "" - "" - "\n" -}; - -const char file_ID__[12] = BOOTUF2_FAMILYID_ARRAY; - -static struct bootuf2_FILE files[] = { - [0] = { .Name = file_ID__, .Content = NULL, .FileSize = 0 }, - [1] = { .Name = "INFO_UF2TXT", .Content = file_INFO, .FileSize = sizeof(file_INFO) - 1 }, - [2] = { .Name = "INDEX HTM", .Content = file_IDEX, .FileSize = sizeof(file_IDEX) - 1 }, - [3] = { .Name = "JOIN HTM", .Content = file_JOIN, .FileSize = sizeof(file_JOIN) - 1 }, -}; - -struct bootuf2_data { - const struct bootuf2_DBR *const DBR; - struct bootuf2_STATE *const STATE; - uint8_t *const fbuff; - uint8_t *const erase; - size_t page_count; - uint8_t *const cache; - const size_t cache_size; - uint32_t cached_address; - size_t cached_bytes; -}; - -/*!< define DBRs */ -static const struct bootuf2_DBR bootuf2_DBR = { - .JMPInstruction = { 0xEB, 0x3C, 0x90 }, - .OEM = "UF2 UF2 ", - .BPB = { - .BytesPerSector = CONFIG_BOOTUF2_SECTOR_SIZE, - .SectorsPerCluster = CONFIG_BOOTUF2_SECTOR_PER_CLUSTER, - .ReservedSectors = CONFIG_BOOTUF2_SECTOR_RESERVED, - .NumberOfFAT = CONFIG_BOOTUF2_NUM_OF_FAT, - .RootEntries = CONFIG_BOOTUF2_ROOT_ENTRIES, - .Sectors = (BOOTUF2_SECTORS(0) > 0xFFFF) ? 0 : BOOTUF2_SECTORS(0), - .MediaDescriptor = 0xF8, - .SectorsPerFAT = BOOTUF2_SECTORS_PER_FAT(0), - .SectorsPerTrack = 1, - .Heads = 1, - .HiddenSectors = 0, - .SectorsOver32MB = (BOOTUF2_SECTORS(0) > 0xFFFF) ? BOOTUF2_SECTORS(0) : 0, - .BIOSDrive = 0x80, - .Reserved = 0, - .ExtendBootSignature = 0x29, - .VolumeSerialNumber = 0x00420042, - .VolumeLabel = "CHERRYUF2", - .FileSystem = "FAT16 ", - }, -}; - -/*!< define mask */ -static uint8_t __attribute__((aligned(4))) bootuf2_mask[BOOTUF2_BLOCKSMAX / 8 + 1] = { 0 }; - -/*!< define state */ -static struct bootuf2_STATE bootuf2_STATE = { - .NumberOfBlock = 0, - .NumberOfWritten = 0, - .Mask = bootuf2_mask, - .Enable = 1, -}; - -/*!< define flash cache */ -static uint8_t __attribute__((aligned(4))) bootuf2_disk_cache[CONFIG_BOOTUF2_CACHE_SIZE]; - -/*!< define flash buff */ -static uint8_t __attribute__((aligned(4))) bootuf2_disk_fbuff[256]; - -/*!< define erase flag buff */ -static uint8_t __attribute__((aligned(4))) bootuf2_disk_erase[BOOTUF2_DIVCEIL(CONFIG_BOOTUF2_PAGE_COUNTMAX, 8)]; - -/*!< define disk */ -static struct bootuf2_data bootuf2_disk = { - .DBR = &bootuf2_DBR, - .STATE = &bootuf2_STATE, - .fbuff = bootuf2_disk_fbuff, - .erase = bootuf2_disk_erase, - .cache = bootuf2_disk_cache, - .cache_size = sizeof(bootuf2_disk_cache), -}; - -static void fname_copy(char *dst, char const *src, uint16_t len) -{ - for (size_t i = 0; i < len; ++i) { - if (*src) - *dst++ = *src++; - else - *dst++ = ' '; - } -} - -static void fcalculate_cluster(struct bootuf2_data *ctx) -{ - /*!< init files cluster */ - uint16_t cluster_beg = 2; - for (int i = 0; i < ARRAY_SIZE(files); i++) { - files[i].ClusterBeg = cluster_beg; - files[i].ClusterEnd = -1 + cluster_beg + - BOOTUF2_DIVCEIL(files[i].FileSize, - ctx->DBR->BPB.BytesPerSector * - ctx->DBR->BPB.SectorsPerCluster); - cluster_beg = files[i].ClusterEnd + 1; - } -} - -static int ffind_by_cluster(uint32_t cluster) -{ - if (cluster >= 0xFFF0) { - return -1; - } - - for (uint32_t i = 0; i < ARRAY_SIZE(files); i++) { - if ((files[i].ClusterBeg <= cluster) && - (cluster <= files[i].ClusterEnd)) { - return i; - } - } - - return -1; -} - -static bool bootuf2block_check_writable(struct bootuf2_STATE *STATE, - struct bootuf2_BLOCK *uf2, uint32_t block_max) -{ - if (uf2->NumberOfBlock) { - if (uf2->BlockIndex < block_max) { - uint8_t mask = 1 << (uf2->BlockIndex % 8); - uint32_t pos = uf2->BlockIndex / 8; - - if ((STATE->Mask[pos] & mask) == 0) { - return true; - } - } - } - - return false; -} - -static void bootuf2block_state_update(struct bootuf2_STATE *STATE, - struct bootuf2_BLOCK *uf2, uint32_t block_max) -{ - if (uf2->NumberOfBlock) { - if (STATE->NumberOfBlock != uf2->NumberOfBlock) { - if ((uf2->NumberOfBlock >= BOOTUF2_BLOCKSMAX) || - STATE->NumberOfBlock) { - /*!< uf2 block only can be update once */ - /*!< this will cause never auto reboot */ - STATE->NumberOfBlock = 0xffffffff; - } else { - STATE->NumberOfBlock = uf2->NumberOfBlock; - } - } - - if (uf2->BlockIndex < block_max) { - uint8_t mask = 1 << (uf2->BlockIndex % 8); - uint32_t pos = uf2->BlockIndex / 8; - - if ((STATE->Mask[pos] & mask) == 0) { - STATE->Mask[pos] |= mask; - STATE->NumberOfWritten++; - } - } - } - - USB_LOG_DBG("UF2 block total %d written %d index %d\r\n", - uf2->NumberOfBlock, STATE->NumberOfWritten, uf2->BlockIndex); -} - -static bool bootuf2block_state_check(struct bootuf2_STATE *STATE) -{ - return (STATE->NumberOfWritten >= STATE->NumberOfBlock) && - STATE->NumberOfBlock; -} - -static int bootuf2_flash_flush(struct bootuf2_data *ctx) -{ - int err; - - if (ctx->cached_bytes == 0) { - return 0; - } - - err = bootuf2_flash_write(ctx->cached_address, ctx->cache, ctx->cached_bytes); - - if (err) { - USB_LOG_ERR("UF2 slot flash write error %d at offset %08lx len %d\r\n", - err, ctx->cached_address, ctx->cached_bytes); - return -1; - } - - ctx->cached_bytes = 0; - - return 0; -} - -int bootuf2_flash_write_internal(struct bootuf2_data *ctx, struct bootuf2_BLOCK *uf2) -{ - /*!< 1.cache not empty and address not continue */ - /*!< 2.cache full */ - if ((ctx->cached_bytes && ((ctx->cached_address + ctx->cached_bytes) != uf2->TargetAddress)) || - (ctx->cached_bytes == ctx->cache_size)) { - int err = bootuf2_flash_flush(ctx); - if (err) - return err; - } - - /*!< write len always is 256, cache_size always is a multiple of 256 */ - memcpy(ctx->cache + ctx->cached_bytes, uf2->Data, uf2->PayloadSize); - - ctx->cached_address = uf2->TargetAddress - ctx->cached_bytes; - ctx->cached_bytes += uf2->PayloadSize; - - return 0; -} - -void bootuf2_init(void) -{ - struct bootuf2_data *ctx; - - ctx = &bootuf2_disk; - - fcalculate_cluster(ctx); - - ctx->cached_bytes = 0; - ctx->cached_address = 0; -} - -int boot2uf2_read_sector(uint32_t start_sector, uint8_t *buff, uint32_t sector_count) -{ - struct bootuf2_data *ctx; - - ctx = &bootuf2_disk; - - while (sector_count) { - memset(buff, 0, ctx->DBR->BPB.BytesPerSector); - - uint32_t sector_relative = start_sector; - - /*!< DBR sector */ - if (start_sector == BOOTUF2_SECTOR_DBR_END) { - memcpy(buff, ctx->DBR, sizeof(struct bootuf2_DBR)); - buff[510] = 0x55; - buff[511] = 0xaa; - } - /*!< FAT sector */ - else if (start_sector < BOOTUF2_SECTOR_FAT_END(ctx->DBR)) { - uint16_t *buff16 = (uint16_t *)buff; - - sector_relative -= BOOTUF2_SECTOR_RSVD_END(ctx->DBR); - - /*!< Perform the same operation on all FAT tables */ - while (sector_relative >= ctx->DBR->BPB.SectorsPerFAT) { - sector_relative -= ctx->DBR->BPB.SectorsPerFAT; - } - - uint16_t cluster_unused = files[ARRAY_SIZE(files) - 1].ClusterEnd + 1; - uint16_t cluster_absolute_first = sector_relative * - BOOTUF2_FAT16_PER_SECTOR(ctx->DBR); - - /*!< cluster used link to chain, or unsed */ - for (uint16_t i = 0, cluster_absolute = cluster_absolute_first; - i < BOOTUF2_FAT16_PER_SECTOR(ctx->DBR); - i++, cluster_absolute++) { - if (cluster_absolute >= cluster_unused) - buff16[i] = 0; - else - buff16[i] = cluster_absolute + 1; - } - - /*!< cluster 0 and 1 */ - if (sector_relative == 0) { - buff[0] = ctx->DBR->BPB.MediaDescriptor; - buff[1] = 0xff; - buff16[1] = 0xffff; - } - - /*!< cluster end of file */ - for (uint32_t i = 0; i < ARRAY_SIZE(files); i++) { - uint16_t cluster_file_last = files[i].ClusterEnd; - - if (cluster_file_last >= cluster_absolute_first) { - uint16_t idx = cluster_file_last - cluster_absolute_first; - if (idx < BOOTUF2_FAT16_PER_SECTOR(ctx->DBR)) { - buff16[idx] = 0xffff; - } - } - } - } - /*!< root entries */ - else if (start_sector < BOOTUF2_SECTOR_ROOT_END(ctx->DBR)) { - sector_relative -= BOOTUF2_SECTOR_FAT_END(ctx->DBR); - - struct bootuf2_ENTRY *ent = (void *)buff; - int remain_entries = BOOTUF2_ENTRY_PER_SECTOR(ctx->DBR); - - uint32_t file_index_first; - - /*!< volume label entry */ - if (sector_relative == 0) { - fname_copy(ent->Name, (char const *)ctx->DBR->BPB.VolumeLabel, 11); - ent->Attribute = 0x28; - ent++; - remain_entries--; - file_index_first = 0; - } else { - /*!< -1 to account for volume label in first sector */ - file_index_first = sector_relative * BOOTUF2_ENTRY_PER_SECTOR(ctx->DBR) - 1; - } - - for (uint32_t idx = file_index_first; - (remain_entries > 0) && (idx < ARRAY_SIZE(files)); - idx++, ent++) { - const uint32_t cluster_beg = files[idx].ClusterBeg; - - const struct bootuf2_FILE *f = &files[idx]; - - if ((0 == f->FileSize) && - (0 != idx)) { - continue; - } - - fname_copy(ent->Name, f->Name, 11); - ent->Attribute = 0x05; - ent->CreateTimeTeenth = BOOTUF2_SECONDS_INT % 2 * 100; - ent->CreateTime = BOOTUF2_DOS_TIME; - ent->CreateDate = BOOTUF2_DOS_DATE; - ent->LastAccessDate = BOOTUF2_DOS_DATE; - ent->FirstClustH16 = cluster_beg >> 16; - ent->UpdateTime = BOOTUF2_DOS_TIME; - ent->UpdateDate = BOOTUF2_DOS_DATE; - ent->FirstClustL16 = cluster_beg & 0xffff; - ent->FileSize = f->FileSize; - } - } - /*!< data */ - else if (start_sector < BOOTUF2_SECTOR_DATA_END(ctx->DBR)) { - sector_relative -= BOOTUF2_SECTOR_ROOT_END(ctx->DBR); - - int fid = ffind_by_cluster(2 + sector_relative / ctx->DBR->BPB.SectorsPerCluster); - - if (fid >= 0) { - const struct bootuf2_FILE *f = &files[fid]; - - uint32_t sector_relative_file = - sector_relative - - (files[fid].ClusterBeg - 2) * ctx->DBR->BPB.SectorsPerCluster; - - size_t fcontent_offset = sector_relative_file * ctx->DBR->BPB.BytesPerSector; - size_t fcontent_length = f->FileSize; - - if (fcontent_length > fcontent_offset) { - const void *src = (void *)((uint8_t *)(f->Content) + fcontent_offset); - size_t copy_size = fcontent_length - fcontent_offset; - - if (copy_size > ctx->DBR->BPB.BytesPerSector) { - copy_size = ctx->DBR->BPB.BytesPerSector; - } - - memcpy(buff, src, copy_size); - } - } - } - /*!< unknown sector, ignore */ - - start_sector++; - sector_count--; - buff += ctx->DBR->BPB.BytesPerSector; - } - - return 0; -} - -int bootuf2_write_sector(uint32_t start_sector, const uint8_t *buff, uint32_t sector_count) -{ - struct bootuf2_data *ctx; - - ctx = &bootuf2_disk; - - while (sector_count) { - struct bootuf2_BLOCK *uf2 = (void *)buff; - - if (!((uf2->MagicStart0 == BOOTUF2_MAGIC_START0) && - (uf2->MagicStart1 == BOOTUF2_MAGIC_START1) && - (uf2->MagicEnd == BOOTUF2_MAGIC_END) && - (uf2->Flags & BOOTUF2_FLAG_FAMILID_PRESENT) && - !(uf2->Flags & BOOTUF2_FLAG_NOT_MAIN_FLASH))) { - goto next; - } - - if (uf2->FamilyID == CONFIG_BOOTUF2_FAMILYID) { - if (bootuf2block_check_writable(ctx->STATE, uf2, CONFIG_BOOTUF2_FLASHMAX)) { - bootuf2_flash_write_internal(ctx, uf2); - bootuf2block_state_update(ctx->STATE, uf2, CONFIG_BOOTUF2_FLASHMAX); - } else { - USB_LOG_DBG("UF2 block %d already written\r\n", - uf2->BlockIndex); - } - } else { - USB_LOG_DBG("UF2 block illegal id %08x\r\n", uf2->FamilyID); - } - - next: - start_sector++; - sector_count--; - buff += ctx->DBR->BPB.BytesPerSector; - } - - return 0; -} - -uint16_t bootuf2_get_sector_size(void) -{ - return bootuf2_disk.DBR->BPB.BytesPerSector; -} - -uint32_t bootuf2_get_sector_count(void) -{ - return bootuf2_disk.DBR->BPB.SectorsOver32MB + bootuf2_disk.DBR->BPB.Sectors; -} - -bool bootuf2_is_write_done(void) -{ - if (bootuf2block_state_check(bootuf2_disk.STATE)) { - bootuf2_flash_flush(&bootuf2_disk); - USB_LOG_DBG("UF2 update ok\r\n"); - return true; - } else { - return false; - } -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2.h b/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2.h deleted file mode 100644 index ec31d3e..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * Copyright (c) 2024, Egahp - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef BOOTUF2_H -#define BOOTUF2_H - -#include -#include -#include -#include -#include -#include - -#ifndef __PACKED -#define __PACKED __attribute__((packed)) -#endif - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(array) \ - ((int)((sizeof(array) / sizeof((array)[0])))) -#endif - -struct bootuf2_BLOCK -{ - // 32 byte header - uint32_t MagicStart0; - uint32_t MagicStart1; - uint32_t Flags; - uint32_t TargetAddress; - uint32_t PayloadSize; - uint32_t BlockIndex; - uint32_t NumberOfBlock; - uint32_t FamilyID; // or file_size - uint8_t Data[476]; - uint32_t MagicEnd; -} __PACKED; -//BUILD_ASSERT(sizeof(struct bootuf2_BLOCK) == 512, "bootuf2_BLOCK not sector sized"); - -struct bootuf2_STATE -{ - uint32_t NumberOfBlock; - uint32_t NumberOfWritten; - uint8_t *const Mask; - uint8_t Enable; -}; - -struct bootuf2_DBR -{ - /*!< offset 0 */ - uint8_t JMPInstruction[3]; - /*!< offset 3 */ - uint8_t OEM[8]; - /*!< offset 11 */ - struct - { - uint16_t BytesPerSector; - uint8_t SectorsPerCluster; - uint16_t ReservedSectors; - uint8_t NumberOfFAT; - uint16_t RootEntries; - uint16_t Sectors; - uint8_t MediaDescriptor; - uint16_t SectorsPerFAT; - uint16_t SectorsPerTrack; - uint16_t Heads; - uint32_t HiddenSectors; - uint32_t SectorsOver32MB; - uint8_t BIOSDrive; - uint8_t Reserved; - uint8_t ExtendBootSignature; - uint32_t VolumeSerialNumber; - uint8_t VolumeLabel[11]; - uint8_t FileSystem[8]; - } __PACKED BPB; - /*!< offset 62 */ - /*!< BootLoader */ - /*!< offset 511 */ - /*!< 0x55 0xAA */ -} __PACKED; -//BUILD_ASSERT(sizeof(struct bootuf2_DBR) == 62, "bootuf2_DBR size must be 62 byte"); - -struct bootuf2_ENTRY -{ - char Name[11]; - uint8_t Attribute; - uint8_t NTReserved; - uint8_t CreateTimeTeenth; - uint16_t CreateTime; - uint16_t CreateDate; - uint16_t LastAccessDate; - uint16_t FirstClustH16; - uint16_t UpdateTime; - uint16_t UpdateDate; - uint16_t FirstClustL16; - uint32_t FileSize; -} __PACKED; -//BUILD_ASSERT(sizeof(struct bootuf2_ENTRY) == 32, "bootuf2_ENTRY size must be 32 byte"); - -struct bootuf2_FILE -{ - const char *const Name; - const void *const Content; - uint32_t FileSize; - uint16_t ClusterBeg; - uint16_t ClusterEnd; -}; - -#define BOOTUF2_DIVCEIL(_v, _d) (((_v) / (_d)) + ((_v) % (_d) ? 1 : 0)) - -#define BOOTUF2_MAGIC_START0 0x0A324655u -#define BOOTUF2_MAGIC_START1 0x9E5D5157u -#define BOOTUF2_MAGIC_SERIAL 0x251B18BDu -#define BOOTUF2_MAGIC_END 0x0AB16F30u - -#define BOOTUF2_FLAG_NOT_MAIN_FLASH 0x00000001u -#define BOOTUF2_FLAG_FILE_CONTAINER 0x00001000u -#define BOOTUF2_FLAG_FAMILID_PRESENT 0x00002000u -#define BOOTUF2_FLAG_MD5_PRESENT 0x00004000u - -#define BOOTUF2_CMD_READ 0 -#define BOOTUF2_CMD_SYNC 1 - -#define BOOTUF2_BLOCKSMAX (((CONFIG_BOOTUF2_FLASHMAX) / 256) + (((CONFIG_BOOTUF2_FLASHMAX) % 256) ? 1 : 0)) - -#define BOOTUF2_FAMILYID_POSNUM(n) (((CONFIG_BOOTUF2_FAMILYID) / (0x10000000 >> ((n) * 4))) % 0x10) -#define BOOTUF2_FAMILYID_ARRAY \ - { \ - ((BOOTUF2_FAMILYID_POSNUM(0) >= 10) ? BOOTUF2_FAMILYID_POSNUM(0) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(0) + '0'), \ - ((BOOTUF2_FAMILYID_POSNUM(1) >= 10) ? BOOTUF2_FAMILYID_POSNUM(1) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(1) + '0'), \ - ((BOOTUF2_FAMILYID_POSNUM(2) >= 10) ? BOOTUF2_FAMILYID_POSNUM(2) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(2) + '0'), \ - ((BOOTUF2_FAMILYID_POSNUM(3) >= 10) ? BOOTUF2_FAMILYID_POSNUM(3) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(3) + '0'), \ - ((BOOTUF2_FAMILYID_POSNUM(4) >= 10) ? BOOTUF2_FAMILYID_POSNUM(4) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(4) + '0'), \ - ((BOOTUF2_FAMILYID_POSNUM(5) >= 10) ? BOOTUF2_FAMILYID_POSNUM(5) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(5) + '0'), \ - ((BOOTUF2_FAMILYID_POSNUM(6) >= 10) ? BOOTUF2_FAMILYID_POSNUM(6) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(6) + '0'), \ - ((BOOTUF2_FAMILYID_POSNUM(7) >= 10) ? BOOTUF2_FAMILYID_POSNUM(7) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(7) + '0'), \ - ('I'), \ - ('D'), \ - (' '), \ - ('\0'), \ - }; - -#define BOOTUF2_FAT16_PER_SECTOR(pDBR) (pDBR->BPB.BytesPerSector / 2) -#define BOOTUF2_ENTRY_PER_SECTOR(pDBR) (pDBR->BPB.BytesPerSector / sizeof(struct bootuf2_ENTRY)) -#define BOOTUF2_CLUSTERSMAX (0xFFF0 - 2) -#define BOOTUF2_SECTOR_DBR_END (0) -#define BOOTUF2_SECTOR_RSVD_END(pDBR) BOOTUF2_SECTOR_DBR_END + (pDBR->BPB.ReservedSectors) -#define BOOTUF2_SECTOR_FAT_END(pDBR) BOOTUF2_SECTOR_RSVD_END(pDBR) + (pDBR->BPB.SectorsPerFAT * pDBR->BPB.NumberOfFAT) -#define BOOTUF2_SECTOR_ROOT_END(pDBR) BOOTUF2_SECTOR_FAT_END(pDBR) + (pDBR->BPB.RootEntries / (pDBR->BPB.BytesPerSector / sizeof(struct bootuf2_ENTRY))) -#define BOOTUF2_SECTOR_DATA_END(pDBR) (pDBR->BPB.Sectors + pDBR->BPB.SectorsOver32MB) - -#define BOOTUF2_SECTORS_PER_FAT(n) \ - BOOTUF2_DIVCEIL(BOOTUF2_CLUSTERSMAX, (CONFIG_BOOTUF2_SECTOR_SIZE / 2)) -#define BOOTUF2_SECTORS_FOR_ENTRIES(n) \ - (CONFIG_BOOTUF2_ROOT_ENTRIES / (CONFIG_BOOTUF2_SECTOR_SIZE / sizeof(struct bootuf2_ENTRY))) -#define BOOTUF2_SECTORS(n) \ - (CONFIG_BOOTUF2_SECTOR_RESERVED + \ - CONFIG_BOOTUF2_NUM_OF_FAT * BOOTUF2_SECTORS_PER_FAT(n) + \ - BOOTUF2_SECTORS_FOR_ENTRIES(n) + \ - BOOTUF2_CLUSTERSMAX * CONFIG_BOOTUF2_SECTOR_PER_CLUSTER) - -#define BOOTUF2_YEAR_INT ( \ - (__DATE__[7u] - '0') * 1000u + \ - (__DATE__[8u] - '0') * 100u + \ - (__DATE__[9u] - '0') * 10u + \ - (__DATE__[10u] - '0') * 1u) - -#define BOOTUF2_MONTH_INT ( \ - (__DATE__[2u] == 'n' && __DATE__[1u] == 'a') ? 1u /*Jan*/ \ - : (__DATE__[2u] == 'b') ? 2u /*Feb*/ \ - : (__DATE__[2u] == 'r' && __DATE__[1u] == 'a') ? 3u /*Mar*/ \ - : (__DATE__[2u] == 'r') ? 4u /*Apr*/ \ - : (__DATE__[2u] == 'y') ? 5u /*May*/ \ - : (__DATE__[2u] == 'n') ? 6u /*Jun*/ \ - : (__DATE__[2u] == 'l') ? 7u /*Jul*/ \ - : (__DATE__[2u] == 'g') ? 8u /*Aug*/ \ - : (__DATE__[2u] == 'p') ? 9u /*Sep*/ \ - : (__DATE__[2u] == 't') ? 10u /*Oct*/ \ - : (__DATE__[2u] == 'v') ? 11u /*Nov*/ \ - : 12u /*Dec*/) - -#define BOOTUF2_DAY_INT ( \ - (__DATE__[4u] == ' ' ? 0 : __DATE__[4u] - '0') * 10u + \ - (__DATE__[5u] - '0')) - -#define BOOTUF2_HOUR_INT ( \ - (__TIME__[0u] == '?' ? 0 : __TIME__[0u] - '0') * 10u + (__TIME__[1u] == '?' ? 0 : __TIME__[1u] - '0')) - -#define BOOTUF2_MINUTE_INT ( \ - (__TIME__[3u] == '?' ? 0 : __TIME__[3u] - '0') * 10u + (__TIME__[4u] == '?' ? 0 : __TIME__[4u] - '0')) - -#define BOOTUF2_SECONDS_INT ( \ - (__TIME__[6u] == '?' ? 0 : __TIME__[6u] - '0') * 10u + (__TIME__[7u] == '?' ? 0 : __TIME__[7u] - '0')) - -#define BOOTUF2_DOS_DATE ( \ - ((BOOTUF2_YEAR_INT - 1980u) << 9u) | \ - (BOOTUF2_MONTH_INT << 5u) | \ - (BOOTUF2_DAY_INT << 0u)) - -#define BOOTUF2_DOS_TIME ( \ - (BOOTUF2_HOUR_INT << 11u) | \ - (BOOTUF2_MINUTE_INT << 5u) | \ - (BOOTUF2_SECONDS_INT << 0u)) - -void bootuf2_init(void); -int boot2uf2_read_sector(uint32_t start_sector, uint8_t *buff, uint32_t sector_count); -int bootuf2_write_sector(uint32_t start_sector, const uint8_t *buff, uint32_t sector_count); -uint16_t bootuf2_get_sector_size(void); -uint32_t bootuf2_get_sector_count(void); - -bool bootuf2_is_write_done(void); - -void boot2uf2_flash_init(void); -int bootuf2_flash_write(uint32_t address, const uint8_t *data, size_t size); - -#endif /* BOOTUF2_H */ diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2_config.h b/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2_config.h deleted file mode 100644 index 307d09d..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/bootuf2_config.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef BOOTUF2_CONFIG_H -#define BOOTUF2_CONFIG_H - -#define CONFIG_PRODUCT "CherryUSB" -#define CONFIG_BOARD "CherryUSB BOARD" -#define CONFIG_BOOTUF2_INDEX_URL "https://github.com/cherry-embedded" -#define CONFIG_BOOTUF2_JOIN_URL "http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GyH2M5XfWTHQzmZis4ClpgvfdObPrvtk&authKey=LmcLhfno%2BiW51wmgVC%2F8WoYwUXqiclzWDHMU1Jy1d6S8cECJ4Q7bfJ%2FTe67RLakI&noverify=0&group_code=642693751" - -#define CONFIG_BOOTUF2_CACHE_SIZE 4096 -#define CONFIG_BOOTUF2_SECTOR_SIZE 512 -#define CONFIG_BOOTUF2_SECTOR_PER_CLUSTER 2 -#define CONFIG_BOOTUF2_SECTOR_RESERVED 1 -#define CONFIG_BOOTUF2_NUM_OF_FAT 2 -#define CONFIG_BOOTUF2_ROOT_ENTRIES 64 - -#define CONFIG_BOOTUF2_FAMILYID 0xFFFFFFFF -#define CONFIG_BOOTUF2_FLASHMAX 0x800000 -#define CONFIG_BOOTUF2_PAGE_COUNTMAX 1024 - -#endif \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/cherryuf2.png b/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/cherryuf2.png deleted file mode 100644 index aff7ee4..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/cherryuf2.png and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c deleted file mode 100644 index fbada2d..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/demo/bootuf2/msc_bootuf2_template.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbd_core.h" -#include "usbd_msc.h" -#include "bootuf2.h" - -#define MSC_IN_EP 0x81 -#define MSC_OUT_EP 0x02 - -#define USBD_VID 0xFFFF -#define USBD_PID 0xFFFF -#define USBD_MAX_POWER 100 -#define USBD_LANGID_STRING 1033 - -#define USB_CONFIG_SIZE (9 + MSC_DESCRIPTOR_LEN) - -#ifdef CONFIG_USB_HS -#define MSC_MAX_MPS 512 -#else -#define MSC_MAX_MPS 64 -#endif - -const uint8_t msc_bootuf2_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - MSC_DESCRIPTOR_INIT(0x00, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'U', 0x00, /* wcChar10 */ - 'F', 0x00, /* wcChar11 */ - '2', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; - -static void usbd_event_handler(uint8_t busid, uint8_t event) -{ - switch (event) { - case USBD_EVENT_RESET: - break; - case USBD_EVENT_CONNECTED: - break; - case USBD_EVENT_DISCONNECTED: - break; - case USBD_EVENT_RESUME: - break; - case USBD_EVENT_SUSPEND: - break; - case USBD_EVENT_CONFIGURED: - bootuf2_init(); - break; - case USBD_EVENT_SET_REMOTE_WAKEUP: - break; - case USBD_EVENT_CLR_REMOTE_WAKEUP: - break; - - default: - break; - } -} - -void usbd_msc_get_cap(uint8_t busid, uint8_t lun, uint32_t *block_num, uint32_t *block_size) -{ - *block_num = bootuf2_get_sector_count(); - *block_size = bootuf2_get_sector_size(); - - USB_LOG_INFO("sector count:%d, sector size:%d\n", *block_num, *block_size); -} -int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length) -{ - boot2uf2_read_sector(sector, buffer, length / bootuf2_get_sector_size()); - return 0; -} - -int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length) -{ - bootuf2_write_sector(sector, buffer, length / bootuf2_get_sector_size()); - return 0; -} - -static struct usbd_interface intf0; - -void msc_bootuf2_init(uint8_t busid, uintptr_t reg_base) -{ - boot2uf2_flash_init(); - usbd_desc_register(busid, msc_bootuf2_descriptor); - usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP)); - - usbd_initialize(busid, reg_base, usbd_event_handler); -} - -void boot2uf2_flash_init(void) -{ -} - -int bootuf2_flash_write(uint32_t address, const uint8_t *data, size_t size) -{ - USB_LOG_INFO("address:%08x, size:%d\n", address, size); - return 0; -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c index 148f324..93a3dc1 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_hid_msc_template.c @@ -5,7 +5,7 @@ */ #include "usbd_core.h" #include "usbd_msc.h" -#include "usbd_cdc_acm.h" +#include "usbd_cdc.h" #include "usbd_hid.h" /*!< endpoint address */ @@ -147,7 +147,7 @@ const uint8_t cdc_acm_hid_msc_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -301,7 +301,7 @@ struct usbd_interface intf1; struct usbd_interface intf2; struct usbd_interface intf3; -void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uintptr_t reg_base) +void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, cdc_acm_hid_msc_descriptor); @@ -332,15 +332,14 @@ void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uintptr_t reg_base) */ void hid_mouse_test(uint8_t busid) { - if(usb_device_is_configured(busid) == false) { - return; - } /*!< move mouse pointer */ mouse_cfg.x += 10; mouse_cfg.y = 0; - + int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4); + if (ret < 0) { + return; + } hid_state = HID_STATE_BUSY; - usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4); while (hid_state == HID_STATE_BUSY) { } } diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c index a5ad404..7ab5810 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_msc_template.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "usbd_core.h" -#include "usbd_cdc_acm.h" +#include "usbd_cdc.h" #include "usbd_msc.h" /*!< endpoint address */ @@ -58,7 +58,7 @@ static const uint8_t device_quality_descriptor[] = { 0x02, 0x01, 0x40, - 0x00, + 0x01, 0x00, }; @@ -173,7 +173,7 @@ static const uint8_t cdc_msc_descriptor[] = { 0x02, 0x01, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -247,7 +247,7 @@ struct usbd_interface intf0; struct usbd_interface intf1; struct usbd_interface intf2; -void cdc_acm_msc_init(uint8_t busid, uintptr_t reg_base) +void cdc_acm_msc_init(uint8_t busid, uint32_t reg_base) { #ifdef CONFIG_USBDEV_ADVANCE_DESC usbd_desc_register(busid, &cdc_msc_descriptor); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c index 13f67f4..fa3eb65 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_multi_template.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "usbd_core.h" -#include "usbd_cdc_acm.h" +#include "usbd_cdc.h" /*!< endpoint address */ #define CDC_IN_EP 0x81 @@ -113,7 +113,7 @@ static const uint8_t cdc_descriptor[] = { 0x02, 0x01, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -223,7 +223,7 @@ struct usbd_interface intf5; struct usbd_interface intf6; struct usbd_interface intf7; -void cdc_acm_multi_init(uint8_t busid, uintptr_t reg_base) +void cdc_acm_multi_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, cdc_descriptor); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_template.c index a13d96a..490b716 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/cdc_acm_template.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "usbd_core.h" -#include "usbd_cdc_acm.h" +#include "usbd_cdc.h" /*!< endpoint address */ #define CDC_IN_EP 0x81 @@ -98,7 +98,7 @@ static const uint8_t cdc_descriptor[] = { 0x02, 0x01, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -174,7 +174,7 @@ struct usbd_endpoint cdc_in_ep = { static struct usbd_interface intf0; static struct usbd_interface intf1; -void cdc_acm_init(uint8_t busid, uintptr_t reg_base) +void cdc_acm_init(uint8_t busid, uint32_t reg_base) { const uint8_t data[10] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 }; diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c index 9147c92..fd58a29 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/cdc_ecm_template.c @@ -6,10 +6,6 @@ #include "usbd_core.h" #include "usbd_cdc_ecm.h" -#ifndef CONFIG_USBDEV_CDC_ECM_USING_LWIP -#error "Please enable CONFIG_USBDEV_CDC_ECM_USING_LWIP for this demo" -#endif - /*!< endpoint address */ #define CDC_IN_EP 0x81 #define CDC_OUT_EP 0x02 @@ -128,7 +124,7 @@ static const uint8_t cdc_ecm_descriptor[] = { 0x02, 0x01, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -226,12 +222,12 @@ void cdc_ecm_lwip_init(void) while (!netif_is_up(netif)) { } - while (dhserv_init(&dhcp_config)) {} + // while (dhserv_init(&dhcp_config)) {} - while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {} + // while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {} } -void usbd_cdc_ecm_data_recv_done(uint32_t len) +void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len) { } @@ -273,7 +269,7 @@ struct usbd_interface intf1; * sudo ifconfig enxaabbccddeeff up * sudo dhcpclient enxaabbccddeeff */ -void cdc_ecm_init(uint8_t busid, uintptr_t reg_base) +void cdc_ecm_init(uint8_t busid, uint32_t reg_base) { cdc_ecm_lwip_init(); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c index a83a755..cb4aef6 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/cdc_rndis_template.c @@ -6,10 +6,6 @@ #include "usbd_core.h" #include "usbd_rndis.h" -#ifndef CONFIG_USBDEV_RNDIS_USING_LWIP -#error "Please enable CONFIG_USBDEV_RNDIS_USING_LWIP for this demo" -#endif - /*!< endpoint address */ #define CDC_IN_EP 0x81 #define CDC_OUT_EP 0x02 @@ -104,7 +100,7 @@ static const uint8_t cdc_descriptor[] = { 0x02, 0x01, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -174,7 +170,7 @@ rt_err_t rt_usbd_rndis_eth_tx(rt_device_t dev, struct pbuf *p) return usbd_rndis_eth_tx(p); } -void usbd_rndis_data_recv_done(uint32_t len) +void usbd_rndis_data_recv_done(void) { eth_device_ready(&rndis_dev); } @@ -262,12 +258,12 @@ void rndis_lwip_init(void) while (!netif_is_up(netif)) { } - while (dhserv_init(&dhcp_config)) {} + // while (dhserv_init(&dhcp_config)) {} - while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {} + // while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {} } -void usbd_rndis_data_recv_done(uint32_t len) +void usbd_rndis_data_recv_done(void) { } @@ -308,7 +304,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event) struct usbd_interface intf0; struct usbd_interface intf1; -void cdc_rndis_init(uint8_t busid, uintptr_t reg_base) +void cdc_rndis_init(uint8_t busid, uint32_t reg_base) { #ifdef RT_USING_LWIP rt_usbd_rndis_init(); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c index cd3ed53..1d94702 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/dfu_with_st_tool_template.c @@ -136,7 +136,7 @@ const uint8_t dfu_flash_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -169,7 +169,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event) struct usbd_interface intf0; -void dfu_flash_init(uint8_t busid, uintptr_t reg_base) +void dfu_flash_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, dfu_flash_descriptor); usbd_add_interface(busid, usbd_dfu_init_intf(&intf0)); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c index e5874c7..92bca37 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/hid_custom_inout_template.c @@ -146,7 +146,7 @@ static const uint8_t hid_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -272,7 +272,7 @@ static struct usbd_endpoint custom_out_ep = { */ struct usbd_interface intf0; -void hid_custom_init(uint8_t busid, uintptr_t reg_base) +void hid_custom_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, hid_descriptor); usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_custom_report_desc, HID_CUSTOM_REPORT_DESC_SIZE)); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c index 4d1afc3..5e106f2 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/hid_keyboard_template.c @@ -122,7 +122,7 @@ static const uint8_t hid_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -221,7 +221,7 @@ static struct usbd_endpoint hid_in_ep = { struct usbd_interface intf0; -void hid_keyboard_init(uint8_t busid, uintptr_t reg_base) +void hid_keyboard_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, hid_descriptor); usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE)); @@ -236,13 +236,12 @@ void hid_keyboard_test(uint8_t busid) { const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 }; - if(usb_device_is_configured(busid) == false) { + memcpy(write_buffer, sendbuffer, 8); + int ret = usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8); + if (ret < 0) { return; } - - memcpy(write_buffer, sendbuffer, 8); hid_state = HID_STATE_BUSY; - usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8); while (hid_state == HID_STATE_BUSY) { } } diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/hid_mouse_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/hid_mouse_template.c index 564d171..d335601 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/hid_mouse_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/hid_mouse_template.c @@ -9,7 +9,7 @@ /*!< endpoint address */ #define HID_INT_EP 0x81 #define HID_INT_EP_SIZE 4 -#define HID_INT_EP_INTERVAL 1 +#define HID_INT_EP_INTERVAL 10 #define USBD_VID 0xffff #define USBD_PID 0xffff @@ -126,7 +126,7 @@ const uint8_t hid_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -239,7 +239,7 @@ static struct usbd_endpoint hid_in_ep = { struct usbd_interface intf0; -void hid_mouse_init(uint8_t busid, uintptr_t reg_base) +void hid_mouse_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, hid_descriptor); usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE)); @@ -254,65 +254,25 @@ void hid_mouse_init(uint8_t busid, uintptr_t reg_base) mouse_cfg.y = 0; } -#define CURSOR_STEP 2U -#define CURSOR_WIDTH 20U - -void draw_circle(uint8_t *buf) -{ - static int32_t move_cnt = 0; - static uint8_t step_x_y = 0; - static int8_t x = 0, y = 0; - - move_cnt++; - if (move_cnt > CURSOR_WIDTH) { - step_x_y++; - step_x_y = step_x_y % 4; - move_cnt = 0; - } - switch (step_x_y) { - case 0: { - y = 0; - x = CURSOR_STEP; - - } break; - - case 1: { - x = 0; - y = CURSOR_STEP; - - } break; - - case 2: { - y = 0; - x = (int8_t)(-CURSOR_STEP); - - } break; - - case 3: { - x = 0; - y = (int8_t)(-CURSOR_STEP); - - } break; - } - - buf[0] = 0; - buf[1] = x; - buf[2] = y; - buf[3] = 0; -} - -/* https://cps-check.com/cn/polling-rate-check */ +/** + * @brief hid mouse test + * @pre none + * @param[in] none + * @retval none + */ void hid_mouse_test(uint8_t busid) { - if(usb_device_is_configured(busid) == false) { - return; - } - int counter = 0; while (counter < 1000) { - draw_circle((uint8_t *)&mouse_cfg); + /*!< move mouse pointer */ + mouse_cfg.x += 40; + mouse_cfg.y += 0; + + int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4); + if (ret < 0) { + return; + } hid_state = HID_STATE_BUSY; - usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4); while (hid_state == HID_STATE_BUSY) { } diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c deleted file mode 100644 index 786c324..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/demo/hid_remote_wakeup_template.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbd_core.h" -#include "usbd_hid.h" - -/*!< endpoint address */ -#define HID_INT_EP 0x81 -#define HID_INT_EP_SIZE 4 -#define HID_INT_EP_INTERVAL 1 - -#define USBD_VID 0xffff -#define USBD_PID 0xffff -#define USBD_MAX_POWER 100 -#define USBD_LANGID_STRING 1033 - -/*!< config descriptor size */ -#define USB_HID_CONFIG_DESC_SIZ 34 -/*!< report descriptor size */ -#define HID_MOUSE_REPORT_DESC_SIZE 74 - -/*!< global descriptor */ -const uint8_t hid_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER), - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'H', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'D', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; - -/*!< hid mouse report descriptor */ -static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = { - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x02, // USAGE (Mouse) - 0xA1, 0x01, // COLLECTION (Application) - 0x09, 0x01, // USAGE (Pointer) - - 0xA1, 0x00, // COLLECTION (Physical) - 0x05, 0x09, // USAGE_PAGE (Button) - 0x19, 0x01, // USAGE_MINIMUM (Button 1) - 0x29, 0x03, // USAGE_MAXIMUM (Button 3) - - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x95, 0x03, // REPORT_COUNT (3) - 0x75, 0x01, // REPORT_SIZE (1) - - 0x81, 0x02, // INPUT (Data,Var,Abs) - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x05, // REPORT_SIZE (5) - 0x81, 0x01, // INPUT (Cnst,Var,Abs) - - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x30, // USAGE (X) - 0x09, 0x31, // USAGE (Y) - 0x09, 0x38, - - 0x15, 0x81, // LOGICAL_MINIMUM (-127) - 0x25, 0x7F, // LOGICAL_MAXIMUM (127) - 0x75, 0x08, // REPORT_SIZE (8) - 0x95, 0x03, // REPORT_COUNT (2) - - 0x81, 0x06, // INPUT (Data,Var,Rel) - 0xC0, 0x09, - 0x3c, 0x05, - 0xff, 0x09, - - 0x01, 0x15, - 0x00, 0x25, - 0x01, 0x75, - 0x01, 0x95, - - 0x02, 0xb1, - 0x22, 0x75, - 0x06, 0x95, - 0x01, 0xb1, - - 0x01, 0xc0 // END_COLLECTION -}; - -/*!< mouse report struct */ -struct hid_mouse { - uint8_t buttons; - int8_t x; - int8_t y; - int8_t wheel; -}; - -/*!< mouse report */ -static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct hid_mouse mouse_cfg; - -#define HID_STATE_IDLE 0 -#define HID_STATE_BUSY 1 - -/*!< hid state ! Data can be sent only when state is idle */ -static volatile uint8_t hid_state = HID_STATE_IDLE; - -static void usbd_event_handler(uint8_t busid, uint8_t event) -{ - switch (event) { - case USBD_EVENT_RESET: - break; - case USBD_EVENT_CONNECTED: - break; - case USBD_EVENT_DISCONNECTED: - break; - case USBD_EVENT_RESUME: - break; - case USBD_EVENT_SUSPEND: - break; - case USBD_EVENT_CONFIGURED: - hid_state = HID_STATE_IDLE; - break; - case USBD_EVENT_SET_REMOTE_WAKEUP: - break; - case USBD_EVENT_CLR_REMOTE_WAKEUP: - break; - - default: - break; - } -} - -/* function ------------------------------------------------------------------*/ -static void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) -{ - hid_state = HID_STATE_IDLE; -} - -/*!< endpoint call back */ -static struct usbd_endpoint hid_in_ep = { - .ep_cb = usbd_hid_int_callback, - .ep_addr = HID_INT_EP -}; - -static struct usbd_interface intf0; - -void hid_mouse_init(uint8_t busid, uintptr_t reg_base) -{ - usbd_desc_register(busid, hid_descriptor); - usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE)); - usbd_add_endpoint(busid, &hid_in_ep); - - usbd_initialize(busid, reg_base, usbd_event_handler); - - /*!< init mouse report data */ - mouse_cfg.buttons = 0; - mouse_cfg.wheel = 0; - mouse_cfg.x = 0; - mouse_cfg.y = 0; -} - -#define CURSOR_STEP 2U -#define CURSOR_WIDTH 20U - -void draw_circle(uint8_t *buf) -{ - static int32_t move_cnt = 0; - static uint8_t step_x_y = 0; - static int8_t x = 0, y = 0; - - move_cnt++; - if (move_cnt > CURSOR_WIDTH) { - step_x_y++; - step_x_y = step_x_y % 4; - move_cnt = 0; - } - switch (step_x_y) { - case 0: { - y = 0; - x = CURSOR_STEP; - - } break; - - case 1: { - x = 0; - y = CURSOR_STEP; - - } break; - - case 2: { - y = 0; - x = (int8_t)(-CURSOR_STEP); - - } break; - - case 3: { - x = 0; - y = (int8_t)(-CURSOR_STEP); - - } break; - } - - buf[0] = 0; - buf[1] = x; - buf[2] = y; - buf[3] = 0; -} - -/* https://cps-check.com/cn/polling-rate-check */ -void hid_mouse_test(uint8_t busid) -{ - static uint32_t count = 1000; - int ret; - - if(usb_device_is_configured(busid) == false) { - return; - } - - // if (gpio_read_pin(GPIO_PIN) == 1) { - // ret = usbd_send_remote_wakeup(busid); - // if (ret < 0) { - // return; - // } - // count = 5000; - // } - - while (count) { - draw_circle((uint8_t *)&mouse_cfg); - hid_state = HID_STATE_BUSY; - usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4); - while (hid_state == HID_STATE_BUSY) { - } - - count--; - } -} diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/midi_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/midi_template.c index aa3b2ad..d09a943 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/midi_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/midi_template.c @@ -145,7 +145,7 @@ const uint8_t midi_descriptor[] = { 0x02, 0x01, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -202,7 +202,7 @@ struct usbd_endpoint midi_in_ep = { .ep_cb = usbd_midi_bulk_in }; -void midi_init(uint8_t busid, uintptr_t reg_base) +void midi_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, midi_descriptor); usbd_add_interface(busid, &intf0); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/msc_ram_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/msc_ram_template.c index 9021483..933cd88 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/msc_ram_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/msc_ram_template.c @@ -94,7 +94,7 @@ const uint8_t msc_ram_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -154,19 +154,12 @@ int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t * return 0; } -static struct usbd_interface intf0; +struct usbd_interface intf0; -void msc_ram_init(uint8_t busid, uintptr_t reg_base) +void msc_ram_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, msc_ram_descriptor); usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP)); usbd_initialize(busid, reg_base, usbd_event_handler); } - -#if defined(CONFIG_USBDEV_MSC_POLLING) -void msc_ram_polling(uint8_t busid) -{ - usbd_msc_polling(busid); -} -#endif \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/msc_storage_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/msc_storage_template.c index 047bad8..a335164 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/msc_storage_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/msc_storage_template.c @@ -97,7 +97,7 @@ const uint8_t msc_storage_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -154,7 +154,7 @@ int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t * return 0; } -void msc_storage_init(uint8_t busid, uintptr_t reg_base) +void msc_storage_init(uint8_t busid, uint32_t reg_base) { rt_err_t res; diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/usb_host.c b/rt-thread/components/drivers/usb/cherryusb/demo/usb_host.c index 817103d..8c8ac22 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/usb_host.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/usb_host.c @@ -120,7 +120,7 @@ void usbh_hid_callback(void *arg, int nbytes) struct usbh_hid *hid_class = (struct usbh_hid *)arg; if (nbytes > 0) { - for (int i = 0; i < nbytes; i++) { + for (size_t i = 0; i < nbytes; i++) { USB_LOG_RAW("0x%02x ", hid_buffer[i]); } USB_LOG_RAW("nbytes:%d\r\n", nbytes); @@ -254,38 +254,38 @@ delete: } #endif -#if TEST_USBH_CDC_ACM void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class) { +#if TEST_USBH_CDC_ACM usb_osal_thread_create("usbh_cdc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_acm_thread, cdc_acm_class); +#endif } void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class) { } -#endif -#if TEST_USBH_HID void usbh_hid_run(struct usbh_hid *hid_class) { +#if TEST_USBH_HID usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, hid_class); +#endif } void usbh_hid_stop(struct usbh_hid *hid_class) { } -#endif -#if TEST_USBH_MSC void usbh_msc_run(struct usbh_msc *msc_class) { +#if TEST_USBH_MSC usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class); +#endif } void usbh_msc_stop(struct usbh_msc *msc_class) { } -#endif #if TEST_USBH_AUDIO #error "commercial charge" @@ -294,26 +294,3 @@ void usbh_msc_stop(struct usbh_msc *msc_class) #if TEST_USBH_VIDEO #error "commercial charge" #endif - -#if 0 -#include "usbh_aoa.h" - -static struct aoa_string_info deviceinfo = { - .acc_manufacturer = "CherryUSB", - .acc_model = "CherryUSB", - .acc_description = "Android Open Accessory CherryUSB", - .acc_version = "1.0", - .acc_uri = "http://developer.android.com/tools/adk/index.html", - .acc_serial = "CherryUSB" -}; - -int aoa_switch(int argc, char **argv) -{ - struct usbh_hubport *hport = usbh_find_hubport(0, 1, 1); - - usbh_aoa_switch(hport, &deviceinfo); - return 0; -} - -SHELL_CMD_EXPORT_ALIAS(aoa_switch, aoa_switch, aoa_switch); -#endif \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c index 6a41162..97f1743 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/video_audiov1_hid_template.c @@ -9,8 +9,6 @@ #include "usbd_hid.h" #include "cherryusb_mjpeg.h" -#define MAX_PACKETS_IN_ONE_TRANSFER 1 - #define VIDEO_IN_EP 0x81 #define VIDEO_INT_EP 0x86 @@ -226,7 +224,7 @@ const uint8_t video_audio_hid_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -269,7 +267,7 @@ static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = { USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t audio_read_buffer[AUDIO_OUT_PACKET]; USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t audio_write_buffer[AUDIO_IN_PACKET]; -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t video_packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t video_packet_buffer[40 * 1024]; volatile bool video_tx_flag = 0; volatile bool audio_tx_flag = 0; @@ -333,10 +331,8 @@ void usbd_video_close(uint8_t busid, uint8_t intf) void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) { - if (usbd_video_stream_split_transfer(busid, ep)) { - /* one frame has done */ - video_iso_tx_busy = false; - } + //USB_LOG_RAW("actual in len:%d\r\n", nbytes); + video_iso_tx_busy = false; } static struct usbd_endpoint video_in_ep = { @@ -420,7 +416,7 @@ struct audio_entity_info audio_entity_table[] = { .ep = AUDIO_OUT_EP }, }; -void composite_init(uint8_t busid, uintptr_t reg_base) +void composite_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, video_audio_hid_descriptor); usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE)); @@ -462,30 +458,56 @@ void hid_keyboard_test(uint8_t busid) { const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 }; - if(usb_device_is_configured(busid) == false) { + memcpy(hid_write_buffer, sendbuffer, 8); + int ret = usbd_ep_start_write(busid, HID_INT_EP, hid_write_buffer, 8); + if (ret < 0) { return; } - - memcpy(hid_write_buffer, sendbuffer, 8); hid_state = HID_STATE_BUSY; - usbd_ep_start_write(busid, HID_INT_EP, hid_write_buffer, 8); while (hid_state == HID_STATE_BUSY) { } } void video_test(uint8_t busid) { - memset(video_packet_buffer, 0, sizeof(video_packet_buffer)); + uint32_t out_len; + uint32_t packets; + (void)packets; + memset(video_packet_buffer, 0, 40 * 1024); while (1) { if (video_tx_flag) { + packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg), video_packet_buffer, &out_len); +#if 1 video_iso_tx_busy = true; - usbd_video_stream_start_write(busid, VIDEO_IN_EP, &video_packet_buffer[0][0], &video_packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg)); + usbd_ep_start_write(busid, VIDEO_IN_EP, video_packet_buffer, out_len); while (video_iso_tx_busy) { if (video_tx_flag == 0) { break; } } +#else + /* dwc2 must use this method */ + for (uint32_t i = 0; i < packets; i++) { + if (i == (packets - 1)) { + video_iso_tx_busy = true; + usbd_ep_start_write(busid, VIDEO_IN_EP, &video_packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE); + while (video_iso_tx_busy) { + if (video_tx_flag == 0) { + break; + } + } + } else { + video_iso_tx_busy = true; + usbd_ep_start_write(busid, VIDEO_IN_EP, &video_packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE); + while (video_iso_tx_busy) { + if (video_tx_flag == 0) { + break; + } + } + } + } +#endif } } } \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/video_static_h264_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/video_static_h264_template.c index e325964..adfb879 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/video_static_h264_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/video_static_h264_template.c @@ -7,8 +7,6 @@ #include "usbd_video.h" #include "cherryusb_h264.h" -#define MAX_PACKETS_IN_ONE_TRANSFER 1 - #define VIDEO_IN_EP 0x81 #define VIDEO_INT_EP 0x83 @@ -131,7 +129,7 @@ const uint8_t video_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -182,10 +180,8 @@ void usbd_video_close(uint8_t busid, uint8_t intf) void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) { - if (usbd_video_stream_split_transfer(busid, ep)) { - /* one frame has done */ - iso_tx_busy = false; - } + //USB_LOG_RAW("actual in len:%d\r\n", nbytes); + iso_tx_busy = false; } static struct usbd_endpoint video_in_ep = { @@ -196,7 +192,7 @@ static struct usbd_endpoint video_in_ep = { struct usbd_interface intf0; struct usbd_interface intf1; -void video_init(uint8_t busid, uintptr_t reg_base) +void video_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, video_descriptor); usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE)); @@ -206,7 +202,7 @@ void video_init(uint8_t busid, uintptr_t reg_base) usbd_initialize(busid, reg_base, usbd_event_handler); } -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][40 * 1024]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[40 * 1024]; void video_test(uint8_t busid) { @@ -214,16 +210,40 @@ void video_test(uint8_t busid) uint32_t packets; (void)packets; - memset(packet_buffer, 0, sizeof(packet_buffer)); + memset(packet_buffer, 0, 40 * 1024); while (1) { if (tx_flag) { + packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_h264, sizeof(cherryusb_h264), packet_buffer, &out_len); +#if 1 iso_tx_busy = true; - usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_h264, sizeof(cherryusb_h264)); + usbd_ep_start_write(busid, VIDEO_IN_EP, packet_buffer, out_len); while (iso_tx_busy) { if (tx_flag == 0) { break; } } +#else + /* dwc2 must use this method */ + for (uint32_t i = 0; i < packets; i++) { + if (i == (packets - 1)) { + iso_tx_busy = true; + usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE); + while (iso_tx_busy) { + if (tx_flag == 0) { + break; + } + } + } else { + iso_tx_busy = true; + usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE); + while (iso_tx_busy) { + if (tx_flag == 0) { + break; + } + } + } + } +#endif } } } \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c index 1d2ae01..85b659d 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/video_static_mjpeg_template.c @@ -7,8 +7,6 @@ #include "usbd_video.h" #include "cherryusb_mjpeg.h" -#define MAX_PACKETS_IN_ONE_TRANSFER 1 - #define VIDEO_IN_EP 0x81 #define VIDEO_INT_EP 0x83 @@ -36,7 +34,7 @@ #define MAX_BIT_RATE (unsigned long)(WIDTH * HEIGHT * 16 * CAM_FPS) #define MAX_FRAME_SIZE (unsigned long)(WIDTH * HEIGHT * 2) -#define VS_HEADER_SIZ (unsigned int)(VIDEO_SIZEOF_VS_INPUT_HEADER_DESC(1, 1) + VIDEO_SIZEOF_VS_FORMAT_MJPEG_DESC + VIDEO_SIZEOF_VS_FRAME_MJPEG_DESC(1)) +#define VS_HEADER_SIZ (unsigned int)(VIDEO_SIZEOF_VS_INPUT_HEADER_DESC(1,1) + VIDEO_SIZEOF_VS_FORMAT_MJPEG_DESC + VIDEO_SIZEOF_VS_FRAME_MJPEG_DESC(1)) #define USB_VIDEO_DESC_SIZ (unsigned long)(9 + \ VIDEO_VC_NOEP_DESCRIPTOR_LEN + \ @@ -131,7 +129,7 @@ const uint8_t video_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -182,10 +180,8 @@ void usbd_video_close(uint8_t busid, uint8_t intf) void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) { - if (usbd_video_stream_split_transfer(busid, ep)) { - /* one frame has done */ - iso_tx_busy = false; - } + //USB_LOG_RAW("actual in len:%d\r\n", nbytes); + iso_tx_busy = false; } static struct usbd_endpoint video_in_ep = { @@ -196,7 +192,7 @@ static struct usbd_endpoint video_in_ep = { struct usbd_interface intf0; struct usbd_interface intf1; -void video_init(uint8_t busid, uintptr_t reg_base) +void video_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, video_descriptor); usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE)); @@ -206,21 +202,48 @@ void video_init(uint8_t busid, uintptr_t reg_base) usbd_initialize(busid, reg_base, usbd_event_handler); } -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[40 * 1024]; void video_test(uint8_t busid) { - memset(packet_buffer, 0, sizeof(packet_buffer)); + uint32_t out_len; + uint32_t packets; + (void)packets; + memset(packet_buffer, 0, 40 * 1024); while (1) { if (tx_flag) { + packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg), packet_buffer, &out_len); +#if 1 iso_tx_busy = true; - usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg)); + usbd_ep_start_write(busid, VIDEO_IN_EP, packet_buffer, out_len); while (iso_tx_busy) { if (tx_flag == 0) { break; } } +#else + /* dwc2 must use this method */ + for (uint32_t i = 0; i < packets; i++) { + if (i == (packets - 1)) { + iso_tx_busy = true; + usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE); + while (iso_tx_busy) { + if (tx_flag == 0) { + break; + } + } + } else { + iso_tx_busy = true; + usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE); + while (iso_tx_busy) { + if (tx_flag == 0) { + break; + } + } + } + } +#endif } } } \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c index 4ba7170..febbaf9 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/video_static_yuyv_template.c @@ -7,8 +7,6 @@ #include "usbd_video.h" #include "cherryusb_yuyv.h" -#define MAX_PACKETS_IN_ONE_TRANSFER 1 - #define VIDEO_IN_EP 0x81 #define VIDEO_INT_EP 0x83 @@ -133,7 +131,7 @@ const uint8_t video_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -184,10 +182,8 @@ void usbd_video_close(uint8_t busid, uint8_t intf) void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) { - if (usbd_video_stream_split_transfer(busid, ep)) { - /* one frame has done */ - iso_tx_busy = false; - } + //USB_LOG_RAW("actual in len:%d\r\n", nbytes); + iso_tx_busy = false; } static struct usbd_endpoint video_in_ep = { @@ -198,7 +194,7 @@ static struct usbd_endpoint video_in_ep = { struct usbd_interface intf0; struct usbd_interface intf1; -void video_init(uint8_t busid, uintptr_t reg_base) +void video_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, video_descriptor); usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE)); @@ -208,21 +204,48 @@ void video_init(uint8_t busid, uintptr_t reg_base) usbd_initialize(busid, reg_base, usbd_event_handler); } -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[40 * 1024]; void video_test(uint8_t busid) { - memset(packet_buffer, 0, sizeof(packet_buffer)); + uint32_t out_len; + uint32_t packets; + (void)packets; + memset(packet_buffer, 0, 40 * 1024); while (1) { if (tx_flag) { + packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_yuyv, sizeof(cherryusb_yuyv), packet_buffer, &out_len); +#if 1 iso_tx_busy = true; - usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_yuyv, sizeof(cherryusb_yuyv)); + usbd_ep_start_write(busid, VIDEO_IN_EP, packet_buffer, out_len); while (iso_tx_busy) { if (tx_flag == 0) { break; } } +#else + /* dwc2 must use this method */ + for (uint32_t i = 0; i < packets; i++) { + if (i == (packets - 1)) { + iso_tx_busy = true; + usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE); + while (iso_tx_busy) { + if (tx_flag == 0) { + break; + } + } + } else { + iso_tx_busy = true; + usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE); + while (iso_tx_busy) { + if (tx_flag == 0) { + break; + } + } + } + } +#endif } } } \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/webusb_hid_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/webusb_hid_template.c deleted file mode 100644 index 5257087..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/demo/webusb_hid_template.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbd_core.h" -#include "usbd_hid.h" - -#define USBD_VID 0xffff -#define USBD_PID 0xffff -#define USBD_MAX_POWER 100 -#define USBD_LANGID_STRING 1033 - -#define HID_INT_EP 0x81 -#define HID_INT_EP_SIZE 8 -#define HID_INT_EP_INTERVAL 10 - -#define USB_HID_CONFIG_DESC_SIZ (34 + 9) -#define HID_KEYBOARD_REPORT_DESC_SIZE 63 - -#define USBD_WEBUSB_VENDOR_CODE (0x22) -#define USBD_WINUSB_VENDOR_CODE (0x21) - -#define USBD_WINUSB_DESC_SET_LEN (0xB2) -#define URL_DESCRIPTOR_LENGTH (3 + 36) - -#define USBD_WEBUSB_INTF_NUM 0x01 - -#define WEBUSB_URL_STRINGS \ - 'g', 'i', 't', 'h', 'u', 'b', '.', 'c', 'o', 'm', '/', \ - 'c', 'h', 'e', 'r', 'r', 'y', '-', 'e', 'm', 'b', 'e', 'd', 'd', 'e', 'd', '/', 'C', 'h', 'e', 'r', 'r', 'y', 'U', 'S', 'B', - -const uint8_t USBD_WinUSBDescriptorSetDescriptor[USBD_WINUSB_DESC_SET_LEN] = { - // Microsoft OS 2.0 描述符集标头 - 0x0A, 0x00, // Descriptor size (10 bytes) - 0x00, 0x00, // MS OS 2.0 descriptor set header - 0x00, 0x00, 0x03, 0x06, // Windows version (8.1) (0x06030000) - USBD_WINUSB_DESC_SET_LEN, 0x00, // Size, MS OS 2.0 descriptor set - - // Microsoft OS 2.0 配置子集标头 - 0x08, 0x00, // wLength - 0x01, 0x00, // wDescriptorType - 0x00, // 适用于配置 1 - 0x00, // bReserved - 0XA8, 0X00, // Size, MS OS 2.0 configuration subset - - // Microsoft OS 2.0 功能子集头 - 0x08, 0x00, // Descriptor size (8 bytes) - 0x02, 0x00, // MS OS 2.0 function subset header - USBD_WEBUSB_INTF_NUM, // bFirstInterface - 0x00, // 必须设置为 0 - 0xA0, 0x00, - - // Microsoft OS 2.0 兼容 ID 描述符 - // 兼容 ID 描述符告诉 Windows 此设备与 WinUSB 驱动程序兼容 - 0x14, 0x00, // wLength 20 - 0x03, 0x00, // MS_OS_20_FEATURE_COMPATIBLE_ID - 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - // Microsoft OS 2.0 注册表属性描述符 - // 注册表属性分配设备接口 GUID - 0x84, 0x00, //wLength: 132 - 0x04, 0x00, // wDescriptorType: MS_OS_20_FEATURE_REG_PROPERTY: 0x04 (Table 9) - 0x07, 0x00, //wPropertyDataType: REG_MULTI_SZ (Table 15) - 0x2a, 0x00, //wPropertyNameLength: - //bPropertyName: “DeviceInterfaceGUID” - 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00, - 'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, - 0x00, 0x00, - 0x50, 0x00, // wPropertyDataLength - //bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”. - '{', 0x00, '9', 0x00, 'd', 0x00, '7', 0x00, 'd', 0x00, 'e', 0x00, 'b', 0x00, 'b', 0x00, 'c', 0x00, '-', 0x00, - 'c', 0x00, '8', 0x00, '5', 0x00, 'd', 0x00, '-', 0x00, '1', 0x00, '1', 0x00, 'd', 0x00, '1', 0x00, '-', 0x00, - '9', 0x00, 'e', 0x00, 'b', 0x00, '4', 0x00, '-', 0x00, '0', 0x00, '0', 0x00, '6', 0x00, '0', 0x00, '0', 0x00, - '8', 0x00, 'c', 0x00, '3', 0x00, 'a', 0x00, '1', 0x00, '9', 0x00, 'a', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = { - URL_DESCRIPTOR_LENGTH, - WEBUSB_URL_TYPE, - WEBUSB_URL_SCHEME_HTTPS, - WEBUSB_URL_STRINGS -}; - -#define USBD_BOS_WTOTALLENGTH 0x39 - -#define LANDING_PAGE 0x01 -uint8_t USBD_BinaryObjectStoreDescriptor[USBD_BOS_WTOTALLENGTH] = { - // BOS描述符 - 0x05, // bLength 固长为5 - 0x0F, // bDescriptorType 固定为15 - USBD_BOS_WTOTALLENGTH, 0x00, // wTotalLength BOS描述符的总大小 - 0x02, // bNumDeviceCaps BOS描述符中独立设备功能特性描述符的数量 - - // WebUSB 平台功能描述符 - 0x18, // Descriptor size (24 bytes) - 0x10, // Descriptor type (Device Capability) 设备功能描述符 - 0x05, // Capability type (Platform) 平台描述符 - 0x00, // Reserved - - // WebUSB Platform Capability ID (3408b638-09a9-47a0-8bfd-a0768815b665) - // 平台功能 UUID 将此标识为WebUSB 平台功能描述符,它提供有关设备的基本信息 - 0x38, 0xB6, 0x08, 0x34, - 0xA9, 0x09, - 0xA0, 0x47, - 0x8B, 0xFD, - 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65, - - 0x00, 0x01, // WebUSB version 1.0 - USBD_WEBUSB_VENDOR_CODE, // Vendor-assigned WebUSB request code - LANDING_PAGE, // Landing page - - // Microsoft 平台功能描述符 - // 标头 - 0x1C, // Descriptor size (28 bytes) - 0x10, // Descriptor type (Device Capability) - 0x05, // Capability type (Platform) - 0x00, // Reserved - - 0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */ - 0x89, 0x45, 0xC7, 0x4C, - 0x9C, 0xD2, 0x65, 0x9D, - 0x9E, 0x64, 0x8A, 0x9F, - - // 描述符集信息结构 - 0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 * dwWindowsVersion 最低兼容 Windows 版本 */ - - USBD_WINUSB_DESC_SET_LEN, 0X00, /* wDescriptorSetTotalLength */ - - USBD_WINUSB_VENDOR_CODE, /* bVendorCode */ - 0X00 /* bAltEnumCode */ -}; - -struct usb_webusb_descriptor webusb_url_desc = { - .vendor_code = USBD_WEBUSB_VENDOR_CODE, - .string = USBD_WebUSBURLDescriptor, - .string_len = USBD_WINUSB_DESC_SET_LEN -}; - -struct usb_msosv2_descriptor msosv2_desc = { - .vendor_code = USBD_WINUSB_VENDOR_CODE, - .compat_id = USBD_WinUSBDescriptorSetDescriptor, - .compat_id_len = USBD_WINUSB_DESC_SET_LEN, -}; - -struct usb_bos_descriptor bos_desc = { - .string = USBD_BinaryObjectStoreDescriptor, - .string_len = USBD_BOS_WTOTALLENGTH -}; - -static const uint8_t webusb_hid_descriptor[] = { - USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01), - USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), - - /************** Descriptor of Joystick Mouse interface ****************/ - /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ - /******************** Descriptor of Joystick Mouse HID ********************/ - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, - /******************** Descriptor of Mouse endpoint ********************/ - /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */ - 0x00, - HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */ - /* 34 */ - USB_INTERFACE_DESCRIPTOR_INIT(USBD_WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00), - /////////////////////////////////////// - /// string0 descriptor - /////////////////////////////////////// - USB_LANGID_INIT(USBD_LANGID_STRING), - /////////////////////////////////////// - /// string1 descriptor - /////////////////////////////////////// - 0x14, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - /////////////////////////////////////// - /// string2 descriptor - /////////////////////////////////////// - 0x26, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - 'C', 0x00, /* wcChar0 */ - 'h', 0x00, /* wcChar1 */ - 'e', 0x00, /* wcChar2 */ - 'r', 0x00, /* wcChar3 */ - 'r', 0x00, /* wcChar4 */ - 'y', 0x00, /* wcChar5 */ - 'U', 0x00, /* wcChar6 */ - 'S', 0x00, /* wcChar7 */ - 'B', 0x00, /* wcChar8 */ - ' ', 0x00, /* wcChar9 */ - 'H', 0x00, /* wcChar10 */ - 'I', 0x00, /* wcChar11 */ - 'D', 0x00, /* wcChar12 */ - ' ', 0x00, /* wcChar13 */ - 'D', 0x00, /* wcChar14 */ - 'E', 0x00, /* wcChar15 */ - 'M', 0x00, /* wcChar16 */ - 'O', 0x00, /* wcChar17 */ - /////////////////////////////////////// - /// string3 descriptor - /////////////////////////////////////// - 0x16, /* bLength */ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ - '2', 0x00, /* wcChar0 */ - '0', 0x00, /* wcChar1 */ - '2', 0x00, /* wcChar2 */ - '2', 0x00, /* wcChar3 */ - '1', 0x00, /* wcChar4 */ - '2', 0x00, /* wcChar5 */ - '3', 0x00, /* wcChar6 */ - '4', 0x00, /* wcChar7 */ - '5', 0x00, /* wcChar8 */ - '6', 0x00, /* wcChar9 */ -#ifdef CONFIG_USB_HS - /////////////////////////////////////// - /// device qualifier descriptor - /////////////////////////////////////// - 0x0a, - USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x40, - 0x00, - 0x00, -#endif - 0x00 -}; - -/* USB HID device Configuration Descriptor */ -static uint8_t hid_desc[9] __ALIGN_END = { - /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ - 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ - 0x00, -}; - -static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = { - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x06, // USAGE (Keyboard) - 0xa1, 0x01, // COLLECTION (Application) - 0x05, 0x07, // USAGE_PAGE (Keyboard) - 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) - 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x75, 0x01, // REPORT_SIZE (1) - 0x95, 0x08, // REPORT_COUNT (8) - 0x81, 0x02, // INPUT (Data,Var,Abs) - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x08, // REPORT_SIZE (8) - 0x81, 0x03, // INPUT (Cnst,Var,Abs) - 0x95, 0x05, // REPORT_COUNT (5) - 0x75, 0x01, // REPORT_SIZE (1) - 0x05, 0x08, // USAGE_PAGE (LEDs) - 0x19, 0x01, // USAGE_MINIMUM (Num Lock) - 0x29, 0x05, // USAGE_MAXIMUM (Kana) - 0x91, 0x02, // OUTPUT (Data,Var,Abs) - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x03, // REPORT_SIZE (3) - 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) - 0x95, 0x06, // REPORT_COUNT (6) - 0x75, 0x08, // REPORT_SIZE (8) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0xFF, // LOGICAL_MAXIMUM (255) - 0x05, 0x07, // USAGE_PAGE (Keyboard) - 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) - 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) - 0x81, 0x00, // INPUT (Data,Ary,Abs) - 0xc0 // END_COLLECTION -}; - -#define HID_STATE_IDLE 0 -#define HID_STATE_BUSY 1 - -/*!< hid state ! Data can be sent only when state is idle */ -static volatile uint8_t hid_state = HID_STATE_IDLE; - -static void usbd_event_handler(uint8_t busid, uint8_t event) -{ - switch (event) { - case USBD_EVENT_RESET: - break; - case USBD_EVENT_CONNECTED: - break; - case USBD_EVENT_DISCONNECTED: - break; - case USBD_EVENT_RESUME: - break; - case USBD_EVENT_SUSPEND: - break; - case USBD_EVENT_CONFIGURED: - hid_state = HID_STATE_IDLE; - break; - case USBD_EVENT_SET_REMOTE_WAKEUP: - break; - case USBD_EVENT_CLR_REMOTE_WAKEUP: - break; - - default: - break; - } -} - -void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) -{ - hid_state = HID_STATE_IDLE; -} - -static struct usbd_endpoint hid_in_ep = { - .ep_cb = usbd_hid_int_callback, - .ep_addr = HID_INT_EP -}; - -static struct usbd_interface intf0; - -void webusb_hid_keyboard_init(uint8_t busid, uintptr_t reg_base) -{ - usbd_desc_register(busid, webusb_hid_descriptor); - usbd_bos_desc_register(busid, &bos_desc); - usbd_msosv2_desc_register(busid, &msosv2_desc); - usbd_webusb_desc_register(busid, &webusb_url_desc); - usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE)); - usbd_add_endpoint(busid, &hid_in_ep); - - usbd_initialize(busid, reg_base, usbd_event_handler); -} - -USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[64]; - -void hid_keyboard_test(uint8_t busid) -{ - const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - if(usb_device_is_configured(busid) == false) { - return; - } - - memcpy(write_buffer, sendbuffer, 8); - hid_state = HID_STATE_BUSY; - usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8); - while (hid_state == HID_STATE_BUSY) { - } -} diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/winusb1.0_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/winusb1.0_template.c index 1eb390b..c1fbba9 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/winusb1.0_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/winusb1.0_template.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "usbd_core.h" -#include "usbd_cdc_acm.h" +#include "usbd_cdc.h" #define WCID_VENDOR_CODE 0x17 @@ -151,16 +151,18 @@ __ALIGN_BEGIN const uint8_t WINUSB_IF1_WCIDProperties [142] __ALIGN_END = { const uint8_t *WINUSB_IFx_WCIDProperties[] = { WINUSB_IF0_WCIDProperties, -#if DOUBLE_WINUSB == 1 WINUSB_IF1_WCIDProperties, -#endif }; struct usb_msosv1_descriptor msosv1_desc = { .string = WCID_StringDescriptor_MSOS, .vendor_code = WCID_VENDOR_CODE, .compat_id = WINUSB_WCIDDescriptor, +#if DOUBLE_WINUSB == 0 + .comp_id_property = &WINUSB_IF0_WCIDProperties, +#else .comp_id_property = WINUSB_IFx_WCIDProperties, +#endif }; #define WINUSB_IN_EP 0x81 @@ -326,7 +328,7 @@ const uint8_t winusb_descriptor[] = { 0x02, 0x01, 0x40, - 0x00, + 0x01, 0x00, #endif 0x00 @@ -444,7 +446,7 @@ struct usbd_interface intf1; #endif -void winusb_init(uint8_t busid, uintptr_t reg_base) +void winusb_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, winusb_descriptor); usbd_msosv1_desc_register(busid, &msosv1_desc); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c index 493668e..8fe6e99 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/winusb2.0_cdc_template.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "usbd_core.h" -#include "usbd_cdc_acm.h" +#include "usbd_cdc.h" #define WINUSB_IN_EP 0x81 #define WINUSB_OUT_EP 0x02 @@ -219,7 +219,7 @@ const uint8_t winusbv2_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif /* End */ @@ -318,7 +318,7 @@ struct usb_bos_descriptor bos_desc = { .string_len = USBD_BOS_WTOTALLENGTH }; -void winusbv2_init(uint8_t busid, uintptr_t reg_base) +void winusbv2_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, winusbv2_descriptor); usbd_bos_desc_register(busid, &bos_desc); diff --git a/rt-thread/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c b/rt-thread/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c index a209dbd..8df623e 100644 --- a/rt-thread/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c +++ b/rt-thread/components/drivers/usb/cherryusb/demo/winusb2.0_hid_template.c @@ -255,7 +255,7 @@ const uint8_t winusbv2_descriptor[] = { 0x00, 0x00, 0x40, - 0x00, + 0x01, 0x00, #endif /* End */ @@ -422,7 +422,7 @@ struct usb_bos_descriptor bos_desc = { .string_len = USBD_BOS_WTOTALLENGTH }; -void winusbv2_init(uint8_t busid, uintptr_t reg_base) +void winusbv2_init(uint8_t busid, uint32_t reg_base) { usbd_desc_register(busid, winusbv2_descriptor); usbd_bos_desc_register(busid, &bos_desc); diff --git a/rt-thread/components/drivers/usb/cherryusb/idf_component.yml b/rt-thread/components/drivers/usb/cherryusb/idf_component.yml deleted file mode 100644 index a500a24..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/idf_component.yml +++ /dev/null @@ -1,25 +0,0 @@ -version: "1.4.2" -description: CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP -tags: - - usb - - usb-device - - usb-host - - cdc_acm - - cdc_ecm - - cdc_ncm - - hid - - msc - - rndis - - uvc - - uac - - winusb -url: https://github.com/cherry-embedded/CherryUSB -repository: https://github.com/cherry-embedded/CherryUSB.git -documentation: https://cherryusb.readthedocs.io/ -issues: https://github.com/cherry-embedded/CherryUSB/issues -dependencies: - idf: ">=5.0" -targets: - - esp32s2 - - esp32s3 - - esp32p4 \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c b/rt-thread/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c index d355699..18b66a4 100644 --- a/rt-thread/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c +++ b/rt-thread/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c @@ -5,8 +5,6 @@ */ #include "usb_osal.h" #include "usb_errno.h" -#include "usb_config.h" -#include "usb_log.h" #include #include @@ -14,11 +12,6 @@ usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, { rt_thread_t htask; htask = rt_thread_create(name, entry, args, stack_size, prio, 10); - if (htask == NULL) { - USB_LOG_ERR("Create thread %s failed\r\n", name); - while (1) { - } - } rt_thread_startup(htask); return (usb_osal_thread_t)htask; } @@ -34,13 +27,7 @@ void usb_osal_thread_delete(usb_osal_thread_t thread) usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) { - usb_osal_sem_t sem = (usb_osal_sem_t)rt_sem_create("usbh_sem", initial_count, RT_IPC_FLAG_FIFO); - if (sem == NULL) { - USB_LOG_ERR("Create semaphore failed\r\n"); - while (1) { - } - } - return sem; + return (usb_osal_sem_t)rt_sem_create("usbh_sem", initial_count, RT_IPC_FLAG_FIFO); } void usb_osal_sem_delete(usb_osal_sem_t sem) @@ -81,13 +68,7 @@ void usb_osal_sem_reset(usb_osal_sem_t sem) usb_osal_mutex_t usb_osal_mutex_create(void) { - usb_osal_mutex_t mutex = (usb_osal_mutex_t)rt_mutex_create("usbh_mutex", RT_IPC_FLAG_FIFO); - if (mutex == NULL) { - USB_LOG_ERR("Create mutex failed\r\n"); - while (1) { - } - } - return mutex; + return (usb_osal_mutex_t)rt_mutex_create("usbh_mutex", RT_IPC_FLAG_FIFO); } void usb_osal_mutex_delete(usb_osal_mutex_t mutex) @@ -146,18 +127,11 @@ struct usb_osal_timer *usb_osal_timer_create(const char *name, uint32_t timeout_ struct usb_osal_timer *timer; timer = rt_malloc(sizeof(struct usb_osal_timer)); - if (timer == NULL) { - USB_LOG_ERR("Create usb_osal_timer failed\r\n"); - while (1) { - } - } memset(timer, 0, sizeof(struct usb_osal_timer)); - timer->timer = (void *)rt_timer_create(name, handler, argument, timeout_ms, is_period ? (RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER) : (RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER)); + timer->timer = (void *)rt_timer_create("usb_tim", handler, argument, timeout_ms, is_period ? (RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER) : (RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER)); if (timer->timer == NULL) { - USB_LOG_ERR("Create timer failed\r\n"); - while (1) { - } + return NULL; } return timer; } @@ -193,13 +167,3 @@ void usb_osal_msleep(uint32_t delay) { rt_thread_mdelay(delay); } - -void *usb_osal_malloc(size_t size) -{ - return rt_malloc(size); -} - -void usb_osal_free(void *ptr) -{ - rt_free(ptr); -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c b/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c index b20e17d..d4baf03 100644 --- a/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c +++ b/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c @@ -1,13 +1,17 @@ #include "rtthread.h" -#ifdef RT_CHERRYUSB_HOST +#ifdef PKG_CHERRYUSB_HOST #ifndef RT_USING_TIMER_SOFT #error must enable RT_USING_TIMER_SOFT to support timer callback in thread #endif +#if IDLE_THREAD_STACK_SIZE < 2048 +#error "IDLE_THREAD_STACK_SIZE must be greater than 2048" +#endif + #if RT_TIMER_THREAD_STACK_SIZE < 2048 -#error "RT_TIMER_THREAD_STACK_SIZE must be >= 2048" +#error "RT_TIMER_THREAD_STACK_SIZE must be greater than 2048" #endif #endif diff --git a/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c b/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c index 073d52e..12799e6 100644 --- a/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c +++ b/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usbh_dfs.c @@ -9,7 +9,7 @@ #include "rtthread.h" #include -#define DEV_FORMAT "/dev/sd%c" +#define DEV_FORMAT "/sd%c" #ifndef CONFIG_USB_DFS_MOUNT_POINT #define CONFIG_USB_DFS_MOUNT_POINT "/" @@ -36,6 +36,17 @@ void rt_hw_cpu_dcache_ops(int ops, void *addr, int size) bflb_l1c_dcache_invalidate_range(addr, size); } } +#elif defined(SOC_HPM5000) || defined(SOC_HPM6000) +#include "hpm_l1c_drv.h" + +void rt_hw_cpu_dcache_ops(int ops, void *addr, int size) +{ + if (ops == RT_HW_CACHE_FLUSH) { + l1c_dc_flush((uint32_t)addr, size); + } else { + l1c_dc_invalidate((uint32_t)addr, size); + } +} #endif USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t msc_sector[512]; @@ -46,7 +57,7 @@ static rt_err_t rt_udisk_init(rt_device_t dev) } static ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer, - rt_size_t size) + rt_size_t size) { struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data; int ret; @@ -85,7 +96,7 @@ static ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer, } static ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buffer, - rt_size_t size) + rt_size_t size) { struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data; int ret; @@ -175,17 +186,15 @@ int udisk_init(struct usbh_msc *msc_class) ret = usbh_msc_scsi_read10(msc_class, 0, msc_sector, 1); if (ret != RT_EOK) { rt_kprintf("usb mass_storage read failed\n"); - rt_free(dev); return ret; } - for (i = 0; i < 4; i++) { + for (i = 0; i < 16; i++) { /* Get the first partition */ ret = dfs_filesystem_get_partition(&part0, msc_sector, i); if (ret == RT_EOK) { rt_kprintf("Found partition %d: type = %d, offet=0x%x, size=0x%x\n", i, part0.type, part0.offset, part0.size); - break; } else { break; } @@ -221,8 +230,6 @@ void usbh_msc_run(struct usbh_msc *msc_class) void usbh_msc_stop(struct usbh_msc *msc_class) { - struct rt_device *dev; - char name[CONFIG_USBHOST_DEV_NAMELEN]; char mount_point[CONFIG_USBHOST_DEV_NAMELEN]; @@ -230,9 +237,5 @@ void usbh_msc_stop(struct usbh_msc *msc_class) snprintf(mount_point, CONFIG_USBHOST_DEV_NAMELEN, CONFIG_USB_DFS_MOUNT_POINT, msc_class->sdchar); dfs_unmount(mount_point); - dev = rt_device_find(name); - if (dev) { - rt_device_unregister(dev); - rt_free(dev); - } + rt_device_unregister(rt_device_find(name)); } diff --git a/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usbh_lwip.c b/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usbh_lwip.c index 34dc385..360a848 100644 --- a/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usbh_lwip.c +++ b/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usbh_lwip.c @@ -44,10 +44,6 @@ #error PBUF_POOL_BUFSIZE must be larger than 1600 #endif -#if RT_LWIP_TCPTHREAD_STACKSIZE < 2048 -#error RT_LWIP_TCPTHREAD_STACKSIZE must be >= 2048 -#endif - // #define CONFIG_USBHOST_PLATFORM_CDC_ECM // #define CONFIG_USBHOST_PLATFORM_CDC_RNDIS // #define CONFIG_USBHOST_PLATFORM_CDC_NCM @@ -122,7 +118,6 @@ static rt_err_t rt_usbh_cdc_ecm_control(rt_device_t dev, int cmd, void *args) static rt_err_t rt_usbh_cdc_ecm_eth_tx(rt_device_t dev, struct pbuf *p) { int ret; - (void)dev; usbh_lwip_eth_output_common(p, usbh_cdc_ecm_get_eth_txbuf()); ret = usbh_cdc_ecm_eth_output(p->tot_len); @@ -155,8 +150,6 @@ void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class) void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class) { - (void)cdc_ecm_class; - eth_device_deinit(&g_cdc_ecm_dev); } #endif @@ -211,7 +204,6 @@ static rt_err_t rt_usbh_rndis_control(rt_device_t dev, int cmd, void *args) static rt_err_t rt_usbh_rndis_eth_tx(rt_device_t dev, struct pbuf *p) { int ret; - (void)dev; usbh_lwip_eth_output_common(p, usbh_rndis_get_eth_txbuf()); ret = usbh_rndis_eth_output(p->tot_len); @@ -245,8 +237,6 @@ void usbh_rndis_run(struct usbh_rndis *rndis_class) void usbh_rndis_stop(struct usbh_rndis *rndis_class) { - (void)rndis_class; - eth_device_deinit(&g_rndis_dev); // rt_timer_stop(keep_timer); // rt_timer_delete(keep_timer); @@ -283,7 +273,6 @@ static rt_err_t rt_usbh_cdc_ncm_control(rt_device_t dev, int cmd, void *args) static rt_err_t rt_usbh_cdc_ncm_eth_tx(rt_device_t dev, struct pbuf *p) { int ret; - (void)dev; usbh_lwip_eth_output_common(p, usbh_cdc_ncm_get_eth_txbuf()); ret = usbh_cdc_ncm_eth_output(p->tot_len); @@ -316,8 +305,6 @@ void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class) void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class) { - (void)cdc_ncm_class; - eth_device_deinit(&g_cdc_ncm_dev); } #endif @@ -352,7 +339,6 @@ static rt_err_t rt_usbh_asix_control(rt_device_t dev, int cmd, void *args) static rt_err_t rt_usbh_asix_eth_tx(rt_device_t dev, struct pbuf *p) { int ret; - (void)dev; usbh_lwip_eth_output_common(p, usbh_asix_get_eth_txbuf()); ret = usbh_asix_eth_output(p->tot_len); @@ -385,8 +371,6 @@ void usbh_asix_run(struct usbh_asix *asix_class) void usbh_asix_stop(struct usbh_asix *asix_class) { - (void)asix_class; - eth_device_deinit(&g_asix_dev); } #endif @@ -421,7 +405,6 @@ static rt_err_t rt_usbh_rtl8152_control(rt_device_t dev, int cmd, void *args) static rt_err_t rt_usbh_rtl8152_eth_tx(rt_device_t dev, struct pbuf *p) { int ret; - (void)dev; usbh_lwip_eth_output_common(p, usbh_rtl8152_get_eth_txbuf()); ret = usbh_rtl8152_eth_output(p->tot_len); @@ -454,8 +437,6 @@ void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class) void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class) { - (void)rtl8152_class; - eth_device_deinit(&g_rtl8152_dev); } #endif diff --git a/rt-thread/components/drivers/usb/cherryusb/port/bouffalolab/usb_dc_bl.c b/rt-thread/components/drivers/usb/cherryusb/port/bouffalolab/usb_dc_bl.c index b6859f8..6f45329 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/bouffalolab/usb_dc_bl.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/bouffalolab/usb_dc_bl.c @@ -613,23 +613,6 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } -int usbd_set_remote_wakeup(uint8_t busid) -{ - uint32_t regval; - - regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET); - regval |= USB_CAP_RMWAKUP; - putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET); - - bflb_mtimer_delay_ms(10); - - regval = getreg32(BFLB_USB_BASE + USB_DEV_CTL_OFFSET); - regval &= ~USB_CAP_RMWAKUP; - putreg32(regval, BFLB_USB_BASE + USB_DEV_CTL_OFFSET); - - return 0; -} - uint8_t usbd_get_port_speed(uint8_t busid) { uint8_t speed = 3; @@ -655,7 +638,7 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) uint8_t ep_idx = USB_EP_GET_IDX(ep_addr); - if (ep_idx > 4) { + if ((ep_idx > 4) && (ep_idx < 9)) { return 0; } @@ -839,29 +822,6 @@ int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep) int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled) { - uint32_t regval; - - uint8_t ep_idx = USB_EP_GET_IDX(ep); - - if (ep_idx == 0) { - } else { - if (USB_EP_DIR_IS_OUT(ep)) { - regval = getreg32(BFLB_USB_BASE + USB_DEV_OUTMPS1_OFFSET + (ep_idx - 1) * 4); - if (regval & USB_STL_OEP1) { - *stalled = 1; - } else { - *stalled = 0; - } - } else { - regval = getreg32(BFLB_USB_BASE + USB_DEV_INMPS1_OFFSET + (ep_idx - 1) * 4); - if (regval & USB_STL_IEP1) { - *stalled = 1; - } else { - *stalled = 0; - } - } - } - return 0; } @@ -1059,11 +1019,12 @@ void USBD_IRQHandler(uint8_t busid) } #ifdef CONFIG_USBDEV_TEST_MODE -void usbd_execute_test_mode(uint8_t busid, uint8_t test_mode) +void usbd_execute_test_mode(struct usb_setup_packet *setup) { uint32_t regval; + uint8_t index = setup->wIndex >> 8; - switch (test_mode) { + switch (index) { case 1: // Test_J { regval = getreg32(BFLB_USB_BASE + USB_PHY_TST_OFFSET); diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbfs.c b/rt-thread/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbfs.c index 7aabd41..4b4b72d 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbfs.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbfs.c @@ -101,11 +101,6 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } -int usbd_set_remote_wakeup(uint8_t busid) -{ - return -1; -} - uint8_t usbd_get_port_speed(uint8_t busid) { return USB_SPEED_FULL; diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbhs.c b/rt-thread/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbhs.c index a8d3036..758ffd7 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbhs.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/ch32/usb_dc_usbhs.c @@ -101,11 +101,6 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } -int usbd_set_remote_wakeup(uint8_t busid) -{ - return -1; -} - uint8_t usbd_get_port_speed(uint8_t busid) { return USB_SPEED_HIGH; diff --git a/rt-thread/components/drivers/usb/cherryusb/port/chipidea/README.md b/rt-thread/components/drivers/usb/cherryusb/port/chipidea/README.md deleted file mode 100644 index 6a43f79..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/chipidea/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Note - -## Support Chip List - -### NXP - -Modify USB_NOCACHE_RAM_SECTION - -``` -#define USB_NOCACHE_RAM_SECTION __attribute__((section(".NonCacheable"))) -``` - -- IMRT10XX/IMRT11XX -- MCXN9XX/MCXN236 diff --git a/rt-thread/components/drivers/usb/cherryusb/port/chipidea/usb_chipidea_reg.h b/rt-thread/components/drivers/usb/cherryusb/port/chipidea/usb_chipidea_reg.h deleted file mode 100644 index 4867ef5..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/chipidea/usb_chipidea_reg.h +++ /dev/null @@ -1,2249 +0,0 @@ -/* - * Copyright (c) 2021-2024 HPMicro - * - * SPDX-License-Identifier: BSD-3-Clause - * - */ - - -#ifndef HPM_USB_H -#define HPM_USB_H - -#define __R volatile const /* Define "read-only" permission */ -#define __RW volatile /* Define "read-write" permission */ -#define __W volatile /* Define "write-only" permission */ - -typedef struct { - __R uint8_t RESERVED0[128]; /* 0x0 - 0x7F: Reserved */ - __RW uint32_t GPTIMER0LD; /* 0x80: General Purpose Timer #0 Load Register */ - __RW uint32_t GPTIMER0CTRL; /* 0x84: General Purpose Timer #0 Controller Register */ - __RW uint32_t GPTIMER1LD; /* 0x88: General Purpose Timer #1 Load Register */ - __RW uint32_t GPTIMER1CTRL; /* 0x8C: General Purpose Timer #1 Controller Register */ - __RW uint32_t SBUSCFG; /* 0x90: System Bus Config Register */ - __R uint8_t RESERVED1[172]; /* 0x94 - 0x13F: Reserved */ - __RW uint32_t USBCMD; /* 0x140: USB Command Register */ - __RW uint32_t USBSTS; /* 0x144: USB Status Register */ - __RW uint32_t USBINTR; /* 0x148: Interrupt Enable Register */ - __RW uint32_t FRINDEX; /* 0x14C: USB Frame Index Register */ - __R uint8_t RESERVED2[4]; /* 0x150 - 0x153: Reserved */ - union { - __RW uint32_t DEVICEADDR; /* 0x154: Device Address Register */ - __RW uint32_t PERIODICLISTBASE; /* 0x154: Frame List Base Address Register */ - }; - union { - __RW uint32_t ASYNCLISTADDR; /* 0x158: Next Asynch. Address Register */ - __RW uint32_t ENDPTLISTADDR; /* 0x158: Endpoint List Address Register */ - }; - __R uint8_t RESERVED3[4]; /* 0x15C - 0x15F: Reserved */ - __RW uint32_t BURSTSIZE; /* 0x160: Programmable Burst Size Register */ - __RW uint32_t TXFILLTUNING; /* 0x164: TX FIFO Fill Tuning Register */ - __R uint8_t RESERVED4[16]; /* 0x168 - 0x177: Reserved */ - __RW uint32_t ENDPTNAK; /* 0x178: Endpoint NAK Register */ - __RW uint32_t ENDPTNAKEN; /* 0x17C: Endpoint NAK Enable Register */ - __R uint8_t RESERVED5[4]; /* 0x180 - 0x183: Reserved */ - __RW uint32_t PORTSC1; /* 0x184: Port Status & Control */ - __R uint8_t RESERVED6[28]; /* 0x188 - 0x1A3: Reserved */ - __RW uint32_t OTGSC; /* 0x1A4: On-The-Go Status & control Register */ - __RW uint32_t USBMODE; /* 0x1A8: USB Device Mode Register */ - __RW uint32_t ENDPTSETUPSTAT; /* 0x1AC: Endpoint Setup Status Register */ - __RW uint32_t ENDPTPRIME; /* 0x1B0: Endpoint Prime Register */ - __RW uint32_t ENDPTFLUSH; /* 0x1B4: Endpoint Flush Register */ - __R uint32_t ENDPTSTAT; /* 0x1B8: Endpoint Status Register */ - __RW uint32_t ENDPTCOMPLETE; /* 0x1BC: Endpoint Complete Register */ - __RW uint32_t ENDPTCTRL[8]; /* 0x1C0 - 0x1DC: Endpoint Control0 Register... Endpoint Control7 Register */ -} CHIPIDEA_TypeDef; - - -/* Bitfield definition for register: GPTIMER0LD */ -/* - * GPTLD (RW) - * - * GPTLD - * General Purpose Timer Load Value - * These bit fields are loaded to GPTCNT bits when GPTRST bit is set '1b'. - * This value represents the time in microseconds minus 1 for the timer duration. - * Example: for a one millisecond timer, load 1000-1=999 or 0x0003E7. - * NOTE: Max value is 0xFFFFFF or 16.777215 seconds. - */ -#define USB_GPTIMER0LD_GPTLD_MASK (0xFFFFFFUL) -#define USB_GPTIMER0LD_GPTLD_SHIFT (0U) -#define USB_GPTIMER0LD_GPTLD_SET(x) (((uint32_t)(x) << USB_GPTIMER0LD_GPTLD_SHIFT) & USB_GPTIMER0LD_GPTLD_MASK) -#define USB_GPTIMER0LD_GPTLD_GET(x) (((uint32_t)(x) & USB_GPTIMER0LD_GPTLD_MASK) >> USB_GPTIMER0LD_GPTLD_SHIFT) - -/* Bitfield definition for register: GPTIMER0CTRL */ -/* - * GPTRUN (RW) - * - * GPTRUN - * General Purpose Timer Run - * GPTCNT bits are not effected when setting or clearing this bit. - * 0 - Stop counting - * 1 - Run - */ -#define USB_GPTIMER0CTRL_GPTRUN_MASK (0x80000000UL) -#define USB_GPTIMER0CTRL_GPTRUN_SHIFT (31U) -#define USB_GPTIMER0CTRL_GPTRUN_SET(x) (((uint32_t)(x) << USB_GPTIMER0CTRL_GPTRUN_SHIFT) & USB_GPTIMER0CTRL_GPTRUN_MASK) -#define USB_GPTIMER0CTRL_GPTRUN_GET(x) (((uint32_t)(x) & USB_GPTIMER0CTRL_GPTRUN_MASK) >> USB_GPTIMER0CTRL_GPTRUN_SHIFT) - -/* - * GPTRST (WO) - * - * GPTRST - * General Purpose Timer Reset - * 0 - No action - * 1 - Load counter value from GPTLD bits in n_GPTIMER0LD - */ -#define USB_GPTIMER0CTRL_GPTRST_MASK (0x40000000UL) -#define USB_GPTIMER0CTRL_GPTRST_SHIFT (30U) -#define USB_GPTIMER0CTRL_GPTRST_SET(x) (((uint32_t)(x) << USB_GPTIMER0CTRL_GPTRST_SHIFT) & USB_GPTIMER0CTRL_GPTRST_MASK) -#define USB_GPTIMER0CTRL_GPTRST_GET(x) (((uint32_t)(x) & USB_GPTIMER0CTRL_GPTRST_MASK) >> USB_GPTIMER0CTRL_GPTRST_SHIFT) - -/* - * GPTMODE (RW) - * - * GPTMODE - * General Purpose Timer Mode - * In one shot mode, the timer will count down to zero, generate an interrupt, and stop until the counter is - * reset by software; - * In repeat mode, the timer will count down to zero, generate an interrupt and automatically reload the - * counter value from GPTLD bits to start again. - * 0 - One Shot Mode - * 1 - Repeat Mode - */ -#define USB_GPTIMER0CTRL_GPTMODE_MASK (0x1000000UL) -#define USB_GPTIMER0CTRL_GPTMODE_SHIFT (24U) -#define USB_GPTIMER0CTRL_GPTMODE_SET(x) (((uint32_t)(x) << USB_GPTIMER0CTRL_GPTMODE_SHIFT) & USB_GPTIMER0CTRL_GPTMODE_MASK) -#define USB_GPTIMER0CTRL_GPTMODE_GET(x) (((uint32_t)(x) & USB_GPTIMER0CTRL_GPTMODE_MASK) >> USB_GPTIMER0CTRL_GPTMODE_SHIFT) - -/* - * GPTCNT (RO) - * - * GPTCNT - * General Purpose Timer Counter. - * This field is the count value of the countdown timer. - */ -#define USB_GPTIMER0CTRL_GPTCNT_MASK (0xFFFFFFUL) -#define USB_GPTIMER0CTRL_GPTCNT_SHIFT (0U) -#define USB_GPTIMER0CTRL_GPTCNT_GET(x) (((uint32_t)(x) & USB_GPTIMER0CTRL_GPTCNT_MASK) >> USB_GPTIMER0CTRL_GPTCNT_SHIFT) - -/* Bitfield definition for register: GPTIMER1LD */ -/* - * GPTLD (RW) - * - * GPTLD - * General Purpose Timer Load Value - * These bit fields are loaded to GPTCNT bits when GPTRST bit is set '1b'. - * This value represents the time in microseconds minus 1 for the timer duration. - * Example: for a one millisecond timer, load 1000-1=999 or 0x0003E7. - * NOTE: Max value is 0xFFFFFF or 16.777215 seconds. - */ -#define USB_GPTIMER1LD_GPTLD_MASK (0xFFFFFFUL) -#define USB_GPTIMER1LD_GPTLD_SHIFT (0U) -#define USB_GPTIMER1LD_GPTLD_SET(x) (((uint32_t)(x) << USB_GPTIMER1LD_GPTLD_SHIFT) & USB_GPTIMER1LD_GPTLD_MASK) -#define USB_GPTIMER1LD_GPTLD_GET(x) (((uint32_t)(x) & USB_GPTIMER1LD_GPTLD_MASK) >> USB_GPTIMER1LD_GPTLD_SHIFT) - -/* Bitfield definition for register: GPTIMER1CTRL */ -/* - * GPTRUN (RW) - * - * GPTRUN - * General Purpose Timer Run - * GPTCNT bits are not effected when setting or clearing this bit. - * 0 - Stop counting - * 1 - Run - */ -#define USB_GPTIMER1CTRL_GPTRUN_MASK (0x80000000UL) -#define USB_GPTIMER1CTRL_GPTRUN_SHIFT (31U) -#define USB_GPTIMER1CTRL_GPTRUN_SET(x) (((uint32_t)(x) << USB_GPTIMER1CTRL_GPTRUN_SHIFT) & USB_GPTIMER1CTRL_GPTRUN_MASK) -#define USB_GPTIMER1CTRL_GPTRUN_GET(x) (((uint32_t)(x) & USB_GPTIMER1CTRL_GPTRUN_MASK) >> USB_GPTIMER1CTRL_GPTRUN_SHIFT) - -/* - * GPTRST (WO) - * - * GPTRST - * General Purpose Timer Reset - * 0 - No action - * 1 - Load counter value from GPTLD bits in USB_n_GPTIMER1LD - */ -#define USB_GPTIMER1CTRL_GPTRST_MASK (0x40000000UL) -#define USB_GPTIMER1CTRL_GPTRST_SHIFT (30U) -#define USB_GPTIMER1CTRL_GPTRST_SET(x) (((uint32_t)(x) << USB_GPTIMER1CTRL_GPTRST_SHIFT) & USB_GPTIMER1CTRL_GPTRST_MASK) -#define USB_GPTIMER1CTRL_GPTRST_GET(x) (((uint32_t)(x) & USB_GPTIMER1CTRL_GPTRST_MASK) >> USB_GPTIMER1CTRL_GPTRST_SHIFT) - -/* - * GPTMODE (RW) - * - * GPTMODE - * General Purpose Timer Mode - * In one shot mode, the timer will count down to zero, generate an interrupt, and stop until the counter is - * reset by software. In repeat mode, the timer will count down to zero, generate an interrupt and - * automatically reload the counter value from GPTLD bits to start again. - * 0 - One Shot Mode - * 1 - Repeat Mode - */ -#define USB_GPTIMER1CTRL_GPTMODE_MASK (0x1000000UL) -#define USB_GPTIMER1CTRL_GPTMODE_SHIFT (24U) -#define USB_GPTIMER1CTRL_GPTMODE_SET(x) (((uint32_t)(x) << USB_GPTIMER1CTRL_GPTMODE_SHIFT) & USB_GPTIMER1CTRL_GPTMODE_MASK) -#define USB_GPTIMER1CTRL_GPTMODE_GET(x) (((uint32_t)(x) & USB_GPTIMER1CTRL_GPTMODE_MASK) >> USB_GPTIMER1CTRL_GPTMODE_SHIFT) - -/* - * GPTCNT (RO) - * - * GPTCNT - * General Purpose Timer Counter. - * This field is the count value of the countdown timer. - */ -#define USB_GPTIMER1CTRL_GPTCNT_MASK (0xFFFFFFUL) -#define USB_GPTIMER1CTRL_GPTCNT_SHIFT (0U) -#define USB_GPTIMER1CTRL_GPTCNT_GET(x) (((uint32_t)(x) & USB_GPTIMER1CTRL_GPTCNT_MASK) >> USB_GPTIMER1CTRL_GPTCNT_SHIFT) - -/* Bitfield definition for register: SBUSCFG */ -/* - * AHBBRST (RW) - * - * AHBBRST - * AHB master interface Burst configuration - * These bits control AHB master transfer type sequence (or priority). - * NOTE: This register overrides n_BURSTSIZE register when its value is not zero. - * 000 - Incremental burst of unspecified length only - * 001 - INCR4 burst, then single transfer - * 010 - INCR8 burst, INCR4 burst, then single transfer - * 011 - INCR16 burst, INCR8 burst, INCR4 burst, then single transfer - * 100 - Reserved, don't use - * 101 - INCR4 burst, then incremental burst of unspecified length - * 110 - INCR8 burst, INCR4 burst, then incremental burst of unspecified length - * 111 - INCR16 burst, INCR8 burst, INCR4 burst, then incremental burst of unspecified length - */ -#define USB_SBUSCFG_AHBBRST_MASK (0x7U) -#define USB_SBUSCFG_AHBBRST_SHIFT (0U) -#define USB_SBUSCFG_AHBBRST_SET(x) (((uint32_t)(x) << USB_SBUSCFG_AHBBRST_SHIFT) & USB_SBUSCFG_AHBBRST_MASK) -#define USB_SBUSCFG_AHBBRST_GET(x) (((uint32_t)(x) & USB_SBUSCFG_AHBBRST_MASK) >> USB_SBUSCFG_AHBBRST_SHIFT) - -/* Bitfield definition for register: USBCMD */ -/* - * ITC (RW) - * - * ITC - * Interrupt Threshold Control -Read/Write. - * The system software uses this field to set the maximum rate at which the host/device controller will issue interrupts. - * ITC contains the maximum interrupt interval measured in micro-frames. Valid values are - * shown below. - * Value Maximum Interrupt Interval - * 00000000 - Immediate (no threshold) - * 00000001 - 1 micro-frame - * 00000010 - 2 micro-frames - * 00000100 - 4 micro-frames - * 00001000 - 8 micro-frames - * 00010000 - 16 micro-frames - * 00100000 - 32 micro-frames - * 01000000 - 64 micro-frames - */ -#define USB_USBCMD_ITC_MASK (0xFF0000UL) -#define USB_USBCMD_ITC_SHIFT (16U) -#define USB_USBCMD_ITC_SET(x) (((uint32_t)(x) << USB_USBCMD_ITC_SHIFT) & USB_USBCMD_ITC_MASK) -#define USB_USBCMD_ITC_GET(x) (((uint32_t)(x) & USB_USBCMD_ITC_MASK) >> USB_USBCMD_ITC_SHIFT) - -/* - * FS_2 (RW) - * - * FS_2 - * Frame List Size - (Read/Write or Read Only). [host mode only] - * This field is Read/Write only if Programmable Frame List Flag in the HCCPARAMS registers is set to one. - * This field specifies the size of the frame list that controls which bits in the Frame Index Register should be used for the Frame List Current index. - * NOTE: This field is made up from USBCMD bits 15, 3 and 2. - * Value Meaning - * 0b000 - 1024 elements (4096 bytes) Default value - * 0b001 - 512 elements (2048 bytes) - * 0b010 - 256 elements (1024 bytes) - * 0b011 - 128 elements (512 bytes) - * 0b100 - 64 elements (256 bytes) - * 0b101 - 32 elements (128 bytes) - * 0b110 - 16 elements (64 bytes) - * 0b111 - 8 elements (32 bytes) - */ -#define USB_USBCMD_FS_2_MASK (0x8000U) -#define USB_USBCMD_FS_2_SHIFT (15U) -#define USB_USBCMD_FS_2_SET(x) (((uint32_t)(x) << USB_USBCMD_FS_2_SHIFT) & USB_USBCMD_FS_2_MASK) -#define USB_USBCMD_FS_2_GET(x) (((uint32_t)(x) & USB_USBCMD_FS_2_MASK) >> USB_USBCMD_FS_2_SHIFT) - -/* - * ATDTW (RW) - * - * ATDTW - * Add dTD TripWire - Read/Write. [device mode only] - * This bit is used as a semaphore to ensure proper addition of a new dTD to an active (primed) endpoint's - * linked list. This bit is set and cleared by software. - * This bit would also be cleared by hardware when state machine is hazard region for which adding a dTD - * to a primed endpoint may go unrecognized. - */ -#define USB_USBCMD_ATDTW_MASK (0x4000U) -#define USB_USBCMD_ATDTW_SHIFT (14U) -#define USB_USBCMD_ATDTW_SET(x) (((uint32_t)(x) << USB_USBCMD_ATDTW_SHIFT) & USB_USBCMD_ATDTW_MASK) -#define USB_USBCMD_ATDTW_GET(x) (((uint32_t)(x) & USB_USBCMD_ATDTW_MASK) >> USB_USBCMD_ATDTW_SHIFT) - -/* - * SUTW (RW) - * - * SUTW - * Setup TripWire - Read/Write. [device mode only] - * This bit is used as a semaphore to ensure that the setup data payload of 8 bytes is extracted from a QH by the DCD without being corrupted. - * If the setup lockout mode is off (SLOM bit in USB core register n_USBMODE, see USBMODE ) then - * there is a hazard when new setup data arrives while the DCD is copying the setup data payload - * from the QH for a previous setup packet. This bit is set and cleared by software. - * This bit would also be cleared by hardware when a hazard detected. - */ -#define USB_USBCMD_SUTW_MASK (0x2000U) -#define USB_USBCMD_SUTW_SHIFT (13U) -#define USB_USBCMD_SUTW_SET(x) (((uint32_t)(x) << USB_USBCMD_SUTW_SHIFT) & USB_USBCMD_SUTW_MASK) -#define USB_USBCMD_SUTW_GET(x) (((uint32_t)(x) & USB_USBCMD_SUTW_MASK) >> USB_USBCMD_SUTW_SHIFT) - -/* - * ASPE (RW) - * - * ASPE - * Asynchronous Schedule Park Mode Enable - Read/Write. - * If the Asynchronous Park Capability bit in the HCCPARAMS register is a one, then this bit defaults to a 1h and is R/W. - * Otherwise the bit must be a zero and is RO. Software uses this bit to enable or disable Park mode. - * When this bit is one, Park mode is enabled. When this bit is a zero, Park mode is disabled. - * NOTE: ASPE bit reset value: '0b' for OTG controller . - */ -#define USB_USBCMD_ASPE_MASK (0x800U) -#define USB_USBCMD_ASPE_SHIFT (11U) -#define USB_USBCMD_ASPE_SET(x) (((uint32_t)(x) << USB_USBCMD_ASPE_SHIFT) & USB_USBCMD_ASPE_MASK) -#define USB_USBCMD_ASPE_GET(x) (((uint32_t)(x) & USB_USBCMD_ASPE_MASK) >> USB_USBCMD_ASPE_SHIFT) - -/* - * ASP (RW) - * - * ASP - * Asynchronous Schedule Park Mode Count - Read/Write. - * If the Asynchronous Park Capability bit in the HCCPARAMS register is a one, then this field defaults to 3h and is R/W. Otherwise it defaults to zero and is Read-Only. - * It contains a count of the number of successive transactions the host controller is allowed to - * execute from a high-speed queue head on the Asynchronous schedule before continuing traversal of the Asynchronous schedule. - * Valid values are 1h to 3h. Software must not write a zero to this bit when Park Mode Enable is a one as this will result in undefined behavior. - * This field is set to 3h in all controller core. - */ -#define USB_USBCMD_ASP_MASK (0x300U) -#define USB_USBCMD_ASP_SHIFT (8U) -#define USB_USBCMD_ASP_SET(x) (((uint32_t)(x) << USB_USBCMD_ASP_SHIFT) & USB_USBCMD_ASP_MASK) -#define USB_USBCMD_ASP_GET(x) (((uint32_t)(x) & USB_USBCMD_ASP_MASK) >> USB_USBCMD_ASP_SHIFT) - -/* - * IAA (RW) - * - * IAA - * Interrupt on Async Advance Doorbell - Read/Write. - * This bit is used as a doorbell by software to tell the host controller to issue an interrupt the next time it advances asynchronous schedule. Software must write a 1 to this bit to ring the doorbell. - * When the host controller has evicted all appropriate cached schedule states, - * it sets the Interrupt on Async Advance status bit in the USBSTS register. - * If the Interrupt on Sync Advance Enable bit in the USBINTR register is one, then the host controller will assert an interrupt at the next interrupt threshold. - * The host controller sets this bit to zero after it has set the Interrupt on Sync Advance status bit in the USBSTS register to one. - * Software should not write a one to this bit when the asynchronous schedule is inactive. Doing so will yield undefined results. - * This bit is only used in host mode. Writing a one to this bit when device mode is selected will have undefined results. - */ -#define USB_USBCMD_IAA_MASK (0x40U) -#define USB_USBCMD_IAA_SHIFT (6U) -#define USB_USBCMD_IAA_SET(x) (((uint32_t)(x) << USB_USBCMD_IAA_SHIFT) & USB_USBCMD_IAA_MASK) -#define USB_USBCMD_IAA_GET(x) (((uint32_t)(x) & USB_USBCMD_IAA_MASK) >> USB_USBCMD_IAA_SHIFT) - -/* - * ASE (RW) - * - * ASE - * Asynchronous Schedule Enable - Read/Write. Default 0b. - * This bit controls whether the host controller skips processing the Asynchronous Schedule. - * Only the host controller uses this bit. - * Values Meaning - * 0 - Do not process the Asynchronous Schedule. - * 1 - Use the ASYNCLISTADDR register to access the Asynchronous Schedule. - */ -#define USB_USBCMD_ASE_MASK (0x20U) -#define USB_USBCMD_ASE_SHIFT (5U) -#define USB_USBCMD_ASE_SET(x) (((uint32_t)(x) << USB_USBCMD_ASE_SHIFT) & USB_USBCMD_ASE_MASK) -#define USB_USBCMD_ASE_GET(x) (((uint32_t)(x) & USB_USBCMD_ASE_MASK) >> USB_USBCMD_ASE_SHIFT) - -/* - * PSE (RW) - * - * PSE - * Periodic Schedule Enable- Read/Write. Default 0b. - * This bit controls whether the host controller skips processing the Periodic Schedule. - * Only the host controller uses this bit. - * Values Meaning - * 0 - Do not process the Periodic Schedule - * 1 - Use the PERIODICLISTBASE register to access the Periodic Schedule. - */ -#define USB_USBCMD_PSE_MASK (0x10U) -#define USB_USBCMD_PSE_SHIFT (4U) -#define USB_USBCMD_PSE_SET(x) (((uint32_t)(x) << USB_USBCMD_PSE_SHIFT) & USB_USBCMD_PSE_MASK) -#define USB_USBCMD_PSE_GET(x) (((uint32_t)(x) & USB_USBCMD_PSE_MASK) >> USB_USBCMD_PSE_SHIFT) - -/* - * FS_1 (RW) - * - * FS_1 - * See description at bit 15 - */ -#define USB_USBCMD_FS_1_MASK (0xCU) -#define USB_USBCMD_FS_1_SHIFT (2U) -#define USB_USBCMD_FS_1_SET(x) (((uint32_t)(x) << USB_USBCMD_FS_1_SHIFT) & USB_USBCMD_FS_1_MASK) -#define USB_USBCMD_FS_1_GET(x) (((uint32_t)(x) & USB_USBCMD_FS_1_MASK) >> USB_USBCMD_FS_1_SHIFT) - -/* - * RST (RW) - * - * RST - * Controller Reset (RESET) - Read/Write. Software uses this bit to reset the controller. - * This bit is set to zero by the Host/Device Controller when the reset process is complete. Software cannot terminate the reset process early by writing a zero to this register. - * Host operation mode: - * When software writes a one to this bit, the Controller resets its internal pipelines, timers, counters, state machines etc. to their initial value. - * Any transaction currently in progress on USB is immediately terminated. A USB reset is not driven on downstream ports. - * Software should not set this bit to a one when the HCHalted bit in the USBSTS register is a zero. - * Attempting to reset an actively running host controller will result in undefined behavior. - * Device operation mode: - * When software writes a one to this bit, the Controller resets its internal pipelines, timers, counters, state machines etc. to their initial value. - * Writing a one to this bit when the device is in the attached state is not recommended, because the effect on an attached host is undefined. - * In order to ensure that the device is not in an attached state before initiating a device controller reset, all primed endpoints should be flushed and the USBCMD Run/Stop bit should be set to 0. - */ -#define USB_USBCMD_RST_MASK (0x2U) -#define USB_USBCMD_RST_SHIFT (1U) -#define USB_USBCMD_RST_SET(x) (((uint32_t)(x) << USB_USBCMD_RST_SHIFT) & USB_USBCMD_RST_MASK) -#define USB_USBCMD_RST_GET(x) (((uint32_t)(x) & USB_USBCMD_RST_MASK) >> USB_USBCMD_RST_SHIFT) - -/* - * RS (RW) - * - * RS - * Run/Stop (RS) - Read/Write. Default 0b. 1=Run. 0=Stop. - * Host operation mode: - * When set to '1b', the Controller proceeds with the execution of the schedule. The Controller continues execution as long as this bit is set to a one. - * When this bit is set to 0, the Host Controller completes the current transaction on the USB and then halts. - * The HC Halted bit in the status register indicates when the Controller has finished the transaction and has entered the stopped state. - * Software should not write a one to this field unless the controller is in the Halted state (that is, HCHalted in the USBSTS register is a one). - * Device operation mode: - * Writing a one to this bit will cause the controller to enable a pull-up on D+ and initiate an attach event. - * This control bit is not directly connected to the pull-up enable, as the pull-up will become disabled upon transitioning into high-speed mode. - * Software should use this bit to prevent an attach event before the controller has been properly initialized. Writing a 0 to this will cause a detach event. - */ -#define USB_USBCMD_RS_MASK (0x1U) -#define USB_USBCMD_RS_SHIFT (0U) -#define USB_USBCMD_RS_SET(x) (((uint32_t)(x) << USB_USBCMD_RS_SHIFT) & USB_USBCMD_RS_MASK) -#define USB_USBCMD_RS_GET(x) (((uint32_t)(x) & USB_USBCMD_RS_MASK) >> USB_USBCMD_RS_SHIFT) - -/* Bitfield definition for register: USBSTS */ -/* - * TI1 (RWC) - * - * TI1 - * General Purpose Timer Interrupt 1(GPTINT1)--R/WC. - * This bit is set when the counter in the GPTIMER1CTRL register transitions to zero, writing a one to this - * bit will clear it. - */ -#define USB_USBSTS_TI1_MASK (0x2000000UL) -#define USB_USBSTS_TI1_SHIFT (25U) -#define USB_USBSTS_TI1_SET(x) (((uint32_t)(x) << USB_USBSTS_TI1_SHIFT) & USB_USBSTS_TI1_MASK) -#define USB_USBSTS_TI1_GET(x) (((uint32_t)(x) & USB_USBSTS_TI1_MASK) >> USB_USBSTS_TI1_SHIFT) - -/* - * TI0 (RWC) - * - * TI0 - * General Purpose Timer Interrupt 0(GPTINT0)--R/WC. - * This bit is set when the counter in the GPTIMER0CTRL register transitions to zero, writing a one to this - * bit clears it. - */ -#define USB_USBSTS_TI0_MASK (0x1000000UL) -#define USB_USBSTS_TI0_SHIFT (24U) -#define USB_USBSTS_TI0_SET(x) (((uint32_t)(x) << USB_USBSTS_TI0_SHIFT) & USB_USBSTS_TI0_MASK) -#define USB_USBSTS_TI0_GET(x) (((uint32_t)(x) & USB_USBSTS_TI0_MASK) >> USB_USBSTS_TI0_SHIFT) - -/* - * UPI (RWC) - * - * USB Host Periodic Interrupt – RWC. Default = 0b. - * This bit is set by the Host Controller when the cause of an interrupt is a completion of a USB transaction - * where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set and the TD was from the periodic schedule. - * This bit is also set by the Host Controller when a short packet is detected and the packet is on the periodic schedule. - * A short packet is when the actual number of bytes received was less than expected. - * This bit is not used by the device controller and will always be zero. - */ -#define USB_USBSTS_UPI_MASK (0x80000UL) -#define USB_USBSTS_UPI_SHIFT (19U) -#define USB_USBSTS_UPI_SET(x) (((uint32_t)(x) << USB_USBSTS_UPI_SHIFT) & USB_USBSTS_UPI_MASK) -#define USB_USBSTS_UPI_GET(x) (((uint32_t)(x) & USB_USBSTS_UPI_MASK) >> USB_USBSTS_UPI_SHIFT) - -/* - * UAI (RWC) - * - * USB Host Asynchronous Interrupt – RWC. Default = 0b. - * This bit is set by the Host Controller when the cause of an interrupt is a completion of a USB transaction - * where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set AND the TD was from the asynchronous schedule. - * This bit is also set by the Host when a short packet is detected and the packet is on the asynchronous schedule. - * A short packet is when the actual number of bytes received was less than expected. - * This bit is not used by the device controller and will always be zero - */ -#define USB_USBSTS_UAI_MASK (0x40000UL) -#define USB_USBSTS_UAI_SHIFT (18U) -#define USB_USBSTS_UAI_SET(x) (((uint32_t)(x) << USB_USBSTS_UAI_SHIFT) & USB_USBSTS_UAI_MASK) -#define USB_USBSTS_UAI_GET(x) (((uint32_t)(x) & USB_USBSTS_UAI_MASK) >> USB_USBSTS_UAI_SHIFT) - -/* - * NAKI (RO) - * - * NAKI - * NAK Interrupt Bit--RO. - * This bit is set by hardware when for a particular endpoint both the TX/RX Endpoint NAK bit and - * corresponding TX/RX Endpoint NAK Enable bit are set. This bit is automatically cleared by hardware - * when all Enabled TX/RX Endpoint NAK bits are cleared. - */ -#define USB_USBSTS_NAKI_MASK (0x10000UL) -#define USB_USBSTS_NAKI_SHIFT (16U) -#define USB_USBSTS_NAKI_GET(x) (((uint32_t)(x) & USB_USBSTS_NAKI_MASK) >> USB_USBSTS_NAKI_SHIFT) - -/* - * AS (RO) - * - * AS - * Asynchronous Schedule Status - Read Only. - * This bit reports the current real status of the Asynchronous Schedule. When set to zero the asynchronous schedule status is disabled and if set to one the status is enabled. - * The Host Controller is not required to immediately disable or enable the Asynchronous Schedule when software transitions the Asynchronous Schedule Enable bit in the USBCMD register. - * When this bit and the Asynchronous Schedule Enable bit are the same value, the Asynchronous Schedule is either enabled (1) or disabled (0). - * Only used in the host operation mode. - */ -#define USB_USBSTS_AS_MASK (0x8000U) -#define USB_USBSTS_AS_SHIFT (15U) -#define USB_USBSTS_AS_GET(x) (((uint32_t)(x) & USB_USBSTS_AS_MASK) >> USB_USBSTS_AS_SHIFT) - -/* - * PS (RO) - * - * PS - * Periodic Schedule Status - Read Only. - * This bit reports the current real status of the Periodic Schedule. When set to zero the periodic schedule is disabled, and if set to one the status is enabled. - * The Host Controller is not required to immediately disable or enable the Periodic Schedule when software transitions the Periodic Schedule Enable bit in the USBCMD register. - * When this bit and the Periodic Schedule Enable bit are the same value, the Periodic Schedule is either enabled (1) or disabled (0). - * Only used in the host operation mode. - */ -#define USB_USBSTS_PS_MASK (0x4000U) -#define USB_USBSTS_PS_SHIFT (14U) -#define USB_USBSTS_PS_GET(x) (((uint32_t)(x) & USB_USBSTS_PS_MASK) >> USB_USBSTS_PS_SHIFT) - -/* - * RCL (RO) - * - * RCL - * Reclamation - Read Only. - * This is a read-only status bit used to detect an empty asynchronous schedule. - * Only used in the host operation mode. - */ -#define USB_USBSTS_RCL_MASK (0x2000U) -#define USB_USBSTS_RCL_SHIFT (13U) -#define USB_USBSTS_RCL_GET(x) (((uint32_t)(x) & USB_USBSTS_RCL_MASK) >> USB_USBSTS_RCL_SHIFT) - -/* - * HCH (RO) - * - * HCH - * HCHaIted - Read Only. - * This bit is a zero whenever the Run/Stop bit is a one. - * The Controller sets this bit to one after it has stopped executing because of the Run/Stop bit being set to 0, - * either by software or by the Controller hardware (for example, an internal error). - * Only used in the host operation mode. - * Default value is '0b' for OTG core . - * This is because OTG core is not operating as host in default. Please see CM bit in USB_n_USBMODE - * register. - * NOTE: HCH bit reset value: '0b' for OTG controller core . - */ -#define USB_USBSTS_HCH_MASK (0x1000U) -#define USB_USBSTS_HCH_SHIFT (12U) -#define USB_USBSTS_HCH_GET(x) (((uint32_t)(x) & USB_USBSTS_HCH_MASK) >> USB_USBSTS_HCH_SHIFT) - -/* - * SLI (RWC) - * - * SLI - * DCSuspend - R/WC. - * When a controller enters a suspend state from an active state, this bit will be set to a one. The device controller clears the bit upon exiting from a suspend state. - * Only used in device operation mode. - */ -#define USB_USBSTS_SLI_MASK (0x100U) -#define USB_USBSTS_SLI_SHIFT (8U) -#define USB_USBSTS_SLI_SET(x) (((uint32_t)(x) << USB_USBSTS_SLI_SHIFT) & USB_USBSTS_SLI_MASK) -#define USB_USBSTS_SLI_GET(x) (((uint32_t)(x) & USB_USBSTS_SLI_MASK) >> USB_USBSTS_SLI_SHIFT) - -/* - * SRI (RWC) - * - * SRI - * SOF Received - R/WC. - * When the device controller detects a Start Of (micro) Frame, this bit will be set to a one. - * When a SOF is extremely late, the device controller will automatically set this bit to indicate that an SOF was expected. - * Therefore, this bit will be set roughly every 1ms in device FS mode and every 125ms in HS mode and will be synchronized to the actual SOF that is received. - * Because the device controller is initialized to FS before connect, this bit will be set at an interval of 1ms during the prelude to connect and chirp. - * In host mode, this bit will be set every 125us and can be used by host controller driver as a time base. - * Software writes a 1 to this bit to clear it. - */ -#define USB_USBSTS_SRI_MASK (0x80U) -#define USB_USBSTS_SRI_SHIFT (7U) -#define USB_USBSTS_SRI_SET(x) (((uint32_t)(x) << USB_USBSTS_SRI_SHIFT) & USB_USBSTS_SRI_MASK) -#define USB_USBSTS_SRI_GET(x) (((uint32_t)(x) & USB_USBSTS_SRI_MASK) >> USB_USBSTS_SRI_SHIFT) - -/* - * URI (RWC) - * - * URI - * USB Reset Received - R/WC. - * When the device controller detects a USB Reset and enters the default state, this bit will be set to a one. - * Software can write a 1 to this bit to clear the USB Reset Received status bit. - * Only used in device operation mode. - */ -#define USB_USBSTS_URI_MASK (0x40U) -#define USB_USBSTS_URI_SHIFT (6U) -#define USB_USBSTS_URI_SET(x) (((uint32_t)(x) << USB_USBSTS_URI_SHIFT) & USB_USBSTS_URI_MASK) -#define USB_USBSTS_URI_GET(x) (((uint32_t)(x) & USB_USBSTS_URI_MASK) >> USB_USBSTS_URI_SHIFT) - -/* - * AAI (RWC) - * - * AAI - * Interrupt on Async Advance - R/WC. - * System software can force the host controller to issue an interrupt the next time the host controller advances the asynchronous schedule - * by writing a one to the Interrupt on Async Advance Doorbell bit in the n_USBCMD register. This status bit indicates the assertion of that interrupt source. - * Only used in host operation mode. - */ -#define USB_USBSTS_AAI_MASK (0x20U) -#define USB_USBSTS_AAI_SHIFT (5U) -#define USB_USBSTS_AAI_SET(x) (((uint32_t)(x) << USB_USBSTS_AAI_SHIFT) & USB_USBSTS_AAI_MASK) -#define USB_USBSTS_AAI_GET(x) (((uint32_t)(x) & USB_USBSTS_AAI_MASK) >> USB_USBSTS_AAI_SHIFT) - -/* - * SEI (RWC) - * - * System Error – RWC. Default = 0b. - * In the BVCI implementation of the USBHS core, this bit is not used, and will always be cleared to '0b'. - * In the AMBA implementation, this bit will be set to '1b' when an Error response is seen by the master interface (HRESP[1:0]=ERROR) - */ -#define USB_USBSTS_SEI_MASK (0x10U) -#define USB_USBSTS_SEI_SHIFT (4U) -#define USB_USBSTS_SEI_SET(x) (((uint32_t)(x) << USB_USBSTS_SEI_SHIFT) & USB_USBSTS_SEI_MASK) -#define USB_USBSTS_SEI_GET(x) (((uint32_t)(x) & USB_USBSTS_SEI_MASK) >> USB_USBSTS_SEI_SHIFT) - -/* - * FRI (RWC) - * - * FRI - * Frame List Rollover - R/WC. - * The Host Controller sets this bit to a one when the Frame List Index rolls over from its maximum value to - * zero. The exact value at which the rollover occurs depends on the frame list size. For example. If the - * frame list size (as programmed in the Frame List Size field of the USB_n_USBCMD register) is 1024, the - * Frame Index Register rolls over every time FRINDEX [13] toggles. Similarly, if the size is 512, the Host - * Controller sets this bit to a one every time FHINDEX [12] toggles. - * Only used in host operation mode. - */ -#define USB_USBSTS_FRI_MASK (0x8U) -#define USB_USBSTS_FRI_SHIFT (3U) -#define USB_USBSTS_FRI_SET(x) (((uint32_t)(x) << USB_USBSTS_FRI_SHIFT) & USB_USBSTS_FRI_MASK) -#define USB_USBSTS_FRI_GET(x) (((uint32_t)(x) & USB_USBSTS_FRI_MASK) >> USB_USBSTS_FRI_SHIFT) - -/* - * PCI (RWC) - * - * PCI - * Port Change Detect - R/WC. - * The Host Controller sets this bit to a one when on any port a Connect Status occurs, a Port Enable/Disable Change occurs, - * or the Force Port Resume bit is set as the result of a J-K transition on the suspended port. - * The Device Controller sets this bit to a one when the port controller enters the full or high-speed operational state. - * When the port controller exits the full or high-speed operation states due to Reset or Suspend events, - * the notification mechanisms are the USB Reset Received bit and the DCSuspend bits Respectively. - */ -#define USB_USBSTS_PCI_MASK (0x4U) -#define USB_USBSTS_PCI_SHIFT (2U) -#define USB_USBSTS_PCI_SET(x) (((uint32_t)(x) << USB_USBSTS_PCI_SHIFT) & USB_USBSTS_PCI_MASK) -#define USB_USBSTS_PCI_GET(x) (((uint32_t)(x) & USB_USBSTS_PCI_MASK) >> USB_USBSTS_PCI_SHIFT) - -/* - * UEI (RWC) - * - * UEI - * USB Error Interrupt (USBERRINT) - R/WC. - * When completion of a USB transaction results in an error condition, this bit is set by the Host/Device Controller. - * This bit is set along with the USBINT bit, if the TD on which the error interrupt occurred also had its interrupt on complete (IOC) bit set. - */ -#define USB_USBSTS_UEI_MASK (0x2U) -#define USB_USBSTS_UEI_SHIFT (1U) -#define USB_USBSTS_UEI_SET(x) (((uint32_t)(x) << USB_USBSTS_UEI_SHIFT) & USB_USBSTS_UEI_MASK) -#define USB_USBSTS_UEI_GET(x) (((uint32_t)(x) & USB_USBSTS_UEI_MASK) >> USB_USBSTS_UEI_SHIFT) - -/* - * UI (RWC) - * - * UI - * USB Interrupt (USBINT) - R/WC. - * This bit is set by the Host/Device Controller when the cause of an interrupt is a completion of a USB - * transaction where the Transfer Descriptor (TD) has an interrupt on complete (IOC) bit set. - * This bit is also set by the Host/Device Controller when a short packet is detected. A short packet is when - * the actual number of bytes received was less than the expected number of bytes. - */ -#define USB_USBSTS_UI_MASK (0x1U) -#define USB_USBSTS_UI_SHIFT (0U) -#define USB_USBSTS_UI_SET(x) (((uint32_t)(x) << USB_USBSTS_UI_SHIFT) & USB_USBSTS_UI_MASK) -#define USB_USBSTS_UI_GET(x) (((uint32_t)(x) & USB_USBSTS_UI_MASK) >> USB_USBSTS_UI_SHIFT) - -/* Bitfield definition for register: USBINTR */ -/* - * TIE1 (RW) - * - * TIE1 - * General Purpose Timer #1 Interrupt Enable - * When this bit is one and the TI1 bit in n_USBSTS register is a one the controller will issue an interrupt. - */ -#define USB_USBINTR_TIE1_MASK (0x2000000UL) -#define USB_USBINTR_TIE1_SHIFT (25U) -#define USB_USBINTR_TIE1_SET(x) (((uint32_t)(x) << USB_USBINTR_TIE1_SHIFT) & USB_USBINTR_TIE1_MASK) -#define USB_USBINTR_TIE1_GET(x) (((uint32_t)(x) & USB_USBINTR_TIE1_MASK) >> USB_USBINTR_TIE1_SHIFT) - -/* - * TIE0 (RW) - * - * TIE0 - * General Purpose Timer #0 Interrupt Enable - * When this bit is one and the TI0 bit in n_USBSTS register is a one the controller will issue an interrupt. - */ -#define USB_USBINTR_TIE0_MASK (0x1000000UL) -#define USB_USBINTR_TIE0_SHIFT (24U) -#define USB_USBINTR_TIE0_SET(x) (((uint32_t)(x) << USB_USBINTR_TIE0_SHIFT) & USB_USBINTR_TIE0_MASK) -#define USB_USBINTR_TIE0_GET(x) (((uint32_t)(x) & USB_USBINTR_TIE0_MASK) >> USB_USBINTR_TIE0_SHIFT) - -/* - * UPIE (RW) - * - * UPIE - * USB Host Periodic Interrupt Enable - * When this bit is one, and the UPI bit in the n_USBSTS register is one, host controller will issue an - * interrupt at the next interrupt threshold. - */ -#define USB_USBINTR_UPIE_MASK (0x80000UL) -#define USB_USBINTR_UPIE_SHIFT (19U) -#define USB_USBINTR_UPIE_SET(x) (((uint32_t)(x) << USB_USBINTR_UPIE_SHIFT) & USB_USBINTR_UPIE_MASK) -#define USB_USBINTR_UPIE_GET(x) (((uint32_t)(x) & USB_USBINTR_UPIE_MASK) >> USB_USBINTR_UPIE_SHIFT) - -/* - * UAIE (RW) - * - * UAIE - * USB Host Asynchronous Interrupt Enable - * When this bit is one, and the UAI bit in the n_USBSTS register is one, host controller will issue an - * interrupt at the next interrupt threshold. - */ -#define USB_USBINTR_UAIE_MASK (0x40000UL) -#define USB_USBINTR_UAIE_SHIFT (18U) -#define USB_USBINTR_UAIE_SET(x) (((uint32_t)(x) << USB_USBINTR_UAIE_SHIFT) & USB_USBINTR_UAIE_MASK) -#define USB_USBINTR_UAIE_GET(x) (((uint32_t)(x) & USB_USBINTR_UAIE_MASK) >> USB_USBINTR_UAIE_SHIFT) - -/* - * NAKE (RO) - * - * NAKE - * NAK Interrupt Enable - * When this bit is one and the NAKI bit in n_USBSTS register is a one the controller will issue an interrupt. - */ -#define USB_USBINTR_NAKE_MASK (0x10000UL) -#define USB_USBINTR_NAKE_SHIFT (16U) -#define USB_USBINTR_NAKE_GET(x) (((uint32_t)(x) & USB_USBINTR_NAKE_MASK) >> USB_USBINTR_NAKE_SHIFT) - -/* - * SLE (RW) - * - * SLE - * Sleep Interrupt Enable - * When this bit is one and the SLI bit in n_n_USBSTS register is a one the controller will issue an interrupt. - * Only used in device operation mode. - */ -#define USB_USBINTR_SLE_MASK (0x100U) -#define USB_USBINTR_SLE_SHIFT (8U) -#define USB_USBINTR_SLE_SET(x) (((uint32_t)(x) << USB_USBINTR_SLE_SHIFT) & USB_USBINTR_SLE_MASK) -#define USB_USBINTR_SLE_GET(x) (((uint32_t)(x) & USB_USBINTR_SLE_MASK) >> USB_USBINTR_SLE_SHIFT) - -/* - * SRE (RW) - * - * SRE - * SOF Received Interrupt Enable - * When this bit is one and the SRI bit in n_USBSTS register is a one the controller will issue an interrupt. - */ -#define USB_USBINTR_SRE_MASK (0x80U) -#define USB_USBINTR_SRE_SHIFT (7U) -#define USB_USBINTR_SRE_SET(x) (((uint32_t)(x) << USB_USBINTR_SRE_SHIFT) & USB_USBINTR_SRE_MASK) -#define USB_USBINTR_SRE_GET(x) (((uint32_t)(x) & USB_USBINTR_SRE_MASK) >> USB_USBINTR_SRE_SHIFT) - -/* - * URE (RW) - * - * URE - * USB Reset Interrupt Enable - * When this bit is one and the URI bit in n_USBSTS register is a one the controller will issue an interrupt. - * Only used in device operation mode. - */ -#define USB_USBINTR_URE_MASK (0x40U) -#define USB_USBINTR_URE_SHIFT (6U) -#define USB_USBINTR_URE_SET(x) (((uint32_t)(x) << USB_USBINTR_URE_SHIFT) & USB_USBINTR_URE_MASK) -#define USB_USBINTR_URE_GET(x) (((uint32_t)(x) & USB_USBINTR_URE_MASK) >> USB_USBINTR_URE_SHIFT) - -/* - * AAE (RW) - * - * AAE - * Async Advance Interrupt Enable - * When this bit is one and the AAI bit in n_USBSTS register is a one the controller will issue an interrupt. - * Only used in host operation mode. - */ -#define USB_USBINTR_AAE_MASK (0x20U) -#define USB_USBINTR_AAE_SHIFT (5U) -#define USB_USBINTR_AAE_SET(x) (((uint32_t)(x) << USB_USBINTR_AAE_SHIFT) & USB_USBINTR_AAE_MASK) -#define USB_USBINTR_AAE_GET(x) (((uint32_t)(x) & USB_USBINTR_AAE_MASK) >> USB_USBINTR_AAE_SHIFT) - -/* - * SEE (RW) - * - * SEE - * System Error Interrupt Enable - * When this bit is one and the SEI bit in n_USBSTS register is a one the controller will issue an interrupt. - * Only used in host operation mode. - */ -#define USB_USBINTR_SEE_MASK (0x10U) -#define USB_USBINTR_SEE_SHIFT (4U) -#define USB_USBINTR_SEE_SET(x) (((uint32_t)(x) << USB_USBINTR_SEE_SHIFT) & USB_USBINTR_SEE_MASK) -#define USB_USBINTR_SEE_GET(x) (((uint32_t)(x) & USB_USBINTR_SEE_MASK) >> USB_USBINTR_SEE_SHIFT) - -/* - * FRE (RW) - * - * FRE - * Frame List Rollover Interrupt Enable - * When this bit is one and the FRI bit in n_USBSTS register is a one the controller will issue an interrupt. - * Only used in host operation mode. - */ -#define USB_USBINTR_FRE_MASK (0x8U) -#define USB_USBINTR_FRE_SHIFT (3U) -#define USB_USBINTR_FRE_SET(x) (((uint32_t)(x) << USB_USBINTR_FRE_SHIFT) & USB_USBINTR_FRE_MASK) -#define USB_USBINTR_FRE_GET(x) (((uint32_t)(x) & USB_USBINTR_FRE_MASK) >> USB_USBINTR_FRE_SHIFT) - -/* - * PCE (RW) - * - * PCE - * Port Change Detect Interrupt Enable - * When this bit is one and the PCI bit in n_USBSTS register is a one the controller will issue an interrupt. - */ -#define USB_USBINTR_PCE_MASK (0x4U) -#define USB_USBINTR_PCE_SHIFT (2U) -#define USB_USBINTR_PCE_SET(x) (((uint32_t)(x) << USB_USBINTR_PCE_SHIFT) & USB_USBINTR_PCE_MASK) -#define USB_USBINTR_PCE_GET(x) (((uint32_t)(x) & USB_USBINTR_PCE_MASK) >> USB_USBINTR_PCE_SHIFT) - -/* - * UEE (RWC) - * - * UEE - * USB Error Interrupt Enable - * When this bit is one and the UEI bit in n_USBSTS register is a one the controller will issue an interrupt. - */ -#define USB_USBINTR_UEE_MASK (0x2U) -#define USB_USBINTR_UEE_SHIFT (1U) -#define USB_USBINTR_UEE_SET(x) (((uint32_t)(x) << USB_USBINTR_UEE_SHIFT) & USB_USBINTR_UEE_MASK) -#define USB_USBINTR_UEE_GET(x) (((uint32_t)(x) & USB_USBINTR_UEE_MASK) >> USB_USBINTR_UEE_SHIFT) - -/* - * UE (RW) - * - * UE - * USB Interrupt Enable - * When this bit is one and the UI bit in n_USBSTS register is a one the controller will issue an interrupt. - */ -#define USB_USBINTR_UE_MASK (0x1U) -#define USB_USBINTR_UE_SHIFT (0U) -#define USB_USBINTR_UE_SET(x) (((uint32_t)(x) << USB_USBINTR_UE_SHIFT) & USB_USBINTR_UE_MASK) -#define USB_USBINTR_UE_GET(x) (((uint32_t)(x) & USB_USBINTR_UE_MASK) >> USB_USBINTR_UE_SHIFT) - -/* Bitfield definition for register: FRINDEX */ -/* - * FRINDEX (RW) - * - * FRINDEX - * Frame Index. - * The value, in this register, increments at the end of each time frame (micro-frame). Bits [N: 3] are used for the Frame List current index. - * This means that each location of the frame list is accessed 8 times (frames or micro-frames) before moving to the next index. - * The following illustrates values of N based on the value of the Frame List Size field in the USBCMD register, when used in host mode. - * USBCMD [Frame List Size] Number Elements N - * In device mode the value is the current frame number of the last frame transmitted. It is not used as an index. - * In either mode bits 2:0 indicate the current microframe. - * The bit field values description below is represented as (Frame List Size) Number Elements N. - * 00000000000000 - (1024) 12 - * 00000000000001 - (512) 11 - * 00000000000010 - (256) 10 - * 00000000000011 - (128) 9 - * 00000000000100 - (64) 8 - * 00000000000101 - (32) 7 - * 00000000000110 - (16) 6 - * 00000000000111 - (8) 5 - */ -#define USB_FRINDEX_FRINDEX_MASK (0x3FFFU) -#define USB_FRINDEX_FRINDEX_SHIFT (0U) -#define USB_FRINDEX_FRINDEX_SET(x) (((uint32_t)(x) << USB_FRINDEX_FRINDEX_SHIFT) & USB_FRINDEX_FRINDEX_MASK) -#define USB_FRINDEX_FRINDEX_GET(x) (((uint32_t)(x) & USB_FRINDEX_FRINDEX_MASK) >> USB_FRINDEX_FRINDEX_SHIFT) - -/* Bitfield definition for register: DEVICEADDR */ -/* - * USBADR (RW) - * - * USBADR - * Device Address. - * These bits correspond to the USB device address - */ -#define USB_DEVICEADDR_USBADR_MASK (0xFE000000UL) -#define USB_DEVICEADDR_USBADR_SHIFT (25U) -#define USB_DEVICEADDR_USBADR_SET(x) (((uint32_t)(x) << USB_DEVICEADDR_USBADR_SHIFT) & USB_DEVICEADDR_USBADR_MASK) -#define USB_DEVICEADDR_USBADR_GET(x) (((uint32_t)(x) & USB_DEVICEADDR_USBADR_MASK) >> USB_DEVICEADDR_USBADR_SHIFT) - -/* - * USBADRA (RW) - * - * USBADRA - * Device Address Advance. Default=0. - * When this bit is '0', any writes to USBADR are instantaneous. - * When this bit is written to a '1' at the same time or before USBADR is written, the write to the USBADR field is staged and held in a hidden register. - * After an IN occurs on endpoint 0 and is ACKed, USBADR will be loaded from the holding register. - * Hardware will automatically clear this bit on the following conditions: - * 1) IN is ACKed to endpoint 0. (USBADR is updated from staging register). - * 2) OUT/SETUP occur to endpoint 0. (USBADR is not updated). - * 3) Device Reset occurs (USBADR is reset to 0). - * NOTE: After the status phase of the SET_ADDRESS descriptor, the DCD has 2 ms to program the USBADR field. - * This mechanism will ensure this specification is met when the DCD can not write of the device address within 2ms from the SET_ADDRESS status phase. - * If the DCD writes the USBADR with USBADRA=1 after the SET_ADDRESS data phase (before the prime of the status phase), - * the USBADR will be programmed instantly at the correct time and meet the 2ms USB requirement. - */ -#define USB_DEVICEADDR_USBADRA_MASK (0x1000000UL) -#define USB_DEVICEADDR_USBADRA_SHIFT (24U) -#define USB_DEVICEADDR_USBADRA_SET(x) (((uint32_t)(x) << USB_DEVICEADDR_USBADRA_SHIFT) & USB_DEVICEADDR_USBADRA_MASK) -#define USB_DEVICEADDR_USBADRA_GET(x) (((uint32_t)(x) & USB_DEVICEADDR_USBADRA_MASK) >> USB_DEVICEADDR_USBADRA_SHIFT) - -/* Bitfield definition for register: PERIODICLISTBASE */ -/* - * BASEADR (RW) - * - * BASEADR - * Base Address (Low). - * These bits correspond to memory address signals [31:12], respectively. - * Only used by the host controller. - */ -#define USB_PERIODICLISTBASE_BASEADR_MASK (0xFFFFF000UL) -#define USB_PERIODICLISTBASE_BASEADR_SHIFT (12U) -#define USB_PERIODICLISTBASE_BASEADR_SET(x) (((uint32_t)(x) << USB_PERIODICLISTBASE_BASEADR_SHIFT) & USB_PERIODICLISTBASE_BASEADR_MASK) -#define USB_PERIODICLISTBASE_BASEADR_GET(x) (((uint32_t)(x) & USB_PERIODICLISTBASE_BASEADR_MASK) >> USB_PERIODICLISTBASE_BASEADR_SHIFT) - -/* Bitfield definition for register: ASYNCLISTADDR */ -/* - * ASYBASE (RW) - * - * ASYBASE - * Link Pointer Low (LPL). - * These bits correspond to memory address signals [31:5], respectively. This field may only reference a - * Queue Head (QH). - * Only used by the host controller. - */ -#define USB_ASYNCLISTADDR_ASYBASE_MASK (0xFFFFFFE0UL) -#define USB_ASYNCLISTADDR_ASYBASE_SHIFT (5U) -#define USB_ASYNCLISTADDR_ASYBASE_SET(x) (((uint32_t)(x) << USB_ASYNCLISTADDR_ASYBASE_SHIFT) & USB_ASYNCLISTADDR_ASYBASE_MASK) -#define USB_ASYNCLISTADDR_ASYBASE_GET(x) (((uint32_t)(x) & USB_ASYNCLISTADDR_ASYBASE_MASK) >> USB_ASYNCLISTADDR_ASYBASE_SHIFT) - -/* Bitfield definition for register: ENDPTLISTADDR */ -/* - * EPBASE (RW) - * - * EPBASE - * Endpoint List Pointer(Low). These bits correspond to memory address signals [31:11], respectively. - * This field will reference a list of up to 32 Queue Head (QH) (that is, one queue head per endpoint & direction). - */ -#define USB_ENDPTLISTADDR_EPBASE_MASK (0xFFFFF800UL) -#define USB_ENDPTLISTADDR_EPBASE_SHIFT (11U) -#define USB_ENDPTLISTADDR_EPBASE_SET(x) (((uint32_t)(x) << USB_ENDPTLISTADDR_EPBASE_SHIFT) & USB_ENDPTLISTADDR_EPBASE_MASK) -#define USB_ENDPTLISTADDR_EPBASE_GET(x) (((uint32_t)(x) & USB_ENDPTLISTADDR_EPBASE_MASK) >> USB_ENDPTLISTADDR_EPBASE_SHIFT) - -/* Bitfield definition for register: BURSTSIZE */ -/* - * TXPBURST (RW) - * - * TXPBURST - * Programmable TX Burst Size. - * Default value is determined by TXBURST bits in n_HWTXBUF. - * This register represents the maximum length of a the burst in 32-bit words while moving data from system - * memory to the USB bus. - */ -#define USB_BURSTSIZE_TXPBURST_MASK (0xFF00U) -#define USB_BURSTSIZE_TXPBURST_SHIFT (8U) -#define USB_BURSTSIZE_TXPBURST_SET(x) (((uint32_t)(x) << USB_BURSTSIZE_TXPBURST_SHIFT) & USB_BURSTSIZE_TXPBURST_MASK) -#define USB_BURSTSIZE_TXPBURST_GET(x) (((uint32_t)(x) & USB_BURSTSIZE_TXPBURST_MASK) >> USB_BURSTSIZE_TXPBURST_SHIFT) - -/* - * RXPBURST (RW) - * - * RXPBURST - * Programmable RX Burst Size. - * Default value is determined by TXBURST bits in n_HWRXBUF. - * This register represents the maximum length of a the burst in 32-bit words while moving data from the - * USB bus to system memory. - */ -#define USB_BURSTSIZE_RXPBURST_MASK (0xFFU) -#define USB_BURSTSIZE_RXPBURST_SHIFT (0U) -#define USB_BURSTSIZE_RXPBURST_SET(x) (((uint32_t)(x) << USB_BURSTSIZE_RXPBURST_SHIFT) & USB_BURSTSIZE_RXPBURST_MASK) -#define USB_BURSTSIZE_RXPBURST_GET(x) (((uint32_t)(x) & USB_BURSTSIZE_RXPBURST_MASK) >> USB_BURSTSIZE_RXPBURST_SHIFT) - -/* Bitfield definition for register: TXFILLTUNING */ -/* - * TXFIFOTHRES (RW) - * - * TXFIFOTHRES - * FIFO Burst Threshold. (Read/Write) - * This register controls the number of data bursts that are posted to the TX latency FIFO in host mode before the packet begins on to the bus. - * The minimum value is 2 and this value should be a low as possible to maximize USB performance. - * A higher value can be used in systems with unpredictable latency and/or insufficient bandwidth - * where the FIFO may underrun because the data transferred from the latency FIFO to USB occurs before it can be replenished from system memory. - * This value is ignored if the Stream Disable bit in USB_n_USBMODE register is set. - */ -#define USB_TXFILLTUNING_TXFIFOTHRES_MASK (0x3F0000UL) -#define USB_TXFILLTUNING_TXFIFOTHRES_SHIFT (16U) -#define USB_TXFILLTUNING_TXFIFOTHRES_SET(x) (((uint32_t)(x) << USB_TXFILLTUNING_TXFIFOTHRES_SHIFT) & USB_TXFILLTUNING_TXFIFOTHRES_MASK) -#define USB_TXFILLTUNING_TXFIFOTHRES_GET(x) (((uint32_t)(x) & USB_TXFILLTUNING_TXFIFOTHRES_MASK) >> USB_TXFILLTUNING_TXFIFOTHRES_SHIFT) - -/* - * TXSCHHEALTH (RWC) - * - * TXSCHHEALTH - * Scheduler Health Counter. (Read/Write To Clear) - * Table continues on the next page - * This register increments when the host controller fails to fill the TX latency FIFO to the level programmed by TXFIFOTHRES - * before running out of time to send the packet before the next Start-Of-Frame. - * This health counter measures the number of times this occurs to provide feedback to selecting a proper TXSCHOH. - * Writing to this register will clear the counter and this counter will max. at 31. - */ -#define USB_TXFILLTUNING_TXSCHHEALTH_MASK (0x1F00U) -#define USB_TXFILLTUNING_TXSCHHEALTH_SHIFT (8U) -#define USB_TXFILLTUNING_TXSCHHEALTH_SET(x) (((uint32_t)(x) << USB_TXFILLTUNING_TXSCHHEALTH_SHIFT) & USB_TXFILLTUNING_TXSCHHEALTH_MASK) -#define USB_TXFILLTUNING_TXSCHHEALTH_GET(x) (((uint32_t)(x) & USB_TXFILLTUNING_TXSCHHEALTH_MASK) >> USB_TXFILLTUNING_TXSCHHEALTH_SHIFT) - -/* - * TXSCHOH (RW) - * - * TXSCHOH - * Scheduler Overhead. (Read/Write) [Default = 0] - * This register adds an additional fixed offset to the schedule time estimator described above as Tff. - * As an approximation, the value chosen for this register should limit the number of back-off events captured - * in the TXSCHHEALTH to less than 10 per second in a highly utilized bus. - * Choosing a value that is too high for this register is not desired as it can needlessly reduce USB utilization. - * The time unit represented in this register is 1.267us when a device is connected in High-Speed Mode. - * The time unit represented in this register is 6.333us when a device is connected in Low/Full Speed Mode. - * Default value is '08h' for OTG controller core . - */ -#define USB_TXFILLTUNING_TXSCHOH_MASK (0x7FU) -#define USB_TXFILLTUNING_TXSCHOH_SHIFT (0U) -#define USB_TXFILLTUNING_TXSCHOH_SET(x) (((uint32_t)(x) << USB_TXFILLTUNING_TXSCHOH_SHIFT) & USB_TXFILLTUNING_TXSCHOH_MASK) -#define USB_TXFILLTUNING_TXSCHOH_GET(x) (((uint32_t)(x) & USB_TXFILLTUNING_TXSCHOH_MASK) >> USB_TXFILLTUNING_TXSCHOH_SHIFT) - -/* Bitfield definition for register: ENDPTNAK */ -/* - * EPTN (RWC) - * - * EPTN - * TX Endpoint NAK - R/WC. - * Each TX endpoint has 1 bit in this field. The bit is set when the - * device sends a NAK handshake on a received IN token for the corresponding endpoint. - * Bit [N] - Endpoint #[N], N is 0-7 - */ -#define USB_ENDPTNAK_EPTN_MASK (0xFFFF0000UL) -#define USB_ENDPTNAK_EPTN_SHIFT (16U) -#define USB_ENDPTNAK_EPTN_SET(x) (((uint32_t)(x) << USB_ENDPTNAK_EPTN_SHIFT) & USB_ENDPTNAK_EPTN_MASK) -#define USB_ENDPTNAK_EPTN_GET(x) (((uint32_t)(x) & USB_ENDPTNAK_EPTN_MASK) >> USB_ENDPTNAK_EPTN_SHIFT) - -/* - * EPRN (RWC) - * - * EPRN - * RX Endpoint NAK - R/WC. - * Each RX endpoint has 1 bit in this field. The bit is set when the - * device sends a NAK handshake on a received OUT or PING token for the corresponding endpoint. - * Bit [N] - Endpoint #[N], N is 0-7 - */ -#define USB_ENDPTNAK_EPRN_MASK (0xFFFFU) -#define USB_ENDPTNAK_EPRN_SHIFT (0U) -#define USB_ENDPTNAK_EPRN_SET(x) (((uint32_t)(x) << USB_ENDPTNAK_EPRN_SHIFT) & USB_ENDPTNAK_EPRN_MASK) -#define USB_ENDPTNAK_EPRN_GET(x) (((uint32_t)(x) & USB_ENDPTNAK_EPRN_MASK) >> USB_ENDPTNAK_EPRN_SHIFT) - -/* Bitfield definition for register: ENDPTNAKEN */ -/* - * EPTNE (RW) - * - * EPTNE - * TX Endpoint NAK Enable - R/W. - * Each bit is an enable bit for the corresponding TX Endpoint NAK bit. If this bit is set and the - * corresponding TX Endpoint NAK bit is set, the NAK Interrupt bit is set. - * Bit [N] - Endpoint #[N], N is 0-7 - */ -#define USB_ENDPTNAKEN_EPTNE_MASK (0xFFFF0000UL) -#define USB_ENDPTNAKEN_EPTNE_SHIFT (16U) -#define USB_ENDPTNAKEN_EPTNE_SET(x) (((uint32_t)(x) << USB_ENDPTNAKEN_EPTNE_SHIFT) & USB_ENDPTNAKEN_EPTNE_MASK) -#define USB_ENDPTNAKEN_EPTNE_GET(x) (((uint32_t)(x) & USB_ENDPTNAKEN_EPTNE_MASK) >> USB_ENDPTNAKEN_EPTNE_SHIFT) - -/* - * EPRNE (RW) - * - * EPRNE - * RX Endpoint NAK Enable - R/W. - * Each bit is an enable bit for the corresponding RX Endpoint NAK bit. If this bit is set and the - * corresponding RX Endpoint NAK bit is set, the NAK Interrupt bit is set. - * Bit [N] - Endpoint #[N], N is 0-7 - */ -#define USB_ENDPTNAKEN_EPRNE_MASK (0xFFFFU) -#define USB_ENDPTNAKEN_EPRNE_SHIFT (0U) -#define USB_ENDPTNAKEN_EPRNE_SET(x) (((uint32_t)(x) << USB_ENDPTNAKEN_EPRNE_SHIFT) & USB_ENDPTNAKEN_EPRNE_MASK) -#define USB_ENDPTNAKEN_EPRNE_GET(x) (((uint32_t)(x) & USB_ENDPTNAKEN_EPRNE_MASK) >> USB_ENDPTNAKEN_EPRNE_SHIFT) - -/* Bitfield definition for register: PORTSC1 */ -/* - * STS (RW) - * - * STS - * Serial Transceiver Select - * 1 Serial Interface Engine is selected - * 0 Parallel Interface signals is selected - * Serial Interface Engine can be used in combination with UTMI+/ULPI physical interface to provide FS/LS signaling instead of the parallel interface signals. - * When this bit is set '1b', serial interface engine will be used instead of parallel interface signals. - */ -#define USB_PORTSC1_STS_MASK (0x20000000UL) -#define USB_PORTSC1_STS_SHIFT (29U) -#define USB_PORTSC1_STS_SET(x) (((uint32_t)(x) << USB_PORTSC1_STS_SHIFT) & USB_PORTSC1_STS_MASK) -#define USB_PORTSC1_STS_GET(x) (((uint32_t)(x) & USB_PORTSC1_STS_MASK) >> USB_PORTSC1_STS_SHIFT) - -/* - * PTW (RW) - * - * PTW - * Parallel Transceiver Width - * This bit has no effect if serial interface engine is used. - * 0 - Select the 8-bit UTMI interface [60MHz] - * 1 - Select the 16-bit UTMI interface [30MHz] - */ -#define USB_PORTSC1_PTW_MASK (0x10000000UL) -#define USB_PORTSC1_PTW_SHIFT (28U) -#define USB_PORTSC1_PTW_SET(x) (((uint32_t)(x) << USB_PORTSC1_PTW_SHIFT) & USB_PORTSC1_PTW_MASK) -#define USB_PORTSC1_PTW_GET(x) (((uint32_t)(x) & USB_PORTSC1_PTW_MASK) >> USB_PORTSC1_PTW_SHIFT) - -/* - * PSPD (RO) - * - * PSPD - * Port Speed - Read Only. - * This register field indicates the speed at which the port is operating. - * 00 - Full Speed - * 01 - Low Speed - * 10 - High Speed - * 11 - Undefined - */ -#define USB_PORTSC1_PSPD_MASK (0xC000000UL) -#define USB_PORTSC1_PSPD_SHIFT (26U) -#define USB_PORTSC1_PSPD_GET(x) (((uint32_t)(x) & USB_PORTSC1_PSPD_MASK) >> USB_PORTSC1_PSPD_SHIFT) - -/* - * PFSC (RW) - * - * PFSC - * Port Force Full Speed Connect - Read/Write. Default = 0b. - * When this bit is set to '1b', the port will be forced to only connect at Full Speed, It disables the chirp - * sequence that allows the port to identify itself as High Speed. - * 0 - Normal operation - * 1 - Forced to full speed - */ -#define USB_PORTSC1_PFSC_MASK (0x1000000UL) -#define USB_PORTSC1_PFSC_SHIFT (24U) -#define USB_PORTSC1_PFSC_SET(x) (((uint32_t)(x) << USB_PORTSC1_PFSC_SHIFT) & USB_PORTSC1_PFSC_MASK) -#define USB_PORTSC1_PFSC_GET(x) (((uint32_t)(x) & USB_PORTSC1_PFSC_MASK) >> USB_PORTSC1_PFSC_SHIFT) - -/* - * PHCD (RW) - * - * PHCD - * PHY Low Power Suspend - Clock Disable (PLPSCD) - Read/Write. Default = 0b. - * When this bit is set to '1b', the PHY clock is disabled. Reading this bit will indicate the status of the PHY - * clock. - * NOTE: The PHY clock cannot be disabled if it is being used as the system clock. - * In device mode, The PHY can be put into Low Power Suspend when the device is not running (USBCMD - * Run/Stop=0b) or the host has signalled suspend (PORTSC1 SUSPEND=1b). PHY Low power suspend - * will be cleared automatically when the host initials resume. Before forcing a resume from the device, the - * device controller driver must clear this bit. - * In host mode, the PHY can be put into Low Power Suspend when the downstream device has been put - * into suspend mode or when no downstream device is connected. Low power suspend is completely - * under the control of software. - * 0 - Enable PHY clock - * 1 - Disable PHY clock - */ -#define USB_PORTSC1_PHCD_MASK (0x800000UL) -#define USB_PORTSC1_PHCD_SHIFT (23U) -#define USB_PORTSC1_PHCD_SET(x) (((uint32_t)(x) << USB_PORTSC1_PHCD_SHIFT) & USB_PORTSC1_PHCD_MASK) -#define USB_PORTSC1_PHCD_GET(x) (((uint32_t)(x) & USB_PORTSC1_PHCD_MASK) >> USB_PORTSC1_PHCD_SHIFT) - -/* - * WKOC (RW) - * - * WKOC - * Wake on Over-current Enable (WKOC_E) - Read/Write. Default = 0b. - * Writing this bit to a one enables the port to be sensitive to over-current conditions as wake-up events. - * This field is zero if Port Power(PORTSC1) is zero. - */ -#define USB_PORTSC1_WKOC_MASK (0x400000UL) -#define USB_PORTSC1_WKOC_SHIFT (22U) -#define USB_PORTSC1_WKOC_SET(x) (((uint32_t)(x) << USB_PORTSC1_WKOC_SHIFT) & USB_PORTSC1_WKOC_MASK) -#define USB_PORTSC1_WKOC_GET(x) (((uint32_t)(x) & USB_PORTSC1_WKOC_MASK) >> USB_PORTSC1_WKOC_SHIFT) - -/* - * WKDC (RW) - * - * WKDC - * Wake on Disconnect Enable (WKDSCNNT_E) - Read/Write. Default=0b. Writing this bit to a one enables - * the port to be sensitive to device disconnects as wake-up events. - * This field is zero if Port Power(PORTSC1) is zero or in device mode. - */ -#define USB_PORTSC1_WKDC_MASK (0x200000UL) -#define USB_PORTSC1_WKDC_SHIFT (21U) -#define USB_PORTSC1_WKDC_SET(x) (((uint32_t)(x) << USB_PORTSC1_WKDC_SHIFT) & USB_PORTSC1_WKDC_MASK) -#define USB_PORTSC1_WKDC_GET(x) (((uint32_t)(x) & USB_PORTSC1_WKDC_MASK) >> USB_PORTSC1_WKDC_SHIFT) - -/* - * WKCN (RW) - * - * WKCN - * Wake on Connect Enable (WKCNNT_E) - Read/Write. Default=0b. - * Writing this bit to a one enables the port to be sensitive to device connects as wake-up events. - * This field is zero if Port Power(PORTSC1) is zero or in device mode. - */ -#define USB_PORTSC1_WKCN_MASK (0x100000UL) -#define USB_PORTSC1_WKCN_SHIFT (20U) -#define USB_PORTSC1_WKCN_SET(x) (((uint32_t)(x) << USB_PORTSC1_WKCN_SHIFT) & USB_PORTSC1_WKCN_MASK) -#define USB_PORTSC1_WKCN_GET(x) (((uint32_t)(x) & USB_PORTSC1_WKCN_MASK) >> USB_PORTSC1_WKCN_SHIFT) - -/* - * PTC (RW) - * - * PTC - * Port Test Control - Read/Write. Default = 0000b. - * Refer to Port Test Mode for the operational model for using these test modes and the USB Specification Revision 2.0, Chapter 7 for details on each test mode. - * The FORCE_ENABLE_FS and FORCE ENABLE_LS are extensions to the test mode support specified in the EHCI specification. - * Writing the PTC field to any of the FORCE_ENABLE_{HS/FS/LS} values will force the port into the connected and enabled state at the selected speed. - * Writing the PTC field back to TEST_MODE_DISABLE will allow the port state machines to progress normally from that point. - * NOTE: Low speed operations are not supported as a peripheral device. - * Any other value than zero indicates that the port is operating in test mode. - * Value Specific Test - * 0000 - TEST_MODE_DISABLE - * 0001 - J_STATE - * 0010 - K_STATE - * 0011 - SE0 (host) / NAK (device) - * 0100 - Packet - * 0101 - FORCE_ENABLE_HS - * 0110 - FORCE_ENABLE_FS - * 0111 - FORCE_ENABLE_LS - * 1000-1111 - Reserved - */ -#define USB_PORTSC1_PTC_MASK (0xF0000UL) -#define USB_PORTSC1_PTC_SHIFT (16U) -#define USB_PORTSC1_PTC_SET(x) (((uint32_t)(x) << USB_PORTSC1_PTC_SHIFT) & USB_PORTSC1_PTC_MASK) -#define USB_PORTSC1_PTC_GET(x) (((uint32_t)(x) & USB_PORTSC1_PTC_MASK) >> USB_PORTSC1_PTC_SHIFT) - -/* - * PP (RW) - * - * PP - * Port Power (PP)-Read/Write or Read Only. - * The function of this bit depends on the value of the Port Power Switching (PPC) field in the HCSPARAMS register. The behavior is as follows: - * PPC - * PP Operation - * 0 - * 1b Read Only - Host controller does not have port power control switches. Each port is hard-wired to power. - * 1 - * 1b/0b - Read/Write. OTG controller requires port power control switches. This bit represents the current setting of the switch (0=off, 1=on). - * When power is not available on a port (that is, PP equals a 0), the port is non-functional and will not report attaches, detaches, etc. - * When an over-current condition is detected on a powered port and PPC is a one, - * the PP bit in each affected port may be transitional by the host controller driver from a one to a zero (removing power from the port). - * This feature is implemented in all controller cores (PPC = 1). - */ -#define USB_PORTSC1_PP_MASK (0x1000U) -#define USB_PORTSC1_PP_SHIFT (12U) -#define USB_PORTSC1_PP_SET(x) (((uint32_t)(x) << USB_PORTSC1_PP_SHIFT) & USB_PORTSC1_PP_MASK) -#define USB_PORTSC1_PP_GET(x) (((uint32_t)(x) & USB_PORTSC1_PP_MASK) >> USB_PORTSC1_PP_SHIFT) - -/* - * LS (RO) - * - * LS - * Line Status-Read Only. These bits reflect the current logical levels of the D+ (bit 11) and D- (bit 10) signal - * lines. - * In host mode, the use of linestate by the host controller driver is not necessary (unlike EHCI), because - * the port controller state machine and the port routing manage the connection of LS and FS. - * In device mode, the use of linestate by the device controller driver is not necessary. - * The encoding of the bits are: - * Bits [11:10] Meaning - * 00 - SE0 - * 01 - K-state - * 10 - J-state - * 11 - Undefined - */ -#define USB_PORTSC1_LS_MASK (0xC00U) -#define USB_PORTSC1_LS_SHIFT (10U) -#define USB_PORTSC1_LS_GET(x) (((uint32_t)(x) & USB_PORTSC1_LS_MASK) >> USB_PORTSC1_LS_SHIFT) - -/* - * HSP (RO) - * - * HSP - * High-Speed Port - Read Only. Default = 0b. - * When the bit is one, the host/device connected to the port is in high-speed mode and if set to zero, the - * host/device connected to the port is not in a high-speed mode. - * NOTE: HSP is redundant with PSPD(bit 27, 26) but remained for compatibility. - */ -#define USB_PORTSC1_HSP_MASK (0x200U) -#define USB_PORTSC1_HSP_SHIFT (9U) -#define USB_PORTSC1_HSP_GET(x) (((uint32_t)(x) & USB_PORTSC1_HSP_MASK) >> USB_PORTSC1_HSP_SHIFT) - -/* - * PR (RW) - * - * PR - * Port Reset - Read/Write or Read Only. Default = 0b. - * In Host Mode: Read/Write. 1=Port is in Reset. 0=Port is not in Reset. Default 0. - * When software writes a one to this bit the bus-reset sequence as defined in the USB Specification Revision 2.0 is started. - * This bit will automatically change to zero after the reset sequence is complete. - * This behavior is different from EHCI where the host controller driver is required to set this bit to a zero after the reset duration is timed in the driver. - * In Device Mode: This bit is a read only status bit. Device reset from the USB bus is also indicated in the USBSTS register. - */ -#define USB_PORTSC1_PR_MASK (0x100U) -#define USB_PORTSC1_PR_SHIFT (8U) -#define USB_PORTSC1_PR_SET(x) (((uint32_t)(x) << USB_PORTSC1_PR_SHIFT) & USB_PORTSC1_PR_MASK) -#define USB_PORTSC1_PR_GET(x) (((uint32_t)(x) & USB_PORTSC1_PR_MASK) >> USB_PORTSC1_PR_SHIFT) - -/* - * SUSP (RW) - * - * SUSP - * Suspend - Read/Write or Read Only. Default = 0b. - * 1=Port in suspend state. 0=Port not in suspend state. - * In Host Mode: Read/Write. - * Port Enabled Bit and Suspend bit of this register define the port states as follows: - * Bits [Port Enabled, Suspend] Port State - * 0x Disable - * 10 Enable - * 11 Suspend - * When in suspend state, downstream propagation of data is blocked on this port, except for port reset. - * The blocking occurs at the end of the current transaction if a transaction was in progress when this bit was written to 1. - * In the suspend state, the port is sensitive to resume detection. - * Note that the bit status does not change until the port is suspended and that there may be a delay in suspending a port if there is a transaction currently in progress on the USB. - * The host controller will unconditionally set this bit to zero when software sets the Force Port Resume bit to zero. The host controller ignores a write of zero to this bit. - * If host software sets this bit to a one when the port is not enabled (that is, Port enabled bit is a zero) the results are undefined. - * This field is zero if Port Power(PORTSC1) is zero in host mode. - * In Device Mode: Read Only. - * In device mode this bit is a read only status bit. - */ -#define USB_PORTSC1_SUSP_MASK (0x80U) -#define USB_PORTSC1_SUSP_SHIFT (7U) -#define USB_PORTSC1_SUSP_SET(x) (((uint32_t)(x) << USB_PORTSC1_SUSP_SHIFT) & USB_PORTSC1_SUSP_MASK) -#define USB_PORTSC1_SUSP_GET(x) (((uint32_t)(x) & USB_PORTSC1_SUSP_MASK) >> USB_PORTSC1_SUSP_SHIFT) - -/* - * FPR (RW) - * - * FPR - * Force Port Resume -Read/Write. 1= Resume detected/driven on port. 0=No resume (K-state) detected driven on port. Default = 0. - * In Host Mode: - * Software sets this bit to one to drive resume signaling. The Host Controller sets this bit to one if a J-to-K transition is detected while the port is in the Suspend state. - * When this bit transitions to a one because a J-to-K transition is detected, the Port Change Detect bit in the USBSTS register is also set to one. - * This bit will automatically change to zero after the resume sequence is complete. - * This behavior is different from EHCI where the host controller driver is required to set this bit to a zero after the resume duration is timed in the driver. - * Note that when the Host controller owns the port, the resume sequence follows the defined sequence documented in the USB Specification Revision 2.0. - * The resume signaling (Full-speed 'K') is driven on the port as long as this bit remains a one. This bit will remain a one until the port has switched to the high-speed idle. - * Writing a zero has no effect because the port controller will time the resume operation, clear the bit the port control state switches to HS or FS idle. - * This field is zero if Port Power(PORTSC1) is zero in host mode. - * This bit is not-EHCI compatible. - * In Device mode: - * After the device has been in Suspend State for 5ms or more, software must set this bit to one to drive resume signaling before clearing. - * The Device Controller will set this bit to one if a J-to-K transition is detected while the port is in the Suspend state. - * The bit will be cleared when the device returns to normal operation. - * Also, when this bit wil be cleared because a K-to-J transition detected, the Port Change Detect bit in the USBSTS register is also set to one. - */ -#define USB_PORTSC1_FPR_MASK (0x40U) -#define USB_PORTSC1_FPR_SHIFT (6U) -#define USB_PORTSC1_FPR_SET(x) (((uint32_t)(x) << USB_PORTSC1_FPR_SHIFT) & USB_PORTSC1_FPR_MASK) -#define USB_PORTSC1_FPR_GET(x) (((uint32_t)(x) & USB_PORTSC1_FPR_MASK) >> USB_PORTSC1_FPR_SHIFT) - -/* - * OCC (RW) - * - * OCC - * Over-current Change-R/WC. Default=0. - * This bit is set '1b' by hardware when there is a change to Over-current Active. Software can clear this bit by writing a one to this bit position. - */ -#define USB_PORTSC1_OCC_MASK (0x20U) -#define USB_PORTSC1_OCC_SHIFT (5U) -#define USB_PORTSC1_OCC_SET(x) (((uint32_t)(x) << USB_PORTSC1_OCC_SHIFT) & USB_PORTSC1_OCC_MASK) -#define USB_PORTSC1_OCC_GET(x) (((uint32_t)(x) & USB_PORTSC1_OCC_MASK) >> USB_PORTSC1_OCC_SHIFT) - -/* - * OCA (RO) - * - * OCA - * Over-current Active-Read Only. Default 0. - * This bit will automatically transition from one to zero when the over current condition is removed. - * 0 - This port does not have an over-current condition. - * 1 - This port currently has an over-current condition - */ -#define USB_PORTSC1_OCA_MASK (0x10U) -#define USB_PORTSC1_OCA_SHIFT (4U) -#define USB_PORTSC1_OCA_GET(x) (((uint32_t)(x) & USB_PORTSC1_OCA_MASK) >> USB_PORTSC1_OCA_SHIFT) - -/* - * PEC (RWC) - * - * PEC - * Port Enable/Disable Change-R/WC. 1=Port enabled/disabled status has changed. 0=No change. Default = 0. - * In Host Mode: - * For the root hub, this bit is set to a one only when a port is disabled due to disconnect on the port or - * due to the appropriate conditions existing at the EOF2 point (See Chapter 11 of the USB Specification). - * Software clears this by writing a one to it. - * This field is zero if Port Power(PORTSC1) is zero. - * In Device mode: - * The device port is always enabled, so this bit is always '0b'. - */ -#define USB_PORTSC1_PEC_MASK (0x8U) -#define USB_PORTSC1_PEC_SHIFT (3U) -#define USB_PORTSC1_PEC_SET(x) (((uint32_t)(x) << USB_PORTSC1_PEC_SHIFT) & USB_PORTSC1_PEC_MASK) -#define USB_PORTSC1_PEC_GET(x) (((uint32_t)(x) & USB_PORTSC1_PEC_MASK) >> USB_PORTSC1_PEC_SHIFT) - -/* - * PE (RWC) - * - * PE - * Port Enabled/Disabled-Read/Write. 1=Enable. 0=Disable. Default 0. - * In Host Mode: - * Ports can only be enabled by the host controller as a part of the reset and enable. Software cannot enable a port by writing a one to this field. - * Ports can be disabled by either a fault condition (disconnect event or other fault condition) or by the host software. - * Note that the bit status does not change until the port state actually changes. There may be a delay in disabling or enabling a port due to other host controller and bus events. - * When the port is disabled, (0b) downstream propagation of data is blocked except for reset. - * This field is zero if Port Power(PORTSC1) is zero in host mode. - * In Device Mode: - * The device port is always enabled, so this bit is always '1b'. - */ -#define USB_PORTSC1_PE_MASK (0x4U) -#define USB_PORTSC1_PE_SHIFT (2U) -#define USB_PORTSC1_PE_SET(x) (((uint32_t)(x) << USB_PORTSC1_PE_SHIFT) & USB_PORTSC1_PE_MASK) -#define USB_PORTSC1_PE_GET(x) (((uint32_t)(x) & USB_PORTSC1_PE_MASK) >> USB_PORTSC1_PE_SHIFT) - -/* - * CSC (RWC) - * - * CSC - * Connect Status Change-R/WC. 1 =Change in Current Connect Status. 0=No change. Default 0. - * In Host Mode: - * Indicates a change has occurred in the port's Current Connect Status. - * The host/device controller sets this bit for all changes to the port device connect status, even if system software has not cleared an existing connect status change. - * For example, the insertion status changes twice before system software has cleared the changed condition, - * hub hardware will be 'setting' an already-set bit (that is, the bit will remain set). Software clears this bit by writing a one to it. - * This field is zero if Port Power(PORTSC1) is zero in host mode. - * In Device Mode: - * This bit is undefined in device controller mode. - */ -#define USB_PORTSC1_CSC_MASK (0x2U) -#define USB_PORTSC1_CSC_SHIFT (1U) -#define USB_PORTSC1_CSC_SET(x) (((uint32_t)(x) << USB_PORTSC1_CSC_SHIFT) & USB_PORTSC1_CSC_MASK) -#define USB_PORTSC1_CSC_GET(x) (((uint32_t)(x) & USB_PORTSC1_CSC_MASK) >> USB_PORTSC1_CSC_SHIFT) - -/* - * CCS (RWC) - * - * CCS - * Current Connect Status-Read Only. - * In Host Mode: - * 1=Device is present on port. 0=No device is present. Default = 0. - * This value reflects the current state of the port, and may not correspond directly to the event that caused the Connect Status Change bit (Bit 1) to be set. - * This field is zero if Port Power(PORTSC1) is zero in host mode. - * In Device Mode: - * 1=Attached. 0=Not Attached. Default=0. - * A one indicates that the device successfully attached and is operating in either high speed or full speed as indicated by the High Speed Port bit in this register. - * A zero indicates that the device did not attach successfully or was forcibly disconnected by the software writing a zero to the Run bit in the USBCMD register. - * It does not state the device being disconnected or Suspended. - */ -#define USB_PORTSC1_CCS_MASK (0x1U) -#define USB_PORTSC1_CCS_SHIFT (0U) -#define USB_PORTSC1_CCS_SET(x) (((uint32_t)(x) << USB_PORTSC1_CCS_SHIFT) & USB_PORTSC1_CCS_MASK) -#define USB_PORTSC1_CCS_GET(x) (((uint32_t)(x) & USB_PORTSC1_CCS_MASK) >> USB_PORTSC1_CCS_SHIFT) - -/* Bitfield definition for register: OTGSC */ -/* - * ASVIE (RW) - * - * ASVIE - * A Session Valid Interrupt Enable - Read/Write. - */ -#define USB_OTGSC_ASVIE_MASK (0x4000000UL) -#define USB_OTGSC_ASVIE_SHIFT (26U) -#define USB_OTGSC_ASVIE_SET(x) (((uint32_t)(x) << USB_OTGSC_ASVIE_SHIFT) & USB_OTGSC_ASVIE_MASK) -#define USB_OTGSC_ASVIE_GET(x) (((uint32_t)(x) & USB_OTGSC_ASVIE_MASK) >> USB_OTGSC_ASVIE_SHIFT) - -/* - * AVVIE (RW) - * - * AVVIE - * A VBus Valid Interrupt Enable - Read/Write. - * Setting this bit enables the A VBus valid interrupt. - */ -#define USB_OTGSC_AVVIE_MASK (0x2000000UL) -#define USB_OTGSC_AVVIE_SHIFT (25U) -#define USB_OTGSC_AVVIE_SET(x) (((uint32_t)(x) << USB_OTGSC_AVVIE_SHIFT) & USB_OTGSC_AVVIE_MASK) -#define USB_OTGSC_AVVIE_GET(x) (((uint32_t)(x) & USB_OTGSC_AVVIE_MASK) >> USB_OTGSC_AVVIE_SHIFT) - -/* - * IDIE (RW) - * - * IDIE - * USB ID Interrupt Enable - Read/Write. - * Setting this bit enables the USB ID interrupt. - */ -#define USB_OTGSC_IDIE_MASK (0x1000000UL) -#define USB_OTGSC_IDIE_SHIFT (24U) -#define USB_OTGSC_IDIE_SET(x) (((uint32_t)(x) << USB_OTGSC_IDIE_SHIFT) & USB_OTGSC_IDIE_MASK) -#define USB_OTGSC_IDIE_GET(x) (((uint32_t)(x) & USB_OTGSC_IDIE_MASK) >> USB_OTGSC_IDIE_SHIFT) - -/* - * ASVIS (RWC) - * - * ASVIS - * A Session Valid Interrupt Status - Read/Write to Clear. - * This bit is set when VBus has either risen above or fallen below the A session valid threshold. - * Software must write a one to clear this bit. - */ -#define USB_OTGSC_ASVIS_MASK (0x40000UL) -#define USB_OTGSC_ASVIS_SHIFT (18U) -#define USB_OTGSC_ASVIS_SET(x) (((uint32_t)(x) << USB_OTGSC_ASVIS_SHIFT) & USB_OTGSC_ASVIS_MASK) -#define USB_OTGSC_ASVIS_GET(x) (((uint32_t)(x) & USB_OTGSC_ASVIS_MASK) >> USB_OTGSC_ASVIS_SHIFT) - -/* - * AVVIS (RWC) - * - * AVVIS - * A VBus Valid Interrupt Status - Read/Write to Clear. - * This bit is set when VBus has either risen above or fallen below the VBus valid threshold on an A device. - * Software must write a one to clear this bit. - */ -#define USB_OTGSC_AVVIS_MASK (0x20000UL) -#define USB_OTGSC_AVVIS_SHIFT (17U) -#define USB_OTGSC_AVVIS_SET(x) (((uint32_t)(x) << USB_OTGSC_AVVIS_SHIFT) & USB_OTGSC_AVVIS_MASK) -#define USB_OTGSC_AVVIS_GET(x) (((uint32_t)(x) & USB_OTGSC_AVVIS_MASK) >> USB_OTGSC_AVVIS_SHIFT) - -/* - * IDIS (RWC) - * - * IDIS - * USB ID Interrupt Status - Read/Write. - * This bit is set when a change on the ID input has been detected. - * Software must write a one to clear this bit. - */ -#define USB_OTGSC_IDIS_MASK (0x10000UL) -#define USB_OTGSC_IDIS_SHIFT (16U) -#define USB_OTGSC_IDIS_SET(x) (((uint32_t)(x) << USB_OTGSC_IDIS_SHIFT) & USB_OTGSC_IDIS_MASK) -#define USB_OTGSC_IDIS_GET(x) (((uint32_t)(x) & USB_OTGSC_IDIS_MASK) >> USB_OTGSC_IDIS_SHIFT) - -/* - * ASV (RO) - * - * ASV - * A Session Valid - Read Only. - * Indicates VBus is above the A session valid threshold. - */ -#define USB_OTGSC_ASV_MASK (0x400U) -#define USB_OTGSC_ASV_SHIFT (10U) -#define USB_OTGSC_ASV_GET(x) (((uint32_t)(x) & USB_OTGSC_ASV_MASK) >> USB_OTGSC_ASV_SHIFT) - -/* - * AVV (RO) - * - * AVV - * A VBus Valid - Read Only. - * Indicates VBus is above the A VBus valid threshold. - */ -#define USB_OTGSC_AVV_MASK (0x200U) -#define USB_OTGSC_AVV_SHIFT (9U) -#define USB_OTGSC_AVV_GET(x) (((uint32_t)(x) & USB_OTGSC_AVV_MASK) >> USB_OTGSC_AVV_SHIFT) - -/* - * ID (RO) - * - * ID - * USB ID - Read Only. - * 0 = A device, 1 = B device - */ -#define USB_OTGSC_ID_MASK (0x100U) -#define USB_OTGSC_ID_SHIFT (8U) -#define USB_OTGSC_ID_GET(x) (((uint32_t)(x) & USB_OTGSC_ID_MASK) >> USB_OTGSC_ID_SHIFT) - -/* - * IDPU (RW) - * - * IDPU - * ID Pullup - Read/Write - * This bit provide control over the ID pull-up resistor; 0 = off, 1 = on [default]. When this bit is 0, the ID input - * will not be sampled. - */ -#define USB_OTGSC_IDPU_MASK (0x20U) -#define USB_OTGSC_IDPU_SHIFT (5U) -#define USB_OTGSC_IDPU_SET(x) (((uint32_t)(x) << USB_OTGSC_IDPU_SHIFT) & USB_OTGSC_IDPU_MASK) -#define USB_OTGSC_IDPU_GET(x) (((uint32_t)(x) & USB_OTGSC_IDPU_MASK) >> USB_OTGSC_IDPU_SHIFT) - -/* - * VC (RW) - * - * VC - * VBUS Charge - Read/Write. - * Setting this bit causes the VBus line to be charged. This is used for VBus pulsing during SRP. - */ -#define USB_OTGSC_VC_MASK (0x2U) -#define USB_OTGSC_VC_SHIFT (1U) -#define USB_OTGSC_VC_SET(x) (((uint32_t)(x) << USB_OTGSC_VC_SHIFT) & USB_OTGSC_VC_MASK) -#define USB_OTGSC_VC_GET(x) (((uint32_t)(x) & USB_OTGSC_VC_MASK) >> USB_OTGSC_VC_SHIFT) - -/* - * VD (RW) - * - * VD - * VBUS_Discharge - Read/Write. - * Setting this bit causes VBus to discharge through a resistor. - */ -#define USB_OTGSC_VD_MASK (0x1U) -#define USB_OTGSC_VD_SHIFT (0U) -#define USB_OTGSC_VD_SET(x) (((uint32_t)(x) << USB_OTGSC_VD_SHIFT) & USB_OTGSC_VD_MASK) -#define USB_OTGSC_VD_GET(x) (((uint32_t)(x) & USB_OTGSC_VD_MASK) >> USB_OTGSC_VD_SHIFT) - -/* Bitfield definition for register: USBMODE */ -/* - * SDIS (RW) - * - * SDIS - * Stream Disable Mode. (0 - Inactive [default]; 1 - Active) - * Device Mode: Setting to a '1' disables double priming on both RX and TX for low bandwidth systems. - * This mode ensures that when the RX and TX buffers are sufficient to contain an entire packet that the standard double buffering scheme is disabled to prevent overruns/underruns in bandwidth limited systems. - * Note: In High Speed Mode, all packets received are responded to with a NYET handshake when stream disable is active. - * Host Mode: Setting to a '1' ensures that overruns/underruns of the latency FIFO are eliminated for low bandwidth systems - * where the RX and TX buffers are sufficient to contain the entire packet. Enabling stream disable also has the effect of ensuring the TX latency is filled to capacity before the packet is launched onto the USB. - * NOTE: Time duration to pre-fill the FIFO becomes significant when stream disable is active. See TXFILLTUNING and TXTTFILLTUNING [MPH Only] to characterize the adjustments needed for - * the scheduler when using this feature. - * NOTE: The use of this feature substantially limits of the overall USB performance that can be achieved. - */ -#define USB_USBMODE_SDIS_MASK (0x10U) -#define USB_USBMODE_SDIS_SHIFT (4U) -#define USB_USBMODE_SDIS_SET(x) (((uint32_t)(x) << USB_USBMODE_SDIS_SHIFT) & USB_USBMODE_SDIS_MASK) -#define USB_USBMODE_SDIS_GET(x) (((uint32_t)(x) & USB_USBMODE_SDIS_MASK) >> USB_USBMODE_SDIS_SHIFT) - -/* - * SLOM (RW) - * - * SLOM - * Setup Lockout Mode. In device mode, this bit controls behavior of the setup lock mechanism. See Control Endpoint Operation Model . - * 0 - Setup Lockouts On (default); - * 1 - Setup Lockouts Off. DCD requires use of Setup Data Buffer Tripwire in USBCMD. - */ -#define USB_USBMODE_SLOM_MASK (0x8U) -#define USB_USBMODE_SLOM_SHIFT (3U) -#define USB_USBMODE_SLOM_SET(x) (((uint32_t)(x) << USB_USBMODE_SLOM_SHIFT) & USB_USBMODE_SLOM_MASK) -#define USB_USBMODE_SLOM_GET(x) (((uint32_t)(x) & USB_USBMODE_SLOM_MASK) >> USB_USBMODE_SLOM_SHIFT) - -/* - * ES (RW) - * - * ES - * Endian Select - Read/Write. This bit can change the byte alignment of the transfer buffers to match the - * host microprocessor. The bit fields in the microprocessor interface and the data structures are unaffected - * by the value of this bit because they are based upon the 32-bit word. - * Bit Meaning - * 0 - Little Endian [Default] - * 1 - Big Endian - */ -#define USB_USBMODE_ES_MASK (0x4U) -#define USB_USBMODE_ES_SHIFT (2U) -#define USB_USBMODE_ES_SET(x) (((uint32_t)(x) << USB_USBMODE_ES_SHIFT) & USB_USBMODE_ES_MASK) -#define USB_USBMODE_ES_GET(x) (((uint32_t)(x) & USB_USBMODE_ES_MASK) >> USB_USBMODE_ES_SHIFT) - -/* - * CM (RW) - * - * CM - * Controller Mode - R/WO. Controller mode is defaulted to the proper mode for host only and device only - * implementations. For those designs that contain both host & device capability, the controller defaults to - * an idle state and needs to be initialized to the desired operating mode after reset. For combination host/ - * device controllers, this register can only be written once after reset. If it is necessary to switch modes, - * software must reset the controller by writing to the RESET bit in the USBCMD register before - * reprogramming this register. - * For OTG controller core, reset value is '00b'. - * 00 - Idle [Default for combination host/device] - * 01 - Reserved - * 10 - Device Controller [Default for device only controller] - * 11 - Host Controller [Default for host only controller] - */ -#define USB_USBMODE_CM_MASK (0x3U) -#define USB_USBMODE_CM_SHIFT (0U) -#define USB_USBMODE_CM_SET(x) (((uint32_t)(x) << USB_USBMODE_CM_SHIFT) & USB_USBMODE_CM_MASK) -#define USB_USBMODE_CM_GET(x) (((uint32_t)(x) & USB_USBMODE_CM_MASK) >> USB_USBMODE_CM_SHIFT) - -/* Bitfield definition for register: ENDPTSETUPSTAT */ -/* - * ENDPTSETUPSTAT (RWC) - * - * ENDPTSETUPSTAT - * Setup Endpoint Status. For every setup transaction that is received, a corresponding bit in this register is set to one. - * Software must clear or acknowledge the setup transfer by writing a one to a respective bit after it has read the setup data from Queue head. - * The response to a setup packet as in the order of operations and total response time is crucial to limit bus time outs while the setup lock out mechanism is engaged. - * This register is only used in device mode. - */ -#define USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_MASK (0xFFFFU) -#define USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_SHIFT (0U) -#define USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_SET(x) (((uint32_t)(x) << USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_SHIFT) & USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_MASK) -#define USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_GET(x) (((uint32_t)(x) & USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_MASK) >> USB_ENDPTSETUPSTAT_ENDPTSETUPSTAT_SHIFT) - -/* Bitfield definition for register: ENDPTPRIME */ -/* - * PETB (RWS) - * - * PETB - * Prime Endpoint Transmit Buffer - R/WS. For each endpoint a corresponding bit is used to request that a - * buffer is prepared for a transmit operation in order to respond to a USB IN/INTERRUPT transaction. - * Software should write a one to the corresponding bit when posting a new transfer descriptor to an - * endpoint queue head. Hardware automatically uses this bit to begin parsing for a new transfer descriptor - * from the queue head and prepare a transmit buffer. Hardware clears this bit when the associated - * endpoint(s) is (are) successfully primed. - * NOTE: These bits are momentarily set by hardware during hardware re-priming operations when a dTD - * is retired, and the dQH is updated. - * PETB[N] - Endpoint #N, N is in 0..7 - */ -#define USB_ENDPTPRIME_PETB_MASK (0xFFFF0000UL) -#define USB_ENDPTPRIME_PETB_SHIFT (16U) -#define USB_ENDPTPRIME_PETB_SET(x) (((uint32_t)(x) << USB_ENDPTPRIME_PETB_SHIFT) & USB_ENDPTPRIME_PETB_MASK) -#define USB_ENDPTPRIME_PETB_GET(x) (((uint32_t)(x) & USB_ENDPTPRIME_PETB_MASK) >> USB_ENDPTPRIME_PETB_SHIFT) - -/* - * PERB (RWS) - * - * PERB - * Prime Endpoint Receive Buffer - R/WS. For each endpoint, a corresponding bit is used to request a buffer prepare for a receive operation for when a USB host initiates a USB OUT transaction. - * Software should write a one to the corresponding bit whenever posting a new transfer descriptor to an endpoint queue head. - * Hardware automatically uses this bit to begin parsing for a new transfer descriptor from the queue head and prepare a receive buffer. - * Hardware clears this bit when the associated endpoint(s) is (are) successfully primed. - * NOTE: These bits are momentarily set by hardware during hardware re-priming operations when a dTD - * is retired, and the dQH is updated. - * PERB[N] - Endpoint #N, N is in 0..7 - */ -#define USB_ENDPTPRIME_PERB_MASK (0xFFFFU) -#define USB_ENDPTPRIME_PERB_SHIFT (0U) -#define USB_ENDPTPRIME_PERB_SET(x) (((uint32_t)(x) << USB_ENDPTPRIME_PERB_SHIFT) & USB_ENDPTPRIME_PERB_MASK) -#define USB_ENDPTPRIME_PERB_GET(x) (((uint32_t)(x) & USB_ENDPTPRIME_PERB_MASK) >> USB_ENDPTPRIME_PERB_SHIFT) - -/* Bitfield definition for register: ENDPTFLUSH */ -/* - * FETB (RWS) - * - * FETB - * Flush Endpoint Transmit Buffer - R/WS. Writing one to a bit(s) in this register causes the associated endpoint(s) to clear any primed buffers. - * If a packet is in progress for one of the associated endpoints, then that transfer continues until completion. - * Hardware clears this register after the endpoint flush operation is successful. - * FETB[N] - Endpoint #N, N is in 0..7 - */ -#define USB_ENDPTFLUSH_FETB_MASK (0xFFFF0000UL) -#define USB_ENDPTFLUSH_FETB_SHIFT (16U) -#define USB_ENDPTFLUSH_FETB_SET(x) (((uint32_t)(x) << USB_ENDPTFLUSH_FETB_SHIFT) & USB_ENDPTFLUSH_FETB_MASK) -#define USB_ENDPTFLUSH_FETB_GET(x) (((uint32_t)(x) & USB_ENDPTFLUSH_FETB_MASK) >> USB_ENDPTFLUSH_FETB_SHIFT) - -/* - * FERB (RWS) - * - * FERB - * Flush Endpoint Receive Buffer - R/WS. Writing one to a bit(s) causes the associated endpoint(s) to clear any primed buffers. - * If a packet is in progress for one of the associated endpoints, then that transfer continues until completion. - * Hardware clears this register after the endpoint flush operation is successful. - * FERB[N] - Endpoint #N, N is in 0..7 - */ -#define USB_ENDPTFLUSH_FERB_MASK (0xFFFFU) -#define USB_ENDPTFLUSH_FERB_SHIFT (0U) -#define USB_ENDPTFLUSH_FERB_SET(x) (((uint32_t)(x) << USB_ENDPTFLUSH_FERB_SHIFT) & USB_ENDPTFLUSH_FERB_MASK) -#define USB_ENDPTFLUSH_FERB_GET(x) (((uint32_t)(x) & USB_ENDPTFLUSH_FERB_MASK) >> USB_ENDPTFLUSH_FERB_SHIFT) - -/* Bitfield definition for register: ENDPTSTAT */ -/* - * ETBR (RO) - * - * ETBR - * Endpoint Transmit Buffer Ready -- Read Only. One bit for each endpoint indicates status of the respective endpoint buffer. - * This bit is set to one by the hardware as a response to receiving a command from a corresponding bit in the ENDPTPRIME register. - * There is always a delay between setting a bit in the ENDPTPRIME register and endpoint indicating ready. - * This delay time varies based upon the current USB traffic and the number of bits set in the ENDPRIME register. - * Buffer ready is cleared by USB reset, by the USB DMA system, or through the ENDPTFLUSH register. - * NOTE: These bits are momentarily cleared by hardware during hardware endpoint re-priming operations when a dTD is retired, and the dQH is updated. - * ETBR[N] - Endpoint #N, N is in 0..7 - */ -#define USB_ENDPTSTAT_ETBR_MASK (0xFFFF0000UL) -#define USB_ENDPTSTAT_ETBR_SHIFT (16U) -#define USB_ENDPTSTAT_ETBR_GET(x) (((uint32_t)(x) & USB_ENDPTSTAT_ETBR_MASK) >> USB_ENDPTSTAT_ETBR_SHIFT) - -/* - * ERBR (RO) - * - * ERBR - * Endpoint Receive Buffer Ready -- Read Only. One bit for each endpoint indicates status of the respective - * endpoint buffer. This bit is set to a one by the hardware as a response to receiving a command from a - * corresponding bit in the ENDPRIME register. There is always a delay between setting a bit in the - * ENDPRIME register and endpoint indicating ready. This delay time varies based upon the current USB - * traffic and the number of bits set in the ENDPRIME register. Buffer ready is cleared by USB reset, by the - * USB DMA system, or through the ENDPTFLUSH register. - * NOTE: These bits are momentarily cleared by hardware during hardware endpoint re-priming operations - * when a dTD is retired, and the dQH is updated. - * ERBR[N] - Endpoint #N, N is in 0..7 - */ -#define USB_ENDPTSTAT_ERBR_MASK (0xFFFFU) -#define USB_ENDPTSTAT_ERBR_SHIFT (0U) -#define USB_ENDPTSTAT_ERBR_GET(x) (((uint32_t)(x) & USB_ENDPTSTAT_ERBR_MASK) >> USB_ENDPTSTAT_ERBR_SHIFT) - -/* Bitfield definition for register: ENDPTCOMPLETE */ -/* - * ETCE (RWC) - * - * ETCE - * Endpoint Transmit Complete Event - R/WC. Each bit indicates a transmit event (IN/INTERRUPT) occurred and software should read the corresponding endpoint queue to determine the endpoint status. - * If the corresponding IOC bit is set in the Transfer Descriptor, then this bit is set simultaneously with the USBINT . Writing one clears the corresponding bit in this register. - * ETCE[N] - Endpoint #N, N is in 0..7 - */ -#define USB_ENDPTCOMPLETE_ETCE_MASK (0xFFFF0000UL) -#define USB_ENDPTCOMPLETE_ETCE_SHIFT (16U) -#define USB_ENDPTCOMPLETE_ETCE_SET(x) (((uint32_t)(x) << USB_ENDPTCOMPLETE_ETCE_SHIFT) & USB_ENDPTCOMPLETE_ETCE_MASK) -#define USB_ENDPTCOMPLETE_ETCE_GET(x) (((uint32_t)(x) & USB_ENDPTCOMPLETE_ETCE_MASK) >> USB_ENDPTCOMPLETE_ETCE_SHIFT) - -/* - * ERCE (RWC) - * - * ERCE - * Endpoint Receive Complete Event - RW/C. Each bit indicates a received event (OUT/SETUP) occurred - * and software should read the corresponding endpoint queue to determine the transfer status. If the - * corresponding IOC bit is set in the Transfer Descriptor, then this bit is set simultaneously with the - * USBINT . Writing one clears the corresponding bit in this register. - * ERCE[N] - Endpoint #N, N is in 0..7 - */ -#define USB_ENDPTCOMPLETE_ERCE_MASK (0xFFFFU) -#define USB_ENDPTCOMPLETE_ERCE_SHIFT (0U) -#define USB_ENDPTCOMPLETE_ERCE_SET(x) (((uint32_t)(x) << USB_ENDPTCOMPLETE_ERCE_SHIFT) & USB_ENDPTCOMPLETE_ERCE_MASK) -#define USB_ENDPTCOMPLETE_ERCE_GET(x) (((uint32_t)(x) & USB_ENDPTCOMPLETE_ERCE_MASK) >> USB_ENDPTCOMPLETE_ERCE_SHIFT) - -/* Bitfield definition for register array: ENDPTCTRL */ -/* - * TXE (RW) - * - * TXE - * TX Endpoint Enable - * 0 Disabled [Default] - * 1 Enabled - * An Endpoint should be enabled only after it has been configured. - */ -#define USB_ENDPTCTRL_TXE_MASK (0x800000UL) -#define USB_ENDPTCTRL_TXE_SHIFT (23U) -#define USB_ENDPTCTRL_TXE_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_TXE_SHIFT) & USB_ENDPTCTRL_TXE_MASK) -#define USB_ENDPTCTRL_TXE_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_TXE_MASK) >> USB_ENDPTCTRL_TXE_SHIFT) - -/* - * TXR (WS) - * - * TXR - * TX Data Toggle Reset (WS) - * Write 1 - Reset PID Sequence - * Whenever a configuration event is received for this Endpoint, software must write a one to this bit in order - * to synchronize the data PID's between the Host and device. - */ -#define USB_ENDPTCTRL_TXR_MASK (0x400000UL) -#define USB_ENDPTCTRL_TXR_SHIFT (22U) -#define USB_ENDPTCTRL_TXR_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_TXR_SHIFT) & USB_ENDPTCTRL_TXR_MASK) -#define USB_ENDPTCTRL_TXR_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_TXR_MASK) >> USB_ENDPTCTRL_TXR_SHIFT) - -/* - * TXT (RW) - * - * TXT - * TX Endpoint Type - Read/Write - * 00 Control - * 01 Isochronous - * 10 Bulk - * 11 Interrupt - */ -#define USB_ENDPTCTRL_TXT_MASK (0xC0000UL) -#define USB_ENDPTCTRL_TXT_SHIFT (18U) -#define USB_ENDPTCTRL_TXT_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_TXT_SHIFT) & USB_ENDPTCTRL_TXT_MASK) -#define USB_ENDPTCTRL_TXT_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_TXT_MASK) >> USB_ENDPTCTRL_TXT_SHIFT) - -/* - * TXS (RW) - * - * TXS - * TX Endpoint Stall - Read/Write - * 0 End Point OK - * 1 End Point Stalled - * This bit will be cleared automatically upon receipt of a SETUP request if this Endpoint is configured - * as a Control Endpoint and this bit will continue to be cleared by hardware until the associated ENDPTSETUPSTAT bit is cleared. - * Software can write a one to this bit to force the endpoint to return a STALL handshake to the Host. - * This control will continue to STALL until this bit is either cleared by software or automatically cleared as above for control endpoints. - * NOTE: [CONTROL ENDPOINT TYPES ONLY]: there is a slight delay (50 clocks max) between the ENDPTSETUPSTAT begin cleared and hardware continuing to clear this bit. - * In most systems, it is unlikely the DCD software will observe this delay. However, should the DCD observe that the stall bit is not set after writing a one to it then follow this procedure: - * continually write this stall bit until it is set or until a new setup has been received by checking the associated endptsetupstat Bit. - */ -#define USB_ENDPTCTRL_TXS_MASK (0x10000UL) -#define USB_ENDPTCTRL_TXS_SHIFT (16U) -#define USB_ENDPTCTRL_TXS_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_TXS_SHIFT) & USB_ENDPTCTRL_TXS_MASK) -#define USB_ENDPTCTRL_TXS_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_TXS_MASK) >> USB_ENDPTCTRL_TXS_SHIFT) - -/* - * RXE (RW) - * - * RXE - * RX Endpoint Enable - * 0 Disabled [Default] - * 1 Enabled - * An Endpoint should be enabled only after it has been configured. - */ -#define USB_ENDPTCTRL_RXE_MASK (0x80U) -#define USB_ENDPTCTRL_RXE_SHIFT (7U) -#define USB_ENDPTCTRL_RXE_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_RXE_SHIFT) & USB_ENDPTCTRL_RXE_MASK) -#define USB_ENDPTCTRL_RXE_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_RXE_MASK) >> USB_ENDPTCTRL_RXE_SHIFT) - -/* - * RXR (WS) - * - * RXR - * RX Data Toggle Reset (WS) - * Write 1 - Reset PID Sequence - * Whenever a configuration event is received for this Endpoint, software must write a one to this bit in order - * to synchronize the data PID's between the host and device. - */ -#define USB_ENDPTCTRL_RXR_MASK (0x40U) -#define USB_ENDPTCTRL_RXR_SHIFT (6U) -#define USB_ENDPTCTRL_RXR_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_RXR_SHIFT) & USB_ENDPTCTRL_RXR_MASK) -#define USB_ENDPTCTRL_RXR_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_RXR_MASK) >> USB_ENDPTCTRL_RXR_SHIFT) - -/* - * RXT (RW) - * - * RXT - * RX Endpoint Type - Read/Write - * 00 Control - * 01 Isochronous - * 10 Bulk - * 11 Interrupt - */ -#define USB_ENDPTCTRL_RXT_MASK (0xCU) -#define USB_ENDPTCTRL_RXT_SHIFT (2U) -#define USB_ENDPTCTRL_RXT_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_RXT_SHIFT) & USB_ENDPTCTRL_RXT_MASK) -#define USB_ENDPTCTRL_RXT_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_RXT_MASK) >> USB_ENDPTCTRL_RXT_SHIFT) - -/* - * RXS (RW) - * - * RXS - * RX Endpoint Stall - Read/Write - * 0 End Point OK. [Default] - * 1 End Point Stalled - * This bit is set automatically upon receipt of a SETUP request if this Endpoint is configured as a Control - * Endpointand this bit will continue to be cleared by hardware until the associated ENDPTSETUPSTAT bit - * is cleared. - * Software can write a one to this bit to force the endpoint to return a STALL handshake to the Host. This - * control will continue to STALL until this bit is either cleared by software or automatically cleared as above - * for control endpoints. - * NOTE: [CONTROL ENDPOINT TYPES ONLY]: there is a slight delay (50 clocks max) between the - * ENDPTSETUPSTAT begin cleared and hardware continuing to clear this bit. In most systems, it - * is unlikely the DCD software will observe this delay. However, should the DCD observe that the - * stall bit is not set after writing a one to it then follow this procedure: continually write this stall bit - * until it is set or until a new setup has been received by checking the associated endptsetupstat - * Bit. - */ -#define USB_ENDPTCTRL_RXS_MASK (0x1U) -#define USB_ENDPTCTRL_RXS_SHIFT (0U) -#define USB_ENDPTCTRL_RXS_SET(x) (((uint32_t)(x) << USB_ENDPTCTRL_RXS_SHIFT) & USB_ENDPTCTRL_RXS_MASK) -#define USB_ENDPTCTRL_RXS_GET(x) (((uint32_t)(x) & USB_ENDPTCTRL_RXS_MASK) >> USB_ENDPTCTRL_RXS_SHIFT) - -/* Bitfield definition for register: OTG_CTRL0 */ -/* - * OTG_WKDPDMCHG_EN (RW) - * - */ -#define USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_MASK (0x2000000UL) -#define USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_SHIFT (25U) -#define USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_SHIFT) & USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_MASK) -#define USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_MASK) >> USB_OTG_CTRL0_OTG_WKDPDMCHG_EN_SHIFT) - -/* - * AUTORESUME_EN (RW) - * - */ -#define USB_OTG_CTRL0_AUTORESUME_EN_MASK (0x80000UL) -#define USB_OTG_CTRL0_AUTORESUME_EN_SHIFT (19U) -#define USB_OTG_CTRL0_AUTORESUME_EN_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_AUTORESUME_EN_SHIFT) & USB_OTG_CTRL0_AUTORESUME_EN_MASK) -#define USB_OTG_CTRL0_AUTORESUME_EN_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_AUTORESUME_EN_MASK) >> USB_OTG_CTRL0_AUTORESUME_EN_SHIFT) - -/* - * OTG_VBUS_WAKEUP_EN (RW) - * - */ -#define USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_MASK (0x20000UL) -#define USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_SHIFT (17U) -#define USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_SHIFT) & USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_MASK) -#define USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_MASK) >> USB_OTG_CTRL0_OTG_VBUS_WAKEUP_EN_SHIFT) - -/* - * OTG_ID_WAKEUP_EN (RW) - * - */ -#define USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_MASK (0x10000UL) -#define USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_SHIFT (16U) -#define USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_SHIFT) & USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_MASK) -#define USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_MASK) >> USB_OTG_CTRL0_OTG_ID_WAKEUP_EN_SHIFT) - -/* - * OTG_VBUS_SOURCE_SEL (RW) - * - */ -#define USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_MASK (0x2000U) -#define USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_SHIFT (13U) -#define USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_SHIFT) & USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_MASK) -#define USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_MASK) >> USB_OTG_CTRL0_OTG_VBUS_SOURCE_SEL_SHIFT) - -/* - * OTG_UTMI_SUSPENDM_SW (RW) - * - * default 0 for naneng usbphy - */ -#define USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_MASK (0x1000U) -#define USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_SHIFT (12U) -#define USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_SHIFT) & USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_MASK) -#define USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_MASK) >> USB_OTG_CTRL0_OTG_UTMI_SUSPENDM_SW_SHIFT) - -/* - * OTG_UTMI_RESET_SW (RW) - * - * default 1 for naneng usbphy - */ -#define USB_OTG_CTRL0_OTG_UTMI_RESET_SW_MASK (0x800U) -#define USB_OTG_CTRL0_OTG_UTMI_RESET_SW_SHIFT (11U) -#define USB_OTG_CTRL0_OTG_UTMI_RESET_SW_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_UTMI_RESET_SW_SHIFT) & USB_OTG_CTRL0_OTG_UTMI_RESET_SW_MASK) -#define USB_OTG_CTRL0_OTG_UTMI_RESET_SW_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_UTMI_RESET_SW_MASK) >> USB_OTG_CTRL0_OTG_UTMI_RESET_SW_SHIFT) - -/* - * OTG_WAKEUP_INT_ENABLE (RW) - * - */ -#define USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_MASK (0x400U) -#define USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_SHIFT (10U) -#define USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_SHIFT) & USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_MASK) -#define USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_MASK) >> USB_OTG_CTRL0_OTG_WAKEUP_INT_ENABLE_SHIFT) - -/* - * OTG_POWER_MASK (RW) - * - */ -#define USB_OTG_CTRL0_OTG_POWER_MASK_MASK (0x200U) -#define USB_OTG_CTRL0_OTG_POWER_MASK_SHIFT (9U) -#define USB_OTG_CTRL0_OTG_POWER_MASK_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_POWER_MASK_SHIFT) & USB_OTG_CTRL0_OTG_POWER_MASK_MASK) -#define USB_OTG_CTRL0_OTG_POWER_MASK_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_POWER_MASK_MASK) >> USB_OTG_CTRL0_OTG_POWER_MASK_SHIFT) - -/* - * OTG_OVER_CUR_POL (RW) - * - */ -#define USB_OTG_CTRL0_OTG_OVER_CUR_POL_MASK (0x100U) -#define USB_OTG_CTRL0_OTG_OVER_CUR_POL_SHIFT (8U) -#define USB_OTG_CTRL0_OTG_OVER_CUR_POL_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_OVER_CUR_POL_SHIFT) & USB_OTG_CTRL0_OTG_OVER_CUR_POL_MASK) -#define USB_OTG_CTRL0_OTG_OVER_CUR_POL_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_OVER_CUR_POL_MASK) >> USB_OTG_CTRL0_OTG_OVER_CUR_POL_SHIFT) - -/* - * OTG_OVER_CUR_DIS (RW) - * - */ -#define USB_OTG_CTRL0_OTG_OVER_CUR_DIS_MASK (0x80U) -#define USB_OTG_CTRL0_OTG_OVER_CUR_DIS_SHIFT (7U) -#define USB_OTG_CTRL0_OTG_OVER_CUR_DIS_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_OTG_OVER_CUR_DIS_SHIFT) & USB_OTG_CTRL0_OTG_OVER_CUR_DIS_MASK) -#define USB_OTG_CTRL0_OTG_OVER_CUR_DIS_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_OTG_OVER_CUR_DIS_MASK) >> USB_OTG_CTRL0_OTG_OVER_CUR_DIS_SHIFT) - -/* - * SER_MODE_SUSPEND_EN (RW) - * - * for naneng usbphy, only switch to serial mode when suspend - */ -#define USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_MASK (0x10U) -#define USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_SHIFT (4U) -#define USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_SET(x) (((uint32_t)(x) << USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_SHIFT) & USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_MASK) -#define USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_GET(x) (((uint32_t)(x) & USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_MASK) >> USB_OTG_CTRL0_SER_MODE_SUSPEND_EN_SHIFT) - -/* Bitfield definition for register: PHY_CTRL0 */ -/* - * GPIO_ID_SEL_N (RW) - * - */ -#define USB_PHY_CTRL0_GPIO_ID_SEL_N_MASK (0x2000000UL) -#define USB_PHY_CTRL0_GPIO_ID_SEL_N_SHIFT (25U) -#define USB_PHY_CTRL0_GPIO_ID_SEL_N_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_GPIO_ID_SEL_N_SHIFT) & USB_PHY_CTRL0_GPIO_ID_SEL_N_MASK) -#define USB_PHY_CTRL0_GPIO_ID_SEL_N_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_GPIO_ID_SEL_N_MASK) >> USB_PHY_CTRL0_GPIO_ID_SEL_N_SHIFT) - -/* - * ID_DIG_OVERRIDE (RW) - * - */ -#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_MASK (0x4000U) -#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_SHIFT (14U) -#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_ID_DIG_OVERRIDE_SHIFT) & USB_PHY_CTRL0_ID_DIG_OVERRIDE_MASK) -#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_ID_DIG_OVERRIDE_MASK) >> USB_PHY_CTRL0_ID_DIG_OVERRIDE_SHIFT) - -/* - * SESS_VALID_OVERRIDE (RW) - * - */ -#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_MASK (0x2000U) -#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_SHIFT (13U) -#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_SESS_VALID_OVERRIDE_SHIFT) & USB_PHY_CTRL0_SESS_VALID_OVERRIDE_MASK) -#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_SESS_VALID_OVERRIDE_MASK) >> USB_PHY_CTRL0_SESS_VALID_OVERRIDE_SHIFT) - -/* - * VBUS_VALID_OVERRIDE (RW) - * - */ -#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_MASK (0x1000U) -#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_SHIFT (12U) -#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_SHIFT) & USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_MASK) -#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_MASK) >> USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_SHIFT) - -/* - * ID_DIG_OVERRIDE_EN (RW) - * - */ -#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_MASK (0x4U) -#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_SHIFT (2U) -#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_SHIFT) & USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_MASK) -#define USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_MASK) >> USB_PHY_CTRL0_ID_DIG_OVERRIDE_EN_SHIFT) - -/* - * SESS_VALID_OVERRIDE_EN (RW) - * - */ -#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_MASK (0x2U) -#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_SHIFT (1U) -#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_SHIFT) & USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_MASK) -#define USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_MASK) >> USB_PHY_CTRL0_SESS_VALID_OVERRIDE_EN_SHIFT) - -/* - * VBUS_VALID_OVERRIDE_EN (RW) - * - */ -#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_MASK (0x1U) -#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_SHIFT (0U) -#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_SET(x) (((uint32_t)(x) << USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_SHIFT) & USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_MASK) -#define USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_GET(x) (((uint32_t)(x) & USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_MASK) >> USB_PHY_CTRL0_VBUS_VALID_OVERRIDE_EN_SHIFT) - -/* Bitfield definition for register: PHY_CTRL1 */ -/* - * UTMI_CFG_RST_N (RW) - * - */ -#define USB_PHY_CTRL1_UTMI_CFG_RST_N_MASK (0x100000UL) -#define USB_PHY_CTRL1_UTMI_CFG_RST_N_SHIFT (20U) -#define USB_PHY_CTRL1_UTMI_CFG_RST_N_SET(x) (((uint32_t)(x) << USB_PHY_CTRL1_UTMI_CFG_RST_N_SHIFT) & USB_PHY_CTRL1_UTMI_CFG_RST_N_MASK) -#define USB_PHY_CTRL1_UTMI_CFG_RST_N_GET(x) (((uint32_t)(x) & USB_PHY_CTRL1_UTMI_CFG_RST_N_MASK) >> USB_PHY_CTRL1_UTMI_CFG_RST_N_SHIFT) - -/* - * UTMI_OTG_SUSPENDM (RW) - * - * OTG suspend, not utmi_suspendm - */ -#define USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_MASK (0x2U) -#define USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_SHIFT (1U) -#define USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_SET(x) (((uint32_t)(x) << USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_SHIFT) & USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_MASK) -#define USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_GET(x) (((uint32_t)(x) & USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_MASK) >> USB_PHY_CTRL1_UTMI_OTG_SUSPENDM_SHIFT) - -/* Bitfield definition for register: TOP_STATUS */ -/* - * WAKEUP_INT_STATUS (RW) - * - */ -#define USB_TOP_STATUS_WAKEUP_INT_STATUS_MASK (0x80000000UL) -#define USB_TOP_STATUS_WAKEUP_INT_STATUS_SHIFT (31U) -#define USB_TOP_STATUS_WAKEUP_INT_STATUS_SET(x) (((uint32_t)(x) << USB_TOP_STATUS_WAKEUP_INT_STATUS_SHIFT) & USB_TOP_STATUS_WAKEUP_INT_STATUS_MASK) -#define USB_TOP_STATUS_WAKEUP_INT_STATUS_GET(x) (((uint32_t)(x) & USB_TOP_STATUS_WAKEUP_INT_STATUS_MASK) >> USB_TOP_STATUS_WAKEUP_INT_STATUS_SHIFT) - -/* Bitfield definition for register: PHY_STATUS */ -/* - * UTMI_CLK_VALID (RW) - * - */ -#define USB_PHY_STATUS_UTMI_CLK_VALID_MASK (0x80000000UL) -#define USB_PHY_STATUS_UTMI_CLK_VALID_SHIFT (31U) -#define USB_PHY_STATUS_UTMI_CLK_VALID_SET(x) (((uint32_t)(x) << USB_PHY_STATUS_UTMI_CLK_VALID_SHIFT) & USB_PHY_STATUS_UTMI_CLK_VALID_MASK) -#define USB_PHY_STATUS_UTMI_CLK_VALID_GET(x) (((uint32_t)(x) & USB_PHY_STATUS_UTMI_CLK_VALID_MASK) >> USB_PHY_STATUS_UTMI_CLK_VALID_SHIFT) - -/* - * LINE_STATE (RW) - * - */ -#define USB_PHY_STATUS_LINE_STATE_MASK (0xC0U) -#define USB_PHY_STATUS_LINE_STATE_SHIFT (6U) -#define USB_PHY_STATUS_LINE_STATE_SET(x) (((uint32_t)(x) << USB_PHY_STATUS_LINE_STATE_SHIFT) & USB_PHY_STATUS_LINE_STATE_MASK) -#define USB_PHY_STATUS_LINE_STATE_GET(x) (((uint32_t)(x) & USB_PHY_STATUS_LINE_STATE_MASK) >> USB_PHY_STATUS_LINE_STATE_SHIFT) - -/* - * HOST_DISCONNECT (RW) - * - */ -#define USB_PHY_STATUS_HOST_DISCONNECT_MASK (0x20U) -#define USB_PHY_STATUS_HOST_DISCONNECT_SHIFT (5U) -#define USB_PHY_STATUS_HOST_DISCONNECT_SET(x) (((uint32_t)(x) << USB_PHY_STATUS_HOST_DISCONNECT_SHIFT) & USB_PHY_STATUS_HOST_DISCONNECT_MASK) -#define USB_PHY_STATUS_HOST_DISCONNECT_GET(x) (((uint32_t)(x) & USB_PHY_STATUS_HOST_DISCONNECT_MASK) >> USB_PHY_STATUS_HOST_DISCONNECT_SHIFT) - -/* - * ID_DIG (RW) - * - */ -#define USB_PHY_STATUS_ID_DIG_MASK (0x10U) -#define USB_PHY_STATUS_ID_DIG_SHIFT (4U) -#define USB_PHY_STATUS_ID_DIG_SET(x) (((uint32_t)(x) << USB_PHY_STATUS_ID_DIG_SHIFT) & USB_PHY_STATUS_ID_DIG_MASK) -#define USB_PHY_STATUS_ID_DIG_GET(x) (((uint32_t)(x) & USB_PHY_STATUS_ID_DIG_MASK) >> USB_PHY_STATUS_ID_DIG_SHIFT) - -/* - * UTMI_SESS_VALID (RW) - * - */ -#define USB_PHY_STATUS_UTMI_SESS_VALID_MASK (0x4U) -#define USB_PHY_STATUS_UTMI_SESS_VALID_SHIFT (2U) -#define USB_PHY_STATUS_UTMI_SESS_VALID_SET(x) (((uint32_t)(x) << USB_PHY_STATUS_UTMI_SESS_VALID_SHIFT) & USB_PHY_STATUS_UTMI_SESS_VALID_MASK) -#define USB_PHY_STATUS_UTMI_SESS_VALID_GET(x) (((uint32_t)(x) & USB_PHY_STATUS_UTMI_SESS_VALID_MASK) >> USB_PHY_STATUS_UTMI_SESS_VALID_SHIFT) - -/* - * VBUS_VALID (RW) - * - */ -#define USB_PHY_STATUS_VBUS_VALID_MASK (0x1U) -#define USB_PHY_STATUS_VBUS_VALID_SHIFT (0U) -#define USB_PHY_STATUS_VBUS_VALID_SET(x) (((uint32_t)(x) << USB_PHY_STATUS_VBUS_VALID_SHIFT) & USB_PHY_STATUS_VBUS_VALID_MASK) -#define USB_PHY_STATUS_VBUS_VALID_GET(x) (((uint32_t)(x) & USB_PHY_STATUS_VBUS_VALID_MASK) >> USB_PHY_STATUS_VBUS_VALID_SHIFT) - - - -/* ENDPTCTRL register group index macro definition */ -#define USB_ENDPTCTRL_ENDPTCTRL0 (0UL) -#define USB_ENDPTCTRL_ENDPTCTRL1 (1UL) -#define USB_ENDPTCTRL_ENDPTCTRL2 (2UL) -#define USB_ENDPTCTRL_ENDPTCTRL3 (3UL) -#define USB_ENDPTCTRL_ENDPTCTRL4 (4UL) -#define USB_ENDPTCTRL_ENDPTCTRL5 (5UL) -#define USB_ENDPTCTRL_ENDPTCTRL6 (6UL) -#define USB_ENDPTCTRL_ENDPTCTRL7 (7UL) - - -#endif /* HPM_USB_H */ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c b/rt-thread/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c deleted file mode 100644 index c6b6c0f..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/chipidea/usb_dc_chipidea.c +++ /dev/null @@ -1,718 +0,0 @@ -/* - * Copyright (c) 2021-2024 HPMicro - * - * SPDX-License-Identifier: BSD-3-Clause - * - */ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbd_core.h" -#include "usb_chipidea_reg.h" - -#define USB_OTG_DEV ((CHIPIDEA_TypeDef *)g_usbdev_bus[busid].reg_base) - -#define CHIPIDEA_BITSMASK(val, offset) ((uint32_t)(val) << (offset)) -#define QTD_COUNT_EACH_ENDPOINT (8U) - -/* ENDPTCTRL */ -enum { - ENDPTCTRL_STALL = CHIPIDEA_BITSMASK(1, 0), - ENDPTCTRL_TYPE = CHIPIDEA_BITSMASK(3, 2), - ENDPTCTRL_TOGGLE_INHIBIT = CHIPIDEA_BITSMASK(1, 5), - ENDPTCTRL_TOGGLE_RESET = CHIPIDEA_BITSMASK(1, 6), - ENDPTCTRL_ENABLE = CHIPIDEA_BITSMASK(1, 7), -}; - -/* USBSTS, USBINTR */ -enum { - intr_usb = CHIPIDEA_BITSMASK(1, 0), - intr_error = CHIPIDEA_BITSMASK(1, 1), - intr_port_change = CHIPIDEA_BITSMASK(1, 2), - intr_reset = CHIPIDEA_BITSMASK(1, 6), - intr_sof = CHIPIDEA_BITSMASK(1, 7), - intr_suspend = CHIPIDEA_BITSMASK(1, 8), - intr_nak = CHIPIDEA_BITSMASK(1, 16) -}; - -/* Queue Transfer Descriptor */ -typedef struct { - /* Word 0: Next QTD Pointer */ - volatile uint32_t next; /* Next link pointer This field contains the physical memory address of the next dTD to be processed */ - - /* Word 1: qTQ Token */ - volatile uint32_t : 3; - volatile uint32_t xact_err : 1; - volatile uint32_t : 1; - volatile uint32_t buffer_err : 1; - volatile uint32_t halted : 1; - volatile uint32_t active : 1; - volatile uint32_t : 2; - volatile uint32_t iso_mult_override : 2; /* This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO. */ - volatile uint32_t : 3; - volatile uint32_t int_on_complete : 1; - volatile uint32_t total_bytes : 15; - volatile uint32_t : 0; - - /* Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page */ - volatile uint32_t buffer[5]; - - /*------------- DCD Area -------------*/ - volatile uint16_t expected_bytes; - volatile uint8_t reserved[2]; -} dcd_qtd_t; - -/* Queue Head */ -typedef struct { - /* Word 0: Capabilities and Characteristics */ - - volatile uint32_t : 15; /* Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed. */ - volatile uint32_t int_on_setup : 1; /* Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received. */ - volatile uint32_t max_packet_size : 11; /* This directly corresponds to the maximum packet size of the associated endpoint (wMaxPacketSize) */ - volatile uint32_t : 2; - volatile uint32_t zero_length_termination : 1; /* This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length. */ - volatile uint32_t iso_mult : 2; - volatile uint32_t : 0; - - /* Word 1: Current qTD Pointer */ - volatile uint32_t qtd_addr; - - /* Word 2-9: Transfer Overlay */ - volatile dcd_qtd_t qtd_overlay; - - /* Word 10-11: Setup request (control OUT only) */ - volatile struct usb_setup_packet setup_request; - - /*-------------------------------------------------------------------- - * Due to the fact QHD is 64 bytes aligned but occupies only 48 bytes - * thus there are 16 bytes padding free that we can make use of. - *-------------------------------------------------------------------- - */ - volatile uint8_t reserved[16]; -} dcd_qhd_t; - -typedef struct { - dcd_qhd_t qhd[CONFIG_USBDEV_EP_NUM * 2]; - dcd_qtd_t qtd[CONFIG_USBDEV_EP_NUM * 2 * QTD_COUNT_EACH_ENDPOINT]; -} dcd_data_t; - -/* Endpoint state */ -struct chipidea_ep_state { - uint16_t ep_mps; /* Endpoint max packet size */ - uint8_t ep_type; /* Endpoint type */ - uint8_t ep_stalled; /* Endpoint stall flag */ - uint8_t ep_enable; /* Endpoint enable */ - uint8_t *xfer_buf; - uint32_t xfer_len; - uint32_t actual_xfer_len; -}; - -/* Driver state */ -struct chipidea_udc { - dcd_data_t *dcd_data; - bool is_suspend; - struct chipidea_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/ - struct chipidea_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */ -} g_chipidea_udc[CONFIG_USBDEV_MAX_BUS]; - -static USB_NOCACHE_RAM_SECTION __attribute__((aligned(2048))) dcd_data_t _dcd_data0; -#if CONFIG_USBDEV_MAX_BUS == 2 -static USB_NOCACHE_RAM_SECTION __attribute__((aligned(2048))) dcd_data_t _dcd_data1; -#endif - -static dcd_data_t *g_dcd_data[CONFIG_USBDEV_MAX_BUS] = { - &_dcd_data0, -#if CONFIG_USBDEV_MAX_BUS == 2 - &_dcd_data1 -#endif -}; - -/* Index to bit position in register */ -static inline uint8_t ep_idx2bit(uint8_t ep_idx) -{ - return ep_idx / 2 + ((ep_idx % 2) ? 16 : 0); -} - -static void __chipidea_bus_reset(CHIPIDEA_TypeDef *ptr) -{ - /* The reset value for all endpoint types is the control endpoint. If one endpoint - * direction is enabled and the paired endpoint of opposite direction is disabled, then the - * endpoint type of the unused direction must be changed from the control type to any other - * type (e.g. bulk). Leaving an un-configured endpoint control will cause undefined behavior - * for the data PID tracking on the active endpoint. - */ - - for (uint32_t i = 1; i < CONFIG_USBDEV_EP_NUM; i++) { - ptr->ENDPTCTRL[i] = USB_ENDPTCTRL_TXT_SET(USB_ENDPOINT_TYPE_BULK) | USB_ENDPTCTRL_RXT_SET(USB_ENDPOINT_TYPE_BULK); - } - - /* Clear All Registers */ - ptr->ENDPTNAK = ptr->ENDPTNAK; - ptr->ENDPTNAKEN = 0; - ptr->USBSTS = ptr->USBSTS; - ptr->ENDPTSETUPSTAT = ptr->ENDPTSETUPSTAT; - ptr->ENDPTCOMPLETE = ptr->ENDPTCOMPLETE; - - while (ptr->ENDPTPRIME) { - } - ptr->ENDPTFLUSH = 0xFFFFFFFF; - while (ptr->ENDPTFLUSH) { - } -} - -static void chipidea_init(CHIPIDEA_TypeDef *ptr) -{ - /* Reset controller */ - ptr->USBCMD |= USB_USBCMD_RST_MASK; - while (USB_USBCMD_RST_GET(ptr->USBCMD)) { - } - - /* Set mode to device, must be set immediately after reset */ - ptr->USBMODE &= ~USB_USBMODE_CM_MASK; - ptr->USBMODE |= USB_USBMODE_CM_SET(2); - - /* Disable setup lockout, please refer to "Control Endpoint Operation" section in RM. */ - ptr->USBMODE &= ~USB_USBMODE_SLOM_MASK; - - /* Set the endian */ - ptr->USBMODE &= ~USB_USBMODE_ES_MASK; - - /* Set parallel interface signal */ - ptr->PORTSC1 &= ~USB_PORTSC1_STS_MASK; - - /* Set parallel transceiver width */ - ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK; - - /* Set usb forced to full speed mode */ - //ptr->PORTSC1 |= USB_PORTSC1_PFSC_MASK; - - /* Not use interrupt threshold. */ - ptr->USBCMD &= ~USB_USBCMD_ITC_MASK; - - /* Enable VBUS discharge */ - ptr->OTGSC |= USB_OTGSC_VD_MASK; -} - -static void chipidea_deinit(CHIPIDEA_TypeDef *ptr) -{ - /* Stop */ - ptr->USBCMD &= ~USB_USBCMD_RS_MASK; - - /* Reset controller */ - ptr->USBCMD |= USB_USBCMD_RST_MASK; - while (USB_USBCMD_RST_GET(ptr->USBCMD)) { - } - - /* Reset endpoint list address register */ - ptr->ENDPTLISTADDR = 0; - - /* Reset status register */ - ptr->USBSTS = ptr->USBSTS; - - /* Reset interrupt enable register */ - ptr->USBINTR = 0; -} - -/*--------------------------------------------------------------------- - * Endpoint API - *--------------------------------------------------------------------- - */ -static void __chipidea_edpt_open(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr, uint8_t ep_type) -{ - uint8_t const epnum = ep_addr & 0x0f; - uint8_t const dir = (ep_addr & 0x80) >> 7; - - /* Enable EP Control */ - uint32_t temp = ptr->ENDPTCTRL[epnum]; - temp &= ~((0x03 << 2) << (dir ? 16 : 0)); - temp |= ((ep_type << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0); - ptr->ENDPTCTRL[epnum] = temp; -} - -static void chipidea_edpt_xfer(CHIPIDEA_TypeDef *ptr, uint8_t ep_idx) -{ - uint32_t offset = ep_idx / 2 + ((ep_idx % 2) ? 16 : 0); - - /* Start transfer */ - ptr->ENDPTPRIME = 1 << offset; -} - -static void chipidea_edpt_stall(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr) -{ - uint8_t const epnum = ep_addr & 0x0f; - uint8_t const dir = (ep_addr & 0x80) >> 7; - - ptr->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0); -} - -static void chipidea_edpt_clear_stall(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr) -{ - uint8_t const epnum = ep_addr & 0x0f; - uint8_t const dir = (ep_addr & 0x80) >> 7; - - /* data toggle also need to be reset */ - ptr->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << (dir ? 16 : 0); - ptr->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << (dir ? 16 : 0)); -} - -static bool chipidea_edpt_check_stall(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr) -{ - uint8_t const epnum = ep_addr & 0x0f; - uint8_t const dir = (ep_addr & 0x80) >> 7; - - return (ptr->ENDPTCTRL[epnum] & (ENDPTCTRL_STALL << (dir ? 16 : 0))) ? true : false; -} - -static void chipidea_edpt_close(CHIPIDEA_TypeDef *ptr, uint8_t ep_addr) -{ - uint8_t const epnum = ep_addr & 0x0f; - uint8_t const dir = (ep_addr & 0x80) >> 7; - - uint32_t primebit = CHIPIDEA_BITSMASK(1, epnum) << (dir ? 16 : 0); - - /* Flush the endpoint to stop a transfer. */ - do { - /* Set the corresponding bit(s) in the ENDPTFLUSH register */ - ptr->ENDPTFLUSH |= primebit; - - /* Wait until all bits in the ENDPTFLUSH register are cleared. */ - while (0U != (ptr->ENDPTFLUSH & primebit)) { - } - /* - * Read the ENDPTSTAT register to ensure that for all endpoints - * commanded to be flushed, that the corresponding bits - * are now cleared. - */ - } while (0U != (ptr->ENDPTSTAT & primebit)); - - /* Disable the endpoint */ - ptr->ENDPTCTRL[epnum] &= ~((ENDPTCTRL_TYPE | ENDPTCTRL_ENABLE | ENDPTCTRL_STALL) << (dir ? 16 : 0)); - ptr->ENDPTCTRL[epnum] |= (USB_ENDPOINT_TYPE_BULK << 2) << (dir ? 16 : 0); -} - -/* Initialize qtd */ -static void usb_qtd_init(dcd_qtd_t *p_qtd, void *data_ptr, uint16_t total_bytes) -{ - memset(p_qtd, 0, sizeof(dcd_qtd_t)); - - p_qtd->next = 1; - p_qtd->active = 1; - p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; - - if (data_ptr != NULL) { - p_qtd->buffer[0] = (uint32_t)data_ptr; - for (uint8_t i = 1; i < 5; i++) { - p_qtd->buffer[i] |= ((p_qtd->buffer[i - 1]) & 0xFFFFF000UL) + 4096U; - } - } -} - -static dcd_qhd_t *chipidea_qhd_get(uint8_t busid, uint8_t ep_idx) -{ - dcd_data_t *dcd_data; - - dcd_data = g_chipidea_udc[busid].dcd_data; - return &dcd_data->qhd[ep_idx]; -} - -static dcd_qtd_t *chipidea_qtd_get(uint8_t busid, uint8_t ep_idx) -{ - dcd_data_t *dcd_data; - - dcd_data = g_chipidea_udc[busid].dcd_data; - return &dcd_data->qtd[ep_idx * QTD_COUNT_EACH_ENDPOINT]; -} - -static void chipidea_bus_reset(uint8_t busid, uint16_t ep0_max_packet_size) -{ - dcd_data_t *dcd_data; - - dcd_data = g_chipidea_udc[busid].dcd_data; - __chipidea_bus_reset(USB_OTG_DEV); - - /* Queue Head & Queue TD */ - memset(dcd_data, 0, sizeof(dcd_data_t)); - - /* Set up Control Endpoints (0 OUT, 1 IN) */ - dcd_data->qhd[0].zero_length_termination = dcd_data->qhd[1].zero_length_termination = 1; - dcd_data->qhd[0].max_packet_size = dcd_data->qhd[1].max_packet_size = ep0_max_packet_size; - dcd_data->qhd[0].qtd_overlay.next = dcd_data->qhd[1].qtd_overlay.next = 1; - - /* OUT only */ - dcd_data->qhd[0].int_on_setup = 1; -} - -static void chipidea_edpt_open(uint8_t busid, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps) -{ - uint8_t const epnum = ep_addr & 0x0f; - uint8_t const dir = (ep_addr & 0x80) >> 7; - uint8_t const ep_idx = 2 * epnum + dir; - dcd_data_t *dcd_data; - dcd_qhd_t *p_qhd; - - /* Prepare Queue Head */ - dcd_data = g_chipidea_udc[busid].dcd_data; - p_qhd = &dcd_data->qhd[ep_idx]; - memset(p_qhd, 0, sizeof(dcd_qhd_t)); - - p_qhd->zero_length_termination = 1; - p_qhd->max_packet_size = ep_mps & 0x7FFu; - p_qhd->qtd_overlay.next = 1; - if (ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) { - p_qhd->iso_mult = ((ep_mps >> 11u) & 0x3u) + 1u; - } - - __chipidea_edpt_open(USB_OTG_DEV, ep_addr, ep_type); -} - -static bool chipidea_start_xfer(uint8_t busid, uint8_t ep_addr, uint8_t *buffer, uint32_t total_bytes) -{ - uint8_t const epnum = ep_addr & 0x0f; - uint8_t const dir = (ep_addr & 0x80) >> 7; - uint8_t const ep_idx = 2 * epnum + dir; - uint8_t qtd_num; - uint8_t i; - uint32_t xfer_len; - dcd_qhd_t *p_qhd; - dcd_qtd_t *p_qtd; - dcd_qtd_t *first_p_qtd = NULL; - dcd_qtd_t *prev_p_qtd = NULL; - dcd_data_t *dcd_data; - - dcd_data = g_chipidea_udc[busid].dcd_data; - - if (epnum == 0) { - /* follows UM Setup packet handling using setup lockout mechanism - * wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out - */ - while (USB_OTG_DEV->ENDPTSETUPSTAT & CHIPIDEA_BITSMASK(1, 0)) { - } - } - - qtd_num = (total_bytes + 0x3fff) / 0x4000; - if (qtd_num > QTD_COUNT_EACH_ENDPOINT) { - return false; - } - - if (buffer != NULL) { - buffer = (uint8_t *)buffer; - } - p_qhd = &dcd_data->qhd[ep_idx]; - i = 0; - do { - p_qtd = &dcd_data->qtd[ep_idx * QTD_COUNT_EACH_ENDPOINT + i]; - i++; - - if (total_bytes > 0x4000) { - xfer_len = 0x4000; - total_bytes -= 0x4000; - } else { - xfer_len = total_bytes; - total_bytes = 0; - } - - usb_qtd_init(p_qtd, (void *)buffer, xfer_len); - if (total_bytes == 0) { - p_qtd->int_on_complete = true; - } - buffer += xfer_len; - - if (prev_p_qtd) { - prev_p_qtd->next = (uint32_t)p_qtd; - } else { - first_p_qtd = p_qtd; - } - prev_p_qtd = p_qtd; - } while (total_bytes > 0); - - p_qhd->qtd_overlay.next = (uint32_t)first_p_qtd; /* link qtd to qhd */ - - chipidea_edpt_xfer(USB_OTG_DEV, ep_idx); - - return true; -} - -__WEAK void usb_dc_low_level_init(uint8_t busid) -{ -} - -__WEAK void usb_dc_low_level_deinit(uint8_t busid) -{ -} - -int usb_dc_init(uint8_t busid) -{ - uint32_t int_mask; - int_mask = (USB_USBINTR_UE_MASK | USB_USBINTR_UEE_MASK | USB_USBINTR_SLE_MASK | - USB_USBINTR_PCE_MASK | USB_USBINTR_URE_MASK); - - usb_dc_low_level_init(busid); - - memset(&g_chipidea_udc[busid], 0, sizeof(struct chipidea_udc)); - g_chipidea_udc[busid].dcd_data = g_dcd_data[busid]; - memset(g_chipidea_udc[busid].dcd_data, 0, sizeof(dcd_data_t)); - - chipidea_init(USB_OTG_DEV); - - /* Set endpoint list address */ - USB_OTG_DEV->ENDPTLISTADDR = ((uint32_t)g_chipidea_udc[busid].dcd_data->qhd) & USB_ENDPTLISTADDR_EPBASE_MASK; - - /* Clear status */ - USB_OTG_DEV->USBSTS = USB_OTG_DEV->USBSTS; - - /* Enable interrupt mask */ - USB_OTG_DEV->USBINTR |= int_mask; - - /* Connect by enabling internal pull-up resistor on D+/D- */ - USB_OTG_DEV->USBCMD |= USB_USBCMD_RS_MASK; - return 0; -} - -int usb_dc_deinit(uint8_t busid) -{ - chipidea_deinit(USB_OTG_DEV); - - for (uint32_t i = 0; i < CONFIG_USBDEV_EP_NUM; i++) { - chipidea_edpt_close(USB_OTG_DEV, (i | 0x80)); - chipidea_edpt_close(USB_OTG_DEV, (i | 0x00)); - } - - usb_dc_low_level_deinit(busid); - return 0; -} - -int usbd_set_address(uint8_t busid, const uint8_t addr) -{ - USB_OTG_DEV->DEVICEADDR = USB_DEVICEADDR_USBADR_SET(addr) | USB_DEVICEADDR_USBADRA_MASK; - return 0; -} - -int usbd_set_remote_wakeup(uint8_t busid) -{ - if (!USB_PORTSC1_SUSP_GET(USB_OTG_DEV->PORTSC1)) { - return -1; - } - - USB_OTG_DEV->PORTSC1 |= USB_PORTSC1_FPR_MASK; - while (USB_OTG_DEV->PORTSC1 & USB_PORTSC1_FPR_MASK) { - } - - return 0; -} - -uint8_t usbd_get_port_speed(uint8_t busid) -{ - uint8_t speed; - - speed = USB_PORTSC1_PSPD_GET(USB_OTG_DEV->PORTSC1); - - if (speed == 0x00) { - return USB_SPEED_FULL; - } - if (speed == 0x01) { - return USB_SPEED_LOW; - } - if (speed == 0x02) { - return USB_SPEED_HIGH; - } - - return 0; -} - -int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress); - - /* Must not exceed max endpoint number */ - if (ep_idx >= CONFIG_USBDEV_EP_NUM) { - return -1; - } - - chipidea_edpt_open(busid, ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(ep->bmAttributes), ep->wMaxPacketSize); - - if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) { - g_chipidea_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); - g_chipidea_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); - g_chipidea_udc[busid].out_ep[ep_idx].ep_enable = true; - } else { - g_chipidea_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); - g_chipidea_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); - g_chipidea_udc[busid].in_ep[ep_idx].ep_enable = true; - } - - return 0; -} - -int usbd_ep_close(uint8_t busid, const uint8_t ep) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep); - - if (USB_EP_DIR_IS_OUT(ep)) { - g_chipidea_udc[busid].out_ep[ep_idx].ep_enable = false; - } else { - g_chipidea_udc[busid].in_ep[ep_idx].ep_enable = false; - } - - chipidea_edpt_close(USB_OTG_DEV, ep); - - return 0; -} - -int usbd_ep_set_stall(uint8_t busid, const uint8_t ep) -{ - chipidea_edpt_stall(USB_OTG_DEV, ep); - return 0; -} - -int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep) -{ - chipidea_edpt_clear_stall(USB_OTG_DEV, ep); - return 0; -} - -int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled) -{ - *stalled = chipidea_edpt_check_stall(USB_OTG_DEV, ep); - return 0; -} - -int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep); - - if (!data && data_len) { - return -1; - } - if (!g_chipidea_udc[busid].in_ep[ep_idx].ep_enable) { - return -2; - } - - g_chipidea_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data; - g_chipidea_udc[busid].in_ep[ep_idx].xfer_len = data_len; - g_chipidea_udc[busid].in_ep[ep_idx].actual_xfer_len = 0; - - chipidea_start_xfer(busid, ep, (uint8_t *)data, data_len); - - return 0; -} - -int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep); - - if (!data && data_len) { - return -1; - } - if (!g_chipidea_udc[busid].out_ep[ep_idx].ep_enable) { - return -2; - } - - g_chipidea_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data; - g_chipidea_udc[busid].out_ep[ep_idx].xfer_len = data_len; - g_chipidea_udc[busid].out_ep[ep_idx].actual_xfer_len = 0; - - chipidea_start_xfer(busid, ep, data, data_len); - - return 0; -} - -void USBD_IRQHandler(uint8_t busid) -{ - uint32_t int_status; - uint32_t transfer_len; - bool ep_cb_req; - - /* Acknowledge handled interrupt */ - int_status = USB_OTG_DEV->USBSTS; - int_status &= USB_OTG_DEV->USBINTR; - USB_OTG_DEV->USBSTS = int_status; - - if (int_status & intr_error) { - USB_LOG_ERR("usbd intr error!\r\n"); - } - - if (int_status & intr_reset) { - g_chipidea_udc[busid].is_suspend = false; - memset(g_chipidea_udc[busid].in_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM); - memset(g_chipidea_udc[busid].out_ep, 0, sizeof(struct chipidea_ep_state) * CONFIG_USBDEV_EP_NUM); - usbd_event_reset_handler(busid); - chipidea_bus_reset(busid, 64); - } - - if (int_status & intr_suspend) { - if (USB_PORTSC1_SUSP_GET(USB_OTG_DEV->PORTSC1)) { - /* Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. */ - if (USB_DEVICEADDR_USBADR_GET(USB_OTG_DEV->DEVICEADDR)) { - g_chipidea_udc[busid].is_suspend = true; - usbd_event_suspend_handler(busid); - } - } else { - } - } - - if (int_status & intr_port_change) { - if (!USB_PORTSC1_CCS_GET(USB_OTG_DEV->PORTSC1)) { - usbd_event_disconnect_handler(busid); - } else { - if (g_chipidea_udc[busid].is_suspend) { - g_chipidea_udc[busid].is_suspend = false; - usbd_event_resume_handler(busid); - } - usbd_event_connect_handler(busid); - } - } - - if (int_status & intr_usb) { - uint32_t const edpt_complete = USB_OTG_DEV->ENDPTCOMPLETE; - USB_OTG_DEV->ENDPTCOMPLETE = edpt_complete; - uint32_t edpt_setup_status = USB_OTG_DEV->ENDPTSETUPSTAT; - - if (edpt_setup_status) { - /*------------- Set up Received -------------*/ - USB_OTG_DEV->ENDPTSETUPSTAT = edpt_setup_status; - dcd_qhd_t *qhd0 = chipidea_qhd_get(busid, 0); - usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&qhd0->setup_request); - } - - if (edpt_complete) { - for (uint8_t ep_idx = 0; ep_idx < (CONFIG_USBDEV_EP_NUM * 2); ep_idx++) { - if (edpt_complete & (1 << ep_idx2bit(ep_idx))) { - transfer_len = 0; - ep_cb_req = true; - - /* Failed QTD also get ENDPTCOMPLETE set */ - dcd_qtd_t *p_qtd = chipidea_qtd_get(busid, ep_idx); - while (1) { - if (p_qtd->halted || p_qtd->xact_err || p_qtd->buffer_err) { - USB_LOG_ERR("usbd transfer error!\r\n"); - ep_cb_req = false; - break; - } else if (p_qtd->active) { - ep_cb_req = false; - break; - } else { - transfer_len += p_qtd->expected_bytes - p_qtd->total_bytes; - } - - if (p_qtd->next == 1) { - break; - } else { - p_qtd = (dcd_qtd_t *)p_qtd->next; - } - } - - if (ep_cb_req) { - uint8_t const ep_addr = (ep_idx / 2) | ((ep_idx & 0x01) ? 0x80 : 0); - if (ep_addr & 0x80) { - usbd_event_ep_in_complete_handler(busid, ep_addr, transfer_len); - } else { - usbd_event_ep_out_complete_handler(busid, ep_addr, transfer_len); - } - } - } - } - } - } -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/chipidea/usb_glue_mcx.c b/rt-thread/components/drivers/usb/cherryusb/port/chipidea/usb_glue_mcx.c deleted file mode 100644 index 3f9b46b..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/chipidea/usb_glue_mcx.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbd_core.h" -#include "fsl_common.h" - -/*! @brief USB controller ID */ -typedef enum _usb_controller_index { - kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */ - kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved - to be used in the future. */ - kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */ - kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U */ -} usb_controller_index_t; - -#define USB_DEVICE_CONFIG_EHCI 1 - -/* USB PHY condfiguration */ -#define BOARD_USB_PHY_D_CAL (0x04U) -#define BOARD_USB_PHY_TXCAL45DP (0x07U) -#define BOARD_USB_PHY_TXCAL45DM (0x07U) -#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ - -#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) -#include "usb_phy.h" -#endif - -#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) -void USB1_HS_IRQHandler(void) -{ - extern void USBD_IRQHandler(uint8_t busid); - USBD_IRQHandler(0); -} -#endif - -void USB_ClockInit(void) -{ -#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) - usb_phy_config_struct_t phyConfig = { - BOARD_USB_PHY_D_CAL, - BOARD_USB_PHY_TXCAL45DP, - BOARD_USB_PHY_TXCAL45DM, - }; -#endif -#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) - SPC0->ACTIVE_VDELAY = 0x0500; - /* Change the power DCDC to 1.8v (By deafult, DCDC is 1.8V), CORELDO to 1.1v (By deafult, CORELDO is 1.0V) */ - SPC0->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK; - SPC0->ACTIVE_CFG |= SPC_ACTIVE_CFG_DCDC_VDD_LVL(0x3) | SPC_ACTIVE_CFG_CORELDO_VDD_LVL(0x3) | - SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK | SPC_ACTIVE_CFG_DCDC_VDD_DS(0x2u); - /* Wait until it is done */ - while (SPC0->SC & SPC_SC_BUSY_MASK) - ; - if (0u == (SCG0->LDOCSR & SCG_LDOCSR_LDOEN_MASK)) { - SCG0->TRIM_LOCK = 0x5a5a0001U; - SCG0->LDOCSR |= SCG_LDOCSR_LDOEN_MASK; - /* wait LDO ready */ - while (0U == (SCG0->LDOCSR & SCG_LDOCSR_VOUT_OK_MASK)) - ; - } - SYSCON->AHBCLKCTRLSET[2] |= SYSCON_AHBCLKCTRL2_USB_HS_MASK | SYSCON_AHBCLKCTRL2_USB_HS_PHY_MASK; - SCG0->SOSCCFG &= ~(SCG_SOSCCFG_RANGE_MASK | SCG_SOSCCFG_EREFS_MASK); - /* xtal = 20 ~ 30MHz */ - SCG0->SOSCCFG = (1U << SCG_SOSCCFG_RANGE_SHIFT) | (1U << SCG_SOSCCFG_EREFS_SHIFT); - SCG0->SOSCCSR |= SCG_SOSCCSR_SOSCEN_MASK; - while (1) { - if (SCG0->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) { - break; - } - } - SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK | SYSCON_CLOCK_CTRL_CLKIN_ENA_FM_USBH_LPT_MASK; - CLOCK_EnableClock(kCLOCK_UsbHs); - CLOCK_EnableClock(kCLOCK_UsbHsPhy); - CLOCK_EnableUsbhsPhyPllClock(kCLOCK_Usbphy480M, 24000000U); - CLOCK_EnableUsbhsClock(); - USB_EhciPhyInit(kUSB_ControllerEhci0, BOARD_XTAL0_CLK_HZ, &phyConfig); -#endif -#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U) - CLOCK_AttachClk(kCLK_48M_to_USB0); - CLOCK_EnableClock(kCLOCK_Usb0Ram); - CLOCK_EnableClock(kCLOCK_Usb0Fs); - CLOCK_EnableUsbfsClock(); -#endif -} - -void usb_dc_low_level_init(uint8_t busid) -{ - USB_ClockInit(); - /* Install isr, set priority, and enable IRQ. */ - NVIC_SetPriority((IRQn_Type)USB1_HS_IRQn, 3); - EnableIRQ((IRQn_Type)USB1_HS_IRQn); -} - -void usb_dc_low_level_deinit(uint8_t busid) -{ - DisableIRQ((IRQn_Type)USB1_HS_IRQn); -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/README.md b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/README.md index 3218b31..2111008 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/README.md +++ b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/README.md @@ -1,7 +1,5 @@ # Note -If you are using more than one port, all ip parameters must be the same(like fifo num, endpoint num, dma support and so on), otherwise give up using multi ports. - ## Support Chip List ## STM32 @@ -20,11 +18,6 @@ If you are using more than one port, all ip parameters must be the same(like fif ## GD32 -CONFIG_USBDEV_EP_NUM 必须为4 或者 6,并删除 usb_dc_dwc2.c 中 while(1){} - -当 CONFIG_USBDEV_EP_NUM 为4 时,fifo_num 不得大于 320 字 -当 CONFIG_USBDEV_EP_NUM 为6 时,fifo_num 不得大于 1280 字 - - GD32F30X_CL - GD32F405、GD32F407 - GD32F450 diff --git a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c index 6054a33..9dee5c1 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c @@ -51,6 +51,8 @@ #endif // clang-format on +//#define CONFIG_USB_DWC2_DMA_ENABLE + #ifndef CONFIG_USB_DWC2_RXALL_FIFO_SIZE #define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4) #endif @@ -60,7 +62,7 @@ #endif #ifndef CONFIG_USB_DWC2_TX1_FIFO_SIZE -#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (1024 / 4) +#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (512 / 4) #endif #ifndef CONFIG_USB_DWC2_TX2_FIFO_SIZE @@ -91,7 +93,7 @@ #define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4) #endif -#define USBD_BASE (g_usbdev_bus[busid].reg_base) +#define USBD_BASE (g_usbdev_bus[0].reg_base) #define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(USBD_BASE)) #define USB_OTG_DEV ((DWC2_DeviceTypeDef *)(USBD_BASE + USB_OTG_DEVICE_BASE)) @@ -117,9 +119,9 @@ USB_NOCACHE_RAM_SECTION struct dwc2_udc { __attribute__((aligned(32))) struct usb_setup_packet setup; struct dwc2_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/ struct dwc2_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */ -} g_dwc2_udc[CONFIG_USBDEV_MAX_BUS]; +} g_dwc2_udc; -static inline int dwc2_reset(uint8_t busid) +static inline int dwc2_reset(void) { volatile uint32_t count = 0U; @@ -136,16 +138,14 @@ static inline int dwc2_reset(uint8_t busid) do { if (++count > 200000U) { - break; + return -1; } } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); - USB_OTG_GLB->GRSTCTL &= ~USB_OTG_GRSTCTL_CSRST; - return 0; } -static inline int dwc2_core_init(uint8_t busid) +static inline int dwc2_core_init(void) { int ret; #if defined(CONFIG_USB_HS) @@ -156,18 +156,18 @@ static inline int dwc2_core_init(uint8_t busid) USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); /* Reset after a PHY select */ - ret = dwc2_reset(busid); + ret = dwc2_reset(); #else /* Select FS Embedded PHY */ USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; /* Reset after a PHY select */ - ret = dwc2_reset(busid); + ret = dwc2_reset(); #endif return ret; } -static inline void dwc2_set_mode(uint8_t busid, uint8_t mode) +static inline void dwc2_set_mode(uint8_t mode) { USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD); @@ -176,22 +176,12 @@ static inline void dwc2_set_mode(uint8_t busid, uint8_t mode) } else if (mode == USB_OTG_MODE_DEVICE) { USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; } - - usbd_dwc2_delay_ms(50); } -static inline int dwc2_flush_rxfifo(uint8_t busid) +static inline int dwc2_flush_rxfifo(void) { - volatile uint32_t count = 0U; + volatile uint32_t count = 0; - /* Wait for AHB master IDLE state. */ - do { - if (++count > 200000U) { - return -1; - } - } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); - - count = 0; USB_OTG_GLB->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH; do { @@ -203,18 +193,10 @@ static inline int dwc2_flush_rxfifo(uint8_t busid) return 0; } -static inline int dwc2_flush_txfifo(uint8_t busid, uint32_t num) +static inline int dwc2_flush_txfifo(uint32_t num) { volatile uint32_t count = 0U; - /* Wait for AHB master IDLE state. */ - do { - if (++count > 200000U) { - return -1; - } - } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); - - count = 0; USB_OTG_GLB->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6)); do { @@ -226,7 +208,7 @@ static inline int dwc2_flush_txfifo(uint8_t busid, uint32_t num) return 0; } -static void dwc2_set_turnaroundtime(uint8_t busid, uint32_t hclk, uint8_t speed) +static void dwc2_set_turnaroundtime(uint32_t hclk, uint8_t speed) { uint32_t UsbTrd; @@ -279,7 +261,7 @@ static void dwc2_set_turnaroundtime(uint8_t busid, uint32_t hclk, uint8_t speed) USB_OTG_GLB->GUSBCFG |= (uint32_t)((UsbTrd << USB_OTG_GUSBCFG_TRDT_Pos) & USB_OTG_GUSBCFG_TRDT); } -static void dwc2_set_txfifo(uint8_t busid, uint8_t fifo, uint16_t size) +static void dwc2_set_txfifo(uint8_t fifo, uint16_t size) { uint8_t i; uint32_t tx_offset; @@ -311,7 +293,7 @@ static void dwc2_set_txfifo(uint8_t busid, uint8_t fifo, uint16_t size) USB_LOG_INFO("fifo%d size:%04x, offset:%04x\r\n", fifo, size, tx_offset); } -static uint8_t dwc2_get_devspeed(uint8_t busid) +static uint8_t dwc2_get_devspeed(void) { uint8_t speed; uint32_t DevEnumSpeed = USB_OTG_DEV->DSTS & USB_OTG_DSTS_ENUMSPD; @@ -328,7 +310,7 @@ static uint8_t dwc2_get_devspeed(uint8_t busid) return speed; } -static void dwc2_ep0_start_read_setup(uint8_t busid, uint8_t *psetup) +static void dwc2_ep0_start_read_setup(uint8_t *psetup) { USB_OTG_OUTEP(0U)->DOEPTSIZ = 0U; USB_OTG_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19)); @@ -342,7 +324,7 @@ static void dwc2_ep0_start_read_setup(uint8_t busid, uint8_t *psetup) #endif } -void dwc2_ep_write(uint8_t busid, uint8_t ep_idx, uint8_t *src, uint16_t len) +void dwc2_ep_write(uint8_t ep_idx, uint8_t *src, uint16_t len) { uint32_t *pSrc = (uint32_t *)src; uint32_t count32b, i; @@ -354,7 +336,7 @@ void dwc2_ep_write(uint8_t busid, uint8_t ep_idx, uint8_t *src, uint16_t len) } } -void dwc2_ep_read(uint8_t busid, uint8_t *dest, uint16_t len) +void dwc2_ep_read(uint8_t *dest, uint16_t len) { uint32_t *pDest = (uint32_t *)dest; uint32_t i; @@ -366,44 +348,33 @@ void dwc2_ep_read(uint8_t busid, uint8_t *dest, uint16_t len) } } -static void dwc2_tx_fifo_empty_procecss(uint8_t busid, uint8_t ep_idx) +static void dwc2_tx_fifo_empty_procecss(uint8_t ep_idx) { uint32_t len; uint32_t len32b; uint32_t fifoemptymsk; - len = g_dwc2_udc[busid].in_ep[ep_idx].xfer_len - g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len; - if (len > g_dwc2_udc[busid].in_ep[ep_idx].ep_mps) { - len = g_dwc2_udc[busid].in_ep[ep_idx].ep_mps; + len = g_dwc2_udc.in_ep[ep_idx].xfer_len - g_dwc2_udc.in_ep[ep_idx].actual_xfer_len; + if (len > g_dwc2_udc.in_ep[ep_idx].ep_mps) { + len = g_dwc2_udc.in_ep[ep_idx].ep_mps; } len32b = (len + 3U) / 4U; while (((USB_OTG_INEP(ep_idx)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) && - (g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len < g_dwc2_udc[busid].in_ep[ep_idx].xfer_len) && (g_dwc2_udc[busid].in_ep[ep_idx].xfer_len != 0U)) { + (g_dwc2_udc.in_ep[ep_idx].actual_xfer_len < g_dwc2_udc.in_ep[ep_idx].xfer_len) && (g_dwc2_udc.in_ep[ep_idx].xfer_len != 0U)) { /* Write the FIFO */ - len = g_dwc2_udc[busid].in_ep[ep_idx].xfer_len - g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len; - if (len > g_dwc2_udc[busid].in_ep[ep_idx].ep_mps) { - len = g_dwc2_udc[busid].in_ep[ep_idx].ep_mps; - } - if (g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) { - if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) { - USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_SD0PID_SEVNFRM; - USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM; - } else { - USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_SODDFRM; - USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; - } - USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT); - USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29)); + len = g_dwc2_udc.in_ep[ep_idx].xfer_len - g_dwc2_udc.in_ep[ep_idx].actual_xfer_len; + if (len > g_dwc2_udc.in_ep[ep_idx].ep_mps) { + len = g_dwc2_udc.in_ep[ep_idx].ep_mps; } - dwc2_ep_write(busid, ep_idx, g_dwc2_udc[busid].in_ep[ep_idx].xfer_buf, len); - g_dwc2_udc[busid].in_ep[ep_idx].xfer_buf += len; - g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len += len; + dwc2_ep_write(ep_idx, g_dwc2_udc.in_ep[ep_idx].xfer_buf, len); + g_dwc2_udc.in_ep[ep_idx].xfer_buf += len; + g_dwc2_udc.in_ep[ep_idx].actual_xfer_len += len; } - if (g_dwc2_udc[busid].in_ep[ep_idx].xfer_len <= g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len) { + if (g_dwc2_udc.in_ep[ep_idx].xfer_len <= g_dwc2_udc.in_ep[ep_idx].actual_xfer_len) { fifoemptymsk = (uint32_t)(0x1UL << (ep_idx & 0x0f)); USB_OTG_DEV->DIEPEMPMSK &= ~fifoemptymsk; } @@ -413,7 +384,7 @@ static void dwc2_tx_fifo_empty_procecss(uint8_t busid, uint8_t ep_idx) * @brief dwc2_get_glb_intstatus: return the global USB interrupt status * @retval status */ -static inline uint32_t dwc2_get_glb_intstatus(uint8_t busid) +static inline uint32_t dwc2_get_glb_intstatus(void) { uint32_t tmpreg; @@ -427,7 +398,7 @@ static inline uint32_t dwc2_get_glb_intstatus(uint8_t busid) * @brief dwc2_get_outeps_intstatus: return the USB device OUT endpoints interrupt status * @retval status */ -static inline uint32_t dwc2_get_outeps_intstatus(uint8_t busid) +static inline uint32_t dwc2_get_outeps_intstatus(void) { uint32_t tmpreg; @@ -441,7 +412,7 @@ static inline uint32_t dwc2_get_outeps_intstatus(uint8_t busid) * @brief dwc2_get_ineps_intstatus: return the USB device IN endpoints interrupt status * @retval status */ -static inline uint32_t dwc2_get_ineps_intstatus(uint8_t busid) +static inline uint32_t dwc2_get_ineps_intstatus(void) { uint32_t tmpreg; @@ -457,13 +428,12 @@ static inline uint32_t dwc2_get_ineps_intstatus(uint8_t busid) * This parameter can be a value from 0 to 15 * @retval Device OUT EP Interrupt register */ -static inline uint32_t dwc2_get_outep_intstatus(uint8_t busid, uint8_t epnum) +static inline uint32_t dwc2_get_outep_intstatus(uint8_t epnum) { uint32_t tmpreg; tmpreg = USB_OTG_OUTEP((uint32_t)epnum)->DOEPINT; - USB_OTG_OUTEP((uint32_t)epnum)->DOEPINT = tmpreg; - tmpreg = tmpreg & USB_OTG_DEV->DOEPMSK; + tmpreg &= USB_OTG_DEV->DOEPMSK; return tmpreg; } @@ -474,21 +444,26 @@ static inline uint32_t dwc2_get_outep_intstatus(uint8_t busid, uint8_t epnum) * This parameter can be a value from 0 to 15 * @retval Device IN EP Interrupt register */ -static inline uint32_t dwc2_get_inep_intstatus(uint8_t busid, uint8_t epnum) +static inline uint32_t dwc2_get_inep_intstatus(uint8_t epnum) { uint32_t tmpreg, msk, emp; msk = USB_OTG_DEV->DIEPMSK; emp = USB_OTG_DEV->DIEPEMPMSK; - msk |= ((emp >> (epnum & 0x0F)) & 0x1U) << 7; - - tmpreg = USB_OTG_INEP((uint32_t)epnum)->DIEPINT; - USB_OTG_INEP((uint32_t)epnum)->DIEPINT = tmpreg; - tmpreg = tmpreg & msk; + msk |= ((emp >> (epnum & 0x07)) & 0x1U) << 7; + tmpreg = USB_OTG_INEP((uint32_t)epnum)->DIEPINT & msk; return tmpreg; } +__WEAK void usb_dc_low_level_init(void) +{ +} + +__WEAK void usb_dc_low_level_deinit(void) +{ +} + int usb_dc_init(uint8_t busid) { int ret; @@ -498,9 +473,9 @@ int usb_dc_init(uint8_t busid) uint8_t endpoints; uint32_t fifo_num; - memset(&g_dwc2_udc[busid], 0, sizeof(struct dwc2_udc)); + memset(&g_dwc2_udc, 0, sizeof(struct dwc2_udc)); - usb_dc_low_level_init(busid); + usb_dc_low_level_init(); /* Full-Speed PHY Interface Type (FSPhyType) @@ -551,10 +526,14 @@ int usb_dc_init(uint8_t busid) /* This is vendor register */ USB_OTG_GLB->GCCFG = usbd_get_dwc2_gccfg_conf(USBD_BASE); - ret = dwc2_core_init(busid); + ret = dwc2_core_init(); /* Force Device Mode*/ - dwc2_set_mode(busid, USB_OTG_MODE_DEVICE); + dwc2_set_mode(USB_OTG_MODE_DEVICE); + + /* B-peripheral session valid override enable */ + // USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; + // USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; for (uint8_t i = 0U; i < 15U; i++) { USB_OTG_GLB->DIEPTXF[i] = 0U; @@ -588,7 +567,7 @@ int usb_dc_init(uint8_t busid) /* Enable interrupts matching to the Device mode ONLY */ USB_OTG_GLB->GINTMSK = USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT | - USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM; + USB_OTG_GINTMSK_IISOIXFRM | USB_OTG_GINTMSK_PXFRM_IISOOXFRM; #ifdef CONFIG_USB_DWC2_DMA_ENABLE if (((USB_OTG_GLB->GHWCFG2 & (0x3U << 3)) >> 3) != 2) { @@ -598,7 +577,6 @@ int usb_dc_init(uint8_t busid) } USB_OTG_DEV->DCFG &= ~USB_OTG_DCFG_DESCDMA; - USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_HBSTLEN; USB_OTG_GLB->GAHBCFG |= (USB_OTG_GAHBCFG_DMAEN | USB_OTG_GAHBCFG_HBSTLEN_4); #else USB_OTG_GLB->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; @@ -612,10 +590,10 @@ int usb_dc_init(uint8_t busid) USB_OTG_GLB->GRXFSIZ = (CONFIG_USB_DWC2_RXALL_FIFO_SIZE); - dwc2_set_txfifo(busid, 0, CONFIG_USB_DWC2_TX0_FIFO_SIZE); - dwc2_set_txfifo(busid, 1, CONFIG_USB_DWC2_TX1_FIFO_SIZE); - dwc2_set_txfifo(busid, 2, CONFIG_USB_DWC2_TX2_FIFO_SIZE); - dwc2_set_txfifo(busid, 3, CONFIG_USB_DWC2_TX3_FIFO_SIZE); + dwc2_set_txfifo(0, CONFIG_USB_DWC2_TX0_FIFO_SIZE); + dwc2_set_txfifo(1, CONFIG_USB_DWC2_TX1_FIFO_SIZE); + dwc2_set_txfifo(2, CONFIG_USB_DWC2_TX2_FIFO_SIZE); + dwc2_set_txfifo(3, CONFIG_USB_DWC2_TX3_FIFO_SIZE); fifo_num = CONFIG_USB_DWC2_RXALL_FIFO_SIZE; fifo_num += CONFIG_USB_DWC2_TX0_FIFO_SIZE; @@ -623,23 +601,23 @@ int usb_dc_init(uint8_t busid) fifo_num += CONFIG_USB_DWC2_TX2_FIFO_SIZE; fifo_num += CONFIG_USB_DWC2_TX3_FIFO_SIZE; #if CONFIG_USBDEV_EP_NUM > 4 - dwc2_set_txfifo(busid, 4, CONFIG_USB_DWC2_TX4_FIFO_SIZE); + dwc2_set_txfifo(4, CONFIG_USB_DWC2_TX4_FIFO_SIZE); fifo_num += CONFIG_USB_DWC2_TX4_FIFO_SIZE; #endif #if CONFIG_USBDEV_EP_NUM > 5 - dwc2_set_txfifo(busid, 5, CONFIG_USB_DWC2_TX5_FIFO_SIZE); + dwc2_set_txfifo(5, CONFIG_USB_DWC2_TX5_FIFO_SIZE); fifo_num += CONFIG_USB_DWC2_TX5_FIFO_SIZE; #endif #if CONFIG_USBDEV_EP_NUM > 6 - dwc2_set_txfifo(busid, 6, CONFIG_USB_DWC2_TX6_FIFO_SIZE); + dwc2_set_txfifo(6, CONFIG_USB_DWC2_TX6_FIFO_SIZE); fifo_num += CONFIG_USB_DWC2_TX6_FIFO_SIZE; #endif #if CONFIG_USBDEV_EP_NUM > 7 - dwc2_set_txfifo(busid, 7, CONFIG_USB_DWC2_TX7_FIFO_SIZE); + dwc2_set_txfifo(7, CONFIG_USB_DWC2_TX7_FIFO_SIZE); fifo_num += CONFIG_USB_DWC2_TX7_FIFO_SIZE; #endif #if CONFIG_USBDEV_EP_NUM > 8 - dwc2_set_txfifo(busid, 8, CONFIG_USB_DWC2_TX8_FIFO_SIZE); + dwc2_set_txfifo(8, CONFIG_USB_DWC2_TX8_FIFO_SIZE); fifo_num += CONFIG_USB_DWC2_TX8_FIFO_SIZE; #endif @@ -656,8 +634,8 @@ int usb_dc_init(uint8_t busid) } } - ret = dwc2_flush_txfifo(busid, 0x10U); - ret = dwc2_flush_rxfifo(busid); + ret = dwc2_flush_txfifo(0x10U); + ret = dwc2_flush_rxfifo(); USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_GINT; USB_OTG_DEV->DCTL &= ~USB_OTG_DCTL_SDIS; @@ -682,10 +660,10 @@ int usb_dc_deinit(uint8_t busid) USB_OTG_DEV->DAINTMSK = 0U; /* Flush the FIFO */ - dwc2_flush_txfifo(busid, 0x10U); - dwc2_flush_rxfifo(busid); + dwc2_flush_txfifo(0x10U); + dwc2_flush_rxfifo(); - usb_dc_low_level_deinit(busid); + usb_dc_low_level_deinit(); return 0; } @@ -696,17 +674,6 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } -int usbd_set_remote_wakeup(uint8_t busid) -{ - if (!(USB_OTG_DEV->DSTS & USB_OTG_DSTS_SUSPSTS)) { - return -1; - } - USB_OTG_DEV->DCTL |= USB_OTG_DCTL_RWUSIG; - usbd_dwc2_delay_ms(10); - USB_OTG_DEV->DCTL &= ~USB_OTG_DCTL_RWUSIG; - return 0; -} - uint8_t usbd_get_port_speed(uint8_t busid) { uint8_t speed; @@ -734,8 +701,8 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) } if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) { - g_dwc2_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); - g_dwc2_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); + g_dwc2_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); + g_dwc2_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & (uint32_t)(1UL << (16 + ep_idx)); @@ -757,8 +724,8 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) return -2; } - g_dwc2_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); - g_dwc2_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); + g_dwc2_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); + g_dwc2_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); USB_OTG_DEV->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << ep_idx); @@ -768,7 +735,7 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) USB_OTG_DIEPCTL_SD0PID_SEVNFRM | USB_OTG_DIEPCTL_USBAEP; } - dwc2_flush_txfifo(busid, ep_idx); + dwc2_flush_txfifo(ep_idx); } return 0; } @@ -792,7 +759,7 @@ int usbd_ep_close(uint8_t busid, const uint8_t ep) } while ((USB_OTG_OUTEP(ep_idx)->DOEPINT & USB_OTG_DOEPINT_EPDISD) != USB_OTG_DOEPINT_EPDISD); /* Clear and unmask endpoint disabled interrupt */ - USB_OTG_OUTEP(ep_idx)->DOEPINT = USB_OTG_DOEPINT_EPDISD; + USB_OTG_OUTEP(ep_idx)->DOEPINT |= USB_OTG_DOEPINT_EPDISD; } USB_OTG_DEV->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep_idx & 0x07)) << 16)); @@ -812,7 +779,7 @@ int usbd_ep_close(uint8_t busid, const uint8_t ep) } while ((USB_OTG_INEP(ep_idx)->DIEPINT & USB_OTG_DIEPINT_EPDISD) != USB_OTG_DIEPINT_EPDISD); /* Clear and unmask endpoint disabled interrupt */ - USB_OTG_INEP(ep_idx)->DIEPINT = USB_OTG_DIEPINT_EPDISD; + USB_OTG_INEP(ep_idx)->DIEPINT |= USB_OTG_DIEPINT_EPDISD; } USB_OTG_DEV->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep_idx & 0x07))); @@ -839,7 +806,7 @@ int usbd_ep_set_stall(uint8_t busid, const uint8_t ep) } #ifdef CONFIG_USB_DWC2_DMA_ENABLE if (ep_idx == 0) { - dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup); + dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup); } #endif return 0; @@ -851,14 +818,14 @@ int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep) if (USB_EP_DIR_IS_OUT(ep)) { USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; - if ((g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) || - (g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) { + if ((g_dwc2_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) || + (g_dwc2_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) { USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */ } } else { USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; - if ((g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) || - (g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) { + if ((g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_INTERRUPT) || + (g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_BULK)) { USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */ } } @@ -867,20 +834,8 @@ int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep) int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled) { - uint8_t ep_idx = USB_EP_GET_IDX(ep); - if (USB_EP_DIR_IS_OUT(ep)) { - if (USB_OTG_OUTEP(ep_idx)->DOEPCTL & USB_OTG_DOEPCTL_STALL) { - *stalled = 1; - } else { - *stalled = 0; - } } else { - if (USB_OTG_INEP(ep_idx)->DIEPCTL & USB_OTG_DIEPCTL_STALL) { - *stalled = 1; - } else { - *stalled = 0; - } } return 0; } @@ -905,9 +860,9 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui return -4; } - g_dwc2_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data; - g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = data_len; - g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len = 0; + g_dwc2_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data; + g_dwc2_udc.in_ep[ep_idx].xfer_len = data_len; + g_dwc2_udc.in_ep[ep_idx].actual_xfer_len = 0; USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); @@ -919,20 +874,20 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui } if (ep_idx == 0) { - if (data_len > g_dwc2_udc[busid].in_ep[ep_idx].ep_mps) { - data_len = g_dwc2_udc[busid].in_ep[ep_idx].ep_mps; + if (data_len > g_dwc2_udc.in_ep[ep_idx].ep_mps) { + data_len = g_dwc2_udc.in_ep[ep_idx].ep_mps; } - g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = data_len; + g_dwc2_udc.in_ep[ep_idx].xfer_len = data_len; USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19)); USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & data_len); } else { - pktcnt = (uint16_t)((data_len + g_dwc2_udc[busid].in_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc[busid].in_ep[ep_idx].ep_mps); + pktcnt = (uint16_t)((data_len + g_dwc2_udc.in_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc.in_ep[ep_idx].ep_mps); USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (pktcnt << 19)); USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & data_len); } - if (g_dwc2_udc[busid].in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) { + if (g_dwc2_udc.in_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) { if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) { USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_SD0PID_SEVNFRM; USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM; @@ -978,28 +933,28 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t return -4; } - g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data; - g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = data_len; - g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = 0; + g_dwc2_udc.out_ep[ep_idx].xfer_buf = (uint8_t *)data; + g_dwc2_udc.out_ep[ep_idx].xfer_len = data_len; + g_dwc2_udc.out_ep[ep_idx].actual_xfer_len = 0; USB_OTG_OUTEP(ep_idx)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT); USB_OTG_OUTEP(ep_idx)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ); if (data_len == 0) { USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)); - USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & g_dwc2_udc[busid].out_ep[ep_idx].ep_mps); + USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & g_dwc2_udc.out_ep[ep_idx].ep_mps); USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); return 0; } if (ep_idx == 0) { - if (data_len > g_dwc2_udc[busid].out_ep[ep_idx].ep_mps) { - data_len = g_dwc2_udc[busid].out_ep[ep_idx].ep_mps; + if (data_len > g_dwc2_udc.out_ep[ep_idx].ep_mps) { + data_len = g_dwc2_udc.out_ep[ep_idx].ep_mps; } - g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = data_len; + g_dwc2_udc.out_ep[ep_idx].xfer_len = data_len; USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19)); USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & data_len); } else { - pktcnt = (uint16_t)((data_len + g_dwc2_udc[busid].out_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc[busid].out_ep[ep_idx].ep_mps); + pktcnt = (uint16_t)((data_len + g_dwc2_udc.out_ep[ep_idx].ep_mps - 1U) / g_dwc2_udc.out_ep[ep_idx].ep_mps); USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19)); USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & data_len); @@ -1008,7 +963,7 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t #ifdef CONFIG_USB_DWC2_DMA_ENABLE USB_OTG_OUTEP(ep_idx)->DOEPDMA = (uint32_t)data; #endif - if (g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) { + if (g_dwc2_udc.out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) { if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) { USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_SD0PID_SEVNFRM; USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM; @@ -1024,7 +979,7 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t void USBD_IRQHandler(uint8_t busid) { uint32_t gint_status, temp, ep_idx, ep_intr, epint, read_count, daintmask; - gint_status = dwc2_get_glb_intstatus(busid); + gint_status = dwc2_get_glb_intstatus(); if ((USB_OTG_GLB->GINTSTS & 0x1U) == USB_OTG_MODE_DEVICE) { /* Avoid spurious interrupt */ @@ -1043,12 +998,12 @@ void USBD_IRQHandler(uint8_t busid) if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_DATA_UPDT) { read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4; if (read_count != 0) { - dwc2_ep_read(busid, g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, read_count); - g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf += read_count; + dwc2_ep_read(g_dwc2_udc.out_ep[ep_idx].xfer_buf, read_count); + g_dwc2_udc.out_ep[ep_idx].xfer_buf += read_count; } } else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_SETUP_UPDT) { read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4; - dwc2_ep_read(busid, (uint8_t *)&g_dwc2_udc[busid].setup, read_count); + dwc2_ep_read((uint8_t *)&g_dwc2_udc.setup, read_count); } else { /* ... */ } @@ -1057,30 +1012,32 @@ void USBD_IRQHandler(uint8_t busid) #endif if (gint_status & USB_OTG_GINTSTS_OEPINT) { ep_idx = 0; - ep_intr = dwc2_get_outeps_intstatus(busid); + ep_intr = dwc2_get_outeps_intstatus(); while (ep_intr != 0U) { if ((ep_intr & 0x1U) != 0U) { - epint = dwc2_get_outep_intstatus(busid, ep_idx); + epint = dwc2_get_outep_intstatus(ep_idx); + uint32_t DoepintReg = USB_OTG_OUTEP(ep_idx)->DOEPINT; + USB_OTG_OUTEP(ep_idx)->DOEPINT = DoepintReg; if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) { if (ep_idx == 0) { - if (g_dwc2_udc[busid].out_ep[ep_idx].xfer_len == 0) { + if (g_dwc2_udc.out_ep[ep_idx].xfer_len == 0) { /* Out status, start reading setup */ - dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup); + dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup); } else { - g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ); - g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = 0; - usbd_event_ep_out_complete_handler(busid, 0x00, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len); + g_dwc2_udc.out_ep[ep_idx].actual_xfer_len = g_dwc2_udc.out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ); + g_dwc2_udc.out_ep[ep_idx].xfer_len = 0; + usbd_event_ep_out_complete_handler(0, 0x00, g_dwc2_udc.out_ep[ep_idx].actual_xfer_len); } } else { - g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ); - g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = 0; - usbd_event_ep_out_complete_handler(busid, ep_idx, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len); + g_dwc2_udc.out_ep[ep_idx].actual_xfer_len = g_dwc2_udc.out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ); + g_dwc2_udc.out_ep[ep_idx].xfer_len = 0; + usbd_event_ep_out_complete_handler(0, ep_idx, g_dwc2_udc.out_ep[ep_idx].actual_xfer_len); } } if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) { - usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&g_dwc2_udc[busid].setup); + usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&g_dwc2_udc.setup); } } ep_intr >>= 1U; @@ -1089,32 +1046,34 @@ void USBD_IRQHandler(uint8_t busid) } if (gint_status & USB_OTG_GINTSTS_IEPINT) { ep_idx = 0U; - ep_intr = dwc2_get_ineps_intstatus(busid); + ep_intr = dwc2_get_ineps_intstatus(); while (ep_intr != 0U) { if ((ep_intr & 0x1U) != 0U) { - epint = dwc2_get_inep_intstatus(busid, ep_idx); + epint = dwc2_get_inep_intstatus(ep_idx); + uint32_t DiepintReg = USB_OTG_INEP(ep_idx)->DIEPINT; + USB_OTG_INEP(ep_idx)->DIEPINT = DiepintReg; if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) { if (ep_idx == 0) { - g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].in_ep[ep_idx].xfer_len - ((USB_OTG_INEP(ep_idx)->DIEPTSIZ) & USB_OTG_DIEPTSIZ_XFRSIZ); - g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = 0; - usbd_event_ep_in_complete_handler(busid, 0x80, g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len); + g_dwc2_udc.in_ep[ep_idx].actual_xfer_len = g_dwc2_udc.in_ep[ep_idx].xfer_len - ((USB_OTG_INEP(ep_idx)->DIEPTSIZ) & USB_OTG_DIEPTSIZ_XFRSIZ); + g_dwc2_udc.in_ep[ep_idx].xfer_len = 0; + usbd_event_ep_in_complete_handler(0, 0x80, g_dwc2_udc.in_ep[ep_idx].actual_xfer_len); - if (g_dwc2_udc[busid].setup.wLength && ((g_dwc2_udc[busid].setup.bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT)) { + if (g_dwc2_udc.setup.wLength && ((g_dwc2_udc.setup.bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT)) { /* In status, start reading setup */ - dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup); - } else if (g_dwc2_udc[busid].setup.wLength == 0) { + dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup); + } else if (g_dwc2_udc.setup.wLength == 0) { /* In status, start reading setup */ - dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup); + dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup); } } else { - g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].in_ep[ep_idx].xfer_len - ((USB_OTG_INEP(ep_idx)->DIEPTSIZ) & USB_OTG_DIEPTSIZ_XFRSIZ); - g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = 0; - usbd_event_ep_in_complete_handler(busid, ep_idx | 0x80, g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len); + g_dwc2_udc.in_ep[ep_idx].actual_xfer_len = g_dwc2_udc.in_ep[ep_idx].xfer_len - ((USB_OTG_INEP(ep_idx)->DIEPTSIZ) & USB_OTG_DIEPTSIZ_XFRSIZ); + g_dwc2_udc.in_ep[ep_idx].xfer_len = 0; + usbd_event_ep_in_complete_handler(0, ep_idx | 0x80, g_dwc2_udc.in_ep[ep_idx].actual_xfer_len); } } if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) { - dwc2_tx_fifo_empty_procecss(busid, ep_idx); + dwc2_tx_fifo_empty_procecss(ep_idx); } } ep_intr >>= 1U; @@ -1122,11 +1081,11 @@ void USBD_IRQHandler(uint8_t busid) } } if (gint_status & USB_OTG_GINTSTS_USBRST) { - USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_USBRST; + USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_USBRST; USB_OTG_DEV->DCTL &= ~USB_OTG_DCTL_RWUSIG; - dwc2_flush_txfifo(busid, 0x10U); - dwc2_flush_rxfifo(busid); + dwc2_flush_txfifo(0x10U); + dwc2_flush_rxfifo(); for (uint8_t i = 0U; i < CONFIG_USBDEV_EP_NUM; i++) { if (i == 0U) { @@ -1157,35 +1116,69 @@ void USBD_IRQHandler(uint8_t busid) USB_OTG_DEV->DIEPMSK = USB_OTG_DIEPMSK_XFRCM; - memset(&g_dwc2_udc[busid], 0, sizeof(struct dwc2_udc)); - usbd_event_reset_handler(busid); + memset(&g_dwc2_udc, 0, sizeof(struct dwc2_udc)); + usbd_event_reset_handler(0); /* Start reading setup */ - dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup); + dwc2_ep0_start_read_setup((uint8_t *)&g_dwc2_udc.setup); } if (gint_status & USB_OTG_GINTSTS_ENUMDNE) { - USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; - dwc2_set_turnaroundtime(busid, SystemCoreClock, dwc2_get_devspeed(busid)); + USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_ENUMDNE; + dwc2_set_turnaroundtime(SystemCoreClock, dwc2_get_devspeed()); USB_OTG_DEV->DCTL |= USB_OTG_DCTL_CGINAK; } if (gint_status & USB_OTG_GINTSTS_PXFR_INCOMPISOOUT) { - USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_PXFR_INCOMPISOOUT; + daintmask = USB_OTG_DEV->DAINTMSK; + daintmask >>= 16; + + for (ep_idx = 1; ep_idx < CONFIG_USBDEV_EP_NUM; ep_idx++) { + if ((BIT(ep_idx) & ~daintmask) || (g_dwc2_udc.out_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS)) + continue; + if (!(USB_OTG_OUTEP(ep_idx)->DOEPCTL & USB_OTG_DOEPCTL_USBAEP)) + continue; + + if ((USB_OTG_DEV->DSTS & (1U << 8)) != 0U) { + USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; + USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_SODDFRM; + } else { + USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_SD0PID_SEVNFRM; + USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM; + } + } + + USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_PXFR_INCOMPISOOUT; } if (gint_status & USB_OTG_GINTSTS_IISOIXFR) { - USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_IISOIXFR; + daintmask = USB_OTG_DEV->DAINTMSK; + daintmask >>= 16; + + for (ep_idx = 1; ep_idx < CONFIG_USBDEV_EP_NUM; ep_idx++) { + if (((BIT(ep_idx) & ~daintmask)) || (g_dwc2_udc.in_ep[ep_idx].ep_type != USB_ENDPOINT_TYPE_ISOCHRONOUS)) + continue; + + if (!(USB_OTG_INEP(ep_idx)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP)) + continue; + + if ((USB_OTG_DEV->DSTS & (1U << 8)) != 0U) { + USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; + USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_SODDFRM; + } else { + USB_OTG_INEP(ep_idx)->DIEPCTL &= ~USB_OTG_DIEPCTL_SD0PID_SEVNFRM; + USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM; + } + } + USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_IISOIXFR; } if (gint_status & USB_OTG_GINTSTS_SOF) { - USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_SOF; + USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_SOF; } if (gint_status & USB_OTG_GINTSTS_USBSUSP) { - USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_USBSUSP; - usbd_event_suspend_handler(busid); + USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_USBSUSP; } if (gint_status & USB_OTG_GINTSTS_WKUINT) { - USB_OTG_GLB->GINTSTS = USB_OTG_GINTSTS_WKUINT; - usbd_event_resume_handler(busid); + USB_OTG_GLB->GINTSTS |= USB_OTG_GINTSTS_WKUINT; } if (gint_status & USB_OTG_GINTSTS_OTGINT) { temp = USB_OTG_GLB->GOTGINT; diff --git a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_reg.h b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_reg.h index 5f9b5f9..c3bd75d 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_reg.h +++ b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_reg.h @@ -1716,9 +1716,6 @@ typedef struct #define USB_UNMASK_HALT_HC_INT(chnum) (USB_OTG_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM) #define CLEAR_HC_INT(chnum, __INTERRUPT__) (USB_OTG_HC(chnum)->HCINT = (__INTERRUPT__)) -void usb_dc_low_level_init(uint8_t busid); -void usb_dc_low_level_deinit(uint8_t busid); uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base); uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base); -void usbd_dwc2_delay_ms(uint8_t ms); #endif diff --git a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c index 8d45f65..d9c2626 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_at.c @@ -7,20 +7,16 @@ #include "stdint.h" #include "usb_dwc2_reg.h" -extern unsigned int system_core_clock; - -uint32_t SystemCoreClock; /* you can find this config in function: usb_global_init, file:at32fxxx_usb.c, for example: * * usbx->gccfg_bit.pwrdown = TRUE; * usbx->gccfg_bit.avalidsesen = TRUE; * usbx->gccfg_bit.bvalidsesen = TRUE; - * + * */ uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base) { - SystemCoreClock = system_core_clock; #ifdef CONFIG_USB_HS return ((1 << 16) | (1 << 21)); #else @@ -39,7 +35,6 @@ uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base) uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) { - SystemCoreClock = system_core_clock; #ifdef CONFIG_USB_HS return ((1 << 16) | (1 << 21)); #else @@ -54,9 +49,4 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) return ((1 << 16) | (1 << 21)); #endif #endif -} - -void usbd_dwc2_delay_ms(uint8_t ms) -{ - /* implement later */ } \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c index 76abb19..8c63234 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_esp.c @@ -8,19 +8,13 @@ #include "esp_intr_alloc.h" #include "esp_private/usb_phy.h" #include "soc/periph_defs.h" -#include "freertos/FreeRTOS.h" #include "usbd_core.h" #include "usbh_core.h" #ifdef CONFIG_IDF_TARGET_ESP32S2 #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ -#define DEFAULT_USB_INTR_SOURCE ETS_USB_INTR_SOURCE #elif CONFIG_IDF_TARGET_ESP32S3 #define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ -#define DEFAULT_USB_INTR_SOURCE ETS_USB_INTR_SOURCE -#elif CONFIG_IDF_TARGET_ESP32P4 -#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ -#define DEFAULT_USB_INTR_SOURCE ETS_USB_OTG_INTR_SOURCE #else #define DEFAULT_CPU_FREQ_MHZ 160 #endif @@ -35,7 +29,7 @@ static void usb_dc_interrupt_cb(void *arg_pv) USBD_IRQHandler(0); } -void usb_dc_low_level_init(uint8_t busid) +void usb_dc_low_level_init(void) { usb_phy_config_t phy_config = { .controller = USB_PHY_CTRL_OTG, @@ -50,15 +44,15 @@ void usb_dc_low_level_init(uint8_t busid) } // TODO: Check when to enable interrupt - ret = esp_intr_alloc(DEFAULT_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, usb_dc_interrupt_cb, 0, &s_interrupt_handle); + ret = esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LEVEL2, usb_dc_interrupt_cb, 0, &s_interrupt_handle); if (ret != ESP_OK) { USB_LOG_ERR("USB Interrupt Init Failed!\r\n"); return; } - USB_LOG_INFO("cherryusb, version: "CHERRYUSB_VERSION_STR"\r\n"); + USB_LOG_INFO("cherryusb, version: 0x%06x\r\n", CHERRYUSB_VERSION); } -void usb_dc_low_level_deinit(uint8_t busid) +void usb_dc_low_level_deinit(void) { if (s_interrupt_handle) { esp_intr_free(s_interrupt_handle); @@ -100,12 +94,12 @@ void usb_hc_low_level_init(struct usbh_bus *bus) } // TODO: Check when to enable interrupt - ret = esp_intr_alloc(DEFAULT_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, usb_hc_interrupt_cb, 0, &s_interrupt_handle); + ret = esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LEVEL2, usb_hc_interrupt_cb, 0, &s_interrupt_handle); if (ret != ESP_OK) { USB_LOG_ERR("USB Interrupt Init Failed!\r\n"); return; } - USB_LOG_INFO("cherryusb, version: "CHERRYUSB_VERSION_STR"\r\n"); + USB_LOG_INFO("cherryusb, version: 0x%06x\r\n", CHERRYUSB_VERSION); } void usb_hc_low_level_deinit(struct usbh_bus *bus) @@ -124,8 +118,3 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) { return 0; } - -void usbd_dwc2_delay_ms(uint8_t ms) -{ - vTaskDelay(pdMS_TO_TICKS(ms)); -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_gd.c b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_gd.c index f3fa4d9..bdc0d68 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_gd.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_gd.c @@ -7,14 +7,10 @@ #include "stdint.h" #include "usb_dwc2_reg.h" -#if CONFIG_USBDEV_EP_NUM != 4 && CONFIG_USBDEV_EP_NUM != 6 -#error "gd32 only has 4 endpoints for pa11/pa12 and 6 endpoints for pb14/pb15" -#endif - /* you can find this config in function:usb_core_init, file:drv_usb_core.c, for example: * * usb_regs->gr->GCCFG |= GCCFG_PWRON | GCCFG_VBUSACEN | GCCFG_VBUSBCEN; - * + * */ uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base) @@ -33,9 +29,4 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) #else return ((1 << 16) | (1 << 18) | (1 << 19) | (1 << 21)); #endif -} - -void usbd_dwc2_delay_ms(uint8_t ms) -{ - /* implement later */ } \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_hc.c b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_hc.c index 431b5db..9bebe6d 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_hc.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_hc.c @@ -24,8 +24,3 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL; return 0; } - -void usbd_dwc2_delay_ms(uint8_t ms) -{ - /* implement later */ -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_kendryte.c b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_kendryte.c deleted file mode 100644 index de10352..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_kendryte.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include "usbd_core.h" -#include "usbh_core.h" - -#define DEFAULT_USB_HCLK_FREQ_MHZ 200 - -uint32_t SystemCoreClock = (DEFAULT_USB_HCLK_FREQ_MHZ * 1000 * 1000); -uintptr_t g_usb_otg0_base = (uintptr_t)0x91500000UL; -uintptr_t g_usb_otg1_base = (uintptr_t)0x91540000UL; - -static void sysctl_reset_hw_done(volatile uint32_t *reset_reg, uint8_t reset_bit, uint8_t done_bit) -{ - *reset_reg |= (1 << done_bit); /* clear done bit */ - rt_thread_mdelay(1); - - *reset_reg |= (1 << reset_bit); /* set reset bit */ - rt_thread_mdelay(1); - /* check done bit */ - while (*reset_reg & (1 << done_bit) == 0) - ; -} - -#define USB_IDPULLUP0 (1 << 4) -#define USB_DMPULLDOWN0 (1 << 8) -#define USB_DPPULLDOWN0 (1 << 9) - -#ifdef PKG_CHERRYUSB_HOST -static void usb_hc_interrupt_cb(int irq, void *arg_pv) -{ - extern void USBH_IRQHandler(uint8_t busid); - USBH_IRQHandler((uint8_t)(uintptr_t)arg_pv); -} - -void usb_hc_low_level_init(struct usbh_bus *bus) -{ - uint32_t *hs_reg; - uint32_t usb_ctl3; - - if (bus->hcd.hcd_id == 0) { - sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 0, 28); - - hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x7C), 0x1000); - usb_ctl3 = *hs_reg | USB_IDPULLUP0; - - *hs_reg = usb_ctl3 | (USB_DMPULLDOWN0 | USB_DPPULLDOWN0); - - rt_iounmap(hs_reg); - - rt_hw_interrupt_install(173, usb_hc_interrupt_cb, NULL, "usbh0"); - rt_hw_interrupt_umask(173); - - } else { - sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 1, 29); - - hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x9C), 0x1000); - usb_ctl3 = *hs_reg | USB_IDPULLUP0; - - *hs_reg = usb_ctl3 | (USB_DMPULLDOWN0 | USB_DPPULLDOWN0); - - rt_iounmap(hs_reg); - - rt_hw_interrupt_install(174, usb_hc_interrupt_cb, 1, "usbh1"); - rt_hw_interrupt_umask(174); - } -} - -void usb_hc_low_level_deinit(struct usbh_bus *bus) -{ - if (bus->hcd.hcd_id == 0) { - rt_hw_interrupt_mask(173); - } else { - rt_hw_interrupt_mask(174); - } -} - -uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) -{ - return 0; -} -#endif - -#ifdef PKG_CHERRYUSB_DEVICE -static void usb_dc_interrupt_cb(int irq, void *arg_pv) -{ - extern void USBD_IRQHandler(uint8_t busid); - USBD_IRQHandler(0); -} - -#ifdef CHERRYUSB_DEVICE_USING_USB0 -void usb_dc_low_level_init(uint8_t busid) -{ - sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 0, 28); - uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x7C), 0x1000); - *hs_reg = 0x37; - rt_iounmap(hs_reg); - - rt_hw_interrupt_install(173, usb_dc_interrupt_cb, NULL, "usbd"); - rt_hw_interrupt_umask(173); -} - -void usb_dc_low_level_deinit(uint8_t busid) -{ - rt_hw_interrupt_mask(173); -} -#else -void usb_dc_low_level_init(uint8_t busid) -{ - sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 1, 29); - uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x9C), 0x1000); - *hs_reg = 0x37; - rt_iounmap(hs_reg); - - rt_hw_interrupt_install(174, usb_dc_interrupt_cb, NULL, "usbd"); - rt_hw_interrupt_umask(174); -} - -void usb_dc_low_level_deinit(uint8_t busid) -{ - rt_hw_interrupt_mask(174); -} -#endif -uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base) -{ - return 0; -} - -void usbd_dwc2_delay_ms(uint8_t ms) -{ - /* implement later */ -} -#endif \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c index 4dff31f..94293d2 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c @@ -13,11 +13,9 @@ * USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; * USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN; * USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN; - * + * */ -extern void HAL_Delay(uint32_t Delay); - #if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx) /** * @brief USB_HS_PHY_Registers @@ -166,8 +164,6 @@ uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base) USB_OTG_GLB->GCCFG = (1 << 23); usb_hsphy_init(25000000U); return (1 << 23); /* Enable USB HS PHY USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;*/ -#elif __has_include("stm32h7rsxx.h") - return (1 << 21); #else return 0; #endif @@ -194,8 +190,6 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) USB_OTG_GLB->GCCFG = (1 << 23); usb_hsphy_init(25000000U); return (1 << 23); /* Enable USB HS PHY USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;*/ -#elif __has_include("stm32h7rsxx.h") - return (1 << 21); #else return 0; #endif @@ -207,8 +201,3 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) #endif #endif } - -void usbd_dwc2_delay_ms(uint8_t ms) -{ - HAL_Delay(ms); -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c index 09f5517..ddcbaf2 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_hc_dwc2.c @@ -26,7 +26,7 @@ * 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario */ #ifndef CONFIG_USB_DWC2_RX_FIFO_SIZE -#define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE)) +#define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE) / 4) #endif #define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(bus->hcd.reg_base)) @@ -114,22 +114,12 @@ static inline void dwc2_set_mode(struct usbh_bus *bus, uint8_t mode) } else if (mode == USB_OTG_MODE_DEVICE) { USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; } - - usb_osal_msleep(50); } static inline int dwc2_flush_rxfifo(struct usbh_bus *bus) { - volatile uint32_t count = 0U; + volatile uint32_t count = 0; - /* Wait for AHB master IDLE state. */ - do { - if (++count > 200000U) { - return -1; - } - } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); - - count = 0; USB_OTG_GLB->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH; do { @@ -145,14 +135,6 @@ static inline int dwc2_flush_txfifo(struct usbh_bus *bus, uint32_t num) { volatile uint32_t count = 0U; - /* Wait for AHB master IDLE state. */ - do { - if (++count > 200000U) { - return -1; - } - } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); - - count = 0; USB_OTG_GLB->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6)); do { @@ -215,12 +197,6 @@ static inline void dwc2_chan_char_init(struct usbh_bus *bus, uint8_t ch_num, uin regval |= USB_OTG_HCCHAR_EPDIR; } - if ((usbh_get_port_speed(bus, 0) == USB_SPEED_HIGH) && (speed != USB_SPEED_HIGH)) { - USB_LOG_ERR("Do not support LS/FS device on HS hub\r\n"); - while (1) { - } - } - /* LS device plugged to HUB */ if ((speed == USB_SPEED_LOW) && (usbh_get_port_speed(bus, 0) != USB_SPEED_LOW)) { regval |= USB_OTG_HCCHAR_LSDEV; @@ -448,12 +424,10 @@ static void dwc2_iso_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_u __WEAK void usb_hc_low_level_init(struct usbh_bus *bus) { - (void)bus; } __WEAK void usb_hc_low_level_deinit(struct usbh_bus *bus) { - (void)bus; } int usb_hc_init(struct usbh_bus *bus) @@ -504,6 +478,9 @@ int usb_hc_init(struct usbh_bus *bus) /* Restart the Phy Clock */ USB_OTG_PCGCCTL = 0U; + dwc2_drivebus(bus, 1); + usb_osal_msleep(200); + /* Set default Max speed support */ USB_OTG_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS); @@ -527,7 +504,6 @@ int usb_hc_init(struct usbh_bus *bus) ret = dwc2_flush_txfifo(bus, 0x10U); ret = dwc2_flush_rxfifo(bus); - USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_HBSTLEN; USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_4; USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN; @@ -535,9 +511,6 @@ int usb_hc_init(struct usbh_bus *bus) USB_OTG_GLB->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM | USB_OTG_GINTSTS_DISCINT); - dwc2_drivebus(bus, 1); - usb_osal_msleep(200); - USB_OTG_GLB->GAHBCFG |= USB_OTG_GAHBCFG_GINT; return ret; @@ -654,7 +627,6 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u case HUB_PORT_FEATURE_C_SUSPEND: break; case HUB_PORT_FEATURE_POWER: - dwc2_drivebus(bus, 0); break; case HUB_PORT_FEATURE_C_CONNECTION: g_dwc2_hcd[bus->hcd.hcd_id].port_csc = 0; @@ -680,7 +652,7 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u case HUB_PORT_FEATURE_SUSPEND: break; case HUB_PORT_FEATURE_POWER: - dwc2_drivebus(bus, 1); + USB_OTG_HPRT &= ~USB_OTG_HPRT_PPWR; break; case HUB_PORT_FEATURE_RESET: usbh_reset_port(bus, port); @@ -776,8 +748,8 @@ int usbh_submit_urb(struct usbh_urb *urb) } } else { /* Check if intr and iso pipe tx fifo is overflow */ - if (((USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_ISOCHRONOUS) || - (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT)) && + if (((USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) == USB_ENDPOINT_TYPE_ISOCHRONOUS) || + (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) == USB_ENDPOINT_TYPE_INTERRUPT)) && USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (CONFIG_USB_DWC2_PTX_FIFO_SIZE * 4)) { return -USB_ERR_RANGE; } else { @@ -902,7 +874,6 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num) //printf("s1:%08x\r\n", chan_intstatus); if (chan_intstatus & USB_OTG_HCINT_CHH) { - USB_OTG_HC(ch_num)->HCINT = chan_intstatus; if (chan_intstatus & USB_OTG_HCINT_XFRC) { urb->errorcode = 0; @@ -956,6 +927,7 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num) urb->errorcode = -USB_ERR_IO; dwc2_urb_waitup(urb); } + USB_OTG_HC(ch_num)->HCINT = chan_intstatus; } } @@ -972,7 +944,6 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num) //printf("s2:%08x\r\n", chan_intstatus); if (chan_intstatus & USB_OTG_HCINT_CHH) { - USB_OTG_HC(ch_num)->HCINT = chan_intstatus; if (chan_intstatus & USB_OTG_HCINT_XFRC) { urb->errorcode = 0; @@ -1037,6 +1008,7 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num) urb->errorcode = -USB_ERR_IO; dwc2_urb_waitup(urb); } + USB_OTG_HC(ch_num)->HCINT = chan_intstatus; } } diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ehci/README.md b/rt-thread/components/drivers/usb/cherryusb/port/ehci/README.md index 8160c65..48b9a2b 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/ehci/README.md +++ b/rt-thread/components/drivers/usb/cherryusb/port/ehci/README.md @@ -22,17 +22,6 @@ - d13x, d21x -### NXP - -Modify USB_NOCACHE_RAM_SECTION - -``` -#define USB_NOCACHE_RAM_SECTION __attribute__((section(".NonCacheable"))) -``` - -- IMRT10XX/IMRT11XX -- MCXN9XX/MCXN236 - ### Intel - Intel 6 Series Chipset and Intel C200 Series Chipset diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_ehci_reg.h b/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_ehci_reg.h deleted file mode 100644 index 741eef6..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_ehci_reg.h +++ /dev/null @@ -1,393 +0,0 @@ -/**************************************************************************** - * include/nuttx/usb/ehci.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ -/* - * Copyright 2022 sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef __INCLUDE_NUTTX_USB_EHCI_H -#define __INCLUDE_NUTTX_USB_EHCI_H - -#define EHCI_FULL_SPEED (0) /* Full-Speed (12Mbs) */ -#define EHCI_LOW_SPEED (1) /* Low-Speed (1.5Mbs) */ -#define EHCI_HIGH_SPEED (2) /* High-Speed (480 Mb/s) */ - -/* Host Controller Capability Register Bit Definitions **********************/ - -/* Structural Parameters. Paragraph 2.2.3 */ - -#define EHCI_HCSPARAMS_NPORTS_SHIFT (0) /* Bit 0-3: Number of physical downstream ports */ -#define EHCI_HCSPARAMS_NPORTS_MASK (15 << EHCI_HCSPARAMS_NPORTS_SHIFT) -#define EHCI_HCSPARAMS_PPC (1 << 4) /* Bit 4: Port Power Control */ -#define EHCI_HCSPARAMS_PRR (1 << 7) /* Bit 7: Port Routing Rules */ -#define EHCI_HCSPARAMS_NPCC_SHIFT (8) /* Bit 8-11: Number of Ports per Companion Controller */ -#define EHCI_HCSPARAMS_NPCC_MASK (15 << EHCI_HCSPARAMS_NPCC_SHIFT) -#define EHCI_HCSPARAMS_NCC_SHIFT (12) /* Bit 12-15: Number of Companion Controllers */ -#define EHCI_HCSPARAMS_NCC_MASK (15 << EHCI_HCSPARAMS_NCC_SHIFT) -#define EHCI_HCSPARAMS_PIND (1 << 16) /* Bit 16: Port Indicators */ -#define EHCI_HCSPARAMS_DBGPORT_SHIFT (20) /* Bit 20-23: Debug Port Number */ -#define EHCI_HCSPARAMS_DBGPORT_MASK (15 << EHCI_HCSPARAMS_DBGPORT_SHIFT) - -/* Capability Parameters. Paragraph 2.2.4 */ - -#define EHCI_HCCPARAMS_64BIT (1 << 0) /* Bit 0: 64-bit Addressing Capability */ -#define EHCI_HCCPARAMS_PFLF (1 << 1) /* Bit 1: Programmable Frame List Flag */ -#define EHCI_HCCPARAMS_ASPC (1 << 2) /* Bit 2: Asynchronous Schedule Park Capability */ -#define EHCI_HCCPARAMS_IST_SHIFT (4) /* Bits 4-7: Isochronous Scheduling Threshold */ -#define EHCI_HCCPARAMS_IST_MASK (15 << EHCI_HCCPARAMS_IST_SHIFT) -#define EHCI_HCCPARAMS_EECP_SHIFT (8) /* Bits 8-15: EHCI Extended Capabilities Pointer */ -#define EHCI_HCCPARAMS_EECP_MASK (0xff << EHCI_HCCPARAMS_EECP_SHIFT) - -/* Host Controller Operational Register Bit Definitions *********************/ - -/* USB Command. Paragraph 2.3.1 */ - -#define EHCI_USBCMD_RUN (1 << 0) /* Bit 0: Run/Stop */ -#define EHCI_USBCMD_HCRESET (1 << 1) /* Bit 1: Host Controller Reset */ -#define EHCI_USBCMD_FLSIZE_SHIFT (2) /* Bits 2-3: Frame List Size */ -#define EHCI_USBCMD_FLSIZE_MASK (3 << EHCI_USBCMD_FLSIZE_SHIFT) -#define EHCI_USBCMD_FLSIZE_1024 (0 << EHCI_USBCMD_FLSIZE_SHIFT) /* 1024 elements (4096 bytes) */ -#define EHCI_USBCMD_FLSIZE_512 (1 << EHCI_USBCMD_FLSIZE_SHIFT) /* 512 elements (2048 bytes) */ -#define EHCI_USBCMD_FLSIZE_256 (2 << EHCI_USBCMD_FLSIZE_SHIFT) /* 256 elements (1024 bytes) */ -#define EHCI_USBCMD_PSEN (1 << 4) /* Bit 4: Periodic Schedule Enable */ -#define EHCI_USBCMD_ASEN (1 << 5) /* Bit 5: Asynchronous Schedule Enable */ -#define EHCI_USBCMD_IAAD (1 << 6) /* Bit 6: Interrupt on Async Advance Doorbell */ -#define EHCI_USBCMD_LRESET (1 << 7) /* Bit 7: Light Host Controller Reset */ -#define EHCI_USBCMD_ASYNC_PARKCNT_SHIFT (8) /* Bits 8-9: Asynchronous Schedule Park Mode Count */ -#define EHCI_USBCMD_ASYNC_PARKCNT_MASK (3 << EHCI_USBCMD_ASYNC_PARKCNT_SHIFT) -#define EHCI_USBCMD_ASYNC_PARK (1 << 11) /* Bit 11: Asynchronous Schedule Park Mode Enable */ -#define EHCI_USBCMD_ITHRE_SHIFT (16) /* Bits 16-23: Interrupt Threshold Control */ -#define EHCI_USBCMD_ITHRE_MASK (0xff << EHCI_USBCMD_ITHRE_SHIFT) -#define EHCI_USBCMD_ITHRE_1MF (0x01 << EHCI_USBCMD_ITHRE_SHIFT) /* 1 micro-frame */ -#define EHCI_USBCMD_ITHRE_2MF (0x02 << EHCI_USBCMD_ITHRE_SHIFT) /* 2 micro-frames */ -#define EHCI_USBCMD_ITHRE_4MF (0x04 << EHCI_USBCMD_ITHRE_SHIFT) /* 4 micro-frames */ -#define EHCI_USBCMD_ITHRE_8MF (0x08 << EHCI_USBCMD_ITHRE_SHIFT) /* 8 micro-frames (default, 1 ms) */ -#define EHCI_USBCMD_ITHRE_16MF (0x10 << EHCI_USBCMD_ITHRE_SHIFT) /* 16 micro-frames (2 ms) */ -#define EHCI_USBCMD_ITHRE_32MF (0x20 << EHCI_USBCMD_ITHRE_SHIFT) /* 32 micro-frames (4 ms) */ -#define EHCI_USBCMD_ITHRE_64MF (0x40 << EHCI_USBCMD_ITHRE_SHIFT) /* 64 micro-frames (8 ms) */ - -/* USB Status. Paragraph 2.3.2 */ - -#define EHCI_USBSTS_INT (1 << 0) /* Bit 0: USB Interrupt */ -#define EHCI_USBSTS_ERR (1 << 1) /* Bit 1: USB Error Interrupt */ -#define EHCI_USBSTS_PCD (1 << 2) /* Bit 2: Port Change Detect */ -#define EHCI_USBSTS_FLR (1 << 3) /* Bit 3: Frame List Rollover */ -#define EHCI_USBSTS_FATAL (1 << 4) /* Bit 4: Host System Error */ -#define EHCI_USBSTS_IAA (1 << 5) /* Bit 5: Interrupt on Async Advance */ -#define EHCI_USBSTS_HALTED (1 << 12) /* Bit 12: HC Halted */ -#define EHCI_USBSTS_RECLAM (1 << 13) /* Bit 13: Reclamation */ -#define EHCI_USBSTS_PSS (1 << 14) /* Bit 14: Periodic Schedule Status */ -#define EHCI_USBSTS_ASS (1 << 15) /* Bit 15: Asynchronous Schedule Status */ - /* Bits 16-31: Reserved */ - -/* USB Interrupt Enable. Paragraph 2.3.3 */ - -#define EHCI_USBIE_INT (1 << 0) /* Bit 0: USB Interrupt */ -#define EHCI_USBIE_ERR (1 << 1) /* Bit 1: USB Error Interrupt */ -#define EHCI_USBIE_PCD (1 << 2) /* Bit 2: Port Change Detect */ -#define EHCI_USBIE_FLROLL (1 << 3) /* Bit 3: Frame List Rollover */ -#define EHCI_USBIE_FATAL (1 << 4) /* Bit 4: Host System Error */ -#define EHCI_USBIE_IAA (1 << 5) /* Bit 5: Interrupt on Async Advance */ -#define EHCI_USBIE_ALLINTS (0x3f) /* Bits 0-5: All interrupts */ - -/* USB Frame Index. Paragraph 2.3.4 */ - -#define EHCI_FRINDEX_MASK (0x3fff) /* Bits 0-13: Frame index */ - -/* 4G Segment Selector. - * Paragraph 2.3.5, Bits[64:32] of data structure addresses - */ - -/* Frame List Base Address. Paragraph 2.3.6 */ -#define EHCI_PERIODICLISTBASE_MASK (0xfffff000) /* Bits 12-31: Base Address (Low) */ - -/* Next Asynchronous List Address. Paragraph 2.3.7 */ - -#define EHCI_ASYNCLISTADDR_MASK (0xffffffe0) /* Bits 5-31: Link Pointer Low (LPL) */ - -/* Configured Flag Register. Paragraph 2.3.8 */ - -#define EHCI_CONFIGFLAG (1 << 0) /* Bit 0: Configure Flag */ - -/* Port Status/Control, Port 1-n. Paragraph 2.3.9 */ - -#define EHCI_PORTSC_CCS (1 << 0) /* Bit 0: Current Connect Status */ -#define EHCI_PORTSC_CSC (1 << 1) /* Bit 1: Connect Status Change */ -#define EHCI_PORTSC_PE (1 << 2) /* Bit 2: Port Enable */ -#define EHCI_PORTSC_PEC (1 << 3) /* Bit 3: Port Enable/Disable Change */ -#define EHCI_PORTSC_OCA (1 << 4) /* Bit 4: Over-current Active */ -#define EHCI_PORTSC_OCC (1 << 5) /* Bit 5: Over-current Change */ -#define EHCI_PORTSC_RESUME (1 << 6) /* Bit 6: Force Port Resume */ -#define EHCI_PORTSC_SUSPEND (1 << 7) /* Bit 7: Suspend */ -#define EHCI_PORTSC_RESET (1 << 8) /* Bit 8: Port Reset */ -#define EHCI_PORTSC_LSTATUS_SHIFT (10) /* Bits 10-11: Line Status */ -#define EHCI_PORTSC_LSTATUS_MASK (3 << EHCI_PORTSC_LSTATUS_SHIFT) -#define EHCI_PORTSC_LSTATUS_SE0 (0 << EHCI_PORTSC_LSTATUS_SHIFT) /* SE0 Not Low-speed device, perform EHCI reset */ -#define EHCI_PORTSC_LSTATUS_KSTATE (1 << EHCI_PORTSC_LSTATUS_SHIFT) /* K-state Low-speed device, release ownership of port */ -#define EHCI_PORTSC_LSTATUS_JSTATE (2 << EHCI_PORTSC_LSTATUS_SHIFT) /* J-state Not Low-speed device, perform EHCI reset */ -#define EHCI_PORTSC_PP (1 << 12) /* Bit 12: Port Power */ -#define EHCI_PORTSC_OWNER (1 << 13) /* Bit 13: Port Owner */ -#define EHCI_PORTSC_PIC_SHIFT (14) /* Bits 14-15: Port Indicator Control */ -#define EHCI_PORTSC_PIC_MASK (3 << EHCI_PORTSC_PIC_SHIFT) -#define EHCI_PORTSC_PIC_OFF (0 << EHCI_PORTSC_PIC_SHIFT) /* Port indicators are off */ -#define EHCI_PORTSC_PIC_AMBER (1 << EHCI_PORTSC_PIC_SHIFT) /* Amber */ -#define EHCI_PORTSC_PIC_GREEN (2 << EHCI_PORTSC_PIC_SHIFT) /* Green */ -#define EHCI_PORTSC_PTC_SHIFT (16) /* Bits 16-19: Port Test Control */ -#define EHCI_PORTSC_PTC_MASK (15 << EHCI_PORTSC_PTC_SHIFT) -#define EHCI_PORTSC_PTC_DISABLED (0 << EHCI_PORTSC_PTC_SHIFT) /* Test mode not enabled */ -#define EHCI_PORTSC_PTC_JSTATE (1 << EHCI_PORTSC_PTC_SHIFT) /* Test J_STATE */ -#define EHCI_PORTSC_PTC_KSTATE (2 << EHCI_PORTSC_PTC_SHIFT) /* Test K_STATE */ -#define EHCI_PORTSC_PTC_SE0NAK (3 << EHCI_PORTSC_PTC_SHIFT) /* Test SE0_NAK */ -#define EHCI_PORTSC_PTC_PACKET (4 << EHCI_PORTSC_PTC_SHIFT) /* Test Packet */ -#define EHCI_PORTSC_PTC_ENABLE (5 << EHCI_PORTSC_PTC_SHIFT) /* Test FORCE_ENABLE */ -#define EHCI_PORTSC_WKCCNTE (1 << 20) /* Bit 20: Wake on Connect Enable */ -#define EHCI_PORTSC_WKDSCNNTE (1 << 21) /* Bit 21: Wake on Disconnect Enable */ -#define EHCI_PORTSC_WKOCE (1 << 22) /* Bit 22: Wake on Over-current Enable */ - /* Bits 23-31: Reserved */ - -#define EHCI_PORTSC_ALLINTS (EHCI_PORTSC_CSC | EHCI_PORTSC_PEC | \ - EHCI_PORTSC_OCC | EHCI_PORTSC_RESUME) - -/* Queue Head. Paragraph 3.6 */ - -/* Queue Head Horizontal Link Pointer: Queue Head DWord 0. Table 3-19 */ - -#define QH_HLP_END 0x1 - -#define QH_HLP_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0) /* Isochronous Transfer Descriptor */ -#define QH_HLP_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2) /* Queue Head */ -#define QH_HLP_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4) /* Split Transaction Isochronous Transfer Descriptor */ -#define QH_HLP_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6) /* Frame Span Traversal Node */ - -/* Endpoint Characteristics: Queue Head DWord 1. Table 3-19 */ - -#define QH_EPCHAR_DEVADDR_SHIFT (0) /* Bitx 0-6: Device Address */ -#define QH_EPCHAR_DEVADDR_MASK (0x7f << QH_EPCHAR_DEVADDR_SHIFT) -#define QH_EPCHAR_I (1 << 7) /* Bit 7: Inactivate on Next Transaction */ -#define QH_EPCHAR_ENDPT_SHIFT (8) /* Bitx 8-11: Endpoint Number */ -#define QH_EPCHAR_ENDPT_MASK (15 << QH_EPCHAR_ENDPT_SHIFT) -#define QH_EPCHAR_EPS_SHIFT (12) /* Bitx 12-13: Endpoint Speed */ -#define QH_EPCHAR_EPS_MASK (3 << QH_EPCHAR_EPS_SHIFT) -#define QH_EPCHAR_EPS_FULL (0 << QH_EPCHAR_EPS_SHIFT) /* Full-Speed (12Mbs) */ -#define QH_EPCHAR_EPS_LOW (1 << QH_EPCHAR_EPS_SHIFT) /* Low-Speed (1.5Mbs) */ -#define QH_EPCHAR_EPS_HIGH (2 << QH_EPCHAR_EPS_SHIFT) /* High-Speed (480 Mb/s) */ -#define QH_EPCHAR_DTC (1 << 14) /* Bit 14: Data Toggle Control */ -#define QH_EPCHAR_H (1 << 15) /* Bit 15: Head of Reclamation List Flag */ -#define QH_EPCHAR_MAXPKT_SHIFT (16) /* Bitx 16-26: Maximum Packet Length */ -#define QH_EPCHAR_MAXPKT_MASK (0x7ff << QH_EPCHAR_MAXPKT_SHIFT) -#define QH_EPCHAR_C (1 << 27) /* Bit 27: Control Endpoint Flag */ -#define QH_EPCHAR_RL_SHIFT (28) /* Bitx 28-31: Nak Count Reload */ -#define QH_EPCHAR_RL_MASK (15 << QH_EPCHAR_RL_SHIFT) - -/* Endpoint Capabilities: Queue Head DWord 2. Table 3-20 */ - -#define QH_EPCAPS_SSMASK_SHIFT (0) /* Bitx 0-7: Interrupt Schedule Mask (Frame S-mask) */ -#define QH_EPCAPS_SSMASK_MASK (0xff << QH_EPCAPS_SSMASK_SHIFT) -#define QH_EPCAPS_SSMASK(n) ((n) << QH_EPCAPS_SSMASK_SHIFT) -#define QH_EPCAPS_SCMASK_SHIFT (8) /* Bitx 8-15: Split Completion Mask (Frame C-Mask) */ -#define QH_EPCAPS_SCMASK_MASK (0xff << QH_EPCAPS_SCMASK_SHIFT) -#define QH_EPCAPS_SCMASK(n) ((n) << QH_EPCAPS_SCMASK_SHIFT) -#define QH_EPCAPS_HUBADDR_SHIFT (16) /* Bitx 16-22: Hub Address */ -#define QH_EPCAPS_HUBADDR_MASK (0x7f << QH_EPCAPS_HUBADDR_SHIFT) -#define QH_EPCAPS_HUBADDR(n) ((n) << QH_EPCAPS_HUBADDR_SHIFT) -#define QH_EPCAPS_PORT_SHIFT (23) /* Bit 23-29: Port Number */ -#define QH_EPCAPS_PORT_MASK (0x7f << QH_EPCAPS_PORT_SHIFT) -#define QH_EPCAPS_PORT(n) ((n) << QH_EPCAPS_PORT_SHIFT) -#define QH_EPCAPS_MULT_SHIFT (30) /* Bit 30-31: High-Bandwidth Pipe Multiplier */ -#define QH_EPCAPS_MULT_MASK (3 << QH_EPCAPS_MULT_SHIFT) -#define QH_EPCAPS_MULT(n) ((n) << QH_EPCAPS_MULT_SHIFT) - -/* qTD Token. Paragraph 3.5.3 */ - -#define QTD_LIST_END 1 - -#define QTD_TOKEN_STATUS_SHIFT (0) /* Bits 0-7: Status */ -#define QTD_TOKEN_STATUS_MASK (0xff << QTD_TOKEN_STATUS_SHIFT) -#define QTD_TOKEN_STATUS_PINGSTATE (1 << 0) /* Bit 0 Ping State */ -#define QTD_TOKEN_STATUS_ERR (1 << 0) /* Bit 0 Error */ -#define QTD_TOKEN_STATUS_SPLITXSTATE (1 << 1) /* Bit 1 Split Transaction State */ -#define QTD_TOKEN_STATUS_MMF (1 << 2) /* Bit 2 Missed Micro-Frame */ -#define QTD_TOKEN_STATUS_XACTERR (1 << 3) /* Bit 3 Transaction Error */ -#define QTD_TOKEN_STATUS_BABBLE (1 << 4) /* Bit 4 Babble Detected */ -#define QTD_TOKEN_STATUS_DBERR (1 << 5) /* Bit 5 Data Buffer Error */ -#define QTD_TOKEN_STATUS_HALTED (1 << 6) /* Bit 6 Halted */ -#define QTD_TOKEN_STATUS_ACTIVE (1 << 7) /* Bit 7 Active */ -#define QTD_TOKEN_STATUS_ERRORS (0x78 << QTD_TOKEN_STATUS_SHIFT) -#define QTD_TOKEN_PID_SHIFT (8) /* Bits 8-9: PID Code */ -#define QTD_TOKEN_PID_MASK (3 << QTD_TOKEN_PID_SHIFT) -#define QTD_TOKEN_PID_OUT (0 << QTD_TOKEN_PID_SHIFT) /* OUT Token generates token (E1H) */ -#define QTD_TOKEN_PID_IN (1 << QTD_TOKEN_PID_SHIFT) /* IN Token generates token (69H) */ -#define QTD_TOKEN_PID_SETUP (2 << QTD_TOKEN_PID_SHIFT) /* SETUP Token generates token (2DH) */ -#define QTD_TOKEN_CERR_SHIFT (10) /* Bits 10-11: Error Counter */ -#define QTD_TOKEN_CERR_MASK (3 << QTD_TOKEN_CERR_SHIFT) -#define QTD_TOKEN_CPAGE_SHIFT (12) /* Bits 12-14: Current Page */ -#define QTD_TOKEN_CPAGE_MASK (7 << QTD_TOKEN_CPAGE_SHIFT) -#define QTD_TOKEN_IOC (1 << 15) /* Bit 15: Interrupt On Complete */ -#define QTD_TOKEN_NBYTES_SHIFT (16) /* Bits 16-30: Total Bytes to Transfer */ -#define QTD_TOKEN_NBYTES_MASK (0x7fff << QTD_TOKEN_NBYTES_SHIFT) -#define QTD_TOKEN_TOGGLE (1 << 31) /* Bit 31: Data Toggle */ - -/* Isochronous (High-Speed) Transfer Descriptor (iTD). Paragraph 3.3 */ - -/* iTD Next Link Pointer. Paragraph 3.3.1 */ - -#define ITD_NLP_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0) -#define ITD_NLP_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2) -#define ITD_NLP_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4) -#define ITD_NLP_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6) - -/* iTD Transaction Status and Control List. Paragraph 3.3.2 */ -#define ITD_TSCL_XOFFS_SHIFT (0) /* Bits 0-11: Transaction X offset */ -#define ITD_TSCL_XOFFS_MASK (0xfff << ITD_TSCL_XOFFS_SHIFT) -#define ITD_TSCL_PG_SHIFT (12) /* Bits 12-14: Page select */ -#define ITD_TSCL_PG_MASK (7 << ITD_TSCL_PG_SHIFT) -#define ITD_TSCL_IOC (1 << 15) /* Bit 15: Interrupt On Comp */ -#define ITD_TSCL_LENGTH_SHIFT (16) /* Bits 16-27: Transaction length */ -#define ITD_TSCL_LENGTH_MASK (0xfff << ITD_TSCL_LENGTH_SHIFT) -#define ITD_TSCL_STATUS_SHIFT (28) /* Bits 28-31: Transaction status */ -#define ITD_TSCL_STATUS_MASK (15 << ITD_TSCL_STATUS_SHIFT) -#define ITD_TSCL_STATUS_XACTERR (1 << 28) /* Bit 28: Transaction error */ -#define ITD_TSCL_STATUS_BABBLE (1 << 29) /* Bit 29: Babble Detected */ -#define ITD_TSCL_STATUS_DBERROR (1 << 30) /* Bit 30: Data Buffer Error */ -#define ITD_TSCL_STATUS_ACTIVE (1 << 31) /* Bit 31: Active error */ - -/* iTD Buffer Page Pointer List. Paragraph 3.3.4 */ - -/* iTD Buffer Pointer Page 0. Table 3-4 */ - -#define ITD_BUFPTR0_DEVADDR_SHIFT (0) /* Bits 0-6: Device Address */ -#define ITD_BUFPTR0_DEVADDR_MASK (0x7f << ITD_BUFPTR0_DEVADDR_SHIFT) -#define ITD_BUFPTR0_ENDPT_SHIFT (8) /* Bits 8-11: Endpoint Number */ -#define ITD_BUFPTR0_ENDPT_MASK (15 << ITD_BUFPTR0_ENDPT_SHIFT) - -/* iTD Buffer Pointer Page 1. Table 3-5 */ - -#define ITD_BUFPTR1_MAXPKT_SHIFT (0) /* Bits 0-10: Maximum Packet Size */ -#define ITD_BUFPTR1_MAXPKT_MASK (0x7ff << ITD_BUFPTR1_MAXPKT_SHIFT) -#define ITD_BUFPTR1_DIRIN (1 << 11) /* Bit 11: Direction 1=IN */ -#define ITD_BUFPTR1_DIROUT (0) /* Bit 11: Direction 0=OUT */ - -/* iTD Buffer Pointer Page 2. Table 3-6 */ - -#define ITD_BUFPTR2_MULTI_SHIFT (0) /* Bits 0-1: Multi */ -#define ITD_BUFPTR2_MULTI_MASK (3 << ITD_BUFPTR2_MULTI_SHIFT) -#define ITD_BUFPTR2_MULTI_1 (1 << ITD_BUFPTR2_MULTI_SHIFT) /* One transaction per micro-frame */ -#define ITD_BUFPTR2_MULTI_2 (2 << ITD_BUFPTR2_MULTI_SHIFT) /* Two transactions per micro-frame */ -#define ITD_BUFPTR2_MULTI_3 (3 << ITD_BUFPTR2_MULTI_SHIFT) /* Three transactions per micro-frame */ - -/* Registers ****************************************************************/ - -/* Host Controller Capability Registers. - * This register block must be positioned at a well known address. - */ - -struct ehci_hccr { - volatile uint8_t caplength; /* 0x00: Capability Register Length */ - volatile uint8_t reserved; /* 0x01: reserved */ - volatile uint16_t hciversion; /* 0x02: Interface Version Number */ - volatile uint32_t hcsparams; /* 0x04: Structural Parameters */ - volatile uint32_t hccparams; /* 0x08: Capability Parameters */ - volatile uint8_t hcspportroute[8]; /* 0x0c: Companion Port Route Description */ -}; - -/* Host Controller Operational Registers. - * This register block is positioned at an offset of 'caplength' from the - * beginning of the Host Controller Capability Registers. - */ - -struct ehci_hcor { - volatile uint32_t usbcmd; /* 0x00: USB Command */ - volatile uint32_t usbsts; /* 0x04: USB Status */ - volatile uint32_t usbintr; /* 0x08: USB Interrupt Enable */ - volatile uint32_t frindex; /* 0x0c: USB Frame Index */ - volatile uint32_t ctrldssegment; /* 0x10: 4G Segment Selector */ - volatile uint32_t periodiclistbase; /* 0x14: Frame List Base Address */ - volatile uint32_t asynclistaddr; /* 0x18: Next Asynchronous List Address */ -#ifndef CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE - uint32_t reserved[9]; -#endif - volatile uint32_t configflag; /* 0x40: Configured Flag Register */ - volatile uint32_t portsc[15]; /* 0x44: Port Status/Control */ -}; - -/* USB2 Debug Port Register Interface. - * This register block is normally found via the PCI capabalities. - * In non-PCI implementions, you need apriori information about the - * location of these registers. - */ - -struct ehci_debug { - uint32_t psc; /* 0x00: Debug Port Control/Status Register */ - uint32_t pids; /* 0x04: Debug USB PIDs Register */ - uint32_t data[2]; /* 0x08: Debug Data buffer Registers */ - uint32_t addr; /* 0x10: Device Address Register */ -}; - -/* Data Structures **********************************************************/ - -/* Queue Element Transfer Descriptor (qTD). Paragraph 3.5 */ - -struct ehci_qtd { - uint32_t next_qtd; /* 0x00-0x03: Next qTD Pointer */ - uint32_t alt_next_qtd; /* 0x04-0x07: Alternate Next qTD Pointer */ - uint32_t token; /* 0x08-0x0b: qTD Token */ - uint32_t bpl[5]; /* 0x0c-0x1c: Buffer Page Pointer List */ -}; - -#define SIZEOF_EHCI_QTD (32) /* 8*sizeof(uint32_t) */ - -/* Queue Head. Paragraph 3.6 */ - -struct ehci_qh { - uint32_t hlp; /* 0x00-0x03: Queue Head Horizontal Link Pointer */ - uint32_t epchar; /* 0x04-0x07: Endpoint Characteristics */ - uint32_t epcap; /* 0x08-0x0b: Endpoint Capabilities */ - uint32_t curr_qtd; /* 0x0c-0x0f: Current qTD Pointer */ - struct ehci_qtd overlay; /* 0x10-0x2c: Transfer overlay */ -}; - -#define SIZEOF_EHCI_QH (48) /* 4*sizeof(uint32_t) + 32 */ - -/* Isochronous (High-Speed) Transfer Descriptor (iTD). - * Paragraph 3.3. Must be aligned to 32-byte boundaries. - */ - -struct ehci_itd { - uint32_t nlp; /* 0x00-0x03: Next link pointer */ - uint32_t tscl[8]; /* 0x04-0x23: Transaction Status and Control List */ - uint32_t bpl[7]; /* 0x24-0x3c: Buffer Page Pointer List */ -}; - -#define SIZEOF_EHCI_ITD (64) /* 16*sizeof(uint32_t) */ - -/* Split Transaction Isochronous Transfer Descriptor (siTD). Paragraph 3.4 */ - -struct ehci_sitd { - uint32_t nlp; /* 0x00-0x03: Next link pointer */ - uint32_t epchar; /* 0x04-0x07: Endpoint and Transaction Translator Characteristics */ - uint32_t mfsc; /* 0x08-0x0b: Micro-frame Schedule Control */ - uint32_t tsc; /* 0x0c-0x0f: Transfer Status and Control */ - uint32_t bpl[2]; /* 0x10-0x17: Buffer Pointer List */ - uint32_t blp; /* 0x18-0x1b: Back link pointer */ -}; - -#define SIZEOF_EHCI_SITD (28) /* 7*sizeof(uint32_t) */ - -#endif /* __INCLUDE_NUTTX_USB_EHCI_H */ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c b/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c index 500bc02..5445b53 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_aic.c @@ -8,20 +8,7 @@ #include #include #include "usbh_core.h" -#include "usb_hc_ehci.h" -#include "usb_hc_ohci.h" - -#if !defined(CONFIG_USB_EHCI_CONFIGFLAG) -#error "aic ehci must define CONFIG_USB_EHCI_CONFIGFLAG" -#endif - -#if !defined(CONFIG_USB_EHCI_WITH_OHCI) -#error "aic must define CONFIG_USB_EHCI_WITH_OHCI for ls/fs device" -#endif - -#if CONFIG_USB_OHCI_HCOR_OFFSET != 0x400 -#error "aic CONFIG_USB_OHCI_HCOR_OFFSET must be 0x400" -#endif +#include "usb_ehci_priv.h" extern void USBH_IRQHandler(uint8_t busid); @@ -130,12 +117,21 @@ void usb_hc_low_level_init(struct usbh_bus *bus) aicos_request_irq(config[i].irq_num + 1, (irq_handler_t)aic_ohci_isr, 0, "usb_host_ohci", bus); aicos_irq_enable(config[i].irq_num); - aicos_irq_enable(config[i].irq_num + 1); } uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port) { - return USB_SPEED_HIGH; + /* Defined by individual manufacturers */ + uint32_t regval; + + regval = EHCI_HCOR->portsc[port-1]; + if ((regval & EHCI_PORTSC_LSTATUS_MASK) == EHCI_PORTSC_LSTATUS_KSTATE) + return USB_SPEED_LOW; + + if (regval & EHCI_PORTSC_PE) + return USB_SPEED_HIGH; + else + return USB_SPEED_FULL; } void usb_ehci_dcache_clean(uintptr_t addr, uint32_t len) @@ -153,7 +149,7 @@ void usb_ehci_dcache_clean_invalidate(uintptr_t addr, uint32_t len) aicos_dcache_clean_invalid_range((size_t *)addr, len); } -int __usbh_init(void) +int usbh_init(void) { #if defined(AIC_USING_USB0_HOST) || defined(AIC_USING_USB1_HOST) int bus_id = 0; @@ -175,5 +171,11 @@ int __usbh_init(void) #include #include -INIT_ENV_EXPORT(__usbh_init); +INIT_ENV_EXPORT(usbh_init); + +#if defined (RT_USING_FINSH) +#include + +MSH_CMD_EXPORT_ALIAS(lsusb, lsusb, list usb device); +#endif #endif \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_hpm.c b/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_hpm.c index 40105a9..f616f2c 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_hpm.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_hpm.c @@ -35,11 +35,6 @@ static void usb_host_mode_init(USB_Type *ptr) /* Set parallel transceiver width */ ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK; -#ifdef CONFIG_USB_HOST_FORCE_FULL_SPEED - /* Set usb forced to full speed mode */ - ptr->PORTSC1 |= USB_PORTSC1_PFSC_MASK; -#endif - /* Not use interrupt threshold. */ ptr->USBCMD &= ~USB_USBCMD_ITC_MASK; } @@ -58,7 +53,7 @@ void usb_hc_low_level_init(struct usbh_bus *bus) #endif } - usb_phy_init((USB_Type *)(bus->hcd.reg_base), true); + usb_phy_init((USB_Type *)(bus->hcd.reg_base)); intc_m_enable_irq(_hcd_irqnum[bus->hcd.hcd_id]); } @@ -87,22 +82,18 @@ uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port) return 0; } -#if !defined(USBH_USE_CUSTOM_ISR) || !USBH_USE_CUSTOM_ISR - extern void USBH_IRQHandler(uint8_t busid); -SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usbh0) void isr_usbh0(void) { USBH_IRQHandler(_hcd_busid[0]); } +SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usbh0) #ifdef HPM_USB1_BASE -SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbh1) void isr_usbh1(void) { USBH_IRQHandler(_hcd_busid[1]); } -#endif - +SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbh1) #endif diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_ma35d0.c b/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_ma35d0.c index 3e03bbd..76e621e 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_ma35d0.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_ma35d0.c @@ -57,7 +57,7 @@ void usb_hc_low_level_init(struct usbh_bus *bus) SYS->MISCFCR0 &= ~SYS_MISCFCR0_UHOVRCURH_Msk; while (1) { rt_thread_mdelay(1); - if (SYS->USBPMISCR & SYS_USBPMISCR_PHY0HSTCKSTB_Msk) + if ((SYS->USBPMISCR & SYS_USBPMISCR_PHY0HSTCKSTB_Msk) &&) break; /* both USB PHY0 and PHY1 clock 60MHz UTMI clock stable */ timeout--; @@ -88,7 +88,7 @@ void usb_hc_low_level_init(struct usbh_bus *bus) SYS->MISCFCR0 &= ~SYS_MISCFCR0_UHOVRCURH_Msk; while (1) { rt_thread_mdelay(1); - if (SYS->USBPMISCR & SYS_USBPMISCR_PHY1HSTCKSTB_Msk) + if ((SYS->USBPMISCR & SYS_USBPMISCR_PHY1HSTCKSTB_Msk)) break; /* both USB PHY0 and PHY1 clock 60MHz UTMI clock stable */ timeout--; diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_mcx.c b/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_mcx.c deleted file mode 100644 index 92b2c25..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_glue_mcx.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbh_core.h" -#include "fsl_common.h" -#include "usb_chipidea_reg.h" - -#define USB_DEVICE_CONFIG_EHCI 1 - -/*! @brief USB controller ID */ -typedef enum _usb_controller_index -{ - kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */ - kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved - to be used in the future. */ - kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */ - kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U */ -} usb_controller_index_t; - -/* USB PHY condfiguration */ -#define BOARD_USB_PHY_D_CAL (0x04U) -#define BOARD_USB_PHY_TXCAL45DP (0x07U) -#define BOARD_USB_PHY_TXCAL45DM (0x07U) -#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */ - -#if !defined(CONFIG_USB_EHCI_NXP) -#error "mcx ehci must config CONFIG_USB_EHCI_NXP" -#endif - -#if !defined(CONFIG_USB_EHCI_HCCR_OFFSET) || CONFIG_USB_EHCI_HCCR_OFFSET != 0x100 -#error "mcx ehci must config CONFIG_USB_EHCI_HCCR_OFFSET to 0x100" -#endif - -#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) -#include "usb_phy.h" -#endif - -#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) -void USB1_HS_IRQHandler(void) -{ - extern void USBH_IRQHandler(uint8_t busid); - USBH_IRQHandler(0); -} -#endif - -void USB_ClockInit(void) -{ -#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) - usb_phy_config_struct_t phyConfig = { - BOARD_USB_PHY_D_CAL, - BOARD_USB_PHY_TXCAL45DP, - BOARD_USB_PHY_TXCAL45DM, - }; -#endif -#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) - SPC0->ACTIVE_VDELAY = 0x0500; - /* Change the power DCDC to 1.8v (By deafult, DCDC is 1.8V), CORELDO to 1.1v (By deafult, CORELDO is 1.0V) */ - SPC0->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK; - SPC0->ACTIVE_CFG |= SPC_ACTIVE_CFG_DCDC_VDD_LVL(0x3) | SPC_ACTIVE_CFG_CORELDO_VDD_LVL(0x3) | - SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK | SPC_ACTIVE_CFG_DCDC_VDD_DS(0x2u); - /* Wait until it is done */ - while (SPC0->SC & SPC_SC_BUSY_MASK) - ; - if (0u == (SCG0->LDOCSR & SCG_LDOCSR_LDOEN_MASK)) { - SCG0->TRIM_LOCK = 0x5a5a0001U; - SCG0->LDOCSR |= SCG_LDOCSR_LDOEN_MASK; - /* wait LDO ready */ - while (0U == (SCG0->LDOCSR & SCG_LDOCSR_VOUT_OK_MASK)) - ; - } - SYSCON->AHBCLKCTRLSET[2] |= SYSCON_AHBCLKCTRL2_USB_HS_MASK | SYSCON_AHBCLKCTRL2_USB_HS_PHY_MASK; - SCG0->SOSCCFG &= ~(SCG_SOSCCFG_RANGE_MASK | SCG_SOSCCFG_EREFS_MASK); - /* xtal = 20 ~ 30MHz */ - SCG0->SOSCCFG = (1U << SCG_SOSCCFG_RANGE_SHIFT) | (1U << SCG_SOSCCFG_EREFS_SHIFT); - SCG0->SOSCCSR |= SCG_SOSCCSR_SOSCEN_MASK; - while (1) { - if (SCG0->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) { - break; - } - } - SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK | SYSCON_CLOCK_CTRL_CLKIN_ENA_FM_USBH_LPT_MASK; - CLOCK_EnableClock(kCLOCK_UsbHs); - CLOCK_EnableClock(kCLOCK_UsbHsPhy); - CLOCK_EnableUsbhsPhyPllClock(kCLOCK_Usbphy480M, 24000000U); - CLOCK_EnableUsbhsClock(); - USB_EhciPhyInit(kUSB_ControllerEhci0, BOARD_XTAL0_CLK_HZ, &phyConfig); -#endif -#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U) - CLOCK_AttachClk(kCLK_48M_to_USB0); - CLOCK_EnableClock(kCLOCK_Usb0Ram); - CLOCK_EnableClock(kCLOCK_Usb0Fs); - CLOCK_EnableUsbfsClock(); -#endif -} - -static void usb_host_mode_init(CHIPIDEA_TypeDef *ptr) -{ - /* Set mode to host, must be set immediately after reset */ - ptr->USBMODE &= ~USB_USBMODE_CM_MASK; - ptr->USBMODE |= USB_USBMODE_CM_SET(3); - - /* Set the endian */ - ptr->USBMODE &= ~USB_USBMODE_ES_MASK; - - /* Set parallel interface signal */ - ptr->PORTSC1 &= ~USB_PORTSC1_STS_MASK; - - /* Set parallel transceiver width */ - ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK; - - /* Not use interrupt threshold. */ - ptr->USBCMD &= ~USB_USBCMD_ITC_MASK; -} - -void usb_hc_low_level_init(struct usbh_bus *bus) -{ - USB_ClockInit(); - /* Install isr, set priority, and enable IRQ. */ - NVIC_SetPriority((IRQn_Type)USB1_HS_IRQn, 3); - EnableIRQ((IRQn_Type)USB1_HS_IRQn); -} - -void usb_hc_low_level2_init(struct usbh_bus *bus) -{ - usb_host_mode_init((CHIPIDEA_TypeDef *)(bus->hcd.reg_base)); -} - -void usb_hc_low_level_deinit(struct usbh_bus *bus) -{ - DisableIRQ((IRQn_Type)USB1_HS_IRQn); -} - -uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port) -{ - (void)port; - uint8_t speed; - - CHIPIDEA_TypeDef *ptr = (CHIPIDEA_TypeDef *)bus->hcd.reg_base; - - speed = USB_PORTSC1_PSPD_GET(ptr->PORTSC1); - - if (speed == 0x00) { - return USB_SPEED_FULL; - } - if (speed == 0x01) { - return USB_SPEED_LOW; - } - if (speed == 0x02) { - USB_EhcihostPhyDisconnectDetectCmd(kUSB_ControllerEhci0, 1); - return USB_SPEED_HIGH; - } - - return 0; -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c b/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c index 4f61854..d837012 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.c @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include "usb_hc_ehci.h" +#include "usb_ehci_priv.h" #ifdef CONFIG_USB_EHCI_WITH_OHCI -#include "usb_hc_ohci.h" +#include "usb_ohci_priv.h" #endif #define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ @@ -167,7 +167,6 @@ static void ehci_qh_fill(struct ehci_qh_hw *qh, switch (speed) { case USB_SPEED_LOW: epchar |= QH_EPCHAR_EPS_LOW; - __attribute__((fallthrough)); case USB_SPEED_FULL: if (ep_type == USB_ENDPOINT_TYPE_CONTROL) { epchar |= QH_EPCHAR_C; /* for TT */ @@ -380,7 +379,7 @@ static struct ehci_qh_hw *ehci_bulk_urb_init(struct usbh_bus *bus, struct usbh_u urb->hport->parent->hub_addr, urb->hport->port); - while (1) { + while (buflen >= 0) { qtd = &qh->qtd_pool[qtd_num]; if (buflen > 0x4000) { @@ -481,7 +480,7 @@ static struct ehci_qh_hw *ehci_intr_urb_init(struct usbh_bus *bus, struct usbh_u urb->hport->parent->hub_addr, urb->hport->port); - while (1) { + while (buflen >= 0) { qtd = &qh->qtd_pool[qtd_num]; if (buflen > 0x4000) { @@ -584,8 +583,6 @@ static void ehci_qh_scan_qtds(struct usbh_bus *bus, struct ehci_qh_hw *qhead, st { struct ehci_qtd_hw *qtd; - (void)bus; - ehci_qh_remove(qhead, qh); qtd = EHCI_ADDR2QTD(qh->first_qtd); @@ -658,8 +655,6 @@ static void ehci_kill_qh(struct usbh_bus *bus, struct ehci_qh_hw *qhead, struct { struct ehci_qtd_hw *qtd; - (void)bus; - ehci_qh_remove(qhead, qh); qtd = EHCI_ADDR2QTD(qh->first_qtd); @@ -702,17 +697,14 @@ static int usbh_reset_port(struct usbh_bus *bus, const uint8_t port) __WEAK void usb_hc_low_level_init(struct usbh_bus *bus) { - (void)bus; } __WEAK void usb_hc_low_level2_init(struct usbh_bus *bus) { - (void)bus; } __WEAK void usb_hc_low_level_deinit(struct usbh_bus *bus) { - (void)bus; } int usb_hc_init(struct usbh_bus *bus) @@ -785,8 +777,6 @@ int usb_hc_init(struct usbh_bus *bus) g_ehci_hcd[bus->hcd.hcd_id].n_cc, g_ehci_hcd[bus->hcd.hcd_id].n_pcc); - EHCI_HCOR->usbcmd &= ~EHCI_USBCMD_RUN; - usb_osal_msleep(2); EHCI_HCOR->usbcmd |= EHCI_USBCMD_HCRESET; while (EHCI_HCOR->usbcmd & EHCI_USBCMD_HCRESET) { usb_osal_msleep(1); @@ -840,7 +830,6 @@ int usb_hc_init(struct usbh_bus *bus) for (uint8_t port = 0; port < g_ehci_hcd[bus->hcd.hcd_id].n_ports; port++) { regval = EHCI_HCOR->portsc[port]; regval |= EHCI_PORTSC_PP; - regval &= ~(EHCI_PORTSC_CSC | EHCI_PORTSC_PEC | EHCI_PORTSC_OCC); EHCI_HCOR->portsc[port] = regval; } } @@ -883,7 +872,7 @@ int usb_hc_deinit(struct usbh_bus *bus) regval &= ~EHCI_USBCMD_RUN; EHCI_HCOR->usbcmd = regval; - while ((EHCI_HCOR->usbsts & (EHCI_USBSTS_PSS | EHCI_USBSTS_ASS)) || ((EHCI_HCOR->usbsts & EHCI_USBSTS_HALTED) == 0)) { + while ((EHCI_HCOR->usbsts & (EHCI_USBSTS_PSS | EHCI_USBSTS_ASS))) { usb_osal_msleep(1); timeout++; if (timeout > 100) { @@ -904,7 +893,6 @@ int usb_hc_deinit(struct usbh_bus *bus) #endif EHCI_HCOR->usbsts = EHCI_HCOR->usbsts; - EHCI_HCOR->usbcmd |= EHCI_USBCMD_HCRESET; for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) { qh = &ehci_qh_pool[bus->hcd.hcd_id][index]; @@ -952,7 +940,6 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u while (!(EHCI_HCOR->portsc[port - 1] & EHCI_PORTSC_OWNER)) { } - USB_LOG_INFO("Switch port %u to OHCI\r\n", port); return ohci_roothub_control(bus, setup, buf); } #endif @@ -1064,9 +1051,7 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u while (!(EHCI_HCOR->portsc[port - 1] & EHCI_PORTSC_OWNER)) { } - - USB_LOG_INFO("Switch port %u to OHCI\r\n", port); - return -USB_ERR_NOTSUPP; + return ohci_roothub_control(bus, setup, buf); } #endif break; @@ -1113,7 +1098,7 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u if (temp & EHCI_PORTSC_RESET) { status |= (1 << HUB_PORT_FEATURE_RESET); } - if (temp & EHCI_PORTSC_PP || !(EHCI_HCCR->hcsparams & EHCI_HCSPARAMS_PPC)) { + if (temp & EHCI_PORTSC_PP) { status |= (1 << HUB_PORT_FEATURE_POWER); } memcpy(buf, &status, 4); @@ -1356,11 +1341,6 @@ void USBH_IRQHandler(uint8_t busid) if (portsc & EHCI_PORTSC_CSC) { if ((portsc & EHCI_PORTSC_CCS) == EHCI_PORTSC_CCS) { } else { -#if defined(CONFIG_USB_EHCI_NXP) - /* kUSB_ControllerEhci0 and kUSB_ControllerEhci1*/ - extern void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable); - USB_EhcihostPhyDisconnectDetectCmd(2 + busid, 0); -#endif for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) { g_ehci_hcd[bus->hcd.hcd_id].ehci_qh_used[index] = false; } diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.h b/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.h index 714128b..7f3febc 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.h +++ b/rt-thread/components/drivers/usb/cherryusb/port/ehci/usb_hc_ehci.h @@ -1,84 +1,375 @@ /* - * Copyright (c) 2022, sakumisu - * + * Copyright 2020 The Apache Software Foundation + * Copyright 2022 sakumisu + * * SPDX-License-Identifier: Apache-2.0 */ -#ifndef _USB_EHCI_PRIV_H -#define _USB_EHCI_PRIV_H +#ifndef USB_HC_EHCI_H +#define USB_HC_EHCI_H -#include "usbh_core.h" -#include "usbh_hub.h" -#include "usb_ehci_reg.h" +#define EHCI_FULL_SPEED (0) /* Full-Speed (12Mbs) */ +#define EHCI_LOW_SPEED (1) /* Low-Speed (1.5Mbs) */ +#define EHCI_HIGH_SPEED (2) /* High-Speed (480 Mb/s) */ -#define EHCI_HCCR ((struct ehci_hccr *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCCR_OFFSET)) -#define EHCI_HCOR ((struct ehci_hcor *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_EHCI_HCCR_OFFSET + g_ehci_hcd[bus->hcd.hcd_id].hcor_offset)) +/* Host Controller Capability Register Bit Definitions **********************/ -#define EHCI_PTR2ADDR(x) ((uint32_t)(uintptr_t)(x) & ~0x1F) -#define EHCI_ADDR2QH(x) ((struct ehci_qh_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F)) -#define EHCI_ADDR2QTD(x) ((struct ehci_qtd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F)) -#define EHCI_ADDR2ITD(x) ((struct ehci_itd_hw *)(uintptr_t)((uint32_t)(x) & ~0x1F)) +/* Structural Parameters. Paragraph 2.2.3 */ -#ifndef CONFIG_USB_EHCI_QH_NUM -#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM -#endif -#ifndef CONFIG_USB_EHCI_QTD_NUM -#define CONFIG_USB_EHCI_QTD_NUM 3 -#endif -#ifndef CONFIG_USB_EHCI_ITD_NUM -#define CONFIG_USB_EHCI_ITD_NUM 5 -#endif -#ifndef CONFIG_USB_EHCI_ISO_NUM -#define CONFIG_USB_EHCI_ISO_NUM 4 -#endif +#define EHCI_HCSPARAMS_NPORTS_SHIFT (0) /* Bit 0-3: Number of physical downstream ports */ +#define EHCI_HCSPARAMS_NPORTS_MASK (15 << EHCI_HCSPARAMS_NPORTS_SHIFT) +#define EHCI_HCSPARAMS_PPC (1 << 4) /* Bit 4: Port Power Control */ +#define EHCI_HCSPARAMS_PRR (1 << 7) /* Bit 7: Port Routing Rules */ +#define EHCI_HCSPARAMS_NPCC_SHIFT (8) /* Bit 8-11: Number of Ports per Companion Controller */ +#define EHCI_HCSPARAMS_NPCC_MASK (15 << EHCI_HCSPARAMS_NPCC_SHIFT) +#define EHCI_HCSPARAMS_NCC_SHIFT (12) /* Bit 12-15: Number of Companion Controllers */ +#define EHCI_HCSPARAMS_NCC_MASK (15 << EHCI_HCSPARAMS_NCC_SHIFT) +#define EHCI_HCSPARAMS_PIND (1 << 16) /* Bit 16: Port Indicators */ +#define EHCI_HCSPARAMS_DBGPORT_SHIFT (20) /* Bit 20-23: Debug Port Number */ +#define EHCI_HCSPARAMS_DBGPORT_MASK (15 << EHCI_HCSPARAMS_DBGPORT_SHIFT) -extern uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port); +/* Capability Parameters. Paragraph 2.2.4 */ -struct ehci_qtd_hw { - struct ehci_qtd hw; - struct usbh_urb *urb; - uint32_t length; -} __attribute__((aligned(32))); +#define EHCI_HCCPARAMS_64BIT (1 << 0) /* Bit 0: 64-bit Addressing Capability */ +#define EHCI_HCCPARAMS_PFLF (1 << 1) /* Bit 1: Programmable Frame List Flag */ +#define EHCI_HCCPARAMS_ASPC (1 << 2) /* Bit 2: Asynchronous Schedule Park Capability */ +#define EHCI_HCCPARAMS_IST_SHIFT (4) /* Bits 4-7: Isochronous Scheduling Threshold */ +#define EHCI_HCCPARAMS_IST_MASK (15 << EHCI_HCCPARAMS_IST_SHIFT) +#define EHCI_HCCPARAMS_EECP_SHIFT (8) /* Bits 8-15: EHCI Extended Capabilities Pointer */ +#define EHCI_HCCPARAMS_EECP_MASK (0xff << EHCI_HCCPARAMS_EECP_SHIFT) -struct ehci_qh_hw { - struct ehci_qh hw; - struct ehci_qtd_hw qtd_pool[CONFIG_USB_EHCI_QTD_NUM]; - uint32_t first_qtd; - struct usbh_urb *urb; - usb_osal_sem_t waitsem; - uint8_t remove_in_iaad; -} __attribute__((aligned(32))); +/* Host Controller Operational Register Bit Definitions *********************/ -struct ehci_itd_hw { - struct ehci_itd hw; - struct usbh_urb *urb; - uint16_t start_frame; - uint8_t mf_unmask; - uint8_t mf_valid; - uint32_t pkt_idx[8]; -} __attribute__((aligned(32))); +/* USB Command. Paragraph 2.3.1 */ -struct ehci_iso_hw -{ - struct ehci_itd_hw itd_pool[CONFIG_USB_EHCI_ITD_NUM]; - uint32_t itd_num; +#define EHCI_USBCMD_RUN (1 << 0) /* Bit 0: Run/Stop */ +#define EHCI_USBCMD_HCRESET (1 << 1) /* Bit 1: Host Controller Reset */ +#define EHCI_USBCMD_FLSIZE_SHIFT (2) /* Bits 2-3: Frame List Size */ +#define EHCI_USBCMD_FLSIZE_MASK (3 << EHCI_USBCMD_FLSIZE_SHIFT) +#define EHCI_USBCMD_FLSIZE_1024 (0 << EHCI_USBCMD_FLSIZE_SHIFT) /* 1024 elements (4096 bytes) */ +#define EHCI_USBCMD_FLSIZE_512 (1 << EHCI_USBCMD_FLSIZE_SHIFT) /* 512 elements (2048 bytes) */ +#define EHCI_USBCMD_FLSIZE_256 (2 << EHCI_USBCMD_FLSIZE_SHIFT) /* 256 elements (1024 bytes) */ +#define EHCI_USBCMD_PSEN (1 << 4) /* Bit 4: Periodic Schedule Enable */ +#define EHCI_USBCMD_ASEN (1 << 5) /* Bit 5: Asynchronous Schedule Enable */ +#define EHCI_USBCMD_IAAD (1 << 6) /* Bit 6: Interrupt on Async Advance Doorbell */ +#define EHCI_USBCMD_LRESET (1 << 7) /* Bit 7: Light Host Controller Reset */ +#define EHCI_USBCMD_ASYNC_PARKCNT_SHIFT (8) /* Bits 8-9: Asynchronous Schedule Park Mode Count */ +#define EHCI_USBCMD_ASYNC_PARKCNT_MASK (3 << EHCI_USBCMD_ASYNC_PARKCNT_SHIFT) +#define EHCI_USBCMD_ASYNC_PARK (1 << 11) /* Bit 11: Asynchronous Schedule Park Mode Enable */ +#define EHCI_USBCMD_ITHRE_SHIFT (16) /* Bits 16-23: Interrupt Threshold Control */ +#define EHCI_USBCMD_ITHRE_MASK (0xff << EHCI_USBCMD_ITHRE_SHIFT) +#define EHCI_USBCMD_ITHRE_1MF (0x01 << EHCI_USBCMD_ITHRE_SHIFT) /* 1 micro-frame */ +#define EHCI_USBCMD_ITHRE_2MF (0x02 << EHCI_USBCMD_ITHRE_SHIFT) /* 2 micro-frames */ +#define EHCI_USBCMD_ITHRE_4MF (0x04 << EHCI_USBCMD_ITHRE_SHIFT) /* 4 micro-frames */ +#define EHCI_USBCMD_ITHRE_8MF (0x08 << EHCI_USBCMD_ITHRE_SHIFT) /* 8 micro-frames (default, 1 ms) */ +#define EHCI_USBCMD_ITHRE_16MF (0x10 << EHCI_USBCMD_ITHRE_SHIFT) /* 16 micro-frames (2 ms) */ +#define EHCI_USBCMD_ITHRE_32MF (0x20 << EHCI_USBCMD_ITHRE_SHIFT) /* 32 micro-frames (4 ms) */ +#define EHCI_USBCMD_ITHRE_64MF (0x40 << EHCI_USBCMD_ITHRE_SHIFT) /* 64 micro-frames (8 ms) */ + +/* USB Status. Paragraph 2.3.2 */ + +#define EHCI_USBSTS_INT (1 << 0) /* Bit 0: USB Interrupt */ +#define EHCI_USBSTS_ERR (1 << 1) /* Bit 1: USB Error Interrupt */ +#define EHCI_USBSTS_PCD (1 << 2) /* Bit 2: Port Change Detect */ +#define EHCI_USBSTS_FLR (1 << 3) /* Bit 3: Frame List Rollover */ +#define EHCI_USBSTS_FATAL (1 << 4) /* Bit 4: Host System Error */ +#define EHCI_USBSTS_IAA (1 << 5) /* Bit 5: Interrupt on Async Advance */ +#define EHCI_USBSTS_HALTED (1 << 12) /* Bit 12: HC Halted */ +#define EHCI_USBSTS_RECLAM (1 << 13) /* Bit 13: Reclamation */ +#define EHCI_USBSTS_PSS (1 << 14) /* Bit 14: Periodic Schedule Status */ +#define EHCI_USBSTS_ASS (1 << 15) /* Bit 15: Asynchronous Schedule Status */ + /* Bits 16-31: Reserved */ + +/* USB Interrupt Enable. Paragraph 2.3.3 */ + +#define EHCI_USBIE_INT (1 << 0) /* Bit 0: USB Interrupt */ +#define EHCI_USBIE_ERR (1 << 1) /* Bit 1: USB Error Interrupt */ +#define EHCI_USBIE_PCD (1 << 2) /* Bit 2: Port Change Detect */ +#define EHCI_USBIE_FLROLL (1 << 3) /* Bit 3: Frame List Rollover */ +#define EHCI_USBIE_FATAL (1 << 4) /* Bit 4: Host System Error */ +#define EHCI_USBIE_IAA (1 << 5) /* Bit 5: Interrupt on Async Advance */ +#define EHCI_USBIE_ALLINTS (0x3f) /* Bits 0-5: All interrupts */ + +/* USB Frame Index. Paragraph 2.3.4 */ + +#define EHCI_FRINDEX_MASK (0x3fff) /* Bits 0-13: Frame index */ + +/* 4G Segment Selector. + * Paragraph 2.3.5, Bits[64:32] of data structure addresses + */ + +/* Frame List Base Address. Paragraph 2.3.6 */ +#define EHCI_PERIODICLISTBASE_MASK (0xfffff000) /* Bits 12-31: Base Address (Low) */ + +/* Next Asynchronous List Address. Paragraph 2.3.7 */ + +#define EHCI_ASYNCLISTADDR_MASK (0xffffffe0) /* Bits 5-31: Link Pointer Low (LPL) */ + +/* Configured Flag Register. Paragraph 2.3.8 */ + +#define EHCI_CONFIGFLAG (1 << 0) /* Bit 0: Configure Flag */ + +/* Port Status/Control, Port 1-n. Paragraph 2.3.9 */ + +#define EHCI_PORTSC_CCS (1 << 0) /* Bit 0: Current Connect Status */ +#define EHCI_PORTSC_CSC (1 << 1) /* Bit 1: Connect Status Change */ +#define EHCI_PORTSC_PE (1 << 2) /* Bit 2: Port Enable */ +#define EHCI_PORTSC_PEC (1 << 3) /* Bit 3: Port Enable/Disable Change */ +#define EHCI_PORTSC_OCA (1 << 4) /* Bit 4: Over-current Active */ +#define EHCI_PORTSC_OCC (1 << 5) /* Bit 5: Over-current Change */ +#define EHCI_PORTSC_RESUME (1 << 6) /* Bit 6: Force Port Resume */ +#define EHCI_PORTSC_SUSPEND (1 << 7) /* Bit 7: Suspend */ +#define EHCI_PORTSC_RESET (1 << 8) /* Bit 8: Port Reset */ +#define EHCI_PORTSC_LSTATUS_SHIFT (10) /* Bits 10-11: Line Status */ +#define EHCI_PORTSC_LSTATUS_MASK (3 << EHCI_PORTSC_LSTATUS_SHIFT) +#define EHCI_PORTSC_LSTATUS_SE0 (0 << EHCI_PORTSC_LSTATUS_SHIFT) /* SE0 Not Low-speed device, perform EHCI reset */ +#define EHCI_PORTSC_LSTATUS_KSTATE (1 << EHCI_PORTSC_LSTATUS_SHIFT) /* K-state Low-speed device, release ownership of port */ +#define EHCI_PORTSC_LSTATUS_JSTATE (2 << EHCI_PORTSC_LSTATUS_SHIFT) /* J-state Not Low-speed device, perform EHCI reset */ +#define EHCI_PORTSC_PP (1 << 12) /* Bit 12: Port Power */ +#define EHCI_PORTSC_OWNER (1 << 13) /* Bit 13: Port Owner */ +#define EHCI_PORTSC_PIC_SHIFT (14) /* Bits 14-15: Port Indicator Control */ +#define EHCI_PORTSC_PIC_MASK (3 << EHCI_PORTSC_PIC_SHIFT) +#define EHCI_PORTSC_PIC_OFF (0 << EHCI_PORTSC_PIC_SHIFT) /* Port indicators are off */ +#define EHCI_PORTSC_PIC_AMBER (1 << EHCI_PORTSC_PIC_SHIFT) /* Amber */ +#define EHCI_PORTSC_PIC_GREEN (2 << EHCI_PORTSC_PIC_SHIFT) /* Green */ +#define EHCI_PORTSC_PTC_SHIFT (16) /* Bits 16-19: Port Test Control */ +#define EHCI_PORTSC_PTC_MASK (15 << EHCI_PORTSC_PTC_SHIFT) +#define EHCI_PORTSC_PTC_DISABLED (0 << EHCI_PORTSC_PTC_SHIFT) /* Test mode not enabled */ +#define EHCI_PORTSC_PTC_JSTATE (1 << EHCI_PORTSC_PTC_SHIFT) /* Test J_STATE */ +#define EHCI_PORTSC_PTC_KSTATE (2 << EHCI_PORTSC_PTC_SHIFT) /* Test K_STATE */ +#define EHCI_PORTSC_PTC_SE0NAK (3 << EHCI_PORTSC_PTC_SHIFT) /* Test SE0_NAK */ +#define EHCI_PORTSC_PTC_PACKET (4 << EHCI_PORTSC_PTC_SHIFT) /* Test Packet */ +#define EHCI_PORTSC_PTC_ENABLE (5 << EHCI_PORTSC_PTC_SHIFT) /* Test FORCE_ENABLE */ +#define EHCI_PORTSC_WKCCNTE (1 << 20) /* Bit 20: Wake on Connect Enable */ +#define EHCI_PORTSC_WKDSCNNTE (1 << 21) /* Bit 21: Wake on Disconnect Enable */ +#define EHCI_PORTSC_WKOCE (1 << 22) /* Bit 22: Wake on Over-current Enable */ + /* Bits 23-31: Reserved */ + +#define EHCI_PORTSC_ALLINTS (EHCI_PORTSC_CSC | EHCI_PORTSC_PEC | \ + EHCI_PORTSC_OCC | EHCI_PORTSC_RESUME) + +/* Queue Head. Paragraph 3.6 */ + +/* Queue Head Horizontal Link Pointer: Queue Head DWord 0. Table 3-19 */ + +#define QH_HLP_END 0x1 + +#define QH_HLP_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0) /* Isochronous Transfer Descriptor */ +#define QH_HLP_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2) /* Queue Head */ +#define QH_HLP_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4) /* Split Transaction Isochronous Transfer Descriptor */ +#define QH_HLP_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6) /* Frame Span Traversal Node */ + +/* Endpoint Characteristics: Queue Head DWord 1. Table 3-19 */ + +#define QH_EPCHAR_DEVADDR_SHIFT (0) /* Bitx 0-6: Device Address */ +#define QH_EPCHAR_DEVADDR_MASK (0x7f << QH_EPCHAR_DEVADDR_SHIFT) +#define QH_EPCHAR_I (1 << 7) /* Bit 7: Inactivate on Next Transaction */ +#define QH_EPCHAR_ENDPT_SHIFT (8) /* Bitx 8-11: Endpoint Number */ +#define QH_EPCHAR_ENDPT_MASK (15 << QH_EPCHAR_ENDPT_SHIFT) +#define QH_EPCHAR_EPS_SHIFT (12) /* Bitx 12-13: Endpoint Speed */ +#define QH_EPCHAR_EPS_MASK (3 << QH_EPCHAR_EPS_SHIFT) +#define QH_EPCHAR_EPS_FULL (0 << QH_EPCHAR_EPS_SHIFT) /* Full-Speed (12Mbs) */ +#define QH_EPCHAR_EPS_LOW (1 << QH_EPCHAR_EPS_SHIFT) /* Low-Speed (1.5Mbs) */ +#define QH_EPCHAR_EPS_HIGH (2 << QH_EPCHAR_EPS_SHIFT) /* High-Speed (480 Mb/s) */ +#define QH_EPCHAR_DTC (1 << 14) /* Bit 14: Data Toggle Control */ +#define QH_EPCHAR_H (1 << 15) /* Bit 15: Head of Reclamation List Flag */ +#define QH_EPCHAR_MAXPKT_SHIFT (16) /* Bitx 16-26: Maximum Packet Length */ +#define QH_EPCHAR_MAXPKT_MASK (0x7ff << QH_EPCHAR_MAXPKT_SHIFT) +#define QH_EPCHAR_C (1 << 27) /* Bit 27: Control Endpoint Flag */ +#define QH_EPCHAR_RL_SHIFT (28) /* Bitx 28-31: Nak Count Reload */ +#define QH_EPCHAR_RL_MASK (15 << QH_EPCHAR_RL_SHIFT) + +/* Endpoint Capabilities: Queue Head DWord 2. Table 3-20 */ + +#define QH_EPCAPS_SSMASK_SHIFT (0) /* Bitx 0-7: Interrupt Schedule Mask (Frame S-mask) */ +#define QH_EPCAPS_SSMASK_MASK (0xff << QH_EPCAPS_SSMASK_SHIFT) +#define QH_EPCAPS_SSMASK(n) ((n) << QH_EPCAPS_SSMASK_SHIFT) +#define QH_EPCAPS_SCMASK_SHIFT (8) /* Bitx 8-15: Split Completion Mask (Frame C-Mask) */ +#define QH_EPCAPS_SCMASK_MASK (0xff << QH_EPCAPS_SCMASK_SHIFT) +#define QH_EPCAPS_SCMASK(n) ((n) << QH_EPCAPS_SCMASK_SHIFT) +#define QH_EPCAPS_HUBADDR_SHIFT (16) /* Bitx 16-22: Hub Address */ +#define QH_EPCAPS_HUBADDR_MASK (0x7f << QH_EPCAPS_HUBADDR_SHIFT) +#define QH_EPCAPS_HUBADDR(n) ((n) << QH_EPCAPS_HUBADDR_SHIFT) +#define QH_EPCAPS_PORT_SHIFT (23) /* Bit 23-29: Port Number */ +#define QH_EPCAPS_PORT_MASK (0x7f << QH_EPCAPS_PORT_SHIFT) +#define QH_EPCAPS_PORT(n) ((n) << QH_EPCAPS_PORT_SHIFT) +#define QH_EPCAPS_MULT_SHIFT (30) /* Bit 30-31: High-Bandwidth Pipe Multiplier */ +#define QH_EPCAPS_MULT_MASK (3 << QH_EPCAPS_MULT_SHIFT) +#define QH_EPCAPS_MULT(n) ((n) << QH_EPCAPS_MULT_SHIFT) + +/* qTD Token. Paragraph 3.5.3 */ + +#define QTD_LIST_END 1 + +#define QTD_TOKEN_STATUS_SHIFT (0) /* Bits 0-7: Status */ +#define QTD_TOKEN_STATUS_MASK (0xff << QTD_TOKEN_STATUS_SHIFT) +#define QTD_TOKEN_STATUS_PINGSTATE (1 << 0) /* Bit 0 Ping State */ +#define QTD_TOKEN_STATUS_ERR (1 << 0) /* Bit 0 Error */ +#define QTD_TOKEN_STATUS_SPLITXSTATE (1 << 1) /* Bit 1 Split Transaction State */ +#define QTD_TOKEN_STATUS_MMF (1 << 2) /* Bit 2 Missed Micro-Frame */ +#define QTD_TOKEN_STATUS_XACTERR (1 << 3) /* Bit 3 Transaction Error */ +#define QTD_TOKEN_STATUS_BABBLE (1 << 4) /* Bit 4 Babble Detected */ +#define QTD_TOKEN_STATUS_DBERR (1 << 5) /* Bit 5 Data Buffer Error */ +#define QTD_TOKEN_STATUS_HALTED (1 << 6) /* Bit 6 Halted */ +#define QTD_TOKEN_STATUS_ACTIVE (1 << 7) /* Bit 7 Active */ +#define QTD_TOKEN_STATUS_ERRORS (0x78 << QTD_TOKEN_STATUS_SHIFT) +#define QTD_TOKEN_PID_SHIFT (8) /* Bits 8-9: PID Code */ +#define QTD_TOKEN_PID_MASK (3 << QTD_TOKEN_PID_SHIFT) +#define QTD_TOKEN_PID_OUT (0 << QTD_TOKEN_PID_SHIFT) /* OUT Token generates token (E1H) */ +#define QTD_TOKEN_PID_IN (1 << QTD_TOKEN_PID_SHIFT) /* IN Token generates token (69H) */ +#define QTD_TOKEN_PID_SETUP (2 << QTD_TOKEN_PID_SHIFT) /* SETUP Token generates token (2DH) */ +#define QTD_TOKEN_CERR_SHIFT (10) /* Bits 10-11: Error Counter */ +#define QTD_TOKEN_CERR_MASK (3 << QTD_TOKEN_CERR_SHIFT) +#define QTD_TOKEN_CPAGE_SHIFT (12) /* Bits 12-14: Current Page */ +#define QTD_TOKEN_CPAGE_MASK (7 << QTD_TOKEN_CPAGE_SHIFT) +#define QTD_TOKEN_IOC (1 << 15) /* Bit 15: Interrupt On Complete */ +#define QTD_TOKEN_NBYTES_SHIFT (16) /* Bits 16-30: Total Bytes to Transfer */ +#define QTD_TOKEN_NBYTES_MASK (0x7fff << QTD_TOKEN_NBYTES_SHIFT) +#define QTD_TOKEN_TOGGLE (1 << 31) /* Bit 31: Data Toggle */ + +/* Isochronous (High-Speed) Transfer Descriptor (iTD). Paragraph 3.3 */ + +/* iTD Next Link Pointer. Paragraph 3.3.1 */ + +#define ITD_NLP_ITD(x) (((uint32_t)(x) & ~0x1F) | 0x0) +#define ITD_NLP_QH(x) (((uint32_t)(x) & ~0x1F) | 0x2) +#define ITD_NLP_SITD(x) (((uint32_t)(x) & ~0x1F) | 0x4) +#define ITD_NLP_FSTN(x) (((uint32_t)(x) & ~0x1F) | 0x6) + +/* iTD Transaction Status and Control List. Paragraph 3.3.2 */ +#define ITD_TSCL_XOFFS_SHIFT (0) /* Bits 0-11: Transaction X offset */ +#define ITD_TSCL_XOFFS_MASK (0xfff << ITD_TSCL_XOFFS_SHIFT) +#define ITD_TSCL_PG_SHIFT (12) /* Bits 12-14: Page select */ +#define ITD_TSCL_PG_MASK (7 << ITD_TSCL_PG_SHIFT) +#define ITD_TSCL_IOC (1 << 15) /* Bit 15: Interrupt On Comp */ +#define ITD_TSCL_LENGTH_SHIFT (16) /* Bits 16-27: Transaction length */ +#define ITD_TSCL_LENGTH_MASK (0xfff << ITD_TSCL_LENGTH_SHIFT) +#define ITD_TSCL_STATUS_SHIFT (28) /* Bits 28-31: Transaction status */ +#define ITD_TSCL_STATUS_MASK (15 << ITD_TSCL_STATUS_SHIFT) +#define ITD_TSCL_STATUS_XACTERR (1 << 28) /* Bit 28: Transaction error */ +#define ITD_TSCL_STATUS_BABBLE (1 << 29) /* Bit 29: Babble Detected */ +#define ITD_TSCL_STATUS_DBERROR (1 << 30) /* Bit 30: Data Buffer Error */ +#define ITD_TSCL_STATUS_ACTIVE (1 << 31) /* Bit 31: Active error */ + +/* iTD Buffer Page Pointer List. Paragraph 3.3.4 */ + +/* iTD Buffer Pointer Page 0. Table 3-4 */ + +#define ITD_BUFPTR0_DEVADDR_SHIFT (0) /* Bits 0-6: Device Address */ +#define ITD_BUFPTR0_DEVADDR_MASK (0x7f << ITD_BUFPTR0_DEVADDR_SHIFT) +#define ITD_BUFPTR0_ENDPT_SHIFT (8) /* Bits 8-11: Endpoint Number */ +#define ITD_BUFPTR0_ENDPT_MASK (15 << ITD_BUFPTR0_ENDPT_SHIFT) + +/* iTD Buffer Pointer Page 1. Table 3-5 */ + +#define ITD_BUFPTR1_MAXPKT_SHIFT (0) /* Bits 0-10: Maximum Packet Size */ +#define ITD_BUFPTR1_MAXPKT_MASK (0x7ff << ITD_BUFPTR1_MAXPKT_SHIFT) +#define ITD_BUFPTR1_DIRIN (1 << 11) /* Bit 11: Direction 1=IN */ +#define ITD_BUFPTR1_DIROUT (0) /* Bit 11: Direction 0=OUT */ + +/* iTD Buffer Pointer Page 2. Table 3-6 */ + +#define ITD_BUFPTR2_MULTI_SHIFT (0) /* Bits 0-1: Multi */ +#define ITD_BUFPTR2_MULTI_MASK (3 << ITD_BUFPTR2_MULTI_SHIFT) +#define ITD_BUFPTR2_MULTI_1 (1 << ITD_BUFPTR2_MULTI_SHIFT) /* One transaction per micro-frame */ +#define ITD_BUFPTR2_MULTI_2 (2 << ITD_BUFPTR2_MULTI_SHIFT) /* Two transactions per micro-frame */ +#define ITD_BUFPTR2_MULTI_3 (3 << ITD_BUFPTR2_MULTI_SHIFT) /* Three transactions per micro-frame */ + +/* Registers ****************************************************************/ + +/* Host Controller Capability Registers. + * This register block must be positioned at a well known address. + */ + +struct ehci_hccr { + volatile uint8_t caplength; /* 0x00: Capability Register Length */ + volatile uint8_t reserved; /* 0x01: reserved */ + volatile uint16_t hciversion; /* 0x02: Interface Version Number */ + volatile uint32_t hcsparams; /* 0x04: Structural Parameters */ + volatile uint32_t hccparams; /* 0x08: Capability Parameters */ + volatile uint8_t hcspportroute[8]; /* 0x0c: Companion Port Route Description */ }; -struct ehci_hcd { - bool ehci_qh_used[CONFIG_USB_EHCI_QH_NUM]; - bool ehci_iso_used[CONFIG_USB_EHCI_ISO_NUM]; - bool ppc; /* Port Power Control */ - bool has_tt; /* if use tt instead of Companion Controller */ - uint8_t n_cc; /* Number of Companion Controller */ - uint8_t n_pcc; /* Number of ports supported per companion host controller */ - uint8_t n_ports; - uint8_t hcor_offset; +/* Host Controller Operational Registers. + * This register block is positioned at an offset of 'caplength' from the + * beginning of the Host Controller Capability Registers. + */ + +struct ehci_hcor { + volatile uint32_t usbcmd; /* 0x00: USB Command */ + volatile uint32_t usbsts; /* 0x04: USB Status */ + volatile uint32_t usbintr; /* 0x08: USB Interrupt Enable */ + volatile uint32_t frindex; /* 0x0c: USB Frame Index */ + volatile uint32_t ctrldssegment; /* 0x10: 4G Segment Selector */ + volatile uint32_t periodiclistbase; /* 0x14: Frame List Base Address */ + volatile uint32_t asynclistaddr; /* 0x18: Next Asynchronous List Address */ +#ifndef CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE + uint32_t reserved[9]; +#endif + volatile uint32_t configflag; /* 0x40: Configured Flag Register */ + volatile uint32_t portsc[15]; /* 0x44: Port Status/Control */ }; -extern struct ehci_hcd g_ehci_hcd[CONFIG_USBHOST_MAX_BUS]; -extern uint32_t g_framelist[CONFIG_USBHOST_MAX_BUS][USB_ALIGN_UP(CONFIG_USB_EHCI_FRAME_LIST_SIZE, 1024)]; +/* USB2 Debug Port Register Interface. + * This register block is normally found via the PCI capabalities. + * In non-PCI implementions, you need apriori information about the + * location of these registers. + */ -int ehci_iso_urb_init(struct usbh_bus *bus, struct usbh_urb *urb); -void ehci_kill_iso_urb(struct usbh_bus *bus, struct usbh_urb *urb); -void ehci_scan_isochronous_list(struct usbh_bus *bus); +struct ehci_debug { + uint32_t psc; /* 0x00: Debug Port Control/Status Register */ + uint32_t pids; /* 0x04: Debug USB PIDs Register */ + uint32_t data[2]; /* 0x08: Debug Data buffer Registers */ + uint32_t addr; /* 0x10: Device Address Register */ +}; -#endif +/* Data Structures **********************************************************/ + +/* Queue Element Transfer Descriptor (qTD). Paragraph 3.5 */ + +struct ehci_qtd { + uint32_t next_qtd; /* 0x00-0x03: Next qTD Pointer */ + uint32_t alt_next_qtd; /* 0x04-0x07: Alternate Next qTD Pointer */ + uint32_t token; /* 0x08-0x0b: qTD Token */ + uint32_t bpl[5]; /* 0x0c-0x1c: Buffer Page Pointer List */ +}; + +#define SIZEOF_EHCI_QTD (32) /* 8*sizeof(uint32_t) */ + +/* Queue Head. Paragraph 3.6 */ + +struct ehci_qh { + uint32_t hlp; /* 0x00-0x03: Queue Head Horizontal Link Pointer */ + uint32_t epchar; /* 0x04-0x07: Endpoint Characteristics */ + uint32_t epcap; /* 0x08-0x0b: Endpoint Capabilities */ + uint32_t curr_qtd; /* 0x0c-0x0f: Current qTD Pointer */ + struct ehci_qtd overlay; /* 0x10-0x2c: Transfer overlay */ +}; + +#define SIZEOF_EHCI_QH (48) /* 4*sizeof(uint32_t) + 32 */ + +/* Isochronous (High-Speed) Transfer Descriptor (iTD). + * Paragraph 3.3. Must be aligned to 32-byte boundaries. + */ + +struct ehci_itd { + uint32_t nlp; /* 0x00-0x03: Next link pointer */ + uint32_t tscl[8]; /* 0x04-0x23: Transaction Status and Control List */ + uint32_t bpl[7]; /* 0x24-0x3c: Buffer Page Pointer List */ +}; + +#define SIZEOF_EHCI_ITD (64) /* 16*sizeof(uint32_t) */ + +/* Split Transaction Isochronous Transfer Descriptor (siTD). Paragraph 3.4 */ + +struct ehci_sitd { + uint32_t nlp; /* 0x00-0x03: Next link pointer */ + uint32_t epchar; /* 0x04-0x07: Endpoint and Transaction Translator Characteristics */ + uint32_t mfsc; /* 0x08-0x0b: Micro-frame Schedule Control */ + uint32_t tsc; /* 0x0c-0x0f: Transfer Status and Control */ + uint32_t bpl[2]; /* 0x10-0x17: Buffer Pointer List */ + uint32_t blp; /* 0x18-0x1b: Back link pointer */ +}; + +#define SIZEOF_EHCI_SITD (28) /* 7*sizeof(uint32_t) */ + +#endif /* USB_HC_EHCI_H */ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/fsdev/usb_dc_fsdev.c b/rt-thread/components/drivers/usb/cherryusb/port/fsdev/usb_dc_fsdev.c index f27e8c6..b3bfb5c 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/fsdev/usb_dc_fsdev.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/fsdev/usb_dc_fsdev.c @@ -117,11 +117,6 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } -int usbd_set_remote_wakeup(uint8_t busid) -{ - return -1; -} - uint8_t usbd_get_port_speed(uint8_t busid) { return USB_SPEED_FULL; @@ -154,8 +149,7 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) case USB_ENDPOINT_TYPE_ISOCHRONOUS: wEpRegVal = USB_EP_ISOCHRONOUS; - USB_LOG_ERR("Do not support iso in fsdev\r\n"); - return -1; + break; default: break; @@ -261,20 +255,8 @@ int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep) int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled) { - uint8_t ep_idx = USB_EP_GET_IDX(ep); - if (USB_EP_DIR_IS_OUT(ep)) { - if (PCD_GET_EP_RX_STATUS(USB, ep_idx) & USB_EP_RX_STALL) { - *stalled = 1; - } else { - *stalled = 0; - } } else { - if (PCD_GET_EP_TX_STATUS(USB, ep_idx) & USB_EP_TX_STALL) { - *stalled = 1; - } else { - *stalled = 0; - } } return 0; } diff --git a/rt-thread/components/drivers/usb/cherryusb/port/hpm/usb_dc_hpm.c b/rt-thread/components/drivers/usb/cherryusb/port/hpm/usb_dc_hpm.c index b663fd9..31ad5b7 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/hpm/usb_dc_hpm.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/hpm/usb_dc_hpm.c @@ -39,7 +39,6 @@ struct hpm_ep_state { /* Driver state */ struct hpm_udc { usb_device_handle_t *handle; - bool is_suspend; struct hpm_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters*/ struct hpm_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */ } g_hpm_udc[CONFIG_USBDEV_MAX_BUS]; @@ -92,7 +91,7 @@ int usb_dc_init(uint8_t busid) } uint32_t int_mask; - int_mask = (USB_USBINTR_UE_MASK | USB_USBINTR_UEE_MASK | USB_USBINTR_SLE_MASK | + int_mask = (USB_USBINTR_UE_MASK | USB_USBINTR_UEE_MASK | USB_USBINTR_PCE_MASK | USB_USBINTR_URE_MASK); usb_device_init(g_hpm_udc[busid].handle, int_mask); @@ -117,21 +116,6 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } -int usbd_set_remote_wakeup(uint8_t busid) -{ - USB_Type *ptr; - - ptr = g_hpm_udc[busid].handle->regs; - - if (!usb_get_suspend_status(ptr)) { - return -1; - } - - usb_force_port_resume(ptr); - - return 0; -} - uint8_t usbd_get_port_speed(uint8_t busid) { uint8_t speed; @@ -275,7 +259,6 @@ void USBD_IRQHandler(uint8_t busid) } if (int_status & intr_reset) { - g_hpm_udc[busid].is_suspend = false; memset(g_hpm_udc[busid].in_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS); memset(g_hpm_udc[busid].out_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS); usbd_event_reset_handler(busid); @@ -284,12 +267,10 @@ void USBD_IRQHandler(uint8_t busid) if (int_status & intr_suspend) { if (usb_device_get_suspend_status(handle)) { + usbd_event_suspend_handler(busid); /* Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. */ if (usb_device_get_address(handle)) { - g_hpm_udc[busid].is_suspend = true; - usbd_event_suspend_handler(busid); } - } else { } } @@ -297,10 +278,6 @@ void USBD_IRQHandler(uint8_t busid) if (!usb_device_get_port_ccs(handle)) { usbd_event_disconnect_handler(busid); } else { - if (g_hpm_udc[busid].is_suspend) { - g_hpm_udc[busid].is_suspend = false; - usbd_event_resume_handler(busid); - } usbd_event_connect_handler(busid); } } @@ -337,7 +314,7 @@ void USBD_IRQHandler(uint8_t busid) transfer_len += p_qtd->expected_bytes - p_qtd->total_bytes; } - if (p_qtd->next == USB_SOC_DCD_QTD_NEXT_INVALID) { + if (p_qtd->next == USB_SOC_DCD_QTD_NEXT_INVALID){ break; } else { p_qtd = (dcd_qtd_t *)p_qtd->next; @@ -358,20 +335,16 @@ void USBD_IRQHandler(uint8_t busid) } } -#if !defined(USBD_USE_CUSTOM_ISR) || !USBD_USE_CUSTOM_ISR - -SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usbd0) void isr_usbd0(void) { USBD_IRQHandler(_dcd_busid[0]); } +SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usbd0) #ifdef HPM_USB1_BASE -SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbd1) void isr_usbd1(void) { USBD_IRQHandler(_dcd_busid[1]); } -#endif - -#endif +SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usbd1) +#endif \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/kinetis/README.md b/rt-thread/components/drivers/usb/cherryusb/port/kinetis/README.md deleted file mode 100644 index f51c9a6..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/kinetis/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Note - -## Support Chip List - -### NXP - -Modify USB_NOCACHE_RAM_SECTION - -``` -#define USB_NOCACHE_RAM_SECTION __attribute__((section(".NonCacheable"))) -``` - -- MCXC444/MCXA153 (device only) -- MCXN947 - -### MM32 - -- MM32F3/MM32F5 diff --git a/rt-thread/components/drivers/usb/cherryusb/port/kinetis/usb_dc_kinetis.c b/rt-thread/components/drivers/usb/cherryusb/port/kinetis/usb_dc_kinetis.c deleted file mode 100644 index bd2b287..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/kinetis/usb_dc_kinetis.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbd_core.h" -#include "usb_kinetis_reg.h" - -#define USB_OTG_DEV ((KINETIS_TypeDef *)g_usbdev_bus[busid].reg_base) - -/* Endpoint state */ -struct kinetis_ep_state { - uint16_t ep_mps; /* Endpoint max packet size */ - uint8_t ep_type; /* Endpoint type */ - uint8_t ep_stalled; /* Endpoint stall flag */ - uint8_t ep_enable; /* Endpoint enable */ - bool ep_odd; /* Endpoint odd */ - uint8_t *xfer_buf; - uint32_t xfer_len; - uint32_t actual_xfer_len; -}; - -/* Driver state */ -struct kinetis_udc { - uint8_t dev_addr; - struct kinetis_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/ - struct kinetis_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */ -} g_kinetis_udc[CONFIG_USBDEV_MAX_BUS]; - -USB_NOCACHE_RAM_SECTION __attribute__((aligned(512))) kinetis_bd_table_t g_kinetis_bdt[CONFIG_USBDEV_MAX_BUS]; -USB_NOCACHE_RAM_SECTION __attribute__((aligned(32))) uint8_t setup_packet[CONFIG_USBDEV_MAX_BUS][8]; - -static int kinetis_start_transfer(uint8_t busid, uint8_t ep, uint8_t *buffer, uint16_t buflen) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep); - uint8_t dir; - uint8_t odd; - uint16_t ep_mps; - kinetis_bd_t *bd; - kinetis_bd_t *next; - - if (USB_EP_DIR_IS_OUT(ep)) { - dir = 0; - odd = g_kinetis_udc[busid].out_ep[ep_idx].ep_odd; - ep_mps = g_kinetis_udc[busid].out_ep[ep_idx].ep_mps; - } else { - dir = 1; - odd = g_kinetis_udc[busid].in_ep[ep_idx].ep_odd; - ep_mps = g_kinetis_udc[busid].in_ep[ep_idx].ep_mps; - } - - bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd]; - - if (bd->own) { - USB_LOG_INFO("ep%02x is busy\r\n", ep); - return -1; - } - - bd->bc = buflen >= ep_mps ? ep_mps : buflen; - bd->addr = (uint32_t)buffer; - bd->own = 1; - return 0; -} - -static void kinetis_read_setup(uint8_t busid) -{ - uint8_t out_odd = g_kinetis_udc[busid].out_ep[0].ep_odd; - uint8_t in_odd = g_kinetis_udc[busid].in_ep[0].ep_odd; - - if (g_kinetis_bdt[busid].table[0][0][out_odd].own) { - USB_LOG_INFO("ep0 is busy\r\n"); - return; - } - - g_kinetis_bdt[busid].table[0][0][out_odd].data = 0; - g_kinetis_bdt[busid].table[0][0][out_odd ^ 1].data = 1; - g_kinetis_bdt[busid].table[0][1][in_odd].data = 1; - g_kinetis_bdt[busid].table[0][1][in_odd ^ 1].data = 0; - - kinetis_start_transfer(busid, USB_CONTROL_OUT_EP0, setup_packet[busid], 8); -} - -__WEAK void usb_dc_low_level_init(uint8_t busid) -{ -} - -__WEAK void usb_dc_low_level_deinit(uint8_t busid) -{ -} - -int usb_dc_init(uint8_t busid) -{ - usb_dc_low_level_init(busid); - - memset(&g_kinetis_udc[busid], 0, sizeof(g_kinetis_udc[busid])); - - USB_OTG_DEV->BDTPAGE1 = (uint8_t)((uintptr_t)&g_kinetis_bdt[busid] >> 8); - USB_OTG_DEV->BDTPAGE2 = (uint8_t)((uintptr_t)&g_kinetis_bdt[busid] >> 16); - USB_OTG_DEV->BDTPAGE3 = (uint8_t)((uintptr_t)&g_kinetis_bdt[busid] >> 24); - - USB_OTG_DEV->INTEN = USB_INTEN_USBRSTEN_MASK | USB_INTEN_TOKDNEEN_MASK | - USB_INTEN_SLEEPEN_MASK | USB_INTEN_RESUMEEN_MASK | - USB_INTEN_ERROREN_MASK; - - USB_OTG_DEV->CTL |= USB_CTL_USBENSOFEN_MASK; - return 0; -} - -int usb_dc_deinit(uint8_t busid) -{ - usb_dc_low_level_deinit(busid); - return 0; -} - -int usbd_set_address(uint8_t busid, const uint8_t addr) -{ - g_kinetis_udc[busid].dev_addr = addr; - - if (addr == 0) { - USB_OTG_DEV->ADDR = 0; - } - return 0; -} - -int usbd_set_remote_wakeup(uint8_t busid) -{ - USB_OTG_DEV->CTL |= USB_CTL_RESUME_MASK; - - usbd_kinetis_delay_ms(10); - - USB_OTG_DEV->CTL &= ~USB_CTL_RESUME_MASK; - - return 0; -} - -uint8_t usbd_get_port_speed(uint8_t busid) -{ - return USB_SPEED_FULL; -} - -int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress); - uint8_t odd; - uint8_t dir; - kinetis_bd_t *bd; - uint8_t regval; - - /* Must not exceed max endpoint number */ - if (ep_idx >= CONFIG_USBDEV_EP_NUM) { - return -1; - } - - if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) { - g_kinetis_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); - g_kinetis_udc[busid].out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); - g_kinetis_udc[busid].out_ep[ep_idx].ep_enable = true; - - dir = 0; - odd = g_kinetis_udc[busid].out_ep[ep_idx].ep_odd; - } else { - g_kinetis_udc[busid].in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize); - g_kinetis_udc[busid].in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes); - g_kinetis_udc[busid].in_ep[ep_idx].ep_enable = true; - - dir = 1; - odd = g_kinetis_udc[busid].in_ep[ep_idx].ep_odd; - } - - if (ep_idx != 0) { - regval = USB_ENDPT_EPCTLDIS_MASK; - regval |= (USB_GET_ENDPOINT_TYPE(ep->bmAttributes) != USB_ENDPOINT_TYPE_ISOCHRONOUS) ? USB_ENDPT_EPHSHK_MASK : 0; - regval |= dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; - USB_OTG_DEV->ENDPOINT[ep_idx].ENDPT |= regval; - - if (USB_GET_ENDPOINT_TYPE(ep->bmAttributes) != USB_ENDPOINT_TYPE_ISOCHRONOUS) { - bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd]; - bd->dts = 1; - bd->data = 0; - - bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd ^ 1]; - bd->dts = 1; - bd->data = 1; - } - } - - return 0; -} - -int usbd_ep_close(uint8_t busid, const uint8_t ep) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep); - uint8_t dir; - kinetis_bd_t *bd; - - if (USB_EP_DIR_IS_OUT(ep)) { - g_kinetis_udc[busid].out_ep[ep_idx].ep_enable = false; - dir = 0; - } else { - g_kinetis_udc[busid].in_ep[ep_idx].ep_enable = false; - dir = 1; - } - - bd = &g_kinetis_bdt[busid].table[ep_idx][dir][0]; - bd->head = 0; - - bd = &g_kinetis_bdt[busid].table[ep_idx][dir][1]; - bd->head = 0; - - USB_OTG_DEV->ENDPOINT[ep_idx].ENDPT &= ~(dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK); - return 0; -} - -int usbd_ep_set_stall(uint8_t busid, const uint8_t ep) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep); - kinetis_bd_t *bd; - uint8_t odd; - uint8_t dir; - - if (0 == ep_idx) { - USB_OTG_DEV->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPSTALL_MASK; - - if (ep_idx == 0) { - kinetis_read_setup(busid); - } - } else { - if (USB_EP_DIR_IS_OUT(ep)) { - dir = 0; - odd = g_kinetis_udc[busid].out_ep[ep_idx].ep_odd; - } else { - dir = 1; - odd = g_kinetis_udc[busid].in_ep[ep_idx].ep_odd; - } - - bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd]; - - bd->bdt_stall = 1; - bd->own = 1; - } - return 0; -} - -int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep); - kinetis_bd_t *bd; - uint8_t odd; - uint8_t dir; - - if (USB_EP_DIR_IS_OUT(ep)) { - dir = 0; - odd = g_kinetis_udc[busid].out_ep[ep_idx].ep_odd; - } else { - dir = 1; - odd = g_kinetis_udc[busid].in_ep[ep_idx].ep_odd; - } - - bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd]; - - bd->own = 0; - bd->bdt_stall = 0; - bd->data = 0; - - bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd ^ 1]; - bd->data = 1; - - uint8_t regval = USB_OTG_DEV->ENDPOINT[ep_idx].ENDPT; - if (regval & USB_ENDPT_EPSTALL_MASK) { - USB_OTG_DEV->ENDPOINT[ep_idx].ENDPT = regval & ~USB_ENDPT_EPSTALL_MASK; - } - - return 0; -} - -int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep); - - uint8_t regval = USB_OTG_DEV->ENDPOINT[ep_idx].ENDPT; - if (regval & USB_ENDPT_EPSTALL_MASK) { - *stalled = 1; - } else { - *stalled = 0; - } - - return 0; -} - -int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, - uint32_t data_len) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep); - - if (!data && data_len) { - return -1; - } - if (!g_kinetis_udc[busid].in_ep[ep_idx].ep_enable) { - return -2; - } - - g_kinetis_udc[busid].in_ep[ep_idx].xfer_buf = (uint8_t *)data; - g_kinetis_udc[busid].in_ep[ep_idx].xfer_len = data_len; - g_kinetis_udc[busid].in_ep[ep_idx].actual_xfer_len = 0; - - return kinetis_start_transfer(busid, ep, (uint8_t *)data, MIN(data_len, g_kinetis_udc[busid].in_ep[ep_idx].ep_mps)); -} - -int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, - uint32_t data_len) -{ - uint8_t ep_idx = USB_EP_GET_IDX(ep); - - if (!data && data_len) { - return -1; - } - if (!g_kinetis_udc[busid].out_ep[ep_idx].ep_enable) { - return -2; - } - - g_kinetis_udc[busid].out_ep[ep_idx].xfer_buf = (uint8_t *)data; - g_kinetis_udc[busid].out_ep[ep_idx].xfer_len = data_len; - g_kinetis_udc[busid].out_ep[ep_idx].actual_xfer_len = 0; - - return kinetis_start_transfer(busid, ep, (uint8_t *)data, MIN(data_len, g_kinetis_udc[busid].out_ep[ep_idx].ep_mps)); -} - -void USBD_IRQHandler(uint8_t busid) -{ - uint8_t s; - uint8_t pid; - uint8_t ep_idx; - uint8_t dir; - uint8_t odd; - uint16_t bc; - uint8_t is = USB_OTG_DEV->ISTAT; - uint8_t mask = USB_OTG_DEV->INTEN; - kinetis_bd_t *bd; - - USB_OTG_DEV->ISTAT = is & ~mask; - is &= mask; - - if (is & USB_ISTAT_ERROR_MASK) { - uint32_t es = USB_OTG_DEV->ERRSTAT; - USB_OTG_DEV->ERRSTAT = es; - USB_OTG_DEV->ISTAT = is; - } - - if (is & USB_ISTAT_USBRST_MASK) { - USB_OTG_DEV->ISTAT = is; - USB_OTG_DEV->CTL |= USB_CTL_ODDRST_MASK; - USB_OTG_DEV->ADDR = 0; - - USB_OTG_DEV->ENDPOINT[0].ENDPT = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; - for (uint8_t i = 1; i < 16; i++) { - USB_OTG_DEV->ENDPOINT[i].ENDPT = 0; - } - - memset(&g_kinetis_bdt[busid], 0, sizeof(g_kinetis_bdt[busid])); - memset(g_kinetis_udc[busid].in_ep, 0, sizeof(struct kinetis_ep_state) * CONFIG_USBDEV_EP_NUM); - memset(g_kinetis_udc[busid].out_ep, 0, sizeof(struct kinetis_ep_state) * CONFIG_USBDEV_EP_NUM); - usbd_event_reset_handler(busid); - - kinetis_read_setup(busid); - - USB_OTG_DEV->CTL &= ~USB_CTL_ODDRST_MASK; - } - - if (is & USB_ISTAT_SLEEP_MASK) { - USB_OTG_DEV->ISTAT = USB_ISTAT_SLEEP_MASK; - } - - if (is & USB_ISTAT_RESUME_MASK) { - USB_OTG_DEV->ISTAT = USB_ISTAT_RESUME_MASK; - } - - if (is & USB_ISTAT_SOFTOK_MASK) { - USB_OTG_DEV->ISTAT = USB_ISTAT_SOFTOK_MASK; - } - - if (is & USB_ISTAT_STALL_MASK) { - USB_OTG_DEV->ISTAT = USB_ISTAT_STALL_MASK; - } - - if (is & USB_ISTAT_TOKDNE_MASK) { - s = USB_OTG_DEV->STAT; - USB_OTG_DEV->ISTAT = USB_ISTAT_TOKDNE_MASK; /* must be cleared after get STAT */ - - ep_idx = (s & USB_STAT_ENDP_MASK) >> USB_STAT_ENDP_SHIFT; - dir = (s & USB_STAT_TX_MASK) >> USB_STAT_TX_SHIFT; - odd = (s & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT; - - bd = &g_kinetis_bdt[busid].table[ep_idx][dir][odd]; - - pid = bd->tok_pid; - bc = bd->bc; - - bd->bdt_stall = 0; - bd->dts = 1; - bd->ninc = 0; - bd->keep = 0; - - if (dir) { - g_kinetis_udc[busid].in_ep[ep_idx].ep_odd = odd ^ 1; - } else { - g_kinetis_udc[busid].out_ep[ep_idx].ep_odd = odd ^ 1; - } - - if (pid == USB_TOKEN_PID_SETUP) { - USB_OTG_DEV->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; - usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)bd->addr); - return; - } - - if (dir) { - g_kinetis_udc[busid].in_ep[ep_idx].xfer_buf += bc; - g_kinetis_udc[busid].in_ep[ep_idx].xfer_len -= bc; - g_kinetis_udc[busid].in_ep[ep_idx].actual_xfer_len += bc; - - if (g_kinetis_udc[busid].in_ep[ep_idx].xfer_len == 0) { - usbd_event_ep_in_complete_handler(busid, ep_idx | 0x80, g_kinetis_udc[busid].in_ep[ep_idx].actual_xfer_len); - } else { - kinetis_start_transfer(busid, ep_idx | 0x80, g_kinetis_udc[busid].in_ep[ep_idx].xfer_buf, - MIN(g_kinetis_udc[busid].in_ep[ep_idx].xfer_len, g_kinetis_udc[busid].in_ep[ep_idx].ep_mps)); - } - } else { - g_kinetis_udc[busid].out_ep[ep_idx].xfer_buf += bc; - g_kinetis_udc[busid].out_ep[ep_idx].xfer_len -= bc; - g_kinetis_udc[busid].out_ep[ep_idx].actual_xfer_len += bc; - - if ((bc < g_kinetis_udc[busid].out_ep[ep_idx].ep_mps) || (g_kinetis_udc[busid].out_ep[ep_idx].xfer_len == 0)) { - usbd_event_ep_out_complete_handler(busid, ep_idx, g_kinetis_udc[busid].out_ep[ep_idx].actual_xfer_len); - } else { - kinetis_start_transfer(busid, ep_idx, g_kinetis_udc[busid].out_ep[ep_idx].xfer_buf, - MIN(g_kinetis_udc[busid].out_ep[ep_idx].xfer_len, g_kinetis_udc[busid].out_ep[ep_idx].ep_mps)); - } - } - - if ((bc == 0) && (ep_idx == 0)) { - if ((g_kinetis_udc[busid].dev_addr > 0) && dir) { - USB_OTG_DEV->ADDR = g_kinetis_udc[busid].dev_addr; - g_kinetis_udc[busid].dev_addr = 0; - } - - kinetis_read_setup(busid); - } - } -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/kinetis/usb_glue_mcx.c b/rt-thread/components/drivers/usb/cherryusb/port/kinetis/usb_glue_mcx.c deleted file mode 100644 index 4460779..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/kinetis/usb_glue_mcx.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "usbd_core.h" -#include "fsl_common.h" -#include "usb_kinetis_reg.h" - -#define USB_OTG_DEV ((KINETIS_MCX_TypeDef *)g_usbdev_bus[busid].reg_base) - -#if defined(MCXC444_H_) -#define USBD_IRQ USB0_IRQHandler -void USB_ClockInit(void) -{ - SystemCoreClockUpdate(); - CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U); -} -#elif defined(MCXA153_H_) -#define USBD_IRQ USB0_IRQHandler -void USB_ClockInit(void) -{ - RESET_PeripheralReset(kUSB0_RST_SHIFT_RSTn); - CLOCK_EnableUsbfsClock(); -} -#elif defined(MCXN947_CM33_CORE0_H_) -#define USBD_IRQ USB0_FS_IRQHandler -void USB_ClockInit(void) -{ - CLOCK_AttachClk(kCLK_48M_to_USB0); - CLOCK_EnableClock(kCLOCK_Usb0Ram); - CLOCK_EnableClock(kCLOCK_Usb0Fs); - CLOCK_EnableUsbfsClock(); -} -#else -#error "Unsupported MCU with Kinetis IP" -#endif - -void USBD_IRQ(void) -{ - extern void USBD_IRQHandler(uint8_t busid); - USBD_IRQHandler(0); -} - -void usb_dc_low_level_init(uint8_t busid) -{ - USB_ClockInit(); - - uint8_t irqNumber; - - uint8_t usbDeviceKhciIrq[] = USB_IRQS; - irqNumber = usbDeviceKhciIrq[0]; - - /* Install isr, set priority, and enable IRQ. */ - NVIC_SetPriority((IRQn_Type)irqNumber, 3); - EnableIRQ((IRQn_Type)irqNumber); - - USB_OTG_DEV->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; - while (USB_OTG_DEV->USBTRC0 & USB_USBTRC0_USBRESET_MASK) - ; - - USB_OTG_DEV->USBTRC0 |= USB_USBTRC0_VREGIN_STS(1); /* software must set this bit to 1 */ - USB_OTG_DEV->USBCTRL = 0; - USB_OTG_DEV->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK; -} - -void usb_dc_low_level_deinit(uint8_t busid) -{ - USB_OTG_DEV->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK; - DisableIRQ((IRQn_Type)USB0_FS_IRQn); -} - -void usbd_kinetis_delay_ms(uint8_t ms) -{ -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/kinetis/usb_hc_kinetis.c b/rt-thread/components/drivers/usb/cherryusb/port/kinetis/usb_hc_kinetis.c deleted file mode 100644 index 30404ce..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/kinetis/usb_hc_kinetis.c +++ /dev/null @@ -1 +0,0 @@ -TODO \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/kinetis/usb_kinetis_reg.h b/rt-thread/components/drivers/usb/cherryusb/port/kinetis/usb_kinetis_reg.h deleted file mode 100644 index b2720a6..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/kinetis/usb_kinetis_reg.h +++ /dev/null @@ -1,1487 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef __USB_KINETIS_REG_H__ -#define __USB_KINETIS_REG_H__ - -#define __I volatile const /* Define "read-only" permission */ -#define __IO volatile /* Define "read-write" permission */ - -/* ---------------------------------------------------------------------------- - -- USB Peripheral Access Layer - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup USB_Peripheral_Access_Layer USB Peripheral Access Layer - * @{ - */ - -/** USB - Register Layout Typedef */ -typedef struct { - __I uint8_t PERID; /**< Peripheral ID, offset: 0x0 */ - uint8_t RESERVED_0[3]; - __I uint8_t IDCOMP; /**< Peripheral ID Complement, offset: 0x4 */ - uint8_t RESERVED_1[3]; - __I uint8_t REV; /**< Peripheral Revision, offset: 0x8 */ - uint8_t RESERVED_2[3]; - __I uint8_t ADDINFO; /**< Peripheral Additional Information, offset: 0xC */ - uint8_t RESERVED_3[3]; - __IO uint8_t OTGISTAT; /**< OTG Interrupt Status, offset: 0x10 */ - uint8_t RESERVED_4[3]; - __IO uint8_t OTGICR; /**< OTG Interrupt Control, offset: 0x14 */ - uint8_t RESERVED_5[3]; - __I uint8_t OTGSTAT; /**< OTG Status, offset: 0x18 */ - uint8_t RESERVED_6[3]; - __IO uint8_t OTGCTL; /**< OTG Control, offset: 0x1C */ - uint8_t RESERVED_7[99]; - __IO uint8_t ISTAT; /**< Interrupt Status, offset: 0x80 */ - uint8_t RESERVED_8[3]; - __IO uint8_t INTEN; /**< Interrupt Enable, offset: 0x84 */ - uint8_t RESERVED_9[3]; - __IO uint8_t ERRSTAT; /**< Error Interrupt Status, offset: 0x88 */ - uint8_t RESERVED_10[3]; - __IO uint8_t ERREN; /**< Error Interrupt Enable, offset: 0x8C */ - uint8_t RESERVED_11[3]; - __I uint8_t STAT; /**< Status, offset: 0x90 */ - uint8_t RESERVED_12[3]; - __IO uint8_t CTL; /**< Control, offset: 0x94 */ - uint8_t RESERVED_13[3]; - __IO uint8_t ADDR; /**< Address, offset: 0x98 */ - uint8_t RESERVED_14[3]; - __IO uint8_t BDTPAGE1; /**< BDT Page 1, offset: 0x9C */ - uint8_t RESERVED_15[3]; - __I uint8_t FRMNUML; /**< Frame Number Register Low, offset: 0xA0 */ - uint8_t RESERVED_16[3]; - __I uint8_t FRMNUMH; /**< Frame Number Register High, offset: 0xA4 */ - uint8_t RESERVED_17[3]; - __IO uint8_t TOKEN; /**< Token, offset: 0xA8 */ - uint8_t RESERVED_18[3]; - __IO uint8_t SOFTHLD; /**< SOF Threshold, offset: 0xAC */ - uint8_t RESERVED_19[3]; - __IO uint8_t BDTPAGE2; /**< BDT Page 2, offset: 0xB0 */ - uint8_t RESERVED_20[3]; - __IO uint8_t BDTPAGE3; /**< BDT Page 3, offset: 0xB4 */ - uint8_t RESERVED_21[11]; - struct { /* offset: 0xC0, array step: 0x4 */ - __IO uint8_t ENDPT; /**< Endpoint Control, array offset: 0xC0, array step: 0x4 */ - uint8_t RESERVED_0[3]; - } ENDPOINT[16]; -} KINETIS_TypeDef; - -/* ---------------------------------------------------------------------------- - -- USB Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup USB_Register_Masks USB Register Masks - * @{ - */ - -/*! @name PERID - Peripheral ID */ -/*! @{ */ - -#define USB_PERID_ID_MASK (0x3FU) -#define USB_PERID_ID_SHIFT (0U) -/*! ID - Peripheral Identification */ -#define USB_PERID_ID(x) (((uint8_t)(((uint8_t)(x)) << USB_PERID_ID_SHIFT)) & USB_PERID_ID_MASK) -/*! @} */ - -/*! @name IDCOMP - Peripheral ID Complement */ -/*! @{ */ - -#define USB_IDCOMP_NID_MASK (0x3FU) -#define USB_IDCOMP_NID_SHIFT (0U) -/*! NID - Negative Peripheral ID */ -#define USB_IDCOMP_NID(x) (((uint8_t)(((uint8_t)(x)) << USB_IDCOMP_NID_SHIFT)) & USB_IDCOMP_NID_MASK) -/*! @} */ - -/*! @name REV - Peripheral Revision */ -/*! @{ */ - -#define USB_REV_REV_MASK (0xFFU) -#define USB_REV_REV_SHIFT (0U) -/*! REV - Revision */ -#define USB_REV_REV(x) (((uint8_t)(((uint8_t)(x)) << USB_REV_REV_SHIFT)) & USB_REV_REV_MASK) -/*! @} */ - -/*! @name ADDINFO - Peripheral Additional Information */ -/*! @{ */ - -#define USB_ADDINFO_IEHOST_MASK (0x1U) -#define USB_ADDINFO_IEHOST_SHIFT (0U) -/*! IEHOST - Host Mode Enable - * 0b0..Disabled - * 0b1..Enabled - */ -#define USB_ADDINFO_IEHOST(x) (((uint8_t)(((uint8_t)(x)) << USB_ADDINFO_IEHOST_SHIFT)) & USB_ADDINFO_IEHOST_MASK) -/*! @} */ - -/*! @name OTGISTAT - OTG Interrupt Status */ -/*! @{ */ - -#define USB_OTGISTAT_LINE_STATE_CHG_MASK (0x20U) -#define USB_OTGISTAT_LINE_STATE_CHG_SHIFT (5U) -/*! LINE_STATE_CHG - Line State Change Interrupt Flag - * 0b0..Interrupt did not occur - * 0b1..Interrupt occurred - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_OTGISTAT_LINE_STATE_CHG(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_LINE_STATE_CHG_SHIFT)) & USB_OTGISTAT_LINE_STATE_CHG_MASK) - -#define USB_OTGISTAT_ONEMSEC_MASK (0x40U) -#define USB_OTGISTAT_ONEMSEC_SHIFT (6U) -/*! ONEMSEC - One Millisecond Timer Timeout Flag - * 0b0..Not timed out - * 0b1..Timed out - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_OTGISTAT_ONEMSEC(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_ONEMSEC_SHIFT)) & USB_OTGISTAT_ONEMSEC_MASK) -/*! @} */ - -/*! @name OTGICR - OTG Interrupt Control */ -/*! @{ */ - -#define USB_OTGICR_LINESTATEEN_MASK (0x20U) -#define USB_OTGICR_LINESTATEEN_SHIFT (5U) -/*! LINESTATEEN - Line State Change Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_OTGICR_LINESTATEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_LINESTATEEN_SHIFT)) & USB_OTGICR_LINESTATEEN_MASK) - -#define USB_OTGICR_ONEMSECEN_MASK (0x40U) -#define USB_OTGICR_ONEMSECEN_SHIFT (6U) -/*! ONEMSECEN - 1-Millisecond Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_OTGICR_ONEMSECEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_ONEMSECEN_SHIFT)) & USB_OTGICR_ONEMSECEN_MASK) -/*! @} */ - -/*! @name OTGSTAT - OTG Status */ -/*! @{ */ - -#define USB_OTGSTAT_LINESTATESTABLE_MASK (0x20U) -#define USB_OTGSTAT_LINESTATESTABLE_SHIFT (5U) -/*! LINESTATESTABLE - Line State Stable - * 0b0..Unstable - * 0b1..Stable - */ -#define USB_OTGSTAT_LINESTATESTABLE(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_LINESTATESTABLE_SHIFT)) & USB_OTGSTAT_LINESTATESTABLE_MASK) - -#define USB_OTGSTAT_ONEMSEC_MASK (0x40U) -#define USB_OTGSTAT_ONEMSEC_SHIFT (6U) -/*! ONEMSEC - Reserved for 1 ms count */ -#define USB_OTGSTAT_ONEMSEC(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_ONEMSEC_SHIFT)) & USB_OTGSTAT_ONEMSEC_MASK) -/*! @} */ - -/*! @name OTGCTL - OTG Control */ -/*! @{ */ - -#define USB_OTGCTL_OTGEN_MASK (0x4U) -#define USB_OTGCTL_OTGEN_SHIFT (2U) -/*! OTGEN - On-The-Go Pullup and Pulldown Resistor Enable - * 0b0..If USBENSOFEN is 1 and HOSTMODEEN is 0 in the Control Register (CTL), then the D+ Data line pullup - * resistors are enabled. If HOSTMODEEN is 1, then the D+ and D- Data line pulldown resistors are engaged. - * 0b1..Uses the pullup and pulldown controls in this register. - */ -#define USB_OTGCTL_OTGEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_OTGEN_SHIFT)) & USB_OTGCTL_OTGEN_MASK) - -#define USB_OTGCTL_DMLOW_MASK (0x10U) -#define USB_OTGCTL_DMLOW_SHIFT (4U) -/*! DMLOW - D- Data Line Pulldown Resistor Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_OTGCTL_DMLOW(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_DMLOW_SHIFT)) & USB_OTGCTL_DMLOW_MASK) - -#define USB_OTGCTL_DPLOW_MASK (0x20U) -#define USB_OTGCTL_DPLOW_SHIFT (5U) -/*! DPLOW - D+ Data Line pulldown Resistor Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_OTGCTL_DPLOW(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_DPLOW_SHIFT)) & USB_OTGCTL_DPLOW_MASK) - -#define USB_OTGCTL_DPHIGH_MASK (0x80U) -#define USB_OTGCTL_DPHIGH_SHIFT (7U) -/*! DPHIGH - D+ Data Line Pullup Resistor Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_OTGCTL_DPHIGH(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_DPHIGH_SHIFT)) & USB_OTGCTL_DPHIGH_MASK) -/*! @} */ - -/*! @name ISTAT - Interrupt Status */ -/*! @{ */ - -#define USB_ISTAT_USBRST_MASK (0x1U) -#define USB_ISTAT_USBRST_SHIFT (0U) -/*! USBRST - USB Reset Flag - * 0b0..Not detected - * 0b1..Detected - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ISTAT_USBRST(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_USBRST_SHIFT)) & USB_ISTAT_USBRST_MASK) - -#define USB_ISTAT_ERROR_MASK (0x2U) -#define USB_ISTAT_ERROR_SHIFT (1U) -/*! ERROR - Error Flag - * 0b0..Error did not occur - * 0b1..Error occurred - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ISTAT_ERROR(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_ERROR_SHIFT)) & USB_ISTAT_ERROR_MASK) - -#define USB_ISTAT_SOFTOK_MASK (0x4U) -#define USB_ISTAT_SOFTOK_SHIFT (2U) -/*! SOFTOK - Start Of Frame (SOF) Token Flag - * 0b0..Did not receive - * 0b1..Received - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ISTAT_SOFTOK(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_SOFTOK_SHIFT)) & USB_ISTAT_SOFTOK_MASK) - -#define USB_ISTAT_TOKDNE_MASK (0x8U) -#define USB_ISTAT_TOKDNE_SHIFT (3U) -/*! TOKDNE - Current Token Processing Flag - * 0b0..Not processed - * 0b1..Processed - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ISTAT_TOKDNE(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_TOKDNE_SHIFT)) & USB_ISTAT_TOKDNE_MASK) - -#define USB_ISTAT_SLEEP_MASK (0x10U) -#define USB_ISTAT_SLEEP_SHIFT (4U) -/*! SLEEP - Sleep Flag - * 0b0..Interrupt did not occur - * 0b1..Interrupt occurred - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ISTAT_SLEEP(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_SLEEP_SHIFT)) & USB_ISTAT_SLEEP_MASK) - -#define USB_ISTAT_RESUME_MASK (0x20U) -#define USB_ISTAT_RESUME_SHIFT (5U) -/*! RESUME - Resume Flag - * 0b0..Interrupt did not occur - * 0b1..Interrupt occurred - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ISTAT_RESUME(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_RESUME_SHIFT)) & USB_ISTAT_RESUME_MASK) - -#define USB_ISTAT_ATTACH_MASK (0x40U) -#define USB_ISTAT_ATTACH_SHIFT (6U) -/*! ATTACH - Attach Interrupt Flag - * 0b0..Not detected - * 0b1..Detected - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ISTAT_ATTACH(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_ATTACH_SHIFT)) & USB_ISTAT_ATTACH_MASK) - -#define USB_ISTAT_STALL_MASK (0x80U) -#define USB_ISTAT_STALL_SHIFT (7U) -/*! STALL - Stall Interrupt Flag - * 0b0..Interrupt did not occur - * 0b1..Interrupt occurred - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ISTAT_STALL(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_STALL_SHIFT)) & USB_ISTAT_STALL_MASK) -/*! @} */ - -/*! @name INTEN - Interrupt Enable */ -/*! @{ */ - -#define USB_INTEN_USBRSTEN_MASK (0x1U) -#define USB_INTEN_USBRSTEN_SHIFT (0U) -/*! USBRSTEN - USBRST Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_INTEN_USBRSTEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_USBRSTEN_SHIFT)) & USB_INTEN_USBRSTEN_MASK) - -#define USB_INTEN_ERROREN_MASK (0x2U) -#define USB_INTEN_ERROREN_SHIFT (1U) -/*! ERROREN - ERROR Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_INTEN_ERROREN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_ERROREN_SHIFT)) & USB_INTEN_ERROREN_MASK) - -#define USB_INTEN_SOFTOKEN_MASK (0x4U) -#define USB_INTEN_SOFTOKEN_SHIFT (2U) -/*! SOFTOKEN - SOFTOK Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_INTEN_SOFTOKEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_SOFTOKEN_SHIFT)) & USB_INTEN_SOFTOKEN_MASK) - -#define USB_INTEN_TOKDNEEN_MASK (0x8U) -#define USB_INTEN_TOKDNEEN_SHIFT (3U) -/*! TOKDNEEN - TOKDNE Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_INTEN_TOKDNEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_TOKDNEEN_SHIFT)) & USB_INTEN_TOKDNEEN_MASK) - -#define USB_INTEN_SLEEPEN_MASK (0x10U) -#define USB_INTEN_SLEEPEN_SHIFT (4U) -/*! SLEEPEN - SLEEP Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_INTEN_SLEEPEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_SLEEPEN_SHIFT)) & USB_INTEN_SLEEPEN_MASK) - -#define USB_INTEN_RESUMEEN_MASK (0x20U) -#define USB_INTEN_RESUMEEN_SHIFT (5U) -/*! RESUMEEN - RESUME Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_INTEN_RESUMEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_RESUMEEN_SHIFT)) & USB_INTEN_RESUMEEN_MASK) - -#define USB_INTEN_ATTACHEN_MASK (0x40U) -#define USB_INTEN_ATTACHEN_SHIFT (6U) -/*! ATTACHEN - ATTACH Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_INTEN_ATTACHEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_ATTACHEN_SHIFT)) & USB_INTEN_ATTACHEN_MASK) - -#define USB_INTEN_STALLEN_MASK (0x80U) -#define USB_INTEN_STALLEN_SHIFT (7U) -/*! STALLEN - STALL Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_INTEN_STALLEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_STALLEN_SHIFT)) & USB_INTEN_STALLEN_MASK) -/*! @} */ - -/*! @name ERRSTAT - Error Interrupt Status */ -/*! @{ */ - -#define USB_ERRSTAT_PIDERR_MASK (0x1U) -#define USB_ERRSTAT_PIDERR_SHIFT (0U) -/*! PIDERR - PID Error Flag - * 0b0..Did not fail - * 0b1..Failed - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ERRSTAT_PIDERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_PIDERR_SHIFT)) & USB_ERRSTAT_PIDERR_MASK) - -#define USB_ERRSTAT_CRC5EOF_MASK (0x2U) -#define USB_ERRSTAT_CRC5EOF_SHIFT (1U) -/*! CRC5EOF - CRC5 Error or End of Frame Error Flag - * 0b0..Interrupt did not occur - * 0b1..Interrupt occurred - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ERRSTAT_CRC5EOF(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_CRC5EOF_SHIFT)) & USB_ERRSTAT_CRC5EOF_MASK) - -#define USB_ERRSTAT_CRC16_MASK (0x4U) -#define USB_ERRSTAT_CRC16_SHIFT (2U) -/*! CRC16 - CRC16 Error Flag - * 0b0..Not rejected - * 0b1..Rejected - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ERRSTAT_CRC16(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_CRC16_SHIFT)) & USB_ERRSTAT_CRC16_MASK) - -#define USB_ERRSTAT_DFN8_MASK (0x8U) -#define USB_ERRSTAT_DFN8_SHIFT (3U) -/*! DFN8 - Data Field Not 8 Bits Flag - * 0b0..Integer number of bytes - * 0b1..Not an integer number of bytes - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ERRSTAT_DFN8(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_DFN8_SHIFT)) & USB_ERRSTAT_DFN8_MASK) - -#define USB_ERRSTAT_BTOERR_MASK (0x10U) -#define USB_ERRSTAT_BTOERR_SHIFT (4U) -/*! BTOERR - Bus Turnaround Timeout Error Flag - * 0b0..Not timed out - * 0b1..Timed out - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ERRSTAT_BTOERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_BTOERR_SHIFT)) & USB_ERRSTAT_BTOERR_MASK) - -#define USB_ERRSTAT_DMAERR_MASK (0x20U) -#define USB_ERRSTAT_DMAERR_SHIFT (5U) -/*! DMAERR - DMA Access Error Flag - * 0b0..Interrupt did not occur - * 0b1..Interrupt occurred - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ERRSTAT_DMAERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_DMAERR_SHIFT)) & USB_ERRSTAT_DMAERR_MASK) - -#define USB_ERRSTAT_OWNERR_MASK (0x40U) -#define USB_ERRSTAT_OWNERR_SHIFT (6U) -/*! OWNERR - BD Unavailable Error Flag - * 0b0..Interrupt did not occur - * 0b1..Interrupt occurred - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ERRSTAT_OWNERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_OWNERR_SHIFT)) & USB_ERRSTAT_OWNERR_MASK) - -#define USB_ERRSTAT_BTSERR_MASK (0x80U) -#define USB_ERRSTAT_BTSERR_SHIFT (7U) -/*! BTSERR - Bit Stuff Error Flag - * 0b0..Packet not rejected due to the error - * 0b1..Packet rejected due to the error - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_ERRSTAT_BTSERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_BTSERR_SHIFT)) & USB_ERRSTAT_BTSERR_MASK) -/*! @} */ - -/*! @name ERREN - Error Interrupt Enable */ -/*! @{ */ - -#define USB_ERREN_PIDERREN_MASK (0x1U) -#define USB_ERREN_PIDERREN_SHIFT (0U) -/*! PIDERREN - PIDERR Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_ERREN_PIDERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_PIDERREN_SHIFT)) & USB_ERREN_PIDERREN_MASK) - -#define USB_ERREN_CRC5EOFEN_MASK (0x2U) -#define USB_ERREN_CRC5EOFEN_SHIFT (1U) -/*! CRC5EOFEN - CRC5/EOF Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_ERREN_CRC5EOFEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_CRC5EOFEN_SHIFT)) & USB_ERREN_CRC5EOFEN_MASK) - -#define USB_ERREN_CRC16EN_MASK (0x4U) -#define USB_ERREN_CRC16EN_SHIFT (2U) -/*! CRC16EN - CRC16 Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_ERREN_CRC16EN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_CRC16EN_SHIFT)) & USB_ERREN_CRC16EN_MASK) - -#define USB_ERREN_DFN8EN_MASK (0x8U) -#define USB_ERREN_DFN8EN_SHIFT (3U) -/*! DFN8EN - DFN8 (Data Field Not Integer Number of Bytes) Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_ERREN_DFN8EN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_DFN8EN_SHIFT)) & USB_ERREN_DFN8EN_MASK) - -#define USB_ERREN_BTOERREN_MASK (0x10U) -#define USB_ERREN_BTOERREN_SHIFT (4U) -/*! BTOERREN - BTOERR (Bus Timeout Error) Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_ERREN_BTOERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_BTOERREN_SHIFT)) & USB_ERREN_BTOERREN_MASK) - -#define USB_ERREN_DMAERREN_MASK (0x20U) -#define USB_ERREN_DMAERREN_SHIFT (5U) -/*! DMAERREN - DMAERR Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_ERREN_DMAERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_DMAERREN_SHIFT)) & USB_ERREN_DMAERREN_MASK) - -#define USB_ERREN_OWNERREN_MASK (0x40U) -#define USB_ERREN_OWNERREN_SHIFT (6U) -/*! OWNERREN - OWNERR Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_ERREN_OWNERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_OWNERREN_SHIFT)) & USB_ERREN_OWNERREN_MASK) - -#define USB_ERREN_BTSERREN_MASK (0x80U) -#define USB_ERREN_BTSERREN_SHIFT (7U) -/*! BTSERREN - BTSERR (Bit Stuff Error) Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_ERREN_BTSERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_BTSERREN_SHIFT)) & USB_ERREN_BTSERREN_MASK) -/*! @} */ - -/*! @name STAT - Status */ -/*! @{ */ - -#define USB_STAT_ODD_MASK (0x4U) -#define USB_STAT_ODD_SHIFT (2U) -/*! ODD - Odd Bank - * 0b0..Not in the odd bank - * 0b1..In the odd bank - */ -#define USB_STAT_ODD(x) (((uint8_t)(((uint8_t)(x)) << USB_STAT_ODD_SHIFT)) & USB_STAT_ODD_MASK) - -#define USB_STAT_TX_MASK (0x8U) -#define USB_STAT_TX_SHIFT (3U) -/*! TX - Transmit Indicator - * 0b0..Receive - * 0b1..Transmit - */ -#define USB_STAT_TX(x) (((uint8_t)(((uint8_t)(x)) << USB_STAT_TX_SHIFT)) & USB_STAT_TX_MASK) - -#define USB_STAT_ENDP_MASK (0xF0U) -#define USB_STAT_ENDP_SHIFT (4U) -/*! ENDP - Endpoint address */ -#define USB_STAT_ENDP(x) (((uint8_t)(((uint8_t)(x)) << USB_STAT_ENDP_SHIFT)) & USB_STAT_ENDP_MASK) -/*! @} */ - -/*! @name CTL - Control */ -/*! @{ */ - -#define USB_CTL_USBENSOFEN_MASK (0x1U) -#define USB_CTL_USBENSOFEN_SHIFT (0U) -/*! USBENSOFEN - USB Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_CTL_USBENSOFEN(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_USBENSOFEN_SHIFT)) & USB_CTL_USBENSOFEN_MASK) - -#define USB_CTL_ODDRST_MASK (0x2U) -#define USB_CTL_ODDRST_SHIFT (1U) -/*! ODDRST - Odd Reset */ -#define USB_CTL_ODDRST(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_ODDRST_SHIFT)) & USB_CTL_ODDRST_MASK) - -#define USB_CTL_RESUME_MASK (0x4U) -#define USB_CTL_RESUME_SHIFT (2U) -/*! RESUME - Resume */ -#define USB_CTL_RESUME(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_RESUME_SHIFT)) & USB_CTL_RESUME_MASK) - -#define USB_CTL_HOSTMODEEN_MASK (0x8U) -#define USB_CTL_HOSTMODEEN_SHIFT (3U) -/*! HOSTMODEEN - Host Mode Enable - * 0b0..USBFS operates in Device mode. - * 0b1..USBFS operates in Host mode. In Host mode, USBFS performs USB transactions under the programmed control of the host processor. - */ -#define USB_CTL_HOSTMODEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_HOSTMODEEN_SHIFT)) & USB_CTL_HOSTMODEEN_MASK) - -#define USB_CTL_RESET_MASK (0x10U) -#define USB_CTL_RESET_SHIFT (4U) -/*! RESET - Reset Signaling Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_CTL_RESET(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_RESET_SHIFT)) & USB_CTL_RESET_MASK) - -#define USB_CTL_TXSUSPENDTOKENBUSY_MASK (0x20U) -#define USB_CTL_TXSUSPENDTOKENBUSY_SHIFT (5U) -/*! TXSUSPENDTOKENBUSY - TXD Suspend And Token Busy */ -#define USB_CTL_TXSUSPENDTOKENBUSY(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_TXSUSPENDTOKENBUSY_SHIFT)) & USB_CTL_TXSUSPENDTOKENBUSY_MASK) - -#define USB_CTL_SE0_MASK (0x40U) -#define USB_CTL_SE0_SHIFT (6U) -/*! SE0 - Live USB Single-Ended Zero signal */ -#define USB_CTL_SE0(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_SE0_SHIFT)) & USB_CTL_SE0_MASK) - -#define USB_CTL_JSTATE_MASK (0x80U) -#define USB_CTL_JSTATE_SHIFT (7U) -/*! JSTATE - Live USB Differential Receiver JSTATE Signal */ -#define USB_CTL_JSTATE(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_JSTATE_SHIFT)) & USB_CTL_JSTATE_MASK) -/*! @} */ - -/*! @name ADDR - Address */ -/*! @{ */ - -#define USB_ADDR_ADDR_MASK (0x7FU) -#define USB_ADDR_ADDR_SHIFT (0U) -/*! ADDR - USB Address */ -#define USB_ADDR_ADDR(x) (((uint8_t)(((uint8_t)(x)) << USB_ADDR_ADDR_SHIFT)) & USB_ADDR_ADDR_MASK) - -#define USB_ADDR_LSEN_MASK (0x80U) -#define USB_ADDR_LSEN_SHIFT (7U) -/*! LSEN - Low Speed Enable */ -#define USB_ADDR_LSEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ADDR_LSEN_SHIFT)) & USB_ADDR_LSEN_MASK) -/*! @} */ - -/*! @name BDTPAGE1 - BDT Page 1 */ -/*! @{ */ - -#define USB_BDTPAGE1_BDTBA_MASK (0xFEU) -#define USB_BDTPAGE1_BDTBA_SHIFT (1U) -/*! BDTBA - BDT Base Address */ -#define USB_BDTPAGE1_BDTBA(x) (((uint8_t)(((uint8_t)(x)) << USB_BDTPAGE1_BDTBA_SHIFT)) & USB_BDTPAGE1_BDTBA_MASK) -/*! @} */ - -/*! @name FRMNUML - Frame Number Register Low */ -/*! @{ */ - -#define USB_FRMNUML_FRM_MASK (0xFFU) -#define USB_FRMNUML_FRM_SHIFT (0U) -/*! FRM - Frame Number, Bits 0-7 */ -#define USB_FRMNUML_FRM(x) (((uint8_t)(((uint8_t)(x)) << USB_FRMNUML_FRM_SHIFT)) & USB_FRMNUML_FRM_MASK) -/*! @} */ - -/*! @name FRMNUMH - Frame Number Register High */ -/*! @{ */ - -#define USB_FRMNUMH_FRM_MASK (0x7U) -#define USB_FRMNUMH_FRM_SHIFT (0U) -/*! FRM - Frame Number, Bits 8-10 */ -#define USB_FRMNUMH_FRM(x) (((uint8_t)(((uint8_t)(x)) << USB_FRMNUMH_FRM_SHIFT)) & USB_FRMNUMH_FRM_MASK) -/*! @} */ - -/*! @name TOKEN - Token */ -/*! @{ */ - -#define USB_TOKEN_TOKENENDPT_MASK (0xFU) -#define USB_TOKEN_TOKENENDPT_SHIFT (0U) -/*! TOKENENDPT - Token Endpoint Address */ -#define USB_TOKEN_TOKENENDPT(x) (((uint8_t)(((uint8_t)(x)) << USB_TOKEN_TOKENENDPT_SHIFT)) & USB_TOKEN_TOKENENDPT_MASK) - -#define USB_TOKEN_TOKENPID_MASK (0xF0U) -#define USB_TOKEN_TOKENPID_SHIFT (4U) -/*! TOKENPID - Token Type - * 0b0001..OUT token. USBFS performs an OUT (TX) transaction. - * 0b1001..IN token. USBFS performs an IN (RX) transaction. - * 0b1101..SETUP token. USBFS performs a SETUP (TX) transaction - */ -#define USB_TOKEN_TOKENPID(x) (((uint8_t)(((uint8_t)(x)) << USB_TOKEN_TOKENPID_SHIFT)) & USB_TOKEN_TOKENPID_MASK) -/*! @} */ - -/*! @name SOFTHLD - SOF Threshold */ -/*! @{ */ - -#define USB_SOFTHLD_CNT_MASK (0xFFU) -#define USB_SOFTHLD_CNT_SHIFT (0U) -/*! CNT - SOF Count Threshold */ -#define USB_SOFTHLD_CNT(x) (((uint8_t)(((uint8_t)(x)) << USB_SOFTHLD_CNT_SHIFT)) & USB_SOFTHLD_CNT_MASK) -/*! @} */ - -/*! @name BDTPAGE2 - BDT Page 2 */ -/*! @{ */ - -#define USB_BDTPAGE2_BDTBA_MASK (0xFFU) -#define USB_BDTPAGE2_BDTBA_SHIFT (0U) -/*! BDTBA - BDT Base Address */ -#define USB_BDTPAGE2_BDTBA(x) (((uint8_t)(((uint8_t)(x)) << USB_BDTPAGE2_BDTBA_SHIFT)) & USB_BDTPAGE2_BDTBA_MASK) -/*! @} */ - -/*! @name BDTPAGE3 - BDT Page 3 */ -/*! @{ */ - -#define USB_BDTPAGE3_BDTBA_MASK (0xFFU) -#define USB_BDTPAGE3_BDTBA_SHIFT (0U) -/*! BDTBA - BDT Base Address */ -#define USB_BDTPAGE3_BDTBA(x) (((uint8_t)(((uint8_t)(x)) << USB_BDTPAGE3_BDTBA_SHIFT)) & USB_BDTPAGE3_BDTBA_MASK) -/*! @} */ - -/*! @name ENDPT - Endpoint Control */ -/*! @{ */ - -#define USB_ENDPT_EPHSHK_MASK (0x1U) -#define USB_ENDPT_EPHSHK_SHIFT (0U) -/*! EPHSHK - Endpoint Handshaking Enable */ -#define USB_ENDPT_EPHSHK(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPHSHK_SHIFT)) & USB_ENDPT_EPHSHK_MASK) - -#define USB_ENDPT_EPSTALL_MASK (0x2U) -#define USB_ENDPT_EPSTALL_SHIFT (1U) -/*! EPSTALL - Endpoint Stalled */ -#define USB_ENDPT_EPSTALL(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPSTALL_SHIFT)) & USB_ENDPT_EPSTALL_MASK) - -#define USB_ENDPT_EPTXEN_MASK (0x4U) -#define USB_ENDPT_EPTXEN_SHIFT (2U) -/*! EPTXEN - Endpoint for TX transfers enable */ -#define USB_ENDPT_EPTXEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPTXEN_SHIFT)) & USB_ENDPT_EPTXEN_MASK) - -#define USB_ENDPT_EPRXEN_MASK (0x8U) -#define USB_ENDPT_EPRXEN_SHIFT (3U) -/*! EPRXEN - Endpoint for RX transfers enable */ -#define USB_ENDPT_EPRXEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPRXEN_SHIFT)) & USB_ENDPT_EPRXEN_MASK) - -#define USB_ENDPT_EPCTLDIS_MASK (0x10U) -#define USB_ENDPT_EPCTLDIS_SHIFT (4U) -/*! EPCTLDIS - Control Transfer Disable - * 0b0..Enable - * 0b1..Disable - */ -#define USB_ENDPT_EPCTLDIS(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPCTLDIS_SHIFT)) & USB_ENDPT_EPCTLDIS_MASK) - -#define USB_ENDPT_RETRYDIS_MASK (0x40U) -#define USB_ENDPT_RETRYDIS_SHIFT (6U) -/*! RETRYDIS - Retry Disable - * 0b0..Retried NAK'ed transactions in hardware. - * 0b1..Do not retry NAK'ed transactions. When a transaction is NAK'ed, the BDT PID field is updated with the NAK - * PID, and the TOKEN_DNE interrupt becomes 1. - */ -#define USB_ENDPT_RETRYDIS(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_RETRYDIS_SHIFT)) & USB_ENDPT_RETRYDIS_MASK) - -#define USB_ENDPT_HOSTWOHUB_MASK (0x80U) -#define USB_ENDPT_HOSTWOHUB_SHIFT (7U) -/*! HOSTWOHUB - Host Without A Hub - * 0b0..Connected using a hub (USBFS generates PRE_PID as required) - * 0b1..Connected directly to host without a hub, or was used to attach - */ -#define USB_ENDPT_HOSTWOHUB(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_HOSTWOHUB_SHIFT)) & USB_ENDPT_HOSTWOHUB_MASK) -/*! @} */ - -/* The count of USB_ENDPT */ -#define USB_ENDPT_COUNT (16U) - -/*! @name USBCTRL - USB Control */ -/*! @{ */ - -#define USB_USBCTRL_DPDM_LANE_REVERSE_MASK (0x4U) -#define USB_USBCTRL_DPDM_LANE_REVERSE_SHIFT (2U) -/*! DPDM_LANE_REVERSE - DP and DM Lane Reversal Control - * 0b0..Standard USB DP and DM package pin assignment - * 0b1..Reverse roles of USB DP and DM package pins - */ -#define USB_USBCTRL_DPDM_LANE_REVERSE(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_DPDM_LANE_REVERSE_SHIFT)) & USB_USBCTRL_DPDM_LANE_REVERSE_MASK) - -#define USB_USBCTRL_HOST_LS_EOP_MASK (0x8U) -#define USB_USBCTRL_HOST_LS_EOP_SHIFT (3U) -/*! HOST_LS_EOP - Host-Mode-Only Low-Speed Device EOP Signaling - * 0b0..Full-speed device or a low-speed device through a hub - * 0b1..Directly-connected low-speed device - */ -#define USB_USBCTRL_HOST_LS_EOP(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_HOST_LS_EOP_SHIFT)) & USB_USBCTRL_HOST_LS_EOP_MASK) - -#define USB_USBCTRL_UARTSEL_MASK (0x10U) -#define USB_USBCTRL_UARTSEL_SHIFT (4U) -/*! UARTSEL - UART Select - * 0b0..USB DP and DM external package pins are used for USB signaling. - * 0b1..USB DP and DM external package pins are used for UART signaling. - */ -#define USB_USBCTRL_UARTSEL(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_UARTSEL_SHIFT)) & USB_USBCTRL_UARTSEL_MASK) - -#define USB_USBCTRL_UARTCHLS_MASK (0x20U) -#define USB_USBCTRL_UARTCHLS_SHIFT (5U) -/*! UARTCHLS - UART Signal Channel Select - * 0b0..USB DP and DM signals are used as UART TX/RX. - * 0b1..USB DP and DM signals are used as UART RX/TX. - */ -#define USB_USBCTRL_UARTCHLS(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_UARTCHLS_SHIFT)) & USB_USBCTRL_UARTCHLS_MASK) - -#define USB_USBCTRL_PDE_MASK (0x40U) -#define USB_USBCTRL_PDE_SHIFT (6U) -/*! PDE - Pulldown Enable - * 0b0..Disable on D+ and D- - * 0b1..Enable on D+ and D- - */ -#define USB_USBCTRL_PDE(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_PDE_SHIFT)) & USB_USBCTRL_PDE_MASK) - -#define USB_USBCTRL_SUSP_MASK (0x80U) -#define USB_USBCTRL_SUSP_SHIFT (7U) -/*! SUSP - Suspend - * 0b0..Not in Suspend state - * 0b1..In Suspend state - */ -#define USB_USBCTRL_SUSP(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_SUSP_SHIFT)) & USB_USBCTRL_SUSP_MASK) -/*! @} */ - -/*! @name OBSERVE - USB OTG Observe */ -/*! @{ */ - -#define USB_OBSERVE_DMPD_MASK (0x10U) -#define USB_OBSERVE_DMPD_SHIFT (4U) -/*! DMPD - D- Pulldown - * 0b0..Disabled - * 0b1..Enabled - */ -#define USB_OBSERVE_DMPD(x) (((uint8_t)(((uint8_t)(x)) << USB_OBSERVE_DMPD_SHIFT)) & USB_OBSERVE_DMPD_MASK) - -#define USB_OBSERVE_DPPD_MASK (0x40U) -#define USB_OBSERVE_DPPD_SHIFT (6U) -/*! DPPD - D+ Pulldown - * 0b0..Disabled - * 0b1..Enabled - */ -#define USB_OBSERVE_DPPD(x) (((uint8_t)(((uint8_t)(x)) << USB_OBSERVE_DPPD_SHIFT)) & USB_OBSERVE_DPPD_MASK) - -#define USB_OBSERVE_DPPU_MASK (0x80U) -#define USB_OBSERVE_DPPU_SHIFT (7U) -/*! DPPU - D+ Pullup - * 0b0..Disabled - * 0b1..Enabled - */ -#define USB_OBSERVE_DPPU(x) (((uint8_t)(((uint8_t)(x)) << USB_OBSERVE_DPPU_SHIFT)) & USB_OBSERVE_DPPU_MASK) -/*! @} */ - -/*! @name CONTROL - USB OTG Control */ -/*! @{ */ - -#define USB_CONTROL_VBUS_SOURCE_SEL_MASK (0x1U) -#define USB_CONTROL_VBUS_SOURCE_SEL_SHIFT (0U) -/*! VBUS_SOURCE_SEL - VBUS Monitoring Source Select - * 0b0..Reserved - * 0b1..Resistive divider attached to a GPIO pin - */ -#define USB_CONTROL_VBUS_SOURCE_SEL(x) (((uint8_t)(((uint8_t)(x)) << USB_CONTROL_VBUS_SOURCE_SEL_SHIFT)) & USB_CONTROL_VBUS_SOURCE_SEL_MASK) - -#define USB_CONTROL_SESS_VLD_MASK (0x2U) -#define USB_CONTROL_SESS_VLD_SHIFT (1U) -/*! SESS_VLD - VBUS Session Valid status - * 0b1..Above - * 0b0..Below - */ -#define USB_CONTROL_SESS_VLD(x) (((uint8_t)(((uint8_t)(x)) << USB_CONTROL_SESS_VLD_SHIFT)) & USB_CONTROL_SESS_VLD_MASK) - -#define USB_CONTROL_DPPULLUPNONOTG_MASK (0x10U) -#define USB_CONTROL_DPPULLUPNONOTG_SHIFT (4U) -/*! DPPULLUPNONOTG - DP Pullup in Non-OTG Device Mode - * 0b0..Disable - * 0b1..Enabled - */ -#define USB_CONTROL_DPPULLUPNONOTG(x) (((uint8_t)(((uint8_t)(x)) << USB_CONTROL_DPPULLUPNONOTG_SHIFT)) & USB_CONTROL_DPPULLUPNONOTG_MASK) -/*! @} */ - -/*! @name USBTRC0 - USB Transceiver Control 0 */ -/*! @{ */ - -#define USB_USBTRC0_USB_RESUME_INT_MASK (0x1U) -#define USB_USBTRC0_USB_RESUME_INT_SHIFT (0U) -/*! USB_RESUME_INT - USB Asynchronous Interrupt - * 0b0..Not generated - * 0b1..Generated because of the USB asynchronous interrupt - */ -#define USB_USBTRC0_USB_RESUME_INT(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USB_RESUME_INT_SHIFT)) & USB_USBTRC0_USB_RESUME_INT_MASK) - -#define USB_USBTRC0_SYNC_DET_MASK (0x2U) -#define USB_USBTRC0_SYNC_DET_SHIFT (1U) -/*! SYNC_DET - Synchronous USB Interrupt Detect - * 0b0..Not detected - * 0b1..Detected - */ -#define USB_USBTRC0_SYNC_DET(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_SYNC_DET_SHIFT)) & USB_USBTRC0_SYNC_DET_MASK) - -#define USB_USBTRC0_USB_CLK_RECOVERY_INT_MASK (0x4U) -#define USB_USBTRC0_USB_CLK_RECOVERY_INT_SHIFT (2U) -/*! USB_CLK_RECOVERY_INT - Combined USB Clock Recovery interrupt status */ -#define USB_USBTRC0_USB_CLK_RECOVERY_INT(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USB_CLK_RECOVERY_INT_SHIFT)) & USB_USBTRC0_USB_CLK_RECOVERY_INT_MASK) - -#define USB_USBTRC0_VREDG_DET_MASK (0x8U) -#define USB_USBTRC0_VREDG_DET_SHIFT (3U) -/*! VREDG_DET - VREGIN Rising Edge Interrupt Detect - * 0b0..Not detected - * 0b1..Detected - */ -#define USB_USBTRC0_VREDG_DET(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_VREDG_DET_SHIFT)) & USB_USBTRC0_VREDG_DET_MASK) - -#define USB_USBTRC0_VFEDG_DET_MASK (0x10U) -#define USB_USBTRC0_VFEDG_DET_SHIFT (4U) -/*! VFEDG_DET - VREGIN Falling Edge Interrupt Detect - * 0b0..Not detected - * 0b1..Detected - */ -#define USB_USBTRC0_VFEDG_DET(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_VFEDG_DET_SHIFT)) & USB_USBTRC0_VFEDG_DET_MASK) - -#define USB_USBTRC0_USBRESMEN_MASK (0x20U) -#define USB_USBTRC0_USBRESMEN_SHIFT (5U) -/*! USBRESMEN - Asynchronous Resume Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_USBTRC0_USBRESMEN(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USBRESMEN_SHIFT)) & USB_USBTRC0_USBRESMEN_MASK) - -#define USB_USBTRC0_VREGIN_STS_MASK (0x40U) -#define USB_USBTRC0_VREGIN_STS_SHIFT (6U) -/*! VREGIN_STS - VREGIN Status */ -#define USB_USBTRC0_VREGIN_STS(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_VREGIN_STS_SHIFT)) & USB_USBTRC0_VREGIN_STS_MASK) - -#define USB_USBTRC0_USBRESET_MASK (0x80U) -#define USB_USBTRC0_USBRESET_SHIFT (7U) -/*! USBRESET - USB Reset - * 0b0..Normal USBFS operation - * 0b1..Returns USBFS to its reset state - */ -#define USB_USBTRC0_USBRESET(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USBRESET_SHIFT)) & USB_USBTRC0_USBRESET_MASK) -/*! @} */ - -/*! @name USBFRMADJUST - Frame Adjust */ -/*! @{ */ - -#define USB_USBFRMADJUST_ADJ_MASK (0xFFU) -#define USB_USBFRMADJUST_ADJ_SHIFT (0U) -/*! ADJ - Frame Adjustment */ -#define USB_USBFRMADJUST_ADJ(x) (((uint8_t)(((uint8_t)(x)) << USB_USBFRMADJUST_ADJ_SHIFT)) & USB_USBFRMADJUST_ADJ_MASK) -/*! @} */ - -/*! @name KEEP_ALIVE_CTRL - Keep Alive Mode Control */ -/*! @{ */ - -#define USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_EN_MASK (0x1U) -#define USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_EN_SHIFT (0U) -/*! KEEP_ALIVE_EN - Keep Alive Mode Enable - * 0b0..Everything remains same as before. - * 0b1..USB shall enter USB_KEEP_ALIVE mode after asserting ipg_stop. - */ -#define USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_EN_SHIFT)) & USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_EN_MASK) - -#define USB_KEEP_ALIVE_CTRL_OWN_OVERRD_EN_MASK (0x2U) -#define USB_KEEP_ALIVE_CTRL_OWN_OVERRD_EN_SHIFT (1U) -/*! OWN_OVERRD_EN - OWN Bit Override Enable */ -#define USB_KEEP_ALIVE_CTRL_OWN_OVERRD_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_KEEP_ALIVE_CTRL_OWN_OVERRD_EN_SHIFT)) & USB_KEEP_ALIVE_CTRL_OWN_OVERRD_EN_MASK) - -#define USB_KEEP_ALIVE_CTRL_STOP_ACK_DLY_EN_MASK (0x4U) -#define USB_KEEP_ALIVE_CTRL_STOP_ACK_DLY_EN_SHIFT (2U) -/*! STOP_ACK_DLY_EN - Stop Acknowledge Delay Enable - * 0b0..Enter KEEP_ALIVE mode immediately when there is no USB AHB transfer. - * 0b1..Enter KEEP_ALIVE mode until the USB core is idle and there is no USB AHB transfer. - */ -#define USB_KEEP_ALIVE_CTRL_STOP_ACK_DLY_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_KEEP_ALIVE_CTRL_STOP_ACK_DLY_EN_SHIFT)) & USB_KEEP_ALIVE_CTRL_STOP_ACK_DLY_EN_MASK) - -#define USB_KEEP_ALIVE_CTRL_WAKE_REQ_EN_MASK (0x8U) -#define USB_KEEP_ALIVE_CTRL_WAKE_REQ_EN_SHIFT (3U) -/*! WAKE_REQ_EN - Wakeup Request Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_KEEP_ALIVE_CTRL_WAKE_REQ_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_KEEP_ALIVE_CTRL_WAKE_REQ_EN_SHIFT)) & USB_KEEP_ALIVE_CTRL_WAKE_REQ_EN_MASK) - -#define USB_KEEP_ALIVE_CTRL_WAKE_INT_EN_MASK (0x10U) -#define USB_KEEP_ALIVE_CTRL_WAKE_INT_EN_SHIFT (4U) -/*! WAKE_INT_EN - Wakeup Interrupt Enable */ -#define USB_KEEP_ALIVE_CTRL_WAKE_INT_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_KEEP_ALIVE_CTRL_WAKE_INT_EN_SHIFT)) & USB_KEEP_ALIVE_CTRL_WAKE_INT_EN_MASK) - -#define USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_STS_MASK (0x40U) -#define USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_STS_SHIFT (6U) -/*! KEEP_ALIVE_STS - Keep Alive Status - * 0b0..Not in Keep Alive mode - * 0b1..In Keep Alive mode - */ -#define USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_STS(x) (((uint8_t)(((uint8_t)(x)) << USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_STS_SHIFT)) & USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_STS_MASK) - -#define USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_MASK (0x80U) -#define USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_SHIFT (7U) -/*! WAKE_INT_STS - Wakeup Interrupt Status Flag - * 0b0..Interrupt did not occur - * 0b1..Interrupt occurred - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_KEEP_ALIVE_CTRL_WAKE_INT_STS(x) (((uint8_t)(((uint8_t)(x)) << USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_SHIFT)) & USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_MASK) -/*! @} */ - -/*! @name KEEP_ALIVE_WKCTRL - Keep Alive Mode Wakeup Control */ -/*! @{ */ - -#define USB_KEEP_ALIVE_WKCTRL_WAKE_ON_THIS_MASK (0xFU) -#define USB_KEEP_ALIVE_WKCTRL_WAKE_ON_THIS_SHIFT (0U) -/*! WAKE_ON_THIS - Token PID for the wakeup request - * 0b0001..Wake up after receiving OUT or SETUP token packet. - * 0b1101..Wake up after receiving SETUP token packet. All other values are reserved. - */ -#define USB_KEEP_ALIVE_WKCTRL_WAKE_ON_THIS(x) (((uint8_t)(((uint8_t)(x)) << USB_KEEP_ALIVE_WKCTRL_WAKE_ON_THIS_SHIFT)) & USB_KEEP_ALIVE_WKCTRL_WAKE_ON_THIS_MASK) - -#define USB_KEEP_ALIVE_WKCTRL_WAKE_ENDPT_MASK (0xF0U) -#define USB_KEEP_ALIVE_WKCTRL_WAKE_ENDPT_SHIFT (4U) -/*! WAKE_ENDPT - Endpoint address for the wakeup request */ -#define USB_KEEP_ALIVE_WKCTRL_WAKE_ENDPT(x) (((uint8_t)(((uint8_t)(x)) << USB_KEEP_ALIVE_WKCTRL_WAKE_ENDPT_SHIFT)) & USB_KEEP_ALIVE_WKCTRL_WAKE_ENDPT_MASK) -/*! @} */ - -/*! @name MISCCTRL - Miscellaneous Control */ -/*! @{ */ - -#define USB_MISCCTRL_SOFDYNTHLD_MASK (0x1U) -#define USB_MISCCTRL_SOFDYNTHLD_SHIFT (0U) -/*! SOFDYNTHLD - Dynamic SOF Threshold Compare mode - * 0b0..When the byte-times SOF threshold is reached - * 0b1..When 8 byte-times SOF threshold is reached or overstepped - */ -#define USB_MISCCTRL_SOFDYNTHLD(x) (((uint8_t)(((uint8_t)(x)) << USB_MISCCTRL_SOFDYNTHLD_SHIFT)) & USB_MISCCTRL_SOFDYNTHLD_MASK) - -#define USB_MISCCTRL_SOFBUSSET_MASK (0x2U) -#define USB_MISCCTRL_SOFBUSSET_SHIFT (1U) -/*! SOFBUSSET - SOF_TOK Interrupt Generation Mode Select - * 0b0..According to the SOF threshold value - * 0b1..When the SOF counter reaches 0 - */ -#define USB_MISCCTRL_SOFBUSSET(x) (((uint8_t)(((uint8_t)(x)) << USB_MISCCTRL_SOFBUSSET_SHIFT)) & USB_MISCCTRL_SOFBUSSET_MASK) - -#define USB_MISCCTRL_OWNERRISODIS_MASK (0x4U) -#define USB_MISCCTRL_OWNERRISODIS_SHIFT (2U) -/*! OWNERRISODIS - OWN Error Detect for ISO IN and ISO OUT Disable - * 0b0..Enable - * 0b1..Disable - */ -#define USB_MISCCTRL_OWNERRISODIS(x) (((uint8_t)(((uint8_t)(x)) << USB_MISCCTRL_OWNERRISODIS_SHIFT)) & USB_MISCCTRL_OWNERRISODIS_MASK) - -#define USB_MISCCTRL_VREDG_EN_MASK (0x8U) -#define USB_MISCCTRL_VREDG_EN_SHIFT (3U) -/*! VREDG_EN - VREGIN Rising Edge Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_MISCCTRL_VREDG_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_MISCCTRL_VREDG_EN_SHIFT)) & USB_MISCCTRL_VREDG_EN_MASK) - -#define USB_MISCCTRL_VFEDG_EN_MASK (0x10U) -#define USB_MISCCTRL_VFEDG_EN_SHIFT (4U) -/*! VFEDG_EN - VREGIN Falling Edge Interrupt Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_MISCCTRL_VFEDG_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_MISCCTRL_VFEDG_EN_SHIFT)) & USB_MISCCTRL_VFEDG_EN_MASK) - -#define USB_MISCCTRL_STL_ADJ_EN_MASK (0x80U) -#define USB_MISCCTRL_STL_ADJ_EN_SHIFT (7U) -/*! STL_ADJ_EN - USB Peripheral Mode Stall Adjust Enable - * 0b0..If ENDPTn[END_STALL] = 1, both IN and OUT directions for the associated endpoint stalls. - * 0b1..If ENDPTn[END_STALL] = 1, the STALL_xx_DIS registers control which directions for the associated endpoint stalls. - */ -#define USB_MISCCTRL_STL_ADJ_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_MISCCTRL_STL_ADJ_EN_SHIFT)) & USB_MISCCTRL_STL_ADJ_EN_MASK) -/*! @} */ - -/*! @name STALL_IL_DIS - Peripheral Mode Stall Disable for Endpoints 7 to 0 in IN Direction */ -/*! @{ */ - -#define USB_STALL_IL_DIS_STALL_I_DIS0_MASK (0x1U) -#define USB_STALL_IL_DIS_STALL_I_DIS0_SHIFT (0U) -/*! STALL_I_DIS0 - Disable Endpoint 0 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IL_DIS_STALL_I_DIS0(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IL_DIS_STALL_I_DIS0_SHIFT)) & USB_STALL_IL_DIS_STALL_I_DIS0_MASK) - -#define USB_STALL_IL_DIS_STALL_I_DIS1_MASK (0x2U) -#define USB_STALL_IL_DIS_STALL_I_DIS1_SHIFT (1U) -/*! STALL_I_DIS1 - Disable Endpoint 1 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IL_DIS_STALL_I_DIS1(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IL_DIS_STALL_I_DIS1_SHIFT)) & USB_STALL_IL_DIS_STALL_I_DIS1_MASK) - -#define USB_STALL_IL_DIS_STALL_I_DIS2_MASK (0x4U) -#define USB_STALL_IL_DIS_STALL_I_DIS2_SHIFT (2U) -/*! STALL_I_DIS2 - Disable Endpoint 2 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IL_DIS_STALL_I_DIS2(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IL_DIS_STALL_I_DIS2_SHIFT)) & USB_STALL_IL_DIS_STALL_I_DIS2_MASK) - -#define USB_STALL_IL_DIS_STALL_I_DIS3_MASK (0x8U) -#define USB_STALL_IL_DIS_STALL_I_DIS3_SHIFT (3U) -/*! STALL_I_DIS3 - Disable Endpoint 3 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IL_DIS_STALL_I_DIS3(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IL_DIS_STALL_I_DIS3_SHIFT)) & USB_STALL_IL_DIS_STALL_I_DIS3_MASK) - -#define USB_STALL_IL_DIS_STALL_I_DIS4_MASK (0x10U) -#define USB_STALL_IL_DIS_STALL_I_DIS4_SHIFT (4U) -/*! STALL_I_DIS4 - Disable Endpoint 4 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IL_DIS_STALL_I_DIS4(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IL_DIS_STALL_I_DIS4_SHIFT)) & USB_STALL_IL_DIS_STALL_I_DIS4_MASK) - -#define USB_STALL_IL_DIS_STALL_I_DIS5_MASK (0x20U) -#define USB_STALL_IL_DIS_STALL_I_DIS5_SHIFT (5U) -/*! STALL_I_DIS5 - Disable Endpoint 5 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IL_DIS_STALL_I_DIS5(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IL_DIS_STALL_I_DIS5_SHIFT)) & USB_STALL_IL_DIS_STALL_I_DIS5_MASK) - -#define USB_STALL_IL_DIS_STALL_I_DIS6_MASK (0x40U) -#define USB_STALL_IL_DIS_STALL_I_DIS6_SHIFT (6U) -/*! STALL_I_DIS6 - Disable Endpoint 6 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IL_DIS_STALL_I_DIS6(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IL_DIS_STALL_I_DIS6_SHIFT)) & USB_STALL_IL_DIS_STALL_I_DIS6_MASK) - -#define USB_STALL_IL_DIS_STALL_I_DIS7_MASK (0x80U) -#define USB_STALL_IL_DIS_STALL_I_DIS7_SHIFT (7U) -/*! STALL_I_DIS7 - Disable Endpoint 7 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IL_DIS_STALL_I_DIS7(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IL_DIS_STALL_I_DIS7_SHIFT)) & USB_STALL_IL_DIS_STALL_I_DIS7_MASK) -/*! @} */ - -/*! @name STALL_IH_DIS - Peripheral Mode Stall Disable for Endpoints 15 to 8 in IN Direction */ -/*! @{ */ - -#define USB_STALL_IH_DIS_STALL_I_DIS8_MASK (0x1U) -#define USB_STALL_IH_DIS_STALL_I_DIS8_SHIFT (0U) -/*! STALL_I_DIS8 - Disable Endpoint 8 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IH_DIS_STALL_I_DIS8(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IH_DIS_STALL_I_DIS8_SHIFT)) & USB_STALL_IH_DIS_STALL_I_DIS8_MASK) - -#define USB_STALL_IH_DIS_STALL_I_DIS9_MASK (0x2U) -#define USB_STALL_IH_DIS_STALL_I_DIS9_SHIFT (1U) -/*! STALL_I_DIS9 - Disable Endpoint 9 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IH_DIS_STALL_I_DIS9(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IH_DIS_STALL_I_DIS9_SHIFT)) & USB_STALL_IH_DIS_STALL_I_DIS9_MASK) - -#define USB_STALL_IH_DIS_STALL_I_DIS10_MASK (0x4U) -#define USB_STALL_IH_DIS_STALL_I_DIS10_SHIFT (2U) -/*! STALL_I_DIS10 - Disable Endpoint 10 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IH_DIS_STALL_I_DIS10(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IH_DIS_STALL_I_DIS10_SHIFT)) & USB_STALL_IH_DIS_STALL_I_DIS10_MASK) - -#define USB_STALL_IH_DIS_STALL_I_DIS11_MASK (0x8U) -#define USB_STALL_IH_DIS_STALL_I_DIS11_SHIFT (3U) -/*! STALL_I_DIS11 - Disable Endpoint 11 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IH_DIS_STALL_I_DIS11(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IH_DIS_STALL_I_DIS11_SHIFT)) & USB_STALL_IH_DIS_STALL_I_DIS11_MASK) - -#define USB_STALL_IH_DIS_STALL_I_DIS12_MASK (0x10U) -#define USB_STALL_IH_DIS_STALL_I_DIS12_SHIFT (4U) -/*! STALL_I_DIS12 - Disable Endpoint 12 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IH_DIS_STALL_I_DIS12(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IH_DIS_STALL_I_DIS12_SHIFT)) & USB_STALL_IH_DIS_STALL_I_DIS12_MASK) - -#define USB_STALL_IH_DIS_STALL_I_DIS13_MASK (0x20U) -#define USB_STALL_IH_DIS_STALL_I_DIS13_SHIFT (5U) -/*! STALL_I_DIS13 - Disable Endpoint 13 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IH_DIS_STALL_I_DIS13(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IH_DIS_STALL_I_DIS13_SHIFT)) & USB_STALL_IH_DIS_STALL_I_DIS13_MASK) - -#define USB_STALL_IH_DIS_STALL_I_DIS14_MASK (0x40U) -#define USB_STALL_IH_DIS_STALL_I_DIS14_SHIFT (6U) -/*! STALL_I_DIS14 - Disable Endpoint 14 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IH_DIS_STALL_I_DIS14(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IH_DIS_STALL_I_DIS14_SHIFT)) & USB_STALL_IH_DIS_STALL_I_DIS14_MASK) - -#define USB_STALL_IH_DIS_STALL_I_DIS15_MASK (0x80U) -#define USB_STALL_IH_DIS_STALL_I_DIS15_SHIFT (7U) -/*! STALL_I_DIS15 - Disable Endpoint 15 IN Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_IH_DIS_STALL_I_DIS15(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_IH_DIS_STALL_I_DIS15_SHIFT)) & USB_STALL_IH_DIS_STALL_I_DIS15_MASK) -/*! @} */ - -/*! @name STALL_OL_DIS - Peripheral Mode Stall Disable for Endpoints 7 to 0 in OUT Direction */ -/*! @{ */ - -#define USB_STALL_OL_DIS_STALL_O_DIS0_MASK (0x1U) -#define USB_STALL_OL_DIS_STALL_O_DIS0_SHIFT (0U) -/*! STALL_O_DIS0 - Disable Endpoint 0 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OL_DIS_STALL_O_DIS0(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OL_DIS_STALL_O_DIS0_SHIFT)) & USB_STALL_OL_DIS_STALL_O_DIS0_MASK) - -#define USB_STALL_OL_DIS_STALL_O_DIS1_MASK (0x2U) -#define USB_STALL_OL_DIS_STALL_O_DIS1_SHIFT (1U) -/*! STALL_O_DIS1 - Disable Endpoint 1 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OL_DIS_STALL_O_DIS1(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OL_DIS_STALL_O_DIS1_SHIFT)) & USB_STALL_OL_DIS_STALL_O_DIS1_MASK) - -#define USB_STALL_OL_DIS_STALL_O_DIS2_MASK (0x4U) -#define USB_STALL_OL_DIS_STALL_O_DIS2_SHIFT (2U) -/*! STALL_O_DIS2 - Disable Endpoint 2 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OL_DIS_STALL_O_DIS2(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OL_DIS_STALL_O_DIS2_SHIFT)) & USB_STALL_OL_DIS_STALL_O_DIS2_MASK) - -#define USB_STALL_OL_DIS_STALL_O_DIS3_MASK (0x8U) -#define USB_STALL_OL_DIS_STALL_O_DIS3_SHIFT (3U) -/*! STALL_O_DIS3 - Disable Endpoint 3 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OL_DIS_STALL_O_DIS3(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OL_DIS_STALL_O_DIS3_SHIFT)) & USB_STALL_OL_DIS_STALL_O_DIS3_MASK) - -#define USB_STALL_OL_DIS_STALL_O_DIS4_MASK (0x10U) -#define USB_STALL_OL_DIS_STALL_O_DIS4_SHIFT (4U) -/*! STALL_O_DIS4 - Disable Endpoint 4 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OL_DIS_STALL_O_DIS4(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OL_DIS_STALL_O_DIS4_SHIFT)) & USB_STALL_OL_DIS_STALL_O_DIS4_MASK) - -#define USB_STALL_OL_DIS_STALL_O_DIS5_MASK (0x20U) -#define USB_STALL_OL_DIS_STALL_O_DIS5_SHIFT (5U) -/*! STALL_O_DIS5 - Disable Endpoint 5 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OL_DIS_STALL_O_DIS5(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OL_DIS_STALL_O_DIS5_SHIFT)) & USB_STALL_OL_DIS_STALL_O_DIS5_MASK) - -#define USB_STALL_OL_DIS_STALL_O_DIS6_MASK (0x40U) -#define USB_STALL_OL_DIS_STALL_O_DIS6_SHIFT (6U) -/*! STALL_O_DIS6 - Disable Endpoint 6 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OL_DIS_STALL_O_DIS6(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OL_DIS_STALL_O_DIS6_SHIFT)) & USB_STALL_OL_DIS_STALL_O_DIS6_MASK) - -#define USB_STALL_OL_DIS_STALL_O_DIS7_MASK (0x80U) -#define USB_STALL_OL_DIS_STALL_O_DIS7_SHIFT (7U) -/*! STALL_O_DIS7 - Disable Endpoint 7 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OL_DIS_STALL_O_DIS7(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OL_DIS_STALL_O_DIS7_SHIFT)) & USB_STALL_OL_DIS_STALL_O_DIS7_MASK) -/*! @} */ - -/*! @name STALL_OH_DIS - Peripheral Mode Stall Disable for Endpoints 15 to 8 in OUT Direction */ -/*! @{ */ - -#define USB_STALL_OH_DIS_STALL_O_DIS8_MASK (0x1U) -#define USB_STALL_OH_DIS_STALL_O_DIS8_SHIFT (0U) -/*! STALL_O_DIS8 - Disable Endpoint 8 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OH_DIS_STALL_O_DIS8(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OH_DIS_STALL_O_DIS8_SHIFT)) & USB_STALL_OH_DIS_STALL_O_DIS8_MASK) - -#define USB_STALL_OH_DIS_STALL_O_DIS9_MASK (0x2U) -#define USB_STALL_OH_DIS_STALL_O_DIS9_SHIFT (1U) -/*! STALL_O_DIS9 - Disable Endpoint 9 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OH_DIS_STALL_O_DIS9(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OH_DIS_STALL_O_DIS9_SHIFT)) & USB_STALL_OH_DIS_STALL_O_DIS9_MASK) - -#define USB_STALL_OH_DIS_STALL_O_DIS10_MASK (0x4U) -#define USB_STALL_OH_DIS_STALL_O_DIS10_SHIFT (2U) -/*! STALL_O_DIS10 - Disable Endpoint 10 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OH_DIS_STALL_O_DIS10(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OH_DIS_STALL_O_DIS10_SHIFT)) & USB_STALL_OH_DIS_STALL_O_DIS10_MASK) - -#define USB_STALL_OH_DIS_STALL_O_DIS11_MASK (0x8U) -#define USB_STALL_OH_DIS_STALL_O_DIS11_SHIFT (3U) -/*! STALL_O_DIS11 - Disable Endpoint 11 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OH_DIS_STALL_O_DIS11(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OH_DIS_STALL_O_DIS11_SHIFT)) & USB_STALL_OH_DIS_STALL_O_DIS11_MASK) - -#define USB_STALL_OH_DIS_STALL_O_DIS12_MASK (0x10U) -#define USB_STALL_OH_DIS_STALL_O_DIS12_SHIFT (4U) -/*! STALL_O_DIS12 - Disable endpoint 12 OUT direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OH_DIS_STALL_O_DIS12(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OH_DIS_STALL_O_DIS12_SHIFT)) & USB_STALL_OH_DIS_STALL_O_DIS12_MASK) - -#define USB_STALL_OH_DIS_STALL_O_DIS13_MASK (0x20U) -#define USB_STALL_OH_DIS_STALL_O_DIS13_SHIFT (5U) -/*! STALL_O_DIS13 - Disable Endpoint 13 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OH_DIS_STALL_O_DIS13(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OH_DIS_STALL_O_DIS13_SHIFT)) & USB_STALL_OH_DIS_STALL_O_DIS13_MASK) - -#define USB_STALL_OH_DIS_STALL_O_DIS14_MASK (0x40U) -#define USB_STALL_OH_DIS_STALL_O_DIS14_SHIFT (6U) -/*! STALL_O_DIS14 - Disable Endpoint 14 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OH_DIS_STALL_O_DIS14(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OH_DIS_STALL_O_DIS14_SHIFT)) & USB_STALL_OH_DIS_STALL_O_DIS14_MASK) - -#define USB_STALL_OH_DIS_STALL_O_DIS15_MASK (0x80U) -#define USB_STALL_OH_DIS_STALL_O_DIS15_SHIFT (7U) -/*! STALL_O_DIS15 - Disable Endpoint 15 OUT Direction - * 0b0..Enable - * 0b1..Disable - */ -#define USB_STALL_OH_DIS_STALL_O_DIS15(x) (((uint8_t)(((uint8_t)(x)) << USB_STALL_OH_DIS_STALL_O_DIS15_SHIFT)) & USB_STALL_OH_DIS_STALL_O_DIS15_MASK) -/*! @} */ - -/*! @name CLK_RECOVER_CTRL - USB Clock Recovery Control */ -/*! @{ */ - -#define USB_CLK_RECOVER_CTRL_TRIM_INIT_VAL_SEL_MASK (0x8U) -#define USB_CLK_RECOVER_CTRL_TRIM_INIT_VAL_SEL_SHIFT (3U) -/*! TRIM_INIT_VAL_SEL - Selects the source for the initial FIRC trim fine value used after a reset. - * 0b0..Mid-scale - * 0b1..IFR - */ -#define USB_CLK_RECOVER_CTRL_TRIM_INIT_VAL_SEL(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_TRIM_INIT_VAL_SEL_SHIFT)) & USB_CLK_RECOVER_CTRL_TRIM_INIT_VAL_SEL_MASK) - -#define USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_MASK (0x20U) -#define USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_SHIFT (5U) -/*! RESTART_IFRTRIM_EN - Restart from IFR Trim Value - * 0b0..Trim fine adjustment always works based on the previous updated trim fine value. - * 0b1..Trim fine restarts from the IFR trim value whenever you detect bus_reset or bus_resume or deassert module enable. - */ -#define USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_SHIFT)) & USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_MASK) - -#define USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_MASK (0x40U) -#define USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_SHIFT (6U) -/*! RESET_RESUME_ROUGH_EN - Reset or Resume to Rough Phase Enable - * 0b0..Always works in tracking phase after the first time rough phase, to track transition. - * 0b1..Go back to rough stage whenever a bus reset or bus resume occurs. - */ -#define USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_SHIFT)) & USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_MASK) - -#define USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK (0x80U) -#define USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_SHIFT (7U) -/*! CLOCK_RECOVER_EN - Crystal-Less USB Enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_SHIFT)) & USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK) -/*! @} */ - -/*! @name CLK_RECOVER_IRC_EN - FIRC Oscillator Enable */ -/*! @{ */ - -#define USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK (0x2U) -#define USB_CLK_RECOVER_IRC_EN_IRC_EN_SHIFT (1U) -/*! IRC_EN - Fast IRC enable - * 0b0..Disable - * 0b1..Enable - */ -#define USB_CLK_RECOVER_IRC_EN_IRC_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_IRC_EN_IRC_EN_SHIFT)) & USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK) -/*! @} */ - -/*! @name CLK_RECOVER_INT_EN - Clock Recovery Combined Interrupt Enable */ -/*! @{ */ - -#define USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN_MASK (0x10U) -#define USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN_SHIFT (4U) -/*! OVF_ERROR_EN - Overflow error interrupt enable - * 0b0..The interrupt is masked - * 0b1..The interrupt is enabled - */ -#define USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN_SHIFT)) & USB_CLK_RECOVER_INT_EN_OVF_ERROR_EN_MASK) -/*! @} */ - -/*! @name CLK_RECOVER_INT_STATUS - Clock Recovery Separated Interrupt Status */ -/*! @{ */ - -#define USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_MASK (0x10U) -#define USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_SHIFT (4U) -/*! OVF_ERROR - Overflow Error Interrupt Status Flag - * 0b0..Interrupt did not occur - * 0b1..Unmasked interrupt occurred - * 0b0..No effect - * 0b1..Clear the flag - */ -#define USB_CLK_RECOVER_INT_STATUS_OVF_ERROR(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_SHIFT)) & USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_MASK) -/*! @} */ - -/*! - * @} - */ -/* end of group USB_Register_Masks */ - -/*! - * @brief This type of structure instance is used to implement the buffer descriptor for USB. - */ -typedef struct -{ - union { - uint32_t head; /*!< Head. */ - struct - { - uint32_t reserved0 : 2; /*!< RESEVED. */ - uint32_t bdt_stall : 1; /*!< Stall. */ - uint32_t dts : 1; /*!< Data shift sync. */ - uint32_t ninc : 1; /*!< DMA addr cannot increasing. */ - uint32_t keep : 1; /*!< Keep BD held by USB. */ - uint32_t data : 1; /*!< DATA0 or DATA1. */ - uint32_t own : 1; /*!< Owner, 0 is CPU, 1 is USB. */ - uint32_t reserved1 : 8; /*!< RESEVED. */ - uint32_t bc : 10; /*!< Packet size. */ - uint32_t reserved2 : 6; /*!< RESEVED. */ - }; - struct - { - uint32_t reserved3 : 2; /*!< RESEVED. */ - uint32_t tok_pid : 4; /*!< Token pid. */ - uint32_t reserved4 : 26; /*!< RESEVED. */ - }; - }; - uint32_t addr; /*!< Buffer addr. */ -} kinetis_bd_t; - -/*! - * @brief This type of structure instance is used to implement the buffer descriptor table for USB. - */ -typedef union { - kinetis_bd_t table[16][2][2]; /*!< [EndPoint] [Direction] [Odd_Even]. */ - uint8_t buffer[512]; /*!< buffer. */ -} kinetis_bd_table_t; - -/** - * @brief USBFS TokenPid type. - */ -typedef enum { - USB_TOKEN_PID_OUT = 0x1u, /*!< USB Token Pid: OUT. */ - USB_TOKEN_PID_IN = 0x9u, /*!< USB Token Pid: IN. */ - USB_TOKEN_PID_SETUP = 0xDu, /*!< USB Token Pid: SETUP. */ - USB_TOKEN_PID_DATA0 = 0x03, /*!< USB Token Pid: DATA0. */ - USB_TOKEN_PID_DATA1 = 0x0B, /*!< USB Token Pid: DATA1. */ - USB_TOKEN_PID_ACK = 0x02, /*!< USB Token Pid: ACK. */ - USB_TOKEN_PID_STALL = 0x0E, /*!< USB Token Pid: STALL. */ - USB_TOKEN_PID_NAK = 0x0A, /*!< USB Token Pid: NAK. */ - USB_TOKEN_PID_BUSTIMEOUT = 0x00, /*!< USB Token Pid: BUSTO. */ - USB_TOKEN_PID_ERR = 0x0f, /*!< USB Token Pid: ERR. */ -} USB_TOKEN_PID_Type; - -typedef struct { - KINETIS_TypeDef base; - __IO uint8_t USBCTRL; /**< USB Control, offset: 0x100 */ - uint8_t RESERVED_22[3]; - __I uint8_t OBSERVE; /**< USB OTG Observe, offset: 0x104 */ - uint8_t RESERVED_23[3]; - __IO uint8_t CONTROL; /**< USB OTG Control, offset: 0x108 */ - uint8_t RESERVED_24[3]; - __IO uint8_t USBTRC0; /**< USB Transceiver Control 0, offset: 0x10C */ - uint8_t RESERVED_25[7]; - __IO uint8_t USBFRMADJUST; /**< Frame Adjust, offset: 0x114 */ - uint8_t RESERVED_26[15]; - __IO uint8_t KEEP_ALIVE_CTRL; /**< Keep Alive Mode Control, offset: 0x124 */ - uint8_t RESERVED_27[3]; - __IO uint8_t KEEP_ALIVE_WKCTRL; /**< Keep Alive Mode Wakeup Control, offset: 0x128 */ - uint8_t RESERVED_28[3]; - __IO uint8_t MISCCTRL; /**< Miscellaneous Control, offset: 0x12C */ - uint8_t RESERVED_29[3]; - __IO uint8_t STALL_IL_DIS; /**< Peripheral Mode Stall Disable for Endpoints 7 to 0 in IN Direction, offset: 0x130 */ - uint8_t RESERVED_30[3]; - __IO uint8_t STALL_IH_DIS; /**< Peripheral Mode Stall Disable for Endpoints 15 to 8 in IN Direction, offset: 0x134 */ - uint8_t RESERVED_31[3]; - __IO uint8_t STALL_OL_DIS; /**< Peripheral Mode Stall Disable for Endpoints 7 to 0 in OUT Direction, offset: 0x138 */ - uint8_t RESERVED_32[3]; - __IO uint8_t STALL_OH_DIS; /**< Peripheral Mode Stall Disable for Endpoints 15 to 8 in OUT Direction, offset: 0x13C */ - uint8_t RESERVED_33[3]; - __IO uint8_t CLK_RECOVER_CTRL; /**< USB Clock Recovery Control, offset: 0x140 */ - uint8_t RESERVED_34[3]; - __IO uint8_t CLK_RECOVER_IRC_EN; /**< FIRC Oscillator Enable, offset: 0x144 */ - uint8_t RESERVED_35[15]; - __IO uint8_t CLK_RECOVER_INT_EN; /**< Clock Recovery Combined Interrupt Enable, offset: 0x154 */ - uint8_t RESERVED_36[7]; - __IO uint8_t CLK_RECOVER_INT_STATUS; /**< Clock Recovery Separated Interrupt Status, offset: 0x15C */ -} KINETIS_MCX_TypeDef; - -void usb_dc_low_level_init(uint8_t busid); -void usb_dc_low_level_deinit(uint8_t busid); - -void usbd_kinetis_delay_ms(uint8_t ms); -#endif \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_dc_musb.c b/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_dc_musb.c index 845e583..d66ec39 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_dc_musb.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_dc_musb.c @@ -273,7 +273,7 @@ int usb_dc_init(uint8_t busid) } /* Enable USB interrupts */ - HWREGB(USB_BASE + MUSB_IE_OFFSET) = USB_IE_RESET | USB_IE_SUSPND | USB_IE_RESUME; + HWREGB(USB_BASE + MUSB_IE_OFFSET) = USB_IE_RESET; HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = USB_TXIE_EP0; HWREGH(USB_BASE + MUSB_RXIE_OFFSET) = 0; @@ -296,14 +296,6 @@ int usbd_set_address(uint8_t busid, const uint8_t addr) return 0; } -int usbd_set_remote_wakeup(uint8_t busid) -{ - HWREGB(USB_BASE + MUSB_POWER_OFFSET) |= USB_POWER_RESUME; - usbd_musb_delay_ms(10); - HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_RESUME; - return 0; -} - uint8_t usbd_get_port_speed(uint8_t busid) { uint8_t speed = USB_SPEED_UNKNOWN; @@ -509,26 +501,6 @@ int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep) int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled) { - uint8_t ep_idx = USB_EP_GET_IDX(ep); - uint8_t old_ep_idx; - - old_ep_idx = musb_get_active_ep(); - musb_set_active_ep(ep_idx); - - if (USB_EP_DIR_IS_OUT(ep)) { - if(HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) & USB_RXCSRL1_STALL) { - *stalled = 1; - } else { - *stalled = 0; - } - } else { - if(HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_STALL) { - *stalled = 1; - } else { - *stalled = 0; - } - } - musb_set_active_ep(old_ep_idx); return 0; } @@ -734,11 +706,9 @@ void USBD_IRQHandler(uint8_t busid) } if (is & USB_IS_RESUME) { - usbd_event_resume_handler(0); } if (is & USB_IS_SUSPEND) { - usbd_event_suspend_handler(0); } txis &= HWREGH(USB_BASE + MUSB_TXIE_OFFSET); diff --git a/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_glue_bk.c b/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_glue_bk.c index 2af1e36..7eb987f 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_glue_bk.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_glue_bk.c @@ -277,11 +277,6 @@ void usb_dc_low_level_deinit(void) sys_drv_dev_clk_pwr_up(CLK_PWR_ID_USB_1, CLK_PWR_CTRL_PWR_DOWN); } -void usbd_musb_delay_ms(uint8_t ms) -{ - /* implement later */ -} - extern void USBH_IRQHandler(uint8_t busid); void USBH_IRQ(void) diff --git a/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_glue_es.c b/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_glue_es.c index b1a8f8e..adfc293 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_glue_es.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_glue_es.c @@ -50,9 +50,4 @@ uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg) uint32_t usb_get_musb_ram_size(void) { return 4096; -} - -void usbd_musb_delay_ms(uint8_t ms) -{ - /* implement later */ -} +} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_glue_sunxi.c b/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_glue_sunxi.c index 706a60c..4339230 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_glue_sunxi.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_glue_sunxi.c @@ -56,9 +56,4 @@ uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg) uint32_t usb_get_musb_ram_size(void) { return 8192; -} - -void usbd_musb_delay_ms(uint8_t ms) -{ - /* implement later */ -} +} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c b/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c index 39c787f..b5d7e36 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_hc_musb.c @@ -475,12 +475,10 @@ static void musb_pipe_free(struct musb_pipe *pipe) __WEAK void usb_hc_low_level_init(struct usbh_bus *bus) { - (void)bus; } __WEAK void usb_hc_low_level_deinit(struct usbh_bus *bus) { - (void)bus; } int usb_hc_init(struct usbh_bus *bus) @@ -655,7 +653,6 @@ int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u } } - status |= (1 << HUB_PORT_FEATURE_POWER); memcpy(buf, &status, 4); break; default: diff --git a/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_musb_reg.h b/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_musb_reg.h index 1776537..885bdd4 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_musb_reg.h +++ b/rt-thread/components/drivers/usb/cherryusb/port/musb/usb_musb_reg.h @@ -3882,6 +3882,5 @@ struct musb_fifo_cfg { uint8_t usbd_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg); uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg); uint32_t usb_get_musb_ram_size(void); -void usbd_musb_delay_ms(uint8_t ms); #endif diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ohci/README.md b/rt-thread/components/drivers/usb/cherryusb/port/ohci/README.md index 928eb0c..34e753c 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/ohci/README.md +++ b/rt-thread/components/drivers/usb/cherryusb/port/ohci/README.md @@ -1,23 +1,18 @@ # Note -This OHCI is a companion controller of EHCI. But you can use OHCI only without CONFIG_USB_EHCI_WITH_OHCI definition. - -**And you need to pay for using OHCI driver**. +This OHCI is a companion controller of EHCI. ## Support Chip List ### AllwinnerTech -- F133(EHCI + OHCI) +- F133 ### Nuvoton -- Nuvoton all series(EHCI + OHCI, OHCI only) +- Nuvoton all series ### Artinchip -- d13x, d21x(EHCI + OHCI) +- d13x, d21x -### NXP - -- LPC4X/LPC5X(OHCI only) \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_glue_lpc.c b/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_glue_lpc.c deleted file mode 100644 index 51ab781..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_glue_lpc.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2024, sakumisu - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "fsl_device_registers.h" -#include "fsl_power.h" -#include "usbh_core.h" - -#if defined(CONFIG_USB_EHCI_WITH_OHCI) -#error "lpc does not have ehci" -#endif - -void usb_hc_low_level_init(struct usbh_bus *bus) -{ -#if ((defined FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT)) - SYSMPU_Enable(SYSMPU, 0); -#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */ - - NVIC_ClearPendingIRQ(USB0_IRQn); - NVIC_ClearPendingIRQ(USB0_NEEDCLK_IRQn); - - POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*< Turn on USB0 Phy */ - - RESET_PeripheralReset(kUSB0D_RST_SHIFT_RSTn); - RESET_PeripheralReset(kUSB0HSL_RST_SHIFT_RSTn); - RESET_PeripheralReset(kUSB0HMR_RST_SHIFT_RSTn); - - CLOCK_EnableUsbfs0HostClock(kCLOCK_UsbfsSrcPll1, 48000000U); - - NVIC_SetPriority(USB0_IRQn, 3); - EnableIRQ(USB0_IRQn); -} - - -void usb_hc_low_level_deinit(struct usbh_bus *bus) -{ - DisableIRQ(USB0_IRQn); -} - -void USB0_IRQHandler(void) -{ - extern void USBH_IRQHandler(uint8_t busid); - USBH_IRQHandler(0); -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.c b/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.c index 2bec2a0..b3d6582 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.c +++ b/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.c @@ -3,59 +3,19 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include "usb_hc_ohci.h" - -/* Frame Interval / Periodic Start. - * - * At 12Mbps, there are 12000 bit time in each 1Msec frame. - */ - -#define OHCI_FMINTERVAL_FI (12000 - 1) -#define OHCI_FMINTERVAL_FSMPS ((6 * (OHCI_FMINTERVAL_FI - 210)) / 7) -#define DEFAULT_FMINTERVAL ((OHCI_FMINTERVAL_FSMPS << OHCI_FMINT_FSMPS_SHIFT) | OHCI_FMINTERVAL_FI) -#define DEFAULT_PERSTART ((OHCI_FMINTERVAL_FI * 9) / 10) - -struct ohci_hcd g_ohci_hcd[CONFIG_USBHOST_MAX_BUS]; - -USB_NOCACHE_RAM_SECTION struct ohci_ed_hw g_ohci_ed_pool[CONFIG_USBHOST_MAX_BUS][CONFIG_USB_OHCI_ED_NUM]; -USB_NOCACHE_RAM_SECTION struct ohci_hcca ohci_hcca[CONFIG_USBHOST_MAX_BUS]; +#include "usb_ohci_priv.h" +#include "usb_ehci_priv.h" int ohci_init(struct usbh_bus *bus) { volatile uint32_t timeout = 0; uint32_t regval; - struct ohci_ed_hw *ed; - - memset(&g_ohci_hcd[bus->hcd.hcd_id], 0, sizeof(struct ohci_hcd)); - memset(g_ohci_ed_pool[bus->hcd.hcd_id], 0, sizeof(struct ohci_ed_hw) * CONFIG_USB_OHCI_ED_NUM); - - for (uint32_t i = 0; i < 32; i++) { - ohci_hcca[bus->hcd.hcd_id].inttbl[i] = 0; - } - - for (uint8_t index = 0; index < CONFIG_USB_OHCI_ED_NUM; index++) { - ed = &g_ohci_ed_pool[bus->hcd.hcd_id][index]; - if ((uint32_t)&ed->hw % 32) { - USB_LOG_ERR("struct ohci_ed_hw is not align 32\r\n"); - return -USB_ERR_INVAL; - } - for (uint8_t i = 0; i < CONFIG_USB_OHCI_TD_NUM; i++) { - if ((uint32_t)&ed->td_pool[i] % 32) { - USB_LOG_ERR("struct ohci_td_hw is not align 32\r\n"); - return -USB_ERR_INVAL; - } - } - } - - for (uint8_t index = 0; index < CONFIG_USB_OHCI_ED_NUM; index++) { - ed = &g_ohci_ed_pool[bus->hcd.hcd_id][index]; - ed->waitsem = usb_osal_sem_create(0); - } USB_LOG_INFO("OHCI hcrevision:0x%02x\r\n", (unsigned int)OHCI_HCOR->hcrevision); - OHCI_HCOR->hcintdis = OHCI_INT_MIE; OHCI_HCOR->hccontrol = 0; + OHCI_HCOR->hccontrolheaded = 0; + OHCI_HCOR->hcbulkheaded = 0; OHCI_HCOR->hccmdsts = OHCI_CMDST_HCR; while (OHCI_HCOR->hccmdsts & OHCI_CMDST_HCR) { @@ -66,39 +26,45 @@ int ohci_init(struct usbh_bus *bus) } } + /* Frame Interval / Periodic Start. + * + * At 12Mbps, there are 12000 bit time in each 1Msec frame. + */ + +#define BITS_PER_FRAME 12000 +#define FI (BITS_PER_FRAME - 1) +#define FSMPS ((6 * (FI - 210)) / 7) +#define DEFAULT_FMINTERVAL ((FSMPS << OHCI_FMINT_FSMPS_SHIFT) | FI) +#define DEFAULT_PERSTART (((9 * BITS_PER_FRAME) / 10) - 1) + OHCI_HCOR->hcfminterval = DEFAULT_FMINTERVAL; OHCI_HCOR->hcperiodicstart = DEFAULT_PERSTART; - OHCI_HCOR->hclsthreshold = 0x628; - OHCI_HCOR->hccontrolheaded = 0; - OHCI_HCOR->hcbulkheaded = 0; - OHCI_HCOR->hchcca = (uintptr_t)&ohci_hcca[bus->hcd.hcd_id]; + /* Put HC in operational state */ + regval = OHCI_HCOR->hccontrol; + regval &= ~OHCI_CTRL_HCFS_MASK; + regval |= OHCI_CTRL_HCFS_OPER; + OHCI_HCOR->hccontrol = regval; + + /* Set global power in HcRhStatus */ + OHCI_HCOR->hcrhsts = OHCI_RHSTATUS_SGP; + + /* Set HCCA base address */ + OHCI_HCOR->hchcca = 0; /* Clear pending interrupts */ regval = OHCI_HCOR->hcintsts; OHCI_HCOR->hcintsts = regval; - /* Put HC in operational state */ - regval = OHCI_HCOR->hccontrol; - regval &= ~OHCI_CTRL_CBSR; - regval &= ~OHCI_CTRL_HCFS_MASK; - regval |= OHCI_CTRL_HCFS_OPER; - regval |= OHCI_CTRL_CBSR; - regval |= OHCI_CTRL_CLE; - OHCI_HCOR->hccontrol = regval; - - g_ohci_hcd[bus->hcd.hcd_id].n_ports = OHCI_HCOR->hcrhdescriptora & OHCI_RHDESCA_NDP_MASK; - USB_LOG_INFO("OHCI n_ports:%d\r\n", g_ohci_hcd[bus->hcd.hcd_id].n_ports); - - OHCI_HCOR->hcrhdescriptora &= ~OHCI_RHDESCA_PSM; - OHCI_HCOR->hcrhdescriptora &= ~OHCI_RHDESCA_NPS; - - /* Set global power in HcRhStatus */ - OHCI_HCOR->hcrhsts = OHCI_RHSTATUS_SGP; - usb_osal_msleep(20); + for (uint8_t port = 0; port < g_ehci_hcd[bus->hcd.hcd_id].n_pcc; port++) { + regval = OHCI_HCOR->hcrhportsts[port]; + regval |= OHCI_RHPORTST_PPS; + OHCI_HCOR->hcrhportsts[port] = regval; + } /* Enable OHCI interrupts */ - OHCI_HCOR->hcinten = OHCI_INT_WDH | OHCI_INT_RHSC | OHCI_INT_MIE; + OHCI_HCOR->hcinten = OHCI_INT_SO | OHCI_INT_RD | OHCI_INT_UE | OHCI_INT_OC | + OHCI_INT_WDH | OHCI_INT_RHSC | OHCI_INT_MIE; return 0; } @@ -106,25 +72,15 @@ int ohci_init(struct usbh_bus *bus) int ohci_deinit(struct usbh_bus *bus) { uint32_t regval; - struct ohci_ed_hw *ed; /* Disable OHCI interrupts */ - OHCI_HCOR->hcintdis = OHCI_INT_WDH | OHCI_INT_RHSC | OHCI_INT_MIE; + OHCI_HCOR->hcintdis = OHCI_INT_SO | OHCI_INT_RD | OHCI_INT_UE | OHCI_INT_OC | + OHCI_INT_WDH | OHCI_INT_RHSC | OHCI_INT_MIE; - /* Clear pending interrupts */ - regval = OHCI_HCOR->hcintsts; - OHCI_HCOR->hcintsts = regval; - - OHCI_HCOR->hcrhsts &= ~OHCI_RHSTATUS_SGP; - - regval = OHCI_HCOR->hccontrol; - regval &= ~OHCI_CTRL_HCFS_MASK; - regval |= OHCI_CTRL_HCFS_SUSPEND; - OHCI_HCOR->hccontrol = regval; - - for (uint8_t index = 0; index < CONFIG_USB_OHCI_ED_NUM; index++) { - ed = &g_ohci_ed_pool[bus->hcd.hcd_id][index]; - usb_osal_sem_delete(ed->waitsem); + for (uint8_t port = 0; port < g_ehci_hcd[bus->hcd.hcd_id].n_pcc; port++) { + regval = OHCI_HCOR->hcrhportsts[port]; + regval &= ~OHCI_RHPORTST_PPS; + OHCI_HCOR->hcrhportsts[port] = regval; } return 0; @@ -141,7 +97,7 @@ int ohci_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u uint8_t port; uint32_t temp; - nports = g_ohci_hcd[bus->hcd.hcd_id].n_ports; + nports = g_ehci_hcd[bus->hcd.hcd_id].n_pcc; port = setup->wIndex; if (setup->bmRequestType & USB_REQUEST_RECIPIENT_DEVICE) { @@ -183,46 +139,28 @@ int ohci_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u switch (setup->wValue) { case HUB_PORT_FEATURE_ENABLE: - temp = OHCI_RHPORTST_CCS; break; case HUB_PORT_FEATURE_SUSPEND: - temp = OHCI_HCOR->hccontrol; - temp &= ~OHCI_CTRL_HCFS_MASK; - temp |= OHCI_CTRL_HCFS_RESUME; - OHCI_HCOR->hccontrol = temp; - usb_osal_msleep(20); - - temp = OHCI_HCOR->hccontrol; - temp &= ~OHCI_CTRL_HCFS_MASK; - temp |= OHCI_CTRL_HCFS_OPER; - OHCI_HCOR->hccontrol = temp; - - temp = OHCI_RHPORTST_POCI; - break; case HUB_PORT_FEATURE_C_SUSPEND: - temp = OHCI_RHPORTST_PSSC; break; case HUB_PORT_FEATURE_POWER: - OHCI_HCOR->hcrhsts = OHCI_RHSTATUS_CGP; - temp = OHCI_RHPORTST_LSDA; break; case HUB_PORT_FEATURE_C_CONNECTION: - temp = OHCI_RHPORTST_CSC; + OHCI_HCOR->hcrhportsts[port - 1] |= OHCI_RHPORTST_CSC; break; case HUB_PORT_FEATURE_C_ENABLE: - temp = OHCI_RHPORTST_PESC; + OHCI_HCOR->hcrhportsts[port - 1] |= OHCI_RHPORTST_PESC; break; case HUB_PORT_FEATURE_C_OVER_CURREN: - temp = OHCI_RHPORTST_OCIC; + OHCI_HCOR->hcrhportsts[port - 1] |= OHCI_RHPORTST_OCIC; break; case HUB_PORT_FEATURE_C_RESET: - temp = OHCI_RHPORTST_PRSC; + OHCI_HCOR->hcrhportsts[port - 1] |= OHCI_RHPORTST_PRSC; break; default: return -USB_ERR_NOTSUPP; } - OHCI_HCOR->hcrhportsts[port - 1] = temp; break; case HUB_REQUEST_SET_FEATURE: if (!port || port > nports) { @@ -231,17 +169,11 @@ int ohci_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u switch (setup->wValue) { case HUB_PORT_FEATURE_SUSPEND: - temp = OHCI_HCOR->hccontrol; - temp &= ~OHCI_CTRL_HCFS_MASK; - temp |= OHCI_CTRL_HCFS_SUSPEND; - OHCI_HCOR->hccontrol = temp; - break; case HUB_PORT_FEATURE_POWER: - OHCI_HCOR->hcrhsts = OHCI_RHSTATUS_SGP; break; case HUB_PORT_FEATURE_RESET: - OHCI_HCOR->hcrhportsts[port - 1] = OHCI_RHPORTST_PRS; + OHCI_HCOR->hcrhportsts[port - 1] |= OHCI_RHPORTST_PRS; while (OHCI_HCOR->hcrhportsts[port - 1] & OHCI_RHPORTST_PRS) { } @@ -256,6 +188,7 @@ int ohci_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, u return -USB_ERR_INVAL; } temp = OHCI_HCOR->hcrhportsts[port - 1]; + memcpy(buf, &temp, 4); break; default: @@ -283,9 +216,9 @@ void OHCI_IRQHandler(uint8_t busid) bus = &g_usbhost_bus[busid]; usbsts = OHCI_HCOR->hcintsts & OHCI_HCOR->hcinten; + OHCI_HCOR->hcintsts = usbsts; if (usbsts & OHCI_INT_RHSC) { - OHCI_HCOR->hcintsts = OHCI_INT_RHSC; for (int port = 0; port < CONFIG_USBHOST_MAX_RHPORTS; port++) { uint32_t portsc = OHCI_HCOR->hcrhportsts[port]; @@ -303,51 +236,5 @@ void OHCI_IRQHandler(uint8_t busid) } } if (usbsts & OHCI_INT_WDH) { - OHCI_HCOR->hcintsts = OHCI_INT_WDH; } -} - -#ifndef CONFIG_USB_EHCI_WITH_OHCI -__WEAK void usb_hc_low_level_init(struct usbh_bus *bus) -{ - (void)bus; -} - -__WEAK void usb_hc_low_level_deinit(struct usbh_bus *bus) -{ - (void)bus; -} - -int usb_hc_init(struct usbh_bus *bus) -{ - usb_hc_low_level_init(bus); - return ohci_init(bus); -} - -int usb_hc_deinit(struct usbh_bus *bus) -{ - ohci_deinit(bus); - usb_hc_low_level_deinit(bus); - return 0; -} - -int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf) -{ - return ohci_roothub_control(bus, setup, buf); -} - -int usbh_submit_urb(struct usbh_urb *urb) -{ - return ohci_submit_urb(urb); -} - -int usbh_kill_urb(struct usbh_urb *urb) -{ - return ohci_kill_urb(urb); -} - -void USBH_IRQHandler(uint8_t busid) -{ - OHCI_IRQHandler(busid); -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.h b/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.h index 19d5190..030350e 100644 --- a/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.h +++ b/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_hc_ohci.h @@ -1,56 +1,484 @@ -/* - * Copyright (c) 2024, sakumisu +/**************************************************************************** + * include/nuttx/usb/ohci.h * - * SPDX-License-Identifier: Apache-2.0 + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_USB_OHCI_H +#define __INCLUDE_NUTTX_USB_OHCI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register offsets *********************************************************/ + +/* Control and status registers (section 7.1) */ + +#define OHCI_HCIREV_OFFSET 0x0000 /* HcRevision: Version of HCI specification */ +#define OHCI_CTRL_OFFSET 0x0004 /* HcControl: HC control */ +#define OHCI_CMDST_OFFSET 0x0008 /* HcCommandStatus: HC command status */ +#define OHCI_INTST_OFFSET 0x000c /* HcInterruptStatus: HC interrupt status */ +#define OHCI_INTEN_OFFSET 0x0010 /* HcInterruptEnable: HC interrupt enable */ +#define OHCI_INTDIS_OFFSET 0x0014 /* HcInterruptDisable: HC interrupt disable */ + +/* Memory pointer registers (section 7.2) */ + +#define OHCI_HCCA_OFFSET 0x0018 /* HcHCCA: HC communication area */ +#define OHCI_PERED_OFFSET 0x001c /* HcPeriodCurrentED: Current isoc or int endpoint desc */ +#define OHCI_CTRLHEADED_OFFSET 0x0020 /* HcControlHeadED: First EP desc in the control list */ +#define OHCI_CTRLED_OFFSET 0x0024 /* HcControlCurrentED: Current EP desc in the control list */ +#define OHCI_BULKHEADED_OFFSET 0x0028 /* HcBulkHeadED: First EP desc in the bulk list */ +#define OHCI_BULKED_OFFSET 0x002c /* HcBulkCurrentED: Current EP desc in the bulk list */ +#define OHCI_DONEHEAD_OFFSET 0x0030 /* HcDoneHead: Last transfer desc added to DONE queue */ + +/* Frame counter registers (section 7.3) */ + +#define OHCI_FMINT_OFFSET 0x0034 /* HcFmInterval: Bit time interval that would not cause overrun */ +#define OHCI_FMREM_OFFSET 0x0038 /* HcFmRemaining: Bit time remaining in current frame */ +#define OHCI_FMNO_OFFSET 0x003c /* HcFmNumber: Frame number counter */ +#define OHCI_PERSTART_OFFSET 0x0040 /* HcPeriodicStart: Time to start processing periodic list */ + +/* Root hub registers (section 7.4) */ + +#define OHCI_LSTHRES_OFFSET 0x0044 /* HcLSThreshold: Commit to transfer threshold */ +#define OHCI_RHDESCA_OFFSET 0x0048 /* HcRhDescriptorA: Describes root hub (part A) */ +#define OHCI_RHDESCB_OFFSET 0x004c /* HcRhDescriptorB: Describes root hub (part B) */ +#define OHCI_RHSTATUS_OFFSET 0x0050 /* HcRhStatus: Root hub status */ + +#define OHCI_MAX_RHPORT 15 /* Maximum number of OHCI root hub ports */ + +#define OHCI_RHPORTST_OFFSET(n) (0x0054 + (((n) - 1) << 2)) +#define OHCI_RHPORTST1_OFFSET 0x0054 /* HcRhPort1Status: Root hub port status 1 */ +#define OHCI_RHPORTST2_OFFSET 0x0058 /* HcRhPort2Status: Root hub port status 2 */ +#define OHCI_RHPORTST3_OFFSET 0x005c /* HcRhPort3Status: Root hub port status 3 */ +#define OHCI_RHPORTST4_OFFSET 0x0060 /* HcRhPort4Status: Root hub port status 4 */ +#define OHCI_RHPORTST5_OFFSET 0x0064 /* HcRhPort5Status: Root hub port status 5 */ +#define OHCI_RHPORTST6_OFFSET 0x0068 /* HcRhPort6Status: Root hub port status 6 */ +#define OHCI_RHPORTST7_OFFSET 0x006c /* HcRhPort7Status: Root hub port status 7 */ +#define OHCI_RHPORTST8_OFFSET 0x0070 /* HcRhPort8Status: Root hub port status 8 */ +#define OHCI_RHPORTST9_OFFSET 0x0074 /* HcRhPort9Status: Root hub port status 9 */ +#define OHCI_RHPORTST10_OFFSET 0x0078 /* HcRhPort10Status: Root hub port status 10 */ +#define OHCI_RHPORTST11_OFFSET 0x007c /* HcRhPort11Status: Root hub port status 11 */ +#define OHCI_RHPORTST12_OFFSET 0x0080 /* HcRhPort12Status: Root hub port status 12 */ +#define OHCI_RHPORTST13_OFFSET 0x0084 /* HcRhPort13Status: Root hub port status 13 */ +#define OHCI_RHPORTST14_OFFSET 0x0088 /* HcRhPort14Status: Root hub port status 14 */ +#define OHCI_RHPORTST15_OFFSET 0x008c /* HcRhPort15Status: Root hub port status 15 */ + +/* Register bit definitions *************************************************/ + +/* HcRevision: Version of HCI specification (7.1.1) */ + +#define OHCI_HCIREV_SHIFT (0) /* Bits 0-7: HCI spec version (BCD) */ +#define OHCI_HCIREV_MASK (0xff << OHCI_HCIREV_SHIFT) + +/* HcControl: HC control (7.1.2) */ + +#define OHCI_CTRL_CBSR (3 << 0) /* Bit 0: Control/bulk service ratio */ +#define OHCI_CTRL_PLE (1 << 2) /* Bit 1: Periodic list enable */ +#define OHCI_CTRL_IE (1 << 3) /* Bit 2: Isochronous enable */ +#define OHCI_CTRL_CLE (1 << 4) /* Bit 3: Control list enable */ +#define OHCI_CTRL_BLE (1 << 5) /* Bit 4: Bulk list enable */ +#define OHCI_CTRL_HCFS_SHIFT (6) /* Bits 6-7: Host controller functional state */ +#define OHCI_CTRL_HCFS_MASK (3 << OHCI_CTRL_HCFS_SHIFT) +# define OHCI_CTRL_HCFS_RESET (0 << OHCI_CTRL_HCFS_SHIFT) +# define OHCI_CTRL_HCFS_RESUME (1 << OHCI_CTRL_HCFS_SHIFT) +# define OHCI_CTRL_HCFS_OPER (2 << OHCI_CTRL_HCFS_SHIFT) +# define OHCI_CTRL_HCFS_SUSPEND (3 << OHCI_CTRL_HCFS_SHIFT) +#define OHCI_CTRL_IR (1 << 8) /* Bit 8: Interrupt routing */ +#define OHCI_CTRL_RWC (1 << 9) /* Bit 9: Remote wakeup connected */ +#define OHCI_CTRL_RWE (1 << 10) /* Bit 10: Remote wakeup enable */ + /* Bits 11-31: Reserved */ + +/* HcCommandStatus: HC command status (7.1.3) */ + +#define OHCI_CMDST_HCR (1 << 0) /* Bit 0: Host controller reset */ +#define OHCI_CMDST_CLF (1 << 1) /* Bit 1: Control list filled */ +#define OHCI_CMDST_BLF (1 << 2) /* Bit 2: Bulk list filled */ +#define OHCI_CMDST_OCR (1 << 3) /* Bit 3: Ownership change request */ + /* Bits 4-15: Reserved */ +#define OHCI_CMDST_SOC (3 << 16) /* Bit 16: Scheduling overrun count */ + /* Bits 17-31: Reserved */ + +/* HcInterruptStatus: HC interrupt status (7.1.4), + * HcInterruptEnable: HC interrupt enable (7.1.5), and + * HcInterruptDisable: HC interrupt disable (7.1.6) */ -#ifndef _USB_OHCI_PRIV_H -#define _USB_OHCI_PRIV_H -#include "usbh_core.h" -#include "usbh_hub.h" -#include "usb_ohci_reg.h" +#define OHCI_INT_SO (1 << 0) /* Bit 0: Scheduling overrun */ +#define OHCI_INT_WDH (1 << 1) /* Bit 1: Writeback done head */ +#define OHCI_INT_SF (1 << 2) /* Bit 2: Start of frame */ +#define OHCI_INT_RD (1 << 3) /* Bit 3: Resume detected */ +#define OHCI_INT_UE (1 << 4) /* Bit 4: Unrecoverable error */ +#define OHCI_INT_FNO (1 << 5) /* Bit 5: Frame number overflow */ +#define OHCI_INT_RHSC (1 << 6) /* Bit 6: Root hub status change */ + /* Bits 7-29: Reserved */ +#define OHCI_INT_OC (1 << 30) /* Bit 30: Ownership change */ +#define OHCI_INT_MIE (1 << 31) /* Bit 31: Master interrupt enable + * (Enable/disable only) */ -#define OHCI_HCOR ((struct ohci_hcor *)(uintptr_t)(bus->hcd.reg_base + CONFIG_USB_OHCI_HCOR_OFFSET)) +/* HcHCCA: HC communication area (7.2.1): + * + * 32-bits aligned to 256 byte boundary. + */ -#define OHCI_PTR2ADDR(x) ((uint32_t)(uintptr_t)(x) & ~0x0F) -#define OHCI_ADDR2ED(x) ((struct ohci_ed_hw *)(uintptr_t)((uint32_t)(x) & ~0x0F)) -#define OHCI_ADDR2TD(x) ((struct ohci_td_hw *)(uintptr_t)((uint32_t)(x) & ~0x0F)) +/* HcPeriodCurrentED: Current isoc or int endpoint desc (7.2.2), + * HcControlHeadED: First EP desc in the control list (7.2.3), + * HcControlCurrentED: Current EP desc in the control list (7.2.4), + * HcBulkHeadED: First EP desc in the bulk list (7.2.5), + * HcBulkCurrentED: Current EP desc in the bulk list (7.2.6), and + * HcDoneHead: Last transfer desc added to DONE queue (7.2.7): + * + * All 32-bits aligned to an 8-byte boundary + */ -#ifndef CONFIG_USB_OHCI_ED_NUM -#define CONFIG_USB_OHCI_ED_NUM CONFIG_USBHOST_PIPE_NUM -#endif -#ifndef CONFIG_USB_OHCI_TD_NUM -#define CONFIG_USB_OHCI_TD_NUM 3 -#endif +/* HcFmInterval: Bit time interval that would not cause overrun (7.3.1) */ -struct ohci_ed_hw; -struct ohci_td_hw { - struct ohci_gtd hw; - struct usbh_urb *urb; - uint32_t buf_start; - uint32_t length; -} __attribute__((aligned(32))); /* min is 16bytes, we use 32 for cacheline */ +#define OHCI_FMINT_FI_SHIFT (0) /* Bits 0-13: Frame interval */ +#define OHCI_FMINT_FI_MASK (0x3fff << OHCI_FMINT_FI_SHIFT) + /* Bits 14-15: Reserved */ +#define OHCI_FMINT_FSMPS_SHIFT (16) /* Bits 16-30: FS largest packet data */ +#define OHCI_FMINT_FSMPS_MASK (0x7fff << OHCI_FMINT_FSMPS_SHIFT) +#define OHCI_FMINT_FIT (1 << 31) /* Bit 31: Frame interval toggle */ -struct ohci_ed_hw { - struct ohci_ed hw; - struct ohci_td_hw td_pool[CONFIG_USB_OHCI_TD_NUM]; - uint32_t td_count; - uint8_t ed_type; - usb_osal_sem_t waitsem; -} __attribute__((aligned(32))); /* min is 16bytes, we use 32 for cacheline */ +/* HcFmRemaining: Bit time remaining in current frame (7.3.2) */ -struct ohci_hcd { - bool ohci_ed_used[CONFIG_USB_OHCI_ED_NUM]; - uint8_t n_ports; +#define OHCI_FMREM_FR_SHIFT (0) /* Bits 0-13: Frame remaining */ +#define OHCI_FMREM_FR_MASK (0x3fff << OHCI_FMREM_FR_SHIFT) + /* Bits 16-30: Reserved */ +#define OHCI_FMINT_FRT (1 << 31) /* Bit 31: Frame remaining toggle */ + +/* HcFmNumber: Frame number counter (7.3.3) */ + +#define OHCI_FMNO_FI_SHIFT (0) /* Bits 0-15: Frame number */ +#define OHCI_FMNO_FI_MASK (0xffff << OHCI_FMINT_FI_SHIFT) + /* Bits 16-31: Reserved */ + +/* HcPeriodicStart: Time to start processing periodic list (7.3.4) */ + +#define OHCI_PERSTART_SHIFT (0) /* Bits 0-13: Periodic start */ +#define OHCI_PERSTART_MASK (0x3fff << OHCI_PERSTART_SHIFT) + /* Bits 14-31: Reserved */ + +/* HcLSThreshold: Commit to transfer threshold (7.3.5) */ + +#define OHCI_LSTHRES_SHIFT (0) /* Bits 0-11: LS threshold */ +#define OHCI_LSTHRES_MASK (0x0fff << OHCI_PERSTART_SHIFT) + /* Bits 12-31: Reserved */ + +/* HcRhDescriptorN: Describes root hub (part A) (7.4.1) */ + +#define OHCI_RHDESCA_NDP_SHIFT (0) /* Bits 0-7: Number downstream ports */ +#define OHCI_RHDESCA_NDP_MASK (0xff << OHCI_RHDESCA_NDP_SHIFT) +#define OHCI_RHDESCA_PSM (1 << 8) /* Bit 8: Power switching mode */ +#define OHCI_RHDESCA_NPS (1 << 9) /* Bit 9: No power switching */ +#define OHCI_RHDESCA_DT (1 << 10) /* Bit 10: Device type */ +#define OHCI_RHDESCA_OCPM (1 << 11) /* Bit 11: Over current protection mode */ +#define OHCI_RHDESCA_NOCP (1 << 12) /* Bit 12: No over current protection */ + /* Bits 13-23: Reserved */ +#define OHCI_RHDESCA_POTPGT_SHIFT (24) /* Bits 24-31: Power on to power good time */ +#define OHCI_RHDESCA_POTPGT_MASK (0xff << OHCI_RHDESCA_POTPGT_SHIFT) + +/* HcRhDescriptorB: Describes root hub (part B) (7.4.2) */ + +#define OHCI_RHDESCB_DR_SHIFT (0) /* Bits 0-15: Device removable */ +#define OHCI_RHDESCB_DR_MASK (0xffff << OHCI_RHDESCB_DR_SHIFT) +# define OHCI_RHDESCB_ATTACHED(n) (1 << (OHCI_RHDESCB_DR_SHIFT+(n))) +#define OHCI_RHDESCB_PPCM_SHIFT (16) /* Bits 16-31: Port power control mask */ +#define OHCI_RHDESCB_PPCM_MASK (0xffff << OHCI_RHDESCB_PPCM_SHIFT) +# define OHCI_RHDESCB_POWERED(n) (1 << (OHCI_RHDESCB_DR_SHIFT+(n))) + +/* HcRhStatus: Root hub status (7.4.3) */ + +#define OHCI_RHSTATUS_LPS (1 << 0) /* Bit 0: Local power status (read)*/ +#define OHCI_RHSTATUS_CGP (1 << 0) /* Bit 0: Clear global power (write)*/ +#define OHCI_RHSTATUS_OCI (1 << 1) /* Bit 1: Over current indicator */ + /* Bits 2-14: Reserved */ +#define OHCI_RHSTATUS_DRWE (1 << 15) /* Bit 15: Device remote wakeup enable */ +#define OHCI_RHSTATUS_LPSC (1 << 16) /* Bit 16: Local power status change (read) */ +#define OHCI_RHSTATUS_SGP (1 << 16) /* Bit 16: Set global power (write) */ +#define OHCI_RHSTATUS_OCIC (1 << 17) /* Bit 17: Overcurrent indicator change */ + /* Bits 18-30: Reserved */ +#define OHCI_RHSTATUS_CRWE (1 << 31) /* Bit 31: Clear remote wakeup enable */ + +/* HcRhPortStatus: Root hub port status (7.4.4) */ + +#define OHCI_RHPORTST_CCS (1 << 0) /* Bit 0: Current connect status */ +#define OHCI_RHPORTST_PES (1 << 1) /* Bit 1: Port enable status */ +#define OHCI_RHPORTST_PSS (1 << 2) /* Bit 2: Port suspend status */ +#define OHCI_RHPORTST_POCI (1 << 3) /* Bit 3: Port over current indicator */ +#define OHCI_RHPORTST_PRS (1 << 4) /* Bit 4: Port reset status */ + /* Bits 5-7: Reserved */ +#define OHCI_RHPORTST_PPS (1 << 8) /* Bit 8: Port power status */ +#define OHCI_RHPORTST_LSDA (1 << 9) /* Bit 9: Low speed device attached */ + /* Bits 10-15: Reserved */ +#define OHCI_RHPORTST_CSC (1 << 16) /* Bit 16: Connect status change */ +#define OHCI_RHPORTST_PESC (1 << 17) /* Bit 17: Port enable status change */ +#define OHCI_RHPORTST_PSSC (1 << 18) /* Bit 18: Port suspend status change */ +#define OHCI_RHPORTST_OCIC (1 << 19) /* Bit 19: Port over current indicator change */ +#define OHCI_RHPORTST_PRSC (1 << 20) /* Bit 20: Port reset status change */ + /* Bits 21-31: Reserved */ + +/* Transfer Descriptors *****************************************************/ + +/* Endpoint Descriptor Offsets (4.2.1) */ + +#define ED_CONTROL_OFFSET (0x00) /* ED status/control bits */ +#define ED_TAILP_OFFSET (0x04) /* TD Queue Tail Pointer (TailP) */ +#define ED_HEADP_OFFSET (0x08) /* TD Queue Head Pointer (HeadP) */ +#define ED_NEXTED_OFFSET (0x0c) /* Next Endpoint Descriptor (NextED) */ + +/* Endpoint Descriptor Bit Definitions (4.2.2) */ + +#define ED_CONTROL_FA_SHIFT (0) /* Bits 0-6: Function Address */ +#define ED_CONTROL_FA_MASK (0x7f << ED_CONTROL_FA_SHIFT) +#define ED_CONTROL_EN_SHIFT (7) /* Bits 7-10: Endpoint number */ +#define ED_CONTROL_EN_MASK (15 << ED_CONTROL_EN_SHIFT) +#define ED_CONTROL_D_SHIFT (11) /* Bits 11-12: Direction */ +#define ED_CONTROL_D_MASK (3 << ED_CONTROL_D_SHIFT) +# define ED_CONTROL_D_TD1 (0 << ED_CONTROL_D_SHIFT) /* Get direction from TD */ +# define ED_CONTROL_D_OUT (1 << ED_CONTROL_D_SHIFT) /* OUT */ +# define ED_CONTROL_D_IN (2 << ED_CONTROL_D_SHIFT) /* IN */ +# define ED_CONTROL_D_TD2 (3 << ED_CONTROL_D_SHIFT) /* Get direction from TD */ + +#define ED_CONTROL_S (1 << 13) /* Bit 13: Speed (low) */ +#define ED_CONTROL_K (1 << 14) /* Bit 14: Skip */ +#define ED_CONTROL_F (1 << 15) /* Bit 15: Format (isochronous) */ +#define ED_CONTROL_MPS_SHIFT (16) /* Bits 16-26: Maximum packet size */ +#define ED_CONTROL_MPS_MASK (0x7ff << ED_CONTROL_MPS_SHIFT) + +#define ED_HEADP_ADDR_SHIFT (0) +#define ED_HEADP_ADDR_MASK 0xfffffff0 +#define ED_HEADP_H (1 << 0) /* Bit 0: Halted */ +#define ED_HEADP_C (1 << 1) /* Bit 1: Toggle carry */ + +/* General Transfer Descriptor Offsets (4.3.1) */ + +#define GTD_STATUS_OFFSET (0x00) /* TD status bits */ +#define GTD_CBP_OFFSET (0x04) /* Current Buffer Pointer (CBP) */ +#define GTD_NEXTTD_OFFSET (0x08) /* Next TD (NextTD) */ +#define GTD_BE_OFFSET (0x0c) /* Buffer End (BE) */ + +/* General Transfer Descriptor Bit Definitions */ + + /* Bits 0-17: Reserved */ + +#define GTD_STATUS_R (1 << 18) /* Bit 18: Buffer rounding */ +#define GTD_STATUS_DP_SHIFT (19) /* Bits 19-20: Direction/PID */ +#define GTD_STATUS_DP_MASK (3 << GTD_STATUS_DP_SHIFT) +# define GTD_STATUS_DP_SETUP (0 << GTD_STATUS_DP_SHIFT) /* To endpoint */ +# define GTD_STATUS_DP_OUT (1 << GTD_STATUS_DP_SHIFT) /* To endpoint */ +# define GTD_STATUS_DP_IN (2 << GTD_STATUS_DP_SHIFT) /* From endpoint */ + +#define GTD_STATUS_DI_SHIFT (21) /* Bits 21-23: Delay input */ +#define GTD_STATUS_DI_MASK (7 << GTD_STATUS_DI_SHIFT) +#define GTD_STATUS_T_SHIFT (24) /* Bits 24-25: Data Toggle */ +#define GTD_STATUS_T_MASK (3 << GTD_STATUS_T_SHIFT) +# define GTD_STATUS_T_TOGGLE (0 << GTD_STATUS_T_SHIFT) +# define GTD_STATUS_T_DATA0 (2 << GTD_STATUS_T_SHIFT) +# define GTD_STATUS_T_DATA1 (3 << GTD_STATUS_T_SHIFT) +#define GTD_STATUS_EC_SHIFT (26) /* Bits 26-27: Error count */ +#define GTD_STATUS_EC_MASK (3 << GTD_STATUS_EC_SHIFT) +#define GTD_STATUS_CC_SHIFT (28) /* Bits 28-31: Condition code */ +#define GTD_STATUS_CC_MASK (15 << GTD_STATUS_CC_SHIFT) + +/* Isochronous Transfer Descriptor Offsets (4.3.2) */ + +#define ITD_STATUS_OFFSET (0x00) /* TD status bits */ +#define ITD_BP0_OFFSET (0x04) /* Buffer page 0 (BP0) */ +#define ITD_NEXTTD_OFFSET (0x08) /* Next TD (NextTD) */ +#define ITD_BE_OFFSET (0x0c) /* Buffer End (BE) */ + +#define ITD_NPSW (8) +#define ITD_PSW0_OFFSET (0x10) /* Offset0/PSW0 */ +#define ITD_PSW1_OFFSET (0x12) /* Offset1/PSW1 */ +#define ITD_PSW2_OFFSET (0x14) /* Offset2/PSW2 */ +#define ITD_PSW3_OFFSET (0x16) /* Offset3/PSW3 */ +#define ITD_PSW4_OFFSET (0x18) /* Offset4/PSW4 */ +#define ITD_PSW5_OFFSET (0x1a) /* Offset5/PSW5 */ +#define ITD_PSW6_OFFSET (0x1c) /* Offset6/PSW6 */ +#define ITD_PSW7_OFFSET (0x1e) /* Offset7/PSW7 */ + +/* Condition codes (Table 4-7) */ + +#define TD_CC_NOERROR 0x00 +#define TD_CC_CRC 0x01 +#define TD_CC_BITSTUFFING 0x02 +#define TD_CC_DATATOGGLEMISMATCH 0x03 +#define TD_CC_STALL 0x04 +#define TD_CC_DEVNOTRESPONDING 0x05 +#define TD_CC_PIDCHECKFAILURE 0x06 +#define TD_CC_UNEXPECTEDPID 0x07 +#define TD_CC_DATAOVERRUN 0x08 +#define TD_CC_DATAUNDERRUN 0x09 +#define TD_CC_BUFFEROVERRUN 0x0c +#define TD_CC_BUFFERUNDERRUN 0x0d +#define TD_CC_NOTACCESSED 0x0f + +#define TD_CC_USER 0x10 /* For use by OHCI drivers */ + +/* Host Controller Communications Area Format (4.4.1) ***********************/ + +/* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */ + +#define HCCA_INTTBL_OFFSET (0x00) +#define HCCA_INTTBL_WSIZE (32) +#define HCCA_INTTBL_BSIZE (HCCA_INTTBL_WSIZE * 4) + +/* HccaFrameNumber: Current frame number */ + +#define HCCA_FMNO_OFFSET (0x80) +#define HCCA_FMNO_BSIZE (2) + +/* HccaPad1: Zero when frame no. updated */ + +#define HCCA_PAD1_OFFSET (0x82) +#define HCCA_PAD1_BSIZE (2) + +/* HccaDoneHead: When the HC reaches the end of a frame and its deferred + * interrupt register is 0, it writes the current value of its HcDoneHead to + * this location and generates an interrupt. + * + * The LSB of HCCADoneHead may be set to 1 to indicate that an unmasked + * HcInterruptStatus was set when HccaDoneHead was written. + */ + +#define HCCA_DONEHEAD_OFFSET (0x84) +#define HCCA_DONEHEAD_BSIZE (4) + +#define HCCA_DONEHEAD_MASK 0xfffffffe +#define HCCA_DONEHEAD_INTSTA (1 << 0) + +/* 0x88: 116 bytes reserved */ + +#define HCCA_RESERVED_OFFSET (0x88) +#define HCCA_RESERVED_BSIZE (116) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct ohci_hcor +{ + volatile uint32_t hcrevision; /* 0x00 */ + volatile uint32_t hccontrol; /* 0x04 */ + volatile uint32_t hccmdsts; /* 0x08 */ + volatile uint32_t hcintsts; /* 0x0c */ + volatile uint32_t hcinten; /* 0x10 */ + volatile uint32_t hcintdis; /* 0x14 */ + volatile uint32_t hchcca; /* 0x18 */ + volatile uint32_t hcperiodcurrented; /* 0x1c */ + volatile uint32_t hccontrolheaded; /* 0x20 */ + volatile uint32_t hccontrolcurrented; /* 0x24 */ + volatile uint32_t hcbulkheaded; /* 0x28 */ + volatile uint32_t hcbulkcurrented; /* 0x2c */ + volatile uint32_t hcdonehead; /* 0x30 */ + volatile uint32_t hcfminterval; /* 0x34 */ + volatile uint32_t hcfmremaining; /* 0x38 */ + volatile uint32_t hcfmnumber; /* 0x3c */ + volatile uint32_t hcperiodicstart; /* 0x40 */ + volatile uint32_t hclsthreshold; /* 0x44 */ + volatile uint32_t hcrhdescriptora; /* 0x48 */ + volatile uint32_t hcrhdescriptorb; /* 0x4c */ + volatile uint32_t hcrhsts; /* 0x50 */ + volatile uint32_t hcrhportsts[15]; /* 0x54 */ }; -int ohci_init(struct usbh_bus *bus); -int ohci_deinit(struct usbh_bus *bus); -uint16_t ohci_get_frame_number(struct usbh_bus *bus); -int ohci_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf); -int ohci_submit_urb(struct usbh_urb *urb); -int ohci_kill_urb(struct usbh_urb *urb); +/* Endpoint Descriptor Offsets (4.2.1) */ -void OHCI_IRQHandler(uint8_t busid); +struct ohci_ed_s +{ + volatile uint32_t ctrl; /* ED status/control bits */ + volatile uint32_t tailp; /* TD Queue Tail Pointer (TailP) */ + volatile uint32_t headp; /* TD Queue Head Pointer (HeadP) */ + volatile uint32_t nexted; /* Next Endpoint Descriptor (NextED) */ +}; -#endif \ No newline at end of file +/* General Transfer Descriptor (4.3.1) */ + +struct ohci_gtd_s +{ + volatile uint32_t ctrl; /* TD status/control bits */ + volatile uint32_t cbp; /* Current Buffer Pointer (CBP) */ + volatile uint32_t nexttd; /* Next TD (NextTD) */ + volatile uint32_t be; /* Buffer End (BE) */ +}; + +/* Isochronous Transfer Descriptor Offsets (4.3.2) */ + +struct ohci_itd_s +{ + volatile uint32_t ctrl; /* TD status/control bits */ + volatile uint32_t bp0; /* Buffer page 0 (BP0 */ + volatile uint32_t nexttd; /* Next TD (NextTD) */ + volatile uint32_t be; /* Buffer End (BE) */ + volatile uint16_t psw[ITD_NPSW]; /* Offset/PSW */ +}; + +/* Host Controller Communications Area Format (4.4.1) */ + +struct ohci_hcca_s +{ + /* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */ + + volatile uint32_t inttbl[HCCA_INTTBL_WSIZE]; + + /* HccaFrameNumber: Current frame number and + * HccaPad1: Zero when frame no. updated + */ + + volatile uint16_t fmno; + volatile uint16_t pad1; + + /* HccaDoneHead: When the HC reaches the end of a frame and its deferred + * interrupt register is 0, it writes the current value of its HcDoneHead + * to this location and generates an interrupt. + */ + + volatile uint32_t donehead; + volatile uint8_t reserved[HCCA_RESERVED_BSIZE]; + volatile uint32_t extra; +} __attribute__((aligned(256))); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_USB_OHCI_H */ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_ohci_reg.h b/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_ohci_reg.h deleted file mode 100644 index 61f7f4b..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/ohci/usb_ohci_reg.h +++ /dev/null @@ -1,484 +0,0 @@ -/**************************************************************************** - * include/nuttx/usb/ohci.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __INCLUDE_NUTTX_USB_OHCI_H -#define __INCLUDE_NUTTX_USB_OHCI_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Register offsets *********************************************************/ - -/* Control and status registers (section 7.1) */ - -#define OHCI_HCIREV_OFFSET 0x0000 /* HcRevision: Version of HCI specification */ -#define OHCI_CTRL_OFFSET 0x0004 /* HcControl: HC control */ -#define OHCI_CMDST_OFFSET 0x0008 /* HcCommandStatus: HC command status */ -#define OHCI_INTST_OFFSET 0x000c /* HcInterruptStatus: HC interrupt status */ -#define OHCI_INTEN_OFFSET 0x0010 /* HcInterruptEnable: HC interrupt enable */ -#define OHCI_INTDIS_OFFSET 0x0014 /* HcInterruptDisable: HC interrupt disable */ - -/* Memory pointer registers (section 7.2) */ - -#define OHCI_HCCA_OFFSET 0x0018 /* HcHCCA: HC communication area */ -#define OHCI_PERED_OFFSET 0x001c /* HcPeriodCurrentED: Current isoc or int endpoint desc */ -#define OHCI_CTRLHEADED_OFFSET 0x0020 /* HcControlHeadED: First EP desc in the control list */ -#define OHCI_CTRLED_OFFSET 0x0024 /* HcControlCurrentED: Current EP desc in the control list */ -#define OHCI_BULKHEADED_OFFSET 0x0028 /* HcBulkHeadED: First EP desc in the bulk list */ -#define OHCI_BULKED_OFFSET 0x002c /* HcBulkCurrentED: Current EP desc in the bulk list */ -#define OHCI_DONEHEAD_OFFSET 0x0030 /* HcDoneHead: Last transfer desc added to DONE queue */ - -/* Frame counter registers (section 7.3) */ - -#define OHCI_FMINT_OFFSET 0x0034 /* HcFmInterval: Bit time interval that would not cause overrun */ -#define OHCI_FMREM_OFFSET 0x0038 /* HcFmRemaining: Bit time remaining in current frame */ -#define OHCI_FMNO_OFFSET 0x003c /* HcFmNumber: Frame number counter */ -#define OHCI_PERSTART_OFFSET 0x0040 /* HcPeriodicStart: Time to start processing periodic list */ - -/* Root hub registers (section 7.4) */ - -#define OHCI_LSTHRES_OFFSET 0x0044 /* HcLSThreshold: Commit to transfer threshold */ -#define OHCI_RHDESCA_OFFSET 0x0048 /* HcRhDescriptorA: Describes root hub (part A) */ -#define OHCI_RHDESCB_OFFSET 0x004c /* HcRhDescriptorB: Describes root hub (part B) */ -#define OHCI_RHSTATUS_OFFSET 0x0050 /* HcRhStatus: Root hub status */ - -#define OHCI_MAX_RHPORT 15 /* Maximum number of OHCI root hub ports */ - -#define OHCI_RHPORTST_OFFSET(n) (0x0054 + (((n) - 1) << 2)) -#define OHCI_RHPORTST1_OFFSET 0x0054 /* HcRhPort1Status: Root hub port status 1 */ -#define OHCI_RHPORTST2_OFFSET 0x0058 /* HcRhPort2Status: Root hub port status 2 */ -#define OHCI_RHPORTST3_OFFSET 0x005c /* HcRhPort3Status: Root hub port status 3 */ -#define OHCI_RHPORTST4_OFFSET 0x0060 /* HcRhPort4Status: Root hub port status 4 */ -#define OHCI_RHPORTST5_OFFSET 0x0064 /* HcRhPort5Status: Root hub port status 5 */ -#define OHCI_RHPORTST6_OFFSET 0x0068 /* HcRhPort6Status: Root hub port status 6 */ -#define OHCI_RHPORTST7_OFFSET 0x006c /* HcRhPort7Status: Root hub port status 7 */ -#define OHCI_RHPORTST8_OFFSET 0x0070 /* HcRhPort8Status: Root hub port status 8 */ -#define OHCI_RHPORTST9_OFFSET 0x0074 /* HcRhPort9Status: Root hub port status 9 */ -#define OHCI_RHPORTST10_OFFSET 0x0078 /* HcRhPort10Status: Root hub port status 10 */ -#define OHCI_RHPORTST11_OFFSET 0x007c /* HcRhPort11Status: Root hub port status 11 */ -#define OHCI_RHPORTST12_OFFSET 0x0080 /* HcRhPort12Status: Root hub port status 12 */ -#define OHCI_RHPORTST13_OFFSET 0x0084 /* HcRhPort13Status: Root hub port status 13 */ -#define OHCI_RHPORTST14_OFFSET 0x0088 /* HcRhPort14Status: Root hub port status 14 */ -#define OHCI_RHPORTST15_OFFSET 0x008c /* HcRhPort15Status: Root hub port status 15 */ - -/* Register bit definitions *************************************************/ - -/* HcRevision: Version of HCI specification (7.1.1) */ - -#define OHCI_HCIREV_SHIFT (0) /* Bits 0-7: HCI spec version (BCD) */ -#define OHCI_HCIREV_MASK (0xff << OHCI_HCIREV_SHIFT) - -/* HcControl: HC control (7.1.2) */ - -#define OHCI_CTRL_CBSR (3 << 0) /* Bit 0: Control/bulk service ratio */ -#define OHCI_CTRL_PLE (1 << 2) /* Bit 2: Periodic list enable */ -#define OHCI_CTRL_IE (1 << 3) /* Bit 3: Isochronous enable */ -#define OHCI_CTRL_CLE (1 << 4) /* Bit 4: Control list enable */ -#define OHCI_CTRL_BLE (1 << 5) /* Bit 5: Bulk list enable */ -#define OHCI_CTRL_HCFS_SHIFT (6) /* Bits 6-7: Host controller functional state */ -#define OHCI_CTRL_HCFS_MASK (3 << OHCI_CTRL_HCFS_SHIFT) -# define OHCI_CTRL_HCFS_RESET (0 << OHCI_CTRL_HCFS_SHIFT) -# define OHCI_CTRL_HCFS_RESUME (1 << OHCI_CTRL_HCFS_SHIFT) -# define OHCI_CTRL_HCFS_OPER (2 << OHCI_CTRL_HCFS_SHIFT) -# define OHCI_CTRL_HCFS_SUSPEND (3 << OHCI_CTRL_HCFS_SHIFT) -#define OHCI_CTRL_IR (1 << 8) /* Bit 8: Interrupt routing */ -#define OHCI_CTRL_RWC (1 << 9) /* Bit 9: Remote wakeup connected */ -#define OHCI_CTRL_RWE (1 << 10) /* Bit 10: Remote wakeup enable */ - /* Bits 11-31: Reserved */ - -/* HcCommandStatus: HC command status (7.1.3) */ - -#define OHCI_CMDST_HCR (1 << 0) /* Bit 0: Host controller reset */ -#define OHCI_CMDST_CLF (1 << 1) /* Bit 1: Control list filled */ -#define OHCI_CMDST_BLF (1 << 2) /* Bit 2: Bulk list filled */ -#define OHCI_CMDST_OCR (1 << 3) /* Bit 3: Ownership change request */ - /* Bits 4-15: Reserved */ -#define OHCI_CMDST_SOC (3 << 16) /* Bit 16: Scheduling overrun count */ - /* Bits 17-31: Reserved */ - -/* HcInterruptStatus: HC interrupt status (7.1.4), - * HcInterruptEnable: HC interrupt enable (7.1.5), and - * HcInterruptDisable: HC interrupt disable (7.1.6) - */ - -#define OHCI_INT_SO (1 << 0) /* Bit 0: Scheduling overrun */ -#define OHCI_INT_WDH (1 << 1) /* Bit 1: Writeback done head */ -#define OHCI_INT_SF (1 << 2) /* Bit 2: Start of frame */ -#define OHCI_INT_RD (1 << 3) /* Bit 3: Resume detected */ -#define OHCI_INT_UE (1 << 4) /* Bit 4: Unrecoverable error */ -#define OHCI_INT_FNO (1 << 5) /* Bit 5: Frame number overflow */ -#define OHCI_INT_RHSC (1 << 6) /* Bit 6: Root hub status change */ - /* Bits 7-29: Reserved */ -#define OHCI_INT_OC (1 << 30) /* Bit 30: Ownership change */ -#define OHCI_INT_MIE (1 << 31) /* Bit 31: Master interrupt enable - * (Enable/disable only) */ - -/* HcHCCA: HC communication area (7.2.1): - * - * 32-bits aligned to 256 byte boundary. - */ - -/* HcPeriodCurrentED: Current isoc or int endpoint desc (7.2.2), - * HcControlHeadED: First EP desc in the control list (7.2.3), - * HcControlCurrentED: Current EP desc in the control list (7.2.4), - * HcBulkHeadED: First EP desc in the bulk list (7.2.5), - * HcBulkCurrentED: Current EP desc in the bulk list (7.2.6), and - * HcDoneHead: Last transfer desc added to DONE queue (7.2.7): - * - * All 32-bits aligned to an 8-byte boundary - */ - -/* HcFmInterval: Bit time interval that would not cause overrun (7.3.1) */ - -#define OHCI_FMINT_FI_SHIFT (0) /* Bits 0-13: Frame interval */ -#define OHCI_FMINT_FI_MASK (0x3fff << OHCI_FMINT_FI_SHIFT) - /* Bits 14-15: Reserved */ -#define OHCI_FMINT_FSMPS_SHIFT (16) /* Bits 16-30: FS largest packet data */ -#define OHCI_FMINT_FSMPS_MASK (0x7fff << OHCI_FMINT_FSMPS_SHIFT) -#define OHCI_FMINT_FIT (1 << 31) /* Bit 31: Frame interval toggle */ - -/* HcFmRemaining: Bit time remaining in current frame (7.3.2) */ - -#define OHCI_FMREM_FR_SHIFT (0) /* Bits 0-13: Frame remaining */ -#define OHCI_FMREM_FR_MASK (0x3fff << OHCI_FMREM_FR_SHIFT) - /* Bits 16-30: Reserved */ -#define OHCI_FMINT_FRT (1 << 31) /* Bit 31: Frame remaining toggle */ - -/* HcFmNumber: Frame number counter (7.3.3) */ - -#define OHCI_FMNO_FI_SHIFT (0) /* Bits 0-15: Frame number */ -#define OHCI_FMNO_FI_MASK (0xffff << OHCI_FMINT_FI_SHIFT) - /* Bits 16-31: Reserved */ - -/* HcPeriodicStart: Time to start processing periodic list (7.3.4) */ - -#define OHCI_PERSTART_SHIFT (0) /* Bits 0-13: Periodic start */ -#define OHCI_PERSTART_MASK (0x3fff << OHCI_PERSTART_SHIFT) - /* Bits 14-31: Reserved */ - -/* HcLSThreshold: Commit to transfer threshold (7.3.5) */ - -#define OHCI_LSTHRES_SHIFT (0) /* Bits 0-11: LS threshold */ -#define OHCI_LSTHRES_MASK (0x0fff << OHCI_PERSTART_SHIFT) - /* Bits 12-31: Reserved */ - -/* HcRhDescriptorN: Describes root hub (part A) (7.4.1) */ - -#define OHCI_RHDESCA_NDP_SHIFT (0) /* Bits 0-7: Number downstream ports */ -#define OHCI_RHDESCA_NDP_MASK (0xff << OHCI_RHDESCA_NDP_SHIFT) -#define OHCI_RHDESCA_PSM (1 << 8) /* Bit 8: Power switching mode */ -#define OHCI_RHDESCA_NPS (1 << 9) /* Bit 9: No power switching */ -#define OHCI_RHDESCA_DT (1 << 10) /* Bit 10: Device type */ -#define OHCI_RHDESCA_OCPM (1 << 11) /* Bit 11: Over current protection mode */ -#define OHCI_RHDESCA_NOCP (1 << 12) /* Bit 12: No over current protection */ - /* Bits 13-23: Reserved */ -#define OHCI_RHDESCA_POTPGT_SHIFT (24) /* Bits 24-31: Power on to power good time */ -#define OHCI_RHDESCA_POTPGT_MASK (0xff << OHCI_RHDESCA_POTPGT_SHIFT) - -/* HcRhDescriptorB: Describes root hub (part B) (7.4.2) */ - -#define OHCI_RHDESCB_DR_SHIFT (0) /* Bits 0-15: Device removable */ -#define OHCI_RHDESCB_DR_MASK (0xffff << OHCI_RHDESCB_DR_SHIFT) -# define OHCI_RHDESCB_ATTACHED(n) (1 << (OHCI_RHDESCB_DR_SHIFT+(n))) -#define OHCI_RHDESCB_PPCM_SHIFT (16) /* Bits 16-31: Port power control mask */ -#define OHCI_RHDESCB_PPCM_MASK (0xffff << OHCI_RHDESCB_PPCM_SHIFT) -# define OHCI_RHDESCB_POWERED(n) (1 << (OHCI_RHDESCB_DR_SHIFT+(n))) - -/* HcRhStatus: Root hub status (7.4.3) */ - -#define OHCI_RHSTATUS_LPS (1 << 0) /* Bit 0: Local power status (read)*/ -#define OHCI_RHSTATUS_CGP (1 << 0) /* Bit 0: Clear global power (write)*/ -#define OHCI_RHSTATUS_OCI (1 << 1) /* Bit 1: Over current indicator */ - /* Bits 2-14: Reserved */ -#define OHCI_RHSTATUS_DRWE (1 << 15) /* Bit 15: Device remote wakeup enable */ -#define OHCI_RHSTATUS_LPSC (1 << 16) /* Bit 16: Local power status change (read) */ -#define OHCI_RHSTATUS_SGP (1 << 16) /* Bit 16: Set global power (write) */ -#define OHCI_RHSTATUS_OCIC (1 << 17) /* Bit 17: Overcurrent indicator change */ - /* Bits 18-30: Reserved */ -#define OHCI_RHSTATUS_CRWE (1 << 31) /* Bit 31: Clear remote wakeup enable */ - -/* HcRhPortStatus: Root hub port status (7.4.4) */ - -#define OHCI_RHPORTST_CCS (1 << 0) /* Bit 0: Current connect status */ -#define OHCI_RHPORTST_PES (1 << 1) /* Bit 1: Port enable status */ -#define OHCI_RHPORTST_PSS (1 << 2) /* Bit 2: Port suspend status */ -#define OHCI_RHPORTST_POCI (1 << 3) /* Bit 3: Port over current indicator */ -#define OHCI_RHPORTST_PRS (1 << 4) /* Bit 4: Port reset status */ - /* Bits 5-7: Reserved */ -#define OHCI_RHPORTST_PPS (1 << 8) /* Bit 8: Port power status */ -#define OHCI_RHPORTST_LSDA (1 << 9) /* Bit 9: Low speed device attached */ - /* Bits 10-15: Reserved */ -#define OHCI_RHPORTST_CSC (1 << 16) /* Bit 16: Connect status change */ -#define OHCI_RHPORTST_PESC (1 << 17) /* Bit 17: Port enable status change */ -#define OHCI_RHPORTST_PSSC (1 << 18) /* Bit 18: Port suspend status change */ -#define OHCI_RHPORTST_OCIC (1 << 19) /* Bit 19: Port over current indicator change */ -#define OHCI_RHPORTST_PRSC (1 << 20) /* Bit 20: Port reset status change */ - /* Bits 21-31: Reserved */ - -/* Transfer Descriptors *****************************************************/ - -/* Endpoint Descriptor Offsets (4.2.1) */ - -#define ED_CONTROL_OFFSET (0x00) /* ED status/control bits */ -#define ED_TAILP_OFFSET (0x04) /* TD Queue Tail Pointer (TailP) */ -#define ED_HEADP_OFFSET (0x08) /* TD Queue Head Pointer (HeadP) */ -#define ED_NEXTED_OFFSET (0x0c) /* Next Endpoint Descriptor (NextED) */ - -/* Endpoint Descriptor Bit Definitions (4.2.2) */ - -#define ED_CONTROL_FA_SHIFT (0) /* Bits 0-6: Function Address */ -#define ED_CONTROL_FA_MASK (0x7f << ED_CONTROL_FA_SHIFT) -#define ED_CONTROL_EN_SHIFT (7) /* Bits 7-10: Endpoint number */ -#define ED_CONTROL_EN_MASK (15 << ED_CONTROL_EN_SHIFT) -#define ED_CONTROL_D_SHIFT (11) /* Bits 11-12: Direction */ -#define ED_CONTROL_D_MASK (3 << ED_CONTROL_D_SHIFT) -# define ED_CONTROL_D_TD1 (0 << ED_CONTROL_D_SHIFT) /* Get direction from TD */ -# define ED_CONTROL_D_OUT (1 << ED_CONTROL_D_SHIFT) /* OUT */ -# define ED_CONTROL_D_IN (2 << ED_CONTROL_D_SHIFT) /* IN */ -# define ED_CONTROL_D_TD2 (3 << ED_CONTROL_D_SHIFT) /* Get direction from TD */ - -#define ED_CONTROL_SPPED_LOW (1 << 13) /* Bit 13: Speed (low) */ -#define ED_CONTROL_SKIP (1 << 14) /* Bit 14: Skip */ -#define ED_CONTROL_FORMAT_ISO (1 << 15) /* Bit 15: Format (isochronous) */ -#define ED_CONTROL_MPS_SHIFT (16) /* Bits 16-26: Maximum packet size */ -#define ED_CONTROL_MPS_MASK (0x7ff << ED_CONTROL_MPS_SHIFT) - -#define ED_HEADP_ADDR_SHIFT (0) -#define ED_HEADP_ADDR_MASK 0xfffffff0 -#define ED_HEADP_H (1 << 0) /* Bit 0: Halted */ -#define ED_HEADP_C (1 << 1) /* Bit 1: Toggle carry */ - -/* General Transfer Descriptor Offsets (4.3.1) */ - -#define GTD_STATUS_OFFSET (0x00) /* TD status bits */ -#define GTD_CBP_OFFSET (0x04) /* Current Buffer Pointer (CBP) */ -#define GTD_NEXTTD_OFFSET (0x08) /* Next TD (NextTD) */ -#define GTD_BE_OFFSET (0x0c) /* Buffer End (BE) */ - -/* General Transfer Descriptor Bit Definitions */ - - /* Bits 0-17: Reserved */ - -#define GTD_STATUS_R (1 << 18) /* Bit 18: Buffer rounding */ -#define GTD_STATUS_DP_SHIFT (19) /* Bits 19-20: Direction/PID */ -#define GTD_STATUS_DP_MASK (3 << GTD_STATUS_DP_SHIFT) -# define GTD_STATUS_DP_SETUP (0 << GTD_STATUS_DP_SHIFT) /* To endpoint */ -# define GTD_STATUS_DP_OUT (1 << GTD_STATUS_DP_SHIFT) /* To endpoint */ -# define GTD_STATUS_DP_IN (2 << GTD_STATUS_DP_SHIFT) /* From endpoint */ - -#define GTD_STATUS_DI_SHIFT (21) /* Bits 21-23: Delay input */ -#define GTD_STATUS_DI_MASK (7 << GTD_STATUS_DI_SHIFT) -#define GTD_STATUS_T_SHIFT (24) /* Bits 24-25: Data Toggle */ -#define GTD_STATUS_T_MASK (3 << GTD_STATUS_T_SHIFT) -# define GTD_STATUS_T_TOGGLE (0 << GTD_STATUS_T_SHIFT) -# define GTD_STATUS_T_DATA0 (2 << GTD_STATUS_T_SHIFT) -# define GTD_STATUS_T_DATA1 (3 << GTD_STATUS_T_SHIFT) -#define GTD_STATUS_EC_SHIFT (26) /* Bits 26-27: Error count */ -#define GTD_STATUS_EC_MASK (3 << GTD_STATUS_EC_SHIFT) -#define GTD_STATUS_CC_SHIFT (28) /* Bits 28-31: Condition code */ -#define GTD_STATUS_CC_MASK (15 << GTD_STATUS_CC_SHIFT) - -/* Isochronous Transfer Descriptor Offsets (4.3.2) */ - -#define ITD_STATUS_OFFSET (0x00) /* TD status bits */ -#define ITD_BP0_OFFSET (0x04) /* Buffer page 0 (BP0) */ -#define ITD_NEXTTD_OFFSET (0x08) /* Next TD (NextTD) */ -#define ITD_BE_OFFSET (0x0c) /* Buffer End (BE) */ - -#define ITD_NPSW (8) -#define ITD_PSW0_OFFSET (0x10) /* Offset0/PSW0 */ -#define ITD_PSW1_OFFSET (0x12) /* Offset1/PSW1 */ -#define ITD_PSW2_OFFSET (0x14) /* Offset2/PSW2 */ -#define ITD_PSW3_OFFSET (0x16) /* Offset3/PSW3 */ -#define ITD_PSW4_OFFSET (0x18) /* Offset4/PSW4 */ -#define ITD_PSW5_OFFSET (0x1a) /* Offset5/PSW5 */ -#define ITD_PSW6_OFFSET (0x1c) /* Offset6/PSW6 */ -#define ITD_PSW7_OFFSET (0x1e) /* Offset7/PSW7 */ - -/* Condition codes (Table 4-7) */ - -#define TD_CC_NOERROR 0x00 -#define TD_CC_CRC 0x01 -#define TD_CC_BITSTUFFING 0x02 -#define TD_CC_DATATOGGLEMISMATCH 0x03 -#define TD_CC_STALL 0x04 -#define TD_CC_DEVNOTRESPONDING 0x05 -#define TD_CC_PIDCHECKFAILURE 0x06 -#define TD_CC_UNEXPECTEDPID 0x07 -#define TD_CC_DATAOVERRUN 0x08 -#define TD_CC_DATAUNDERRUN 0x09 -#define TD_CC_BUFFEROVERRUN 0x0c -#define TD_CC_BUFFERUNDERRUN 0x0d -#define TD_CC_NOTACCESSED 0x0f - -#define TD_CC_USER 0x10 /* For use by OHCI drivers */ - -/* Host Controller Communications Area Format (4.4.1) ***********************/ - -/* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */ - -#define HCCA_INTTBL_OFFSET (0x00) -#define HCCA_INTTBL_WSIZE (32) -#define HCCA_INTTBL_BSIZE (HCCA_INTTBL_WSIZE * 4) - -/* HccaFrameNumber: Current frame number */ - -#define HCCA_FMNO_OFFSET (0x80) -#define HCCA_FMNO_BSIZE (2) - -/* HccaPad1: Zero when frame no. updated */ - -#define HCCA_PAD1_OFFSET (0x82) -#define HCCA_PAD1_BSIZE (2) - -/* HccaDoneHead: When the HC reaches the end of a frame and its deferred - * interrupt register is 0, it writes the current value of its HcDoneHead to - * this location and generates an interrupt. - * - * The LSB of HCCADoneHead may be set to 1 to indicate that an unmasked - * HcInterruptStatus was set when HccaDoneHead was written. - */ - -#define HCCA_DONEHEAD_OFFSET (0x84) -#define HCCA_DONEHEAD_BSIZE (4) - -#define HCCA_DONEHEAD_MASK 0xfffffffe -#define HCCA_DONEHEAD_INTSTA (1 << 0) - -/* 0x88: 116 bytes reserved */ - -#define HCCA_RESERVED_OFFSET (0x88) -#define HCCA_RESERVED_BSIZE (116) - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -struct ohci_hcor -{ - volatile uint32_t hcrevision; /* 0x00 */ - volatile uint32_t hccontrol; /* 0x04 */ - volatile uint32_t hccmdsts; /* 0x08 */ - volatile uint32_t hcintsts; /* 0x0c */ - volatile uint32_t hcinten; /* 0x10 */ - volatile uint32_t hcintdis; /* 0x14 */ - volatile uint32_t hchcca; /* 0x18 */ - volatile uint32_t hcperiodcurrented; /* 0x1c */ - volatile uint32_t hccontrolheaded; /* 0x20 */ - volatile uint32_t hccontrolcurrented; /* 0x24 */ - volatile uint32_t hcbulkheaded; /* 0x28 */ - volatile uint32_t hcbulkcurrented; /* 0x2c */ - volatile uint32_t hcdonehead; /* 0x30 */ - volatile uint32_t hcfminterval; /* 0x34 */ - volatile uint32_t hcfmremaining; /* 0x38 */ - volatile uint32_t hcfmnumber; /* 0x3c */ - volatile uint32_t hcperiodicstart; /* 0x40 */ - volatile uint32_t hclsthreshold; /* 0x44 */ - volatile uint32_t hcrhdescriptora; /* 0x48 */ - volatile uint32_t hcrhdescriptorb; /* 0x4c */ - volatile uint32_t hcrhsts; /* 0x50 */ - volatile uint32_t hcrhportsts[15]; /* 0x54 */ -}; - -/* Endpoint Descriptor Offsets (4.2.1) */ - -struct ohci_ed -{ - volatile uint32_t ctrl; /* ED status/control bits */ - volatile uint32_t tailp; /* TD Queue Tail Pointer (TailP) */ - volatile uint32_t headp; /* TD Queue Head Pointer (HeadP) */ - volatile uint32_t nexted; /* Next Endpoint Descriptor (NextED) */ -}; - -/* General Transfer Descriptor (4.3.1) */ - -struct ohci_gtd -{ - volatile uint32_t ctrl; /* TD status/control bits */ - volatile uint32_t cbp; /* Current Buffer Pointer (CBP) */ - volatile uint32_t nexttd; /* Next TD (NextTD) */ - volatile uint32_t be; /* Buffer End (BE) */ -}; - -/* Isochronous Transfer Descriptor Offsets (4.3.2) */ - -struct ohci_itd -{ - volatile uint32_t ctrl; /* TD status/control bits */ - volatile uint32_t bp0; /* Buffer page 0 (BP0 */ - volatile uint32_t nexttd; /* Next TD (NextTD) */ - volatile uint32_t be; /* Buffer End (BE) */ - volatile uint16_t psw[ITD_NPSW]; /* Offset/PSW */ -}; - -/* Host Controller Communications Area Format (4.4.1) */ - -struct ohci_hcca -{ - /* HccaInterruptTable: 32x32-bit pointers to interrupt EDs */ - - volatile uint32_t inttbl[HCCA_INTTBL_WSIZE]; - - /* HccaFrameNumber: Current frame number and - * HccaPad1: Zero when frame no. updated - */ - - volatile uint16_t fmno; - volatile uint16_t pad1; - - /* HccaDoneHead: When the HC reaches the end of a frame and its deferred - * interrupt register is 0, it writes the current value of its HcDoneHead - * to this location and generates an interrupt. - */ - - volatile uint32_t donehead; - volatile uint8_t reserved[HCCA_RESERVED_BSIZE]; - volatile uint32_t extra; -} __attribute__((aligned(256))); - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#ifdef __cplusplus -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#undef EXTERN -#ifdef __cplusplus -} -#endif - -#endif /* __INCLUDE_NUTTX_USB_OHCI_H */ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/README.md b/rt-thread/components/drivers/usb/cherryusb/port/pusb2/README.md deleted file mode 100644 index f8137af..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# USB 2.0 OTG 控制器 (PUSB2) - -- Phytium PI 和 Phyium E2000 系列开发板提供了兼容 USB2.0 的 OTG 接口 -- 相关的使用例程可以在 Phytium PI(飞腾派)和 E2000 D/Q Demo 板上运行,例程包括 - ---------------------------------------------- - -- Host 模式 - -- - 1. [FreeRTOS 上作为主机使用键盘/鼠标/U盘](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/pusb2_host/README.md) -- - 5. [RT-Thread 上作为主机识别键盘/鼠标/U盘](https://github.com/RT-Thread/rt-thread/blob/master/bsp/phytium/doc/use_cherryusb.md) - ---------------------------------------------- - -- Device 模式 - -- - 1. [裸机上模拟为一个 U 盘](https://gitee.com/phytium_embedded/phytium-standalone-sdk/tree/master/example/peripherals/usb/pusb2_device/README.md) -- - 2. [裸机上模拟为一个虚拟串口](https://gitee.com/phytium_embedded/phytium-standalone-sdk/tree/master/example/peripherals/usb/pusb2_device/README.md) -- - 3. [FreeRTOS 上模拟为一个 U 盘](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/pusb2_device/README.md) -- - 4. [FreeRTOS 上模拟为虚拟串口](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/pusb2_device/README.md) -- - 5. [RT-Thread 上模拟为一个 U 盘](https://github.com/RT-Thread/rt-thread/blob/master/bsp/phytium/doc/use_cherryusb.md) - ---------------------------------------------- - -- PUSB2 的驱动功能以静态库的方式提供, -- - libpusb2_hc_a64.a : AARCH64 主机模式驱动库 -- - libpusb2_dc_a64.a : AARCH64 从机模式驱动库 -- - libpusb2_hc_a32_hardfp.a :AARCH32 主机模式驱动库,使用硬浮点 -- - libpusb2_hc_a32_softfp.a :AARCH32 主机模式驱动库,使用软浮点 -- - libpusb2_dc_a32_hardfp.a :AARCH32 从机模式驱动库,使用硬浮点 -- - libpusb2_dc_a32_softfp.a :AARCH32 从机模式驱动库,使用软浮点 - -需要获取源代码请联系 `opensource_embedded@phytium.com.cn` 获取 - -# USB 2.0 OTG Controller (PUSB2) - -- Phytium PI and the Phytium E2000 series development boards offer OTG interfaces compatible with USB 2.0. -- Relevant usage examples can be run on the Phytium PI and E2000 D/Q Demo boards, including: - ---------------------------------------------- - -- Host Mode - - - 1. [Using a keyboard/mouse/USB flash drive as a host on FreeRTOS](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/pusb2_host/README.md) - - 5. [Recognizing a keyboard/mouse/USB flash drive as a host on RT-Thread](https://github.com/RT-Thread/rt-thread/blob/master/bsp/phytium/doc/use_cherryusb.md) - ---------------------------------------------- - -- Device Mode - - 1. [Simulating as a USB flash drive on a standalone system](https://gitee.com/phytium_embedded/phytium-standalone-sdk/tree/master/example/peripherals/usb/pusb2_device/README.md) - - 2. [Simulating as a virtual serial port on a standalone system](https://gitee.com/phytium_embedded/phytium-standalone-sdk/tree/master/example/peripherals/usb/pusb2_device/README.md) - - 3. [Simulating as a USB flash drive on FreeRTOS](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/pusb2_device/README.md) - - 4. [Simulating as a virtual serial port on FreeRTOS](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/pusb2_device/README.md) - - 5. [Simulating as a USB flash drive on RT-Thread](https://github.com/RT-Thread/rt-thread/blob/master/bsp/phytium/doc/use_cherryusb.md) - ---------------------------------------------- - -- The driver functionality of PUSB2 is provided as static libraries: - - - `libpusb2_hc_a64.a` : Host mode driver library for AARCH64 - - - `libpusb2_dc_a64.a` : Device mode driver library for AARCH64 - - - `libpusb2_hc_a32_hardfp.a` : Host mode driver library for AARCH32, using hard floating point - - - `libpusb2_hc_a32_softfp.a` : Host mode driver library for AARCH32, using soft floating point - - - `libpusb2_dc_a32_hardfp.a` : Device mode driver library for AARCH32, using hard floating point - - - `libpusb2_dc_a32_softfp.a` : Device mode driver library for AARCH32, using soft floating point - -- To obtain the source code, please contact `opensource_embedded@phytium.com.cn`. \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_dc_a32_hardfp.a b/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_dc_a32_hardfp.a deleted file mode 100644 index 685de41..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_dc_a32_hardfp.a and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_dc_a32_softfp_crypto_neon.a b/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_dc_a32_softfp_crypto_neon.a deleted file mode 100644 index f0e1ceb..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_dc_a32_softfp_crypto_neon.a and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_dc_a32_softfp_neon.a b/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_dc_a32_softfp_neon.a deleted file mode 100644 index f4d1580..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_dc_a32_softfp_neon.a and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_dc_a64.a b/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_dc_a64.a deleted file mode 100644 index 3e4ea12..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_dc_a64.a and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_hc_a32_hardfp.a b/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_hc_a32_hardfp.a deleted file mode 100644 index 7e029a6..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_hc_a32_hardfp.a and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_hc_a32_softfp_crypto_neon.a b/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_hc_a32_softfp_crypto_neon.a deleted file mode 100644 index dea366e..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_hc_a32_softfp_crypto_neon.a and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_hc_a32_softfp_neon.a b/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_hc_a32_softfp_neon.a deleted file mode 100644 index 172f969..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_hc_a32_softfp_neon.a and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_hc_a64.a b/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_hc_a64.a deleted file mode 100644 index 575d1dc..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/libpusb2_hc_a64.a and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/rt-thread/usb_config.h b/rt-thread/components/drivers/usb/cherryusb/port/pusb2/rt-thread/usb_config.h deleted file mode 100644 index 2a42c47..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/rt-thread/usb_config.h +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright : (C) 2024 Phytium Information Technology, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2024/6/26 first commit - */ -#ifndef CHERRYUSB_CONFIG_H -#define CHERRYUSB_CONFIG_H - -#include "rtconfig.h" - -/* ================ USB common Configuration ================ */ - -#define CONFIG_USB_PRINTF(...) rt_kprintf(__VA_ARGS__) - -void *usb_sys_mem_malloc(size_t size); -void usb_sys_mem_free(void *ptr); -void *usb_sys_malloc_align(size_t align, size_t size); - -#define usb_malloc(size) usb_sys_mem_malloc(size) -#define usb_free(ptr) usb_sys_mem_free(ptr) -#define usb_align(align, size) usb_sys_malloc_align(align, size) - -unsigned long usb_hc_get_register_base(uint32_t id); -unsigned long usb_dc_get_register_base(uint32_t id); - -#define CONFIG_USB_DBG_LEVEL USB_DBG_ERROR - -/* Enable print with color */ -#define CONFIG_USB_PRINTF_COLOR_ENABLE - -/* data align size when use dma */ -#ifndef CONFIG_USB_ALIGN_SIZE -#define CONFIG_USB_ALIGN_SIZE 4 -#endif - -/* attribute data into no cache ram */ -#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable"))) - -/* ================= USB Device Stack Configuration ================ */ - -/* Ep0 in and out transfer buffer */ -#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN -#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 512 -#endif - -/* Setup packet log for debug */ -// #define CONFIG_USBDEV_SETUP_LOG_PRINT - -/* Send ep0 in data from user buffer instead of copying into ep0 reqdata - * Please note that user buffer must be aligned with CONFIG_USB_ALIGN_SIZE -*/ -// #define CONFIG_USBDEV_EP0_INDATA_NO_COPY - -/* Check if the input descriptor is correct */ -// #define CONFIG_USBDEV_DESC_CHECK - -/* Enable test mode */ -// #define CONFIG_USBDEV_TEST_MODE - -#ifndef CONFIG_USBDEV_MSC_MAX_LUN -#define CONFIG_USBDEV_MSC_MAX_LUN 1 -#endif - -#ifndef CONFIG_USBDEV_MSC_MAX_BUFSIZE -#define CONFIG_USBDEV_MSC_MAX_BUFSIZE 4096 -#endif - -#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING -#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING "" -#endif - -#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING -#define CONFIG_USBDEV_MSC_PRODUCT_STRING "" -#endif - -#ifndef CONFIG_USBDEV_MSC_VERSION_STRING -#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01" -#endif - -// #define CONFIG_USBDEV_MSC_THREAD - -#ifndef CONFIG_USBDEV_MSC_PRIO -#define CONFIG_USBDEV_MSC_PRIO 4 -#endif - -#ifndef CONFIG_USBDEV_MSC_STACKSIZE -#define CONFIG_USBDEV_MSC_STACKSIZE 8192 -#endif - -#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE -#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156 -#endif - -/* rndis transfer buffer size, must be a multiple of (1536 + 44)*/ -#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE -#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1580 -#endif - -#ifndef CONFIG_USBDEV_RNDIS_VENDOR_ID -#define CONFIG_USBDEV_RNDIS_VENDOR_ID 0x0000ffff -#endif - -#ifndef CONFIG_USBDEV_RNDIS_VENDOR_DESC -#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "CherryUSB" -#endif - -#define CONFIG_USBDEV_RNDIS_USING_LWIP - -/* ================ USB HOST Stack Configuration ================== */ - -#define CONFIG_USBHOST_MAX_RHPORTS 1 -#define CONFIG_USBHOST_MAX_EXTHUBS 0 -#define CONFIG_USBHOST_MAX_EHPORTS 8 -#define CONFIG_USBHOST_MAX_INTERFACES 8 -#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8 -#define CONFIG_USBHOST_MAX_ENDPOINTS 8 - -#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4 -#define CONFIG_USBHOST_MAX_HID_CLASS 4 -#define CONFIG_USBHOST_MAX_MSC_CLASS 2 -#define CONFIG_USBHOST_MAX_AUDIO_CLASS 1 -#define CONFIG_USBHOST_MAX_VIDEO_CLASS 1 - -#define CONFIG_USBHOST_DEV_NAMELEN 16 - -#ifndef CONFIG_USBHOST_PSC_PRIO -#define CONFIG_USBHOST_PSC_PRIO 0 -#endif -#ifndef CONFIG_USBHOST_PSC_STACKSIZE -#define CONFIG_USBHOST_PSC_STACKSIZE 8192 -#endif - -//#define CONFIG_USBHOST_GET_STRING_DESC - -// #define CONFIG_USBHOST_MSOS_ENABLE -#ifndef CONFIG_USBHOST_MSOS_VENDOR_CODE -#define CONFIG_USBHOST_MSOS_VENDOR_CODE 0x00 -#endif - -/* Ep0 max transfer buffer */ -#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN -#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512 -#endif - -#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT -#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500 -#endif - -#ifndef CONFIG_USBHOST_MSC_TIMEOUT -#define CONFIG_USBHOST_MSC_TIMEOUT 5000 -#endif - -/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, - * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. - */ -#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE -#define CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE (2048) -#endif - -/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ -#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE -#define CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE (2048) -#endif - -/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, - * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. - */ -#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE -#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE (2048) -#endif -/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ -#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE -#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE (2048) -#endif - -/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, - * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. - */ -#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE -#define CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE (2048) -#endif -/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ -#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE -#define CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE (2048) -#endif - -/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, - * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. - */ -#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE -#define CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE (2048) -#endif -/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ -#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE -#define CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE (2048) -#endif - -#define CONFIG_USBHOST_BLUETOOTH_HCI_H4 -// #define CONFIG_USBHOST_BLUETOOTH_HCI_LOG - -#ifndef CONFIG_USBHOST_BLUETOOTH_TX_SIZE -#define CONFIG_USBHOST_BLUETOOTH_TX_SIZE 2048 -#endif -#ifndef CONFIG_USBHOST_BLUETOOTH_RX_SIZE -#define CONFIG_USBHOST_BLUETOOTH_RX_SIZE 2048 -#endif - -/* ================ USB Device Port Configuration ================*/ - -#ifndef CONFIG_USBDEV_MAX_BUS -#define CONFIG_USBDEV_MAX_BUS 1 // for now, bus num must be 1 except hpm ip -#endif - -#ifndef CONFIG_USBDEV_EP_NUM -#define CONFIG_USBDEV_EP_NUM 8 -#endif - -/* ---------------- FSDEV Configuration ---------------- */ -//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference - -/* ---------------- DWC2 Configuration ---------------- */ -/* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for - * status information) + (2 * number of OUT endpoints) + 1 for Global NAK - */ -// #define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4) -/* IN Endpoints Max packet Size / 4 */ -// #define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4) -// #define CONFIG_USB_DWC2_TX1_FIFO_SIZE (512 / 4) -// #define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4) -// #define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4) -// #define CONFIG_USB_DWC2_TX4_FIFO_SIZE (0 / 4) -// #define CONFIG_USB_DWC2_TX5_FIFO_SIZE (0 / 4) -// #define CONFIG_USB_DWC2_TX6_FIFO_SIZE (0 / 4) -// #define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4) -// #define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4) - -/* ---------------- MUSB Configuration ---------------- */ -// #define CONFIG_USB_MUSB_SUNXI - -/* ================ USB Host Port Configuration ==================*/ -#ifndef CONFIG_INPUT_MOUSE_WHEEL -#define CONFIG_INPUT_MOUSE_WHEEL -#endif - -#ifndef CONFIG_USBHOST_MAX_BUS -#define CONFIG_USBHOST_MAX_BUS 3 -#endif - -#ifndef CONFIG_USBHOST_PIPE_NUM -#define CONFIG_USBHOST_PIPE_NUM 10 -#endif - -/* ---------------- XHCI Configuration ---------------- */ -#define CONFIG_USB_XHCI_HCCR_OFFSET (0x0) - -/* ---------------- PUSB2 Configuration ---------------- */ -#define CONFIG_USB_PUSB2_BUS_NUM 3U -#define CONFIG_USB_PUSB2_BUS_ID 0U - -#endif diff --git a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/rt-thread/usb_dc_glue_phytium.c b/rt-thread/components/drivers/usb/cherryusb/port/pusb2/rt-thread/usb_dc_glue_phytium.c deleted file mode 100644 index fdcf300..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/rt-thread/usb_dc_glue_phytium.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright : (C) 2024 Phytium Information Technology, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2024/6/26 first commit - */ -#include "rtthread.h" -#include "interrupt.h" - -#include "fparameters.h" - -#include "usbd_core.h" - -void USBD_IRQHandler(uint8_t busid); - -void usb_assert(const char *filename, int linenum) -{ - rt_assert_handler("", filename, linenum); -} - -static void usb_dc_pusb2_interrupt_handler(int irqno, void *param) -{ - USBD_IRQHandler(CONFIG_USB_PUSB2_BUS_ID); -} - -static void usb_dc_setup_pusb2_interrupt(uint32_t id) -{ - uint32_t irq_num = FUSB2_0_VHUB_IRQ_NUM; - - rt_hw_interrupt_set_priority(irq_num, 0U); - rt_hw_interrupt_install(irq_num, usb_dc_pusb2_interrupt_handler, NULL, "pusb2-dc"); - rt_hw_interrupt_umask(irq_num); -} - -static void usb_dc_revoke_pusb2_interrupt(uint32_t id) -{ - uint32_t irq_num = FUSB2_0_VHUB_IRQ_NUM; - - rt_hw_interrupt_mask(irq_num); -} - -unsigned long usb_dc_get_register_base(uint32_t id) -{ - USB_ASSERT(id == FUSB2_ID_VHUB_0); - return FUSB2_0_VHUB_BASE_ADDR; -} - -void usb_dc_low_level_init() -{ - usb_dc_setup_pusb2_interrupt(CONFIG_USB_PUSB2_BUS_ID); -} - -void usb_dc_low_level_deinit(void) -{ - usb_dc_revoke_pusb2_interrupt(CONFIG_USB_PUSB2_BUS_ID); -} - -void *usb_sys_mem_malloc(size_t size) -{ - void *buf = rt_malloc(size); - - if (buf) { - rt_memset(buf, 0, size); - } - - return buf; -} - -void usb_sys_mem_free(void *ptr) -{ - if (ptr) { - rt_free(ptr); - } -} - -void *usb_sys_malloc_align(size_t align, size_t size) -{ - void *buf = rt_malloc_align(size, align); - - if (buf) { - rt_memset(buf, 0, size); - } - - return buf; -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/rt-thread/usb_hc_glue_phytium.c b/rt-thread/components/drivers/usb/cherryusb/port/pusb2/rt-thread/usb_hc_glue_phytium.c deleted file mode 100644 index 8dcca04..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/pusb2/rt-thread/usb_hc_glue_phytium.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright : (C) 2024 Phytium Information Technology, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2024/6/26 first commit - */ -#include "rtthread.h" -#include "interrupt.h" - -#include "fparameters.h" - -#include "usbh_core.h" - -static const uint32_t irq_nums[] = { - FUSB2_0_VHUB_IRQ_NUM, FUSB2_1_IRQ_NUM, FUSB2_2_IRQ_NUM -}; - -void USBH_IRQHandler(uint8_t busid); - -void usb_assert(const char *filename, int linenum) -{ - rt_assert_handler("", filename, linenum); -} - -static void usb_hc_pusb2_interrupt_handler(int irqno, void *param) -{ - if (irqno == FUSB2_0_VHUB_IRQ_NUM) { - USBH_IRQHandler(FUSB2_ID_VHUB_0); - } else if (irqno == FUSB2_1_IRQ_NUM) { - USBH_IRQHandler(FUSB2_ID_1); - } else if (irqno == FUSB2_2_IRQ_NUM) { - USBH_IRQHandler(FUSB2_ID_2); - } -} - -static void usb_hc_setup_pusb2_interrupt(uint32_t id) -{ - uint32_t irq_num = irq_nums[id]; - - rt_hw_interrupt_set_priority(irq_num, 0U); - rt_hw_interrupt_install(irq_num, usb_hc_pusb2_interrupt_handler, NULL, "pusb2-hc"); - rt_hw_interrupt_umask(irq_num); - - USB_LOG_DBG("Enable irq-%d\n", irq_num); -} - -static void usb_hc_revoke_pusb2_interrupt(uint32_t id) -{ - uint32_t irq_num = irq_nums[id]; - - rt_hw_interrupt_mask(irq_num); -} - -unsigned long usb_hc_get_register_base(uint32_t id) -{ - if (id == FUSB2_ID_VHUB_0) { - return FUSB2_0_VHUB_BASE_ADDR; - } else if (id == FUSB2_ID_1) { - return FUSB2_1_BASE_ADDR; - } else if (id == FUSB2_ID_2) { - return FUSB2_2_BASE_ADDR; - } else { - USB_ASSERT(0); - return 0; - } -} - -void usb_hc_low_level_init(struct usbh_bus *bus) -{ - usb_hc_setup_pusb2_interrupt(bus->busid); -} - -void usb_hc_low_level_deinit(struct usbh_bus *bus) -{ - usb_hc_revoke_pusb2_interrupt(bus->busid); -} - -void *usb_sys_mem_malloc(size_t size) -{ - void *buf = rt_malloc(size); - - if (buf) { - rt_memset(buf, 0, size); - } - - return buf; -} - -void usb_sys_mem_free(void *ptr) -{ - if (ptr) { - rt_free(ptr); - } -} - -void *usb_sys_malloc_align(size_t align, size_t size) -{ - void *buf = rt_malloc_align(size, align); - - if (buf) { - rt_memset(buf, 0, size); - } - - return buf; -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/README.md b/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/README.md deleted file mode 100644 index 4eb6758..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/README.md +++ /dev/null @@ -1,70 +0,0 @@ -# USB 3.0 Host 控制器 (XHCI) - -- Phytium PI 和 Phyium E2000 系列开发板提供符合 XHCI 1.1 规范的 USB 3.0 Host 控制器, 其它 Phytium 系列平台可以通过 PCIe 扩展卡获得 XHCI 控制器 -- 相关的使用例程可以在 Phytium PI(飞腾派)、E2000 D/Q Demo 板以及 D2000 和后续平台上运行,例程包括 - ---------------------------------------------- - -- FreeRTOS - -- - 1. [XHCI 平台控制器使用鼠标/键盘/U盘功能](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/xhci_platform/README.md) -- - 2. [XHCI PCIe控制器使用鼠标/键盘/U盘功能](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/xhci_pcie/README.md) -- - 3. [LVGL 中使用 XHCI 平台控制器连接的鼠标/键盘/U盘](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/blob/master/example/peripheral/media/lvgl_indev/README.md) - ---------------------------------------------- - -- RT-Thread - -- - 1. [XHCI 平台控制器识别鼠标/键盘/U盘](https://github.com/RT-Thread/rt-thread/blob/master/bsp/phytium/doc/use_cherryusb.md) - ---------------------------------------------- - -- Standalone 裸机 - -- - 暂不支持 - ---------------------------------------------- - -- XHCI 的驱动功能以静态库的方式提供,仅限在 Phytium 系列 CPU 平台使用, - -- - libxhci_a64.a : AARCH64 驱动库 -- - libxhci_a32_hardfp.a : AARCH32 驱动库,使用硬浮点 -- - libxhci_a32_softfp.a : AARCH32 驱动库,使用软浮点 - -需要获取源代码请联系 `opensource_embedded@phytium.com.cn` 获取,如需移植运行到非 Phytium 系列 CPU 平台请提前联系`opensource_embedded@phytium.com.cn`获得允许 - -# USB 3.0 Host Controller (XHCI) - -- The Phytium PI and Phytium E2000 series development boards provide USB 3.0 Host controllers that conform to the XHCI 1.1 specification. Other Phytium series platforms can obtain XHCI controllers through PCIe expansion cards. -- Related example routines can be run on Phytium PI (Fetion Pi), E2000 D/Q Demo boards, and D2000 and later platforms. Examples include: - ---------------------------------------------- - -- FreeRTOS - - - 1. [XHCI platform controller for mouse/keyboard/USB drive functions](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/xhci_platform/README.md) - - 2. [XHCI PCIe controller for mouse/keyboard/USB drive functions](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/tree/master/example/peripheral/usb/xhci_pcie/README.md) - - 3. [Using XHCI platform controller-connected mouse/keyboard/USB drive in LVGL](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk/blob/master/example/peripheral/media/lvgl_indev/README.md) - ---------------------------------------------- - -- RT-Thread - - - 1. [XHCI platform controller recognizing mouse/keyboard/USB drive](https://github.com/RT-Thread/rt-thread/blob/master/bsp/phytium/doc/use_cherryusb.md) - ---------------------------------------------- - -- Standalone (Bare Metal) - - - Not supported yet - ---------------------------------------------- - -- This XHCI driver functionality is provided as a static library and is only available for Phytium series CPU platforms. - - - - `libxhci_a64.a` : Driver library for AARCH64 - - - `libxhci_a32_hardfp.a` : Driver library for AARCH32, using hard floating point - - - `libxhci_a32_softfp.a` : Driver library for AARCH32, using soft floating point - -- To obtain the source code, please contact `opensource_embedded@phytium.com.cn`. -- For porting to non-Phytium CPU platforms, shall contact `opensource_embedded@phytium.com.cn` in advance for permission. \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/libxhci_a32_hardfp.a b/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/libxhci_a32_hardfp.a deleted file mode 100644 index 7b1c5bc..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/libxhci_a32_hardfp.a and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/libxhci_a32_softfp_crypto_neon.a b/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/libxhci_a32_softfp_crypto_neon.a deleted file mode 100644 index c5c624e..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/libxhci_a32_softfp_crypto_neon.a and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/libxhci_a32_softfp_neon.a b/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/libxhci_a32_softfp_neon.a deleted file mode 100644 index 5a8a368..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/libxhci_a32_softfp_neon.a and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/libxhci_a64.a b/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/libxhci_a64.a deleted file mode 100644 index 39062c1..0000000 Binary files a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/libxhci_a64.a and /dev/null differ diff --git a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_config.h b/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_config.h deleted file mode 100644 index 460d124..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_config.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright : (C) 2024 Phytium Information Technology, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2024/6/26 first commit - */ -#ifndef CHERRYUSB_CONFIG_H -#define CHERRYUSB_CONFIG_H - -#include "rtthread.h" - -/* ================ USB common Configuration ================ */ - -#define CONFIG_USB_PRINTF(...) rt_kprintf(__VA_ARGS__) - -void *xhci_mem_malloc(size_t align, size_t size); -void xhci_mem_free(void *ptr); - -#define XHCI_DCACHE_FLUSH (1 << 0) -#define XHCI_DCACHE_INVALIDATE (1 << 1) -void xhci_dcache_sync(void *ptr, size_t len, uint32_t flags); - -unsigned long usb_hc_get_register_base(uint32_t id); - -#define usb_malloc(size) xhci_mem_malloc(sizeof(int), size) -#define usb_free(ptr) xhci_mem_free(ptr) - -#ifndef CONFIG_USB_DBG_LEVEL -#if defined(CONFIG_LOG_ERROR) -#define CONFIG_USB_DBG_LEVEL USB_DBG_ERROR -#elif defined(CONFIG_LOG_WARN) -#define CONFIG_USB_DBG_LEVEL USB_DBG_WARNING -#elif defined(CONFIG_LOG_INFO) -#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO -#elif defined(CONFIG_LOG_DEBUG) || defined(CONFIG_LOG_VERBOS) -#define CONFIG_USB_DBG_LEVEL USB_DBG_LOG -#else -#define CONFIG_USB_DBG_LEVEL USB_DBG_ERROR -#endif -#endif - -/* Enable print with color */ -#define CONFIG_USB_PRINTF_COLOR_ENABLE - -/* data align size when use dma */ -#ifndef CONFIG_USB_ALIGN_SIZE -#define CONFIG_USB_ALIGN_SIZE 4 -#endif - -/* attribute data into no cache ram */ -#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable"))) - -/* ================= USB Device Stack Configuration ================ */ - -/* Ep0 in and out transfer buffer */ -#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN -#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 512 -#endif - -/* Setup packet log for debug */ -// #define CONFIG_USBDEV_SETUP_LOG_PRINT - -/* Send ep0 in data from user buffer instead of copying into ep0 reqdata - * Please note that user buffer must be aligned with CONFIG_USB_ALIGN_SIZE -*/ -// #define CONFIG_USBDEV_EP0_INDATA_NO_COPY - -/* Check if the input descriptor is correct */ -// #define CONFIG_USBDEV_DESC_CHECK - -/* Enable test mode */ -// #define CONFIG_USBDEV_TEST_MODE - -#ifndef CONFIG_USBDEV_MSC_MAX_LUN -#define CONFIG_USBDEV_MSC_MAX_LUN 1 -#endif - -#ifndef CONFIG_USBDEV_MSC_MAX_BUFSIZE -#define CONFIG_USBDEV_MSC_MAX_BUFSIZE 512 -#endif - -#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING -#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING "" -#endif - -#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING -#define CONFIG_USBDEV_MSC_PRODUCT_STRING "" -#endif - -#ifndef CONFIG_USBDEV_MSC_VERSION_STRING -#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01" -#endif - -// #define CONFIG_USBDEV_MSC_THREAD - -#ifndef CONFIG_USBDEV_MSC_PRIO -#define CONFIG_USBDEV_MSC_PRIO 4 -#endif - -#ifndef CONFIG_USBDEV_MSC_STACKSIZE -#define CONFIG_USBDEV_MSC_STACKSIZE 2048 -#endif - -#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE -#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156 -#endif - -/* rndis transfer buffer size, must be a multiple of (1536 + 44)*/ -#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE -#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1580 -#endif - -#ifndef CONFIG_USBDEV_RNDIS_VENDOR_ID -#define CONFIG_USBDEV_RNDIS_VENDOR_ID 0x0000ffff -#endif - -#ifndef CONFIG_USBDEV_RNDIS_VENDOR_DESC -#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "CherryUSB" -#endif - -#define CONFIG_USBDEV_RNDIS_USING_LWIP - -/* ================ USB HOST Stack Configuration ================== */ - -#define CONFIG_USBHOST_MAX_RHPORTS 8 -#define CONFIG_USBHOST_MAX_EXTHUBS 4 -#define CONFIG_USBHOST_MAX_EHPORTS 8 -#define CONFIG_USBHOST_MAX_INTERFACES 8 -#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8 -#define CONFIG_USBHOST_MAX_ENDPOINTS 8 - -#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4 -#define CONFIG_USBHOST_MAX_HID_CLASS 4 -#define CONFIG_USBHOST_MAX_MSC_CLASS 2 -#define CONFIG_USBHOST_MAX_AUDIO_CLASS 1 -#define CONFIG_USBHOST_MAX_VIDEO_CLASS 1 - -#define CONFIG_USBHOST_DEV_NAMELEN 16 - -#ifndef CONFIG_USBHOST_PSC_PRIO -#define CONFIG_USBHOST_PSC_PRIO 0 -#endif -#ifndef CONFIG_USBHOST_PSC_STACKSIZE -#define CONFIG_USBHOST_PSC_STACKSIZE 8192 -#endif - -//#define CONFIG_USBHOST_GET_STRING_DESC - -// #define CONFIG_USBHOST_MSOS_ENABLE -#ifndef CONFIG_USBHOST_MSOS_VENDOR_CODE -#define CONFIG_USBHOST_MSOS_VENDOR_CODE 0x00 -#endif - -/* Ep0 max transfer buffer */ -#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN -#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512 -#endif - -#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT -#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500 -#endif - -#ifndef CONFIG_USBHOST_MSC_TIMEOUT -#define CONFIG_USBHOST_MSC_TIMEOUT 0xffffffff -#endif - -#ifndef CONFIG_INPUT_MOUSE_WHEEL -#define CONFIG_INPUT_MOUSE_WHEEL -#endif - -/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, - * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. - */ -#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE -#define CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE (2048) -#endif - -/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ -#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE -#define CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE (2048) -#endif - -/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, - * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. - */ -#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE -#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE (2048) -#endif -/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ -#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE -#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE (2048) -#endif - -/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, - * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. - */ -#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE -#define CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE (2048) -#endif -/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ -#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE -#define CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE (2048) -#endif - -/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, - * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. - */ -#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE -#define CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE (2048) -#endif -/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ -#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE -#define CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE (2048) -#endif - -#define CONFIG_USBHOST_BLUETOOTH_HCI_H4 -// #define CONFIG_USBHOST_BLUETOOTH_HCI_LOG - -#ifndef CONFIG_USBHOST_BLUETOOTH_TX_SIZE -#define CONFIG_USBHOST_BLUETOOTH_TX_SIZE 2048 -#endif -#ifndef CONFIG_USBHOST_BLUETOOTH_RX_SIZE -#define CONFIG_USBHOST_BLUETOOTH_RX_SIZE 2048 -#endif - -/* ================ USB Device Port Configuration ================*/ - -#ifndef CONFIG_USBDEV_MAX_BUS -#define CONFIG_USBDEV_MAX_BUS 2 // for now, bus num must be 1 except hpm ip -#endif - -#ifndef CONFIG_USBDEV_EP_NUM -#define CONFIG_USBDEV_EP_NUM 8 -#endif - -/* ---------------- FSDEV Configuration ---------------- */ -//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference - -/* ---------------- DWC2 Configuration ---------------- */ -// #define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4) -// #define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4) -// #define CONFIG_USB_DWC2_TX1_FIFO_SIZE (512 / 4) -// #define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4) -// #define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4) -// #define CONFIG_USB_DWC2_TX4_FIFO_SIZE (0 / 4) -// #define CONFIG_USB_DWC2_TX5_FIFO_SIZE (0 / 4) -// #define CONFIG_USB_DWC2_TX6_FIFO_SIZE (0 / 4) -// #define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4) -// #define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4) - -/* ---------------- MUSB Configuration ---------------- */ -// #define CONFIG_USB_MUSB_SUNXI - -/* ================ USB Host Port Configuration ==================*/ -#ifndef CONFIG_USBHOST_MAX_BUS -#define CONFIG_USBHOST_MAX_BUS 2 -#endif - -#ifndef CONFIG_USBHOST_PIPE_NUM -#define CONFIG_USBHOST_PIPE_NUM 10 -#endif - -/* ---------------- EHCI Configuration ---------------- */ - -#define CONFIG_USB_EHCI_HCCR_OFFSET (0x0) -#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024 -#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM -#define CONFIG_USB_EHCI_QTD_NUM 3 -#define CONFIG_USB_EHCI_ITD_NUM 20 -// #define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE -// #define CONFIG_USB_EHCI_CONFIGFLAG -// #define CONFIG_USB_EHCI_ISO -// #define CONFIG_USB_EHCI_WITH_OHCI - -/* ---------------- OHCI Configuration ---------------- */ -#define CONFIG_USB_OHCI_HCOR_OFFSET (0x0) - -/* ---------------- XHCI Configuration ---------------- */ -#define CONFIG_USB_XHCI_HCCR_OFFSET (0x0) - -#ifndef CONFIG_USB_XHCI_ENABLE_SOFT_ISR -#define CONFIG_USB_XHCI_ENABLE_SOFT_ISR 0 -#endif - -#endif diff --git a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_glue_phytium.c b/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_glue_phytium.c deleted file mode 100644 index 1f72f31..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_glue_phytium.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright : (C) 2024 Phytium Information Technology, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2024/6/26 first commit - */ -#include "rtthread.h" -#include "usbh_core.h" - -#include "usb_config.h" - -void usb_hc_setup_xhci_interrupt(uint32_t id); -void usb_hc_revoke_xhci_interrupt(uint32_t id); - -void *xhci_mem_malloc(size_t align, size_t size) -{ - void *result = rt_malloc_align(size, align); - - if (result) - { - memset(result, 0U, size); - } - - return result; -} - -void xhci_mem_free(void *ptr) -{ - if (NULL != ptr) - { - rt_free(ptr); - } -} - -void xhci_dcache_sync(void *ptr, size_t len, uint32_t flags) -{ - if (flags & XHCI_DCACHE_FLUSH) - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, ptr, len); - } - else if (flags & XHCI_DCACHE_INVALIDATE) - { - rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, ptr, len); - } -} - -void usb_assert(const char *filename, int linenum) -{ - rt_assert_handler("", filename, linenum); -} - -void usb_hc_low_level_init(struct usbh_bus *bus) -{ - /* platform XHCI controller */ - usb_hc_setup_xhci_interrupt(bus->busid); -} - -void usb_hc_low_level_deinit(struct usbh_bus *bus) -{ - usb_hc_revoke_xhci_interrupt(bus->busid); -} \ No newline at end of file diff --git a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_glue_phytium_plat.c b/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_glue_phytium_plat.c deleted file mode 100644 index 5847eef..0000000 --- a/rt-thread/components/drivers/usb/cherryusb/port/xhci/phytium/rt-thread/usb_glue_phytium_plat.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright : (C) 2024 Phytium Information Technology, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2024/6/26 first commit - */ -#include "rtthread.h" -#include "interrupt.h" - -#include "fparameters.h" - -void USBH_IRQHandler(uint8_t busid); - -static void usb_hc_xhci_interrupt_handler(int irqno, void *param) -{ - if (irqno == FUSB3_0_IRQ_NUM) { - USBH_IRQHandler(FUSB3_ID_0); - } else if (irqno == FUSB3_1_IRQ_NUM) { - USBH_IRQHandler(FUSB3_ID_1); - } -} - -void usb_hc_setup_xhci_interrupt(uint32_t id) -{ - uint32_t irq_num = (id == FUSB3_ID_0) ? FUSB3_0_IRQ_NUM : FUSB3_1_IRQ_NUM; - rt_hw_interrupt_set_priority(irq_num, 0xd0); - rt_hw_interrupt_install(irq_num, usb_hc_xhci_interrupt_handler, - NULL, "xhci"); - rt_hw_interrupt_umask(irq_num); -} - -void usb_hc_revoke_xhci_interrupt(uint32_t id) -{ - uint32_t irq_num = (id == FUSB3_ID_0) ? FUSB3_0_IRQ_NUM : FUSB3_1_IRQ_NUM; - - rt_hw_interrupt_mask(irq_num); -} - -unsigned long usb_hc_get_register_base(uint32_t id) -{ - if (FUSB3_ID_0 == id) - return FUSB3_0_BASE_ADDR + FUSB3_XHCI_OFFSET; - else - return FUSB3_1_BASE_ADDR + FUSB3_XHCI_OFFSET; -} \ No newline at end of file diff --git a/rt-thread/components/drivers/virtio/virtio_net.c b/rt-thread/components/drivers/virtio/virtio_net.c index d92421b..93a30ee 100644 --- a/rt-thread/components/drivers/virtio/virtio_net.c +++ b/rt-thread/components/drivers/virtio/virtio_net.c @@ -24,6 +24,10 @@ static rt_err_t virtio_net_tx(rt_device_t dev, struct pbuf *p) struct virtio_device *virtio_dev = &virtio_net_dev->virtio_dev; struct virtq *queue_tx = &virtio_dev->queues[VIRTIO_NET_QUEUE_TX]; +#ifdef RT_USING_SMP + rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock); +#endif + id = (queue_tx->avail->idx * 2) % queue_tx->num; virtio_net_dev->info[id].hdr.flags = 0; @@ -52,6 +56,10 @@ static rt_err_t virtio_net_tx(rt_device_t dev, struct pbuf *p) virtio_alloc_desc(virtio_dev, VIRTIO_NET_QUEUE_TX); virtio_alloc_desc(virtio_dev, VIRTIO_NET_QUEUE_TX); +#ifdef RT_USING_SMP + rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level); +#endif + return RT_EOK; } @@ -59,26 +67,46 @@ static struct pbuf *virtio_net_rx(rt_device_t dev) { rt_uint16_t id; rt_uint32_t len; - struct pbuf *p = RT_NULL; + struct pbuf *p = RT_NULL, *new, *ret = RT_NULL; struct virtio_net_device *virtio_net_dev = (struct virtio_net_device *)dev; struct virtio_device *virtio_dev = &virtio_net_dev->virtio_dev; struct virtq *queue_rx = &virtio_dev->queues[VIRTIO_NET_QUEUE_RX]; - if (queue_rx->used_idx != queue_rx->used->idx) + while (queue_rx->used_idx != queue_rx->used->idx) { +#ifdef RT_USING_SMP + rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock); +#endif id = (queue_rx->used->ring[queue_rx->used_idx % queue_rx->num].id + 1) % queue_rx->num; len = queue_rx->used->ring[queue_rx->used_idx % queue_rx->num].len - VIRTIO_NET_HDR_SIZE; +#ifdef RT_USING_SMP + rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level); +#endif if (len > VIRTIO_NET_PAYLOAD_MAX_SIZE) { rt_kprintf("%s: Receive buffer's size = %u is too big!\n", virtio_net_dev->parent.parent.parent.name, len); len = VIRTIO_NET_PAYLOAD_MAX_SIZE; } - p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM); + new = pbuf_alloc(PBUF_RAW, len, PBUF_RAM); if (p != RT_NULL) { + p->next = new; + p = p->next; + } + else + { + p = new; + ret = p; + } + + if (p != RT_NULL) + { +#ifdef RT_USING_SMP + level = rt_spin_lock_irqsave(&virtio_dev->spinlock); +#endif rt_memcpy(p->payload, (void *)queue_rx->desc[id].addr - PV_OFFSET, len); queue_rx->used_idx++; @@ -86,10 +114,18 @@ static struct pbuf *virtio_net_rx(rt_device_t dev) virtio_submit_chain(virtio_dev, VIRTIO_NET_QUEUE_RX, id - 1); virtio_queue_notify(virtio_dev, VIRTIO_NET_QUEUE_RX); + +#ifdef RT_USING_SMP + rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level); +#endif + } + else + { + break; } } - return p; + return ret; } static rt_err_t virtio_net_init(rt_device_t dev) @@ -178,6 +214,10 @@ static void virtio_net_isr(int irqno, void *param) struct virtio_device *virtio_dev = &virtio_net_dev->virtio_dev; struct virtq *queue_rx = &virtio_dev->queues[VIRTIO_NET_QUEUE_RX]; +#ifdef RT_USING_SMP + rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock); +#endif + virtio_interrupt_ack(virtio_dev); rt_hw_dsb(); @@ -187,6 +227,10 @@ static void virtio_net_isr(int irqno, void *param) eth_device_ready(&virtio_net_dev->parent); } + +#ifdef RT_USING_SMP + rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level); +#endif } rt_err_t rt_virtio_net_init(rt_ubase_t *mmio_base, rt_uint32_t irq) @@ -209,6 +253,10 @@ rt_err_t rt_virtio_net_init(rt_ubase_t *mmio_base, rt_uint32_t irq) virtio_net_dev->config = (struct virtio_net_config *)virtio_dev->mmio_config->config; +#ifdef RT_USING_SMP + rt_spin_lock_init(&virtio_dev->spinlock); +#endif + virtio_reset_device(virtio_dev); virtio_status_acknowledge_driver(virtio_dev); diff --git a/rt-thread/components/drivers/watchdog/dev_watchdog.c b/rt-thread/components/drivers/watchdog/dev_watchdog.c deleted file mode 100644 index 9293ebd..0000000 --- a/rt-thread/components/drivers/watchdog/dev_watchdog.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * COPYRIGHT (C) 2011-2023, Real-Thread Information Technology Ltd - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-09-12 heyuanjie87 first version. - * 2014-03-04 Bernard code cleanup - */ - -#include "drivers/dev_watchdog.h" - -/* RT-Thread Device Interface */ - -/* - * This function initializes watchdog - */ -static rt_err_t rt_watchdog_init(struct rt_device *dev) -{ - rt_watchdog_t *wtd; - - RT_ASSERT(dev != RT_NULL); - wtd = (rt_watchdog_t *)dev; - if (wtd->ops->init) - { - return (wtd->ops->init(wtd)); - } - - return (-RT_ENOSYS); -} - -static rt_err_t rt_watchdog_open(struct rt_device *dev, rt_uint16_t oflag) -{ - return (RT_EOK); -} - -static rt_err_t rt_watchdog_close(struct rt_device *dev) -{ - rt_watchdog_t *wtd; - - RT_ASSERT(dev != RT_NULL); - wtd = (rt_watchdog_t *)dev; - - if (wtd->ops->control(wtd, RT_DEVICE_CTRL_WDT_STOP, RT_NULL) != RT_EOK) - { - rt_kprintf(" This watchdog can not be stoped\n"); - - return (-RT_ERROR); - } - - return (RT_EOK); -} - -static rt_err_t rt_watchdog_control(struct rt_device *dev, - int cmd, - void *args) -{ - rt_watchdog_t *wtd; - - RT_ASSERT(dev != RT_NULL); - wtd = (rt_watchdog_t *)dev; - - return (wtd->ops->control(wtd, cmd, args)); -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops wdt_ops = -{ - rt_watchdog_init, - rt_watchdog_open, - rt_watchdog_close, - RT_NULL, - RT_NULL, - rt_watchdog_control, -}; -#endif - -/** - * This function register a watchdog device - */ -rt_err_t rt_hw_watchdog_register(struct rt_watchdog_device *wtd, - const char *name, - rt_uint32_t flag, - void *data) -{ - struct rt_device *device; - RT_ASSERT(wtd != RT_NULL); - - device = &(wtd->parent); - - device->type = RT_Device_Class_WDT; - device->rx_indicate = RT_NULL; - device->tx_complete = RT_NULL; - -#ifdef RT_USING_DEVICE_OPS - device->ops = &wdt_ops; -#else - device->init = rt_watchdog_init; - device->open = rt_watchdog_open; - device->close = rt_watchdog_close; - device->read = RT_NULL; - device->write = RT_NULL; - device->control = rt_watchdog_control; -#endif - device->user_data = data; - - /* register a character device */ - return rt_device_register(device, name, flag); -} diff --git a/rt-thread/components/drivers/wlan/SConscript b/rt-thread/components/drivers/wlan/SConscript index fed9478..f2a6bbd 100644 --- a/rt-thread/components/drivers/wlan/SConscript +++ b/rt-thread/components/drivers/wlan/SConscript @@ -4,26 +4,26 @@ cwd = GetCurrentDir() CPPPATH = [cwd] src = Split(''' - dev_wlan.c + wlan_dev.c ''') if GetDepend(['RT_WLAN_MANAGE_ENABLE']): - src += ['dev_wlan_mgnt.c'] + src += ['wlan_mgnt.c'] if GetDepend(['RT_WLAN_MSH_CMD_ENABLE']): - src += ['dev_wlan_cmd.c'] + src += ['wlan_cmd.c'] if GetDepend(['RT_WLAN_PROT_ENABLE']): - src += ['dev_wlan_prot.c'] + src += ['wlan_prot.c'] if GetDepend(['RT_WLAN_PROT_LWIP_ENABLE']): - src += ['dev_wlan_lwip.c'] + src += ['wlan_lwip.c'] if GetDepend(['RT_WLAN_CFG_ENABLE']): - src += ['dev_wlan_cfg.c'] + src += ['wlan_cfg.c'] if GetDepend(['RT_WLAN_WORK_THREAD_ENABLE']): - src += ['dev_wlan_workqueue.c'] + src += ['wlan_workqueue.c'] group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_WIFI'], CPPPATH = CPPPATH) diff --git a/rt-thread/components/drivers/wlan/dev_wlan.c b/rt-thread/components/drivers/wlan/dev_wlan.c deleted file mode 100644 index a3ed034..0000000 --- a/rt-thread/components/drivers/wlan/dev_wlan.c +++ /dev/null @@ -1,1034 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-08-03 tyx the first version - * 2024-12-25 Evlers add get_info api for more new sta information - * 2025-01-04 Evlers add ap_get_info api for more ap information - */ - -#include -#include -#include -#include - -#define DBG_TAG "WLAN.dev" -#ifdef RT_WLAN_DEV_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif /* RT_WLAN_DEV_DEBUG */ -#include - -#if defined(RT_USING_WIFI) || defined(RT_USING_WLAN) - -#ifndef RT_DEVICE -#define RT_DEVICE(__device) ((rt_device_t)__device) -#endif - -#define WLAN_DEV_LOCK(_wlan) (rt_mutex_take(&(_wlan)->lock, RT_WAITING_FOREVER)) -#define WLAN_DEV_UNLOCK(_wlan) (rt_mutex_release(&(_wlan)->lock)) - -#if RT_WLAN_SSID_MAX_LENGTH < 1 -#error "SSID length is too short" -#endif - -#if RT_WLAN_BSSID_MAX_LENGTH < 1 -#error "BSSID length is too short" -#endif - -#if RT_WLAN_PASSWORD_MAX_LENGTH < 1 -#error "password length is too short" -#endif - -#if RT_WLAN_DEV_EVENT_NUM < 2 -#error "dev num Too little" -#endif - -rt_err_t rt_wlan_dev_init(struct rt_wlan_device *device, rt_wlan_mode_t mode) -{ - rt_err_t result = RT_EOK; - - /* init wlan device */ - LOG_D("F:%s L:%d is run device:0x%08x mode:%d", __FUNCTION__, __LINE__, device, mode); - if ((device == RT_NULL) || (mode >= RT_WLAN_MODE_MAX)) - { - LOG_E("F:%s L:%d Parameter Wrongful device:0x%08x mode:%d", __FUNCTION__, __LINE__, device, mode); - return -RT_ERROR; - } - - if (mode == RT_WLAN_AP && device->flags & RT_WLAN_FLAG_STA_ONLY) - { - LOG_E("F:%s L:%d This wlan device can only be set to sta mode!", __FUNCTION__, __LINE__); - return -RT_ERROR; - } - else if (mode == RT_WLAN_STATION && device->flags & RT_WLAN_FLAG_AP_ONLY) - { - LOG_E("F:%s L:%d This wlan device can only be set to ap mode!", __FUNCTION__, __LINE__); - return -RT_ERROR; - } - - result = rt_device_init(RT_DEVICE(device)); - if (result != RT_EOK) - { - LOG_E("L:%d wlan init failed", __LINE__); - return -RT_ERROR; - } - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_MODE, (void *)&mode); - if (result != RT_EOK) - { - LOG_E("L:%d wlan config mode failed", __LINE__); - return -RT_ERROR; - } - device->mode = mode; - return result; -} - -rt_err_t rt_wlan_dev_connect(struct rt_wlan_device *device, struct rt_wlan_info *info, const char *password, int password_len) -{ - rt_err_t result = RT_EOK; - struct rt_sta_info sta_info; - - if (device == RT_NULL) - { - return -RT_EIO; - } - if (info == RT_NULL) - { - return -RT_ERROR; - } - - if ((password_len > RT_WLAN_PASSWORD_MAX_LENGTH) || - (info->ssid.len > RT_WLAN_SSID_MAX_LENGTH)) - { - LOG_E("L:%d password or ssid is too long", __LINE__); - return -RT_ERROR; - } - rt_memset(&sta_info, 0, sizeof(struct rt_sta_info)); - rt_memcpy(&sta_info.ssid, &info->ssid, sizeof(rt_wlan_ssid_t)); - rt_memcpy(sta_info.bssid, info->bssid, RT_WLAN_BSSID_MAX_LENGTH); - if (password != RT_NULL) - { - rt_memcpy(sta_info.key.val, password, password_len); - sta_info.key.len = password_len; - } - sta_info.channel = info->channel; - sta_info.security = info->security; - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_JOIN, &sta_info); - return result; -} - -rt_err_t rt_wlan_dev_fast_connect(struct rt_wlan_device *device, struct rt_wlan_info *info, const char *password, int password_len) -{ - rt_err_t result = RT_EOK; - struct rt_wlan_buff buff = {0}; - - if (device == RT_NULL) - { - return -RT_EIO; - } - if (info == RT_NULL) - { - return -RT_ERROR; - } - - if ((password_len > RT_WLAN_PASSWORD_MAX_LENGTH) || - (info->ssid.len > RT_WLAN_SSID_MAX_LENGTH)) - { - LOG_E("L:%d password or ssid is too long", __LINE__); - return -RT_ERROR; - } - - buff.len = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_FAST_CONNECT_INFO, buff.data); - if(buff.len < 0) - { - LOG_D("L:%d Can't get fast connect info", __LINE__); - return buff.len; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_FAST_CONNECT, &buff); - - return result; -} - -rt_err_t rt_wlan_dev_disconnect(struct rt_wlan_device *device) -{ - rt_err_t result = RT_EOK; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_DISCONNECT, RT_NULL); - return result; -} - -rt_err_t rt_wlan_dev_ap_start(struct rt_wlan_device *device, struct rt_wlan_info *info, const char *password, int password_len) -{ - rt_err_t result = RT_EOK; - struct rt_ap_info ap_info; - - if (device == RT_NULL) - { - return -RT_EIO; - } - if (info == RT_NULL) - { - return -RT_ERROR; - } - - if ((password_len > RT_WLAN_PASSWORD_MAX_LENGTH) || - (info->ssid.len > RT_WLAN_SSID_MAX_LENGTH)) - { - LOG_E("L:%d password or ssid is too long", __LINE__); - return -RT_ERROR; - } - - rt_memset(&ap_info, 0, sizeof(struct rt_ap_info)); - rt_memcpy(&ap_info.ssid, &info->ssid, sizeof(rt_wlan_ssid_t)); - if (password != RT_NULL) - { - rt_memcpy(ap_info.key.val, password, password_len); - } - ap_info.key.len = password_len; - ap_info.hidden = info->hidden; - ap_info.channel = info->channel; - ap_info.security = info->security; - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_SOFTAP, &ap_info); - return result; -} - -rt_err_t rt_wlan_dev_ap_stop(struct rt_wlan_device *device) -{ - rt_err_t result = RT_EOK; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_AP_STOP, RT_NULL); - return result; -} - -rt_err_t rt_wlan_dev_ap_deauth(struct rt_wlan_device *device, rt_uint8_t mac[6]) -{ - rt_err_t result = RT_EOK; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_AP_DEAUTH, mac); - return result; -} - -int rt_wlan_dev_get_rssi(struct rt_wlan_device *device) -{ - int rssi = 0; - rt_err_t result = RT_EOK; - - if (device == RT_NULL) - { - rt_set_errno(-RT_EIO); - return 0; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_RSSI, &rssi); - if (result != RT_EOK) - { - rt_set_errno(result); - return 0; - } - - return rssi; -} - -rt_err_t rt_wlan_dev_get_info(struct rt_wlan_device *device, struct rt_wlan_info *info) -{ - rt_err_t result = RT_EOK; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_INFO, info); - if (result != RT_EOK) - { - rt_set_errno(result); - return 0; - } - - return result; -} - -rt_err_t rt_wlan_dev_ap_get_info(struct rt_wlan_device *device, struct rt_wlan_info *info) -{ - rt_err_t result = RT_EOK; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_AP_GET_INFO, info); - if (result != RT_EOK) - { - rt_set_errno(result); - return 0; - } - - return result; -} - -rt_err_t rt_wlan_dev_get_mac(struct rt_wlan_device *device, rt_uint8_t mac[6]) -{ - rt_err_t result = RT_EOK; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_MAC, &mac[0]); - return result; -} - -rt_err_t rt_wlan_dev_set_mac(struct rt_wlan_device *device, rt_uint8_t mac[6]) -{ - rt_err_t result = RT_EOK; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_SET_MAC, &mac[0]); - return result; -} - -rt_err_t rt_wlan_dev_set_powersave(struct rt_wlan_device *device, int level) -{ - rt_err_t result = RT_EOK; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_SET_POWERSAVE, &level); - return result; -} - -int rt_wlan_dev_get_powersave(struct rt_wlan_device *device) -{ - int level = -1; - rt_err_t result = RT_EOK; - - if (device == RT_NULL) - { - rt_set_errno(-RT_EIO); - return -1; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_POWERSAVE, &level); - if (result != RT_EOK) - { - rt_set_errno(result); - } - - return level; -} - -rt_err_t rt_wlan_dev_register_event_handler(struct rt_wlan_device *device, rt_wlan_dev_event_t event, rt_wlan_dev_event_handler handler, void *parameter) -{ - int i = 0; - rt_base_t level; - - if (device == RT_NULL) - { - return -RT_EIO; - } - if (event >= RT_WLAN_DEV_EVT_MAX) - { - return -RT_EINVAL; - } - - level = rt_hw_interrupt_disable(); - for (i = 0; i < RT_WLAN_DEV_EVENT_NUM; i++) - { - if (device->handler_table[event][i].handler == RT_NULL) - { - device->handler_table[event][i].handler = handler; - device->handler_table[event][i].parameter = parameter; - rt_hw_interrupt_enable(level); - return RT_EOK; - } - } - rt_hw_interrupt_enable(level); - - /* No space found */ - return -RT_ERROR; -} - -rt_err_t rt_wlan_dev_unregister_event_handler(struct rt_wlan_device *device, rt_wlan_dev_event_t event, rt_wlan_dev_event_handler handler) -{ - int i = 0; - rt_base_t level; - - if (device == RT_NULL) - { - return -RT_EIO; - } - if (event >= RT_WLAN_DEV_EVT_MAX) - { - return -RT_EINVAL; - } - - level = rt_hw_interrupt_disable(); - for (i = 0; i < RT_WLAN_DEV_EVENT_NUM; i++) - { - if (device->handler_table[event][i].handler == handler) - { - rt_memset(&device->handler_table[event][i], 0, sizeof(struct rt_wlan_dev_event_desc)); - rt_hw_interrupt_enable(level); - return RT_EOK; - } - } - rt_hw_interrupt_enable(level); - /* not find iteam */ - return -RT_ERROR; -} - -void rt_wlan_dev_indicate_event_handle(struct rt_wlan_device *device, rt_wlan_dev_event_t event, struct rt_wlan_buff *buff) -{ - void *parameter[RT_WLAN_DEV_EVENT_NUM] = {0}; - rt_wlan_dev_event_handler handler[RT_WLAN_DEV_EVENT_NUM] = {0}; - int i; - rt_base_t level; - - if (device == RT_NULL) - { - return; - } - if (event >= RT_WLAN_DEV_EVT_MAX) - { - return; - } - - /* get callback handle */ - level = rt_hw_interrupt_disable(); - for (i = 0; i < RT_WLAN_DEV_EVENT_NUM; i++) - { - handler[i] = device->handler_table[event][i].handler; - parameter[i] = device->handler_table[event][i].parameter; - } - rt_hw_interrupt_enable(level); - - /* run callback */ - for (i = 0; i < RT_WLAN_DEV_EVENT_NUM; i++) - { - if (handler[i] != RT_NULL) - { - handler[i](device, event, buff, parameter[i]); - } - } -} - -rt_err_t rt_wlan_dev_enter_promisc(struct rt_wlan_device *device) -{ - rt_err_t result = RT_EOK; - int enable = 1; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_CFG_PROMISC, &enable); - return result; -} - -rt_err_t rt_wlan_dev_exit_promisc(struct rt_wlan_device *device) -{ - rt_err_t result = RT_EOK; - int enable = 0; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_CFG_PROMISC, &enable); - return result; -} - -rt_err_t rt_wlan_dev_set_promisc_callback(struct rt_wlan_device *device, rt_wlan_pormisc_callback_t callback) -{ - if (device == RT_NULL) - { - return -RT_EIO; - } - device->pormisc_callback = callback; - - return RT_EOK; -} - -void rt_wlan_dev_promisc_handler(struct rt_wlan_device *device, void *data, int len) -{ - rt_wlan_pormisc_callback_t callback; - - if (device == RT_NULL) - { - return; - } - - callback = device->pormisc_callback; - - if (callback != RT_NULL) - { - callback(device, data, len); - } -} - -rt_err_t rt_wlan_dev_cfg_filter(struct rt_wlan_device *device, struct rt_wlan_filter *filter) -{ - rt_err_t result = RT_EOK; - - if (device == RT_NULL) - { - return -RT_EIO; - } - if (filter == RT_NULL) - { - return -RT_ERROR; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_CFG_FILTER, filter); - return result; -} - -rt_err_t rt_wlan_dev_set_channel(struct rt_wlan_device *device, int channel) -{ - rt_err_t result = RT_EOK; - - if (device == RT_NULL) - { - return -RT_EIO; - } - if (channel < 0) - { - return -RT_ERROR; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_SET_CHANNEL, &channel); - return result; -} - -int rt_wlan_dev_get_channel(struct rt_wlan_device *device) -{ - rt_err_t result = RT_EOK; - int channel = -1; - - if (device == RT_NULL) - { - rt_set_errno(-RT_EIO); - return -1; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_CHANNEL, &channel); - if (result != RT_EOK) - { - rt_set_errno(result); - return -1; - } - - return channel; -} - -rt_err_t rt_wlan_dev_set_country(struct rt_wlan_device *device, rt_country_code_t country_code) -{ - int result = RT_EOK; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_SET_COUNTRY, &country_code); - return result; -} - -rt_country_code_t rt_wlan_dev_get_country(struct rt_wlan_device *device) -{ - int result = RT_EOK; - rt_country_code_t country_code = RT_COUNTRY_UNKNOWN; - - if (device == RT_NULL) - { - rt_set_errno(-RT_EIO); - return RT_COUNTRY_UNKNOWN; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_COUNTRY, &country_code); - if (result != RT_EOK) - { - rt_set_errno(result); - return RT_COUNTRY_UNKNOWN; - } - - return country_code; -} - -rt_err_t rt_wlan_dev_scan(struct rt_wlan_device *device, struct rt_wlan_info *info) -{ - struct rt_scan_info scan_info = { 0 }; - struct rt_scan_info *p_scan_info = RT_NULL; - rt_err_t result = 0; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - if (info != RT_NULL) - { - if (info->ssid.len > RT_WLAN_SSID_MAX_LENGTH) - { - LOG_E("L:%d ssid is too long", __LINE__); - return -RT_EINVAL; - } - rt_memcpy(&scan_info.ssid, &info->ssid, sizeof(rt_wlan_ssid_t)); - rt_memcpy(scan_info.bssid, info->bssid, RT_WLAN_BSSID_MAX_LENGTH); - if (info->channel > 0) - { - scan_info.channel_min = info->channel; - scan_info.channel_max = info->channel; - } - else - { - scan_info.channel_min = -1; - scan_info.channel_max = -1; - } - scan_info.passive = info->hidden ? RT_TRUE : RT_FALSE; - p_scan_info = &scan_info; - } - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_SCAN, p_scan_info); - return result; -} - -rt_err_t rt_wlan_dev_scan_stop(struct rt_wlan_device *device) -{ - rt_err_t result = 0; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_SCAN_STOP, RT_NULL); - return result; -} - -rt_err_t rt_wlan_dev_report_data(struct rt_wlan_device *device, void *buff, int len) -{ -#ifdef RT_WLAN_PROT_ENABLE - return rt_wlan_dev_transfer_prot(device, buff, len); -#else - return -RT_ERROR; -#endif -} - -rt_err_t rt_wlan_dev_enter_mgnt_filter(struct rt_wlan_device *device) -{ - rt_err_t result = RT_EOK; - int enable = 1; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_CFG_MGNT_FILTER, &enable); - return result; -} - -rt_err_t rt_wlan_dev_exit_mgnt_filter(struct rt_wlan_device *device) -{ - rt_err_t result = RT_EOK; - int enable = 0; - - if (device == RT_NULL) - { - return -RT_EIO; - } - - result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_CFG_MGNT_FILTER, &enable); - return result; -} - -rt_err_t rt_wlan_dev_set_mgnt_filter_callback(struct rt_wlan_device *device, rt_wlan_mgnt_filter_callback_t callback) -{ - if (device == RT_NULL) - { - return -RT_EIO; - } - device->mgnt_filter_callback = callback; - - return RT_EOK; -} - -void rt_wlan_dev_mgnt_filter_handler(struct rt_wlan_device *device, void *data, int len) -{ - rt_wlan_mgnt_filter_callback_t callback; - - if (device == RT_NULL) - { - return; - } - - callback = device->mgnt_filter_callback; - - if (callback != RT_NULL) - { - callback(device, data, len); - } -} - -int rt_wlan_dev_send_raw_frame(struct rt_wlan_device *device, void *buff, int len) -{ - if (device == RT_NULL) - { - return -RT_EIO; - } - - if (device->ops->wlan_send_raw_frame) - { - return device->ops->wlan_send_raw_frame(device, buff, len); - } - - return -RT_ERROR; -} - -static rt_err_t _rt_wlan_dev_init(rt_device_t dev) -{ - struct rt_wlan_device *wlan = (struct rt_wlan_device *)dev; - rt_err_t result = RT_EOK; - - rt_mutex_init(&wlan->lock, "wlan_dev", RT_IPC_FLAG_PRIO); - - if (wlan->ops->wlan_init) - result = wlan->ops->wlan_init(wlan); - - if (result == RT_EOK) - { - LOG_I("wlan init success"); - } - else - { - LOG_I("wlan init failed"); - } - - return result; -} - -static rt_err_t _rt_wlan_dev_control(rt_device_t dev, int cmd, void *args) -{ - struct rt_wlan_device *wlan = (struct rt_wlan_device *)dev; - rt_err_t err = RT_EOK; - - RT_ASSERT(dev != RT_NULL); - - WLAN_DEV_LOCK(wlan); - - switch (cmd) - { - case RT_WLAN_CMD_MODE: - { - rt_wlan_mode_t mode = *((rt_wlan_mode_t *)args); - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_MODE, "RT_WLAN_CMD_MODE"); - if (wlan->ops->wlan_mode) - err = wlan->ops->wlan_mode(wlan, mode); - break; - } - case RT_WLAN_CMD_SCAN: - { - struct rt_scan_info *scan_info = args; - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_SCAN, "RT_WLAN_CMD_SCAN"); - if (wlan->ops->wlan_scan) - err = wlan->ops->wlan_scan(wlan, scan_info); - break; - } - case RT_WLAN_CMD_JOIN: - { - struct rt_sta_info *sta_info = args; - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_JOIN, "RT_WLAN_CMD_JOIN"); - if (wlan->ops->wlan_join) - err = wlan->ops->wlan_join(wlan, sta_info); - break; - } - case RT_WLAN_CMD_SOFTAP: - { - struct rt_ap_info *ap_info = args; - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_SOFTAP, "RT_WLAN_CMD_SOFTAP"); - if (wlan->ops->wlan_softap) - err = wlan->ops->wlan_softap(wlan, ap_info); - break; - } - case RT_WLAN_CMD_DISCONNECT: - { - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_DISCONNECT, "RT_WLAN_CMD_DISCONNECT"); - if (wlan->ops->wlan_disconnect) - err = wlan->ops->wlan_disconnect(wlan); - break; - } - case RT_WLAN_CMD_AP_STOP: - { - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_AP_STOP, "RT_WLAN_CMD_AP_STOP"); - if (wlan->ops->wlan_ap_stop) - err = wlan->ops->wlan_ap_stop(wlan); - break; - } - case RT_WLAN_CMD_AP_DEAUTH: - { - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_AP_DEAUTH, "RT_WLAN_CMD_AP_DEAUTH"); - if (wlan->ops->wlan_ap_deauth) - err = wlan->ops->wlan_ap_deauth(wlan, args); - break; - } - case RT_WLAN_CMD_SCAN_STOP: - { - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_SCAN_STOP, "RT_WLAN_CMD_SCAN_STOP"); - if (wlan->ops->wlan_scan_stop) - err = wlan->ops->wlan_scan_stop(wlan); - break; - } - case RT_WLAN_CMD_GET_RSSI: - { - int *rssi = args; - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_GET_RSSI, "RT_WLAN_CMD_GET_RSSI"); - if (wlan->ops->wlan_get_rssi) - *rssi = wlan->ops->wlan_get_rssi(wlan); - break; - } - case RT_WLAN_CMD_GET_INFO: - { - struct rt_wlan_info *info = args; - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_GET_INFO, "RT_WLAN_CMD_GET_INFO"); - if (wlan->ops->wlan_get_info) - err = wlan->ops->wlan_get_info(wlan, info); - else - err = -RT_ERROR; - break; - } - case RT_WLAN_CMD_AP_GET_INFO: - { - struct rt_wlan_info *info = args; - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_AP_GET_INFO, "RT_WLAN_CMD_AP_GET_INFO"); - if (wlan->ops->wlan_ap_get_info) - err = wlan->ops->wlan_ap_get_info(wlan, info); - break; - } - case RT_WLAN_CMD_SET_POWERSAVE: - { - int level = *((int *)args); - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_SET_POWERSAVE, "RT_WLAN_CMD_SET_POWERSAVE"); - if (wlan->ops->wlan_set_powersave) - err = wlan->ops->wlan_set_powersave(wlan, level); - break; - } - case RT_WLAN_CMD_GET_POWERSAVE: - { - int *level = args; - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_GET_POWERSAVE, "RT_WLAN_CMD_GET_POWERSAVE"); - if (wlan->ops->wlan_get_powersave) - *level = wlan->ops->wlan_get_powersave(wlan); - break; - } - case RT_WLAN_CMD_CFG_PROMISC: - { - rt_bool_t start = *((rt_bool_t *)args); - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_CFG_PROMISC, "RT_WLAN_CMD_CFG_PROMISC"); - if (wlan->ops->wlan_cfg_promisc) - err = wlan->ops->wlan_cfg_promisc(wlan, start); - break; - } - case RT_WLAN_CMD_CFG_FILTER: - { - struct rt_wlan_filter *filter = args; - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_CFG_FILTER, "RT_WLAN_CMD_CFG_FILTER"); - if (wlan->ops->wlan_cfg_filter) - err = wlan->ops->wlan_cfg_filter(wlan, filter); - break; - } - case RT_WLAN_CMD_CFG_MGNT_FILTER: - { - rt_bool_t start = *((rt_bool_t *)args); - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_CFG_MGNT_FILTER, "RT_WLAN_CMD_CFG_MGNT_FILTER"); - if (wlan->ops->wlan_cfg_mgnt_filter) - err = wlan->ops->wlan_cfg_mgnt_filter(wlan, start); - break; - } - case RT_WLAN_CMD_SET_CHANNEL: - { - int channel = *(int *)args; - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_SET_CHANNEL, "RT_WLAN_CMD_SET_CHANNEL"); - if (wlan->ops->wlan_set_channel) - err = wlan->ops->wlan_set_channel(wlan, channel); - break; - } - case RT_WLAN_CMD_GET_CHANNEL: - { - int *channel = args; - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_GET_CHANNEL, "RT_WLAN_CMD_GET_CHANNEL"); - if (wlan->ops->wlan_get_channel) - *channel = wlan->ops->wlan_get_channel(wlan); - break; - } - case RT_WLAN_CMD_SET_COUNTRY: - { - rt_country_code_t country = *(rt_country_code_t *)args; - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_SET_COUNTRY, "RT_WLAN_CMD_SET_COUNTRY"); - if (wlan->ops->wlan_set_country) - err = wlan->ops->wlan_set_country(wlan, country); - break; - } - case RT_WLAN_CMD_GET_COUNTRY: - { - rt_country_code_t *country = args; - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_GET_COUNTRY, "RT_WLAN_CMD_GET_COUNTRY"); - if (wlan->ops->wlan_get_country) - *country = wlan->ops->wlan_get_country(wlan); - break; - } - case RT_WLAN_CMD_SET_MAC: - { - rt_uint8_t *mac = args; - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_SET_MAC, "RT_WLAN_CMD_SET_MAC"); - if (wlan->ops->wlan_set_mac) - err = wlan->ops->wlan_set_mac(wlan, mac); - break; - } - case RT_WLAN_CMD_GET_MAC: - { - rt_uint8_t *mac = args; - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_GET_MAC, "RT_WLAN_CMD_GET_MAC"); - if (wlan->ops->wlan_get_mac) - err = wlan->ops->wlan_get_mac(wlan, mac); - break; - } - case RT_WLAN_CMD_GET_FAST_CONNECT_INFO: - { - - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_GET_FAST_INFO, "RT_WLAN_CMD_GET_FAST_INFO"); - if (wlan->ops->wlan_get_fast_info) - { - err = wlan->ops->wlan_get_fast_info(args); - } - else - { - err = -RT_EEMPTY; - } - break; - } - case RT_WLAN_CMD_FAST_CONNECT: - { - struct rt_wlan_buff *buff = (struct rt_wlan_buff *)args; - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_FAST_CONNECT, "RT_WLAN_CMD_FAST_CONNECT"); - if (wlan->ops->wlan_get_fast_info) - { - err = wlan->ops->wlan_fast_connect(buff->data,buff->len); - } - else - { - err = -RT_EEMPTY; - } - break; - } - - default: - LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, -1, "UNKUOWN"); - break; - } - - WLAN_DEV_UNLOCK(wlan); - - return err; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops wlan_ops = -{ - _rt_wlan_dev_init, - RT_NULL, - RT_NULL, - RT_NULL, - RT_NULL, - _rt_wlan_dev_control -}; -#endif - -rt_err_t rt_wlan_dev_register(struct rt_wlan_device *wlan, const char *name, const struct rt_wlan_dev_ops *ops, rt_uint32_t flag, void *user_data) -{ - rt_err_t err = RT_EOK; - - if ((wlan == RT_NULL) || (name == RT_NULL) || (ops == RT_NULL) || - (flag & RT_WLAN_FLAG_STA_ONLY && flag & RT_WLAN_FLAG_AP_ONLY)) - { - LOG_E("F:%s L:%d parameter Wrongful", __FUNCTION__, __LINE__); - return RT_NULL; - } - - rt_memset(wlan, 0, sizeof(struct rt_wlan_device)); - -#ifdef RT_USING_DEVICE_OPS - wlan->device.ops = &wlan_ops; -#else - wlan->device.init = _rt_wlan_dev_init; - wlan->device.open = RT_NULL; - wlan->device.close = RT_NULL; - wlan->device.read = RT_NULL; - wlan->device.write = RT_NULL; - wlan->device.control = _rt_wlan_dev_control; -#endif - - wlan->device.user_data = RT_NULL; - - wlan->device.type = RT_Device_Class_NetIf; - - wlan->ops = ops; - wlan->user_data = user_data; - - wlan->flags = flag; - err = rt_device_register(&wlan->device, name, RT_DEVICE_FLAG_RDWR); - - LOG_D("F:%s L:%d run", __FUNCTION__, __LINE__); - - return err; -} - -#endif diff --git a/rt-thread/components/drivers/wlan/dev_wlan.h b/rt-thread/components/drivers/wlan/dev_wlan.h deleted file mode 100644 index 20e5671..0000000 --- a/rt-thread/components/drivers/wlan/dev_wlan.h +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-08-03 tyx the first version - * 2024-12-25 Evlers add get_info api for more new sta information - * 2025-01-04 Evlers add ap_get_info api for more ap information - */ - -#ifndef __DEV_WLAN_DEVICE_H__ -#define __DEV_WLAN_DEVICE_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define RT_WLAN_DEV_VERSION 0x10001 /* 1.0.1 */ - -typedef enum -{ - RT_WLAN_NONE, - RT_WLAN_STATION, - RT_WLAN_AP, - RT_WLAN_MODE_MAX -} rt_wlan_mode_t; - -typedef enum -{ - RT_WLAN_CMD_MODE = 0x10, - RT_WLAN_CMD_SCAN, /* trigger scanning (list cells) */ - RT_WLAN_CMD_JOIN, - RT_WLAN_CMD_SOFTAP, /* start soft-AP */ - RT_WLAN_CMD_DISCONNECT, - RT_WLAN_CMD_AP_STOP, /* stop soft-AP */ - RT_WLAN_CMD_AP_DEAUTH, - RT_WLAN_CMD_SCAN_STOP, - RT_WLAN_CMD_GET_RSSI, /* get sensitivity (dBm) */ - RT_WLAN_CMD_GET_INFO, /* get information (rssi, channel, datarate.) */ - RT_WLAN_CMD_AP_GET_INFO, /* get ap information (bssid, security, channel.) */ - RT_WLAN_CMD_SET_POWERSAVE, - RT_WLAN_CMD_GET_POWERSAVE, - RT_WLAN_CMD_CFG_PROMISC, /* start/stop minitor */ - RT_WLAN_CMD_CFG_FILTER, /* start/stop frame filter */ - RT_WLAN_CMD_CFG_MGNT_FILTER, /* start/stop management frame filter */ - RT_WLAN_CMD_SET_CHANNEL, - RT_WLAN_CMD_GET_CHANNEL, - RT_WLAN_CMD_SET_COUNTRY, - RT_WLAN_CMD_GET_COUNTRY, - RT_WLAN_CMD_SET_MAC, - RT_WLAN_CMD_GET_MAC, - RT_WLAN_CMD_GET_FAST_CONNECT_INFO, - RT_WLAN_CMD_FAST_CONNECT, -} rt_wlan_cmd_t; - -typedef enum -{ - RT_WLAN_DEV_EVT_INIT_DONE = 0, - RT_WLAN_DEV_EVT_CONNECT, - RT_WLAN_DEV_EVT_CONNECT_FAIL, - RT_WLAN_DEV_EVT_DISCONNECT, - RT_WLAN_DEV_EVT_AP_START, - RT_WLAN_DEV_EVT_AP_STOP, - RT_WLAN_DEV_EVT_AP_ASSOCIATED, - RT_WLAN_DEV_EVT_AP_DISASSOCIATED, - RT_WLAN_DEV_EVT_AP_ASSOCIATE_FAILED, - RT_WLAN_DEV_EVT_SCAN_REPORT, - RT_WLAN_DEV_EVT_SCAN_DONE, - RT_WLAN_DEV_EVT_MAX, -} rt_wlan_dev_event_t; - -#define SHARED_ENABLED 0x00008000 -#define WPA_SECURITY 0x00200000 -#define WPA2_SECURITY 0x00400000 -#define WPS_ENABLED 0x10000000 -#define WEP_ENABLED 0x0001 -#define TKIP_ENABLED 0x0002 -#define AES_ENABLED 0x0004 -#define WSEC_SWFLAG 0x0008 - -#define RT_WLAN_FLAG_STA_ONLY (0x1 << 0) -#define RT_WLAN_FLAG_AP_ONLY (0x1 << 1) - -#ifndef RT_WLAN_SSID_MAX_LENGTH -#define RT_WLAN_SSID_MAX_LENGTH (32) /* SSID MAX LEN */ -#endif - -#ifndef RT_WLAN_BSSID_MAX_LENGTH -#define RT_WLAN_BSSID_MAX_LENGTH (6) /* BSSID MAX LEN (default is 6) */ -#endif - -#ifndef RT_WLAN_PASSWORD_MAX_LENGTH -#define RT_WLAN_PASSWORD_MAX_LENGTH (32) /* PASSWORD MAX LEN*/ -#endif - -#ifndef RT_WLAN_DEV_EVENT_NUM -#define RT_WLAN_DEV_EVENT_NUM (2) /* EVENT GROUP MAX NUM */ -#endif - -/** - * Enumeration of Wi-Fi security modes - */ -typedef enum -{ - SECURITY_OPEN = 0, /* Open security */ - SECURITY_WEP_PSK = WEP_ENABLED, /* WEP Security with open authentication */ - SECURITY_WEP_SHARED = (WEP_ENABLED | SHARED_ENABLED), /* WEP Security with shared authentication */ - SECURITY_WPA_TKIP_PSK = (WPA_SECURITY | TKIP_ENABLED), /* WPA Security with TKIP */ - SECURITY_WPA_AES_PSK = (WPA_SECURITY | AES_ENABLED), /* WPA Security with AES */ - SECURITY_WPA2_AES_PSK = (WPA2_SECURITY | AES_ENABLED), /* WPA2 Security with AES */ - SECURITY_WPA2_TKIP_PSK = (WPA2_SECURITY | TKIP_ENABLED), /* WPA2 Security with TKIP */ - SECURITY_WPA2_MIXED_PSK = (WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED), /* WPA2 Security with AES & TKIP */ - SECURITY_WPS_OPEN = WPS_ENABLED, /* WPS with open security */ - SECURITY_WPS_SECURE = (WPS_ENABLED | AES_ENABLED), /* WPS with AES security */ - SECURITY_UNKNOWN = -1, /* May be returned by scan function if security is unknown. - Do not pass this to the join function! */ -} rt_wlan_security_t; - -typedef enum -{ - RT_802_11_BAND_5GHZ = 0, /* Denotes 5GHz radio band */ - RT_802_11_BAND_2_4GHZ = 1, /* Denotes 2.4GHz radio band */ - RT_802_11_BAND_UNKNOWN = 0x7fffffff, /* unknown */ -} rt_802_11_band_t; - -typedef enum -{ - RT_COUNTRY_AFGHANISTAN, - RT_COUNTRY_ALBANIA, - RT_COUNTRY_ALGERIA, - RT_COUNTRY_AMERICAN_SAMOA, - RT_COUNTRY_ANGOLA, - RT_COUNTRY_ANGUILLA, - RT_COUNTRY_ANTIGUA_AND_BARBUDA, - RT_COUNTRY_ARGENTINA, - RT_COUNTRY_ARMENIA, - RT_COUNTRY_ARUBA, - RT_COUNTRY_AUSTRALIA, - RT_COUNTRY_AUSTRIA, - RT_COUNTRY_AZERBAIJAN, - RT_COUNTRY_BAHAMAS, - RT_COUNTRY_BAHRAIN, - RT_COUNTRY_BAKER_ISLAND, - RT_COUNTRY_BANGLADESH, - RT_COUNTRY_BARBADOS, - RT_COUNTRY_BELARUS, - RT_COUNTRY_BELGIUM, - RT_COUNTRY_BELIZE, - RT_COUNTRY_BENIN, - RT_COUNTRY_BERMUDA, - RT_COUNTRY_BHUTAN, - RT_COUNTRY_BOLIVIA, - RT_COUNTRY_BOSNIA_AND_HERZEGOVINA, - RT_COUNTRY_BOTSWANA, - RT_COUNTRY_BRAZIL, - RT_COUNTRY_BRITISH_INDIAN_OCEAN_TERRITORY, - RT_COUNTRY_BRUNEI_DARUSSALAM, - RT_COUNTRY_BULGARIA, - RT_COUNTRY_BURKINA_FASO, - RT_COUNTRY_BURUNDI, - RT_COUNTRY_CAMBODIA, - RT_COUNTRY_CAMEROON, - RT_COUNTRY_CANADA, - RT_COUNTRY_CAPE_VERDE, - RT_COUNTRY_CAYMAN_ISLANDS, - RT_COUNTRY_CENTRAL_AFRICAN_REPUBLIC, - RT_COUNTRY_CHAD, - RT_COUNTRY_CHILE, - RT_COUNTRY_CHINA, - RT_COUNTRY_CHRISTMAS_ISLAND, - RT_COUNTRY_COLOMBIA, - RT_COUNTRY_COMOROS, - RT_COUNTRY_CONGO, - RT_COUNTRY_CONGO_THE_DEMOCRATIC_REPUBLIC_OF_THE, - RT_COUNTRY_COSTA_RICA, - RT_COUNTRY_COTE_DIVOIRE, - RT_COUNTRY_CROATIA, - RT_COUNTRY_CUBA, - RT_COUNTRY_CYPRUS, - RT_COUNTRY_CZECH_REPUBLIC, - RT_COUNTRY_DENMARK, - RT_COUNTRY_DJIBOUTI, - RT_COUNTRY_DOMINICA, - RT_COUNTRY_DOMINICAN_REPUBLIC, - RT_COUNTRY_DOWN_UNDER, - RT_COUNTRY_ECUADOR, - RT_COUNTRY_EGYPT, - RT_COUNTRY_EL_SALVADOR, - RT_COUNTRY_EQUATORIAL_GUINEA, - RT_COUNTRY_ERITREA, - RT_COUNTRY_ESTONIA, - RT_COUNTRY_ETHIOPIA, - RT_COUNTRY_FALKLAND_ISLANDS_MALVINAS, - RT_COUNTRY_FAROE_ISLANDS, - RT_COUNTRY_FIJI, - RT_COUNTRY_FINLAND, - RT_COUNTRY_FRANCE, - RT_COUNTRY_FRENCH_GUINA, - RT_COUNTRY_FRENCH_POLYNESIA, - RT_COUNTRY_FRENCH_SOUTHERN_TERRITORIES, - RT_COUNTRY_GABON, - RT_COUNTRY_GAMBIA, - RT_COUNTRY_GEORGIA, - RT_COUNTRY_GERMANY, - RT_COUNTRY_GHANA, - RT_COUNTRY_GIBRALTAR, - RT_COUNTRY_GREECE, - RT_COUNTRY_GRENADA, - RT_COUNTRY_GUADELOUPE, - RT_COUNTRY_GUAM, - RT_COUNTRY_GUATEMALA, - RT_COUNTRY_GUERNSEY, - RT_COUNTRY_GUINEA, - RT_COUNTRY_GUINEA_BISSAU, - RT_COUNTRY_GUYANA, - RT_COUNTRY_HAITI, - RT_COUNTRY_HOLY_SEE_VATICAN_CITY_STATE, - RT_COUNTRY_HONDURAS, - RT_COUNTRY_HONG_KONG, - RT_COUNTRY_HUNGARY, - RT_COUNTRY_ICELAND, - RT_COUNTRY_INDIA, - RT_COUNTRY_INDONESIA, - RT_COUNTRY_IRAN_ISLAMIC_REPUBLIC_OF, - RT_COUNTRY_IRAQ, - RT_COUNTRY_IRELAND, - RT_COUNTRY_ISRAEL, - RT_COUNTRY_ITALY, - RT_COUNTRY_JAMAICA, - RT_COUNTRY_JAPAN, - RT_COUNTRY_JERSEY, - RT_COUNTRY_JORDAN, - RT_COUNTRY_KAZAKHSTAN, - RT_COUNTRY_KENYA, - RT_COUNTRY_KIRIBATI, - RT_COUNTRY_KOREA_REPUBLIC_OF, - RT_COUNTRY_KOSOVO, - RT_COUNTRY_KUWAIT, - RT_COUNTRY_KYRGYZSTAN, - RT_COUNTRY_LAO_PEOPLES_DEMOCRATIC_REPUBIC, - RT_COUNTRY_LATVIA, - RT_COUNTRY_LEBANON, - RT_COUNTRY_LESOTHO, - RT_COUNTRY_LIBERIA, - RT_COUNTRY_LIBYAN_ARAB_JAMAHIRIYA, - RT_COUNTRY_LIECHTENSTEIN, - RT_COUNTRY_LITHUANIA, - RT_COUNTRY_LUXEMBOURG, - RT_COUNTRY_MACAO, - RT_COUNTRY_MACEDONIA_FORMER_YUGOSLAV_REPUBLIC_OF, - RT_COUNTRY_MADAGASCAR, - RT_COUNTRY_MALAWI, - RT_COUNTRY_MALAYSIA, - RT_COUNTRY_MALDIVES, - RT_COUNTRY_MALI, - RT_COUNTRY_MALTA, - RT_COUNTRY_MAN_ISLE_OF, - RT_COUNTRY_MARTINIQUE, - RT_COUNTRY_MAURITANIA, - RT_COUNTRY_MAURITIUS, - RT_COUNTRY_MAYOTTE, - RT_COUNTRY_MEXICO, - RT_COUNTRY_MICRONESIA_FEDERATED_STATES_OF, - RT_COUNTRY_MOLDOVA_REPUBLIC_OF, - RT_COUNTRY_MONACO, - RT_COUNTRY_MONGOLIA, - RT_COUNTRY_MONTENEGRO, - RT_COUNTRY_MONTSERRAT, - RT_COUNTRY_MOROCCO, - RT_COUNTRY_MOZAMBIQUE, - RT_COUNTRY_MYANMAR, - RT_COUNTRY_NAMIBIA, - RT_COUNTRY_NAURU, - RT_COUNTRY_NEPAL, - RT_COUNTRY_NETHERLANDS, - RT_COUNTRY_NETHERLANDS_ANTILLES, - RT_COUNTRY_NEW_CALEDONIA, - RT_COUNTRY_NEW_ZEALAND, - RT_COUNTRY_NICARAGUA, - RT_COUNTRY_NIGER, - RT_COUNTRY_NIGERIA, - RT_COUNTRY_NORFOLK_ISLAND, - RT_COUNTRY_NORTHERN_MARIANA_ISLANDS, - RT_COUNTRY_NORWAY, - RT_COUNTRY_OMAN, - RT_COUNTRY_PAKISTAN, - RT_COUNTRY_PALAU, - RT_COUNTRY_PANAMA, - RT_COUNTRY_PAPUA_NEW_GUINEA, - RT_COUNTRY_PARAGUAY, - RT_COUNTRY_PERU, - RT_COUNTRY_PHILIPPINES, - RT_COUNTRY_POLAND, - RT_COUNTRY_PORTUGAL, - RT_COUNTRY_PUETO_RICO, - RT_COUNTRY_QATAR, - RT_COUNTRY_REUNION, - RT_COUNTRY_ROMANIA, - RT_COUNTRY_RUSSIAN_FEDERATION, - RT_COUNTRY_RWANDA, - RT_COUNTRY_SAINT_KITTS_AND_NEVIS, - RT_COUNTRY_SAINT_LUCIA, - RT_COUNTRY_SAINT_PIERRE_AND_MIQUELON, - RT_COUNTRY_SAINT_VINCENT_AND_THE_GRENADINES, - RT_COUNTRY_SAMOA, - RT_COUNTRY_SANIT_MARTIN_SINT_MARTEEN, - RT_COUNTRY_SAO_TOME_AND_PRINCIPE, - RT_COUNTRY_SAUDI_ARABIA, - RT_COUNTRY_SENEGAL, - RT_COUNTRY_SERBIA, - RT_COUNTRY_SEYCHELLES, - RT_COUNTRY_SIERRA_LEONE, - RT_COUNTRY_SINGAPORE, - RT_COUNTRY_SLOVAKIA, - RT_COUNTRY_SLOVENIA, - RT_COUNTRY_SOLOMON_ISLANDS, - RT_COUNTRY_SOMALIA, - RT_COUNTRY_SOUTH_AFRICA, - RT_COUNTRY_SPAIN, - RT_COUNTRY_SRI_LANKA, - RT_COUNTRY_SURINAME, - RT_COUNTRY_SWAZILAND, - RT_COUNTRY_SWEDEN, - RT_COUNTRY_SWITZERLAND, - RT_COUNTRY_SYRIAN_ARAB_REPUBLIC, - RT_COUNTRY_TAIWAN_PROVINCE_OF_CHINA, - RT_COUNTRY_TAJIKISTAN, - RT_COUNTRY_TANZANIA_UNITED_REPUBLIC_OF, - RT_COUNTRY_THAILAND, - RT_COUNTRY_TOGO, - RT_COUNTRY_TONGA, - RT_COUNTRY_TRINIDAD_AND_TOBAGO, - RT_COUNTRY_TUNISIA, - RT_COUNTRY_TURKEY, - RT_COUNTRY_TURKMENISTAN, - RT_COUNTRY_TURKS_AND_CAICOS_ISLANDS, - RT_COUNTRY_TUVALU, - RT_COUNTRY_UGANDA, - RT_COUNTRY_UKRAINE, - RT_COUNTRY_UNITED_ARAB_EMIRATES, - RT_COUNTRY_UNITED_KINGDOM, - RT_COUNTRY_UNITED_STATES, - RT_COUNTRY_UNITED_STATES_REV4, - RT_COUNTRY_UNITED_STATES_NO_DFS, - RT_COUNTRY_UNITED_STATES_MINOR_OUTLYING_ISLANDS, - RT_COUNTRY_URUGUAY, - RT_COUNTRY_UZBEKISTAN, - RT_COUNTRY_VANUATU, - RT_COUNTRY_VENEZUELA, - RT_COUNTRY_VIET_NAM, - RT_COUNTRY_VIRGIN_ISLANDS_BRITISH, - RT_COUNTRY_VIRGIN_ISLANDS_US, - RT_COUNTRY_WALLIS_AND_FUTUNA, - RT_COUNTRY_WEST_BANK, - RT_COUNTRY_WESTERN_SAHARA, - RT_COUNTRY_WORLD_WIDE_XX, - RT_COUNTRY_YEMEN, - RT_COUNTRY_ZAMBIA, - RT_COUNTRY_ZIMBABWE, - RT_COUNTRY_UNKNOWN -} rt_country_code_t; - -struct rt_wlan_device; -struct rt_wlan_buff; - -typedef void (*rt_wlan_dev_event_handler)(struct rt_wlan_device *device, rt_wlan_dev_event_t event, struct rt_wlan_buff *buff, void *parameter); - -typedef void (*rt_wlan_pormisc_callback_t)(struct rt_wlan_device *device, void *data, int len); - -typedef void (*rt_wlan_mgnt_filter_callback_t)(struct rt_wlan_device *device, void *data, int len); - -struct rt_wlan_ssid -{ - rt_uint8_t len; - rt_uint8_t val[RT_WLAN_SSID_MAX_LENGTH + 1]; -}; -typedef struct rt_wlan_ssid rt_wlan_ssid_t; - -struct rt_wlan_key -{ - rt_uint8_t len; - rt_uint8_t val[RT_WLAN_PASSWORD_MAX_LENGTH + 1]; -}; -typedef struct rt_wlan_key rt_wlan_key_t; - -#define INVALID_INFO(_info) do { \ - rt_memset((_info), 0, sizeof(struct rt_wlan_info)); \ - (_info)->band = RT_802_11_BAND_UNKNOWN; \ - (_info)->security = SECURITY_UNKNOWN; \ - (_info)->channel = -1; \ - } while(0) - -#define SSID_SET(_info, _ssid) do { \ - rt_strncpy((char *)(_info)->ssid.val, (_ssid), RT_WLAN_SSID_MAX_LENGTH); \ - (_info)->ssid.len = rt_strlen((char *)(_info)->ssid.val); \ - } while(0) - -struct rt_wlan_info -{ - /* security type */ - rt_wlan_security_t security; - /* 2.4G/5G */ - rt_802_11_band_t band; - /* maximal data rate */ - rt_uint32_t datarate; - /* radio channel */ - rt_int16_t channel; - /* signal strength */ - rt_int16_t rssi; - /* ssid */ - rt_wlan_ssid_t ssid; - /* hwaddr */ - rt_uint8_t bssid[RT_WLAN_BSSID_MAX_LENGTH]; - rt_uint8_t hidden; -}; - -struct rt_wlan_buff -{ - void *data; - rt_int32_t len; -}; - -struct rt_filter_pattern -{ - rt_uint16_t offset; /* Offset in bytes to start filtering (referenced to the start of the ethernet packet) */ - rt_uint16_t mask_size; /* Size of the mask in bytes */ - rt_uint8_t *mask; /* Pattern mask bytes to be ANDed with the pattern eg. "\xff00" (must be in network byte order) */ - rt_uint8_t *pattern; /* Pattern bytes used to filter eg. "\x0800" (must be in network byte order) */ -}; - -typedef enum -{ - RT_POSITIVE_MATCHING = 0, /* Receive the data matching with this pattern and discard the other data */ - RT_NEGATIVE_MATCHING = 1 /* Discard the data matching with this pattern and receive the other data */ -} rt_filter_rule_t; - -struct rt_wlan_filter -{ - struct rt_filter_pattern patt; - rt_filter_rule_t rule; - rt_uint8_t enable; -}; - -struct rt_wlan_dev_event_desc -{ - rt_wlan_dev_event_handler handler; - void *parameter; -}; - -struct rt_wlan_device -{ - struct rt_device device; - rt_wlan_mode_t mode; - struct rt_mutex lock; - struct rt_wlan_dev_event_desc handler_table[RT_WLAN_DEV_EVT_MAX][RT_WLAN_DEV_EVENT_NUM]; - rt_wlan_pormisc_callback_t pormisc_callback; - rt_wlan_mgnt_filter_callback_t mgnt_filter_callback; - const struct rt_wlan_dev_ops *ops; - rt_uint32_t flags; - struct netdev *netdev; - void *prot; - void *user_data; -}; - -struct rt_sta_info -{ - rt_wlan_ssid_t ssid; - rt_wlan_key_t key; - rt_uint8_t bssid[6]; - rt_uint16_t channel; - rt_wlan_security_t security; -}; - -struct rt_ap_info -{ - rt_wlan_ssid_t ssid; - rt_wlan_key_t key; - rt_bool_t hidden; - rt_uint16_t channel; - rt_wlan_security_t security; -}; - -struct rt_scan_info -{ - rt_wlan_ssid_t ssid; - rt_uint8_t bssid[6]; - rt_int16_t channel_min; - rt_int16_t channel_max; - rt_bool_t passive; -}; - -struct rt_wlan_dev_ops -{ - rt_err_t (*wlan_init)(struct rt_wlan_device *wlan); - rt_err_t (*wlan_mode)(struct rt_wlan_device *wlan, rt_wlan_mode_t mode); - rt_err_t (*wlan_scan)(struct rt_wlan_device *wlan, struct rt_scan_info *scan_info); - rt_err_t (*wlan_join)(struct rt_wlan_device *wlan, struct rt_sta_info *sta_info); - rt_err_t (*wlan_softap)(struct rt_wlan_device *wlan, struct rt_ap_info *ap_info); - rt_err_t (*wlan_disconnect)(struct rt_wlan_device *wlan); - rt_err_t (*wlan_ap_stop)(struct rt_wlan_device *wlan); - rt_err_t (*wlan_ap_deauth)(struct rt_wlan_device *wlan, rt_uint8_t mac[]); - rt_err_t (*wlan_scan_stop)(struct rt_wlan_device *wlan); - int (*wlan_get_rssi)(struct rt_wlan_device *wlan); - int (*wlan_get_info)(struct rt_wlan_device *wlan, struct rt_wlan_info *info); - int (*wlan_ap_get_info)(struct rt_wlan_device *wlan, struct rt_wlan_info *info); - rt_err_t (*wlan_set_powersave)(struct rt_wlan_device *wlan, int level); - int (*wlan_get_powersave)(struct rt_wlan_device *wlan); - rt_err_t (*wlan_cfg_promisc)(struct rt_wlan_device *wlan, rt_bool_t start); - rt_err_t (*wlan_cfg_filter)(struct rt_wlan_device *wlan, struct rt_wlan_filter *filter); - rt_err_t (*wlan_cfg_mgnt_filter)(struct rt_wlan_device *wlan, rt_bool_t start); - rt_err_t (*wlan_set_channel)(struct rt_wlan_device *wlan, int channel); - int (*wlan_get_channel)(struct rt_wlan_device *wlan); - rt_err_t (*wlan_set_country)(struct rt_wlan_device *wlan, rt_country_code_t country_code); - rt_country_code_t (*wlan_get_country)(struct rt_wlan_device *wlan); - rt_err_t (*wlan_set_mac)(struct rt_wlan_device *wlan, rt_uint8_t mac[]); - rt_err_t (*wlan_get_mac)(struct rt_wlan_device *wlan, rt_uint8_t mac[]); - int (*wlan_recv)(struct rt_wlan_device *wlan, void *buff, int len); - int (*wlan_send)(struct rt_wlan_device *wlan, void *buff, int len); - int (*wlan_send_raw_frame)(struct rt_wlan_device *wlan, void *buff, int len); - int (*wlan_get_fast_info)(void *data); - rt_err_t (*wlan_fast_connect)(void *data,rt_int32_t len); -}; - -/* - * wlan device init - */ -rt_err_t rt_wlan_dev_init(struct rt_wlan_device *device, rt_wlan_mode_t mode); - -/* - * wlan device station interface - */ -rt_err_t rt_wlan_dev_connect(struct rt_wlan_device *device, struct rt_wlan_info *info, const char *password, int password_len); -rt_err_t rt_wlan_dev_fast_connect(struct rt_wlan_device *device, struct rt_wlan_info *info, const char *password, int password_len); -rt_err_t rt_wlan_dev_disconnect(struct rt_wlan_device *device); -int rt_wlan_dev_get_rssi(struct rt_wlan_device *device); -rt_err_t rt_wlan_dev_get_info(struct rt_wlan_device *device, struct rt_wlan_info *info); - -/* - * wlan device ap interface - */ -rt_err_t rt_wlan_dev_ap_start(struct rt_wlan_device *device, struct rt_wlan_info *info, const char *password, int password_len); -rt_err_t rt_wlan_dev_ap_stop(struct rt_wlan_device *device); -rt_err_t rt_wlan_dev_ap_deauth(struct rt_wlan_device *device, rt_uint8_t mac[6]); -rt_err_t rt_wlan_dev_ap_get_info(struct rt_wlan_device *device, struct rt_wlan_info *info); - -/* - * wlan device scan interface - */ -rt_err_t rt_wlan_dev_scan(struct rt_wlan_device *device, struct rt_wlan_info *info); -rt_err_t rt_wlan_dev_scan_stop(struct rt_wlan_device *device); - -/* - * wlan device mac interface - */ -rt_err_t rt_wlan_dev_get_mac(struct rt_wlan_device *device, rt_uint8_t mac[6]); -rt_err_t rt_wlan_dev_set_mac(struct rt_wlan_device *device, rt_uint8_t mac[6]); - -/* - * wlan device powersave interface - */ -rt_err_t rt_wlan_dev_set_powersave(struct rt_wlan_device *device, int level); -int rt_wlan_dev_get_powersave(struct rt_wlan_device *device); - -/* - * wlan device event interface - */ -rt_err_t rt_wlan_dev_register_event_handler(struct rt_wlan_device *device, rt_wlan_dev_event_t event, rt_wlan_dev_event_handler handler, void *parameter); -rt_err_t rt_wlan_dev_unregister_event_handler(struct rt_wlan_device *device, rt_wlan_dev_event_t event, rt_wlan_dev_event_handler handler); -void rt_wlan_dev_indicate_event_handle(struct rt_wlan_device *device, rt_wlan_dev_event_t event, struct rt_wlan_buff *buff); - -/* - * wlan device promisc interface - */ -rt_err_t rt_wlan_dev_enter_promisc(struct rt_wlan_device *device); -rt_err_t rt_wlan_dev_exit_promisc(struct rt_wlan_device *device); -rt_err_t rt_wlan_dev_set_promisc_callback(struct rt_wlan_device *device, rt_wlan_pormisc_callback_t callback); -void rt_wlan_dev_promisc_handler(struct rt_wlan_device *device, void *data, int len); - -/* - * wlan device filter interface - */ -rt_err_t rt_wlan_dev_cfg_filter(struct rt_wlan_device *device, struct rt_wlan_filter *filter); - -/* - * wlan device channel interface - */ -rt_err_t rt_wlan_dev_set_channel(struct rt_wlan_device *device, int channel); -int rt_wlan_dev_get_channel(struct rt_wlan_device *device); - -/* - * wlan device country interface - */ -rt_err_t rt_wlan_dev_set_country(struct rt_wlan_device *device, rt_country_code_t country_code); -rt_country_code_t rt_wlan_dev_get_country(struct rt_wlan_device *device); - -/* - * wlan device datat transfer interface - */ -rt_err_t rt_wlan_dev_report_data(struct rt_wlan_device *device, void *buff, int len); -// void rt_wlan_dev_data_ready(struct rt_wlan_device *device, int len); - -/* - * wlan device register interface - */ -rt_err_t rt_wlan_dev_register(struct rt_wlan_device *wlan, const char *name, - const struct rt_wlan_dev_ops *ops, rt_uint32_t flag, void *user_data); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/components/drivers/wlan/dev_wlan_cfg.c b/rt-thread/components/drivers/wlan/dev_wlan_cfg.c deleted file mode 100644 index e62ed9d..0000000 --- a/rt-thread/components/drivers/wlan/dev_wlan_cfg.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-08-06 tyx the first version - */ - -#include -#include - -#define DBG_TAG "WLAN.cfg" -#ifdef RT_WLAN_CFG_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif /* RT_WLAN_CFG_DEBUG */ -#include - -#ifdef RT_WLAN_CFG_ENABLE - -#define WLAN_CFG_LOCK() (rt_mutex_take(&cfg_mutex, RT_WAITING_FOREVER)) -#define WLAN_CFG_UNLOCK() (rt_mutex_release(&cfg_mutex)) - -#if RT_WLAN_CFG_INFO_MAX < 1 -#error "The minimum configuration is 1" -#endif - -struct cfg_save_info_head -{ - rt_uint32_t magic; - rt_uint32_t len; - rt_uint32_t num; - rt_uint32_t crc; -}; - -struct rt_wlan_cfg_des -{ - rt_uint32_t num; - struct rt_wlan_cfg_info *cfg_info; -}; - -static struct rt_wlan_cfg_des *cfg_cache; -static const struct rt_wlan_cfg_ops *cfg_ops; -static struct rt_mutex cfg_mutex; - -/* - * CRC16_CCITT - */ -static rt_uint16_t rt_wlan_cal_crc(rt_uint8_t *buff, int len) -{ - rt_uint16_t wCRCin = 0x0000; - rt_uint16_t wCPoly = 0x1021; - rt_uint8_t wChar = 0; - - while (len--) - { - int i; - - wChar = *(buff++); - wCRCin ^= (wChar << 8); - - for (i = 0; i < 8; i++) - { - if (wCRCin & 0x8000) - wCRCin = (wCRCin << 1) ^ wCPoly; - else - wCRCin = wCRCin << 1; - } - } - return wCRCin; -} - -void rt_wlan_cfg_init(void) -{ - /* init cache memory */ - if (cfg_cache == RT_NULL) - { - cfg_cache = rt_malloc(sizeof(struct rt_wlan_cfg_des)); - if (cfg_cache != RT_NULL) - { - rt_memset(cfg_cache, 0, sizeof(struct rt_wlan_cfg_des)); - } - /* init mutex lock */ - rt_mutex_init(&cfg_mutex, "wlan_cfg", RT_IPC_FLAG_PRIO); - } -} - -void rt_wlan_cfg_set_ops(const struct rt_wlan_cfg_ops *ops) -{ - rt_wlan_cfg_init(); - - WLAN_CFG_LOCK(); - /* save ops pointer */ - cfg_ops = ops; - WLAN_CFG_UNLOCK(); -} - -/* save config data */ -rt_err_t rt_wlan_cfg_cache_save(void) -{ - rt_err_t err = RT_EOK; - struct cfg_save_info_head *info_pkg; - int len = 0; - - if ((cfg_ops == RT_NULL) || (cfg_ops->write_cfg == RT_NULL)) - return RT_EOK; - - WLAN_CFG_LOCK(); - len = sizeof(struct cfg_save_info_head) + sizeof(struct rt_wlan_cfg_info) * cfg_cache->num; - info_pkg = rt_malloc(len); - if (info_pkg == RT_NULL) - { - WLAN_CFG_UNLOCK(); - return -RT_ENOMEM; - } - info_pkg->magic = RT_WLAN_CFG_MAGIC; - info_pkg->len = len; - info_pkg->num = cfg_cache->num; - /* CRC */ - info_pkg->crc = rt_wlan_cal_crc((rt_uint8_t *)cfg_cache->cfg_info, sizeof(struct rt_wlan_cfg_info) * cfg_cache->num); - rt_memcpy(((rt_uint8_t *)info_pkg) + sizeof(struct cfg_save_info_head), - cfg_cache->cfg_info, sizeof(struct rt_wlan_cfg_info) * cfg_cache->num); - if (cfg_ops->write_cfg(info_pkg, len) != len) - err = -RT_ERROR; - rt_free(info_pkg); - WLAN_CFG_UNLOCK(); - return err; -} - -rt_err_t rt_wlan_cfg_cache_refresh(void) -{ - int len = 0, i, j; - struct cfg_save_info_head *head; - void *data; - struct rt_wlan_cfg_info *t_info, *cfg_info; - rt_uint32_t crc; - rt_bool_t equal_flag; - - /* cache is full! exit */ - if (cfg_cache == RT_NULL || cfg_cache->num >= RT_WLAN_CFG_INFO_MAX) - return -RT_ERROR; - - /* check callback */ - if ((cfg_ops == RT_NULL) || - (cfg_ops->get_len == RT_NULL) || - (cfg_ops->read_cfg == RT_NULL)) - return -RT_ERROR; - - WLAN_CFG_LOCK(); - /* get data len */ - if ((len = cfg_ops->get_len()) <= 0) - { - WLAN_CFG_UNLOCK(); - return -RT_ERROR; - } - - head = rt_malloc(len); - if (head == RT_NULL) - { - WLAN_CFG_UNLOCK(); - return -RT_ERROR; - } - /* get data */ - if (cfg_ops->read_cfg(head, len) != len) - { - rt_free(head); - WLAN_CFG_UNLOCK(); - return -RT_ERROR; - } - /* get config */ - data = ((rt_uint8_t *)head) + sizeof(struct cfg_save_info_head); - crc = rt_wlan_cal_crc((rt_uint8_t *)data, len - sizeof(struct cfg_save_info_head)); - LOG_D("head->magic:0x%08x RT_WLAN_CFG_MAGIC:0x%08x", head->magic, RT_WLAN_CFG_MAGIC); - LOG_D("head->len:%d len:%d", head->len, len); - LOG_D("head->num:%d num:%d", head->num, (len - sizeof(struct cfg_save_info_head)) / sizeof(struct rt_wlan_cfg_info)); - LOG_D("hred->crc:0x%04x crc:0x%04x", head->crc, crc); - /* check */ - if ((head->magic != RT_WLAN_CFG_MAGIC) || - (head->len != len) || - (head->num != (len - sizeof(struct cfg_save_info_head)) / sizeof(struct rt_wlan_cfg_info)) || - (head->crc != crc)) - { - rt_free(head); - WLAN_CFG_UNLOCK(); - return -RT_ERROR; - } - - /* remove duplicate config */ - cfg_info = (struct rt_wlan_cfg_info *)data; - for (i = 0; i < head->num; i++) - { - equal_flag = RT_FALSE; - for (j = 0; j < cfg_cache->num; j++) - { - if ((cfg_cache->cfg_info[j].info.ssid.len == cfg_info[i].info.ssid.len) && - (rt_memcmp(&cfg_cache->cfg_info[j].info.ssid.val[0], &cfg_info[i].info.ssid.val[0], - cfg_cache->cfg_info[j].info.ssid.len) == 0) && - (rt_memcmp(&cfg_cache->cfg_info[j].info.bssid[0], &cfg_info[i].info.bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0)) - { - equal_flag = RT_TRUE; - break; - } - } - - if (cfg_cache->num >= RT_WLAN_CFG_INFO_MAX) - { - break; - } - - if (equal_flag == RT_FALSE) - { - t_info = rt_realloc(cfg_cache->cfg_info, sizeof(struct rt_wlan_cfg_info) * (cfg_cache->num + 1)); - if (t_info == RT_NULL) - { - rt_free(head); - WLAN_CFG_UNLOCK(); - return -RT_ERROR; - } - cfg_cache->cfg_info = t_info; - cfg_cache->cfg_info[cfg_cache->num] = cfg_info[i]; - cfg_cache->num ++; - } - } - - rt_free(head); - WLAN_CFG_UNLOCK(); - return RT_EOK; -} - -int rt_wlan_cfg_get_num(void) -{ - rt_wlan_cfg_init(); - - return cfg_cache->num; -} - -int rt_wlan_cfg_read(struct rt_wlan_cfg_info *cfg_info, int num) -{ - rt_wlan_cfg_init(); - - if ((cfg_info == RT_NULL) || (num <= 0)) - return 0; - /* copy data */ - WLAN_CFG_LOCK(); - num = cfg_cache->num > num ? num : cfg_cache->num; - rt_memcpy(&cfg_cache->cfg_info[0], cfg_info, sizeof(struct rt_wlan_cfg_info) * num); - WLAN_CFG_UNLOCK(); - - return num; -} - -rt_err_t rt_wlan_cfg_save(struct rt_wlan_cfg_info *cfg_info) -{ - rt_err_t err = RT_EOK; - struct rt_wlan_cfg_info *t_info; - int idx = -1, i = 0; - - rt_wlan_cfg_init(); - - /* parameter check */ - if ((cfg_info == RT_NULL) || (cfg_info->info.ssid.len == 0)) - { - return -RT_EINVAL; - } - /* if (iteam == cache) exit */ - WLAN_CFG_LOCK(); - for (i = 0; i < cfg_cache->num; i++) - { - if ((cfg_cache->cfg_info[i].info.ssid.len == cfg_info->info.ssid.len) && - (rt_memcmp(&cfg_cache->cfg_info[i].info.ssid.val[0], &cfg_info->info.ssid.val[0], - cfg_cache->cfg_info[i].info.ssid.len) == 0) && - (rt_memcmp(&cfg_cache->cfg_info[i].info.bssid[0], &cfg_info->info.bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0)) - { - idx = i; - break; - } - } - - if ((idx == 0) && (cfg_cache->cfg_info[i].key.len == cfg_info->key.len) && - (rt_memcmp(&cfg_cache->cfg_info[i].key.val[0], &cfg_info->key.val[0], cfg_info->key.len) == 0)) - { - WLAN_CFG_UNLOCK(); - return RT_EOK; - } - - /* not find iteam with cache, Add iteam to the head */ - if ((idx == -1) && (cfg_cache->num < RT_WLAN_CFG_INFO_MAX)) - { - t_info = rt_realloc(cfg_cache->cfg_info, sizeof(struct rt_wlan_cfg_info) * (cfg_cache->num + 1)); - if (t_info == RT_NULL) - { - WLAN_CFG_UNLOCK(); - return -RT_ENOMEM; - } - cfg_cache->cfg_info = t_info; - cfg_cache->num ++; - } - - /* move cache info */ - i = (i >= RT_WLAN_CFG_INFO_MAX ? RT_WLAN_CFG_INFO_MAX - 1 : i); - for (; i; i--) - { - cfg_cache->cfg_info[i] = cfg_cache->cfg_info[i - 1]; - } - /* add iteam to head */ - cfg_cache->cfg_info[i] = *cfg_info; - WLAN_CFG_UNLOCK(); - - /* save info to flash */ - err = rt_wlan_cfg_cache_save(); - - return err; -} - -int rt_wlan_cfg_read_index(struct rt_wlan_cfg_info *cfg_info, int index) -{ - rt_wlan_cfg_init(); - - if ((cfg_info == RT_NULL) || (index < 0)) - return 0; - - WLAN_CFG_LOCK(); - if (index >= cfg_cache->num) - { - WLAN_CFG_UNLOCK(); - return 0; - } - /* copy data */ - *cfg_info = cfg_cache->cfg_info[index]; - WLAN_CFG_UNLOCK(); - return 1; -} - -int rt_wlan_cfg_delete_index(int index) -{ - struct rt_wlan_cfg_info *cfg_info; - int i; - - rt_wlan_cfg_init(); - - if (index < 0) - return -1; - - WLAN_CFG_LOCK(); - if (index >= cfg_cache->num) - { - WLAN_CFG_UNLOCK(); - return -1; - } - - /* malloc new mem */ - cfg_info = rt_malloc(sizeof(struct rt_wlan_cfg_info) * (cfg_cache->num - 1)); - if (cfg_info == RT_NULL) - { - WLAN_CFG_UNLOCK(); - return -1; - } - /* copy data to new mem */ - for (i = 0; i < cfg_cache->num; i++) - { - if (i < index) - { - cfg_info[i] = cfg_cache->cfg_info[i]; - } - else if (i > index) - { - cfg_info[i - 1] = cfg_cache->cfg_info[i]; - } - } - rt_free(cfg_cache->cfg_info); - cfg_cache->cfg_info = cfg_info; - cfg_cache->num --; - WLAN_CFG_UNLOCK(); - - return 0; -} - -void rt_wlan_cfg_delete_all(void) -{ - rt_wlan_cfg_init(); - - /* delete all iteam */ - WLAN_CFG_LOCK(); - cfg_cache->num = 0; - rt_free(cfg_cache->cfg_info); - cfg_cache->cfg_info = RT_NULL; - WLAN_CFG_UNLOCK(); -} - -void rt_wlan_cfg_dump(void) -{ - int index = 0; - struct rt_wlan_info *info; - struct rt_wlan_key *key; - char *security; - - rt_wlan_cfg_init(); - - rt_kprintf(" SSID PASSWORD MAC security chn\n"); - rt_kprintf("------------------------------- ------------------------------- ----------------- -------------- ---\n"); - for (index = 0; index < cfg_cache->num; index ++) - { - info = &cfg_cache->cfg_info[index].info; - key = &cfg_cache->cfg_info[index].key; - - if (info->ssid.len) - rt_kprintf("%-32.32s", &info->ssid.val[0]); - else - rt_kprintf("%-32.32s", " "); - - if (key->len) - rt_kprintf("%-32.32s", &key->val[0]); - else - rt_kprintf("%-32.32s", " "); - - rt_kprintf("%02x:%02x:%02x:%02x:%02x:%02x ", - info->bssid[0], - info->bssid[1], - info->bssid[2], - info->bssid[3], - info->bssid[4], - info->bssid[5] - ); - switch (info->security) - { - case SECURITY_OPEN: - security = "OPEN"; - break; - case SECURITY_WEP_PSK: - security = "WEP_PSK"; - break; - case SECURITY_WEP_SHARED: - security = "WEP_SHARED"; - break; - case SECURITY_WPA_TKIP_PSK: - security = "WPA_TKIP_PSK"; - break; - case SECURITY_WPA_AES_PSK: - security = "WPA_AES_PSK"; - break; - case SECURITY_WPA2_AES_PSK: - security = "WPA2_AES_PSK"; - break; - case SECURITY_WPA2_TKIP_PSK: - security = "WPA2_TKIP_PSK"; - break; - case SECURITY_WPA2_MIXED_PSK: - security = "WPA2_MIXED_PSK"; - break; - case SECURITY_WPS_OPEN: - security = "WPS_OPEN"; - break; - case SECURITY_WPS_SECURE: - security = "WPS_SECURE"; - break; - default: - security = "UNKNOWN"; - break; - } - rt_kprintf("%-14.14s ", security); - rt_kprintf("%3d \n", info->channel); - } -} - -#endif diff --git a/rt-thread/components/drivers/wlan/dev_wlan_cfg.h b/rt-thread/components/drivers/wlan/dev_wlan_cfg.h deleted file mode 100644 index 25e44de..0000000 --- a/rt-thread/components/drivers/wlan/dev_wlan_cfg.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-08-06 tyx the first version - */ - -#ifndef __DEV_WLAN_CFG_H__ -#define __DEV_WLAN_CFG_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef RT_WLAN_CFG_INFO_MAX -#define RT_WLAN_CFG_INFO_MAX (3) /* min is 1 */ -#endif - -#define RT_WLAN_CFG_MAGIC (0x426f6d62) - -struct rt_wlan_cfg_info -{ - struct rt_wlan_info info; - struct rt_wlan_key key; -}; - -typedef int (*rt_wlan_wr)(void *buff, int len); - -struct rt_wlan_cfg_ops -{ - int (*read_cfg)(void *buff, int len); - int (*get_len)(void); - int (*write_cfg)(void *buff, int len); -}; - -void rt_wlan_cfg_init(void); - -void rt_wlan_cfg_set_ops(const struct rt_wlan_cfg_ops *ops); - -int rt_wlan_cfg_get_num(void); - -int rt_wlan_cfg_read(struct rt_wlan_cfg_info *cfg_info, int num); - -int rt_wlan_cfg_read_index(struct rt_wlan_cfg_info *cfg_info, int index); - -rt_err_t rt_wlan_cfg_save(struct rt_wlan_cfg_info *cfg_info); - -rt_err_t rt_wlan_cfg_cache_refresh(void); - -rt_err_t rt_wlan_cfg_cache_save(void); - -int rt_wlan_cfg_delete_index(int index); - -void rt_wlan_cfg_delete_all(void); - -void rt_wlan_cfg_dump(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/components/drivers/wlan/dev_wlan_cmd.c b/rt-thread/components/drivers/wlan/dev_wlan_cmd.c deleted file mode 100644 index 6592281..0000000 --- a/rt-thread/components/drivers/wlan/dev_wlan_cmd.c +++ /dev/null @@ -1,827 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-08-13 tyx the first version - * 2024-03-24 Evlers fixed a duplicate issue with the wifi scan command - */ - -#include -#include -#include -#include -#include - -#define DBG_TAG "WLAN.cmd" -#ifdef RT_WLAN_MGNT_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif /* RT_WLAN_MGNT_DEBUG */ -#include - -static struct rt_wlan_scan_result scan_result; -static struct rt_wlan_info *scan_filter = RT_NULL; - -#if defined(RT_WLAN_MANAGE_ENABLE) && defined(RT_WLAN_MSH_CMD_ENABLE) - -struct wifi_cmd_des -{ - const char *cmd; - int (*fun)(int argc, char *argv[]); -}; - -static int wifi_help(int argc, char *argv[]); -static int wifi_scan(int argc, char *argv[]); -static int wifi_status(int argc, char *argv[]); -static int wifi_join(int argc, char *argv[]); -static int wifi_ap(int argc, char *argv[]); -static int wifi_list_sta(int argc, char *argv[]); -static int wifi_disconnect(int argc, char *argv[]); -static int wifi_ap_stop(int argc, char *argv[]); - -#ifdef RT_WLAN_CMD_DEBUG -/* just for debug */ -static int wifi_debug(int argc, char *argv[]); -static int wifi_debug_save_cfg(int argc, char *argv[]); -static int wifi_debug_dump_cfg(int argc, char *argv[]); -static int wifi_debug_clear_cfg(int argc, char *argv[]); -static int wifi_debug_dump_prot(int argc, char *argv[]); -static int wifi_debug_set_mode(int argc, char *argv[]); -static int wifi_debug_set_prot(int argc, char *argv[]); -static int wifi_debug_set_autoconnect(int argc, char *argv[]); -#endif - -/* cmd table */ -static const struct wifi_cmd_des cmd_tab[] = -{ - {"scan", wifi_scan}, - {"help", wifi_help}, - {"status", wifi_status}, - {"join", wifi_join}, - {"ap", wifi_ap}, - {"list_sta", wifi_list_sta}, - {"disc", wifi_disconnect}, - {"ap_stop", wifi_ap_stop}, - {"smartconfig", RT_NULL}, -#ifdef RT_WLAN_CMD_DEBUG - {"-d", wifi_debug}, -#endif -}; - -#ifdef RT_WLAN_CMD_DEBUG -/* debug cmd table */ -static const struct wifi_cmd_des debug_tab[] = -{ - {"save_cfg", wifi_debug_save_cfg}, - {"dump_cfg", wifi_debug_dump_cfg}, - {"clear_cfg", wifi_debug_clear_cfg}, - {"dump_prot", wifi_debug_dump_prot}, - {"mode", wifi_debug_set_mode}, - {"prot", wifi_debug_set_prot}, - {"auto", wifi_debug_set_autoconnect}, -}; -#endif - -static int wifi_help(int argc, char *argv[]) -{ - rt_kprintf("wifi\n"); - rt_kprintf("wifi help\n"); - rt_kprintf("wifi scan [SSID]\n"); - rt_kprintf("wifi join [SSID] [PASSWORD]\n"); - rt_kprintf("wifi ap SSID [PASSWORD]\n"); - rt_kprintf("wifi disc\n"); - rt_kprintf("wifi ap_stop\n"); - rt_kprintf("wifi status\n"); - rt_kprintf("wifi smartconfig\n"); -#ifdef RT_WLAN_CMD_DEBUG - rt_kprintf("wifi -d debug command\n"); -#endif - return 0; -} - -static int wifi_status(int argc, char *argv[]) -{ - int rssi; - struct rt_wlan_info info; - - if (argc > 2) - return -1; - - if (rt_wlan_is_connected() == 1) - { - rssi = rt_wlan_get_rssi(); - rt_wlan_get_info(&info); - rt_kprintf("Wi-Fi STA Info\n"); - rt_kprintf("SSID : %-.32s\n", &info.ssid.val[0]); - rt_kprintf("MAC Addr: %02x:%02x:%02x:%02x:%02x:%02x\n", info.bssid[0], - info.bssid[1], - info.bssid[2], - info.bssid[3], - info.bssid[4], - info.bssid[5]); - rt_kprintf("Channel: %d\n", info.channel); - rt_kprintf("DataRate: %dMbps\n", info.datarate / 1000000); - rt_kprintf("RSSI: %d\n", rssi); - } - else - { - rt_kprintf("wifi disconnected!\n"); - } - - if (rt_wlan_ap_is_active() == 1) - { - rt_wlan_ap_get_info(&info); - rt_kprintf("Wi-Fi AP Info\n"); - rt_kprintf("SSID : %-.32s\n", &info.ssid.val[0]); - rt_kprintf("MAC Addr: %02x:%02x:%02x:%02x:%02x:%02x\n", info.bssid[0], - info.bssid[1], - info.bssid[2], - info.bssid[3], - info.bssid[4], - info.bssid[5]); - rt_kprintf("Channel: %d\n", info.channel); - rt_kprintf("DataRate: %dMbps\n", info.datarate / 1000000); - rt_kprintf("hidden: %s\n", info.hidden ? "Enable" : "Disable"); - } - else - { - rt_kprintf("wifi ap not start!\n"); - } - rt_kprintf("Auto Connect status:%s!\n", (rt_wlan_get_autoreconnect_mode() ? "Enable" : "Disable")); - return 0; -} - - -static rt_bool_t wifi_info_isequ(struct rt_wlan_info *info1, struct rt_wlan_info *info2) -{ - rt_bool_t is_equ = 1; - rt_uint8_t bssid_zero[RT_WLAN_BSSID_MAX_LENGTH] = { 0 }; - - if (is_equ && (info1->security != SECURITY_UNKNOWN) && (info2->security != SECURITY_UNKNOWN)) - { - is_equ &= info2->security == info1->security; - } - if (is_equ && ((info1->ssid.len > 0) && (info2->ssid.len > 0))) - { - is_equ &= info1->ssid.len == info2->ssid.len; - is_equ &= rt_memcmp(&info2->ssid.val[0], &info1->ssid.val[0], info1->ssid.len) == 0; - } - if (is_equ && (rt_memcmp(&info1->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)) && - (rt_memcmp(&info2->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH))) - { - is_equ &= rt_memcmp(&info1->bssid[0], &info2->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0; - } - if (is_equ && info1->datarate && info2->datarate) - { - is_equ &= info1->datarate == info2->datarate; - } - if (is_equ && (info1->channel >= 0) && (info2->channel >= 0)) - { - is_equ &= info1->channel == info2->channel; - } - if (is_equ && (info1->rssi < 0) && (info2->rssi < 0)) - { - is_equ &= info1->rssi == info2->rssi; - } - return is_equ; -} - -static rt_err_t wifi_scan_result_cache(struct rt_wlan_info *info) -{ - struct rt_wlan_info *ptable; - rt_err_t err = RT_EOK; - int i, insert = -1; - rt_base_t level; - - if ((info == RT_NULL) || (info->ssid.len == 0)) return -RT_EINVAL; - - LOG_D("ssid:%s len:%d mac:%02x:%02x:%02x:%02x:%02x:%02x", info->ssid.val, info->ssid.len, - info->bssid[0], info->bssid[1], info->bssid[2], info->bssid[3], info->bssid[4], info->bssid[5]); - - /* scanning result filtering */ - level = rt_hw_interrupt_disable(); - if (scan_filter) - { - struct rt_wlan_info _tmp_info = *scan_filter; - rt_hw_interrupt_enable(level); - if (wifi_info_isequ(&_tmp_info, info) != RT_TRUE) - { - return RT_EOK; - } - } - else - { - rt_hw_interrupt_enable(level); - } - - /* de-duplicatio */ - for (i = 0; i < scan_result.num; i++) - { - if ((info->ssid.len == scan_result.info[i].ssid.len) && - (rt_memcmp(&info->bssid[0], &scan_result.info[i].bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0)) - { - return RT_EOK; - } -#ifdef RT_WLAN_SCAN_SORT - if (insert >= 0) - { - continue; - } - /* Signal intensity comparison */ - if ((info->rssi < 0) && (scan_result.info[i].rssi < 0)) - { - if (info->rssi > scan_result.info[i].rssi) - { - insert = i; - continue; - } - else if (info->rssi < scan_result.info[i].rssi) - { - continue; - } - } - - /* Channel comparison */ - if (info->channel < scan_result.info[i].channel) - { - insert = i; - continue; - } - else if (info->channel > scan_result.info[i].channel) - { - continue; - } - - /* data rate comparison */ - if ((info->datarate > scan_result.info[i].datarate)) - { - insert = i; - continue; - } - else if (info->datarate < scan_result.info[i].datarate) - { - continue; - } -#endif - } - - /* Insert the end */ - if (insert == -1) - insert = scan_result.num; - - if (scan_result.num >= RT_WLAN_SCAN_CACHE_NUM) - return RT_EOK; - - /* malloc memory */ - ptable = rt_malloc(sizeof(struct rt_wlan_info) * (scan_result.num + 1)); - if (ptable == RT_NULL) - { - LOG_E("wlan info malloc failed!"); - return -RT_ENOMEM; - } - scan_result.num ++; - - /* copy info */ - for (i = 0; i < scan_result.num; i++) - { - if (i < insert) - { - ptable[i] = scan_result.info[i]; - } - else if (i > insert) - { - ptable[i] = scan_result.info[i - 1]; - } - else if (i == insert) - { - ptable[i] = *info; - } - } - rt_free(scan_result.info); - scan_result.info = ptable; - return err; -} - - - -static void wifi_scan_result_clean(void) -{ - - /* If there is data */ - if (scan_result.num) - { - scan_result.num = 0; - rt_free(scan_result.info); - scan_result.info = RT_NULL; - } -} - -static void print_ap_info(struct rt_wlan_info *info,int index) -{ - char *security; - - if(index == 0) - { - rt_kprintf(" SSID MAC security rssi chn Mbps\n"); - rt_kprintf("------------------------------- ----------------- -------------- ---- --- ----\n"); - } - - { - rt_kprintf("%-32.32s", &(info->ssid.val[0])); - rt_kprintf("%02x:%02x:%02x:%02x:%02x:%02x ", - info->bssid[0], - info->bssid[1], - info->bssid[2], - info->bssid[3], - info->bssid[4], - info->bssid[5] - ); - switch (info->security) - { - case SECURITY_OPEN: - security = "OPEN"; - break; - case SECURITY_WEP_PSK: - security = "WEP_PSK"; - break; - case SECURITY_WEP_SHARED: - security = "WEP_SHARED"; - break; - case SECURITY_WPA_TKIP_PSK: - security = "WPA_TKIP_PSK"; - break; - case SECURITY_WPA_AES_PSK: - security = "WPA_AES_PSK"; - break; - case SECURITY_WPA2_AES_PSK: - security = "WPA2_AES_PSK"; - break; - case SECURITY_WPA2_TKIP_PSK: - security = "WPA2_TKIP_PSK"; - break; - case SECURITY_WPA2_MIXED_PSK: - security = "WPA2_MIXED_PSK"; - break; - case SECURITY_WPS_OPEN: - security = "WPS_OPEN"; - break; - case SECURITY_WPS_SECURE: - security = "WPS_SECURE"; - break; - default: - security = "UNKNOWN"; - break; - } - rt_kprintf("%-14.14s ", security); - rt_kprintf("%-4d ", info->rssi); - rt_kprintf("%3d ", info->channel); - rt_kprintf("%4d\n", info->datarate / 1000000); - } - -} - -static void user_ap_info_callback(int event, struct rt_wlan_buff *buff, void *parameter) -{ - struct rt_wlan_info *info = RT_NULL; - int index = 0; - int ret = RT_EOK; - rt_uint32_t last_num = scan_result.num; - - RT_ASSERT(event == RT_WLAN_EVT_SCAN_REPORT); - RT_ASSERT(buff != RT_NULL); - RT_ASSERT(parameter != RT_NULL); - - info = (struct rt_wlan_info *)buff->data; - index = *((int *)(parameter)); - - ret = wifi_scan_result_cache(info); - if(ret == RT_EOK) - { - if(scan_filter == RT_NULL || - (scan_filter != RT_NULL && - scan_filter->ssid.len == info->ssid.len && - rt_memcmp(&scan_filter->ssid.val[0], &info->ssid.val[0], scan_filter->ssid.len) == 0)) - { - /*Check whether a new ap is added*/ - if (last_num < scan_result.num) - { - /*Print the info*/ - print_ap_info(info,index); - } - - index++; - *((int *)(parameter)) = index; - } - } - -} -static int wifi_scan(int argc, char *argv[]) -{ - struct rt_wlan_info *info = RT_NULL; - struct rt_wlan_info filter; - int ret = 0; - int i = 0; - - if (argc > 3) - return -1; - - if (argc == 3) - { - INVALID_INFO(&filter); - SSID_SET(&filter, argv[2]); - info = &filter; - } - - ret = rt_wlan_register_event_handler(RT_WLAN_EVT_SCAN_REPORT,user_ap_info_callback,&i); - if(ret != RT_EOK) - { - LOG_E("Scan register user callback error:%d!\n",ret); - return 0; - } - - if(info) - { - scan_filter = info; - } - - - /*Todo: what can i do for it return val */ - ret = rt_wlan_scan_with_info(info); - if(ret != RT_EOK) - { - LOG_E("Scan with info error:%d!\n",ret); - } - - /* clean scan result */ - wifi_scan_result_clean(); - if(info) - { - scan_filter = RT_NULL; - } - return 0; -} - -static int wifi_join(int argc, char *argv[]) -{ - const char *ssid = RT_NULL; - const char *key = RT_NULL; - struct rt_wlan_cfg_info cfg_info; - - rt_memset(&cfg_info, 0, sizeof(cfg_info)); - if (argc == 2) - { -#ifdef RT_WLAN_CFG_ENABLE - /* get info to connect */ - if (rt_wlan_cfg_read_index(&cfg_info, 0) == 1) - { - ssid = (char *)(&cfg_info.info.ssid.val[0]); - if (cfg_info.key.len) - key = (char *)(&cfg_info.key.val[0]); - } - else -#endif - { - rt_kprintf("not find connect info\n"); - } - } - else if (argc == 3) - { - /* ssid */ - ssid = argv[2]; - } - else if (argc == 4) - { - ssid = argv[2]; - /* password */ - key = argv[3]; - } - else - { - return -1; - } - rt_wlan_connect(ssid, key); - return 0; -} - -static int wifi_ap(int argc, char *argv[]) -{ - const char *ssid = RT_NULL; - const char *key = RT_NULL; - - if (argc == 3) - { - ssid = argv[2]; - } - else if (argc == 4) - { - ssid = argv[2]; - key = argv[3]; - } - else - { - return -1; - } - - rt_wlan_start_ap(ssid, key); - return 0; -} - -static int wifi_list_sta(int argc, char *argv[]) -{ - struct rt_wlan_info *sta_info; - int num, i; - - if (argc > 2) - return -1; - num = rt_wlan_ap_get_sta_num(); - sta_info = rt_malloc(sizeof(struct rt_wlan_info) * num); - if (sta_info == RT_NULL) - { - rt_kprintf("num:%d\n", num); - return 0; - } - rt_wlan_ap_get_sta_info(sta_info, num); - rt_kprintf("num:%d\n", num); - for (i = 0; i < num; i++) - { - rt_kprintf("sta mac %02x:%02x:%02x:%02x:%02x:%02x\n", - sta_info[i].bssid[0], sta_info[i].bssid[1], sta_info[i].bssid[2], - sta_info[i].bssid[3], sta_info[i].bssid[4], sta_info[i].bssid[5]); - } - rt_free(sta_info); - return 0; -} - -static int wifi_disconnect(int argc, char *argv[]) -{ - if (argc != 2) - { - return -1; - } - - rt_wlan_disconnect(); - return 0; -} - -static int wifi_ap_stop(int argc, char *argv[]) -{ - if (argc != 2) - { - return -1; - } - - rt_wlan_ap_stop(); - return 0; -} - -#ifdef RT_WLAN_CMD_DEBUG -/* just for debug */ -static int wifi_debug_help(int argc, char *argv[]) -{ - rt_kprintf("save_cfg ssid [password]\n"); - rt_kprintf("dump_cfg\n"); - rt_kprintf("clear_cfg\n"); - rt_kprintf("dump_prot\n"); - rt_kprintf("mode sta/ap dev_name\n"); - rt_kprintf("prot lwip dev_name\n"); - rt_kprintf("auto enable/disable\n"); - return 0; -} - -static int wifi_debug_save_cfg(int argc, char *argv[]) -{ - struct rt_wlan_cfg_info cfg_info; - int len; - char *ssid = RT_NULL, *password = RT_NULL; - - rt_memset(&cfg_info, 0, sizeof(cfg_info)); - INVALID_INFO(&cfg_info.info); - if (argc == 2) - { - ssid = argv[1]; - } - else if (argc == 3) - { - ssid = argv[1]; - password = argv[2]; - } - else - { - return -1; - } - - if (ssid != RT_NULL) - { - len = rt_strlen(ssid); - if (len > RT_WLAN_SSID_MAX_LENGTH) - { - rt_kprintf("ssid is to long"); - return 0; - } - rt_memcpy(&cfg_info.info.ssid.val[0], ssid, len); - cfg_info.info.ssid.len = len; - } - - if (password != RT_NULL) - { - len = rt_strlen(password); - if (len > RT_WLAN_PASSWORD_MAX_LENGTH) - { - rt_kprintf("password is to long"); - return 0; - } - rt_memcpy(&cfg_info.key.val[0], password, len); - cfg_info.key.len = len; - } -#ifdef RT_WLAN_CFG_ENABLE - rt_wlan_cfg_save(&cfg_info); -#endif - return 0; -} - -static int wifi_debug_dump_cfg(int argc, char *argv[]) -{ - if (argc == 1) - { -#ifdef RT_WLAN_CFG_ENABLE - rt_wlan_cfg_dump(); -#endif - } - else - { - return -1; - } - return 0; -} - -static int wifi_debug_clear_cfg(int argc, char *argv[]) -{ - if (argc == 1) - { -#ifdef RT_WLAN_CFG_ENABLE - rt_wlan_cfg_delete_all(); - rt_wlan_cfg_cache_save(); -#endif - } - else - { - return -1; - } - return 0; -} - -static int wifi_debug_dump_prot(int argc, char *argv[]) -{ - if (argc == 1) - { - rt_wlan_prot_dump(); - } - else - { - return -1; - } - return 0; -} - -static int wifi_debug_set_mode(int argc, char *argv[]) -{ - rt_wlan_mode_t mode; - - if (argc != 3) - return -1; - - if (rt_strcmp("sta", argv[1]) == 0) - { - mode = RT_WLAN_STATION; - } - else if (rt_strcmp("ap", argv[1]) == 0) - { - mode = RT_WLAN_AP; - } - else if (rt_strcmp("none", argv[1]) == 0) - { - mode = RT_WLAN_NONE; - } - else - return -1; - - rt_wlan_set_mode(argv[2], mode); - return 0; -} - -static int wifi_debug_set_prot(int argc, char *argv[]) -{ - if (argc != 3) - { - return -1; - } - - rt_wlan_prot_attach(argv[2], argv[1]); - return 0; -} - -static int wifi_debug_set_autoconnect(int argc, char *argv[]) -{ - if (argc == 2) - { - if (rt_strcmp(argv[1], "enable") == 0) - rt_wlan_config_autoreconnect(RT_TRUE); - else if (rt_strcmp(argv[1], "disable") == 0) - rt_wlan_config_autoreconnect(RT_FALSE); - } - else - { - return -1; - } - return 0; -} - -static int wifi_debug(int argc, char *argv[]) -{ - int i, result = 0; - const struct wifi_cmd_des *run_cmd = RT_NULL; - - if (argc < 3) - { - wifi_debug_help(0, RT_NULL); - return 0; - } - - for (i = 0; i < sizeof(debug_tab) / sizeof(debug_tab[0]); i++) - { - if (rt_strcmp(debug_tab[i].cmd, argv[2]) == 0) - { - run_cmd = &debug_tab[i]; - break; - } - } - - if (run_cmd == RT_NULL) - { - wifi_debug_help(0, RT_NULL); - return 0; - } - - if (run_cmd->fun != RT_NULL) - { - result = run_cmd->fun(argc - 2, &argv[2]); - } - - if (result) - { - wifi_debug_help(argc - 2, &argv[2]); - } - return 0; -} -#endif - -static int wifi_msh(int argc, char *argv[]) -{ - int i, result = 0; - const struct wifi_cmd_des *run_cmd = RT_NULL; - - if (argc == 1) - { - wifi_help(argc, argv); - return 0; - } - - /* find fun */ - for (i = 0; i < sizeof(cmd_tab) / sizeof(cmd_tab[0]); i++) - { - if (rt_strcmp(cmd_tab[i].cmd, argv[1]) == 0) - { - run_cmd = &cmd_tab[i]; - break; - } - } - - /* not find fun, print help */ - if (run_cmd == RT_NULL) - { - wifi_help(argc, argv); - return 0; - } - - /* run fun */ - if (run_cmd->fun != RT_NULL) - { - result = run_cmd->fun(argc, argv); - } - - if (result) - { - wifi_help(argc, argv); - } - return 0; -} - -#if defined(RT_USING_FINSH) -MSH_CMD_EXPORT_ALIAS(wifi_msh, wifi, wifi command); -#endif - -#endif diff --git a/rt-thread/components/drivers/wlan/dev_wlan_lwip.c b/rt-thread/components/drivers/wlan/dev_wlan_lwip.c deleted file mode 100644 index 21f43c1..0000000 --- a/rt-thread/components/drivers/wlan/dev_wlan_lwip.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-08-14 tyx the first version - */ - -#include -#include -#include -#include -#include - -#if defined(RT_WLAN_PROT_ENABLE) && defined(RT_WLAN_PROT_LWIP_ENABLE) - -#ifdef RT_USING_LWIP -#include -#include -#ifdef LWIP_USING_DHCPD -#include -#endif -#ifdef RT_USING_NETDEV -#include -#endif - -#define DBG_TAG "WLAN.lwip" -#ifdef RT_WLAN_LWIP_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif /* RT_WLAN_LWIP_DEBUG */ -#include - -#ifndef IPADDR_STRLEN_MAX -#define IPADDR_STRLEN_MAX (32) -#endif - -#ifndef RT_WLAN_PROT_LWIP_NAME -#define RT_WLAN_PROT_LWIP_NAME ("lwip") -#endif - -struct lwip_prot_des -{ - struct rt_wlan_prot prot; - struct eth_device eth; - rt_int8_t connected_flag; - struct rt_timer timer; - struct rt_work work; -}; - -static void netif_is_ready(struct rt_work *work, void *parameter) -{ - ip_addr_t ip_addr_zero = { 0 }; - struct rt_wlan_device *wlan = parameter; - struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)wlan->prot; - struct eth_device *eth_dev; - rt_base_t level; - struct rt_wlan_buff buff; - rt_uint32_t ip_addr[4]; - char str[IPADDR_STRLEN_MAX]; - - if (lwip_prot == RT_NULL) - return; - - eth_dev = &lwip_prot->eth; - rt_timer_stop(&lwip_prot->timer); - if (ip_addr_cmp(&(eth_dev->netif->ip_addr), &ip_addr_zero) != 0) - { - rt_timer_start(&lwip_prot->timer); - goto exit; - } - rt_memset(&ip_addr, 0, sizeof(ip_addr)); -#if LWIP_IPV4 && LWIP_IPV6 - if (eth_dev->netif->ip_addr.type == IPADDR_TYPE_V4) - { - ip_addr[0] = ip4_addr_get_u32(ð_dev->netif->ip_addr.u_addr.ip4); - buff.data = &ip_addr[0]; - buff.len = sizeof(ip_addr[0]); - } - else if (eth_dev->netif->ip_addr.type == IPADDR_TYPE_V6) - { - *(ip6_addr_t *)(&ip_addr[0]) = eth_dev->netif->ip_addr.u_addr.ip6; - buff.data = ip_addr; - buff.len = sizeof(ip_addr); - } - else - { - LOG_W("F:%s L:%d ip addr type not support", __FUNCTION__, __LINE__); - } -#else -#if LWIP_IPV4 - ip_addr[0] = ip4_addr_get_u32(ð_dev->netif->ip_addr); - buff.data = &ip_addr[0]; - buff.len = sizeof(ip_addr[0]); -#else - *(ip_addr_t *)(&ip_addr[0]) = eth_dev->netif->ip_addr; - buff.data = ip_addr; - buff.len = sizeof(ip_addr); -#endif -#endif - if (rt_wlan_prot_ready(wlan, &buff) != 0) - { - rt_timer_start(&lwip_prot->timer); - goto exit; - } - rt_memset(str, 0, IPADDR_STRLEN_MAX); - rt_enter_critical(); - rt_memcpy(str, ipaddr_ntoa(&(eth_dev->netif->ip_addr)), IPADDR_STRLEN_MAX); - rt_exit_critical(); - LOG_I("Got IP address : %s", str); -exit: - level = rt_hw_interrupt_disable(); - if (work) - { - rt_memset(work, 0, sizeof(struct rt_work)); - } - rt_hw_interrupt_enable(level); -} - -static void timer_callback(void *parameter) -{ -#ifdef RT_WLAN_WORK_THREAD_ENABLE - struct rt_workqueue *workqueue; - struct rt_wlan_device *wlan = parameter; - struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)wlan->prot; - struct rt_work *work; - rt_base_t level; - - if (lwip_prot == RT_NULL) - return; - - work = &lwip_prot->work; - workqueue = rt_wlan_get_workqueue(); - if (workqueue != RT_NULL) - { - level = rt_hw_interrupt_disable(); - rt_work_init(work, netif_is_ready, parameter); - rt_hw_interrupt_enable(level); - if (rt_workqueue_dowork(workqueue, work) != RT_EOK) - { - level = rt_hw_interrupt_disable(); - rt_memset(work, 0, sizeof(struct rt_work)); - rt_hw_interrupt_enable(level); - } - } -#else - netif_is_ready(RT_NULL, parameter); -#endif - -} - -static void netif_set_connected(void *parameter) -{ - struct rt_wlan_device *wlan = parameter; - struct lwip_prot_des *lwip_prot = wlan->prot; - struct eth_device *eth_dev; - - if (lwip_prot == RT_NULL) - return; - - eth_dev = &lwip_prot->eth; - - if (lwip_prot->connected_flag) - { - if (wlan->mode == RT_WLAN_STATION) - { - LOG_D("F:%s L:%d dhcp start run", __FUNCTION__, __LINE__); - netifapi_netif_common(eth_dev->netif, netif_set_link_up, NULL); -#ifdef RT_LWIP_DHCP - netifapi_dhcp_start(eth_dev->netif); -#endif - rt_timer_start(&lwip_prot->timer); - } - else if (wlan->mode == RT_WLAN_AP) - { - LOG_D("F:%s L:%d dhcpd start run", __FUNCTION__, __LINE__); - - netifapi_netif_common(eth_dev->netif, netif_set_link_up, NULL); -#ifdef LWIP_USING_DHCPD - { - char netif_name[RT_NAME_MAX]; - - rt_memset(netif_name, 0, sizeof(netif_name)); - rt_memcpy(netif_name, eth_dev->netif->name, sizeof(eth_dev->netif->name)); - dhcpd_start(netif_name); - } -#endif - } - } - else - { - LOG_D("F:%s L:%d set linkdown", __FUNCTION__, __LINE__); - netifapi_netif_common(eth_dev->netif, netif_set_link_down, NULL); - rt_timer_stop(&lwip_prot->timer); -#ifdef RT_LWIP_DHCP - { - ip_addr_t ip_addr = { 0 }; - netifapi_dhcp_stop(eth_dev->netif); - netif_set_addr(eth_dev->netif, &ip_addr, &ip_addr, &ip_addr); - } -#endif -#ifdef LWIP_USING_DHCPD - { - char netif_name[RT_NAME_MAX]; - rt_memset(netif_name, 0, sizeof(netif_name)); - rt_memcpy(netif_name, lwip_prot->eth.netif->name, sizeof(lwip_prot->eth.netif->name)); - dhcpd_stop(netif_name); - } -#endif - } -} - -static void rt_wlan_lwip_event_handle(struct rt_wlan_prot *port, struct rt_wlan_device *wlan, int event) -{ - struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)wlan->prot; - rt_bool_t flag_old; - - if (lwip_prot == RT_NULL) - return; - - flag_old = lwip_prot->connected_flag; - - switch (event) - { - case RT_WLAN_PROT_EVT_CONNECT: - { - LOG_D("event: CONNECT"); - lwip_prot->connected_flag = RT_TRUE; - break; - } - case RT_WLAN_PROT_EVT_DISCONNECT: - { - LOG_D("event: DISCONNECT"); - lwip_prot->connected_flag = RT_FALSE; - break; - } - case RT_WLAN_PROT_EVT_AP_START: - { - LOG_D("event: AP_START"); - lwip_prot->connected_flag = RT_TRUE; - break; - } - case RT_WLAN_PROT_EVT_AP_STOP: - { - LOG_D("event: AP_STOP"); - lwip_prot->connected_flag = RT_FALSE; - break; - } - case RT_WLAN_PROT_EVT_AP_ASSOCIATED: - { - LOG_D("event: ASSOCIATED"); - break; - } - case RT_WLAN_PROT_EVT_AP_DISASSOCIATED: - { - LOG_D("event: DISASSOCIATED"); - break; - } - default : - { - LOG_D("event: UNKNOWN"); - break; - } - } - if (flag_old != lwip_prot->connected_flag) - { -#ifdef RT_WLAN_WORK_THREAD_ENABLE - rt_wlan_workqueue_dowork(netif_set_connected, wlan); -#else - netif_set_connected(wlan); -#endif - } -} - -static rt_err_t rt_wlan_lwip_protocol_control(rt_device_t device, int cmd, void *args) -{ - struct eth_device *eth_dev = (struct eth_device *)device; - struct rt_wlan_device *wlan; - rt_err_t err = RT_EOK; - - RT_ASSERT(eth_dev != RT_NULL); - - LOG_D("F:%s L:%d device:0x%08x user_data:0x%08x", __FUNCTION__, __LINE__, eth_dev, eth_dev->parent.user_data); - - switch (cmd) - { - case NIOCTL_GADDR: - /* get MAC address */ - wlan = eth_dev->parent.user_data; - err = rt_device_control((rt_device_t)wlan, RT_WLAN_CMD_GET_MAC, args); - break; - default : - break; - } - return err; -} - -static rt_err_t rt_wlan_lwip_protocol_recv(struct rt_wlan_device *wlan, void *buff, int len) -{ - struct eth_device *eth_dev = &((struct lwip_prot_des *)wlan->prot)->eth; - struct pbuf *p = RT_NULL; - - LOG_D("F:%s L:%d run", __FUNCTION__, __LINE__); - - if (eth_dev == RT_NULL) - { - return -RT_ERROR; - } -#ifdef RT_WLAN_PROT_LWIP_PBUF_FORCE - { - p = buff; - if ((eth_dev->netif->input(p, eth_dev->netif)) != ERR_OK) - { - return -RT_ERROR; - } - return RT_EOK; - } -#else - { - int count = 0; - - while (p == RT_NULL) - { - p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); - if (p != RT_NULL) - break; - - p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM); - if (p != RT_NULL) - break; - - LOG_D("F:%s L:%d wait for pbuf_alloc!", __FUNCTION__, __LINE__); - rt_thread_delay(1); - count++; - - //wait for 10ms or give up!! - if (count >= 10) - { - LOG_W("F:%s L:%d pbuf allocate fail!!!", __FUNCTION__, __LINE__); - return -RT_ENOMEM; - } - } - /*copy data dat -> pbuf*/ - pbuf_take(p, buff, len); - if ((eth_dev->netif->input(p, eth_dev->netif)) != ERR_OK) - { - LOG_D("F:%s L:%d IP input error", __FUNCTION__, __LINE__); - pbuf_free(p); - p = RT_NULL; - } - LOG_D("F:%s L:%d netif iput success! len:%d", __FUNCTION__, __LINE__, len); - return RT_EOK; - } -#endif -} - -static rt_err_t rt_wlan_lwip_protocol_send(rt_device_t device, struct pbuf *p) -{ - struct rt_wlan_device *wlan = ((struct eth_device *)device)->parent.user_data; - - LOG_D("F:%s L:%d run", __FUNCTION__, __LINE__); - - if (wlan == RT_NULL) - { - return RT_EOK; - } - -#ifdef RT_WLAN_PROT_LWIP_PBUF_FORCE - { - rt_wlan_prot_transfer_dev(wlan, p, p->tot_len); - return RT_EOK; - } -#else - { - rt_uint8_t *frame; - - /* sending data directly */ - if (p->len == p->tot_len) - { - frame = (rt_uint8_t *)p->payload; - rt_wlan_prot_transfer_dev(wlan, frame, p->tot_len); - LOG_D("F:%s L:%d run len:%d", __FUNCTION__, __LINE__, p->tot_len); - return RT_EOK; - } - frame = rt_malloc(p->tot_len); - if (frame == RT_NULL) - { - LOG_E("F:%s L:%d malloc out_buf fail\n", __FUNCTION__, __LINE__); - return -RT_ENOMEM; - } - /*copy pbuf -> data dat*/ - pbuf_copy_partial(p, frame, p->tot_len, 0); - /* send data */ - rt_wlan_prot_transfer_dev(wlan, frame, p->tot_len); - LOG_D("F:%s L:%d run len:%d", __FUNCTION__, __LINE__, p->tot_len); - rt_free(frame); - return RT_EOK; - } -#endif -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops wlan_lwip_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - RT_NULL, - RT_NULL, - rt_wlan_lwip_protocol_control -}; -#endif - -static struct rt_wlan_prot *rt_wlan_lwip_protocol_register(struct rt_wlan_prot *prot, struct rt_wlan_device *wlan) -{ - struct eth_device *eth = RT_NULL; - rt_uint8_t id = 0; - char eth_name[4], timer_name[16]; - rt_device_t device = RT_NULL; - struct lwip_prot_des *lwip_prot; - - if (wlan == RT_NULL || prot == RT_NULL) - return RT_NULL;; - - LOG_D("F:%s L:%d is run wlan:0x%08x", __FUNCTION__, __LINE__, wlan); - - do - { - /* find ETH device name */ - eth_name[0] = 'w'; - eth_name[1] = '0' + id++; - eth_name[2] = '\0'; - device = rt_device_find(eth_name); - } - while (device); - - if (id > 9) - { - LOG_E("F:%s L:%d not find Empty name", __FUNCTION__, __LINE__, eth_name); - return RT_NULL; - } - - if (rt_device_open((rt_device_t)wlan, RT_DEVICE_OFLAG_RDWR) != RT_EOK) - { - LOG_E("F:%s L:%d open wlan failed", __FUNCTION__, __LINE__); - return RT_NULL; - } - - lwip_prot = rt_malloc(sizeof(struct lwip_prot_des)); - if (lwip_prot == RT_NULL) - { - LOG_E("F:%s L:%d malloc mem failed", __FUNCTION__, __LINE__); - rt_device_close((rt_device_t)wlan); - return RT_NULL; - } - rt_memset(lwip_prot, 0, sizeof(struct lwip_prot_des)); - - eth = &lwip_prot->eth; - -#ifdef RT_USING_DEVICE_OPS - eth->parent.ops = &wlan_lwip_ops; -#else - eth->parent.init = RT_NULL; - eth->parent.open = RT_NULL; - eth->parent.close = RT_NULL; - eth->parent.read = RT_NULL; - eth->parent.write = RT_NULL; - eth->parent.control = rt_wlan_lwip_protocol_control; -#endif - - eth->parent.user_data = wlan; - eth->eth_rx = RT_NULL; - eth->eth_tx = rt_wlan_lwip_protocol_send; - - /* register ETH device */ - if (eth_device_init(eth, eth_name) != RT_EOK) - { - LOG_E("eth device init failed"); - rt_device_close((rt_device_t)wlan); - rt_free(lwip_prot); - return RT_NULL; - } - rt_memcpy(&lwip_prot->prot, prot, sizeof(struct rt_wlan_prot)); - rt_sprintf(timer_name, "timer_%s", eth_name); - rt_timer_init(&lwip_prot->timer, timer_name, timer_callback, wlan, rt_tick_from_millisecond(1000), - RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT); - netif_set_up(eth->netif); - LOG_I("eth device init ok name:%s", eth_name); -#ifdef RT_USING_NETDEV - wlan->netdev = netdev_get_by_name(eth_name); -#endif - return &lwip_prot->prot; -} - -static void rt_wlan_lwip_protocol_unregister(struct rt_wlan_prot *prot, struct rt_wlan_device *wlan) -{ - struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)prot; - - LOG_D("F:%s L:%d is run wlan:0x%08x", __FUNCTION__, __LINE__, wlan); -#if !defined(RT_USING_LWIP141) - wlan->prot = RT_NULL; - if (lwip_prot == RT_NULL) - { - return; - } - -#ifdef LWIP_USING_DHCPD - { - char netif_name[RT_NAME_MAX]; - rt_memset(netif_name, 0, sizeof(netif_name)); - rt_memcpy(netif_name, lwip_prot->eth.netif->name, sizeof(lwip_prot->eth.netif->name)); - dhcpd_stop(netif_name); - } -#endif - eth_device_deinit(&lwip_prot->eth); - rt_device_close((rt_device_t)wlan); - rt_timer_detach(&lwip_prot->timer); - wlan->netdev = RT_NULL; - rt_free(lwip_prot); -#endif -} - -static struct rt_wlan_prot_ops ops = -{ - rt_wlan_lwip_protocol_recv, - rt_wlan_lwip_protocol_register, - rt_wlan_lwip_protocol_unregister -}; - -int rt_wlan_lwip_init(void) -{ - static struct rt_wlan_prot prot; - rt_wlan_prot_event_t event; - - rt_memset(&prot, 0, sizeof(prot)); - rt_strncpy(&prot.name[0], RT_WLAN_PROT_LWIP_NAME, RT_WLAN_PROT_NAME_LEN); - prot.ops = &ops; - - if (rt_wlan_prot_regisetr(&prot) != RT_EOK) - { - LOG_E("F:%s L:%d protocol regisetr failed", __FUNCTION__, __LINE__); - return -1; - } - - for (event = RT_WLAN_PROT_EVT_INIT_DONE; event < RT_WLAN_PROT_EVT_MAX; event++) - { - rt_wlan_prot_event_register(&prot, event, rt_wlan_lwip_event_handle); - } - - return 0; -} -INIT_PREV_EXPORT(rt_wlan_lwip_init); - -#endif -#endif diff --git a/rt-thread/components/drivers/wlan/dev_wlan_mgnt.c b/rt-thread/components/drivers/wlan/dev_wlan_mgnt.c deleted file mode 100644 index 5d338ba..0000000 --- a/rt-thread/components/drivers/wlan/dev_wlan_mgnt.c +++ /dev/null @@ -1,1788 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-08-06 tyx the first version - * 2023-12-12 Evlers add the wlan join scan function - * 2024-12-25 Evlers add get_info api for more new sta information - * 2025-01-04 Evlers add ap_get_info api for more ap information - */ - -#include -#include -#include -#include -#include -#include -#include - -// #define RT_WLAN_MGNT_DEBUG -#define DBG_TAG "WLAN.mgnt" -#ifdef RT_WLAN_MGNT_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif /* RT_WLAN_MGNT_DEBUG */ -#include - -#ifdef RT_WLAN_MANAGE_ENABLE - -#ifndef RT_WLAN_DEVICE -#define RT_WLAN_DEVICE(__device) ((struct rt_wlan_device *)__device) -#endif - -#define RT_WLAN_LOG_D(_fmt, ...) LOG_D("L:%d "_fmt"", __LINE__, ##__VA_ARGS__) -#define RT_WLAN_LOG_I(...) LOG_I(__VA_ARGS__) -#define RT_WLAN_LOG_W(_fmt, ...) LOG_W("F:%s L:%d "_fmt"", __FUNCTION__, __LINE__, ##__VA_ARGS__) -#define RT_WLAN_LOG_E(_fmt, ...) LOG_E("F:%s L:%d "_fmt"", __FUNCTION__, __LINE__, ##__VA_ARGS__) - -#define STA_DEVICE() (_sta_mgnt.device) -#define AP_DEVICE() (_ap_mgnt.device) - -#define STAINFO_LOCK() (rt_mutex_take(&sta_info_mutex, RT_WAITING_FOREVER)) -#define STAINFO_UNLOCK() (rt_mutex_release(&sta_info_mutex)) - -#define MGNT_LOCK() (rt_mutex_take(&mgnt_mutex, RT_WAITING_FOREVER)) -#define MGNT_UNLOCK() (rt_mutex_release(&mgnt_mutex)) - -#define COMPLETE_LOCK() (rt_mutex_take(&complete_mutex, RT_WAITING_FOREVER)) -#define COMPLETE_UNLOCK() (rt_mutex_release(&complete_mutex)) - -#ifdef RT_WLAN_AUTO_CONNECT_ENABLE -#define TIME_STOP() (rt_timer_stop(&reconnect_time)) -#define TIME_START() (rt_timer_start(&reconnect_time)) -static rt_uint32_t id = 0; -#else -#define TIME_STOP() -#define TIME_START() -#endif - -#if RT_WLAN_EBOX_NUM < 1 -#error "event box num Too few" -#endif - -struct rt_wlan_mgnt_des -{ - struct rt_wlan_device *device; - struct rt_wlan_info info; - struct rt_wlan_key key; - rt_uint8_t state; - rt_uint8_t flags; -}; - -struct rt_wlan_event_desc -{ - rt_wlan_event_handler handler; - void *parameter; -}; - -struct rt_wlan_sta_list -{ - struct rt_wlan_sta_list *next; - struct rt_wlan_info info; -}; - -struct rt_wlan_sta_des -{ - int num; - struct rt_wlan_sta_list *node; -}; - -struct rt_wlan_msg -{ - rt_int32_t event; - rt_int32_t len; - void *buff; -}; - -struct rt_wlan_complete_des -{ - struct rt_event complete; - rt_uint32_t event_flag; - int index; -}; - -static struct rt_mutex mgnt_mutex; - -static struct rt_wlan_mgnt_des _sta_mgnt; -static struct rt_wlan_mgnt_des _ap_mgnt; - - -static struct rt_wlan_sta_des sta_info; -static struct rt_mutex sta_info_mutex; - -static struct rt_wlan_event_desc event_tab[RT_WLAN_EVT_MAX]; - -static struct rt_wlan_complete_des *complete_tab[5]; -static struct rt_mutex complete_mutex; - -#ifdef RT_WLAN_AUTO_CONNECT_ENABLE -static struct rt_timer reconnect_time; -#endif - -rt_inline int _sta_is_null(void) -{ - if (_sta_mgnt.device == RT_NULL) - { - return 1; - } - return 0; -} - -rt_inline int _ap_is_null(void) -{ - if (_ap_mgnt.device == RT_NULL) - { - return 1; - } - return 0; -} - -rt_inline rt_bool_t _is_do_connect(void) -{ - if ((rt_wlan_get_autoreconnect_mode() == RT_FALSE) || - (rt_wlan_is_connected() == RT_TRUE) || - (_sta_mgnt.state & RT_WLAN_STATE_CONNECTING)) - { - return RT_FALSE; - } - return RT_TRUE; -} - -#ifdef RT_WLAN_WORK_THREAD_ENABLE - -static void rt_wlan_mgnt_work(void *parameter) -{ - struct rt_wlan_msg *msg = parameter; - void *user_parameter; - rt_wlan_event_handler handler = RT_NULL; - struct rt_wlan_buff user_buff = { 0 }; - rt_base_t level; - - /* Get user callback */ - if (msg->event < RT_WLAN_EVT_MAX) - { - level = rt_hw_interrupt_disable(); - handler = event_tab[msg->event].handler; - user_parameter = event_tab[msg->event].parameter; - rt_hw_interrupt_enable(level); - } - - /* run user callback fun */ - if (handler) - { - user_buff.data = msg->buff; - user_buff.len = msg->len; - RT_WLAN_LOG_D("wlan work thread run user callback, event:%d", msg->event); - handler(msg->event, &user_buff, user_parameter); - } - - switch (msg->event) - { - case RT_WLAN_EVT_STA_CONNECTED: - { - struct rt_wlan_cfg_info cfg_info; - - rt_memset(&cfg_info, 0, sizeof(cfg_info)); - /* save config */ - if (rt_wlan_is_connected() == RT_TRUE) - { - rt_enter_critical(); - cfg_info.info = _sta_mgnt.info; - cfg_info.key = _sta_mgnt.key; - rt_exit_critical(); - RT_WLAN_LOG_D("run save config! ssid:%s len%d", _sta_mgnt.info.ssid.val, _sta_mgnt.info.ssid.len); -#ifdef RT_WLAN_CFG_ENABLE - rt_wlan_cfg_save(&cfg_info); -#endif - } - break; - } - default : - break; - } - - rt_free(msg); -} - -static rt_err_t rt_wlan_send_to_thread(rt_wlan_event_t event, void *buff, int len) -{ - struct rt_wlan_msg *msg; - - RT_WLAN_LOG_D("F:%s is run event:%d", __FUNCTION__, event); - - /* Event packing */ - msg = rt_malloc(sizeof(struct rt_wlan_msg) + len); - if (msg == RT_NULL) - { - RT_WLAN_LOG_E("wlan mgnt send msg err! No memory"); - return -RT_ENOMEM; - } - rt_memset(msg, 0, sizeof(struct rt_wlan_msg) + len); - msg->event = event; - if (len != 0) - { - msg->buff = (void *)&msg[1]; - rt_memcpy(msg->buff, buff, len); - msg->len = len; - } - - /* send event to wlan thread */ - if (rt_wlan_workqueue_dowork(rt_wlan_mgnt_work, msg) != RT_EOK) - { - rt_free(msg); - RT_WLAN_LOG_E("wlan mgnt do work fail"); - return -RT_ERROR; - } - return RT_EOK; -} -#endif - -static rt_err_t rt_wlan_sta_info_add(struct rt_wlan_info *info, int timeout) -{ - struct rt_wlan_sta_list *sta_list; - rt_err_t err = RT_EOK; - - if (_ap_is_null() || (info == RT_NULL)) return RT_EOK; - - err = rt_mutex_take(&sta_info_mutex, rt_tick_from_millisecond(timeout)); - if (err == RT_EOK) - { - /* malloc memory */ - sta_list = rt_malloc(sizeof(struct rt_wlan_sta_list)); - if (sta_list == RT_NULL) - { - rt_mutex_release(&sta_info_mutex); - RT_WLAN_LOG_E("sta list malloc failed!"); - return -RT_ENOMEM; - } - sta_list->next = RT_NULL; - sta_list->info = *info; - - /* Append sta info */ - sta_list->next = sta_info.node; - sta_info.node = sta_list; - /* num++ */ - sta_info.num ++; - rt_mutex_release(&sta_info_mutex); - RT_WLAN_LOG_I("sta associated mac:%02x:%02x:%02x:%02x:%02x:%02x", - info->bssid[0], info->bssid[1], info->bssid[2], - info->bssid[3], info->bssid[4], info->bssid[5]); - } - return err; -} - -static rt_err_t rt_wlan_sta_info_del(struct rt_wlan_info *info, int timeout) -{ - struct rt_wlan_sta_list *sta_list, *sta_prve; - rt_err_t err = RT_EOK; - - if (_ap_is_null() || (info == RT_NULL)) return RT_EOK; - - err = rt_mutex_take(&sta_info_mutex, rt_tick_from_millisecond(timeout)); - if (err == RT_EOK) - { - /* traversing the list */ - for (sta_list = sta_info.node, sta_prve = RT_NULL; sta_list != RT_NULL; - sta_prve = sta_list, sta_list = sta_list->next) - { - /* find mac addr */ - if (rt_memcmp(&sta_list->info.bssid[0], &info->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0) - { - if (sta_prve == RT_NULL) - { - sta_info.node = sta_list->next; - } - else - { - sta_prve->next = sta_list->next; - } - sta_info.num --; - rt_free(sta_list); - break; - } - } - rt_mutex_release(&sta_info_mutex); - RT_WLAN_LOG_I("sta exit mac:%02x:%02x:%02x:%02x:%02x:%02x", - info->bssid[0], info->bssid[1], info->bssid[2], - info->bssid[3], info->bssid[4], info->bssid[5]); - } - return err; -} - -static rt_err_t rt_wlan_sta_info_del_all(int timeout) -{ - struct rt_wlan_sta_list *sta_list, *sta_next; - rt_err_t err = RT_EOK; - - err = rt_mutex_take(&sta_info_mutex, rt_tick_from_millisecond(timeout)); - if (err == RT_EOK) - { - /* traversing the list */ - for (sta_list = sta_info.node; sta_list != RT_NULL; sta_list = sta_next) - { - sta_next = sta_list->next; - sta_info.num --; - rt_free(sta_list); - } - rt_mutex_release(&sta_info_mutex); - } - if (sta_info.num != 0) - { - RT_WLAN_LOG_W("\n\n!!!Program runing exception!!!\n\n"); - } - sta_info.num = 0; - sta_info.node = RT_NULL; - return err; -} -#ifdef RT_WLAN_AUTO_CONNECT_ENABLE -static void rt_wlan_auto_connect_run(struct rt_work *work, void *parameter) -{ - struct rt_wlan_cfg_info cfg_info; - char *password = RT_NULL; - rt_base_t level; - - RT_WLAN_LOG_D("F:%s is run", __FUNCTION__); - - if (rt_mutex_take(&mgnt_mutex, 0) != RT_EOK) - goto exit; - - /* auto connect status is disable or wifi is connect or connecting, exit */ - if (_is_do_connect() == RT_FALSE) - { - id = 0; - RT_WLAN_LOG_D("not connection"); - goto exit; - } - - /* Read the next configuration */ - rt_memset(&cfg_info, 0, sizeof(struct rt_wlan_cfg_info)); - if (rt_wlan_cfg_read_index(&cfg_info, id ++) == 0) - { - RT_WLAN_LOG_D("read cfg fail"); - id = 0; - goto exit; - } - - if (id >= rt_wlan_cfg_get_num()) id = 0; - - if ((cfg_info.key.len > 0) && (cfg_info.key.len <= RT_WLAN_PASSWORD_MAX_LENGTH)) - { - cfg_info.key.val[cfg_info.key.len] = '\0'; - password = (char *)(&cfg_info.key.val[0]); - } - rt_wlan_connect((char *)cfg_info.info.ssid.val, password); -exit: - rt_mutex_release(&mgnt_mutex); - level = rt_hw_interrupt_disable(); - rt_memset(work, 0, sizeof(struct rt_work)); - rt_hw_interrupt_enable(level); -} - -static void rt_wlan_cyclic_check(void *parameter) -{ - static struct rt_work work; - rt_base_t level; - - if ((_is_do_connect() == RT_TRUE) && (work.work_func == RT_NULL)) - { - level = rt_hw_interrupt_disable(); - rt_work_init(&work, rt_wlan_auto_connect_run, RT_NULL); - rt_hw_interrupt_enable(level); - if(rt_work_submit(&work,RT_TICK_PER_SECOND) != RT_EOK) - { - level = rt_hw_interrupt_disable(); - rt_memset(&work, 0, sizeof(struct rt_work)); - rt_hw_interrupt_enable(level); - } - } -} -#endif - -static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_event_t event, struct rt_wlan_buff *buff, void *parameter) -{ - rt_err_t err = RT_NULL; - rt_wlan_event_t user_event = RT_WLAN_EVT_MAX; - int i; - struct rt_wlan_buff user_buff = { 0 }; - - if (buff) - { - user_buff = *buff; - } - /* Event Handle */ - switch (event) - { - case RT_WLAN_DEV_EVT_CONNECT: - { - RT_WLAN_LOG_D("event: CONNECT"); -#ifdef RT_WLAN_AUTO_CONNECT_ENABLE - id = 0; -#endif - _sta_mgnt.state |= RT_WLAN_STATE_CONNECT; - _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECTING; - user_event = RT_WLAN_EVT_STA_CONNECTED; - TIME_STOP(); - user_buff.data = &_sta_mgnt.info; - user_buff.len = sizeof(struct rt_wlan_info); - RT_WLAN_LOG_I("wifi connect success ssid:%s", &_sta_mgnt.info.ssid.val[0]); - -#ifdef RT_WLAN_CFG_ENABLE - { - struct rt_wlan_cfg_info cfg_info; - rt_memset(&cfg_info, 0, sizeof(cfg_info)); - /* save config */ - if (rt_wlan_is_connected() == RT_TRUE) - { - rt_enter_critical(); - cfg_info.info = _sta_mgnt.info; - cfg_info.key = _sta_mgnt.key; - rt_exit_critical(); - RT_WLAN_LOG_D("run save config! ssid:%s len%d", _sta_mgnt.info.ssid.val, _sta_mgnt.info.ssid.len); - rt_wlan_cfg_save(&cfg_info); - } - } -#endif - break; - } - case RT_WLAN_DEV_EVT_CONNECT_FAIL: - { - RT_WLAN_LOG_D("event: CONNECT_FAIL"); - _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECT; - _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECTING; - _sta_mgnt.state &= ~RT_WLAN_STATE_READY; - user_event = RT_WLAN_EVT_STA_CONNECTED_FAIL; - user_buff.data = &_sta_mgnt.info; - user_buff.len = sizeof(struct rt_wlan_info); - if (rt_wlan_get_autoreconnect_mode()) - { - TIME_START(); - } - break; - } - case RT_WLAN_DEV_EVT_DISCONNECT: - { - RT_WLAN_LOG_D("event: DISCONNECT"); - _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECT; - _sta_mgnt.state &= ~RT_WLAN_STATE_READY; - user_event = RT_WLAN_EVT_STA_DISCONNECTED; - user_buff.data = &_sta_mgnt.info; - user_buff.len = sizeof(struct rt_wlan_info); - if (rt_wlan_get_autoreconnect_mode()) - { - TIME_START(); - } - break; - } - case RT_WLAN_DEV_EVT_AP_START: - { - RT_WLAN_LOG_D("event: AP_START"); - _ap_mgnt.state |= RT_WLAN_STATE_ACTIVE; - user_event = RT_WLAN_EVT_AP_START; - user_buff.data = &_ap_mgnt.info; - user_buff.len = sizeof(struct rt_wlan_info); - break; - } - case RT_WLAN_DEV_EVT_AP_STOP: - { - RT_WLAN_LOG_D("event: AP_STOP"); - _ap_mgnt.state &= ~RT_WLAN_STATE_ACTIVE; - user_event = RT_WLAN_EVT_AP_STOP; - err = rt_wlan_sta_info_del_all(RT_WAITING_FOREVER); - if (err != RT_NULL) - { - RT_WLAN_LOG_W("AP_STOP event handle fail"); - } - user_buff.data = &_ap_mgnt.info; - user_buff.len = sizeof(struct rt_wlan_info); - break; - } - case RT_WLAN_DEV_EVT_AP_ASSOCIATED: - { - RT_WLAN_LOG_D("event: ASSOCIATED"); - user_event = RT_WLAN_EVT_AP_ASSOCIATED; - if (user_buff.len != sizeof(struct rt_wlan_info)) - break; - err = rt_wlan_sta_info_add(user_buff.data, RT_WAITING_FOREVER); - if (err != RT_EOK) - { - RT_WLAN_LOG_W("AP_ASSOCIATED event handle fail"); - } - break; - } - case RT_WLAN_DEV_EVT_AP_DISASSOCIATED: - { - RT_WLAN_LOG_D("event: DISASSOCIATED"); - user_event = RT_WLAN_EVT_AP_DISASSOCIATED; - if (user_buff.len != sizeof(struct rt_wlan_info)) - break; - err = rt_wlan_sta_info_del(user_buff.data, RT_WAITING_FOREVER); - if (err != RT_EOK) - { - RT_WLAN_LOG_W("AP_DISASSOCIATED event handle fail"); - } - break; - } - case RT_WLAN_DEV_EVT_AP_ASSOCIATE_FAILED: - { - RT_WLAN_LOG_D("event: AP_ASSOCIATE_FAILED"); - break; - } - case RT_WLAN_DEV_EVT_SCAN_REPORT: - { - RT_WLAN_LOG_D("event: SCAN_REPORT"); - user_event = RT_WLAN_EVT_SCAN_REPORT; - break; - } - case RT_WLAN_DEV_EVT_SCAN_DONE: - { - RT_WLAN_LOG_D("event: SCAN_DONE"); - user_event = RT_WLAN_EVT_SCAN_DONE; - break; - } - default : - { - RT_WLAN_LOG_D("event: UNKNOWN"); - return; - } - } - - /* send event */ - COMPLETE_LOCK(); - for (i = 0; i < sizeof(complete_tab) / sizeof(complete_tab[0]); i++) - { - if ((complete_tab[i] != RT_NULL)) - { - complete_tab[i]->event_flag |= 0x1 << event; - rt_event_send(&complete_tab[i]->complete, 0x1 << event); - RT_WLAN_LOG_D("&complete_tab[i]->complete:0x%08x", &complete_tab[i]->complete); - } - } - COMPLETE_UNLOCK(); -#ifdef RT_WLAN_WORK_THREAD_ENABLE - rt_wlan_send_to_thread(user_event, user_buff.data, user_buff.len); -#else - { - void *user_parameter; - rt_wlan_event_handler handler = RT_NULL; - rt_base_t level; - /* Get user callback */ - if (user_event < RT_WLAN_EVT_MAX) - { - level = rt_hw_interrupt_disable(); - handler = event_tab[user_event].handler; - user_parameter = event_tab[user_event].parameter; - rt_hw_interrupt_enable(level); - } - - /* run user callback fun */ - if (handler) - { - RT_WLAN_LOG_D("unknown thread run user callback, event:%d", user_event); - handler(user_event, &user_buff, user_parameter); - } - } -#endif -} - -static struct rt_wlan_complete_des *rt_wlan_complete_create(const char *name) -{ - struct rt_wlan_complete_des *complete; - int i; - - complete = rt_malloc(sizeof(struct rt_wlan_complete_des)); - if (complete == RT_NULL) - { - RT_WLAN_LOG_E("complete event create failed"); - MGNT_UNLOCK(); - return complete; - } - rt_event_init(&complete->complete, name, RT_IPC_FLAG_FIFO); - complete->event_flag = 0; - //protect - COMPLETE_LOCK(); - for (i = 0; i < sizeof(complete_tab) / sizeof(complete_tab[0]); i++) - { - if (complete_tab[i] == RT_NULL) - { - complete->index = i; - complete_tab[i] = complete; - break; - } - } - COMPLETE_UNLOCK(); - - if (i >= sizeof(complete_tab) / sizeof(complete_tab[0])) - { - rt_event_detach(&complete->complete); - rt_free(complete); - complete = RT_NULL; - } - - return complete; -} - -static rt_err_t rt_wlan_complete_wait(struct rt_wlan_complete_des *complete, rt_uint32_t event, - rt_uint32_t timeout, rt_uint32_t *recved) -{ - if (complete == RT_NULL) - { - return -RT_ERROR; - } - - /* Check whether there is a waiting event */ - if (complete->event_flag & event) - { - *recved = complete->event_flag; - return RT_EOK; - } - else - { - return rt_event_recv(&complete->complete, event, RT_EVENT_FLAG_OR, - rt_tick_from_millisecond(timeout), recved); - } -} - -static void rt_wlan_complete_delete(struct rt_wlan_complete_des *complete) -{ - if (complete == RT_NULL) - { - return; - } - COMPLETE_LOCK(); - complete_tab[complete->index] = RT_NULL; - COMPLETE_UNLOCK(); - rt_event_detach(&complete->complete); - rt_free(complete); -} - -rt_err_t rt_wlan_set_mode(const char *dev_name, rt_wlan_mode_t mode) -{ - rt_device_t device = RT_NULL; - rt_err_t err; - rt_int8_t up_event_flag = 0; - rt_wlan_dev_event_handler handler = RT_NULL; - - if ((dev_name == RT_NULL) || (mode >= RT_WLAN_MODE_MAX)) - { - RT_WLAN_LOG_E("Parameter Wrongful name:%s mode:%d", dev_name, mode); - return -RT_EINVAL; - } - - RT_WLAN_LOG_D("%s is run dev_name:%s mode:%s%s%s", __FUNCTION__, dev_name, - mode == RT_WLAN_NONE ? "NONE" : "", - mode == RT_WLAN_STATION ? "STA" : "", - mode == RT_WLAN_AP ? "AP" : "" - ); - - /* find device */ - device = rt_device_find(dev_name); - if (device == RT_NULL) - { - RT_WLAN_LOG_E("not find device, set mode failed! name:%s", dev_name); - return -RT_EIO; - } - - MGNT_LOCK(); - if (RT_WLAN_DEVICE(device)->mode == mode) - { - RT_WLAN_LOG_D("L:%d this device mode is set"); - MGNT_UNLOCK(); - return RT_EOK; - } - - if ((mode == RT_WLAN_STATION) && - (RT_WLAN_DEVICE(device)->flags & RT_WLAN_FLAG_AP_ONLY)) - { - RT_WLAN_LOG_I("this device ap mode only"); - MGNT_UNLOCK(); - return -RT_ERROR; - } - else if ((mode == RT_WLAN_AP) && - (RT_WLAN_DEVICE(device)->flags & RT_WLAN_FLAG_STA_ONLY)) - { - RT_WLAN_LOG_I("this device sta mode only"); - MGNT_UNLOCK(); - return -RT_ERROR; - } - - /* - * device == sta and change to ap, should deinit - * device == ap and change to sta, should deinit - */ - if (((mode == RT_WLAN_STATION) && (RT_WLAN_DEVICE(device) == AP_DEVICE())) || - ((mode == RT_WLAN_AP) && (RT_WLAN_DEVICE(device) == STA_DEVICE()))) - { - err = rt_wlan_set_mode(dev_name, RT_WLAN_NONE); - if (err != RT_EOK) - { - RT_WLAN_LOG_E("change mode failed!"); - MGNT_UNLOCK(); - return err; - } - } - - /* init device */ - err = rt_wlan_dev_init(RT_WLAN_DEVICE(device), mode); - if (err != RT_EOK) - { - RT_WLAN_LOG_E("F:%s L:%d wlan init failed", __FUNCTION__, __LINE__); - MGNT_UNLOCK(); - return err; - } - - /* the mode is none */ - if (mode == RT_WLAN_NONE) - { - if (_sta_mgnt.device == RT_WLAN_DEVICE(device)) - { - _sta_mgnt.device = RT_NULL; - _sta_mgnt.state = 0; - up_event_flag = 1; - handler = RT_NULL; - } - else if (_ap_mgnt.device == RT_WLAN_DEVICE(device)) - { - _ap_mgnt.state = 0; - _ap_mgnt.device = RT_NULL; - up_event_flag = 1; - handler = RT_NULL; - } - } - /* save sta device */ - else if (mode == RT_WLAN_STATION) - { - up_event_flag = 1; - handler = rt_wlan_event_dispatch; - _sta_mgnt.device = RT_WLAN_DEVICE(device); - } - /* save ap device */ - else if (mode == RT_WLAN_AP) - { - up_event_flag = 1; - handler = rt_wlan_event_dispatch; - _ap_mgnt.device = RT_WLAN_DEVICE(device); - } - - /* update dev event handle */ - if (up_event_flag == 1) - { - if (handler) - { - if (mode == RT_WLAN_STATION) - { - rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_CONNECT, handler, RT_NULL); - rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_CONNECT_FAIL, handler, RT_NULL); - rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_DISCONNECT, handler, RT_NULL); - rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_SCAN_REPORT, handler, RT_NULL); - rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_SCAN_DONE, handler, RT_NULL); - } - else if (mode == RT_WLAN_AP) - { - rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_START, handler, RT_NULL); - rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_STOP, handler, RT_NULL); - rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_ASSOCIATED, handler, RT_NULL); - rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_DISASSOCIATED, handler, RT_NULL); - rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_ASSOCIATE_FAILED, handler, RT_NULL); - } - } - else - { - rt_wlan_dev_event_t event; - handler = rt_wlan_event_dispatch; - for (event = RT_WLAN_DEV_EVT_INIT_DONE; event < RT_WLAN_DEV_EVT_MAX; event++) - { - rt_wlan_dev_unregister_event_handler(RT_WLAN_DEVICE(device), event, handler); - } - } - } - MGNT_UNLOCK(); - - /* Mount protocol */ -#if defined(RT_WLAN_PROT_ENABLE) && defined(RT_WLAN_DEFAULT_PROT) - if (err == RT_EOK) - { - rt_wlan_prot_attach(dev_name, RT_WLAN_DEFAULT_PROT); - } -#endif - return err; -} - -rt_wlan_mode_t rt_wlan_get_mode(const char *dev_name) -{ - rt_device_t device = RT_NULL; - rt_wlan_mode_t mode; - - if (dev_name == RT_NULL) - { - RT_WLAN_LOG_E("name is null"); - return RT_WLAN_NONE; - } - - /* find device */ - device = rt_device_find(dev_name); - if (device == RT_NULL) - { - RT_WLAN_LOG_E("device not find! name:%s", dev_name); - return RT_WLAN_NONE; - } - - /* get mode */ - mode = RT_WLAN_DEVICE(device)->mode; - RT_WLAN_LOG_D("%s is run dev_name:%s mode:%s%s%s", __FUNCTION__, dev_name, - mode == RT_WLAN_NONE ? "NONE" : "", - mode == RT_WLAN_STATION ? "STA" : "", - mode == RT_WLAN_AP ? "AP" : ""); - - return mode; -} - -#ifdef RT_WLAN_JOIN_SCAN_BY_MGNT -static void rt_wlan_join_scan_callback(int event, struct rt_wlan_buff *buff, void *parameter) -{ - struct rt_wlan_info *info = RT_NULL; - struct rt_wlan_info *tgt_info = RT_NULL; - - RT_ASSERT(event == RT_WLAN_EVT_SCAN_REPORT); - RT_ASSERT(buff != RT_NULL); - RT_ASSERT(parameter != RT_NULL); - - info = (struct rt_wlan_info *)buff->data; - tgt_info = (struct rt_wlan_info *)parameter; - - - RT_WLAN_LOG_D("%s info len:%d tgt info len:%d", __FUNCTION__,info->ssid.len,tgt_info->ssid.len); - RT_WLAN_LOG_D("%s info ssid:%s tgt info ssid:%s", __FUNCTION__,&info->ssid.val[0],&tgt_info->ssid.val[0]); - - if(rt_memcmp(&info->ssid.val[0], &tgt_info->ssid.val[0], info->ssid.len) == 0 && - info->ssid.len == tgt_info->ssid.len) - { - /*Get the rssi the max ap*/ - if((info->rssi > tgt_info->rssi) || (tgt_info->rssi == 0)) - { - tgt_info->security = info->security; - tgt_info->band = info->band; - tgt_info->datarate = info->datarate; - tgt_info->channel = info->channel; - tgt_info->rssi = info->rssi; - tgt_info->hidden = info->hidden; - /* hwaddr */ - rt_memcpy(tgt_info->bssid,info->bssid,RT_WLAN_BSSID_MAX_LENGTH); - } - } -} -#endif - -rt_err_t rt_wlan_connect(const char *ssid, const char *password) -{ - rt_err_t err = RT_EOK; - int ssid_len = 0; - struct rt_wlan_info info; - struct rt_wlan_complete_des *complete; - rt_uint32_t set = 0, recved = 0; - - /* sta dev Can't be NULL */ - if (_sta_is_null()) - { - return -RT_EIO; - } - RT_WLAN_LOG_D("%s is run ssid:%s password:%s", __FUNCTION__, ssid, password); - if (ssid == RT_NULL) - { - RT_WLAN_LOG_E("ssid is null!"); - return -RT_EINVAL; - } - ssid_len = rt_strlen(ssid); - if (ssid_len > RT_WLAN_SSID_MAX_LENGTH) - { - RT_WLAN_LOG_E("ssid is to long! ssid:%s len:%d", ssid, ssid_len); - return -RT_EINVAL; - } - - if ((rt_wlan_is_connected() == RT_TRUE) && - (rt_strcmp((char *)&_sta_mgnt.info.ssid.val[0], ssid) == 0)) - { - RT_WLAN_LOG_I("wifi is connect ssid:%s", ssid); - return RT_EOK; - } - /* get info from cache */ - INVALID_INFO(&info); - MGNT_LOCK(); - - rt_memcpy(&info.ssid.val[0],ssid,rt_strlen(ssid)); - info.ssid.len = rt_strlen(ssid); - -#ifdef RT_WLAN_JOIN_SCAN_BY_MGNT - err = rt_wlan_register_event_handler(RT_WLAN_EVT_SCAN_REPORT,rt_wlan_join_scan_callback,&info); - if(err != RT_EOK) - { - LOG_E("Scan register user callback error:%d!\n",err); - return err; - } - - err = rt_wlan_scan_with_info(&info); - if(err != RT_EOK) - { - LOG_E("Scan with info error:%d!\n",err); - return err; - } - - if (info.channel <= 0) - { - RT_WLAN_LOG_W("not find ap! ssid:%s,info.ssid.len=%d", ssid,info.ssid.len); - MGNT_UNLOCK(); - return -RT_ERROR; - } - - RT_WLAN_LOG_D("find best info ssid:%s mac: %02x %02x %02x %02x %02x %02x", - info.ssid.val, info.bssid[0], info.bssid[1], info.bssid[2], info.bssid[3], info.bssid[4], info.bssid[5]); -#endif - - /* create event wait complete */ - complete = rt_wlan_complete_create("join"); - if (complete == RT_NULL) - { - MGNT_UNLOCK(); - return -RT_ENOMEM; - } - /* run connect adv */ - err = rt_wlan_connect_adv(&info, password); - if (err != RT_EOK) - { - rt_wlan_complete_delete(complete); - MGNT_UNLOCK(); - return err; - } - - /* Initializing events that need to wait */ - set |= 0x1 << RT_WLAN_DEV_EVT_CONNECT; - set |= 0x1 << RT_WLAN_DEV_EVT_CONNECT_FAIL; - /* Check whether there is a waiting event */ - rt_wlan_complete_wait(complete, set, RT_WLAN_CONNECT_WAIT_MS, &recved); - rt_wlan_complete_delete(complete); - /* check event */ - set = 0x1 << RT_WLAN_DEV_EVT_CONNECT; - if (!(recved & set)) - { - RT_WLAN_LOG_I("wifi connect failed!"); - MGNT_UNLOCK(); - return -RT_ERROR; - } - MGNT_UNLOCK(); - return err; -} - -rt_err_t rt_wlan_connect_adv(struct rt_wlan_info *info, const char *password) -{ - int password_len = 0; - rt_err_t err = RT_EOK; - - if (_sta_is_null()) - { - return -RT_EIO; - } - if (info == RT_NULL) - { - RT_WLAN_LOG_E("info is null!"); - return -RT_EINVAL; - } - RT_WLAN_LOG_D("%s is run ssid:%s password:%s", __FUNCTION__, info->ssid.val, password); - /* Parameter checking */ - if (password != RT_NULL) - { - password_len = rt_strlen(password); - if (password_len > RT_WLAN_PASSWORD_MAX_LENGTH) - { - RT_WLAN_LOG_E("password is to long! password:%s len:%d", password, password_len); - return -RT_EINVAL; - } - } - if (info->ssid.len == 0 || info->ssid.len > RT_WLAN_SSID_MAX_LENGTH) - { - RT_WLAN_LOG_E("ssid is zero or to long! ssid:%s len:%d", info->ssid.val, info->ssid.len); - return -RT_EINVAL; - } - /* is connect ? */ - MGNT_LOCK(); - if (rt_wlan_is_connected()) - { - if ((_sta_mgnt.info.ssid.len == info->ssid.len) && - (_sta_mgnt.key.len == password_len) && - (rt_memcmp(&_sta_mgnt.info.ssid.val[0], &info->ssid.val[0], info->ssid.len) == 0) && - (rt_memcmp(&_sta_mgnt.info.bssid[0], &info->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0) && - (rt_memcmp(&_sta_mgnt.key.val[0], password, password_len) == 0)) - { - RT_WLAN_LOG_I("wifi Already Connected"); - MGNT_UNLOCK(); - return RT_EOK; - } - - err = rt_wlan_disconnect(); - if (err != RT_EOK) - { - MGNT_UNLOCK(); - return err; - } - } - - /* save info */ - rt_enter_critical(); - _sta_mgnt.info = *info; - rt_memcpy(&_sta_mgnt.key.val, password, password_len); - _sta_mgnt.key.len = password_len; - _sta_mgnt.key.val[password_len] = '\0'; - rt_exit_critical(); - /* run wifi connect */ - _sta_mgnt.state |= RT_WLAN_STATE_CONNECTING; - - err = rt_wlan_dev_fast_connect(_sta_mgnt.device, info, password, password_len); - if(err != RT_EOK) - { - err = rt_wlan_dev_connect(_sta_mgnt.device, info, password, password_len); - if (err != RT_EOK) - { - rt_enter_critical(); - rt_memset(&_sta_mgnt.info, 0, sizeof(struct rt_wlan_ssid)); - rt_memset(&_sta_mgnt.key, 0, sizeof(struct rt_wlan_key)); - rt_exit_critical(); - _sta_mgnt.state &= ~RT_WLAN_STATE_CONNECTING; - MGNT_UNLOCK(); - return err; - } - } - - MGNT_UNLOCK(); - return err; -} - -rt_err_t rt_wlan_disconnect(void) -{ - rt_err_t err; - struct rt_wlan_complete_des *complete; - rt_uint32_t recved = 0, set = 0; - - /* ap dev Can't be empty */ - if (_sta_is_null()) - { - return -RT_EIO; - } - RT_WLAN_LOG_D("%s is run", __FUNCTION__); - - /* run disconnect */ - MGNT_LOCK(); - /* create event wait complete */ - complete = rt_wlan_complete_create("disc"); - if (complete == RT_NULL) - { - MGNT_UNLOCK(); - return -RT_ENOMEM; - } - err = rt_wlan_dev_disconnect(_sta_mgnt.device); - if (err != RT_EOK) - { - RT_WLAN_LOG_E("wifi disconnect fail"); - rt_wlan_complete_delete(complete); - MGNT_UNLOCK(); - return err; - } - /* Initializing events that need to wait */ - set |= 0x1 << RT_WLAN_DEV_EVT_DISCONNECT; - /* Check whether there is a waiting event */ - rt_wlan_complete_wait(complete, set, RT_WLAN_CONNECT_WAIT_MS, &recved); - rt_wlan_complete_delete(complete); - /* check event */ - set = 0x1 << RT_WLAN_DEV_EVT_DISCONNECT; - if (!(recved & set)) - { - RT_WLAN_LOG_E("disconnect failed!"); - MGNT_UNLOCK(); - return -RT_ERROR; - } - RT_WLAN_LOG_I("disconnect success!"); - MGNT_UNLOCK(); - return err; -} - -rt_bool_t rt_wlan_is_connected(void) -{ - rt_bool_t _connect; - - if (_sta_is_null()) - { - return RT_FALSE; - } - _connect = _sta_mgnt.state & RT_WLAN_STATE_CONNECT ? RT_TRUE : RT_FALSE; - RT_WLAN_LOG_D("%s is run : %s", __FUNCTION__, _connect ? "connect" : "disconnect"); - return _connect; -} - -rt_bool_t rt_wlan_is_ready(void) -{ - rt_bool_t _ready; - - if (_sta_is_null()) - { - return RT_FALSE; - } - _ready = _sta_mgnt.state & RT_WLAN_STATE_READY ? RT_TRUE : RT_FALSE; - RT_WLAN_LOG_D("%s is run : %s", __FUNCTION__, _ready ? "ready" : "not ready"); - return _ready; -} - -rt_err_t rt_wlan_set_mac(rt_uint8_t mac[6]) -{ - rt_err_t err = RT_EOK; - - if (_sta_is_null()) - { - return -RT_EIO; - } - RT_WLAN_LOG_D("%s is run mac: %02x:%02x:%02x:%02x:%02x:%02x", - __FUNCTION__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - MGNT_LOCK(); - err = rt_wlan_dev_set_mac(STA_DEVICE(), mac); - if (err != RT_EOK) - { - RT_WLAN_LOG_E("set sta mac addr fail"); - MGNT_UNLOCK(); - return err; - } - MGNT_UNLOCK(); - return err; -} - -rt_err_t rt_wlan_get_mac(rt_uint8_t mac[6]) -{ - rt_err_t err = RT_EOK; - - if (_sta_is_null()) - { - return -RT_EIO; - } - MGNT_LOCK(); - err = rt_wlan_dev_get_mac(STA_DEVICE(), mac); - if (err != RT_EOK) - { - RT_WLAN_LOG_E("get sta mac addr fail"); - MGNT_UNLOCK(); - return err; - } - RT_WLAN_LOG_D("%s is run mac: %02x:%02x:%02x:%02x:%02x:%02x", - __FUNCTION__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - MGNT_UNLOCK(); - return err; -} - -rt_err_t rt_wlan_get_info(struct rt_wlan_info *info) -{ - if (_sta_is_null()) - { - return -RT_EIO; - } - RT_WLAN_LOG_D("%s is run", __FUNCTION__); - - if (rt_wlan_is_connected() == RT_TRUE) - { - /* Initialize the information to the scan first */ - *info = _sta_mgnt.info; - /* Try using get_info's API for more new information */ - if (rt_wlan_dev_get_info(STA_DEVICE(), info) != RT_EOK) - { - /* The get_info returns an error and gets the rssi value separately */ - info->rssi = rt_wlan_get_rssi(); - } - return RT_EOK; - } - return -RT_ERROR; -} - -int rt_wlan_get_rssi(void) -{ - int rssi = 0; - - if (_sta_is_null()) - { - return -RT_EIO; - } - - MGNT_LOCK(); - rssi = rt_wlan_dev_get_rssi(STA_DEVICE()); - RT_WLAN_LOG_D("%s is run rssi:%d", __FUNCTION__, rssi); - MGNT_UNLOCK(); - return rssi; -} - -rt_err_t rt_wlan_start_ap(const char *ssid, const char *password) -{ - rt_err_t err = RT_EOK; - int ssid_len = 0; - struct rt_wlan_info info; - struct rt_wlan_complete_des *complete; - rt_uint32_t set = 0, recved = 0; - - if (_ap_is_null()) - { - return -RT_EIO; - } - if (ssid == RT_NULL) return -RT_EINVAL; - - rt_memset(&info, 0, sizeof(struct rt_wlan_info)); - RT_WLAN_LOG_D("%s is run ssid:%s password:%s", __FUNCTION__, ssid, password); - if (password) - { - info.security = SECURITY_WPA2_AES_PSK; - } - ssid_len = rt_strlen(ssid); - if (ssid_len > RT_WLAN_SSID_MAX_LENGTH) - { - RT_WLAN_LOG_E("ssid is to long! len:%d", ssid_len); - } - - /* copy info */ - rt_memcpy(&info.ssid.val, ssid, ssid_len); - info.ssid.len = ssid_len; - info.channel = 6; - info.band = RT_802_11_BAND_2_4GHZ; - - /* Initializing events that need to wait */ - MGNT_LOCK(); - /* create event wait complete */ - complete = rt_wlan_complete_create("start_ap"); - if (complete == RT_NULL) - { - MGNT_UNLOCK(); - return -RT_ENOMEM; - } - - /* start ap */ - err = rt_wlan_start_ap_adv(&info, password); - if (err != RT_EOK) - { - rt_wlan_complete_delete(complete); - RT_WLAN_LOG_I("start ap failed!"); - MGNT_UNLOCK(); - return err; - } - - /* Initializing events that need to wait */ - set |= 0x1 << RT_WLAN_DEV_EVT_AP_START; - set |= 0x1 << RT_WLAN_DEV_EVT_AP_STOP; - /* Check whether there is a waiting event */ - rt_wlan_complete_wait(complete, set, RT_WLAN_START_AP_WAIT_MS, &recved); - rt_wlan_complete_delete(complete); - /* check event */ - set = 0x1 << RT_WLAN_DEV_EVT_AP_START; - if (!(recved & set)) - { - RT_WLAN_LOG_I("start ap failed!"); - MGNT_UNLOCK(); - return -RT_ERROR; - } - RT_WLAN_LOG_I("start ap successs!"); - MGNT_UNLOCK(); - return err; -} - -rt_err_t rt_wlan_start_ap_adv(struct rt_wlan_info *info, const char *password) -{ - rt_err_t err = RT_EOK; - int password_len = 0; - - if (_ap_is_null()) - { - return -RT_EIO; - } - RT_WLAN_LOG_D("%s is run", __FUNCTION__); - if (password != RT_NULL) - { - password_len = rt_strlen(password); - } - if (password_len > RT_WLAN_PASSWORD_MAX_LENGTH) - { - RT_WLAN_LOG_E("key is to long! len:%d", password_len); - return -RT_EINVAL; - } - /* is start up ? */ - MGNT_LOCK(); - if (rt_wlan_ap_is_active()) - { - if ((_ap_mgnt.info.ssid.len == info->ssid.len) && - (_ap_mgnt.info.security == info->security) && - (_ap_mgnt.info.channel == info->channel) && - (_ap_mgnt.info.hidden == info->hidden) && - (_ap_mgnt.key.len == password_len) && - (rt_memcmp(&_ap_mgnt.info.ssid.val[0], &info->ssid.val[0], info->ssid.len) == 0) && - (rt_memcmp(&_ap_mgnt.key.val[0], password, password_len))) - { - RT_WLAN_LOG_D("wifi Already Start"); - MGNT_UNLOCK(); - return RT_EOK; - } - } - - err = rt_wlan_dev_ap_start(AP_DEVICE(), info, password, password_len); - if (err != RT_EOK) - { - MGNT_UNLOCK(); - return err; - } - rt_memcpy(&_ap_mgnt.info, info, sizeof(struct rt_wlan_info)); - rt_memcpy(&_ap_mgnt.key.val, password, password_len); - _ap_mgnt.key.len = password_len; - - MGNT_UNLOCK(); - return err; -} - -rt_bool_t rt_wlan_ap_is_active(void) -{ - rt_bool_t _active = RT_FALSE; - - if (_ap_is_null()) - { - return RT_FALSE; - } - - _active = _ap_mgnt.state & RT_WLAN_STATE_ACTIVE ? RT_TRUE : RT_FALSE; - RT_WLAN_LOG_D("%s is run active:%s", __FUNCTION__, _active ? "Active" : "Inactive"); - return _active; -} - -rt_err_t rt_wlan_ap_stop(void) -{ - rt_err_t err = RT_EOK; - struct rt_wlan_complete_des *complete; - rt_uint32_t set = 0, recved = 0; - - if (_ap_is_null()) - { - return -RT_EIO; - } - RT_WLAN_LOG_D("%s is run", __FUNCTION__); - - MGNT_LOCK(); - /* create event wait complete */ - complete = rt_wlan_complete_create("stop_ap"); - if (complete == RT_NULL) - { - MGNT_UNLOCK(); - return -RT_ENOMEM; - } - err = rt_wlan_dev_ap_stop(AP_DEVICE()); - if (err != RT_EOK) - { - RT_WLAN_LOG_E("ap stop fail"); - rt_wlan_complete_delete(complete); - MGNT_UNLOCK(); - return err; - } - /* Initializing events that need to wait */ - set |= 0x1 << RT_WLAN_DEV_EVT_AP_STOP; - /* Check whether there is a waiting event */ - rt_wlan_complete_wait(complete, set, RT_WLAN_START_AP_WAIT_MS, &recved); - rt_wlan_complete_delete(complete); - /* check event */ - set = 0x1 << RT_WLAN_DEV_EVT_AP_STOP; - if (!(recved & set)) - { - RT_WLAN_LOG_I("ap stop failed!"); - MGNT_UNLOCK(); - return -RT_ERROR; - } - RT_WLAN_LOG_I("ap stop success!"); - MGNT_UNLOCK(); - return err; -} - -rt_err_t rt_wlan_ap_get_info(struct rt_wlan_info *info) -{ - if (_ap_is_null()) - { - return -RT_EIO; - } - RT_WLAN_LOG_D("%s is run", __FUNCTION__); - - if (rt_wlan_ap_is_active() == RT_TRUE) - { - *info = _ap_mgnt.info; - if (rt_wlan_dev_ap_get_info(AP_DEVICE(), info) != RT_EOK) - { - RT_WLAN_LOG_E("get ap info failed!"); - return -RT_ERROR; - } - return RT_EOK; - } - return -RT_ERROR; -} - -/* get sta number */ -int rt_wlan_ap_get_sta_num(void) -{ - int sta_num = 0; - - STAINFO_LOCK(); - sta_num = sta_info.num; - STAINFO_UNLOCK(); - RT_WLAN_LOG_D("%s is run num:%d", __FUNCTION__, sta_num); - return sta_num; -} - -/* get sta info */ -int rt_wlan_ap_get_sta_info(struct rt_wlan_info *info, int num) -{ - int sta_num = 0, i = 0; - struct rt_wlan_sta_list *sta_list; - - STAINFO_LOCK(); - /* sta_num = min(sta_info.num, num) */ - sta_num = sta_info.num > num ? num : sta_info.num; - for (sta_list = sta_info.node; sta_list != RT_NULL && i < sta_num; sta_list = sta_list->next) - { - info[i] = sta_list->info; - i ++; - } - STAINFO_UNLOCK(); - RT_WLAN_LOG_D("%s is run num:%d", __FUNCTION__, i); - return i; -} - -/* deauth sta */ -rt_err_t rt_wlan_ap_deauth_sta(rt_uint8_t *mac) -{ - rt_err_t err = RT_EOK; - struct rt_wlan_sta_list *sta_list; - rt_bool_t find_flag = RT_FALSE; - - if (_ap_is_null()) - { - return -RT_EIO; - } - RT_WLAN_LOG_D("%s is run mac: %02x:%02x:%02x:%02x:%02x:%02x:%d", - __FUNCTION__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - if (mac == RT_NULL) - { - RT_WLAN_LOG_E("mac addr is null"); - return -RT_EINVAL; - } - - MGNT_LOCK(); - if (sta_info.node == RT_NULL || sta_info.num == 0) - { - RT_WLAN_LOG_E("No AP"); - MGNT_UNLOCK(); - return -RT_ERROR; - } - - STAINFO_LOCK(); - /* Search for MAC address from sta list */ - for (sta_list = sta_info.node; sta_list != RT_NULL; sta_list = sta_list->next) - { - if (rt_memcmp(&sta_list->info.bssid[0], &mac[0], RT_WLAN_BSSID_MAX_LENGTH) == 0) - { - find_flag = RT_TRUE; - break; - } - } - STAINFO_UNLOCK(); - - /* No MAC address was found. return */ - if (find_flag != RT_TRUE) - { - RT_WLAN_LOG_E("Not find mac addr"); - MGNT_UNLOCK(); - return -RT_ERROR; - } - - /* Kill STA */ - err = rt_wlan_dev_ap_deauth(AP_DEVICE(), mac); - if (err != RT_NULL) - { - RT_WLAN_LOG_E("deauth sta failed"); - MGNT_UNLOCK(); - return err; - } - - MGNT_UNLOCK(); - return err; -} - -rt_err_t rt_wlan_ap_set_country(rt_country_code_t country_code) -{ - rt_err_t err = RT_EOK; - - if (_ap_is_null()) - { - return -RT_EIO; - } - RT_WLAN_LOG_D("%s is run country:%d", __FUNCTION__, country_code); - MGNT_LOCK(); - err = rt_wlan_dev_set_country(AP_DEVICE(), country_code); - MGNT_UNLOCK(); - return err; -} - -rt_country_code_t rt_wlan_ap_get_country(void) -{ - rt_country_code_t country_code = RT_COUNTRY_UNKNOWN; - - if (_ap_is_null()) - { - return country_code; - } - MGNT_LOCK(); - country_code = rt_wlan_dev_get_country(AP_DEVICE()); - RT_WLAN_LOG_D("%s is run country:%d", __FUNCTION__, country_code); - MGNT_UNLOCK(); - return country_code; -} - -void rt_wlan_config_autoreconnect(rt_bool_t enable) -{ -#ifdef RT_WLAN_AUTO_CONNECT_ENABLE - RT_WLAN_LOG_D("%s is run enable:%d", __FUNCTION__, enable); - - MGNT_LOCK(); - if (enable) - { - TIME_START(); - _sta_mgnt.flags |= RT_WLAN_STATE_AUTOEN; - } - else - { - TIME_STOP(); - _sta_mgnt.flags &= ~RT_WLAN_STATE_AUTOEN; - } - MGNT_UNLOCK(); -#endif -} - -rt_bool_t rt_wlan_get_autoreconnect_mode(void) -{ -#ifdef RT_WLAN_AUTO_CONNECT_ENABLE - rt_bool_t enable = 0; - - enable = _sta_mgnt.flags & RT_WLAN_STATE_AUTOEN ? 1 : 0; - RT_WLAN_LOG_D("%s is run enable:%d", __FUNCTION__, enable); - return enable; -#else - return RT_FALSE; -#endif -} - -/* Call the underlying scan function, which is asynchronous. -The hotspots scanned are returned by callbacks */ -rt_err_t rt_wlan_scan(void) -{ - rt_err_t err = RT_EOK; - - if (_sta_is_null()) - { - return -RT_EIO; - } - RT_WLAN_LOG_D("%s is run", __FUNCTION__); - - MGNT_LOCK(); - err = rt_wlan_dev_scan(STA_DEVICE(), RT_NULL); - MGNT_UNLOCK(); - return err; -} - -rt_err_t rt_wlan_scan_with_info(struct rt_wlan_info *info) -{ - rt_err_t err = RT_EOK; - struct rt_wlan_complete_des *complete; - rt_uint32_t set = 0, recved = 0; - - if (_sta_is_null()) - { - return -RT_EINVAL; - } - RT_WLAN_LOG_D("%s is run", __FUNCTION__); - if (info != RT_NULL && info->ssid.len > RT_WLAN_SSID_MAX_LENGTH) - { - RT_WLAN_LOG_E("ssid is to long!"); - return -RT_EINVAL; - } - - /* Create an event that needs to wait. */ - MGNT_LOCK(); - complete = rt_wlan_complete_create("scan"); - if (complete == RT_NULL) - { - MGNT_UNLOCK(); - return -RT_EIO; - } - - /* run scan */ - err = rt_wlan_dev_scan(STA_DEVICE(), info); - if (err != RT_EOK) - { - rt_wlan_complete_delete(complete); - MGNT_UNLOCK(); - RT_WLAN_LOG_E("scan sync fail"); - return -RT_ERROR; - } - - /* Initializing events that need to wait */ - set |= 0x1 << RT_WLAN_DEV_EVT_SCAN_DONE; - /* Check whether there is a waiting event */ - rt_wlan_complete_wait(complete, set, RT_WLAN_CONNECT_WAIT_MS, &recved); - rt_wlan_complete_delete(complete); - /* check event */ - set = 0x1 << RT_WLAN_DEV_EVT_SCAN_DONE; - if (!(recved & set)) - { - MGNT_UNLOCK(); - RT_WLAN_LOG_E("scan wait timeout!"); - return -RT_ETIMEOUT; - } - - MGNT_UNLOCK(); - return RT_EOK; -} - -rt_err_t rt_wlan_set_powersave(int level) -{ - rt_err_t err = RT_EOK; - - if (_sta_is_null()) - { - return -RT_EIO; - } - RT_WLAN_LOG_D("%s is run", __FUNCTION__); - MGNT_LOCK(); - err = rt_wlan_dev_set_powersave(STA_DEVICE(), level); - MGNT_UNLOCK(); - return err; -} - -int rt_wlan_get_powersave(void) -{ - int level; - - if (_sta_is_null()) - { - return -1; - } - RT_WLAN_LOG_D("%s is run", __FUNCTION__); - MGNT_LOCK(); - level = rt_wlan_dev_get_powersave(STA_DEVICE()); - MGNT_UNLOCK(); - return level; -} - -rt_err_t rt_wlan_register_event_handler(rt_wlan_event_t event, rt_wlan_event_handler handler, void *parameter) -{ - rt_base_t level; - - if (event >= RT_WLAN_EVT_MAX) - { - return -RT_EINVAL; - } - RT_WLAN_LOG_D("%s is run event:%d", __FUNCTION__, event); - - MGNT_LOCK(); - /* Registering Callbacks */ - level = rt_hw_interrupt_disable(); - event_tab[event].handler = handler; - event_tab[event].parameter = parameter; - rt_hw_interrupt_enable(level); - MGNT_UNLOCK(); - return RT_EOK; -} - -rt_err_t rt_wlan_unregister_event_handler(rt_wlan_event_t event) -{ - rt_base_t level; - - if (event >= RT_WLAN_EVT_MAX) - { - return -RT_EINVAL; - } - RT_WLAN_LOG_D("%s is run event:%d", __FUNCTION__, event); - MGNT_LOCK(); - /* unregister*/ - level = rt_hw_interrupt_disable(); - event_tab[event].handler = RT_NULL; - event_tab[event].parameter = RT_NULL; - rt_hw_interrupt_enable(level); - MGNT_UNLOCK(); - return RT_EOK; -} - -void rt_wlan_mgnt_lock(void) -{ - MGNT_LOCK(); -} - -void rt_wlan_mgnt_unlock(void) -{ - MGNT_UNLOCK(); -} - -int rt_wlan_prot_ready_event(struct rt_wlan_device *wlan, struct rt_wlan_buff *buff) -{ - rt_base_t level; - - if ((wlan == RT_NULL) || (_sta_mgnt.device != wlan) || - (!(_sta_mgnt.state & RT_WLAN_STATE_CONNECT))) - { - return -1; - } - if (_sta_mgnt.state & RT_WLAN_STATE_READY) - { - return 0; - } - level = rt_hw_interrupt_disable(); - _sta_mgnt.state |= RT_WLAN_STATE_READY; - rt_hw_interrupt_enable(level); -#ifdef RT_WLAN_WORK_THREAD_ENABLE - rt_wlan_send_to_thread(RT_WLAN_EVT_READY, buff->data, buff->len); -#else - { - void *user_parameter; - rt_wlan_event_handler handler = RT_NULL; - - level = rt_hw_interrupt_disable(); - handler = event_tab[RT_WLAN_EVT_READY].handler; - user_parameter = event_tab[RT_WLAN_EVT_READY].parameter; - rt_hw_interrupt_enable(level); - if (handler) - { - handler(RT_WLAN_EVT_READY, buff, user_parameter); - } - } -#endif - return 0; -} - -int rt_wlan_init(void) -{ - static rt_int8_t _init_flag = 0; - - /* Execute only once */ - if (_init_flag == 0) - { - rt_memset(&_sta_mgnt, 0, sizeof(struct rt_wlan_mgnt_des)); - rt_memset(&_ap_mgnt, 0, sizeof(struct rt_wlan_mgnt_des)); - rt_memset(&sta_info, 0, sizeof(struct rt_wlan_sta_des)); - rt_mutex_init(&mgnt_mutex, "mgnt", RT_IPC_FLAG_FIFO); - rt_mutex_init(&sta_info_mutex, "sta", RT_IPC_FLAG_FIFO); - rt_mutex_init(&complete_mutex, "complete", RT_IPC_FLAG_FIFO); -#ifdef RT_WLAN_AUTO_CONNECT_ENABLE - rt_timer_init(&reconnect_time, "wifi_tim", rt_wlan_cyclic_check, RT_NULL, - rt_tick_from_millisecond(AUTO_CONNECTION_PERIOD_MS), - RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER); -#endif - _init_flag = 1; - } - return 0; -} -INIT_PREV_EXPORT(rt_wlan_init); - -#endif diff --git a/rt-thread/components/drivers/wlan/dev_wlan_mgnt.h b/rt-thread/components/drivers/wlan/dev_wlan_mgnt.h deleted file mode 100644 index dc5b17e..0000000 --- a/rt-thread/components/drivers/wlan/dev_wlan_mgnt.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-08-06 tyx the first version - */ - -#ifndef __DEV_WLAN_MGNT_H__ -#define __DEV_WLAN_MGNT_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef RT_WLAN_SCAN_WAIT_MS -#define RT_WLAN_SCAN_WAIT_MS (10 * 1000) -#endif - -#ifndef RT_WLAN_SCAN_CACHE_NUM -#define RT_WLAN_SCAN_CACHE_NUM (50) -#endif - -#ifndef RT_WLAN_CONNECT_WAIT_MS -#define RT_WLAN_CONNECT_WAIT_MS (10 * 1000) -#endif - -#ifndef RT_WLAN_START_AP_WAIT_MS -#define RT_WLAN_START_AP_WAIT_MS (10 * 1000) -#endif - -#ifndef RT_WLAN_EBOX_NUM -#define RT_WLAN_EBOX_NUM (10) -#endif - -#ifndef RT_WLAN_SCAN_RETRY_CNT -#define RT_WLAN_SCAN_RETRY_CNT (3) -#endif - -#ifndef AUTO_CONNECTION_PERIOD_MS -#define AUTO_CONNECTION_PERIOD_MS (2000) -#endif - -/*state fot station*/ -#define RT_WLAN_STATE_CONNECT (1UL << 0) -#define RT_WLAN_STATE_CONNECTING (1UL << 1) -#define RT_WLAN_STATE_READY (1UL << 2) -#define RT_WLAN_STATE_POWERSAVE (1UL << 3) - -/*flags fot station*/ -#define RT_WLAN_STATE_AUTOEN (1UL << 0) - -/*state fot ap*/ -#define RT_WLAN_STATE_ACTIVE (1UL << 0) - -typedef enum -{ - RT_WLAN_EVT_READY = 0, /* connect and prot is ok, You can send data*/ - RT_WLAN_EVT_SCAN_DONE, /* Scan a info */ - RT_WLAN_EVT_SCAN_REPORT, /* Scan end */ - RT_WLAN_EVT_STA_CONNECTED, /* connect success */ - RT_WLAN_EVT_STA_CONNECTED_FAIL, /* connection failed */ - RT_WLAN_EVT_STA_DISCONNECTED, /* disconnect */ - RT_WLAN_EVT_AP_START, /* AP start */ - RT_WLAN_EVT_AP_STOP, /* AP stop */ - RT_WLAN_EVT_AP_ASSOCIATED, /* sta associated */ - RT_WLAN_EVT_AP_DISASSOCIATED, /* sta disassociated */ - RT_WLAN_EVT_MAX -} rt_wlan_event_t; - -typedef void (*rt_wlan_event_handler)(int event, struct rt_wlan_buff *buff, void *parameter); - -struct rt_wlan_scan_result -{ - rt_int32_t num; - struct rt_wlan_info *info; -}; - -/* - * wifi init interface - */ -int rt_wlan_init(void); -rt_err_t rt_wlan_set_mode(const char *dev_name, rt_wlan_mode_t mode); -rt_wlan_mode_t rt_wlan_get_mode(const char *dev_name); - -/* - * wifi station mode interface - */ -rt_err_t rt_wlan_connect(const char *ssid, const char *password); -rt_err_t rt_wlan_connect_adv(struct rt_wlan_info *info, const char *password); -rt_err_t rt_wlan_disconnect(void); -rt_bool_t rt_wlan_is_connected(void); -rt_bool_t rt_wlan_is_ready(void); -rt_err_t rt_wlan_set_mac(rt_uint8_t *mac); -rt_err_t rt_wlan_get_mac(rt_uint8_t *mac); -rt_err_t rt_wlan_get_info(struct rt_wlan_info *info); -int rt_wlan_get_rssi(void); - -/* - * wifi ap mode interface - */ -rt_err_t rt_wlan_start_ap(const char *ssid, const char *password); -rt_err_t rt_wlan_start_ap_adv(struct rt_wlan_info *info, const char *password); -rt_bool_t rt_wlan_ap_is_active(void); -rt_err_t rt_wlan_ap_stop(void); -rt_err_t rt_wlan_ap_get_info(struct rt_wlan_info *info); -int rt_wlan_ap_get_sta_num(void); -int rt_wlan_ap_get_sta_info(struct rt_wlan_info *info, int num); -rt_err_t rt_wlan_ap_deauth_sta(rt_uint8_t *mac); -rt_err_t rt_wlan_ap_set_country(rt_country_code_t country_code); -rt_country_code_t rt_wlan_ap_get_country(void); - -/* - * wifi scan interface - */ -rt_err_t rt_wlan_scan(void); -struct rt_wlan_scan_result *rt_wlan_scan_sync(void); -rt_err_t rt_wlan_scan_with_info(struct rt_wlan_info *info); - - -/* - * wifi auto connect interface - */ -void rt_wlan_config_autoreconnect(rt_bool_t enable); -rt_bool_t rt_wlan_get_autoreconnect_mode(void); - -/* - * wifi power management interface - */ -rt_err_t rt_wlan_set_powersave(int level); -int rt_wlan_get_powersave(void); - -/* - * wifi event management interface - */ -rt_err_t rt_wlan_register_event_handler(rt_wlan_event_t event, rt_wlan_event_handler handler, void *parameter); -rt_err_t rt_wlan_unregister_event_handler(rt_wlan_event_t event); - -/* - * wifi management lock interface - */ -void rt_wlan_mgnt_lock(void); -void rt_wlan_mgnt_unlock(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/components/drivers/wlan/dev_wlan_prot.c b/rt-thread/components/drivers/wlan/dev_wlan_prot.c deleted file mode 100644 index 5373033..0000000 --- a/rt-thread/components/drivers/wlan/dev_wlan_prot.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-08-14 tyx the first version - */ - -#include -#include -#include -#include - -#define DBG_TAG "WLAN.prot" -#ifdef RT_WLAN_PROT_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_INFO -#endif /* RT_WLAN_PROT_DEBUG */ -#include - -#ifdef RT_WLAN_PROT_ENABLE - -#if RT_WLAN_PROT_NAME_LEN < 4 -#error "The name is too short" -#endif - -struct rt_wlan_prot_event_des -{ - rt_wlan_prot_event_handler handler; - struct rt_wlan_prot *prot; -}; - -static struct rt_wlan_prot *_prot[RT_WLAN_PROT_MAX]; - -static struct rt_wlan_prot_event_des prot_event_tab[RT_WLAN_PROT_EVT_MAX][RT_WLAN_PROT_MAX]; - -static void rt_wlan_prot_event_handle(struct rt_wlan_device *wlan, rt_wlan_dev_event_t event, struct rt_wlan_buff *buff, void *parameter) -{ - int i; - struct rt_wlan_prot *wlan_prot; - struct rt_wlan_prot *prot; - rt_wlan_prot_event_handler handler; - rt_wlan_prot_event_t prot_event; - - LOG_D("F:%s L:%d event:%d", __FUNCTION__, __LINE__, event); - - wlan_prot = wlan->prot; - handler = RT_NULL; - prot = RT_NULL; - switch (event) - { - case RT_WLAN_DEV_EVT_INIT_DONE: - { - LOG_D("L%d event: INIT_DONE", __LINE__); - prot_event = RT_WLAN_PROT_EVT_INIT_DONE; - break; - } - case RT_WLAN_DEV_EVT_CONNECT: - { - LOG_D("L%d event: CONNECT", __LINE__); - prot_event = RT_WLAN_PROT_EVT_CONNECT; - break; - } - case RT_WLAN_DEV_EVT_DISCONNECT: - { - LOG_D("L%d event: DISCONNECT", __LINE__); - prot_event = RT_WLAN_PROT_EVT_DISCONNECT; - break; - } - case RT_WLAN_DEV_EVT_AP_START: - { - LOG_D("L%d event: AP_START", __LINE__); - prot_event = RT_WLAN_PROT_EVT_AP_START; - break; - } - case RT_WLAN_DEV_EVT_AP_STOP: - { - LOG_D("L%d event: AP_STOP", __LINE__); - prot_event = RT_WLAN_PROT_EVT_AP_STOP; - break; - } - case RT_WLAN_DEV_EVT_AP_ASSOCIATED: - { - LOG_D("L%d event: AP_ASSOCIATED", __LINE__); - prot_event = RT_WLAN_PROT_EVT_AP_ASSOCIATED; - break; - } - case RT_WLAN_DEV_EVT_AP_DISASSOCIATED: - { - LOG_D("L%d event: AP_DISASSOCIATED", __LINE__); - prot_event = RT_WLAN_PROT_EVT_AP_DISASSOCIATED; - break; - } - default: - { - return; - } - } - for (i = 0; i < RT_WLAN_PROT_MAX; i++) - { - if ((prot_event_tab[prot_event][i].handler != RT_NULL) && - (prot_event_tab[prot_event][i].prot->id == wlan_prot->id)) - { - handler = prot_event_tab[prot_event][i].handler; - prot = prot_event_tab[prot_event][i].prot; - break; - } - } - - if (handler != RT_NULL) - { - handler(prot, wlan, prot_event); - } -} - -static struct rt_wlan_device *rt_wlan_prot_find_by_name(const char *name) -{ - rt_device_t device; - - if (name == RT_NULL) - { - LOG_E("F:%s L:%d Parameter Wrongful", __FUNCTION__, __LINE__); - return RT_NULL; - } - device = rt_device_find(name); - if (device == RT_NULL) - { - LOG_E("F:%s L:%d not find wlan dev!! name:%s", __FUNCTION__, __LINE__, name); - return RT_NULL; - } - return (struct rt_wlan_device *)device; -} - -rt_err_t rt_wlan_prot_attach(const char *dev_name, const char *prot_name) -{ - struct rt_wlan_device *wlan; - - wlan = rt_wlan_prot_find_by_name(dev_name); - if (wlan == RT_NULL) - { - return -RT_ERROR; - } - return rt_wlan_prot_attach_dev(wlan, prot_name); -} - -rt_err_t rt_wlan_prot_detach(const char *name) -{ - struct rt_wlan_device *wlan; - - wlan = rt_wlan_prot_find_by_name(name); - if (wlan == RT_NULL) - { - return -RT_ERROR; - } - return rt_wlan_prot_detach_dev(wlan); -} - -rt_err_t rt_wlan_prot_attach_dev(struct rt_wlan_device *wlan, const char *prot_name) -{ - int i = 0; - struct rt_wlan_prot *prot = wlan->prot; - rt_wlan_dev_event_handler handler = rt_wlan_prot_event_handle; - - if (wlan == RT_NULL) - { - LOG_E("F:%s L:%d wlan is null", __FUNCTION__, __LINE__); - return -RT_ERROR; - } - - if (prot != RT_NULL && - (rt_strcmp(prot->name, prot_name) == 0)) - { - LOG_D("prot is register"); - return RT_EOK; - } - - /* if prot not NULL */ - if (prot != RT_NULL) - rt_wlan_prot_detach_dev(wlan); - -#ifdef RT_WLAN_PROT_LWIP_PBUF_FORCE - if (rt_strcmp(RT_WLAN_PROT_LWIP_NAME, prot_name) != 0) - { - return -RT_ERROR; - } -#endif - /* find prot */ - for (i = 0; i < RT_WLAN_PROT_MAX; i++) - { - if ((_prot[i] != RT_NULL) && (rt_strcmp(_prot[i]->name, prot_name) == 0)) - { - /* attach prot */ - wlan->prot = _prot[i]->ops->dev_reg_callback(_prot[i], wlan); - break; - } - } - - if (i >= RT_WLAN_PROT_MAX) - { - LOG_E("F:%s L:%d not find wlan protocol", __FUNCTION__, __LINE__); - return -RT_ERROR; - } - - rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_CONNECT, handler, RT_NULL); - rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_DISCONNECT, handler, RT_NULL); - rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_START, handler, RT_NULL); - rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_STOP, handler, RT_NULL); - rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_ASSOCIATED, handler, RT_NULL); - rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_DISASSOCIATED, handler, RT_NULL); - - return RT_EOK; -} - -rt_err_t rt_wlan_prot_detach_dev(struct rt_wlan_device *wlan) -{ - struct rt_wlan_prot *prot = wlan->prot; - rt_wlan_dev_event_t event; - - if (prot == RT_NULL) - return RT_EOK; - - for (event = RT_WLAN_DEV_EVT_INIT_DONE; event < RT_WLAN_DEV_EVT_MAX; event ++) - { - rt_wlan_dev_unregister_event_handler(wlan, event, rt_wlan_prot_event_handle); - } - - /* detach prot */ - prot->ops->dev_unreg_callback(prot, wlan); - wlan->prot = RT_NULL; - - return RT_EOK; -} - -rt_err_t rt_wlan_prot_regisetr(struct rt_wlan_prot *prot) -{ - int i; - rt_uint32_t id; - static rt_uint8_t num; - - /* Parameter checking */ - if ((prot == RT_NULL) || - (prot->ops->prot_recv == RT_NULL) || - (prot->ops->dev_reg_callback == RT_NULL)) - { - LOG_E("F:%s L:%d Parameter Wrongful", __FUNCTION__, __LINE__); - return -RT_EINVAL; - } - - /* save prot */ - for (i = 0; i < RT_WLAN_PROT_MAX; i++) - { - if (_prot[i] == RT_NULL) - { - id = (RT_LWAN_ID_PREFIX << 16) | num; - prot->id = id; - _prot[i] = prot; - num ++; - break; - } - else if (rt_strcmp(_prot[i]->name, prot->name) == 0) - { - break; - } - } - - /* is full */ - if (i >= RT_WLAN_PROT_MAX) - { - LOG_E("F:%s L:%d Space full", __FUNCTION__, __LINE__); - return -RT_ERROR; - } - - return RT_EOK; -} - -rt_err_t rt_wlan_prot_event_register(struct rt_wlan_prot *prot, rt_wlan_prot_event_t event, rt_wlan_prot_event_handler handler) -{ - int i; - - if ((prot == RT_NULL) || (handler == RT_NULL)) - { - return -RT_EINVAL; - } - - for (i = 0; i < RT_WLAN_PROT_MAX; i++) - { - if (prot_event_tab[event][i].handler == RT_NULL) - { - prot_event_tab[event][i].handler = handler; - prot_event_tab[event][i].prot = prot; - return RT_EOK; - } - } - - return -RT_ERROR; -} - -rt_err_t rt_wlan_prot_event_unregister(struct rt_wlan_prot *prot, rt_wlan_prot_event_t event) -{ - int i; - - if (prot == RT_NULL) - { - return -RT_EINVAL; - } - - for (i = 0; i < RT_WLAN_PROT_MAX; i++) - { - if ((prot_event_tab[event][i].handler != RT_NULL) && - (prot_event_tab[event][i].prot == prot)) - { - rt_memset(&prot_event_tab[event][i], 0, sizeof(struct rt_wlan_prot_event_des)); - return RT_EOK; - } - } - - return -RT_ERROR; -} - -rt_err_t rt_wlan_prot_transfer_dev(struct rt_wlan_device *wlan, void *buff, int len) -{ - if (wlan->ops->wlan_send != RT_NULL) - { - return wlan->ops->wlan_send(wlan, buff, len); - } - return -RT_ERROR; -} - -rt_err_t rt_wlan_dev_transfer_prot(struct rt_wlan_device *wlan, void *buff, int len) -{ - struct rt_wlan_prot *prot = wlan->prot; - - if (prot != RT_NULL) - { - return prot->ops->prot_recv(wlan, buff, len); - } - return -RT_ERROR; -} - -extern int rt_wlan_prot_ready_event(struct rt_wlan_device *wlan, struct rt_wlan_buff *buff); -int rt_wlan_prot_ready(struct rt_wlan_device *wlan, struct rt_wlan_buff *buff) -{ - return rt_wlan_prot_ready_event(wlan, buff); -} - -void rt_wlan_prot_dump(void) -{ - int i; - - rt_kprintf(" name id \n"); - rt_kprintf("-------- --------\n"); - for (i = 0; i < RT_WLAN_PROT_MAX; i++) - { - if (_prot[i] != RT_NULL) - { - rt_kprintf("%-8.8s ", _prot[i]->name); - rt_kprintf("%08x\n", _prot[i]->id); - } - } -} -#endif diff --git a/rt-thread/components/drivers/wlan/dev_wlan_prot.h b/rt-thread/components/drivers/wlan/dev_wlan_prot.h deleted file mode 100644 index 3ba1daa..0000000 --- a/rt-thread/components/drivers/wlan/dev_wlan_prot.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-08-14 tyx the first version - */ - -#ifndef __DEV_WLAN_PROT_H__ -#define __DEV_WLAN_PROT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef RT_WLAN_PROT_NAME_LEN -#define RT_WLAN_PROT_NAME_LEN (8) -#endif - -#ifndef RT_WLAN_PROT_MAX -#define RT_WLAN_PROT_MAX (1) -#endif - -#define RT_LWAN_ID_PREFIX (0x5054) - -typedef enum -{ - RT_WLAN_PROT_EVT_INIT_DONE = 0, - RT_WLAN_PROT_EVT_CONNECT, - RT_WLAN_PROT_EVT_DISCONNECT, - RT_WLAN_PROT_EVT_AP_START, - RT_WLAN_PROT_EVT_AP_STOP, - RT_WLAN_PROT_EVT_AP_ASSOCIATED, - RT_WLAN_PROT_EVT_AP_DISASSOCIATED, - RT_WLAN_PROT_EVT_MAX, -} rt_wlan_prot_event_t; - -struct rt_wlan_prot; -struct rt_wlan_prot_ops -{ - rt_err_t (*prot_recv)(struct rt_wlan_device *wlan, void *buff, int len); - struct rt_wlan_prot *(*dev_reg_callback)(struct rt_wlan_prot *prot, struct rt_wlan_device *wlan); - void (*dev_unreg_callback)(struct rt_wlan_prot *prot, struct rt_wlan_device *wlan); -}; - -struct rt_wlan_prot -{ - char name[RT_WLAN_PROT_NAME_LEN]; - rt_uint32_t id; - const struct rt_wlan_prot_ops *ops; -}; - -typedef void (*rt_wlan_prot_event_handler)(struct rt_wlan_prot *port, struct rt_wlan_device *wlan, int event); - -rt_err_t rt_wlan_prot_attach(const char *dev_name, const char *prot_name); - -rt_err_t rt_wlan_prot_attach_dev(struct rt_wlan_device *wlan, const char *prot_name); - -rt_err_t rt_wlan_prot_detach(const char *dev_name); - -rt_err_t rt_wlan_prot_detach_dev(struct rt_wlan_device *wlan); - -rt_err_t rt_wlan_prot_regisetr(struct rt_wlan_prot *prot); - -rt_err_t rt_wlan_prot_transfer_dev(struct rt_wlan_device *wlan, void *buff, int len); - -rt_err_t rt_wlan_dev_transfer_prot(struct rt_wlan_device *wlan, void *buff, int len); - -rt_err_t rt_wlan_prot_event_register(struct rt_wlan_prot *prot, rt_wlan_prot_event_t event, rt_wlan_prot_event_handler handler); - -rt_err_t rt_wlan_prot_event_unregister(struct rt_wlan_prot *prot, rt_wlan_prot_event_t event); - -int rt_wlan_prot_ready(struct rt_wlan_device *wlan, struct rt_wlan_buff *buff); - -void rt_wlan_prot_dump(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/components/drivers/wlan/dev_wlan_workqueue.c b/rt-thread/components/drivers/wlan/dev_wlan_workqueue.c deleted file mode 100644 index c663a4e..0000000 --- a/rt-thread/components/drivers/wlan/dev_wlan_workqueue.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-08-19 tyx the first version - */ - -#include -#include -#include -#include - -#define DBG_TAG "WLAN.work" -#define DBG_LVL DBG_INFO -#include - -#ifdef RT_WLAN_WORK_THREAD_ENABLE - -struct rt_wlan_work -{ - struct rt_work work; - void (*fun)(void *parameter); - void *parameter; -}; - -static struct rt_workqueue *wlan_workqueue; - -static void rt_wlan_workqueue_fun(struct rt_work *work, void *work_data) -{ - struct rt_wlan_work *wlan_work = work_data; - - wlan_work->fun(wlan_work->parameter); - rt_free(wlan_work); -} - -struct rt_workqueue *rt_wlan_get_workqueue(void) -{ - return wlan_workqueue; -} - -rt_err_t rt_wlan_workqueue_dowork(void (*func)(void *parameter), void *parameter) -{ - struct rt_wlan_work *wlan_work; - rt_err_t err = RT_EOK; - - LOG_D("F:%s is run", __FUNCTION__); - if (func == RT_NULL) - { - LOG_E("F:%s L:%d func is null", __FUNCTION__, __LINE__); - return -RT_EINVAL; - } - - if (wlan_workqueue == RT_NULL) - { - LOG_E("F:%s L:%d not init wlan work queue", __FUNCTION__, __LINE__); - return -RT_ERROR; - } - - wlan_work = rt_malloc(sizeof(struct rt_wlan_work)); - if (wlan_work == RT_NULL) - { - LOG_E("F:%s L:%d create work failed", __FUNCTION__, __LINE__); - return -RT_ENOMEM; - } - wlan_work->fun = func; - wlan_work->parameter = parameter; - rt_work_init(&wlan_work->work, rt_wlan_workqueue_fun, wlan_work); - err = rt_workqueue_dowork(wlan_workqueue, &wlan_work->work); - if (err != RT_EOK) - { - LOG_E("F:%s L:%d do work failed", __FUNCTION__, __LINE__); - rt_free(wlan_work); - return err; - } - return err; -} - -int rt_wlan_workqueue_init(void) -{ - static rt_int8_t _init_flag = 0; - - if (_init_flag == 0) - { - wlan_workqueue = rt_workqueue_create(RT_WLAN_WORKQUEUE_THREAD_NAME, RT_WLAN_WORKQUEUE_THREAD_SIZE, - RT_WLAN_WORKQUEUE_THREAD_PRIO); - if (wlan_workqueue == RT_NULL) - { - LOG_E("F:%s L:%d wlan work queue create failed", __FUNCTION__, __LINE__); - return -1; - } - _init_flag = 1; - return 0; - } - return 0; -} -INIT_PREV_EXPORT(rt_wlan_workqueue_init); - -#endif diff --git a/rt-thread/components/drivers/wlan/dev_wlan_workqueue.h b/rt-thread/components/drivers/wlan/dev_wlan_workqueue.h deleted file mode 100644 index f85f849..0000000 --- a/rt-thread/components/drivers/wlan/dev_wlan_workqueue.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-08-19 tyx the first version - */ - -#ifndef __DEV_WLAN_WORKQUEUE_H__ -#define __DEV_WLAN_WORKQUEUE_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef RT_WLAN_WORKQUEUE_THREAD_NAME -#define RT_WLAN_WORKQUEUE_THREAD_NAME ("wlan_job") -#endif - -#ifndef RT_WLAN_WORKQUEUE_THREAD_SIZE -#define RT_WLAN_WORKQUEUE_THREAD_SIZE (2048) -#endif - -#ifndef RT_WLAN_WORKQUEUE_THREAD_PRIO -#define RT_WLAN_WORKQUEUE_THREAD_PRIO (20) -#endif - -int rt_wlan_workqueue_init(void); - -rt_err_t rt_wlan_workqueue_dowork(void (*func)(void *parameter), void *parameter); - -struct rt_workqueue *rt_wlan_get_workqueue(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/components/fal/Kconfig b/rt-thread/components/fal/Kconfig index 559014d..4eb967b 100644 --- a/rt-thread/components/fal/Kconfig +++ b/rt-thread/components/fal/Kconfig @@ -5,10 +5,14 @@ menuconfig RT_USING_FAL default n if RT_USING_FAL - config FAL_USING_DEBUG + config FAL_DEBUG_CONFIG bool "Enable debug log output" - default y if RT_USING_DEBUG - default n + default y + + config FAL_DEBUG + int + default 1 if FAL_DEBUG_CONFIG + default 0 config FAL_PART_HAS_TABLE_CFG bool "FAL partition table config has defined on 'fal_cfg.h'" diff --git a/rt-thread/components/fal/docs/fal_api.md b/rt-thread/components/fal/docs/fal_api.md index c4d1889..05d5ea0 100644 --- a/rt-thread/components/fal/docs/fal_api.md +++ b/rt-thread/components/fal/docs/fal_api.md @@ -25,7 +25,7 @@ const struct fal_partition *fal_partition_find(const char *name) ## 获取分区表 ```C -const struct fal_partition *fal_get_partition_table(rt_size_t *len) +const struct fal_partition *fal_get_partition_table(size_t *len) ``` | 参数 | 描述 | @@ -38,7 +38,7 @@ const struct fal_partition *fal_get_partition_table(rt_size_t *len) FAL 初始化时会自动装载默认分区表。使用该设置将临时修改分区表,重启后会 **丢失** 该设置 ```C -void fal_set_partition_table_temp(struct fal_partition *table, rt_size_t len) +void fal_set_partition_table_temp(struct fal_partition *table, size_t len) ``` | 参数 | 描述 | @@ -49,7 +49,7 @@ void fal_set_partition_table_temp(struct fal_partition *table, rt_size_t len) ## 从分区读取数据 ```C -int fal_partition_read(const struct fal_partition *part, rt_uint32_t addr, rt_uint8_t *buf, rt_size_t size) +int fal_partition_read(const struct fal_partition *part, uint32_t addr, uint8_t *buf, size_t size) ``` | 参数 | 描述 | @@ -63,7 +63,7 @@ int fal_partition_read(const struct fal_partition *part, rt_uint32_t addr, rt_ui ## 往分区写入数据 ```C -int fal_partition_write(const struct fal_partition *part, rt_uint32_t addr, const rt_uint8_t *buf, rt_size_t size) +int fal_partition_write(const struct fal_partition *part, uint32_t addr, const uint8_t *buf, size_t size) ``` | 参数 | 描述 | @@ -77,7 +77,7 @@ int fal_partition_write(const struct fal_partition *part, rt_uint32_t addr, cons ## 擦除分区数据 ```C -int fal_partition_erase(const struct fal_partition *part, rt_uint32_t addr, rt_size_t size) +int fal_partition_erase(const struct fal_partition *part, uint32_t addr, size_t size) ``` | 参数 | 描述 | diff --git a/rt-thread/components/fal/docs/fal_api_en.md b/rt-thread/components/fal/docs/fal_api_en.md index d44597e..df4b011 100644 --- a/rt-thread/components/fal/docs/fal_api_en.md +++ b/rt-thread/components/fal/docs/fal_api_en.md @@ -25,7 +25,7 @@ const struct fal_partition *fal_partition_find(const char *name) ## Get the partition table ```C -const struct fal_partition *fal_get_partition_table(rt_size_t *len) +const struct fal_partition *fal_get_partition_table(size_t *len) ``` | Parameters | Description | @@ -38,7 +38,7 @@ const struct fal_partition *fal_get_partition_table(rt_size_t *len) The default partition table will be automatically loaded when FAL is initialized. Using this setting will temporarily modify the partition table and will **lost** this setting after restarting ```C -void fal_set_partition_table_temp(struct fal_partition *table, rt_size_t len) +void fal_set_partition_table_temp(struct fal_partition *table, size_t len) ``` | Parameters | Description | @@ -49,7 +49,7 @@ void fal_set_partition_table_temp(struct fal_partition *table, rt_size_t len) ## Read data from partition ```C -int fal_partition_read(const struct fal_partition *part, rt_uint32_t addr, rt_uint8_t *buf, rt_size_t size) +int fal_partition_read(const struct fal_partition *part, uint32_t addr, uint8_t *buf, size_t size) ``` | Parameters | Description | @@ -63,7 +63,7 @@ int fal_partition_read(const struct fal_partition *part, rt_uint32_t addr, rt_ui ## Write data to partition ```C -int fal_partition_write(const struct fal_partition *part, rt_uint32_t addr, const rt_uint8_t *buf, rt_size_t size) +int fal_partition_write(const struct fal_partition *part, uint32_t addr, const uint8_t *buf, size_t size) ``` | Parameters | Description | @@ -77,7 +77,7 @@ int fal_partition_write(const struct fal_partition *part, rt_uint32_t addr, cons ## Erase partition data ```C -int fal_partition_erase(const struct fal_partition *part, rt_uint32_t addr, rt_size_t size) +int fal_partition_erase(const struct fal_partition *part, uint32_t addr, size_t size) ``` | Parameters | Description | diff --git a/rt-thread/components/fal/inc/fal.h b/rt-thread/components/fal/inc/fal.h index 1c2ebdd..eca4402 100644 --- a/rt-thread/components/fal/inc/fal.h +++ b/rt-thread/components/fal/inc/fal.h @@ -56,7 +56,7 @@ const struct fal_partition *fal_partition_find(const char *name); * * @return partition table */ -const struct fal_partition *fal_get_partition_table(rt_size_t *len); +const struct fal_partition *fal_get_partition_table(size_t *len); /** * set partition table temporarily @@ -65,7 +65,7 @@ const struct fal_partition *fal_get_partition_table(rt_size_t *len); * @param table partition table * @param len partition table length */ -void fal_set_partition_table_temp(struct fal_partition *table, rt_size_t len); +void fal_set_partition_table_temp(struct fal_partition *table, size_t len); /** * read data from partition @@ -78,7 +78,7 @@ void fal_set_partition_table_temp(struct fal_partition *table, rt_size_t len); * @return >= 0: successful read data size * -1: error */ -int fal_partition_read(const struct fal_partition *part, rt_uint32_t addr, rt_uint8_t *buf, rt_size_t size); +int fal_partition_read(const struct fal_partition *part, uint32_t addr, uint8_t *buf, size_t size); /** * write data to partition @@ -91,7 +91,7 @@ int fal_partition_read(const struct fal_partition *part, rt_uint32_t addr, rt_ui * @return >= 0: successful write data size * -1: error */ -int fal_partition_write(const struct fal_partition *part, rt_uint32_t addr, const rt_uint8_t *buf, rt_size_t size); +int fal_partition_write(const struct fal_partition *part, uint32_t addr, const uint8_t *buf, size_t size); /** * erase partition data @@ -103,7 +103,7 @@ int fal_partition_write(const struct fal_partition *part, rt_uint32_t addr, cons * @return >= 0: successful erased data size * -1: error */ -int fal_partition_erase(const struct fal_partition *part, rt_uint32_t addr, rt_size_t size); +int fal_partition_erase(const struct fal_partition *part, uint32_t addr, size_t size); /** * erase partition all data diff --git a/rt-thread/components/fal/inc/fal_def.h b/rt-thread/components/fal/inc/fal_def.h index a2a4d07..1372798 100644 --- a/rt-thread/components/fal/inc/fal_def.h +++ b/rt-thread/components/fal/inc/fal_def.h @@ -11,8 +11,63 @@ #ifndef _FAL_DEF_H_ #define _FAL_DEF_H_ +#include +#include #include +#define FAL_PRINTF rt_kprintf +#define FAL_MALLOC rt_malloc +#define FAL_CALLOC rt_calloc +#define FAL_REALLOC rt_realloc +#define FAL_FREE rt_free + +#ifndef FAL_DEBUG +#define FAL_DEBUG 0 +#endif + +#if FAL_DEBUG +#ifdef assert +#undef assert +#endif +#define assert(EXPR) \ +if (!(EXPR)) \ +{ \ + FAL_PRINTF("(%s) has assert failed at %s.\n", #EXPR, __FUNCTION__); \ + while (1); \ +} + +/* debug level log */ +#ifdef log_d +#undef log_d +#endif +#define log_d(...) FAL_PRINTF("[D/FAL] (%s:%d) ", __FUNCTION__, __LINE__); FAL_PRINTF(__VA_ARGS__);FAL_PRINTF("\n") + +#else + +#ifdef assert +#undef assert +#endif +#define assert(EXPR) ((void)0); + +/* debug level log */ +#ifdef log_d +#undef log_d +#endif +#define log_d(...) +#endif /* FAL_DEBUG */ + +/* error level log */ +#ifdef log_e +#undef log_e +#endif +#define log_e(...) FAL_PRINTF("\033[31;22m[E/FAL] (%s:%d) ", __FUNCTION__, __LINE__);FAL_PRINTF(__VA_ARGS__);FAL_PRINTF("\033[0m\n") + +/* info level log */ +#ifdef log_i +#undef log_i +#endif +#define log_i(...) FAL_PRINTF("\033[32;22m[I/FAL] "); FAL_PRINTF(__VA_ARGS__);FAL_PRINTF("\033[0m\n") + /* FAL flash and partition device name max length */ #ifndef FAL_DEV_NAME_MAX #define FAL_DEV_NAME_MAX 24 @@ -24,8 +79,8 @@ struct flash_blk { - rt_size_t size; - rt_size_t count; + size_t size; + size_t count; }; struct fal_flash_dev @@ -33,23 +88,23 @@ struct fal_flash_dev char name[FAL_DEV_NAME_MAX]; /* flash device start address and len */ - rt_uint32_t addr; - rt_size_t len; + uint32_t addr; + size_t len; /* the block size in the flash for erase minimum granularity */ - rt_size_t blk_size; + size_t blk_size; struct { int (*init)(void); - int (*read)(long offset, rt_uint8_t *buf, rt_size_t size); - int (*write)(long offset, const rt_uint8_t *buf, rt_size_t size); - int (*erase)(long offset, rt_size_t size); + int (*read)(long offset, uint8_t *buf, size_t size); + int (*write)(long offset, const uint8_t *buf, size_t size); + int (*erase)(long offset, size_t size); } ops; /* write minimum granularity, unit: bit. 1(nor flash)/ 8(stm32f2/f4)/ 32(stm32f1)/ 64(stm32l4) 0 will not take effect. */ - rt_size_t write_gran; + size_t write_gran; struct flash_blk blocks[FAL_DEV_BLK_MAX]; }; typedef struct fal_flash_dev *fal_flash_dev_t; @@ -59,7 +114,7 @@ typedef struct fal_flash_dev *fal_flash_dev_t; */ struct fal_partition { - rt_uint32_t magic_word; + uint32_t magic_word; /* partition name */ char name[FAL_DEV_NAME_MAX]; @@ -68,9 +123,9 @@ struct fal_partition /* partition offset address on flash device */ long offset; - rt_size_t len; + size_t len; - rt_uint32_t reserved; + uint32_t reserved; }; typedef struct fal_partition *fal_partition_t; diff --git a/rt-thread/components/fal/samples/porting/README.md b/rt-thread/components/fal/samples/porting/README.md index c804644..36c04e1 100644 --- a/rt-thread/components/fal/samples/porting/README.md +++ b/rt-thread/components/fal/samples/porting/README.md @@ -12,7 +12,7 @@ - `static int init(void)`:**可选** 的初始化操作 -- `static int read(long offset, rt_uint8_t *buf, rt_size_t size)`:读取操作 +- `static int read(long offset, uint8_t *buf, size_t size)`:读取操作 |参数 |描述| |:----- |:----| @@ -21,7 +21,7 @@ |size |待读取数据的大小| |return |返回实际读取的数据大小| -- `static int write(long offset, const rt_uint8_t *buf, rt_size_t size)` :写入操作 +- `static int write(long offset, const uint8_t *buf, size_t size)` :写入操作 | 参数 | 描述 | | :----- | :------------------------ | @@ -30,7 +30,7 @@ | size | 待写入数据的大小 | | return | 返回实际写入的数据大小 | -- `static int erase(long offset, rt_size_t size)` :擦除操作 +- `static int erase(long offset, size_t size)` :擦除操作 | 参数 | 描述 | | :----- | :------------------------ | diff --git a/rt-thread/components/fal/samples/porting/fal_flash_sfud_port.c b/rt-thread/components/fal/samples/porting/fal_flash_sfud_port.c index 4c1ae2f..35bbc0f 100644 --- a/rt-thread/components/fal/samples/porting/fal_flash_sfud_port.c +++ b/rt-thread/components/fal/samples/porting/fal_flash_sfud_port.c @@ -13,7 +13,7 @@ #ifdef FAL_USING_SFUD_PORT #ifdef RT_USING_SFUD -#include +#include #endif #ifndef FAL_USING_NOR_FLASH_DEV_NAME @@ -21,9 +21,9 @@ #endif static int init(void); -static int read(long offset, rt_uint8_t *buf, rt_size_t size); -static int write(long offset, const rt_uint8_t *buf, rt_size_t size); -static int erase(long offset, rt_size_t size); +static int read(long offset, uint8_t *buf, size_t size); +static int write(long offset, const uint8_t *buf, size_t size); +static int erase(long offset, size_t size); static sfud_flash_t sfud_dev = NULL; struct fal_flash_dev nor_flash0 = @@ -60,19 +60,19 @@ static int init(void) return 0; } -static int read(long offset, rt_uint8_t *buf, rt_size_t size) +static int read(long offset, uint8_t *buf, size_t size) { - RT_ASSERT(sfud_dev); - RT_ASSERT(sfud_dev->init_ok); + assert(sfud_dev); + assert(sfud_dev->init_ok); sfud_read(sfud_dev, nor_flash0.addr + offset, size, buf); return size; } -static int write(long offset, const rt_uint8_t *buf, rt_size_t size) +static int write(long offset, const uint8_t *buf, size_t size) { - RT_ASSERT(sfud_dev); - RT_ASSERT(sfud_dev->init_ok); + assert(sfud_dev); + assert(sfud_dev->init_ok); if (sfud_write(sfud_dev, nor_flash0.addr + offset, size, buf) != SFUD_SUCCESS) { return -1; @@ -81,10 +81,10 @@ static int write(long offset, const rt_uint8_t *buf, rt_size_t size) return size; } -static int erase(long offset, rt_size_t size) +static int erase(long offset, size_t size) { - RT_ASSERT(sfud_dev); - RT_ASSERT(sfud_dev->init_ok); + assert(sfud_dev); + assert(sfud_dev->init_ok); if (sfud_erase(sfud_dev, nor_flash0.addr + offset, size) != SFUD_SUCCESS) { return -1; diff --git a/rt-thread/components/fal/samples/porting/fal_flash_stm32f2_port.c b/rt-thread/components/fal/samples/porting/fal_flash_stm32f2_port.c index 3a8eb3e..ed2c2c0 100644 --- a/rt-thread/components/fal/samples/porting/fal_flash_stm32f2_port.c +++ b/rt-thread/components/fal/samples/porting/fal_flash_stm32f2_port.c @@ -13,18 +13,18 @@ #include /* base address of the flash sectors */ -#define ADDR_FLASH_SECTOR_0 ((rt_uint32_t)0x08000000) /* Base address of Sector 0, 16 K bytes */ -#define ADDR_FLASH_SECTOR_1 ((rt_uint32_t)0x08004000) /* Base address of Sector 1, 16 K bytes */ -#define ADDR_FLASH_SECTOR_2 ((rt_uint32_t)0x08008000) /* Base address of Sector 2, 16 K bytes */ -#define ADDR_FLASH_SECTOR_3 ((rt_uint32_t)0x0800C000) /* Base address of Sector 3, 16 K bytes */ -#define ADDR_FLASH_SECTOR_4 ((rt_uint32_t)0x08010000) /* Base address of Sector 4, 64 K bytes */ -#define ADDR_FLASH_SECTOR_5 ((rt_uint32_t)0x08020000) /* Base address of Sector 5, 128 K bytes */ -#define ADDR_FLASH_SECTOR_6 ((rt_uint32_t)0x08040000) /* Base address of Sector 6, 128 K bytes */ -#define ADDR_FLASH_SECTOR_7 ((rt_uint32_t)0x08060000) /* Base address of Sector 7, 128 K bytes */ -#define ADDR_FLASH_SECTOR_8 ((rt_uint32_t)0x08080000) /* Base address of Sector 8, 128 K bytes */ -#define ADDR_FLASH_SECTOR_9 ((rt_uint32_t)0x080A0000) /* Base address of Sector 9, 128 K bytes */ -#define ADDR_FLASH_SECTOR_10 ((rt_uint32_t)0x080C0000) /* Base address of Sector 10, 128 K bytes */ -#define ADDR_FLASH_SECTOR_11 ((rt_uint32_t)0x080E0000) /* Base address of Sector 11, 128 K bytes */ +#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base address of Sector 0, 16 K bytes */ +#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base address of Sector 1, 16 K bytes */ +#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base address of Sector 2, 16 K bytes */ +#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base address of Sector 3, 16 K bytes */ +#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base address of Sector 4, 64 K bytes */ +#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base address of Sector 5, 128 K bytes */ +#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base address of Sector 6, 128 K bytes */ +#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base address of Sector 7, 128 K bytes */ +#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base address of Sector 8, 128 K bytes */ +#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base address of Sector 9, 128 K bytes */ +#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base address of Sector 10, 128 K bytes */ +#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base address of Sector 11, 128 K bytes */ /** * Get the sector of a given address @@ -33,9 +33,9 @@ * * @return The sector of a given address */ -static rt_uint32_t stm32_get_sector(rt_uint32_t address) +static uint32_t stm32_get_sector(uint32_t address) { - rt_uint32_t sector = 0; + uint32_t sector = 0; if ((address < ADDR_FLASH_SECTOR_1) && (address >= ADDR_FLASH_SECTOR_0)) { @@ -96,8 +96,8 @@ static rt_uint32_t stm32_get_sector(rt_uint32_t address) * * @return sector size */ -static rt_uint32_t stm32_get_sector_size(rt_uint32_t sector) { - RT_ASSERT(IS_FLASH_SECTOR(sector)); +static uint32_t stm32_get_sector_size(uint32_t sector) { + assert(IS_FLASH_SECTOR(sector)); switch (sector) { case FLASH_Sector_0: return 16 * 1024; @@ -120,23 +120,23 @@ static int init(void) /* do nothing now */ } -static int read(long offset, rt_uint8_t *buf, rt_size_t size) +static int read(long offset, uint8_t *buf, size_t size) { - rt_size_t i; - rt_uint32_t addr = stm32f2_onchip_flash.addr + offset; + size_t i; + uint32_t addr = stm32f2_onchip_flash.addr + offset; for (i = 0; i < size; i++, addr++, buf++) { - *buf = *(rt_uint8_t *) addr; + *buf = *(uint8_t *) addr; } return size; } -static int write(long offset, const rt_uint8_t *buf, rt_size_t size) +static int write(long offset, const uint8_t *buf, size_t size) { - rt_size_t i; - rt_uint32_t read_data; - rt_uint32_t addr = stm32f2_onchip_flash.addr + offset; + size_t i; + uint32_t read_data; + uint32_t addr = stm32f2_onchip_flash.addr + offset; FLASH_Unlock(); FLASH_ClearFlag( @@ -146,7 +146,7 @@ static int write(long offset, const rt_uint8_t *buf, rt_size_t size) { /* write data */ FLASH_ProgramByte(addr, *buf); - read_data = *(rt_uint8_t *) addr; + read_data = *(uint8_t *) addr; /* check data */ if (read_data != *buf) { @@ -158,12 +158,12 @@ static int write(long offset, const rt_uint8_t *buf, rt_size_t size) return size; } -static int erase(long offset, rt_size_t size) +static int erase(long offset, size_t size) { FLASH_Status flash_status; - rt_size_t erased_size = 0; - rt_uint32_t cur_erase_sector; - rt_uint32_t addr = stm32f2_onchip_flash.addr + offset; + size_t erased_size = 0; + uint32_t cur_erase_sector; + uint32_t addr = stm32f2_onchip_flash.addr + offset; /* start erase */ FLASH_Unlock(); diff --git a/rt-thread/components/fal/src/fal.c b/rt-thread/components/fal/src/fal.c index 52c7ed7..292b492 100644 --- a/rt-thread/components/fal/src/fal.c +++ b/rt-thread/components/fal/src/fal.c @@ -9,17 +9,8 @@ */ #include -#include -#define DBG_TAG "FAL" -#ifdef FAL_USING_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_WARNING -#endif -#include - -static rt_uint8_t init_ok = 0; +static uint8_t init_ok = 0; /** * FAL (Flash Abstraction Layer) initialization. @@ -49,12 +40,12 @@ __exit: if ((result > 0) && (!init_ok)) { init_ok = 1; - LOG_I("RT-Thread Flash Abstraction Layer initialize success."); + log_i("RT-Thread Flash Abstraction Layer initialize success."); } else if(result <= 0) { init_ok = 0; - LOG_E("RT-Thread Flash Abstraction Layer initialize failed."); + log_e("RT-Thread Flash Abstraction Layer initialize failed."); } return result; diff --git a/rt-thread/components/fal/src/fal_flash.c b/rt-thread/components/fal/src/fal_flash.c index d4fba4e..b0ca60f 100644 --- a/rt-thread/components/fal/src/fal_flash.c +++ b/rt-thread/components/fal/src/fal_flash.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -11,22 +11,14 @@ #include #include -#define DBG_TAG "FAL" -#ifdef FAL_USING_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_WARNING -#endif -#include - /* flash device table, must defined by user */ #if !defined(FAL_FLASH_DEV_TABLE) #error "You must defined flash device table (FAL_FLASH_DEV_TABLE) on 'fal_cfg.h'" #endif static const struct fal_flash_dev * const device_table[] = FAL_FLASH_DEV_TABLE; -static const rt_size_t device_table_len = sizeof(device_table) / sizeof(device_table[0]); -static rt_uint8_t init_ok = 0; +static const size_t device_table_len = sizeof(device_table) / sizeof(device_table[0]); +static uint8_t init_ok = 0; /** * Initialize all flash device on FAL flash table @@ -35,7 +27,7 @@ static rt_uint8_t init_ok = 0; */ int fal_flash_init(void) { - rt_size_t i, j, offset; + size_t i, j, offset; if (init_ok) { @@ -44,33 +36,25 @@ int fal_flash_init(void) for (i = 0; i < device_table_len; i++) { - RT_ASSERT(device_table[i]->ops.read); - RT_ASSERT(device_table[i]->ops.write); - RT_ASSERT(device_table[i]->ops.erase); + assert(device_table[i]->ops.read); + assert(device_table[i]->ops.write); + assert(device_table[i]->ops.erase); /* init flash device on flash table */ if (device_table[i]->ops.init) { device_table[i]->ops.init(); } - LOG_D("Flash device | %*.*s | addr: 0x%08lx | len: 0x%08x | blk_size: 0x%08x |initialized finish.", + log_d("Flash device | %*.*s | addr: 0x%08lx | len: 0x%08x | blk_size: 0x%08x |initialized finish.", FAL_DEV_NAME_MAX, FAL_DEV_NAME_MAX, device_table[i]->name, device_table[i]->addr, device_table[i]->len, device_table[i]->blk_size); offset = 0; for (j = 0; j < FAL_DEV_BLK_MAX; j ++) { const struct flash_blk *blk = &device_table[i]->blocks[j]; - rt_size_t blk_len = blk->count * blk->size; + size_t blk_len = blk->count * blk->size; if (blk->count == 0 || blk->size == 0) break; - - if(offset > device_table[i]->len) - { - LOG_I("Flash device %*.*s: add block failed, offset %d > len %d.", - FAL_DEV_NAME_MAX, FAL_DEV_NAME_MAX, device_table[i]->name, device_table[i]->addr, offset, device_table[i]->len); - break; - } - - LOG_D(" blk%2d | addr: 0x%08lx | len: 0x%08x | blk_size: 0x%08x |initialized finish.", + log_d(" blk%2d | addr: 0x%08lx | len: 0x%08x | blk_size: 0x%08x |initialized finish.", j, device_table[i]->addr + offset, blk_len, blk->size); offset += blk_len; } @@ -90,10 +74,10 @@ int fal_flash_init(void) */ const struct fal_flash_dev *fal_flash_device_find(const char *name) { - RT_ASSERT(init_ok); - RT_ASSERT(name); + assert(init_ok); + assert(name); - rt_size_t i; + size_t i; for (i = 0; i < device_table_len; i++) { diff --git a/rt-thread/components/fal/src/fal_partition.c b/rt-thread/components/fal/src/fal_partition.c index 5a97a50..a26a018 100644 --- a/rt-thread/components/fal/src/fal_partition.c +++ b/rt-thread/components/fal/src/fal_partition.c @@ -10,15 +10,7 @@ #include #include - -#define DBG_TAG "FAL" -#ifdef FAL_USING_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_WARNING -#endif -#include - +#include /* partition magic word */ #define FAL_PART_MAGIC_WORD 0x45503130 @@ -63,8 +55,8 @@ static struct fal_partition *partition_table = NULL; static struct part_flash_info *part_flash_cache = NULL; #endif /* FAL_PART_HAS_TABLE_CFG */ -static rt_uint8_t init_ok = 0; -static rt_size_t partition_table_len = 0; +static uint8_t init_ok = 0; +static size_t partition_table_len = 0; /** * print the partition table @@ -72,7 +64,7 @@ static rt_size_t partition_table_len = 0; void fal_show_part_table(void) { char *item1 = "name", *item2 = "flash_dev"; - rt_size_t i, part_name_max = strlen(item1), flash_dev_name_max = strlen(item2); + size_t i, part_name_max = strlen(item1), flash_dev_name_max = strlen(item2); const struct fal_partition *part; if (partition_table_len) @@ -90,10 +82,10 @@ void fal_show_part_table(void) } } } - LOG_I("==================== FAL partition table ===================="); - LOG_I("| %-*.*s | %-*.*s | offset | length |", part_name_max, FAL_DEV_NAME_MAX, item1, flash_dev_name_max, + log_i("==================== FAL partition table ===================="); + log_i("| %-*.*s | %-*.*s | offset | length |", part_name_max, FAL_DEV_NAME_MAX, item1, flash_dev_name_max, FAL_DEV_NAME_MAX, item2); - LOG_I("-------------------------------------------------------------"); + log_i("-------------------------------------------------------------"); for (i = 0; i < partition_table_len; i++) { @@ -103,26 +95,26 @@ void fal_show_part_table(void) part = &partition_table[partition_table_len - i - 1]; #endif - LOG_I("| %-*.*s | %-*.*s | 0x%08lx | 0x%08x |", part_name_max, FAL_DEV_NAME_MAX, part->name, flash_dev_name_max, + log_i("| %-*.*s | %-*.*s | 0x%08lx | 0x%08x |", part_name_max, FAL_DEV_NAME_MAX, part->name, flash_dev_name_max, FAL_DEV_NAME_MAX, part->flash_name, part->offset, part->len); } - LOG_I("============================================================="); + log_i("============================================================="); } -static int check_and_update_part_cache(const struct fal_partition *table, rt_size_t len) +static int check_and_update_part_cache(const struct fal_partition *table, size_t len) { const struct fal_flash_dev *flash_dev = NULL; - rt_size_t i; + size_t i; #ifndef FAL_PART_HAS_TABLE_CFG if (part_flash_cache) { - rt_free(part_flash_cache); + FAL_FREE(part_flash_cache); } - part_flash_cache = rt_malloc(len * sizeof(struct part_flash_info)); + part_flash_cache = FAL_MALLOC(len * sizeof(struct part_flash_info)); if (part_flash_cache == NULL) { - LOG_E("Initialize failed! No memory for partition table cache"); + log_e("Initialize failed! No memory for partition table cache"); return -2; } #endif @@ -132,13 +124,13 @@ static int check_and_update_part_cache(const struct fal_partition *table, rt_siz flash_dev = fal_flash_device_find(table[i].flash_name); if (flash_dev == NULL) { - LOG_D("Warning: Do NOT found the flash device(%s).", table[i].flash_name); + log_d("Warning: Do NOT found the flash device(%s).", table[i].flash_name); continue; } if (table[i].offset >= (long)flash_dev->len) { - LOG_E("Initialize failed! Partition(%s) offset address(%ld) out of flash bound(<%d).", + log_e("Initialize failed! Partition(%s) offset address(%ld) out of flash bound(<%d).", table[i].name, table[i].offset, flash_dev->len); partition_table_len = 0; @@ -170,38 +162,38 @@ int fal_partition_init(void) #else /* load partition table from the end address FAL_PART_TABLE_END_OFFSET, error return 0 */ long part_table_offset = FAL_PART_TABLE_END_OFFSET; - rt_size_t table_num = 0, table_item_size = 0; - rt_uint8_t part_table_find_ok = 0; - rt_uint32_t read_magic_word; + size_t table_num = 0, table_item_size = 0; + uint8_t part_table_find_ok = 0; + uint32_t read_magic_word; fal_partition_t new_part = NULL; - rt_size_t i; + size_t i; const struct fal_flash_dev *flash_dev = NULL; flash_dev = fal_flash_device_find(FAL_PART_TABLE_FLASH_DEV_NAME); if (flash_dev == NULL) { - LOG_E("Initialize failed! Flash device (%s) NOT found.", FAL_PART_TABLE_FLASH_DEV_NAME); + log_e("Initialize failed! Flash device (%s) NOT found.", FAL_PART_TABLE_FLASH_DEV_NAME); goto _exit; } /* check partition table offset address */ if (part_table_offset < 0 || part_table_offset >= (long) flash_dev->len) { - LOG_E("Setting partition table end offset address(%ld) out of flash bound(<%d).", part_table_offset, flash_dev->len); + log_e("Setting partition table end offset address(%ld) out of flash bound(<%d).", part_table_offset, flash_dev->len); goto _exit; } table_item_size = sizeof(struct fal_partition); - new_part = (fal_partition_t)rt_malloc(table_item_size); + new_part = (fal_partition_t)FAL_MALLOC(table_item_size); if (new_part == NULL) { - LOG_E("Initialize failed! No memory for table buffer."); + log_e("Initialize failed! No memory for table buffer."); goto _exit; } /* find partition table location */ { - rt_uint8_t read_buf[64]; + uint8_t read_buf[64]; part_table_offset -= sizeof(read_buf); while (part_table_offset >= 0) @@ -216,7 +208,7 @@ int fal_partition_init(void) { part_table_find_ok = 1; part_table_offset += i; - LOG_D("Find the partition table on '%s' offset @0x%08lx.", FAL_PART_TABLE_FLASH_DEV_NAME, + log_d("Find the partition table on '%s' offset @0x%08lx.", FAL_PART_TABLE_FLASH_DEV_NAME, part_table_offset); break; } @@ -257,10 +249,10 @@ int fal_partition_init(void) while (part_table_find_ok) { memset(new_part, 0x00, table_num); - if (flash_dev->ops.read(part_table_offset - table_item_size * (table_num), (rt_uint8_t *) new_part, + if (flash_dev->ops.read(part_table_offset - table_item_size * (table_num), (uint8_t *) new_part, table_item_size) < 0) { - LOG_E("Initialize failed! Flash device (%s) read error!", flash_dev->name); + log_e("Initialize failed! Flash device (%s) read error!", flash_dev->name); table_num = 0; break; } @@ -270,10 +262,10 @@ int fal_partition_init(void) break; } - partition_table = (fal_partition_t) rt_realloc(partition_table, table_item_size * (table_num + 1)); + partition_table = (fal_partition_t) FAL_REALLOC(partition_table, table_item_size * (table_num + 1)); if (partition_table == NULL) { - LOG_E("Initialize failed! No memory for partition table"); + log_e("Initialize failed! No memory for partition table"); table_num = 0; break; } @@ -285,7 +277,7 @@ int fal_partition_init(void) if (table_num == 0) { - LOG_E("Partition table NOT found on flash: %s (len: %d) from offset: 0x%08x.", FAL_PART_TABLE_FLASH_DEV_NAME, + log_e("Partition table NOT found on flash: %s (len: %d) from offset: 0x%08x.", FAL_PART_TABLE_FLASH_DEV_NAME, FAL_DEV_NAME_MAX, FAL_PART_TABLE_END_OFFSET); goto _exit; } @@ -305,14 +297,14 @@ int fal_partition_init(void) _exit: -#ifdef FAL_USING_DEBUG +#if FAL_DEBUG fal_show_part_table(); -#endif /* FAL_USING_DEBUG */ +#endif #ifndef FAL_PART_HAS_TABLE_CFG if (new_part) { - rt_free(new_part); + FAL_FREE(new_part); } #endif /* !FAL_PART_HAS_TABLE_CFG */ @@ -332,7 +324,7 @@ const struct fal_partition *fal_partition_find(const char *name) if (!init_ok) return NULL; - rt_size_t i; + size_t i; for (i = 0; i < partition_table_len; i++) { @@ -347,8 +339,8 @@ const struct fal_partition *fal_partition_find(const char *name) static const struct fal_flash_dev *flash_device_find_by_part(const struct fal_partition *part) { - RT_ASSERT(part >= partition_table); - RT_ASSERT(part <= &partition_table[partition_table_len - 1]); + assert(part >= partition_table); + assert(part <= &partition_table[partition_table_len - 1]); return part_flash_cache[part - partition_table].flash_dev; } @@ -360,9 +352,9 @@ static const struct fal_flash_dev *flash_device_find_by_part(const struct fal_pa * * @return partition table */ -const struct fal_partition *fal_get_partition_table(rt_size_t *len) +const struct fal_partition *fal_get_partition_table(size_t *len) { - RT_ASSERT(len); + assert(len); if (!init_ok) return NULL; @@ -379,13 +371,13 @@ const struct fal_partition *fal_get_partition_table(rt_size_t *len) * @param table partition table * @param len partition table length */ -void fal_set_partition_table_temp(struct fal_partition *table, rt_size_t len) +void fal_set_partition_table_temp(struct fal_partition *table, size_t len) { - RT_ASSERT(table); + assert(table); if (!init_ok) { - LOG_E("FAL NOT initialized"); + log_e("FAL NOT initialized"); return; } @@ -406,31 +398,31 @@ void fal_set_partition_table_temp(struct fal_partition *table, rt_size_t len) * @return >= 0: successful read data size * -1: error */ -int fal_partition_read(const struct fal_partition *part, rt_uint32_t addr, rt_uint8_t *buf, rt_size_t size) +int fal_partition_read(const struct fal_partition *part, uint32_t addr, uint8_t *buf, size_t size) { int ret = 0; const struct fal_flash_dev *flash_dev = NULL; - RT_ASSERT(part); - RT_ASSERT(buf); + assert(part); + assert(buf); if (addr + size > part->len) { - LOG_E("Partition read error! Partition(%s) address(0x%08x) out of bound(0x%08x).", part->name, addr + size, part->len); + log_e("Partition read error! Partition(%s) address(0x%08x) out of bound(0x%08x).", part->name, addr + size, part->len); return -1; } flash_dev = flash_device_find_by_part(part); if (flash_dev == NULL) { - LOG_E("Partition read error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name); + log_e("Partition read error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name); return -1; } ret = flash_dev->ops.read(part->offset + addr, buf, size); if (ret < 0) { - LOG_E("Partition read error! Flash device(%s) read error!", part->flash_name); + log_e("Partition read error! Flash device(%s) read error!", part->flash_name); } return ret; @@ -447,31 +439,31 @@ int fal_partition_read(const struct fal_partition *part, rt_uint32_t addr, rt_ui * @return >= 0: successful write data size * -1: error */ -int fal_partition_write(const struct fal_partition *part, rt_uint32_t addr, const rt_uint8_t *buf, rt_size_t size) +int fal_partition_write(const struct fal_partition *part, uint32_t addr, const uint8_t *buf, size_t size) { int ret = 0; const struct fal_flash_dev *flash_dev = NULL; - RT_ASSERT(part); - RT_ASSERT(buf); + assert(part); + assert(buf); if (addr + size > part->len) { - LOG_E("Partition write error! Partition address out of bound."); + log_e("Partition write error! Partition address out of bound."); return -1; } flash_dev = flash_device_find_by_part(part); if (flash_dev == NULL) { - LOG_E("Partition write error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name); + log_e("Partition write error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name); return -1; } ret = flash_dev->ops.write(part->offset + addr, buf, size); if (ret < 0) { - LOG_E("Partition write error! Flash device(%s) write error!", part->flash_name); + log_e("Partition write error! Flash device(%s) write error!", part->flash_name); } return ret; @@ -487,30 +479,30 @@ int fal_partition_write(const struct fal_partition *part, rt_uint32_t addr, cons * @return >= 0: successful erased data size * -1: error */ -int fal_partition_erase(const struct fal_partition *part, rt_uint32_t addr, rt_size_t size) +int fal_partition_erase(const struct fal_partition *part, uint32_t addr, size_t size) { int ret = 0; const struct fal_flash_dev *flash_dev = NULL; - RT_ASSERT(part); + assert(part); if (addr + size > part->len) { - LOG_E("Partition erase error! Partition address out of bound."); + log_e("Partition erase error! Partition address out of bound."); return -1; } flash_dev = flash_device_find_by_part(part); if (flash_dev == NULL) { - LOG_E("Partition erase error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name); + log_e("Partition erase error! Don't found flash device(%s) of the partition(%s).", part->flash_name, part->name); return -1; } ret = flash_dev->ops.erase(part->offset + addr, size); if (ret < 0) { - LOG_E("Partition erase error! Flash device(%s) erase error!", part->flash_name); + log_e("Partition erase error! Flash device(%s) erase error!", part->flash_name); } return ret; diff --git a/rt-thread/components/fal/src/fal_rtt.c b/rt-thread/components/fal/src/fal_rtt.c index 9ae93ea..f8d548d 100644 --- a/rt-thread/components/fal/src/fal_rtt.c +++ b/rt-thread/components/fal/src/fal_rtt.c @@ -10,18 +10,12 @@ */ #include + +#ifdef RT_VER_NUM +#include +#include #include #include -#include - -#define DBG_TAG "FAL" -#ifdef FAL_USING_DEBUG -#define DBG_LVL DBG_LOG -#else -#define DBG_LVL DBG_WARNING -#endif -#include - /* ========================== block device ======================== */ struct fal_blk_device @@ -40,7 +34,7 @@ static rt_err_t blk_dev_control(rt_device_t dev, rt_uint8_t cmd, void *args) { struct fal_blk_device *part = (struct fal_blk_device*) dev; - RT_ASSERT(part != RT_NULL); + assert(part != RT_NULL); if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME) { @@ -52,7 +46,7 @@ static rt_err_t blk_dev_control(rt_device_t dev, rt_uint8_t cmd, void *args) return -RT_ERROR; } - rt_memcpy(geometry, &part->geometry, sizeof(struct rt_device_blk_geometry)); + memcpy(geometry, &part->geometry, sizeof(struct rt_device_blk_geometry)); } else if (cmd == RT_DEVICE_CTRL_BLK_ERASE) { @@ -86,7 +80,7 @@ static rt_ssize_t blk_dev_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_s int ret = 0; struct fal_blk_device *part = (struct fal_blk_device*) dev; - RT_ASSERT(part != RT_NULL); + assert(part != RT_NULL); ret = fal_partition_read(part->fal_part, pos * part->geometry.block_size, buffer, size * part->geometry.block_size); @@ -110,7 +104,7 @@ static rt_ssize_t blk_dev_write(rt_device_t dev, rt_off_t pos, const void* buffe rt_size_t phy_size; part = (struct fal_blk_device*) dev; - RT_ASSERT(part != RT_NULL); + assert(part != RT_NULL); /* change the block device's logic address to physical address */ phy_pos = pos * part->geometry.bytes_per_sector; @@ -163,13 +157,13 @@ struct rt_device *fal_blk_device_create(const char *parition_name) if (!fal_part) { - LOG_E("Error: the partition name (%s) is not found.", parition_name); + log_e("Error: the partition name (%s) is not found.", parition_name); return NULL; } if ((fal_flash = fal_flash_device_find(fal_part->flash_name)) == NULL) { - LOG_E("Error: the flash device name (%s) is not found.", fal_part->flash_name); + log_e("Error: the flash device name (%s) is not found.", fal_part->flash_name); return NULL; } @@ -198,12 +192,12 @@ struct rt_device *fal_blk_device_create(const char *parition_name) /* no private */ blk_dev->parent.user_data = RT_NULL; - LOG_I("The FAL block device (%s) created successfully", fal_part->name); + log_i("The FAL block device (%s) created successfully", fal_part->name); rt_device_register(RT_DEVICE(blk_dev), fal_part->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE); } else { - LOG_E("Error: no memory for create FAL block device"); + log_e("Error: no memory for create FAL block device"); } return RT_DEVICE(blk_dev); @@ -223,7 +217,7 @@ static rt_ssize_t mtd_nor_dev_read(struct rt_mtd_nor_device* device, rt_off_t of int ret = 0; struct fal_mtd_nor_device *part = (struct fal_mtd_nor_device*) device; - RT_ASSERT(part != RT_NULL); + assert(part != RT_NULL); ret = fal_partition_read(part->fal_part, offset, data, length); @@ -245,7 +239,7 @@ static rt_ssize_t mtd_nor_dev_write(struct rt_mtd_nor_device* device, rt_off_t o struct fal_mtd_nor_device *part; part = (struct fal_mtd_nor_device*) device; - RT_ASSERT(part != RT_NULL); + assert(part != RT_NULL); ret = fal_partition_write(part->fal_part, offset, data, length); @@ -267,7 +261,7 @@ static rt_err_t mtd_nor_dev_erase(struct rt_mtd_nor_device* device, rt_off_t off struct fal_mtd_nor_device *part; part = (struct fal_mtd_nor_device*) device; - RT_ASSERT(part != RT_NULL); + assert(part != RT_NULL); ret = fal_partition_erase(part->fal_part, offset, length); @@ -305,13 +299,13 @@ struct rt_device *fal_mtd_nor_device_create(const char *parition_name) if (!fal_part) { - LOG_E("Error: the partition name (%s) is not found.", parition_name); + log_e("Error: the partition name (%s) is not found.", parition_name); return NULL; } if ((fal_flash = fal_flash_device_find(fal_part->flash_name)) == NULL) { - LOG_E("Error: the flash device name (%s) is not found.", fal_part->flash_name); + log_e("Error: the flash device name (%s) is not found.", fal_part->flash_name); return NULL; } @@ -327,12 +321,12 @@ struct rt_device *fal_mtd_nor_device_create(const char *parition_name) /* set ops */ mtd_nor_dev->parent.ops = &_ops; - LOG_I("The FAL MTD NOR device (%s) created successfully", fal_part->name); + log_i("The FAL MTD NOR device (%s) created successfully", fal_part->name); rt_mtd_nor_register_device(fal_part->name, &mtd_nor_dev->parent); } else { - LOG_E("Error: no memory for create FAL MTD NOR device"); + log_e("Error: no memory for create FAL MTD NOR device"); } return RT_DEVICE(&mtd_nor_dev->parent); @@ -354,7 +348,7 @@ static rt_ssize_t char_dev_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_ int ret = 0; struct fal_char_device *part = (struct fal_char_device *) dev; - RT_ASSERT(part != RT_NULL); + assert(part != RT_NULL); if (pos + size > part->fal_part->len) size = part->fal_part->len - pos; @@ -373,7 +367,7 @@ static rt_ssize_t char_dev_write(rt_device_t dev, rt_off_t pos, const void *buff struct fal_char_device *part; part = (struct fal_char_device *) dev; - RT_ASSERT(part != RT_NULL); + assert(part != RT_NULL); if (pos == 0) { @@ -416,7 +410,7 @@ static int char_dev_fopen(struct dfs_file *fd) { struct fal_char_device *part = (struct fal_char_device *) fd->vnode->data; - RT_ASSERT(part != RT_NULL); + assert(part != RT_NULL); switch (fd->flags & O_ACCMODE) { @@ -435,12 +429,12 @@ static int char_dev_fopen(struct dfs_file *fd) return RT_EOK; } -static int char_dev_fread(struct dfs_file *fd, void *buf, rt_size_t count) +static int char_dev_fread(struct dfs_file *fd, void *buf, size_t count) { int ret = 0; struct fal_char_device *part = (struct fal_char_device *) fd->vnode->data; - RT_ASSERT(part != RT_NULL); + assert(part != RT_NULL); if (DFS_FILE_POS(fd) + count > part->fal_part->len) count = part->fal_part->len - DFS_FILE_POS(fd); @@ -455,12 +449,12 @@ static int char_dev_fread(struct dfs_file *fd, void *buf, rt_size_t count) return ret; } -static int char_dev_fwrite(struct dfs_file *fd, const void *buf, rt_size_t count) +static int char_dev_fwrite(struct dfs_file *fd, const void *buf, size_t count) { int ret = 0; struct fal_char_device *part = (struct fal_char_device *) fd->vnode->data; - RT_ASSERT(part != RT_NULL); + assert(part != RT_NULL); if (DFS_FILE_POS(fd) + count > part->fal_part->len) count = part->fal_part->len - DFS_FILE_POS(fd); @@ -504,13 +498,13 @@ struct rt_device *fal_char_device_create(const char *parition_name) if (!fal_part) { - LOG_E("Error: the partition name (%s) is not found.", parition_name); + log_e("Error: the partition name (%s) is not found.", parition_name); return NULL; } if ((fal_flash_device_find(fal_part->flash_name)) == NULL) { - LOG_E("Error: the flash device name (%s) is not found.", fal_part->flash_name); + log_e("Error: the flash device name (%s) is not found.", fal_part->flash_name); return NULL; } @@ -536,7 +530,7 @@ struct rt_device *fal_char_device_create(const char *parition_name) #endif rt_device_register(RT_DEVICE(char_dev), fal_part->name, RT_DEVICE_FLAG_RDWR); - LOG_I("The FAL char device (%s) created successfully", fal_part->name); + log_i("The FAL char device (%s) created successfully", fal_part->name); #ifdef RT_USING_POSIX_DEVIO /* set fops */ @@ -546,7 +540,7 @@ struct rt_device *fal_char_device_create(const char *parition_name) } else { - LOG_E("Error: no memory for create FAL char device"); + log_e("Error: no memory for create FAL char device"); } return RT_DEVICE(char_dev); @@ -557,7 +551,7 @@ struct rt_device *fal_char_device_create(const char *parition_name) #include extern int fal_init_check(void); -static void fal(rt_uint8_t argc, char **argv) { +static void fal(uint8_t argc, char **argv) { #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ') #define HEXDUMP_WIDTH 16 @@ -570,7 +564,7 @@ static void fal(rt_uint8_t argc, char **argv) { int result = 0; static const struct fal_flash_dev *flash_dev = NULL; static const struct fal_partition *part_dev = NULL; - rt_size_t i = 0, j = 0; + size_t i = 0, j = 0; const char* help_info[] = { @@ -599,7 +593,7 @@ static void fal(rt_uint8_t argc, char **argv) { else { const char *operator = argv[1]; - rt_uint32_t addr, size; + uint32_t addr, size; if (!strcmp(operator, "probe")) { @@ -657,7 +651,7 @@ static void fal(rt_uint8_t argc, char **argv) { { addr = strtol(argv[2], NULL, 0); size = strtol(argv[3], NULL, 0); - rt_uint8_t *data = rt_malloc(size); + uint8_t *data = rt_malloc(size); if (data) { if (flash_dev) @@ -719,7 +713,7 @@ static void fal(rt_uint8_t argc, char **argv) { { addr = strtol(argv[2], NULL, 0); size = argc - 3; - rt_uint8_t *data = rt_malloc(size); + uint8_t *data = rt_malloc(size); if (data) { for (i = 0; i < size; i++) @@ -790,9 +784,9 @@ static void fal(rt_uint8_t argc, char **argv) { return; } /* full chip benchmark test */ - rt_uint32_t start_time, time_cast; - rt_size_t write_size = strtol(argv[2], NULL, 0), read_size = strtol(argv[2], NULL, 0), cur_op_size; - rt_uint8_t *write_data = (rt_uint8_t *)rt_malloc(write_size), *read_data = (rt_uint8_t *)rt_malloc(read_size); + uint32_t start_time, time_cast; + size_t write_size = strtol(argv[2], NULL, 0), read_size = strtol(argv[2], NULL, 0), cur_op_size; + uint8_t *write_data = (uint8_t *)rt_malloc(write_size), *read_data = (uint8_t *)rt_malloc(read_size); if (write_data && read_data) { @@ -886,7 +880,7 @@ static void fal(rt_uint8_t argc, char **argv) { result = fal_partition_read(part_dev, i, read_data, cur_op_size); } /* data check */ - for (rt_size_t index = 0; index < cur_op_size; index ++) + for (size_t index = 0; index < cur_op_size; index ++) { if (write_data[index] != read_data[index]) { @@ -942,3 +936,4 @@ static void fal(rt_uint8_t argc, char **argv) { MSH_CMD_EXPORT(fal, FAL (Flash Abstraction Layer) operate.); #endif /* defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) */ +#endif /* RT_VER_NUM */ diff --git a/rt-thread/components/finsh/finsh.h b/rt-thread/components/finsh/finsh.h index 530ab9b..9fe36fa 100644 --- a/rt-thread/components/finsh/finsh.h +++ b/rt-thread/components/finsh/finsh.h @@ -130,13 +130,13 @@ typedef long (*syscall_func)(void); #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) /** - * @ingroup finsh + * @ingroup msh * * This macro exports a command to module shell. * - * param command is the name of the command. - * param desc is the description of the command, which will show in help list. - * param opt This is an option, enter any content to enable option completion + * @param command is the name of the command. + * @param desc is the description of the command, which will show in help list. + * @param opt This is an option, enter any content to enable option completion */ /* MSH_CMD_EXPORT(command, desc) or MSH_CMD_EXPORT(command, desc, opt) */ #define MSH_CMD_EXPORT(...) \ @@ -144,18 +144,17 @@ typedef long (*syscall_func)(void); _MSH_FUNCTION_CMD2)(__VA_ARGS__) /** - * @ingroup finsh + * @ingroup msh * * This macro exports a command with alias to module shell. * - * param command is the name of the command. - * param alias is the alias of the command. - * param desc is the description of the command, which will show in help list. - * param opt This is an option, enter any content to enable option completion - * @code + * @param command is the name of the command. + * @param alias is the alias of the command. + * @param desc is the description of the command, which will show in help list. + * @param opt This is an option, enter any content to enable option completion + * @note * #define MSH_CMD_EXPORT_ALIAS(command, alias, desc) or * #define MSH_CMD_EXPORT_ALIAS(command, alias, desc, opt) - * @endcode */ #define MSH_CMD_EXPORT_ALIAS(...) \ __MSH_GET_EXPORT_MACRO(__VA_ARGS__, _MSH_FUNCTION_EXPORT_CMD3_OPT, \ diff --git a/rt-thread/components/finsh/msh.c b/rt-thread/components/finsh/msh.c index d8586e5..9cc0c6b 100644 --- a/rt-thread/components/finsh/msh.c +++ b/rt-thread/components/finsh/msh.c @@ -755,10 +755,10 @@ void msh_auto_complete_path(char *path) } else if (S_ISLNK(buffer.st_mode)) { - DIR *link_dir = opendir(path); - if (link_dir) + DIR *dir = opendir(path); + if (dir) { - closedir(link_dir); + closedir(dir); strcat(path, "/"); } } diff --git a/rt-thread/components/finsh/shell.c b/rt-thread/components/finsh/shell.c index a9aa830..e698edd 100644 --- a/rt-thread/components/finsh/shell.c +++ b/rt-thread/components/finsh/shell.c @@ -32,11 +32,6 @@ #include #endif /* DFS_USING_POSIX */ -#ifdef RT_USING_POSIX_STDIO -#include -#include -#endif /* RT_USING_POSIX_STDIO */ - /* finsh thread */ #ifndef RT_USING_HEAP static struct rt_thread finsh_thread; @@ -159,7 +154,7 @@ int finsh_getchar(void) #ifdef RT_USING_DEVICE char ch = 0; #ifdef RT_USING_POSIX_STDIO - if(read(rt_posix_stdio_get_console(), &ch, 1) > 0) + if(read(STDIN_FILENO, &ch, 1) > 0) { return ch; } diff --git a/rt-thread/components/legacy/fdt/Kconfig b/rt-thread/components/legacy/fdt/Kconfig index a92c3c4..af3c4ef 100644 --- a/rt-thread/components/legacy/fdt/Kconfig +++ b/rt-thread/components/legacy/fdt/Kconfig @@ -9,7 +9,7 @@ config RT_USING_FDT bool "Using fdt fwnode for device drivers" default n config FDT_USING_DEBUG - bool "Using fdt debug function" + bool "Using fdt debug function " default n endif diff --git a/rt-thread/components/libc/compilers/common/cstring.c b/rt-thread/components/libc/compilers/common/cstring.c index 41f6c65..59c516d 100644 --- a/rt-thread/components/libc/compilers/common/cstring.c +++ b/rt-thread/components/libc/compilers/common/cstring.c @@ -13,13 +13,13 @@ #include #include -#ifndef RT_USING_PICOLIBC /** * @brief erases the data in the n bytes of the memory starting at the * location pointed to by s, by writing zeros (bytes containing '\0') to that area. * * @note The bzero() function is deprecated (marked as LEGACY in POSIX. 1-2001). */ +#ifndef RT_USING_PICOLIBC void bzero(void* s, size_t n) { rt_memset(s, 0, n); @@ -46,12 +46,12 @@ void explicit_bzero(void* s, size_t n) } } -char *index(const char* s, int c) +char* index(const char* s, int c) { return strchr(s, c); } -char *rindex(const char* s, int c) +char* rindex(const char* s, int c) { return strrchr(s, c); } @@ -99,7 +99,7 @@ int ffsll(long long i) * * @note This function is GNU extension, available since glibc 2.1.91. */ -void *memrchr(const void* ptr, int ch, size_t pos) +void* memrchr(const void* ptr, int ch, size_t pos) { char* end = (char*)ptr + pos - 1; while (end != ptr) @@ -118,7 +118,7 @@ size_t strnlen(const char *s, size_t maxlen) return sc - s; } -char *strchrnul(const char* s, int c) +char* strchrnul(const char* s, int c) { while (*s != '\0' && *s != c) s++; diff --git a/rt-thread/components/libc/compilers/common/ctime.c b/rt-thread/components/libc/compilers/common/ctime.c index 7910356..ef006c4 100644 --- a/rt-thread/components/libc/compilers/common/ctime.c +++ b/rt-thread/components/libc/compilers/common/ctime.c @@ -30,10 +30,8 @@ #include "sys/time.h" #include -#include -#ifdef RT_USING_RTC #include -#endif /* RT_USING_RTC */ +#include #include #include #ifdef RT_USING_SMART @@ -70,8 +68,8 @@ static const short __spm[13] = (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31), }; -rt_align(RT_ALIGN_SIZE) static const char days[] = "Sun Mon Tue Wed Thu Fri Sat "; -rt_align(RT_ALIGN_SIZE) static const char months[] = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec "; +rt_align(RT_ALIGN_SIZE) static const char *days = "Sun Mon Tue Wed Thu Fri Sat "; +rt_align(RT_ALIGN_SIZE) static const char *months = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec "; #ifndef __isleap static int __isleap(int year) @@ -89,9 +87,9 @@ static void num2str(char *c, int i) c[1] = i % 10 + '0'; } -#ifdef RT_USING_RTC static rt_err_t _control_rtc(int cmd, void *arg) { +#ifdef RT_USING_RTC static rt_device_t device = RT_NULL; rt_err_t rst = -RT_ERROR; @@ -115,8 +113,11 @@ static rt_err_t _control_rtc(int cmd, void *arg) return -RT_ENOSYS; } return rst; -} +#else + LOG_W(_WARNING_NO_RTC); + return -RT_ENOSYS; #endif /* RT_USING_RTC */ +} /* lightweight timezone and daylight saving time */ #ifdef RT_LIBC_USING_LIGHT_TZ_DST @@ -339,7 +340,6 @@ RTM_EXPORT(strftime); /* inherent in the toolchain */ */ rt_weak time_t time(time_t *t) { -#ifdef RT_USING_RTC time_t _t; if (_control_rtc(RT_DEVICE_CTRL_RTC_GET_TIME, &_t) != RT_EOK) @@ -352,10 +352,6 @@ rt_weak time_t time(time_t *t) *t = _t; return _t; -#else - rt_set_errno(EFAULT); - return (time_t)-1; -#endif } RTM_EXPORT(time); @@ -367,12 +363,10 @@ RTM_EXPORT(clock); int stime(const time_t *t) { -#ifdef RT_USING_RTC if ((t != RT_NULL) && (_control_rtc(RT_DEVICE_CTRL_RTC_SET_TIME, (void *)t) == RT_EOK)) { return 0; } -#endif /* RT_USING_RTC */ rt_set_errno(EFAULT); return -1; @@ -481,7 +475,6 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) #endif /* RT_LIBC_USING_LIGHT_TZ_DST */ } -#ifdef RT_USING_RTC if (tv != RT_NULL) { tv->tv_sec = 0; @@ -499,7 +492,6 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) } } } -#endif /* RT_USING_RTC */ rt_set_errno(EINVAL); return -1; @@ -513,7 +505,6 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz) * The tz_dsttime field has never been used under Linux. * Thus, the following is purely of historic interest. */ -#ifdef RT_USING_RTC if (tv != RT_NULL && (long)tv->tv_usec >= 0 && (long)tv->tv_sec >= 0) { if (_control_rtc(RT_DEVICE_CTRL_RTC_SET_TIMEVAL, (void *)tv) == RT_EOK) @@ -528,7 +519,6 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz) } } } -#endif /* RT_USING_RTC */ rt_set_errno(EINVAL); return -1; @@ -604,9 +594,7 @@ int clock_getres(clockid_t clockid, struct timespec *res) { case CLOCK_REALTIME: // use RTC case CLOCK_REALTIME_COARSE: -#ifdef RT_USING_RTC return _control_rtc(RT_DEVICE_CTRL_RTC_GET_TIMERES, res); -#endif /* RT_USING_RTC */ case CLOCK_MONOTONIC: // use cputimer case CLOCK_MONOTONIC_COARSE: @@ -637,9 +625,7 @@ int clock_gettime(clockid_t clockid, struct timespec *tp) { case CLOCK_REALTIME: // use RTC case CLOCK_REALTIME_COARSE: -#ifdef RT_USING_RTC return _control_rtc(RT_DEVICE_CTRL_RTC_GET_TIMESPEC, tp); -#endif /* RT_USING_RTC */ case CLOCK_MONOTONIC: // use boottime case CLOCK_MONOTONIC_COARSE: @@ -680,11 +666,9 @@ int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp, s switch (clockid) { case CLOCK_REALTIME: // use RTC -#ifdef RT_USING_RTC if (flags & TIMER_ABSTIME) err = _control_rtc(RT_DEVICE_CTRL_RTC_GET_TIMESPEC, &ts); break; -#endif /* RT_USING_RTC */ case CLOCK_MONOTONIC: // use boottime case CLOCK_PROCESS_CPUTIME_ID: @@ -733,10 +717,8 @@ int clock_settime(clockid_t clockid, const struct timespec *tp) switch (clockid) { -#ifdef RT_USING_RTC case CLOCK_REALTIME: return _control_rtc(RT_DEVICE_CTRL_RTC_SET_TIMESPEC, (void *)tp); -#endif /* RT_USING_RTC */ case CLOCK_REALTIME_COARSE: case CLOCK_MONOTONIC: @@ -801,7 +783,7 @@ RTM_EXPORT(rt_timespec_to_tick); struct timer_obj { struct rt_ktime_hrtimer hrtimer; - void (*sigev_notify_func)(union sigval val); + void (*sigev_notify_function)(union sigval val); union sigval val; struct timespec interval; /* Reload value */ struct timespec value; /* Reload value */ @@ -903,7 +885,7 @@ static void rtthread_timer_wrapper(void *timerobj) } #ifdef RT_USING_SMART /* this field is named as tid in musl */ - void *ptid = &timer->sigev_notify_func; + void *ptid = &timer->sigev_notify_function; int tid = *(int *)ptid; struct lwp_timer_event_param *data = rt_container_of(timer->work, struct lwp_timer_event_param, work); data->signo = timer->sigev_signo; @@ -922,9 +904,9 @@ static void rtthread_timer_wrapper(void *timerobj) if (rt_work_submit(timer->work, 0)) RT_ASSERT(0); #else - if(timer->sigev_notify_func != RT_NULL) + if(timer->sigev_notify_function != RT_NULL) { - (timer->sigev_notify_func)(timer->val); + (timer->sigev_notify_function)(timer->val); } #endif /* RT_USING_SMART */ } @@ -1012,7 +994,7 @@ int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid) timer->work = work; #endif /* RT_USING_SMART */ - timer->sigev_notify_func = evp->sigev_notify_function; + timer->sigev_notify_function = evp->sigev_notify_function; timer->val = evp->sigev_value; timer->interval.tv_sec = 0; timer->interval.tv_nsec = 0; @@ -1199,13 +1181,11 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, switch (timer->clockid) { -#ifdef RT_USING_RTC case CLOCK_REALTIME: case CLOCK_REALTIME_ALARM: if (flags & TIMER_ABSTIME) err = _control_rtc(RT_DEVICE_CTRL_RTC_GET_TIMESPEC, &ts); break; -#endif /* RT_USING_RTC */ case CLOCK_MONOTONIC: case CLOCK_BOOTTIME: case CLOCK_BOOTTIME_ALARM: diff --git a/rt-thread/components/libc/compilers/common/cwchar.c b/rt-thread/components/libc/compilers/common/cwchar.c index efa0a7c..c808083 100644 --- a/rt-thread/components/libc/compilers/common/cwchar.c +++ b/rt-thread/components/libc/compilers/common/cwchar.c @@ -112,12 +112,12 @@ int wcwidth(wchar_t ucs) (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ (ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */ - (ucs >= 0xffe0 && ucs <= 0xffe6) || - #ifndef _WIN32 - (ucs >= 0x20000 && ucs <= 0x2ffff) - #else - 0 - #endif + (ucs >= 0xffe0 && ucs <= 0xffe6) // || + //#ifndef _WIN32 + // (ucs >= 0x20000 && ucs <= 0x2ffff) + //#else + // 0 + //#endif )); } diff --git a/rt-thread/components/libc/compilers/common/include/dirent.h b/rt-thread/components/libc/compilers/common/include/dirent.h index 6020e95..51451e2 100644 --- a/rt-thread/components/libc/compilers/common/include/dirent.h +++ b/rt-thread/components/libc/compilers/common/include/dirent.h @@ -65,19 +65,6 @@ struct dirent }; #endif -#ifdef RT_USING_MUSLLIBC -typedef uint64_t ino_t; -#endif -struct libc_dirent { -#ifdef RT_USING_MUSLLIBC - ino_t d_ino; -#endif - off_t d_off; - unsigned short d_reclen; - unsigned char d_type; - char d_name[DIRENT_NAME_MAX]; -}; - int closedir(DIR *); DIR *opendir(const char *); struct dirent *readdir(DIR *); diff --git a/rt-thread/components/libc/compilers/musl/fcntl.h b/rt-thread/components/libc/compilers/musl/fcntl.h index 51387f7..9388f10 100644 --- a/rt-thread/components/libc/compilers/musl/fcntl.h +++ b/rt-thread/components/libc/compilers/musl/fcntl.h @@ -22,33 +22,18 @@ #define O_DSYNC 010000 #define O_SYNC 04010000 #define O_RSYNC 04010000 +#define O_DIRECTORY 040000 +#define O_NOFOLLOW 0100000 #define O_CLOEXEC 02000000 #define O_ASYNC 020000 +#define O_DIRECT 0200000 +#define O_LARGEFILE 0400000 #define O_NOATIME 01000000 #define O_PATH 010000000 +#define O_TMPFILE 020040000 #define O_NDELAY O_NONBLOCK -#ifndef O_LARGEFILE -#define O_LARGEFILE 0400000 -#endif - -#ifndef O_DIRECT -#define O_DIRECT 0200000 -#endif - -#ifndef O_TMPFILE -#define O_TMPFILE 020040000 -#endif - -#ifndef O_NOFOLLOW -#define O_NOFOLLOW 0100000 -#endif - -#ifndef O_DIRECTORY -#define O_DIRECTORY 040000 -#endif - #ifndef O_BINARY #define O_BINARY 00 #endif diff --git a/rt-thread/components/libc/posix/io/timerfd/timerfd.c b/rt-thread/components/libc/posix/io/timerfd/timerfd.c index ddf46fd..19f86e4 100644 --- a/rt-thread/components/libc/posix/io/timerfd/timerfd.c +++ b/rt-thread/components/libc/posix/io/timerfd/timerfd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -546,100 +546,16 @@ static int timerfd_do_gettime(int fd, struct itimerspec *cur) return 0; } -/** - * @brief Creates a file descriptor for a timer. - * - * The `timerfd_create` function creates a new timer object that generates - * timer expiration notifications via a file descriptor. - * - * @param clockid The clock ID that specifies the clock to be used as the - * timing base for the timer. Common values include: - * - `CLOCK_REALTIME`: A system-wide clock representing - * wall-clock time. - * - `CLOCK_MONOTONIC`: A clock that cannot be set and - * represents monotonic time since some unspecified - * starting point. - * @param flags A bitmask that can include the following flags: - * - `TFD_CLOEXEC`: Close the file descriptor on `execve`. - * - `TFD_NONBLOCK`: Set the file descriptor to non-blocking mode. - * - * @return On success, returns a file descriptor for the timer. On error, - * returns -1 and sets `errno` appropriately. - * - * @note The file descriptor can be used with select, poll, or epoll to wait - * for timer expirations. - * - * @warning The timerfd interface is Linux-specific and may not be available - * on other operating systems. - * - * @see timerfd_settime, timerfd_gettime - */ int timerfd_create(int clockid, int flags) { return timerfd_do_create(clockid, flags); } -/** - * @brief Sets the time for a timer file descriptor. - * - * The `timerfd_settime` function starts or modifies the timer associated - * with the specified timer file descriptor. - * - * @param fd The file descriptor of the timer, obtained from - * `timerfd_create`. - * @param flags Flags that control the behavior of the timer. Possible - * values include: - * - `0`: Relative time is specified in `new`. - * - `TFD_TIMER_ABSTIME`: Use absolute time instead of - * relative time. - * @param new A pointer to a `itimerspec` structure that specifies the - * new timer settings: - * - `it_value`: The initial expiration time. A zero value - * means the timer is disabled. - * - `it_interval`: The interval for periodic timers. A zero - * value means the timer is not periodic. - * @param old A pointer to a `itimerspec` structure to store the - * previous timer settings. Can be `NULL` if this information - * is not needed. - * - * @return On success, returns 0. On error, returns -1 and sets `errno` - * appropriately. - * - * @note The timer starts counting down immediately after this call if - * `it_value` is non-zero. - * - * @warning If the timer is set to a very short interval, high-frequency - * events may impact system performance. - * - * @see timerfd_create, timerfd_gettime - */ int timerfd_settime(int fd, int flags, const struct itimerspec *new, struct itimerspec *old) { return timerfd_do_settime(fd, flags, new, old); } -/** - * @brief Retrieves the current value and interval of a timer. - * - * The `timerfd_gettime` function queries the settings of the timer associated - * with the specified timer file descriptor. - * - * @param fd The file descriptor of the timer, obtained from `timerfd_create`. - * @param cur A pointer to a `itimerspec` structure where the current timer - * settings will be stored: - * - `it_value`: The time remaining until the next expiration. - * If zero, the timer is disabled. - * - `it_interval`: The interval for periodic timers. Zero if the - * timer is not periodic. - * - * @return On success, returns 0. On error, returns -1 and sets `errno` - * appropriately. - * - * @note This function does not reset or modify the timer; it only retrieves - * the current settings. - * - * @see timerfd_create, timerfd_settime - */ int timerfd_gettime(int fd, struct itimerspec *cur) { return timerfd_do_gettime(fd, cur); diff --git a/rt-thread/components/libc/posix/libdl/arch/arm.c b/rt-thread/components/libc/posix/libdl/arch/arm.c index 7914df2..2996f2e 100644 --- a/rt-thread/components/libc/posix/libdl/arch/arm.c +++ b/rt-thread/components/libc/posix/libdl/arch/arm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/rt-thread/components/libc/posix/libdl/arch/riscv.c b/rt-thread/components/libc/posix/libdl/arch/riscv.c index 13a4eda..8dd0978 100644 --- a/rt-thread/components/libc/posix/libdl/arch/riscv.c +++ b/rt-thread/components/libc/posix/libdl/arch/riscv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/rt-thread/components/libc/posix/libdl/arch/x86.c b/rt-thread/components/libc/posix/libdl/arch/x86.c index 7d59146..1987d45 100644 --- a/rt-thread/components/libc/posix/libdl/arch/x86.c +++ b/rt-thread/components/libc/posix/libdl/arch/x86.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/rt-thread/components/libc/posix/libdl/dlclose.c b/rt-thread/components/libc/posix/libdl/dlclose.c index 8763892..876a157 100644 --- a/rt-thread/components/libc/posix/libdl/dlclose.c +++ b/rt-thread/components/libc/posix/libdl/dlclose.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -13,15 +13,6 @@ #include "dlmodule.h" -/** - * @brief close a dynamically loaded shared library. - * - * @param handle the handle which identifies the shared library to be closed. - * @return int it returns RT_TRUE on success. - * - * @note This function is an API of POSIX standard, which is designed to decrease the reference count (nref) for a dynamically loaded module - * and destroy it if no references remain. - */ int dlclose(void *handle) { struct rt_dlmodule *module; diff --git a/rt-thread/components/libc/posix/libdl/dlelf.c b/rt-thread/components/libc/posix/libdl/dlelf.c index 9e8f1c6..418ad75 100644 --- a/rt-thread/components/libc/posix/libdl/dlelf.c +++ b/rt-thread/components/libc/posix/libdl/dlelf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -14,32 +14,8 @@ #define DBG_TAG "DLMD" #define DBG_LVL DBG_INFO -#include /* must after of DEBUG_ENABLE or some other options*/ +#include // must after of DEBUG_ENABLE or some other options -/** - * @brief Load a shared object file into memory. - * - * @param module A pointer to a rt_dlmodule object for holding the module's information. - * @param module_ptr A pointer to the raw memory of the ELF file (shared object) that is being loaded. - * @return rt_err_t On success, it returns RT_EOK. Otherwise, it returns the error code. - * - * @note This function loads a shared object (ELF file) into memory, broken down into steps: - * 1. Initialization and Validation: it begins by validating the module pointer - * and checking if the ELF file has been linked by comparing its magic number (RTMMAG). - * If matched, the module is considered linked. - * 2. Calculating the ELF Image Size: it iterates over the ELF program headers to compute the total size of the ELF image - * by adding the sizes of loadable segments. It also ensures there are no overlaps or invalid addresses in the segments. - * 3. Allocating Memory for the Module: After determining the module size, the function allocates memory (module->mem_space) for the ELF image - * and initializes it to zero. Then, it copies the relevant program segments from the ELF file into this allocated memory. - * 4. Setting the Module Entry Point: it sets the entry point address (module->entry_addr) based on the ELF entry point adjusted by the calculated base address. - * 5. Handling Relocation Sections: It processes each relocation section in the ELF file. - * For each relocation entry, it either resolves the symbol from the module's own symbol table - * or looks up the symbol in the kernel symbol table if it was not found locally. - * 6. Building the Module's Symbol Table: it looks for the .dynsym section to extract global function symbols. - * It creates a symbol table (module->symtab) and populates it with the function names and addresses for all global symbols of type STT_FUNC. - * 7. Extracting Additional Parameters: It extracts additional parameters, such as thread priority (dlmodule_thread_priority) and stack size (dlmodule_thread_stacksize), - * from the symbol table and assigns them to the module if valid. - */ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_ptr) { rt_bool_t linked = RT_FALSE; @@ -297,23 +273,6 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt return RT_EOK; } -/** - * @brief Load a relocatable file into memory. - * - * @param module A pointer to a rt_dlmodule object for holding the module's information. - * @param module_ptr A pointer to the raw memory of the ELF file (relocatable file) that is being loaded. - * @return rt_err_t On success, it returns RT_EOK. Otherwise, it returns the error code. - * - * @note This function loads a relocatable file (ELF file) into memory, broken down step by step: - * 1. Calculate Module Size: iterates over the ELF sections (text, data, rodata, and bss) to calculate the total size of the module - * and identifies the start address for each section. - * 2. Allocate Memory: It allocates memory for the module based on the calculated size. If allocation fails, an error is returned. - * 3. Load Sections into Memory: The function loads the text, rodata, data, and BSS sections into the allocated memory. - * The BSS section is zeroed out, while the others are copied from the ELF image. - * 4. Set Entry Point: The entry point of the module is set by calculating the address relative to the start of the allocated memory. - * 5. Handle Relocation: It processes the relocation entries, resolving symbol addresses and relocating them as needed. - * This includes functions, sections (rodata, bss, data), and external symbols from the kernel symbol table. - */ rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module_ptr) { rt_ubase_t index, rodata_addr = 0, bss_addr = 0, data_addr = 0; diff --git a/rt-thread/components/libc/posix/libdl/dlelf.h b/rt-thread/components/libc/posix/libdl/dlelf.h index 6b03271..339e172 100644 --- a/rt-thread/components/libc/posix/libdl/dlelf.h +++ b/rt-thread/components/libc/posix/libdl/dlelf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/rt-thread/components/libc/posix/libdl/dlerror.c b/rt-thread/components/libc/posix/libdl/dlerror.c index 7c5ce45..de948eb 100644 --- a/rt-thread/components/libc/posix/libdl/dlerror.c +++ b/rt-thread/components/libc/posix/libdl/dlerror.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -11,13 +11,6 @@ #include #include -/** - * @brief retrieve a string describing the last error that occurred from a dynamic linking operation. - * - * @return const char* a string containing an error message describing the last error. - * - * @note This function is an API of POSIX standard, which is still remaining TBD. - */ const char *dlerror(void) { return "TODO"; diff --git a/rt-thread/components/libc/posix/libdl/dlfcn.h b/rt-thread/components/libc/posix/libdl/dlfcn.h index 7cbbc7d..f5c9063 100644 --- a/rt-thread/components/libc/posix/libdl/dlfcn.h +++ b/rt-thread/components/libc/posix/libdl/dlfcn.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/rt-thread/components/libc/posix/libdl/dlmodule.c b/rt-thread/components/libc/posix/libdl/dlmodule.c index 269e7bc..0d05190 100644 --- a/rt-thread/components/libc/posix/libdl/dlmodule.c +++ b/rt-thread/components/libc/posix/libdl/dlmodule.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -24,7 +24,7 @@ #define DBG_TAG "DLMD" #define DBG_LVL DBG_INFO -#include /* must after of DEBUG_ENABLE or some other options*/ +#include // must after of DEBUG_ENABLE or some other options static struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL; static struct rt_module_symtab *_rt_module_symtab_end = RT_NULL; @@ -176,11 +176,6 @@ __exit: return ; } -/** - * @brief create a dynamic module object and initialize it. - * - * @return struct rt_dlmodule* If module create successfully, return the pointer to its rt_dlmodule structure. - */ struct rt_dlmodule *dlmodule_create(void) { struct rt_dlmodule *module = RT_NULL; @@ -238,12 +233,6 @@ void dlmodule_destroy_subthread(struct rt_dlmodule *module, rt_thread_t thread) #endif } -/** - * @brief destroy dynamic module and cleanup all kernel objects inside it. - * - * @param module Pointer to the module to be destroyed. - * @return rt_err_t On success, it returns RT_EOK. Otherwise, it returns the error code. - */ rt_err_t dlmodule_destroy(struct rt_dlmodule* module) { int i; @@ -266,7 +255,7 @@ rt_err_t dlmodule_destroy(struct rt_dlmodule* module) rt_exit_critical(); } - /* list_object(&(module->object_list));*/ + // list_object(&(module->object_list)); /* cleanup for all kernel objects inside module*/ { @@ -404,11 +393,6 @@ rt_err_t dlmodule_destroy(struct rt_dlmodule* module) return RT_EOK; } -/** - * @brief retrieve the dynamically loaded module that the current thread belongs to. - * - * @return struct rt_dlmodule* On success, it returns a pointer to the module. otherwise, it returns RT_NULL. - */ struct rt_dlmodule *dlmodule_self(void) { rt_thread_t tid; @@ -431,20 +415,6 @@ struct rt_dlmodule *rt_module_self(void) return dlmodule_self(); } -/** - * @brief load an ELF module to memory. - * - * @param filename the path to the module to load. - * @return struct rt_dlmodule* On success, it returns a pointer to the module object. otherwise, RT_NULL is returned. - * - * @note the function is used to load an ELF (Executable and Linkable Format) module from a file, validate it, - * and initialize it as a dynamically loaded module. what it implements are as follows: - * 1. Load and Validate ELF: It loads an ELF file, checks its validity, and identifies it as either a relocatable or shared object. - * 2. Memory Allocation and Cleanup: Uses rt_malloc and rt_free to allocate and free memory for module data. - * Error handling ensures all resources are released if an error occurs. - * 3. Symbol Resolution and Initialization: Sets up init function and cleanup function, and calls the module_init function if it is present. - * 4. Cache Management: Optionally (when RT_USING_CACHE defined) flushes data and invalidates instruction caches to ensure the module is correctly loaded into memory. - */ struct rt_dlmodule* dlmodule_load(const char* filename) { #ifdef RT_USING_POSIX_FS @@ -555,14 +525,6 @@ __exit: return RT_NULL; } -/** - * @brief load a dynamic module, and create a thread to excute the module main function. - * - * @param pgname path of the module to be loaded. - * @param cmd the command string (with commandline options) for startup module. - * @param cmd_size the command's length. - * @return struct rt_dlmodule* On success, it returns a pointer to the module object. otherwise, RT_NULL is returned. - */ struct rt_dlmodule* dlmodule_exec(const char* pgname, const char* cmd, int cmd_size) { struct rt_dlmodule *module = RT_NULL; @@ -780,17 +742,6 @@ struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, in } #endif -/** - * @brief exit a dynamically loaded module. - * - * @param ret_code the return code for module exit. - * - * @note this function is responsible for gracefully exiting a dynamically loaded module, releasing resources associated with the module, - * and handling cleanup operations. what it implements are as follows: - * 1. Thread and Resource Cleanup: The function safely exits a module by deleting its main thread and freeing resources associated with it. - * 2. Status Management: Checks and updates the module's state, setting a return code and calling _dlmodule_exit() to transition to a closing state. - * 3. Critical Sections: Critical sections ensure that the exit process is atomic and free from race conditions. - */ void dlmodule_exit(int ret_code) { rt_thread_t thread; @@ -833,13 +784,6 @@ void dlmodule_exit(int ret_code) rt_exit_critical(); } -/** - * @brief search for a symbol by its name in the kernel symbol table. - * - * @param sym_str the symbol name string. - * @return rt_uint32_t On success, it returns the address of the symbol. - * Otherwise, it returns 0 (indicating the symbol was not found). - */ rt_uint32_t dlmodule_symbol_find(const char *sym_str) { /* find in kernel symbol table */ diff --git a/rt-thread/components/libc/posix/libdl/dlmodule.h b/rt-thread/components/libc/posix/libdl/dlmodule.h index 62a0cdd..183faca 100644 --- a/rt-thread/components/libc/posix/libdl/dlmodule.h +++ b/rt-thread/components/libc/posix/libdl/dlmodule.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/rt-thread/components/libc/posix/libdl/dlopen.c b/rt-thread/components/libc/posix/libdl/dlopen.c index 8545bce..bcb57d7 100644 --- a/rt-thread/components/libc/posix/libdl/dlopen.c +++ b/rt-thread/components/libc/posix/libdl/dlopen.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -16,19 +16,6 @@ #define MODULE_ROOT_DIR "/modules" -/** - * @brief dynamically load a shared library at runtime. - * - * @param filename the path to the shared library to load, which shouldn't be set to NULL. - * @param flags options for loading the shared library. - * @return void* on success, it returns a handle (a pointer) to the opened shared library, otherwise it returns NULL. - * - * @note This function is an API of POSIX standard, which is used for dynamically loading shared libraries at runtime. - * the function first tries to check if the module is already loaded, by finding module in module list. - * If module is found in memory (RT_NULL check fails), the reference count (nref) is incremented. - * Otherwise, dlmodule_load() will be called to load the module into memory. - * A handle (a pointer to the module) is returned at last, which can be used with other functions like dlsym(). - */ void* dlopen(const char *filename, int flags) { struct rt_dlmodule *module; diff --git a/rt-thread/components/libc/posix/libdl/dlsym.c b/rt-thread/components/libc/posix/libdl/dlsym.c index 372cec6..f7c1c90 100644 --- a/rt-thread/components/libc/posix/libdl/dlsym.c +++ b/rt-thread/components/libc/posix/libdl/dlsym.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -13,17 +13,6 @@ #include "dlmodule.h" -/** - * @brief look up the address of a symbol in a dynamically loaded shared library. - * - * @param handle the handle returned by dlopen() when the library was previously loaded. - * @param symbol A string containing the name of the symbol to locate. - * @return void* On success, it returns a pointer to the symbol. Otherwise, it returns RT_NULL. - * - * @note This function is an API of POSIX standard, which is commonly used in conjunction with dlopen() to retrieve function pointers from shared libraries. - * the input symbol name, which can be the name of a function or variable, is compared with each symbol - * in the module symbol table. if the same symbol is found, return its address. - */ void* dlsym(void *handle, const char* symbol) { int i; diff --git a/rt-thread/components/libc/posix/libdl/dlsyms.c b/rt-thread/components/libc/posix/libdl/dlsyms.c index 8476b10..e6ca23b 100644 --- a/rt-thread/components/libc/posix/libdl/dlsyms.c +++ b/rt-thread/components/libc/posix/libdl/dlsyms.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * diff --git a/rt-thread/components/libc/posix/pthreads/pthread.c b/rt-thread/components/libc/posix/pthreads/pthread.c index 0ad8f9f..0d7ed8f 100644 --- a/rt-thread/components/libc/posix/pthreads/pthread.c +++ b/rt-thread/components/libc/posix/pthreads/pthread.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -213,42 +213,6 @@ static void pthread_entry_stub(void *parameter) } } -/** - * @brief Creates a new thread in a POSIX-compliant system. - * - * The `pthread_create` function initializes a new thread in the calling process. The new thread starts execution - * by invoking the function specified by the `start` parameter. The thread runs concurrently with the calling thread. - * - * @param[out] pid - * A pointer to a `pthread_t` object where the ID of the newly created thread will be stored. - * This ID can be used to refer to the thread in subsequent function calls. - * - * @param[in] attr - * A pointer to a `pthread_attr_t` object that specifies attributes for the new thread, or `NULL` for default attributes. - * Default attributes include: - * - Detached state: joinable. - * - Stack size: implementation-defined default. - * - * @param[in] start - * A pointer to the function that the new thread will execute. This function must have the following signature: - * `void *start(void *parameter)`. - * - * @param[in] parameter - * A pointer to data passed as an argument to the `start` function. The meaning and handling of this data is determined - * by the `start` function. - * - * @return - * Returns 0 on success. On failure, a non-zero error code is returned, indicating the error condition: - * - `EAGAIN`: Insufficient resources to create another thread. - * - `EINVAL`: Invalid attributes specified in `attr`. - * - `EPERM`: Insufficient permissions to set the requested attributes. - * - * @note - * It is the caller's responsibility to manage the lifetime of any resources associated with the new thread. - * If the thread is not detached, it must be joined using `pthread_join` to avoid resource leaks. - * - * @see pthread_join, pthread_exit, pthread_attr_init - */ int pthread_create(pthread_t *pid, const pthread_attr_t *attr, void *(*start)(void *), void *parameter) @@ -370,28 +334,6 @@ __exit: } RTM_EXPORT(pthread_create); -/** - * @brief Marks a thread as detached, allowing its resources to be automatically released upon termination. - * - * The `pthread_detach` function separates the specified thread from the calling thread. Once a thread is detached, - * its resources will be automatically reclaimed by the system upon the thread's termination. A detached thread cannot - * be joined using `pthread_join`. - * - * @param[in] thread - * The thread ID of the thread to be detached. This must be a valid thread ID returned by `pthread_create`. - * - * @return - * Returns 0 on success. On failure, an error code is returned: - * - `EINVAL`: The specified thread is not joinable or is already detached. - * - `ESRCH`: No thread with the specified ID could be found. - * - * @note - * - Detaching a thread allows it to run independently. Once detached, the thread's termination status cannot - * be retrieved, and it cannot be joined. - * - Threads can be created in a detached state using attributes set with `pthread_attr_setdetachstate`. - * - * @see pthread_create, pthread_join, pthread_attr_setdetachstate - */ int pthread_detach(pthread_t thread) { int ret = 0; @@ -436,33 +378,6 @@ __exit: } RTM_EXPORT(pthread_detach); -/** - * @brief Waits for the specified thread to terminate and retrieves its exit status. - * - * The `pthread_join` function blocks the calling thread until the specified thread terminates. - * If the specified thread has already terminated, it returns immediately. The exit status of - * the terminated thread can optionally be retrieved via the `value_ptr` parameter. - * - * @param[in] thread - * The thread ID of the thread to wait for. This must be a joinable thread created with `pthread_create`. - * - * @param[out] value_ptr - * A pointer to a location where the exit status of the terminated thread will be stored. - * If the thread terminated by calling `pthread_exit`, the value passed to `pthread_exit` - * will be stored at this location. If this parameter is `NULL`, the exit status is ignored. - * - * @return - * Returns 0 on success. On failure, an error code is returned: - * - `ESRCH`: The specified thread does not exist. - * - `EINVAL`: The specified thread is not joinable. - * - `EDEADLK`: A deadlock was detected (e.g., a thread tries to join itself). - * - * @note - * - Threads must not be detached to use `pthread_join`. - * - If `pthread_join` is not called for joinable threads, their resources are not released, leading to resource leaks. - * - * @see pthread_create, pthread_exit, pthread_detach - */ int pthread_join(pthread_t thread, void **value_ptr) { _pthread_data_t *ptd; @@ -475,7 +390,7 @@ int pthread_join(pthread_t thread, void **value_ptr) return EINVAL; /* invalid pthread id */ } - if (ptd->tid == rt_thread_self()) + if (ptd && ptd->tid == rt_thread_self()) { /* join self */ return EDEADLK; @@ -505,25 +420,6 @@ int pthread_join(pthread_t thread, void **value_ptr) } RTM_EXPORT(pthread_join); -/** - * @brief Returns the thread ID of the calling thread. - * - * The `pthread_self` function returns the thread ID of the calling thread. The thread ID is unique to the - * thread within a process and can be used to identify the calling thread in the context of multithreading. - * - * The value returned by `pthread_self` can be compared with the thread IDs of other threads to determine - * if two threads are the same. - * - * @return - * The thread ID of the calling thread. - * - * @note - * - The thread ID returned by `pthread_self` is not the same as the operating system's thread ID. - * - This function does not affect the calling thread's state or execution. - * - The thread ID returned by `pthread_self` is only meaningful in the context of the current process. - * - * @see pthread_create, pthread_equal, pthread_join - */ pthread_t pthread_self (void) { rt_thread_t tid; @@ -540,32 +436,6 @@ pthread_t pthread_self (void) } RTM_EXPORT(pthread_self); -/** - * @brief Retrieves the clock ID for the specified thread. - * - * The `pthread_getcpuclockid` function retrieves the clock ID associated with the CPU time used - * by the specified thread. - * - * @param[in] thread - * The thread whose CPU clock ID is to be retrieved. If the thread is the calling thread, - * the current thread's ID is used. - * - * @param[out] clock_id - * A pointer to a `clockid_t` variable that will be filled with the clock ID associated - * with the specified thread. - * - * @return - * - `0` on success. - * - `EINVAL` if the `thread` is not a valid thread identifier. - * - `ESRCH` if the specified thread does not exist. - * - * @note - * The clock returned by this function is specific to the thread and is different from the - * system-wide clock. It measures the CPU time consumed by the specified thread, not wall-clock - * time. The thread's CPU time can be obtained using `clock_gettime` with the returned `clock_id`. - * - * @see clock_gettime, pthread_create, pthread_self - */ int pthread_getcpuclockid(pthread_t thread, clockid_t *clock_id) { if(_pthread_get_data(thread) == NULL) @@ -579,62 +449,12 @@ int pthread_getcpuclockid(pthread_t thread, clockid_t *clock_id) } RTM_EXPORT(pthread_getcpuclockid); -/** - * @brief Retrieves the current concurrency level of the program. - * - * The `pthread_getconcurrency` function returns the current concurrency level of the program. - * This value represents the number of threads that can run concurrently in the program, - * based on the current settings of the pthreads library. It is used to help tune the behavior - * of thread scheduling in some systems. - * - * @return - * The current concurrency level of the program. - * - The value is an integer representing the number of threads that are permitted to run - * concurrently in the system, based on the library's current configuration. - * - A return value of `0` typically means that the system is using the default concurrency - * level, which may be determined automatically by the system or by thread creation behavior. - * - * @note - * - The behavior and meaning of concurrency levels can be implementation-dependent, - * and it may vary across different systems or environments. - * - The function is typically used for diagnostic purposes, and its behavior may not - * affect thread execution directly. - * - * @see pthread_setconcurrency - */ int pthread_getconcurrency(void) { return concurrency_level; } RTM_EXPORT(pthread_getconcurrency); -/** - * @brief Sets the concurrency level of the program. - * - * The `pthread_setconcurrency` function sets the number of threads that are allowed to run concurrently. - * The concurrency level defines the maximum number of threads that can be executed in parallel by the system. - * This is useful for tuning thread behavior and controlling system resource usage, especially in environments - * with limited resources (e.g., CPU cores). - * - * @param[in] new_level - * The new concurrency level to be set. This value represents the number of threads that can execute concurrently. - * - A value of `0` typically means that the system will automatically determine the concurrency level based on - * the system's configuration and available resources. - * - A non-zero value explicitly sets the maximum number of threads that can run concurrently. - * - * @return - * - `0` on success. - * - `EINVAL` if the `new_level` is invalid or if the system does not support this functionality. - * - * @note - * - The behavior of this function is system-dependent. Some systems may ignore the concurrency setting - * and automatically manage the concurrency based on available resources (e.g., CPU cores). - * - This function may not have any effect on systems that do not support concurrency settings at the library level. - * - The concurrency level controls thread scheduling policies and is intended to influence how the thread library - * manages threads, not how the operating system schedules them at the kernel level. - * - * @see pthread_getconcurrency - */ int pthread_setconcurrency(int new_level) { concurrency_level = new_level; @@ -643,44 +463,6 @@ int pthread_setconcurrency(int new_level) } RTM_EXPORT(pthread_setconcurrency); -/** - * @brief Retrieves the scheduling policy and parameters of a thread. - * - * The `pthread_getschedparam` function retrieves the scheduling policy and the scheduling parameters - * (such as priority) for the specified thread. This allows you to check the scheduling settings of a thread - * and can be useful for thread management and performance tuning in a multithreaded application. - * - * @param[in] thread - * The thread whose scheduling policy and parameters are to be retrieved. This is typically a valid - * `pthread_t` identifier of a thread that has already been created. - * - * @param[out] policy - * A pointer to an integer where the scheduling policy of the specified thread will be stored. The - * value will be one of the following constants defined in ``: - * - `SCHED_FIFO`: First-in, first-out scheduling policy. - * - `SCHED_RR`: Round-robin scheduling policy. - * - `SCHED_OTHER`: Default policy, which is typically used by non-realtime threads. - * - `SCHED_IDLE`: For idle threads (system-level threads that do minimal work). - * - `SCHED_BATCH`: For threads that should be scheduled with lower priority than interactive threads. - * - `SCHED_DEADLINE`: A policy that allows specifying real-time deadlines (on systems that support it). - * - * @param[out] param - * A pointer to a `struct sched_param` where the scheduling parameters (e.g., priority) for the thread - * will be stored. The `sched_param` structure typically contains: - * - `sched_priority`: The priority value associated with the thread's scheduling policy. - * - * @return - * - `0` on success. - * - `ESRCH` if the specified thread does not exist. - * - `EINVAL` if an invalid argument is provided, such as an invalid thread ID or null pointers for the policy or parameters. - * - * @note - * - This function retrieves the current scheduling settings for a thread. These settings can be used - * to monitor or adjust thread behavior. - * - The scheduling policies and priorities may be platform-dependent and subject to system configuration. - * - * @see pthread_setschedparam, sched_getparam - */ int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param) { _pthread_data_t *ptd; @@ -693,47 +475,6 @@ int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *par } RTM_EXPORT(pthread_getschedparam); -/** - * @brief Sets the scheduling policy and parameters for a thread. - * - * The `pthread_setschedparam` function sets the scheduling policy and scheduling parameters (such as priority) - * for the specified thread. This allows you to control how the thread is scheduled by the operating system. - * It is useful for adjusting thread behavior, especially for real-time or performance-sensitive applications. - * - * @param[in] thread - * The thread whose scheduling policy and parameters are to be set. This is a valid `pthread_t` identifier. - * - * @param[in] policy - * The scheduling policy to be set for the thread. This can be one of the following values: - * - `SCHED_FIFO`: First-in, first-out scheduling policy, where threads are scheduled based on their arrival time. - * - `SCHED_RR`: Round-robin scheduling policy, where each thread is allocated a fixed time slice and scheduled cyclically. - * - `SCHED_OTHER`: Default policy for non-realtime threads. - * - `SCHED_IDLE`: For threads intended to run only when no other threads are runnable. - * - `SCHED_BATCH`: For threads that should run with lower priority than interactive threads. - * - `SCHED_DEADLINE`: For real-time threads that have a specified deadline (if supported). - * - * @param[in] param - * A pointer to a `struct sched_param`, which contains the scheduling parameters, typically the thread's priority. - * The `sched_priority` field is the most commonly used parameter, and it controls the thread's priority within - * the specified scheduling policy. - * - * @return - * - `0` on success. - * - `EINVAL` if an invalid policy or parameter is provided. - * - `ESRCH` if the specified thread does not exist. - * - `EPERM` if the caller does not have permission to modify the thread's scheduling attributes. - * - * @note - * - The `sched_param` structure's `sched_priority` field specifies the priority of the thread. The priority - * range depends on the policy used. For example, for `SCHED_FIFO` and `SCHED_RR`, higher priority values - * correspond to higher priority threads, while for `SCHED_OTHER`, priorities are not as strictly enforced. - * - Changing a thread's scheduling parameters may affect its execution behavior, including how it competes with - * other threads for CPU time. - * - The system may not allow you to modify scheduling parameters for all threads, depending on system configuration - * and privileges. - * - * @see pthread_getschedparam - */ int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param) { _pthread_data_t *ptd; @@ -746,35 +487,6 @@ int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param } RTM_EXPORT(pthread_setschedparam); -/** - * @brief Sets the scheduling priority for a thread. - * - * The `pthread_setschedprio` function adjusts the priority of the specified thread while leaving its - * scheduling policy unchanged. This is useful for fine-tuning thread behavior in multithreaded applications. - * - * @param[in] thread - * The thread whose scheduling priority is to be changed. This must be a valid `pthread_t` identifier. - * - * @param[in] prio - * The new scheduling priority for the thread. The priority must fall within the valid range for the - * thread's current scheduling policy, as defined by `sched_get_priority_min` and `sched_get_priority_max`. - * - * @return - * - `0` on success. - * - `EINVAL` if the specified priority is invalid for the thread's current scheduling policy. - * - `ESRCH` if the specified thread does not exist. - * - `EPERM` if the calling process lacks the necessary privileges to set the thread's priority. - * - * @note - * - Changing a thread's priority may require elevated privileges (e.g., root) on certain systems, especially - * for real-time priorities. - * - The priority range and behavior depend on the thread's current scheduling policy. For example: - * - `SCHED_FIFO` and `SCHED_RR`: Priorities are used for strict scheduling. - * - `SCHED_OTHER`: Priorities may have minimal or no effect. - * - The behavior of this function is platform-dependent and may vary between different operating systems. - * - * @see pthread_setschedparam, pthread_getschedparam - */ int pthread_setschedprio(pthread_t thread, int prio) { _pthread_data_t *ptd; @@ -788,24 +500,6 @@ int pthread_setschedprio(pthread_t thread, int prio) } RTM_EXPORT(pthread_setschedprio); -/** - * @brief Terminates the calling thread and optionally returns a value. - * - * The `pthread_exit` function terminates the calling thread. It can optionally provide an exit status that can be - * retrieved by other threads that join the calling thread using `pthread_join`. If the thread is detached, the - * exit status is ignored and the system automatically reclaims resources once the thread terminates. - * - * @param[in] value - * A pointer to a value that will be returned to any thread that calls `pthread_join` on this thread. - * If `NULL`, no value is returned. - * - * @note - * - This function does not terminate the process. It only terminates the calling thread. - * - If the calling thread is the main thread, `pthread_exit` allows other threads to continue execution. - * - If a thread terminates without calling `pthread_exit`, it returns control to the system when the thread's function ends. - * - * @see pthread_join, pthread_create - */ void pthread_exit(void *value) { _pthread_data_t *ptd; @@ -870,33 +564,6 @@ void pthread_exit(void *value) } RTM_EXPORT(pthread_exit); -/** - * @brief Executes a routine once in a multithreaded environment. - * - * The `pthread_once` function ensures that the specified initialization routine is executed exactly once, - * even if multiple threads attempt to execute it simultaneously. It is typically used for one-time - * initialization tasks in a multithreaded program. - * - * @param[in] once_control - * A pointer to a `pthread_once_t` control variable. The init_routine can only be excuted - * when (*once_control) is zero. - * - * @param[in] init_routine - * A pointer to the initialization routine to be executed. This routine takes no arguments and - * returns no value. It is guaranteed to be executed exactly once. - * - * @return - * - `0` on success. - * - * @note - * - The `pthread_once` function is thread-safe and guarantees that the `init_routine` is called only once. - * - The `once_control` variable must remain valid and should not be modified by the application after - * initialization. - * - If the initialization routine fails or encounters an error, it is the responsibility of the routine - * to handle it appropriately. - * - * @see pthread_mutex_lock, pthread_mutex_unlock - */ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) { RT_ASSERT(once_control != RT_NULL); @@ -923,35 +590,6 @@ int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(vo } RTM_EXPORT(pthread_atfork); -/** - * @brief Sends a signal to a specific thread. - * - * The `pthread_kill` function sends the specified signal to the target thread. This allows fine-grained - * control over signal handling in multithreaded applications. - * - * @param[in] thread - * The target thread to which the signal is sent. This is a valid `pthread_t` identifier. - * - * @param[in] sig - * The signal to be sent. This can be any valid signal, such as those defined in ``. For example: - * - `SIGTERM`: Request thread termination. - * - `SIGUSR1` or `SIGUSR2`: User-defined signals. - * - `0`: Used to check if the thread is still valid without sending a signal. - * - * @return - * - `0` on success. - * - `ESRCH` if the specified thread does not exist or is invalid. - * - `EINVAL` if the signal number `sig` is invalid. - * - * @note - * - The signal is delivered to the specified thread only if the thread has the appropriate signal handlers - * set up. Unhandled signals might result in the default action for that signal. - * - If `sig` is `0`, no signal is sent, but the function checks if the thread is valid and exists. - * - Signal handling behavior is shared across threads in a process. For example, blocking or ignoring a signal - * in one thread affects the entire process. - * - * @see pthread_sigmask, sigaction - */ int pthread_kill(pthread_t thread, int sig) { #ifdef RT_USING_SIGNALS @@ -978,62 +616,12 @@ int pthread_kill(pthread_t thread, int sig) RTM_EXPORT(pthread_kill); #ifdef RT_USING_SIGNALS -/** - * @brief Modifies or retrieves the signal mask of the calling thread. - * - * The `pthread_sigmask` function allows a thread to block, unblock, or examine the signals in its signal mask. - * Signals that are blocked are not delivered to the thread until they are unblocked. - * - * @param[in] how - * Specifies how the signal mask is modified. Possible values: - * - `SIG_BLOCK`: Add the signals in `set` to the current signal mask. - * - `SIG_UNBLOCK`: Remove the signals in `set` from the current signal mask. - * - `SIG_SETMASK`: Replace the current signal mask with the signals in `set`. - * - * @param[in] set - * A pointer to a `sigset_t` containing the signals to be modified in the mask. Can be `NULL` if no change is needed. - * - * @param[out] oset - * A pointer to a `sigset_t` where the previous signal mask will be stored. Can be `NULL` if the previous mask is not required. - * - * @return - * - `0` on success. - * - * @note - * - Signal masks are thread-specific in a multithreaded program. - * - The `pthread_sigmask` function is designed for multithreaded programs, whereas `sigprocmask` should not be used. - * - Blocking a signal prevents it from being delivered to the thread until unblocked. - * - * @see sigprocmask, sigaction, pthread_kill - */ int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) { return sigprocmask(how, set, oset); } #endif -/** - * @brief Unregisters a cleanup handler and optionally executes it. - * - * The `pthread_cleanup_pop` function unregisters a cleanup handler that was previously registered - * using `pthread_cleanup_push`. If the `execute` parameter is non-zero, the cleanup handler is executed - * at the point where the thread terminates or is canceled. - * - * If `execute` is zero, the handler is unregistered without being executed. This allows the handler - * to be removed from the cleanup stack without performing any actions. - * - * @param[in] execute - * If non-zero, the cleanup handler is executed when the thread terminates or is canceled. - * If zero, the handler is simply removed from the stack without executing it. - * - * @note - * - Cleanup handlers are executed in the reverse order of their registration (i.e., last-in, first-out). - * - It is important to use `pthread_cleanup_push` to register cleanup handlers and `pthread_cleanup_pop` - * to ensure they are properly unregistered and executed if needed. - * - This function should be paired with `pthread_cleanup_push` to manage cleanup handlers effectively. - * - * @see pthread_cleanup_push, pthread_exit, pthread_cancel - */ void pthread_cleanup_pop(int execute) { _pthread_data_t *ptd; @@ -1063,33 +651,6 @@ void pthread_cleanup_pop(int execute) } RTM_EXPORT(pthread_cleanup_pop); -/** - * @brief Registers a cleanup handler to be executed when the calling thread terminates. - * - * The `pthread_cleanup_push` function registers a cleanup handler that is executed when the calling thread - * is canceled or exits (either normally or via `pthread_exit`). The cleanup handler will be executed - * in the reverse order of their registration. - * - * The cleanup handler can be used to release resources such as memory or file descriptors when the thread - * is terminated, whether it terminates normally or is canceled. - * - * @param[in] routine - * A pointer to the cleanup handler function. The function must have the following signature: - * `void routine(void* arg);`. It is invoked when the thread terminates or is canceled. - * - * @param[in] arg - * A pointer to the argument that will be passed to the cleanup handler (`routine`). - * This allows the handler to perform actions with the passed argument. - * - * @note - * - The cleanup handler is automatically invoked when a thread terminates or is canceled. - * - The cleanup handlers are executed in the reverse order of their registration, similar to how - * destructors are executed in a stack-based fashion. - * - `pthread_cleanup_pop` must be called to unregister the cleanup handler. It ensures that the handler - * is only invoked during the thread's termination process. - * - * @see pthread_cleanup_pop, pthread_cancel, pthread_exit - */ void pthread_cleanup_push(void (*routine)(void *), void *arg) { _pthread_data_t *ptd; @@ -1143,33 +704,6 @@ RTM_EXPORT(pthread_cleanup_push); * functions are defined to be async-cancel safe. */ -/** - * @brief Sets the cancelability state of the calling thread. - * - * The `pthread_setcancelstate` function allows a thread to enable or disable its ability to be canceled - * by another thread. Cancelability determines if and when a thread responds to a cancellation request. - * - * @param[in] state - * The new cancelability state for the calling thread. Possible values: - * - `PTHREAD_CANCEL_ENABLE`: The thread can be canceled. - * - `PTHREAD_CANCEL_DISABLE`: The thread cannot be canceled. - * - * @param[out] oldstate - * A pointer to an integer where the previous cancelability state will be stored. Can be `NULL` if - * the previous state is not needed. - * - * @return - * - `0` on success. - * - `EINVAL` if the `state` is not a valid cancelability state. - * - * @note - * - The cancelability state affects how the thread responds to cancellation requests: - * - In the `PTHREAD_CANCEL_DISABLE` state, cancellation requests are held pending until the state is changed to `PTHREAD_CANCEL_ENABLE`. - * - Cancelability is distinct from the cancelability type, which controls the timing of cancellation (deferred or asynchronous). - * - By default, threads are created with `PTHREAD_CANCEL_ENABLE`. - * - * @see pthread_cancel, pthread_setcanceltype - */ int pthread_setcancelstate(int state, int *oldstate) { _pthread_data_t *ptd; @@ -1193,34 +727,6 @@ int pthread_setcancelstate(int state, int *oldstate) } RTM_EXPORT(pthread_setcancelstate); -/** - * @brief Sets the cancellation type of the calling thread. - * - * The `pthread_setcanceltype` function allows a thread to specify when it should respond to - * a cancellation request. The cancellation type can be set to deferred or asynchronous. - * - * @param[in] type - * The new cancellation type for the calling thread. Possible values: - * - `PTHREAD_CANCEL_DEFERRED`: Cancellation occurs at cancellation points (default behavior). - * - `PTHREAD_CANCEL_ASYNCHRONOUS`: Cancellation occurs immediately when a request is received. - * - * @param[out] oldtype - * A pointer to an integer where the previous cancellation type will be stored. Can be `NULL` - * if the previous type is not required. - * - * @return - * - `0` on success. - * - `EINVAL` if the `type` is not a valid cancellation type. - * - * @note - * - The cancellation type determines when a thread processes a cancellation request: - * - **Deferred**: The thread responds to cancellation only at well-defined cancellation points. - * - **Asynchronous**: The thread can be canceled immediately, which may lead to resource inconsistencies. - * - By default, threads use `PTHREAD_CANCEL_DEFERRED`. - * - Asynchronous cancellation should be used cautiously as it can interrupt a thread at any point. - * - * @see pthread_cancel, pthread_setcancelstate, pthread_testcancel - */ int pthread_setcanceltype(int type, int *oldtype) { _pthread_data_t *ptd; @@ -1242,23 +748,6 @@ int pthread_setcanceltype(int type, int *oldtype) } RTM_EXPORT(pthread_setcanceltype); -/** - * @brief Explicitly checks for pending cancellation requests in the calling thread. - * - * The `pthread_testcancel` function allows a thread to determine if it has a pending - * cancellation request. If a cancellation request is pending and the thread's cancelability - * state is set to `PTHREAD_CANCEL_ENABLE`, the thread will terminate immediately. - * - * @note - * - This function is a cancellation point, meaning it checks for cancellation and responds if applicable. - * - If the thread's cancelability state is `PTHREAD_CANCEL_DISABLE`, the function has no effect. - * - The thread will invoke any cleanup handlers registered with `pthread_cleanup_push` before termination. - * - * @return - * This function does not return if a cancellation is performed. Otherwise, it returns normally. - * - * @see pthread_setcancelstate, pthread_setcanceltype, pthread_cancel - */ void pthread_testcancel(void) { int cancel = 0; @@ -1277,30 +766,6 @@ void pthread_testcancel(void) } RTM_EXPORT(pthread_testcancel); -/** - * @brief Sends a cancellation request to a specified thread. - * - * The `pthread_cancel` function requests the cancellation of the thread identified by `thread`. - * The actual response to the request depends on the target thread's cancelability state and type. - * - * @param[in] thread - * The identifier of the thread to be canceled. - * - * @return - * - `0` on success. - * - `EINVAL` if the specified thread does not exist. - * - * @note - * - Cancellation is an asynchronous mechanism. The thread may not terminate immediately or at all - * if its cancelability state is set to `PTHREAD_CANCEL_DISABLE`. - * - If the thread is cancelable and terminates, it invokes cleanup handlers registered with - * `pthread_cleanup_push` before termination. - * - The thread's cancellation type determines when it processes the cancellation request: - * - `PTHREAD_CANCEL_DEFERRED` (default): At specific cancellation points. - * - `PTHREAD_CANCEL_ASYNCHRONOUS`: Immediately upon receipt of the request. - * - * @see pthread_setcancelstate, pthread_setcanceltype, pthread_testcancel - */ int pthread_cancel(pthread_t thread) { _pthread_data_t *ptd; diff --git a/rt-thread/components/libc/posix/pthreads/pthread_barrier.c b/rt-thread/components/libc/posix/pthreads/pthread_barrier.c index 8802aae..bebd25a 100644 --- a/rt-thread/components/libc/posix/pthreads/pthread_barrier.c +++ b/rt-thread/components/libc/posix/pthreads/pthread_barrier.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -45,40 +45,12 @@ int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared) if (!attr) return EINVAL; if (pshared == PTHREAD_PROCESS_PRIVATE) - { - *attr = PTHREAD_PROCESS_PRIVATE; - return 0; - } + attr = PTHREAD_PROCESS_PRIVATE; return EINVAL; } RTM_EXPORT(pthread_barrierattr_setpshared); -/** - * @brief Destroys a barrier object. - * - * The `pthread_barrier_destroy` function releases any resources associated - * with the specified barrier object. After a barrier has been destroyed, - * it cannot be used again unless it is reinitialized using `pthread_barrier_init`. - * - * @param[in] barrier - * A pointer to an initialized `pthread_barrier_t` object to be destroyed. - * - * @return - * - `0` on success. - * - `EINVAL` if the `barrier` is invalid or uninitialized. - * - `EBUSY` if there are threads currently blocked on the barrier. - * - * @note - * - Ensure that no threads are blocked on the barrier before calling this function. - * - Attempting to destroy a barrier that is still in use results in undefined behavior. - * - * @warning - * Destroying a barrier without ensuring it is no longer in use can lead to - * resource leaks or undefined program behavior. - * - * @see pthread_barrier_init, pthread_barrier_wait - */ int pthread_barrier_destroy(pthread_barrier_t *barrier) { rt_err_t result; @@ -86,68 +58,12 @@ int pthread_barrier_destroy(pthread_barrier_t *barrier) if (!barrier) return EINVAL; - /* Lock the internal mutex to safely check the barrier's state*/ - result = pthread_mutex_lock(&(barrier->mutex)); - if (result != 0) - return result; - - /* Check if any threads are currently waiting on the barrier*/ - if (barrier->count != 0) - { - pthread_mutex_unlock(&(barrier->mutex)); - return EBUSY; /* Threads are still waiting*/ - } - - /* Free resources associated with the barrier*/ - result = pthread_mutex_unlock(&(barrier->mutex)); - if (result != 0) - { - return result; /* Return mutex unlock error*/ - } - - result = pthread_mutex_destroy(&(barrier->mutex)); - if (result != 0) - { - return result; /* Return mutex destroy error*/ - } result = pthread_cond_destroy(&(barrier->cond)); return result; } RTM_EXPORT(pthread_barrier_destroy); -/** - * @brief Initializes a barrier for synchronizing threads. - * - * The `pthread_barrier_init` function initializes a barrier object - * that allows a specified number of threads to synchronize at a barrier point. - * Each thread waits at the barrier until the required number of threads have called - * `pthread_barrier_wait`. - * - * @param[out] barrier - * A pointer to the `pthread_barrier_t` object to be initialized. - * This object must not already be initialized. - * - * @param[in] attr - * A pointer to a `pthread_barrierattr_t` object that specifies - * attributes for the barrier (e.g., process-shared or process-private). - * If NULL, the default attributes are used. - * - * @param[in] count - * The number of threads that must call `pthread_barrier_wait` - * before any of them successfully return from the barrier. - * - * @return - * - `0` on success. - * - `EINVAL` if the `count` is zero or `barrier` is invalid. - * - * @note The barrier must be destroyed using `pthread_barrier_destroy` - * when it is no longer needed. - * - * @warning If `count` is set to zero, the behavior is undefined. - * - * @see pthread_barrier_wait, pthread_barrier_destroy - */ int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned count) @@ -167,33 +83,6 @@ int pthread_barrier_init(pthread_barrier_t *barrier, } RTM_EXPORT(pthread_barrier_init); -/** - * @brief Synchronizes threads at a barrier. - * - * The `pthread_barrier_wait` function blocks the calling thread at the specified - * barrier until the required number of threads have reached the barrier. Once - * the required number of threads have called this function, all threads are - * unblocked and can proceed. - * - * @param[in] barrier - * A pointer to an initialized `pthread_barrier_t` object representing the barrier - * at which threads will synchronize. - * - * @return - * - `0` for all threads except one. - * - `EINVAL` - The `barrier` is invalid or uninitialized. - * - * @note - * - All threads participating in the barrier must call `pthread_barrier_wait` - * before any of them are released. - * - * @warning - * Ensure that the number of threads specified during the barrier's initialization - * matches the number of threads calling this function, otherwise the program - * may hang indefinitely. - * - * @see pthread_barrier_init, pthread_barrier_destroy - */ int pthread_barrier_wait(pthread_barrier_t *barrier) { rt_err_t result; diff --git a/rt-thread/components/libc/posix/pthreads/pthread_cond.c b/rt-thread/components/libc/posix/pthreads/pthread_cond.c index 1241ef8..6c3db2e 100644 --- a/rt-thread/components/libc/posix/pthreads/pthread_cond.c +++ b/rt-thread/components/libc/posix/pthreads/pthread_cond.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -72,30 +72,6 @@ int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared) } RTM_EXPORT(pthread_condattr_setpshared); -/** - * @brief Initializes a condition variable. - * - * This function initializes the condition variable pointed to by `cond` with the attributes - * specified by `attr`. If `attr` is NULL, the condition variable is initialized with the - * default attributes. - * - * @param cond A pointer to the condition variable to be initialized. - * Must point to valid memory. - * @param attr A pointer to the condition variable attributes object. - * If NULL, default attributes are used. - * - * @return - * - `0` on success. - * - A non-zero error code on failure, including: - * - `EINVAL`: Invalid attributes, invalid condition variable pointer, or semaphore init failed. - * - * @note - * - The condition variable must not be used until it has been initialized. - * - Each condition variable must be destroyed using `pthread_cond_destroy()` - * once it is no longer needed. - * - * @see pthread_cond_destroy, pthread_cond_wait, pthread_cond_signal, pthread_cond_broadcast - */ int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { rt_err_t result; @@ -134,30 +110,6 @@ int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) } RTM_EXPORT(pthread_cond_init); -/** - * @brief Destroys a condition variable. - * - * This function destroys the condition variable pointed to by `cond`. After a condition - * variable is destroyed, it must not be used until it is reinitialized with - * `pthread_cond_init`. - * - * @param cond A pointer to the condition variable to be destroyed. - * Must point to a valid, previously initialized condition variable. - * - * @return - * - `0` on success. - * - A non-zero error code on failure, including: - * - `EBUSY`: The condition variable is currently in use by other threads. - * - `EINVAL`: The condition variable is invalid or uninitialized. - * - * @note - * - The condition variable must not be destroyed while it is being used by other threads - * (e.g., in `pthread_cond_wait` or `pthread_cond_timedwait`). - * - Attempting to destroy a condition variable that has not been initialized results in - * undefined behavior. - * - * @see pthread_cond_init, pthread_cond_wait, pthread_cond_signal, pthread_cond_broadcast - */ int pthread_cond_destroy(pthread_cond_t *cond) { rt_err_t result; @@ -191,30 +143,6 @@ __retry: } RTM_EXPORT(pthread_cond_destroy); -/** - * @brief Unblocks all threads waiting on the specified condition variable. - * - * This function wakes up all threads that are currently blocked on the condition variable - * pointed to by `cond`. The condition variable must be associated with a mutex, and - * threads waiting on the condition variable should recheck the condition after being - * unblocked. - * - * @param cond A pointer to the condition variable. - * Must point to a valid, initialized condition variable. - * - * @return - * - `0` on success. - * - A non-zero error code on failure, including: - * - `EINVAL`: The condition variable is invalid or uninitialized. - * - * @note - * - Calling this function does not release the associated mutex. - * - Waking up threads does not guarantee that any specific thread will acquire the - * mutex immediately, as thread scheduling depends on the system. - * - Typically used when the condition might allow multiple waiting threads to proceed. - * - * @see pthread_cond_signal, pthread_cond_wait, pthread_cond_init, pthread_cond_destroy - */ int pthread_cond_broadcast(pthread_cond_t *cond) { rt_err_t result; @@ -249,30 +177,6 @@ int pthread_cond_broadcast(pthread_cond_t *cond) } RTM_EXPORT(pthread_cond_broadcast); -/** - * @brief Wakes up one thread waiting on the specified condition variable. - * - * This function unblocks one thread that is currently waiting on the - * condition variable `cond`. If multiple threads are waiting, the thread to wake - * up is determined by the system's scheduling policies. - * - * @param cond A pointer to the condition variable to signal. - * Must point to a valid and initialized condition variable. - * - * @return - * - `0` on success. - * - A non-zero error code on failure, including: - * - `EINVAL`: The condition variable is invalid or uninitialized. - * - * @note - * - This function does not release the associated mutex. - * - If no threads are currently waiting on the condition variable, the call has no effect. - * - The awakened thread will not run until it can reacquire the associated mutex and - * re-evaluate the waiting condition. - * - It is typically used when only one waiting thread should be allowed to proceed. - * - * @see pthread_cond_broadcast, pthread_cond_wait, pthread_cond_init, pthread_cond_destroy - */ int pthread_cond_signal(pthread_cond_t *cond) { rt_base_t temp; @@ -306,35 +210,6 @@ int pthread_cond_signal(pthread_cond_t *cond) } RTM_EXPORT(pthread_cond_signal); -/** - * @brief Waits on a condition variable with a timeout. - * - * This function causes the calling thread to block on the condition variable `cond`, - * releasing the associated mutex `mutex`. The thread will remain blocked until - * one of the following occurs: - * - It is signaled or broadcast using `pthread_cond_signal` or `pthread_cond_broadcast`. - * - The specified timeout expires. - * - * @param cond A pointer to the condition variable to wait on. - * Must point to a valid, initialized condition variable. - * @param mutex A pointer to the mutex associated with the condition variable. - * Must be locked by the calling thread before invoking this function. - * @param timeout The timeout duration in milliseconds. A value of `RT_WAITING_FOREVER` - * indicates the thread will wait indefinitely. - * - * @return - * - `RT_EOK` on successful wakeup (signaled or broadcast). - * - `-RT_ETIMEOUT` if the timeout expires before the condition variable is signaled. - * - `-RT_ERROR` if an error occurs (e.g., invalid parameters). - * - * @note - * - The mutex is automatically released while the thread waits and re-acquired before - * the function returns. - * - If `timeout` is 0, the function behaves as a non-blocking check. - * - Ensure the condition variable and mutex are properly initialized before use. - * - * @see pthread_cond_signal, pthread_cond_broadcast, pthread_mutex_lock, pthread_mutex_unlock - */ rt_err_t _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, rt_int32_t timeout) @@ -452,33 +327,6 @@ rt_err_t _pthread_cond_timedwait(pthread_cond_t *cond, } RTM_EXPORT(_pthread_cond_timedwait); -/** - * @brief Waits on a condition variable. - * - * This function blocks the calling thread on the condition variable `cond` and releases - * the associated mutex `mutex`. The thread remains blocked until it is signaled or - * broadcast using `pthread_cond_signal` or `pthread_cond_broadcast`. When the thread - * is awakened, it re-acquires the mutex and resumes execution. - * - * @param cond A pointer to the condition variable to wait on. - * Must point to a valid, initialized condition variable. - * @param mutex A pointer to the mutex associated with the condition variable. - * Must be locked by the calling thread before invoking this function. - * - * @return - * - `0` on success. - * - A non-zero error code on failure, including: - * - `EINVAL`: The condition variable or mutex is invalid or uninitialized. - * - * @note - * - The mutex must be locked before calling this function. - * - Upon returning, the mutex is locked again by the calling thread. - * - Spurious wakeups may occur, so the thread should always recheck the waiting - * condition upon wakeup. - * - This function may block indefinitely unless the condition is signaled or broadcast. - * - * @see pthread_cond_signal, pthread_cond_broadcast, pthread_cond_timedwait, pthread_mutex_lock - */ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { rt_err_t result; @@ -501,37 +349,6 @@ __retry: } RTM_EXPORT(pthread_cond_wait); -/** - * @brief Waits on a condition variable with a timeout. - * - * This function blocks the calling thread on the condition variable `cond`, releasing - * the associated mutex `mutex`. The thread remains blocked until one of the following occurs: - * - The condition variable is signaled or broadcast using `pthread_cond_signal` or `pthread_cond_broadcast`. - * - The specified absolute timeout `abstime` is reached. - * - A spurious wakeup occurs (requiring the thread to recheck the condition). - * - * @param cond A pointer to the condition variable to wait on. - * Must point to a valid, initialized condition variable. - * @param mutex A pointer to the mutex associated with the condition variable. - * Must be locked by the calling thread before invoking this function. - * @param abstime A pointer to a `struct timespec` specifying the absolute timeout (in seconds and nanoseconds - * since the Epoch). If the time specified is already reached, the function immediately returns. - * - * @return - * - `0` on successful wakeup (signaled or broadcast). - * - `ETIMEDOUT` if the timeout expires before the condition variable is signaled. - * - A non-zero error code on failure, including: - * - `EINVAL`: The condition variable, mutex, or `abstime` is invalid. - * - `EPERM`: The mutex is not owned by the calling thread. - * - * @note - * - The mutex is released while the thread is waiting and re-acquired before the function returns. - * - Spurious wakeups may occur, so the thread must always recheck the waiting condition upon wakeup. - * - The timeout is specified in absolute time, not relative duration. - * - Ensure the condition variable and mutex are properly initialized before use. - * - * @see pthread_cond_wait, pthread_cond_signal, pthread_cond_broadcast, pthread_mutex_lock - */ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) diff --git a/rt-thread/components/libc/posix/pthreads/pthread_mutex.c b/rt-thread/components/libc/posix/pthreads/pthread_mutex.c index ba433b2..1010c06 100644 --- a/rt-thread/components/libc/posix/pthreads/pthread_mutex.c +++ b/rt-thread/components/libc/posix/pthreads/pthread_mutex.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -16,28 +16,6 @@ const pthread_mutexattr_t pthread_default_mutexattr = PTHREAD_PROCESS_PRIVATE; -/** - * @brief Initializes a mutex attributes object. - * - * This function initializes a mutex attributes object pointed to by `attr` with - * default attribute values. Once initialized, the attributes object can be used - * to customize the behavior of mutexes created using it. - * - * @param[out] attr Pointer to the mutex attributes object to be initialized. - * - * @return - * - 0 on success. - * - Non-zero error code on failure. - * - * @note - * After initialization, the mutex attributes object must be destroyed with - * `pthread_mutexattr_destroy()` when it is no longer needed. - * - * @warning - * Using an uninitialized mutex attributes object may result in undefined behavior. - * - * @see pthread_mutexattr_destroy, pthread_mutex_init - */ int pthread_mutexattr_init(pthread_mutexattr_t *attr) { if (attr) @@ -51,29 +29,6 @@ int pthread_mutexattr_init(pthread_mutexattr_t *attr) } RTM_EXPORT(pthread_mutexattr_init); -/** - * @brief Destroys a mutex attributes object. - * - * This function releases any resources associated with the mutex attributes object - * pointed to by `attr`. After the attributes object is destroyed, it should not - * be used unless it is re-initialized with `pthread_mutexattr_init()`. - * - * @param[in,out] attr Pointer to the mutex attributes object to be destroyed. - * - * @return - * - 0 on success. - * - Non-zero error code on failure, including: - * - `EINVAL`: The attributes object is invalid or uninitialized. - * - * @note - * Destroying an uninitialized or already destroyed attributes object results in undefined behavior. - * - * @warning - * Ensure that no mutexes are being initialized or created using this attributes object - * at the time of its destruction. - * - * @see pthread_mutexattr_init, pthread_mutex_init - */ int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) { if (attr) @@ -87,30 +42,6 @@ int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) } RTM_EXPORT(pthread_mutexattr_destroy); -/** - * @brief Retrieves the type attribute of a mutex attributes object. - * - * This function retrieves the mutex type attribute from the attributes object - * pointed to by `attr` and stores it in the integer pointed to by `type`. - * - * @param[in] attr Pointer to the mutex attributes object. - * @param[out] type Pointer to an integer where the mutex type will be stored. - * Possible values include: - * - `PTHREAD_MUTEX_NORMAL`: Default mutex type. - * - `PTHREAD_MUTEX_ERRORCHECK`: Mutex with error-checking. - * - `PTHREAD_MUTEX_RECURSIVE`: Recursive mutex. - * - * @return - * - 0 on success. - * - Non-zero error code on failure, including: - * - `EINVAL`: The attributes object or the `type` pointer is invalid. - * - * @note - * Use this function to check the type of a mutex attributes object that has - * already been initialized or configured. - * - * @see pthread_mutexattr_settype, pthread_mutexattr_init - */ int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) { if (attr && type) @@ -129,41 +60,6 @@ int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) } RTM_EXPORT(pthread_mutexattr_gettype); -/** - * @brief Sets the type attribute of a mutex attributes object. - * - * This function sets the type of the mutex to be initialized using the - * attributes object pointed to by `attr`. The `type` can be one of the - * following values: - * - `PTHREAD_MUTEX_NORMAL`: Default mutex type. The mutex does not allow - * a thread to unlock it if it was not locked by that thread (this results - * in undefined behavior). - * - `PTHREAD_MUTEX_ERRORCHECK`: Error-checking mutex type. A thread trying to - * lock a mutex it already holds will return an error. - * - `PTHREAD_MUTEX_RECURSIVE`: Recursive mutex type. The same thread can lock - * the mutex multiple times without causing a deadlock, but it must unlock it - * the same number of times. - * - * @param[in,out] attr Pointer to the mutex attributes object. - * @param[in] type The type to set for the mutex. One of the following: - * - `PTHREAD_MUTEX_NORMAL` - * - `PTHREAD_MUTEX_ERRORCHECK` - * - `PTHREAD_MUTEX_RECURSIVE` - * - * @return - * - 0 on success. - * - Non-zero error code on failure, including: - * - `EINVAL`: The specified type is invalid. - * - * @note - * The type must be set before the mutex attributes object is used to - * initialize a mutex with `pthread_mutex_init()`. - * - * @warning - * Attempting to set an invalid mutex type will result in an error. - * - * @see pthread_mutexattr_gettype, pthread_mutexattr_init, pthread_mutex_init - */ int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) { if (attr && type >= PTHREAD_MUTEX_NORMAL && type <= PTHREAD_MUTEX_ERRORCHECK) @@ -177,37 +73,6 @@ int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) } RTM_EXPORT(pthread_mutexattr_settype); -/** - * @brief Sets the shared attribute of a mutex attributes object. - * - * This function sets the `pshared` attribute of the mutex attributes object - * pointed to by `attr`. The `pshared` attribute determines whether the mutex - * is shared between threads of the same process or can be shared between - * threads of different processes. - * - * @param[in,out] attr Pointer to the mutex attributes object. - * @param[in] pshared The sharing behavior of the mutex. This can be one of the following: - * - `PTHREAD_PROCESS_PRIVATE`: The mutex is only shared between threads - * of the same process (this is the default behavior). - * - `PTHREAD_PROCESS_SHARED`: The mutex can be shared between threads - * of different processes (requires the mutex to be allocated in - * shared memory). - * - * @return - * - 0 on success. - * - Non-zero error code on failure, including: - * - `EINVAL`: Invalid `pshared` value or invalid attributes object. - * - * @note - * The `pshared` attribute must be set before the mutex attributes object is - * used to initialize a mutex with `pthread_mutex_init()`. For shared mutexes - * (`PTHREAD_PROCESS_SHARED`), the mutex object must be allocated in shared memory. - * - * @warning - * Attempting to set an invalid `pshared` value will result in an error. - * - * @see pthread_mutexattr_getpshared, pthread_mutexattr_init, pthread_mutex_init - */ int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) { if (!attr) @@ -228,35 +93,6 @@ int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) } RTM_EXPORT(pthread_mutexattr_setpshared); -/** - * @brief Retrieves the shared attribute of a mutex attributes object. - * - * This function retrieves the `pshared` attribute from the mutex attributes - * object pointed to by `attr` and stores it in the integer pointed to by `pshared`. - * The `pshared` attribute indicates whether the mutex can be shared between threads - * of different processes or only within the same process. - * - * @param[in] attr Pointer to the mutex attributes object. - * @param[out] pshared Pointer to an integer where the shared attribute will be stored. - * Possible values are: - * - `PTHREAD_PROCESS_PRIVATE`: Mutex is shared only within the same process. - * - `PTHREAD_PROCESS_SHARED`: Mutex can be shared between threads of different processes. - * - * @return - * - 0 on success. - * - Non-zero error code on failure, including: - * - `EINVAL`: Invalid attributes object or the `pshared` pointer is NULL. - * - * @note - * Use this function to check the shared attribute of an already initialized - * mutex attributes object. - * - * @warning - * Attempting to get the `pshared` attribute of an uninitialized or invalid - * attributes object will result in an error. - * - * @see pthread_mutexattr_setpshared, pthread_mutexattr_init, pthread_mutex_init - */ int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared) { if (!attr || !pshared) @@ -268,31 +104,6 @@ int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared) } RTM_EXPORT(pthread_mutexattr_getpshared); -/** - * @brief Initializes a mutex with optional attributes. - * - * This function initializes a mutex object pointed to by `mutex`. The mutex - * can optionally be initialized with attributes specified by `attr`. If - * `attr` is `NULL`, default attributes are used. - * - * @param[in,out] mutex Pointer to the mutex to be initialized. - * @param[in] attr Pointer to the mutex attributes object. Pass `NULL` to use - * default attributes. - * - * @return - * - 0 on success. - * - Non-zero error code on failure, including: - * - `EINVAL`: Invalid parameters or result. - * - * @note - * The mutex object must be destroyed using `pthread_mutex_destroy()` after it - * is no longer needed to free associated resources. - * - * @warning - * A mutex should not be re-initialized while it is already in use. - * - * @see pthread_mutex_destroy, pthread_mutex_lock, pthread_mutex_unlock - */ int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { rt_err_t result; @@ -322,31 +133,6 @@ int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) } RTM_EXPORT(pthread_mutex_init); -/** - * @brief Destroys a mutex object. - * - * This function releases any resources associated with the mutex object - * pointed to by `mutex`. After the mutex has been destroyed, it cannot - * be used unless it is re-initialized with `pthread_mutex_init()`. - * - * @param[in,out] mutex Pointer to the mutex to be destroyed. - * - * @return - * - 0 on success. - * - Non-zero error code on failure, including: - * - `EBUSY`: The mutex is currently locked or being used by another thread. - * - `EINVAL`: The mutex is invalid or has not been initialized. - * - * @note - * Before calling this function, ensure that the mutex is not locked or in use - * by any thread. Destroying a locked mutex results in undefined behavior. - * - * @warning - * Attempting to destroy a mutex that is still in use can cause resource leaks - * or undefined behavior. - * - * @see pthread_mutex_init, pthread_mutex_lock, pthread_mutex_unlock - */ int pthread_mutex_destroy(pthread_mutex_t *mutex) { if (!mutex || mutex->attr == -1) @@ -363,34 +149,6 @@ int pthread_mutex_destroy(pthread_mutex_t *mutex) } RTM_EXPORT(pthread_mutex_destroy); -/** - * @brief Locks a mutex. - * - * This function locks the mutex object pointed to by `mutex`. If the mutex is - * already locked by another thread, the calling thread will block until the - * mutex becomes available. - * - * @param[in,out] mutex Pointer to the mutex to be locked. - * - * @return - * - 0 on success. - * - Non-zero error code on failure, including: - * - `EDEADLK`: A deadlock condition was detected (e.g., the current thread - * already holds the mutex in a recursive locking scenario). - * - `EINVAL`: The mutex is invalid or uninitialized. - * - * @note - * If the mutex is initialized with the `PTHREAD_MUTEX_RECURSIVE` attribute, - * the same thread can lock the mutex multiple times without causing a deadlock. - * However, the mutex must be unlocked an equal number of times before it - * becomes available to other threads. - * - * @warning - * Attempting to lock an uninitialized or already destroyed mutex results in - * undefined behavior. - * - * @see pthread_mutex_unlock, pthread_mutex_trylock, pthread_mutex_init - */ int pthread_mutex_lock(pthread_mutex_t *mutex) { int mtype; @@ -424,33 +182,6 @@ int pthread_mutex_lock(pthread_mutex_t *mutex) } RTM_EXPORT(pthread_mutex_lock); -/** - * @brief Unlocks a mutex. - * - * This function unlocks the mutex object pointed to by `mutex`. If other threads - * are blocked waiting for the mutex, one of them will acquire the lock once it is - * released. The calling thread must hold the lock on the mutex before calling - * this function. - * - * @param[in,out] mutex Pointer to the mutex to be unlocked. - * - * @return - * - 0 on success. - * - Non-zero error code on failure, including: - * - `EPERM`: The current thread does not hold the lock on the mutex. - * - `EINVAL`: The mutex is invalid or uninitialized. - * - * @note - * If the mutex was initialized with the `PTHREAD_MUTEX_RECURSIVE` attribute, - * the mutex will only be unlocked after the calling thread unlocks it as many - * times as it was locked. - * - * @warning - * Attempting to unlock an uninitialized, destroyed, or unlocked mutex results - * in undefined behavior. - * - * @see pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_init - */ int pthread_mutex_unlock(pthread_mutex_t *mutex) { rt_err_t result; @@ -485,31 +216,6 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex) } RTM_EXPORT(pthread_mutex_unlock); -/** - * @brief Attempts to lock a mutex without blocking. - * - * This function attempts to lock the mutex object pointed to by `mutex`. If the mutex - * is already locked by another thread, the function returns immediately with an error - * code instead of blocking. - * - * @param[in,out] mutex Pointer to the mutex to be locked. - * - * @return - * - 0 on success (the mutex was successfully locked). - * - Non-zero error code on failure, including: - * - `EBUSY`: The mutex is already locked by another thread. - * - `EINVAL`: The mutex is invalid or uninitialized. - * - * @note - * This function is useful for implementing non-blocking mutex acquisition. If the mutex - * was initialized with the `PTHREAD_MUTEX_RECURSIVE` attribute, the calling thread can - * lock it multiple times, but must unlock it the same number of times. - * - * @warning - * Attempting to trylock an uninitialized or destroyed mutex results in undefined behavior. - * - * @see pthread_mutex_lock, pthread_mutex_unlock, pthread_mutex_init - */ int pthread_mutex_trylock(pthread_mutex_t *mutex) { rt_err_t result; diff --git a/rt-thread/components/libc/posix/pthreads/pthread_rwlock.c b/rt-thread/components/libc/posix/pthreads/pthread_rwlock.c index 6157551..1c2fe19 100644 --- a/rt-thread/components/libc/posix/pthreads/pthread_rwlock.c +++ b/rt-thread/components/libc/posix/pthreads/pthread_rwlock.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -50,31 +50,6 @@ int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared) } RTM_EXPORT(pthread_rwlockattr_setpshared); -/** - * @brief Initializes a read-write lock. - * - * This function initializes the read-write lock object pointed to by `rwlock` with the - * attributes specified by `attr`. If `attr` is `NULL`, the default attributes are used. - * A read-write lock allows multiple threads to read or a single thread to write, but not both simultaneously. - * - * @param rwlock A pointer to the read-write lock object to be initialized. - * Must point to valid memory. - * @param attr A pointer to the attributes for the read-write lock. - * If `NULL`, default attributes are applied. - * - * @return - * - `0` on success. - * - A non-zero error code on failure, including: - * - `EINVAL`: Invalid attributes. - * - * @note - * - The read-write lock must be destroyed using `pthread_rwlock_destroy()` when it is no longer needed. - * - 'rw_mutex' is used for protecting rwlock data. - * 'rw_condreaders' is a condition variable for controlling readers. - * 'rw_condwriters' is a condition variable for controlling writers. - * - * @see pthread_rwlock_destroy, pthread_rwlock_rdlock, pthread_rwlock_wrlock, pthread_rwlock_unlock - */ int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) { @@ -94,30 +69,6 @@ int pthread_rwlock_init(pthread_rwlock_t *rwlock, } RTM_EXPORT(pthread_rwlock_init); -/** - * @brief Destroys a read-write lock. - * - * This function destroys the read-write lock object pointed to by `rwlock`. After - * the lock is destroyed, it cannot be used until it is reinitialized with - * `pthread_rwlock_init`. Any threads currently blocked on the lock are affected by the destruction. - * - * @param rwlock A pointer to the read-write lock object to be destroyed. - * Must point to a valid, initialized read-write lock. - * - * @return - * - `0` on success. - * - A non-zero error code on failure, including: - * - `EINVAL`: The `rwlock` is invalid or uninitialized. - * - `EBUSY`: The lock is currently in use by a thread, and cannot be destroyed. - * - * @note - * - The read-write lock must not be in use (i.e., no threads should be blocked on it) - * when `pthread_rwlock_destroy` is called. - * - Calling this function on an uninitialized or destroyed lock will result in undefined behavior. - * - Ensure that all threads have unlocked the lock before attempting to destroy it. - * - * @see pthread_rwlock_init, pthread_rwlock_rdlock, pthread_rwlock_wrlock, pthread_rwlock_unlock - */ int pthread_rwlock_destroy (pthread_rwlock_t *rwlock) { int result; @@ -171,29 +122,6 @@ int pthread_rwlock_destroy (pthread_rwlock_t *rwlock) } RTM_EXPORT(pthread_rwlock_destroy); -/** - * @brief Acquire a read lock on a read-write lock. - * - * This function locks the specified read-write lock for reading. If the lock - * is already held by one or more threads for reading, the calling thread - * can acquire the lock as well (shared access). However, if the lock is - * held by another writer thread, or other writer thread has been waiting - * for the lock, the calling thread will block until the write lock is released. - * - * @param rwlock A pointer to the read-write lock to be locked. - * - * @return - 0 on success. - * - EINVAL if the rwlock is invalid. - * - EDEADLK if a deadlock condition is detected (optional; implementation-dependent). - * - * @note A thread that has acquired a read lock must eventually release it - * using `pthread_rwlock_unlock`. Multiple read locks can be held - * simultaneously, but a write lock excludes all other locks. - * - * @see pthread_rwlock_unlock - * @see pthread_rwlock_wrlock - * @see pthread_rwlock_tryrdlock - */ int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) { int result; @@ -228,28 +156,6 @@ int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) } RTM_EXPORT(pthread_rwlock_rdlock); -/** - * @brief Try to acquire a read lock on a read-write lock without blocking. - * - * This function attempts to acquire a read lock on the specified read-write lock. - * If the lock is already held for writing, the function will return immediately - * without blocking the calling thread. If the lock is available for reading, - * it will be acquired successfully. - * - * @param rwlock A pointer to the read-write lock to attempt to lock. - * - * @return - 0 on success, indicating the read lock was acquired. - * - EBUSY if the lock is currently held for writing by another thread. - * - EINVAL if the rwlock is invalid. - * - * @note This function is non-blocking and returns immediately if the lock - * cannot be acquired. After successfully acquiring the read lock, - * the thread must release it using `pthread_rwlock_unlock`. - * - * @see pthread_rwlock_unlock - * @see pthread_rwlock_rdlock - * @see pthread_rwlock_trywrlock - */ int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) { int result; @@ -273,35 +179,6 @@ int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) } RTM_EXPORT(pthread_rwlock_tryrdlock); -/** - * @brief Acquire a read lock on a read-write lock with a timeout. - * - * This function attempts to lock the specified read-write lock for reading, - * blocking until the lock becomes available or the specified timeout expires. - * If the lock is held for writing by another thread, the calling thread will - * block, but only up to the time specified by `abstime`. - * - * @param rwlock A pointer to the read-write lock to be locked. - * @param abstime A pointer to a `timespec` structure specifying the - * absolute timeout (in seconds and nanoseconds since the - * Epoch, 1970-01-01 00:00:00 UTC). - * - * @return - 0 on success, indicating the read lock was acquired. - * - ETIMEDOUT if the timeout expired before the lock could be acquired. - * - EINVAL if the `rwlock` is invalid or `abstime` contains invalid values. - * - EDEADLK if a deadlock condition is detected (optional; implementation-dependent). - * - * @note The timeout is specified as an absolute time (not relative). After - * acquiring the read lock, the thread must release it using - * `pthread_rwlock_unlock`. - * - * @warning If the system clock is changed (e.g., via manual adjustment or - * NTP synchronization), the timeout behavior may be affected. - * - * @see pthread_rwlock_unlock - * @see pthread_rwlock_rdlock - * @see pthread_rwlock_tryrdlock - */ int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, const struct timespec *abstime) { @@ -337,35 +214,6 @@ int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, } RTM_EXPORT(pthread_rwlock_timedrdlock); -/** - * @brief Acquire a write lock on a read-write lock with a timeout. - * - * This function attempts to acquire a write lock on the specified read-write lock, - * blocking until the lock becomes available or the specified timeout expires. - * If the lock is already held for reading or writing by another thread, the - * calling thread will block, but only up to the time specified by `abstime`. - * - * @param rwlock A pointer to the read-write lock to be locked. - * @param abstime A pointer to a `timespec` structure specifying the - * absolute timeout (in seconds and nanoseconds since the - * Epoch, 1970-01-01 00:00:00 UTC). - * - * @return - * - 0 on success, indicating the write lock was acquired. - * - EINVAL if the `rwlock` is invalid or `abstime` contains invalid values. - * - EDEADLK if a deadlock condition is detected (optional; implementation-dependent). - * - * @note The timeout is specified as an absolute time (not relative). After - * acquiring the write lock, the thread must release it using - * `pthread_rwlock_unlock`. - * - * @warning If the system clock is adjusted (e.g., manually or via NTP synchronization), - * the timeout behavior may be affected. - * - * @see pthread_rwlock_unlock - * @see pthread_rwlock_wrlock - * @see pthread_rwlock_trywrlock - */ int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const struct timespec *abstime) { @@ -400,29 +248,6 @@ int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, } RTM_EXPORT(pthread_rwlock_timedwrlock); -/** - * @brief Try to acquire a write lock on a read-write lock without blocking. - * - * This function attempts to acquire a write lock on the specified read-write lock. - * If the lock is already held for reading or writing by another thread, the function - * will return immediately without blocking the calling thread. If the lock is - * available, it will be acquired successfully. - * - * @param rwlock A pointer to the read-write lock to attempt to lock. - * - * @return - * - 0 on success, indicating the write lock was acquired. - * - EBUSY if the lock is currently held by another thread (read or write lock). - * - EINVAL if the `rwlock` is invalid. - * - * @note This function is non-blocking and returns immediately if the lock cannot - * be acquired. After successfully acquiring the write lock, the thread must - * release it using `pthread_rwlock_unlock`. - * - * @see pthread_rwlock_unlock - * @see pthread_rwlock_wrlock - * @see pthread_rwlock_timedwrlock - */ int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock) { int result; @@ -446,28 +271,6 @@ int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock) } RTM_EXPORT(pthread_rwlock_trywrlock); -/** - * @brief Release a read or write lock on a read-write lock. - * - * This function unlocks the specified read-write lock, releasing either a read - * lock or a write lock held by the calling thread. If the calling thread does - * not hold the lock, the behavior is undefined. - * - * @param rwlock A pointer to the read-write lock to be unlocked. - * - * @return - * - 0 on success. - * - EINVAL if the `rwlock` is invalid. - * - * @note - * - This function must only be called by the thread that successfully acquired - * the lock. - * - * @see pthread_rwlock_rdlock - * @see pthread_rwlock_wrlock - * @see pthread_rwlock_tryrdlock - * @see pthread_rwlock_trywrlock - */ int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) { int result; @@ -502,31 +305,6 @@ int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) } RTM_EXPORT(pthread_rwlock_unlock); -/** - * @brief Acquire a write lock on a read-write lock. - * - * This function locks the specified read-write lock for writing. If the lock - * is already held by another thread for reading or writing, the calling thread - * blocks until the lock becomes available. - * - * @param rwlock A pointer to the read-write lock to be locked. - * - * @return - * - 0 on success, indicating the write lock was acquired. - * - EINVAL if the `rwlock` is invalid. - * - EDEADLK if a deadlock condition is detected (optional; implementation-dependent). - * - * @note - * - A write lock is exclusive, meaning no other thread can acquire a read or - * write lock while a write lock is held. - * - The thread that successfully acquires the write lock must release it using - * `pthread_rwlock_unlock`. - * - * @see pthread_rwlock_unlock - * @see pthread_rwlock_trywrlock - * @see pthread_rwlock_timedwrlock - * @see pthread_rwlock_rdlock - */ int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) { int result; diff --git a/rt-thread/components/libc/posix/pthreads/pthread_tls.c b/rt-thread/components/libc/posix/pthreads/pthread_tls.c index 996c117..2e709ac 100644 --- a/rt-thread/components/libc/posix/pthreads/pthread_tls.c +++ b/rt-thread/components/libc/posix/pthreads/pthread_tls.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -21,31 +21,6 @@ static int pthread_key_system_init(void) } INIT_COMPONENT_EXPORT(pthread_key_system_init); -/** - * @brief Retrieves the value associated with a thread-specific data key for the calling thread. - * - * This function returns the value that was previously set for the specified key - * in the calling thread using `pthread_setspecific`. Each thread has its own independent - * value for the same key. - * - * @param[in] key - * The thread-specific data key, created using `pthread_key_create`. - * - * @return - * - The value associated with the key for the calling thread, or `NULL` if no value - * has been set for the key in this thread. - * - * @note - * - If no value has been set for the key in the calling thread, `pthread_getspecific` - * returns `NULL`. This does not indicate an error unless `NULL` was explicitly set as the value. - * - The value retrieved is specific to the calling thread and may differ for other threads. - * - * @attention - * - If the key has been deleted using `pthread_key_delete`, the behavior of this - * function is undefined. - * - * @see pthread_key_create(), pthread_setspecific(), pthread_key_delete() - */ void *pthread_getspecific(pthread_key_t key) { struct _pthread_data* ptd; @@ -66,37 +41,6 @@ void *pthread_getspecific(pthread_key_t key) } RTM_EXPORT(pthread_getspecific); -/** - * @brief Associates a value with a thread-specific data key for the calling thread. - * - * This function sets a thread-specific value for the given key. Each thread has its - * own independent value associated with the same key, and this value is not shared with - * other threads. - * - * @param[in] key - * The thread-specific data key, created using `pthread_key_create`. - * @param[in] value - * The value to associate with the key for the calling thread. The value can be - * a pointer to any data or `NULL`. - * - * @return - * - `0`: The value was successfully set. - * - `EINVAL`: The specified key is invalid or not initialized. - * - * @note - * - Setting a new value for a key in a thread overwrites any previously set value - * for that key in the same thread. - * - The value set using `pthread_setspecific` is accessible via `pthread_getspecific` - * for the same thread. - * - The association between the key and value is valid until the thread terminates, - * the key is deleted using `pthread_key_delete`, or a new value is set with this function. - * - * @attention - * - The value is specific to the calling thread; other threads will not be affected - * and will continue to maintain their own independent values for the same key. - * - * @see pthread_key_create(), pthread_getspecific(), pthread_key_delete() - */ int pthread_setspecific(pthread_key_t key, const void *value) { struct _pthread_data* ptd; @@ -110,7 +54,7 @@ int pthread_setspecific(pthread_key_t key, const void *value) /* check tls area */ if (ptd->tls == NULL) { - ptd->tls = (void**)rt_calloc(PTHREAD_KEY_MAX, sizeof(void*)); + ptd->tls = (void**)rt_malloc(sizeof(void*) * PTHREAD_KEY_MAX); } if ((key < PTHREAD_KEY_MAX) && _thread_keys[key].is_used) @@ -124,35 +68,6 @@ int pthread_setspecific(pthread_key_t key, const void *value) } RTM_EXPORT(pthread_setspecific); -/** - * @brief Creates a thread-specific data key. - * - * This function allocates a unique key for thread-specific data (TSD). - * Each thread can use this key to access its own specific data associated with it. - * - * @param[out] key - * A pointer to a variable where the newly created key will be stored. - * On success, `*key` will hold the newly allocated key. - * @param[in] destructor - * An optional destructor function pointer. This function will be called to - * clean up thread-specific data associated with the key when a thread terminates. - * Pass `NULL` if no cleanup is required. - * - * @return - * - `0`: The key was successfully created. - * - `EAGAIN`: The system has reached the maximum number of available keys, and no new key can be allocated. - * - * @note - * - Each thread can use `pthread_setspecific` and `pthread_getspecific` to set and retrieve the thread-specific data associated with the key. - * - The destructor function will be invoked automatically by the system when the thread terminates, if not explicitly called. - * - * @attention - * - If the `destructor` function is invoked and it sets thread-specific data for the same key, - * the destructor may be called multiple times, up to a limit defined by the system - * (typically `PTHREAD_DESTRUCTOR_ITERATIONS`). - * - * @see pthread_setspecific(), pthread_getspecific(), pthread_key_delete() - */ int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)) { rt_uint32_t index; @@ -179,29 +94,6 @@ int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)) } RTM_EXPORT(pthread_key_create); -/** - * @brief Deletes a thread-specific data key. - * - * This function deletes a previously created thread-specific data key. - * The key will no longer be valid for use in `pthread_setspecific` or `pthread_getspecific`. - * - * @param[in] key - * The thread-specific data key to delete. The key must have been created with - * `pthread_key_create`. - * - * @return - * - `0`: The key was successfully deleted. - * - `EINVAL`: The specified key is invalid or has not been initialized. - * - * @note - * - Deleting a key does not automatically free or clean up the thread-specific data - * associated with the key. It is the programmer's responsibility to ensure that - * associated resources are properly released, if necessary. - * - After deletion, using the key in `pthread_setspecific` or `pthread_getspecific` - * will result in undefined behavior. - * - * @see pthread_key_create(), pthread_setspecific(), pthread_getspecific() - */ int pthread_key_delete(pthread_key_t key) { if (key >= PTHREAD_KEY_MAX) diff --git a/rt-thread/components/lwp/Kconfig b/rt-thread/components/lwp/Kconfig index 8740fc3..22cfbea 100644 --- a/rt-thread/components/lwp/Kconfig +++ b/rt-thread/components/lwp/Kconfig @@ -8,23 +8,15 @@ menuconfig RT_USING_LWP if RT_USING_LWP menuconfig LWP_DEBUG bool "Enable debugging features of LwP" - default n + default y if LWP_DEBUG config LWP_DEBUG_INIT select RT_USING_HOOKLIST bool "Enable debug mode of init process" - depends on LWP_USING_RUNTIME - default y + default n endif - config LWP_USING_RUNTIME - bool "Using processes runtime environment (INIT process)" - default y - help - Runtime environment provide by init process including boot scripts, - poweroff, shutdown, reboot, etc. - config RT_LWP_MAX_NR int "The max number of light-weight process" default 30 @@ -37,6 +29,10 @@ if RT_USING_LWP int "The maximum number of channel messages" default 1024 + config LWP_CONSOLE_INPUT_BUFFER_SIZE + int "The input buffer size of lwp console device" + default 1024 + config LWP_TID_MAX_NR int "The maximum number of lwp thread id" default 64 @@ -85,6 +81,5 @@ if RT_USING_LWP endif rsource "terminal/Kconfig" -rsource "vdso/Kconfig" endif diff --git a/rt-thread/components/lwp/SConscript b/rt-thread/components/lwp/SConscript index cd8a242..5f4a618 100644 --- a/rt-thread/components/lwp/SConscript +++ b/rt-thread/components/lwp/SConscript @@ -18,23 +18,19 @@ cpu = rtconfig.CPU # fix the cpu for risc-v if arch == 'risc-v': - if GetDepend('ARCH_CPU_64BIT'): + rv64 = ['virt64', 'c906'] + if cpu in rv64: cpu = 'rv64' if platform in platform_file.keys(): # support platforms if arch in support_arch.keys() and cpu in support_arch[arch]: asm_path = 'arch/' + arch + '/' + cpu + '/*_' + platform_file[platform] arch_common = 'arch/' + arch + '/' + 'common/*.c' - if not GetDepend('RT_USING_VDSO'): - vdso_files = ['vdso_data.c', 'vdso.c'] - src += [f for f in Glob(arch_common) if os.path.basename(str(f)) not in vdso_files] - else: - src += Glob(arch_common) if not GetDepend('ARCH_MM_MMU'): excluded_files = ['ioremap.c', 'lwp_futex.c', 'lwp_mm_area.c', 'lwp_pmutex.c', 'lwp_shm.c', 'lwp_user_mm.c'] - src += [f for f in Glob('*.c') if os.path.basename(str(f)) not in excluded_files] + Glob(asm_path) + src += [f for f in Glob('*.c') if os.path.basename(str(f)) not in excluded_files] + Glob(asm_path) + Glob(arch_common) else: - src += Glob('*.c') + Glob(asm_path) + src += Glob('*.c') + Glob(asm_path) + Glob(arch_common) src += Glob('arch/' + arch + '/' + cpu + '/*.c') CPPPATH = [cwd] CPPPATH += [cwd + '/arch/' + arch + '/' + cpu] @@ -45,11 +41,6 @@ for item in termios_path: src += Glob(item + '*.c') CPPPATH += ['./terminal/'] -# Remove optional sources -if not GetDepend(['LWP_USING_RUNTIME']): - SrcRemove(src, 'lwp_runtime.c') - group = DefineGroup('lwP', src, depend = ['RT_USING_SMART'], CPPPATH = CPPPATH) -group = group + SConscript(os.path.join('vdso', 'SConscript')) Return('group') diff --git a/rt-thread/components/lwp/arch/aarch64/common/vdso.c b/rt-thread/components/lwp/arch/aarch64/common/vdso.c deleted file mode 100644 index 41b0a6d..0000000 --- a/rt-thread/components/lwp/arch/aarch64/common/vdso.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-04 rcitach init ver. - */ - -#include -#include -#include -#include - -#include "vdso.h" -#include "vdso_datapage.h" -#define DBG_TAG "vdso" -#define DBG_LVL DBG_INFO -#include - -enum vdso_abi { - VDSO_ABI_AA64, -}; -enum vvar_pages { - VVAR_DATA_PAGE_OFFSET, - VVAR_TIMENS_PAGE_OFFSET, - VVAR_NR_PAGES, -}; -struct vdso_abi_info { - const char *name; - const char *vdso_code_start; - const char *vdso_code_end; - unsigned long vdso_pages; - -}; - -static struct vdso_abi_info vdso_info[] = { - [VDSO_ABI_AA64] = { - .name = "vdso_aarch64", - .vdso_code_start = __vdso_text_start, - .vdso_code_end = __vdso_text_end, - }, -}; - -static union { - struct vdso_data data[CS_BASES]; - uint8_t page[ARCH_PAGE_SIZE]; -} vdso_data_store __page_aligned_data; -struct vdso_data *vdso_data = vdso_data_store.data; -int init_ret_flag = RT_EOK; - -static int __setup_additional_pages(enum vdso_abi abi, struct rt_lwp *lwp) -{ - RT_ASSERT(lwp != RT_NULL); - - int ret; - void *vdso_base = RT_NULL; - unsigned long vdso_data_len, vdso_text_len; - - vdso_data_len = VVAR_NR_PAGES * ARCH_PAGE_SIZE; - vdso_text_len = vdso_info[abi].vdso_pages << ARCH_PAGE_SHIFT; - - vdso_base = lwp_map_user_phy(lwp, RT_NULL, rt_kmem_v2p((void *)vdso_data), vdso_data_len, 0); - if(vdso_base != RT_NULL) - { - ret = RT_EOK; - } - else - { - ret = RT_ERROR; - } - vdso_base += vdso_data_len; - vdso_base = lwp_map_user_phy(lwp, vdso_base, rt_kmem_v2p((void *)vdso_info[abi].vdso_code_start), vdso_text_len, 0); - - lwp->vdso_vbase = vdso_base; - return ret; -} - -int arch_setup_additional_pages(struct rt_lwp *lwp) -{ - int ret; - if (init_ret_flag != RT_EOK) return -RT_ERROR; - ret = __setup_additional_pages(VDSO_ABI_AA64, lwp); - - return ret; -} - -static void __initdata(void) -{ - struct tm time_vdso = SOFT_RTC_VDSOTIME_DEFAULT; - vdso_data->realtime_initdata = timegm(&time_vdso); -} - -static int validate_vdso_elf(void) -{ - if (rt_memcmp(vdso_info[VDSO_ABI_AA64].vdso_code_start, ELF_HEAD, ELF_HEAD_LEN)) { - LOG_E("vDSO is not a valid ELF object!"); - init_ret_flag = -RT_ERROR; - return -RT_ERROR; - } - vdso_info[VDSO_ABI_AA64].vdso_pages = ( - vdso_info[VDSO_ABI_AA64].vdso_code_end - - vdso_info[VDSO_ABI_AA64].vdso_code_start) >> - ARCH_PAGE_SHIFT; - - __initdata(); - return RT_EOK; -} -INIT_COMPONENT_EXPORT(validate_vdso_elf); diff --git a/rt-thread/components/lwp/arch/aarch64/common/vdso_data.c b/rt-thread/components/lwp/arch/aarch64/common/vdso_data.c deleted file mode 100644 index 13c055e..0000000 --- a/rt-thread/components/lwp/arch/aarch64/common/vdso_data.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-04 rcitach init ver. - */ - -#include -#include -#include -#include -#include -#include - -void rt_vdso_update_glob_time(void) -{ - struct vdso_data *vdata = get_k_vdso_data(); - struct timespec *vdso_ts; - uint64_t initdata = vdata->realtime_initdata; - rt_vdso_write_begin(vdata); - - vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME]; - rt_ktime_boottime_get_ns(vdso_ts); - vdso_ts->tv_sec = initdata + vdso_ts->tv_sec; - - vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC]; - rt_ktime_boottime_get_ns(vdso_ts); - - vdata->cycle_last = rt_hw_get_cntpct_val(); - rt_vdso_write_end(vdata); -} diff --git a/rt-thread/components/lwp/arch/aarch64/cortex-a/lwp_arch.c b/rt-thread/components/lwp/arch/aarch64/cortex-a/lwp_arch.c index 7e6cd45..3df6b2f 100644 --- a/rt-thread/components/lwp/arch/aarch64/cortex-a/lwp_arch.c +++ b/rt-thread/components/lwp/arch/aarch64/cortex-a/lwp_arch.c @@ -106,16 +106,18 @@ int arch_set_thread_context(void (*exit)(void), void *new_thread_stack, struct rt_hw_exp_stack *ori_syscall = rt_thread_self()->user_ctx.ctx; RT_ASSERT(ori_syscall != RT_NULL); - new_thread_stack = (rt_ubase_t*)RT_ALIGN_DOWN((rt_ubase_t)new_thread_stack, 16); + thread_frame = (void *)((long)new_thread_stack - sizeof(struct rt_hw_exp_stack)); + syscall_frame = (void *)((long)new_thread_stack - 2 * sizeof(struct rt_hw_exp_stack)); - syscall_frame = (void *)((long)new_thread_stack - sizeof(struct rt_hw_exp_stack)); memcpy(syscall_frame, ori_syscall, sizeof(*syscall_frame)); syscall_frame->sp_el0 = (long)user_stack; syscall_frame->x0 = 0; - thread_frame = (void *)rt_hw_stack_init(exit, RT_NULL, (void *)syscall_frame, RT_NULL); + thread_frame->cpsr = ((3 << 6) | 0x4 | 0x1); + thread_frame->pc = (long)exit; + thread_frame->x0 = 0; - *thread_sp = thread_frame; + *thread_sp = syscall_frame; return 0; } diff --git a/rt-thread/components/lwp/arch/aarch64/cortex-a/lwp_gcc.S b/rt-thread/components/lwp/arch/aarch64/cortex-a/lwp_gcc.S index 9c4b7eb..a71ee33 100644 --- a/rt-thread/components/lwp/arch/aarch64/cortex-a/lwp_gcc.S +++ b/rt-thread/components/lwp/arch/aarch64/cortex-a/lwp_gcc.S @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -106,7 +105,6 @@ arch_get_user_sp: .global arch_clone_exit arch_fork_exit: arch_clone_exit: - mov x0, xzr b arch_syscall_exit /* @@ -127,37 +125,15 @@ lwp_exec_user: * since this routine reset the SP, we take it as a start point */ START_POINT(SVC_Handler) - mov fp, xzr - mov lr, xzr - /* x0 is initial sp */ mov sp, x0 - bl _SVC_Handler - - /* jump explictly, make this code position independant */ - b arch_syscall_exit -START_POINT_END(SVC_Handler) - -TRACE_SYMBOL(_SVC_Handler) -#define FRAME_REG x19 - -/** - * x0 -> frame_addr - */ -_SVC_Handler: - .local _SVC_Handler - - stp fp, lr, [sp, -16]! - mov fp, sp - - mov FRAME_REG, x0 /* save the value of frame address */ msr daifclr, #3 /* enable interrupt */ - GET_THREAD_SELF x0 + bl rt_thread_self bl lwp_user_setting_save - ldp x8, x9, [FRAME_REG, #(CONTEXT_OFFSET_X8)] + ldp x8, x9, [sp, #(CONTEXT_OFFSET_X8)] and x0, x8, #0xf000 cmp x0, #0xe000 beq arch_signal_quit @@ -170,46 +146,78 @@ _SVC_Handler: cmp x0, xzr mov x30, x0 beq arch_syscall_exit - ldp x0, x1, [FRAME_REG, #(CONTEXT_OFFSET_X0)] - ldp x2, x3, [FRAME_REG, #(CONTEXT_OFFSET_X2)] - ldp x4, x5, [FRAME_REG, #(CONTEXT_OFFSET_X4)] - ldp x6, x7, [FRAME_REG, #(CONTEXT_OFFSET_X6)] + ldp x0, x1, [sp, #(CONTEXT_OFFSET_X0)] + ldp x2, x3, [sp, #(CONTEXT_OFFSET_X2)] + ldp x4, x5, [sp, #(CONTEXT_OFFSET_X4)] + ldp x6, x7, [sp, #(CONTEXT_OFFSET_X6)] blr x30 + /* jump explictly, make this code position independant */ + b arch_syscall_exit +START_POINT_END(SVC_Handler) - ldp fp, lr, [sp], 16 - ret - -/** - * void arch_syscall_exit(long rc) - */ +.global arch_syscall_exit arch_syscall_exit: - .global arch_syscall_exit /** - * backup former x0 which is required to restart syscall, then setup + * @brief back up former x0 which is required to restart syscall, then setup * syscall return value in stack frame */ mov x1, sp bl arch_syscall_prepare_signal - /** - * disable local irq so we don't messup with the spsr_el1 witch is not saved - * for kernel space IRQ/EXCEPTION - */ msr daifset, #3 - b arch_ret_to_user + ldp x2, x3, [sp], #0x10 /* SPSR and ELR. */ + msr spsr_el1, x3 + msr elr_el1, x2 + + ldp x29, x30, [sp], #0x10 + msr sp_el0, x29 + ldp x28, x29, [sp], #0x10 + msr fpcr, x28 + msr fpsr, x29 + ldp x28, x29, [sp], #0x10 + ldp x26, x27, [sp], #0x10 + ldp x24, x25, [sp], #0x10 + ldp x22, x23, [sp], #0x10 + ldp x20, x21, [sp], #0x10 + ldp x18, x19, [sp], #0x10 + ldp x16, x17, [sp], #0x10 + ldp x14, x15, [sp], #0x10 + ldp x12, x13, [sp], #0x10 + ldp x10, x11, [sp], #0x10 + ldp x8, x9, [sp], #0x10 + ldp x6, x7, [sp], #0x10 + ldp x4, x5, [sp], #0x10 + ldp x2, x3, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + RESTORE_FPU sp /* the sp is reset to the outer most level, irq and fiq are disabled */ START_POINT(arch_ret_to_user) msr daifset, #3 + /* save exception frame */ + SAVE_FPU sp + stp x0, x1, [sp, #-0x10]! + stp x2, x3, [sp, #-0x10]! + stp x4, x5, [sp, #-0x10]! + stp x6, x7, [sp, #-0x10]! + stp x8, x9, [sp, #-0x10]! + stp x10, x11, [sp, #-0x10]! + stp x12, x13, [sp, #-0x10]! + stp x14, x15, [sp, #-0x10]! + stp x16, x17, [sp, #-0x10]! + stp x18, x19, [sp, #-0x10]! + stp x20, x21, [sp, #-0x10]! + stp x22, x23, [sp, #-0x10]! + stp x24, x25, [sp, #-0x10]! + stp x26, x27, [sp, #-0x10]! + stp x28, x29, [sp, #-0x10]! - ldr x2, [sp, #CONTEXT_OFFSET_SP_EL0] - msr sp_el0, x2 - ldr x2, [sp, #CONTEXT_OFFSET_ELR_EL1] - msr elr_el1, x2 - ldr x3, [sp, #CONTEXT_OFFSET_SPSR_EL1] - msr spsr_el1, x3 + mrs x0, fpcr + mrs x1, fpsr + stp x0, x1, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! /* pre-action */ bl lwp_check_debug @@ -220,8 +228,7 @@ START_POINT(arch_ret_to_user) msr daifclr, #3 mov x0, xzr b sys_exit - -1: /* handling dbg */ +1: /* check if dbg ops exist */ ldr x0, =rt_dbg_ops ldr x0, [x0] @@ -233,42 +240,104 @@ START_POINT(arch_ret_to_user) orr x2, x2, x1 msr spsr_el1, x2 b 3f -2: /* clear software step */ +2: bic x2, x2, x1 msr spsr_el1, x2 -3: /* handling signal */ +3: /** - * push updated spsr & elr to exception frame. - * Note: these 2 maybe updated after handling dbg + * push 2 dummy words to simulate a exception frame of interrupt + * Note: in kernel state, the context switch dont saved the context */ mrs x0, spsr_el1 - str x0, [sp, #CONTEXT_OFFSET_SPSR_EL1] mrs x1, elr_el1 - str x1, [sp, #CONTEXT_OFFSET_ELR_EL1] + stp x1, x0, [sp, #-0x10]! mov x0, sp - - /* restore the thread execution environment */ msr daifclr, #3 bl lwp_thread_signal_catch - - /* restore the exception-return exec-flow */ msr daifset, #3 + ldp x1, x0, [sp], #0x10 + msr spsr_el1, x0 + msr elr_el1, x1 /* check debug */ + /* restore exception frame */ + ldp x29, x30, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + msr fpcr, x0 + msr fpsr, x1 + ldp x28, x29, [sp], #0x10 + ldp x26, x27, [sp], #0x10 + ldp x24, x25, [sp], #0x10 + ldp x22, x23, [sp], #0x10 + ldp x20, x21, [sp], #0x10 + ldp x18, x19, [sp], #0x10 + ldp x16, x17, [sp], #0x10 + ldp x14, x15, [sp], #0x10 + ldp x12, x13, [sp], #0x10 + ldp x10, x11, [sp], #0x10 + ldp x8, x9, [sp], #0x10 + ldp x6, x7, [sp], #0x10 + ldp x4, x5, [sp], #0x10 + ldp x2, x3, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + RESTORE_FPU sp + + stp x0, x1, [sp, #-0x10]! ldr x0, =rt_dbg_ops ldr x0, [x0] cmp x0, xzr - + ldp x0, x1, [sp], #0x10 beq 1f - ldr x0, [sp, #CONTEXT_OFFSET_ELR_EL1] + /* save */ + SAVE_FPU sp + stp x0, x1, [sp, #-0x10]! + stp x2, x3, [sp, #-0x10]! + stp x4, x5, [sp, #-0x10]! + stp x6, x7, [sp, #-0x10]! + stp x8, x9, [sp, #-0x10]! + stp x10, x11, [sp, #-0x10]! + stp x12, x13, [sp, #-0x10]! + stp x14, x15, [sp, #-0x10]! + stp x16, x17, [sp, #-0x10]! + stp x18, x19, [sp, #-0x10]! + stp x20, x21, [sp, #-0x10]! + stp x22, x23, [sp, #-0x10]! + stp x24, x25, [sp, #-0x10]! + stp x26, x27, [sp, #-0x10]! + stp x28, x29, [sp, #-0x10]! + mrs x0, fpcr + mrs x1, fpsr + stp x0, x1, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! + + mrs x0, elr_el1 bl dbg_attach_req + /* restore */ + ldp x29, x30, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + msr fpcr, x0 + msr fpsr, x1 + ldp x28, x29, [sp], #0x10 + ldp x26, x27, [sp], #0x10 + ldp x24, x25, [sp], #0x10 + ldp x22, x23, [sp], #0x10 + ldp x20, x21, [sp], #0x10 + ldp x18, x19, [sp], #0x10 + ldp x16, x17, [sp], #0x10 + ldp x14, x15, [sp], #0x10 + ldp x12, x13, [sp], #0x10 + ldp x10, x11, [sp], #0x10 + ldp x8, x9, [sp], #0x10 + ldp x6, x7, [sp], #0x10 + ldp x4, x5, [sp], #0x10 + ldp x2, x3, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + RESTORE_FPU sp 1: - RESTORE_IRQ_CONTEXT_NO_SPEL0 - eret START_POINT_END(arch_ret_to_user) @@ -338,7 +407,32 @@ arch_syscall_restart: /* restore previous exception frame */ msr spsel, #0 - RESTORE_IRQ_CONTEXT_NO_SPEL0 + ldp x2, x3, [sp], #0x10 + msr elr_el1, x2 + msr spsr_el1, x3 + + ldp x29, x30, [sp], #0x10 + + ldp x28, x29, [sp], #0x10 + msr fpcr, x28 + msr fpsr, x29 + + ldp x28, x29, [sp], #0x10 + ldp x26, x27, [sp], #0x10 + ldp x24, x25, [sp], #0x10 + ldp x22, x23, [sp], #0x10 + ldp x20, x21, [sp], #0x10 + ldp x18, x19, [sp], #0x10 + ldp x16, x17, [sp], #0x10 + ldp x14, x15, [sp], #0x10 + ldp x12, x13, [sp], #0x10 + ldp x10, x11, [sp], #0x10 + ldp x8, x9, [sp], #0x10 + ldp x6, x7, [sp], #0x10 + ldp x4, x5, [sp], #0x10 + ldp x2, x3, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + RESTORE_FPU sp msr spsel, #1 @@ -346,8 +440,8 @@ arch_syscall_restart: arch_signal_quit: - /* drop current exception frame & sigreturn */ - add sp, sp, #(CONTEXT_SIZE + 0x10) + /* drop current exception frame */ + add sp, sp, #CONTEXT_SIZE mov x1, sp mrs x0, sp_el0 bl arch_signal_ucontext_restore @@ -363,12 +457,35 @@ arch_signal_quit: /* restore previous exception frame */ msr spsel, #0 - RESTORE_IRQ_CONTEXT_NO_SPEL0 + ldp x2, x3, [sp], #0x10 + msr elr_el1, x2 + msr spsr_el1, x3 + + ldp x29, x30, [sp], #0x10 + + ldp x28, x29, [sp], #0x10 + msr fpcr, x28 + msr fpsr, x29 + + ldp x28, x29, [sp], #0x10 + ldp x26, x27, [sp], #0x10 + ldp x24, x25, [sp], #0x10 + ldp x22, x23, [sp], #0x10 + ldp x20, x21, [sp], #0x10 + ldp x18, x19, [sp], #0x10 + ldp x16, x17, [sp], #0x10 + ldp x14, x15, [sp], #0x10 + ldp x12, x13, [sp], #0x10 + ldp x10, x11, [sp], #0x10 + ldp x8, x9, [sp], #0x10 + ldp x6, x7, [sp], #0x10 + ldp x4, x5, [sp], #0x10 + ldp x2, x3, [sp], #0x10 + ldp x0, x1, [sp], #0x10 + RESTORE_FPU sp msr spsel, #1 - SAVE_IRQ_CONTEXT - b arch_ret_to_user /** diff --git a/rt-thread/components/lwp/arch/x86/i386/lwp_arch.c b/rt-thread/components/lwp/arch/x86/i386/lwp_arch.c index c49e198..4b054f9 100644 --- a/rt-thread/components/lwp/arch/x86/i386/lwp_arch.c +++ b/rt-thread/components/lwp/arch/x86/i386/lwp_arch.c @@ -48,7 +48,7 @@ int arch_expand_user_stack(void *addr) else /* map failed, send signal SIGSEGV */ { #ifdef RT_USING_SIGNALS - LOG_E("[fault] thread %s mapped addr %p failed!\n", rt_thread_self()->parent.name, addr); + dbg_log(DBG_ERROR, "[fault] thread %s mapped addr %p failed!\n", rt_thread_self()->parent.name, addr); lwp_thread_kill(rt_thread_self(), SIGSEGV); ret = 1; /* return 1, will return back to intr, then check exit */ #endif @@ -57,7 +57,7 @@ int arch_expand_user_stack(void *addr) else /* not stack, send signal SIGSEGV */ { #ifdef RT_USING_SIGNALS - LOG_E("[fault] thread %s access unmapped addr %p!\n", rt_thread_self()->parent.name, addr); + dbg_log(DBG_ERROR, "[fault] thread %s access unmapped addr %p!\n", rt_thread_self()->parent.name, addr); lwp_thread_kill(rt_thread_self(), SIGSEGV); ret = 1; /* return 1, will return back to intr, then check exit */ #endif diff --git a/rt-thread/components/lwp/libc_musl.h b/rt-thread/components/lwp/libc_musl.h index 586fd49..fbc2ad5 100644 --- a/rt-thread/components/lwp/libc_musl.h +++ b/rt-thread/components/lwp/libc_musl.h @@ -11,15 +11,6 @@ #ifndef __LIBC_MUSL_H__ #define __LIBC_MUSL_H__ -/* from reboot.h */ -#define RB_AUTOBOOT 0x01234567 -#define RB_HALT_SYSTEM 0xcdef0123 -#define RB_ENABLE_CAD 0x89abcdef -#define RB_DISABLE_CAD 0 -#define RB_POWER_OFF 0x4321fedc -#define RB_SW_SUSPEND 0xd000fce2 -#define RB_KEXEC 0x45584543 - /* from internal/futex.h */ #define FUTEX_WAIT 0 diff --git a/rt-thread/components/lwp/lwp.c b/rt-thread/components/lwp/lwp.c index f5435bc..e809222 100644 --- a/rt-thread/components/lwp/lwp.c +++ b/rt-thread/components/lwp/lwp.c @@ -83,6 +83,87 @@ static int lwp_component_init(void) } INIT_COMPONENT_EXPORT(lwp_component_init); +rt_weak int lwp_startup_debug_request(void) +{ + return 0; +} + +#define LATENCY_TIMES (3) +#define LATENCY_IN_MSEC (128) +#define LWP_CONSOLE_PATH "CONSOLE=/dev/console" +const char *init_search_path[] = { + "/sbin/init", + "/bin/init", +}; + +/** + * Startup process 0 and do the essential works + * This is the "Hello World" point of RT-Smart + */ +static int lwp_startup(void) +{ + int error; + + const char *init_path; + char *argv[] = {0, "&"}; + char *envp[] = {LWP_CONSOLE_PATH, 0}; + +#ifdef LWP_DEBUG_INIT + int command; + int countdown = LATENCY_TIMES; + while (countdown) + { + command = lwp_startup_debug_request(); + if (command) + { + return 0; + } + rt_kprintf("Press any key to stop init process startup ... %d\n", countdown); + countdown -= 1; + rt_thread_mdelay(LATENCY_IN_MSEC); + } + rt_kprintf("Starting init ...\n"); +#endif /* LWP_DEBUG_INIT */ + + for (size_t i = 0; i < sizeof(init_search_path)/sizeof(init_search_path[0]); i++) + { + struct stat s; + init_path = init_search_path[i]; + error = stat(init_path, &s); + if (error == 0) + { + argv[0] = (void *)init_path; + error = lwp_execve((void *)init_path, 0, sizeof(argv)/sizeof(argv[0]), argv, envp); + if (error < 0) + { + LOG_E("%s: failed to startup process 0 (init)\n" + "Switching to legacy mode...", __func__); + } + else if (error != 1) + { + LOG_E("%s: pid 1 is already allocated", __func__); + error = -EBUSY; + } + else + { + rt_lwp_t p = lwp_from_pid_locked(1); + p->sig_protected = 1; + + error = 0; + } + break; + } + } + + if (error) + { + LOG_D("%s: init program not found\n" + "Switching to legacy mode...", __func__); + } + return error; +} +INIT_APP_EXPORT(lwp_startup); + void lwp_setcwd(char *buf) { struct rt_lwp *lwp = RT_NULL; @@ -366,7 +447,7 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp) if (lwp == RT_NULL) { - LOG_E("lwp struct out of memory!\n"); + dbg_log(DBG_ERROR, "lwp struct out of memory!\n"); return -ENOMEM; } LOG_D("lwp malloc : %p, size: %d!", lwp, sizeof(struct rt_lwp)); @@ -583,12 +664,12 @@ rt_err_t lwp_backtrace_frame(rt_thread_t uthread, struct rt_hw_backtrace_frame * argv = lwp_get_command_line_args(lwp); if (argv) { - rt_kprintf("please use: addr2line -e %s -a -f\n", argv[0]); + rt_kprintf("please use: addr2line -e %s -a -f", argv[0]); lwp_free_command_line_args(argv); } else { - rt_kprintf("please use: addr2line -e %s -a -f\n", lwp->cmd); + rt_kprintf("please use: addr2line -e %s -a -f", lwp->cmd); } while (nesting < RT_BACKTRACE_LEVEL_MAX_NR) diff --git a/rt-thread/components/lwp/lwp.h b/rt-thread/components/lwp/lwp.h index 2c95dee..e2cf2e8 100644 --- a/rt-thread/components/lwp/lwp.h +++ b/rt-thread/components/lwp/lwp.h @@ -197,10 +197,6 @@ struct rt_lwp unsigned int asid; #endif struct rusage rt_rusage; - -#ifdef RT_USING_VDSO - void *vdso_vbase; -#endif }; @@ -340,8 +336,6 @@ int lwp_session_set_foreground(rt_session_t session, pid_t pgid); /* complete the job control related bussiness on process exit */ void lwp_jobctrl_on_exit(struct rt_lwp *lwp); -sysret_t lwp_teardown(struct rt_lwp *lwp, void (*cb)(void)); - #ifdef __cplusplus } #endif @@ -379,7 +373,6 @@ sysret_t lwp_teardown(struct rt_lwp *lwp, void (*cb)(void)); #define AT_RANDOM 25 #define AT_HWCAP2 26 #define AT_EXECFN 31 -#define AT_SYSINFO_EHDR 33 struct process_aux_item { diff --git a/rt-thread/components/lwp/lwp_args.c b/rt-thread/components/lwp/lwp_args.c index c122a0f..3c70f7c 100644 --- a/rt-thread/components/lwp/lwp_args.c +++ b/rt-thread/components/lwp/lwp_args.c @@ -633,10 +633,10 @@ quit: return error; } -char **lwp_get_command_line_args(struct rt_lwp *lwp) +char** lwp_get_command_line_args(struct rt_lwp *lwp) { size_t argc = 0; - char **argv = NULL; + char** argv = NULL; int ret; size_t i; size_t len; @@ -648,7 +648,7 @@ char **lwp_get_command_line_args(struct rt_lwp *lwp) { return RT_NULL; } - argv = (char**)rt_calloc((argc + 1), sizeof(char*)); + argv = (char**)rt_malloc((argc + 1) * sizeof(char*)); if (argv) { @@ -658,23 +658,25 @@ char **lwp_get_command_line_args(struct rt_lwp *lwp) ret = lwp_data_get(lwp, &argvp, &((char **)lwp->args)[1 + i], sizeof(argvp)); if (ret == 0) { - goto error_exit; + lwp_free_command_line_args(argv); + return RT_NULL; } - len = lwp_user_strlen_ext(lwp, argvp); - if (len >= 0) + + if (len > 0) { argv[i] = (char*)rt_malloc(len + 1); ret = lwp_data_get(lwp, argv[i], argvp, len); - if (ret != len) + if (ret == 0) { - goto error_exit; + lwp_free_command_line_args(argv); + return RT_NULL; } argv[i][len] = '\0'; } else { - goto error_exit; + argv[i] = NULL; } } argv[argc] = NULL; @@ -682,9 +684,6 @@ char **lwp_get_command_line_args(struct rt_lwp *lwp) } return argv; -error_exit: - lwp_free_command_line_args(argv); - return RT_NULL; } void lwp_print_envp(struct rt_lwp *lwp) diff --git a/rt-thread/components/lwp/lwp_elf.c b/rt-thread/components/lwp/lwp_elf.c index 69021a4..da698e3 100644 --- a/rt-thread/components/lwp/lwp_elf.c +++ b/rt-thread/components/lwp/lwp_elf.c @@ -25,10 +25,6 @@ #include #endif -#ifdef RT_USING_VDSO -#include -#endif - #define DBG_TAG "load.elf" #ifdef ELF_DEBUG_ENABLE #define DBG_LVL DBG_LOG @@ -611,17 +607,6 @@ static int elf_aux_fill(elf_load_info_t *load_info) ELF_AUX_ENT(aux_info, AT_CLKTCK, 0); ELF_AUX_ENT(aux_info, AT_SECURE, 0); -#ifdef RT_USING_VDSO - if(RT_EOK == arch_setup_additional_pages(load_info->lwp)) - { - ELF_AUX_ENT(aux_info, AT_SYSINFO_EHDR, (size_t)load_info->lwp->vdso_vbase); - } - else - { - LOG_W("vdso map error,VDSO currently only supports aarch64 architecture!"); - } -#endif - return 0; } diff --git a/rt-thread/components/lwp/lwp_pgrp.c b/rt-thread/components/lwp/lwp_pgrp.c index b699e12..700565b 100644 --- a/rt-thread/components/lwp/lwp_pgrp.c +++ b/rt-thread/components/lwp/lwp_pgrp.c @@ -403,18 +403,6 @@ sysret_t sys_setpgid(pid_t pid, pid_t pgid) if (group == RT_NULL) { group = lwp_pgrp_create(process); - lwp_pgrp_move(group, process); - session = lwp_session_find(sid); - if (session == RT_NULL) - { - LOG_E("the session of sid: %d cannot be found", sid); - err = -EPERM; - goto exit; - } - else - { - lwp_session_insert(session, group); - } } else { diff --git a/rt-thread/components/lwp/lwp_pid.c b/rt-thread/components/lwp/lwp_pid.c index e455544..af32818 100644 --- a/rt-thread/components/lwp/lwp_pid.c +++ b/rt-thread/components/lwp/lwp_pid.c @@ -69,30 +69,13 @@ static int lwp_pid_ary_alloced = 0; static struct lwp_avl_struct *lwp_pid_root = RT_NULL; static pid_t current_pid = 0; static struct rt_mutex pid_mtx; -static struct rt_wqueue _pid_emptyq; int lwp_pid_init(void) { - rt_wqueue_init(&_pid_emptyq); rt_mutex_init(&pid_mtx, "pidmtx", RT_IPC_FLAG_PRIO); return 0; } -int lwp_pid_wait_for_empty(int wait_flags, rt_tick_t to) -{ - int error; - - if (wait_flags == RT_INTERRUPTIBLE) - { - error = rt_wqueue_wait_interruptible(&_pid_emptyq, 0, to); - } - else - { - error = rt_wqueue_wait_killable(&_pid_emptyq, 0, to); - } - return error; -} - void lwp_pid_lock_take(void) { LWP_DEF_RETURN_CODE(rc); @@ -110,35 +93,6 @@ void lwp_pid_lock_release(void) RT_ASSERT(0); } -struct pid_foreach_param -{ - int (*cb)(pid_t pid, void *data); - void *data; -}; - -static int _before_cb(struct lwp_avl_struct *node, void *data) -{ - struct pid_foreach_param *param = data; - pid_t pid = node->avl_key; - return param->cb(pid, param->data); -} - -int lwp_pid_for_each(int (*cb)(pid_t pid, void *data), void *data) -{ - int error; - struct pid_foreach_param buf = - { - .cb = cb, - .data = data, - }; - - lwp_pid_lock_take(); - error = lwp_avl_traversal(lwp_pid_root, _before_cb, &buf); - lwp_pid_lock_release(); - - return error; -} - struct lwp_avl_struct *lwp_get_pid_ary(void) { return lwp_pid_ary; @@ -228,15 +182,7 @@ void lwp_pid_put(struct rt_lwp *lwp) lwp_pid_lock_take(); lwp_pid_put_locked(lwp->pid); - if (lwp_pid_root == AVL_EMPTY) - { - rt_wqueue_wakeup_all(&_pid_emptyq, RT_NULL); - /* refuse any new pid allocation now */ - } - else - { - lwp_pid_lock_release(); - } + lwp_pid_lock_release(); /* reset pid field */ lwp->pid = 0; @@ -1564,7 +1510,6 @@ static void _notify_parent(rt_lwp_t lwp) static void _resr_cleanup(struct rt_lwp *lwp) { - int need_cleanup_pid = RT_FALSE; lwp_jobctrl_on_exit(lwp); LWP_LOCK(lwp); @@ -1634,7 +1579,7 @@ static void _resr_cleanup(struct rt_lwp *lwp) * if process is orphan, it doesn't have parent to do the recycling. * Otherwise, its parent had setup a flag to mask out recycling event */ - need_cleanup_pid = RT_TRUE; + lwp_pid_put(lwp); } LWP_LOCK(lwp); @@ -1654,11 +1599,6 @@ static void _resr_cleanup(struct rt_lwp *lwp) { LWP_UNLOCK(lwp); } - - if (need_cleanup_pid) - { - lwp_pid_put(lwp); - } } static int _lwp_setaffinity(int tid, int cpu) diff --git a/rt-thread/components/lwp/lwp_pid.h b/rt-thread/components/lwp/lwp_pid.h index 826f7a9..5e170f6 100644 --- a/rt-thread/components/lwp/lwp_pid.h +++ b/rt-thread/components/lwp/lwp_pid.h @@ -15,8 +15,6 @@ extern "C" { #endif -#include - #define LWP_CREATE_FLAG_NONE 0x0000 #define LWP_CREATE_FLAG_ALLOC_PID 0x0001 /* allocate pid on lwp object create */ #define LWP_CREATE_FLAG_INIT_USPACE 0x0002 /* do user space initialization */ @@ -26,8 +24,6 @@ struct rt_lwp; struct lwp_avl_struct *lwp_get_pid_ary(void); int lwp_pid_init(void); -int lwp_pid_wait_for_empty(int wait_flags, rt_tick_t to); -int lwp_pid_for_each(int (*cb)(pid_t pid, void *data), void *data); void lwp_pid_put(struct rt_lwp *lwp); void lwp_pid_lock_take(void); void lwp_pid_lock_release(void); diff --git a/rt-thread/components/lwp/lwp_runtime.c b/rt-thread/components/lwp/lwp_runtime.c deleted file mode 100644 index 34174d6..0000000 --- a/rt-thread/components/lwp/lwp_runtime.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-11-11 Shell moved lwp_startup() from lwp.c; - * added lwp_teardown() - */ - -#define DBG_TAG "lwp" -#define DBG_LVL DBG_INFO -#include - -#include "lwp_internal.h" - -#include -#include - -#include -#include -#include - -/** - * lwp_runtime: - * Runtime environment provide by init process including boot scripts, - * poweroff, shutdown, reboot, service management etc. In the kernel, lwp will - * provide the underlying software bootstrap and cleanup for the init proc. - * - */ - -rt_weak int lwp_startup_debug_request(void) -{ - return 0; -} - -#define LATENCY_TIMES (3) -#define LATENCY_IN_MSEC (128) -#define LWP_CONSOLE_PATH "CONSOLE=/dev/console" -const char *init_search_path[] = { - "/sbin/init", - "/bin/init", -}; - -/** - * Startup process 1 and do the essential works - */ -static int lwp_startup(void) -{ - int error; - - const char *init_path; - char *argv[] = {0, "&"}; - char *envp[] = {LWP_CONSOLE_PATH, 0}; - -#ifdef LWP_DEBUG_INIT - int command; - int countdown = LATENCY_TIMES; - while (countdown) - { - command = lwp_startup_debug_request(); - if (command) - { - return 0; - } - rt_kprintf("Press any key to stop init process startup ... %d\n", countdown); - countdown -= 1; - rt_thread_mdelay(LATENCY_IN_MSEC); - } - rt_kprintf("Starting init ...\n"); -#endif /* LWP_DEBUG_INIT */ - - for (size_t i = 0; i < sizeof(init_search_path)/sizeof(init_search_path[0]); i++) - { - struct stat s; - init_path = init_search_path[i]; - error = stat(init_path, &s); - if (error == 0) - { - argv[0] = (void *)init_path; - error = lwp_execve((void *)init_path, 0, sizeof(argv)/sizeof(argv[0]), argv, envp); - if (error < 0) - { - LOG_W("%s: failed to setup runtime environment\b" - "\tlwp_execve() failed with code %d", __func__, error); - } - else if (error != 1) - { - LOG_W("%s: pid 1 is already allocated", __func__); - error = -EBUSY; - } - else - { - rt_lwp_t p = lwp_from_pid_locked(1); - p->sig_protected = 1; - - error = 0; - } - break; - } - } - - if (error) - { - LOG_D("%s: failed to setup runtime environment\b" - "\tinit program not found", __func__); - } - return error; -} -INIT_APP_EXPORT(lwp_startup); - -/* don't use heap for safety */ -static struct rt_work _teardown_work; - -#define INIT_PID 1 -static void _teardown_entry(struct rt_work *work, void *work_data) -{ - int error; - void (*cb_on_reboot)(void) = work_data; - - /* cleanup of process */ - do - { - error = lwp_pid_wait_for_empty(RT_KILLABLE, RT_WAITING_FOREVER); - } - while (error); - LOG_I("All processes exited"); - - cb_on_reboot(); - return; -} - -static int _get_parent_pid(struct rt_lwp *lwp) -{ - return lwp->parent ? lwp->parent->pid : 0; -} - -/* reverse operation of lwp_startup() */ -sysret_t lwp_teardown(struct rt_lwp *lwp, void (*cb)(void)) -{ - struct rt_work *work; - - if (lwp->pid != INIT_PID && _get_parent_pid(lwp) != INIT_PID) - { - /* The calling process has insufficient privilege */ - return -EPERM; - } - - work = &_teardown_work; - rt_work_init(work, _teardown_entry, cb); - -#define SOME_DELAY (RT_TICK_PER_SECOND / 10) /* allow idle to cleanup resource */ - rt_work_submit(work, SOME_DELAY); - - lwp_exit(lwp, LWP_CREATE_STAT_EXIT(EXIT_SUCCESS)); - - /* never return */ - RT_ASSERT(0); - return 0; -} diff --git a/rt-thread/components/lwp/lwp_signal.c b/rt-thread/components/lwp/lwp_signal.c index 0bbb98c..1f20ad5 100644 --- a/rt-thread/components/lwp/lwp_signal.c +++ b/rt-thread/components/lwp/lwp_signal.c @@ -1442,41 +1442,3 @@ rt_err_t lwp_pgrp_signal_kill(rt_processgroup_t pgrp, long signo, long code, return rc; } - -struct kill_all_param -{ - long signo; - long code; - lwp_siginfo_ext_t value; -}; - -static int _kill_each(pid_t pid, void *data) -{ - struct kill_all_param *param = data; - rt_lwp_t lwp; - rt_err_t error; - - lwp = lwp_from_pid_locked(pid); - if (lwp && !lwp->sig_protected) - { - error = lwp_signal_kill(lwp, param->signo, param->code, param->value); - } - else - { - error = RT_EOK; - } - - return error; -} - -rt_err_t lwp_signal_kill_all(long signo, long code, lwp_siginfo_ext_t value) -{ - struct kill_all_param buf = - { - .signo = signo, - .code = code, - .value = value, - }; - - return lwp_pid_for_each(_kill_each, &buf); -} diff --git a/rt-thread/components/lwp/lwp_signal.h b/rt-thread/components/lwp/lwp_signal.h index 7e7bbad..f98b43d 100644 --- a/rt-thread/components/lwp/lwp_signal.h +++ b/rt-thread/components/lwp/lwp_signal.h @@ -229,8 +229,6 @@ rt_err_t lwp_signal_setitimer(struct rt_lwp *lwp, int which, rt_bool_t lwp_signal_restart_syscall(struct rt_lwp *lwp, int error_code); -rt_err_t lwp_signal_kill_all(long signo, long code, lwp_siginfo_ext_t value); - #ifdef __cplusplus } #endif diff --git a/rt-thread/components/lwp/lwp_sys_socket.h b/rt-thread/components/lwp/lwp_sys_socket.h index 7f1fc45..28a0887 100644 --- a/rt-thread/components/lwp/lwp_sys_socket.h +++ b/rt-thread/components/lwp/lwp_sys_socket.h @@ -41,10 +41,6 @@ #define INTF_SO_SNDBUF 7 #define INTF_SO_SNDLOWAT 19 #define INTF_SO_RCVLOWAT 18 -#define INTF_SO_BINDTODEVICE 25 -#define INTF_SO_TIMESTAMPNS 35 -#define INTF_SO_TIMESTAMPING 37 -#define INTF_SO_SELECT_ERR_QUEUE 45 #define IMPL_SO_BROADCAST 0x0020 #define IMPL_SO_KEEPALIVE 0x0008 @@ -63,10 +59,6 @@ #define IMPL_SO_SNDBUF 0x1001 #define IMPL_SO_SNDLOWAT 0x1003 #define IMPL_SO_RCVLOWAT 0x1004 -#define IMPL_SO_BINDTODEVICE 0x100b -#define IMPL_SO_TIMESTAMPNS INTF_SO_TIMESTAMPNS -#define IMPL_SO_TIMESTAMPING INTF_SO_TIMESTAMPING -#define IMPL_SO_SELECT_ERR_QUEUE INTF_SO_SELECT_ERR_QUEUE /* IPPROTO_IP option names */ #define INTF_IP_TTL 2 diff --git a/rt-thread/components/lwp/lwp_syscall.c b/rt-thread/components/lwp/lwp_syscall.c index 72f5b87..e539e04 100644 --- a/rt-thread/components/lwp/lwp_syscall.c +++ b/rt-thread/components/lwp/lwp_syscall.c @@ -198,18 +198,6 @@ void lwp_cleanup(struct rt_thread *tid); case INTF_SO_NO_CHECK: *optname = IMPL_SO_NO_CHECK; break; - case INTF_SO_BINDTODEVICE: - *optname = IMPL_SO_BINDTODEVICE; - break; - case INTF_SO_TIMESTAMPNS: - *optname = IMPL_SO_TIMESTAMPNS; - break; - case INTF_SO_TIMESTAMPING: - *optname = IMPL_SO_TIMESTAMPING; - break; - case INTF_SO_SELECT_ERR_QUEUE: - *optname = IMPL_SO_SELECT_ERR_QUEUE; - break; /* * SO_DONTLINGER (*level = ((int)(~SO_LINGER))), @@ -473,7 +461,7 @@ ssize_t sys_write(int fd, const void *buf, size_t nbyte) /* syscall: "lseek" ret: "off_t" args: "int" "off_t" "int" */ size_t sys_lseek(int fd, size_t offset, int whence) { - ssize_t ret = lseek(fd, offset, whence); + size_t ret = lseek(fd, offset, whence); return (ret < 0 ? GET_ERRNO() : ret); } @@ -821,7 +809,7 @@ sysret_t sys_unlink(const char *pathname) sysret_t sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp) { int ret = 0; - LOG_D("sys_nanosleep\n"); + dbg_log(DBG_LOG, "sys_nanosleep\n"); if (!lwp_user_accessable((void *)rqtp, sizeof *rqtp)) return -EFAULT; @@ -994,7 +982,7 @@ sysret_t sys_kill(int pid, int signo) * of system processes) for which the process has permission to send * that signal. */ - kret = lwp_signal_kill_all(signo, SI_USER, 0); + kret = -RT_ENOSYS; } switch (kret) @@ -1241,7 +1229,7 @@ void *sys_mmap2(void *addr, size_t length, int prot, rc = (sysret_t)lwp_mmap2(lwp_self(), addr, length, prot, flags, fd, pgoffset); } - return rc < 0 ? (char *)rc : (char *)rc + offset; + return (char *)rc + offset; } sysret_t sys_munmap(void *addr, size_t length) @@ -1844,7 +1832,6 @@ long _sys_clone(void *arg[]) rt_thread_t thread = RT_NULL; rt_thread_t self = RT_NULL; int tid = 0; - rt_err_t err; unsigned long flags = 0; void *user_stack = RT_NULL; @@ -1948,9 +1935,6 @@ long _sys_clone(void *arg[]) rt_thread_startup(thread); return (long)tid; fail: - err = GET_ERRNO(); - RT_ASSERT(err < 0); - lwp_tid_put(tid); if (thread) { @@ -1960,7 +1944,7 @@ fail: { lwp_ref_dec(lwp); } - return (long)err; + return GET_ERRNO(); } rt_weak long sys_clone(void *arg[]) @@ -2188,7 +2172,7 @@ rt_weak sysret_t sys_vfork(void) sysret_t sys_execve(const char *path, char *const argv[], char *const envp[]) { - rt_err_t error = -1; + int error = -1; size_t len; struct rt_lwp *new_lwp = NULL; struct rt_lwp *lwp; @@ -2239,9 +2223,8 @@ sysret_t sys_execve(const char *path, char *const argv[], char *const envp[]) if (access(kpath, X_OK) != 0) { - error = rt_get_errno(); rt_free(kpath); - return (sysret_t)error; + return -EACCES; } /* setup args */ @@ -2892,12 +2875,23 @@ sysret_t sys_bind(int socket, const struct musl_sockaddr *name, socklen_t namele lwp_get_from_user(&family, (void *)name, 2); if (family == AF_UNIX) { + if (!lwp_user_accessable((void *)name, sizeof(struct sockaddr_un))) + { + return -EFAULT; + } + lwp_get_from_user(&un_addr, (void *)name, sizeof(struct sockaddr_un)); ret = bind(socket, (struct sockaddr *)&un_addr, namelen); } else if (family == AF_NETLINK) { + if (!lwp_user_accessable((void *)name, namelen)) + { + return -EFAULT; + } + lwp_get_from_user(&sa, (void *)name, namelen); + ret = bind(socket, &sa, namelen); } else @@ -3138,11 +3132,6 @@ static int netflags_muslc_2_lwip(int flags) { flgs |= MSG_MORE; } - if (flags & MSG_ERRQUEUE) - { - flgs |= MSG_ERRQUEUE; - } - return flgs; } @@ -4484,9 +4473,8 @@ sysret_t sys_mkdir(const char *path, mode_t mode) sysret_t sys_rmdir(const char *path) { - int err = 0; - int ret = 0; #ifdef ARCH_MM_MMU + int err = 0; int len = 0; char *kpath = RT_NULL; @@ -4508,25 +4496,29 @@ sysret_t sys_rmdir(const char *path) return -EINVAL; } - ret = rmdir(kpath); - if(ret < 0) - { - err = GET_ERRNO(); - } + err = rmdir(kpath); kmem_put(kpath); - return (err < 0 ? err : ret); + return (err < 0 ? GET_ERRNO() : err); #else - ret = rmdir(path); - if(ret < 0) - { - err = GET_ERRNO(); - } - return (err < 0 ? err : ret); + int ret = rmdir(path); + return (ret < 0 ? GET_ERRNO() : ret); #endif } +#ifdef RT_USING_MUSLLIBC +typedef uint64_t ino_t; +#endif + +struct libc_dirent { + ino_t d_ino; + off_t d_off; + unsigned short d_reclen; + unsigned char d_type; + char d_name[DIRENT_NAME_MAX]; +}; + sysret_t sys_getdents(int fd, struct libc_dirent *dirp, size_t nbytes) { int ret = -1; @@ -4759,7 +4751,7 @@ sysret_t sys_clock_gettime(clockid_t clk, struct timespec *ts) sysret_t sys_clock_nanosleep(clockid_t clk, int flags, const struct timespec *rqtp, struct timespec *rmtp) { int ret = 0; - LOG_D("sys_nanosleep\n"); + dbg_log(DBG_LOG, "sys_nanosleep\n"); if (!lwp_user_accessable((void *)rqtp, sizeof *rqtp)) return -EFAULT; @@ -5007,8 +4999,7 @@ ssize_t sys_readlink(char* path, char *buf, size_t bufsz) err = dfs_file_readlink(copy_path, link_fn, DFS_PATH_MAX); if (err > 0) { - buf[bufsz > err ? err : bufsz] = '\0'; - rtn = lwp_put_to_user(buf, link_fn, bufsz > err ? err : bufsz); + rtn = lwp_put_to_user(buf, link_fn, bufsz > err ? err : bufsz - 1); } else { @@ -5743,94 +5734,58 @@ sysret_t sys_fstatfs64(int fd, size_t sz, struct statfs *buf) return ret; } -static char *_cp_from_usr_string(char *dst, char *src, size_t length) +sysret_t sys_mount(char *source, char *target, + char *filesystemtype, + unsigned long mountflags, void *data) { - char *rc; - size_t copied_bytes; - if (length) - { - copied_bytes = lwp_get_from_user(dst, src, length); - dst[copied_bytes] = '\0'; - rc = dst; - } - else - { - rc = RT_NULL; - } - return rc; -} - -sysret_t sys_mount(char *source, char *target, char *filesystemtype, - unsigned long mountflags, void *data) -{ - char *kbuffer, *ksource, *ktarget, *kfs; - size_t len_source, len_target, len_fs; + char *copy_source; + char *copy_target; + char *copy_filesystemtype; + size_t len_source, copy_len_source; + size_t len_target, copy_len_target; + size_t len_filesystemtype, copy_len_filesystemtype; char *tmp = NULL; int ret = 0; - struct stat buf = {0}; - char *dev_fullpath = RT_NULL; - len_source = source ? lwp_user_strlen(source) : 0; - if (len_source < 0) + len_source = lwp_user_strlen(source); + if (len_source <= 0) return -EINVAL; - len_target = target ? lwp_user_strlen(target) : 0; + len_target = lwp_user_strlen(target); if (len_target <= 0) return -EINVAL; - len_fs = filesystemtype ? lwp_user_strlen(filesystemtype) : 0; - if (len_fs < 0) + len_filesystemtype = lwp_user_strlen(filesystemtype); + if (len_filesystemtype <= 0) return -EINVAL; - kbuffer = (char *)rt_malloc(len_source + 1 + len_target + 1 + len_fs + 1); - if (!kbuffer) + copy_source = (char*)rt_malloc(len_source + 1 + len_target + 1 + len_filesystemtype + 1); + if (!copy_source) { return -ENOMEM; } + copy_target = copy_source + len_source + 1; + copy_filesystemtype = copy_target + len_target + 1; - /* get parameters from user space */ - ksource = kbuffer; - ktarget = ksource + len_source + 1; - kfs = ktarget + len_target + 1; - ksource = _cp_from_usr_string(ksource, source, len_source); - ktarget = _cp_from_usr_string(ktarget, target, len_target); - kfs = _cp_from_usr_string(kfs, filesystemtype, len_fs); + copy_len_source = lwp_get_from_user(copy_source, source, len_source); + copy_source[copy_len_source] = '\0'; + copy_len_target = lwp_get_from_user(copy_target, target, len_target); + copy_target[copy_len_target] = '\0'; + copy_len_filesystemtype = lwp_get_from_user(copy_filesystemtype, filesystemtype, len_filesystemtype); + copy_filesystemtype[copy_len_filesystemtype] = '\0'; - if (mountflags & MS_REMOUNT) + if (strcmp(copy_filesystemtype, "nfs") == 0) { - ret = dfs_remount(ktarget, mountflags, data); + tmp = copy_source; + copy_source = NULL; } - else + if (strcmp(copy_filesystemtype, "tmp") == 0) { - if (strcmp(kfs, "nfs") == 0) - { - tmp = ksource; - ksource = NULL; - } - if (strcmp(kfs, "tmp") == 0) - { - ksource = NULL; - } - - if (ksource && !dfs_file_stat(ksource, &buf) && S_ISBLK(buf.st_mode)) - { - dev_fullpath = dfs_normalize_path(RT_NULL, ksource); - RT_ASSERT(rt_strncmp(dev_fullpath, "/dev/", sizeof("/dev/") - 1) == 0); - ret = dfs_mount(dev_fullpath + sizeof("/dev/") - 1, ktarget, kfs, 0, tmp); - } - else - { - ret = dfs_mount(ksource, ktarget, kfs, 0, tmp); - } - - if (ret < 0) - { - ret = -rt_get_errno(); - } + copy_source = NULL; } + ret = dfs_mount(copy_source, copy_target, copy_filesystemtype, 0, tmp); + rt_free(copy_source); - rt_free(kbuffer); - rt_free(dev_fullpath); return ret; } @@ -5864,7 +5819,7 @@ sysret_t sys_umount2(char *__special_file, int __flags) sysret_t sys_link(const char *existing, const char *new) { int ret = -1; - int err = 0; + #ifdef RT_USING_DFS_V2 #ifdef ARCH_MM_MMU int len = 0; @@ -5911,10 +5866,6 @@ sysret_t sys_link(const char *existing, const char *new) } ret = dfs_file_link(kexisting, knew); - if(ret < 0) - { - err = GET_ERRNO(); - } kmem_put(knew); kmem_put(kexisting); @@ -5923,40 +5874,36 @@ sysret_t sys_link(const char *existing, const char *new) #endif #else SET_ERRNO(EFAULT); - err = GET_ERRNO(); #endif - return (err < 0 ? err : ret); + return (ret < 0 ? GET_ERRNO() : ret); } sysret_t sys_symlink(const char *existing, const char *new) { int ret = -1; - int err = 0 ; -#ifdef ARCH_MM_MMU - ret = lwp_user_strlen(existing); - if (ret <= 0) +#ifdef ARCH_MM_MMU + int err; + + err = lwp_user_strlen(existing); + if (err <= 0) { return -EFAULT; } - ret = lwp_user_strlen(new); - if (ret <= 0) + err = lwp_user_strlen(new); + if (err <= 0) { return -EFAULT; } #endif #ifdef RT_USING_DFS_V2 ret = dfs_file_symlink(existing, new); - if(ret < 0) - { - err = GET_ERRNO(); - } #else SET_ERRNO(EFAULT); #endif - return (err < 0 ? err : ret); + return (ret < 0 ? GET_ERRNO() : ret); } sysret_t sys_eventfd2(unsigned int count, int flags) @@ -6186,27 +6133,16 @@ sysret_t sys_chown(const char *pathname, uid_t owner, gid_t group) return (ret < 0 ? GET_ERRNO() : ret); } -#ifndef LWP_USING_RUNTIME -sysret_t lwp_teardown(struct rt_lwp *lwp, void (*cb)(void)) -{ - /* if no LWP_USING_RUNTIME configured */ - return -ENOSYS; -} -#endif - -sysret_t sys_reboot(int magic, int magic2, int type, void *arg) +#include +sysret_t sys_reboot(int magic, int magic2, int type) { sysret_t rc; switch (type) { - /* Hardware reset */ + /* TODO add software poweroff protocols */ case RB_AUTOBOOT: - rc = lwp_teardown(lwp_self(), rt_hw_cpu_reset); - break; - - /* Stop system and switch power off */ case RB_POWER_OFF: - rc = lwp_teardown(lwp_self(), rt_hw_cpu_shutdown); + rt_hw_cpu_reset(); break; default: rc = -ENOSYS; diff --git a/rt-thread/components/lwp/lwp_syscall.h b/rt-thread/components/lwp/lwp_syscall.h index 45c9526..1527a76 100644 --- a/rt-thread/components/lwp/lwp_syscall.h +++ b/rt-thread/components/lwp/lwp_syscall.h @@ -32,6 +32,7 @@ extern "C" { #endif +typedef long suseconds_t; /* microseconds (signed) */ typedef uint32_t id_t; /* may contain pid, uid or gid */ /* diff --git a/rt-thread/components/lwp/lwp_tid.c b/rt-thread/components/lwp/lwp_tid.c index e5e4889..3e33002 100644 --- a/rt-thread/components/lwp/lwp_tid.c +++ b/rt-thread/components/lwp/lwp_tid.c @@ -88,12 +88,6 @@ int lwp_tid_get(void) current_tid = tid; } lwp_mutex_release_safe(&tid_lock); - - if (tid <= 0) - { - LOG_W("resource TID exhausted."); - } - return tid; } diff --git a/rt-thread/components/lwp/lwp_user_mm.c b/rt-thread/components/lwp/lwp_user_mm.c index 18f10e1..01640d5 100644 --- a/rt-thread/components/lwp/lwp_user_mm.c +++ b/rt-thread/components/lwp/lwp_user_mm.c @@ -70,29 +70,11 @@ static void _null_page_fault(struct rt_varea *varea, static rt_err_t _null_shrink(rt_varea_t varea, void *new_start, rt_size_t size) { - char *varea_start = varea->start; - void *rm_start; - void *rm_end; - - if (varea_start == (char *)new_start) - { - rm_start = varea_start + size; - rm_end = varea_start + varea->size; - } - else /* if (varea_start < (char *)new_start) */ - { - RT_ASSERT(varea_start < (char *)new_start); - rm_start = varea_start; - rm_end = new_start; - } - - rt_varea_unmap_range(varea, rm_start, rm_end - rm_start); return RT_EOK; } static rt_err_t _null_split(struct rt_varea *existed, void *unmap_start, rt_size_t unmap_len, struct rt_varea *subset) { - rt_varea_unmap_range(existed, unmap_start, unmap_len); return RT_EOK; } diff --git a/rt-thread/components/lwp/syscall_generic.h b/rt-thread/components/lwp/syscall_generic.h index 5d82873..a589b6f 100644 --- a/rt-thread/components/lwp/syscall_generic.h +++ b/rt-thread/components/lwp/syscall_generic.h @@ -16,8 +16,7 @@ #include #include -/* signed ARCH related types */ -typedef rt_base_t sysret_t; +typedef long sysret_t; struct rt_syscall_def { diff --git a/rt-thread/components/lwp/terminal/Kconfig b/rt-thread/components/lwp/terminal/Kconfig index a62df00..7fd77e7 100644 --- a/rt-thread/components/lwp/terminal/Kconfig +++ b/rt-thread/components/lwp/terminal/Kconfig @@ -2,7 +2,6 @@ menuconfig LWP_USING_TERMINAL bool "Terminal I/O Subsystem" depends on RT_USING_SMART default y - select RT_USING_SERIAL_BYPASS if LWP_USING_TERMINAL config LWP_PTY_MAX_PARIS_LIMIT diff --git a/rt-thread/components/lwp/terminal/freebsd/tty.c b/rt-thread/components/lwp/terminal/freebsd/tty.c index e5a6e79..cdd9006 100644 --- a/rt-thread/components/lwp/terminal/freebsd/tty.c +++ b/rt-thread/components/lwp/terminal/freebsd/tty.c @@ -73,7 +73,7 @@ static const char *dev_console_filename; #define TTYSUP_CFLAG \ (CIGNORE | CSIZE | CSTOPB | CREAD | PARENB | PARODD | HUPCL | CLOCAL | \ CCTS_OFLOW | CRTS_IFLOW | CDTR_IFLOW | CDSR_OFLOW | CCAR_OFLOW | \ - CNO_RTSDTR | CBAUD) + CNO_RTSDTR) /* * Set TTY buffer sizes. diff --git a/rt-thread/components/lwp/terminal/tty_ptmx.c b/rt-thread/components/lwp/terminal/tty_ptmx.c index 371c27a..8daebc0 100644 --- a/rt-thread/components/lwp/terminal/tty_ptmx.c +++ b/rt-thread/components/lwp/terminal/tty_ptmx.c @@ -27,6 +27,7 @@ static int ptm_fops_open(struct dfs_file *file) rt_uint32_t oflags = file->flags; rt_thread_t cur_thr = rt_thread_self(); + /* we don't check refcnt because each open will create a new device */ if (file->vnode && file->vnode->data) { /** @@ -61,9 +62,16 @@ static int ptm_fops_close(struct dfs_file *file) if (file->data) { - device = (rt_device_t)file->data; - tp = rt_container_of(device, struct lwp_tty, parent); - rc = bsd_ptsdev_methods.fo_close(tp, rt_thread_self()); + if (file->vnode->ref_count != 1) + { + rc = 0; + } + else + { + device = (rt_device_t)file->data; + tp = rt_container_of(device, struct lwp_tty, parent); + rc = bsd_ptsdev_methods.fo_close(tp, rt_thread_self()); + } } else { diff --git a/rt-thread/components/lwp/vdso/Kconfig b/rt-thread/components/lwp/vdso/Kconfig deleted file mode 100644 index 144a945..0000000 --- a/rt-thread/components/lwp/vdso/Kconfig +++ /dev/null @@ -1,4 +0,0 @@ -menuconfig RT_USING_VDSO - bool "vDSO" - default y - depends on RT_USING_SMART && ARCH_ARMV8 diff --git a/rt-thread/components/lwp/vdso/SConscript b/rt-thread/components/lwp/vdso/SConscript deleted file mode 100644 index addcdfc..0000000 --- a/rt-thread/components/lwp/vdso/SConscript +++ /dev/null @@ -1,48 +0,0 @@ -import os -import rtconfig -import subprocess -from building import * -Import('RTT_ROOT') - -group = [] - -cwd = GetCurrentDir() -CPPPATH = [cwd, cwd + "/kernel"] - -if not GetDepend(['RT_USING_VDSO']): - Return('group') - -if rtconfig.ARCH != "aarch64": - src = Glob('*.c') - group = DefineGroup('VDSO', src, depend = ['RT_USING_SMART','RT_USING_VDSO'], CPPPATH = CPPPATH) - Return('group') - -list = os.listdir(cwd) -src = Glob('kernel/*.c') -src +=Glob('kernel/*.S') - -if not os.path.exists(cwd + "/user/vdso.lds"): - Preprocessing("user/vdso.lds.S", ".lds", CPPPATH=[cwd]) - -#aarch64 vdso xmake -# vdso_file = os.path.join(cwd, 'usr', 'xmake.lua') -# command = ["xmake", "-F", vdso_file] -# clean = ["xmake", "clean"] - -vdso_file = os.path.join(cwd, 'user', 'SConstruct') -command = ["scons", "-f", vdso_file] -clean = ["scons", "-f", vdso_file, "--clean"] - -if not GetOption('clean'): - result = subprocess.run(command) -else: - result = subprocess.run(clean) - -if result.returncode == 0: - print("Command executed successfully") -else: - print("Command failed with exit code:", result.returncode) - exit(1) - -group = DefineGroup('VDSO', src, depend = ['RT_USING_SMART','RT_USING_VDSO'], CPPPATH = CPPPATH) -Return('group') diff --git a/rt-thread/components/lwp/vdso/kernel/vdso.h b/rt-thread/components/lwp/vdso/kernel/vdso.h deleted file mode 100644 index 1cb3b44..0000000 --- a/rt-thread/components/lwp/vdso/kernel/vdso.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-04 rcitach init ver. - */ - -#ifndef _VDSO_H -#define _VDSO_H - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern char __vdso_text_start[]; -extern char __vdso_text_end[]; - -#define ELF_HEAD "\177ELF" -#define ELF_HEAD_LEN 4 -#define MAX_PAGES 5 - -#define __page_aligned_data __attribute__((section(".data.vdso.datapage"))) __attribute__((aligned(VDSO_PAGE_SIZE))) - -int arch_setup_additional_pages(struct rt_lwp *lwp); -void rt_vdso_update_glob_time(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _VDSO_H */ diff --git a/rt-thread/components/lwp/vdso/kernel/vdso_data.h b/rt-thread/components/lwp/vdso/kernel/vdso_data.h deleted file mode 100644 index 5d077e4..0000000 --- a/rt-thread/components/lwp/vdso/kernel/vdso_data.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-04 rcitach init ver. - */ - -#ifndef _VDSO_KDATA_H -#define _VDSO_KDATA_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern struct vdso_data *vdso_data; - -rt_inline -struct vdso_data *_get_k_vdso_data(void) -{ - return vdso_data; -} -#define get_k_vdso_data _get_k_vdso_data - -rt_inline -void rt_vdso_write_begin(struct vdso_data *vd) -{ - rt_atomic_add(&vd[CS_HRES_COARSE].seq, 1); - rt_atomic_add(&vd[CS_RAW].seq, 1); -} - -rt_inline -void rt_vdso_write_end(struct vdso_data *vd) -{ - rt_atomic_add(&vd[CS_HRES_COARSE].seq, 1); - rt_atomic_add(&vd[CS_RAW].seq, 1); -} - -#ifdef __cplusplus -} -#endif - -#endif /* _VDSO_KDATA_H */ diff --git a/rt-thread/components/lwp/vdso/kernel/vdso_text.S b/rt-thread/components/lwp/vdso/kernel/vdso_text.S deleted file mode 100644 index f9c1f8a..0000000 --- a/rt-thread/components/lwp/vdso/kernel/vdso_text.S +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-04 rcitach init ver. - */ - -#include - - .globl __vdso_text_start, __vdso_text_end - .section .rodata - .balign VDSO_PAGE_SIZE -__vdso_text_start: - .incbin VDSO_PATH - .balign VDSO_PAGE_SIZE -__vdso_text_end: - - .previous diff --git a/rt-thread/components/lwp/vdso/user/SConstruct b/rt-thread/components/lwp/vdso/user/SConstruct deleted file mode 100644 index a7cee11..0000000 --- a/rt-thread/components/lwp/vdso/user/SConstruct +++ /dev/null @@ -1,39 +0,0 @@ -import os -import sys -import subprocess - -arguments = sys.argv[2] -vdso_usr = os.path.dirname(arguments) -vdso_root = os.path.dirname(vdso_usr) - - -EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin' -PREFIX = os.getenv('RTT_CC_PREFIX') or 'aarch64-none-elf-' - -CC = PREFIX + 'gcc' -CXX = PREFIX + 'g++' -CPP = PREFIX + 'cpp' -AS = PREFIX + 'gcc' -AR = PREFIX + 'ar' -LINK = PREFIX + 'gcc' - -DEVICE = ' -march=armv8-a -mtune=cortex-a53 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing' -CXXFLAGS = DEVICE + ' -Wall -fdiagnostics-color=always' -AFLAGS = ' -x assembler-with-cpp' -CFLAGS = DEVICE + ' -Wall -Wno-cpp -std=gnu99 -fdiagnostics-color=always -fPIC -O2' -LFLAGS = DEVICE + ' -Bsymbolic -Wl,--gc-sections,-u,system_vectors -T {path}/vdso.lds'.format(path=vdso_usr) -CFLAGS += " -I {path} -I{path}/user".format(path=vdso_root) - -env = Environment(tools=['gcc', 'link'], - AS = AS, ASFLAGS = AFLAGS, - CC = CC, CFLAGS = CFLAGS, - CXX = CXX, CXXFLAGS = CXXFLAGS, - AR = AR, - LINK = LINK, LINKFLAGS = LFLAGS) -env.PrependENVPath('PATH', EXEC_PATH) - -src = os.path.join(vdso_usr,'vdso_sys.c') -target_name = 'librtos_vdso.so' -target = os.path.join(vdso_usr, "build", target_name) -shared_lib = env.SharedLibrary(target=target, source=src) -env.Default(shared_lib) diff --git a/rt-thread/components/lwp/vdso/user/vdso.lds.S b/rt-thread/components/lwp/vdso/user/vdso.lds.S deleted file mode 100644 index 8b0038e..0000000 --- a/rt-thread/components/lwp/vdso/user/vdso.lds.S +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-04 rcitach init ver. - */ - -#include - -OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") -OUTPUT_ARCH(aarch64) - -SECTIONS -{ - PROVIDE(_vdso_data = . - __VVAR_PAGES * VDSO_PAGE_SIZE); - . = SIZEOF_HEADERS; - - .hash : { *(.hash) } :text - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - - .dynamic : { *(.dynamic) } :text :dynamic - .rela.dyn : ALIGN(8) { *(.rela .rela*) } - - .rodata : { - *(.rodata*) - *(.got) - *(.got.plt) - *(.plt) - *(.plt.*) - *(.iplt) - *(.igot .igot.plt) - } :text - /DISCARD/ : { - *(.data .data.* .sdata*) - *(.bss .sbss .dynbss .dynsbss) - } -} - -PHDRS -{ - text PT_LOAD FLAGS(5) FILEHDR PHDRS; - dynamic PT_DYNAMIC FLAGS(4); -} - -VERSION -{ - LINUX_2.6.39 { - global: - __kernel_clock_gettime; - local: *; - }; -} diff --git a/rt-thread/components/lwp/vdso/user/vdso_sys.c b/rt-thread/components/lwp/vdso/user/vdso_sys.c deleted file mode 100644 index 61da379..0000000 --- a/rt-thread/components/lwp/vdso/user/vdso_sys.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-04 rcitach init ver. - */ - -#include -#include -#include -#include -#include - -#ifndef rt_vdso_cycles_ready -static inline bool rt_vdso_cycles_ready(uint64_t cycles) -{ - return true; -} -#endif - -#ifndef rt_vdso_get_ns -static inline -uint64_t rt_vdso_get_ns(uint64_t cycles, uint64_t last) -{ - return (cycles - last) * NSEC_PER_SEC / __arch_get_hw_frq(); -} -#endif - -static int -__rt_vdso_getcoarse(struct timespec *ts, clockid_t clock, const struct vdso_data *vdns) -{ - const struct vdso_data *vd; - const struct timespec *vdso_ts; - uint32_t seq; - uint64_t sec, last, ns, cycles; - - if (clock != CLOCK_MONOTONIC_RAW) - vd = &vdns[CS_HRES_COARSE]; - else - vd = &vdns[CS_RAW]; - - vdso_ts = &vd->basetime[clock]; - - do { - seq = rt_vdso_read_begin(vd); - cycles = __arch_get_hw_counter(vd->clock_mode, vd); - if (unlikely(!rt_vdso_cycles_ready(cycles))) - return -1; - ns = vdso_ts->tv_nsec; - last = vd->cycle_last; - ns += rt_vdso_get_ns(cycles, last); - sec = vdso_ts->tv_sec; - } while (unlikely(rt_vdso_read_retry(vd, seq))); - - ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); - ts->tv_nsec = ns; - - return 0; -} - -static inline int -__vdso_clock_gettime_common(const struct vdso_data *vd, clockid_t clock, - struct timespec *ts) -{ - u_int32_t msk; - - if (unlikely((u_int32_t) clock >= MAX_CLOCKS)) - return -1; - - msk = 1U << clock; - if (likely(msk & VDSO_REALTIME)) - return __rt_vdso_getcoarse(ts,CLOCK_REALTIME,vd); - else if (msk & VDSO_MONOTIME) - return __rt_vdso_getcoarse(ts,CLOCK_MONOTONIC,vd); - else - return ENOENT; -} - -static __maybe_unused int -rt_vdso_clock_gettime_data(const struct vdso_data *vd, clockid_t clock, - struct timespec *ts) -{ - int ret = 0; - ret = __vdso_clock_gettime_common(vd, clock, ts); - return ret; -} - -int -__kernel_clock_gettime(clockid_t clock, struct timespec *ts) -{ - return rt_vdso_clock_gettime_data(__arch_get_vdso_data(), clock, ts); -} diff --git a/rt-thread/components/lwp/vdso/user/vdso_sys.h b/rt-thread/components/lwp/vdso/user/vdso_sys.h deleted file mode 100644 index ecc7b36..0000000 --- a/rt-thread/components/lwp/vdso/user/vdso_sys.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-04 rcitach init ver. - */ - -#ifndef ASM_VDSO_SYS_H -#define ASM_VDSO_SYS_H - -#include -#include -#include -#include -#include - -#define __always_unused __attribute__((__unused__)) -#define __maybe_unused __attribute__((__unused__)) - -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) - -#define arch_counter_enforce_ordering(val) do { \ - uint64_t tmp, _val = (val); \ - \ - asm volatile( \ - " eor %0, %1, %1\n" \ - " add %0, sp, %0\n" \ - " ldr xzr, [%0]" \ - : "=r" (tmp) : "r" (_val)); \ -} while (0) - -static inline uint64_t __arch_get_hw_counter() -{ - uint64_t res; - - __asm__ volatile("mrs %0, CNTVCT_EL0":"=r"(res)); - - arch_counter_enforce_ordering(res); - return res; -} - -static inline uint64_t __arch_get_hw_frq() -{ - uint64_t res; - - __asm__ volatile("mrs %0, CNTFRQ_EL0":"=r"(res)); - - arch_counter_enforce_ordering(res); - return res; -} - -static inline uint32_t -__iter_div_u64_rem(uint64_t dividend, uint32_t divisor, uint64_t *remainder) -{ - uint32_t ret = 0; - - while (dividend >= divisor) { - /* The following asm() prevents the compiler from - optimising this loop into a modulo operation. */ - __asm__("" : "+rm"(dividend)); - - dividend -= divisor; - ret++; - } - - *remainder = dividend; - - return ret; -} - -#define __RT_STRINGIFY(x...) #x -#define RT_STRINGIFY(x...) __RT_STRINGIFY(x) -#define rt_hw_barrier(cmd, ...) \ - __asm__ volatile (RT_STRINGIFY(cmd) " "RT_STRINGIFY(__VA_ARGS__):::"memory") - -#define rt_hw_isb() rt_hw_barrier(isb) -#define rt_hw_dmb() rt_hw_barrier(dmb, ish) -#define rt_hw_wmb() rt_hw_barrier(dmb, ishst) -#define rt_hw_rmb() rt_hw_barrier(dmb, ishld) -#define rt_hw_dsb() rt_hw_barrier(dsb, ish) - -#ifndef barrier -/* The "volatile" is due to gcc bugs */ -# define barrier() __asm__ __volatile__("": : :"memory") -#endif - -static inline void cpu_relax(void) -{ - __asm__ volatile("yield" ::: "memory"); -} - -#define __READ_ONCE_SIZE \ -({ \ - switch (size) { \ - case 1: *(__u8 *)res = *(volatile __u8 *)p; break; \ - case 2: *(__u16 *)res = *(volatile __u16 *)p; break; \ - case 4: *(__u32 *)res = *(volatile __u32 *)p; break; \ - case 8: *(__u64 *)res = *(volatile __u64 *)p; break; \ - default: \ - barrier(); \ - __builtin_memcpy((void *)res, (const void *)p, size); \ - barrier(); \ - } \ -}) - -static inline -void __read_once_size(const volatile void *p, void *res, int size) -{ - __READ_ONCE_SIZE; -} - -#define __READ_ONCE(x, check) \ -({ \ - union { typeof(x) __val; char __c[1]; } __u; \ - if (check) \ - __read_once_size(&(x), __u.__c, sizeof(x)); \ - smp_read_barrier_depends(); /* Enforce dependency ordering from x */ \ - __u.__val; \ -}) -#define READ_ONCE(x) __READ_ONCE(x, 1) - -extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden"))); -static inline struct vdso_data *__arch_get_vdso_data(void) -{ - return _vdso_data; -} - -static inline uint32_t rt_vdso_read_begin(const struct vdso_data *vd) -{ - uint32_t seq; - - while (unlikely((seq = READ_ONCE(vd->seq)) & 1)) - cpu_relax(); - - rt_hw_rmb(); - return seq; -} - -static inline uint32_t rt_vdso_read_retry(const struct vdso_data *vd, - uint32_t start) -{ - uint32_t seq; - - rt_hw_rmb(); - seq = READ_ONCE(vd->seq); - return seq != start; -} - -#endif diff --git a/rt-thread/components/lwp/vdso/user/xmake.lua b/rt-thread/components/lwp/vdso/user/xmake.lua deleted file mode 100644 index c364481..0000000 --- a/rt-thread/components/lwp/vdso/user/xmake.lua +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-04 rcitach init ver. - */ - -toolchain("aarch64-smart-musleabi") - set_kind("standalone") - - local exec_path = os.getenv("RTT_EXEC_PATH") or "/opt/aarch64-linux-musleabi/bin/" - local sdkdir = exec_path .. "/../" - local incdir = os.curdir() .. "/../include" - local device = '-march=armv8-a -mtune=cortex-a53 -ftree-vectorize -ffast-math -funwind-tables -fno-strict-aliasing' - - set_bindir(exec_path) - set_sdkdir(sdkdir) - - set_toolset("sh", "aarch64-linux-musleabi-gcc") - on_load(function(toolchain) - toolchain:load_cross_toolchain() - toolchain:add("cxflags", device) - toolchain:add("cxflags", "-Wall -Wno-cpp -std=gnu99") - toolchain:add("cxflags", "-fdiagnostics-color=always") - toolchain:add("cxflags", "-O2") - toolchain:add("cxflags", "-I" .. incdir) - - toolchain:add("shflags", device) - toolchain:add("shflags", "-Wl,--gc-sections") - toolchain:add("shflags", "-u,system_vectors") - toolchain:add("shflags", "-T vdso.lds") - end) -toolchain_end() - -set_config("plat", "cross") -set_config("target_os", "rt-smart") -set_config("arch", "aarch64") - -rule("vdso_lds") - set_extensions(".lds.S") - on_buildcmd_file(function (target, batchcmds, sourcefile, opt) - local incdir = os.curdir() .. "/../include" - local targetfile = path.basename(sourcefile) - local prefix = os.getenv("RTT_CC_PREFIX=") or "aarch64-linux-musleabi-" - batchcmds:vrunv(prefix .. "gcc", {"-E", "-P", sourcefile, "-o", targetfile, "-I", incdir}) - end) - -target("rtos_vdso") - set_toolchains("aarch64-smart-musleabi") - add_rules("vdso_lds") - set_kind("shared") - add_files("vdso.lds.S") - add_files("vdso_sys.c") - set_targetdir("build") -target_end() diff --git a/rt-thread/components/lwp/vdso/vdso_config.h b/rt-thread/components/lwp/vdso/vdso_config.h deleted file mode 100644 index ec5d775..0000000 --- a/rt-thread/components/lwp/vdso/vdso_config.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-04 rcitach init ver. - */ - -#ifndef __ASM_VDSO_H -#define __ASM_VDSO_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define __VVAR_PAGES 2 -#define VDSO_PAGE_SHIFT 12 -#define VDSO_PAGE_SIZE (1 << VDSO_PAGE_SHIFT) - -#define BIT_MASK(nr) ((1) << (nr)) - -#ifndef read_barrier_depends -#define read_barrier_depends() do { } while (0) -#endif - -#ifndef smp_read_barrier_depends -#define smp_read_barrier_depends() read_barrier_depends() -#endif - -#define VDSO_PATH "../user/build/librtos_vdso.so" - -#ifdef __cplusplus -} -#endif - -#endif /* __ASM_VDSO_H */ diff --git a/rt-thread/components/lwp/vdso/vdso_datapage.h b/rt-thread/components/lwp/vdso/vdso_datapage.h deleted file mode 100644 index 243af48..0000000 --- a/rt-thread/components/lwp/vdso/vdso_datapage.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-04 rcitach init ver. - */ - -#ifndef _VDSO_DATAPAGE_H -#define _VDSO_DATAPAGE_H - -#include -#include -#include "vdso_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef signed char __s8; -typedef signed short __s16; -typedef signed int __s32; -typedef signed long __s64; - -typedef unsigned char __u8; -typedef unsigned short __u16; -typedef unsigned int __u32; -typedef unsigned long __u64; - -#define MAX_CLOCKS 16 - -#define VDSO_BASES (CLOCK_TAI + 1) -#define VDSO_REALTIME (BIT_MASK(CLOCK_REALTIME) | \ - BIT_MASK(CLOCK_REALTIME_COARSE)) -#define VDSO_MONOTIME (BIT_MASK(CLOCK_MONOTONIC) | \ - BIT_MASK(CLOCK_MONOTONIC_COARSE) | \ - BIT_MASK(CLOCK_MONOTONIC_RAW) | \ - BIT_MASK(CLOCK_BOOTTIME)) - -#define CS_HRES_COARSE 0 -#define CS_RAW 1 -#define CS_BASES (CS_RAW + 1) - -/* 2018-01-30 14:44:50 = RTC_TIME_INIT(2018, 1, 30, 14, 44, 50) */ -#define RTC_VDSOTIME_INIT(year, month, day, hour, minute, second) \ - {.tm_year = year - 1900, .tm_mon = month - 1, .tm_mday = day, .tm_hour = hour, .tm_min = minute, .tm_sec = second} - -#ifndef SOFT_RTC_VDSOTIME_DEFAULT -#define SOFT_RTC_VDSOTIME_DEFAULT RTC_VDSOTIME_INIT(2018, 1, 1, 0, 0 ,0) -#endif - -struct vdso_data { - uint32_t seq; - uint32_t clock_mode; - uint64_t realtime_initdata; - uint64_t cycle_last; - struct timespec basetime[VDSO_BASES]; -}; -typedef struct vdso_data *vdso_data_t; - -#define MSEC_PER_SEC 1000L -#define USEC_PER_MSEC 1000L -#define NSEC_PER_USEC 1000L -#define NSEC_PER_MSEC 1000000L -#define USEC_PER_SEC 1000000L -#define NSEC_PER_SEC 1000000000L -#define FSEC_PER_SEC 1000000000000000LL - -#ifdef __cplusplus -} -#endif - -#endif /* _VDSO_DATAPAGE_H */ diff --git a/rt-thread/components/lwp/vdso/vdso_weak.c b/rt-thread/components/lwp/vdso/vdso_weak.c deleted file mode 100644 index 56f452c..0000000 --- a/rt-thread/components/lwp/vdso/vdso_weak.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2006-2024 RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-07-04 rcitach init ver. - */ - -#include -#include -#include "vdso.h" - -rt_weak int arch_setup_additional_pages(struct rt_lwp *lwp) -{ - return -RT_ERROR; -} - -rt_weak void rt_vdso_update_glob_time(void) -{ - -} diff --git a/rt-thread/components/mm/mm_memblock.c b/rt-thread/components/mm/mm_memblock.c index d3d4e44..77ef4dd 100644 --- a/rt-thread/components/mm/mm_memblock.c +++ b/rt-thread/components/mm/mm_memblock.c @@ -22,12 +22,6 @@ #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) -#ifdef ARCH_CPU_64BIT -#define MIN_BIT 16 -#else -#define MIN_BIT 8 -#endif - #ifndef RT_INIT_MEMORY_REGIONS #define RT_INIT_MEMORY_REGIONS 128 #endif @@ -161,16 +155,16 @@ static rt_err_t _memblock_add_range(struct rt_memblock *memblock, rt_err_t rt_memblock_add_memory(const char *name, rt_size_t start, rt_size_t end, mmblk_flag_t flags) { - LOG_D("add physical address range [0x%.*lx-0x%.*lx) with flag 0x%x" \ - " to overall memory regions\n", MIN_BIT, base, MIN_BIT, base + size, flag); + LOG_D("add physical address range [%p-%p) with flag 0x%x" \ + " to overall memory regions\n", base, base + size, flag); return _memblock_add_range(&mmblk_memory, name, start, end, flags); } rt_err_t rt_memblock_reserve_memory(const char *name, rt_size_t start, rt_size_t end, mmblk_flag_t flags) { - LOG_D("add physical address range %s [0x%.*lx-0x%.*lx) to reserved memory regions\n", - name, MIN_BIT, start, MIN_BIT, end); + LOG_D("add physical address range [%p-%p) to reserved memory regions\n",\ + base, base + size); return _memblock_add_range(&mmblk_reserved, name, start, end, flags); } @@ -353,14 +347,14 @@ void rt_memblock_setup_memory_environment(void) rt_slist_for_each_entry(iter, &(mmblk_memory.reg_list), node) { - LOG_I(" %-*.s [0x%.*lx, 0x%.*lx]", RT_NAME_MAX, iter->memreg.name, MIN_BIT, iter->memreg.start, MIN_BIT, iter->memreg.end); + LOG_I(" %-*.s [%p, %p]", RT_NAME_MAX, iter->memreg.name, iter->memreg.start, iter->memreg.end); } LOG_I("Reserved memory:"); rt_slist_for_each_entry(iter, &(mmblk_reserved.reg_list), node) { - LOG_I(" %-*.s [0x%.*lx, 0x%.*lx]", RT_NAME_MAX, iter->memreg.name, MIN_BIT, iter->memreg.start, MIN_BIT, iter->memreg.end); + LOG_I(" %-*.s [%p, %p]", RT_NAME_MAX, iter->memreg.name, iter->memreg.start, iter->memreg.end); if (iter->flags != MEMBLOCK_NONE) { diff --git a/rt-thread/components/net/at/at_socket/at_socket.c b/rt-thread/components/net/at/at_socket/at_socket.c index 4695d3c..2beed44 100644 --- a/rt-thread/components/net/at/at_socket/at_socket.c +++ b/rt-thread/components/net/at/at_socket/at_socket.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -56,8 +56,6 @@ typedef enum { static void at_connect_notice_cb(struct at_socket *sock, at_socket_evt_t event, const char *buff, size_t bfsz); #endif -static rt_mutex_t at_slock = RT_NULL; - /* the global of sockets list */ static rt_slist_t _socket_list = RT_SLIST_OBJECT_INIT(_socket_list); @@ -319,67 +317,37 @@ static void at_do_event_clean(struct at_socket *sock, at_event_t event) } } -static int free_socket(struct at_socket *sock) +static int alloc_empty_socket(rt_slist_t *l) { - if (at_slock == RT_NULL) + rt_base_t level; + rt_slist_t *node = RT_NULL; + rt_slist_t *pre_node = &_socket_list; + struct at_socket *at_sock = RT_NULL; + int idx = 0; + + level = rt_hw_interrupt_disable(); + + rt_slist_init(l); + + rt_slist_for_each(node, &_socket_list) { - /* create AT socket lock */ - at_slock = rt_mutex_create("at_slock", RT_IPC_FLAG_PRIO); - if (at_slock == RT_NULL) - { - LOG_E("No memory for socket allocation lock!"); - return RT_NULL; - } + at_sock = rt_slist_entry(node, struct at_socket, list); + if(at_sock && at_sock->socket != idx) + break; + idx++; + pre_node = node; } - rt_mutex_take(at_slock, RT_WAITING_FOREVER); - if (sock->recv_notice) - { - rt_sem_delete(sock->recv_notice); - } + rt_slist_insert(pre_node, l); - if (sock->recv_lock) - { - rt_mutex_delete(sock->recv_lock); - } + rt_hw_interrupt_enable(level); - if (!rt_slist_isempty(&sock->recvpkt_list)) - { - at_recvpkt_all_delete(&sock->recvpkt_list); - } - - /* delect socket from socket list */ - { - rt_base_t level; - rt_slist_t *node = RT_NULL; - struct at_socket *at_sock = RT_NULL; - - level = rt_hw_interrupt_disable(); - - rt_slist_for_each(node, &_socket_list) - { - at_sock = rt_slist_entry(node, struct at_socket, list); - if (at_sock && sock->socket == at_sock->socket) - { - if (at_sock->magic == AT_SOCKET_MAGIC) - { - rt_slist_remove(&_socket_list, &at_sock->list); - break; - } - } - } - - rt_hw_interrupt_enable(level); - } - - rt_memset(sock, RT_NULL, sizeof(struct at_socket)); - rt_mutex_release(at_slock); - return 0; + return idx; } static struct at_socket *alloc_socket_by_device(struct at_device *device, enum at_socket_type type) { - rt_base_t level; + static rt_mutex_t at_slock = RT_NULL; struct at_socket *sock = RT_NULL; char name[RT_NAME_MAX] = {0}; int idx = 0; @@ -404,19 +372,18 @@ static struct at_socket *alloc_socket_by_device(struct at_device *device, enum a } else { - for (idx = 0; idx < device->class->socket_num && device->sockets[idx].magic == AT_SOCKET_MAGIC; idx++); + for (idx = 0; idx < device->class->socket_num && device->sockets[idx].magic; idx++); } /* can't find an empty protocol family entry */ if (idx < 0 || idx >= device->class->socket_num) { - LOG_E("can't find an empty protocol family entry."); goto __err; } sock = &(device->sockets[idx]); /* the socket descriptor is the number of sockte lists */ - sock->socket = idx; + sock->socket = alloc_empty_socket(&(sock->list)); /* the socket operations is the specify operations of the device */ sock->ops = device->class->socket_ops; /* the user-data is the at device socket descriptor */ @@ -427,32 +394,25 @@ static struct at_socket *alloc_socket_by_device(struct at_device *device, enum a sock->rcvevent = RT_NULL; sock->sendevent = RT_NULL; sock->errevent = RT_NULL; - - rt_slist_init(&(sock->list)); - level = rt_hw_interrupt_disable(); - rt_slist_insert(&_socket_list, &(sock->list)); - rt_hw_interrupt_enable(level); - rt_slist_init(&sock->recvpkt_list); #ifdef SAL_USING_POSIX rt_wqueue_init(&sock->wait_head); #endif rt_snprintf(name, RT_NAME_MAX, "%s%d", "at_skt", idx); - /* create AT socket receive semaphore */ + /* create AT socket receive mailbox */ if ((sock->recv_notice = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO)) == RT_NULL) { LOG_E("No memory socket receive notic semaphore create."); goto __err; } - /* set AT socket receive semaphore 'max_value' to 1 */ - rt_sem_control(sock->recv_notice, RT_IPC_CMD_SET_VLIMIT, (void *)1); rt_snprintf(name, RT_NAME_MAX, "%s%d", "at_skt", idx); /* create AT socket receive ring buffer lock */ if((sock->recv_lock = rt_mutex_create(name, RT_IPC_FLAG_PRIO)) == RT_NULL) { LOG_E("No memory for socket receive mutex create."); + rt_sem_delete(sock->recv_notice); goto __err; } @@ -461,10 +421,6 @@ static struct at_socket *alloc_socket_by_device(struct at_device *device, enum a __err: rt_mutex_release(at_slock); - if(sock != RT_NULL) - { - free_socket(sock); - } return RT_NULL; } @@ -507,13 +463,9 @@ int at_socket(int domain, int type, int protocol) enum at_socket_type socket_type; /* check socket family protocol */ - if(domain != AF_INET && domain != AF_AT) - { - rt_set_errno(EAFNOSUPPORT); - return -1; - } + RT_ASSERT(domain == AF_AT || domain == AF_INET); - /*TODO check protocol*/ + //TODO check protocol switch(type) { @@ -527,7 +479,6 @@ int at_socket(int domain, int type, int protocol) default : LOG_E("Don't support socket type (%d)!", type); - rt_set_errno(EPROTOTYPE); return -1; } @@ -535,8 +486,6 @@ int at_socket(int domain, int type, int protocol) sock = alloc_socket(socket_type); if (sock == RT_NULL) { - LOG_E("Failed to allocate socket"); - rt_set_errno(EIO); return -1; } sock->type = socket_type; @@ -552,6 +501,52 @@ int at_socket(int domain, int type, int protocol) return sock->socket; } +static int free_socket(struct at_socket *sock) +{ + if (sock->recv_notice) + { + rt_sem_delete(sock->recv_notice); + } + + if (sock->recv_lock) + { + rt_mutex_delete(sock->recv_lock); + } + + if (!rt_slist_isempty(&sock->recvpkt_list)) + { + at_recvpkt_all_delete(&sock->recvpkt_list); + } + + /* delect socket from socket list */ + { + rt_base_t level; + rt_slist_t *node = RT_NULL; + struct at_socket *at_sock = RT_NULL; + + level = rt_hw_interrupt_disable(); + + rt_slist_for_each(node, &_socket_list) + { + at_sock = rt_slist_entry(node, struct at_socket, list); + if (at_sock && sock->socket == at_sock->socket) + { + if (at_sock->magic == AT_SOCKET_MAGIC) + { + rt_slist_remove(&_socket_list, &at_sock->list); + break; + } + } + } + + rt_hw_interrupt_enable(level); + } + + rt_memset(sock, 0x00, sizeof(struct at_socket)); + + return 0; +} + int at_closesocket(int socket) { struct at_socket *sock = RT_NULL; @@ -563,7 +558,6 @@ int at_closesocket(int socket) sock = at_get_socket(socket); if (sock == RT_NULL) { - rt_set_errno(ENXIO); return -1; } @@ -577,7 +571,6 @@ int at_closesocket(int socket) if (sock->ops->at_closesocket(sock) != 0) { free_socket(sock); - rt_set_errno(EIO); return -1; } } @@ -594,7 +587,6 @@ int at_shutdown(int socket, int how) sock = at_get_socket(socket); if (sock == RT_NULL) { - rt_set_errno(ENXIO); return -1; } @@ -608,7 +600,6 @@ int at_shutdown(int socket, int how) if (sock->ops->at_closesocket(sock) != 0) { free_socket(sock); - rt_set_errno(EIO); return -1; } } @@ -663,16 +654,9 @@ int at_bind(int socket, const struct sockaddr *name, socklen_t namelen) ip_addr_t input_ipaddr, local_ipaddr; uint16_t port = 0; - if (name == NULL || namelen == 0) - { - rt_set_errno(EINVAL); - return -1; - } - sock = at_get_socket(socket); if (sock == RT_NULL) { - rt_set_errno(ENXIO); return -1; } @@ -693,8 +677,6 @@ int at_bind(int socket, const struct sockaddr *name, socklen_t namelen) /* close old socket */ if (at_closesocket(socket) < 0) { - free_socket(sock); - rt_set_errno(EIO); return -1; } @@ -702,7 +684,6 @@ int at_bind(int socket, const struct sockaddr *name, socklen_t namelen) new_device = at_device_get_by_ipaddr(&input_ipaddr); if (new_device == RT_NULL) { - rt_set_errno(EHOSTUNREACH); return -1; } @@ -710,7 +691,6 @@ int at_bind(int socket, const struct sockaddr *name, socklen_t namelen) new_sock = alloc_socket_by_device(new_device, type); if (new_sock == RT_NULL) { - rt_set_errno(EIO); return -1; } new_sock->type = type; @@ -759,7 +739,7 @@ static void at_connect_notice_cb(struct at_socket *sock, at_socket_evt_t event, } new_sock = at_get_socket(new_socket); new_sock->state = AT_SOCKET_CONNECT; - rt_sscanf(buff, "SOCKET:%d", &base_socket); + sscanf(buff, "SOCKET:%d", &base_socket); LOG_D("ACCEPT BASE SOCKET: %d", base_socket); new_sock->user_data = (void *)base_socket; @@ -856,21 +836,18 @@ int at_listen(int socket, int backlog) sock = at_get_socket(socket); if (sock == RT_NULL) { - rt_set_errno(ENXIO); return -1; } if (sock->state != AT_SOCKET_OPEN) { LOG_E("Socket(%d) connect state is %d.", sock->socket, sock->state); - rt_set_errno(ENETUNREACH); result = -1; goto __exit; } if (sock->ops->at_listen(sock, backlog) < 0) { - rt_set_errno(EIO); result = -1; goto __exit; } @@ -879,6 +856,7 @@ int at_listen(int socket, int backlog) sock->state = AT_SOCKET_LISTEN; __exit: + if (result < 0) { at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); @@ -896,23 +874,15 @@ int at_connect(int socket, const struct sockaddr *name, socklen_t namelen) char ipstr[16] = { 0 }; int result = 0; - if (name == RT_NULL || namelen == 0) - { - rt_set_errno(EINVAL); - return -1; - } - sock = at_get_socket(socket); if (sock == RT_NULL) { - rt_set_errno(ENXIO); return -1; } if (sock->state != AT_SOCKET_OPEN) { LOG_E("Socket(%d) connect state is %d.", sock->socket, sock->state); - rt_set_errno(EPERM); result = -1; goto __exit; } @@ -923,7 +893,6 @@ int at_connect(int socket, const struct sockaddr *name, socklen_t namelen) if (sock->ops->at_connect(sock, ipstr, remote_port, sock->type, RT_TRUE) < 0) { - rt_set_errno(EIO); result = -1; goto __exit; } @@ -931,6 +900,7 @@ int at_connect(int socket, const struct sockaddr *name, socklen_t namelen) sock->state = AT_SOCKET_CONNECT; __exit: + if (result < 0) { at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); @@ -957,22 +927,20 @@ int at_accept(int socket, struct sockaddr *name, socklen_t *namelen) sock = at_get_socket(socket); if (sock == RT_NULL) { - rt_set_errno(ENXIO); return -1; } if (sock->state != AT_SOCKET_LISTEN) { LOG_E("Socket(%d) connect state is %d.", sock->socket, sock->state); - rt_set_errno(EIO); result = -1; goto __exit; } /* wait the receive semaphore, waiting for info */ - if (rt_sem_take(sock->recv_notice, RT_WAITING_FOREVER) != RT_EOK) + if (rt_sem_take(sock->recv_notice, RT_WAITING_FOREVER) < 0) { - rt_set_errno(EAGAIN); + errno = EAGAIN; result = -1; goto __exit; } @@ -985,7 +953,7 @@ int at_accept(int socket, struct sockaddr *name, socklen_t *namelen) at_do_event_changes(sock, AT_EVENT_RECV, RT_FALSE); } - rt_sscanf(&receive_buff[0], "SOCKET:%d", &new_socket); + sscanf(&receive_buff[0], "SOCKET:%d", &new_socket); new_sock = at_get_socket(new_socket); ip4_addr_set_any(&remote_addr); ipaddr_port_to_socketaddr(name, &remote_addr, &remote_port); @@ -1010,61 +978,44 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f if (mem == RT_NULL || len == 0) { /* if the requested number of bytes to receive from a stream socket was 0. */ - rt_set_errno(EFAULT); - return -1; + return 0; } sock = at_get_socket(socket); if (sock == RT_NULL) { - rt_set_errno(ENXIO); return -1; } /* if the socket type is UDP, need to connect socket first */ - if (sock->type == AT_SOCKET_UDP) + if (from && sock->type == AT_SOCKET_UDP && sock->state == AT_SOCKET_OPEN) { - if (from == RT_NULL || fromlen == 0) + ip_addr_t remote_addr; + uint16_t remote_port = 0; + char ipstr[16] = { 0 }; + + socketaddr_to_ipaddr_port(from, &remote_addr, &remote_port); + ipaddr_to_ipstr(from, ipstr); + + if (sock->ops->at_connect(sock, ipstr, remote_port, sock->type, RT_TRUE) < 0) { - rt_set_errno(EFAULT); - return -1; - } - - if(sock->state == AT_SOCKET_CONNECT && rt_memcmp(&sock->last_udp_adr, from, sizeof(struct sockaddr)) != 0) - { - if (sock->ops->at_closesocket(sock) != 0) - { - free_socket(sock); - rt_set_errno(EIO); - goto __exit; - } - sock->state = AT_SOCKET_OPEN; - } - - if (sock->state == AT_SOCKET_OPEN) - { - ip_addr_t remote_addr; - uint16_t remote_port = 0; - char ipstr[16] = { 0 }; - - socketaddr_to_ipaddr_port(from, &remote_addr, &remote_port); - ipaddr_to_ipstr(from, ipstr); - - if (sock->ops->at_connect(sock, ipstr, remote_port, sock->type, RT_TRUE) < 0) - { - at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); - rt_set_errno(EIO); - /* socket shutdown */ - goto __exit; - } - - rt_memcpy(&sock->last_udp_adr, from, sizeof(struct sockaddr)); - sock->state = AT_SOCKET_CONNECT; + at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); + /* socket shutdown */ + return 0; } + sock->state = AT_SOCKET_CONNECT; } while (1) { + if (sock->state == AT_SOCKET_CLOSED) + { + /* socket passively closed, receive function return 0 */ + result = 0; + break; + } + + rt_sem_control(sock->recv_notice, RT_IPC_CMD_RESET, RT_NULL); /* receive packet list last transmission of remaining data */ rt_mutex_take(sock->recv_lock, RT_WAITING_FOREVER); recv_len = at_recvpkt_get(&(sock->recvpkt_list), (char *)mem, len); @@ -1075,22 +1026,16 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f { at_do_event_clean(sock, AT_EVENT_RECV); } + errno = 0; result = recv_len; - goto __exit; - } - - if (sock->state == AT_SOCKET_CLOSED) - { - /* socket passively closed, receive function return 0 */ - result = 0; - goto __exit; + break; } if (flags & MSG_DONTWAIT) { - rt_set_errno(EAGAIN); + errno = EAGAIN; result = -1; - goto __exit; + break; } /* set AT socket receive timeout */ @@ -1105,13 +1050,12 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f if (rt_sem_take(sock->recv_notice, timeout) != RT_EOK) { LOG_D("AT socket (%d) receive timeout (%d)!", socket, timeout); - rt_set_errno(EAGAIN); + errno = EAGAIN; result = -1; - goto __exit; + break; } } -__exit: if (result <= 0) { at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); @@ -1133,14 +1077,12 @@ int at_sendto(int socket, const void *data, size_t size, int flags, const struct if (data == RT_NULL || size == 0) { LOG_E("AT sendto input data or size error!"); - rt_set_errno(EFAULT); return -1; } sock = at_get_socket(socket); if (sock == RT_NULL) { - rt_set_errno(ENXIO); return -1; } @@ -1149,47 +1091,25 @@ int at_sendto(int socket, const void *data, size_t size, int flags, const struct case AT_SOCKET_TCP: if (sock->state == AT_SOCKET_CLOSED) { - /* socket passively closed, transmit function return 0 */ result = 0; goto __exit; } - else if (sock->state != AT_SOCKET_CONNECT) + else if (sock->state != AT_SOCKET_CONNECT && sock->state != AT_SOCKET_OPEN) { LOG_E("send data error, current socket (%d) state (%d) is error.", socket, sock->state); - rt_set_errno(ENETUNREACH); result = -1; goto __exit; } if ((len = sock->ops->at_send(sock, (const char *) data, size, sock->type)) < 0) { - rt_set_errno(EIO); result = -1; goto __exit; } break; case AT_SOCKET_UDP: - if (to == RT_NULL || tolen == 0) - { - rt_set_errno(EFAULT); - result = -1; - goto __exit; - } - - /* Inconsistent with the last UDP sending address, reconnect to a new address */ - if(sock->state == AT_SOCKET_CONNECT && rt_memcmp(&sock->last_udp_adr, to, sizeof(struct sockaddr)) != 0) - { - if (sock->ops->at_closesocket(sock) != 0) - { - free_socket(sock); - rt_set_errno(EIO); - goto __exit; - } - sock->state = AT_SOCKET_OPEN; - } - - if (sock->state == AT_SOCKET_OPEN) + if (to && sock->state == AT_SOCKET_OPEN) { ip_addr_t remote_addr; uint16_t remote_port = 0; @@ -1200,18 +1120,14 @@ int at_sendto(int socket, const void *data, size_t size, int flags, const struct if (sock->ops->at_connect(sock, ipstr, remote_port, sock->type, RT_TRUE) < 0) { - rt_set_errno(EIO); result = -1; goto __exit; } - - rt_memcpy(&sock->last_udp_adr, to, sizeof(struct sockaddr)); sock->state = AT_SOCKET_CONNECT; } if ((len = sock->ops->at_send(sock, (char *) data, size, sock->type)) < 0) { - rt_set_errno(EIO); result = -1; goto __exit; } @@ -1219,12 +1135,12 @@ int at_sendto(int socket, const void *data, size_t size, int flags, const struct default: LOG_E("Socket (%d) type %d is not support.", socket, sock->type); - rt_set_errno(EPERM); result = -1; goto __exit; } __exit: + if (result < 0) { at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); @@ -1250,14 +1166,12 @@ int at_getsockopt(int socket, int level, int optname, void *optval, socklen_t *o if (optval == RT_NULL || optlen == RT_NULL) { LOG_E("AT getsocketopt input option value or option length error!"); - rt_set_errno(EFAULT); return -1; } sock = at_get_socket(socket); if (sock == RT_NULL) { - rt_set_errno(ENXIO); return -1; } @@ -1280,14 +1194,12 @@ int at_getsockopt(int socket, int level, int optname, void *optval, socklen_t *o default: LOG_E("AT socket (%d) not support option name : %d.", socket, optname); - rt_set_errno(EPERM); return -1; } break; default: LOG_E("AT socket (%d) not support option level : %d.", socket, level); - rt_set_errno(EPERM); return -1; } @@ -1301,14 +1213,12 @@ int at_setsockopt(int socket, int level, int optname, const void *optval, sockle if (optval == RT_NULL) { LOG_E("AT setsockopt input option value error!"); - rt_set_errno(EFAULT); return -1; } sock = at_get_socket(socket); if (sock == RT_NULL) { - rt_set_errno(ENXIO); return -1; } @@ -1329,7 +1239,6 @@ int at_setsockopt(int socket, int level, int optname, const void *optval, sockle default: LOG_E("AT socket (%d) not support option name : %d.", socket, optname); - rt_set_errno(EPERM); return -1; } break; @@ -1342,7 +1251,6 @@ int at_setsockopt(int socket, int level, int optname, const void *optval, sockle break; default: LOG_E("AT socket (%d) not support option level : %d.", socket, level); - rt_set_errno(EPERM); return -1; } @@ -1386,87 +1294,18 @@ static uint32_t ipstr_to_u32(char *ipstr) return *(uint32_t *) ipBytes; } -/** - * @brief resolves a domain name via AT device and returns its IP address. - * @note function uses static global mutex internally, which will cause multiple AT devices to block and wait while performing DNS resolution. - * @param name Pointer to a string containing the domain name. - * @param addr Pointer to a structure where the IP address information is stored. - * @return int Returns 0 on success or -1/-2 on failure - * -1: domain failed - * -2: HOST_NOT_FOUND - */ -static int _gethostbyname_by_device(const char *name, ip_addr_t *addr) -{ - static rt_mutex_t at_dlock = RT_NULL; - - struct at_device *device = RT_NULL; - char ipstr[16] = { 0 }; - size_t idx = 0; - - device = at_device_get_first_initialized(); - if (device == RT_NULL) - { - return -1; - } - - if (!netdev_is_link_up(device->netdev)) - { - return -1; - } - - for (idx = 0; idx < strlen(name) && !isalpha(name[idx]); idx++); - - if (idx < strlen(name)) - { - if (at_dlock == RT_NULL) - { - at_dlock = rt_mutex_create("at_dlock", RT_IPC_FLAG_PRIO); - if (at_dlock == RT_NULL) - { - return -1; - } - } - - rt_mutex_take(at_dlock, RT_WAITING_FOREVER); - if (device->class->socket_ops->at_domain_resolve(name, ipstr) < 0) - { - rt_mutex_release(at_dlock); - return -2; - } - rt_mutex_release(at_dlock); - } - else - { - strncpy(ipstr, name, strlen(name)); - } - -#if NETDEV_IPV4 && NETDEV_IPV6 - addr.type = IPADDR_TYPE_V4; - if (inet_aton(ipstr, addr) == 0) - { - return -1; - } -#elif NETDEV_IPV4 - if (inet_aton(ipstr, addr) == 0) - { - return -1; - } -#elif NETDEV_IPV6 -#error "not support IPV6." -#endif /* NETDEV_IPV4 && NETDEV_IPV6 */ - - return 0; -} - struct hostent *at_gethostbyname(const char *name) { + struct at_device *device = RT_NULL; ip_addr_t addr = {0}; + char ipstr[16] = { 0 }; /* buffer variables for at_gethostbyname() */ static struct hostent s_hostent; static char *s_aliases; static ip_addr_t s_hostent_addr; static ip_addr_t *s_phostent_addr[2]; static char s_hostname[DNS_MAX_NAME_LENGTH + 1]; + size_t idx = 0; if (name == RT_NULL) { @@ -1474,25 +1313,43 @@ struct hostent *at_gethostbyname(const char *name) return RT_NULL; } - if (strlen(name) > DNS_MAX_NAME_LENGTH) + device = at_device_get_first_initialized(); + if (device == RT_NULL) { return RT_NULL; } - if (_gethostbyname_by_device(name, &addr) != 0) + for (idx = 0; idx < strlen(name) && !isalpha(name[idx]); idx++); + + if (idx < strlen(name)) { - return RT_NULL; + if (device->class->socket_ops->at_domain_resolve(name, ipstr) < 0) + { + return RT_NULL; + } } + else + { + strncpy(ipstr, name, strlen(name)); + } + +#if NETDEV_IPV4 && NETDEV_IPV6 + addr.u_addr.ip4.addr = ipstr_to_u32(ipstr); + addr.type = IPADDR_TYPE_V4; +#elif NETDEV_IPV4 + addr.addr = ipstr_to_u32(ipstr); +#elif NETDEV_IPV6 +#error "not support IPV6." +#endif /* NETDEV_IPV4 && NETDEV_IPV6 */ /* fill hostent structure */ s_hostent_addr = addr; s_phostent_addr[0] = &s_hostent_addr; s_phostent_addr[1] = RT_NULL; - strncpy(s_hostname, name, strlen(name)); - s_hostname[strlen(name)] = 0; - s_aliases = RT_NULL; - + strncpy(s_hostname, name, DNS_MAX_NAME_LENGTH); + s_hostname[DNS_MAX_NAME_LENGTH] = 0; s_hostent.h_name = s_hostname; + s_aliases = RT_NULL; s_hostent.h_aliases = &s_aliases; s_hostent.h_addrtype = AF_AT; s_hostent.h_length = sizeof(ip_addr_t); @@ -1501,89 +1358,17 @@ struct hostent *at_gethostbyname(const char *name) return &s_hostent; } -int at_gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) -{ - struct gethostbyname_r_helper - { - ip_addr_t *addr_list[2]; - ip_addr_t addr; - char *aliases; - }; - - char *hostname = RT_NULL; - int lh_errno = 0; - int domain_err = 0; - size_t namelen = 0; - struct gethostbyname_r_helper *h = RT_NULL; - - if (h_errnop == RT_NULL) - { - h_errnop = &lh_errno; - } - - if ((name == RT_NULL) || (ret == RT_NULL) || (buf == RT_NULL)) - { - *h_errnop = EINVAL; - return -1; - } - - if (result == RT_NULL) - { - *h_errnop = EINVAL; - return -1; - } - - *result = RT_NULL; - - namelen = strlen(name); - if (buflen < (sizeof(struct gethostbyname_r_helper) + (namelen + 1))) - { - *h_errnop = ERANGE; - return -1; - } - - h = (struct gethostbyname_r_helper *)buf; - hostname = ((char *)h) + sizeof(struct gethostbyname_r_helper); - - domain_err = _gethostbyname_by_device(name, &h->addr); - if (domain_err != 0) - { - if (domain_err == -2) - { - *h_errnop = HOST_NOT_FOUND; - } - - *h_errnop = NO_DATA; - return -1; - } - - rt_memcpy(hostname, name, namelen); - hostname[namelen] = 0; - - h->addr_list[0] = &h->addr; - h->addr_list[1] = NULL; - h->aliases = NULL; - - ret->h_name = hostname; - ret->h_aliases = &h->aliases; - ret->h_addrtype = AF_INET; - ret->h_length = sizeof(ip_addr_t); - ret->h_addr_list = (char **)&h->addr_list; - - *result = ret; - return 0; -} - int at_getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { int port_nr = 0; - ip_addr_t addr = {0}; + ip_addr_t addr; struct addrinfo *ai; struct sockaddr_storage *sa; size_t total_size = 0; size_t namelen = 0; int ai_family = 0; + struct at_device *device = RT_NULL; if (res == RT_NULL) { @@ -1591,6 +1376,12 @@ int at_getaddrinfo(const char *nodename, const char *servname, } *res = RT_NULL; + device = at_device_get_first_initialized(); + if (device == RT_NULL) + { + return EAI_FAIL; + } + if ((nodename == RT_NULL) && (servname == RT_NULL)) { return EAI_NONAME; @@ -1604,10 +1395,6 @@ int at_getaddrinfo(const char *nodename, const char *servname, return EAI_FAMILY; } } - else - { - ai_family = AF_UNSPEC; - } if (servname != RT_NULL) { @@ -1624,63 +1411,74 @@ int at_getaddrinfo(const char *nodename, const char *servname, /* service location specified, try to resolve */ if ((hints != RT_NULL) && (hints->ai_flags & AI_NUMERICHOST)) { - if (ai_family == AF_AT || ai_family == AF_INET) - { - return EAI_NONAME; - } - /* no DNS lookup, just parse for an address string */ if (!inet_aton(nodename, &addr)) { return EAI_NONAME; } + if (ai_family == AF_AT || ai_family == AF_INET) + { + return EAI_NONAME; + } } else { - int domain_err = 0; - domain_err = _gethostbyname_by_device(nodename, &addr); - if (domain_err != 0) - { - if (domain_err == -2) - { - return HOST_NOT_FOUND; - } + char ip_str[16] = { 0 }; + size_t idx = 0; - return NO_DATA; + for (idx = 0; idx < strlen(nodename) && !isalpha(nodename[idx]); idx++); + + if(idx < strlen(nodename)) + { + if (device->class->socket_ops->at_domain_resolve((char *) nodename, ip_str) != 0) + { + return EAI_FAIL; + } } + else + { + strncpy(ip_str, nodename, strlen(nodename)); + } + + #if NETDEV_IPV4 && NETDEV_IPV6 + addr.type = IPADDR_TYPE_V4; + if ((addr.u_addr.ip4.addr = ipstr_to_u32(ip_str)) == 0) + { + return EAI_FAIL; + } + #elif NETDEV_IPV4 + addr.addr = ipstr_to_u32(ip_str); + #elif NETDEV_IPV6 + #error "not support IPV6." + #endif /* NETDEV_IPV4 && NETDEV_IPV6 */ } } else { - /* service location specified, use loopback address */ - inet_aton("127.0.0.1", &addr); + /* to do service location specified, use loopback address */ } total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_storage); if (nodename != RT_NULL) { namelen = strlen(nodename); - if (namelen == 0 || namelen > DNS_MAX_NAME_LENGTH) + if (namelen > DNS_MAX_NAME_LENGTH) { /* invalid name length */ return EAI_FAIL; } - + RT_ASSERT(total_size + namelen + 1 > total_size); total_size += namelen + 1; } /* If this fails, please report to lwip-devel! :-) */ - if (total_size > sizeof(struct addrinfo) + sizeof(struct sockaddr_storage) + DNS_MAX_NAME_LENGTH + 1) - { - return EAI_FAIL; - } - + RT_ASSERT(total_size <= sizeof(struct addrinfo) + sizeof(struct sockaddr_storage) + DNS_MAX_NAME_LENGTH + 1); ai = (struct addrinfo *) rt_malloc(total_size); if (ai == RT_NULL) { return EAI_MEMORY; } - rt_memset(ai, RT_NULL, total_size); + rt_memset(ai, 0, total_size); /* cast through void* to get rid of alignment warnings */ sa = (struct sockaddr_storage *) (void *) ((uint8_t *) ai + sizeof(struct addrinfo)); struct sockaddr_in *sa4 = (struct sockaddr_in *) sa; diff --git a/rt-thread/components/net/at/at_socket/at_socket.h b/rt-thread/components/net/at/at_socket/at_socket.h index ed8b5dd..97c158f 100644 --- a/rt-thread/components/net/at/at_socket/at_socket.h +++ b/rt-thread/components/net/at/at_socket/at_socket.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -138,8 +138,6 @@ struct at_socket uint16_t sendevent; /* error happened for this socket, set by event_callback() */ uint16_t errevent; - /* Last UDP connect address */ - struct sockaddr last_udp_adr; #ifdef SAL_USING_POSIX rt_wqueue_t wait_head; @@ -168,7 +166,6 @@ int at_recv(int socket, void *mem, size_t len, int flags); int at_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen); int at_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen); struct hostent *at_gethostbyname(const char *name); -int at_gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop); int at_getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res); void at_freeaddrinfo(struct addrinfo *ai); diff --git a/rt-thread/components/net/at/include/at.h b/rt-thread/components/net/at/include/at.h index bfd4550..2d9e7e5 100644 --- a/rt-thread/components/net/at/include/at.h +++ b/rt-thread/components/net/at/include/at.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2025, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -14,7 +14,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/rt-thread/components/net/at/src/at_client.c b/rt-thread/components/net/at/src/at_client.c index 81879d8..5d665fe 100644 --- a/rt-thread/components/net/at/src/at_client.c +++ b/rt-thread/components/net/at/src/at_client.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2025, RT-Thread Development Team + * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -10,7 +10,6 @@ * 2018-08-17 chenyong multiple client support * 2021-03-17 Meco Man fix a buf of leaking memory * 2021-07-14 Sszl fix a buf of leaking memory - * 2025-01-02 dongly support SERIAL_V2 */ #include @@ -961,10 +960,6 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu RT_ASSERT(client->device->type == RT_Device_Class_Char); rt_device_set_rx_indicate(client->device, at_client_rx_ind); - -#ifdef RT_USING_SERIAL_V2 - open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_RX_NON_BLOCKING); -#else /* using DMA mode first */ open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX); /* using interrupt mode when DMA mode not supported */ @@ -972,7 +967,6 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz, rt_size_t send_bu { open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX); } -#endif /* RT_USING_SERIAL_V2 */ RT_ASSERT(open_result == RT_EOK); } else diff --git a/rt-thread/components/net/at/src/at_server.c b/rt-thread/components/net/at/src/at_server.c index 7817372..de67001 100644 --- a/rt-thread/components/net/at/src/at_server.c +++ b/rt-thread/components/net/at/src/at_server.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2025, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -7,7 +7,6 @@ * Date Author Notes * 2018-03-30 chenyong first version * 2018-04-14 chenyong modify parse arguments - * 2025-01-02 dongly support SERIAL_V2 */ #include @@ -566,10 +565,6 @@ int at_server_init(void) RT_ASSERT(at_server_local->device->type == RT_Device_Class_Char); rt_device_set_rx_indicate(at_server_local->device, at_rx_ind); - -#ifdef RT_USING_SERIAL_V2 - open_result = rt_device_open(client->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_RX_NON_BLOCKING); -#else /* using DMA mode first */ open_result = rt_device_open(at_server_local->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX); /* using interrupt mode when DMA mode not supported */ @@ -577,7 +572,6 @@ int at_server_init(void) { open_result = rt_device_open(at_server_local->device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX); } -#endif /* RT_USING_SERIAL_V2 */ RT_ASSERT(open_result == RT_EOK); } else diff --git a/rt-thread/components/net/lwip-dhcpd/dhcp_server_raw.c b/rt-thread/components/net/lwip-dhcpd/dhcp_server_raw.c index 9098cbb..6273600 100644 --- a/rt-thread/components/net/lwip-dhcpd/dhcp_server_raw.c +++ b/rt-thread/components/net/lwip-dhcpd/dhcp_server_raw.c @@ -736,7 +736,7 @@ void dhcpd_start(const char *netif_name) DEBUG_PRINTF("ip_start: [%s]\r\n", str_tmp); sprintf(p, "%d", DHCPD_CLIENT_IP_MAX); ip4addr_aton(str_tmp, &ip_end); - DEBUG_PRINTF("ip_end: [%s]\r\n", str_tmp); + DEBUG_PRINTF("ip_start: [%s]\r\n", str_tmp); res = dhcp_server_start(netif, &ip_start, &ip_end); if (res != 0) diff --git a/rt-thread/components/net/lwip/Kconfig b/rt-thread/components/net/lwip/Kconfig index 48f2a1d..883c14a 100644 --- a/rt-thread/components/net/lwip/Kconfig +++ b/rt-thread/components/net/lwip/Kconfig @@ -281,10 +281,6 @@ if RT_USING_LWIP endif endif - config RT_LWIP_ENABLE_USER_HOOKS - bool "Enable user-defined LWIP hooks" - default n - menuconfig RT_LWIP_DEBUG bool "Enable lwIP Debugging Options" default n diff --git a/rt-thread/components/net/lwip/lwip-2.1.2/src/core/dns.c b/rt-thread/components/net/lwip/lwip-2.1.2/src/core/dns.c index e6009d9..c688cb2 100644 --- a/rt-thread/components/net/lwip/lwip-2.1.2/src/core/dns.c +++ b/rt-thread/components/net/lwip/lwip-2.1.2/src/core/dns.c @@ -99,10 +99,6 @@ #include -#ifdef RT_USING_NETDEV -#include "netdev.h" -#endif - /** Random generator function to create random TXIDs and source ports for queries */ #ifndef DNS_RAND_TXID #if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_XID) != 0) @@ -304,9 +300,7 @@ static u8_t dns_last_pcb_idx; static u8_t dns_seqno; static struct dns_table_entry dns_table[DNS_TABLE_SIZE]; static struct dns_req_entry dns_requests[DNS_MAX_REQUESTS]; -#ifndef RT_USING_NETDEV static ip_addr_t dns_servers[DNS_MAX_SERVERS]; -#endif #if LWIP_IPV4 const ip_addr_t dns_mquery_v4group = DNS_MQUERY_IPV4_GROUP_INIT; @@ -370,25 +364,21 @@ dns_setserver(u8_t numdns, const ip_addr_t *dnsserver) { if (numdns < DNS_MAX_SERVERS) { if (dnsserver != NULL) { + dns_servers[numdns] = (*dnsserver); + #ifdef RT_USING_NETDEV + extern struct netif *netif_list; + extern struct netdev *netdev_get_by_name(const char *name); + extern void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server); struct netif *netif = NULL; /* set network interface device DNS server address */ for (netif = netif_list; netif != NULL; netif = netif->next) { - netdev_set_dns_server(netdev_get_by_name(netif->name), numdns, dnsserver); + netdev_low_level_set_dns_server(netdev_get_by_name(netif->name), numdns, dnsserver); } -#else - dns_servers[numdns] = (*dnsserver); #endif /* RT_USING_NETDEV */ } else { -#ifdef RT_USING_NETDEV - struct netif *netif = NULL; - for (netif = netif_list; netif != NULL; netif = netif->next) { - netdev_set_dns_server(netdev_get_by_name(netif->name), numdns, IP_ADDR_ANY); - } -#else dns_servers[numdns] = *IP_ADDR_ANY; -#endif } } } @@ -405,11 +395,7 @@ const ip_addr_t * dns_getserver(u8_t numdns) { if (numdns < DNS_MAX_SERVERS) { -#ifdef RT_USING_NETDEV - return &netdev_default->dns_servers[numdns]; -#else return &dns_servers[numdns]; -#endif } else { return IP_ADDR_ANY; } @@ -784,19 +770,11 @@ dns_send(u8_t idx) u8_t n; u8_t pcb_idx; struct dns_table_entry *entry = &dns_table[idx]; - const ip_addr_t *dns_addr; LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n", (u16_t)(entry->server_idx), entry->name)); LWIP_ASSERT("dns server out of array", entry->server_idx < DNS_MAX_SERVERS); - -#ifdef RT_USING_NETDEV - dns_addr = &netdev_default->dns_servers[entry->server_idx]; -#else - dns_addr = &dns_servers[entry->server_idx]; -#endif - - if (ip_addr_isany(dns_addr) + if (ip_addr_isany_val(dns_servers[entry->server_idx]) #if LWIP_DNS_SUPPORT_MDNS_QUERIES && !entry->is_mdns #endif @@ -881,11 +859,7 @@ dns_send(u8_t idx) #endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */ { dst_port = DNS_SERVER_PORT; - dst = dns_addr; -#ifdef RT_USING_NETDEV - /* set netif index for this pcb, specify the network interface corresponding to the DNS server */ - dns_pcbs[pcb_idx]->netif_idx = netif_get_index((struct netif *)netdev_default->user_data); -#endif + dst = &dns_servers[entry->server_idx]; } err = udp_sendto(dns_pcbs[pcb_idx], p, dst, dst_port); @@ -1066,15 +1040,8 @@ dns_backupserver_available(struct dns_table_entry *pentry) u8_t ret = 0; if (pentry) { - if ((pentry->server_idx + 1 < DNS_MAX_SERVERS)) { -#ifdef RT_USING_NETDEV - const ip_addr_t *dns_addr = &netdev_default->dns_servers[pentry->server_idx + 1]; -#else - const ip_addr_t *dns_addr = &dns_servers[pentry->server_idx + 1]; -#endif - if (!ip_addr_isany(dns_addr)) { - ret = 1; - } + if ((pentry->server_idx + 1 < DNS_MAX_SERVERS) && !ip_addr_isany_val(dns_servers[pentry->server_idx + 1])) { + ret = 1; } } @@ -1263,14 +1230,9 @@ dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, if (!entry->is_mdns) #endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */ { -#ifdef RT_USING_NETDEV - const ip_addr_t *dns_addr = &netdev_default->dns_servers[entry->server_idx]; -#else - const ip_addr_t *dns_addr = &dns_servers[entry->server_idx]; -#endif /* Check whether response comes from the same network address to which the question was sent. (RFC 5452) */ - if (!ip_addr_cmp(addr, dns_addr)) { + if (!ip_addr_cmp(addr, &dns_servers[entry->server_idx])) { goto ignore_packet; /* ignore this packet */ } } @@ -1669,13 +1631,8 @@ dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, dns_found_call if (!is_mdns) #endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */ { -#ifdef RT_USING_NETDEV - const ip_addr_t *dns_addr = &netdev_default->dns_servers[0]; -#else - const ip_addr_t *dns_addr = &dns_servers[0]; -#endif /* prevent calling found callback if no server is set, return error instead */ - if (ip_addr_isany(dns_addr)) { + if (ip_addr_isany_val(dns_servers[0])) { return ERR_VAL; } } diff --git a/rt-thread/components/net/lwip/lwip-2.1.2/src/core/ipv4/dhcp.c b/rt-thread/components/net/lwip/lwip-2.1.2/src/core/ipv4/dhcp.c index e6ceaeb..534574f 100644 --- a/rt-thread/components/net/lwip/lwip-2.1.2/src/core/ipv4/dhcp.c +++ b/rt-thread/components/net/lwip/lwip-2.1.2/src/core/ipv4/dhcp.c @@ -673,16 +673,7 @@ dhcp_handle_ack(struct netif *netif, struct dhcp_msg *msg_in) for (n = 0; (n < LWIP_DHCP_PROVIDE_DNS_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) { ip_addr_t dns_addr; ip_addr_set_ip4_u32_val(dns_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n))); -#ifdef RT_USING_NETDEV - extern struct netdev *netdev_get_by_name(const char *name); - extern void netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server); - /* Here we only need to set the dns server of the corresponding network device, - * but do not need to configure all network devices. - */ - netdev_set_dns_server(netdev_get_by_name(netif->name), n, &dns_addr); -#else dns_setserver(n, &dns_addr); -#endif } #endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */ } diff --git a/rt-thread/components/net/lwip/lwip-2.1.2/src/core/ipv6/dhcp6.c b/rt-thread/components/net/lwip/lwip-2.1.2/src/core/ipv6/dhcp6.c index eec1159..7cf98a5 100644 --- a/rt-thread/components/net/lwip/lwip-2.1.2/src/core/ipv6/dhcp6.c +++ b/rt-thread/components/net/lwip/lwip-2.1.2/src/core/ipv6/dhcp6.c @@ -538,16 +538,7 @@ dhcp6_handle_config_reply(struct netif *netif, struct pbuf *p_msg_in) } ip6_addr_assign_zone(dns_addr6, IP6_UNKNOWN, netif); /* @todo: do we need a different offset than DHCP(v4)? */ -#ifdef RT_USING_NETDEV - extern struct netdev *netdev_get_by_name(const char *name); - extern void netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server); - /* Here we only need to set the dns server of the corresponding network device, - * but do not need to configure all network devices. - */ - netdev_set_dns_server(netdev_get_by_name(netif->name), n, &dns_addr); -#else dns_setserver(n, &dns_addr); -#endif } } /* @ todo: parse and set Domain Search List */ diff --git a/rt-thread/components/net/lwip/lwip-2.1.2/src/core/ipv6/nd6.c b/rt-thread/components/net/lwip/lwip-2.1.2/src/core/ipv6/nd6.c index b50c2d4..db0c132 100644 --- a/rt-thread/components/net/lwip/lwip-2.1.2/src/core/ipv6/nd6.c +++ b/rt-thread/components/net/lwip/lwip-2.1.2/src/core/ipv6/nd6.c @@ -776,32 +776,14 @@ nd6_input(struct pbuf *p, struct netif *inp) if (htonl(rdnss_opt->lifetime) > 0) { /* TODO implement Lifetime > 0 */ -#ifdef RT_USING_NETDEV - extern struct netdev *netdev_get_by_name(const char *name); - extern void netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server); - /* Here we only need to set the dns server of the corresponding network device, - * but do not need to configure all network devices. - */ - netdev_set_dns_server(netdev_get_by_name(inp->name), rdnss_server_idx++, &rdnss_address); -#else dns_setserver(rdnss_server_idx++, &rdnss_address); -#endif } else { /* TODO implement DNS removal in dns.c */ u8_t s; for (s = 0; s < DNS_MAX_SERVERS; s++) { const ip_addr_t *addr = dns_getserver(s); if(ip_addr_cmp(addr, &rdnss_address)) { -#ifdef RT_USING_NETDEV - extern struct netdev *netdev_get_by_name(const char *name); - extern void netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server); - /* Here we only need to set the dns server of the corresponding network device, - * but do not need to configure all network devices. - */ - netdev_set_dns_server(netdev_get_by_name(inp->name), s, IP_ADDR_ANY); -#else - dns_setserver(s, IP_ADDR_ANY); -#endif + dns_setserver(s, NULL); } } } diff --git a/rt-thread/components/net/lwip/lwip-2.1.2/src/include/lwip/sockets.h b/rt-thread/components/net/lwip/lwip-2.1.2/src/include/lwip/sockets.h index 7fc8572..335bee3 100644 --- a/rt-thread/components/net/lwip/lwip-2.1.2/src/include/lwip/sockets.h +++ b/rt-thread/components/net/lwip/lwip-2.1.2/src/include/lwip/sockets.h @@ -495,18 +495,6 @@ typedef struct fd_set /* poll-related defines and types */ /* @todo: find a better way to guard the definition of these defines and types if already defined */ #if !defined(POLLIN) && !defined(POLLOUT) -#ifdef RT_USING_MUSLLIBC -#define POLLIN 0x001 /**< There is data to read. */ -#define POLLPRI 0x002 /**< There is urgent data to read. */ -#define POLLOUT 0x004 /**< Writing is now possible. */ -#define POLLERR 0x008 /**< Error condition. */ -#define POLLHUP 0x010 /**< Hang up. */ -#define POLLNVAL 0x020 /**< Invalid polling request. */ -#define POLLRDNORM 0x040 /**< Normal data may be read. */ -#define POLLRDBAND 0x080 /**< Priority data may be read. */ -#define POLLWRNORM 0x100 /**< Writing normal data is possible. */ -#define POLLWRBAND 0x200 /**< Writing priority data is possible. */ -#else #define POLLIN 0x1 #define POLLOUT 0x2 #define POLLERR 0x4 @@ -518,7 +506,6 @@ typedef struct fd_set #define POLLWRNORM 0x80 #define POLLWRBAND 0x100 #define POLLHUP 0x200 -#endif /* RT_USING_MUSLLIBC */ typedef unsigned int nfds_t; struct pollfd { diff --git a/rt-thread/components/net/lwip/lwip-2.1.2/src/netif/ppp/ppp.c b/rt-thread/components/net/lwip/lwip-2.1.2/src/netif/ppp/ppp.c index 298bbc1..a9c18e3 100644 --- a/rt-thread/components/net/lwip/lwip-2.1.2/src/netif/ppp/ppp.c +++ b/rt-thread/components/net/lwip/lwip-2.1.2/src/netif/ppp/ppp.c @@ -24,8 +24,7 @@ * ****************************************************************************** * REVISION HISTORY -* 24-09-12 Evlers <1425295900@qq.com> -* add support for independent dns services for multiple network devices +* * 03-01-01 Marc Boucher * Ported to lwIP. * 97-11-05 Guy Lancaster , Global Election Systems Inc. @@ -135,9 +134,6 @@ #if PPP_IPV6_SUPPORT #include "netif/ppp/ipv6cp.h" #endif /* PPP_IPV6_SUPPORT */ -#ifdef RT_USING_NETDEV -#include "netdev.h" -#endif /* RT_USING_NETDEV */ /*************************/ /*** LOCAL DEFINITIONS ***/ @@ -1113,20 +1109,9 @@ int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { LWIP_UNUSED_ARG(pcb); ip_addr_set_ip4_u32_val(ns, ns1); -#ifdef RT_USING_NETDEV - /* Here we only need to set the dns server of the corresponding network device, - * but do not need to configure all network cards. - */ - netdev_set_dns_server(netdev_get_by_name(pcb->netif->name), 0, &ns); -#else dns_setserver(0, &ns); -#endif ip_addr_set_ip4_u32_val(ns, ns2); -#ifdef RT_USING_NETDEV - netdev_set_dns_server(netdev_get_by_name(pcb->netif->name), 1, &ns); -#else dns_setserver(1, &ns); -#endif return 1; } @@ -1142,20 +1127,12 @@ int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { nsa = dns_getserver(0); ip_addr_set_ip4_u32_val(nsb, ns1); if (ip_addr_cmp(nsa, &nsb)) { -#ifdef RT_USING_NETDEV - netdev_set_dns_server(netdev_get_by_name(pcb->netif->name), 0, IP_ADDR_ANY); -#else dns_setserver(0, IP_ADDR_ANY); -#endif } nsa = dns_getserver(1); ip_addr_set_ip4_u32_val(nsb, ns2); if (ip_addr_cmp(nsa, &nsb)) { -#ifdef RT_USING_NETDEV - netdev_set_dns_server(netdev_get_by_name(pcb->netif->name), 1, IP_ADDR_ANY); -#else dns_setserver(1, IP_ADDR_ANY); -#endif } return 1; } diff --git a/rt-thread/components/net/lwip/port/ethernetif.c b/rt-thread/components/net/lwip/port/ethernetif.c index 0f32ac8..c88337c 100644 --- a/rt-thread/components/net/lwip/port/ethernetif.c +++ b/rt-thread/components/net/lwip/port/ethernetif.c @@ -15,7 +15,6 @@ * 2018-11-02 MurphyZhao port to lwIP 2.1.0 * 2021-09-07 Grissiom fix eth_tx_msg ack bug * 2022-02-22 xiangxistu integrate v1.4.1 v2.0.3 and v2.1.2 porting layer - * 2024-09-12 Evlers add support for independent dns services for multiple network devices */ /* @@ -170,11 +169,8 @@ static int lwip_netdev_set_addr_info(struct netdev *netif, ip_addr_t *ip_addr, i } #ifdef RT_LWIP_DNS -static int lwip_netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, ip_addr_t *dns_server) +static int lwip_netdev_set_dns_server(struct netdev *netif, uint8_t dns_num, ip_addr_t *dns_server) { -#if RT_USING_LWIP_VER_NUM >= 0x20102 - netdev_low_level_set_dns_server(netdev, dns_num, dns_server); -#else #if LWIP_VERSION_MAJOR == 1U /* v1.x */ extern void dns_setserver(u8_t numdns, ip_addr_t *dnsserver); #else /* >=2.x */ @@ -182,7 +178,6 @@ static int lwip_netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, ip #endif /* LWIP_VERSION_MAJOR == 1U */ dns_setserver(dns_num, dns_server); -#endif /* RT_USING_LWIP_VER_NUM >= 0x20102 */ return ERR_OK; } #endif /* RT_LWIP_DNS */ @@ -426,11 +421,6 @@ static int netdev_add(struct netif *lwip_netif) netdev->gw = lwip_netif->gw; netdev->netmask = lwip_netif->netmask; -#ifdef NETDEV_USING_LINK_STATUS_CALLBACK - extern void netdev_status_change(struct netdev *netdev, enum netdev_cb_type type); - netdev_set_status_callback(netdev, netdev_status_change); -#endif - return result; } diff --git a/rt-thread/components/net/lwip/port/lwipopts.h b/rt-thread/components/net/lwip/port/lwipopts.h index 9cd86ab..37ed55b 100644 --- a/rt-thread/components/net/lwip/port/lwipopts.h +++ b/rt-thread/components/net/lwip/port/lwipopts.h @@ -654,15 +654,4 @@ #endif #endif /* RT_USING_LWIP_VER_NUM >= 0x20000 */ -#ifdef RT_LWIP_ENABLE_USER_HOOKS -/** - * This hook provides flexibility for handling unknown Ethernet protocols. - * - * For example, you can define how to handle packets of unknown types, - * such as forwarding them to another interface, discarding them, - * or passing them to an application for further processing. - */ -#define LWIP_HOOK_UNKNOWN_ETH_PROTOCOL lwip_hook_unknown_eth_protocol -#endif /* RT_LWIP_ENABLE_USER_HOOKS */ - #endif /* __LWIPOPTS_H__ */ diff --git a/rt-thread/components/net/netdev/Kconfig b/rt-thread/components/net/netdev/Kconfig index b45c279..5f1697d 100644 --- a/rt-thread/components/net/netdev/Kconfig +++ b/rt-thread/components/net/netdev/Kconfig @@ -19,11 +19,7 @@ if RT_USING_NETDEV config NETDEV_USING_AUTO_DEFAULT bool "Enable default netdev automatic change features" default y - - config NETDEV_USING_LINK_STATUS_CALLBACK - bool "Enable netdev callback on link status change" - default n - + config NETDEV_USING_IPV6 bool "Enable IPV6 protocol support" default n diff --git a/rt-thread/components/net/netdev/include/netdev.h b/rt-thread/components/net/netdev/include/netdev.h index 7963ea4..5dc68bf 100644 --- a/rt-thread/components/net/netdev/include/netdev.h +++ b/rt-thread/components/net/netdev/include/netdev.h @@ -101,8 +101,6 @@ struct netdev netdev_callback_fn status_callback; /* network interface device flags change callback */ netdev_callback_fn addr_callback; /* network interface device address information change callback */ - int ifindex; /* network interface device ifindex */ - #ifdef RT_USING_SAL void *sal_user_data; /* user-specific data for SAL */ #endif /* RT_USING_SAL */ @@ -113,6 +111,8 @@ struct netdev extern struct netdev *netdev_list; /* The default network interface device */ extern struct netdev *netdev_default; +/* The local virtual network device */ +extern struct netdev *netdev_lo; /* The network interface device ping response object */ struct netdev_ping_resp { @@ -153,14 +153,10 @@ int netdev_unregister(struct netdev *netdev); struct netdev *netdev_get_first_by_flags(uint16_t flags); struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr); struct netdev *netdev_get_by_name(const char *name); -struct netdev *netdev_get_by_ifindex(int ifindex); #ifdef RT_USING_SAL struct netdev *netdev_get_by_family(int family); int netdev_family_get(struct netdev *netdev); #endif /* RT_USING_SAL */ -#if defined(SAL_USING_AF_NETLINK) -int netdev_getnetdev(struct msg_buf *msg, int (*cb)(struct msg_buf *m_buf, struct netdev *nd, int nd_num, int index, int ipvx)); -#endif /* Set default network interface device in list */ void netdev_set_default(struct netdev *netdev); diff --git a/rt-thread/components/net/netdev/src/netdev.c b/rt-thread/components/net/netdev/src/netdev.c index 94f7613..e6398cf 100644 --- a/rt-thread/components/net/netdev/src/netdev.c +++ b/rt-thread/components/net/netdev/src/netdev.c @@ -35,11 +35,12 @@ struct netdev *netdev_list = RT_NULL; /* The default network interface device */ struct netdev *netdev_default = RT_NULL; +/* The local virtual network device */ +struct netdev *netdev_lo = RT_NULL; /* The global network register callback */ static netdev_callback_fn g_netdev_register_callback = RT_NULL; static netdev_callback_fn g_netdev_default_change_callback = RT_NULL; static RT_DEFINE_SPINLOCK(_spinlock); -static int netdev_num; /** * This function will register network interface device and @@ -54,6 +55,7 @@ static int netdev_num; */ int netdev_register(struct netdev *netdev, const char *name, void *user_data) { + rt_base_t level; rt_uint16_t flags_mask; rt_uint16_t index; @@ -101,7 +103,7 @@ int netdev_register(struct netdev *netdev, const char *name, void *user_data) /* initialize current network interface device single list */ rt_slist_init(&(netdev->list)); - rt_spin_lock(&_spinlock); + level = rt_spin_lock_irqsave(&_spinlock); if (netdev_list == RT_NULL) { @@ -113,10 +115,7 @@ int netdev_register(struct netdev *netdev, const char *name, void *user_data) rt_slist_append(&(netdev_list->list), &(netdev->list)); } - netdev_num++; - netdev->ifindex = netdev_num; - - rt_spin_unlock(&_spinlock); + rt_spin_unlock_irqrestore(&_spinlock, level); if (netdev_default == RT_NULL) { @@ -147,6 +146,7 @@ int netdev_register(struct netdev *netdev, const char *name, void *user_data) */ int netdev_unregister(struct netdev *netdev) { + rt_base_t level; rt_slist_t *node = RT_NULL; struct netdev *cur_netdev = RT_NULL; @@ -157,7 +157,7 @@ int netdev_unregister(struct netdev *netdev) return -RT_ERROR; } - rt_spin_lock(&_spinlock); + level = rt_spin_lock_irqsave(&_spinlock); for (node = &(netdev_list->list); node; node = rt_slist_next(node)) { @@ -188,7 +188,7 @@ int netdev_unregister(struct netdev *netdev) break; } } - rt_spin_unlock(&_spinlock); + rt_spin_unlock_irqrestore(&_spinlock, level); #if defined(SAL_USING_AF_NETLINK) rtnl_ip_notify(netdev, RTM_DELLINK); @@ -233,6 +233,7 @@ void netdev_set_register_callback(netdev_callback_fn register_callback) */ struct netdev *netdev_get_first_by_flags(uint16_t flags) { + rt_base_t level; rt_slist_t *node = RT_NULL; struct netdev *netdev = RT_NULL; @@ -241,19 +242,19 @@ struct netdev *netdev_get_first_by_flags(uint16_t flags) return RT_NULL; } - rt_spin_lock(&_spinlock); + level = rt_spin_lock_irqsave(&_spinlock); for (node = &(netdev_list->list); node; node = rt_slist_next(node)) { netdev = rt_slist_entry(node, struct netdev, list); if (netdev && (netdev->flags & flags) != 0) { - rt_spin_unlock(&_spinlock); + rt_spin_unlock_irqrestore(&_spinlock, level); return netdev; } } - rt_spin_unlock(&_spinlock); + rt_spin_unlock_irqrestore(&_spinlock, level); return RT_NULL; } @@ -269,6 +270,7 @@ struct netdev *netdev_get_first_by_flags(uint16_t flags) */ struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr) { + rt_base_t level; rt_slist_t *node = RT_NULL; struct netdev *netdev = RT_NULL; @@ -277,19 +279,19 @@ struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr) return RT_NULL; } - rt_spin_lock(&_spinlock); + level = rt_spin_lock_irqsave(&_spinlock); for (node = &(netdev_list->list); node; node = rt_slist_next(node)) { netdev = rt_slist_entry(node, struct netdev, list); if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr)) { - rt_spin_unlock(&_spinlock); + rt_spin_unlock_irqrestore(&_spinlock, level); return netdev; } } - rt_spin_unlock(&_spinlock); + rt_spin_unlock_irqrestore(&_spinlock, level); return RT_NULL; } @@ -305,6 +307,7 @@ struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr) */ struct netdev *netdev_get_by_name(const char *name) { + rt_base_t level; rt_slist_t *node = RT_NULL; struct netdev *netdev = RT_NULL; @@ -313,55 +316,19 @@ struct netdev *netdev_get_by_name(const char *name) return RT_NULL; } - rt_spin_lock(&_spinlock); + level = rt_spin_lock_irqsave(&_spinlock); for (node = &(netdev_list->list); node; node = rt_slist_next(node)) { netdev = rt_slist_entry(node, struct netdev, list); if (netdev && (rt_strncmp(netdev->name, name, rt_strlen(name) < RT_NAME_MAX ? rt_strlen(name) : RT_NAME_MAX) == 0)) { - rt_spin_unlock(&_spinlock); + rt_spin_unlock_irqrestore(&_spinlock, level); return netdev; } } - rt_spin_unlock(&_spinlock); - - return RT_NULL; -} - -/** - * This function will get network interface device - * in network interface device list by netdev ifindex. - * - * @param ifindex the ifindex of network interface device - * - * @return != NULL: network interface device object - * NULL: get failed - */ -struct netdev *netdev_get_by_ifindex(int ifindex) -{ - rt_slist_t *node = RT_NULL; - struct netdev *netdev = RT_NULL; - - if (netdev_list == RT_NULL) - { - return RT_NULL; - } - - rt_spin_lock(&_spinlock); - - for (node = &(netdev_list->list); node; node = rt_slist_next(node)) - { - netdev = rt_slist_entry(node, struct netdev, list); - if (netdev && (netdev->ifindex == ifindex)) - { - rt_spin_unlock(&_spinlock); - return netdev; - } - } - - rt_spin_unlock(&_spinlock); + rt_spin_unlock_irqrestore(&_spinlock, level); return RT_NULL; } @@ -378,6 +345,7 @@ struct netdev *netdev_get_by_ifindex(int ifindex) */ struct netdev *netdev_get_by_family(int family) { + rt_base_t level; rt_slist_t *node = RT_NULL; struct netdev *netdev = RT_NULL; struct sal_proto_family *pf = RT_NULL; @@ -387,7 +355,7 @@ struct netdev *netdev_get_by_family(int family) return RT_NULL; } - rt_spin_lock(&_spinlock); + level = rt_spin_lock_irqsave(&_spinlock); for (node = &(netdev_list->list); node; node = rt_slist_next(node)) { @@ -395,7 +363,7 @@ struct netdev *netdev_get_by_family(int family) pf = (struct sal_proto_family *) netdev->sal_user_data; if (pf && pf->skt_ops && pf->family == family && netdev_is_up(netdev)) { - rt_spin_unlock(&_spinlock); + rt_spin_unlock_irqrestore(&_spinlock, level); return netdev; } } @@ -406,12 +374,12 @@ struct netdev *netdev_get_by_family(int family) pf = (struct sal_proto_family *) netdev->sal_user_data; if (pf && pf->skt_ops && pf->sec_family == family && netdev_is_up(netdev)) { - rt_spin_unlock(&_spinlock); + rt_spin_unlock_irqrestore(&_spinlock, level); return netdev; } } - rt_spin_unlock(&_spinlock); + rt_spin_unlock_irqrestore(&_spinlock, level); return RT_NULL; } @@ -432,44 +400,6 @@ int netdev_family_get(struct netdev *netdev) #endif /* RT_USING_SAL */ -#if defined(SAL_USING_AF_NETLINK) -int netdev_getnetdev(struct msg_buf *msg, int (*cb)(struct msg_buf *m_buf, struct netdev *nd, int nd_num, int index, int ipvx)) -{ - struct netdev *cur_nd_list = netdev_list; - struct netdev *nd_node; - int nd_num = 0; - int err = 0; - - if (cur_nd_list == RT_NULL) - return 0; - - rt_spin_lock(&_spinlock); - nd_num = rt_slist_len(&cur_nd_list->list) + 1; - rt_spin_unlock(&_spinlock); - - err = cb(msg, cur_nd_list, nd_num, nd.ifindex, ROUTE_IPV4_TRUE); - if (err < 0) - return err; - - - rt_spin_lock(&_spinlock); - rt_slist_for_each_entry(nd_node, &(cur_nd_list->list), list) - { - rt_spin_unlock(&_spinlock); - err = cb(msg, nd_node, nd_num, nd.ifindex, ROUTE_IPV4_TRUE); - if (err < 0) - { - return err; - } - - rt_spin_lock(&_spinlock); - } - rt_spin_unlock(&_spinlock); - - return 0; -} -#endif - /** * This function will set default network interface device. * diff --git a/rt-thread/components/net/sal/impl/af_inet_at.c b/rt-thread/components/net/sal/impl/af_inet_at.c index 540e240..f119c0b 100644 --- a/rt-thread/components/net/sal/impl/af_inet_at.c +++ b/rt-thread/components/net/sal/impl/af_inet_at.c @@ -99,7 +99,7 @@ static const struct sal_socket_ops at_socket_ops = static const struct sal_netdb_ops at_netdb_ops = { at_gethostbyname, - at_gethostbyname_r, + NULL, at_getaddrinfo, at_freeaddrinfo, }; diff --git a/rt-thread/components/net/sal/impl/af_inet_lwip.c b/rt-thread/components/net/sal/impl/af_inet_lwip.c index 876dfba..9183e1a 100644 --- a/rt-thread/components/net/sal/impl/af_inet_lwip.c +++ b/rt-thread/components/net/sal/impl/af_inet_lwip.c @@ -10,16 +10,16 @@ #include -#ifdef SAL_USING_POSIX -#include -#endif - #include #include #include #include #include +#ifdef SAL_USING_POSIX +#include +#endif + #include #include diff --git a/rt-thread/components/net/sal/socket/net_sockets.c b/rt-thread/components/net/sal/socket/net_sockets.c index c0662b1..63de88e 100644 --- a/rt-thread/components/net/sal/socket/net_sockets.c +++ b/rt-thread/components/net/sal/socket/net_sockets.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -16,31 +16,6 @@ #include #include -/** - * @brief Accepts an incoming connection on a listening socket. - * - * This function extracts the first connection request from the queue of pending connections for - * the listening socket specified by 's' and creates a new socket for the connection. - * - * @param s The file descriptor of the listening socket. This socket must be created with - * 'socket()', bound with 'bind()', and set to listen with 'listen()'. - * @param addr A pointer to a 'sockaddr' structure that will receive the address of the connecting entity. - * This structure is filled with the address of the client once the connection is accepted. - * Can be 'NULL' if the address is not needed. - * @param addrlen A pointer to a variable containing the size of 'addr'. When the function returns, this - * variable will hold the actual size of the address returned. Can be 'NULL' if 'addr' is 'NULL'. - * - * @return On success, returns a new file descriptor for the accepted connection. On failure, returns '-1' - * and sets errno to indicate the error. - * - * @note The original socket 's' remains open and continues to listen for additional incoming connections. - * The returned file descriptor is used for communication with the connected client. - * - * @see socket() Creates a socket for accepting connections. - * @see bind() Binds the socket to a local address. - * @see listen() Sets the socket to listen for incoming connections. - * @see close()/closesocket() Closes a socket when it is no longer needed. - */ int accept(int s, struct sockaddr *addr, socklen_t *addrlen) { int new_socket = -1; @@ -96,27 +71,6 @@ int accept(int s, struct sockaddr *addr, socklen_t *addrlen) } RTM_EXPORT(accept); -/** - * @brief Binds a socket to a specific local address and port. - * - * This function assigns a local address to a socket, defined by the 'name' parameter. - * The address allows the socket to receive data sent to this address. - * - * @param s The file descriptor of the socket to bind. - * @param name A pointer to a 'sockaddr' structure that specifies the address to bind to. - * The structure varies based on the address family, such as 'sockaddr_in' for IPv4. - * @param namelen The length of the 'sockaddr' structure pointed to by 'name', in bytes. - * - * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. - * - * @note The socket must be created with 'socket()' before calling 'bind()'. - * Binding is typically used for server sockets, specifying the local IP and port to listen on. - * If the port is set to '0', the system assigns an available port automatically. - * - * @see socket() Creates a socket for binding. - * @see listen() Prepares the socket to listen for incoming connections after binding. - * @see accept() Accepts connections on a bound and listening socket. - */ int bind(int s, const struct sockaddr *name, socklen_t namelen) { int socket = dfs_net_getsocket(s); @@ -125,30 +79,6 @@ int bind(int s, const struct sockaddr *name, socklen_t namelen) } RTM_EXPORT(bind); -/** - * @brief Shuts down part of a full-duplex connection on a socket. - * - * This function disables further sends or receives on the specified socket, depending on the value - * of the 'how' parameter. It does not close the socket, which must still be closed separately using - * 'close()' or 'closesocket()'. - * - * @param s The file descriptor of the socket to shut down. - * @param how Specifies the type of shutdown to perform. The 'how' parameter can be one of the following: - * - 'SHUT_RD': Disables further reading on the socket. The socket will not receive data. - * - 'SHUT_WR': Disables further writing on the socket. The socket will not send data. - * - 'SHUT_RDWR': Disables both reading and writing on the socket. The socket will be fully shut down. - * - * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. - * - * @note The 'shutdown()' function is used to gracefully close a socket in one or both directions - * (read/write). It is commonly used in scenarios like closing the write side of a TCP connection - * when a server has finished sending data but still expects to receive data. - * - * @see socket() Creates the socket used for communication. - * @see close()/closesocket() Closes the socket after the shutdown is complete. - * @see recv() Receives data on a socket. - * @see send() Sends data on a socket. - */ int shutdown(int s, int how) { int error = 0; @@ -183,28 +113,6 @@ int shutdown(int s, int how) } RTM_EXPORT(shutdown); -/** - * @brief Retrieves the address of the peer connected to a socket. - * - * This function obtains the address of the peer (remote end) connected to the socket 's'. - * It is typically used on connected sockets (e.g., TCP) to retrieve information about the peer. - * - * @param s The file descriptor of the connected socket. - * @param name A pointer to a 'sockaddr' structure that will be filled with the address of the peer. - * The structure type (e.g., 'sockaddr_in' for IPv4) depends on the address family of the socket. - * @param namelen A pointer to a variable that initially specifies the size of the 'name' structure. - * On return, it contains the actual size of the address returned. - * - * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. - * - * @note The 'getpeername()' function is useful for retrieving information about the remote end of a connection, - * such as the IP address and port of a peer in a TCP connection. This function is only valid for sockets - * that are in a connected state. - * - * @see socket() Creates the socket used for the connection. - * @see connect() Connects the socket to a remote address. - * @see getsockname() Retrieves the local address of a socket. - */ int getpeername(int s, struct sockaddr *name, socklen_t *namelen) { int socket = dfs_net_getsocket(s); @@ -213,29 +121,6 @@ int getpeername(int s, struct sockaddr *name, socklen_t *namelen) } RTM_EXPORT(getpeername); -/** - * @brief Retrieves the local address of a socket. - * - * This function obtains the local address (IP address and port) associated with the socket 's'. - * It is typically used to determine the local address and port of a bound or connected socket. - * - * @param s The file descriptor of the socket. - * @param name A pointer to a 'sockaddr' structure that will be filled with the local address - * of the socket. The structure type (e.g., 'sockaddr_in' for IPv4) depends on the - * address family of the socket. - * @param namelen A pointer to a variable that initially specifies the size of the 'name' structure. - * Upon return, this variable contains the actual size of the address returned. - * - * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. - * - * @note The 'getsockname()' function is useful for retrieving the local address information of a socket, - * which can be especially useful in cases where the socket was bound with an ephemeral port (port 0), - * allowing you to discover the actual port number assigned by the system. - * - * @see socket() Creates the socket for communication. - * @see bind() Binds the socket to a specific local address. - * @see getpeername() Retrieves the address of the peer connected to a socket. - */ int getsockname(int s, struct sockaddr *name, socklen_t *namelen) { int socket = dfs_net_getsocket(s); @@ -244,34 +129,6 @@ int getsockname(int s, struct sockaddr *name, socklen_t *namelen) } RTM_EXPORT(getsockname); -/** - * @brief Retrieves options for a socket. - * - * This function retrieves the current value for a specified option on a socket, identified - * by the file descriptor 's'. The option is specified by the 'level' and 'optname' parameters. - * - * @param s The file descriptor of the socket from which to retrieve the option. - * @param level The protocol level at which the option resides. Common levels include: - * - 'SOL_SOCKET': To retrieve socket-level options. - * - 'IPPROTO_IP': To retrieve IPv4 options. - * - 'IPPROTO_TCP': To retrieve TCP options. - * @param optname The name of the option to retrieve. Some common options include: - * - 'SO_REUSEADDR': Checks if address reuse is enabled. - * - 'SO_RCVBUF': Retrieves the receive buffer size. - * - 'TCP_NODELAY': Checks if Nagle's algorithm is disabled for TCP sockets. - * @param optval A pointer to a buffer where the value of the option will be stored. - * The buffer must be large enough to hold the option value. - * @param optlen A pointer to a variable that initially specifies the size of 'optval'. - * On return, it contains the actual size of the option value returned. - * - * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. - * - * @note The 'getsockopt()' function is useful for inspecting socket configuration and current settings. - * It can provide information about options such as buffer sizes, timeouts, and protocol-specific features. - * - * @see socket() Creates the socket to retrieve options from. - * @see setsockopt() Sets options for the socket. - */ int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) { int socket = dfs_net_getsocket(s); @@ -280,35 +137,6 @@ int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) } RTM_EXPORT(getsockopt); -/** - * @brief Sets options on a socket. - * - * This function sets the specified option for the socket referenced by the file descriptor 's'. - * Socket options affect the behavior of the socket and are specified by the 'level' and 'optname' parameters. - * - * @param s The file descriptor of the socket on which to set the option. - * @param level The protocol level at which the option resides. Common levels include: - * - 'SOL_SOCKET': To configure socket-level options. - * - 'IPPROTO_IP': To configure IPv4 options. - * - 'IPPROTO_TCP': To configure TCP options. - * @param optname The name of the option to set. Some common options include: - * - 'SO_REUSEADDR': Allows reuse of local addresses. - * - 'SO_RCVBUF': Sets the receive buffer size. - * - 'TCP_NODELAY': Disables Nagle's algorithm for TCP sockets. - * @param optval A pointer to the buffer containing the value to set for the specified option. - * The type of data in this buffer depends on the option being set. - * @param optlen The size, in bytes, of the option value pointed to by 'optval'. - * - * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. - * - * @note The 'setsockopt()' function is useful for configuring various socket behaviors, such as - * setting timeouts, buffer sizes, and enabling or disabling certain protocol features. - * The changes may affect socket performance and resource usage. - * - * @see socket() Creates the socket to configure. - * @see getsockopt() Retrieves options set on the socket. - * @see bind() Binds the socket to a local address. - */ int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) { int socket = dfs_net_getsocket(s); @@ -317,29 +145,6 @@ int setsockopt(int s, int level, int optname, const void *optval, socklen_t optl } RTM_EXPORT(setsockopt); -/** - * @brief Initiates a connection on a socket. - * - * This function connects the socket specified by 's' to the server address specified by 'name'. - * The socket must have been created with 'socket()' and, for some types of sockets, may need - * to be bound to a local address with 'bind()' before calling 'connect()'. - * - * @param s The file descriptor of the socket to connect. - * @param name A pointer to a 'sockaddr' structure that specifies the address of the server to connect to. - * The specific structure (e.g., 'sockaddr_in' for IPv4) depends on the address family. - * @param namelen The length, in bytes, of the address structure pointed to by 'name'. - * - * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. - * - * @note 'connect()' is typically used by client sockets to establish a connection with a server. - * For connection-oriented protocols (e.g., TCP), this initiates the connection handshake. - * For connectionless protocols (e.g., UDP), it defines a fixed peer address. - * - * @see socket() Creates the socket to be connected. - * @see bind() Binds the socket to a local address (optional for client sockets). - * @see accept() Used by server sockets to accept incoming connections. - * @see close()/closesocket() Closes the socket when done. - */ int connect(int s, const struct sockaddr *name, socklen_t namelen) { int socket = dfs_net_getsocket(s); @@ -347,26 +152,6 @@ int connect(int s, const struct sockaddr *name, socklen_t namelen) } RTM_EXPORT(connect); -/** - * @brief Marks a socket as a passive socket, ready to accept incoming connections. - * - * This function prepares a socket to accept incoming connection requests. The socket - * must first be created with 'socket()' and bound to a local address with 'bind()'. - * - * @param s The file descriptor of the socket to set to listening mode. - * @param backlog The maximum number of pending connections that can be queued for acceptance. - * If more incoming connections arrive than the backlog limit, they may be rejected - * or ignored until the server accepts some of the pending connections. - * - * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. - * - * @note After calling 'listen()', the socket can be used with 'accept()' to handle connection requests. - * The backlog size affects how many connections can wait to be accepted before being rejected. - * - * @see socket() Creates the socket. - * @see bind() Binds the socket to a specific address. - * @see accept() Accepts a pending connection request on the listening socket. - */ int listen(int s, int backlog) { int socket = dfs_net_getsocket(s); @@ -375,31 +160,6 @@ int listen(int s, int backlog) } RTM_EXPORT(listen); -/** - * @brief Receives data from a connected socket. - * - * This function reads data from a connected socket and stores it in the specified buffer. - * It is typically used with connection-oriented protocols (e.g., TCP). - * - * @param s The file descriptor of the connected socket to receive data from. - * @param mem A pointer to the buffer where the received data will be stored. - * @param len The maximum number of bytes to read into the buffer. - * @param flags Specifies the behavior of the receive operation. Common flags include: - * - '0': Default operation. - * - 'MSG_DONTWAIT': Non-blocking operation. - * - 'MSG_PEEK': Peeks at the incoming data without removing it from the queue. - * - * @return Returns the number of bytes received on success. On failure, returns '-1' and sets errno to indicate the error. - * A return value of '0' indicates that the connection has been closed by the remote peer. - * - * @note The 'recv()' function may not receive all the requested bytes in a single call. - * Multiple calls to 'recv()' may be needed to read the complete data. - * - * @see socket() Creates the socket to be used for receiving data. - * @see connect() Connects the socket to a remote address (for connection-oriented protocols). - * @see recvfrom() Receives data from a specific address, typically used with connectionless sockets. - * @see send() Sends data on a connected socket. - */ int recv(int s, void *mem, size_t len, int flags) { int socket = dfs_net_getsocket(s); @@ -408,36 +168,6 @@ int recv(int s, void *mem, size_t len, int flags) } RTM_EXPORT(recv); -/** - * @brief Sends a message on a socket. - * - * The 'sendmsg()' function sends data on the socket 's' using the structured data in the 'msghdr' - * structure. This function is commonly used for sending complex messages with multiple buffers, - * control information, or for working with datagram sockets. - * - * @param s The file descriptor of the socket to send the message on. - * @param message A pointer to an 'msghdr' structure, which contains the data, address, and control information: - * - 'msg_name': Optional destination address (used for connectionless sockets). - * - 'msg_namelen': Size of the destination address. - * - 'msg_iov': An array of 'iovec' structures that point to the data buffers to be sent. - * - 'msg_iovlen': The number of elements in the 'msg_iov' array. - * - 'msg_control': Optional ancillary data, such as file descriptors for UNIX domain sockets. - * - 'msg_controllen': The size of the ancillary data buffer. - * - 'msg_flags': Flags related to the message. - * @param flags Specifies how the message should be sent. Common flags include: - * - 'MSG_DONTWAIT': Sends the message in non-blocking mode. - * - 'MSG_EOR': Indicates the end of a record (for record-oriented sockets). - * - * @return Returns the number of bytes sent on success. On failure, returns '-1' and sets errno to indicate the error. - * - * @note The 'sendmsg()' function is useful for sending messages with multiple buffers or ancillary data, - * allowing flexible communication options such as attaching file descriptors. This function can be - * used with both connection-oriented and connectionless sockets. - * - * @see recvmsg() Receives a message from a socket. - * @see send() Sends data on a socket. - * @see socket() Creates the socket to use with 'sendmsg()'. - */ int sendmsg(int s, const struct msghdr *message, int flags) { int socket = dfs_net_getsocket(s); @@ -446,38 +176,6 @@ int sendmsg(int s, const struct msghdr *message, int flags) } RTM_EXPORT(sendmsg); -/** - * @brief Receives a message from a socket. - * - * The 'recvmsg()' function receives data from the socket 's' into the buffers described by - * the 'msghdr' structure. This function allows for complex data structures, including multiple - * data buffers and optional control information. - * - * @param s The file descriptor of the socket to receive data from. - * @param message A pointer to an 'msghdr' structure, which will be filled with the received data and - * information. The structure contains: - * - 'msg_name': A buffer for the source address (used for connectionless sockets). - * - 'msg_namelen': Specifies the size of the 'msg_name' buffer. - * - 'msg_iov': An array of 'iovec' structures that point to the buffers to store received data. - * - 'msg_iovlen': The number of elements in the 'msg_iov' array. - * - 'msg_control': A buffer for ancillary data, such as received file descriptors. - * - 'msg_controllen': The size of the ancillary data buffer. - * - 'msg_flags': Flags set by the 'recvmsg()' call to indicate the message status. - * @param flags Specifies how the message should be received. Common flags include: - * - 'MSG_DONTWAIT': Receives the message in non-blocking mode. - * - 'MSG_PEEK': Peeks at the incoming message without removing it from the queue. - * - 'MSG_WAITALL': Waits for the full amount of data to be received. - * - * @return Returns the number of bytes received on success. On failure, returns '-1' and sets errno to indicate the error. - * - * @note The 'recvmsg()' function is useful for receiving messages with multiple buffers or ancillary data. - * It can be used with both connection-oriented and connectionless sockets, making it versatile for - * different communication needs. - * - * @see sendmsg() Sends a message on a socket. - * @see recv() Receives data on a socket. - * @see socket() Creates the socket used with 'recvmsg()'. - */ int recvmsg(int s, struct msghdr *message, int flags) { int socket = dfs_net_getsocket(s); @@ -486,36 +184,6 @@ int recvmsg(int s, struct msghdr *message, int flags) } RTM_EXPORT(recvmsg); -/** - * @brief Receives data from a specific address using an unconnected socket. - * - * This function reads data from a socket and stores it in the specified buffer. It is commonly used - * with connectionless protocols (e.g., UDP) to receive data from a specific source address. - * - * @param s The file descriptor of the socket to receive data from. - * @param mem A pointer to the buffer where the received data will be stored. - * @param len The maximum number of bytes to read into the buffer. - * @param flags Specifies the behavior of the receive operation. Common flags include: - * - '0': Default operation. - * - 'MSG_DONTWAIT': Non-blocking operation. - * - 'MSG_PEEK': Peeks at the incoming data without removing it from the queue. - * @param from A pointer to a 'sockaddr' structure that will be filled with the address of the - * sending entity. This is the source address from which the data was received. - * @param fromlen A pointer to a variable that initially contains the size of the 'from' structure. - * Upon return, this variable will hold the actual size of the address returned. - * - * @return Returns the number of bytes received on success. On failure, returns '-1' and sets errno to indicate the error. - * A return value of '0' indicates that the connection has been closed by the remote peer. - * - * @note The 'recvfrom()' function is useful for receiving data from an arbitrary source address, - * which makes it especially suited for connectionless protocols where the peer's address may vary. - * The 'from' parameter is filled with the sender's address, which can be useful for identifying - * the origin of the data. - * - * @see socket() Creates the socket used for receiving data. - * @see sendto() Sends data to a specific address, typically used with connectionless sockets. - * @see recv() Receives data on a connected socket. - */ int recvfrom(int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) { @@ -525,32 +193,6 @@ int recvfrom(int s, void *mem, size_t len, int flags, } RTM_EXPORT(recvfrom); -/** - * @brief Sends data on a connected socket. - * - * This function sends data to a connected socket, specified by the file descriptor 's'. - * It is typically used with connection-oriented protocols (e.g., TCP). - * - * @param s The file descriptor of the socket to send data on. - * The socket must be connected to a remote peer. - * @param dataptr A pointer to the buffer containing the data to send. - * @param size The size, in bytes, of the data to be sent from the buffer. - * @param flags Specifies the behavior of the send operation. Common flags include: - * - '0': Default operation. - * - 'MSG_DONTWAIT': Non-blocking operation. - * - 'MSG_NOSIGNAL': Prevents the sending of 'SIGPIPE' on errors. - * - * @return Returns the number of bytes sent on success. On failure, returns '-1' and sets errno to indicate the error. - * If the connection is closed by the remote peer, the return value may be '0'. - * - * @note The 'send()' function does not guarantee that all data will be sent in a single call. - * If fewer bytes are sent than requested, the remaining data should be sent in subsequent calls. - * - * @see socket() Creates the socket to be used for sending data. - * @see connect() Connects the socket to a remote address (for connection-oriented protocols). - * @see sendto() Sends data to a specific address, typically used with connectionless sockets. - * @see recv() Receives data from a connected socket. - */ int send(int s, const void *dataptr, size_t size, int flags) { int socket = dfs_net_getsocket(s); @@ -559,34 +201,6 @@ int send(int s, const void *dataptr, size_t size, int flags) } RTM_EXPORT(send); -/** - * @brief Sends data to a specific address using an unconnected socket. - * - * This function is typically used with connectionless protocols (e.g., UDP) to send data - * to a specific destination address, as specified by 'to'. - * - * @param s The file descriptor of the socket to send data on. - * @param dataptr A pointer to the buffer containing the data to be sent. - * @param size The size, in bytes, of the data to be sent from the buffer. - * @param flags Specifies the behavior of the send operation. Common flags include: - * - '0': Default operation. - * - 'MSG_DONTWAIT': Non-blocking operation. - * - 'MSG_NOSIGNAL': Prevents the sending of 'SIGPIPE' on errors. - * @param to A pointer to a 'sockaddr' structure that specifies the destination address. - * The structure type (e.g., 'sockaddr_in' for IPv4) depends on the address family. - * @param tolen The length, in bytes, of the address structure pointed to by 'to'. - * - * @return Returns the number of bytes sent on success. On failure, returns '-1' and sets errno to indicate the error. - * - * @note Unlike 'send()', 'sendto()' can specify a target address for each message, allowing it to be used - * for both connected and unconnected sockets. In connectionless protocols, 'sendto()' is commonly - * used without prior calls to 'connect()'. - * - * @see socket() Creates the socket used for sending data. - * @see recvfrom() Receives data from a specific address, typically used with connectionless sockets. - * @see connect() Optional for connection-oriented protocols. - * @see send() Sends data on a connected socket. - */ int sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen) { @@ -596,38 +210,6 @@ int sendto(int s, const void *dataptr, size_t size, int flags, } RTM_EXPORT(sendto); -/** - * @brief Creates a network socket. - * - * This function creates a socket and returns a file descriptor that can be used for network communication. - * - * @param domain The communication protocol family (address family) that defines the socket's protocol. - * Common values include: - * - 'AF_INET': IPv4 - * - 'AF_INET6': IPv6 - * - 'AF_UNIX': Local communication (inter-process communication on the same machine) - * - 'AF_AT': AT socket - * - 'AF_WIZ': WIZnet - * @param type The type of socket, which determines the characteristics of data transmission. - * Common values include: - * - 'SOCK_STREAM': Connection-oriented byte stream communication (e.g., TCP) - * - 'SOCK_DGRAM': Connectionless datagram communication (e.g., UDP) - * - 'SOCK_RAW': Provides raw network protocol access - * @param protocol Specifies the protocol to be used with the socket. It is usually set to '0', - * which allows the system to choose the default protocol: - * - For 'SOCK_STREAM', the default is TCP. - * - For 'SOCK_DGRAM', the default is UDP. - * - * @return On success, returns a file descriptor (a non-negative integer) representing the socket. - * On failure, returns '-1' and sets errno to indicate the error. - * - * @note The created socket can be used for binding, listening, receiving, and sending data. - * - * @see bind() Used to bind the socket to a local address. - * @see listen() Used to set the socket to listen for incoming connections. - * @see accept() Used to accept incoming connection requests. - * @see connect() Used to connect to a remote host. - */ int socket(int domain, int type, int protocol) { /* create a BSD socket */ @@ -680,25 +262,6 @@ int socket(int domain, int type, int protocol) } RTM_EXPORT(socket); -/** - * @brief Closes a socket. - * - * This function closes the socket specified by the file descriptor 's'. Once closed, the socket - * can no longer be used for communication. Any pending data that has not been transmitted may be lost. - * - * @param s The file descriptor of the socket to close. - * - * @return Returns '0' on success. On failure, returns '-1' and sets errno to indicate the error. - * - * @note After calling 'closesocket()', the socket descriptor becomes invalid. The socket cannot - * be used for further communication or operations. It is important to close sockets when they are no longer needed - * to release system resources. - * - * @see socket() Creates a socket. - * @see shutdown() Shuts down the socket for reading and/or writing, without closing it. - * @see recv() Receives data from a socket. - * @see send() Sends data on a socket. - */ int closesocket(int s) { int error = 0; @@ -742,32 +305,7 @@ int closesocket(int s) } RTM_EXPORT(closesocket); -/** - * @brief Creates a pair of connected sockets. - * - * The 'socketpair()' function creates two connected sockets, which can be used for bidirectional - * communication between processes or threads on the same machine. This is commonly used for inter-process - * communication (IPC) in UNIX-like operating systems. - * - * @param domain The communication domain (or protocol family). Typically, 'AF_UNIX' (or 'AF_LOCAL') - * is used to create sockets for local communication. - * @param type The type of socket to be created. Common values include: - * - 'SOCK_STREAM': Provides reliable, connection-oriented communication. - * - 'SOCK_DGRAM': Provides connectionless, unreliable communication. - * @param protocol The protocol to be used with the sockets. Normally set to '0' to use the default protocol - * for the specified 'domain' and 'type'. - * @param fds An array of two integers where the file descriptors for the two connected sockets will be stored. - * After a successful call, 'fds[0]' and 'fds[1]' represent the two ends of the socket pair. - * - * @return Returns '0' on success. On failure, returns '-1' and sets 'errno' to indicate the error. - * - * @note The 'socketpair()' function is commonly used to create a communication channel between two processes - * (parent and child after 'fork()') or two threads. Data written to one socket is available for reading - * from the other. It is primarily supported on UNIX-like systems and may not be available on Windows. - * - * @see socket() Creates a single socket for network communication. - * @see pipe() Creates an unidirectional communication channel between processes. - */ + int socketpair(int domain, int type, int protocol, int *fds) { rt_err_t ret = 0; @@ -804,32 +342,6 @@ int socketpair(int domain, int type, int protocol, int *fds) } RTM_EXPORT(socketpair); -/** - * @brief Controls socket I/O modes. - * - * The 'ioctlsocket()' function manipulates the I/O mode of the socket specified by the file descriptor 's'. - * It is primarily used to enable or disable non-blocking mode on a socket or to perform other socket-specific - * operations. - * - * @param s The file descriptor of the socket to control. - * @param cmd The command that specifies the operation to perform. Some common commands include: - * - 'FIONBIO': Enables or disables non-blocking mode. Setting 'arg' to a non-zero value - * enables non-blocking mode; setting it to zero disables it. - * - 'FIONREAD': Retrieves the number of bytes available to read, storing the result in 'arg'. - * @param arg A pointer to an argument for the command. The type and meaning of this argument depend on the - * specified command ('cmd'). For example, in non-blocking mode ('FIONBIO'), it points to a 'long' - * that is either non-zero (to enable) or zero (to disable) non-blocking mode. - * - * @return Returns '0' on success. On failure, returns '-1' and sets errno (or 'WSAGetLastError()' on Windows) to indicate the error. - * - * @note This function is specific to Windows environments and is a part of the Winsock API. It performs - * similar functionality to the 'fcntl()' function on UNIX-like systems. - * The 'ioctlsocket()' function allows for various socket manipulations that affect how the socket - * operates in certain conditions, such as setting it to non-blocking mode. - * - * @see socket() Creates a socket to use with 'ioctlsocket()'. - * @see fcntl() Performs similar operations on UNIX-like systems. - */ int ioctlsocket(int s, long cmd, void *arg) { int socket = dfs_net_getsocket(s); diff --git a/rt-thread/components/net/sal/src/sal_socket.c b/rt-thread/components/net/sal/src/sal_socket.c index ce0a9ca..63009b8 100644 --- a/rt-thread/components/net/sal/src/sal_socket.c +++ b/rt-thread/components/net/sal/src/sal_socket.c @@ -444,6 +444,11 @@ static int socket_init(int family, int type, int protocol, struct sal_socket **r struct netdev *netdev = RT_NULL; rt_bool_t flag = RT_FALSE; + if (family == AF_UNIX) + { + netdv_def = netdev_lo; + } + if (family < 0 || family > AF_MAX) { return -1; @@ -679,8 +684,7 @@ int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen) addr_un = (struct sockaddr_un *)name; -#define IS_INET_ADDR_FAMILY(_af) ((_af) == AF_INET) || ((_af) == AF_INET6) - if (IS_INET_ADDR_FAMILY(name->sa_family)) + if ((addr_un->sa_family != AF_UNIX) && (addr_un->sa_family != AF_NETLINK)) { /* bind network interface by ip address */ sal_sockaddr_to_ipaddr(name, &input_ipaddr); @@ -906,11 +910,11 @@ int sal_sendmsg(int socket, const struct msghdr *message, int flags) SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, sendmsg); #ifdef SAL_USING_TLS - if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, send)) + if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, sendmsg)) { int ret; - if ((ret = proto_tls->ops->send(sock->user_data_tls, message, flags)) < 0) + if ((ret = proto_tls->ops->sendmsg(sock->user_data_tls, message, flags)) < 0) { return -1; } @@ -939,11 +943,11 @@ int sal_recvmsg(int socket, struct msghdr *message, int flags) SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, recvmsg); #ifdef SAL_USING_TLS - if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, recv)) + if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, recvmsg)) { int ret; - if ((ret = proto_tls->ops->recv(sock->user_data_tls, message, flags)) < 0) + if ((ret = proto_tls->ops->recvmsg(sock->user_data_tls, message, flags)) < 0) { return -1; } @@ -1167,9 +1171,12 @@ int sal_ioctlsocket(int socket, long cmd, void *arg) /* get the socket object by socket descriptor */ SAL_SOCKET_OBJ_GET(sock, socket); + /* check the network interface socket opreation */ + SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, ioctlsocket); + struct sal_ifreq *ifr = (struct sal_ifreq *)arg; - if (ifr != RT_NULL) + if((sock->domain == AF_INET)&&(sock->netdev)&&(ifr != RT_NULL)) { switch (cmd) { @@ -1467,24 +1474,10 @@ int sal_ioctlsocket(int socket, long cmd, void *arg) ifconf_tmp->ifc_ifcu.ifcu_buf = ifconf_tmp->ifc_ifcu.ifcu_buf - sizeof(struct sal_ifreq) * count_size; return 0; } - case SIOCGIFINDEX: - { - netdev = netdev_get_by_name(ifr->ifr_ifrn.ifrn_name); - if (netdev) - { - ifr->ifr_ifru.ifru_ivalue = netdev->ifindex; - return 0; - } - return -ENODEV; - } default: break; } } - - /* check the network interface socket opreation */ - SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, ioctlsocket); - return pf->skt_ops->ioctlsocket((int)(size_t)sock->user_data, cmd, arg); } diff --git a/rt-thread/components/utilities/Kconfig b/rt-thread/components/utilities/Kconfig index 74e16cc..b64b319 100644 --- a/rt-thread/components/utilities/Kconfig +++ b/rt-thread/components/utilities/Kconfig @@ -137,7 +137,7 @@ menuconfig RT_USING_ULOG config ULOG_OUTPUT_FLOAT bool "Enable float number support. It will using more thread stack." default n - select RT_KLIBC_USING_VSNPRINTF_STANDARD + select PKG_USING_RT_VSNPRINTF_FULL help The default formater is using rt_vsnprint and it not supported float number. When enable this option then it will enable libc. The formater will change to vsnprint on libc. @@ -210,19 +210,6 @@ config RT_USING_UTEST config UTEST_THR_PRIORITY int "The utest thread priority" default 20 - - config RT_UTEST_USING_AUTO_RUN - bool "Enable auto run test cases" - default n - help - If enable this option, the test cases will be run automatically when board boot up. - - config RT_UTEST_USING_ALL_CASES - bool "Enable all selected modules' test cases" - default n - help - If enable this option, all selected modules' test cases will be run. - Otherwise, only the test cases that are explicitly enabled will be run. endif config RT_USING_VAR_EXPORT diff --git a/rt-thread/components/utilities/ulog/ulog.c b/rt-thread/components/utilities/ulog/ulog.c index b92787f..a880b71 100644 --- a/rt-thread/components/utilities/ulog/ulog.c +++ b/rt-thread/components/utilities/ulog/ulog.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -108,7 +108,6 @@ struct rt_ulog #endif /* ULOG_USING_FILTER */ }; -#ifdef ULOG_OUTPUT_LEVEL /* level output info */ static const char * const level_output_info[] = { @@ -121,7 +120,6 @@ static const char * const level_output_info[] = "I/", "D/", }; -#endif /* ULOG_OUTPUT_LEVEL */ #ifdef ULOG_USING_COLOR /* color output info */ @@ -1262,24 +1260,6 @@ MSH_CMD_EXPORT(ulog_filter, Show ulog filter settings); #endif /* RT_USING_FINSH */ #endif /* ULOG_USING_FILTER */ -/** - * @brief register the backend device into the ulog. - * - * @param backend Backend device handle, a pointer to a "struct ulog_backend" obj. - * @param name Backend device name. - * @param support_color Whether it supports color logs. - * @return rt_err_t - return 0 on success. - * - * @note - This function is used to register the backend device into the ulog, - * ensuring that the function members in the backend device structure are set before registration. - * - about struct ulog_backend: - * 1. The name and support_color properties can be passed in through the ulog_backend_register() function. - * 2. output is the back-end specific output function, and all backends must implement the interface. - * 3. init/deinit is optional, init is called at register, and deinit is called at unregister or ulog_deinit. - * 4. flush is also optional, and some internal output cached backends need to implement this interface. - * For example, some file systems with RAM cache. The flush of the backend is usually called by - * ulog_flush in the case of an exception such as assertion or hardfault. - */ rt_err_t ulog_backend_register(ulog_backend_t backend, const char *name, rt_bool_t support_color) { rt_base_t level; @@ -1305,13 +1285,6 @@ rt_err_t ulog_backend_register(ulog_backend_t backend, const char *name, rt_bool return RT_EOK; } -/** - * @brief unregister a backend device that has already been registered. - * - * @param backend Backend device handle - * @return rt_err_t - return 0 on success. - * @note deinit function will be called at unregister. - */ rt_err_t ulog_backend_unregister(ulog_backend_t backend) { rt_base_t level; @@ -1485,14 +1458,6 @@ void ulog_flush(void) } } -/** - * @brief ulog initialization - * - * @return int return 0 on success, return -5 when failed of insufficient memory. - * - * @note This function must be called to complete ulog initialization before using ulog. - * This function will also be called automatically if component auto-initialization is turned on. - */ int ulog_init(void) { if (ulog.init_ok) @@ -1551,11 +1516,6 @@ int ulog_async_init(void) INIT_PREV_EXPORT(ulog_async_init); #endif /* ULOG_USING_ASYNC_OUTPUT */ -/** - * @brief ulog deinitialization - * - * @note This deinit release resource can be executed when ulog is no longer used. - */ void ulog_deinit(void) { rt_slist_t *node; diff --git a/rt-thread/components/utilities/ulog/ulog_def.h b/rt-thread/components/utilities/ulog/ulog_def.h index e84b198..42869b1 100644 --- a/rt-thread/components/utilities/ulog/ulog_def.h +++ b/rt-thread/components/utilities/ulog/ulog_def.h @@ -43,10 +43,16 @@ extern "C" { #undef DBG_WARNING #undef DBG_INFO #undef DBG_LOG +#undef dbg_log #define DBG_ERROR LOG_LVL_ERROR #define DBG_WARNING LOG_LVL_WARNING #define DBG_INFO LOG_LVL_INFO #define DBG_LOG LOG_LVL_DBG +#define dbg_log(level, ...) \ + if ((level) <= LOG_LVL) \ + { \ + ulog_output(level, LOG_TAG, RT_FALSE, __VA_ARGS__);\ + } #if !defined(LOG_TAG) /* compatible for rtdbg */ diff --git a/rt-thread/components/utilities/utest/TC_uassert.c b/rt-thread/components/utilities/utest/TC_uassert.c deleted file mode 100644 index bb212c1..0000000 --- a/rt-thread/components/utilities/utest/TC_uassert.c +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include "utest.h" - -static void TC_uassert_true_false(void) -{ - uassert_true(1); - uassert_false(0); -} - -static void TC_uassert_null_not_null(void) -{ - int *ptr = RT_NULL; - int value = 10; - int *ptr2 = &value; - - uassert_null(ptr); - uassert_not_null(ptr2); -} - -static void TC_uassert_int_op(void) -{ - int a = 5; - int b = 10; - - uassert_int_equal(a, a); - uassert_int_not_equal(a, b); - uassert_value_less(a, b); - uassert_value_less_equal(a, b); - uassert_value_less_equal(a, a); - uassert_value_greater(b, a); - uassert_value_greater_equal(b, a); - uassert_value_greater_equal(b, b); -} - -static void TC_uassert_float_op(void) -{ - float a = 5.0; - float b = 5.0; - - uassert_float_equal(a, b); - uassert_float_not_equal(a, b + 0.0002); -} - -static void TC_uassert_ptr_op(void) -{ - int a = 5; - int b = 10; - int *ptr_a = &a; - int *ptr_b = &b; - - uassert_ptr_equal(ptr_a, ptr_a); - uassert_ptr_not_equal(ptr_a, ptr_b); -} - -static void TC_uassert_str_op(void) -{ - const char *str1 = "Hello"; - const char *str2 = "Hello"; - const char *str3 = "World"; - - uassert_str_equal(str1, str2); - uassert_str_not_equal(str1, str3); -} - -static void TC_uassert_in_range(void) -{ - int value = 5; - uassert_in_range(value, 1, 10); - uassert_not_in_range(value, 10, 20); -} - -static void utest_do_tc(void) -{ - UTEST_UNIT_RUN(TC_uassert_true_false); - UTEST_UNIT_RUN(TC_uassert_null_not_null); - UTEST_UNIT_RUN(TC_uassert_int_op); - UTEST_UNIT_RUN(TC_uassert_float_op); - UTEST_UNIT_RUN(TC_uassert_ptr_op); - UTEST_UNIT_RUN(TC_uassert_str_op); - UTEST_UNIT_RUN(TC_uassert_in_range); -} - -UTEST_TC_EXPORT(utest_do_tc, "utest.uassert", RT_NULL, RT_NULL, 10); diff --git a/rt-thread/components/utilities/utest/utest.c b/rt-thread/components/utilities/utest/utest.c index f5baa71..4871735 100644 --- a/rt-thread/components/utilities/utest/utest.c +++ b/rt-thread/components/utilities/utest/utest.c @@ -11,8 +11,12 @@ #include #include #include + #include "utest.h" -#include "utest_log.h" +#include + +#undef DBG_TAG +#undef DBG_LVL #define DBG_TAG "utest" #ifdef UTEST_DEBUG @@ -29,7 +33,7 @@ #ifdef UTEST_THR_STACK_SIZE #define UTEST_THREAD_STACK_SIZE UTEST_THR_STACK_SIZE #else -#define UTEST_THREAD_STACK_SIZE 4096 +#define UTEST_THREAD_STACK_SIZE (4096) #endif #ifdef UTEST_THR_PRIORITY @@ -187,7 +191,7 @@ static int utest_help(void) return 0; } -static void utest_do_run(const char *utest_name) +static void utest_run(const char *utest_name) { rt_size_t i; rt_uint32_t index; @@ -213,7 +217,7 @@ static void utest_do_run(const char *utest_name) { if (utest_name) { - int len = rt_strlen(utest_name); + int len = strlen(utest_name); if (utest_name[len - 1] == '*') { len -= 1; @@ -231,7 +235,7 @@ static void utest_do_run(const char *utest_name) { if (tc_table[i].init() != RT_EOK) { - LOG_E("[ FAILED ] [ result ] testcase init (%s)", tc_table[i].name); + LOG_E("[ FAILED ] [ result ] testcase (%s)", tc_table[i].name); goto __tc_continue; } } @@ -259,7 +263,7 @@ static void utest_do_run(const char *utest_name) { if (tc_table[i].cleanup() != RT_EOK) { - LOG_E("[ FAILED ] [ result ] testcase cleanup (%s)", tc_table[i].name); + LOG_E("[ FAILED ] [ result ] testcase (%s)", tc_table[i].name); goto __tc_continue; } } @@ -296,38 +300,17 @@ static void utest_do_run(const char *utest_name) } } -static void utest_thr_entry(void *para) +static void utest_thr_entry(const char *utest_name) { - char *utest_name = (char *)para; - rt_thread_mdelay(1000); /* see commit:0dc7b9a for details */ - rt_kprintf("\n"); - utest_do_run(utest_name); + /* see commit:0dc7b9a for details */ + rt_thread_mdelay(1000); + + utest_run(utest_name); } -static void utest_thread_create(const char *utest_name) +long utest_testcase_run(int argc, char** argv) { - rt_thread_t tid = RT_NULL; - tid = rt_thread_create("utest", - utest_thr_entry, (void *)utest_name, - UTEST_THREAD_STACK_SIZE, UTEST_THREAD_PRIORITY, 10); - if (tid != RT_NULL) - { - rt_thread_startup(tid); - } -} -#ifdef RT_UTEST_USING_AUTO_RUN -static int utest_auto_run(void) -{ - tc_loop = 1; - utest_thread_create(RT_NULL); - return RT_EOK; -} -INIT_APP_EXPORT(utest_auto_run); -#endif /* RT_UTEST_USING_AUTO_RUN */ - -int utest_testcase_run(int argc, char** argv) -{ static char utest_name[UTEST_NAME_MAX_LEN]; rt_memset(utest_name, 0x0, sizeof(utest_name)); @@ -335,21 +318,27 @@ int utest_testcase_run(int argc, char** argv) if (argc == 1) { - utest_thread_create(RT_NULL); + utest_run(RT_NULL); + return 0; } else if (argc == 2 || argc == 3 || argc == 4) { if (rt_strcmp(argv[1], "-thread") == 0) { + rt_thread_t tid = RT_NULL; if (argc == 3 || argc == 4) { rt_strncpy(utest_name, argv[2], sizeof(utest_name) -1); - if (argc == 4) - { - tc_loop = atoi(argv[3]); - } + + if (argc == 4) tc_loop = atoi(argv[3]); + } + tid = rt_thread_create("utest", + (void (*)(void *))utest_thr_entry, utest_name, + UTEST_THREAD_STACK_SIZE, UTEST_THREAD_PRIORITY, 10); + if (tid != NULL) + { + rt_thread_startup(tid); } - utest_thread_create(utest_name); } else if (rt_strcmp(argv[1], "-help") == 0) { @@ -358,11 +347,8 @@ int utest_testcase_run(int argc, char** argv) else { rt_strncpy(utest_name, argv[1], sizeof(utest_name) -1); - if (argc == 3) - { - tc_loop = atoi(argv[2]); - } - utest_do_run(utest_name); + if (argc == 3) tc_loop = atoi(argv[2]); + utest_run(utest_name); } } else @@ -370,8 +356,7 @@ int utest_testcase_run(int argc, char** argv) LOG_E("[ error ] at (%s:%d), in param error.", __func__, __LINE__); utest_help(); } - - return RT_EOK; + return 0; } MSH_CMD_EXPORT_ALIAS(utest_testcase_run, utest_run, utest_run [-thread or -help] [testcase name] [loop num]); @@ -382,7 +367,7 @@ utest_t utest_handle_get(void) void utest_unit_run(test_unit_func func, const char *unit_func_name) { - LOG_I("[==========] utest unit name: (%s)", unit_func_name); + // LOG_I("[==========] utest unit name: (%s)", unit_func_name); local_utest.error = UTEST_PASSED; local_utest.passed_num = 0; local_utest.failed_num = 0; @@ -393,27 +378,13 @@ void utest_unit_run(test_unit_func func, const char *unit_func_name) } } -/* -* utest_assert - assert function -* -* @param value - assert value -* @param file - file name -* @param line - line number -* @param func - function name -* @param msg - assert message -* -* @return - RT_TRUE: assert success; RT_FALSE: assert failed -*/ -rt_bool_t utest_assert(int value, const char *file, int line, const char *func, const char *msg) +void utest_assert(int value, const char *file, int line, const char *func, const char *msg) { - rt_bool_t rst = RT_FALSE; - if (!(value)) { local_utest.error = UTEST_FAILED; local_utest.failed_num ++; LOG_E("[ ASSERT ] [ unit ] at (%s); func: (%s:%d); msg: (%s)", file_basename(file), func, line, msg); - rst = RT_FALSE; } else { @@ -423,49 +394,37 @@ rt_bool_t utest_assert(int value, const char *file, int line, const char *func, } local_utest.error = UTEST_PASSED; local_utest.passed_num ++; - rst = RT_TRUE; } - - return rst; } void utest_assert_string(const char *a, const char *b, rt_bool_t equal, const char *file, int line, const char *func, const char *msg) { - rt_bool_t rst = RT_FALSE; - if (a == RT_NULL || b == RT_NULL) { - rst = utest_assert(0, file, line, func, msg); + utest_assert(0, file, line, func, msg); } - else + + if (equal) { - if (equal) + if (rt_strcmp(a, b) == 0) { - if (rt_strcmp(a, b) == 0) - { - rst = utest_assert(1, file, line, func, msg); - } - else - { - rst = utest_assert(0, file, line, func, msg); - } + utest_assert(1, file, line, func, msg); } else { - if (rt_strcmp(a, b) == 0) - { - rst = utest_assert(0, file, line, func, msg); - } - else - { - rst = utest_assert(1, file, line, func, msg); - } + utest_assert(0, file, line, func, msg); } } - - if (!rst) + else { - LOG_E("[ ASSERT ] [ unit ] str-a: (%s); str-b: (%s)", a, b); + if (rt_strcmp(a, b) == 0) + { + utest_assert(0, file, line, func, msg); + } + else + { + utest_assert(1, file, line, func, msg); + } } } diff --git a/rt-thread/components/utilities/utest/utest.h b/rt-thread/components/utilities/utest/utest.h index 21329f6..56a6e0d 100644 --- a/rt-thread/components/utilities/utest/utest.h +++ b/rt-thread/components/utilities/utest/utest.h @@ -12,6 +12,7 @@ #define __UTEST_H__ #include +#include #include "utest_log.h" #include "utest_assert.h" @@ -172,12 +173,9 @@ utest_t utest_handle_get(void); * @return None * */ -#define _UTEST_UNIT_RUN(test_unit_func) \ - do { \ - utest_unit_run(test_unit_func, #test_unit_func); \ - } while (0) - -#define UTEST_UNIT_RUN(test_unit_func) _UTEST_UNIT_RUN(test_unit_func) +#define UTEST_UNIT_RUN(test_unit_func) \ + utest_unit_run(test_unit_func, #test_unit_func); \ + if(utest_handle_get()->failed_num != 0) return; #ifdef __cplusplus } diff --git a/rt-thread/components/utilities/utest/utest_assert.h b/rt-thread/components/utilities/utest/utest_assert.h index 86381f5..ba76fc3 100644 --- a/rt-thread/components/utilities/utest/utest_assert.h +++ b/rt-thread/components/utilities/utest/utest_assert.h @@ -19,7 +19,7 @@ extern "C" { #endif /* No need for the user to use this function directly */ -rt_bool_t utest_assert(int value, const char *file, int line, const char *func, const char *msg); +void utest_assert(int value, const char *file, int line, const char *func, const char *msg); /* No need for the user to use this function directly */ void utest_assert_string(const char *a, const char *b, rt_bool_t equal, const char *file, int line, const char *func, const char *msg); @@ -27,7 +27,6 @@ void utest_assert_buf(const char *a, const char *b, rt_size_t sz, rt_bool_t equa /* No need for the user to use this macro directly */ #define __utest_assert(value, msg) utest_assert(value, __FILE__, __LINE__, __func__, msg) -#define __uassert_value_op(a, b, op) __utest_assert((a) op (b), "(" #a ") not " #op " (" #b ")") /** * uassert_x macros @@ -47,61 +46,15 @@ void utest_assert_buf(const char *a, const char *b, rt_size_t sz, rt_bool_t equa * @macro uassert_buf_not_equal if @a not equal to @b, not assert, means passing. buf type test. * @macro uassert_in_range if @value is in range of min and max, not assert, means passing. * @macro uassert_not_in_range if @value is not in range of min and max, not assert, means passing. - * @macro uassert_float_equal if @a equal to @b, not assert, means passing. Float type test. - * @macro uassert_float_not_equal if @a not equal to @b, not assert, means passing. Float type test. - * @macro uassert_value_less if @a less than @b, not assert, means passing. - * @macro uassert_value_less_equal if @a less than or equal to @b, not assert, means passing. - * @macro uassert_value_greater if @a greater than @b, not assert, means passing. - * @macro uassert_value_greater_equal if @a greater than or equal to @b, not assert, means passing. - * @macro uassert_ptr_equal if @a equal to @b, not assert, means passing. Pointer type test. - * @macro uassert_ptr_not_equal if @a not equal to @b, not assert, means passing. Pointer type test. - */ + * +*/ #define uassert_true(value) __utest_assert(value, "(" #value ") is false") #define uassert_false(value) __utest_assert(!(value), "(" #value ") is true") - #define uassert_null(value) __utest_assert((const char *)(value) == RT_NULL, "(" #value ") is not null") #define uassert_not_null(value) __utest_assert((const char *)(value) != RT_NULL, "(" #value ") is null") -#define uassert_in_range(value, min, max) \ - do { \ - double _value = (value); \ - double _min = (min); \ - double _max = (max); \ - __utest_assert((_value >= _min) && (_value <= _max), "(" #value ") not in range("#min","#max")"); \ - } while(0) - -#define uassert_not_in_range(value, min, max) \ - do { \ - double _value = (value); \ - double _min = (min); \ - double _max = (max); \ - __utest_assert((_value < _min) || (_value > _max), "(" #value ") in range("#min","#max")"); \ - } while(0) - -#define uassert_float_equal(a, b) \ - do { \ - double _a = (a); \ - double _b = (b); \ - uassert_in_range(_a, ((double)_b - 0.0001), ((double)_b + 0.0001)); \ - } while(0) - -#define uassert_float_not_equal(a, b) \ - do { \ - double _a = (a); \ - double _b = (b); \ - uassert_not_in_range(_a, ((double)_b - 0.0001), ((double)_b + 0.0001)); \ - } while(0) - -#define uassert_int_equal(a, b) __uassert_value_op(a, b, ==) -#define uassert_int_not_equal(a, b) __uassert_value_op(a, b, !=) - -#define uassert_value_less(a, b) __uassert_value_op(a, b, <) -#define uassert_value_less_equal(a, b) __uassert_value_op(a, b, <=) -#define uassert_value_greater(a, b) __uassert_value_op(a, b, >) -#define uassert_value_greater_equal(a, b) __uassert_value_op(a, b, >=) - -#define uassert_ptr_equal(a, b) __utest_assert((const void*)(a) == (const void*)(b), "(" #a ") not equal to (" #b ")") -#define uassert_ptr_not_equal(a, b) __utest_assert((const void*)(a) != (const void*)(b), "(" #a ") equal to (" #b ")") +#define uassert_int_equal(a, b) __utest_assert((a) == (b), "(" #a ") not equal to (" #b ")") +#define uassert_int_not_equal(a, b) __utest_assert((a) != (b), "(" #a ") equal to (" #b ")") #define uassert_str_equal(a, b) utest_assert_string((const char*)(a), (const char*)(b), RT_TRUE, __FILE__, __LINE__, __func__, "string not equal") #define uassert_str_not_equal(a, b) utest_assert_string((const char*)(a), (const char*)(b), RT_FALSE, __FILE__, __LINE__, __func__, "string equal") @@ -109,6 +62,9 @@ void utest_assert_buf(const char *a, const char *b, rt_size_t sz, rt_bool_t equa #define uassert_buf_equal(a, b, sz) utest_assert_buf((const char*)(a), (const char*)(b), (sz), RT_TRUE, __FILE__, __LINE__, __func__, "buf not equal") #define uassert_buf_not_equal(a, b, sz) utest_assert_buf((const char*)(a), (const char*)(b), (sz), RT_FALSE, __FILE__, __LINE__, __func__, "buf equal") +#define uassert_in_range(value, min, max) __utest_assert(((value >= min) && (value <= max)), "(" #value ") not in range("#min","#max")") +#define uassert_not_in_range(value, min, max) __utest_assert(!((value >= min) && (value <= max)), "(" #value ") in range("#min","#max")") + #ifdef __cplusplus } #endif diff --git a/rt-thread/components/utilities/utest/utest_log.h b/rt-thread/components/utilities/utest/utest_log.h index e39d0d9..6aa5438 100644 --- a/rt-thread/components/utilities/utest/utest_log.h +++ b/rt-thread/components/utilities/utest/utest_log.h @@ -13,12 +13,12 @@ #include -// #define UTEST_DEBUG +#define UTEST_DEBUG #undef DBG_TAG #undef DBG_LVL -#define DBG_TAG "utest" +#define DBG_TAG "testcase" #ifdef UTEST_DEBUG #define DBG_LVL DBG_LOG #else diff --git a/rt-thread/components/utilities/ymodem/ry_sy.c b/rt-thread/components/utilities/ymodem/ry_sy.c index 4bbf816..89664f1 100644 --- a/rt-thread/components/utilities/ymodem/ry_sy.c +++ b/rt-thread/components/utilities/ymodem/ry_sy.c @@ -46,6 +46,7 @@ static enum rym_code _rym_recv_begin( rt_size_t len) { struct custom_ctx *cctx = (struct custom_ctx *)ctx; + struct stat file_buf; char insert_0 = '\0'; char *ret; rt_err_t err; @@ -63,7 +64,7 @@ static enum rym_code _rym_recv_begin( cctx->fd = open(cctx->fpath, O_CREAT | O_WRONLY | O_TRUNC, 0); if (cctx->fd < 0) { - err = rt_get_errno(); + rt_err_t err = rt_get_errno(); rt_kprintf("error creating file: %d\n", err); return RYM_CODE_CAN; } diff --git a/rt-thread/components/utilities/ymodem/ymodem.c b/rt-thread/components/utilities/ymodem/ymodem.c index fefa9fe..f554d81 100644 --- a/rt-thread/components/utilities/ymodem/ymodem.c +++ b/rt-thread/components/utilities/ymodem/ymodem.c @@ -500,8 +500,8 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx) else return -RYM_ERR_CODE; - i = _rym_read_data(ctx, data_sz - 1); - if (i != (data_sz - 1)) + i = _rym_read_data(ctx, _RYM_SOH_PKG_SZ - 1); + if (i != (_RYM_SOH_PKG_SZ - 1)) return -RYM_ERR_DSZ; /* sanity check @@ -509,8 +509,8 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx) if (ctx->buf[1] != 0 || ctx->buf[2] != 0xFF) return -RYM_ERR_SEQ; - recv_crc = (rt_uint16_t)(*(ctx->buf + data_sz - 2) << 8) | *(ctx->buf + data_sz - 1); - if (recv_crc != CRC16(ctx->buf + 3, data_sz - 5)) + recv_crc = (rt_uint16_t)(*(ctx->buf + _RYM_SOH_PKG_SZ - 2) << 8) | *(ctx->buf + _RYM_SOH_PKG_SZ - 1); + if (recv_crc != CRC16(ctx->buf + 3, _RYM_SOH_PKG_SZ - 5)) return -RYM_ERR_CRC; /*next file transmission*/ diff --git a/rt-thread/include/klibc/kerrno.h b/rt-thread/include/klibc/kerrno.h deleted file mode 100644 index 55209d9..0000000 --- a/rt-thread/include/klibc/kerrno.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-09-22 Meco Man the first version - */ - -#ifndef __RT_KERRNO_H__ -#define __RT_KERRNO_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(RT_USING_LIBC) && !defined(RT_USING_NANO) -/* POSIX error code compatible */ -#define RT_EOK 0 /**< There is no error */ -#define RT_ERROR 255 /**< A generic/unknown error happens */ -#define RT_ETIMEOUT ETIMEDOUT /**< Timed out */ -#define RT_EFULL ENOSPC /**< The resource is full */ -#define RT_EEMPTY ENODATA /**< The resource is empty */ -#define RT_ENOMEM ENOMEM /**< No memory */ -#define RT_ENOSYS ENOSYS /**< Function not implemented */ -#define RT_EBUSY EBUSY /**< Busy */ -#define RT_EIO EIO /**< IO error */ -#define RT_EINTR EINTR /**< Interrupted system call */ -#define RT_EINVAL EINVAL /**< Invalid argument */ -#define RT_ENOENT ENOENT /**< No entry */ -#define RT_ENOSPC ENOSPC /**< No space left */ -#define RT_EPERM EPERM /**< Operation not permitted */ -#define RT_EFAULT EFAULT /**< Bad address */ -#define RT_ENOBUFS ENOBUFS /**< No buffer space is available */ -#define RT_ESCHEDISR 253 /**< scheduler failure in isr context */ -#define RT_ESCHEDLOCKED 252 /**< scheduler failure in critical region */ -#define RT_ETRAP 254 /**< Trap event */ -#else -#define RT_EOK 0 /**< There is no error */ -#define RT_ERROR 1 /**< A generic/unknown error happens */ -#define RT_ETIMEOUT 2 /**< Timed out */ -#define RT_EFULL 3 /**< The resource is full */ -#define RT_EEMPTY 4 /**< The resource is empty */ -#define RT_ENOMEM 5 /**< No memory */ -#define RT_ENOSYS 6 /**< Function not implemented */ -#define RT_EBUSY 7 /**< Busy */ -#define RT_EIO 8 /**< IO error */ -#define RT_EINTR 9 /**< Interrupted system call */ -#define RT_EINVAL 10 /**< Invalid argument */ -#define RT_ENOENT 11 /**< No entry */ -#define RT_ENOSPC 12 /**< No space left */ -#define RT_EPERM 13 /**< Operation not permitted */ -#define RT_ETRAP 14 /**< Trap event */ -#define RT_EFAULT 15 /**< Bad address */ -#define RT_ENOBUFS 16 /**< No buffer space is available */ -#define RT_ESCHEDISR 17 /**< scheduler failure in isr context */ -#define RT_ESCHEDLOCKED 18 /**< scheduler failure in critical region */ -#endif /* defined(RT_USING_LIBC) && !defined(RT_USING_NANO) */ - -rt_err_t rt_get_errno(void); -void rt_set_errno(rt_err_t no); -int *_rt_errno(void); -const char *rt_strerror(rt_err_t error); -#if !defined(RT_USING_NEWLIBC) && !defined(_WIN32) -#ifndef errno -#define errno *_rt_errno() -#endif -#endif /* !defined(RT_USING_NEWLIBC) && !defined(_WIN32) */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/include/klibc/kstdio.h b/rt-thread/include/klibc/kstdio.h deleted file mode 100644 index 3eee8fa..0000000 --- a/rt-thread/include/klibc/kstdio.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-09-22 Meco Man the first version - */ - -#ifndef __RT_KSTDIO_H__ -#define __RT_KSTDIO_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int rt_vsprintf(char *dest, const char *format, va_list arg_ptr); -int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args); -int rt_sprintf(char *buf, const char *format, ...); -int rt_snprintf(char *buf, rt_size_t size, const char *format, ...); -int rt_vsscanf(const char *buffer, const char *format, va_list ap); -int rt_sscanf(const char *str, const char *format, ...); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/include/klibc/kstring.h b/rt-thread/include/klibc/kstring.h deleted file mode 100644 index fc6c3bf..0000000 --- a/rt-thread/include/klibc/kstring.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-09-22 Meco Man the first version - */ - -#ifndef __RT_KSTRING_H__ -#define __RT_KSTRING_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void *rt_memset(void *src, int c, rt_ubase_t n); -void *rt_memcpy(void *dest, const void *src, rt_ubase_t n); -void *rt_memmove(void *dest, const void *src, rt_size_t n); -rt_int32_t rt_memcmp(const void *cs, const void *ct, rt_size_t count); - -char *rt_strdup(const char *s); -rt_size_t rt_strnlen(const char *s, rt_ubase_t maxlen); -char *rt_strstr(const char *str1, const char *str2); -rt_int32_t rt_strcasecmp(const char *a, const char *b); -char *rt_strcpy(char *dst, const char *src); -char *rt_strncpy(char *dest, const char *src, rt_size_t n); -rt_int32_t rt_strncmp(const char *cs, const char *ct, rt_size_t count); -rt_int32_t rt_strcmp(const char *cs, const char *ct); -rt_size_t rt_strlen(const char *src); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/rt-thread/include/rtatomic.h b/rt-thread/include/rtatomic.h index 4719339..5363ee5 100644 --- a/rt-thread/include/rtatomic.h +++ b/rt-thread/include/rtatomic.h @@ -27,7 +27,20 @@ void rt_hw_atomic_flag_clear(volatile rt_atomic_t *ptr); rt_atomic_t rt_hw_atomic_flag_test_and_set(volatile rt_atomic_t *ptr); rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_atomic_t *expected, rt_atomic_t desired); -#if defined(RT_USING_STDC_ATOMIC) +#if defined(RT_USING_HW_ATOMIC) +#define rt_atomic_load(ptr) rt_hw_atomic_load(ptr) +#define rt_atomic_store(ptr, v) rt_hw_atomic_store(ptr, v) +#define rt_atomic_add(ptr, v) rt_hw_atomic_add(ptr, v) +#define rt_atomic_sub(ptr, v) rt_hw_atomic_sub(ptr, v) +#define rt_atomic_and(ptr, v) rt_hw_atomic_and(ptr, v) +#define rt_atomic_or(ptr, v) rt_hw_atomic_or(ptr, v) +#define rt_atomic_xor(ptr, v) rt_hw_atomic_xor(ptr, v) +#define rt_atomic_exchange(ptr, v) rt_hw_atomic_exchange(ptr, v) +#define rt_atomic_flag_clear(ptr) rt_hw_atomic_flag_clear(ptr) +#define rt_atomic_flag_test_and_set(ptr) rt_hw_atomic_flag_test_and_set(ptr) +#define rt_atomic_compare_exchange_strong(ptr, v,des) rt_hw_atomic_compare_exchange_strong(ptr, v ,des) + +#elif defined(RT_USING_STDC_ATOMIC) #ifndef __STDC_NO_ATOMICS__ #define rt_atomic_load(ptr) atomic_load(ptr) @@ -45,19 +58,6 @@ rt_atomic_t rt_hw_atomic_compare_exchange_strong(volatile rt_atomic_t *ptr, rt_a #error "The standard library C doesn't support the atomic operation" #endif /* __STDC_NO_ATOMICS__ */ -#elif defined(RT_USING_HW_ATOMIC) -#define rt_atomic_load(ptr) rt_hw_atomic_load(ptr) -#define rt_atomic_store(ptr, v) rt_hw_atomic_store(ptr, v) -#define rt_atomic_add(ptr, v) rt_hw_atomic_add(ptr, v) -#define rt_atomic_sub(ptr, v) rt_hw_atomic_sub(ptr, v) -#define rt_atomic_and(ptr, v) rt_hw_atomic_and(ptr, v) -#define rt_atomic_or(ptr, v) rt_hw_atomic_or(ptr, v) -#define rt_atomic_xor(ptr, v) rt_hw_atomic_xor(ptr, v) -#define rt_atomic_exchange(ptr, v) rt_hw_atomic_exchange(ptr, v) -#define rt_atomic_flag_clear(ptr) rt_hw_atomic_flag_clear(ptr) -#define rt_atomic_flag_test_and_set(ptr) rt_hw_atomic_flag_test_and_set(ptr) -#define rt_atomic_compare_exchange_strong(ptr, v,des) rt_hw_atomic_compare_exchange_strong(ptr, v ,des) - #else #include #define rt_atomic_load(ptr) rt_soft_atomic_load(ptr) @@ -203,7 +203,7 @@ rt_inline rt_atomic_t rt_soft_atomic_compare_exchange_strong(volatile rt_atomic_ rt_inline rt_bool_t rt_atomic_dec_and_test(volatile rt_atomic_t *ptr) { - return rt_atomic_sub(ptr, 1) == 1; + return rt_atomic_sub(ptr, 1) == 0; } rt_inline rt_atomic_t rt_atomic_fetch_add_unless(volatile rt_atomic_t *ptr, rt_atomic_t a, rt_atomic_t u) @@ -230,39 +230,6 @@ rt_inline rt_bool_t rt_atomic_inc_not_zero(volatile rt_atomic_t *ptr) return rt_atomic_add_unless(ptr, 1, 0); } -/** - * @brief initialize a lock-less single list - * - * @param l the single list to be initialized - */ -rt_inline void rt_ll_slist_init(rt_ll_slist_t *l) -{ - l->next = 0; -} - -rt_inline void rt_ll_slist_enqueue(rt_ll_slist_t *l, rt_ll_slist_t *n) -{ - rt_base_t exp; - exp = rt_atomic_load(&l->next); - do - { - n->next = exp; - } while (!rt_atomic_compare_exchange_strong(&l->next, &exp, (rt_base_t)n)); -} - -rt_inline rt_ll_slist_t *rt_ll_slist_dequeue(rt_ll_slist_t *l) -{ - rt_base_t exp; - rt_ll_slist_t *head; - - exp = rt_atomic_load(&l->next); - do - { - head = (rt_ll_slist_t *)exp; - } while (head && !rt_atomic_compare_exchange_strong(&l->next, &exp, rt_atomic_load(&head->next))); - return head; -} - #endif /* __cplusplus */ #endif /* __RT_ATOMIC_H__ */ diff --git a/rt-thread/include/rtcompiler.h b/rt-thread/include/rtcompiler.h index 121f084..bf1da29 100644 --- a/rt-thread/include/rtcompiler.h +++ b/rt-thread/include/rtcompiler.h @@ -16,11 +16,6 @@ #define rt_section(x) __attribute__((section(x))) #define rt_used __attribute__((used)) #define rt_align(n) __attribute__((aligned(n))) -#if __ARMCC_VERSION >= 6010050 -#define rt_packed(declare) declare __attribute__((packed)) -#else -#define rt_packed(declare) declare -#endif #define rt_weak __attribute__((weak)) #define rt_typeof typeof #define rt_noreturn @@ -31,7 +26,6 @@ #define rt_used __root #define PRAGMA(x) _Pragma(#x) #define rt_align(n) PRAGMA(data_alignment=n) -#define rt_packed(declare) declare #define rt_weak __weak #define rt_typeof __typeof #define rt_noreturn @@ -43,7 +37,6 @@ #define rt_section(x) __attribute__((section(x))) #define rt_used __attribute__((used)) #define rt_align(n) __attribute__((aligned(n))) -#define rt_packed(declare) declare __attribute__((packed)) #define rt_weak __attribute__((weak)) #define rt_typeof __typeof__ #define rt_noreturn __attribute__ ((noreturn)) @@ -53,7 +46,6 @@ #define rt_section(x) __attribute__((section(x))) #define rt_used __attribute__((used)) #define rt_align(n) __attribute__((aligned(n))) -#define rt_packed(declare) declare #define rt_weak __attribute__((weak)) #define rt_typeof typeof #define rt_noreturn @@ -63,7 +55,6 @@ #define rt_section(x) #define rt_used #define rt_align(n) __declspec(align(n)) -#define rt_packed(declare) __pragma(pack(push, 1)) declare __pragma(pack(pop)) #define rt_weak #define rt_typeof typeof #define rt_noreturn @@ -83,7 +74,6 @@ #endif #define PRAGMA(x) _Pragma(#x) #define rt_align(n) __attribute__((aligned(n))) -#define rt_packed(declare) declare __attribute__((packed)) #ifdef __TI_EABI__ #define rt_weak __attribute__((weak)) #else @@ -98,7 +88,6 @@ #define rt_used __attribute__((used, protect)) #define PRAGMA(x) _Pragma(#x) #define rt_align(n) __attribute__((__align(n))) -#define rt_packed(declare) declare __packed__ #define rt_weak __attribute__((weak)) #define rt_typeof typeof #define rt_noreturn diff --git a/rt-thread/include/rtdbg.h b/rt-thread/include/rtdbg.h index 080c722..10331ed 100644 --- a/rt-thread/include/rtdbg.h +++ b/rt-thread/include/rtdbg.h @@ -113,6 +113,32 @@ extern "C" { rt_kprintf("\n") #endif /* DBG_COLOR */ +/* + * static debug routine + * NOTE: This is a NOT RECOMMENDED API. Please using LOG_X API. + * It will be DISCARDED later. Because it will take up more resources. + */ +#define dbg_log(level, fmt, ...) \ + if ((level) <= DBG_LEVEL) \ + { \ + switch(level) \ + { \ + case DBG_ERROR: _DBG_LOG_HDR("E", 31); break; \ + case DBG_WARNING: _DBG_LOG_HDR("W", 33); break; \ + case DBG_INFO: _DBG_LOG_HDR("I", 32); break; \ + case DBG_LOG: _DBG_LOG_HDR("D", 0); break; \ + default: break; \ + } \ + rt_kprintf(fmt, ##__VA_ARGS__); \ + _DBG_COLOR(0); \ + } + +#define dbg_here \ + if ((DBG_LEVEL) <= DBG_LOG){ \ + rt_kprintf(DBG_SECTION_NAME " Here %s:%d\n", \ + __FUNCTION__, __LINE__); \ + } + #define dbg_log_line(lvl, color_n, fmt, ...) \ do \ { \ @@ -125,6 +151,10 @@ extern "C" { #define dbg_raw(...) rt_kprintf(__VA_ARGS__); #else +#define dbg_log(level, fmt, ...) +#define dbg_here +#define dbg_enter +#define dbg_exit #define dbg_log_line(lvl, color_n, fmt, ...) #define dbg_raw(...) #endif /* DBG_ENABLE */ diff --git a/rt-thread/include/rtdef.h b/rt-thread/include/rtdef.h index 05c59f8..6985bb8 100644 --- a/rt-thread/include/rtdef.h +++ b/rt-thread/include/rtdef.h @@ -68,8 +68,6 @@ #include "rtsched.h" #include "rttypes.h" -#include "klibc/kerrno.h" - #ifdef __cplusplus extern "C" { #endif @@ -86,11 +84,12 @@ extern "C" { #define RT_VERSION_PATCH 0 /**< Patch version number (x.x.X) */ /* e.g. #if (RTTHREAD_VERSION >= RT_VERSION_CHECK(4, 1, 0) */ -#define RT_VERSION_CHECK(major, minor, revise) ((major * 10000U) + (minor * 100U) + revise) +#define RT_VERSION_CHECK(major, minor, revise) ((major * 10000) + (minor * 100) + revise) /* RT-Thread version */ #define RTTHREAD_VERSION RT_VERSION_CHECK(RT_VERSION_MAJOR, RT_VERSION_MINOR, RT_VERSION_PATCH) + /**@}*/ /* maximum value of base type */ @@ -100,10 +99,10 @@ extern "C" { #define RT_UINT32_MAX UINT32_MAX /**< Maximum number of UINT32 */ #define RT_UINT64_MAX UINT64_MAX /**< Maximum number of UINT64 */ #else -#define RT_UINT8_MAX 0xFFU /**< Maximum number of UINT8 */ -#define RT_UINT16_MAX 0xFFFFU /**< Maximum number of UINT16 */ -#define RT_UINT32_MAX 0xFFFFFFFFUL /**< Maximum number of UINT32 */ -#define RT_UINT64_MAX 0xFFFFFFFFFFFFFFFFULL /**< Maximum number of UINT64 */ +#define RT_UINT8_MAX 0xff /**< Maximum number of UINT8 */ +#define RT_UINT16_MAX 0xffff /**< Maximum number of UINT16 */ +#define RT_UINT32_MAX 0xffffffff /**< Maximum number of UINT32 */ +#define RT_UINT64_MAX 0xffffffffffffffff #endif /* RT_USING_LIBC */ #define RT_TICK_MAX RT_UINT32_MAX /**< Maximum number of tick */ @@ -117,7 +116,7 @@ extern "C" { /* Common Utilities */ -#define RT_UNUSED(x) ((void)(x)) +#define RT_UNUSED(x) ((void)x) /* compile time assertion */ #define RT_STATIC_ASSERT(name, expn) typedef char _static_assert_##name[(expn)?1:-1] @@ -180,10 +179,15 @@ typedef int (*init_fn_t)(void); /* init cpu, memory, interrupt-controller, bus... */ #define INIT_CORE_EXPORT(fn) INIT_EXPORT(fn, "1.0") -/* init sys-timer, clk, pinctrl... */ -#define INIT_SUBSYS_EXPORT(fn) INIT_EXPORT(fn, "1.1") +/* init pci/pcie, usb platform driver... */ +#define INIT_FRAMEWORK_EXPORT(fn) INIT_EXPORT(fn, "1.1") /* init platform, user code... */ #define INIT_PLATFORM_EXPORT(fn) INIT_EXPORT(fn, "1.2") +/* init sys-timer, clk, pinctrl... */ +#define INIT_SUBSYS_EARLY_EXPORT(fn) INIT_EXPORT(fn, "1.3.0") +#define INIT_SUBSYS_EXPORT(fn) INIT_EXPORT(fn, "1.3.1") +/* init early drivers */ +#define INIT_DRIVER_EARLY_EXPORT(fn) INIT_EXPORT(fn, "1.4") /* pre/device/component/env/app init routines will be called in init_thread */ /* components pre-initialization (pure software initialization) */ @@ -234,6 +238,58 @@ typedef int (*init_fn_t)(void); #define RT_KERNEL_REALLOC(ptr, size) rt_realloc(ptr, size) #endif /* RT_KERNEL_REALLOC */ +/** + * @addtogroup Error + */ + +/**@{*/ + +/* RT-Thread error code definitions */ +#if defined(RT_USING_LIBC) && !defined(RT_USING_NANO) +/* POSIX error code compatible */ +#define RT_EOK 0 /**< There is no error */ +#define RT_ERROR 255 /**< A generic/unknown error happens */ +#define RT_ETIMEOUT ETIMEDOUT /**< Timed out */ +#define RT_EFULL ENOSPC /**< The resource is full */ +#define RT_EEMPTY ENODATA /**< The resource is empty */ +#define RT_ENOMEM ENOMEM /**< No memory */ +#define RT_ENOSYS ENOSYS /**< Function not implemented */ +#define RT_EBUSY EBUSY /**< Busy */ +#define RT_EIO EIO /**< IO error */ +#define RT_EINTR EINTR /**< Interrupted system call */ +#define RT_EINVAL EINVAL /**< Invalid argument */ +#define RT_ENOENT ENOENT /**< No entry */ +#define RT_ENOSPC ENOSPC /**< No space left */ +#define RT_EPERM EPERM /**< Operation not permitted */ +#define RT_EFAULT EFAULT /**< Bad address */ +#define RT_ENOBUFS ENOBUFS /**< No buffer space is available */ +#define RT_ESCHEDISR 253 /**< scheduler failure in isr context */ +#define RT_ESCHEDLOCKED 252 /**< scheduler failure in critical region */ +#define RT_ETRAP 254 /**< Trap event */ +#else +#define RT_EOK 0 /**< There is no error */ +#define RT_ERROR 1 /**< A generic/unknown error happens */ +#define RT_ETIMEOUT 2 /**< Timed out */ +#define RT_EFULL 3 /**< The resource is full */ +#define RT_EEMPTY 4 /**< The resource is empty */ +#define RT_ENOMEM 5 /**< No memory */ +#define RT_ENOSYS 6 /**< Function not implemented */ +#define RT_EBUSY 7 /**< Busy */ +#define RT_EIO 8 /**< IO error */ +#define RT_EINTR 9 /**< Interrupted system call */ +#define RT_EINVAL 10 /**< Invalid argument */ +#define RT_ENOENT 11 /**< No entry */ +#define RT_ENOSPC 12 /**< No space left */ +#define RT_EPERM 13 /**< Operation not permitted */ +#define RT_ETRAP 14 /**< Trap event */ +#define RT_EFAULT 15 /**< Bad address */ +#define RT_ENOBUFS 16 /**< No buffer space is available */ +#define RT_ESCHEDISR 17 /**< scheduler failure in isr context */ +#define RT_ESCHEDLOCKED 18 /**< scheduler failure in critical region */ +#endif /* defined(RT_USING_LIBC) && !defined(RT_USING_NANO) */ + +/**@}*/ + /** * @ingroup BasicDef * @@ -669,12 +725,6 @@ typedef struct rt_cpu_usage_stats *rt_cpu_usage_stats_t; #define RT_STOP_IPI 1 #endif /* RT_STOP_IPI */ -#ifndef RT_SMP_CALL_IPI -#define RT_SMP_CALL_IPI 2 -#endif - -#define RT_MAX_IPI 3 - #define _SCHEDULER_CONTEXT(fileds) fileds /** @@ -718,9 +768,6 @@ struct rt_cpu #ifdef RT_USING_CPU_USAGE_TRACER struct rt_cpu_usage_stats cpu_stat; #endif /* RT_USING_CPU_USAGE_TRACER */ -#ifdef ARCH_USING_IRQ_CTX_LIST - rt_slist_t irq_ctx_head; -#endif /* ARCH_USING_IRQ_CTX_LIST */ }; #else /* !RT_USING_SMP */ @@ -732,9 +779,6 @@ struct rt_cpu #ifdef RT_USING_CPU_USAGE_TRACER struct rt_cpu_usage_stats cpu_stat; #endif /* RT_USING_CPU_USAGE_TRACER */ -#ifdef ARCH_USING_IRQ_CTX_LIST - rt_slist_t irq_ctx_head; -#endif /* ARCH_USING_IRQ_CTX_LIST */ }; #endif /* RT_USING_SMP */ @@ -745,16 +789,6 @@ typedef struct rt_cpu *rt_cpu_t; struct rt_thread; -/** - * interrupt/exception frame handling - * - */ - -typedef struct rt_interrupt_context { - void *context; /**< arch specific context */ - rt_slist_t node; /**< node for nested interrupt */ -} *rt_interrupt_context_t; - #ifdef RT_USING_SMART typedef rt_err_t (*rt_wakeup_func_t)(void *object, struct rt_thread *thread); @@ -1378,9 +1412,6 @@ struct rt_device void *ofw_node; /**< ofw node get from device tree */ #endif /* RT_USING_OFW */ void *power_domain_unit; -#ifdef RT_USING_DMA - const void *dma_ops; -#endif #endif /* RT_USING_DM */ enum rt_device_class_type type; /**< device type */ @@ -1388,9 +1419,6 @@ struct rt_device rt_uint16_t open_flag; /**< device open flag */ rt_uint8_t ref_count; /**< reference count */ -#ifdef RT_USING_DM - rt_uint8_t master_id; /**< 0 - 255 */ -#endif rt_uint8_t device_id; /**< 0 - 255 */ /* device call back */ diff --git a/rt-thread/include/rthw.h b/rt-thread/include/rthw.h index 672e820..f7712cb 100644 --- a/rt-thread/include/rthw.h +++ b/rt-thread/include/rthw.h @@ -172,8 +172,8 @@ void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to, rt_thread_t * Hardware Layer Backtrace Service */ struct rt_hw_backtrace_frame { - rt_uintptr_t fp; - rt_uintptr_t pc; + rt_base_t fp; + rt_base_t pc; }; rt_err_t rt_hw_backtrace_frame_get(rt_thread_t thread, struct rt_hw_backtrace_frame *frame); diff --git a/rt-thread/include/rtklibc.h b/rt-thread/include/rtklibc.h index 1577c20..52fd8b9 100644 --- a/rt-thread/include/rtklibc.h +++ b/rt-thread/include/rtklibc.h @@ -14,8 +14,44 @@ #include #include -#include "klibc/kstring.h" -#include "klibc/kstdio.h" -#include "klibc/kerrno.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* kstdio */ +int rt_vsprintf(char *dest, const char *format, va_list arg_ptr); +int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args); +int rt_sprintf(char *buf, const char *format, ...); +int rt_snprintf(char *buf, rt_size_t size, const char *format, ...); + +rt_err_t rt_get_errno(void); +void rt_set_errno(rt_err_t no); +int *_rt_errno(void); +const char *rt_strerror(rt_err_t error); +#if !defined(RT_USING_NEWLIBC) && !defined(_WIN32) +#ifndef errno +#define errno *_rt_errno() +#endif +#endif /* !defined(RT_USING_NEWLIBC) && !defined(_WIN32) */ + +/* kstring */ + +void *rt_memset(void *src, int c, rt_ubase_t n); +void *rt_memcpy(void *dest, const void *src, rt_ubase_t n); +void *rt_memmove(void *dest, const void *src, rt_size_t n); +rt_int32_t rt_memcmp(const void *cs, const void *ct, rt_size_t count); +char *rt_strdup(const char *s); +rt_size_t rt_strnlen(const char *s, rt_ubase_t maxlen); +char *rt_strstr(const char *str1, const char *str2); +rt_int32_t rt_strcasecmp(const char *a, const char *b); +char *rt_strcpy(char *dst, const char *src); +char *rt_strncpy(char *dest, const char *src, rt_size_t n); +rt_int32_t rt_strncmp(const char *cs, const char *ct, rt_size_t count); +rt_int32_t rt_strcmp(const char *cs, const char *ct); +rt_size_t rt_strlen(const char *src); + +#ifdef __cplusplus +} +#endif #endif /* __RT_KLIBC_H__ */ diff --git a/rt-thread/include/rtsched.h b/rt-thread/include/rtsched.h index 01951a2..786ca8b 100644 --- a/rt-thread/include/rtsched.h +++ b/rt-thread/include/rtsched.h @@ -5,7 +5,7 @@ * * Change Logs: * Date Author Notes - * 2024-01-19 Shell Separate scheduling statements from rt_thread_t + * 2024-01-19 Shell Seperate schduling statements from rt_thread_t * to rt_sched_thread_ctx. Add definitions of scheduler. */ #ifndef __RT_SCHED_H__ @@ -22,6 +22,8 @@ struct rt_thread; typedef rt_uint8_t rt_sched_thread_status_t; +#ifdef RT_USING_SCHED_THREAD_CTX + /** * Scheduler private status binding on thread. Caller should never accessing * these members. @@ -83,6 +85,43 @@ struct rt_sched_thread_ctx struct rt_thread, sched_thread_ctx) #define RT_THREAD_LIST_NODE(thread) (RT_SCHED_CTX(thread).thread_list_node) +#else /* !defined(RT_USING_SCHED_THREAD_CTX) */ + +#if RT_THREAD_PRIORITY_MAX > 32 +#define _RT_SCHED_THREAD_CTX_PRIO_EXT \ + rt_uint8_t number; /**< priority low number */ \ + rt_uint8_t high_mask; /**< priority high mask */ + +#else /* ! RT_THREAD_PRIORITY_MAX > 32 */ + +#define _RT_SCHED_THREAD_CTX_PRIO_EXT +#endif /* RT_THREAD_PRIORITY_MAX > 32 */ + +#define RT_SCHED_THREAD_CTX \ + rt_list_t tlist; /**< node in thread list */ \ + rt_uint8_t stat; /**< thread status */ \ + rt_uint8_t sched_flag_locked:1; \ + /**< calling thread have the scheduler locked */ \ + rt_uint8_t sched_flag_ttmr_set:1; /**< thread timer is start */ \ + rt_tick_t init_tick; /**< thread's initialized tick */ \ + rt_tick_t remaining_tick; /**< remaining tick */ \ + rt_uint8_t current_priority; /**< current priority */ \ + rt_uint8_t init_priority; /**< initialized priority */ \ + _RT_SCHED_THREAD_CTX_PRIO_EXT \ + rt_uint32_t number_mask; /**< priority number mask */ + +#define RT_SCHED_PRIV(thread) (*thread) +#define RT_SCHED_CTX(thread) (*thread) + +/** + * Convert a list node in container RT_SCHED_CTX(thread)->thread_list_node + * to a thread pointer. + */ +#define RT_THREAD_LIST_NODE_ENTRY(node) rt_list_entry((node), struct rt_thread, tlist) +#define RT_THREAD_LIST_NODE(thread) (RT_SCHED_CTX(thread).tlist) + +#endif /* RT_USING_SCHED_THREAD_CTX */ + /** * System Scheduler Locking */ @@ -118,7 +157,7 @@ void rt_sched_thread_startup(struct rt_thread *thread); /* scheduler related routine */ void rt_sched_post_ctx_switch(struct rt_thread *thread); -rt_err_t rt_sched_tick_increase(rt_tick_t tick); +rt_err_t rt_sched_tick_increase(void); /* thread status operation */ rt_uint8_t rt_sched_thread_get_stat(struct rt_thread *thread); diff --git a/rt-thread/include/rtservice.h b/rt-thread/include/rtservice.h index a5b15ed..993b95d 100644 --- a/rt-thread/include/rtservice.h +++ b/rt-thread/include/rtservice.h @@ -11,7 +11,6 @@ * 2012-03-22 Bernard rename kservice.h to rtservice.h * 2017-11-15 JasonJia Modify rt_slist_foreach to rt_slist_for_each_entry. * Make code cleanup. - * 2024-01-03 Shell add rt_slist_pop() */ #ifndef __RT_SERVICE_H__ @@ -225,20 +224,6 @@ rt_inline unsigned int rt_slist_len(const rt_slist_t *l) return len; } -rt_inline rt_slist_t *rt_slist_pop(rt_slist_t *l) -{ - struct rt_slist_node *node = l; - - /* remove node */ - node = node->next; - if (node != (rt_slist_t *)0) - { - ((struct rt_slist_node *)l)->next = node->next; - } - - return node; -} - rt_inline rt_slist_t *rt_slist_remove(rt_slist_t *l, rt_slist_t *n) { /* remove slist head */ diff --git a/rt-thread/include/rtthread.h b/rt-thread/include/rtthread.h index 69dcdff..517d3da 100644 --- a/rt-thread/include/rtthread.h +++ b/rt-thread/include/rtthread.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -100,7 +100,6 @@ void rt_object_put_sethook(void (*hook)(struct rt_object *object)); rt_tick_t rt_tick_get(void); void rt_tick_set(rt_tick_t tick); void rt_tick_increase(void); -void rt_tick_increase_tick(rt_tick_t tick); rt_tick_t rt_tick_from_millisecond(rt_int32_t ms); rt_tick_t rt_tick_get_millisecond(void); #ifdef RT_USING_HOOK @@ -641,10 +640,8 @@ rt_ssize_t rt_mq_recv_prio(rt_mq_t mq, /**@}*/ /* defunct */ -void rt_thread_defunct_init(void); void rt_thread_defunct_enqueue(rt_thread_t thread); rt_thread_t rt_thread_defunct_dequeue(void); -void rt_defunct_execute(void); /* * spinlock @@ -713,10 +710,6 @@ rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg); void rt_interrupt_enter(void); void rt_interrupt_leave(void); -void rt_interrupt_context_push(rt_interrupt_context_t this_ctx); -void rt_interrupt_context_pop(void); -void *rt_interrupt_context_get(void); - /** * CPU object */ @@ -793,8 +786,6 @@ rt_device_t rt_console_get_device(void); #endif /* defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE) */ int __rt_ffs(int value); -unsigned long __rt_ffsl(unsigned long value); -unsigned long __rt_clz(unsigned long value); void rt_show_version(void); @@ -809,7 +800,7 @@ if (!(EX)) \ rt_assert_handler(#EX, __FUNCTION__, __LINE__); \ } #else -#define RT_ASSERT(EX) {RT_UNUSED(EX);} +#define RT_ASSERT(EX) #endif /* RT_DEBUGING_ASSERT */ #ifdef RT_DEBUGING_CONTEXT diff --git a/rt-thread/include/rttypes.h b/rt-thread/include/rttypes.h index 75bf58d..78d6c63 100644 --- a/rt-thread/include/rttypes.h +++ b/rt-thread/include/rttypes.h @@ -33,6 +33,8 @@ extern "C" { */ typedef int rt_bool_t; /**< boolean type */ +typedef signed long rt_base_t; /**< Nbit CPU related data type */ +typedef unsigned long rt_ubase_t; /**< Nbit unsigned CPU related data type */ #ifndef RT_USING_ARCH_DATA_TYPE #ifdef RT_USING_LIBC @@ -61,24 +63,12 @@ typedef unsigned long long rt_uint64_t; /**< 64bit unsigned inte #endif /* RT_USING_LIBC */ #endif /* RT_USING_ARCH_DATA_TYPE */ -#ifdef ARCH_CPU_64BIT -typedef rt_int64_t rt_base_t; /**< Nbit CPU related data type */ -typedef rt_uint64_t rt_ubase_t; /**< Nbit unsigned CPU related data type */ -#else -typedef rt_int32_t rt_base_t; /**< Nbit CPU related data type */ -typedef rt_uint32_t rt_ubase_t; /**< Nbit unsigned CPU related data type */ -#endif - #if defined(RT_USING_LIBC) && !defined(RT_USING_NANO) typedef size_t rt_size_t; /**< Type for size number */ typedef ssize_t rt_ssize_t; /**< Used for a count of bytes or an error indication */ -typedef intptr_t rt_intptr_t; /**< Type for signed pointer length integer */ -typedef uintptr_t rt_uintptr_t; /**< Type for unsigned pointer length integer */ #else typedef rt_ubase_t rt_size_t; /**< Type for size number */ typedef rt_base_t rt_ssize_t; /**< Used for a count of bytes or an error indication */ -typedef rt_ubase_t rt_intptr_t; /**< Type for signed pointer length integer */ -typedef rt_base_t rt_uintptr_t; /**< Type for unsigned pointer length integer */ #endif /* defined(RT_USING_LIBC) && !defined(RT_USING_NANO) */ typedef rt_base_t rt_err_t; /**< Type for error number */ @@ -88,19 +78,14 @@ typedef rt_base_t rt_flag_t; /**< Type for flags */ typedef rt_ubase_t rt_dev_t; /**< Type for device */ typedef rt_base_t rt_off_t; /**< Type for offset */ -#if defined(RT_USING_STDC_ATOMIC) && __STDC_VERSION__ < 201112L -#undef RT_USING_STDC_ATOMIC -#warning Not using C11 or beyond! Maybe you should change the -std option on your compiler -#endif - #ifdef __cplusplus typedef rt_base_t rt_atomic_t; #else - #if defined(RT_USING_STDC_ATOMIC) - #include - typedef _Atomic(rt_base_t) rt_atomic_t; - #elif defined(RT_USING_HW_ATOMIC) + #if defined(RT_USING_HW_ATOMIC) typedef rt_base_t rt_atomic_t; + #elif defined(RT_USING_STDC_ATOMIC) + #include + typedef atomic_intptr_t rt_atomic_t; #else typedef rt_base_t rt_atomic_t; #endif /* RT_USING_STDC_ATOMIC */ @@ -132,15 +117,6 @@ struct rt_slist_node }; typedef struct rt_slist_node rt_slist_t; /**< Type for single list. */ -/** - * Lock-less Single List structure - */ -struct rt_lockless_slist_node -{ - rt_atomic_t next; /**< point to next node. */ -}; -typedef struct rt_lockless_slist_node rt_ll_slist_t; /**< Type for lock-les single list. */ - /** * Spinlock */ diff --git a/rt-thread/libcpu/Kconfig b/rt-thread/libcpu/Kconfig index 1edace1..2c07f46 100644 --- a/rt-thread/libcpu/Kconfig +++ b/rt-thread/libcpu/Kconfig @@ -1,5 +1,29 @@ if ARCH_ARMV8 && ARCH_CPU_64BIT - orsource "./aarch64/Kconfig" + menu "AArch64 Architecture Configuration" + config ARCH_TEXT_OFFSET + hex "Text offset" + default 0x200000 + config ARCH_RAM_OFFSET + hex "RAM offset" + default 0 + config ARCH_SECONDARY_CPU_STACK_SIZE + int "Secondary CPU stack size" + default 4096 + config ARCH_HAVE_EFFICIENT_UNALIGNED_ACCESS + bool + default y + config ARCH_USING_GENERIC_CPUID + bool "Using generic cpuid implemenation" + select ARCH_USING_HW_THREAD_SELF + default y if RT_USING_OFW + default n + config ARCH_HEAP_SIZE + hex "Size of system heap" + default 0x4000000 + config ARCH_INIT_PAGE_SIZE + hex "Size of init page region" + default 0x200000 + endmenu endif config ARCH_CPU_64BIT @@ -77,7 +101,6 @@ config ARCH_ARM_CORTEX_M7 select ARCH_ARM_CORTEX_M select RT_USING_CPU_FFS select RT_USING_CACHE - select RT_USING_HW_ATOMIC config ARCH_ARM_CORTEX_M85 bool @@ -195,8 +218,6 @@ config ARCH_ARMV8 select ARCH_ARM select ARCH_ARM_MMU select RT_USING_CPU_FFS - select ARCH_USING_ASID - select ARCH_USING_IRQ_CTX_LIST config ARCH_MIPS bool @@ -224,21 +245,6 @@ config ARCH_RISCV config ARCH_RISCV_FPU bool -config ARCH_RISCV_VECTOR - bool - - if ARCH_RISCV_VECTOR - choice - prompt "RISCV Vector Vlen" - default ARCH_VECTOR_VLEN_128 - - config ARCH_VECTOR_VLEN_128 - bool "128" - config ARCH_VECTOR_VLEN_256 - bool "256" - endchoice - endif - config ARCH_RISCV_FPU_S select ARCH_RISCV_FPU bool @@ -256,20 +262,6 @@ config ARCH_RISCV64 select ARCH_CPU_64BIT bool -if ARCH_RISCV64 - config ARCH_USING_NEW_CTX_SWITCH - bool - default y - - config ARCH_USING_RISCV_COMMON64 - bool - depends on ARCH_RISCV64 - select RT_USING_CPUTIME - select ARCH_USING_NEW_CTX_SWITCH - help - Using the common64 implementation under ./libcpu/risc-v -endif - config ARCH_REMAP_KERNEL bool depends on RT_USING_SMART @@ -303,7 +295,3 @@ config ARCH_CPU_STACK_GROWS_UPWARD config ARCH_USING_HW_THREAD_SELF bool default n - -config ARCH_USING_IRQ_CTX_LIST - bool - default n diff --git a/rt-thread/libcpu/arm/AT91SAM7S/interrupt.c b/rt-thread/libcpu/arm/AT91SAM7S/interrupt.c index 8468d36..e4aa864 100644 --- a/rt-thread/libcpu/arm/AT91SAM7S/interrupt.c +++ b/rt-thread/libcpu/arm/AT91SAM7S/interrupt.c @@ -13,7 +13,7 @@ #define MAX_HANDLERS 32 -extern rt_atomic_t rt_interrupt_nest; +extern rt_uint32_t rt_interrupt_nest; rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; diff --git a/rt-thread/libcpu/arm/AT91SAM7X/interrupt.c b/rt-thread/libcpu/arm/AT91SAM7X/interrupt.c index 1d47365..3a28f50 100644 --- a/rt-thread/libcpu/arm/AT91SAM7X/interrupt.c +++ b/rt-thread/libcpu/arm/AT91SAM7X/interrupt.c @@ -18,7 +18,7 @@ /* exception and interrupt handler table */ struct rt_irq_desc irq_desc[MAX_HANDLERS]; -extern rt_atomic_t rt_interrupt_nest; +extern rt_uint32_t rt_interrupt_nest; rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; diff --git a/rt-thread/libcpu/arm/am335x/interrupt.c b/rt-thread/libcpu/arm/am335x/interrupt.c index ca9fe97..1810a92 100644 --- a/rt-thread/libcpu/arm/am335x/interrupt.c +++ b/rt-thread/libcpu/arm/am335x/interrupt.c @@ -19,7 +19,7 @@ #define MAX_HANDLERS 128 -extern volatile rt_atomic_t rt_interrupt_nest; +extern volatile rt_uint8_t rt_interrupt_nest; /* exception and interrupt handler table */ struct rt_irq_desc isr_table[MAX_HANDLERS]; diff --git a/rt-thread/libcpu/arm/cortex-a/backtrace.c b/rt-thread/libcpu/arm/cortex-a/backtrace.c index c9960f2..f9f4457 100644 --- a/rt-thread/libcpu/arm/cortex-a/backtrace.c +++ b/rt-thread/libcpu/arm/cortex-a/backtrace.c @@ -489,7 +489,7 @@ void unwind_backtrace(struct pt_regs *regs, const struct unwind_idx exidx_start[ arm_get_current_stackframe(regs, &frame); #ifndef RT_BACKTRACE_FUNCTION_NAME - rt_kprintf("please use: addr2line -e rtthread.elf -a -f %08x\n", frame.pc); + rt_kprintf("please use: addr2line -e rtthread.elf -a -f %08x", frame.pc); #endif LOG_D("pc = %08x, sp = %08x", frame.pc, frame.sp); diff --git a/rt-thread/libcpu/arm/cortex-m23/cpuport.c b/rt-thread/libcpu/arm/cortex-m23/cpuport.c index c5525d2..20c611a 100644 --- a/rt-thread/libcpu/arm/cortex-m23/cpuport.c +++ b/rt-thread/libcpu/arm/cortex-m23/cpuport.c @@ -14,7 +14,34 @@ #include -#include "cpuport.h" +struct exception_stack_frame +{ + rt_uint32_t r0; + rt_uint32_t r1; + rt_uint32_t r2; + rt_uint32_t r3; + rt_uint32_t r12; + rt_uint32_t lr; + rt_uint32_t pc; + rt_uint32_t psr; +}; + +struct stack_frame +{ + /* r4 ~ r7 low register */ + rt_uint32_t r4; + rt_uint32_t r5; + rt_uint32_t r6; + rt_uint32_t r7; + + /* r8 ~ r11 high register */ + rt_uint32_t r8; + rt_uint32_t r9; + rt_uint32_t r10; + rt_uint32_t r11; + + struct exception_stack_frame exception_stack_frame; +}; /* flag in interrupt handling */ rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; diff --git a/rt-thread/libcpu/arm/cortex-m23/cpuport.h b/rt-thread/libcpu/arm/cortex-m23/cpuport.h deleted file mode 100644 index d5bd764..0000000 --- a/rt-thread/libcpu/arm/cortex-m23/cpuport.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-11-17 RT-Thread first version - */ - -#ifndef __CPUPORT_H__ -#define __CPUPORT_H__ - -#include - -struct exception_stack_frame -{ - rt_uint32_t r0; - rt_uint32_t r1; - rt_uint32_t r2; - rt_uint32_t r3; - rt_uint32_t r12; - rt_uint32_t lr; - rt_uint32_t pc; - rt_uint32_t psr; -}; - -struct stack_frame -{ - /* r4 ~ r7 low register */ - rt_uint32_t r4; - rt_uint32_t r5; - rt_uint32_t r6; - rt_uint32_t r7; - - /* r8 ~ r11 high register */ - rt_uint32_t r8; - rt_uint32_t r9; - rt_uint32_t r10; - rt_uint32_t r11; - - struct exception_stack_frame exception_stack_frame; -}; - -#endif /* __CPUPORT_H__ */ diff --git a/rt-thread/libcpu/arm/cortex-m4/README.md b/rt-thread/libcpu/arm/cortex-m4/README.md deleted file mode 100644 index 05e4b14..0000000 --- a/rt-thread/libcpu/arm/cortex-m4/README.md +++ /dev/null @@ -1,53 +0,0 @@ -## Independent Interrupts Management - -### Introduction -Calling `rt_hw_interrupt_disable` in multiple places on `rt-thread` may cause interruption delays when the application requires accurate interrupt responses. This is because the system cannot generate any interrupts except abnormal interrupts after disabling interrupts. This is a common problem in the interrupt management of the operating system. The independent interrupt management module is designed to solve this problem. - -The independent interrupt management module is designed to solve the problem of interrupt delays caused by calling `rt_hw_interrupt_disable` in multiple places on `rt-thread`. The module is implemented by rewrite the `rt_hw_interrupt_disable` and `rt_hw_interrupt_enable` functions in the `libcpu` library. - - -### Usage -- Add the following code to the project's `board.c` file. -``` -#ifdef RT_USING_INDEPENDENT_INTERRUPT_MANAGEMENT -#define RT_NVIC_PRO_BITS __NVIC_PRIO_BITS - -rt_base_t rt_hw_interrupt_disable(void) -{ - rt_base_t level = __get_BASEPRI(); - __set_BASEPRI(RT_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - RT_NVIC_PRO_BITS)); - - __ISB(); - __DSB(); - - return level; -} - -void rt_hw_interrupt_enable(rt_base_t level) -{ - __set_BASEPRI(level); -} - -#endif /* RT_USING_INDEPENDENT_INTERRUPT_MANAGEMENT */ -``` -- Add the following configuration to the `Kconfig` file in the `board` directory. -``` - menuconfig RT_USING_INDEPENDENT_INTERRUPT_MANAGEMENT - bool "Enable independent interrupt management" - default n - - if RT_USING_INDEPENDENT_INTERRUPT_MANAGEMENT - config RT_MAX_SYSCALL_INTERRUPT_PRIORITY - int "Set max syscall interrupt priority" - range 0 7 - default 2 - endif -``` -- Select `RT_USING_INDEPENDENT_INTERRUPT_MANAGEMENT` to enable this feature. -- Select `RT_MAX_SYSCALL_INTERRUPT_PRIORITY` to set the maximum priority of the interrupt that can be called by the system call. The default value is 2. - -### Description -- The [basepri](https://developer.arm.com/documentation/107706/0100/Exceptions-and-interrupts-overview/Special-registers-for-exception-masking/BASEPRI) register is used in the functions to complete the interrupt management. -- For example, if `RT_MAX_SYSCALL_INTERRUPT_PRIORITY` is set to 0x01, the system masking only interrupts with a priority of `0x01-0xFF`. -- Interrupts with a priority of 0 are not managed by the system and can continue to respond to interrupts after `rt_hw_interrupt_disable` is called. -- When using the [basepri](https://developer.arm.com/documentation/107706/0100/Exceptions-and-interrupts-overview/Special-registers-for-exception-masking/BASEPRI) register for independent interrupt management, note that interrupts with a priority value lower than `RT_MAX_SYSCALL_INTERRUPT_PRIORITY` cannot call any `system API`. diff --git a/rt-thread/libcpu/arm/cortex-m4/context_gcc.S b/rt-thread/libcpu/arm/cortex-m4/context_gcc.S index 908c957..5088e40 100644 --- a/rt-thread/libcpu/arm/cortex-m4/context_gcc.S +++ b/rt-thread/libcpu/arm/cortex-m4/context_gcc.S @@ -10,7 +10,6 @@ * 2013-06-18 aozima add restore MSP feature. * 2013-06-23 aozima support lazy stack optimized. * 2018-07-24 aozima enhancement hard fault exception handler. - * 2024-08-13 Evlers allows rewrite to interrupt enable/disable api to support independent interrupts management */ /** @@ -33,7 +32,6 @@ * rt_base_t rt_hw_interrupt_disable(); */ .global rt_hw_interrupt_disable -.weak rt_hw_interrupt_disable .type rt_hw_interrupt_disable, %function rt_hw_interrupt_disable: MRS r0, PRIMASK @@ -44,7 +42,6 @@ rt_hw_interrupt_disable: * void rt_hw_interrupt_enable(rt_base_t level); */ .global rt_hw_interrupt_enable -.weak rt_hw_interrupt_enable .type rt_hw_interrupt_enable, %function rt_hw_interrupt_enable: MSR PRIMASK, r0 @@ -211,10 +208,6 @@ rt_hw_context_switch_to: CPSIE F CPSIE I - /* clear the BASEPRI register to disable masking priority */ - MOV r0, #0x00 - MSR BASEPRI, r0 - /* ensure PendSV exception taken place before subsequent operation */ DSB ISB diff --git a/rt-thread/libcpu/arm/cortex-m4/context_iar.S b/rt-thread/libcpu/arm/cortex-m4/context_iar.S index fc87c82..30be2b7 100644 --- a/rt-thread/libcpu/arm/cortex-m4/context_iar.S +++ b/rt-thread/libcpu/arm/cortex-m4/context_iar.S @@ -11,7 +11,6 @@ ; * 2013-06-18 aozima add restore MSP feature. ; * 2013-06-23 aozima support lazy stack optimized. ; * 2018-07-24 aozima enhancement hard fault exception handler. -; * 2024-08-13 Evlers allows rewrite to interrupt enable/disable api to support independent interrupts management ; */ ;/** @@ -37,8 +36,7 @@ NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV excep ;/* ; * rt_base_t rt_hw_interrupt_disable(); ; */ - PUBWEAK rt_hw_interrupt_disable - SECTION .text:CODE:REORDER:NOROOT(2) + EXPORT rt_hw_interrupt_disable rt_hw_interrupt_disable: MRS r0, PRIMASK CPSID I @@ -47,8 +45,7 @@ rt_hw_interrupt_disable: ;/* ; * void rt_hw_interrupt_enable(rt_base_t level); ; */ - PUBWEAK rt_hw_interrupt_enable - SECTION .text:CODE:REORDER:NOROOT(2) + EXPORT rt_hw_interrupt_enable rt_hw_interrupt_enable: MSR PRIMASK, r0 BX LR @@ -211,10 +208,6 @@ rt_hw_context_switch_to: CPSIE F CPSIE I - ; clear the BASEPRI register to disable masking priority - MOV r0, #0x00 - MSR BASEPRI, r0 - ; ensure PendSV exception taken place before subsequent operation DSB ISB diff --git a/rt-thread/libcpu/arm/cortex-m4/context_rvds.S b/rt-thread/libcpu/arm/cortex-m4/context_rvds.S index 3f6e2e8..018e425 100644 --- a/rt-thread/libcpu/arm/cortex-m4/context_rvds.S +++ b/rt-thread/libcpu/arm/cortex-m4/context_rvds.S @@ -10,7 +10,6 @@ ; * 2013-06-18 aozima add restore MSP feature. ; * 2013-06-23 aozima support lazy stack optimized. ; * 2018-07-24 aozima enhancement hard fault exception handler. -; * 2024-08-13 Evlers allows rewrite to interrupt enable/disable api to support independent interrupts management ; */ ;/** @@ -37,7 +36,7 @@ NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV excep ; * rt_base_t rt_hw_interrupt_disable(); ; */ rt_hw_interrupt_disable PROC - EXPORT rt_hw_interrupt_disable [WEAK] + EXPORT rt_hw_interrupt_disable MRS r0, PRIMASK CPSID I BX LR @@ -47,7 +46,7 @@ rt_hw_interrupt_disable PROC ; * void rt_hw_interrupt_enable(rt_base_t level); ; */ rt_hw_interrupt_enable PROC - EXPORT rt_hw_interrupt_enable [WEAK] + EXPORT rt_hw_interrupt_enable MSR PRIMASK, r0 BX LR ENDP @@ -209,10 +208,6 @@ rt_hw_context_switch_to PROC CPSIE F CPSIE I - ; clear the BASEPRI register to disable masking priority - MOV r0, #0x00 - MSR BASEPRI, r0 - ; ensure PendSV exception taken place before subsequent operation DSB ISB diff --git a/rt-thread/libcpu/arm/cortex-m7/context_gcc.S b/rt-thread/libcpu/arm/cortex-m7/context_gcc.S index a4b5d21..cbc03e0 100644 --- a/rt-thread/libcpu/arm/cortex-m7/context_gcc.S +++ b/rt-thread/libcpu/arm/cortex-m7/context_gcc.S @@ -13,13 +13,13 @@ */ /** - * @addtogroup cortex-m7 + * @addtogroup cortex-m4 */ /*@{*/ #include -.cpu cortex-m7 +.cpu cortex-m4 .syntax unified .thumb .text diff --git a/rt-thread/libcpu/arm/cortex-r4/interrupt.c b/rt-thread/libcpu/arm/cortex-r4/interrupt.c index 345ca30..14a9023 100644 --- a/rt-thread/libcpu/arm/cortex-r4/interrupt.c +++ b/rt-thread/libcpu/arm/cortex-r4/interrupt.c @@ -22,7 +22,7 @@ /* exception and interrupt handler table */ struct rt_irq_desc irq_desc[MAX_HANDLERS]; -extern volatile rt_atomic_t rt_interrupt_nest; +extern volatile rt_uint8_t rt_interrupt_nest; /* exception and interrupt handler table */ rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; diff --git a/rt-thread/libcpu/arm/cortex-r52/backtrace.c b/rt-thread/libcpu/arm/cortex-r52/backtrace.c index 85a6935..ca7ec26 100644 --- a/rt-thread/libcpu/arm/cortex-r52/backtrace.c +++ b/rt-thread/libcpu/arm/cortex-r52/backtrace.c @@ -490,7 +490,7 @@ void unwind_backtrace(struct pt_regs *regs, const struct unwind_idx exidx_start[ arm_get_current_stackframe(regs, &frame); #ifndef RT_BACKTRACE_FUNCTION_NAME - rt_kprintf("please use: addr2line -e rtthread.elf -a -f %08x\n", frame.pc); + rt_kprintf("please use: addr2line -e rtthread.elf -a -f %08x", frame.pc); #endif LOG_D("pc = %08x, sp = %08x", frame.pc, frame.sp); diff --git a/rt-thread/libcpu/arm/cortex-r52/context_gcc.S b/rt-thread/libcpu/arm/cortex-r52/context_gcc.S index 1bd581e..f02559c 100644 --- a/rt-thread/libcpu/arm/cortex-r52/context_gcc.S +++ b/rt-thread/libcpu/arm/cortex-r52/context_gcc.S @@ -8,112 +8,116 @@ * 2024-03-01 Wangyuqiang first version */ -.syntax unified -.text +/** + * @addtogroup cortex-r52 + */ +/*@{*/ -.globl rt_thread_switch_interrupt_flag -.globl rt_interrupt_from_thread -.globl rt_interrupt_to_thread -.globl rt_interrupt_enter -.globl rt_interrupt_leave -.globl rt_hw_trap_irq +//#include + + .text + .arm + .globl rt_thread_switch_interrupt_flag + .globl rt_interrupt_from_thread + .globl rt_interrupt_to_thread + .globl rt_interrupt_enter + .globl rt_interrupt_leave + .globl rt_hw_trap_irq /* - * rt_base_t rt_hw_interrupt_disable(); + * rt_base_t rt_hw_interrupt_disable() */ -.globl rt_hw_interrupt_disable + .globl rt_hw_interrupt_disable rt_hw_interrupt_disable: - mrs r0, cpsr - cpsid i - bx lr + MRS r0, cpsr + CPSID IF + BX lr /* - * void rt_hw_interrupt_enable(rt_base_t level); + * void rt_hw_interrupt_enable(rt_base_t level) */ -.globl rt_hw_interrupt_enable + .globl rt_hw_interrupt_enable rt_hw_interrupt_enable: - msr cpsr, r0 - bx lr + MSR cpsr_c, r0 + BX lr /* * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to) * r0 --> from * r1 --> to */ -.globl rt_hw_context_switch + .globl rt_hw_context_switch rt_hw_context_switch: - clrex - stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) - stmfd sp!, {r0-r12, lr} @ push lr & register file + STMDB sp!, {lr} @ push pc (lr should be pushed in place of PC) + STMDB sp!, {r0-r12, lr} @ push lr & register file - mrs r4, cpsr - tst lr, #0x01 - orrne r4, r4, #0x20 @ it's thumb code + MRS r4, cpsr + TST lr, #0x01 + ORRNE r4, r4, #0x20 @ it's thumb code - stmfd sp!, {r4} @ push cpsr + STMDB sp!, {r4} @ push cpsr -#ifdef RT_USING_FPU - /* fpu context */ - vmrs r6, fpexc - tst r6, #(1<<30) - beq __no_vfp_frame1 - vstmdb sp!, {d0-d15} - vstmdb sp!, {d16-d31} - vmrs r5, fpscr - stmfd sp!, {r5} +#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING) + VMRS r4, fpexc + TST r4, #0x40000000 + BEQ __no_vfp_frame1 + VSTMDB sp!, {d0-d15} + VMRS r5, fpscr + @ TODO: add support for Common VFPv3. + @ Save registers like FPINST, FPINST2 + STMDB sp!, {r5} __no_vfp_frame1: - stmfd sp!, {r6} + STMDB sp!, {r4} #endif - str sp, [r0] @ store sp in preempted tasks TCB - ldr sp, [r1] @ get new task stack pointer -#ifdef RT_USING_FPU - /* fpu context */ - ldmfd sp!, {r6} - vmsr fpexc, r6 - tst r6, #(1<<30) - beq __no_vfp_frame2 - ldmfd sp!, {r5} - vmsr fpscr, r5 - vldmia sp!, {d16-d31} - vldmia sp!, {d0-d15} + STR sp, [r0] @ store sp in preempted tasks TCB + LDR sp, [r1] @ get new task stack pointer + +#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING) + LDMIA sp!, {r0} @ get fpexc + VMSR fpexc, r0 @ restore fpexc + TST r0, #0x40000000 + BEQ __no_vfp_frame2 + LDMIA sp!, {r1} @ get fpscr + VMSR fpscr, r1 + VLDMIA sp!, {d0-d15} __no_vfp_frame2: -#endif + #endif - ldmfd sp!, {r1} - msr spsr_cxsf, r1 /* original mode */ + LDMIA sp!, {r4} @ pop new task cpsr to spsr + MSR spsr_cxsf, r4 - ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */ + LDMIA sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr /* * void rt_hw_context_switch_to(rt_uint32 to) * r0 --> to */ -.globl rt_hw_context_switch_to + .globl rt_hw_context_switch_to rt_hw_context_switch_to: LDR sp, [r0] @ get new task stack pointer -#ifdef RT_USING_FPU - ldmfd sp!, {r6} - vmsr fpexc, r6 - tst r6, #(1<<30) - beq __no_vfp_frame_to - ldmfd sp!, {r5} - vmsr fpscr, r5 - vldmia sp!, {d0-d15} +#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING) + LDMIA sp!, {r0} @ get fpexc + VMSR fpexc, r0 + TST r0, #0x40000000 + BEQ __no_vfp_frame_to + LDMIA sp!, {r1} @ get fpscr + VMSR fpscr, r1 + VLDMIA sp!, {d0-d15} __no_vfp_frame_to: #endif LDMIA sp!, {r4} @ pop new task cpsr to spsr MSR spsr_cxsf, r4 - ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */ + LDMIA sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr /* * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)@ */ -.globl rt_hw_context_switch_interrupt + .globl rt_hw_context_switch_interrupt rt_hw_context_switch_interrupt: LDR r2, =rt_thread_switch_interrupt_flag LDR r3, [r2] @@ -129,21 +133,21 @@ _reswitch: STR r1, [r2] BX lr -.globl IRQ_Handler + .globl IRQ_Handler IRQ_Handler: STMDB sp!, {r0-r12,lr} -#ifdef RT_USING_FPU - VMRS r0, fpexc - TST r0, #0x40000000 - BEQ __no_vfp_frame_str_irq - VSTMDB sp!, {d0-d15} - VMRS r1, fpscr - @ TODO: add support for Common VFPv3. - @ Save registers like FPINST, FPINST2 - STMDB sp!, {r1} +#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING) + VMRS r0, fpexc + TST r0, #0x40000000 + BEQ __no_vfp_frame_str_irq + VSTMDB sp!, {d0-d15} + VMRS r1, fpscr + @ TODO: add support for Common VFPv3. + @ Save registers like FPINST, FPINST2 + STMDB sp!, {r1} __no_vfp_frame_str_irq: - STMDB sp!, {r0} + STMDB sp!, {r0} #endif BL rt_interrupt_enter @@ -157,14 +161,14 @@ __no_vfp_frame_str_irq: CMP r1, #1 BEQ rt_hw_context_switch_interrupt_do -#ifdef RT_USING_FPU - LDMIA sp!, {r0} @ get fpexc - VMSR fpexc, r0 - TST r0, #0x40000000 - BEQ __no_vfp_frame_ldr_irq - LDMIA sp!, {r1} @ get fpscr - VMSR fpscr, r1 - VLDMIA sp!, {d0-d15} +#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING) + LDMIA sp!, {r0} @ get fpexc + VMSR fpexc, r0 + TST r0, #0x40000000 + BEQ __no_vfp_frame_ldr_irq + LDMIA sp!, {r1} @ get fpscr + VMSR fpscr, r1 + VLDMIA sp!, {d0-d15} __no_vfp_frame_ldr_irq: #endif @@ -174,19 +178,19 @@ __no_vfp_frame_ldr_irq: /* * void rt_hw_context_switch_interrupt_do(rt_base_t flag) */ -.globl rt_hw_context_switch_interrupt_do + .globl rt_hw_context_switch_interrupt_do rt_hw_context_switch_interrupt_do: MOV r1, #0 @ clear flag STR r1, [r0] -#ifdef RT_USING_FPU - LDMIA sp!, {r0} @ get fpexc - VMSR fpexc, r0 - TST r0, #0x40000000 - BEQ __no_vfp_frame_do1 - LDMIA sp!, {r1} @ get fpscr - VMSR fpscr, r1 - VLDMIA sp!, {d0-d15} +#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING) + LDMIA sp!, {r0} @ get fpexc + VMSR fpexc, r0 + TST r0, #0x40000000 + BEQ __no_vfp_frame_do1 + LDMIA sp!, {r1} @ get fpscr + VMSR fpscr, r1 + VLDMIA sp!, {d0-d15} __no_vfp_frame_do1: #endif @@ -209,17 +213,17 @@ __no_vfp_frame_do1: @ use them here. STMDB sp!, {r3} @ push old task's cpsr -#ifdef RT_USING_FPU - VMRS r0, fpexc - TST r0, #0x40000000 - BEQ __no_vfp_frame_do2 - VSTMDB sp!, {d0-d15} - VMRS r1, fpscr - @ TODO: add support for Common VFPv3. - @ Save registers like FPINST, FPINST2 - STMDB sp!, {r1} +#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING) + VMRS r0, fpexc + TST r0, #0x40000000 + BEQ __no_vfp_frame_do2 + VSTMDB sp!, {d0-d15} + VMRS r1, fpscr + @ TODO: add support for Common VFPv3. + @ Save registers like FPINST, FPINST2 + STMDB sp!, {r1} __no_vfp_frame_do2: - STMDB sp!, {r0} + STMDB sp!, {r0} #endif LDR r4, =rt_interrupt_from_thread @@ -230,20 +234,19 @@ __no_vfp_frame_do2: LDR r6, [r6] LDR sp, [r6] @ get new task's stack pointer -#ifdef RT_USING_FPU - ldmfd sp!, {r6} - vmsr fpexc, r6 - tst r6, #(1<<30) - beq __no_vfp_frame_do3 - ldmfd sp!, {r5} - vmsr fpscr, r5 - vldmia sp!, {d0-d15} - +#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING) + LDMIA sp!, {r0} @ get fpexc + VMSR fpexc, r0 + TST r0, #0x40000000 + BEQ __no_vfp_frame_do3 + LDMIA sp!, {r1} @ get fpscr + VMSR fpscr, r1 + VLDMIA sp!, {d0-d15} __no_vfp_frame_do3: #endif LDMIA sp!, {r4} @ pop new task's cpsr to spsr MSR spsr_cxsf, r4 - ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */ + LDMIA sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr diff --git a/rt-thread/libcpu/arm/cortex-r52/start_gcc.S b/rt-thread/libcpu/arm/cortex-r52/start_gcc.S index 73d70a6..787d3e4 100644 --- a/rt-thread/libcpu/arm/cortex-r52/start_gcc.S +++ b/rt-thread/libcpu/arm/cortex-r52/start_gcc.S @@ -12,6 +12,8 @@ @ (c) Texas Instruments 2009-2013, All rights reserved. @ +//#include + .equ Mode_USR, 0x10 .equ Mode_FIQ, 0x11 .equ Mode_IRQ, 0x12 @@ -45,7 +47,7 @@ stack_top: .text .arm - .globl entry + .globl _c_int00 .globl _reset _reset: @@ -120,7 +122,7 @@ next2: next3: bl next4 next4: - ldr lr, =entry + ldr lr, =_c_int00 bx lr .globl data_init @@ -477,38 +479,26 @@ turnon_VFP: str lr, [r0, #14*4] @/* Save calling PC */ .endm -.globl SWI_Handler -SWI_Handler: - push_svc_reg - bl rt_hw_trap_swi - b . + .globl vector_svc +vector_svc: + push_svc_reg + bl rt_hw_trap_svc + b . -.globl Undefined_Handler -Undefined_Handler: - push_svc_reg - bl rt_hw_trap_undef - b . + .globl vector_pabort +vector_pabort: + push_svc_reg + bl rt_hw_trap_pabt + b . -.globl SVC_Handler -SVC_Handler: - push_svc_reg - b rt_hw_trap_svc - b . + .globl vector_dabort +vector_dabort: + push_svc_reg + bl rt_hw_trap_dabt + b . -.globl Prefetch_Handler -Prefetch_Handler: - push_svc_reg - b rt_hw_trap_pabt - b . - -.globl Abort_Handler -Abort_Handler: - push_svc_reg - b rt_hw_trap_dabt - b . - -.globl Reserved_Handler -Reserved_Handler: - push_svc_reg - b rt_hw_trap_resv - b . + .globl vector_resv +vector_resv: + push_svc_reg + bl rt_hw_trap_resv + b . diff --git a/rt-thread/libcpu/arm/cortex-r52/start_iar.S b/rt-thread/libcpu/arm/cortex-r52/start_iar.S index ec096d5..9e110dd 100644 --- a/rt-thread/libcpu/arm/cortex-r52/start_iar.S +++ b/rt-thread/libcpu/arm/cortex-r52/start_iar.S @@ -31,13 +31,11 @@ ABT_Stack_Size EQU 0x00000000 FIQ_Stack_Size EQU 0x00001000 IRQ_Stack_Size EQU 0x00001000 - IMPORT entry + IMPORT _c_int00 IMPORT rt_hw_trap_svc IMPORT rt_hw_trap_pabt IMPORT rt_hw_trap_dabt IMPORT rt_hw_trap_resv - IMPORT rt_hw_trap_swi - IMPORT rt_hw_trap_undef IMPORT system_init IMPORT __iar_program_start @@ -310,18 +308,6 @@ turnon_VFP: str lr, [r0, #14*4] ;@/* Save calling PC */ endm - EXPORT SWI_Handler -SWI_Handler: - push_svc_reg - bl rt_hw_trap_swi - b . - - EXPORT Undefined_Handler -Undefined_Handler: - push_svc_reg - bl rt_hw_trap_undef - b . - EXPORT SVC_Handler SVC_Handler: push_svc_reg diff --git a/rt-thread/libcpu/arm/cortex-r52/vector_gcc.S b/rt-thread/libcpu/arm/cortex-r52/vector_gcc.S index 85686ed..a0421d5 100644 --- a/rt-thread/libcpu/arm/cortex-r52/vector_gcc.S +++ b/rt-thread/libcpu/arm/cortex-r52/vector_gcc.S @@ -19,8 +19,7 @@ @ import reference for interrupt routines .globl Reset_Handler - .globl Undefined_Handler - .globl SWI_Handler + .globl turnon_VFP .globl SVC_Handler .globl Prefetch_Handler .globl Abort_Handler @@ -29,11 +28,10 @@ .globl FIQ_Handler -.globl system_vector -system_vector: +.globl system_vectors +system_vectors: b Reset_Handler - b Undefined_Handler - b SWI_Handler + b turnon_VFP b SVC_Handler b Prefetch_Handler b Abort_Handler diff --git a/rt-thread/libcpu/arm/cortex-r52/vector_iar.S b/rt-thread/libcpu/arm/cortex-r52/vector_iar.S index 57de4e8..916e44d 100644 --- a/rt-thread/libcpu/arm/cortex-r52/vector_iar.S +++ b/rt-thread/libcpu/arm/cortex-r52/vector_iar.S @@ -20,7 +20,6 @@ IMPORT Reset_Handler IMPORT Undefined_Handler - IMPORT SWI_Handler IMPORT SVC_Handler IMPORT Prefetch_Handler IMPORT Abort_Handler @@ -36,7 +35,6 @@ system_vectors: b Reset_Handler b Undefined_Handler - b SWI_Handler b SVC_Handler b Prefetch_Handler b Abort_Handler diff --git a/rt-thread/libcpu/arm/lpc214x/cpuport.c b/rt-thread/libcpu/arm/lpc214x/cpuport.c index 927ae93..4b8896a 100644 --- a/rt-thread/libcpu/arm/lpc214x/cpuport.c +++ b/rt-thread/libcpu/arm/lpc214x/cpuport.c @@ -16,7 +16,7 @@ #define MAX_HANDLERS 32 #define SVCMODE 0x13 -extern rt_atomic_t rt_interrupt_nest; +extern rt_uint32_t rt_interrupt_nest; /* exception and interrupt handler table */ struct rt_irq_desc irq_desc[MAX_HANDLERS]; diff --git a/rt-thread/libcpu/arm/lpc24xx/interrupt.c b/rt-thread/libcpu/arm/lpc24xx/interrupt.c index ec1b29e..87bb86b 100644 --- a/rt-thread/libcpu/arm/lpc24xx/interrupt.c +++ b/rt-thread/libcpu/arm/lpc24xx/interrupt.c @@ -18,7 +18,7 @@ /* exception and interrupt handler table */ struct rt_irq_desc irq_desc[MAX_HANDLERS]; -extern rt_atomic_t rt_interrupt_nest; +extern rt_uint32_t rt_interrupt_nest; /* exception and interrupt handler table */ rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; diff --git a/rt-thread/libcpu/arm/realview-a8-vmm/interrupt.c b/rt-thread/libcpu/arm/realview-a8-vmm/interrupt.c index e846880..2f55f72 100644 --- a/rt-thread/libcpu/arm/realview-a8-vmm/interrupt.c +++ b/rt-thread/libcpu/arm/realview-a8-vmm/interrupt.c @@ -16,7 +16,7 @@ #define MAX_HANDLERS NR_IRQS_PBA8 -extern volatile rt_atomic_t rt_interrupt_nest; +extern volatile rt_uint8_t rt_interrupt_nest; /* exception and interrupt handler table */ struct rt_irq_desc isr_table[MAX_HANDLERS]; diff --git a/rt-thread/libcpu/arm/s3c24x0/interrupt.c b/rt-thread/libcpu/arm/s3c24x0/interrupt.c index 79ef42d..c985fc7 100644 --- a/rt-thread/libcpu/arm/s3c24x0/interrupt.c +++ b/rt-thread/libcpu/arm/s3c24x0/interrupt.c @@ -15,7 +15,7 @@ #define MAX_HANDLERS 32 -extern rt_atomic_t rt_interrupt_nest; +extern rt_uint32_t rt_interrupt_nest; /* exception and interrupt handler table */ struct rt_irq_desc isr_table[MAX_HANDLERS]; diff --git a/rt-thread/libcpu/arm/s3c44b0/interrupt.c b/rt-thread/libcpu/arm/s3c44b0/interrupt.c index b69e675..5464011 100644 --- a/rt-thread/libcpu/arm/s3c44b0/interrupt.c +++ b/rt-thread/libcpu/arm/s3c44b0/interrupt.c @@ -15,7 +15,7 @@ #define MAX_HANDLERS 26 -extern rt_atomic_t rt_interrupt_nest; +extern rt_uint32_t rt_interrupt_nest; /* exception and interrupt handler table */ rt_isr_handler_t isr_table[MAX_HANDLERS]; diff --git a/rt-thread/libcpu/arm/sep4020/interrupt.c b/rt-thread/libcpu/arm/sep4020/interrupt.c index 641472d..24907c1 100644 --- a/rt-thread/libcpu/arm/sep4020/interrupt.c +++ b/rt-thread/libcpu/arm/sep4020/interrupt.c @@ -15,7 +15,7 @@ #define MAX_HANDLERS 32 -extern rt_atomic_t rt_interrupt_nest; +extern rt_uint32_t rt_interrupt_nest; /* exception and interrupt handler table */ struct rt_irq_desc isr_table[MAX_HANDLERS]; diff --git a/rt-thread/libcpu/arm/zynqmp-r5/interrupt.c b/rt-thread/libcpu/arm/zynqmp-r5/interrupt.c index dd9dc1a..fa37674 100644 --- a/rt-thread/libcpu/arm/zynqmp-r5/interrupt.c +++ b/rt-thread/libcpu/arm/zynqmp-r5/interrupt.c @@ -16,7 +16,7 @@ #define MAX_HANDLERS IRQ_ZynqMP_MAXNR -extern volatile rt_atomic_t rt_interrupt_nest; +extern volatile rt_uint8_t rt_interrupt_nest; /* exception and interrupt handler table */ struct rt_irq_desc isr_table[MAX_HANDLERS]; diff --git a/rt-thread/src/Kconfig b/rt-thread/src/Kconfig index 75c59ad..30105c3 100644 --- a/rt-thread/src/Kconfig +++ b/rt-thread/src/Kconfig @@ -1,10 +1,9 @@ +#include "rtconfig.h" menu "RT-Thread Kernel" -rsource "klibc/Kconfig" - config RT_NAME_MAX int "The maximal size of kernel object name" - range 2 64 + range 1 64 default 8 help Each kernel object, such as thread, timer, semaphore etc, has a name, @@ -19,13 +18,6 @@ config RT_USING_ARCH_DATA_TYPE Please re-define these data types in rtconfig_project.h file. -config RT_USING_NANO - bool "Enable RT-Thread Nano" - default n - help - RT-Thread Nano is a very small size and refined hard real-time kernel, - which is suited for the extremely resource-constrained MCU system. - config RT_USING_SMART bool "Enable RT-Thread Smart (microkernel on kernel/userland)" default n @@ -51,6 +43,13 @@ config RT_USING_SMART help RT-Thread Smart is a microkernel based operating system on RT-Thread. +config RT_USING_NANO + bool "Enable RT-Thread Nano" + default n + help + RT-Thread Nano with a very small size and refined hard real-time kernel, + which is very suited for the resource-constrained MCU system. + config RT_USING_AMP bool "Enable AMP (Asymmetric Multi-Processing)" default n @@ -70,6 +69,7 @@ config RT_USING_AMP config RT_USING_SMP bool "Enable SMP (Symmetric multiprocessing)" default n + select RT_USING_SCHED_THREAD_CTX help This option should be selected by machines which have an SMP- capable CPU. @@ -116,13 +116,6 @@ config RT_TICK_PER_SECOND help System's tick frequency, Hz. -config RT_USING_OVERFLOW_CHECK - bool "Using stack overflow checking" - default y if RT_USING_DEBUG - help - Enable thread stack overflow checking. The stack overflow is checking when - each thread switch. - config RT_USING_HOOK bool "Enable system hook" default y @@ -197,12 +190,40 @@ config RT_USING_CPU_USAGE_TRACER default y if RT_USING_SMART default n -menu "kservice options" +menu "kservice optimization" config RT_USING_TINY_FFS bool "Enable kservice to use tiny finding first bit set method" default n endmenu +menu "klibc optimization" + + config RT_KLIBC_USING_STDLIB + bool "Enable klibc to use standard C library" + default n + + if RT_KLIBC_USING_STDLIB + config RT_KLIBC_USING_STDLIB_MEMORY + bool "Use stdlib memory functions to replace (faster, but not safe)" + default n + help + e.g. use memcpy to replace rt_memcpy + endif + + config RT_KLIBC_USING_TINY_SIZE + bool "Enable tiny size of klibc" + default n + + config RT_KLIBC_USING_PRINTF_LONGLONG + bool "Enable rt_printf-family functions to support long-long format" + default y if ARCH_CPU_64BIT + default n + help + Enable rt_printf()/rt_snprintf()/rt_sprintf()/rt_vsnprintf()/rt_vsprintf() + functions to support long-long format + +endmenu + menuconfig RT_USING_DEBUG bool "Enable debugging features" default y @@ -239,16 +260,14 @@ menuconfig RT_USING_DEBUG depends on RT_USING_SMP default y if RT_USING_SMART default n - endif -config RT_USING_CI_ACTION - bool "Enable CI Action build mode" - select RT_USING_UTEST - select RT_UTEST_USING_AUTO_RUN - select RT_UTEST_USING_ALL_CASES - default n - help - Identify that the environment is CI Action. + config RT_USING_OVERFLOW_CHECK + bool "Using stack overflow checking" + default y + help + Enable thread stack overflow checking. The stack overflow is checking when + each thread switch. + endif menu "Inter-Thread communication" @@ -431,6 +450,14 @@ config RT_USING_THREADSAFE_PRINTF bool "Enable thread safe kernel print service" default y if RT_USING_SMP && RT_USING_SMART +config RT_USING_SCHED_THREAD_CTX + bool "Using the scheduler thread context" + help + Using the scheduler thread context embedded in the thread object. + This options is only for backward compatible codes. Maybe use as a + mandatory option in the future. + default y if RT_USING_SMP + config RT_USING_CONSOLE bool "Using console for rt_kprintf" default y @@ -438,7 +465,6 @@ config RT_USING_CONSOLE if RT_USING_CONSOLE config RT_CONSOLEBUF_SIZE int "the buffer size for console log printf" - default 256 if RT_USING_UTEST default 128 config RT_CONSOLE_DEVICE_NAME diff --git a/rt-thread/src/SConscript b/rt-thread/src/SConscript index 8407e6e..08a7d81 100644 --- a/rt-thread/src/SConscript +++ b/rt-thread/src/SConscript @@ -2,6 +2,7 @@ from building import * import os src = Glob('*.c') +src += Glob('klibc/*.c') cwd = GetCurrentDir() inc = [os.path.join(cwd, '..', 'include')] @@ -48,9 +49,4 @@ group = DefineGroup('Kernel', src, depend=[''], CPPPATH=inc, LINKFLAGS=LINKFLAGS, LOCAL_CFLAGS=LOCAL_CFLAGS, CPPDEFINES=['__RTTHREAD__'], LOCAL_CPPDEFINES=['__RT_KERNEL_SOURCE__']) -list = os.listdir(cwd) -for item in list: - if os.path.isfile(os.path.join(cwd, item, 'SConscript')): - group = group + SConscript(os.path.join(item, 'SConscript')) - Return('group') diff --git a/rt-thread/src/clock.c b/rt-thread/src/clock.c index 5ebfd83..6a2366a 100644 --- a/rt-thread/src/clock.c +++ b/rt-thread/src/clock.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -23,10 +23,6 @@ #include #include -#if defined(RT_USING_SMART) && defined(RT_USING_VDSO) -#include -#endif - #ifdef RT_USING_SMP #define rt_tick rt_cpu_index(0)->tick #else @@ -84,33 +80,33 @@ void rt_tick_set(rt_tick_t tick) } #ifdef RT_USING_CPU_USAGE_TRACER -static void _update_process_times(rt_tick_t tick) +static void _update_process_times(void) { struct rt_thread *thread = rt_thread_self(); struct rt_cpu *pcpu = rt_cpu_self(); if (!LWP_IS_USER_MODE(thread)) { - thread->user_time += tick; - pcpu->cpu_stat.user += tick; + thread->user_time += 1; + pcpu->cpu_stat.user += 1; } else { - thread->system_time += tick; + thread->system_time += 1; if (thread == pcpu->idle_thread) { - pcpu->cpu_stat.idle += tick; + pcpu->cpu_stat.idle += 1; } else { - pcpu->cpu_stat.system += tick; + pcpu->cpu_stat.system += 1; } } } #else -#define _update_process_times(tick) +#define _update_process_times() #endif /* RT_USING_CPU_USAGE_TRACER */ /** @@ -124,7 +120,7 @@ void rt_tick_increase(void) RT_OBJECT_HOOK_CALL(rt_tick_hook, ()); /* tracing cpu usage */ - _update_process_times(1); + _update_process_times(); /* increase the global tick */ #ifdef RT_USING_SMP @@ -135,7 +131,7 @@ void rt_tick_increase(void) #endif /* RT_USING_SMP */ /* check time slice */ - rt_sched_tick_increase(1); + rt_sched_tick_increase(); /* check timer */ #ifdef RT_USING_SMP @@ -147,44 +143,6 @@ void rt_tick_increase(void) rt_timer_check(); } -/** - * @brief This function will notify kernel there is n tick passed. - * Normally, this function is invoked by clock ISR. - */ -void rt_tick_increase_tick(rt_tick_t tick) -{ - RT_ASSERT(rt_interrupt_get_nest() > 0); - - RT_OBJECT_HOOK_CALL(rt_tick_hook, ()); - - /* tracing cpu usage */ - _update_process_times(tick); - - /* increase the global tick */ -#ifdef RT_USING_SMP - /* get percpu and increase the tick */ - rt_atomic_add(&(rt_cpu_self()->tick), tick); -#else - rt_atomic_add(&(rt_tick), tick); -#endif /* RT_USING_SMP */ - - /* check time slice */ - rt_sched_tick_increase(tick); - - /* check timer */ -#ifdef RT_USING_SMP - if (rt_cpu_get_id() != 0) - { - return; - } -#endif - rt_timer_check(); - -#ifdef RT_USING_VDSO - rt_vdso_update_glob_time(); -#endif -} - /** * @brief This function will calculate the tick from millisecond. * @@ -205,12 +163,8 @@ rt_tick_t rt_tick_from_millisecond(rt_int32_t ms) } else { -#if RT_TICK_PER_SECOND == 1000u - tick = ms; -#else tick = RT_TICK_PER_SECOND * (ms / 1000); tick += (RT_TICK_PER_SECOND * (ms % 1000) + 999) / 1000; -#endif /* RT_TICK_PER_SECOND == 1000u */ } /* return the calculated tick */ @@ -229,7 +183,7 @@ RTM_EXPORT(rt_tick_from_millisecond); */ rt_weak rt_tick_t rt_tick_get_millisecond(void) { -#if RT_TICK_PER_SECOND == 0 /* make cppcheck happy*/ +#if RT_TICK_PER_SECOND == 0 // make cppcheck happy #error "RT_TICK_PER_SECOND must be greater than zero" #endif diff --git a/rt-thread/src/components.c b/rt-thread/src/components.c index 9a1db27..d1adac1 100644 --- a/rt-thread/src/components.c +++ b/rt-thread/src/components.c @@ -90,7 +90,7 @@ void rt_components_board_init(void) const struct rt_init_desc *desc; for (desc = &__rt_init_desc_rti_board_start; desc < &__rt_init_desc_rti_board_end; desc ++) { - rt_kprintf("initialize %s\n", desc->fn_name); + rt_kprintf("initialize %s", desc->fn_name); result = desc->fn(); rt_kprintf(":%d done\n", result); } @@ -116,7 +116,7 @@ void rt_components_init(void) rt_kprintf("do components initialization.\n"); for (desc = &__rt_init_desc_rti_board_end; desc < &__rt_init_desc_rti_end; desc ++) { - rt_kprintf("initialize %s\n", desc->fn_name); + rt_kprintf("initialize %s", desc->fn_name); result = desc->fn(); rt_kprintf(":%d done\n", result); } @@ -270,9 +270,6 @@ int rtthread_startup(void) /* idle thread initialization */ rt_thread_idle_init(); - /* defunct thread initialization */ - rt_thread_defunct_init(); - #ifdef RT_USING_SMP rt_hw_spin_lock(&_cpus_lock); #endif /* RT_USING_SMP */ diff --git a/rt-thread/src/defunct.c b/rt-thread/src/defunct.c deleted file mode 100644 index 8fa7073..0000000 --- a/rt-thread/src/defunct.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-08-30 heyuanjie87 the first version - * - */ - -#include -#include - -#ifndef SYSTEM_THREAD_STACK_SIZE -#define SYSTEM_THREAD_STACK_SIZE IDLE_THREAD_STACK_SIZE -#endif -static rt_list_t _rt_thread_defunct = RT_LIST_OBJECT_INIT(_rt_thread_defunct); -static struct rt_spinlock _defunct_spinlock; -#if defined(RT_USING_SMP) || defined(RT_USING_SMART) -static struct rt_thread rt_system_thread; -rt_align(RT_ALIGN_SIZE) static rt_uint8_t rt_system_stack[SYSTEM_THREAD_STACK_SIZE]; -static struct rt_semaphore system_sem; -#endif - -/** - * @brief Enqueue a thread to defunct queue. - * - * @param thread the thread to be enqueued. - * - * @note It must be called between rt_hw_interrupt_disable and rt_hw_interrupt_enable - */ -void rt_thread_defunct_enqueue(rt_thread_t thread) -{ - rt_base_t level; - level = rt_spin_lock_irqsave(&_defunct_spinlock); - rt_list_insert_after(&_rt_thread_defunct, &RT_THREAD_LIST_NODE(thread)); - rt_spin_unlock_irqrestore(&_defunct_spinlock, level); -#if defined(RT_USING_SMP) || defined(RT_USING_SMART) - rt_sem_release(&system_sem); -#endif -} - -/** - * @brief Dequeue a thread from defunct queue. - */ -rt_thread_t rt_thread_defunct_dequeue(void) -{ - rt_base_t level; - rt_thread_t thread = RT_NULL; - rt_list_t *l = &_rt_thread_defunct; - - level = rt_spin_lock_irqsave(&_defunct_spinlock); - if (!rt_list_isempty(l)) - { - thread = RT_THREAD_LIST_NODE_ENTRY(l->next); - rt_list_remove(&RT_THREAD_LIST_NODE(thread)); - } - rt_spin_unlock_irqrestore(&_defunct_spinlock, level); - - return thread; -} - -/** - * @brief This function will perform system background job when system idle. - */ -void rt_defunct_execute(void) -{ - /* Loop until there is no dead thread. So one call to rt_defunct_execute - * will do all the cleanups. */ - while (1) - { - rt_thread_t thread; - rt_bool_t object_is_systemobject; - void (*cleanup)(struct rt_thread *tid); - -#ifdef RT_USING_MODULE - struct rt_dlmodule *module = RT_NULL; -#endif - /* get defunct thread */ - thread = rt_thread_defunct_dequeue(); - if (thread == RT_NULL) - { - break; - } - -#ifdef RT_USING_MODULE - module = (struct rt_dlmodule *)thread->parent.module_id; - if (module) - { - dlmodule_destroy(module); - } -#endif - -#ifdef RT_USING_SIGNALS - rt_thread_free_sig(thread); -#endif - - /* store the point of "thread->cleanup" avoid to lose */ - cleanup = thread->cleanup; - - /* if it's a system object, detach it */ - object_is_systemobject = rt_object_is_systemobject((rt_object_t)thread); - if (object_is_systemobject == RT_TRUE) - { - /* detach this object */ - rt_object_detach((rt_object_t)thread); - } - - /* invoke thread cleanup */ - if (cleanup != RT_NULL) - { - cleanup(thread); - } - -#ifdef RT_USING_HEAP -#ifdef RT_USING_MEM_PROTECTION - if (thread->mem_regions != RT_NULL) - { - RT_KERNEL_FREE(thread->mem_regions); - } -#endif - /* if need free, delete it */ - if (object_is_systemobject == RT_FALSE) - { - /* release thread's stack */ -#ifdef RT_USING_HW_STACK_GUARD - RT_KERNEL_FREE(thread->stack_buf); -#else - RT_KERNEL_FREE(thread->stack_addr); -#endif - /* delete thread object */ - rt_object_delete((rt_object_t)thread); - } -#endif - } -} - -#if defined(RT_USING_SMP) || defined(RT_USING_SMART) -static void rt_thread_system_entry(void *parameter) -{ - RT_UNUSED(parameter); - - while (1) - { - int ret = rt_sem_take(&system_sem, RT_WAITING_FOREVER); - if (ret != RT_EOK) - { - rt_kprintf("failed to sem_take() error %d\n", ret); - RT_ASSERT(0); - } - rt_defunct_execute(); - } -} -#endif - -void rt_thread_defunct_init(void) -{ - RT_ASSERT(RT_THREAD_PRIORITY_MAX > 2); - - rt_spin_lock_init(&_defunct_spinlock); - -#if defined(RT_USING_SMP) || defined(RT_USING_SMART) - rt_sem_init(&system_sem, "defunct", 0, RT_IPC_FLAG_FIFO); - - /* create defunct thread */ - rt_thread_init(&rt_system_thread, - "tsystem", - rt_thread_system_entry, - RT_NULL, - rt_system_stack, - sizeof(rt_system_stack), - RT_THREAD_PRIORITY_MAX - 2, - 32); - /* startup */ - rt_thread_startup(&rt_system_thread); -#endif -} diff --git a/rt-thread/src/idle.c b/rt-thread/src/idle.c index ce32149..0447de7 100644 --- a/rt-thread/src/idle.c +++ b/rt-thread/src/idle.c @@ -44,10 +44,22 @@ #define _CPUS_NR RT_CPUS_NR +static rt_list_t _rt_thread_defunct = RT_LIST_OBJECT_INIT(_rt_thread_defunct); +static struct rt_spinlock _defunct_spinlock; static struct rt_thread idle_thread[_CPUS_NR]; rt_align(RT_ALIGN_SIZE) static rt_uint8_t idle_thread_stack[_CPUS_NR][IDLE_THREAD_STACK_SIZE]; +#ifdef RT_USING_SMP +#ifndef SYSTEM_THREAD_STACK_SIZE +#define SYSTEM_THREAD_STACK_SIZE IDLE_THREAD_STACK_SIZE +#endif +static struct rt_thread rt_system_thread; +rt_align(RT_ALIGN_SIZE) +static rt_uint8_t rt_system_stack[SYSTEM_THREAD_STACK_SIZE]; +static struct rt_semaphore system_sem; +#endif + #ifdef RT_USING_IDLE_HOOK #ifndef RT_IDLE_HOOK_LIST_SIZE #define RT_IDLE_HOOK_LIST_SIZE 4 @@ -123,6 +135,128 @@ rt_err_t rt_thread_idle_delhook(void (*hook)(void)) #endif /* RT_USING_IDLE_HOOK */ +/** + * @brief Enqueue a thread to defunct queue. + * + * @param thread the thread to be enqueued. + * + * @note It must be called between rt_hw_interrupt_disable and rt_hw_interrupt_enable + */ +void rt_thread_defunct_enqueue(rt_thread_t thread) +{ + rt_base_t level; + level = rt_spin_lock_irqsave(&_defunct_spinlock); + rt_list_insert_after(&_rt_thread_defunct, &RT_THREAD_LIST_NODE(thread)); + rt_spin_unlock_irqrestore(&_defunct_spinlock, level); +#ifdef RT_USING_SMP + rt_sem_release(&system_sem); +#endif +} + +/** + * @brief Dequeue a thread from defunct queue. + */ +rt_thread_t rt_thread_defunct_dequeue(void) +{ + rt_base_t level; + rt_thread_t thread = RT_NULL; + rt_list_t *l = &_rt_thread_defunct; + +#ifdef RT_USING_SMP + level = rt_spin_lock_irqsave(&_defunct_spinlock); + if (l->next != l) + { + thread = RT_THREAD_LIST_NODE_ENTRY(l->next); + rt_list_remove(&RT_THREAD_LIST_NODE(thread)); + } + rt_spin_unlock_irqrestore(&_defunct_spinlock, level); +#else + if (l->next != l) + { + thread = RT_THREAD_LIST_NODE_ENTRY(l->next); + level = rt_hw_interrupt_disable(); + rt_list_remove(&RT_THREAD_LIST_NODE(thread)); + rt_hw_interrupt_enable(level); + } +#endif + return thread; +} + +/** + * @brief This function will perform system background job when system idle. + */ +static void rt_defunct_execute(void) +{ + /* Loop until there is no dead thread. So one call to rt_defunct_execute + * will do all the cleanups. */ + while (1) + { + rt_thread_t thread; + rt_bool_t object_is_systemobject; + void (*cleanup)(struct rt_thread *tid); + +#ifdef RT_USING_MODULE + struct rt_dlmodule *module = RT_NULL; +#endif + /* get defunct thread */ + thread = rt_thread_defunct_dequeue(); + if (thread == RT_NULL) + { + break; + } + +#ifdef RT_USING_MODULE + module = (struct rt_dlmodule*)thread->parent.module_id; + if (module) + { + dlmodule_destroy(module); + } +#endif + +#ifdef RT_USING_SIGNALS + rt_thread_free_sig(thread); +#endif + + /* store the point of "thread->cleanup" avoid to lose */ + cleanup = thread->cleanup; + + /* if it's a system object, detach it */ + object_is_systemobject = rt_object_is_systemobject((rt_object_t)thread); + if (object_is_systemobject == RT_TRUE) + { + /* detach this object */ + rt_object_detach((rt_object_t)thread); + } + + /* invoke thread cleanup */ + if (cleanup != RT_NULL) + { + cleanup(thread); + } + +#ifdef RT_USING_HEAP +#ifdef RT_USING_MEM_PROTECTION + if (thread->mem_regions != RT_NULL) + { + RT_KERNEL_FREE(thread->mem_regions); + } +#endif + /* if need free, delete it */ + if (object_is_systemobject == RT_FALSE) + { + /* release thread's stack */ +#ifdef RT_USING_HW_STACK_GUARD + RT_KERNEL_FREE(thread->stack_buf); +#else + RT_KERNEL_FREE(thread->stack_addr); +#endif + /* delete thread object */ + rt_object_delete((rt_object_t)thread); + } +#endif + } +} + static void idle_thread_entry(void *parameter) { RT_UNUSED(parameter); @@ -152,9 +286,9 @@ static void idle_thread_entry(void *parameter) } #endif /* RT_USING_IDLE_HOOK */ -#if !defined(RT_USING_SMP) && !defined(RT_USING_SMART) - rt_defunct_execute(); -#endif +#ifndef RT_USING_SMP + rt_defunct_execute(); +#endif /* RT_USING_SMP */ #ifdef RT_USING_PM void rt_system_power_manager(void); @@ -163,6 +297,24 @@ static void idle_thread_entry(void *parameter) } } +#ifdef RT_USING_SMP +static void rt_thread_system_entry(void *parameter) +{ + RT_UNUSED(parameter); + + while (1) + { + int ret = rt_sem_take(&system_sem, RT_WAITING_FOREVER); + if (ret != RT_EOK) + { + rt_kprintf("failed to sem_take() error %d\n", ret); + RT_ASSERT(0); + } + rt_defunct_execute(); + } +} +#endif + /** * @brief This function will initialize idle thread, then start it. * @@ -175,10 +327,6 @@ void rt_thread_idle_init(void) char idle_thread_name[RT_NAME_MAX]; #endif /* RT_NAME_MAX > 0 */ -#ifdef RT_USING_IDLE_HOOK - rt_spin_lock_init(&_hook_spinlock); -#endif - for (i = 0; i < _CPUS_NR; i++) { #if RT_NAME_MAX > 0 @@ -206,6 +354,27 @@ void rt_thread_idle_init(void) /* startup */ rt_thread_startup(&idle_thread[i]); } + +#ifdef RT_USING_SMP + RT_ASSERT(RT_THREAD_PRIORITY_MAX > 2); + + rt_spin_lock_init(&_defunct_spinlock); + rt_spin_lock_init(&_hook_spinlock); + + rt_sem_init(&system_sem, "defunct", 0, RT_IPC_FLAG_FIFO); + + /* create defunct thread */ + rt_thread_init(&rt_system_thread, + "tsystem", + rt_thread_system_entry, + RT_NULL, + rt_system_stack, + sizeof(rt_system_stack), + RT_THREAD_PRIORITY_MAX - 2, + 32); + /* startup */ + rt_thread_startup(&rt_system_thread); +#endif } /** diff --git a/rt-thread/src/ipc.c b/rt-thread/src/ipc.c index 4cea8d8..5ffcf01 100644 --- a/rt-thread/src/ipc.c +++ b/rt-thread/src/ipc.c @@ -769,7 +769,7 @@ rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg) rt_ubase_t value; /* get value */ - value = (rt_uintptr_t)arg; + value = (rt_ubase_t)arg; level = rt_spin_lock_irqsave(&(sem->spinlock)); /* resume all waiting thread */ @@ -787,7 +787,7 @@ rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg) rt_ubase_t max_value; rt_bool_t need_schedule = RT_FALSE; - max_value = (rt_uint16_t)((rt_uintptr_t)arg); + max_value = (rt_uint16_t)((rt_ubase_t)arg); if (max_value > RT_SEM_VALUE_MAX || max_value < 1) { return -RT_EINVAL; @@ -945,30 +945,28 @@ static rt_bool_t _check_and_update_prio(rt_thread_t thread, rt_mutex_t mutex) static void _mutex_before_delete_detach(rt_mutex_t mutex) { rt_sched_lock_level_t slvl; - rt_bool_t need_schedule = RT_FALSE; + rt_bool_t need_schedule; rt_spin_lock(&(mutex->spinlock)); /* wakeup all suspended threads */ rt_susp_list_resume_all(&(mutex->parent.suspend_thread), RT_ERROR); - - rt_sched_lock(&slvl); - /* remove mutex from thread's taken list */ rt_list_remove(&mutex->taken_list); /* whether change the thread priority */ if (mutex->owner) { + rt_sched_lock(&slvl); need_schedule = _check_and_update_prio(mutex->owner, mutex); - } - if (need_schedule) - { - rt_sched_unlock_n_resched(slvl); - } - else - { - rt_sched_unlock(slvl); + if (need_schedule) + { + rt_sched_unlock_n_resched(slvl); + } + else + { + rt_sched_unlock(slvl); + } } /* unlock and do necessary reschedule if required */ @@ -1351,7 +1349,7 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend if (mutex->owner == thread) { - if (mutex->hold < RT_MUTEX_HOLD_MAX) + if(mutex->hold < RT_MUTEX_HOLD_MAX) { /* it's the same thread */ mutex->hold ++; @@ -1450,13 +1448,13 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend rt_spin_lock(&(mutex->spinlock)); - if (mutex->owner == thread) + if (thread->error == RT_EOK) { /** * get mutex successfully * Note: assert to avoid an unexpected resume */ - RT_ASSERT(thread->error == RT_EOK); + RT_ASSERT(mutex->owner == thread); } else { @@ -1468,12 +1466,6 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend /* get value first before calling to other APIs */ ret = thread->error; - /* unexpected resume */ - if (ret == RT_EOK) - { - ret = -RT_EINTR; - } - rt_sched_lock(&slvl); /** @@ -1625,11 +1617,11 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) /* if no hold */ if (mutex->hold == 0) { - rt_sched_lock(&slvl); - /* remove mutex from thread's taken list */ rt_list_remove(&mutex->taken_list); + rt_sched_lock(&slvl); + /* whether change the thread priority */ need_schedule = _check_and_update_prio(thread, mutex); diff --git a/rt-thread/src/irq.c b/rt-thread/src/irq.c index f6b33a7..fb5a502 100644 --- a/rt-thread/src/irq.c +++ b/rt-thread/src/irq.c @@ -14,7 +14,6 @@ * 2022-07-04 Yunjie fix RT_DEBUG_LOG * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2024-01-05 Shell Fixup of data racing in rt_interrupt_get_nest - * 2024-01-03 Shell Support for interrupt context */ #include @@ -70,25 +69,6 @@ void rt_interrupt_leave_sethook(void (*hook)(void)) volatile rt_atomic_t rt_interrupt_nest = 0; #endif /* RT_USING_SMP */ -#ifdef ARCH_USING_IRQ_CTX_LIST -void rt_interrupt_context_push(rt_interrupt_context_t this_ctx) -{ - struct rt_cpu *this_cpu = rt_cpu_self(); - rt_slist_insert(&this_cpu->irq_ctx_head, &this_ctx->node); -} - -void rt_interrupt_context_pop(void) -{ - struct rt_cpu *this_cpu = rt_cpu_self(); - rt_slist_pop(&this_cpu->irq_ctx_head); -} - -void *rt_interrupt_context_get(void) -{ - struct rt_cpu *this_cpu = rt_cpu_self(); - return rt_slist_first_entry(&this_cpu->irq_ctx_head, struct rt_interrupt_context, node)->context; -} -#endif /* ARCH_USING_IRQ_CTX_LIST */ /** * @brief This function will be invoked by BSP, when enter interrupt service routine diff --git a/rt-thread/src/klibc/Kconfig b/rt-thread/src/klibc/Kconfig deleted file mode 100644 index bc90e90..0000000 --- a/rt-thread/src/klibc/Kconfig +++ /dev/null @@ -1,258 +0,0 @@ -menu "klibc options" - menu "rt_vsnprintf options" - config RT_KLIBC_USING_LIBC_VSNPRINTF - bool "Enable rt_vsnprintf to use libc vsnprintf" - default n - - config RT_KLIBC_USING_VSNPRINTF_LONGLONG - bool "Enable rt_vsnprintf function to support long-long format" - depends on !RT_KLIBC_USING_LIBC_VSNPRINTF - default n - help - Support for the long long integral types (with the ll, z and t length modifiers for specifiers - %d,%i,%o,%x,%X,%u, and with the %p specifier). Note: 'L' (long double) is not supported. - - menuconfig RT_KLIBC_USING_VSNPRINTF_STANDARD - bool "Enable standard rt_vsnprintf version" - default y if ARCH_CPU_64BIT - default n - select RT_KLIBC_USING_VSNPRINTF_LONGLONG - depends on !RT_KLIBC_USING_LIBC_VSNPRINTF - help - Standard version of rt_vsnprintf, which is full function but higher stack usage. - - if RT_KLIBC_USING_VSNPRINTF_STANDARD - - config RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS - bool "Support decimal notation floating point conversion specifiers (%f, %F)" - default y - help - Support for the decimal notation floating point conversion specifiers (%f, %F) - - config RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - bool "Support exponential notation floating point conversion specifiers (%e, %g, %E, %G)" - default y - help - Support for the exponential notation floating point conversion specifiers (%e, %g, %E, %G) - - config RT_KLIBC_USING_VSNPRINTF_WRITEBACK_SPECIFIER - bool "Support length write-back specifier (%n)" - default y - help - Support for the length write-back specifier (%n) - - config RT_KLIBC_USING_VSNPRINTF_CHECK_NUL_IN_FORMAT_SPECIFIER - bool "safety check: no NULL end string" - default y if RT_USING_DEBUG - default n - help - Be extra-safe, and don't assume format specifiers are completed correctly - before the format string end. - - config RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - bool "Support MSVC style integer specifiers" - default n - help - the integer format specifiers used in Microsoft's Visual C++ (MSVC) compiler. - These specifiers, like %I64d for 64-bit integers, deviate slightly from the standard - C format specifiers and are specific to MSVC. They allow for controlled formatting of - integers in printf()-like functions, accommodating different integer sizes and ensuring - compatibility with MSVC's environment. It's important to note that these specifiers might - not be recognized or function in other compilers due to their MSVC-specific nature. - - config RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE - int "'ntoa' conversion buffer size" - default 32 - help - 'ntoa' conversion buffer size, this must be big enough to hold one converted - numeric number including padded zeros (dynamically created on stack) - - config RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE - int "printing individual decimal numbers buffer size" - default 32 - help - size of the fixed (on-stack) buffer for printing individual decimal numbers. - this must be big enough to hold one converted floating-point value including - padded zeros. - - config RT_KLIBC_USING_VSNPRINTF_FLOAT_PRECISION - int "floating point conversion specifiers" - default 6 - help - Default precision for the floating point conversion specifiers (the C standard sets this at 6) - - config RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL - int "integral nums printed as float in rt_vsnprint" - default 9 - help - According to the C languages standard, printf() and related functions must be able to print any - integral number in floating-point notation, regardless of length, when using the %f specifier - - possibly hundreds of characters, potentially overflowing your buffers. In this implementation, - all values beyond this threshold are switched to exponential notation. - - config RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS - int "the number of terms in a Taylor series expansion of log_10(x)" - default 4 - range 2 99 - help - The number of terms in a Taylor series expansion of log_10(x) to - use for approximation - including the power-zero term (i.e. the - value at the point of expansion). - - endif - endmenu # rt_vsnprintf options - - menu "rt_vsscanf options" - config RT_KLIBC_USING_LIBC_VSSCANF - bool "Enable rt_vsscanf to use libc vsscanf" - default n - endmenu # rt_vsscanf options - - menu "rt_memset options" - config RT_KLIBC_USING_USER_MEMSET - bool "Enable rt_memset to use user-defined version" - default n - - if !RT_KLIBC_USING_USER_MEMSET - config RT_KLIBC_USING_LIBC_MEMSET - bool "Enable rt_memset to use libc memset" - default n - - config RT_KLIBC_USING_TINY_MEMSET - bool "Enable rt_memset to use tiny version" - depends on !RT_KLIBC_USING_LIBC_MEMSET - default n - endif - endmenu # rt_memset options - - menu "rt_memcpy options" - config RT_KLIBC_USING_USER_MEMCPY - bool "Enable rt_memcpy to use user-defined version" - default n - - if !RT_KLIBC_USING_USER_MEMCPY - config RT_KLIBC_USING_LIBC_MEMCPY - bool "Enable rt_memcpy to use libc memcpy" - default n - - config RT_KLIBC_USING_TINY_MEMCPY - bool "Enable rt_memcpy to use tiny version" - depends on !RT_KLIBC_USING_LIBC_MEMCPY - default n - endif - endmenu # rt_memcpy options - - menu "rt_memmove options" - config RT_KLIBC_USING_USER_MEMMOVE - bool "Enable rt_memmove to use user-defined version" - default n - - if !RT_KLIBC_USING_USER_MEMMOVE - config RT_KLIBC_USING_LIBC_MEMMOVE - bool "Enable rt_memmove to use libc memmove" - default n - endif - endmenu # rt_memmove options - - menu "rt_memcmp options" - config RT_KLIBC_USING_USER_MEMCMP - bool "Enable rt_memcmp to use user-defined version" - default n - - if !RT_KLIBC_USING_USER_MEMCMP - config RT_KLIBC_USING_LIBC_MEMCMP - bool "Enable rt_memcmp to use libc memcmp" - default n - endif - endmenu # rt_memcmp options - - menu "rt_strstr options" - config RT_KLIBC_USING_USER_STRSTR - bool "Enable rt_strstr to use user-defined version" - default n - - if !RT_KLIBC_USING_USER_STRSTR - config RT_KLIBC_USING_LIBC_STRSTR - bool "Enable rt_strstr to use libc strstr" - default n - endif - endmenu # rt_strstr options - - menu "rt_strcasecmp options" - config RT_KLIBC_USING_USER_STRCASECMP - bool "Enable rt_strcasecmp to use user-defined version" - default n - endmenu # rt_strcasecmp options - - menu "rt_strncpy options" - config RT_KLIBC_USING_USER_STRNCPY - bool "Enable rt_strncpy to use user-defined version" - default n - - if !RT_KLIBC_USING_USER_STRNCPY - config RT_KLIBC_USING_LIBC_STRNCPY - bool "Enable rt_strncpy to use libc strncpy" - default n - endif - endmenu # rt_strncpy options - - menu "rt_strcpy options" - config RT_KLIBC_USING_USER_STRCPY - bool "Enable rt_strcpy to use user-defined version" - default n - - if !RT_KLIBC_USING_USER_STRCPY - config RT_KLIBC_USING_LIBC_STRCPY - bool "Enable rt_strcpy to use libc strcpy" - default n - endif - endmenu # rt_strcpy options - - menu "rt_strncmp options" - config RT_KLIBC_USING_USER_STRNCMP - bool "Enable rt_strncmp to use user-defined version" - default n - - if !RT_KLIBC_USING_USER_STRNCMP - config RT_KLIBC_USING_LIBC_STRNCMP - bool "Enable rt_strncmp to use libc strncmp" - default n - endif - endmenu # rt_strncmp options - - menu "rt_strcmp options" - config RT_KLIBC_USING_USER_STRCMP - bool "Enable rt_strcmp to use user-defined version" - default n - - if !RT_KLIBC_USING_USER_STRCMP - config RT_KLIBC_USING_LIBC_STRCMP - bool "Enable rt_strcmp to use libc strcmp" - default n - endif - endmenu # rt_strcmp options - - menu "rt_strlen options" - config RT_KLIBC_USING_USER_STRLEN - bool "Enable rt_strlen to use user-defined version" - default n - - if !RT_KLIBC_USING_USER_STRLEN - config RT_KLIBC_USING_LIBC_STRLEN - bool "Enable rt_strlen to use libc strlen" - default n - endif - endmenu # rt_strlen options - - menu "rt_strnlen options" - config RT_KLIBC_USING_USER_STRNLEN - bool "Enable rt_strnlen to use user-defined version" - default n - endmenu # rt_strnlen options - - config RT_UTEST_TC_USING_KLIBC - bool "Enable klibc utest cases" - select RT_USING_UTEST - default n - -endmenu diff --git a/rt-thread/src/klibc/SConscript b/rt-thread/src/klibc/SConscript deleted file mode 100644 index eb629ef..0000000 --- a/rt-thread/src/klibc/SConscript +++ /dev/null @@ -1,23 +0,0 @@ -from building import * -import os - -cwd = GetCurrentDir() -src = ['kerrno.c', 'kstdio.c', 'kstring.c'] - -if not GetDepend(['RT_KLIBC_USING_LIBC_VSNPRINTF']): - if GetDepend(['RT_KLIBC_USING_VSNPRINTF_STANDARD']): - src += ['rt_vsnprintf_std.c'] - else: - src += ['rt_vsnprintf_tiny.c'] - -if not GetDepend(['RT_KLIBC_USING_LIBC_VSSCANF']): - src += ['rt_vsscanf.c'] - -group = DefineGroup('klibc', src, depend = ['']) - -list = os.listdir(cwd) -for item in list: - if os.path.isfile(os.path.join(cwd, item, 'SConscript')): - group = group + SConscript(os.path.join(item, 'SConscript')) - -Return('group') diff --git a/rt-thread/src/klibc/kerrno.c b/rt-thread/src/klibc/kerrno.c deleted file mode 100644 index 49a73c6..0000000 --- a/rt-thread/src/klibc/kerrno.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-09-22 Meco Man the first version - */ - -#include - -/** - * @brief A global variable used to store the error code. - * - * This volatile static integer is used to store the most recent error code globally. - * Its volatile nature ensures that every read operation fetches the most current value, - * providing real-time error status across different parts of the program. - */ -static volatile int __rt_errno; - -/** - * @struct _errno_str_t - * @brief Structure for mapping error codes to corresponding error strings. - * - * This structure is used to create a mapping that associates an rt_err_t type error code - * with a corresponding error description string. - */ -struct _errno_str_t -{ - rt_err_t error; /**< Error code of type rt_err_t, representing different kinds of errors. */ - const char *str; /**< Pointer to the error description string. */ -}; - -/** - * @brief An array containing mappings of error codes to their corresponding error strings. - * - * This array uses the _errno_str_t structure to define several error codes and their - * corresponding error description strings. These mappings can be used at runtime - * to provide more readable error information. - */ -static struct _errno_str_t rt_errno_strs[] = -{ - {RT_EOK , "OK "}, /**< Operation successful. */ - {RT_ERROR , "ERROR "}, /**< General error. */ - {RT_ETIMEOUT, "ETIMOUT"}, /**< Operation timed out. */ - {RT_EFULL , "ERSFULL"}, /**< Resource is full. */ - {RT_EEMPTY , "ERSEPTY"}, /**< Resource is empty. */ - {RT_ENOMEM , "ENOMEM "}, /**< Not enough memory. */ - {RT_ENOSYS , "ENOSYS "}, /**< Function not implemented. */ - {RT_EBUSY , "EBUSY "}, /**< Resource is busy. */ - {RT_EIO , "EIO "}, /**< Input/output error. */ - {RT_EINTR , "EINTRPT"}, /**< Interrupted system call. */ - {RT_EINVAL , "EINVAL "}, /**< Invalid argument. */ - {RT_ENOENT , "ENOENT "}, /**< No such file or directory. */ - {RT_ENOSPC , "ENOSPC "}, /**< No space left on device. */ - {RT_EPERM , "EPERM "}, /**< Operation not permitted. */ - {RT_ETRAP , "ETRAP "}, /**< Trap error. */ -}; - -/** - * @brief This function return a pointer to a string that contains the - * message of error. - * - * @param error the errorno code - * @return a point to error message string - */ -const char *rt_strerror(rt_err_t error) -{ - int i = 0; - - if (error < 0) - error = -error; - - for (i = 0; i < sizeof(rt_errno_strs) / sizeof(rt_errno_strs[0]); i++) - { - if (rt_errno_strs[i].error == error) - return rt_errno_strs[i].str; - } - - return "EUNKNOW"; -} -RTM_EXPORT(rt_strerror); - -/** - * @brief This function gets the global errno for the current thread. - * - * @return errno - */ -rt_err_t rt_get_errno(void) -{ - rt_thread_t tid = RT_NULL; - - if (rt_interrupt_get_nest() != 0) - { - /* it's in interrupt context */ - return __rt_errno; - } - - tid = rt_thread_self(); - if (tid == RT_NULL) - { - return __rt_errno; - } - - return tid->error; -} -RTM_EXPORT(rt_get_errno); - -/** - * @brief This function sets the global errno for the current thread. - * - * @param error is the errno shall be set. - */ -void rt_set_errno(rt_err_t error) -{ - rt_thread_t tid = RT_NULL; - - if (rt_interrupt_get_nest() != 0) - { - /* it's in interrupt context */ - __rt_errno = error; - - return; - } - - tid = rt_thread_self(); - if (tid == RT_NULL) - { - __rt_errno = error; - - return; - } - - tid->error = error; -} -RTM_EXPORT(rt_set_errno); - -/** - * @brief This function returns the address of the current thread errno. - * - * @return The errno address. - */ -int *_rt_errno(void) -{ - rt_thread_t tid = RT_NULL; - - if (rt_interrupt_get_nest() != 0) - { - return (int *)&__rt_errno; - } - - tid = rt_thread_self(); - if (tid != RT_NULL) - { - return (int *) & (tid->error); - } - - return (int *)&__rt_errno; -} -RTM_EXPORT(_rt_errno); diff --git a/rt-thread/src/klibc/kstdio.c b/rt-thread/src/klibc/kstdio.c index df73eab..44ff758 100644 --- a/rt-thread/src/klibc/kstdio.c +++ b/rt-thread/src/klibc/kstdio.c @@ -8,12 +8,619 @@ * 2024-03-10 Meco Man the first version */ -#include -#if defined(RT_KLIBC_USING_LIBC_VSSCANF) || \ - defined(RT_KLIBC_USING_LIBC_VSNPRINTF) -#include +#include +#include +#include +#include + +#define DBG_TAG "kernel.stdio" +#ifdef RT_DEBUG_DEVICE +#define DBG_LVL DBG_LOG +#else +#define DBG_LVL DBG_WARNING +#endif /* defined (RT_DEBUG_DEVICE) */ +#include + +#define _ISDIGIT(c) ((unsigned)((c) - '0') < 10) + +/** + * @brief This function will duplicate a string. + * + * @param n is the string to be duplicated. + * + * @param base is support divide instructions value. + * + * @return the duplicated string pointer. + */ +#ifdef RT_KLIBC_USING_PRINTF_LONGLONG +rt_inline int divide(unsigned long long *n, int base) +#else +rt_inline int divide(unsigned long *n, int base) +#endif /* RT_KLIBC_USING_PRINTF_LONGLONG */ +{ + int res; + + /* optimized for processor which does not support divide instructions. */ +#ifdef RT_KLIBC_USING_PRINTF_LONGLONG + res = (int)((*n) % base); + *n = (long long)((*n) / base); +#else + res = (int)((*n) % base); + *n = (long)((*n) / base); #endif + return res; +} + +rt_inline int skip_atoi(const char **s) +{ + int i = 0; + while (_ISDIGIT(**s)) + i = i * 10 + *((*s)++) - '0'; + + return i; +} + +#define ZEROPAD (1 << 0) /* pad with zero */ +#define SIGN (1 << 1) /* unsigned/signed long */ +#define PLUS (1 << 2) /* show plus */ +#define SPACE (1 << 3) /* space if plus */ +#define LEFT (1 << 4) /* left justified */ +#define SPECIAL (1 << 5) /* 0x */ +#define LARGE (1 << 6) /* use 'ABCDEF' instead of 'abcdef' */ + +static char *print_number(char *buf, + char *end, +#ifdef RT_KLIBC_USING_PRINTF_LONGLONG + unsigned long long num, +#else + unsigned long num, +#endif /* RT_KLIBC_USING_PRINTF_LONGLONG */ + int base, + int qualifier, + int s, + int precision, + int type) +{ + char c = 0, sign = 0; +#ifdef RT_KLIBC_USING_PRINTF_LONGLONG + char tmp[64] = {0}; +#else + char tmp[32] = {0}; +#endif /* RT_KLIBC_USING_PRINTF_LONGLONG */ + int precision_bak = precision; + const char *digits = RT_NULL; + static const char small_digits[] = "0123456789abcdef"; + static const char large_digits[] = "0123456789ABCDEF"; + int i = 0; + int size = 0; + + size = s; + + digits = (type & LARGE) ? large_digits : small_digits; + if (type & LEFT) + { + type &= ~ZEROPAD; + } + + c = (type & ZEROPAD) ? '0' : ' '; + + /* get sign */ + sign = 0; + if (type & SIGN) + { + switch (qualifier) + { + case 'h': + if ((rt_int16_t)num < 0) + { + sign = '-'; + num = (rt_uint16_t)-num; + } + break; + case 'L': + case 'l': + if ((long)num < 0) + { + sign = '-'; + num = (unsigned long)-num; + } + break; + case 0: + default: + if ((rt_int32_t)num < 0) + { + sign = '-'; + num = (rt_uint32_t)-num; + } + break; + } + + if (sign != '-') + { + if (type & PLUS) + { + sign = '+'; + } + else if (type & SPACE) + { + sign = ' '; + } + } + } + + if (type & SPECIAL) + { + if (base == 2 || base == 16) + { + size -= 2; + } + else if (base == 8) + { + size--; + } + } + + i = 0; + if (num == 0) + { + tmp[i++] = '0'; + } + else + { + while (num != 0) + tmp[i++] = digits[divide(&num, base)]; + } + + if (i > precision) + { + precision = i; + } + size -= precision; + + if (!(type & (ZEROPAD | LEFT))) + { + if ((sign) && (size > 0)) + { + size--; + } + + while (size-- > 0) + { + if (buf < end) + { + *buf = ' '; + } + + ++ buf; + } + } + + if (sign) + { + if (buf < end) + { + *buf = sign; + } + -- size; + ++ buf; + } + + if (type & SPECIAL) + { + if (base == 2) + { + if (buf < end) + *buf = '0'; + ++ buf; + if (buf < end) + *buf = 'b'; + ++ buf; + } + else if (base == 8) + { + if (buf < end) + *buf = '0'; + ++ buf; + } + else if (base == 16) + { + if (buf < end) + { + *buf = '0'; + } + + ++ buf; + if (buf < end) + { + *buf = type & LARGE ? 'X' : 'x'; + } + ++ buf; + } + } + + /* no align to the left */ + if (!(type & LEFT)) + { + while (size-- > 0) + { + if (buf < end) + { + *buf = c; + } + + ++ buf; + } + } + + while (i < precision--) + { + if (buf < end) + { + *buf = '0'; + } + + ++ buf; + } + + /* put number in the temporary buffer */ + while (i-- > 0 && (precision_bak != 0)) + { + if (buf < end) + { + *buf = tmp[i]; + } + + ++ buf; + } + + while (size-- > 0) + { + if (buf < end) + { + *buf = ' '; + } + + ++ buf; + } + + return buf; +} + +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) /* GCC */ +#pragma GCC diagnostic push +/* ignore warning: this statement may fall through */ +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif /* defined(__GNUC__) && !defined(__ARMCC_VERSION) */ +/** + * @brief This function will fill a formatted string to buffer. + * + * @param buf is the buffer to save formatted string. + * + * @param size is the size of buffer. + * + * @param fmt is the format parameters. + * + * @param args is a list of variable parameters. + * + * @return The number of characters actually written to buffer. + */ +rt_weak int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args) +{ +#ifdef RT_KLIBC_USING_PRINTF_LONGLONG + unsigned long long num = 0; +#else + unsigned long num = 0; +#endif /* RT_KLIBC_USING_PRINTF_LONGLONG */ + int i = 0, len = 0; + char *str = RT_NULL, *end = RT_NULL, c = 0; + const char *s = RT_NULL; + + rt_uint8_t base = 0; /* the base of number */ + rt_uint8_t flags = 0; /* flags to print number */ + rt_uint8_t qualifier = 0; /* 'h', 'l', or 'L' for integer fields */ + rt_int32_t field_width = 0; /* width of output field */ + int precision = 0; /* min. # of digits for integers and max for a string */ + + str = buf; + end = buf + size; + + /* Make sure end is always >= buf */ + if (end < buf) + { + end = ((char *) - 1); + size = end - buf; + } + + for (; *fmt ; ++fmt) + { + if (*fmt != '%') + { + if (str < end) + { + *str = *fmt; + } + + ++ str; + continue; + } + + /* process flags */ + flags = 0; + + while (1) + { + /* skips the first '%' also */ + ++fmt; + if (*fmt == '-') flags |= LEFT; + else if (*fmt == '+') flags |= PLUS; + else if (*fmt == ' ') flags |= SPACE; + else if (*fmt == '#') flags |= SPECIAL; + else if (*fmt == '0') flags |= ZEROPAD; + else break; + } + + /* get field width */ + field_width = -1; + if (_ISDIGIT(*fmt)) + { + field_width = skip_atoi(&fmt); + } + else if (*fmt == '*') + { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) + { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') + { + ++fmt; + if (_ISDIGIT(*fmt)) + { + precision = skip_atoi(&fmt); + } + else if (*fmt == '*') + { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + { + precision = 0; + } + } + + qualifier = 0; /* get the conversion qualifier */ + + if (*fmt == 'h' || *fmt == 'l' || +#ifdef RT_KLIBC_USING_PRINTF_LONGLONG + *fmt == 'L' || +#endif /* RT_KLIBC_USING_PRINTF_LONGLONG */ + *fmt == 'z') + { + qualifier = *fmt; + ++fmt; +#ifdef RT_KLIBC_USING_PRINTF_LONGLONG + if (qualifier == 'l' && *fmt == 'l') + { + qualifier = 'L'; + ++fmt; + } +#endif /* RT_KLIBC_USING_PRINTF_LONGLONG */ + if (qualifier == 'h' && *fmt == 'h') + { + qualifier = 'H'; + ++fmt; + } + } + + /* the default base */ + base = 10; + + switch (*fmt) + { + case 'c': + if (!(flags & LEFT)) + { + while (--field_width > 0) + { + if (str < end) *str = ' '; + ++ str; + } + } + + /* get character */ + c = (rt_uint8_t)va_arg(args, int); + if (str < end) + { + *str = c; + } + ++ str; + + /* put width */ + while (--field_width > 0) + { + if (str < end) *str = ' '; + ++ str; + } + continue; + + case 's': + s = va_arg(args, char *); + if (!s) + { + s = "(NULL)"; + } + + for (len = 0; (len != field_width) && (s[len] != '\0'); len++); + + if (precision > 0 && len > precision) + { + len = precision; + } + + if (!(flags & LEFT)) + { + while (len < field_width--) + { + if (str < end) *str = ' '; + ++ str; + } + } + + for (i = 0; i < len; ++i) + { + if (str < end) *str = *s; + ++ str; + ++ s; + } + + while (len < field_width--) + { + if (str < end) *str = ' '; + ++ str; + } + continue; + + case 'p': + if (field_width == -1) + { + field_width = sizeof(void *) << 1; + field_width += 2; /* `0x` prefix */ + flags |= SPECIAL; + flags |= ZEROPAD; + } + str = print_number(str, end, (unsigned long)va_arg(args, void *), + 16, qualifier, field_width, precision, flags); + continue; + + case '%': + if (str < end) + { + *str = '%'; + } + ++ str; + continue; + + /* integer number formats - set up the flags and "break" */ + case 'b': + base = 2; + break; + case 'o': + base = 8; + break; + + case 'X': + flags |= LARGE; + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + case 'e': + case 'E': + case 'G': + case 'g': + case 'f': + case 'F': + va_arg(args, double); + default: + if (str < end) + { + *str = '%'; + } + ++ str; + + if (*fmt) + { + if (str < end) + { + *str = *fmt; + } + ++ str; + } + else + { + -- fmt; + } + continue; + } + + if (qualifier == 'L') + { + num = va_arg(args, unsigned long long); + } + else if (qualifier == 'l') + { + num = va_arg(args, unsigned long); + } + else if (qualifier == 'H') + { + num = (rt_int8_t)va_arg(args, rt_int32_t); + if (flags & SIGN) + { + num = (rt_int8_t)num; + } + } + else if (qualifier == 'h') + { + num = (rt_uint16_t)va_arg(args, rt_int32_t); + if (flags & SIGN) + { + num = (rt_int16_t)num; + } + } + else if (qualifier == 'z') + { + num = va_arg(args, rt_size_t); + if (flags & SIGN) + { + num = (rt_ssize_t)num; + } + } + else + { + num = (rt_uint32_t)va_arg(args, unsigned long); + } + str = print_number(str, end, num, base, qualifier, field_width, precision, flags); + } + + if (size > 0) + { + if (str < end) + { + *str = '\0'; + } + else + { + end[-1] = '\0'; + } + } + + /* the trailing null byte doesn't count towards the total + * ++str; + */ + return str - buf; +} +RTM_EXPORT(rt_vsnprintf); +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) /* GCC */ +#pragma GCC diagnostic pop /* ignored "-Wimplicit-fallthrough" */ +#endif /* defined(__GNUC__) && !defined(__ARMCC_VERSION) */ + /** * @brief This function will fill a formatted string to buffer. * @@ -77,40 +684,154 @@ int rt_sprintf(char *buf, const char *format, ...) } RTM_EXPORT(rt_sprintf); -#ifdef RT_KLIBC_USING_LIBC_VSNPRINTF -int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args) -{ - return vsnprintf(buf, size, fmt, args); -} -#endif /* RT_KLIBC_USING_LIBC_VSNPRINTF */ -RTM_EXPORT(rt_vsnprintf); - -#ifdef RT_KLIBC_USING_LIBC_VSSCANF -int rt_vsscanf(const char *buffer, const char *format, va_list ap) -{ - return vsscanf(buffer, format, ap); -} -#endif /* RT_KLIBC_USING_LIBC_VSSCANF */ -RTM_EXPORT(rt_vsscanf); +/* errno functions */ /** - * @brief This function parses a formatted string from the input string. + * @brief A global variable used to store the error code. * - * @param str the input string to be parsed. - * - * @param format the format string that specifies how to interpret the input. - * - * @return The number of input items successfully matched and assigned. + * This volatile static integer is used to store the most recent error code globally. + * Its volatile nature ensures that every read operation fetches the most current value, + * providing real-time error status across different parts of the program. */ -int rt_sscanf(const char *str, const char *format, ...) +static volatile int __rt_errno; + +/** + * @struct _errno_str_t + * @brief Structure for mapping error codes to corresponding error strings. + * + * This structure is used to create a mapping that associates an rt_err_t type error code + * with a corresponding error description string. + */ +struct _errno_str_t { - va_list ap; - int rv; + rt_err_t error; /**< Error code of type rt_err_t, representing different kinds of errors. */ + const char *str; /**< Pointer to the error description string. */ +}; - va_start(ap, format); - rv = rt_vsscanf(str, format, ap); - va_end(ap); +/** + * @brief An array containing mappings of error codes to their corresponding error strings. + * + * This array uses the _errno_str_t structure to define several error codes and their + * corresponding error description strings. These mappings can be used at runtime + * to provide more readable error information. + */ +static struct _errno_str_t rt_errno_strs[] = +{ + {RT_EOK , "OK "}, /**< Operation successful. */ + {RT_ERROR , "ERROR "}, /**< General error. */ + {RT_ETIMEOUT, "ETIMOUT"}, /**< Operation timed out. */ + {RT_EFULL , "ERSFULL"}, /**< Resource is full. */ + {RT_EEMPTY , "ERSEPTY"}, /**< Resource is empty. */ + {RT_ENOMEM , "ENOMEM "}, /**< Not enough memory. */ + {RT_ENOSYS , "ENOSYS "}, /**< Function not implemented. */ + {RT_EBUSY , "EBUSY "}, /**< Resource is busy. */ + {RT_EIO , "EIO "}, /**< Input/output error. */ + {RT_EINTR , "EINTRPT"}, /**< Interrupted system call. */ + {RT_EINVAL , "EINVAL "}, /**< Invalid argument. */ + {RT_ENOENT , "ENOENT "}, /**< No such file or directory. */ + {RT_ENOSPC , "ENOSPC "}, /**< No space left on device. */ + {RT_EPERM , "EPERM "}, /**< Operation not permitted. */ + {RT_ETRAP , "ETRAP "}, /**< Trap error. */ +}; - return rv; +/** + * @brief This function return a pointer to a string that contains the + * message of error. + * + * @param error the errorno code + * @return a point to error message string + */ +const char *rt_strerror(rt_err_t error) +{ + int i = 0; + + if (error < 0) + error = -error; + + for (i = 0; i < sizeof(rt_errno_strs) / sizeof(rt_errno_strs[0]); i++) + { + if (rt_errno_strs[i].error == error) + return rt_errno_strs[i].str; + } + + return "EUNKNOW"; } -RTM_EXPORT(rt_sscanf); +RTM_EXPORT(rt_strerror); + +/** + * @brief This function gets the global errno for the current thread. + * + * @return errno + */ +rt_err_t rt_get_errno(void) +{ + rt_thread_t tid = RT_NULL; + + if (rt_interrupt_get_nest() != 0) + { + /* it's in interrupt context */ + return __rt_errno; + } + + tid = rt_thread_self(); + if (tid == RT_NULL) + { + return __rt_errno; + } + + return tid->error; +} +RTM_EXPORT(rt_get_errno); + +/** + * @brief This function sets the global errno for the current thread. + * + * @param error is the errno shall be set. + */ +void rt_set_errno(rt_err_t error) +{ + rt_thread_t tid = RT_NULL; + + if (rt_interrupt_get_nest() != 0) + { + /* it's in interrupt context */ + __rt_errno = error; + + return; + } + + tid = rt_thread_self(); + if (tid == RT_NULL) + { + __rt_errno = error; + + return; + } + + tid->error = error; +} +RTM_EXPORT(rt_set_errno); + +/** + * @brief This function returns the address of the current thread errno. + * + * @return The errno address. + */ +int *_rt_errno(void) +{ + rt_thread_t tid = RT_NULL; + + if (rt_interrupt_get_nest() != 0) + { + return (int *)&__rt_errno; + } + + tid = rt_thread_self(); + if (tid != RT_NULL) + { + return (int *) & (tid->error); + } + + return (int *)&__rt_errno; +} +RTM_EXPORT(_rt_errno); diff --git a/rt-thread/src/klibc/kstring.c b/rt-thread/src/klibc/kstring.c index d2988d6..b3fb3b0 100644 --- a/rt-thread/src/klibc/kstring.c +++ b/rt-thread/src/klibc/kstring.c @@ -8,20 +8,21 @@ * 2024-03-10 Meco Man the first version */ -#include - -#if defined(RT_KLIBC_USING_LIBC_MEMSET) || \ - defined(RT_KLIBC_USING_LIBC_MEMCPY) || \ - defined(RT_KLIBC_USING_LIBC_MEMMOVE) || \ - defined(RT_KLIBC_USING_LIBC_MEMCMP) || \ - defined(RT_KLIBC_USING_LIBC_STRSTR) || \ - defined(RT_KLIBC_USING_LIBC_STRNCPY) || \ - defined(RT_KLIBC_USING_LIBC_STRCPY) || \ - defined(RT_KLIBC_USING_LIBC_STRNCMP) || \ - defined(RT_KLIBC_USING_LIBC_STRCMP) || \ - defined(RT_KLIBC_USING_LIBC_STRLEN) +#include +#include +#include +#include +#ifdef RT_KLIBC_USING_STDLIB #include -#endif +#endif /* RT_KLIBC_USING_STDLIB */ + +#define DBG_TAG "kernel.string" +#ifdef RT_DEBUG_DEVICE +#define DBG_LVL DBG_LOG +#else +#define DBG_LVL DBG_WARNING +#endif /* defined (RT_DEBUG_DEVICE) */ +#include /** * @brief This function will set the content of memory to specified value. @@ -35,12 +36,11 @@ * * @return The address of source memory. */ -#ifndef RT_KLIBC_USING_USER_MEMSET -void *rt_memset(void *s, int c, rt_ubase_t count) +rt_weak void *rt_memset(void *s, int c, rt_ubase_t count) { -#if defined(RT_KLIBC_USING_LIBC_MEMSET) +#if defined(RT_KLIBC_USING_STDLIB_MEMORY) return memset(s, c, count); -#elif defined(RT_KLIBC_USING_TINY_MEMSET) +#elif defined(RT_KLIBC_USING_TINY_SIZE) char *xs = (char *)s; while (count--) @@ -48,7 +48,6 @@ void *rt_memset(void *s, int c, rt_ubase_t count) return s; #else - #define LBLOCKSIZE (sizeof(rt_ubase_t)) #define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1)) #define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE) @@ -104,9 +103,8 @@ void *rt_memset(void *s, int c, rt_ubase_t count) #undef LBLOCKSIZE #undef UNALIGNED #undef TOO_SMALL -#endif /* RT_KLIBC_USING_LIBC_MEMSET */ +#endif /* RT_KLIBC_USING_STDLIB_MEMORY */ } -#endif /* RT_KLIBC_USING_USER_MEMSET */ RTM_EXPORT(rt_memset); /** @@ -120,12 +118,11 @@ RTM_EXPORT(rt_memset); * * @return The address of destination memory */ -#ifndef RT_KLIBC_USING_USER_MEMCPY -void *rt_memcpy(void *dst, const void *src, rt_ubase_t count) +rt_weak void *rt_memcpy(void *dst, const void *src, rt_ubase_t count) { -#if defined(RT_KLIBC_USING_LIBC_MEMCPY) +#if defined(RT_KLIBC_USING_STDLIB_MEMORY) return memcpy(dst, src, count); -#elif defined(RT_KLIBC_USING_TINY_MEMCPY) +#elif defined(RT_KLIBC_USING_TINY_SIZE) char *tmp = (char *)dst, *s = (char *)src; rt_ubase_t len = 0; @@ -192,9 +189,8 @@ void *rt_memcpy(void *dst, const void *src, rt_ubase_t count) #undef BIGBLOCKSIZE #undef LITTLEBLOCKSIZE #undef TOO_SMALL -#endif /* RT_KLIBC_USING_LIBC_MEMCPY */ +#endif /* RT_KLIBC_USING_STDLIB_MEMORY */ } -#endif /* RT_KLIBC_USING_USER_MEMCPY */ RTM_EXPORT(rt_memcpy); /** @@ -210,10 +206,9 @@ RTM_EXPORT(rt_memcpy); * * @return The address of destination memory. */ -#ifndef RT_KLIBC_USING_USER_MEMMOVE void *rt_memmove(void *dest, const void *src, rt_size_t n) { -#ifdef RT_KLIBC_USING_LIBC_MEMMOVE +#ifdef RT_KLIBC_USING_STDLIB_MEMORY return memmove(dest, src, n); #else char *tmp = (char *)dest, *s = (char *)src; @@ -233,9 +228,8 @@ void *rt_memmove(void *dest, const void *src, rt_size_t n) } return dest; -#endif /* RT_KLIBC_USING_LIBC_MEMMOVE */ +#endif /* RT_KLIBC_USING_STDLIB_MEMORY */ } -#endif /* RT_KLIBC_USING_USER_MEMMOVE */ RTM_EXPORT(rt_memmove); /** @@ -252,10 +246,9 @@ RTM_EXPORT(rt_memmove); * If the result > 0, cs is greater than ct. * If the result = 0, cs is equal to ct. */ -#ifndef RT_KLIBC_USING_USER_MEMCMP rt_int32_t rt_memcmp(const void *cs, const void *ct, rt_size_t count) { -#ifdef RT_KLIBC_USING_LIBC_MEMCMP +#ifdef RT_KLIBC_USING_STDLIB_MEMORY return memcmp(cs, ct, count); #else const unsigned char *su1 = RT_NULL, *su2 = RT_NULL; @@ -266,9 +259,8 @@ rt_int32_t rt_memcmp(const void *cs, const void *ct, rt_size_t count) break; return res; -#endif /* RT_KLIBC_USING_LIBC_MEMCMP */ +#endif /* RT_KLIBC_USING_STDLIB_MEMORY */ } -#endif /* RT_KLIBC_USING_USER_MEMCMP */ RTM_EXPORT(rt_memcmp); /** @@ -281,10 +273,9 @@ RTM_EXPORT(rt_memcmp); * * @return The first occurrence of a s2 in s1, or RT_NULL if no found. */ -#ifndef RT_KLIBC_USING_USER_STRSTR char *rt_strstr(const char *s1, const char *s2) { -#ifdef RT_KLIBC_USING_LIBC_STRSTR +#ifdef RT_KLIBC_USING_STDLIB return strstr(s1, s2); #else int l1 = 0, l2 = 0; @@ -308,9 +299,8 @@ char *rt_strstr(const char *s1, const char *s2) } return RT_NULL; -#endif /* RT_KLIBC_USING_LIBC_STRSTR */ +#endif /* RT_KLIBC_USING_STDLIB */ } -#endif /* RT_KLIBC_USING_USER_STRSTR */ RTM_EXPORT(rt_strstr); /** @@ -325,7 +315,6 @@ RTM_EXPORT(rt_strstr); * If the result > 0, a is greater than a. * If the result = 0, a is equal to a. */ -#ifndef RT_KLIBC_USING_USER_STRCASECMP rt_int32_t rt_strcasecmp(const char *a, const char *b) { int ca = 0, cb = 0; @@ -343,7 +332,6 @@ rt_int32_t rt_strcasecmp(const char *a, const char *b) return ca - cb; } -#endif /* RT_KLIBC_USING_USER_STRCASECMP */ RTM_EXPORT(rt_strcasecmp); /** @@ -357,10 +345,9 @@ RTM_EXPORT(rt_strcasecmp); * * @return The address where the copied content is stored. */ -#ifndef RT_KLIBC_USING_USER_STRNCPY char *rt_strncpy(char *dst, const char *src, rt_size_t n) { -#ifdef RT_KLIBC_USING_LIBC_STRNCPY +#ifdef RT_KLIBC_USING_STDLIB return strncpy(dst, src, n); #else if (n != 0) @@ -384,9 +371,8 @@ char *rt_strncpy(char *dst, const char *src, rt_size_t n) } return (dst); -#endif /* RT_KLIBC_USING_LIBC_STRNCPY */ +#endif /* RT_KLIBC_USING_STDLIB */ } -#endif /* RT_KLIBC_USING_USER_STRNCPY */ RTM_EXPORT(rt_strncpy); /** @@ -398,10 +384,9 @@ RTM_EXPORT(rt_strncpy); * * @return The address where the copied content is stored. */ -#ifndef RT_KLIBC_USING_USER_STRCPY char *rt_strcpy(char *dst, const char *src) { -#ifdef RT_KLIBC_USING_LIBC_STRCPY +#ifdef RT_KLIBC_USING_STDLIB return strcpy(dst, src); #else char *dest = dst; @@ -415,9 +400,8 @@ char *rt_strcpy(char *dst, const char *src) *dst = '\0'; return dest; -#endif /* RT_KLIBC_USING_LIBC_STRCPY */ +#endif /* RT_KLIBC_USING_STDLIB */ } -#endif /* RT_KLIBC_USING_USER_STRCPY */ RTM_EXPORT(rt_strcpy); /** @@ -434,10 +418,9 @@ RTM_EXPORT(rt_strcpy); * If the result > 0, cs is greater than ct. * If the result = 0, cs is equal to ct. */ -#ifndef RT_KLIBC_USING_USER_STRNCMP rt_int32_t rt_strncmp(const char *cs, const char *ct, rt_size_t count) { -#ifdef RT_KLIBC_USING_LIBC_STRNCMP +#ifdef RT_KLIBC_USING_STDLIB return strncmp(cs, ct, count); #else signed char res = 0; @@ -453,9 +436,8 @@ rt_int32_t rt_strncmp(const char *cs, const char *ct, rt_size_t count) } return res; -#endif /* RT_KLIBC_USING_LIBC_STRNCMP */ +#endif /* RT_KLIBC_USING_STDLIB */ } -#endif /* RT_KLIBC_USING_USER_STRNCMP */ RTM_EXPORT(rt_strncmp); /** @@ -470,10 +452,9 @@ RTM_EXPORT(rt_strncmp); * If the result > 0, cs is greater than ct. * If the result = 0, cs is equal to ct. */ -#ifndef RT_KLIBC_USING_USER_STRCMP rt_int32_t rt_strcmp(const char *cs, const char *ct) { -#ifdef RT_KLIBC_USING_LIBC_STRCMP +#ifdef RT_KLIBC_USING_STDLIB return strcmp(cs, ct); #else while (*cs && *cs == *ct) @@ -483,9 +464,8 @@ rt_int32_t rt_strcmp(const char *cs, const char *ct) } return (*cs - *ct); -#endif /* RT_KLIBC_USING_LIBC_STRCMP */ +#endif /* RT_KLIBC_USING_STDLIB */ } -#endif /* RT_KLIBC_USING_USER_STRCMP */ RTM_EXPORT(rt_strcmp); /** @@ -496,18 +476,16 @@ RTM_EXPORT(rt_strcmp); * * @return The length of string. */ -#ifndef RT_KLIBC_USING_USER_STRLEN rt_size_t rt_strlen(const char *s) { -#ifdef RT_KLIBC_USING_LIBC_STRLEN +#ifdef RT_KLIBC_USING_STDLIB return strlen(s); #else const char *sc = RT_NULL; for (sc = s; *sc != '\0'; ++sc); return sc - s; -#endif /* RT_KLIBC_USING_LIBC_STRLEN */ +#endif /* RT_KLIBC_USING_STDLIB */ } -#endif /* RT_KLIBC_USING_USER_STRLEN */ RTM_EXPORT(rt_strlen); /** @@ -523,14 +501,12 @@ RTM_EXPORT(rt_strlen); * * @return The length of string. */ -#ifndef RT_KLIBC_USING_USER_STRNLEN rt_size_t rt_strnlen(const char *s, rt_ubase_t maxlen) { const char *sc; for (sc = s; *sc != '\0' && (rt_ubase_t)(sc - s) < maxlen; ++sc); return sc - s; } -#endif /* RT_KLIBC_USING_USER_STRNLEN */ RTM_EXPORT(rt_strnlen); #ifdef RT_USING_HEAP diff --git a/rt-thread/src/klibc/rt_vsnprintf_std.c b/rt-thread/src/klibc/rt_vsnprintf_std.c deleted file mode 100644 index 583cfb7..0000000 --- a/rt-thread/src/klibc/rt_vsnprintf_std.c +++ /dev/null @@ -1,1351 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-11-27 Meco Man porting for rt_vsnprintf as the fully functional version - * 2024-11-19 Meco Man move to klibc - */ - -/** - * @author (c) Eyal Rozenberg - * 2021-2022, Haifa, Palestine/Israel - * @author (c) Marco Paland (info@paland.com) - * 2014-2019, PALANDesign Hannover, Germany - * - * @note Others have made smaller contributions to this file: see the - * contributors page at https://github.com/eyalroz/printf/graphs/contributors - * or ask one of the authors. The original code for exponential specifiers was - * contributed by Martijn Jasperse . - * - * @brief Small stand-alone implementation of the printf family of functions - * (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems with - * a very limited resources. - * - * @note the implementations are thread-safe; re-entrant; use no functions from - * the standard library; and do not dynamically allocate any memory. - * - * @license The MIT License (MIT) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include -#include -#include - -// 'ntoa' conversion buffer size, this must be big enough to hold one converted -// numeric number including padded zeros (dynamically created on stack) -#ifndef RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE -#define RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE 32 -#endif - -// size of the fixed (on-stack) buffer for printing individual decimal numbers. -// this must be big enough to hold one converted floating-point value including -// padded zeros. -#ifndef RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE -#define RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE 32 -#endif - -// Support for the decimal notation floating point conversion specifiers (%f, %F) -#ifndef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS -#define RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS -#endif - -// Support for the exponential notation floating point conversion specifiers (%e, %g, %E, %G) -#ifndef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS -#define RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS -#endif - -// Support for the length write-back specifier (%n) -#ifndef RT_KLIBC_USING_VSNPRINTF_WRITEBACK_SPECIFIER -#define RT_KLIBC_USING_VSNPRINTF_WRITEBACK_SPECIFIER -#endif - -// Default precision for the floating point conversion specifiers (the C standard sets this at 6) -#ifndef RT_KLIBC_USING_VSNPRINTF_FLOAT_PRECISION -#define RT_KLIBC_USING_VSNPRINTF_FLOAT_PRECISION 6 -#endif - -// According to the C languages standard, printf() and related functions must be able to print any -// integral number in floating-point notation, regardless of length, when using the %f specifier - -// possibly hundreds of characters, potentially overflowing your buffers. In this implementation, -// all values beyond this threshold are switched to exponential notation. -#ifndef RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL -#define RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL 9 -#endif - -// Support for the long long integral types (with the ll, z and t length modifiers for specifiers -// %d,%i,%o,%x,%X,%u, and with the %p specifier). Note: 'L' (long double) is not supported. -#ifndef RT_KLIBC_USING_VSNPRINTF_LONGLONG -#define RT_KLIBC_USING_VSNPRINTF_LONGLONG -#endif - -// The number of terms in a Taylor series expansion of log_10(x) to -// use for approximation - including the power-zero term (i.e. the -// value at the point of expansion). -#ifndef RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS -#define RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS 4 -#endif - -// Be extra-safe, and don't assume format specifiers are completed correctly -// before the format string end. -#if !defined(RT_KLIBC_USING_VSNPRINTF_CHECK_NUL_IN_FORMAT_SPECIFIER) || defined(RT_USING_DEBUG) -#define RT_KLIBC_USING_VSNPRINTF_CHECK_NUL_IN_FORMAT_SPECIFIER -#endif - -#if RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS <= 1 -#error "At least one non-constant Taylor expansion is necessary for the log10() calculation" -#endif - -/////////////////////////////////////////////////////////////////////////////// - -#define PRINTF_PREFER_DECIMAL false -#define PRINTF_PREFER_EXPONENTIAL true - -// The following will convert the number-of-digits into an exponential-notation literal -#define PRINTF_CONCATENATE(s1, s2) s1##s2 -#define PRINTF_EXPAND_THEN_CONCATENATE(s1, s2) PRINTF_CONCATENATE(s1, s2) -#define PRINTF_FLOAT_NOTATION_THRESHOLD PRINTF_EXPAND_THEN_CONCATENATE(1e,RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL) - -// internal flag definitions -#define FLAGS_ZEROPAD (1U << 0U) -#define FLAGS_LEFT (1U << 1U) -#define FLAGS_PLUS (1U << 2U) -#define FLAGS_SPACE (1U << 3U) -#define FLAGS_HASH (1U << 4U) -#define FLAGS_UPPERCASE (1U << 5U) -#define FLAGS_CHAR (1U << 6U) -#define FLAGS_SHORT (1U << 7U) -#define FLAGS_INT (1U << 8U) -// Only used with RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS -#define FLAGS_LONG (1U << 9U) -#define FLAGS_LONG_LONG (1U << 10U) -#define FLAGS_PRECISION (1U << 11U) -#define FLAGS_ADAPT_EXP (1U << 12U) -#define FLAGS_POINTER (1U << 13U) -// Note: Similar, but not identical, effect as FLAGS_HASH -#define FLAGS_SIGNED (1U << 14U) -// Only used with RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - -#define FLAGS_INT8 FLAGS_CHAR - -#if (SHRT_MAX == 32767LL) -#define FLAGS_INT16 FLAGS_SHORT -#elif (INT_MAX == 32767LL) -#define FLAGS_INT16 FLAGS_INT -#elif (LONG_MAX == 32767LL) -#define FLAGS_INT16 FLAGS_LONG -#elif (LLONG_MAX == 32767LL) -#define FLAGS_INT16 FLAGS_LONG_LONG -#else -#error "No basic integer type has a size of 16 bits exactly" -#endif - -#if (SHRT_MAX == 2147483647LL) -#define FLAGS_INT32 FLAGS_SHORT -#elif (INT_MAX == 2147483647LL) -#define FLAGS_INT32 FLAGS_INT -#elif (LONG_MAX == 2147483647LL) -#define FLAGS_INT32 FLAGS_LONG -#elif (LLONG_MAX == 2147483647LL) -#define FLAGS_INT32 FLAGS_LONG_LONG -#else -#error "No basic integer type has a size of 32 bits exactly" -#endif - -#if (SHRT_MAX == 9223372036854775807LL) -#define FLAGS_INT64 FLAGS_SHORT -#elif (INT_MAX == 9223372036854775807LL) -#define FLAGS_INT64 FLAGS_INT -#elif (LONG_MAX == 9223372036854775807LL) -#define FLAGS_INT64 FLAGS_LONG -#elif (LLONG_MAX == 9223372036854775807LL) -#define FLAGS_INT64 FLAGS_LONG_LONG -#else -#error "No basic integer type has a size of 64 bits exactly" -#endif - -#endif // RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - - -typedef unsigned int printf_flags_t; - -#define BASE_BINARY 2 -#define BASE_OCTAL 8 -#define BASE_DECIMAL 10 -#define BASE_HEX 16 - -typedef uint8_t numeric_base_t; - -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG -typedef unsigned long long printf_unsigned_value_t; -typedef long long printf_signed_value_t; -#else -typedef unsigned long printf_unsigned_value_t; -typedef long printf_signed_value_t; -#endif - -// The printf()-family functions return an `int`; it is therefore -// unnecessary/inappropriate to use size_t - often larger than int -// in practice - for non-negative related values, such as widths, -// precisions, offsets into buffers used for printing and the sizes -// of these buffers. instead, we use: -typedef unsigned int printf_size_t; -#define PRINTF_MAX_POSSIBLE_BUFFER_SIZE INT_MAX - // If we were to nitpick, this would actually be INT_MAX + 1, - // since INT_MAX is the maximum return value, which excludes the - // trailing '\0'. - -#if defined(RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS) || defined(RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS) -#include -#if FLT_RADIX != 2 -#error "Non-binary-radix floating-point types are unsupported." -#endif - -#if DBL_MANT_DIG == 24 - -#define DOUBLE_SIZE_IN_BITS 32 -typedef uint32_t double_uint_t; -#define DOUBLE_EXPONENT_MASK 0xFFU -#define DOUBLE_BASE_EXPONENT 127 -#define DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10 -38 -#define DOUBLE_MAX_SUBNORMAL_POWER_OF_10 1e-38 - -#elif DBL_MANT_DIG == 53 - -#define DOUBLE_SIZE_IN_BITS 64 -typedef uint64_t double_uint_t; -#define DOUBLE_EXPONENT_MASK 0x7FFU -#define DOUBLE_BASE_EXPONENT 1023 -#define DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10 -308 -#define DOUBLE_MAX_SUBNORMAL_POWER_OF_10 ((double)1e-308L) - -#else -#error "Unsupported double type configuration" -#endif -#define DOUBLE_STORED_MANTISSA_BITS (DBL_MANT_DIG - 1) - -typedef union { - double_uint_t U; - double F; -} double_with_bit_access; - -// This is unnecessary in C99, since compound initializers can be used, -// but: -// 1. Some compilers are finicky about this; -// 2. Some people may want to convert this to C89; -// 3. If you try to use it as C++, only C++20 supports compound literals -static inline double_with_bit_access get_bit_access(double x) -{ - double_with_bit_access dwba; - dwba.F = x; - return dwba; -} - -static inline int get_sign_bit(double x) -{ - // The sign is stored in the highest bit - return (int) (get_bit_access(x).U >> (DOUBLE_SIZE_IN_BITS - 1)); -} - -static inline int get_exp2(double_with_bit_access x) -{ - // The exponent in an IEEE-754 floating-point number occupies a contiguous - // sequence of bits (e.g. 52..62 for 64-bit doubles), but with a non-trivial representation: An - // unsigned offset from some negative value (with the extremal offset values reserved for - // special use). - return (int)((x.U >> DOUBLE_STORED_MANTISSA_BITS ) & DOUBLE_EXPONENT_MASK) - DOUBLE_BASE_EXPONENT; -} -#define PRINTF_ABS(_x) ( (_x) > 0 ? (_x) : -(_x) ) - -#endif // (RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS || RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS) - -// Note in particular the behavior here on LONG_MIN or LLONG_MIN; it is valid -// and well-defined, but if you're not careful you can easily trigger undefined -// behavior with -LONG_MIN or -LLONG_MIN -#define ABS_FOR_PRINTING(_x) ((printf_unsigned_value_t) ( (_x) > 0 ? (_x) : -((printf_signed_value_t)_x) )) - -// wrapper (used as buffer) for output function type -// -// One of the following must hold: -// 1. max_chars is 0 -// 2. buffer is non-null -// 3. function is non-null -// -// ... otherwise bad things will happen. -typedef struct { - void (*function)(char c, void* extra_arg); - void* extra_function_arg; - char* buffer; - printf_size_t pos; - printf_size_t max_chars; -} output_gadget_t; - -// Note: This function currently assumes it is not passed a '\0' c, -// or alternatively, that '\0' can be passed to the function in the output -// gadget. The former assumption holds within the printf library. It also -// assumes that the output gadget has been properly initialized. -static inline void putchar_via_gadget(output_gadget_t* gadget, char c) -{ - printf_size_t write_pos = gadget->pos++; - // We're _always_ increasing pos, so as to count how may characters - // _would_ have been written if not for the max_chars limitation - if (write_pos >= gadget->max_chars) { - return; - } - if (gadget->function != NULL) { - // No check for c == '\0' . - gadget->function(c, gadget->extra_function_arg); - } - else { - // it must be the case that gadget->buffer != NULL , due to the constraint - // on output_gadget_t ; and note we're relying on write_pos being non-negative. - gadget->buffer[write_pos] = c; - } -} - -// Possibly-write the string-terminating '\0' character -static inline void append_termination_with_gadget(output_gadget_t* gadget) -{ - if (gadget->function != NULL || gadget->max_chars == 0) { - return; - } - if (gadget->buffer == NULL) { - return; - } - printf_size_t null_char_pos = gadget->pos < gadget->max_chars ? gadget->pos : gadget->max_chars - 1; - gadget->buffer[null_char_pos] = '\0'; -} - -static inline output_gadget_t discarding_gadget(void) -{ - output_gadget_t gadget; - gadget.function = NULL; - gadget.extra_function_arg = NULL; - gadget.buffer = NULL; - gadget.pos = 0; - gadget.max_chars = 0; - return gadget; -} - -static inline output_gadget_t buffer_gadget(char* buffer, size_t buffer_size) -{ - printf_size_t usable_buffer_size = (buffer_size > PRINTF_MAX_POSSIBLE_BUFFER_SIZE) ? - PRINTF_MAX_POSSIBLE_BUFFER_SIZE : (printf_size_t) buffer_size; - output_gadget_t result = discarding_gadget(); - if (buffer != NULL) { - result.buffer = buffer; - result.max_chars = usable_buffer_size; - } - return result; -} - -// internal secure strlen -// @return The length of the string (excluding the terminating 0) limited by 'maxsize' -// @note strlen uses size_t, but wes only use this function with printf_size_t -// variables - hence the signature. -static inline printf_size_t strnlen_s_(const char* str, printf_size_t maxsize) -{ - const char* s; - for (s = str; *s && maxsize--; ++s); - return (printf_size_t)(s - str); -} - - -// internal test if char is a digit (0-9) -// @return true if char is a digit -static inline bool is_digit_(char ch) -{ - return (ch >= '0') && (ch <= '9'); -} - - -// internal ASCII string to printf_size_t conversion -static printf_size_t atou_(const char** str) -{ - printf_size_t i = 0U; - while (is_digit_(**str)) { - i = i * 10U + (printf_size_t)(*((*str)++) - '0'); - } - return i; -} - - -// output the specified string in reverse, taking care of any zero-padding -static void out_rev_(output_gadget_t* output, const char* buf, printf_size_t len, printf_size_t width, printf_flags_t flags) -{ - const printf_size_t start_pos = output->pos; - - // pad spaces up to given width - if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) { - for (printf_size_t i = len; i < width; i++) { - putchar_via_gadget(output, ' '); - } - } - - // reverse string - while (len) { - putchar_via_gadget(output, buf[--len]); - } - - // append pad spaces up to given width - if (flags & FLAGS_LEFT) { - while (output->pos - start_pos < width) { - putchar_via_gadget(output, ' '); - } - } -} - - -// Invoked by print_integer after the actual number has been printed, performing necessary -// work on the number's prefix (as the number is initially printed in reverse order) -static void print_integer_finalization(output_gadget_t* output, char* buf, printf_size_t len, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags) -{ - printf_size_t unpadded_len = len; - - // pad with leading zeros - { - if (!(flags & FLAGS_LEFT)) { - if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { - width--; - } - while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE)) { - buf[len++] = '0'; - } - } - - while ((len < precision) && (len < RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE)) { - buf[len++] = '0'; - } - - if (base == BASE_OCTAL && (len > unpadded_len)) { - // Since we've written some zeros, we've satisfied the alternative format leading space requirement - flags &= ~FLAGS_HASH; - } - } - - // handle hash - if (flags & (FLAGS_HASH | FLAGS_POINTER)) { - if (!(flags & FLAGS_PRECISION) && len && ((len == precision) || (len == width))) { - // Let's take back some padding digits to fit in what will eventually - // be the format-specific prefix - if (unpadded_len < len) { - len--; // This should suffice for BASE_OCTAL - } - if (len && (base == BASE_HEX || base == BASE_BINARY) && (unpadded_len < len)) { - len--; // ... and an extra one for 0x or 0b - } - } - if ((base == BASE_HEX) && !(flags & FLAGS_UPPERCASE) && (len < RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE)) { - buf[len++] = 'x'; - } - else if ((base == BASE_HEX) && (flags & FLAGS_UPPERCASE) && (len < RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE)) { - buf[len++] = 'X'; - } - else if ((base == BASE_BINARY) && (len < RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE)) { - buf[len++] = 'b'; - } - if (len < RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE) { - buf[len++] = '0'; - } - } - - if (len < RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE) { - if (negative) { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) { - buf[len++] = ' '; - } - } - - out_rev_(output, buf, len, width, flags); -} - -// An internal itoa-like function -static void print_integer(output_gadget_t* output, printf_unsigned_value_t value, bool negative, numeric_base_t base, printf_size_t precision, printf_size_t width, printf_flags_t flags) -{ - char buf[RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE]; - printf_size_t len = 0U; - - if (!value) { - if ( !(flags & FLAGS_PRECISION) ) { - buf[len++] = '0'; - flags &= ~FLAGS_HASH; - // We drop this flag this since either the alternative and regular modes of the specifier - // don't differ on 0 values, or (in the case of octal) we've already provided the special - // handling for this mode. - } - else if (base == BASE_HEX) { - flags &= ~FLAGS_HASH; - // We drop this flag this since either the alternative and regular modes of the specifier - // don't differ on 0 values - } - } - else { - do { - const char digit = (char)(value % base); - buf[len++] = (char)(digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10); - value /= base; - } while (value && (len < RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE)); - } - - print_integer_finalization(output, buf, len, negative, base, precision, width, flags); -} - -#if defined(RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS) || defined(RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS) - -// Stores a fixed-precision representation of a double relative -// to a fixed precision (which cannot be determined by examining this structure) -struct double_components { - int_fast64_t integral; - int_fast64_t fractional; - // ... truncation of the actual fractional part of the double value, scaled - // by the precision value - bool is_negative; -}; - -#define NUM_DECIMAL_DIGITS_IN_INT64_T 18 -#define PRINTF_MAX_PRECOMPUTED_POWER_OF_10 NUM_DECIMAL_DIGITS_IN_INT64_T -static const double powers_of_10[NUM_DECIMAL_DIGITS_IN_INT64_T] = { - 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, - 1e09, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17 -}; - -#define PRINTF_MAX_SUPPORTED_PRECISION NUM_DECIMAL_DIGITS_IN_INT64_T - 1 - - -// Break up a double number - which is known to be a finite non-negative number - -// into its base-10 parts: integral - before the decimal point, and fractional - after it. -// Taken the precision into account, but does not change it even internally. -static struct double_components get_components(double number, printf_size_t precision) -{ - struct double_components number_; - number_.is_negative = get_sign_bit(number); - double abs_number = (number_.is_negative) ? -number : number; - number_.integral = (int_fast64_t)abs_number; - double remainder = (abs_number - (double) number_.integral) * powers_of_10[precision]; - number_.fractional = (int_fast64_t)remainder; - - remainder -= (double) number_.fractional; - - if (remainder > 0.5) { - ++number_.fractional; - // handle rollover, e.g. case 0.99 with precision 1 is 1.0 - if ((double) number_.fractional >= powers_of_10[precision]) { - number_.fractional = 0; - ++number_.integral; - } - } - else if ((remainder == 0.5) && ((number_.fractional == 0U) || (number_.fractional & 1U))) { - // if halfway, round up if odd OR if last digit is 0 - ++number_.fractional; - } - - if (precision == 0U) { - remainder = abs_number - (double) number_.integral; - if ((!(remainder < 0.5) || (remainder > 0.5)) && (number_.integral & 1)) { - // exactly 0.5 and ODD, then round up - // 1.5 -> 2, but 2.5 -> 2 - ++number_.integral; - } - } - return number_; -} - -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS -struct scaling_factor { - double raw_factor; - bool multiply; // if true, need to multiply by raw_factor; otherwise need to divide by it -}; - -static double apply_scaling(double num, struct scaling_factor normalization) -{ - return normalization.multiply ? num * normalization.raw_factor : num / normalization.raw_factor; -} - -static double unapply_scaling(double normalized, struct scaling_factor normalization) -{ -#if defined(__GNUC__) && !defined(__ARMCC_VERSION) /* GCC */ -// accounting for a static analysis bug in GCC 6.x and earlier -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - return normalization.multiply ? normalized / normalization.raw_factor : normalized * normalization.raw_factor; -#if defined(__GNUC__) && !defined(__ARMCC_VERSION) /* GCC */ -#pragma GCC diagnostic pop -#endif -} - -static struct scaling_factor update_normalization(struct scaling_factor sf, double extra_multiplicative_factor) -{ - struct scaling_factor result; - if (sf.multiply) { - result.multiply = true; - result.raw_factor = sf.raw_factor * extra_multiplicative_factor; - } - else { - int factor_exp2 = get_exp2(get_bit_access(sf.raw_factor)); - int extra_factor_exp2 = get_exp2(get_bit_access(extra_multiplicative_factor)); - - // Divide the larger-exponent raw raw_factor by the smaller - if (PRINTF_ABS(factor_exp2) > PRINTF_ABS(extra_factor_exp2)) { - result.multiply = false; - result.raw_factor = sf.raw_factor / extra_multiplicative_factor; - } - else { - result.multiply = true; - result.raw_factor = extra_multiplicative_factor / sf.raw_factor; - } - } - return result; -} - -static struct double_components get_normalized_components(bool negative, printf_size_t precision, double non_normalized, struct scaling_factor normalization, int floored_exp10) -{ - struct double_components components; - components.is_negative = negative; - double scaled = apply_scaling(non_normalized, normalization); - - bool close_to_representation_extremum = ( (-floored_exp10 + (int) precision) >= DBL_MAX_10_EXP - 1 ); - if (close_to_representation_extremum) { - // We can't have a normalization factor which also accounts for the precision, i.e. moves - // some decimal digits into the mantissa, since it's unrepresentable, or nearly unrepresentable. - // So, we'll give up early on getting extra precision... - return get_components(negative ? -scaled : scaled, precision); - } - components.integral = (int_fast64_t) scaled; - double remainder = non_normalized - unapply_scaling((double) components.integral, normalization); - double prec_power_of_10 = powers_of_10[precision]; - struct scaling_factor account_for_precision = update_normalization(normalization, prec_power_of_10); - double scaled_remainder = apply_scaling(remainder, account_for_precision); - double rounding_threshold = 0.5; - - components.fractional = (int_fast64_t) scaled_remainder; // when precision == 0, the assigned value should be 0 - scaled_remainder -= (double) components.fractional; //when precision == 0, this will not change scaled_remainder - - components.fractional += (scaled_remainder >= rounding_threshold); - if (scaled_remainder == rounding_threshold) { - // banker's rounding: Round towards the even number (making the mean error 0) - components.fractional &= ~((int_fast64_t) 0x1); - } - // handle rollover, e.g. the case of 0.99 with precision 1 becoming (0,100), - // and must then be corrected into (1, 0). - // Note: for precision = 0, this will "translate" the rounding effect from - // the fractional part to the integral part where it should actually be - // felt (as prec_power_of_10 is 1) - if ((double) components.fractional >= prec_power_of_10) { - components.fractional = 0; - ++components.integral; - } - return components; -} -#endif // RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - -static void print_broken_up_decimal( - struct double_components number_, output_gadget_t* output, printf_size_t precision, - printf_size_t width, printf_flags_t flags, char *buf, printf_size_t len) -{ - if (precision != 0U) { - // do fractional part, as an unsigned number - - printf_size_t count = precision; - - // %g/%G mandates we skip the trailing 0 digits... - if ((flags & FLAGS_ADAPT_EXP) && !(flags & FLAGS_HASH) && (number_.fractional > 0)) { - while(true) { - int_fast64_t digit = number_.fractional % 10U; - if (digit != 0) { - break; - } - --count; - number_.fractional /= 10U; - - } - // ... and even the decimal point if there are no - // non-zero fractional part digits (see below) - } - - if (number_.fractional > 0 || !(flags & FLAGS_ADAPT_EXP) || (flags & FLAGS_HASH) ) { - while (len < RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE) { - --count; - buf[len++] = (char)('0' + number_.fractional % 10U); - if (!(number_.fractional /= 10U)) { - break; - } - } - // add extra 0s - while ((len < RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE) && (count > 0U)) { - buf[len++] = '0'; - --count; - } - if (len < RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE) { - buf[len++] = '.'; - } - } - } - else { - if ((flags & FLAGS_HASH) && (len < RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE)) { - buf[len++] = '.'; - } - } - - // Write the integer part of the number (it comes after the fractional - // since the character order is reversed) - while (len < RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE) { - buf[len++] = (char)('0' + (number_.integral % 10)); - if (!(number_.integral /= 10)) { - break; - } - } - - // pad leading zeros - if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) { - if (width && (number_.is_negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) { - width--; - } - while ((len < width) && (len < RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE)) { - buf[len++] = '0'; - } - } - - if (len < RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE) { - if (number_.is_negative) { - buf[len++] = '-'; - } - else if (flags & FLAGS_PLUS) { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & FLAGS_SPACE) { - buf[len++] = ' '; - } - } - - out_rev_(output, buf, len, width, flags); -} - - // internal ftoa for fixed decimal floating point -static void print_decimal_number(output_gadget_t* output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char* buf, printf_size_t len) -{ - struct double_components value_ = get_components(number, precision); - print_broken_up_decimal(value_, output, precision, width, flags, buf, len); -} - -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - -// A floor function - but one which only works for numbers whose -// floor value is representable by an int. -static int bastardized_floor(double x) -{ - if (x >= 0) { return (int) x; } - int n = (int) x; - return ( ((double) n) == x ) ? n : n-1; -} - -// Computes the base-10 logarithm of the input number - which must be an actual -// positive number (not infinity or NaN, nor a sub-normal) -static double log10_of_positive(double positive_number) -{ - // The implementation follows David Gay (https://www.ampl.com/netlib/fp/dtoa.c). - // - // Since log_10 ( M * 2^x ) = log_10(M) + x , we can separate the components of - // our input number, and need only solve log_10(M) for M between 1 and 2 (as - // the base-2 mantissa is always 1-point-something). In that limited range, a - // Taylor series expansion of log10(x) should serve us well enough; and we'll - // take the mid-point, 1.5, as the point of expansion. - - double_with_bit_access dwba = get_bit_access(positive_number); - // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) - int exp2 = get_exp2(dwba); - // drop the exponent, so dwba.F comes into the range [1,2) - dwba.U = (dwba.U & (((double_uint_t) (1) << DOUBLE_STORED_MANTISSA_BITS) - 1U)) | - ((double_uint_t) DOUBLE_BASE_EXPONENT << DOUBLE_STORED_MANTISSA_BITS); - double z = (dwba.F - 1.5); - return ( - // Taylor expansion around 1.5: - 0.1760912590556812420 // Expansion term 0: ln(1.5) / ln(10) - + z * 0.2895296546021678851 // Expansion term 1: (M - 1.5) * 2/3 / ln(10) -#if RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS > 2 - - z*z * 0.0965098848673892950 // Expansion term 2: (M - 1.5)^2 * 2/9 / ln(10) -#if RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS > 3 - + z*z*z * 0.0428932821632841311 // Expansion term 2: (M - 1.5)^3 * 8/81 / ln(10) -#endif -#endif - // exact log_2 of the exponent x, with logarithm base change - + exp2 * 0.30102999566398119521 // = exp2 * log_10(2) = exp2 * ln(2)/ln(10) - ); -} - - -static double pow10_of_int(int floored_exp10) -{ - // A crude hack for avoiding undesired behavior with barely-normal or slightly-subnormal values. - if (floored_exp10 == DOUBLE_MAX_SUBNORMAL_EXPONENT_OF_10) { - return DOUBLE_MAX_SUBNORMAL_POWER_OF_10; - } - // Compute 10^(floored_exp10) but (try to) make sure that doesn't overflow - double_with_bit_access dwba; - int exp2 = bastardized_floor(floored_exp10 * 3.321928094887362 + 0.5); - const double z = floored_exp10 * 2.302585092994046 - exp2 * 0.6931471805599453; - const double z2 = z * z; - dwba.U = ((double_uint_t)(exp2) + DOUBLE_BASE_EXPONENT) << DOUBLE_STORED_MANTISSA_BITS; - // compute exp(z) using continued fractions, - // see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex - dwba.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); - return dwba.F; -} - -static void print_exponential_number(output_gadget_t* output, double number, printf_size_t precision, printf_size_t width, printf_flags_t flags, char* buf, printf_size_t len) -{ - const bool negative = get_sign_bit(number); - // This number will decrease gradually (by factors of 10) as we "extract" the exponent out of it - double abs_number = negative ? -number : number; - - int floored_exp10; - bool abs_exp10_covered_by_powers_table; - struct scaling_factor normalization; - - - // Determine the decimal exponent - if (abs_number == 0.0) { - // TODO: This is a special-case for 0.0 (and -0.0); but proper handling is required for denormals more generally. - floored_exp10 = 0; // ... and no need to set a normalization factor or check the powers table - } - else { - double exp10 = log10_of_positive(abs_number); - floored_exp10 = bastardized_floor(exp10); - double p10 = pow10_of_int(floored_exp10); - // correct for rounding errors - if (abs_number < p10) { - floored_exp10--; - p10 /= 10; - } - abs_exp10_covered_by_powers_table = PRINTF_ABS(floored_exp10) < PRINTF_MAX_PRECOMPUTED_POWER_OF_10; - normalization.raw_factor = abs_exp10_covered_by_powers_table ? powers_of_10[PRINTF_ABS(floored_exp10)] : p10; - } - - // We now begin accounting for the widths of the two parts of our printed field: - // the decimal part after decimal exponent extraction, and the base-10 exponent part. - // For both of these, the value of 0 has a special meaning, but not the same one: - // a 0 exponent-part width means "don't print the exponent"; a 0 decimal-part width - // means "use as many characters as necessary". - - bool fall_back_to_decimal_only_mode = false; - if (flags & FLAGS_ADAPT_EXP) { - int required_significant_digits = (precision == 0) ? 1 : (int) precision; - // Should we want to fall-back to "%f" mode, and only print the decimal part? - fall_back_to_decimal_only_mode = (floored_exp10 >= -4 && floored_exp10 < required_significant_digits); - // Now, let's adjust the precision - // This also decided how we adjust the precision value - as in "%g" mode, - // "precision" is the number of _significant digits_, and this is when we "translate" - // the precision value to an actual number of decimal digits. - int precision_ = fall_back_to_decimal_only_mode ? - (int) precision - 1 - floored_exp10 : - (int) precision - 1; // the presence of the exponent ensures only one significant digit comes before the decimal point - precision = (precision_ > 0 ? (unsigned) precision_ : 0U); - flags |= FLAGS_PRECISION; // make sure print_broken_up_decimal respects our choice above - } - - normalization.multiply = (floored_exp10 < 0 && abs_exp10_covered_by_powers_table); - bool should_skip_normalization = (fall_back_to_decimal_only_mode || floored_exp10 == 0); - struct double_components decimal_part_components = - should_skip_normalization ? - get_components(negative ? -abs_number : abs_number, precision) : - get_normalized_components(negative, precision, abs_number, normalization, floored_exp10); - - // Account for roll-over, e.g. rounding from 9.99 to 100.0 - which effects - // the exponent and may require additional tweaking of the parts - if (fall_back_to_decimal_only_mode) { - if ((flags & FLAGS_ADAPT_EXP) && floored_exp10 >= -1 && decimal_part_components.integral == powers_of_10[floored_exp10 + 1]) { - floored_exp10++; // Not strictly necessary, since floored_exp10 is no longer really used - precision--; - // ... and it should already be the case that decimal_part_components.fractional == 0 - } - // TODO: What about rollover strictly within the fractional part? - } - else { - if (decimal_part_components.integral >= 10) { - floored_exp10++; - decimal_part_components.integral = 1; - decimal_part_components.fractional = 0; - } - } - - // the floored_exp10 format is "E%+03d" and largest possible floored_exp10 value for a 64-bit double - // is "307" (for 2^1023), so we set aside 4-5 characters overall - printf_size_t exp10_part_width = fall_back_to_decimal_only_mode ? 0U : (PRINTF_ABS(floored_exp10) < 100) ? 4U : 5U; - - printf_size_t decimal_part_width = - ((flags & FLAGS_LEFT) && exp10_part_width) ? - // We're padding on the right, so the width constraint is the exponent part's - // problem, not the decimal part's, so we'll use as many characters as we need: - 0U : - // We're padding on the left; so the width constraint is the decimal part's - // problem. Well, can both the decimal part and the exponent part fit within our overall width? - ((width > exp10_part_width) ? - // Yes, so we limit our decimal part's width. - // (Note this is trivially valid even if we've fallen back to "%f" mode) - width - exp10_part_width : - // No; we just give up on any restriction on the decimal part and use as many - // characters as we need - 0U); - - const printf_size_t printed_exponential_start_pos = output->pos; - print_broken_up_decimal(decimal_part_components, output, precision, decimal_part_width, flags, buf, len); - - if (! fall_back_to_decimal_only_mode) { - putchar_via_gadget(output, (flags & FLAGS_UPPERCASE) ? 'E' : 'e'); - print_integer(output, - ABS_FOR_PRINTING(floored_exp10), - floored_exp10 < 0, 10, 0, exp10_part_width - 1, - FLAGS_ZEROPAD | FLAGS_PLUS); - if (flags & FLAGS_LEFT) { - // We need to right-pad with spaces to meet the width requirement - while (output->pos - printed_exponential_start_pos < width) { - putchar_via_gadget(output, ' '); - } - } - } -} -#endif // RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - -static void print_floating_point(output_gadget_t* output, double value, printf_size_t precision, printf_size_t width, printf_flags_t flags, bool prefer_exponential) -{ - char buf[RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE]; - printf_size_t len = 0U; - - // test for special values - if (value != value) { - out_rev_(output, "nan", 3, width, flags); - return; - } - if (value < -DBL_MAX) { - out_rev_(output, "fni-", 4, width, flags); - return; - } - if (value > DBL_MAX) { - out_rev_(output, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags); - return; - } - - if (!prefer_exponential && - ((value > PRINTF_FLOAT_NOTATION_THRESHOLD) || (value < -PRINTF_FLOAT_NOTATION_THRESHOLD))) { - // The required behavior of standard printf is to print _every_ integral-part digit -- which could mean - // printing hundreds of characters, overflowing any fixed internal buffer and necessitating a more complicated - // implementation. -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - print_exponential_number(output, value, precision, width, flags, buf, len); -#endif - return; - } - - // set default precision, if not set explicitly - if (!(flags & FLAGS_PRECISION)) { - precision = RT_KLIBC_USING_VSNPRINTF_FLOAT_PRECISION; - } - - // limit precision so that our integer holding the fractional part does not overflow - while ((len < RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE) && (precision > PRINTF_MAX_SUPPORTED_PRECISION)) { - buf[len++] = '0'; // This respects the precision in terms of result length only - precision--; - } - -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - if (prefer_exponential) - print_exponential_number(output, value, precision, width, flags, buf, len); - else -#endif - print_decimal_number(output, value, precision, width, flags, buf, len); -} - -#endif // (RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS || RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS) - -// Advances the format pointer past the flags, and returns the parsed flags -// due to the characters passed -static printf_flags_t parse_flags(const char** format) -{ - printf_flags_t flags = 0U; - do { - switch (**format) { - case '0': flags |= FLAGS_ZEROPAD; (*format)++; break; - case '-': flags |= FLAGS_LEFT; (*format)++; break; - case '+': flags |= FLAGS_PLUS; (*format)++; break; - case ' ': flags |= FLAGS_SPACE; (*format)++; break; - case '#': flags |= FLAGS_HASH; (*format)++; break; - default : return flags; - } - } while (true); -} - -static inline void format_string_loop(output_gadget_t* output, const char* format, va_list args) -{ -#ifdef RT_KLIBC_USING_VSNPRINTF_CHECK_NUL_IN_FORMAT_SPECIFIER -#define ADVANCE_IN_FORMAT_STRING(cptr_) do { (cptr_)++; if (!*(cptr_)) return; } while(0) -#else -#define ADVANCE_IN_FORMAT_STRING(cptr_) (cptr_)++ -#endif - - - while (*format) - { - if (*format != '%') { - // A regular content character - putchar_via_gadget(output, *format); - format++; - continue; - } - // We're parsing a format specifier: %[flags][width][.precision][length] - ADVANCE_IN_FORMAT_STRING(format); - - printf_flags_t flags = parse_flags(&format); - - // evaluate width field - printf_size_t width = 0U; - if (is_digit_(*format)) { - width = (printf_size_t) atou_(&format); - } - else if (*format == '*') { - const int w = va_arg(args, int); - if (w < 0) { - flags |= FLAGS_LEFT; // reverse padding - width = (printf_size_t)-w; - } - else { - width = (printf_size_t)w; - } - ADVANCE_IN_FORMAT_STRING(format); - } - - // evaluate precision field - printf_size_t precision = 0U; - if (*format == '.') { - flags |= FLAGS_PRECISION; - ADVANCE_IN_FORMAT_STRING(format); - if (is_digit_(*format)) { - precision = (printf_size_t) atou_(&format); - } - else if (*format == '*') { - const int precision_ = va_arg(args, int); - precision = precision_ > 0 ? (printf_size_t) precision_ : 0U; - ADVANCE_IN_FORMAT_STRING(format); - } - } - - // evaluate length field - switch (*format) { -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - case 'I' : { - ADVANCE_IN_FORMAT_STRING(format); - // Greedily parse for size in bits: 8, 16, 32 or 64 - switch(*format) { - case '8': flags |= FLAGS_INT8; - ADVANCE_IN_FORMAT_STRING(format); - break; - case '1': - ADVANCE_IN_FORMAT_STRING(format); - if (*format == '6') { format++; flags |= FLAGS_INT16; } - break; - case '3': - ADVANCE_IN_FORMAT_STRING(format); - if (*format == '2') { ADVANCE_IN_FORMAT_STRING(format); flags |= FLAGS_INT32; } - break; - case '6': - ADVANCE_IN_FORMAT_STRING(format); - if (*format == '4') { ADVANCE_IN_FORMAT_STRING(format); flags |= FLAGS_INT64; } - break; - default: break; - } - break; - } -#endif - case 'l' : - flags |= FLAGS_LONG; - ADVANCE_IN_FORMAT_STRING(format); - if (*format == 'l') { - flags |= FLAGS_LONG_LONG; - ADVANCE_IN_FORMAT_STRING(format); - } - break; - case 'h' : - flags |= FLAGS_SHORT; - ADVANCE_IN_FORMAT_STRING(format); - if (*format == 'h') { - flags |= FLAGS_CHAR; - ADVANCE_IN_FORMAT_STRING(format); - } - break; - case 't' : - flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - ADVANCE_IN_FORMAT_STRING(format); - break; - case 'j' : - flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - ADVANCE_IN_FORMAT_STRING(format); - break; - case 'z' : - flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG); - ADVANCE_IN_FORMAT_STRING(format); - break; - default: - break; - } - - // evaluate specifier - switch (*format) { - case 'd' : - case 'i' : - case 'u' : - case 'x' : - case 'X' : - case 'o' : - case 'b' : { - - if (*format == 'd' || *format == 'i') { - flags |= FLAGS_SIGNED; - } - - numeric_base_t base; - if (*format == 'x' || *format == 'X') { - base = BASE_HEX; - } - else if (*format == 'o') { - base = BASE_OCTAL; - } - else if (*format == 'b') { - base = BASE_BINARY; - } - else { - base = BASE_DECIMAL; - flags &= ~FLAGS_HASH; // decimal integers have no alternative presentation - } - - if (*format == 'X') { - flags |= FLAGS_UPPERCASE; - } - - format++; - // ignore '0' flag when precision is given - if (flags & FLAGS_PRECISION) { - flags &= ~FLAGS_ZEROPAD; - } - - if (flags & FLAGS_SIGNED) { - // A signed specifier: d, i or possibly I + bit size if enabled - - if (flags & FLAGS_LONG_LONG) { -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - const long long value = va_arg(args, long long); - print_integer(output, ABS_FOR_PRINTING(value), value < 0, base, precision, width, flags); -#endif - } - else if (flags & FLAGS_LONG) { - const long value = va_arg(args, long); - print_integer(output, ABS_FOR_PRINTING(value), value < 0, base, precision, width, flags); - } - else { - // We never try to interpret the argument as something potentially-smaller than int, - // due to integer promotion rules: Even if the user passed a short int, short unsigned - // etc. - these will come in after promotion, as int's (or unsigned for the case of - // short unsigned when it has the same size as int) - const int value = - (flags & FLAGS_CHAR) ? (signed char) va_arg(args, int) : - (flags & FLAGS_SHORT) ? (short int) va_arg(args, int) : - va_arg(args, int); - print_integer(output, ABS_FOR_PRINTING(value), value < 0, base, precision, width, flags); - } - } - else { - // An unsigned specifier: u, x, X, o, b - - flags &= ~(FLAGS_PLUS | FLAGS_SPACE); - - if (flags & FLAGS_LONG_LONG) { -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - print_integer(output, (printf_unsigned_value_t) va_arg(args, unsigned long long), false, base, precision, width, flags); -#endif - } - else if (flags & FLAGS_LONG) { - print_integer(output, (printf_unsigned_value_t) va_arg(args, unsigned long), false, base, precision, width, flags); - } - else { - const unsigned int value = - (flags & FLAGS_CHAR) ? (unsigned char)va_arg(args, unsigned int) : - (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(args, unsigned int) : - va_arg(args, unsigned int); - print_integer(output, (printf_unsigned_value_t) value, false, base, precision, width, flags); - } - } - break; - } -#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS - case 'f' : - case 'F' : - if (*format == 'F') flags |= FLAGS_UPPERCASE; - print_floating_point(output, va_arg(args, double), precision, width, flags, PRINTF_PREFER_DECIMAL); - format++; - break; -#endif -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - case 'e': - case 'E': - case 'g': - case 'G': - if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP; - if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE; - print_floating_point(output, va_arg(args, double), precision, width, flags, PRINTF_PREFER_EXPONENTIAL); - format++; - break; -#endif // RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - case 'c' : { - printf_size_t l = 1U; - // pre padding - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - putchar_via_gadget(output, ' '); - } - } - // char output - putchar_via_gadget(output, (char) va_arg(args, int) ); - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - putchar_via_gadget(output, ' '); - } - } - format++; - break; - } - - case 's' : { - const char* p = va_arg(args, char*); - if (p == NULL) { - out_rev_(output, ")llun(", 6, width, flags); - } - else { - printf_size_t l = strnlen_s_(p, precision ? precision : PRINTF_MAX_POSSIBLE_BUFFER_SIZE); - // pre padding - if (flags & FLAGS_PRECISION) { - l = (l < precision ? l : precision); - } - if (!(flags & FLAGS_LEFT)) { - while (l++ < width) { - putchar_via_gadget(output, ' '); - } - } - // string output - while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision)) { - putchar_via_gadget(output, *(p++)); - --precision; - } - // post padding - if (flags & FLAGS_LEFT) { - while (l++ < width) { - putchar_via_gadget(output, ' '); - } - } - } - format++; - break; - } - - case 'p' : { - width = sizeof(void*) * 2U + 2; // 2 hex chars per byte + the "0x" prefix - flags |= FLAGS_ZEROPAD | FLAGS_POINTER; - uintptr_t value = (uintptr_t)va_arg(args, void*); - (value == (uintptr_t) NULL) ? - out_rev_(output, ")lin(", 5, width, flags) : - print_integer(output, (printf_unsigned_value_t) value, false, BASE_HEX, precision, width, flags); - format++; - break; - } - - case '%' : - putchar_via_gadget(output, '%'); - format++; - break; - - // Many people prefer to disable support for %n, as it lets the caller - // engineer a write to an arbitrary location, of a value the caller - // effectively controls - which could be a security concern in some cases. -#ifdef RT_KLIBC_USING_VSNPRINTF_WRITEBACK_SPECIFIER - case 'n' : { - if (flags & FLAGS_CHAR) *(va_arg(args, char*)) = (char) output->pos; - else if (flags & FLAGS_SHORT) *(va_arg(args, short*)) = (short) output->pos; - else if (flags & FLAGS_LONG) *(va_arg(args, long*)) = (long) output->pos; -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - else if (flags & FLAGS_LONG_LONG) *(va_arg(args, long long*)) = (long long int) output->pos; -#endif // RT_KLIBC_USING_VSNPRINTF_LONGLONG - else *(va_arg(args, int*)) = (int) output->pos; - format++; - break; - } -#endif // RT_KLIBC_USING_VSNPRINTF_WRITEBACK_SPECIFIER - - default : - putchar_via_gadget(output, *format); - format++; - break; - } - } -} - -// internal vsnprintf - used for implementing _all library functions -static int vsnprintf_impl(output_gadget_t* output, const char* format, va_list args) -{ - // Note: The library only calls vsnprintf_impl() with output->pos being 0. However, it is - // possible to call this function with a non-zero pos value for some "remedial printing". - format_string_loop(output, format, args); - - // termination - append_termination_with_gadget(output); - - // return written chars without terminating \0 - return (int)output->pos; -} - -/////////////////////////////////////////////////////////////////////////////// - -/** - * @brief This function will fill a formatted string to buffer. - * - * @param buf is the buffer to save formatted string. - * - * @param size is the size of buffer. - * - * @param fmt is the format parameters. - * - * @param args is a list of variable parameters. - * - * @return The number of characters actually written to buffer. - */ -int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args) -{ - output_gadget_t gadget = buffer_gadget(buf, size); - return vsnprintf_impl(&gadget, fmt, args); -} diff --git a/rt-thread/src/klibc/rt_vsnprintf_tiny.c b/rt-thread/src/klibc/rt_vsnprintf_tiny.c deleted file mode 100644 index 7ef610c..0000000 --- a/rt-thread/src/klibc/rt_vsnprintf_tiny.c +++ /dev/null @@ -1,611 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-11-19 Meco Man the first version - */ - -#include - -#define _ISDIGIT(c) ((unsigned)((c) - '0') < 10) - -/** - * @brief This function will duplicate a string. - * - * @param n is the string to be duplicated. - * - * @param base is support divide instructions value. - * - * @return the duplicated string pointer. - */ -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG -rt_inline int divide(unsigned long long *n, int base) -#else -rt_inline int divide(unsigned long *n, int base) -#endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */ -{ - int res; - - /* optimized for processor which does not support divide instructions. */ -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - res = (int)((*n) % base); - *n = (long long)((*n) / base); -#else - res = (int)((*n) % base); - *n = (long)((*n) / base); -#endif - - return res; -} - -rt_inline int skip_atoi(const char **s) -{ - int i = 0; - while (_ISDIGIT(**s)) - i = i * 10 + *((*s)++) - '0'; - - return i; -} - -#define ZEROPAD (1 << 0) /* pad with zero */ -#define SIGN (1 << 1) /* unsigned/signed long */ -#define PLUS (1 << 2) /* show plus */ -#define SPACE (1 << 3) /* space if plus */ -#define LEFT (1 << 4) /* left justified */ -#define SPECIAL (1 << 5) /* 0x */ -#define LARGE (1 << 6) /* use 'ABCDEF' instead of 'abcdef' */ - -static char *print_number(char *buf, - char *end, -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - unsigned long long num, -#else - unsigned long num, -#endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */ - int base, - int qualifier, - int s, - int precision, - int type) -{ - char c = 0, sign = 0; -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - char tmp[64] = {0}; -#else - char tmp[32] = {0}; -#endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */ - int precision_bak = precision; - const char *digits = RT_NULL; - static const char small_digits[] = "0123456789abcdef"; - static const char large_digits[] = "0123456789ABCDEF"; - int i = 0; - int size = 0; - - size = s; - - digits = (type & LARGE) ? large_digits : small_digits; - if (type & LEFT) - { - type &= ~ZEROPAD; - } - - c = (type & ZEROPAD) ? '0' : ' '; - - /* get sign */ - sign = 0; - if (type & SIGN) - { - switch (qualifier) - { - case 'h': - if ((rt_int16_t)num < 0) - { - sign = '-'; - num = (rt_uint16_t)-num; - } - break; - case 'L': - case 'l': - if ((long)num < 0) - { - sign = '-'; - num = (unsigned long)-num; - } - break; - case 0: - default: - if ((rt_int32_t)num < 0) - { - sign = '-'; - num = (rt_uint32_t)-num; - } - break; - } - - if (sign != '-') - { - if (type & PLUS) - { - sign = '+'; - } - else if (type & SPACE) - { - sign = ' '; - } - } - } - - if (type & SPECIAL) - { - if (base == 2 || base == 16) - { - size -= 2; - } - else if (base == 8) - { - size--; - } - } - - i = 0; - if (num == 0) - { - tmp[i++] = '0'; - } - else - { - while (num != 0) - tmp[i++] = digits[divide(&num, base)]; - } - - if (i > precision) - { - precision = i; - } - size -= precision; - - if (!(type & (ZEROPAD | LEFT))) - { - if ((sign) && (size > 0)) - { - size--; - } - - while (size-- > 0) - { - if (buf < end) - { - *buf = ' '; - } - - ++ buf; - } - } - - if (sign) - { - if (buf < end) - { - *buf = sign; - } - -- size; - ++ buf; - } - - if (type & SPECIAL) - { - if (base == 2) - { - if (buf < end) - *buf = '0'; - ++ buf; - if (buf < end) - *buf = 'b'; - ++ buf; - } - else if (base == 8) - { - if (buf < end) - *buf = '0'; - ++ buf; - } - else if (base == 16) - { - if (buf < end) - { - *buf = '0'; - } - - ++ buf; - if (buf < end) - { - *buf = type & LARGE ? 'X' : 'x'; - } - ++ buf; - } - } - - /* no align to the left */ - if (!(type & LEFT)) - { - while (size-- > 0) - { - if (buf < end) - { - *buf = c; - } - - ++ buf; - } - } - - while (i < precision--) - { - if (buf < end) - { - *buf = '0'; - } - - ++ buf; - } - - /* put number in the temporary buffer */ - while (i-- > 0 && (precision_bak != 0)) - { - if (buf < end) - { - *buf = tmp[i]; - } - - ++ buf; - } - - while (size-- > 0) - { - if (buf < end) - { - *buf = ' '; - } - - ++ buf; - } - - return buf; -} - -#if (defined(__GNUC__) && !defined(__ARMCC_VERSION) /* GCC */) && (__GNUC__ >= 7) -/* Disable "-Wimplicit-fallthrough" below GNUC V7 */ -#pragma GCC diagnostic push -/* ignore warning: this statement may fall through */ -#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" -#endif /* (defined(__GNUC__) && !defined(__ARMCC_VERSION)) && (__GNUC__ >= 7 */ -/** - * @brief This function will fill a formatted string to buffer. - * - * @param buf is the buffer to save formatted string. - * - * @param size is the size of buffer. - * - * @param fmt is the format parameters. - * - * @param args is a list of variable parameters. - * - * @return The number of characters actually written to buffer. - */ -int rt_vsnprintf(char *buf, rt_size_t size, const char *fmt, va_list args) -{ -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - unsigned long long num = 0; -#else - unsigned long num = 0; -#endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */ - int i = 0, len = 0; - char *str = RT_NULL, *end = RT_NULL, c = 0; - const char *s = RT_NULL; - - rt_uint8_t base = 0; /* the base of number */ - rt_uint8_t flags = 0; /* flags to print number */ - rt_uint8_t qualifier = 0; /* 'h', 'l', or 'L' for integer fields */ - rt_int32_t field_width = 0; /* width of output field */ - int precision = 0; /* min. # of digits for integers and max for a string */ - - str = buf; - end = buf + size; - - /* Make sure end is always >= buf */ - if (end < buf) - { - end = ((char *) - 1); - size = end - buf; - } - - for (; *fmt ; ++fmt) - { - if (*fmt != '%') - { - if (str < end) - { - *str = *fmt; - } - - ++ str; - continue; - } - - /* process flags */ - flags = 0; - - while (1) - { - /* skips the first '%' also */ - ++fmt; - if (*fmt == '-') flags |= LEFT; - else if (*fmt == '+') flags |= PLUS; - else if (*fmt == ' ') flags |= SPACE; - else if (*fmt == '#') flags |= SPECIAL; - else if (*fmt == '0') flags |= ZEROPAD; - else break; - } - - /* get field width */ - field_width = -1; - if (_ISDIGIT(*fmt)) - { - field_width = skip_atoi(&fmt); - } - else if (*fmt == '*') - { - ++fmt; - /* it's the next argument */ - field_width = va_arg(args, int); - if (field_width < 0) - { - field_width = -field_width; - flags |= LEFT; - } - } - - /* get the precision */ - precision = -1; - if (*fmt == '.') - { - ++fmt; - if (_ISDIGIT(*fmt)) - { - precision = skip_atoi(&fmt); - } - else if (*fmt == '*') - { - ++fmt; - /* it's the next argument */ - precision = va_arg(args, int); - } - if (precision < 0) - { - precision = 0; - } - } - - qualifier = 0; /* get the conversion qualifier */ - - if (*fmt == 'h' || *fmt == 'l' || -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - *fmt == 'L' || -#endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */ - *fmt == 'z') - { - qualifier = *fmt; - ++fmt; -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - if (qualifier == 'l' && *fmt == 'l') - { - qualifier = 'L'; - ++fmt; - } -#endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */ - if (qualifier == 'h' && *fmt == 'h') - { - qualifier = 'H'; - ++fmt; - } - } - - /* the default base */ - base = 10; - - switch (*fmt) - { - case 'c': - if (!(flags & LEFT)) - { - while (--field_width > 0) - { - if (str < end) *str = ' '; - ++ str; - } - } - - /* get character */ - c = (rt_uint8_t)va_arg(args, int); - if (str < end) - { - *str = c; - } - ++ str; - - /* put width */ - while (--field_width > 0) - { - if (str < end) *str = ' '; - ++ str; - } - continue; - - case 's': - s = va_arg(args, char *); - if (!s) - { - s = "(null)"; - } - - for (len = 0; (len != field_width) && (s[len] != '\0'); len++); - - if (precision > 0 && len > precision) - { - len = precision; - } - - if (!(flags & LEFT)) - { - while (len < field_width--) - { - if (str < end) *str = ' '; - ++ str; - } - } - - for (i = 0; i < len; ++i) - { - if (str < end) *str = *s; - ++ str; - ++ s; - } - - while (len < field_width--) - { - if (str < end) *str = ' '; - ++ str; - } - continue; - - case 'p': - if (field_width == -1) - { - field_width = sizeof(void *) << 1; - field_width += 2; /* `0x` prefix */ - flags |= SPECIAL; - flags |= ZEROPAD; - } - str = print_number(str, end, (unsigned long)va_arg(args, void *), - 16, qualifier, field_width, precision, flags); - continue; - - case '%': - if (str < end) - { - *str = '%'; - } - ++ str; - continue; - - /* integer number formats - set up the flags and "break" */ - case 'b': - base = 2; - break; - case 'o': - base = 8; - break; - - case 'X': - flags |= LARGE; - case 'x': - base = 16; - break; - - case 'd': - case 'i': - flags |= SIGN; - case 'u': - break; - - case 'e': - case 'E': - case 'G': - case 'g': - case 'f': - case 'F': - va_arg(args, double); - default: - if (str < end) - { - *str = '%'; - } - ++ str; - - if (*fmt) - { - if (str < end) - { - *str = *fmt; - } - ++ str; - } - else - { - -- fmt; - } - continue; - } - - if (qualifier == 'L') - { - num = va_arg(args, unsigned long long); - } - else if (qualifier == 'l') - { - num = va_arg(args, unsigned long); - } - else if (qualifier == 'H') - { - num = (rt_int8_t)va_arg(args, rt_int32_t); - if (flags & SIGN) - { - num = (rt_int8_t)num; - } - } - else if (qualifier == 'h') - { - num = (rt_uint16_t)va_arg(args, rt_int32_t); - if (flags & SIGN) - { - num = (rt_int16_t)num; - } - } - else if (qualifier == 'z') - { - num = va_arg(args, rt_size_t); - if (flags & SIGN) - { - num = (rt_ssize_t)num; - } - } - else - { - num = (rt_uint32_t)va_arg(args, unsigned long); - } - str = print_number(str, end, num, base, qualifier, field_width, precision, flags); - } - - if (size > 0) - { - if (str < end) - { - *str = '\0'; - } - else - { - end[-1] = '\0'; - } - } - - /* the trailing null byte doesn't count towards the total - * ++str; - */ - return str - buf; -} -#if (defined(__GNUC__) && !defined(__ARMCC_VERSION) /* GCC */) && (__GNUC__ >= 7) -#pragma GCC diagnostic pop /* ignored "-Wimplicit-fallthrough" */ -#endif /* (defined(__GNUC__) && !defined(__ARMCC_VERSION)) && (__GNUC__ >= 7 */ diff --git a/rt-thread/src/klibc/rt_vsscanf.c b/rt-thread/src/klibc/rt_vsscanf.c deleted file mode 100644 index 8369b65..0000000 --- a/rt-thread/src/klibc/rt_vsscanf.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * Copyright (c) 2006-2025, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-11-24 Meco Man port to klibc - * 2025-01-04 Meco Man using Phoenix version - */ - -/* - * Copyright 2017, 2022-2023 Phoenix Systems - * Author: Adrian Kepka, Gerard Swiderski - */ - -#include -#include /* for strtod */ -#include /* for isspace */ -#include /* for va_list */ - -#define FORMAT_NIL_STR "(nil)" -#define FORMAT_NIL_STR_LEN (sizeof(FORMAT_NIL_STR) - 1) - -#define LONG 0x01 /* l: long or double */ -#define LONGDOUBLE 0x02 /* L: long double */ -#define SHORT 0x04 /* h: short */ -#define SUPPRESS 0x08 /* *: suppress assignment */ -#define POINTER 0x10 /* p: void * (as hex) */ -#define NOSKIP 0x20 /* [ or c: do not skip blanks */ -#define LONGLONG 0x400 /* ll: long long (+ deprecated q: quad) */ -#define PTRDIFF 0x800 /* t: ptrdiff_t */ -#define SHORTSHORT 0x4000 /* hh: char */ -#define UNSIGNED 0x8000 /* %[oupxX] conversions */ - -#define SIGNOK 0x40 /* +/- is (still) legal */ -#define NDIGITS 0x80 /* no digits detected */ -#define PFXOK 0x100 /* 0x prefix is (still) legal */ -#define NZDIGITS 0x200 /* no zero digits detected */ - -#define CT_CHAR 0 /* %c conversion */ -#define CT_CCL 1 /* %[...] conversion */ -#define CT_STRING 2 /* %s conversion */ -#define CT_INT 3 /* %[dioupxX] conversion */ -#define CT_FLOAT 4 /* %[aefgAEFG] conversion */ -#define CT_NONE 5 /* No conversion (ex. %n) */ - -static const unsigned char *__sccl(char *tab, const unsigned char *fmt) -{ - int c, n, v; - - c = *fmt++; - if (c == '^') { - v = 1; - c = *fmt++; - } - else { - v = 0; - } - - rt_memset(tab, (uint8_t)v, 256); - - if (c == 0) { - return (fmt - 1); - } - - v = 1 - v; - tab[c] = v; - for (;;) { - n = *fmt++; - switch (n) { - - case 0: - return (fmt - 1); - - case '-': - n = *fmt; - if ((n == ']') || (n < c)) { - c = '-'; - tab[c] = v; - break; - } - fmt++; - - do { - tab[++c] = v; - } while (c < n); - c = n; - break; - - case ']': - return (fmt); - - default: - c = n; - tab[c] = v; - break; - } - } -} - -static int scanf_parse(char *ccltab, const char *inp, int *inr, char const *fmt0, va_list ap) -{ - const unsigned char *fmt = (const unsigned char *)fmt0; - int c, n, flags, nassigned, nconversions, nread, base; - rt_size_t width; - char *p, *p0; - char buf[32]; - - static const short basefix[17] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; - - *inr = rt_strlen(inp); - - nassigned = 0; - nconversions = 0; - nread = 0; - base = 0; - for (;;) { - int convType = CT_NONE; - c = *fmt++; - if (c == '\0') { - return (nassigned); - } - - if (isspace(c) != 0) { - while ((*inr > 0) && (isspace((int)*inp) != 0)) { - nread++; - (*inr)--; - inp++; - } - continue; - } - - if (c != '%') { - if (*inr <= 0) { - return (nconversions != 0 ? nassigned : -1); - } - - if (*inp != c) { - return nassigned; - } - - nread++; - (*inr)--; - inp++; - continue; - } - - width = 0; - flags = 0; - for (;;) { - c = *fmt++; - if (c == '\0') { - return nassigned; - } - - if (c == '%') { - if (*inr <= 0) { - return (nconversions != 0 ? nassigned : -1); - } - - if (*inp != c) { - return nassigned; - } - - nread++; - (*inr)--; - inp++; - break; - } - - switch (c) { - case '*': - flags |= SUPPRESS; - continue; - - case 'l': - if ((flags & LONG) != 0) { - flags &= ~LONG; - flags |= LONGLONG; - } - else { - flags |= LONG; - } - continue; - - case 'L': - flags |= LONGDOUBLE; - continue; - - case 'q': - case 'j': - flags |= LONGLONG; - continue; - - case 't': - flags |= PTRDIFF; - continue; - - case 'z': - if (sizeof(rt_size_t) == sizeof(uint64_t)) { - flags |= LONGLONG; - } - continue; - - case 'h': - if ((flags & SHORT) != 0) { - flags &= ~SHORT; - flags |= SHORTSHORT; - } - else { - flags |= SHORT; - } - continue; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - width = width * 10 + c - '0'; - continue; - default: - break; - } - - /* conversions */ - switch (c) { - case 'd': - convType = CT_INT; - base = 10; - break; - - case 'i': - convType = CT_INT; - base = 0; - break; - - case 'o': - convType = CT_INT; - flags |= UNSIGNED; - base = 8; - break; - - case 'u': - convType = CT_INT; - flags |= UNSIGNED; - base = 10; - break; - - case 'X': - case 'x': - flags |= PFXOK; /* enable 0x prefixing */ - convType = CT_INT; - flags |= UNSIGNED; - base = 16; - break; - - case 'A': - case 'E': - case 'F': - case 'G': - case 'a': - case 'e': - case 'f': - case 'g': - convType = CT_FLOAT; - break; - - - case 's': - convType = CT_STRING; - break; - - case '[': - fmt = __sccl(ccltab, fmt); - flags |= NOSKIP; - convType = CT_CCL; - break; - - case 'c': - flags |= NOSKIP; - convType = CT_CHAR; - break; - - case 'p': - flags |= POINTER | PFXOK | UNSIGNED; - convType = CT_INT; - base = 16; - break; - - case 'n': - nconversions++; - if ((flags & SUPPRESS) != 0) { - break; - } - if ((flags & SHORTSHORT) != 0) { - *va_arg(ap, char *) = nread; - } - else if ((flags & SHORT) != 0) { - *va_arg(ap, short *) = nread; - } - else if ((flags & LONG) != 0) { - *va_arg(ap, long *) = nread; - } - else if ((flags & LONGLONG) != 0) { - *va_arg(ap, long long *) = nread; - } - else if ((flags & PTRDIFF) != 0) { - *va_arg(ap, ptrdiff_t *) = nread; - } - else { - *va_arg(ap, int *) = nread; - } - break; - - default: - /* Character not a conversion specifier; end parsing */ - return nassigned; - } - - break; - } - - if (convType == CT_NONE) { - continue; - } - - if (*inr <= 0) { - return (nconversions != 0 ? nassigned : -1); - } - - if ((flags & NOSKIP) == 0) { - while (isspace((int)*inp) != 0) { - nread++; - if (--(*inr) > 0) { - inp++; - } - else { - return (nconversions != 0 ? nassigned : -1); - } - } - } - - /* do the conversion */ - switch (convType) { - case CT_CHAR: - if (width == 0) { - width = 1; - } - - if (*inr <= 0) { - return (nconversions != 0 ? nassigned : -1); - } - - if (width > *inr) { - width = *inr; - } - - if ((flags & SUPPRESS) == 0) { - rt_memcpy(va_arg(ap, char *), inp, width); - nassigned++; - } - - *inr -= width; - inp += width; - nread += width; - nconversions++; - break; - - case CT_CCL: - if (width == 0) { - width = (rt_size_t)~0; - } - if ((flags & SUPPRESS) != 0) { - n = 0; - while (ccltab[(unsigned char)*inp] != 0) { - n++; - (*inr)--; - inp++; - if (--width == 0) { - break; - } - if (*inr <= 0) { - if (n == 0) { - return (nconversions != 0 ? nassigned : -1); - } - break; - } - } - if (n == 0) { - return nassigned; - } - } - else { - p0 = p = va_arg(ap, char *); - while (ccltab[(unsigned char)*inp] != 0) { - (*inr)--; - *p++ = *inp++; - if (--width == 0) { - break; - } - if (*inr <= 0) { - if (p == p0) { - return (nconversions != 0 ? nassigned : -1); - } - break; - } - } - n = p - p0; - if (n == 0) { - return nassigned; - } - *p = 0; - nassigned++; - } - nread += n; - nconversions++; - break; - - case CT_STRING: - if (width == 0) { - width = (rt_size_t)~0; - } - if ((flags & SUPPRESS) != 0) { - while (isspace((int)*inp) == 0) { - nread++; - (*inr)--; - inp++; - if (--width == 0) { - break; - } - if (*inr <= 0) { - break; - } - } - } - else { - p0 = p = va_arg(ap, char *); - while (isspace((int)*inp) == 0) { - (*inr)--; - *p++ = *inp++; - if (--width == 0) { - break; - } - if (*inr <= 0) { - break; - } - } - *p = 0; - nread += p - p0; - nassigned++; - } - nconversions++; - continue; - - case CT_INT: - if (((flags & POINTER) != 0) && ((*inr) >= FORMAT_NIL_STR_LEN) && (rt_strncmp(FORMAT_NIL_STR, inp, FORMAT_NIL_STR_LEN) == 0)) { - *va_arg(ap, void **) = RT_NULL; - nassigned++; - nconversions++; - nread += FORMAT_NIL_STR_LEN; - inp += FORMAT_NIL_STR_LEN; - (*inr) -= FORMAT_NIL_STR_LEN; - break; - } - - if (--width > (sizeof(buf) - 2)) { - width = sizeof(buf) - 2; - } - width++; - - if ((flags & SUPPRESS) != 0) { - width = ~0; - } - - flags |= SIGNOK | NDIGITS | NZDIGITS; - for (p = buf; width; width--) { - int ok = 0; - c = *inp; - switch (c) { - case '0': - if (base == 0) { - base = 8; - flags |= PFXOK; - } - if ((flags & NZDIGITS) != 0) { - flags &= ~(SIGNOK | NZDIGITS | NDIGITS); - } - else { - flags &= ~(SIGNOK | PFXOK | NDIGITS); - } - ok = 1; - break; - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - base = basefix[base]; - flags &= ~(SIGNOK | PFXOK | NDIGITS); - ok = 1; - break; - - case '8': - case '9': - base = basefix[base]; - if (base <= 8) { - break; /* not legal here */ - } - flags &= ~(SIGNOK | PFXOK | NDIGITS); - ok = 1; - break; - - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - if (base <= 10) { - break; - } - flags &= ~(SIGNOK | PFXOK | NDIGITS); - ok = 1; - break; - - case '+': - case '-': - if ((flags & SIGNOK) != 0) { - flags &= ~SIGNOK; - ok = 1; - } - break; - - case 'x': - case 'X': - if (((flags & PFXOK) != 0) && (p == buf + 1)) { - base = 16; /* if %i */ - flags &= ~PFXOK; - ok = 1; - } - break; - } - if (!ok) - break; - - if ((flags & SUPPRESS) == 0) { - *p++ = c; - } - if (--(*inr) > 0) { - inp++; - } - else { - break; - } - } - if ((flags & NDIGITS) != 0) { - return (nconversions != 0 ? nassigned : -1); - } - - c = ((unsigned char *)p)[-1]; - if ((c == 'x') || (c == 'X')) { - --p; - inp--; - (*inr)++; - } - - if ((flags & SUPPRESS) == 0) { - uint64_t res; - - *p = 0; - if ((flags & UNSIGNED) == 0) { - res = strtoll(buf, (char **)RT_NULL, base); - } - else { - res = strtoull(buf, (char **)RT_NULL, base); - } - if ((flags & POINTER) != 0) { - *va_arg(ap, void **) = (void *)(unsigned long)res; - } - else if ((flags & SHORTSHORT) != 0) { - *va_arg(ap, char *) = res; - } - else if ((flags & SHORT) != 0) { - *va_arg(ap, short *) = res; - } - else if ((flags & LONG) != 0) { - *va_arg(ap, long *) = res; - } - else if ((flags & LONGLONG) != 0) { - *va_arg(ap, long long *) = res; - } - else if ((flags & PTRDIFF) != 0) { - *va_arg(ap, ptrdiff_t *) = res; - } - else { - *va_arg(ap, int *) = res; - } - nassigned++; - } - - nread += p - buf; - nconversions++; - break; - - case CT_FLOAT: { - union { - float f; - double d; - long double ld; - } res; - - const char *srcbuf = inp; - if ((width != 0) && (width < *inr)) { - /* TODO: handle larger widths */ - if (width > (sizeof(buf) - 1)) { - return (nconversions != 0 ? nassigned : -1); - } - - rt_memcpy(buf, inp, width); - buf[width] = '\0'; - srcbuf = buf; - } - - int is_zero; - if ((flags & LONGDOUBLE) != 0) { - res.ld = strtold(srcbuf, &p); - is_zero = res.ld == 0; - } - else if ((flags & LONG) != 0) { - res.d = strtod(srcbuf, &p); - is_zero = res.d == 0; - } - else { - res.f = strtof(srcbuf, &p); - is_zero = res.f == 0; - } - - if (is_zero && (srcbuf == p)) { - return (nconversions != 0 ? nassigned : -1); - } - - int consumed = p - srcbuf; - *inr -= consumed; - inp += consumed; - nread += consumed; - nconversions++; - if ((flags & SUPPRESS) == 0) { - if ((flags & LONGDOUBLE) != 0) { - *va_arg(ap, long double *) = res.ld; - } - else if ((flags & LONG) != 0) { - *va_arg(ap, double *) = res.d; - } - else { - *va_arg(ap, float *) = res.f; - } - - nassigned++; - } - - break; - } - - default: - break; - } - } - /* never reached */ -} - -int rt_vsscanf(const char *str, const char *format, va_list ap) -{ - int ret, nremain; - char *ccltab = rt_malloc(256); - - if (ccltab == RT_NULL) { - return -1; - } - - ret = scanf_parse(ccltab, str, &nremain, format, ap); - rt_free(ccltab); - - return ret; -} diff --git a/rt-thread/src/klibc/utest/SConscript b/rt-thread/src/klibc/utest/SConscript deleted file mode 100644 index a9acd1b..0000000 --- a/rt-thread/src/klibc/utest/SConscript +++ /dev/null @@ -1,10 +0,0 @@ -from building import * - -src = [] - -if GetDepend('RT_UTEST_USING_ALL_CASES') or GetDepend('RT_UTEST_TC_USING_KLIBC'): - src += Glob('TC_*.c') - -group = DefineGroup('utestcases', src, depend = ['']) - -Return('group') diff --git a/rt-thread/src/klibc/utest/TC_rt_memcmp.c b/rt-thread/src/klibc/utest/TC_rt_memcmp.c deleted file mode 100644 index e8baf55..0000000 --- a/rt-thread/src/klibc/utest/TC_rt_memcmp.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020-05-06 Phillip Johnston the first version - * 2024-12-24 Meco Man port to utest - */ - -#include -#include - -static void TC_rt_memcmp_str(void) -{ - const char* s = "abc 123"; - - uassert_int_equal(rt_memcmp("abc", "abc", 4), 0); - uassert_int_equal(rt_memcmp(s, "abc", 3), 0); - uassert_int_equal(rt_memcmp("abc", s, 3), 0); - - /* The following tests intentionally use a length > 3 */ - /* To test what rt_memcmp does in such a situation */ - uassert_value_greater(rt_memcmp(s, "abc", 6), 0); - uassert_value_less(rt_memcmp("abc", s, 6), 0); -} - -static void TC_rt_memcmp_int_array(void) -{ - int arr1[] = {1, 2, 3, 4, 5}; - int arr2[] = {1, 2, 3, 4, 5}; - int arr3[] = {1, 2, 3, 4, 6}; - - uassert_int_equal(rt_memcmp(arr1, arr2, sizeof(arr1)), 0); - uassert_value_less(rt_memcmp(arr1, arr3, sizeof(arr1)), 0); - uassert_value_greater(rt_memcmp(arr3, arr1, sizeof(arr1)), 0); -} - -static void TC_rt_memcmp_float_array(void) -{ - float arr1[] = {1.0f, 2.0f, 3.0f}; - float arr2[] = {1.0f, 2.0f, 3.0f}; - float arr3[] = {1.0f, 2.0f, 3.1f}; - - uassert_int_equal(rt_memcmp(arr1, arr2, sizeof(arr1)), 0); - uassert_value_less(rt_memcmp(arr1, arr3, sizeof(arr1)), 0); - uassert_value_greater(rt_memcmp(arr3, arr1, sizeof(arr1)), 0); -} - -typedef struct { - int id; - float value; -} Item; - -static void TC_rt_memcmp_struct_array(void) -{ - Item arr1[] = {{1, 1.0f}, {2, 2.0f}}; - Item arr2[] = {{1, 1.0f}, {2, 2.0f}}; - Item arr3[] = {{1, 1.0f}, {2, 2.1f}}; - - uassert_int_equal(rt_memcmp(arr1, arr2, sizeof(arr1)), 0); - uassert_value_less(rt_memcmp(arr1, arr3, sizeof(arr1)), 0); - uassert_value_greater(rt_memcmp(arr3, arr1, sizeof(arr1)), 0); -} - -typedef struct { - int id; - float value; - char name[10]; -} MixedItem; - -static void TC_rt_memcmp_mixed_array(void) -{ - MixedItem arr1[] = {{1, 1.0f, "item1"}, {2, 2.0f, "item2"}}; - MixedItem arr2[] = {{1, 1.0f, "item1"}, {2, 2.0f, "item2"}}; - MixedItem arr3[] = {{1, 1.0f, "item1"}, {2, 2.1f, "item2"}}; - - uassert_int_equal(rt_memcmp(arr1, arr2, sizeof(arr1)), 0); - uassert_value_less(rt_memcmp(arr1, arr3, sizeof(arr1)), 0); - uassert_value_greater(rt_memcmp(arr3, arr1, sizeof(arr1)), 0); -} - -typedef struct { - int id; - float score; -} Student; - -typedef struct { - Student students[3]; - char className[10]; -} Class; - -static void TC_rt_memcmp_nested_struct_array(void) -{ - Class class1 = { - .students = {{1, 90.5}, {2, 85.0}, {3, 92.0}}, - .className = "ClassA" - }; - - Class class2 = { - .students = {{1, 90.5}, {2, 85.0}, {3, 92.0}}, - .className = "ClassA" - }; - - Class class3 = { - .students = {{1, 90.5}, {2, 85.1}, {3, 92.0}}, - .className = "ClassA" - }; - - uassert_int_equal(rt_memcmp(&class1, &class2, sizeof(Class)), 0); - uassert_int_not_equal(rt_memcmp(&class1, &class3, sizeof(Class)), 0); -} - -static void TC_rt_memcmp_partial_match(void) -{ - char arr1[] = "abcdefghijklmnopqrstuvwxyz"; - char arr2[] = "abcdefghijklmxyznopqrstuvw"; - - uassert_int_equal(rt_memcmp(arr1, arr2, 13), 0); - uassert_int_not_equal(rt_memcmp(arr1, arr2, sizeof(arr1)), 0); -} - -#define LARGE_ARRAY_SIZE 1000 - -static void TC_rt_memcmp_large_array(void) -{ - int *arr1 = rt_calloc(LARGE_ARRAY_SIZE, sizeof(int)); - int *arr2 = rt_calloc(LARGE_ARRAY_SIZE, sizeof(int)); - - uassert_not_null(arr1); - uassert_not_null(arr2); - - for (int i = 0; i < LARGE_ARRAY_SIZE; i++) { - arr1[i] = i; - arr2[i] = i; - } - - uassert_int_equal(rt_memcmp(arr1, arr2, LARGE_ARRAY_SIZE * sizeof(int)), 0); - arr2[LARGE_ARRAY_SIZE - 1] = LARGE_ARRAY_SIZE; - - uassert_value_less(rt_memcmp(arr1, arr2, LARGE_ARRAY_SIZE * sizeof(int)), 0); - uassert_value_greater(rt_memcmp(arr2, arr1, LARGE_ARRAY_SIZE * sizeof(int)), 0); - - rt_free(arr1); - rt_free(arr2); -} - -static void utest_do_tc(void) -{ - UTEST_UNIT_RUN(TC_rt_memcmp_str); - UTEST_UNIT_RUN(TC_rt_memcmp_int_array); - UTEST_UNIT_RUN(TC_rt_memcmp_float_array); - UTEST_UNIT_RUN(TC_rt_memcmp_struct_array); - UTEST_UNIT_RUN(TC_rt_memcmp_mixed_array); - UTEST_UNIT_RUN(TC_rt_memcmp_nested_struct_array); - UTEST_UNIT_RUN(TC_rt_memcmp_partial_match); - UTEST_UNIT_RUN(TC_rt_memcmp_large_array); -} - -UTEST_TC_EXPORT(utest_do_tc, "klibc.rt_memcmp", RT_NULL, RT_NULL, 1000); diff --git a/rt-thread/src/klibc/utest/TC_rt_memcpy.c b/rt-thread/src/klibc/utest/TC_rt_memcpy.c deleted file mode 100644 index c02ccd5..0000000 --- a/rt-thread/src/klibc/utest/TC_rt_memcpy.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020-05-06 Phillip Johnston the first version - * 2024-12-24 Meco Man port to utest - */ - -#include -#include - -#define N 80 /**< Define the constant N for buffer size as 80 */ -#define TEST_BUF_SIZE 512 /**< Define the constant TEST_BUF_SIZE as 512 */ -static char *buf; /**< Define a static buffer of 512 bytes, initialized to 0 */ - -static rt_err_t utest_tc_init(void) -{ - buf = rt_malloc(TEST_BUF_SIZE * sizeof(char)); /**< Allocate memory for the buffer */ - uassert_not_null(buf); - return RT_EOK; -} - -static rt_err_t utest_tc_cleanup(void) -{ - rt_free(buf); - return RT_EOK; -} - -/** - * Test memory copy with alignment. - * @param dalign The alignment offset for the destination buffer. - * @param salign The alignment offset for the source buffer. - * @param len The length of data to copy. - */ -static void test_align(unsigned dalign, unsigned salign, size_t len) -{ - char *src = (char *)RT_ALIGN((rt_ubase_t)buf, 64); /**< Source buffer starting address, 64-byte aligned */ - char *dst = (char *)RT_ALIGN(((rt_ubase_t)buf + 128), 64); /**< Destination buffer starting address, 64-byte aligned from buf+128 */ - char *want = (char *)RT_ALIGN(((rt_ubase_t)buf + 256), 64); /**< Expected result buffer starting address, 64-byte aligned from buf+256 */ - char *p; /**< Pointer to receive the return value of rt_memcpy */ - unsigned i; - - /** Assert that the source alignment offset plus length does not exceed N */ - uassert_false(salign + len > N); - /** Assert that the destination alignment offset plus length does not exceed N */ - uassert_false(dalign + len > N); - - /** Initialize all buffers with '#' or ' ' */ - for(i = 0; i < N; i++) - { - src[i] = '#'; - dst[i] = want[i] = ' '; - } - - /** Set data in the specified alignment offsets of the source and expected result buffers */ - for(i = 0; i < len; i++) - { - src[salign + i] = want[dalign + i] = (char)('0' + i); - } - - /** Call rt_memcpy to copy data */ - p = rt_memcpy(dst + dalign, src + salign, len); - - /** Assert that the return value of rt_memcpy is the pointer to the start of the copied data in the destination buffer */ - uassert_ptr_equal(p, dst + dalign); - - /** Assert that the content of the destination buffer matches the expected result buffer */ - for(i = 0; i < N; i++) - { - uassert_int_equal(dst[i], want[i]); - } -} - -/** - * Test case to iterate over all possible alignment offsets and length combinations. - */ -static void TC_rt_memcpy_align(void) -{ - for(unsigned i = 0; i < 16; i++) /**< Iterate over source alignment offsets from 0 to 15 */ - { - for(unsigned j = 0; j < 16; j++) /**< Iterate over destination alignment offsets from 0 to 15 */ - { - for(size_t k = 0; k < 64; k++) /**< Iterate over data lengths from 0 to 63 */ - { - test_align(i, j, k); /**< Call the test_align function */ - } - } - } -} - -static void TC_rt_memcpy_str(void) -{ - const char src[] = "Hello, memcpy!"; - char dest[20] = {0}; - rt_memcpy(dest, src, sizeof(src)); - uassert_true(rt_strcmp(src, dest) == 0); -} - -static void utest_do_tc(void) -{ - UTEST_UNIT_RUN(TC_rt_memcpy_str); - UTEST_UNIT_RUN(TC_rt_memcpy_align); -} - -UTEST_TC_EXPORT(utest_do_tc, "klibc.rt_memcpy", utest_tc_init, utest_tc_cleanup, 1000); diff --git a/rt-thread/src/klibc/utest/TC_rt_memmove.c b/rt-thread/src/klibc/utest/TC_rt_memmove.c deleted file mode 100644 index 22f8021..0000000 --- a/rt-thread/src/klibc/utest/TC_rt_memmove.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-12-25 Meco Man first version - */ - -#include -#include - -/* Basic move with no overlap */ -static void TC_rt_memmove_basic(void) -{ - char src[] = "Hello"; - char dest[10] = {0}; - rt_memmove(dest, src, rt_strlen(src) + 1); - uassert_str_equal(dest, "Hello"); -} - -/* Move with overlap (src before dest) */ -static void TC_rt_memmove_overlap_src_before(void) -{ - char buffer[] = "1234567890"; - rt_memmove(&buffer[3], buffer, 5); - uassert_str_equal(buffer, "1231234590"); -} - -/* Move with overlap (src after dest) */ -static void TC_rt_memmove_overlap_src_after(void) -{ - char buffer[] = "1234567890"; - rt_memmove(&buffer[2], &buffer[5], 5); - uassert_str_equal(buffer, "1267890890"); -} - -/* Move with zero length */ -static void TC_rt_memmove_zero_length(void) -{ - char src[] = "Hello"; - char dest[10] = "World"; - rt_memmove(dest, src, 0); - uassert_str_equal(dest, "World"); -} - -/* Move to the same location */ -static void TC_rt_memmove_same_location(void) -{ - char buffer[] = "Hello"; - rt_memmove(buffer, buffer, rt_strlen(buffer) + 1); - uassert_str_equal(buffer, "Hello"); -} - -/* Move from NULL */ -static void TC_rt_memmove_null_src(void) -{ - char dest[10]; - rt_memset(dest, 'A', sizeof(dest)); - rt_memmove(dest, RT_NULL, 0); /* Should not crash and do nothing */ - uassert_buf_equal(dest, "AAAAAAAAAA", 10); -} - -/* Move to NULL */ -static void TC_rt_memmove_null_dest(void) -{ - char src[] = "Hello"; - rt_memmove(RT_NULL, src, 0); /* Should not crash and do nothing */ -} - -/* Move more than source size */ -static void TC_rt_memmove_too_long(void) -{ - char src[] = "Short"; - char dest[10] = {0}; - rt_memmove(dest, src, sizeof(src) + 5); /* Should only copy up to src length */ - uassert_str_equal(dest, "Short"); - uassert_int_equal(dest[5], 0); /* Ensure no buffer overflow */ -} - -/* Move empty string */ -static void TC_rt_memmove_empty_string(void) -{ - char src[] = ""; - char dest[10] = "Unchanged"; - rt_memmove(dest, src, rt_strlen(src) + 1); - - /* Expect dest to only contain '\0' at the start */ - uassert_str_equal(dest, ""); /* Destination should now be an empty string */ - uassert_int_equal(dest[0], '\0'); /* First character should be '\0' */ -} - -/* Utest function to run all test cases */ -static void utest_do_tc(void) -{ - UTEST_UNIT_RUN(TC_rt_memmove_basic); - UTEST_UNIT_RUN(TC_rt_memmove_overlap_src_before); - UTEST_UNIT_RUN(TC_rt_memmove_overlap_src_after); - UTEST_UNIT_RUN(TC_rt_memmove_zero_length); - UTEST_UNIT_RUN(TC_rt_memmove_same_location); - UTEST_UNIT_RUN(TC_rt_memmove_null_src); - UTEST_UNIT_RUN(TC_rt_memmove_null_dest); - UTEST_UNIT_RUN(TC_rt_memmove_too_long); - UTEST_UNIT_RUN(TC_rt_memmove_empty_string); -} - -UTEST_TC_EXPORT(utest_do_tc, "klibc.rt_memmove", RT_NULL, RT_NULL, 1000); diff --git a/rt-thread/src/klibc/utest/TC_rt_memset.c b/rt-thread/src/klibc/utest/TC_rt_memset.c deleted file mode 100644 index afe705d..0000000 --- a/rt-thread/src/klibc/utest/TC_rt_memset.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020-05-06 Phillip Johnston the first version - * 2024-12-24 Meco Man port to utest - */ - -#include -#include - -#define TEST_BUF_SIZE 400 - -static char *buf; -static char *buf2; - -static rt_err_t utest_tc_init(void) -{ - buf = rt_malloc(TEST_BUF_SIZE * sizeof(char)); - uassert_not_null(buf); - buf2 = rt_malloc(TEST_BUF_SIZE * sizeof(char)); - uassert_not_null(buf2); - return RT_EOK; -} - -static rt_err_t utest_tc_cleanup(void) -{ - rt_free(buf); - rt_free(buf2); - return RT_EOK; -} - -static void test_align(int align, size_t len) -{ - char *s = (char *)RT_ALIGN(((rt_ubase_t)buf + 64), 64) + align; - char *want = (char *)RT_ALIGN(((rt_ubase_t)buf2 + 64), 64) + align; - char *p; - int i; - - uassert_false(len + 64 > (size_t)(buf + TEST_BUF_SIZE - s)); - uassert_false(len + 64 > (size_t)(buf2 + TEST_BUF_SIZE - want)); - - for(i = 0; i < TEST_BUF_SIZE; i++) - { - buf[i] = buf2[i] = ' '; - } - - for(i = 0; i < (int)len; i++) - { - want[i] = '#'; - } - - p = rt_memset(s, '#', len); - - uassert_ptr_equal(p, s); - - for(i = -64; i < (int)len + 64; i++) - { - uassert_int_equal(s[i], want[i]); - } -} - -static void TC_rt_memcpy_align(void) -{ - for(int i = 0; i < 16; i++) - { - for(size_t j = 0; j < 200; j++) - { - test_align(i, j); - } - } -} - -static void test_input(char c) -{ - rt_memset(buf, c, 10); - for(int i = 0; i < 10; i++) - { - uassert_int_equal(buf[i], c); - } -} - -static void TC_rt_memcpy_input(void) -{ - test_input('c'); - test_input(0); - test_input(-1); - test_input(0xab); - test_input((char)RT_UINT32_MAX); - test_input((char)-RT_UINT32_MAX); -} - -static void utest_do_tc(void) -{ - UTEST_UNIT_RUN(TC_rt_memcpy_align); - UTEST_UNIT_RUN(TC_rt_memcpy_input); -} - -UTEST_TC_EXPORT(utest_do_tc, "klibc.rt_memset", utest_tc_init, utest_tc_cleanup, 1000); diff --git a/rt-thread/src/klibc/utest/TC_rt_sprintf.c b/rt-thread/src/klibc/utest/TC_rt_sprintf.c deleted file mode 100644 index 709155c..0000000 --- a/rt-thread/src/klibc/utest/TC_rt_sprintf.c +++ /dev/null @@ -1,1065 +0,0 @@ -/* - * Copyright (c) 2006-2024, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2024-12-22 Meco Man the first version - */ - -/** - * @author (c) Eyal Rozenberg - * 2021-2022, Haifa, Palestine/Israel - * @author (c) Marco Paland (info@paland.com) - * 2014-2019, PALANDesign Hannover, Germany - * - * @note Others have made smaller contributions to this file: see the - * contributors page at https://github.com/eyalroz/printf/graphs/contributors - * or ask one of the authors. The original code for exponential specifiers was - * contributed by Martijn Jasperse . - * - * @brief Small stand-alone implementation of the printf family of functions - * (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems with - * a very limited resources. - * - * @note the implementations are thread-safe; re-entrant; use no functions from - * the standard library; and do not dynamically allocate any memory. - * - * @license The MIT License (MIT) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/* -Unported test cases: -buffer_length -extremal_signed_integer_values -extremal_unsigned_integer_values -*/ - -#include -#include -#include - -#define base_buffer_size 100 - -#define SPRINTF_CHECK(expected, buffer, format, ...) \ -do { \ - rt_memset(buffer, 0xCC, base_buffer_size); \ - rt_sprintf(buffer, format, ##__VA_ARGS__); \ - uassert_str_equal(expected, buffer); \ -} while (0) - -#define SPRINTF_TEST_CASE_NAME(testname) TC_##testname -#define SPRINTF_TEST_CASE(testname) static void SPRINTF_TEST_CASE_NAME(testname)(void) - -SPRINTF_TEST_CASE(space_flag) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK(" 42", buffer, "% d", 42); - SPRINTF_CHECK("-42", buffer, "% d", -42); - SPRINTF_CHECK(" 42", buffer, "% 5d", 42); - SPRINTF_CHECK(" -42", buffer, "% 5d", -42); - SPRINTF_CHECK(" 42", buffer, "% 15d", 42); - SPRINTF_CHECK(" -42", buffer, "% 15d", -42); - SPRINTF_CHECK(" -42", buffer, "% 15d", -42); -#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS - SPRINTF_CHECK(" -42.987", buffer, "% 15.3f", -42.987); - SPRINTF_CHECK(" 42.987", buffer, "% 15.3f", 42.987); -#endif - SPRINTF_CHECK(" 1024", buffer, "% d", 1024); - SPRINTF_CHECK("-1024", buffer, "% d", -1024); - SPRINTF_CHECK(" 1024", buffer, "% i", 1024); - SPRINTF_CHECK("-1024", buffer, "% i", -1024); -} - -SPRINTF_TEST_CASE(space_flag__non_standard_format) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("Hello testing", buffer, "% s", "Hello testing"); - SPRINTF_CHECK("1024", buffer, "% u", 1024); -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - SPRINTF_CHECK("1024", buffer, "% I16u", (uint16_t) 1024); - SPRINTF_CHECK("1024", buffer, "% I32u", (uint32_t) 1024); - SPRINTF_CHECK("1024", buffer, "% I64u", (uint64_t) 1024); -#endif - SPRINTF_CHECK("4294966272", buffer, "% u", 4294966272U); -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - SPRINTF_CHECK("4294966272", buffer, "% I32u", (uint32_t) 4294966272U); - SPRINTF_CHECK("4294966272", buffer, "% I64u", (uint64_t) 4294966272U); -#endif - SPRINTF_CHECK("777", buffer, "% o", 511); - SPRINTF_CHECK("37777777001", buffer, "% o", 4294966785U); - SPRINTF_CHECK("1234abcd", buffer, "% x", 305441741); - SPRINTF_CHECK("edcb5433", buffer, "% x", 3989525555U); - SPRINTF_CHECK("1234ABCD", buffer, "% X", 305441741); - SPRINTF_CHECK("EDCB5433", buffer, "% X", 3989525555U); - SPRINTF_CHECK("x", buffer, "% c", 'x'); -} - -SPRINTF_TEST_CASE(plus_flag) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("+42", buffer, "%+d", 42); - SPRINTF_CHECK("-42", buffer, "%+d", -42); - SPRINTF_CHECK(" +42", buffer, "%+5d", 42); - SPRINTF_CHECK(" -42", buffer, "%+5d", -42); - SPRINTF_CHECK(" +42", buffer, "%+15d", 42); - SPRINTF_CHECK(" -42", buffer, "%+15d", -42); - SPRINTF_CHECK("+1024", buffer, "%+d", 1024); - SPRINTF_CHECK("-1024", buffer, "%+d", -1024); - SPRINTF_CHECK("+1024", buffer, "%+i", 1024); - SPRINTF_CHECK("-1024", buffer, "%+i", -1024); -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - SPRINTF_CHECK("+1024", buffer, "%+I16d", (int16_t) 1024); - SPRINTF_CHECK("-1024", buffer, "%+I16d", (int16_t) -1024); - SPRINTF_CHECK("+1024", buffer, "%+I32d", (int32_t) 1024); - SPRINTF_CHECK("-1024", buffer, "%+I32d", (int32_t) -1024); - SPRINTF_CHECK("+1024", buffer, "%+I64d", (int64_t) 1024); - SPRINTF_CHECK("-1024", buffer, "%+I64d", (int64_t) -1024); -#endif - SPRINTF_CHECK("+", buffer, "%+.0d", 0); -} - -SPRINTF_TEST_CASE(plus_flag__non_standard_format) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("Hello testing", buffer, "%+s", "Hello testing"); - SPRINTF_CHECK("1024", buffer, "%+u", 1024); -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - SPRINTF_CHECK("1024", buffer, "%+I32u", (uint32_t) 1024); -#endif - SPRINTF_CHECK("4294966272", buffer, "%+u", 4294966272U); -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - SPRINTF_CHECK("4294966272", buffer, "%+I32u", (uint32_t) 4294966272U); -#endif - SPRINTF_CHECK("777", buffer, "%+o", 511); - SPRINTF_CHECK("37777777001", buffer, "%+o", 4294966785U); - SPRINTF_CHECK("1234abcd", buffer, "%+x", 305441741); - SPRINTF_CHECK("edcb5433", buffer, "%+x", 3989525555U); - SPRINTF_CHECK("1234ABCD", buffer, "%+X", 305441741); - SPRINTF_CHECK("EDCB5433", buffer, "%+X", 3989525555U); - SPRINTF_CHECK("x", buffer, "%+c", 'x'); -} - -SPRINTF_TEST_CASE(zero_flag) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("42", buffer, "%0d", 42); - SPRINTF_CHECK("42", buffer, "%0ld", 42L); - SPRINTF_CHECK("-42", buffer, "%0d", -42); - SPRINTF_CHECK("00042", buffer, "%05d", 42); - SPRINTF_CHECK("-0042", buffer, "%05d", -42); - SPRINTF_CHECK("000000000000042", buffer, "%015d", 42); - SPRINTF_CHECK("-00000000000042", buffer, "%015d", -42); -#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS - SPRINTF_CHECK("000000000042.12", buffer, "%015.2f", 42.1234); - SPRINTF_CHECK("00000000042.988", buffer, "%015.3f", 42.9876); - SPRINTF_CHECK("-00000042.98760", buffer, "%015.5f", -42.9876); -#endif -} - -SPRINTF_TEST_CASE(minus_flag) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("42", buffer, "%-d", 42); - SPRINTF_CHECK("-42", buffer, "%-d", -42); - SPRINTF_CHECK("42 ", buffer, "%-5d", 42); - SPRINTF_CHECK("-42 ", buffer, "%-5d", -42); - SPRINTF_CHECK("42 ", buffer, "%-15d", 42); - SPRINTF_CHECK("-42 ", buffer, "%-15d", -42); -} - -SPRINTF_TEST_CASE(minus_flag_and_non_standard_zero_modifier_for_integers) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("42", buffer, "%-0d", 42); - SPRINTF_CHECK("-42", buffer, "%-0d", -42); - SPRINTF_CHECK("42 ", buffer, "%-05d", 42); - SPRINTF_CHECK("-42 ", buffer, "%-05d", -42); - SPRINTF_CHECK("42 ", buffer, "%-015d", 42); - SPRINTF_CHECK("-42 ", buffer, "%-015d", -42); - SPRINTF_CHECK("42", buffer, "%0-d", 42); - SPRINTF_CHECK("-42", buffer, "%0-d", -42); - SPRINTF_CHECK("42 ", buffer, "%0-5d", 42); - SPRINTF_CHECK("-42 ", buffer, "%0-5d", -42); - SPRINTF_CHECK("42 ", buffer, "%0-15d", 42); - SPRINTF_CHECK("-42 ", buffer, "%0-15d", -42); - -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - SPRINTF_CHECK("-4.200e+01 ", buffer, "%0-15.3e", -42.); - SPRINTF_CHECK("-42 ", buffer, "%0-15.3g", -42.); -#else - SPRINTF_CHECK("e", buffer, "%0-15.3e", -42.); - SPRINTF_CHECK("g", buffer, "%0-15.3g", -42.); -#endif /* RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS */ -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ -} - -SPRINTF_TEST_CASE(sharp_flag) -{ - char buffer[base_buffer_size]; -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("0", buffer, "%#o", 0); - SPRINTF_CHECK("0", buffer, "%#0o", 0); -#endif - SPRINTF_CHECK("0", buffer, "%#.0o", 0); -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("0", buffer, "%#.1o", 0); - SPRINTF_CHECK(" 0", buffer, "%#4o", 0); - SPRINTF_CHECK("0000", buffer, "%#.4o", 0); -#endif - SPRINTF_CHECK("01", buffer, "%#o", 1); - SPRINTF_CHECK("01", buffer, "%#0o", 1); -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("01", buffer, "%#.0o", 1); -#endif - SPRINTF_CHECK("01", buffer, "%#.1o", 1); - SPRINTF_CHECK(" 01", buffer, "%#4o", 1); -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("0001", buffer, "%#.4o", 1); -#endif - SPRINTF_CHECK("0x1001", buffer, "%#04x", 0x1001); - SPRINTF_CHECK("01001", buffer, "%#04o", 01001); -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("", buffer, "%#.0x", 0); -#endif - SPRINTF_CHECK("0x0000614e", buffer, "%#.8x", 0x614e); -} - -SPRINTF_TEST_CASE(sharp_flag__non_standard_format) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("0b110", buffer, "%#b", 6); - SPRINTF_CHECK("0b11111111", buffer, "%#010b", 0xff); - SPRINTF_CHECK("0b011111111", buffer, "%#011b", 0xff); - SPRINTF_CHECK("077", buffer, "%#03o", 077); - SPRINTF_CHECK("0077", buffer, "%#04o", 077); -} - -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG -SPRINTF_TEST_CASE(sharp_flag_with_long_long) -{ - char buffer[base_buffer_size]; -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("0", buffer, "%#llo", (long long) 0); - SPRINTF_CHECK("0", buffer, "%#0llo", (long long) 0); -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ - SPRINTF_CHECK("0", buffer, "%#.0llo", (long long) 0); -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("0", buffer, "%#.1llo", (long long) 0); - SPRINTF_CHECK(" 0", buffer, "%#4llo", (long long) 0); - SPRINTF_CHECK("0000", buffer, "%#.4llo", (long long) 0); -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ - SPRINTF_CHECK("01", buffer, "%#llo", (long long) 1); - SPRINTF_CHECK("01", buffer, "%#0llo", (long long) 1); -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("01", buffer, "%#.0llo", (long long) 1); -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ - SPRINTF_CHECK("01", buffer, "%#.1llo", (long long) 1); - SPRINTF_CHECK(" 01", buffer, "%#4llo", (long long) 1); -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("0001", buffer, "%#.4llo", (long long) 1); -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ - SPRINTF_CHECK("0x1001", buffer, "%#04llx", (long long) 0x1001); - SPRINTF_CHECK("01001", buffer, "%#04llo", (long long) 01001); -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("", buffer, "%#.0llx", (long long) 0); -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ - SPRINTF_CHECK("0x0000614e", buffer, "%#.8llx", (long long) 0x614e); -} - -SPRINTF_TEST_CASE(sharp_flag_with_long_long__non_standard_format) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("0b110", buffer, "%#llb", (long long) 6); -} -#endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */ - -SPRINTF_TEST_CASE(specifier) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("Hello testing", buffer, "Hello testing"); - SPRINTF_CHECK("Hello testing", buffer, "%s", "Hello testing"); - SPRINTF_CHECK("(null)", buffer, "%s", (const char *) RT_NULL); - SPRINTF_CHECK("1024", buffer, "%d", 1024); -#if INT_MAX >= 2147483647LL - SPRINTF_CHECK("2147483647", buffer, "%d", 2147483647); - SPRINTF_CHECK("4294966272", buffer, "%u", 4294966272U); - SPRINTF_CHECK("37777777001", buffer, "%o", 4294966785U); - SPRINTF_CHECK("1234abcd", buffer, "%x", 305441741); - SPRINTF_CHECK("edcb5433", buffer, "%x", 3989525555U); - SPRINTF_CHECK("1234ABCD", buffer, "%X", 305441741); - SPRINTF_CHECK("EDCB5433", buffer, "%X", 3989525555U); -#endif - SPRINTF_CHECK("-1024", buffer, "%d", -1024); - SPRINTF_CHECK("1024", buffer, "%i", 1024); - SPRINTF_CHECK("-1024", buffer, "%i", -1024); - SPRINTF_CHECK("1024", buffer, "%u", 1024); - SPRINTF_CHECK("777", buffer, "%o", 511); - SPRINTF_CHECK("%", buffer, "%%"); - -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - SPRINTF_CHECK("127", buffer, "%I8d", (int8_t) 127LL); -#if (SHRT_MAX >= 32767) - SPRINTF_CHECK("32767", buffer, "%I16d", (int16_t) 32767LL); -#endif -#if (LLONG_MAX >= 2147483647) - SPRINTF_CHECK("2147483647", buffer, "%I32d", (int32_t) 2147483647LL); -#if (LLONG_MAX >= 9223372036854775807LL) - SPRINTF_CHECK("9223372036854775807", buffer, "%I64d", (int64_t) 9223372036854775807LL); -#endif -#endif -#endif /* RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS */ -} - -SPRINTF_TEST_CASE(width) -{ - char buffer[base_buffer_size]; -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("Hello testing", buffer, "%1s", "Hello testing"); -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ - SPRINTF_CHECK("1024", buffer, "%1d", 1024); - SPRINTF_CHECK("-1024", buffer, "%1d", -1024); - SPRINTF_CHECK("1024", buffer, "%1i", 1024); - SPRINTF_CHECK("-1024", buffer, "%1i", -1024); - SPRINTF_CHECK("1024", buffer, "%1u", 1024); -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - SPRINTF_CHECK("1024", buffer, "%1I16u", (uint16_t) 1024); - SPRINTF_CHECK("1024", buffer, "%1I32u", (uint32_t) 1024); - SPRINTF_CHECK("1024", buffer, "%1I64u", (uint64_t) 1024); -#endif /* RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS */ - SPRINTF_CHECK("4294966272", buffer, "%1u", 4294966272U); -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - SPRINTF_CHECK("4294966272", buffer, "%1I32u", (uint32_t) 4294966272U); - SPRINTF_CHECK("4294966272", buffer, "%1I64u", (uint64_t) 4294966272U); -#endif /* RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS */ - SPRINTF_CHECK("777", buffer, "%1o", 511); - SPRINTF_CHECK("37777777001", buffer, "%1o", 4294966785U); - SPRINTF_CHECK("1234abcd", buffer, "%1x", 305441741); - SPRINTF_CHECK("edcb5433", buffer, "%1x", 3989525555U); - SPRINTF_CHECK("1234ABCD", buffer, "%1X", 305441741); - SPRINTF_CHECK("EDCB5433", buffer, "%1X", 3989525555U); - SPRINTF_CHECK("x", buffer, "%1c", 'x'); -} - -SPRINTF_TEST_CASE(width_20) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK(" Hello", buffer, "%20s", "Hello"); - SPRINTF_CHECK(" 1024", buffer, "%20d", 1024); - SPRINTF_CHECK(" -1024", buffer, "%20d", -1024); - SPRINTF_CHECK(" 1024", buffer, "%20i", 1024); - SPRINTF_CHECK(" -1024", buffer, "%20i", -1024); - SPRINTF_CHECK(" 0", buffer, "%20i", 0); - SPRINTF_CHECK(" 1024", buffer, "%20u", 1024); -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - SPRINTF_CHECK(" 1024", buffer, "%20I16u", (uint16_t) 1024); - SPRINTF_CHECK(" 1024", buffer, "%20I32u", (uint32_t) 1024); - SPRINTF_CHECK(" 1024", buffer, "%20I64u", (uint64_t) 1024); -#endif /* RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS */ - SPRINTF_CHECK(" 4294966272", buffer, "%20u", 4294966272U); -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - SPRINTF_CHECK(" 4294966272", buffer, "%20I32u", (uint32_t) 4294966272U); - SPRINTF_CHECK(" 4294966272", buffer, "%20I64u", (uint64_t) 4294966272U); -#endif /* RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS */ - SPRINTF_CHECK(" 777", buffer, "%20o", 511); - SPRINTF_CHECK(" 37777777001", buffer, "%20o", 4294966785U); - SPRINTF_CHECK(" 1234abcd", buffer, "%20x", 305441741); - SPRINTF_CHECK(" edcb5433", buffer, "%20x", 3989525555U); - SPRINTF_CHECK(" 1234ABCD", buffer, "%20X", 305441741); - SPRINTF_CHECK(" EDCB5433", buffer, "%20X", 3989525555U); - SPRINTF_CHECK(" 0", buffer, "%20X", 0); - SPRINTF_CHECK(" 0", buffer, "%20X", 0U); -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - SPRINTF_CHECK(" 0", buffer, "%20llX", 0ULL); -#endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */ - SPRINTF_CHECK(" x", buffer, "%20c", 'x'); -} - -SPRINTF_TEST_CASE(width_asterisk_20) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK(" Hello", buffer, "%*s", 20, "Hello"); - SPRINTF_CHECK(" 1024", buffer, "%*d", 20, 1024); - SPRINTF_CHECK(" -1024", buffer, "%*d", 20, -1024); - SPRINTF_CHECK(" 1024", buffer, "%*i", 20, 1024); - SPRINTF_CHECK(" -1024", buffer, "%*i", 20, -1024); - SPRINTF_CHECK(" 1024", buffer, "%*u", 20, 1024); -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - SPRINTF_CHECK(" 1024", buffer, "%*I16u", 20, (uint16_t) 1024); - SPRINTF_CHECK(" 1024", buffer, "%*I32u", 20, (uint32_t) 1024); - SPRINTF_CHECK(" 1024", buffer, "%*I64u", 20, (uint64_t) 1024); -#endif /* RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS */ - SPRINTF_CHECK(" 4294966272", buffer, "%*u", 20, 4294966272U); -#ifdef RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS - SPRINTF_CHECK(" 4294966272", buffer, "%*I32u", 20, (uint32_t) 4294966272U); - SPRINTF_CHECK(" 4294966272", buffer, "%*I64u", 20, (uint64_t) 4294966272U); -#endif /* RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS */ - SPRINTF_CHECK(" 777", buffer, "%*o", 20, 511); - SPRINTF_CHECK(" 37777777001", buffer, "%*o", 20, 4294966785U); - SPRINTF_CHECK(" 1234abcd", buffer, "%*x", 20, 305441741); - SPRINTF_CHECK(" edcb5433", buffer, "%*x", 20, 3989525555U); - SPRINTF_CHECK(" 1234ABCD", buffer, "%*X", 20, 305441741); - SPRINTF_CHECK(" EDCB5433", buffer, "%*X", 20, 3989525555U); - SPRINTF_CHECK(" x", buffer, "%*c", 20, 'x'); -} - -SPRINTF_TEST_CASE(width_minus_20) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("Hello ", buffer, "%-20s", "Hello"); - SPRINTF_CHECK("1024 ", buffer, "%-20d", 1024); - SPRINTF_CHECK("-1024 ", buffer, "%-20d", -1024); - SPRINTF_CHECK("1024 ", buffer, "%-20i", 1024); - SPRINTF_CHECK("-1024 ", buffer, "%-20i", -1024); - SPRINTF_CHECK("1024 ", buffer, "%-20u", 1024); -#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS - SPRINTF_CHECK("1024.1234 ", buffer, "%-20.4f", 1024.1234); -#endif /* RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS */ - SPRINTF_CHECK("4294966272 ", buffer, "%-20u", 4294966272U); - SPRINTF_CHECK("777 ", buffer, "%-20o", 511); - SPRINTF_CHECK("37777777001 ", buffer, "%-20o", 4294966785U); - SPRINTF_CHECK("1234abcd ", buffer, "%-20x", 305441741); - SPRINTF_CHECK("edcb5433 ", buffer, "%-20x", 3989525555U); - SPRINTF_CHECK("1234ABCD ", buffer, "%-20X", 305441741); - SPRINTF_CHECK("EDCB5433 ", buffer, "%-20X", 3989525555U); - SPRINTF_CHECK("x ", buffer, "%-20c", 'x'); - SPRINTF_CHECK("| 9| |9 | | 9|", buffer, "|%5d| |%-2d| |%5d|", 9, 9, 9); - SPRINTF_CHECK("| 10| |10| | 10|", buffer, "|%5d| |%-2d| |%5d|", 10, 10, 10); - SPRINTF_CHECK("| 9| |9 | | 9|", buffer, "|%5d| |%-12d| |%5d|", 9, 9, 9); - SPRINTF_CHECK("| 10| |10 | | 10|", buffer, "|%5d| |%-12d| |%5d|", 10, 10, 10); -} - -SPRINTF_TEST_CASE(width_0_minus_20) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("Hello ", buffer, "%0-20s", "Hello"); - SPRINTF_CHECK("1024 ", buffer, "%0-20d", 1024); - SPRINTF_CHECK("-1024 ", buffer, "%0-20d", -1024); - SPRINTF_CHECK("1024 ", buffer, "%0-20i", 1024); - SPRINTF_CHECK("-1024 ", buffer, "%0-20i", -1024); - SPRINTF_CHECK("1024 ", buffer, "%0-20u", 1024); - SPRINTF_CHECK("4294966272 ", buffer, "%0-20u", 4294966272U); - SPRINTF_CHECK("777 ", buffer, "%0-20o", 511); - SPRINTF_CHECK("37777777001 ", buffer, "%0-20o", 4294966785U); - SPRINTF_CHECK("1234abcd ", buffer, "%0-20x", 305441741); - SPRINTF_CHECK("edcb5433 ", buffer, "%0-20x", 3989525555U); - SPRINTF_CHECK("1234ABCD ", buffer, "%0-20X", 305441741); - SPRINTF_CHECK("EDCB5433 ", buffer, "%0-20X", 3989525555U); - SPRINTF_CHECK("x ", buffer, "%0-20c", 'x'); -} - -SPRINTF_TEST_CASE(padding_20) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("00000000000000001024", buffer, "%020d", 1024); - SPRINTF_CHECK("-0000000000000001024", buffer, "%020d", -1024); - SPRINTF_CHECK("00000000000000001024", buffer, "%020i", 1024); - SPRINTF_CHECK("-0000000000000001024", buffer, "%020i", -1024); - SPRINTF_CHECK("00000000000000001024", buffer, "%020u", 1024); - SPRINTF_CHECK("00000000004294966272", buffer, "%020u", 4294966272U); - SPRINTF_CHECK("00000000000000000777", buffer, "%020o", 511); - SPRINTF_CHECK("00000000037777777001", buffer, "%020o", 4294966785U); - SPRINTF_CHECK("0000000000001234abcd", buffer, "%020x", 305441741); - SPRINTF_CHECK("000000000000edcb5433", buffer, "%020x", 3989525555U); - SPRINTF_CHECK("0000000000001234ABCD", buffer, "%020X", 305441741); - SPRINTF_CHECK("000000000000EDCB5433", buffer, "%020X", 3989525555U); -} - -SPRINTF_TEST_CASE(padding_dot_20) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("00000000000000001024", buffer, "%.20d", 1024); - SPRINTF_CHECK("-00000000000000001024", buffer, "%.20d", -1024); - SPRINTF_CHECK("00000000000000001024", buffer, "%.20i", 1024); - SPRINTF_CHECK("-00000000000000001024", buffer, "%.20i", -1024); - SPRINTF_CHECK("00000000000000001024", buffer, "%.20u", 1024); - SPRINTF_CHECK("00000000004294966272", buffer, "%.20u", 4294966272U); - SPRINTF_CHECK("00000000000000000777", buffer, "%.20o", 511); - SPRINTF_CHECK("00000000037777777001", buffer, "%.20o", 4294966785U); - SPRINTF_CHECK("0000000000001234abcd", buffer, "%.20x", 305441741); - SPRINTF_CHECK("000000000000edcb5433", buffer, "%.20x", 3989525555U); - SPRINTF_CHECK("0000000000001234ABCD", buffer, "%.20X", 305441741); - SPRINTF_CHECK("000000000000EDCB5433", buffer, "%.20X", 3989525555U); -} - -SPRINTF_TEST_CASE(padding_sharp_020__non_standard_format) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("00000000000000001024", buffer, "%#020d", 1024); - SPRINTF_CHECK("-0000000000000001024", buffer, "%#020d", -1024); - SPRINTF_CHECK("00000000000000001024", buffer, "%#020i", 1024); - SPRINTF_CHECK("-0000000000000001024", buffer, "%#020i", -1024); - SPRINTF_CHECK("00000000000000001024", buffer, "%#020u", 1024); - SPRINTF_CHECK("00000000004294966272", buffer, "%#020u", 4294966272U); -} - -SPRINTF_TEST_CASE(padding_sharp_020) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("00000000000000000777", buffer, "%#020o", 511); - SPRINTF_CHECK("00000000037777777001", buffer, "%#020o", 4294966785U); - SPRINTF_CHECK("0x00000000001234abcd", buffer, "%#020x", 305441741); - SPRINTF_CHECK("0x0000000000edcb5433", buffer, "%#020x", 3989525555U); - SPRINTF_CHECK("0X00000000001234ABCD", buffer, "%#020X", 305441741); - SPRINTF_CHECK("0X0000000000EDCB5433", buffer, "%#020X", 3989525555U); -} - -SPRINTF_TEST_CASE(padding_sharp_20__non_standard_format) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK(" 1024", buffer, "%#20d", 1024); - SPRINTF_CHECK(" -1024", buffer, "%#20d", -1024); - SPRINTF_CHECK(" 1024", buffer, "%#20i", 1024); - SPRINTF_CHECK(" -1024", buffer, "%#20i", -1024); - SPRINTF_CHECK(" 1024", buffer, "%#20u", 1024); - SPRINTF_CHECK(" 4294966272", buffer, "%#20u", 4294966272U); -} - -SPRINTF_TEST_CASE(padding_sharp_20) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK(" 0777", buffer, "%#20o", 511); - SPRINTF_CHECK(" 037777777001", buffer, "%#20o", 4294966785U); - SPRINTF_CHECK(" 0x1234abcd", buffer, "%#20x", 305441741); - SPRINTF_CHECK(" 0xedcb5433", buffer, "%#20x", 3989525555U); - SPRINTF_CHECK(" 0X1234ABCD", buffer, "%#20X", 305441741); - SPRINTF_CHECK(" 0XEDCB5433", buffer, "%#20X", 3989525555U); -} - -SPRINTF_TEST_CASE(padding_20_point_5) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK(" 01024", buffer, "%20.5d", 1024); - SPRINTF_CHECK(" -01024", buffer, "%20.5d", -1024); - SPRINTF_CHECK(" 01024", buffer, "%20.5i", 1024); - SPRINTF_CHECK(" -01024", buffer, "%20.5i", -1024); - SPRINTF_CHECK(" 01024", buffer, "%20.5u", 1024); - SPRINTF_CHECK(" 4294966272", buffer, "%20.5u", 4294966272U); - SPRINTF_CHECK(" 00777", buffer, "%20.5o", 511); - SPRINTF_CHECK(" 37777777001", buffer, "%20.5o", 4294966785U); - SPRINTF_CHECK(" 1234abcd", buffer, "%20.5x", 305441741); - SPRINTF_CHECK(" 00edcb5433", buffer, "%20.10x", 3989525555U); - SPRINTF_CHECK(" 1234ABCD", buffer, "%20.5X", 305441741); - SPRINTF_CHECK(" 00EDCB5433", buffer, "%20.10X", 3989525555U); -} - -SPRINTF_TEST_CASE(padding_negative_numbers) -{ - char buffer[base_buffer_size]; - - /* space padding */ - SPRINTF_CHECK("-5", buffer, "% 1d", -5); - SPRINTF_CHECK("-5", buffer, "% 2d", -5); - SPRINTF_CHECK(" -5", buffer, "% 3d", -5); - SPRINTF_CHECK(" -5", buffer, "% 4d", -5); - - /* zero padding */ - SPRINTF_CHECK("-5", buffer, "%01d", -5); - SPRINTF_CHECK("-5", buffer, "%02d", -5); - SPRINTF_CHECK("-05", buffer, "%03d", -5); - SPRINTF_CHECK("-005", buffer, "%04d", -5); -} - -#if defined(RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS) || \ - defined(RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS) -SPRINTF_TEST_CASE(float_padding_negative_numbers) -{ - char buffer[base_buffer_size]; - - /* space padding */ -#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS - SPRINTF_CHECK("-5.0", buffer, "% 3.1f", -5.); - SPRINTF_CHECK("-5.0", buffer, "% 4.1f", -5.); - SPRINTF_CHECK(" -5.0", buffer, "% 5.1f", -5.); -#endif - -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - SPRINTF_CHECK(" -5", buffer, "% 6.1g", -5.); - SPRINTF_CHECK("-5.0e+00", buffer, "% 6.1e", -5.); - SPRINTF_CHECK(" -5.0e+00", buffer, "% 10.1e", -5.); -#endif - - /* zero padding */ -#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS - SPRINTF_CHECK("-5.0", buffer, "%03.1f", -5.); - SPRINTF_CHECK("-5.0", buffer, "%04.1f", -5.); - SPRINTF_CHECK("-05.0", buffer, "%05.1f", -5.); - - /* zero padding no decimal point */ - SPRINTF_CHECK("-5", buffer, "%01.0f", -5.); - SPRINTF_CHECK("-5", buffer, "%02.0f", -5.); - SPRINTF_CHECK("-05", buffer, "%03.0f", -5.); -#endif - -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - SPRINTF_CHECK("-005.0e+00", buffer, "%010.1e", -5.); - SPRINTF_CHECK("-05E+00", buffer, "%07.0E", -5.); - SPRINTF_CHECK("-05", buffer, "%03.0g", -5.); -#endif -} - -SPRINTF_TEST_CASE(infinity_and_not_a_number_values) -{ - char buffer[base_buffer_size]; - - /* test special-case floats using math.h macros */ -#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS - SPRINTF_CHECK(" nan", buffer, "%8f", (double) NAN); - SPRINTF_CHECK(" inf", buffer, "%8f", (double) INFINITY); - SPRINTF_CHECK("-inf ", buffer, "%-8f", (double) -INFINITY); -#endif /* RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS */ -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - SPRINTF_CHECK(" nan", buffer, "%8e", (double) NAN); - SPRINTF_CHECK(" inf", buffer, "%8e", (double) INFINITY); - SPRINTF_CHECK("-inf ", buffer, "%-8e", (double) -INFINITY); -#endif /* RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS */ -} - -SPRINTF_TEST_CASE(floating_point_specifiers_precision_and_flags) -{ - char buffer[base_buffer_size]; -#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS - SPRINTF_CHECK("3.1415", buffer, "%.4f", 3.1415354); - SPRINTF_CHECK("30343.142", buffer, "%.3f", 30343.1415354); - SPRINTF_CHECK("34", buffer, "%.0f", 34.1415354); - SPRINTF_CHECK("1", buffer, "%.0f", 1.3); - SPRINTF_CHECK("2", buffer, "%.0f", 1.55); - SPRINTF_CHECK("1.6", buffer, "%.1f", 1.64); - SPRINTF_CHECK("42.90", buffer, "%.2f", 42.8952); - SPRINTF_CHECK("42.895200000", buffer, "%.9f", 42.8952); - SPRINTF_CHECK("42.8952230000", buffer, "%.10f", 42.895223); - SPRINTF_CHECK("42.895223123457", buffer, "%.12f", 42.89522312345678); - SPRINTF_CHECK("42477.371093750000000", buffer, "%020.15f", 42477.37109375); - SPRINTF_CHECK("42.895223876543", buffer, "%.12f", 42.89522387654321); - SPRINTF_CHECK(" 42.90", buffer, "%6.2f", 42.8952); - SPRINTF_CHECK("+42.90", buffer, "%+6.2f", 42.8952); - SPRINTF_CHECK("+42.9", buffer, "%+5.1f", 42.9252); - SPRINTF_CHECK("42.500000", buffer, "%f", 42.5); - SPRINTF_CHECK("42.5", buffer, "%.1f", 42.5); - SPRINTF_CHECK("42167.000000", buffer, "%f", 42167.0); - SPRINTF_CHECK("-12345.987654321", buffer, "%.9f", -12345.987654321); - SPRINTF_CHECK("4.0", buffer, "%.1f", 3.999); - SPRINTF_CHECK("4", buffer, "%.0f", 3.5); - SPRINTF_CHECK("4", buffer, "%.0f", 4.5); - SPRINTF_CHECK("3", buffer, "%.0f", 3.49); - SPRINTF_CHECK("3.5", buffer, "%.1f", 3.49); - SPRINTF_CHECK("a0.5 ", buffer, "a%-5.1f", 0.5); - SPRINTF_CHECK("a0.5 end", buffer, "a%-5.1fend", 0.5); - - /* %f for double */ - SPRINTF_CHECK("42.895223123457", buffer, "%.12f", 42.89522312345678); - /* %F for double */ - SPRINTF_CHECK("42.895223123457", buffer, "%.12F", 42.89522312345678); - /* %lf for double */ - SPRINTF_CHECK("42.895223123457", buffer, "%.12lf", 42.89522312345678); - /* %Lf for long double */ - // TODO: fix me - // SPRINTF_CHECK("42.895223123457", buffer, "%.12Lf", 42.89522312345678l); - // SPRINTF_CHECK("42.895223123457", buffer, "%.12Lf", 42.89522312345678L); -#endif /* RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS */ - -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - SPRINTF_CHECK("0.5", buffer, "%.4g", 0.5); - SPRINTF_CHECK("1", buffer, "%.4g", 1.0); - SPRINTF_CHECK("12345.7", buffer, "%G", 12345.678); - SPRINTF_CHECK("12345.68", buffer, "%.7G", 12345.678); - SPRINTF_CHECK("1.2346E+08", buffer, "%.5G", 123456789.); - SPRINTF_CHECK("12345", buffer, "%.6G", 12345.); - SPRINTF_CHECK(" +1.235e+08", buffer, "%+12.4g", 123456789.); - SPRINTF_CHECK("0.0012", buffer, "%.2G", 0.001234); - SPRINTF_CHECK(" +0.001234", buffer, "%+10.4G", 0.001234); - SPRINTF_CHECK("+001.234e-05", buffer, "%+012.4g", 0.00001234); - /* Note: The following two values are _barely_ normal; - make their mantissa 1.1 and they lose their normality. */ - SPRINTF_CHECK("-1.23e-308", buffer, "%.3g", -1.2345e-308); - SPRINTF_CHECK("+1.230E+308", buffer, "%+.3E", 1.23e+308); - SPRINTF_CHECK("1.000e+01", buffer, "%.3e", 9.9996); - SPRINTF_CHECK("0", buffer, "%g", 0.); - SPRINTF_CHECK("-0", buffer, "%g", -0.); - SPRINTF_CHECK("+0", buffer, "%+g", 0.); - SPRINTF_CHECK("-0", buffer, "%+g", -0.); - SPRINTF_CHECK("-4e+04", buffer, "%.1g", -40661.5); - SPRINTF_CHECK("-4.e+04", buffer, "%#.1g", -40661.5); - SPRINTF_CHECK("100.", buffer, "%#.3g", 99.998580932617187500); - // TODO: fix me - // SPRINTF_CHECK("1.e01", buffer, "%# 01.1g", 9.8); - /* Note: The following value is _barely_ normal; - make the mantissa 1.1 and it loses its normality. */ - SPRINTF_CHECK("1.2345678901e-308", buffer, "%.10e", 1.2345678901e-308); - /* Rounding-focused checks */ - SPRINTF_CHECK("4.895512e+04", buffer, "%e", 48955.125); - SPRINTF_CHECK("9.2524e+04", buffer, "%.4e", 92523.5); - SPRINTF_CHECK("-8.380923438e+04", buffer, "%.9e", -83809.234375); - - /* %g for double */ - SPRINTF_CHECK("100.", buffer, "%#.3g", 99.998580932617187500); - /* %G for double */ - SPRINTF_CHECK("100.", buffer, "%#.3G", 99.998580932617187500); - /* %lg for double */ - SPRINTF_CHECK("100.", buffer, "%#.3lg", 99.998580932617187500); - /* %Lg for long double */ - // TODO: fix me - // SPRINTF_CHECK("100.", buffer, "%#.3Lg", 99.998580932617187500l); - // SPRINTF_CHECK("100.", buffer, "%#.3Lg", 99.998580932617187500L); - - /* %e for double */ - SPRINTF_CHECK("-8.380923438e+04", buffer, "%.9e", -83809.234375); - /* %E for double */ - SPRINTF_CHECK("-8.380923438E+04", buffer, "%.9E", -83809.234375); - /* %le for double */ - SPRINTF_CHECK("-8.380923438e+04", buffer, "%.9le", -83809.234375); - /* %Le for long double */ - // TODO: fix me - // SPRINTF_CHECK("-8.380923438e+04", buffer, "%.9Le", -83809.234375l); - // SPRINTF_CHECK("-8.380923438e+04", buffer, "%.9Le", -83809.234375L); -#endif /* RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS */ -} - -#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS -SPRINTF_TEST_CASE(floating_point_specifiers_with_31_to_32_bit_integer_values) -{ - char buffer[base_buffer_size]; -#if RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL >= 10 - SPRINTF_CHECK("2147483647", buffer, "%.10f", 2147483647.0); /* 2^31 - 1 */ - SPRINTF_CHECK("2147483648", buffer, "%.10f", 2147483648.0); /* 2^31 */ - SPRINTF_CHECK("4294967295", buffer, "%.10f", 4294967295.0); /* 2^32 - 1 */ - SPRINTF_CHECK("4294967296", buffer, "%.10f", 4294967296.0); /* 2^32 */ -#else - SPRINTF_CHECK("2.1474836470e+09", buffer, "%.10f", 2147483647.0); /* 2^31 - 1 */ - SPRINTF_CHECK("2.1474836480e+09", buffer, "%.10f", 2147483648.0); /* 2^31 */ - SPRINTF_CHECK("4.2949672950e+09", buffer, "%.10f", 4294967295.0); /* 2^32 - 1 */ - SPRINTF_CHECK("4.2949672960e+09", buffer, "%.10f", 4294967296.0); /* 2^32 */ -#endif /* RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL */ - SPRINTF_CHECK("2147483647", buffer, "%.10g", 2147483647.0); /* 2^31 - 1 */ - SPRINTF_CHECK("2147483648", buffer, "%.10g", 2147483648.0); /* 2^31 */ - SPRINTF_CHECK("4294967295", buffer, "%.10g", 4294967295.0); /* 2^32 - 1 */ - SPRINTF_CHECK("4294967296", buffer, "%.10g", 4294967296.0); /* 2^32 */ -} - -SPRINTF_TEST_CASE(fallback_from_decimal_to_exponential) -{ - char buffer[base_buffer_size]; - - /* Check for 1 * 1000 */ - if (RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL < 3) { - SPRINTF_CHECK("1e+3", buffer, "%.0f", (double) ((int64_t) 1 * 1000)); - } else { - SPRINTF_CHECK("1000", buffer, "%.0f", (double) ((int64_t) 1 * 1000)); - } - - /* Check for 1 * 1000 * 1000 */ - if (RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL < 6) { - SPRINTF_CHECK("1e+6", buffer, "%.0f", (double) ((int64_t) 1 * 1000 * 1000)); - } else { - SPRINTF_CHECK("1000000", buffer, "%.0f", (double) ((int64_t) 1 * 1000 * 1000)); - } - - /* Check for 1 * 1000 * 1000 * 1000 */ - if (RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL < 9) { - SPRINTF_CHECK("1e+9", buffer, "%.0f", (double) ((int64_t) 1 * 1000 * 1000 * 1000)); - } else { - SPRINTF_CHECK("1000000000", buffer, "%.0f", (double) ((int64_t) 1 * 1000 * 1000 * 1000)); - } - - /* Check for 1 * 1000 * 1000 * 1000 * 1000 */ - if (RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL < 12) { -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - SPRINTF_CHECK("1e+12", buffer, "%.0f", (double) ((int64_t) 1 * 1000 * 1000 * 1000 * 1000)); -#else - SPRINTF_CHECK("", buffer, "%.0f", (double) ((int64_t) 1 * 1000 * 1000 * 1000 * 1000)); -#endif - } else { - SPRINTF_CHECK("1000000000000", buffer, "%.0f", (double) ((int64_t) 1 * 1000 * 1000 * 1000 * 1000)); - } - - /* Check for 1 * 1000 * 1000 * 1000 * 1000 * 1000 */ - if (RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL < 15) { -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - SPRINTF_CHECK("1e+15", buffer, "%.0f", (double) ((int64_t) 1 * 1000 * 1000 * 1000 * 1000 * 1000)); -#else - SPRINTF_CHECK("", buffer, "%.0f", (double) ((int64_t) 1 * 1000 * 1000 * 1000 * 1000 * 1000)); -#endif - } else { - SPRINTF_CHECK("1000000000000000", buffer, "%.0f", (double) ((int64_t) 1 * 1000 * 1000 * 1000 * 1000 * 1000)); - } - - /* Check for a value which should definitely be out of range for float */ -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - SPRINTF_CHECK("1.0e+20", buffer, "%.1f", 1E20); -#else - SPRINTF_CHECK("", buffer, "%.1f", 1E20); -#endif -} -#endif /* RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS */ - -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS -SPRINTF_TEST_CASE(tiny_floating_point_values) -{ - char buffer[base_buffer_size]; - - SPRINTF_CHECK("1e-23", buffer, "%.0e", 1.380651569e-23); - SPRINTF_CHECK("1.4e-23", buffer, "%.1e", 1.380651569e-23); - SPRINTF_CHECK("1.38e-23", buffer, "%.2e", 1.380651569e-23); - SPRINTF_CHECK("1.381e-23", buffer, "%.3e", 1.380651569e-23); - SPRINTF_CHECK("1.3807e-23", buffer, "%.4e", 1.380651569e-23); - SPRINTF_CHECK("1.38065e-23", buffer, "%.5e", 1.380651569e-23); - SPRINTF_CHECK("1.380652e-23", buffer, "%.6e", 1.380651569e-23); - SPRINTF_CHECK("1.3806516e-23", buffer, "%.7e", 1.380651569e-23); - SPRINTF_CHECK("1.38065157e-23", buffer, "%.8e", 1.380651569e-23); - SPRINTF_CHECK("1.380651569e-23", buffer, "%.9e", 1.380651569e-23); - SPRINTF_CHECK("1.3806515690e-23", buffer, "%.10e", 1.380651569e-23); - SPRINTF_CHECK("1.38065156900e-23", buffer, "%.11e", 1.380651569e-23); -} -#endif /* RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS */ -#endif /* RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS || RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS */ - -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD -SPRINTF_TEST_CASE(length) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("", buffer, "%.0s", "Hello testing"); - SPRINTF_CHECK(" ", buffer, "%20.0s", "Hello testing"); - SPRINTF_CHECK("", buffer, "%.s", "Hello testing"); - SPRINTF_CHECK(" ", buffer, "%20.s", "Hello testing"); - SPRINTF_CHECK(" 1024", buffer, "%20.0d", 1024); - SPRINTF_CHECK(" -1024", buffer, "%20.0d", -1024); - SPRINTF_CHECK(" ", buffer, "%20.d", 0); - SPRINTF_CHECK(" 1024", buffer, "%20.0i", 1024); - SPRINTF_CHECK(" -1024", buffer, "%20.i", -1024); - SPRINTF_CHECK(" ", buffer, "%20.i", 0); - SPRINTF_CHECK(" 1024", buffer, "%20.u", 1024); - SPRINTF_CHECK(" 4294966272", buffer, "%20.0u", 4294966272U); - SPRINTF_CHECK(" ", buffer, "%20.u", 0U); - SPRINTF_CHECK(" 777", buffer, "%20.o", 511); - SPRINTF_CHECK(" 37777777001", buffer, "%20.0o", 4294966785U); - SPRINTF_CHECK(" ", buffer, "%20.o", 0U); - SPRINTF_CHECK(" 1234abcd", buffer, "%20.x", 305441741); - SPRINTF_CHECK(" 1234abcd", - buffer, "%50.x", 305441741); - SPRINTF_CHECK(" 1234abcd 12345", - buffer, "%50.x%10.u", 305441741, 12345); - SPRINTF_CHECK(" edcb5433", buffer, "%20.0x", 3989525555U); - SPRINTF_CHECK(" ", buffer, "%20.x", 0U); - SPRINTF_CHECK(" 1234ABCD", buffer, "%20.X", 305441741); - SPRINTF_CHECK(" EDCB5433", buffer, "%20.0X", 3989525555U); - SPRINTF_CHECK(" ", buffer, "%20.X", 0U); -} - -SPRINTF_TEST_CASE(length__non_standard_format) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK(" ", buffer, "%02.0u", 0U); - SPRINTF_CHECK(" ", buffer, "%02.0d", 0); -} - -SPRINTF_TEST_CASE(unknown_flag__non_standard_format) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("kmarco", buffer, "%kmarco", 42, 37); -} - -SPRINTF_TEST_CASE(string_length__non_standard_format) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK(".2s", buffer, "%.4.2s", "123456"); -} -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ - -SPRINTF_TEST_CASE(integer_types) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("0", buffer, "%i", 0); - SPRINTF_CHECK("1234", buffer, "%i", 1234); - SPRINTF_CHECK("32767", buffer, "%i", 32767); - SPRINTF_CHECK("-32767", buffer, "%i", -32767); - SPRINTF_CHECK("30", buffer, "%li", 30L); - SPRINTF_CHECK("-2147483647", buffer, "%li", -2147483647L); - SPRINTF_CHECK("2147483647", buffer, "%li", 2147483647L); -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - SPRINTF_CHECK("30", buffer, "%lli", 30LL); -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("-9223372036854775807", buffer, "%lli", -9223372036854775807LL); - SPRINTF_CHECK("9223372036854775807", buffer, "%lli", 9223372036854775807LL); -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ -#endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */ - SPRINTF_CHECK("100000", buffer, "%lu", 100000L); - SPRINTF_CHECK("4294967295", buffer, "%lu", 0xFFFFFFFFL); -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - SPRINTF_CHECK("281474976710656", buffer, "%llu", 281474976710656LLU); - SPRINTF_CHECK("18446744073709551615", buffer, "%llu", 18446744073709551615LLU); -#endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */ - SPRINTF_CHECK("2147483647", buffer, "%zu", (size_t) 2147483647UL); - SPRINTF_CHECK("2147483647", buffer, "%zd", (size_t) 2147483647UL); - SPRINTF_CHECK("-2147483647", buffer, "%zi", (ssize_t) -2147483647L); - SPRINTF_CHECK("165140", buffer, "%o", 60000); - SPRINTF_CHECK("57060516", buffer, "%lo", 12345678L); - SPRINTF_CHECK("12345678", buffer, "%lx", 0x12345678L); -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - SPRINTF_CHECK("1234567891234567", buffer, "%llx", 0x1234567891234567LLU); -#endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */ - SPRINTF_CHECK("abcdefab", buffer, "%lx", 0xabcdefabL); - SPRINTF_CHECK("ABCDEFAB", buffer, "%lX", 0xabcdefabL); - SPRINTF_CHECK("v", buffer, "%c", 'v'); - SPRINTF_CHECK("wv", buffer, "%cv", 'w'); - SPRINTF_CHECK("A Test", buffer, "%s", "A Test"); -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("255", buffer, "%hhu", (unsigned char) 0xFFU); -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ - SPRINTF_CHECK("4660", buffer, "%hu", (unsigned short) 0x1234u); - SPRINTF_CHECK("Test100 65535", buffer, "%s%hhi %hu", "Test", (char) 100, (unsigned short) 0xFFFF); -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("a", buffer, "%tx", &buffer[10] - &buffer[0]); - SPRINTF_CHECK("-2147483647", buffer, "%ji", (intmax_t) -2147483647L); -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ -} - -SPRINTF_TEST_CASE(types__non_standard_format) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("1110101001100000", buffer, "%b", 60000); - SPRINTF_CHECK("101111000110000101001110", buffer, "%lb", 12345678L); -} - -SPRINTF_TEST_CASE(pointer) -{ - char buffer[base_buffer_size]; - - /* Test for pointer value 0x1234U */ - SPRINTF_CHECK((sizeof(void *) == 4U) ? "0x00001234" : "0x0000000000001234", - buffer, "%p", (void *) 0x1234U); - - /* Test for pointer value 0x12345678U */ - SPRINTF_CHECK((sizeof(void *) == 4U) ? "0x12345678" : "0x0000000012345678", - buffer, "%p", (void *) 0x12345678U); - - /* Test for pointer range 0x12345678U to 0x7EDCBA98U */ - SPRINTF_CHECK((sizeof(void *) == 4U) ? "0x12345678-0x7edcba98" : "0x0000000012345678-0x000000007edcba98", - buffer, "%p-%p", (void *) 0x12345678U, (void *) 0x7EDCBA98U); - - /* Test for maximum uintptr_t value 0xFFFFFFFFU */ - if (sizeof(uintptr_t) == sizeof(uint64_t)) { - SPRINTF_CHECK("0x00000000ffffffff", buffer, "%p", (void *) (uintptr_t) 0xFFFFFFFFU); - } else { - SPRINTF_CHECK("0xffffffff", buffer, "%p", (void *) (uintptr_t) 0xFFFFFFFFU); - } - -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - /* Test for NULL pointer */ - SPRINTF_CHECK("(nil)", buffer, "%p", (const void *)RT_NULL); -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ -} - -SPRINTF_TEST_CASE(string_length) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("This", buffer, "%.4s", "This is a test"); - SPRINTF_CHECK("test", buffer, "%.4s", "test"); - SPRINTF_CHECK("123", buffer, "%.7s", "123"); - SPRINTF_CHECK("", buffer, "%.7s", ""); - SPRINTF_CHECK("1234ab", buffer, "%.4s%.2s", "123456", "abcdef"); - SPRINTF_CHECK("123", buffer, "%.*s", 3, "123456"); -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - SPRINTF_CHECK("(null)", buffer, "%.*s", 3, (const char *) RT_NULL); -#else - SPRINTF_CHECK("(nu", buffer, "%.*s", 3, (const char *) RT_NULL); -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ -} - -SPRINTF_TEST_CASE(misc) -{ - char buffer[base_buffer_size]; - SPRINTF_CHECK("53000atest-20 bit", buffer, "%u%u%ctest%d %s", 5, 3000, 'a', -20, "bit"); -#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS - SPRINTF_CHECK("0.33", buffer, "%.*f", 2, 0.33333333); - SPRINTF_CHECK("1", buffer, "%.*d", -1, 1); - SPRINTF_CHECK("foo", buffer, "%.3s", "foobar"); - SPRINTF_CHECK(" ", buffer, "% .0d", 0); - SPRINTF_CHECK(" 00004", buffer, "%10.5d", 4); - SPRINTF_CHECK("hi x", buffer, "%*sx", -3, "hi"); - SPRINTF_CHECK("00123 ", buffer, "%-20.5i", 123); - SPRINTF_CHECK("-67224.546875000000000000", buffer, "%.18f", -67224.546875); -#endif /* RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS */ -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - SPRINTF_CHECK("0.33", buffer, "%.*g", 2, 0.33333333); - SPRINTF_CHECK("3.33e-01", buffer, "%.*e", 2, 0.33333333); - SPRINTF_CHECK("0.000000e+00", buffer, "%e", 0.0); - SPRINTF_CHECK("-0.000000e+00", buffer, "%e", -0.0); -#endif /* RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS */ -} - -static void utest_do_tc(void) -{ - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(space_flag)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(space_flag__non_standard_format)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(plus_flag)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(plus_flag__non_standard_format)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(zero_flag)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(minus_flag)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(minus_flag_and_non_standard_zero_modifier_for_integers)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(sharp_flag)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(sharp_flag__non_standard_format)); -#ifdef RT_KLIBC_USING_VSNPRINTF_LONGLONG - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(sharp_flag_with_long_long)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(sharp_flag_with_long_long__non_standard_format)); -#endif /* RT_KLIBC_USING_VSNPRINTF_LONGLONG */ - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(specifier)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(width)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(width_20)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(width_asterisk_20)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(width_minus_20)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(width_0_minus_20)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(padding_20)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(padding_dot_20)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(padding_sharp_020__non_standard_format)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(padding_sharp_020)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(padding_sharp_20__non_standard_format)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(padding_sharp_20)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(padding_20_point_5)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(padding_negative_numbers)); -#if defined(RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS) || \ - defined(RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS) - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(float_padding_negative_numbers)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(infinity_and_not_a_number_values)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(floating_point_specifiers_precision_and_flags)); -#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(floating_point_specifiers_with_31_to_32_bit_integer_values)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(fallback_from_decimal_to_exponential)); -#endif /* RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS */ -#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(tiny_floating_point_values)); -#endif /* RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS */ -#endif /* RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS || RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS */ -#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(length)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(length__non_standard_format)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(unknown_flag__non_standard_format)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(string_length__non_standard_format)); -#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */ - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(integer_types)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(types__non_standard_format)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(pointer)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(string_length)); - UTEST_UNIT_RUN(SPRINTF_TEST_CASE_NAME(misc)); -} - -UTEST_TC_EXPORT(utest_do_tc, "klibc.rt_sprintf", RT_NULL, RT_NULL, 1000); diff --git a/rt-thread/src/klibc/utest/TC_rt_sscanf.c b/rt-thread/src/klibc/utest/TC_rt_sscanf.c deleted file mode 100644 index b82be04..0000000 --- a/rt-thread/src/klibc/utest/TC_rt_sscanf.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (c) 2006-2025, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2025-01-04 Meco Man the first version - */ - -#include -#include "utest.h" - -static void TC_rt_sscanf_char(void) -{ - const char str[] = "A B"; - char a, b; - rt_sscanf(str, "%c %c", &a, &b); - uassert_true(a == 'A' && b == 'B'); - /* Move to the next character after space for the second %c */ - rt_sscanf(str + 2, "%c", &b); - uassert_true(b == 'B'); -} - -static void TC_rt_sscanf_basic_int(void) -{ - const char str[] = "12345"; - int value; - int result = rt_sscanf(str, "%d", &value); - uassert_int_equal(result, 1); - uassert_int_equal(value, 12345); -} - -static void TC_rt_sscanf_basic_float(void) -{ - const char str[] = "123.45"; - float value; - int result = rt_sscanf(str, "%f", &value); - uassert_int_equal(result, 1); - uassert_float_equal(value, 123.45); -} - -static void TC_rt_sscanf_basic_string(void) -{ - const char str[] = "Hello, World!"; - char buffer[20]; - int result = rt_sscanf(str, "%s", buffer); - uassert_int_equal(result, 1); - uassert_str_equal(buffer, "Hello,"); -} - -static void TC_rt_sscanf_string_with_space(void) -{ - const char str[] = "Hello World"; - char a[20]; - rt_sscanf(str, "%*s %s", a); - uassert_str_equal(a, "World"); -} - -static void TC_rt_sscanf_basic_char(void) -{ - const char str[] = "A"; - char value; - int result = rt_sscanf(str, "%c", &value); - uassert_int_equal(result, 1); - uassert_int_equal(value, 'A'); -} - -static void TC_rt_sscanf_hex_1(void) -{ - const char str[] = "0x1A3F"; - int value; - int result = rt_sscanf(str, "%x", &value); - uassert_int_equal(result, 1); - uassert_int_equal(value, 0x1A3F); -} - -static void TC_rt_sscanf_hex_2(void) -{ - const char str[] = "0x1A 0XFF"; - int a, b; - rt_sscanf(str, "%x %x", &a, &b); - uassert_true(a == 0x1A && b == 0XFF); -} - -static void TC_rt_sscanf_oct_1(void) -{ - const char str[] = "0755"; - int value; - int result = rt_sscanf(str, "%o", &value); - uassert_int_equal(result, 1); - uassert_int_equal(value, 0755); -} - -static void TC_rt_sscanf_oct_2(void) -{ - const char str[] = "012 077"; - int a, b; - rt_sscanf(str, "%o %o", &a, &b); - uassert_true(a == 012 && b == 077); -} - -static void TC_rt_sscanf_multiple_args(void) -{ - const char str[] = "123 Hello"; - int int_value; - char str_value[20]; - int result = rt_sscanf(str, "%d %s", &int_value, str_value); - uassert_int_equal(result, 2); - uassert_int_equal(int_value, 123); - uassert_str_equal(str_value, "Hello"); -} - -static void TC_rt_sscanf_pointer(void) -{ - const char str[] = "0x12345678"; - void *ptr; - int result = rt_sscanf(str, "%p", &ptr); - uassert_int_equal(result, 1); - uassert_ptr_equal(ptr, (void *)0x12345678); -} - -static void TC_rt_sscanf_width_specifier(void) -{ - const char str[] = "123456789"; - int value; - int result = rt_sscanf(str, "%4d", &value); - uassert_int_equal(result, 1); - uassert_int_equal(value, 1234); -} - -static void TC_rt_sscanf_suppression(void) -{ - const char str[] = "123 456"; - int second_value; - int result = rt_sscanf(str, "%*d %d", &second_value); - uassert_int_equal(result, 1); - uassert_int_equal(second_value, 456); -} - -static void TC_rt_sscanf_match_set(void) -{ - const char str[] = "abc123"; - char buffer[10] = {0}; - int result = rt_sscanf(str, "%[a-z]", buffer); - uassert_int_equal(result, 1); - uassert_str_equal(buffer, "abc"); -} - -static void TC_rt_sscanf_match_set_negated(void) -{ - const char str[] = "abc123"; - char buffer[10]; - int result = rt_sscanf(str, "%[^0-9]", buffer); - uassert_int_equal(result, 1); - uassert_str_equal(buffer, "abc"); -} - -static void TC_rt_sscanf_match_set_range(void) -{ - const char str[] = "a-zA-Z"; - char buffer[10]; - int result = rt_sscanf(str, "%[a-z-A-Z]", buffer); - uassert_int_equal(result, 1); - uassert_str_equal(buffer, "a-zA-Z"); -} - -static void TC_rt_sscanf_whitespace_skip(void) -{ - const char str[] = " 12345"; - int value; - int result = rt_sscanf(str, "%d", &value); - uassert_int_equal(result, 1); - uassert_int_equal(value, 12345); -} - -static void TC_rt_sscanf_unsigned_int(void) -{ - const char str[] = "4294967295"; - unsigned int value; - int result = rt_sscanf(str, "%u", &value); - uassert_int_equal(result, 1); - uassert_int_equal(value, 4294967295U); -} - -static void TC_rt_sscanf_long_long_int(void) -{ - const char str[] = "9223372036854775807"; - long long value; - int result = rt_sscanf(str, "%lld", &value); - uassert_int_equal(result, 1); - uassert_int_equal(value, 9223372036854775807LL); -} - -static void TC_rt_sscanf_short_int(void) -{ - const char str[] = "32767"; - short value; - int result = rt_sscanf(str, "%hd", &value); - uassert_int_equal(result, 1); - uassert_int_equal(value, 32767); -} - -static void TC_rt_sscanf_null_string(void) -{ - const char str[] = ""; - int value; - int result = rt_sscanf(str, "%d", &value); - uassert_int_equal(result, -1); -} - -/* https://github.com/RT-Thread/rt-thread/issues/9853 */ -static void TC_rt_sscanf_issue_9853(void) -{ - int device_socket = 255; - int bfsz = 255; - const char str[] = "+MIPURC: \"rtcp\",0,240,HTTP/1.1 200 OK"; - rt_sscanf(str, "+MIPURC:%*[^,],%d,%d", &device_socket, (int *)&bfsz); - uassert_int_equal(device_socket, 0); - uassert_int_equal(bfsz, 240); -} - -static void utest_do_tc(void) -{ - UTEST_UNIT_RUN(TC_rt_sscanf_char); - UTEST_UNIT_RUN(TC_rt_sscanf_basic_int); - UTEST_UNIT_RUN(TC_rt_sscanf_basic_float); - UTEST_UNIT_RUN(TC_rt_sscanf_basic_string); - UTEST_UNIT_RUN(TC_rt_sscanf_string_with_space); - UTEST_UNIT_RUN(TC_rt_sscanf_basic_char); - UTEST_UNIT_RUN(TC_rt_sscanf_hex_1); - UTEST_UNIT_RUN(TC_rt_sscanf_hex_2); - UTEST_UNIT_RUN(TC_rt_sscanf_oct_1); - UTEST_UNIT_RUN(TC_rt_sscanf_oct_2); - UTEST_UNIT_RUN(TC_rt_sscanf_multiple_args); - UTEST_UNIT_RUN(TC_rt_sscanf_pointer); - UTEST_UNIT_RUN(TC_rt_sscanf_width_specifier); - UTEST_UNIT_RUN(TC_rt_sscanf_suppression); - UTEST_UNIT_RUN(TC_rt_sscanf_match_set); - UTEST_UNIT_RUN(TC_rt_sscanf_match_set_negated); - UTEST_UNIT_RUN(TC_rt_sscanf_match_set_range); - UTEST_UNIT_RUN(TC_rt_sscanf_whitespace_skip); - UTEST_UNIT_RUN(TC_rt_sscanf_unsigned_int); - UTEST_UNIT_RUN(TC_rt_sscanf_long_long_int); - UTEST_UNIT_RUN(TC_rt_sscanf_short_int); - UTEST_UNIT_RUN(TC_rt_sscanf_null_string); - UTEST_UNIT_RUN(TC_rt_sscanf_issue_9853); -} - -UTEST_TC_EXPORT(utest_do_tc, "klibc.rt_sscanf", RT_NULL, RT_NULL, 1000); diff --git a/rt-thread/src/kservice.c b/rt-thread/src/kservice.c index ee03b5a..915850e 100644 --- a/rt-thread/src/kservice.c +++ b/rt-thread/src/kservice.c @@ -93,8 +93,8 @@ rt_weak void rt_hw_cpu_shutdown(void) #ifdef __GNUC__ #define RT_HW_BACKTRACE_FRAME_GET_SELF(frame) do { \ - (frame)->fp = (rt_uintptr_t)__builtin_frame_address(0U); \ - (frame)->pc = ({__label__ pc; pc: (rt_uintptr_t)&&pc;}); \ + (frame)->fp = (rt_base_t)__builtin_frame_address(0U); \ + (frame)->pc = ({__label__ pc; pc: (rt_base_t)&&pc;}); \ } while (0) #else @@ -187,15 +187,23 @@ RTM_EXPORT(rt_console_get_device); */ rt_device_t rt_console_set_device(const char *name) { - rt_device_t old_device = _console_device; - rt_device_t new_device = rt_device_find(name); + rt_device_t new_device, old_device; - if (new_device != RT_NULL && new_device != old_device) + /* save old device */ + old_device = _console_device; + + /* find new console device */ + new_device = rt_device_find(name); + + /* check whether it's a same device */ + if (new_device == old_device) return RT_NULL; + + if (new_device != RT_NULL) { - if (old_device != RT_NULL) + if (_console_device != RT_NULL) { /* close old console device */ - rt_device_close(old_device); + rt_device_close(_console_device); } /* set new console device */ @@ -311,23 +319,20 @@ static void _console_release(void) */ static void _kputs(const char *str, long len) { -#ifdef RT_USING_DEVICE - rt_device_t console_device = rt_console_get_device(); -#endif /* RT_USING_DEVICE */ + RT_UNUSED(len); CONSOLE_TAKE; #ifdef RT_USING_DEVICE - if (console_device == RT_NULL) + if (_console_device == RT_NULL) { rt_hw_console_output(str); } else { - rt_device_write(console_device, 0, str, len); + rt_device_write(_console_device, 0, str, len); } #else - RT_UNUSED(len); rt_hw_console_output(str); #endif /* RT_USING_DEVICE */ @@ -417,7 +422,7 @@ rt_weak rt_err_t rt_backtrace_frame(rt_thread_t thread, struct rt_hw_backtrace_f { long nesting = 0; - rt_kprintf("please use: addr2line -e rtthread.elf -a -f\n"); + rt_kprintf("please use: addr2line -e rtthread.elf -a -f"); while (nesting < RT_BACKTRACE_LEVEL_MAX_NR) { @@ -441,9 +446,9 @@ rt_weak rt_err_t rt_backtrace_frame(rt_thread_t thread, struct rt_hw_backtrace_f */ rt_weak rt_err_t rt_backtrace_formatted_print(rt_ubase_t *buffer, long buflen) { - rt_kprintf("please use: addr2line -e rtthread.elf -a -f\n"); + rt_kprintf("please use: addr2line -e rtthread.elf -a -f"); - for (rt_size_t i = 0; i < buflen && buffer[i] != 0; i++) + for (size_t i = 0; i < buflen && buffer[i] != 0; i++) { rt_kprintf(" 0x%lx", (rt_ubase_t)buffer[i]); } @@ -540,7 +545,7 @@ rt_err_t rt_backtrace_thread(rt_thread_t thread) static void cmd_backtrace(int argc, char** argv) { - rt_uintptr_t pid; + rt_ubase_t pid; char *end_ptr; if (argc != 2) @@ -773,8 +778,8 @@ rt_inline void _slab_info(rt_size_t *total, */ void rt_system_heap_init_generic(void *begin_addr, void *end_addr) { - rt_uintptr_t begin_align = RT_ALIGN((rt_uintptr_t)begin_addr, RT_ALIGN_SIZE); - rt_uintptr_t end_align = RT_ALIGN_DOWN((rt_uintptr_t)end_addr, RT_ALIGN_SIZE); + rt_ubase_t begin_align = RT_ALIGN((rt_ubase_t)begin_addr, RT_ALIGN_SIZE); + rt_ubase_t end_align = RT_ALIGN_DOWN((rt_ubase_t)end_addr, RT_ALIGN_SIZE); RT_ASSERT(end_align > begin_align); @@ -983,17 +988,17 @@ rt_weak void *rt_malloc_align(rt_size_t size, rt_size_t align) if (ptr != RT_NULL) { /* the allocated memory block is aligned */ - if (((rt_uintptr_t)ptr & (align - 1)) == 0) + if (((rt_ubase_t)ptr & (align - 1)) == 0) { - align_ptr = (void *)((rt_uintptr_t)ptr + align); + align_ptr = (void *)((rt_ubase_t)ptr + align); } else { - align_ptr = (void *)(((rt_uintptr_t)ptr + (align - 1)) & ~(align - 1)); + align_ptr = (void *)(((rt_ubase_t)ptr + (align - 1)) & ~(align - 1)); } /* set the pointer before alignment pointer to the real pointer */ - *((rt_uintptr_t *)((rt_uintptr_t)align_ptr - sizeof(void *))) = (rt_uintptr_t)ptr; + *((rt_ubase_t *)((rt_ubase_t)align_ptr - sizeof(void *))) = (rt_ubase_t)ptr; ptr = align_ptr; } @@ -1014,7 +1019,7 @@ rt_weak void rt_free_align(void *ptr) /* NULL check */ if (ptr == RT_NULL) return; - real_ptr = (void *) * (rt_uintptr_t *)((rt_uintptr_t)ptr - sizeof(void *)); + real_ptr = (void *) * (rt_ubase_t *)((rt_ubase_t)ptr - sizeof(void *)); rt_free(real_ptr); } RTM_EXPORT(rt_free_align); diff --git a/rt-thread/src/mem.c b/rt-thread/src/mem.c index 26cba6d..64bf0fe 100644 --- a/rt-thread/src/mem.c +++ b/rt-thread/src/mem.c @@ -58,7 +58,7 @@ struct rt_small_mem_item { - rt_uintptr_t pool_ptr; /**< small memory object addr */ + rt_ubase_t pool_ptr; /**< small memory object addr */ rt_size_t next; /**< next free item */ rt_size_t prev; /**< prev free item */ #ifdef RT_USING_MEMTRACE @@ -82,19 +82,19 @@ struct rt_small_mem rt_size_t mem_size_aligned; /**< aligned memory size */ }; -#define MIN_SIZE (sizeof(rt_uintptr_t) + sizeof(rt_size_t) + sizeof(rt_size_t)) +#define MIN_SIZE (sizeof(rt_ubase_t) + sizeof(rt_size_t) + sizeof(rt_size_t)) #define MEM_MASK ((~(rt_size_t)0) - 1) -#define MEM_USED(_mem) ((((rt_uintptr_t)(_mem)) & MEM_MASK) | 0x1) -#define MEM_FREED(_mem) ((((rt_uintptr_t)(_mem)) & MEM_MASK) | 0x0) +#define MEM_USED(_mem) ((((rt_base_t)(_mem)) & MEM_MASK) | 0x1) +#define MEM_FREED(_mem) ((((rt_base_t)(_mem)) & MEM_MASK) | 0x0) #define MEM_ISUSED(_mem) \ - (((rt_uintptr_t)(((struct rt_small_mem_item *)(_mem))->pool_ptr)) & (~MEM_MASK)) + (((rt_base_t)(((struct rt_small_mem_item *)(_mem))->pool_ptr)) & (~MEM_MASK)) #define MEM_POOL(_mem) \ - ((struct rt_small_mem *)(((rt_uintptr_t)(((struct rt_small_mem_item *)(_mem))->pool_ptr)) & (MEM_MASK))) + ((struct rt_small_mem *)(((rt_base_t)(((struct rt_small_mem_item *)(_mem))->pool_ptr)) & (MEM_MASK))) #define MEM_SIZE(_heap, _mem) \ - (((struct rt_small_mem_item *)(_mem))->next - ((rt_uintptr_t)(_mem) - \ - (rt_uintptr_t)((_heap)->heap_ptr)) - RT_ALIGN(sizeof(struct rt_small_mem_item), RT_ALIGN_SIZE)) + (((struct rt_small_mem_item *)(_mem))->next - ((rt_ubase_t)(_mem) - \ + (rt_ubase_t)((_heap)->heap_ptr)) - RT_ALIGN(sizeof(struct rt_small_mem_item), RT_ALIGN_SIZE)) #define MIN_SIZE_ALIGNED RT_ALIGN(MIN_SIZE, RT_ALIGN_SIZE) #define SIZEOF_STRUCT_MEM RT_ALIGN(sizeof(struct rt_small_mem_item), RT_ALIGN_SIZE) @@ -173,12 +173,12 @@ rt_smem_t rt_smem_init(const char *name, { struct rt_small_mem_item *mem; struct rt_small_mem *small_mem; - rt_uintptr_t start_addr, begin_align, end_align, mem_size; + rt_ubase_t start_addr, begin_align, end_align, mem_size; - small_mem = (struct rt_small_mem *)RT_ALIGN((rt_uintptr_t)begin_addr, RT_ALIGN_SIZE); - start_addr = (rt_uintptr_t)small_mem + sizeof(*small_mem); - begin_align = RT_ALIGN((rt_uintptr_t)start_addr, RT_ALIGN_SIZE); - end_align = RT_ALIGN_DOWN((rt_uintptr_t)begin_addr + size, RT_ALIGN_SIZE); + small_mem = (struct rt_small_mem *)RT_ALIGN((rt_ubase_t)begin_addr, RT_ALIGN_SIZE); + start_addr = (rt_ubase_t)small_mem + sizeof(*small_mem); + begin_align = RT_ALIGN((rt_ubase_t)start_addr, RT_ALIGN_SIZE); + end_align = RT_ALIGN_DOWN((rt_ubase_t)begin_addr + size, RT_ALIGN_SIZE); /* alignment addr */ if ((end_align > (2 * SIZEOF_STRUCT_MEM)) && @@ -190,7 +190,7 @@ rt_smem_t rt_smem_init(const char *name, else { rt_kprintf("mem init, error begin address 0x%x, and end address 0x%x\n", - (rt_uintptr_t)begin_addr, (rt_uintptr_t)begin_addr + size); + (rt_ubase_t)begin_addr, (rt_ubase_t)begin_addr + size); return RT_NULL; } @@ -207,7 +207,7 @@ rt_smem_t rt_smem_init(const char *name, small_mem->heap_ptr = (rt_uint8_t *)begin_align; LOG_D("mem init, heap begin address 0x%x, size %d", - (rt_uintptr_t)small_mem->heap_ptr, small_mem->mem_size_aligned); + (rt_ubase_t)small_mem->heap_ptr, small_mem->mem_size_aligned); /* initialize the start of the heap */ mem = (struct rt_small_mem_item *)small_mem->heap_ptr; @@ -372,13 +372,13 @@ void *rt_smem_alloc(rt_smem_t m, rt_size_t size) RT_ASSERT(((small_mem->lfree == small_mem->heap_end) || (!MEM_ISUSED(small_mem->lfree)))); } - RT_ASSERT((rt_uintptr_t)mem + SIZEOF_STRUCT_MEM + size <= (rt_uintptr_t)small_mem->heap_end); - RT_ASSERT((rt_uintptr_t)((rt_uint8_t *)mem + SIZEOF_STRUCT_MEM) % RT_ALIGN_SIZE == 0); - RT_ASSERT((((rt_uintptr_t)mem) & (RT_ALIGN_SIZE - 1)) == 0); + RT_ASSERT((rt_ubase_t)mem + SIZEOF_STRUCT_MEM + size <= (rt_ubase_t)small_mem->heap_end); + RT_ASSERT((rt_ubase_t)((rt_uint8_t *)mem + SIZEOF_STRUCT_MEM) % RT_ALIGN_SIZE == 0); + RT_ASSERT((((rt_ubase_t)mem) & (RT_ALIGN_SIZE - 1)) == 0); LOG_D("allocate memory at 0x%x, size: %d", - (rt_uintptr_t)((rt_uint8_t *)mem + SIZEOF_STRUCT_MEM), - (rt_uintptr_t)(mem->next - ((rt_uint8_t *)mem - small_mem->heap_ptr))); + (rt_ubase_t)((rt_uint8_t *)mem + SIZEOF_STRUCT_MEM), + (rt_ubase_t)(mem->next - ((rt_uint8_t *)mem - small_mem->heap_ptr))); /* return the memory data except mem struct */ return (rt_uint8_t *)mem + SIZEOF_STRUCT_MEM; @@ -431,7 +431,7 @@ void *rt_smem_realloc(rt_smem_t m, void *rmem, rt_size_t newsize) if (rmem == RT_NULL) return rt_smem_alloc(&small_mem->parent, newsize); - RT_ASSERT((((rt_uintptr_t)rmem) & (RT_ALIGN_SIZE - 1)) == 0); + RT_ASSERT((((rt_ubase_t)rmem) & (RT_ALIGN_SIZE - 1)) == 0); RT_ASSERT((rt_uint8_t *)rmem >= (rt_uint8_t *)small_mem->heap_ptr); RT_ASSERT((rt_uint8_t *)rmem < (rt_uint8_t *)small_mem->heap_end); @@ -502,7 +502,7 @@ void rt_smem_free(void *rmem) if (rmem == RT_NULL) return; - RT_ASSERT((((rt_uintptr_t)rmem) & (RT_ALIGN_SIZE - 1)) == 0); + RT_ASSERT((((rt_ubase_t)rmem) & (RT_ALIGN_SIZE - 1)) == 0); /* Get the corresponding struct rt_small_mem_item ... */ mem = (struct rt_small_mem_item *)((rt_uint8_t *)rmem - SIZEOF_STRUCT_MEM); @@ -517,8 +517,8 @@ void rt_smem_free(void *rmem) RT_ASSERT(MEM_POOL(&small_mem->heap_ptr[mem->next]) == small_mem); LOG_D("release memory 0x%x, size: %d", - (rt_uintptr_t)rmem, - (rt_uintptr_t)(mem->next - ((rt_uint8_t *)mem - small_mem->heap_ptr))); + (rt_ubase_t)rmem, + (rt_ubase_t)(mem->next - ((rt_uint8_t *)mem - small_mem->heap_ptr))); /* ... and is now unused. */ mem->pool_ptr = MEM_FREED(small_mem); @@ -578,7 +578,7 @@ static int memcheck(int argc, char *argv[]) /* check mem */ for (mem = (struct rt_small_mem_item *)m->heap_ptr; mem != m->heap_end; mem = (struct rt_small_mem_item *)&m->heap_ptr[mem->next]) { - position = (rt_uintptr_t)mem - (rt_uintptr_t)m->heap_ptr; + position = (rt_ubase_t)mem - (rt_ubase_t)m->heap_ptr; if (position < 0) goto __exit; if (position > (int)m->mem_size_aligned) goto __exit; if (MEM_POOL(mem) != m) goto __exit; diff --git a/rt-thread/src/memheap.c b/rt-thread/src/memheap.c index edc1eb2..4b09fea 100644 --- a/rt-thread/src/memheap.c +++ b/rt-thread/src/memheap.c @@ -40,7 +40,7 @@ #define RT_MEMHEAP_MINIALLOC RT_ALIGN(12, RT_ALIGN_SIZE) #define RT_MEMHEAP_SIZE RT_ALIGN(sizeof(struct rt_memheap_item), RT_ALIGN_SIZE) -#define MEMITEM_SIZE(item) ((rt_uintptr_t)item->next - (rt_uintptr_t)item - RT_MEMHEAP_SIZE) +#define MEMITEM_SIZE(item) ((rt_ubase_t)item->next - (rt_ubase_t)item - RT_MEMHEAP_SIZE) #define MEMITEM(ptr) (struct rt_memheap_item*)((rt_uint8_t*)ptr - RT_MEMHEAP_SIZE) static void _remove_next_ptr(volatile struct rt_memheap_item *next_ptr) @@ -899,10 +899,10 @@ static int memheapcheck(int argc, char *argv[]) break; } /* check next and prev */ - if (!((rt_uintptr_t)item->next <= (rt_uintptr_t)((rt_uintptr_t)heap->start_addr + heap->pool_size) && - (rt_uintptr_t)item->prev >= (rt_uintptr_t)heap->start_addr) && - (rt_uintptr_t)item->next == RT_ALIGN((rt_uintptr_t)item->next, RT_ALIGN_SIZE) && - (rt_uintptr_t)item->prev == RT_ALIGN((rt_uintptr_t)item->prev, RT_ALIGN_SIZE)) + if (!((rt_ubase_t)item->next <= (rt_ubase_t)((rt_ubase_t)heap->start_addr + heap->pool_size) && + (rt_ubase_t)item->prev >= (rt_ubase_t)heap->start_addr) && + (rt_ubase_t)item->next == RT_ALIGN((rt_ubase_t)item->next, RT_ALIGN_SIZE) && + (rt_ubase_t)item->prev == RT_ALIGN((rt_ubase_t)item->prev, RT_ALIGN_SIZE)) { has_bad = RT_TRUE; break; diff --git a/rt-thread/src/object.c b/rt-thread/src/object.c index 4e28eeb..0cb1a18 100644 --- a/rt-thread/src/object.c +++ b/rt-thread/src/object.c @@ -429,7 +429,7 @@ void rt_object_detach(rt_object_t object) rt_list_remove(&(object->list)); rt_spin_unlock_irqrestore(&(information->spinlock), level); - object->type = RT_Object_Class_Null; + object->type = 0; } #ifdef RT_USING_HEAP diff --git a/rt-thread/src/scheduler_comm.c b/rt-thread/src/scheduler_comm.c index 957f1a1..6cf8a0c 100644 --- a/rt-thread/src/scheduler_comm.c +++ b/rt-thread/src/scheduler_comm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2024, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -144,7 +144,7 @@ rt_err_t rt_sched_thread_ready(struct rt_thread *thread) return error; } -rt_err_t rt_sched_tick_increase(rt_tick_t tick) +rt_err_t rt_sched_tick_increase(void) { struct rt_thread *thread; rt_sched_lock_level_t slvl; @@ -153,15 +153,7 @@ rt_err_t rt_sched_tick_increase(rt_tick_t tick) rt_sched_lock(&slvl); - if(RT_SCHED_PRIV(thread).remaining_tick > tick) - { - RT_SCHED_PRIV(thread).remaining_tick -= tick; - } - else - { - RT_SCHED_PRIV(thread).remaining_tick = 0; - } - + RT_SCHED_PRIV(thread).remaining_tick--; if (RT_SCHED_PRIV(thread).remaining_tick) { rt_sched_unlock(slvl); @@ -244,13 +236,13 @@ void rt_scheduler_stack_check(struct rt_thread *thread) #ifndef RT_USING_HW_STACK_GUARD #ifdef ARCH_CPU_STACK_GROWS_UPWARD - if (*((rt_uint8_t *)((rt_uintptr_t)thread->stack_addr + thread->stack_size - 1)) != '#' || + if (*((rt_uint8_t *)((rt_ubase_t)thread->stack_addr + thread->stack_size - 1)) != '#' || #else if (*((rt_uint8_t *)thread->stack_addr) != '#' || #endif /* ARCH_CPU_STACK_GROWS_UPWARD */ - (rt_uintptr_t)thread->sp <= (rt_uintptr_t)thread->stack_addr || - (rt_uintptr_t)thread->sp > - (rt_uintptr_t)thread->stack_addr + (rt_uintptr_t)thread->stack_size) + (rt_ubase_t)thread->sp <= (rt_ubase_t)thread->stack_addr || + (rt_ubase_t)thread->sp > + (rt_ubase_t)thread->stack_addr + (rt_ubase_t)thread->stack_size) { rt_base_t dummy = 1; @@ -261,9 +253,9 @@ void rt_scheduler_stack_check(struct rt_thread *thread) #endif /* RT_USING_HW_STACK_GUARD */ #ifdef ARCH_CPU_STACK_GROWS_UPWARD #ifndef RT_USING_HW_STACK_GUARD - else if ((rt_uintptr_t)thread->sp > ((rt_uintptr_t)thread->stack_addr + thread->stack_size)) + else if ((rt_ubase_t)thread->sp > ((rt_ubase_t)thread->stack_addr + thread->stack_size)) #else - if ((rt_uintptr_t)thread->sp > ((rt_uintptr_t)thread->stack_addr + thread->stack_size)) + if ((rt_ubase_t)thread->sp > ((rt_ubase_t)thread->stack_addr + thread->stack_size)) #endif { LOG_W("warning: %s stack is close to the top of stack address.\n", @@ -271,9 +263,9 @@ void rt_scheduler_stack_check(struct rt_thread *thread) } #else #ifndef RT_USING_HW_STACK_GUARD - else if ((rt_uintptr_t)thread->sp <= ((rt_uintptr_t)thread->stack_addr + 32)) + else if ((rt_ubase_t)thread->sp <= ((rt_ubase_t)thread->stack_addr + 32)) #else - if ((rt_uintptr_t)thread->sp <= ((rt_uintptr_t)thread->stack_addr + 32)) + if ((rt_ubase_t)thread->sp <= ((rt_ubase_t)thread->stack_addr + 32)) #endif { LOG_W("warning: %s stack is close to end of stack address.\n", diff --git a/rt-thread/src/scheduler_mp.c b/rt-thread/src/scheduler_mp.c index 6a228e6..7a7bd61 100644 --- a/rt-thread/src/scheduler_mp.c +++ b/rt-thread/src/scheduler_mp.c @@ -1069,6 +1069,9 @@ void rt_sched_post_ctx_switch(struct rt_thread *thread) } /* safe to access since irq is masked out */ pcpu->current_thread = thread; +#ifdef ARCH_USING_HW_THREAD_SELF + rt_hw_thread_set_self(thread); +#endif /* ARCH_USING_HW_THREAD_SELF */ } #ifdef RT_DEBUGING_CRITICAL diff --git a/rt-thread/src/scheduler_up.c b/rt-thread/src/scheduler_up.c index cbd2eea..acc8ee8 100644 --- a/rt-thread/src/scheduler_up.c +++ b/rt-thread/src/scheduler_up.c @@ -46,7 +46,7 @@ rt_uint32_t rt_thread_ready_priority_group; rt_uint8_t rt_thread_ready_table[32]; #endif /* RT_THREAD_PRIORITY_MAX > 32 */ -extern volatile rt_atomic_t rt_interrupt_nest; +extern volatile rt_uint8_t rt_interrupt_nest; static rt_int16_t rt_scheduler_lock_nest; rt_uint8_t rt_current_priority; @@ -181,7 +181,7 @@ void rt_system_scheduler_start(void) /* switch to new thread */ - rt_hw_context_switch_to((rt_uintptr_t)&to_thread->sp); + rt_hw_context_switch_to((rt_ubase_t)&to_thread->sp); /* never come back */ } @@ -275,8 +275,8 @@ void rt_schedule(void) RT_OBJECT_HOOK_CALL(rt_scheduler_switch_hook, (from_thread)); - rt_hw_context_switch((rt_uintptr_t)&from_thread->sp, - (rt_uintptr_t)&to_thread->sp); + rt_hw_context_switch((rt_ubase_t)&from_thread->sp, + (rt_ubase_t)&to_thread->sp); /* enable interrupt */ rt_hw_interrupt_enable(level); @@ -306,8 +306,8 @@ void rt_schedule(void) { LOG_D("switch in interrupt"); - rt_hw_context_switch_interrupt((rt_uintptr_t)&from_thread->sp, - (rt_uintptr_t)&to_thread->sp, from_thread, to_thread); + rt_hw_context_switch_interrupt((rt_ubase_t)&from_thread->sp, + (rt_ubase_t)&to_thread->sp, from_thread, to_thread); } } else diff --git a/rt-thread/src/signal.c b/rt-thread/src/signal.c index b33e242..552d2a8 100644 --- a/rt-thread/src/signal.c +++ b/rt-thread/src/signal.c @@ -30,11 +30,7 @@ #define DBG_LVL DBG_WARNING #include -#ifdef RT_USING_MUSLLIBC - #define sig_mask(sig_no) (1u << (sig_no - 1)) -#else - #define sig_mask(sig_no) (1u << sig_no) -#endif +#define sig_mask(sig_no) (1u << sig_no) #define sig_valid(sig_no) (sig_no >= 0 && sig_no < RT_SIG_MAX) static struct rt_spinlock _thread_signal_lock = RT_SPINLOCK_INIT; @@ -76,9 +72,9 @@ static void _signal_entry(void *parameter) RT_SCHED_CTX(tid).stat &= ~RT_THREAD_STAT_SIGNAL; #ifdef RT_USING_SMP - rt_hw_context_switch_to((rt_uintptr_t)¶meter, tid); + rt_hw_context_switch_to((rt_base_t)¶meter, tid); #else - rt_hw_context_switch_to((rt_uintptr_t)&(tid->sp)); + rt_hw_context_switch_to((rt_ubase_t)&(tid->sp)); #endif /* RT_USING_SMP */ } diff --git a/rt-thread/src/slab.c b/rt-thread/src/slab.c index 456f0ec..18f3048 100644 --- a/rt-thread/src/slab.c +++ b/rt-thread/src/slab.c @@ -136,7 +136,7 @@ #define PAGE_TYPE_LARGE 0x02 #define btokup(addr) \ - (&slab->memusage[((rt_uintptr_t)(addr) - slab->heap_start) >> RT_MM_PAGE_BITS]) + (&slab->memusage[((rt_ubase_t)(addr) - slab->heap_start) >> RT_MM_PAGE_BITS]) /** * Base structure of slab memory object @@ -194,8 +194,8 @@ struct rt_slab_page struct rt_slab { struct rt_memory parent; /**< inherit from rt_memory */ - rt_uintptr_t heap_start; /**< memory start address */ - rt_uintptr_t heap_end; /**< memory end address */ + rt_ubase_t heap_start; /**< memory start address */ + rt_ubase_t heap_end; /**< memory end address */ struct rt_slab_memusage *memusage; struct rt_slab_zone *zone_array[RT_SLAB_NZONES]; /* linked list of zones NFree > 0 */ struct rt_slab_zone *zone_free; /* whole zones that have become free */ @@ -261,7 +261,7 @@ void rt_slab_page_free(rt_slab_t m, void *addr, rt_size_t npages) struct rt_slab *slab = (struct rt_slab *)m; RT_ASSERT(addr != RT_NULL); - RT_ASSERT((rt_uintptr_t)addr % RT_MM_PAGE_SIZE == 0); + RT_ASSERT((rt_ubase_t)addr % RT_MM_PAGE_SIZE == 0); RT_ASSERT(npages != 0); n = (struct rt_slab_page *)addr; @@ -324,18 +324,18 @@ static void rt_slab_page_init(struct rt_slab *slab, void *addr, rt_size_t npages rt_slab_t rt_slab_init(const char *name, void *begin_addr, rt_size_t size) { rt_uint32_t limsize, npages; - rt_uintptr_t start_addr, begin_align, end_align; + rt_ubase_t start_addr, begin_align, end_align; struct rt_slab *slab; - slab = (struct rt_slab *)RT_ALIGN((rt_uintptr_t)begin_addr, RT_ALIGN_SIZE); - start_addr = (rt_uintptr_t)slab + sizeof(*slab); + slab = (struct rt_slab *)RT_ALIGN((rt_ubase_t)begin_addr, RT_ALIGN_SIZE); + start_addr = (rt_ubase_t)slab + sizeof(*slab); /* align begin and end addr to page */ - begin_align = RT_ALIGN((rt_uintptr_t)start_addr, RT_MM_PAGE_SIZE); - end_align = RT_ALIGN_DOWN((rt_uintptr_t)begin_addr + size, RT_MM_PAGE_SIZE); + begin_align = RT_ALIGN((rt_ubase_t)start_addr, RT_MM_PAGE_SIZE); + end_align = RT_ALIGN_DOWN((rt_ubase_t)begin_addr + size, RT_MM_PAGE_SIZE); if (begin_align >= end_align) { rt_kprintf("slab init errr. wrong address[0x%x - 0x%x]\n", - (rt_uintptr_t)begin_addr, (rt_uintptr_t)begin_addr + size); + (rt_ubase_t)begin_addr, (rt_ubase_t)begin_addr + size); return RT_NULL; } @@ -378,7 +378,7 @@ rt_slab_t rt_slab_init(const char *name, void *begin_addr, rt_size_t size) slab->memusage = rt_slab_page_alloc((rt_slab_t)(&slab->parent), limsize / RT_MM_PAGE_SIZE); LOG_D("slab->memusage 0x%x, size 0x%x", - (rt_uintptr_t)slab->memusage, limsize); + (rt_ubase_t)slab->memusage, limsize); return &slab->parent; } RTM_EXPORT(rt_slab_init); @@ -411,7 +411,7 @@ RTM_EXPORT(rt_slab_detach); rt_inline int zoneindex(rt_size_t *bytes) { /* unsigned for shift opt */ - rt_uintptr_t n = (rt_uintptr_t)(*bytes); + rt_ubase_t n = (rt_ubase_t)(*bytes); if (n < 128) { @@ -519,7 +519,7 @@ void *rt_slab_alloc(rt_slab_t m, rt_size_t size) LOG_D("alloc a large memory 0x%x, page cnt %d, kup %d", size, size >> RT_MM_PAGE_BITS, - ((rt_uintptr_t)chunk - slab->heap_start) >> RT_MM_PAGE_BITS); + ((rt_ubase_t)chunk - slab->heap_start) >> RT_MM_PAGE_BITS); /* mem stat */ slab->parent.used += size; if (slab->parent.used > slab->parent.max) @@ -605,7 +605,7 @@ void *rt_slab_alloc(rt_slab_t m, rt_size_t size) } LOG_D("alloc a new zone: 0x%x", - (rt_uintptr_t)z); + (rt_ubase_t)z); /* set message usage */ for (off = 0, kup = btokup(z); off < slab->zone_page_cnt; off ++) @@ -686,7 +686,7 @@ void *rt_slab_realloc(rt_slab_t m, void *ptr, rt_size_t size) * Get the original allocation's zone. If the new request winds up * using the same chunk size we do not have to do anything. */ - kup = btokup((rt_uintptr_t)ptr & ~RT_MM_PAGE_MASK); + kup = btokup((rt_ubase_t)ptr & ~RT_MM_PAGE_MASK); if (kup->type == PAGE_TYPE_LARGE) { rt_size_t osize; @@ -701,7 +701,7 @@ void *rt_slab_realloc(rt_slab_t m, void *ptr, rt_size_t size) } else if (kup->type == PAGE_TYPE_SMALL) { - z = (struct rt_slab_zone *)(((rt_uintptr_t)ptr & ~RT_MM_PAGE_MASK) - + z = (struct rt_slab_zone *)(((rt_ubase_t)ptr & ~RT_MM_PAGE_MASK) - kup->size * RT_MM_PAGE_SIZE); RT_ASSERT(z->z_magic == ZALLOC_SLAB_MAGIC); @@ -749,19 +749,19 @@ void rt_slab_free(rt_slab_t m, void *ptr) /* get memory usage */ #if (DBG_LVL == DBG_LOG) { - rt_uintptr_t addr = ((rt_uintptr_t)ptr & ~RT_MM_PAGE_MASK); + rt_ubase_t addr = ((rt_ubase_t)ptr & ~RT_MM_PAGE_MASK); LOG_D("free a memory 0x%x and align to 0x%x, kup index %d", - (rt_uintptr_t)ptr, - (rt_uintptr_t)addr, - ((rt_uintptr_t)(addr) - slab->heap_start) >> RT_MM_PAGE_BITS); + (rt_ubase_t)ptr, + (rt_ubase_t)addr, + ((rt_ubase_t)(addr) - slab->heap_start) >> RT_MM_PAGE_BITS); } #endif /* DBG_LVL == DBG_LOG */ - kup = btokup((rt_uintptr_t)ptr & ~RT_MM_PAGE_MASK); + kup = btokup((rt_ubase_t)ptr & ~RT_MM_PAGE_MASK); /* release large allocation */ if (kup->type == PAGE_TYPE_LARGE) { - rt_uintptr_t size; + rt_ubase_t size; /* clear page counter */ size = kup->size; @@ -770,7 +770,7 @@ void rt_slab_free(rt_slab_t m, void *ptr) slab->parent.used -= size * RT_MM_PAGE_SIZE; LOG_D("free large memory block 0x%x, page count %d", - (rt_uintptr_t)ptr, size); + (rt_ubase_t)ptr, size); /* free this page */ rt_slab_page_free(m, ptr, size); @@ -779,7 +779,7 @@ void rt_slab_free(rt_slab_t m, void *ptr) } /* zone case. get out zone. */ - z = (struct rt_slab_zone *)(((rt_uintptr_t)ptr & ~RT_MM_PAGE_MASK) - + z = (struct rt_slab_zone *)(((rt_ubase_t)ptr & ~RT_MM_PAGE_MASK) - kup->size * RT_MM_PAGE_SIZE); RT_ASSERT(z->z_magic == ZALLOC_SLAB_MAGIC); @@ -810,8 +810,8 @@ void rt_slab_free(rt_slab_t m, void *ptr) { struct rt_slab_zone **pz; - LOG_D("free zone %#x, zoneindex %d", - (rt_uintptr_t)z, z->z_zoneindex); + LOG_D("free zone 0x%x", + (rt_ubase_t)z, z->z_zoneindex); /* remove zone from zone array list */ for (pz = &slab->zone_array[z->z_zoneindex]; z != *pz; pz = &(*pz)->z_next) diff --git a/rt-thread/src/thread.c b/rt-thread/src/thread.c index 994e04d..1327c47 100644 --- a/rt-thread/src/thread.c +++ b/rt-thread/src/thread.c @@ -76,44 +76,6 @@ void rt_thread_resume_sethook(void (*hook)(rt_thread_t thread)) RT_OBJECT_HOOKLIST_DEFINE(rt_thread_inited); #endif /* defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR) */ -#ifdef RT_USING_MUTEX -static void _thread_detach_from_mutex(rt_thread_t thread) -{ - rt_list_t *node; - rt_list_t *tmp_list; - struct rt_mutex *mutex; - rt_base_t level; - - level = rt_spin_lock_irqsave(&thread->spinlock); - - /* check if thread is waiting on a mutex */ - if ((thread->pending_object) && - (rt_object_get_type(thread->pending_object) == RT_Object_Class_Mutex)) - { - /* remove it from its waiting list */ - struct rt_mutex *mutex = (struct rt_mutex*)thread->pending_object; - rt_mutex_drop_thread(mutex, thread); - thread->pending_object = RT_NULL; - } - - /* free taken mutex after detaching from waiting, so we don't lost mutex just got */ - rt_list_for_each_safe(node, tmp_list, &(thread->taken_object_list)) - { - mutex = rt_list_entry(node, struct rt_mutex, taken_list); - LOG_D("Thread [%s] exits while holding mutex [%s].\n", thread->parent.name, mutex->parent.parent.name); - /* recursively take */ - mutex->hold = 1; - rt_mutex_release(mutex); - } - - rt_spin_unlock_irqrestore(&thread->spinlock, level); -} - -#else - -static void _thread_detach_from_mutex(rt_thread_t thread) {} -#endif - static void _thread_exit(void) { struct rt_thread *thread; @@ -126,8 +88,6 @@ static void _thread_exit(void) rt_thread_close(thread); - _thread_detach_from_mutex(thread); - /* insert to defunct thread list */ rt_thread_defunct_enqueue(thread); @@ -173,6 +133,41 @@ static void _thread_timeout(void *parameter) rt_sched_unlock_n_resched(slvl); } +#ifdef RT_USING_MUTEX +static void _thread_detach_from_mutex(rt_thread_t thread) +{ + rt_list_t *node; + rt_list_t *tmp_list; + struct rt_mutex *mutex; + rt_base_t level; + + level = rt_spin_lock_irqsave(&thread->spinlock); + + /* check if thread is waiting on a mutex */ + if ((thread->pending_object) && + (rt_object_get_type(thread->pending_object) == RT_Object_Class_Mutex)) + { + /* remove it from its waiting list */ + struct rt_mutex *mutex = (struct rt_mutex*)thread->pending_object; + rt_mutex_drop_thread(mutex, thread); + thread->pending_object = RT_NULL; + } + + /* free taken mutex after detaching from waiting, so we don't lost mutex just got */ + rt_list_for_each_safe(node, tmp_list, &(thread->taken_object_list)) + { + mutex = rt_list_entry(node, struct rt_mutex, taken_list); + rt_mutex_release(mutex); + } + + rt_spin_unlock_irqrestore(&thread->spinlock, level); +} + +#else + +static void _thread_detach_from_mutex(rt_thread_t thread) {} +#endif + static rt_err_t _thread_init(struct rt_thread *thread, const char *name, void (*entry)(void *parameter), @@ -339,9 +334,6 @@ rt_err_t rt_thread_init(struct rt_thread *thread, RT_ASSERT(stack_start != RT_NULL); RT_ASSERT(tick != 0); - /* clean memory data of thread */ - rt_memset(thread, 0x0, sizeof(struct rt_thread)); - /* initialize thread object */ rt_object_init((rt_object_t)thread, RT_Object_Class_Thread, name); @@ -829,7 +821,7 @@ rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg) { rt_uint8_t cpu; - cpu = (rt_uint8_t)(rt_size_t)arg; + cpu = (rt_uint8_t)(size_t)arg; return rt_sched_thread_bind_cpu(thread, cpu); } diff --git a/rt-thread/tools/building.py b/rt-thread/tools/building.py index c64c393..480197d 100644 --- a/rt-thread/tools/building.py +++ b/rt-thread/tools/building.py @@ -23,7 +23,6 @@ # 2015-07-25 Bernard Add LOCAL_CCFLAGS/LOCAL_CPPPATH/LOCAL_CPPDEFINES for # group definition. # 2024-04-21 Bernard Add toolchain detection in sdk packages -# 2025-01-05 Bernard Add logging as Env['log'] import os import sys @@ -32,7 +31,6 @@ import utils import operator import rtconfig import platform -import logging from SCons.Script import * from utils import _make_path_relative @@ -132,14 +130,6 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [ AddOptions() Env = env - - # prepare logging and set log - logging.basicConfig(level=logging.INFO, format="%(message)s") - logger = logging.getLogger('rt-scons') - if GetOption('verbose'): - logger.setLevel(logging.DEBUG) - Env['log'] = logger - Rtt_Root = os.path.abspath(root_directory) # make an absolute root directory @@ -152,6 +142,17 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [ # set BSP_ROOT in ENV Env['BSP_ROOT'] = Dir('#').abspath os.environ["BSP_DIR"] = Dir('#').abspath + # set PKGS_ROOT in ENV + if "PKGS_DIR" in os.environ: + pass + elif "PKGS_ROOT" in os.environ: + os.environ["PKGS_DIR"] = os.environ["PKGS_ROOT"] + elif "ENV_ROOT" in os.environ: + os.environ["PKGS_DIR"] = os.path.join(os.environ["ENV_ROOT"], "packages") + elif sys.platform == "win32": + os.environ["PKGS_DIR"] = os.path.join(os.environ["USERPROFILE"], ".env", "packages") + else: + os.environ["PKGS_DIR"] = os.path.join(os.environ["HOME"], ".env", "packages") sys.path += os.path.join(Rtt_Root, 'tools') @@ -173,8 +174,7 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [ 'cmake-armclang':('keil', 'armclang'), 'xmake':('gcc', 'gcc'), 'codelite' : ('gcc', 'gcc'), - 'esp-idf': ('gcc', 'gcc'), - 'zig':('gcc', 'gcc')} + 'esp-idf': ('gcc', 'gcc')} tgt_name = GetOption('target') if tgt_name: @@ -199,30 +199,24 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [ # auto change the 'RTT_EXEC_PATH' when 'rtconfig.EXEC_PATH' get failed if not utils.CmdExists(os.path.join(rtconfig.EXEC_PATH, rtconfig.CC)): - Env['log'].debug('To detect CC because CC path in rtconfig.py is invalid:') - Env['log'].debug(' rtconfig.py cc ->' + os.path.join(rtconfig.EXEC_PATH, rtconfig.CC)) if 'RTT_EXEC_PATH' in os.environ: # del the 'RTT_EXEC_PATH' and using the 'EXEC_PATH' setting on rtconfig.py del os.environ['RTT_EXEC_PATH'] try: # try to detect toolchains in env - envm = utils.ImportModule('env_utility') + envm = utils.ImportModule('env') # from env import GetSDKPath exec_path = envm.GetSDKPath(rtconfig.CC) - if exec_path != None: - if 'gcc' in rtconfig.CC: - exec_path = os.path.join(exec_path, 'bin') + if 'gcc' in rtconfig.CC: + exec_path = os.path.join(exec_path, 'bin') - if os.path.exists(exec_path): - Env['log'].debug('set CC to ' + exec_path) - rtconfig.EXEC_PATH = exec_path - os.environ['RTT_EXEC_PATH'] = exec_path - else: - Env['log'].debug('No Toolchain found in path(%s).' % exec_path) + if os.path.exists(exec_path): + print('set CC to ' + exec_path) + rtconfig.EXEC_PATH = exec_path + os.environ['RTT_EXEC_PATH'] = exec_path except Exception as e: # detect failed, ignore - Env['log'].debug(e) pass exec_path = GetOption('exec-path') @@ -337,7 +331,7 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [ print('--global-macros arguments are illegal!') if GetOption('genconfig'): - from env_utility import genconfig + from menukconfig import genconfig genconfig() exit(0) @@ -347,23 +341,23 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [ exit(0) if GetOption('menuconfig'): - from env_utility import menuconfig + from menukconfig import menuconfig menuconfig(Rtt_Root) exit(0) - if GetOption('defconfig'): - from env_utility import defconfig - defconfig(Rtt_Root) + if GetOption('pyconfig-silent'): + from menukconfig import guiconfig_silent + guiconfig_silent(Rtt_Root) exit(0) - elif GetOption('guiconfig'): - from env_utility import guiconfig + elif GetOption('pyconfig'): + from menukconfig import guiconfig guiconfig(Rtt_Root) exit(0) configfn = GetOption('useconfig') if configfn: - from env_utility import mk_rtconfig + from menukconfig import mk_rtconfig mk_rtconfig(configfn) exit(0) @@ -839,11 +833,6 @@ def DoBuilding(target, objects): break else: - # generate build/compile_commands.json - if GetOption('cdb') and utils.VerTuple(SCons.__version__) >= (4, 0, 0): - Env.Tool("compilation_db") - Env.CompilationDatabase('build/compile_commands.json') - # remove source files with local flags setting for group in Projects: if 'LOCAL_CFLAGS' in group or 'LOCAL_CXXFLAGS' in group or 'LOCAL_CCFLAGS' in group or 'LOCAL_CPPPATH' in group or 'LOCAL_CPPDEFINES' in group: @@ -864,6 +853,11 @@ def DoBuilding(target, objects): objects = sorted(objects) objects.append(objects_in_group) + # generate build/compile_commands.json + if GetOption('cdb') and utils.VerTuple(SCons.__version__) >= (4, 0, 0): + Env.Tool("compilation_db") + Env.CompilationDatabase('build/compile_commands.json') + program = Env.Program(target, objects) EndBuilding(target, program) @@ -949,10 +943,6 @@ def GenTargetProject(program = None): from esp_idf import ESPIDFProject ESPIDFProject(Env, Projects) - if GetOption('target') == 'zig': - from zigbuild import ZigBuildProject - ZigBuildProject(Env, Projects) - def EndBuilding(target, program = None): from mkdist import MkDist diff --git a/rt-thread/tools/ci/bsp_buildings.py b/rt-thread/tools/ci/bsp_buildings.py index f170dbe..ab731c5 100644 --- a/rt-thread/tools/ci/bsp_buildings.py +++ b/rt-thread/tools/ci/bsp_buildings.py @@ -2,7 +2,7 @@ import os import shutil import re import multiprocessing -import yaml + def add_summary(text): """ @@ -68,7 +68,7 @@ def build_bsp(bsp, scons_args=''): nproc = multiprocessing.cpu_count() os.chdir(rtt_root) cmd = f'scons -C bsp/{bsp} -j{nproc} {scons_args}' - __, res = run_cmd(cmd, output_info=True) + __, res = run_cmd(cmd, output_info=False) if res != 0: success = False @@ -91,6 +91,7 @@ def append_file(source_file, destination_file): for line in source: destination.write(line) + def check_scons_args(file_path): args = [] with open(file_path, 'r') as file: @@ -100,26 +101,6 @@ def check_scons_args(file_path): args.append(match.group(1).strip()) return ' '.join(args) -def get_details_and_dependencies(details, projects, seen=None): - if seen is None: - seen = set() - detail_list = [] - if details is not None: - for dep in details: - if dep not in seen: - dep_details=projects.get(dep) - seen.add(dep) - if dep_details is not None: - if dep_details.get('depends') is not None: - detail_temp=get_details_and_dependencies(dep_details.get('depends'), projects, seen) - for line in detail_temp: - detail_list.append(line) - if dep_details.get('kconfig') is not None: - for line in dep_details.get('kconfig'): - detail_list.append(line) - else: - print(f"::error::There are some problems with attachconfig depend: {dep}"); - return detail_list def build_bsp_attachconfig(bsp, attach_file): """ @@ -179,67 +160,13 @@ if __name__ == "__main__": add_summary(f'- ✅ build {bsp} success.') print("::endgroup::") - yml_files_content = [] - directory = os.path.join(rtt_root, 'bsp', bsp, '.ci/attachconfig') - if os.path.exists(directory): - for root, dirs, files in os.walk(directory): - for filename in files: - if filename.endswith('attachconfig.yml'): - file_path = os.path.join(root, filename) - if os.path.exists(file_path): - try: - with open(file_path, 'r') as file: - content = yaml.safe_load(file) - if content is None: - continue - yml_files_content.append(content) - except yaml.YAMLError as e: - print(f"::error::Error parsing YAML file: {e}") - continue - except Exception as e: - print(f"::error::Error reading file: {e}") - continue - - config_file = os.path.join(rtt_root, 'bsp', bsp, '.config') - - for projects in yml_files_content: - for name, details in projects.items(): - count += 1 - config_bacakup = config_file+'.origin' - shutil.copyfile(config_file, config_bacakup) - with open(config_file, 'a') as destination: - if details.get("kconfig") is None: - continue - if(projects.get(name) is not None): - detail_list=get_details_and_dependencies([name],projects) - for line in detail_list: - destination.write(line + '\n') - scons_arg=[] - if details.get('scons_arg') is not None: - for line in details.get('scons_arg'): - scons_arg.append(line) - scons_arg_str=' '.join(scons_arg) if scons_arg else ' ' - print(f"::group::\tCompiling yml project: =={count}==={name}=scons_arg={scons_arg_str}==") - res = build_bsp(bsp, scons_arg_str) - if not res: - print(f"::error::build {bsp} {name} failed.") - add_summary(f'\t- ❌ build {bsp} {name} failed.') - failed += 1 - else: - add_summary(f'\t- ✅ build {bsp} {name} success.') - print("::endgroup::") - - shutil.copyfile(config_bacakup, config_file) - os.remove(config_bacakup) - attach_dir = os.path.join(rtt_root, 'bsp', bsp, '.ci/attachconfig') attach_list = [] for root, dirs, files in os.walk(attach_dir): for file in files: - if file.endswith('attach'): - file_path = os.path.join(root, file) - relative_path = os.path.relpath(file_path, attach_dir) - attach_list.append(relative_path) + file_path = os.path.join(root, file) + relative_path = os.path.relpath(file_path, attach_dir) + attach_list.append(relative_path) for attach_file in attach_list: count += 1 diff --git a/rt-thread/tools/ci/bsp_detail.py b/rt-thread/tools/ci/bsp_detail.py deleted file mode 100644 index 7e68e16..0000000 --- a/rt-thread/tools/ci/bsp_detail.py +++ /dev/null @@ -1,206 +0,0 @@ -# -# Copyright (c) 2024, RT-Thread Development Team -# -# SPDX-License-Identifier: Apache-2.0 -# -# Change Logs: -# Date Author Notes -# 2024-08-24 supperthomas the first version -# - -# 这个文件会根据bsp中的信息生成对应的bsp_detail.yml文件,这个文件会包含bsp中的一些信息,比如是否有Kconfig文件,是否有template.uvprojx文件等等 -# 根据生成的bsp_detail.yml文件,会生成一个toolchain_bsp.yml文件,这个文件会包含所有的gcc编译器的信息,以及对应的bsp文件夹 - -import os -import pandas as pd -import yaml -from datetime import datetime -import subprocess -#pip install pandas -#pip install tabulate -#pip install pyyaml - -# 添加每个工具链的下载地址 -download_urls = { - 'arm-none-eabi-gcc': 'https://github.com/RT-Thread/toolchains-ci/releases/download/v1.3/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2', - 'mips-sde-elf-gcc': 'https://github.com/RT-Thread/toolchains-ci/releases/download/v1.6/gcc-arm-10.2-2020.11-x86_64-aarch64-none-elf.tar.xz', - 'riscv64-unknown-elf-gcc': 'https://github.com/RT-Thread/toolchains-ci/releases/download/v1.4/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz', - 'riscv32-unknown-elf-gcc': 'https://github.com/hpmicro/riscv-gnu-toolchain/releases/download/2022.05.15/riscv32-unknown-elf-newlib-multilib_2022.05.15_linux.tar.gz', - 'llvm-arm': 'https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-16.0.0/LLVMEmbeddedToolchainForArm-16.0.0-Linux-x86_64.tar.gz', - 'riscv-none-embed-gcc': 'https://github.com/RT-Thread/toolchains-ci/releases/download/v1.5/xpack-riscv-none-embed-gcc-8.3.0-2.3-linux-x64.tar.gz', - 'riscv32-esp-elf-gcc': 'https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1-RC1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-RC1-linux-amd64.tar.xz', - 'clang': 'https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-16.0.0/LLVMEmbeddedToolchainForArm-16.0.0-Linux-x86_64.tar.gz', - # 添加其他工具链的下载地址 -} -# 产生toolchain.yml文件 -def generate_toolchain_yaml(input_file, output_file, header_comment): - with open(input_file, 'r', encoding='utf-8') as file: - data = yaml.safe_load(file) - - toolchain_data = {} - for folder, details in data.items(): - gcc = details.get('gcc') - if gcc: - if gcc not in toolchain_data: - toolchain_data[gcc] = {'bsp': []} - toolchain_data[gcc]['bsp'].append(folder) - - - # 添加每个工具链的个数 - for gcc, details in toolchain_data.items(): - details['count'] = len(details['bsp']) - download_url = download_urls.get(gcc) - if download_url: - details['download_url'] = download_url - - with open(output_file, 'w', encoding='utf-8') as file: - file.write(f"# {header_comment}\n") - yaml.dump(toolchain_data, file, default_flow_style=False, allow_unicode=True) - - -# 这个函数通过检查文件是否存在来检查bsp的支持情况 -def check_files(root_dir, file_list): - data = [] - folders_checked = set() - - for projects in sconstruct_paths: - found_arch = False # Flag to track if ARCH has been found - found_cpu = False # Flag to track if ARCH has been found - if projects not in folders_checked: - #file_dict = {file: True if os.path.isfile(os.path.join(projects, file)) else '' for file in file_list} - file_dict = {} - for file in file_list: - file_exists = os.path.isfile(os.path.join(projects, file)) - if file == 'template.uvprojx': - file_dict['mdk5'] = True if file_exists else False - elif file == 'template.ewp': - file_dict['iar'] = True if file_exists else False - elif file == 'template.uvproj': - file_dict['mdk4'] = True if file_exists else False - elif file == 'template.Uv2': - file_dict['mdk3'] = True if file_exists else False - elif file == 'Kconfig': - file_dict['menuconfig'] = True if file_exists else False - else: - file_dict[file] = True if file_exists else False - - # 提取 rtconfig.py 中的 PREFIX 信息 - rtconfig_path = os.path.join(projects, 'rtconfig.py') - if os.path.isfile(rtconfig_path): - print(f"Reading {rtconfig_path}") - with open(rtconfig_path, 'r') as f: - for line in f: - if not found_arch and line.strip().startswith('ARCH'): - arch_value = line.split('=')[1].strip().strip("'\"") - file_dict['arch'] = f"{arch_value}" - print(f"Found ARCH: {arch_value} in {rtconfig_path}") - found_arch = True # Set the flag to True - - # 解析CPU属性 - if not found_cpu and line.strip().startswith('CPU'): - cpu_value = line.split('=')[1].strip().strip("'\"") - file_dict['cpu'] = f"{cpu_value}" - print(f"Found CPU: {cpu_value} in {rtconfig_path}") - found_cpu = True - - if line.strip().startswith('PREFIX'): - prefix_value = line.split('=')[1].strip().strip("'\"") - # 只提取实际的编译器前缀 - if 'os.getenv' in prefix_value: - prefix_value = prefix_value.split('or')[-1].strip().strip("'\"") - file_dict['gcc'] = f"{prefix_value}gcc" - print(f"Found PREFIX: {prefix_value} in {rtconfig_path}") - break - else: - print(f"No PREFIX found in {rtconfig_path}") - - # 去掉路径中的 '/workspaces/rt-thread/bsp/' 部分 - projects2 = projects.replace(root_dir + '/', '') - file_dict['Folder'] = projects2 - data.append(file_dict) - #data.append({'Folder': projects2, **file_dict}) - folders_checked.add(projects) - df = pd.DataFrame(data) - return df - -def find_sconstruct_paths(project_dir, exclude_paths): - sconstruct_paths = [] - for root, dirs, files in os.walk(project_dir): - - if all(exclude_path not in root for exclude_path in exclude_paths): - - if 'SConstruct' in files: - sconstruct_paths.append(root) - return sconstruct_paths - -def output_to_markdown(df, output_file): - with open(output_file, 'w', encoding='utf-8') as file: - file.write(df.to_markdown(index=False)) - -def output_to_yaml(dataframe, output_file, header_comment): - data = dataframe.to_dict(orient='records') - yaml_data = {} - for item in data: - folder = item.pop('Folder') - filtered_item = {k: v for k, v in item.items() if v is True or isinstance(v, str)} - yaml_data[folder] = filtered_item - with open(output_file, 'w', encoding='utf-8') as file: - file.write(f"# {header_comment}\n") - yaml.dump(yaml_data, file, default_flow_style=False, allow_unicode=True) - -# Find the rt-thread root directory -rtt_root = os.getcwd() -while not os.path.exists(os.path.join(rtt_root, 'LICENSE')): - rtt_root = os.path.dirname(rtt_root) -bsp_root = os.path.join(rtt_root, 'bsp') - -exclude_paths = ['templates', 'doc'] -files_to_check = ['README.md','rtconfig.h', '.config','Kconfig', 'template.uvprojx','template.ewp', 'README.md', 'README_ZH.md', 'template.Uv2','template.uvproj'] -sconstruct_paths = find_sconstruct_paths(bsp_root, exclude_paths) -result_table = check_files(bsp_root, files_to_check) -print(result_table) -output_file = 'output.md' - -output_to_markdown(result_table, output_file) - -# 将 output.yml 和 toolchain.yml 文件保存到 bsp 目录下 - -# 获取今天的日期 -today_date = datetime.today().strftime('%Y-%m-%d') - -# 获取当前年份 -current_year = datetime.today().year - -def get_git_user_name(): - try: - result = subprocess.run(['git', 'config', 'user.name'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - if result.returncode == 0: - return result.stdout.strip() - else: - return "Unknown Author" - except Exception as e: - return "Unknown Author" - -# 获取 Git 用户名 -author_name = get_git_user_name() - -# 头部注释 -header_comment = f""" -# Copyright (c) {current_year}, RT-Thread Development Team -# -# SPDX-License-Identifier: Apache-2.0 -# -# Change Logs: -# Date Author Notes -# {today_date} {author_name} the first version -# -""" -# 将 output.yml 和 toolchain.yml 文件保存到 tools/ci 目录下 -ci_dir = os.path.join(rtt_root, 'tools', 'ci') -os.makedirs(ci_dir, exist_ok=True) - -bsp_detail_file = os.path.join(ci_dir, 'bsp_detail.yml') -output_to_yaml(result_table, bsp_detail_file, header_comment) - -toolchain_output_file = os.path.join(ci_dir, 'toolchain_bsp.yml') -generate_toolchain_yaml(bsp_detail_file, toolchain_output_file, header_comment) \ No newline at end of file diff --git a/rt-thread/tools/ci/bsp_detail.yml b/rt-thread/tools/ci/bsp_detail.yml deleted file mode 100644 index 17aff17..0000000 --- a/rt-thread/tools/ci/bsp_detail.yml +++ /dev/null @@ -1,2606 +0,0 @@ -# -# Copyright (c) 2024, RT-Thread Development Team -# -# SPDX-License-Identifier: Apache-2.0 -# -# Change Logs: -# Date Author Notes -# 2024-08-25 supperthomas the first version -# - -CME_M7: - .config: true - gcc: arm-none-eabi-gcc - mdk4: true - menuconfig: true - rtconfig.h: true -ESP32_C3: - .config: true - README.md: true - README_ZH.md: true - gcc: riscv32-esp-elf-gcc - menuconfig: true - rtconfig.h: true -Infineon/psoc6-cy8ckit-062-BLE: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -Infineon/psoc6-cy8ckit-062-WIFI-BT: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -Infineon/psoc6-cy8ckit-062S2-43012: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -Infineon/psoc6-cy8ckit-062s4: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -Infineon/psoc6-cy8cproto-062S3-4343W: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -Infineon/psoc6-evaluationkit-062S2: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -Infineon/xmc7200-kit_xmc7200_evk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -Vango/v85xx: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -Vango/v85xxp: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -acm32/acm32f0x0-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -acm32/acm32f4xx-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -airm2m/air105: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -airm2m/air32f103: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -allwinner/d1: - .config: true - README.md: true - gcc: riscv64-unknown-linux-musl-gcc - menuconfig: true - rtconfig.h: true -allwinner/d1s: - .config: true - README.md: true - gcc: riscv64-unknown-linux-musl-gcc - menuconfig: true - rtconfig.h: true -allwinner_tina: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -amebaz: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - menuconfig: true - rtconfig.h: true -apm32/apm32e103ze-evalboard: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -apm32/apm32e103ze-tinyboard: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -apm32/apm32f030r8-miniboard: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -apm32/apm32f051r8-evalboard: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -apm32/apm32f072vb-miniboard: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -apm32/apm32f091vc-miniboard: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -apm32/apm32f103vb-miniboard: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -apm32/apm32f103xe-minibroard: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -apm32/apm32f107vc-evalboard: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -apm32/apm32f407ig-minibroard: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -apm32/apm32f407zg-evalboard: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -apm32/apm32s103vb-miniboard: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -apollo2: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -asm9260t: - .config: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - menuconfig: true - rtconfig.h: true -at32/at32a403a-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at32/at32a423-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at32/at32f402-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at32/at32f403a-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at32/at32f405-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at32/at32f407-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at32/at32f413-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at32/at32f415-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at32/at32f421-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at32/at32f423-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at32/at32f425-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at32/at32f435-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at32/at32f437-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -at91/at91sam9260: - .config: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - menuconfig: true - rtconfig.h: true -at91/at91sam9g45: - .config: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - menuconfig: true - rtconfig.h: true -avr32/at32uc3a0256: - .config: true - README.md: true - gcc: avr32-gcc - menuconfig: true - rtconfig.h: true -avr32/at32uc3b0256: - .config: true - README.md: true - gcc: avr32-gcc - menuconfig: true - rtconfig.h: true -beaglebone: - .config: true - gcc: arm-none-eabi-gcc - iar: true - menuconfig: true - rtconfig.h: true -bluetrum/ab32vg1-ab-prougen: - .config: true - README.md: true - gcc: riscv64-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -bm3803: - .config: true - README.md: true - gcc: sparc-gaisler-elf-gcc - menuconfig: true - rtconfig.h: true -bouffalo_lab/bl60x: - .config: true - gcc: riscv64-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -bouffalo_lab/bl61x: - .config: true - gcc: riscv64-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -bouffalo_lab/bl70x: - .config: true - gcc: riscv64-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -bouffalo_lab/bl808/d0: - .config: true - gcc: riscv64-unknown-linux-musl-gcc - menuconfig: true - rtconfig.h: true -bouffalo_lab/bl808/lp: - .config: true - gcc: riscv64-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -bouffalo_lab/bl808/m0: - .config: true - gcc: riscv64-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -ck802: - .config: true - README.md: true - gcc: csky-abiv2-elf-gcc - menuconfig: true - rtconfig.h: true -core-v-mcu/core-v-cv32e40p: - .config: true - gcc: riscv32-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -cvitek/c906_little: - .config: true - gcc: riscv64-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -cvitek/cv18xx_aarch64: - .config: true - README.md: true - gcc: aarch64-none-elf-gcc - menuconfig: true - rtconfig.h: true -cvitek/cv18xx_risc-v: - .config: true - gcc: riscv64-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -dm365: - .config: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -efm32: - gcc: arm-none-eabi-gcc - rtconfig.h: true -essemi/es32f0654: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -essemi/es32f365x: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -essemi/es32f369x: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -essemi/es32vf2264: - .config: true - README.md: true - gcc: csky-abiv2-elf-gcc - menuconfig: true - rtconfig.h: true -fm33lc026: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -frdm-k64f: - .config: true - gcc: arm-none-eabi-gcc - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -ft2004: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -ft32/ft32f072xb-starter: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -fujitsu/mb9x/mb9bf500r: - .config: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -fujitsu/mb9x/mb9bf506r: - .config: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - menuconfig: true - rtconfig.h: true -fujitsu/mb9x/mb9bf568r: - .config: true - gcc: arm-none-eabi-gcc - mdk4: true - menuconfig: true - rtconfig.h: true -fujitsu/mb9x/mb9bf618s: - .config: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32103c-eval: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32105c-eval: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32105r-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32107c-eval: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32205r-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32207i-eval: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32303c-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32303e-eval: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32305r-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32307e-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32407v-lckfb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32407v-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32450z-eval: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32470z-lckfb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/arm/gd32h759i-start: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -gd32/risc-v/gd32vf103r-start: - .config: true - README.md: true - gcc: riscv-none-embed-gcc - menuconfig: true - rtconfig.h: true -gd32/risc-v/gd32vf103v-eval: - .config: true - README.md: true - gcc: riscv-none-embed-gcc - menuconfig: true - rtconfig.h: true -hc32/ev_hc32f448_lqfp80: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -hc32/ev_hc32f460_lqfp100_v2: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -hc32/ev_hc32f472_lqfp100: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -hc32/ev_hc32f4a0_lqfp176: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -hc32/lckfb-hc32f4a0-lqfp100: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -hc32l136: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -hc32l196: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -hifive1: - .config: true - README.md: true - gcc: riscv-none-embed-gcc - menuconfig: true - rtconfig.h: true -hk32/hk32f030c8-mini: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -hpmicro/hpm5300evk: - .config: true - README.md: true - gcc: riscv32-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -hpmicro/hpm5301evklite: - .config: true - README.md: true - gcc: riscv32-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -hpmicro/hpm6200evk: - .config: true - README.md: true - gcc: riscv32-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -hpmicro/hpm6300evk: - .config: true - README.md: true - gcc: riscv32-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -hpmicro/hpm6750evk: - .config: true - README.md: true - gcc: riscv32-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -hpmicro/hpm6750evk2: - .config: true - README.md: true - gcc: riscv32-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -hpmicro/hpm6750evkmini: - .config: true - README.md: true - gcc: riscv32-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -hpmicro/hpm6800evk: - .config: true - README.md: true - gcc: riscv32-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -ht32/ht32f12366: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -ht32/ht32f52352: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -juicevm: - .config: true - README.md: true - gcc: riscv-none-embed-gcc - menuconfig: true - rtconfig.h: true -k210: - .config: true - README.md: true - gcc: riscv-none-embed-gcc - menuconfig: true - rtconfig.h: true -lm3s8962: - .config: true - gcc: arm-none-eabi-gcc - mdk3: true - menuconfig: true - rtconfig.h: true -lm3s9b9x: - .config: true - gcc: arm-none-eabi-gcc - mdk3: true - menuconfig: true - rtconfig.h: true -lm4f232: - .config: true - gcc: arm-none-eabi-gcc - mdk4: true - menuconfig: true - rtconfig.h: true -loongson/ls1bdev: - .config: true - gcc: mips-sde-elf-gcc - menuconfig: true - rtconfig.h: true -loongson/ls1cdev: - .config: true - README.md: true - gcc: mips-sde-elf-gcc - menuconfig: true - rtconfig.h: true -loongson/ls2kdev: - .config: true - README.md: true - gcc: mips-sde-elf-gcc - menuconfig: true - rtconfig.h: true -m16c62p: - gcc: m32c-elf-gcc - iar: true - rtconfig.h: true -maxim/max32660-evsys: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -microchip/samc21: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -microchip/samd51-adafruit-metro-m4: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -microchip/samd51-seeed-wio-terminal: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -microchip/same54: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -microchip/same70: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -microchip/saml10: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -mini2440: - .config: true - gcc: arm-none-eabi-gcc - mdk3: true - mdk4: true - menuconfig: true - rtconfig.h: true -mini4020: - gcc: arm-none-eabi-gcc - mdk3: true - rtconfig.h: true -mipssim: - .config: true - README.md: true - gcc: mips-sde-elf-gcc - menuconfig: true - rtconfig.h: true -mm32/mm32f3270-100ask-pitaya: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -mm32f103x: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -mm32f327x: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -mm32l07x: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -mm32l3xx: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -msp432e401y-LaunchPad: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32/n32g43xcl-stb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32/n32g457qel-stb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32/n32g45xcl-stb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32/n32g45xml-stb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32/n32g45xrl-stb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32/n32g45xvl-stb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32/n32g4frml-stb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32/n32l40xcl-stb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32/n32l436-evb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32/n32l43xml-stb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32/n32l43xrl-stb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32/n32wb45xl-evb: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -n32g452xx/n32g452xx-mini-system: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nrf5x/nrf51822: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nrf5x/nrf52832: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nrf5x/nrf52833: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nrf5x/nrf52840: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nrf5x/nrf5340: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nuclei/gd32vf103_rvstar: - .config: true - README.md: true - gcc: riscv-nuclei-elf-gcc - menuconfig: true - rtconfig.h: true -nuclei/nuclei_fpga_eval: - .config: true - README.md: true - gcc: riscv-nuclei-elf-gcc - menuconfig: true - rtconfig.h: true -nuvoton/ma35-rtp: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true -nuvoton/nk-980iot: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk4: true - menuconfig: true -nuvoton/nk-n9h30: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk4: true - menuconfig: true -nuvoton/nk-rtu980: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk4: true - menuconfig: true -nuvoton/numaker-hmi-ma35d1: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true -nuvoton/numaker-iot-m467: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true -nuvoton/numaker-iot-m487: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true -nuvoton/numaker-iot-ma35d1: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true -nuvoton/numaker-m032ki: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true -nuvoton/numaker-m2354: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true -nuvoton/numaker-m467hj: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true -nuvoton/numaker-pfm-m487: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true -nv32f100x: - gcc: arm-none-eabi-gcc - mdk5: true - rtconfig.h: true -nxp/imx/imx6sx/cortex-a9: - .config: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -nxp/imx/imx6ul: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -nxp/imx/imx6ull-smart: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -nxp/imx/imxrt/imxrt1021-nxp-evk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/imx/imxrt/imxrt1052-atk-commander: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/imx/imxrt/imxrt1052-fire-pro: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/imx/imxrt/imxrt1052-nxp-evk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/imx/imxrt/imxrt1052-seeed-ArchMix: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/imx/imxrt/imxrt1060-nxp-evk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/imx/imxrt/imxrt1061-forlinx-OK1061-S: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/imx/imxrt/imxrt1064-nxp-evk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/imx/imxrt/imxrt1170-nxp-evk/m7: - .config: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc1114: - .config: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc176x: - .config: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc178x: - .config: true - gcc: arm-none-eabi-gcc - mdk4: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc2148: - .config: true - gcc: arm-none-eabi-gcc - mdk3: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc2478: - .config: true - gcc: arm-none-eabi-gcc - mdk4: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc408x: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc43xx/M0: - gcc: arm-none-eabi-gcc - mdk4: true - rtconfig.h: true -nxp/lpc/lpc43xx/M4: - gcc: arm-none-eabi-gcc - mdk4: true - rtconfig.h: true -nxp/lpc/lpc5410x: - .config: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc54114-lite: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc54608-LPCXpresso: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc55sxx/Libraries/template/lpc55s6xxxx: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc55sxx/lpc55s06_nxp_evk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc55sxx/lpc55s16_nxp_evk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc55sxx/lpc55s28_nxp_evk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc55sxx/lpc55s36_nxp_evk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc55sxx/lpc55s69_nxp_evk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/lpc/lpc824: - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - rtconfig.h: true -nxp/mcx/mcxa/frdm-mcxa153: - .config: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/mcx/mcxn/frdm-mcxn236: - .config: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -nxp/mcx/mcxn/frdm-mcxn947: - .config: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -phytium/aarch32: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -phytium/aarch64: - .config: true - README.md: true - gcc: aarch64-none-elf-gcc - menuconfig: true - rtconfig.h: true -qemu-vexpress-a9: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -qemu-virt64-aarch64: - .config: true - README.md: true - gcc: aarch64-none-elf-gcc - menuconfig: true - rtconfig.h: true -qemu-virt64-riscv: - .config: true - README.md: true - README_ZH.md: true - gcc: riscv64-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -raspberry-pi/raspi2: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -raspberry-pi/raspi3-32: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -raspberry-pi/raspi3-64: - .config: true - README.md: true - gcc: aarch64-none-elf-gcc - menuconfig: true - rtconfig.h: true -raspberry-pi/raspi4-32: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -raspberry-pi/raspi4-64: - .config: true - README.md: true - gcc: aarch64-none-elf-gcc - menuconfig: true - rtconfig.h: true -raspberry-pico: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -renesas/ebf_qi_min_6m5: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -renesas/libraries/bsp-template: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -renesas/ra2l1-cpk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -renesas/ra4m2-eco: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -renesas/ra6m3-ek: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -renesas/ra6m3-hmi-board: - .config: true - README.md: true - README_ZH.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -renesas/ra6m4-cpk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -renesas/ra6m4-iot: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -renesas/ra8d1-ek: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -renesas/ra8d1-vision-board: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -renesas/ra8m1-ek: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -renesas/rzt2m_rsk: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - menuconfig: true - rtconfig.h: true -rm48x50: - .config: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -rockchip/rk2108: - .config: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -rockchip/rk3568: - .config: true - README.md: true - gcc: aarch64-none-elf-gcc - menuconfig: true - rtconfig.h: true -rv32m1_vega/ri5cy: - .config: true - gcc: riscv-none-embed-gcc - menuconfig: true - rtconfig.h: true -sam7x: - .config: true - gcc: arm-none-eabi-gcc - mdk4: true - menuconfig: true - rtconfig.h: true -samd21: - gcc: arm-none-eabi-gcc - mdk5: true - rtconfig.h: true -sep6200: - gcc: unicore32-linux-gcc - rtconfig.h: true -simulator: - .config: true - gcc: gcc - menuconfig: true - rtconfig.h: true -smartfusion2: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -sparkfun-redv: - .config: true - README.md: true - gcc: riscv64-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -stm32/stm32f072-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f091-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-100ask-mini: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-100ask-pro: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-atk-nano: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-atk-warshipv3: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-blue-pill: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-dofly-M3S: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-dofly-lyc8: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-fire-arbitrary: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-gizwits-gokitv21: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-hw100k-ibox: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-onenet-nbiot: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-yf-ufun: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f103-ys-f1pro: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f107-uc-eval: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f207-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f302-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f334-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f401-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f401-weact-blackpill: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f405-smdz-breadfruit: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f405zg-mini-template: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f407-armfly-v5: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f407-atk-explorer: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f407-fk407m2-zgt6: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f407-lckfb-skystar: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f407-robomaster-c: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f407-rt-spark: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f407-st-discovery: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f410-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f411-atk-nano: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f411-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f411-weact-blackpill: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f412-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f413-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f427-robomaster-a: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f429-armfly-v6: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f429-atk-apollo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f429-fire-challenger: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f429-st-disco: - .config: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f446-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f469-st-disco: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f723-st-disco: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f746-st-disco: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f746-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f767-atk-apollo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f767-fire-challenger-v1: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f767-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32f769-st-disco: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32g070-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32g071-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32g431-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32g474-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32g491-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32h503-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32h563-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32h743-armfly-v7: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32h743-atk-apollo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32h743-openmv-h7plus: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32h743-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32h747-st-discovery: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32h750-armfly-h7-tool: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32h750-artpi: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32h750-fk750m1-vbt6: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32h750-weact-ministm32h7xx: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32h7s7-st-disco: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l010-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l053-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l412-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l431-BearPi: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l431-tencentos-tiny-EVB_MX+: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l432-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l433-ali-startkit: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l433-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l452-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l475-atk-pandora: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l475-st-discovery: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l476-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l496-ali-developer: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l496-st-discovery: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l496-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l4r5-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l4r9-st-eval: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l4r9-st-sensortile-box: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32l552-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32mp157a-st-discovery: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32mp157a-st-ev1: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32u575-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32u585-iot02a: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32wb55-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32wl55-st-nucleo: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32wle5-yizhilian-lm401: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -stm32/stm32wle5-yizhilian-lm402: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -synopsys/boards: - .config: true - README.md: true - gcc: arc-elf32-gcc - menuconfig: true - rtconfig.h: true -synwit/swm320-mini: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -synwit/swm341-mini: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -tae32f5300: - .config: true - README.md: true - mdk5: true - menuconfig: true - rtconfig.h: true -taihu: - gcc: powerpc-eabi-gcc - rtconfig.h: true -thead-smart: - .config: true - README.md: true - gcc: riscv64-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -ti/c28x/tms320f28379d: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true -tkm32F499: - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -tm4c123bsp: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - mdk5: true - menuconfig: true - rtconfig.h: true -tm4c129x: - .config: true - gcc: arm-none-eabi-gcc - iar: true - mdk4: true - menuconfig: true - rtconfig.h: true -upd70f3454: - gcc: m32c-elf-gcc - iar: true - rtconfig.h: true -w60x: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -wch/arm/ch32f103c8-core: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -wch/arm/ch32f203r-evt: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -wch/arm/ch579m: - .config: true - gcc: arm-none-eabi-gcc - mdk5: true - menuconfig: true - rtconfig.h: true -wch/risc-v/ch32v103r-evt: - .config: true - README.md: true - gcc: riscv-none-embed-gcc - menuconfig: true - rtconfig.h: true -wch/risc-v/ch32v208w-r0: - .config: true - gcc: riscv-none-embed-gcc - menuconfig: true - rtconfig.h: true -wch/risc-v/ch32v307v-r1: - .config: true - README.md: true - gcc: riscv-none-embed-gcc - menuconfig: true - rtconfig.h: true -wch/risc-v/ch569w-evt: - .config: true - gcc: riscv-none-embed-gcc - menuconfig: true - rtconfig.h: true -wch/risc-v/yd-ch32v307vct6: - .config: true - README.md: true - gcc: riscv-none-embed-gcc - menuconfig: true - rtconfig.h: true -x86: - .config: true - README.md: true - gcc: i386-unknown-elf-gcc - menuconfig: true - rtconfig.h: true -xplorer4330/M0: - gcc: arm-none-eabi-gcc - mdk4: true - rtconfig.h: true -xplorer4330/M4: - .config: true - gcc: arm-none-eabi-gcc - mdk4: true - menuconfig: true - rtconfig.h: true -yichip/yc3121-pos: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -yichip/yc3122-pos: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - iar: true - mdk5: true - menuconfig: true - rtconfig.h: true -zynqmp-a53-dfzu2eg: - .config: true - README.md: true - gcc: aarch64-none-elf-gcc - menuconfig: true - rtconfig.h: true -zynqmp-r5-axu4ev: - .config: true - README.md: true - gcc: arm-none-eabi-gcc - menuconfig: true - rtconfig.h: true diff --git a/rt-thread/tools/ci/cpp_check.py b/rt-thread/tools/ci/cpp_check.py index 7f3ca5a..5e7e100 100644 --- a/rt-thread/tools/ci/cpp_check.py +++ b/rt-thread/tools/ci/cpp_check.py @@ -6,7 +6,6 @@ # Change Logs: # Date Author Notes # 2023-05-16 dejavudwh the first version -# 2024-09-12 supperthomas add cppcheck summary for detail # import click @@ -14,35 +13,7 @@ import logging import subprocess import sys import format_ignore -import os -''' ---suppress=syntaxError: -该选项用于抑制特定的错误类型。在这里,syntaxError 是被忽略的错误类型。这意味着 Cppcheck 不会报告语法错误(syntaxError)。这是因为在某些情况下,分析工具可能会误报语法错误,但 CI(持续集成)系统会在编译时捕获这些错误,因此可以忽略。 ---enable=warning: -该选项用于启用特定类型的检查。Cppcheck 可以检查不同的级别和种类的问题,如错误、警告、性能问题等。--enable=warning 启用的是警告级别的检查,帮助检测代码中可能存在的问题,但不是严重的错误。 - -performance: -Cppcheck 可以启用多个检查种类,在这里指定了 performance,意味着会检查与代码性能相关的潜在问题,例如不必要的拷贝操作、无效的条件判断等。这有助于提高代码的运行效率。 - -portability: -Cppcheck 会检查代码的可移植性问题。可移植性检查帮助发现代码在不同平台或编译器中可能遇到的问题,如特定平台上不支持的类型、函数或特性。这对跨平台开发非常重要。 - ---inline-suppr: -该选项允许在代码中使用注释来抑制特定的警告或错误信息。通过这种方式,开发者可以直接在代码中添加注释,告诉 Cppcheck 忽略某些检查或警告。例如,开发者可以在代码中添加 // cppcheck-suppress 来抑制特定的警告信息。 - ---error-exitcode=1: -该选项告诉 Cppcheck 如果遇到错误,就返回指定的退出码。在这里指定的是 1。这对自动化工具非常有用,尤其是在 CI 环境中,因为它可以通过检查返回码来判断 Cppcheck 是否发现了错误。如果有错误,CI 系统会将整个任务标记为失败。 - ---force: -这个选项强制 Cppcheck 对所有文件进行检查,即使它检测到编译条件缺失或某些配置问题。通常,如果某些宏定义或依赖项缺失,Cppcheck 可能会跳过某些文件的检查。但 --force 会强制工具继续执行分析,即使有可能缺少某些信息。这在某些大型项目中很有用,可以确保所有文件都经过检查。 -''' -def add_summary(text): - """ - add summary to github action. - """ - os.system(f'echo "{text}" >> $GITHUB_STEP_SUMMARY ;') - class CPPCheck: def __init__(self, file_list): self.file_list = file_list @@ -52,10 +23,6 @@ class CPPCheck: logging.info("Start to static code analysis.") check_result = True for file in file_list_filtered: - macros = [] - if os.path.basename(file) == 'lwp.c': - macros.append('-DRT_USING_DFS') - result = subprocess.run( [ 'cppcheck', @@ -66,7 +33,6 @@ class CPPCheck: '-I thread/components/finsh', # it's okay because CI will do the real compilation to check this '--suppress=syntaxError', - '--check-level=exhaustive', '--enable=warning', 'performance', 'portability', @@ -74,14 +40,11 @@ class CPPCheck: '--error-exitcode=1', '--force', file - ] + macros, + ], stdout = subprocess.PIPE, stderr = subprocess.PIPE) logging.info(result.stdout.decode()) logging.info(result.stderr.decode()) if result.stderr: - add_summary("The following errors are for reference only. If they are not actual issues, please ignore them and do not make unnecessary modifications.") - add_summary("以下错误仅供参考,如果发现没有问题,请直接忽略,不需要强行修改") - add_summary(f"- :rotating_light: {result.stderr.decode()}") check_result = False return check_result diff --git a/rt-thread/tools/ci/install.sh b/rt-thread/tools/ci/install.sh deleted file mode 100644 index 30112a1..0000000 --- a/rt-thread/tools/ci/install.sh +++ /dev/null @@ -1,219 +0,0 @@ -#!/bin/bash - -# -# Copyright (c) 2024, RT-Thread Development Team -# -# SPDX-License-Identifier: Apache-2.0 -# -# Change Logs: -# Date Author Notes -# 2024-08-27 Supperthomas the first version -# - -#这个脚本用于安装RT-Thread开发环境 请确保网络畅通 - -# 设置环境变量 如果希望生效请在当前shell中执行source install.sh - -export RTT_ROOT=$(pwd) -export RTT_CC=gcc - -echo "RTT_ROOT is set to: $RTT_ROOT" - - -check_if_china_ip() { - # 默认情况下不使用gitee - use_gitee=false - - # 尝试通过IP地址判断 - ip=$(curl -s https://ifconfig.me/ip) - if [ -n "$ip" ]; then - location=$(curl -s http://www.ip-api.com/json/$ip | grep -o '"country":"China"') - if [ "$location" == '"country":"China"' ]; then - use_gitee=true - echo "Detected China IP. Using gitee." - else - echo "IP location is not in China." - fi - else - echo "Failed to retrieve IP address. Falling back to timezone check." - - # 通过时区判断 - if [ $(($(date +%z)/100)) -eq 8 ]; then - use_gitee=true - echo "Detected timezone UTC+8. Using gitee." - else - echo "Timezone is not UTC+8." - fi - fi - - echo $use_gitee -} - - -# 检测操作系统类型和发行版 -detect_os() { - if command -v uname >/dev/null 2>&1; then - OS=$(uname -s) - else - if [ -f "/etc/os-release" ]; then - OS="Linux" - elif [ -f "/System/Library/CoreServices/SystemVersion.plist" ]; then - OS="macOS" - elif [[ -d "/mnt/c/Windows" || -d "/c/Windows" ]]; then - OS="WSL" - else - OS="UNKNOWN" - fi - fi - - if [ "$OS" == "Linux" ]; then - if [ -f /etc/os-release ]; then - . /etc/os-release - DISTRO=$ID - VERSION=$VERSION_ID - elif [ -f /etc/lsb-release ]; then - . /etc/lsb-release - DISTRO=$DISTRIB_ID - VERSION=$DISTRIB_RELEASE - else - DISTRO="UNKNOWN" - VERSION="UNKNOWN" - fi - fi - - echo "Detected Operating System: $OS, Distribution: $DISTRO, Version: $VERSION" -} - -# 修改的安装函数 -install_on_ubuntu() { - echo "Installing on Debian/Ubuntu..." - use_gitee=$(check_if_china_ip) - - # 根据检测结果决定是否使用--gitee参数 - if [ "$use_gitee" = true ]; then - wget https://raw.githubusercontent.com/RT-Thread/env/master/install_ubuntu.sh - chmod 777 install_ubuntu.sh - echo "Installing on China gitee..." - ./install_ubuntu.sh --gitee - else - wget https://raw.githubusercontent.com/RT-Thread/env/master/install_ubuntu.sh - chmod 777 install_ubuntu.sh - echo "Installing on no China..." - ./install_ubuntu.sh - fi - rm install_ubuntu.sh -} - - -install_on_fedora() { - echo "Installing on Fedora..." - -} - -install_on_centos() { - echo "Installing on CentOS/RHEL..." -} - -install_on_arch() { - echo "Installing on Arch Linux..." -} - -install_on_macos() { - echo "Installing on macOS..." - use_gitee=$(check_if_china_ip) - - # 根据检测结果决定是否使用--gitee参数 - if [ "$use_gitee" = true ]; then - wget https://raw.githubusercontent.com/RT-Thread/env/master/install_macos.sh - chmod 777 install_macos.sh - echo "Installing on China gitee..." - ./install_macos.sh --gitee - else - wget https://raw.githubusercontent.com/RT-Thread/env/master/install_macos.sh - chmod 777 install_macos.sh - echo "Installing on no China..." - ./install_macos.sh - fi - rm ./install_macos.sh -} - -install_on_wsl() { - echo "Installing on Windows Subsystem for Linux (WSL)..." -} - -install_on_windows() { - echo "Installing on Windows using PowerShell..." - use_gitee=$(check_if_china_ip) - - # 根据检测结果决定是否使用--gitee参数 - if [ "$use_gitee" = true ]; then - wget https://raw.githubusercontent.com/RT-Thread/env/master/install_windows.ps1 - echo "Installing on China gitee..." - ./install_windows.ps1 --gitee - else - wget https://raw.githubusercontent.com/RT-Thread/env/master/install_windows.ps1 - echo "Installing on no China..." - ./install_windows.ps1 - fi - rm ./install_windows.ps1 -} - -install_on_opensuse() { - echo "Installing on openSUSE..." - use_gitee=$(check_if_china_ip) - if [ "$use_gitee" = true ]; then - wget https://raw.githubusercontent.com/RT-Thread/env/master/install_suse.sh - chmod 777 install_suse.sh - echo "Installing on China gitee..." - ./install_suse.sh --gitee - else - wget https://raw.githubusercontent.com/RT-Thread/env/master/install_suse.sh - chmod 777 install_suse.sh - echo "Installing on no China..." - ./install_suse.sh - fi - rm ./install_suse.sh -} -# 主函数 -main() { - detect_os - case "$OS" in - Linux) - case "$DISTRO" in - ubuntu|debian) - install_on_ubuntu - ;; - fedora) - install_on_fedora - ;; - centos|rhel) - install_on_centos - ;; - arch) - install_on_arch - ;; - *) - echo "Unsupported Linux distribution: $DISTRO" - exit 1 - ;; - esac - ;; - macOS) - install_on_macos - ;; - WSL) - install_on_wsl - ;; - Windows) - install_on_windows - ;; - *) - echo "Unsupported Operating System: $OS" - exit 1 - ;; - esac - echo "Installation completed!" -} - -# 执行主函数 -main diff --git a/rt-thread/tools/ci/manual_bsp_build_all.py b/rt-thread/tools/ci/manual_bsp_build_all.py deleted file mode 100644 index 733c29a..0000000 --- a/rt-thread/tools/ci/manual_bsp_build_all.py +++ /dev/null @@ -1,338 +0,0 @@ -# -# Copyright (c) 2006-2024, RT-Thread Development Team -# -# SPDX-License-Identifier: Apache-2.0 -# -# Change Logs: -# Date Author Notes -# 2024-07-25 supperthomas the first version -# - -""" -这个脚本用来编译所有的bsp -这里的脚本是用的arm-none-eabi-gcc, 默认根据本机已经安装的gcc来编译 -其他的工具链暂时不支持,其实主要根据运行的环境中支持不支持,目前只打算支持主流的 -失败的bsp会存到failed_bsp.log里面 -""" - -import os -import sys -import shutil -import multiprocessing -from multiprocessing import Process -import yaml - -#help说明 -def usage(): - print('%s all -- build all GCC bsp' % os.path.basename(sys.argv[0])) - print('%s clean -- clean all bsp' % os.path.basename(sys.argv[0])) - print('%s update -- update all prject files' % os.path.basename(sys.argv[0])) - -def add_summary(text): - """ - add summary to github action. - """ - os.system(f'echo "{text}" >> $GITHUB_STEP_SUMMARY ;') - -def run_cmd(cmd, output_info=True): - """ - 这个函数用来执行命令 - run command and return output and result. - """ - print('\033[1;32m' + cmd + '\033[0m ' + os.getcwd()) - - output_str_list = [] - res = 0 - - if output_info: - res = os.system(cmd + " > output.txt 2>&1") - else: - res = os.system(cmd + " > /dev/null 2>output.txt") - try: - with open("output.txt", "r") as file: - output_str_list = file.readlines() - except FileNotFoundError: - with open("output.txt", "w") as file: - file.write("new file") - - for line in output_str_list: - print(line, end='') - - os.remove("output.txt") - - return output_str_list, res - - -def build_bsp(bsp, scons_args=''): - """ - build bsp. - - cd {rtt_root} - scons -C bsp/{bsp} --pyconfig-silent > /dev/null - - cd {rtt_root}/bsp/{bsp} - pkgs --update > /dev/null - pkgs --list - - cd {rtt_root} - scons -C bsp/{bsp} -j{nproc} {scons_args} - - cd {rtt_root}/bsp/{bsp} - scons -c > /dev/null - rm -rf packages - - """ - success = True - pwd = os.getcwd() - print('======pwd==='+ os.getcwd()+'===bsp:=='+bsp) - - os.chdir(rtt_root) - #有Kconfig 说明可以执行menuconfig - if os.path.exists(f"{rtt_root}/bsp/{bsp}/Kconfig"): - os.chdir(rtt_root) - print('======pwd==='+ os.getcwd()+'===bsp:=='+bsp) - run_cmd(f'scons -C bsp/{bsp} --pyconfig-silent', output_info=True) - os.chdir(f'{rtt_root}/bsp/{bsp}') - print('======pwd222==='+ os.getcwd()+'===bsp:=='+bsp) - run_cmd('pkgs --update', output_info=True) - run_cmd('pkgs --list') - nproc = multiprocessing.cpu_count() - os.chdir(rtt_root) - cmd = f'scons -C bsp/{bsp} -j{nproc} {scons_args}' - result_log, res = run_cmd(cmd, output_info=True) - - if res != 0: - # 将失败的bsp写入特定的txt文件 - with open(os.path.join(rtt_root, 'failed_bsp_list.txt'), 'a') as file: - file.write(bsp + '\n') - # 打印失败的bsp的log,把它放到对应的文件名文bsp的txt文件中 - with open(os.path.join(rtt_root, 'failed_bsp.log'), 'a') as file: - file.write(f'===================={bsp}====================\n') - for line in result_log: - file.write(line) - print(f"::error::build {bsp} failed") - add_summary(f"- ❌ build {bsp} failed.") - success = False - else: - # 如果没有Kconfig直接执行scons - os.chdir(f'{rtt_root}/bsp/{bsp}') - run_cmd('scons', output_info=True) - - # 删除packages文件夹 - pkg_dir = os.path.join(rtt_root, 'bsp', bsp, 'packages') - shutil.rmtree(pkg_dir, ignore_errors=True) - #恢复到原目录 - os.chdir(pwd) - return success - -#判断参数是否是2个 -if len(sys.argv) != 2: - usage() - sys.exit(0) -#更新MDK等文件 -def update_project_file(project_dir): - if os.path.isfile(os.path.join(project_dir, 'template.Uv2')): - print('prepare MDK3 project file on ' + project_dir) - command = ' --target=mdk -s' - os.system('scons --directory=' + project_dir + command + ' > 1.txt') - - if os.path.isfile(os.path.join(project_dir, 'template.uvproj')): - print('prepare MDK4 project file on ' + project_dir) - command = ' --target=mdk4 -s' - os.system('scons --directory=' + project_dir + command + ' > 1.txt') - - if os.path.isfile(os.path.join(project_dir, 'template.uvprojx')): - print('prepare MDK5 project file on ' + project_dir) - command = ' --target=mdk5 -s' - os.system('scons --directory=' + project_dir + command + ' > 1.txt') - - if os.path.isfile(os.path.join(project_dir, 'template.ewp')): - print('prepare IAR project file on ' + project_dir) - command = ' --target=iar -s' - os.system('scons --directory=' + project_dir + command + ' > 1.txt') - -#更新所有可以scons的文件夹文件,先执行menuconfig --silent 再执行scons --target=mdk5 -#处理带有sconstruct的文件夹 -def update_all_project_files(sconstruct_paths): - for projects in sconstruct_paths: - try: - # update rtconfig.h and .config - #执行menuconfig - if os.path.isfile(os.path.join(projects, 'Kconfig')): - if "win32" in sys.platform: - retval = os.getcwd() - os.chdir(projects) - os.system("menuconfig --silent") - os.chdir(retval) - else: - os.system('scons --pyconfig-silent -C {0}'.format(projects)) - print('==menuconfig=======projects='+ projects) - else: - print('==no kconfig=in==!!!!!=projects='+ projects) - # update mdk, IAR etc file - update_project_file(projects) - except Exception as e: - print("error message: {}".format(e)) - sys.exit(-1) - -#找到带有Sconstruct的文件夹 - -def find_sconstruct_paths(project_dir, exclude_paths, include_paths): - sconstruct_paths = [] - bsp_detail_path = os.path.join(rtt_root, 'tools', 'ci', 'bsp_detail.yml') - if os.path.exists(bsp_detail_path): - with open(bsp_detail_path, 'r') as file: - bsp_detail = yaml.safe_load(file) - for root, dirs, files in os.walk(project_dir): - if include_paths: - if any(include_path in root for include_path in include_paths) and all(exclude_path not in root for exclude_path in exclude_paths): - if 'SConstruct' in files: - bsp_name = os.path.relpath(root, bsp_root) - if bsp_name in bsp_detail and bsp_detail[bsp_name].get('gcc') == 'arm-none-eabi-gcc': - sconstruct_paths.append(root) - else: - if all(exclude_path not in root for exclude_path in exclude_paths): - if 'SConstruct' in files: - bsp_name = os.path.relpath(root, bsp_root) - if bsp_name in bsp_detail and bsp_detail[bsp_name].get('gcc') == 'arm-none-eabi-gcc': - sconstruct_paths.append(root) - return sconstruct_paths - -#检查EXE命令是否存在,判断环境 -def check_command_availability(cmd): - """ - Check if a command is available. - """ - cmd_path = shutil.which(cmd) - if cmd_path is not None: - #print(f"{cmd} command is available at {cmd_path}") - return True - else: - print(f"{cmd} command is not available") - return False -# Find the rt-thread root directory -rtt_root = os.getcwd() -while not os.path.exists(os.path.join(rtt_root, 'LICENSE')): - rtt_root = os.path.dirname(rtt_root) - -bsp_root = os.path.join(rtt_root, 'bsp') - -#需要排除的文件夹名字 -exclude_paths = ['templates', 'doc', 'libraries', 'Libraries', 'template'] -include_paths = []#['nrf5x','qemu-vexpress-a9', 'ESP32_C3','simulator'] - -sconstruct_paths = find_sconstruct_paths(bsp_root, exclude_paths,include_paths) - -# get command options -command = '' -command_clean_flag = False - -print(rtt_root) - -if sys.argv[1] == 'all': - if os.path.exists(os.path.join(rtt_root, 'failed_bsp_list.txt')): - os.remove(os.path.join(rtt_root, 'failed_bsp_list.txt')) - if os.path.exists(os.path.join(rtt_root, 'failed_bsp.log')): - os.remove(os.path.join(rtt_root, 'failed_bsp.log')) - command = ' ' -#更新所有的工程 - print('begin to update all the bsp projects') - update_all_project_files(sconstruct_paths) -#iarbuild .\project.ewp -clean rt-thread -elif sys.argv[1] == 'clean': - command = ' -c' - command_clean_flag = True - print('begin to clean all the bsp projects') -# 执行所有其他IDE的 update 但是不编译,这个一般不会出错 -elif sys.argv[1] == 'update': - print('begin to update all the bsp projects') -#更新所有的工程 - update_all_project_files(sconstruct_paths) - print('finished!') - sys.exit(0) -else: - usage() - sys.exit(0) - -if sconstruct_paths: - print("包含 'SConstruct' 文件的路径:") - for path in sconstruct_paths: - print(path) -else: - print("未找到包含 'SConstruct' 文件的路径") - -#遍历所有的sconstruct_paths 路径中的文件夹 - -def bsp_scons_worker(project_dir): - print('=========project_dir===='+ project_dir) -#判断有没有SConstruct 文件, - if os.path.isfile(os.path.join(project_dir, 'SConstruct')): - print('==menuconfig=======rtt_root='+ rtt_root) - print('==project_dir=======project_dir='+ project_dir) - - # 去掉 'bsp' 前面的三级目录 - parts = project_dir.split(os.sep) - if 'bsp' in parts: - bsp_index = parts.index('bsp') - new_project_dir = os.sep.join(parts[bsp_index+1:]) - else: - new_project_dir = project_dir - print('==project_dir=======new_project_dir='+ new_project_dir) - #开始编译bsp - build_bsp(new_project_dir) - -# 发现有keil相关的,执行keil相关的命令,先检查一下UV4.exe命令有没有,然后执行UV4.exe - if check_command_availability('UV4.exe') : - """ - UV4.exe -b project.uvprojx -q -j0 -t rt-thread -o action_runner.log - ls - sleep 10 - cat action_runner.log - """ - if os.path.isfile(os.path.join(project_dir, 'template.uvprojx')): - if check_command_availability('UV4.exe'): - print('Start to build keil project======') - os.chdir(f'{project_dir}') - print('clean keil project======') - run_cmd('UV4.exe -c project.uvprojx -q') - ___, res = run_cmd('UV4.exe -b project.uvprojx -q -j0 -t rt-thread -o keil.log') - os.chdir(f'{rtt_root}') - else: - print('UV4.exe is not available, please check your keil installation') - if check_command_availability('iarbuild.exe') : - """ - iarbuild .\project.ewp rt-thread - """ - if os.path.isfile(os.path.join(project_dir, 'template.ewp')): - if check_command_availability('iarbuild.exe'): - print('Start to build iar project======') - os.chdir(f'{project_dir}') - ___, res = run_cmd('iarbuild .\project.ewp -clean rt-thread') - if res != 0: - print('run clean failed!!') - ___, res = run_cmd('iarbuild .\project.ewp rt-thread > iar.log') - if res != 0: - print('run_cmd1 failed!!') - os.chdir(f'{rtt_root}') - else: - print('iarbuild is not available, please check your iar installation') - -processes = [] -for project_dir in sconstruct_paths: - bsp_scons_worker(project_dir) - #p = Process(target=bsp_scons_worker, args=(project_dir,)) - #p.start() - #processes.append(p) - -#for p in processes: -# p.join() # 等待所有进程完成 - -print('finished!') - -# 将failed_bsp_list.txt的内容追加到failed_bsp.log文件中 -if os.path.exists(os.path.join(rtt_root, 'failed_bsp_list.txt')): - with open(os.path.join(rtt_root, 'failed_bsp_list.txt'), 'r') as file: - failed_bsp_list = file.read() -if os.path.exists(os.path.join(rtt_root, 'failed_bsp.log')): - with open(os.path.join(rtt_root, 'failed_bsp.log'), 'a') as file: - file.write(failed_bsp_list) \ No newline at end of file diff --git a/rt-thread/tools/ci/requirements.txt b/rt-thread/tools/ci/requirements.txt deleted file mode 100644 index e582593..0000000 --- a/rt-thread/tools/ci/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -pyyaml -pandas \ No newline at end of file diff --git a/rt-thread/tools/ci/toolchain.sh b/rt-thread/tools/ci/toolchain.sh deleted file mode 100644 index 24293b3..0000000 --- a/rt-thread/tools/ci/toolchain.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/bash - -declare -A download_urls=( -["arm-none-eabi-gcc"]="https://github.com/RT-Thread/toolchains-ci/releases/download/v1.3/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2" -["mips-sde-elf-gcc"]="https://github.com/RT-Thread/toolchains-ci/releases/download/v1.1/mips-2016.05-7-mips-sde-elf-i686-pc-linux-gnu.tar.bz2" -["aarch64-none-elf-gcc"]="https://github.com/RT-Thread/toolchains-ci/releases/download/v1.6/gcc-arm-10.2-2020.11-x86_64-aarch64-none-elf.tar.xz" -["riscv64-unknown-elf-gcc"]="https://github.com/RT-Thread/toolchains-ci/releases/download/v1.4/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz" -["riscv32-unknown-elf-gcc"]="https://github.com/hpmicro/riscv-gnu-toolchain/releases/download/2022.05.15/riscv32-unknown-elf-newlib-multilib_2022.05.15_linux.tar.gz" -["riscv-none-embed-gcc"]="https://github.com/RT-Thread/toolchains-ci/releases/download/v1.5/xpack-riscv-none-embed-gcc-8.3.0-2.3-linux-x64.tar.gz" -["riscv32-esp-elf-gcc"]="https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1-RC1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-RC1-linux-amd64.tar.xz" -["clang"]="https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-16.0.0/LLVMEmbeddedToolchainForArm-16.0.0-Linux-x86_64.tar.gz" - -) - -show_help() { - echo "Available toolchains:" - for key in "${!download_urls[@]}"; do - echo " - $key" - done -} - -extract_file() { - local file_name=$1 - local destination=$2 - echo "Extracting $file_name to $destination..." - case "$file_name" in - *.tar.bz2) tar -xjf "$file_name" -C "$destination" --strip-components=1;; - *.tar.gz) tar -xzf "$file_name" -C "$destination" --strip-components=1;; - *.tar.xz) tar -xJf "$file_name" -C "$destination" --strip-components=1;; - *) echo "Unsupported file format: $file_name"; exit 1;; - esac - echo "Extracted to $destination" -} - - -install_toolchain() { - local toolchain_name=$1 - local url="${download_urls[$toolchain_name]}" - if [ -z "$url" ]; then - echo "Toolchain not found." - exit 1 - fi - local file_name=$(basename "$url") - echo "Downloading $file_name..." - wget -q "$url" - echo "Extracting $file_name..." - - local target_dir="/opt/$toolchain_name" - echo "target_dir $target_dir..." - mkdir -p "$target_dir" - extract_file "$file_name" "$target_dir" - - rm $file_name - - echo "Installed: $target_dir" - - local toolchain_bin="$target_dir/bin" - if [[ ":$PATH:" != *":$toolchain_bin:"* ]]; then - echo "Adding $toolchain_bin to PATH..." - export PATH="$PATH:$toolchain_bin" - echo "export PATH=\$PATH:$toolchain_bin" >> ~/.bashrc - fi - #need source toolchain.sh or source ~/.bashrc to work - - #local toolchain_exec=$(find "$toolchain_bin" -type f -executable | head -n 1) - local toolchain_exec=$(which "$toolchain_name") - if [ -x "$toolchain_exec" ]; then - echo "Testing executable: $toolchain_exec" - $toolchain_exec --version - else - echo "No executable found in $toolchain_bin" - fi -} - -if [[ $# -eq 1 ]]; then - if [[ "$1" == "help" ]]; then - show_help - elif [ "$1" == "all" ]; then - for toolchain in "${!download_urls[@]}"; do - install_toolchain "$toolchain" - done - else - install_toolchain "$1" - fi -else - show_help -fi diff --git a/rt-thread/tools/ci/toolchain_bsp.yml b/rt-thread/tools/ci/toolchain_bsp.yml deleted file mode 100644 index 16c2ea0..0000000 --- a/rt-thread/tools/ci/toolchain_bsp.yml +++ /dev/null @@ -1,428 +0,0 @@ -# -# Copyright (c) 2024, RT-Thread Development Team -# -# SPDX-License-Identifier: Apache-2.0 -# -# Change Logs: -# Date Author Notes -# 2024-08-25 supperthomas the first version -# - -aarch64-none-elf-gcc: - bsp: - - cvitek/cv18xx_aarch64 - - phytium/aarch64 - - qemu-virt64-aarch64 - - raspberry-pi/raspi3-64 - - raspberry-pi/raspi4-64 - - rockchip/rk3568 - - zynqmp-a53-dfzu2eg - count: 7 -arc-elf32-gcc: - bsp: - - synopsys/boards - count: 1 -arm-none-eabi-gcc: - bsp: - - CME_M7 - - Infineon/psoc6-cy8ckit-062-BLE - - Infineon/psoc6-cy8ckit-062-WIFI-BT - - Infineon/psoc6-cy8ckit-062S2-43012 - - Infineon/psoc6-cy8ckit-062s4 - - Infineon/psoc6-cy8cproto-062S3-4343W - - Infineon/psoc6-evaluationkit-062S2 - - Infineon/xmc7200-kit_xmc7200_evk - - Vango/v85xx - - Vango/v85xxp - - acm32/acm32f0x0-nucleo - - acm32/acm32f4xx-nucleo - - airm2m/air105 - - airm2m/air32f103 - - allwinner_tina - - amebaz - - apm32/apm32e103ze-evalboard - - apm32/apm32e103ze-tinyboard - - apm32/apm32f030r8-miniboard - - apm32/apm32f051r8-evalboard - - apm32/apm32f072vb-miniboard - - apm32/apm32f091vc-miniboard - - apm32/apm32f103vb-miniboard - - apm32/apm32f103xe-minibroard - - apm32/apm32f107vc-evalboard - - apm32/apm32f407ig-minibroard - - apm32/apm32f407zg-evalboard - - apm32/apm32s103vb-miniboard - - apollo2 - - asm9260t - - at32/at32a403a-start - - at32/at32a423-start - - at32/at32f402-start - - at32/at32f403a-start - - at32/at32f405-start - - at32/at32f407-start - - at32/at32f413-start - - at32/at32f415-start - - at32/at32f421-start - - at32/at32f423-start - - at32/at32f425-start - - at32/at32f435-start - - at32/at32f437-start - - at91/at91sam9260 - - at91/at91sam9g45 - - beaglebone - - dm365 - - efm32 - - essemi/es32f0654 - - essemi/es32f365x - - essemi/es32f369x - - fm33lc026 - - frdm-k64f - - ft2004 - - ft32/ft32f072xb-starter - - fujitsu/mb9x/mb9bf500r - - fujitsu/mb9x/mb9bf506r - - fujitsu/mb9x/mb9bf568r - - fujitsu/mb9x/mb9bf618s - - gd32/arm/gd32103c-eval - - gd32/arm/gd32105c-eval - - gd32/arm/gd32105r-start - - gd32/arm/gd32107c-eval - - gd32/arm/gd32205r-start - - gd32/arm/gd32207i-eval - - gd32/arm/gd32303c-start - - gd32/arm/gd32303e-eval - - gd32/arm/gd32305r-start - - gd32/arm/gd32307e-start - - gd32/arm/gd32407v-lckfb - - gd32/arm/gd32407v-start - - gd32/arm/gd32450z-eval - - gd32/arm/gd32470z-lckfb - - gd32/arm/gd32h759i-start - - hc32/ev_hc32f448_lqfp80 - - hc32/ev_hc32f460_lqfp100_v2 - - hc32/ev_hc32f472_lqfp100 - - hc32/ev_hc32f4a0_lqfp176 - - hc32/lckfb-hc32f4a0-lqfp100 - - hc32l136 - - hc32l196 - - hk32/hk32f030c8-mini - - ht32/ht32f12366 - - ht32/ht32f52352 - - lm3s8962 - - lm3s9b9x - - lm4f232 - - maxim/max32660-evsys - - microchip/samc21 - - microchip/samd51-adafruit-metro-m4 - - microchip/samd51-seeed-wio-terminal - - microchip/same54 - - microchip/same70 - - microchip/saml10 - - mini2440 - - mini4020 - - mm32/mm32f3270-100ask-pitaya - - mm32f103x - - mm32f327x - - mm32l07x - - mm32l3xx - - msp432e401y-LaunchPad - - n32/n32g43xcl-stb - - n32/n32g457qel-stb - - n32/n32g45xcl-stb - - n32/n32g45xml-stb - - n32/n32g45xrl-stb - - n32/n32g45xvl-stb - - n32/n32g4frml-stb - - n32/n32l40xcl-stb - - n32/n32l436-evb - - n32/n32l43xml-stb - - n32/n32l43xrl-stb - - n32/n32wb45xl-evb - - n32g452xx/n32g452xx-mini-system - - nrf5x/nrf51822 - - nrf5x/nrf52832 - - nrf5x/nrf52833 - - nrf5x/nrf52840 - - nrf5x/nrf5340 - - nuvoton/ma35-rtp - - nuvoton/nk-980iot - - nuvoton/nk-n9h30 - - nuvoton/nk-rtu980 - - nuvoton/numaker-hmi-ma35d1 - - nuvoton/numaker-iot-m467 - - nuvoton/numaker-iot-m487 - - nuvoton/numaker-iot-ma35d1 - - nuvoton/numaker-m032ki - - nuvoton/numaker-m2354 - - nuvoton/numaker-m467hj - - nuvoton/numaker-pfm-m487 - - nv32f100x - - nxp/imx/imx6sx/cortex-a9 - - nxp/imx/imx6ul - - nxp/imx/imx6ull-smart - - nxp/imx/imxrt/imxrt1021-nxp-evk - - nxp/imx/imxrt/imxrt1052-atk-commander - - nxp/imx/imxrt/imxrt1052-fire-pro - - nxp/imx/imxrt/imxrt1052-nxp-evk - - nxp/imx/imxrt/imxrt1052-seeed-ArchMix - - nxp/imx/imxrt/imxrt1060-nxp-evk - - nxp/imx/imxrt/imxrt1061-forlinx-OK1061-S - - nxp/imx/imxrt/imxrt1064-nxp-evk - - nxp/imx/imxrt/imxrt1170-nxp-evk/m7 - - nxp/lpc/lpc1114 - - nxp/lpc/lpc176x - - nxp/lpc/lpc178x - - nxp/lpc/lpc2148 - - nxp/lpc/lpc2478 - - nxp/lpc/lpc408x - - nxp/lpc/lpc43xx/M0 - - nxp/lpc/lpc43xx/M4 - - nxp/lpc/lpc5410x - - nxp/lpc/lpc54114-lite - - nxp/lpc/lpc54608-LPCXpresso - - nxp/lpc/lpc55sxx/Libraries/template/lpc55s6xxxx - - nxp/lpc/lpc55sxx/lpc55s06_nxp_evk - - nxp/lpc/lpc55sxx/lpc55s16_nxp_evk - - nxp/lpc/lpc55sxx/lpc55s28_nxp_evk - - nxp/lpc/lpc55sxx/lpc55s36_nxp_evk - - nxp/lpc/lpc55sxx/lpc55s69_nxp_evk - - nxp/lpc/lpc824 - - nxp/mcx/mcxa/frdm-mcxa153 - - nxp/mcx/mcxn/frdm-mcxn236 - - nxp/mcx/mcxn/frdm-mcxn947 - - phytium/aarch32 - - qemu-vexpress-a9 - - raspberry-pi/raspi2 - - raspberry-pi/raspi3-32 - - raspberry-pi/raspi4-32 - - raspberry-pico - - renesas/ebf_qi_min_6m5 - - renesas/libraries/bsp-template - - renesas/ra2l1-cpk - - renesas/ra4m2-eco - - renesas/ra6m3-ek - - renesas/ra6m3-hmi-board - - renesas/ra6m4-cpk - - renesas/ra6m4-iot - - renesas/ra8d1-ek - - renesas/ra8d1-vision-board - - renesas/ra8m1-ek - - renesas/rzt2m_rsk - - rm48x50 - - rockchip/rk2108 - - sam7x - - samd21 - - smartfusion2 - - stm32/stm32f072-st-nucleo - - stm32/stm32f091-st-nucleo - - stm32/stm32f103-100ask-mini - - stm32/stm32f103-100ask-pro - - stm32/stm32f103-atk-nano - - stm32/stm32f103-atk-warshipv3 - - stm32/stm32f103-blue-pill - - stm32/stm32f103-dofly-M3S - - stm32/stm32f103-dofly-lyc8 - - stm32/stm32f103-fire-arbitrary - - stm32/stm32f103-gizwits-gokitv21 - - stm32/stm32f103-hw100k-ibox - - stm32/stm32f103-onenet-nbiot - - stm32/stm32f103-yf-ufun - - stm32/stm32f103-ys-f1pro - - stm32/stm32f107-uc-eval - - stm32/stm32f207-st-nucleo - - stm32/stm32f302-st-nucleo - - stm32/stm32f334-st-nucleo - - stm32/stm32f401-st-nucleo - - stm32/stm32f401-weact-blackpill - - stm32/stm32f405-smdz-breadfruit - - stm32/stm32f405zg-mini-template - - stm32/stm32f407-armfly-v5 - - stm32/stm32f407-atk-explorer - - stm32/stm32f407-fk407m2-zgt6 - - stm32/stm32f407-lckfb-skystar - - stm32/stm32f407-robomaster-c - - stm32/stm32f407-rt-spark - - stm32/stm32f407-st-discovery - - stm32/stm32f410-st-nucleo - - stm32/stm32f411-atk-nano - - stm32/stm32f411-st-nucleo - - stm32/stm32f411-weact-blackpill - - stm32/stm32f412-st-nucleo - - stm32/stm32f413-st-nucleo - - stm32/stm32f427-robomaster-a - - stm32/stm32f429-armfly-v6 - - stm32/stm32f429-atk-apollo - - stm32/stm32f429-fire-challenger - - stm32/stm32f429-st-disco - - stm32/stm32f446-st-nucleo - - stm32/stm32f469-st-disco - - stm32/stm32f723-st-disco - - stm32/stm32f746-st-disco - - stm32/stm32f746-st-nucleo - - stm32/stm32f767-atk-apollo - - stm32/stm32f767-fire-challenger-v1 - - stm32/stm32f767-st-nucleo - - stm32/stm32f769-st-disco - - stm32/stm32g070-st-nucleo - - stm32/stm32g071-st-nucleo - - stm32/stm32g431-st-nucleo - - stm32/stm32g474-st-nucleo - - stm32/stm32g491-st-nucleo - - stm32/stm32h503-st-nucleo - - stm32/stm32h563-st-nucleo - - stm32/stm32h743-armfly-v7 - - stm32/stm32h743-atk-apollo - - stm32/stm32h743-openmv-h7plus - - stm32/stm32h743-st-nucleo - - stm32/stm32h747-st-discovery - - stm32/stm32h750-armfly-h7-tool - - stm32/stm32h750-artpi - - stm32/stm32h750-fk750m1-vbt6 - - stm32/stm32h750-weact-ministm32h7xx - - stm32/stm32h7s7-st-disco - - stm32/stm32l010-st-nucleo - - stm32/stm32l053-st-nucleo - - stm32/stm32l412-st-nucleo - - stm32/stm32l431-BearPi - - stm32/stm32l431-tencentos-tiny-EVB_MX+ - - stm32/stm32l432-st-nucleo - - stm32/stm32l433-ali-startkit - - stm32/stm32l433-st-nucleo - - stm32/stm32l452-st-nucleo - - stm32/stm32l475-atk-pandora - - stm32/stm32l475-st-discovery - - stm32/stm32l476-st-nucleo - - stm32/stm32l496-ali-developer - - stm32/stm32l496-st-discovery - - stm32/stm32l496-st-nucleo - - stm32/stm32l4r5-st-nucleo - - stm32/stm32l4r9-st-eval - - stm32/stm32l4r9-st-sensortile-box - - stm32/stm32l552-st-nucleo - - stm32/stm32mp157a-st-discovery - - stm32/stm32mp157a-st-ev1 - - stm32/stm32u575-st-nucleo - - stm32/stm32u585-iot02a - - stm32/stm32wb55-st-nucleo - - stm32/stm32wl55-st-nucleo - - stm32/stm32wle5-yizhilian-lm401 - - stm32/stm32wle5-yizhilian-lm402 - - synwit/swm320-mini - - synwit/swm341-mini - - ti/c28x/tms320f28379d - - tkm32F499 - - tm4c123bsp - - tm4c129x - - w60x - - wch/arm/ch32f103c8-core - - wch/arm/ch32f203r-evt - - wch/arm/ch579m - - xplorer4330/M0 - - xplorer4330/M4 - - yichip/yc3121-pos - - yichip/yc3122-pos - - zynqmp-r5-axu4ev - count: 298 - download_url: https://github.com/RT-Thread/toolchains-ci/releases/download/v1.3/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 -avr32-gcc: - bsp: - - avr32/at32uc3a0256 - - avr32/at32uc3b0256 - count: 2 -csky-abiv2-elf-gcc: - bsp: - - ck802 - - essemi/es32vf2264 - count: 2 -gcc: - bsp: - - simulator - count: 1 -i386-unknown-elf-gcc: - bsp: - - x86 - count: 1 -m32c-elf-gcc: - bsp: - - m16c62p - - upd70f3454 - count: 2 -mips-sde-elf-gcc: - bsp: - - loongson/ls1bdev - - loongson/ls1cdev - - loongson/ls2kdev - - mipssim - count: 4 - download_url: https://github.com/RT-Thread/toolchains-ci/releases/download/v1.6/gcc-arm-10.2-2020.11-x86_64-aarch64-none-elf.tar.xz -powerpc-eabi-gcc: - bsp: - - taihu - count: 1 -riscv-none-embed-gcc: - bsp: - - gd32/risc-v/gd32vf103r-start - - gd32/risc-v/gd32vf103v-eval - - hifive1 - - juicevm - - k210 - - rv32m1_vega/ri5cy - - wch/risc-v/ch32v103r-evt - - wch/risc-v/ch32v208w-r0 - - wch/risc-v/ch32v307v-r1 - - wch/risc-v/ch569w-evt - - wch/risc-v/yd-ch32v307vct6 - count: 11 - download_url: https://github.com/RT-Thread/toolchains-ci/releases/download/v1.5/xpack-riscv-none-embed-gcc-8.3.0-2.3-linux-x64.tar.gz -riscv-nuclei-elf-gcc: - bsp: - - nuclei/gd32vf103_rvstar - - nuclei/nuclei_fpga_eval - count: 2 -riscv32-esp-elf-gcc: - bsp: - - ESP32_C3 - count: 1 - download_url: https://github.com/espressif/crosstool-NG/releases/download/esp-2022r1-RC1/riscv32-esp-elf-gcc11_2_0-esp-2022r1-RC1-linux-amd64.tar.xz -riscv32-unknown-elf-gcc: - bsp: - - core-v-mcu/core-v-cv32e40p - - hpmicro/hpm5300evk - - hpmicro/hpm5301evklite - - hpmicro/hpm6200evk - - hpmicro/hpm6300evk - - hpmicro/hpm6750evk - - hpmicro/hpm6750evk2 - - hpmicro/hpm6750evkmini - - hpmicro/hpm6800evk - count: 9 - download_url: https://github.com/hpmicro/riscv-gnu-toolchain/releases/download/2022.05.15/riscv32-unknown-elf-newlib-multilib_2022.05.15_linux.tar.gz -riscv64-unknown-elf-gcc: - bsp: - - bluetrum/ab32vg1-ab-prougen - - bouffalo_lab/bl60x - - bouffalo_lab/bl61x - - bouffalo_lab/bl70x - - bouffalo_lab/bl808/lp - - bouffalo_lab/bl808/m0 - - cvitek/c906_little - - cvitek/cv18xx_risc-v - - qemu-virt64-riscv - - sparkfun-redv - - thead-smart - count: 11 - download_url: https://github.com/RT-Thread/toolchains-ci/releases/download/v1.4/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar.gz -riscv64-unknown-linux-musl-gcc: - bsp: - - allwinner/d1 - - allwinner/d1s - - bouffalo_lab/bl808/d0 - count: 3 -sparc-gaisler-elf-gcc: - bsp: - - bm3803 - count: 1 -unicore32-linux-gcc: - bsp: - - sep6200 - count: 1 diff --git a/rt-thread/tools/cmake.py b/rt-thread/tools/cmake.py index fb894d1..5e6765f 100644 --- a/rt-thread/tools/cmake.py +++ b/rt-thread/tools/cmake.py @@ -9,7 +9,7 @@ import re import utils import rtconfig from utils import _make_path_relative -from collections import defaultdict, Counter +from collections import defaultdict def GenerateCFiles(env, project, project_name): @@ -172,139 +172,32 @@ def GenerateCFiles(env, project, project_name): cm_file.write("\t-D" + i + "\n") cm_file.write(")\n\n") - libgroups = [] - interfacelibgroups = [] + cm_file.write("SET(PROJECT_SOURCES\n") for group in project: - if group['name'] == 'Applications': - continue - - # When a group is provided without sources, add it to the library list - if len(group['src']) == 0: - interfacelibgroups.append(group) - else: - libgroups.append(group) - - # Process groups whose names differ only in capitalization. - # (Groups have same name should be merged into one before) - for group in libgroups: - group['alias'] = group['name'].lower() - names = [group['alias'] for group in libgroups] - counter = Counter(names) - names = [name for name in names if counter[name] > 1] - for group in libgroups: - if group['alias'] in names: - counter[group['alias']] -= 1 - group['alias'] = f"{group['name']}_{counter[group['alias']]}" - print(f"Renamed {group['name']} to {group['alias']}") - group['name'] = group['alias'] - - cm_file.write("# Library source files\n") - for group in project: - cm_file.write("SET(RT_{:s}_SOURCES\n".format(group['name'].upper())) for f in group['src']: # use relative path path = _make_path_relative(os.getcwd(), os.path.normpath(f.rfile().abspath)) cm_file.write( "\t" + path.replace("\\", "/") + "\n" ) - cm_file.write(")\n\n") - - cm_file.write("# Library search paths\n") - for group in libgroups + interfacelibgroups: - if not 'LIBPATH' in group.keys(): - continue - - if len(group['LIBPATH']) == 0: - continue - - cm_file.write("SET(RT_{:s}_LINK_DIRS\n".format(group['name'].upper())) - for f in group['LIBPATH']: - cm_file.write("\t"+ f.replace("\\", "/") + "\n" ) - cm_file.write(")\n\n") - - cm_file.write("# Library local macro definitions\n") - for group in libgroups: - if not 'LOCAL_CPPDEFINES' in group.keys(): - continue - - if len(group['LOCAL_CPPDEFINES']) == 0: - continue - - cm_file.write("SET(RT_{:s}_DEFINES\n".format(group['name'].upper())) - for f in group['LOCAL_CPPDEFINES']: - cm_file.write("\t"+ f.replace("\\", "/") + "\n" ) - cm_file.write(")\n\n") - - cm_file.write("# Library dependencies\n") - for group in libgroups + interfacelibgroups: - if not 'LIBS' in group.keys(): - continue - - if len(group['LIBS']) == 0: - continue - - cm_file.write("SET(RT_{:s}_LIBS\n".format(group['name'].upper())) - for f in group['LIBS']: - cm_file.write("\t"+ "{}\n".format(f.replace("\\", "/"))) - cm_file.write(")\n\n") - - cm_file.write("# Libraries\n") - for group in libgroups: - cm_file.write("ADD_LIBRARY(rtt_{:s} OBJECT ${{RT_{:s}_SOURCES}})\n" - .format(group['name'], group['name'].upper())) - - cm_file.write("\n") - - cm_file.write("# Interface libraries\n") - for group in interfacelibgroups: - cm_file.write("ADD_LIBRARY(rtt_{:s} INTERFACE)\n".format(group['name'])) - - cm_file.write("\n") - - cm_file.write("# Private macros\n") - for group in libgroups: - if not 'LOCAL_CPPDEFINES' in group.keys(): - continue - - if len(group['LOCAL_CPPDEFINES']) == 0: - continue - - cm_file.write("TARGET_COMPILE_DEFINITIONS(rtt_{:s} PRIVATE ${{RT_{:s}_DEFINES}})\n" - .format(group['name'], group['name'].upper())) - - cm_file.write("\n") - - cm_file.write("# Interface library search paths\n") - if rtconfig.PLATFORM in ['gcc']: - for group in libgroups: - if not 'LIBPATH' in group.keys(): - continue - - if len(group['LIBPATH']) == 0: - continue - - cm_file.write("TARGET_LINK_DIRECTORIES(rtt_{:s} INTERFACE ${{RT_{:s}_LINK_DIRS}})\n" - .format(group['name'], group['name'].upper())) - - for group in libgroups: - if not 'LIBS' in group.keys(): - continue - - if len(group['LIBS']) == 0: - continue - - cm_file.write("TARGET_LINK_LIBRARIES(rtt_{:s} INTERFACE ${{RT_{:s}_LIBS}})\n" - .format(group['name'], group['name'].upper())) - - cm_file.write("\n") - - cm_file.write("ADD_EXECUTABLE(${CMAKE_PROJECT_NAME}.elf ${RT_APPLICATIONS_SOURCES})\n") - - cm_file.write("TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME}.elf\n") - for group in libgroups + interfacelibgroups: - cm_file.write("\trtt_{:s}\n".format(group['name'])) cm_file.write(")\n\n") - cm_file.write("ADD_CUSTOM_COMMAND(TARGET ${CMAKE_PROJECT_NAME}.elf POST_BUILD \n" + POST_ACTION + '\n)\n') + if rtconfig.PLATFORM in ['gcc']: + cm_file.write("LINK_DIRECTORIES(\n") + for group in project: + if 'LIBPATH' in group.keys(): + for f in group['LIBPATH']: + cm_file.write( "\t"+ f.replace("\\", "/") + "\n" ) + cm_file.write(")\n\n") + cm_file.write("LINK_LIBRARIES(\n") + for group in project: + if 'LIBS' in group.keys(): + for f in group['LIBS']: + cm_file.write( "\t"+ "{}\n".format(f.replace("\\", "/"))) + cm_file.write(")\n\n") + + cm_file.write("ADD_EXECUTABLE(${CMAKE_PROJECT_NAME}.elf ${PROJECT_SOURCES})\n") + cm_file.write("ADD_CUSTOM_COMMAND(TARGET ${CMAKE_PROJECT_NAME}.elf POST_BUILD \n" + POST_ACTION + '\n)\n') + # auto inclue `custom.cmake` for user custom settings custom_cmake = \ ''' diff --git a/rt-thread/tools/eclipse.py b/rt-thread/tools/eclipse.py index cb8d105..878dbdb 100644 --- a/rt-thread/tools/eclipse.py +++ b/rt-thread/tools/eclipse.py @@ -21,7 +21,7 @@ from utils import xml_indent MODULE_VER_NUM = 6 -source_pattern = ['*.c', '*.cpp', '*.cxx', '*.cc', '*.s', '*.S', '*.asm','*.cmd'] +source_pattern = ['*.c', '*.cpp', '*.cxx', '*.s', '*.S', '*.asm','*.cmd'] def OSPath(path): diff --git a/rt-thread/tools/env_utility.py b/rt-thread/tools/env_utility.py deleted file mode 100644 index d950d07..0000000 --- a/rt-thread/tools/env_utility.py +++ /dev/null @@ -1,488 +0,0 @@ -#! /usr/bin/env python -# coding=utf-8 -# -# Copyright (c) 2024, RT-Thread Development Team -# -# SPDX-License-Identifier: GPL-2.0 -# -# Change Logs: -# Date Author Notes -# 2024-04-20 Bernard the first version - -import os -import json -import platform -import re -import sys -import shutil -import hashlib -import operator - - -def GetEnvPath(): - if "ENV_ROOT" in os.environ: - return os.environ["ENV_ROOT"] - - if platform.system() == 'Windows': - env_root = os.path.join(os.environ['USERPROFILE'], '.env') - else: - env_root = os.path.join(os.environ['HOME'], '.env') - - return env_root - - -def GetPkgPath(): - if "PKGS_DIR" in os.environ: - return os.environ["PKGS_DIR"] - elif "PKGS_ROOT" in os.environ: - return os.environ["PKGS_ROOT"] - elif GetEnvPath(): - return os.path.join(GetEnvPath(), "packages") - else: - return None - -def GetSDKPackagePath(): - env = GetEnvPath() - - if env: - return os.path.join(env, "tools", "scripts", "packages") - - return None - -# get SDK path based on name -# for example, GetSDKPath('arm-none-eabi') = '.env/tools/scripts/packages/arm-none-eabi-gcc-v10.3' -def GetSDKPath(name): - sdk_pkgs = GetSDKPackagePath() - - if sdk_pkgs: - # read env/tools/scripts/sdk_cfg.json for curstomized SDK path - if os.path.exists(os.path.join(sdk_pkgs, '..', 'sdk_cfg.json')): - with open(os.path.join(sdk_pkgs, '..', 'sdk_cfg.json'), 'r', encoding='utf-8') as f: - sdk_cfg = json.load(f) - for item in sdk_cfg: - if item['name'] == name: - sdk = os.path.join(sdk_pkgs, item['path']) - return sdk - - # read packages.json under env/tools/scripts/packages - with open(os.path.join(sdk_pkgs, 'pkgs.json'), 'r', encoding='utf-8') as f: - # packages_json = f.read() - packages = json.load(f) - - for item in packages: - package_path = os.path.join(GetEnvPath(), 'packages', item['path'], 'package.json') - # read package['path']/package.json under env/packages - with open(package_path, 'r', encoding='utf-8') as f: - # package_json = f.read() - package = json.load(f) - - if package['name'] == name: - sdk = os.path.join(sdk_pkgs, package['name'] + '-' + item['ver']) - return sdk - - # not found named package - return None - -def help_info(): - print( - "**********************************************************************************\n" - "* Help infomation:\n" - "* Git tool install step.\n" - "* If your system is linux, you can use command below to install git.\n" - "* $ sudo yum install git\n" - "* $ sudo apt-get install git\n" - "* If your system is windows, you should download git software(msysGit).\n" - "* Download path: http://git-scm.com/download/win\n" - "* After you install it, be sure to add the git command execution PATH \n" - "* to your system PATH.\n" - "* Usually, git command PATH is $YOUR_INSTALL_DIR\\Git\\bin\n" - "* If your system is OSX, please download git and install it.\n" - "* Download path: http://git-scm.com/download/mac\n" - "**********************************************************************************\n" - ) - - -def touch_env(use_gitee=False): - if sys.platform != 'win32': - home_dir = os.environ['HOME'] - else: - home_dir = os.environ['USERPROFILE'] - - if use_gitee: - # "Install RT-Thread Environment from Gitee" - sdk_url = 'https://gitee.com/RT-Thread-Mirror/sdk.git' - pkg_url = 'https://gitee.com/RT-Thread-Mirror/packages.git' - env_url = 'https://gitee.com/RT-Thread-Mirror/env.git' - else: - pkg_url = 'https://github.com/RT-Thread/packages.git' - sdk_url = 'https://github.com/RT-Thread/sdk.git' - env_url = 'https://github.com/RT-Thread/env.git' - - pkg_url = os.getenv('RTT_PACKAGE_URL') or pkg_url - sdk_url = os.getenv('RTT_SDK_URL') or sdk_url - env_url = os.getenv('RTT_ENV_URL') or env_url - - # make .env and other directories - env_dir = os.path.join(home_dir, '.env') - if not os.path.exists(env_dir): - os.mkdir(env_dir) - os.mkdir(os.path.join(env_dir, 'local_pkgs')) - os.mkdir(os.path.join(env_dir, 'packages')) - os.mkdir(os.path.join(env_dir, 'tools')) - kconfig = open(os.path.join(env_dir, 'packages', 'Kconfig'), 'w') - kconfig.close() - - # git clone packages - if not os.path.exists(os.path.join(env_dir, 'packages', 'packages')): - try: - ret = os.system('git clone %s %s' % (pkg_url, os.path.join(env_dir, 'packages', 'packages'))) - if ret != 0: - shutil.rmtree(os.path.join(env_dir, 'packages', 'packages')) - print( - "********************************************************************************\n" - "* Warnning:\n" - "* Run command error for \"git clone https://github.com/RT-Thread/packages.git\".\n" - "* This error may have been caused by not found a git tool or network error.\n" - "* If the git tool is not installed, install the git tool first.\n" - "* If the git utility is installed, check whether the git command is added to \n" - "* the system PATH.\n" - "* This error may cause the RT-Thread packages to not work properly.\n" - "********************************************************************************\n" - ) - help_info() - else: - kconfig = open(os.path.join(env_dir, 'packages', 'Kconfig'), 'w') - kconfig.write('source "$PKGS_DIR/packages/Kconfig"') - kconfig.close() - except: - print( - "**********************************************************************************\n" - "* Warnning:\n" - "* Run command error for \"git clone https://github.com/RT-Thread/packages.git\". \n" - "* This error may have been caused by not found a git tool or git tool not in \n" - "* the system PATH. \n" - "* This error may cause the RT-Thread packages to not work properly. \n" - "**********************************************************************************\n" - ) - help_info() - - # git clone env scripts - if not os.path.exists(os.path.join(env_dir, 'tools', 'scripts')): - try: - ret = os.system('git clone %s %s' % (env_url, os.path.join(env_dir, 'tools', 'scripts'))) - if ret != 0: - shutil.rmtree(os.path.join(env_dir, 'tools', 'scripts')) - print( - "********************************************************************************\n" - "* Warnning:\n" - "* Run command error for \"git clone https://github.com/RT-Thread/env.git\".\n" - "* This error may have been caused by not found a git tool or network error.\n" - "* If the git tool is not installed, install the git tool first.\n" - "* If the git utility is installed, check whether the git command is added \n" - "* to the system PATH.\n" - "* This error may cause script tools to fail to work properly.\n" - "********************************************************************************\n" - ) - help_info() - except: - print( - "********************************************************************************\n" - "* Warnning:\n" - "* Run command error for \"git clone https://github.com/RT-Thread/env.git\". \n" - "* This error may have been caused by not found a git tool or git tool not in \n" - "* the system PATH. \n" - "* This error may cause script tools to fail to work properly. \n" - "********************************************************************************\n" - ) - help_info() - - # git clone sdk - if not os.path.exists(os.path.join(env_dir, 'packages', 'sdk')): - try: - ret = os.system('git clone %s %s' % (sdk_url, os.path.join(env_dir, 'packages', 'sdk'))) - if ret != 0: - shutil.rmtree(os.path.join(env_dir, 'packages', 'sdk')) - print( - "********************************************************************************\n" - "* Warnning:\n" - "* Run command error for \"git clone https://github.com/RT-Thread/sdk.git\".\n" - "* This error may have been caused by not found a git tool or network error.\n" - "* If the git tool is not installed, install the git tool first.\n" - "* If the git utility is installed, check whether the git command is added \n" - "* to the system PATH.\n" - "* This error may cause the RT-Thread SDK to not work properly.\n" - "********************************************************************************\n" - ) - help_info() - except: - print( - "********************************************************************************\n" - "* Warnning:\n" - "* Run command error for \"https://github.com/RT-Thread/sdk.git\".\n" - "* This error may have been caused by not found a git tool or git tool not in \n" - "* the system PATH. \n" - "* This error may cause the RT-Thread SDK to not work properly. \n" - "********************************************************************************\n" - ) - help_info() - - # try to create an empty .config file - if not os.path.exists(os.path.join(env_dir, 'tools', '.config')): - kconfig = open(os.path.join(env_dir, 'tools', '.config'), 'w') - kconfig.close() - - # copy env.sh or env.ps1, Kconfig - shutil.copy(os.path.join(env_dir, 'tools', 'scripts', 'Kconfig'), os.path.join(home_dir, '.env', 'tools')) - if sys.platform != 'win32': - shutil.copy(os.path.join(env_dir, 'tools', 'scripts', 'env.sh'), os.path.join(home_dir, '.env', 'env.sh')) - else: - shutil.copy(os.path.join(env_dir, 'tools', 'scripts', 'env.ps1'), os.path.join(home_dir, '.env', 'env.ps1')) - # unzip kconfig-mconf.zip - # zip_file = os.path.join(env_dir, 'tools', 'scripts', 'kconfig-mconf.zip') - # if os.path.exists(zip_file): - # zip_file_dir = os.path.join(env_dir, 'tools', 'bin') - # if os.path.exists(zip_file_dir): - # shutil.rmtree(zip_file_dir) - # zip_file_obj = zipfile.ZipFile(zip_file, 'r') - # for file in zip_file_obj.namelist(): - # zip_file_obj.extract(file, zip_file_dir) - # zip_file_obj.close() - - -def is_pkg_special_config(config_str): - '''judge if it's CONFIG_PKG_XX_PATH or CONFIG_PKG_XX_VER''' - - if type(config_str) == type('a'): - if config_str.startswith("PKG_") and (config_str.endswith('_PATH') or config_str.endswith('_VER')): - return True - return False - - -def mk_rtconfig(filename): - try: - config = open(filename, 'r') - except: - print('open config:%s failed' % filename) - return - - rtconfig = open('rtconfig.h', 'w') - rtconfig.write('#ifndef RT_CONFIG_H__\n') - rtconfig.write('#define RT_CONFIG_H__\n\n') - - empty_line = 1 - - for line in config: - line = line.lstrip(' ').replace('\n', '').replace('\r', '') - - if len(line) == 0: - continue - - if line[0] == '#': - if len(line) == 1: - if empty_line: - continue - - rtconfig.write('\n') - empty_line = 1 - continue - - if line.startswith('# CONFIG_'): - line = ' ' + line[9:] - else: - line = line[1:] - rtconfig.write('/*%s */\n' % line) - - empty_line = 0 - else: - empty_line = 0 - setting = line.split('=') - if len(setting) >= 2: - if setting[0].startswith('CONFIG_'): - setting[0] = setting[0][7:] - - # remove CONFIG_PKG_XX_PATH or CONFIG_PKG_XX_VER - if is_pkg_special_config(setting[0]): - continue - - if setting[1] == 'y': - rtconfig.write('#define %s\n' % setting[0]) - else: - rtconfig.write('#define %s %s\n' % (setting[0], re.findall(r"^.*?=(.*)$", line)[0])) - - if os.path.isfile('rtconfig_project.h'): - rtconfig.write('#include "rtconfig_project.h"\n') - - rtconfig.write('\n') - rtconfig.write('#endif\n') - rtconfig.close() - - -def get_file_md5(file): - MD5 = hashlib.new('md5') - with open(file, 'r') as fp: - MD5.update(fp.read().encode('utf8')) - fp_md5 = MD5.hexdigest() - return fp_md5 - - -# Exclude utestcases -def exclude_utestcases(RTT_ROOT): - if os.path.isfile(os.path.join(RTT_ROOT, 'examples/utest/testcases/Kconfig')): - return - - if not os.path.isfile(os.path.join(RTT_ROOT, 'Kconfig')): - return - - with open(os.path.join(RTT_ROOT, 'Kconfig'), 'r') as f: - data = f.readlines() - with open(os.path.join(RTT_ROOT, 'Kconfig'), 'w') as f: - for line in data: - if line.find('examples/utest/testcases/Kconfig') == -1: - f.write(line) - - -# fix locale for kconfiglib -def kconfiglib_fix_locale(): - import os - import locale - - # Get the list of supported locales - supported_locales = set(locale.locale_alias.keys()) - - # Check if LANG is set and its value is not in the supported locales - if 'LANG' in os.environ and os.environ['LANG'] not in supported_locales: - os.environ['LANG'] = 'C' - - -def kconfiglib_check_installed(): - try: - import kconfiglib - except ImportError as e: - print("\033[1;31m**ERROR**: Failed to import kconfiglib, " + str(e)) - print("") - print("You may need to install it using:") - print(" pip install kconfiglib\033[0m") - print("") - sys.exit(1) - - # set PKGS_DIR envrionment - pkg_dir = GetPkgPath() - if os.path.exists(pkg_dir): - os.environ["PKGS_DIR"] = pkg_dir - elif sys.platform != 'win32': - touch_env() - os.environ["PKGS_DIR"] = GetPkgPath() - else: - print("\033[1;33m**WARNING**: PKGS_DIR not found, please install ENV tools\033[0m") - - -# menuconfig for Linux and Windows -def menuconfig(RTT_ROOT): - kconfiglib_check_installed() - - import menuconfig - - # Exclude utestcases - exclude_utestcases(RTT_ROOT) - - fn = '.config' - fn_old = '.config.old' - - sys.argv = ['menuconfig', 'Kconfig'] - - # fix vscode console - kconfiglib_fix_locale() - - menuconfig._main() - - if os.path.isfile(fn): - if os.path.isfile(fn_old): - diff_eq = operator.eq(get_file_md5(fn), get_file_md5(fn_old)) - else: - diff_eq = False - else: - sys.exit(-1) - - # make rtconfig.h - if diff_eq == False: - shutil.copyfile(fn, fn_old) - mk_rtconfig(fn) - - -# guiconfig for windows and linux -def guiconfig(RTT_ROOT): - kconfiglib_check_installed() - - import guiconfig - - # Exclude utestcases - exclude_utestcases(RTT_ROOT) - - fn = '.config' - fn_old = '.config.old' - - sys.argv = ['guiconfig', 'Kconfig'] - guiconfig._main() - - if os.path.isfile(fn): - if os.path.isfile(fn_old): - diff_eq = operator.eq(get_file_md5(fn), get_file_md5(fn_old)) - else: - diff_eq = False - else: - sys.exit(-1) - - # make rtconfig.h - if diff_eq == False: - shutil.copyfile(fn, fn_old) - mk_rtconfig(fn) - - -# defconfig for windows and linux -def defconfig(RTT_ROOT): - kconfiglib_check_installed() - - import defconfig - - # Exclude utestcases - exclude_utestcases(RTT_ROOT) - - fn = '.config' - - sys.argv = ['defconfig', '--kconfig', 'Kconfig', '.config'] - defconfig.main() - - # silent mode, force to make rtconfig.h - mk_rtconfig(fn) - - -def genconfig(): - from SCons.Script import SCons - - PreProcessor = SCons.cpp.PreProcessor() - - try: - f = open('rtconfig.h', 'r') - contents = f.read() - f.close() - except: - print("Open rtconfig.h file failed.") - - PreProcessor.process_contents(contents) - options = PreProcessor.cpp_namespace - - try: - f = open('.config', 'w') - for opt, value in options.items(): - if type(value) == type(1): - f.write("CONFIG_%s=%d\n" % (opt, value)) - - if type(value) == type('') and value == '': - f.write("CONFIG_%s=y\n" % opt) - elif type(value) == type('str'): - f.write("CONFIG_%s=%s\n" % (opt, value)) - - print("Generate .config done!") - f.close() - except: - print("Generate .config file failed.") diff --git a/rt-thread/tools/mkdist.py b/rt-thread/tools/mkdist.py index 78a235c..ea1a0c9 100644 --- a/rt-thread/tools/mkdist.py +++ b/rt-thread/tools/mkdist.py @@ -54,7 +54,7 @@ def do_copy_folder(src_dir, dst_dir, ignore=None): shutil.copytree(src_dir, dst_dir, ignore = ignore) -source_ext = ['c', 'h', 's', 'S', 'cpp', 'cxx', 'cc', 'xpm'] +source_ext = ['c', 'h', 's', 'S', 'cpp', 'xpm'] source_list = [] def walk_children(child): diff --git a/rt-thread/tools/options.py b/rt-thread/tools/options.py index b77b675..c1b3967 100644 --- a/rt-thread/tools/options.py +++ b/rt-thread/tools/options.py @@ -121,16 +121,16 @@ def AddOptions(): action = 'store_true', default = False, help = 'reset the project configurations to default') - AddOption('--guiconfig', '--pyconfig', - dest = 'guiconfig', + AddOption('--pyconfig', '--guiconfig', + dest = 'pyconfig', action = 'store_true', default = False, help = 'Python GUI menuconfig for RT-Thread BSP') - AddOption('--defconfig', '--pyconfig-silent', - dest = 'defconfig', + AddOption('--pyconfig-silent', '--defconfig', + dest = 'pyconfig-silent', action = 'store_true', default = False, - help = 'Don`t show Python GUI menuconfig window') + help = 'Don`t show pyconfig window') AddOption('--menuconfig', dest = 'menuconfig', action = 'store_true', diff --git a/rt-thread/tools/utils.py b/rt-thread/tools/utils.py index 9c09bbf..758e561 100644 --- a/rt-thread/tools/utils.py +++ b/rt-thread/tools/utils.py @@ -106,7 +106,7 @@ def xml_indent(elem, level=0): elem.tail = i -source_ext = ["c", "h", "s", "S", "cpp", "cxx", "cc", "xpm"] +source_ext = ["c", "h", "s", "S", "cpp", "xpm"] source_list = [] def walk_children(child): diff --git a/rt-thread/tools/vsc.py b/rt-thread/tools/vsc.py index c005bcf..bbb0deb 100644 --- a/rt-thread/tools/vsc.py +++ b/rt-thread/tools/vsc.py @@ -21,7 +21,7 @@ # Date Author Notes # 2018-05-30 Bernard The first version # 2023-03-03 Supperthomas Add the vscode workspace config file -# 2024-12-13 Supperthomas covert compile_commands.json to vscode workspace file + """ Utils for VSCode """ @@ -30,171 +30,7 @@ import os import json import utils import rtconfig - from utils import _make_path_relative -def find_first_node_with_two_children(tree): - for key, subtree in tree.items(): - if len(subtree) >= 2: - return key, subtree - result = find_first_node_with_two_children(subtree) - if result: - return result - return None, None - - -def filt_tree(tree): - key, subtree = find_first_node_with_two_children(tree) - if key: - return {key: subtree} - return {} - - -def add_path_to_tree(tree, path): - parts = path.split(os.sep) - current_level = tree - for part in parts: - if part not in current_level: - current_level[part] = {} - current_level = current_level[part] - - -def build_tree(paths): - tree = {} - current_working_directory = os.getcwd() - current_folder_name = os.path.basename(current_working_directory) - #过滤异常和不存在的路径 - relative_dirs = [] - for path in paths: - normalized_path = os.path.normpath(path) - try: - rel_path = os.path.relpath(normalized_path, start=current_working_directory) - add_path_to_tree(tree, normalized_path) - except ValueError: - print(f"Remove unexcpect dir:{path}") - - return tree - -def print_tree(tree, indent=''): - for key, subtree in sorted(tree.items()): - print(indent + key) - print_tree(subtree, indent + ' ') - - -def extract_source_dirs(compile_commands): - source_dirs = set() - - for entry in compile_commands: - file_path = os.path.abspath(entry['file']) - - if file_path.endswith('.c'): - dir_path = os.path.dirname(file_path) - source_dirs.add(dir_path) - # command 或者arguments - command = entry.get('command') or entry.get('arguments') - - if isinstance(command, str): - parts = command.split() - else: - parts = command - # 读取-I或者/I - for i, part in enumerate(parts): - if part.startswith('-I'): - include_dir = part[2:] if len(part) > 2 else parts[i + 1] - source_dirs.add(os.path.abspath(include_dir)) - elif part.startswith('/I'): - include_dir = part[2:] if len(part) > 2 else parts[i + 1] - source_dirs.add(os.path.abspath(include_dir)) - #print(f"Source Directories: {source_dirs}") - return sorted(source_dirs) - - -def is_path_in_tree(path, tree): - parts = path.split(os.sep) - current_level = tree - found_first_node = False - root_key = list(tree.keys())[0] - #print(root_key) - #print(path) - index_start = parts.index(root_key) - length = len(parts) - try: - for i in range(index_start, length): - current_level = current_level[parts[i]] - return True - except KeyError: - return False - - -def generate_code_workspace_file(source_dirs,command_json_path,root_path): - current_working_directory = os.getcwd() - current_folder_name = os.path.basename(current_working_directory) - - relative_dirs = [] - for dir_path in source_dirs: - try: - rel_path = os.path.relpath(dir_path, root_path) - relative_dirs.append(rel_path) - except ValueError: - continue - - root_rel_path = os.path.relpath(root_path, current_working_directory) - command_json_path = os.path.relpath(current_working_directory, root_path) + os.sep - workspace_data = { - "folders": [ - { - "path": f"{root_rel_path}" - } - ], - "settings": { - "clangd.arguments": [ - f"--compile-commands-dir={command_json_path}", - "--header-insertion=never" - ], - "files.exclude": {dir.replace('\\','/'): True for dir in sorted(relative_dirs)} - } - } - workspace_filename = f'{current_folder_name}.code-workspace' - # print(workspace_data) - with open(workspace_filename, 'w') as f: - json.dump(workspace_data, f, indent=4) - - print(f'Workspace file {workspace_filename} created.') - -def command_json_to_workspace(root_path,command_json_path): - - with open('build/compile_commands.json', 'r') as f: - compile_commands = json.load(f) - - source_dirs = extract_source_dirs(compile_commands) - tree = build_tree(source_dirs) - #print_tree(tree) - filtered_tree = filt_tree(tree) - print("Filtered Directory Tree:") - #print_tree(filtered_tree) - - # 打印filtered_tree的root节点的相对路径 - root_key = list(filtered_tree.keys())[0] - print(f"Root node relative path: {root_key}") - - # 初始化exclude_fold集合 - exclude_fold = set() - - # os.chdir(root_path) - # 轮询root文件夹下面的每一个文件夹和子文件夹 - for root, dirs, files in os.walk(root_path): - # 检查当前root是否在filtered_tree中 - if not is_path_in_tree(root, filtered_tree): - exclude_fold.add(root) - dirs[:] = [] # 不往下轮询子文件夹 - continue - for dir in dirs: - dir_path = os.path.join(root, dir) - if not is_path_in_tree(dir_path, filtered_tree): - exclude_fold.add(dir_path) - - #print("Excluded Folders:") - #print(exclude_fold) - generate_code_workspace_file(exclude_fold,command_json_path,root_path) def delete_repeatelist(data): temp_dict = set([str(item) for item in data]) @@ -203,7 +39,7 @@ def delete_repeatelist(data): def GenerateCFiles(env): """ - Generate c_cpp_properties.json and build/compile_commands.json files + Generate c_cpp_properties files """ if not os.path.exists('.vscode'): os.mkdir('.vscode') @@ -246,13 +82,6 @@ def GenerateCFiles(env): vsc_file.close() """ - Generate vscode.code-workspace files by build/compile_commands.json - """ - if os.path.exists('build/compile_commands.json'): - - command_json_to_workspace(env['RTT_ROOT'],'build/compile_commands.json') - return - """ Generate vscode.code-workspace files """ vsc_space_file = open('vscode.code-workspace', 'w') @@ -278,62 +107,14 @@ def GenerateCFiles(env): target_path_list = [] for path in path_list: if path['path'] != '.': - normalized_path = path['path'].replace('\\', os.path.sep) - segments = [p for p in normalized_path.split(os.path.sep) if p != '..'] - path['name'] = 'rtthread/' + '/'.join(segments) + path['name'] = 'rtthread/' + '/'.join([p for p in path['path'].split('\\') if p != '..']) json_obj['folders'] = path_list - if os.path.exists('build/compile_commands.json'): - json_obj['settings'] = { - "clangd.arguments": [ - "--compile-commands-dir=.", - "--header-insertion=never" - ] - } vsc_space_file.write(json.dumps(json_obj, ensure_ascii=False, indent=4)) vsc_space_file.close() return -def GenerateProjectFiles(env): - """ - Generate project.json file - """ - if not os.path.exists('.vscode'): - os.mkdir('.vscode') - - project = env['project'] - vsc_file = open('.vscode/project.json', 'w') - if vsc_file: - groups = [] - for group in project: - if len(group['src']) > 0: - item = {} - item['name'] = group['name'] - item['path'] = _make_path_relative(os.getcwd(), group['path']) - item['files'] = [] - - for fn in group['src']: - item['files'].append(str(fn)) - - # append SConscript if exist - if os.path.exists(os.path.join(item['path'], 'SConscript')): - item['files'].append(os.path.join(item['path'], 'SConscript')) - - groups.append(item) - - json_dict = {} - json_dict['RT-Thread'] = env['RTT_ROOT'] - json_dict['Groups'] = groups - - # write groups to project.json - vsc_file.write(json.dumps(json_dict, ensure_ascii=False, indent=4)) - vsc_file.close() - - return - def GenerateVSCode(env): print('Update setting files for VSCode...') - - GenerateProjectFiles(env) GenerateCFiles(env) print('Done!') diff --git a/rt-thread/tools/wizard.py b/rt-thread/tools/wizard.py index 7184d3f..d0f39ae 100644 --- a/rt-thread/tools/wizard.py +++ b/rt-thread/tools/wizard.py @@ -40,7 +40,7 @@ SConscript_com = '''# RT-Thread building script for component from building import * cwd = GetCurrentDir() -src = Glob('*.c') + Glob('*.cpp') + Glob('*.cxx') + Glob('*.cc') +src = Glob('*.c') + Glob('*.cpp') CPPPATH = [cwd] group = DefineGroup('COMPONENT_NAME', src, depend = [''], CPPPATH = CPPPATH) diff --git a/rt-thread/tools/zigbuild.py b/rt-thread/tools/zigbuild.py deleted file mode 100644 index 8811639..0000000 --- a/rt-thread/tools/zigbuild.py +++ /dev/null @@ -1,100 +0,0 @@ -""" -Utils for CMake -Author: https://github.com/klivelinux -""" - -import os -import sys -import re -import utils -import rtconfig -from utils import _make_path_relative - - -def GenerateCFiles(env,project): - info = utils.ProjectInfo(env) - - ARCH = ".thumb" if rtconfig.CPU in ['cortex-m0', 'cortex-m3', 'cortex-m4', 'cortex-m7','cortex-m23','cortex-m33','cortex-m85'] else ".arm" - - CFLAGS = rtconfig.CFLAGS.replace('\\', "/").replace('\"', "\\\"") - LFLAGS = rtconfig.LFLAGS.replace('\\', "/").replace('\"', "\\\"") - - zig_file = open('build.zig', 'w') - if zig_file: - zig_file.write("const std = @import(\"std\");\n\n") - - zig_file.write("const target = std.zig.CrossTarget{\n") - zig_file.write(" .cpu_arch = {},\n".format(ARCH)) - zig_file.write(" .cpu_model = .{{ .explicit = &std.Target.{}.cpu.{} }},\n".format(rtconfig.ARCH, rtconfig.CPU.replace('-', '_'))) - zig_file.write(" .os_tag = .freestanding,\n") - zig_file.write(" .abi = .eabi,\n") - zig_file.write("};\n\n") - - zig_file.write("const c_includes = [_][]const u8{\n") - for i in info['CPPPATH']: - # use relative path - path = _make_path_relative(os.getcwd(), i) - zig_file.write("\t\"{}\",\n".format(path.replace("\\", "/"))) - zig_file.write("};\n\n") - - zig_file.write("const c_sources = [_][]const u8{\n") - for group in project: - for f in group['src']: - # use relative path - path = _make_path_relative(os.getcwd(), os.path.normpath(f.rfile().abspath)) - zig_file.write("\t\"{}\",\n".format(path.replace("\\", "/"))) - zig_file.write("};\n\n") - - zig_file.write("const c_flags = [_][]const u8{\n") - zig_file.write("\t\"-std=c99\",\n") - zig_file.write("\t\"-ffunction-sections\",\n") - zig_file.write("\t\"-fdata-sections\",\n") - # conver CDefines to CFlags - for i in info['CPPDEFINES']: - zig_file.write("\t\"-D{}\",\n".format(i)) - # conver LocalCDefines to CFlags - for group in project: - if 'LOCAL_CPPDEFINES' in group and group['LOCAL_CPPDEFINES']: - for i in group['LOCAL_CPPDEFINES']: - zig_file.write("\t\"-D{}\",\n".format(i)) - zig_file.write("};\n\n") - - zig_file.write("pub fn build(b: *std.Build) void {\n") - zig_file.write(" const optimize = .ReleaseSafe;\n\n") - - zig_file.write(" const elf = b.addExecutable(.{\n") - zig_file.write(" .name = \"rtthread.elf\",\n") - zig_file.write(" .target = b.resolveTargetQuery(target),\n") - zig_file.write(" .optimize = optimize,\n") - zig_file.write(" .strip = false,\n") - zig_file.write(" });\n\n") - zig_file.write(" elf.entry = .{ .symbol_name = \"Reset_Handler\" };\n\n") - - zig_file.write(" elf.addCSourceFiles(.{ .files = &c_sources, .flags = &c_flags });\n") - zig_file.write(" for (c_includes) |include| {\n") - zig_file.write(" elf.addIncludePath(b.path(include));\n") - zig_file.write(" }\n\n") - - # find link script in rtconfig.LFLAGS - LINK_SCRIPT = re.search(r'-T\s*(\S+)', LFLAGS) - zig_file.write(" elf.setLinkerScript(b.path(\"{}\"));\n".format(LINK_SCRIPT.group(1))) - - zig_file.write(" const copy_elf = b.addInstallArtifact(elf, .{});\n") - zig_file.write(" b.default_step.dependOn(©_elf.step);\n\n") - - zig_file.write(" const bin = b.addObjCopy(elf.getEmittedBin(), .{ .format = .bin });\n") - zig_file.write(" bin.step.dependOn(&elf.step);\n") - - zig_file.write(" const copy_bin = b.addInstallBinFile(bin.getOutput(), \"rtthread.bin\");\n") - zig_file.write(" b.default_step.dependOn(©_bin.step);\n") - zig_file.write("}\n") - zig_file.close() - - return - -def ZigBuildProject(env,project): - print('Update setting files for build.zig...') - GenerateCFiles(env,project) - print('Done!') - - return