OpenGround – Part 8 – Buttons, Lazyness, GPIOS, and memory locations on STM32F0

By | September 23, 2016

This is the eighth post of my series documenting the development of a custom firmware for the FS-i6s transmitter. In my previous post we used the I2C peripheral to talk to the touch controller chip. This time we will hack a small piece of code to find out the pin mapping for the buttons.

Buttons! Where?

There are a total of 4 buttons on the Flysky FS-i6s transmitter. In reality this is not fully correct, both power buttons have to be pressed together and single presses can neither be detected nor be differentiated. As it gets boring to manually trace the pinout we will do something differently this time. As we have a working screen and the debug routines that allow us to print values, we will write a small code snippet that will show the status of all GPIO pins (see io.c).

In order to do this the function io_test_prepare() configures all i/os to input and activates the internal pull-up resistorbefore other  peripheral init code remaps pin directions to output or special functions. These subsequent initialization routines e.g. for the screen will properly re-configure some pins to outputs and those pins will no longer report proper input values. This is no big deal for this application as we are interested in new, unused pins where our buttons are potentially connected.

Once everything is prepared, the function io_test() will print out the values of all 6 GPIO banks in a loop. An inner loop uses a nice trick to access all six GPIOS by an index: As all STM32 peripherals map to special memory locations with a known offset between two GPIO adresses (0x0400) we can access all I/Os by reading from the location GPIOA_BASE + p*0x0400:

GPIO_ReadInputDataBit(((GPIO_TypeDef *) (GPIOA_BASE + p*0x00000400)), (1<<i))

Try it out

You can compile an test the code on your own, check out the tag part8_buttons and build the code (this requires the arm gcc toolchain to be installed):

git clone
git checkout part8_buttons

After the code was compiled we can now flash the code to our transmitter. We will use the ST-Link interface to flash the chip. The makefile has a nice macro for that, you can flash the target by executing:

make flash

The screen should now be initialized and you should see a screen similar to this:


GPIOA 1111111111111111
GPIOB 1111111111111111
GPIOC 1111111111111111
GPIOD 1111111111111111
GPIOE 1111111111111111
GPIOF 1111111111111111

There will be some ‘0’ and some ‘1’ entries in that view. Now press both powerbuttons, you should notice an activity on PORTB.14. Pressing the buttons on the back will toggle PORTA.9 and PORTB.10.

Leave a Reply

Your email address will not be published. Required fields are marked *