Skip to content

Commit fefb472

Browse files
ZhaoxiangJinaescolar
authored andcommitted
drivers: lpadc/adc_mcux_lpadc/: enable nxp lpadc acquisition time feature
Enable nxp lpadc driver acquisition time feature Signed-off-by: Zhaoxiang Jin <[email protected]>
1 parent a30695b commit fefb472

File tree

1 file changed

+72
-11
lines changed

1 file changed

+72
-11
lines changed

drivers/adc/adc_mcux_lpadc.c

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023 NXP
2+
* Copyright 2023-2024 NXP
33
* Copyright (c) 2020 Toby Firth
44
*
55
* Based on adc_mcux_adc16.c and adc_mcux_adc12.c, which are:
@@ -14,14 +14,14 @@
1414
#include <errno.h>
1515
#include <zephyr/drivers/adc.h>
1616
#include <zephyr/sys/util.h>
17-
#include <fsl_lpadc.h>
1817
#include <zephyr/drivers/regulator.h>
19-
18+
#include <zephyr/drivers/clock_control.h>
2019
#include <zephyr/drivers/pinctrl.h>
2120

2221
#define LOG_LEVEL CONFIG_ADC_LOG_LEVEL
2322
#include <zephyr/logging/log.h>
2423
#include <zephyr/irq.h>
24+
#include <fsl_lpadc.h>
2525
LOG_MODULE_REGISTER(nxp_mcux_lpadc);
2626

2727
/*
@@ -35,7 +35,6 @@ LOG_MODULE_REGISTER(nxp_mcux_lpadc);
3535
#define ADC_CONTEXT_USES_KERNEL_TIMER
3636
#include "adc_context.h"
3737

38-
3938
struct mcux_lpadc_config {
4039
ADC_Type *base;
4140
lpadc_reference_voltage_source_t voltage_ref;
@@ -46,6 +45,8 @@ struct mcux_lpadc_config {
4645
void (*irq_config_func)(const struct device *dev);
4746
const struct pinctrl_dev_config *pincfg;
4847
const struct device **ref_supplies;
48+
const struct device *clock_dev;
49+
clock_control_subsys_t clock_subsys;
4950
};
5051

5152
struct mcux_lpadc_data {
@@ -57,13 +58,70 @@ struct mcux_lpadc_data {
5758
lpadc_conv_command_config_t cmd_config[CONFIG_LPADC_CHANNEL_COUNT];
5859
};
5960

61+
static int mcux_lpadc_acquisition_time_setup(const struct device *dev, uint16_t acq_time,
62+
lpadc_conv_command_config_t *cmd)
63+
{
64+
const struct mcux_lpadc_config *config = dev->config;
65+
uint32_t adc_freq_hz = 0;
66+
uint32_t conversion_factor = 0;
67+
uint32_t acquisition_time_value = ADC_ACQ_TIME_VALUE(acq_time);
68+
uint8_t acquisition_time_unit = ADC_ACQ_TIME_UNIT(acq_time);
69+
70+
if (ADC_ACQ_TIME_DEFAULT == acquisition_time_value) {
71+
return 0;
72+
}
73+
74+
/* If the acquisition time is expressed in ADC ticks, then directly compare
75+
* the acquisition time with configuration items (3, 5, 7, etc. ADC ticks)
76+
* supported by the LPADC. The conversion factor is set to 1 (means do not need
77+
* to convert configuration items from ADC ticks to nanoseconds).
78+
* If the acquisition time is expressed in microseconds or nanoseconds, First
79+
* calculate the ADC cycle based on the ADC clock, then convert the configuration
80+
* items supported by LPADC into nanoseconds, and finally compare the acquisition
81+
* time with configuration items. The conversion factor is equal to the ADC cycle
82+
* (means convert configuration items from ADC ticks to nanoseconds).
83+
*/
84+
if (ADC_ACQ_TIME_TICKS == acquisition_time_unit) {
85+
conversion_factor = 1;
86+
} else {
87+
if (clock_control_get_rate(config->clock_dev, config->clock_subsys, &adc_freq_hz)) {
88+
LOG_ERR("Get clock rate failed");
89+
return -EINVAL;
90+
}
91+
92+
conversion_factor = 1000000000 / adc_freq_hz;
93+
94+
if (ADC_ACQ_TIME_MICROSECONDS == acquisition_time_unit) {
95+
acquisition_time_value *= 1000;
96+
}
97+
}
98+
99+
if ((3 * conversion_factor) >= acquisition_time_value) {
100+
cmd->sampleTimeMode = kLPADC_SampleTimeADCK3;
101+
} else if ((5 * conversion_factor) >= acquisition_time_value) {
102+
cmd->sampleTimeMode = kLPADC_SampleTimeADCK5;
103+
} else if ((7 * conversion_factor) >= acquisition_time_value) {
104+
cmd->sampleTimeMode = kLPADC_SampleTimeADCK7;
105+
} else if ((11 * conversion_factor) >= acquisition_time_value) {
106+
cmd->sampleTimeMode = kLPADC_SampleTimeADCK11;
107+
} else if ((19 * conversion_factor) >= acquisition_time_value) {
108+
cmd->sampleTimeMode = kLPADC_SampleTimeADCK19;
109+
} else if ((35 * conversion_factor) >= acquisition_time_value) {
110+
cmd->sampleTimeMode = kLPADC_SampleTimeADCK35;
111+
} else if ((67 * conversion_factor) >= acquisition_time_value) {
112+
cmd->sampleTimeMode = kLPADC_SampleTimeADCK67;
113+
} else if ((131 * conversion_factor) >= acquisition_time_value) {
114+
cmd->sampleTimeMode = kLPADC_SampleTimeADCK131;
115+
} else {
116+
return -EINVAL;
117+
}
60118

119+
return 0;
120+
}
61121

62122
static int mcux_lpadc_channel_setup(const struct device *dev,
63123
const struct adc_channel_cfg *channel_cfg)
64124
{
65-
66-
67125
struct mcux_lpadc_data *data = dev->data;
68126
lpadc_conv_command_config_t *cmd;
69127
uint8_t channel_side;
@@ -75,11 +133,6 @@ static int mcux_lpadc_channel_setup(const struct device *dev,
75133
return -EINVAL;
76134
}
77135

78-
if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
79-
LOG_ERR("Invalid channel acquisition time");
80-
return -EINVAL;
81-
}
82-
83136
/* Select ADC CMD register to configure based off channel ID */
84137
cmd = &data->cmd_config[channel_cfg->channel_id];
85138

@@ -93,6 +146,12 @@ static int mcux_lpadc_channel_setup(const struct device *dev,
93146

94147
LPADC_GetDefaultConvCommandConfig(cmd);
95148

149+
/* Configure LPADC acquisition time. */
150+
if (mcux_lpadc_acquisition_time_setup(dev, channel_cfg->acquisition_time, cmd)) {
151+
LOG_ERR("LPADC acquisition time setting failed");
152+
return -EINVAL;
153+
}
154+
96155
if (channel_cfg->differential) {
97156
/* Channel pairs must match in differential mode */
98157
if ((ADC_CMDL_ADCH(channel_cfg->input_positive)) !=
@@ -493,6 +552,8 @@ static const struct adc_driver_api mcux_lpadc_driver_api = {
493552
.irq_config_func = mcux_lpadc_config_func_##n, \
494553
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
495554
.ref_supplies = mcux_lpadc_ref_supplies_##n, \
555+
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
556+
.clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name),\
496557
}; \
497558
static struct mcux_lpadc_data mcux_lpadc_data_##n = { \
498559
ADC_CONTEXT_INIT_TIMER(mcux_lpadc_data_##n, ctx), \

0 commit comments

Comments
 (0)