As you can tell from the file name usb_pwr.c, this file is related to power consumption and has many states: power on, power off, suspend, and resume.
First of all, the USB power-on and power-off functions are defined.
The USB power-on function is as follows:
/*******************************************************************************
* Function Name : PowerOn
* Description : Power on
* Input : None.
* Output : None.
* Return : USB_SUCCESS.
*******************************************************************************/
RESULT PowerOn(void)
{
u16 wRegVal;
USB_Cable_Config(ENABLE); //Connect the pull-up resistor
wRegVal = CNTR_FRES; //Set forced reset
_SetCNTR(wRegVal);
wInterrupt_Mask = 0; // Disable all interrupts first
_SetCNTR(wInterrupt_Mask);
_SetISTR(0); //Clear all interrupt flags
wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
_SetCNTR(wInterrupt_Mask); //Re-enable the reset interrupt, suspend interrupt, and wake-up interrupt mask bits
return USB_SUCCESS;
}
The power-on process is:
1. Of course, connect the pull-up resistor of D+ or D- so that the host can recognize the USB;
2. Configure the USB control register CNTR to force a USB reset
3. Turn on reset interrupt, suspend interrupt, wake-up interrupt, and turn off other interrupt mask bits
Next is the power-off function definition:
/*******************************************************************************
* Function Name : PowerOff
* Description : Power off
* Input : None.
* Output : None.
* Return : USB_SUCCESS.
*******************************************************************************/
RESULT PowerOff()
{
/* disable all ints and force USB reset */
_SetCNTR(CNTR_FRES); //Set forced reset
_SetISTR(0); //Clear all interrupt flags
USB_Cable_Config(DISABLE); //Disconnect the pull-up resistor
_SetCNTR(CNTR_FRES + CNTR_PDWN); //Set forced reset and enter power-off mode
return USB_SUCCESS;
}
The power-off process is very simple. First, force the USB to reset, clear all interrupt flags, disconnect the pull-up resistor, and set the control to enter power-off mode.
Suspend is also a state of USB. The so-called suspend starts with entering a low-power state. I don’t respond to general things unless there is something important that I will wake up to handle.
/*******************************************************************************
* Function Name : Suspend
* Description : Suspend
* Input : None.
* Output : None.
* Return : USB_SUCCESS.
*******************************************************************************/
void Suspend(void)
{
u16 wCNTR;
wCNTR = _GetCNTR(); //Read the value of the control register
wCNTR |= CNTR_FSUSP; //Add forced suspension flag
_SetCNTR(wCNTR); //Enter suspend mode
wCNTR = _GetCNTR(); //Read the value of the control register
wCNTR |= CNTR_LPMODE; //Add low power consumption flag
_SetCNTR(wCNTR); //Enter low power mode
Enter_LowPowerMode(); //Enter low power mode
}
The process of entering the suspend state is very similar to the process of entering the interrupt service function. Of course, the scene must be protected. Therefore, when the USB enters the suspend state, the original value of the control register is not changed, but the suspend state and low power state flags are added to the original value.
Speaking of suspend, of course there is resume. First of all, let's talk about the Resume_Init() function:
/*******************************************************************************
* Function Name : Resume_Init
* Description: Function to handle wake-up recovery
* Input : None.
* Output : None.
* Return : USB_SUCCESS.
*******************************************************************************/
void Resume_Init(void)
{
u16 wCNTR;
wCNTR = _GetCNTR();
wCNTR &= (~CNTR_LPMODE);
_SetCNTR(wCNTR); //Enter non-low power mode
Leave_LowPowerMode(); //Leave low power mode
_SetCNTR(IMR_MSK); //Enable all interrupts
}
This is the wake-up function, which is relatively simple, but what is more difficult to understand are the various states of recovery.
typedef enum _RESUME_STATE
{
RESUME_EXTERNAL,
RESUME_INTERNAL,
RESUME_LATER,
RESUME_WAIT,
RESUME_START,
RESUME_ON,
RESUME_OFF,
RESUME_ESOF
} RESUME_STATE;
There are so many state changes in recovery, of course it makes sense to understand each state.
RESUME_EXTERNAL: In my opinion, just like hardware reset, it wakes up the USB through some physical hardware.
RESUME_INTERNAL: The wakeup in this state should be software wakeup, such as receiving an interrupt
RESUME_LATER: Indicates waking up later. Of course, this involves a timing process. When the timing is reached, the system will resume.
RESUME_WAIT: This state indicates that the timing process is waiting for the end.
RESUME_START: Indicates that the USB is starting to recover.
RESUME_ON: indicates that the USB module is about to be restored. This state remains valid for 1 millisecond to 15 milliseconds, and the host will wake up the USB module.
RESUME_OFF: Indicates that the recovery has been completed
RESUME_ESOF: My personal understanding is that when the ESOF interrupt flag is received, the USB is not allowed to enter the suspend state
The conversion between each state is as follows:
/*******************************************************************************
* Function Name : Resume
* Description: This is the state machine that handles resume operations and timing. Control is based on the Resume structure variables and
* ESOF interrupt calls this subroutine without changing the machine state. Control restore state
* Input : a state machine value (RESUME_STATE)
* RESUME_ESOF doesn't change ResumeS.eState allowing
* decrementing of the ESOF counter in different states.
* Output : None.
* Return : None.
*******************************************************************************/
void Resume(RESUME_STATE eResumeSetVal)
{
u16 wCNTR;
if (eResumeSetVal != RESUME_ESOF) //If it is not caused by ESOF interrupt
ResumeS.eState = eResumeSetVal; //ResumeS.eState is set to the value you set
switch (ResumeS.eState)
{
case RESUME_EXTERNAL: //RESUME_EXTERNAL external recovery
Resume_Init();
ResumeS.eState = RESUME_OFF;
break;
case RESUME_INTERNAL: //RESUME_INTERNAL internal recovery
Resume_Init();
ResumeS.eState = RESUME_START;
break;
case RESUME_LATER: //RESUME_LATER scheduled recovery
ResumeS.bESOFcnt = 2;
ResumeS.eState = RESUME_WAIT;
break;
case RESUME_WAIT: //RESUME_WAIT waits for the timer to end
ResumeS.bESOFcnt--;
if (ResumeS.bESOFcnt == 0)
ResumeS.eState = RESUME_START;
break;
case RESUME_START: //RESUME_START starts recovery
wCNTR = _GetCNTR();
wCNTR |= CNTR_RESUME;
_SetCNTR(wCNTR); //Set the wake-up request bit to send a wake-up request to the PC host
ResumeS.eState = RESUME_ON;
ResumeS.bESOFcnt = 10; //10ms timing. If it remains valid within this time, the host will wake up the USB module.
break;
case RESUME_ON: //RESUME_ON
ResumeS.bESOFcnt--; //Timing in progress
if (ResumeS.bESOFcnt == 0) //The timing is up
{
wCNTR = _GetCNTR();
wCNTR &= (~CNTR_RESUME); //Clear wake-up request flag
_SetCNTR(wCNTR);
ResumeS.eState = RESUME_OFF;
}
break;
case RESUME_OFF: //RESUME_OFF
case RESUME_ESOF: //RESUME_ESOF
default:
ResumeS.eState = RESUME_OFF;
break;
}
}
It is obvious that the transformation process of each state can be seen:
1、RESUME_EXTERNAL->RESUME_OFF
2、RESUME_INTERNAL->RESUME_START->RESUME_ON->RESUME_OFF
3、RESUME_WAIT->RESUME_START->RESUME_ON->RESUME_OFF
4、RESUME_ESOF->RESUME_OFF
Previous article:STM32 usb_prop.c file analysis and some data definition analysis of usb_core.h
Next article:STM32 usb_core.c analysis
Recommended ReadingLatest update time:2024-11-15 14:35
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- EEWORLD University Hall ---- EMC pre-test environment construction
- [Zhongke Bluexun AB32VG1 RISC-V Evaluation Board] Try to use RTThread multitasking
- CC3200 wireless wifi processor full voice interactive control smart home system
- Pre-registration for the prize live broadcast | ON Semiconductor's advanced image sensor solutions for the Internet of Things
- Free | VIP tickets to EDI CON, the annual RF conference (Beijing, April 1-3)
- Year-end benefits! 2019 TI Industrial Applications Selected Courses Summary, Grab the Building to Win Gifts
- Fujitsu Live Today|FRAM Authenticity Verification Solution without Encryption Algorithm (Spectrum)
- Do capacitors have a filtering effect on high-frequency DC signals?
- [OrCAD] How to display the name of the offpage connector after it is manually hidden?
- AD9 interface issues