|
|
|
@ -2,6 +2,8 @@ |
|
|
|
|
#include <libopencm3/stm32/rcc.h> |
|
|
|
|
#include <libopencm3/stm32/gpio.h> |
|
|
|
|
#include <libopencm3/stm32/usart.h> |
|
|
|
|
#include <libopencm3/cm3/nvic.h> |
|
|
|
|
#include <libopencm3/cm3/scb.h> |
|
|
|
|
|
|
|
|
|
#include <ctype.h> |
|
|
|
|
#include <stdio.h> |
|
|
|
@ -14,36 +16,115 @@ |
|
|
|
|
|
|
|
|
|
#include <console.h> |
|
|
|
|
|
|
|
|
|
static ssize_t usart_read(void *cookie, char *buf, size_t n) |
|
|
|
|
#define RECV_BUF_LEN 128 |
|
|
|
|
|
|
|
|
|
struct usart_console { |
|
|
|
|
char recv_buf[RECV_BUF_LEN]; |
|
|
|
|
volatile size_t cur, next; |
|
|
|
|
uint32_t dev; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct usart_console *usart1 = NULL; |
|
|
|
|
struct usart_console user_console; |
|
|
|
|
|
|
|
|
|
static void usart_isr(struct usart_console *console) |
|
|
|
|
{ |
|
|
|
|
uint32_t dev = (uint32_t)cookie; |
|
|
|
|
uint32_t reg; |
|
|
|
|
size_t i; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < n; ++i) { |
|
|
|
|
buf[i] = (char)usart_recv_blocking(dev); |
|
|
|
|
if (!console) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
do { |
|
|
|
|
reg = USART_ISR(console->dev); |
|
|
|
|
|
|
|
|
|
if (!(reg & USART_ISR_RXNE)) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
console->recv_buf[console->next] = usart_recv(console->dev); |
|
|
|
|
|
|
|
|
|
if (console->recv_buf[console->next] == '\003') |
|
|
|
|
scb_reset_system(); |
|
|
|
|
|
|
|
|
|
i = (console->next + 1) % RECV_BUF_LEN; |
|
|
|
|
|
|
|
|
|
if (i != console->cur) |
|
|
|
|
console->next = i; |
|
|
|
|
} while (usart_get_flag(console->dev, USART_ISR_RXNE)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void usart1_isr(void) |
|
|
|
|
{ |
|
|
|
|
usart_isr(usart1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static char usart_getc(struct usart_console *console, int block) |
|
|
|
|
{ |
|
|
|
|
char c = 0; |
|
|
|
|
|
|
|
|
|
while (block && (console->cur == console->next)); |
|
|
|
|
|
|
|
|
|
if (console->cur != console->next) { |
|
|
|
|
c = console->recv_buf[console->cur]; |
|
|
|
|
console->cur = (console->cur + 1) % RECV_BUF_LEN; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return c; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static ssize_t usart_read(void *cookie, char *buf, size_t n) |
|
|
|
|
{ |
|
|
|
|
struct usart_console *console = cookie; |
|
|
|
|
char *p = buf; |
|
|
|
|
char c; |
|
|
|
|
|
|
|
|
|
*buf = '\0'; |
|
|
|
|
|
|
|
|
|
while ((c = usart_getc(console, 1)) != '\r') { |
|
|
|
|
switch (c) { |
|
|
|
|
case 10: |
|
|
|
|
case 127: |
|
|
|
|
if (buf < p) { |
|
|
|
|
usart_send_blocking(console->dev, '\010'); |
|
|
|
|
usart_send_blocking(console->dev, ' '); |
|
|
|
|
usart_send_blocking(console->dev, '\010'); |
|
|
|
|
--p; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (buf[i] == '\r') { |
|
|
|
|
buf[i++] = '\n'; |
|
|
|
|
putchar('\n'); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
*p = c; |
|
|
|
|
usart_send_blocking(console->dev, c); |
|
|
|
|
|
|
|
|
|
if (((size_t)p - (size_t)buf) < n) { |
|
|
|
|
++p; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
putchar(buf[i]); |
|
|
|
|
*p = '\0'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return i; |
|
|
|
|
*p = '\n'; |
|
|
|
|
|
|
|
|
|
if (((size_t)p - (size_t)buf) < n) { |
|
|
|
|
++p; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
*p = '\0'; |
|
|
|
|
|
|
|
|
|
return p - buf; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static ssize_t usart_write(void *cookie, const char *buf, size_t n) |
|
|
|
|
{ |
|
|
|
|
uint32_t dev = (uint32_t)cookie; |
|
|
|
|
struct usart_console *console = cookie; |
|
|
|
|
size_t i; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < n; ++i) { |
|
|
|
|
if (buf[i] == '\n') |
|
|
|
|
usart_send_blocking(dev, '\r'); |
|
|
|
|
usart_send_blocking(console->dev, '\r'); |
|
|
|
|
|
|
|
|
|
usart_send_blocking(dev, buf[i]); |
|
|
|
|
usart_send_blocking(console->dev, buf[i]); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
return i; |
|
|
|
@ -67,7 +148,10 @@ static void usart_init(void) |
|
|
|
|
usart_set_mode(USART1, USART_MODE_TX_RX); |
|
|
|
|
usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE); |
|
|
|
|
|
|
|
|
|
nvic_enable_irq(NVIC_USART1_IRQ); |
|
|
|
|
|
|
|
|
|
usart_enable(USART1); |
|
|
|
|
usart_enable_rx_interrupt(USART1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void console_init(void) |
|
|
|
@ -85,11 +169,15 @@ void console_init(void) |
|
|
|
|
.close = NULL, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
user_console.dev = USART1; |
|
|
|
|
user_console.cur = 0; |
|
|
|
|
user_console.next = 0; |
|
|
|
|
usart1 = &user_console; |
|
|
|
|
usart_init(); |
|
|
|
|
|
|
|
|
|
stdin = fopencookie((void *)USART1, "r", console_in); |
|
|
|
|
stdout = fopencookie((void *)USART1, "w", console_out); |
|
|
|
|
stderr = fopencookie((void *)USART1, "w", console_out); |
|
|
|
|
stdin = fopencookie(&user_console, "r", console_in); |
|
|
|
|
stdout = fopencookie(&user_console, "w", console_out); |
|
|
|
|
stderr = fopencookie(&user_console, "w", console_out); |
|
|
|
|
|
|
|
|
|
setbuf(stdout, NULL); |
|
|
|
|
//setlinebuf(stdout);
|
|
|
|
|