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.

[参考译文] AM2431:具有 FIFO 的 UART:如何检测中断中的传输结束

Guru**** 657930 points
Other Parts Discussed in Thread: LP-AM243
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1166981/am2431-uart-with-fifo-how-to-detect-the-end-of-transmission-in-interrupt

器件型号:AM2431
主题中讨论的其他器件:LP-AM243

尊敬的 TI:  

配置 HW 以检测传输结束的正确方法是什么?
传输数据后、我们 希望切换到接收模式或执行其他一些操作。
切勿过早切换、这一点很重要。

我们使用 UART FIFO 来缓冲数据、以便在 TX 操作期间减轻 CPU 的负载。
一旦 达到"可编程 FIFO 阈值"电平并且没有更多数据要放入 UART_THR 中、就会禁用中断并完成传输。
开始。 我们是否可以通过中断"空 FIFO 缓冲区和移位寄存器"进行检测、以清楚地指示所有数据已传输的时间?

UART_FCR:TX_FIFO_TRIG 配置似乎不允许设置"0空格"选项。

0h = 8个空格
1h = 16个空格
2h = 32个空格
3h = 56个空格

如果可能的话,对我来说是不干净的。  

...
p_serial_hw_hdl->p_params->readMode         = UART_TRANSFER_MODE_CALLBACK;
p_serial_hw_hdl->p_params->readReturnMode   = UART_READ_RETURN_MODE_PARTIAL;
p_serial_hw_hdl->p_params->writeMode        = UART_TRANSFER_MODE_CALLBACK;
p_serial_hw_hdl->p_params->readCallbackFxn  = mbp_ti_uart_irq_rx_callback;
p_serial_hw_hdl->p_params->writeCallbackFxn = mbp_ti_uart_irq_tx_callback;
...
p_serial_hw_hdl->p_params->hwFlowControlThr = UART_RXTRIGLVL_56; // greater than or equal to the RX FIFO trigger level
p_serial_hw_hdl->p_params->operMode         = UART_OPER_MODE_13X;
p_serial_hw_hdl->p_params->rxTrigLvl        = UART_RXTRIGLVL_56;
p_serial_hw_hdl->p_params->txTrigLvl        = UART_TXTRIGLVL_56;
...

谢谢你。

此致、
ms

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

    我可能发现了同样的问题、并得出结论、此功能不受支持。  
    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/943209/am3358-ep-determine-end-of-uart-data-tx

    我们将尝试通过环回数据并设置"Rx 超时"来解决此问题。

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

    Marek、

    UART_INI2Enable()和 UART_INI2Status() API 似乎可用于启用和检测接收 FIFO 空中断。 有关 UART API 的完整列表、请参阅 用于 UART的 API。
     

    此外、查看 UART_IE2寄存器。 如果您能够 使用这些 API 启用和检测空 FIFO 缓冲区和移位寄存器的中断、请告诉我  

    此致、

    Erik

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

    Erik、

    感谢您的提示。 为了最大程度地减小误差、我切换到了 LP 和官方演示、结果是失败。

    我在 LP-AM243上运行来自 SDK (C:\ti\mcu_plus_sdk_am243x-lp_r5fs0-0_nortos_ti-arm-clang)的官方演示"UART_ECHO_LOW_RELATE_INTERRUPT_AM243x-lp-r5fs0-0_02_00_31。

    此演示具有必要的函数调用、我认为作者甚至打算阻止、直到完成。 但他失败了,因为我失败了。  

    完整代码:

    static void App_uartUserISR(void *arg)
    {
        UART_AppPrms  *appPrms     = (UART_AppPrms *) arg;
        uint32_t       intrType;
    
        intrType = UART_getIntrIdentityStatus(appPrms->baseAddr);
    
        /* Check RX FIFO threshold is set */
        if((intrType & UART_INTID_RX_THRES_REACH) == UART_INTID_RX_THRES_REACH)
        {
            uint32_t       readSuccess;
            uint8_t       *readBuf, readChar;
    
            /* Read all data from RX FIFO */
            readBuf = (uint8_t *)appPrms->readBuf + appPrms->readCount;
            while(1)
            {
                readSuccess = UART_getChar(appPrms->baseAddr, &readChar);
                if(readSuccess == TRUE)
                {
                    if(appPrms->readCount >= APP_UART_BUFSIZE)
                    {
                        /* Rx buffer overflow */
                        appPrms->rxOverflow = TRUE;
                    }
                    else
                    {
                        /* Store data in buffer */
                        *readBuf = readChar;
                        readBuf++;
                        appPrms->readCount++;
                    }
                }
                else
                {
                    break;      /* No data left in FIFO */
                }
            }
    
            if(appPrms->rxOverflow == TRUE)
            {
                /* Stop processing further data */
                UART_intrDisable(appPrms->baseAddr, UART_INTR_RHR_CTI);
            }
        }
    
        /* Check TX FIFO threshold is set */
        if((intrType & UART_INTID_TX_THRES_REACH) == UART_INTID_TX_THRES_REACH)
        {
            uint32_t       numBytesToTransfer;
            const uint8_t *writeBuf;
    
            if(appPrms->writeSizeRemaining > 0U)
            {
                numBytesToTransfer = appPrms->writeSizeRemaining;
                if(numBytesToTransfer > appPrms->txTrigLvl)
                {
                    /* Write only threshold level of data */
                    numBytesToTransfer = appPrms->txTrigLvl;
                }
                appPrms->writeSizeRemaining -= numBytesToTransfer;
    
                /* Send characters upto FIFO threshold level or until done */
                writeBuf = appPrms->writeBuf + appPrms->writeCount;
                while(numBytesToTransfer != 0U)
                {
                    UART_putChar(appPrms->baseAddr, *writeBuf);
                    writeBuf++;
                    numBytesToTransfer--;
                    appPrms->writeCount++;
                }
    
                if(appPrms->writeSizeRemaining == 0U)
                {
                    /* Write complete  - disable TX interrupts */
                    appPrms->txDataSent = TRUE;
                    UART_intrDisable(appPrms->baseAddr, UART_INTR_THR);
                    UART_intr2Enable(appPrms->baseAddr, UART_INTR2_TX_EMPTY);
                }
            }
            else
            {
                /* Disable interrupt */
                UART_intrDisable(appPrms->baseAddr, UART_INTR_THR);
            }
        }
    
        /* Check if TX FIFO is empty */
        if(appPrms->txDataSent == TRUE)
        {
            intrType = UART_getIntr2Status(appPrms->baseAddr);
            if((intrType & UART_INTR2_TX_EMPTY) != 0U)
            {
                UART_intr2Disable(appPrms->baseAddr, UART_INTR2_TX_EMPTY);
                appPrms->txDataSent = FALSE;
    
                GPIO_pinWriteHigh(CONFIG_GPIO_PULSE_BASE_ADDR, CONFIG_GPIO_PULSE_PIN);
                GPIO_pinWriteHigh(CONFIG_GPIO_PULSE_BASE_ADDR, CONFIG_GPIO_PULSE_PIN);
                GPIO_pinWriteHigh(CONFIG_GPIO_PULSE_BASE_ADDR, CONFIG_GPIO_PULSE_PIN);
    
                SemaphoreP_post(&appPrms->writeDoneSem);
    
                GPIO_pinWriteLow(CONFIG_GPIO_PULSE_BASE_ADDR, CONFIG_GPIO_PULSE_PIN);
                GPIO_pinWriteLow(CONFIG_GPIO_PULSE_BASE_ADDR, CONFIG_GPIO_PULSE_PIN);
                GPIO_pinWriteLow(CONFIG_GPIO_PULSE_BASE_ADDR, CONFIG_GPIO_PULSE_PIN);
            }
        }
    
        return;
    }

    以下是我们大家都希望做的神奇之处:

        /* Check if TX FIFO is empty */
        if(appPrms->txDataSent == TRUE)
        {
            intrType = UART_getIntr2Status(appPrms->baseAddr);
            if((intrType & UART_INTR2_TX_EMPTY) != 0U)
            {
                UART_intr2Disable(appPrms->baseAddr, UART_INTR2_TX_EMPTY);
                appPrms->txDataSent = FALSE;
    
                GPIO_pinWriteHigh(CONFIG_GPIO_PULSE_BASE_ADDR, CONFIG_GPIO_PULSE_PIN);
    
                SemaphoreP_post(&appPrms->writeDoneSem);
    
                GPIO_pinWriteLow(CONFIG_GPIO_PULSE_BASE_ADDR, CONFIG_GPIO_PULSE_PIN);
            }
        }

    这就是发生的情况

    此致、

    ms

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

    大家好、

    在和处、我们使用了 RX 和 TX 之间的外部回送、并结合了 RX 超时。  

    此致、

    ms