新手入门的系列文档【原创】
本贴讲解了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;
}
|