📄 pm_if.c
字号:
/*
* description: USBD I/F Module (S1R72V05)
* Maker : Tsuyoshi Yamashita
* Copyright : (C)2004,SEIKO EPSON Corp. All Rights Reserved.
*
* --------------------------------------------------------------------------
*/
/*=== Include =============================================================*/
#include "SPRDEF.h"
#include "SPRSTS.h"
#include "OSCall.h"
#include "Reg72V05.h"
#include "PM_IF.h"
#include "DebugTask.h"
/*=== define =============================================================*/
/* CallBack */
#define CBINF_FINISHD_PM (0x00) /* PM completion's notification */
#define MAX_CALLBACK (1) /* Number of callback */
#define DEF_WAKEUP_TIM 0xFFFF
#define MAX_IS (1) /* Number of interrupt status */
/* Interrupt Status */
#define IS_MAIN_INT_STAT (0x01) /* Position for saving interrupt status */
/*=== Macro ===============================================================*/
#define IS_EPX_DIRIN(epn) (((epn) & 0x80) == 0x80 ? TRUE : FALSE)
#define IS_BIT(bits,mask) (((bits) & (mask)) != 0x00 ? TRUE : FALSE)
#define CLR_BIT(bits,mask) ((bits) = ((bits) & ~(mask)))
#define SET_BIT(bits,mask) ((bits) = ((bits) | (mask)))
#define DIRECT_B(a) *(unsigned char *)&(a) /* Structure's direct access */
/*=== Variable ================================================*/
/* Area for saving interrupt status */
static volatile UCHAR IntStat[MAX_IS];
static CALLBACK_PROC CallbackTable[MAX_CALLBACK];
static volatile UCHAR tempMainIntStat;
/*=== Function Prototype ==================================================*/
static void PM_IFISRProcess ( void );
/*=============================================================================
// Function_Name: PM_IFReset
// description : Reset
// argument : None
// return : STATUS_SUCCESS Terminated normally
// STATUS_UNSUCCESSFUL Not opened
// flag :
// global :
// =============================================================================
*/
LONG PM_IFReset ( const PM_IF_CPU_CONFIG *cpuConfig )
{
int i;
USHORT cpuCnf = 0;
volatile UCHAR temp;
// DBG_FlowStrPrint("\r\nPM_IFReset", 1);
// Check parameter
if( cpuConfig == NULL )
{
return STATUS_INVALID_PARAMETER;
}
// Set DEVICE Int Level
if( cpuConfig->IntLevel == PM_IF_HIGH_ACT )
{
cpuCnf |= 0x80;
}
// Set DEVICE Int Mode
if( cpuConfig->IntMode == PM_IF_HiZ_0_MODE )
{
cpuCnf |= 0x40;
}
// Set DEVICE DREQ Level
if( cpuConfig->DREQ_Level == PM_IF_HIGH_ACT )
{
cpuCnf |= 0x20;
}
// Set DEVICE DACK Levle
if( cpuConfig->DACK_Level == PM_IF_HIGH_ACT )
{
cpuCnf |= 0x10;
}
// Set DEVICE CS mode
if( cpuConfig->CS_Mode == PM_IF_CS_MODE )
{
cpuCnf |= 0x08;
}
// Set CPU SWAP
if( cpuConfig->CPU_Swap == PM_IF_CPU_SWAP_ON )
{
cpuCnf |= 0x04;
}
// Set Bus Mode
if( cpuConfig->BusMode == PM_IF_XBE_MODE )
{
cpuCnf |= 0x02;
}
// Set Bus Access
if( cpuConfig->Bus8x16 == PM_IF_BUS8 )
{
cpuCnf |= 0x01;
}
// Set register in order to do first register's access(ChipConfig)
#ifdef LITTLE_ENDIAN_C
RegWrite(REG08_ChipConfig - 1,cpuCnf); // Chip config set
#else /* #ifdef LITTLE_ENDIAN_C */
RegWrite(REG08_CPU_Config,cpuCnf); // Chip config set
#endif /* #ifdef LITTLE_ENDIAN_C */
temp = RegRead(REG08_CPU_ChgEndian); // Reading and do nothing
// ChipReset
RegWrite(REG08_ChipReset,BIT_AllReset);
OS_DlyTsk(1);
// Setting of reading and do nothing
temp = RegRead(REG08_CPU_ChgEndian); // Reading and do nothing
// Because the value of ChipConfig is initialized when ChipReset is done, the value is set to ChipConfig again
#ifdef LITTLE_ENDIAN_C
RegWrite(REG08_ChipConfig - 1,cpuCnf); // Chip config set
#else /* #ifdef LITTLE_ENDIAN_C */
RegWrite(REG08_ChipConfig,cpuCnf); // Chip config set
#endif /* #ifdef LITTLE_ENDIAN_C */
temp = RegRead(REG08_CPU_ChgEndian); // Reading and do nothing
// Set V05 CLK
if( cpuConfig->clkSel == PM_IF_CLK12 )
{
RegModify(REG08_ClkSelect,MASK_ClkSelect,BIT_ClkSelect_12MHz); // 12MHz
}
else
{
RegModify(REG08_ClkSelect,MASK_ClkSelect,BIT_ClkSelect_24MHz); // 24MHz
}
RegWrite(REG08_ModeProtect,BIT_ModeProtect_OFF);// Protect for ChipConfig register
// Set HOSTxDev
RegModify(REG08_HostDeviceSel,MASK_HOSTxDEVICE,BIT_HOSTxDEVICE_HOST);
// Release ResetHTM
RegClear(REG08_H_Reset,BIT_ResetHTM); /* Clear ResetHTM */
while ((RegRead(REG08_H_Reset) & MASK_ResetHTM) == BIT_ResetHTM) {
;
}
// Set HOSTxDev
RegModify(REG08_HostDeviceSel,MASK_HOSTxDEVICE,BIT_HOSTxDEVICE_DEVICE);
// Release ResetDTM
RegClear(REG08_D_Reset,BIT_ResetDTM); /* Clear ResetDTM*/
while ((RegRead(REG08_D_Reset) & MASK_ResetDTM) == BIT_ResetDTM) {
;
}
RegClear(REG08_MainIntEnb,BIT_EnFinishedPM); /* Clear FinishedPM */
RegWrite(REG08_MainIntStat,BIT_FinishedPM);
/* Callback function's table */
for (i = 0;i < MAX_CALLBACK;i++) {
CallbackTable[i] = 0x00;
}
return STATUS_SUCCESS;
}
/*=============================================================================
// Function_Name: PM_IFSetWakeupTim
// description : Wakeup Tim setting
// argument : None
// return : STATUS_SUCCESS Terminated normally
// flag :
// global :
// =============================================================================
*/
LONG PM_IFSetWakeupTim ( USHORT time )
{
RegWrite(REG08_WakeupTim_H,time >> 8);
RegWrite(REG08_WakeupTim_L,(UCHAR)time);
return STATUS_SUCCESS;
}
/*=============================================================================
// Function_Name: PM_IFGetPMState
// description : Get PM State
// argument : pmState Pointer that returns PM state
// return : STATUS_SUCCESS Terminated normally
// flag :
// global :
// =============================================================================
*/
LONG PM_IFGetPMState ( UCHAR *pmState )
{
if( pmState == NULL )
{
return STATUS_INVALID_PARAMETER;
}
*pmState = (RegRead(REG08_PM_Control_1) & MASK_PM_State) >> SHIFT_PM_State; /* PM_Control_1.PM_State */
return STATUS_SUCCESS;
}
/*=============================================================================
// Function_Name: PM_IFSetPMState
// description : Set PM State
// argument : pmState PM state
// return : STATUS_SUCCESS Terminated normally
// flag :
// global :
// =============================================================================
*/
LONG PM_IFSetPMState ( UCHAR pmState )
{
UCHAR nowState;
if( pmState & 0xE0 )
{
return STATUS_INVALID_PARAMETER;
}
RegWrite(REG08_MainIntStat,BIT_FinishedPM); /* Clear FinishedPM*/
// Get present state
nowState = (RegRead(REG08_PM_Control_1) & MASK_PM_State) >> SHIFT_PM_State; /* PM_Control.PM_State */
switch( pmState )
{
case PM_IF_PMSTATE_ACT_HOST:
if( nowState == PM_IF_PMSTATE_ACT_HOST )
{
return STATUS_SUCCESS;
}
// Can not do GoActHost when it is 1 port operation
if( ( RegRead(REG08_ClkSelect) & MASK_Port1x2) == BIT_Port1x2_1Port) {
while(1);
}
RegWrite(REG08_PM_Control_0,BIT_GoActHost);
break;
case PM_IF_PMSTATE_ACT_DEVICE:
if( nowState == PM_IF_PMSTATE_ACT_DEVICE )
{
return STATUS_SUCCESS;
}
RegWrite(REG08_PM_Control_0,BIT_GoActDevice);
break;
case PM_IF_PMSTATE_ACT_60:
if( nowState == PM_IF_PMSTATE_ACT_60 )
{
return STATUS_SUCCESS;
}
RegWrite(REG08_PM_Control_0,BIT_GoActive60);
break;
case PM_IF_PMSTATE_SNOOZE:
if( nowState == PM_IF_PMSTATE_SNOOZE )
{
return STATUS_SUCCESS;
}
#ifndef FPGA_DEBUG_C
RegWrite(REG08_PM_Control_0,BIT_GoSNOOZE);
break;
#else
return STATUS_SUCCESS;
#endif
case PM_IF_PMSTATE_SLEEP:
if( nowState == PM_IF_PMSTATE_SLEEP)
{
return STATUS_SUCCESS;
}
#ifndef FPGA_DEBUG_C
RegWrite(REG08_PM_Control_0,BIT_GoSLEEP);
break;
#else
return STATUS_SUCCESS;
#endif
default:
return STATUS_INVALID_PARAMETER;
// break;
}
// Wait for PM's completion
while ((RegRead(REG08_MainIntStat) & MASK_FinishedPM) != BIT_FinishedPM) {
;
}
RegWrite(REG08_MainIntStat,BIT_FinishedPM); /* Clear FinishedPM */
if (pmState == PM_IF_PMSTATE_ACT_HOST) {
// Can not do GoActHost when it is 1 port operation
if( (RegRead(REG08_ClkSelect) & MASK_Port1x2) == BIT_Port1x2_1Port) {
RegWrite(REG08_PM_Control_0,BIT_GoSLEEP);
while(1);
}
RegWrite(REG08_H_SIE_IntStat_0,BIT_DetectCon);
// Set HOSTxDev
RegSet(REG08_HostDeviceSel,BIT_HOSTxDEVICE_HOST);
RegModify(REG08_H_NegoControl_0,MASK_AutoMode,BIT_AutoMode_GoWAIT_CONNECT);
RegWrite(REG08_H_SIE_IntStat_0,BIT_DetectCon);
RegClear(REG08_HostDeviceSel,BIT_HOSTxDEVICE_HOST);
}
return STATUS_SUCCESS;
}
/*=============================================================================
// Function_Name: PM_IFSetIntEvent
// description : Interrupt event setting
// argument : Event's Interrupt event
// flag Set flag
// return : STATUS_SUCCESS Terminated normally
// flag :
// global :
// =============================================================================
*/
LONG PM_IFSetIntEvent(UCHAR event,UCHAR flag)
{
return STATUS_SUCCESS;
}
/*=============================================================================
// Function_Name: PM_IFRegisterCBRFinishedPM
// description : Register the callback for the notification of PMState change's completion
// argument : pfnCallback Pointer of Callback function
// return : STATUS_SUCCESS Terminated normally
// STATUS_UNABLE_TO_REGISTER Unable to register
// flag :
// global :
// =============================================================================
*/
LONG PM_IFRegisterCBRFinishedPM ( const CALLBACK_PROC pfnCallback )
{
if( CallbackTable[CBINF_FINISHD_PM] != NULL )
{
return STATUS_UNABLE_TO_REGISTER;
}
/* Callback function's registration*/
CallbackTable[CBINF_FINISHD_PM] = pfnCallback;
return STATUS_SUCCESS;
}
/*=============================================================================
// Function_Name: PM_IFUnregisterCBRFinishedPM
// description : Delete the callback which set by PM_IFRegisterCBRFinishedPM
// argument : None
// return : STATUS_SUCCESS Terminated normally
// flag :
// global :
// =============================================================================
*/
LONG PM_IFUnregisterCBRFinishedPM ( const CALLBACK_PROC pfnCallback )
{
RegClear(REG08_MainIntEnb,BIT_EnFinishedPM);
if (CallbackTable[CBINF_FINISHD_PM] == pfnCallback) {
/* Delete callback function */
CallbackTable[CBINF_FINISHD_PM] = NULL;
} else {
/* Unable to delete */
return STATUS_UNREGISTERED;
}
return STATUS_SUCCESS;
}
/*=============================================================================
// Function_Name: PM_IFInterruptProc
// description : Interrupt processing
// argument : None
// return : STATUS_SUCCESS Terminated normally
// flag :
// global :
// =============================================================================
*/
void PM_IFInterruptProc ( UCHAR mainIntEnb )
{
/* MainIntStat */
tempMainIntStat = (RegRead(REG08_MainIntStat) & (mainIntEnb & RegRead(REG08_MainIntEnb)));
if (tempMainIntStat != 0) {
IntStat[IS_MAIN_INT_STAT] |= tempMainIntStat;
/* Delete interrupt status */
RegWrite(REG08_MainIntStat,tempMainIntStat);
}
/* Return interrupt enable */
RegSet(REG08_MainIntEnb,mainIntEnb);
if (tempMainIntStat != 0) {
/* Process the callback to upper layer of the I/F layer */
PM_IFISRProcess();
}
}
/*-----------------------------------------------------------------------------
// Function_Name: ISRProcess
// description : Process interrupt
// argument : None
// return : None
// flag :
// global :
// -----------------------------------------------------------------------------
*/
void PM_IFISRProcess ( void )
{
if( IntStat[IS_MAIN_INT_STAT] != 0x00 )
{
/* Finished PM */
if( CallbackTable[CBINF_FINISHD_PM] != NULL )
{
if( (IntStat[IS_MAIN_INT_STAT] & MASK_FinishedPM) == BIT_FinishedPM)
{
/* Clear interrupt status */
CLR_BIT( IntStat[IS_MAIN_INT_STAT],BIT_FinishedPM);
/* Callback's notification */
CallbackTable[CBINF_FINISHD_PM]( 0, 0, NULL );
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -