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.

MSP430F5529LP chokes on signal input

Other Parts Discussed in Thread: TLV2372, MSP430F5529

I am developing an application on the MSP430F5529LP that senses plant tissue resistance. A change in such resistance changes the frequency of an opamp (TLV2372) R-C multivibrator, the output of which is buffered by the second opamp in the same package. I feed this output into Port 4.0 with the intention of measuring pulse width using timer_B capture. The power supply for the opamp is the launchpad 3.3V.

I started to write a program to do this, but, having trouble with capture, I decided to constantly monitor timer_B by generating an independent PWM output. The complete code listing is here:

	#include "driverlib.h"
    #include <msp430.h>
	void Port_Mapping(void);

    void main (void){
        WDT_A_hold(WDT_A_BASE);
      UCS_clockSignalInit(UCS_MCLK, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_1);
	  // Setup Port Pins

    Port_Mapping();
   	GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P7,GPIO_PIN4);
   				//PWM to verify timer_B is on

    GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
    			//variation in LED luminance tracks input signal

    TIMER_B_configureContinuousMode(TIMER_B0_BASE,TIMER_B_CLOCKSOURCE_SMCLK,
    		TIMER_B_CLOCKSOURCE_DIVIDER_1,TIMER_B_TBIE_INTERRUPT_DISABLE,
    		TIMER_B_DO_CLEAR);

    TIMER_B_startCounter(TIMER_B0_BASE,TIMER_B_CONTINUOUS_MODE);

    TIMER_B_initCompare(TIMER_B0_BASE,TIMER_B_CAPTURECOMPARE_REGISTER_2,
    		TIMER_B_CAPTURECOMPARE_INTERRUPT_DISABLE,
            TIMER_B_OUTPUTMODE_RESET_SET,0x8000);

    TB0CCTL0 = CM_1 + CCIS_0 + SCS + CAP + CCIE;
    		// pos. edge + CCIXA + sync + capture mode + Interrupt enable
    		//TIMER_B_initCapture in driverlib is broken - will not compile (TIMER_B_CAPTURE_INPUTSELECT_CCI0A not valid)

    TB0CCTL1 = OUTMOD_3;	// CCR1 set/reset to P1.0

      while (1){
    	  __delay_cycles(0x00FF);
      }
	}

      #pragma vector=TIMERB0_VECTOR
      __interrupt void TIMERB0_ISR (void)
      {
    	static int TB0CCR0_old;
    	static int TB0CCR0_diff;

    	TB0CCR0_diff = TB0CCR0 - TB0CCR0_old;
    	TB0CCR0_old = TB0CCR0;
        TB0CCR1 = TB0CCR0_diff + 0x2000;// Add Offset to CCR1 [Cont mode]
      }

      void Port_Mapping(void)
      {
          P4DIR = 0xFE;         // P4.1 - P4.7 output, P4.0 input
          P4SEL |= 0x81;        // select P4.0 and P4.7 for Port Map functions
        __disable_interrupt();  // Disable Interrupts before altering Port Mapping registers
        PMAPPWD = 0x02D52;      // Enable Write-access to modify port mapping registers
        #ifdef PORT_MAP_RECFG
        PMAPCTL = PMAPRECFG;     // Allow reconfiguration during runtime
        #endif
        P4MAP0 = PM_TB0CCR0A;	// P4.0 capture pin
        PMAPPWD = 0;            // Disable Write-Access to modify port mapping registers
        #ifdef PORT_MAP_EINT
        __enable_interrupt();   // Re-enable all interrupts
        #endif
      }

My efforts in monitoring timer_B paid off in that I found the test output signal at P7.4 vanished when I connected my opamp multivibrator to P4.0. I then tried inserting a one megohm resistor between the signal source and P4.0 with the same result. I then tried connecting, through a 10K resistor, P4.0 to launchpad ground and 3.3V. In all cases, the test output at P7.4 got messed up in that the square wave it should have been became no longer square - the duty cycle got messed up. All of the jumpers I used for this are short: 5 inches long.

I also noticed that, when the duty cycle was wrong, halting the program (not using the pause in CCS, but hitting the red stop button, thus leaving the launchpad "dangling") made the duty cycle returne to the square wave it should be. But the susceptibility to connecting anything to P4.0 remained even in this "dangling" state.

So my concern here is that perhaps this chip is not suitable for real-world sensing applications. Say it 'aint so!

  • The driverlib probably turned on the TB0 overflow interrupt and you do not have an ISR to handle it. \

    It's a time-bomb ;-)

  • So do it without driverlib, as in direct setting of registers?

  • It does not matter whether you use libraries, write your own code, or copy someone's code, the bottom line is, the CPU will simply follow the machine code loaded into the Flash. If that code enables interrupt without an ISR to handle it, when that interrupt is triggered, the CPU will crash.

  • Thanks, old_cow_yellow. I know this, but did not know how flaky the driverlib can be. I am discouraged that no TI person has chimed in on this, which is a show-stopper for me. I am redoing my application with the Tiva launchpad: maybe it will be more robust.

  • Sorry, I might have misled you (unintentionally).

    I do not really know what made your F5529 choke. One thing you could do is add ISRs to trap all un-expected interrupts.

    Please un-check the "This question is answered" or "Verified" so that the TI engineers might answer you.

    -- OCY

  • Otto Hunt said:
    Thanks, old_cow_yellow. I know this, but did not know how flaky the driverlib can be. I am discouraged that no TI person has chimed in on this, which is a show-stopper for me. I am redoing my application with the Tiva launchpad: maybe it will be more robust.

     Hi Otto, TIVA is not "more robust" this way, I think can be less robust so MSP is quite simple and you missed an Interrupt service, in TIVA environment you can also be catched by increased complexity of that and also by defaulted pin not well documented as is on MSP430.

     I think you had to have a working capture routine then your problem is solved.

     Try use GRACE utility and take e look how it initialize all periplheral register then try learn from one or more setting how change your code.

     If you need capture enable interrupt on capture and in the IRQ service read the value, subtract from previous sample.

     If sampled time is greater than timer then you have to also account overflow and do a time difference from a variable long.

     Timer are designed to simplify this job but need be grasped in full to use better.

     Try see how it work software uart, it measure incoming pulses or an example about time measuring.

  • Hi Roberto,

    It appears Grace does not support the MSP430F5529. Would Grace support the timer functionality only? i have not tried Grace due to this lack of 5529 support.

  • Otto Hunt said:
    Grace due to this lack of 5529 support.

     Hi Otto, sorry I was aware of this lack of support, I used the 5510 but I wrote all code dealing with timer reading the datasheet.

     I just remember timer module was very similar to all other in the family other than timer D is just in this.

     Have you familiarity on how to use a capture timer? If so please be more specific over what is wrong otherwise tell us and we can find a solution/cure to problem.

  • Hi Roberto,

    I posted my complete code listing above, along with a detailed account of the troublesome chip behavior. If anything I wrote is unclear or incomplete, do ask and I will elaborate.

    i could redo this without using driverlib, and OCY also suggests, I have moved on though, studying other approaches to my project using PSoC and CPLD.

  • Besides the code, maybe you should give some more information about the application parameters. In which frequency range does the RC oscillate? Does it have 50% duty cycle?
    What is your XT2 crystal speed?
    Sometimes it is better you count the pulses with a timer and read the timer count in fixed intervals (e.g. triggered by ACLK), rather than to try to determine the pulse width.It depends on the frequencies.

  • Hi Jens-Michael, I am using the MSP439F5529 Lauchpad, unmodified. My signal source is an opamp multivibrator (inverting input has a capacitor to ground, with a resistor from output to inverting input) which oscillates at 220 Hz. I need a low frequency because I want to minimize the effect of plant tissue capacitance in this system. The output is pretty close to %50 duty cycle. Counting pulses would be too slow.

  • For 220Hz, indeed checking the pulse width is the better solution.

    The ‘not valid’ error is because the constant is TIMER_B_CAPTURE_INPUTSELECT_CCIxA (as it is the same for all CCRs, so no need to define up to 7 individual identical constants)

    Also, you seem to init CCR2 for compare/PWM mode, but you increment CCR1 in the ISR.

  • Thanks again, Jens-Michael, I will note your comments and give driverlib another chance for configuring capture.

    You are correct in that CCR2 is being used to monitor TimerB health (glad I did! - see my original post) by simply outputting a PWM signal, while CCR1 is being used for capture of the 220Hz signal.

  • Okay, I see. What was and still is puzzling me is the formula/logic you use for TB0CCR1. You set it to 0x2000 + TB0CCR0 - TB0CCR0_old. So the PWM output of CCR1 will have a duty cycle of (0x2000+x)/65536, where x is the pulse with. Effectively, the CCR1 output will be by 8192 timer clock pulses longer than the detected input frequency and not synchronous to it. Since the next pulse will be detected within this interval (assuming constant input frequency), you are reconfiguring TBCCR1 up to 0x2000 timer ticks before it would have triggered, depending on the phase of CCR0 input to TAR overflow. This will surely give something like an erratically looking output for TB0.1 as soon as the input frequency isn’t constant.
    It shouldn’t, however, influence TB0.2 output. (P7.4).
    So the only thing I can imagine right now is that applying the input signal causes your XT2 to fail, switching back to DCO, which will change the timer counting speed. However, it you don’t have code to recover, the timer speed will then be constant (even though different) and the TB0.2 output should still have 50% DC, even though at a different frequency.

    One thing you could try is to set a breakpoint at start of main, then let it run. Does it hit the breakpoint again (indicating that for some reason, the MSP resets)?

     One more thing: you enable P1.0 as GPIO output. With the comment that ‘variation in luminance will track input signal’. However, you don’t ever touch P1.0 again. And TB0CCR1 output is on P5.7, which you never enable. But then, you enable P4.7 for module usage, but nothing is mapped there. Maybe a typo?

**Attention** This is a public forum