summaryrefslogtreecommitdiff
path: root/peripherals/adc
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-07-04 20:52:54 +0200
committerHarald Welte <laforge@gnumonks.org>2011-07-04 20:52:54 +0200
commit044ad7c3987460ede48ff27afd6bdb0ca05a0432 (patch)
tree924818cdb0d39ca08aec540d18da7bd406eaae8c /peripherals/adc
import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v1501120100901_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
Diffstat (limited to 'peripherals/adc')
-rw-r--r--peripherals/adc/adc.c346
-rw-r--r--peripherals/adc/adc.dir37
-rw-r--r--peripherals/adc/adc.h145
-rw-r--r--peripherals/adc/adc12.c196
-rw-r--r--peripherals/adc/adc12.h142
5 files changed, 866 insertions, 0 deletions
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 <board.h>
+#include <adc/adc.h>
+#include <utility/trace.h>
+#include <utility/assert.h>
+
+//-----------------------------------------------------------------------------
+/// 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<<channel)) == (1<<channel)) {
+ status = 1;
+ }
+ else {
+ status = 0;
+ }
+ return status;
+}
+
+
+
+
diff --git a/peripherals/adc/adc.dir b/peripherals/adc/adc.dir
new file mode 100644
index 0000000..69da9df
--- /dev/null
+++ b/peripherals/adc/adc.dir
@@ -0,0 +1,37 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \dir
+///
+/// !!!Purpose
+///
+/// Contains the peripheral API for the Analog-to-Digital Converter (ADC).
+//------------------------------------------------------------------------------
+
diff --git a/peripherals/adc/adc.h b/peripherals/adc/adc.h
new file mode 100644
index 0000000..331ceae
--- /dev/null
+++ b/peripherals/adc/adc.h
@@ -0,0 +1,145 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Interface for configuration the Analog-to-Digital Converter (ADC) peripheral.
+///
+/// !Usage
+///
+/// -# Configurate the pins for ADC
+/// -# Initialize the ADC with ADC_Initialize().
+/// -# Select the active channel using ADC_EnableChannel()
+/// -# Start the conversion with ADC_StartConversion()
+// -# Wait the end of the conversion by polling status with ADC_GetStatus()
+// -# Finally, get the converted data using ADC_GetConvertedData()
+///
+//------------------------------------------------------------------------------
+#ifndef ADC_H
+#define ADC_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+#include <utility/assert.h>
+
+//------------------------------------------------------------------------------
+// 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 <board.h>
+#include <adc/adc12.h>
+#include <utility/trace.h>
+#include <utility/assert.h>
+
+
+
+//------------------------------------------------------------------------------
+// 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<<channel)) == (1<<channel)) {
+ status = 1;
+ }
+ else {
+ status = 0;
+ }
+ return status;
+}
+
+
+
+
+
diff --git a/peripherals/adc/adc12.h b/peripherals/adc/adc12.h
new file mode 100644
index 0000000..5a854aa
--- /dev/null
+++ b/peripherals/adc/adc12.h
@@ -0,0 +1,142 @@
+/* ----------------------------------------------------------------------------
+ * 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.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Interface for configuration the Analog-to-Digital Converter (ADC) peripheral.
+///
+/// !Usage
+///
+/// -# Configurate the pins for ADC
+/// -# Initialize the ADC with ADC_Initialize().
+/// -# Select the active channel using ADC_EnableChannel()
+/// -# Start the conversion with ADC_StartConversion()
+// -# Wait the end of the conversion by polling status with ADC_GetStatus()
+// -# Finally, get the converted data using ADC_GetConvertedData()
+///
+//------------------------------------------------------------------------------
+#ifndef ADC12_H
+#define ADC12_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+#include <utility/assert.h>
+
+//------------------------------------------------------------------------------
+// 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
personal git repositories of Harald Welte. Your mileage may vary