From e6f670440832f519464b19f497b4cac9476de548 Mon Sep 17 00:00:00 2001 From: Anton Staaf Date: Mon, 2 Mar 2015 14:48:27 -0800 Subject: USB Stream: Make RX and TX buffer sizes configurable Previously the USB Stream buffer sizes were fixed at USB_MAX_PACKET_SIZE (currently 64 bytes). But that ended up using up too much packet RAM, a very limited resource. This change makes them configurable and adds asserts to insure that the sizes are valid for the underlying hardware. Signed-off-by: Anton Staaf BRANCH=None BUG=None TEST=make buildall -j Verify that USART forwarding on discovery works Change-Id: Ib19c0dcfa9b16f23c1d72a5a7fc18026ab103f05 Reviewed-on: https://chromium-review.googlesource.com/255232 Trybot-Ready: Anton Staaf Tested-by: Anton Staaf Reviewed-by: Vic Yang Commit-Queue: Anton Staaf --- board/discovery-stm32f072/echo.c | 2 ++ chip/stm32/usb-stream.c | 12 ++++++++++-- chip/stm32/usb-stream.h | 32 ++++++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/board/discovery-stm32f072/echo.c b/board/discovery-stm32f072/echo.c index 56f99a1ddf..56fbef7bbe 100644 --- a/board/discovery-stm32f072/echo.c +++ b/board/discovery-stm32f072/echo.c @@ -75,6 +75,8 @@ USB_STREAM_CONFIG(usb_stream1, USB_IFACE_STREAM, USB_STR_STREAM_NAME, USB_EP_STREAM, + 64, + 64, usb_rx_queue, usb_tx_queue, usb_in.consumer, diff --git a/chip/stm32/usb-stream.c b/chip/stm32/usb-stream.c index 42d9d3774c..05351a8ca3 100644 --- a/chip/stm32/usb-stream.c +++ b/chip/stm32/usb-stream.c @@ -36,7 +36,7 @@ static size_t tx_write(struct usb_stream_config const *config) { size_t count = consumer_read_memcpy(&config->consumer, config->tx_ram, - USB_MAX_PACKET_SIZE, + config->tx_size, memcpy_to_usbram); btable_ep[config->endpoint].tx_count = count; @@ -120,6 +120,14 @@ void usb_stream_rx(struct usb_stream_config const *config) } } +static usb_uint usb_ep_rx_size(size_t bytes) +{ + if (bytes < 64) + return bytes << 9; + else + return 0x8000 | ((bytes - 32) << 5); +} + void usb_stream_reset(struct usb_stream_config const *config) { int i = config->endpoint; @@ -128,7 +136,7 @@ void usb_stream_reset(struct usb_stream_config const *config) btable_ep[i].tx_count = 0; btable_ep[i].rx_addr = usb_sram_addr(config->rx_ram); - btable_ep[i].rx_count = 0x8000 | ((USB_MAX_PACKET_SIZE / 32 - 1) << 10); + btable_ep[i].rx_count = usb_ep_rx_size(config->rx_size); config->state->rx_waiting = 0; diff --git a/chip/stm32/usb-stream.h b/chip/stm32/usb-stream.h index 06374676f9..cca1523ab1 100644 --- a/chip/stm32/usb-stream.h +++ b/chip/stm32/usb-stream.h @@ -51,6 +51,9 @@ struct usb_stream_config { */ int endpoint; + size_t rx_size; + size_t tx_size; + usb_uint *rx_ram; usb_uint *tx_ram; @@ -81,6 +84,10 @@ extern struct producer_ops const usb_stream_producer_ops; * ENDPOINT is the index of the USB bulk endpoint used for receiving and * transmitting bytes. * + * RX_SIZE and TX_SIZE are the number of bytes of USB packet RAM to allocate + * for the RX and TX packets respectively. The valid values for these + * parameters are dictated by the USB peripheral. + * * RX_QUEUE and TX_QUEUE are the names of the RX and TX queues that this driver * should write to and read from respectively. They must match the queues * that the CONSUMER and PRODUCER read from and write to respectively. @@ -92,8 +99,8 @@ extern struct producer_ops const usb_stream_producer_ops; * The following assertions can not be made because they require access to * non-const fields, but should be kept in mind. * - * BUILD_ASSERT(RX_QUEUE.buffer_units >= USB_MAX_PACKET_SIZE); - * BUILD_ASSERT(TX_QUEUE.buffer_units >= USB_MAX_PACKET_SIZE); + * BUILD_ASSERT(RX_QUEUE.buffer_units >= RX_SIZE); + * BUILD_ASSERT(TX_QUEUE.buffer_units >= TX_SIZE); * BUILD_ASSERT(RX_QUEUE.unit_bytes == 1); * BUILD_ASSERT(TX_QUEUE.unit_bytes == 1); * BUILD_ASSERT(PRODUCER.queue == &TX_QUEUE); @@ -103,17 +110,30 @@ extern struct producer_ops const usb_stream_producer_ops; INTERFACE, \ INTERFACE_NAME, \ ENDPOINT, \ + RX_SIZE, \ + TX_SIZE, \ RX_QUEUE, \ TX_QUEUE, \ CONSUMER, \ PRODUCER) \ \ - static usb_uint CONCAT2(NAME, _ep_rx_buffer)[USB_MAX_PACKET_SIZE / 2] __usb_ram; \ - static usb_uint CONCAT2(NAME, _ep_tx_buffer)[USB_MAX_PACKET_SIZE / 2] __usb_ram; \ + BUILD_ASSERT(RX_SIZE <= USB_MAX_PACKET_SIZE); \ + BUILD_ASSERT(TX_SIZE <= USB_MAX_PACKET_SIZE); \ + BUILD_ASSERT(RX_SIZE > 0); \ + BUILD_ASSERT(TX_SIZE > 0); \ + BUILD_ASSERT((RX_SIZE < 64 && (RX_SIZE & 0x01) == 0) || \ + (RX_SIZE < 1024 && (RX_SIZE & 0x1f) == 0)); \ + BUILD_ASSERT((TX_SIZE < 64 && (TX_SIZE & 0x01) == 0) || \ + (TX_SIZE < 1024 && (TX_SIZE & 0x1f) == 0)); \ + \ + static usb_uint CONCAT2(NAME, _ep_rx_buffer)[RX_SIZE / 2] __usb_ram; \ + static usb_uint CONCAT2(NAME, _ep_tx_buffer)[TX_SIZE / 2] __usb_ram; \ static struct usb_stream_state CONCAT2(NAME, _state); \ struct usb_stream_config const NAME = { \ .state = &CONCAT2(NAME, _state), \ .endpoint = ENDPOINT, \ + .rx_size = RX_SIZE, \ + .tx_size = TX_SIZE, \ .rx_ram = CONCAT2(NAME, _ep_rx_buffer), \ .tx_ram = CONCAT2(NAME, _ep_tx_buffer), \ .consumer = { \ @@ -145,7 +165,7 @@ extern struct producer_ops const usb_stream_producer_ops; .bDescriptorType = USB_DT_ENDPOINT, \ .bEndpointAddress = 0x80 | ENDPOINT, \ .bmAttributes = 0x02 /* Bulk IN */, \ - .wMaxPacketSize = USB_MAX_PACKET_SIZE, \ + .wMaxPacketSize = TX_SIZE, \ .bInterval = 10, \ }; \ const struct usb_endpoint_descriptor \ @@ -154,7 +174,7 @@ extern struct producer_ops const usb_stream_producer_ops; .bDescriptorType = USB_DT_ENDPOINT, \ .bEndpointAddress = ENDPOINT, \ .bmAttributes = 0x02 /* Bulk OUT */, \ - .wMaxPacketSize = USB_MAX_PACKET_SIZE, \ + .wMaxPacketSize = RX_SIZE, \ .bInterval = 0, \ }; \ static void CONCAT2(NAME, _ep_tx)(void) \ -- cgit v1.2.1