USB HID support on Core?

Continuing the discussion from Using the Spark Core as a HID:

Is there anybody already in the middle of porting USB-HID-Mouse and/or USB-HID-Keyboard support for the core?
I'm still waiting for my Cores - got the shipping date as 24.12.2013 (whoopeeeeee!).
As soon as I'll get them, I'd try my luck with porting the Teensyduino HID libraries, but if there is already someone at work with the Arduino ones or any other libs, I'd be happy to use them just as much.

I havenā€™t had much time to try but I have spent several hours to get an overview what USB related files exist in the Core FW repository and what they do, and how the Virtual_Com_Port was built by @satishgn.
I also built the USB descriptors (device, interface, report, endpoint, ā€¦) for HID Keyboard/Mouse/Joystick and the high level functions, but now Iā€™m stuck, since I canā€™t hook these up with the Cores USB ā€œframeworkā€ (descriptor negotiation, low level communication, ā€¦).
I got the impression - or could just not see it - that there is no clear separation of USB ā€œframeworkā€ and the implementation of VCP.
I hoped to be able to just ā€œunhookā€ the default VCP and replace it with my implementation of the HID composite or an HID extended version of the VCP, without having to fiddle in a lot of FW files.
My naive idea was to find a precomp variable like VIRTUAL_COM_PORT_ENABLED to be #undefed and then to provide my own implementation - preferably as one file as long Online IDE (aka Sparkulator) does not support multiple files and user libs - , call some hook-up-routines and have my own WiFi USB Mouse/Keyboard which I can control from anywhere in the world.
But ā€¦ :cry:

Maybe someone (e.g. @satishgn, @zachary, @mohit, @Dave ) could give me some pointers :blush: PLEASE!!!

Hi @ScruffR,

This is a cool idea! Lemme do some research and see if I can help provide some pointers ā€“ although I think @satishgn would be our best bet here. Iā€™ll be back with details soon :slight_smile:

Thanks,
David

Hmm, so, I think the easiest way to get started on this might be to compile locally, since you probably want to be modifying files outside the normal user ā€œapplication.cppā€. Having support for this through the ā€œSparkulatorā€ :wink: , would be cool, but first weā€™d need to know which hooks would need to be exposed to make this convenient.

Apologies if my responses arenā€™t super on-point, Iā€™m not personally familiar with writing client-side USB devices in C, so Iā€™m guessing a bit:

I can tell you the STM32 USB driver is in core-common-lib here:

I wonder if the most interesting code with regards to what hooks we should expose would be something like the USB serial interface. Since that is an example of user-code that can modify the usb device state.

Something around here: https://github.com/spark/core-firmware/blob/master/src/main.cpp#L334

Of course if you wanted to build locally instructions are here; https://github.com/spark/core-firmware

I hope you keep updating this thread, Iā€™m really curious to see how this progresses, and Iā€™m happy to help if I can!

Thanks,
David

1 Like

Thanks @Dave,

since this topic was sitting around a while already with no attention of the community, I thought Iā€™ll be left on my own. But your replies keep hopes alive :wink:

I feared that local compile might be the only way to this, at least for now.
I have to admit that I havenā€™t looked into STM32_USB_FS_Device_Driver/src yet, since the core-firmware usb_.* files have been quite overwhelming for me already.
(Edit: Actually I had already looked at STM32_USB_FS_Device_Driver/src - I just didnā€™t realize that the usb_
.* files I searched for, were stored in that folder ;- )

To reduce the feeling ā€œGosh, where do I look first, and where do I go from there?!?!? :blush:ā€, and since Iā€™m a somewhat visual learner, Iā€™d love to have some kind of hirachy diagram what .c/.cpp builds up on which other and what action takes place before which other during bootup and USB setup.
This way my feeling that there is no clean cut separation between USB ā€œBIOSā€ implementation and user device implementation might go away.
But Iā€™m obviously not up to putting this together on my own.

1 Like

Thanks @Dave, @ScruffR for pointing out the HID stuff.
I had in the past worked on HID implementation for some ECG devices.
So extending that to Mouse and Keyboard should get easy using the ST framework.
Hopefully weā€™ll be able to deliver these new features before end of Feb.

2 Likes

Thanks @satishgn,

this is great news for me :smiley:
I feel a bit lost with my attempt to do it myself.

One essential option Iā€™d like to request in this connection would be a way to deactivate the USB_VIRTUAL_COM_PORT at compile time, since the Sun/Solaris machines Iā€™d be using the Core HID with, do not accept that combination.
As for now Iā€™m using a Teensy 2.0 as Teensyduino-HID, which workes fine as Keyboard/Mouse/Joystick device, but fails to work as Keyboard/Mouse/Joystick + Serial on the Sun/Solaris, where Windows has no trouble accepting it.

So Iā€™ll be eagerly looking forward to your throw at this
:smiley: :smiley: :smiley: :smiley: :smiley:

(While still trying to get my own head round it, too - promise :blush: )

Hi @satishgn,
Iā€™m trying to local build the core-firmware feature/usb_hid_support branch, but seem to have some problems with missing headers (e.g. #include ā€œconfig.hā€, #include ā€œspark_macros.hā€, #include ā€œdebug.hā€).
When I search my local copy of the other repositories I canā€™t find any of them.
What branch of core-common-lib and core-communication-lib have you based your core-firmware on, so that I can rebase my local repo?

Thanks

Can you try:
git pull origin feature/usb-hid-support
and then
git checkout feature/usb-hid-support

I just merged the latest master into feature/usb-hid-support so that should help resolve the compilation issues. Please pull latest core-firmware and supporting libs and checkout to the feature/usb-hid-support branch before running the make command.

Thanks, Iā€™ll try that.

I think I did what you suggested, but it didnā€™t really change anything.
So I downloaded the latest gcc, done a pull/checkout on master branch for core-common-lib and core-communication-lib and another pull/checkout on feature/usb-hid-support for core-firmware - which all reported up to date and I still get this

Building file: ../src/application.cpp
Invoking: ARM GCC CPP Compiler
mkdir -p obj/src/
arm-none-eabi-gcc -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb  -I../inc -I../../core-common-lib/CMSIS/Include -I../../core-common-lib/CMSIS/Device/ST/STM32F10x/In
clude -I../../core-common-lib/STM32F10x_StdPeriph_Driver/inc -I../../core-common-lib/STM32_USB-FS-Device_Driver/inc -I../../core-common-lib/CC3000_Host_Driver -
I../../core-common-lib/SPARK_Firmware_Driver/inc -I../../core-communication-lib/lib/tropicssl/include -I../../core-communication-lib/src -I. -ffunction-sections
 -Wall -fmessage-length=0 -MD -MP -MF obj/src/application.o.d -DUSE_STDPERIPH_DRIVER -DSTM32F10X_MD -DDFU_BUILD_ENABLE -DRELEASE_BUILD -fno-exceptions -fno-rtti
  -c -o obj/src/application.o ../src/application.cpp
In file included from ../inc/application.h:31:0,
                 from ../src/application.cpp:27:
../inc/spark_wiring.h:31:20: fatal error: config.h: No such file or directory
 #include "config.h"

I can find two config.h files, but both donā€™t seem to fit the bill for spark_wiring.h

 .\GitHub\core-communication-lib\lib\tropicssl\include\tropicssl\config.h
 .\GitHub\core-communication-lib\tests\UnitTest++\src\Config.h

Since the make file is not looking there, so I copyed the *.h files from .\include\tropicssl out into .\include, but then I get

Building file: ../src/application.cpp
Invoking: ARM GCC CPP Compiler
mkdir -p obj/src/
arm-none-eabi-gcc -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb  -I../inc -I../../core-common-lib/CMSIS/Include -I../../core-common-lib/CMSIS/Device/ST/STM32F10x/In
clude -I../../core-common-lib/STM32F10x_StdPeriph_Driver/inc -I../../core-common-lib/STM32_USB-FS-Device_Driver/inc -I../../core-common-lib/CC3000_Host_Driver -
I../../core-common-lib/SPARK_Firmware_Driver/inc -I../../core-communication-lib/lib/tropicssl/include -I../../core-communication-lib/src -I. -ffunction-sections
 -Wall -fmessage-length=0 -MD -MP -MF obj/src/application.o.d -DUSE_STDPERIPH_DRIVER -DSTM32F10X_MD -DDFU_BUILD_ENABLE -DRELEASE_BUILD -fno-exceptions -fno-rtti
  -c -o obj/src/application.o ../src/application.cpp
In file included from ../inc/application.h:31:0,
                 from ../src/application.cpp:27:
../inc/spark_wiring.h:32:26: fatal error: spark_macros.h: No such file or directory
 #include "spark_macros.h"
                          ^
compilation terminated.

But this spark_macros.h is nowhere to find - and even if this was there the next include (debug.h) would trip the compiler again.

Iā€™ve no idea what Iā€™m doing wrong here :disappointed:

@ScruffR, the config.h and spark_macros.h are there in ā€œcore-common-lib\SPARK_Firmware_Driver\incā€. It seems like you donā€™t have the latest master of core-common-lib.
Please try doing a git pull and let us know how it goes.

Thanks @satishgn for your patience!

Since I couldnā€™t get GitHub to pull the latest masters - whatever I tried, I obviously didnā€™t try the right thing :blush: - I ended up downloading all three ZIP files and shoehorned them into my local repo and now I can compile.

But now I fear Iā€™ve broken the GitHub history :disappointed:

@satishgn, as Iā€™m attempting my first stabs at the USB HID Mouse feature I just came across a minor point.
In your declaration of MouseReport and therefore in the related methods you declared x, y and wheel as uint8_t but should they not be int8_t since they can be positive or negative?

typedef struct
{
	uint8_t buttons;
	uint8_t x;
	uint8_t y;
	uint8_t wheel;
} MouseReport;

I know it doesnā€™t make any difference in functionalty, but just to avoid confusion, why the mouse moves in the wrong direction, when you pass a value greater than 127.

An even more puzzling behaviour I got, when I tried to go ahead with my cloud connected mouse project.
Since it didnā€™t behave as I expected, I whipped up this little test function and called it via Spark API Helper

int mouseTest(String command)
{
	// move to 0/0
	Mouse.move(-127,-127,0);
	delay(REPEAT_DELAY);
	Mouse.move(-127,-127,0);
	delay(REPEAT_DELAY);
	Mouse.move(-127,-127,0);
	delay(REPEAT_DELAY);
	Mouse.move(-127,-127,0);
	delay(REPEAT_DELAY);
	Mouse.move(-127,-127,0);
	delay(REPEAT_DELAY);

	// move to 545/305
	Mouse.move(127,127,0);
	delay(REPEAT_DELAY);
	Mouse.move(127,127,0);
	delay(REPEAT_DELAY);
	Mouse.move(127,51,0);
	delay(REPEAT_DELAY);
	Mouse.move(127,0,0);
	delay(REPEAT_DELAY);
	Mouse.move(37,0,0);
	delay(REPEAT_DELAY);

	return 1;
} 

For testing I set REPEAT_DELAY to 500ms, where I would normally have no more than 50ms. But when I watch the mouse movement I see that the Mouse.move(-127,-127,0) calls do move the mouse diagonally, but the calls with positive coordinates do not. I get the downward movement first and then the horizontal, but only the ones zero Y coordinates.

I got the problem on a Win 8.1 tablet - Iā€™ve not yet been able to test in on my Win 8.x PCs (could have to do with the left edge system gesture or the Win 8.x HID drivers)
Under Win XP, Win 7 and Linux it works as expected.

@ScruffR, I think you are right about the type. I will update the structure and the associated arduino function prototype. Thanks for testing this. I am just testing this on my Windows Vista system.

@satishgn, you are welcome.
I will carry on testing and Iā€™ll also try to figure out how you do your magic there (and maybe contribute :wink: )
One feature Iā€™d also like to see on the USB HID mouse would be an ā€œabsolute modeā€ (like on digitizer tablets). As I have been using Teensy boards before and the Teensy 3.x does sport a Mouse.moveTo(x,y) function that would be a cool feature for the Core, too.
For the time being Iā€™ve equiped my application.cpp with rudimentary logical/physical coordinate mapping and send the mouse to 0/0 (with some overshoot obviously) and then move from there relative in chunks of max. 127 mouse steps.

1 Like

@ScruffR, thanks for your support :smile:
I just pushed some changes in the HID branch. Just try a pull and see if that helps.

2 Likes

Hi,

any news on this? I see the branch in the core-firmware, but it hasnā€™t been merged into main yet, correct?

Robert