mirror of
https://github.com/eddyem/IR-controller.git
synced 2025-12-06 18:55:20 +03:00
136 lines
3.2 KiB
C
136 lines
3.2 KiB
C
/*
|
|
* usb_pwr.c - USB power (on/off, suspend, resume)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "usb_pwr.h"
|
|
|
|
__IO uint32_t bDeviceState = UNCONNECTED; /* USB device status */
|
|
__IO bool fSuspendEnabled = FALSE; /* true when suspend is possible */
|
|
|
|
struct{
|
|
__IO RESUME_STATE eState;
|
|
__IO uint8_t bESOFcnt;
|
|
} ResumeS;
|
|
|
|
RESULT PowerOn(void){
|
|
uint16_t wRegVal;
|
|
USB_Cable_Config(DISABLE);
|
|
/*** CNTR_PWDN = 0 ***/
|
|
wRegVal = CNTR_FRES;
|
|
_SetCNTR(wRegVal);
|
|
/*** CNTR_FRES = 0 ***/
|
|
wInterrupt_Mask = 0;
|
|
_SetCNTR(wInterrupt_Mask);
|
|
/*** Clear pending interrupts ***/
|
|
_SetISTR(0);
|
|
/*** Set interrupt mask ***/
|
|
wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
|
|
_SetCNTR(wInterrupt_Mask);
|
|
/*** cable plugged-in ? ***/
|
|
/*while(!CablePluggedIn());*/
|
|
USB_Cable_Config(ENABLE);
|
|
return USB_SUCCESS;
|
|
}
|
|
|
|
RESULT PowerOff(){
|
|
/* disable all interrupts and force USB reset */
|
|
_SetCNTR(CNTR_FRES);
|
|
/* clear interrupt status register */
|
|
_SetISTR(0);
|
|
/* Disable the Pull-Up*/
|
|
USB_Cable_Config(DISABLE);
|
|
/* switch-off device */
|
|
_SetCNTR(CNTR_FRES + CNTR_PDWN);
|
|
/* sw variables reset */
|
|
/* ... */
|
|
return USB_SUCCESS;
|
|
}
|
|
|
|
void Suspend(void){
|
|
uint16_t wCNTR;
|
|
/* macrocell enters suspend mode */
|
|
wCNTR = _GetCNTR();
|
|
wCNTR |= CNTR_FSUSP;
|
|
_SetCNTR(wCNTR);
|
|
/* force low-power mode in the macrocell */
|
|
wCNTR = _GetCNTR();
|
|
wCNTR |= CNTR_LPMODE;
|
|
_SetCNTR(wCNTR);
|
|
Enter_LowPowerMode();
|
|
}
|
|
|
|
void Resume_Init(void){
|
|
uint16_t wCNTR;
|
|
/* CNTR_LPMODE = 0 */
|
|
wCNTR = _GetCNTR();
|
|
wCNTR &= (~CNTR_LPMODE);
|
|
_SetCNTR(wCNTR);
|
|
Leave_LowPowerMode();
|
|
/* reset FSUSP bit */
|
|
_SetCNTR(IMR_MSK);
|
|
}
|
|
|
|
void Resume(RESUME_STATE eResumeSetVal){
|
|
uint16_t wCNTR;
|
|
|
|
if (eResumeSetVal != RESUME_ESOF)
|
|
ResumeS.eState = eResumeSetVal;
|
|
|
|
switch (ResumeS.eState){
|
|
case RESUME_EXTERNAL:
|
|
Resume_Init();
|
|
ResumeS.eState = RESUME_OFF;
|
|
break;
|
|
case RESUME_INTERNAL:
|
|
Resume_Init();
|
|
ResumeS.eState = RESUME_START;
|
|
break;
|
|
case RESUME_LATER:
|
|
ResumeS.bESOFcnt = 2;
|
|
ResumeS.eState = RESUME_WAIT;
|
|
break;
|
|
case RESUME_WAIT:
|
|
ResumeS.bESOFcnt--;
|
|
if (ResumeS.bESOFcnt == 0)
|
|
ResumeS.eState = RESUME_START;
|
|
break;
|
|
case RESUME_START:
|
|
wCNTR = _GetCNTR();
|
|
wCNTR |= CNTR_RESUME;
|
|
_SetCNTR(wCNTR);
|
|
ResumeS.eState = RESUME_ON;
|
|
ResumeS.bESOFcnt = 10;
|
|
break;
|
|
case RESUME_ON:
|
|
ResumeS.bESOFcnt--;
|
|
if (ResumeS.bESOFcnt == 0){
|
|
wCNTR = _GetCNTR();
|
|
wCNTR &= (~CNTR_RESUME);
|
|
_SetCNTR(wCNTR);
|
|
ResumeS.eState = RESUME_OFF;
|
|
}
|
|
break;
|
|
case RESUME_OFF:
|
|
case RESUME_ESOF:
|
|
default:
|
|
ResumeS.eState = RESUME_OFF;
|
|
break;
|
|
}
|
|
}
|
|
|