mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
mbed_official
Date:
Wed Jul 01 09:45:11 2015 +0100
Revision:
579:53297373a894
Child:
592:a274ee790e56
Synchronized with git revision d5b4d2ab9c47edb4dc5776e7177b0c2263459081

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

Initial version of drivers for SAMR21

Who changed what in which revision?

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