USB device stack

Dependents:   USBMSD_step1 USBMSD_step1_5 picossd_step1_2cs

Committer:
Kojto
Date:
Thu Jul 27 12:14:04 2017 +0100
Revision:
71:53949e6131f6
Update libraries

Fixes the previous commmit, as some devices were not copied. USBDevice contains
now targets directory with all targets implementations

Who changed what in which revision?

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