commit b62d9eec09ab894ea91feb9248c8599a709361fe
parent 6533cdb8b7d9d742ad92e84d6d6aa556bd02e283
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sun, 23 Apr 2023 11:47:20 +0900
update
Diffstat:
3 files changed, 96 insertions(+), 20 deletions(-)
diff --git a/man/draft/rp2040_1.html b/man/draft/rp2040_1.html
@@ -130,7 +130,7 @@ source code ---------> object ------> elf -------->----->---> uf2
<pre><code>\
111000111000000110000110111000111000001010010011111000111000000110010011 入力(適当)
|......|
-111000110000000000000000000000000000000000000000000000000000000000000000 先頭1バイト
+111000110000000000000000000000000 先頭1バイト
100000100110000010001110110110111 除数
------------------------------------------------------------------------
011000010110000010001110110110111
@@ -460,9 +460,9 @@ CRC32のチェックサムが書き込まれたバイナリファイルを、こ
<h2>Flash Second Stage</h2>
<p>
RP2040に電源を投入し、CRC32のチェックが通った後、フラッシュROMからコピー\
-されたプログラムの先頭から実行が開始される。このコピーされた部分で\
+されたプログラムの先頭から実行が開始される。このコピーされた部分で、\
その後の動作に必要な各種の設定を行うことになる。\
-RP2040のデータシートには、この部分でフラッシュROMとSSIコントローラのXIP\
+RP2040のデータシートには、フラッシュROMとSSIコントローラのXIP\
を設定するようにと書かれている。\
XIPはExecute in Placeの略で、フラッシュROMの内容をCPUから\
直接実行するものである。SSIはSynchronous Serial Interfaceの略で、\
@@ -477,7 +477,7 @@ RP2040はチップに内蔵されたこのSSIコントローラを通して、\
しかしこのSSIコントローラはSynopsysという会社のDW_apb_ssiというIPを\
使っているようで、データシートのSSIコントローラの章は多分Synopsysの\
人が書いている。その他の章はRaspberry Pi財団の書いたブリティッシュイングリッシュ\
-だが、この部分だけ多分中国人の書いたいい加減な英語である。誤植も多い。\
+だが、この部分だけ多分ネイティブじゃない人の書いたいい加減な英語である。誤植も多い。\
何日かかけて理解しようとしたが、あまりにも必要な情報が書かれていないので\
よく分からん。不毛なので一旦諦めた。\
</p>
@@ -564,6 +564,52 @@ vectors:
</code></pre>
<h3>GPIOの設定</h3>
+<p>
+電源投入直後、RP2040の周辺機器はリセット状態になっている。\
+まずは今回利用するGPIOのリセット状態を解除する必要がある。\
+日本語だと意味が分かりにくいが英語でも同じようなものである。\
+データシートの2.14. Subsystem Resetsには以下のように書かれている:
+</p>
+<blockquote cite="https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf">
+<p>
+Every peripheral reset by the reset controller is held in reset at power-up.
+It is up to software to deassert the reset of peripherals it intends to use.
+</p>
+</blockquote>
+<p>
+リセット状態を解除するには、RESETS_BASE(<code>0x4000c000</code>)から\
+<code>0x0</code>バイト目のRESETS: RESEレジスタのうち利用したい周辺機器の\
+ビットを<code>0x0</code>にすればいい。
+GPIOはIO Bank 0なので(これ明記されてなくない?)、RESETS: RESETレジスタの\
+IO_BANK0(5番目のビット)を<code>0x0</code>にする。
+</p>
+<h4>レジスタのアトミックなクリア</h4>
+<p>
+RESETS: RESETレジスタのうち5番目のビットだけを<code>0x0</code>に\
+したい。この時、まずこのレジスタを読み込んでから<code>~(1 << 5)</code>と\
+論理積を取って同レジスタに書き戻してもいいのだが、RP2040にはこれを\
+一回の<code>str</code>でしかもアトミックにできる便利な機能が用意されている。\
+今回の場合アトミックかどうかは関係ないと思うが。\
+</p>
+<p>
+各レジスタには4個のアドレスが割り当てられている。\
+データシートの各章のList of Registersに記載されているアドレスは\
+通常の読み書きができる。そのアドレスに<code>0x1000</code>を足したもの\
+にアクセスするとアトミックなXORが、<code>0x2000</code>を足したものは\
+アトミックなセットが、<code>0x3000</code>を足したものはアトミックな\
+クリアができる。つまりレジスタのアドレスに<code>0x3000</code>を足した\
+ものに、<code>0x1 << 5</code>を<code>str</code>すれば5番目のビットだけ\
+<code>0x0</code>にして、他のビットは変更されない。\
+逆に指定したビットだけ立てて他は触らない場合は<code>0x2000</code>を、\
+あるいは指定したビットだけトグルしたい場合は<code>0x1000</code>を足したアドレス\
+にアクセスすればいい。\
+</p>
+<h4>リセット状態の確認</h4>
+<p>\
+リセットの解除はすぐに完了するわけではないようである。
+<p>
+以上から、GPIOのリセットを解除するのは以下のコード:
+</p>
<pre><code>\
.section .text
reset:
@@ -573,12 +619,20 @@ reset:
ldr r3, resets_base
ldr r1, atomic_clr
str r0, [r3, r1] // RESETS: RESET
-
reset_chk:
ldr r1, [r3, #0x8] // RESETS: RESET_DONE
and r0, r0, r1
beq reset_chk
+/* ... */
+
+atomic_clr:
+ .word 0x00003000
+resets_base:
+ .word 0x4000c000
+</code></pre>
+
+<pre><code>\
// set gpio functions
ldr r3, io_bank0_base
mov r0, #5 // sio
@@ -593,10 +647,6 @@ reset_chk:
/* ... */
-atomic_clr:
- .word 0x00003000
-resets_base:
- .word 0x4000c000
io_bank0_base:
.word 0x40014000
sio_base:
diff --git a/pub/draft/rp2040_1.html b/pub/draft/rp2040_1.html
@@ -110,7 +110,7 @@ RP2040は電源を入れるといくつかの段階(ここでは関係ないの
</p>
<pre><code>111000111000000110000110111000111000001010010011111000111000000110010011 入力(適当)
|......|
-111000110000000000000000000000000000000000000000000000000000000000000000 先頭1バイト
+111000110000000000000000000000000 先頭1バイト
100000100110000010001110110110111 除数
------------------------------------------------------------------------
011000010110000010001110110110111
@@ -409,10 +409,10 @@ CRC32のチェックサムが書き込まれたバイナリファイルを、こ
<h2>Flash Second Stage</h2>
<p>
-RP2040に電源を投入し、CRC32のチェックが通った後、フラッシュROMからコピーされたプログラムの先頭から実行が開始される。このコピーされた部分でその後の動作に必要な各種の設定を行うことになる。RP2040のデータシートには、この部分でフラッシュROMとSSIコントローラのXIPを設定するようにと書かれている。XIPはExecute in Placeの略で、フラッシュROMの内容をCPUから直接実行するものである。SSIはSynchronous Serial Interfaceの略で、周辺機器と情報のやりとりをする通信方式である。RP2040はチップに内蔵されたこのSSIコントローラを通して、外部のフラッシュROMと通信しているのだが、このコントローラを適切に設定すればフラッシュROMの内容がCPUから直接アクセスできる<code>0x10000000</code>番地以降にマップされる。これによりフラッシュROMから内部のSRAMにデータをコピーすることなく命令を実行できるので、速くて便利だという。
+RP2040に電源を投入し、CRC32のチェックが通った後、フラッシュROMからコピーされたプログラムの先頭から実行が開始される。このコピーされた部分で、その後の動作に必要な各種の設定を行うことになる。RP2040のデータシートには、フラッシュROMとSSIコントローラのXIPを設定するようにと書かれている。XIPはExecute in Placeの略で、フラッシュROMの内容をCPUから直接実行するものである。SSIはSynchronous Serial Interfaceの略で、周辺機器と情報のやりとりをする通信方式である。RP2040はチップに内蔵されたこのSSIコントローラを通して、外部のフラッシュROMと通信しているのだが、このコントローラを適切に設定すればフラッシュROMの内容がCPUから直接アクセスできる<code>0x10000000</code>番地以降にマップされる。これによりフラッシュROMから内部のSRAMにデータをコピーすることなく命令を実行できるので、速くて便利だという。
</p>
<p>
-しかしこのSSIコントローラはSynopsysという会社のDW_apb_ssiというIPを使っているようで、データシートのSSIコントローラの章は多分Synopsysの人が書いている。その他の章はRaspberry Pi財団の書いたブリティッシュイングリッシュだが、この部分だけ多分中国人の書いたいい加減な英語である。誤植も多い。何日かかけて理解しようとしたが、あまりにも必要な情報が書かれていないのでよく分からん。不毛なので一旦諦めた。</p>
+しかしこのSSIコントローラはSynopsysという会社のDW_apb_ssiというIPを使っているようで、データシートのSSIコントローラの章は多分Synopsysの人が書いている。その他の章はRaspberry Pi財団の書いたブリティッシュイングリッシュだが、この部分だけ多分ネイティブじゃない人の書いたいい加減な英語である。誤植も多い。何日かかけて理解しようとしたが、あまりにも必要な情報が書かれていないのでよく分からん。不毛なので一旦諦めた。</p>
<p>
RP2040には内部にもROMがあり、中にはバージョン情報や、電源を投入した時の動作、その他便利な関数が書き込まれている。この関数のなかに外部のフラッシュROMとSSIコントローラを設定するものも含まれているので今回はこれを利用した。ただしこの方法だとフラッシュROMとの通信方式がStandard SPIのままなので少し遅い。詳しくはデータシート<sup>[3]</sup>の2.3.8. 「Bootrom Contents」を参照。
</p>
@@ -469,6 +469,29 @@ vectors:
</code></pre>
<h3>GPIOの設定</h3>
+<p>
+電源投入直後、RP2040の周辺機器はリセット状態になっている。まずは今回利用するGPIOのリセット状態を解除する必要がある。日本語だと意味が分かりにくいが英語でも同じようなものである。データシートの2.14. Subsystem Resetsには以下のように書かれている:
+</p>
+<blockquote cite="https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf">
+<p>
+Every peripheral reset by the reset controller is held in reset at power-up.
+It is up to software to deassert the reset of peripherals it intends to use.
+</p>
+</blockquote>
+<p>
+リセット状態を解除するには、RESETS_BASE(<code>0x4000c000</code>)から<code>0x0</code>バイト目のRESETS: RESEレジスタのうち利用したい周辺機器のビットを<code>0x0</code>にすればいい。
+GPIOはIO Bank 0なので(これ明記されてなくない?)、RESETS: RESETレジスタのIO_BANK0(5番目のビット)を<code>0x0</code>にする。
+</p>
+<h4>レジスタのアトミックなクリア</h4>
+<p>
+RESETS: RESETレジスタのうち5番目のビットだけを<code>0x0</code>にしたい。この時、まずこのレジスタを読み込んでから<code>~(1 << 5)</code>と論理積を取って同レジスタに書き戻してもいいのだが、RP2040にはこれを一回の<code>str</code>でしかもアトミックにできる便利な機能が用意されている。今回の場合アトミックかどうかは関係ないと思うが。</p>
+<p>
+各レジスタには4個のアドレスが割り当てられている。データシートの各章のList of Registersに記載されているアドレスは通常の読み書きができる。そのアドレスに<code>0x1000</code>を足したものにアクセスするとアトミックなXORが、<code>0x2000</code>を足したものはアトミックなセットが、<code>0x3000</code>を足したものはアトミックなクリアができる。つまりレジスタのアドレスに<code>0x3000</code>を足したものに、<code>0x1 << 5</code>を<code>str</code>すれば5番目のビットだけ<code>0x0</code>にして、他のビットは変更されない。逆に指定したビットだけ立てて他は触らない場合は<code>0x2000</code>を、あるいは指定したビットだけトグルしたい場合は<code>0x1000</code>を足したアドレスにアクセスすればいい。</p>
+<h4>リセット状態の確認</h4>
+<p>リセットの解除はすぐに完了するわけではないようである。
+<p>
+以上から、GPIOのリセットを解除するのは以下のコード:
+</p>
<pre><code> .section .text
reset:
// unreset gpio
@@ -477,13 +500,20 @@ reset:
ldr r3, resets_base
ldr r1, atomic_clr
str r0, [r3, r1] // RESETS: RESET
-
reset_chk:
ldr r1, [r3, #0x8] // RESETS: RESET_DONE
and r0, r0, r1
beq reset_chk
- // set gpio functions
+/* ... */
+
+atomic_clr:
+ .word 0x00003000
+resets_base:
+ .word 0x4000c000
+</code></pre>
+
+<pre><code> // set gpio functions
ldr r3, io_bank0_base
mov r0, #5 // sio
mov r1, #0xcc
@@ -497,10 +527,6 @@ reset_chk:
/* ... */
-atomic_clr:
- .word 0x00003000
-resets_base:
- .word 0x4000c000
io_bank0_base:
.word 0x40014000
sio_base:
diff --git a/pub/rss.xml b/pub/rss.xml
@@ -5,8 +5,8 @@
<description>ウェブページの更新履歴</description>
<language>ja-jp</language>
<link>https://www.mtkn.jp</link>
-<lastBuildDate>Sat, 22 Apr 2023 13:38:27 +0900</lastBuildDate>
-<pubDate>Sat, 22 Apr 2023 13:38:27 +0900</pubDate>
+<lastBuildDate>Sun, 23 Apr 2023 11:47:12 +0900</lastBuildDate>
+<pubDate>Sun, 23 Apr 2023 11:47:12 +0900</pubDate>
<docs>https://www.rssboard.org/rss-specification</docs>
<item>
<title>Xlibで遊んでみる6</title>