2 * Copyright (c) 2014, Texas Instruments Incorporated
\r
3 * All rights reserved.
\r
5 * Redistribution and use in source and binary forms, with or without
\r
6 * modification, are permitted provided that the following conditions
\r
9 * * Redistributions of source code must retain the above copyright
\r
10 * notice, this list of conditions and the following disclaimer.
\r
12 * * Redistributions in binary form must reproduce the above copyright
\r
13 * notice, this list of conditions and the following disclaimer in the
\r
14 * documentation and/or other materials provided with the distribution.
\r
16 * * Neither the name of Texas Instruments Incorporated nor the names of
\r
17 * its contributors may be used to endorse or promote products derived
\r
18 * from this software without specific prior written permission.
\r
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
\r
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
\r
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
\r
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
\r
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
\r
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
\r
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
\r
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
\r
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
32 //*****************************************************************************
\r
34 // adc12_b.c - Driver for the adc12_b Module.
\r
36 //*****************************************************************************
\r
38 //*****************************************************************************
\r
40 //! \addtogroup adc12_b_api adc12_b
\r
43 //*****************************************************************************
\r
45 #include "inc/hw_regaccess.h"
\r
46 #include "inc/hw_memmap.h"
\r
48 #ifdef __MSP430_HAS_ADC12_B__
\r
49 #include "adc12_b.h"
\r
53 bool ADC12_B_init(uint16_t baseAddress,
\r
54 ADC12_B_initParam *param)
\r
56 //Make sure the ENC bit is cleared before initializing the ADC12
\r
57 HWREG8(baseAddress + OFS_ADC12CTL0_L) &= ~ADC12ENC;
\r
59 bool retVal = STATUS_SUCCESS;
\r
61 //Turn OFF ADC12B Module & Clear Interrupt Registers
\r
62 HWREG16(baseAddress + OFS_ADC12CTL0) &= ~(ADC12ON + ADC12ENC + ADC12SC);
\r
63 HWREG16(baseAddress + OFS_ADC12IER0) &= 0x0000; //Reset ALL interrupt enables
\r
64 HWREG16(baseAddress + OFS_ADC12IER1) &= 0x0000;
\r
65 HWREG16(baseAddress + OFS_ADC12IER2) &= 0x0000;
\r
66 HWREG16(baseAddress + OFS_ADC12IFGR0) &= 0x0000; //Reset ALL interrupt flags
\r
67 HWREG16(baseAddress + OFS_ADC12IFGR1) &= 0x0000;
\r
68 HWREG16(baseAddress + OFS_ADC12IFGR2) &= 0x0000;
\r
70 //Set ADC12B Control 1
\r
71 HWREG16(baseAddress + OFS_ADC12CTL1) =
\r
72 param->sampleHoldSignalSourceSelect //Setup the Sample-and-Hold Source
\r
73 + (param->clockSourceDivider & ADC12DIV_7) //Set Clock Divider
\r
74 + (param->clockSourcePredivider & ADC12PDIV__64)
\r
75 + param->clockSourceSelect; //Setup Clock Source
\r
77 //Set ADC12B Control 2
\r
78 HWREG16(baseAddress + OFS_ADC12CTL2) =
\r
79 ADC12RES_2; //Default resolution to 12-bits
\r
81 //Set ADC12B Control 3
\r
82 HWREG16(baseAddress + OFS_ADC12CTL3) =
\r
83 param->internalChannelMap; // Map internal channels
\r
88 void ADC12_B_enable(uint16_t baseAddress)
\r
91 HWREG8(baseAddress + OFS_ADC12CTL0_L) &= ~ADC12ENC;
\r
93 //Enable the ADC12B Module
\r
94 HWREG8(baseAddress + OFS_ADC12CTL0_L) |= ADC12ON;
\r
97 void ADC12_B_disable(uint16_t baseAddress)
\r
100 HWREG8(baseAddress + OFS_ADC12CTL0_L) &= ~ADC12ENC;
\r
102 //Disable ADC12B module
\r
103 HWREG8(baseAddress + OFS_ADC12CTL0_L) &= ~ADC12ON;
\r
106 void ADC12_B_setupSamplingTimer(uint16_t baseAddress,
\r
107 uint16_t clockCycleHoldCountLowMem,
\r
108 uint16_t clockCycleHoldCountHighMem,
\r
109 uint16_t multipleSamplesEnabled)
\r
111 HWREG16(baseAddress + OFS_ADC12CTL1) |= ADC12SHP;
\r
113 //Reset clock cycle hold counts and msc bit before setting them
\r
114 HWREG16(baseAddress + OFS_ADC12CTL0) &=
\r
115 ~(ADC12SHT0_15 + ADC12SHT1_15 + ADC12MSC);
\r
117 //Set clock cycle hold counts and msc bit
\r
118 HWREG16(baseAddress + OFS_ADC12CTL0) |= clockCycleHoldCountLowMem
\r
119 + (clockCycleHoldCountHighMem << 4)
\r
120 + multipleSamplesEnabled;
\r
123 void ADC12_B_disableSamplingTimer(uint16_t baseAddress)
\r
125 HWREG16(baseAddress + OFS_ADC12CTL1) &= ~(ADC12SHP);
\r
128 void ADC12_B_configureMemory(uint16_t baseAddress,
\r
129 ADC12_B_configureMemoryParam *param)
\r
131 //Set the offset in respect to ADC12MCTL0
\r
132 uint16_t memoryBufferControlOffset =
\r
133 (OFS_ADC12MCTL0 + param->memoryBufferControlIndex);
\r
135 //Reset the memory buffer control and Set the input source
\r
136 HWREG16(baseAddress + memoryBufferControlOffset) =
\r
137 param->inputSourceSelect //Set Input Source
\r
138 + param->refVoltageSourceSelect //Set Vref+/-
\r
139 + param->endOfSequence; //Set End of Sequence
\r
141 HWREG16(baseAddress + memoryBufferControlOffset)
\r
144 HWREG16(baseAddress + memoryBufferControlOffset)
\r
145 |= param->windowComparatorSelect;
\r
146 //(OFS_ADC12MCTL0_H + memoryIndex) == offset of OFS_ADC12MCTLX_H
\r
148 HWREG16(baseAddress + memoryBufferControlOffset)
\r
151 HWREG16(baseAddress + memoryBufferControlOffset)
\r
152 |= param->differentialModeSelect;
\r
153 //(OFS_ADC12MCTL0_H + memoryIndex) == offset of OFS_ADC12MCTLX_H
\r
156 void ADC12_B_setWindowCompAdvanced(uint16_t baseAddress,
\r
157 uint16_t highThreshold,
\r
158 uint16_t lowThreshold)
\r
160 HWREG16(baseAddress + OFS_ADC12HI) = highThreshold;
\r
161 HWREG16(baseAddress + OFS_ADC12LO) = lowThreshold;
\r
164 void ADC12_B_enableInterrupt(uint16_t baseAddress,
\r
165 uint16_t interruptMask0,
\r
166 uint16_t interruptMask1,
\r
167 uint16_t interruptMask2)
\r
169 HWREG16(baseAddress + OFS_ADC12IER0) |= interruptMask0;
\r
170 HWREG16(baseAddress + OFS_ADC12IER1) |= interruptMask1;
\r
171 HWREG16(baseAddress + OFS_ADC12IER2) |= interruptMask2;
\r
174 void ADC12_B_disableInterrupt(uint16_t baseAddress,
\r
175 uint16_t interruptMask0,
\r
176 uint16_t interruptMask1,
\r
177 uint16_t interruptMask2)
\r
179 HWREG16(baseAddress + OFS_ADC12IER0) &= ~(interruptMask0);
\r
180 HWREG16(baseAddress + OFS_ADC12IER1) &= ~(interruptMask1);
\r
181 HWREG16(baseAddress + OFS_ADC12IER2) &= ~(interruptMask2);
\r
184 void ADC12_B_clearInterrupt(uint16_t baseAddress,
\r
185 uint8_t interruptRegisterChoice,
\r
186 uint16_t memoryInterruptFlagMask)
\r
188 HWREG16(baseAddress + OFS_ADC12IFGR0 + 2 * interruptRegisterChoice) &=
\r
189 ~(memoryInterruptFlagMask);
\r
192 uint16_t ADC12_B_getInterruptStatus(uint16_t baseAddress,
\r
193 uint8_t interruptRegisterChoice,
\r
194 uint16_t memoryInterruptFlagMask)
\r
196 return (HWREG16(baseAddress + OFS_ADC12IFGR0 + 2 * interruptRegisterChoice)
\r
197 & memoryInterruptFlagMask);
\r
200 void ADC12_B_startConversion(uint16_t baseAddress,
\r
201 uint16_t startingMemoryBufferIndex,
\r
202 uint8_t conversionSequenceModeSelect)
\r
204 //Reset the ENC bit to set the starting memory address and conversion mode
\r
206 HWREG8(baseAddress + OFS_ADC12CTL0_L) &= ~(ADC12ENC);
\r
207 //Reset the bits about to be set
\r
208 HWREG16(baseAddress + OFS_ADC12CTL3) &= ~(ADC12CSTARTADD_31);
\r
209 HWREG16(baseAddress + OFS_ADC12CTL1) &= ~(ADC12CONSEQ_3);
\r
211 HWREG16(baseAddress + OFS_ADC12CTL3) |= startingMemoryBufferIndex;
\r
212 HWREG16(baseAddress + OFS_ADC12CTL1) |= conversionSequenceModeSelect;
\r
213 HWREG8(baseAddress + OFS_ADC12CTL0_L) |= ADC12ENC + ADC12SC;
\r
216 void ADC12_B_disableConversions(uint16_t baseAddress,
\r
219 if(ADC12_B_PREEMPTCONVERSION == preempt)
\r
221 HWREG8(baseAddress + OFS_ADC12CTL1_L) &= ~(ADC12CONSEQ_3);
\r
222 //Reset conversion sequence mode to single-channel, single-conversion
\r
224 else if(~(HWREG8(baseAddress + OFS_ADC12CTL1_L) & ADC12CONSEQ_3))
\r
226 //To prevent preemption of a single-channel, single-conversion we must
\r
227 //wait for the ADC core to finish the conversion.
\r
228 while(ADC12_B_isBusy(baseAddress))
\r
234 HWREG8(baseAddress + OFS_ADC12CTL0_L) &= ~(ADC12ENC);
\r
237 uint16_t ADC12_B_getResults(uint16_t baseAddress,
\r
238 uint8_t memoryBufferIndex)
\r
240 return (HWREG16(baseAddress + (OFS_ADC12MEM0 + memoryBufferIndex)));
\r
241 //(0x60 + memoryBufferIndex) == offset of ADC12MEMx
\r
244 void ADC12_B_setResolution(uint16_t baseAddress,
\r
245 uint8_t resolutionSelect)
\r
247 HWREG8(baseAddress + OFS_ADC12CTL2_L) &= ~(ADC12RES_3);
\r
248 HWREG8(baseAddress + OFS_ADC12CTL2_L) |= resolutionSelect;
\r
251 void ADC12_B_setSampleHoldSignalInversion(uint16_t baseAddress,
\r
252 uint16_t invertedSignal)
\r
254 HWREG16(baseAddress + OFS_ADC12CTL1) &= ~(ADC12ISSH);
\r
255 HWREG16(baseAddress + OFS_ADC12CTL1) |= invertedSignal;
\r
258 void ADC12_B_setDataReadBackFormat(uint16_t baseAddress,
\r
259 uint8_t readBackFormat)
\r
261 HWREG8(baseAddress + OFS_ADC12CTL2_L) &= ~(ADC12DF);
\r
262 HWREG8(baseAddress + OFS_ADC12CTL2_L) |= readBackFormat;
\r
265 void ADC12_B_setAdcPowerMode(uint16_t baseAddress,
\r
268 HWREG8(baseAddress + OFS_ADC12CTL2_L) &= ~(ADC12PWRMD);
\r
269 HWREG8(baseAddress + OFS_ADC12CTL2_L) |= powerMode;
\r
272 uint32_t ADC12_B_getMemoryAddressForDMA(uint16_t baseAddress,
\r
273 uint8_t memoryIndex)
\r
275 return (baseAddress + (OFS_ADC12MEM0 + memoryIndex));
\r
276 //(0x60 + memoryIndex) == offset of ADC12MEMx
\r
279 uint8_t ADC12_B_isBusy(uint16_t baseAddress)
\r
281 return (HWREG8(baseAddress + OFS_ADC12CTL1_L) & ADC12BUSY);
\r
285 //*****************************************************************************
\r
287 //! Close the doxygen group for adc12_b_api
\r
290 //*****************************************************************************
\r