mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_Cypress/TARGET_PSOC6/analogout_api.c@189:f392fc9709a3, 2019-02-20 (annotated)
- 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?
User | Revision | Line number | New 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 "analogout_api.h" |
AnnaBridge | 188:bcfe06ba3d64 | 22 | #include "cy_ctdac.h" |
AnnaBridge | 188:bcfe06ba3d64 | 23 | #include "psoc6_utils.h" |
AnnaBridge | 188:bcfe06ba3d64 | 24 | #include "mbed_assert.h" |
AnnaBridge | 188:bcfe06ba3d64 | 25 | #include "mbed_error.h" |
AnnaBridge | 188:bcfe06ba3d64 | 26 | #include "pinmap.h" |
AnnaBridge | 188:bcfe06ba3d64 | 27 | #include "PeripheralPins.h" |
AnnaBridge | 188:bcfe06ba3d64 | 28 | #include "platform/mbed_error.h" |
AnnaBridge | 188:bcfe06ba3d64 | 29 | |
AnnaBridge | 188:bcfe06ba3d64 | 30 | #if DEVICE_ANALOGOUT |
AnnaBridge | 188:bcfe06ba3d64 | 31 | |
AnnaBridge | 188:bcfe06ba3d64 | 32 | #define CTDAC_NUM_BITS 12 |
AnnaBridge | 188:bcfe06ba3d64 | 33 | const uint16_t CTDAC_MAX_VALUE = (uint16_t)((1UL << CTDAC_NUM_BITS) - 1); |
AnnaBridge | 188:bcfe06ba3d64 | 34 | |
AnnaBridge | 188:bcfe06ba3d64 | 35 | const uint32_t CTDAC_BASE_CLOCK_HZ = 500000; // 500 kHz or less |
AnnaBridge | 188:bcfe06ba3d64 | 36 | |
AnnaBridge | 188:bcfe06ba3d64 | 37 | #define CTDAC_DEGLITCH_CYCLES 35 |
AnnaBridge | 188:bcfe06ba3d64 | 38 | |
AnnaBridge | 188:bcfe06ba3d64 | 39 | |
AnnaBridge | 188:bcfe06ba3d64 | 40 | |
AnnaBridge | 188:bcfe06ba3d64 | 41 | /** Global CTDAC configuration data. |
AnnaBridge | 188:bcfe06ba3d64 | 42 | */ |
AnnaBridge | 188:bcfe06ba3d64 | 43 | static cy_stc_ctdac_config_t ctdac_config = { |
AnnaBridge | 188:bcfe06ba3d64 | 44 | .refSource = CY_CTDAC_REFSOURCE_VDDA, /**< Reference source: Vdda or externally through Opamp1 of CTB */ |
AnnaBridge | 188:bcfe06ba3d64 | 45 | .formatMode = CY_CTDAC_FORMAT_UNSIGNED, /**< Format of DAC value: signed or unsigned */ |
AnnaBridge | 188:bcfe06ba3d64 | 46 | .updateMode = CY_CTDAC_UPDATE_BUFFERED_WRITE, /**< Update mode: direct or buffered writes or hardware, edge or level */ |
AnnaBridge | 188:bcfe06ba3d64 | 47 | .deglitchMode = CY_CTDAC_DEGLITCHMODE_UNBUFFERED, /**< Deglitch mode: disabled, buffered, unbuffered, or both */ |
AnnaBridge | 188:bcfe06ba3d64 | 48 | .outputMode = CY_CTDAC_OUTPUT_VALUE, /**< Output mode: enabled (value or value + 1), high-z, Vssa, or Vdda */ |
AnnaBridge | 188:bcfe06ba3d64 | 49 | .outputBuffer = CY_CTDAC_OUTPUT_UNBUFFERED, /**< Output path: Buffered through Opamp0 of CTB or connected directly to Pin 6 */ |
AnnaBridge | 188:bcfe06ba3d64 | 50 | .deepSleep = CY_CTDAC_DEEPSLEEP_DISABLE, /**< Enable or disable the CTDAC during Deep Sleep */ |
AnnaBridge | 188:bcfe06ba3d64 | 51 | .deglitchCycles = CTDAC_DEGLITCH_CYCLES, /**< Number of deglitch cycles from 0 to 63 */ |
AnnaBridge | 188:bcfe06ba3d64 | 52 | .value = 0, /**< Current DAC value */ |
AnnaBridge | 188:bcfe06ba3d64 | 53 | .nextValue = 0, /**< Next DAC value for double buffering */ |
AnnaBridge | 188:bcfe06ba3d64 | 54 | .enableInterrupt = false, /**< If true, enable interrupt when next value register is transferred to value register */ |
AnnaBridge | 188:bcfe06ba3d64 | 55 | .configClock = false, /**< Configure or ignore clock information */ |
AnnaBridge | 188:bcfe06ba3d64 | 56 | }; |
AnnaBridge | 188:bcfe06ba3d64 | 57 | |
AnnaBridge | 188:bcfe06ba3d64 | 58 | |
AnnaBridge | 188:bcfe06ba3d64 | 59 | static bool ctdac_initialized = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 60 | |
AnnaBridge | 188:bcfe06ba3d64 | 61 | static void ctdac_init(dac_t *obj) |
AnnaBridge | 188:bcfe06ba3d64 | 62 | { |
AnnaBridge | 188:bcfe06ba3d64 | 63 | if (!ctdac_initialized) { |
AnnaBridge | 188:bcfe06ba3d64 | 64 | uint32_t dac_clock_divider = CY_INVALID_DIVIDER; |
AnnaBridge | 188:bcfe06ba3d64 | 65 | |
AnnaBridge | 188:bcfe06ba3d64 | 66 | ctdac_initialized = true; |
AnnaBridge | 188:bcfe06ba3d64 | 67 | // Allocate and setup clock. |
AnnaBridge | 188:bcfe06ba3d64 | 68 | dac_clock_divider = cy_clk_allocate_divider(CY_SYSCLK_DIV_8_BIT); |
AnnaBridge | 188:bcfe06ba3d64 | 69 | if (dac_clock_divider == CY_INVALID_DIVIDER) { |
AnnaBridge | 188:bcfe06ba3d64 | 70 | error("CTDAC clock divider allocation failed."); |
AnnaBridge | 188:bcfe06ba3d64 | 71 | } |
AnnaBridge | 188:bcfe06ba3d64 | 72 | Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, |
AnnaBridge | 188:bcfe06ba3d64 | 73 | dac_clock_divider, |
AnnaBridge | 189:f392fc9709a3 | 74 | ((cy_PeriClkFreqHz + CTDAC_BASE_CLOCK_HZ / 2) / CTDAC_BASE_CLOCK_HZ) - 1); |
AnnaBridge | 188:bcfe06ba3d64 | 75 | Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, dac_clock_divider); |
AnnaBridge | 188:bcfe06ba3d64 | 76 | Cy_SysClk_PeriphAssignDivider(obj->clock, CY_SYSCLK_DIV_8_BIT, dac_clock_divider); |
AnnaBridge | 188:bcfe06ba3d64 | 77 | |
AnnaBridge | 188:bcfe06ba3d64 | 78 | Cy_CTDAC_Init(obj->base, &ctdac_config); |
AnnaBridge | 188:bcfe06ba3d64 | 79 | Cy_CTDAC_Enable(obj->base); |
AnnaBridge | 188:bcfe06ba3d64 | 80 | } |
AnnaBridge | 188:bcfe06ba3d64 | 81 | } |
AnnaBridge | 188:bcfe06ba3d64 | 82 | |
AnnaBridge | 188:bcfe06ba3d64 | 83 | |
AnnaBridge | 188:bcfe06ba3d64 | 84 | void analogout_init(dac_t *obj, PinName pin) |
AnnaBridge | 188:bcfe06ba3d64 | 85 | { |
AnnaBridge | 188:bcfe06ba3d64 | 86 | uint32_t dac = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 87 | uint32_t dac_function = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 88 | |
AnnaBridge | 188:bcfe06ba3d64 | 89 | MBED_ASSERT(obj); |
AnnaBridge | 188:bcfe06ba3d64 | 90 | MBED_ASSERT(pin != (PinName)NC); |
AnnaBridge | 188:bcfe06ba3d64 | 91 | |
AnnaBridge | 188:bcfe06ba3d64 | 92 | dac = pinmap_peripheral(pin, PinMap_DAC); |
AnnaBridge | 188:bcfe06ba3d64 | 93 | if (dac != (uint32_t)NC) { |
AnnaBridge | 189:f392fc9709a3 | 94 | |
AnnaBridge | 189:f392fc9709a3 | 95 | if ((0 != cy_reserve_io_pin(pin)) && !ctdac_initialized) { |
AnnaBridge | 188:bcfe06ba3d64 | 96 | error("ANALOG OUT pin reservation conflict."); |
AnnaBridge | 188:bcfe06ba3d64 | 97 | } |
AnnaBridge | 189:f392fc9709a3 | 98 | |
AnnaBridge | 189:f392fc9709a3 | 99 | /* Initialize object */ |
AnnaBridge | 189:f392fc9709a3 | 100 | obj->base = (CTDAC_Type *)CY_PERIPHERAL_BASE(dac); |
AnnaBridge | 188:bcfe06ba3d64 | 101 | obj->pin = pin; |
AnnaBridge | 188:bcfe06ba3d64 | 102 | |
AnnaBridge | 189:f392fc9709a3 | 103 | /* Configure CTDAC hardware */ |
AnnaBridge | 188:bcfe06ba3d64 | 104 | dac_function = pinmap_function(pin, PinMap_DAC); |
AnnaBridge | 188:bcfe06ba3d64 | 105 | obj->clock = CY_PIN_CLOCK(dac_function); |
AnnaBridge | 188:bcfe06ba3d64 | 106 | pin_function(pin, dac_function); |
AnnaBridge | 189:f392fc9709a3 | 107 | |
AnnaBridge | 189:f392fc9709a3 | 108 | if (AOUT != pin) { |
AnnaBridge | 189:f392fc9709a3 | 109 | const PinName directOutput = AOUT; |
AnnaBridge | 189:f392fc9709a3 | 110 | |
AnnaBridge | 189:f392fc9709a3 | 111 | /* Connect AOUT to the AMUXA bus to drive output */ |
AnnaBridge | 189:f392fc9709a3 | 112 | Cy_GPIO_SetHSIOM(Cy_GPIO_PortToAddr(CY_PORT(directOutput)), CY_PIN(directOutput), HSIOM_SEL_AMUXA); |
AnnaBridge | 189:f392fc9709a3 | 113 | } |
AnnaBridge | 189:f392fc9709a3 | 114 | |
AnnaBridge | 188:bcfe06ba3d64 | 115 | ctdac_init(obj); |
AnnaBridge | 189:f392fc9709a3 | 116 | |
AnnaBridge | 188:bcfe06ba3d64 | 117 | } else { |
AnnaBridge | 188:bcfe06ba3d64 | 118 | error("ANALOG OUT pinout mismatch."); |
AnnaBridge | 188:bcfe06ba3d64 | 119 | } |
AnnaBridge | 188:bcfe06ba3d64 | 120 | } |
AnnaBridge | 188:bcfe06ba3d64 | 121 | |
AnnaBridge | 188:bcfe06ba3d64 | 122 | void analogout_free(dac_t *obj) |
AnnaBridge | 188:bcfe06ba3d64 | 123 | { |
AnnaBridge | 189:f392fc9709a3 | 124 | /* MBED AnalogIn driver does not call this function in destructor */ |
AnnaBridge | 188:bcfe06ba3d64 | 125 | } |
AnnaBridge | 188:bcfe06ba3d64 | 126 | |
AnnaBridge | 188:bcfe06ba3d64 | 127 | void analogout_write(dac_t *obj, float value) |
AnnaBridge | 188:bcfe06ba3d64 | 128 | { |
AnnaBridge | 188:bcfe06ba3d64 | 129 | uint32_t val = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 130 | |
AnnaBridge | 188:bcfe06ba3d64 | 131 | if (value > 1.0) { |
AnnaBridge | 188:bcfe06ba3d64 | 132 | val = CTDAC_MAX_VALUE; |
AnnaBridge | 188:bcfe06ba3d64 | 133 | } else if (value > 0.0) { |
AnnaBridge | 188:bcfe06ba3d64 | 134 | val = value * CTDAC_MAX_VALUE; |
AnnaBridge | 188:bcfe06ba3d64 | 135 | } |
AnnaBridge | 188:bcfe06ba3d64 | 136 | Cy_CTDAC_SetValueBuffered(obj->base, val); |
AnnaBridge | 188:bcfe06ba3d64 | 137 | } |
AnnaBridge | 188:bcfe06ba3d64 | 138 | |
AnnaBridge | 188:bcfe06ba3d64 | 139 | void analogout_write_u16(dac_t *obj, uint16_t value) |
AnnaBridge | 188:bcfe06ba3d64 | 140 | { |
AnnaBridge | 188:bcfe06ba3d64 | 141 | uint32_t val = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 142 | |
AnnaBridge | 188:bcfe06ba3d64 | 143 | val = (value >> (16 - CTDAC_NUM_BITS)); // Convert from 16-bit range. |
AnnaBridge | 188:bcfe06ba3d64 | 144 | |
AnnaBridge | 188:bcfe06ba3d64 | 145 | Cy_CTDAC_SetValueBuffered(obj->base, val); |
AnnaBridge | 188:bcfe06ba3d64 | 146 | } |
AnnaBridge | 188:bcfe06ba3d64 | 147 | |
AnnaBridge | 188:bcfe06ba3d64 | 148 | float analogout_read(dac_t *obj) |
AnnaBridge | 188:bcfe06ba3d64 | 149 | { |
AnnaBridge | 188:bcfe06ba3d64 | 150 | return (float)analogout_read_u16(obj) / 0xffff; |
AnnaBridge | 188:bcfe06ba3d64 | 151 | } |
AnnaBridge | 188:bcfe06ba3d64 | 152 | |
AnnaBridge | 188:bcfe06ba3d64 | 153 | uint16_t analogout_read_u16(dac_t *obj) |
AnnaBridge | 188:bcfe06ba3d64 | 154 | { |
AnnaBridge | 188:bcfe06ba3d64 | 155 | uint16_t value = (obj->base->CTDAC_VAL_NXT >> CTDAC_CTDAC_VAL_NXT_VALUE_Pos) & CTDAC_CTDAC_VAL_NXT_VALUE_Msk; |
AnnaBridge | 188:bcfe06ba3d64 | 156 | |
AnnaBridge | 188:bcfe06ba3d64 | 157 | value <<= (16 - CTDAC_NUM_BITS); // Convert to 16-bit range. |
AnnaBridge | 188:bcfe06ba3d64 | 158 | |
AnnaBridge | 188:bcfe06ba3d64 | 159 | return value; |
AnnaBridge | 188:bcfe06ba3d64 | 160 | } |
AnnaBridge | 188:bcfe06ba3d64 | 161 | |
AnnaBridge | 188:bcfe06ba3d64 | 162 | #endif // DEVICE_ANALOGIN |
AnnaBridge | 188:bcfe06ba3d64 | 163 |