FlexIO logic mode

xxxajk

Well-known member
I have an analog front-end pre-processor that has 4 outputs.
The outputs are pretty stupid, and signals can end up stretched.
The timing is very tight...
I could use the usual 74xxx logic to get what I need, and infact did that.

I could do it in code, but...
The CPU will be busy doing other things (sampling data), and this is time sensitive.
If I do this in code, any interrupt will affect the result.

BUT...
The FlexIO in the i.MX on Teensy 4.1 should technically be able to do what
I require without the additional hardware logic, taking up board space and increasing
the BOM costs. This is fairly easy to do on other chips that have programmable logic via state machines, again, that would increase the BOM.


Problem is there are no examples on how to do the logic mode, they're all
dealing with serial and parallel but not the logic or state machine mode.

What I have is the following signals, with a brief explanation.

Four outputs from the analog frontend:
signal SA "signal has started A"
signal SB "signal has started B"
detect DA "active low detected signal"
detect DB "active low detected signal"

The logic is as such in pseudo code:
Code:
do {
        do { nothing(); } while (SA == SB);
        wait(~100nS); // wait for signals DA and DB to settle, filter out glitches

        while (SA !=SB) {
                if(DA or DB HIGH to LOW (_EDGE_) {
                        output_to_pin(negative_pulse(500-1000nS);
                }
        }
} while(1);

Again, very simple, or it should be, but the processor RM isn't clear on the details...
 
The main limitation of the logic shifter mode is that its inputs and outputs are fixed, depending on which shifter is used:
- Shifter 0 in logic mode uses FlexIO pins 0-3 as input and outputs on pin 4
- Shifter 1 in logic mode uses FlexIO pins 1-4 as input and outputs on pin 5
.. and so on up to Shifter 3, and then:
- Shifter 4 in logic mode uses FlexIO pins 8-11 as input and outputs on pin 12
- Shifter 5 in logic mode uses FlexIO pins 9-12 as input and outputs on pin 13
- etc. up to Shifter 7.

And when you look at how the pins are mapped on the T4.1 there's barely any way to get a usable configuration.

Looking at your function though, I think you may be better off using the state mode instead due to the output being a timed pulse rather than a simple combinatorial output. Logic mode is asynchronous (only the feedback from its output is clocked) whereas with State mode each stage can be fixed lengths of time.
 
I'm fine with fixed, And if it works on one, then it's a simple matter to use the second one...
I'll use which ever mode makes sense.


Here are some scope shots from the raw output as in raw from analog, before it is corrected to levels for 3.3v...
Note that I know there is a DC offset, I already have a post-processing circuit that cleans it up, and can generate whatever I/O levels I need.
For Teensy 4.1, that will be a simple pullup to 3.3v.


Settle time is ~62nS, 100nS is overkill, but makes sure that a glitch doesn't sneak in.
Yellow trace is the "ready" signal, violet is the data signal.
start_to_settle.png



These are the two start signals, one of them doesn't go to the zero trip point, but that's ok, it shouldn't.
startAB.png



Finally a few snapshots of the DATA AB lines, I only need to get the falling edge, since the rising edge is too slow, and doesn't matter.
dataAB_1.png



dataAB_2.png
dataAB_3.png
 
Last edited:
One of the reasons I am interested in the logic mode, is because I can simplify the state machine part, plus the output needs to be steered.
To explain:
There is a "main steering" signal that says data is starting to flow either in or out. The default is OUT, so here's the whole picture for a single input (there will be up to two) and why I am interested in the logic mode.

First there's a main "startup" signal (!MAIN), that activates for BOTH channels. It's a "start internal clocking" signal. These are spat out at a distance between pulses that are separated by each other for 1uS or more. I plan on using SPI in slave mode to automate the capture, in groups of 8 samples, at 4MHz. The clock will be generated from the i.MX chip to save on the BOM.

When !MAIN is active (LOW) data begins to flow from one of two sources of 500-1000nS pulses.When high, I need to stop the SPI DMA data capture, and move it to a new buffer for processing, then process it.

Basically speaking, signal SA == SB indicate which source to choose from. Low means the analog generated source, high is a different pulse stream from other hardware. Both end up being merged, and get sent to MOSI.

The pulses were generated via SR latch driven by an edge detector and a counter. This got me the 500-1000nS pulse out of the SR latch.

I'd like to steer using the built-in logic. Here's how I did it in hardware, so you can understand better what I'm after...

Considering 2 channels:
(SA1 != SB1) = source for channel 1 (I used XOR)
AD1_0 is data from analog channel 1, source 0,
AD1_1 is data from another source for channel 1, source 1
OUTPUT1 is the steered pulse from source 0 or source 1 for channel 1, I used OR and this ends up at MOSI1, DMA moves the byte to DMAMEM.

(SA2 != SB2) = source for channel 2
AD2_0 is data from analog channel 2, source 0,
AD2_1 is data from another source for channel 2, source 1
OUTPUT2 is the steered pulse from source 0 or source 1 for channel 1, I used OR and this ends up at MOSI2, DMA moves the byte to DMAMEM.

When !MAIN goes high, the two DMA buffers get copied to perform work on them.
 
Considering how pins need to be consecutive, I broke them down into useful groups.
Now, if I have the pin->pad->alt assigments right...

Pin groups for Flexio are/should be:
Code:
FlexIO          pin     pad
UNUSABLE
XXX             1       AD_B0_02
XXX             0       AD_B0_03
XXX             24      AD_B0_12
XXX             25      AD_B0_13
XXX             28      EMC_32
XXX             29      EMC_31
XXX             30      EMC_37
XXX             31      EMC_36


FLEXIO1 ALT4
FLEXIO1_D04     2       EMC_04
FLEXIO1_D05     3       EMC_05
FLEXIO1_D06     4       EMC_06
FLEXIO1_D07     33      EMC_07
FLEXIO1_D08     5       EMC_08

FLEXIO2 ALT4
FLEXIO2_D00     10      B0_00
FLEXIO2_D01     12      B0_01
FLEXIO2_D02     11      B0_02
FLEXIO2_D03     13      B0_03

FLEXIO2_D10     6       B0_10
FLEXIO2_D11     9       B0_11
FLEXIO2_D12     32      B0_12

FLEXIO2_D16     8       B1_00
FLEXIO2_D17     7       B1_01
FLEXIO2_D18     36      B1_02
FLEXIO2_D19     37      B1_03


FLEXIO2_D28     35      B1_12
FLEXIO2_D29     34      B1_13

FLEXIO3 ALT9
FLEXIO3_D00     19      AD_B1_00
FLEXIO3_D01     18      AD_B1_01
FLEXIO3_D02     14      AD_B1_02
FLEXIO3_D03     15      AD_B1_03
FLEXIO3_D04     40      AD_B1_04
FLEXIO3_D05     41      AD_B1_05
FLEXIO3_D06     17      AD_B1_06
FLEXIO3_D07     16      AD_B1_07
FLEXIO3_D08     22      AD_B1_08
FLEXIO3_D09     23      AD_B1_09
FLEXIO3_D10     20      AD_B1_10
FLEXIO3_D11     21      AD_B1_11
FLEXIO3_D12     38      AD_B1_12
FLEXIO3_D13     39      AD_B1_13
FLEXIO3_D14     26      AD_B1_14
FLEXIO3_D15     27      AD_B1_15
 
@jmarsh Out of curiosity with flexio, do you happen to know what the P->Q latency is for some simple logic? Is it clocked, or is it fully independent of any of the various SoC clocks?

I'm asking because I can get under 6nS latency if I don't do any glitch filters in the later stages, and totally independent of clocks, on AVR these days.
Basically a modern AVR has some programmable logic that is like a miniature FPGA for ~$1US and I have been thinking of just using that as the solution, which is less than the usual discrete logic by 1-2 orders of magnitude. Just plain logic with 4-6 gates ends up costing more, I'm familiar with the chip as they are used in some of the products I make. I've done some wicked tricks using them. You can even do complex FM/MFM modulation/demodulation with the on-chip logic. I'd even get some extra independent processing power if I need it too.
 
I don't know what the minimum latency is but the output of shifters in logic mode isn't clocked. A FlexIO timer can be used to clock one (out of the total five) of the input signals, which can sometimes come in handy for a feedback signal.
 
I don't know what the minimum latency is but the output of shifters in logic mode isn't clocked. A FlexIO timer can be used to clock one (out of the total five) of the input signals, which can sometimes come in handy for a feedback signal.
So, almost as good as the AVR implementation... interesting.
Deal is that on the AVR, there's extra stuff you can do, such as D-flipflop's in-line with the input to artificially delay a signal, and even a flipflop you can use, all with any kind of clock, external, internal, timers, etc. I just might use it as a helper chip as it does seem to be a good way to do it.

One thing I'd love to see (even though you may think it's useless) is a simple example of logic mode, like an AND gate or something, just so someone can get a head-start on using it, without additional fluff/goals in the code. That way you could connect even a lowly LED for those without a scope, and understand what does things how.

Basic AND/OR/NOT, etc would be a great start for many people to learn how to exploit the ability I'd think.
If you have the time (I DO understand people are busy, me too!) a few examples would be super appreciated, and perhaps it should be included in the examples in Teensyduino. Same goes for the state mode. Any examples/other's code always has a lot of fluff/extra code to weed out for anyone to understand the basics, and is hardly ideal.

Perhaps @Paul has the time now to do such examples considering he's not involved in production any longer.

The other thing that would be nice to have would be a simple thing like DMA to/from GPIO from a buffer, where GPIO is read in on one set of pins, and appears on another.
Doesn't have to be practical to demonstrate how DMA actually works. I know how DMA works at least, but a clean does-nothing-practical example sometimes is the key, and sometimes it's as silly as a button on one or more pins, that lights up LEDs on some other pins, much like Ben Eater does, which is where I usually send people who want to learn the deep guts of how logic works. He's really good at this.
 
Come to think of it I did post some example code for logic mode a while ago: https://forum.pjrc.com/index.php?th...iving-arinc429-with-flexio.76264/#post-353293

Unfortunately something went weird with the original thread and now the forum software can't find it, but the opening post sums up the encoding used by the two input signals.
Fantastic! Thank you so much. I get what the comments say about most of the stuff, mentions "timer" stuff, but I know what the comment actually means.
I'll write some full examples (I'll document it differently/better) and post them here for reference.
What I have seen in other setups are libraries that hide the nasty details, so I'll do it in a similar fashion, and call it a logic library as others do.
Hopefully (after cleanup/etc) @Paul would include them in the next Teensyduino libraries.
 
One other thing about implementing programmable logic: there's a part of the XBAR module called the And-Or-Inverter that can logically combine XBAR inputs. The documentation explicitly mentions GPIOs but I've read it multiple times and can't figure out how to use it with GPIO inputs - all of the connected XBAR inputs are from other modules, not physical pins. There's a diagram on page 3361 of the reference manual showing that it's basically the same config as a PAL with 4 inputs... sure would be nice if there was a way to use it with direct external signals.
 
@jmarsh Doesn't work, documentation is crappy/unhelpful, or I am plain stupid?

Code:
        CCM_CCGR3 |= CCM_CCGR3_FLEXIO2(CCM_CCGR_ON);
        FLEXIO2_CTRL |= FLEXIO_CTRL_FLEXEN;
        IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_10 = FLEXIO2_ALT_MODE;       // D10 Input2
        IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_10 = 0x0001F038U;

        IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_11 = FLEXIO2_ALT_MODE;       // D11 Input3
        IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_11 = 0x0001F038U;

        IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_12 = FLEXIO2_ALT_MODE;       // D12 Output
        IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_12 = 0x0001F038U;

        // "When set, {SSTOP[1:0], SSTART[1:0]} will mask FXIO_D[x+3]...FXIO_D[x] inputs respectively"
        // SSTART MASK I0/I1 1 == mask
        // SSTOP MASK I2/I3 1 == mask
        FLEXIO2_SHIFTCFG4 = FLEXIO_SHIFTCFG_SSTART(0x03U);        // Look only at I2 and I3, I0 and I1 don't exist
        FLEXIO2_SHIFTBUF4 = 0x66666666;                            // Y = I2 XOR I3
        // Logic mode
        /* <HORRIBLE_DOCUMENTATION>
         * "Selects which pin is used by the Shifter input or output. PINSEL=i will select the FXIO_Di pin."
         * </HORRIBLE_DOCUMENTATION>
         * PINSEL is 5bits, 0 to 32 means it can output to any of the FXIO_D pins?? Why would it be "locked" to B0_12?
         */
        
        FLEXIO2_SHIFTCTL4 = FLEXIO_SHIFTCTL_SMOD(7) | FLEXIO_SHIFTCTL_PINCFG(3) | FLEXIO_SHIFTCTL_PINSEL(12);
 
Come to think of it, I wonder if the logic "truth" value is looking at the wrong sequences
 
On a regular CCL LUT, each bit is output from a bit indexed in the "truth" byte, which has 3 inputs.
3 bits 8 locations...
So wouldn't XOR be:

Code:
         *      I I I I I O
         *      N N N N N U
         *      4 3 2 1 0 T
         *  00  0 0 0 0 0 0
         *  01  0 0 0 0 1 0
         *  02  0 0 0 1 0 0
         *  03  0 0 0 1 1 0
         *  04  0 0 1 0 0 1
         *  05  0 0 1 0 1 1
         *  06  0 0 1 1 0 1
         *  07  0 0 1 1 1 1
         *  08  0 1 0 0 0 1
         *  09  0 1 0 0 1 1
         *  0a  0 1 0 1 0 1
         *  0b  0 1 0 1 1 1
         *  0c  0 1 1 0 0 0
         *  0d  0 1 1 0 1 0
         *  0e  0 1 1 1 0 0
         *  0f  0 1 1 1 1 0
         *  10  1 0 0 0 0 0
         *  11  1 0 0 0 1 0
         *  12  1 0 0 1 0 0
         *  13  1 0 0 1 1 0
         *  14  1 0 1 0 0 1
         *  15  1 0 1 0 1 1
         *  16  1 0 1 1 0 1
         *  17  1 0 1 1 1 1
         *  18  1 1 0 0 0 1
         *  19  1 1 0 0 1 1
         *  1a  1 1 0 1 0 1
         *  1b  1 1 0 1 1 1
         *  1c  1 1 1 0 0 0
         *  1d  1 1 1 0 1 0
         *  1e  1 1 1 1 0 0
         *  1f  1 1 1 1 1 0
         * 
         *  0000 1111 1111 0000 0000 1111 1111 0000
         *  0    F    F    0    0    F    F    0
0xFF00FF0 ?
 
Yep! That was the whole problem! Me being stupid :)
For my next trick, I'm going to see if I can force the output to appear on GPIO_B0_00
:)
 
Good news is you can output on a bit higher, but the bad news is the selection doesn't wrap...
E.G. input for shifter 4, can't reference any bits before bit 09! The output is always base IO + 1, which almost makes sense, but on AVR it is legal to loopback output to the input... I suppose a mode exists for this (internal?) but in 01 out 01 should work?
Point of that would be to generate a very high frequency via NOT, of course the same could be done by connecting pins physically...
It's a great test of the speed of the hardware.
 
Full logic example on FLEXIO2. Hopefully it helps people understand how to at least use FlexIO2/shifter4
@jmarsh Whadoyathink?

C:
#include <Arduino.h>


/* Instructions for wiring:
 *  INPUTS A and B
 *  connect button to pin 6 to ground, this is A
 *  connect button to pin 9 to ground, this is B
 *  OUTPUT
 *  connect LED and 470 ohm resistor to pin 32 or connect it to pin 13, this is Y (the result)
 *
 *  Uncomment ONLY ONE of the lines below
 *
 *  See bottom of sketch to see how these patterns are created.
 */

//#define TRUTH_TABLE_BITS  0xF000F000U // AND
//#define TRUTH_TABLE_BITS  0x0FFF0FFFU // NAND
//#define TRUTH_TABLE_BITS  0xFFF0FFF0U // OR
//#define TRUTH_TABLE_BITS  0x000F000FU // NOR
//#define TRUTH_TABLE_BITS  0x0FF00FF0U // XOR
//#define TRUTH_TABLE_BITS  0xF00FF00FU // XNOR

#define FLEXIO2_ALT_MODE 4U

void setup() {
        CCM_CCGR3 |= CCM_CCGR3_FLEXIO2(CCM_CCGR_ON);
        FLEXIO2_CTRL |= FLEXIO_CTRL_FLEXEN;
        IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_10 = FLEXIO2_ALT_MODE;       // D10 Input2
        IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_10 = 0x0001F038U;

        IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_11 = FLEXIO2_ALT_MODE;       // D11 Input3
        IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_11 = 0x0001F038U;

        IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_12 = FLEXIO2_ALT_MODE;       // D12 Output
        IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_12 = 0x0001F038U;

                                                                  // Not actually needed...
        FLEXIO2_SHIFTCFG4 = FLEXIO_SHIFTCFG_SSTART(0x03U);        // Look only at I2 and I3, I0 and I1 don't exist
        FLEXIO2_SHIFTBUF4 = TRUTH_TABLE_BITS;                   
        FLEXIO2_SHIFTCTL4 = FLEXIO_SHIFTCTL_SMOD(7) | FLEXIO_SHIFTCTL_PINCFG(3) | FLEXIO_SHIFTCTL_PINSEL(3);
}

void loop() {
       // Nothing to see here... Everything happens in hardware.
}


        /*
         * Much like AVR CCL LUT...
         *
         *
         *  XOR
         *      I I I I I O
         *      N N N N N U
         *      4 3 2 1 0 T
         *  00  0 0 0 0 0 0
         *  01  0 0 0 0 1 0
         *  02  0 0 0 1 0 0
         *  03  0 0 0 1 1 0
         *  04  0 0 1 0 0 1
         *  05  0 0 1 0 1 1
         *  06  0 0 1 1 0 1
         *  07  0 0 1 1 1 1
         *  08  0 1 0 0 0 1
         *  09  0 1 0 0 1 1
         *  0a  0 1 0 1 0 1
         *  0b  0 1 0 1 1 1
         *  0c  0 1 1 0 0 0
         *  0d  0 1 1 0 1 0
         *  0e  0 1 1 1 0 0
         *  0f  0 1 1 1 1 0
         *  10  1 0 0 0 0 0
         *  11  1 0 0 0 1 0
         *  12  1 0 0 1 0 0
         *  13  1 0 0 1 1 0
         *  14  1 0 1 0 0 1
         *  15  1 0 1 0 1 1
         *  16  1 0 1 1 0 1
         *  17  1 0 1 1 1 1
         *  18  1 1 0 0 0 1
         *  19  1 1 0 0 1 1
         *  1a  1 1 0 1 0 1
         *  1b  1 1 0 1 1 1
         *  1c  1 1 1 0 0 0
         *  1d  1 1 1 0 1 0
         *  1e  1 1 1 1 0 0
         *  1f  1 1 1 1 1 0
         *
         *  0000 1111 1111 0000 0000 1111 1111 0000
         *  0    F    F    0    0    F    F    0
         *
         *  0x0FF00FF0
         *
         *
         *  OR
         *      I I I I I O
         *      N N N N N U
         *      4 3 2 1 0 T
         *  00  0 0 0 0 0 0
         *  01  0 0 0 0 1 0
         *  02  0 0 0 1 0 0
         *  03  0 0 0 1 1 0
         *  04  0 0 1 0 0 1
         *  05  0 0 1 0 1 1
         *  06  0 0 1 1 0 1
         *  07  0 0 1 1 1 1
         *  08  0 1 0 0 0 1
         *  09  0 1 0 0 1 1
         *  0a  0 1 0 1 0 1
         *  0b  0 1 0 1 1 1
         *  0c  0 1 1 0 0 1
         *  0d  0 1 1 0 1 1
         *  0e  0 1 1 1 0 1
         *  0f  0 1 1 1 1 1
         *  10  1 0 0 0 0 0
         *  11  1 0 0 0 1 0
         *  12  1 0 0 1 0 0
         *  13  1 0 0 1 1 0
         *  14  1 0 1 0 0 1
         *  15  1 0 1 0 1 1
         *  16  1 0 1 1 0 1
         *  17  1 0 1 1 1 1
         *  18  1 1 0 0 0 1
         *  19  1 1 0 0 1 1
         *  1a  1 1 0 1 0 1
         *  1b  1 1 0 1 1 1
         *  1c  1 1 1 0 0 1
         *  1d  1 1 1 0 1 1
         *  1e  1 1 1 1 0 1
         *  1f  1 1 1 1 1 1
         *
         *  1111 1111 1111 0000 1111 1111 1111 00000
         *  F    F    F    0    F    F    F     0
         *
         *  0xFFF0FFF0
         *
         *  AND
         *      I I I I I O
         *      N N N N N U
         *      4 3 2 1 0 T
         *  00  0 0 0 0 0 0
         *  01  0 0 0 0 1 0
         *  02  0 0 0 1 0 0
         *  03  0 0 0 1 1 0
         *  04  0 0 1 0 0 0
         *  05  0 0 1 0 1 0
         *  06  0 0 1 1 0 0
         *  07  0 0 1 1 1 0
         *  08  0 1 0 0 0 0
         *  09  0 1 0 0 1 0
         *  0a  0 1 0 1 0 0
         *  0b  0 1 0 1 1 0
         *  0c  0 1 1 0 0 1
         *  0d  0 1 1 0 1 1
         *  0e  0 1 1 1 0 1
         *  0f  0 1 1 1 1 1
         *  10  1 0 0 0 0 0
         *  11  1 0 0 0 1 0
         *  12  1 0 0 1 0 0
         *  13  1 0 0 1 1 0
         *  14  1 0 1 0 0 0
         *  15  1 0 1 0 1 0
         *  16  1 0 1 1 0 0
         *  17  1 0 1 1 1 0
         *  18  1 1 0 0 0 0
         *  19  1 1 0 0 1 0
         *  1a  1 1 0 1 0 0
         *  1b  1 1 0 1 1 0
         *  1c  1 1 1 0 0 1
         *  1d  1 1 1 0 1 1
         *  1e  1 1 1 1 0 1
         *  1f  1 1 1 1 1 1
         *
         *  1111 0000 0000 0000 1111 0000 0000 0000
         *  F    0    0    0    F    0    0    0
         *
         *  0xF000F000
         *
         *
         *
         */
 
Last edited:
Good news is you can output on a bit higher, but the bad news is the selection doesn't wrap...
E.G. input for shifter 4, can't reference any bits before bit 09! The output is always base IO + 1, which almost makes sense, but on AVR it is legal to loopback output to the input... I suppose a mode exists for this (internal?) but in 01 out 01 should work?
Point of that would be to generate a very high frequency via NOT, of course the same could be done by connecting pins physically...
It's a great test of the speed of the hardware.
My understanding is that you can do this. The logic mode has 5 inputs; four of them are fixed while one is selectable, but it's clocked. Using shifter 4 as an example:
IN0 = D8
IN1 = D9
IN2 = D10
IN3 = D11
OUT = D12
IN4 when INSRC is set to 1: the output of shifter 5 (n+1 = shifter 4+1)
IN4 when INSRC is set to 0: any FlexIO pin, selected by PINSEL. Polarity is selected by PINPOL.
However IN4 doesn't get used directly, it gets fed into a 32-bit shift register which is clocked (using the timer specified by TIMSEL) and the value that gets shifted out at each clock is what ends up being fed to the logic LUT. So you can loopback the logic output but there is a configurable delay, depending on the timer and configured shift width.
 
My understanding is that you can do this. The logic mode has 5 inputs; four of them are fixed while one is selectable, but it's clocked. Using shifter 4 as an example:
IN0 = D8
IN1 = D9
IN2 = D10
IN3 = D11
OUT = D12
IN4 when INSRC is set to 1: the output of shifter 5 (n+1 = shifter 4+1)
IN4 when INSRC is set to 0: any FlexIO pin, selected by PINSEL. Polarity is selected by PINPOL.
However IN4 doesn't get used directly, it gets fed into a 32-bit shift register which is clocked (using the timer specified by TIMSEL) and the value that gets shifted out at each clock is what ends up being fed to the logic LUT. So you can loopback the logic output but there is a configurable delay, depending on the timer and configured shift width.

Yeah, the only thing I find disappointing, is as far as hack value is that the 32bits don't roll over, but are lost or masked, so it's as if something useful like that was engineered out of it? 🤔

As for the whole clocking thing, I don't know how much it will impact the performance I am aiming to get. I need to build and test, and I need a few days before I can get to it. As long as the latency isn't too high it's usable. As far as the whole 100ns on the two signals that I need to watch, if there's a clocked delay, that could be useful, or I can just use the delay/deglitch features in the AVR. I still need to see exactly what FlexIO can do as far as if it can be used to route an event (positive/negative pulse, or whatever) to start a one-shot. I can do this easily on AVR, I just tell it to send the output to a timer trigger, and in some cases, where it has to sync with such a signal, resets the clock driving the one-shot timer. Turns out after all of that on the AVR I can easily get all of that done, in parallel totally inside the chip, with externally accessable pins reflecting the states, and done in under 10nS. No software involved other than setup.

I'm always using hardware for unintended uses...

Just to be clear, as an example of what I mean by hack value/unintended uses...
Teensy 3.x (Think the 4.x has one or two, been a while) that had unconnected NVIC interrupts, and you could trigger them via software, so you could trigger an interrupt in software... Intended use? Hell no! BUT SUPER USEFUL if you need to simulate a sort-of controlled re-entrant ISR like you get on less sophisticated MCU (AVR) to handle fast interrupt responses to an ISR that needs a fast ISR, but allowing you to hand a less important event in another lower priority pseudo thread or queue for less time critical processing. This is a trick I use in my USB host stack, to hand out tasks with priority, without having to write a an actual task manager and put up with the inherent delays in it. Hardware is always going to be faster than software. NVIC actually makes this super easy to deal with, v.s. AVR, where you need to be super careful to not run out of heap due to stack smashing. NVIC abuse is one of my many "repurposing" of SoC features to do something totally different. Making SPI do tricks is yet another...
 
Technically with the T4 you don't need the NVIC for that, the CPU has the PendSV interrupt mechanism built into it... but the Teensy core code uses it for EventResponder, so unless you know for sure it won't be needed the interrupt has to be "shared".
 
Technically with the T4 you don't need the NVIC for that, the CPU has the PendSV interrupt mechanism built into it... but the Teensy core code uses it for EventResponder, so unless you know for sure it won't be needed the interrupt has to be "shared".
...or stolen from unused section, which is what I do on MIPS with NVIC...
 
Back
Top