STM32 usb_pwr.c file analysis

Publisher:心想的45号Latest update time:2016-12-20 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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


Keywords:STM32 Reference address:STM32 usb_pwr.c file analysis

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

STM32 IIC Detailed Explanation: STM32 IIC Slave Mode (Interrupt Mode to Send and Receive Data)
1. Introduction to IIC This part of the content will be used in the second section of the code. For IIC, the slave cannot actively send data, and the start conditions are all generated by the host.  1.1、Host sends data process   1) When the host detects that the bus is in the "idle state" (that is, the SDA and S
[Microcontroller]
The meaning of stm microcontroller model The difference between stm8 and stm32 programming programs stm8 reading program
The meaning of stm microcontroller model STM microcontroller models generally consist of several parts, each part represents a different meaning: The first part: STM or STM32 or STM8, represents the brand and series of the microcontroller. The STM32 series is a series of microcontrollers based on the ARM Cortex-M co
[Microcontroller]
stm32 startup process
In the current embedded application development process, C language has become the best choice for most occasions. In this way, the main function seems to be the starting point for granted - because C programs often start execution from the main function. But a question that is often overlooked is: how does the microc
[Microcontroller]
Stm32 serial port sends string data
ps: Divide the string into bytes and send them cyclically   /* *illustrate: *PA0:KEY1;PA1:KEY2; *PA2:LED1;PA3:LED2; *PA9:USART1_TX;PA10:USART1_RX */ #include "stm32f10x.h" #include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include "stm32f10x_usart.h" #include "stm32f10x_crc.h" #include "system_stm32f10x.h"
[Microcontroller]
A problem encountered in debugging ARM STM32 external interrupt
Background: The PB9 and PE0 pins of STM32f103zet6 are connected to a button respectively. It is hoped that these two buttons can generate an external interrupt and light up the LED corresponding to the button. Use the EXTI channel.   First configure RCC: void RCC_Configuration() { ErrorStatus HSEStartUpStatu
[Microcontroller]
STM32 timer timing calculation
Assuming the system clock is 72Mhz, TIM1 is obtained from PCLK2 (72MHz), and TIM2-7 is obtained from PCLK1. The key is to set the clock pre-division number and the value of the automatic reload register period. Basic settings of the timer      1.     TIM_TimeBaseStructure.TIM_Prescaler = 7199; //Clock pre-divisi
[Microcontroller]
STM32 six-step PWM output
As mentioned before, only two advanced timers TIM1 and TIM8 of STM32 can have complementary output. The six-step PWM output we are talking about here requires complementary output, so only TIM1 and TIM8 can achieve it. What is six-step PWM output? Let's explain it below. When a timer needs complementary output, you can
[Microcontroller]
STM32 boot process complete solution
This article mainly explains the comprehensive analysis of the STM32 startup process, including the introduction of the startup process, the display of the startup code, and in-depth analysis.   Compared with the mainstream ARM7/ARM9 core architecture of the previous generation of ARM, the startup method of the new ge
[Analog Electronics]
STM32 boot process complete solution
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号