/** @file dma_cbuf.h
 * Module handling Direct Memory Access controller's circular system
 *
 * The module provides a convenient tool to receive data from a peripheral in a
 * buffered, low-latency, low-cpu usage, non-blocking way
 */

#ifndef _DMA_CBUF_H_
#define _DMA_CBUF_H_

//--includes--------------------------------------------------------------------

#include "../drv/dma.h"


//--type definitions------------------------------------------------------------

/**
 * Struct used by the circular buffer system. This system allows bufferized
 * reads to a peripheral with no latency, minimal cpu usage and customisable
 * buffer sizes
 */
struct DmaCircBuffer {
	volatile void* buffer;    //the buffer to use as a circular buffer

	uint16_t size;            //the size of the buffer
	uint16_t begin;           //pointer to the current begin of the buffer

	enum DmaPeriph dma;      //DMA peripheral used for transfers
	enum DmaChannel channel; //DMA channel used for transfers

	bool dma_looped;          //whether the DMA looped or not (buffer overflow)
};


//--functions-------------------------------------------------------------------

/**
 * Configure a DMA circular buffer for a single DMA channel. A standard buffer
 * is used a base to construct a circular buffer, supplied in data by DMA
 * tranfers from a peripheral.
 * The peripheral's specific configuration must be handled separately.
 * Each peripheral's driver is responsible for providing the DMA configuration
 * for said peripheral, though it can be manually given too. Please note that
 * multiple peripherals may share the same DMA channel, which will cause issue
 * when used with this buffer.
 *
 * Once this function is called, the system will start running right away and
 * will stay running until manually stopped
 */
void dma_cbuf_configure(volatile struct DmaCircBuffer* buffer,
		const struct DmaParam* param, enum DmaConfig priority,
		volatile void* raw_buffer, uint16_t buffer_size);

/**
 * Reads a bytes from the buffer, returning if the read operation was
 * successfull, 1 otherwise. This function is non-blocking.
 */
uint32_t dma_cbuf_read_byte(volatile struct DmaCircBuffer* buffer,
		uint8_t* byte);


#endif //_DMA_CBUF_H_

