mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Mon Nov 09 13:30:11 2015 +0000
Revision:
18:da299f395b9e
Parent:
15:a81a8d6c1dfe
Child:
64:41a834223ea3
Synchronized with git revision f605825f66bb2e462ff7dbc5fb4ed2dbe979d1c3

Full URL: https://github.com/mbedmicro/mbed/commit/f605825f66bb2e462ff7dbc5fb4ed2dbe979d1c3/

Added support for SAML21

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 15:a81a8d6c1dfe 1 /* mbed Microcontroller Library
mbed_official 15:a81a8d6c1dfe 2 * Copyright (c) 2006-2015 ARM Limited
mbed_official 15:a81a8d6c1dfe 3 *
mbed_official 15:a81a8d6c1dfe 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 15:a81a8d6c1dfe 5 * you may not use this file except in compliance with the License.
mbed_official 15:a81a8d6c1dfe 6 * You may obtain a copy of the License at
mbed_official 15:a81a8d6c1dfe 7 *
mbed_official 15:a81a8d6c1dfe 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 15:a81a8d6c1dfe 9 *
mbed_official 15:a81a8d6c1dfe 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 15:a81a8d6c1dfe 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 15:a81a8d6c1dfe 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 15:a81a8d6c1dfe 13 * See the License for the specific language governing permissions and
mbed_official 15:a81a8d6c1dfe 14 * limitations under the License.
mbed_official 15:a81a8d6c1dfe 15 */
mbed_official 15:a81a8d6c1dfe 16 #include <stddef.h>
mbed_official 15:a81a8d6c1dfe 17 #include "us_ticker_api.h"
mbed_official 15:a81a8d6c1dfe 18 #include "cmsis.h"
mbed_official 15:a81a8d6c1dfe 19 #include "mbed_assert.h"
mbed_official 15:a81a8d6c1dfe 20 #include "ins_gclk.h"
mbed_official 15:a81a8d6c1dfe 21 #include "compiler.h"
mbed_official 15:a81a8d6c1dfe 22 #include "system.h"
mbed_official 15:a81a8d6c1dfe 23 #include "tc.h"
mbed_official 15:a81a8d6c1dfe 24 #include "tc_interrupt.h"
mbed_official 15:a81a8d6c1dfe 25
mbed_official 18:da299f395b9e 26 #if (SAMD21) || (SAMR21)
mbed_official 15:a81a8d6c1dfe 27 #define TICKER_COUNTER_uS TC4
mbed_official 15:a81a8d6c1dfe 28 #define TICKER_COUNTER_IRQn TC4_IRQn
mbed_official 15:a81a8d6c1dfe 29 #define TICKER_COUNTER_Handlr TC4_Handler
mbed_official 18:da299f395b9e 30 #elif (SAML21) /*SAML21 TCC4 does not support 32 bit counter operations*/
mbed_official 18:da299f395b9e 31 #define TICKER_COUNTER_uS TC0
mbed_official 18:da299f395b9e 32 #define TICKER_COUNTER_IRQn TC0_IRQn
mbed_official 18:da299f395b9e 33 #define TICKER_COUNTER_Handlr TC0_Handler
mbed_official 18:da299f395b9e 34 #endif
mbed_official 15:a81a8d6c1dfe 35
mbed_official 15:a81a8d6c1dfe 36 static int us_ticker_inited = 0;
mbed_official 15:a81a8d6c1dfe 37 extern uint8_t g_sys_init;
mbed_official 15:a81a8d6c1dfe 38
mbed_official 15:a81a8d6c1dfe 39 struct tc_module us_ticker_module;
mbed_official 15:a81a8d6c1dfe 40
mbed_official 15:a81a8d6c1dfe 41
mbed_official 15:a81a8d6c1dfe 42 static inline void tc_clear_interrupt(
mbed_official 15:a81a8d6c1dfe 43 struct tc_module *const module,
mbed_official 15:a81a8d6c1dfe 44 const enum tc_callback callback_type)
mbed_official 15:a81a8d6c1dfe 45 {
mbed_official 15:a81a8d6c1dfe 46 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 47 MBED_ASSERT(module);
mbed_official 15:a81a8d6c1dfe 48
mbed_official 15:a81a8d6c1dfe 49 /* Clear interrupt flags */
mbed_official 15:a81a8d6c1dfe 50 if (callback_type == TC_CALLBACK_CC_CHANNEL0) {
mbed_official 15:a81a8d6c1dfe 51 module->hw->COUNT8.INTENCLR.reg = TC_INTFLAG_MC(1);
mbed_official 15:a81a8d6c1dfe 52 } else if (callback_type == TC_CALLBACK_CC_CHANNEL1) {
mbed_official 15:a81a8d6c1dfe 53 module->hw->COUNT8.INTENCLR.reg = TC_INTFLAG_MC(2);
mbed_official 15:a81a8d6c1dfe 54 } else {
mbed_official 15:a81a8d6c1dfe 55 module->hw->COUNT8.INTENCLR.reg = (1 << callback_type);
mbed_official 15:a81a8d6c1dfe 56 }
mbed_official 15:a81a8d6c1dfe 57 }
mbed_official 15:a81a8d6c1dfe 58
mbed_official 15:a81a8d6c1dfe 59 void us_ticker_irq_handler_internal(struct tc_module* us_tc_module)
mbed_official 15:a81a8d6c1dfe 60 {
mbed_official 15:a81a8d6c1dfe 61 uint32_t status_flags;
mbed_official 15:a81a8d6c1dfe 62
mbed_official 15:a81a8d6c1dfe 63 /* Clear TC capture overflow and TC count overflow */
mbed_official 15:a81a8d6c1dfe 64 status_flags = TC_STATUS_CAPTURE_OVERFLOW | TC_STATUS_COUNT_OVERFLOW;
mbed_official 15:a81a8d6c1dfe 65 tc_clear_status(&us_ticker_module, status_flags);
mbed_official 15:a81a8d6c1dfe 66
mbed_official 15:a81a8d6c1dfe 67 us_ticker_irq_handler();
mbed_official 15:a81a8d6c1dfe 68 }
mbed_official 15:a81a8d6c1dfe 69
mbed_official 15:a81a8d6c1dfe 70 void us_ticker_init(void)
mbed_official 15:a81a8d6c1dfe 71 {
mbed_official 15:a81a8d6c1dfe 72 uint32_t cycles_per_us;
mbed_official 15:a81a8d6c1dfe 73 uint32_t prescaler = 0;
mbed_official 15:a81a8d6c1dfe 74 struct tc_config config_tc;
mbed_official 15:a81a8d6c1dfe 75 enum status_code ret_status;
mbed_official 15:a81a8d6c1dfe 76
mbed_official 15:a81a8d6c1dfe 77 if (us_ticker_inited) return;
mbed_official 15:a81a8d6c1dfe 78 us_ticker_inited = 1;
mbed_official 15:a81a8d6c1dfe 79
mbed_official 15:a81a8d6c1dfe 80 if (g_sys_init == 0) {
mbed_official 15:a81a8d6c1dfe 81 system_init();
mbed_official 15:a81a8d6c1dfe 82 g_sys_init = 1;
mbed_official 15:a81a8d6c1dfe 83 }
mbed_official 15:a81a8d6c1dfe 84
mbed_official 15:a81a8d6c1dfe 85 tc_get_config_defaults(&config_tc);
mbed_official 15:a81a8d6c1dfe 86
mbed_official 15:a81a8d6c1dfe 87 cycles_per_us = system_gclk_gen_get_hz(config_tc.clock_source) / 1000000;
mbed_official 15:a81a8d6c1dfe 88 MBED_ASSERT(cycles_per_us > 0);
mbed_official 15:a81a8d6c1dfe 89 /*while((cycles_per_us & 1) == 0 && prescaler <= 10) {
mbed_official 15:a81a8d6c1dfe 90 cycles_per_us = cycles_per_us >> 1;
mbed_official 15:a81a8d6c1dfe 91 prescaler++;
mbed_official 15:a81a8d6c1dfe 92 }*/
mbed_official 15:a81a8d6c1dfe 93 while((cycles_per_us > 1) && (prescaler <= 10)) {
mbed_official 15:a81a8d6c1dfe 94 cycles_per_us = cycles_per_us >> 1;
mbed_official 15:a81a8d6c1dfe 95 prescaler++;
mbed_official 15:a81a8d6c1dfe 96 }
mbed_official 15:a81a8d6c1dfe 97 if (prescaler >= 9) {
mbed_official 15:a81a8d6c1dfe 98 prescaler = 7;
mbed_official 15:a81a8d6c1dfe 99 } else if (prescaler >= 7) {
mbed_official 15:a81a8d6c1dfe 100 prescaler = 6;
mbed_official 15:a81a8d6c1dfe 101 } else if (prescaler >= 5) {
mbed_official 15:a81a8d6c1dfe 102 prescaler = 5;
mbed_official 15:a81a8d6c1dfe 103 }
mbed_official 15:a81a8d6c1dfe 104
mbed_official 15:a81a8d6c1dfe 105 config_tc.clock_prescaler = TC_CTRLA_PRESCALER(prescaler);
mbed_official 15:a81a8d6c1dfe 106 config_tc.counter_size = TC_COUNTER_SIZE_32BIT;
mbed_official 15:a81a8d6c1dfe 107 config_tc.run_in_standby = true;
mbed_official 15:a81a8d6c1dfe 108 config_tc.counter_32_bit.value = 0;
mbed_official 15:a81a8d6c1dfe 109 config_tc.counter_32_bit.compare_capture_channel[TC_COMPARE_CAPTURE_CHANNEL_0] = 0xFFFFFFFF;
mbed_official 15:a81a8d6c1dfe 110
mbed_official 15:a81a8d6c1dfe 111 /* Initialize the timer */
mbed_official 15:a81a8d6c1dfe 112 ret_status = tc_init(&us_ticker_module, TICKER_COUNTER_uS, &config_tc);
mbed_official 15:a81a8d6c1dfe 113 MBED_ASSERT(ret_status == STATUS_OK);
mbed_official 15:a81a8d6c1dfe 114
mbed_official 15:a81a8d6c1dfe 115 /* Register callback function */
mbed_official 15:a81a8d6c1dfe 116 tc_register_callback(&us_ticker_module, (tc_callback_t)us_ticker_irq_handler_internal, TC_CALLBACK_CC_CHANNEL0);
mbed_official 15:a81a8d6c1dfe 117
mbed_official 15:a81a8d6c1dfe 118 /* Enable the timer module */
mbed_official 15:a81a8d6c1dfe 119 tc_enable(&us_ticker_module);
mbed_official 15:a81a8d6c1dfe 120 }
mbed_official 15:a81a8d6c1dfe 121
mbed_official 15:a81a8d6c1dfe 122 uint32_t us_ticker_read()
mbed_official 15:a81a8d6c1dfe 123 {
mbed_official 15:a81a8d6c1dfe 124 if (!us_ticker_inited)
mbed_official 15:a81a8d6c1dfe 125 us_ticker_init();
mbed_official 15:a81a8d6c1dfe 126
mbed_official 15:a81a8d6c1dfe 127 return tc_get_count_value(&us_ticker_module);
mbed_official 15:a81a8d6c1dfe 128 }
mbed_official 15:a81a8d6c1dfe 129
mbed_official 15:a81a8d6c1dfe 130 void us_ticker_set_interrupt(timestamp_t timestamp)
mbed_official 15:a81a8d6c1dfe 131 {
mbed_official 15:a81a8d6c1dfe 132 uint32_t cur_time;
mbed_official 15:a81a8d6c1dfe 133 int32_t delta;
mbed_official 15:a81a8d6c1dfe 134
mbed_official 15:a81a8d6c1dfe 135 cur_time = us_ticker_read();
mbed_official 15:a81a8d6c1dfe 136 delta = (int32_t)((uint32_t)timestamp - cur_time);
mbed_official 15:a81a8d6c1dfe 137 if (delta < 0) {
mbed_official 15:a81a8d6c1dfe 138 /* Event already occurred in past */
mbed_official 15:a81a8d6c1dfe 139 us_ticker_irq_handler();
mbed_official 15:a81a8d6c1dfe 140 return;
mbed_official 15:a81a8d6c1dfe 141 }
mbed_official 15:a81a8d6c1dfe 142
mbed_official 15:a81a8d6c1dfe 143 NVIC_DisableIRQ(TICKER_COUNTER_IRQn);
mbed_official 15:a81a8d6c1dfe 144 NVIC_SetVector(TICKER_COUNTER_IRQn, (uint32_t)TICKER_COUNTER_Handlr);
mbed_official 15:a81a8d6c1dfe 145
mbed_official 15:a81a8d6c1dfe 146 /* Enable the callback */
mbed_official 15:a81a8d6c1dfe 147 tc_enable_callback(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0);
mbed_official 15:a81a8d6c1dfe 148 tc_set_compare_value(&us_ticker_module, TC_COMPARE_CAPTURE_CHANNEL_0, (uint32_t)timestamp);
mbed_official 15:a81a8d6c1dfe 149
mbed_official 15:a81a8d6c1dfe 150 NVIC_EnableIRQ(TICKER_COUNTER_IRQn);
mbed_official 15:a81a8d6c1dfe 151 }
mbed_official 15:a81a8d6c1dfe 152
mbed_official 15:a81a8d6c1dfe 153 void us_ticker_disable_interrupt(void)
mbed_official 15:a81a8d6c1dfe 154 {
mbed_official 15:a81a8d6c1dfe 155 /* Disable the callback */
mbed_official 15:a81a8d6c1dfe 156 tc_disable_callback(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0);
mbed_official 15:a81a8d6c1dfe 157 NVIC_DisableIRQ(TICKER_COUNTER_IRQn);
mbed_official 15:a81a8d6c1dfe 158 }
mbed_official 15:a81a8d6c1dfe 159
mbed_official 15:a81a8d6c1dfe 160 void us_ticker_clear_interrupt(void)
mbed_official 15:a81a8d6c1dfe 161 {
mbed_official 15:a81a8d6c1dfe 162 uint32_t status_flags;
mbed_official 15:a81a8d6c1dfe 163
mbed_official 15:a81a8d6c1dfe 164 /* Clear TC channel 0 match */
mbed_official 15:a81a8d6c1dfe 165 status_flags = TC_STATUS_CHANNEL_0_MATCH;
mbed_official 15:a81a8d6c1dfe 166 tc_clear_status(&us_ticker_module, status_flags);
mbed_official 15:a81a8d6c1dfe 167
mbed_official 15:a81a8d6c1dfe 168 /* Clear the interrupt */
mbed_official 15:a81a8d6c1dfe 169 tc_clear_interrupt(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0);
mbed_official 15:a81a8d6c1dfe 170 NVIC_ClearPendingIRQ(TICKER_COUNTER_IRQn);
mbed_official 15:a81a8d6c1dfe 171 }