This is the driver for the ControlBlock re.v 2.X, a power switch and input/output/gameapd gadget for the Raspberry Pi
Clone or download

README.md

ControlBlockService2

Build Status

This is the driver for the petrockblock.com ControlBlock, which is an extension board for the Raspberry Pi (TM). The driver itself is denoted as controlblock in the following. The driver provides a service for interacting with the power button signals as well as for mapping attached game controllers to corresponding game pad devices on the Raspberry Pi.

Please note that this is the driver for revision 2.X of the ControlBlock. If you have a revision 1.X board, you need to use the driver for that revision series.

Contents

Prerequisites

To be able to successfully build ControlBlockService you need to have certain APT packages installed. You can make sure that you have the latest version of those packages with these commands:

sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install -y git cmake g++-4.9 doxygen

Downloading

If you would like to download the latest version of controlblock from its Github repository, you can use this command:

git clone --recursive https://github.com/petrockblog/ControlBlockService2.git

Note that the above command also takes care for downloading the included Git submodules.

Quick Installation

There comes an installation script with this reposity that does all the steps described below: install.sh This script compiles the driver, installs the binary and configuration files, and installs the ControlBlock service.

To run the quick installation, you just need to call this one line from the Raspbian console

wget -O - https://raw.githubusercontent.com/petrockblog/ControlBlockService2/master/install.sh | sudo bash

Here is a video of a typical quick installation procedure:

asciicast

Building and Installation

To build controlblock follow these commands:

cd ControlBlockService2
mkdir build
cd build
cmake ..
make

If everything went fine you can install the driver from within the folder build with the command

sudo make install

Installation as Service

You can install controlblock as daemon from within the folder build with this command:

sudo make installservice

It might be that you need to restart your Raspberry afterwards to have all needed services running.

Uninstalling the service and/or the binary

You can uninstall the daemon from within the folder build with this command:

sudo make uninstallservice

You can uninstall the binary from within the folder build with this command:

sudo make uninstall

Configuration

The configuration file of controlblock is located at /etc/controlblockconfig.cfg. It uses JSON syntax for setting the the values of its configuration parameters.

The default configuration file looks like this:

{
    "controlblocks" : [
        {
            "enabled" : true,          // Enables (=true) or disables (=false) the ControlBlock 
            "address" : {              // The address information of the first ControlBlock
                "SJ1" : 0,             // The hardware address solder-jumper SJ1. Options: 0, 1 
                "SJ2" : 0              // The hardware address solder-jumper SJ2, Options: 0, 1
            },
            "gamepadtype" : "arcade",  // Sets the gamepad type. Options: "arcade", "mame", "snes", "genesis", "none"
            "onlyOneGamepad" : false,  // If true, registers only one gamepad instead of two
            "powerswitchOn" : true     // Enables (=true) the power switch functionality. Options: true, false
        },
        {
            "enabled" : false,          // Enables (=true) or disables (=false) the second ControlBlock 
            "address" : {               // The address information of the second ControlBlock
                "SJ1" : 1,              // The hardware address solder-jumper SJ1. Options: 0, 1 
                "SJ2" : 0               // The hardware address solder-jumper SJ2, Options: 0, 1
            },
            "gamepadtype" : "arcade",   // Sets the gamepad type. Options: "arcade", "mame", "snes", "none"
            "onlyOneGamepad" : false    // If true, registers only one gamepad instead of two
        }
    ]
}

Setting the Type of Gamepad

To set the type of the gamepad you need to set the value of the element gamepadtype. You can choose between these values:

  • arcade: Enables two game pads in the system and maps the GPIOs of the ControlBlock to these game pads.
    ArcadeMapping

  • mame: Enables a virtual keyboard and maps the GPIOs of the ControlBlock to this keyboard with a MAME layout.
    MAMEMapping

  • snes: Enables two game pads in the system and maps the attached SNES/NES controllers accordingly.
    SNESMapping You can also connect a non-latching reset button to Player-1, Input B. If the button is pressed a virtual ESC-key press will be triggered as well as a simultaneous press of the start and select buttons for player 1.

  • genesis: Enables two game pads in the system and maps the attached Genesis/Megadrive/Atari controllers accordingly.
    GenesisMapping You can switch to six-button controller by pressing the button combination START, A, B, C, UP at the same time.

Using Only one Gamepad

If you want to connect only one gamepad to the ControlBlock you can set the element onlyOneGamepad to true: It enables only one gamepad in the system (e.g., if only Player-1 buttons are wired to the ControlBlock in your setup, this prevents a ghost gamepad from being selected as default player 2 in retroarch)

Enabling or Disabling the Power Switch Functionality

To enable or disable the power switch functionality you can set the element powerswitchOn to true or false:

  • true: Activates the handling of the power switch signals of the ControlBlock.
  • false: Deactivates the handling of the power switch signals of the ControlBlock.

Custom Actions at Shutdown

When the driver observes a shutdown signal from the ControlBlock, a shutdown Bash script is called. You can find and edit it at /etc/controlblockswitchoff.sh.

4-Player Extension with two ControlBlocks

The driver can handle up to two ControlBlocks. This means that you can stack two ControlBlock on top of each other to have inputs for four players.

Setting Base Address with the Solder Jumpers

In order to use two ControlBlocks on top of each other, you need to change the base address of one of the ControlBlocks to a different value than the default one. The base address is used by the ControlBlock driver to identify and distinguish the two ControlBlocks from each other. The base address can be set with the solder jumpers SJ1 and SJ2. To change the base address, you need to use a solder iron and set, e.g., SJ1 to "1". Make sure that only two of the three solder pads are connected with each other! The following image shows the solder jumpers:

Solder jumpers SJ1 and SJ2 for setting the base address

Interrupting the Signal Lines for the Power Switch on the Second ControlBlock

It is important that you interrupt the signal lines for the power switch to the second ControlBlock. If you do not interrupt the signals to the top ControlBlock, the system will shutdown immediately after the system start. To interrupt the signal lines you can snap off or bend the pins 11 and 12 on the bottom ControlBlock. The power switch functionality and all game pad functionalities are still given! Here are two images that show how the pins could be bent:

Bending pins for 4-player functionality, view 1

Bending pins for 4-player functionality, view 2

Adapting the Configuration File for Four Players

The values of the solder jumpers have to be set in the configuration file with the elements SJ1 and SJ2. Also, you have to enable the second ControlBlock by setting the element enabled for the second ControlBlock to true.

If you have set the solder jumper SJ1 to 1, a usual 4-player configuration that enables two ControlBlocks with arcade mode would look like this:

{
    "controlblocks" : [
        {
            "enabled" : true,          // Enables (=true) or disables (=false) the ControlBlock 
            "address" : {              // The address information of the first ControlBlock
                "SJ1" : 0,             // The hardware address solder-jumper SJ1. Options: 0, 1 
                "SJ2" : 0              // The hardware address solder-jumper SJ2, Options: 0, 1
            },
            "gamepadtype" : "arcade",  // Sets the gamepad type. Options: "arcade", "mame", "snes", "genesis", "none"
            "onlyOneGamepad" : false,  // If true, registers only one gamepad instead of two
            "powerswitchOn" : true     // Enables (=true) the power switch functionality. Options: true, false
        },
        {
            "enabled" : true,          // Enables (=true) or disables (=false) the second ControlBlock 
            "address" : {               // The address information of the second ControlBlock
                "SJ1" : 1,              // The hardware address solder-jumper SJ1. Options: 0, 1 
                "SJ2" : 0               // The hardware address solder-jumper SJ2, Options: 0, 1
            },
            "gamepadtype" : "arcade",   // Sets the gamepad type. Options: "arcade", "mame", "snes", "none"
            "onlyOneGamepad" : false    // If true, registers only one gamepad instead of two
        }
    ]
}

Four Player Hardware Setup Example

Here is an image that shows an exemplary 4-player hardware setup:

Four Player Hardware Setup Example

Things to note:

  1. The ControlBlock with the interrupted signal lines for the power switch is directly attached to the Raspberry Pi. The other ControlBlock is on top of that.
  2. If you want to use a power switch, you need to attach the switch and the optional LED to the "lower" ControlBlock, which is directly attached to the Raspberry Pi.
  3. The micro USB connector for the supply power is attached to the lower ControlBlock, which is directly attached to the Raspberry Pi.

Troubleshooting

It is important to start with a well defined and working installation. Therefore, I suggest to start with a fresh Raspbian, RetroPie or whatever image and install the ControlBlock driver with only the power switch connected. Follow the steps [as described above for that.

If that works, you can test the functionality of the arcade button input pins by using a jumper wire that is connected to GND and contacting the various button pins. jstest /dev/input/js0 gives you the so simulated button presses for player one and jstest /dev/input/js1 gives you the simulated button presses for player two (You can exit jstest with Ctrl-C.

If you find that every input pin is working as expected start with connecting the controls in small steps. For example, first the joysticks, then the buttons for one player, then the ones for the other player. Use jstest after every smaller step to verify that things still work as expected.

Checking the Raw GPIO of the Raspberry

To check that the GPIOs of the Raspberry Pi itself are working correctly, you can use the bash script scripts/testRPiGPIO.sh). You can start it with ./scripts/testRPiGPIO.sh. Please follow the instructions that are printed to the shell.



Have fun!

-Florian petrockblock.com