add BF spektrum RSSI patch
[inav.git] / src / main / vcp / usb_pwr.c
blob8cdd7eb3d155d707bf313ae3825ccc1fd34f65a0
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()
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 #if defined (STM32F303xC) || defined (STM32F37X)
176 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
177 #else
178 SCB->SCR |= SCB_SCR_SLEEPDEEP;
179 #endif
180 /* enter system in STOP mode, only when wakeup flag in not set */
181 if ((_GetISTR() & ISTR_WKUP) == 0) {
182 __WFI();
183 /* Reset SLEEPDEEP bit of Cortex System Control Register */
184 #if defined (STM32F303xC) || defined (STM32F37X)
185 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
186 #else
187 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
188 #endif
189 } else {
190 /* Clear Wakeup flag */
191 _SetISTR(CLR_WKUP);
192 /* clear FSUSP to abort entry in suspend mode */
193 wCNTR = _GetCNTR();
194 wCNTR &= ~CNTR_FSUSP;
195 _SetCNTR(wCNTR);
197 /*restore sleep mode configuration */
198 /* restore Power regulator config in sleep mode*/
199 PWR->CR = savePWR_CR;
201 /* Reset SLEEPDEEP bit of Cortex System Control Register */
202 #if defined (STM32F303xC) || defined (STM32F37X)
203 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
204 #else
205 SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
206 #endif
211 /*******************************************************************************
212 * Function Name : Resume_Init
213 * Description : Handles wake-up restoring normal operations
214 * Input : None.
215 * Output : None.
216 * Return : USB_SUCCESS.
217 *******************************************************************************/
218 void Resume_Init(void)
220 uint16_t wCNTR;
222 /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
223 /* restart the clocks */
224 /* ... */
226 /* CNTR_LPMODE = 0 */
227 wCNTR = _GetCNTR();
228 wCNTR &= (~CNTR_LPMODE);
229 _SetCNTR(wCNTR);
231 /* restore full power */
232 /* ... on connected devices */
233 Leave_LowPowerMode();
235 /* reset FSUSP bit */
236 _SetCNTR(IMR_MSK);
238 /* reverse suspend preparation */
239 /* ... */
243 /*******************************************************************************
244 * Function Name : Resume
245 * Description : This is the state machine handling resume operations and
246 * timing sequence. The control is based on the Resume structure
247 * variables and on the ESOF interrupt calling this subroutine
248 * without changing machine state.
249 * Input : a state machine value (RESUME_STATE)
250 * RESUME_ESOF doesn't change ResumeS.eState allowing
251 * decrementing of the ESOF counter in different states.
252 * Output : None.
253 * Return : None.
254 *******************************************************************************/
255 void Resume(RESUME_STATE eResumeSetVal)
257 uint16_t wCNTR;
259 if (eResumeSetVal != RESUME_ESOF)
260 ResumeS.eState = eResumeSetVal;
261 switch (ResumeS.eState) {
262 case RESUME_EXTERNAL:
263 if (remotewakeupon == 0) {
264 Resume_Init();
265 ResumeS.eState = RESUME_OFF;
266 } else /* RESUME detected during the RemoteWAkeup signalling => keep RemoteWakeup handling*/
268 ResumeS.eState = RESUME_ON;
270 break;
271 case RESUME_INTERNAL:
272 Resume_Init();
273 ResumeS.eState = RESUME_START;
274 remotewakeupon = 1;
275 break;
276 case RESUME_LATER:
277 ResumeS.bESOFcnt = 2;
278 ResumeS.eState = RESUME_WAIT;
279 break;
280 case RESUME_WAIT:
281 ResumeS.bESOFcnt--;
282 if (ResumeS.bESOFcnt == 0)
283 ResumeS.eState = RESUME_START;
284 break;
285 case RESUME_START:
286 wCNTR = _GetCNTR();
287 wCNTR |= CNTR_RESUME;
288 _SetCNTR(wCNTR);
289 ResumeS.eState = RESUME_ON;
290 ResumeS.bESOFcnt = 10;
291 break;
292 case RESUME_ON:
293 ResumeS.bESOFcnt--;
294 if (ResumeS.bESOFcnt == 0) {
295 wCNTR = _GetCNTR();
296 wCNTR &= (~CNTR_RESUME);
297 _SetCNTR(wCNTR);
298 ResumeS.eState = RESUME_OFF;
299 remotewakeupon = 0;
301 break;
302 case RESUME_OFF:
303 case RESUME_ESOF:
304 default:
305 ResumeS.eState = RESUME_OFF;
306 break;
310 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/