Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-src by
us_ticker.c
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include <stddef.h> 00017 #include "us_ticker_api.h" 00018 #include "PeripheralNames.h" 00019 00020 static void pit_init(void); 00021 static void lptmr_init(void); 00022 00023 static int us_ticker_inited = 0; 00024 00025 void us_ticker_init(void) { 00026 if (us_ticker_inited) return; 00027 us_ticker_inited = 1; 00028 00029 pit_init(); 00030 lptmr_init(); 00031 } 00032 00033 /****************************************************************************** 00034 * Timer for us timing. 00035 ******************************************************************************/ 00036 static void pit_init(void) { 00037 SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; // Clock PIT 00038 PIT->MCR = 0; // Enable PIT 00039 00040 // Channel 1 00041 PIT->CHANNEL[1].LDVAL = 0xFFFFFFFF; 00042 PIT->CHANNEL[1].TCTRL = PIT_TCTRL_CHN_MASK; // Chain to timer 0, disable Interrupts 00043 PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK; // Start timer 1 00044 00045 // Use channel 0 as a prescaler for channel 1 00046 PIT->CHANNEL[0].LDVAL = 23; 00047 PIT->CHANNEL[0].TCTRL = PIT_TCTRL_TEN_MASK; // Start timer 0, disable interrupts 00048 } 00049 00050 uint32_t us_ticker_read() { 00051 if (!us_ticker_inited) 00052 us_ticker_init(); 00053 00054 // The PIT is a countdown timer 00055 return ~(PIT->CHANNEL[1].CVAL); 00056 } 00057 00058 /****************************************************************************** 00059 * Timer Event 00060 * 00061 * It schedules interrupts at given (32bit)us interval of time. 00062 * It is implemented used the 16bit Low Power Timer that remains powered in all 00063 * power modes. 00064 ******************************************************************************/ 00065 static void lptmr_isr(void); 00066 00067 static void lptmr_init(void) { 00068 /* Clock the timer */ 00069 SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK; 00070 00071 /* Reset */ 00072 LPTMR0->CSR = 0; 00073 00074 /* Set interrupt handler */ 00075 NVIC_SetVector(LPTimer_IRQn, (uint32_t)lptmr_isr); 00076 NVIC_EnableIRQ(LPTimer_IRQn); 00077 00078 /* Clock at (1)MHz -> (1)tick/us */ 00079 LPTMR0->PSR = LPTMR_PSR_PCS(3); // OSCERCLK -> 8MHz 00080 LPTMR0->PSR |= LPTMR_PSR_PRESCALE(2); // divide by 8 00081 } 00082 00083 void us_ticker_disable_interrupt(void) { 00084 LPTMR0->CSR &= ~LPTMR_CSR_TIE_MASK; 00085 } 00086 00087 void us_ticker_clear_interrupt(void) { 00088 // we already clear interrupt in lptmr_isr 00089 } 00090 00091 static uint32_t us_ticker_int_counter = 0; 00092 static uint16_t us_ticker_int_remainder = 0; 00093 00094 static void lptmr_set(unsigned short count) { 00095 /* Reset */ 00096 LPTMR0->CSR = 0; 00097 00098 /* Set the compare register */ 00099 LPTMR0->CMR = count; 00100 00101 /* Enable interrupt */ 00102 LPTMR0->CSR |= LPTMR_CSR_TIE_MASK; 00103 00104 /* Start the timer */ 00105 LPTMR0->CSR |= LPTMR_CSR_TEN_MASK; 00106 } 00107 00108 static void lptmr_isr(void) { 00109 // write 1 to TCF to clear the LPT timer compare flag 00110 LPTMR0->CSR |= LPTMR_CSR_TCF_MASK; 00111 00112 if (us_ticker_int_counter > 0) { 00113 lptmr_set(0xFFFF); 00114 us_ticker_int_counter--; 00115 00116 } else { 00117 if (us_ticker_int_remainder > 0) { 00118 lptmr_set(us_ticker_int_remainder); 00119 us_ticker_int_remainder = 0; 00120 00121 } else { 00122 // This function is going to disable the interrupts if there are 00123 // no other events in the queue 00124 us_ticker_irq_handler(); 00125 } 00126 } 00127 } 00128 00129 void us_ticker_set_interrupt(unsigned int timestamp) { 00130 int delta = (int)(timestamp - us_ticker_read()); 00131 if (delta <= 0) { 00132 // This event was in the past: 00133 us_ticker_irq_handler(); 00134 return; 00135 } 00136 00137 us_ticker_int_counter = (uint32_t)(delta >> 16); 00138 us_ticker_int_remainder = (uint16_t)(0xFFFF & delta); 00139 if (us_ticker_int_counter > 0) { 00140 lptmr_set(0xFFFF); 00141 us_ticker_int_counter--; 00142 } else { 00143 lptmr_set(us_ticker_int_remainder); 00144 us_ticker_int_remainder = 0; 00145 } 00146 }
Generated on Tue Jul 12 2022 13:47:02 by
 1.7.2
 1.7.2 
    