2 ******************************************************************************
4 * @author MCD Application Team
6 * @date 21-January-2013
7 * @brief Connection/disconnection & power management
8 ******************************************************************************
11 * <h2><center>© 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 ------------------------------------------------------------------*/
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
43 __IO RESUME_STATE eState
;
44 __IO
uint8_t bESOFcnt
;
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
59 * Return : USB_SUCCESS.
60 *******************************************************************************/
65 /*** cable plugged-in ? ***/
66 USB_Cable_Config(ENABLE
);
68 /*** CNTR_PWDN = 0 ***/
72 /*** CNTR_FRES = 0 ***/
74 _SetCNTR(wInterrupt_Mask
);
75 /*** Clear pending interrupts ***/
77 /*** Set interrupt mask ***/
78 wInterrupt_Mask
= CNTR_RESETM
| CNTR_SUSPM
| CNTR_WKUPM
;
79 _SetCNTR(wInterrupt_Mask
);
84 /*******************************************************************************
85 * Function Name : PowerOff
86 * Description : handles switch-off conditions
89 * Return : USB_SUCCESS.
90 *******************************************************************************/
93 /* disable all interrupts and force USB reset */
95 /* clear interrupt status register */
97 /* Disable the Pull-Up*/
98 USB_Cable_Config(DISABLE
);
99 /* switch-off device */
100 _SetCNTR(CNTR_FRES
+ CNTR_PDWN
);
101 /* sw variables reset */
107 /*******************************************************************************
108 * Function Name : Suspend
109 * Description : sets suspend mode operating conditions
112 * Return : USB_SUCCESS.
113 *******************************************************************************/
119 __IO
uint32_t savePWR_CR
= 0;
120 /* suspend preparation */
123 /*Store CNTR value */
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
;
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
);
152 for (i
= 0; i
< 8; i
++)
153 _SetENDPOINT(i
, EP
[i
]);
155 /* Now it is safe to enter macrocell in suspend mode */
159 /* force low-power mode in the macrocell */
161 wCNTR
|= CNTR_LPMODE
;
164 /*prepare entry in low power mode (STOP mode)*/
165 /* Select the regulator state in STOP mode*/
166 savePWR_CR
= 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 */
174 /* Set SLEEPDEEP bit of Cortex System Control Register */
175 #if defined (STM32F303xC) || defined (STM32F37X)
176 SCB
->SCR
|= SCB_SCR_SLEEPDEEP_Msk
;
178 SCB
->SCR
|= SCB_SCR_SLEEPDEEP
;
180 /* enter system in STOP mode, only when wakeup flag in not set */
181 if ((_GetISTR() & ISTR_WKUP
) == 0) {
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
);
187 SCB
->SCR
&= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP
);
190 /* Clear Wakeup flag */
192 /* clear FSUSP to abort entry in suspend mode */
194 wCNTR
&= ~CNTR_FSUSP
;
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
);
205 SCB
->SCR
&= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP
);
211 /*******************************************************************************
212 * Function Name : Resume_Init
213 * Description : Handles wake-up restoring normal operations
216 * Return : USB_SUCCESS.
217 *******************************************************************************/
218 void Resume_Init(void)
222 /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
223 /* restart the clocks */
226 /* CNTR_LPMODE = 0 */
228 wCNTR
&= (~CNTR_LPMODE
);
231 /* restore full power */
232 /* ... on connected devices */
233 Leave_LowPowerMode();
235 /* reset FSUSP bit */
238 /* reverse suspend preparation */
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.
254 *******************************************************************************/
255 void Resume(RESUME_STATE eResumeSetVal
)
259 if (eResumeSetVal
!= RESUME_ESOF
)
260 ResumeS
.eState
= eResumeSetVal
;
261 switch (ResumeS
.eState
) {
262 case RESUME_EXTERNAL
:
263 if (remotewakeupon
== 0) {
265 ResumeS
.eState
= RESUME_OFF
;
266 } else /* RESUME detected during the RemoteWAkeup signalling => keep RemoteWakeup handling*/
268 ResumeS
.eState
= RESUME_ON
;
271 case RESUME_INTERNAL
:
273 ResumeS
.eState
= RESUME_START
;
277 ResumeS
.bESOFcnt
= 2;
278 ResumeS
.eState
= RESUME_WAIT
;
282 if (ResumeS
.bESOFcnt
== 0)
283 ResumeS
.eState
= RESUME_START
;
287 wCNTR
|= CNTR_RESUME
;
289 ResumeS
.eState
= RESUME_ON
;
290 ResumeS
.bESOFcnt
= 10;
294 if (ResumeS
.bESOFcnt
== 0) {
296 wCNTR
&= (~CNTR_RESUME
);
298 ResumeS
.eState
= RESUME_OFF
;
305 ResumeS
.eState
= RESUME_OFF
;
310 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/