MPC574xG STM behavior

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MPC574xG STM behavior

1,313 Views
martinfroschham
Contributor I

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

4 Replies

793 Views
ankur_kala
NXP Employee
NXP Employee
This behavior is explained in the note attached to the STM count register explanation. Copying from the RM section 52.4.2:
 
52.4.2 STM Count Register (STM_CNT)
The STM Count Register holds the timer count value.
NOTE
Due to two clock sources and different clock domains, Values
in this field can lag behind the internal counter value for up to
six system plus eight counter clock cycles. Therefore, the value
read from this field immediately after may be lower than the
actual value of the internal counter.
 
This would explain if the customer reads the CNT value and adds a small delay it would effectively mean that it's not a future value but one from the past.
Regards,
Ankur
0 Kudos

793 Views
davidhaworth
Contributor I

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.

0 Kudos

793 Views
martinfroschham
Contributor I

OK, after further investigation the derivative was the MPC5746C_1N84S. So the controller is affected by e10200. But did this issue explain that behavior?

793 Views
davidhaworth
Contributor I

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?

0 Kudos