/** @file dma_mbuf.h * Module handling Direct Memory Access controller's multibuffer system * * The module provides a convenient tool to send data to a peripheral in a * buffered, low-altency, low-cpu usage, non-blocking way */ #ifndef _DMA_MBUF_H_ #define _DMA_MBUF_H_ //--includes-------------------------------------------------------------------- #include "dma.h" //--type definitions------------------------------------------------------------ /** * Struct used by the multibuffer system. This system allows bufferized writes * to a peripheral with no latency, minimal cpu usage and customisable buffer * sizes */ struct DmaMultiBuffer { void** buffers; //list of buffers to write to volatile void* dest; //destination peripheral register uint16_t buffer_size; //size of a single buffer uint8_t buffer_nb; //total number of buffers uint8_t free_buffer_nb; //number of buffers not currently used uint8_t buffer_index; //index of the current buffer uint8_t dma_buffer_index; //index of the DMA's current buffer enum DmaPeriph dma; //DMA peripheral, must correspond to peripheral enum DmaChannel channel; //DMA channel, must correspond to peripheral enum DmaConfig config; //DMA config, must correspond to peripheral }; //--functions------------------------------------------------------------------- /** * Configure a DMA multibuffer for a single DMA channel. A list of buffers is * used to allow concurent write and DMA tranfers to the specified destination * wich must be a peripheral. The DMA's priority is also given as parameters. * The peripheral's specific configuration must be handled separately. 2 bytes * are reserved in each buffer for index storage. * * This system needs to be started manually: dma_mbuf_refresh() should be called * whenever a DMA transfer can be started. This can be done manually after * filling up the buffer. Transfers will then automatically be started as long * as there are bytes in the buffer. See the usart module for an usage exemple */ void dma_mbuf_configure(volatile struct DmaMultiBuffer* buffer, void** buffers, volatile void* dest, uint16_t buffer_size, uint8_t buffer_nb, enum DmaPeriph dma, enum DmaChannel channel, enum DmaConfig priority); /** * Write the given byte to the given buffer. Returns 0 if the write operation * was successfull, 1 otherwise. The function is non-blocking. * * Note: calling this function will not trigger a DMA transfer, see * dma_mbuf_refresh() to do that */ uint32_t dma_mbuf_write_byte(volatile struct DmaMultiBuffer* buffer, uint8_t byte); /** * Refresh the buffer state, checking for bytes to send and triggering a DMA * transfer if necessary. Should be called for the first transfer, any remaining * transfer will be handled automatically until there are no bytes left in the * buffer */ void dma_mbuf_refresh(volatile struct DmaMultiBuffer* buffer); #endif //_DMA_MBUF_H_