I made a USB HID game controller using a MPU6050 module. It was inspired by Cemu Gyro Joystick project that uses a dongle to supplement motion data for CEMUhook used in emulators.
Except mine is built with a STM8S003 with VUSB library. The STM8S003 is under the programming header. T he module is surface mounted without Castellated Edges.
There were some problems with I2C errata and interference from USB traffics, but that was all resolved by adding a delay.
It is a USB low speed device and as such limited to 7 byte HID reports (1 byte by Report ID). How to send 12 bytes of data? Group the Accelerometers and Gyroscopes under separate report ID and alternating their reports. Let the PC figure them out.
Windows recognizes the new device as a game controller with 6-axis (X/Y + 4).
Let's say I don't have a clue with setting up Node.JS and figure out how to compile stuff. I have to figure out what programs to use as an alternative.
Github: https://github.com/FPGA-Computer/STM8-Gyrostick
My project page: https://hw-by-design.blogspot.com/2021/05/stm8-gyrostock.html
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
This HID project takes up: ram:151 flash:4465 eeprom:0 stack:43 unknown:283
My STM8 HID Dial: ram:122 flash:3196 eeprom:0 stack:41 unknown:283
The unknown is the silly segment for the usb_rx.s is probably for alignment purposes as Cosmic C doesn't honor that at all. (bug?) STM8 messes up pipeline cycles if it fetch code off alignment. The USB code actually uses a couple of bytes in EE to store the internal 16MHz clock trim value.
Aside from the timing sensitive assembly language, the rest was pretty much C code. Do watch out for the STM8 register header file. They use struct and actual binary values for bits. My code is full metal, so expect to see that a lot. I have a copy of the stm8 header in the source tree to make life easier to everyone.
e.g. TIM4->CR1 = TIM4_CR1_CEN; not (1<<TIM4_CR1_CEN)
As for SDCC, I haven't tried it since my 8051 days. My impression is that the code was not efficient as I had to tweak the peehole rules and do silly things to function calls.
I did however wrote a USB stack for TUSB part on SDCC. The only reason why I did that was that the TI source code targeted for IAR compiled to about 2X of available memory. So USB stack is doable in SDCC, but I wouldn't do it myself again. I am spoiled by hardware debugger with source code trace and peeking at call stack and internal registers.
The original Russian source code is under STM8-LCDUSB or something like that. I did what I can to trim it and still feels it is more complex than needed (vs VUSB). It is pretty solid.
Are you sure? yes | no
Thanks a lot! The STM8 32bit instruction fetch for feeding the pipeline makes low level coding a bit more demanding. The stable and versatile vUSB makes it easy to forget that simulating USB on a slowish µC is demanding.
Are you sure? yes | no
I had to add a small time delay from where I check for ready to send to reading from the IRQ based I2C driver. There were tons of errata there and one of them got stuck after a while with heavy USB traffics. With the small time delay, both the USB driver and the I2C gets their time slows and each happily work as they should be. AVR VUSB was known for not working well with IRQ.
Are you sure? yes | no
BTW there are still some work I'll need to do on the USB stack. There is a currently hard coded limit to only 2 end points that I hop to remove further down the road. I have a working USB composite device (descriptor so far) that could use at least one extra EP.
These USB projects - each of them a bit different help to refine the library.
Are you sure? yes | no
Nice! I noticed your project on GitHub yesterday (no, I'm not stalking you ;-) ).
What is the footprint of a plain HID implementation? Do you think that it might be possible to port that to SDCC?
Are you sure? yes | no