console: usart: set up stdout, stderr and stdout
This commit is contained in:
parent
b0dd5a9abc
commit
a572b357f7
7 changed files with 76 additions and 65 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
struct cmd {
|
struct cmd {
|
||||||
const char *key;
|
const char *key;
|
||||||
void (* exec)(FILE *fp, const char *s);
|
void (* exec)(const char *s);
|
||||||
};
|
};
|
||||||
|
|
||||||
void cmd_loop(FILE *fp, const char *s);
|
void cmd_loop(const char *s);
|
||||||
|
|
|
@ -30,4 +30,4 @@ void spi_send_cmd(uint32_t dev, const char *cmd, size_t cmd_len,
|
||||||
char *data, size_t data_len);
|
char *data, size_t data_len);
|
||||||
void spi_flash_read(uint32_t dev, uint32_t addr, char *data, size_t len);
|
void spi_flash_read(uint32_t dev, uint32_t addr, char *data, size_t len);
|
||||||
void spi_flash_write(uint32_t dev, uint32_t addr, char *data, size_t len);
|
void spi_flash_write(uint32_t dev, uint32_t addr, char *data, size_t len);
|
||||||
void spi_flash_erase(FILE *fp, uint32_t dev, uint32_t addr, size_t len);
|
void spi_flash_erase(uint32_t dev, uint32_t addr, size_t len);
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <libopencm3/stm32/usart.h>
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
FILE *init_usart(uint32_t dev);
|
void console_init(void);
|
||||||
|
|
|
@ -6,11 +6,9 @@
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
console_init();
|
||||||
|
|
||||||
init_spi();
|
init_spi();
|
||||||
fp = init_usart(USART1);
|
cmd_loop("tbm # ");
|
||||||
cmd_loop(fp, "tbm # ");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
#include "spi_flash.h"
|
#include "spi_flash.h"
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
|
|
||||||
static void do_probe(FILE *fp, const char *s);
|
static void do_probe(const char *s);
|
||||||
static void do_read(FILE *fp, const char *s);
|
static void do_read(const char *s);
|
||||||
static void do_write(FILE *fp, const char *s);
|
static void do_write(const char *s);
|
||||||
static void do_erase(FILE *fp, const char *s);
|
static void do_erase(const char *s);
|
||||||
|
|
||||||
struct cmd cmds[] = {
|
struct cmd cmds[] = {
|
||||||
{ "probe", do_probe },
|
{ "probe", do_probe },
|
||||||
|
@ -41,21 +41,21 @@ static void parse_hex(FILE *fp, char *buf, size_t len)
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
memset(s, '\0', 3);
|
memset(s, '\0', 3);
|
||||||
|
|
||||||
while ((s[0] = fgetc(fp)) && !isxdigit(s[0]))
|
while ((s[0] = getc(fp)) && !isxdigit(s[0]))
|
||||||
fputc(s[0], fp);
|
putchar(s[0]);
|
||||||
|
|
||||||
fputc(s[0], fp);
|
putchar(s[0]);
|
||||||
|
|
||||||
while ((s[1] = fgetc(fp)) && !isxdigit(s[1]))
|
while ((s[1] = getc(fp)) && !isxdigit(s[1]))
|
||||||
fputc(s[1], fp);
|
putchar(s[1]);
|
||||||
|
|
||||||
fputc(s[1], fp);
|
putchar(s[1]);
|
||||||
|
|
||||||
*buf++ = strtoul(s, NULL, 16);
|
*buf++ = strtoul(s, NULL, 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_hex_ascii(FILE *fp, const char *buf, size_t len)
|
static void print_hex_ascii(const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
size_t n, i;
|
size_t n, i;
|
||||||
char c;
|
char c;
|
||||||
|
@ -65,35 +65,35 @@ static void print_hex_ascii(FILE *fp, const char *buf, size_t len)
|
||||||
|
|
||||||
for (i = 0; i < 16; ++i) {
|
for (i = 0; i < 16; ++i) {
|
||||||
c = (i < n) ? buf[i] : 0;
|
c = (i < n) ? buf[i] : 0;
|
||||||
fprintf(fp, "%02x", c);
|
printf("%02x", c);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fp, " ");
|
printf(" ");
|
||||||
|
|
||||||
for (i = 0; i < 16; ++i) {
|
for (i = 0; i < 16; ++i) {
|
||||||
c = (i < n) ? buf[i] : 0;
|
c = (i < n) ? buf[i] : 0;
|
||||||
fprintf(fp, "%c", isalnum(c) ? c : '.');
|
printf("%c", isalnum(c) ? c : '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fp, "\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *prompt(FILE *fp, const char *prefix)
|
static char *prompt(const char *prefix)
|
||||||
{
|
{
|
||||||
char *alloc, *line, *s;
|
char *alloc, *line, *s;
|
||||||
size_t nbytes = 0, nalloc_bytes = 16;
|
size_t nbytes = 0, nalloc_bytes = 16;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
fprintf(fp, prefix);
|
printf(prefix);
|
||||||
|
|
||||||
if (!(line = malloc(nalloc_bytes)))
|
if (!(line = malloc(nalloc_bytes)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
s = line;
|
s = line;
|
||||||
|
|
||||||
while ((c = fgetc(fp)) && c != '\n') {
|
while ((c = getchar()) && c != '\n') {
|
||||||
fputc(c, fp);
|
putchar(c);
|
||||||
|
|
||||||
if (nbytes + 1 >= nalloc_bytes) {
|
if (nbytes + 1 >= nalloc_bytes) {
|
||||||
nalloc_bytes *= 2;
|
nalloc_bytes *= 2;
|
||||||
|
@ -108,7 +108,7 @@ static char *prompt(FILE *fp, const char *prefix)
|
||||||
nbytes++;
|
nbytes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fp, "\n");
|
printf("\n");
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
|
@ -118,7 +118,7 @@ err_free_line:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_probe(FILE *fp, const char *s)
|
static void do_probe(const char *s)
|
||||||
{
|
{
|
||||||
char cmd[1] = { CMD_READ_ID };
|
char cmd[1] = { CMD_READ_ID };
|
||||||
char buf[6];
|
char buf[6];
|
||||||
|
@ -126,10 +126,10 @@ static void do_probe(FILE *fp, const char *s)
|
||||||
(void)s;
|
(void)s;
|
||||||
|
|
||||||
spi_send_cmd(SPI1, cmd, 1, buf, 6);
|
spi_send_cmd(SPI1, cmd, 1, buf, 6);
|
||||||
fprintf(fp, "JEDEC ID: %02x%02x%02x\n", buf[0], buf[1], buf[2]);
|
printf("JEDEC ID: %02x%02x%02x\n", buf[0], buf[1], buf[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_read(FILE *fp, const char *s)
|
static void do_read(const char *s)
|
||||||
{
|
{
|
||||||
char buf[256], *end = NULL;
|
char buf[256], *end = NULL;
|
||||||
size_t addr, len, nbytes;
|
size_t addr, len, nbytes;
|
||||||
|
@ -160,14 +160,14 @@ static void do_read(FILE *fp, const char *s)
|
||||||
while (len) {
|
while (len) {
|
||||||
nbytes = min(len, 256);
|
nbytes = min(len, 256);
|
||||||
spi_flash_read(SPI1, addr, buf, nbytes);
|
spi_flash_read(SPI1, addr, buf, nbytes);
|
||||||
print_hex_ascii(fp, buf, nbytes);
|
print_hex_ascii(buf, nbytes);
|
||||||
|
|
||||||
addr += nbytes;
|
addr += nbytes;
|
||||||
len -= nbytes;
|
len -= nbytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_write(FILE *fp, const char *s)
|
static void do_write(const char *s)
|
||||||
{
|
{
|
||||||
char buf[256], *end = NULL;
|
char buf[256], *end = NULL;
|
||||||
size_t addr, len, nbytes;
|
size_t addr, len, nbytes;
|
||||||
|
@ -197,9 +197,9 @@ static void do_write(FILE *fp, const char *s)
|
||||||
|
|
||||||
while (len) {
|
while (len) {
|
||||||
nbytes = (len > 256) ? 256 : len;
|
nbytes = (len > 256) ? 256 : len;
|
||||||
parse_hex(fp, buf, nbytes);
|
parse_hex(stdin, buf, nbytes);
|
||||||
fprintf(fp, "\n");
|
printf("\n");
|
||||||
print_hex_ascii(fp, buf, nbytes);
|
print_hex_ascii(buf, nbytes);
|
||||||
spi_flash_write(SPI1, addr, buf, nbytes);
|
spi_flash_write(SPI1, addr, buf, nbytes);
|
||||||
|
|
||||||
addr += nbytes;
|
addr += nbytes;
|
||||||
|
@ -207,13 +207,11 @@ static void do_write(FILE *fp, const char *s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_erase(FILE *fp, const char *s)
|
static void do_erase(const char *s)
|
||||||
{
|
{
|
||||||
char *end = NULL;
|
char *end = NULL;
|
||||||
size_t addr, len;
|
size_t addr, len;
|
||||||
|
|
||||||
(void)fp;
|
|
||||||
|
|
||||||
if (strncmp(s, "0x", 2) == 0)
|
if (strncmp(s, "0x", 2) == 0)
|
||||||
s += 2;
|
s += 2;
|
||||||
|
|
||||||
|
@ -237,10 +235,10 @@ static void do_erase(FILE *fp, const char *s)
|
||||||
if (!len)
|
if (!len)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
spi_flash_erase(fp, SPI1, addr, len);
|
spi_flash_erase(SPI1, addr, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_cmd(FILE *fp, const char *s)
|
static void parse_cmd(const char *s)
|
||||||
{
|
{
|
||||||
struct cmd *cmd;
|
struct cmd *cmd;
|
||||||
const char *args;
|
const char *args;
|
||||||
|
@ -255,17 +253,17 @@ static void parse_cmd(FILE *fp, const char *s)
|
||||||
|
|
||||||
for (cmd = cmds; cmd->key; cmd++) {
|
for (cmd = cmds; cmd->key; cmd++) {
|
||||||
if (strcmp(cmd->key, key) == 0)
|
if (strcmp(cmd->key, key) == 0)
|
||||||
cmd->exec(fp, args);
|
cmd->exec(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_loop(FILE *fp, const char *show)
|
void cmd_loop(const char *show)
|
||||||
{
|
{
|
||||||
char *line;
|
char *line;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
line = prompt(fp, show);
|
line = prompt(show);
|
||||||
parse_cmd(fp, line);
|
parse_cmd(line);
|
||||||
free(line);
|
free(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ void spi_flash_write(uint32_t dev, uint32_t addr, char *data, size_t len)
|
||||||
spi_disable_write(dev);
|
spi_disable_write(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spi_flash_erase(FILE *fp, uint32_t dev, uint32_t addr, size_t len)
|
void spi_flash_erase(uint32_t dev, uint32_t addr, size_t len)
|
||||||
{
|
{
|
||||||
char cmd[4];
|
char cmd[4];
|
||||||
size_t size;
|
size_t size;
|
||||||
|
@ -144,7 +144,7 @@ void spi_flash_erase(FILE *fp, uint32_t dev, uint32_t addr, size_t len)
|
||||||
default: goto err_disable_write;
|
default: goto err_disable_write;
|
||||||
};
|
};
|
||||||
|
|
||||||
fprintf(fp, "addr: %lx; size: %u\n", addr, size);
|
printf("addr: %lx; size: %u\n", addr, size);
|
||||||
spi_flash_addr(cmd, addr);
|
spi_flash_addr(cmd, addr);
|
||||||
spi_send_cmd(dev, cmd, 4, NULL, 0);
|
spi_send_cmd(dev, cmd, 4, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,11 +47,8 @@ static ssize_t usart_write(void *cookie, const char *buf, size_t n)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *init_usart(uint32_t dev)
|
static void usart_init(void)
|
||||||
{
|
{
|
||||||
cookie_io_functions_t stub = { usart_read, usart_write, NULL, NULL };
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
/* Set up clocks for USART 1 */
|
/* Set up clocks for USART 1 */
|
||||||
rcc_periph_clock_enable(RCC_GPIOA);
|
rcc_periph_clock_enable(RCC_GPIOA);
|
||||||
rcc_periph_clock_enable(RCC_USART1);
|
rcc_periph_clock_enable(RCC_USART1);
|
||||||
|
@ -61,16 +58,37 @@ FILE *init_usart(uint32_t dev)
|
||||||
gpio_set_af(GPIOA, GPIO_AF1, GPIO9 | GPIO10);
|
gpio_set_af(GPIOA, GPIO_AF1, GPIO9 | GPIO10);
|
||||||
gpio_set_af(GPIOA, GPIO_AF1, GPIO10);
|
gpio_set_af(GPIOA, GPIO_AF1, GPIO10);
|
||||||
|
|
||||||
usart_set_baudrate(dev, 115200);
|
usart_set_baudrate(USART1, 115200);
|
||||||
usart_set_databits(dev, 8);
|
usart_set_databits(USART1, 8);
|
||||||
usart_set_parity(dev, USART_PARITY_NONE);
|
usart_set_parity(USART1, USART_PARITY_NONE);
|
||||||
usart_set_stopbits(dev, USART_CR2_STOP_1_0BIT);
|
usart_set_stopbits(USART1, USART_CR2_STOP_1_0BIT);
|
||||||
usart_set_mode(dev, USART_MODE_TX_RX);
|
usart_set_mode(USART1, USART_MODE_TX_RX);
|
||||||
usart_set_flow_control(dev, USART_FLOWCONTROL_NONE);
|
usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE);
|
||||||
|
|
||||||
usart_enable(dev);
|
usart_enable(USART1);
|
||||||
|
}
|
||||||
fp = fopencookie((void *)dev, "rw+", stub);
|
|
||||||
setvbuf(fp, NULL, _IONBF, 0);
|
void console_init(void)
|
||||||
return fp;
|
{
|
||||||
|
cookie_io_functions_t console_in = {
|
||||||
|
.read = usart_read,
|
||||||
|
.write = NULL,
|
||||||
|
.seek = NULL,
|
||||||
|
.close = NULL,
|
||||||
|
};
|
||||||
|
cookie_io_functions_t console_out = {
|
||||||
|
.read = NULL,
|
||||||
|
.write = usart_write,
|
||||||
|
.seek = NULL,
|
||||||
|
.close = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
usart_init();
|
||||||
|
|
||||||
|
stdin = fopencookie((void *)USART1, "r", console_in);
|
||||||
|
stdout = fopencookie((void *)USART1, "w", console_out);
|
||||||
|
stderr = fopencookie((void *)USART1, "w", console_out);
|
||||||
|
|
||||||
|
setlinebuf(stdout);
|
||||||
|
setbuf(stderr, NULL);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue