このドキュメンテーションは、MicroPython の最新開発ブランチのためのものです。 リリースバージョンでは利用できない機能に言及することがあります。

特定のリリースのドキュメントをお探しの場合は、左側のドロップダウンメニューを使って、 望みのバージョンを選択します。

3. レジスタでペリフェラルに直接アクセスする方法

ESP32 のペリフェラルは、レジスタを直接読み書きして制御できます。そのためには、データシートを読んで、どのレジスタを使用するか、どの値を書き込むかを知る必要があります。次の例では、MCPWM0 ペリフェラルのプリスケーラをオンにして変更する方法を示しています。

from micropython import const
from machine import mem32

# 使うレジスタアドレスを定義。
DR_REG_DPORT_BASE = const(0x3FF00000)
DPORT_PERIP_CLK_EN_REG = const(DR_REG_DPORT_BASE + 0x0C0)
DPORT_PERIP_RST_EN_REG = const(DR_REG_DPORT_BASE + 0x0C4)
DPORT_PWM0_CLK_EN = const(1 << 17)
MCPWM0 = const(0x3FF5E000)
MCPWM1 = const(0x3FF6C000)

# CLK の有効化と RST の無効化。
print(hex(mem32[DPORT_PERIP_CLK_EN_REG] & 0xffffffff))
print(hex(mem32[DPORT_PERIP_RST_EN_REG] & 0xffffffff))
mem32[DPORT_PERIP_CLK_EN_REG] |= DPORT_PWM0_CLK_EN
mem32[DPORT_PERIP_RST_EN_REG] &= ~DPORT_PWM0_CLK_EN
print(hex(mem32[DPORT_PERIP_CLK_EN_REG] & 0xffffffff))
print(hex(mem32[DPORT_PERIP_RST_EN_REG] & 0xffffffff))

# MCPWM0 プリスケーラの変更。
print(hex(mem32[MCPWM0])) # PWM_CLK_CFG_REG (reset value = 0)の読取り
mem32[MCPWM0] = 0x55      # PWM_CLK_PRESCALE の変更
print(hex(mem32[MCPWM0])) # PWM_CLK_CFG_REG の読取り

ペリフェラルを使う前には、そのクロックを有効にし、リセットを解除する必要があります。上記の例では、以下のレジスタがこのために使用されています。

  • DPORT_PERI_CLK_EN_REG: ペリフェラルクロックを有効にするために使われています

  • DPORT_PERI_RST_EN_REG: ペリフェラルのリセット(またはリセットの無効化)に使われています

MCPWM0 ペリフェラルは上記2つのレジスタの第17ビットすなわち DPORT_PWM0_CLK_EN の値になります。

3.1. レジスタを介したピンへの直接同期アクセス

次のコードは、レジスタを介してピンに直接アクセスする方法を示しています。これは一般的な ESP32 ボードでテストしています。コードは、ピン 16, 17, 32, 33 をレジスタを介して出力モードに設定し、ピンの出力値をレジスタを介して切り替えます。ピン 16 と 17 は同時に切り替わります。

from micropython import const
from machine import mem32, Pin

GPIO_OUT_REG = const(0x3FF44004)  # GPIO 0-31 の出力レジスタ
GPIO_OUT1_REG = const(0x3FF44010)  # GPIO 32-39 の出力レジスタ

GPIO_ENABLE_REG = const(0x3FF44020)  # GPIO 0-31 の出力設定レジスタ
GPIO_ENABLE1_REG = const(0x3FF4402C)  # GPIO 32-39 の出力設定レジスタ

M16 = 1 << 16  # Pin(16) のビットマスク
M17 = 1 << 17  # Pin(17) のビットマスク

M32 = 1 << (32-32)  # Pin(32) のビットマスク
M33 = 1 << (33-32)  # Pin(33) のビットマスク

# 次のような出力モードに設定
# p16 = Pin(16, mode=Pin.OUT)
# p17 = Pin(17, mode=Pin.OUT)
# p32 = Pin(32, mode=Pin.OUT)
# p33 = Pin(33, mode=Pin.OUT)
mem32[GPIO_ENABLE_REG] = mem32[GPIO_ENABLE_REG] | M16 | M17
mem32[GPIO_ENABLE1_REG] = mem32[GPIO_ENABLE1_REG] | M32 | M33

print(hex(mem32[GPIO_OUT_REG]), hex(mem32[GPIO_OUT1_REG]))

# 次のように 1 を出力
# p16(1)
# p17(1)
# p32(1)
# p33(1)
mem32[GPIO_OUT_REG] = mem32[GPIO_OUT_REG] | M16 | M17
mem32[GPIO_OUT1_REG] = mem32[GPIO_OUT1_REG] | M32 | M33

print(hex(mem32[GPIO_OUT_REG]), hex(mem32[GPIO_OUT1_REG]))

# 次のように 0 を出力
# p16(0)
# p17(0)
# p32(0)
# p33(0)
mem32[GPIO_OUT_REG] = mem32[GPIO_OUT_REG] & ~(M16 | M17)
mem32[GPIO_OUT1_REG] = mem32[GPIO_OUT1_REG] & ~(M32 | M33)

print(hex(mem32[GPIO_OUT_REG]), hex(mem32[GPIO_OUT1_REG]))

while True:
    # 1 を出力
    mem32[GPIO_OUT_REG] = mem32[GPIO_OUT_REG] | M16 | M17
    mem32[GPIO_OUT1_REG] = mem32[GPIO_OUT1_REG] | M32 | M33

    # 0 を出力
    mem32[GPIO_OUT_REG] = mem32[GPIO_OUT_REG] & ~(M16 | M17)
    mem32[GPIO_OUT1_REG] = mem32[GPIO_OUT1_REG] & ~(M32 | M33)

以下のような出力が得られます:

0x0 0x0
0x30000 0x3
0x0 0x0

"ピン 16 と 17 は同時に切り替わります:

../../_images/mem32_gpio_output.jpg

ピン 32 と 33 も同様です。

ピン 34-36 と 39 は入力専用であることに注意してください。また、ピン 1 と 3 は REPL UART の Tx と Rx であり、ピン 6-11 は内蔵の SPI フラッシュに結線されています。