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.

MSP-EXP430FR2433: Consultation on capture timer related issues

Part Number: MSP-EXP430FR2433

Hello, we are trying to debug the capture timer, using the 16Mhz SMCLK configuration, currently we need to capture the low-level duration of the us level.
But there are currently the following two questions, I would like to ask you to help confirm them:
1. Whether the relevant configuration of CS (sys_cs_init) is normal, especially the CS_MCLK_FLLREF_RATIO parameter in the code.
2. Whether the calculation method of elapsedTime in the capture interrupt is correct, the unit is us.PUMA-MCU-test.zip

  • Hi Zhou ge

    we have the application notes on MSP430FR2xx and MSP430FR4xx DCO+FLL Application Guide. Hope it is helpful on question 1.

    Thanks!

  • Hello, can you help verify the project in the attachment? See if it is possible to capture the low-level duration of the us level?

    PUMA-MCU-test.zip
  • Hi 

    This seems to be the same as the case I mentioned earlier, including questions and attachments. I would like to ask you to help confirm whether the capture can capture the low-level duration of "us" using the current CS configuration. thanks.

  • We need to test the duration of 300us, we expect the error to not exceed 30us

  • Timer capture is accurate to the resolution of the timer.

    If I may suggest, I see two hazards here:

    1) The technique of starting at 0 (using TACLR) introduces a software latency into the start time, so it will be wrong by however long it took for the CPU to reach the TACLR setting. You should use the value that was captured in CCR1, which is correct

    2) Counting overflows works most of the time, but is susceptible to corner/race conditions. And in your application you don't need to.

    So I suggest you:

    A) Don't use TACLR at the leading (falling) edge, merely record the captured (TA0CCR1) value. At the trailing (rising) edge, subtract that value from the (new) TA0CCR1 value. The rules of unsigned-subtract will give you the correct result, even if TA0R "wraps" to 0 in between.

    B) Divide the timer clock by /8 by setting ID=3. Then your resolution is 0.5usec, but you can have a maximum period of 32+ milliseconds; (which seems within what the original code expects) and needn't count overflows.

    If you are concerned about timeouts (I always am), here's one method:

    C) Adopt a second CCR (e.g. TA0CCR2), and set its CCIE. At the leading edge, store TA0CCR1 into TA0CCR2. If you ever get a Compare-match (CCIFG) from TA0CCR2, TA0R has come full-circle (32ms) so you've timed out,. You can then take remedial action (probably just throw out that reading).

  • Sorry, I am not very clear about the modification configuration you mentioned. Could you please modify the code uploaded before and explain it?

    1) The technique of starting at 0 (using TACLR) introduces a software latency into the start time, so it will be wrong by however long it took for the CPU to reach the TACLR setting. You should use the value that was captured in CCR1, which is correct

    Currently, the endTime in the interrupt uses TA0CCR1. At the same time, I still don't understand what you said about TACLR.

    B) Divide the timer clock by /8 by setting ID=3. Then your resolution is 0.5usec, but you can have a maximum period of 32+ milliseconds; (which seems within what the original code expects) and needn't count overflows.

    Regarding this modification, can I also change 16Mhz to 2Mhz? Is it the same situation?In this case, if we want to capture 15.6ms, there is no need to consider the overflow situation.

    Here I want to explain that we need to capture the following three data, 15.6ms, 330us, and 670us.

  • A) i)Replace

    >startTime = 0; //Reset timer variable and CCR2, start timer in cont mode
    >TA0CCR1 = 0;
    >TA0CTL |= TACLR | MC_2;

    with

    >startTime = TA0CCR1; //Capture leading edge
    >TA0CCR2 = startTime;  // Save for timeout check;

    ii) and replace

    > elapsedTime = (4096*overflowCounter) + (endTime/16);

    with

    > elapsedTime = (endTime - startTime)/2;  // Low period in usec

    iii) and add

    >case TA0IV_TACCR2: // Timeout

    >edgeFlag = 0;   // Didn't work out -- start over
    >break; //

    -----

    B) Yes, if you don't need the CPU (MCLK) to run at 16MHz, you can slow MCLK/SMCLK down to 2MHz and get the same result.

  • Hello, I have a question to confirm first, is the calculation of the macro control parameter CS_MCLK_FLLREF_RATIO correct? 16000000/32768≈488.
    Is this parameter used as the ratio parameter of the CS_initFLLCalculateTrim function correctly?
    If it is not correct, how should it be calculated?

  • The main reason is that I tried to test sleep 1s with the current configuration. It seems that it is not accurate. I tried to call the mg_sleep interface to test.

  • How did you test it? What results did you get?

    488 is the correct value. It becomes CSCTL2:FLLN (the driverlib function does the -1 for you).

    As I mentioned over in the other thread, I took your code and put SMCLK out on a pin. My scope measured 15.9-16.1 MHz (it's a mediocre scope). That tells me that the final result of all the calls is as expected.

    Another thing I mentioned in the other thread is that I couldn't get your project (as posted) to work, so I created a new project and copied main.c into it. You might want to do the same thing, since it's possible your project has some strange setting that's getting in your way.

  • Hello, I use the following definition
    #define mg_sleep(s) __delay_cycles(16000000*s)
    I tried to add a while(1) loop in the main function, call the mg_sleep interface, flip the P1.0 pin once in 1S, and then test the waveform of the P1.0 pin with an oscilloscope.But the test situation cycle is not changed every 1S.

    +#define mg_sleep(s)  __delay_cycles(16000000*s)
    
    int main(void) {
    
    +   GPIO_setAsOutputPin(
    +       GPIO_PORT_P1,
    +       GPIO_PIN0
    +   );
    +   while(1)
    +   {
    +       GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
    +       mg_sleep(1);//sleep 1s
    +   }
    }

  • Hello, I checked the code and found that the reason for the inaccurate sleep is that the ADC-related configuration is configured in our code. This part of the code contains the configuration of SMCLK. Sleep1S is normal after shielding the adc_init interface, but our project also needs ADC multi-channel sampling function. Can you provide some suggestions? See if the configuration of TA1 in ADC needs some modification?

    Please see the attachment for code engineering

    8015.PUMA-MCU-test.zip

  • Since this is a new question, I suggest you create a new thread.

    I won't be able to help before next week

  • OK ,I will create a new case.

    Thanks.

**Attention** This is a public forum