以前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 multithreadstdio_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_targetwait 0 gpio 18 [7] ; GP18(=DIN11pin=CLK)が0になるまで待つwait 1 gpio 18 ; GP18(=DIN11pin=CLK)が1になるまで待つnop [1] ; Pinデータを読み込む前にWaitin 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入力したらAutoPushpio_sm_init(pio, sm, offset, &c);pio_sm_set_enabled(pio, sm, true);}%}
PIO(SM1)で、FIFOバッファに書き込まれた8bitデータをGPIO2-9に出力
.program usbkey_keyreturn.wrap_targetpull 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を使っているが、ここで速度のばらつきが発生しているっぽい。
これでは、ちょっと使いものにならない。。
0 件のコメント:
コメントを投稿