2021年5月28日金曜日

PIOを見直してみる

前回Picoでパソピア700のUSBキーボードアダプタを作ってみたが、安定しない。

Core1とPIOのFIFOバッファやりとりに速度のばらつきがありそうなので、そこに依存しないPIOの使い方を考えてみる。

まずは回路図の見直し


今回は8bitのデータ保持用に、74LS574を追加。
配線してみると、こんな感じ

PicoとUSBキーボードを接続し、DIN13pinはPasopia700と接続する

Raspberry Pi Picoには、133MHzで動作する2つのコアと、それとは独立に動作するプログラマブルI/O(PIO)を8つ持っている。

今回は1つのコア(Core0)と8つのPIO(PIO0 SM0-3とPIO1 SM0-3)を使って、以下の処理を試してみる
(1) Core0でUSBキーボードで押されたキーの情報を、8つのPIOの各FIFOバッファに格納
(2) PIOでパソピアからの7bitスキャン信号(GPIO10-16)をCLK立ち上がり時に読み込み、FIFOに格納されているビット情報から1bitを決めて出力。8つのPIOがそれぞれのGPIOに出力して、8bitデータをGPIO2-9に出力
(5) 前回保存しておいた7bitスキャン信号は74LS574に保存してあるので、キー入力に変化があった場合、押されたキーの情報を、8つのPIOの各FIFOバッファに格納し、8つのPIOを再呼び出しすることでGPIO2-9の出力データを更新する

PIOの都合もあって、FIFOに渡す32bitのデータ配列は以下の並びに
Bit 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
KeyBlock A&B&C B&C A&C C A&B B A None
KeyScanLine0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 KeyOff(0), KeyOn(1)

パソピア700から届く7bitのスキャン信号は、3bitのKeyBlockと4bitのKeyScanLine信号。
7bit全ての組み合わせを保存するのに128bitデータ領域が必要だが、FIFO 1つで対応したかったので32bitにキー情報を収める。
KeyBlockは3bit全ての組み合わせを持ち、KeyScanLineはそれぞれのビット毎にKeyOn/Offデータを保持する。どれか1つでもKeyOn(1)があれば、そのGPIOはLow出力する。

例えば以下表Exampleのように、7bitのスキャン信号(0b0110101)が届いた場合、
Pico GPIO GP16 GP15 GP14 GP13 GP12 GP11 GP10
DIN13pin 9pin 8pin 7pin 6pin 5pin 4pin 3pin
Pasopia700 KeyBlock_C KeyBlock_B KeyBlock_A KeyScanLIne_3 KeyScanLIne_2 KeyScanLIne_1 KeyScanLIne_0
Example 0 1 1 0 1 0 1 0b0110101

KeyBlockはAとBが有効なので、FIFOの15~12bitのデータをチェックする
KeyScanLineは0と2が有効なので、FIFOの15bitと13bitの値をチェックし、どちらか1つでも1があれば、GPIOのピンにLow(0)をセットする
パソピア700とKeyScanLineの並びが逆だったり、出力信号のLow/Highが逆だったりするが、PIOの制約があったのでFIFOはこの並び順にした。

出来上がったPIOは以下
.program usbkey
.side_set 1 opt

usbkey_start:
    wait 0 gpio 18 [7]  ; GP18(=Din11pin=CLK)が0になるまで待つ
    wait 1 gpio 18 [1]  ; GP18(=Din11pin=CLK)が1になるまで待つ
    // バッファ(74LC574)がある場合、Pinデータを読み込む前に1clock必要
    in NULL, 32     ; ISRを初期化 →(ISR) |0|...|0|

    ; SideSetピンを1にセットして、TX FIFO(32bitデータ)をOSRに読み出し
    ; noblockオプション: FIFOが空の場合、Scratch XからOSRにコピー
    pull noblock side 1
    mov X, OSR ; 次回FIFOが空だった場合に備えてOSR値をScratch Xにコピー

    ; Pins(GP10-GP16)の7bitデータをInput Shift Register (ISR)にセット
    in pins, 7      ; ISRを7bitシフトした後、pinデータ読み込み
    mov OSR, ISR  ; ISRをOSRにコピー(OSRのShiftCounterもゼロリセット)
    mov ISR, X  ; XレジスタをISRにコピー(ISRのShiftCounterもゼロリセット)

    out Y, 1        ; OSRの左1bitデータをYレジスタにセット
    jmp !Y shift_keyblock_c_end ; Yレジスタ=0(KeyBlock_C=0)ならジャンプ
    in NULL, 16  ; 16bitシフト
shift_keyblock_c_end:
    out Y, 1        ; OSRの左1bitデータをYレジスタにセット
    jmp !Y shift_keyblock_b_end ; Yレジスタ=0(KeyBlock_B=0)ならジャンプ
    in NULL, 8    ; 8bitシフト
shift_keyblock_b_end:
    out Y, 1        ; OSRの左1bitデータをYレジスタにセット
    jmp !Y shift_keyblock_a_end ; Yレジスタ=0(KeyBlock_A=0)ならジャンプ
    in NULL, 4    ; 4bitシフト
shift_keyblock_a_end:

    in ISR, 4
    in NULL, 28  ; ISRの左28bitをゼロ埋め
keyscanline_loop:
    mov Y, OSR  ; YレジスタにOSRの内容をコピー
    jmp !Y keyscanline_end ; Y(OSR)=0(KSL=全てLow)の場合はループ終了
    out Y, 1        ; OSRの左1bitデータをYレジスタに左シフト
    jmp !Y keyscanline_Low ; Y=0(KSLx=0)の場合は次のビット判定にJump

keyscanline_High:
    in ISR, 1      ; ISRのSETビット列を1ビットループ
    jmp keyscanline_loop
keyscanline_Low:
    in NULL, 1    ; ISRのSETビット列を1ビット破棄
    jmp keyscanline_loop
keyscanline_end:
    in NULL, 28  ; 左4bitの値のみ有効にする
    mov Y, ISR   ; YレジスタにISRの内容をコピー
    jmp !Y usbkey_start ; Y=0(SETx全て0)なら、指定Pin=Highのまま戻る
set_pin_low:
    nop side 0 ; Y!=0(SETxいずれか1)なら、指定Pin=LowにしてStartに戻る

% c-sdk {
static inline void usbkey_program_init(PIO pio, uint sm, uint offset, uint pin) {
    pio_gpio_init(pio, pin);
    pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
    pio_gpio_init(pio, 10);
    pio_gpio_init(pio, 11);
    pio_gpio_init(pio, 12);
    pio_gpio_init(pio, 13);
    pio_gpio_init(pio, 14);
    pio_gpio_init(pio, 15);
    pio_gpio_init(pio, 16);
    pio_sm_set_consecutive_pindirs(pio,  // [pio] The PIO instance
      sm,  // [sm] State machine index (0..3) to use
      10,  // [pin_base] the first pin to set a direction for
      7,  // [pin_count] the count of consecutive pins to set the direction for
      false);  // [is_out] the direction to set; true = out, false = in

    pio_sm_config c = usbkey_program_get_default_config(offset);
    sm_config_set_sideset_pins(&c, pin);
    sm_config_set_in_pins(&c,
      10);  // [in_base] 0-31 First pin to set as input
    sm_config_set_in_shift(&c,  // INは右シフト
      true,  // [shift_right] true to shift ISR to right, false to shift ISR to left
      false, // [autopush] whether autopush is enabled
      32);  // [push_threshold]
    sm_config_set_out_shift (&c,  // OUTは左シフト
      false,// [shift_right] true to shift OSR to right, false to shift OSR to left
      false, // [autopull] whether autopull is enabled
      32);  // [pull_threshold]

    pio_sm_init(pio,  // [pio] The PIO instance; either pio0 or pio1
      sm,     // [sm] State machine index (0..3)
      offset, // [initial_pc] the initial program memory offset to run from
      &c);  // [config] the configuration to apply (or NULL to apply defaults)
    pio_sm_set_enabled(pio,  // [pio] The PIO instance; either pio0 or pio1
      sm,     // [sm] State machine index (0..3)
      true);  // [enabled] true to enable the state machine; false to disable
}
%}
PIOの命令数はギリギリ31に収めた。マニュアルには32が上限とあり、確かに32命令でもビルドが通るが、31命令以下にしないとPico実行時にAssertで止まってしまう。

PIOの設定は、C言語側で行う
void init_pio(void) {
    uint offset0 = pio_add_program(pio0, &usbkey_program);
    usbkey_program_init(pio0, 0, offset0, 2);     // GP2
    usbkey_program_init(pio0, 1, offset0, 3);     // GP3
    usbkey_program_init(pio0, 2, offset0, 4);     // GP4
    usbkey_program_init(pio0, 3, offset0, 5);     // GP5

    uint offset1 = pio_add_program(pio1, &usbkey_program);
    usbkey_program_init(pio1, 0, offset1, 6);     // GP6
    usbkey_program_init(pio1, 1, offset1, 7);     // GP7
    usbkey_program_init(pio1, 2, offset1, 8);     // GP8
    usbkey_program_init(pio1, 3, offset1, 9);     // GP9

    pio0->txf[0] = 0;
    pio0->txf[1] = 0;
    pio0->txf[2] = 0;
    pio0->txf[3] = 0;
    pio1->txf[0] = 0;
    pio1->txf[1] = 0;
    pio1->txf[2] = 0;
    pio1->txf[3] = 0;
}
FIFOに登録するキーデータは、定義しておく
typedef struct {
    uint32_t nKeyReturnValue;
    uint8_t keyReturnPin;
    uint8_t modifier;
} PASOPIA700_KEYMAP;

static const PASOPIA700_KEYMAP keyMap[256] = {
    {0x00000000, 0x08, 0x00},   // 00:No Event -> Nop
    {0x00000000, 0x08, 0x00},   // 01:Overrun Error -> Nop
    {0x00000000, 0x08, 0x00},   // 02:POST Fail -> Nop
    {0x00000000, 0x08, 0x00},   // 03:ErrorUndefined -> Nop
    {0x22220000, 0x00, 0x00},   // 04:a A -> A チ
    {0x11110000, 0x03, 0x00},   // 05:b B -> B コ
    {0x11110000, 0x02, 0x00},   // 06:c C -> C ソ
    …
    {0x00000000, 0x08, 0x00}    // FF:RESERVED -> Nop
};
キーが押されたタイミングで、新しいキーデータを各PIOのFIFOに登録しCLK信号をラッチ
static inline void process_kbd_report(hid_keyboard_report_t const *p_new_report) {
    const PASOPIA700_KEYMAP* pKey;
    uint32_t keyReturn[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
    uint8_t modifier = p_new_report->modifier;

    // Key1
    pKey = keyMap + p_new_report->keycode[0];
    keyReturn[pKey->keyReturnPin] |= pKey->nKeyReturnValue;
    modifier |= pKey->modifier;
    …
    // Key6
    pKey = keyMap + p_new_report->keycode[5];
    keyReturn[pKey->keyReturnPin] |= pKey->nKeyReturnValue;
    modifier |= pKey->modifier;
    // Modifier
    if (0 < (modifier & 0b00100010)) {
        keyReturn[1] |= 0x80808080;     // modifier[bit1]=Shift -> KS0[bit1]=SHIFT
    }
    …
    // 各PIOのFIFOにセットする
    pio0->txf[0] = keyReturn[0];  // GP2
    pio0->txf[1] = keyReturn[1];  // GP3
    pio0->txf[2] = keyReturn[2];  // GP4
    pio0->txf[3] = keyReturn[3];  // GP5
    pio1->txf[0] = keyReturn[4];  // GP6
    pio1->txf[1] = keyReturn[5];  // GP7
    pio1->txf[2] = keyReturn[6];  // GP8
    pio1->txf[3] = keyReturn[7];  // GP9

    // GP20を一旦LOWにして、GP18(CLK)に出力する
    gpio_put(20, 0);
    gpio_put(20, 1);
パソピア700から届くCLK(Pin11)とPicoのGP20のどちらかがLowなら、GP18にLowが入るようにAND回路を組んでおく。

実際にPasopia700に接続して、ロジアナで計測してみる

DIR=High(パソピア700から7bitスキャン信号が届く)になった直後、KeyScanLine信号がふらついてる。但しCLK立ち上がり時は安定しているので大丈夫そう。
DIR=Low(Picoから8bit信号線を送る)の後に少しふらついている。
CLK信号の立ち上がりにPIOが動作するようにしているので、これは良くない。。

上の回路図に書いたが安全のため、8bit信号線とCLK、DIR、全てにプルアップ、プルダウンをつけると安定した。
上のキャプチャは、A0~A7がKeyScanLine、B0がCLK、B1がDIR
ふらつきが無くなって、全てのキーが安定して入力されるようになった。

多分こんな変態的なPIOの使い方はあまりないと思うが、なんかやりきった感はある。
満足...

2021年5月16日日曜日

PicoでPasopia700 USB Keyboard Adaptor

以前AVR 2個でPasopia700用USBキーボードアダプタを作成したが、今回はPicoで試してみる

パソピア700の信号は、前回の解析結果を参考。

今回Pico用に作成した回路図は以下。

AVRの時と違って、ピンの数が多いので入力と出力を別々のピンで処理できる。

DIR信号によって入力・出力が変わる部分は、やはりソフト切替えだと危険なので74LS541で制御させる。

基板に配線してみた。

5VはDIN13ピン経由でパソピア700から入力するが、デバッグ用にACアダプタの電源ラインは残しておく。

Picoを乗せてUSBキーボードを接続するとこんな感じ

Raspberry Pi Picoには、133MHzで動作する2つのコアと、それとは独立に動作するプログラマブルI/O(PIO)を8つ持っている。

今回は2つのコア(Core0とCore1)と2つのPIO(StateMachine0と StateMachine1)を使って、以下の処理を試してみる
(1) Core0でUSBキーボードで押されたキーをバッファに格納
(2) PIO(SM0)でパソピアからの7bitスキャン信号(GPIO10-16)を、CLK立ち上がり時に読み込み、FIFO経由でCore1に7bitスキャン信号を渡す
(3) Core1は7bitスキャン信号に該当するキー入力データを読み込み、FIFO経由でPIO(SM1)に渡す
(4) PIO(SM1)はFIFOから受け取った8bitデータをGPIO2-9に出力
(5) キー入力に変化があった場合、前回保存しておいた7bitスキャン信号に該当するキー入力データを読み込み、SM1経由でGPIO2-9に出力


まずはCore1を起動し、PIOからの7bitデータ読み込みと8bitデータ出力をさせる
int main(void) {
...
    // Start Core1 for multithread
    stdio_init_all();
    multicore_launch_core1(core1_entry);
...
}

uint8_t keyscan;
volatile uint8_t* pPioKeyReturnFifo = (volatile uint8_t*)&pio0->txf[1];

void core1_entry(void) {
...
    while (1) {
        keyscan = (uint8_t)pio_sm_get_blocking(pio0, 0);  // KeyScan
        *pPioKeyReturnFifo = keyStatus[keyscan];  // KeyReturn
    }
}

PIO(SM0)で、7bitスキャン信号を読み取りFIFOバッファに書き込む
.program usbkey_keyscan

.wrap_target
    wait 0 gpio 18 [7]    ; GP18(=DIN11pin=CLK)が0になるまで待つ
    wait 1 gpio 18    ; GP18(=DIN11pin=CLK)が1になるまで待つ
    nop [1]      ; Pinデータを読み込む前にWait
    in pins, 7    ; GPIO10-16の内容を読込み、FIFOバッファにAutoPush
.wrap

% c-sdk {
static inline void usbkey_keyscan_program_init(PIO pio, uint sm, uint offset) {
    pio_gpio_init(pio, 10);
    pio_gpio_init(pio, 11);
    pio_gpio_init(pio, 12);
    pio_gpio_init(pio, 13);
    pio_gpio_init(pio, 14);
    pio_gpio_init(pio, 15);
    pio_gpio_init(pio, 16);
    pio_sm_set_consecutive_pindirs(pio, sm, 10, 7, false);  // GPIO10以降の7pinを入力ピンとしてセット
    pio_sm_config c=usbkey_keyscan_program_get_default_config(offset);
    sm_config_set_in_pins(&c, 10);  // inputの最初のピンをGPIO10に設定
    sm_config_set_in_shift(&c, false, true, 7);  // シフト方向はLeft、7bit入力したらAutoPush
    pio_sm_init(pio, sm, offset, &c);
    pio_sm_set_enabled(pio, sm, true);
}
%}

PIO(SM1)で、FIFOバッファに書き込まれた8bitデータをGPIO2-9に出力
.program usbkey_keyreturn

.wrap_target
    pull block  ; FIFOに入力されるまで待つ
    out pins, 8  ;GPIO2-9にデータを出力
.wrap

% c-sdk {
static inline void usbkey_keyreturn_program_init(PIO pio, uint sm, uint offset) {
    pio_gpio_init(pio, 2);
    pio_gpio_init(pio, 3);
    pio_gpio_init(pio, 4);
    pio_gpio_init(pio, 5);
    pio_gpio_init(pio, 6);
    pio_gpio_init(pio, 7);
    pio_gpio_init(pio, 8);
    pio_gpio_init(pio, 9);
    pio_sm_set_consecutive_pindirs(pio, sm, 2, 8, true);  // GPIO2以降の8pinを出力ピンとしてセット
    pio_sm_config c=usbkey_keyreturn_program_get_default_config(offset);
    sm_config_set_out_pins(&c, 2, 8);  // outputピンをGPIO2-9に設定
    sm_config_set_out_shift (&c, false, false, 32);  // シフト方向はLeft、AutoPullしない
    pio_sm_init(pio, sm, offset, &c);
    pio_sm_set_enabled(pio, sm, true);
}
%}

これでパソピア700に繋いで試してみたところ、キー入力が安定しない。。
テンキー「1」を入力しても、時々「9」が入力されてしまう。

これはAVRの時にもあった現象で、パソピアからのキースキャン信号に対して、リターンが間に合っていないのが原因。
ロジアナで計測してみると、間に合っているときもあるし、間に合っていない時もある。
下の図は、ぎりぎり間に合っていないケース
B0がDIRで、B1がCLK。
DIRがHighになるとパソピア700から7bitスキャン信号が出力される
DIR=Highになってから500nsほどでCLKが立ち上がるので、そのタイミングで7bitスキャン信号を読み込む。
残り500ns程でスキャン信号に合わせてUSBキーの状態を出力しなければならないが、間に合わない場合がある。

Core1側とPIOの間のデータやりとりにFIFOを使っているが、ここで速度のばらつきが発生しているっぽい。
これでは、ちょっと使いものにならない。。

2021年5月9日日曜日

USB Hostサンプル

前回ビルドしたpico-examplesで、USB Hostを試してみる。

PicoのBOOTSELボタンを押しながら、Windows PCとPicoをUSBケーブルで接続(接続する前にACアダプタは抜いておく)


エクスプローラーに「RPI-RP2」というUSBドライブが表示される

そのUSBドライブのルートフォルダに、ビルドしたUSB Hostのサンプル
...\pico-examples\build\usb\host\host_hid\host_hid.uf2
をコピーする

ファイルコピーが終わるとUSBドライブは自動的にアンマウントされ、書き込んだプログラムが自動で起動する。(LEDがチカチカ点滅している状態になっているはず...)

PCからUSBケーブルを一旦抜いて、USBシリアル変換アダプタUSBとPCを接続し、TeraTermを起動
Pico側のUSBコネクタには、USB変換コネクタ経由でUSBキーボードを接続

基板に5VのACアダプタを接続して、VBUSに5Vを投入するとPicoが起動する。

電源投入直後は、通信が安定しないのかTerminalに文字化けが表示されるが、1~2秒するとPicoのLEDが点滅するようになって、ターミナルに意図した文字が表示されるようになる。
USBキーボードを認識すると「A Keyboard device (address 1) is mounted」と表示される。その後押したキーがTerminalに表示され、AC電源を落とすとunmountedと表示されて終了する。

ひとまずUSBキーボードからの入力を認識したので、何種類かキーボードを試してみた。
  • Buffalo BKBU-J109LG : OK
  • Buffalo YDKBU02BK : OK
  • iBuffalo SAVIOR BSKBC02 : NG
  • Fujitsu USB Hub付キーボード : NG
  • Dell Keyboard KB212 : OK
  • Sanwa Supply SKB-SL065V : OK
  • ユーエーシー KU-8933 : OK
いくつか認識しないキーボードがあったが、Picoのマニュアルとサンプルを参考にしながら、意外と簡単にUSBキーボードの確認ができた。

2021年5月4日火曜日

PicoのWindows開発環境

Raspberry Pi PicoのWindows C++開発環境をセットアップしたので、備忘録として残しておく。

マニュアル「Getting started with Raspberry Pi Pico」の「8.2. Building on MS Windows」とこの動画を参考にしました。

まずは、ARM GCC compilerをダウンロード

インストーラーを起動して、ウィーザードに沿ってインストールしていく。

最後は「Add path to environment variable」にチェックしてから完了ボタンを押す。


次に、Notepad++をダウンロード

インストーラーを起動して、ウィーザードに沿ってインストールしていく。

必要に応じてローカライズ言語を追加
完了ボタンで終了

続いてGitをダウンロード

インストーラーを起動して、ウィーザードに沿ってインストールしていく。

Select Componentsはそのまま。

次のdefault editorでは、Notepad++を選択

以下はデフォルト設定のまま、セットアップを続ける



この画面では「Checkout as-is, commit as-is」を選択

ここは「Use Windows' default console window」を選択




ここは「Enable experimental support for pseudo consoles.」にチェック

この後ファイルコピーが始まって、しばらくするとCompleting the Git SetupWizard画面が表示されたら「Finish」ボタンで終了

今回は使わないけど、Pythonもインストールしておく

「Customize installation」を選択


「Add Python to environment variables」と「Precompile standard library」にチェック

続いてCMakeをインストール
CMakeのインストーラーをダウンロード


「Add CMake to the system PATH for xxx」を選択

インストール先のフォルダを確認


インストールが終わった後、Windowsの環境設定画面で「Path」設定を確認

CMakeのbinフォルダが追加されていることを確認

Visual Studio Codeをインストールする前に、コマンドプロンプトで以下のコマンドを実行
(管理者権限で実行した方がいいかも)
cd "展開先のフォルダ"
git clone -b master https://github.com/raspberrypi/pico-sdk.git
cd pico-sdk
git submodule update --init
cd ..
git clone -b master https://github.com/raspberrypi/pico-examples.git

途中、結構時間がかかります。

例えば「C:\Pico」が展開先のフォルダの場合、以下のように終われば成功です。


続いてVisual Studio 2019をインストール。Community版でOK

インストール途中「C++によるデスクトップ環境」を選択



次にVisual Studio Build Tools 2019をインストール
前のVisual Studio 2019ダウンロードページ下の方に「Visual Studio 2019のツール」があるので、そこからダウンロード

「C++ Build Tools」をチェックしてインストール

インストールが完了すると以下の画面が表示される

続いて、Visual Studio Codeのインストール

前のVisual Studio 2019ダウンロードページ中程に「Visual Studio Code」があるので、そこからダウンロード


インストーラーが起動したら、特に変更するオプションはなし

「PATHへの追加(再起動後に使用可能)」にチェックがあることを確認


スタートメニューから「Visual Studio 2019」→「Developer Command Prompt for VS 2019」を起動

コマンドプロンプトが起動したら、以下コマンドを打ち込みパス設定をする
setx PICO_SDK_PATH "..\..\pico-sdk"
「成功:指定した値は保存されました。」と表示されれば成功

一旦コマンドプロンプトを閉じて、もう一度「Developer Command Prompt for VS 2019」を起動。
code

と打ち込み、Visual Studio Codeを起動する



Ctrl+Shift+XキーでExtensionsバーを起動
"Search Extensions in Marketplace"ボックスで「cmake」を検索
「CMake Tools」を選択して「intall」ボタン

左下の歯車アイコン→Settings→Extenstions→CMake Tools configuration
「CMake Tools configuration」が表示されない場合は、Visual Studio Codeを再起動

Cmake: Configuration Environment→「Add Item」ボタンを押して、以下を入力
Item:「PICO_SDK_PATH」, Value:「..\..\pico-sdk」
Cmake: Generatorの項目にあるテキストボックスに以下を入力
「NMake Makefiles」

左上の「File」メニュー → 「Open Folder...」でOpen Folderダイアログを開く

展開先フォルダにある「\pico-examples」フォルダを選択してOKボタン

PICO-EXAMPLESのフォルダを選択→下に表示されるビルドアイコンを選択
→上に表示されるリストボックスで"GCC for arm-none-eabi"を選択

しばらくするとビルドが完了する

「pico-examples\build」の下にある各サンプルフォルダにuf2ファイルができているか確認


Raspberry Pi PicoのUSBコネクタ近くにあるBOOTSELボタンを押しながら、USBケーブルをWindows PCに接続。
エクスプローラーに「RPI-RP2」というUSBドライブが表示されるので、そのUSBドライブのルートフォルダにビルドした「*.uf2」ファイルをコピーする
ファイル書込みが終わるとUSBドライブは自動的にアンマウントされ、書き込んだプログラムが自動で起動する。はず...