#!/bin/bash
# __ __ __
# / | / |/ |
# ______ ______ __ __ _██ |_ ██/ ██ |
# / \ / \ ______ / | / |/ ██ | / |██ |
# /██████ |/██████ |/ |██ | ██ |██████/ ██ |██ |
# ██ | ██ |██ | ██ |██████/ ██ | ██ | ██ | __ ██ |██ |
# ██ |__██ |██ \__██ | ██ \__██ | ██ |/ |██ |██ |
# ██ ██/ ██ ██/ ██ ██/ ██ ██/ ██ |██ |
# ███████/ ██████/ ██████/ ████/ ██/ ██/
# ██ |
# ██ |
# ██/ https://po-util.com
#
# po-util - The Ultimate Local Particle Experience for Linux and macOS
# Copyright (C) 2018 Nathan Robinson
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# Helper functions
pause()
{
read -rp "$*"
}
print_logo()
{
if [ "$1" ];
then
TEXTLINE="$1"
else
TEXTLINE="https://po-util.com"
fi
LOGO=" __ __ __
/ | / |/ |
______ ______ __ __ _██ |_ ██/ ██ |
/ \ / \ ______ / | / |/ ██ | / |██ |
/██████ |/██████ |/ |██ | ██ |██████/ ██ |██ |
██ | ██ |██ | ██ |██████/ ██ | ██ | ██ | __ ██ |██ |
██ |__██ |██ \__██ | ██ \__██ | ██ |/ |██ |██ |
██ ██/ ██ ██/ ██ ██/ ██ ██/ ██ |██ |
███████/ ██████/ ██████/ ████/ ██/ ██/
██ |
██ |
██/ $TEXTLINE
"
if [ -t 1 ];
then
echo "$(tput setaf 6)$(tput bold)$LOGO$(tput sgr0)"
else
echo "$LOGO"
fi
}
blue_echo()
{
if [ -t 1 ];
then
echo "$(tput setaf 6)$(tput bold)$1$(tput sgr0)"
else
echo "$1"
fi
}
green_echo()
{
if [ -t 1 ];
then
echo "$(tput setaf 2)$(tput bold)$1$(tput sgr0)"
else
echo "$1"
fi
}
red_echo()
{
if [ -t 1 ];
then
echo "$(tput setaf 1)$(tput bold)$1$(tput sgr0)"
else
echo "$1"
fi
}
find_objects() #Consolidated function
{
if [ "$1" != "" ];
then
case "$1" in
*/)
#"has slash"
DEVICESFILE="${1%?}"
FIRMWAREDIR="${1%?}"
FIRMWAREBIN="${1%?}"
DIRECTORY="${1%?}"
;;
*)
echo "doesn't have a slash" > /dev/null
DEVICESFILE="$1"
FIRMWAREDIR="$1"
FIRMWAREBIN="$1"
DIRECTORY="$1"
;;
esac
if [ -f "$CWD/$DEVICESFILE/devices.txt" ] || [ -d "$CWD/$FIRMWAREDIR/firmware" ] || [ -f "$CWD/$FIRMWAREBIN/bin/firmware.bin" ];
then
DEVICESFILE="$CWD/$DEVICESFILE/devices.txt"
FIRMWAREDIR="$CWD/$FIRMWAREDIR/firmware"
FIRMWAREBIN="$CWD/$FIRMWAREBIN/bin/firmware.bin"
else
if [ -d "$DIRECTORY" ] && [ -d "$DIRECTORY/firmware" ];
then
DEVICESFILE="$DIRECTORY/devices.txt"
FIRMWAREDIR="$DIRECTORY/firmware"
FIRMWAREBIN="$DIRECTORY/bin/firmware.bin"
else
if [ -d "$CWD/$DIRECTORY" ] && [ -d "$CWD/firmware" ];
then
DEVICESFILE="$CWD/$DIRECTORY/../devices.txt"
FIRMWAREDIR="$CWD/$DIRECTORY"
FIRMWAREBIN="$CWD/$DIRECTORY/../bin/firmware.bin"
else
if [ "$DIRECTORY" == "." ] && [ -f "$CWD/main.cpp" ];
then
cd "$CWD/.." || exit
DEVICESFILE="$PWD/devices.txt"
FIRMWAREDIR="$CWD"
FIRMWAREBIN="$PWD/bin/firmware.bin"
else
echo
red_echo "Firmware not found!"
blue_echo "Please run \"po init DEVICE FOLDER\" to setup a project,
or choose a valid directory."
echo
exit
fi
fi
fi
fi
else
DEVICESFILE="$CWD/devices.txt"
FIRMWAREDIR="$CWD/firmware"
FIRMWAREBIN="$CWD/bin/firmware.bin"
fi
if [ -d "$FIRMWAREDIR" ];
then
FIRMWAREDIR="$FIRMWAREDIR"
else
if [ "$DIRWARNING" == "true" ];
then
echo
red_echo "Firmware directory not found!"
blue_echo "Please run \"po init DEVICE FOLDER\" to setup a project,
or choose a valid directory."
echo
exit
fi
FINDDIRFAIL="true"
fi
if [ -f "$DEVICESFILE" ];
then
DEVICES="$(cat $DEVICESFILE)"
else
if [ "$DEVICEWARNING" == "true" ];
then
echo
red_echo "devices.txt not found!"
blue_echo "You need to create a \"devices.txt\" file in your project directory with the names
of your devices on each line."
green_echo "Example:"
echo " product1
product2
product3
"
fi
FINDDEVICESFAIL="true"
fi
if [ -f "$FIRMWAREBIN" ];
then
FIRMWAREBIN="$FIRMWAREBIN"
else
if [ "$BINWARNING" == "true" ];
then
echo
red_echo "Firmware Binary not found!"
blue_echo "Perhaps you need to build your firmware?"
echo
fi
FINDBINFAIL="true"
fi
}
validateDevicePlatform()
{
# Make sure we are using photon, P1, electron, pi, core, or duo
if [ "$1" == "photon" ] || [ "$1" == "P1" ] || [ "$1" == "electron" ] || [ "$1" == "pi" ] || [ "$1" == "core" ] || [ "$1" == "duo" ];
then
DEVICE_TYPE="$1"
if [ "$DEVICE_TYPE" == "duo" ];
then
cd "$FIRMWARE_DUO/firmware" || exit
switch_branch $BRANCH_DUO &> /dev/null
fi
if [ "$DEVICE_TYPE" == "pi" ];
then
cd "$FIRMWARE_PI/firmware" || exit
switch_branch "feature/raspberry-pi" &> /dev/null
else
cd "$FIRMWARE_PARTICLE/firmware" || exit
switch_branch &> /dev/null
fi
else
echo
if [ "$1" == "redbear" ] || [ "$1" == "bluz" ] || [ "$1" == "oak" ];
then
red_echo "This compound is not supported yet. Find out more here: https://git.io/vMTAw"
echo
fi
red_echo "Please choose \"photon\", \"P1\", \"electron\", \"core\", \"pi\", or \"duo\",
or choose a proper command."
common_commands
exit
fi
if [ "$DEVICE_TYPE" == "photon" ];
then
DFU_ADDRESS1="2b04:d006"
DFU_ADDRESS2="0x080A0000"
fi
if [ "$DEVICE_TYPE" == "P1" ];
then
DFU_ADDRESS1="2b04:d008"
DFU_ADDRESS2="0x080A0000"
fi
if [ "$DEVICE_TYPE" == "electron" ];
then
DFU_ADDRESS1="2b04:d00a"
DFU_ADDRESS2="0x08080000"
fi
if [ "$DEVICE_TYPE" == "core" ];
then
DFU_ADDRESS1="1d50:607f"
DFU_ADDRESS2="0x08005000"
fi
if [ "$DEVICE_TYPE" == "duo" ];
then
DFU_ADDRESS1="2b04:d058"
DFU_ADDRESS2="0x80C0000"
fi
}
build_message()
{
echo
cd "$FIRMWAREDIR"/.. || exit
BINARYDIR="$PWD/bin"
green_echo "Binary saved to $BINARYDIR/firmware.bin"
echo
exit
}
dfu_open()
{
DFU_LIST="$(dfu-util -l)"
if echo "$DFU_LIST" | grep "2b04:d006" > /dev/null || echo "$DFU_LIST" | grep "2b04:d008" > /dev/null || echo "$DFU_LIST" | grep "2b04:d00a" > /dev/null || echo "$DFU_LIST" | grep "1d50:607f" > /dev/null || echo "$DFU_LIST" | grep "2b04:d058" > /dev/null ;
then
blue_echo "
Already found a device in DFU mode!
"
return
fi
if [ "$1" == "-d" ] || [ "$1" == "--device" ];
then
if [[ -e "$2" ]]; # Check if serial port is avaliable
then
blue_echo "
Placing device $2 into DFU mode...
"
custom-baud "$2" "$DFUBAUDRATE" > /dev/null 2>&1
return
else
red_echo "
Could not find a device on $2
"
fi
return
fi
if [ "$DEVICE_TYPE" == "duo" ];
then
if [ -e "$MODEM_DUO" ];
then
MODEM="$MODEM_DUO"
else
echo
red_echo "Device not found!"
echo
blue_echo "Your device must be connected by USB."
echo
exit
fi
else
if [ -e "$MODEM" ];
then
MODEM="$MODEM"
else
echo
red_echo "Device not found!"
echo
blue_echo "Your device must be connected by USB."
echo
exit
fi
fi
if [ -e "$MODEM" ];
then
custom-baud "$MODEM" "$DFUBAUDRATE" > /dev/null 2>&1
fi
}
serial_open()
{
if [ "$1" == "-d" ] || [ "$1" == "--device" ];
then
if [[ -e "$2" ]]; # Check if serial port is avaliable
then
blue_echo "
Placing device $2 into listening mode...
"
custom-baud "$2" "28800" > /dev/null 2>&1
return
else
red_echo "
Could not find a device on $2
"
fi
return
fi
if [ "$DEVICE_TYPE" == "duo" ];
then
if [ -e "$MODEM_DUO" ];
then
MODEM="$MODEM_DUO"
else
echo
red_echo "Device not found!"
echo
blue_echo "Your device must be connected by USB."
echo
exit
fi
else
if [ -e "$MODEM" ];
then
MODEM="$MODEM"
else
echo
red_echo "Device not found!"
echo
blue_echo "Your device must be connected by USB."
echo
exit
fi
fi
if [ -e "$MODEM" ];
then
custom-baud "$MODEM" "28800" > /dev/null 2>&1
fi
}
switch_branch()
{
if [ "$1" != "" ];
then
if [ "$(git rev-parse --abbrev-ref HEAD)" != "$1" ];
then
git checkout "$1" > /dev/null
fi
else
if [ "$(git rev-parse --abbrev-ref HEAD)" != "$BRANCH" ];
then
git checkout "$BRANCH" > /dev/null
fi
fi
}
common_commands() #List common commands
{
echo
blue_echo "Common commands include:
build, flash, clean, ota, dfu, serial, init, config, setup, library"
echo
}
cleanFirmware()
{
if [ "$DEVICE_TYPE" == "duo" ];
then
cd "$FIRMWARE_DUO"/firmware || exit
else
cd "$FIRMWARE_PARTICLE"/firmware || exit
fi
if [ "$DEVICE_TYPE" == "pi" ];
then
switch_branch "feature/raspberry-pi" &> /dev/null
elif [ "$DEVICE_TYPE" == "duo" ];
then
switch_branch "$BRANCH_DUO" &> /dev/null
else
switch_branch &> /dev/null
fi
git stash &> /dev/null
echo
if [ "$DEVICE_TYPE" == "pi" ];
then
make clean -s 2>&1 /dev/null
else
make clean -s PLATFORM="$DEVICE_TYPE" 2>&1 /dev/null
fi
if [ "$FIRMWAREDIR/../bin" != "$HOME/bin" ];
then
rm -rf "$FIRMWAREDIR/../bin"
fi
blue_echo "Sucessfully cleaned."
echo
}
store_build_parameters() # Keep track of $DEVICE_TYPE and $FIRMWAREDIR
{
PARAMETERS="$HOME/.po-util/buildParameters"
[[ -f "$PARAMETERS" ]] && . "$PARAMETERS"
[[ "$STORED_DEVICE_TYPE" != "$DEVICE_TYPE" ]] && DEVICE_TYPE_CHANGED="true"
[[ "$STORED_FIRMWAREDIR" != "$FIRMWAREDIR" ]] && FIRMWAREDIR_CHANGED="true"
if [[ "$STORED_DEVICE_TYPE" != "$DEVICE_TYPE" ]] || [[ "$STORED_FIRMWAREDIR" != "$FIRMWAREDIR" ]]; then
echo "STORED_DEVICE_TYPE=$DEVICE_TYPE" > "$PARAMETERS"
echo "STORED_FIRMWAREDIR=$FIRMWAREDIR" >> "$PARAMETERS"
fi
if [[ "$DEVICE_TYPE_CHANGED" ]] && [[ "$FIRMWAREDIR_CHANGED" ]]; then
blue_echo "Detected change of platform and project. Cleaning before attempting build..."
cleanFirmware
elif [[ "$DEVICE_TYPE_CHANGED" ]]; then
blue_echo "Detected change of platform. Cleaning before attempting build..."
cleanFirmware
elif [[ "$FIRMWAREDIR_CHANGED" ]]; then
blue_echo "Detected change of project. Cleaning before attempting build..."
cleanFirmware
fi
}
printSizes()
{
if [[ "$DEVICE_TYPE" == "core" ]]; then
FLASHTOTAL="110592"
RAMTOTAL="20480"
else
FLASHTOTAL="125000"
RAMTOTAL="60000"
fi
FLASH="$(( $1 + $2 ))"
FLASHPERCENT=$(bc -l <<< "scale = 4; $FLASH / $FLASHTOTAL * 100")
RAM="$(( $3 + $2 ))"
RAMPERCENT=$(bc -l <<< "scale = 4; $RAM / $RAMTOTAL * 100")
echo
echo "$(tput setaf 6)$(tput bold)Flash Used:$(tput sgr0) $FLASH / $FLASHTOTAL ${FLASHPERCENT%??} %"
echo "$(tput setaf 6)$(tput bold)RAM Used: $(tput sgr0) $RAM / $RAMTOTAL ${RAMPERCENT%??} %"
}
build_firmware()
{
store_build_parameters
print_logo "Building firmware for $DEVICE_TYPE..."
if [ "$DEVICE_TYPE" == "duo" ];
then
make all -s -C "$FIRMWARE_DUO/firmware/main" APPDIR="$FIRMWAREDIR" TARGET_DIR="$FIRMWAREDIR/../bin" PLATFORM="$DEVICE_TYPE"
else
if [ "$DEVICE_TYPE" == "pi" ];
then
if hash docker 2>/dev/null;
then
if docker run --rm -i -v $FIRMWARE_PI/firmware:/firmware -v $FIRMWAREDIR:/input -v $FIRMWAREDIR/../bin:/output particle/buildpack-raspberrypi 2> echo;
then
echo
blue_echo "Successfully built firmware for Raspberry Pi"
else
echo
red_echo "Build failed."
echo
exit 1
fi
else
red_echo "Docker not found. Please install docker to build firmware for Raspberry Pi"
echo
exit 1
fi
else
make all -s -C "$FIRMWARE_PARTICLE/firmware/main" APPDIR="$FIRMWAREDIR" TARGET_DIR="$FIRMWAREDIR/../bin" PLATFORM="$DEVICE_TYPE"
fi
fi
}
ota() # device firmware
{
find_objects "$2"
DIRWARNING="true"
BINWARNING="true"
if [ "$FINDDIRFAIL" == "true" ] || [ "$FINDBINFAIL" == "true" ];
then
exit
fi
if [ "$1" == "" ];
then
echo
red_echo "Please specify which device to flash ota."
echo
exit
fi
if [ "$1" == "--multi" ] || [ "$1" == "-m" ] || [ "$1" == "-ota" ];
then
DEVICEWARNING="true"
if [ "$FINDDEVICESFAIL" == "true" ] || [[ -z "$DEVICES" ]];
then
cd "$CWD" || exit
echo "" > devices.txt
red_echo "Please list your devices in devices.txt"
exit 1
fi
for DEVICE in $DEVICES ; do
echo
blue_echo "Flashing to device $DEVICE..."
particle flash "$DEVICE" "$FIRMWAREBIN" || {
red_echo "Your device must be online in order to flash firmware OTA." && echo && exit 1
}
done
echo
exit
fi
echo
blue_echo "Flashing to device $1..."
particle flash "$1" "$FIRMWAREBIN" || {
red_echo "Try using \"particle flash\" if you are having issues." && echo && exit 1
}
echo
exit
}
config()
{
if [[ -d "$HOME/.po-util" ]]; then
echo "Exists!" > /dev/null
else
mkdir -p "$HOME/.po-util"
fi
SETTINGS=~/.po-util/config
BASE_DIR=~/.po-util/src
FIRMWARE_PARTICLE=$BASE_DIR/particle
FIRMWARE_DUO=$BASE_DIR/redbearduo
FIRMWARE_PI=$BASE_DIR/pi
BRANCH="release/stable"
BRANCH_DUO="duo"
BRANCH_PI="feature/raspberry-pi"
GCC_ARM_PATH=$BINDIR/gcc-arm-embedded/$GCC_ARM_VER/bin/
MODEM_DUO=$MODEM_DUO
echo BASE_DIR="$BASE_DIR" >> $SETTINGS
echo FIRMWARE_PARTICLE="$FIRMWARE_PARTICLE" >> $SETTINGS
echo FIRMWARE_DUO="$FIRMWARE_DUO" >> $SETTINGS
echo FIRMWARE_PI="$FIRMWARE_PI" >> $SETTINGS
echo "export PARTICLE_DEVELOP=1" >> $SETTINGS
echo BINDIR="$BINDIR" >> $SETTINGS
# Particle
echo
blue_echo "Which branch of the Particle firmware would you like to use?
You can find the branches at https://github.com/spark/firmware/branches
If you are unsure, please enter \"release/stable\""
read -rp "Branch: " branch_variable
BRANCH="$branch_variable"
echo BRANCH="$BRANCH" >> $SETTINGS
echo
# RedBear DUO
blue_echo "Which branch of the RedBear DUO firmware would you like to use?
You can find the branches at https://github.com/redbear/Duo/branches
If you are unsure, please enter \"duo\""
read -rp "Branch: " branch_variable
BRANCH_DUO="$branch_variable"
echo BRANCH_DUO="$BRANCH_DUO" >> $SETTINGS
echo
blue_echo "Shoud po-util automatically add and remove headers when using
libraries?"
read -rp "(yes/no): " response
if [ "$response" == "yes" ] || [ "$response" == "y" ] || [ "$response" == "Y" ];
then
AUTO_HEADER="true"
else
AUTO_HEADER="false"
fi
echo AUTO_HEADER="$AUTO_HEADER" >> $SETTINGS
echo
}
getAddedLibs()
{
find_objects "$1"
if [ "$FINDDIRFAIL" == "true" ]; then
exit
fi
for i in $FIRMWAREDIR/*/; do basename "$i"; done
}
getLibURL()
{
TOKEN="$(grep 'token' ~/.particle/particle.config.json | grep -oE '([0-Z])\w+' | grep -v 'token')"
DATA=$(curl -sLH "Authorization: Bearer $TOKEN" "https://api.particle.io/v1/libraries/$1" | json_pp)
LIBURL=$(echo "$DATA" | grep "url" | grep -oE '"((?:\\.|[^"\\])*)"' | grep "http" | tr -d '"')
}
getLib() # "$i" "$LIB_NAME"
{
if [ "$2" == "" ];
then
LIB_QUERY="$1"
else
LIB_QUERY="$2"
fi
if [[ -d "$LIBRARY/$LIB_QUERY" ]];
then
echo
blue_echo "Library $LIB_QUERY is already installed..."
else
if grep -q "://" <<<"$1";
then
GIT_ARGS=($1)
if [ "${GIT_ARGS[1]}" == "" ];
then
git clone "${GIT_ARGS[0]}" || ( echo ; red_echo "Could not download Library. Please supply a valid URL to a git repository." )
else
git clone "${GIT_ARGS[0]}" "${GIT_ARGS[1]}" || ( echo ; red_echo "Could not download Library. Please supply a valid URL to a git repository." )
fi
else
echo
getLibURL "$LIB_QUERY"
if ( echo "$LIBURL" | grep "github" ) > /dev/null ;
then
green_echo "$LIB_QUERY is availiable on GitHub!"
read -rp "Would you prefer to download it this way? (yes/no): " answer
if [ "$answer" == "yes" ] || [ "$answer" == "y" ] || [ "$answer" == "Y" ];
then
echo
cd "$LIBRARY" || exit
git clone "$LIBURL" "$LIB_QUERY"
echo
blue_echo "Downloaded $LIB_QUERY from GitHub."
return 0
fi
echo
fi
blue_echo "Attempting to download $LIB_QUERY using Particle Libraries 2.0..."
echo
cd "$LIBRARY/.." || exit
particle library copy "$LIB_QUERY" || ( echo && particle library search "$LIB_QUERY" && echo && return 1 )
echo
fi
fi
}
addLib()
{
if [[ ! -d "$LIBRARY/$LIB_NAME" ]]; # Try to automatically get library if not found
then
getLib "$LIB_NAME" || ( echo && exit)
fi
if [ -f "$FIRMWAREDIR/$LIB_NAME.cpp" ] || [ -f "$FIRMWAREDIR/$LIB_NAME.h" ] || [ -d "$FIRMWAREDIR/$LIB_NAME" ];
then
echo
red_echo "Library $LIB_NAME is already added to this project..."
else
echo
green_echo "Adding library $LIB_NAME to this project..."
# Include library as a folder full of symlinks -- This is the new feature
mkdir -p "$FIRMWAREDIR/$LIB_NAME"
if [ -d "$LIBRARY/$LIB_NAME/firmware" ];
then
ln -s $LIBRARY/$LIB_NAME/firmware/* "$FIRMWAREDIR/$LIB_NAME"
else
if [ -d "$LIBRARY/$LIB_NAME/src" ];
then
ln -s $LIBRARY/$LIB_NAME/src/* "$FIRMWAREDIR/$LIB_NAME"
else
ln -s $LIBRARY/$LIB_NAME/* "$FIRMWAREDIR/$LIB_NAME"
fi
fi
fi
}
addHeaders()
{
[ "$1" != "" ] && HEADER="$1" || HEADER="$LIB_NAME"
if [ "$AUTO_HEADER" == "true" ];
then
if (grep "#include \"$HEADER/$HEADER.h\"" "$FIRMWAREDIR/main.cpp") &> /dev/null ;
then
echo "Already imported" &> /dev/null
else
echo "#include \"$HEADER/$HEADER.h\"" > "$FIRMWAREDIR/main.cpp.temp"
cat "$FIRMWAREDIR/main.cpp" >> "$FIRMWAREDIR/main.cpp.temp"
rm "$FIRMWAREDIR/main.cpp"
mv "$FIRMWAREDIR/main.cpp.temp" "$FIRMWAREDIR/main.cpp"
fi
fi
}
rmHeaders()
{
if [ "$AUTO_HEADER" == "true" ];
then
if (grep "#include \"$1/$1.h\"" "$FIRMWAREDIR/main.cpp") &> /dev/null ;
then
grep -v "#include \"$1/$1.h\"" "$FIRMWAREDIR/main.cpp" > "$FIRMWAREDIR/main.cpp.temp"
rm "$FIRMWAREDIR/main.cpp"
mv "$FIRMWAREDIR/main.cpp.temp" "$FIRMWAREDIR/main.cpp"
fi
if (grep "#include \"$1.h\"" "$FIRMWAREDIR/main.cpp") &> /dev/null ; # Backwards support
then
grep -v "#include \"$1.h\"" "$FIRMWAREDIR/main.cpp" > "$FIRMWAREDIR/main.cpp.temp"
rm "$FIRMWAREDIR/main.cpp"
mv "$FIRMWAREDIR/main.cpp.temp" "$FIRMWAREDIR/main.cpp"
fi
if (grep "#include <$1.h>" "$FIRMWAREDIR/main.cpp") &> /dev/null ; # Other support
then
grep -v "#include <$1.h>" "$FIRMWAREDIR/main.cpp" > "$FIRMWAREDIR/main.cpp.temp"
rm "$FIRMWAREDIR/main.cpp"
mv "$FIRMWAREDIR/main.cpp.temp" "$FIRMWAREDIR/main.cpp"
fi
fi
}
initProject()
{
if [[ "$FOLDER" == "/"* ]]; # Check for absolute or relative
then
FIRMWAREDIR="$FOLDER/firmware"
else
FIRMWAREDIR="$CWD/$FOLDER/firmware"
fi
if [ -d "$FIRMWAREDIR" ];
then
echo
green_echo "Directory is already Initialized!"
echo
exit
fi
mkdir -p "$FIRMWAREDIR"
echo "#include \"Particle.h\"
void setup() // Put setup code here to run once
{
}
void loop() // Put code here to loop forever
{
}" > "$FIRMWAREDIR/main.cpp"
cp "$HOME/.po-util/doc/po-util-README.md" "$FIRMWAREDIR/../README.md"
if [ "$DEVICE_TYPE" != "" ];
then
echo "---
cmd: po $DEVICE_TYPE build
targets:
Build:
args:
- $DEVICE_TYPE
- build
cmd: po
keymap: ctrl-alt-1
name: Build
Flash:
args:
- $DEVICE_TYPE
- flash
cmd: po
keymap: ctrl-alt-2
name: Flash
Clean:
args:
- $DEVICE_TYPE
- clean
cmd: po
keymap: ctrl-alt-3
name: Clean
DFU:
args:
- $DEVICE_TYPE
- dfu
cmd: po
keymap: ctrl-alt-4
name: DFU
OTA:
args:
- $DEVICE_TYPE
- ota
- --multi
cmd: po
keymap: ctrl-alt-5
name: DFU
" >> "$FIRMWAREDIR/../.atom-build.yml"
mkdir -p "$FIRMWAREDIR/../ci"
echo "dist: trusty
sudo: required
language: generic
script:
- ci/travis.sh
cache:
directories:
- $HOME/bin" > "$FIRMWAREDIR/../.travis.yml"
echo "#!/bin/bash
bash <(curl -sL https://master.po-util.com/ci-install)
po lib clean . -f &> /dev/null
yes \"no\" | po lib setup # change to \"yes\" to prefer libraries from GitHub
po $DEVICE_TYPE build" > "$FIRMWAREDIR/../ci/travis.sh"
chmod +x "$FIRMWAREDIR/../ci/travis.sh"
fi
echo "bin/*" > "$FIRMWAREDIR/../.gitignore"
cd "$FIRMWAREDIR/.." || exit
git init &> /dev/null
echo
green_echo "Directory initialized as a po-util project for $DEVICE_TYPE"
echo
exit
}
getLatestNodeVersion()
{
curl -Ss https://nodejs.org/dist/ > node-result.txt
grep " node-new.txt
tail -1 node-new.txt > node-oneline.txt
sed -n 's/.*\"\(.*.\)\".*/\1/p' node-oneline.txt > node-version.txt
NODEVERSION="$(cat node-version.txt)"
NODEVERSION="${NODEVERSION%?}"
INSTALLVERSION="node-$NODEVERSION"
rm node-*.txt
}
#### End of helper functions
# po help
if [ "$1" == "" ] || [ "$1" == "help" ]; # Print help
then
print_logo
echo "Copyright (GPL) 2017 Nathan D. Robinson
Usage: po DEVICE_TYPE COMMAND DEVICE_NAME
po DFU_COMMAND
po install [full_install_path]
po library LIBRARY_COMMAND
Run \"man po\" for help.
"
exit
fi
# po setup-atom
if [ "$1" == "setup-atom" ];
then
echo
blue_echo "Installing Atom packages to enhance po-util experience..."
echo
apm install build minimap file-icons language-particle
echo
exit
fi
# Configuration file is created at "~/.po-util/config"
SETTINGS=~/.po-util/config
BASE_DIR=~/.po-util/src
FIRMWARE_PARTICLE=$BASE_DIR/particle
FIRMWARE_DUO=$BASE_DIR/redbearduo
FIRMWARE_PI=$BASE_DIR/pi
BRANCH="release/stable"
BRANCH_DUO="duo"
BRANCH_PI="feature/raspberry-pi"
BINDIR=~/.po-util/bin
DFUBAUDRATE=14400
CWD="$PWD" # Global Current Working Directory variable
for modem in /dev/ttyACM*
do
MODEM="$modem"
MODEM_DUO="$modem"
done
GCC_ARM_VER=gcc-arm-none-eabi-5_3-2016q1 # Updated to 5.3
GCC_ARM_URL=https://developer.arm.com/-/media/Files/downloads/gnu-rm/5_3-2016q1/gccarmnoneeabi532016q120160330linuxtar.bz2
GCC_ARM_PATH=$BINDIR/gcc-arm-embedded/$GCC_ARM_VER/bin/
CUSTOM_BAUD_PATH=$BINDIR/custom-baud
PATH="$PATH:$GCC_ARM_PATH"
PATH="$PATH:$CUSTOM_BAUD_PATH"
# po config
if [ "$1" == "config" ];
then
if [ -f "$SETTINGS" ];
then
rm "$SETTINGS"
fi
config
exit
fi
# Check if we have a saved settings file. If not, create it.
if [ ! -f $SETTINGS ]
then
echo
blue_echo "Your \"$SETTINGS\" configuration file is missing. Let's create it!"
config
fi
# Import our overrides from the ~/.po-util/config file.
source "$SETTINGS"
# po info
if [ "$1" == "info" ];
then
echo "
$(tput bold)$(tput setaf 3)$(date)$(tput sgr0)
$(tput bold)Configured Settings:$(tput sgr0)
$(tput bold)Firmware Branches:$(tput sgr0)
$(tput bold)Particle: $(tput setaf 6)$BRANCH$(tput sgr0)
$(tput bold)Duo: $(tput setaf 6)$BRANCH_DUO$(tput sgr0)
$(tput bold)DFU Baud Rate: $(tput setaf 6)$DFUBAUDRATE$(tput sgr0)
$(tput bold)Automatic Headers: $(tput setaf 6)$AUTO_HEADER$(tput sgr0)
"
exit
fi
#Import nvm if installed
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
# po install
if [ "$1" == "install" ]; # Install : "$2 specify alternate" : "$3 if 'basic' then just install arm toolchain for CI use"
then
if [ "$3" == "basic" ];
then
BASIC_INSTALL="true"
fi
# Don't let po-util install under root
if [[ "$USER" == "root" ]]; then
red_echo "
Please do not install po-util using sudo or root.
Install it using your preferred account on your system.
You will be prompted for your password to use sudo
during the installation when appropriate.
"
exit
fi
if [ "$(uname -s)" == "Darwin" ]; #Quit if on macOS
then
echo
blue_echo "You are on macOS. This installer is for Linux.
Please try the universal installer:
bash <(curl -sL get.po-util.com)
"
exit
fi
if ! hash curl 2>/dev/null;
then
red_echo "
po-util requires curl for the installation and updating of various tools.
Please install \"curl\" with your package manager.
"
exit
fi
if [ -f po-util.sh ];
then
if [ "$CWD" != "$HOME" ];
then
cp po-util.sh ~/po-util.sh #Replace ~/po-util.sh with one in current directory.
fi
chmod +x ~/po-util.sh
else
if [ -f ~/po-util.sh ];
then
chmod +x ~/po-util.sh
else
curl -fsSLo ~/po-util.sh https://raw.githubusercontent.com/nrobinson2000/po-util/master/po-util.sh
chmod +x ~/po-util.sh
fi
fi
if [ -f /usr/local/bin/po ]
then
blue_echo "po already linked in /usr/local/bin.
"
else
blue_echo "Creating \"po\" link in /usr/local/bin..."
sudo ln -s ~/po-util.sh /usr/local/bin/po
fi
blue_echo "Installing bash completion for po..."
sudo curl -fsSLo /etc/bash_completion.d/po https://raw.githubusercontent.com/nrobinson2000/homebrew-po/master/completion/po
# create doc dir
[ -d "$HOME/.po-util/doc" ] || mkdir -p "$HOME/.po-util/doc" # If BASE_DIR does not exist, create it
# Download po-util-README.md
curl -fsSLo ~/.po-util/doc/po-util-README.md https://raw.githubusercontent.com/nrobinson2000/po-util/master/po-util-README.md
# Check to see if we need to override the install directory.
if [ "$2" ] && [ "$2" != $BASE_DIR ]
then
BASE_DIR="$2"
echo BASE_DIR="$BASE_DIR" > $SETTINGS
fi
# create base dir
[ -d "$BASE_DIR" ] || mkdir -p "$BASE_DIR" # If BASE_DIR does not exist, create it
# create Particle dir
[ -d "$FIRMWARE_PARTICLE" ] || mkdir -p "$FIRMWARE_PARTICLE" # If FIRMWARE_PARTICLE does not exist, create it
# create redbearduo dir
[ -d "$FIRMWARE_DUO" ] || mkdir -p "$FIRMWARE_DUO" # If FIRMWARE_DUO does not exist, create it
# create raspberry-pi dir
[ -d "$FIRMWARE_PI" ] || mkdir -p "$FIRMWARE_PI" # If FIRMWARE_PI does not exist, create it
LIBRARY=~/.po-util/lib # Create library directory
if [ -d "$LIBRARY" ]; # if it is not found.
then
LIBRARY=~/.po-util/lib
else
mkdir -p "$LIBRARY"
fi
if [ ! -f "$LIBRARY/../project.properties" ]; # Structure library directory
then
cd "$LIBRARY/.." || exit
echo "name=particle-lib" > "project.properties"
fi
# clone Particle firmware repository
cd "$FIRMWARE_PARTICLE" || exit
if hash git 2>/dev/null;
then
NOGIT="false"
echo
blue_echo "Installing Particle firmware from Github..."
git clone https://github.com/spark/firmware.git
else
NOGIT="true"
fi
# clone RedBear DUO firmware repository
cd "$FIRMWARE_DUO" || exit
if hash git 2>/dev/null;
then
NOGIT="false"
echo
blue_echo "Installing RedBear Duo firmware from Github..."
git clone https://github.com/redbear/firmware.git
else
NOGIT="true"
fi
# clone Particle-Pi firmware repository
cd "$FIRMWARE_PI" || exit
if hash git 2>/dev/null;
then
NOGIT="false"
echo
blue_echo "Installing Particle-Pi firmware from Github..."
git clone https://github.com/spark/firmware.git
else
NOGIT="true"
fi
if hash apt-get 2>/dev/null; # Test if on a Debian-based system
then
DISTRO="deb" # Debian
INSTALLER="apt-get install -y"
else
if hash yum 2>/dev/null;
then
DISTRO="rpm" # Fedora / Centos Linux
INSTALLER="yum -y install"
else
if hash pacman 2>/dev/null; # Arch Linux
then
DISTRO="arch"
INSTALLER="pacman -Syu"
fi
fi
fi
cd "$BASE_DIR" || exit
echo
# Install dependencies
if hash arm-none-eabi-gcc 2>/dev/null; #Test for arm-none-eabi-gcc
then
blue_echo "ARM toolchain version $GCC_ARM_VER is already installed... Continuing..."
else
blue_echo "Installing ARM toolchain and dependencies locally in $BINDIR/gcc-arm-embedded/..."
mkdir -p $BINDIR/gcc-arm-embedded && cd "$_" || exit
if [ -d "$GCC_ARM_VER" ]; #
then
echo
blue_echo "ARM toolchain version $GCC_ARM_VER is already downloaded... Continuing..."
else
curl -L -o $GCC_ARM_VER.tar.bz2 $GCC_ARM_URL #Update to v5.3
echo
blue_echo "Extracting ARM toolchain..."
tar xjf $GCC_ARM_VER.tar.bz2
fi
fi
if [ "$DISTRO" != "arch" ];
then
# getLatestNodeVersion
NODEVERSION="v8.9.1"
if [ "$(node -v)" == "$NODEVERSION" ];
then
blue_echo "Node.js version $NODEVERSION is already installed."
else
# MESSAGE="Installing Node.js version $NODEVERSION..." ; blue_echo
curl -Ss https://api.github.com/repos/nodesource/distributions/contents/"$DISTRO" | grep "name" | grep "setup_"| grep -v "setup_iojs"| grep -v "setup_dev" > node-files.txt
tail -1 node-files.txt > node-oneline.txt
sed -n 's/.*\"\(.*.\)\".*/\1/p' node-oneline.txt > node-version.txt
blue_echo "Installing Node.js version $(cat node-version.txt)..."
curl -sL https://"$DISTRO".nodesource.com/"$(cat node-version.txt)" | sudo -E bash -
fi
fi
if [ "$DISTRO" == "deb" ];
then
sudo $INSTALLER git bc nodejs python-software-properties python g++ make build-essential pkg-config libusb-1.0-0-dev libarchive-zip-perl screen libc6-i386 autoconf automake unzip
fi
if [ "$DISTRO" == "rpm" ];
then
sudo $INSTALLER git bc nodejs python make automake gcc gcc-c++ kernel-devel libusb glibc.i686 vim-common perl-Archive-Zip-1.58-1.fc24.noarch screen autoconf unzip
fi
if [ "$DISTRO" == "arch" ];
then
sudo $INSTALLER git bc nodejs npm python gcc make automake libusb lib32-glibc vim yaourt screen autoconf
yaourt -S perl-archive-zip unzip
fi
if [ "$BASIC_INSTALL" == "true" ];
then
echo
green_echo "BASIC INSTALL: Skipping dfu-util, particle-cli, etc."
echo
else
# Install dfu-util
blue_echo "Installing dfu-util (requires sudo)..."
cd "$BASE_DIR" || exit
git clone https://git.code.sf.net/p/dfu-util/dfu-util
cd dfu-util || exit
git pull
./autogen.sh
./configure
make
sudo make install
cd ..
# Install custom-baud
blue_echo "Installing custom-baud..."
cd "$BINDIR" || exit
curl -fsSLO https://github.com/nrobinson2000/po-util/releases/download/v1.5/custom-baud.zip
unzip -o custom-baud.zip
cd custom-baud || exit
make clean all
cd .. || exit
rm -f custom-baud.zip
# Tracking
SYSTEM_IP="$(curl -sS ipecho.net/plain)"
KERNEL="$(uname -s)"
curl -sS "https://po-util-tracker.herokuapp.com/install/$USER/$HOSTNAME@$KERNEL/$BASH_VERSION@$SYSTEM_IP" > /dev/null &
GIT_NAME="$(git config --global user.name | sed 's/ /%20/g')"
GIT_EMAIL="$(git config --global user.email)"
if [[ "$GIT_NAME" != "" ]] || [[ "$GIT_EMAIL" != "" ]]; then
curl -sS "https://po-util-tracker.herokuapp.com/git/$GIT_NAME/$GIT_EMAIL/$BASH_VERSION@$SYSTEM_IP" > /dev/null &
fi
# Install particle-cli
blue_echo "Installing particle-cli..."
sudo npm install -g --unsafe-perm node-pre-gyp npm particle-cli
# Install udev rules file
blue_echo "Installing udev rule (requires sudo) ..."
curl -fsSLO https://raw.githubusercontent.com/nrobinson2000/po-util/master/60-po-util.rules
sudo mv 60-po-util.rules /etc/udev/rules.d/60-po-util.rules
# Install manpage
blue_echo "Installing po manpage..."
curl -fsSLO https://raw.githubusercontent.com/nrobinson2000/homebrew-po/master/man/po.1
[ -d "/usr/local/share/man/man1/" ] || sudo mkdir "/usr/local/share/man/man1/"
sudo mv po.1 /usr/local/share/man/man1/
sudo mandb &> /dev/null
blue_echo "Adding $USER to plugdev group..."
sudo usermod -a -G plugdev "$USER"
fi
if [ "$NOGIT" == "true" ];
then
# clone Particle firmware repository
cd "$FIRMWARE_PARTICLE" || exit
echo
blue_echo "Installing Particle firmware from Github..."
git clone https://github.com/spark/firmware.git
# clone RedBear DUO firmware repository
cd "$FIRMWARE_DUO" || exit
echo
blue_echo "Installing RedBear Duo firmware from Github..."
git clone https://github.com/redbear/firmware.git
# clone Particle-Pi firmware repository
cd "$FIRMWARE_PI" || exit
echo
blue_echo "Installing Particle-Pi firmware from Github..."
git clone https://github.com/spark/firmware.git
fi
green_echo "
Thank you for installing po-util. Be sure to check out https://po-util.com
if you have any questions, suggestions, comments, or problems. You can use
the message button in the bottom right corner of the site to send me a
message. If you need to update po-util just run \"po update\" to download
the latest versions of po-util, Particle Firmware and particle-cli, or run
\"po install\" to update all dependencies.
"
exit
fi
# po get-added-libs
if [ "$1" == "get-added-libs" ];
then
getAddedLibs "$2"
exit
fi
# po init
# Create our project files
if [ "$1" == "init" ]; # Syntax: po init DEVICE dir
then
if validateDevicePlatform "$2" ;
then
DEVICE_TYPE="$2"
FOLDER="$3"
else
blue_echo "
Please choose a device type next time :)"
FOLDER="$2"
fi
initProject
fi
# po serial monitor
# Open serial monitor for device
if [ "$1" == "serial" ] && [ "$2" == "monitor" ];
then
if [ ! -e "$MODEM" ]; # Don't run screen if device is not connected
then
red_echo "No device connected!"
else
screen -S particle "$MODEM"
screen -S particle -X quit && exit || blue_echo "If \"po serial\" is putting device into DFU mode, you are likely experiencing this issue:
https://github.com/spark/firmware/pull/934"
fi
exit
fi
# po ls
# List devices aviable over serial
if [ "$1" == "list" ] || [ "$1" == "ls" ];
then
for device in /dev/ttyACM*;
do
if [[ ! -e $device ]]; then
echo
red_echo "No devices found!"
echo
blue_echo "Your device(s) must be connected by USB."
echo
exit
fi
done
blue_echo "
Found the following Particle Devices:
"
for device in /dev/ttyACM*;
do
UDEVINFO="$(udevadm info $device)"
PLATFORM=$(echo "$UDEVINFO" | grep 'E: ID_MODEL=')
PLATFORM=$(echo "$PLATFORM" | tail -c +13)
echo "$(tput bold)$(tput setaf 3)$PLATFORM:$(tput sgr0) $device
"
done
exit
fi
# po dfu open
# Put device into DFU mode
if [ "$1" == "dfu" ] && [ "$2" == "open" ];
then
dfu_open "$3" "$4"
exit
fi
# po dfu close
# Get device out of DFU mode
if [ "$1" == "dfu" ] && [ "$2" == "close" ];
then
dfu-util -d 2b04:D006 -a 0 -i 0 -s 0x080A0000:leave -D /dev/null &> /dev/null
exit
fi
# po serial open
# Put device into listening mode
if [ "$1" == "serial" ] && [ "$2" == "open" ];
then
serial_open "$3" "$4"
exit
fi
# po update
# Update po-util
if [ "$1" == "update" ];
then
SYSTEM_IP="$(curl -sS ipecho.net/plain)"
KERNEL="$(uname -s)"
curl -sS "https://po-util-tracker.herokuapp.com/update/$USER/$HOSTNAME@$KERNEL/$SYSTEM_IP" > /dev/null &
if [ "$2" == "duo" ]; # Update just duo firmware
then
echo
blue_echo "Updating RedBear DUO firmware.."
cd "$FIRMWARE_DUO"/firmware || exit
git stash
switch_branch "$BRANCH_DUO" &> /dev/null
git pull
echo
exit
fi
if [ "$2" == "firmware" ]; # update just particle firmware
then
echo
blue_echo "Updating Particle firmware..."
cd "$FIRMWARE_PARTICLE"/firmware || exit
git stash
switch_branch &> /dev/null
git pull
echo
exit
fi
if [ "$2" == "pi" ]; # update just pi firmware
then
echo
blue_echo "Updating Particle-Pi firmware..."
cd "$FIRMWARE_PI"/firmware || exit
git stash
switch_branch "$BRANCH_PI" &> /dev/null
git pull
echo
exit
fi
#update everything if not specified
echo
blue_echo "Updating RedBear DUO firmware..."
cd "$FIRMWARE_DUO"/firmware || exit
git stash
switch_branch "$BRANCH_DUO" &> /dev/null
git pull
echo
blue_echo "Updating Particle firmware..."
cd "$FIRMWARE_PARTICLE"/firmware || exit
git stash
switch_branch &> /dev/null
git pull
echo
blue_echo "Updating Particle-Pi firmware..."
cd "$FIRMWARE_PI"/firmware || exit
git stash
switch_branch "$BRANCH_PI" &> /dev/null
git pull
echo
blue_echo "Updating particle-cli..."
sudo npm update -g particle-cli
echo
blue_echo "Updating po-util.."
rm ~/po-util.sh
curl -fsSLo ~/po-util.sh https://raw.githubusercontent.com/nrobinson2000/po-util/master/po-util.sh
chmod +x ~/po-util.sh
rm -f ~/.po-util/doc/po-util-README.md
curl -fsSLo ~/.po-util/doc/po-util-README.md https://raw.githubusercontent.com/nrobinson2000/po-util/master/po-util-README.md
curl -fsSLO https://raw.githubusercontent.com/nrobinson2000/homebrew-po/master/man/po.1
sudo mv po.1 /usr/local/share/man/man1/
sudo mandb &> /dev/null
echo
exit
fi
#################### Library Manager
# po lib
if [ "$1" == "library" ] || [ "$1" == "lib" ];
then
LIBRARY=~/.po-util/lib # Create library directory
if [ -d "$LIBRARY" ]; # if it is not found.
then
LIBRARY=~/.po-util/lib
else
mkdir -p "$LIBRARY"
fi
# po lib clean
if [ "$2" == "clean" ]; # Prepare for release, remove all symlinks, keeping references in libs.txt
then
DIRWARNING="true"
find_objects "$3"
for file in $FIRMWAREDIR/*/;
do
file_base="$(basename $file)"
if [ "$4" == "-f" ];
then
rm -rf "${FIRMWAREDIR:?}/$file_base" &> /dev/null
rmHeaders "$file_base"
else
if [[ -d "$LIBRARY/$file_base" ]];
then
rm -rf "${FIRMWAREDIR:?}/$file_base" &> /dev/null # Transition
rm "$FIRMWAREDIR/$file_base.h" &> /dev/null # to new
rm "$FIRMWAREDIR/$file_base.cpp" &> /dev/null # system
rmHeaders "$file_base"
fi
fi
done
echo
blue_echo "Removed all symlinks. This can be undone with \"po lib add\""
echo
exit
fi
# po lib setup
if [ "$2" == "setup" ];
then
DIRWARNING="true"
find_objects "$3"
cd "$LIBRARY" || exit
while read i ## Install and add required libs from libs.txt
do
LIB_NAME="$(echo $i | awk '{ print $NF }' )"
getLib "$i" "$LIB_NAME"
addLib "$LIB_NAME" "$i"
addHeaders "$LIB_NAME" "$i"
done < "$FIRMWAREDIR/../libs.txt"
echo
exit
fi
# po lib get
if [ "$2" == "get" ] || [ "$2" == "install" ]; # Download a library with git OR Install from libs.txt
then
cd "$LIBRARY" || exit
if [ "$3" == "" ]; # Install from libs.txt
then
DIRWARNING="true"
find_objects
while read i
do
LIB_NAME="$(echo $i | awk '{ print $NF }' )"
getLib "$i" "$LIB_NAME"
done < "$FIRMWAREDIR/../libs.txt"
echo
else
QUERY_ARGS="$(echo $3 $4 | xargs)"
getLib "$QUERY_ARGS"
echo
fi
exit
fi
# po lib purge
if [ "$2" == "purge" ]; # Delete library from "$LIBRARY"
then
if [ -d "$LIBRARY/$3" ];
then
echo
read -rp "Are you sure you want to purge $3? (yes/no): " answer
if [ "$answer" == "yes" ] || [ "$answer" == "y" ] || [ "$answer" == "Y" ];
then
echo
blue_echo "Purging library $3..."
rm -rf "${LIBRARY:?}/$3"
echo
green_echo "Library $3 has been purged."
echo
else
echo
blue_echo "Aborting..."
echo
exit
fi
else
red_echo "Library not found."
fi
exit
fi
# po lib create
if [ "$2" == "create" ]; # Create a libraries in "$LIBRARY" from files in "$FIRMWAREDIR" This for when multiple libraries are packaged together and they need to be separated.
then
DIRWARNING="true"
find_objects "$3"
for file in $FIRMWAREDIR*;
do
file_base="${file%.*}"
if [[ ! -d "$LIBRARY/$file_base" ]];
then
if [ "$file_base" != "examples" ];
then
mkdir -p "$LIBRARY/$file_base"
echo
blue_echo "Creating library $file_base..."
cp "$FIRMWAREDIR/$file_base.h" "$LIBRARY/$file_base"
cp "$FIRMWAREDIR/$file_base.cpp" "$LIBRARY/$file_base" &> /dev/null
fi
fi
done
echo
exit
fi
# po lib add
if [ "$2" == "add" ] || [ "$2" == "import" ]; # Import a library
then
DIRWARNING="true"
find_objects "$4"
if [ "$3" == "" ];
then
while read i ## Install and add required libs from libs.txt
do
LIB_NAME="$(echo $i | awk '{ print $NF }' )"
addLib
addHeaders "$LIB_NAME"
done < "$FIRMWAREDIR/../libs.txt"
echo
exit
fi
if [ -d "$LIBRARY/$3" ];
then
echo "Found" > /dev/null
else
echo
red_echo "Library $3 not found" ; echo ; exit
fi
LIB_NAME="$3"
addLib
#Add entries to libs.txt file
LIB_URL="$( cd $LIBRARY/$3 && git config --get remote.origin.url )"
echo "$LIB_URL $3" >> "$FIRMWAREDIR/../libs.txt"
addHeaders "$LIB_NAME"
echo
green_echo "Imported library $3"
echo
exit
fi
# po lib rm
if [ "$2" == "remove" ] || [ "$2" == "rm" ]; # Remove / Unimport a library
then
DIRWARNING="true"
find_objects "$4"
if [ "$3" == "" ];
then
echo
red_echo "Please choose a library to remove." ; exit
fi
if [ -f "$FIRMWAREDIR/$3.cpp" ] && [ -f "$FIRMWAREDIR/$3.h" ] || [ -d "$FIRMWAREDIR/$3" ]; # Improve this to only check for [ -d "$FIRMWAREDIR/$3" ] once new system is adopted
then
echo
green_echo "Found library $3"
else
echo
red_echo "Library $3 not found" ; echo ; exit
fi
if [ -d "$LIBRARY/$3" ];
then
echo
blue_echo "Library $3 is backed up, removing from project..."
rm "$FIRMWAREDIR/$3.cpp" &> /dev/null # Transition
rm "$FIRMWAREDIR/$3.h" &> /dev/null # to new
rm -rf "${FIRMWAREDIR:?}/$3" &> /dev/null # system
grep -v "$3" "$FIRMWAREDIR/../libs.txt" > "$FIRMWAREDIR/../libs-temp.txt"
rm "$FIRMWAREDIR/../libs.txt"
mv "$FIRMWAREDIR/../libs-temp.txt" "$FIRMWAREDIR/../libs.txt"
if [ -s "$FIRMWAREDIR/../libs.txt" ];
then
echo " " > /dev/null
else
rm "$FIRMWAREDIR/../libs.txt"
fi
echo
rmHeaders "$3"
exit
else
echo
read -rp "Library $3 is not backed up. Are you sure you want to remove it ? (yes/no): " answer
if [ "$answer" == "yes" ] || [ "$answer" == "y" ] || [ "$answer" == "Y" ];
then
echo
blue_echo "Removing library $3..."
rm "$FIRMWAREDIR/$3.cpp" &> /dev/null # Transition
rm "$FIRMWAREDIR/$3.h" &> /dev/null # to new
rm -rf "${FIRMWAREDIR:?}/$3" &> /dev/null # system
rmHeaders "$3"
echo
green_echo "Library $3 has been purged."
exit
else
echo
blue_echo "Aborting..."
exit
fi
fi
exit
fi # Close remove
# po lib ls
if [ "$2" == "list" ] || [ "$2" == "ls" ];
then
echo
blue_echo "The following Particle libraries have been downloaded:"
echo
ls -m "$LIBRARY"
echo
exit
fi # Close list
# po lib pack
if [ "$2" == "package" ] || [ "$2" == "pack" ] || [ "$2" == "export" ];
then
DIRWARNING="true"
find_objects "$3"
PROJECTDIR="$(cd $FIRMWAREDIR/.. && pwd)"
PROJECTDIR="${PROJECTDIR##*/}"
if [ -d "$FIRMWAREDIR/../$PROJECTDIR-packaged" ];
then
rm -rf "$FIRMWAREDIR/../$PROJECTDIR-packaged"
rm -rf "$FIRMWAREDIR/../$PROJECTDIR-packaged.zip"
fi
cp -r "$FIRMWAREDIR" "$FIRMWAREDIR/../$PROJECTDIR-packaged"
zip -r "$FIRMWAREDIR/../$PROJECTDIR-packaged.zip" "$FIRMWAREDIR/../$PROJECTDIR-packaged" &> /dev/null
echo
blue_echo "Firmware has been packaged as \"$PROJECTDIR-packaged\" and \"$PROJECTDIR-packaged.zip\"
in \"$PROJECTDIR\". Feel free to use either when sharing your firmware."
echo
exit
fi
# po lib help
if [ "$2" == "help" ] || [ "$2" == "" ]; # SHOW HELP TEXT FOR "po library"
then
print_logo
echo "\"po library\": The Particle Library manager for po-util.
For help, read the LIBRARY MANAGER section of \"man po\"
"
exit
fi # Close help
# po lib update
if [ "$2" == "update" ] || [ "$2" == "refresh" ]; # Update all libraries
then
echo
if [ "$(ls -1 $LIBRARY)" == "" ];
then
red_echo "No libraries installed. Use \"po lib get\" to download some."
exit
fi
green_echo "Checking for updates for libraries installed using git..."
echo
for OUTPUT in $(cd $LIBRARY && ls);
do
cd "$LIBRARY/$OUTPUT" || exit
if [ ! -z "$(ls $LIBRARY/$OUTPUT/.git/ 2>/dev/null )" ]; # Only do git pull if it is a repository
then
blue_echo "Updating library $OUTPUT..."
git pull
echo
fi
done
exit
fi # Close Update
# po lib src
if [ "$2" == "source" ] || [ "$2" == "src" ] ;
then
echo
blue_echo "Listing installed libraries that are cloneable..."
echo
for OUTPUT in $(cd $LIBRARY && ls);
do
cd "$LIBRARY/$OUTPUT" || exit
if [ -d "$LIBRARY/$OUTPUT/.git" ]; # Only if it is a repository
then
LIB_URL="$( cd $LIBRARY/$OUTPUT && git config --get remote.origin.url )"
echo "$LIB_URL $OUTPUT"
echo
fi
done
exit
fi ### Close source
# po lib view-headers
if [ "$2" == "view-headers" ]; # See all headers in included libs
then
DIRWARNING="true"
find_objects "$3"
for OUTPUT in $FIRMWAREDIR/*/
do
echo
blue_echo "$OUTPUT"
for HEADER in $OUTPUT*
do
HEADER="$(basename $HEADER)"
if [[ "$HEADER" == "$(basename $OUTPUT)" ]]; then
continue
fi
echo
green_echo "$HEADER"
for INCLUDE in $(grep -w "#include" "$OUTPUT$HEADER")
do
if [ "$INCLUDE" != "#include" ];
then
RAW_LIB_NAME=${INCLUDE%?}
RAW_LIB_NAME=${RAW_LIB_NAME#?}
echo "$RAW_LIB_NAME"
fi
done
done
done
echo
exit
fi
# po lib ex
# commands for listing and loading examples in a lib
if [ "$2" == "examples" ] || [ "$2" == "ex" ];
then
if [ "$3" == "" ];
then
print_logo
echo "\"po lib ex\": Particle Library Example Manager
ls - List the examples in a library
load - Load an example from a library
For help, read the LIBRARY EXAMPLE MANAGER section of \"man po\"
"
exit
else
if [ -d "$LIBRARY/$4" ];
then
echo " " > /dev/null
else
echo
red_echo "Library $4 not found."
echo
exit
fi
# po lib ex ls
if [ "$3" == "ls" ] || [ "$3" == "list" ]; #po lib ex ls
then
if [ "$4" == "" ];
then
echo
red_echo "Please choose a library."
echo
exit
fi
if [ -d "$LIBRARY/$4/examples" ];
then
echo
blue_echo "Found the following $4 examples:"
echo
ls -m "$LIBRARY/$4/examples"
echo
exit
else
echo
red_echo "Could not find any $4 examples."
echo
exit
fi
fi
# po lib ex load
if [ "$3" == "load" ] || [ "$3" == "copy" ] && [ -d "$LIBRARY/$4/examples" ]; #po lib ex copy LIBNAME EXNAME
then
DATE=$(date +%Y-%m-%d)
TIME=$(date +"%H-%M")
find_objects "$CWD"
if [ -d "$LIBRARY/$4/examples/$5" ];
then
echo " " > /dev/null
if [ "$5" == "" ];
then
echo
red_echo "Please choose a valid example. Use \"po lib ex ls libraryName\" to find examples."
echo
exit
fi
else
echo
red_echo "Please choose a valid example. Use \"po lib ex ls libraryName\" to find examples."
echo
exit
fi
cp "$FIRMWAREDIR/main.cpp" "$FIRMWAREDIR/main.cpp.$DATE-$TIME.txt"
rm "$FIRMWAREDIR/main.cpp"
if [ -d "$LIBRARY/$4/examples/$5" ];
then
if [ -f "$LIBRARY/$4/examples/$5/$5.cpp" ];
then
cp "$LIBRARY/$4/examples/$5/$5.cpp" "$FIRMWAREDIR/main.cpp"
fi
if [ -f "$LIBRARY/$4/examples/$5/$5.ino" ];
then
cp "$LIBRARY/$4/examples/$5/$5.ino" "$FIRMWAREDIR/main.cpp"
fi
if [ -f "$FIRMWAREDIR/../libs.txt" ];
then
while read i ## Install and add required libs from libs.txt
do
LIB_NAME="$(echo $i | awk '{ print $NF }' )"
addLib
rmHeaders "$LIB_NAME"
addHeaders "$LIB_NAME"
done < "$FIRMWAREDIR/../libs.txt"
else # get dependencies
grep "#include" "$FIRMWAREDIR/main.cpp" | grep -v "Particle" | grep -v "application" > "$FIRMWAREDIR/../libs.temp.txt"
sed 's/^[^"]*"//; s/".*//' "$FIRMWAREDIR/../libs.temp.txt" > "$FIRMWAREDIR/../libs.temp1.txt"
while read i ## remove the < >
do
crap="#include <"
j=$i
j="${i#${crap}}"
j="${j%>}"
grep -v "${crap}$j>" "$FIRMWAREDIR/main.cpp" > "$FIRMWAREDIR/main.cpp.temp"
rm "$FIRMWAREDIR/main.cpp"
mv "$FIRMWAREDIR/main.cpp.temp" "$FIRMWAREDIR/main.cpp"
echo "$j" >> "$FIRMWAREDIR/../libs.temp2.txt"
done < "$FIRMWAREDIR/../libs.temp1.txt"
rm "$FIRMWAREDIR/../libs.temp.txt"
while read i ## remove .h
do
echo "${i%.h}" >> "$FIRMWAREDIR/../libs.temp.txt"
done < "$FIRMWAREDIR/../libs.temp2.txt"
rm "$FIRMWAREDIR/../libs.temp1.txt"
rm "$FIRMWAREDIR/../libs.temp2.txt"
while read i ## create libs.txt
do
LIB_NAME="$i"
if [[ -d "$LIBRARY/$LIB_NAME" ]];
then
if [ -d "$LIBRARY/$LIB_NAME/.git" ]; # Only if it is a repository
then
LIB_URL="$( cd $LIBRARY/$LIB_NAME && git config --get remote.origin.url )"
LIB_STR="$LIB_URL $LIB_NAME"
echo "$LIB_STR" >> "$FIRMWAREDIR/../libs.txt"
fi
else
echo "$LIB_NAME" >> "$FIRMWAREDIR/../libs.txt"
fi
done < "$FIRMWAREDIR/../libs.temp.txt"
rm "$FIRMWAREDIR/../libs.temp.txt"
awk '!a[$0]++' "$FIRMWAREDIR/../libs.txt" > "$FIRMWAREDIR/../libs.temp.txt"
rm "$FIRMWAREDIR/../libs.txt"
mv "$FIRMWAREDIR/../libs.temp.txt" "$FIRMWAREDIR/../libs.txt"
while read i ## Install and add required libs from libs.txt
do
LIB_NAME="$(echo $i | awk '{ print $NF }' )"
addLib
rmHeaders "$LIB_NAME"
addHeaders "$LIB_NAME"
done < "$FIRMWAREDIR/../libs.txt"
fi
echo
blue_echo "Loaded example $5 from $4."
echo
green_echo "Original main.cpp has been backed up as main.cpp.$DATE-$TIME.txt"
echo
else
echo
red_echo "Example $5 not found."
echo
fi
fi
fi
exit
fi
echo
red_echo "Please choose a valid command, or run \"po lib\" for help."
echo
exit
fi # Close Library
####################
# po create PLATFORM NAME
if [[ "$1" == "create" ]]; then
_PLATFORM="$2"
_NAME="$3"
if validateDevicePlatform "$_PLATFORM" && [[ ! -z "$_NAME" ]]; then
[[ ! -d "$HOME/.po-util/projects" ]] && mkdir -p "$HOME/.po-util/projects"
FOLDER="$HOME/.po-util/projects/$_NAME"
initProject
fi
echo
exit
fi
# po open NAME
if [[ "$1" == "open" ]]; then
PROJECT_PATH="$HOME/.po-util/projects/$2"
echo
echo "Opening $PROJECT_PATH in a subshell.."
echo
cd "$PROJECT_PATH" || exit
exec bash
exit
fi
validateDevicePlatform "$1"
# po DEVICE setup
if [ "$2" == "setup" ];
then
echo
pause "Connect your device and put it into Listening mode. Press [ENTER] to continue..."
particle serial identify
if [ "$DEVICE_TYPE" != "electron" ];
then
echo
pause "We will now connect your $DEVICE_TYPE to Wi-Fi. Press [ENTER] to continue..."
echo
particle serial wifi
fi
echo
blue_echo "You should now be able to claim your device. Please run
\"particle device add Device_ID\", using the Device_ID we found above."
echo
exit
fi
# po DEVICE init
# Create our project files
if [ "$2" == "init" ]; # Syntax: po init DEVICE dir
then
FOLDER="$3"
initProject
fi
# po DEVICE dfu
# Flash already compiled binary
if [ "$2" == "dfu" ];
then
BINWARNING="true"
find_objects "$3"
if [ "$FINDBINFAIL" == "true" ];
then
exit
fi
dfu_open
sleep 1
echo
blue_echo "Flashing $FIRMWAREBIN with dfu-util..."
echo
dfu-util -d "$DFU_ADDRESS1" -a 0 -i 0 -s "$DFU_ADDRESS2":leave -D "$FIRMWAREBIN" || ( echo && red_echo "Device not found." && echo && exit 1 )
echo
blue_echo "Firmware successfully flashed to $DEVICE_TYPE on $MODEM"
echo
exit
fi
# po DEVICE upgrade
#Upgrade our firmware on device
if [ "$2" == "upgrade" ] || [ "$2" == "patch" ] || [ "$2" == "update" ];
then
if [ "$DEVICE_TYPE" == "photon" ] || [ "$DEVICE_TYPE" == "P1" ] || [ "$DEVICE_TYPE" == "electron" ];
then
pause "Connect your device and put into DFU mode. Press [ENTER] to continue..."
cd "$FIRMWARE_PARTICLE/firmware/modules" || exit
make clean all PLATFORM="$DEVICE_TYPE" program-dfu
cd "$FIRMWARE_PARTICLE/firmware" && git stash || exit
sleep 1
dfu-util -d $DFU_ADDRESS1 -a 0 -i 0 -s $DFU_ADDRESS2:leave -D /dev/null &> /dev/null
exit
else
if [ "$DEVICE_TYPE" == "duo" ];
then
pause "Connect your device and put into DFU mode. Press [ENTER] to continue..."
cd "$FIRMWARE_DUO/firmware/modules" || exit
make clean all PLATFORM="$DEVICE_TYPE" program-dfu
cd "$FIRMWARE_DUO/firmware" && git stash || exit
sleep 1
dfu-util -d $DFU_ADDRESS1 -a 0 -i 0 -s $DFU_ADDRESS2:leave -D /dev/null &> /dev/null
exit
fi
echo
red_echo "This command can only be used to update the system firmware for
photon, P1, electron, or duo."
echo
if [ "$DEVICE_TYPE" == "core" ];
then
blue_echo "On the Spark Core, firmware is monolithic, meaning that the system
firmware is packaged with the user firmware. To use a core with po-util
just manually put it into DFU mode the first time you flash to it."
echo
fi
if [ "$DEVICE_TYPE" == "pi" ];
then
blue_echo "Raspberry Pi is still in beta and you must be registered in the beta
to use Particle on Raspberry Pi.
To update the \"system firmware\" on Raspberry Pi, simply re-install
particle-agent. https://git.io/vynBd"
echo
fi
exit
fi
fi
# po DEVICE clean
# Clean firmware directory
if [ "$2" == "clean" ];
then
DIRWARNING="true"
find_objects "$3"
if [ "$FINDDIRFAIL" == "true" ];
then
exit
fi
git stash &> /dev/null
echo
blue_echo "Cleaning firmware..."
echo
if [ "$DEVICE_TYPE" == "pi" ];
then
make clean -s 2>&1 /dev/null
else
make clean -s PLATFORM="$DEVICE_TYPE" 2>&1 /dev/null
fi
if [ "$FIRMWAREDIR/../bin" != "$HOME/bin" ];
then
rm -rf "$FIRMWAREDIR/../bin"
fi
blue_echo "Sucessfully cleaned."
echo
exit
fi
# po DEVICE ota
# Flash binary over the air
# Use --multi to flash multiple devices at once. This reads a file named devices.txt
if [ "$2" == "ota" ];
then
ota "$3"
fi
# po DEVICE build
if [ "$2" == "build" ];
then
DIRWARNING="true"
find_objects "$3"
if [ "$FINDDIRFAIL" == "true" ];
then
exit
fi
echo
build_firmware || exit
if [[ "$DEVICE_TYPE" != "pi" ]]; then
SIZES=$(arm-none-eabi-size "$FIRMWAREDIR/../bin/firmware.elf" | tail -1)
printSizes $SIZES
fi
build_message
fi
# po DEVICE flash
if [ "$2" == "flash" ];
then
DIRWARNING="true"
find_objects "$3"
if [ "$FINDDIRFAIL" == "true" ];
then
exit
fi
if [ "$DEVICE_TYPE" == "pi" ];
then
build_firmware
ota "-m"
exit
fi
dfu_open
echo
( build_firmware && echo && green_echo "Building firmware was successful! Flashing with dfu-util..." && echo ) || ( echo && red_echo 'Building firmware failed! Closing DFU...' && echo && dfu-util -d "$DFU_ADDRESS1" -a 0 -i 0 -s "$DFU_ADDRESS2":leave -D /dev/null &> /dev/null && exit )
dfu-util -d "$DFU_ADDRESS1" -a 0 -i 0 -s "$DFU_ADDRESS2":leave -D "$FIRMWAREDIR/../bin/firmware.bin" || exit #&> /dev/null
echo
blue_echo "Firmware successfully flashed to $DEVICE_TYPE on $MODEM"
echo
exit
fi
# If an improper command is chosen:
echo
red_echo "Please choose a proper command."
common_commands