25.7.9.1 Ping Pong Linked List

Consider a scenario where two data buffers are created in system memory. There is a linked-list descriptors associated with each of the data buffer. Each descriptor defines block transfer of the associated buffer to the same communication peripheral. The following figure shows the linked-list structure for such a scenario. The descriptors are linked in circular fashion. The BDCFG.LLEN bit in both descriptors are set to zero. In this configuration, software can update one of the buffers while the DMA is transferring the other buffer to the peripheral.

Figure 25-9. Ping-Pong Linked-List Example

Initially, software programs the address of Descriptor #1 into the CHNXTk.NXT register, assembles the data buffer, and then sets the CHCTRLAk.LLEN bit to 1. The DMA loads the descriptor, configures the channel SFRs to perform the block transfer, and finally sets the CHCTRLAk.ENABLE=1 and CHCTRLAk.LLEN=0 as configured in Descriptor #1. The channel is now read to perform block transfer #1. Note, after the Descriptor #1 loads, the CHNXTk.NXT register contains the address location of Descriptor #2.

While the DMA is processing the block transfer for Descriptor #1, software works on assembling the data for Descriptor #2. On completion of data assembly, software writes the CHCTRLAk.LLEN bit to 1. If the DMA has already completed block transfer #1, it loads Descriptor #2 immediately and prepares for block transfer #2. If block transfer #1 has not completed, the DMA waits until the block transfer completes before loading Descriptor #2. After the Descriptor #2 loads, the CHNXTk.NXT register contains the address location of Descriptor #1. Since LLEN=0 after loading Descriptor #2, the DMA will not load Descriptor #1. Software will write LLEN=1 when data for Descriptor #1 is ready.

This linked-list configuration allows for a “ping-pong” usage of buffers with a simple program model. Software only needs to write to CHCTRLAk.LLEN to notify the DMA there is new data to send and track when a block transfer has completed to know if a buffer is free to update.