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.

MSP430FR2155: MSP430FR2155

Part Number: MSP430FR2155

Hi 

I have another question regarding the Timer.

I set the CCR0 to 239, however, Timer seems to kick  223 clock cycle and some for 240 clock cycle.

How can I not having an consistent clock cycle for every Timer kick.

( I also make sure that there is no other service routine interrupt timer)

Thanks

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_B0_VECTOR
__interrupt void TIMER0_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) TIMER0_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
delta[count] = RTCCNT - pre_rtc;
pre_rtc = RTCCNT;
count++;
if (count>=120)
{
HWREG16(TIMER_B0_BASE + OFS_TBxCTL) &= ~MC;
// process data
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Hi ming,

    So it appears you are reading the RTC counter at time intervals you have setup for TimerB0 - correct?

    Can you provide your setup code for the RTC and TimerB0?

  • Hi Dennis,

    Yes, it is TimerB0 and RTC .

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    void RTCInit()
    {
    HWREG16(RTC_BASE + OFS_RTCCTL) &= ~(RTCSS_3 | RTCPS_7);
    HWREG16(RTC_BASE + OFS_RTCMOD) = 32767;
    RTC_start(RTC_BASE, RTCSS_1);
    }
    void InitTimer()
    {
    HWREG16(TIMER_B0_BASE + OFS_TBxCTL) = TBSSEL__SMCLK;
    HWREG16(TIMER_B0_BASE + OFS_TBxCCR0) = 239;
    HWREG16(TIMER_B0_BASE + OFS_TBxCCTL0) |= CCIE
    HWREG16(TIMER_B0_BASE + OFS_TBxCTL) |= MC__UP;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Hi ming,

    Ok, looks good, but I forgot to ask what is the SMCLK frequency?

  • Hi Dennis,

    SMCLK is 24Mhz

    Thanks

  • Hi ming,

    Ok, so you are clocking the RTC and TimerB using SMCLK running at 24MHz - correct so far?

    You don't mention how fast CPU is operating so I will assume the same 24MHz, in which case, do you have FRAM wait states = 2?

    Here are couple of experiments to try to help narrow down the problem.

    1. Change your code from delta[count] = RTCCNT - pre-rtc to delta[count] = RTCCNT - 239.  What do you see?

    2. Keep the CPU operating at 24MHz, but divide the SMCLK down to 4MHz.  What do you see?

  • Hi Dennis,

    yes, FRAM is set NWAITS_2.

    1> I change to delta[count] = RTCCNT - 240

         and the delta change to F0 for most of the time .

         Attach the result in the following.

         This is also the concern that result should be 240 regardless any codes written in between two Timer kicks as long as instructions did not exceed 240 clock cycle.  Why is it act like this by just changing one line of code?  (actually i did see cases similar to this, this is most simple case to describe)

        

    2> 4 Mhz is not really an option for us, however, if really necessary i can try it later to see the consequence.

    Thanks

  • Hi ming,

    Let me look into this.

  • Hi ming,

    Ok, there is something not correct here.  I went back and took a second look at your RTC initialization. According to your initialization code, you are clearing the RTCSS bits, which selects 'No Clock'.  What clock source did you intend to use for the RTC? 

  • Hi Dennis,

    it use smclk for the RTC.

    It is a library call for RTC_start() to set the clock source

    I attach the code here.

    Thanks

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void RTC_start(uint16_t baseAddress,
    uint16_t clockSource)
    {
    HWREG16(baseAddress + OFS_RTCCTL) &= ~RTCSS_3;
    #ifdef RTCCKSEL
    HWREG16(SYS_BASE + OFS_SYSCFG2) &= ~RTCCKSEL;
    if(clockSource == RTC_CLOCKSOURCE_ACLK)
    {
    HWREG16(SYS_BASE + OFS_SYSCFG2) |= RTCCKSEL;
    HWREG16(baseAddress + OFS_RTCCTL) |= RTCSS_1;
    }
    else
    {
    HWREG16(baseAddress + OFS_RTCCTL) |= clockSource;
    }
    #else
    HWREG16(baseAddress + OFS_RTCCTL) |= clockSource;
    #endif
    HWREG16(baseAddress + OFS_RTCCTL) |= RTCSR;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Thanks ming for clarifying this.

    So you are running the RTC, TimerB and the CPU at 24MHz, correct?  This means for every SMCLK, both RTC and TimerB advance by one count. So in theory when TimerB count matches CCR0 for the very first time, RTCCNT will be equal to TimerB count, right?

    Then TimerB generates an interrupt and resets the count = 0. At this same time, the CPU detects the interrupt, pushes status register and stack pointer and performs the few instructions to read the RTCCNT register.  But from the very moment of the interrupt until the time the CPU reads the RTCCNT register, the SMCLK continues to advance the RTC and TimerB counts. So if it takes the CPU 20 clock cycles (as an example) to execute the code leading up to reading the RTCCNT register, the RTCCNT and TimerB will be +20 counts from when the interrupt occurred.  So this means you can't only subtract 239 from RTCCNT, you need to account for the CPU time, in this case RTCCNT - 239 - 20.

    Can I ask the purpose of trying to read the RTCCNT with TimerB?

  • Hi Dennis,

    There is only one difference from my understanding. Timer interval between two kicks should be 240 cycle as long as the instructions is less than 240 cycle. 

    The board is read/write data from the port 1 interface.  

    It works when the timer can kick on the the fix interval 240. 

    The reference board that we get from TI did not have the controller for that traffic. 

    Thanks

  • Hi ming,

    Unfortunately I don't have an FR2155 in front of me to program and try your code, but maybe you can try a quick experiment?

    In your ISR, instead of reading the RTCCNT value and writing to the array, modify the code to read the TimerB count register (TB0R) and write those values to the array and show me what you capture.

  • Hi Dennis,

    I test with two different cases. One with RTC in accumulated style and the other with RTC delta style coding.  please refer to the image with two results accordingly.

    The first case has TB0R counter 0x21 and the second one has TB0R counter value 0x38.

    The first case has RTC counter 240  and the second one has RTC counter 220.

    The instruction did not exceed the 240 clock cycle but  RTC counter should be the same, right?

    However, it has different RTC value and this is what we like to find out how can we fix this.

    Thanks

  • Hi ming,

    Ok, the TB0R are pretty consistent and that is exactly what I would expect. I'm not sure why the RTC count doesn't make any sense.  I'll have access to a FR2155 tomorrow and will run your code to see if I can reproduce.

  • Hi ming,

    I setup my project using your original code and it seems to work fine.  I get a delta of 223 every time in the ISR.

    I have attached my source code for you to try.  Note, I had to use FR2355 which is in the same family with same peripherals.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <msp430.h>
    #include "driverlib/MSP430FR2xx_4xx/inc/hw_memmap.h"
    #include "stdint.h"
    #define RTC_CLOCKSOURCE_SMCLK RTCSS__SMCLK
    #define RTC_CLOCKSOURCE_ACLK RTCSS__XT1CLK
    void RTC_start(uint16_t, uint16_t);
    void RTCInit()
    {
    HWREG16(RTC_BASE + OFS_RTCCTL) &= ~(RTCSS_3 | RTCPS_7);
    HWREG16(RTC_BASE + OFS_RTCMOD) = 32767;
    RTC_start(RTC_BASE, RTCSS_1);
    }
    void InitTimer()
    {
    HWREG16(TIMER_B0_BASE + OFS_TBxCTL) = TBSSEL__SMCLK;
    HWREG16(TIMER_B0_BASE + OFS_TBxCCR0) = 239;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

**Attention** This is a public forum