This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28379D:SCI.TXFFST 中的 fifo 占用不正确

Guru**** 2515445 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1562562/tms320f28379d-incorrect-fifo-occupation-from-sci-txffst

部件号:TMS320F28379D


工具/软件:

您好、

我使用 SCI 并启用了 TX FIFO (9600bps)。 由于设计要求、我不能使用中断或 DMA。
为了发送一些日志消息、我有一个循环中多次调用的函数。

在函数中、我检查 TX fifo 中有多大的空间、并最多填充 16 个字符:

while(SciRegs->SCIFFTX.bit.TXFFST < 16 && transmit_index < data_out_length)
{
     SciRegs->SCITXBUF.all = data_out[transmit_index++];
}

The problem is that I observe random missing characters.

I prepared an experiment with logic analyser where:

  1. TXD line is observed,
  2. each write to SCITXBUF is signaled on specific gpio by state change (6th green signal below),
  3. initial contents of sent buffer is printed on another serial

正确的行为是:

  • 在第一个函数调用时、当 FIFO 为空时、一个'while '循环中有 17 次写入(我假设 FIFO 中有 16 次、TX 寄存器中有 1 次)(每次写入 FIFO~0、35)、
  • 传输每个字符后、'while '循环仅添加一个字符。

出错时、TXD 上会缺少预期的字符。
问题之前是两次写入 fifo、当然会导致 fifo 溢出 — 请参阅双倍写入 FIFO(第一个垂直绿色标记 2xWR)(写入之间有 17 或 32us 间隙)。
在 while 循环的条件下、对 FIFO 的写入次数由 TXFFST 控制。

我的结论是读取 TXFFST 可能会导致值不正确。

SCI 硬件中是否存在种族危险问题?

此致、

Piotr Romaniuk

 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Piotr、

    您能否向我发送 SCI 初始化信息、以便我了解它在您的用例中是如何配置的?

    此致、

    Allison

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Allison:

    SCI 初始化如下所示:

            GPIO_Setup(RX_pin);
            GPIO_Setup(DERE_pin);
    
            EALLOW;
            CpuSysRegs.PCLKCR7.all |= 1<<(SciRegs - &SciaRegs);
            EDIS;
    
            SciRegs->SCICTL1.bit.SWRESET = 0;
            SciRegs->SCIFFTX.bit.SCIRST = 0;
            SciRegs->SCIFFTX.bit.TXFIFORESET = 0;
            SciRegs->SCIFFRX.bit.RXFIFORESET = 0;
    
            SciRegs->SCICCR.all = 0x0007;      // 1 stop bit,  No loopback
                                             // No parity,8 char bits,
                                             // async mode, idle-line protocol
            SciRegs->SCICTL1.bit.TXENA = 1;
            SciRegs->SCICTL1.bit.RXENA = 1;
    
            Uint16 Baudrate_reg = CALC_BAUDRATE(baudrate);
            SciRegs->SCIHBAUD.bit.BAUD = Baudrate_reg >> 8;
            SciRegs->SCILBAUD.bit.BAUD = Baudrate_reg;
            SciRegs->SCICCR.bit.PARITYENA = 0;
            
            SciRegs->SCIFFTX.bit.SCIFFENA = 1;
    
            SciRegs->SCICTL1.bit.SWRESET = 1;
            SciRegs->SCIFFTX.bit.SCIRST = 1;
            SciRegs->SCIFFTX.bit.TXFIFORESET = 1;
            SciRegs->SCIFFRX.bit.RXFIFORESET = 1;
    
            SciRegs->SCITXBUF.all = 0xA;
    
            EALLOW;
            CpuSysRegs.PCLKCR3.all |= 1<<(ECapRegs - &ECap1Regs);
            EDIS;
    
            EALLOW;
            *(&InputXbarRegs.INPUT7SELECT + (ECapRegs - &ECap1Regs)) = RX_pin;         // Set eCAPx source to GPIO-pin
            EDIS;
    
            // Configure peripheral registers
            //
            ECapRegs->ECCTL2.bit.CONT_ONESHT = 0;   // Continuous
            ECapRegs->ECCTL2.bit.STOP_WRAP = 1;     // Stop at 2 events
            ECapRegs->ECCTL1.bit.CAP1POL = 0;       // Rising edge
            ECapRegs->ECCTL1.bit.CAP2POL = 1;       // Falling edge
            ECapRegs->ECCTL1.bit.CTRRST1 = 1;       // Reset counter after latch
            ECapRegs->ECCTL1.bit.CTRRST2 = 1;       // Reset counter after latch
            ECapRegs->ECCTL1.bit.CAPLDEN = 1;       // Enable capture units
    
            ECapRegs->ECCTL2.bit.TSCTRSTOP = 1;     // Start Counter
            ECapRegs->ECCTL2.bit.REARM = 1;         // arm one-shot
            ECapRegs->ECCTL1.bit.CAPLDEN = 1;       // Enable CAP1-CAP4 register loads
    
            Sci_words_x35 = ((float)CPU_CLK / (float)baudrate) * 3.5f * 10.0f;//3.5 times 10bits
            Sci_words_x1 = ((float)CPU_CLK / (float)baudrate) * 1.0f * 10.0f;//1.0 times 10bits
    
            while(!SciRegs->SCICTL2.bit.TXRDY);
            GPIO_Setup(TX_pin);

    此致、

    Piotr Romaniuk

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Alison:

    我发现我也是从中断调用函数。
    它不可重入、这可能是原因。

    I POST 测试结果。

    此致、

    Piotr Romaniuk

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Piotr、  

    完成测试后、请随时在此处更新调查结果。

    此致、

    Allison

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Alison:

    该问题 是由从两个上下文中调用 interrupt_task () 引起的:主循环和中断。
    当 TXFFST 读取和写入 FIFO 之间出现中断时、发生了在主循环上下文中保留旧值的情况。 在中断中、FIFO 被填充、并且在返回后执行第二次写入。

    ==== main loop ctx ====                                      ==== intr ctx ====
    while(SciRegs->SCIFFTX.bit.TXFFST < 16 && ...)
    {
        ------------------ INTERRUPT ------------------------------>
        
                                                                while(SciRegs->SCIFFTX.bit.TXFFST < 16 && ...) {
                                                                     SciRegs->SCITXBUF.all = data_out[transmit_index++];
                                                                }
        <-----------------------------------------------------------                                                            
        
         SciRegs->SCITXBUF.all = data_out[transmit_index++];
    }

    此致、

    Piotr Romaniuk