USBDevice for STM support

Dependents:   Nucleo_Usb_JoyMouse Nucleo_usbmouse ELEC350_1-referral-2018-usb-hid USBJoystick_HelloWorld2_wip ... more

This library contains all mbed usb device library (mbed-os\features\unsupported\USBDevice).

Committer:
frq08711@LMECWL0871.LME.ST.COM
Date:
Tue Mar 28 11:00:57 2017 +0200
Branch:
master
Revision:
4:50ec00aa4515
Parent:
1:2a3ae13b45ef
update for 5.4.2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 1 /***************************************************************************//**
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 2 * @file em_usbtimer.c
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 3 * @brief USB protocol stack library, timer API.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 4 * @version 3.20.14
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 5 *******************************************************************************
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 6 * @section License
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 7 * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 8 *******************************************************************************
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 9 * Licensed under the Apache License, Version 2.0 (the "License");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 10 * you may not use this file except in compliance with the License.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 11 * You may obtain a copy of the License at
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 12 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 13 * http://www.apache.org/licenses/LICENSE-2.0
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 14 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 15 * Unless required by applicable law or agreed to in writing, software
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 16 * distributed under the License is distributed on an "AS IS" BASIS,
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 18 * See the License for the specific language governing permissions and
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 19 * limitations under the License.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 20 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 21 ******************************************************************************/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 22
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 23 #include "em_device.h"
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 24 #if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 25 #include "em_usb.h"
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 26 #if defined( USB_DEVICE ) || defined( USB_HOST )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 27 #include "em_cmu.h"
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 28 #include "em_timer.h"
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 29 #include "em_usbtypes.h"
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 30 #include "em_usbhal.h"
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 31
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 32 #include "device_peripherals.h"
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 33
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 34 /*
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 35 * Use one HW timer to serve n software milisecond timers.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 36 * A timer is, when running, in a linked list of timers.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 37 * A given timers timeout period is the acculmulated timeout
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 38 * of all timers preceeding it in the queue.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 39 * This makes timer start (linked list insertion) computing intensive,
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 40 * but the checking of the queue at each tick very effective.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 41 * ______ ______ ______
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 42 * | | --->| | --->| |
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 43 * head --> | | | | | | | |
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 44 * |______|--- |______|--- |______|---/ NULL
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 45 */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 46
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 47 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 48
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 49 #ifndef USB_TIMER
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 50 #error HW platform must define the timer to use for USB
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 51 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 52
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 53 #if ( USB_TIMER == USB_TIMER0 ) && ( TIMER_COUNT >= 1 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 54 #define TIMER TIMER0
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 55 #define TIMER_CLK cmuClock_TIMER0
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 56 #define TIMER_IRQ TIMER0_IRQn
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 57 #define TIMER_IRQHandler TIMER0_IRQHandler
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 58
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 59 #elif ( USB_TIMER == USB_TIMER1 ) && ( TIMER_COUNT >= 2 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 60 #define TIMER TIMER1
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 61 #define TIMER_CLK cmuClock_TIMER1
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 62 #define TIMER_IRQ TIMER1_IRQn
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 63 #define TIMER_IRQHandler TIMER1_IRQHandler
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 64
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 65 #elif ( USB_TIMER == USB_TIMER2 ) && ( TIMER_COUNT >= 3 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 66 #define TIMER TIMER2
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 67 #define TIMER_CLK cmuClock_TIMER2
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 68 #define TIMER_IRQ TIMER2_IRQn
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 69 #define TIMER_IRQHandler TIMER2_IRQHandler
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 70
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 71 #elif ( USB_TIMER == USB_TIMER3 ) && ( TIMER_COUNT == 4 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 72 #define TIMER TIMER3
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 73 #define TIMER_CLK cmuClock_TIMER3
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 74 #define TIMER_IRQ TIMER3_IRQn
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 75 #define TIMER_IRQHandler TIMER3_IRQHandler
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 76
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 77 #else
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 78 #error "Illegal USB TIMER definition"
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 79 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 80
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 81 typedef struct _timer
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 82 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 83 uint32_t timeout; /* Delta value relative to prev. timer */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 84 struct _timer *next;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 85 USBTIMER_Callback_TypeDef callback;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 86 bool running;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 87 } USBTIMER_Timer_TypeDef;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 88
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 89 #if ( NUM_QTIMERS > 0 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 90 static USBTIMER_Timer_TypeDef timers[ NUM_QTIMERS ];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 91 static USBTIMER_Timer_TypeDef *head = NULL;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 92 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 93
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 94 static uint32_t ticksPrMs, ticksPr1us, ticksPr10us, ticksPr100us;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 95
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 96 #if ( NUM_QTIMERS > 0 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 97
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 98 static void TimerTick( void );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 99
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 100 void TIMER_IRQHandler( void )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 101 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 102 uint32_t flags;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 103
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 104 flags = TIMER_IntGet( TIMER );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 105
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 106 if ( flags & TIMER_IF_CC0 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 107 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 108 TIMER_IntClear( TIMER, TIMER_IFC_CC0 );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 109 TIMER_CompareSet( TIMER, 0, TIMER_CaptureGet( TIMER, 0 ) + ticksPrMs );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 110 TimerTick();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 111 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 112 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 113 #endif /* ( NUM_QTIMERS > 0 ) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 114
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 115 static void DelayTicks( uint16_t ticks )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 116 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 117 uint16_t startTime;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 118 volatile uint16_t now;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 119
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 120 if ( ticks )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 121 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 122 startTime = TIMER_CounterGet( TIMER );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 123 do
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 124 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 125 now = TIMER_CounterGet(TIMER);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 126 } while ( (uint16_t)( now - startTime ) < ticks );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 127 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 128 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 129
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 130 /** @endcond */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 131
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 132 /** @addtogroup USB_COMMON
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 133 * @{*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 134
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 135 /***************************************************************************//**
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 136 * @brief
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 137 * Active wait millisecond delay function. Can also be used inside
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 138 * interrupt handlers.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 139 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 140 * @param[in] msec
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 141 * Number of milliseconds to wait.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 142 ******************************************************************************/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 143 void USBTIMER_DelayMs( uint32_t msec )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 144 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 145 uint64_t totalTicks;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 146
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 147 totalTicks = (uint64_t)ticksPrMs * msec;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 148 while ( totalTicks > 20000 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 149 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 150 DelayTicks( 20000 );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 151 totalTicks -= 20000;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 152 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 153 DelayTicks( (uint16_t)totalTicks );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 154 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 155
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 156 /***************************************************************************//**
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 157 * @brief
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 158 * Active wait microsecond delay function. Can also be used inside
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 159 * interrupt handlers.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 160 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 161 * @param[in] usec
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 162 * Number of microseconds to wait.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 163 ******************************************************************************/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 164 void USBTIMER_DelayUs( uint32_t usec )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 165 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 166 uint64_t totalTicks;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 167
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 168 totalTicks = (uint64_t)ticksPr1us * usec;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 169 if ( totalTicks == 0 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 170 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 171 usec /= 10;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 172 totalTicks = (uint64_t)ticksPr10us * usec;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 173
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 174 if ( totalTicks == 0 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 175 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 176 usec /= 10;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 177 totalTicks = (uint64_t)ticksPr100us * usec;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 178 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 179 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 180
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 181 while ( totalTicks > 60000 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 182 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 183 DelayTicks( 60000 );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 184 totalTicks -= 60000;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 185 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 186 DelayTicks( (uint16_t)totalTicks );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 187 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 188
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 189 /***************************************************************************//**
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 190 * @brief
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 191 * Activate the hardware timer used to pace the 1 millisecond timer system.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 192 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 193 * @details
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 194 * Call this function whenever the HFPERCLK frequency is changed.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 195 * This function is initially called by HOST and DEVICE stack xxxx_Init()
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 196 * functions.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 197 ******************************************************************************/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 198 void USBTIMER_Init( void )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 199 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 200 uint32_t freq;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 201 TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 202 TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 203
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 204 freq = CMU_ClockFreqGet( cmuClock_HFPER );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 205 ticksPrMs = ( freq + 500 ) / 1000;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 206 ticksPr1us = ( freq + 500000 ) / 1000000;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 207 ticksPr10us = ( freq + 50000 ) / 100000;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 208 ticksPr100us = ( freq + 5000 ) / 10000;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 209
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 210 timerCCInit.mode = timerCCModeCompare;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 211 CMU_ClockEnable( TIMER_CLK, true );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 212 TIMER_TopSet( TIMER, 0xFFFF );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 213 TIMER_InitCC( TIMER, 0, &timerCCInit );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 214 TIMER_Init( TIMER, &timerInit );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 215
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 216 #if ( NUM_QTIMERS > 0 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 217 TIMER_IntClear( TIMER, 0xFFFFFFFF );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 218 TIMER_IntEnable( TIMER, TIMER_IEN_CC0 );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 219 TIMER_CompareSet( TIMER, 0, TIMER_CounterGet( TIMER ) + ticksPrMs );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 220 NVIC_ClearPendingIRQ( TIMER_IRQ );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 221 NVIC_EnableIRQ( TIMER_IRQ );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 222 #endif /* ( NUM_QTIMERS > 0 ) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 223 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 224
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 225 #if ( NUM_QTIMERS > 0 ) || defined( DOXY_DOC_ONLY )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 226 /***************************************************************************//**
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 227 * @brief
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 228 * Start a timer.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 229 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 230 * @details
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 231 * If the timer is already running, it will be restarted with new timeout.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 232 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 233 * @param[in] id
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 234 * Timer id (0..).
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 235 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 236 * @param[in] timeout
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 237 * Number of milliseconds before timer will elapse.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 238 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 239 * @param[in] callback
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 240 * Function to be called on timer elapse, ref. @ref USBTIMER_Callback_TypeDef.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 241 ******************************************************************************/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 242 void USBTIMER_Start( uint32_t id, uint32_t timeout,
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 243 USBTIMER_Callback_TypeDef callback )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 244 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 245 uint32_t accumulated;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 246 USBTIMER_Timer_TypeDef *this, **last;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 247
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 248 INT_Disable();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 249
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 250 if ( timers[ id ].running )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 251 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 252 USBTIMER_Stop( id );
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 253 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 254
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 255 if ( timeout == 0 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 256 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 257 callback();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 258 INT_Enable();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 259 return;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 260 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 261
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 262 timers[ id ].running = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 263 timers[ id ].callback = callback;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 264 timers[ id ].next = NULL;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 265
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 266 if ( !head ) /* Queue empty ? */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 267 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 268 timers[ id ].timeout = timeout;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 269 head = &timers[ id ];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 270 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 271 else
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 272 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 273 this = head;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 274 last = &head;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 275 accumulated = 0;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 276
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 277 /* Do a sorted insert */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 278 while ( this )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 279 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 280 if ( timeout < accumulated + this->timeout ) /* Insert before "this" ? */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 281 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 282 timers[ id ].timeout = timeout - accumulated;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 283 timers[ id ].next = this;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 284 *last = &timers[ id ];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 285 this->timeout -= timers[ id ].timeout; /* Adjust timeout */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 286 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 287 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 288 else if ( this->next == NULL ) /* At end of queue ? */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 289 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 290 timers[ id ].timeout = timeout - accumulated - this->timeout;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 291 this->next = &timers[ id ];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 292 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 293 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 294 accumulated += this->timeout;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 295 last = &this->next;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 296 this = this->next;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 297 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 298 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 299
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 300 INT_Enable();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 301 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 302
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 303 /***************************************************************************//**
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 304 * @brief
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 305 * Stop a timer.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 306 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 307 * @param[in] id
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 308 * Timer id (0..).
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 309 ******************************************************************************/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 310 void USBTIMER_Stop( uint32_t id )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 311 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 312 USBTIMER_Timer_TypeDef *this, **last;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 313
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 314 INT_Disable();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 315
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 316 if ( head ) /* Queue empty ? */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 317 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 318 this = head;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 319 last = &head;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 320 timers[ id ].running = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 321
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 322 while ( this )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 323 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 324 if ( this == &timers[ id ] ) /* Correct timer ? */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 325 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 326 if ( this->next )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 327 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 328 this->next->timeout += timers[ id ].timeout; /* Adjust timeout */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 329 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 330 *last = this->next;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 331 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 332 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 333 last = &this->next;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 334 this = this->next;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 335 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 336 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 337
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 338 INT_Enable();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 339 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 340 #endif /* ( NUM_QTIMERS > 0 ) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 341
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 342 /** @} (end addtogroup USB_COMMON) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 343
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 344 #if ( NUM_QTIMERS > 0 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 345 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 346
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 347 static void TimerTick( void )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 348 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 349 USBTIMER_Callback_TypeDef cb;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 350
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 351 INT_Disable();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 352
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 353 if ( head )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 354 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 355 head->timeout--;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 356
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 357 while ( head )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 358 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 359 if ( head->timeout == 0 )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 360 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 361 cb = head->callback;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 362 head->running = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 363 head = head->next;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 364 /* The callback may place new items in the queue !!! */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 365 if ( cb )
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 366 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 367 (cb)();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 368 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 369 continue; /* There might be more than one timeout pr. tick */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 370 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 371 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 372 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 373 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 374
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 375 INT_Enable();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 376 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 377 /** @endcond */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 378 #endif /* ( NUM_QTIMERS > 0 ) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 379
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 380 #endif /* defined( USB_DEVICE ) || defined( USB_HOST ) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 381 #endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */