#!/bin/bash
#********************************************************************
# Description: hal_demo
#
# This script is used to test/demo the Hardware Abstraction Layer
#
# There are actually a number of demos, and right now they may
# change frequently.  To avoid cluttering up the scripts directory,
# this file contains all the demos.  Select the one you want by
# giving an argument.  For example, "hal_demo jogwheel" will run
# the jogwheel demo.
#
# if you don't specify a demo, this prints a usage message
#
# Author:
# License: GPL Version 2
# System: Linux
#    
# Copyright (c) 2004-2009 All rights reserved.
#*******************************************************************/
if [ ! $1 ] ; then
    echo "Usage:  scripts/hal_demo <demo_name>"
    echo "Run from the emc2 directory only"
    # print the list of demos
    scripts/hal_demo list
    exit 0
fi
#
# the first demo isn't a real demo - it simply lists all the demos
#
if [ $1 = list ] ; then
    echo "Available demos are:"
    echo "  list - prints this list"
    echo "  load - loads hal core modules"
    echo "  unload - unloads hal code modules"
    echo "  parport1 - an introductory demo - step by step"
    echo "  siggen - another introductory demo - signal generator"
    echo "  scope - simple demo of halscope"
    exit 0
fi
#
# The next two demos aren't really demos either - they simply
# load or unload the rtapi enviroment
#
# here is the "load" command
#
if [ $1 = load ] ; then
    # load the rtos and rtapi
    if ! scripts/realtime start ; then
        exit -1
    fi
    # done
    echo "RTAPI core loaded"
    exit 0
fi
#
# here is the "unload" command
#
if [ $1 = unload ] ; then
    # unload any left-over modules
    bin/halcmd unloadrt all
    # unload the rtos and rtapi
    if ! scripts/realtime stop ; then
        exit -1
    fi
    # done
    echo "RTAPI core unloaded"
    exit 0
fi
#
# We're almost ready for the real demos, first we must
# make sure the rtapi core is loaded
#
HAL_LIB_STR=`/sbin/lsmod | awk '{print $1}' | grep -x hal_lib `
if [ ! "$HAL_LIB_STR" ] ; then
    echo "All of the demos require the RTAPI and HAL_LIB modules"
    echo "to be loaded.  Use 'hal_demo load' to load them."
    exit -1
fi
#
# The first demo: "parport1" simply tests the parallel port
# this one is a step by step, tutorial/intro to HAL concepts
#
if [ $1 = parport1 ] ; then
    echo "(Comments that are part of the demo are in parenthesis.)"
    echo "(This demo echos its commands to the screen so you can"
    echo " see what each step does.  Echoed commands start with '$')"
    echo "Hit enter to install the parport module"
    read
    # change the 0278 if your port is at a different address
    echo "$ bin/halcmd loadrt hal_parport cfg=\"0278\""
    bin/halcmd loadrt hal_parport cfg="0278"
    echo "Hit enter see the component list"
    read
    echo "$ bin/halcmd show comp"
    bin/halcmd show comp
    echo "Hit enter to create a 1mS thread"
    read
    echo "$ bin/halcmd newthread parport.thread 1000000"
    bin/halcmd newthread parport.thread 1000000
    echo "Hit enter see the threads and functions"
    read
    echo "$ bin/halcmd show thread"
    bin/halcmd show thread
    echo "(the period is in nano-seconds)"
    echo "$ bin/halcmd show funct"
    bin/halcmd show funct
    echo "Hit enter to continue"
    read
    echo "(connecting the parport read and write"
    echo " functions to the 1mS thread)"
    echo "$ bin/halcmd addf parport.0.read parport.thread"
    bin/halcmd addf parport.0.read parport.thread
    echo "$ bin/halcmd addf parport.0.write parport.thread"
    bin/halcmd addf parport.0.write parport.thread
    echo "(start the realtime thread)"
    echo "$ bin/halcmd start"
    bin/halcmd start
    echo "Hit enter see the threads and functions again"
    read
    echo "$ bin/halcmd show thread"
    bin/halcmd show thread
    echo "(thread now has functions attached)"
    echo "$ bin/halcmd show funct"
    bin/halcmd show funct
    echo "(functions have a non-zero users count)"
    echo "Hit enter to see the pins"
    read
    echo "$ bin/halcmd show pin"
    bin/halcmd show pin
    echo "Hit enter to see the parameters"
    read
    echo "$ bin/halcmd show param"
    bin/halcmd show param
    echo "Hit enter to create some signals"
    read
    echo "$ bin/halcmd newsig jumper1 bit"
    bin/halcmd newsig jumper1 bit
    echo "$ bin/halcmd newsig jumper2 bit"
    bin/halcmd newsig jumper2 bit
    echo "(signals created - lets look at them)"
    echo "$ bin/halcmd show sig"
    bin/halcmd show sig
    echo "Hit enter to connect signals to pins"
    read
    echo "(use signal jumper1 to connect input pin 10 to output pin 2)"
    echo "$ bin/halcmd linksp jumper1 parport.0.pin-10-in"
    bin/halcmd linksp jumper1 parport.0.pin-10-in
    echo "$ bin/halcmd linksp jumper1 parport.0.pin-02-out"
    bin/halcmd linksp jumper1 parport.0.pin-02-out
    echo "(connections made - lets take a look)"
    echo "$ bin/halcmd show sig"
    bin/halcmd show sig
    echo "(If you have a breakout board or other access to the port"
    echo " you can apply a signal to pin 10 and verify that pin 2"
    echo " follows it - updated every 1mS )"
    echo "Hit enter to add another output"
    read
    echo "$ bin/halcmd linksp jumper1 parport.0.pin-03-out"
    bin/halcmd linksp jumper1 parport.0.pin-03-out
    echo "(input pin 10 is now routed to output pins 2 and 3 )"
    echo "$ bin/halcmd show sig"
    bin/halcmd show sig
    echo "Hit enter to invert the pin 3 output"
    read
    echo "(invert pin 3 by setting a parameter of the parport module)"
    echo "$ bin/halcmd setp parport.0.pin-03-out-invert TRUE"
    bin/halcmd setp parport.0.pin-03-out-invert TRUE
    echo "(if you have access to the pins, you can verify"
    echo " that pin 3 is now inverted)"
    echo "Hit enter to see the parameters"
    read
    echo "$ bin/halcmd show param"
    bin/halcmd show param
    echo "Hit enter to try halmeter"
    read
    echo "(running halmeter, a GUI application - it should"
    echo " appear in another window.)"
    echo "(click on the select button, then select a pin, signal,"
    echo " or parameter to observe.  You can change what you are"
    echo " observing at any time.)"
    echo "(the meter updates approx. every 0.1 seconds - if you"
    echo " have access to the pins, change the input and halmeter"
    echo " will show the changes.)"
    echo "(an interesting paremeter to observe is parport.thread.time"
    echo " which is the most recent execution time of the thread in"
    echo " nanoseconds.  you should be able to see it change a little"
    echo " due to jitter and other factors."
    echo "(Click exit to shut down halmeter.)"
    echo "$ bin/halmeter"
    bin/halmeter
    echo "Hit enter to finish the demo"
    read
    echo "(deleting signals)"
    echo "$ bin/halcmd delsig jumper1"
    bin/halcmd delsig jumper1
    echo "$ bin/halcmd delsig jumper2"
    bin/halcmd delsig jumper2
    echo "(unloading realtime modules)"
    echo "$ bin/halcmd unloadrt all"
    bin/halcmd unloadrt all
    exit 0
fi
#
# The next demo: "siggen" tests the signal generator component
# and halmeter.
# this one is also a step by step tutorial
#
if [ $1 = siggen ] ; then
    echo "(Comments that are part of the demo are in parenthesis.)"
    echo "(This demo echos its commands to the screen so you can"
    echo " see what each step does.  Echoed commands start with '$')"
    echo "Hit enter to install the siggen module"
    read
    echo "$ bin/halcmd loadrt siggen"
    bin/halcmd loadrt siggen
    echo "Hit enter see the component list"
    read
    echo "$ bin/halcmd show comp"
    bin/halcmd show comp
    echo "Hit enter to create a 1mS thread"
    read
    echo "$ bin/halcmd newthread siggen.thread 1000000"
    bin/halcmd loadrt newthread siggen.thread 1000000
    echo "Hit enter see the threads and functions"
    read
    echo "$ bin/halcmd show thread"
    bin/halcmd show thread
    echo "(the period is in nano-seconds)"
    echo "$ bin/halcmd show funct"
    bin/halcmd show funct
    echo "Hit enter to continue"
    read
    echo "(connecting the siggen update function to the 1mS thread)"
    echo "$ bin/halcmd addf siggen.0.update siggen.thread"
    bin/halcmd addf siggen.0.update siggen.thread
    echo "(start the realtime thread)"
    echo "$ bin/halcmd start"
    bin/halcmd start
    echo "Hit enter see the threads and functions again"
    read
    echo "$ bin/halcmd show thread"
    bin/halcmd show thread
    echo "(thread now has function attached)"
    echo "$ bin/halcmd show funct"
    bin/halcmd show funct
    echo "(function has a non-zero users count)"
    echo "Hit enter to see the pins"
    read
    echo "$ bin/halcmd show pin"
    bin/halcmd show pin
    echo "Hit enter to see the parameters"
    read
    echo "$ bin/halcmd show param"
    bin/halcmd show param
    echo "Hit enter to change the frequency to 0.1Hz"
    read
    echo "$ bin/halcmd setp siggen.0.frequency 0.1"
    bin/halcmd setp siggen.0.frequency 0.1
    echo "Hit enter to see the parameters"
    read
    echo "$ bin/halcmd show param"
    bin/halcmd show param
    echo "Hit enter to try halmeter"
    read
    echo "(running halmeter, a GUI application - it should"
    echo " appear in another window.)"
    echo "(it will initially display the sine signal, click"
    echo " on the select button, then select a pin, signal, or"
    echo " parameter to observe.  You can change what you are"
    echo " observing at any time.)"
    echo "(the meter updates approx. every 0.1 seconds - if you"
    echo " select one of the output pins, you should see it go"
    echo " through a complete cycle every 10 seconds, since we"
    echo " set the frequency to 0.1Hz.)"
    echo "(Click exit to shut down halmeter.)"
    echo "$ bin/halmeter pin siggen.0.sine"
    bin/halmeter pin siggen.0.sine
    echo "Hit enter to finish the demo"
    read
    echo "(unloading realtime modules)"
    echo "$ bin/halcmd unloadrt all"
    bin/halcmd unloadrt all
    exit 0
fi
#
# The next demo: "scope" lets the user play with the scope
# using siggen as a signal source.
# this one is also a step by step tutorial
#
if [ $1 = scope ] ; then
    echo "The first part of this demo is identical to the siggen"
    echo "demo.  Hit enter to get started"
    read
    echo "First we load the siggen demo (not echoed)"
    bin/halcmd loadrt siggen
    bin/halcmd newthread siggen.thread 1000000
    bin/halcmd addf siggen.0.update siggen.thread
    bin/halcmd start
    bin/halcmd setp siggen.0.frequency 10
    echo "Then we load the realtime component of halscope:"
    echo "$ bin/halcmd loadrt scope_rt"
    bin/halcmd loadrt scope_rt
    echo "Finally we start the user component (in the background"
    echo "so that the foreground can continue to give instructions):"
    echo "$ bin/halscope &"
    bin/halscope &
    echo "HALSCOPE should appear in a new window.  Select this "
    echo "window again and hit enter for step by step instructions"
    read
    echo "First we need to set the sample rate.  Click on then name"
    echo "of a realtime thread (this example has only one)."
    echo "You can optionally change the multiplier if you don't"
    echo "want to sample every time the thread runs.  You can also"
    echo "change the record length to allow for more channels.  For"
    echo "the demo, you want at least 4 channels, so change it."
    echo "When you are done, click OK, then come back to this"
    echo "window and hit enter for the next step."
    read
    echo "Now we need to select the pins/signals/parameters that"
    echo "we are going to observe.  The 16 buttons in a vertical"
    echo "column are the channel select buttons.  Click #1"
    echo "In the dialog that pops up, select a pin - perhaps the"
    echo "triangle output of the siggen.  Note that the channel"
    echo "number and name appear in the lower left of the scope"
    echo "window.  This is the selected (highlighted) channel."
    echo "Now click on another channel number like #3, and select"
    echo "another pin, perhaps the sine output.  Then come back"
    echo "to this window and hit enter for the next step"
    read
    echo "Now you have a couple channels.  To start sampling, click"
    echo "on NORMAL in the 'Run Mode' window in the upper right."
    echo "The state display at the top right of the display will"
    echo "change from IDLE to PRE-TRIG as the scope acquires"
    echo "pre-trigger data.  The status display will show a bar"
    echo "that represents the portion of the record that has been"
    echo "captured.  The state will change to TRIGGER? when the"
    echo "pre-trigger phase is done, to show that it is waiting "
    echo "for a trigger.  Currently the only working trigger source"
    echo "is the manual one, so click the 'Force' button to cause"
    echo "a trigger. You can also click on 'Auto', which causes"
    echo "the scope to trigger automaticlly after a delay.  Fully"
    echo "functional triggering is under construction.  When the"
    echo "scope triggers, the state will change to TRIGGERED and"
    echo "the bar will show progress as it acquires post-trigger"
    echo "data.  When it is done, the waveforms will display, and"
    echo "the scope will begin acquiring data again.  Hit enter"
    echo "for the next step."
    read
    echo "The signals are likely to be near the top of the screen"
    echo "if you used a low numbered channel.  Use the position"
    echo "slider in the vertical menu (lower right) to move the"
    echo "selected signal (the green one) down.  Use the gain"
    echo "slider to scale it if you wish.  Note the scale displayed"
    echo "below the slider - it has a very wide range.  When the"
    echo "selected channel is adjusted to your liking, click on"
    echo "the channel number for the other channel to select it."
    echo "(Note the name and number at the bottom left.)  Adjust"
    echo "the second channels vertical position and gain, then"
    echo "hit enter for the next step"
    read
    echo "Now that vertical is set, lets look at horizontal.  The"
    echo "horizontal controls are above the screen.  Below the"
    echo "sliders and sample rate display is a graphic that shows"
    echo "the display as a large box, and the data record as a"
    echo "smaller box (probably half or all black).  Move the zoom"
    echo "slider one click to the right.  Note that the large box"
    echo "is now shorter.  Now move the position slider, and see"
    echo "how the large box moves with respect to the smaller one."
    echo "This display quickly shows you what portion of the record"
    echo "you are viewing.  Zoom in some more to clearly see the"
    echo "sine and triangle waveforms.  Hit enter for the next step."
    read
    echo "If you want to change the sample rate, use the 'Change"
    echo "Rate/Len' button, which brings up the same dialog that"
    echo "appeared when the program started.  To add more channels,"
    echo "click on additional channel number buttons.  If you want"
    echo "to turn a channel off, select it and click the 'Channel"
    echo "Off' button (the signal source, position, etc, will be"
    echo "remembered if you turn it back on again.  To change the"
    echo "signal captured by a channel, select the channel and click"
    echo "the 'Source' button.  An interesting item to look at is"
    echo "the paremeter 'siggen.thread.time', which is the time"
    echo "needed by the thread, in nano-seconds.  It is updated"
    echo "every time the thread runs, and varies based on cache hits"
    echo "and other loading.  Its value will be in the thousands"
    echo "of nanoseconds (a few microseconds), so the trace will"
    echo "initially be off scale. Set the scale to 5K/div or so to"
    echo "make it visible. Hit enter for the next step."
    read
    echo "To shut down the scope, use the [X] button in the corner"
    echo "Hit enter to finish the demo"
    read
    bin/halcmd unloadrt all
    exit 0
fi
#
#
# if we get here, the user asked for a non-existant demo
#
echo "Sorry, there is no demo called '$1'"
scripts/hal_demo
exit -1

