/* =========================================================================== * * Copyright (c) 2015-2017, Infineon Technologies AG * * All rights reserved. * * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * * list of conditions and the following disclaimer. Redistributions in binary * * form must reproduce the above copyright notice, this list of conditions and * * the following disclaimer in the documentation and/or other materials * * provided with the distribution. Neither the name of the copyright holders * * nor the names of its contributors may be used to endorse or promote * * products derived from this software without specific prior written * * permission. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * To improve the quality of the software, users are encouraged to share * * modifications, enhancements or bug fixes with * * Infineon Technologies AG (dave@infineon.com). * * * * =========================================================================== */ /** * @file * @date 15 April, 2017 * @version 1.0.0 * * History
* * Version 1.0.0 Initial
* */ /********************************************************************************************************************* * HEADER FILES ********************************************************************************************************************/ #include "xmc_gpio.h" #include "timer.h" #include "timer.h" #include #include /********************************************************************************************************************* * API IMPLEMENTATION ********************************************************************************************************************/ /** * User timer callback */ __WEAK void timer_cb() { } void CCU40_0_IRQHandler(void) { timer_cb(); } void TIMER_Init(uint32_t divider) { XMC_CCU4_SLICE_COMPARE_CONFIG_t slice_config; XMC_CCU4_SLICE_EVENT_CONFIG_t event_config = { .mapped_input = CCU40_IN0_SCU_GSC40, .edge = XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_RISING_EDGE }; /* Init CCU4x module */ XMC_CCU4_Init(CCU40, XMC_CCU4_SLICE_MCMS_ACTION_TRANSFER_PR_CR); XMC_STRUCT_INIT(slice_config); slice_config.prescaler_initval = divider; XMC_CCU4_SLICE_CompareInit(CCU40_CC40, &slice_config); slice_config.timer_concatenation = true; XMC_CCU4_SLICE_CompareInit(CCU40_CC41, &slice_config); XMC_CCU4_SLICE_SetTimerPeriodMatch(CCU40_CC40, 0xffffU); XMC_CCU4_SLICE_SetTimerPeriodMatch(CCU40_CC41, 0xffffU); // Configure event to start synchronously the two slices XMC_CCU4_SLICE_ConfigureEvent(CCU40_CC40, XMC_CCU4_SLICE_EVENT_0, &event_config); XMC_CCU4_SLICE_ConfigureEvent(CCU40_CC41, XMC_CCU4_SLICE_EVENT_0, &event_config); XMC_CCU4_SLICE_StartConfig(CCU40_CC40, XMC_CCU4_SLICE_EVENT_0, XMC_CCU4_SLICE_START_MODE_TIMER_START); XMC_CCU4_SLICE_StartConfig(CCU40_CC41, XMC_CCU4_SLICE_EVENT_0, XMC_CCU4_SLICE_START_MODE_TIMER_START); // Configure event to stop synchronously the two slices event_config.edge = XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_FALLING_EDGE; XMC_CCU4_SLICE_ConfigureEvent(CCU40_CC40, XMC_CCU4_SLICE_EVENT_1, &event_config); XMC_CCU4_SLICE_ConfigureEvent(CCU40_CC41, XMC_CCU4_SLICE_EVENT_1, &event_config); XMC_CCU4_SLICE_StopConfig(CCU40_CC40, XMC_CCU4_SLICE_EVENT_1, XMC_CCU4_SLICE_END_MODE_TIMER_STOP); XMC_CCU4_SLICE_StopConfig(CCU40_CC41, XMC_CCU4_SLICE_EVENT_1, XMC_CCU4_SLICE_END_MODE_TIMER_STOP); // Assign interrupt node and set priority XMC_CCU4_SLICE_SetInterruptNode(CCU40_CC41, XMC_CCU4_SLICE_IRQ_ID_COMPARE_MATCH_UP, XMC_CCU4_SLICE_SR_ID_0); NVIC_SetPriority(CCU40_0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 63, 0)); NVIC_EnableIRQ(CCU40_0_IRQn); // Enable clock to both slices XMC_CCU4_EnableClock(CCU40, (uint8_t)0); XMC_CCU4_EnableClock(CCU40, (uint8_t)1); } void TIMER_Start(uint32_t ticks) { XMC_CCU4_SLICE_SetTimerCompareMatch(CCU40_CC40, ticks & 0xffffU); XMC_CCU4_SLICE_SetTimerCompareMatch(CCU40_CC41, ticks >> 16U); XMC_CCU4_EnableShadowTransfer(CCU40, XMC_CCU4_SHADOW_TRANSFER_SLICE_0 | XMC_CCU4_SHADOW_TRANSFER_SLICE_1); XMC_CCU4_SLICE_EnableEvent(CCU40_CC41, XMC_CCU4_SLICE_IRQ_ID_COMPARE_MATCH_UP); /* Synchronous start of CCU4x timer slices */ XMC_SCU_SetCcuTriggerHigh(XMC_SCU_CCU_TRIGGER_CCU40); } void TIMER_Stop(void) { XMC_CCU4_SLICE_DisableEvent(CCU40_CC41, XMC_CCU4_SLICE_IRQ_ID_COMPARE_MATCH_UP); /* Synchronous stop of CCU4x timer slices */ XMC_SCU_SetCcuTriggerLow(XMC_SCU_CCU_TRIGGER_CCU40); } void TIMER_Clear() { XMC_CCU4_SLICE_ClearTimer(CCU40_CC40); XMC_CCU4_SLICE_ClearTimer(CCU40_CC41); } uint32_t TIMER_GetTime(void) { uint32_t time_h = XMC_CCU4_SLICE_GetTimerValue(CCU40_CC41); uint32_t time_l = XMC_CCU4_SLICE_GetTimerValue(CCU40_CC40); while (XMC_CCU4_SLICE_GetTimerValue(CCU40_CC41) != time_h) { time_h = XMC_CCU4_SLICE_GetTimerValue(CCU40_CC41); time_l = XMC_CCU4_SLICE_GetTimerValue(CCU40_CC40); } return ((time_h << 16) | time_l); }