When the forum posts were "converted", all "Code" sections got mangled.
Here are relevant ones (manually) reformatted in case they are useful for anyone wanting to run their own tests.
Tom Evans on Oct 11, 2010 10:19 PM
Here's the result or programming FOUR PITs at
the same time, all set to 500us timeout, but
using /1, /2, /4 and /8 prescaler (code provided later).
Once per second the code prints out the current values
of the MCF_PIT[0123]_PCNTR registers:
Test 0, PIF clear by Byte Write to PCSR
PITs now at 0x9B5E, 0x4DCD, 0x26F8, 0x1385
PITs now at 0x9B5D, 0x4DD3, 0x26FB, 0x1387
PITs now at 0x9B5D, 0x4DD3, 0x26FB, 0x1387
PITs now at 0x9B5D, 0x4DD3, 0x26FB, 0x1387
PITs now at 0x9B5D, 0x4DD3, 0x26FB, 0x1387
PITs now at 0x9B5D, 0x4DD3, 0x26FB, 0x1387
PITs now at 0x9B5D, 0x4DD3, 0x26FB, 0x1387
PITs now at 0x9B5D, 0x4DD3, 0x26FB, 0x1387
PITs now at 0x9B5D, 0x4DD3, 0x26FB, 0x1387
PITs now at 0x9B5D, 0x4DD3, 0x26FB, 0x1387
(All the PIT Counters are the same in this test)
Test 1, PIF clear by Word Write to PCSR
PITs now at 0x2332, 0x11BE, 0x08F0, 0x0482
PITs now at 0x06E1, 0x0395, 0x0223, 0x04D9
PITs now at 0x0EAC, 0x077A, 0x045E, 0x09B7
PITs now at 0x1671, 0x0B5C, 0x0696, 0x0E94
PITs now at 0x1E3E, 0x0F42, 0x08D0, 0x1371
PITs now at 0x2607, 0x1326, 0x0B0B, 0x04C6
PITs now at 0x2DD0, 0x170A, 0x0D44, 0x09A3
PITs now at 0x3599, 0x1AEE, 0x0F7E, 0x0E81
PITs now at 0x3D62, 0x1ED2, 0x11B8, 0x135F
PITs now at 0x452A, 0x22B5, 0x13F1, 0x04B4
(All the PIT counters are drifting, not keeping time)
Test 2, PIF clear by Write to PMR
PITs now at 0x79CE, 0x3D07, 0x2161, 0x0F2D
PITs now at 0x54B9, 0x2A7B, 0x17EC, 0x0993
PITs now at 0x5C80, 0x2E60, 0x19AC, 0x0995
PITs now at 0x644D, 0x3245, 0x1B6F, 0x0996
PITs now at 0x6C14, 0x362A, 0x1D2E, 0x0996
PITs now at 0x73E1, 0x3A0F, 0x1EF0, 0x0996
PITs now at 0x7BA8, 0x3DF4, 0x20AF, 0x099B
PITs now at 0x8375, 0x41D9, 0x2270, 0x099B
PITs now at 0x8B3C, 0x45BE, 0x2430, 0x09A1
PITs now at 0x9308, 0x49A3, 0x25F0, 0x09A1
The code that generated the above:
#define COUNT_US (MCF_DTIM3_DTCN)
#define DELAY_US(us) nTimeUs = COUNT_US; while ((COUNT_US - nTimeUs) < us) { ; }
#define MCF_PIT_PCSR_LB(x) (*(vuint8*)(0xFC080001+((x)*0x4000)))
void pitTest(void)
{
uint16_t old_ipl = asm_set_ipl(7);
uint32_t nTimeUs;
uint32_t nCount;
uint32_t nTest;
uint32_t nPit;
uint16_t nPcsr;
uint16_t nPcntr[4];
/* Initialise DMA Timer 3 to free-run at 1us as a timebase */
MCF_DTIM3_DTMR = MCF_DTIM_DTMR_CLK_DIV1 | MCF_DTIM_DTMR_FRR |
MCF_DTIM_DTMR_CE_NONE | MCF_DTIM_DTMR_RST | MCF_DTIM_DTMR_PS( 80 - 1 );
/* 80MHz/80 = 1MHz count */
/* Program all pits to 500us timeout, 4 different dividers */
MCF_PIT0_PCSR = MCF_PIT_PCSR_OVW;
MCF_PIT1_PCSR = MCF_PIT_PCSR_OVW;
MCF_PIT2_PCSR = MCF_PIT_PCSR_OVW;
MCF_PIT3_PCSR = MCF_PIT_PCSR_OVW;
MCF_PIT0_PMR = (40000 - 1);
MCF_PIT1_PMR = (20000 - 1);
MCF_PIT2_PMR = (10000 - 1);
MCF_PIT3_PMR = (5000 - 1);
nPcsr = MCF_PIT_PCSR_HALTED | MCF_PIT_PCSR_PIF |
MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_EN;
/* Enable them all, staggered at 1us */
MCF_PIT0_PCSR = nPcsr | MCF_PIT_PCSR_PRE(0);
/* Prescale off */
DELAY_US(1);
MCF_PIT1_PCSR = nPcsr | MCF_PIT_PCSR_PRE(1);
/* Prescale /2 */
DELAY_US(1);
MCF_PIT2_PCSR = nPcsr | MCF_PIT_PCSR_PRE(2);
/* Prescale /4 */
DELAY_US(1);
MCF_PIT3_PCSR = nPcsr | MCF_PIT_PCSR_PRE(3);
/* Prescale /8 */
nTimeUs = COUNT_US - (1000000L - 50000L);
/* Start in 50ms */
for (nTest = 0; nTest < 3; nTest++)
{
DEBUG(0, "Test %d, PIF clear by %s", nTest,
(nTest == 0) ? "Byte Write to PCSR" :
(nTest == 1) ? "Word Write to PCSR" :
"Write to PMR");
for (nCount = 0; nCount < 10; nCount++)
{
/* Wait for the rest of the second to pass */
while ((COUNT_US - nTimeUs) < 1000000L)
{
;
}
/* Read and print current counters */
nPcntr[0] = MCF_PIT0_PCNTR;
nPcntr[1] = MCF_PIT1_PCNTR;
nPcntr[2] = MCF_PIT2_PCNTR;
nPcntr[3] = MCF_PIT3_PCNTR;
DEBUG(0, "PITs now at 0x%04x, 0x%04x, 0x%04x, 0x%04x"
/* = %4d, %4d, %4d */,
nPcntr[0], nPcntr[1], nPcntr[2], nPcntr[3]
/*, nPcntr[1] - nPcntr[0],
nPcntr[2] - nPcntr[0], nPcntr[3] - nPcntr[0] */);
nTimeUs += 1000000L;
/* Set up for next time */
/* Wait for nearly a second to pass */
while ((COUNT_US - nTimeUs) < 999950L)
{
MCF_WTM_WSR=0x5555;
/* Watchdog is running, pat it */
MCF_WTM_WSR=0xAAAA;
for (nPit = 0; nPit < 4; nPit++)
{
if ((MCF_PIT_PCSR(nPit) & MCF_PIT_PCSR_PIF) != 0)
{
if (nTest == 0) /* Reset PIF by byte-write to PCSR */
{
MCF_PIT_PCSR_LB(nPit) |= MCF_PIT_PCSR_PIF;
}
else if (nTest == 1)/* Reset PIF by word-write to PCSR */
{
MCF_PIT_PCSR(nPit) |= MCF_PIT_PCSR_PIF;
}
else /* Reset PIF by reloading PMR */
{
MCF_PIT_PMR(nPit) = MCF_PIT_PMR(nPit);
}
}
}
}
}
}
asm_set_ipl(old_ipl);
DEBUG(0, "Test done, locking up...");
while (TRUE)
{
MCF_WTM_WSR=0x5555;
/* Watchdog is running, pat it */
MCF_WTM_WSR=0xAAAA;
}
}
Tom Evans Oct 12, 2010 12:38 AM
PIT is 80MHz / 32768 = 2441.4Hz or 409.6us
Modulus is "1" meaning "divide by 2".
Measuring 5000 cycles, expected value 4.096 seconds:
Test 0, PIF clear by Byte Write to PCSR
000.000 pitTest:460 Test 0 took 4096000us
Test 1, PIF clear by Byte Write to PCSR with Delay
000.000 pitTest:460 Test 1 took 4096000us
Test 2, PIF clear by Word Write to PCSR
000.000 pitTest:460 Test 2 took 4097562us
Test 3, PIF clear by Word Write to PCSR with Delay
000.000 pitTest:460 Test 3 took 5094800us
The "normal word write" resulted in an error of
4097.562/4096 = 1.00038 = 0.038% = 381ppm.
That's 11 counts in 32k, so the code took 11 clocks
to write to the PCSR and inadvertently reset the prescaler.
Waiting for 200us (out of the 491us period) and then
performing the word write resulted in an error of
5094.8/4096 = 1.2438 = 24% = 243,847ppm, which
might be a little more obvious!
Tom Evans Oct 31, 2010 6:58 AM
I followed your advice, and after 3 weeks received the following:
I talked with the apps team and they told me that the
redaction doesn’t seems to implies that writing the
same value to the PRE bits doesn't reset the timer.
Anyway they will review and make any necessary change
if necessary. Thanks in advance for your feedback.
Have a nice day.
Tom Evans Mar 1, 2011 1:57 AM
This is a gotcha that is addressed in AN3400, but only
MCF5213 users would be expected to find that App Note.
It would help if it AN3400 was referenced from all
Freescale Product Documentation Web Pages for all
Coldfire chips that have this PIT in it.
That would be simple to do, but hasn't been done either.