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.

MSP430FR5969: Unexpected elapsed time measurement

Part Number: MSP430FR5969

Hi,

I am currently using 2 MSP430FR5969 MCU, one of which is the launchpad and the other is a client's custom board with MSP430FR5969 MCU. The launchpad is used to emulate a transmitter for the client's custom board and is wired to output directly into the client's input pin. Both boards are set to run at 16MHz. I have been trying to detect a falling edge and rising edge transition with duration of roughly 20us (320 cycles) on the client's board, but I am consistently seeing roughly 284 cycles instead. I was expecting to see higher cycle count than the expected 320 cycles but it is reading lower cycle count than expected. I have also tried to have the timer pin trigger on both edges synchronously but it is still reading roughly the same as before. Is there any particular reason why I am not getting close to the expected elapsed time/cycle count?

On the launchpad I am free running the following code

#include <msp430.h>
#include <stdio.h>

static uint8_t tst[16] = {1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1};
static int tstIndex = 0;

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer

    PM5CTL0 &= ~LOCKLPM5;

    FRCTL0 = FRCTLPW | NWAITS0;

    CSCTL0_H = CSKEY >> 8;
    CSCTL1 = DCOFSEL_4 | DCORSEL;
    CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;
    CSCTL6 &= ~(MODCLKREQEN | SMCLKREQEN | MCLKREQEN);
    CSCTL6 |= ACLKREQEN;

    __bic_SR_register(GIE);

    P1DIR |= BIT5;
    P1OUT |= BIT5;

    TA0CCTL0 = CCIE;
    TA0CCR0 = 160;
    TA0CTL = TASSEL__SMCLK | MC__UP | TACLR;

    __bis_SR_register(LPM0_bits | GIE);
    return 0;
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR (void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
    if(tstIndex > 15)
    {
        tstIndex = 0;
    }
    P1OUT = (BIT5 & (tst[tstIndex] << 5));
    tstIndex++;
}

and on the client's custom board, I am running the following pieces of code:

int main(void)
{
    DIRECT_SET_BIT(WDTCTL, WDTPW | WDTHOLD);
    CLR_BIT(PM5CTL0, LOCKLPM5);

    FRAM_init();
    ChangeClockSpeed_1MHZ();
    setup_pins_default();
    setup_data_struct();

    state = STATE_READY;

    while(FOREVER)
    {
        switch(state)
        {
        case STATE_READY:
            state = handleStateReady(STATE_READY, &g_rx_raw_data);
            ChangeClockSpeed_1MHZ();
            break;
        default:
            break;
        }
    }
	return 0;
}

static volatile uint16_t delimiterDuration;
void setup_receive(uint8_t currentState) { __bic_SR_register(GIE); ChangeClockSpeed_16MHZ(); SET_BIT(PIN_LED1_DIR, PIN_LED1); SET_BIT(PIN_LED2_DIR, PIN_LED2); CLR_BIT(PIN_LED1_OUT, PIN_LED1); CLR_BIT(PIN_LED2_OUT, PIN_LED2); delimiterDuration = 0; state = currentState; DIRECT_SET_BIT(TA0CCTL0, 0); SET_BIT(TA0CTL, TACLR); CLR_BIT(PIN_RX_SEL0, PIN_RX); CLR_BIT(PIN_RX_SEL1, PIN_RX); SET_BIT(PIN_RX_IES, PIN_RX); CLR_BIT(PIN_RX_IFG, PIN_RX); SET_BIT(PIN_RX_IE, PIN_RX); } uint8_t handleStateReady(uint8_t currentState, volatile Rx_raw_data_context* g_rx_raw_data) { setup_receive(currentState); __bis_SR_register(LPM0_bits | GIE); printf("%u\n", delimiterDuration); if((uint16_t)(delimiterDuration - MINIMUM_DELIM_LENGTH) <= DELIM_RANGE) { SET_BIT(PIN_LED1_OUT, PIN_LED1); state = STATE_ARBITRATE; } else { SET_BIT(PIN_LED2_OUT, PIN_LED2); state = STATE_READY; } return state; } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer0_A0_ISR (void) #elif defined(__GNUC__) void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void) #else #error Compiler not supported! #endif { CLR_BIT(TA0CTL, MC__CONTINUOUS); delimiterDuration = TA0CCR0; DIRECT_SET_BIT(TA0CCTL0, 0); SET_BIT(TA0CTL, TACLR); _bic_SR_register_on_exit(LPM0_bits | GIE); } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = PORT2_VECTOR __interrupt void Port2_ISR (void) #elif defined(__GNUC__) void __attribute__ ((interrupt(PORT2_VECTOR))) Port2_ISR (void) #else #error Compiler not supported! #endif { CLR_BIT(PIN_RX_IE, PIN_RX); SET_BIT(PIN_RX_SEL0, PIN_RX); CLR_BIT(PIN_RX_SEL1, PIN_RX); DIRECT_SET_BIT(TA0CCTL0, CM_1 | CCIS_1 | CCIE | SCS | CAP); DIRECT_SET_BIT(TA0CTL, TASSEL__SMCLK | MC__CONTINUOUS | TACLR); }
  • Hey Ben,

    If I understand correctly, you are trying to generate some sort of PWM signal from the custom board and it should have a period of 20uS (50 kHz), but it seems to be to fast.  Is that correct? 

    I took a quick look at the code you provided for the custom board, but I wasn't able to full follow it.  I couldn't see what pin you are trying to output on. 

    I'd recommend trying to run the example code to generate your signal so you have one side working.  Maybe this example for a PWM signal running off the DCO:  https://dev.ti.com/tirex/explore/node?node=AJaCTZBNOaYcl60z596fGA__IOGqZri__LATEST 

    Thanks,

    JD   

  • Hi JD,

    Sorry if the code is confusing as I have to omit some parts due to confidentiality, to clarify:

    I am trying to output a "PWM" signal from the launchpad to the custom board with a period of 20uS. The launchpad is outputting using P1.5 and the custom board is receiving the output using P2.3. Currently I have both board running at 16MHz. I have already tried using the PWM example on the launchpad before but the custom board was still capturing roughly 285 cycles instead of around the expected 320 cycles. So yes, for some reason the custom board is indicating that it is capturing too fast which should be impossible as the capture of the custom board should happen after the launchpad has made the rising edge transition.

    The steps I am doing to detect the falling and rising edge transition on the custom board is using P2.3's GPIO interrupt for the falling edge and setup the synchronous timer capture in the port ISR for the rising edge. When the rising edge occurs, I save the TA0CCR0 register into a variable for the "elapsed time" between the falling and rising edge.

    I suspected that maybe the falling edge interrupt of the custom board was too slow but using synchronous timer capture on both edge did not show me any difference. I also suspected it may have been because of the printf, hence, I had commented out the printf and output to LED if it detected the correct duration within a small range. This also did not work as the custom board lit up the "correct" LED when the range was between 270 and 290 instead of 310 to 330.

    Thanks,

    Ben

  • The measurement of the trailing edge is happening exactly at the time of the trailing edge (via capture). but the measurement of the leading edge (TACLR) is happening much later than the edge itself, at the end of the PORT2 interrupt. I count easily 25 clocks' worth of instructions in the PORT2 ISR. Combined with 10+ clocks of ISR overhead, that would  explain your 35-clock discrepancy.

    I recommend you measure both edges using timer capture. I suggest you run TA0 in continuous mode all the time, then use CM_3 and check CCI to see which edge you just captured. Once you have the two edges, just subtract the two time stamps.

    [Edit: Unsolicited:

    >     _bic_SR_register_on_exit(LPM0_bits | GIE);
    This is disabling interrupts in main. I suspect that wasn't what you intended.]

**Attention** This is a public forum