]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/MSP430FR5969_LaunchPad/driverlib/MSP430FR5xx_6xx/adc12_b.c
Start of an MSP430FR5969 IAR project - currently running Blinky only.
[freertos] / FreeRTOS / Demo / MSP430FR5969_LaunchPad / driverlib / MSP430FR5xx_6xx / adc12_b.c
1 /* --COPYRIGHT--,BSD\r
2  * Copyright (c) 2014, Texas Instruments Incorporated\r
3  * All rights reserved.\r
4  *\r
5  * Redistribution and use in source and binary forms, with or without\r
6  * modification, are permitted provided that the following conditions\r
7  * are met:\r
8  *\r
9  * *  Redistributions of source code must retain the above copyright\r
10  *    notice, this list of conditions and the following disclaimer.\r
11  *\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
15  *\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
19  *\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
31  * --/COPYRIGHT--*/\r
32 //*****************************************************************************\r
33 //\r
34 // adc12_b.c - Driver for the adc12_b Module.\r
35 //\r
36 //*****************************************************************************\r
37 \r
38 //*****************************************************************************\r
39 //\r
40 //! \addtogroup adc12_b_api adc12_b\r
41 //! @{\r
42 //\r
43 //*****************************************************************************\r
44 \r
45 #include "inc/hw_regaccess.h"\r
46 #include "inc/hw_memmap.h"\r
47 \r
48 #ifdef __MSP430_HAS_ADC12_B__\r
49 #include "adc12_b.h"\r
50 \r
51 #include <assert.h>\r
52 \r
53 bool ADC12_B_init(uint16_t baseAddress,\r
54                   ADC12_B_initParam *param)\r
55 {\r
56     //Make sure the ENC bit is cleared before initializing the ADC12\r
57     HWREG8(baseAddress + OFS_ADC12CTL0_L) &= ~ADC12ENC;\r
58 \r
59     bool retVal = STATUS_SUCCESS;\r
60 \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
69 \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
76 \r
77     //Set ADC12B Control 2\r
78     HWREG16(baseAddress + OFS_ADC12CTL2) =\r
79         ADC12RES_2; //Default resolution to 12-bits\r
80 \r
81     //Set ADC12B Control 3\r
82     HWREG16(baseAddress + OFS_ADC12CTL3) =\r
83         param->internalChannelMap; // Map internal channels\r
84 \r
85     return (retVal);\r
86 }\r
87 \r
88 void ADC12_B_enable(uint16_t baseAddress)\r
89 {\r
90     // Clear ENC bit\r
91     HWREG8(baseAddress + OFS_ADC12CTL0_L) &= ~ADC12ENC;\r
92 \r
93     //Enable the ADC12B Module\r
94     HWREG8(baseAddress + OFS_ADC12CTL0_L) |= ADC12ON;\r
95 }\r
96 \r
97 void ADC12_B_disable(uint16_t baseAddress)\r
98 {\r
99     // Clear ENC bit\r
100     HWREG8(baseAddress + OFS_ADC12CTL0_L) &= ~ADC12ENC;\r
101 \r
102     //Disable ADC12B module\r
103     HWREG8(baseAddress + OFS_ADC12CTL0_L) &= ~ADC12ON;\r
104 }\r
105 \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
110 {\r
111     HWREG16(baseAddress + OFS_ADC12CTL1) |= ADC12SHP;\r
112 \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
116 \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
121 }\r
122 \r
123 void ADC12_B_disableSamplingTimer(uint16_t baseAddress)\r
124 {\r
125     HWREG16(baseAddress + OFS_ADC12CTL1) &= ~(ADC12SHP);\r
126 }\r
127 \r
128 void ADC12_B_configureMemory(uint16_t baseAddress,\r
129                              ADC12_B_configureMemoryParam *param)\r
130 {\r
131     //Set the offset in respect to ADC12MCTL0\r
132     uint16_t memoryBufferControlOffset =\r
133         (OFS_ADC12MCTL0 + param->memoryBufferControlIndex);\r
134 \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
140 \r
141     HWREG16(baseAddress + memoryBufferControlOffset)\r
142         &= ~(ADC12WINC);\r
143 \r
144     HWREG16(baseAddress + memoryBufferControlOffset)\r
145         |= param->windowComparatorSelect;\r
146     //(OFS_ADC12MCTL0_H + memoryIndex) == offset of OFS_ADC12MCTLX_H\r
147 \r
148     HWREG16(baseAddress + memoryBufferControlOffset)\r
149         &= ~(ADC12DIF);\r
150 \r
151     HWREG16(baseAddress + memoryBufferControlOffset)\r
152         |= param->differentialModeSelect;\r
153     //(OFS_ADC12MCTL0_H + memoryIndex) == offset of OFS_ADC12MCTLX_H\r
154 }\r
155 \r
156 void ADC12_B_setWindowCompAdvanced(uint16_t baseAddress,\r
157                                    uint16_t highThreshold,\r
158                                    uint16_t lowThreshold)\r
159 {\r
160     HWREG16(baseAddress + OFS_ADC12HI) = highThreshold;\r
161     HWREG16(baseAddress + OFS_ADC12LO) = lowThreshold;\r
162 }\r
163 \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
168 {\r
169     HWREG16(baseAddress + OFS_ADC12IER0) |= interruptMask0;\r
170     HWREG16(baseAddress + OFS_ADC12IER1) |= interruptMask1;\r
171     HWREG16(baseAddress + OFS_ADC12IER2) |= interruptMask2;\r
172 }\r
173 \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
178 {\r
179     HWREG16(baseAddress + OFS_ADC12IER0) &= ~(interruptMask0);\r
180     HWREG16(baseAddress + OFS_ADC12IER1) &= ~(interruptMask1);\r
181     HWREG16(baseAddress + OFS_ADC12IER2) &= ~(interruptMask2);\r
182 }\r
183 \r
184 void ADC12_B_clearInterrupt(uint16_t baseAddress,\r
185                             uint8_t interruptRegisterChoice,\r
186                             uint16_t memoryInterruptFlagMask)\r
187 {\r
188     HWREG16(baseAddress + OFS_ADC12IFGR0 + 2 * interruptRegisterChoice) &=\r
189         ~(memoryInterruptFlagMask);\r
190 }\r
191 \r
192 uint16_t ADC12_B_getInterruptStatus(uint16_t baseAddress,\r
193                                     uint8_t interruptRegisterChoice,\r
194                                     uint16_t memoryInterruptFlagMask)\r
195 {\r
196     return (HWREG16(baseAddress + OFS_ADC12IFGR0 + 2 * interruptRegisterChoice)\r
197             & memoryInterruptFlagMask);\r
198 }\r
199 \r
200 void ADC12_B_startConversion(uint16_t baseAddress,\r
201                              uint16_t startingMemoryBufferIndex,\r
202                              uint8_t conversionSequenceModeSelect)\r
203 {\r
204     //Reset the ENC bit to set the starting memory address and conversion mode\r
205     //sequence\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
210 \r
211     HWREG16(baseAddress + OFS_ADC12CTL3) |= startingMemoryBufferIndex;\r
212     HWREG16(baseAddress + OFS_ADC12CTL1) |= conversionSequenceModeSelect;\r
213     HWREG8(baseAddress + OFS_ADC12CTL0_L) |= ADC12ENC + ADC12SC;\r
214 }\r
215 \r
216 void ADC12_B_disableConversions(uint16_t baseAddress,\r
217                                 bool preempt)\r
218 {\r
219     if(ADC12_B_PREEMPTCONVERSION == preempt)\r
220     {\r
221         HWREG8(baseAddress + OFS_ADC12CTL1_L) &= ~(ADC12CONSEQ_3);\r
222         //Reset conversion sequence mode to single-channel, single-conversion\r
223     }\r
224     else if(~(HWREG8(baseAddress + OFS_ADC12CTL1_L) & ADC12CONSEQ_3))\r
225     {\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
229         {\r
230             ;\r
231         }\r
232     }\r
233 \r
234     HWREG8(baseAddress + OFS_ADC12CTL0_L) &= ~(ADC12ENC);\r
235 }\r
236 \r
237 uint16_t ADC12_B_getResults(uint16_t baseAddress,\r
238                             uint8_t memoryBufferIndex)\r
239 {\r
240     return (HWREG16(baseAddress + (OFS_ADC12MEM0 + memoryBufferIndex)));\r
241     //(0x60 + memoryBufferIndex) == offset of ADC12MEMx\r
242 }\r
243 \r
244 void ADC12_B_setResolution(uint16_t baseAddress,\r
245                            uint8_t resolutionSelect)\r
246 {\r
247     HWREG8(baseAddress + OFS_ADC12CTL2_L) &= ~(ADC12RES_3);\r
248     HWREG8(baseAddress + OFS_ADC12CTL2_L) |= resolutionSelect;\r
249 }\r
250 \r
251 void ADC12_B_setSampleHoldSignalInversion(uint16_t baseAddress,\r
252                                           uint16_t invertedSignal)\r
253 {\r
254     HWREG16(baseAddress + OFS_ADC12CTL1) &= ~(ADC12ISSH);\r
255     HWREG16(baseAddress + OFS_ADC12CTL1) |= invertedSignal;\r
256 }\r
257 \r
258 void ADC12_B_setDataReadBackFormat(uint16_t baseAddress,\r
259                                    uint8_t readBackFormat)\r
260 {\r
261     HWREG8(baseAddress + OFS_ADC12CTL2_L) &= ~(ADC12DF);\r
262     HWREG8(baseAddress + OFS_ADC12CTL2_L) |= readBackFormat;\r
263 }\r
264 \r
265 void ADC12_B_setAdcPowerMode(uint16_t baseAddress,\r
266                              uint8_t powerMode)\r
267 {\r
268     HWREG8(baseAddress + OFS_ADC12CTL2_L) &= ~(ADC12PWRMD);\r
269     HWREG8(baseAddress + OFS_ADC12CTL2_L) |= powerMode;\r
270 }\r
271 \r
272 uint32_t ADC12_B_getMemoryAddressForDMA(uint16_t baseAddress,\r
273                                         uint8_t memoryIndex)\r
274 {\r
275     return (baseAddress + (OFS_ADC12MEM0 + memoryIndex));\r
276     //(0x60 + memoryIndex) == offset of ADC12MEMx\r
277 }\r
278 \r
279 uint8_t ADC12_B_isBusy(uint16_t baseAddress)\r
280 {\r
281     return (HWREG8(baseAddress + OFS_ADC12CTL1_L) & ADC12BUSY);\r
282 }\r
283 \r
284 #endif\r
285 //*****************************************************************************\r
286 //\r
287 //! Close the doxygen group for adc12_b_api\r
288 //! @}\r
289 //\r
290 //*****************************************************************************\r