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 * Copyright (c) 2006-2018 ARM Limited
lypinator 0:bb348c97df44 3 *
lypinator 0:bb348c97df44 4 * Licensed under the Apache License, Version 2.0 (the "License");
lypinator 0:bb348c97df44 5 * you may not use this file except in compliance with the License.
lypinator 0:bb348c97df44 6 * You may obtain a copy of the License at
lypinator 0:bb348c97df44 7 *
lypinator 0:bb348c97df44 8 * http://www.apache.org/licenses/LICENSE-2.0
lypinator 0:bb348c97df44 9 *
lypinator 0:bb348c97df44 10 * Unless required by applicable law or agreed to in writing, software
lypinator 0:bb348c97df44 11 * distributed under the License is distributed on an "AS IS" BASIS,
lypinator 0:bb348c97df44 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
lypinator 0:bb348c97df44 13 * See the License for the specific language governing permissions and
lypinator 0:bb348c97df44 14 * limitations under the License.
lypinator 0:bb348c97df44 15 */
lypinator 0:bb348c97df44 16 #include <stddef.h>
lypinator 0:bb348c97df44 17 #include "us_ticker_api.h"
lypinator 0:bb348c97df44 18 #include "PeripheralNames.h"
lypinator 0:bb348c97df44 19 #include "us_ticker_data.h"
lypinator 0:bb348c97df44 20
lypinator 0:bb348c97df44 21 TIM_HandleTypeDef TimMasterHandle;
lypinator 0:bb348c97df44 22
lypinator 0:bb348c97df44 23 uint32_t timer_cnt_reg;
lypinator 0:bb348c97df44 24 uint32_t timer_ccr1_reg;
lypinator 0:bb348c97df44 25 uint32_t timer_dier_reg;
lypinator 0:bb348c97df44 26
lypinator 0:bb348c97df44 27 const ticker_info_t *us_ticker_get_info()
lypinator 0:bb348c97df44 28 {
lypinator 0:bb348c97df44 29 static const ticker_info_t info = {
lypinator 0:bb348c97df44 30 1000000,
lypinator 0:bb348c97df44 31 TIM_MST_BIT_WIDTH
lypinator 0:bb348c97df44 32 };
lypinator 0:bb348c97df44 33 return &info;
lypinator 0:bb348c97df44 34 }
lypinator 0:bb348c97df44 35
lypinator 0:bb348c97df44 36 void us_ticker_irq_handler(void);
lypinator 0:bb348c97df44 37
lypinator 0:bb348c97df44 38 // ************************************ 16-bit timer ************************************
lypinator 0:bb348c97df44 39 #if TIM_MST_BIT_WIDTH == 16
lypinator 0:bb348c97df44 40
lypinator 0:bb348c97df44 41 extern uint32_t prev_time;
lypinator 0:bb348c97df44 42 extern uint32_t elapsed_time;
lypinator 0:bb348c97df44 43
lypinator 0:bb348c97df44 44 #if defined(TARGET_STM32F0)
lypinator 0:bb348c97df44 45 void timer_update_irq_handler(void)
lypinator 0:bb348c97df44 46 {
lypinator 0:bb348c97df44 47 #else
lypinator 0:bb348c97df44 48 void timer_irq_handler(void)
lypinator 0:bb348c97df44 49 {
lypinator 0:bb348c97df44 50 #endif
lypinator 0:bb348c97df44 51 TimMasterHandle.Instance = TIM_MST;
lypinator 0:bb348c97df44 52
lypinator 0:bb348c97df44 53 #if defined(TARGET_STM32F0)
lypinator 0:bb348c97df44 54 } // end timer_update_irq_handler function
lypinator 0:bb348c97df44 55
lypinator 0:bb348c97df44 56 void timer_oc_irq_handler(void)
lypinator 0:bb348c97df44 57 {
lypinator 0:bb348c97df44 58 TimMasterHandle.Instance = TIM_MST;
lypinator 0:bb348c97df44 59 #endif
lypinator 0:bb348c97df44 60 if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) {
lypinator 0:bb348c97df44 61 if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_CC1) == SET) {
lypinator 0:bb348c97df44 62 __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1);
lypinator 0:bb348c97df44 63 us_ticker_irq_handler();
lypinator 0:bb348c97df44 64 }
lypinator 0:bb348c97df44 65 }
lypinator 0:bb348c97df44 66 }
lypinator 0:bb348c97df44 67
lypinator 0:bb348c97df44 68 void init_16bit_timer(void)
lypinator 0:bb348c97df44 69 {
lypinator 0:bb348c97df44 70 // Enable timer clock
lypinator 0:bb348c97df44 71 TIM_MST_RCC;
lypinator 0:bb348c97df44 72
lypinator 0:bb348c97df44 73 // Reset timer
lypinator 0:bb348c97df44 74 TIM_MST_RESET_ON;
lypinator 0:bb348c97df44 75 TIM_MST_RESET_OFF;
lypinator 0:bb348c97df44 76
lypinator 0:bb348c97df44 77 // Update the SystemCoreClock variable
lypinator 0:bb348c97df44 78 SystemCoreClockUpdate();
lypinator 0:bb348c97df44 79
lypinator 0:bb348c97df44 80 // Configure time base
lypinator 0:bb348c97df44 81 TimMasterHandle.Instance = TIM_MST;
lypinator 0:bb348c97df44 82 TimMasterHandle.Init.Period = 0xFFFF;
lypinator 0:bb348c97df44 83 TimMasterHandle.Init.Prescaler = (uint32_t)(SystemCoreClock / 1000000) - 1; // 1 us tick
lypinator 0:bb348c97df44 84 TimMasterHandle.Init.ClockDivision = 0;
lypinator 0:bb348c97df44 85 TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
lypinator 0:bb348c97df44 86 #if !defined(TARGET_STM32L0) && !defined(TARGET_STM32L1)
lypinator 0:bb348c97df44 87 TimMasterHandle.Init.RepetitionCounter = 0;
lypinator 0:bb348c97df44 88 #endif
lypinator 0:bb348c97df44 89 #ifdef TIM_AUTORELOAD_PRELOAD_DISABLE
lypinator 0:bb348c97df44 90 TimMasterHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
lypinator 0:bb348c97df44 91 #endif
lypinator 0:bb348c97df44 92 HAL_TIM_Base_Init(&TimMasterHandle);
lypinator 0:bb348c97df44 93
lypinator 0:bb348c97df44 94 // Configure output compare channel 1 for mbed timeout (enabled later when used)
lypinator 0:bb348c97df44 95 HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1);
lypinator 0:bb348c97df44 96
lypinator 0:bb348c97df44 97 // Output compare channel 1 interrupt for mbed timeout
lypinator 0:bb348c97df44 98 #if defined(TARGET_STM32F0)
lypinator 0:bb348c97df44 99 NVIC_SetVector(TIM_MST_UP_IRQ, (uint32_t)timer_update_irq_handler);
lypinator 0:bb348c97df44 100 NVIC_EnableIRQ(TIM_MST_UP_IRQ);
lypinator 0:bb348c97df44 101 NVIC_SetPriority(TIM_MST_UP_IRQ, 0);
lypinator 0:bb348c97df44 102 NVIC_SetVector(TIM_MST_OC_IRQ, (uint32_t)timer_oc_irq_handler);
lypinator 0:bb348c97df44 103 NVIC_EnableIRQ(TIM_MST_OC_IRQ);
lypinator 0:bb348c97df44 104 NVIC_SetPriority(TIM_MST_OC_IRQ, 1);
lypinator 0:bb348c97df44 105 #else
lypinator 0:bb348c97df44 106 NVIC_SetVector(TIM_MST_IRQ, (uint32_t)timer_irq_handler);
lypinator 0:bb348c97df44 107 NVIC_EnableIRQ(TIM_MST_IRQ);
lypinator 0:bb348c97df44 108 #endif
lypinator 0:bb348c97df44 109
lypinator 0:bb348c97df44 110 // Enable timer
lypinator 0:bb348c97df44 111 HAL_TIM_Base_Start(&TimMasterHandle);
lypinator 0:bb348c97df44 112
lypinator 0:bb348c97df44 113 // Freeze timer on stop/breakpoint
lypinator 0:bb348c97df44 114 // Define the FREEZE_TIMER_ON_DEBUG macro in mbed_app.json for example
lypinator 0:bb348c97df44 115 #if !defined(NDEBUG) && defined(FREEZE_TIMER_ON_DEBUG) && defined(TIM_MST_DBGMCU_FREEZE)
lypinator 0:bb348c97df44 116 TIM_MST_DBGMCU_FREEZE;
lypinator 0:bb348c97df44 117 #endif
lypinator 0:bb348c97df44 118
lypinator 0:bb348c97df44 119 __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1);
lypinator 0:bb348c97df44 120
lypinator 0:bb348c97df44 121 // Used by HAL_GetTick()
lypinator 0:bb348c97df44 122 prev_time = 0;
lypinator 0:bb348c97df44 123 elapsed_time = 0;
lypinator 0:bb348c97df44 124 }
lypinator 0:bb348c97df44 125
lypinator 0:bb348c97df44 126 // ************************************ 32-bit timer ************************************
lypinator 0:bb348c97df44 127 #else
lypinator 0:bb348c97df44 128
lypinator 0:bb348c97df44 129 void timer_irq_handler(void)
lypinator 0:bb348c97df44 130 {
lypinator 0:bb348c97df44 131 TimMasterHandle.Instance = TIM_MST;
lypinator 0:bb348c97df44 132 if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) {
lypinator 0:bb348c97df44 133 if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_CC1) == SET) {
lypinator 0:bb348c97df44 134 __HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_CC1);
lypinator 0:bb348c97df44 135 us_ticker_irq_handler();
lypinator 0:bb348c97df44 136 }
lypinator 0:bb348c97df44 137 }
lypinator 0:bb348c97df44 138 }
lypinator 0:bb348c97df44 139
lypinator 0:bb348c97df44 140 void init_32bit_timer(void)
lypinator 0:bb348c97df44 141 {
lypinator 0:bb348c97df44 142 RCC_ClkInitTypeDef RCC_ClkInitStruct;
lypinator 0:bb348c97df44 143 uint32_t PclkFreq;
lypinator 0:bb348c97df44 144
lypinator 0:bb348c97df44 145 // Get clock configuration
lypinator 0:bb348c97df44 146 // Note: PclkFreq contains here the Latency (not used after)
lypinator 0:bb348c97df44 147 HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &PclkFreq);
lypinator 0:bb348c97df44 148
lypinator 0:bb348c97df44 149 // Get timer clock value
lypinator 0:bb348c97df44 150 #if TIM_MST_PCLK == 1
lypinator 0:bb348c97df44 151 PclkFreq = HAL_RCC_GetPCLK1Freq();
lypinator 0:bb348c97df44 152 #else
lypinator 0:bb348c97df44 153 PclkFreq = HAL_RCC_GetPCLK2Freq();
lypinator 0:bb348c97df44 154 #endif
lypinator 0:bb348c97df44 155
lypinator 0:bb348c97df44 156 // Enable timer clock
lypinator 0:bb348c97df44 157 TIM_MST_RCC;
lypinator 0:bb348c97df44 158
lypinator 0:bb348c97df44 159 // Reset timer
lypinator 0:bb348c97df44 160 TIM_MST_RESET_ON;
lypinator 0:bb348c97df44 161 TIM_MST_RESET_OFF;
lypinator 0:bb348c97df44 162
lypinator 0:bb348c97df44 163 // Configure time base
lypinator 0:bb348c97df44 164 TimMasterHandle.Instance = TIM_MST;
lypinator 0:bb348c97df44 165 TimMasterHandle.Init.Period = 0xFFFFFFFF;
lypinator 0:bb348c97df44 166
lypinator 0:bb348c97df44 167 // TIMxCLK = PCLKx when the APB prescaler = 1 else TIMxCLK = 2 * PCLKx
lypinator 0:bb348c97df44 168 #if TIM_MST_PCLK == 1
lypinator 0:bb348c97df44 169 if (RCC_ClkInitStruct.APB1CLKDivider == RCC_HCLK_DIV1) {
lypinator 0:bb348c97df44 170 #else
lypinator 0:bb348c97df44 171 if (RCC_ClkInitStruct.APB2CLKDivider == RCC_HCLK_DIV1) {
lypinator 0:bb348c97df44 172 #endif
lypinator 0:bb348c97df44 173 TimMasterHandle.Init.Prescaler = (uint16_t)((PclkFreq) / 1000000) - 1; // 1 us tick
lypinator 0:bb348c97df44 174 } else {
lypinator 0:bb348c97df44 175 TimMasterHandle.Init.Prescaler = (uint16_t)((PclkFreq * 2) / 1000000) - 1; // 1 us tick
lypinator 0:bb348c97df44 176 }
lypinator 0:bb348c97df44 177
lypinator 0:bb348c97df44 178 TimMasterHandle.Init.ClockDivision = 0;
lypinator 0:bb348c97df44 179 TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
lypinator 0:bb348c97df44 180 #if !TARGET_STM32L1
lypinator 0:bb348c97df44 181 TimMasterHandle.Init.RepetitionCounter = 0;
lypinator 0:bb348c97df44 182 #endif
lypinator 0:bb348c97df44 183 #ifdef TIM_AUTORELOAD_PRELOAD_DISABLE
lypinator 0:bb348c97df44 184 TimMasterHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
lypinator 0:bb348c97df44 185 #endif
lypinator 0:bb348c97df44 186 HAL_TIM_OC_Init(&TimMasterHandle);
lypinator 0:bb348c97df44 187
lypinator 0:bb348c97df44 188 NVIC_SetVector(TIM_MST_IRQ, (uint32_t)timer_irq_handler);
lypinator 0:bb348c97df44 189 NVIC_EnableIRQ(TIM_MST_IRQ);
lypinator 0:bb348c97df44 190
lypinator 0:bb348c97df44 191 // Channel 1 for mbed timeout
lypinator 0:bb348c97df44 192 HAL_TIM_OC_Start(&TimMasterHandle, TIM_CHANNEL_1);
lypinator 0:bb348c97df44 193
lypinator 0:bb348c97df44 194 // Freeze timer on stop/breakpoint
lypinator 0:bb348c97df44 195 // Define the FREEZE_TIMER_ON_DEBUG macro in mbed_app.json for example
lypinator 0:bb348c97df44 196 #if !defined(NDEBUG) && defined(FREEZE_TIMER_ON_DEBUG) && defined(TIM_MST_DBGMCU_FREEZE)
lypinator 0:bb348c97df44 197 TIM_MST_DBGMCU_FREEZE;
lypinator 0:bb348c97df44 198 #endif
lypinator 0:bb348c97df44 199
lypinator 0:bb348c97df44 200 __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1);
lypinator 0:bb348c97df44 201 }
lypinator 0:bb348c97df44 202
lypinator 0:bb348c97df44 203 #endif // 16-bit/32-bit timer
lypinator 0:bb348c97df44 204
lypinator 0:bb348c97df44 205 void us_ticker_init(void)
lypinator 0:bb348c97df44 206 {
lypinator 0:bb348c97df44 207 // Timer is already initialized in HAL_InitTick()
lypinator 0:bb348c97df44 208 __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1);
lypinator 0:bb348c97df44 209 }
lypinator 0:bb348c97df44 210
lypinator 0:bb348c97df44 211 uint32_t us_ticker_read()
lypinator 0:bb348c97df44 212 {
lypinator 0:bb348c97df44 213 return TIM_MST->CNT;
lypinator 0:bb348c97df44 214 }
lypinator 0:bb348c97df44 215
lypinator 0:bb348c97df44 216 void us_ticker_set_interrupt(timestamp_t timestamp)
lypinator 0:bb348c97df44 217 {
lypinator 0:bb348c97df44 218 // NOTE: This function must be called with interrupts disabled to keep our
lypinator 0:bb348c97df44 219 // timer interrupt setup atomic
lypinator 0:bb348c97df44 220 // Set new output compare value
lypinator 0:bb348c97df44 221 __HAL_TIM_SET_COMPARE(&TimMasterHandle, TIM_CHANNEL_1, (uint32_t)timestamp);
lypinator 0:bb348c97df44 222 // Ensure the compare event starts clear
lypinator 0:bb348c97df44 223 __HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1);
lypinator 0:bb348c97df44 224 // Enable IT
lypinator 0:bb348c97df44 225 __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC1);
lypinator 0:bb348c97df44 226 }
lypinator 0:bb348c97df44 227
lypinator 0:bb348c97df44 228 void us_ticker_fire_interrupt(void)
lypinator 0:bb348c97df44 229 {
lypinator 0:bb348c97df44 230 __HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1);
lypinator 0:bb348c97df44 231 LL_TIM_GenerateEvent_CC1(TimMasterHandle.Instance);
lypinator 0:bb348c97df44 232 __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC1);
lypinator 0:bb348c97df44 233 }
lypinator 0:bb348c97df44 234
lypinator 0:bb348c97df44 235 void us_ticker_disable_interrupt(void)
lypinator 0:bb348c97df44 236 {
lypinator 0:bb348c97df44 237 __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1);
lypinator 0:bb348c97df44 238 }
lypinator 0:bb348c97df44 239
lypinator 0:bb348c97df44 240 /* NOTE: must be called with interrupts disabled! */
lypinator 0:bb348c97df44 241 void us_ticker_clear_interrupt(void)
lypinator 0:bb348c97df44 242 {
lypinator 0:bb348c97df44 243 __HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1);
lypinator 0:bb348c97df44 244 }
lypinator 0:bb348c97df44 245
lypinator 0:bb348c97df44 246 void save_timer_ctx(void)
lypinator 0:bb348c97df44 247 {
lypinator 0:bb348c97df44 248 timer_cnt_reg = __HAL_TIM_GET_COUNTER(&TimMasterHandle);
lypinator 0:bb348c97df44 249 timer_ccr1_reg = __HAL_TIM_GET_COMPARE(&TimMasterHandle, TIM_CHANNEL_1);
lypinator 0:bb348c97df44 250 timer_dier_reg = TIM_MST->DIER;
lypinator 0:bb348c97df44 251 }
lypinator 0:bb348c97df44 252
lypinator 0:bb348c97df44 253 void restore_timer_ctx(void)
lypinator 0:bb348c97df44 254 {
lypinator 0:bb348c97df44 255 __HAL_TIM_SET_COUNTER(&TimMasterHandle, timer_cnt_reg);
lypinator 0:bb348c97df44 256 __HAL_TIM_SET_COMPARE(&TimMasterHandle, TIM_CHANNEL_1, timer_ccr1_reg);
lypinator 0:bb348c97df44 257 TIM_MST->DIER = timer_dier_reg;
lypinator 0:bb348c97df44 258 }