1 //###########################################################################
2 //
3 // FILE:   F2837xD_Adc.c
4 //
5 // TITLE:  F2837xD Adc Support Functions.
6 //
7 //###########################################################################
8 // $TI Release: F2837xD Support Library v3.05.00.00 $
9 // $Release Date: Tue Jun 26 03:15:23 CDT 2018 $
10 // $Copyright:
11 // Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
12 //
13 // Redistribution and use in source and binary forms, with or without
14 // modification, are permitted provided that the following conditions
15 // are met:
16 //
17 //   Redistributions of source code must retain the above copyright
18 //   notice, this list of conditions and the following disclaimer.
19 //
20 //   Redistributions in binary form must reproduce the above copyright
21 //   notice, this list of conditions and the following disclaimer in the
22 //   documentation and/or other materials provided with the
23 //   distribution.
24 //
25 //   Neither the name of Texas Instruments Incorporated nor the names of
26 //   its contributors may be used to endorse or promote products derived
27 //   from this software without specific prior written permission.
28 //
29 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 // $
41 //###########################################################################
42 
43 //
44 // Included Files
45 //
46 #include "F2837xD_device.h"
47 #include "F2837xD_Examples.h"
48 
49 //
50 // AdcSetMode - Set the resolution and signalmode for a given ADC. This will
51 //              ensure that the correct trim is loaded.
52 //
53 // NOTE!!! There is no EALLOW/EDIS in this function! You need to make sure you
54 // perform the EALLOW before calling this function or else the ADC registers
55 // will not be configured.
56 //
AdcSetMode(Uint16 adc,Uint16 resolution,Uint16 signalmode)57 void AdcSetMode(Uint16 adc, Uint16 resolution, Uint16 signalmode)
58 {
59     Uint16 adcOffsetTrimOTPIndex; //index into OTP table of ADC offset trims
60     Uint16 adcOffsetTrim;         //temporary ADC offset trim
61 
62     //
63     //re-populate INL trim
64     //
65     CalAdcINL(adc);
66 
67     if(0xFFFF != *((Uint16*)GetAdcOffsetTrimOTP))
68     {
69         //
70         //offset trim function is programmed into OTP, so call it
71         //
72 
73         //
74         //calculate the index into OTP table of offset trims and call
75         //function to return the correct offset trim
76         //
77 #ifndef _DUAL_HEADERS
78         if(ADC_RESOLUTION_12BIT == resolution)
79 #else
80         if(ADC_BITRESOLUTION_12BIT == resolution)
81 #endif
82         {
83             adcOffsetTrimOTPIndex = 4*adc + 1*signalmode;
84         }
85         else
86         {
87             adcOffsetTrimOTPIndex = 4*adc + 1*signalmode + 2;
88         }
89 
90         adcOffsetTrim = (*GetAdcOffsetTrimOTP)(adcOffsetTrimOTPIndex);
91     }
92     else
93     {
94         //
95         //offset trim function is not populated, so set offset trim to 0
96         //
97         adcOffsetTrim = 0;
98     }
99 
100     //
101     // Apply the resolution and signalmode to the specified ADC.
102     // Also apply the offset trim and, if needed, linearity trim correction.
103     //
104     switch(adc)
105     {
106         case ADC_ADCA:
107         {
108             AdcaRegs.ADCCTL2.bit.SIGNALMODE = signalmode;
109             AdcaRegs.ADCOFFTRIM.all = adcOffsetTrim;
110 #ifndef _DUAL_HEADERS
111             if(ADC_RESOLUTION_12BIT == resolution)
112 #else
113             if(ADC_BITRESOLUTION_12BIT == resolution)
114 #endif
115             {
116                 AdcaRegs.ADCCTL2.bit.RESOLUTION = 0;
117 
118                 //
119                 //12-bit linearity trim workaround
120                 //
121                 AdcaRegs.ADCINLTRIM1 &= 0xFFFF0000;
122                 AdcaRegs.ADCINLTRIM2 &= 0xFFFF0000;
123                 AdcaRegs.ADCINLTRIM4 &= 0xFFFF0000;
124                 AdcaRegs.ADCINLTRIM5 &= 0xFFFF0000;
125             }
126             else
127             {
128                 AdcaRegs.ADCCTL2.bit.RESOLUTION = 1;
129             }
130             break;
131         }
132         case ADC_ADCB:
133         {
134             AdcbRegs.ADCCTL2.bit.SIGNALMODE = signalmode;
135             AdcbRegs.ADCOFFTRIM.all = adcOffsetTrim;
136 #ifndef _DUAL_HEADERS
137             if(ADC_RESOLUTION_12BIT == resolution)
138 #else
139             if(ADC_BITRESOLUTION_12BIT == resolution)
140 #endif
141             {
142                 AdcbRegs.ADCCTL2.bit.RESOLUTION = 0;
143 
144                 //
145                 //12-bit linearity trim workaround
146                 //
147                 AdcbRegs.ADCINLTRIM1 &= 0xFFFF0000;
148                 AdcbRegs.ADCINLTRIM2 &= 0xFFFF0000;
149                 AdcbRegs.ADCINLTRIM4 &= 0xFFFF0000;
150                 AdcbRegs.ADCINLTRIM5 &= 0xFFFF0000;
151             }
152             else
153             {
154                 AdcbRegs.ADCCTL2.bit.RESOLUTION = 1;
155             }
156             break;
157         }
158         case ADC_ADCC:
159         {
160             AdccRegs.ADCCTL2.bit.SIGNALMODE = signalmode;
161             AdccRegs.ADCOFFTRIM.all = adcOffsetTrim;
162 #ifndef _DUAL_HEADERS
163             if(ADC_RESOLUTION_12BIT == resolution)
164 #else
165             if(ADC_BITRESOLUTION_12BIT == resolution)
166 #endif
167             {
168                 AdccRegs.ADCCTL2.bit.RESOLUTION = 0;
169                 //
170                 //12-bit linearity trim workaround
171                 //
172                 AdccRegs.ADCINLTRIM1 &= 0xFFFF0000;
173                 AdccRegs.ADCINLTRIM2 &= 0xFFFF0000;
174                 AdccRegs.ADCINLTRIM4 &= 0xFFFF0000;
175                 AdccRegs.ADCINLTRIM5 &= 0xFFFF0000;
176             }
177             else
178             {
179                 AdccRegs.ADCCTL2.bit.RESOLUTION = 1;
180             }
181             break;
182         }
183         case ADC_ADCD:
184         {
185             AdcdRegs.ADCCTL2.bit.SIGNALMODE = signalmode;
186             AdcdRegs.ADCOFFTRIM.all = adcOffsetTrim;
187 #ifndef _DUAL_HEADERS
188             if(ADC_RESOLUTION_12BIT == resolution)
189 #else
190             if(ADC_BITRESOLUTION_12BIT == resolution)
191 #endif
192             {
193                 AdcdRegs.ADCCTL2.bit.RESOLUTION = 0;
194 
195                 //
196                 //12-bit linearity trim workaround
197                 //
198                 AdcdRegs.ADCINLTRIM1 &= 0xFFFF0000;
199                 AdcdRegs.ADCINLTRIM2 &= 0xFFFF0000;
200                 AdcdRegs.ADCINLTRIM4 &= 0xFFFF0000;
201                 AdcdRegs.ADCINLTRIM5 &= 0xFFFF0000;
202             }
203             else
204             {
205                 AdcdRegs.ADCCTL2.bit.RESOLUTION = 1;
206             }
207             break;
208         }
209     }
210 }
211 
212 //
213 // CalAdcINL - Loads INL trim values from OTP into the trim registers of the
214 //             specified ADC. Use only as part of AdcSetMode function, since
215 //             linearity trim correction is needed for some modes.
216 //
CalAdcINL(Uint16 adc)217 void CalAdcINL(Uint16 adc)
218 {
219     switch(adc)
220     {
221         case ADC_ADCA:
222             if(0xFFFF != *((Uint16*)CalAdcaINL))
223             {
224                 //
225                 //trim function is programmed into OTP, so call it
226                 //
227                 (*CalAdcaINL)();
228             }
229             else
230             {
231                 //
232                 //do nothing, no INL trim function populated
233                 //
234             }
235             break;
236         case ADC_ADCB:
237             if(0xFFFF != *((Uint16*)CalAdcbINL))
238             {
239                 //
240                 //trim function is programmed into OTP, so call it
241                 //
242                 (*CalAdcbINL)();
243             }
244             else
245             {
246                 //
247                 //do nothing, no INL trim function populated
248                 //
249             }
250             break;
251         case ADC_ADCC:
252             if(0xFFFF != *((Uint16*)CalAdccINL))
253             {
254                 //
255                 //trim function is programmed into OTP, so call it
256                 //
257                 (*CalAdccINL)();
258             }
259             else
260             {
261                 //
262                 //do nothing, no INL trim function populated
263                 //
264             }
265             break;
266         case ADC_ADCD:
267             if(0xFFFF != *((Uint16*)CalAdcdINL))
268             {
269                 //
270                 //trim function is programmed into OTP, so call it
271                 //
272                 (*CalAdcdINL)();
273             }
274             else
275             {
276                 //
277                 //do nothing, no INL trim function populated
278                 //
279             }
280             break;
281     }
282 }
283 
284 //
285 // End of file
286 //
287