Browse Source

[adc] 支持adc框架获取BSP的ADC分辨率 (#5853)

Man, Jianting (Meco) 3 years ago
parent
commit
c2a0995545

+ 26 - 2
bsp/stm32/libraries/HAL_Drivers/drv_adc.c

@@ -70,6 +70,29 @@ static rt_err_t stm32_adc_enabled(struct rt_adc_device *device, rt_uint32_t chan
     return RT_EOK;
 }
 
+static rt_uint8_t stm32_adc_get_resolution(struct rt_adc_device *device)
+{
+    ADC_HandleTypeDef *stm32_adc_handler;
+
+    RT_ASSERT(device != RT_NULL);
+
+    stm32_adc_handler = device->parent.user_data;
+
+    switch(stm32_adc_handler->Init.Resolution)
+    {
+        case ADC_RESOLUTION_12B:
+            return 12;
+        case ADC_RESOLUTION_10B:
+            return 10;
+        case ADC_RESOLUTION_8B:
+            return 8;
+        case ADC_RESOLUTION_6B:
+            return 6;
+        default:
+            return 0;
+    }
+}
+
 static rt_uint32_t stm32_adc_get_channel(rt_uint32_t channel)
 {
     rt_uint32_t stm32_channel = 0;
@@ -147,7 +170,7 @@ static rt_uint32_t stm32_adc_get_channel(rt_uint32_t channel)
     return stm32_channel;
 }
 
-static rt_err_t stm32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
+static rt_err_t stm32_adc_get_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
 {
     ADC_ChannelConfTypeDef ADC_ChanConf;
     ADC_HandleTypeDef *stm32_adc_handler;
@@ -260,7 +283,8 @@ static rt_err_t stm32_get_adc_value(struct rt_adc_device *device, rt_uint32_t ch
 static const struct rt_adc_ops stm_adc_ops =
 {
     .enabled = stm32_adc_enabled,
-    .convert = stm32_get_adc_value,
+    .convert = stm32_adc_get_value,
+    .get_resolution = stm32_adc_get_resolution,
 };
 
 static int stm32_adc_init(void)

+ 2 - 0
components/drivers/include/drivers/adc.h

@@ -18,6 +18,7 @@ struct rt_adc_ops
 {
     rt_err_t (*enabled)(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled);
     rt_err_t (*convert)(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value);
+    rt_uint8_t (*get_resolution)(struct rt_adc_device *device);
 };
 
 struct rt_adc_device
@@ -31,6 +32,7 @@ typedef enum
 {
     RT_ADC_CMD_ENABLE = RT_DEVICE_CTRL_BASE(ADC) + 1,
     RT_ADC_CMD_DISABLE = RT_DEVICE_CTRL_BASE(ADC) + 2,
+    RT_ADC_CMD_GET_RESOLUTION = RT_DEVICE_CTRL_BASE(ADC) + 3,
 } rt_adc_cmd_t;
 
 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);

+ 15 - 7
components/drivers/misc/adc.c

@@ -41,21 +41,27 @@ static rt_size_t _adc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_
 
 static rt_err_t _adc_control(rt_device_t dev, int cmd, void *args)
 {
-    rt_err_t result = RT_EOK;
+    rt_err_t result = -RT_EINVAL;
     rt_adc_device_t adc = (struct rt_adc_device *)dev;
 
-    if (adc->ops->enabled == RT_NULL)
-    {
-        return -RT_ENOSYS;
-    }
-    if (cmd == RT_ADC_CMD_ENABLE)
+    if (cmd == RT_ADC_CMD_ENABLE && adc->ops->enabled)
     {
         result = adc->ops->enabled(adc, (rt_uint32_t)args, RT_TRUE);
     }
-    else if (cmd == RT_ADC_CMD_DISABLE)
+    else if (cmd == RT_ADC_CMD_DISABLE && adc->ops->enabled)
     {
         result = adc->ops->enabled(adc, (rt_uint32_t)args, RT_FALSE);
     }
+    else if (cmd == RT_ADC_CMD_GET_RESOLUTION && adc->ops->get_resolution)
+    {
+        rt_uint8_t resolution = adc->ops->get_resolution(adc);
+        if(resolution != 0)
+        {
+            *((rt_uint8_t*)args) = resolution;
+            LOG_D("ADC resolution:%d", resolution);
+            result = RT_EOK;
+        }
+    }
 
     return result;
 }
@@ -115,6 +121,7 @@ rt_err_t rt_adc_enable(rt_adc_device_t dev, rt_uint32_t channel)
     rt_err_t result = RT_EOK;
 
     RT_ASSERT(dev);
+
     if (dev->ops->enabled != RT_NULL)
     {
         result = dev->ops->enabled(dev, channel, RT_TRUE);
@@ -132,6 +139,7 @@ rt_err_t rt_adc_disable(rt_adc_device_t dev, rt_uint32_t channel)
     rt_err_t result = RT_EOK;
 
     RT_ASSERT(dev);
+
     if (dev->ops->enabled != RT_NULL)
     {
         result = dev->ops->enabled(dev, channel, RT_FALSE);