diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2014-10-20 15:13:59 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-10-28 06:12:39 +0000 |
commit | b8e4f1b66a06d556b4443c182de541b187da32ac (patch) | |
tree | 3eec83920e889b4a4ae69e62aa19aa0ec41796d9 | |
parent | 682f7aabda3bc55854c1df8fd2757e4d600832f1 (diff) | |
download | chrome-ec-b8e4f1b66a06d556b4443c182de541b187da32ac.tar.gz |
twinkie: dual channel CCx sniffingstabilize-6412.B
Update the sniffer code to sample both CC lines at the same time.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=none
BUG=chrome-os-partner:28337
TEST=make BOARD=twinkie
do an on a sample pattern from the function generator on both channels
and verify that the waveform looks good.
Change-Id: I30c607591775531e432e757f61209733804b55e5
Reviewed-on: https://chromium-review.googlesource.com/224583
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@google.com>
Tested-by: Vincent Palatin <vpalatin@google.com>
-rw-r--r-- | board/twinkie/board.c | 5 | ||||
-rw-r--r-- | board/twinkie/board.h | 6 | ||||
-rw-r--r-- | board/twinkie/sniffer.c | 169 |
3 files changed, 111 insertions, 69 deletions
diff --git a/board/twinkie/board.c b/board/twinkie/board.c index 109b90da41..682c15945e 100644 --- a/board/twinkie/board.c +++ b/board/twinkie/board.c @@ -34,8 +34,9 @@ void board_config_pre_init(void) { /* enable SYSCFG clock */ STM32_RCC_APB2ENR |= 1 << 0; - /* Remap USART DMA to match the USART driver */ - STM32_SYSCFG_CFGR1 |= (1 << 9) | (1 << 10);/* Remap USART1 RX/TX DMA */ + /* Remap USART DMA to match the USART driver and TIM2 DMA */ + STM32_SYSCFG_CFGR1 |= (1 << 9) | (1 << 10) /* Remap USART1 RX/TX DMA */ + | (1 << 29);/* Remap TIM2 DMA */ /* 40 MHz pin speed on UART PA9/PA10 */ STM32_GPIO_OSPEEDR(GPIO_A) |= 0x003C0000; /* 40 MHz pin speed on TX clock out PB9 */ diff --git a/board/twinkie/board.h b/board/twinkie/board.h index 6e4dc5c1ee..1c257dae9d 100644 --- a/board/twinkie/board.h +++ b/board/twinkie/board.h @@ -15,7 +15,6 @@ #define CONFIG_UART_CONSOLE 1 /* Optional features */ -#define CONFIG_STM_HWTIMER32 #define CONFIG_USB #define CONFIG_USB_CONSOLE @@ -54,8 +53,9 @@ #ifndef __ASSEMBLER__ /* Timer selection */ -#define TIM_CLOCK32 2 -#define TIM_ADC 3 +#define TIM_CLOCK_MSB 3 +#define TIM_CLOCK_LSB 15 +#define TIM_ADC 16 #include "gpio_signal.h" diff --git a/board/twinkie/sniffer.c b/board/twinkie/sniffer.c index d664edb76a..a4e4f6f16e 100644 --- a/board/twinkie/sniffer.c +++ b/board/twinkie/sniffer.c @@ -30,13 +30,13 @@ #define USB_EVENTS TASK_EVENT_CUSTOM(3) /* edge timing samples */ -static uint8_t samples[RX_COUNT]; +static uint8_t samples[2][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]; +static uint16_t sample_tstamp[4]; /* sequence number of the beginning of DMA buffers */ -static uint16_t sample_seq[2]; +static uint16_t sample_seq[4]; /* Bulk endpoint double buffer */ static usb_uint ep_buf[2][EP_BUF_SIZE / 2] __usb_ram; @@ -97,19 +97,26 @@ USB_DECLARE_EP(USB_EP_SNIFFER, ep_tx, ep_tx, ep_reset); /* --- RX operation using comparator linked to timer --- */ -/* RX is using COMP1 triggering TIM1 CH1 */ -#define DMAC_TIM_RX STM32_DMAC_CH6 -#define TIM_CCR_IDX 1 -#define TIM_CCR_CS 1 -#define EXTI_COMP 21 - -/* Timer used for RX clocking */ -#define TIM_RX 1 +/* RX on CC1 is using COMP1 triggering TIM1 CH1 */ +#define TIM_RX1 1 +#define DMAC_TIM_RX1 STM32_DMAC_CH6 +#define TIM_RX1_CCR_IDX 1 +/* RX on CC1 is using COMP2 triggering TIM2 CH4 */ +#define TIM_RX2 2 +#define DMAC_TIM_RX2 STM32_DMAC_CH7 +#define TIM_RX2_CCR_IDX 4 + /* Clock divider for RX edges timings (2.4Mhz counter from 48Mhz clock) */ #define RX_CLOCK_DIV (20 - 1) -static const struct dma_option dma_tim_option = { - DMAC_TIM_RX, (void *)&STM32_TIM_CCRx(TIM_RX, TIM_CCR_IDX), +static const struct dma_option dma_tim_cc1 = { + DMAC_TIM_RX1, (void *)&STM32_TIM_CCRx(TIM_RX1, TIM_RX1_CCR_IDX), + STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | + STM32_DMA_CCR_CIRC | STM32_DMA_CCR_TCIE | STM32_DMA_CCR_HTIE +}; + +static const struct dma_option dma_tim_cc2 = { + DMAC_TIM_RX2, (void *)&STM32_TIM_CCRx(TIM_RX2, TIM_RX2_CCR_IDX), STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | STM32_DMA_CCR_CIRC | STM32_DMA_CCR_TCIE | STM32_DMA_CCR_HTIE }; @@ -119,85 +126,118 @@ static volatile uint32_t seq; /* Buffer overflow count */ static uint32_t oflow; -void tim_dma_handler(void) +void tim_rx1_handler(uint32_t stat) +{ + stm32_dma_regs_t *dma = STM32_DMA1_REGS; + int idx = !(stat & STM32_DMA_ISR_HTIF(DMAC_TIM_RX1)); + uint32_t mask = idx ? 0xFF00 : 0x00FF; + uint32_t next = idx ? 0x0001 : 0x0100; + + sample_tstamp[idx] = __hw_clock_source_read(); + sample_seq[idx] = ((seq++ << 3) & 0x0ff8) | (0<<12) /* CC1 */; + if (filled_dma & next) { + oflow++; + sample_seq[idx] |= 0x8000; + } + filled_dma |= mask; + dma->ifcr = STM32_DMA_ISR_ALL(DMAC_TIM_RX1); +} + +void tim_rx2_handler(uint32_t stat) { 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)); - int idx = !(stat & STM32_DMA_ISR_HTIF(DMAC_TIM_RX)); - uint16_t mask = idx ? 0xFF00 : 0x00FF; - int next = idx ? 0x0001 : 0x0100; + int idx = !(stat & STM32_DMA_ISR_HTIF(DMAC_TIM_RX2)); + uint32_t mask = idx ? 0xFF000000 : 0x00FF0000; + uint32_t next = idx ? 0x00010000 : 0x01000000; + idx += 2; sample_tstamp[idx] = __hw_clock_source_read(); - sample_seq[idx] = (seq++ << 3) & 0x0ff8; + sample_seq[idx] = ((seq++ << 3) & 0x0ff8) | (1<<12) /* CC2 */; if (filled_dma & next) { oflow++; sample_seq[idx] |= 0x8000; } filled_dma |= mask; - dma->ifcr |= STM32_DMA_ISR_ALL(DMAC_TIM_RX); + dma->ifcr = STM32_DMA_ISR_ALL(DMAC_TIM_RX2); +} + +void tim_dma_handler(void) +{ + stm32_dma_regs_t *dma = STM32_DMA1_REGS; + uint32_t stat = dma->isr & (STM32_DMA_ISR_HTIF(DMAC_TIM_RX1) + | STM32_DMA_ISR_TCIF(DMAC_TIM_RX1) + | STM32_DMA_ISR_HTIF(DMAC_TIM_RX2) + | STM32_DMA_ISR_TCIF(DMAC_TIM_RX2)); + if (stat & STM32_DMA_ISR_ALL(DMAC_TIM_RX2)) + tim_rx2_handler(stat); + else + tim_rx1_handler(stat); /* 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); -static void sniffer_init(void) +static void rx_timer_init(int tim_id, timer_ctlr_t *tim, int ch_idx, int up_idx) { - /* remap TIM1 CH1/2/3 to DMA channel 6 */ - STM32_SYSCFG_CFGR1 |= 1 << 28; + int bit_idx = 8 * ((ch_idx - 1) % 2); /* --- set counter for RX timing : 2.4Mhz rate, free-running --- */ - __hw_timer_enable_clock(TIM_RX, 1); + __hw_timer_enable_clock(tim_id, 1); /* Timer configuration */ - STM32_TIM_CR1(TIM_RX) = 0x0000; - STM32_TIM_CR2(TIM_RX) = 0x0000; + tim->cr1 = 0x0004; + tim->cr2 = 0x0000; /* Auto-reload value : 8-bit free running counter */ - STM32_TIM_ARR(TIM_RX) = 0xFF; + tim->arr = 0xFF; /* Counter reloading event after 106us */ - STM32_TIM_CCR2(TIM_RX) = 0xFF; + tim->ccr[1] = 0xFF; /* Timer ICx input configuration */ -#if TIM_CCR_IDX == 1 - STM32_TIM_CCMR1(TIM_RX) = TIM_CCR_CS << 0; -#elif TIM_CCR_IDX == 4 - STM32_TIM_CCMR2(TIM_RX) = TIM_CCR_CS << 8; -#else -#error Unsupported RX timer capture input -#endif - STM32_TIM_CCER(TIM_RX) = 0xB << ((TIM_CCR_IDX - 1) * 4); + if (ch_idx <= 2) + tim->ccmr1 = 1 << bit_idx; + else + tim->ccmr2 = 1 << bit_idx; + tim->ccer = 0xB << ((ch_idx - 1) * 4); /* TODO: add input filtering */ - /* configure DMA request on CCRx update */ - STM32_TIM_DIER(TIM_RX) = (1 << (8 + TIM_CCR_IDX)) | (1 << (8+2)); + /* configure DMA request on CCRx update and overflow/update event */ + tim->dier = (1 << (8 + ch_idx)) | (1 << (8 + up_idx)); /* set prescaler to /26 (F=2.4Mhz, T=0.4us) */ - STM32_TIM_PSC(TIM_RX) = RX_CLOCK_DIV; - /* Reload the pre-scaler and reset the counter */ - STM32_TIM_EGR(TIM_RX) = 0x0001 | (1 << TIM_CCR_IDX) /* clear CCRx */; + tim->psc = RX_CLOCK_DIV; + /* Reload the pre-scaler and reset the counter, clear CCRx */ + tim->egr = 0x001F; /* clear update event from reloading */ - STM32_TIM_SR(TIM_RX) = 0; + tim->sr = 0; +} + +static void sniffer_init(void) +{ + /* remap TIM1 CH1/2/3 to DMA channel 6 */ + STM32_SYSCFG_CFGR1 |= 1 << 28; - /* --- DAC configuration for comparator at 550mV --- */ - /* Enable DAC interface clock. */ - STM32_RCC_APB1ENR |= (1 << 29); - /* set voltage Vout=0.550V (Vref = 3.0V) */ - STM32_DAC_DHR12RD = 550 * 4096 / 3000; - /* Start DAC channel 1 */ - STM32_DAC_CR = STM32_DAC_CR_EN1 | STM32_DAC_CR_BOFF1; + /* TIM1 CH1 for CC1 RX */ + rx_timer_init(TIM_RX1, (void *)STM32_TIM_BASE(TIM_RX1), + TIM_RX1_CCR_IDX, 2); + /* TIM3 CH4 for CC2 RX */ + rx_timer_init(TIM_RX2, (void *)STM32_TIM_BASE(TIM_RX2), + TIM_RX2_CCR_IDX, 2); - /* --- COMP2 as comparator for RX vs Vmid = 550mV --- */ /* turn on COMP/SYSCFG */ STM32_RCC_APB2ENR |= 1 << 0; - /* currently in hi-speed mode : INP = PA1 , INM = DAC1 / PA4 / INM4 */ STM32_COMP_CSR = STM32_COMP_CMP1EN | STM32_COMP_CMP1MODE_HSPEED | STM32_COMP_CMP1INSEL_VREF12 | - /*STM32_COMP_CMP1INSEL_INM4 |*/ STM32_COMP_CMP1OUTSEL_TIM1_IC1 | - STM32_COMP_CMP1HYST_HI; + STM32_COMP_CMP1HYST_HI | + STM32_COMP_CMP2EN | STM32_COMP_CMP2MODE_HSPEED | + STM32_COMP_CMP2INSEL_VREF12 | + STM32_COMP_CMP2OUTSEL_TIM2_IC4 | + STM32_COMP_CMP2HYST_HI; ccprintf("Sniffer initialized\n"); - /* start sampling the edges on the CC line using the RX timer */ - dma_start_rx(&dma_tim_option, RX_COUNT, samples); + /* start sampling the edges on the CC lines using the RX timers */ + dma_start_rx(&dma_tim_cc1, RX_COUNT, samples[0]); + dma_start_rx(&dma_tim_cc2, RX_COUNT, samples[1]); task_enable_irq(STM32_IRQ_DMA_CHANNEL_4_7); - /* start RX timer */ - STM32_TIM_CR1(TIM_RX) |= 1; + /* start RX timers on CC1 and CC2 */ + STM32_TIM_CR1(TIM_RX1) |= 1; + STM32_TIM_CR1(TIM_RX2) |= 1; } DECLARE_HOOK(HOOK_INIT, sniffer_init, HOOK_PRIO_DEFAULT); @@ -214,18 +254,19 @@ void sniffer_task(void) /* send the available samples over USB if we have a buffer*/ while (filled_dma && free_usb) { + while (!(filled_dma & (1 << d))) { + d = (d + 1) & 31; + off += EP_PAYLOAD_SIZE; + if (off >= RX_COUNT) + off = 0; + } 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); + samples[d >> 4]+off, 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; } } } |