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

📄 sx2usbdrv.c

📁 CYPRESS的新手上手工具,可以测试设备是否连接,等等。
💻 C
📖 第 1 页 / 共 3 页
字号:
*
* VOID hostSx2Wakeup(VOID);
*
* RETURNS: OK or ERROR.
*/

STATUS sx2Wakeup(VOID)
{

    /* check if host specific wakeup function exists */

    if (hostCpu._func_hostSx2Wakeup != NULL)
    {
        (*hostCpu._func_hostSx2Wakeup)();
        return (OK);
    }

    return (ERROR);
}


/*******************************************************************************
*
* sx2Reset - Reset the SX2. 
*
* The reset operation is completely determined by how the SX2 RESET pin is 
* wired, e.g. if RESET is connected to a host CPU GPIO pin the wakeup function
* pointer should be initialized with a function that asserts the GPIO pin.
*
* The host CPU specific reset function has to be declared as follows:
*
* VOID hostSx2Reset(VOID);
*
* RETURNS: OK or ERROR.
*/

STATUS sx2Reset(VOID)
{

    /* check if host specific reset function exists */

    if (hostCpu._func_hostSx2Reset != NULL)
    {
        (*hostCpu._func_hostSx2Reset)();
        return (OK);
    }

    return (ERROR);
}

 
/*******************************************************************************
*
* sx2SetIntHook - Set the ISR hook function pointer to the specified function. 
*                 The hook can be cleared by passing NULL for hookFunc.
*                 
* The ISR hook has to be defined as follows:  
* 
* STATUS sx2IsrHook(UINT16 intCause)
*
* The main ISR calls this hook and passes the value of the IRQ register,
* indicating the type of interrupt that occurred.
*
* RETURNS: OK.
*/

STATUS sx2SetIntHook(STATUS (*hookFunc)(UINT16))
{

    hostCpu._func_isrHook = hookFunc;
    return (OK);
}


/*******************************************************************************
*
* sx2GetIntHook - Return the ISR hook function pointer.
*
* RETURNS: Hook function pointer.
*/

FUNCPTR sx2GetIntHook(VOID)
{
    return (FUNCPTR)(hostCpu._func_isrHook);
}


/*******************************************************************************
*
* sx2SetNotifyHook - Set the specified notification hook function to the
*                    function pointer provided.
* 
* This function allows the setting of different notification callbacks. 
* The user can assign a callback function to be invoked when certain 
* operations complete. This can be used to implement higher level 
* blocking and non-blocking calls.
*
* The following notification hooks (hookType parameter) are supported:
*
*   READ_REG_NOTIFY   - notification upon register read completion
*   WRITE_REG_NOTIFY  - notification upon register write completion
*   READ_FIFO_NOTIFY  - notification upon fifo read completion
*   WRITE_FIFO_NOTIFY - notification upon fifo write completion
*
* The notification hook functions have to be defined as follows:  
* 
* STATUS notifyHook(UINT32 param)
*
* Notes:
* - to clear a hook, call sx2SetNotifyHook with hookFunc=NULL
* - the hook is invoked with param=0 as this feature is not
*   currently used.
*
* RETURNS: OK or ERROR if hookType invalid.
*/

STATUS sx2SetNotifyHook(UINT8 hookType, STATUS (*hookFunc)(UINT32 param))
{

    /* assign hook function pointer */

    switch (hookType) 
    {
    case READ_REG_NOTIFY:
        hostCpu._func_readRegNotifyHook = hookFunc;
        break;
    case WRITE_REG_NOTIFY:
        hostCpu._func_writeRegNotifyHook = hookFunc;
        break;
    case READ_FIFO_NOTIFY:
        hostCpu._func_readFifoNotifyHook = hookFunc;
        break;
    case WRITE_FIFO_NOTIFY:
        hostCpu._func_writeFifoNotifyHook = hookFunc;
        break;
    default:
        return (ERROR);

    }

    return (OK);
}


/*******************************************************************************
*
* sx2GetNotifyHook - Return the requested notification hook function pointer. 
*
* RETURNS: Hook function pointer or ERROR if hookType invalid.
*/

FUNCPTR sx2GetNotifyHook(UINT8 hookType)
{

    STATUS (*hookFunc)(UINT32);

    /* retrieve hook function pointer */

    switch (hookType) 
    {
    case READ_REG_NOTIFY:
        hookFunc = hostCpu._func_readRegNotifyHook;
        break;
    case WRITE_REG_NOTIFY:
        hookFunc = hostCpu._func_writeRegNotifyHook;
        break;
    case READ_FIFO_NOTIFY:
        hookFunc = hostCpu._func_readFifoNotifyHook;
        break;
    case WRITE_FIFO_NOTIFY:
        hookFunc = hostCpu._func_writeFifoNotifyHook;
        break;
    default:
        return (FUNCPTR)(ERROR);

    }

    return (hookFunc);
}




/* internal routines */

/*******************************************************************************
*
* sx2Isr - SX2 main interrupt service routine
*
* RETURNS: OK or ERROR.
*/

LOCAL VOID sx2Isr(UINT32 param)
{

    UINT32  level;

    /* We first have to check if someone has initiated a read request, in 
       which case the interrupt needs to be treated as a read interrupt */

    /* lock interrupts */

    level = intLock();

    if (hostCpu.readSyncFlag != 0)
    {
        /* We're dealing with a read interrupt. Even though this interrupt 
           doesn't have a bit in the IRQ reg, we still have to acknowledge it 
           by reading the cmd reg, the data read is irrelevant */

        (*hostCpu._func_hostCpuRead) (hostCpu.sx2Cmd);

        /* Wake up the reader task. We only give the semaphore if the reader 
           is a task */

        if ((hostCpu.readSyncFlag) & READER_IS_TASK)
        {
            /* clear read sync flag and unlock ints */

            hostCpu.readSyncFlag = 0;
            intUnlock (level);
            semGive (hostCpu.readSyncSem);
        }
        else
        {
            /* clear read sync flag and unlock ints */

            hostCpu.readSyncFlag = 0;
            intUnlock (level);
        }
    }
    else
    {
        /* unlock interrupts */

        intUnlock (level);

        /* it must be one of the six standard interrupts. Read IRQ reg to clear 
           the interrupt condition. Note that after an interrupt, the IRQ reg is 
           ready to be read, no register read request has to be issued. */

        sx2IntCause = SX2_WORD_SWAP((*hostCpu._func_hostCpuRead) (hostCpu.sx2Cmd));

        /* catch the READY interrupt */

         if (sx2IntCause == READY_INT) 
         {
             hostCpu.sx2Initialized = TRUE;
         }

        #ifdef SX2_DEBUG
            logMsg("SX2 interrupt, cause = 0x%x\n", sx2IntCause,0,0,0,0,0);
        #endif
        
        /* The default action is to send a message to the service task along
           with the type of interrupt that was received. The user has the option
           to supply an interrupt hook if certain actions have to take place
           at interrupt level. This hook is subject to all standard ISR
           restrictions. If no hook is provided, or if the hook returns OK, 
           we send a message to the service task. If the hook returns ERROR 
           no message is sent. */

        if (hostCpu._func_isrHook != NULL)
        {
            if ((*hostCpu._func_isrHook)(sx2IntCause) == OK)
            {
                /* wake up the service task */

                if (msgQSend(hostCpu.svcQId, (UINT8 *)&sx2IntCause, SVC_Q_MSG_SIZE, 
                             NO_WAIT, MSG_PRI_NORMAL) == ERROR)
                {
                    logMsg("sx2Isr() - error sending msg to service task.\n",0,0,0,0,0,0);
                }

            }
        }
        else
        {
            /* wake up the service task */

            if (msgQSend(hostCpu.svcQId, (UINT8 *)&sx2IntCause, SVC_Q_MSG_SIZE, 
                         NO_WAIT, MSG_PRI_NORMAL) == ERROR)
            {
                logMsg("sx2Isr() - error sending msg to service task.\n",0,0,0,0,0,0);
            }
        }
    }
}


/*******************************************************************************
*
* sx2WriteNibbles() - write a byte to the SX2, one nibble at a time
*
* RETURNS: OK or ERROR if timed out polling READY line.
*/

LOCAL STATUS sx2WriteNibbles (UINT8 data)
{

    UINT8 upper = (data >> 4) & 0x0F;
    UINT8 lower = data & 0x0F;

    /* wait for READY to go high */

    if ((*hostCpu._func_waitReady)() != OK)
        return (ERROR);

    /* write first nibble */

    (*hostCpu._func_hostCpuWrite) (hostCpu.sx2Cmd, 
                                   SX2_WORD_SWAP(upper & SX2_CMD_DATA));

    /* wait for READY to go high */

    if ((*hostCpu._func_waitReady)() != OK)
        return (ERROR);
    
    /* write second nibble */

    (*hostCpu._func_hostCpuWrite) (hostCpu.sx2Cmd, 
                                   SX2_WORD_SWAP(lower & SX2_CMD_DATA));

    return (OK);
}


/*******************************************************************************
*
* sx2DrvCleanup() - clean up resources allocated by driver
*
* The host CPU specific cleanup function has to be defined as follows:  
* 
* STATUS hostSx2DrvCleanup(VOID)
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS sx2DrvCleanup(VOID)
{

    STATUS  status = OK;

    if (hostCpu._func_drvCleanup != NULL)
    {
        status = (*hostCpu._func_drvCleanup)();
    }

    hostCpu.sx2Initialized = FALSE;

    return (status);
}


/*******************************************************************************
*
* sx2FlushFifos() - flush all SX2 FIFOs
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS sx2FlushFifos(VOID)
{

    if (sx2WriteReg(INPKTENDFLUSH, 
                    FIFO2FLUSH|FIFO4FLUSH|FIFO6FLUSH|FIFO8FLUSH) == ERROR)
    {
        return (ERROR);
    }

    return (OK);
}


/*******************************************************************************
*
* sx2SetFifoWidth() - Set access width of FIFOs as defined by macros
*                     SX2_BUS_WIDTH and SX2_FIFO_WIDTH
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS sx2SetFifoWidth(VOID)
{

    UINT32  i;
    UINT8   data;
    UINT8   reg = EP2PKTLENH;

#if (SX2_BUS_WIDTH == SX2_BUS_16BIT)

    /* walk through the 4 EPxPKTLENH registers and set/clear the WORDWIDE bit */

    for (i=0; i<4; i++) 
    {
        if (sx2ReadReg(reg, &data) == ERROR)
            return (ERROR);

        #if (SX2_FIFO_WIDTH == SX2_FIFO_16BIT)
        data |= WORDWIDE;
        #else
        data &= ~WORDWIDE;
        #endif

        if (sx2WriteReg(reg, data) == ERROR)
            return (ERROR);

        reg += 2;

        /* The delay is needed, determined through experimentation. If no delay
           is inserted, the first read/write sequence completes ok. The second
           time around, the SX2 will not generate any more read interrupts (or any
           other interrupts for that matter). The task calling sx2SetFifoWidth() 
           will be pended on the read sync semaphore forever. This appears to 
           be a timing problem on the SX2, apparently caused when a write is 
           immediately followed by a read. Need clarification from Cypress. */
                      
        taskDelay (1);
    }
#endif

    return (OK);
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -