2013年4月12日金曜日

CMSIS-DAP用のUSBHIDの作り方

pyOCDはmbedのVID、PIDをみてHIDからCMSIS-DAPを探しているようだが、Keil uvison4はどうしているのだろうと調べていた時の副産物です。

Keil uvison4 が認識するように mbed の USBDeviceライブラリの USBHID を改造してみました。

/USBDevice/USBHID/USBHID.cpp の stringIproductDescriptor[] を CMSIS-DAP を含む文字列に書き換える。
例:

uint8_t * USBHID::stringIproductDesc() {
    static uint8_t stringIproductDescriptor[] = {
        32,                                                       //bLength
        STRING_DESCRIPTOR,                                        //bDescriptorType 0x03
        'K',0,'L',0,'2',0,'5',0,'Z',0,' ',0,'C',0,'M',0,'S',0,'I',0,'S',0,'-',0,'D',0,'A',0,'P',0 // KL25Z CMSIS-DAP
    };
    return stringIproductDescriptor;
}


/USBDevice/USBHID/USBHID.cpp の reportDescriptor[] の HIDリポートディスクリプタを書き換える。
例:(KL25Zのインターフェース3のHIDリポートディスクリプタです)

uint8_t * USBHID::reportDesc() {
    static uint8_t reportDescriptor[] = {
        0x06, 0x00, 0xff,
        0x09, 0x01,         // usage
        0xA1, 0x01,         // Collection 0x01
        0x15, 0x00,         // logical minimum = 0
        0x26, 0xFF, 0x00,   // logical maximum = 255
        0x75, 0x08,         // report size = 8 bits
        0x95, 0x40,         // report count
        0x09, 0x01,         // usage
        0x81, 0x02,         // Input (array)
        0x95, 0x40,         // report count
        0x09, 0x01,         // usage
        0x91, 0x02,         // Output (array)
        0x95, 0x01,         // report count
        0x09, 0x01,         // usage
        0xb1, 0x02,
        0xC0                // end collection
    };
    reportLength = sizeof(reportDescriptor);
    return reportDescriptor;
}

(2013/4/12)

usbd_user_hid.c を見てみるとusbd_hid_set_report()が非同期でパケットを受信しているようなので、
コネクト・ディスコネクトくらいのパケット数が少ないのは取りこぼすことは無かったが、
Flash書き込みで非同期で大量のパケットが送られてくると取りこぼすのかもしれません。
USBSerialのように割込みからパケットを受信するようにしないといけないのかもしれません。

(2013/4/15追加)

Flash書き込みでVerifyOKと表示されるから問題なく受信出来ているのであろう。
DAP.c を見ていたら、Infoコマンド(0x00) の DAP_ID_PACKET_COUNT(0xfe) で、
送受信可能のパケット数 DAP_PACKET_COUNT をホストに知らせている。
実際にはホスト側の実装に依存すると思うが、USBHIDのように1つのパケットをポーリングで送受信している場合は
DAP_PACKET_COUNT を 1 にしておけばより安全かもしれません。。

(2013/4/16追加)

USBDeviceライブラリを修正しなくても、USBHIDから継承すればいいかと考えたが、
stringIproductDesc()は仮想関数なので、実装するだけで文字列を変更できる。
しかし、reportDesc()は実装しても反映されないのでUSBHIDクラスをそのままコピーして
新しいクラスUSBDAPを作るようにしました。

(2013/4/17追加)
---

0 件のコメント: