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.

CC2530 Timer 1 Modulo mode issue

Other Parts Discussed in Thread: CC2530, TIMAC, Z-STACK, CC2530EM, SIMPLICITI

Hi,

Am using the Timer 1 in CC2530 to operate in Modulo mode, inspite of setting the needed timer registers correctlly the Timer simply work . I want an interrupt on the compare value match, Ive set IM bit  and the mode field in T1CCTL0 accordingly. Also ive enabled the global interrupt and the Timer 1 overflow interrupt , i start the counter from 0x0000 but  i dont get an interrupt on the match value. Even if i start the counter with a value above the compare value i do not get the overflow interrupt.

With the same register setting am able to run the timer in free run mode and up down mode with proper interrupts on the overflow condition. What can be the issue am i missing something in the configuration?

T1CTL &= ~0x03;  //Disable Timer]

T1CTL &= ~0x0C; //Clear prescalar
T1CTL |= 0x04;   //Set prescalar to 128

T1CNTL =  0x00; //set the count value to 0
T1CNTH = 0x00;

T1STAT |=  BV(5);  //Enable the overflow interrupt

IRCON |= BV(1);//Enable the Timer 1 interrupt

T1CTL |= 0x02; //Start the timer in  Modulo mode

T1CCTL0 |= 0x44; //Interrupt on compare and compare mode

 

  • In your code, you do not set the T1CC0L/T1CC0H registers. They hold the end value for the count when in modulo mode. The reset value is 0, and if you don't change these registers, your counter will count from 0x0000 to 0x0000 in modulo mode, meaning it doesn't count at all. Set these registers to your period minus one, and it should work.

  • Am sorry i forgot to mention that, i do set the T1CC0L/T1CC0H to a value one less than the period.  Am not sure if the timer begins counting in the first place or if the interrupt is not generated. But the same register setting with only a change in the mode runs perfectly.

     

  • You have not enabled the T1 interrupt in your code. I think you intended to do so by IRCON |= BV(1), but that sets the interrupt flag (which is meaningless, if anything, you should clear it), not the enable bit. Remove that statement and add:

    T1IE = 1;

    And you also need to do global interrupt enable:

    EA = 1;

  • Hi Hec,

    Actually its a typo error on my part sorry about that. Well i am enabling both the global(EA = 1) as well as the T1 interrupt(T1IE = 1) , in free run mode i enable the T1 overflow interrup too (TIMIF.OVFIM = 1) and in modulo mode i set the T1CCTL0.IM bit to get an interrup on compare match. About the compare value (T1CC0H & T1CC0L) i set it to some value close to the overflow value (something like 0xFF00) before enabling the timer is also set the timer counter value to 0x0000 (T1CNTL & T1CNTH writing to T1CNTL makes it 0x0000 but i still set both to 0x00). Ive also tried setting the counter start value to something above T1CC0 inorder to get a interrupt on overflow still no good.

    In all cases i enable interrupts such that there is just one interrupt source like in case where i use modulo mode but want overflow interrupt for a start value above compare value i disable the compare match interrupt source. And the common register settings like prescalar n tick frequency etc are the same and works fine for free run mode.

    P.S sorry for the late reply

  • I don't quite get what your problem is. However, your code contained a lot of errors compared to the comments, and I have commented on that. There are others as well; your prescaler did not match the setting and the overflow interrupt enabling was also wrong.

    You will get a compare interrupt at the end of the period in modulo mode. The overflow interrupt does not normally happen in that mode and can be seen as an error indication. Here is an example which shows how you get both the period interrupt and the overflow interrupt (once) in modulo mode. If you uncomment the second clearing of the timer, the overflow is gone.

    Note that you can not write any other value than zero to the timer, so to set a value above the period in order to observe the overflow interrupt, you have to let the timer run as in my example. Note that the example is for demonstration of the interrupts only, the code, especially the first part of it, is not particularly useful.

    #include <ioCC2530.h>

    #define BV(x) (1 << (x))

    int main (void)
    {
        union {
            unsigned char byte[2];
            unsigned short val;
        } t1cnt;
                
        P1 = 0x00;      // LEDs off
        P1DIR = 0x03;   // LEDs on P1_0 and P1_1 as output
        T1CTL = 0x00;   //Disable Timer]
        T1CNTL =  0x00; //set the count value to 0
        
        // Start timer in free running mode, no prescaler
        T1CTL = 0x01;
        
        // Wait until timer is above period to use
        do {
            t1cnt.byte[0] = T1CNTL;
            t1cnt.byte[1] = T1CNTH;
        } while (t1cnt.val <= 0xA000);
            
        // Stop timer
        T1CTL = 0x00;           
        //T1CNTL =  0x00; //set the count value to 0
        
        // Set period
        T1CC0L = 0x00;
        T1CC0H = 0xA0;

        T1CCTL0 = 0x44; // Interrupt on compare and compare mode
        T1OVFIM = 1;    // Enable the overflow interrupt
        T1IE = 1;       // Enable the Timer 1 interrupt
        EA = 1;         // Global interrupt enable

        // Set prescaler to 128 and start timer in modulo mode
        T1CTL = 0x0E;
        
        while (1);
    }

    #pragma vector=T1_VECTOR
    __interrupt void t1Isr (void)
    {
        if (T1STAT & 0x01) {
            // Channel 0
            P1_0 = ! P1_0; // Toggle the P1.0 LED (green on SmartRF05 EB) each period
            T1STAT = ~0x01;
        }
        if (T1STAT & 0x20) {
            // OVFIF
            P1_1 = ! P1_1; // Toggle the P1.1 LED (red on SmartRF05 EB) when overflow occurs
            T1STAT = ~0x20;
        }
    }


  • Hi HEC,

    i want to blink the led on CC2530 P0 with 1 sec time, and want to create the delay using timers, and i am also working to derive LCD 16x2 on CC2530. Please help me to work this in IAR Work Bench, i am facing problems to get work with cc2530 modules because its registers are different from 8051.

    Thanks in advance HEC for support.

    Adil Ahmed.

  • Please start a new thread for these questions (or even one for each question), and please do not ask for a specific person to answer. If you are setting up a new IAR project (rather than integrating with Z-Satck or TIMAC), please consider using the Low Power RF Tools Forum for the IAR question.

  • Hi Adil,

    If you are using Z-Stack, you can

    1. You can use API in hal_led.c to do LED blink.

    2. You can refer to hal_lcd.c and check how it works.

  • Thanks YiKai Chen,

    i am using the CC2530 standalone  unit, without the SmartRF05 and CC2530EM development platform and kits.

     Therefore hal type libraries are useless for me, i want the simple C/C++ programming for CC2530 and operate it like 8051 controller, and i also need to communicate b/w two CC2530 unit. is there is any simple help for that?

    Thanks

    Adil Ahmed 

  • If you don't use Z-Stack or other TI stack such as SimpliciTI or TIMAC, you can only refer to CC253x/4x User's Guide (Rev. F) - Texas Instruments and do it by yourself. However, hal_lcd.c and hal_led.c are still good example codes for your references.