USB device stack

Dependents:   USBMSD_step1 USBMSD_step1_5 picossd_step1_2cs

Committer:
muraguchi
Date:
Wed Sep 15 16:31:51 2021 +0000
Revision:
73:72808bd55ce2
Parent:
71:53949e6131f6
AirioBase + 2 chip PicoSSD board

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 ) */