2021年3月31日水曜日

デュアルコア用の機能

マルチコア用の仕組みはこれだけではなくコアの間にSIO(Single-cycle IO block)というブロックがありこの中にFIFO 0 to 1、FIFO 1 to 0というコア間でデータ転送する仕組みとHardware Spinlockというリソースの排他制御の仕組みなどがあります。


SIO(Single-cycle IO block)に含まれる機能
・CPUID
・GPIO Control
・Hardware Spinlock
・Inter-processor FIFO (Mailboxes)
・Integer Divider
・Interpolator



2021年3月30日火曜日

Tiny USB のMIDIクラスの受信ルーチン

先日見つけた Tiny USB のサンプルコードは送信しかしていなかったので受信はどうするのかなと色々見てたのですが特にドキュメントも用意されていない様子。まぁこれぐらいのことはソースコードを読んで理解しろということなのかもしれません。

とりあえずサンプルコードで送信している関数tudi_midi_write24()をgrepしてみるとこれはmidi_device.hというヘッダーファイルにインライン関数として定義されていました。
同列に用意されているAPIは以下の通り。

//--------------------------------------------------------------------+
// Application API (Single Interface)
//--------------------------------------------------------------------+
static inline bool     tud_midi_mounted    (void);
static inline uint32_t tud_midi_available  (void);
static inline uint32_t tud_midi_read       (voidbufferuint32_t bufsize);
static inline void     tud_midi_read_flush (void);
static inline uint32_t tud_midi_write      (uint8_t jack_iduint8_t constbufferuint32_t bufsize);
static inline uint32_t tudi_midi_write24   (uint8_t jack_iduint8_t b1uint8_t b2uint8_t b3);
static inline bool     tud_midi_receive    (uint8_t packet[4]);
static inline bool     tud_midi_send       (uint8_t const packet[4]);

3バイトメッセージの送信関数はあるのに2バイトメッセージの送信関数は無いんだなという中途半端感はありますが、問題はそこではなく受信関数でした。この中で受信に関係ありそうなのはtud_midi_read()とtud_midi_read_flush()。ソースコードを確認してみたところtud_midi_available()も受信用APIでした。

static inline uint32_t tud_midi_available(void);
受信FIFOにあるデータ数を返す。

static inline uint32_t tud_midi_read(void* buffer, uint32_t bufsize);
受信FIFOにあるデータを指定されたバッファにコピーする。

static inline void     tud_midi_read_flush(void);
受信FIFOをクリアする。

ということらしいのでtud_midi_available()でデータを受信しているか確認してデータがあればtud_midi_read()で読み込むというのが正しそうです。

実際のコードにするとこんな感じ

void MIDI_ReadTaskvoid )
{
    uint8_t buff[RX_BUFFSIZE];
    
    uint32_t read_size = tud_midi_available();
    if ( read_size > 0 )
    {
        int32_t i;
        read_size = tud_midi_readbuffRX_BUFFSIZE );

        for ( i=0i<read_sizei++ )
        {
            printf"0x%02X "buff[i] );
        }
        puts(" ");
    }
}

試しにMIDI-OXからノートメッセージを送信してみるとコンソールに正しく表示されました。この関数をメインループの中からポーリングしても良いですがtud_midi_rx_cb()というコールバックの仕組みも用意されているのでこちらから呼ぶのがスマートですね。
RTOSが使えるようになったらここでタスクを起床してMIDI処理をさせる流れです。

void tud_midi_rx_cb(uint8_t itf)
{
    MIDI_ReadTask();
}



2021年3月29日月曜日

「Pico RGB Keypad」を買ってみた!

 秋月で自作基板用の部品を見繕っていたらPimoroniのPico RGB Keypadを見つけ、「これはMIDIコントローラーに良いかも!」と一緒に注文してしまいました。

それが届いたので早速組み立て。といっても半田付けするようなところはなくキーパッドのシリコンパッドをネジ止めするだけです。そして公式のGitリポジトリからサンプルコードを落として、コンパイル、焼きこみ、・・・何も起こらない。

サンプルのソースコードを見るとLEDは薄く点灯してパッドを押すとLEDの色が変化する感じのようです。とりあえず良くわからないのでサンプルコードでUSB-シリアルを使えるように変更してprintfデバッグしてみたところ、どうやらスイッチは正しく読めているがLEDが全く反応しない。PICOのSPI端子の所をオシロで見てもそれなりに動いてそうです。
Pimoroni公式に何か情報ないかと見て回ったのですが、この基板の回路図すらおいてない。まぁ動いてしまえば大したことやってる基板じゃないからサンプルコードだけあれば十分なんだろうけどね。楽しみにしていた分がっかりでした。



2021年3月28日日曜日

根岸公園に行ってきた!

 桜が満開ということなので根岸公園に行ってきました。このご時世なのでホントに散歩だけしに行ったのですが、人はそれなりに多かったですが通常よりもかなり少なく迷惑な酔っ払いもいないので非常にゆっくりできました。



自動販売機にファンタプレミアムなオレンジがあったので購入しました。
グレープはちょっとファンタっぽい感じがしなかったのですが、こちらはなかなか良い感じに仕上がってると思います。







2021年3月27日土曜日

Pico用の基板ができた!

 3/14に発注した基板が今日届きました!13日後ということで2週間かからずに手に入るのはなかなか良いのではないかと思います。ほとんどが輸送にかかっている時間なので輸送にお金をかければもっと早くなるんじゃないかと思います。

こんな感じの梱包で届きました。


部品面

半田面

部品を実装するとこんな感じ

ピンヘッダーも付けたのでブレッドボードと組み合わせるもよし、ユニバーサル基板部分も設けているので開発基板としてはそれなりに使えそうです。

だがしかし、肝心のPicoが1枚しかないのでPicoprobeを使った開発がまだできないのが残念。現在追加の発注をしているので届くまではprintfデバッグで頑張ります!


2021年3月26日金曜日

Raspberry Pi Picoはデュアルコア!

Raspberry Pi PicoはRaspberry Pi財団が独自に開発したARM Cortex M0+デュアルコアのRP2040というマイコンが搭載されています。スマホに慣れた人にはデュアルコアなんて当たり前に見えるかもしれませんがARMのM系マイコンのプログラミングをしたことのある人には「え?どうなってんの?」と思わずにはいられないと思います。一般的にはメインメモリへのアクセスの競合を抑えるためにコアにキャッシュを持つのがマルチコアの常套手段だと思うのですがRP2040はM0+コアですからキャッシュなんてありません。RP2040のデータシートを見てみるとどうやらAHB-Lite crossbarというバスと6個に分割されているSRAMに仕組みがありました。AHB-Lite crossbarはクロスバーというだけあり単純なバスではなくSplitterとArbiterの組み合わせにより最大同時4転送できるようになっており分割されたSRAMを個別に割り当てることにより独立動作することが可能になっているようです。

RP2040の主な機能
• Dual Cortex M0+ processor cores, up to 133 MHz
• 264 kB of embedded SRAM in 6 banks
• 6 dedicated IO for SPI Flash (supporting XIP)
• 30 multifunction GPIO
• Dedicated hardware for commonly used peripherals
• Programmable IO for extended peripheral support
• 4 channel ADC with internal temperature sensor, 0.5 MSa/s, 12-bit conversion
• USB 1.1 Host/Device



2021年3月23日火曜日

USB-MIDIのサンプルコードはどこ?

まじめにTinyUSBのドキュメントを読み込むのは大変なのでUSB-MIDIのサンプルコードが無いかなと探していたところpico-sdk/lib/tinyusbにサンプルが含まれているという記事を見つけて、「そうかpico-exampleじゃなくてpico-sdkの方か!」と早速そのフォルダを見てみるとなんとカラでした。
WEBから見るGitリポジトリにはファイルが色々あるのでどうやら落とせてないだけみたい。Gitには詳しくないので色々調べてみたところ、Raspberry Pi Picoに直接関係が無いような部分はsubmoduleで管理しておりドキュメントで書かれているコマンドでは落ちてこないそうです。

ドキュメントに書かれているSDKを落とすコマンド
>git clone -b master https://github.com/raspberrypi/pico-sdk.git

こうするとsubmoduleも全部落としてくれる
>git clone --recursive https://github.com/raspberrypi/pico-sdk.git

私のように既に落としてしまっている場合はpico-sdkフォルダ上から
>git submodule update --init --recursive

とすると全部落としてくれます。


ちなみにUSB-MIDIのサンプルはここにありました。
pico-sdk\lib\tinyusb\examples\device\midi_test

 

2021年3月22日月曜日

Raspberry Pi Pico SDKのタイマー値を読む

スイッチをマジメに読むにはチャタリングの除去をする必要がありますが、タイマー割り込みを設定するほどのことではないのでサンプルコードにちょうど良い物がないかなと探してみたらTiny USBのコードの中でboard_millis()という関数で起動からの積算時間をミリ秒単位で取得していました。ソースコードを見てみるとTiny USBとして抽象化するためにラッピングしているだけのようなので、直接SDKのAPIを呼ぶようにします。
APIとしては to_ms_since_boot(get_absolute_time()) こんな感じでget_absolute_time()でマイクロ秒単位の時間を単純に/1000しているだけのようです。
実際のコードはほぼサンプルコードと同じにして経過時間が達していなければリターンするコードとなっています。

int32_t Switch_Taskvoid )
{
    static uint32_t start_ms = 0;
    uint32_t s,d,e;
    int32_t i;

    if (to_ms_since_boot(get_absolute_time()) - start_ms < SWITCH_INTERVAL)
    {
        return 0/* 時間になる前ならリターン */
    }
    start_ms += SWITCH_INTERVAL;
~中略~


int main()
{
    stdio_init_all();

    puts("Raspberry Pi Pico");
      
    while (1
    {
        Switch_Task();
    }


2021年3月21日日曜日

The pico project generatorで新しいプロジェクトを作ってみた

プロジェクトを手動で作る方法を延々と説明した後で、GUIでプロジェクトを作成するツールが紹介されてます。初心者にはこちらを先に教えてもらった方がうれしいのではないだろうか?

さっそくGitから落とします。
> git clone https://github.com/raspberrypi/pico-project-generator.git 

フォルダに移動して実行します
> cd pico-project-generator
> pico_project.py --gui 


Project NameとLocationを設定します。LocationはPICO_SDK_PATHがドキュメントにあるような"../../pico-sdk"感じに設定されているとこの相対パスに合うような位置にする必要があります。それを鑑みるとPICO_SDK_PATHは絶対パスで指定しておいた方が面倒がないです。
IDE OptionsにCreate VSCode projectがありますのでチェックしておくとVSCodeのOpen Folder..で開けるようになります。


2021年3月20日土曜日

Raspberry Pi Picoでスイッチ入力してみた

基板を発送したとメールが来たので、中身の方を少しづつ作っていく事にします。
まずはLチカでGPIO出力はやってみているのでブレッドボード上にSWを実装してGPIO入力を確認します。


写真の通りGPIO10とGND間にタクトスイッチを実装します。

通常スイッチ入力の場合、抵抗でプルアップしますがRP2040は各ポートに内蔵プルアップ/プルダウンの機能があるのでそれを有効にします。SDKにgpio_puull_upというAPIが用意されているのでそれを使ってプルアップ抵抗を有効にします。

    gpio_init(SW_PIN);
    gpio_pull_up(SW_PIN);
    gpio_set_dir(SW_PIN, GPIO_IN);

    while (1
    {
        if (gpio_get(SW_PIN))
        {
            gpio_put(LED_PIN1);
        }
        else
        {
            gpio_put(LED_PIN0);
        }
        sleep_ms(10);
    }

実行部分は簡単に押されてGPIOがローレベルになったらそのままLEDのGPIOもローレベルにしてLEDを消灯するというものです。

現状Picoがなかなか入手できないので2枚使ってのSWDデバッグが出来ないのでついでにprintfデバッグをするためのシリアル出力を確認しておきます。

CMakeLists.txtに下記の行を入れます。

pico_enable_stdio_usb(test 1)

標準入出力のヘッダーファイルstdio.hをインクルードします。

#include <stdio.h>

main関数の冒頭で初期化します。

    stdio_init_all();

puts関数で出力します。

    while (1
    {
        sw = gpio_get(SW_PIN);
        if (sw)
        {
            gpio_put(LED_PIN1);
            if (edge == 0)
            {
                puts("Sw turn high");
            }
        }
        else
        {
            gpio_put(LED_PIN0);
            if (edge == 1)
            {
                puts("Sw turn low");
            }
        }
        edge = sw;
        sleep_ms(10);
    }

非常に簡単です、ちなみにCMakeLists.txtの行を入れ替えるだけでUART出力に入れ替えられるようです。SDKさまさまです、とても良くできてると思います。


2021年3月19日金曜日

新規プロジェクトを作る

 サンプルコードを直接変更するのも何なので「Getting started with Raspberry Pi Pico」の「Chapter 7. Creating your own Project」の感じで新規プロジェクトを作成します。

ドキュメントではLinux環境で説明されているのでWindows用に読み替えていきます。

pico-examples/
pico-sdk/
test/

ここにtestフォルダを作成してソースコード(test.c)とCMakeLists.txt、pico_sdk_import.cmakeをコピーします。

CMakeLists.txtの中身はこんな感じ

cmake_minimum_required(VERSION 3.12)
include(pico_sdk_import.cmake)
project(test_project)
pico_sdk_init()
add_executable(test
    test.c
)
pico_enable_stdio_usb(test 1)
pico_add_extra_outputs(test)
target_link_libraries(test pico_stdlib)

pico_sdk_import.cmakeは pico-sdk/external/pico_sdk_import.cmake にあります。

testフォルダ内にbuildフォルダを作成してそこから下記のようにmakeを実行します。

cmake -G "NMake Makefiles" ..
nmake

これでtest.uf2まで作成できます。
ちなみにファイルを追加する場合はCMakeLists.txtにファイル名を追加します。

add_executable(test
    test.c
    add_file.c
)



2021年3月17日水曜日

iBUFFALO BSMOB07を分解してみた

 バッファローのマウスがホイールの調子が悪かったり電池の持ちが悪かったりと使い勝手が悪いので、先日分解したマイクロソフト マウス用の部品取りに使えないかと分解してみることにしました。


電池蓋を外してみましたがとりあえず見えるところにはネジが1本だけです、例の特殊ネジなのでT5のドライバーで外します。ところがちょっと後ろ側が浮くもののなかなか外れません、ゴム足の下にネジが隠れているのかと剥がしてみたりもしましたがネジはありませんでした。強めにかみ合っているだけのようなので強引に外しました。


上側はこんな感じ。


下側はこんな感じ、マイクロソフト マウスと比べて非常にシンプルです。使ってなかったこともあってかなりキレイです。ホイールが調子悪いのも特に汚れているからってわけでは無さそうです。そして肝心のタクトスイッチは全然違う部品でした。がっかり・・・


全部品はこんな感じ、とりあえずそのまま組みなおしました。

2021年3月16日火曜日

Microsoft Sculpt Comfort Mouse を分解してみた

 嫁が使っていたマイクロソフト マウスの右クリックが出来なくなったから捨てるというのでそれなら一度バラしてみようということで写真を取りながら分解しました。



まずは電池を外します。


両面テープで貼られている足の下に特殊ネジが4本止まっています。
MacのSSDを交換する時に買ったT5なドライバーで外すことが出来ました。


上側のケースが外れます、Winodwsキー辺りがひっかかり気味です。

SMTタイプのタクトスイッチが使われていました。

ホイールはハマっているだけなので力業で外します。

基板上のネジを外すと基板が持ち上げられます。ケーブルが半田付けされているので完全には取り外せません。どうせ全く反応しないスイッチなのでタクトスイッチもバラします。
するとなんか中央部分が黒く汚い感じです外側はキレイだったのに何故?

比較にホイールスイッチのタクトスイッチもバラしてみましたが、こちらは普通に金属の接点が見えます。嫁の話だと買った時から調子が悪かったと言うのでもしかすると最初から部品不良だったのかもしれません。


とりあえずアルコールで拭いたぐらいではびくともしないので精密ドライバーのマイナスで削ってから拭いてみました。とりあえず金属部分が見えるようになったので動作確認のために逆順に組み立てます。

結果はとりあえず右クリックで来たのですが、ちゃんと押さないと反応しないことがあり完全復活って感じにはなりませんでした。やはりタクトスイッチを交換しないとダメですね。
あまり使わないホイールスイッチと交換するか、秋葉原で似たようなタクトスイッチを探すかですね。とりあえずMac用だったら右クリック無くても良いかなと思い始めた・・・






2021年3月14日日曜日

Raspberry Pi Picoを実装する基板を作ってみた

Raspberry Pi PicoのドキュメントによるとSWDデバッグをするにはPicoを2台接続すれば良くて、接続例としてはブレッドボードを2個使用していたけどそれだとさすがにわちゃわちゃしすぎているし、PicoにはLEDが一個しか接続されていないからさすがにI/Oのテストとしてもスイッチとかもいくつかは欲しい。というわけでPicoを2個実装できる基板を作ってしまおうかと考えた。

Seeed Fusionの基板作成サービスだと100mmx100mmなら$4.9+送料でトータル2000円ぐらいで作れてしまうので失敗しても大して懐も痛まない。ホントに良い世の中になった。

以前、基板は作ったことあったのだが5年以上前に1回だけだったのですっかり忘れてしまったので、せっかくだから自分の忘備録もかねてここに手順を書いておくことにする。


・CADのインストール

フリーのCADはいくつかあるようですが、Picoの公式から出ている設計データがKiCADなのと依然作った時もKiCADだったので迷う必要もなくKiCAD一択です。

https://kicad.org/

ここからWindows 64bit版をダウンロードして、インストール。最新版は5.1.9でした。

Picoの部品データが欲しいのでhardware-design-with-rp2040.pdfに載っている「The VGA, SD Card & Audio Demo board」の設計データを落とします。

https://datasheets.raspberrypi.org/rp2040/VGA-KiCAD.zip


・回路図の作成

起動して新規作成するとこんな感じです。

回路図CADを起動します。必要があれば図面サイズなどを変更します。最初に先ほど落としたPicoを含む部品ライブラリを読み込まなければいけないので設定>シンボルライブラリを管理...でライブラリのパスを登録します。



1. 部品を配置する

右側のツールバーの上から3番目にある「シンボルを配置」を選択してシート内をクリックすると「シンボルを選択」ダイアログが現れるので左ペインでRPi_Pico>Picoを選択してOKするとPico回路図部品が配置できます。今回は2個実装しますので同じ手順で2個配置します。

その他の部品も同じ手順で配置していきます。


2.配線する

右側のツールバーの上から5番目にある「ワイヤーを配置」を選択して端子と端子を接続していきます。


3.部品のリファレンス番号を設定する

部品を右クリックしてプロパティ>リファレンスを編集...でも設定できますが、最初は「回路図シンボルをアノテーション」を使って自動でリファレンス番号を割り振った方が楽です。

4.ERCで確認する

上部ツールバーのてんとう虫アイコン「エレクトリカル ルールのチェックを行う」を押してダイアログを開きERCを実行します。ただPicoの部品はERCが通るようには設定されていないようなので今回はあまり気にしないことにします。

5.ネットリストを出力する

上部ツールバーのNETアイコン「ネットリストを生成」を押してダイアログを開きネットリストを出力します。


・基板の作成

1.部品ライブラリを読み込む

設定>フットプリントライブラリを管理...でライブラリのパスを設定します。


2.ネットリストを読み込む

上部ツールバーのNETアイコン「ネットリストをロード」を押してダイアログを開き先ほど出力したネットリストを読み込みます。

ライブラリの設定がうまくいっているとここで部品がドカンと出てきます。

うまくいかない場合は回路図シンボルとフットプリント部品の関連付けがうまくいってないので回路図CADの方から「回路図シンボルへPCBフットプリントへ関連付けをする」で開いたダイアログで設定します。


3.外形やネジ穴を書く

左側のツールバーで単位系をミリメートル系に設定して外形Edge.Cuts層に入力します。
右側ツールバーの「寸法線を追加」機能を使うと簡単に寸法を入れることができます。


4.部品を配置する

コネクタとか場所が決まっているものから配置していきます。


5.信号線を配線する。

頑張って引き切ります。


6.シルク位置を調整する

フットプリントのデフォルトの位置だと部品同士が干渉してしまうことが多々あるので一つ一つ調整していきます。


7.べたパターンを作る

Raspberry Pi Picoにはファクトリーテスト用に裏面にパッドが用意されていますが、これに干渉しないように配線禁止のエリアがありPicoのフットプリント部品にはDwgs.User層にべたが入力されているのでこれに合わせてべた禁止領域を設定する必要があります。


8.DRCで確認する

上部ツールバーのてんとう虫アイコンをクリックしてダイアログを開きDRCを実行します。全部配線できていればエラーなしになるはずです。


9.3Dビューアーで確認

表示>3Dビューアーで完成基板のイメージが表示できるので、配線やシルクなどがイメージ通りかを確認しましょう。意外とシルクの不備はこの段階で良く見つかります。


10.ガーバーデータを出力する

上部ツールバーのプロットアイコンをクリックしてダイアログを開きガーバーデータとドリルデータを出力します。

出力されたファイルはまとめてZIP化しておきます。


11.Fusionのサイトにデータをアップロードする。

https://www.seeedstudio.com/fusion_pcb.html


サイトにアップデートすると完成見本が表示できるので最終確認してOKならカートに入れて発注します。


値段は10枚で$4.9と一番安い輸送費で$14.6、合わせて$19.5でした。






2021年3月13日土曜日

tyny USB

Raspberry Pi PicoのSDKで採用しているUSBスタックはtyny USB。
tynyUSBはGithubの説明文を読むと組み込みシステム用のオープン ソースクロスプラットフォーム USB ホスト/デバイス スタックだそうです。

GitHub - hathach/tinyusb: An open source cross-platform USB stack for embedded system

ここでサポートしているクラスは以下のように紹介されています。

  • USB オーディオ クラス 2.0 (UAC2) 開発中
  • Bluetooth ホスト コントローラ インターフェイス (BTH HCI)
  • 通信クラス (CDC)
  • デバイス ファームウェアの更新 (DFU): Runtinme のみ
  • ヒューマンインタフェースデバイス(HID):ジェネリック(イン&アウト)、キーボード、マウス、ゲームパッドなど.
  • 大容量ストレージ クラス(MSC): 複数の LUN 対応
  • Music Instrument Digital Interface(MIDI)
  • RNDIS、CDC-ECM を使用したネットワーク (開発中)
  • USBテストおよび測定クラス(USBTMC)
  • 汎用の In & Out エンドポイントを使用したベンダー固有のクラスサポート。INF ファイルなしの winUSB ドライバーをロードする MS OS 2.0 互換の記述子と使用できます。
  • ベンダ固有のクラスを使用するWebUSB
ホストもHIDとMSCに対応となっていますが開発中でテスト不十分となっています。

サンプルコードに含まれるtusb_config.hにも下記のようにマクロ定義されています。
//------------- CLASS -------------//
#define CFG_TUD_CDC             0
#define CFG_TUD_MSC             0
#define CFG_TUD_HID             1
#define CFG_TUD_MIDI            0
#define CFG_TUD_VENDOR          0

これを見るとMIDIクラスはSDKでもサポートされていそうですがサンプルコードはありません、この辺は早めに試してみたいところです。

2021年3月11日木曜日

Raspberry Pi Pico USBのVID&PID

電子工作でUSBデバイスを作成する時に困るのがVID&PIDの取得です。
これをもとにドライバーのロードとかしているので公開する場合は正しいVID&PIDは必須です。

VIDの取得はここのページで紹介しています。

https://www.itf.co.jp/tech/road-to-usb-master/get-vid

ですが個人で取れるかもわかりませんしVIDの取得だけでも費用が$6000となっています。日本円で60万円以上かけるのは個人の電子工作としては現実的ではありません。

サンプルコード(CDC)はどんな値を使っているのか、Hello World(USB)を実行して確認してみました。

VID:2E8A
PID:000A

ブートモードのMSCは以下の通り。

VID:2E8A
PID:0003

厳密にはNGでしょうが、とりあえず同じクラスを使う分にはそのまま使っても実害は無さそうです。

2021年3月9日火曜日

Raspberry Pi Pico サポートサイト

 ブートモード時に表示されるINDEX.HTMをクリックすると以下のサイトにリダイレクトされ

https://www.raspberrypi.org/documentation/rp2040/getting-started/

ドキュメント、RP2040を使用したボード、プロジェクトなどが紹介されています。


ここにFAQドキュメントが公開されてました。中を見てみると色々書いてある中でRTOSに触れられており、移植中と書いてあります。FreeRTOSでも移植しても良いかもと思っていたのですが、ここはおとなしく待つこととします。デュアルコアのサポートとかも含まれるのかが興味ある所です。


2021年3月8日月曜日

Raspberry Pi Pico にリセットスイッチを付けてみた

「ブートスイッチを押しながらケーブルを差すだけでブートモードに」なるわけですが、このケーブルの抜き差しが意外と面倒です。要はリセットをかければ良いのでリセットスイッチを付けることにしました。ピンを半田付けしてブレッドボードに差し30ピンの「RUN」端子とGNDをショートするようにしました。これで書き込みがちょっとだけ簡単になります。
早くもう一枚買ってSWDでデバッグできるようにした方が良いな・・・





2021年3月7日日曜日

Raspberry Pi Pico を動かしてみた

 とりあえず実機が手に入ったので定番のLチカでもしてみようと思います。といってもサンプルコードですでに用意されているのでそれを焼きこむだけです。

何も焼きこんでいない状態のPicoはUSBケーブルを刺すだけでブートモードになるようでドライブが現れますのでサンプルで用意されていたblink.uf2をドラッグアンドドロップで書き込みます。そうすると自動的にドライブが切断されてLEDがチカチカし始めました。非常にあっさりです。

ここでどれぐらいの速度でGPIOポートを操作できるのか確認しようとsleep関数をコメントアウトしてみました。

int main() {
    const uint LED_PIN = 25;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PINGPIO_OUT);
    while (true) {
        gpio_put(LED_PIN1);
    //    sleep_ms(250);
        gpio_put(LED_PIN0);
    //    sleep_ms(250);
    }
}

想定では少し暗くLEDが点灯するはずですが、消灯のままです。最適化でコードが無くなっちゃってるのかと思いアセンブラ出力ファイルblink.disを開いてみるとmain関数はこんな感じでコードが無くなっている感じはありません。

sleepあり

1000030c <main>:
1000030c: b570      push {r4, r5, r6, lr}
1000030e: 2019      movs r0, #25
10000310: f000 f82a bl 10000368 <gpio_init>
10000314: 23d0      movs r3, #208 ; 0xd0
10000316: 061b      lsls r3, r3, #24
10000318: 2280      movs r2, #128 ; 0x80
1000031a: 0492      lsls r2, r2, #18
1000031c: 625a      str r2, [r3, #36] ; 0x24
1000031e: 24d0      movs r4, #208 ; 0xd0
10000320: 0624      lsls r4, r4, #24
10000322: 2580      movs r5, #128 ; 0x80
10000324: 04ad      lsls r5, r5, #18
10000326: 6165      str r5, [r4, #20]
10000328: 20fa      movs r0, #250 ; 0xfa
1000032a: f000 fcb1 bl 10000c90 <sleep_ms>
1000032e: 61a5      str r5, [r4, #24]
10000330: 20fa      movs r0, #250 ; 0xfa
10000332: f000 fcad bl 10000c90 <sleep_ms>
10000336: e7f2      b.n 1000031e <main+0x12>

sleepなし

1000030c <main>:
1000030c: b510      push {r4, lr}
1000030e: 2019      movs r0, #25
10000310: f000 f824 bl 1000035c <gpio_init>
10000314: 23d0      movs r3, #208 ; 0xd0
10000316: 061b      lsls r3, r3, #24
10000318: 2280      movs r2, #128 ; 0x80
1000031a: 0492      lsls r2, r2, #18
1000031c: 625a      str r2, [r3, #36] ; 0x24
1000031e: 23d0      movs r3, #208 ; 0xd0
10000320: 061b      lsls r3, r3, #24
10000322: 2280      movs r2, #128 ; 0x80
10000324: 0492      lsls r2, r2, #18
10000326: 615a      str r2, [r3, #20]
10000328: 619a      str r2, [r3, #24]
1000032a: e7f8      b.n 1000031e <main+0x12>

赤字の部分がGPIOへのセットとリセットですが1命令で並んでいるのでペリフェラルへアクセスするタイミングでは同タイミングになってしまい無かったことになっているか100MHzのオシロスコープでは見えないようなパルスになっているのかもしれません。
試しに0と1の順番を変えてみるとLEDは点灯しっぱなしになりました。

    while (true) {
        gpio_put(LED_PIN0);
    //    sleep_ms(250);
        gpio_put(LED_PIN1);
    //    sleep_ms(250);
    }


しょうがないのでレジスタアクセスを無駄に1個増やしてみたところ、無事パルスが出るようになりました。

int main() {
    const uint LED_PIN = 25;
    const uint GPIO_PIN = 22;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PINGPIO_OUT);
    gpio_init(GPIO_PIN);
    gpio_set_dir(GPIO_PINGPIO_OUT);
    while (true) {
        gpio_put(LED_PIN0);
    //    sleep_ms(250);
        gpio_put(GPIO_PIN1);
        gpio_put(LED_PIN1);
    //    sleep_ms(250);
    }
}


1000030c <main>:
1000030c: b510      push {r4, lr}
1000030e: 2019      movs r0, #25
10000310: f000 f82e bl 10000370 <gpio_init>
10000314: 24d0      movs r4, #208 ; 0xd0
10000316: 0624      lsls r4, r4, #24
10000318: 2380      movs r3, #128 ; 0x80
1000031a: 049b      lsls r3, r3, #18
1000031c: 6263      str r3, [r4, #36] ; 0x24
1000031e: 2016      movs r0, #22
10000320: f000 f826 bl 10000370 <gpio_init>
10000324: 2380      movs r3, #128 ; 0x80
10000326: 03db      lsls r3, r3, #15
10000328: 6263      str r3, [r4, #36] ; 0x24
1000032a: 23d0      movs r3, #208 ; 0xd0
1000032c: 061b      lsls r3, r3, #24
1000032e: 2280      movs r2, #128 ; 0x80
10000330: 0492      lsls r2, r2, #18
10000332: 619a      str r2, [r3, #24]
10000334: 2180      movs r1, #128 ; 0x80
10000336: 03c9      lsls r1, r1, #15
10000338: 6159      str r1, [r3, #20]

1000033a: 615a      str r2, [r3, #20]
1000033c: e7f5      b.n 1000032a <main+0x1e>

0x1000032aからのループなのでちょうど10ステップ、このループが12MHzぐらいで回っているので、I/Oアクセスでもそれほどスピードが落ちていない感じです。


2021年3月2日火曜日

Raspberry Pi Pico が届いた!

どこでも品切れなPicoですがアマゾンでちょっと割高ですが売ってるのを見つけたので1枚買ってみました。

Raspberry Pi的な箱に入ってくるのかと思ったら電子パーツっぽくこんなパッケージで送られてきました。




USB端子の足はどうなってるのかと思っていたのですが切ってあるのか出っ張っていませんでした。まぁ表面実装できると言ってるんだから当たり前ですが。


 

Visual Studio Codeを使った開発環境の構築

 「Getting started with Raspberry Pi Pico」のチャプター8.2.4.にVisual Studio Codeを使ったビルド方法が解説されているのでこちらも試してみることにします。Visual Studio Codeは先にインストールしたVisual Studio 2019とは別物でマイクロソフトが作ったオープンソースなコードエディターで最近ではかなり人気のある開発環境なそうです。

まずマイクロソフトのサイトからダウンロードしてインストールします。https://code.visualstudio.com/download

インストールが完了したらスタートメニューからではなくVisual Studio 2019のDeveloper Command Prompt for VS2019を起動してそこでcodeと入力してVisual Studio Codeを起動します。
これをしないと環境変数などのツールチェーンの設定が正しく行われないと注意が書かれています。
次に、CMakeTools extensionをインストールします。 左側のツールバーのExtensionsアイコンをクリックして(またはCtrl + Shift + X)、「CMake Tools」を検索しリストのエントリをクリックしてからインストールボタンをクリックします。
インストールされたCMakeTools extensionの歯車アイコンををクリックし、[Extension Settings]を選択します。「Cmake:Buid Environment」まで下にスクロールします。 [Add Item]をクリックして、「PICO_SDK_PATH」に「.. \ .. \ pico-sdk」と設定します。 

さらに下にスクロールして「Cmake:Generator」に「NMake Makefiles」と設定します。

次にサンプルプロジェクトを開きます。[File]メニューから[Open Folder...]でフォルダー選択ダイアログを開きpico-examplesフォルダを選択します。[OK]をクリックすると プロジェクトを構成するように求められます。コンパイラーとして「GCCforarm-none-eabi」を選択するとプロジェクトが設定されますので下部にある歯車アイコン+ビルドをクリックするとプロジェクトがビルドされます。


2021年3月1日月曜日

Windows環境への開発ツールのインストール

「Getting started with Paspberry Pi Pico」のチャプター8にWindowsへのインストール手順があるのでそれ通りに実行します。
記載がある以下のツールをダウンロードしてインストールしていきます。
ドキュメントに載っているものよりも新しいものがあればそれをチョイスしていきます。

・ARM GCC compiler
・CMake
・Build Tools for Visual Studio 2019
・Python 3
・Git


・ARM GCC compiler

https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads
10-2020-q4-major
gcc-arm-none-eabi-10-2020-q4-major-win32.exe
Windows 32-bit Installer (Signed for Windows 10 and later) 

Windows64bit用は無いみたいなので32bitの物をダウンロード


「ARMコンパイラへのパスを環境変数としてWindowsシェルに登録する必要があります。」とありますのでチェックボックス「Add path to environment variable」にチェックを入れます。



・CMake

https://cmake.org/download/

マニュアルには詳しい情報がなかったので正式版の最新の中から
cmake-3.19.6-win64-x64.msi
をダウンロードして、インストール。


こちらも「すべてのユーザーのシステムPATHにCMakeを追加します。」とあるのでインストール中に表示されるラジオボタンで「Add CMake to the system PATH for all users.」を選択します。


・Build Tools for Visual Studio 2019

https://visualstudio.microsoft.com/ja/downloads/

Visual Studio Communityを選択

「C ++ビルドツールのみをインストールする必要があります。 」とありますが具体的にどれを入れたらいいのかわからないのでドキュメントのスクリーンショットに載ってるアイテムを選択。
だけど「Testing tools core features - Build Tools」だけ見つからないけどあまり気にしない方向で。

・MSVC v1.42 - VS 2019 C++ x64/x86 build tools
・Windows 10 SDK
・C++ CMake tools for Windows
・Testing tools core features - Build Tools
・C++ AddressSanitizer


・Python 3

https://www.python.org/downloads/windows/
Python 3.9.2 - Feb. 19, 2021
Windows installer (64-bit)



「すべてのユーザーのシステムPATHにPython3.7を追加します。」

 「MAX_PATHの長さをさらに無効にする」を選びます。 


・Git

https://git-scm.com/download/win
latest (2.30.1) 64-bit version of Git for Windows.

「Gitをインストールするときは、デフォルトのエディターをvimから変更する必要がある。」とあるのでNotepadをとりあえず選んでおきます。

特に理由がない限り、Gitをインストールするときは、[Checkout as is, commit as-is]チェックボックスをオンにして、[Use Windows]を選択する必要があります。 インストールプロセス中の「Use Windows' default console window」、および「Enable experimental support for pseudo consoles」。 


・SDKとサンプルコードの取得

コマンドプロンプトからドキュメントの通りのコマンドで取得します。
ユーザーフォルダを使うとパスに2バイト文字を含んでしまうので念のためパスを変更しました。

C:\Data\pico\Downloads> git clone -b master https://github.com/raspberrypi/pico-sdk.git
C:\Data\pico\Downloads> cd pico-sdk
C:\Data\pico\Downloads\pico-sdk> git submodule update --init
C:\Data\pico\Downloads\pico-sdk> cd ..
C:\Data\pico\Downloads> git clone -b master https://github.com/raspberrypi/pico-examples.git


・"Hello World"をコマンドラインからビルドする

Visual Studio 2019に含まれるDeveloper Command Promptを起動します。ウィンドウズメニューの "Visual Studio 2019 > Developer Command Prompt"から起動します。

以下のコマンドを実行してPICO SDKのパスを設定します。

C:\Users\pico\Downloads> setx PICO_SDK_PATH "..\..\pico-sdk"

追記:ドキュメントに習うとここでパスを相対パスで設定していますが絶対パスにしておいた方が後々良い気がします。

このコマンドを実行したらコマンドウィンドウを閉じてもう一度開きなおします。これを忘れるとパスが正しく設定されず次のビルドでエラーになってしまいます。
というわけで新しく開いたコマンドウィンドウから書きコマンドを実行してビルドします。

C:\Data\pico\Downloads> cd pico-examples
C:\Data\pico\Downloads\pico-examples> mkdir build
C:\Data\pico\Downloads\pico-examples> cd build
C:\Data\pico\Downloads\pico-examples\build> cmake -G "NMake Makefiles" ..
C:\Data\pico\Downloads\pico-examples\build> nmake

これによりビルドディレクトリ内のhello_worldディレクトリに ELF、bin、およびuf2ターゲットが生成されました。UF2バイナリはUSBを使用してPCからPaspberry Pi Picoボードに直接ドラッグアンドドロップで書き込むことができます。