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

📄 sx2hostcpu.c

📁 CYPRESS的新手上手工具,可以测试设备是否连接,等等。
💻 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 + -