From f75fb03131198e58beef78db70a3f3ef3ac3f2c8 Mon Sep 17 00:00:00 2001 From: wdfk-prog <1425075683@qq.com> Date: Thu, 25 Sep 2025 10:31:19 +0800 Subject: [PATCH] feat[SPI]: Add SPI device detach function --- .../libraries/HAL_Drivers/drivers/drv_spi.c | 45 ++++++++++++++++++- .../libraries/HAL_Drivers/drivers/drv_spi.h | 3 +- components/drivers/include/drivers/dev_spi.h | 30 ++++++++++++- components/drivers/spi/dev_spi_core.c | 33 ++++++++++++++ 4 files changed, 107 insertions(+), 4 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c index 3a7bf681258..07be86130dd 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024, RT-Thread Development Team + * Copyright (c) 2006-2025 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -25,7 +25,7 @@ #include "drv_config.h" #include -//#define DRV_DEBUG +/*#define DRV_DEBUG*/ #define LOG_TAG "drv.spi" #include @@ -683,6 +683,47 @@ rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, return result; } +/** + * Detach the spi device from SPI bus. + * + * @param device_name the name of the spi device to be detached. + */ +rt_err_t rt_hw_spi_device_detach(const char *device_name) +{ + RT_ASSERT(device_name != RT_NULL); + + rt_err_t result; + struct rt_spi_device *spi_device; + + rt_device_t device = rt_device_find(device_name); + if (device == RT_NULL) + { + LOG_E("SPI device %s not found.", device_name); + return -RT_ERROR; + } + + if (device->type != RT_Device_Class_SPIDevice) + { + LOG_E("%s is not an SPI device.", device_name); + return -RT_ERROR; + } + + spi_device = (struct rt_spi_device *)device; + + result = rt_spi_bus_detach_device_cspin(spi_device); + if (result != RT_EOK) + { + LOG_E("Failed to detach %s from its bus, error code: %d", device_name, result); + return result; + } + + rt_free(spi_device); + + LOG_D("SPI device %s has been detached.", device_name); + + return RT_EOK; +} + #if defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI1_RX_USING_DMA) void SPI1_IRQHandler(void) { diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h index 10b94fbbe8d..746809cad99 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2025 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -23,6 +23,7 @@ extern "C" { #endif rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin); +rt_err_t rt_hw_spi_device_detach(const char *device_name); #ifdef __cplusplus } diff --git a/components/drivers/include/drivers/dev_spi.h b/components/drivers/include/drivers/dev_spi.h index 2cee92748e1..195ba4b6ee5 100644 --- a/components/drivers/include/drivers/dev_spi.h +++ b/components/drivers/include/drivers/dev_spi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2025 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -349,6 +349,19 @@ rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device, const char *bus_name, void *user_data); +/** + * @brief Detach a device from the SPI bus. + * + * This function serves as the high-level API to detach a SPI device from its bus. + * It unregisters the device from the device framework and ensures all associated + * resources, such as the chip select pin, are properly released by calling + * the underlying implementation. + * + * @param device The SPI device to be detached. + * + * @return rt_err_t The result of the operation. RT_EOK on success, otherwise an error code. + */ +rt_err_t rt_spi_bus_detach_device(struct rt_spi_device *device); /** * @brief attach a device on SPI bus with CS pin @@ -367,6 +380,21 @@ rt_err_t rt_spi_bus_attach_device_cspin(struct rt_spi_device *device, rt_base_t cs_pin, void *user_data); +/** + * @brief Detach a device from the SPI bus and release its CS pin. + * + * This function provides the low-level implementation for detaching a device + * from the SPI bus. It specifically handles the operations for the chip select (CS) + * pin, resetting it to input mode to release it. This function is typically + * called by the higher-level rt_spi_bus_detach_device() and should not be + * called directly by the user application. + * + * @param device The SPI device to be detached. + * + * @return rt_err_t The result of the operation. RT_EOK on success, otherwise an error code. + */ +rt_err_t rt_spi_bus_detach_device_cspin(struct rt_spi_device *device); + /** * @brief Reconfigure the SPI bus for the specified device. * diff --git a/components/drivers/spi/dev_spi_core.c b/components/drivers/spi/dev_spi_core.c index 53bb7284faa..42f829447ab 100644 --- a/components/drivers/spi/dev_spi_core.c +++ b/components/drivers/spi/dev_spi_core.c @@ -123,6 +123,34 @@ rt_err_t rt_spi_bus_attach_device_cspin(struct rt_spi_device *device, return -RT_ERROR; } +rt_err_t rt_spi_bus_detach_device_cspin(struct rt_spi_device *device) +{ + rt_err_t result; + + RT_ASSERT(device != RT_NULL); + + result = rt_device_unregister(&device->parent); + if (result != RT_EOK) + { + LOG_E("Failed to unregister spi device, result: %d", result); + return result; + } + + if (device->bus != RT_NULL && device->bus->owner == device) + { + device->bus->owner = RT_NULL; + } + + if (device->cs_pin != PIN_NONE) + { + rt_pin_mode(device->cs_pin, PIN_MODE_INPUT); + } + + device->bus = RT_NULL; + + return RT_EOK; +} + rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device, const char *name, const char *bus_name, @@ -131,6 +159,11 @@ rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device, return rt_spi_bus_attach_device_cspin(device, name, bus_name, PIN_NONE, user_data); } +rt_err_t rt_spi_bus_detach_device(struct rt_spi_device *device) +{ + return rt_spi_bus_detach_device_cspin(device); +} + rt_err_t rt_spi_bus_configure(struct rt_spi_device *device) { rt_err_t result = -RT_ERROR;