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;
}