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.

AM3352: UART FIFO EMPTY interrupt

Part Number: AM3352
Other Parts Discussed in Thread: AMIC110

Hi experts

My customer currently uses [SCR.TXEMPTYCTLIT=1] for UART FIFO EMPTY interrupt.
However, according to actual measurements, in the case of high baud rate transmission, there is a very small probability (<1%) of interrupts causing ms-level delays;
So we want to ask, are there any other registers or other interrupts that can achieve the purpose of UART FIFO EMPTY interrupt?
Thanks!

  • Hello Ethan,

    Thanks for the question.

    I have done my part and gone through the AM335x TRMhttps://www.ti.com/lit/ug/spruh73q/spruh73q.pdf

    I have gone through the UART registers and found out that apart from UART SCR(Supplementary Control Register) register you can use the UART SSR(Supplementary Status Register) register.

    In UART SSR register. bit 0 will help in identifying if the TX FIFO is full or not.

    For your reference I am going to attach a snippet from the TRM and also give the section here: 19.5.1.40

    I hope the above information helps.

    Looking forward to your response.

    Thanks,

    Vaibhav

  • Hello Vaibhav

    Thanks for the answer!
    If I want to determine whether the TX FIFO is empty, which register should I use to determine it?

  • Hello Ethan, 

    I am not sure if there is an alternative signal available that could be used to identify TX FIFO empty.

    I looked at the below sections and the below E2E.

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/313302/uart-shift-register-empty-interrupt

    Is there a way to set an interrupt to occur when the transmit shift register is empty on AM335x? Thanks in advance!

    Yes, this is the TXEMPTYCTLIT bit in the SCR Register (AM335X Technical Reference Manual, Rev. J, section 19.5.1.39).

    Regards,

    Sreenivasa

  • Hello Sreenivasa

    Regarding the THR interrupt of AM3352's UART, we use TXEMPTYCTLIT bit to configure the THR interrupt triggering time (set the FIFO threshold to 0):

    According to the setting, when TX FIFO empty and shift register empty are satisfied at the same time, THR interrupt will be triggered;
    However, we found that in some cases, the interrupt was triggered a bit later than it actually was.

    Can we use the following FIFO empty interrupt to determine that the transfer has been completed? Will the timeliness be improved compared to the above usage?

  • Hello Ethan, 

    Please refer below.

    https://e2e.ti.com/support/archive/internal/int-processors/f/int--processors-forum-read-only/272386/am335x-trigger-of-uart-thr-interrupt/951335?tisearch=e2e-sitesearch&keymatch=TXEMPTYCTLIT#951335

    the TX_EMPTY_CTL_IT bit functions as described. Here is further clarification:

    If TX_EMPTY_CTL_IT = 1: LSR.TX_SR_E asserts the interrupt.

    If TX_EMPTY_CTL_IT = 0, then:

    FCR.FIFO_E = 0: LSR.TX_FIFO_E asserts the interrupt.
    FCR.FIFO_E = 1: FIFO level < trigger level asserts the interrupt.

    Can we use the following FIFO empty interrupt to determine that the transfer has been completed? Will the timeliness be improved compared to the above usage?

    Not sure if this is an interrupt. You could use this to understand if FIFO is empty.

    Regards,

    Sreenivasa

  • Hello Sreenivasa

    However, the RTOS demo code uses the IER2/ISR2 register pair

    Void UARTInt2Enable(unsigned int baseAddr, unsigned int intFlag)
    {
    /* Programming the bits IER2[1:0]. */
    HW_WR_REG32(haseAddr + part_IER2, HW_RD_REG32(haseAddr + part_IER2) | (intFlag & 0x03U));
    }

    Unsigned int UARTInt2Statusget(unsigned int baseAddr)
    {
    unsigned int retVal = 0;
    
    RetVal = HW_RD_REG32(baseAddr + part_ISR2) &
    (SUART_IER2_EN_RXFIFO_empty_mask | part_IER2_EN_TXFIFO_empty_mask);
    
    Return retVal;
    }
    This pair of registers is also described in the User Manual
    19.5.1.49 IER2 Register (offset = 6Ch) [Reset = 0h]
    19.5.1.50 ISR2 Register (offset = 70h) [reset = 0h]

    Are these registers actually available (in the AM3352)?
    Because customers have actually tested it here and it does trigger an interrupt to the FIFO empty, but I'm not sure if it's being used correctly, so I'm going to ask

  • Hello Ethan, 

    Please refer below ISR2 description.

    ISR2 is shown in Figure 19-83 and described in Table 19-79. Refer to Section 19.3.7.1 to determine the mode(s) in which this register can be accessed. The ISR2 displays the status of RX/TX FIFOs empty corresponding interrupts.

    Are these registers actually available (in the AM3352)?
    Because customers have actually tested it here and it does trigger an interrupt to the FIFO empty, but I'm not sure if it's being used correctly, so I'm going to ask

    Please check and update the thread.

    I will have to reassign the thread based on the answer.

    Regards,

    Sreenivasa

  • Hello Sreenivasa

    Customer's deployment is based on the following code from the RTOS SDK: 

    hile ((bool)true){
            intType = UARTIntIdentityGet(hwAttrs->baseAddr);
            
            /* Receive IRQ Process */
            if ((intType & SUART_INTID_RX_THRES_REACH) == SUART_INTID_RX_THRES_REACH){
                if ((intType & SUART_INTID_RX_LINE_STAT_ERROR) ==  SUART_INTID_RX_LINE_STAT_ERROR){
                    /* RX line status error */
                    SUARTDrv_procLineStatusErr(handle);
                }else{
                    if ((intType & SUART_INTID_CHAR_TIMEOUT) == SUART_INTID_CHAR_TIMEOUT){
                        /* rx timeout, log the rx timeout errors */
                        object->rxTimeoutCnt++;
                    }
    
                    /* RX FIFO threshold reached */
                    if (object->readSize > 0U){
                        object->readSize = (size_t)SUARTDrv_v1_readData(handle, (int)(object->readSize));
                        if ((object->readSize) == 0U){
                            UARTIntDisable(hwAttrs->baseAddr, SUART_INT_RHR_CTI | SUART_INT_LINE_STAT);
                            /* Reset the read buffer so we can pass it back */
                            object->readBuf = (unsigned char *)object->readBuf - object->readCount;
                            if (object->readTrans != NULL){
                                object->readTrans->count = (unsigned int)(object->readCount);
                                object->readTrans->status = SUART_TRANSFER_STATUS_SUCCESS;
                            }
    
                            /* Call back to application if in callback mode */
                            SUARTDrv_callback(handle, (bool)true);
                            object->readTrans = NULL;
                        }
                    }else{
                        (void)UARTCharGetNonBlocking2(hwAttrs->baseAddr, &rdData);
                        UARTIntDisable(hwAttrs->baseAddr, SUART_INT_RHR_CTI | SUART_INT_LINE_STAT);
                    }
                }
            }else if ((intType & SUART_INTID_TX_THRES_REACH) == SUART_INTID_TX_THRES_REACH){
                /* TX FIFO threshold reached */
                if (object->writeSize > 0U){
                    object->writeSize = (size_t)SUARTDrv_writeData(handle, (int)(object->writeSize));
                    if ((object->writeSize) == 0U){
                        UARTIntDisable(hwAttrs->baseAddr, SUART_INT_THR);
                        /* Reset the write buffer so we can pass it back */
                        object->writeBuf = (const unsigned char *)object->writeBuf - object->writeCount;
    
                        if (object->writeTrans != NULL){
                            object->writeTrans->count = (unsigned int)(object->writeCount);
                            object->writeTrans->status = SUART_TRANSFER_STATUS_SUCCESS;
                        }
    
                        object->txDataSent = TRUE;
                        UARTInt2Enable(hwAttrs->baseAddr, SUART_INT2_TX_EMPTY);
                    }
                }else{
                    UARTIntDisable(hwAttrs->baseAddr, SUART_INT_THR);
                }
            }else{
                break;
            }
        }
    
        if (object->txDataSent == TRUE){
            intType = UARTInt2StatusGet(hwAttrs->baseAddr);
            if ((intType & SUART_INT2_TX_EMPTY) != 0U){
                UARTInt2Disable(hwAttrs->baseAddr, SUART_INT2_TX_EMPTY);
    
                /* Call back to application if in callback mode */
                SUARTDrv_callback(handle, (bool)false);
                object->writeTrans = NULL;
                object->txDataSent = FALSE;
            }
        }
    

    I understand that after setting IER2.EN_TXFIFO_EMPTY = 1, a UART interrupt (IIR.T_PENDING == 1) will be generated, but this interrupt is not in the IIR.IT_TYPE list. ISR.TXFIFO_EMPTY_STS is required to determine
    This new interrupt should not be a THR interrupt. THR interrupt was turned off before IER2 was set

    BR

    Ethan

  • Hello Ethan, 

    Thank you for the inputs.

    Please help me understand customer query in the note.

    Regards,

    Sreenivasa

  • Hello Sreenivasa

    Thank you for your quick response, please tell me what a note is?

    Customer wants to know can they use ISR2 as FIFO empty interrupt to determine that the transfer has been completed? Because customers have actually tested it.

    BR

    Ethan

  • Hello Ethan, 

    Thank you.

    please tell me what a note is?

    The content of a thread is the message or note.

    Customer wants to know can they use ISR2 as FIFO empty interrupt to determine that the transfer has been completed? Because customers have actually tested it.

    I need to check internally.

    You said customer has tested ISR2 and works for him - is that correct?

    Regards,

    Sreenivasa

  • Hi Sreenivasa

    Yes, your understanding is correct 

  • Hello Ethan, 

    Thank you. Let me check with the team and update you.

    Regards,

    Sreenivasa