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 <stddef.h>
AnnaBridge 188:bcfe06ba3d64 21 #include <limits.h>
AnnaBridge 188:bcfe06ba3d64 22 #include "device.h"
AnnaBridge 188:bcfe06ba3d64 23 #include "PeripheralNames.h"
AnnaBridge 188:bcfe06ba3d64 24 #include "us_ticker_api.h"
AnnaBridge 188:bcfe06ba3d64 25 #include "mbed_error.h"
AnnaBridge 188:bcfe06ba3d64 26 #include "psoc6_utils.h"
AnnaBridge 188:bcfe06ba3d64 27
AnnaBridge 189:f392fc9709a3 28 #include "cy_sysint.h"
AnnaBridge 189:f392fc9709a3 29 #include "cy_sysclk.h"
AnnaBridge 189:f392fc9709a3 30 #include "cy_tcpwm_counter.h"
AnnaBridge 189:f392fc9709a3 31 #include "cy_syspm.h"
AnnaBridge 188:bcfe06ba3d64 32
AnnaBridge 188:bcfe06ba3d64 33 /** Each CPU core in PSoC6 needs its own usec timer.
AnnaBridge 188:bcfe06ba3d64 34 ** Although each of TCPWM timers have two compare registers,
AnnaBridge 188:bcfe06ba3d64 35 ** it has only one interrupt line, so we need to allocate
AnnaBridge 188:bcfe06ba3d64 36 ** two TCPWM counters for the purpose of us_ticker
AnnaBridge 188:bcfe06ba3d64 37 **/
AnnaBridge 188:bcfe06ba3d64 38
AnnaBridge 188:bcfe06ba3d64 39
AnnaBridge 188:bcfe06ba3d64 40 #if defined(TARGET_MCU_PSOC6_M0)
AnnaBridge 188:bcfe06ba3d64 41
AnnaBridge 188:bcfe06ba3d64 42 #define TICKER_COUNTER_UNIT TCPWM0
AnnaBridge 188:bcfe06ba3d64 43 #define TICKER_COUNTER_NUM 0
AnnaBridge 188:bcfe06ba3d64 44 #define TICKER_COUNTER_INTERRUPT_SOURCE tcpwm_0_interrupts_0_IRQn
AnnaBridge 188:bcfe06ba3d64 45 #define TICKER_COUNTER_NVIC_IRQN CY_M0_CORE_IRQ_CHANNEL_US_TICKER
AnnaBridge 188:bcfe06ba3d64 46 #define TICKER_COUNTER_INTERRUPT_PRIORITY 3
AnnaBridge 189:f392fc9709a3 47 #define TICKER_CLOCK_DIVIDER_NUM 6
AnnaBridge 188:bcfe06ba3d64 48
AnnaBridge 188:bcfe06ba3d64 49 #elif defined(TARGET_MCU_PSOC6_M4)
AnnaBridge 188:bcfe06ba3d64 50
AnnaBridge 188:bcfe06ba3d64 51 #define TICKER_COUNTER_UNIT TCPWM0
AnnaBridge 188:bcfe06ba3d64 52 #define TICKER_COUNTER_NUM 1
AnnaBridge 188:bcfe06ba3d64 53 #define TICKER_COUNTER_INTERRUPT_SOURCE tcpwm_0_interrupts_1_IRQn
AnnaBridge 188:bcfe06ba3d64 54 #define TICKER_COUNTER_NVIC_IRQN TICKER_COUNTER_INTERRUPT_SOURCE
AnnaBridge 188:bcfe06ba3d64 55 #define TICKER_COUNTER_INTERRUPT_PRIORITY 6
AnnaBridge 189:f392fc9709a3 56 #define TICKER_CLOCK_DIVIDER_NUM 7
AnnaBridge 188:bcfe06ba3d64 57
AnnaBridge 188:bcfe06ba3d64 58 #else
AnnaBridge 188:bcfe06ba3d64 59 #error "Unknown MCU type."
AnnaBridge 188:bcfe06ba3d64 60 #endif
AnnaBridge 188:bcfe06ba3d64 61
AnnaBridge 188:bcfe06ba3d64 62
AnnaBridge 188:bcfe06ba3d64 63 static const ticker_info_t us_ticker_info = {
AnnaBridge 188:bcfe06ba3d64 64 .frequency = 1000000UL,
AnnaBridge 188:bcfe06ba3d64 65 .bits = 32,
AnnaBridge 188:bcfe06ba3d64 66 };
AnnaBridge 188:bcfe06ba3d64 67
AnnaBridge 188:bcfe06ba3d64 68 static const cy_stc_sysint_t us_ticker_sysint_cfg = {
AnnaBridge 188:bcfe06ba3d64 69 .intrSrc = TICKER_COUNTER_NVIC_IRQN,
AnnaBridge 188:bcfe06ba3d64 70 #if defined(TARGET_MCU_PSOC6_M0)
AnnaBridge 188:bcfe06ba3d64 71 .cm0pSrc = TICKER_COUNTER_INTERRUPT_SOURCE,
AnnaBridge 188:bcfe06ba3d64 72 #endif
AnnaBridge 188:bcfe06ba3d64 73 .intrPriority = TICKER_COUNTER_INTERRUPT_PRIORITY
AnnaBridge 188:bcfe06ba3d64 74 };
AnnaBridge 188:bcfe06ba3d64 75
AnnaBridge 188:bcfe06ba3d64 76 static int us_ticker_inited = 0;
AnnaBridge 188:bcfe06ba3d64 77
AnnaBridge 188:bcfe06ba3d64 78 static const cy_stc_tcpwm_counter_config_t cy_counter_config = {
AnnaBridge 188:bcfe06ba3d64 79 .period = 0xFFFFFFFFUL,
AnnaBridge 188:bcfe06ba3d64 80 .clockPrescaler = CY_TCPWM_COUNTER_PRESCALER_DIVBY_1,
AnnaBridge 188:bcfe06ba3d64 81 .runMode = CY_TCPWM_COUNTER_CONTINUOUS,
AnnaBridge 188:bcfe06ba3d64 82 .countDirection = CY_TCPWM_COUNTER_COUNT_UP,
AnnaBridge 188:bcfe06ba3d64 83 .compareOrCapture = CY_TCPWM_COUNTER_MODE_COMPARE,
AnnaBridge 188:bcfe06ba3d64 84 .enableCompareSwap = false,
AnnaBridge 188:bcfe06ba3d64 85 .interruptSources = CY_TCPWM_INT_ON_CC,
AnnaBridge 188:bcfe06ba3d64 86 .countInputMode = CY_TCPWM_INPUT_LEVEL,
AnnaBridge 188:bcfe06ba3d64 87 .countInput = CY_TCPWM_INPUT_1
AnnaBridge 188:bcfe06ba3d64 88 };
AnnaBridge 188:bcfe06ba3d64 89
AnnaBridge 188:bcfe06ba3d64 90 // PM callback to be executed when exiting deep sleep.
AnnaBridge 189:f392fc9709a3 91 static cy_en_syspm_status_t ticker_pm_callback(cy_stc_syspm_callback_params_t *callbackParams, cy_en_syspm_callback_mode_t mode);
AnnaBridge 188:bcfe06ba3d64 92
AnnaBridge 188:bcfe06ba3d64 93 static cy_stc_syspm_callback_params_t ticker_pm_callback_params = {
AnnaBridge 188:bcfe06ba3d64 94 .base = TICKER_COUNTER_UNIT
AnnaBridge 188:bcfe06ba3d64 95 };
AnnaBridge 188:bcfe06ba3d64 96
AnnaBridge 188:bcfe06ba3d64 97 static cy_stc_syspm_callback_t ticker_pm_callback_handler = {
AnnaBridge 188:bcfe06ba3d64 98 .callback = ticker_pm_callback,
AnnaBridge 188:bcfe06ba3d64 99 .type = CY_SYSPM_DEEPSLEEP,
AnnaBridge 188:bcfe06ba3d64 100 .skipMode = CY_SYSPM_SKIP_CHECK_READY | CY_SYSPM_SKIP_CHECK_FAIL | CY_SYSPM_SKIP_BEFORE_TRANSITION,
AnnaBridge 188:bcfe06ba3d64 101 .callbackParams = &ticker_pm_callback_params
AnnaBridge 188:bcfe06ba3d64 102 };
AnnaBridge 188:bcfe06ba3d64 103
AnnaBridge 188:bcfe06ba3d64 104
AnnaBridge 188:bcfe06ba3d64 105 /*
AnnaBridge 188:bcfe06ba3d64 106 * Callback handler to restart the timer after deep sleep.
AnnaBridge 188:bcfe06ba3d64 107 */
AnnaBridge 189:f392fc9709a3 108 static cy_en_syspm_status_t ticker_pm_callback(cy_stc_syspm_callback_params_t *params, cy_en_syspm_callback_mode_t mode)
AnnaBridge 188:bcfe06ba3d64 109 {
AnnaBridge 189:f392fc9709a3 110 if (mode == CY_SYSPM_AFTER_TRANSITION) {
AnnaBridge 188:bcfe06ba3d64 111 Cy_TCPWM_Counter_Enable(TICKER_COUNTER_UNIT, TICKER_COUNTER_NUM);
AnnaBridge 188:bcfe06ba3d64 112 Cy_TCPWM_TriggerStart(TICKER_COUNTER_UNIT, 1UL << TICKER_COUNTER_NUM);
AnnaBridge 188:bcfe06ba3d64 113 }
AnnaBridge 188:bcfe06ba3d64 114 return CY_SYSPM_SUCCESS;
AnnaBridge 188:bcfe06ba3d64 115 }
AnnaBridge 188:bcfe06ba3d64 116
AnnaBridge 188:bcfe06ba3d64 117 /*
AnnaBridge 188:bcfe06ba3d64 118 * Interrupt handler.
AnnaBridge 188:bcfe06ba3d64 119 */
AnnaBridge 188:bcfe06ba3d64 120 static void local_irq_handler(void)
AnnaBridge 188:bcfe06ba3d64 121 {
AnnaBridge 188:bcfe06ba3d64 122 us_ticker_clear_interrupt();
AnnaBridge 188:bcfe06ba3d64 123 us_ticker_disable_interrupt();
AnnaBridge 188:bcfe06ba3d64 124 us_ticker_irq_handler();
AnnaBridge 188:bcfe06ba3d64 125 }
AnnaBridge 188:bcfe06ba3d64 126
AnnaBridge 188:bcfe06ba3d64 127
AnnaBridge 188:bcfe06ba3d64 128 void us_ticker_init(void)
AnnaBridge 188:bcfe06ba3d64 129 {
AnnaBridge 188:bcfe06ba3d64 130 us_ticker_disable_interrupt();
AnnaBridge 188:bcfe06ba3d64 131 us_ticker_clear_interrupt();
AnnaBridge 188:bcfe06ba3d64 132
AnnaBridge 189:f392fc9709a3 133 if (us_ticker_inited) {
AnnaBridge 188:bcfe06ba3d64 134 return;
AnnaBridge 189:f392fc9709a3 135 }
AnnaBridge 188:bcfe06ba3d64 136
AnnaBridge 188:bcfe06ba3d64 137 us_ticker_inited = 1;
AnnaBridge 188:bcfe06ba3d64 138
AnnaBridge 188:bcfe06ba3d64 139 // Configure the clock, us_ticker 1 MHz from PCLK 50 MHz
AnnaBridge 188:bcfe06ba3d64 140 Cy_SysClk_PeriphAssignDivider(PCLK_TCPWM0_CLOCKS0 + TICKER_COUNTER_NUM, CY_SYSCLK_DIV_8_BIT, TICKER_CLOCK_DIVIDER_NUM);
AnnaBridge 189:f392fc9709a3 141 Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, TICKER_CLOCK_DIVIDER_NUM, (cy_PeriClkFreqHz / 1000000UL) - 1);
AnnaBridge 188:bcfe06ba3d64 142 Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, TICKER_CLOCK_DIVIDER_NUM);
AnnaBridge 188:bcfe06ba3d64 143
AnnaBridge 188:bcfe06ba3d64 144 /*
AnnaBridge 188:bcfe06ba3d64 145 Configure the counter
AnnaBridge 188:bcfe06ba3d64 146 */
AnnaBridge 188:bcfe06ba3d64 147
AnnaBridge 188:bcfe06ba3d64 148 Cy_TCPWM_Counter_Init(TICKER_COUNTER_UNIT, TICKER_COUNTER_NUM, &cy_counter_config);
AnnaBridge 188:bcfe06ba3d64 149 Cy_TCPWM_Counter_Enable(TICKER_COUNTER_UNIT, TICKER_COUNTER_NUM);
AnnaBridge 188:bcfe06ba3d64 150 if (!Cy_SysPm_RegisterCallback(&ticker_pm_callback_handler)) {
AnnaBridge 188:bcfe06ba3d64 151 error("PM callback registration failed!");
AnnaBridge 188:bcfe06ba3d64 152 }
AnnaBridge 188:bcfe06ba3d64 153 Cy_TCPWM_TriggerStart(TICKER_COUNTER_UNIT, 1UL << TICKER_COUNTER_NUM);
AnnaBridge 188:bcfe06ba3d64 154
AnnaBridge 188:bcfe06ba3d64 155 #if defined (TARGET_MCU_PSOC6_M0)
AnnaBridge 188:bcfe06ba3d64 156 if (cy_m0_nvic_reserve_channel(TICKER_COUNTER_NVIC_IRQN, CY_US_TICKER_IRQN_ID) == (IRQn_Type)(-1)) {
AnnaBridge 188:bcfe06ba3d64 157 error("Microsecond ticker NVIC channel reservation conflict.");
AnnaBridge 188:bcfe06ba3d64 158 }
AnnaBridge 188:bcfe06ba3d64 159 #endif //
AnnaBridge 188:bcfe06ba3d64 160
AnnaBridge 188:bcfe06ba3d64 161 Cy_SysInt_Init(&us_ticker_sysint_cfg, local_irq_handler);
AnnaBridge 188:bcfe06ba3d64 162 }
AnnaBridge 188:bcfe06ba3d64 163
AnnaBridge 188:bcfe06ba3d64 164 void us_ticker_free(void)
AnnaBridge 188:bcfe06ba3d64 165 {
AnnaBridge 188:bcfe06ba3d64 166 us_ticker_disable_interrupt();
AnnaBridge 188:bcfe06ba3d64 167 Cy_TCPWM_Counter_Disable(TICKER_COUNTER_UNIT, TICKER_COUNTER_NUM);
AnnaBridge 188:bcfe06ba3d64 168 Cy_SysPm_UnregisterCallback(&ticker_pm_callback_handler);
AnnaBridge 188:bcfe06ba3d64 169 #if defined (TARGET_MCU_PSOC6_M0)
AnnaBridge 188:bcfe06ba3d64 170 cy_m0_nvic_release_channel(TICKER_COUNTER_NVIC_IRQN, CY_US_TICKER_IRQN_ID);
AnnaBridge 188:bcfe06ba3d64 171 #endif //
AnnaBridge 188:bcfe06ba3d64 172 us_ticker_inited = 0;
AnnaBridge 188:bcfe06ba3d64 173 }
AnnaBridge 188:bcfe06ba3d64 174
AnnaBridge 188:bcfe06ba3d64 175 uint32_t us_ticker_read(void)
AnnaBridge 188:bcfe06ba3d64 176 {
AnnaBridge 189:f392fc9709a3 177 if (!us_ticker_inited) {
AnnaBridge 188:bcfe06ba3d64 178 us_ticker_init();
AnnaBridge 189:f392fc9709a3 179 }
AnnaBridge 188:bcfe06ba3d64 180 return Cy_TCPWM_Counter_GetCounter(TICKER_COUNTER_UNIT, TICKER_COUNTER_NUM);
AnnaBridge 188:bcfe06ba3d64 181 }
AnnaBridge 188:bcfe06ba3d64 182
AnnaBridge 188:bcfe06ba3d64 183 void us_ticker_set_interrupt(timestamp_t timestamp)
AnnaBridge 188:bcfe06ba3d64 184 {
AnnaBridge 188:bcfe06ba3d64 185 uint32_t current_ts = Cy_TCPWM_Counter_GetCounter(TICKER_COUNTER_UNIT, TICKER_COUNTER_NUM);
AnnaBridge 188:bcfe06ba3d64 186 uint32_t delta = timestamp - current_ts;
AnnaBridge 188:bcfe06ba3d64 187
AnnaBridge 189:f392fc9709a3 188 if (!us_ticker_inited) {
AnnaBridge 188:bcfe06ba3d64 189 us_ticker_init();
AnnaBridge 189:f392fc9709a3 190 }
AnnaBridge 188:bcfe06ba3d64 191
AnnaBridge 188:bcfe06ba3d64 192 // Set new output compare value
AnnaBridge 188:bcfe06ba3d64 193 if ((delta < 2) || (delta > (uint32_t)(-3))) {
AnnaBridge 188:bcfe06ba3d64 194 timestamp = current_ts + 2;
AnnaBridge 188:bcfe06ba3d64 195 }
AnnaBridge 188:bcfe06ba3d64 196 Cy_TCPWM_Counter_SetCompare0(TICKER_COUNTER_UNIT, TICKER_COUNTER_NUM, timestamp);
AnnaBridge 188:bcfe06ba3d64 197 // Enable int
AnnaBridge 188:bcfe06ba3d64 198 NVIC_EnableIRQ(TICKER_COUNTER_NVIC_IRQN);
AnnaBridge 188:bcfe06ba3d64 199 }
AnnaBridge 188:bcfe06ba3d64 200
AnnaBridge 188:bcfe06ba3d64 201 void us_ticker_disable_interrupt(void)
AnnaBridge 188:bcfe06ba3d64 202 {
AnnaBridge 188:bcfe06ba3d64 203 NVIC_DisableIRQ(TICKER_COUNTER_NVIC_IRQN);
AnnaBridge 188:bcfe06ba3d64 204 }
AnnaBridge 188:bcfe06ba3d64 205
AnnaBridge 188:bcfe06ba3d64 206 void us_ticker_clear_interrupt(void)
AnnaBridge 188:bcfe06ba3d64 207 {
AnnaBridge 188:bcfe06ba3d64 208 Cy_TCPWM_ClearInterrupt(TICKER_COUNTER_UNIT, TICKER_COUNTER_NUM, CY_TCPWM_INT_ON_CC);
AnnaBridge 188:bcfe06ba3d64 209 }
AnnaBridge 188:bcfe06ba3d64 210
AnnaBridge 188:bcfe06ba3d64 211 void us_ticker_fire_interrupt(void)
AnnaBridge 188:bcfe06ba3d64 212 {
AnnaBridge 188:bcfe06ba3d64 213 NVIC_EnableIRQ(TICKER_COUNTER_NVIC_IRQN);
AnnaBridge 188:bcfe06ba3d64 214 NVIC_SetPendingIRQ(TICKER_COUNTER_NVIC_IRQN);
AnnaBridge 188:bcfe06ba3d64 215 }
AnnaBridge 188:bcfe06ba3d64 216
AnnaBridge 189:f392fc9709a3 217 const ticker_info_t *us_ticker_get_info(void)
AnnaBridge 188:bcfe06ba3d64 218 {
AnnaBridge 188:bcfe06ba3d64 219 return &us_ticker_info;
AnnaBridge 188:bcfe06ba3d64 220 }