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
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 189:f392fc9709a3 1 /*
AnnaBridge 189:f392fc9709a3 2 * mbed Microcontroller Library
AnnaBridge 189:f392fc9709a3 3 * Copyright (c) 2017-2018 Future Electronics
AnnaBridge 189:f392fc9709a3 4 *
AnnaBridge 189:f392fc9709a3 5 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 189:f392fc9709a3 6 * you may not use this file except in compliance with the License.
AnnaBridge 189:f392fc9709a3 7 * You may obtain a copy of the License at
AnnaBridge 189:f392fc9709a3 8 *
AnnaBridge 189:f392fc9709a3 9 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 189:f392fc9709a3 10 *
AnnaBridge 189:f392fc9709a3 11 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 189:f392fc9709a3 12 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 189:f392fc9709a3 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 189:f392fc9709a3 14 * See the License for the specific language governing permissions and
AnnaBridge 189:f392fc9709a3 15 * limitations under the License.
AnnaBridge 189:f392fc9709a3 16 */
AnnaBridge 189:f392fc9709a3 17
AnnaBridge 189:f392fc9709a3 18 #include <stddef.h>
AnnaBridge 189:f392fc9709a3 19 #include "device.h"
AnnaBridge 189:f392fc9709a3 20 #include "mbed_error.h"
AnnaBridge 189:f392fc9709a3 21 #include "lp_ticker_api.h"
AnnaBridge 189:f392fc9709a3 22 #include "device/drivers/peripheral/mcwdt/cy_mcwdt.h"
AnnaBridge 189:f392fc9709a3 23 #include "device/drivers/peripheral/sysint/cy_sysint.h"
AnnaBridge 189:f392fc9709a3 24 #include "psoc6_utils.h"
AnnaBridge 189:f392fc9709a3 25
AnnaBridge 189:f392fc9709a3 26 #if DEVICE_LPTICKER
AnnaBridge 189:f392fc9709a3 27
AnnaBridge 189:f392fc9709a3 28 /*
AnnaBridge 189:f392fc9709a3 29 * Low Power Timer API on PSoC6 uses MCWD0 timer0 to implement functionality.
AnnaBridge 189:f392fc9709a3 30 */
AnnaBridge 189:f392fc9709a3 31
AnnaBridge 189:f392fc9709a3 32 #if defined(TARGET_MCU_PSOC6_M0)
AnnaBridge 189:f392fc9709a3 33 #define LPT_MCWDT_UNIT MCWDT_STRUCT0
AnnaBridge 189:f392fc9709a3 34 #define LPT_INTERRUPT_PRIORITY 3
AnnaBridge 189:f392fc9709a3 35 #define LPT_INTERRUPT_SOURCE srss_interrupt_mcwdt_0_IRQn
AnnaBridge 189:f392fc9709a3 36 #else
AnnaBridge 189:f392fc9709a3 37 #define LPT_MCWDT_UNIT MCWDT_STRUCT1
AnnaBridge 189:f392fc9709a3 38 #define LPT_INTERRUPT_PRIORITY 6
AnnaBridge 189:f392fc9709a3 39 #define LPT_INTERRUPT_SOURCE srss_interrupt_mcwdt_1_IRQn
AnnaBridge 189:f392fc9709a3 40 #endif
AnnaBridge 189:f392fc9709a3 41 #define LPT_MCWDT_DELAY_WAIT 0 // Recommended value is 93, but then we fail function execution time test.
AnnaBridge 189:f392fc9709a3 42
AnnaBridge 189:f392fc9709a3 43 static const ticker_info_t lp_ticker_info = {
AnnaBridge 189:f392fc9709a3 44 .frequency = CY_CLK_WCO_FREQ_HZ,
AnnaBridge 189:f392fc9709a3 45 .bits = 16,
AnnaBridge 189:f392fc9709a3 46 };
AnnaBridge 189:f392fc9709a3 47
AnnaBridge 189:f392fc9709a3 48 static bool lpt_init_done = false;
AnnaBridge 189:f392fc9709a3 49 // Timer h/w configuration.
AnnaBridge 189:f392fc9709a3 50 static cy_stc_mcwdt_config_t config = {
AnnaBridge 189:f392fc9709a3 51 .c0Match = 0,
AnnaBridge 189:f392fc9709a3 52 .c1Match = 0,
AnnaBridge 189:f392fc9709a3 53 .c0Mode = CY_MCWDT_MODE_INT,
AnnaBridge 189:f392fc9709a3 54 .c1Mode = CY_MCWDT_MODE_NONE,
AnnaBridge 189:f392fc9709a3 55 .c2ToggleBit = 0,
AnnaBridge 189:f392fc9709a3 56 .c2Mode = CY_MCWDT_MODE_NONE,
AnnaBridge 189:f392fc9709a3 57 .c0ClearOnMatch = false,
AnnaBridge 189:f392fc9709a3 58 .c1ClearOnMatch = false,
AnnaBridge 189:f392fc9709a3 59 .c0c1Cascade = false,
AnnaBridge 189:f392fc9709a3 60 .c1c2Cascade = false
AnnaBridge 189:f392fc9709a3 61 };
AnnaBridge 189:f392fc9709a3 62
AnnaBridge 189:f392fc9709a3 63 // Interrupt configuration.
AnnaBridge 189:f392fc9709a3 64 static cy_stc_sysint_t lpt_sysint_config = {
AnnaBridge 189:f392fc9709a3 65 #if defined(TARGET_MCU_PSOC6_M0)
AnnaBridge 189:f392fc9709a3 66 .intrSrc = (IRQn_Type)(-1),
AnnaBridge 189:f392fc9709a3 67 .cm0pSrc = LPT_INTERRUPT_SOURCE,
AnnaBridge 189:f392fc9709a3 68 #else
AnnaBridge 189:f392fc9709a3 69 .intrSrc = LPT_INTERRUPT_SOURCE,
AnnaBridge 189:f392fc9709a3 70 #endif
AnnaBridge 189:f392fc9709a3 71 .intrPriority = LPT_INTERRUPT_PRIORITY
AnnaBridge 189:f392fc9709a3 72 };
AnnaBridge 189:f392fc9709a3 73
AnnaBridge 189:f392fc9709a3 74
AnnaBridge 189:f392fc9709a3 75 void lp_ticker_init(void)
AnnaBridge 189:f392fc9709a3 76 {
AnnaBridge 189:f392fc9709a3 77 lp_ticker_disable_interrupt();
AnnaBridge 189:f392fc9709a3 78 lp_ticker_clear_interrupt();
AnnaBridge 189:f392fc9709a3 79
AnnaBridge 189:f392fc9709a3 80 if (lpt_init_done) {
AnnaBridge 189:f392fc9709a3 81 return;
AnnaBridge 189:f392fc9709a3 82 }
AnnaBridge 189:f392fc9709a3 83
AnnaBridge 189:f392fc9709a3 84 #ifdef TARGET_MCU_PSOC6_M0
AnnaBridge 189:f392fc9709a3 85 // Allocate NVIC channel.
AnnaBridge 189:f392fc9709a3 86 lpt_sysint_config.intrSrc = cy_m0_nvic_allocate_channel(CY_LP_TICKER_IRQN_ID);
AnnaBridge 189:f392fc9709a3 87 if (lpt_sysint_config.intrSrc == (IRQn_Type)(-1)) {
AnnaBridge 189:f392fc9709a3 88 // No free NVIC channel.
AnnaBridge 189:f392fc9709a3 89 error("LP_TICKER NVIC channel allocation failed.");
AnnaBridge 189:f392fc9709a3 90 return;
AnnaBridge 189:f392fc9709a3 91 }
AnnaBridge 189:f392fc9709a3 92 #endif
AnnaBridge 189:f392fc9709a3 93
AnnaBridge 189:f392fc9709a3 94 Cy_MCWDT_Init(LPT_MCWDT_UNIT, &config);
AnnaBridge 189:f392fc9709a3 95 Cy_SysInt_Init(&lpt_sysint_config, lp_ticker_irq_handler);
AnnaBridge 189:f392fc9709a3 96 NVIC_EnableIRQ(lpt_sysint_config.intrSrc);
AnnaBridge 189:f392fc9709a3 97 Cy_MCWDT_Enable(LPT_MCWDT_UNIT, CY_MCWDT_CTR0, LPT_MCWDT_DELAY_WAIT);
AnnaBridge 189:f392fc9709a3 98 lpt_init_done = true;
AnnaBridge 189:f392fc9709a3 99 }
AnnaBridge 189:f392fc9709a3 100
AnnaBridge 189:f392fc9709a3 101 void lp_ticker_free(void)
AnnaBridge 189:f392fc9709a3 102 {
AnnaBridge 189:f392fc9709a3 103 NVIC_DisableIRQ(lpt_sysint_config.intrSrc);
AnnaBridge 189:f392fc9709a3 104 Cy_MCWDT_Disable(LPT_MCWDT_UNIT, CY_MCWDT_CTR0, LPT_MCWDT_DELAY_WAIT);
AnnaBridge 189:f392fc9709a3 105 #ifdef TARGET_MCU_PSOC6_M0
AnnaBridge 189:f392fc9709a3 106 cy_m0_nvic_release_channel(CY_LP_TICKER_IRQN_ID, lpt_sysint_config.intrSrc);
AnnaBridge 189:f392fc9709a3 107 lpt_sysint_config.intrSrc = (IRQn_Type)(-1);
AnnaBridge 189:f392fc9709a3 108 #endif
AnnaBridge 189:f392fc9709a3 109 lpt_init_done = 0;
AnnaBridge 189:f392fc9709a3 110 }
AnnaBridge 189:f392fc9709a3 111
AnnaBridge 189:f392fc9709a3 112 uint32_t lp_ticker_read(void)
AnnaBridge 189:f392fc9709a3 113 {
AnnaBridge 189:f392fc9709a3 114 return Cy_MCWDT_GetCount(LPT_MCWDT_UNIT, CY_MCWDT_COUNTER0);
AnnaBridge 189:f392fc9709a3 115 }
AnnaBridge 189:f392fc9709a3 116
AnnaBridge 189:f392fc9709a3 117 void lp_ticker_set_interrupt(timestamp_t timestamp)
AnnaBridge 189:f392fc9709a3 118 {
AnnaBridge 189:f392fc9709a3 119 uint16_t delay;
AnnaBridge 189:f392fc9709a3 120 uint16_t current = Cy_MCWDT_GetCount(LPT_MCWDT_UNIT, CY_MCWDT_COUNTER0);
AnnaBridge 189:f392fc9709a3 121 uint16_t new_ts = (uint16_t)timestamp;
AnnaBridge 189:f392fc9709a3 122 delay = new_ts - current;
AnnaBridge 189:f392fc9709a3 123 // Make sure the event is set for the future. Mbed internally will not schedule
AnnaBridge 189:f392fc9709a3 124 // delays longer than 0x7000, so too large delay means it should occur already.
AnnaBridge 189:f392fc9709a3 125 // MCWDT has internal delay of about 1.5 LF clock ticks, so this is the minimum
AnnaBridge 189:f392fc9709a3 126 // that we can schedule.
AnnaBridge 189:f392fc9709a3 127 if ((delay < 3) || (delay > (uint16_t)(-3))) {
AnnaBridge 189:f392fc9709a3 128 // Cheating a bit here.
AnnaBridge 189:f392fc9709a3 129 new_ts = current + 3;
AnnaBridge 189:f392fc9709a3 130 }
AnnaBridge 189:f392fc9709a3 131
AnnaBridge 189:f392fc9709a3 132 // Cypress PDL manual says that valid match range is 1..65535.
AnnaBridge 189:f392fc9709a3 133 if (new_ts == 0) {
AnnaBridge 189:f392fc9709a3 134 new_ts = 1;
AnnaBridge 189:f392fc9709a3 135 }
AnnaBridge 189:f392fc9709a3 136
AnnaBridge 189:f392fc9709a3 137 // Set up and enable match interrupt.
AnnaBridge 189:f392fc9709a3 138 Cy_MCWDT_SetMatch(LPT_MCWDT_UNIT, CY_MCWDT_COUNTER0, new_ts, LPT_MCWDT_DELAY_WAIT);
AnnaBridge 189:f392fc9709a3 139 Cy_MCWDT_SetInterruptMask(LPT_MCWDT_UNIT, CY_MCWDT_CTR0);
AnnaBridge 189:f392fc9709a3 140 }
AnnaBridge 189:f392fc9709a3 141
AnnaBridge 189:f392fc9709a3 142 void lp_ticker_disable_interrupt(void)
AnnaBridge 189:f392fc9709a3 143 {
AnnaBridge 189:f392fc9709a3 144 Cy_MCWDT_SetInterruptMask(LPT_MCWDT_UNIT, 0);
AnnaBridge 189:f392fc9709a3 145 }
AnnaBridge 189:f392fc9709a3 146
AnnaBridge 189:f392fc9709a3 147 void lp_ticker_clear_interrupt(void)
AnnaBridge 189:f392fc9709a3 148 {
AnnaBridge 189:f392fc9709a3 149 Cy_MCWDT_ClearInterrupt(LPT_MCWDT_UNIT, CY_MCWDT_CTR0);
AnnaBridge 189:f392fc9709a3 150 }
AnnaBridge 189:f392fc9709a3 151
AnnaBridge 189:f392fc9709a3 152 void lp_ticker_fire_interrupt(void)
AnnaBridge 189:f392fc9709a3 153 {
AnnaBridge 189:f392fc9709a3 154 NVIC_SetPendingIRQ(lpt_sysint_config.intrSrc);
AnnaBridge 189:f392fc9709a3 155 }
AnnaBridge 189:f392fc9709a3 156
AnnaBridge 189:f392fc9709a3 157 const ticker_info_t* lp_ticker_get_info(void)
AnnaBridge 189:f392fc9709a3 158 {
AnnaBridge 189:f392fc9709a3 159 return &lp_ticker_info;
AnnaBridge 189:f392fc9709a3 160 }
AnnaBridge 189:f392fc9709a3 161
AnnaBridge 189:f392fc9709a3 162 #endif // DEVICE_LPTICKER