Lines Matching +full:hold +full:- +full:time +full:- +full:2 +full:x

4  * SPDX-License-Identifier: Apache-2.0
69 const struct adc_sam_config *const cfg = dev->config; in adc_sam_channel_setup()
70 Adc *const adc = cfg->regs; in adc_sam_channel_setup()
72 uint8_t channel_id = channel_cfg->channel_id; in adc_sam_channel_setup()
74 if (channel_cfg->differential) { in adc_sam_channel_setup()
75 if (channel_id != (channel_cfg->input_positive / 2U) in adc_sam_channel_setup()
76 || channel_id != (channel_cfg->input_negative / 2U)) { in adc_sam_channel_setup()
78 return -EINVAL; in adc_sam_channel_setup()
81 if (channel_id != channel_cfg->input_positive) { in adc_sam_channel_setup()
82 LOG_ERR("Invalid ADC single-ended input for channel %u", channel_id); in adc_sam_channel_setup()
83 return -EINVAL; in adc_sam_channel_setup()
87 if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) { in adc_sam_channel_setup()
88 LOG_ERR("Invalid ADC channel acquisition time"); in adc_sam_channel_setup()
89 return -EINVAL; in adc_sam_channel_setup()
92 if (channel_cfg->reference != ADC_REF_EXTERNAL0) { in adc_sam_channel_setup()
93 LOG_ERR("Invalid ADC channel reference (%d)", channel_cfg->reference); in adc_sam_channel_setup()
94 return -EINVAL; in adc_sam_channel_setup()
97 /* Enable internal temperature sensor (channel 15 / single-ended) */ in adc_sam_channel_setup()
98 if (channel_cfg->channel_id == SAM_ADC_TEMP_CHANNEL) { in adc_sam_channel_setup()
99 adc->ADC_ACR |= ADC_ACR_TSON; in adc_sam_channel_setup()
103 if (channel_cfg->differential) { in adc_sam_channel_setup()
104 adc->ADC_COR |= (ADC_COR_DIFF0 | ADC_COR_DIFF1) << (channel_id * 2U); in adc_sam_channel_setup()
106 adc->ADC_COR &= ~((ADC_COR_DIFF0 | ADC_COR_DIFF1) << (channel_id * 2U)); in adc_sam_channel_setup()
110 adc->ADC_CGR &= ~(ADC_CGR_GAIN0_Msk << (channel_id * 2U)); in adc_sam_channel_setup()
112 switch (channel_cfg->gain) { in adc_sam_channel_setup()
114 if (!channel_cfg->differential) { in adc_sam_channel_setup()
115 LOG_ERR("ADC 1/2x gain only allowed for differential channel"); in adc_sam_channel_setup()
116 return -EINVAL; in adc_sam_channel_setup()
121 adc->ADC_CGR |= ADC_CGR_GAIN0(1) << (channel_id * 2U); in adc_sam_channel_setup()
124 adc->ADC_CGR |= ADC_CGR_GAIN0(2) << (channel_id * 2U); in adc_sam_channel_setup()
127 if (channel_cfg->differential) { in adc_sam_channel_setup()
128 LOG_ERR("ADC 4x gain only allowed for single-ended channel"); in adc_sam_channel_setup()
129 return -EINVAL; in adc_sam_channel_setup()
131 adc->ADC_CGR |= ADC_CGR_GAIN0(3) << (channel_id * 2U); in adc_sam_channel_setup()
134 LOG_ERR("Invalid ADC channel gain (%d)", channel_cfg->gain); in adc_sam_channel_setup()
135 return -EINVAL; in adc_sam_channel_setup()
143 const struct adc_sam_config *const cfg = dev->config; in adc_sam_start_conversion()
144 Adc *const adc = cfg->regs; in adc_sam_start_conversion()
146 adc->ADC_CR = ADC_CR_START; in adc_sam_start_conversion()
156 const struct adc_sam_config *const cfg = data->dev->config; in adc_context_start_sampling()
157 Adc *const adc = cfg->regs; in adc_context_start_sampling()
159 data->num_active_channels = count_bits(ctx->sequence.channels); in adc_context_start_sampling()
162 adc->ADC_CHDR = 0xffff; in adc_context_start_sampling()
165 adc->ADC_CHER = ctx->sequence.channels; in adc_context_start_sampling()
167 LOG_DBG("Starting conversion for %u channels", data->num_active_channels); in adc_context_start_sampling()
169 adc_sam_start_conversion(data->dev); in adc_context_start_sampling()
177 data->buffer = data->repeat_buffer; in adc_context_update_buffer_pointer()
186 if (sequence->options) { in check_buffer_size()
187 needed_buffer_size *= (1 + sequence->options->extra_samplings); in check_buffer_size()
190 if (sequence->buffer_size < needed_buffer_size) { in check_buffer_size()
192 sequence->buffer_size, needed_buffer_size); in check_buffer_size()
193 return -ENOMEM; in check_buffer_size()
202 struct adc_sam_data *data = dev->data; in start_read()
203 uint32_t channels = sequence->channels; in start_read()
207 * a non-existing one is selected). in start_read()
212 return -EINVAL; in start_read()
215 if (sequence->oversampling != 0U) { in start_read()
217 return -EINVAL; in start_read()
220 if (sequence->resolution != 12U) { in start_read()
221 LOG_ERR("ADC resolution %d is not valid", sequence->resolution); in start_read()
222 return -EINVAL; in start_read()
225 data->num_active_channels = count_bits(channels); in start_read()
227 error = check_buffer_size(sequence, data->num_active_channels); in start_read()
232 data->buffer = sequence->buffer; in start_read()
233 data->repeat_buffer = sequence->buffer; in start_read()
240 adc_context_start_read(&data->ctx, sequence); in start_read()
242 return adc_context_wait_for_completion(&data->ctx); in start_read()
248 struct adc_sam_data *data = dev->data; in adc_sam_read()
251 adc_context_lock(&data->ctx, false, NULL); in adc_sam_read()
253 adc_context_release(&data->ctx, error); in adc_sam_read()
260 const struct adc_sam_config *const cfg = dev->config; in adc_sam_isr()
261 struct adc_sam_data *data = dev->data; in adc_sam_isr()
262 Adc *const adc = cfg->regs; in adc_sam_isr()
266 if (adc->ADC_ISR & ADC_ISR_DRDY) { in adc_sam_isr()
267 result = adc->ADC_LCDR & ADC_LCDR_LDATA_Msk; in adc_sam_isr()
269 *data->buffer++ = result; in adc_sam_isr()
270 data->num_active_channels--; in adc_sam_isr()
272 if (data->num_active_channels == 0) { in adc_sam_isr()
274 adc_context_on_sampling_done(&data->ctx, dev); in adc_sam_isr()
283 const struct adc_sam_config *const cfg = dev->config; in adc_sam_init()
284 struct adc_sam_data *data = dev->data; in adc_sam_init()
285 Adc *const adc = cfg->regs; in adc_sam_init()
292 (clock_control_subsys_t)&cfg->clock_cfg, in adc_sam_init()
296 return -ENODEV; in adc_sam_init()
300 frequency = frequency / 2U / (cfg->prescaler + 1U); in adc_sam_init()
303 return -EINVAL; in adc_sam_init()
307 conv_periods = MAX(20U, cfg->tracking_time + 6U); in adc_sam_init()
313 adc->ADC_CR = ADC_CR_SWRST; in adc_sam_init()
316 adc->ADC_MR = 0U; in adc_sam_init()
319 adc->ADC_PTCR = ADC_PTCR_RXTDIS | ADC_PTCR_TXTDIS; in adc_sam_init()
320 adc->ADC_RCR = 0U; in adc_sam_init()
321 adc->ADC_RNCR = 0U; in adc_sam_init()
324 adc->ADC_MR = ADC_MR_PRESCAL(cfg->prescaler) in adc_sam_init()
325 | ADC_MR_STARTUP(cfg->startup_time) in adc_sam_init()
326 | ADC_MR_SETTLING(cfg->settling_time) in adc_sam_init()
327 | ADC_MR_TRACKTIM(cfg->tracking_time) in adc_sam_init()
328 | ADC_MR_TRANSFER(2U) /* Should be 2 to guarantee the optimal hold time. */ in adc_sam_init()
336 adc->ADC_ACR = ADC_ACR_IBCTL(frequency < 500000U ? 0U : 1U); in adc_sam_init()
340 (clock_control_subsys_t)&cfg->clock_cfg); in adc_sam_init()
343 return -ENODEV; in adc_sam_init()
346 ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); in adc_sam_init()
351 cfg->config_func(dev); in adc_sam_init()
354 adc->ADC_IER = ADC_IER_DRDY; in adc_sam_init()
356 data->dev = dev; in adc_sam_init()
358 adc_context_unlock_unconditionally(&data->ctx); in adc_sam_init()
368 struct adc_sam_data *data = dev->data; in adc_sam_read_async()
371 adc_context_lock(&data->ctx, true, async); in adc_sam_read_async()
373 adc_context_release(&data->ctx, error); in adc_sam_read_async()