diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2014-10-15 11:18:26 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-10-20 19:59:43 +0000 |
commit | ece9501f06e3eb5c0b09f440859f817d1d39a93c (patch) | |
tree | b8cf95e645f566dc2a7633e05de4a3a6ff441fd3 | |
parent | ccc270368bb9193c5b368b1b82d5a8fecc5c4bc4 (diff) | |
download | chrome-ec-ece9501f06e3eb5c0b09f440859f817d1d39a93c.tar.gz |
Twinkie: update sniffer code
- Remove hardware double-buffering : it's complex to get right and does
not provide any performance improvement.
- Increase buffer size x2 to decrease overflow frequency.
- Fix buffering and simplify code.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=none
BUG=chrome-os-partner:28337
TEST=make BOARD=twinkie
do a long acquisition on a sample pattern from the function generator
and verify that no packet are missing and the waveform looks good.
Change-Id: I12a9e8370d3f238e8894f15ce0190e2e0fbc26d7
Reviewed-on: https://chromium-review.googlesource.com/223565
Reviewed-by: Todd Broch <tbroch@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | board/twinkie/sniffer.c | 99 |
1 files changed, 50 insertions, 49 deletions
diff --git a/board/twinkie/sniffer.c b/board/twinkie/sniffer.c index 5d6fdcc9e0..d664edb76a 100644 --- a/board/twinkie/sniffer.c +++ b/board/twinkie/sniffer.c @@ -3,6 +3,7 @@ * found in the LICENSE file. */ +#include "atomic.h" #include "clock.h" #include "common.h" #include "console.h" @@ -23,19 +24,24 @@ #define EP_PAYLOAD_SIZE (EP_BUF_SIZE - 4) /* Buffer enough to avoid overflowing due to USB latencies on both sides */ -#define RX_COUNT (8 * EP_PAYLOAD_SIZE) +#define RX_COUNT (16 * EP_PAYLOAD_SIZE) /* Task event for the USB transfer interrupt */ #define USB_EVENTS TASK_EVENT_CUSTOM(3) /* edge timing samples */ static uint8_t samples[RX_COUNT]; +/* bitmap of the samples sub-buffer filled with DMA data */ +static volatile uint32_t filled_dma; +/* timestamps of the beginning of DMA buffers */ +static uint16_t sample_tstamp[2]; +/* sequence number of the beginning of DMA buffers */ +static uint16_t sample_seq[2]; /* Bulk endpoint double buffer */ static usb_uint ep_buf[2][EP_BUF_SIZE / 2] __usb_ram; - -/* The host is reading the incoming packets */ -static int tx_on; +/* USB Buffers not used, ready to be filled */ +static volatile uint32_t free_usb = 3; /* USB descriptors */ const struct usb_interface_descriptor USB_IFACE_DESC(USB_IFACE_VENDOR) = { @@ -62,31 +68,29 @@ const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_VENDOR, /* USB callbacks */ static void ep_tx(void) { - int b = !(STM32_USB_EP(USB_EP_SNIFFER) & EP_TX_DTOG); - if (b) - btable_ep[USB_EP_SNIFFER].rx_count = 0; - else - btable_ep[USB_EP_SNIFFER].tx_count = 0; + static int b; /* current buffer index */ + if (btable_ep[USB_EP_SNIFFER].tx_count) { + /* we have transmitted the previous buffer, toggle it */ + free_usb |= 1 << b; + b = b ? 0 : 1; + btable_ep[USB_EP_SNIFFER].tx_addr = usb_sram_addr(ep_buf[b]); + } + /* re-enable data transmission if we have available data */ + btable_ep[USB_EP_SNIFFER].tx_count = (free_usb & (1<<b)) ? 0 + : EP_BUF_SIZE; + STM32_TOGGLE_EP(USB_EP_SNIFFER, EP_TX_MASK, EP_TX_VALID, 0); /* wake up the processing */ task_set_event(TASK_ID_SNIFFER, 1 << b, 0); - /* clear IT, toggle and validate buffers */ - STM32_TOGGLE_EP(USB_EP_SNIFFER, 0, 0, EP_RX_DTOG); - STM32_TOGGLE_EP(USB_EP_SNIFFER, EP_TX_MASK, EP_TX_VALID, 0); - /* record the valid transmission */ - tx_on = 1; } static void ep_reset(void) { - /* Bulk IN endpoint with double-buffering */ + /* Bulk IN endpoint */ btable_ep[USB_EP_SNIFFER].tx_addr = usb_sram_addr(ep_buf[0]); - btable_ep[USB_EP_SNIFFER].rx_addr = usb_sram_addr(ep_buf[1]); - btable_ep[USB_EP_SNIFFER].tx_count = 0; - btable_ep[USB_EP_SNIFFER].rx_count = 0; + btable_ep[USB_EP_SNIFFER].tx_count = EP_BUF_SIZE; STM32_USB_EP(USB_EP_SNIFFER) = (USB_EP_SNIFFER << 0) /*Endpoint Num*/ | (3 << 4) /* TX Valid */ | (0 << 9) /* Bulk EP */ | - (1 << 8) /* DBL BUF */ | (0 << 12) /* RX Disabled */; } USB_DECLARE_EP(USB_EP_SNIFFER, ep_tx, ep_tx, ep_reset); @@ -120,10 +124,20 @@ void tim_dma_handler(void) stm32_dma_regs_t *dma = STM32_DMA1_REGS; uint32_t stat = dma->isr & (STM32_DMA_ISR_HTIF(DMAC_TIM_RX) | STM32_DMA_ISR_TCIF(DMAC_TIM_RX)); - seq++; + int idx = !(stat & STM32_DMA_ISR_HTIF(DMAC_TIM_RX)); + uint16_t mask = idx ? 0xFF00 : 0x00FF; + int next = idx ? 0x0001 : 0x0100; + + sample_tstamp[idx] = __hw_clock_source_read(); + sample_seq[idx] = (seq++ << 3) & 0x0ff8; + if (filled_dma & next) { + oflow++; + sample_seq[idx] |= 0x8000; + } + filled_dma |= mask; dma->ifcr |= STM32_DMA_ISR_ALL(DMAC_TIM_RX); - if (tx_on) - task_set_event(TASK_ID_SNIFFER, TASK_EVENT_CUSTOM(stat), 0); + /* time to process the samples */ + task_set_event(TASK_ID_SNIFFER, TASK_EVENT_CUSTOM(stat), 0); } DECLARE_IRQ(STM32_IRQ_DMA_CHANNEL_4_7, tim_dma_handler, 1); @@ -190,38 +204,25 @@ DECLARE_HOOK(HOOK_INIT, sniffer_init, HOOK_PRIO_DEFAULT); /* Task to post-process the samples and copy them the USB endpoint buffer */ void sniffer_task(void) { - uint16_t cnt = 0; - int off = 0; - uint8_t freebuf = 3; - struct stm32_endpoint *ep = btable_ep+USB_EP_SNIFFER; + int u = 0; /* current USB buffer index */ + int d = 0; /* current DMA buffer index */ + int off = 0; /* DMA buffer offset */ while (1) { /* Wait for a new buffer of samples or a new USB free buffer */ - uint32_t evt = task_wait_event(-1); - - freebuf |= evt & USB_EVENTS; - if (evt & ~USB_EVENTS) { - off = evt & STM32_DMA_ISR_TCIF(DMAC_TIM_RX) ? - RX_COUNT/2 : 0; - cnt += RX_COUNT/2; - if (cnt > RX_COUNT) { - cnt -= RX_COUNT/2; - oflow++; - } - } + task_wait_event(-1); + /* send the available samples over USB if we have a buffer*/ - while (cnt && freebuf) { - int b = freebuf & 1 ? 0 : 1; - freebuf &= ~(1 << b); - ep_buf[b][0] = (seq << 8) | 1 /* CC1 stream */; - ep_buf[b][1] = __hw_clock_source_read(); - memcpy_usbram(ep_buf[b] + 2, + while (filled_dma && free_usb) { + ep_buf[u][0] = sample_seq[d >> 3] | (d & 7); + ep_buf[u][1] = sample_tstamp[d >> 3]; + memcpy_usbram(ep_buf[u] + 2, samples+off, EP_PAYLOAD_SIZE); - if (b) - ep->rx_count = EP_BUF_SIZE; - else - ep->tx_count = EP_BUF_SIZE; - cnt -= EP_PAYLOAD_SIZE; + atomic_clear((uint32_t *)&free_usb, 1 << u); + u = !u; + atomic_clear((uint32_t *)&filled_dma, 1 << d); + + d = (d + 1) & 15; off += EP_PAYLOAD_SIZE; if (off >= RX_COUNT) off = 0; |