mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Mon Oct 02 15:33:19 2017 +0100
Revision:
174:b96e65c34a4d
Parent:
149:156823d33999
Child:
188:bcfe06ba3d64
This updates the lib to the mbed lib v 152

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 8:69ce7aaad4c4 1 /* mbed Microcontroller Library
mbed_official 8:69ce7aaad4c4 2 * Copyright (c) 2006-2015 ARM Limited
mbed_official 8:69ce7aaad4c4 3 *
mbed_official 8:69ce7aaad4c4 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 8:69ce7aaad4c4 5 * you may not use this file except in compliance with the License.
mbed_official 8:69ce7aaad4c4 6 * You may obtain a copy of the License at
mbed_official 8:69ce7aaad4c4 7 *
mbed_official 8:69ce7aaad4c4 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 8:69ce7aaad4c4 9 *
mbed_official 8:69ce7aaad4c4 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 8:69ce7aaad4c4 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 8:69ce7aaad4c4 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 8:69ce7aaad4c4 13 * See the License for the specific language governing permissions and
mbed_official 8:69ce7aaad4c4 14 * limitations under the License.
mbed_official 8:69ce7aaad4c4 15 */
mbed_official 8:69ce7aaad4c4 16 #include <stddef.h>
mbed_official 8:69ce7aaad4c4 17 #include "us_ticker_api.h"
mbed_official 8:69ce7aaad4c4 18 #include "PeripheralNames.h"
mbed_official 8:69ce7aaad4c4 19 #include "clk_freqs.h"
mbed_official 8:69ce7aaad4c4 20
mbed_official 8:69ce7aaad4c4 21 #define PIT_TIMER PIT->CHANNEL[0]
mbed_official 8:69ce7aaad4c4 22 #define PIT_TIMER_IRQ PIT0_IRQn
mbed_official 8:69ce7aaad4c4 23 #define PIT_TICKER PIT->CHANNEL[1]
mbed_official 8:69ce7aaad4c4 24 #define PIT_TICKER_IRQ PIT1_IRQn
mbed_official 8:69ce7aaad4c4 25
mbed_official 8:69ce7aaad4c4 26 static void timer_init(void);
mbed_official 8:69ce7aaad4c4 27 static void ticker_init(void);
mbed_official 8:69ce7aaad4c4 28
mbed_official 8:69ce7aaad4c4 29
mbed_official 8:69ce7aaad4c4 30 static int us_ticker_inited = 0;
mbed_official 8:69ce7aaad4c4 31 static uint32_t clk_mhz;
mbed_official 8:69ce7aaad4c4 32
mbed_official 8:69ce7aaad4c4 33 void us_ticker_init(void) {
mbed_official 8:69ce7aaad4c4 34 if (us_ticker_inited)
mbed_official 8:69ce7aaad4c4 35 return;
mbed_official 8:69ce7aaad4c4 36 us_ticker_inited = 1;
mbed_official 8:69ce7aaad4c4 37
mbed_official 8:69ce7aaad4c4 38 SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; // Clock PIT
mbed_official 8:69ce7aaad4c4 39 PIT->MCR = 0; // Enable PIT
mbed_official 8:69ce7aaad4c4 40
mbed_official 8:69ce7aaad4c4 41 clk_mhz = bus_frequency() / 1000000;
mbed_official 8:69ce7aaad4c4 42
mbed_official 8:69ce7aaad4c4 43 timer_init();
mbed_official 8:69ce7aaad4c4 44 ticker_init();
mbed_official 8:69ce7aaad4c4 45 }
mbed_official 8:69ce7aaad4c4 46
mbed_official 8:69ce7aaad4c4 47 /******************************************************************************
mbed_official 8:69ce7aaad4c4 48 * Timer for us timing.
mbed_official 8:69ce7aaad4c4 49 *
mbed_official 8:69ce7aaad4c4 50 * The K20D5M does not have a prescaler on its PIT timer nor the option
mbed_official 8:69ce7aaad4c4 51 * to chain timers, which is why a software timer is required to get 32-bit
mbed_official 8:69ce7aaad4c4 52 * word length.
mbed_official 8:69ce7aaad4c4 53 ******************************************************************************/
mbed_official 8:69ce7aaad4c4 54 static volatile uint32_t msb_counter = 0;
mbed_official 8:69ce7aaad4c4 55 static uint32_t timer_ldval = 0;
mbed_official 8:69ce7aaad4c4 56
mbed_official 8:69ce7aaad4c4 57 static void timer_isr(void) {
mbed_official 8:69ce7aaad4c4 58 if (PIT_TIMER.TFLG == 1) {
mbed_official 8:69ce7aaad4c4 59 msb_counter++;
mbed_official 8:69ce7aaad4c4 60 PIT_TIMER.TFLG = 1;
mbed_official 8:69ce7aaad4c4 61 }
mbed_official 8:69ce7aaad4c4 62 }
mbed_official 8:69ce7aaad4c4 63
mbed_official 8:69ce7aaad4c4 64 static void timer_init(void) {
mbed_official 8:69ce7aaad4c4 65 //CLZ counts the leading zeros, returning number of bits not used by clk_mhz
mbed_official 8:69ce7aaad4c4 66 timer_ldval = clk_mhz << __CLZ(clk_mhz);
mbed_official 8:69ce7aaad4c4 67
mbed_official 8:69ce7aaad4c4 68 PIT_TIMER.LDVAL = timer_ldval; // 1us
mbed_official 8:69ce7aaad4c4 69 PIT_TIMER.TCTRL |= PIT_TCTRL_TIE_MASK;
mbed_official 8:69ce7aaad4c4 70 PIT_TIMER.TCTRL |= PIT_TCTRL_TEN_MASK; // Start timer 0
mbed_official 8:69ce7aaad4c4 71
mbed_official 8:69ce7aaad4c4 72 NVIC_SetVector(PIT_TIMER_IRQ, (uint32_t)timer_isr);
mbed_official 8:69ce7aaad4c4 73 NVIC_EnableIRQ(PIT_TIMER_IRQ);
mbed_official 8:69ce7aaad4c4 74 }
mbed_official 8:69ce7aaad4c4 75
mbed_official 8:69ce7aaad4c4 76 uint32_t us_ticker_read() {
mbed_official 8:69ce7aaad4c4 77 if (!us_ticker_inited)
mbed_official 8:69ce7aaad4c4 78 us_ticker_init();
mbed_official 8:69ce7aaad4c4 79
mbed_official 8:69ce7aaad4c4 80 uint32_t retval;
mbed_official 8:69ce7aaad4c4 81 __disable_irq();
mbed_official 8:69ce7aaad4c4 82 retval = (timer_ldval - PIT_TIMER.CVAL) / clk_mhz; //Hardware bits
mbed_official 8:69ce7aaad4c4 83 retval |= msb_counter << __CLZ(clk_mhz); //Software bits
mbed_official 8:69ce7aaad4c4 84
mbed_official 8:69ce7aaad4c4 85 if (PIT_TIMER.TFLG == 1) { //If overflow bit is set, force it to be handled
mbed_official 8:69ce7aaad4c4 86 timer_isr(); //Handle IRQ, read again to make sure software/hardware bits are synced
mbed_official 8:69ce7aaad4c4 87 NVIC_ClearPendingIRQ(PIT_TIMER_IRQ);
mbed_official 8:69ce7aaad4c4 88 return us_ticker_read();
mbed_official 8:69ce7aaad4c4 89 }
mbed_official 8:69ce7aaad4c4 90
mbed_official 8:69ce7aaad4c4 91 __enable_irq();
mbed_official 8:69ce7aaad4c4 92 return retval;
mbed_official 8:69ce7aaad4c4 93 }
mbed_official 8:69ce7aaad4c4 94
mbed_official 8:69ce7aaad4c4 95 /******************************************************************************
mbed_official 8:69ce7aaad4c4 96 * Timer Event
mbed_official 8:69ce7aaad4c4 97 *
mbed_official 8:69ce7aaad4c4 98 * It schedules interrupts at given (32bit)us interval of time.
mbed_official 8:69ce7aaad4c4 99 * It is implemented using PIT channel 1, since no prescaler is available,
mbed_official 8:69ce7aaad4c4 100 * some bits are implemented in software.
mbed_official 8:69ce7aaad4c4 101 ******************************************************************************/
mbed_official 8:69ce7aaad4c4 102 static void ticker_isr(void);
mbed_official 8:69ce7aaad4c4 103
mbed_official 8:69ce7aaad4c4 104 static void ticker_init(void) {
mbed_official 8:69ce7aaad4c4 105 /* Set interrupt handler */
mbed_official 8:69ce7aaad4c4 106 NVIC_SetVector(PIT_TICKER_IRQ, (uint32_t)ticker_isr);
mbed_official 8:69ce7aaad4c4 107 NVIC_EnableIRQ(PIT_TICKER_IRQ);
mbed_official 8:69ce7aaad4c4 108 }
mbed_official 8:69ce7aaad4c4 109
mbed_official 8:69ce7aaad4c4 110 void us_ticker_disable_interrupt(void) {
mbed_official 8:69ce7aaad4c4 111 PIT_TICKER.TCTRL &= ~PIT_TCTRL_TIE_MASK;
mbed_official 8:69ce7aaad4c4 112 }
mbed_official 8:69ce7aaad4c4 113
mbed_official 8:69ce7aaad4c4 114 void us_ticker_clear_interrupt(void) {
mbed_official 8:69ce7aaad4c4 115 // we already clear interrupt in lptmr_isr
mbed_official 8:69ce7aaad4c4 116 }
mbed_official 8:69ce7aaad4c4 117
mbed_official 8:69ce7aaad4c4 118 static uint32_t us_ticker_int_counter = 0;
mbed_official 8:69ce7aaad4c4 119
mbed_official 8:69ce7aaad4c4 120 inline static void ticker_set(uint32_t count) {
mbed_official 8:69ce7aaad4c4 121 PIT_TICKER.TCTRL = 0;
mbed_official 8:69ce7aaad4c4 122 PIT_TICKER.LDVAL = count;
mbed_official 8:69ce7aaad4c4 123 PIT_TICKER.TCTRL = PIT_TCTRL_TIE_MASK | PIT_TCTRL_TEN_MASK;
mbed_official 8:69ce7aaad4c4 124 }
mbed_official 8:69ce7aaad4c4 125
mbed_official 8:69ce7aaad4c4 126 static void ticker_isr(void) {
mbed_official 8:69ce7aaad4c4 127 // Clear IRQ flag
mbed_official 8:69ce7aaad4c4 128 PIT_TICKER.TFLG = 1;
mbed_official 8:69ce7aaad4c4 129
mbed_official 8:69ce7aaad4c4 130 if (us_ticker_int_counter > 0) {
mbed_official 8:69ce7aaad4c4 131 ticker_set(0xFFFFFFFF);
mbed_official 8:69ce7aaad4c4 132 us_ticker_int_counter--;
mbed_official 8:69ce7aaad4c4 133 } else {
mbed_official 8:69ce7aaad4c4 134 // This function is going to disable the interrupts if there are
mbed_official 8:69ce7aaad4c4 135 // no other events in the queue
mbed_official 8:69ce7aaad4c4 136 us_ticker_irq_handler();
mbed_official 8:69ce7aaad4c4 137 }
mbed_official 8:69ce7aaad4c4 138 }
mbed_official 8:69ce7aaad4c4 139
mbed_official 8:69ce7aaad4c4 140 void us_ticker_set_interrupt(timestamp_t timestamp) {
AnnaBridge 174:b96e65c34a4d 141 uint32_t delta = timestamp - us_ticker_read();
mbed_official 8:69ce7aaad4c4 142 //Calculate how much falls outside the 32-bit after multiplying with clk_mhz
mbed_official 8:69ce7aaad4c4 143 //We shift twice 16-bit to keep everything within the 32-bit variable
mbed_official 8:69ce7aaad4c4 144 us_ticker_int_counter = (uint32_t)(delta >> 16);
mbed_official 8:69ce7aaad4c4 145 us_ticker_int_counter *= clk_mhz;
mbed_official 8:69ce7aaad4c4 146 us_ticker_int_counter >>= 16;
mbed_official 8:69ce7aaad4c4 147
mbed_official 8:69ce7aaad4c4 148 uint32_t us_ticker_int_remainder = (uint32_t)delta * clk_mhz;
mbed_official 8:69ce7aaad4c4 149 if (us_ticker_int_remainder == 0) {
mbed_official 8:69ce7aaad4c4 150 ticker_set(0xFFFFFFFF);
mbed_official 8:69ce7aaad4c4 151 us_ticker_int_counter--;
mbed_official 8:69ce7aaad4c4 152 } else {
mbed_official 8:69ce7aaad4c4 153 ticker_set(us_ticker_int_remainder);
mbed_official 8:69ce7aaad4c4 154 }
mbed_official 8:69ce7aaad4c4 155 }
AnnaBridge 174:b96e65c34a4d 156
AnnaBridge 174:b96e65c34a4d 157 void us_ticker_fire_interrupt(void)
AnnaBridge 174:b96e65c34a4d 158 {
AnnaBridge 174:b96e65c34a4d 159 NVIC_SetPendingIRQ(PIT_TICKER_IRQ);
AnnaBridge 174:b96e65c34a4d 160 }