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.

Hercules RM48L942 RTI1 ISR Does not trigger.

Other Parts Discussed in Thread: HALCOGEN

Hi. We are using the RM48L952ZWT Hercules platform. The RTI1 ISR does not trigger and I wanted to check if there is something we missed in HalCoGen to trigger the RTI (I have set up breakpoint in CCS and the ISR function (rtiNotification) in notification.c is never called. Thank you. I have uploaded our HalCoGen project here (we are using version 04.03.00):5873.HalCoGen.zip

  • Hi Tammy,

    rtiNotification in notification.c isn't actually the ISR.

    This ISR is going to be one of rtiCompare0Interrupt, rtiCompare1Interrupt, rtiCompare2Interrupt, rtiCompare3Interrupt, rtiOverflow0Interrupt, rtiOverflow1Interrupt or rtiTimebaseInterrupt (hopefully I didn't miss one). These functions can be found in rti.c. You may want to confirm whether or not you are getting into any of these ISRS. These ISRs then in turn call rtiNotification with a parameter indicating the interrupt source.

    If you are not getting into the actual ISR then you should check to see if there is an interrupt flag set in the RTI module (RTIINTFLAG).
    If no flag - then the RTI configuration needs to be checked.

    If there's a flag - then check the bit in (INTREQ[0]) that is tied to the RTI to see if the VIM sees the request. If VIM sees this request but doesn't create an interrupt to the CPU then something in the VIM needs to be configured.

    Best Regards,
    Anthony
  • Hi Anthony. Thank you for your guidance -- I now have test triggering looping every 280msec on RTI1. But it was in a wierd way as follows with the HalCoGen set up I uploaded for you - does this look Ok to you?:

    [...]
    DisableInterrupt(4u); /* Enable VIM interrupt channel */

    //Setup RTI period rtiCompare2 = 2 in rti.h and Timeout = 150000
    rtiSetPeriod(rtiCOMPARE2, TIMEOUT);

    //Update compare register based on associated block time
    rtiREG1->CMP[rtiCOMPARE2].COMPx = rtiREG1->CNT[rtiCOUNTER_BLOCK1].FRCx + TIMEOUT; //timeout = 150000

    //Enable RTI compare 2 notification = 4u in rti.h
    rtiEnableNotification(rtiNOTIFICATION_COMPARE2);

    EnableInterrupt(4u); /* Enable VIM interrupt channel */

    /* Start RTI Counter Block 0 */
    rtiStartCounter(rtiCOUNTER_BLOCK1); //rtiCOUNTER_BLOCK1 = 1
    [...]
    -------------------

    1. I could not figure out a less complex way to retrigger the ISR, after it was already triggered with doing the above each time. Is there a more recommended way?

    2. Why does 150000 = a period of 280 msec?

    3. We want to use all 3 RTIs (incl. having a watch dog). How do we select which rtiCompare and which rtiCounter_Block to use with which RTI (1,2, or 3)? I did this as a test, but is the recommendation?

    Thank You Again.
  • Hi Tammy,

    You shouldn't need to do what's listed above.    The update compare register should be added to the compare register whenever there is a compare match.   This is different than some RTIs where the counter is reset on a compare match.   the 570 RTI counters always increment freely.  When the compare matches the period (update compare register) is added to the compare register to compute the compare value for the next period.

    In other words, this line of code:

    rtiREG1->CMP[rtiCOMPARE2].COMPx = rtiREG1->CNT[rtiCOUNTER_BLOCK1].FRCx + TIMEOUT; //timeout = 150000

    Should be handled for you by the Update Compare register hardware and adder.   You shouldn't need to write directly to the compare register.  

    So

    Tammy Noergaard said:
    1. I could not figure out a less complex way to retrigger the ISR, after it was already triggered with doing the above each time. Is there a more recommended way?

    May just be an issue of writing to the wrong register.  You should be writing tothe update compare register,  not the compare register.

    Tammy Noergaard said:
    2. Why does 150000 = a period of 280 msec?

    It shouldn't as far as I can tell from your HalCoGen file which shows a 10MHz time base for the RTI counter.
    But it may be a side-effect of how you are retriggering the RTI.

    Tammy Noergaard said:
    3. We want to use all 3 RTIs (incl. having a watch dog). How do we select which rtiCompare and which rtiCounter_Block to use with which RTI (1,2, or 3)? I did this as a test, but is the recommendation?

    HalCoGen's 'Comp0 Source, Comp1 Source, Comp 2 Source, Comp 3 Source switch boxes on the RTI Compare Tab handle this for the compares.   The watchdog is separate from the RTI compares.

  • Hi Anthony. Thank you. Forgive me for not clarifying. The reason is we do not want this particular RTI to trigger while certain events are happening (which is why I was resetting the timing manually if the event happens within the timeframe). Is there a better way to do it if I do not want the RTI to trigger as along as the event is happening within the timeout period, then manually changing the value of the register like you describe above?
  • Tammy,

    If that's what you want - I would recommend disabling the interrupt in the VIM during the blackout period.
    Then either clear the interrupt flag and re-enable (if you don't want to service any RTI compares that occurred during this period)
    or just re-enable if you do want to service them.
  • Or I should add - if you do that above this will keep the RTI period constant but you will either delay or miss servicing.

    If you do not want a constant RTI period, then you should write the new period value to the update compare register.
    When the current RTI period finishes, the new period will take effect.

    If your application cannot 'wait' for the current RTI period to complete, then you need to read the free running counter, add the desired period to it, and write this back to the actual compare register. But this is dangerous in the sense that you are then bypassing the double-buffering provided by the update compare register. The RTI will continue to count between the read and the write, and if the RTI counter value passes the compare register value it will be a long time (counter rollover) before the compare matches.

    Depending on how complex the use case is - it may be something better offloaded to a more flexible timer like N2HET.
  • Hi Anthony. Thank you.

    We will change the ddesign plan to allow the RTI to complete then as you recommend.

    So if we want the same period for the RTI0 to trigger and i.e., the RTI ISR to go off every 2msec for example I would in my code:

    rtiSetPeriod(rtiCOMPARE0, 20000); //Setup RTI period , 10,000 ticks = 1 msec
    rtiEnableNotification(rtiNOTIFICATION_COMPARE0); //Enable RTI compare 0 notification
    BSP_InterruptEnable(2u); /* Enable VIM interrupt channel 2 = RTI0*/
    rtiStartCounter(rtiCOUNTER_BLOCK0);

    Is this what you mean? I am using the HalCoGen generated rtiSetPeriod, rtiEnableNotification and rtiStartCounter functions. Is this enough to set the RTI to go off every 2msec? Thank you again.
  • Hi Anthony did you get my reply? The RTI is critical for us, and we are a few weeks away from release so I hope you can make time to help with your workload, for us to get the RTI working properly.

    Question is if we want the same period for the RTI0 to trigger and i.e., the RTI ISR to go off every 2msec for example I would in my code:

    rtiSetPeriod(rtiCOMPARE0, 20000); //i.e., Setup RTI period , 10,000 ticks = 1 msec
    rtiEnableNotification(rtiNOTIFICATION_COMPARE0); //Enable RTI compare 0 notification
    BSP_InterruptEnable(2u); /* Enable VIM interrupt channel 2 = RTI0*/
    rtiStartCounter(rtiCOUNTER_BLOCK0);

    i.e, how can we calculate accurately the ticks to timing ratio? Is it 10,000 ticks = 1 msec? The rti routines above are autogenerated by HalCoGen in rti.c.

    Thank you again.
  • Hi Tammy,

    Sorry, I've been out of the office since Friday just getting back today.

    I have been playing w. a simple program to measure interrupt latency and it generates a periodic interrupt with the RTI Compare 0 with just these calls in main():

    void main(void)
    {
    /* USER CODE BEGIN (3) */
    rtiInit();
    rtiStartCounter(rtiCOUNTER_BLOCK0);
    rtiEnableNotification(rtiNOTIFICATION_COMPARE0);
    _enable_interrupt_();
    while(1);
    /* USER CODE END */
    }

    Which basically matches what you have above.

    You're using Micrium's OS - correct? I forgot that until I noticed the BSP_InterruptEnable(2u); call..

    If so then there's a very good chance the OS is already using the RTI and so the trickiest part will be not stepping on a resource already in use. For example good chance that Compare0 is being used for the OS tick.

    Let me know the OS answer please - because if you've got the OS there I think it should be able to give you a 2ms event without you needing to access the RTI directly; and that could be a cleaner solution.

    -Anthony
  • Hi Anthony. Thank you. We are happy you are back. Yes your TI drivers/ISRs are registered in the uC-OS BSP but not much else happens using the OS (the uCOS usually just call the HalCoGen generated drivers), and so far we have had no problems with the other ISRs. We have not tried using the ISRs before now. Thank you for the code example -- but where did you set the 2msec value for the ISR to trigger on? I thought this is why we had to call the "rtiSetPeriod" function as well...
  • Hi Tammy,

    I set the RTI compare period directly in HalCoGen through the GUI so that I didn't need to call the set period function, but it's fine to

    call the function rather than rely on the initial RTI settings. 

    My halcogen RTI configuration looks like this:

    So 1ms is calculated from the RTI clock running at 75MHz with a prescale of /8  (7 in UC compare). 

    75Mhz/8 = 9.375 MHz counter rate.   If there are 9,375,000 counts per second,  then in 1ms (1/1000 sec) there

    are 9375 counts.   That value is used in the Update Compare 0 and Compare 0 register.

    Still I would really investigate getting your timebase not from the RTI directly but from uCOS.

    The OS should theoretically *own* the RTI because it's needed for the OS tick.
    You should be able to use OS services to create time-based tasks ..

    If you try to use COMPARE0 you may wind up colliding with the RTOS's use of this resource.


    I don't know exactly which compare the RTOS is using but that would be something to check.


    Now our RTI has 4 comparators so that you are not limited to *only* time based events that are multiples of the OS tick.

    What I don't know is whether these other 3 comparators are exposed through Micrium's BSP or if you have to work around

    and go directly to the RTI control registers in order to use them.



    If I had to guess - it would be most likely that uCOS is using RTI Compare 0 for a tick and not using Compare 1,2,3 for anything.

    But this really depends on the uCOS port and I'd suggest asking Micrium to confirm which RTI resources they are using,  and

    advise on how to best create your 2ms task.


    The RTOS is providing you abstraction of the HW for things like time triggered tasks - so you should really try to use this capability especially for something 'slow' at a 2ms rate.   That way you have less chance of conflicts w. the RTOS and you gain the portability it provides you.   That's my opinion anyway.

    Best Regards,

    Anthony

  • Hi Anthony, Thank you then that is probably why we have seen wierd behavior. Where did we find what comparator and RTI (0,1, or 2) that that uCOS is using?

  • Hi Tammy,

    It would be somewhere in the uCOS code. Might be in the BSP folder.
    This question I would route to Micrium as it's their code and they know it the best.

    But in the meantime you may want to just try their published APIs for timers
    (per link in above post) .. Normally the common tick interrupt that is probably already
    there is used to periodically activate other processes like 'timers' so as long as your tick
    can divide into 2ms evenly you should be in good shape.

    Best Regards,
    Anthony
  • Hi Anthony. Thank you for your guidance. I just wrote to Micrium and will keep you posted. Thank You again.
  • Hi Anthony. Going through with micrium their uCOSII code now to figure out what they are doing with what RTI. Question how should these pair up when we want to use the various 4 possible RTIs (0,1,2, or 3) in terms of the 2 Blocks (0 or 1), and Notification_Compares (0,1,2, or 3). i.e.,s should RTI0 use rtiCOMPARE0 and rtiNOTIFICATION_COMPARE0. And RTI1 use rtiCOMPARE1 and rtiNOTIFICATION_COMPARE1 and so on? What about which rtiCOUNTER_BLOCK0/1 should we use with which RTI?

    from HalCoGen rti.h:

    #define rtiCOUNTER_BLOCK0 0U
    #define rtiCOUNTER_BLOCK1 1U

    #define rtiCOMPARE0 0U
    #define rtiCOMPARE1 1U
    #define rtiCOMPARE2 2U
    #define rtiCOMPARE3 3U


    #define rtiNOTIFICATION_COMPARE0 1U
    #define rtiNOTIFICATION_COMPARE1 2U
    #define rtiNOTIFICATION_COMPARE2 4U
    #define rtiNOTIFICATION_COMPARE3 8U
  • Hi Tammy,

    Yes you have the COMPARE's paired up with their ISRs correctly.

    The counters don't pair in any fixed way with the compares, each compare can be configured to compare against either counter 0 or counter 1. There are two counters because you may want a timebase that is related to 'network time' in addition to the local timebase.

    You can see which counter each of the compares is comparing against by looking at the RTI-RTI1 Compare tab.
    There is a checkbox in the lower left of each comparator that allows you to select between counter 0 or counter 1 as input.
    You can select these as you see fit - (with the exception of making sure you don't violate any assumptions about the RTI that the OS port may make).

    But... just to keep poking at this... do you think it's best to go around the OS in this case and try to take the RTI interrupt directly?
    [this may be required in some cases but I don't understand your particular use case and my instinct would be leaning toward relying on the OS's timers].

    Thanks and Best Regards,
    Anthony
  • Hi Anthony. It is good you are asking and we appreciate it. There could be a bigger bug in our software then we thought (or how uCOSII has been configured), we need to resolve it then properly. The reason is when we hooked up a scope and measured using the uCOSII timer function call (we just toggled an output port), the timer was way off sometimes almost double the period (i.e, we want 50msec and we do not get the timer triggering until 80msec). when we did the same using the RTI -- it is hard real time precise which we need hard real time. I do not think uCOSII is hard realtime, only soft real time? Or should it be hard realtime and we should solve this issue with their timing and using the OS timers? Thank you again Anthony.
  • Hi Tammy,

    I don't really see why the OS shouldn't be able to give you a hard '50ms' interrupt except for the fact that the OS is going to evaluate pending objects in some priority order. It sounds like the issue may be that the timer doesn't have the high priority that you want it to have. There may be some setting or API call in uCOS that you can make to adjust the priority - I'd definitely ask that question to Micrium.

    I'm also concerned about ownership of the RTI being shared between the OS and your application. It *shouldn't* be a problem the way that the hardware is defined, but that statement relies heavily on the RTI BSP code being carefully written so that the timebases are never reset and the flags of compares not being used by the OS are not touched.

    EDIT:  I should add that I would also assume in this case that you have the tick period for the OS set < 50ms and in a way that divides evenly into 50ms  if you want to implement a 50ms timer.

  • Hi Anthony, Just as you predicted Micrium tweaked their code to use the HalCoGen settings and all is Ok now around their timers. Thank you again.