From b4cefea4fe265ce3bead428c13f1435227016cee Mon Sep 17 00:00:00 2001 From: "R. Steve McKown" Date: Mon, 29 Dec 2014 16:02:27 -0700 Subject: [PATCH] msp430 usci: fix DMA TX byte overwrite The DMA transmit operation for USCI was a little naive, in that it was not accounting for the possibility that UCxxTXBUF already has a byte to be transmitted. Wait for this byte to be transmitted before starting the DMA operation. Also note in the code that the DMA transfer operations, trigered by UCxxTXIFG, are edge sensitive. --- tos/chips/msp430/usci/Msp430UartDmaP.nc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tos/chips/msp430/usci/Msp430UartDmaP.nc b/tos/chips/msp430/usci/Msp430UartDmaP.nc index 99a5c911..d8a59d97 100644 --- a/tos/chips/msp430/usci/Msp430UartDmaP.nc +++ b/tos/chips/msp430/usci/Msp430UartDmaP.nc @@ -162,15 +162,25 @@ implementation { m_solen = len; } - call Registers.clrIfgTx(); - /* Configure DMA to transfer m_solen bytes from m_sobuf */ call DmaChannel.setupTransfer(DMA_SINGLE_TRANSFER, DMAxTSEL_x, DMA_EDGE_SENSITIVE, m_sobuf, (void *)UCxxTXBUF_, m_solen, DMA_BYTE, DMA_BYTE, DMA_ADDRESS_INCREMENTED, DMA_ADDRESS_UNCHANGED); - call DmaChannel.startTransfer(); - /* Set IFGTX to start DMA transfers */ + /* DMA writes to UCxxTXBUF each time UCxxTXIFG moves from 0 to 1 as its + * trigger is edge sensitive. Therefore, if UCxxTXIFG is already 1, + * indicating the UCxxTXBUF is empty, the trigger is not asserted and the + * DMA transfer will hang having done nothing. The solution is a little + * kludgy: + * + * - Wait for UCxxTXBUF to empty + * - Manually clear UCxxTXIFG + * - Start the DMA transfer (enable the channel trigger) + * - Manually set the UCxxTXIFG + */ + while (!(call Registers.getIfgTx())); + call Registers.clrIfgTx(); + call DmaChannel.startTransfer(); call Registers.setIfgTx(); return SUCCESS; } -- 2.39.2