summaryrefslogtreecommitdiff
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
parent5b4c295d009d91347fefa5d48646cf77e5a5f43d (diff)
downloadsecure-hid-5009a152801f3b14486cabffe81360603f48b44a.tar.gz
secure-hid-5009a152801f3b14486cabffe81360603f48b44a.tar.bz2
secure-hid-5009a152801f3b14486cabffe81360603f48b44a.zip
DMA-supported LOG_PRINTF works
-rw-r--r--CMakeLists.txt10
-rw-r--r--src/demo.c9
-rw-r--r--src/tinyprintf.c2
-rw-r--r--src/usart_helpers.c156
-rw-r--r--src/usart_helpers.h7
5 files changed, 80 insertions, 104 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7b28316..5abb56c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,8 +17,10 @@ set (USE_STM32F4_FS TRUE CACHE BOOL "Use USB full speed (FS) host periphery")
set (USE_STM32F4_HS TRUE CACHE BOOL "Use USB high speed (HS) host periphery")
set (USE_USART_DEBUG TRUE CACHE BOOL "Enable human-readable serial debug output")
set (DEBUG_USART USART1 CACHE STRING "USART to use for debug output")
-set (DEBUG_USART_DMA DMA2 CACHE STRING "DMA controller to use for debug usart")
+set (DEBUG_USART_BAUDRATE 1000000 CACHE STRING "Baud rate to use for debug USART")
+set (DEBUG_USART_DMA_NUM 2 CACHE STRING "DMA controller number to use for debug usart")
set (DEBUG_USART_DMA_STREAM_NUM 7 CACHE STRING "DMA stream number to use for debug usart. This must be the stream mapped to the [DEBUG_USART]_TX channel")
+set (DEBUG_USART_DMA_CHANNEL_NUM 4 CACHE STRING "DMA channel number to use for debug usart. This must be the channel mapped to the [DEBUG_USART]_TX channel")
# Set compiler and linker flags
@@ -90,6 +92,12 @@ if (USE_USART_DEBUG)
endif (USE_USART_DEBUG)
message (STATUS "Setup done")
+add_definitions (-DDEBUG_USART=${DEBUG_USART})
+add_definitions (-DDEBUG_USART_BAUDRATE=${DEBUG_USART_BAUDRATE})
+add_definitions (-DDEBUG_USART_DMA_NUM=${DEBUG_USART_DMA_NUM})
+add_definitions (-DDEBUG_USART_DMA_STREAM_NUM=${DEBUG_USART_DMA_STREAM_NUM})
+add_definitions (-DDEBUG_USART_DMA_CHANNEL_NUM=${DEBUG_USART_DMA_CHANNEL_NUM})
+
add_custom_target (README.md
SOURCES README.md
)
diff --git a/src/demo.c b/src/demo.c
index d61460f..4458dd6 100644
--- a/src/demo.c
+++ b/src/demo.c
@@ -38,8 +38,6 @@
#include <string.h>
#include <stdlib.h>
-#define UNUSED(var) ((void)var)
-
static inline void delay_ms_busy_loop(uint32_t ms) {
for (volatile uint32_t i = 0; i < 14903*ms; i++);
}
@@ -55,8 +53,8 @@ static void clock_setup(void) {
rcc_periph_clock_enable(RCC_USART1);
rcc_periph_clock_enable(RCC_USART2);
rcc_periph_clock_enable(RCC_OTGFS);
- rcc_periph_clock_enable(RCC_OTGHS);
rcc_periph_clock_enable(RCC_TIM6);
+ rcc_periph_clock_enable(RCC_DMA2);
}
@@ -159,9 +157,14 @@ int main(void)
LOG_PRINTF("USB init complete\n");
+ int i = 0, j = 0;
while (23) {
usbh_poll(tim6_get_time_us());
delay_ms_busy_loop(1); /* approx 1ms interval between usbh_poll() */
+ if (i++ == 200) {
+ i = 0;
+ LOG_PRINTF("Loop iteration %d\n", j++);
+ }
}
return 0;
}
diff --git a/src/tinyprintf.c b/src/tinyprintf.c
index bb22700..0f9ec4e 100644
--- a/src/tinyprintf.c
+++ b/src/tinyprintf.c
@@ -380,7 +380,9 @@ void tfp_format(void *putp, putcf putf, const char *fmt, va_list va)
lng = 2;
# endif
#endif
+ __attribute__((fallthrough));
case 'x':
+ __attribute__((fallthrough));
case 'X':
p.base = 16;
p.uc = (ch == 'X')?1:0;
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);
}
diff --git a/src/usart_helpers.h b/src/usart_helpers.h
index 445a477..18de3b4 100644
--- a/src/usart_helpers.h
+++ b/src/usart_helpers.h
@@ -32,16 +32,17 @@ BEGIN_DECLS
#ifdef USART_DEBUG
void usart_init(uint32_t usart, uint32_t baudrate);
void usart_printf(const char *str, ...);
-void usart_fifo_send(void);
-void usart_interrupt(void);
+void usart_fifo_push(uint8_t c);
-void debug_usart_init() {
+void debug_usart_init(void);
#define LOG_PRINTF(format, ...) usart_printf(format, ##__VA_ARGS__);
#else
#define LOG_PRINTF(dummy, ...) ((void)dummy)
#endif
+#define UNUSED(var) ((void)var)
+
END_DECLS
#endif