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 ------------------------------------------------------------------*/
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
46 __IO RESUME_STATE eState
;
47 __IO
uint8_t bESOFcnt
;
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
62 * Return : USB_SUCCESS.
63 *******************************************************************************/
68 /*** cable plugged-in ? ***/
69 USB_Cable_Config(ENABLE
);
71 /*** CNTR_PWDN = 0 ***/
75 /*** CNTR_FRES = 0 ***/
77 _SetCNTR(wInterrupt_Mask
);
78 /*** Clear pending interrupts ***/
80 /*** Set interrupt mask ***/
81 wInterrupt_Mask
= CNTR_RESETM
| CNTR_SUSPM
| CNTR_WKUPM
;
82 _SetCNTR(wInterrupt_Mask
);
87 /*******************************************************************************
88 * Function Name : PowerOff
89 * Description : handles switch-off conditions
92 * Return : USB_SUCCESS.
93 *******************************************************************************/
96 /* disable all interrupts and force USB reset */
98 /* clear interrupt status register */
100 /* Disable the Pull-Up*/
101 USB_Cable_Config(DISABLE
);
102 /* switch-off device */
103 _SetCNTR(CNTR_FRES
+ CNTR_PDWN
);
104 /* sw variables reset */
110 /*******************************************************************************
111 * Function Name : Suspend
112 * Description : sets suspend mode operating conditions
115 * Return : USB_SUCCESS.
116 *******************************************************************************/
122 __IO
uint32_t savePWR_CR
= 0;
123 /* suspend preparation */
126 /*Store CNTR value */
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
;
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
);
155 for (i
= 0; i
< 8; i
++)
156 _SetENDPOINT(i
, EP
[i
]);
158 /* Now it is safe to enter macrocell in suspend mode */
162 /* force low-power mode in the macrocell */
164 wCNTR
|= CNTR_LPMODE
;
167 /*prepare entry in low power mode (STOP mode)*/
168 /* Select the regulator state in STOP mode*/
169 savePWR_CR
= 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 */
177 /* Set SLEEPDEEP bit of Cortex System Control Register */
178 #if defined (STM32F303xC) || defined (STM32F37X)
179 SCB
->SCR
|= SCB_SCR_SLEEPDEEP_Msk
;
181 SCB
->SCR
|= SCB_SCR_SLEEPDEEP
;
183 /* enter system in STOP mode, only when wakeup flag in not set */
184 if ((_GetISTR() & ISTR_WKUP
) == 0) {
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
);
190 SCB
->SCR
&= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP
);
193 /* Clear Wakeup flag */
195 /* clear FSUSP to abort entry in suspend mode */
197 wCNTR
&= ~CNTR_FSUSP
;
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
);
208 SCB
->SCR
&= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP
);
214 /*******************************************************************************
215 * Function Name : Resume_Init
216 * Description : Handles wake-up restoring normal operations
219 * Return : USB_SUCCESS.
220 *******************************************************************************/
221 void Resume_Init(void)
225 /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
226 /* restart the clocks */
229 /* CNTR_LPMODE = 0 */
231 wCNTR
&= (~CNTR_LPMODE
);
234 /* restore full power */
235 /* ... on connected devices */
236 Leave_LowPowerMode();
238 /* reset FSUSP bit */
241 /* reverse suspend preparation */
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.
257 *******************************************************************************/
258 void Resume(RESUME_STATE eResumeSetVal
)
262 if (eResumeSetVal
!= RESUME_ESOF
)
263 ResumeS
.eState
= eResumeSetVal
;
264 switch (ResumeS
.eState
) {
265 case RESUME_EXTERNAL
:
266 if (remotewakeupon
== 0) {
268 ResumeS
.eState
= RESUME_OFF
;
269 } else /* RESUME detected during the RemoteWAkeup signalling => keep RemoteWakeup handling*/
271 ResumeS
.eState
= RESUME_ON
;
274 case RESUME_INTERNAL
:
276 ResumeS
.eState
= RESUME_START
;
280 ResumeS
.bESOFcnt
= 2;
281 ResumeS
.eState
= RESUME_WAIT
;
285 if (ResumeS
.bESOFcnt
== 0)
286 ResumeS
.eState
= RESUME_START
;
290 wCNTR
|= CNTR_RESUME
;
292 ResumeS
.eState
= RESUME_ON
;
293 ResumeS
.bESOFcnt
= 10;
297 if (ResumeS
.bESOFcnt
== 0) {
299 wCNTR
&= (~CNTR_RESUME
);
301 ResumeS
.eState
= RESUME_OFF
;
308 ResumeS
.eState
= RESUME_OFF
;
313 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/