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.

Need to know how to implement a delay using the timers in TMS57020216LSUSB

Hi,

I am Gowdham. I am started to implement the Bootloader and startup codes for this controller. Now i need to know how to implement the timer module to introduce the delay of 3 secs.

I tried with HET IDE, and it is difficult for me to understand.

Please tell me how to implement the timer in this controller.

Thanks

Gowdham.

  • Hi Gowdham,

     

    It will be easier to use RTI to generate delay. The frequency of RTI is VCLK. The only thing you need is to program the RTI counter register.

     

    Regards,

    QJ

  • Hi Gowdham,

    I agree with QJ that the RTI is a better option for just a periodic interrupt.   

    RTI is the realtime interrupt module and it is usually used for operating system delays. 

    NHET / HET are control timers - and typically they are used for input capture / output compare functions  where you need to drive IO pins.   NHET / HET each can drive a whole bunch of pins from one timer - which is one reason they're unique.

    Still, if you really want to generate a simple periodic interrupt from NHET,  you could look at the NHET instruction "CNT".

    The syntax of CNT (From the Technical Reference Manual) is :

    CNT {
    [brk={OFF | ON}]
    [next={label | 9-bit unsigned integer}]
    [reqnum={3-bit unsigned integer}]
    [request={NOREQ | GENREQ | QUIET}]
    [angle_count={OFF | ON}]
    [reg={A | B | T | NONE}]
    [comp ={EQ | GE}]
    [irq={OFF | ON}]
    [control={OFF | ON}]
    max={25-bit unsigned integer}
    [data={25-bit unsigned integer]
    }

    all the fields with [] are optional so your program could be as simple as:

    START:   CNT {max = XYZ, irq=ON, data=0}

                     BR {event = NOCOND, cond_addr = START}

                                                             (note that I put the branch after CNT because a proper NHET program must be at least two instructions long...)

    XYZ would be replaced by your desired period - say 3 seconds divided by the Loop resolution period of the NHET.    A typical value for the loop resolution period could be 1-2us so even with the 25 bit value for max you should be able to reach 3 seconds...

    The field irq=ON means the CNT instruction generates an interrupt when it rolls over from max back to zero.    Internally, the NHET has multiple interrupt channels that it maps to two different interrupt lines going back to the CPU.    The channel number depends on the address of the CNT instruction in the NHET code; and there are control registers that need to be setup in the NHET, VIM, and CPU to enable the interrupt.  

    That's just a teaser for NHET in case you want to experiment.  Of course this program is too simple really for NHET and that's why RTI is a good choice.

    But if you every want to do something more interesting, like coordinate the delay with some IO activity - say interrupt the CPU whenever either a pin toggles or 3s which ever comes first, then this is where you might want to look at NHET.

     

  • Hi QJ,

    Thanks for your information. But if i want to use RTI, is it necessary need to configure VIM or not?

    Regards

    Gowdham

  • Hi Anthony,

    Thanks for your information. I am started to implement using RTI. But i will also try (using NHET) what you mentioned in your reply later.

    Regards

    Gowdham

  • Hi Gowdham,

    If you use RTI for delay only in your bootloader, you don't need interrupt.  Enclosed is a simple example for your reference. The code is not tested.

    Regards,

    QJ

    #define TIMER_LOAD_VAL 0xffffffff
    #define READ_TIMER (0xFFFFFFFF - *(volatile ulong *)(0xFFFFFC00 + 0x10))
    #define CFG_HZ  ( your vclk in Hz ) /*for example 80000000 (80MHz),*/


    //usec is micro-second, tmo is clock cycle
    void delay (unsigned int usec)
    {
     unsigned int tmo, tmp;

     if(usec >= 1000){ 
      tmo = usec / 1000;
      tmo *= CFG_HZ; 
      tmo /= 1000; 
     }else{    
      tmo = usec * CFG_HZ;
      tmo /= (1000*1000);
     }

     tmp = get_timer_masked();  /* get current timestamp */
     if( (tmo + tmp + 1) < tmp ){
      lastdec = READ_TIMER;  /* capure current decrementer value time */
      timestamp = 0;      
     } 
     else
      tmo += tmp; 

     while (get_timer_masked () < tmo)/* loop till event */
    }

    ulong get_timer_masked (void)
    {
     unsigned int now = READ_TIMER;  /* current tick value */

     if (lastdec >= now) {  
      /* normal mode */
      timestamp += lastdec - now;
     } else {
      timestamp += lastdec + TIMER_LOAD_VAL - now;
     }
     lastdec = now;

     return timestamp;
    }

  • Hi QJ,

    Thanks. i will test this code and give you the feedback. one more doubt while implementing RTI using the example code mentioned at the end of spna123.pdf (Generating Operating System Tick Using RTI on a TMSx70 Micro controller). In that code, they are implementing

    VIM_RAM_Init();                                       //VIM initialization
    RTI_irq_int_enable();                            //Enabling the RTI Interrupts in VIM
    swi_enable_irq() ;                                  //Int_irq_enable Enable only IRQ

    Out of these three functions, i implemented swi_enable_irq(); this function. but i don't know how to implement the other two. Please let me know how to do this.

    Regards

    Gowdham.

  • Hi QJ,

    Thanks. I will test this code and tell you the feedback. But i have some doubt while implementing the RTI using the example code given at the end of the document spna123.pdf (Generating Operating System Tick Using RTI on a TMSx70 Micro controller). In this i don't know how to implement the below mentioned functions,

    VIM_RAM_Init();                                              //VIM initialization
    RTI_irq_int_enable();                                   //Enabling the RTI Interrupts in VIM
    swi_enable_irq() ;                                         //Int_irq_enable Enable only IRQ

    Out of three i implemented swi_enable_irq(); this function. Please tell me how to implement the other two functions.

    Regards

    Gowdham

  • Hi Gowdham,

    I didn't read this appnote before. The sample code in the appnote (SPNA123.PDF) uses RTI INT for toggling GIO pins. Do you only use it for SW delay in your bootloader, right?

    For RTI INT enable function, 2 statement is enough. They are used to enable/disbale the INT for the module (RTI, DCAN, ..) and set the IRQ/FIQ priority for each INT. please refer to databook to understand the INT request assignment.

        /* set IRQ/FIQ priorities */
        vimREG->FIRQPR0 |=  (SYS_FIQ <<  1U)        
                        | (SYS_IRQ <<  2U)          /*2, RTI compare INT0*/
                        | (SYS_IRQ <<  3U)          /*3, RTI compare INT1*/        
                        | (SYS_IRQ <<  4U)          /*4, RTI compare INT2*/
                        | (SYS_IRQ <<  5U)          /*5, RTI compare INT3*/
                        | (SYS_IRQ <<  6U)          /*6, RTI overflow INT0*/
                        | (SYS_IRQ <<  7U)          /*7, RTI overflow INT1*/
                        | (SYS_IRQ <<  8U)          /*8, RTI Timebase*/

        /* enable interrupts */
        vimREG->REQMASKSET0 |= (1U << 2)             /*1: enable*/
                            | (0U << 3)              /*0: disable*/ 
                            | (0U << 3)
                            | (0U << 4)
                            | (0U << 5)
                            | (0U << 6)
                            | (0U << 7)
                            | (0U << 8); 

    For VIM_RAM_INT, you can use this way:

     

     

     

    typedef volatile struct vimRam
    {
        t_isrFuncPTR ISR[VIM_CHANNELS];
    } vimRAM_t;

    #define vimRAM ((vimRAM_t *)0xFFF82000U)    /*VIM RAM*/

    void VIM_RAM_Init(void)
    {
      int i;
      for (i=0;i < VIM_CHANNELS;i++)
     {
      vimRAM->ISR[i] = &phantomInterrupt;
     }
      vimRAM->ISR[2+1]   = &rtiCompare0Interrupt;      //ISR in your code
      vimRAM->ISR[21+1]  = &sciLowLevelInterrupt1;
      vimRAM->ISR[0+1]   = &esmHighLevelInterrupt;
      vimRAM->ISR[22+1]  = &can1HighLevelInterrupt;
      vimRAM->ISR[29+1]  = &can2HighLevelInterrupt;
    }

    Regards,

    QJ

  • Hi QJ,

    Thanks. I am Implementing the delay for bootloader only. But at the same time, i am trying to implement this RTI in my project. But when i used this VIM_RAM_Init function as it is, some error was thrown as "unresolved symbol" for below

    vimRAM->ISR[2+1]   = &rtiCompare0Interrupt;      //ISR in your code
      vimRAM->ISR[21+1]  = &sciLowLevelInterrupt1;
      vimRAM->ISR[0+1]   = &esmHighLevelInterrupt;
      vimRAM->ISR[22+1]  = &can1HighLevelInterrupt;
      vimRAM->ISR[29+1]  = &can2HighLevelInterrupt;

     

    i don't what it means. Please tell me how to proceed.


    Thanks

    Gowdham

  • HI Gowdham,

    You assigned the ISR address to the vimRAM table, so you need to define the ISR in your project too. Otherwsie, you will get errors.

    Regards,

    QJ