Apr 30, 2016, 1:37 PM

Hi All, Comme de nombreux avant moi, je suis en train de monter une racalbox dans un boitier NES. J'avais commandé un Mausberry switch pour gérer les boutons mais comme ils m'ont mis une carotte... Je me repli sur le mode GPIO que la team a implémenté il y a peu. Le problème, c'est que le script ne gère que le Power, pas le Reset. J'ai donc mis les mains dedans pour améliorer le script et gérer les deux actions (+ la LED). Les deux fichier à ajouter/écraser: rpi-nes.py

import RPi.GPIO as GPIO
import time
import os

POWERPLUS = 3
RESETPLUS = 2
LED = 14

GPIO.setmode(GPIO.BCM)     # set up BCM GPIO numbering 

GPIO.setup(RESETPLUS, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# GPIO on pin 3 is the GPIO 2 in BCM mode
#to Reset+

GPIO.setup(POWERPLUS, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# GPIO on pin 5 is the GPIO 3 in BCM mode
#to Power+

GPIO.setup(LED, GPIO.OUT)
GPIO.output(LED, True)
# GPIO on pin 8 is the GPIO 14 in BCM mode
#to LED+

POWER_triggered = False
RESET_triggered = False

# Define a threaded callback function to run in another thread when events are detected  
def reset(channel):
	global RESET_triggered
	RESET_triggered = True

def power(channel):
	global POWER_triggered
	POWER_triggered = True

def blink(speed):
	GPIO.output(LED, False)
	time.sleep(speed)
	GPIO.output(LED, True)
	time.sleep(speed)

GPIO.add_event_detect(RESETPLUS, GPIO.FALLING, callback=reset)
GPIO.add_event_detect(POWERPLUS, GPIO.RISING, callback=power)

while not POWER_triggered and not RESET_triggered:
	time.sleep(.1)

if RESET_triggered:
	os.system("shutdown -r now")
	for i in range(0,100):  
			blink(0.05)

if POWER_triggered:
	os.system("shutdown -h now")
	for i in range(0,10):  
			blink(0.15)

GPIO.cleanup()         # clean up after yourself  

powerswitch.sh

#!/bin/bash

# http://lowpowerlab.com/atxraspi/#installation
atx_raspi_start()
{
    # This is GPIO 7 (pin 26 on the pinout diagram).
    # This is an input from ATXRaspi to the Pi.
    # When button is held for ~3 seconds, this pin will become HIGH signalling to this script to poweroff the Pi.
    SHUTDOWN=$1
    REBOOTPULSEMINIMUM=200        #reboot pulse signal should be at least this long
    REBOOTPULSEMAXIMUM=600        #reboot pulse signal should be at most this long
    echo "$SHUTDOWN" > /sys/class/gpio/export
    echo "in" > /sys/class/gpio/gpio$SHUTDOWN/direction

    # Added reboot feature (with ATXRaspi R2.6 (or ATXRaspi 2.5 with blue dot on chip)
    # Hold ATXRaspi button for at least 500ms but no more than 2000ms and a reboot HIGH pulse of 500ms length will be issued

    # This is GPIO 8 (pin 24 on the pinout diagram).
    # This is an output from Pi to ATXRaspi and signals that the Pi has booted.
    # This pin is asserted HIGH as soon as this script runs (by writing "1" to /sys/class/gpio/gpio8/value)
    BOOT=$2
    echo "$BOOT" > /sys/class/gpio/export
    echo "out" > /sys/class/gpio/gpio$BOOT/direction
    echo "1" > /sys/class/gpio/gpio$BOOT/value

    echo "ATXRaspi shutdown script started: asserted pins ($SHUTDOWN=input,LOW; $BOOT=output,HIGH). Waiting for GPIO$SHUTDOWN to become HIGH..."

    #This loop continuously checks if the shutdown button was pressed on ATXRaspi (GPIO7 to become HIGH), and issues a shutdown when that happens.
    #It sleeps as long as that has not happened.
    while true; do
        shutdownSignal=$(cat /sys/class/gpio/gpio$SHUTDOWN/value)
        if [ $shutdownSignal = 0 ]; then
            /bin/sleep 0.2
        else
            pulseStart=$(date +%s%N | cut -b1-13) # mark the time when Shutoff signal went HIGH (milliseconds since epoch)
            while [ $shutdownSignal = 1 ]; do
                /bin/sleep 0.02
                if [ $(($(date +%s%N | cut -b1-13)-$pulseStart)) -gt $REBOOTPULSEMAXIMUM ]; then
                    echo "ATXRaspi triggered a shutdown signal, halting Rpi ... "
                    touch "/tmp/poweroff.please"
                    poweroff
                    exit
                fi
                shutdownSignal=$(cat /sys/class/gpio/gpio$SHUTDOWN/value)
            done
            #pulse went LOW, check if it was long enough, and trigger reboot
            if [ $(($(date +%s%N | cut -b1-13)-$pulseStart)) -gt $REBOOTPULSEMINIMUM ]; then 
                echo "ATXRaspi triggered a reboot signal, recycling Rpi ... "
                reboot
                exit
            fi
        fi
    done    
}

atx_raspi_stop()
{
    # Cleanup GPIO init
    for i in $*; do
        echo "$i" > /sys/class/gpio/unexport
    done
}

# http://mausberry-circuits.myshopify.com/pages/setup
mausberry_start()
{
    # Init GPIO :
    # $1 is the GPIO pin connected to the lead on switch labeled OUT
    # $2 is the GPIO pin connected to the lead on switch labeled IN
    echo "$1" > /sys/class/gpio/export
    echo "in" > /sys/class/gpio/gpio$1/direction

    echo "$2" > /sys/class/gpio/export
    echo "out" > /sys/class/gpio/gpio$2/direction
    echo "1" > /sys/class/gpio/gpio$2/value

    # Wait for switch off signal 
    power=0
    while [ "$power" = "0" ]; do
        sleep 1
        power=$(cat /sys/class/gpio/gpio$1/value)
    done

    # Switch off
    if [ "$?" = "0" ]; then
        touch "/tmp/poweroff.please"
        poweroff
    fi
}

mausberry_stop()
{
    # Cleanup GPIO init
    for i in $*; do
        echo "$i" > /sys/class/gpio/unexport
    done
}

# http://www.msldigital.com/pages/support-for-remotepi-board-2013
# http://www.msldigital.com/pages/support-for-remotepi-board-plus-2015
msldigital_start()
{
    # Init GPIO : 
    # $1 is the GPIO pin receiving the shut-down signal
    echo "$1" > /sys/class/gpio/export
    echo "in" > /sys/class/gpio/gpio$1/direction

    # Wait for switch off signal 
    power=0
    while [ "$power" = "0" ]; do
        sleep 1
        power=$(cat /sys/class/gpio/gpio$1/value)
    done

    # Switch off
    if [ "$?" = "0" ]; then
        touch "/tmp/poweroff.please"
        poweroff
    fi
}

msldigital_stop()
{
    if [ -f "/tmp/shutdown.please" -o -f "/tmp/poweroff.please" ]; then
        if [ -f "/tmp/shutdown.please" -a "$CONFVALUE" = "REMOTEPIBOARD_2005" ]; then
            # Init GPIO
            GPIOpin=15
            echo "$GPIOpin" > /sys/class/gpio/export

            # Execute shutdown sequence on pin
            echo "out" > /sys/class/gpio/gpio$GPIOpin/direction
            echo "1" > /sys/class/gpio/gpio$GPIOpin/value
            usleep 125000
            echo "0" > /sys/class/gpio/gpio$GPIOpin/value
            usleep 200000
            echo "1" > /sys/class/gpio/gpio$GPIOpin/value
            usleep 400000
            echo "0" > /sys/class/gpio/gpio$GPIOpin/value
            sleep 1

            # Uninit GPIO
            echo "$GPIOpin" > /sys/class/gpio/unexport
        fi
        echo "out" > /sys/class/gpio/gpio$1/direction
        echo "1" > /sys/class/gpio/gpio$1/value
        sleep 3
    fi
    # Cleanup GPIO init
    for i in $*; do
        echo "$i" > /sys/class/gpio/unexport
    done
}

nes_start()
{
	python /recalbox/scripts/rpi-nes.py &
    pid=$!
    echo "$pid" > /tmp/rpi-nes.pid
    wait "$pid"
}
nes_stop()
{
    if [[ -f /tmp/rpi-nes.pid ]]; then
        kill <code>cat /tmp/rpi-nes.pid</code>
    fi
}

pin56_start()
{
    mode=$1
    python /recalbox/scripts/rpi-pin56-power.py -m "$mode" &
    pid=$!
    echo "$pid" > /tmp/rpi-pin56-power.pid
    wait "$pid"
}
pin56_stop()
{
    if [[ -f /tmp/rpi-pin56-power.pid ]]; then
        kill <code>cat /tmp/rpi-pin56-power.pid</code>
    fi
}

# First parameter must be start or stop
if [[ "$1" != "start" && $1 != "stop" ]]; then
    exit 1
fi

CONFFILE="/recalbox/share/system/recalbox.conf"
CONFPARAM="system.power.switch" 
CONFVALUE=
if [ -e $CONFFILE ]; then
    CONFVALUE=$(sed -rn "s/^$CONFPARAM=(\w*)\s*.*$/\1/p" $CONFFILE | tail -n 1)
fi

case "$CONFVALUE" in
    "ATX_RASPI_R2_6")
        atx_raspi_$1 7 8
    ;;
    "MAUSBERRY")
        mausberry_$1 23 24
    ;;
    "REMOTEPIBOARD_2003")
        msldigital_$1 22
    ;;
    "REMOTEPIBOARD_2005")
        msldigital_$1 14
    ;;
    "PIN56ONOFF")
        pin56_$1 onoff
    ;;
    "PIN56PUSH")
        echo "will start pin56_$1"
        pin56_$1 push
    ;;
	"NES")
        echo "will start NES_$1"
        nes_$1 useless
    ;;
esac

-SSH sur la recalbox -mount -o remount, rw / pour passer la partition en écriture -copie des 2 fichiers dans /recalbox/scripts -modif des droits: chmod 644 rpi-nes.py et chmod 755 powerswitch.sh -enfin, on ajoute system.power.switch=NES dans le recalbox.conf Maintenant pour ce qui est du câbage: -Power+ (Fil marron) --> GPIO3 (pin 5) -Reset+ (Fil jaune)--> GPIO2 (pin 3) -LED+ --> GPIO14 (pin 😎 -Power- (Fil rouge), Reset- (Fil orange), LED- --> GND (pin 6) Ne pas oublier de mettre une resistance de 300 Ohm sur le LED+ Pour la LED, soit on vient souder 2 fils dessus et on coupe la trace du PCB qui va au Reset- Ou bien on retourne la LED sur le PCB et dans ce cas le fil Reset- est aussi la masse de la LED. Une fois tout ça en place, vous aurez un bouton Power qui allume et éteind la Recalbox et un bouton Reset qui la redémarre (soft reset). En prime, j'ai rajouté du clignotement de LED dans le script (rapide pour reset, lent pour power).