投稿

2021の投稿を表示しています

RP2040でPIOをプロジェクト新規作成して動かすまで(C言語)

イメージ
RP2040でPIOを動かすまでのプロジェクト新規作成・ビルド方法について解説します。 ここではPythonではなくC言語をターゲットとしています。 まず、『PIOTest』プロジェクトを プロジェクトの作成 を参考にして作成します。 プロジェクトの作成 を参考に、ビルド・デバッグができる所まで進めたら、VSCodeのエクスプローラーで、PIOTest.cと同一階層にPIOTest.pioというファイルを新規作成し、次のように編集します。(末尾の『%}』 以降に余計な改行等が無いように注意してください) PIOTest.pio .program PIOTest ; TX FIFOから32bitのデータを繰り返し取得し、 ; FIFOが空になるとpullでFIFOにデータが入るまで待機します。 ; また、取得したデータの最下位ビットをあらかじめ設定してある ; 出力ピン(GPIO)に書き込みます。 loop: pull out pins, 1 jmp loop % c-sdk { static inline void PIOTest_program_init(PIO pio, uint sm, uint offset, uint pin) { pio_sm_config c = PIOTest_program_get_default_config(offset); // ステートマシンにてOUTの対象(『out pins, 1』等で値が入る対象)となるGPIOを設定します。 // 変数pinにはGPIO番号が入ります。次の引数にはそのGPIO番号からいくつ連続で使用するかの値で、 // ここでは"1"としていますので、pinのGPIOのみが使用されることになります。 sm_config_set_out_pins(&c, pin, 1); // GPIO番号"pin"をGPIOとして使えるようにします。 pio_gpio_init(pio, pin); // 対象のGPIOを出力に設定します。(true:出力 false:入力) pio_sm_set_consecutive_pindirs(pi

RP2040のPIOのJMP, MOV, PUSHとかの解説(C言語向け)

RP2040(Raspberry Pi Pico)のPIOのJMPやMOVといったアセンブラのような命令について解説します。 1. JMP 条件によって設定したラベル位置に処理を移動させます。 JMP 例 loop: ; ラベルloopを設定(名前は自由に付けれる) ~その他処理~ jmp !x loop ; レジスタXが0の場合、ラベルloopに処理をジャンプします。 命令は次のフォーマットで記述します。 jmp (<条件>) <ラベル> かっこ()は省略可を意味します。(『jmp <ラベル>』と書くことも可能ということ) 条件が成立(true)する場合に、ラベルにジャンプします。条件は次の8パターンの書き方があります。 条件 動作 記載なし 条件は常に成立(true)となり、常にラベルにジャンプします。 !x レジスタXが0の場合、ラベルにジャンプします。 x-- レジスタXが0では無い場合、ラベルにジャンプします。ついでにレジスタxの値を1引きます。 !y レジスタYが0の場合、ラベルにジャンプします。 y-- レジスタYが0では無い場合、ラベルにジャンプします。ついでにレジスタyの値を1引きます。 x!=y レジスタXとYが違う値の場合、ラベルにジャンプします。 pin あらかじめsm_config_set_ jmp _pin関数で設定しておいたGPIOピンがHレベルの場合、ラベルにジャンプします。 !OSRE OUTシフトレジスタが空でなければ、ラベルにジャンプします。(OUTシフトレジスタにはPULL命令によってTX FIFOから32bitのデータが格納される) 2. WAIT 条件が成立するまで待機します。遅延命令を付けた場合は、条件成立直後に遅延処理が実施されます。 WAIT 例 wait 1 gpio 28

RP2040データシートのPIOブロック図を解説

イメージ
RP2040(Raspberry Pi Pico)の データシート に記載されてるPIO(Programmable I/O)のブロック図を解説します。私なりにブロック図を書き直して、それを元にPIOについて説明します。 RP2040のPIO(Programmable I/O)とは、簡単に言うとメインのCPUとは別で動く非常に小さなCPUのことです。この小さなCPU(ステートマシンと呼びます)は合計8つ存在し、IO操作等が可能です。 CPUとは独立して動作しますので、タイミングのシビアなI/O制御に向いており、プログラミング次第でUARTやSPIといった周辺回路と大体同様の機能を作成できます。 全体のブロック図は次のようになります。 ステートマシンはPIO0とPIO1の2ブロックに4つずつ、合計8つ存在します。 詳細なブロック図は次のようになります。 ① TX FIFO 32bit CPUからステートマシンにデータを送る際に使用される32bitのバッファ。CPU側はC言語の場合『pio_sm_put_blocking』関数等を利用して目的のデータをTX FIFOに入れる。PIO側は『PULL』命令によってTX FIFOからOutシフトレジスタへ値を移動できる。FIFOは他のFIFOと結合してサイズを拡張可能。(単方向では最大8×32bitまで拡張可能) ② RX FIFO 32bit ステートマシンからCPUにデータを送る際に使用される32bitのバッファ。CPU側はC言語の場合『pio_sm_get_blocking』関数等を利用してRX FIFOから目的のデータを取得する。PIO側は『PUSH』命令によってInシフトレジスタからRX FIFOへ値を移動できる。TX FIFOと同じく結合してサイズ拡張可能。 ③ Outシフトレジスタ32bit 32bitのデータを保持できるビットシフト機能の付いたレジスタ。『OUT』命令で保持データ(指定ビット数分)をGPIO等に反映し、ビットシフトする。 ④ Inシフトレジスタ32bit 32bitのデータを保持できるビットシフト機能の付いたレジスタ。『IN』命令でGPIO等の値(指定ビット数分)を取得し、ビットシフトする。 ⑤ 汎用レジスタX 32bit 32bitのデー

Raspberry Pi Picoのステップ実行できる開発環境づくり

イメージ
Raspberry Pi 4とVSCodeを用いてRaspberry Pi Pico(RP2040)の開発環境(C言語)の構築の方法を解説します。最終的にはステップ実行・プロジェクトの新規作成までできるようになります。 対象マイコン: Raspberry Pi Pico(RP2040) 開発PC: Raspberry Pi 4 開発OS: Raspberry Pi OS IDE: Visual Studio Code (VSCode) 開発言語: C言語 1. セットアップスクリプトのダウンロード・実行 ターミナル(LXTerminal)を開いてセットアップスクリプトをダウンロード・実行します。 このブログではホームフォルダ(/home/pi)でセットアップスクリプトを実施したことを前提に説明します。ターミナルを開いた時に、『pi@raspberrypi:~ $』という表示になっていなければ、『cd ~ 』コマンドにてホームフォルダ(/home/pi)に移動してから以下のコマンドを実施してください。 Terminal # このブログではホームフォルダ(/home/pi)にて実施します。 pi@raspberrypi:~ $ cd ~ # wgetでセットアップスクリプトをダウンロード pi@raspberrypi:~ $ wget https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh # スクリプトに実行権限を与える pi@raspberrypi:~ $ chmod +x pico_setup.sh # スクリプト実行 pi@raspberrypi:~ $ ./pico_setup.sh # スクリプト実行後、再起動 pi@raspberrypi:~ $ sudo reboot このスクリプトの実行で、開発環境のセットアップはほぼ完了です。 pico-sdkやサンプルコードがインストールされる他、コードエディタ・デバッガとしてVisual Studio Codeがインストールされます。 2. ボード上のLEDを点滅させてみる : 既存のUF2ファイルを使用 セットアップスクリプトにより、サンプルコー

RP2040で簡単マルチコアコーディング(C言語)

RP2040はCPU(Cortex-M0+)を2つ内蔵しているデュアルコアのマイコンで、2つの異なるコードを並列に実行することができます。 使い方も簡単で以下のように専用関数の呼び出しで使用できます。 #include "pico/multicore.h" void core1_entry() { // Core1で動作させる処理 ... } // main関数はCore0で動作する int main() { // Core1でcore1_entry関数を動作させる multicore_launch_core1(core1_entry); // 以下Core0で動作させる処理 ... } "pico/multicore.h" を使用するために、『CMakeLists.txt』の『target_link_libraries』に『pico_multicore』を追記します。 CMakeLists.txt ・・・ # pico_multicore を追記 (『YourProjName』はプロジェクト名に変更してください) target_link_libraries(YourProjName pico_stdlib pico_multicore) ・・・ マルチコアプログラミングでは、複数のコアから同時に同じメモリや同じIO等にアクセスしないように排他処理が必要です。 ここでは semaphore_t を使ったセマフォによる排他処理を使用します。 #include "pico/multicore.h" // 排他処理用のセマフォ static semaphore_t sem; void core1_entry() { // Core1で動作させる処理 // セマフォから許可を要求。許可が得られるまで待機 sem_acquire_blocking(&sem); // ここでCore0と共用するメモリ・IO等ハードウェアにアクセスする処理を記述 ... // 完了後、セマフォ解放。Core0を止めるのでなるべく早く解除する。 sem_release(&sem)

IZOKEEの圧着ペンチでXHコネクタとPHコネクタを作る方法

イメージ
XHコネクタとPHコネクタを作成する為に、Amazonでコスパが良いと思われるIZOKEEの圧着ペンチを購入したのですが、こちらは同時圧着ペンチという被服と心線を一回で圧着可能なもので、初見では何をどうすれば良いか解りにくかったので使い方を紹介します。 IZOKEEの圧着ペンチでXHコネクタを作る方法 電線は直径1.2mmの物を使用します。 被覆を適当に剥きます。ワイヤストリッパーがあれば使用します。ワイヤストリッパーが無ければカッターで慎重に剥きます。切り口が直角になるようにします。剥き終わったら芯線を軽く指でねじってまとまりを出します。 適当に被服を剥く。被服の切り口は直角になるように。 剥き出しになる芯線の長さがピッタリ3mmになるように慎重にカットします。(3.0mm〜2.8mm位までの間なら許容できると思います) カットが終わったら芯線を軽く指でねじってまとまりを出します。 心線は3mm露出するように正確にカット XHコンタクトに電線を当てて、被覆と電線を圧着するのに問題無い長さ、形状である事を確認します。この時、電線を完全に奥まで当てます。(被服圧着部と心線圧着部が分からない場合は、7番目の圧着完了後の画像を先に確認してください) 電線を奥まで当てて形状を確認 XHコンタクトを圧着ペンチの先端から2番目にセットします。圧着ペンチは被覆圧着部と芯線圧着部で完全に閉じたときの隙間のサイズが異なり、被覆圧着部のほうがより大きく隙間ができるようになっています。その為、圧着ペンチの被覆圧着部と芯線圧着部で段差があるのですが、その段差の壁にXHコンタクトの被覆圧着金具が当たるようにセットします。ピンセットを使うと楽かもしれません。 XHコンタクトをセット。段差の壁に被服圧着金具をひっかける。 圧着ペンチでXHコンタクトの先端の返しの部分を潰さない位置にある事を確認しながら、XHコンタクトを軽く挟む位置まで握り込みます。 XHコンタクトを軽く挟む位置まで握る。返しの部分はギリギリ挟まれないはず。 電線を奥まで差し込み、圧着ペンチを完全に握り込みます。 後ろの方から電線を奥まで差し込んでいる。完全に握り