Tuesday, February 6, 2018

Raspberry PI - The Audio Engine - Part 9 - USB HUB Control

We're still on the way to collect this or that crumb that's been left on the table.

We already turned off HDMI, Wifi, Bluetooth, LEDs and several processes earlier. 
The idea is to get rid of any potential unnecessary distraction to the audio job.


Today we're looking at how to control our USB ports including the ethernet port.
(The PI ethernet port is basically an integrated USB dongle.)

The PI, actually all PIs,  come with a major bottleneck.
Just a ""single"" USB 2.0 pipe 
is used into the SOC (main CPU chip) for all USB ports incl. ethernet. All of them get routed over that single pipe. 

That's what I'd call a major bottleneck.

There a now two tweak options I'd like to suggest.


1.

Those of you who now run e.g. a 3B+ and followed my recent advise to go wireless on a 3B+ can basically completely shutdown USB incl. ethernet. 

Wifi is not attached to the USB bus btw!

This will seriously bring down any USB related activity and also seriously reduce power consumption.

2.

Those who followed my earlier advise to use an external network dongle can also tweak
the USB ports.  The tweak potential is much more limited though.



A fellow programmer - Yutaka from Japan - has written a nice little tool to control USB-Hubs. 

It has been written in 2006 and - guess what - it still works.


Option 1. Total USB and ethernet shutdown


Enter the commands as seen in below pCP screenshot:



Save it and reboot.

Done.

Option 2. Selective USB  shutdown

Since we - at least some of you I guess - use a USB ethernet dongle, for the networking, we can physically switch off all the other ports. 
The onboard-ethernet port in particular.

The port-scheme follows below layout (port rearside of your PI):

####################
#            #          #         #
#            #    1    #    2   #
#            #          #         #
#   eth0  #############
#            #          #         #
#            #    4    #    3   #
#            #          #         #
####################

The tool has a slightly different port numbering. We gonna match it according to below
scheme:

# Hub:Port -- Controlled port(s) 
0:1 -- Controls the PI Ethernet port eth0
0:2 -- Controls all four PI-USB ports (not the Ethernet)
0:3 -- Controls PI-USB Port 4
0:4 -- Controls PI-USB Port 2
0:5 -- Controls PI-USB Port 3

You might have figured already, all ports can be controlled except PI-USB Port 1.
Great. This Port 1 is where we plug-in our ethernet usb dongle. 
Because then we just turn the rest off.

Now's your turn.

To be able to use this HUB tool we have to build it first. 
I assume that you built the squeezelite binary on the way here and you still have the compiling environment installed.

If so, let's get started. If not install the customized squeezelite binary first, you don't want  to miss that!


As usual ssh login to your RPI as user tc. 

Then copy/paste following commands one after one:

###############################

tce-load -wi libusb-compat-dev.tcz
cd /tmp
wget https://github.com/codazoda/hub-ctrl.c/archive/master.zip && unzip master.zip
cd ./hub-ctrl.c-master
gcc -o hub-ctrl hub-ctrl.c -lusb

sudo su 

install -o tc -g staff -m 770 hub-ctrl /mnt/mmcblk0p2/tce




###############################

That'll take about 20 seconds.

That was an easy one. Wasn't it !?!?

To check if the hub-ctrl binary is at the right spot, type:

###############################
ls -l /mnt/mmcblk0p2/tce


###############################

Now we have to execute the hub-ctrl tool with the right options at one point in time. 
We do this, as usual, with our "tune.sh" tool, which is already running quite some actions 3 minutes after boot. We just add the hub-ctrl actions to it.

NOTE: If you run below without having an external ethernet dongle and that one not sticking in Port 1 - as indicated above - you'll loose your network connections! 

OK. I told you. Let's go ahead.

Copy/paste below. All text between the hashed-lines:

################################
test -f /mnt/mmcblk0p2/tce/tune.sh || touch /mnt/mmcblk0p2/tce/tune.sh
chmod 777 /mnt/mmcblk0p2/tce/tune.sh

cat <<'EOF' >>/mnt/mmcblk0p2/tce/tune.sh
# ETH0 = off
/mnt/mmcblk0p2/tce/hub-ctrl -h 0 -P 1 -p 0
# USB Port 2
/mnt/mmcblk0p2/tce/hub-ctrl -h 0 -P 4 -p 0
# USB Port 3
/mnt/mmcblk0p2/tce/hub-ctrl -h 0 -P 5 -p 0
# USB Port 4
/mnt/mmcblk0p2/tce/hub-ctrl -h 0 -P 3 -p 0

EOF

sed -i  '/^\s*$/d' /mnt/mmcblk0p2/tce/tune.sh
sync


##################################

Now you can reboot or repower your PI.

Above commands simply turn all the ports off. 
For those of you who want to play with the hub-ctrl tool. Using e.g. a "-p 1" at the end of above listed commands would turn the respective ports on again.


Done. A 20 minute exercise. Congrats.


As usual make a backup of your SD-card!


Enjoy.




3 comments:

  1. When i originally tried this on piCorePlayer 3.2.2Audio, it wouldn't compile. But as soon as i upgraded to 3.5.0Audio it worked just like above. Not really sure i hear any diff with this like i do with all Soundcheck's previous changes.

    ReplyDelete
  2. Hi Klaus,
    Great blog. Using a pi 3B+ with a usb dac. Looking to turn off all other usb ports + ethernet. Can it be done without this tool using echo '1.1.1.??' somehow? Also, where is tune.sh run from?
    Thanks again,
    Mike

    ReplyDelete
  3. I ended up using this to turn off ethernet, I use a usb dac.
    pkill -f eth0
    ifconfig eth0 down
    echo 0 > /sys/bus/usb/devices/1-1.1.1/bConfigurationValue
    echo 0 > /sys/bus/usb/devices/1-1.1/bConfigurationValue

    Mike


    ReplyDelete