Using QTMR to generate a pulse on the output upon toggles on the input

cancel
Showing results for 
Search instead for 
Did you mean: 

Using QTMR to generate a pulse on the output upon toggles on the input

528 Views
madisonchou
Contributor III

Hi,

This seems a simple thing to make.  But I've tried many approaches and have not been successful.   If you have done it, it will be greatly appreciated if you can share.   It doesn't have to be QTMR.

Interrupt-driven won't work for me because I am dealing with input in >200KHz.

I am looking for a way without much of intervention of the processor.

Input to QTMR flips states (hi to lo, lo to hi) in various interval.

The output that I am trying to construct is a short pulse, say... 0.5 uSec wide.

 

0 Kudos
7 Replies

472 Views
madisonchou
Contributor III

Typo in comments in previous post:

Should be "QTMR4 Timer2"

Should be "QTMR3 Timer0"

Should be "XBAR2_IN18"

0 Kudos

472 Views
madisonchou
Contributor III

Got a solution.  It is kind of twisted:

  • Generate a delay line from input.
  • Use AOI for exclusive-OR function.
  • Heavy uses of XBAR.

Assuming the signal I am dealing with, a variable width of square waves, is generated by QTMR4 Timer2.  Fold it back into QTMR3 Timer0 using XBAR1:

// QTMR3 Timer0 to receive output from QTMR4 Timer3...
IOMUXC_GPR->GPR6 |= IOMUXC_GPR_GPR6_QTIMER3_TRM0_INPUT_SEL_MASK; // Sel XBAR as QTMR3's Timer3 input
XBARA1->SEL47 |= XBARA_SEL47_SEL94( 38 );                        // XBAR1_IN38 (QTMR4 Timer2) to QTMR3 Timer0

Make QTMR3 Time0 a "follower" of the variable width square wave, i.e. a delay line.  The delay is provided by QTMR's filter.

// Configure QTMR3 timer3 as a delay line...
TMR3->CHANNEL[ 0 ].CTRL = TMR_CTRL_PCS( 0 ) | TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE( 3 ); // Toggle output
TMR3->CHANNEL[ 0 ].FILT = TMR_FILT_FILT_CNT( 3 ) | TMR_FILT_FILT_PER( 10 ); // Latency = (3+3)*10+2=62 clks @ 150MHz IPG, i.e. 413nS (Actual ~470nS)
TMR3->CHANNEL[ 0 ].COMP1 = TMR_COMP1_COMPARISON_1( 0 ); // COMP1 == 0 for toggling on every input edge
TMR3->CHANNEL[ 0 ].SCTRL |= TMR_SCTRL_OEN_MASK;         // Output OFLAG
TMR3->CHANNEL[ 0 ].CSCTRL = TMR_CSCTRL_DBG_EN( 1 );     // Hold counter when debug
TMR3->CHANNEL[ 0 ].CTRL |= TMR_CTRL_CM( 2 );            // Count both edges of input

 

Bring both QTMR4 Timer2's and QTMR3 Timer0's output into XBAR2:

// For Exclusive-OR gate in AOI1 function, route QTMR3 Timer0's output to XBAR2's input and to AOI's input
XBARB2->SEL0 = XBARB_SEL0_SEL0( 18 ); // XBAR2_IN19 (QTMR4 Timer2) to XBAR2_OUT00 (AOI1_IN00)
XBARB2->SEL0 |= XBARB_SEL0_SEL1( 12 ); // XBAR2_IN12 (QTMR3 Timer0) to XBAR2_OUT01 (AOI1_IN01)

Create exclusive-OR logic:

// Configure AOI1's Event0 as Exclusive-OR gate
AOI1->BFCRT[ 0 ].BFCRT01 = 0x6f9f;
AOI1->BFCRT[ 0 ].BFCRT23 = 0x0000;

Finally, output the result (a 0.5uS pulses synchronized to input edges) to pin GPIO_SD_B0_03 (IOMUX_XBAR_INOUT07):

// Route AOI1 Event0 (AOI1_OUT0, i.e. XBAR1_IN72) to GPIO_SD_B0_03 pin (IOMUX_XBAR_INOUT07)
IOMUXC->SW_MUX_CTL_PAD[ kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_03 ] = IOMUXC_SW_MUX_CTL_PAD_MUX_MODE( 3 ); // ALT3 = IOMUX_XBAR_INOUT07
IOMUXC_GPR->GPR6 |= IOMUXC_GPR_GPR6_IOMUXC_XBAR_DIR_SEL_7_MASK;  // IOMUX_XBAR_INOUT07 as output
XBARA1->SEL3 |= XBARA_SEL3_SEL7( 72 );   // AOI1_OUT0 (XBAR1_IN72) to XBAR1_OUT7 (GPIO_SD_B0_03)

 

 

0 Kudos

526 Views
madisonchou
Contributor III

BTW, the function can be easily done with simple external circuit.

madisonchou_0-1613446661695.png

 

0 Kudos

515 Views
madisonchou
Contributor III

Diagram not quite right.   Here is:

madisonchou_0-1613488329038.png

 

0 Kudos

508 Views
mjbcswitzerland
Specialist V

Hi

I would suggest looking at using a timer that can be triggered to start, that can set a high output at count value 1 and a low output at count value 2, and then stops.

Trigger it to start using an XBAR_IN pin.

XBAR discribed here:
https://youtu.be/zNWIG-O7ZW0

Regards

Mark

 

492 Views
madisonchou
Contributor III

Yes, I've connected my "variable-interval signal input" to QTMR via XBAR.  Also, I can start timer to set output to high.  But subsequently to set the output to low proved to be difficult.

I even tried DMA to set an GPIO to high and link to 2nd DMA to start a timer.   Upon expiration of the timer, it triggers 3rd DMA to set the GPIO to low.   But the QTMR timer is not built for generating DMA event that I was hoping for.

0 Kudos

486 Views
mjbcswitzerland
Specialist V

Hi

I would try with the FlexPWM module since it is intended more for what you need to do.

Regards

Mark

 

0 Kudos