usart #1
@ -12,9 +12,12 @@
|
|||||||
|
|
||||||
//--local definitions-----------------------------------------------------------
|
//--local definitions-----------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DMA configuration to be used for the buffer. Additionnal configuration may be
|
||||||
|
* added by the peripherals used
|
||||||
|
*/
|
||||||
#define DMA_CONFIG (DMA_CONFIG_IRQ_COMPLETE | DMA_CONFIG_FROM_MEM \
|
#define DMA_CONFIG (DMA_CONFIG_IRQ_COMPLETE | DMA_CONFIG_FROM_MEM \
|
||||||
| DMA_CONFIG_INC_MEM | DMA_CONFIG_PSIZE_8BITS \
|
| DMA_CONFIG_INC_MEM | DMA_CONFIG_MSIZE_8BITS)
|
||||||
| DMA_CONFIG_MSIZE_8BITS)
|
|
||||||
|
|
||||||
static void mbuf_callback(enum DmaIRQSource src, volatile void* param);
|
static void mbuf_callback(enum DmaIRQSource src, volatile void* param);
|
||||||
|
|
||||||
@ -60,12 +63,16 @@ uint32_t dma_mbuf_write_byte(volatile struct DmaMultiBuffer* buffer,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dma_mbuf_switch(volatile struct DmaMultiBuffer* buffer)
|
uint32_t dma_mbuf_switch(volatile struct DmaMultiBuffer* buffer)
|
||||||
{
|
{
|
||||||
//if transfer already in progress or no data to send, don't start the
|
//no data to send, stop here
|
||||||
//transfer
|
if (buffer->byte_index == 0) {
|
||||||
if (buffer->dma_running || buffer->byte_index == 0) {
|
return 0;
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
//dma already running, give up
|
||||||
|
if (buffer->dma_running) {
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//start a new transfer
|
//start a new transfer
|
||||||
@ -80,15 +87,15 @@ void dma_mbuf_switch(volatile struct DmaMultiBuffer* buffer)
|
|||||||
buffer->buffer_index = 0;
|
buffer->buffer_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--local functions-------------------------------------------------------------
|
//--local functions-------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback called on DMA TX tranfert's completion. Checks for any remaining
|
* Callback called on DMA TX tranfert's completion. Stops the DMA and notifies
|
||||||
* data to send. If any, starts a new transfer, else stop the DMA
|
* the buffer that the transfer is done.
|
||||||
*/
|
*/
|
||||||
static void mbuf_callback(enum DmaIRQSource src, volatile void* param)
|
static void mbuf_callback(enum DmaIRQSource src, volatile void* param)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
* Module handling Direct Memory Access controller's multibuffer system
|
* Module handling Direct Memory Access controller's multibuffer system
|
||||||
*
|
*
|
||||||
* The module provides a convenient tool to send data to a peripheral in a
|
* The module provides a convenient tool to send data to a peripheral in a
|
||||||
* buffered, low-altency, low-cpu usage, non-blocking way
|
* buffered, low-latency, low-cpu usage, non-blocking way
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _DMA_MBUF_H_
|
#ifndef _DMA_MBUF_H_
|
||||||
@ -17,36 +17,38 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Struct used by the multibuffer system. This system allows bufferized writes
|
* Struct used by the multibuffer system. This system allows bufferized writes
|
||||||
* to a peripheral with no latency, minimal cpu usage and customisable buffer
|
* to a peripheral with controlled latency, minimal cpu usage and customisable
|
||||||
* sizes
|
* buffer size
|
||||||
*/
|
*/
|
||||||
struct DmaMultiBuffer {
|
struct DmaMultiBuffer {
|
||||||
uint8_t* raw_buffer;
|
uint8_t* raw_buffer; //the buffer to use as a multi-buffer
|
||||||
|
|
||||||
uint16_t buffer_size;
|
uint16_t buffer_size; //the size of the buffer
|
||||||
|
|
||||||
uint8_t byte_index;
|
uint8_t byte_index; //index of the next byte to be written
|
||||||
uint8_t buffer_index;
|
uint8_t buffer_index; //index of the buffer being written to
|
||||||
enum DmaPeriph dma;
|
enum DmaPeriph dma; //DMA peripheral used for transfers
|
||||||
enum DmaChannel channel;
|
enum DmaChannel channel; //DMA channel used for transfers
|
||||||
|
|
||||||
bool dma_running;
|
bool dma_running; //whether the dam is currently running or not
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//--functions-------------------------------------------------------------------
|
//--functions-------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure a DMA multibuffer for a single DMA channel. A list of buffers is
|
* Configure a DMA multibuffer for a single DMA channel. The given buffer is
|
||||||
* used to allow concurent write and DMA tranfers to the specified destination
|
* divided into 2 to allow one part to be written to while the other is being
|
||||||
* wich must be a peripheral. The DMA's priority is also given as parameters.
|
* transfered by the DMA to a peripheral.
|
||||||
* The peripheral's specific configuration must be handled separately. 2 bytes
|
* The peripheral's specific configuration must be handled separately.
|
||||||
* are reserved in each buffer for index storage.
|
* 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.
|
||||||
*
|
*
|
||||||
* This system needs to be started manually: dma_mbuf_refresh() should be called
|
* This buffer can be written to at any given time using dma_mbuf_write_byte(),
|
||||||
* whenever a DMA transfer can be started. This can be done manually after
|
* but its content are only written to the corresponding peripheral when
|
||||||
* filling up the buffer. Transfers will then automatically be started as long
|
* dma_mbuf_switch() is called.
|
||||||
* as there are bytes in the buffer. See the usart module for an usage exemple
|
|
||||||
*/
|
*/
|
||||||
void dma_mbuf_configure(volatile struct DmaMultiBuffer* buffer,
|
void dma_mbuf_configure(volatile struct DmaMultiBuffer* buffer,
|
||||||
const struct DmaParam* param, enum DmaConfig priority,
|
const struct DmaParam* param, enum DmaConfig priority,
|
||||||
@ -57,18 +59,17 @@ void dma_mbuf_configure(volatile struct DmaMultiBuffer* buffer,
|
|||||||
* was successfull, 1 otherwise. The function is non-blocking.
|
* was successfull, 1 otherwise. The function is non-blocking.
|
||||||
*
|
*
|
||||||
* Note: calling this function will not trigger a DMA transfer, see
|
* Note: calling this function will not trigger a DMA transfer, see
|
||||||
* dma_mbuf_refresh() to do that
|
* dma_mbuf_switch() to do that
|
||||||
*/
|
*/
|
||||||
uint32_t dma_mbuf_write_byte(volatile struct DmaMultiBuffer* buffer,
|
uint32_t dma_mbuf_write_byte(volatile struct DmaMultiBuffer* buffer,
|
||||||
uint8_t byte);
|
uint8_t byte);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh the buffer state, checking for bytes to send and triggering a DMA
|
* Switch the buffers, triggering a DMA transfer while allowing writes to
|
||||||
* transfer if necessary. Should be called for the first transfer, any remaining
|
* continue. This function may fail if a DMA transfer is already running,
|
||||||
* transfer will be handled automatically until there are no bytes left in the
|
* returning 1
|
||||||
* buffer
|
|
||||||
*/
|
*/
|
||||||
void dma_mbuf_switch(volatile struct DmaMultiBuffer* buffer);
|
uint32_t dma_mbuf_switch(volatile struct DmaMultiBuffer* buffer);
|
||||||
|
|
||||||
|
|
||||||
#endif //_DMA_MBUF_H_
|
#endif //_DMA_MBUF_H_
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user