mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
188:bcfe06ba3d64
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 188:bcfe06ba3d64 1 /*
AnnaBridge 188:bcfe06ba3d64 2 * mbed Microcontroller Library
AnnaBridge 188:bcfe06ba3d64 3 * Copyright (c) 2017-2018 Future Electronics
AnnaBridge 189:f392fc9709a3 4 * Copyright (c) 2018-2019 Cypress Semiconductor Corporation
AnnaBridge 189:f392fc9709a3 5 * SPDX-License-Identifier: Apache-2.0
AnnaBridge 188:bcfe06ba3d64 6 *
AnnaBridge 188:bcfe06ba3d64 7 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 188:bcfe06ba3d64 8 * you may not use this file except in compliance with the License.
AnnaBridge 188:bcfe06ba3d64 9 * You may obtain a copy of the License at
AnnaBridge 188:bcfe06ba3d64 10 *
AnnaBridge 188:bcfe06ba3d64 11 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 188:bcfe06ba3d64 12 *
AnnaBridge 188:bcfe06ba3d64 13 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 188:bcfe06ba3d64 14 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 188:bcfe06ba3d64 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 188:bcfe06ba3d64 16 * See the License for the specific language governing permissions and
AnnaBridge 188:bcfe06ba3d64 17 * limitations under the License.
AnnaBridge 188:bcfe06ba3d64 18 */
AnnaBridge 188:bcfe06ba3d64 19
AnnaBridge 188:bcfe06ba3d64 20 #include "device.h"
AnnaBridge 188:bcfe06ba3d64 21 #include "analogin_api.h"
AnnaBridge 188:bcfe06ba3d64 22 #include "cy_sar.h"
AnnaBridge 189:f392fc9709a3 23 #include "cy_sysanalog.h"
AnnaBridge 188:bcfe06ba3d64 24 #include "psoc6_utils.h"
AnnaBridge 188:bcfe06ba3d64 25 #include "mbed_assert.h"
AnnaBridge 188:bcfe06ba3d64 26 #include "mbed_error.h"
AnnaBridge 188:bcfe06ba3d64 27 #include "pinmap.h"
AnnaBridge 188:bcfe06ba3d64 28 #include "PeripheralPins.h"
AnnaBridge 188:bcfe06ba3d64 29 #include "platform/mbed_error.h"
AnnaBridge 188:bcfe06ba3d64 30
AnnaBridge 188:bcfe06ba3d64 31 #if DEVICE_ANALOGIN
AnnaBridge 188:bcfe06ba3d64 32
AnnaBridge 188:bcfe06ba3d64 33 const uint16_t ADC_MAX_VALUE = 0x0fff;
AnnaBridge 188:bcfe06ba3d64 34
AnnaBridge 188:bcfe06ba3d64 35 const uint32_t SAR_BASE_CLOCK_HZ = 18000000; // 18 MHz or less
AnnaBridge 188:bcfe06ba3d64 36
AnnaBridge 188:bcfe06ba3d64 37 /** Default SAR channel configuration.
AnnaBridge 188:bcfe06ba3d64 38 * Notice, that because dynamic SAR MUX switching is disabled,
AnnaBridge 188:bcfe06ba3d64 39 * per-channel MUX configuration is ignored, thus not configured here.
AnnaBridge 188:bcfe06ba3d64 40 */
AnnaBridge 188:bcfe06ba3d64 41 #define DEFAULT_CHANNEL_CONFIG ( \
AnnaBridge 188:bcfe06ba3d64 42 CY_SAR_CHAN_SINGLE_ENDED | \
AnnaBridge 188:bcfe06ba3d64 43 CY_SAR_CHAN_AVG_ENABLE | \
AnnaBridge 188:bcfe06ba3d64 44 CY_SAR_CHAN_SAMPLE_TIME_0 \
AnnaBridge 188:bcfe06ba3d64 45 )
AnnaBridge 188:bcfe06ba3d64 46
AnnaBridge 189:f392fc9709a3 47 #define CY_SAR_PORT_9 (9uL)
AnnaBridge 188:bcfe06ba3d64 48
AnnaBridge 188:bcfe06ba3d64 49 /** Global SAR configuration data, modified as channels are configured.
AnnaBridge 188:bcfe06ba3d64 50 */
AnnaBridge 188:bcfe06ba3d64 51 static cy_stc_sar_config_t sar_config = {
AnnaBridge 188:bcfe06ba3d64 52 .ctrl = CY_SAR_VREF_SEL_VDDA_DIV_2 |
AnnaBridge 188:bcfe06ba3d64 53 CY_SAR_NEG_SEL_VREF |
AnnaBridge 188:bcfe06ba3d64 54 CY_SAR_CTRL_COMP_DLY_12 |
AnnaBridge 188:bcfe06ba3d64 55 CY_SAR_COMP_PWR_50 |
AnnaBridge 188:bcfe06ba3d64 56 CY_SAR_SARSEQ_SWITCH_DISABLE, /**< Control register */
AnnaBridge 188:bcfe06ba3d64 57 .sampleCtrl = CY_SAR_RIGHT_ALIGN |
AnnaBridge 188:bcfe06ba3d64 58 CY_SAR_SINGLE_ENDED_UNSIGNED |
AnnaBridge 188:bcfe06ba3d64 59 CY_SAR_AVG_CNT_16 |
AnnaBridge 188:bcfe06ba3d64 60 CY_SAR_AVG_MODE_SEQUENTIAL_FIXED |
AnnaBridge 188:bcfe06ba3d64 61 CY_SAR_TRIGGER_MODE_FW_ONLY, /**< Sample control register */
AnnaBridge 188:bcfe06ba3d64 62 .sampleTime01 = (4uL << CY_SAR_SAMPLE_TIME0_SHIFT) |
AnnaBridge 188:bcfe06ba3d64 63 (4uL << CY_SAR_SAMPLE_TIME1_SHIFT), /**< Sample time in ADC clocks for ST0 and ST1 */
AnnaBridge 188:bcfe06ba3d64 64 .sampleTime23 = (4uL << CY_SAR_SAMPLE_TIME2_SHIFT) |
AnnaBridge 188:bcfe06ba3d64 65 (4uL << CY_SAR_SAMPLE_TIME3_SHIFT), /**< Sample time in ADC clocks for ST2 and ST3 */
AnnaBridge 188:bcfe06ba3d64 66 .rangeThres = 0, /**< Range detect threshold register for all channels (unused)*/
AnnaBridge 188:bcfe06ba3d64 67 .rangeCond = 0, /**< Range detect mode for all channels (unused)*/
AnnaBridge 188:bcfe06ba3d64 68 .chanEn = 0, /**< Enable bits for the channels */
AnnaBridge 188:bcfe06ba3d64 69 .chanConfig = { /**< Channel configuration registers */
AnnaBridge 188:bcfe06ba3d64 70 DEFAULT_CHANNEL_CONFIG, // chn 0
AnnaBridge 188:bcfe06ba3d64 71 DEFAULT_CHANNEL_CONFIG, // chn 1
AnnaBridge 188:bcfe06ba3d64 72 DEFAULT_CHANNEL_CONFIG, // chn 2
AnnaBridge 188:bcfe06ba3d64 73 DEFAULT_CHANNEL_CONFIG, // chn 3
AnnaBridge 188:bcfe06ba3d64 74 DEFAULT_CHANNEL_CONFIG, // chn 4
AnnaBridge 188:bcfe06ba3d64 75 DEFAULT_CHANNEL_CONFIG, // chn 5
AnnaBridge 188:bcfe06ba3d64 76 DEFAULT_CHANNEL_CONFIG, // chn 6
AnnaBridge 188:bcfe06ba3d64 77 DEFAULT_CHANNEL_CONFIG, // chn 7
AnnaBridge 188:bcfe06ba3d64 78 DEFAULT_CHANNEL_CONFIG, // chn 8
AnnaBridge 188:bcfe06ba3d64 79 DEFAULT_CHANNEL_CONFIG, // chn 9
AnnaBridge 188:bcfe06ba3d64 80 DEFAULT_CHANNEL_CONFIG, // chn 10
AnnaBridge 188:bcfe06ba3d64 81 DEFAULT_CHANNEL_CONFIG, // chn 11
AnnaBridge 188:bcfe06ba3d64 82 DEFAULT_CHANNEL_CONFIG, // chn 12
AnnaBridge 188:bcfe06ba3d64 83 DEFAULT_CHANNEL_CONFIG, // chn 13
AnnaBridge 188:bcfe06ba3d64 84 DEFAULT_CHANNEL_CONFIG, // chn 14
AnnaBridge 188:bcfe06ba3d64 85 DEFAULT_CHANNEL_CONFIG, // chn 15
AnnaBridge 188:bcfe06ba3d64 86 },
AnnaBridge 188:bcfe06ba3d64 87 .intrMask = 0, /**< Interrupt enable mask */
AnnaBridge 188:bcfe06ba3d64 88 .satIntrMask = 0, /**< Saturate interrupt mask register */
AnnaBridge 188:bcfe06ba3d64 89 .rangeIntrMask = 0, /**< Range interrupt mask register */
AnnaBridge 188:bcfe06ba3d64 90 .muxSwitch = 0, /**< SARMUX firmware switches to connect analog signals to SAR */
AnnaBridge 188:bcfe06ba3d64 91 .muxSwitchSqCtrl = 0, /**< SARMUX Switch SAR sequencer control */
AnnaBridge 188:bcfe06ba3d64 92 .configRouting = false, /**< Configure or ignore routing related registers (muxSwitch, muxSwitchSqCtrl) */
AnnaBridge 188:bcfe06ba3d64 93 .vrefMvValue = 0, /**< Reference voltage in millivolts used in counts to volts conversion */
AnnaBridge 188:bcfe06ba3d64 94 };
AnnaBridge 188:bcfe06ba3d64 95
AnnaBridge 188:bcfe06ba3d64 96 static bool sar_initialized = false;
AnnaBridge 188:bcfe06ba3d64 97
AnnaBridge 188:bcfe06ba3d64 98
AnnaBridge 188:bcfe06ba3d64 99 static void sar_init(analogin_t *obj)
AnnaBridge 188:bcfe06ba3d64 100 {
AnnaBridge 188:bcfe06ba3d64 101 if (!sar_initialized) {
AnnaBridge 188:bcfe06ba3d64 102 uint32_t sar_clock_divider = CY_INVALID_DIVIDER;
AnnaBridge 188:bcfe06ba3d64 103
AnnaBridge 188:bcfe06ba3d64 104 sar_initialized = true;
AnnaBridge 188:bcfe06ba3d64 105 // Allocate and setup clock.
AnnaBridge 188:bcfe06ba3d64 106 sar_clock_divider = cy_clk_allocate_divider(CY_SYSCLK_DIV_8_BIT);
AnnaBridge 188:bcfe06ba3d64 107 if (sar_clock_divider == CY_INVALID_DIVIDER) {
AnnaBridge 188:bcfe06ba3d64 108 error("SAR clock divider allocation failed.");
AnnaBridge 188:bcfe06ba3d64 109 return;
AnnaBridge 188:bcfe06ba3d64 110 }
AnnaBridge 188:bcfe06ba3d64 111 Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT,
AnnaBridge 188:bcfe06ba3d64 112 sar_clock_divider,
AnnaBridge 189:f392fc9709a3 113 ((cy_PeriClkFreqHz + SAR_BASE_CLOCK_HZ / 2) / SAR_BASE_CLOCK_HZ) - 1);
AnnaBridge 188:bcfe06ba3d64 114 Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, sar_clock_divider);
AnnaBridge 188:bcfe06ba3d64 115 Cy_SysClk_PeriphAssignDivider(obj->clock, CY_SYSCLK_DIV_8_BIT, sar_clock_divider);
AnnaBridge 188:bcfe06ba3d64 116
AnnaBridge 189:f392fc9709a3 117 /* Init and Enable the Analog Reference for SAR ADC operation */
AnnaBridge 189:f392fc9709a3 118 Cy_SysAnalog_Init(&Cy_SysAnalog_Fast_Local);
AnnaBridge 189:f392fc9709a3 119 Cy_SysAnalog_Enable();
AnnaBridge 189:f392fc9709a3 120
AnnaBridge 188:bcfe06ba3d64 121 Cy_SAR_Init(obj->base, &sar_config);
AnnaBridge 188:bcfe06ba3d64 122 Cy_SAR_Enable(obj->base);
AnnaBridge 188:bcfe06ba3d64 123 }
AnnaBridge 188:bcfe06ba3d64 124 }
AnnaBridge 188:bcfe06ba3d64 125
AnnaBridge 188:bcfe06ba3d64 126 void analogin_init(analogin_t *obj, PinName pin)
AnnaBridge 188:bcfe06ba3d64 127 {
AnnaBridge 188:bcfe06ba3d64 128 uint32_t sar = 0;
AnnaBridge 188:bcfe06ba3d64 129 uint32_t sar_function = 0;
AnnaBridge 188:bcfe06ba3d64 130
AnnaBridge 188:bcfe06ba3d64 131 MBED_ASSERT(obj);
AnnaBridge 188:bcfe06ba3d64 132 MBED_ASSERT(pin != (PinName)NC);
AnnaBridge 188:bcfe06ba3d64 133
AnnaBridge 188:bcfe06ba3d64 134 sar = pinmap_peripheral(pin, PinMap_ADC);
AnnaBridge 188:bcfe06ba3d64 135 if (sar != (uint32_t)NC) {
AnnaBridge 189:f392fc9709a3 136
AnnaBridge 189:f392fc9709a3 137 if ((0 != cy_reserve_io_pin(pin)) && !sar_initialized) {
AnnaBridge 188:bcfe06ba3d64 138 error("ANALOG IN pin reservation conflict.");
AnnaBridge 188:bcfe06ba3d64 139 }
AnnaBridge 189:f392fc9709a3 140
AnnaBridge 189:f392fc9709a3 141 /* Initialize object */
AnnaBridge 189:f392fc9709a3 142 obj->base = (SAR_Type *) CY_PERIPHERAL_BASE(sar);
AnnaBridge 188:bcfe06ba3d64 143 obj->pin = pin;
AnnaBridge 188:bcfe06ba3d64 144 obj->channel_mask = 1 << CY_PIN(pin);
AnnaBridge 188:bcfe06ba3d64 145
AnnaBridge 189:f392fc9709a3 146 /* Configure SAR hardware */
AnnaBridge 188:bcfe06ba3d64 147 sar_function = pinmap_function(pin, PinMap_ADC);
AnnaBridge 188:bcfe06ba3d64 148 obj->clock = CY_PIN_CLOCK(sar_function);
AnnaBridge 188:bcfe06ba3d64 149 sar_init(obj);
AnnaBridge 188:bcfe06ba3d64 150 pin_function(pin, sar_function);
AnnaBridge 189:f392fc9709a3 151
AnnaBridge 188:bcfe06ba3d64 152 } else {
AnnaBridge 188:bcfe06ba3d64 153 error("ANALOG IN pinout mismatch.");
AnnaBridge 188:bcfe06ba3d64 154 }
AnnaBridge 188:bcfe06ba3d64 155 }
AnnaBridge 188:bcfe06ba3d64 156
AnnaBridge 188:bcfe06ba3d64 157 float analogin_read(analogin_t *obj)
AnnaBridge 188:bcfe06ba3d64 158 {
AnnaBridge 188:bcfe06ba3d64 159 uint16_t result = analogin_read_u16(obj);
AnnaBridge 188:bcfe06ba3d64 160
AnnaBridge 188:bcfe06ba3d64 161 return (float)result * (1.0 / ADC_MAX_VALUE);
AnnaBridge 188:bcfe06ba3d64 162 }
AnnaBridge 188:bcfe06ba3d64 163
AnnaBridge 188:bcfe06ba3d64 164 uint16_t analogin_read_u16(analogin_t *obj)
AnnaBridge 188:bcfe06ba3d64 165 {
AnnaBridge 188:bcfe06ba3d64 166 uint32_t result = 0;
AnnaBridge 189:f392fc9709a3 167 uint32_t port = CY_PORT(obj->pin);
AnnaBridge 189:f392fc9709a3 168 GPIO_PRT_Type *portPrt = Cy_GPIO_PortToAddr(port);
AnnaBridge 188:bcfe06ba3d64 169
AnnaBridge 188:bcfe06ba3d64 170 Cy_SAR_SetChanMask(obj->base, obj->channel_mask);
AnnaBridge 189:f392fc9709a3 171
AnnaBridge 189:f392fc9709a3 172 /* The port 10 uses the direct connection to the pin */
AnnaBridge 189:f392fc9709a3 173 if (CY_SAR_PORT_9 != port) {
AnnaBridge 189:f392fc9709a3 174 /* Connect the SAR Vplus input to the pin directly */
AnnaBridge 189:f392fc9709a3 175 Cy_SAR_SetAnalogSwitch(obj->base, CY_SAR_MUX_SWITCH0, obj->channel_mask, CY_SAR_SWITCH_CLOSE);
AnnaBridge 189:f392fc9709a3 176 }
AnnaBridge 189:f392fc9709a3 177 else {
AnnaBridge 189:f392fc9709a3 178 /* Connect the SAR Vplus input to the AMUXA bus */
AnnaBridge 189:f392fc9709a3 179 Cy_SAR_SetAnalogSwitch(obj->base, CY_SAR_MUX_SWITCH0, SAR_MUX_SWITCH0_MUX_FW_AMUXBUSA_VPLUS_Msk, CY_SAR_SWITCH_CLOSE);
AnnaBridge 189:f392fc9709a3 180
AnnaBridge 189:f392fc9709a3 181 /* Connect the AMUXA bus to the pin */
AnnaBridge 189:f392fc9709a3 182 Cy_GPIO_SetHSIOM(portPrt, CY_PIN(obj->pin), HSIOM_SEL_AMUXA);
AnnaBridge 189:f392fc9709a3 183 }
AnnaBridge 189:f392fc9709a3 184
AnnaBridge 188:bcfe06ba3d64 185 Cy_SAR_StartConvert(obj->base, CY_SAR_START_CONVERT_SINGLE_SHOT);
AnnaBridge 188:bcfe06ba3d64 186 if (Cy_SAR_IsEndConversion(obj->base, CY_SAR_WAIT_FOR_RESULT) == CY_SAR_SUCCESS) {
AnnaBridge 188:bcfe06ba3d64 187 result = Cy_SAR_GetResult32(obj->base, CY_PIN(obj->pin));
AnnaBridge 188:bcfe06ba3d64 188 } else {
AnnaBridge 188:bcfe06ba3d64 189 error("ANALOG IN: measurement failed!");
AnnaBridge 188:bcfe06ba3d64 190 }
AnnaBridge 189:f392fc9709a3 191
AnnaBridge 189:f392fc9709a3 192 if (CY_SAR_PORT_9 != port) {
AnnaBridge 189:f392fc9709a3 193 /* Disconnect the SAR Vplus input from the pin */
AnnaBridge 189:f392fc9709a3 194 Cy_SAR_SetAnalogSwitch(obj->base, CY_SAR_MUX_SWITCH0, obj->channel_mask, CY_SAR_SWITCH_OPEN);
AnnaBridge 189:f392fc9709a3 195 }
AnnaBridge 189:f392fc9709a3 196 else {
AnnaBridge 189:f392fc9709a3 197 /* Disconnect the AMUXA bus from the pin */
AnnaBridge 189:f392fc9709a3 198 Cy_GPIO_SetHSIOM(portPrt, CY_PIN(obj->pin), HSIOM_SEL_GPIO);
AnnaBridge 189:f392fc9709a3 199
AnnaBridge 189:f392fc9709a3 200 /* Disconnect the SAR Vplus input from the AMUXA bus */
AnnaBridge 189:f392fc9709a3 201 Cy_SAR_SetAnalogSwitch(obj->base, CY_SAR_MUX_SWITCH0, SAR_MUX_SWITCH0_MUX_FW_AMUXBUSA_VPLUS_Msk, CY_SAR_SWITCH_OPEN);
AnnaBridge 189:f392fc9709a3 202 }
AnnaBridge 189:f392fc9709a3 203
AnnaBridge 188:bcfe06ba3d64 204 // We are running 16x oversampling extending results to 16 bits.
AnnaBridge 188:bcfe06ba3d64 205 return (uint16_t)(result);
AnnaBridge 188:bcfe06ba3d64 206 }
AnnaBridge 188:bcfe06ba3d64 207
AnnaBridge 188:bcfe06ba3d64 208 #endif // DEVICE_ANALOGIN
AnnaBridge 188:bcfe06ba3d64 209