Cypress技术william hill官网
直播中

王莉

7年用户 302经验值
私信 关注
[问答]

RX_FIFO_RD_SILENT功能不起作用?

你好,
我正在运行低级UART W/ISR的示例应用CE219656。该部分已更改为运行在PSoC6 WiFi板上。未修改的代码工作正常。然而,对于我的应用程序,我想看看在执行FIFO读之前,RX FIFO堆栈上最新接收到的字节是什么(即我想在FIFO弹出之前偷窥)。这应该是通过读取RXYFIFOZRDY静默寄存器而不是中断服务例程中的RXI FIFORYRD寄存器来实现的。但是,当我将这行添加到ISR代码:Read StaseDe= UARTHYHW-GT;RXYFIFORZRDY静默在调用Read Opthys= CysScBuUARTHEGET(UARTHYHW)之前,数据被损坏;即不正确的字符被写入终端。我猜想,添加Read Office=UARTHYHW-GT;RXA FIFOORDDSIOLL不应该破坏代码。我能正确地理解这一点吗?谢谢你,史葛

以上来自于百度翻译


     以下为原文
  
Hi,

I am running the example application CE219656 for low-level UART w/ ISR.  The part has been changed to run on the PSOC6 WiFi board.

Non-modified code works as expected.  However, for my application, I am trying to see what the latest received byte is on the RX FIFO stack before performing a FIFO read, ie I want to 'peek' before I 'pop' the FIFO.

This should be achievable by reading the  RX_FIFO_RD_SILENT register instead of the RX_FIFO_RD register in the interrupt service routine.

However, when I add this line to the ISR code:

read_data = UART_HW->RX_FIFO_RD_SILENT  

before the call to  

read_data = Cy_SCB_UART_Get(UART_HW)

the data is corrupted; ie the incorrect characters are written to the terminal.

I would suspect that adding the  

read_data = UART_HW->RX_FIFO_RD_SILENT  

should not break the code.

Am I understanding this correctly?

Thank you,
Scott

回帖(3)

刘建伟

2018-9-29 16:09:59
我只是回顾了这段代码,注意到在中断代码中有一个bug。您的用例导致这个bug出现。
错误是在FIFO中读取数据之前清除RX FIFO非空中断。在代码示例中,在中断被清除之后,FIFO被直接读取,我相信它足够快,不会导致中断重新触发。在您的情况下,在中断清除和实际读取之间插入代码,这会导致中断再次触发。因此,ISR再次进入,导致它从空FIFO中读出…
为了解决这个问题,在FIFO的读取下移动中断清除代码:
Read数据=UARTHYHW-gt;
*从终端获取字符*
RealthDATA=CysScBuUARTHEGET(UARTHYHW);
/*清除UART“RX FIFO不空中断”*/
UARTHY-HW-GT;InTyrx=UARTHY-HW-GT;
但是,对于这个代码,仍然存在一个问题,它引起了中断,因为一个不同的原因,我还没有调试过。因此,对于您的用例充分工作,你需要改变你的ISR看起来像:
空隙ISRUUART(无效)
{
*检查“RX FIFO不是空中断”*/
如果(UARTHI HW-GT;InthRx掩码和SCBIInrxRxMaskddNoToPosiTyjyMSK)!= 0)
{
Read数据=UARTHYHW-gt;
*从终端获取字符*
RealthDATA=CysScBuUARTHEGET(UARTHYHW);
/*清除UART“RX FIFO不空中断”*/
UARTHY-HW-GT;InTyrx=UARTHY-HW-GT;
/*更新DATAY接收标志*/
DATAY接收=1;
}
其他的
{
/*如果发生任何其他中断* *
//UARTHARE错误=1;
}
}
当我考虑中断是如何导致错误代码运行时,我会回过头来。我猜是下溢。

以上来自于百度翻译


     以下为原文
  I was just reviewing this code and noticed that there is a bug in the interrupt code. Your use case caused this bug to show up.
 
The bug is that the RX fifo not empty interrupt is cleared before data is read out of the FIFO. In the code example the FIFO was read directly after the interrupt was cleared which I believe was fast enough to not cause the interrupt to retrigger. In your case you inserted code between the interrupt clear and the actual read, which causes the interrupt to fire again. So the ISR gets entered again which causes it to read out of an empty fifo...
 
To fix the issue move the interrupt clear code below the read of the FIFO:
 
 
        read_data = UART_HW->RX_FIFO_RD_SILENT;
        /* Get the character from terminal */
read_data = Cy_SCB_UART_Get(UART_HW);
       
        /* Clear UART "RX fifo not empty interrupt" */
UART_HW->INTR_RX = UART_HW->INTR_RX & SCB_INTR_RX_NOT_EMPTY_Msk;  
 
However with this code there is still an issue which causes the interrupt to fire for a different reason I haven't debugged yet. So for your use case to fully work you need to change your ISR to look like:
void ISR_UART(void)
{
    /* Check for "RX fifo not empty interrupt" */
    if((UART_HW->INTR_RX_MASKED & SCB_INTR_RX_MASKED_NOT_EMPTY_Msk ) != 0)
{    
       
        read_data = UART_HW->RX_FIFO_RD_SILENT;
        /* Get the character from terminal */
read_data = Cy_SCB_UART_Get(UART_HW);
       
        /* Clear UART "RX fifo not empty interrupt" */
UART_HW->INTR_RX = UART_HW->INTR_RX & SCB_INTR_RX_NOT_EMPTY_Msk;  
 
 
        /* Update data_received flag */
        data_received = 1;       
}  
    else
    {
        /* Error if any other interrupt occurs */
        //uart_error = 1;
    }
}
 
I'll post back when I figure how which interrupt is causing the error code to run. My guess is that it is underflow.
举报

刘建伟

2018-9-29 16:17:21
引用: 60user133 发表于 2018-9-29 13:28
我只是回顾了这段代码,注意到在中断代码中有一个bug。您的用例导致这个bug出现。
错误是在FIFO中读取数据之前清除RX FIFO非空中断。在代码示例中,在中断被清除之后,FIFO被直接读取,我相信它足够快,不会导致中断重新触发。在您的情况下,在中断清除和实际读取之间插入代码,这会导致中断再次触发。因此,ISR再次进入, ...

你还需要清除ISR中的NVIC。由于FIFO不是空信号是电平,并且NVIC再次触发。
下面是我的代码:
空隙ISRUUART(无效)
{
*检查“RX FIFO不是空中断”*/
如果(UARTHI HW-GT;InthRx掩码和SCBIInrxRxMaskddNoToPosiTyjyMSK)!= 0)
{
Read数据=UARTHYHW-gt;
*从终端获取字符*
RealthDATA=CysScBuUARTHEGET(UARTHYHW);
/*清除UART“RX FIFO不空中断”*/
UARTHY-HW-GT;InTyrx=UARTHY-HW-GT;
NVICI- CultBuangIrrq(UARTHI SCBIIQLYCFG.In SRSRC);
/*更新DATAY接收标志*/
DATAY接收=1;
}
其他的
{
/*如果发生任何其他中断* *
UARTHARE错误=1;
}
}

以上来自于百度翻译


     以下为原文
  You also need to clear the NVIC in the ISR. As the FIFO not empty signal is level, and the NVIC gets triggered again.
 
Here is the code that works for me:
 
void ISR_UART(void)
{
    /* Check for "RX fifo not empty interrupt" */
    if((UART_HW->INTR_RX_MASKED & SCB_INTR_RX_MASKED_NOT_EMPTY_Msk ) != 0)
{    
       
        read_data = UART_HW->RX_FIFO_RD_SILENT;
        /* Get the character from terminal */
read_data = Cy_SCB_UART_Get(UART_HW);
       
        /* Clear UART "RX fifo not empty interrupt" */
UART_HW->INTR_RX = UART_HW->INTR_RX & SCB_INTR_RX_NOT_EMPTY_Msk;
        NVIC_ClearPendingIRQ(UART_SCB_IRQ_cfg.intrSrc);
 
 
        /* Update data_received flag */
        data_received = 1;       
}  
    else
    {
        /* Error if any other interrupt occurs */
        uart_error = 1;
    }
}
举报

王莉

2018-9-29 16:27:23
引用: 60user133 发表于 2018-9-29 13:35
你还需要清除ISR中的NVIC。由于FIFO不是空信号是电平,并且NVIC再次触发。
下面是我的代码:
空隙ISRUUART(无效)

感谢您的快速和详细的响应!
这确实是意料之中的事情。
最好的问候,
斯科特

以上来自于百度翻译


     以下为原文
  Thank you for your fast and detailed response!
 
This is indeed working as expected.
 
Best regards,
Scott
举报

更多回帖

发帖
×
20
完善资料,
赚取积分