diff --git a/drv/dma.h b/drv/dma.h index 309f797..89d9e00 100644 --- a/drv/dma.h +++ b/drv/dma.h @@ -77,6 +77,13 @@ enum DmaIRQSource { typedef void (*DmaCallback)(enum DmaIRQSource, volatile void* param); +struct DmaParam { + void* periph; + enum DmaConfig config; //DMA config, must correspond to peripheral + enum DmaPeriph dma; //DMA peripheral, must correspond to peripheral + enum DmaChannel channel; //DMA channel, must correspond to peripheral +}; + //--functions------------------------------------------------------------------- diff --git a/drv/dma_mbuf.c b/drv/dma_mbuf.c deleted file mode 100644 index 8d10b27..0000000 --- a/drv/dma_mbuf.c +++ /dev/null @@ -1,143 +0,0 @@ -/** @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 - */ - -//--includes-------------------------------------------------------------------- - -#include "dma_mbuf.h" - - -//--local definitions----------------------------------------------------------- - -#define DMA_CONFIG (DMA_CONFIG_IRQ_COMPLETE | DMA_CONFIG_FROM_MEM \ - | DMA_CONFIG_INC_MEM | DMA_CONFIG_PSIZE_8BITS \ - | DMA_CONFIG_MSIZE_8BITS) - -static void mbuf_callback(enum DmaIRQSource src, volatile void* param); - -//take last 2 bytes of a buffer and assemble them store the current byte index -#define byte_index (((uint16_t**)buffer->buffers) \ - [buffer->buffer_index][buffer->buffer_size/2]) -#define dma_byte_index (((uint16_t**)buffer->buffers) \ - [buffer->dma_buffer_index][buffer->buffer_size/2]) - - -//--local variables------------------------------------------------------------- - -//--public functions------------------------------------------------------------ - -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) -{ - #warning "check for null ptr" - - buffer->buffers = buffers; - buffer->dest = dest; - - buffer->buffer_size = buffer_size - 2; - - buffer->buffer_nb = buffer_nb; - buffer->free_buffer_nb = buffer_nb - 1; - buffer->buffer_index = 0; - buffer->dma_buffer_index = 0; - - buffer->dma = dma; - buffer->channel = channel; - buffer->config = DMA_CONFIG | priority; - - for (uint8_t i=0; ibuffer_nb; ++i) { - for (uint16_t j=0; jbuffer_size + 2; ++j) { - ((uint8_t**)buffer->buffers)[i][j] = 0; - } - } -} - -uint32_t dma_mbuf_write_byte(volatile struct DmaMultiBuffer* buffer, - uint8_t byte) -{ - dma_enter_critical(buffer->dma, buffer->channel); - - //if the current buffer is full, we need to switch it with an empty one - volatile uint16_t index = byte_index; - if (byte_index >= buffer->buffer_size) { - - //if all buffer full, give up - if (buffer->free_buffer_nb == 0) { - dma_exit_critical(buffer->dma, buffer->channel); - return 1; - } - - ++buffer->buffer_index; - if (buffer->buffer_index >= buffer->buffer_nb) { - buffer->buffer_index = 0; - } - --buffer->free_buffer_nb; - - byte_index = 0; - } - - //write the byte - uint8_t** buffers = (uint8_t**)buffer->buffers; - buffers[buffer->buffer_index][byte_index] = byte; - ++byte_index; - ++index; - - dma_exit_critical(buffer->dma, buffer->channel); - return 0; -} - -void dma_mbuf_refresh(volatile struct DmaMultiBuffer* buffer) -{ - //no more data to send, stop here - if (buffer->dma_buffer_index == buffer->buffer_index - && byte_index == 0) { - return; - } - - //else start a new transfer - dma_configure(buffer->dma, buffer->channel, buffer->config, buffer->dest, - buffer->buffers[buffer->dma_buffer_index], - dma_byte_index, mbuf_callback, buffer); - - //if the newly transfering buffer was being written to, switch the current - //buffer. Since we just ended a transfer, the next buffer should be empty - if (buffer->dma_buffer_index == buffer->buffer_index) - { - ++buffer->buffer_index; - if (buffer->buffer_index >= buffer->buffer_nb) { - buffer->buffer_index = 0; - } - --buffer->free_buffer_nb; - - byte_index = 0; - } - - return; -} - - -//--local functions------------------------------------------------------------- - -/** - * Callback called on DMA TX tranfert's completion. Checks for any remaining - * data to send. If any, starts a new transfer, else stop the DMA - */ -static void mbuf_callback(enum DmaIRQSource src, volatile void* param) -{ - (void)src; //only transfer complete expected - volatile struct DmaMultiBuffer* buffer = param; - - //increment DMA's buffer since the last once has already been sent - ++buffer->dma_buffer_index; - if (buffer->dma_buffer_index >= buffer->buffer_nb) { - buffer->dma_buffer_index = 0; - } - ++buffer->free_buffer_nb; - - dma_mbuf_refresh(param); -} - diff --git a/drv/usart.c b/drv/usart.c index ae53d66..ae1a928 100644 --- a/drv/usart.c +++ b/drv/usart.c @@ -14,8 +14,6 @@ #include "rcc.h" #include "dma.h" -#include "dma_mbuf.h" -#include "dma_cbuf.h" #include "stddef.h" @@ -27,6 +25,8 @@ static void configure_usart(volatile struct USART* regs, static void configure_baudrate(volatile struct USART* regs, uint32_t clock, uint32_t baudrate); +#define DMA_CONFIG (DMA_CONFIG_PSIZE_8BITS) + //--local variables------------------------------------------------------------- @@ -34,12 +34,47 @@ static volatile struct USART* const usart1 = (struct USART*)USART1_BASE_ADDRESS; static volatile struct USART* const usart2 = (struct USART*)USART2_BASE_ADDRESS; static volatile struct USART* const usart3 = (struct USART*)USART3_BASE_ADDRESS; -static volatile struct DmaCircBuffer usart1_rx_buffer; -static volatile struct DmaMultiBuffer usart1_tx_buffer; -static volatile struct DmaCircBuffer usart2_rx_buffer; -static volatile struct DmaMultiBuffer usart2_tx_buffer; -static volatile struct DmaCircBuffer usart3_rx_buffer; -static volatile struct DmaMultiBuffer usart3_tx_buffer; +static const struct DmaParam usart1_rx_param = { + (void*)&usart1->DR, + DMA_CONFIG, + DMA_PERIPH_1, + DMA_CHANNEL_5, +}; + +static const struct DmaParam usart2_rx_param = { + (void*)&usart2->DR, + DMA_CONFIG, + DMA_PERIPH_1, + DMA_CHANNEL_6, +}; + +static const struct DmaParam usart3_rx_param = { + (void*)&usart3->DR, + DMA_CONFIG, + DMA_PERIPH_1, + DMA_CHANNEL_3, +}; + +static const struct DmaParam usart1_tx_param = { + (void*)&usart1->DR, + DMA_CONFIG, + DMA_PERIPH_1, + DMA_CHANNEL_4, +}; + +static const struct DmaParam usart2_tx_param = { + (void*)&usart2->DR, + DMA_CONFIG, + DMA_PERIPH_1, + DMA_CHANNEL_7, +}; + +static const struct DmaParam usart3_tx_param = { + (void*)&usart3->DR, + DMA_CONFIG, + DMA_PERIPH_1, + DMA_CHANNEL_2, +}; //--public functions------------------------------------------------------------ @@ -55,22 +90,16 @@ void usart_configure(enum UsartPeriph periph, enum UsartConfig config, rcc_enable(RCC_AHB_NONE, RCC_APB1_NONE, RCC_APB2_USART); configure_baudrate(usart1, clocks.apb2_freq, baudrate); configure_usart(usart1, config); - usart1_tx_buffer.buffers = NULL; - usart1_rx_buffer.buffer = NULL; break; case USART_PERIPH_2: rcc_enable(RCC_AHB_NONE, RCC_APB1_USART2, RCC_APB2_NONE); configure_baudrate(usart2, clocks.apb1_freq, baudrate); configure_usart(usart2, config); - usart2_tx_buffer.buffers = NULL; - usart2_rx_buffer.buffer = NULL; break; case USART_PERIPH_3: rcc_enable(RCC_AHB_NONE, RCC_APB1_USART3, RCC_APB2_NONE); configure_baudrate(usart3, clocks.apb1_freq, baudrate); configure_usart(usart3, config); - usart3_tx_buffer.buffers = NULL; - usart3_rx_buffer.buffer = NULL; break; default: break; @@ -80,134 +109,104 @@ void usart_configure(enum UsartPeriph periph, enum UsartConfig config, uint32_t usart_write_byte(enum UsartPeriph periph, uint8_t byte) { volatile struct USART* regs; - volatile struct DmaMultiBuffer* buffer; - enum NvicIrq irq; switch (periph) { case USART_PERIPH_1: regs = usart1; - buffer = &usart1_tx_buffer; - irq = NVIC_IRQ_USART1; break; case USART_PERIPH_2: regs = usart2; - buffer = &usart2_tx_buffer; - irq = NVIC_IRQ_USART2; break; case USART_PERIPH_3: regs = usart3; - buffer = &usart3_tx_buffer; - irq = NVIC_IRQ_USART3; break; default: return 1; break; } - if (buffer->buffers) { - //if the tx register is empty, there is no need to go through the dma - if (regs->SR.TC) { - reg_write(regs->DR, USART_DR_DR, byte); - //enable IRQ, disable DMA - reg_reset(regs->CR3, USART_CR3_DMAT); - reg_set(regs->CR1, USART_CR1_TXEIE); - nvic_enable(irq); - return 0; - } else { - return dma_mbuf_write_byte(buffer, byte); - } + //only write data if the tx register it empty, give up otherwise + if (regs->SR.TXE) { + reg_write(regs->DR, USART_DR_DR, byte); + return 0; } else { - //only write data if the tx register it empty, give up otherwise - if (regs->SR.TXE) { - reg_write(regs->DR, USART_DR_DR, byte); - return 0; - } else { - return 1; - } + return 1; } } uint32_t usart_read_byte(enum UsartPeriph periph, uint8_t* byte) { volatile struct USART* regs; - volatile struct DmaCircBuffer* buffer; switch (periph) { case USART_PERIPH_1: regs = usart1; - buffer = &usart1_rx_buffer; break; case USART_PERIPH_2: regs = usart2; - buffer = &usart2_rx_buffer; break; case USART_PERIPH_3: regs = usart3; - buffer = &usart3_rx_buffer; break; default: return 1; break; } - if (buffer->buffer) { - return dma_cbuf_read_byte(buffer, byte); + if (regs->SR.RXNE) { + *byte = regs->DR.DR; + return 0; } else { - if (regs->SR.RXNE) { - *byte = regs->DR.DR; - return 0; - } else { - return 1; - } + return 1; } } -void usart_set_tx_buffer(enum UsartPeriph periph, uint8_t** buffers, - uint16_t buffer_size, uint8_t buffer_nb, enum DmaConfig priority) +const struct DmaParam* usart_configure_rx_dma(enum UsartPeriph periph) { - switch (periph) { - case USART_PERIPH_1: - dma_mbuf_configure(&usart1_tx_buffer, (void**)buffers, &usart1->DR, - buffer_size, buffer_nb, DMA_PERIPH_1, DMA_CHANNEL_4, - priority); - break; - case USART_PERIPH_2: - dma_mbuf_configure(&usart2_tx_buffer, (void**)buffers, &usart2->DR, - buffer_size, buffer_nb, DMA_PERIPH_1, DMA_CHANNEL_7, - priority); - break; - case USART_PERIPH_3: - dma_mbuf_configure(&usart3_tx_buffer, (void**)buffers, &usart3->DR, - buffer_size, buffer_nb, DMA_PERIPH_1, DMA_CHANNEL_2, - priority); - break; - } -} + const struct DmaParam* param; -void usart_set_rx_buffer(enum UsartPeriph periph, uint8_t* buffer, - uint16_t size, enum DmaConfig priority) -{ switch (periph) { case USART_PERIPH_1: - dma_cbuf_configure(&usart1_rx_buffer, buffer, (void*)&usart1->DR, - size, DMA_PERIPH_1, DMA_CHANNEL_5, priority); + param = &usart1_rx_param; reg_set(usart1->CR3, USART_CR3_DMAR); break; case USART_PERIPH_2: - dma_cbuf_configure(&usart2_rx_buffer, buffer, (void*)&usart2->DR, - size, DMA_PERIPH_1, DMA_CHANNEL_6, priority); + param = &usart2_rx_param; reg_set(usart2->CR3, USART_CR3_DMAR); break; - case USART_PERIPH_3: - dma_cbuf_configure(&usart3_rx_buffer, buffer, (void*)&usart3->DR, - size, DMA_PERIPH_1, DMA_CHANNEL_3, priority); + param = &usart3_rx_param; reg_set(usart3->CR3, USART_CR3_DMAR); - break; + default: + return nullptr; } + + return param; } +const struct DmaParam* usart_configure_tx_dma(enum UsartPeriph periph) +{ + const struct DmaParam* param; + + switch (periph) { + case USART_PERIPH_1: + param = &usart1_tx_param; + break; + case USART_PERIPH_2: + param = &usart2_tx_param; + break; + case USART_PERIPH_3: + param = &usart3_tx_param; + break; + default: + return nullptr; + } + + return param; +} + + //--local functions------------------------------------------------------------- /** @@ -309,39 +308,3 @@ static void configure_baudrate(volatile struct USART* regs, uint32_t clock, reg_write(regs->BRR, USART_BRR_DIV_Fraction, divider & 0xF); } - -//--ISRs------------------------------------------------------------------------ - -void hdr_usart1(void) -{ - //disable the interrupt. It will be reenabled on a write if needed - nvic_clear_pending(NVIC_IRQ_USART1); - nvic_disable(NVIC_IRQ_USART1); - reg_reset(usart1->CR1, USART_CR1_TXEIE); - reg_set(usart1->CR3, USART_CR3_DMAT); - - dma_mbuf_refresh(&usart1_tx_buffer); -} - -void hdr_usart2(void) -{ - //disable the interrupt. It will be reenabled on a write if needed - nvic_clear_pending(NVIC_IRQ_USART2); - nvic_disable(NVIC_IRQ_USART2); - reg_reset(usart2->CR1, USART_CR1_TXEIE); - reg_set(usart2->CR3, USART_CR3_DMAT); - - dma_mbuf_refresh(&usart2_tx_buffer); -} - -void hdr_usart3(void) -{ - //disable the interrupt. It will be reenabled on a write if needed - nvic_clear_pending(NVIC_IRQ_USART3); - nvic_disable(NVIC_IRQ_USART3); - reg_reset(usart3->CR1, USART_CR1_TXEIE); - reg_set(usart3->CR3, USART_CR3_DMAT); - - dma_mbuf_refresh(&usart3_tx_buffer); -} - diff --git a/drv/usart.h b/drv/usart.h index 8739e63..9189d01 100644 --- a/drv/usart.h +++ b/drv/usart.h @@ -41,18 +41,13 @@ enum UsartConfig { void usart_configure(enum UsartPeriph periph, enum UsartConfig config, uint32_t baudrate); - void usart_reset(enum UsartPeriph periph); uint32_t usart_write_byte(enum UsartPeriph periph, uint8_t byte); - uint32_t usart_read_byte(enum UsartPeriph periph, uint8_t* byte); -void usart_set_tx_buffer(enum UsartPeriph periph, uint8_t** buffers, - uint16_t buffer_size, uint8_t buffer_nb, enum DmaConfig priority); - -void usart_set_rx_buffer(enum UsartPeriph periph, uint8_t* buffer, - uint16_t size, enum DmaConfig priority); +const struct DmaParam* usart_configure_rx_dma(enum UsartPeriph periph); +const struct DmaParam* usart_configure_tx_dma(enum UsartPeriph periph); #endif //_USART_H_ diff --git a/drv/dma_cbuf.c b/srv/dma_cbuf.c similarity index 85% rename from drv/dma_cbuf.c rename to srv/dma_cbuf.c index f324d20..e66b0e1 100644 --- a/drv/dma_cbuf.c +++ b/srv/dma_cbuf.c @@ -24,24 +24,23 @@ static void cbuf_callback(enum DmaIRQSource src, volatile void* param); //--public functions------------------------------------------------------------ void dma_cbuf_configure(volatile struct DmaCircBuffer* buffer, - volatile void* raw_buffer, volatile void* src, uint16_t buffer_size, - enum DmaPeriph dma, enum DmaChannel channel, enum DmaConfig priority) + const struct DmaParam* param, enum DmaConfig priority, + volatile void* raw_buffer, uint16_t buffer_size) { #warning "check for null ptr" buffer->buffer = raw_buffer; - buffer->src = src; + + buffer->param = param; + buffer->priority = priority; buffer->size = buffer_size; buffer->begin = 0; - buffer->dma = dma; - buffer->channel = channel; - buffer->config = DMA_CONFIG | priority; - buffer->dma_looped = false; - dma_configure(buffer->dma, buffer->channel, buffer->config, buffer->src, + dma_configure(buffer->param->dma, buffer->param->channel, + buffer->param->config, buffer->param->periph, buffer->buffer, buffer->size, cbuf_callback, buffer); } @@ -50,7 +49,7 @@ uint32_t dma_cbuf_read_byte(volatile struct DmaCircBuffer* buffer, { //retreive the current end of the buffer based on the DMA's progress uint16_t end = buffer->size - - dma_get_remaining(buffer->dma, buffer->channel); + - dma_get_remaining(buffer->param->dma, buffer->param->channel); //check for bytes to read and overflow if ((end > buffer->begin) && buffer->dma_looped) { diff --git a/drv/dma_cbuf.h b/srv/dma_cbuf.h similarity index 78% rename from drv/dma_cbuf.h rename to srv/dma_cbuf.h index 4221f14..606829e 100644 --- a/drv/dma_cbuf.h +++ b/srv/dma_cbuf.h @@ -10,7 +10,7 @@ //--includes-------------------------------------------------------------------- -#include "dma.h" +#include "../drv/dma.h" //--type definitions------------------------------------------------------------ @@ -22,15 +22,13 @@ */ struct DmaCircBuffer { volatile void* buffer; //the buffer to use as a circular buffer - volatile void* src; //source peripheral register + + const struct DmaParam* param; + enum DmaConfig priority; //DMA config, must correspond to peripheral uint16_t size; //the size of the buffer uint16_t begin; //pointer to the current begin of the 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 - bool dma_looped; //whether the DMA looped or not (buffer overflow) }; @@ -47,8 +45,8 @@ struct DmaCircBuffer { * will stay running until manually stopped */ void dma_cbuf_configure(volatile struct DmaCircBuffer* buffer, - volatile void* raw_buffer, volatile void* src, uint16_t buffer_size, - enum DmaPeriph dma, enum DmaChannel channel, enum DmaConfig priority); + const struct DmaParam* param, enum DmaConfig priority, + volatile void* raw_buffer, uint16_t buffer_size); uint32_t dma_cbuf_read_byte(volatile struct DmaCircBuffer* buffer, uint8_t* byte); diff --git a/srv/dma_mbuf.c b/srv/dma_mbuf.c new file mode 100644 index 0000000..dc6a876 --- /dev/null +++ b/srv/dma_mbuf.c @@ -0,0 +1,99 @@ +/** @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 + */ + +//--includes-------------------------------------------------------------------- + +#include "dma_mbuf.h" + + +//--local definitions----------------------------------------------------------- + +#define DMA_CONFIG (DMA_CONFIG_IRQ_COMPLETE | DMA_CONFIG_FROM_MEM \ + | DMA_CONFIG_INC_MEM | DMA_CONFIG_PSIZE_8BITS \ + | DMA_CONFIG_MSIZE_8BITS) + +static void mbuf_callback(enum DmaIRQSource src, volatile void* param); + + +//--local variables------------------------------------------------------------- + +//--public functions------------------------------------------------------------ + +void dma_mbuf_configure(volatile struct DmaMultiBuffer* buffer, + const struct DmaParam* param, enum DmaConfig priority, + void* raw_buffer, uint16_t buffer_size) +{ + #warning "check for null ptr" + + buffer->raw_buffer = raw_buffer; + + buffer->param = param; + buffer->priority = priority; + + buffer->buffer_size = buffer_size / 2; + + buffer->byte_index = 0; + buffer->buffer_index = 0; + + buffer->dma_running = false; +} + +uint32_t dma_mbuf_write_byte(volatile struct DmaMultiBuffer* buffer, + uint8_t byte) +{ + //if the current buffer is full, give up + if (buffer->byte_index >= buffer->buffer_size) { + return 1; + } + + //write the byte + buffer->raw_buffer[buffer->buffer_index * buffer->buffer_size + + buffer->byte_index] = byte; + ++buffer->byte_index; + return 0; +} + +void dma_mbuf_switch(volatile struct DmaMultiBuffer* buffer) +{ + //if transfer already in progress or no data to send, don't start the + //transfer + if (buffer->dma_running || buffer->byte_index == 0) { + return; + } + + //start a new transfer + dma_configure(buffer->param->dma, buffer->param->channel, + DMA_CONFIG | buffer->param->config | buffer->priority, + buffer->param->periph, + &buffer->raw_buffer[buffer->buffer_index * buffer->buffer_size], + buffer->byte_index, mbuf_callback, buffer); + buffer->dma_running = true; + + buffer->byte_index = 0; + ++buffer->buffer_index; + if (buffer->buffer_index > 1) { + buffer->buffer_index = 0; + } + + return; +} + + +//--local functions------------------------------------------------------------- + +/** + * Callback called on DMA TX tranfert's completion. Checks for any remaining + * data to send. If any, starts a new transfer, else stop the DMA + */ +static void mbuf_callback(enum DmaIRQSource src, volatile void* param) +{ + (void)src; //only transfer complete expected + volatile struct DmaMultiBuffer* buffer = param; + + buffer->dma_running = false; +} + diff --git a/drv/dma_mbuf.h b/srv/dma_mbuf.h similarity index 68% rename from drv/dma_mbuf.h rename to srv/dma_mbuf.h index 4ab6952..966c5c1 100644 --- a/drv/dma_mbuf.h +++ b/srv/dma_mbuf.h @@ -10,7 +10,7 @@ //--includes-------------------------------------------------------------------- -#include "dma.h" +#include "../drv/dma.h" //--type definitions------------------------------------------------------------ @@ -21,19 +21,17 @@ * sizes */ struct DmaMultiBuffer { - void** buffers; //list of buffers to write to - volatile void* dest; //destination peripheral register + uint8_t* raw_buffer; - uint16_t buffer_size; //size of a single buffer + const struct DmaParam* param; + enum DmaConfig priority; - 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 + uint16_t buffer_size; - 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 + uint8_t byte_index; + uint8_t buffer_index; + + bool dma_running; }; @@ -51,9 +49,9 @@ struct DmaMultiBuffer { * 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); +void dma_mbuf_configure(volatile struct DmaMultiBuffer* buffer, + const struct DmaParam* param, enum DmaConfig priority, + void* raw_buffer, uint16_t buffer_size); /** * Write the given byte to the given buffer. Returns 0 if the write operation @@ -71,7 +69,7 @@ uint32_t dma_mbuf_write_byte(volatile struct DmaMultiBuffer* buffer, * transfer will be handled automatically until there are no bytes left in the * buffer */ -void dma_mbuf_refresh(volatile struct DmaMultiBuffer* buffer); +void dma_mbuf_switch(volatile struct DmaMultiBuffer* buffer); #endif //_DMA_MBUF_H_