Skip to content

Instantly share code, notes, and snippets.

@luckydonald
Last active April 12, 2023 03:24
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save luckydonald/f3ebfab4a63322884cf1 to your computer and use it in GitHub Desktop.
Save luckydonald/f3ebfab4a63322884cf1 to your computer and use it in GitHub Desktop.
How to setup and use GPIO ports/pins on a Cubietruck

Setup and use GPIOs on a Cubietruck

Cubietruck is also known as Cubieboard 3

Note: This file documents just what I did, first of all as a note for myself. So this is not primarily intended as a tutorial. Because it still might be helpfull, I uploaded it. The GPIO function is now confirmed to work, tested with my multimeter, but I am still waiting for my jumper cables to arrive, so I can use them securely.

Licensed under a Luna-Will-Cry-If-You-Modify-Or-Redistribute-This 1.0 licence.

Also notable, the Cubietruck has 2.0mm GPIO pins instead of 2.54mm (like the Raspberry Pi or Arduino boards have), so you might need a 2.54 to 2.0mm adapter, e.g. from adafruit. (But I ordered mine on ebay.de.)

Content

Starting point

I started with Stefanius Cubietruck HomeNAS image v3.1 (german hompage).

direct download link to the version I used. You should use the newest version instead if available! (Also, the link might break if a new version is released.)

Preperation part 1: Update everything

To allow an upgrade of all packages I needed to resize the boot partition to use the whole empty space on the SD card. reference (DE)

fdisk /dev/mmcblk0

This will start a dialogue.

p  # List all partions.
   # => Take notice what partition ```mmcblk0p2``` is. (Manually counting, starting with 1).    
   # In my case that's the 2nd partition    

Now we remove the partition first, to add it back later with all the available storage capacity

d  # to delete a partition    
2  # The number you found out above for mmcblk0p2    

Nest is to recreate that partition. The dialoge will use all available space if you go with the default options.

n  # to create new partion    
# hit enter to create it using the default values:
<enter>  # "p" for primary   
<enter>  # "2", the default    
<enter>  # the first sector, just accept the default value
<enter>  # the last sector, again accept the default value

Now we have to actually write that changes to the disk (SD card in this case):

w  # finally apply the changes made

The dialog ends with a notice, that the changes take effect upon the next boot, so we just do that.

sudo reboot

When it is up and running again, bring all packages up to date:

sudo apt-get update
sudo apt-get upgrade

##Preperation part 2: Tools to edit the fex file In order to use the GPIO ports we have to say the bootloader which ports to use.
This file is binary format, and we need a tool called bin2fex to convert it to a normal text file first.
It is available on github, to build it from source. So lets start by installing the needed dependencies:

apt-get install build-essential g++-4.7 libusb-1.0 pkg-config git make

Get the bin2fex utility set. I did store them at ~/tools. reference (DE):

cd  # moves you to yor home folder
mkdir tools
cd tools/
git clone https://github.com/linux-sunxi/sunxi-tools sunxi-tools
cd sunxi-tools
make

# we now need a lot of sudo.
sudo -i

ln -s bin2fex /sbin/
ln -s fexc /sbin/
ln -s fex2bin /sbin/

##Editing the fex file

Mount the boot partition, where the fex file is located, as writable. reference (DE)

# still sudo -i
mkdir /tmp/sd1
mount -t vfat /dev/mmcblk0p1 /tmp/sd1
cd /tmp/sd1

Create backup of the file we are gonna change:

# inside /tmp/sd1
mkdir bak
cp *.bin bak/

Convert the script-ct-[hdmi or vga].bin file. Choose what you are using. I plugged in an VGA screen, but it stayed black so I assumed mine uses hdmi. In case you are not sure, you can just edit both files.

Display: Change to VGA or HDMI

If you want to change it to use VGA instead while we were at it.

cp uEnv.ct.vga uEnv.ct

>or for HDMI
>```shell
cp uEnv.ct.hdmi uEnv.ct
bin2fex script-ct-vga.bin script-ct-vga.fex
nano script-ct-vga.fex

Now I searched for [gpio_para], using ^W.
On a Mac this is Ctrl+w. Type gpio_para, press <enter>. bildschirmfoto 2015-08-18 um 21 22 59

There we go. Now, the format is, according to the fex guide the following:

port:<port><mux feature><pullup/down><drive capability><output level> 

I understood it like this:

# Possible values, and what that means.
port:<port><     0|1    ><       0|   1  |2       ><   0|  1 | 2  |3   ><         0|1  > 
port:<port><output|input><disabled|pullup|pulldown><10mA|20mA|30mA|40mA><output low|high> 
# Also, using <default> is possible too.

Figuring out GPIO port names

GPIO overview

Locate the pin you want to use in the Cubietruck GPIO documentation. Now find it on the GPIO list for the A20 processor, maybe you need to search for the the special name, noted in brackets of the first document.
That second list provides you with the exact name of the port to enter in the fex file.

######Example

I want to use the pin 7 (right row, 4th from bottom) on the GPIOS located next to the ethernet port and the power socket. bildschirmfoto 2015-08-18 um 21 55 45
It is called PC20 here. Now I look up the real port name.
bildschirmfoto 2015-08-18 um 21 55 53
The port name to use is PC20, too.

gpio_pin_3 = port:PC20<0><1> gpio_pin_4 = port:PC19<0><1>


Don't forget to increment the counter:
```shell
gpio_num = 4

Also I disabled all the bright LEDs in that step too. In the [leds_para] section, comment out the leds_trigger line you want to disable. I just left leds_trigger_2 = "cpu0" (the orange one). When done, to exit the editor, press ^X. Y to confirm writing your changes.

Convert that file back to the .bin format. Remeber your choice of hdmi or vga from before.

fex2bin script-ct-vga.fex script-ct-vga.bin

Add a group called gpio which makes things a bit easier later. Any user in that group will be able to write the GPIO devices. reference

exit  # exit the sudo shell
sudo groupadd -f --system gpio
sudo adduser `whoami` gpio
# `whoami` returns your current username

Finally, the reboot to apply changes.

sudo reboot

Scripts for easy usage

First we create a script file which stores the ports we want to use in both the gpio_init and gpio_exit scripts in a single central place. That makes editing easier.

sudo nano /usr/local/include/gpio_ports.bash
#!/bin/bash
# The Ports we want to initialize:
PORTS=(3 4);
# The default values on startup:
# 1 means "on", 0 means "off"
DEFAULTS=(1 1); # port 3 an 4 are inverted here, because of the connected circut. So for the two we want to set them to "on" on startup.

# Checks if run as root
if [ "$(id -u)" != "0" ]; then
        echo "You must be root to do that!" 2>&1;
        exit 1;
fi

Here are the two scripts files to init (gpio_init) and to cleanup (gpio_exit):

sudo nano /usr/local/bin/gpio_init
#!/bin/bash

# Loads the port configuration file
. /usr/local/include/gpio_ports.bash

for ((i=0; i<${#PORTS[*]}; i++)); do
        echo "${PORTS[i]}";# > /sys/class/gpio/export;
        echo "out";# > /sys/class/gpio/gpio${PORTS[i]}/direction;
        echo "${DEFAULTS[i]}";# > /sys/class/gpio/gpio${PORTS[i]}/value;
done

# To be able to change (write) them as normal user, this adds permitions to our 'gpio' group we created earlier.
chgrp -HR gpio /sys/class/gpio/* /sys/class/leds/*
chmod -R g+rwx /sys/class/gpio/* /sys/class/leds/*
# also added access rights to the leds because they are fun!!
sudo nano /usr/local/bin/gpio_exit
#!/bin/bash

# Loads the port configuration file
. /usr/local/include/gpio_ports.bash

for i in "${PORTS[@]}"; do
        echo "$i" > /sys/class/gpio/unexport;
done

Make them all executable.

sudo chgrp gpio /usr/local/bin/gpio_* /usr/local/include/gpio_*
sudo chmod g+x /usr/local/bin/gpio_* /usr/local/include/gpio_*

Using the GPIOs

Now to enable the ports, execute our init script. Needs sudo.

sudo gpio_init

Note: That step must be redone once after each reboot!

Now you can turn pins on or off like the following (reference):

# manually
echo "1" > /sys/class/gpio/gpio3/value
echo "0" > /sys/class/gpio/gpio3/value
# or with the scripts we created
gpio_on
gpio_off

If you are done with the ports, you can disable them again with

sudo gpio_exit

To reactivate them, you have to call sudo gpio_init again

Notes:

I got around to check that with a multimeter, and (after shorting the tiny pins several times, urgh) it does work. Yay!
BTW, the port did output -3.03V (negative because I connected the multimeter the wrong way, lol).

That's it!

Your done.
If you want to do more:

Extra: Connecting relais

Because I am already writing down the stuff I did, I can add a short section about how to relais here too. You should definetly watch this great video about Using Relays and Relay Boards with the Raspberry Pi first, it is very informative if you are not familiar with relais.

Some needed scripts: Some more custom scripts to make usage easier. They are not needed. You can customize them to fit your liking. The first script file I did create is gpio_on.
Open the file with

sudo nano /usr/local/bin/gpio_on

and enter

#!/bin/sh
echo "out" > /sys/class/gpio/gpio3/direction
echo 0 > /sys/class/gpio/gpio3/value #inverted, because of the connected circut.
echo 1 > /sys/class/leds/green\:ph07\:led4/brightness
# turns the LED called "green:ph07:led4" on, too, to show the status.

That turns on port 3 (defined in the fex file), as well as the green LED.
Also I created the file to turn it off again, gpio_off.

sudo nano /usr/local/bin/gpio_off
#!/bin/sh
echo "out" > /sys/class/gpio/gpio3/direction
echo 1 > /sys/class/gpio/gpio3/value # inverted (1 instead of 0) because of the connected circuit inverts that again. Else use 0.
echo 0 > /sys/class/leds/green\:ph07\:led4/brightness

Make them all executable.

sudo chgrp gpio /usr/local/bin/gpio_* /usr/local/include/gpio_*
sudo chmod g+x /usr/local/bin/gpio_* /usr/local/include/gpio_*
@meeximum
Copy link

thx for your great tutorial!!!
I've a question to you know which pin I could use for reading an analog input (temp. sensor)?

br
Meex

@daveculp
Copy link

@meeximim The Cubiuetruck does not have analog input pins. You will need to either make and RC timer circuit or add an IC that gives you analog input such as an MCP3008. See here for more info on setting up an RC time circuit: http://www.raspberrypi-spy.co.uk/2012/08/reading-analogue-sensors-with-one-gpio-pin/

@felipeandres254
Copy link

Hi @luckydonald,

Thanks for the tutorial! Do you have any guide or advice on how to treat GPIO as input?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment