From 5009a152801f3b14486cabffe81360603f48b44a Mon Sep 17 00:00:00 2001 From: jaseg Date: Tue, 6 Nov 2018 09:15:37 +0900 Subject: DMA-supported LOG_PRINTF works --- src/usart_helpers.c | 156 ++++++++++++++++++++-------------------------------- 1 file changed, 59 insertions(+), 97 deletions(-) (limited to 'src/usart_helpers.c') diff --git a/src/usart_helpers.c b/src/usart_helpers.c index 97aa0f0..6ba9cea 100644 --- a/src/usart_helpers.c +++ b/src/usart_helpers.c @@ -31,86 +31,12 @@ #include #include #include +#include +#include +#include -uint32_t debug_usart = 0; - -#define USART_FIFO_OUT_SIZE (4096) -uint8_t usart_fifo_out_data[USART_FIFO_OUT_SIZE]; -uint32_t usart_fifo_out_len = 0; -uint32_t usart_fifo_out_index = 0; - -#define USART_FIFO_IN_SIZE (1024) -uint8_t usart_fifo_in_data[USART_FIFO_IN_SIZE]; -uint32_t usart_fifo_in_len = 0; -uint32_t usart_fifo_in_index = 0; - -static uint32_t usart = 0; - -static uint8_t usart_fifo_pop(void) -{ - uint8_t ret; - usart_fifo_out_len--; - ret = usart_fifo_out_data[usart_fifo_out_index]; - usart_fifo_out_index++; - if (usart_fifo_out_index == USART_FIFO_OUT_SIZE ) { - usart_fifo_out_index = 0; - } - return ret; -} - -static void usart_fifo_push(uint8_t aData) -{ - uint32_t i; - if( (usart_fifo_out_len + 1) == USART_FIFO_OUT_SIZE)//overflow - { - usart_fifo_out_len = 0; - LOG_PRINTF("OVERFLOW!"); - return; - } - - i = usart_fifo_out_index + usart_fifo_out_len; - if (i >= USART_FIFO_OUT_SIZE) { - i -= USART_FIFO_OUT_SIZE; - } - usart_fifo_out_data[i] = aData; - usart_fifo_out_len++; -} - - -static uint8_t usart_fifo_in_pop(void) -{ - uint8_t ret; - usart_fifo_in_len--; - ret = usart_fifo_in_data[usart_fifo_in_index]; - usart_fifo_in_index++; - if (usart_fifo_in_index == USART_FIFO_IN_SIZE ) { - usart_fifo_in_index = 0; - } - return ret; -} - -static void usart_fifo_in_push(uint8_t aData) -{ - uint32_t i; - if( (usart_fifo_in_len + 1) == USART_FIFO_IN_SIZE)//overflow - { - usart_fifo_in_len = 0; - return; - } - - i = usart_fifo_in_index + usart_fifo_in_len; - if (i >= USART_FIFO_IN_SIZE) { - i -= USART_FIFO_IN_SIZE; - } - usart_fifo_in_data[i] = aData; - usart_fifo_in_len++; -} - -static void putf(void *arg, char c) -{ - //unused argument - (void)arg; - +static void putf(void *file, char c) { + UNUSED(file); usart_fifo_push(c); } @@ -135,41 +61,77 @@ void usart_init(uint32_t arg_usart, uint32_t baudrate) #define WRITE_BUF_LEN 256 struct tx_buf { - buf[WRITE_BUF_LEN]; - int pos; + uint8_t buf[WRITE_BUF_LEN]; + uint32_t pos; } tx_buf[2]; int tx_buf_active; -#define DEBUG_USART_DMA_STREAM (DMA_STREAM##DEBUG_USART_DMA_STREAM_NUM) -#define DEBUG_USART_NVIC_DMA_IRQ (NVIC_##DEBUG_USART_DMA##_##DEBUG_USART_DMA_STREAM##_IRQ) -#define DEBUG_USART_DMA_ISR (DEBUG_USART_DMA##_##DEBUG_USART_DMA_STREAM##_IRQHandler) +/* This macro abomination templates a bunch of dma-specific register/constant names from preprocessor macros passed in + * from cmake. */ +#define DEBUG_USART_DMA_PASTE(num) DMA ## num +#define DEBUG_USART_DMA_EVAL(num) DEBUG_USART_DMA_PASTE(num) +#define DEBUG_USART_DMA DEBUG_USART_DMA_EVAL(DEBUG_USART_DMA_NUM) + +#define DEBUG_USART_DMA_STREAM_PASTE(num) DMA_STREAM ## num +#define DEBUG_USART_DMA_STREAM_EVAL(num) DEBUG_USART_DMA_STREAM_PASTE(num) +#define DEBUG_USART_DMA_STREAM DEBUG_USART_DMA_STREAM_EVAL(DEBUG_USART_DMA_STREAM_NUM) + +#define DEBUG_USART_NVIC_DMA_IRQ_PASTE(dma, stream) NVIC_ ## DMA ## dma ## _ ## STREAM ## stream ## _IRQ +#define DEBUG_USART_NVIC_DMA_IRQ_EVAL(dma, stream) DEBUG_USART_NVIC_DMA_IRQ_PASTE(dma, stream) +#define DEBUG_USART_NVIC_DMA_IRQ DEBUG_USART_NVIC_DMA_IRQ_EVAL(DEBUG_USART_DMA_NUM, DEBUG_USART_DMA_STREAM_NUM) + +#define DEBUG_USART_DMA_ISR_PASTE(dma, stream) DMA ## dma ## _ ## STREAM ## stream ## _IRQHandler +#define DEBUG_USART_DMA_ISR_EVAL(dma, stream) DEBUG_USART_DMA_ISR_PASTE(dma, stream) +#define DEBUG_USART_DMA_ISR DEBUG_USART_DMA_ISR_EVAL(DEBUG_USART_DMA_NUM, DEBUG_USART_DMA_STREAM_NUM) + +#define DEBUG_USART_DMA_CHANNEL_PASTE(channel) DMA_SxCR_CHSEL_ ## channel +#define DEBUG_USART_DMA_CHANNEL_EVAL(channel) DEBUG_USART_DMA_CHANNEL_PASTE(channel) +#define DEBUG_USART_DMA_CHANNEL DEBUG_USART_DMA_CHANNEL_EVAL(DEBUG_USART_DMA_CHANNEL_NUM) + void debug_usart_init() { tx_buf[0].pos = tx_buf[1].pos = 0; tx_buf_active = 1; - usart_init(DEBUG_USART, DEBUG_BAUDRATE); + usart_init(DEBUG_USART, DEBUG_USART_BAUDRATE); dma_stream_reset(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM); - dma_set_peripheral_address(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, (uint32_t)&DEBUG_USART##_DR); - dma_set_memory_address(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, (uint32_t)tx_buf[1].buf); - dma_set_number_of_data(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, size); - dma_set_read_from_memory(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM); + dma_channel_select(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, DEBUG_USART_DMA_CHANNEL); + dma_set_peripheral_address(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, (uint32_t)&USART_DR(DEBUG_USART)); + dma_set_transfer_mode(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, DMA_SxCR_DIR_MEM_TO_PERIPHERAL); dma_enable_memory_increment_mode(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM); - dma_set_peripheral_size(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, DMA_CCR_PSIZE_8BIT); - dma_set_memory_size(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, DMA_CCR_MSIZE_8BIT); - dma_set_priority(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, DMA_CCR_PL_VERY_HIGH); + dma_set_peripheral_size(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, DMA_SxCR_PSIZE_8BIT); + dma_set_memory_size(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, DMA_SxCR_MSIZE_8BIT); + dma_set_priority(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, DMA_SxCR_PL_VERY_HIGH); dma_enable_transfer_complete_interrupt(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM); - dma_enable_channel(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM); usart_enable_tx_dma(DEBUG_USART); - nvic_enable_irq(DEBUG_USART_NVIC_DMA_IRQ); } -void DEBUG_USART_DMA_ISR +static void usart_kickoff_dma(void) { + tx_buf[tx_buf_active].pos = 0; /* clear old buffer */ + tx_buf_active = !tx_buf_active; /* swap buffers */ + /* initiate transmission of new buffer */ + dma_set_memory_address(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, (uint32_t)&tx_buf[tx_buf_active].buf); /* select active buffer address */ + dma_set_number_of_data(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, tx_buf[tx_buf_active].pos); + dma_enable_stream(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM); +} + +void DEBUG_USART_DMA_ISR(void) { + dma_clear_interrupt_flags(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, DMA_TCIF); + + struct tx_buf *buf = &tx_buf[!tx_buf_active]; /* select inactive buffer */ + if (buf->pos != 0) { + usart_kickoff_dma(); + } +} void usart_fifo_push(uint8_t c) { + nvic_disable_irq(DEBUG_USART_NVIC_DMA_IRQ); struct tx_buf *buf = &tx_buf[!tx_buf_active]; /* select inactive buffer */ buf->buf[buf->pos++] = c; - nvic_disable_irq(DEBUG_USART_NVIC_DMA_IRQ); - if + if (!(DMA_SCR(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM) & DMA_SxCR_EN) /* DMA is not running */ + && !dma_get_interrupt_flag(DEBUG_USART_DMA, DEBUG_USART_DMA_STREAM, DMA_TCIF)/* DMA interrupt is clear */) { + usart_kickoff_dma(); + } + nvic_enable_irq(DEBUG_USART_NVIC_DMA_IRQ); } -- cgit