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 SCB
->SCR
|= SCB_SCR_SLEEPDEEP
;
176 /* enter system in STOP mode, only when wakeup flag in not set */
177 if ((_GetISTR() & ISTR_WKUP
) == 0) {
179 /* Reset SLEEPDEEP bit of Cortex System Control Register */
180 SCB
->SCR
&= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP
);
182 /* Clear Wakeup flag */
184 /* clear FSUSP to abort entry in suspend mode */
186 wCNTR
&= ~CNTR_FSUSP
;
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
203 * Return : USB_SUCCESS.
204 *******************************************************************************/
205 void Resume_Init(void)
209 /* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
210 /* restart the clocks */
213 /* CNTR_LPMODE = 0 */
215 wCNTR
&= (~CNTR_LPMODE
);
218 /* restore full power */
219 /* ... on connected devices */
220 Leave_LowPowerMode();
222 /* reset FSUSP bit */
225 /* reverse suspend preparation */
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.
241 *******************************************************************************/
242 void Resume(RESUME_STATE eResumeSetVal
)
246 if (eResumeSetVal
!= RESUME_ESOF
)
247 ResumeS
.eState
= eResumeSetVal
;
248 switch (ResumeS
.eState
) {
249 case RESUME_EXTERNAL
:
250 if (remotewakeupon
== 0) {
252 ResumeS
.eState
= RESUME_OFF
;
253 } else /* RESUME detected during the RemoteWAkeup signalling => keep RemoteWakeup handling*/
255 ResumeS
.eState
= RESUME_ON
;
258 case RESUME_INTERNAL
:
260 ResumeS
.eState
= RESUME_START
;
264 ResumeS
.bESOFcnt
= 2;
265 ResumeS
.eState
= RESUME_WAIT
;
269 if (ResumeS
.bESOFcnt
== 0)
270 ResumeS
.eState
= RESUME_START
;
274 wCNTR
|= CNTR_RESUME
;
276 ResumeS
.eState
= RESUME_ON
;
277 ResumeS
.bESOFcnt
= 10;
281 if (ResumeS
.bESOFcnt
== 0) {
283 wCNTR
&= (~CNTR_RESUME
);
285 ResumeS
.eState
= RESUME_OFF
;
292 ResumeS
.eState
= RESUME_OFF
;
297 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/