1
1
/*
2
2
* mbed Microcontroller Library
3
3
* Copyright (c) 2017-2018 Future Electronics
4
+ * Copyright (c) 2018-2019 Cypress Semiconductor Corporation
5
+ * SPDX-License-Identifier: Apache-2.0
4
6
*
5
7
* Licensed under the Apache License, Version 2.0 (the "License");
6
8
* you may not use this file except in compliance with the License.
18
20
#include "device.h"
19
21
#include "analogin_api.h"
20
22
#include "cy_sar.h"
23
+ #include "cy_sysanalog.h"
21
24
#include "psoc6_utils.h"
22
25
#include "mbed_assert.h"
23
26
#include "mbed_error.h"
@@ -41,6 +44,7 @@ const uint32_t SAR_BASE_CLOCK_HZ = 18000000; // 18 MHz or less
41
44
CY_SAR_CHAN_SAMPLE_TIME_0 \
42
45
)
43
46
47
+ #define CY_SAR_PORT_9 (9uL)
44
48
45
49
/** Global SAR configuration data, modified as channels are configured.
46
50
*/
@@ -106,10 +110,14 @@ static void sar_init(analogin_t *obj)
106
110
}
107
111
Cy_SysClk_PeriphSetDivider (CY_SYSCLK_DIV_8_BIT ,
108
112
sar_clock_divider ,
109
- ((CY_CLK_PERICLK_FREQ_HZ + SAR_BASE_CLOCK_HZ / 2 ) / SAR_BASE_CLOCK_HZ ) - 1 );
113
+ ((cy_PeriClkFreqHz + SAR_BASE_CLOCK_HZ / 2 ) / SAR_BASE_CLOCK_HZ ) - 1 );
110
114
Cy_SysClk_PeriphEnableDivider (CY_SYSCLK_DIV_8_BIT , sar_clock_divider );
111
115
Cy_SysClk_PeriphAssignDivider (obj -> clock , CY_SYSCLK_DIV_8_BIT , sar_clock_divider );
112
116
117
+ /* Init and Enable the Analog Reference for SAR ADC operation */
118
+ Cy_SysAnalog_Init (& Cy_SysAnalog_Fast_Local );
119
+ Cy_SysAnalog_Enable ();
120
+
113
121
Cy_SAR_Init (obj -> base , & sar_config );
114
122
Cy_SAR_Enable (obj -> base );
115
123
}
@@ -123,21 +131,24 @@ void analogin_init(analogin_t *obj, PinName pin)
123
131
MBED_ASSERT (obj );
124
132
MBED_ASSERT (pin != (PinName )NC );
125
133
126
-
127
134
sar = pinmap_peripheral (pin , PinMap_ADC );
128
135
if (sar != (uint32_t )NC ) {
129
- if (cy_reserve_io_pin (pin )) {
136
+
137
+ if ((0 != cy_reserve_io_pin (pin )) && !sar_initialized ) {
130
138
error ("ANALOG IN pin reservation conflict." );
131
139
}
132
- obj -> base = (SAR_Type * )CY_PERIPHERAL_BASE (sar );
140
+
141
+ /* Initialize object */
142
+ obj -> base = (SAR_Type * ) CY_PERIPHERAL_BASE (sar );
133
143
obj -> pin = pin ;
134
144
obj -> channel_mask = 1 << CY_PIN (pin );
135
145
136
- // Configure clock.
146
+ /* Configure SAR hardware */
137
147
sar_function = pinmap_function (pin , PinMap_ADC );
138
148
obj -> clock = CY_PIN_CLOCK (sar_function );
139
149
sar_init (obj );
140
150
pin_function (pin , sar_function );
151
+
141
152
} else {
142
153
error ("ANALOG IN pinout mismatch." );
143
154
}
@@ -153,16 +164,43 @@ float analogin_read(analogin_t *obj)
153
164
uint16_t analogin_read_u16 (analogin_t * obj )
154
165
{
155
166
uint32_t result = 0 ;
167
+ uint32_t port = CY_PORT (obj -> pin );
168
+ GPIO_PRT_Type * portPrt = Cy_GPIO_PortToAddr (port );
156
169
157
170
Cy_SAR_SetChanMask (obj -> base , obj -> channel_mask );
158
- Cy_SAR_SetAnalogSwitch (obj -> base , CY_SAR_MUX_SWITCH0 , obj -> channel_mask , CY_SAR_SWITCH_CLOSE );
171
+
172
+ /* The port 10 uses the direct connection to the pin */
173
+ if (CY_SAR_PORT_9 != port ) {
174
+ /* Connect the SAR Vplus input to the pin directly */
175
+ Cy_SAR_SetAnalogSwitch (obj -> base , CY_SAR_MUX_SWITCH0 , obj -> channel_mask , CY_SAR_SWITCH_CLOSE );
176
+ }
177
+ else {
178
+ /* Connect the SAR Vplus input to the AMUXA bus */
179
+ Cy_SAR_SetAnalogSwitch (obj -> base , CY_SAR_MUX_SWITCH0 , SAR_MUX_SWITCH0_MUX_FW_AMUXBUSA_VPLUS_Msk , CY_SAR_SWITCH_CLOSE );
180
+
181
+ /* Connect the AMUXA bus to the pin */
182
+ Cy_GPIO_SetHSIOM (portPrt , CY_PIN (obj -> pin ), HSIOM_SEL_AMUXA );
183
+ }
184
+
159
185
Cy_SAR_StartConvert (obj -> base , CY_SAR_START_CONVERT_SINGLE_SHOT );
160
186
if (Cy_SAR_IsEndConversion (obj -> base , CY_SAR_WAIT_FOR_RESULT ) == CY_SAR_SUCCESS ) {
161
187
result = Cy_SAR_GetResult32 (obj -> base , CY_PIN (obj -> pin ));
162
188
} else {
163
189
error ("ANALOG IN: measurement failed!" );
164
190
}
165
- Cy_SAR_SetAnalogSwitch (obj -> base , CY_SAR_MUX_SWITCH0 , obj -> channel_mask , CY_SAR_SWITCH_OPEN );
191
+
192
+ if (CY_SAR_PORT_9 != port ) {
193
+ /* Disconnect the SAR Vplus input from the pin */
194
+ Cy_SAR_SetAnalogSwitch (obj -> base , CY_SAR_MUX_SWITCH0 , obj -> channel_mask , CY_SAR_SWITCH_OPEN );
195
+ }
196
+ else {
197
+ /* Disconnect the AMUXA bus from the pin */
198
+ Cy_GPIO_SetHSIOM (portPrt , CY_PIN (obj -> pin ), HSIOM_SEL_GPIO );
199
+
200
+ /* Disconnect the SAR Vplus input from the AMUXA bus */
201
+ Cy_SAR_SetAnalogSwitch (obj -> base , CY_SAR_MUX_SWITCH0 , SAR_MUX_SWITCH0_MUX_FW_AMUXBUSA_VPLUS_Msk , CY_SAR_SWITCH_OPEN );
202
+ }
203
+
166
204
// We are running 16x oversampling extending results to 16 bits.
167
205
return (uint16_t )(result );
168
206
}
0 commit comments