Initial commit

Dependencies:   FastPWM

Committer:
lypinator
Date:
Wed Sep 16 01:11:49 2020 +0000
Revision:
0:bb348c97df44
Added PWM

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lypinator 0:bb348c97df44 1 /* mbed Microcontroller Library
lypinator 0:bb348c97df44 2 *******************************************************************************
lypinator 0:bb348c97df44 3 * Copyright (c) 2018, STMicroelectronics
lypinator 0:bb348c97df44 4 * All rights reserved.
lypinator 0:bb348c97df44 5 *
lypinator 0:bb348c97df44 6 * Redistribution and use in source and binary forms, with or without
lypinator 0:bb348c97df44 7 * modification, are permitted provided that the following conditions are met:
lypinator 0:bb348c97df44 8 *
lypinator 0:bb348c97df44 9 * 1. Redistributions of source code must retain the above copyright notice,
lypinator 0:bb348c97df44 10 * this list of conditions and the following disclaimer.
lypinator 0:bb348c97df44 11 * 2. Redistributions in binary form must reproduce the above copyright notice,
lypinator 0:bb348c97df44 12 * this list of conditions and the following disclaimer in the documentation
lypinator 0:bb348c97df44 13 * and/or other materials provided with the distribution.
lypinator 0:bb348c97df44 14 * 3. Neither the name of STMicroelectronics nor the names of its contributors
lypinator 0:bb348c97df44 15 * may be used to endorse or promote products derived from this software
lypinator 0:bb348c97df44 16 * without specific prior written permission.
lypinator 0:bb348c97df44 17 *
lypinator 0:bb348c97df44 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
lypinator 0:bb348c97df44 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
lypinator 0:bb348c97df44 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
lypinator 0:bb348c97df44 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
lypinator 0:bb348c97df44 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
lypinator 0:bb348c97df44 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
lypinator 0:bb348c97df44 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
lypinator 0:bb348c97df44 25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
lypinator 0:bb348c97df44 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
lypinator 0:bb348c97df44 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
lypinator 0:bb348c97df44 28 *******************************************************************************
lypinator 0:bb348c97df44 29 */
lypinator 0:bb348c97df44 30
lypinator 0:bb348c97df44 31 #if DEVICE_LPTICKER
lypinator 0:bb348c97df44 32
lypinator 0:bb348c97df44 33 /***********************************************************************/
lypinator 0:bb348c97df44 34 /* lpticker_lptim config is 1 in json config file */
lypinator 0:bb348c97df44 35 /* LPTICKER is based on LPTIM feature from ST drivers. RTC is not used */
lypinator 0:bb348c97df44 36 #if MBED_CONF_TARGET_LPTICKER_LPTIM
lypinator 0:bb348c97df44 37
lypinator 0:bb348c97df44 38 #include "lp_ticker_api.h"
lypinator 0:bb348c97df44 39 #include "mbed_error.h"
lypinator 0:bb348c97df44 40
lypinator 0:bb348c97df44 41 LPTIM_HandleTypeDef LptimHandle;
lypinator 0:bb348c97df44 42
lypinator 0:bb348c97df44 43 const ticker_info_t *lp_ticker_get_info()
lypinator 0:bb348c97df44 44 {
lypinator 0:bb348c97df44 45 static const ticker_info_t info = {
lypinator 0:bb348c97df44 46 #if MBED_CONF_TARGET_LSE_AVAILABLE
lypinator 0:bb348c97df44 47 LSE_VALUE,
lypinator 0:bb348c97df44 48 #else
lypinator 0:bb348c97df44 49 LSI_VALUE,
lypinator 0:bb348c97df44 50 #endif
lypinator 0:bb348c97df44 51 16
lypinator 0:bb348c97df44 52 };
lypinator 0:bb348c97df44 53 return &info;
lypinator 0:bb348c97df44 54 }
lypinator 0:bb348c97df44 55
lypinator 0:bb348c97df44 56 volatile uint8_t lp_Fired = 0;
lypinator 0:bb348c97df44 57
lypinator 0:bb348c97df44 58 static void LPTIM1_IRQHandler(void);
lypinator 0:bb348c97df44 59 static void (*irq_handler)(void);
lypinator 0:bb348c97df44 60
lypinator 0:bb348c97df44 61 void lp_ticker_init(void)
lypinator 0:bb348c97df44 62 {
lypinator 0:bb348c97df44 63 /* Check if LPTIM is already configured */
lypinator 0:bb348c97df44 64 if (__HAL_RCC_LPTIM1_IS_CLK_ENABLED()) {
lypinator 0:bb348c97df44 65 lp_ticker_disable_interrupt();
lypinator 0:bb348c97df44 66 return;
lypinator 0:bb348c97df44 67 }
lypinator 0:bb348c97df44 68
lypinator 0:bb348c97df44 69 RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct = {0};
lypinator 0:bb348c97df44 70 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
lypinator 0:bb348c97df44 71
lypinator 0:bb348c97df44 72 #if MBED_CONF_TARGET_LSE_AVAILABLE
lypinator 0:bb348c97df44 73
lypinator 0:bb348c97df44 74 /* Enable LSE clock */
lypinator 0:bb348c97df44 75 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
lypinator 0:bb348c97df44 76 RCC_OscInitStruct.LSEState = RCC_LSE_ON;
lypinator 0:bb348c97df44 77 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
lypinator 0:bb348c97df44 78
lypinator 0:bb348c97df44 79 /* Select the LSE clock as LPTIM peripheral clock */
lypinator 0:bb348c97df44 80 RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1;
lypinator 0:bb348c97df44 81 #if (TARGET_STM32L0)
lypinator 0:bb348c97df44 82 RCC_PeriphCLKInitStruct.LptimClockSelection = RCC_LPTIM1CLKSOURCE_LSE;
lypinator 0:bb348c97df44 83 #else
lypinator 0:bb348c97df44 84 RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSE;
lypinator 0:bb348c97df44 85 #endif
lypinator 0:bb348c97df44 86
lypinator 0:bb348c97df44 87 #else /* MBED_CONF_TARGET_LSE_AVAILABLE */
lypinator 0:bb348c97df44 88
lypinator 0:bb348c97df44 89 /* Enable LSI clock */
lypinator 0:bb348c97df44 90 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
lypinator 0:bb348c97df44 91 RCC_OscInitStruct.LSIState = RCC_LSI_ON;
lypinator 0:bb348c97df44 92 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
lypinator 0:bb348c97df44 93
lypinator 0:bb348c97df44 94 /* Select the LSI clock as LPTIM peripheral clock */
lypinator 0:bb348c97df44 95 RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1;
lypinator 0:bb348c97df44 96 #if (TARGET_STM32L0)
lypinator 0:bb348c97df44 97 RCC_PeriphCLKInitStruct.LptimClockSelection = RCC_LPTIM1CLKSOURCE_LSI;
lypinator 0:bb348c97df44 98 #else
lypinator 0:bb348c97df44 99 RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSI;
lypinator 0:bb348c97df44 100 #endif
lypinator 0:bb348c97df44 101
lypinator 0:bb348c97df44 102 #endif /* MBED_CONF_TARGET_LSE_AVAILABLE */
lypinator 0:bb348c97df44 103
lypinator 0:bb348c97df44 104 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
lypinator 0:bb348c97df44 105 error("HAL_RCC_OscConfig ERROR\n");
lypinator 0:bb348c97df44 106 return;
lypinator 0:bb348c97df44 107 }
lypinator 0:bb348c97df44 108
lypinator 0:bb348c97df44 109 if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct) != HAL_OK) {
lypinator 0:bb348c97df44 110 error("HAL_RCCEx_PeriphCLKConfig ERROR\n");
lypinator 0:bb348c97df44 111 return;
lypinator 0:bb348c97df44 112 }
lypinator 0:bb348c97df44 113
lypinator 0:bb348c97df44 114 __HAL_RCC_LPTIM1_CLK_ENABLE();
lypinator 0:bb348c97df44 115 __HAL_RCC_LPTIM1_FORCE_RESET();
lypinator 0:bb348c97df44 116 __HAL_RCC_LPTIM1_RELEASE_RESET();
lypinator 0:bb348c97df44 117
lypinator 0:bb348c97df44 118 /* Initialize the LPTIM peripheral */
lypinator 0:bb348c97df44 119 LptimHandle.Instance = LPTIM1;
lypinator 0:bb348c97df44 120 LptimHandle.State = HAL_LPTIM_STATE_RESET;
lypinator 0:bb348c97df44 121 LptimHandle.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
lypinator 0:bb348c97df44 122 LptimHandle.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
lypinator 0:bb348c97df44 123
lypinator 0:bb348c97df44 124 LptimHandle.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
lypinator 0:bb348c97df44 125 LptimHandle.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
lypinator 0:bb348c97df44 126 LptimHandle.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
lypinator 0:bb348c97df44 127 LptimHandle.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
lypinator 0:bb348c97df44 128 #if (TARGET_STM32L4)
lypinator 0:bb348c97df44 129 LptimHandle.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
lypinator 0:bb348c97df44 130 LptimHandle.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
lypinator 0:bb348c97df44 131 #endif /* TARGET_STM32L4 */
lypinator 0:bb348c97df44 132
lypinator 0:bb348c97df44 133 if (HAL_LPTIM_Init(&LptimHandle) != HAL_OK) {
lypinator 0:bb348c97df44 134 error("HAL_LPTIM_Init ERROR\n");
lypinator 0:bb348c97df44 135 return;
lypinator 0:bb348c97df44 136 }
lypinator 0:bb348c97df44 137
lypinator 0:bb348c97df44 138 NVIC_SetVector(LPTIM1_IRQn, (uint32_t)LPTIM1_IRQHandler);
lypinator 0:bb348c97df44 139
lypinator 0:bb348c97df44 140 #if !(TARGET_STM32L4)
lypinator 0:bb348c97df44 141 /* EXTI lines are not configured by default */
lypinator 0:bb348c97df44 142 __HAL_LPTIM_WAKEUPTIMER_EXTI_ENABLE_IT();
lypinator 0:bb348c97df44 143 __HAL_LPTIM_WAKEUPTIMER_EXTI_ENABLE_RISING_EDGE();
lypinator 0:bb348c97df44 144 #endif
lypinator 0:bb348c97df44 145
lypinator 0:bb348c97df44 146 __HAL_LPTIM_ENABLE_IT(&LptimHandle, LPTIM_IT_CMPM);
lypinator 0:bb348c97df44 147 HAL_LPTIM_Counter_Start(&LptimHandle, 0xFFFF);
lypinator 0:bb348c97df44 148
lypinator 0:bb348c97df44 149 /* Need to write a compare value in order to get LPTIM_FLAG_CMPOK in set_interrupt */
lypinator 0:bb348c97df44 150 __HAL_LPTIM_COMPARE_SET(&LptimHandle, 0);
lypinator 0:bb348c97df44 151 }
lypinator 0:bb348c97df44 152
lypinator 0:bb348c97df44 153 static void LPTIM1_IRQHandler(void)
lypinator 0:bb348c97df44 154 {
lypinator 0:bb348c97df44 155 LptimHandle.Instance = LPTIM1;
lypinator 0:bb348c97df44 156
lypinator 0:bb348c97df44 157 if (lp_Fired) {
lypinator 0:bb348c97df44 158 lp_Fired = 0;
lypinator 0:bb348c97df44 159 if (irq_handler) {
lypinator 0:bb348c97df44 160 irq_handler();
lypinator 0:bb348c97df44 161 }
lypinator 0:bb348c97df44 162 }
lypinator 0:bb348c97df44 163
lypinator 0:bb348c97df44 164 /* Compare match interrupt */
lypinator 0:bb348c97df44 165 if (__HAL_LPTIM_GET_FLAG(&LptimHandle, LPTIM_FLAG_CMPM) != RESET) {
lypinator 0:bb348c97df44 166 if (__HAL_LPTIM_GET_IT_SOURCE(&LptimHandle, LPTIM_IT_CMPM) != RESET) {
lypinator 0:bb348c97df44 167 /* Clear Compare match flag */
lypinator 0:bb348c97df44 168 __HAL_LPTIM_CLEAR_FLAG(&LptimHandle, LPTIM_FLAG_CMPM);
lypinator 0:bb348c97df44 169
lypinator 0:bb348c97df44 170 if (irq_handler) {
lypinator 0:bb348c97df44 171 irq_handler();
lypinator 0:bb348c97df44 172 }
lypinator 0:bb348c97df44 173 }
lypinator 0:bb348c97df44 174 }
lypinator 0:bb348c97df44 175
lypinator 0:bb348c97df44 176 #if !(TARGET_STM32L4)
lypinator 0:bb348c97df44 177 __HAL_LPTIM_WAKEUPTIMER_EXTI_CLEAR_FLAG();
lypinator 0:bb348c97df44 178 #endif
lypinator 0:bb348c97df44 179 }
lypinator 0:bb348c97df44 180
lypinator 0:bb348c97df44 181 uint32_t lp_ticker_read(void)
lypinator 0:bb348c97df44 182 {
lypinator 0:bb348c97df44 183 uint32_t lp_time = LPTIM1->CNT;
lypinator 0:bb348c97df44 184 /* Reading the LPTIM_CNT register may return unreliable values.
lypinator 0:bb348c97df44 185 It is necessary to perform two consecutive read accesses and verify that the two returned values are identical */
lypinator 0:bb348c97df44 186 while (lp_time != LPTIM1->CNT) {
lypinator 0:bb348c97df44 187 lp_time = LPTIM1->CNT;
lypinator 0:bb348c97df44 188 }
lypinator 0:bb348c97df44 189 return lp_time;
lypinator 0:bb348c97df44 190 }
lypinator 0:bb348c97df44 191
lypinator 0:bb348c97df44 192 void lp_ticker_set_interrupt(timestamp_t timestamp)
lypinator 0:bb348c97df44 193 {
lypinator 0:bb348c97df44 194 LptimHandle.Instance = LPTIM1;
lypinator 0:bb348c97df44 195 irq_handler = (void (*)(void))lp_ticker_irq_handler;
lypinator 0:bb348c97df44 196
lypinator 0:bb348c97df44 197 /* CMPOK is set by hardware to inform application that the APB bus write operation to the LPTIM_CMP register has been successfully completed */
lypinator 0:bb348c97df44 198 /* Any successive write before the CMPOK flag be set, will lead to unpredictable results */
lypinator 0:bb348c97df44 199 while (__HAL_LPTIM_GET_FLAG(&LptimHandle, LPTIM_FLAG_CMPOK) == RESET) {
lypinator 0:bb348c97df44 200 }
lypinator 0:bb348c97df44 201
lypinator 0:bb348c97df44 202 __HAL_LPTIM_CLEAR_FLAG(&LptimHandle, LPTIM_FLAG_CMPOK);
lypinator 0:bb348c97df44 203 __HAL_LPTIM_CLEAR_FLAG(&LptimHandle, LPTIM_FLAG_CMPM);
lypinator 0:bb348c97df44 204 __HAL_LPTIM_COMPARE_SET(&LptimHandle, timestamp);
lypinator 0:bb348c97df44 205
lypinator 0:bb348c97df44 206 NVIC_EnableIRQ(LPTIM1_IRQn);
lypinator 0:bb348c97df44 207 }
lypinator 0:bb348c97df44 208
lypinator 0:bb348c97df44 209 void lp_ticker_fire_interrupt(void)
lypinator 0:bb348c97df44 210 {
lypinator 0:bb348c97df44 211 lp_Fired = 1;
lypinator 0:bb348c97df44 212 NVIC_SetPendingIRQ(LPTIM1_IRQn);
lypinator 0:bb348c97df44 213 NVIC_EnableIRQ(LPTIM1_IRQn);
lypinator 0:bb348c97df44 214 }
lypinator 0:bb348c97df44 215
lypinator 0:bb348c97df44 216 void lp_ticker_disable_interrupt(void)
lypinator 0:bb348c97df44 217 {
lypinator 0:bb348c97df44 218 NVIC_DisableIRQ(LPTIM1_IRQn);
lypinator 0:bb348c97df44 219 LptimHandle.Instance = LPTIM1;
lypinator 0:bb348c97df44 220 /* Waiting last write operation completion */
lypinator 0:bb348c97df44 221 while (__HAL_LPTIM_GET_FLAG(&LptimHandle, LPTIM_FLAG_CMPOK) == RESET) {
lypinator 0:bb348c97df44 222 }
lypinator 0:bb348c97df44 223 }
lypinator 0:bb348c97df44 224
lypinator 0:bb348c97df44 225 void lp_ticker_clear_interrupt(void)
lypinator 0:bb348c97df44 226 {
lypinator 0:bb348c97df44 227 LptimHandle.Instance = LPTIM1;
lypinator 0:bb348c97df44 228 __HAL_LPTIM_CLEAR_FLAG(&LptimHandle, LPTIM_FLAG_CMPM);
lypinator 0:bb348c97df44 229 NVIC_ClearPendingIRQ(LPTIM1_IRQn);
lypinator 0:bb348c97df44 230 }
lypinator 0:bb348c97df44 231
lypinator 0:bb348c97df44 232
lypinator 0:bb348c97df44 233
lypinator 0:bb348c97df44 234 /*****************************************************************/
lypinator 0:bb348c97df44 235 /* lpticker_lptim config is 0 or not defined in json config file */
lypinator 0:bb348c97df44 236 /* LPTICKER is based on RTC wake up feature from ST drivers */
lypinator 0:bb348c97df44 237 #else /* MBED_CONF_TARGET_LPTICKER_LPTIM */
lypinator 0:bb348c97df44 238
lypinator 0:bb348c97df44 239 #include "rtc_api_hal.h"
lypinator 0:bb348c97df44 240
lypinator 0:bb348c97df44 241 const ticker_info_t *lp_ticker_get_info()
lypinator 0:bb348c97df44 242 {
lypinator 0:bb348c97df44 243 static const ticker_info_t info = {
lypinator 0:bb348c97df44 244 RTC_CLOCK / 4, // RTC_WAKEUPCLOCK_RTCCLK_DIV4
lypinator 0:bb348c97df44 245 32
lypinator 0:bb348c97df44 246 };
lypinator 0:bb348c97df44 247 return &info;
lypinator 0:bb348c97df44 248 }
lypinator 0:bb348c97df44 249
lypinator 0:bb348c97df44 250 void lp_ticker_init(void)
lypinator 0:bb348c97df44 251 {
lypinator 0:bb348c97df44 252 rtc_init();
lypinator 0:bb348c97df44 253 lp_ticker_disable_interrupt();
lypinator 0:bb348c97df44 254 }
lypinator 0:bb348c97df44 255
lypinator 0:bb348c97df44 256 uint32_t lp_ticker_read(void)
lypinator 0:bb348c97df44 257 {
lypinator 0:bb348c97df44 258 return rtc_read_lp();
lypinator 0:bb348c97df44 259 }
lypinator 0:bb348c97df44 260
lypinator 0:bb348c97df44 261 void lp_ticker_set_interrupt(timestamp_t timestamp)
lypinator 0:bb348c97df44 262 {
lypinator 0:bb348c97df44 263 lp_ticker_disable_interrupt();
lypinator 0:bb348c97df44 264 rtc_set_wake_up_timer(timestamp);
lypinator 0:bb348c97df44 265 }
lypinator 0:bb348c97df44 266
lypinator 0:bb348c97df44 267 void lp_ticker_fire_interrupt(void)
lypinator 0:bb348c97df44 268 {
lypinator 0:bb348c97df44 269 rtc_fire_interrupt();
lypinator 0:bb348c97df44 270 }
lypinator 0:bb348c97df44 271
lypinator 0:bb348c97df44 272 void lp_ticker_disable_interrupt(void)
lypinator 0:bb348c97df44 273 {
lypinator 0:bb348c97df44 274 rtc_deactivate_wake_up_timer();
lypinator 0:bb348c97df44 275 }
lypinator 0:bb348c97df44 276
lypinator 0:bb348c97df44 277 void lp_ticker_clear_interrupt(void)
lypinator 0:bb348c97df44 278 {
lypinator 0:bb348c97df44 279 NVIC_DisableIRQ(RTC_WKUP_IRQn);
lypinator 0:bb348c97df44 280 }
lypinator 0:bb348c97df44 281
lypinator 0:bb348c97df44 282 #endif /* MBED_CONF_TARGET_LPTICKER_LPTIM */
lypinator 0:bb348c97df44 283
lypinator 0:bb348c97df44 284 #endif /* DEVICE_LPTICKER */