Support SBUS2 FASSTest 12 channel short frame time
[inav.git] / src / main / vcp / usb_pwr.c
blob6f96498b1dde4d96aee8b0970367d162dffa459d
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 ------------------------------------------------------------------*/
29 #include "usb_lib.h"
30 #include "usb_conf.h"
31 #include "usb_pwr.h"
32 #include "hw_config.h"
34 /* Private typedef -----------------------------------------------------------*/
35 /* Private define ------------------------------------------------------------*/
36 /* Private macro -------------------------------------------------------------*/
37 /* Private variables ---------------------------------------------------------*/
38 __IO uint32_t bDeviceState = UNCONNECTED; /* USB device status */
39 __IO boolean fSuspendEnabled = TRUE; /* true when suspend is possible */ // HJI
40 __IO uint32_t EP[8];
42 struct {
43 __IO RESUME_STATE eState;
44 __IO uint8_t bESOFcnt;
45 } ResumeS;
47 __IO uint32_t remotewakeupon = 0;
49 /* Extern variables ----------------------------------------------------------*/
50 /* Private function prototypes -----------------------------------------------*/
51 /* Extern function prototypes ------------------------------------------------*/
52 /* Private functions ---------------------------------------------------------*/
54 /*******************************************************************************
55 * Function Name : PowerOn
56 * Description :
57 * Input : None.
58 * Output : None.
59 * Return : USB_SUCCESS.
60 *******************************************************************************/
61 RESULT PowerOn(void)
63 uint16_t wRegVal;
65 /*** cable plugged-in ? ***/
66 USB_Cable_Config(ENABLE);
68 /*** CNTR_PWDN = 0 ***/
69 wRegVal = CNTR_FRES;
70 _SetCNTR(wRegVal);
72 /*** CNTR_FRES = 0 ***/
73 wInterrupt_Mask = 0;
74 _SetCNTR(wInterrupt_Mask);
75 /*** Clear pending interrupts ***/
76 _SetISTR(0);
77 /*** Set interrupt mask ***/
78 wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
79 _SetCNTR(wInterrupt_Mask);
81 return USB_SUCCESS;
84 /*******************************************************************************
85 * Function Name : PowerOff
86 * Description : handles switch-off conditions
87 * Input : None.
88 * Output : None.
89 * Return : USB_SUCCESS.
90 *******************************************************************************/
91 RESULT PowerOff(void)
93 /* disable all interrupts and force USB reset */
94 _SetCNTR(CNTR_FRES);
95 /* clear interrupt status register */
96 _SetISTR(0);
97 /* Disable the Pull-Up*/
98 USB_Cable_Config(DISABLE);
99 /* switch-off device */
100 _SetCNTR(CNTR_FRES + CNTR_PDWN);
101 /* sw variables reset */
102 /* ... */
104 return USB_SUCCESS;
107 /*******************************************************************************
108 * Function Name : Suspend
109 * Description : sets suspend mode operating conditions
110 * Input : None.
111 * Output : None.
112 * Return : USB_SUCCESS.
113 *******************************************************************************/
114 void Suspend(void)
116 uint32_t i = 0;
117 uint16_t wCNTR;
118 uint32_t tmpreg = 0;
119 __IO uint32_t savePWR_CR = 0;
120 /* suspend preparation */
121 /* ... */
123 /*Store CNTR value */
124 wCNTR = _GetCNTR();
126 /* This a sequence to apply a force RESET to handle a robustness case */
128 /*Store endpoints registers status */
129 for (i = 0; i < 8; i++)
130 EP[i] = _GetENDPOINT(i);
132 /* unmask RESET flag */
133 wCNTR |= CNTR_RESETM;
134 _SetCNTR(wCNTR);
136 /*apply FRES */
137 wCNTR |= CNTR_FRES;
138 _SetCNTR(wCNTR);
140 /*clear FRES*/
141 wCNTR &= ~CNTR_FRES;
142 _SetCNTR(wCNTR);
144 /*poll for RESET flag in ISTR*/
145 while ((_GetISTR() & ISTR_RESET) == 0)
148 /* clear RESET flag in ISTR */
149 _SetISTR((uint16_t)CLR_RESET);
151 /*restore Enpoints*/
152 for (i = 0; i < 8; i++)
153 _SetENDPOINT(i, EP[i]);
155 /* Now it is safe to enter macrocell in suspend mode */
156 wCNTR |= CNTR_FSUSP;
157 _SetCNTR(wCNTR);
159 /* force low-power mode in the macrocell */
160 wCNTR = _GetCNTR();
161 wCNTR |= CNTR_LPMODE;
162 _SetCNTR(wCNTR);
164 /*prepare entry in low power mode (STOP mode)*/
165 /* Select the regulator state in STOP mode*/
166 savePWR_CR = PWR->CR;
167 tmpreg = PWR->CR;
168 /* Clear PDDS and LPDS bits */
169 tmpreg &= ((uint32_t)0xFFFFFFFC);
170 /* Set LPDS bit according to PWR_Regulator value */
171 tmpreg |= PWR_Regulator_LowPower;
172 /* Store the new value */
173 PWR->CR = tmpreg;
174 /* Set SLEEPDEEP bit of Cortex System Control Register */
175 SCB->SCR |= SCB_SCR_SLEEPDEEP;
176 /* enter system in STOP mode, only when wakeup flag in not set */
177 if ((_GetISTR() & ISTR_WKUP) == 0) {
178 __WFI();
179 /* Reset SLEEPDEEP bit of Cortex System Control Register */
180 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
181 } else {
182 /* Clear Wakeup flag */
183 _SetISTR(CLR_WKUP);
184 /* clear FSUSP to abort entry in suspend mode */
185 wCNTR = _GetCNTR();
186 wCNTR &= ~CNTR_FSUSP;
187 _SetCNTR(wCNTR);
189 /*restore sleep mode configuration */
190 /* restore Power regulator config in sleep mode*/
191 PWR->CR = savePWR_CR;
193 /* Reset SLEEPDEEP bit of Cortex System Control Register */
194 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
198 /*******************************************************************************
199 * Function Name : Resume_Init
200 * Description : Handles wake-up restoring normal operations
201 * Input : None.
202 * Output : None.
203 * Return : USB_SUCCESS.
204 *******************************************************************************/
205 void Resume_Init(void)
207 uint16_t wCNTR;
209 /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
210 /* restart the clocks */
211 /* ... */
213 /* CNTR_LPMODE = 0 */
214 wCNTR = _GetCNTR();
215 wCNTR &= (~CNTR_LPMODE);
216 _SetCNTR(wCNTR);
218 /* restore full power */
219 /* ... on connected devices */
220 Leave_LowPowerMode();
222 /* reset FSUSP bit */
223 _SetCNTR(IMR_MSK);
225 /* reverse suspend preparation */
226 /* ... */
230 /*******************************************************************************
231 * Function Name : Resume
232 * Description : This is the state machine handling resume operations and
233 * timing sequence. The control is based on the Resume structure
234 * variables and on the ESOF interrupt calling this subroutine
235 * without changing machine state.
236 * Input : a state machine value (RESUME_STATE)
237 * RESUME_ESOF doesn't change ResumeS.eState allowing
238 * decrementing of the ESOF counter in different states.
239 * Output : None.
240 * Return : None.
241 *******************************************************************************/
242 void Resume(RESUME_STATE eResumeSetVal)
244 uint16_t wCNTR;
246 if (eResumeSetVal != RESUME_ESOF)
247 ResumeS.eState = eResumeSetVal;
248 switch (ResumeS.eState) {
249 case RESUME_EXTERNAL:
250 if (remotewakeupon == 0) {
251 Resume_Init();
252 ResumeS.eState = RESUME_OFF;
253 } else /* RESUME detected during the RemoteWAkeup signalling => keep RemoteWakeup handling*/
255 ResumeS.eState = RESUME_ON;
257 break;
258 case RESUME_INTERNAL:
259 Resume_Init();
260 ResumeS.eState = RESUME_START;
261 remotewakeupon = 1;
262 break;
263 case RESUME_LATER:
264 ResumeS.bESOFcnt = 2;
265 ResumeS.eState = RESUME_WAIT;
266 break;
267 case RESUME_WAIT:
268 ResumeS.bESOFcnt--;
269 if (ResumeS.bESOFcnt == 0)
270 ResumeS.eState = RESUME_START;
271 break;
272 case RESUME_START:
273 wCNTR = _GetCNTR();
274 wCNTR |= CNTR_RESUME;
275 _SetCNTR(wCNTR);
276 ResumeS.eState = RESUME_ON;
277 ResumeS.bESOFcnt = 10;
278 break;
279 case RESUME_ON:
280 ResumeS.bESOFcnt--;
281 if (ResumeS.bESOFcnt == 0) {
282 wCNTR = _GetCNTR();
283 wCNTR &= (~CNTR_RESUME);
284 _SetCNTR(wCNTR);
285 ResumeS.eState = RESUME_OFF;
286 remotewakeupon = 0;
288 break;
289 case RESUME_OFF:
290 case RESUME_ESOF:
291 default:
292 ResumeS.eState = RESUME_OFF;
293 break;
297 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/