If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

FreqMeasureMulti on the T4

OK. So I have had look into porting FreqMeasureMulti for the t4 and it is all very confusing. Can someone give me some pointers please?

I am not sure which timer to use: flexpwm or GPT? Both can be triggered by waveform features. From the datasheet, flexpwm4 is attached to pins 22 (AD_B1_08 as used by FreqMeasure), 23 (AD_B1_09) and 3 (EMC_05). That gives 3 readings only. GPT1 is not attached to any pins and GPT2 is only attached to pin 15 (AD_B1_03). Can 1 pin take multiple readings? Or can a variety of timers be used across multiple pins?

My goal is to measure 4 square-wave frequencies in the range 1KHz to 100KHz, up to 16 times each per second. I would prefer to use FreqMeasure if possible as FreqCount probably won't provide enough resolution at this sample rate. Might the t4 push FreqMeasure up that high?

Excellent work. The library works very well. I can take readings from 4 sensors producing square wave frequencies around 50KHz in less than 1 microsecond! Using pulseIn() or digitalRead() takes much longer - over 100 milliseconds.

I have been trying to get this to work with TeensyTimerTools as I want to take readings every so often. However I am getting strange results such as 0 or inf or 65535. Could this be conflicting interrupts or is the buffer overflowing?

I am not a full expert on a lot of this. I started off from what Paul did for one pin in the other library and generalized it some to work with the other pins. Note in all cases like it, it is best to take a look at the actual code.

So a lot of main setup stuff was done by Paul. But I did learn a lot while doing the converting.

The code uses the eFlexPWM (chapter 54 of the IMXRT1060RM) Each of these pins that are supported here are pins that can be Input pins one of the channels of the 4 submodules of the 4 modules)

For example T4 pin 0 is: FlexPWM1_1_X Module 1 sub module 1 X channel. If you look at the library source file FreqMeasureMultiIMXRT.cpp you will see a table with all of the pins and the stuff that makes them work...

Probably has more details in it than you are interested in, but includes things like: it is FlexPWM4 so first thing is pointer to that objects hardware registers. The (4,2) is encoding that it is FlexPWM 2 sub module 2, the 1 is saying that it is the A channel. The 1 | 0x10 says we need to change this pins MODE to this to be a flexPWM input pin. Next is systems ISR number for this, the next is a pointer to the ISR function that will be called, and the next two are saying that I might have to tell the system that for this actual function MAP the SELECT INPUT, using the mentioned register address to the value 0 in this case...

So the begin method uses all of that above data, to first initialize the timer for the module/submodule . Note: there can be a complication that more than one pin might use the same timer module/sub-module as again three channels (A, B, X), The code tries to handle it by link listing the objects to each other and handle all of them in same ISR.

But again the code than changes the IO pin mentioned into the MUX value specified plus if needed set the pin SELECT_INPUT PIN as to route that signal from that pin.

Note: For each of these channels, the Module/SubModule can capture two time of the two possible edges. But in the Falling or rising case it only sets up to capture one of these in the first of the two.
It then tells the module to interrupt us on that channel capture as well as overflows of the timer. The ISR when triggered sees if there was an overlow and if so updates a count in the object.

And it detects if there was an edge captured. If so it calculates the actual timing and saves it out on the output queue, which the client can then get...

New FreqMeasureMulti

Hi KurtE (and everyone else)

Unfortunately, I was right about FreqMeasureMulti being a cycle counter and not a cycle measurer.

So, I had a go at writing my own! It doesn't have the broad functionality of the original, but it does accurately measure the time taken for 1 period to pass and it does what I need it to. Perhaps it can be expanded or the method integrated into the original?

Anyway, see what you think. You will need to provide a frequency source for testing.

FreqMeasureMulti_X

Attached is the final version of FreqMeasureMulti_X. The version attached to message #12 above is now redundant.

This new version measures the period of 4 digital signals at a certain, specified rate. This frees up time to do other stuff inbetween readings, such as saving the data to an SD card.

It uses the PIT timer to trigger an isr where the flexPWM timer captures the time between 2 consecutive rising edges. The flexPWM timer ticks over at 6.66667 nanoseconds, so resolution is excellent.

The time taken from the start of the isr to the end of copying the volatile buffer to a non-volatile buffer is about 1.2 microseconds. In theory read rates of more than 800,000 per second should be possible! I have no way of measuring this though.

Also, my testing was carried out on a ~40KHz signal. I don't know what the signal frequency limit might be (less than 150MHz presumably).