STM8 timer input trigger latency - Page 1
Forum section: electronics / general

author: HwAoRrDk
author_rank: Super Contributor
timestamp: January 09, 2021, 08:36:00 am
content: This is probably a shot in the dark, as I suspect there's no workaround for this, but I thought I'd ask anyway...I'm using the timer input trigger functionality on an STM8 microcontroller to try and generate a short pulse triggered on every falling edge of an SPI SCK (also coming from the MCU).I have it wired up so that the SCK line is routed back (externally) to the pin for TIM1 CH1. I then have the timer set up with CH1 as an input which is mapped to TI1FP1, and set up to trigger on a falling edge. When it triggers it will reset the timer (i.e. zero the counter). TIM1 CH2 is then set up for PWM output, with a suitable compare value for a pulse length approx. 25% of the SCK clock period.It works, but with one major exception: there is a (relatively) large amount of latency between the falling edge and the reset of the timer counter! (See logic analyser capture below.) There's about 290 ns of latency, which is longer than the damned pulse length I'm trying to generate (250 ns)!Does anyone happen to know of any way to mitigate this delay? Any register flags I might have missed?I have a feeling this latency is because the timer trigger is sampling the input for edge detection, rather than some other lower-latency means, evidenced by the fact the triggering can be configured to have filtering and prescaling (which I'm not using, of course).

author: ogden
author_rank: Super Contributor
timestamp: January 09, 2021, 09:13:39 am
content: Quote from: HwAoRrDk on January 09, 2021, 08:36:00 amFaster clock. Source of delay is fact that input is synchronous, sampled at (timer) clock frequency. This means that worst case latency for input is 1/F_timer.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: January 09, 2021, 11:22:08 am
content: Quote from: ogden on January 09, 2021, 09:13:39 amI'm running the timer at full speed - 16 MHz. No prescaling. So each timer clock cycle is 62.5 ns. If it works like you say, this implies that trigger edge detection takes at least 4-5 cycles.

author: ogden
author_rank: Super Contributor
timestamp: January 09, 2021, 01:10:11 pm
content: When we check datasheet it says input capture takes 2 cycles. Then reset takes one more. So 3 cycles at least. In short: you have to look for other solution. Could you tell more what exactly you are building? Maybe there is other way around..

author: HwAoRrDk
author_rank: Super Contributor
timestamp: January 09, 2021, 02:48:10 pm
content: Quote from: ogden on January 09, 2021, 01:10:11 pmWhere does it say that in the datasheet? I haven't seen it.I did notice now that the datasheet (RM0016) gives comment that there will be some kind of trigger delay, in the example for configuring reset triggering mode: "The delay between the rising edge on TI1 and the actual reset of the counter is due to the resynchronization circuit on TI1 input.". The accompanying diagram (figure 50), seems to imply that there is approximately 2 clock cycles between edge detection and counter reset.BTW, I tried changing the trigger selection in TIM1_SMCR register to TI1F_ED ("TI1 edge detector"), thinking perhaps it would bypass whatever synchronisation/sampling/filtering/whatever and give less latency. For my scenario, technically wouldn't really matter that the timer reset would be triggered on both falling and rising edges of SCK. But, that had not effect.Quote from: ogden on January 09, 2021, 01:10:11 pmI was thinking about how I could drive some NeoPixel/WS2812B/etc. LED strings without using bit-banging. I was intending to try out the technique mikeselectricstuff demonstrated in his recent video (see below), albeit without DMA trickery (as the STM8S doesn't have it). An external 74xx157 multiplexer chip is used to turn the SPI data stream into the variable-pulse-width bitstream. A short pulse synchronised with the falling edges of the SCK are used to drive A/B select input of the multiplexer to give the high period common to both '0' and '1' bits.

author: ogden
author_rank: Super Contributor
timestamp: January 09, 2021, 03:48:09 pm
content: Quote from: HwAoRrDk on January 09, 2021, 02:48:10 pmUps, sorry. It was Reference Manual, RM0031 for instance. Chapter "Timer Overview", table "Timer Characteristics".QuoteRight. Too complex. Why don't encode variable pulse width using bits. Encode one WS2812B bit using three SPI bits. Example: 100 bit combination would mean short pulse and 110 - longer pulse. DMA is useful, but not mandatory for SPI. DMA are used for background transfers to free-up CPU cycles for something else, but you don't do multitasking on tiny MCU's like stm8 anyway. I checked idea using search and did find that some uses 4 bits to encode one:

author: HwAoRrDk
author_rank: Super Contributor
timestamp: January 09, 2021, 04:37:28 pm
content: Quote from: ogden on January 09, 2021, 03:48:09 pmAh, I see it now, yes. Thanks.Quote from: ogden on January 09, 2021, 03:48:09 pmI'm just experimenting with a range of techniques, that being one of them.I already wrote some hybrid C/assembly code using bit-banging of a GPIO port usingNOPs for correct timing. Also some code that encodes each bit as 3 bits and sends via SPI, like you suggested.The technique I conjured for the latter I thought was quite neat: use a 9-byte (72 bits) 'template' buffer pre-filled with a '100100...' bit pattern; each of the 8 bits in each colour channel is then shifted one-by-one into the carry, and the carry value is then copied (usingBCCMinstruction) into the 'middle' bit of a '100' triplet in the appropriate location in the buffer. Only 53 cycles unrolled. The 9 byte buffer is then fired out the SPI using 3x clock speed.Quote from: ogden on January 09, 2021, 03:48:09 pmIndeed. I was just trying to reduce the amount of processing required to produce the bitstream. With external hardware and some timer magic I was hoping to get a minimal-processing solution.