Ok STM32F Wizards, what is IndirectTI for Input Capture? - Page 1
Forum section: electronics / general

author: richardman
author_rank: Frequent Contributor
timestamp: June 17, 2016, 08:13:16 am
content: I am writing JumpStart API for timer input capture on the STM32F4xx. Seems fairly straight forward: a timer can do input capture from any of the 4 channels. Each channel can be mapped to some GPIO pin Alternate Function. Tedious, but no big deal.Channel 1 and Channel 2 are selected in the CCMR1 register, and Channel 3 and 4 are in the CCMR2 register. So far so good. Haven't read far enough to see what happens if you enable more than one channel, but that's not the question.The question is, for channel 1, CC1S bit, you can map it as output, or as TI1 (DirectTI) or TI2 (IndirectTI), ditto with CC2S for channel 2 and the other 2 channels as well. If I understand it correctly, this means you can useGPIO TIM CH1 pin for timer channel 1 (DirectTI), or just for sh*t and grins, set it as timer channel 2 (IndirectTI).GPIO TIM CH2 pin for timer channel 2, or just for sh*t and grins, set it as timer channel 1.and ditto for channel 3 and 4.Do I understand this correctly? If not, please correct me. If so,... then it begs the question... why?Thanks

author: Brutte
author_rank: Frequent Contributor
timestamp: June 17, 2016, 09:39:24 am
content: The advanced timer you are referring to hasfourindependent capturecompare channels. Or rather CaptureOrCompare channels. Depending on CCnS bit (n={1:4}) you set the channel as either capture or compare.These four channels are independent and identical.Allbutthe 1-st one, which has additional feature which in capture mode can trigger a capture on three xored inputs (T1=CH1^CH2^CH3). So if you wire three hal sensors to three IOs then it would capture to CCR1 on any input change (useful for BLDC in closed loop as you do not need external XOR or hogging three capture channels).Thus, for all but first you just pick: "capture or compare", but for channel 1 this is not enough as in capture you have to decide if you want it only from CH1 pin or you want it exored (CH1, CH2, CH3 ).QuoteNo, only channel 1 has the flexibility. You cannot capture to CCR2 with CH1 pin.

author: richardman
author_rank: Frequent Contributor
timestamp: June 17, 2016, 09:56:46 am
content: I understand the XOR CH1..3 for Hall Sensor part, but this is different. Again, this is the F4xx and the description are the same the ADV Timers TIM1/TIM8 and the other timers. The reference manual RM0385 says:Bits 9:8 CC2S[1:0]: Capture/Compare 2 selection00: CC2 channel is configured as output01: CC2 channel is configured as input, IC2 is mapped on TI210: CC2 channel is configured as input, IC2 is mapped on TI111: CC2 channel is configured as input, IC2 is mapped on TRC. This mode is working only if an internal trigger input is selected through the TS bit (TIMx_SMCR register)Bits 1:0 CC1S: Capture/Compare 1 selection00: CC1 channel is configured as output.01: CC1 channel is configured as input, IC1 is mapped on TI1.10: CC1 channel is configured as input, IC1 is mapped on TI2.11: CC1 channel is configured as input, IC1 is mapped on TRC. This mode is working only if an internal trigger input is selected through TS bit (TIMx_SMCR register)and similarly for CC3S and CC4S

author: Brutte
author_rank: Frequent Contributor
timestamp: June 17, 2016, 10:18:03 am
content: Ok, now I think I understand what you mean. The question is not about XOR but about edge filtering redirection.-for channel 1 (TI1) this can go to CCR1 or CCR2-for channel 2 (TI2) this can go to CCR2 or CCR1If four channels were identical, what would that be useful for (apart from easing IO layout)?Well, four channels arenotidentical (because of XOR). Thus redirecting feature adds flexibility.

author: richardman
author_rank: Frequent Contributor
timestamp: June 17, 2016, 10:37:07 am
content: Thanks, so normally (DirectTI), channel 1 uses TI1 as input trigger and the result goes to CCR1. Likewise for Channel 2 - 4.However, for flexibility, channel 1 may use TI2 and get the triggered value from CCR2.As I have not used this sort of advanced feature (mainly a software person), without a concrete example, it's still not clear to me why one may want to do that, but probably for good reasons.But I presume the default cases are the most useful ones.Thanks again.Quote from: Brutte on June 17, 2016, 10:18:03 am

author: Brutte
author_rank: Frequent Contributor
timestamp: June 17, 2016, 11:50:41 am
content: Quote from: richardman on June 17, 2016, 10:37:07 amIndeed the straight through seems like reset-default, most obvious choice.As an example of the feature being used, consider you can feed TI1 rising edge to IC1(and then to CCR1) and simultaneously feed same TI1 but falling edge to IC2 (and then to CCR2) as edge polarities of TI1FP1 and TI1FP2 are configurable. This way you can capture timing of both edges with one IO pin. For similar functionality without the redirection you'd need two IO pins (or you'd have to trigger on both edges and readout CCR1 twice as often and remember which was for rising and which was for falling edge, complicating software).Thus, the feature has its place

author: richardman
author_rank: Frequent Contributor
timestamp: June 17, 2016, 06:41:35 pm
content: Oh HEY! That's exactly why the customer was asking to do, and my initial thought is to detect one edge, then when the interrupt hits, switch the check, but as you said, this IndrectTI feature is exactly what they/I need!Now to wrap it up in a function name that makes senseThanks!Quote from: Brutte on June 17, 2016, 11:50:41 am

author: richardman
author_rank: Frequent Contributor
timestamp: June 19, 2016, 08:42:45 am
content: FWIW, here's the signature I came up with for the basic usage:int JSAPI_TIMER::InputCapture(int chan_no, unsigned ICxF, unsigned ICxPSC, enum edge edgetype, unsigned *captured_value);The filter values and prescalar are just too specific that I feel it's best for the user to go ahead and use the values from the datasheet. This should work for all Advanced and General Purpose timers (basic timers don't have input capture).I was stuck for a short while trying to figure out how to test it, until I get the bright idea that I can just generate a pulse programmatically on another GPIO and capture that. :-) Two lines compute a pulse width:unsigned start, stop;if (timer1.InputCapture(1, 0, 0, RISING_EDGE, &start) < 0) printf("bad val\n");if (timer1.InputCapture(1, 0, 0, FALLING_EDGE, &stop) < 0) printf("bad val2\n");;printf("pulse width %u-%u = %u\n", stop, start, stop-start);Yes, I know the subtract does not handle overflow. Currently, I have not added interrupt yet, will do that tomorrow :-)Brutte, thanks again for your help!

author: Brutte
author_rank: Frequent Contributor
timestamp: June 20, 2016, 08:11:43 am
content: Quote from: richardman on June 19, 2016, 08:42:45 amJust use other timer as PWM source.Also, you should run both PWM source and PWM sink with synchronized clock. I'd suggest tweaking DBGMCU registers to freeze both timers and synchronize with HCLK. This way both would halt when the core is being halted. That eases the debugging greatly.