It’s all about the clocks it would seem, for anything nontrivial. Need to first understand the default configuration for micropython
to prevent locking up the MCU as soon as you touch it. In this case working on the ItsyBitsy M4 as an exemplar of the platform.
Code to probe the Generic Clock Controller registers which control the clocks and peripheral links:
from machine import mem32
GCLK_BASE = 0x40001C00
# clock configuration - § 14.8.3
def print_clock_register(register):
div = register >> 16
conf = (register & 0xff00) >> 8
src = register & 0xf
en = bool(register & (1<<8))
print(f"Divider: {div}\nConf: {conf:08b}\nSrc: {src}\nEnabled: {en}")
for j in range(12):
reg = mem32[GCLK_BASE + 0x20 + 4 * j]
print(f"Clock {j}")
print_clock_register(reg)
print()
# peripheral configuration - §14.8.4
for j in range(48):
reg = mem32[GCLK_BASE + 0x80 + 4 * j] & 0xff
wrtlock = bool(reg & (1<<7))
en = bool(reg & (1<<6))
gen = reg & 0xf
print(f"Peripheral {j}")
print(f"Write lock / enable: {wrtlock} / {en}")
print(f"Generator: {gen}")
print()
Default config looks like:
Clock 0
Divider: 0
Conf: 00100001
Src: 7
Enabled: True
Clock 1
Divider: 1465
Conf: 00000001
Src: 6
Enabled: True
Clock 2
Divider: 1
Conf: 00100001
Src: 6
Enabled: True
Clock 3
Divider: 3
Conf: 00100001
Src: 6
Enabled: True
Clock 4
Divider: 0
Conf: 00000000
Src: 0
Enabled: False
Clock 5
Divider: 1
Conf: 00100001
Src: 6
Enabled: True
Clock 6
Divider: 0
Conf: 00000000
Src: 0
Enabled: False
Clock 7
Divider: 0
Conf: 00000000
Src: 0
Enabled: False
Clock 8
Divider: 0
Conf: 00000000
Src: 0
Enabled: False
Clock 9
Divider: 0
Conf: 00000000
Src: 0
Enabled: False
Clock 10
Divider: 0
Conf: 00000000
Src: 0
Enabled: False
Clock 11
Divider: 0
Conf: 00000000
Src: 0
Enabled: False
Peripheral 0
Write lock / enable: False / False
Generator: 0
Peripheral 1
Write lock / enable: False / True
Generator: 1
Peripheral 2
Write lock / enable: False / False
Generator: 0
Peripheral 3
Write lock / enable: False / False
Generator: 0
Peripheral 4
Write lock / enable: False / False
Generator: 0
Peripheral 5
Write lock / enable: False / False
Generator: 0
Peripheral 6
Write lock / enable: False / False
Generator: 0
Peripheral 7
Write lock / enable: False / False
Generator: 0
Peripheral 8
Write lock / enable: False / False
Generator: 0
Peripheral 9
Write lock / enable: False / True
Generator: 3
Peripheral 10
Write lock / enable: False / True
Generator: 5
Peripheral 11
Write lock / enable: False / False
Generator: 0
Peripheral 12
Write lock / enable: False / False
Generator: 0
Peripheral 13
Write lock / enable: False / False
Generator: 0
Peripheral 14
Write lock / enable: False / False
Generator: 0
Peripheral 15
Write lock / enable: False / False
Generator: 0
Peripheral 16
Write lock / enable: False / False
Generator: 0
Peripheral 17
Write lock / enable: False / False
Generator: 0
Peripheral 18
Write lock / enable: False / False
Generator: 0
Peripheral 19
Write lock / enable: False / False
Generator: 0
Peripheral 20
Write lock / enable: False / False
Generator: 0
Peripheral 21
Write lock / enable: False / False
Generator: 0
Peripheral 22
Write lock / enable: False / False
Generator: 0
Peripheral 23
Write lock / enable: False / False
Generator: 0
Peripheral 24
Write lock / enable: False / False
Generator: 0
Peripheral 25
Write lock / enable: False / False
Generator: 0
Peripheral 26
Write lock / enable: False / False
Generator: 0
Peripheral 27
Write lock / enable: False / False
Generator: 0
Peripheral 28
Write lock / enable: False / False
Generator: 0
Peripheral 29
Write lock / enable: False / False
Generator: 0
Peripheral 30
Write lock / enable: False / False
Generator: 0
Peripheral 31
Write lock / enable: False / False
Generator: 0
Peripheral 32
Write lock / enable: False / False
Generator: 0
Peripheral 33
Write lock / enable: False / False
Generator: 0
Peripheral 34
Write lock / enable: False / False
Generator: 0
Peripheral 35
Write lock / enable: False / False
Generator: 0
Peripheral 36
Write lock / enable: False / False
Generator: 0
Peripheral 37
Write lock / enable: False / False
Generator: 0
Peripheral 38
Write lock / enable: False / False
Generator: 0
Peripheral 39
Write lock / enable: False / False
Generator: 0
Peripheral 40
Write lock / enable: False / False
Generator: 0
Peripheral 41
Write lock / enable: False / False
Generator: 0
Peripheral 42
Write lock / enable: False / False
Generator: 0
Peripheral 43
Write lock / enable: False / False
Generator: 0
Peripheral 44
Write lock / enable: False / False
Generator: 0
Peripheral 45
Write lock / enable: False / False
Generator: 0
Peripheral 46
Write lock / enable: False / False
Generator: 0
Peripheral 47
Write lock / enable: False / False
Generator: 0
Which is a lot of information (guess should have printed a pretty table?) - link to §14 of the data sheet for details. In this case looks like everyone based on the 48MHz PLL (which is in turn driven by the USB connection?) except that one is disabed so 🤔 -> need to investigate more.
MCLK_BASE=0x40000800
HSDIV = mem8[MCLK_BASE | 0x4]
CPUDIV = mem8[MCLK_BASE | 0x5]
AHBMASK = mem32[MCLK_BASE | 0x10]
APBAMASK = mem32[MCLK_BASE | 0x14]
APBBMASK = mem32[MCLK_BASE | 0x18]
APBCMASK = mem32[MCLK_BASE | 0x1c]
APBDMASK = mem32[MCLK_BASE | 0x20]
def print_LE_bits(value):
for j in range(0, 32, 8):
byte = (value >> j) & 0xff
print(f"{byte:08b}")
print("Main clock")
print(f"HSDIV / CPUDIV: {HSDIV} / {CPUDIV}")
print("AHBMASK")
print_LE_bits(AHBMASK)
print()
print("APBAMASK")
print_LE_bits(APBAMASK)
print()
print("APBBMASK")
print_LE_bits(APBBMASK)
print()
print("APBCMASK")
print_LE_bits(APBCMASK)
print()
print("APBDMASK")
print_LE_bits(APBDMASK)
print()
Output
Main clock
HSDIV / CPUDIV: 1 / 1
AHBMASK
11111111
10111111
11111000
00000000
APBAMASK
11111111
11000111
00000000
00000000
APBBMASK
01010111
10000000
00000001
00000000
APBCMASK
00000000
00100000
00000000
00000000
APBDMASK
00000000
00000000
00000000
00000000