打印

FX3 CyU3PGpifReadDataWords API详解 (新手入门手册)

[复制链接]
1906|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zengweitotty|  楼主 | 2015-12-15 16:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
新手入门的系列文档【原创】
本贴讲解了API的使用方法和源代码分析。
如下是API的声明部分。CyU3PReturnStatus_t
CyU3PGpifReadDataWords (
        uint32_t  threadIndex,    //线程号
        CyBool_t  selectThread,   //是否选择线程
        uint32_t  numWords, //需要读取多少个字
        uint32_t *buffer_p, //读取到的字存储的地址
        uint32_t  waitOption)     //等待多长时间

1. 参数判断
       如果当前传递的thread号大于4,返回CY_U3P_ERROR_BAD_ARGUMENT
       如果当前PIB工作在PP mode下,返回CY_U3P_ERROR_FAILURE
      如果当前传递的参数selectThread=CyTrue,同时当前的Thread的号是通过state machine中指定thread号,或者是通过地址线选择thread号,返回CY_U3P_ERROR_FAILURE
2. selectThread=CyTrue, 配置当前的DATA_THREAD[1:0]为相应的值。
3. 判断一下在对应DATA_THREAD是否有数据,拷贝到相应的buffer_p对应的地址空间,清除DATA_THREAD数据有效的中断。
4. 配置DATA_THREAD有有效数据时产生中断,读取相应的数据到buffer_p对应的地址空间,并清除DATA_THREAD数据有效的中断
在CyU3PgpifIntHandler中将会设置相应的事件。注意事件的bitmarks是从bit[12]开始的,

        if (intrVal & CY_U3P_GPIF_INTR_IN_DATA_VALID_MASK)
        {
            /* Find which threads have active in_data_empty status andupdate the events. */
            msg = ((intrVal &CY_U3P_GPIF_INTR_IN_DATA_VALID_MASK) >> (CY_U3P_GPIF_INTR_IN_DATA_VALID_POS - 8));
            CyU3PEventSet (&glPibEvt, msg,CYU3P_EVENT_OR);

            PIB->gpif_intr =CY_U3P_GPIF_INTR_IN_DATA_VALID_MASK;
        }

源代码讲解:
CyU3PReturnStatus_t
CyU3PGpifReadDataWords (
        uint32_t  threadIndex,    //线程号
        CyBool_t  selectThread,   //是否选择线程
        uint32_t  numWords, //需要读取多少个字
        uint32_t *buffer_p, //读取到的字存储的地址
        uint32_t  waitOption)     //等待多长时间


{
    CyU3PReturnStatus_t status;
    uint32_t tmp, mask;

    if (threadIndex >= CYU3P_PIB_THREAD_COUNT) //线程号不能超过4个
    {
        return CY_U3P_ERROR_BAD_ARGUMENT;
    }

    if ((PIB->gpif_config & CY_U3P_GPIF_CONF_PP_MODE) != 0) //不能在PP mode下使用
    {
        return CY_U3P_ERROR_FAILURE;
    }

    /* If the thread has to be activated, check if software basedthread selection
     * is permitted; and do so.
     */
    if (selectThread)
{
//如果支持firmware选择thread号,则需要判断gpif_config寄存器中是否是从状态机中选择thread号,同时是从DATA_THREAD中读取数据,不是根据地址线来选择DATA_THREAD
        if (((PIB->gpif_config & CY_U3P_GPIF_CONF_THREAD_IN_STATE) != 0) ||
                ((PIB->gpif_ad_config & CY_U3P_GPIF_AIN_DATA) == 0))
        {
            return CY_U3P_ERROR_FAILURE;
        }
//选择从哪个DATA_THREAD中读取数据
        PIB->gpif_ad_config = (PIB->gpif_ad_config & ~CY_U3P_GPIF_DATA_THREAD_MASK) |
            (threadIndex <<CY_U3P_GPIF_DATA_THREAD_POS);
    }

/* If the register already has data, read the first word from itdirectly without waiting for an event. */

//查看当前的DATA_THREAD中有数据,如果有数据,则拷贝到buffer_p对应的地址空间
    if (PIB->gpif_status & (1 << (CY_U3P_GPIF_STATUS_IN_DATA_VALID_POS +threadIndex)))
    {
        *buffer_p++ = PIB->gpif_ingress_data[threadIndex];
        PIB->gpif_data_ctrl = (1 << threadIndex); //清除DATA_THREAD中有数据的标记,写1清除
        numWords--;
    }

    if (numWords)
    {
        /* Make sure that the IN_DATA_READY interrupt for this threadhas been enabled. */
       //设置当前DATA_THREAD有数据时,要响应相应的中断
        PIB->gpif_intr_mask |= (1 << (CY_U3P_GPIF_INTR_IN_DATA_VALID_POS +threadIndex));
        /* For each word, wait for the data ready event and copy thedata into the buffer. */
        mask = (1 <<(CY_U3P_PIB_THR0_INDATA_EVT_POS + threadIndex));//捕获当前DATA_THREAD中断产生的事件
        while (numWords--)
        {
            status = CyU3PEventGet(&glPibEvt, mask, CYU3P_EVENT_OR_CLEAR, &tmp, waitOption);//有数据
            if (status != CY_U3P_SUCCESS)
            {
                return status;
            }

            /* Read the data into the buffer and clear the data valid flag.*/
            *buffer_p++ = PIB->gpif_ingress_data[threadIndex];
            PIB->gpif_data_ctrl = (1 << threadIndex); //清除DATA_THREAD中有数据的标记,写1清除
        }
    }

    return CY_U3P_SUCCESS;
}

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

61

帖子

19

粉丝