Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sun May 14 23:18:57 2017 +0000
Revision:
18:6a4db94011d3
Publishing again

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sahilmgandhi 18:6a4db94011d3 1 /**
sahilmgandhi 18:6a4db94011d3 2 * \file
sahilmgandhi 18:6a4db94011d3 3 *
sahilmgandhi 18:6a4db94011d3 4 * \brief ADC Controller driver.
sahilmgandhi 18:6a4db94011d3 5 *
sahilmgandhi 18:6a4db94011d3 6 * Copyright (c) 2013-2015 Atmel Corporation. All rights reserved.
sahilmgandhi 18:6a4db94011d3 7 *
sahilmgandhi 18:6a4db94011d3 8 * \asf_license_start
sahilmgandhi 18:6a4db94011d3 9 *
sahilmgandhi 18:6a4db94011d3 10 * \page License
sahilmgandhi 18:6a4db94011d3 11 *
sahilmgandhi 18:6a4db94011d3 12 * Redistribution and use in source and binary forms, with or without
sahilmgandhi 18:6a4db94011d3 13 * modification, are permitted provided that the following conditions are met:
sahilmgandhi 18:6a4db94011d3 14 *
sahilmgandhi 18:6a4db94011d3 15 * 1. Redistributions of source code must retain the above copyright notice,
sahilmgandhi 18:6a4db94011d3 16 * this list of conditions and the following disclaimer.
sahilmgandhi 18:6a4db94011d3 17 *
sahilmgandhi 18:6a4db94011d3 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
sahilmgandhi 18:6a4db94011d3 19 * this list of conditions and the following disclaimer in the documentation
sahilmgandhi 18:6a4db94011d3 20 * and/or other materials provided with the distribution.
sahilmgandhi 18:6a4db94011d3 21 *
sahilmgandhi 18:6a4db94011d3 22 * 3. The name of Atmel may not be used to endorse or promote products derived
sahilmgandhi 18:6a4db94011d3 23 * from this software without specific prior written permission.
sahilmgandhi 18:6a4db94011d3 24 *
sahilmgandhi 18:6a4db94011d3 25 * 4. This software may only be redistributed and used in connection with an
sahilmgandhi 18:6a4db94011d3 26 * Atmel microcontroller product.
sahilmgandhi 18:6a4db94011d3 27 *
sahilmgandhi 18:6a4db94011d3 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
sahilmgandhi 18:6a4db94011d3 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
sahilmgandhi 18:6a4db94011d3 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
sahilmgandhi 18:6a4db94011d3 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
sahilmgandhi 18:6a4db94011d3 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
sahilmgandhi 18:6a4db94011d3 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
sahilmgandhi 18:6a4db94011d3 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sahilmgandhi 18:6a4db94011d3 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
sahilmgandhi 18:6a4db94011d3 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
sahilmgandhi 18:6a4db94011d3 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
sahilmgandhi 18:6a4db94011d3 38 * POSSIBILITY OF SUCH DAMAGE.
sahilmgandhi 18:6a4db94011d3 39 *
sahilmgandhi 18:6a4db94011d3 40 * \asf_license_stop
sahilmgandhi 18:6a4db94011d3 41 *
sahilmgandhi 18:6a4db94011d3 42 */
sahilmgandhi 18:6a4db94011d3 43 /*
sahilmgandhi 18:6a4db94011d3 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
sahilmgandhi 18:6a4db94011d3 45 */
sahilmgandhi 18:6a4db94011d3 46
sahilmgandhi 18:6a4db94011d3 47 #include "adc2.h"
sahilmgandhi 18:6a4db94011d3 48 #include "sleepmgr.h"
sahilmgandhi 18:6a4db94011d3 49 #include "status_codes.h"
sahilmgandhi 18:6a4db94011d3 50 #include "sysclk.h"
sahilmgandhi 18:6a4db94011d3 51 #include "pmc.h"
sahilmgandhi 18:6a4db94011d3 52
sahilmgandhi 18:6a4db94011d3 53 /**
sahilmgandhi 18:6a4db94011d3 54 * \defgroup sam_drivers_adc2_group Analog-to-Digital Controller
sahilmgandhi 18:6a4db94011d3 55 *
sahilmgandhi 18:6a4db94011d3 56 * See \ref sam_adc2_quickstart.
sahilmgandhi 18:6a4db94011d3 57 *
sahilmgandhi 18:6a4db94011d3 58 * Driver for the Analog-to-Digital Controller. This driver provides access to
sahilmgandhi 18:6a4db94011d3 59 * the main features of the ADC controller.
sahilmgandhi 18:6a4db94011d3 60 *
sahilmgandhi 18:6a4db94011d3 61 * @{
sahilmgandhi 18:6a4db94011d3 62 */
sahilmgandhi 18:6a4db94011d3 63
sahilmgandhi 18:6a4db94011d3 64 /* The number of channel in channel sequence1 register */
sahilmgandhi 18:6a4db94011d3 65 #define ADC_SEQ1_CHANNEL_NUM (8UL)
sahilmgandhi 18:6a4db94011d3 66
sahilmgandhi 18:6a4db94011d3 67 /* The number of ADC interrupt source */
sahilmgandhi 18:6a4db94011d3 68 #define ADC_NUM_OF_INTERRUPT_SOURCE (24UL)
sahilmgandhi 18:6a4db94011d3 69
sahilmgandhi 18:6a4db94011d3 70
sahilmgandhi 18:6a4db94011d3 71 const uint32_t adc_interrupt_mask[ADC_NUM_OF_INTERRUPT_SOURCE] = {
sahilmgandhi 18:6a4db94011d3 72 ADC_ISR_EOC0, ADC_ISR_EOC1, ADC_ISR_EOC2, ADC_ISR_EOC3,
sahilmgandhi 18:6a4db94011d3 73 ADC_ISR_EOC4, ADC_ISR_EOC5, ADC_ISR_EOC6, ADC_ISR_EOC7,
sahilmgandhi 18:6a4db94011d3 74 #if (SAM4N)
sahilmgandhi 18:6a4db94011d3 75 ADC_ISR_EOC8, ADC_ISR_EOC9, ADC_ISR_EOC10, ADC_ISR_EOC11,
sahilmgandhi 18:6a4db94011d3 76 ADC_ISR_EOC12, ADC_ISR_EOC13, ADC_ISR_EOC14, ADC_ISR_EOC15,
sahilmgandhi 18:6a4db94011d3 77 ADC_ISR_EOC16,
sahilmgandhi 18:6a4db94011d3 78 #endif
sahilmgandhi 18:6a4db94011d3 79 #ifdef TEMP_SENSOR
sahilmgandhi 18:6a4db94011d3 80 ADC_ISR_TEMPCHG,
sahilmgandhi 18:6a4db94011d3 81 #endif
sahilmgandhi 18:6a4db94011d3 82 ADC_ISR_EOCAL, ADC_ISR_DRDY,
sahilmgandhi 18:6a4db94011d3 83 ADC_ISR_GOVRE, ADC_ISR_COMPE, ADC_ISR_ENDRX, ADC_ISR_RXBUFF,
sahilmgandhi 18:6a4db94011d3 84 };
sahilmgandhi 18:6a4db94011d3 85
sahilmgandhi 18:6a4db94011d3 86 adc_callback_t adc_callback_pointer[ADC_NUM_OF_INTERRUPT_SOURCE];
sahilmgandhi 18:6a4db94011d3 87
sahilmgandhi 18:6a4db94011d3 88 /**
sahilmgandhi 18:6a4db94011d3 89 * \brief Get the ADC default configurations.
sahilmgandhi 18:6a4db94011d3 90 *
sahilmgandhi 18:6a4db94011d3 91 * Use to initialize the configuration structure to known default values. This
sahilmgandhi 18:6a4db94011d3 92 * function should be called at the start of any ADC initiation.
sahilmgandhi 18:6a4db94011d3 93 *
sahilmgandhi 18:6a4db94011d3 94 * The default configuration is as follows:
sahilmgandhi 18:6a4db94011d3 95 * - 10-bit resolution
sahilmgandhi 18:6a4db94011d3 96 * - ADC clock frequency is 6MHz
sahilmgandhi 18:6a4db94011d3 97 * - Start Up Time is 64 periods ADC clock
sahilmgandhi 18:6a4db94011d3 98 * - Tracking Time is 3 periods of ADC clock
sahilmgandhi 18:6a4db94011d3 99 * - Transfer Period field shall be programmed with 2 as datasheet said
sahilmgandhi 18:6a4db94011d3 100 * - The controller converts channels in a simple numeric order
sahilmgandhi 18:6a4db94011d3 101 * - Appends the channel number to the conversion result in ADC_LCDR register
sahilmgandhi 18:6a4db94011d3 102 * - Only a Single Trigger is required to get an averaged value
sahilmgandhi 18:6a4db94011d3 103 *
sahilmgandhi 18:6a4db94011d3 104 * \param cfg Pointer to configuration structure to be initiated.
sahilmgandhi 18:6a4db94011d3 105 */
sahilmgandhi 18:6a4db94011d3 106 void adc_get_config_defaults(struct adc_config *const cfg)
sahilmgandhi 18:6a4db94011d3 107 {
sahilmgandhi 18:6a4db94011d3 108 /* Sanity check argument. */
sahilmgandhi 18:6a4db94011d3 109 Assert(cfg);
sahilmgandhi 18:6a4db94011d3 110
sahilmgandhi 18:6a4db94011d3 111 #if SAMG55
sahilmgandhi 18:6a4db94011d3 112 cfg->resolution = ADC_12_BITS;
sahilmgandhi 18:6a4db94011d3 113 #else
sahilmgandhi 18:6a4db94011d3 114 cfg->resolution = ADC_10_BITS;
sahilmgandhi 18:6a4db94011d3 115 #endif
sahilmgandhi 18:6a4db94011d3 116 cfg->mck = sysclk_get_cpu_hz();
sahilmgandhi 18:6a4db94011d3 117 cfg->adc_clock = 6000000UL;
sahilmgandhi 18:6a4db94011d3 118 cfg->startup_time = ADC_STARTUP_TIME_4;
sahilmgandhi 18:6a4db94011d3 119 cfg->tracktim = 2;
sahilmgandhi 18:6a4db94011d3 120 cfg->transfer = 2;
sahilmgandhi 18:6a4db94011d3 121 cfg->useq = false;
sahilmgandhi 18:6a4db94011d3 122 cfg->tag = false;
sahilmgandhi 18:6a4db94011d3 123 cfg->aste = false;
sahilmgandhi 18:6a4db94011d3 124 }
sahilmgandhi 18:6a4db94011d3 125
sahilmgandhi 18:6a4db94011d3 126 /**
sahilmgandhi 18:6a4db94011d3 127 * \internal
sahilmgandhi 18:6a4db94011d3 128 * \brief Configure the ADC Module.
sahilmgandhi 18:6a4db94011d3 129 *
sahilmgandhi 18:6a4db94011d3 130 * \param adc Base address of the ADC
sahilmgandhi 18:6a4db94011d3 131 * \param config Configuration for the ADC
sahilmgandhi 18:6a4db94011d3 132 */
sahilmgandhi 18:6a4db94011d3 133 static void adc_set_config(Adc *const adc, struct adc_config *config)
sahilmgandhi 18:6a4db94011d3 134 {
sahilmgandhi 18:6a4db94011d3 135 uint32_t reg = 0;
sahilmgandhi 18:6a4db94011d3 136
sahilmgandhi 18:6a4db94011d3 137 reg = (config->useq ? ADC_MR_USEQ_REG_ORDER : 0) |
sahilmgandhi 18:6a4db94011d3 138 ADC_MR_PRESCAL(config->mck /
sahilmgandhi 18:6a4db94011d3 139 (2 * config->adc_clock) - 1) |
sahilmgandhi 18:6a4db94011d3 140 ADC_MR_TRACKTIM(config->tracktim) |
sahilmgandhi 18:6a4db94011d3 141 ADC_MR_TRANSFER(config->transfer) |
sahilmgandhi 18:6a4db94011d3 142 (config->startup_time);
sahilmgandhi 18:6a4db94011d3 143
sahilmgandhi 18:6a4db94011d3 144 adc->ADC_MR = reg;
sahilmgandhi 18:6a4db94011d3 145
sahilmgandhi 18:6a4db94011d3 146 adc->ADC_EMR = (config->tag ? ADC_EMR_TAG : 0) |
sahilmgandhi 18:6a4db94011d3 147 (config->aste ? ADC_EMR_ASTE_SINGLE_TRIG_AVERAGE : 0);
sahilmgandhi 18:6a4db94011d3 148
sahilmgandhi 18:6a4db94011d3 149 adc_set_resolution(adc, config->resolution);
sahilmgandhi 18:6a4db94011d3 150 }
sahilmgandhi 18:6a4db94011d3 151
sahilmgandhi 18:6a4db94011d3 152 #ifdef TEMP_SENSOR
sahilmgandhi 18:6a4db94011d3 153 /**
sahilmgandhi 18:6a4db94011d3 154 * \brief Get the ADC Temperature Sensor default configurations.
sahilmgandhi 18:6a4db94011d3 155 *
sahilmgandhi 18:6a4db94011d3 156 * Use to initialize the configuration structure to known default values.
sahilmgandhi 18:6a4db94011d3 157 *
sahilmgandhi 18:6a4db94011d3 158 * The default configuration is as follows:
sahilmgandhi 18:6a4db94011d3 159 * - Generates an event when the converted data is in the comparison window
sahilmgandhi 18:6a4db94011d3 160 * - The window range is 0xFF ~ 0xFFF
sahilmgandhi 18:6a4db94011d3 161 *
sahilmgandhi 18:6a4db94011d3 162 * \param cfg Pointer to temperature sensor configuration structure
sahilmgandhi 18:6a4db94011d3 163 * to be initiated.
sahilmgandhi 18:6a4db94011d3 164 */
sahilmgandhi 18:6a4db94011d3 165 void adc_temp_sensor_get_config_defaults(
sahilmgandhi 18:6a4db94011d3 166 struct adc_temp_sensor_config *const cfg)
sahilmgandhi 18:6a4db94011d3 167 {
sahilmgandhi 18:6a4db94011d3 168 /*Sanity check argument. */
sahilmgandhi 18:6a4db94011d3 169 Assert(cfg);
sahilmgandhi 18:6a4db94011d3 170
sahilmgandhi 18:6a4db94011d3 171 cfg->tempon = true;
sahilmgandhi 18:6a4db94011d3 172 cfg->mode = ADC_TEMP_CMP_MODE_2;
sahilmgandhi 18:6a4db94011d3 173 cfg->low_threshold = 0xFF;
sahilmgandhi 18:6a4db94011d3 174 cfg->high_threshold = 0xFFF;
sahilmgandhi 18:6a4db94011d3 175 }
sahilmgandhi 18:6a4db94011d3 176
sahilmgandhi 18:6a4db94011d3 177 /**
sahilmgandhi 18:6a4db94011d3 178 * \brief Configure the ADC temperature sensor.
sahilmgandhi 18:6a4db94011d3 179 *
sahilmgandhi 18:6a4db94011d3 180 * \param adc Base address of the ADC
sahilmgandhi 18:6a4db94011d3 181 * \param config Configuration for the ADC temperature sensor
sahilmgandhi 18:6a4db94011d3 182 */
sahilmgandhi 18:6a4db94011d3 183 void adc_temp_sensor_set_config(Adc *const adc,
sahilmgandhi 18:6a4db94011d3 184 struct adc_temp_sensor_config *config)
sahilmgandhi 18:6a4db94011d3 185 {
sahilmgandhi 18:6a4db94011d3 186 uint32_t reg = 0;
sahilmgandhi 18:6a4db94011d3 187
sahilmgandhi 18:6a4db94011d3 188 reg = ((config->tempon) ? ADC_TEMPMR_TEMPON : 0) | (config->mode);
sahilmgandhi 18:6a4db94011d3 189 adc->ADC_TEMPMR = reg;
sahilmgandhi 18:6a4db94011d3 190
sahilmgandhi 18:6a4db94011d3 191 adc->ADC_TEMPCWR = ADC_TEMPCWR_TLOWTHRES(config->low_threshold) |
sahilmgandhi 18:6a4db94011d3 192 ADC_TEMPCWR_THIGHTHRES(config->high_threshold);
sahilmgandhi 18:6a4db94011d3 193 }
sahilmgandhi 18:6a4db94011d3 194 #endif
sahilmgandhi 18:6a4db94011d3 195
sahilmgandhi 18:6a4db94011d3 196 #if (SAMG)
sahilmgandhi 18:6a4db94011d3 197 /**
sahilmgandhi 18:6a4db94011d3 198 * \brief Get the Last Channel Specific Measurement default configurations.
sahilmgandhi 18:6a4db94011d3 199 *
sahilmgandhi 18:6a4db94011d3 200 * Use to initialize the configuration structure to known default values.
sahilmgandhi 18:6a4db94011d3 201 *
sahilmgandhi 18:6a4db94011d3 202 * The default configuration is as follows:
sahilmgandhi 18:6a4db94011d3 203 * - Generates an event when the converted data is in the comparison window
sahilmgandhi 18:6a4db94011d3 204 * - The window range is 0xFF ~ 0xFFF
sahilmgandhi 18:6a4db94011d3 205 *
sahilmgandhi 18:6a4db94011d3 206 * \param cfg Pointer to last channel configuration structure
sahilmgandhi 18:6a4db94011d3 207 * to be initiated.
sahilmgandhi 18:6a4db94011d3 208 */
sahilmgandhi 18:6a4db94011d3 209 void adc_last_channel_get_config_defaults(
sahilmgandhi 18:6a4db94011d3 210 struct adc_last_channel_config *const cfg)
sahilmgandhi 18:6a4db94011d3 211 {
sahilmgandhi 18:6a4db94011d3 212 /*Sanity check argument. */
sahilmgandhi 18:6a4db94011d3 213 Assert(cfg);
sahilmgandhi 18:6a4db94011d3 214
sahilmgandhi 18:6a4db94011d3 215 cfg->dual_trig_on = true;
sahilmgandhi 18:6a4db94011d3 216 cfg->mode = ADC_LAST_CHANNEL_CMP_MODE_2;
sahilmgandhi 18:6a4db94011d3 217 cfg->low_threshold = 0xFF;
sahilmgandhi 18:6a4db94011d3 218 cfg->high_threshold = 0xFFF;
sahilmgandhi 18:6a4db94011d3 219 }
sahilmgandhi 18:6a4db94011d3 220
sahilmgandhi 18:6a4db94011d3 221 /**
sahilmgandhi 18:6a4db94011d3 222 * \brief Configure the ADC Last Channel Specific Measurement.
sahilmgandhi 18:6a4db94011d3 223 *
sahilmgandhi 18:6a4db94011d3 224 * \param adc Base address of the ADC
sahilmgandhi 18:6a4db94011d3 225 * \param config Configuration for the last channel
sahilmgandhi 18:6a4db94011d3 226 */
sahilmgandhi 18:6a4db94011d3 227 void adc_last_channel_set_config(Adc *const adc,
sahilmgandhi 18:6a4db94011d3 228 struct adc_last_channel_config *config)
sahilmgandhi 18:6a4db94011d3 229 {
sahilmgandhi 18:6a4db94011d3 230 uint32_t reg = 0;
sahilmgandhi 18:6a4db94011d3 231
sahilmgandhi 18:6a4db94011d3 232 reg = ((config->dual_trig_on) ? ADC_LCTMR_DUALTRIG : 0) | (config->mode);
sahilmgandhi 18:6a4db94011d3 233 adc->ADC_LCTMR = reg;
sahilmgandhi 18:6a4db94011d3 234
sahilmgandhi 18:6a4db94011d3 235 adc->ADC_LCCWR = ADC_LCCWR_LOWTHRES(config->low_threshold) |
sahilmgandhi 18:6a4db94011d3 236 ADC_LCCWR_HIGHTHRES(config->high_threshold);
sahilmgandhi 18:6a4db94011d3 237 }
sahilmgandhi 18:6a4db94011d3 238 #endif
sahilmgandhi 18:6a4db94011d3 239
sahilmgandhi 18:6a4db94011d3 240 /**
sahilmgandhi 18:6a4db94011d3 241 * \brief Initialize the ADC Module.
sahilmgandhi 18:6a4db94011d3 242 *
sahilmgandhi 18:6a4db94011d3 243 * \param adc Base address of the ADC
sahilmgandhi 18:6a4db94011d3 244 * \param config Configuration for the ADC
sahilmgandhi 18:6a4db94011d3 245 *
sahilmgandhi 18:6a4db94011d3 246 * \retval STATUS_OK Initialization is finished.
sahilmgandhi 18:6a4db94011d3 247 * \retval STATUS_ERR_BUSY Initialization failed.
sahilmgandhi 18:6a4db94011d3 248 */
sahilmgandhi 18:6a4db94011d3 249 enum status_code adc_init(Adc *const adc, struct adc_config *config)
sahilmgandhi 18:6a4db94011d3 250 {
sahilmgandhi 18:6a4db94011d3 251 Assert(adc);
sahilmgandhi 18:6a4db94011d3 252 Assert(config);
sahilmgandhi 18:6a4db94011d3 253
sahilmgandhi 18:6a4db94011d3 254 if ((adc_get_interrupt_status(adc) & ADC_ISR_DRDY) == ADC_ISR_DRDY) {
sahilmgandhi 18:6a4db94011d3 255 return STATUS_ERR_BUSY;
sahilmgandhi 18:6a4db94011d3 256 }
sahilmgandhi 18:6a4db94011d3 257
sahilmgandhi 18:6a4db94011d3 258 /* Reset and configure the ADC module */
sahilmgandhi 18:6a4db94011d3 259 adc->ADC_CR = ADC_CR_SWRST;
sahilmgandhi 18:6a4db94011d3 260 adc_set_config(adc, config);
sahilmgandhi 18:6a4db94011d3 261
sahilmgandhi 18:6a4db94011d3 262 uint32_t i;
sahilmgandhi 18:6a4db94011d3 263 for (i = 0; i < ADC_NUM_OF_INTERRUPT_SOURCE; i++) {
sahilmgandhi 18:6a4db94011d3 264 adc_callback_pointer[i] = 0;
sahilmgandhi 18:6a4db94011d3 265 }
sahilmgandhi 18:6a4db94011d3 266
sahilmgandhi 18:6a4db94011d3 267 return STATUS_OK;
sahilmgandhi 18:6a4db94011d3 268 }
sahilmgandhi 18:6a4db94011d3 269
sahilmgandhi 18:6a4db94011d3 270 /**
sahilmgandhi 18:6a4db94011d3 271 * \brief Configure conversion resolution.
sahilmgandhi 18:6a4db94011d3 272 *
sahilmgandhi 18:6a4db94011d3 273 * \param adc Base address of the ADC.
sahilmgandhi 18:6a4db94011d3 274 * \param res Conversion resolution.
sahilmgandhi 18:6a4db94011d3 275 *
sahilmgandhi 18:6a4db94011d3 276 */
sahilmgandhi 18:6a4db94011d3 277 void adc_set_resolution(Adc *const adc,
sahilmgandhi 18:6a4db94011d3 278 const enum adc_resolution res)
sahilmgandhi 18:6a4db94011d3 279 {
sahilmgandhi 18:6a4db94011d3 280 #if SAMG55
sahilmgandhi 18:6a4db94011d3 281 adc->ADC_EMR |= res;
sahilmgandhi 18:6a4db94011d3 282 #else
sahilmgandhi 18:6a4db94011d3 283 if (res == ADC_11_BITS || res == ADC_12_BITS) {
sahilmgandhi 18:6a4db94011d3 284 adc->ADC_MR &= ~ADC_MR_LOWRES;
sahilmgandhi 18:6a4db94011d3 285 adc->ADC_EMR |= res;
sahilmgandhi 18:6a4db94011d3 286 } else {
sahilmgandhi 18:6a4db94011d3 287 adc->ADC_MR |= res;
sahilmgandhi 18:6a4db94011d3 288 adc->ADC_EMR &= ~ADC_EMR_OSR_Msk;
sahilmgandhi 18:6a4db94011d3 289 }
sahilmgandhi 18:6a4db94011d3 290 #endif
sahilmgandhi 18:6a4db94011d3 291 }
sahilmgandhi 18:6a4db94011d3 292
sahilmgandhi 18:6a4db94011d3 293 /**
sahilmgandhi 18:6a4db94011d3 294 * \brief Configure comparison mode.
sahilmgandhi 18:6a4db94011d3 295 *
sahilmgandhi 18:6a4db94011d3 296 * \param adc Base address of the ADC.
sahilmgandhi 18:6a4db94011d3 297 * \param mode Comparison mode.
sahilmgandhi 18:6a4db94011d3 298 * \param channel Comparison Selected Channel.
sahilmgandhi 18:6a4db94011d3 299 * \param cmp_filter Compare Event Filtering.
sahilmgandhi 18:6a4db94011d3 300 */
sahilmgandhi 18:6a4db94011d3 301 void adc_set_comparison_mode(Adc *const adc,
sahilmgandhi 18:6a4db94011d3 302 const enum adc_cmp_mode mode,
sahilmgandhi 18:6a4db94011d3 303 const enum adc_channel_num channel, uint8_t cmp_filter)
sahilmgandhi 18:6a4db94011d3 304 {
sahilmgandhi 18:6a4db94011d3 305 if (channel != ADC_CHANNEL_ALL) {
sahilmgandhi 18:6a4db94011d3 306 adc_ch_sanity_check(adc, channel);
sahilmgandhi 18:6a4db94011d3 307 }
sahilmgandhi 18:6a4db94011d3 308
sahilmgandhi 18:6a4db94011d3 309 uint32_t reg;
sahilmgandhi 18:6a4db94011d3 310
sahilmgandhi 18:6a4db94011d3 311 reg = adc->ADC_EMR;
sahilmgandhi 18:6a4db94011d3 312
sahilmgandhi 18:6a4db94011d3 313 reg &= ~(ADC_EMR_CMPSEL_Msk |
sahilmgandhi 18:6a4db94011d3 314 ADC_EMR_CMPMODE_Msk |
sahilmgandhi 18:6a4db94011d3 315 ADC_EMR_CMPFILTER_Msk);
sahilmgandhi 18:6a4db94011d3 316 reg |= mode |
sahilmgandhi 18:6a4db94011d3 317 ((channel == ADC_CHANNEL_ALL) ? ADC_EMR_CMPALL
sahilmgandhi 18:6a4db94011d3 318 : ADC_EMR_CMPSEL(channel)) |
sahilmgandhi 18:6a4db94011d3 319 ADC_EMR_CMPFILTER(cmp_filter);
sahilmgandhi 18:6a4db94011d3 320
sahilmgandhi 18:6a4db94011d3 321 adc->ADC_EMR = reg;
sahilmgandhi 18:6a4db94011d3 322 }
sahilmgandhi 18:6a4db94011d3 323
sahilmgandhi 18:6a4db94011d3 324 /**
sahilmgandhi 18:6a4db94011d3 325 * \brief Configure ADC power mode.
sahilmgandhi 18:6a4db94011d3 326 *
sahilmgandhi 18:6a4db94011d3 327 * \param adc Base address of the ADC.
sahilmgandhi 18:6a4db94011d3 328 * \param mode ADC power mode value.
sahilmgandhi 18:6a4db94011d3 329 */
sahilmgandhi 18:6a4db94011d3 330 void adc_set_power_mode(Adc *const adc,
sahilmgandhi 18:6a4db94011d3 331 const enum adc_power_mode mode)
sahilmgandhi 18:6a4db94011d3 332 {
sahilmgandhi 18:6a4db94011d3 333 uint32_t reg;
sahilmgandhi 18:6a4db94011d3 334
sahilmgandhi 18:6a4db94011d3 335 reg = adc->ADC_MR;
sahilmgandhi 18:6a4db94011d3 336
sahilmgandhi 18:6a4db94011d3 337 switch (mode) {
sahilmgandhi 18:6a4db94011d3 338 case ADC_POWER_MODE_0:
sahilmgandhi 18:6a4db94011d3 339 reg |= ADC_MR_SLEEP_NORMAL;
sahilmgandhi 18:6a4db94011d3 340 break;
sahilmgandhi 18:6a4db94011d3 341
sahilmgandhi 18:6a4db94011d3 342 case ADC_POWER_MODE_1:
sahilmgandhi 18:6a4db94011d3 343 reg |= ADC_MR_SLEEP_SLEEP;
sahilmgandhi 18:6a4db94011d3 344 break;
sahilmgandhi 18:6a4db94011d3 345 }
sahilmgandhi 18:6a4db94011d3 346
sahilmgandhi 18:6a4db94011d3 347 adc->ADC_MR = reg;
sahilmgandhi 18:6a4db94011d3 348 }
sahilmgandhi 18:6a4db94011d3 349
sahilmgandhi 18:6a4db94011d3 350 /**
sahilmgandhi 18:6a4db94011d3 351 * \brief Set callback for ADC
sahilmgandhi 18:6a4db94011d3 352 *
sahilmgandhi 18:6a4db94011d3 353 * \param adc Base address of the ADC
sahilmgandhi 18:6a4db94011d3 354 * \param source Interrupt source
sahilmgandhi 18:6a4db94011d3 355 * \param callback Callback function pointer
sahilmgandhi 18:6a4db94011d3 356 * \param irq_level Interrupt level
sahilmgandhi 18:6a4db94011d3 357 */
sahilmgandhi 18:6a4db94011d3 358 void adc_set_callback(Adc *const adc, enum adc_interrupt_source source,
sahilmgandhi 18:6a4db94011d3 359 adc_callback_t callback, uint8_t irq_level)
sahilmgandhi 18:6a4db94011d3 360 {
sahilmgandhi 18:6a4db94011d3 361 Assert(adc);
sahilmgandhi 18:6a4db94011d3 362 Assert(callback);
sahilmgandhi 18:6a4db94011d3 363
sahilmgandhi 18:6a4db94011d3 364 adc_callback_pointer[source] = callback;
sahilmgandhi 18:6a4db94011d3 365 irq_register_handler(ADC_IRQn, irq_level);
sahilmgandhi 18:6a4db94011d3 366
sahilmgandhi 18:6a4db94011d3 367 /* Enable the specified interrupt source */
sahilmgandhi 18:6a4db94011d3 368 adc_enable_interrupt(adc, source);
sahilmgandhi 18:6a4db94011d3 369 }
sahilmgandhi 18:6a4db94011d3 370
sahilmgandhi 18:6a4db94011d3 371 /**
sahilmgandhi 18:6a4db94011d3 372 * \brief Enable ADC interrupts.
sahilmgandhi 18:6a4db94011d3 373 *
sahilmgandhi 18:6a4db94011d3 374 * \param adc Base address of the ADC.
sahilmgandhi 18:6a4db94011d3 375 * \param interrupt_source Interrupts to be enabled.
sahilmgandhi 18:6a4db94011d3 376 */
sahilmgandhi 18:6a4db94011d3 377 void adc_enable_interrupt(Adc *const adc,
sahilmgandhi 18:6a4db94011d3 378 enum adc_interrupt_source interrupt_source)
sahilmgandhi 18:6a4db94011d3 379 {
sahilmgandhi 18:6a4db94011d3 380 if (interrupt_source == ADC_INTERRUPT_ALL) {
sahilmgandhi 18:6a4db94011d3 381 adc->ADC_IER = ADC_INTERRUPT_ALL;
sahilmgandhi 18:6a4db94011d3 382 return;
sahilmgandhi 18:6a4db94011d3 383 } else {
sahilmgandhi 18:6a4db94011d3 384 adc->ADC_IER = adc_interrupt_mask[interrupt_source];
sahilmgandhi 18:6a4db94011d3 385 }
sahilmgandhi 18:6a4db94011d3 386 }
sahilmgandhi 18:6a4db94011d3 387
sahilmgandhi 18:6a4db94011d3 388 /**
sahilmgandhi 18:6a4db94011d3 389 * \brief Disable ADC interrupts.
sahilmgandhi 18:6a4db94011d3 390 *
sahilmgandhi 18:6a4db94011d3 391 * \param adc Base address of the ADC.
sahilmgandhi 18:6a4db94011d3 392 * \param interrupt_source Interrupts to be disabled.
sahilmgandhi 18:6a4db94011d3 393 */
sahilmgandhi 18:6a4db94011d3 394 void adc_disable_interrupt(Adc *const adc,
sahilmgandhi 18:6a4db94011d3 395 enum adc_interrupt_source interrupt_source)
sahilmgandhi 18:6a4db94011d3 396 {
sahilmgandhi 18:6a4db94011d3 397 if (interrupt_source == ADC_INTERRUPT_ALL) {
sahilmgandhi 18:6a4db94011d3 398 adc->ADC_IDR = ADC_INTERRUPT_ALL;
sahilmgandhi 18:6a4db94011d3 399 return;
sahilmgandhi 18:6a4db94011d3 400 } else {
sahilmgandhi 18:6a4db94011d3 401 adc->ADC_IDR = adc_interrupt_mask[interrupt_source];
sahilmgandhi 18:6a4db94011d3 402 }
sahilmgandhi 18:6a4db94011d3 403 }
sahilmgandhi 18:6a4db94011d3 404
sahilmgandhi 18:6a4db94011d3 405 /**
sahilmgandhi 18:6a4db94011d3 406 * \internal
sahilmgandhi 18:6a4db94011d3 407 * \brief Common ADC interrupt handler
sahilmgandhi 18:6a4db94011d3 408 *
sahilmgandhi 18:6a4db94011d3 409 * The optional callback used by the interrupt handler is set by the
sahilmgandhi 18:6a4db94011d3 410 * adc_set_callback() function.
sahilmgandhi 18:6a4db94011d3 411 *
sahilmgandhi 18:6a4db94011d3 412 * \param inst_num ADC instance number to handle interrupt for
sahilmgandhi 18:6a4db94011d3 413 * \param source Interrupt source number
sahilmgandhi 18:6a4db94011d3 414 */
sahilmgandhi 18:6a4db94011d3 415 static void adc_interrupt(enum adc_interrupt_source source)
sahilmgandhi 18:6a4db94011d3 416 {
sahilmgandhi 18:6a4db94011d3 417 if (adc_callback_pointer[source]) {
sahilmgandhi 18:6a4db94011d3 418 adc_callback_pointer[source]();
sahilmgandhi 18:6a4db94011d3 419 }
sahilmgandhi 18:6a4db94011d3 420 }
sahilmgandhi 18:6a4db94011d3 421
sahilmgandhi 18:6a4db94011d3 422 /**
sahilmgandhi 18:6a4db94011d3 423 * \internal
sahilmgandhi 18:6a4db94011d3 424 * \brief Call the callback function if the corresponding interrupt is asserted
sahilmgandhi 18:6a4db94011d3 425 *
sahilmgandhi 18:6a4db94011d3 426 * \param adc Base address of the ADC.
sahilmgandhi 18:6a4db94011d3 427 */
sahilmgandhi 18:6a4db94011d3 428 static void adc_process_callback(Adc *const adc)
sahilmgandhi 18:6a4db94011d3 429 {
sahilmgandhi 18:6a4db94011d3 430 volatile uint32_t status;
sahilmgandhi 18:6a4db94011d3 431 uint32_t cnt;
sahilmgandhi 18:6a4db94011d3 432
sahilmgandhi 18:6a4db94011d3 433 status = adc_get_interrupt_status(adc);
sahilmgandhi 18:6a4db94011d3 434
sahilmgandhi 18:6a4db94011d3 435 for (cnt = 0; cnt < ADC_NUM_OF_INTERRUPT_SOURCE; cnt++) {
sahilmgandhi 18:6a4db94011d3 436 if (status & adc_interrupt_mask[cnt]) {
sahilmgandhi 18:6a4db94011d3 437 adc_interrupt((enum adc_interrupt_source)cnt);
sahilmgandhi 18:6a4db94011d3 438 }
sahilmgandhi 18:6a4db94011d3 439 }
sahilmgandhi 18:6a4db94011d3 440 }
sahilmgandhi 18:6a4db94011d3 441
sahilmgandhi 18:6a4db94011d3 442 /**
sahilmgandhi 18:6a4db94011d3 443 * \brief Interrupt handler for ADC.
sahilmgandhi 18:6a4db94011d3 444 */
sahilmgandhi 18:6a4db94011d3 445 void ADC_Handler(void)
sahilmgandhi 18:6a4db94011d3 446 {
sahilmgandhi 18:6a4db94011d3 447 adc_process_callback(ADC);
sahilmgandhi 18:6a4db94011d3 448 }
sahilmgandhi 18:6a4db94011d3 449
sahilmgandhi 18:6a4db94011d3 450 /**
sahilmgandhi 18:6a4db94011d3 451 * \brief Enable ADC Module.
sahilmgandhi 18:6a4db94011d3 452 *
sahilmgandhi 18:6a4db94011d3 453 */
sahilmgandhi 18:6a4db94011d3 454 void adc_enable(void)
sahilmgandhi 18:6a4db94011d3 455 {
sahilmgandhi 18:6a4db94011d3 456 /* Enable peripheral clock. */
sahilmgandhi 18:6a4db94011d3 457 pmc_enable_periph_clk(ID_ADC);
sahilmgandhi 18:6a4db94011d3 458 sleepmgr_lock_mode(SLEEP_MODE_ADC);
sahilmgandhi 18:6a4db94011d3 459 }
sahilmgandhi 18:6a4db94011d3 460
sahilmgandhi 18:6a4db94011d3 461 /**
sahilmgandhi 18:6a4db94011d3 462 * \brief Disable ADC Module.
sahilmgandhi 18:6a4db94011d3 463 *
sahilmgandhi 18:6a4db94011d3 464 */
sahilmgandhi 18:6a4db94011d3 465 void adc_disable(void)
sahilmgandhi 18:6a4db94011d3 466 {
sahilmgandhi 18:6a4db94011d3 467 /* Disable peripheral clock. */
sahilmgandhi 18:6a4db94011d3 468 pmc_disable_periph_clk(ID_ADC);
sahilmgandhi 18:6a4db94011d3 469 sleepmgr_unlock_mode(SLEEP_MODE_ADC);
sahilmgandhi 18:6a4db94011d3 470 }
sahilmgandhi 18:6a4db94011d3 471
sahilmgandhi 18:6a4db94011d3 472 /**
sahilmgandhi 18:6a4db94011d3 473 * \brief Configure conversion sequence.
sahilmgandhi 18:6a4db94011d3 474 *
sahilmgandhi 18:6a4db94011d3 475 * \param adc Base address of the ADC.
sahilmgandhi 18:6a4db94011d3 476 * \param ch_list Channel sequence list.
sahilmgandhi 18:6a4db94011d3 477 * \param uc_num Number of channels in the list.
sahilmgandhi 18:6a4db94011d3 478 */
sahilmgandhi 18:6a4db94011d3 479 void adc_configure_sequence(Adc *const adc,
sahilmgandhi 18:6a4db94011d3 480 const enum adc_channel_num ch_list[], uint8_t uc_num)
sahilmgandhi 18:6a4db94011d3 481 {
sahilmgandhi 18:6a4db94011d3 482 uint8_t uc_counter;
sahilmgandhi 18:6a4db94011d3 483
sahilmgandhi 18:6a4db94011d3 484 /* Set user sequence mode */
sahilmgandhi 18:6a4db94011d3 485 adc->ADC_MR |= ADC_MR_USEQ_REG_ORDER;
sahilmgandhi 18:6a4db94011d3 486 #if (SAM4N)
sahilmgandhi 18:6a4db94011d3 487 adc->ADC_SEQR1 = 0;
sahilmgandhi 18:6a4db94011d3 488 adc->ADC_SEQR2 = 0;
sahilmgandhi 18:6a4db94011d3 489 #endif
sahilmgandhi 18:6a4db94011d3 490 #if (SAMG)
sahilmgandhi 18:6a4db94011d3 491 adc->ADC_SEQR1 = 0;
sahilmgandhi 18:6a4db94011d3 492 #endif
sahilmgandhi 18:6a4db94011d3 493
sahilmgandhi 18:6a4db94011d3 494 if (uc_num <= ADC_SEQ1_CHANNEL_NUM) {
sahilmgandhi 18:6a4db94011d3 495 for (uc_counter = 0; uc_counter < uc_num; uc_counter++) {
sahilmgandhi 18:6a4db94011d3 496 #if (SAM4N || SAMG)
sahilmgandhi 18:6a4db94011d3 497 adc->ADC_SEQR1
sahilmgandhi 18:6a4db94011d3 498 #endif
sahilmgandhi 18:6a4db94011d3 499 |= ch_list[uc_counter] << (4 * uc_counter);
sahilmgandhi 18:6a4db94011d3 500 }
sahilmgandhi 18:6a4db94011d3 501 } else {
sahilmgandhi 18:6a4db94011d3 502 for (uc_counter = 0; uc_counter <= ADC_SEQ1_CHANNEL_NUM;
sahilmgandhi 18:6a4db94011d3 503 uc_counter++) {
sahilmgandhi 18:6a4db94011d3 504 #if (SAM4N || SAMG)
sahilmgandhi 18:6a4db94011d3 505 adc->ADC_SEQR1
sahilmgandhi 18:6a4db94011d3 506 #endif
sahilmgandhi 18:6a4db94011d3 507 |= ch_list[uc_counter] << (4 * uc_counter);
sahilmgandhi 18:6a4db94011d3 508 }
sahilmgandhi 18:6a4db94011d3 509 for (uc_counter = 0; uc_counter < uc_num - ADC_SEQ1_CHANNEL_NUM;
sahilmgandhi 18:6a4db94011d3 510 uc_counter++) {
sahilmgandhi 18:6a4db94011d3 511 #if (SAM4N)
sahilmgandhi 18:6a4db94011d3 512 adc->ADC_SEQR2 |= ch_list[8 + uc_counter] << (4 * uc_counter);
sahilmgandhi 18:6a4db94011d3 513 #endif
sahilmgandhi 18:6a4db94011d3 514 }
sahilmgandhi 18:6a4db94011d3 515 }
sahilmgandhi 18:6a4db94011d3 516 }
sahilmgandhi 18:6a4db94011d3 517
sahilmgandhi 18:6a4db94011d3 518 //@}