• AVR Freaks

[FAQ]Core timer handler stops updating ?

Author
rletos
New Member
  • Total Posts : 29
  • Reward points : 0
  • Joined: 2008/10/16 04:56:31
  • Location: 0
  • Status: offline
2008/11/12 04:53:42 (permalink)
0

Core timer handler stops updating ?

Hi,
I am currently interfacing LCD Nokia 6610 with PIC32. As it requires 9bit SPI I wrote my own software SPI. It works, however I wanted the code to be as speedy as possible, so I tried to implement my own routines for millisecond/microsecond delay(), using core timer. I have written something like this:
...
#define FOSC                          80000000    // 8MHz / FPLLIDIV * FPLLMUL / FPLLODIV
#define TOGGLES_PER_SEC        1000                       
#define CORE_TIMER_PERIOD    (FOSC/2/TOGGLES_PER_SEC)  
...
volatile unsigned long milliseconds=0;

void __ISR(_CORE_TIMER_VECTOR,ipl1) CoreTimerHandler(void)
{
    mCTClearIntFlag();
    milliseconds++;       
    UpdateCoreTimer(CORE_TIMER_PERIOD);
}

void delay(volatile unsigned long msec)
{
    volatile unsigned long startTime;
    while(msec)
    {
        startTime=milliseconds;
        while (startTime==milliseconds);           
        msec--;   
    }
}
...

What I experience now is that sometimes call to delay() never comes back, usually in case bigger msec values, like 500 or 1000 are passed to.  When I then break into the debugger, my code stays looping on this line:
       while (startTime==milliseconds);
which means that global variable milliseconds is being no more updated by CoreTimerHandler. I fail to understand why...am I overlooking something obvious? Can perhaps someone shed light on this?
Thank you!

rosti



#1

12 Replies Related Threads

    Deenayd
    Super Member
    • Total Posts : 905
    • Reward points : 0
    • Joined: 2004/09/08 06:15:13
    • Location: Poland
    • Status: offline
    RE: Core timer handler stops updating ? 2008/11/12 05:11:57 (permalink)
    0
    Check IF flag for core timer (after breaking into debuger). Is it set? If so you've probably made something that prevents an interrupt from starting (like disabling interrupts or not clearing an IF flag of some equal or higher priority interrupt in it's handler).
     
    I hope you don't call the "delay" routine from an ISR...

    Slawek Piotrowski
    Rejestracja Czasu Pracy Ewidencja Czasu Pracy
    #2
    jamodio
    Super Member
    • Total Posts : 2197
    • Reward points : 0
    • Joined: 2006/03/01 19:29:13
    • Location: San Antonio, Texas
    • Status: offline
    RE: Core timer handler stops updating ? 2008/11/12 07:21:58 (permalink)
    5 (2)
     
    Here is the "classic" DelayMS() routine using the core timer.
     

    #define GetSystemClock()       (FOSC)
     
    //*****************************************************************************
    // DelayMs creates a delay of given miliseconds using the Core Timer
    //
    void DelayMs(WORD delay)
    {
        unsigned int int_status;
        while( delay-- )
        {
            int_status = INTDisableInterrupts();
            OpenCoreTimer(GetSystemClock() / 2000);
            INTRestoreInterrupts(int_status);
            mCTClearIntFlag();
            while( !mCTGetIntFlag() );
        }
        mCTClearIntFlag();
    }

     
    My .02
     

    Jorge Amodio - LJCV Electronics, San Antonio, Texas
    "If everything seems to be going well, you obviously overlooked something. Murphy's law"
    #3
    grahamfclark
    Starting Member
    • Total Posts : 55
    • Reward points : 0
    • Joined: 2008/08/02 07:33:59
    • Location: 0
    • Status: offline
    RE: Core timer handler stops updating ? 2008/11/12 15:15:43 (permalink)
    0
    This code below works for me. It's similar to yours but the ISR is called from an assembler wrapper as I'm using FreeRTOS. I can't see whay yours doesn't work unless it's due to your low interrupt priority, the use of lots of 'volatiles' or maybe the optimisation level? I only make coreTImerTicks volatile and run at ipl4.

    void  CoreTimerInterruptHandler(void) {
        asm("ei"); // allow nested interrupts
        mCTClearIntFlag();
        //update a tick timer
        coreTimerTicks++;   
        // reset the period
        UpdateCoreTimer(40000);
        portEND_SWITCHING_ISR( FALSE );
    }

    void  DelayMs(WORD time)
    {
        unsigned int currentTime;        // 32 bit value
        currentTime = coreTimerTicks;    
        while(time) {
            if ( currentTime != coreTimerTicks ) { // the timer has changed maybe by more than 1 tick but who cares
                currentTime = coreTimerTicks;
                time--;
            }
        }
    }

    #4
    JasonK
    Super Member
    • Total Posts : 3414
    • Reward points : 0
    • Joined: 2003/11/14 09:49:40
    • Location: Microchip Technology in Arizona, USA
    • Status: offline
    RE: Core timer handler stops updating ? 2008/11/12 16:28:59 (permalink)
    0
    Maybe this older thread will help.

    Jason Kajita
     Follow me on Twitter
    http://support.microchip.com for urgent questions
    #5
    rletos
    New Member
    • Total Posts : 29
    • Reward points : 0
    • Joined: 2008/10/16 04:56:31
    • Location: 0
    • Status: offline
    RE: Core timer handler stops updating ? 2008/11/14 16:27:33 (permalink)
    0
    Well, I changed now the priority and will do some more tests.
    Thanks for all your inputs!

    rosti

    #6
    lovlylion
    New Member
    • Total Posts : 15
    • Reward points : 0
    • Joined: 2008/02/15 16:29:50
    • Location: 0
    • Status: offline
    RE: Core timer handler stops updating ? 2008/12/01 13:36:32 (permalink)
    0
    Dear rletos,
     
    i need your code that interfacing Nokia Lcd with pic32
     
    i hope you help me
     
    Thanks
    #7
    rletos
    New Member
    • Total Posts : 29
    • Reward points : 0
    • Joined: 2008/10/16 04:56:31
    • Location: 0
    • Status: offline
    RE: Core timer handler stops updating ? 2008/12/04 06:08:24 (permalink)
    0
    Hi,

    my own code is based on information available here:http://www.sparkfun.com/commerce/product_info.php?products_id=569,
    is not ready yet, and is HW dependent. It still behaves murky, sometimes it works, sometimes it doesn't, I suspect compiler/debugger issue here as the behavior changes/toggles with code length.

    Please check the link above for available code.

    rosti
    #8
    Sciencefiction68
    Starting Member
    • Total Posts : 33
    • Reward points : 0
    • Joined: 2012/10/01 06:15:03
    • Location: 0
    • Status: offline
    Re: RE: Core timer handler stops updating ? 2012/10/20 17:23:40 (permalink)
    0
    hi. 
    I have 2 questions according to your code.
    1. 
    OpenCoreTimer(GetSystemClock() / 2000); Does dividing any System clock frequency by 2000 will give us delay in mSeconds ?? What if im not using 8 MHz crystal but 72MHz ?? 2.   int_status = INTDisableInterrupts();
             OpenCoreTimer(GetSystemClock() / 2000);
             INTRestoreInterrupts(int_status); Does this means that interrupts are going to be disabled during delay time??? What if want to have delay lasting 3 minutes and interrupts are crucial in my application?? thanks:)  
    #9
    rpg7
    Super Member
    • Total Posts : 1424
    • Reward points : 0
    • Joined: 2003/11/07 12:47:35
    • Status: offline
    Re: RE: Core timer handler stops updating ? 2012/10/21 00:54:34 (permalink)
    0
    Sciencefiction68
    1. 
    OpenCoreTimer(GetSystemClock() / 2000);
    Does dividing any System clock frequency by 2000 will give us delay in mSeconds ?? What if im not using 8 MHz crystal but 72MHz ??

    The the core timer runs at the system clock / 2.
    How long will it take to count (system clock / 2) ?
    How long will it take to count (system clock / 2000) ?
    If you run system clock at 10000Hz how long with it take to count (system clock / 2)  counts?
    If you run system clock at 12345678Hz how long with it take to count (system clock / 2)  counts?
     
    Sciencefiction68
    2.   int_status = INTDisableInterrupts();
           OpenCoreTimer(GetSystemClock() / 2000);
           INTRestoreInterrupts(int_status);
    Does this means that interrupts are going to be disabled during delay time??? What if want to have delay lasting 3 minutes and interrupts are crucial in my application??

    No.
    However, the example above  is a fairly poor method of implementing a delay.
    #10
    Muenchow
    Super Member
    • Total Posts : 282
    • Reward points : 0
    • Joined: 2012/02/20 02:25:22
    • Location: Bochum Germany
    • Status: offline
    Re: RE: Core timer handler stops updating ? 2012/10/23 07:33:42 (permalink)
    0
    rpg7
    However, the example above  is a fairly poor method of implementing a delay.

    Seriously, I don't understand any of the core timer code suggestions in this thread. A reasonable designed core timer based delay should allow interrupts and must not change the current core timer state, as discussed in may previous threads, e.g.: 

    http://www.microchip.com/forums/tm.aspx?tree=true&high=&m=652985&mpage=1#
    #11
    rpg7
    Super Member
    • Total Posts : 1424
    • Reward points : 0
    • Joined: 2003/11/07 12:47:35
    • Status: offline
    Re: RE: Core timer handler stops updating ? 2012/10/23 08:40:25 (permalink)
    0
    Muenchow Seriously, I don't understand any of the core timer code suggestions in this thread.

    They make sense if you are already using the core timer to generate (for example) a 1msec interrupt. But for a simple delay no.

    #12
    Bb63
    New Member
    • Total Posts : 28
    • Reward points : 0
    • Joined: 2011/02/21 12:35:43
    • Location: Germany
    • Status: offline
    Re: RE: Core timer handler stops updating ? 2013/01/28 05:14:58 (permalink)
    0
    Maybe my nanoseconds delay function is useful for somebody.
    configCPU_CLOCK_HZ is set to 8000000Hz (FreeRTOS configuration).
    The below macro will be inaccurate (wait a bit to long) if (configCPU_CLOCK_HZ / 2) is not a factor of 1000000000.
     
    /*
    ** Macro for delay in nanoseconds using the MIPS core counter assuming that
    ** the core counter is free running with half CPU clock and is never changed
    ** by software
    */
    #define scNsDelay( nsDelay )                    \
    {                                               \
       register unsigned int startCnt = _CP0_GET_COUNT(); \
       register unsigned int waitCnt = nsDelay / ( 1000000000 / (configCPU_CLOCK_HZ / 2) );  \
       while( _CP0_GET_COUNT() - startCnt < waitCnt ) ; \
    }
    Regards,
    Bernd
    #13
    Jump to:
    © 2021 APG vNext Commercial Version 4.5