Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

PluggableUSB and PluggableHID howto

Allen Wild edited this pageMar 11, 2019 ·12 revisions

An example is worth a thousand words

MIDIUSB orHID libraries are based on PluggableUSB.

Keyboard andMouse libraries are based on PluggableHID and are bundled with the IDE

Writing a library as a PluggableUSB Module

If you wish to write a library that exposes low-level USB functionality likeMIDI orMass Storage you can take advantage of the newPluggableUSB core.

Attaching to this framework is very simple. First of all your library needs to include PluggableUSB header:

#include"PluggableUSB.h"

Then, you need to implement a PluggableUSBModule, so the constructor will look like:

/* we need 2 endpoints and 2 interfaces */MIDI_::MIDI_(void) :PluggableUSBModule(2,2,epType){epType[0]=EP_TYPE_BULK_OUT_MIDI;// MIDI_ENDPOINT_OUTepType[1]=EP_TYPE_BULK_IN_MIDI;// MIDI_ENDPOINT_INPluggableUSB().plug(this);}

ThePluggableUSBModule must implementsetup,getInterface andgetDescriptor functions and declare how many endpoints and interfaces it needs to allocate

setup function signature isbool setup(USBSetup& usb_setup);it is expected to returntrue if the request was directed to the module and executed correctly,false otherwise.

If no setup phase is required, simply returnfalse

< examples from HID.cpp - simplified >

boolHID_::setup(USBSetup& setup){if (pluggedInterface != setup.wIndex) {returnfalse;}uint8_t request = setup.bRequest;uint8_t requestType = setup.bmRequestType;        etc etc...

getDescriptor function signature isint getDescriptor(USBSetup& setup);it is expected to return the number of bytes sent if the request was directed to the module, 0 if the request has not been served or -1 if errors has been encountered.

If no device descriptor is required, simply return 0

< examples from HID.cpp - simplified >

intHID_::getDescriptor(USBSetup& setup){// Check if this is a HID Class Descriptor requestif (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) {return0; }if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) {return0; }// In a HID Class Descriptor wIndex cointains the interface numberif (setup.wIndex != pluggedInterface) {return0; }int total =0;HIDSubDescriptor* node;for (node = rootNode; node; node = node->next) {int res =USB_SendControl(TRANSFER_PGM, node->data, node->length);if (res == -1)return -1;total += res;}return total;}

getInterface function signature isint getInterface(uint8_t* interfaceCount);it is expected to return the number of bytes sent and increment theinterfaceNum variable with the number of interfaces used.

< examples from HID.cpp - simplified >

intHID_::getInterface(uint8_t* interfaceCount){*interfaceCount +=1;// uses 1HIDDescriptor hidInterface = {D_INTERFACE(pluggedInterface,1, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_NONE, HID_PROTOCOL_NONE),D_HIDREPORT(descriptorSize),D_ENDPOINT(USB_ENDPOINT_IN(pluggedEndpoint), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE,0x01)};returnUSB_SendControl(0, &hidInterface,sizeof(hidInterface));}

Everything is configured, so callingPluggableUSB().plug(this) will do all the magic.

Your library will be plugged when the constructor is called, so you need to pre-instantiate a singleton for your class to make sure to be already plugged whenmain() is executed.

Then you can perform USB writes calling, for example:

USB_Send(pluggedEndpoint, data, len);

Writing a library as a PluggableHID Module

If you are interested in writing a library for a specific HID peripheral (Mouse, Keyboard, Touchscreen, Gamepad etc) you can take advantage of the PluggableHID core. No need to explore the darkest corners of USB specifications!

In your library

#include"HID.h"

in your header file.

If the core you are targeting is pluggable-ready,_USING_HID will be defined.

#ifndef MOUSE_h#defineMOUSE_h#include"HID.h"#if !defined(_USING_HID)#warning "Using legacy HID core (non pluggable)"#elseetc etc .....

In the cpp file, add a const report descriptor of your choice

staticconst u8 _hidReportDescriptor[] PROGMEM = {//  Mouse0x05,0x01,// USAGE_PAGE (Generic Desktop)  // 540x09,0x02,// USAGE (Mouse)  .  . etc etc  .  }

In the constructor call add the following snippet

Mouse_::Mouse_(void) : _buttons(0){static HIDSubDescriptornode(_hidReportDescriptor,sizeof(_hidReportDescriptor));HID().AppendDescriptor(&node);}

And you are done 😄

Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp