Pic32 port: timers and ticks

erupter wrote on Sunday, October 02, 2011:

I’m opening a new topic because I feel it doesn’t have much in common with my previous one.
Although all the research I’m doing stems from my other problems.

I’ve opened a Microchip demo (PIC32 starter kit timer interrupt):
they are using an undocumented 32bit counter, the CPU own internal counter referenced by undocumented macros

// configure the core timer roll-over rate (100msec)

    // set up the core timer interrupt with a prioirty of 2 and zero sub-priority
    mConfigIntCoreTimer((CT_INT_ON | CT_INT_PRIOR_2 | CT_INT_SUB_PRIOR_0));

// update the period

    // clear the interrupt flag

And it’s working.
By searching here and there, it comes out this is an internal feature of the MIPS core, separated from microchip’s own Timer1/5 timers.

I’m looking into it, but it seems the Tick should use this counter instead of a peripheral timer.
And given the resolution an the speed (fixed at half the clock) it could also be suitable for the stats generator.

I would have tried it myself, but the fact that the  ISR is in asm is blocking me: I don’t know asm.
I also can’t find any reference in the MCHP docs to anything in the following line
They don’t exist in the docs.

So can I use the CoreTimer to feed the stats?
Why it hasn’t been used for the tick?
What are the undocumented macros?


rtel wrote on Sunday, October 02, 2011:

There is nothing undocumented.  The core timer is part of the MIPS core, which is used by the PIC32.  It is very well documented in the MIPS manual.

I would strongly discourage use of the core timer as the tick interrupt source.  As I recall, it cannot be reset on a compare match interrupt, so you have to recalculate the compare match value by adding a constant to the previous compare match value on each tick interrupt - with disastrous consequences for the “real time”'ness of your application if a tick is missed (due to a critical section, or whatever).


erupter wrote on Sunday, October 02, 2011:

it isn’t documented by microchip which makes a demo available on it with config macros not depicted in any of its docs.
Also a reset is possible as stated here:

(Mips 4K Core Family Software User’s Manual)
5.2.8 Count Register (CP0 Register 9, Select 0)
The Count register acts as a timer, incrementing at a constant rate, whether or not an instruction is executed, retired, or
any forward progress is made through the pipeline. The counter increments every other clock.
The Count register can be written for functional or diagnostic purposes, including at reset or to synchronize processors

But I’m not familiar with the finer details about it to continue this discussion.
Would the core timer be ok for the stats generator?

FreeRTOS also uses this macro

I haven’t found mentions of it in any PIC32 related doc I could find.
Can you help me on this? What is it, where is it documented?

rtel wrote on Sunday, October 02, 2011:

The Count register can be written for functional or diagnostic purposes, including at reset or to synchronize processors

Resetting in software is no good for a timer tick interrupt source, as you will continuously suffer from clock slippage as the interrupt entry time will always be slightly different - especially when there is deep and frequent interrupt nesting, or critical sections are used.  The peripheral timer resets itself at the right time, so is not effected by anything the software is doing.

Would the core timer be ok for the stats generator?

Yes, because it is fine for the stats generator to free run - in fact, that is exactly what you want it to do.  Take care of the frequency of overflows though.

I haven’t found mentions of it in any PIC32 related doc I could find.

The latest C32 compiler has this defined in a file called int_legacy.h - which could explain why you cannot find it in the documentation.  I’m sure if this is now a legacy function there will be an alternative that is a current C32 equivalent.


erupter wrote on Monday, October 03, 2011:

thank you for the information.

I’ve encountered something I’m unable to explain.
There is demo available which I’m using as base.
It runs ok but I noticed something strange with the timings.

The Pic32 config is the following

#pragma config FNOSC    = PRIPLL        // Oscillator Selection
#pragma config FPLLIDIV = DIV_2         // PLL Input Divider (PIC32 Starter Kit: use divide by 2 only)
#pragma config FPLLMUL  = MUL_20        // PLL Multiplier
#pragma config FPLLODIV = DIV_1         // PLL Output Divider
#pragma config FPBDIV   = DIV_2         // Peripheral Clock divisor
#pragma config FWDTEN   = OFF           // Watchdog Timer 
#pragma config WDTPS    = PS1           // Watchdog Timer Postscale
#pragma config FCKSM    = CSDCMD        // Clock Switching & Fail Safe Clock Monitor
#pragma config OSCIOFNC = OFF           // CLKO Enable
#pragma config POSCMOD  = XT        // Primary Oscillator
#pragma config IESO     = OFF           // Internal/External Switch-over
#pragma config FSOSCEN  = OFF           // Secondary Oscillator Enable
#pragma config CP       = OFF           // Code Protect
#pragma config BWP      = OFF           // Boot Flash Write Protect
#pragma config PWP      = OFF           // Program Flash Write Protect
#pragma config ICESEL   = ICS_PGx2      // ICE/ICD Comm Channel Select
#pragma config DEBUG    = OFF           // Debugger Disabled for Starter Kit
#pragma config UPLLEN   = ON        // USB PLL Enabled
#pragma config UPLLIDIV = DIV_2         // USB PLL Input Divider
#pragma config FSRSSEL = PRIORITY_7     

while the Timer1 port config is this

void prvSetupTimerInterrupt( void )
const unsigned long ulCompareMatch = ( (configPERIPHERAL_CLOCK_HZ / portTIMER_PRESCALE) / configTICK_RATE_HZ ) - 1;
	OpenTimer1( ( T1_ON | T1_PS_1_8 | T1_SOURCE_INT | T1_SYNC_EXT_ON), ulCompareMatch );
	ConfigIntTimer1( T1_INT_ON | configKERNEL_INTERRUPT_PRIORITY );

and finally these are the config defines

#define configTICK_RATE_HZ				( ( portTickType ) 1000 )
#define configCPU_CLOCK_HZ				( ( unsigned long ) 80000000UL )  
#define configPERIPHERAL_CLOCK_HZ		( ( unsigned long ) 40000000UL )

The board crystal is 8Mhz, which is divided by the PLL-pre-scaler by 2, it then gets mutiplied by the PLL by 20 = 80 MHz.
The Peripheral clock is the system clock divided by 2 so 40 MHz.
So the actual fuse config match the defines.
Also the internal calculation give a rollover value for the timer 1 of 5000 which taking into account the 40 MHz peripheral clock, the divide-by-8 timer1 pre-scaler, makes for a 1 ms period.

Except that it’s not.
With a tickhook inverting a pin I see that the tick runs with a 500 ms period.

But the very same configuration in a clean project (just the timer and the interrupt routine on the very same led) runs with the correct 1000 ms period.

How can I track this discrepancy?

erupter wrote on Monday, October 03, 2011:

I’m sorry there is an error in the above.
The FreeRTOS timer1 period is 0.5ms, it’s twice as fast as the clean timer1 period which is 1 ms.

(is there a way to edit the posts? no button appear in my firefox)

erupter wrote on Wednesday, October 05, 2011:

Richard, may I ask you to comment on the last bit of my post?
I still haven’t figured out how the same board, with same fuses, can behave differently with the two firmwares.
I have the FreeRTOS tick interrupt running at 0.5ms and the simple interrupt routine running at 1ms.
Exactly same configuration.

erupter wrote on Monday, October 10, 2011:

Ok maybe I’m stupid but I can’t find a solution to this.
The oscillator, scalers and pll configurations are the same.
The timers configurations are the same.
Only thing that differs is the interrupt handler, but freertos one is in asm so I can’t compare it (I don’t know asm).
What can I do to track this?