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 "device.h"
AnnaBridge 188:bcfe06ba3d64 22 #include "mbed_error.h"
AnnaBridge 188:bcfe06ba3d64 23 #include "lp_ticker_api.h"
AnnaBridge 189:f392fc9709a3 24 #include "cy_mcwdt.h"
AnnaBridge 189:f392fc9709a3 25 #include "cy_sysint.h"
AnnaBridge 188:bcfe06ba3d64 26 #include "psoc6_utils.h"
AnnaBridge 188:bcfe06ba3d64 27
AnnaBridge 188:bcfe06ba3d64 28 #if DEVICE_LPTICKER
AnnaBridge 188:bcfe06ba3d64 29
AnnaBridge 188:bcfe06ba3d64 30 /*
AnnaBridge 188:bcfe06ba3d64 31 * Low Power Timer API on PSoC6 uses MCWD0 timer0 to implement functionality.
AnnaBridge 188:bcfe06ba3d64 32 */
AnnaBridge 188:bcfe06ba3d64 33
AnnaBridge 188:bcfe06ba3d64 34 #if defined(TARGET_MCU_PSOC6_M0)
AnnaBridge 188:bcfe06ba3d64 35 #define LPT_MCWDT_UNIT MCWDT_STRUCT0
AnnaBridge 188:bcfe06ba3d64 36 #define LPT_INTERRUPT_PRIORITY 3
AnnaBridge 188:bcfe06ba3d64 37 #define LPT_INTERRUPT_SOURCE srss_interrupt_mcwdt_0_IRQn
AnnaBridge 188:bcfe06ba3d64 38 #else
AnnaBridge 188:bcfe06ba3d64 39 #define LPT_MCWDT_UNIT MCWDT_STRUCT1
AnnaBridge 188:bcfe06ba3d64 40 #define LPT_INTERRUPT_PRIORITY 6
AnnaBridge 188:bcfe06ba3d64 41 #define LPT_INTERRUPT_SOURCE srss_interrupt_mcwdt_1_IRQn
AnnaBridge 188:bcfe06ba3d64 42 #endif
AnnaBridge 188:bcfe06ba3d64 43 #define LPT_MCWDT_DELAY_WAIT 0 // Recommended value is 93, but then we fail function execution time test.
AnnaBridge 188:bcfe06ba3d64 44
AnnaBridge 189:f392fc9709a3 45 #if !defined (CY_CFG_SYSCLK_CLKLF_FREQ_HZ)
AnnaBridge 189:f392fc9709a3 46 #define CY_CFG_SYSCLK_CLKLF_FREQ_HZ 32768UL /* Default to 32K ILO */
AnnaBridge 189:f392fc9709a3 47 #endif /* CY_CFG_SYSCLK_CLKLF_FREQ_HZ */
AnnaBridge 189:f392fc9709a3 48
AnnaBridge 188:bcfe06ba3d64 49 static const ticker_info_t lp_ticker_info = {
AnnaBridge 189:f392fc9709a3 50 .frequency = CY_CFG_SYSCLK_CLKLF_FREQ_HZ,
AnnaBridge 189:f392fc9709a3 51 .bits = 16UL,
AnnaBridge 188:bcfe06ba3d64 52 };
AnnaBridge 188:bcfe06ba3d64 53
AnnaBridge 188:bcfe06ba3d64 54 static bool lpt_init_done = false;
AnnaBridge 188:bcfe06ba3d64 55 // Timer h/w configuration.
AnnaBridge 188:bcfe06ba3d64 56 static cy_stc_mcwdt_config_t config = {
AnnaBridge 188:bcfe06ba3d64 57 .c0Match = 0,
AnnaBridge 188:bcfe06ba3d64 58 .c1Match = 0,
AnnaBridge 188:bcfe06ba3d64 59 .c0Mode = CY_MCWDT_MODE_INT,
AnnaBridge 188:bcfe06ba3d64 60 .c1Mode = CY_MCWDT_MODE_NONE,
AnnaBridge 188:bcfe06ba3d64 61 .c2ToggleBit = 0,
AnnaBridge 188:bcfe06ba3d64 62 .c2Mode = CY_MCWDT_MODE_NONE,
AnnaBridge 188:bcfe06ba3d64 63 .c0ClearOnMatch = false,
AnnaBridge 188:bcfe06ba3d64 64 .c1ClearOnMatch = false,
AnnaBridge 188:bcfe06ba3d64 65 .c0c1Cascade = false,
AnnaBridge 188:bcfe06ba3d64 66 .c1c2Cascade = false
AnnaBridge 188:bcfe06ba3d64 67 };
AnnaBridge 188:bcfe06ba3d64 68
AnnaBridge 188:bcfe06ba3d64 69 // Interrupt configuration.
AnnaBridge 188:bcfe06ba3d64 70 static cy_stc_sysint_t lpt_sysint_config = {
AnnaBridge 188:bcfe06ba3d64 71 #if defined(TARGET_MCU_PSOC6_M0)
AnnaBridge 188:bcfe06ba3d64 72 .intrSrc = (IRQn_Type)(-1),
AnnaBridge 188:bcfe06ba3d64 73 .cm0pSrc = LPT_INTERRUPT_SOURCE,
AnnaBridge 188:bcfe06ba3d64 74 #else
AnnaBridge 188:bcfe06ba3d64 75 .intrSrc = LPT_INTERRUPT_SOURCE,
AnnaBridge 188:bcfe06ba3d64 76 #endif
AnnaBridge 188:bcfe06ba3d64 77 .intrPriority = LPT_INTERRUPT_PRIORITY
AnnaBridge 188:bcfe06ba3d64 78 };
AnnaBridge 188:bcfe06ba3d64 79
AnnaBridge 188:bcfe06ba3d64 80
AnnaBridge 188:bcfe06ba3d64 81 void lp_ticker_init(void)
AnnaBridge 188:bcfe06ba3d64 82 {
AnnaBridge 188:bcfe06ba3d64 83 lp_ticker_disable_interrupt();
AnnaBridge 188:bcfe06ba3d64 84 lp_ticker_clear_interrupt();
AnnaBridge 188:bcfe06ba3d64 85
AnnaBridge 188:bcfe06ba3d64 86 if (lpt_init_done) {
AnnaBridge 188:bcfe06ba3d64 87 return;
AnnaBridge 188:bcfe06ba3d64 88 }
AnnaBridge 188:bcfe06ba3d64 89
AnnaBridge 188:bcfe06ba3d64 90 #ifdef TARGET_MCU_PSOC6_M0
AnnaBridge 188:bcfe06ba3d64 91 // Allocate NVIC channel.
AnnaBridge 188:bcfe06ba3d64 92 lpt_sysint_config.intrSrc = cy_m0_nvic_allocate_channel(CY_LP_TICKER_IRQN_ID);
AnnaBridge 188:bcfe06ba3d64 93 if (lpt_sysint_config.intrSrc == (IRQn_Type)(-1)) {
AnnaBridge 188:bcfe06ba3d64 94 // No free NVIC channel.
AnnaBridge 188:bcfe06ba3d64 95 error("LP_TICKER NVIC channel allocation failed.");
AnnaBridge 188:bcfe06ba3d64 96 return;
AnnaBridge 188:bcfe06ba3d64 97 }
AnnaBridge 188:bcfe06ba3d64 98 #endif
AnnaBridge 188:bcfe06ba3d64 99
AnnaBridge 188:bcfe06ba3d64 100 Cy_MCWDT_Init(LPT_MCWDT_UNIT, &config);
AnnaBridge 188:bcfe06ba3d64 101 Cy_SysInt_Init(&lpt_sysint_config, lp_ticker_irq_handler);
AnnaBridge 188:bcfe06ba3d64 102 NVIC_EnableIRQ(lpt_sysint_config.intrSrc);
AnnaBridge 188:bcfe06ba3d64 103 Cy_MCWDT_Enable(LPT_MCWDT_UNIT, CY_MCWDT_CTR0, LPT_MCWDT_DELAY_WAIT);
AnnaBridge 188:bcfe06ba3d64 104 lpt_init_done = true;
AnnaBridge 188:bcfe06ba3d64 105 }
AnnaBridge 188:bcfe06ba3d64 106
AnnaBridge 188:bcfe06ba3d64 107 void lp_ticker_free(void)
AnnaBridge 188:bcfe06ba3d64 108 {
AnnaBridge 188:bcfe06ba3d64 109 NVIC_DisableIRQ(lpt_sysint_config.intrSrc);
AnnaBridge 188:bcfe06ba3d64 110 Cy_MCWDT_Disable(LPT_MCWDT_UNIT, CY_MCWDT_CTR0, LPT_MCWDT_DELAY_WAIT);
AnnaBridge 188:bcfe06ba3d64 111 #ifdef TARGET_MCU_PSOC6_M0
AnnaBridge 188:bcfe06ba3d64 112 cy_m0_nvic_release_channel(CY_LP_TICKER_IRQN_ID, lpt_sysint_config.intrSrc);
AnnaBridge 188:bcfe06ba3d64 113 lpt_sysint_config.intrSrc = (IRQn_Type)(-1);
AnnaBridge 188:bcfe06ba3d64 114 #endif
AnnaBridge 188:bcfe06ba3d64 115 lpt_init_done = 0;
AnnaBridge 188:bcfe06ba3d64 116 }
AnnaBridge 188:bcfe06ba3d64 117
AnnaBridge 188:bcfe06ba3d64 118 uint32_t lp_ticker_read(void)
AnnaBridge 188:bcfe06ba3d64 119 {
AnnaBridge 188:bcfe06ba3d64 120 return Cy_MCWDT_GetCount(LPT_MCWDT_UNIT, CY_MCWDT_COUNTER0);
AnnaBridge 188:bcfe06ba3d64 121 }
AnnaBridge 188:bcfe06ba3d64 122
AnnaBridge 188:bcfe06ba3d64 123 void lp_ticker_set_interrupt(timestamp_t timestamp)
AnnaBridge 188:bcfe06ba3d64 124 {
AnnaBridge 188:bcfe06ba3d64 125 uint16_t delay;
AnnaBridge 188:bcfe06ba3d64 126 uint16_t current = Cy_MCWDT_GetCount(LPT_MCWDT_UNIT, CY_MCWDT_COUNTER0);
AnnaBridge 188:bcfe06ba3d64 127 uint16_t new_ts = (uint16_t)timestamp;
AnnaBridge 188:bcfe06ba3d64 128 delay = new_ts - current;
AnnaBridge 188:bcfe06ba3d64 129 // Make sure the event is set for the future. Mbed internally will not schedule
AnnaBridge 188:bcfe06ba3d64 130 // delays longer than 0x7000, so too large delay means it should occur already.
AnnaBridge 188:bcfe06ba3d64 131 // MCWDT has internal delay of about 1.5 LF clock ticks, so this is the minimum
AnnaBridge 188:bcfe06ba3d64 132 // that we can schedule.
AnnaBridge 188:bcfe06ba3d64 133 if ((delay < 3) || (delay > (uint16_t)(-3))) {
AnnaBridge 188:bcfe06ba3d64 134 // Cheating a bit here.
AnnaBridge 188:bcfe06ba3d64 135 new_ts = current + 3;
AnnaBridge 188:bcfe06ba3d64 136 }
AnnaBridge 188:bcfe06ba3d64 137
AnnaBridge 188:bcfe06ba3d64 138 // Cypress PDL manual says that valid match range is 1..65535.
AnnaBridge 188:bcfe06ba3d64 139 if (new_ts == 0) {
AnnaBridge 188:bcfe06ba3d64 140 new_ts = 1;
AnnaBridge 188:bcfe06ba3d64 141 }
AnnaBridge 188:bcfe06ba3d64 142
AnnaBridge 188:bcfe06ba3d64 143 // Set up and enable match interrupt.
AnnaBridge 188:bcfe06ba3d64 144 Cy_MCWDT_SetMatch(LPT_MCWDT_UNIT, CY_MCWDT_COUNTER0, new_ts, LPT_MCWDT_DELAY_WAIT);
AnnaBridge 188:bcfe06ba3d64 145 Cy_MCWDT_SetInterruptMask(LPT_MCWDT_UNIT, CY_MCWDT_CTR0);
AnnaBridge 188:bcfe06ba3d64 146 }
AnnaBridge 188:bcfe06ba3d64 147
AnnaBridge 188:bcfe06ba3d64 148 void lp_ticker_disable_interrupt(void)
AnnaBridge 188:bcfe06ba3d64 149 {
AnnaBridge 188:bcfe06ba3d64 150 Cy_MCWDT_SetInterruptMask(LPT_MCWDT_UNIT, 0);
AnnaBridge 188:bcfe06ba3d64 151 }
AnnaBridge 188:bcfe06ba3d64 152
AnnaBridge 188:bcfe06ba3d64 153 void lp_ticker_clear_interrupt(void)
AnnaBridge 188:bcfe06ba3d64 154 {
AnnaBridge 188:bcfe06ba3d64 155 Cy_MCWDT_ClearInterrupt(LPT_MCWDT_UNIT, CY_MCWDT_CTR0);
AnnaBridge 188:bcfe06ba3d64 156 }
AnnaBridge 188:bcfe06ba3d64 157
AnnaBridge 188:bcfe06ba3d64 158 void lp_ticker_fire_interrupt(void)
AnnaBridge 188:bcfe06ba3d64 159 {
AnnaBridge 188:bcfe06ba3d64 160 NVIC_SetPendingIRQ(lpt_sysint_config.intrSrc);
AnnaBridge 188:bcfe06ba3d64 161 }
AnnaBridge 188:bcfe06ba3d64 162
AnnaBridge 189:f392fc9709a3 163 const ticker_info_t *lp_ticker_get_info(void)
AnnaBridge 188:bcfe06ba3d64 164 {
AnnaBridge 188:bcfe06ba3d64 165 return &lp_ticker_info;
AnnaBridge 188:bcfe06ba3d64 166 }
AnnaBridge 188:bcfe06ba3d64 167
AnnaBridge 188:bcfe06ba3d64 168 #endif // DEVICE_LPTICKER