usart: generalise code for both stm32f0 and stm32f1

tags/0.1.0
S.J.R. van Schaik 8 years ago
parent 81b475c334
commit 2f632d140a
  1. 1
      source/platform/Makefile
  2. 1
      source/platform/stm32f0/Makefile
  3. 1
      source/platform/stm32f1/Makefile
  4. 261
      source/platform/stm32f1/usart.c
  5. 10
      source/platform/usart.c

@ -1,6 +1,7 @@
ifeq ($(TARGET),host)
else
obj-y += source/platform/spi_flash.o
obj-y += source/platform/usart.o
endif
-include source/platform/$(TARGET)/Makefile

@ -2,4 +2,3 @@ obj-y += source/platform/stm32f0/gpio.o
obj-y += source/platform/stm32f0/rcc.o
obj-y += source/platform/stm32f0/rtc.o
obj-y += source/platform/stm32f0/spi.o
obj-y += source/platform/stm32f0/usart.o

@ -2,4 +2,3 @@ obj-y += source/platform/stm32f1/gpio.o
obj-y += source/platform/stm32f1/rcc.o
obj-y += source/platform/stm32f1/rtc.o
obj-y += source/platform/stm32f1/spi.o
obj-y += source/platform/stm32f1/usart.o

@ -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;
}

@ -29,6 +29,14 @@ struct usart_console {
static struct usart_console usart[2];
#ifdef STM32F0
#define USART_STOPBITS_1 USART_CR2_STOP_1_0BIT
#endif
#ifdef STM32F1
#define USART_ISR_RXNE USART_SR_RXNE
#endif
static void usart_isr(struct usart_console *console)
{
size_t i;
@ -220,7 +228,7 @@ static int usart_init(struct usart_console *console)
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_CR2_STOP_1_0BIT);
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);
Loading…
Cancel
Save