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.

CC2538: CC2538 - MAC timer configuration

Part Number: CC2538

Hello,

I am reading the user manual related to the MAC timer for the cc2538 radio and I am having difficulties in understanding some of the operations provided.
I am mainly interested in the timer-compare and counter-overflow-compare modes, since I want to use them to schedule TX/RX operations through CSP commands.

My doubts concern the period of the timer when the two operations above are used.

By reading the manual I understood that:
1. the timer consists of a 24bit overflow counter and a 16bit timer counter.
2. The timer counter is updated by 1 at every clock cycle, which ticks at system clock (32MHz, giving a precision of 31.25ns)

It is also reported that the overflow counter is incremented whenever the period set has elapsed, but I am not sure what period it is referring to since I am using a compare operation.

Is the period simply the maximum achievable delta time giving the 16bit wide timer counter and the 31.25ns precision, which should be roughly 2.0479ms ?

I really thank you for your attention.

Best regards

  • Hi,

    The "timer overflow" happens when the timer counts to value equal to the "set timer period".
    The "set timer period" is configurable (see 1.3.5.1 MAC Timer in User's Guide). To set this value: RFCORE_SFR_MTMSEL.MTMSEL should be 010 before writing to RFCORE_SFR_MTM0 and RFCORE_SFR_MTM1.

    Since this is a 16-bit value, the max period would be according to your calculations, 2.0479 ms (0xFFFF/32MHz).

    The "Overflow-Count Compare" compare values may be set in a similar way (see RFCORE_SFR_MTMSEL.MTMOVFSEL).

    Regards,
    Toby

  • Thank you the quick reply, really appreciated.

    Unfortunately, this does not answer my original question. Maybe I didn't state it clearly.

    I will try to explain the issue with a concrete example.

    Let's assume the MAC timer is at 0x0000000001 (considering the entire 40bit MAC timer).
    I'd like to set an event to be triggered roughly 8.192 ms after the timestamp above.

    Since this delay is basically (1 << 18) I set the MAC timer and overflow registers with the value 0x0000040001.

    Note that the timestamp above means that:
    1. the 24 bit overflow value is set to 0x4
    2. the 16 bit timer value is set to 0x1

    I then enable one of the timer to be an overflow-compare-match event, and the other to be a counter-compare match.
    I use CSP commands to wait first for the overflow event and then for the counter event.

    The question is: the second event will fire after a) 8.192ms or after b) 125ns (31.25ns * 4) ?
    According to the user manual and your answer, option b would be the case.

    However, by using a secondary 32KHz timer provided by the board I use and timestamping this latency, it "seems" option a to be somehow possible.

    Hope the example makes things clearer now.
    I really thank you for your availability.

    Best regards,
    Diego

  • Diego Lobba said:

    I then enable one of the timer to be an overflow-compare-match event, and the other to be a counter-compare match.
    I use CSP commands to wait first for the overflow event and then for the counter event.

    The question is: the second event will fire after a) 8.192ms or after b) 125ns (31.25ns * 4) ?

    Can you clarify what you mean by "second event"?
    Is this referring to "counter event":
    - event 1: overflow-compare-match event
    - event 2: counter-compare match   <--- is this "second event"?
    OR
    is this referring to the second sequence of events:
    - event 1: overflow-compare-match event, counter-compare match
    - event 2: overflow-compare-match event, counter-compare match   <--- is this "second event"?

    If you are using compare values, what values have you set for MT_cmp1, MT_cmp2, MTovf_cmp1, MTovf_cmp2 ?

    Can you share some code snippets of:
    - how you are writing the MAC timer related registers?
    - how you are determining time between events with 32 KHz timer?

  • Hi,

    about the events order, I mean the first one you mention (overflow-compare-match AND then counter-compare-match).

    The code I use to set the MAC timer registers is the following:

    /* Set MTMOVFSEL bits to 011 as we are going to set overflow compare 1 value */
    REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMOVFSEL) | 0x00000030;
    REG(RFCORE_SFR_MTMOVF0) = ((uint32_t)(ts_tx_mt >> 16)) & RFCORE_SFR_MTMOVF0_MTMOVF0;
    REG(RFCORE_SFR_MTMOVF1) = ((uint32_t)(ts_tx_mt >> 24)) & RFCORE_SFR_MTMOVF1_MTMOVF1;
    REG(RFCORE_SFR_MTMOVF2) = ((uint32_t)(ts_tx_mt >> 32)) & RFCORE_SFR_MTMOVF2_MTMOVF2;
                                                                                                   
    /* Set MTMSEL bits to 011 as we are going to set counter compare 1 value */
    REG(RFCORE_SFR_MTMSEL) = (REG(RFCORE_SFR_MTMSEL) & ~RFCORE_SFR_MTMSEL_MTMSEL) | 0x00000003;
    REG(RFCORE_SFR_MTM0) = ((uint32_t) ts_tx_mt) & RFCORE_SFR_MTM0_MTM0;
    REG(RFCORE_SFR_MTM1) = ((uint32_t)(ts_tx_mt >> 8)) & RFCORE_SFR_MTM1_MTM1;
    
    /* We only use the overflow event if we need more than 1 overflows. */
    if ((ts_tx_mt >> 16) - (t_now >> 16) > 1) {
        /* Enable MAC timer event 1 (EVENT1) to be overflow compare match */
        REG(RFCORE_SFR_MTCSPCFG) = (REG(RFCORE_SFR_MTCSPCFG)
                & ~RFCORE_SFR_MTCSPCFG_MACTIMER_EVENT1_CFG) | 0x00000004;
        /* Write instruction to wait until MAC timer overflow match happens (event 1) */
        REG(RFCORE_SFR_RFST) = CC2538_RF_CSP_OP_WEVENT1;
    }
                                                                                         
    /* Enable MAC timer event 2 (EVENMT) to be counter compare match */
    REG(RFCORE_SFR_MTCSPCFG) = (REG(RFCORE_SFR_MTCSPCFG)
            & ~RFCORE_SFR_MTCSPCFG_MACTIMER_EVENMT_CFG) | 0x00000010;
    
    /* load CSP program which waits (event1), event_mt then TX and finally stops */

    
    

    About the 32kHZ timer. I am using Contiki to run the program, which is programmed to use a 32kHz timer for rtimers (a type of timers provided by the os).
    So I simply request and timestamp the time elapsed between the scheduled operation and its end.

    I did a self-contained application which prints the value of the timestamps related to scheduled TXs and the saved timestamps retrieved using the 32kHz timer.
    It is available here.

    I really thank you for the help.

    Best regards,
    Diego

  • Thanks for sharing the code.

    Below is what I think is happening.

    From the code snippet, you are scheduling radio TX at intervals such as this:
    MT_count() + [0x000004][0x0000]
    MT_count() + [0x000008][0x0000]
    MT_count() + [0x00000C][0x0000]
    ...
    MT_count() + [0x000004][0x0000] * n
    ...
    where MT_count() is the current read value of [overflow count, 24 bits][mac timer count, 16 bit]

    I see that you use the above values to set MTovf_cmp1 and MT_cmp1 to accomplish this. However, I don't see where you have written the MT_per value, which determines the interval that MTovf increments. I'll assume this is the max value of 0xFFFF.

    Now, going through a sample sequence, which starts at time T:

    1. Wait for overflow compare event on value in MTovf_cmp1.
      This will happen after 0x4 * MT_per / 32MHz == 8.192 ms
    2. Wait for timer compare event on value MT_cmp1.
      Assuming the timer compare value has just overflowed (during last iteration of overflow count), this will happen quite soon, compared to 8 ms.

    So total time to wait after second event is about 8 ms after T.

    This is assuming that the 16 bit MTtim has a period of 0xFFFF (~2 ms). You can adjust this period by setting MT_per.

  • Thank you so much!

    I will double check the value of MT_PER. Indeed that value was never set in my code and maybe everything works under this assumption.

    Best regards,
    Diego