mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
screamer
Date:
Tue Aug 02 14:07:36 2016 +0000
Revision:
144:423e1876dc07
Parent:
18:da299f395b9e
Added targets.json file for the supported targets in the release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 15:a81a8d6c1dfe 1 /**
mbed_official 15:a81a8d6c1dfe 2 * \file
mbed_official 15:a81a8d6c1dfe 3 *
mbed_official 15:a81a8d6c1dfe 4 * \brief SAM Peripheral Analog-to-Digital Converter Driver
mbed_official 15:a81a8d6c1dfe 5 *
mbed_official 15:a81a8d6c1dfe 6 * Copyright (C) 2012-2015 Atmel Corporation. All rights reserved.
mbed_official 15:a81a8d6c1dfe 7 *
mbed_official 15:a81a8d6c1dfe 8 * \asf_license_start
mbed_official 15:a81a8d6c1dfe 9 *
mbed_official 15:a81a8d6c1dfe 10 * \page License
mbed_official 15:a81a8d6c1dfe 11 *
mbed_official 15:a81a8d6c1dfe 12 * Redistribution and use in source and binary forms, with or without
mbed_official 15:a81a8d6c1dfe 13 * modification, are permitted provided that the following conditions are met:
mbed_official 15:a81a8d6c1dfe 14 *
mbed_official 15:a81a8d6c1dfe 15 * 1. Redistributions of source code must retain the above copyright notice,
mbed_official 15:a81a8d6c1dfe 16 * this list of conditions and the following disclaimer.
mbed_official 15:a81a8d6c1dfe 17 *
mbed_official 15:a81a8d6c1dfe 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
mbed_official 15:a81a8d6c1dfe 19 * this list of conditions and the following disclaimer in the documentation
mbed_official 15:a81a8d6c1dfe 20 * and/or other materials provided with the distribution.
mbed_official 15:a81a8d6c1dfe 21 *
mbed_official 15:a81a8d6c1dfe 22 * 3. The name of Atmel may not be used to endorse or promote products derived
mbed_official 15:a81a8d6c1dfe 23 * from this software without specific prior written permission.
mbed_official 15:a81a8d6c1dfe 24 *
mbed_official 15:a81a8d6c1dfe 25 * 4. This software may only be redistributed and used in connection with an
mbed_official 15:a81a8d6c1dfe 26 * Atmel microcontroller product.
mbed_official 15:a81a8d6c1dfe 27 *
mbed_official 15:a81a8d6c1dfe 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
mbed_official 15:a81a8d6c1dfe 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
mbed_official 15:a81a8d6c1dfe 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
mbed_official 15:a81a8d6c1dfe 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
mbed_official 15:a81a8d6c1dfe 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
mbed_official 15:a81a8d6c1dfe 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
mbed_official 15:a81a8d6c1dfe 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
mbed_official 15:a81a8d6c1dfe 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
mbed_official 15:a81a8d6c1dfe 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
mbed_official 15:a81a8d6c1dfe 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
mbed_official 15:a81a8d6c1dfe 38 * POSSIBILITY OF SUCH DAMAGE.
mbed_official 15:a81a8d6c1dfe 39 *
mbed_official 15:a81a8d6c1dfe 40 * \asf_license_stop
mbed_official 15:a81a8d6c1dfe 41 *
mbed_official 15:a81a8d6c1dfe 42 */
mbed_official 15:a81a8d6c1dfe 43 /*
mbed_official 15:a81a8d6c1dfe 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
mbed_official 15:a81a8d6c1dfe 45 */
mbed_official 15:a81a8d6c1dfe 46
mbed_official 15:a81a8d6c1dfe 47 #include "adc.h"
mbed_official 15:a81a8d6c1dfe 48
mbed_official 15:a81a8d6c1dfe 49 #if SAMD20
mbed_official 15:a81a8d6c1dfe 50 /* The Die revision D number */
mbed_official 15:a81a8d6c1dfe 51 #define REVISON_D_NUM 3
mbed_official 15:a81a8d6c1dfe 52 #endif
mbed_official 15:a81a8d6c1dfe 53
mbed_official 15:a81a8d6c1dfe 54 /**
mbed_official 15:a81a8d6c1dfe 55 * \brief Initializes an ADC configuration structure to defaults
mbed_official 15:a81a8d6c1dfe 56 *
mbed_official 15:a81a8d6c1dfe 57 * Initializes a given ADC configuration struct to a set of known default
mbed_official 15:a81a8d6c1dfe 58 * values. This function should be called on any new instance of the
mbed_official 15:a81a8d6c1dfe 59 * configuration struct before being modified by the user application.
mbed_official 15:a81a8d6c1dfe 60 *
mbed_official 15:a81a8d6c1dfe 61 * The default configuration is as follows:
mbed_official 15:a81a8d6c1dfe 62 * \li GCLK generator 0 (GCLK main) clock source
mbed_official 15:a81a8d6c1dfe 63 * \li 1V from internal bandgap reference
mbed_official 15:a81a8d6c1dfe 64 * \li Div 4 clock prescaler
mbed_official 15:a81a8d6c1dfe 65 * \li 12-bit resolution
mbed_official 15:a81a8d6c1dfe 66 * \li Window monitor disabled
mbed_official 15:a81a8d6c1dfe 67 * \li No gain
mbed_official 15:a81a8d6c1dfe 68 * \li Positive input on ADC PIN 0
mbed_official 15:a81a8d6c1dfe 69 * \li Negative input on ADC PIN 1
mbed_official 15:a81a8d6c1dfe 70 * \li Averaging disabled
mbed_official 15:a81a8d6c1dfe 71 * \li Oversampling disabled
mbed_official 15:a81a8d6c1dfe 72 * \li Right adjust data
mbed_official 15:a81a8d6c1dfe 73 * \li Single-ended mode
mbed_official 15:a81a8d6c1dfe 74 * \li Free running disabled
mbed_official 15:a81a8d6c1dfe 75 * \li All events (input and generation) disabled
mbed_official 15:a81a8d6c1dfe 76 * \li Sleep operation disabled
mbed_official 15:a81a8d6c1dfe 77 * \li No reference compensation
mbed_official 15:a81a8d6c1dfe 78 * \li No gain/offset correction
mbed_official 15:a81a8d6c1dfe 79 * \li No added sampling time
mbed_official 15:a81a8d6c1dfe 80 * \li Pin scan mode disabled
mbed_official 15:a81a8d6c1dfe 81 *
mbed_official 15:a81a8d6c1dfe 82 * \param[out] config Pointer to configuration struct to initialize to
mbed_official 15:a81a8d6c1dfe 83 * default values
mbed_official 15:a81a8d6c1dfe 84 */
mbed_official 15:a81a8d6c1dfe 85 void adc_get_config_defaults(struct adc_config *const config)
mbed_official 15:a81a8d6c1dfe 86 {
mbed_official 15:a81a8d6c1dfe 87 Assert(config);
mbed_official 15:a81a8d6c1dfe 88 config->clock_source = GCLK_GENERATOR_0;
mbed_official 15:a81a8d6c1dfe 89 config->reference = ADC_REFERENCE_INT1V;
mbed_official 15:a81a8d6c1dfe 90 config->clock_prescaler = ADC_CLOCK_PRESCALER_DIV4;
mbed_official 15:a81a8d6c1dfe 91 config->resolution = ADC_RESOLUTION_12BIT;
mbed_official 15:a81a8d6c1dfe 92 config->window.window_mode = ADC_WINDOW_MODE_DISABLE;
mbed_official 15:a81a8d6c1dfe 93 config->window.window_upper_value = 0;
mbed_official 15:a81a8d6c1dfe 94 config->window.window_lower_value = 0;
mbed_official 15:a81a8d6c1dfe 95 config->gain_factor = ADC_GAIN_FACTOR_1X;
mbed_official 15:a81a8d6c1dfe 96 #if SAMR21
mbed_official 15:a81a8d6c1dfe 97 config->positive_input = ADC_POSITIVE_INPUT_PIN6 ;
mbed_official 15:a81a8d6c1dfe 98 #else
mbed_official 15:a81a8d6c1dfe 99 config->positive_input = ADC_POSITIVE_INPUT_PIN0 ;
mbed_official 15:a81a8d6c1dfe 100 #endif
mbed_official 15:a81a8d6c1dfe 101 config->negative_input = ADC_NEGATIVE_INPUT_GND ;
mbed_official 15:a81a8d6c1dfe 102 config->accumulate_samples = ADC_ACCUMULATE_DISABLE;
mbed_official 15:a81a8d6c1dfe 103 config->divide_result = ADC_DIVIDE_RESULT_DISABLE;
mbed_official 15:a81a8d6c1dfe 104 config->left_adjust = false;
mbed_official 15:a81a8d6c1dfe 105 config->differential_mode = false;
mbed_official 15:a81a8d6c1dfe 106 config->freerunning = false;
mbed_official 15:a81a8d6c1dfe 107 config->event_action = ADC_EVENT_ACTION_DISABLED;
mbed_official 15:a81a8d6c1dfe 108 config->run_in_standby = false;
mbed_official 15:a81a8d6c1dfe 109 config->reference_compensation_enable = false;
mbed_official 15:a81a8d6c1dfe 110 config->correction.correction_enable = false;
mbed_official 15:a81a8d6c1dfe 111 config->correction.gain_correction = ADC_GAINCORR_RESETVALUE;
mbed_official 15:a81a8d6c1dfe 112 config->correction.offset_correction = ADC_OFFSETCORR_RESETVALUE;
mbed_official 15:a81a8d6c1dfe 113 config->sample_length = 0;
mbed_official 15:a81a8d6c1dfe 114 config->pin_scan.offset_start_scan = 0;
mbed_official 15:a81a8d6c1dfe 115 config->pin_scan.inputs_to_scan = 0;
mbed_official 15:a81a8d6c1dfe 116 }
mbed_official 15:a81a8d6c1dfe 117
mbed_official 15:a81a8d6c1dfe 118 /**
mbed_official 15:a81a8d6c1dfe 119 * \brief Sets the ADC window mode
mbed_official 15:a81a8d6c1dfe 120 *
mbed_official 15:a81a8d6c1dfe 121 * Sets the ADC window mode to a given mode and value range.
mbed_official 15:a81a8d6c1dfe 122 *
mbed_official 15:a81a8d6c1dfe 123 * \param[in] module_inst Pointer to the ADC software instance struct
mbed_official 15:a81a8d6c1dfe 124 * \param[in] window_mode Window monitor mode to set
mbed_official 15:a81a8d6c1dfe 125 * \param[in] window_lower_value Lower window monitor threshold value
mbed_official 15:a81a8d6c1dfe 126 * \param[in] window_upper_value Upper window monitor threshold value
mbed_official 15:a81a8d6c1dfe 127 */
mbed_official 15:a81a8d6c1dfe 128 void adc_set_window_mode(
mbed_official 15:a81a8d6c1dfe 129 struct adc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 130 const enum adc_window_mode window_mode,
mbed_official 15:a81a8d6c1dfe 131 const int16_t window_lower_value,
mbed_official 15:a81a8d6c1dfe 132 const int16_t window_upper_value)
mbed_official 15:a81a8d6c1dfe 133 {
mbed_official 15:a81a8d6c1dfe 134 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 135 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 136 Assert(module_inst->hw);
mbed_official 15:a81a8d6c1dfe 137
mbed_official 15:a81a8d6c1dfe 138 Adc *const adc_module = module_inst->hw;
mbed_official 15:a81a8d6c1dfe 139
mbed_official 15:a81a8d6c1dfe 140 while (adc_is_syncing(module_inst)) {
mbed_official 15:a81a8d6c1dfe 141 /* Wait for synchronization */
mbed_official 15:a81a8d6c1dfe 142 }
mbed_official 15:a81a8d6c1dfe 143
mbed_official 15:a81a8d6c1dfe 144 /* Set window mode */
mbed_official 15:a81a8d6c1dfe 145 adc_module->WINCTRL.reg = window_mode << ADC_WINCTRL_WINMODE_Pos;
mbed_official 15:a81a8d6c1dfe 146
mbed_official 15:a81a8d6c1dfe 147 while (adc_is_syncing(module_inst)) {
mbed_official 15:a81a8d6c1dfe 148 /* Wait for synchronization */
mbed_official 15:a81a8d6c1dfe 149 }
mbed_official 15:a81a8d6c1dfe 150
mbed_official 15:a81a8d6c1dfe 151 /* Set lower window monitor threshold value */
mbed_official 15:a81a8d6c1dfe 152 adc_module->WINLT.reg = window_lower_value << ADC_WINLT_WINLT_Pos;
mbed_official 15:a81a8d6c1dfe 153
mbed_official 15:a81a8d6c1dfe 154 while (adc_is_syncing(module_inst)) {
mbed_official 15:a81a8d6c1dfe 155 /* Wait for synchronization */
mbed_official 15:a81a8d6c1dfe 156 }
mbed_official 15:a81a8d6c1dfe 157
mbed_official 15:a81a8d6c1dfe 158 /* Set upper window monitor threshold value */
mbed_official 15:a81a8d6c1dfe 159 adc_module->WINUT.reg = window_upper_value << ADC_WINUT_WINUT_Pos;
mbed_official 15:a81a8d6c1dfe 160 }
mbed_official 15:a81a8d6c1dfe 161
mbed_official 15:a81a8d6c1dfe 162 /**
mbed_official 15:a81a8d6c1dfe 163 * \internal Configure MUX settings for the analog pins
mbed_official 15:a81a8d6c1dfe 164 *
mbed_official 15:a81a8d6c1dfe 165 * This function will set the given ADC input pins
mbed_official 15:a81a8d6c1dfe 166 * to the analog function in the pinmux, giving
mbed_official 15:a81a8d6c1dfe 167 * the ADC access to the analog signal
mbed_official 15:a81a8d6c1dfe 168 *
mbed_official 15:a81a8d6c1dfe 169 * \param [in] pin AINxx pin to configure
mbed_official 15:a81a8d6c1dfe 170 */
mbed_official 15:a81a8d6c1dfe 171 static inline void _adc_configure_ain_pin(uint32_t pin)
mbed_official 15:a81a8d6c1dfe 172 {
mbed_official 15:a81a8d6c1dfe 173 #define PIN_INVALID_ADC_AIN 0xFFFFUL
mbed_official 15:a81a8d6c1dfe 174
mbed_official 15:a81a8d6c1dfe 175 /* Pinmapping table for AINxx -> GPIO pin number */
mbed_official 15:a81a8d6c1dfe 176 const uint32_t pinmapping[] = {
mbed_official 15:a81a8d6c1dfe 177 #if (SAMD20E) || (SAMD21E)|| (SAMDA1E)
mbed_official 15:a81a8d6c1dfe 178 PIN_PA02B_ADC_AIN0, PIN_PA03B_ADC_AIN1,
mbed_official 15:a81a8d6c1dfe 179 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 180 PIN_PA04B_ADC_AIN4, PIN_PA05B_ADC_AIN5,
mbed_official 15:a81a8d6c1dfe 181 PIN_PA06B_ADC_AIN6, PIN_PA07B_ADC_AIN7,
mbed_official 15:a81a8d6c1dfe 182 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 183 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 184 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 185 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 186 PIN_PA08B_ADC_AIN16, PIN_PA09B_ADC_AIN17,
mbed_official 15:a81a8d6c1dfe 187 PIN_PA10B_ADC_AIN18, PIN_PA11B_ADC_AIN19,
mbed_official 15:a81a8d6c1dfe 188 #elif (SAMD20G) || (SAMD21G)|| (SAMDA1G)
mbed_official 15:a81a8d6c1dfe 189 PIN_PA02B_ADC_AIN0, PIN_PA03B_ADC_AIN1,
mbed_official 15:a81a8d6c1dfe 190 PIN_PB08B_ADC_AIN2, PIN_PB09B_ADC_AIN3,
mbed_official 15:a81a8d6c1dfe 191 PIN_PA04B_ADC_AIN4, PIN_PA05B_ADC_AIN5,
mbed_official 15:a81a8d6c1dfe 192 PIN_PA06B_ADC_AIN6, PIN_PA07B_ADC_AIN7,
mbed_official 15:a81a8d6c1dfe 193 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 194 PIN_PB02B_ADC_AIN10, PIN_PB03B_ADC_AIN11,
mbed_official 15:a81a8d6c1dfe 195 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 196 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 197 PIN_PA08B_ADC_AIN16, PIN_PA09B_ADC_AIN17,
mbed_official 15:a81a8d6c1dfe 198 PIN_PA10B_ADC_AIN18, PIN_PA11B_ADC_AIN19,
mbed_official 15:a81a8d6c1dfe 199 #elif (SAMD20J) || (SAMD21J)|| (SAMDA1J)
mbed_official 15:a81a8d6c1dfe 200 PIN_PA02B_ADC_AIN0, PIN_PA03B_ADC_AIN1,
mbed_official 15:a81a8d6c1dfe 201 PIN_PB08B_ADC_AIN2, PIN_PB09B_ADC_AIN3,
mbed_official 15:a81a8d6c1dfe 202 PIN_PA04B_ADC_AIN4, PIN_PA05B_ADC_AIN5,
mbed_official 15:a81a8d6c1dfe 203 PIN_PA06B_ADC_AIN6, PIN_PA07B_ADC_AIN7,
mbed_official 15:a81a8d6c1dfe 204 PIN_PB00B_ADC_AIN8, PIN_PB01B_ADC_AIN9,
mbed_official 15:a81a8d6c1dfe 205 PIN_PB02B_ADC_AIN10, PIN_PB03B_ADC_AIN11,
mbed_official 15:a81a8d6c1dfe 206 PIN_PB04B_ADC_AIN12, PIN_PB05B_ADC_AIN13,
mbed_official 15:a81a8d6c1dfe 207 PIN_PB06B_ADC_AIN14, PIN_PB07B_ADC_AIN15,
mbed_official 15:a81a8d6c1dfe 208 PIN_PA08B_ADC_AIN16, PIN_PA09B_ADC_AIN17,
mbed_official 15:a81a8d6c1dfe 209 PIN_PA10B_ADC_AIN18, PIN_PA11B_ADC_AIN19,
mbed_official 15:a81a8d6c1dfe 210 #elif SAMR21E
mbed_official 15:a81a8d6c1dfe 211 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 212 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 213 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 214 PIN_PA06B_ADC_AIN6, PIN_PA07B_ADC_AIN7,
mbed_official 15:a81a8d6c1dfe 215 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 216 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 217 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 218 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 219 PIN_PA08B_ADC_AIN16, PIN_PA09B_ADC_AIN17,
mbed_official 15:a81a8d6c1dfe 220 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 221 #elif SAMR21G
mbed_official 15:a81a8d6c1dfe 222 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 223 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 224 PIN_PA04B_ADC_AIN4, PIN_PA05B_ADC_AIN5,
mbed_official 15:a81a8d6c1dfe 225 PIN_PA06B_ADC_AIN6, PIN_PA07B_ADC_AIN7,
mbed_official 15:a81a8d6c1dfe 226 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 227 PIN_PB02B_ADC_AIN10, PIN_PB03B_ADC_AIN11,
mbed_official 15:a81a8d6c1dfe 228 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 229 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 230 PIN_PA08B_ADC_AIN16, PIN_PA09B_ADC_AIN17,
mbed_official 15:a81a8d6c1dfe 231 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 232 #elif (SAMD10C) || (SAMD11C)
mbed_official 15:a81a8d6c1dfe 233 PIN_PA02B_ADC_AIN0, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 234 PIN_PA04B_ADC_AIN2, PIN_PA05B_ADC_AIN3,
mbed_official 15:a81a8d6c1dfe 235 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 236 PIN_PA14B_ADC_AIN6, PIN_PA15B_ADC_AIN7,
mbed_official 15:a81a8d6c1dfe 237 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 238 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 239 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 240 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 241 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 242 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 243 #elif (SAMD10DS) || (SAMD11DS)
mbed_official 15:a81a8d6c1dfe 244 PIN_PA02B_ADC_AIN0, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 245 PIN_PA04B_ADC_AIN2, PIN_PA05B_ADC_AIN3,
mbed_official 15:a81a8d6c1dfe 246 PIN_PA06B_ADC_AIN4, PIN_PA07B_ADC_AIN5,
mbed_official 15:a81a8d6c1dfe 247 PIN_PA14B_ADC_AIN6, PIN_PA15B_ADC_AIN7,
mbed_official 15:a81a8d6c1dfe 248 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 249 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 250 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 251 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 252 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 253 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 254 #elif (SAMD10DM) || (SAMD11DM)
mbed_official 15:a81a8d6c1dfe 255 PIN_PA02B_ADC_AIN0, PIN_PA03B_ADC_AIN1,
mbed_official 15:a81a8d6c1dfe 256 PIN_PA04B_ADC_AIN2, PIN_PA05B_ADC_AIN3,
mbed_official 15:a81a8d6c1dfe 257 PIN_PA06B_ADC_AIN4, PIN_PA07B_ADC_AIN5,
mbed_official 15:a81a8d6c1dfe 258 PIN_PA14B_ADC_AIN6, PIN_PA15B_ADC_AIN7,
mbed_official 15:a81a8d6c1dfe 259 PIN_PA10B_ADC_AIN8, PIN_PA11B_ADC_AIN9,
mbed_official 15:a81a8d6c1dfe 260 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 261 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 262 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 263 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 264 PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN,
mbed_official 15:a81a8d6c1dfe 265 #else
mbed_official 15:a81a8d6c1dfe 266 # error ADC pin mappings are not defined for this device.
mbed_official 15:a81a8d6c1dfe 267 #endif
mbed_official 15:a81a8d6c1dfe 268 };
mbed_official 15:a81a8d6c1dfe 269
mbed_official 15:a81a8d6c1dfe 270 uint32_t pin_map_result = PIN_INVALID_ADC_AIN;
mbed_official 15:a81a8d6c1dfe 271
mbed_official 15:a81a8d6c1dfe 272 if (pin <= ADC_EXTCHANNEL_MSB) {
mbed_official 15:a81a8d6c1dfe 273 pin_map_result = pinmapping[pin >> ADC_INPUTCTRL_MUXPOS_Pos];
mbed_official 15:a81a8d6c1dfe 274
mbed_official 15:a81a8d6c1dfe 275 Assert(pin_map_result != PIN_INVALID_ADC_AIN);
mbed_official 15:a81a8d6c1dfe 276
mbed_official 15:a81a8d6c1dfe 277 struct system_pinmux_config config;
mbed_official 15:a81a8d6c1dfe 278 system_pinmux_get_config_defaults(&config);
mbed_official 15:a81a8d6c1dfe 279
mbed_official 15:a81a8d6c1dfe 280 /* Analog functions are all on MUX setting B */
mbed_official 15:a81a8d6c1dfe 281 config.input_pull = SYSTEM_PINMUX_PIN_PULL_NONE;
mbed_official 15:a81a8d6c1dfe 282 config.mux_position = 1;
mbed_official 15:a81a8d6c1dfe 283
mbed_official 15:a81a8d6c1dfe 284 system_pinmux_pin_set_config(pin_map_result, &config);
mbed_official 15:a81a8d6c1dfe 285 }
mbed_official 15:a81a8d6c1dfe 286 }
mbed_official 15:a81a8d6c1dfe 287
mbed_official 15:a81a8d6c1dfe 288 /**
mbed_official 15:a81a8d6c1dfe 289 * \internal Writes an ADC configuration to the hardware module
mbed_official 15:a81a8d6c1dfe 290 *
mbed_official 15:a81a8d6c1dfe 291 * Writes out a given ADC module configuration to the hardware module.
mbed_official 15:a81a8d6c1dfe 292 *
mbed_official 15:a81a8d6c1dfe 293 * \param[out] module_inst Pointer to the ADC software instance struct
mbed_official 15:a81a8d6c1dfe 294 * \param[in] config Pointer to configuration struct
mbed_official 15:a81a8d6c1dfe 295 *
mbed_official 15:a81a8d6c1dfe 296 * \return Status of the configuration procedure
mbed_official 15:a81a8d6c1dfe 297 * \retval STATUS_OK The configuration was successful
mbed_official 15:a81a8d6c1dfe 298 * \retval STATUS_ERR_INVALID_ARG Invalid argument(s) were provided
mbed_official 15:a81a8d6c1dfe 299 */
mbed_official 15:a81a8d6c1dfe 300 static enum status_code _adc_set_config(
mbed_official 15:a81a8d6c1dfe 301 struct adc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 302 struct adc_config *const config)
mbed_official 15:a81a8d6c1dfe 303 {
mbed_official 15:a81a8d6c1dfe 304 uint8_t adjres = 0;
mbed_official 15:a81a8d6c1dfe 305 uint32_t resolution = ADC_RESOLUTION_16BIT;
mbed_official 15:a81a8d6c1dfe 306 enum adc_accumulate_samples accumulate = ADC_ACCUMULATE_DISABLE;
mbed_official 15:a81a8d6c1dfe 307 #if SAMD20
mbed_official 15:a81a8d6c1dfe 308 uint8_t revision_num = ((REG_DSU_DID & DSU_DID_DIE_Msk) >> DSU_DID_DIE_Pos);
mbed_official 15:a81a8d6c1dfe 309 #endif
mbed_official 15:a81a8d6c1dfe 310
mbed_official 15:a81a8d6c1dfe 311 /* Get the hardware module pointer */
mbed_official 15:a81a8d6c1dfe 312 Adc *const adc_module = module_inst->hw;
mbed_official 15:a81a8d6c1dfe 313
mbed_official 15:a81a8d6c1dfe 314 /* Configure GCLK channel and enable clock */
mbed_official 15:a81a8d6c1dfe 315 struct system_gclk_chan_config gclk_chan_conf;
mbed_official 15:a81a8d6c1dfe 316 system_gclk_chan_get_config_defaults(&gclk_chan_conf);
mbed_official 15:a81a8d6c1dfe 317 gclk_chan_conf.source_generator = config->clock_source;
mbed_official 15:a81a8d6c1dfe 318 system_gclk_chan_set_config(ADC_GCLK_ID, &gclk_chan_conf);
mbed_official 15:a81a8d6c1dfe 319 system_gclk_chan_enable(ADC_GCLK_ID);
mbed_official 15:a81a8d6c1dfe 320
mbed_official 15:a81a8d6c1dfe 321 /* Setup pinmuxing for analog inputs */
mbed_official 15:a81a8d6c1dfe 322 if (config->pin_scan.inputs_to_scan != 0) {
mbed_official 15:a81a8d6c1dfe 323 uint8_t offset = config->pin_scan.offset_start_scan;
mbed_official 15:a81a8d6c1dfe 324 uint8_t start_pin =
mbed_official 15:a81a8d6c1dfe 325 offset +(uint8_t)config->positive_input;
mbed_official 15:a81a8d6c1dfe 326 uint8_t end_pin =
mbed_official 15:a81a8d6c1dfe 327 start_pin + config->pin_scan.inputs_to_scan;
mbed_official 15:a81a8d6c1dfe 328
mbed_official 15:a81a8d6c1dfe 329 while (start_pin < end_pin) {
mbed_official 15:a81a8d6c1dfe 330 _adc_configure_ain_pin((offset % 16)+(uint8_t)config->positive_input);
mbed_official 15:a81a8d6c1dfe 331 start_pin++;
mbed_official 15:a81a8d6c1dfe 332 offset++;
mbed_official 15:a81a8d6c1dfe 333 }
mbed_official 15:a81a8d6c1dfe 334 _adc_configure_ain_pin(config->negative_input);
mbed_official 15:a81a8d6c1dfe 335 } else {
mbed_official 15:a81a8d6c1dfe 336 _adc_configure_ain_pin(config->positive_input);
mbed_official 15:a81a8d6c1dfe 337 _adc_configure_ain_pin(config->negative_input);
mbed_official 15:a81a8d6c1dfe 338 }
mbed_official 15:a81a8d6c1dfe 339
mbed_official 15:a81a8d6c1dfe 340 /* Configure run in standby */
mbed_official 15:a81a8d6c1dfe 341 adc_module->CTRLA.reg = (config->run_in_standby << ADC_CTRLA_RUNSTDBY_Pos);
mbed_official 15:a81a8d6c1dfe 342
mbed_official 15:a81a8d6c1dfe 343 /* Configure reference */
mbed_official 15:a81a8d6c1dfe 344 adc_module->REFCTRL.reg =
mbed_official 15:a81a8d6c1dfe 345 (config->reference_compensation_enable << ADC_REFCTRL_REFCOMP_Pos) |
mbed_official 15:a81a8d6c1dfe 346 (config->reference);
mbed_official 15:a81a8d6c1dfe 347
mbed_official 15:a81a8d6c1dfe 348 /* Set adjusting result and number of samples */
mbed_official 15:a81a8d6c1dfe 349 switch (config->resolution) {
mbed_official 15:a81a8d6c1dfe 350
mbed_official 15:a81a8d6c1dfe 351 case ADC_RESOLUTION_CUSTOM:
mbed_official 15:a81a8d6c1dfe 352 adjres = config->divide_result;
mbed_official 15:a81a8d6c1dfe 353 accumulate = config->accumulate_samples;
mbed_official 15:a81a8d6c1dfe 354 /* 16-bit result register */
mbed_official 15:a81a8d6c1dfe 355 resolution = ADC_RESOLUTION_16BIT;
mbed_official 15:a81a8d6c1dfe 356 break;
mbed_official 15:a81a8d6c1dfe 357
mbed_official 15:a81a8d6c1dfe 358 case ADC_RESOLUTION_13BIT:
mbed_official 15:a81a8d6c1dfe 359 /* Increase resolution by 1 bit */
mbed_official 15:a81a8d6c1dfe 360 adjres = ADC_DIVIDE_RESULT_2;
mbed_official 15:a81a8d6c1dfe 361 accumulate = ADC_ACCUMULATE_SAMPLES_4;
mbed_official 15:a81a8d6c1dfe 362 /* 16-bit result register */
mbed_official 15:a81a8d6c1dfe 363 resolution = ADC_RESOLUTION_16BIT;
mbed_official 15:a81a8d6c1dfe 364 break;
mbed_official 15:a81a8d6c1dfe 365
mbed_official 15:a81a8d6c1dfe 366 case ADC_RESOLUTION_14BIT:
mbed_official 15:a81a8d6c1dfe 367 /* Increase resolution by 2 bit */
mbed_official 15:a81a8d6c1dfe 368 adjres = ADC_DIVIDE_RESULT_4;
mbed_official 15:a81a8d6c1dfe 369 accumulate = ADC_ACCUMULATE_SAMPLES_16;
mbed_official 15:a81a8d6c1dfe 370 /* 16-bit result register */
mbed_official 15:a81a8d6c1dfe 371 resolution = ADC_RESOLUTION_16BIT;
mbed_official 15:a81a8d6c1dfe 372 break;
mbed_official 15:a81a8d6c1dfe 373 #if SAMD20
mbed_official 15:a81a8d6c1dfe 374 /* See $35.1.8 for ADC errata of SAM D20.
mbed_official 15:a81a8d6c1dfe 375 The revisions before D have this issue.*/
mbed_official 15:a81a8d6c1dfe 376 case ADC_RESOLUTION_15BIT:
mbed_official 15:a81a8d6c1dfe 377 /* Increase resolution by 3 bit */
mbed_official 15:a81a8d6c1dfe 378 if(revision_num < REVISON_D_NUM) {
mbed_official 15:a81a8d6c1dfe 379 adjres = ADC_DIVIDE_RESULT_8;
mbed_official 15:a81a8d6c1dfe 380 } else {
mbed_official 15:a81a8d6c1dfe 381 adjres = ADC_DIVIDE_RESULT_2;
mbed_official 15:a81a8d6c1dfe 382 }
mbed_official 15:a81a8d6c1dfe 383 accumulate = ADC_ACCUMULATE_SAMPLES_64;
mbed_official 15:a81a8d6c1dfe 384 /* 16-bit result register */
mbed_official 15:a81a8d6c1dfe 385 resolution = ADC_RESOLUTION_16BIT;
mbed_official 15:a81a8d6c1dfe 386 break;
mbed_official 15:a81a8d6c1dfe 387
mbed_official 15:a81a8d6c1dfe 388 case ADC_RESOLUTION_16BIT:
mbed_official 15:a81a8d6c1dfe 389 if(revision_num < REVISON_D_NUM) {
mbed_official 15:a81a8d6c1dfe 390 /* Increase resolution by 4 bit */
mbed_official 15:a81a8d6c1dfe 391 adjres = ADC_DIVIDE_RESULT_16;
mbed_official 15:a81a8d6c1dfe 392 } else {
mbed_official 15:a81a8d6c1dfe 393 adjres = ADC_DIVIDE_RESULT_DISABLE;
mbed_official 15:a81a8d6c1dfe 394 }
mbed_official 15:a81a8d6c1dfe 395 accumulate = ADC_ACCUMULATE_SAMPLES_256;
mbed_official 15:a81a8d6c1dfe 396 /* 16-bit result register */
mbed_official 15:a81a8d6c1dfe 397 resolution = ADC_RESOLUTION_16BIT;
mbed_official 15:a81a8d6c1dfe 398 break;
mbed_official 15:a81a8d6c1dfe 399 #else
mbed_official 15:a81a8d6c1dfe 400 case ADC_RESOLUTION_15BIT:
mbed_official 15:a81a8d6c1dfe 401 /* Increase resolution by 3 bit */
mbed_official 15:a81a8d6c1dfe 402 adjres = ADC_DIVIDE_RESULT_2;
mbed_official 15:a81a8d6c1dfe 403 accumulate = ADC_ACCUMULATE_SAMPLES_64;
mbed_official 15:a81a8d6c1dfe 404 /* 16-bit result register */
mbed_official 15:a81a8d6c1dfe 405 resolution = ADC_RESOLUTION_16BIT;
mbed_official 15:a81a8d6c1dfe 406 break;
mbed_official 15:a81a8d6c1dfe 407
mbed_official 15:a81a8d6c1dfe 408 case ADC_RESOLUTION_16BIT:
mbed_official 15:a81a8d6c1dfe 409 /* Increase resolution by 4 bit */
mbed_official 15:a81a8d6c1dfe 410 adjres = ADC_DIVIDE_RESULT_DISABLE;
mbed_official 15:a81a8d6c1dfe 411 accumulate = ADC_ACCUMULATE_SAMPLES_256;
mbed_official 15:a81a8d6c1dfe 412 /* 16-bit result register */
mbed_official 15:a81a8d6c1dfe 413 resolution = ADC_RESOLUTION_16BIT;
mbed_official 15:a81a8d6c1dfe 414 break;
mbed_official 15:a81a8d6c1dfe 415 #endif
mbed_official 15:a81a8d6c1dfe 416 case ADC_RESOLUTION_8BIT:
mbed_official 15:a81a8d6c1dfe 417 /* 8-bit result register */
mbed_official 15:a81a8d6c1dfe 418 resolution = ADC_RESOLUTION_8BIT;
mbed_official 15:a81a8d6c1dfe 419 break;
mbed_official 15:a81a8d6c1dfe 420 case ADC_RESOLUTION_10BIT:
mbed_official 15:a81a8d6c1dfe 421 /* 10-bit result register */
mbed_official 15:a81a8d6c1dfe 422 resolution = ADC_RESOLUTION_10BIT;
mbed_official 15:a81a8d6c1dfe 423 break;
mbed_official 15:a81a8d6c1dfe 424 case ADC_RESOLUTION_12BIT:
mbed_official 15:a81a8d6c1dfe 425 /* 12-bit result register */
mbed_official 15:a81a8d6c1dfe 426 resolution = ADC_RESOLUTION_12BIT;
mbed_official 15:a81a8d6c1dfe 427 break;
mbed_official 15:a81a8d6c1dfe 428
mbed_official 15:a81a8d6c1dfe 429 default:
mbed_official 15:a81a8d6c1dfe 430 /* Unknown. Abort. */
mbed_official 15:a81a8d6c1dfe 431 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 432 }
mbed_official 15:a81a8d6c1dfe 433
mbed_official 15:a81a8d6c1dfe 434 adc_module->AVGCTRL.reg = ADC_AVGCTRL_ADJRES(adjres) | accumulate;
mbed_official 15:a81a8d6c1dfe 435
mbed_official 15:a81a8d6c1dfe 436 /* Check validity of sample length value */
mbed_official 15:a81a8d6c1dfe 437 if (config->sample_length > 63) {
mbed_official 15:a81a8d6c1dfe 438 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 439 } else {
mbed_official 15:a81a8d6c1dfe 440 /* Configure sample length */
mbed_official 15:a81a8d6c1dfe 441 adc_module->SAMPCTRL.reg =
mbed_official 15:a81a8d6c1dfe 442 (config->sample_length << ADC_SAMPCTRL_SAMPLEN_Pos);
mbed_official 15:a81a8d6c1dfe 443 }
mbed_official 15:a81a8d6c1dfe 444
mbed_official 15:a81a8d6c1dfe 445 while (adc_is_syncing(module_inst)) {
mbed_official 15:a81a8d6c1dfe 446 /* Wait for synchronization */
mbed_official 15:a81a8d6c1dfe 447 }
mbed_official 15:a81a8d6c1dfe 448
mbed_official 15:a81a8d6c1dfe 449 /* Configure CTRLB */
mbed_official 15:a81a8d6c1dfe 450 adc_module->CTRLB.reg =
mbed_official 15:a81a8d6c1dfe 451 config->clock_prescaler |
mbed_official 15:a81a8d6c1dfe 452 resolution |
mbed_official 15:a81a8d6c1dfe 453 (config->correction.correction_enable << ADC_CTRLB_CORREN_Pos) |
mbed_official 15:a81a8d6c1dfe 454 (config->freerunning << ADC_CTRLB_FREERUN_Pos) |
mbed_official 15:a81a8d6c1dfe 455 (config->left_adjust << ADC_CTRLB_LEFTADJ_Pos) |
mbed_official 15:a81a8d6c1dfe 456 (config->differential_mode << ADC_CTRLB_DIFFMODE_Pos);
mbed_official 15:a81a8d6c1dfe 457
mbed_official 15:a81a8d6c1dfe 458 /* Check validity of window thresholds */
mbed_official 15:a81a8d6c1dfe 459 if (config->window.window_mode != ADC_WINDOW_MODE_DISABLE) {
mbed_official 15:a81a8d6c1dfe 460 switch (resolution) {
mbed_official 15:a81a8d6c1dfe 461 case ADC_RESOLUTION_8BIT:
mbed_official 15:a81a8d6c1dfe 462 if (config->differential_mode &&
mbed_official 15:a81a8d6c1dfe 463 (config->window.window_lower_value > 127 ||
mbed_official 15:a81a8d6c1dfe 464 config->window.window_lower_value < -128 ||
mbed_official 15:a81a8d6c1dfe 465 config->window.window_upper_value > 127 ||
mbed_official 15:a81a8d6c1dfe 466 config->window.window_upper_value < -128)) {
mbed_official 15:a81a8d6c1dfe 467 /* Invalid value */
mbed_official 15:a81a8d6c1dfe 468 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 469 } else if (config->window.window_lower_value > 255 ||
mbed_official 15:a81a8d6c1dfe 470 config->window.window_upper_value > 255) {
mbed_official 15:a81a8d6c1dfe 471 /* Invalid value */
mbed_official 15:a81a8d6c1dfe 472 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 473 }
mbed_official 15:a81a8d6c1dfe 474 break;
mbed_official 15:a81a8d6c1dfe 475 case ADC_RESOLUTION_10BIT:
mbed_official 15:a81a8d6c1dfe 476 if (config->differential_mode &&
mbed_official 15:a81a8d6c1dfe 477 (config->window.window_lower_value > 511 ||
mbed_official 15:a81a8d6c1dfe 478 config->window.window_lower_value < -512 ||
mbed_official 15:a81a8d6c1dfe 479 config->window.window_upper_value > 511 ||
mbed_official 15:a81a8d6c1dfe 480 config->window.window_upper_value < -512)) {
mbed_official 15:a81a8d6c1dfe 481 /* Invalid value */
mbed_official 15:a81a8d6c1dfe 482 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 483 } else if (config->window.window_lower_value > 1023 ||
mbed_official 15:a81a8d6c1dfe 484 config->window.window_upper_value > 1023) {
mbed_official 15:a81a8d6c1dfe 485 /* Invalid value */
mbed_official 15:a81a8d6c1dfe 486 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 487 }
mbed_official 15:a81a8d6c1dfe 488 break;
mbed_official 15:a81a8d6c1dfe 489 case ADC_RESOLUTION_12BIT:
mbed_official 15:a81a8d6c1dfe 490 if (config->differential_mode &&
mbed_official 15:a81a8d6c1dfe 491 (config->window.window_lower_value > 2047 ||
mbed_official 15:a81a8d6c1dfe 492 config->window.window_lower_value < -2048 ||
mbed_official 15:a81a8d6c1dfe 493 config->window.window_upper_value > 2047 ||
mbed_official 15:a81a8d6c1dfe 494 config->window.window_upper_value < -2048)) {
mbed_official 15:a81a8d6c1dfe 495 /* Invalid value */
mbed_official 15:a81a8d6c1dfe 496 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 497 } else if (config->window.window_lower_value > 4095 ||
mbed_official 15:a81a8d6c1dfe 498 config->window.window_upper_value > 4095) {
mbed_official 15:a81a8d6c1dfe 499 /* Invalid value */
mbed_official 15:a81a8d6c1dfe 500 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 501 }
mbed_official 15:a81a8d6c1dfe 502 break;
mbed_official 15:a81a8d6c1dfe 503 case ADC_RESOLUTION_16BIT:
mbed_official 15:a81a8d6c1dfe 504 if (config->differential_mode &&
mbed_official 15:a81a8d6c1dfe 505 (config->window.window_lower_value > 32767 ||
mbed_official 15:a81a8d6c1dfe 506 config->window.window_lower_value < -32768 ||
mbed_official 15:a81a8d6c1dfe 507 config->window.window_upper_value > 32767 ||
mbed_official 15:a81a8d6c1dfe 508 config->window.window_upper_value < -32768)) {
mbed_official 15:a81a8d6c1dfe 509 /* Invalid value */
mbed_official 15:a81a8d6c1dfe 510 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 511 } else if (config->window.window_lower_value > 65535 ||
mbed_official 15:a81a8d6c1dfe 512 config->window.window_upper_value > 65535) {
mbed_official 15:a81a8d6c1dfe 513 /* Invalid value */
mbed_official 15:a81a8d6c1dfe 514 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 515 }
mbed_official 15:a81a8d6c1dfe 516 break;
mbed_official 15:a81a8d6c1dfe 517 }
mbed_official 15:a81a8d6c1dfe 518 }
mbed_official 15:a81a8d6c1dfe 519
mbed_official 15:a81a8d6c1dfe 520 while (adc_is_syncing(module_inst)) {
mbed_official 15:a81a8d6c1dfe 521 /* Wait for synchronization */
mbed_official 15:a81a8d6c1dfe 522 }
mbed_official 15:a81a8d6c1dfe 523
mbed_official 15:a81a8d6c1dfe 524 /* Configure window mode */
mbed_official 15:a81a8d6c1dfe 525 adc_module->WINCTRL.reg = config->window.window_mode;
mbed_official 15:a81a8d6c1dfe 526
mbed_official 15:a81a8d6c1dfe 527 while (adc_is_syncing(module_inst)) {
mbed_official 15:a81a8d6c1dfe 528 /* Wait for synchronization */
mbed_official 15:a81a8d6c1dfe 529 }
mbed_official 15:a81a8d6c1dfe 530
mbed_official 15:a81a8d6c1dfe 531 /* Configure lower threshold */
mbed_official 15:a81a8d6c1dfe 532 adc_module->WINLT.reg =
mbed_official 15:a81a8d6c1dfe 533 config->window.window_lower_value << ADC_WINLT_WINLT_Pos;
mbed_official 15:a81a8d6c1dfe 534
mbed_official 15:a81a8d6c1dfe 535 while (adc_is_syncing(module_inst)) {
mbed_official 15:a81a8d6c1dfe 536 /* Wait for synchronization */
mbed_official 15:a81a8d6c1dfe 537 }
mbed_official 15:a81a8d6c1dfe 538
mbed_official 15:a81a8d6c1dfe 539 /* Configure lower threshold */
mbed_official 15:a81a8d6c1dfe 540 adc_module->WINUT.reg = config->window.window_upper_value <<
mbed_official 15:a81a8d6c1dfe 541 ADC_WINUT_WINUT_Pos;
mbed_official 15:a81a8d6c1dfe 542
mbed_official 15:a81a8d6c1dfe 543 uint8_t inputs_to_scan = config->pin_scan.inputs_to_scan;
mbed_official 15:a81a8d6c1dfe 544 if (inputs_to_scan > 0) {
mbed_official 15:a81a8d6c1dfe 545 /*
mbed_official 15:a81a8d6c1dfe 546 * Number of input sources included is the value written to INPUTSCAN
mbed_official 15:a81a8d6c1dfe 547 * plus 1.
mbed_official 15:a81a8d6c1dfe 548 */
mbed_official 15:a81a8d6c1dfe 549 inputs_to_scan--;
mbed_official 15:a81a8d6c1dfe 550 }
mbed_official 15:a81a8d6c1dfe 551
mbed_official 15:a81a8d6c1dfe 552 if (inputs_to_scan > (ADC_INPUTCTRL_INPUTSCAN_Msk >> ADC_INPUTCTRL_INPUTSCAN_Pos) ||
mbed_official 15:a81a8d6c1dfe 553 config->pin_scan.offset_start_scan > (ADC_INPUTCTRL_INPUTOFFSET_Msk >> ADC_INPUTCTRL_INPUTOFFSET_Pos)) {
mbed_official 15:a81a8d6c1dfe 554 /* Invalid number of input pins or input offset */
mbed_official 15:a81a8d6c1dfe 555 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 556 }
mbed_official 15:a81a8d6c1dfe 557
mbed_official 15:a81a8d6c1dfe 558 while (adc_is_syncing(module_inst)) {
mbed_official 15:a81a8d6c1dfe 559 /* Wait for synchronization */
mbed_official 15:a81a8d6c1dfe 560 }
mbed_official 15:a81a8d6c1dfe 561
mbed_official 15:a81a8d6c1dfe 562 /* Configure pin scan mode and positive and negative input pins */
mbed_official 15:a81a8d6c1dfe 563 adc_module->INPUTCTRL.reg =
mbed_official 15:a81a8d6c1dfe 564 config->gain_factor |
mbed_official 15:a81a8d6c1dfe 565 (config->pin_scan.offset_start_scan <<
mbed_official 15:a81a8d6c1dfe 566 ADC_INPUTCTRL_INPUTOFFSET_Pos) |
mbed_official 15:a81a8d6c1dfe 567 (inputs_to_scan << ADC_INPUTCTRL_INPUTSCAN_Pos) |
mbed_official 15:a81a8d6c1dfe 568 config->negative_input |
mbed_official 15:a81a8d6c1dfe 569 config->positive_input;
mbed_official 15:a81a8d6c1dfe 570
mbed_official 15:a81a8d6c1dfe 571 /* Configure events */
mbed_official 15:a81a8d6c1dfe 572 adc_module->EVCTRL.reg = config->event_action;
mbed_official 15:a81a8d6c1dfe 573
mbed_official 15:a81a8d6c1dfe 574 /* Disable all interrupts */
mbed_official 15:a81a8d6c1dfe 575 adc_module->INTENCLR.reg =
mbed_official 15:a81a8d6c1dfe 576 (1 << ADC_INTENCLR_SYNCRDY_Pos) | (1 << ADC_INTENCLR_WINMON_Pos) |
mbed_official 15:a81a8d6c1dfe 577 (1 << ADC_INTENCLR_OVERRUN_Pos) | (1 << ADC_INTENCLR_RESRDY_Pos);
mbed_official 15:a81a8d6c1dfe 578
mbed_official 15:a81a8d6c1dfe 579 if (config->correction.correction_enable) {
mbed_official 15:a81a8d6c1dfe 580 /* Make sure gain_correction value is valid */
mbed_official 15:a81a8d6c1dfe 581 if (config->correction.gain_correction > ADC_GAINCORR_GAINCORR_Msk) {
mbed_official 15:a81a8d6c1dfe 582 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 583 } else {
mbed_official 15:a81a8d6c1dfe 584 /* Set gain correction value */
mbed_official 15:a81a8d6c1dfe 585 adc_module->GAINCORR.reg = config->correction.gain_correction <<
mbed_official 15:a81a8d6c1dfe 586 ADC_GAINCORR_GAINCORR_Pos;
mbed_official 15:a81a8d6c1dfe 587 }
mbed_official 15:a81a8d6c1dfe 588
mbed_official 15:a81a8d6c1dfe 589 /* Make sure offset correction value is valid */
mbed_official 15:a81a8d6c1dfe 590 if (config->correction.offset_correction > 2047 ||
mbed_official 15:a81a8d6c1dfe 591 config->correction.offset_correction < -2048) {
mbed_official 15:a81a8d6c1dfe 592 return STATUS_ERR_INVALID_ARG;
mbed_official 15:a81a8d6c1dfe 593 } else {
mbed_official 15:a81a8d6c1dfe 594 /* Set offset correction value */
mbed_official 15:a81a8d6c1dfe 595 adc_module->OFFSETCORR.reg = config->correction.offset_correction <<
mbed_official 15:a81a8d6c1dfe 596 ADC_OFFSETCORR_OFFSETCORR_Pos;
mbed_official 15:a81a8d6c1dfe 597 }
mbed_official 15:a81a8d6c1dfe 598 }
mbed_official 15:a81a8d6c1dfe 599
mbed_official 15:a81a8d6c1dfe 600 /* Load in the fixed device ADC calibration constants */
mbed_official 15:a81a8d6c1dfe 601 adc_module->CALIB.reg =
mbed_official 15:a81a8d6c1dfe 602 ADC_CALIB_BIAS_CAL(
mbed_official 15:a81a8d6c1dfe 603 (*(uint32_t *)ADC_FUSES_BIASCAL_ADDR >> ADC_FUSES_BIASCAL_Pos)
mbed_official 15:a81a8d6c1dfe 604 ) |
mbed_official 15:a81a8d6c1dfe 605 ADC_CALIB_LINEARITY_CAL(
mbed_official 15:a81a8d6c1dfe 606 (*(uint64_t *)ADC_FUSES_LINEARITY_0_ADDR >> ADC_FUSES_LINEARITY_0_Pos)
mbed_official 15:a81a8d6c1dfe 607 );
mbed_official 15:a81a8d6c1dfe 608
mbed_official 15:a81a8d6c1dfe 609 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 610 }
mbed_official 15:a81a8d6c1dfe 611
mbed_official 15:a81a8d6c1dfe 612 /**
mbed_official 15:a81a8d6c1dfe 613 * \brief Initializes the ADC channel sequence
mbed_official 15:a81a8d6c1dfe 614 *
mbed_official 15:a81a8d6c1dfe 615 * Like SAMD and SAMR21 the INPUTOFFSET register will be incremented one
mbed_official 15:a81a8d6c1dfe 616 * automatically after a conversion done, causing the next conversion
mbed_official 15:a81a8d6c1dfe 617 * to be done with the positive input equal to MUXPOS + INPUTOFFSET,
mbed_official 15:a81a8d6c1dfe 618 * it is scanning continuously one by one even ADC channels are not continuous.
mbed_official 15:a81a8d6c1dfe 619 *
mbed_official 15:a81a8d6c1dfe 620 * Initializes the ADC channel sequence by the sequence of pin_array.
mbed_official 15:a81a8d6c1dfe 621 *
mbed_official 15:a81a8d6c1dfe 622 * \param[in] pin_array The array of the Mux selection for the positive ADC input
mbed_official 15:a81a8d6c1dfe 623 * \param[in] size The size of pin_array
mbed_official 15:a81a8d6c1dfe 624 */
mbed_official 15:a81a8d6c1dfe 625 void adc_regular_ain_channel(uint32_t *pin_array, uint8_t size)
mbed_official 15:a81a8d6c1dfe 626 {
mbed_official 15:a81a8d6c1dfe 627 for (int i = 0; i < size; i++) {
mbed_official 15:a81a8d6c1dfe 628 _adc_configure_ain_pin(pin_array[i]);
mbed_official 15:a81a8d6c1dfe 629 }
mbed_official 15:a81a8d6c1dfe 630 }
mbed_official 15:a81a8d6c1dfe 631
mbed_official 15:a81a8d6c1dfe 632 /**
mbed_official 15:a81a8d6c1dfe 633 * \brief Initializes the ADC
mbed_official 15:a81a8d6c1dfe 634 *
mbed_official 15:a81a8d6c1dfe 635 * Initializes the ADC device struct and the hardware module based on the
mbed_official 15:a81a8d6c1dfe 636 * given configuration struct values.
mbed_official 15:a81a8d6c1dfe 637 *
mbed_official 15:a81a8d6c1dfe 638 * \param[out] module_inst Pointer to the ADC software instance struct
mbed_official 15:a81a8d6c1dfe 639 * \param[in] hw Pointer to the ADC module instance
mbed_official 15:a81a8d6c1dfe 640 * \param[in] config Pointer to the configuration struct
mbed_official 15:a81a8d6c1dfe 641 *
mbed_official 15:a81a8d6c1dfe 642 * \return Status of the initialization procedure.
mbed_official 15:a81a8d6c1dfe 643 * \retval STATUS_OK The initialization was successful
mbed_official 15:a81a8d6c1dfe 644 * \retval STATUS_ERR_INVALID_ARG Invalid argument(s) were provided
mbed_official 15:a81a8d6c1dfe 645 * \retval STATUS_BUSY The module is busy with a reset operation
mbed_official 15:a81a8d6c1dfe 646 * \retval STATUS_ERR_DENIED The module is enabled
mbed_official 15:a81a8d6c1dfe 647 */
mbed_official 15:a81a8d6c1dfe 648 enum status_code adc_init(
mbed_official 15:a81a8d6c1dfe 649 struct adc_module *const module_inst,
mbed_official 15:a81a8d6c1dfe 650 Adc *hw,
mbed_official 15:a81a8d6c1dfe 651 struct adc_config *config)
mbed_official 15:a81a8d6c1dfe 652 {
mbed_official 15:a81a8d6c1dfe 653 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 654 Assert(module_inst);
mbed_official 15:a81a8d6c1dfe 655 Assert(hw);
mbed_official 15:a81a8d6c1dfe 656 Assert(config);
mbed_official 15:a81a8d6c1dfe 657
mbed_official 15:a81a8d6c1dfe 658 /* Associate the software module instance with the hardware module */
mbed_official 15:a81a8d6c1dfe 659 module_inst->hw = hw;
mbed_official 15:a81a8d6c1dfe 660
mbed_official 15:a81a8d6c1dfe 661 /* Turn on the digital interface clock */
mbed_official 15:a81a8d6c1dfe 662 system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_ADC);
mbed_official 15:a81a8d6c1dfe 663
mbed_official 15:a81a8d6c1dfe 664 if (hw->CTRLA.reg & ADC_CTRLA_SWRST) {
mbed_official 15:a81a8d6c1dfe 665 /* We are in the middle of a reset. Abort. */
mbed_official 15:a81a8d6c1dfe 666 return STATUS_BUSY;
mbed_official 15:a81a8d6c1dfe 667 }
mbed_official 15:a81a8d6c1dfe 668
mbed_official 15:a81a8d6c1dfe 669 if (hw->CTRLA.reg & ADC_CTRLA_ENABLE) {
mbed_official 15:a81a8d6c1dfe 670 /* Module must be disabled before initialization. Abort. */
mbed_official 15:a81a8d6c1dfe 671 return STATUS_ERR_DENIED;
mbed_official 15:a81a8d6c1dfe 672 }
mbed_official 15:a81a8d6c1dfe 673
mbed_official 15:a81a8d6c1dfe 674 /* Store the selected reference for later use */
mbed_official 15:a81a8d6c1dfe 675 module_inst->reference = config->reference;
mbed_official 15:a81a8d6c1dfe 676
mbed_official 15:a81a8d6c1dfe 677 /* Make sure bandgap is enabled if requested by the config */
mbed_official 15:a81a8d6c1dfe 678 if (module_inst->reference == ADC_REFERENCE_INT1V) {
mbed_official 15:a81a8d6c1dfe 679 system_voltage_reference_enable(SYSTEM_VOLTAGE_REFERENCE_BANDGAP);
mbed_official 15:a81a8d6c1dfe 680 }
mbed_official 15:a81a8d6c1dfe 681
mbed_official 15:a81a8d6c1dfe 682 #if ADC_CALLBACK_MODE == true
mbed_official 15:a81a8d6c1dfe 683 for (uint8_t i = 0; i < ADC_CALLBACK_N; i++) {
mbed_official 15:a81a8d6c1dfe 684 module_inst->callback[i] = NULL;
mbed_official 15:a81a8d6c1dfe 685 };
mbed_official 15:a81a8d6c1dfe 686
mbed_official 15:a81a8d6c1dfe 687 module_inst->registered_callback_mask = 0;
mbed_official 15:a81a8d6c1dfe 688 module_inst->enabled_callback_mask = 0;
mbed_official 15:a81a8d6c1dfe 689 module_inst->remaining_conversions = 0;
mbed_official 15:a81a8d6c1dfe 690 module_inst->job_status = STATUS_OK;
mbed_official 15:a81a8d6c1dfe 691
mbed_official 15:a81a8d6c1dfe 692 _adc_instances[0] = module_inst;
mbed_official 15:a81a8d6c1dfe 693
mbed_official 15:a81a8d6c1dfe 694 if (config->event_action == ADC_EVENT_ACTION_DISABLED &&
mbed_official 15:a81a8d6c1dfe 695 !config->freerunning) {
mbed_official 15:a81a8d6c1dfe 696 module_inst->software_trigger = true;
mbed_official 15:a81a8d6c1dfe 697 } else {
mbed_official 15:a81a8d6c1dfe 698 module_inst->software_trigger = false;
mbed_official 15:a81a8d6c1dfe 699 }
mbed_official 15:a81a8d6c1dfe 700 #endif
mbed_official 15:a81a8d6c1dfe 701
mbed_official 15:a81a8d6c1dfe 702 /* Write configuration to module */
mbed_official 15:a81a8d6c1dfe 703 return _adc_set_config(module_inst, config);
mbed_official 15:a81a8d6c1dfe 704 }