Hello,
we noticed a strange behavior when using the STM Unit of an MPC574xG (1N81M) that we cannot explain. If we write a compare value a short time before the STM counter reaches the value, it seems that no interrupt is generated.
We have the following sequence. The intention is to set the next trigger point either in the future or immediately if counter already passed the point in time:
/* Set the compare value and trigger a the STM interrupt if compare value is already in the past.
* Hint:
* The timer range is split into three parts in order to differenciate between future, now and past.
* now = current tick value of counter
* past = half timer cycle behind now (range: now-0x80000000 ... now-1)
* future = half timer cycle after now (range: now+1 ... now+0x7FFFFFFF)
*/
void SetCompareValue(uint32 CompareValue)
{
uint32 now;
/* Write compare value to hardware */
*(volatile uint32*)(0xFC068018) = CompareValue; /* Write STM_CMP */
/* Get the current counter value */
now = *(volatile uint32*)(0xFC068004); /* Read STM_CNT */
/* Trigger the timer interrupt if the compare value is already in the past or now. */
if(((CompareValue - now) <= 0x80000000) || (CompareValue == now))
{
TriggerInterruptInPeripheral_STM();
}
}
In the case the compare value is set a short time before the counter reaches the value it seems that no interrupt is generated. But the condition below that checks that the compare valued was set to a value in the past also does not match. So also no manual interrupt triggering is done.
When reading back the STM_CMP register before getting the current counter value STM_CNT removes the effect, but we are not sure if we eliminate the root cause by doing that or if it simply change the runtime behavior that way that it not occurs in this situation.
Replacing the read back by a mbar synchronization instruction is not successful.
So my questions is, can this behavior be explained somehow? And if yes, is the read back of the compare value a general solution?
I also noticed an issue (e10200) in the errata of the Chipmask 0N78S where there might be a connection. So is the 1N81M affected as well?
Best Regards
Martin
Does it really explain my problem? In my case I have already written a value into the CMP register, and I want to know if the counter value afterwards is higher than the value that I have already written. I am *not* reading the counter, adding a small number of ticks then writing the comparator.
If this behavior is the cause of my problem, it means that the processor is predicting my read operation and setting it in motion before the instruction is executed.
OK, after further investigation the derivative was the MPC5746C_1N84S. So the controller is affected by e10200. But did this issue explain that behavior?
I've also observed this problem on MPC5746C - exact mask not yet known. Except in our case we handle the "in the past" case purely in software.
I added code to save the last-known counter value ("now" in this case) to a global variable. When the timer failed to trigger the compare value was usually a few ticks (6 or so) in the future, relative to the global variable.
I also tried adding mbar. That apparently made the problem less likely to occur.
I tried adding a read-back from the CMP, but I'm told that didn't work either, although I never got chance to confirm it first-hand.
My current workaround is
do { asm("msync"); } while ( STM_CMP != CompareValue );
just after writing the compare value.
I too would like to know if this is a real fix or has it just moved the problem. I already know that the symptoms are very time-sensitive: adding code to toggle a GPIO pin in strategic places can also make the symptoms disappear in this particular case.
Traditionally, the STMs were always behind the peripheral bridge. On this derivative it isn't clear where they sit on the bus. If you take the block diagram in the ref. manual literally, they aren't connected at all. :-(
Update [2017-12-07] In my case the exact derivative is marked SPC5746CSMKU6, 1N06M, QAJ1637H. I assume the mask is 1N06M. Is that also affected by the errata?