1 /*
2 * Copyright (c) 2016-2017, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * By default disable both asserts and log for this module.
35 * This must be done before DebugP.h is included.
36 */
37 #ifndef DebugP_ASSERT_ENABLED
38 #define DebugP_ASSERT_ENABLED 0
39 #endif
40 #ifndef DebugP_LOG_ENABLED
41 #define DebugP_LOG_ENABLED 0
42 #endif
43
44 #include <stdint.h>
45
46 #include <ti/drivers/dpl/DebugP.h>
47 #include <ti/drivers/dpl/HwiP.h>
48
49 #include <ti/drivers/adc/ADCCC32XX.h>
50
51 #include <ti/devices/cc32xx/inc/hw_memmap.h>
52 #include <ti/devices/cc32xx/inc/hw_ocp_shared.h>
53 #include <ti/devices/cc32xx/inc/hw_types.h>
54 #include <ti/devices/cc32xx/driverlib/rom.h>
55 #include <ti/devices/cc32xx/driverlib/rom_map.h>
56 #include <ti/devices/cc32xx/driverlib/rom_patch.h>
57 #include <ti/devices/cc32xx/driverlib/adc.h>
58 #include <ti/devices/cc32xx/driverlib/pin.h>
59
60 /* Pad configuration register defaults */
61 #define PAD_CONFIG_BASE (OCP_SHARED_BASE + OCP_SHARED_O_GPIO_PAD_CONFIG_0)
62 #define PAD_RESET_DRIVE PIN_STRENGTH_6MA
63 #define PAD_RESET_TYPE PIN_TYPE_STD
64 #define PAD_RESET_STATE 0xC61
65
66 #define PinConfigChannel(config) (((config) >> 8) & 0xff)
67 #define PinConfigPin(config) ((config) & 0xff)
68
69 void ADCCC32XX_close(ADC_Handle handle);
70 int_fast16_t ADCCC32XX_control(ADC_Handle handle, uint_fast16_t cmd, void *arg);
71 int_fast16_t ADCCC32XX_convert(ADC_Handle handle, uint16_t *value);
72 uint32_t ADCCC32XX_convertToMicroVolts(ADC_Handle handle,
73 uint16_t adcValue);
74 void ADCCC32XX_init(ADC_Handle handle);
75 ADC_Handle ADCCC32XX_open(ADC_Handle handle, ADC_Params *params);
76
77 /* ADC function table for ADCCC32XX implementation */
78 const ADC_FxnTable ADCCC32XX_fxnTable = {
79 ADCCC32XX_close,
80 ADCCC32XX_control,
81 ADCCC32XX_convert,
82 ADCCC32XX_convertToMicroVolts,
83 ADCCC32XX_init,
84 ADCCC32XX_open
85 };
86
87 /* Internal ADC status structure */
88 static ADCCC32XX_State state = {
89 .baseAddr = ADC_BASE,
90 .numOpenChannels = 0
91 };
92
93 /*
94 * ======== ADCCC32XX_close ========
95 */
ADCCC32XX_close(ADC_Handle handle)96 void ADCCC32XX_close(ADC_Handle handle)
97 {
98 uintptr_t key;
99 uint32_t pin;
100 uint32_t padRegister;
101 ADCCC32XX_Object *object = handle->object;
102 ADCCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
103
104 pin = PinConfigChannel(hwAttrs->adcPin);
105
106 key = HwiP_disable();
107
108 MAP_ADCChannelDisable(state.baseAddr, pin);
109 state.numOpenChannels--;
110
111 if (state.numOpenChannels == 0) {
112 MAP_ADCDisable(state.baseAddr);
113 }
114
115 HwiP_restore(key);
116
117 /* Call PinConfigSet to de-isolate the input */
118 pin = PinConfigPin(hwAttrs->adcPin);
119 MAP_PinConfigSet(pin, PAD_RESET_DRIVE, PAD_RESET_TYPE);
120 /* Set reset state for the pad register */
121 padRegister = (PinToPadGet(pin)<<2) + PAD_CONFIG_BASE;
122 HWREG(padRegister) = PAD_RESET_STATE;
123
124 object->isOpen = false;
125
126 DebugP_log0("ADC: (%p) closed");
127 }
128
129 /*
130 * ======== ADCCC32XX_control ========
131 */
ADCCC32XX_control(ADC_Handle handle,uint_fast16_t cmd,void * arg)132 int_fast16_t ADCCC32XX_control(ADC_Handle handle, uint_fast16_t cmd, void *arg)
133 {
134 /* No implementation yet */
135 return (ADC_STATUS_UNDEFINEDCMD);
136 }
137
138 /*
139 * ======== ADCCC32XX_convert ========
140 */
ADCCC32XX_convert(ADC_Handle handle,uint16_t * value)141 int_fast16_t ADCCC32XX_convert(ADC_Handle handle, uint16_t *value)
142 {
143 uintptr_t key;
144 uint16_t adcSample = 0;
145 uint_fast16_t adcChannel;
146 ADCCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
147
148 adcChannel = PinConfigChannel(hwAttrs->adcPin);
149 key = HwiP_disable();
150
151 /* Wait until the FIFO is not empty */
152 while (MAP_ADCFIFOLvlGet(state.baseAddr, adcChannel) == 0) {
153 HwiP_restore(key);
154 key = HwiP_disable();
155 }
156
157 adcSample = MAP_ADCFIFORead(ADC_BASE, adcChannel);
158
159 HwiP_restore(key);
160
161 /* Strip time stamp & reserve bits from ADC sample */
162 *value = ((adcSample >> 2) & 0x0FFF);
163
164 return (ADC_STATUS_SUCCESS);
165 }
166
167 /*
168 * ======== ADCCC32XX_convertToMicroVolts ========
169 */
ADCCC32XX_convertToMicroVolts(ADC_Handle handle,uint16_t adcValue)170 uint32_t ADCCC32XX_convertToMicroVolts(ADC_Handle handle,
171 uint16_t adcValue)
172 {
173 /* Internal voltage reference is 1.467V (1467000 uV) */
174 return ((uint_fast32_t)(adcValue * (1467000.0 / 4095.0)));
175 }
176
177 /*
178 * ======== ADCCC32XX_init ========
179 */
ADCCC32XX_init(ADC_Handle handle)180 void ADCCC32XX_init(ADC_Handle handle)
181 {
182 /* Mark the object as available */
183 ((ADCCC32XX_Object *) handle->object)->isOpen = false;
184 }
185
186 /*
187 * ======== ADCCC32XX_open ========
188 */
ADCCC32XX_open(ADC_Handle handle,ADC_Params * params)189 ADC_Handle ADCCC32XX_open(ADC_Handle handle, ADC_Params *params)
190 {
191 uintptr_t key;
192 uint32_t pin;
193 ADCCC32XX_Object *object = handle->object;
194 ADCCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
195 uint32_t i;
196
197 key = HwiP_disable();
198
199 if (object->isOpen) {
200 HwiP_restore(key);
201
202 DebugP_log1("ADC: (%p) already opened", (uintptr_t) handle);
203 return (NULL);
204 }
205
206 object->isOpen = true;
207 state.numOpenChannels++;
208
209 HwiP_restore(key);
210
211 /* Configure pin as ADC input */
212 pin = PinConfigPin(hwAttrs->adcPin);
213 MAP_PinTypeADC(pin, PIN_MODE_255);
214
215 /* Enable ADC Peripheral and ADC Channel */
216 pin = PinConfigChannel(hwAttrs->adcPin);
217 MAP_ADCEnable(state.baseAddr);
218 MAP_ADCChannelEnable(state.baseAddr, pin);
219
220 /* Empty 5 samples from the FIFO */
221 for (i = 0; i < 5; i++) {
222 while (MAP_ADCFIFOLvlGet(state.baseAddr, pin) == 0){
223 }
224 MAP_ADCFIFORead(state.baseAddr, pin);
225 }
226
227 DebugP_log1("ADC: (%p) instance opened.", (uintptr_t) handle);
228
229 return (handle);
230 }
231