Mouse code for the MacroRat
Diff: mbed-dev/targets/TARGET_Atmel/TARGET_SAM_CortexM4/lp_ticker.c
- Revision:
- 18:6a4db94011d3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-dev/targets/TARGET_Atmel/TARGET_SAM_CortexM4/lp_ticker.c Sun May 14 23:18:57 2017 +0000 @@ -0,0 +1,133 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cmsis.h" +#include <stddef.h> +#include "lp_ticker_api.h" +#include "mbed_assert.h" +#include "sleep_api.h" +#include "compiler.h" +#include "sysclk.h" +#include "tc.h" +#include "us_ticker_api.h" + +uint8_t lp_ticker_inited = 0; +extern volatile uint8_t us_ticker_inited; +extern uint8_t g_sys_init; +extern volatile uint32_t overflow32bitcounter; +volatile uint16_t lp_ticker_16bit_counter; +volatile uint16_t lp_ticker_interrupt_counter; +volatile uint16_t lp_ticker_interrupt_offset; +volatile uint32_t lpoverflow32bitcounter = 0; + +#define TICKER_COUNTER_lp TC0 + +#define TICKER_COUNTER_CLK2 ID_TC2 + +#define TICKER_COUNTER_CHANNEL2 2 +#define TICKER_COUNTER_IRQn2 TC2_IRQn +#define TICKER_COUNTER_Handlr2 TC2_Handler + +#define OVERFLOW_16bit_VALUE 0xFFFF + + +void TICKER_COUNTER_Handlr2(void) +{ + uint32_t status=tc_get_status(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2); + uint32_t interrupmask=tc_get_interrupt_mask(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2); + + if (((status & interrupmask) & TC_IER_CPCS)) { + if(lp_ticker_interrupt_counter) { + lp_ticker_interrupt_counter--; + } else { + if(lp_ticker_interrupt_offset) { + tc_stop(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2); + tc_write_rc(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2, (uint32_t)lp_ticker_interrupt_offset); + tc_start(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2); + lp_ticker_interrupt_offset=0; + } else { + lp_ticker_irq_handler(); + } + } + } +} + +void lp_ticker_init(void) +{ + if(lp_ticker_inited) + return; + if (!us_ticker_inited) + us_ticker_init(); + sysclk_enable_peripheral_clock(TICKER_COUNTER_CLK2); + tc_init(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2, TC_CMR_TCCLKS_TIMER_CLOCK4); + lp_ticker_inited = 1; +} + +uint32_t lp_ticker_read() +{ + if (!lp_ticker_inited) + lp_ticker_init(); + return us_ticker_read(); +} + +void lp_ticker_set_interrupt(timestamp_t timestamp) +{ + uint32_t cur_time; + int32_t delta; + + cur_time = lp_ticker_read(); + delta = (int32_t)((uint32_t)timestamp - cur_time); + if (delta < 0) { + /* Event already occurred in past */ + lp_ticker_irq_handler(); + return; + } + + uint16_t interruptat=0; + + if(delta > OVERFLOW_16bit_VALUE) { + lp_ticker_interrupt_counter= (delta/OVERFLOW_16bit_VALUE) -1; + lp_ticker_interrupt_offset=delta%OVERFLOW_16bit_VALUE; + interruptat=OVERFLOW_16bit_VALUE; + } else { + lp_ticker_interrupt_counter=0; + lp_ticker_interrupt_offset=0; + interruptat=delta; + } + + NVIC_DisableIRQ(TICKER_COUNTER_IRQn2); + + tc_write_rc(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2, (uint32_t)interruptat); + + NVIC_ClearPendingIRQ(TICKER_COUNTER_IRQn2); + NVIC_SetPriority(TICKER_COUNTER_IRQn2, 0); + NVIC_EnableIRQ(TICKER_COUNTER_IRQn2); + tc_enable_interrupt(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2, TC_IDR_CPCS ); + + tc_start(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2); +} + +void lp_ticker_disable_interrupt(void) +{ + tc_stop(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2); + tc_disable_interrupt(TICKER_COUNTER_lp, TICKER_COUNTER_CHANNEL2, TC_IDR_CPCS); + NVIC_DisableIRQ(TICKER_COUNTER_IRQn2); +} + +void lp_ticker_clear_interrupt(void) +{ + NVIC_ClearPendingIRQ(TICKER_COUNTER_IRQn2); +}