38#include <status_codes.h>
58#if SAM3S || SAM4S || SAM3N || SAM3XA || SAM4C || SAM4CP || SAM4CM
86 ul_prescal = ul_mck / (2 * ul_adc_clock) - 1;
104uint32_t
adc_init(
Adc *p_adc,
const uint32_t ul_mck,
const uint32_t ul_adc_clock,
105 const uint32_t ul_startuptime)
107 uint32_t ul_prescal, ul_startup;
117 ul_prescal = ul_mck / (2 * ul_adc_clock) - 1;
118 ul_startup = ((ul_adc_clock / 1000000) * ul_startuptime / 8) - 1;
136#if SAM4C || SAM4CP || SAM4CM
137 p_adc->
ADC_EMR &= ~ADC_EMR_OSR_Msk;
138 switch (resolution) {
153 p_adc->
ADC_MR |= resolution;
158#if SAM3S || SAM4S || SAM3N || SAM3XA || SAM4C || SAM4CP || SAM4CM
186#if SAM3S8 || SAM4S || SAM3N || SAM3SD8
203#elif SAM3U || SAM4C || SAM4CP || SAM4CM
220#if SAM3S || SAM4S || SAM3N || SAM3XA || SAM4C || SAM4CP || SAM4CM
232 volatile uint32_t *adc_seqr = &p_adc->
ADC_SEQR1;
235 for (uc_counter = 0; uc_counter < uc_num; uc_counter++) {
237 ch_list[uc_counter] << (4 * uc_counter);
240 for (uc_counter = 0; uc_counter < 8; uc_counter++) {
242 ch_list[uc_counter] << (4 * uc_counter);
244 for (uc_counter = 0; uc_counter < uc_num - 8; uc_counter++) {
246 ch_list[8 + uc_counter] << (4 * uc_counter);
252#if SAM3S || SAM4S || SAM3XA
267#elif SAM3N || SAM4C || SAM4CP || SAM4CM
287 p_adc->
ADC_MR |= ADC_MR_SHTIM(ul_sh);
291#if SAM3S || SAM4S || SAM3XA
359#if SAM3S || SAM4S || SAM3N || SAM3XA
361#elif SAM3U || SAM4C || SAM4CP || SAM4CM
384#if SAM3S || SAM4S || SAM3N || SAM3XA
386#elif SAM3U || SAM4C || SAM4CP || SAM4CM
402 return p_adc->
ADC_CHSR & (1 << adc_ch);
415 uint32_t ul_data = 0;
418 ul_data = *(p_adc->
ADC_CDR + adc_ch);
436#if SAM3S || SAM4S || SAM3N || SAM3XA || SAM4C || SAM4CP || SAM4CM
526 const uint16_t us_high_threshold)
550#if SAM3S || SAM4S || SAM3XA
559 p_adc->
ADC_COR |= 0x01u << (16 + channel);
572 p_adc->
ADC_COR &= 0xfffeffffu << channel;
584 p_adc->
ADC_COR |= 0x01u << channel;
597 p_adc->
ADC_COR &= (0xfffffffeu << channel);
611 p_adc->
ADC_CGR |= (0x03u << (2 * channel)) & (gain << (2 * channel));
615#if SAM3S8 || SAM3SD8 || SAM4S
642 ul_adcfreq = ul_mck / ((ul_prescal + 1) * 2);
668#if SAM3S || SAM4S || SAM3N || SAM3XA || SAM4C || SAM4CP || SAM4CM
702 return p_adc->ADC_SR;
718#if SAM3S || SAM4S || SAM3XA
754#if SAM3S || SAM4S || SAM3N || SAM3XA || SAM4C || SAM4CP || SAM4CM
755#ifndef ADC_WPMR_WPKEY_PASSWD
756#define ADC_WPMR_WPKEY_PASSWD ADC_WPMR_WPKEY(0x414443u)
794 uint32_t ul_startup_value = 0;
797 ul_startup_value = 0;
798 else if (ul_startup == 1)
799 ul_startup_value = 8;
800 else if (ul_startup == 2)
801 ul_startup_value = 16;
802 else if (ul_startup == 3)
803 ul_startup_value = 24;
804 else if (ul_startup == 4)
805 ul_startup_value = 64;
806 else if (ul_startup == 5)
807 ul_startup_value = 80;
808 else if (ul_startup == 6)
809 ul_startup_value = 96;
810 else if (ul_startup == 7)
811 ul_startup_value = 112;
812 else if (ul_startup == 8)
813 ul_startup_value = 512;
814 else if (ul_startup == 9)
815 ul_startup_value = 576;
816 else if (ul_startup == 10)
817 ul_startup_value = 640;
818 else if (ul_startup == 11)
819 ul_startup_value = 704;
820 else if (ul_startup == 12)
821 ul_startup_value = 768;
822 else if (ul_startup == 13)
823 ul_startup_value = 832;
824 else if (ul_startup == 14)
825 ul_startup_value = 896;
826 else if (ul_startup == 15)
827 ul_startup_value = 960;
829 return ul_startup_value;
847 ul_adcfreq = ul_mck / ((ul_prescal + 1) * 2);
848 printf(
"ADC clock frequency = %d Hz\r\n", (
int)ul_adcfreq);
851 printf(
"adc frequency too low (out of specification: %d Hz)\r\n",
855 printf(
"adc frequency too high (out of specification: %d Hz)\r\n",
865 printf(
"Startup time too small: %d, programmed: %d\r\n",
872 puts(
"FreeRun forbidden in sleep mode\r");
874#if !SAM4C && !SAM4CP && !SAM4CM
879 printf(
"Startup time too small: %d, programmed: %d\r\n",
888 printf(
"Startup time too small: %d, programmed: %d\r\n",
912#if SAM4C || SAM4CP || SAM4CM
920void adc_set_averaging_trigger(
Adc *p_adc,
bool multi)
923 p_adc->
ADC_EMR &= ~ADC_EMR_ASTE;
925 p_adc->
ADC_EMR |= ADC_EMR_ASTE;
936void adc_set_comparison_filter(
Adc *p_adc, uint8_t filter)
938 p_adc->
ADC_EMR &= ~ADC_EMR_CMPFILTER_Msk;
939 p_adc->
ADC_EMR |= ADC_EMR_CMPFILTER(filter);
949 p_adc->ADC_TEMPMR |= ADC_TEMPMR_TEMPON;
959 p_adc->ADC_TEMPMR &= ~ADC_TEMPMR_TEMPON;
970void adc_configure_ts_comparison(
Adc *p_adc,
enum adc_temp_cmp_mode mode,
971 uint16_t low_threshold, uint16_t high_threshold)
973 uint32_t tmp = p_adc->ADC_TEMPMR;
974 tmp &= ~ADC_TEMPMR_TEMPCMPMOD_Msk;
977 p_adc->ADC_TEMPCWR = ADC_TEMPCWR_TLOWTHRES(low_threshold) |
978 ADC_TEMPCWR_THIGHTHRES(high_threshold);
979 p_adc->ADC_TEMPMR = tmp;
990enum status_code adc_set_internal_reference_voltage(
Adc *p_adc,
991 struct adc_internal_ref *ref)
995 if (ref->adc_force_internal_ref && ref->adc_internal_ref_on) {
996 return ERR_INVALID_ARG;
998 tmp = (ref->adc_internal_ref_change_enable ? ADC_ACR_IRVCE_SELECTION : 0) |
999 ADC_ACR_IRVS(ref->volt) |
1000 (ref->adc_force_internal_ref ? ADC_ACR_FORCEREF : 0) |
1001 (ref->adc_internal_ref_on ? ADC_ACR_ONREF : 0);
Analog-to-Digital Converter (ADC/ADC12B) driver for SAM.
adc_startup_time
Definitions for ADC Start Up Time.
#define ADC_CWR_LOWTHRES(value)
#define ADC_EMR_CMPSEL_Pos
#define ADC_CWR_HIGHTHRES(value)
#define ADC_MR_PRESCAL(value)
#define ADC_MR_FREERUN
(ADC_MR) Free Run Mode
#define ADC_MR_STARTUP_Msk
(ADC_MR) Start Up Time
#define ADC_CR_SWRST
(ADC_CR) Software Reset
#define ADC_MR_LOWRES
(ADC_MR) Resolution
#define ADC_MR_SLEEP
(ADC_MR) Sleep Mode
#define ADC_WPMR_WPEN
(ADC_WPMR) Write Protect Enable
#define ADC_CR_START
(ADC_CR) Start Conversion
#define ADC_PTCR_TXTDIS
(ADC_PTCR) Transmitter Transfer Disable
#define ADC_LCDR_CHNB_Msk
(ADC_LCDR) Channel Number
#define ADC_WPSR_WPVSRC_Pos
#define ADC_MR_STARTUP_Pos
#define ADC_EMR_CMPSEL_Msk
(ADC_EMR) Comparison Selected Channel
#define ADC_MR_USEQ
(ADC_MR) Use Sequence Enable
#define ADC_EMR_CMPALL
(ADC_EMR) Compare All Channels
#define ADC_LCDR_CHNB_Pos
#define ADC_WPSR_WPVSRC_Msk
(ADC_WPSR) Write Protect Violation Source
#define ADC_ACR_TSON
(ADC_ACR) Temperature Sensor On
#define ADC_CR_AUTOCAL
(ADC_CR) Automatic Calibration of ADC
#define ADC_MR_ANACH
(ADC_MR) Analog Change
#define ADC_MR_SLEEP_SLEEP
(ADC_MR) Sleep Mode: The wake-up time can be modified by programming FWUP bit
#define ADC_MR_TRACKTIM(value)
#define ADC_MR_TRANSFER(value)
#define ADC_EMR_TAG
(ADC_EMR) TAG of the ADC_LDCR register
#define ADC_MR_FREERUN_ON
(ADC_MR) Free Run Mode: Never wait for any trigger.
#define ADC_ACR_IBCTL(value)
#define ADC_WPSR_WPVS
(ADC_WPSR) Write Protect Violation Status
#define ADC_MR_FWUP_ON
(ADC_MR) If SLEEP is 1 then Fast Wake-up Sleep Mode: The Voltage reference is ON between conversions ...
#define ADC_PTCR_RXTDIS
(ADC_PTCR) Receiver Transfer Disable
#define ADC_MR_PRESCAL_Pos
#define ADC_EMR_CMPMODE_Msk
(ADC_EMR) Comparison Mode
#define ADC_MR_FWUP
(ADC_MR) Fast Wake Up
#define ADC_MR_PRESCAL_Msk
(ADC_MR) Prescaler Rate Selection
void adc_disable_ts(Adc *p_adc)
Turn off temperature sensor.
void adc_configure_trigger(Adc *p_adc, const enum adc_trigger_t trigger, uint8_t uc_freerun)
Configure conversion trigger and free run mode.
uint32_t adc_get_latest_value(const Adc *p_adc)
Read the last ADC result data.
void adc_disable_channel_differential_input(Adc *p_adc, const enum adc_channel_num_t channel)
Disable differential input for the specified channel.
void adc_set_comparison_channel(Adc *p_adc, const enum adc_channel_num_t channel)
Configure comparison selected channel.
void adc_configure_timing(Adc *p_adc, const uint8_t uc_tracking, const enum adc_settling_time_t settling, const uint8_t uc_transfer)
Configure ADC timing.
void adc_set_resolution(Adc *p_adc, const enum adc_resolution_t resolution)
Configure the conversion resolution.
void adc_start_sequencer(Adc *p_adc)
Enable conversion sequencer.
uint32_t adc_get_writeprotect_status(const Adc *p_adc)
Indicate write protect status.
void adc_set_calibmode(Adc *p_adc)
Set ADC auto calibration mode.
void adc_stop_sequencer(Adc *p_adc)
Disable conversion sequencer.
void adc_set_bias_current(Adc *p_adc, const uint8_t uc_ibctl)
Adapt performance versus power consumption.
void adc_configure_sequence(Adc *p_adc, const enum adc_channel_num_t ch_list[], uint8_t uc_num)
Configure conversion sequence.
enum adc_channel_num_t adc_get_tag(const Adc *p_adc)
Indicate the last converted channel.
void adc_disable_channel_input_offset(Adc *p_adc, const enum adc_channel_num_t channel)
Disable analog signal offset for the specified channel.
uint32_t adc_get_status(const Adc *p_adc)
Get ADC interrupt and overrun error status.
uint32_t adc_get_overrun_status(const Adc *p_adc)
Get ADC interrupt and overrun error status.
void adc_disable_all_channel(Adc *p_adc)
Disable all ADC channel.
void adc_disable_tag(Adc *p_adc)
Disable TAG option.
#define ADC_WPMR_WPKEY_PASSWD
void adc_disable_channel(Adc *p_adc, const enum adc_channel_num_t adc_ch)
Disable the specified ADC channel.
void adc_disable_interrupt(Adc *p_adc, const uint32_t ul_source)
Disable ADC interrupts.
void adc_start(Adc *p_adc)
Start analog-to-digital conversion.
void adc_reset(Adc *p_adc)
Reset ADC.
uint32_t adc_get_interrupt_mask(const Adc *p_adc)
Read ADC interrupt mask.
void adc_enable_tag(Adc *p_adc)
Enable TAG option so that the number of the last converted channel can be indicated.
uint32_t adc_init(Adc *p_adc, const uint32_t ul_mck, const uint32_t ul_adc_clock, const enum adc_startup_time startup)
Initialize the given ADC with the specified ADC clock and startup time.
void adc_set_comparison_mode(Adc *p_adc, const uint8_t uc_mode)
Configure comparison mode.
void adc_disable_anch(Adc *p_adc)
Disable analog change.
void adc_enable_channel_differential_input(Adc *p_adc, const enum adc_channel_num_t channel)
Enable differential input for the specified channel.
void adc_enable_all_channel(Adc *p_adc)
Enable all ADC channels.
static uint32_t calcul_startup(const uint32_t ul_startup)
calcul_startup
void adc_set_channel_input_gain(Adc *p_adc, const enum adc_channel_num_t channel, const enum adc_gainvalue_t gain)
Configure input gain for the specified channel.
void adc_enable_interrupt(Adc *p_adc, const uint32_t ul_source)
Enable ADC interrupts.
void adc_enable_anch(Adc *p_adc)
Enable analog change.
uint32_t adc_get_channel_value(const Adc *p_adc, const enum adc_channel_num_t adc_ch)
Read the ADC result data of the specified channel.
void adc_configure_power_save(Adc *p_adc, const uint8_t uc_sleep, const uint8_t uc_fwup)
Configures ADC power saving mode.
uint32_t adc_get_actual_adc_clock(const Adc *p_adc, const uint32_t ul_mck)
Return the actual ADC clock.
void adc_set_writeprotect(Adc *p_adc, const uint32_t ul_enable)
Enable or disable write protection of ADC registers.
Pdc * adc_get_pdc_base(const Adc *p_adc)
Get PDC registers base address.
void adc_enable_channel(Adc *p_adc, const enum adc_channel_num_t adc_ch)
Enable the specified ADC channel.
void adc_check(Adc *p_adc, const uint32_t ul_mck)
Check ADC configurations.
void adc_enable_channel_input_offset(Adc *p_adc, const enum adc_channel_num_t channel)
Enable analog signal offset for the specified channel.
void adc_set_comparison_window(Adc *p_adc, const uint16_t us_low_threshold, const uint16_t us_high_threshold)
Configure ADC compare window.
uint32_t adc_get_comparison_mode(const Adc *p_adc)
Get comparison mode.
uint32_t adc_get_channel_status(const Adc *p_adc, const enum adc_channel_num_t adc_ch)
Read the ADC channel status.
void adc_enable_ts(Adc *p_adc)
Turn on temperature sensor.
#define PDC_ADC
(PDC_ADC ) Base Address
__I uint32_t ADC_WPSR
(Adc Offset: 0xE8) Write Protect Status Register
__IO uint32_t ADC_EMR
(Adc Offset: 0x40) Extended Mode Register
__O uint32_t ADC_PTCR
(Adc Offset: 0x120) Transfer Control Register
__IO uint32_t ADC_MR
(Adc Offset: 0x04) Mode Register
__I uint32_t ADC_CHSR
(Adc Offset: 0x18) Channel Status Register
__O uint32_t ADC_IDR
(Adc Offset: 0x28) Interrupt Disable Register
__I uint32_t ADC_ISR
(Adc Offset: 0x30) Interrupt Status Register
__IO uint32_t ADC_RCR
(Adc Offset: 0x104) Receive Counter Register
__O uint32_t ADC_CHER
(Adc Offset: 0x10) Channel Enable Register
__O uint32_t ADC_IER
(Adc Offset: 0x24) Interrupt Enable Register
__I uint32_t ADC_IMR
(Adc Offset: 0x2C) Interrupt Mask Register
__IO uint32_t ADC_CWR
(Adc Offset: 0x44) Compare Window Register
__IO uint32_t ADC_COR
(Adc Offset: 0x4C) Channel Offset Register
__O uint32_t ADC_CR
(Adc Offset: 0x00) Control Register
__I uint32_t ADC_LCDR
(Adc Offset: 0x20) Last Converted Data Register
__I uint32_t ADC_OVER
(Adc Offset: 0x3C) Overrun Status Register
__IO uint32_t ADC_CGR
(Adc Offset: 0x48) Channel Gain Register
__IO uint32_t ADC_SEQR1
(Adc Offset: 0x08) Channel Sequence Register 1
__IO uint32_t ADC_WPMR
(Adc Offset: 0xE4) Write Protect Mode Register
__IO uint32_t ADC_RNCR
(Adc Offset: 0x114) Receive Next Counter Register
__IO uint32_t ADC_ACR
(Adc Offset: 0x94) Analog Control Register
__I uint32_t ADC_CDR[16]
(Adc Offset: 0x50) Channel Data Register
__O uint32_t ADC_CHDR
(Adc Offset: 0x14) Channel Disable Register