mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Mon Nov 09 13:30:11 2015 +0000
Revision:
18:da299f395b9e
Synchronized with git revision f605825f66bb2e462ff7dbc5fb4ed2dbe979d1c3

Full URL: https://github.com/mbedmicro/mbed/commit/f605825f66bb2e462ff7dbc5fb4ed2dbe979d1c3/

Added support for SAML21

Who changed what in which revision?

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