I changed one line of code in the file with path name: USBDeviceHT/targets/TARGET_Maxim

Fork of USBDeviceHT by Helmut Tschemernjak

Committer:
Helmut64
Date:
Mon Feb 05 10:22:57 2018 +0000
Revision:
0:a3ea811f80f2
Inital checkin after copied from mbed.

Who changed what in which revision?

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