summaryrefslogtreecommitdiff
path: root/src/usart_helpers.c
diff options
context:
space:
mode:
authorjaseg <git@jaseg.net>2018-11-06 09:15:37 +0900
committerjaseg <git@jaseg.net>2018-11-06 09:15:37 +0900
commit5009a152801f3b14486cabffe81360603f48b44a (patch)
tree96cce28fbd27324fcd8cfcf54a62477955ff690b /src/usart_helpers.c
parent5b4c295d009d91347fefa5d48646cf77e5a5f43d (diff)
downloadsecure-hid-5009a152801f3b14486cabffe81360603f48b44a.tar.gz
secure-hid-5009a152801f3b14486cabffe81360603f48b44a.tar.bz2
secure-hid-5009a152801f3b14486cabffe81360603f48b44a.zip
DMA-supported LOG_PRINTF works
Diffstat (limited to 'src/usart_helpers.c')
-rw-r--r--src/usart_helpers.c156
1 files changed, 59 insertions, 97 deletions
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 <stdlib.h>
#include <stdio.h>
#include <libopencm3/stm32/usart.h>
+#include <libopencm3/stm32/dma.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencmsis/core_cm3.h>
-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);
}