parent
81b475c334
commit
2f632d140a
@ -1,6 +1,7 @@ |
|||||||
ifeq ($(TARGET),host) |
ifeq ($(TARGET),host) |
||||||
else |
else |
||||||
obj-y += source/platform/spi_flash.o
|
obj-y += source/platform/spi_flash.o
|
||||||
|
obj-y += source/platform/usart.o
|
||||||
endif |
endif |
||||||
|
|
||||||
-include source/platform/$(TARGET)/Makefile |
-include source/platform/$(TARGET)/Makefile |
||||||
|
@ -1,261 +0,0 @@ |
|||||||
#define _GNU_SOURCE |
|
||||||
#include <libopencm3/stm32/usart.h> |
|
||||||
#include <libopencm3/cm3/nvic.h> |
|
||||||
#include <libopencm3/cm3/scb.h> |
|
||||||
|
|
||||||
#include <ctype.h> |
|
||||||
#include <stdarg.h> |
|
||||||
#include <stdio.h> |
|
||||||
#include <stdlib.h> |
|
||||||
#include <string.h> |
|
||||||
#include <errno.h> |
|
||||||
#include <stddef.h> |
|
||||||
#include <limits.h> |
|
||||||
#include <sys/types.h> |
|
||||||
|
|
||||||
#include <console.h> |
|
||||||
#include <macros.h> |
|
||||||
|
|
||||||
#define RECV_BUF_LEN 128 |
|
||||||
|
|
||||||
struct usart_console { |
|
||||||
struct console console; |
|
||||||
char recv_buf[RECV_BUF_LEN]; |
|
||||||
volatile size_t cur; |
|
||||||
volatile size_t next; |
|
||||||
unsigned irq_no; |
|
||||||
uint32_t dev; |
|
||||||
}; |
|
||||||
|
|
||||||
static struct usart_console usart[2]; |
|
||||||
|
|
||||||
static void usart_isr(struct usart_console *console) |
|
||||||
{ |
|
||||||
size_t i; |
|
||||||
|
|
||||||
if (!console) |
|
||||||
return; |
|
||||||
|
|
||||||
while (usart_get_flag(console->dev, USART_SR_RXNE)) { |
|
||||||
console->recv_buf[console->next] = usart_recv(console->dev); |
|
||||||
|
|
||||||
i = (console->next + 1) % RECV_BUF_LEN; |
|
||||||
|
|
||||||
if (i != console->cur) |
|
||||||
console->next = i; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void usart1_isr(void) |
|
||||||
{ |
|
||||||
usart_isr(usart + 0); |
|
||||||
} |
|
||||||
|
|
||||||
void usart2_isr(void) |
|
||||||
{ |
|
||||||
usart_isr(usart + 1); |
|
||||||
} |
|
||||||
|
|
||||||
int console_peek(char *c, struct console *console_, int block) |
|
||||||
{ |
|
||||||
struct usart_console *console = container_of(console_, |
|
||||||
struct usart_console, console); |
|
||||||
|
|
||||||
while (block && console->cur == console->next); |
|
||||||
|
|
||||||
if (console->cur != console->next) { |
|
||||||
*c = console->recv_buf[console->cur]; |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
return -EAGAIN; |
|
||||||
} |
|
||||||
|
|
||||||
int console_getc(char *c, struct console *console_) |
|
||||||
{ |
|
||||||
struct usart_console *console = container_of(console_, |
|
||||||
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 console *console_, char *buf, size_t n) |
|
||||||
{ |
|
||||||
struct usart_console *console = container_of(console_, |
|
||||||
struct usart_console, console); |
|
||||||
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'; |
|
||||||
} |
|
||||||
|
|
||||||
*p = '\0'; |
|
||||||
|
|
||||||
return -EAGAIN; |
|
||||||
} |
|
||||||
|
|
||||||
ssize_t console_read(struct console *console_, char *buf, size_t n) |
|
||||||
{ |
|
||||||
struct usart_console *console = container_of(console_, |
|
||||||
struct usart_console, console); |
|
||||||
char *p = buf; |
|
||||||
char c; |
|
||||||
|
|
||||||
*buf = '\0'; |
|
||||||
|
|
||||||
while (console_peek(&c, console_, 1) == 0) { |
|
||||||
switch (c) { |
|
||||||
case '\004': |
|
||||||
if (buf < p) |
|
||||||
goto out; |
|
||||||
|
|
||||||
console_getc(&c, console_); |
|
||||||
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; |
|
||||||
} |
|
||||||
|
|
||||||
console_getc(&c, console_); |
|
||||||
|
|
||||||
break; |
|
||||||
case '\r': |
|
||||||
if (((size_t)p - (size_t)buf) >= n) |
|
||||||
goto out; |
|
||||||
|
|
||||||
*p++ = '\n'; |
|
||||||
usart_send_blocking(console->dev, '\r'); |
|
||||||
console_getc(&c, console_); |
|
||||||
goto out; |
|
||||||
default: |
|
||||||
if (((size_t)p - (size_t)buf) >= n) |
|
||||||
goto out; |
|
||||||
|
|
||||||
*p++ = c; |
|
||||||
usart_send_blocking(console->dev, c); |
|
||||||
console_getc(&c, console_); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
out: |
|
||||||
*p = '\0'; |
|
||||||
|
|
||||||
return p - buf; |
|
||||||
} |
|
||||||
|
|
||||||
static ssize_t usart_write(void *cookie, const char *buf, size_t n) |
|
||||||
{ |
|
||||||
struct usart_console *console = cookie; |
|
||||||
size_t i; |
|
||||||
|
|
||||||
for (i = 0; i < n; ++i) { |
|
||||||
if (buf[i] == '\n') |
|
||||||
usart_send_blocking(console->dev, '\r'); |
|
||||||
|
|
||||||
usart_send_blocking(console->dev, buf[i]); |
|
||||||
}; |
|
||||||
|
|
||||||
return i; |
|
||||||
} |
|
||||||
|
|
||||||
static int usart_get_irq_no(unsigned *irq_no, unsigned dev) |
|
||||||
{ |
|
||||||
if (!irq_no) |
|
||||||
return -1; |
|
||||||
|
|
||||||
switch (dev) { |
|
||||||
case USART1: *irq_no = NVIC_USART1_IRQ; break; |
|
||||||
case USART2: *irq_no = NVIC_USART2_IRQ; break; |
|
||||||
default: return -1; |
|
||||||
} |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
static int usart_init(struct usart_console *console) |
|
||||||
{ |
|
||||||
if (usart_get_irq_no(&console->irq_no, console->dev) < 0) |
|
||||||
return -1; |
|
||||||
|
|
||||||
usart_set_baudrate(console->dev, 115200); |
|
||||||
usart_set_databits(console->dev, 8); |
|
||||||
usart_set_parity(console->dev, USART_PARITY_NONE); |
|
||||||
usart_set_stopbits(console->dev, USART_STOPBITS_1); |
|
||||||
usart_set_mode(console->dev, USART_MODE_TX_RX); |
|
||||||
usart_set_flow_control(console->dev, USART_FLOWCONTROL_NONE); |
|
||||||
|
|
||||||
nvic_enable_irq(console->irq_no); |
|
||||||
usart_enable(console->dev); |
|
||||||
usart_enable_rx_interrupt(console->dev); |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
struct console *console_init(unsigned dev_id) |
|
||||||
{ |
|
||||||
cookie_io_functions_t fops = { |
|
||||||
.read = NULL, |
|
||||||
.write = usart_write, |
|
||||||
.seek = NULL, |
|
||||||
.close = NULL, |
|
||||||
}; |
|
||||||
struct usart_console *console; |
|
||||||
|
|
||||||
console = usart + dev_id; |
|
||||||
|
|
||||||
switch (dev_id) { |
|
||||||
case 0: console->dev = USART1; break; |
|
||||||
case 1: console->dev = USART2; break; |
|
||||||
default: return NULL; |
|
||||||
} |
|
||||||
|
|
||||||
console->cur = 0; |
|
||||||
console->next = 0; |
|
||||||
|
|
||||||
usart_init(console); |
|
||||||
|
|
||||||
console->console.fp = fopencookie(console, "w", fops); |
|
||||||
setvbuf(console->console.fp, NULL, _IONBF, 0); |
|
||||||
|
|
||||||
return &console->console; |
|
||||||
} |
|
Loading…
Reference in new issue