UINT fnTimerThreadProc( zPVOID p ) { ZTimer *pZTimer = (ZTimer *) p; HWND hWnd = pZTimer->m_hWnd; zUSHORT uInterval = (zUSHORT) pZTimer->m_lInterval; // DWORD dwStart = GetTickCount( ); // Stop if this has taken too long // if( GetTickCount() - dwStart >= TIMELIMIT ) // Cancel(); #ifdef DEBUG_ALL TraceLineI( "Starting Thread: ", (zLONG) AfxGetThread( ) ); #endif while ( mIs_hWnd( hWnd ) && pZTimer->m_bEnabled ) { SysWait( uInterval ); if ( mIs_hWnd( hWnd ) ) ProcessImmediateEvent( pZTimer, 1, 0 ); } #ifdef DEBUG_ALL TraceLineI( "All Done!!! Exiting Thread: ", (zLONG) AfxGetThread( ) ); #endif if ( mIs_hWnd( hWnd ) ) pZTimer->m_pThread = 0; return( 0 ); } // fnTimerThreadProc
void pIoDelete ( struct MqIoS ** const ioP ) { if (unlikely(ioP == NULL || *ioP == NULL)) { return; // nothing to do } else { struct MqIoS const * const io = *ioP; struct MqS const * const context = io->context; // ... if (MQ_IS_PARENT (context)) { // wait for started thread because to exit ithe main process image will // exit the thread too, and the thread propably has no chance for // proper cleanup -> this is only used in FILTER mode SysWait (MQ_ERROR_IGNORE, &io->id); // drop event pEventDelete (context); // cleanup the io data switch (io->config->com) { #if defined(MQ_IS_POSIX) case MQ_IO_UDS: UdsDelete ((struct UdsS **) & io->iocom); break; #endif case MQ_IO_TCP: TcpDelete ((struct TcpS **) & io->iocom); break; case MQ_IO_PIPE: PipeDelete ((struct PipeS **) & io->iocom); break; } } MqSysFree (*ioP); return; } }
void _reentrant USBInsertionMonitorTask(void) { USHORT usStatus; BOOL bInserted = FALSE; WORD i,j; WORD iWaitCount; // Check for USB disconnect while(1) { usb_device_get_status(USB_STATUS_CONNECTION,&usStatus); switch(usStatus) { case USB_CONNECTED: bInserted=TRUE; break; default: if(bInserted)//if we've been inserted, and now we're not, lets shut down { // #ifdef DEVICE_3410 // 3410 still has power when removed from usb. #ifdef CHKDSK UsbMscCheckDiskAll(); #endif // #endif // TODO - put this back in later if needed // Clear the display // ClearDisplay(); // We need to immediately pull Write Protect low to protect the NANDs and // to reset the Renesas part (same line). HW_GPFLASH_CSR1R.B.WP0 = 0; // We need to clean up any media transactions that may be hanging // As best we can :) // stmp4770 and stmp4795, Remove drive flush on USB disconnect for NAND devices. // Drive flush still necessary for MMC media, to properly close multi-writes // that may be pending between SCSI commands. for(i=0;i<g_wUsbMscNumDevices;i++) { for(j=0;j<UsbMscDevice[i].wNumLunsSupported;j++) { if(UsbMscDevice[i].Lun[j].bMediaIsRemovable == TRUE) { DriveFlush(UsbMscDevice[i].Lun[j].wFileSystemDriveNumber); } } } //Do not leave. Wait for 5V to be removed. //Monitor D+/- and reset if it returns. HW_USBCSR.B.PLUGGEDIN_EN = 1; iWaitCount = 0; //ensure 5V Disconnect IRQ is enabled SysSetIrqLevel(HW_SR_IM_L2_SETMASK); while(HW_USBCSR.B.VBUSSENSE) { //if USB is plugged-in. Break loop and reset to return to USBMSC. if(HW_USBCSR.B.PLUGGEDIN) { break; } //wait a bit SysWait(200); if(iWaitCount > 10) { break; // if we waited a couple secs, time to break } else { iWaitCount++; //increment wait count } } SysWait(200); // Shut down SystemShutdown(); // Reset the device SystemReset(); } } SysWait(USB_WATCH_CALL_BACK_DELAY); } }
///////////////////////////////////////////////////////////////////////////////////////// // //> Name: BatteryChargeStateMachineNormal // // Type: State Function // // Description: Call the appropriate functions (BatteryChargeImplementationSample and // BatteryChargeImplementationGetCurrentLimit) // // Inputs: wCounter--ignored // // Outputs: next state in the state machine: // BATTERY_CHARGE_WAIT_FOR_5V // BATTERY_CHARGE_NORMAL // // Notes: //< ////////////////////////////////////////////////////////////////////////////////////////// _reentrant WORD BatteryChargeStateMachineNormal(WORD wCounter) { WORD wCurrentLimit; WORD wBitfield; WORD wBatteryCurrentReading; int i; WORD wReturn; if(wCounter>POWER_OFF_FREQUENCY) { //this will go to the state that will turn off the charging until //5v is inserted. wReturn = BATTERY_CHARGE_WAIT_FOR_5V; } else { BatteryChargeImplementationSample(wCounter);//wCounter will be zero (false) for the first time //this will let us sample once when the charging is off wCurrentLimit = BatteryChargeImplementatonGetCurrentLimit(); wBitfield = 0; if(wCurrentLimit && g_bBatteryChargeEnabled) { //Grab the actual current setting. wBatteryCurrentReading = HW_VDD5V_PWR_CHARGE.B.BATT_CURRENT; //Determine which bits to set to reach desired battery charge current. for(i=0;i<5;i++) { if (wCurrentLimit >= BATT_CURRENT_BITS[i][0]) { wCurrentLimit -= BATT_CURRENT_BITS[i][0]; wBitfield |= BATT_CURRENT_BITS[i][1]; } } //Update current bitfield if required. if(wBatteryCurrentReading != wBitfield) { //step up the charging to prevent large current spikes on USB. //step to 100mA, 200mA, and then step to final current setting. if(wBitfield > HW_VDD5V_PWR_CHARGE_BATT_CURRENT_100MA) { HW_VDD5V_PWR_CHARGE.B.BATT_CURRENT=HW_VDD5V_PWR_CHARGE_BATT_CURRENT_100MA; //set to 100mA HW_VDD5V_PWR_CHARGE.B.PWD = FALSE; #ifdef STMP_BUILD_PLAYER SysWaitOnEvent(0,0,1); //wait to settle #else SysWait(1); #endif } //step to 200mA if(wBitfield > HW_VDD5V_PWR_CHARGE_BATT_CURRENT_200MA) { HW_VDD5V_PWR_CHARGE.B.BATT_CURRENT=HW_VDD5V_PWR_CHARGE_BATT_CURRENT_200MA; //set to 200mA HW_VDD5V_PWR_CHARGE.B.PWD = FALSE; #ifdef STMP_BUILD_PLAYER SysWaitOnEvent(0,0,1); //wait to settle #else SysWait(1); #endif } HW_VDD5V_PWR_CHARGE.B.PWD = FALSE; HW_VDD5V_PWR_CHARGE.B.BATT_CURRENT=wBitfield; } } wReturn = BATTERY_CHARGE_NORMAL; } return wReturn; }
//#undef FUNCLET //////////////////////////////////////////////////////////////////////////////// // //> Name: ServiceDCDC // // Type: Function // // Description: Service the DCDC converter to prepare for disconnect // // Inputs: none // // Outputs: none // // Notes: none //< //////////////////////////////////////////////////////////////////////////////// ///#ifdef FUNCLET /// #pragma asm /// FServiceDCDC: /// /// nolist /// include "sysmacro.asm" /// include "resource.inc" /// list /// /// ;If using funclet, function will be executed via funclet kernel /// CallFunclet RSRC_FUNCLET_SERVICEDCDC /// /// org p,"RSRC_FUNCLET_SERVICEDCDC_P": /// dc RSRC_FUNCLET_SERVICEDCDC /// #pragma endasm ///void _reentrant ServiceDCDC_Funclet(void) ///#else void _reentrant ServiceDCDC(void) ///#endif { //Only add code if using 5V to DCDC Power Transfer #ifdef DCDC_POWER_TRANSFER INT iBattLevel=0; INT iNLevel=0; if(g_bServiceDCDC) //service DCDC converter if flag is set { if((HW_VDD5V_PWR_CHARGE.B.VDD5V_PRESENT) || (HW_VDD5V_PWR_CHARGE.B.PWDN_ON_IOBRNOUT)) { //Build option to service DCDC based on DCDC Mode (boost or buck) #ifdef BATTERY_TYPE_LI_ION // Open DCDC control loop and set it up to be close to desired target for disconnect. HW_DCDC1_CTRL1.B.R = 9; HW_DCDC1_CTRL1.B.C = 0; HW_DCDC2_CTRL1.B.R = 9; HW_DCDC2_CTRL1.B.C = 0; //Check for Single Channel Buck. DCDCMODE=1 for 100-pin package. DCDCMODE=3 if 144-pin package //is forced to single channel buck if ((HW_REVR.B.DCDCMODE == 0x1)||(HW_REVR.B.DCDCMODE == 0x3)) { // Control loop is in a bad state HW_DCDC1_CTRL0.B.NLEV = 0x1A; SysWait(1); HW_DCDC1_CTRL0.B.NLEV = 0x12; // Ring OSC1 should be around 0x78 at this point g_bServiceDCDC = FALSE; //control loop in a good state; stop service HW_VDD5V_PWR_CHARGE.B.PWDN_ON_IOBRNOUT=0; //Clear PWDN_ON_IOBRNOUT bit } else { // 2 Channel buck mode // Ring OSC2 should be between 0x20 and 0x30 after the loop runs a few times if((HW_SPEED.B.RINGOSC2 < 0x27) || (HW_SPEED.B.RINGOSC2 > 0x30)) { // Control loop is in a bad state HW_DCDC2_CTRL1.B.FFOR = 1; SysWait(1); HW_DCDC2_CTRL1.B.FFOR = 0; } else { g_bServiceDCDC = FALSE; //control loop in a good state; stop service HW_VDD5V_PWR_CHARGE.B.PWDN_ON_IOBRNOUT=0; //Clear PWDN_ON_IOBRNOUT bit HW_DCDC2_CTRL0.B.NLEV = 0x1F; //Now change NLEV to Buck State } // Control loop is in a bad state HW_DCDC1_CTRL0.B.NLEV = 0x1A; SysWait(1); HW_DCDC1_CTRL0.B.NLEV = 0x12; // Ring OSC1 should be around 0x78 at this point } #else //Boost Player // Open DCDC control loop and set it up to be close to desired target for disconnect. HW_DCDC1_CTRL1.B.R = 9; HW_DCDC1_CTRL1.B.C = 0; HW_DCDC2_CTRL1.B.R = 9; HW_DCDC2_CTRL1.B.C = 0; // boost mode //Check the battery level and updated if it has changed. Required for Boost Mode. iBattLevel=HW_BATT_RESULT.B.DATA_OUT; // alter NLEV and return back to step control loop //scale NLEV based on battery voltage. if >1.44 NLEV=06, 1.44V-0.9V NLEV=06 to NLEV=31 iNLevel = 31-(iBattLevel-BOOST_NLEV_BASE_STEP); //assumes HW_BATT_CTRL.I = 0x020200 (steps 46-72) if (iNLevel < 6) iNLevel = 6; else if (iNLevel > 31) iNLevel = 31; HW_DCDC1_CTRL0.B.NLEV = iNLevel; //Control Loop in an open state, clear PWDN_ON_IOBRNOUT bit HW_VDD5V_PWR_CHARGE.B.PWDN_ON_IOBRNOUT=0; // disable battery brownout for case with 5V present and battery removed // ** currently disabled in usbmsc in SDK ** add code if change SDK #endif } else //5V is not connected, close DCDC control loop { //Build option to service DCDC based on DCDC Mode (boost or buck) #ifdef BATTERY_TYPE_LI_ION //close DCDC Control loop HW_DCDC1_CTRL1.B.R = 5; HW_DCDC1_CTRL1.B.C = 4; HW_DCDC2_CTRL1.B.R = 5; HW_DCDC2_CTRL1.B.C = 4; #else //close DCDC Control loop HW_DCDC1_CTRL1.B.R = 3; HW_DCDC1_CTRL1.B.C = 4; HW_DCDC2_CTRL1.B.R = 3; HW_DCDC2_CTRL1.B.C = 4; #endif } } //end g_bServiceDCDC #endif //DCDC_POWER_TRANSFER } //end Check5V
// Function Description: // Inputs: no parameters // Returns: no register returns // Notes: void _reentrant UserInterfaceTask(void) { int iTransferRate; WORD State=SCSI_IDLE; //Message Msg; int iDelay = HALF_SEC_UPDATE_RATE; int Image2Display = 0; BOOL bNeedToReEnable = FALSE; USHORT usStatus; SysPostMessage(5,LCD_CLEAR_RANGE,0,0,98,64); SysPostMessage(5,LCD_PRINT_RANGE_RSRC,0,0,ReadyImage); SysWait(250); while(1) { #ifdef BATTERY_CHARGE //Only charge if we're in high usb current mode. March 11 2005 addition if(usb_get_current_limit() <= 100) //mA { BatteryChargeDisableCharging(TRUE); // until next stmp bootup } else { usb_device_get_status(USB_STATUS, &usStatus); if(usStatus != USB_STATE_CONFIGURED) { if(bNeedToReEnable == FALSE) { BatteryChargeDisableCharging(FALSE); bNeedToReEnable = TRUE; } } else { if(bNeedToReEnable == TRUE) { BatteryChargeEnableCharging(); bNeedToReEnable = FALSE; } BatteryChargeStateMachine(); } } #endif SysWait(UPDATE_RATE); if(State!= g_wActivityState ) { State = g_wActivityState; switch(State) { case SCSI_IDLE: Image2Display = ReadyImage; break; case SCSI_READING: Image2Display = ReadingImage; break; case SCSI_WRITING: Image2Display = WritingImage; break; } if (0 != Image2Display) { SysPostMessage(5,LCD_PRINT_RANGE_RSRC,0,0,Image2Display); } } iTransferRate = g_lBulkInBytes / (1+g_lLastBulkInTime-g_lFirstBulkInTime); SysPostMessage(7,LCD_PRINT_NUMBER,0,16,iTransferRate,5,' '); iTransferRate = g_lBulkOutBytes / (1+g_lLastBulkOutTime-g_lFirstBulkOutTime); SysPostMessage(7,LCD_PRINT_NUMBER,0,24,iTransferRate,5,' '); SysWait(0); SysPostMessage(7,LCD_PRINT_NUMBER, 0,40,g_iCommonCommands,5,' '); SysPostMessage(7,LCD_PRINT_NUMBER,32,40,g_iUpdaterCommands,5,' '); SysPostMessage(7,LCD_PRINT_NUMBER,64,40,g_iUnknownCommands,5,' '); }// end while(1) }
// Function Description: // Inputs: no parameters // Returns: no register returns // Notes: void _reentrant UserInterfaceTask(void) { USHORT usStatus; //int iTransferRate; WORD State=SCSI_IDLE; //Message Msg; int iDelay = HALF_SEC_UPDATE_RATE; BOOL bNeedToReEnable = FALSE; int Write_State_Persisten_Time = WRITE_STATE_PERSISTENT_TIME; int i; for (i=10;i< USER_INTERFACE_STACK_SIZE;i++ ) { g_UserInterfaceStack[i]=0xc0ffee; } Init5VSense(); USBLCDDisplayInit(); SysWait(250); while(1) { #if (NUM_REMOVABLE_MEDIA == 1) // Wait until we have decided whether device is in MTP vs. MSC mode // Media detection uses different code for the two modes if(g_MtpArbitrationDone) { if(MTPDetected) { MtpCheckExternalMedia(); } else { ScsiInsertionRemovalCode(); } } #endif usb_device_get_status(USB_STATUS, &usStatus); if(usStatus == USB_STATE_SUSPENDED) { SysWait(UPDATE_RATE); } else { SysPostMessage(2,LCD_END_FRAME); SysWait(UPDATE_RATE); SysPostMessage(2,LCD_BEGIN_FRAME); USBLCDCheckForTransfers(); if(g_bServiceDCDC) { ServiceDCDC(); //Service DCDC converter } #ifdef BATTERY_CHARGE // For 3500 Battery Monitoring must be done only during battery charging // The rest of the time the system operates from USB +5V // and battery monitoring does not make any sense. // Also, battery brownout always triggered if sys operates w/ no battery. //Only charge if we're in high usb current mode. March 11 2005 addition if(usb_get_current_limit() <= 100) //mA { BatteryChargeDisableCharging(TRUE); // until next stmp bootup } else { if(usStatus != USB_STATE_CONFIGURED) { if(bNeedToReEnable == FALSE) { BatteryChargeDisableCharging(FALSE); bNeedToReEnable = TRUE; } } else { if(bNeedToReEnable == TRUE) { BatteryChargeEnableCharging(); bNeedToReEnable = FALSE; } BatteryChargeStateMachine(); } } #endif #if defined(BATTERY_CHARGE) // I only want to update the Battery icon once per 1/2 second // but always check and average battery level. USBLCDCheckBatteryLevel(); #endif if (iDelay-- <= 0) { #if defined(BATTERY_CHARGE) USBLCDDisplayBatteryLevel(); #endif USBLCDCheckDBStoreDirty(); iDelay = HALF_SEC_UPDATE_RATE; } // g_wActivityState - This global is set by other code to indicate the state of the // system. // Can be set by SCSI code, or MTP code (depending on the connection) // Modification added for MTP/MSC system // In MTP/MSC, MSC uses overlays thus we need to be careful yielding to the kernel for display updates. // This can not be done in the middle of a multi write sequence. // The code was modified and uses the same technique as a monostable device. Each time scsi write is entered // the global g_wActivityStateMultiWrite is set to SCSI_WRITING. This will trigger the monostable for // WRITE_STATE_PERSISTENT_TIME miliseconds. If a new scsi write command arrives prior WRITE_STATE_PERSISTENT_TIME // expires, the new scsi write command re-starts the monostable for a new full WRITE_STATE_PERSISTENT_TIME ms. // Once the monostable time expires without no new SCSI write commands, the state will switch to IDLE and display // will return to the READY state. // The display task has a chance to run everytime a new SCSI write command arrives. There is no display refresh // during mutltiwrites. if((g_wActivityStateMultiWrite == SCSI_WRITING) || (Write_State_Persisten_Time < WRITE_STATE_PERSISTENT_TIME)) { if(g_wActivityStateMultiWrite == SCSI_WRITING) { g_wActivityStateMultiWrite = SCSI_IDLE; Write_State_Persisten_Time = 0; if(State != SCSI_WRITING) { State = SCSI_WRITING; USBLCDWriting(); } } else { Write_State_Persisten_Time += UPDATE_RATE; } } else { if(State!= g_wActivityState ) { State = g_wActivityState; switch(State) { case SCSI_IDLE: USBLCDIdle(); break; case SCSI_READING: USBLCDReading(); break; case SCSI_WRITING: USBLCDWriting(); break; default : USBLCDIdle(); } } } } // end else !suspended { USHORT usStatus; // fixes 8777 (0 or 2 usb unplug tries out of 20 would not // boot player & mtp was still running due to rare irq loss) usb_device_get_status(USB_STATUS_CONNECTION,&usStatus); //we could just check the usb 5v bit instead of calling this. if( usStatus == USB_DISCONNECTED ) { // Restart the MTP device and re-enumerate //DebugBuildAssert(0); //During JLN verification, this hit & the reset started player. StorFlush(); // flush the database first SystemShutdown();// we could use pragma asm to jump to the missed isr instead which resets also. SystemReset(); } } // Update the count if it is not disabled( negative means disabled). if (g_StoreWatchDogCount >= 0) { g_StoreWatchDogCount++; } } // while(1) } // void _reentrant UserInterfaceTask(void)