Просмотр исходного кода

feat[SPI]: Add SPI device detach function

wdfk-prog 3 месяцев назад
Родитель
Сommit
7e5cd48360

+ 43 - 2
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 <string.h>
 
-//#define DRV_DEBUG
+/*#define DRV_DEBUG*/
 #define LOG_TAG              "drv.spi"
 #include <drv_log.h>
 
@@ -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)
 {

+ 2 - 1
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
 }

+ 29 - 1
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.
  *

+ 33 - 0
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;