Kogin - 津軽こぎん刺しと南部菱刺し用図案描写ソフト
津軽こぎん刺しと南部菱刺し用図案描写専用ソフトです。
https://github.com/hanya/kogin
ダウンロードはリリースより https://github.com/hanya/kogin/releases
お試し用のウェブ版は以下より https://hanya.github.io/kogin/src/index.html
図案例
Koginで作成した図案データはSVG画像としてデータを含む形で保存できます。SVG画像はブラウザなどで表示できます。また、データを含む画像ファイルをKoginで読み込むと編集できます。
以下のような図案が作成できます。
一部だけ表示するような図案も作成できます。
マニュアル等
- マニュアル https://github.com/hanya/kogin/blob/master/help/help_ja.md
- ショートカットキー一覧 https://github.com/hanya/kogin/blob/master/help/keys_ja.md
テンプレートレポジトリ
テンプレートを外部の github や gitlab から読み込むことが出来ます。
以下の型コテンプレートレポジトリから読み込むには、テンプレートウィンドウの場所追加ウィンドウに次のように入力します。 https://github.com/hanya/katako
ユーザー: hanya レポジトリ: katako
レポジトリのディレクトリ内だけを追加したいときは、サブディレクトリも入力してください。
テンプレートの保存場所
作成して保存したテンプレートファイルはユーザーの設定ディレクトリに保存されます。
Windows User\ユーザー名\AppData\kogin Linux ~/.config/kogin
Rust で重み付き抽選
重み付き抽選とは、ゲームのアイテムドロップの判定などに使われる選択手法です。
それぞれの選択率がリンゴ (50%)、みかん (20%)、柿 (20%)の場合、この確率に従って乱数で選びます。
Rust では rand クレートの WeightedIndex や rand_distr クレートの WeightedAliasIndex を利用できます。
rand::distributions::WeightedIndex
選択時の計算量は O(log N) です。N は要素数。つまり、要素数が多いと急に遅くなります。初期化時の計算量は O(N) です。
一度のサンプリングで乱数を1つ消費します。
コードより要素数とメモリ使用量の関係を調べます。
// https://docs.rs/rand/0.8.4/src/rand/distributions/weighted_index.rs.html#81-85 pub struct WeightedIndex<X: SampleUniform + PartialOrd> { cumulative_weights: Vec<X>, total_weight: X, weight_distribution: X::Sampler, }
X は重みを指定する値の型です。
cumulative_weights のサイズは要素数と同じです。つまり、メモリ量は O(N) です。
rand_distr::weighted_alias::WeightedAliasIndex
選択時の計算量は O(1) です。初期化時の計算量は O(N) です。要素数が多いと事前に用意するデータが大きくなりメモリ消費量が増えます。
一度のサンプリングで乱数を2つ消費します。
同様にコードを確認します。
// https://docs.rs/rand_distr/0.4.2/src/rand_distr/weighted_alias.rs.html#72-77 pub struct WeightedAliasIndex<W: AliasableWeight> { aliases: Box<[u32]>, no_alias_odds: Box<[W]>, uniform_index: Uniform<u32>, uniform_within_weight_sum: Uniform<W>, }
W は重みを指定する数値の型です。
no_alias_odds の要素数は N です。
aliases の要素数は N なので(ドキュメントより)、WeightedIndex とのメモリ量の差は sizeof(u32) * N です。
乱数の使用数調査
コードを見ると WeightedAliasIndex は一度のサンプリングで2つの乱数を消費しているようなので、以下のようにして乱数の消費数を調べます。
use rand::Rng; use rand::distributions::{Distribution, WeightedIndex}; use rand_core::{Error, RngCore, SeedableRng}; use rand_pcg::Lcg64Xsh32; use rand_distr::weighted_alias::WeightedAliasIndex; /// Couting wrapper. struct CountRnd { rng: Lcg64Xsh32, count_u32: usize, } impl CountRnd { pub fn new(seed: u64) -> Self { Self { rng: Lcg64Xsh32::seed_from_u64(seed), count_u32: 0, } } pub fn count_u32(&self) -> usize { self.count_u32 } pub fn reset_count(&mut self) { self.count_u32 = 0; } } impl RngCore for CountRnd { fn next_u32(&mut self) -> u32 { self.count_u32 += 1; self.rng.next_u32() } fn next_u64(&mut self) -> u64 { self.rng.next_u64() } fn fill_bytes(&mut self, dest: &mut [u8]) { self.rng.fill_bytes(dest) } fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { self.rng.try_fill_bytes(dest) } } fn main() { let mut rng = CountRnd::new(1234); let items = ['a', 'b', 'c']; let weights = [20, 10, 10]; let dist = WeightedIndex::new(&weights.clone()).unwrap(); for _ in 0..100 { let _i = items[dist.sample(&mut rng)]; } println!("count: {}", rng.count_u32()); // 100 rng.reset_count(); let dist = WeightedAliasIndex::new(weights.to_vec()).unwrap(); for _ in 0..100 { let _i = items[dist.sample(&mut rng)]; } println!("count: {}", rng.count_u32()); // 200 }
二倍消費していることが分かります。
Rust では乱数を使用するときによく使われるクレートに重み付き抽選が実装されています。
抽選対象の確率から分布が作成され、その分布に与えられた乱数から抽選されます。
RngCore トレイトを実装している乱数生成器ならどれでも使用できます。
高速に判定したい場合はメモリの使用量に問題なければ WeightedAliasIndex を使えます。
しかし、一度のサンプリングで乱数を2つ消費したくなければ WeightedIndex を使いましょう。
RPi pico ハードウェア
Rpi pico の回路図をみながらパッドに引き出されていないピンなどを調べる。
- Pico データシート
- Pico 回路図
ピンアウト
- ピンアウト図
- ファンクションセレクト
RP2040 MCU は GPIO 0-29 あるが一部のピンはパッドに引き出されていない。表にまとめた。テストポイントについて同時に記載した。
ピン | TP | 説明 |
GPIO23 | TP4 | レギュレータ PS 端子 |
GPIO24 | - | 分圧済みVBUS |
GPIO25 | TP5 | 緑 LED |
GPIO29 | - | ADC3 VSYS/3 ※ |
- | TP1 | GND |
USB_DM | TP2 | USB_DM |
USB_DP | TP3 | USB_DP |
- | TP6 | BOOTSEL |
GPIO24 は USB OVCUR DET 機能を持つ。つまりデバイスモードで USB DET として使えないため、自分で検出する必要がある。
※ VSYS が供給されていて 3V3 が供給されないとき (3V3_EN LOW)、GPIO29_ADC3 のダイオードからのリークを減らすために使用。
レギュレータ
RT6150B-33GQW が載っている。Back-Boost コンバータなので 1.8-5.5V の範囲を供給すると 3.3V を出力する。昇圧、降圧共に可能。
USB コネクタの VBUS とレギュレータ入力の間にダイオードが入っているため、低圧の供給は VSYS からがよい。
EN ピンが HIGH で有効、LOW で無効。3V3_EN パッドにとして引き出されている。3V3 パッドから電源を供給して Pico のレギュレータを停止させたいときなどに使える。
PS | モード | 図 | 説明 |
0 | PFM | 左 | 出力全体でおよそ効率が良い |
1 | PWM | 右 | リップルが少ないが低出力で効率が悪い |
データシート[1]によると効率は以下のようになっている。
左図の PFM モードでは低電流 (1-60 mA) では効率が 67-73% である。
右図の PWM モードでは低電流で効率が 77% 未満に収まっている。
それ以上の出力電流でもさほどの差は見られない。そのため、リップルが問題にならなければ PFM モードでよい。
ADC などでリップルが問題になる場合、変換中のみ PWM モードに切り替えるとよい (4.3. Using the ADC [2] 参照)。
[1]: https://www.richtek.com/assets/product_file/RT6150A=RT6150B/DS6150AB-06.pdf
[2]: https://datasheets.raspberrypi.org/pico/pico-datasheet.pdf#%5B%7B%22num%22%3A20%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C115%2C359.05%2Cnull%5D
GDB Python スクリプトでビットを表示
マイコンではレジスタでビットフラグが多用されているが、慣れていないと gdb の x コマンドでメモリの値を読み出してもどのビットがセットされているか分かりにくい。
GDB Python スクリプトでなんとかできそうだったが情報が少なかったので残しておく。
Python スクリプトから GDB の機能を実行する方法は以下に記載がある。
Python コード埋め込み
gdbinit ファイルを -x オプションで読み込むと、設定や独自の定義のコマンドが利用できる。
この設定ファイルに Python のコードを埋め込める。python ... end の間に Python のコードを書ける。
python # Python code end
Python コード実行
python call_func()
定義コマンドの中で実行するなら引数を渡すこともできる。
define xbits python bits($arg0) end
引数は $arg0, $arg1, ... など。
ビット表示
アドレスを引数として受け取るとそのアドレスの値を x コマンドの出力から得て、ビットとして表示する xbits およびそのエイリアス xt を作成した。
python def _bits_extend(value, max, min): vs = [] vs.append("") for i in range(min, max + 1)[::-1]: if (value & (1 << i)) > 0: vs.append(" 1") else: vs.append(" 0") vs.append("") return "|".join(vs) def bits(arg0): addr, tvalue = gdb.execute('x {}'.format(arg0), to_string=True).rstrip().split("\t") value = int(tvalue, 16) s = [] s.append("{}\t{}".format(addr, tvalue)) s.append("|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|") s.append(_bits_extend(value, 31, 16)) #s.append("") s.append("|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|") s.append(_bits_extend(value, 15, 0)) print("\n".join(s)) end define xbits python bits($arg0) end alias -a xt = xbits
実行結果
(gdb) xt 0x50110000 0x50110000: 0x00000000 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16| | 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| | 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0|
このように各ビットがひと目で分かる。
ブラウザでビットフラグを表示
数値をビットに展開して表示するページを作成しました。10進数および0xから始まる16進数を入力できます。
bs2_default_padded_checksummed.S の作り方
2nd ブートファイルをフラッシュの先頭に置いてブートさせる場合、pico-sdk 以外から bs2_default_padded_checksummed.S ファイルを使用したい場合があります。
以下のようにしてビルドできます。
cd pico-sdk mkdir build cd build cmake .. #cd src/rp2_common/boot_stage2 make bs2_default_padded_checksummed_asm
pico-sdk/build/src/rp2_common/boot_stage2/bs2_default_padded_checksummed.S にファイルが作成されます。リンク時に指定します。
このようにリンク先のターゲット無しでビルドすると boot2_generic_03h.S ファイルがコンパイルされます。
make 時にターゲットとして bs2_default_padded_checksummed_asm を指定しないと bin ファイルや S ファイルは生成されません。
RP2040 PIO レジスタと Pico SDK 覚え書き
詳細はデータシート参照のこと
- https://datasheets.raspberrypi.org/rp2040/rp2040-datasheet.pdf
- https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__pio.html
- レジスタと関連なし
- CTRL
- FSTAT
- FDEBUG
- FLEVEL
- TXF0, TXF1, TXF2, TXF3
- RXF0, RXF1, RXF2, RXF3
- IRQ
- IRQ_FORCE
- INPUT_SYNC_BYPASS
- DBG_PADOUT
- DBG_PADOE
- DBG_CFGINFO
- INSTR_MEM0, INSTR_MEM1, ... INSTR_MEM30, INSTR_MEM31
- SM0_CLKDIV, SM1_CLKDIV, SM2_CLKDIV, SM3_CLKDIV
- SM0_EXECCTRL, SM1_EXECCTRL, SM2_EXECCTRL, SM3_EXECCTRL
- SM0_SHIFTCTRL, SM1_SHIFTCTRL, SM2_SHIFTCTRL, SM3_SHIFTCTRL
- SM0_ADDR, SM1_ADDR, SM2_ADDR, SM3_ADDR
- SM0_PINCTRL, SM1_PINCTRL, SM2_PINCTRL, SM3_PINCTRL
- INTR
- IRQ0_INTE
- IRQ0_INTF
- IRQ0_INTS
レジスタと関連なし
-
- pio0
- pio ブロック 0
- pio1
- pio ブロック 1
- pio0
-
- pio_get_default_sm_config
- デフォルト値を持つ pio_sm_config 構造体を返す
- pio_sm_set_config
- ステートマシンの設定をステートマシンに適用する
- pio_get_index
- PIO のインスタンス番号を返す
- pio_gpio_init
- 出力のために GPIO を設定する
- output に必要だ
- input のみなら設定しなくてもステートマシンからピンの状態を読み出せる
- pio_get_dreq
- TX または RX の DREQ (Data Request) を返す
- DREQ は System DREQ Table (RP2040 リファレンス参照) で定義されている番号
- pio_get_default_sm_config
CTRL
- CTRL
-
- pio_sm_init
- ステートマシンを初期化する
- pio_sm_set_enabled
- 指定したステートマシンを有効/無効にする
- pio_set_sm_mask_enabled
- マスクで指定したステートマシンを有効/無効にする
- pio_enable_sm_mask_in_sync
- マスクで指定したステートマシンを同期して開始する
- pio_set_sm_mask_enabled の次に pio_clkdiv_restart_sm_mask を呼ぶのと同じ結果
- pio_sm_restart
- 指定したステートマシンを再起動する
- ステートマシンの状態は初期化される
- pio_restart_sm_mask
- マスクで指定したステートマシンを再起動する
- pio_sm_clkdiv_restart
- クロック分割器を再起動する
- pio_clkdiv_restart_sm_mask
- 複数のステートマシンのクロック分割器を再起動する
- 複数のステートマシンを同期させられる
- pio_sm_init
FSTAT
FDEBUG
TXF0, TXF1, TXF2, TXF3
RXF0, RXF1, RXF2, RXF3
IRQ_FORCE
INPUT_SYNC_BYPASS
- INPUT_SYNC_BYPASS
- GPIO 入力の 2-フリップフロップ同期回路をバイパスする。
- 同期しつつ相当高速にしたい場合に使用する。
DBG_PADOUT
- DBG_PADOUT
- 現在 PIO が駆動している GPIO の状態を読み出す。
DBG_PADOE
- DBG_PADOE
- 現在 PIO の出力が有効な (方向) GPIO の状態を読み出す。
DBG_CFGINFO
INSTR_MEM0, INSTR_MEM1, ... INSTR_MEM30, INSTR_MEM31
- INSTR_MEM0, INSTR_MEM1, ... INSTR_MEM30, INSTR_MEM31
- 命令メモリ、書き込み専用
-
- pio_can_add_program
- 指定のプログラムが命令メモリに入るかどうか確認する
- pio_can_add_program_at_offset
- 指定のプログラムが命令メモリの指定の位置からメモリに入るかどうか確認する
- pio_remove_program
- 命令メモリからオフセットを開始位置として指定のプログラムを削除する
- pio_clear_instruction_memory
- 命令メモリを空にする
- pio_can_add_program
SM0_CLKDIV, SM1_CLKDIV, SM2_CLKDIV, SM3_CLKDIV
- SM0_CLKDIV, SM1_CLKDIV, SM2_CLKDIV, SM3_CLKDIV
- クロック分割レジスタ
- 周波数 = クロック周波数 / (CLKDIV_INT + CLKDIV_FRAC / 256)
- INT
- 整数部。0 は 65536 とみなされる。INT が 0 の時は FRAC もゼロのこと
- FRAC
- 小数部
-
- sm_config_set_clkdiv_int_frac
- クロック分割の整数部と小数部を設定する
- sm_config_set_clkdiv
- クロック分割を設定する、整数部と小数部に分割して設定される
- pio_sm_set_clkdiv_int_frac
- クロック分割の整数部と小数部を設定する
- pio_sm_set_clkdiv
- クロック分割を設定する、整数部と小数部に分割して設定される
- sm_config_set_clkdiv_int_frac
SM0_EXECCTRL, SM1_EXECCTRL, SM2_EXECCTRL, SM3_EXECCTRL
- SM0_EXECCTRL, SM1_EXECCTRL, SM2_EXECCTRL, SM3_EXECCTRL
- 動作と挙動設定
- EXEC_STALLED
- 1 のとき、SMx_INSTR に書き込まれた命令がストール
- SIDE_EN
- 1 のとき、Delay/Side-set フィールドの MSB がサイドセットの有効/無効を表す
- サイドセットをオプションにできるが、サイドセットのビット数が減る
- SIDE_PINDIR
- 1 のとき、データはピンの方向指定となる (このとき、ピンの値の設定はできない、どちらか一方のみ)
- JMP_PIN
- JMP PIN の条件の GPIO 番号。マッピングに影響されない
- OUT_EN_SEL
- インライン OUT を有効にするためのデータビットを指定
- INLINE_OUT_EN
- 1 のとき、データの 1 つのビットを補助的な書き込み有効設定に使用する。
- 複数のステートマシンが同時に同じピンに出力する場合、インラインアウト指定になっているステートマシンからの出力が、インラインアウト指定なしのステートマシンからの出力より優先される。
- 複数のステートマシンでインラインアウトが指定されている場合、ステートマシン番号の大きな方が優先される。これはインラインアウトの指定の無い場合の優先順位と同じ。
- https://www.raspberrypi.org/forums/viewtopic.php?t=313962
- OUT_STICKY
- OUT_EN_SELで指定したビットがゼロでも、インラインアウトで最後に指定されたピンへの OUT/SET が継続的にアサートされる
- WRAP_TOP
- WRAP_TOP は終了インデックス。WRAP_BOTTOM との間を繰り返す
- 命令がジャンプの場合、ジャンプの条件が真ならジャンプが優先される
- pioasm では .wrap_target で生成される
- WRAP_BOTTOM
- WRAP_BOTTOM は開始インデックス。WRAP_TOP との間を繰り返す
- pioams では .wrap で生成される
- STATUS_SEL
- STATUS_N
- 比較用 N
-
- sm_config_set_out_special
- 特別な OUT 動作について設定する
- sm_config_set_wrap
- ラップアドレスを設定する
- sm_config_set_jmp_pin
- JMP PIN で使用される GPIO ピンを設定する
- ピンは絶対番号で指定する、ピンマッピングのベースに影響を受けない
- sm_config_set_mov_status
- MOV STATUS で使用する条件と N を設定する
- sm_config_set_out_special
-
- pio_sm_is_exec_stalled
- pio_sm_exec で実行された命令がストール状態かどうか返す
- pio_sm_set_wrap
- ラップアドレスを設定する
- pio_sm_is_exec_stalled
SM0_SHIFTCTRL, SM1_SHIFTCTRL, SM2_SHIFTCTRL, SM3_SHIFTCTRL
- SM0_SHIFTCTRL, SM1_SHIFTCTRL, SM2_SHIFTCTRL, SM3_SHIFTCTRL
- 入出力シフトレジスタの動作制御
- FJOIN_RX
- FJOIN_TX
- PULL_THRESH
- オートプルまたは条件付きプル (PULL IFEMPTY) 動作までにシフトアウトされるビット数。0 は 32 と解釈される
- PUSH_THRESH
- オートプッシュまたは条件付きプッシュ (PUSH IFFULL) 動作までにシフトインされるビット数。0 は 32 と解釈される
- OUT_SHIFTDIR
- 1 のとき右シフト、0 のとき左シフト
- IN_SHIFTDIR
- 1 のとき右シフト(データは左から入る)、0 のとき左シフト
- AUTOPULL
- 出力シフトレジスタが空になったとき、自動的にプルされる
- OUT 命令で出力シフトカウンタが PULL_THRESH に到達または超えた時
- AUTOPUSH
- 入力シフトレジスタに入力があったとき、自動的にプッシュされる
- IN 命令で入力シフトカウンタが PUSH_THRESH に到達または超えた時
SM0_ADDR, SM1_ADDR, SM2_ADDR, SM3_ADDR
- SM0_ADDR, SM1_ADDR, SM2_ADDR, SM3_ADDR
- 現在の命令アドレス
-
- pio_sm_get_pc
- 現在のプログラムカウンタ (命令アドレス) を設定する
- pio_sm_get_pc
- SM0_INSTR, SM1_INSTR, SM2_INSTR, SM3_INSTR
- 現在ステートマシンに割り当てられている命令
- このレジスタに書き込むとすぐに実行され、復帰する
-
- pio_sm_exec
- 命令を即座に実行する
- pio_sm_exec_wait_blocking
- 命令を即座に実行して完了するまで待つ
- pio_sm_exec
SM0_PINCTRL, SM1_PINCTRL, SM2_PINCTRL, SM3_PINCTRL
- SM0_PINCTRL, SM1_PINCTRL, SM2_PINCTRL, SM3_PINCTRL
- ステートマシンのピン制御
- SIDESET_COUNT
- サイドセットに使用する Delay/Side-set フィールドの MSB 側のビット数
- 0 (すべてディレイ、サイドセットなし) から 5 (すべてサイドセット、ディレイなし)
- SET_COUNT
- SET でアサートされるピン数、0-5
- OUT_COUNT
- OUT PINS, OUT PINDIRS, MOV PINS 命令でアサートされるピン数、0-32
- IN_BASE
- ステートマシンの IN データバスの最下位ビットにマップされるピン
- 上位のビットのピンは連続的にマップされる
- ピン番号の 32 の剰余が使われるので、32 は 0 番ピン
- SIDESET_BASE
- サイドセットの一番小さな番号のピンを指定
- サイドセット指定の最下位ビットがこのピンに相当する。より上位のビットはより大きな番号のピンに相当する
- SET_BASE
- SET PINS または SET PINDIRS 命令の一番小さな番号のピンを指定
- このピンに書き込まれるのは SET のデータの最下位ビット
- OUT_BASE
- OUT PINS または OUT PINDIRS または MOV PINS 命令の一番小さな番号のピンを指定
- このピンに書き込まれるデータは OUT または MOV のデータの最下位ビット
-
- sm_config_set_out_pins
- OUT ピンについて設定する
- sm_config_set_set_pins
- SET ピンについて設定する
- sm_config_set_in_pins
- IN ピンについて設定する
- sm_config_set_sideset_pins
- サイドセットピンについて設定する
- sm_config_set_sideset
- サイドセットについて設定する
- サイドセットに使われるビット数、サイドセットがオプションかどうか、ピンの方向設定に使用するかどうか
- sm_config_set_out_pins
-
- pio_sm_set_out_pins
- OUT ピンについて設定する
- pio_sm_set_set_pins
- SET ピンについて設定する
- pio_sm_set_in_pins
- IN ピンについて設定する
- pio_sm_set_sideset_pins
- サイドセットピンについて設定する
- pio_sm_set_out_pins
-
- pio_sm_set_pins
- すべての 32 ピンについて設定する
- SET 命令で実行される
- 初期値の設定に使用できる、実行中のステートマシンに対して使用すべきではない
- pio_sm_set_pins_with_mask
- マスクで選択したピンについて値を設定する、後はマスクしない pio_sm_set_pins 関数と同じ
- pio_sm_set_pindirs_with_mask
- マスクで選択したピンについてピンの方向を設定する
- SET 命令で実行される
- pio_sm_set_consecutive_pindirs
- 連続したピンについてピンの方向を同じ方向に設定する
- SET 命令で実行される
- pio_sm_set_pins
INTR
- INTR
- 割り込みソースの有効/無効
IRQ0_INTE
- IRQ0_INTE
- irq0 用の割り込み有効/無効
IRQ0_INTF
- IRQ0_INTF
- irq0 用の割り込み強制
IRQ0_INTS
- IRQ0_INTS
- irq0 用のマスクと強制の後のステータス
irq1 は省略。
PIO ブロックごとに irq0 と irq1 があり、これら2つはシステムの割り込み。
それぞれの irq はソースを選択できる。
-
- pio_set_irq0_source_enabled
- irq0 のソースのうち一つを有効/無効にする
- pio_set_irq1_source_enabled
- irq1 のソースのうち一つを有効/無効にする
- pio_set_irq0_source_mask_enabled
- irq0 のマスクで指定したソースすべてを有効/無効にする
- pio_set_irq1_source_mask_enabled
- irq1 のマスクで指定したソースすべてを有効/無効にする
- pio_set_irqn_source_enabled
- irqn のソースのうち一つを有効/無効にする
- pio_set_irqn_source_mask_enabled
- irqn のマスクで指定したソースすべてを有効/無効にする
- pio_set_irq0_source_enabled