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.

UART UCTXIFG and UCTXCPTIFG flags set together

Other Parts Discussed in Thread: MSP430FR5859

Hi all,

I am trying to use the UCTXIFG and UCTXCPTIFG flags to determine when the UART has finished transmitting some data I have sent (using DMA to transfer from memory to the TX buffer but I don't suppose that is relevant). I was using the UCTXIFG flag to decide when to send more data and that was working, but now I wish to know when the data has truly left the chip so I started using UCTXCPTIFG. Based on the documentation and other posts here this seems like it should be the correct thing to do, however it isn't working for me. Both UCTXIFG and UCTXCPTIFG are always being set at the same time and often that is in the middle of transmitting the last byte.

I have been testing this with a 'scope and it shows:

  • I am polling the UCA0IFG register about once per 20us starting after the DMA has finished
  • To start with both UCTXIFG and UCTXCPTIFG are clear
  • Both UCTXIFG and UCTXCPTIFG are set together (or at least within the 20us)
  • These bits are set often while the UART TX line is still transmitting the final byte (using 115200baud 8N1 so 1byte is approx 86us)

Has anyone ever seen this before or have any idea what I could be doing wrong?

Thanks

MSP430FR5859

  • Thanks for the link. Reading it and trying things out I realise where I was going wrong. I had rashly assumed that UCTXCPTIFG was cleared each time new data was moved from the TXBUF into the shift registers so I was only checking UCTXCPTIFG after UCTXIFG was set to avoid triggering early. Now I see that I was wrong but I can't work out when UCTXCPTIFG is cleared. Do I have to clear it manually by setting up an ISR and reading the IV register or is there a way to get it to clear itself when data is copied into the shift register?

  • I have posted an example that may be relevant to your problem.
    e2e.ti.com/.../470860
  • That example uses interrupts again which clears the UCTXCPTIFG flag when the interrupt is handled. I'm hoping for something that doesn't require any intervention from the code to clear this flag once data is put back into the shift register. However it doesn't look like that is possible so I might just give up. I did write and test something that uses interrupts and it does work but it is rather fiddly since the interrupts have to be disabled with the DMA is running. Also the UART interrupt priority is fairly low so it can be delayed somwhat when the chip is working hard on something else.

  • In your original posting, you said:

    I wish to know when the data has truly left the chip so I started using UCTXCPTIFG. Based on the documentation and other posts here this seems like it should be the correct thing to do, however it isn't working for me.

    I think what you said is correct, the documentation about UCTXCPTIFG is incorrect and that is why it isn’t working. (See my explanation below.)

    You also said:

    Both UCTXIFG and UCTXCPTIFG are always being set at the same time and often that is in the middle of transmitting the last byte.

    I think that is incorrect. In your case,

    (a) TXIFG is set to begin with, and there is no TXCPTIFG at that time.

    (b) One bit-time later, TXIFG is set again, and there is no TXCPTIFG at that time either

    (c) Another nine bit-times later, TXCPTIFG is set.

    (d) Another one bit-time later, TXIFG is set.

    This (c) and (d) pair repeats until your DMA finishes the block transfer. After that, TXCPTIFG is set twice ten bit-times apart.

    The User’s Guide says:

    UCTXCPTIFG Transmit complete interrupt. This flag is set, after the complete UART byte in the internal shift register including STOP bit got shifted out and UCAxTXBUF is empty.

    I think this flag is set even when UCAxTXBUF is not empty.

  • That bug is confirmed. See:
    e2e.ti.com/.../1704745
  • Thank you for following up on this. 

  • Slau367n now describes the correct operation in Table 30-6.  Slaz681e.pdf  USCI42 is thus cleared and can be removed.

    However, Slau367 still needs to be updated to indicate  how to detect Tx complete.

    I suspect that the last UCTXIFG is followed by two UCTXCPTIFGs thus the following needs to be done:

    1) wait for final UCTXIFG (and do not write to the Tx buffer)

    2) reset UCTXCPTIFG

    3) wait for UCTXCPTIFG (stop bit of second to last byte)

    4) reset UCTXCPTIFG

    5) wait for UCTXCPTIFG to signal Tx complete (stop bit of last byte)

    (The applicable baud rates and if the race condition 1-3 may cause problems will also need clarification:-)

**Attention** This is a public forum