As with the UART code, this busy waiting can be replaced by blocking the thread initiating the DMA operation on a synchronization object (in this case a binary semaphore is appropriate) and utilizing an interrupt handler to unblock the thread (as illustrated below).