Does TyCommander handle FTDI? Or am I doing something wrong?

I spent the past couple of hours marking up code and getting an assessment of what I need to do. Have a couple of questions on various topics.

1. Whats the max duration of IntervalTimer? Does it pick the appropriate timer according to the delay?
2. For prioritizing timers, is it possible to give priorities that are not multiples of 16? Will a 17 interrupt an 18? Or do they map to a lower priority? (32)?
3. What's the advantage of using IntervalTimer vs TeensyTimerTool?

I have 3 timers in my system.
1. A periodic 20 ms timer for RPM calculation
2. A one shot timer to generate a 4us stepper pulse. Currently turned off in SW. Could just have the one shot signal routed to a pin...
3. A display blanking timer that blanks 2 revolutions of the spindle (during sync time) 1 rev = 300ms @ 200 RPM. Min speed is 100 RPM --> 1 rev = 600 ms.
Can I do all of these using IntervalTimer?

How does one handle the 32 bit rollover for QuadEncoder? Does the difference register work correctly? Say the spindle is going in reverse and each count is decrementing. At roll over what happens to the difference? What happens to the count? Count is max value? Is the difference still -1? This confuses me.
 
Differences are correct if using unsigned or 2's complement signed values (i.e. always these days since 1's complement isn't used on modern hardware).
 
1. Whats the max duration of IntervalTimer? Does it pick the appropriate timer according to the delay?
Not sure what is the max. IntervalTimer uses the PIT (periodic interrupt timer), of which there are 4, all with the same capability. You don't have to decide which one you are using. When you define one, it uses the first one, then the next, up to 4.
2. For prioritizing timers, is it possible to give priorities that are not multiples of 16? Will a 17 interrupt an 18? Or do they map to a lower priority? (32)?
Yes, you can use any priority from 0 (highest) to 255 (lowest). 0 will supersede 1 will supersede 2, etc.
3. What's the advantage of using IntervalTimer vs TeensyTimerTool?
TeensyTimerTool supports not only PIT, but also GPT and other timers. IIRC, there is a syntax to let you specify which type of timer you want to use, and also a "generic" syntax, where it will choose a timer for you.
I have 3 timers in my system.
1. A periodic 20 ms timer for RPM calculation
2. A one shot timer to generate a 4us stepper pulse. Currently turned off in SW. Could just have the one shot signal routed to a pin...
3. A display blanking timer that blanks 2 revolutions of the spindle (during sync time) 1 rev = 300ms @ 200 RPM. Min speed is 100 RPM --> 1 rev = 600 ms.
Can I do all of these using IntervalTimer?
I don't see why not.
How does one handle the 32 bit rollover for QuadEncoder? Does the difference register work correctly? Say the spindle is going in reverse and each count is decrementing. At roll over what happens to the difference? What happens to the count? Count is max value? Is the difference still -1? This confuses me.
You have to say more about what you want to do. For example, in your system, does position start at 0 and only go up from there, and when it comes back down, will it always be >= 0? If so, you can define your position variable as uint32_t, and it can only roll over in the positive direction. If your position starts at 0 and mostly goes up, but also go down and go beyond 0, then your position variables should be int32_t. Either way, you can determine the difference between two positions (position0 and position1) with the following statement:

int32_t difference = position1 - position0;

This will provide the correct +/- (signed) difference as long as the actual change in position between position0 and position1 is in the range of a 32-bit signed integer, which is -(2^31) to +(2^31)-1. It works correctly whether position0 and position1 are int32_t or uint32_t, per the magic of 2's-complement integer math, as per @MarkT.

For example:

If p0 and p1 are type int32_t, with p0=1 and p1=-1, then (int32_t)(p1-p0) = -1-1 = -2.

If p0 and p1 are type uint32_t, with p0=1 and p1=0xFFFFFFFF, then (int32)t)(p1-p0) = 0xFFFFFFFE, which is -2.
 
priority from 0 (highest) to 255 (lowest). 0 will supersede 1 will supersede 2
Pri can be specified 0,1,2,3 :: But they are applied equally in groups of 8 being the same in each group:: 0-7, 8-15, 16-23, ...

As @MarkT noted in p#227 : Use uint32_t [ like in the proof of concept code ] and the difference will work for 32 bit rollover with Millis, Micros, ARM_DWT_CYCCNT, or any other ever-increasing count, UNTIL THEY WRAP past the original 'start' lesser value.
 
Not sure what is the max. IntervalTimer uses the PIT (periodic interrupt timer), of which there are 4, all with the same capability. You don't have to decide which one you are using. When you define one, it uses the first one, then the next, up to 4.

Yes, you can use any priority from 0 (highest) to 255 (lowest). 0 will supersede 1 will supersede 2, etc.
Can I have PIT timers with different priorities? PIT1>PIT2?
TeensyTimerTool supports not only PIT, but also GPT and other timers. IIRC, there is a syntax to let you specify which type of timer you want to use, and also a "generic" syntax, where it will choose a timer for you.

I don't see why not.

You have to say more about what you want to do.
I want to ensure my Bresenham algorithm works for both positive and negative directions. I can post that in a following note. The lathe can run either CW or CCW depending on what operation, or what handed thread is cut, RH or LH. It could be that the count rolls over from 0 to uint32_max, or it rolls under, depending on which way the lathe is rotating CW or CCW. As I understand it, the HW counter is uint32.
For example, in your system, does position start at 0 and only go up from there, and when it comes back down, will it always be >= 0? If so, you can define your position variable as uint32_t, and it can only roll over in the positive direction. If your position starts at 0 and mostly goes up, but also go down and go beyond 0, then your position variables should be int32_t. Either way, you can determine the difference between two positions (position0 and position1) with the following statement:

int32_t difference = position1 - position0;

This will provide the correct +/- (signed) difference as long as the actual change in position between position0 and position1 is in the range of a 32-bit signed integer, which is -(2^31) to +(2^31)-1. It works correctly whether position0 and position1 are int32_t or uint32_t, per the magic of 2's-complement integer math, as per @MarkT.

For example:

If p0 and p1 are type int32_t, with p0=1 and p1=-1, then (int32_t)(p1-p0) = -1-1 = -2.

If p0 and p1 are type uint32_t, with p0=1 and p1=0xFFFFFFFF, then (int32)t)(p1-p0) = 0xFFFFFFFE, which is -2.
 
Pri can be specified 0,1,2,3 :: But they are applied equally in groups of 8 being the same in each group:: 0-7, 8-15, 16-23, ...
So does this means a priority 16 is handled the same as 17? Or if 16 comes along it will interrupt 17?
As @MarkT noted in p#227 : Use uint32_t [ like in the proof of concept code ] and the difference will work for 32 bit rollover with Millis, Micros, ARM_DWT_CYCCNT, or any other ever-increasing count, UNTIL THEY WRAP past the original 'start' lesser value.
UNTIL THEY WRAP... then what happens? I need that to work as well. That's the crux of the problem. That could happen if the machine is left on for 8 hours. I want to avoid bad stuff, should that WRAP occurs. 2**32 isn't that big of a number.

Edit: I just need for the system to behave gracefully if that occurs.
 
So does this means a priority 16 is handled the same as 17? Or if 16 comes along it will interrupt 17?
I defer to defragster on this one. He says you can specify values from 0-255, but groups of 8 are effectively "equal", so that gives you 16 nestable levels: 0-7, 8-15, 15-23, etc. So, if you want to know for sure that interrupt A will take priority over interrupt B, then they should be in different groups of 8. I think it would really help if you made a list of your interrupt sources and their priorities, both for your own review and for others. We just don't know enough about what you're doing to answer some of these questions.
UNTIL THEY WRAP... then what happens? I need that to work as well. That's the crux of the problem. That could happen if the machine is left on for 8 hours. I want to avoid bad stuff, should that WRAP occurs. 2**32 isn't that big of a number.
With 4096 edges per rev, you can count 524,488 revolutions before you get a rollover, if you treat the count as signed. That is almost 22 hours at 400 rpm, so 8 hours is not a problem at all, and if you treat it as unsigned, you get 44 hours. If that somehow does occur, you can count rollovers and either keep it as a separate value, or use it to synthesize a 64-bit position. It doesn't seem like that is likely to ever happen, certainly not while you are cutting metal, but whatever you are doing now with TeensyTimerTool, you can also do with QuadEncoder.
 
I defer to defragster on this one. He says you can specify values from 0-255, but groups of 8 are effectively "equal", so that gives you 16 nestable levels: 0-7, 8-15, 15-23, etc. So, if you want to know for sure that interrupt A will take priority over interrupt B, then they should be in different groups of 8. I think it would really help if you made a list of your interrupt sources and their priorities, both for your own review and for others. We just don't know enough about what you're doing to answer some of these questions.

With 4096 edges per rev, you can count 524,488 revolutions before you get a rollover, if you treat the count as signed. That is almost 22 hours at 400 rpm, so 8 hours is not a problem at all, and if you treat it as unsigned, you get 44 hours. If that somehow does occur, you can count rollovers and either keep it as a separate value, or use it to synthesize a 64-bit position. It doesn't seem like that is likely to ever happen, certainly not while you are cutting metal, but whatever you are doing now with TeensyTimerTool, you can also do with QuadEncoder.
Not so fast on the revolutions... The lathe can operate up to 2200 RPM, this is needed for small diameter pieces, to get the surface feet per minute up to the recommended cutting rate. So for feeding (not threading) the WRAP will occur in 7.94 hours. I need a way to handle this event. Other lathes may have the ability to go faster. Handling this WRAP and not causing machine destruction or damage is a priority for me. I take machine safety seriously, especially if I am the operator, or I sold this board or software to someone.

There aren't that many interrupt sources.
1. Encoder priority 32
2. t1 TMR4 priority 48 one shot for step pulse
3. t2 PIT priority 64 20ms periodic timer to measure RPM
4. t4 PIT priority 64 2 revolution blanking timer (100's of ms)
5. Serial5 priority 96

Hmm, maybe I ought to change t4 to GPT, t2 and t4 have the same priority. t2 is pretty important, more so than t4. I'd like to set t4 priority to 80. Is GPT available in IntervalTimer?

I thought I read that the interrupt priorities stepped by 16, not by 8. Stepping by 8 is a lot nicer than 16. This post by @Paul says they are stepped by 16. https://forum.pjrc.com/index.php?th...rupt-priority-on-given-pins.59828/post-231315
 
Last edited:
So for feeding (not threading) the WRAP will occur in 7.94 hours. I need a way to handle this event.
In short, you need to detect rollover and handle it by synthesizing a 64-bit edge count, with the upper 32-bits increment or decrementing on each rollover event. Do you do that now?
 
In short, you need to detect rollover and handle it by synthesizing a 64-bit edge count, with the upper 32-bits increment or decrementing on each rollover event. Do you do that now?
I didn't need to with the SW encoder. Luni had extended it to 64 bits for EncoderTool. The 64bit rollover is so far out, I didn't need to deal with it. (3.89 million years @ 2200 RPM!)
Code:
In [19]: 60/(2200*4096) *2**64 /3600/24/365.25
Out[19]: 3892103.4674003003
But the HW encoder is only 32 bits.
 
Okay. Best to stay with EncoderTool until you know what’s wrong with your code. Add the logging and measure the max execution time of your ISR. That is likely to show a problem. QuadEncoder would avoid missing edges, but it really won’t solve your problems because your design depends on executing your ELS logic on every edge.
 
Forgot to hit POST on this hours ago ... would have crossposted with @joepasquariello back then ...
Can add this: You can see in the @luni code how he accomplishes 64 bit quite nicely to track the wrapping. But that code if it works would be tested to work and as noted use that code if you can.

16 comes along it will interrupt 17?
No, "the same in each group"

Edit: I just need for the system to behave gracefully if that occurs.
You must choose and monitor usage to assure it can never happen, or recognize it when it does when possible/needed.

example: ARM_DWT_CYCCNT can be any running value 0 to 2^32-1.
put any value in START=ARM_DWT_CYCCNT and all is well to get the difference "ARM_DWT_CYCCNT - START" for any count of CPU cycles (600M/sec), as long as it doesn't run long enough for ARM_DWT_CYCCNT to EQUAL (it would be ZERO) or WRAP past that START as the difference would then start : 0,1,2,3, ...
 
Okay. Best to stay with EncoderTool until you know what’s wrong with your code. Add the logging and measure the max execution time of your ISR. That is likely to show a problem. QuadEncoder would avoid missing edges, but it really won’t solve your problems because your design depends on executing your ELS logic on every edge.
Short answer: Something is taking too long. Now to find it.

Think I have a better handle on logging now, with the structs. May go back to my original idea of attempting to profile parts of the code. I can time each function in cycles using ARM_DWT_CYCCNT (modifying for rollover later) and enter the line number and file number of the code. It's primitive, but I think I can get an assessment of things.
 
How is the project going? We have not heard anything for a month now. Have you fixed your problem? If so what was the problem that was causing all the trouble?
 
How is the project going? We have not heard anything for a month now. Have you fixed your problem? If so what was the problem that was causing all the trouble?
Been stalled. Vacations, travel, grandchildren, life, etc. Have made no progress on this. Need to get back to it.
The development work isn't easy for me. (I'm out of practice.) My development area is a mess and it's not trivial to straighten it out.

Thanks for inquiring! It gives me some encouragement.

Hope to be able to attack the literal desktop this week, so it will be easier to code and test.
 
Back
Top