Skip to content

Commit 6c47d77

Browse files
author
rze
committed
added example file calculating clkdiv-register in mp
1 parent 1e829a6 commit 6c47d77

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#https://forums.raspberrypi.com/viewtopic.php?p=1985859#p1984172
2+
#Changing frequency of SM while running
3+
4+
#https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf
5+
# see chapter 4.9.6. List of Registers
6+
#Clock divisor register for state machine N
7+
#Frequency = clock freq / (CLKDIV_INT + CLKDIV_FRAC / 256)
8+
9+
#31:16 INT - Effective frequency is sysclk/(int + frac/256). Value of 0 is interpreted as 65536. If INT is 0, FRAC must also be 0
10+
#15:8 FRAC - Fractional part of clock divisor
11+
#7:0 Reserved
12+
13+
import rp2
14+
from machine import freq, mem32, Pin
15+
from time import sleep
16+
17+
def sm_div_calc(target_f):
18+
if target_f < 0:
19+
div = 256
20+
elif target_f == 0:
21+
# Special case: set clkdiv to 0.
22+
div = 0
23+
else:
24+
div = freq() * 256 // target_f
25+
if div <= 256 or div >= 16777216:
26+
raise ValueError("freq out of range")
27+
return div << 8
28+
29+
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
30+
31+
def signal():
32+
wrap_target()
33+
nop()
34+
wrap()
35+
36+
def sm_div_ref(target_f):
37+
sm0 = rp2.StateMachine(0, signal, freq=target_f, set_base=Pin(26))
38+
SM0_CLKDIV = 0x50200000 + 0x0c8
39+
# convert to signed int value to unsigned int value
40+
if (mem32[SM0_CLKDIV]<0):
41+
return mem32[SM0_CLKDIV] + 2**32
42+
else:
43+
return mem32[SM0_CLKDIV]
44+
45+
print("freq():", freq())
46+
47+
# check if same results for example 2000 are calculated
48+
tf = 2000
49+
50+
#x = 0b10000000_00000000_00000010_00000000
51+
x = sm_div_ref(tf)
52+
im = 0b11111111_11111111_00000000_00000000
53+
fm = 0b00000000_00000000_11111111_00000000
54+
55+
i = (x&im)>>16
56+
f = (x&fm)>>8
57+
cf = freq() / (i + f / 256)
58+
59+
print("sm()", type(x), x, bin(x), i, f , cf, tf)
60+
61+
#using horuable's function to calc clock divider
62+
63+
div = sm_div_calc(tf)
64+
65+
i = (div&im)>>16
66+
f = (div&fm)>>8
67+
print("python",type(div), div, bin(div), i, f , cf, tf)
68+
69+
70+
71+
assert sm_div_ref(2000) ^ sm_div_calc(2000) == 0, "register values are different for freq 2000"
72+
73+
for f in [2000, 23413, 213123213, 123123,1000, 12323]:
74+
try:
75+
assert sm_div_ref(f) ^ sm_div_calc(f) == 0, "register values are different for freq "+str(f)
76+
except ValueError as e:
77+
print(e, "at frequency", str(f))
78+
79+
80+

0 commit comments

Comments
 (0)