mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_Cypress/TARGET_PSOC6/pwmout_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 "pwmout_api.h" |
AnnaBridge | 188:bcfe06ba3d64 | 22 | #include "cy_tcpwm.h" |
AnnaBridge | 188:bcfe06ba3d64 | 23 | #include "cy_tcpwm_pwm.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 | #include "cy_syspm.h" |
AnnaBridge | 188:bcfe06ba3d64 | 31 | |
AnnaBridge | 188:bcfe06ba3d64 | 32 | #define PWMOUT_BASE_CLOCK_HZ 1000000UL |
AnnaBridge | 188:bcfe06ba3d64 | 33 | #define MAX_16_BIT_PERIOD 65536 |
AnnaBridge | 188:bcfe06ba3d64 | 34 | |
AnnaBridge | 188:bcfe06ba3d64 | 35 | static uint32_t pwm_clock_divider = CY_INVALID_DIVIDER; |
AnnaBridge | 188:bcfe06ba3d64 | 36 | |
AnnaBridge | 188:bcfe06ba3d64 | 37 | static const cy_stc_tcpwm_pwm_config_t pwm_config = { |
AnnaBridge | 188:bcfe06ba3d64 | 38 | .pwmMode = CY_TCPWM_PWM_MODE_PWM, |
AnnaBridge | 188:bcfe06ba3d64 | 39 | .clockPrescaler = 0, // will be configured separately |
AnnaBridge | 188:bcfe06ba3d64 | 40 | .pwmAlignment = CY_TCPWM_PWM_LEFT_ALIGN, |
AnnaBridge | 188:bcfe06ba3d64 | 41 | .runMode = CY_TCPWM_PWM_CONTINUOUS, |
AnnaBridge | 188:bcfe06ba3d64 | 42 | .period0 = 0, // will be configured separately |
AnnaBridge | 188:bcfe06ba3d64 | 43 | .enablePeriodSwap = 0, |
AnnaBridge | 188:bcfe06ba3d64 | 44 | .compare0 = 0, // will be configured separately |
AnnaBridge | 188:bcfe06ba3d64 | 45 | .compare1 = 0, // will be configured separately |
AnnaBridge | 188:bcfe06ba3d64 | 46 | .enableCompareSwap = 0, |
AnnaBridge | 188:bcfe06ba3d64 | 47 | .interruptSources = 0, //CY_TCPWM_INT_ON_CC, |
AnnaBridge | 188:bcfe06ba3d64 | 48 | .invertPWMOut = CY_TCPWM_PWM_INVERT_DISABLE, |
AnnaBridge | 188:bcfe06ba3d64 | 49 | .invertPWMOutN = CY_TCPWM_PWM_INVERT_ENABLE, |
AnnaBridge | 188:bcfe06ba3d64 | 50 | .killMode = CY_TCPWM_PWM_ASYNC_KILL, |
AnnaBridge | 188:bcfe06ba3d64 | 51 | .countInputMode = CY_TCPWM_INPUT_LEVEL, |
AnnaBridge | 188:bcfe06ba3d64 | 52 | .countInput = CY_TCPWM_INPUT_1, |
AnnaBridge | 188:bcfe06ba3d64 | 53 | .swapInputMode = CY_TCPWM_INPUT_LEVEL, |
AnnaBridge | 188:bcfe06ba3d64 | 54 | .swapInput = CY_TCPWM_INPUT_1, |
AnnaBridge | 188:bcfe06ba3d64 | 55 | .reloadInputMode = CY_TCPWM_INPUT_LEVEL, |
AnnaBridge | 188:bcfe06ba3d64 | 56 | .reloadInput = CY_TCPWM_INPUT_0, |
AnnaBridge | 188:bcfe06ba3d64 | 57 | .startInputMode = CY_TCPWM_INPUT_LEVEL, |
AnnaBridge | 188:bcfe06ba3d64 | 58 | .startInput = CY_TCPWM_INPUT_0, |
AnnaBridge | 188:bcfe06ba3d64 | 59 | .killInputMode = CY_TCPWM_INPUT_LEVEL, |
AnnaBridge | 188:bcfe06ba3d64 | 60 | .killInput = CY_TCPWM_INPUT_0, |
AnnaBridge | 188:bcfe06ba3d64 | 61 | }; |
AnnaBridge | 188:bcfe06ba3d64 | 62 | |
AnnaBridge | 188:bcfe06ba3d64 | 63 | |
AnnaBridge | 188:bcfe06ba3d64 | 64 | static void Cy_TCPWM_PWM_SetPrescaler(TCPWM_Type *base, uint32_t cntNum, uint32_t prescaler) |
AnnaBridge | 188:bcfe06ba3d64 | 65 | { |
AnnaBridge | 188:bcfe06ba3d64 | 66 | base->CNT[cntNum].CTRL = _CLR_SET_FLD32U(base->CNT[cntNum].CTRL, TCPWM_CNT_CTRL_GENERIC, prescaler); |
AnnaBridge | 188:bcfe06ba3d64 | 67 | } |
AnnaBridge | 188:bcfe06ba3d64 | 68 | |
AnnaBridge | 188:bcfe06ba3d64 | 69 | static void pwm_start_32b(pwmout_t *obj, uint32_t new_period, uint32_t new_width) |
AnnaBridge | 188:bcfe06ba3d64 | 70 | { |
AnnaBridge | 188:bcfe06ba3d64 | 71 | obj->period = new_period; |
AnnaBridge | 188:bcfe06ba3d64 | 72 | obj->pulse_width = new_width; |
AnnaBridge | 188:bcfe06ba3d64 | 73 | Cy_TCPWM_PWM_SetPeriod0(obj->base, obj->counter_id, obj->period - 1); |
AnnaBridge | 188:bcfe06ba3d64 | 74 | Cy_TCPWM_PWM_SetCompare0(obj->base, obj->counter_id, obj->pulse_width); |
AnnaBridge | 188:bcfe06ba3d64 | 75 | Cy_TCPWM_PWM_Enable(obj->base, obj->counter_id); |
AnnaBridge | 188:bcfe06ba3d64 | 76 | Cy_TCPWM_TriggerStart(obj->base, 1UL << obj->counter_id); |
AnnaBridge | 188:bcfe06ba3d64 | 77 | } |
AnnaBridge | 188:bcfe06ba3d64 | 78 | |
AnnaBridge | 188:bcfe06ba3d64 | 79 | static void pwm_start_16b(pwmout_t *obj, uint32_t period, uint32_t width) |
AnnaBridge | 188:bcfe06ba3d64 | 80 | { |
AnnaBridge | 188:bcfe06ba3d64 | 81 | uint32_t prescaler = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 82 | |
AnnaBridge | 188:bcfe06ba3d64 | 83 | obj->period = period; |
AnnaBridge | 188:bcfe06ba3d64 | 84 | obj->pulse_width = width; |
AnnaBridge | 188:bcfe06ba3d64 | 85 | |
AnnaBridge | 188:bcfe06ba3d64 | 86 | // For 16-bit counters we need to configure prescaler appropriately. |
AnnaBridge | 188:bcfe06ba3d64 | 87 | while ((period > MAX_16_BIT_PERIOD) && (prescaler < CY_TCPWM_PWM_PRESCALER_DIVBY_128)) { |
AnnaBridge | 188:bcfe06ba3d64 | 88 | period /= 2; |
AnnaBridge | 188:bcfe06ba3d64 | 89 | prescaler += 1; |
AnnaBridge | 188:bcfe06ba3d64 | 90 | } |
AnnaBridge | 189:f392fc9709a3 | 91 | |
AnnaBridge | 188:bcfe06ba3d64 | 92 | if (period > MAX_16_BIT_PERIOD) { |
AnnaBridge | 188:bcfe06ba3d64 | 93 | // We have reached the prescaler limit, set period to max value. |
AnnaBridge | 188:bcfe06ba3d64 | 94 | error("Can't configure required PWM period."); |
AnnaBridge | 188:bcfe06ba3d64 | 95 | } |
AnnaBridge | 188:bcfe06ba3d64 | 96 | |
AnnaBridge | 188:bcfe06ba3d64 | 97 | obj->prescaler = prescaler; |
AnnaBridge | 188:bcfe06ba3d64 | 98 | width >>= prescaler; |
AnnaBridge | 188:bcfe06ba3d64 | 99 | |
AnnaBridge | 188:bcfe06ba3d64 | 100 | Cy_TCPWM_PWM_SetPeriod0(obj->base, obj->counter_id, period - 1); |
AnnaBridge | 188:bcfe06ba3d64 | 101 | Cy_TCPWM_PWM_SetPrescaler(obj->base, obj->counter_id, prescaler); |
AnnaBridge | 188:bcfe06ba3d64 | 102 | Cy_TCPWM_PWM_SetCompare0(obj->base, obj->counter_id, width); |
AnnaBridge | 188:bcfe06ba3d64 | 103 | Cy_TCPWM_PWM_Enable(obj->base, obj->counter_id); |
AnnaBridge | 188:bcfe06ba3d64 | 104 | Cy_TCPWM_TriggerStart(obj->base, 1UL << obj->counter_id); |
AnnaBridge | 188:bcfe06ba3d64 | 105 | } |
AnnaBridge | 188:bcfe06ba3d64 | 106 | |
AnnaBridge | 188:bcfe06ba3d64 | 107 | static void pwm_start(pwmout_t *obj, uint32_t new_period, uint32_t new_pulse_width) |
AnnaBridge | 188:bcfe06ba3d64 | 108 | { |
AnnaBridge | 188:bcfe06ba3d64 | 109 | obj->period = new_period; |
AnnaBridge | 188:bcfe06ba3d64 | 110 | obj->pulse_width = new_pulse_width; |
AnnaBridge | 188:bcfe06ba3d64 | 111 | Cy_TCPWM_PWM_Disable(obj->base, obj->counter_id); |
AnnaBridge | 188:bcfe06ba3d64 | 112 | if (new_period > 0) { |
AnnaBridge | 188:bcfe06ba3d64 | 113 | if (obj->base == TCPWM0) { |
AnnaBridge | 188:bcfe06ba3d64 | 114 | pwm_start_32b(obj, new_period, new_pulse_width); |
AnnaBridge | 188:bcfe06ba3d64 | 115 | } else { |
AnnaBridge | 188:bcfe06ba3d64 | 116 | pwm_start_16b(obj, new_period, new_pulse_width); |
AnnaBridge | 188:bcfe06ba3d64 | 117 | } |
AnnaBridge | 188:bcfe06ba3d64 | 118 | } |
AnnaBridge | 188:bcfe06ba3d64 | 119 | } |
AnnaBridge | 188:bcfe06ba3d64 | 120 | |
AnnaBridge | 188:bcfe06ba3d64 | 121 | |
AnnaBridge | 188:bcfe06ba3d64 | 122 | /* |
AnnaBridge | 188:bcfe06ba3d64 | 123 | * Callback handler to restart the timer after deep sleep. |
AnnaBridge | 188:bcfe06ba3d64 | 124 | */ |
AnnaBridge | 189:f392fc9709a3 | 125 | #if DEVICE_SLEEP && DEVICE_LPTICKER |
AnnaBridge | 189:f392fc9709a3 | 126 | static cy_en_syspm_status_t pwm_pm_callback(cy_stc_syspm_callback_params_t *callback_params, cy_en_syspm_callback_mode_t mode) |
AnnaBridge | 188:bcfe06ba3d64 | 127 | { |
AnnaBridge | 188:bcfe06ba3d64 | 128 | pwmout_t *obj = (pwmout_t *)callback_params->context; |
AnnaBridge | 188:bcfe06ba3d64 | 129 | |
AnnaBridge | 189:f392fc9709a3 | 130 | switch (mode) { |
AnnaBridge | 188:bcfe06ba3d64 | 131 | case CY_SYSPM_BEFORE_TRANSITION: |
AnnaBridge | 188:bcfe06ba3d64 | 132 | /* Disable timer before transition */ |
AnnaBridge | 188:bcfe06ba3d64 | 133 | Cy_TCPWM_PWM_Disable(obj->base, obj->counter_id); |
AnnaBridge | 188:bcfe06ba3d64 | 134 | break; |
AnnaBridge | 188:bcfe06ba3d64 | 135 | |
AnnaBridge | 188:bcfe06ba3d64 | 136 | case CY_SYSPM_AFTER_TRANSITION: |
AnnaBridge | 188:bcfe06ba3d64 | 137 | /* Enable the timer to operate */ |
AnnaBridge | 188:bcfe06ba3d64 | 138 | if (obj->period > 0) { |
AnnaBridge | 188:bcfe06ba3d64 | 139 | Cy_TCPWM_PWM_Enable(obj->base, obj->counter_id); |
AnnaBridge | 188:bcfe06ba3d64 | 140 | Cy_TCPWM_TriggerStart(obj->base, 1UL << obj->counter_id); |
AnnaBridge | 188:bcfe06ba3d64 | 141 | } |
AnnaBridge | 188:bcfe06ba3d64 | 142 | break; |
AnnaBridge | 188:bcfe06ba3d64 | 143 | |
AnnaBridge | 188:bcfe06ba3d64 | 144 | default: |
AnnaBridge | 188:bcfe06ba3d64 | 145 | break; |
AnnaBridge | 188:bcfe06ba3d64 | 146 | } |
AnnaBridge | 188:bcfe06ba3d64 | 147 | |
AnnaBridge | 188:bcfe06ba3d64 | 148 | return CY_SYSPM_SUCCESS; |
AnnaBridge | 188:bcfe06ba3d64 | 149 | } |
AnnaBridge | 189:f392fc9709a3 | 150 | #endif // DEVICE_SLEEP && DEVICE_LPTICKER |
AnnaBridge | 188:bcfe06ba3d64 | 151 | |
AnnaBridge | 188:bcfe06ba3d64 | 152 | |
AnnaBridge | 188:bcfe06ba3d64 | 153 | void pwmout_init(pwmout_t *obj, PinName pin) |
AnnaBridge | 188:bcfe06ba3d64 | 154 | { |
AnnaBridge | 188:bcfe06ba3d64 | 155 | uint32_t pwm_cnt = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 156 | uint32_t pwm_function = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 157 | uint32_t abs_cnt_num = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 158 | |
AnnaBridge | 188:bcfe06ba3d64 | 159 | MBED_ASSERT(obj); |
AnnaBridge | 188:bcfe06ba3d64 | 160 | MBED_ASSERT(pin != (PinName)NC); |
AnnaBridge | 189:f392fc9709a3 | 161 | |
AnnaBridge | 189:f392fc9709a3 | 162 | // Allocate and setup clock (same clock for all PWMs) |
AnnaBridge | 188:bcfe06ba3d64 | 163 | if (pwm_clock_divider == CY_INVALID_DIVIDER) { |
AnnaBridge | 189:f392fc9709a3 | 164 | |
AnnaBridge | 188:bcfe06ba3d64 | 165 | pwm_clock_divider = cy_clk_allocate_divider(CY_SYSCLK_DIV_8_BIT); |
AnnaBridge | 188:bcfe06ba3d64 | 166 | if (pwm_clock_divider == CY_INVALID_DIVIDER) { |
AnnaBridge | 188:bcfe06ba3d64 | 167 | error("PWM clock divider allocation failed."); |
AnnaBridge | 188:bcfe06ba3d64 | 168 | } |
AnnaBridge | 189:f392fc9709a3 | 169 | |
AnnaBridge | 189:f392fc9709a3 | 170 | /* Configure divider */ |
AnnaBridge | 189:f392fc9709a3 | 171 | Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, pwm_clock_divider, |
AnnaBridge | 189:f392fc9709a3 | 172 | (cy_PeriClkFreqHz / PWMOUT_BASE_CLOCK_HZ) - 1); |
AnnaBridge | 188:bcfe06ba3d64 | 173 | Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, pwm_clock_divider); |
AnnaBridge | 188:bcfe06ba3d64 | 174 | } |
AnnaBridge | 188:bcfe06ba3d64 | 175 | |
AnnaBridge | 189:f392fc9709a3 | 176 | /* Find instance using pins */ |
AnnaBridge | 188:bcfe06ba3d64 | 177 | pwm_cnt = pinmap_peripheral(pin, PinMap_PWM_OUT); |
AnnaBridge | 188:bcfe06ba3d64 | 178 | if (pwm_cnt != (uint32_t)NC) { |
AnnaBridge | 189:f392fc9709a3 | 179 | |
AnnaBridge | 189:f392fc9709a3 | 180 | obj->pin = pin; |
AnnaBridge | 189:f392fc9709a3 | 181 | obj->base = (TCPWM_Type *)CY_PERIPHERAL_BASE(pwm_cnt); |
AnnaBridge | 188:bcfe06ba3d64 | 182 | if (obj->base == TCPWM0) { |
AnnaBridge | 189:f392fc9709a3 | 183 | /* TCPWM0 is used */ |
AnnaBridge | 188:bcfe06ba3d64 | 184 | obj->counter_id = ((PWMName)pwm_cnt - PWM_32b_0) / (PWM_32b_1 - PWM_32b_0); |
AnnaBridge | 188:bcfe06ba3d64 | 185 | abs_cnt_num = obj->counter_id; |
AnnaBridge | 188:bcfe06ba3d64 | 186 | } else { |
AnnaBridge | 189:f392fc9709a3 | 187 | /* TCPWM1 is used */ |
AnnaBridge | 188:bcfe06ba3d64 | 188 | obj->counter_id = ((PWMName)pwm_cnt - PWM_16b_0) / (PWM_16b_1 - PWM_16b_0); |
AnnaBridge | 188:bcfe06ba3d64 | 189 | abs_cnt_num = obj->counter_id + 8; |
AnnaBridge | 188:bcfe06ba3d64 | 190 | } |
AnnaBridge | 189:f392fc9709a3 | 191 | |
AnnaBridge | 189:f392fc9709a3 | 192 | /* Check if resource severed */ |
AnnaBridge | 189:f392fc9709a3 | 193 | if (0 != cy_reserve_tcpwm(abs_cnt_num)) { |
AnnaBridge | 189:f392fc9709a3 | 194 | Cy_TCPWM_PWM_Disable(obj->base, obj->counter_id); |
AnnaBridge | 189:f392fc9709a3 | 195 | Cy_TCPWM_PWM_DeInit(obj->base, obj->counter_id, &pwm_config); |
AnnaBridge | 189:f392fc9709a3 | 196 | } else { |
AnnaBridge | 189:f392fc9709a3 | 197 | if (cy_reserve_io_pin(pin)) { |
AnnaBridge | 189:f392fc9709a3 | 198 | error("PWMOUT pin reservation conflict."); |
AnnaBridge | 189:f392fc9709a3 | 199 | } |
AnnaBridge | 189:f392fc9709a3 | 200 | |
AnnaBridge | 189:f392fc9709a3 | 201 | #if DEVICE_SLEEP && DEVICE_LPTICKER |
AnnaBridge | 189:f392fc9709a3 | 202 | /* Register callback once */ |
AnnaBridge | 189:f392fc9709a3 | 203 | obj->pm_callback_handler.callback = pwm_pm_callback; |
AnnaBridge | 189:f392fc9709a3 | 204 | obj->pm_callback_handler.type = CY_SYSPM_DEEPSLEEP; |
AnnaBridge | 189:f392fc9709a3 | 205 | obj->pm_callback_handler.skipMode = 0; |
AnnaBridge | 189:f392fc9709a3 | 206 | obj->pm_callback_handler.callbackParams = &obj->pm_callback_params; |
AnnaBridge | 189:f392fc9709a3 | 207 | obj->pm_callback_params.base = obj->base; |
AnnaBridge | 189:f392fc9709a3 | 208 | obj->pm_callback_params.context = obj; |
AnnaBridge | 189:f392fc9709a3 | 209 | if (!Cy_SysPm_RegisterCallback(&obj->pm_callback_handler)) { |
AnnaBridge | 189:f392fc9709a3 | 210 | error("PM callback registration failed!"); |
AnnaBridge | 189:f392fc9709a3 | 211 | } |
AnnaBridge | 189:f392fc9709a3 | 212 | #endif // DEVICE_SLEEP && DEVICE_LPTICKER |
AnnaBridge | 188:bcfe06ba3d64 | 213 | } |
AnnaBridge | 188:bcfe06ba3d64 | 214 | |
AnnaBridge | 189:f392fc9709a3 | 215 | /* Configure pin */ |
AnnaBridge | 188:bcfe06ba3d64 | 216 | pwm_function = pinmap_function(pin, PinMap_PWM_OUT); |
AnnaBridge | 189:f392fc9709a3 | 217 | pin_function(pin, pwm_function); |
AnnaBridge | 189:f392fc9709a3 | 218 | |
AnnaBridge | 189:f392fc9709a3 | 219 | /* Connect clock */ |
AnnaBridge | 188:bcfe06ba3d64 | 220 | obj->clock = CY_PIN_CLOCK(pwm_function); |
AnnaBridge | 188:bcfe06ba3d64 | 221 | Cy_SysClk_PeriphAssignDivider(obj->clock, CY_SYSCLK_DIV_8_BIT, pwm_clock_divider); |
AnnaBridge | 189:f392fc9709a3 | 222 | |
AnnaBridge | 189:f392fc9709a3 | 223 | /* Configure hardarwe */ |
AnnaBridge | 188:bcfe06ba3d64 | 224 | Cy_TCPWM_PWM_Init(obj->base, obj->counter_id, &pwm_config); |
AnnaBridge | 189:f392fc9709a3 | 225 | |
AnnaBridge | 188:bcfe06ba3d64 | 226 | // These will be properly configured later on. |
AnnaBridge | 189:f392fc9709a3 | 227 | obj->period = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 228 | obj->pulse_width = 0; |
AnnaBridge | 189:f392fc9709a3 | 229 | obj->prescaler = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 230 | |
AnnaBridge | 188:bcfe06ba3d64 | 231 | } else { |
AnnaBridge | 188:bcfe06ba3d64 | 232 | error("PWM OUT pinout mismatch."); |
AnnaBridge | 188:bcfe06ba3d64 | 233 | } |
AnnaBridge | 188:bcfe06ba3d64 | 234 | } |
AnnaBridge | 188:bcfe06ba3d64 | 235 | |
AnnaBridge | 188:bcfe06ba3d64 | 236 | void pwmout_free(pwmout_t *obj) |
AnnaBridge | 188:bcfe06ba3d64 | 237 | { |
AnnaBridge | 189:f392fc9709a3 | 238 | /* Does nothing because it is not called in the MBED PWMOUT driver |
AnnaBridge | 189:f392fc9709a3 | 239 | * destructor. The pwmout_init handles multiple calls of constructor. |
AnnaBridge | 189:f392fc9709a3 | 240 | */ |
AnnaBridge | 188:bcfe06ba3d64 | 241 | } |
AnnaBridge | 188:bcfe06ba3d64 | 242 | |
AnnaBridge | 188:bcfe06ba3d64 | 243 | void pwmout_write(pwmout_t *obj, float percent) |
AnnaBridge | 188:bcfe06ba3d64 | 244 | { |
AnnaBridge | 188:bcfe06ba3d64 | 245 | uint32_t pulse_width; |
AnnaBridge | 188:bcfe06ba3d64 | 246 | MBED_ASSERT(obj); |
AnnaBridge | 188:bcfe06ba3d64 | 247 | |
AnnaBridge | 188:bcfe06ba3d64 | 248 | if (percent < 0.0) { |
AnnaBridge | 188:bcfe06ba3d64 | 249 | percent = 0.0; |
AnnaBridge | 188:bcfe06ba3d64 | 250 | } else if (percent > 1.0) { |
AnnaBridge | 188:bcfe06ba3d64 | 251 | percent = 1.0; |
AnnaBridge | 188:bcfe06ba3d64 | 252 | } |
AnnaBridge | 188:bcfe06ba3d64 | 253 | pulse_width = (uint32_t)(percent * obj->period + 0.5); |
AnnaBridge | 188:bcfe06ba3d64 | 254 | pwm_start(obj, obj->period, pulse_width); |
AnnaBridge | 188:bcfe06ba3d64 | 255 | } |
AnnaBridge | 188:bcfe06ba3d64 | 256 | |
AnnaBridge | 188:bcfe06ba3d64 | 257 | float pwmout_read(pwmout_t *obj) |
AnnaBridge | 188:bcfe06ba3d64 | 258 | { |
AnnaBridge | 188:bcfe06ba3d64 | 259 | MBED_ASSERT(obj); |
AnnaBridge | 188:bcfe06ba3d64 | 260 | |
AnnaBridge | 188:bcfe06ba3d64 | 261 | return (float)(obj->pulse_width) / obj->period; |
AnnaBridge | 188:bcfe06ba3d64 | 262 | } |
AnnaBridge | 188:bcfe06ba3d64 | 263 | |
AnnaBridge | 188:bcfe06ba3d64 | 264 | void pwmout_period(pwmout_t *obj, float seconds) |
AnnaBridge | 188:bcfe06ba3d64 | 265 | { |
AnnaBridge | 188:bcfe06ba3d64 | 266 | uint32_t period; |
AnnaBridge | 188:bcfe06ba3d64 | 267 | uint32_t pulse_width; |
AnnaBridge | 188:bcfe06ba3d64 | 268 | |
AnnaBridge | 188:bcfe06ba3d64 | 269 | MBED_ASSERT(obj); |
AnnaBridge | 188:bcfe06ba3d64 | 270 | |
AnnaBridge | 188:bcfe06ba3d64 | 271 | if (seconds < 0.0) { |
AnnaBridge | 188:bcfe06ba3d64 | 272 | seconds = 0.0; |
AnnaBridge | 188:bcfe06ba3d64 | 273 | } |
AnnaBridge | 188:bcfe06ba3d64 | 274 | period = (uint32_t)(seconds * 1000000 + 0.5); |
AnnaBridge | 188:bcfe06ba3d64 | 275 | pulse_width = (uint32_t)((uint64_t)period * obj->pulse_width / obj->period); |
AnnaBridge | 188:bcfe06ba3d64 | 276 | pwm_start(obj, period, pulse_width); |
AnnaBridge | 188:bcfe06ba3d64 | 277 | } |
AnnaBridge | 188:bcfe06ba3d64 | 278 | |
AnnaBridge | 188:bcfe06ba3d64 | 279 | void pwmout_period_ms(pwmout_t *obj, int ms) |
AnnaBridge | 188:bcfe06ba3d64 | 280 | { |
AnnaBridge | 188:bcfe06ba3d64 | 281 | uint32_t period; |
AnnaBridge | 188:bcfe06ba3d64 | 282 | uint32_t pulse_width; |
AnnaBridge | 188:bcfe06ba3d64 | 283 | |
AnnaBridge | 188:bcfe06ba3d64 | 284 | MBED_ASSERT(obj); |
AnnaBridge | 188:bcfe06ba3d64 | 285 | |
AnnaBridge | 188:bcfe06ba3d64 | 286 | if (ms < 0.0) { |
AnnaBridge | 188:bcfe06ba3d64 | 287 | ms = 0.0; |
AnnaBridge | 188:bcfe06ba3d64 | 288 | } |
AnnaBridge | 188:bcfe06ba3d64 | 289 | period = (uint32_t)(ms * 1000 + 0.5); |
AnnaBridge | 188:bcfe06ba3d64 | 290 | pulse_width = (uint32_t)((uint64_t)period * obj->pulse_width / obj->period); |
AnnaBridge | 188:bcfe06ba3d64 | 291 | pwm_start(obj, period, pulse_width); |
AnnaBridge | 188:bcfe06ba3d64 | 292 | } |
AnnaBridge | 188:bcfe06ba3d64 | 293 | |
AnnaBridge | 188:bcfe06ba3d64 | 294 | void pwmout_period_us(pwmout_t *obj, int us) |
AnnaBridge | 188:bcfe06ba3d64 | 295 | { |
AnnaBridge | 188:bcfe06ba3d64 | 296 | uint32_t pulse_width; |
AnnaBridge | 188:bcfe06ba3d64 | 297 | |
AnnaBridge | 188:bcfe06ba3d64 | 298 | MBED_ASSERT(obj); |
AnnaBridge | 188:bcfe06ba3d64 | 299 | |
AnnaBridge | 188:bcfe06ba3d64 | 300 | if (us < 0) { |
AnnaBridge | 188:bcfe06ba3d64 | 301 | us = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 302 | } |
AnnaBridge | 188:bcfe06ba3d64 | 303 | pulse_width = (uint32_t)((uint64_t)us * obj->pulse_width / obj->period); |
AnnaBridge | 188:bcfe06ba3d64 | 304 | pwm_start(obj, us, pulse_width); |
AnnaBridge | 188:bcfe06ba3d64 | 305 | } |
AnnaBridge | 188:bcfe06ba3d64 | 306 | |
AnnaBridge | 188:bcfe06ba3d64 | 307 | void pwmout_pulsewidth(pwmout_t *obj, float seconds) |
AnnaBridge | 188:bcfe06ba3d64 | 308 | { |
AnnaBridge | 188:bcfe06ba3d64 | 309 | uint32_t pulse_width; |
AnnaBridge | 188:bcfe06ba3d64 | 310 | |
AnnaBridge | 188:bcfe06ba3d64 | 311 | MBED_ASSERT(obj); |
AnnaBridge | 188:bcfe06ba3d64 | 312 | |
AnnaBridge | 188:bcfe06ba3d64 | 313 | if (seconds < 0.0) { |
AnnaBridge | 188:bcfe06ba3d64 | 314 | seconds = 0.0; |
AnnaBridge | 188:bcfe06ba3d64 | 315 | } |
AnnaBridge | 188:bcfe06ba3d64 | 316 | pulse_width = (uint32_t)(seconds * 1000000 + 0.5); |
AnnaBridge | 188:bcfe06ba3d64 | 317 | pwm_start(obj, obj->period, pulse_width); |
AnnaBridge | 188:bcfe06ba3d64 | 318 | } |
AnnaBridge | 188:bcfe06ba3d64 | 319 | |
AnnaBridge | 188:bcfe06ba3d64 | 320 | void pwmout_pulsewidth_ms(pwmout_t *obj, int ms) |
AnnaBridge | 188:bcfe06ba3d64 | 321 | { |
AnnaBridge | 188:bcfe06ba3d64 | 322 | uint32_t pulse_width; |
AnnaBridge | 188:bcfe06ba3d64 | 323 | |
AnnaBridge | 188:bcfe06ba3d64 | 324 | MBED_ASSERT(obj); |
AnnaBridge | 188:bcfe06ba3d64 | 325 | |
AnnaBridge | 188:bcfe06ba3d64 | 326 | if (ms < 0.0) { |
AnnaBridge | 188:bcfe06ba3d64 | 327 | ms = 0.0; |
AnnaBridge | 188:bcfe06ba3d64 | 328 | } |
AnnaBridge | 188:bcfe06ba3d64 | 329 | pulse_width = (uint32_t)(ms * 1000 + 0.5); |
AnnaBridge | 188:bcfe06ba3d64 | 330 | pwm_start(obj, obj->period, pulse_width); |
AnnaBridge | 188:bcfe06ba3d64 | 331 | } |
AnnaBridge | 188:bcfe06ba3d64 | 332 | |
AnnaBridge | 188:bcfe06ba3d64 | 333 | void pwmout_pulsewidth_us(pwmout_t *obj, int us) |
AnnaBridge | 188:bcfe06ba3d64 | 334 | { |
AnnaBridge | 188:bcfe06ba3d64 | 335 | MBED_ASSERT(obj); |
AnnaBridge | 188:bcfe06ba3d64 | 336 | |
AnnaBridge | 188:bcfe06ba3d64 | 337 | if (us < 0) { |
AnnaBridge | 188:bcfe06ba3d64 | 338 | us = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 339 | } |
AnnaBridge | 188:bcfe06ba3d64 | 340 | pwm_start(obj, obj->period, us); |
AnnaBridge | 188:bcfe06ba3d64 | 341 | } |