From 044ad7c3987460ede48ff27afd6bdb0ca05a0432 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2011 20:52:54 +0200 Subject: import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v15011 it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself --- peripherals/adc/adc.c | 346 ++++++++++++++++++++++++++++++++++++++++++++++++ peripherals/adc/adc.dir | 37 ++++++ peripherals/adc/adc.h | 145 ++++++++++++++++++++ peripherals/adc/adc12.c | 196 +++++++++++++++++++++++++++ peripherals/adc/adc12.h | 142 ++++++++++++++++++++ 5 files changed, 866 insertions(+) create mode 100644 peripherals/adc/adc.c create mode 100644 peripherals/adc/adc.dir create mode 100644 peripherals/adc/adc.h create mode 100644 peripherals/adc/adc12.c create mode 100644 peripherals/adc/adc12.h (limited to 'peripherals/adc') diff --git a/peripherals/adc/adc.c b/peripherals/adc/adc.c new file mode 100644 index 0000000..6e0cfac --- /dev/null +++ b/peripherals/adc/adc.c @@ -0,0 +1,346 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include +#include +#include +#include + +//----------------------------------------------------------------------------- +/// Configure the Mode Register of the ADC controller +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param mode value to write in mode register +//----------------------------------------------------------------------------- + +//replaced with macro definition in adc.h + +//void ADC_CfgModeReg(AT91S_ADC *pAdc, unsigned int mode, unsigned int extmode) +//{ +// ASSERT((mode&0xF00000C0)== 0, "ADC Bad configuration ADC MR"); +// +// // Write to the MR register +// pAdc->ADC_MR = mode; +//} + +//------------------------------------------------------------------------------ +// Global Functions +//------------------------------------------------------------------------------ + +//----------------------------------------------------------------------------- +/// Initialize the ADC controller +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param trgEn trigger mode, software or Hardware +/// \param trgSel hardware trigger selection +/// \param sleepMode sleep mode selection +/// \param resolution resolution selection 8 bits or 10 bits +/// \param mckClock value of MCK in Hz +/// \param adcClock value of the ADC clock in Hz +/// \param startupTime value of the start up time (in us) (see datasheet) +/// \param sampleAndHoldTime (in ns) +//----------------------------------------------------------------------------- +void ADC_Initialize (AT91S_ADC *pAdc, + unsigned char idAdc, + unsigned char trgEn, + unsigned char trgSel, + unsigned char sleepMode, + unsigned char resolution, + unsigned int mckClock, + unsigned int adcClock, + unsigned int startupTime, + unsigned int sampleAndHoldTime) +{ + unsigned int prescal; + unsigned int startup; + unsigned int shtim; + + ASSERT(startupTime<=ADC_STARTUP_TIME_MAX, "ADC Bad startupTime\n\r"); + ASSERT(sampleAndHoldTime>=ADC_TRACK_HOLD_TIME_MIN, "ADC Bad sampleAndHoldTime\n\r"); + + // Example: + // 5 MHz operation, 20us startup time, 600ns track and hold time + // PRESCAL: Prescaler Rate Selection ADCClock = MCK / ( (PRESCAL+1) * 2 ) + // PRESCAL = [MCK / (ADCClock * 2)] -1 = [48/(5*2)]-1 = 3,8 + // PRESCAL = 4 -> 48/((4+1)*2) = 48/10 = 4.8MHz + // 48/((3+1)*2) = 48/8 = 6MHz + // Startup Time = (STARTUP+1) * 8 / ADCClock + // STARTUP = [(Startup Time * ADCClock)/8]-1 = [(20 10e-6 * 5000000)/8]-1 = 11,5 + // STARTUP = 11 -> (11+1)*8/48000000 = 96/4800000 = 20us + // + // Sample & Hold Time = (SHTIM) / ADCClock + // SHTIM = (HoldTime * ADCClock) = (600 10e-9 * 5000000) = 3 + // SHTIM = 3 -> (3)/4800000 = 1/1600000 = 625ns + prescal = (mckClock / (2*adcClock)) - 1; + startup = ((adcClock/1000000) * startupTime / 8) - 1; + shtim = (((adcClock/1000000) * sampleAndHoldTime)/1000); + + ASSERT( (prescal<0x3F), "ADC Bad PRESCAL\n\r"); + ASSERT(startup<0x7F, "ADC Bad STARTUP\n\r"); + ASSERT(shtim<0xF, "ADC Bad SampleAndHoldTime\n\r"); + + TRACE_DEBUG("adcClock:%d MasterClock:%d\n\r", (mckClock/((prescal+1)*2)), mckClock); + TRACE_DEBUG("prescal:0x%X startup:0x%X shtim:0x%X\n\r", prescal, startup, shtim); + + if( adcClock != (mckClock/((prescal+1)*2)) ) { + TRACE_WARNING("User and calculated adcClocks are different : user=%d calc=%d\n\r", + adcClock, (mckClock/((prescal+1)*2))); + } + + // Enable peripheral clock + AT91C_BASE_PMC->PMC_PCER = 1 << idAdc; + + // Reset the controller + ADC_SoftReset(pAdc); + + // Write to the MR register + ADC_CfgModeReg( pAdc, + ( trgEn & AT91C_ADC_TRGEN) + | ( trgSel & AT91C_ADC_TRGSEL) + | ( resolution & AT91C_ADC_LOWRES) + | ( sleepMode & AT91C_ADC_SLEEP) + | ( (prescal<<8) & AT91C_ADC_PRESCAL) + | ( (startup<<16) & AT91C_ADC_STARTUP) + | ( (shtim<<24) & AT91C_ADC_SHTIM) ); +} + +//----------------------------------------------------------------------------- +/// Return the Mode Register of the ADC controller value +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \return ADC Mode register +//----------------------------------------------------------------------------- + +//replaced with macro definition in adc.h + +//unsigned int ADC_GetModeReg(AT91S_ADC *pAdc) +//{ +// return pAdc->ADC_MR; +//} + +//----------------------------------------------------------------------------- +/// Enable Channel +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param channel channel to enable +//----------------------------------------------------------------------------- +//void ADC_EnableChannel(AT91S_ADC *pAdc, unsigned int channel) +//{ +// ASSERT(channel < 8, "ADC Channel not exist"); +// +// // Write to the CHER register +// pAdc->ADC_CHER = (1 << channel); +//} + +//----------------------------------------------------------------------------- +/// Disable Channel +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param channel channel to disable +//----------------------------------------------------------------------------- +//void ADC_DisableChannel (AT91S_ADC *pAdc, unsigned int channel) +//{ +// ASSERT(channel < 8, "ADC Channel not exist"); +// +// // Write to the CHDR register +// pAdc->ADC_CHDR = (1 << channel); +//} + +//----------------------------------------------------------------------------- +/// Return chanel status +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \return ADC Channel Status Register +//----------------------------------------------------------------------------- +//unsigned int ADC_GetChannelStatus(AT91S_ADC *pAdc) +//{ +// return pAdc->ADC_CHSR; +//} + +//----------------------------------------------------------------------------- +/// Software request for a analog to digital conversion +/// \param pAdc Pointer to an AT91S_ADC instance. +//----------------------------------------------------------------------------- +//void ADC_StartConversion(AT91S_ADC *pAdc) +//{ +// pAdc->ADC_CR = AT91C_ADC_START; +//} + +//----------------------------------------------------------------------------- +/// Software reset +/// \param pAdc Pointer to an AT91S_ADC instance. +//----------------------------------------------------------------------------- +//void ADC_SoftReset(AT91S_ADC *pAdc) +//{ +// pAdc->ADC_CR = AT91C_ADC_SWRST; +//} + +//----------------------------------------------------------------------------- +/// Return the Last Converted Data +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \return Last Converted Data +//----------------------------------------------------------------------------- +//unsigned int ADC_GetLastConvertedData(AT91S_ADC *pAdc) +//{ +// return pAdc->ADC_LCDR; +//} + +//----------------------------------------------------------------------------- +/// Return the Channel Converted Data +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param channel channel to get converted value +/// \return Channel converted data of the specified channel +//----------------------------------------------------------------------------- +unsigned int ADC_GetConvertedData(AT91S_ADC *pAdc, unsigned int channel) +{ + unsigned int data=0; + + ASSERT(channel < 8, "ADC channel not exist"); + + switch(channel) { + case 0: data = pAdc->ADC_CDR0; break; + case 1: data = pAdc->ADC_CDR1; break; + case 2: data = pAdc->ADC_CDR2; break; + case 3: data = pAdc->ADC_CDR3; break; + #ifdef AT91C_ADC_CDR4 + case 4: data = pAdc->ADC_CDR4; break; + #endif + #ifdef AT91C_ADC_CDR5 + case 5: data = pAdc->ADC_CDR5; break; + #endif + #ifdef AT91C_ADC_CDR6 + case 6: data = pAdc->ADC_CDR6; break; + #endif + #ifdef AT91C_ADC_CDR7 + case 7: data = pAdc->ADC_CDR7; break; + #endif + } + return data; +} + +//----------------------------------------------------------------------------- +/// Enable ADC interrupt +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param flag IT to be enabled +//----------------------------------------------------------------------------- +//void ADC_EnableIt(AT91S_ADC *pAdc, unsigned int flag) +//{ +// ASSERT((flag&0xFFF00000)== 0, "ADC bad interrupt IER"); +// +// // Write to the IER register +// pAdc->ADC_IER = flag; +//} + +//----------------------------------------------------------------------------- +/// Enable ADC Data Ready interrupt +/// \param pAdc Pointer to an AT91S_ADC instance. +//----------------------------------------------------------------------------- + +//void ADC_EnableDataReadyIt(AT91S_ADC *pAdc) +//{ +// pAdc->ADC_IER = AT91C_ADC_DRDY; +//} + +//----------------------------------------------------------------------------- +/// Disable ADC interrupt +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param flag IT to be disabled +//----------------------------------------------------------------------------- +//void ADC_DisableIt(AT91S_ADC *pAdc, unsigned int flag) +//{ +// ASSERT((flag&0xFFF00000)== 0, "ADC bad interrupt IDR"); +// +// // Write to the IDR register +// pAdc->ADC_IDR = flag; +//} + +//----------------------------------------------------------------------------- +/// Return ADC Interrupt Status +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \return ADC Stats register +//----------------------------------------------------------------------------- +//unsigned int ADC_GetStatus(AT91S_ADC *pAdc) +//{ +// return pAdc->ADC_SR; +//} + +//----------------------------------------------------------------------------- +/// Return ADC Interrupt Mask Status +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \return ADC Interrupt Mask Register +//----------------------------------------------------------------------------- +//unsigned int ADC_GetInterruptMaskStatus(AT91S_ADC *pAdc) +//{ +// return pAdc->ADC_IMR; +//} + +//----------------------------------------------------------------------------- +/// Test if ADC Interrupt is Masked +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param flag flag to be tested +/// \return 1 if interrupt is masked, otherwise 0 +//----------------------------------------------------------------------------- +unsigned int ADC_IsInterruptMasked(AT91S_ADC *pAdc, unsigned int flag) +{ + return (ADC_GetInterruptMaskStatus(pAdc) & flag); +} + +//----------------------------------------------------------------------------- +/// Test if ADC Status is Set +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param flag flag to be tested +/// \return 1 if the staus is set; 0 otherwise +//----------------------------------------------------------------------------- +unsigned int ADC_IsStatusSet(AT91S_ADC *pAdc, unsigned int flag) +{ + return (ADC_GetStatus(pAdc) & flag); +} + + +//----------------------------------------------------------------------------- +/// Test if ADC channel interrupt Status is Set +/// \param adc_sr Value of SR register +/// \param channel Channel to be tested +/// \return 1 if interrupt status is set, otherwise 0 +//----------------------------------------------------------------------------- +unsigned char ADC_IsChannelInterruptStatusSet(unsigned int adc_sr, + unsigned int channel) +{ + unsigned char status; + + if((adc_sr & (1< + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ +#define ADC_CHANNEL_0 0 +#define ADC_CHANNEL_1 1 +#define ADC_CHANNEL_2 2 +#define ADC_CHANNEL_3 3 +#define ADC_CHANNEL_4 4 +#define ADC_CHANNEL_5 5 +#define ADC_CHANNEL_6 6 +#define ADC_CHANNEL_7 7 + +//------------------------------------------------------------------------------ +// Macros function of register access +//------------------------------------------------------------------------------ +#define ADC_CfgModeReg(pAdc, mode) { \ + ASSERT(((mode)&0xF00000C0)== 0, "ADC Bad configuration ADC MR");\ + (pAdc)->ADC_MR = (mode);\ + } + +#define ADC_GetModeReg(pAdc) ((pAdc)->ADC_MR) + +#define ADC_StartConversion(pAdc) ((pAdc)->ADC_CR = AT91C_ADC_START) + +#define ADC_SoftReset(pAdc) ((pAdc)->ADC_CR = AT91C_ADC_SWRST) + +#define ADC_EnableChannel(pAdc, channel) {\ + ASSERT(channel < 8, "ADC Channel not exist");\ + (pAdc)->ADC_CHER = (1 << (channel));\ + } + +#define ADC_DisableChannel (pAdc, channel) {\ + ASSERT((channel) < 8, "ADC Channel not exist");\ + (pAdc)->ADC_CHDR = (1 << (channel));\ + } + + +#define ADC_EnableIt(pAdc, mode) {\ + ASSERT(((mode)&0xFFF00000)== 0, "ADC bad interrupt IER");\ + (pAdc)->ADC_IER = (mode);\ + } + +#define ADC_DisableIt(pAdc, mode) {\ + ASSERT(((mode)&0xFFF00000)== 0, "ADC bad interrupt IDR");\ + (pAdc)->ADC_IDR = (mode);\ + } + +#define ADC_EnableDataReadyIt(pAdc) ((pAdc)->ADC_IER = AT91C_ADC_DRDY) + +#define ADC_GetStatus(pAdc) ((pAdc)->ADC_SR) + +#define ADC_GetChannelStatus(pAdc) ((pAdc)->ADC_CHSR) + +#define ADC_GetInterruptMaskStatus(pAdc) ((pAdc)->ADC_IMR) + +#define ADC_GetLastConvertedData(pAdc) ((pAdc)->ADC_LCDR) + + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ +extern void ADC_Initialize (AT91S_ADC *pAdc, + unsigned char idAdc, + unsigned char trgEn, + unsigned char trgSel, + unsigned char sleepMode, + unsigned char resolution, + unsigned int mckClock, + unsigned int adcClock, + unsigned int startupTime, + unsigned int sampleAndHoldTime); +//extern void ADC_CfgModeReg(AT91S_ADC *pAdc, unsigned int mode); +//extern unsigned int ADC_GetModeReg(AT91S_ADC *pAdc); +//extern void ADC_EnableChannel(AT91S_ADC *pAdc, unsigned int channel); +//extern void ADC_DisableChannel (AT91S_ADC *pAdc, unsigned int channel); +//extern unsigned int ADC_GetChannelStatus(AT91S_ADC *pAdc); +//extern void ADC_StartConversion(AT91S_ADC *pAdc); +//extern void ADC_SoftReset(AT91S_ADC *pAdc); +//extern unsigned int ADC_GetLastConvertedData(AT91S_ADC *pAdc); +extern unsigned int ADC_GetConvertedData(AT91S_ADC *pAdc, unsigned int channel); +//extern void ADC_EnableIt(AT91S_ADC *pAdc, unsigned int flag); +//extern void ADC_EnableDataReadyIt(AT91S_ADC *pAdc); +//extern void ADC_DisableIt(AT91S_ADC *pAdc, unsigned int flag); +//extern unsigned int ADC_GetStatus(AT91S_ADC *pAdc); +//extern unsigned int ADC_GetInterruptMaskStatus(AT91S_ADC *pAdc); +extern unsigned int ADC_IsInterruptMasked(AT91S_ADC *pAdc, unsigned int flag); +extern unsigned int ADC_IsStatusSet(AT91S_ADC *pAdc, unsigned int flag); +extern unsigned char ADC_IsChannelInterruptStatusSet(unsigned int adc_sr, + unsigned int channel); + +#endif //#ifndef ADC_H diff --git a/peripherals/adc/adc12.c b/peripherals/adc/adc12.c new file mode 100644 index 0000000..79024dc --- /dev/null +++ b/peripherals/adc/adc12.c @@ -0,0 +1,196 @@ +/* ---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support + * ---------------------------------------------------------------------------- + * Copyright (c) 2008, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +//------------------------------------------------------------------------------ +// Headers +//------------------------------------------------------------------------------ + +#include +#include +#include +#include + + + +//------------------------------------------------------------------------------ +// Global Functions +//------------------------------------------------------------------------------ + +//----------------------------------------------------------------------------- +/// Initialize the ADC controller +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param trgEn trigger mode, software or Hardware +/// \param trgSel hardware trigger selection +/// \param sleepMode sleep mode selection +/// \param resolution resolution selection 8 bits or 10 bits +/// \param mckClock value of MCK in Hz +/// \param adcClock value of the ADC clock in Hz +/// \param startupTime value of the start up time (in us) (see datasheet) +/// \param sampleAndHoldTime (in ns) +//----------------------------------------------------------------------------- +void ADC12_Initialize (AT91S_ADC12B *pAdc, + unsigned char idAdc, + unsigned char trgEn, + unsigned char trgSel, + unsigned char sleepMode, + unsigned char resolution, + unsigned int mckClock, + unsigned int adcClock, + unsigned int startupTime, + unsigned int sampleAndHoldTime) +{ + unsigned int prescal; + unsigned int startup; + unsigned int shtim; + + ASSERT(startupTime<=ADC_STARTUP_TIME_MAX, "ADC Bad startupTime\n\r"); + ASSERT(sampleAndHoldTime>=ADC_TRACK_HOLD_TIME_MIN, "ADC Bad sampleAndHoldTime\n\r"); + + // Example: + // 5 MHz operation, 20µs startup time, 600ns track and hold time + // PRESCAL: Prescaler Rate Selection ADCClock = MCK / ( (PRESCAL+1) * 2 ) + // PRESCAL = [MCK / (ADCClock * 2)] -1 = [48/(5*2)]-1 = 3,8 + // PRESCAL = 4 -> 48/((4+1)*2) = 48/10 = 4.8MHz + // 48/((3+1)*2) = 48/8 = 6MHz + // Startup Time = (STARTUP+1) * 8 / ADCClock + // STARTUP = [(Startup Time * ADCClock)/8]-1 = [(20 10e-6 * 5000000)/8]-1 = 11,5 + // STARTUP = 11 -> (11+1)*8/48000000 = 96/4800000 = 20us + // + // Sample & Hold Time = (SHTIM) / ADCClock + // SHTIM = (HoldTime * ADCClock)-1 = (600 10e-9 * 5000000) = 3 + // SHTIM = 3 -> (3)/4800000 = 1/1600000 = 625ns + prescal = (mckClock / (2*adcClock)) - 1; + startup = ((adcClock/1000000) * startupTime / 8) - 1; + shtim = (((adcClock/1000000) * sampleAndHoldTime)/1000); + + ASSERT( (prescal<0x3F), "ADC12 Bad PRESCAL\n\r"); + ASSERT(startup<0x7F, "ADC12 Bad STARTUP\n\r"); + ASSERT(shtim<0xF, "ADC12 Bad SampleAndHoldTime\n\r"); + + TRACE_DEBUG("adcClock:%d MasterClock:%d\n\r", (mckClock/((prescal+1)*2)), mckClock); + TRACE_DEBUG("prescal:0x%X startup:0x%X shtim:0x%X\n\r", prescal, startup, shtim); + + if( adcClock != (mckClock/((prescal+1)*2)) ) { + TRACE_WARNING("User and calculated adcClocks are different : user=%d calc=%d\n\r", + adcClock, (mckClock/((prescal+1)*2))); + } + + // Enable peripheral clock + AT91C_BASE_PMC->PMC_PCER = 1 << idAdc; + + // Reset the controller + ADC12_SoftReset(pAdc); + + // Write to the MR register + ADC12_CfgModeReg( pAdc, + ( trgEn & AT91C_ADC12B_MR_TRGEN) + | ( trgSel & AT91C_ADC12B_MR_TRGSEL) + | ( resolution & AT91C_ADC12B_MR_LOWRES) + | ( sleepMode & AT91C_ADC12B_MR_SLEEP) + | ( (prescal<<8) & AT91C_ADC12B_MR_PRESCAL) + | ( (startup<<16) & AT91C_ADC12B_MR_STARTUP) + | ( (shtim<<24) & AT91C_ADC12B_MR_SHTIM) ); +} + + +//----------------------------------------------------------------------------- +/// Return the Channel Converted Data +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param channel channel to get converted value +/// \return Channel converted data of the specified channel +//----------------------------------------------------------------------------- +unsigned int ADC12_GetConvertedData(AT91S_ADC12B *pAdc, unsigned int channel) +{ + unsigned int data=0; + + ASSERT(channel < 8, "ADC channel %u not exist", channel); + + switch(channel) { + case 0: data = pAdc->ADC12B_CDR[0]; break; + case 1: data = pAdc->ADC12B_CDR[1]; break; + case 2: data = pAdc->ADC12B_CDR[2]; break; + case 3: data = pAdc->ADC12B_CDR[3]; break; + case 4: data = pAdc->ADC12B_CDR[4]; break; + case 5: data = pAdc->ADC12B_CDR[5]; break; + case 6: data = pAdc->ADC12B_CDR[6]; break; + case 7: data = pAdc->ADC12B_CDR[7]; break; + default: printf("\n\r Channel is not available!\n\r"); + + } + return data; +} + + +//----------------------------------------------------------------------------- +/// Test if ADC Interrupt is Masked +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param flag flag to be tested +/// \return 1 if interrupt is masked, otherwise 0 +//----------------------------------------------------------------------------- +unsigned int ADC12_IsInterruptMasked(AT91S_ADC12B *pAdc, unsigned int flag) +{ + return (ADC12_GetInterruptMaskStatus(pAdc) & flag); +} + +//----------------------------------------------------------------------------- +/// Test if ADC Status is Set +/// \param pAdc Pointer to an AT91S_ADC instance. +/// \param flag flag to be tested +/// \return 1 if the staus is set; 0 otherwise +//----------------------------------------------------------------------------- +unsigned int ADC12_IsStatusSet(AT91S_ADC12B *pAdc, unsigned int flag) +{ + return (ADC12_GetStatus(pAdc) & flag); +} + + +//----------------------------------------------------------------------------- +/// Test if ADC channel interrupt Status is Set +/// \param adc_sr Value of SR register +/// \param channel Channel to be tested +/// \return 1 if interrupt status is set, otherwise 0 +//----------------------------------------------------------------------------- +unsigned char ADC12_IsChannelInterruptStatusSet(unsigned int adc_sr, + unsigned int channel) +{ + unsigned char status; + + if((adc_sr & (1< + +//------------------------------------------------------------------------------ +// Definitions +//------------------------------------------------------------------------------ +#define ADC12_CHANNEL_0 0 +#define ADC12_CHANNEL_1 1 +#define ADC12_CHANNEL_2 2 +#define ADC12_CHANNEL_3 3 +#define ADC12_CHANNEL_4 4 +#define ADC12_CHANNEL_5 5 +#define ADC12_CHANNEL_6 6 +#define ADC12_CHANNEL_7 7 + +//------------------------------------------------------------------------------ +// Macros function of register access +//------------------------------------------------------------------------------ +#define ADC12_CfgModeReg(pAdc, mode) { \ + ASSERT(((mode)&0xF00000C0)== 0, "ADC Bad configuration ADC MR");\ + (pAdc)->ADC12B_MR = (mode);\ + } + +#define ADC12_GetModeReg(pAdc) ((pAdc)->ADC12B_MR) + +#define ADC12_StartConversion(pAdc) ((pAdc)->ADC12B_CR = AT91C_ADC_START) + +#define ADC12_SoftReset(pAdc) ((pAdc)->ADC12B_CR = AT91C_ADC_SWRST) + +#define ADC12_EnableChannel(pAdc, channel) {\ + ASSERT(channel < 8, "ADC Channel not exist");\ + (pAdc)->ADC12B_CHER = (1 << (channel));\ + } + +#define ADC12_DisableChannel (pAdc, channel) {\ + ASSERT((channel) < 8, "ADC Channel not exist");\ + (pAdc)->ADC12B_CHDR = (1 << (channel));\ + } + +#define ADC12_EnableIt(pAdc, mode) {\ + ASSERT(((mode)&0xFFF00000)== 0, "ADC bad interrupt IER");\ + (pAdc)->ADC12B_IER = (mode);\ + } + +#define ADC12_DisableIt(pAdc, mode) {\ + ASSERT(((mode)&0xFFF00000)== 0, "ADC bad interrupt IDR");\ + (pAdc)->ADC12B_IDR = (mode);\ + } + +#define ADC12_EnableDataReadyIt(pAdc) ((pAdc)->ADC12B_IER = AT91C_ADC_DRDY) + +#define ADC12_GetStatus(pAdc) ((pAdc)->ADC12B_SR) + +#define ADC12_GetChannelStatus(pAdc) ((pAdc)->ADC12B_CHSR) + +#define ADC12_GetInterruptMaskStatus(pAdc) ((pAdc)->ADC12B_IMR) + +#define ADC12_GetLastConvertedData(pAdc) ((pAdc)->ADC12B_LCDR) + +#define ADC12_CfgAnalogCtrlReg(pAdc,mode) {\ + ASSERT(((mode) & 0xFFFCFF3C)==0, "ADC bad analog control config");\ + (pAdc)->ADC12B_ACR = (mode);\ + } + +#define ADC12_CfgExtModeReg(pAdc, extmode) {\ + ASSERT(((extmode) & 0xFF00FFFE)==0, "ADC bad extended mode config");\ + (pAdc)->ADC12B_EMR = (extmode);\ + } + +#define ADC12_GetAnalogCtrlReg(pAdc) ((pAdc)->ADC12B_ACR) + +//------------------------------------------------------------------------------ +// Exported functions +//------------------------------------------------------------------------------ +extern void ADC12_Initialize (AT91S_ADC12B *pAdc, + unsigned char idAdc, + unsigned char trgEn, + unsigned char trgSel, + unsigned char sleepMode, + unsigned char resolution, + unsigned int mckClock, + unsigned int adcClock, + unsigned int startupTime, + unsigned int sampleAndHoldTime); +extern unsigned int ADC12_GetConvertedData(AT91S_ADC12B *pAdc, unsigned int channel); +extern unsigned int ADC12_IsInterruptMasked(AT91S_ADC12B *pAdc, unsigned int flag); +extern unsigned int ADC12_IsStatusSet(AT91S_ADC12B *pAdc, unsigned int flag); +extern unsigned char ADC12_IsChannelInterruptStatusSet(unsigned int adc_sr, + unsigned int channel); + +#endif //#ifndef ADC12_H -- cgit v1.2.3