/**************************************************************************//** * @brief * Callback function called each time the USB device state is changed. * Starts keyboard scanning when device has been configured by USB host. * * @param[in] oldState The device state the device has just left. * @param[in] newState The new device state. *****************************************************************************/ static void StateChange(USBD_State_TypeDef oldState, USBD_State_TypeDef newState) { /* Call HIDKBD drivers state change event handler. */ HIDKBD_StateChangeEvent( oldState, newState ); if ( newState == USBD_STATE_CONFIGURED ) { /* We have been configured, start scanning the keyboard ! */ if ( oldState != USBD_STATE_SUSPENDED ) /* Resume ? */ { keySeqNo = 0; keyPushed = false; } USBTIMER_Start( SCAN_TIMER, SCAN_RATE, ScanTimeout ); } else if ( ( oldState == USBD_STATE_CONFIGURED ) && ( newState != USBD_STATE_SUSPENDED ) ) { /* We have been de-configured, stop keyboard scanning. */ USBTIMER_Stop( SCAN_TIMER ); } else if ( newState == USBD_STATE_SUSPENDED ) { /* We have been suspended, stop keyboard scanning. */ /* Reduce current consumption to below 2.5 mA. */ USBTIMER_Stop( SCAN_TIMER ); } }
/***************************************************************************//** * @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 * Flush pending media writes. *****************************************************************************/ void MSDDMEDIA_Flush( void ) { #if ( MSD_MEDIA == MSD_FLASH_MEDIA ) || ( MSD_MEDIA == MSD_NORFLASH_MEDIA ) if ( flashStatus.pendingWrite ) { flashStatus.pendingWrite = false; USBTIMER_Stop( FLUSH_TIMER_ID ); FlushFlash(); } #endif }