Browse Source

优化mxca153 adc驱动,支持电压读取

Rbb666 11 months ago
parent
commit
59f1146fae

+ 156 - 0
bsp/nxp/mcx/mcxa/Libraries/drivers/drv_adc.c

@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2006-2024, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-05-16     shelton      first version
+ * 2024-07-21     liujianhua   added mcxa153
+ *
+ */
+#include <rtconfig.h>
+#include <rtdevice.h>
+#include "fsl_lpadc.h"
+#include "fsl_spc.h"
+
+#ifdef RT_USING_ADC
+
+#define DEFAULT_HW_AVG          (kLPADC_HardwareAverageCount4)
+#define DEFAULT_SAMPLE_TIME     (kLPADC_SampleTimeADCK7)
+
+/* by default: cmd = chl+1 */
+static uint8_t adc_chl2cmd[] =  {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+static uint8_t adc_cmd2trig[] = {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3};
+
+struct mcx_adc
+{
+    struct rt_adc_device        mcx_adc_device;
+    ADC_Type                   *adc_base;
+    clock_attach_id_t           clock_attach_id;
+    clock_div_name_t            clock_div_name;
+    uint8_t                     clock_div;
+    uint8_t                     referenceVoltageSource; /* 00, VREFH reference pin, 01, ANA_7(VREFI/VREFO) pin, 10, VDDA supply pin */
+    uint8_t                     resolution;
+    char *name;
+};
+
+static struct mcx_adc mcx_adc_obj[] =
+{
+#ifdef BSP_USING_ADC0
+    {
+        .adc_base = ADC0,
+        .clock_attach_id = kFRO12M_to_ADC0,
+        .clock_div_name = kCLOCK_DivADC0,
+        .clock_div = 2,
+        .referenceVoltageSource = 0,
+        .name = "adc0",
+    },
+#endif
+};
+
+static rt_err_t a153_adc_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled)
+{
+    struct mcx_adc *adc = (struct mcx_adc *)device->parent.user_data;
+
+    if (enabled)
+    {
+        lpadc_config_t adc_config;
+        LPADC_GetDefaultConfig(&adc_config);
+        adc_config.enableAnalogPreliminary = true;
+        adc_config.referenceVoltageSource = adc->referenceVoltageSource;
+        adc_config.conversionAverageMode = kLPADC_ConversionAverage128; /* this is for calibartion avg mode */
+        adc_config.powerLevelMode = kLPADC_PowerLevelAlt4;
+        adc_config.enableConvPause       = false;
+        adc_config.convPauseDelay        = 0;
+
+        LPADC_Init(adc->adc_base, &adc_config);
+        LPADC_DoOffsetCalibration(adc->adc_base);
+        LPADC_DoAutoCalibration(adc->adc_base);
+
+        lpadc_conv_command_config_t cmd_cfg;
+        LPADC_GetDefaultConvCommandConfig(&cmd_cfg);
+
+        cmd_cfg.channelNumber = channel;
+        cmd_cfg.conversionResolutionMode = kLPADC_ConversionResolutionHigh;
+        cmd_cfg.hardwareAverageMode = DEFAULT_HW_AVG;
+        cmd_cfg.loopCount = 0;
+        cmd_cfg.sampleTimeMode = DEFAULT_SAMPLE_TIME;
+        cmd_cfg.sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
+        LPADC_SetConvCommandConfig(adc->adc_base, adc_chl2cmd[channel], &cmd_cfg);
+
+        lpadc_conversion_resolution_mode_t resolution_mode = cmd_cfg.conversionResolutionMode;
+        if (resolution_mode == kLPADC_ConversionResolutionHigh)
+            adc->resolution = 16;
+        else
+            adc->resolution = 0;
+
+        lpadc_conv_trigger_config_t trig_config;
+        LPADC_GetDefaultConvTriggerConfig(&trig_config);
+        trig_config.targetCommandId       = adc_chl2cmd[channel];
+        trig_config.enableHardwareTrigger = false;
+        LPADC_SetConvTriggerConfig(adc->adc_base, adc_cmd2trig[trig_config.targetCommandId], &trig_config); /* Configurate the trigger0. */
+    }
+    else
+    {
+        LPADC_Deinit(adc->adc_base);
+    }
+    return RT_EOK;
+}
+
+static rt_int16_t a153_get_vref(struct rt_adc_device *device)
+{
+    if (device == RT_NULL)
+        return -RT_ERROR;
+
+    return 3300;
+}
+
+static rt_err_t a153_get_adc_value(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value)
+{
+    struct mcx_adc *adc = (struct mcx_adc *)device->parent.user_data;
+
+    lpadc_conv_result_t mLpadcResultConfigStruct;
+
+    LPADC_DoSoftwareTrigger(adc->adc_base, 1 << (adc_cmd2trig[adc_chl2cmd[channel]])); /* 1U is trigger0 mask. */
+    while (!LPADC_GetConvResult(adc->adc_base, &mLpadcResultConfigStruct));
+    *value = mLpadcResultConfigStruct.convValue;
+    return RT_EOK;
+}
+
+static rt_uint8_t a153_adc_get_resolution(struct rt_adc_device *device)
+{
+    RT_ASSERT(device != RT_NULL);
+    struct mcx_adc *adc = (struct mcx_adc *)device->parent.user_data;
+    return adc->resolution;
+}
+
+static const struct rt_adc_ops mcx_adc_ops =
+{
+    .get_resolution = a153_adc_get_resolution,
+    .enabled = a153_adc_enabled,
+    .convert = a153_get_adc_value,
+    .get_vref = a153_get_vref,
+};
+
+static int rt_hw_adc_init(void)
+{
+    int result = RT_EOK;
+    int i = 0;
+
+    /* Enable VREF */
+    SPC0->ACTIVE_CFG1 |= 0xFFFFFFFF;
+    SPC_SetActiveModeBandgapModeConfig(SPC0, kSPC_BandgapEnabledBufferEnabled);
+
+    for (i = 0; i < sizeof(mcx_adc_obj) / sizeof(mcx_adc_obj[0]); i++)
+    {
+        CLOCK_SetClockDiv(mcx_adc_obj[i].clock_div_name, mcx_adc_obj[i].clock_div);
+        CLOCK_AttachClk(mcx_adc_obj[i].clock_attach_id);
+
+        rt_hw_adc_register(&mcx_adc_obj[i].mcx_adc_device, mcx_adc_obj[i].name, &mcx_adc_ops, &mcx_adc_obj[i]);
+    }
+
+    return result;
+}
+INIT_BOARD_EXPORT(rt_hw_adc_init);
+#endif /* BSP_USING_ADC */

+ 2 - 18
bsp/nxp/mcx/mcxa/frdm-mcxa153/board/Kconfig

@@ -69,25 +69,9 @@ menu "On-chip Peripheral Drivers"
             default y
 
             if BSP_USING_ADC
-                config BSP_USING_ADC0_CH0
-                    bool "Enable ADC0 Channel0"
+                config BSP_USING_ADC0
+                    bool "Enable ADC0"
                     default y
-
-                config BSP_USING_ADC0_CH1
-                    bool "Enable ADC0 Channel1"
-                    default n
-
-                config BSP_USING_ADC0_CH8
-                    bool "Enable ADC0 Channel8"
-                    default n
-        
-                config BSP_USING_ADC0_CH13
-                    bool "Enable ADC0 Channel13"
-                    default n
-
-                config BSP_USING_ADC0_CH26
-                    bool "Enable ADC0 Channel26"
-                    default n
             endif
 
     config BSP_USING_FLASH