Create release.yml
[betaflight.git] / src / main / vcp / usb_pwr.c
blob5e65bc9c7661d219590ee51fb2e44f730df99b95
1 /**
2 ******************************************************************************
3 * @file usb_pwr.c
4 * @author MCD Application Team
5 * @version V4.0.0
6 * @date 21-January-2013
7 * @brief Connection/disconnection & power management
8 ******************************************************************************
9 * @attention
11 * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
13 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
14 * You may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at:
17 * http://www.st.com/software_license_agreement_liberty_v2
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
25 ******************************************************************************
28 /* Includes ------------------------------------------------------------------*/
30 #include "platform.h"
32 #include "usb_lib.h"
33 #include "usb_conf.h"
34 #include "usb_pwr.h"
35 #include "hw_config.h"
37 /* Private typedef -----------------------------------------------------------*/
38 /* Private define ------------------------------------------------------------*/
39 /* Private macro -------------------------------------------------------------*/
40 /* Private variables ---------------------------------------------------------*/
41 __IO uint32_t bDeviceState = UNCONNECTED; /* USB device status */
42 __IO boolean fSuspendEnabled = TRUE; /* true when suspend is possible */ // HJI
43 __IO uint32_t EP[8];
45 struct {
46 __IO RESUME_STATE eState;
47 __IO uint8_t bESOFcnt;
48 } ResumeS;
50 __IO uint32_t remotewakeupon = 0;
52 /* Extern variables ----------------------------------------------------------*/
53 /* Private function prototypes -----------------------------------------------*/
54 /* Extern function prototypes ------------------------------------------------*/
55 /* Private functions ---------------------------------------------------------*/
57 /*******************************************************************************
58 * Function Name : PowerOn
59 * Description :
60 * Input : None.
61 * Output : None.
62 * Return : USB_SUCCESS.
63 *******************************************************************************/
64 RESULT PowerOn(void)
66 uint16_t wRegVal;
68 /*** cable plugged-in ? ***/
69 USB_Cable_Config(ENABLE);
71 /*** CNTR_PWDN = 0 ***/
72 wRegVal = CNTR_FRES;
73 _SetCNTR(wRegVal);
75 /*** CNTR_FRES = 0 ***/
76 wInterrupt_Mask = 0;
77 _SetCNTR(wInterrupt_Mask);
78 /*** Clear pending interrupts ***/
79 _SetISTR(0);
80 /*** Set interrupt mask ***/
81 wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
82 _SetCNTR(wInterrupt_Mask);
84 return USB_SUCCESS;
87 /*******************************************************************************
88 * Function Name : PowerOff
89 * Description : handles switch-off conditions
90 * Input : None.
91 * Output : None.
92 * Return : USB_SUCCESS.
93 *******************************************************************************/
94 RESULT PowerOff(void)
96 /* disable all interrupts and force USB reset */
97 _SetCNTR(CNTR_FRES);
98 /* clear interrupt status register */
99 _SetISTR(0);
100 /* Disable the Pull-Up*/
101 USB_Cable_Config(DISABLE);
102 /* switch-off device */
103 _SetCNTR(CNTR_FRES + CNTR_PDWN);
104 /* sw variables reset */
105 /* ... */
107 return USB_SUCCESS;
110 /*******************************************************************************
111 * Function Name : Suspend
112 * Description : sets suspend mode operating conditions
113 * Input : None.
114 * Output : None.
115 * Return : USB_SUCCESS.
116 *******************************************************************************/
117 void Suspend(void)
119 uint32_t i = 0;
120 uint16_t wCNTR;
121 uint32_t tmpreg = 0;
122 __IO uint32_t savePWR_CR = 0;
123 /* suspend preparation */
124 /* ... */
126 /*Store CNTR value */
127 wCNTR = _GetCNTR();
129 /* This a sequence to apply a force RESET to handle a robustness case */
131 /*Store endpoints registers status */
132 for (i = 0; i < 8; i++)
133 EP[i] = _GetENDPOINT(i);
135 /* unmask RESET flag */
136 wCNTR |= CNTR_RESETM;
137 _SetCNTR(wCNTR);
139 /*apply FRES */
140 wCNTR |= CNTR_FRES;
141 _SetCNTR(wCNTR);
143 /*clear FRES*/
144 wCNTR &= ~CNTR_FRES;
145 _SetCNTR(wCNTR);
147 /*poll for RESET flag in ISTR*/
148 while ((_GetISTR() & ISTR_RESET) == 0)
151 /* clear RESET flag in ISTR */
152 _SetISTR((uint16_t)CLR_RESET);
154 /*restore Enpoints*/
155 for (i = 0; i < 8; i++)
156 _SetENDPOINT(i, EP[i]);
158 /* Now it is safe to enter macrocell in suspend mode */
159 wCNTR |= CNTR_FSUSP;
160 _SetCNTR(wCNTR);
162 /* force low-power mode in the macrocell */
163 wCNTR = _GetCNTR();
164 wCNTR |= CNTR_LPMODE;
165 _SetCNTR(wCNTR);
167 /*prepare entry in low power mode (STOP mode)*/
168 /* Select the regulator state in STOP mode*/
169 savePWR_CR = PWR->CR;
170 tmpreg = PWR->CR;
171 /* Clear PDDS and LPDS bits */
172 tmpreg &= ((uint32_t)0xFFFFFFFC);
173 /* Set LPDS bit according to PWR_Regulator value */
174 tmpreg |= PWR_Regulator_LowPower;
175 /* Store the new value */
176 PWR->CR = tmpreg;
177 /* Set SLEEPDEEP bit of Cortex System Control Register */
178 #if defined (STM32F303xC) || defined (STM32F37X)
179 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
180 #else
181 SCB->SCR |= SCB_SCR_SLEEPDEEP;
182 #endif
183 /* enter system in STOP mode, only when wakeup flag in not set */
184 if ((_GetISTR() & ISTR_WKUP) == 0) {
185 __WFI();
186 /* Reset SLEEPDEEP bit of Cortex System Control Register */
187 #if defined (STM32F303xC) || defined (STM32F37X)
188 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
189 #else
190 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
191 #endif
192 } else {
193 /* Clear Wakeup flag */
194 _SetISTR(CLR_WKUP);
195 /* clear FSUSP to abort entry in suspend mode */
196 wCNTR = _GetCNTR();
197 wCNTR &= ~CNTR_FSUSP;
198 _SetCNTR(wCNTR);
200 /*restore sleep mode configuration */
201 /* restore Power regulator config in sleep mode*/
202 PWR->CR = savePWR_CR;
204 /* Reset SLEEPDEEP bit of Cortex System Control Register */
205 #if defined (STM32F303xC) || defined (STM32F37X)
206 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
207 #else
208 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
209 #endif
214 /*******************************************************************************
215 * Function Name : Resume_Init
216 * Description : Handles wake-up restoring normal operations
217 * Input : None.
218 * Output : None.
219 * Return : USB_SUCCESS.
220 *******************************************************************************/
221 void Resume_Init(void)
223 uint16_t wCNTR;
225 /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
226 /* restart the clocks */
227 /* ... */
229 /* CNTR_LPMODE = 0 */
230 wCNTR = _GetCNTR();
231 wCNTR &= (~CNTR_LPMODE);
232 _SetCNTR(wCNTR);
234 /* restore full power */
235 /* ... on connected devices */
236 Leave_LowPowerMode();
238 /* reset FSUSP bit */
239 _SetCNTR(IMR_MSK);
241 /* reverse suspend preparation */
242 /* ... */
246 /*******************************************************************************
247 * Function Name : Resume
248 * Description : This is the state machine handling resume operations and
249 * timing sequence. The control is based on the Resume structure
250 * variables and on the ESOF interrupt calling this subroutine
251 * without changing machine state.
252 * Input : a state machine value (RESUME_STATE)
253 * RESUME_ESOF doesn't change ResumeS.eState allowing
254 * decrementing of the ESOF counter in different states.
255 * Output : None.
256 * Return : None.
257 *******************************************************************************/
258 void Resume(RESUME_STATE eResumeSetVal)
260 uint16_t wCNTR;
262 if (eResumeSetVal != RESUME_ESOF)
263 ResumeS.eState = eResumeSetVal;
264 switch (ResumeS.eState) {
265 case RESUME_EXTERNAL:
266 if (remotewakeupon == 0) {
267 Resume_Init();
268 ResumeS.eState = RESUME_OFF;
269 } else /* RESUME detected during the RemoteWAkeup signalling => keep RemoteWakeup handling*/
271 ResumeS.eState = RESUME_ON;
273 break;
274 case RESUME_INTERNAL:
275 Resume_Init();
276 ResumeS.eState = RESUME_START;
277 remotewakeupon = 1;
278 break;
279 case RESUME_LATER:
280 ResumeS.bESOFcnt = 2;
281 ResumeS.eState = RESUME_WAIT;
282 break;
283 case RESUME_WAIT:
284 ResumeS.bESOFcnt--;
285 if (ResumeS.bESOFcnt == 0)
286 ResumeS.eState = RESUME_START;
287 break;
288 case RESUME_START:
289 wCNTR = _GetCNTR();
290 wCNTR |= CNTR_RESUME;
291 _SetCNTR(wCNTR);
292 ResumeS.eState = RESUME_ON;
293 ResumeS.bESOFcnt = 10;
294 break;
295 case RESUME_ON:
296 ResumeS.bESOFcnt--;
297 if (ResumeS.bESOFcnt == 0) {
298 wCNTR = _GetCNTR();
299 wCNTR &= (~CNTR_RESUME);
300 _SetCNTR(wCNTR);
301 ResumeS.eState = RESUME_OFF;
302 remotewakeupon = 0;
304 break;
305 case RESUME_OFF:
306 case RESUME_ESOF:
307 default:
308 ResumeS.eState = RESUME_OFF;
309 break;
313 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/