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.

How do you turn off the UART Transmitter at the end of an EDMA transfer?

I'm having trouble turning off the UART transmitter in an automatic DMA transfer to the THR register in the UART.  The sequence of operations is:

1) Incoming characters hit the UART RBR Register triggering an EDMA transfer in the UART RX channel into "Buffer 1".

2) The TCCHEN bit in the OPT register of that PaRAM set is on to chain the TX event at the completion of the RX channel transfer.

3) When the RX EDMA transfer completes, the event is chained into the TX event bit in the EDMA.CER register.

4) The TX channel's EDMA transfer begins taking data from "Buffer 2" and sending it to the UART's THR register for transmission. 

The problem is that I can't get it to stop after transmitting the buffer to wait for the next Chained Event from the RX channel.  I want to send out "Buffer 2" and then wait for the next receipt of data for "Buffer 1" through the RX channel before sending "Buffer 2" a second time.

i) If I use a valid LINK in the PaRAM set to reload the TX PaRAM set when the transfer completes, then that linked PaRAM set gets loaded and the transfer starts up all over again and never stops. 

ii) If I use a LINK of 0xFFFF in the TX PaRAM set it will stop the transfer at the right time but then when I try to reload the Tx PaRAM set with a Chained Event to another EDMA transfer, the completion of that third transfer starts up the transmission of data out of the UART all over again even though there has not been an event to trigger the transfer.

The confusing thing is that the RX channel EDMA PaRAM set seems to work flawlessly with the triggering events.  The UART gets data, raises an event to the EDMA CC and the UART's RX PaRAM set reads the correct number of bytes from the UART's RBR register and then it STOPs after linking in a new PaRAM set.  The Rx PaRAM set ends up sitting there ready to go the next time.  One event and you have one transfer and a linked reload of the PaRAM set.   But in the TX channel. one triggering event leads to an infinite number of DMA transfers if the PaRAM set has a linked PaRAM set.

I need to be able to have the UART's TX PaRAM set complete the A-synchronized transfer, link in the LINK PaRAM set and then sit there waiting for another triggering event.

I've tried to use other EDMA transfers to toggle the UART's PWREMU_MGMT.URTST bit to disable the transmitter but that doesn't work either and would be very kludgy even if it did.

Any help would be greatly appreciated.

Thanks,

Mike

 

 

 

  • Never mind.  The UART TX Event was enabled in the EDMA's EER register so things basically got into an infinite loop.  The completion of the chained event EDMA transfer to the UART reloaded the PaRAM set and then the UART's THR empty event was raised which triggered the freshly loaded EDMA transfer.  And it just kept going. 

    But this raises another issue in that if you turn off the TX Event in the EER and send the UART a series of bytes, the UART does not fully transmit the byte string passed to it and things stall. 

    Is there example code of autonomous UART RX and TX processing by the EDMA controller under DSP/BIOS anywhere on the web site?

    Mike

  • Is the device the C6747 since that is one of your tags?

    How many UART words do you want to send? I have not studied it, yet, until I know what device, but it will also help to know exactly what you expect to be coming in for each RX event and going out for each chained Tx event.

    Michael Manness said:

    But this raises another issue in that if you turn off the TX Event in the EER and send the UART a series of bytes, the UART does not fully transmit the byte string passed to it and things stall. 

    The implication I read into this is that you are sending more than 1 UART word per received word. So for both directions, it will be helpful to know how many you want to move, and how many are going out before "things stall".

    What stalls?

  • Hi Randy,

    Yes, the device is a C6747 and I am working on the EVM board.

    The message that I was trying to send is a status response of 7 bytes.  The incoming message is 4 bytes.

    The sequence of events that I was trying to set up was:

    1) A 4 byte status request arrives at UART 2 from the host processor.

    2) The UART raises an event (30) to the DMA controller with every byte.  A total of 4 events.

    3) The DMA controller takes the incoming data and puts it into a buffer.

    4) The PaRAM set for the RX channel (30) has ACNT = 1, BCNT = 4 so it links in a copy of itself from PaRAM set 80 upon transfer completion.  It also has TCCHEN=1 and TCC = 31 to trigger a DMA transfer of the status response of 7 bytes from a second buffer to the transmitter in UART 2.

    5) With the chained event (31) the DMA CC loads PaRAM Set 31 which has ACNT = 1 and BCNT = 7, and Link = 81.

    6) EDMA3 TC0 transfers the 7 bytes and then reloads the PaRAM Set from the link at PaRAM Set 81.

    The problem is that UART 2 raises an event to the DMA CC when its THR register is empty.  That seems to be triggering the DMA CC to queue PaRAM Set 31 all over again and the same status response of 7 bytes gets sent in what amounts to an infinite loop.  I was hoping to stop after the first status response and wait until another status request arrives at UART2.RX which would trigger the sequence all over again.

    WRT "things stall", what I tried to do to get around the infintie loop was to clear bit 31 in EDMA3.EER for UART2 transmit.  When I did that, the PaRAM Set 31 transfer was loaded and partially executed - it did not send all 7 bytes.  I only saw the first byte on the Hyperterm session that I was running to talk to the DSP's UART.  Reading UART2.RBR in CCS 3.3, the same register as UART2.THR, gave me back the 4th byte of the message that I was trying to send.

    I tried a couple of things on Saturday using chained events off of PaRAM set 31 in an effort to turn off and on the TX events to the DMA controller but I wasn't successful and the chained events were getting cumbersome - it just didn't seem like the correct approach.

    Thanks for getting back to me,

    Mike

  • There are a couple of directions you can go here, easy and less easy.

    In your system flow, is it true that the UART 16-byte transmit FIFO will always be completely empty when you reach step 6) above? This would mean that you would never have other data queued up in the FIFO. This would be the easy way, so we can continue when you have a chance to reply.

  • Randy,

    Yes, I believe that the UART transmit FIFO should be empty when the scenario gets to Step 6.  Messages to the UART are being queued one at a time in a relatively intermittent fashion.

    Having said that, I should give you a heads up that I've had to fiddle the length of the transmit message to be 1 byte less than the actual message length, otherwise, I'm seeing an extra character.  For example, if my message has 12 bytes of data to be shifted out of the UART, then I seem to have to load 11 into the PaRAM Set BCNT value.  My transfers are A-synchronized.  It doesn't make sense to me but the kludge seems to give the right number of characters being sent.   After the bytes go out, I then have to manually disable the transmitter with UART.PWREMU_MGMT.UTRST = 0 or else the transmitter will keep sending out extra characters.  It is a related issue in a slightly different context (manual message parsing rather than an automated response) but I thought that I'd mention the 1 character offset just in case it affects your answer. 

    Thanks,

    Mike

  • The idea that I expect would work would be to send all 7 bytes in response to one event, which would mean using ABSync instead of ASync for the transmit data. Each write to the TFR will really have to be 32 bits, so either you will have to store the bytes in sequential 32-bit words in your memory buffer or you will have to do some address or EDMA trickery to get packed bytes written separately. But in any case, clear the EER bit for the UART Tx.

    The easiest is if you can store the 12 bytes in a 32-bit wide buffer, then set ACNT=4, BCNT=12, SRCBIDX=4, SyncDim=ABSync. Then when a single event like the chaining event from the UART read DMA completion occurs, you will send all 12 bytes at one time.

    If that is not practical, another option is to store the bytes in reverse order in the buffer, then set SRCADDR=<1st to send=Buf+11>, ACNT=1, BCNT=12, SRCBIDX=-1, SyncDim=ABSync. Then when a single event occurs, you will send all 12 bytes one-at-a-time.

    If neither of those works well or you do not like them, we can come up with more, like self-chaining, etc. After we figure out how to get the data sent out, we can work on the mis-count problem.

  • Randy,

    Thanks for the tips.  I'll give them a try.  Because of other things, it may take me a couple of days to get back to you.

    Mike

  • Randy,

    Sorry about not getting back to you sooner.  My host took a power surge through a USB port last Wednesday which messed up a bunch of stuff and I'm still trying to rebuild my development environment.  It'll be another few daze!

    Mike

  • Randy,

    Thank you very much.  I got the automatic EDMA response to work with BCNT = 1, ACNT = 8, SRCBIDX = 1, SyncDim=ABSync and the UART TX bit in the EER cleared.  Sorry that it took so long to get back to you on it but the development host going down last week cost me a bit of time.  Getting that DMA transfer working is a big hurdle cleared in the project - thank you again.

    Can I take you up on the mis-count issue in which I've got to tell the DMA controller to send one character less than the actual count?  Any suggestions?

    Mike