summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
4 files changed, 71 insertions, 103 deletions
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