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

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

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

1,130件の閲覧回数
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 件の賞賛
7 返答(返信)

1,074件の閲覧回数
madisonchou
Contributor III

Typo in comments in previous post:

Should be "QTMR4 Timer2"

Should be "QTMR3 Timer0"

Should be "XBAR2_IN18"

0 件の賞賛

1,074件の閲覧回数
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 件の賞賛

1,128件の閲覧回数
madisonchou
Contributor III

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

madisonchou_0-1613446661695.png

 

0 件の賞賛

1,117件の閲覧回数
madisonchou
Contributor III

Diagram not quite right.   Here is:

madisonchou_0-1613488329038.png

 

0 件の賞賛

1,110件の閲覧回数
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

 

1,094件の閲覧回数
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 件の賞賛

1,088件の閲覧回数
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 件の賞賛