This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C123GH6PM: access to SysTick registers requires a delay?

Other Parts Discussed in Thread: TM4C123GH6PM, SYSBIOS

With SysTick configured to be clocked by PIOSC/4 and system clock driven by the PLL at 80MHz, it seems that a read to STCURRENT register returns an unexpected value, at least when followed by some writes to other SysTick registers. Adding a delay (in the form of an extra read) seems to fix the issue:

now = timer->STCURRENT;
timer->STCURRENT; /* delay (otherwise 'now' value is wrong: ~323000 instead of ~398000) */
timer->STRELOAD = newPeriodCounts;
timer->STCURRENT  = 0;

The datasheet for TM4C123GH6PM does not mention anything about a necessary delay upon SysTick register access, except an (unrelated) comment that a system clock of at least 8MHz is needed to access STRELOAD on page 138. The idea to delay came from the fact that the SysTick device is effectively in a separate slower clock domain from the core which is clocked by the system clock. If it is indeed necessary to delay, could we please find out by how much and for which register accesses specifically (the current fix is just a guess)?

Details that shouldn't be relevant: This is inside a modified SYSBIOS with a custom driver module for the SysTick device. Clock and TimestampProvider modified to consume the ITimer interface directly instead of through hal.Timer so that they can use the SysTick module. It later turned out that there's already a driver for SysTick in ti.sysbios.family.arm.m3.Timer as pointed out here [1], but it's not currently unused.

[1] http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/290322/1014038.aspx#1014038

  • Alexei Colin said:
    already a driver for SysTick in ti.sysbios.family.arm.m3.Timer as pointed out here [1], but it's not currently unused.

    Language & crafting of your post is excellent - till that final clause.  (highlighted w/in quote)

    Betting that [1] is not currently used!  (i.e. not & "un" form double negative...)

    Your logic seems sound - our group uses many ARM MCUs - many vendors - but not as you config & detail...

  • I can't be certain but this may be an ARM memory coherence problem (write after read hazard). Have you tried a memory barrier instead of a delay?

    I'm not a TI employee, this is just guesswork.

  • Basically, my code is broken and putting a delay somewhere hides the bug(s). On further investigation, a delay of various length in one of multiple different locations *appears to* fix the issue. A delay changes the timing of the code and causes the timer value to overrun at just the right time. By Murphy's law, that tiny delay of one memory load made the difference and appeared to fix the issue (I did triple check that it did before posting) -- after changing some unrelated code, that particular delay no longer "fixes" anything. To conclude, this has nothing to do with register access. Sorry for a spurious post.

    Thanks for the memory barrier suggestion (sounded like a good bet!). Neither of the three barrier instructions (dmb, dsb, isb) made a difference, which corroborates the above.