|
|
|
@ -19,46 +19,43 @@ |
|
|
|
|
|
|
|
|
|
struct usart_console { |
|
|
|
|
char recv_buf[RECV_BUF_LEN]; |
|
|
|
|
void (* process_line)(FILE *fp); |
|
|
|
|
FILE *fp; |
|
|
|
|
volatile size_t cur, next; |
|
|
|
|
volatile size_t cur; |
|
|
|
|
volatile size_t next; |
|
|
|
|
unsigned irq_no; |
|
|
|
|
uint32_t dev; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static struct usart_console *usart[4]; |
|
|
|
|
static struct usart_console usart[4]; |
|
|
|
|
|
|
|
|
|
static void usart_isr(struct usart_console *console) |
|
|
|
|
{ |
|
|
|
|
size_t idx, next; |
|
|
|
|
size_t i; |
|
|
|
|
|
|
|
|
|
if (!console) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
while (usart_get_flag(console->dev, USART_ISR_RXNE)) { |
|
|
|
|
idx = console->next; |
|
|
|
|
console->recv_buf[idx] = usart_recv(console->dev); |
|
|
|
|
|
|
|
|
|
next = (console->next + 1) % RECV_BUF_LEN; |
|
|
|
|
|
|
|
|
|
if (next != console->cur) |
|
|
|
|
console->next = next; |
|
|
|
|
console->recv_buf[console->next] = usart_recv(console->dev); |
|
|
|
|
|
|
|
|
|
if (console->recv_buf[idx] == '\003') |
|
|
|
|
if (console->recv_buf[console->next] == '\003') |
|
|
|
|
scb_reset_system(); |
|
|
|
|
|
|
|
|
|
if (console->recv_buf[idx] == '\r' && console->process_line) |
|
|
|
|
console->process_line(console->fp); |
|
|
|
|
i = (console->next + 1) % RECV_BUF_LEN; |
|
|
|
|
|
|
|
|
|
if (i != console->cur) |
|
|
|
|
console->next = i; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void usart1_isr(void) |
|
|
|
|
{ |
|
|
|
|
usart_isr(usart[0]); |
|
|
|
|
usart_isr(usart + 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void usart2_isr(void) |
|
|
|
|
{ |
|
|
|
|
usart_isr(usart[1]); |
|
|
|
|
usart_isr(usart + 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static char usart_getc(struct usart_console *console, int block) |
|
|
|
@ -75,6 +72,57 @@ static char usart_getc(struct usart_console *console, int block) |
|
|
|
|
return c; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int console_getc(char *c, struct usart_console *console) |
|
|
|
|
{ |
|
|
|
|
if (console->cur == console->next) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
if (console->cur != console->next) { |
|
|
|
|
*c = console->recv_buf[console->cur]; |
|
|
|
|
console->cur = (console->cur + 1) % RECV_BUF_LEN; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int console_getline(struct usart_console *console, char *buf, size_t n) |
|
|
|
|
{ |
|
|
|
|
char *p = buf + strlen(buf); |
|
|
|
|
char c; |
|
|
|
|
|
|
|
|
|
*p = '\0'; |
|
|
|
|
|
|
|
|
|
while (console_getc(&c, console) == 0) { |
|
|
|
|
switch (c) { |
|
|
|
|
case '\r': |
|
|
|
|
usart_send_blocking(console->dev, '\r'); |
|
|
|
|
usart_send_blocking(console->dev, '\n'); |
|
|
|
|
return 0; |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
*p = c; |
|
|
|
|
usart_send_blocking(console->dev, c); |
|
|
|
|
|
|
|
|
|
if (((size_t)p - (size_t)buf) < n) { |
|
|
|
|
++p; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
*p = '\0'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return -E_AGAIN; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static ssize_t usart_read(void *cookie, char *buf, size_t n) |
|
|
|
|
{ |
|
|
|
|
struct usart_console *console = cookie; |
|
|
|
@ -149,9 +197,7 @@ static int usart_get_irq_no(unsigned *irq_no, unsigned dev) |
|
|
|
|
|
|
|
|
|
static int usart_init(struct usart_console *console) |
|
|
|
|
{ |
|
|
|
|
unsigned irq_no; |
|
|
|
|
|
|
|
|
|
if (usart_get_irq_no(&irq_no, console->dev) < 0) |
|
|
|
|
if (usart_get_irq_no(&console->irq_no, console->dev) < 0) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
usart_set_baudrate(console->dev, 115200); |
|
|
|
@ -161,14 +207,14 @@ static int usart_init(struct usart_console *console) |
|
|
|
|
usart_set_mode(console->dev, USART_MODE_TX_RX); |
|
|
|
|
usart_set_flow_control(console->dev, USART_FLOWCONTROL_NONE); |
|
|
|
|
|
|
|
|
|
nvic_enable_irq(irq_no); |
|
|
|
|
nvic_enable_irq(console->irq_no); |
|
|
|
|
usart_enable(console->dev); |
|
|
|
|
usart_enable_rx_interrupt(console->dev); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
FILE *console_init(unsigned dev_id, void (* process_line)(FILE *fp)) |
|
|
|
|
struct usart_console *console_init(unsigned dev_id) |
|
|
|
|
{ |
|
|
|
|
cookie_io_functions_t fops = { |
|
|
|
|
.read = usart_read, |
|
|
|
@ -178,8 +224,7 @@ FILE *console_init(unsigned dev_id, void (* process_line)(FILE *fp)) |
|
|
|
|
}; |
|
|
|
|
struct usart_console *console; |
|
|
|
|
|
|
|
|
|
if (!(console = malloc(sizeof *console))) |
|
|
|
|
return NULL; |
|
|
|
|
console = usart + dev_id; |
|
|
|
|
|
|
|
|
|
switch (dev_id) { |
|
|
|
|
case 0: console->dev = USART1; break; |
|
|
|
@ -189,8 +234,7 @@ FILE *console_init(unsigned dev_id, void (* process_line)(FILE *fp)) |
|
|
|
|
|
|
|
|
|
console->cur = 0; |
|
|
|
|
console->next = 0; |
|
|
|
|
console->process_line = process_line; |
|
|
|
|
usart[dev_id] = console; |
|
|
|
|
//usart[dev_id] = console;
|
|
|
|
|
|
|
|
|
|
usart_init(console); |
|
|
|
|
|
|
|
|
@ -198,5 +242,10 @@ FILE *console_init(unsigned dev_id, void (* process_line)(FILE *fp)) |
|
|
|
|
|
|
|
|
|
setbuf(console->fp, NULL); |
|
|
|
|
|
|
|
|
|
return console; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
FILE *console_to_fp(struct usart_console *console) |
|
|
|
|
{ |
|
|
|
|
return console->fp; |
|
|
|
|
} |
|
|
|
|