⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pm_if.c

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 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 + -