ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

Committer:
group-onsemi
Date:
Wed Jan 25 20:34:15 2017 +0000
Revision:
0:098463de4c5d
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
group-onsemi 0:098463de4c5d 1 /* mbed Microcontroller Library
group-onsemi 0:098463de4c5d 2 * Copyright (c) 2006-2016 ARM Limited
group-onsemi 0:098463de4c5d 3 *
group-onsemi 0:098463de4c5d 4 * Licensed under the Apache License, Version 2.0 (the "License");
group-onsemi 0:098463de4c5d 5 * you may not use this file except in compliance with the License.
group-onsemi 0:098463de4c5d 6 * You may obtain a copy of the License at
group-onsemi 0:098463de4c5d 7 *
group-onsemi 0:098463de4c5d 8 * http://www.apache.org/licenses/LICENSE-2.0
group-onsemi 0:098463de4c5d 9 *
group-onsemi 0:098463de4c5d 10 * Unless required by applicable law or agreed to in writing, software
group-onsemi 0:098463de4c5d 11 * distributed under the License is distributed on an "AS IS" BASIS,
group-onsemi 0:098463de4c5d 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
group-onsemi 0:098463de4c5d 13 * See the License for the specific language governing permissions and
group-onsemi 0:098463de4c5d 14 * limitations under the License.
group-onsemi 0:098463de4c5d 15 */
group-onsemi 0:098463de4c5d 16 #include <stddef.h>
group-onsemi 0:098463de4c5d 17 #include "us_ticker_api.h"
group-onsemi 0:098463de4c5d 18 #include "PeripheralNames.h"
group-onsemi 0:098463de4c5d 19 #include "hal_tick.h"
group-onsemi 0:098463de4c5d 20
group-onsemi 0:098463de4c5d 21 // A 16-bit timer is used
group-onsemi 0:098463de4c5d 22 #if TIM_MST_16BIT
group-onsemi 0:098463de4c5d 23
group-onsemi 0:098463de4c5d 24 TIM_HandleTypeDef TimMasterHandle;
group-onsemi 0:098463de4c5d 25
group-onsemi 0:098463de4c5d 26 volatile uint32_t SlaveCounter = 0;
group-onsemi 0:098463de4c5d 27 volatile uint32_t oc_int_part = 0;
group-onsemi 0:098463de4c5d 28 volatile uint16_t oc_rem_part = 0;
group-onsemi 0:098463de4c5d 29 volatile uint8_t tim_it_update; // TIM_IT_UPDATE event flag set in timer_irq_handler()
group-onsemi 0:098463de4c5d 30 volatile uint32_t tim_it_counter = 0; // Time stamp to be updated by timer_irq_handler()
group-onsemi 0:098463de4c5d 31
group-onsemi 0:098463de4c5d 32 static int us_ticker_inited = 0;
group-onsemi 0:098463de4c5d 33
group-onsemi 0:098463de4c5d 34 void set_compare(uint16_t count)
group-onsemi 0:098463de4c5d 35 {
group-onsemi 0:098463de4c5d 36 TimMasterHandle.Instance = TIM_MST;
group-onsemi 0:098463de4c5d 37 // Set new output compare value
group-onsemi 0:098463de4c5d 38 __HAL_TIM_SetCompare(&TimMasterHandle, TIM_CHANNEL_1, count);
group-onsemi 0:098463de4c5d 39 // Enable IT
group-onsemi 0:098463de4c5d 40 __HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC1);
group-onsemi 0:098463de4c5d 41 }
group-onsemi 0:098463de4c5d 42
group-onsemi 0:098463de4c5d 43 void us_ticker_init(void)
group-onsemi 0:098463de4c5d 44 {
group-onsemi 0:098463de4c5d 45 if (us_ticker_inited) return;
group-onsemi 0:098463de4c5d 46 us_ticker_inited = 1;
group-onsemi 0:098463de4c5d 47
group-onsemi 0:098463de4c5d 48 TimMasterHandle.Instance = TIM_MST;
group-onsemi 0:098463de4c5d 49
group-onsemi 0:098463de4c5d 50 HAL_InitTick(0); // The passed value is not used
group-onsemi 0:098463de4c5d 51 }
group-onsemi 0:098463de4c5d 52
group-onsemi 0:098463de4c5d 53 uint32_t us_ticker_read()
group-onsemi 0:098463de4c5d 54 {
group-onsemi 0:098463de4c5d 55 uint32_t counter;
group-onsemi 0:098463de4c5d 56
group-onsemi 0:098463de4c5d 57 TimMasterHandle.Instance = TIM_MST;
group-onsemi 0:098463de4c5d 58
group-onsemi 0:098463de4c5d 59 if (!us_ticker_inited) us_ticker_init();
group-onsemi 0:098463de4c5d 60
group-onsemi 0:098463de4c5d 61 #if defined(TARGET_STM32L0)
group-onsemi 0:098463de4c5d 62 uint16_t cntH_old, cntH, cntL;
group-onsemi 0:098463de4c5d 63 do {
group-onsemi 0:098463de4c5d 64 // For some reason on L0xx series we need to read and clear the
group-onsemi 0:098463de4c5d 65 // overflow flag which give extra time to propelry handle possible
group-onsemi 0:098463de4c5d 66 // hiccup after ~60s
group-onsemi 0:098463de4c5d 67 if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1OF) == SET) {
group-onsemi 0:098463de4c5d 68 __HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1OF);
group-onsemi 0:098463de4c5d 69 }
group-onsemi 0:098463de4c5d 70 cntH_old = SlaveCounter;
group-onsemi 0:098463de4c5d 71 if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE) == SET) {
group-onsemi 0:098463de4c5d 72 cntH_old += 1;
group-onsemi 0:098463de4c5d 73 }
group-onsemi 0:098463de4c5d 74 cntL = TIM_MST->CNT;
group-onsemi 0:098463de4c5d 75 cntH = SlaveCounter;
group-onsemi 0:098463de4c5d 76 if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE) == SET) {
group-onsemi 0:098463de4c5d 77 cntH += 1;
group-onsemi 0:098463de4c5d 78 }
group-onsemi 0:098463de4c5d 79 } while(cntH_old != cntH);
group-onsemi 0:098463de4c5d 80 // Glue the upper and lower part together to get a 32 bit timer
group-onsemi 0:098463de4c5d 81 return (uint32_t)(cntH << 16 | cntL);
group-onsemi 0:098463de4c5d 82 #else
group-onsemi 0:098463de4c5d 83 tim_it_update = 0; // Clear TIM_IT_UPDATE event flag
group-onsemi 0:098463de4c5d 84 counter = TIM_MST->CNT + (uint32_t)(SlaveCounter << 16); // Calculate new time stamp
group-onsemi 0:098463de4c5d 85 if (tim_it_update == 1) {
group-onsemi 0:098463de4c5d 86 return tim_it_counter; // In case of TIM_IT_UPDATE return the time stamp that was calculated in timer_irq_handler()
group-onsemi 0:098463de4c5d 87 }
group-onsemi 0:098463de4c5d 88 else {
group-onsemi 0:098463de4c5d 89 return counter; // Otherwise return the time stamp calculated here
group-onsemi 0:098463de4c5d 90 }
group-onsemi 0:098463de4c5d 91 #endif
group-onsemi 0:098463de4c5d 92 }
group-onsemi 0:098463de4c5d 93
group-onsemi 0:098463de4c5d 94 void us_ticker_set_interrupt(timestamp_t timestamp)
group-onsemi 0:098463de4c5d 95 {
group-onsemi 0:098463de4c5d 96 int delta = (int)((uint32_t)timestamp - us_ticker_read());
group-onsemi 0:098463de4c5d 97
group-onsemi 0:098463de4c5d 98 uint16_t cval = TIM_MST->CNT;
group-onsemi 0:098463de4c5d 99
group-onsemi 0:098463de4c5d 100 if (delta <= 0) { // This event was in the past
group-onsemi 0:098463de4c5d 101 us_ticker_irq_handler();
group-onsemi 0:098463de4c5d 102 } else {
group-onsemi 0:098463de4c5d 103 oc_int_part = (uint32_t)(delta >> 16);
group-onsemi 0:098463de4c5d 104 oc_rem_part = (uint16_t)(delta & 0xFFFF);
group-onsemi 0:098463de4c5d 105 if (oc_rem_part <= (0xFFFF - cval)) {
group-onsemi 0:098463de4c5d 106 set_compare(cval + oc_rem_part);
group-onsemi 0:098463de4c5d 107 oc_rem_part = 0;
group-onsemi 0:098463de4c5d 108 } else {
group-onsemi 0:098463de4c5d 109 set_compare(0xFFFF);
group-onsemi 0:098463de4c5d 110 oc_rem_part = oc_rem_part - (0xFFFF - cval);
group-onsemi 0:098463de4c5d 111 }
group-onsemi 0:098463de4c5d 112 }
group-onsemi 0:098463de4c5d 113 }
group-onsemi 0:098463de4c5d 114
group-onsemi 0:098463de4c5d 115 void us_ticker_disable_interrupt(void)
group-onsemi 0:098463de4c5d 116 {
group-onsemi 0:098463de4c5d 117 TimMasterHandle.Instance = TIM_MST;
group-onsemi 0:098463de4c5d 118 __HAL_TIM_DISABLE_IT(&TimMasterHandle, TIM_IT_CC1);
group-onsemi 0:098463de4c5d 119 }
group-onsemi 0:098463de4c5d 120
group-onsemi 0:098463de4c5d 121 void us_ticker_clear_interrupt(void)
group-onsemi 0:098463de4c5d 122 {
group-onsemi 0:098463de4c5d 123 TimMasterHandle.Instance = TIM_MST;
group-onsemi 0:098463de4c5d 124 if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1) == SET) {
group-onsemi 0:098463de4c5d 125 __HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1);
group-onsemi 0:098463de4c5d 126 }
group-onsemi 0:098463de4c5d 127 }
group-onsemi 0:098463de4c5d 128
group-onsemi 0:098463de4c5d 129 #endif // TIM_MST_16BIT