This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Timer_D and single cycle code execution for time-of-flight measurement

Other Parts Discussed in Thread: MSP430F5172

Hello everyone,

First of all, thanks for providing such an informative and helpful forum. E2E and it's contributors are a fantastic reasource. Please bear with me as I am an analog guy, just (3 weeks) new to uC programming with C and the MSP430 launchpad, and very much enjoying myself.

I would like explore the feasibility of using an MSP430F5172 (with the high resolution Timer_D module) to control and measure pulse trains for a compact ultrasonic time-of-flight flowmeter. For the flowmeter measurement principle to work properly, I need to generate acoustic signals and determine their transit time down to +/-10ns.

My time crictical routine is:
1) Write a sequence of deterministic pulses to 4 separate pins/channels to excite the transmit transducer
2) Idle for yet-to-be-determined amount of time (~60us after first excite pulse)
3) Start Timer_D
4) Capture 2 rising edges and 2 falling edges during the middle of an incoming, signal-conditioned pulse train sequence from my receive transducer
5) Prevent the CCR registers from overflowing
Note: My transducer frequency is 300kHz. So with MCLK = 25MHz, I should be able to service CCIFG interrupt and stop Timer_D within 39 clock cycles.

For this scheme to work, I have to know that my time-critical execution will always take the same number of MCLK cycles.

------------------------------------------------------------------------------
Translated into pseudocode:

1) Disable all interrupts except for CCIFG in Timer_D
2) Set up Timer_D: 200MHz, Up count, CCR1 capture rising edges, CCR0 falling edges, etc.

//Time T=0: ***Time-Critical execution of code starts here***
P1OUT = 0x01;                  // Start of +HV pulse
__delay_cycles(10)
P1OUT = 0x00;                  // End of +HV pulse
__delay cycles(HV+_delay)
P1OUT = 0x02;                  // Start of -HV pulse
__delay_cycles(HV-_length)
P1OUT = 0x00;
... more P1OUT writes for other pulses ...
__delay_cycles(until_arrival)         // Delay until known midpoint of incoming pulsetrain

TDxCTL0 |= MC__CONTINOUS     // Start Timer_D
while(1);       // Wait for 2 rising edge and 2 falling edge captures, to trigger Timer D CCR interrupt

__interrupt void TIMER1_D0(void)
{
TDxCTL0 |= MC__STOP;   // Stop TDR before any capture overflows, read arrival time of the acoustic pulses
}

Here are the big questions:

Are there any "gotchas" that would cause +/- MCLK cycles of execution during my time cricial routine?

Outside of my time cricital routine I plan to do calculations and relay results over I2C/SPI.  Would this affect my MSP's stack/heap/bus/flash/mojo and introduce uncertainty into my time-critical sequence exectution?

Will simple procedural code such as the above, with no branching, compile predictably, or do I need to learn assembly?

Thanks for your help!

-Thomas

  •  Hi Thomas, your design can be more simple using the high resolution of C2000 series that can generate and measure pulse within GHz resolution too, last MSP series include a timer D subsystem and EVENT CONTROL performing similar measurement with less resolution.

     If you wish to generate few pulses I don't understand why you are needing 4 pin or you wish shaping the pulse?

     On the other way all timing generation delay and measurement must be done on the same timer to avoid jitter and misalignment of counter:

    •  select up counter free run to 16bit
    • select the position of wave pulses then generate two precise pulse on output
    • disable transducer on last pulse then set compare to delay you wish (60uS)
    • on IRQ again start capture multiple channel (one raising on falling) and transfer all them by software or better with DMA
    • Also set a routine to capture timer overflow to do correction of timing. If you run timer near to 200MHz frequency TAR count with 5nS resolution and overflow every 65536 pulse corresponding to a delay of 327.68 uS, can be enough to do all measurement and no overflow can occur if you reset TAR before sending pulses.

      No need to learn assembly but just usage of hardware to reduce effort.

  • Thanks, Roberto.  Hmm.  I'll take another look at the Piccolo F280xx family.  I overlooked that they have high-res modules as well.

    Yes, the reason I need 4 pin output is for pulse-shaping and transducer damping.

    I also realize that I optimize this process with hardware resources (Timer_A or Timer_D2) to trigger events.  However because I exceed the number of CCRs for my pulse shaping, I must depend on some clock-cycle consistent software execution.

    I guess my question is more fundamental to the MSP430 architecture in the sense that if I write a subroutine of non-branching code (with all external interrupts disabled) to do simple port setting tasks, or set a tightly-controlled timer interrupt to wake the CPU from LPM0 and do some other simple task like starting Timer_D, can I depend on this code to always execute in the same number of clock cycles?

    - Thomas

  • Thomas Ruscher said:
    ing Timer_D, can I depend on this code to always execute in the same number of clock cycles?

     Hi Thomas, sorry for late answer, you depend on TAR of timer D to avoid jitter, a cpu intensive routine can drive the pulse shaping then arm the comparator channels and wait the complete transfer of echo pulses. DMA can help this process but another timer is needed to terminate acquire process.

     About Piccolo, If the MSP resolution is enough you don't need it if more fine under nS resolution CC2xxx series or MSP and an FPGA is the solution.

  • Thanks Roberto.

    I wrote some routines this weekend using both timerAs on the G2553 and confirmed that simple port-setting non-branching code (with interrupts disabled, of course) runs consistently down to the clock cycle.  Given the architecture similarity, I have no reason to believe this same approach would not work on the F5712.

    I plan to use a short cpu sequence to "pulse" 4 separate channels, then go to LPM0 (keeping a HF xtal running for accuracy), wake up on an interrupt 60us later and start timer_D. 

    Best, Thomas

  • Thomas Ruscher said:

    I plan to use a short cpu sequence to "pulse" 4 separate channels, then go to LPM0 (keeping a HF xtal running for accuracy), wake up on an interrupt 60us later and start timer_D. 

     I deducted your measurement are on liquid wave propagation so a small jitter error affect too much precision, not cpu intensive by itself but this way:

     read  TAR than add a value to be sure all code to pulse shaping is executed with some skew then do shaping in sync with tar values, this require no CC channel usages and Jiitter on shaping is no more than few cpu cycles too. If this is not enough try build some different precision hardware shaping by Compare logic then switch to capture for echos measurement.

    example:

    //  time critical cpu intensive part, no irq can be allowed  from here to avoid jiitter...

    ....IRQ_OFF...

    TAR=0;

    MyPulses=TAR+skew;

    ...preparing code....

    while(TAR<Mypulses);

    ....pulse1....

    Mypulses+=delay2pulse2;

    while(TAR<Mypulses);

    ....pulse2....

    ...repeat to pulse4...

    switch to capture and arm end of sequence timer.

     IRQ ON

**Attention** This is a public forum