cancel
Showing results for 
Search instead for 
Did you mean: 

TIM1 registers read errata

ramon13666
Associate II
Posted on January 09, 2017 at 10:00

0690X00000605XvQAI.png

So, info in reference manual is irrelevant? The read should be always done as:

; Read Seq_1
ld A, TIM1_REGH;
ld XL, TIM1_REGL;�?�?�?

?

Will the following sequences lead to incorrect results?

; Read Seq_2
ldw X, #TIM1_REGH; Store in X address of TIM1_REGH
ld A,(X); Read TIM1_REGH
push A;
incw X; Set pointer to TIM1_REGL
ld A,(X); Read TIM1_REGH�?�?�?�?�?�?
; Read Seq_3
ldw X, #TIM1_REGH; Store in X address of TIM1_REGH
ld A,(X); Read TIM1_REGH
push A;
ldw X, #TIM1_REGL; Store in X address of TIM1_REGL
ld A,(X); Read TIM1_REGL�?�?�?�?�?�?�?�?
�?

#stm8-timer
5 REPLIES 5
Max
ST Employee
Posted on January 19, 2017 at 10:42

Hello,

In the three code snippets you are referring too, the only multiple cycle instruction is the INCW X you have in the Read seq_2

As a consequence Read seq_1 and Read seq_3 are OK, but you should not use Read seq_2 for 16-bit TIMer access.

This also means that the recommendation in the RM is correct.

If you want to check if an instruction execute in multiple cycles, please refer to

http://www.st.com/content/ccc/resource/technical/document/programming_manual/43/24/13/9a/89/df/45/ed/CD00161709.pdf/files/CD00161709.pdf/jcr:content/translations/en.CD00161709.pdf

.

The Table 42 page 64 to 74 has a column showing the number of cycles.

Let me know if this is still not clear

Posted on January 19, 2017 at 11:24

This is from doc linked by you:0690X000006065QQAQ.png0690X00000605yfQAA.png

1 cycle or 2? Where the truth?

And for Seq_3: ldw is 2 cycle instruction. It's used to load TIM1->CNTRL to index register.0690X000006065RQAQ.png0690X000006065VQAQ.png

in Seq_1 I've made mistake. LD could not load from memory to XL.

So, none of this three reads will assemble or return correct result.

Currently I'm using ''mov _store_mem, _read_mem

mov _cnt_hi, TIM1_CNTRH
mov _cc_hi, TIM2_CCR1H
mov _cnt_low, TIM1_CNTRL
mov _cc_low, TIM2_CCR1L�?�?�?�?

Does it get the job? Because I don't know how peripheral feature could be impacted by instruction size or exec time. And what if I have 5-10-20 single cycle instructions between reading High and Low registers?

Arlet Ottens
Associate II
Posted on March 19, 2017 at 13:19

I tried it out on a STM8S103F3P6 rev Y, and no matter what I do, I cannot get the timer read to return the wrong answer, as long as I read TIM1_CNTRH before TIM1_CNTRL. I even tried reading CNTRH, calling a function to write that value to the UART, reading CNTRL, and it was still correct. 

My test procedure: stop counter, write 0xffxx to CNTR, start counter, handful of NOPs, and then read CNTRH/CNTRL in various ways. Repeat with incrementing start value. At some point, you'll see the timer roll over. 

Dzor
Associate III

Is it not advisable to load both registers using ldw ?

Like this:

 

uint16_t tim3_last = *(const uint16_t *)&(TIM3->CNTRH);

 

 which produces:

 

 

    ldw x, 0x5328
    ldw (0x07, sp), x

 

 
Would MSB or LSB be loaded first by the hardware? 

RM0016 page 142: Do not use the LDW instruction to read the 16-bit counter. It reads the LS byte first and returns an incorrect result.