a
Fork of USBDevice by
Diff: USBDevice/TARGET_Silicon_Labs/src/em_usbtimer.c
- Revision:
- 71:53949e6131f6
- Parent:
- 70:2c525a50f1b6
--- a/USBDevice/TARGET_Silicon_Labs/src/em_usbtimer.c Thu Jul 20 10:14:36 2017 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,381 +0,0 @@
-/***************************************************************************//**
- * @file em_usbtimer.c
- * @brief USB protocol stack library, timer API.
- * @version 3.20.14
- *******************************************************************************
- * @section License
- * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
- *******************************************************************************
- * 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 "em_device.h"
-#if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
-#include "em_usb.h"
-#if defined( USB_DEVICE ) || defined( USB_HOST )
-#include "em_cmu.h"
-#include "em_timer.h"
-#include "em_usbtypes.h"
-#include "em_usbhal.h"
-
-#include "device_peripherals.h"
-
-/*
- * Use one HW timer to serve n software milisecond timers.
- * A timer is, when running, in a linked list of timers.
- * A given timers timeout period is the acculmulated timeout
- * of all timers preceeding it in the queue.
- * This makes timer start (linked list insertion) computing intensive,
- * but the checking of the queue at each tick very effective.
- * ______ ______ ______
- * | | --->| | --->| |
- * head --> | | | | | | | |
- * |______|--- |______|--- |______|---/ NULL
- */
-
-/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
-
-#ifndef USB_TIMER
-#error HW platform must define the timer to use for USB
-#endif
-
-#if ( USB_TIMER == USB_TIMER0 ) && ( TIMER_COUNT >= 1 )
- #define TIMER TIMER0
- #define TIMER_CLK cmuClock_TIMER0
- #define TIMER_IRQ TIMER0_IRQn
- #define TIMER_IRQHandler TIMER0_IRQHandler
-
-#elif ( USB_TIMER == USB_TIMER1 ) && ( TIMER_COUNT >= 2 )
- #define TIMER TIMER1
- #define TIMER_CLK cmuClock_TIMER1
- #define TIMER_IRQ TIMER1_IRQn
- #define TIMER_IRQHandler TIMER1_IRQHandler
-
-#elif ( USB_TIMER == USB_TIMER2 ) && ( TIMER_COUNT >= 3 )
- #define TIMER TIMER2
- #define TIMER_CLK cmuClock_TIMER2
- #define TIMER_IRQ TIMER2_IRQn
- #define TIMER_IRQHandler TIMER2_IRQHandler
-
-#elif ( USB_TIMER == USB_TIMER3 ) && ( TIMER_COUNT == 4 )
- #define TIMER TIMER3
- #define TIMER_CLK cmuClock_TIMER3
- #define TIMER_IRQ TIMER3_IRQn
- #define TIMER_IRQHandler TIMER3_IRQHandler
-
-#else
-#error "Illegal USB TIMER definition"
-#endif
-
-typedef struct _timer
-{
- uint32_t timeout; /* Delta value relative to prev. timer */
- struct _timer *next;
- USBTIMER_Callback_TypeDef callback;
- bool running;
-} USBTIMER_Timer_TypeDef;
-
-#if ( NUM_QTIMERS > 0 )
-static USBTIMER_Timer_TypeDef timers[ NUM_QTIMERS ];
-static USBTIMER_Timer_TypeDef *head = NULL;
-#endif
-
-static uint32_t ticksPrMs, ticksPr1us, ticksPr10us, ticksPr100us;
-
-#if ( NUM_QTIMERS > 0 )
-
-static void TimerTick( void );
-
-void TIMER_IRQHandler( void )
-{
- uint32_t flags;
-
- flags = TIMER_IntGet( TIMER );
-
- if ( flags & TIMER_IF_CC0 )
- {
- TIMER_IntClear( TIMER, TIMER_IFC_CC0 );
- TIMER_CompareSet( TIMER, 0, TIMER_CaptureGet( TIMER, 0 ) + ticksPrMs );
- TimerTick();
- }
-}
-#endif /* ( NUM_QTIMERS > 0 ) */
-
-static void DelayTicks( uint16_t ticks )
-{
- uint16_t startTime;
- volatile uint16_t now;
-
- if ( ticks )
- {
- startTime = TIMER_CounterGet( TIMER );
- do
- {
- now = TIMER_CounterGet(TIMER);
- } while ( (uint16_t)( now - startTime ) < ticks );
- }
-}
-
-/** @endcond */
-
-/** @addtogroup USB_COMMON
- * @{*/
-
-/***************************************************************************//**
- * @brief
- * Active wait millisecond delay function. Can also be used inside
- * interrupt handlers.
- *
- * @param[in] msec
- * Number of milliseconds to wait.
- ******************************************************************************/
-void USBTIMER_DelayMs( uint32_t msec )
-{
- uint64_t totalTicks;
-
- totalTicks = (uint64_t)ticksPrMs * msec;
- while ( totalTicks > 20000 )
- {
- DelayTicks( 20000 );
- totalTicks -= 20000;
- }
- DelayTicks( (uint16_t)totalTicks );
-}
-
-/***************************************************************************//**
- * @brief
- * Active wait microsecond delay function. Can also be used inside
- * interrupt handlers.
- *
- * @param[in] usec
- * Number of microseconds to wait.
- ******************************************************************************/
-void USBTIMER_DelayUs( uint32_t usec )
-{
- uint64_t totalTicks;
-
- totalTicks = (uint64_t)ticksPr1us * usec;
- if ( totalTicks == 0 )
- {
- usec /= 10;
- totalTicks = (uint64_t)ticksPr10us * usec;
-
- if ( totalTicks == 0 )
- {
- usec /= 10;
- totalTicks = (uint64_t)ticksPr100us * usec;
- }
- }
-
- while ( totalTicks > 60000 )
- {
- DelayTicks( 60000 );
- totalTicks -= 60000;
- }
- DelayTicks( (uint16_t)totalTicks );
-}
-
-/***************************************************************************//**
- * @brief
- * Activate the hardware timer used to pace the 1 millisecond timer system.
- *
- * @details
- * Call this function whenever the HFPERCLK frequency is changed.
- * This function is initially called by HOST and DEVICE stack xxxx_Init()
- * functions.
- ******************************************************************************/
-void USBTIMER_Init( void )
-{
- uint32_t freq;
- TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
- TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT;
-
- freq = CMU_ClockFreqGet( cmuClock_HFPER );
- ticksPrMs = ( freq + 500 ) / 1000;
- ticksPr1us = ( freq + 500000 ) / 1000000;
- ticksPr10us = ( freq + 50000 ) / 100000;
- ticksPr100us = ( freq + 5000 ) / 10000;
-
- timerCCInit.mode = timerCCModeCompare;
- CMU_ClockEnable( TIMER_CLK, true );
- TIMER_TopSet( TIMER, 0xFFFF );
- TIMER_InitCC( TIMER, 0, &timerCCInit );
- TIMER_Init( TIMER, &timerInit );
-
-#if ( NUM_QTIMERS > 0 )
- TIMER_IntClear( TIMER, 0xFFFFFFFF );
- TIMER_IntEnable( TIMER, TIMER_IEN_CC0 );
- TIMER_CompareSet( TIMER, 0, TIMER_CounterGet( TIMER ) + ticksPrMs );
- NVIC_ClearPendingIRQ( TIMER_IRQ );
- NVIC_EnableIRQ( TIMER_IRQ );
-#endif /* ( NUM_QTIMERS > 0 ) */
-}
-
-#if ( NUM_QTIMERS > 0 ) || defined( DOXY_DOC_ONLY )
-/***************************************************************************//**
- * @brief
- * Start a timer.
- *
- * @details
- * If the timer is already running, it will be restarted with new timeout.
- *
- * @param[in] id
- * Timer id (0..).
- *
- * @param[in] timeout
- * Number of milliseconds before timer will elapse.
- *
- * @param[in] callback
- * Function to be called on timer elapse, ref. @ref USBTIMER_Callback_TypeDef.
- ******************************************************************************/
-void USBTIMER_Start( uint32_t id, uint32_t timeout,
- USBTIMER_Callback_TypeDef callback )
-{
- uint32_t accumulated;
- USBTIMER_Timer_TypeDef *this, **last;
-
- INT_Disable();
-
- if ( timers[ id ].running )
- {
- USBTIMER_Stop( id );
- }
-
- if ( timeout == 0 )
- {
- callback();
- INT_Enable();
- return;
- }
-
- timers[ id ].running = true;
- timers[ id ].callback = callback;
- timers[ id ].next = NULL;
-
- if ( !head ) /* Queue empty ? */
- {
- timers[ id ].timeout = timeout;
- head = &timers[ id ];
- }
- else
- {
- this = head;
- last = &head;
- accumulated = 0;
-
- /* Do a sorted insert */
- while ( this )
- {
- if ( timeout < accumulated + this->timeout ) /* Insert before "this" ? */
- {
- timers[ id ].timeout = timeout - accumulated;
- timers[ id ].next = this;
- *last = &timers[ id ];
- this->timeout -= timers[ id ].timeout; /* Adjust timeout */
- break;
- }
- else if ( this->next == NULL ) /* At end of queue ? */
- {
- timers[ id ].timeout = timeout - accumulated - this->timeout;
- this->next = &timers[ id ];
- break;
- }
- accumulated += this->timeout;
- last = &this->next;
- this = this->next;
- }
- }
-
- INT_Enable();
-}
-
-/***************************************************************************//**
- * @brief
- * Stop a timer.
- *
- * @param[in] id
- * Timer id (0..).
- ******************************************************************************/
-void USBTIMER_Stop( uint32_t id )
-{
- USBTIMER_Timer_TypeDef *this, **last;
-
- INT_Disable();
-
- if ( head ) /* Queue empty ? */
- {
- this = head;
- last = &head;
- timers[ id ].running = false;
-
- while ( this )
- {
- if ( this == &timers[ id ] ) /* Correct timer ? */
- {
- if ( this->next )
- {
- this->next->timeout += timers[ id ].timeout; /* Adjust timeout */
- }
- *last = this->next;
- break;
- }
- last = &this->next;
- this = this->next;
- }
- }
-
- INT_Enable();
-}
-#endif /* ( NUM_QTIMERS > 0 ) */
-
-/** @} (end addtogroup USB_COMMON) */
-
-#if ( NUM_QTIMERS > 0 )
-/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
-
-static void TimerTick( void )
-{
- USBTIMER_Callback_TypeDef cb;
-
- INT_Disable();
-
- if ( head )
- {
- head->timeout--;
-
- while ( head )
- {
- if ( head->timeout == 0 )
- {
- cb = head->callback;
- head->running = false;
- head = head->next;
- /* The callback may place new items in the queue !!! */
- if ( cb )
- {
- (cb)();
- }
- continue; /* There might be more than one timeout pr. tick */
- }
- break;
- }
- }
-
- INT_Enable();
-}
-/** @endcond */
-#endif /* ( NUM_QTIMERS > 0 ) */
-
-#endif /* defined( USB_DEVICE ) || defined( USB_HOST ) */
-#endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */
