mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Thu Nov 08 11:46:34 2018 +0000
Revision:
188:bcfe06ba3d64
Child:
189:f392fc9709a3
mbed-dev library. Release version 164

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