📄 sx2hostcpu.c
字号:
/* sx2HostCpu.c - VxWorks SX2 USB driver host CPU specific module */
/*
modification history
--------------------
01a,05nov01,hab Created
*/
/*
DESCRIPTION
This module implements the host CPU and BSP specific portion of the SX2 driver.
Functions and data specific to the host processor and the VxWorks BSP, are kept
in the HOST_CPU data structure, defined in sx2HostCpu.h.
This module is initialized through a call to sx2HostCpuInit(). This function
is not an externally callable routine, but is invoked during main driver
initialization from sx2DrvInit(). sx2HostCpuInit() is responsible for
initializing all the host CPU and BSP specific data and function pointers
in the HOST_CPU data structure. Further, the service task, sync sempahore
and service message queue are created.
*/
/* includes */
#include "vxWorks.h"
#include "semLib.h"
#include "405ppmc.h"
#include "ppc405gp.h"
#include "sx2HostCpu.h"
/* globals */
HOST_CPU hostCpu;
/* prototypes */
LOCAL STATUS ppmc405WaitReady(VOID);
LOCAL VOID ppmc405PktendSet(UINT8 fifo);
LOCAL STATUS ppmc405DrvCleanup(VOID);
LOCAL VOID sx2SvcTask(VOID);
/* external references */
IMPORT UINT8 sysInByte ();
IMPORT VOID sysOutByte ();
IMPORT UINT16 sysInWord ();
IMPORT VOID sysOutWord ();
IMPORT UINT32 sysInLong ();
IMPORT VOID sysOutLong();
/*******************************************************************************
*
* sx2HostCpuInit() - host CPU and BSP specific initialization of HOST_CPU
* data structure
*
* RETURNS: OK or ERROR.
*/
STATUS sx2HostCpuInit(VOID)
{
/* initialize host CPU data structure */
hostCpu.sx2BaseAddr = USB_START; /* SX2 base address */
hostCpu.sx2RegDelta = 2; /* register delta */
hostCpu.sx2IntVec = INT_LVL_EXT_IRQ_0; /* interrupt vector */
hostCpu.maxSpinCount = 500; /* READY polling max iterations */
hostCpu.readSyncFlag = 0; /* task to ISR read sync */
hostCpu.sx2BusActive = TRUE; /* bus activity toggle flag */
hostCpu.sx2Fifo2 = SX2REG(SX2_FIFO2); /* EP FIFO2 reg */
hostCpu.sx2Fifo4 = SX2REG(SX2_FIFO4); /* EP FIFO4 reg */
hostCpu.sx2Fifo6 = SX2REG(SX2_FIFO6); /* EP FIFO6 reg */
hostCpu.sx2Fifo8 = SX2REG(SX2_FIFO8); /* EP FIFO8 reg */
hostCpu.sx2Cmd = SX2REG(SX2_CMD_REG); /* command reg */
/* create service message queue */
hostCpu.svcQId = msgQCreate (SVC_Q_MAX_MSGS, SVC_Q_MSG_SIZE, MSG_Q_FIFO);
if (hostCpu.svcQId == NULL)
{
return (ERROR);
}
/* create read sync semaphore */
hostCpu.readSyncSem = semBCreate (SEM_EMPTY, SEM_Q_FIFO);
if (hostCpu.readSyncSem == NULL)
{
return (ERROR);
}
/* spawn service task */
hostCpu.svcTaskId = taskSpawn (SVC_TASK_NAME,
SVC_TASK_PRIO,
SVC_TASK_OPT,
SVC_TASK_STACK,
(FUNCPTR)sx2SvcTask,
0,0,0,0,0,0,0,0,0,0);
if (hostCpu.svcTaskId == ERROR)
{
return (ERROR);
}
/* initialize mandatory function pointers with host CPU and BSP
specific methods */
#if (SX2_BUS_WIDTH == SX2_BUS_8BIT)
hostCpu._func_hostCpuRead = sysInByte;
hostCpu._func_hostCpuWrite = sysOutByte;
#else
hostCpu._func_hostCpuRead = sysInWord;
hostCpu._func_hostCpuWrite = sysOutWord;
#endif
/* initialize optional function pointers */
hostCpu._func_waitReady = ppmc405WaitReady;
hostCpu._func_hostSx2Wakeup = NULL;
hostCpu._func_hostSx2Reset = NULL;
hostCpu._func_hostFlagRead = NULL;
hostCpu._func_hostPktendSet = ppmc405PktendSet;
hostCpu._func_drvCleanup = ppmc405DrvCleanup;
hostCpu._func_isrHook = NULL;
hostCpu._func_readRegNotifyHook = NULL;
hostCpu._func_writeRegNotifyHook = NULL;
hostCpu._func_readFifoNotifyHook = NULL;
hostCpu._func_writeFifoNotifyHook = NULL;
/* perform additional host CPU specific initialization */
/* enable GPIO12 to get control of SX2 PKTEND pin */
if (hostCpu._func_hostPktendSet != NULL)
{
sysDcrCr0Set(sysDcrCr0Get() | CR0_GPIO_12_EN);
}
return (OK);
}
/*******************************************************************************
*
* ppmc405WaitReady() - spin until SX2 READY line goes high, i.e. GPIO22=1
* It is assumed that the BSP has enabled GPIO22.
*
* RETURNS: OK or ERROR.
*/
STATUS ppmc405WaitReady(VOID)
{
UINT32 spinCount = 0;
while ( (!(sysInLong (GPIO_IR) & GPIO_BIT_22))
&& (spinCount++ < hostCpu.maxSpinCount))
;
return ((spinCount < hostCpu.maxSpinCount) ? OK : ERROR);
}
/*******************************************************************************
*
* ppmc405PktendSet() - assert the SX2 PKTEND pin (GPIO12) for the specified FIFO
* PKTEND is active low by default. It is assumed that the
* default pin polarities are used (see POLAR register).
*
* RETURNS: N/A
*/
VOID ppmc405PktendSet(UINT8 fifo)
{
UINT8 dummy;
/* enable GPIO12's driver, drive GPIO12 low to assert PKTEND */
sysOutLong (GPIO_TCR, sysInLong (GPIO_TCR) | GPIO_BIT_12);
sysOutLong (GPIO_OR, sysInLong (GPIO_OR) & (~GPIO_BIT_12));
/* now that PKTEND is low, we need to select the FIFO for which to
assert PKTEND. This is done by generating a dummy access to the
FIFO's address. */
dummy = (*hostCpu._func_hostCpuRead)((UINT32)SX2REG(fifo));
/* drive GPIO12 high and disable driver */
sysOutLong (GPIO_OR, sysInLong (GPIO_OR) | GPIO_BIT_12);
sysOutLong (GPIO_TCR, sysInLong (GPIO_TCR) & (~GPIO_BIT_12));
}
/*******************************************************************************
*
* ppmc405DrvCleanup() - cleanup resources allocated by driver
*
* RETURNS: OK or ERROR.
*/
STATUS ppmc405DrvCleanup(VOID)
{
/* remove driver resources */
if (taskDelete (hostCpu.svcTaskId) == ERROR)
return (ERROR);
if (semDelete (hostCpu.readSyncSem) == ERROR)
return (ERROR);
if (msgQDelete (hostCpu.svcQId) == ERROR)
return (ERROR);
return (OK);
}
/*******************************************************************************
*
* sx2SvcTask() - service task
*
* RETURNS: N/A
*/
VOID sx2SvcTask(VOID)
{
UINT16 intCause;
FOREVER
{
/* wait for messages from SX2 ISR */
if (msgQReceive (hostCpu.svcQId, (UINT8 *)&intCause,
SVC_Q_MSG_SIZE, WAIT_FOREVER) != SVC_Q_MSG_SIZE)
{
logMsg("msgQReceive: error receiving message, errno=%x\n",errno,0,0,0,0,0);
}
else
{
#ifdef SX2_DEBUG
logMsg("message received, data = 0x%x\n", intCause,0,0,0,0,0);
#endif
/* perform task-level operations based on SX2 interrupt cause */
switch (intCause)
{
case SETUP_INT:
/* TODO: handle SETUP interrupt */
break;
case EP0BUF_INT:
/* TODO: handle EP0BUF interrupt */
break;
case FLAGS_INT:
/* TODO: handle FLAGS interrupt */
break;
case ENUMOK_INT:
/* TODO: handle ENUMOK interrupt */
break;
case BUSACTIVITY_INT:
/* TODO: handle BUSACTIVITY interrupt */
hostCpu.sx2BusActive = !hostCpu.sx2BusActive;
break;
case READY_INT:
/* TODO: handle READY interrupt */
break;
default:
logMsg("unknown interrupt, cause = 0x%x\n", intCause,0,0,0,0,0);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -