- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
HI,
I'm working with the CY8CKIT-049-42XX kit to develop a signal timing application, but I'm running into a nasty problem with a UDB 32-bit counter that I'm using to obtain time stamps of two external events. The UDB is configured as a free running up counter of 1MHz signal at the Count input. The clock is system clock @ 22MHz IMO (within specs as per the datasheet). The resulting counter resolution is therefore 1 microsecond.
I have one pin attached to a signal I call trigger that starts the events sequence. There is an ISR attached to this pin that takes the first reading from the counter with Counter_ReadCounter() into a global uint32 variable. It then enables the event capture Interrupt of the UDB counter in question. The second event signal which I call MEP is connected form a second pin to the Capture pin of the UDB. The associated ISR then reads the UDB status register and saves the event time stamp on a second global variable. Both ISRs also toggles an output pin ON and OFF so I can monitor the timing relationship of signals and ISRs physically on the scope.
Finally, the main loop monitors the event time variable and reports on the serial port both times and the time difference in microseconds. The time between both events hovers around 100 milliseconds (signal sources are not precise on purpose), and the scope confirms that the readings are in agreement …. MOST OF THE TIME.
THE PROBLEM
After much trial and error, changing interrupt priorities and other things and logging data I nailed down the problem to the following: Sometimes the high word of the event captured is incorrect. Actually the high word of the counter SHOWS THE VALUE OF TWO READINGS BACK. It sounds like a double buffering of the counter gets out of sync. Below is an excerpt of sample logs at different times where you can see the retro values. I have seen this also in the Counter_ReadCounter() as well, but since according to the documentation internally it also uses the capture mechanism the problem is the same. Here are the samples:
Capture: 2786E0D, ReleaseTime: 276C3CD, Offset: 109120
Capture: 2871F0A, ReleaseTime: 285751C, Offset: 109038
Capture: 278EBAF, ReleaseTime: 294417B, Offset: 4293175860 (bad capture time high word == of high word of two records back)
Capture: 3F47D89, ReleaseTime: 3F2D25F, Offset: 109354
Capture: 402C081, ReleaseTime: 4011632, Offset: 109135
....
Capture: AB7E4076, ReleaseTime: AB7CA3AC, Offset: 105674
Capture: AB82C60D, ReleaseTime: AB812C1B, Offset: 104946
Capture: AB7E40F8, ReleaseTime: AB862BE5, Offset: 4294448403 (bad capture time high word == of high word of two records back)
Capture: AB8CE0B5, ReleaseTime: AB8B45DF, Offset: 105174
Capture: AB91E416, ReleaseTime: AB904987, Offset: 105103
....
Capture: F1AF6C85, ReleaseTime: F1AE0BA8, Offset: 90333
Capture: F1B36113, ReleaseTime: F1B212B1, Offset: 85602
Capture: F1B86902, ReleaseTime: F1B6F36E, Offset: 95636
Capture: F1B37AB9, ReleaseTime: F1BC3A5A, Offset: 4294393951 (bad capture time high word == of high word of two records back)
Capture: F1C12F31, ReleaseTime: F1BFF240, Offset: 81137
Here are the trigger and capture ISRs:
//-------------------------------------------------------
// Trigger signal ISR - (interrupt priority 1)
//-------------------------------------------------------
CY_ISR(Trigger_ISR) // ~3.5 us from Trigger pin signal to raising edge to TP0
{
TP0_Write(1u); // start of pulse @ 3.5 us _|-|_ @ 22MHz IMO
/* uint8 intrSrc = */ // not need to find out which pin interrupted if only one pin interrupt is used.
TRGIN_ClearInterrupt();
MEP_TIMER_SetInterruptMode(0); // Disable interrupts
ReleaseTime = MEP_TIMER_ReadCounter(); // Get trigger in progress GENERATES INTERRUPT (documentation is incorrect)
MEP_TIMER_ReadCapture(); // Clear FIFO ( it seems that sometimes this reading remains in the FIFO)
MEP_TIMER_ReadStatusRegister(); // remove interrupt
MEP_TIMER_SetInterruptMode(MEP_TIMER_STATUS_CAPTURE_INT_EN_MASK| MEP_TIMER_STATUS_OVERFLOW_INT_EN_MASK );
TP0_Write(0u); // _|-|_ end of pulse ~15.5 us @ 22MHz IMO
}
//-------------------------------------------------------
// MEP Timer ISR (interrupt priority 1)
//-------------------------------------------------------
CY_ISR(MEP_Timer_ISR)
{
char mep_str[200];
TP1_Write(1u);
MEP_TIMER_SetInterruptMode(0); // Disable interrupts
uint8 status = MEP_TIMER_ReadStatusRegister(); // Clears the interrupt
do
{
if ((status & MEP_TIMER_STATUS_CAPTURE) )
{
MEP_Capture_Time = MEP_TIMER_ReadCapture();
}
if ((status & MEP_TIMER_STATUS_FIFONEMP) )
{
/* MEP_Capture_Time =*/ MEP_TIMER_ReadCapture();
}
if ((status & MEP_TIMER_STATUS_CMP) )
{
uint32 ct = MEP_TIMER_ReadCounter();
sprintf(mep_str,"Compare trigger at: %lu\r\n", ct);
UART_2_UartPutString(mep_str);
}
if ((status & MEP_TIMER_STATUS_OVERFLOW) ) // Hour rollover
{
TimerHours++;
sprintf(mep_str,"MEP timer Roll over: %ld\r\n", TimerHours );
UART_2_UartPutString(mep_str);
}
status = MEP_TIMER_ReadStatusRegister();
} while(status & (MEP_TIMER_STATUS_OVERFLOW|MEP_TIMER_STATUS_CMP|MEP_TIMER_STATUS_CAPTURE|MEP_TIMER_STATUS_FIFONEMP));
MEP_TIMER_SetInterruptMode(MEP_TIMER_STATUS_OVERFLOW_INT_EN_MASK); // Keep rollover interrupt only
TP1_Write(0u); // _|-|_ pulse 2 ~15.5 us @ 22MHz IMO
}
- Labels:
-
PSoC 4 Architecture
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Guillermo Gallo,
ThePlease use the latest version of PSoC Creator i.e PSoC Creator 4.2 to build your application to resolve the issue.
Thanks
Ganesh