diff options
-rw-r--r-- | board/discovery-stm32f072/board.h | 31 | ||||
-rw-r--r-- | board/discovery-stm32f072/build.mk | 2 | ||||
-rw-r--r-- | board/discovery-stm32f072/ec.tasklist | 3 | ||||
-rw-r--r-- | board/discovery-stm32f072/echo.c | 173 | ||||
-rw-r--r-- | board/discovery-stm32f072/gpio.inc | 5 |
5 files changed, 211 insertions, 3 deletions
diff --git a/board/discovery-stm32f072/board.h b/board/discovery-stm32f072/board.h index 459ac8eb3a..3ef289691d 100644 --- a/board/discovery-stm32f072/board.h +++ b/board/discovery-stm32f072/board.h @@ -11,6 +11,14 @@ /* 48 MHz SYSCLK clock frequency */ #define CPU_CLOCK 48000000 +/* Enable USART1,3,4 and USB streams */ +#define CONFIG_STREAM +#define CONFIG_STREAM_USART +#define CONFIG_STREAM_USART1 +#define CONFIG_STREAM_USART3 +#define CONFIG_STREAM_USART4 +#define CONFIG_STREAM_USB + /* the UART console is on USART2 (PA14/PA15) */ #undef CONFIG_UART_CONSOLE #define CONFIG_UART_CONSOLE 2 @@ -18,10 +26,14 @@ /* Optional features */ #define CONFIG_STM_HWTIMER32 #define CONFIG_HW_CRC +#define CONFIG_USB #undef CONFIG_WATCHDOG_HELP #undef CONFIG_LID_SWITCH +/* USB configuration */ +#define CONFIG_USB_PID 0x5009 + /* * Allow dangerous commands all the time, since we don't have a write protect * switch. @@ -35,6 +47,25 @@ #include "gpio_signal.h" +/* USB string indexes */ +enum usb_strings { + USB_STR_DESC = 0, + USB_STR_VENDOR, + USB_STR_PRODUCT, + USB_STR_VERSION, + + USB_STR_COUNT +}; + #endif /* !__ASSEMBLER__ */ +/* USB interface indexes (use define rather than enum to expand them) */ +#define USB_IFACE_STREAM 0 +#define USB_IFACE_COUNT 1 + +/* USB endpoint indexes (use define rather than enum to expand them) */ +#define USB_EP_CONTROL 0 +#define USB_EP_STREAM 1 +#define USB_EP_COUNT 2 + #endif /* __BOARD_H */ diff --git a/board/discovery-stm32f072/build.mk b/board/discovery-stm32f072/build.mk index f3d39ab655..d8a22a6ad5 100644 --- a/board/discovery-stm32f072/build.mk +++ b/board/discovery-stm32f072/build.mk @@ -10,4 +10,4 @@ CHIP:=stm32 CHIP_FAMILY:=stm32f0 CHIP_VARIANT:=stm32f07x -board-y=board.o +board-y=board.o echo.o diff --git a/board/discovery-stm32f072/ec.tasklist b/board/discovery-stm32f072/ec.tasklist index 8ff4e8234b..ae6b6c06e7 100644 --- a/board/discovery-stm32f072/ec.tasklist +++ b/board/discovery-stm32f072/ec.tasklist @@ -18,4 +18,5 @@ */ #define CONFIG_TASK_LIST \ TASK_ALWAYS(HOOKS, hook_task, NULL, TASK_STACK_SIZE) \ - TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) + TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE)\ + TASK_ALWAYS(ECHO, echo_task, NULL, TASK_STACK_SIZE) diff --git a/board/discovery-stm32f072/echo.c b/board/discovery-stm32f072/echo.c new file mode 100644 index 0000000000..ec7353e43e --- /dev/null +++ b/board/discovery-stm32f072/echo.c @@ -0,0 +1,173 @@ +/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +/* + * Task to echo any characters from the three non-console USARTs back to all + * non-console USARTs. + */ + +#include "atomic.h" +#include "common.h" +#include "compile_time_macros.h" +#include "console.h" +#include "panic.h" +#include "task.h" +#include "timer.h" +#include "usart-stm32f0.h" +#include "usb-stream.h" +#include "util.h" + +static void in_ready(struct in_stream const *stream) +{ + task_wake(TASK_ID_ECHO); +} + +static void out_ready(struct out_stream const *stream) +{ + task_wake(TASK_ID_ECHO); +} + +USART_CONFIG(usart1, usart1_hw, 115200, 64, 64, in_ready, NULL) +USART_CONFIG(usart3, usart3_hw, 115200, 64, 64, in_ready, NULL) +USART_CONFIG(usart4, usart4_hw, 115200, 64, 64, in_ready, NULL) +USB_STREAM_CONFIG(usb_stream1, + USB_IFACE_STREAM, + USB_EP_STREAM, + 256, + 256, + in_ready, + out_ready) + +const void *const usb_strings[] = { + [USB_STR_DESC] = usb_string_desc, + [USB_STR_VENDOR] = USB_STRING_DESC("Google Inc."), + [USB_STR_PRODUCT] = USB_STRING_DESC("discovery-stm32f072"), + [USB_STR_VERSION] = USB_STRING_DESC("v1.0"), +}; + +BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT); + +struct stream_console_state { + size_t wrote; +}; + +struct stream_console_config { + struct stream_console_state *state; + + struct in_stream const *in; + struct out_stream const *out; +}; + +#define STREAM_CONSOLE_CONFIG(NAME, IN, OUT) \ + static struct stream_console_state NAME##_state; \ + struct stream_console_config const NAME = { \ + .state = &NAME##_state, \ + .in = IN, \ + .out = OUT, \ + }; + +STREAM_CONSOLE_CONFIG(usart1_stream_console, &usart1.in, &usart1.out) +STREAM_CONSOLE_CONFIG(usart3_stream_console, &usart3.in, &usart3.out) +STREAM_CONSOLE_CONFIG(usart4_stream_console, &usart4.in, &usart4.out) +STREAM_CONSOLE_CONFIG(usb_stream1_console, &usb_stream1.in, &usb_stream1.out) + +static struct stream_console_config const *const consoles[] = { + &usart1_stream_console, + &usart3_stream_console, + &usart4_stream_console, + &usb_stream1_console, +}; + +static size_t echo(struct stream_console_config const *const consoles[], + size_t consoles_count) +{ + size_t total = 0; + size_t i; + + for (i = 0; i < consoles_count; ++i) { + size_t j; + uint8_t buffer[64]; + size_t remaining = 0; + size_t count = in_stream_read(consoles[i]->in, + buffer, + sizeof(buffer)); + + if (count == 0) + continue; + + for (j = 0; j < consoles_count; ++j) + consoles[j]->state->wrote = 0; + + do { + remaining = 0; + + for (j = 0; j < consoles_count; ++j) { + size_t wrote = consoles[j]->state->wrote; + + if (count == wrote) + continue; + + wrote += out_stream_write(consoles[j]->out, + buffer + wrote, + count - wrote); + + consoles[j]->state->wrote = wrote; + + remaining += count - wrote; + } + } while (remaining); + + total += count; + } + + return total; +} + +void echo_task(void) +{ + usart_init(&usart1); + usart_init(&usart3); + usart_init(&usart4); + + while (1) { + while (echo(consoles, ARRAY_SIZE(consoles))) { + /* + * Make sure other tasks, like the HOOKS get to run. + */ + msleep(1); + } + + /* + * There was nothing left to echo, go to sleep and be + * woken up by the next input. + */ + task_wait_event(-1); + } +} + +static int command_echo_info(int argc, char **argv) +{ + char const message[] = "Hello World!\r\n"; + size_t i; + + ccprintf("USART1 RX dropped %d bytes\n", + atomic_read_clear((uint32_t *) &(usart1.state->rx_dropped))); + + ccprintf("USART3 RX dropped %d bytes\n", + atomic_read_clear((uint32_t *) &(usart3.state->rx_dropped))); + + ccprintf("USART4 RX dropped %d bytes\n", + atomic_read_clear((uint32_t *) &(usart4.state->rx_dropped))); + + for (i = 0; i < ARRAY_SIZE(consoles); ++i) + out_stream_write(consoles[i]->out, message, strlen(message)); + + return EC_SUCCESS; +} + +DECLARE_CONSOLE_COMMAND(echo_info, + command_echo_info, + NULL, + "Dump echo task debug info", + NULL); diff --git a/board/discovery-stm32f072/gpio.inc b/board/discovery-stm32f072/gpio.inc index d0bd0b2f3e..0d7586f5ae 100644 --- a/board/discovery-stm32f072/gpio.inc +++ b/board/discovery-stm32f072/gpio.inc @@ -18,4 +18,7 @@ GPIO(LED_R, C, 9, GPIO_OUT_LOW, NULL) UNIMPLEMENTED(ENTERING_RW) UNIMPLEMENTED(WP_L) -ALTERNATE(A, 0xC000, 1, MODULE_UART, 0) /* USART2: PA14/PA15 */ +ALTERNATE(A, 0x0600, 1, MODULE_USART, 0) /* USART1: PA09/PA10 */ +ALTERNATE(A, 0xC000, 1, MODULE_UART, 0) /* USART2: PA14/PA15 */ +ALTERNATE(B, 0x0C00, 1, MODULE_USART, 0) /* USART3: PB10/PB11 */ +ALTERNATE(C, 0x0C00, 1, MODULE_USART, 0) /* USART4: PC10/PC11 */ |