Close

First steps with STM32 USB firmware

A project log for Wii Nunchuk as a USB HID controller

Project in which Wii Nunchuk controller is used as a USB HID controller for computer graphics apps.

michalMichal 02/10/2019 at 15:590 Comments

I started by setting up the project structure in a similar way satoshinm did. As I've mentioned before, this article by him - making a Rubber Ducky with Blue Pill - helped me a bit.

The project references the libopencm3 repository and provides 2 Makefiles. Top level Makefile fetches the libopencm3, builds it and builds the firmware. Makefile in the src directory only builds the firmware binary.

Before I could actually flash the boards I decided to check the resistors on the USB lines. The Blue Pill boards suffer from a wrong resistor values. The boards I received used 4.7k resistors, while they should be 1.5k. I desoldered them and soldered in ones with the proper values (1.5k).

I started by copying the code from this example. I stripped it from the DFU functionality.

I also changed the clock source to external 8MHz. In libopencm3 that meant going from:

rcc_clock_setup_in_hsi_out_48mhz()

to

rcc_clock_setup_in_hse_8mhz_out_72mhz()

What puzzled me a bit in libopencm3 is that you can stumble on functions that seem to do the same yet are named differently. An example of that would be:

gpio_mode_setup()

and

gpio_set_mode()

If you look into this file though you can find the answer:

/*
 * Note: The F2 and F4 series have a completely new GPIO peripheral with
 * different configuration options. Here we implement a different API partly to
 * more closely match the peripheral capabilities and also to deliberately
 * break compatibility with old F1 code so there is no confusion with similar
 * sounding functions that have very different functionality.
 */ 

 ...oh, ok then. That meant that for a STM32F1 the gpio_set_mode() was the way to go.

After that I worked on setting SysTick in such a way that it fired 100 times per second.

  systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8);
  // SysTick interrupt every N clock pulses: set reload to N-1
  // 72MHz / 8 = 9MHz
  // 9000000Hz / 90000 = 100Hz
  systick_set_reload(89999);
  systick_interrupt_enable();

 After plugging the board to the PC it did get recognised. I didn't went too deep into what happens when I plug the board in. I went on to add the I2C functionality so I could poll the Wii Nunchuk controller. Little did I know...

But that's a story for the next episode! Stay tuned!

Discussions