diff --git a/Dockerfile b/Dockerfile
index af84c4d64aab1451224c234bc01ff92bfe15fe82..370950521074232b0e8ef1c7144b64bb20b47f03 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,6 +2,7 @@ FROM python:3.9-alpine as sphinx-build-env
 RUN apk update
 RUN python -m pip install --upgrade pip
 RUN pip install -U sphinx
+RUN pip install -U sphinx-design
 RUN pip install sphinxcontrib-svg2pdfconverter
 RUN apk add librsvg
 RUN pip install sphinx_rtd_theme
diff --git a/beaglebone-cookbook/index.rst b/beaglebone-cookbook/index.rst
index 6192126bff250278716438a6a608c8c192998275..f8f394aeb8c0637aba811b634770c95607c4ea28 100644
--- a/beaglebone-cookbook/index.rst
+++ b/beaglebone-cookbook/index.rst
@@ -1,4 +1,4 @@
-.. _beaglebone-cookbook-home:
+.. _bone-cook-book-home:
 
 BeagleBone Cookbook
 #######################
diff --git a/conf.py b/conf.py
index 9d653802b5b7cc0a8fef39fbc171748c2db6c077..b60c51e29f5b66628aa71fea34079b82e6586297 100644
--- a/conf.py
+++ b/conf.py
@@ -25,7 +25,7 @@ author = 'BeagleBoard.org Foundation'
 # -- General configuration ---------------------------------------------------
 
 extensions = [
-    "sphinxcontrib.rsvgconverter",
+    "sphinxcontrib.rsvgconverter", "sphinx_design"
 ]
 
 templates_path = ['_templates']
diff --git a/index.rst b/index.rst
index 8d96344e287eb13ebc8d0cdb6071eb410247f67d..3d9e4de14601ffdfb1666eef43a835d87f2830a1 100644
--- a/index.rst
+++ b/index.rst
@@ -40,6 +40,7 @@ Sections
    :caption: Books
 
    beaglebone-cookbook/index.rst
+   pru-cookbook/index.rst
 
 Indices and tables
 ############################
diff --git a/pru-cookbook/01case/case.rst b/pru-cookbook/01case/case.rst
new file mode 100644
index 0000000000000000000000000000000000000000..61e21f02af4e43aa6f5691f02119de6370621fa9
--- /dev/null
+++ b/pru-cookbook/01case/case.rst
@@ -0,0 +1,1122 @@
+.. _pru-cookbook-case:
+
+Case Studies - Introduction
+#############################
+
+It's an exciting time to be making projects that use embedded processors.  
+Make:'s `Makers' Guide to Boards <https://makezine.com/comparison/boards/>`_ shows
+many of the options that are available and groups them into different types.  
+*Single board computers* (SBCs) generally run Linux on some sort of `ARM <https://www.arm.com/>`_
+processor.  Examples are the BeagleBoard and the Raspberry Pi.  Another type
+is the *microcontroller*, of which the `Arduino <https://www.arduino.cc/>`_ is 
+popular.  
+
+The SBCs are used because they have an operating system to manage files, I/O, 
+and schedule when things are run, all while possibly talking to the Internet.  
+Microcontrollers shine when things 
+being interfaced require careful timing and can't afford to have an OS preempt an 
+operation.
+
+But what if you have a project that needs the flexibility of an OS and the timing 
+of a microcontroller?  This is where the BeagleBoard excels since it has both 
+an ARM procssor running Linux and two footnote:[Four if you are on the BeagleBone AI];
+**P**rogrammable **R**eal-Time **U**nits (PRUs).
+The PRUs have 32-bit cores which run
+independently of the ARM processor, therefore they can
+be programmed to respond quickly to inputs and produce very precisely timed 
+outputs. 
+
+There are many :ref:`Projects <pru-cookbook-projects>`_ that use the PRU.
+They are able to do things that can't be done with just a SBC or just a microcontroller. 
+Here we present some case studies that give a high-level view of using the PRUs. In later
+chapters you will see the details of how they work.
+
+Here we present:
+
+.. TODO Switch from LEDscape to FPP
+
+* `Robotics Control Library <http://strawsondesign.com/docs/roboticscape/>`_
+* `BeagleLogic <https://github.com/abhishek-kakkar/BeagleLogic/wiki>`_
+* `NeoPixels -- 5050 RGB LEDs with Integrated Drivers (Falcon Christmas) <http://falconchristmas.com>`_
+* `RGB LED Matrix (Falcon Christmas) <http://falconchristmas.com>`_
+* `simpPRU -- A python-like language for programming the PRUs`_ <https://github.com/VedantParanjape/simpPRU>
+.. * `MachineKit <http://www.machinekit.io/>`_
+.. * `ArduPilot <http://ardupilot.org/>, <http://ardupilot.org/dev/docs/beaglepilot.html>`_
+.. * `BeagleScope <https://github.com/ZeekHuge/BeagleScope>`_
+
+The following are resources used in this chapter.
+
+.. admonition:: Resources
+
+   * `Pocket Beagle System Reference Manual https://github.com/beagleboard/pocketbeagle/wiki/System-Reference-Manual#673_PRUICSS_Pin_Access`_
+   * `BeagleBone Black P8 Header Table https://github.com/derekmolloy/exploringBB/blob/master/chp06/docs/BeagleboneBlackP8HeaderTable.pdf`_
+   * `BeagleBone Black P9 Header Table https://github.com/derekmolloy/exploringBB/blob/master/chp06/docs/BeagleboneBlackP9HeaderTable.pdf`_
+   * `BeagleBone AI System Reference Manual https://github.com/beagleboard/beaglebone-ai/wiki/System-Reference-Manual`_
+
+
+Robotics Control Library
+-------------------------
+
+Robotics is an embedded application that often requires both an SBC to control the 
+high-level tasks (such as path planning, line following, communicating with the user)
+*and* a microcontroller to handle the low-level tasks (such as telling motors how fast
+to turn, or how to balance in response to an IMU input).  The 
+`EduMIP <https://www.ucsdrobotics.org/edumip>`_ balancing 
+`robot <https://www.hackster.io/edumip/edumip-13a29c>`_ 
+demonstrates that by using the PRU, the Blue can handle both the high 
+and low -level tasks without an additional microcontroller. The EduMIP is shown 
+in :ref:`<case_blue>`.
+
+.. _case_blue:
+
+Blue balancing
+~~~~~~~~~~~~~~~
+
+.. figure:: figures/blue.png
+   :align: center
+   :alt: Blue balancing
+
+The `Robotics Control Library <http://strawsondesign.com/docs/roboticscape/>`_ is a 
+package that is already installed on the Beagle 
+that contains a C library and example/testing programs. It uses the PRU to extend the 
+real-time hardware of the Bone by adding eight addional servo channels and one 
+addition real-time encoder input.
+
+The following examples show how easy it is to use the PRU for robotics.
+
+Controlling Eight Servos
+*************************
+
+Problem
+~~~~~~~~
+
+You need to control eight servos, but the Bone doesn't have enough pulse width 
+modulation (PWM) channels
+and you don't want to add hardware.  
+
+Solution
+~~~~~~~~~
+
+The Robotics Control Library provides eight additional PWM channels 
+via the PRU that can be used out of the box. 
+
+.. note::
+   The I/O pins on the Beagles have a mutliplexer that lets you select what I/O 
+   appears on a given pin.  The Blue has the mux already configured to to run these
+   examples.  Follow the instructions in 
+   :ref:`../03details/details.html#details_configure_servos, Configuring Pins for Controlling Servos` 
+   to configure the pins for the Black and the Pocket.
+
+
+.. * TODO - verify these commands
+
+Just run:
+
+.. code-block:: bash
+
+   bone$ sudo rc_test_servos -f 10 -p 1.5
+
+The ``-f 10`` says to use a frequency of 10 Hz and the ``-p 1.5`` says to set the position to ``1.5``.  The range of positions is
+``-1.5`` to ``1.5``.   Run ``rc_test_servos -h`` to see all the options.
+
+.. code-block:: bash
+
+   bone$ rc_test_servos -h
+
+   Options
+   -c {channel}   Specify one channel from 1-8.
+                  Otherwise all channels will be driven equally
+   -f {hz}        Specify pulse frequency, otherwise 50hz is used
+   -p {position}  Drive servo to a position between -1.5 & 1.5
+   -w {width_us}  Send pulse width in microseconds (us)
+   -s {limit}     Sweep servo back/forth between +- limit
+                  Limit can be between 0 & 1.5
+   -r {ch}        Use DSM radio channel {ch} to control servo
+   -h             Print this help messege 
+
+   sample use to center servo channel 1:
+      rc_test_servo -c 1 -p 0.0
+
+Discussion
+~~~~~~~~~~~
+
+The BeagleBone Blue sends these eight outputs to it's servo channels.  The others use the pins shown in the 
+:ref:`case__register_to_pin_table`.
+
+.. _case__register_to_pin_table:
+
+PRU register to pin table
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+   +-----------+--------+---------+----------+-------+
+   |PRU pin    |Blue pin|Black pin|Pocket pin|AI pin |
+   +===========+========+=========+==========+=======+
+   |pru1_r30_8 |1       |P8_27    |P2.35     |       |
+   +-----------+--------+---------+----------+-------+
+   |pru1_r30_10|2       |P8_28    |P1.35     |P9_42  |
+   +-----------+--------+---------+----------+-------+
+   |pru1_r30_9 |3       |P8_29    |P1.02     |P8_14  |
+   +-----------+--------+---------+----------+-------+
+   |pru1_r30_11|4       |P8_30    |P1.04     |P9_27  |
+   +-----------+--------+---------+----------+-------+
+   |pru1_r30_6 |5       |P8_39    |          |P8_19  |
+   +-----------+--------+---------+----------+-------+
+   |pru1_r30_7 |6       |P8_40    |          |P8_13  |
+   +-----------+--------+---------+----------+-------+
+   |pru1_r30_4 |7       |P8_41    |          |       |
+   +-----------+--------+---------+----------+-------+
+   |pru1_r30_5 |8       |P8_42    |          |P8_18  |
+   +-----------+--------+---------+----------+-------+
+
+
+You can find these details in the 
+`P8 Header Table <https://github.com/derekmolloy/exploringBB/blob/master/chp06/docs/BeagleboneBlackP8HeaderTable.pdf>`_, 
+`P9 Header Table <https://github.com/derekmolloy/exploringBB/blob/master/chp06/docs/BeagleboneBlackP9HeaderTable.pdf>`_, 
+`Pocket Beagle System Reference Manual <https://github.com/beagleboard/pocketbeagle/wiki/System-Reference-Manual#673_PRUICSS_Pin_Access>`_ 
+(Here is a more usable version of the `table <https://docs.google.com/spreadsheets/d/1FRGvYOyW1RiNSEVprvstfJAVeapnASgDXHtxeDOjgqw/edit?usp=sharing>`_.)
+and
+`BeagleBone AI System Reference Manual <https://github.com/beagleboard/beaglebone-ai/wiki/System-Reference-Manual>`_.
+(Here is a more usable version of the `table <https://docs.google.com/spreadsheets/d/1dFSBVem86vAUD7MLXvqdS-N0Efi8_g_O1iTqzql8DAo/edit#gid=0>`_.)
+
+
+Be default the PRUs are already loaded with the code needed to run the
+servos.  All you have to do is run the command.
+
+.. [/opt/source/Robotics_Cape_Installer/pru_firmware/src/pru1-servo.asm]
+
+Controlling Individual Servos
+******************************
+
+Problem
+~~~~~~~~~
+
+``rc_test_servos`` is nice, but I need to control the servos individually.
+
+Solution
+~~~~~~~~~
+
+You can modify ``rc_test_servos.c``.  You'll find it on the bone online at
+https://github.com/beagleboard/librobotcontrol/blob/master/examples/src/rc_test_servos.c.
+
+Just past line 250 you'll find a ``while`` loop that has calls to ``rc_servo_send_pulse_normalized(ch,servo_pos)`` and
+``rc_servo_send_pulse_us(ch, width_us)``.  The first call sets the pulse width relative to the pulse period; the other
+sets the width to an absolute time.  Use whichever works for you.
+
+Controlling More Than Eight Channels
+*************************************
+
+Problem
+~~~~~~~~~~
+
+I need more than eight PWM channels, or I need less jitter on the off time.
+
+Solution
+~~~~~~~~~~
+
+This is a more advanced problem and required reprograming the PRUs.  See 
+:ref:`../05blocks/blocks.html#blocks_pwm, PWM Generator` for an example.
+
+Reading Hardware Encoders
+**************************
+
+Problem
+~~~~~~~~~~
+
+I want to use four encoders to measure four motors, but I only see hardware for three.
+
+Solution
+~~~~~~~~~~
+
+The forth encoder can be implemented on the PRU. If you run ``rc_test_encoders_eqep`` on the Blue, you will see the output of 
+encoders E1-E3 which are connected to the eEQP hardware.
+
+.. code-block:: bash
+
+   bone$ *rc_test_encoders_eqep* 
+
+   Raw encoder positions
+         E1   |      E2   |      E3   | 
+            0 |         0 |         0 |^C
+
+You can also access these hardware encoders on the Black and Pocket using the 
+pins shown in :ref:`case_pin_mapping`.
+
+.. _case_pin_mapping:
+
+eQEP to pin mapping
+~~~~~~~~~~~~~~~~~~~~
+.. table::
+
+   +----+--------+-----------+-----------+--------+--------+------------+-------------+
+   |eQEP|Blue pin|Black pin A|Black pin B|AI pin A|AI pin B|Pocket pin A|Pocket pin B |
+   +====+========+===========+===========+========+========+============+=============+
+   |0   |E1      |P9_42B     |P9_27      |        |        |P1.31       |P2.24        |
+   +----+--------+-----------+-----------+--------+--------+------------+-------------+
+   |1   |E2      |P8_35      |P8_33      |P8_35   |P8_33   |P2.10       |             |
+   +----+--------+-----------+-----------+--------+--------+------------+-------------+
+   |2   |E3      |P8_12      |P8_11      |P8_12   |P8_11   |P2.24       |P2.33        |
+   +----+--------+-----------+-----------+--------+--------+------------+-------------+
+   |2   |        |P8_41      |P8_42      |P9_19   |P9_41   |            |             |
+   +----+--------+-----------+-----------+--------+--------+------------+-------------+
+   |    |E4      |P8_16      |P8_15      |        |        |P2.09       |P2.18        |
+   +----+--------+-----------+-----------+--------+--------+------------+-------------+
+   |3   |        |           |           |P8_25   |P8_24   |            |             |
+   +----+--------+-----------+-----------+--------+--------+------------+-------------+
+   |3   |        |           |           |P9_42   |P9_27   |            |             |
+   +----+--------+-----------+-----------+--------+--------+------------+-------------+
+
+.. note::
+
+   The I/O pins on the Beagles have a mutliplexer that lets you select what I/O 
+   appears on a given pin.  The Blue has the mux already configured to to run these
+   examples.  Follow the instructions in 
+   :ref:`../03details/details.html#details_configure_encoders, Configuring Pins for Controlling Encoders` 
+   to configure the pins for the Black and the Pocket.
+
+
+Reading PRU Encoder
+*********************
+
+Problem
+~~~~~~~~
+
+I want to access the PRU encoder.
+
+Solution
+~~~~~~~~~
+
+The forth encoder is implemented on the PRU and accessed with `sudo rc_test_encoders_pru`  
+.. note::
+   This command needs root permission, so the `sudo` is needed.  
+
+Here's what you will see
+
+.. code-block:: bash
+
+   bone$ *sudo rc_test_encoders_pru*
+   [sudo] password for debian: 
+
+   Raw encoder position
+         E4   | 
+            0 |^C
+
+.. note::
+
+   If you aren't running the Blue you will have to configure the pins as shown 
+   in the note above.  
+
+
+BeagleLogic -- a 14-channel Logic Analyzer
+-------------------------------------------
+
+Problem
+********
+
+I need a 100Msps, 14-channel logic analyzer
+
+Solution
+*********
+
+`BeagleLogic <https://beaglelogic.readthedocs.io/en/latest/>`_ is a 100Msps, 
+14-channel logic analyzer that runs on the Beagle. 
+
+.. admonition:: information
+   
+   BeagleLogic turns your BeagleBone [Black] into a 14-channel, 100Msps Logic 
+   Analyzer. Once loaded, it presents itself as a character device node */dev/beaglelogic*.
+   The core of the logic analyzer is the 'beaglelogic' kernel module that 
+   reserves memory for and drives the two Programmable Real-Time Units 
+   (PRU) via the remoteproc interface wherein the PRU directly writes logic 
+   samples to the System Memory (DDR RAM) at the configured sample rate 
+   one-shot or continuously without intervention from the ARM core.
+
+   https://github.com/abhishek-kakkar/BeagleLogic/wiki
+
+
+The quickest solution is to get the `no-setup-required image <https://github.com/abhishek-kakkar/BeagleLogic/wiki/BeagleLogic-%22no-setup-required%22-setup:-Introducing-System-Image!>`_.  It points to an older image
+(beaglelogic-stretch-2017-07-13-4gb.img.xz) but should still work.
+
+If you want to be running a newer image, there are instructions on the site for `installing BeagleLogic <https://beaglelogic.readthedocs.io/en/latest/install.html>`_, but I had to do the additional steps in :ref:`case_installing_beaglelogic`.
+
+.. TODO - Recheck
+
+.. _case_installing_beaglelogic:
+
+Installing BeagleLogic
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+      
+   bone$ *git clone https://github.com/abhishek-kakkar/BeagleLogic*
+   bone$ *cd BeagleLogic/kernel*
+   bone$ *mv beaglelogic-00A0.dts beaglelogic-00A0.dts.orig*
+   bone$ *wget https://gist.githubusercontent.com/abhishek-kakkar/0761ef7b10822cff4b3efd194837f49c/raw/eb2cf6cfb59ff5ccb1710dcd7d4a40cc01cfc050/beaglelogic-00A0.dts*
+   bone$ *make overlay*
+   bone$ *sudo cp beaglelogic-00A0.dtbo /lib/firmware/*
+   bone$ *sudo update-initramfs -u -k \`uname -r`*
+   bone$ *sudo reboot*
+
+Once the Bone has rebooted, browse to 192.168.7.2:4000 where you'll see
+:ref:`case_beaglelogic_capture`.  Here you can easily select the sample
+rate, number of samples, and which pins to sample. 
+Then click *Begin Capture* to capture your data, at up to 100 MHz!
+
+.. _case_beaglelogic_capture:
+
+BeagleLogic Data Capture
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/beaglelogic_capture.png
+   :align: center
+   :alt: BeagleLogic Data Capture
+
+
+Discussion
+************
+
+BeagleLogic is a complete system that includes firmware for the PRUs, 
+a kernel module and a web interface that create a powerful 100 MHz 
+logic analyzer on the Bone with no additional hardware needed.
+
+.. tip::
+
+   If you need buffered inputs, consider
+   http://standalone.beaglelogic.net/en/latest/[BeagleLogic Standalone],
+   a turnkey Logic Analyzer built on top of BeagleLogic.
+
+
+The kernel interface makes it easy to control the PRUs through the
+command line.  For example
+
+.. code-block:: bash
+      
+   bone$ *dd if=/dev/beaglelogic of=mydump bs=1M count=1*
+
+will capture a binary dump from the PRUs. The sample rate and number of 
+bits per sample can be controlled through ``/sys/``.
+
+.. code-block:: bash
+
+   bone$ *cd /sys/devices/virtual/misc/beaglelogic*
+   bone$ *ls*
+   buffers      filltestpattern  power       state         uevent
+   bufunitsize  lasterror        samplerate  subsystem
+   dev          memalloc         sampleunit  triggerflags
+   bone$ *cat samplerate*
+   1000
+   bone$ *cat sampleunit*
+   8bit
+
+You can set the sample rate by simply writing to ``samplerate``.
+
+.. code-block:: bash
+
+   bone$ *echo 100000000 > samplerate*
+
+`sysfs attributes Reference <https://beaglelogic.readthedocs.io/en/latest/sysfs_attributes.html>`_
+has more details on configuring via sysfs.
+
+If you run ``dmesg -Hw`` in another window you can see when a capture 
+is started and stopped.
+
+.. code-block:: bash
+
+   bone$ *dmesg -Hw*
+   [Jul25 08:46] misc beaglelogic: capture started with sample rate=100000000 Hz, sampleunit=1, triggerflags=0
+   [  +0.086261] misc beaglelogic: capture session ended
+
+
+BeagleLogic uses the two PRUs to sample at 100Msps.  Getting a PRU running at 200Hz to sample at 100Msps is a slick trick.
+`The Embedded Kitchen <http://theembeddedkitchen.net/beaglelogic-building-a-logic-analyzer-with-the-prus-part-1/449>`_ has a nice article 
+explaining how the PRUs get this type of performance.   
+
+
+NeoPixels -- 5050 RGB LEDs with Integrated Drivers (Falcon Christmas)
+----------------------------------------------------------------------
+
+Problem
+*********
+
+You have an `Adafruit NeoPixel LED string <http://www.adafruit.com/products/1138>`_,
+`Adafruit NeoPixel LED matrix <http://www.adafruit.com/products/1487>`_ or
+any other type of 
+`WS2812 LED <https://cdn-shop.adafruit.com/datasheets/WS2812.pdf>`_
+and want to light it up.
+
+.. TODO Show how to drive ws2812's with FPP.
+
+Solution
+*********
+
+If you are driving just one string you can write your own code 
+(See :ref:`../05blocks/blocks.adoc#blocks_ws2812, WS2812 Driver`)
+If you plan to drive multiple strings, then consider
+Falcon Christmas (`FPP <https://falconchristmas.com/>`_). 
+FPP can be used to drive both LEDs with an integrated
+driver (neopixels) or without an integrated driver.  Here we'll show you how to
+set up for the integrated drive and in the next section the no driver LEDs will be 
+show.
+
+Hardware
+*********
+
+For this setup we'll wire a single string of NeoPixels to the Beagle.  
+I've attached the black wire on the string to ground on the Beagle 
+and the red wire to a 3.3V pin on the Beagle.
+The yellow data in line is attached to P1.31 (I'm using a PocketBeagle.).
+
+How did I know to attach to P1.31?  The FalconChristmas git repo
+(https://github.com/FalconChristmas/fpp) has files that tell which pins
+attach to which port.  https://github.com/FalconChristmas/fpp/blob/master/capes/pb/strings/F8-B-20.json
+has a list of 20 ports and where they are connected.  Pin P1.31 appears on
+line 27.  It's the 20th entry in the list.  You could pick any of the others
+if you'd rather.
+
+Software Setup
+***************
+
+Assuming the PocketBeagle is attached via the USB cable, 
+on your host computer browse to <http://192.168.7.2/> and you will see 
+:ref:`case_fpp_program_control2`.
+
+.. _case_fpp_program_control2:
+
+Falcon Play Program Control
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_program_control.png
+   :align: center
+   :alt: Falcon Play Program Control
+
+You can test the display by first setting up the Channel Outputs and then 
+going to *Display Testing*.  :ref:`case_channel_outputs_menu2` shows where to 
+select Channel Outputs and :ref:`case_channel_outputs2` shows which settings to use.
+
+.. _case_channel_outputs_menu2:
+
+Selecting Channel Outputs
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_channel_outputs_menu.png
+   :align: center
+   :alt: Selecting Channel Outputs
+
+.. _case_channel_outputs2:
+
+Channel Outputs Settings
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_channel_outputs_strings.png
+   :align: center
+   :alt: Channel Outputs Settings
+
+Click on the *Pixel Strings* tab.  Earlier we noted that *P1.31* is attached
+to port 20.  Note that at the bottom of the screen, port 20 has a PIXEL COUNT
+of 24.  We're telling FPP our string has 24 NeoPixels and they are attached
+to port 2 which in *P1.31*.  
+
+Be sure to check the *Enable String Cape*.
+
+Next we need to test the display.  Select **Display Testing** shown in
+:ref:`case_display_testing_menu2`.
+
+.. _case_display_testing_menu2:
+
+Selecting Display Testing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_display_testing_menu2.png
+   :align: center
+   :alt: Selecting Display Testing
+
+Set the *End Channel* to *72*. (72 is 3*24)  
+Click *Enable Test Mode* and your matrix should light up.  Try the different 
+testing patterns shown in :ref:`case_display_testing2`.
+
+.. note::
+
+   Clicking on the *-3* will subtract three from the End Channel, which should
+   then display three fewer LEDs which is one NeoPixel.  The last of your NeoPixels
+   should go black.  This is an easy way to make sure you have the correct pixel
+   count.
+
+.. _case_display_testing2:
+
+Display Testing Options
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_display_testing2.png
+   :align: center
+   :alt: Display Testing Options
+
+You can control the LED string using the E1.31 protocol. 
+(https://www.doityourselfchristmas.com/wiki/index.php?title=E1.31_(Streaming-ACN)_Protocol)
+First configure the input channels by going to Channel Inputs as shown in
+:ref:`case_channel_inputs`.
+
+.. _case_channel_inputs:
+
+Going to Channel Inputs
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_channel_inputs.png
+   :align: center
+   :alt: Going to Channel Inputs
+
+Tell it you have 72 LEDs and enable the input as shown in :ref:`case_set_inputs`.
+
+.. _case_set_inputs:
+
+Setting Channel Inputs
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_inputs_setup2.png
+   :align: center
+   :alt: Setting Channel Inputs
+
+Finally go to the Status Page as shown in :ref:`case_status`.
+
+.. _case_status:
+
+Watching the status
+~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_status.png
+   :align: center
+   :alt: Watching Status
+
+Now run a program on another computer that generated E1.31 packets.
+:ref:`case_1.31_example` is an example python program.
+
+.. _cse_e1.31_example:
+
+.e1.31-test.py 
+~~~~~~~~~~~~~~
+
+:downlod:`e1.31-test.py <code/e1.31-test.py>`- Example of generating packets to control the NeoPixels 
+
+.. TODO document the code
+
+.. _case_rgb_matrix:
+
+RGB LED Matrix -- No Integrated Drivers (Falcon Christmas)
+-----------------------------------------------------------
+
+Problem
+*************************
+
+You want to use a RGB LED Matrix display that doesn't have integrated
+drivers such as the 
+`64x32 RGB LED Matrix <https://www.adafruit.com/product/2277>`_ by Adafuit
+shown in :ref:`case_adfruit_matrix`.
+
+.. _case_adfruit_matrix:
+
+Adafruit LED Matrix
+~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/ledmatrix.jpg
+   :align: center
+   :alt: Adafruit LED Matrix
+
+Solution
+*************************
+
+`Falcon Christmas <http://falconchristmas.com>`_ makes a software package
+called 
+`Falcon Player <http://falconchristmas.com/forum/index.php/board,8.0.html>`_ (FPP) which can drive 
+such displays.
+
+.. admonition:: information:
+
+   The Falcon Player (FPP) is a lightweight, optimized, feature-rich sequence player 
+   designed to run on low-cost SBC's (Single Board Computers).
+   FPP is a software solution that you download and install on hardware which can be 
+   purchased from numerous sources around the internet. 
+   FPP aims to be controller agnostic, it can talk E1.31, DMX, Pixelnet, and 
+   Renard to hardware from multiple hardware vendors, including controller 
+   hardware from Falcon Christmas available via COOPs or in the store on FalconChristmas.com.
+
+   http://www.falconchristmas.com/wiki/FPP:FAQ#What_is_FPP.3F
+
+Hardware
+~~~~~~~~~
+
+The Beagle hardware can be either a BeagleBone Black with the 
+`Octoscroller Cape <https://oshpark.com/shared_projects/7mSHNZcD>`_, or a 
+PocketBeagle with the 
+`PocketScroller LED Panel Cape <https://www.hackster.io/daniel-kulp/pocketscroller-led-panel-cape-for-pocketbeagle-fe12a6>`_. 
+(See `to purchase <https://kulplights.com/product/pocketscroller/>`_.)
+`Building and Octoscroller Matrix Display <https://www.diychristmas.org/wiki/index.php?title=Building_an_Octoscroller_Matrix_Display>`_ 
+gives details for using the BeagleBone Black. 
+
+:ref:`case_pocket` shows how to attach the PocketBeagle to the P5 LED matrix 
+and where to attach the 5V power.  If you are going to turn on all the LEDs 
+to full white at the same time you will need at least a 4A supply.
+
+.. _case_pocket:
+
+Pocket Beagle Driving a P5 RGB LED Matrix via the PocketScroller Cape
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/pocketscroller.jpg
+   :align: center
+   :alt: Pocket Beagle Driving a P5 RGB LED Matrix via the PocketScroller Cape
+
+
+Software
+~~~~~~~~~~
+
+The FPP software is most easily installed by downloading the 
+`current FPP release <https://github.com/FalconChristmas/fpp/releases/>`_, flashing an SD card and 
+booting from it. 
+
+.. tip::
+
+   The really brave can install it on a already running image.  See details at
+   https://github.com/FalconChristmas/fpp/blob/master/SD/FPP_Install.sh
+
+
+Assuming the PocketBeagle is attached via the USB cable, 
+on your host computer browse to http://192.168.7.2/ and you will see 
+:ref:`case_fpp_program_control`.
+
+.. _case_fpp_program_control:
+
+Falcon Play Program Control
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_program_control.png
+   :align: center
+   :alt: Falcon Play Program Control
+
+You can test the display by first setting up the Channel Outputs and then 
+going to *Display Testing*.  :ref:`case_channel_outputs_menu` shows where to 
+select Channel Outputs and :ref:`case_channel_outputs` shows which settings to use.
+
+.. _case_channel_outputs_menu:
+
+Selecting Channel Outputs
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_channel_outputs_menu.png
+   :align: center
+   :alt: Selecting Channel Outputs
+
+.. _case_channel_outputs:
+
+Channel Outputs Settings
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_channel_outputs.png
+   :align: center
+   :alt: Channel Outputs Settings
+
+Click on the **LED Panels** tab and then the only changes I made was 
+to select the **Single Panel Size** to be
+*64x32* and to check the **Enable LED Panel Output**.
+
+Next we need to test the display.  Select *Display Testing* shown in
+:ref:`case_display_testing_menu`.
+
+.. _case_display_testing_menu:
+
+Selecting Display Testing
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_display_testing_menu.png
+   :align: center
+   :alt: Selecting Display Testing
+
+Set the **End Channel** to **6144**. (6144 is 3*64*32)  
+Click **Enable Test Mode** and your matrix should light up.  Try the different 
+testing patterns shown in :ref:`case_display_testing`.
+
+.. _case_display_testing:
+
+Display Testing Options
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_display_testing.png
+   :align: center
+   :alt: Display Testing Options
+
+xLights - Creating Content for the Display
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Once you are sure your LED Matrix is working correctly you can program it 
+with a sequence.  
+
+
+.. admonition:: information:
+
+   xLights is a free and open source program that enables you to design, create and play 
+   amazing lighting displays through the use of DMX controllers, E1.31 Ethernet controllers and more.
+
+   With it you can layout your display visually then assign effects to the various items 
+   throughout your sequence. This can be in time to music (with beat-tracking built into xLights) 
+   or just however you like. xLights runs on Windows, OSX and Linux
+
+   https://xlights.org/
+
+
+xLights can be installed on your host computer (not the Beagle) by
+following instructions at https://xlights.org/releases/.
+
+Run xLights and you'll see :ref:`case_xlights_setup`.
+
+.. code-block:: bash
+
+   host$ *chmod +x xLights-2021.18-x86_64.AppImage*
+   host$ *./xLights-2021.18-x86_64.AppImage*
+
+.. TODO update the figures.
+
+.. _case_xlights_setup:
+
+xLights Setup
+~~~~~~~~~~~~~~
+
+.. figure:: figures/xlights_setup.png
+   :align: center
+   :alt: xLights Setup
+
+We'll walk you through a simple setup to get an animation to display on the 
+RGB Matrix.  xLights can use a protocol called E1.31 to send information to 
+the display.  Setup xLights by clicking on *Add Ethernet* and entering the values 
+shown in :ref:`case_xlights_setup_e1_31`.
+
+.. _case_xlights_setup_e1_31:
+
+Setting Up E1.31
+~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/xlights_setup_e1_31.png
+   :align: center
+   :alt: Setting Up E1.31
+
+The **IP Address** is the Bone's address as seen from the host computer. 
+Each LED is one channel, so one RGB LED is three channels.  The P5 board 
+has 3*64*32 or 6144 channels.  These are grouped into universes of 512 
+channels each.  This gives 6144/512 = 12 universes. See the 
+`E.13 documentation <https://www.doityourselfchristmas.com/wiki/index.php?title=E1.31_(Streaming-ACN)_Protocol#Configuring_Sequencing_Software_to_use_E1.31_Output>`_ 
+for more details.
+
+Your setup should look like :ref:`case_xlights_setup_done`.  Click the
+*Save Setup* button to save.
+
+.. _case_xlights_setup_done:
+
+xLights setup for P5 display
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/xlights_setup_done.png
+   :align: center
+   :alt: xLights setup for P5 display
+
+Next click on the **Layout** tab.  Click on the *Matrix* button as shown in 
+:ref:`case_xlights_matrix`, then click on the black area where you want your 
+matrix to appear.
+
+.. _case_xlights_matrix:
+
+Setting up the Matrix Layout
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/xlights_layout.png
+   :align: center
+   :alt: Setting up the Matrix Layout
+
+:ref:`case_xlights_layout_details` shows the setting to use for the P5 matrix. 
+
+.. _case_xlights_layout_details:
+
+Layout details for P5 matrix
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/xlights_layout_details.png
+   :align: center
+   :alt: Layout details for P5 matrix
+
+All I changed was **# Strings**, **Nodes/String**, **Starting Location** and most 
+importantly, expand **String Properties** and select at **String Type** of 
+**RGB Nodes**.  Above the setting you should see that **Start Chan** is 1 and 
+the **End Chan** is 6144, which is the total number of individual LEDs (3*63*32). 
+xLights now knows we are working with a P5 matrix, now on to the sequencer. 
+
+Now click on the *Sequencer* tab and then click on the **New Sequence** button
+(:ref:`case_seq_new`).
+
+.. _case_seq_new:
+
+Starting a new sequence
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/xlights_seq_new.png
+   :align: center
+   :alt: Starting a new sequence
+
+Then click on **Animation**, **20fps (50ms)**, and **Quick Start**. Learning how to 
+do sequences is beyond the scope of this cookbook, however I'll shown you how
+do simple sequence just to be sure xLights is talking to the Bone.
+
+Setting Up E1.31 on the Bone
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+First we need to setup FPP to take input from xLights.  Do this by going to 
+the *Input/Output Setup* menu and selecting *Channel Inputs*.  Then 
+enter *12* for *Universe Count* and click *set* and you will see 
+:ref:`case_inputs_setup`.
+
+.. _case_inputs_setup:
+
+E1.31 Inputs
+~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_inputs_setup.png
+   :align: center
+   :alt: .E1.31 Inputs
+
+Click on the **Save** button above the table.  
+
+Then go to the **Status/Control** menu and select **Status Page**.  
+
+.. TODO  update this
+
+.. _case_mode_bridge:
+
+Bridge Mode
+~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_mode_bridge.png
+   :align: center
+   :alt: Bridge Mode
+
+Testing the xLights Connection
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Bone is now listening for commands from xLights via the E1.31 protocol.
+A quick way to verify everything is t o return to xLights and go to the 
+*Tools* menu and select **Test** (:ref:`case_xlights_test`).  
+
+.. _case_xlights_test:
+
+xLights test page
+~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/xlights_test.png
+   :align: center
+   :alt: xLights test page
+
+Click the box under **Select channels...**, click **Output to lights** and 
+select **Twinkle 50%**.  You matrix should have a colorful twinkle pattern
+(:ref:`case_xlights_twinkle`).
+
+.. _case_xlights_twinkle:
+
+xLights Twinkle test pattern
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/xlights_twinkle.jpg
+   :align: center
+   :alt: xLights Twinkle test pattern
+
+A Simple xLights Sequence
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now that the xLights to FPP link is tested you can generate a sequence to 
+play.  Close the Test window and click on the **Sequencer** tab.  Then drag 
+an effect from the **Effects** box to the timeline that below it.  Drop it to 
+the right of the **Matrix** label (:ref:`case_seq_drag`).  The click 
+*Output To Lights* which is the yellow lightbulb to the right on the top 
+toolbar.  Your matrix should now be displaying your effect.
+
+.. _case_seq_drag:
+
+Drag an effect to the timeline
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/xlights_seq_drag.png
+   :align: center
+   :alt: Drag an effect to the timeline
+
+The setup requires the host computer to send the animation data to the Bone. 
+The next section shows how to save the sequence and play it on the Bone 
+standalone.
+
+Saving a Sequence and Playing it Standalone
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In xLights save your sequence by hitting Ctrl-S and giving it a name.  I called 
+mine *fire* since I used a fire effect.  Now, switch back to FPP and select 
+the *Content Setup* menu and select *File Manager*.  Click the black
+*Select Files* button and select your sequence file that ends in *.fseq*
+(:ref:`case_file_manager`).
+
+.. _case_file_manager:
+
+FPP file manager
+~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_file_manager.png
+   :align: center
+   :alt: FPP file manager
+
+Once your sequence is uploaded, got to **Content Steup** and select **Playlists**. 
+Enter you playlist name (I used **fire**) and click **Add**.  Then click
+**Add a Sequence/Entry** and select **Sequence Only** 
+(:ref:`case_playlist`), then click **Add**. 
+
+.. _case_playlist:
+
+Adding a new playlist to FPP
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_playlist.png
+   :align: center
+   :alt: Adding a new playlist to FPP
+
+Be sure to click **Save Playlist** on the right. Now return to 
+**Status/Control** and **Status Page** and make sure **FPPD Mode:** is set 
+to **Standalone**.  You should see your playlist.  Click the **Play** 
+button and your sequence will play.
+
+.. _case_playlist_status:
+
+Adding a new playlist to FPP
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/fpp_playlist_status.png
+   :align: center
+   :alt: Playing a playlist
+
+The beauty of the PRU is that the Beagle can play a detailed sequence at 
+20 frames per second and the ARM procossor is only 15% used.  The PRUs 
+are doing all the work.
+
+simpPRU -- A python-like language for programming the PRUs 
+-----------------------------------------------------------
+
+`simpPRU <https://github.com/VedantParanjape/simpPRU>`_ is a simple, python-like 
+programming languge designed to make programming the PRUs easy. 
+It has detailed `documentation <https://simppru.readthedocs.io/en/latest/>`_ and
+many `examples <https://simppru.readthedocs.io/en/latest/examples/digital_read/>`_.
+
+.. admonition:: information
+
+   simpPRU is a procedural programming language that is statically typed. 
+   Variables and functions must be assigned data types during compilation.
+   It is typesafe, and data types of variables are decided during compilation.
+   simPRU codes have a +.sim+ extension.
+   simpPRU provides a console app to use Remoteproc functionality.
+
+   https://simppru.readthedocs.io/en/latest/
+
+You can `build simpPRU <https://simppru.readthedocs.io/en/latest/install/build/>`_ from
+source, more easily just `install it <https://simppru.readthedocs.io/en/latest/install/install/>`_. 
+On the Beagle run:
+
+.. code-block:: bash
+
+   bone$ wget https://github.com/VedantParanjape/simpPRU/releases/download/1.4/simppru-1.4-armhf.deb
+   bone$ sudo dpkg -i simppru-1.4-armhf.deb
+   bone$ sudo apt update
+   bone$ sudo apt install gcc-pru
+
+Now, suppose you wanted to run the 
+`LED blink <https://simppru.readthedocs.io/en/latest/examples/led_blink/>`_
+example which is reproduced here.
+
+LED Blink (blink.sim)
+~~~~~~~~~~~~~~~~~~~~~
+
+:download:`blink.sim <code/blink.sim>`
+
+Just run simppru
+
+.. code-block:: bash
+
+   bone$ simppru blink.sim --load 
+   Detected TI AM335x PocketBeagle
+   inside while
+   [4] : setting P1_31 as output
+
+   Current mode for P1_31 is:     pruout
+
+Detected TI AM335x PocketBeagle
+--------------------------------
+
+The +--load+ flag caused the compiled code to be copied to +/lib/firmware+.
+To start just do:
+
+.. code-block:: bash
+
+   bone$ cd /dev/remoteproc/pruss-core0/
+   bone$ ls
+   device  firmware  name  power  state  subsystem  uevent
+   bone$ echo start > state
+   bone$ cat state
+   running
+
+Your LED should now be blinking.
+
+Check out the many examples (https://simppru.readthedocs.io/en/latest/examples/led_blink/).
+
+simpPRU Examples
+~~~~~~~~~~~~~~~~
+
+.. figure:: figures/LEDblink.png
+   :align: center
+   :alt: simpPRU Examples
+
+
+MachineKit
+-----------
+
+`MachineKit <http://www.machinekit.io/>`_ is a platform for machine control 
+applications.  It can control machine tools, robots, or other automated devices. It can control servo 
+motors, stepper motors, relays, and other devices related to machine tools.
+
+.. admonition:: information
+
+   Machinekit is portable across a wide range of hardware platforms and real-time environments, 
+   and delivers excellent performance at low cost. It is based on the HAL component architecture, 
+   an intuitive and easy to use circuit model that includes over 150 building blocks for digital logic, 
+   motion, control loops, signal processing, and hardware drivers. Machinekit supports local and 
+   networked UI options, including ubiquitous platforms like phones or tablets.
+
+   http://www.machinekit.io/about/
+
+ArduPilot
+----------
+`ArduPilot <http://ardupilot.org/>`_ is a open source autopilot system supporting 
+multi-copters, traditional helicopters, fixed wing aircraft and rovers. ArduPilot runs on a many 
+`hardware platforms <http://ardupilot.org/copter/docs/common-autopilots.html>`_ including the
+`BeagleBone Black <http://ardupilot.org/dev/docs/building-for-beaglebone-black-on-linux.html#building-for-beaglebone-black-on-linux>`_ and the 
+`BeagleBone Blue <http://ardupilot.org/copter/docs/common-beagle-bone-blue.html>`_.
+
+
+
+.. admonition:: information
+
+   Ardupilot is the most advanced, full-featured and reliable open source autopilot software available. 
+   It has been developed over 5+ years by a team of diverse professional engineers and computer scientists. 
+   It is the only autopilot software capable of controlling any vehicle system imaginable, from conventional 
+   airplanes, multirotors, and helicopters, to boats and even submarines. And now being expanded to feature 
+   support for new emerging vehicle types such as quad-planes and compound helicopters.
+
+   Installed in over 1,000,000 vehicles world-wide, and with its advanced data-logging, analysis 
+   and simulation tools, Ardupilot is the most tested and proven autopilot software. The open-source 
+   code base means that it is rapidly evolving, always at the cutting edge of technology development. 
+   With many peripheral suppliers creating interfaces, users benefit from a broad ecosystem of sensors, 
+   companion computers and communication systems. Finally, since the source code is open, it can be 
+   audited to ensure compliance with security and secrecy requirements.
+
+   The software suite is installed in aircraft from many OEM UAV companies, such as 3DR, jDrones, 
+   PrecisionHawk, AgEagle and Kespry. It is also used for testing and development by several large 
+   institutions and corporations such as NASA, Intel and Insitu/Boeing, as well as countless 
+   colleges and universities around the world.
+
+   http://www.machinekit.io/about/
diff --git a/pru-cookbook/01case/code/blink.sim b/pru-cookbook/01case/code/blink.sim
new file mode 100644
index 0000000000000000000000000000000000000000..212a21689e76170ad44112b926a0c4300e0c03a4
--- /dev/null
+++ b/pru-cookbook/01case/code/blink.sim
@@ -0,0 +1,7 @@
+/* From: https://simppru.readthedocs.io/en/latest/examples/led_blink/ */
+while : 1 == 1 {
+    digital_write(P1_31, true);
+    delay(250);     /* Delay 250 ms */
+    digital_write(P1_31, false);
+    delay(250);
+}
diff --git a/pru-cookbook/01case/code/circle.py b/pru-cookbook/01case/code/circle.py
new file mode 100755
index 0000000000000000000000000000000000000000..1feb41cc089af343f1f2c490deef92853965bee4
--- /dev/null
+++ b/pru-cookbook/01case/code/circle.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+
+"""A demo client for Open Pixel Control
+http://github.com/zestyping/openpixelcontrol
+
+Runs an LED around in a circle
+
+"""
+
+import time
+import opc
+
+ADDRESS = 'localhost:7890'
+
+# Create a client object
+client = opc.Client(ADDRESS)
+
+# Test if it can connect
+if client.can_connect():
+    print('connected to %s' % ADDRESS)
+else:
+    # We could exit here, but instead let's just print a warning
+    # and then keep trying to send pixels in case the server
+    # appears later
+    print('WARNING: could not connect to %s' % ADDRESS)
+
+# Send pixels forever
+STR_LEN=16
+for i in range(STR_LEN):
+    leds = [(0, 0, 0)] * STR_LEN
+leds[0] = (0, 127, 0)
+
+while True:
+    tmp = leds[0]
+    for i in range(STR_LEN-1):
+        leds[i] = leds[i+1]
+    leds[-1] = tmp
+    if client.put_pixels(leds, channel=0):
+        print('sent')
+    else:
+        print('not connected')
+    time.sleep(0.1)
+
diff --git a/pru-cookbook/01case/code/e1.31-test.py b/pru-cookbook/01case/code/e1.31-test.py
new file mode 100755
index 0000000000000000000000000000000000000000..6016c9eb9e879a6d21f8ccf8fd20ed32bd4c45b3
--- /dev/null
+++ b/pru-cookbook/01case/code/e1.31-test.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python3
+# Controls a NeoPixel (WS2812) string via E1.31 and FPP
+# https://pypi.org/project/sacn/
+# https://github.com/FalconChristmas/fpp/releases
+import sacn
+import time
+
+# provide an IP-Address to bind to if you are using Windows and want to use multicast
+sender = sacn.sACNsender("192.168.7.1")
+sender.start()							# start the sending thread
+sender.activate_output(1)		# start sending out data in the 1st universe
+sender[1].multicast = False # set multicast to True
+sender[1].destination = "192.168.7.2"  # or provide unicast information.
+sender.manual_flush = True # turning off the automatic sending of packets
+# Keep in mind that if multicast is on, unicast is not used
+LEDcount = 24
+# Have green fade is as it goes
+data = []
+for i in range(LEDcount):
+	data.append(0)		# Red
+	data.append(i)		# Green
+	data.append(0)		# Blue
+sender[1].dmx_data = data
+sender.flush()
+time.sleep(0.5)
+
+# Turn off all LEDs
+data=[]
+for i in range(3*LEDcount):
+	data.append(0)
+sender.flush()
+sender[1].dmx_data = data
+time.sleep(0.5)
+
+# Have red fade in
+data = []
+for i in range(LEDcount):
+	data.append(i)
+	data.append(0)
+	data.append(0)
+sender[1].dmx_data = data
+sender.flush()
+time.sleep(0.25)
+
+# Make LED circle 5 times
+for j in range(15):
+	for i in range(LEDcount-1):
+		data[3*i+0] = 0
+		data[3*i+1] = 0
+		data[3*i+2] = 0
+		data[3*i+3] = 0
+		data[3*i+4] = 64
+		data[3*i+5] = 0
+		sender[1].dmx_data = data
+		sender.flush()
+		time.sleep(0.02)
+# Wrap around
+	i = LEDcount-1
+	data[0] = 0
+	data[1] = 64
+	data[2] = 0
+	data[3*i+0] = 0
+	data[3*i+1] = 0
+	data[3*i+2] = 0
+	sender[1].dmx_data = data
+	sender.flush()
+	time.sleep(0.02)
+    
+time.sleep(2)  # send the data for 10 seconds
+sender.stop()  # do not forget to stop the sender
diff --git a/pru-cookbook/01case/code/encoder_setup.sh b/pru-cookbook/01case/code/encoder_setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ffc4ad68842fb6314173b523425295893cd05fc1
--- /dev/null
+++ b/pru-cookbook/01case/code/encoder_setup.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# Configure the pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+
+# Configure eQEP pins
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P9_92 P9_27 P8_35 P8_33 P8_12 P8_11 P8_41 P8_42"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P1_31 P2_34 P2_10 P2_24 P2_33"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin qep
+    config-pin -q $pin
+done
+
+##########################################
+# Configure PRU pins
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P8_16 P8_15"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P2_09 P2_18"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin pruin
+    config-pin -q $pin
+done
diff --git a/pru-cookbook/01case/code/fire.fseq b/pru-cookbook/01case/code/fire.fseq
new file mode 100644
index 0000000000000000000000000000000000000000..4bad5ae76476a87bb7bb71e853e3412b1fc63f29
Binary files /dev/null and b/pru-cookbook/01case/code/fire.fseq differ
diff --git a/pru-cookbook/01case/code/logic_install.sh b/pru-cookbook/01case/code/logic_install.sh
new file mode 100644
index 0000000000000000000000000000000000000000..7fb76122b55b55da9e50ea2a084b1242b8e30b78
--- /dev/null
+++ b/pru-cookbook/01case/code/logic_install.sh
@@ -0,0 +1,34 @@
+# Instructions for installing BeagleLogic
+# https://beaglelogic.readthedocs.io/en/latest/index.html
+# From: https://github.com/abhishek-kakkar/BeagleLogic/wiki
+
+# beaglelogic is installed on the 4.9 kernel, but not the 4.14, so
+# if you are running 4.14, switch to 4.9
+sudo /opt/scripts/tools/update_kernel.sh --lts-4_9
+sudo reboot
+
+git clone https://github.com/abhishek-kakkar/BeagleLogic
+cd BeagleLogic
+sudo ./install.sh
+sudo reboot
+
+# Now the kernel driver headers
+sudo apt install linux-headers-`uname -r`
+
+modinfo beaglelogic
+modprobe beaglelogic
+
+# From: https://beaglelogic.readthedocs.io/en/latest
+
+# Here's what works from abhishek
+git clone https://github.com/abhishek-kakkar/BeagleLogic
+cd BeagleLogic
+# 1. Get the dts file from this gist (https://gist.github.com/abhishek-kakkar/0761ef7b10822cff4b3efd194837f49c)
+
+# 2. cd to 'BeagleLogic/kernel' directory. Put the dts file there. (edited)
+# 3. Run 'make overlay'
+# 4. Run 'sudo cp -v beaglelogic-00A0.dtbo /lib/firmware/' (edited)
+# 5. Run 'sudo update-initramfs -u -k ``uname -r``' (edited)
+# (single backticks only, apparently Slack treats single backtick as code) (edited)
+# 6. Reboot
+# 7. Browse to bone:4000
diff --git a/pru-cookbook/01case/code/main_pru1.c b/pru-cookbook/01case/code/main_pru1.c
new file mode 100644
index 0000000000000000000000000000000000000000..8d751b3e65e06a8dd4e47c9ef6f28f370d60ca24
--- /dev/null
+++ b/pru-cookbook/01case/code/main_pru1.c
@@ -0,0 +1,53 @@
+/*
+ * Source Modified by Zubeen Tolani < ZeekHuge - zeekhuge@gmail.com >
+ * Based on the examples distributed by TI
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *	* Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ *
+ *	* Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the
+ *	  distribution.
+ *
+ *	* Neither the name of Texas Instruments Incorporated nor the names of
+ *	  its contributors may be used to endorse or promote products derived
+ *	  from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+				  
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_pru1.h"
+
+// The function is defined in pru1_asm_blinky.asm in same dir
+// We just need to add a declaration here, the defination can be
+// seperately linked
+extern void start(void);
+
+void main(void)
+{
+    /* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	start();
+}
+
diff --git a/pru-cookbook/01case/code/my-config.json b/pru-cookbook/01case/code/my-config.json
new file mode 100644
index 0000000000000000000000000000000000000000..d1534cfff15f46bbabb10068c01542bb721583c4
--- /dev/null
+++ b/pru-cookbook/01case/code/my-config.json
@@ -0,0 +1,19 @@
+{
+	"outputMode": "ws281x",
+	"outputMapping": "original-ledscape",
+	"demoMode": "fade",
+	"ledsPerStrip": 16,
+	"usedStripCount": 1,
+	"colorChannelOrder": "BRG",
+	"opcTcpPort": 7890,
+	"opcUdpPort": 7890,
+	"enableInterpolation": false,
+	"enableDithering": false,
+	"enableLookupTable": true,
+	"lumCurvePower": 2.0000,
+	"whitePoint": {
+		"red": 0.9000,
+		"green": 1.0000,
+		"blue": 1.0000
+	}
+}
diff --git a/pru-cookbook/01case/code/opc.py b/pru-cookbook/01case/code/opc.py
new file mode 100755
index 0000000000000000000000000000000000000000..36a3bbd6b76e7ff8e6660ea7b163da2271bbe696
--- /dev/null
+++ b/pru-cookbook/01case/code/opc.py
@@ -0,0 +1,177 @@
+#!/usr/bin/env python
+
+"""Python Client library for Open Pixel Control
+http://github.com/zestyping/openpixelcontrol
+
+Sends pixel values to an Open Pixel Control server to be displayed.
+http://openpixelcontrol.org/
+
+Recommended use:
+
+    import opc
+
+    # Create a client object
+    client = opc.Client('localhost:7890')
+
+    # Test if it can connect (optional)
+    if client.can_connect():
+        print('connected to %s' % ADDRESS)
+    else:
+        # We could exit here, but instead let's just print a warning
+        # and then keep trying to send pixels in case the server
+        # appears later
+        print('WARNING: could not connect to %s' % ADDRESS)
+
+    # Send pixels forever at 30 frames per second
+    while True:
+        my_pixels = [(255, 0, 0), (0, 255, 0), (0, 0, 255)]
+        if client.put_pixels(my_pixels, channel=0):
+            print('...')
+        else:
+            print('not connected')
+        time.sleep(1/30.0)
+
+"""
+
+import socket
+import struct
+import sys
+
+SET_PIXEL_COLOURS = 0  # "Set pixel colours" command (see openpixelcontrol.org)
+
+
+class Client(object):
+    def __init__(self, server_ip_port, long_connection=True, verbose=False):
+        """Create an OPC client object which sends pixels to an OPC server.
+
+        server_ip_port should be an ip:port or hostname:port as a single string.
+        For example: '127.0.0.1:7890' or 'localhost:7890'
+
+        There are two connection modes:
+        * In long connection mode, we try to maintain a single long-lived
+          connection to the server.  If that connection is lost we will try to
+          create a new one whenever put_pixels is called.  This mode is best
+          when there's high latency or very high framerates.
+        * In short connection mode, we open a connection when it's needed and
+          close it immediately after.  This means creating a connection for each
+          call to put_pixels. Keeping the connection usually closed makes it
+          possible for others to also connect to the server.
+
+        A connection is not established during __init__.  To check if a
+        connection will succeed, use can_connect().
+
+        If verbose is True, the client will print debugging info to the console.
+
+        """
+        self.verbose = verbose
+
+        self._long_connection = long_connection
+
+        self._ip, self._port = server_ip_port.split(':')
+        self._port = int(self._port)
+
+        self._socket = None  # will be None when we're not connected
+
+    def _debug(self, m):
+        if self.verbose:
+            print('    %s' % str(m))
+
+    def _ensure_connected(self):
+        """Set up a connection if one doesn't already exist.
+
+        Return True on success or False on failure.
+
+        """
+        if self._socket:
+            self._debug('_ensure_connected: already connected, doing nothing')
+            return True
+
+        try:
+            self._debug('_ensure_connected: trying to connect...')
+            self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            self._socket.settimeout(1)
+            self._socket.connect((self._ip, self._port))
+            self._debug('_ensure_connected:    ...success')
+            return True
+        except socket.error:
+            self._debug('_ensure_connected:    ...failure')
+            self._socket = None
+            return False
+
+    def disconnect(self):
+        """Drop the connection to the server, if there is one."""
+        self._debug('disconnecting')
+        if self._socket:
+            self._socket.close()
+        self._socket = None
+
+    def can_connect(self):
+        """Try to connect to the server.
+
+        Return True on success or False on failure.
+
+        If in long connection mode, this connection will be kept and re-used for
+        subsequent put_pixels calls.
+
+        """
+        success = self._ensure_connected()
+        if not self._long_connection:
+            self.disconnect()
+        return success
+
+    def put_pixels(self, pixels, channel=0):
+        """Send the list of pixel colors to the OPC server on the given channel.
+
+        channel: Which strand of lights to send the pixel colors to.
+            Must be an int in the range 0-255 inclusive.
+            0 is a special value which means "all channels".
+
+        pixels: A list of 3-tuples representing rgb colors.
+            Each value in the tuple should be in the range 0-255 inclusive. 
+            For example: [(255, 255, 255), (0, 0, 0), (127, 0, 0)]
+            Floats will be rounded down to integers.
+            Values outside the legal range will be clamped.
+
+        Will establish a connection to the server as needed.
+
+        On successful transmission of pixels, return True.
+        On failure (bad connection), return False.
+
+        The list of pixel colors will be applied to the LED string starting
+        with the first LED.  It's not possible to send a color just to one
+        LED at a time (unless it's the first one).
+
+        """
+        self._debug('put_pixels: connecting')
+        is_connected = self._ensure_connected()
+        if not is_connected:
+            self._debug('put_pixels: not connected.  ignoring these pixels.')
+            return False
+
+        # build OPC message
+        command = SET_PIXEL_COLOURS
+        header = struct.pack('>BBH', channel, SET_PIXEL_COLOURS, len(pixels)*3)
+        pieces = [struct.pack(
+                      'BBB',
+                      min(255, max(0, int(r))),
+                      min(255, max(0, int(g))),
+                      min(255, max(0, int(b)))
+                  ) for r, g, b in pixels]
+        if bytes is str:
+            message = header + ''.join(pieces)
+        else:
+            message = header + b''.join(pieces)
+
+        self._debug('put_pixels: sending pixels to server')
+        try:
+            self._socket.send(message)
+        except socket.error:
+            self._debug('put_pixels: connection lost.  could not send pixels.')
+            self._socket = None
+            return False
+
+        if not self._long_connection:
+            self._debug('put_pixels: disconnecting')
+            self.disconnect()
+
+        return True
diff --git a/pru-cookbook/01case/code/pru1-servo.asm b/pru-cookbook/01case/code/pru1-servo.asm
new file mode 100644
index 0000000000000000000000000000000000000000..c8e66e5234214137be6c7f7a781083c21061190e
--- /dev/null
+++ b/pru-cookbook/01case/code/pru1-servo.asm
@@ -0,0 +1,162 @@
+;*
+;* Copyright (C) 2016 Zubeen Tolani <ZeekHuge - zeekhuge@gmail.com>
+;*
+;* This file is as an example to show how to develope
+;* and compile inline assembly code for PRUs
+;*
+;* This program is free software; you can redistribute it and/or modify
+;* it under the terms of the GNU General Public License version 2 as
+;* published by the Free Software Foundation.
+
+
+	.cdecls "main_pru1.c"
+
+DELAY	.macro time, reg
+	LDI32	reg, time
+	QBEQ	$E?, reg, 0
+$M?:	SUB	reg, reg, 1
+	QBNE	$M?, reg, 0
+$E?:	
+	.endm
+	
+
+	.clink
+	.global start
+start:
+	LDI 	R30, 0xFFFF
+	DELAY 	10000000, r11
+	LDI		R30, 0x0000
+	DELAY 	10000000, r11
+; 	JMP	start	
+
+; 	HALT
+
+
+; these pin definitions are specific to SD-101C Robotics Cape
+    .asg    r30.t8,     CH1BIT  ; P8_27
+	.asg    r30.t10,    CH2BIT	; P8_28
+	.asg    r30.t9,     CH3BIT	; P8_29
+	.asg	r30.t11,	CH4BIT	; P8_30
+	.asg	r30.t6,		CH5BIT	; P8_39
+	.asg	r30.t7,		CH6BIT	; P8_40
+	.asg	r30.t4,		CH7BIT	; P8_41
+	.asg	r30.t5,		CH8BIT	; P8_42
+
+	.asg    C4,     CONST_SYSCFG         
+	.asg    C28,    CONST_PRUSHAREDRAM   
+ 
+	.asg	0x22000,	PRU0_CTRL
+	.asg    0x24000,    PRU1_CTRL       ; page 19
+	.asg    0x28,       CTPPR0          ; page 75
+ 
+	.asg	0x000,	OWN_RAM
+	.asg	0x020,	OTHER_RAM
+	.asg    0x100,	SHARED_RAM       ; This is so prudebug can find it.
+
+	LBCO	&r0, CONST_SYSCFG, 4, 4		; Enable OCP master port
+	CLR 	r0, r0, 4					; Clear SYSCFG[STANDBY_INIT] to enable OCP master port
+	SBCO	&r0, CONST_SYSCFG, 4, 4
+	
+; Configure the programmable pointer register for PRU0 by setting c28_pointer[15:0]
+	LDI     r0, SHARED_RAM              ; Set C28 to point to shared RAM
+	LDI32   r1, PRU1_CTRL + CTPPR0		; Note we use beginning of shared ram unlike example which
+	SBBO    &r0, r1, 0, 4				;  page 25
+	
+	LDI		r9, 0x0				; erase r9 to use to use later
+	
+	LDI 	r0, 0x0				; clear internal counters
+	LDI 	r1, 0x0	
+	LDI 	r2, 0x0
+	LDI 	r3, 0x0
+	LDI 	r4, 0x0
+	LDI 	r5, 0x0
+	LDI 	r6, 0x0
+	LDI32 	r7, 0x0
+	LDI 	r30, 0x0				; turn off GPIO outputs
+	
+
+; Beginning of loop, should always take 48 instructions to complete
+CH1:			
+	QBEQ	CLR1, r0, 0						; If timer is 0, jump to clear channel
+	SET		r30, CH1BIT						; If non-zero turn on the corresponding channel
+	SUB		r0, r0, 1						; Subtract one from timer
+	CLR		r9, r9.t1						; waste a cycle for timing
+	SBCO	&r9, CONST_PRUSHAREDRAM, 0, 4	; write 0 to shared memory
+CH2:			
+	QBEQ	CLR2, r1, 0
+	SET		r30, CH2BIT
+	SUB		r1, r1, 1
+	CLR		r9, r9.t1
+	SBCO	&r9, CONST_PRUSHAREDRAM, 4, 4
+CH3:			
+	QBEQ	CLR3, r2, 0
+	SET		r30, CH3BIT
+	SUB		r2, r2, 1
+	CLR		r9, r9.t1
+	SBCO	&r9, CONST_PRUSHAREDRAM, 8, 4
+CH4:			
+	QBEQ	CLR4, r3, 0
+	SET		r30, CH4BIT
+	SUB		r3, r3, 1
+	CLR		r9, r9.t1
+	SBCO	&r9, CONST_PRUSHAREDRAM, 12, 4
+CH5:			
+	QBEQ	CLR5, r4, 0
+	SET		r30, CH5BIT
+	SUB		r4, r4, 1
+	CLR		r9, r9.t1
+	SBCO	&r9, CONST_PRUSHAREDRAM, 16, 4
+CH6:			
+	QBEQ	CLR6, r5, 0
+	SET		r30, CH6BIT
+	SUB		r5, r5, 1
+	CLR		r9, r9.t1
+	SBCO	&r9, CONST_PRUSHAREDRAM, 20, 4
+CH7:			
+	QBEQ	CLR7, r6, 0
+	SET		r30, CH7BIT
+	SUB		r6, r6, 1
+	CLR		r9, r9.t1
+	SBCO	&r9, CONST_PRUSHAREDRAM, 24, 4
+CH8:			
+	QBEQ	CLR8, r7, 0
+	SET		r30, CH8BIT
+	SUB		r7, r7, 1
+	SBCO	&r9, CONST_PRUSHAREDRAM, 28, 4
+
+	QBA		CH1								; return to beginning of loop
+	; no need to waste a cycle for timing here because of the QBA above
+	
+		
+CLR1:
+	CLR		r30, CH1BIT						; turn off the corresponding channel
+	LBCO	&r0, CONST_PRUSHAREDRAM, 0, 4	; Load new timer register
+	QBA		CH2
+CLR2:
+	CLR		r30, CH2BIT
+	LBCO	&r1, CONST_PRUSHAREDRAM, 4, 4
+	QBA		CH3
+CLR3:
+	CLR		r30, CH3BIT
+	LBCO	&r2, CONST_PRUSHAREDRAM, 8, 4
+	QBA		CH4
+CLR4:
+	CLR		r30, CH4BIT
+	LBCO	&r3, CONST_PRUSHAREDRAM, 12, 4
+	QBA		CH5
+CLR5:
+	CLR		r30, CH5BIT
+	LBCO	&r4, CONST_PRUSHAREDRAM, 16, 4
+	QBA		CH6
+CLR6:
+	CLR		r30, CH6BIT
+	LBCO	&r5, CONST_PRUSHAREDRAM, 20, 4
+	QBA		CH7
+CLR7:
+	CLR		r30, CH7BIT
+	LBCO	&r6, CONST_PRUSHAREDRAM, 24, 4
+	QBA		CH8
+CLR8:
+	CLR		r30, CH8BIT
+	LBCO	&r7, CONST_PRUSHAREDRAM, 28, 4
+	QBA		CH1								; return to beginning of loop
diff --git a/pru-cookbook/01case/code/servo-test.c b/pru-cookbook/01case/code/servo-test.c
new file mode 100644
index 0000000000000000000000000000000000000000..1f94e274e573223dcf84b4bd111f9a3df16ac867
--- /dev/null
+++ b/pru-cookbook/01case/code/servo-test.c
@@ -0,0 +1,84 @@
+/* 
+ *
+ *  servo tester
+ *  (c) Copyright 2016
+ *  Mark A. Yoder, 20-July-2016
+ *
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include "robotics_cape_defs.h"
+
+#define PRU_ADDR		0x4A300000		// Start of PRU memory Page 184 am335x TRM
+#define PRU_LEN			0x80000			// Length of PRU memory
+#define PRU_SHAREDMEM	0x10000			// Offset to shared memory
+
+unsigned int	*prusharedMem_32int_ptr;	// Points to the start of the shared memory
+
+/*******************************************************************************
+* int send_servo_pulse_us(int ch, int us)
+* 
+* Sends a single pulse of duration us (microseconds) to a single channel (ch)
+*******************************************************************************/
+int send_servo_pulse_us(int ch, int us) {
+	// Sanity Checks
+	if(ch<1 || ch>SERVO_CHANNELS){
+		printf("ERROR: Servo Channel must be between 1&%d\n", SERVO_CHANNELS);
+		return -1;
+	} if(prusharedMem_32int_ptr == NULL){
+		printf("ERROR: PRU servo Controller not initialized\n");
+		return -1;
+	}
+	// PRU runs at 200Mhz. find #loops needed
+	unsigned int num_loops = ((us*200.0)/PRU_SERVO_LOOP_INSTRUCTIONS); 
+	// printf("num_loops: %d\n", num_loops);
+	// write to PRU shared memory
+	prusharedMem_32int_ptr[ch-1] = num_loops;
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	unsigned int	*pru;		// Points to start of PRU memory.
+	int	fd;
+	printf("Servo tester\n");
+	
+	fd = open ("/dev/mem", O_RDWR | O_SYNC);
+	if (fd == -1) {
+		printf ("ERROR: could not open /dev/mem.\n\n");
+		return 1;
+	}
+	pru = mmap (0, PRU_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, PRU_ADDR);
+	if (pru == MAP_FAILED) {
+		printf ("ERROR: could not map memory.\n\n");
+		return 1;
+	}
+	close(fd);
+	printf ("Using /dev/mem.\n");
+	
+	prusharedMem_32int_ptr = pru + PRU_SHAREDMEM/4;	// Points to start of shared memory
+
+	// while(1) {
+	// 	printf("value to store: ");
+	// 	scanf("%d", &value);
+	// 	printf("Storing: %d in %lx\n", value, addr);
+	// 	pru[addr/4] = value;
+	// }
+	
+	int i;
+	while(1) {
+		for(i=1; i<=SERVO_CHANNELS; i++) {
+			send_servo_pulse_us(i, 10*i);
+		}
+		usleep(200);
+	}
+	
+	if(munmap(pru, PRU_LEN)) {
+		printf("munmap failed\n");
+	} else {
+		printf("munmap succeeded\n");
+	}
+}
+
diff --git a/pru-cookbook/01case/code/servos_setup.sh b/pru-cookbook/01case/code/servos_setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..330e8f34e30d7fd97d9368861ded65817222e903
--- /dev/null
+++ b/pru-cookbook/01case/code/servos_setup.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P8_27 P8_28 P8_29 P8_30 P8_39 P8_40 P8_41 P8_42"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P2_35 P1_35 P1_02 P1_04"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin pruout
+    config-pin -q $pin
+done
\ No newline at end of file
diff --git a/pru-cookbook/01case/figures/LEDblink.png b/pru-cookbook/01case/figures/LEDblink.png
new file mode 100644
index 0000000000000000000000000000000000000000..793795c761196f2d92ee22b590f81693433b5646
Binary files /dev/null and b/pru-cookbook/01case/figures/LEDblink.png differ
diff --git a/pru-cookbook/01case/figures/beaglelogic_capture.png b/pru-cookbook/01case/figures/beaglelogic_capture.png
new file mode 100644
index 0000000000000000000000000000000000000000..afa771caec1d7b66ba59f0bc6d649ba010fad9e8
Binary files /dev/null and b/pru-cookbook/01case/figures/beaglelogic_capture.png differ
diff --git a/pru-cookbook/01case/figures/blue.png b/pru-cookbook/01case/figures/blue.png
new file mode 100644
index 0000000000000000000000000000000000000000..035b5d3b9b46fc97e145c28505181de6d5f46091
Binary files /dev/null and b/pru-cookbook/01case/figures/blue.png differ
diff --git a/pru-cookbook/01case/figures/fpp_channel_inputs.png b/pru-cookbook/01case/figures/fpp_channel_inputs.png
new file mode 100644
index 0000000000000000000000000000000000000000..ef0c191bcc35eb63ccc868b84a7993555cc581aa
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_channel_inputs.png differ
diff --git a/pru-cookbook/01case/figures/fpp_channel_outputs.png b/pru-cookbook/01case/figures/fpp_channel_outputs.png
new file mode 100644
index 0000000000000000000000000000000000000000..8b2658b766080bac7457ebfd4db479f06e54a1f4
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_channel_outputs.png differ
diff --git a/pru-cookbook/01case/figures/fpp_channel_outputs_menu.png b/pru-cookbook/01case/figures/fpp_channel_outputs_menu.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f3984c868401454ee98e4dccfba2244bff5971a
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_channel_outputs_menu.png differ
diff --git a/pru-cookbook/01case/figures/fpp_channel_outputs_strings.png b/pru-cookbook/01case/figures/fpp_channel_outputs_strings.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f6ab170207cee07848cd1a3aa80a89b70d9d94f
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_channel_outputs_strings.png differ
diff --git a/pru-cookbook/01case/figures/fpp_display_testing.png b/pru-cookbook/01case/figures/fpp_display_testing.png
new file mode 100644
index 0000000000000000000000000000000000000000..515781eaf4dcc076ab6ab633c99629ccd42ad259
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_display_testing.png differ
diff --git a/pru-cookbook/01case/figures/fpp_display_testing2.png b/pru-cookbook/01case/figures/fpp_display_testing2.png
new file mode 100644
index 0000000000000000000000000000000000000000..78a6ba07115dfe5dec7fcc9321192ba8bac63ed0
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_display_testing2.png differ
diff --git a/pru-cookbook/01case/figures/fpp_display_testing_menu.png b/pru-cookbook/01case/figures/fpp_display_testing_menu.png
new file mode 100644
index 0000000000000000000000000000000000000000..6cb7b134f663162ddac1c6f1bbd8986eab06336b
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_display_testing_menu.png differ
diff --git a/pru-cookbook/01case/figures/fpp_display_testing_menu2.png b/pru-cookbook/01case/figures/fpp_display_testing_menu2.png
new file mode 100644
index 0000000000000000000000000000000000000000..c5a5b33b6a003a9b10d5f3c96e84fe105679ab7a
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_display_testing_menu2.png differ
diff --git a/pru-cookbook/01case/figures/fpp_file_manager.png b/pru-cookbook/01case/figures/fpp_file_manager.png
new file mode 100644
index 0000000000000000000000000000000000000000..958bfab9125a87a7d546f63be35b7b98cb92be88
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_file_manager.png differ
diff --git a/pru-cookbook/01case/figures/fpp_inputs_setup.png b/pru-cookbook/01case/figures/fpp_inputs_setup.png
new file mode 100644
index 0000000000000000000000000000000000000000..32046a8ff9bc41d9469ab48c8a91ffcbe010fd15
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_inputs_setup.png differ
diff --git a/pru-cookbook/01case/figures/fpp_inputs_setup2.png b/pru-cookbook/01case/figures/fpp_inputs_setup2.png
new file mode 100644
index 0000000000000000000000000000000000000000..f721e6c5e15ed54e8e84db7861b3e5301fc76422
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_inputs_setup2.png differ
diff --git a/pru-cookbook/01case/figures/fpp_mode_bridge.png b/pru-cookbook/01case/figures/fpp_mode_bridge.png
new file mode 100644
index 0000000000000000000000000000000000000000..9b3366565ff44237767210c9883cbce463837aaa
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_mode_bridge.png differ
diff --git a/pru-cookbook/01case/figures/fpp_playlist.png b/pru-cookbook/01case/figures/fpp_playlist.png
new file mode 100644
index 0000000000000000000000000000000000000000..5c8fa072db13cf23e6254ea5da9dad63eb1031d4
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_playlist.png differ
diff --git a/pru-cookbook/01case/figures/fpp_playlist_status.png b/pru-cookbook/01case/figures/fpp_playlist_status.png
new file mode 100644
index 0000000000000000000000000000000000000000..1994a186874a94817094f036af3a5b8ad84ecf80
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_playlist_status.png differ
diff --git a/pru-cookbook/01case/figures/fpp_program_control.png b/pru-cookbook/01case/figures/fpp_program_control.png
new file mode 100644
index 0000000000000000000000000000000000000000..b3b3662d029234f9884c08e5e71bf86792d70c6a
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_program_control.png differ
diff --git a/pru-cookbook/01case/figures/fpp_status.png b/pru-cookbook/01case/figures/fpp_status.png
new file mode 100644
index 0000000000000000000000000000000000000000..48748134234085f6edb3dc98693e8124307211d8
Binary files /dev/null and b/pru-cookbook/01case/figures/fpp_status.png differ
diff --git a/pru-cookbook/01case/figures/ledmatrix.jpg b/pru-cookbook/01case/figures/ledmatrix.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..20f52dc3c56b5ab982b17a808416f5c2d2a3957c
Binary files /dev/null and b/pru-cookbook/01case/figures/ledmatrix.jpg differ
diff --git a/pru-cookbook/01case/figures/pocketscroller.jpg b/pru-cookbook/01case/figures/pocketscroller.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..972e803dde8a7f6af7f6c979b6a5ff3d31796fab
Binary files /dev/null and b/pru-cookbook/01case/figures/pocketscroller.jpg differ
diff --git a/pru-cookbook/01case/figures/xlights_layout.png b/pru-cookbook/01case/figures/xlights_layout.png
new file mode 100644
index 0000000000000000000000000000000000000000..7a3e6930b704d791935aac4dfa5400ce3ee30638
Binary files /dev/null and b/pru-cookbook/01case/figures/xlights_layout.png differ
diff --git a/pru-cookbook/01case/figures/xlights_layout_details.png b/pru-cookbook/01case/figures/xlights_layout_details.png
new file mode 100644
index 0000000000000000000000000000000000000000..393a0ead4923f018163816ad3b0819b37c1b8745
Binary files /dev/null and b/pru-cookbook/01case/figures/xlights_layout_details.png differ
diff --git a/pru-cookbook/01case/figures/xlights_seq_drag.png b/pru-cookbook/01case/figures/xlights_seq_drag.png
new file mode 100644
index 0000000000000000000000000000000000000000..5dbbd14a9adce10c5b1c2f48da985659cc878520
Binary files /dev/null and b/pru-cookbook/01case/figures/xlights_seq_drag.png differ
diff --git a/pru-cookbook/01case/figures/xlights_seq_new.png b/pru-cookbook/01case/figures/xlights_seq_new.png
new file mode 100644
index 0000000000000000000000000000000000000000..840d8d0021a2f695eb7190c151c69adf3aedbf62
Binary files /dev/null and b/pru-cookbook/01case/figures/xlights_seq_new.png differ
diff --git a/pru-cookbook/01case/figures/xlights_setup.png b/pru-cookbook/01case/figures/xlights_setup.png
new file mode 100644
index 0000000000000000000000000000000000000000..4fd1d9a67db0c2854a5618066b7068d0c6b3cfb1
Binary files /dev/null and b/pru-cookbook/01case/figures/xlights_setup.png differ
diff --git a/pru-cookbook/01case/figures/xlights_setup_done.png b/pru-cookbook/01case/figures/xlights_setup_done.png
new file mode 100644
index 0000000000000000000000000000000000000000..1a6036f09ffcfdd0616e9cbcdd2deb9ebe860abf
Binary files /dev/null and b/pru-cookbook/01case/figures/xlights_setup_done.png differ
diff --git a/pru-cookbook/01case/figures/xlights_setup_e1_31.png b/pru-cookbook/01case/figures/xlights_setup_e1_31.png
new file mode 100644
index 0000000000000000000000000000000000000000..66ab80a082f756ae04dcfb9c35e57706cd7a2041
Binary files /dev/null and b/pru-cookbook/01case/figures/xlights_setup_e1_31.png differ
diff --git a/pru-cookbook/01case/figures/xlights_setup_e1_31.png.orig b/pru-cookbook/01case/figures/xlights_setup_e1_31.png.orig
new file mode 100644
index 0000000000000000000000000000000000000000..40d6f0789b4b1e8eeaa7b6ba3956769612eb96ac
Binary files /dev/null and b/pru-cookbook/01case/figures/xlights_setup_e1_31.png.orig differ
diff --git a/pru-cookbook/01case/figures/xlights_test.png b/pru-cookbook/01case/figures/xlights_test.png
new file mode 100644
index 0000000000000000000000000000000000000000..4023a4ceb00b045c71a872252a763dbb6623eef3
Binary files /dev/null and b/pru-cookbook/01case/figures/xlights_test.png differ
diff --git a/pru-cookbook/01case/figures/xlights_twinkle.jpg b/pru-cookbook/01case/figures/xlights_twinkle.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d98d1fd7991ce1d1dea2e60c769854127c28ad8e
Binary files /dev/null and b/pru-cookbook/01case/figures/xlights_twinkle.jpg differ
diff --git a/pru-cookbook/02start/code/Makefile b/pru-cookbook/02start/code/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a7557fdaa22988d89cec879477ded78522d7116f
--- /dev/null
+++ b/pru-cookbook/02start/code/Makefile
@@ -0,0 +1 @@
+include /var/lib/cloud9/common/Makefile
diff --git a/pru-cookbook/02start/code/ai.notes b/pru-cookbook/02start/code/ai.notes
new file mode 100644
index 0000000000000000000000000000000000000000..d11ac1d4288af4ac3f1cd5a5aa1ac6cec14cb97f
--- /dev/null
+++ b/pru-cookbook/02start/code/ai.notes
@@ -0,0 +1,59 @@
+Here are some differences between the AI and the Black for the PRU.
+
+Black
+/sys/devices/platform/ocp/
+    4a326004.pruss-soc-bus/
+        4a300000.pruss/
+            4a334000.pru/remoteproc/remoteproc1
+            4a338000.pru/remoteproc/remoteproc2
+        
+        
+AI
+/sys/devices/platform/44000000.ocp/
+    4b226004.pruss-soc-bus/
+        4b200000.pruss/
+            4b234000.pru/remoteproc/remoteproc0
+            4b238000.pru/remoteproc/remoteproc1
+    
+    
+    4b2a6004.pruss-soc-bus/
+        4b280000.pruss/
+            4b2b4000.pru/remoteproc/remoteproc2
+            4b2b8000.pru/remoteproc/remoteproc3
+            
+LED addresses
+https://github.com/beagleboard/BeagleBoard-DeviceTrees/blob/v4.19.x-ti/src/arm/am5729-beagleboneai.dts#L134-L171
+		led0 {
+			label = "beaglebone:green:usr0";
+			gpios = <&gpio3 17 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+			default-state = "off";
+		};
+
+		led1 {
+			label = "beaglebone:green:usr1";
+			gpios = <&gpio5 5 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc0";
+			default-state = "off";
+		};
+
+		led2 {
+			label = "beaglebone:green:usr2";
+			gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "cpu";
+			default-state = "off";
+		};
+
+		led3 {
+			label = "beaglebone:green:usr3";
+			gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "mmc1";
+			default-state = "off";
+		};
+
+		led4 {
+			label = "beaglebone:green:usr4";
+			gpios = <&gpio3 7 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy0assoc";
+
+GPIO Addresses:  Page 404 for TRM
\ No newline at end of file
diff --git a/pru-cookbook/02start/code/hello.pru0.c b/pru-cookbook/02start/code/hello.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..ab61e79eaafed3a7198532358d9ae3415559048f
--- /dev/null
+++ b/pru-cookbook/02start/code/hello.pru0.c
@@ -0,0 +1,35 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+volatile register unsigned int __R30;
+volatile register unsigned int __R31;
+
+void main(void) {
+	int i;
+
+	uint32_t *gpio1 = (uint32_t *)GPIO1;
+	
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	for(i=0; i<10; i++) {
+		gpio1[GPIO_SETDATAOUT]   = USR3;	// The the USR3 LED on
+
+		__delay_cycles(500000000/5);    	// Wait 1/2 second
+
+		gpio1[GPIO_CLEARDATAOUT] = USR3;
+
+		__delay_cycles(500000000/5); 
+
+	}
+	__halt();
+}
+
+// Turns off triggers
+#pragma DATA_SECTION(init_pins, ".init_pins")
+#pragma RETAIN(init_pins)
+const char init_pins[] =  
+	"/sys/class/leds/beaglebone:green:usr3/trigger\0none\0" \
+	"\0\0";
diff --git a/pru-cookbook/02start/code/hello.pru1_1.c b/pru-cookbook/02start/code/hello.pru1_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..8cb8146f74c88ee890a5a251108c19642cdb0c75
--- /dev/null
+++ b/pru-cookbook/02start/code/hello.pru1_1.c
@@ -0,0 +1,35 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+volatile register unsigned int __R30;
+volatile register unsigned int __R31;
+
+void main(void) {
+	int i;
+
+	uint32_t *gpio3 = (uint32_t *)GPIO3;
+	
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	for(i=0; i<10; i++) {
+		gpio3[GPIO_SETDATAOUT]   = USR3;	// The the USR3 LED on
+
+		__delay_cycles(500000000/5);    	// Wait 1/2 second
+
+		gpio3[GPIO_CLEARDATAOUT] = USR3;
+
+		__delay_cycles(500000000/5); 
+
+	}
+	__halt();
+}
+
+// Turns off triggers
+#pragma DATA_SECTION(init_pins, ".init_pins")
+#pragma RETAIN(init_pins)
+const char init_pins[] =  
+	"/sys/class/leds/beaglebone:green:usr3/trigger\0none\0" \
+	"\0\0";
diff --git a/pru-cookbook/02start/code/hello2.pru0.c b/pru-cookbook/02start/code/hello2.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..d268d33b637cb9d51a9928589a69ce158101a4e2
--- /dev/null
+++ b/pru-cookbook/02start/code/hello2.pru0.c
@@ -0,0 +1,42 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+volatile register unsigned int __R30;
+volatile register unsigned int __R31;
+
+void main(void) {
+	int i;
+
+	uint32_t *gpio1 = (uint32_t *)GPIO1;
+	
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	for(i=0; i<10; i++) {
+		gpio1[GPIO_SETDATAOUT]   = USR1;			// The the USR3 LED on
+		gpio1[GPIO_CLEARDATAOUT] = USR2;
+		
+		// __R30 |= gpio;		// Set the GPIO pin to 1
+
+		__delay_cycles(500000000/5);    // Wait 1/2 second
+
+		gpio1[GPIO_CLEARDATAOUT] = USR1;
+        gpio1[GPIO_SETDATAOUT]   = USR2;
+		
+		// __R30 &= ~gpio;		// Clearn the GPIO pin
+
+		__delay_cycles(500000000/5); 
+
+	}
+	__halt();
+}
+
+// Turns off triggers
+#pragma DATA_SECTION(init_pins, ".init_pins")
+#pragma RETAIN(init_pins)
+const char init_pins[] =  
+	"/sys/class/leds/beaglebone:green:usr1/trigger\0none\0" \
+	"/sys/class/leds/beaglebone:green:usr2/trigger\0none\0" \
+	"\0\0";
diff --git a/pru-cookbook/02start/code/hello2.pru1.c b/pru-cookbook/02start/code/hello2.pru1.c
new file mode 100644
index 0000000000000000000000000000000000000000..15df54495ecf681b3707a42dfaa6dfae65990559
--- /dev/null
+++ b/pru-cookbook/02start/code/hello2.pru1.c
@@ -0,0 +1,43 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+volatile register unsigned int __R30;
+volatile register unsigned int __R31;
+
+void main(void) {
+	int i;
+
+	uint32_t *gpio1 = (uint32_t *)GPIO1;
+	
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	for(i=0; i<10; i++) {
+		gpio1[GPIO_SETDATAOUT]   = USR1;			// The the USR3 LED on
+		gpio1[GPIO_CLEARDATAOUT] = USR2;
+		
+		// __R30 |= gpio;		// Set the GPIO pin to 1
+
+		__delay_cycles(500000000/5);    // Wait 1/2 second
+
+		gpio1[GPIO_CLEARDATAOUT] = USR1;
+        gpio1[GPIO_SETDATAOUT]   = USR2;
+		
+		// __R30 &= ~gpio;		// Clearn the GPIO pin
+
+		__delay_cycles(500000000/5); 
+
+	}
+	__halt();
+}
+
+// Turns off triggers
+#pragma DATA_SECTION(init_pins, ".init_pins")
+#pragma RETAIN(init_pins)
+const char init_pins[] =  
+	"/sys/class/leds/beaglebone:green:usr1/trigger\0none\0" \
+	"/sys/class/leds/beaglebone:green:usr2/trigger\0none\0" \
+	"\0\0";
+
diff --git a/pru-cookbook/02start/code/hello2.pru1_0.c b/pru-cookbook/02start/code/hello2.pru1_0.c
new file mode 100644
index 0000000000000000000000000000000000000000..564e1bc9b8c0fe7df8c21df6594f519d92470690
--- /dev/null
+++ b/pru-cookbook/02start/code/hello2.pru1_0.c
@@ -0,0 +1,63 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+volatile register unsigned int __R30;
+volatile register unsigned int __R31;
+
+void main(void) {
+	int i;
+
+	// uint32_t *gpio1 = (uint32_t *)GPIO1;
+	// uint32_t *gpio2 = (uint32_t *)GPIO2;
+	uint32_t *gpio3 = (uint32_t *)GPIO3;
+	// uint32_t *gpio4 = (uint32_t *)GPIO4;
+	uint32_t *gpio5 = (uint32_t *)GPIO5;
+	uint32_t *gpio6 = (uint32_t *)GPIO6;
+	// uint32_t *gpio7 = (uint32_t *)GPIO7;
+	uint32_t *gpio8 = (uint32_t *)GPIO8;
+	
+	// Select which pins to toggle.  These are all on pru1_1
+	uint32_t gpio = P9_16 | P8_15 | P8_16 | P8_26;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	for(i=0; i<100; i++) {
+		gpio5[GPIO_SETDATAOUT]   = USR1;		// Turn the USR1 LED on
+		gpio3[GPIO_CLEARDATAOUT] = USR2;
+		gpio8[GPIO_SETDATAOUT]   = P8_17;
+		gpio6[GPIO_SETDATAOUT]   = P9_25;
+		
+		__R30 |= gpio;		// Set the GPIO pin to 1
+
+		__delay_cycles(500000000/5);    // Wait 1/2 second
+
+		gpio5[GPIO_CLEARDATAOUT] = USR1;
+        gpio3[GPIO_SETDATAOUT]   = USR2;
+		gpio8[GPIO_CLEARDATAOUT] = P8_17;
+		gpio6[GPIO_CLEARDATAOUT] = P9_25;
+		
+		__R30 &= ~gpio;		// Clear the GPIO pin
+
+		__delay_cycles(500000000/5); 
+		
+		if((__R31&P8_19) == P8_19) {
+            gpio3[GPIO_CLEARDATAOUT]   = USR3;      // Turn on LED
+        } else
+            gpio3[GPIO_SETDATAOUT]     = USR3;      // Turn off LED
+	}
+	__halt();
+}
+
+// Turns off triggers
+#pragma DATA_SECTION(init_pins, ".init_pins")
+#pragma RETAIN(init_pins)
+const char init_pins[] =  
+	"/sys/class/leds/beaglebone:green:usr1/trigger\0none\0" \
+	"/sys/class/leds/beaglebone:green:usr2/trigger\0none\0" \
+	"/sys/class/gpio/export\0 177\0" \
+	"/sys/class/gpio/gpio177/direction\0out\0" \
+	"\0\0";
+
diff --git a/pru-cookbook/02start/code/hello2.pru1_1.c b/pru-cookbook/02start/code/hello2.pru1_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..564e1bc9b8c0fe7df8c21df6594f519d92470690
--- /dev/null
+++ b/pru-cookbook/02start/code/hello2.pru1_1.c
@@ -0,0 +1,63 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+volatile register unsigned int __R30;
+volatile register unsigned int __R31;
+
+void main(void) {
+	int i;
+
+	// uint32_t *gpio1 = (uint32_t *)GPIO1;
+	// uint32_t *gpio2 = (uint32_t *)GPIO2;
+	uint32_t *gpio3 = (uint32_t *)GPIO3;
+	// uint32_t *gpio4 = (uint32_t *)GPIO4;
+	uint32_t *gpio5 = (uint32_t *)GPIO5;
+	uint32_t *gpio6 = (uint32_t *)GPIO6;
+	// uint32_t *gpio7 = (uint32_t *)GPIO7;
+	uint32_t *gpio8 = (uint32_t *)GPIO8;
+	
+	// Select which pins to toggle.  These are all on pru1_1
+	uint32_t gpio = P9_16 | P8_15 | P8_16 | P8_26;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	for(i=0; i<100; i++) {
+		gpio5[GPIO_SETDATAOUT]   = USR1;		// Turn the USR1 LED on
+		gpio3[GPIO_CLEARDATAOUT] = USR2;
+		gpio8[GPIO_SETDATAOUT]   = P8_17;
+		gpio6[GPIO_SETDATAOUT]   = P9_25;
+		
+		__R30 |= gpio;		// Set the GPIO pin to 1
+
+		__delay_cycles(500000000/5);    // Wait 1/2 second
+
+		gpio5[GPIO_CLEARDATAOUT] = USR1;
+        gpio3[GPIO_SETDATAOUT]   = USR2;
+		gpio8[GPIO_CLEARDATAOUT] = P8_17;
+		gpio6[GPIO_CLEARDATAOUT] = P9_25;
+		
+		__R30 &= ~gpio;		// Clear the GPIO pin
+
+		__delay_cycles(500000000/5); 
+		
+		if((__R31&P8_19) == P8_19) {
+            gpio3[GPIO_CLEARDATAOUT]   = USR3;      // Turn on LED
+        } else
+            gpio3[GPIO_SETDATAOUT]     = USR3;      // Turn off LED
+	}
+	__halt();
+}
+
+// Turns off triggers
+#pragma DATA_SECTION(init_pins, ".init_pins")
+#pragma RETAIN(init_pins)
+const char init_pins[] =  
+	"/sys/class/leds/beaglebone:green:usr1/trigger\0none\0" \
+	"/sys/class/leds/beaglebone:green:usr2/trigger\0none\0" \
+	"/sys/class/gpio/export\0 177\0" \
+	"/sys/class/gpio/gpio177/direction\0out\0" \
+	"\0\0";
+
diff --git a/pru-cookbook/02start/code/hello2.pru2_0.c b/pru-cookbook/02start/code/hello2.pru2_0.c
new file mode 100644
index 0000000000000000000000000000000000000000..564e1bc9b8c0fe7df8c21df6594f519d92470690
--- /dev/null
+++ b/pru-cookbook/02start/code/hello2.pru2_0.c
@@ -0,0 +1,63 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+volatile register unsigned int __R30;
+volatile register unsigned int __R31;
+
+void main(void) {
+	int i;
+
+	// uint32_t *gpio1 = (uint32_t *)GPIO1;
+	// uint32_t *gpio2 = (uint32_t *)GPIO2;
+	uint32_t *gpio3 = (uint32_t *)GPIO3;
+	// uint32_t *gpio4 = (uint32_t *)GPIO4;
+	uint32_t *gpio5 = (uint32_t *)GPIO5;
+	uint32_t *gpio6 = (uint32_t *)GPIO6;
+	// uint32_t *gpio7 = (uint32_t *)GPIO7;
+	uint32_t *gpio8 = (uint32_t *)GPIO8;
+	
+	// Select which pins to toggle.  These are all on pru1_1
+	uint32_t gpio = P9_16 | P8_15 | P8_16 | P8_26;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	for(i=0; i<100; i++) {
+		gpio5[GPIO_SETDATAOUT]   = USR1;		// Turn the USR1 LED on
+		gpio3[GPIO_CLEARDATAOUT] = USR2;
+		gpio8[GPIO_SETDATAOUT]   = P8_17;
+		gpio6[GPIO_SETDATAOUT]   = P9_25;
+		
+		__R30 |= gpio;		// Set the GPIO pin to 1
+
+		__delay_cycles(500000000/5);    // Wait 1/2 second
+
+		gpio5[GPIO_CLEARDATAOUT] = USR1;
+        gpio3[GPIO_SETDATAOUT]   = USR2;
+		gpio8[GPIO_CLEARDATAOUT] = P8_17;
+		gpio6[GPIO_CLEARDATAOUT] = P9_25;
+		
+		__R30 &= ~gpio;		// Clear the GPIO pin
+
+		__delay_cycles(500000000/5); 
+		
+		if((__R31&P8_19) == P8_19) {
+            gpio3[GPIO_CLEARDATAOUT]   = USR3;      // Turn on LED
+        } else
+            gpio3[GPIO_SETDATAOUT]     = USR3;      // Turn off LED
+	}
+	__halt();
+}
+
+// Turns off triggers
+#pragma DATA_SECTION(init_pins, ".init_pins")
+#pragma RETAIN(init_pins)
+const char init_pins[] =  
+	"/sys/class/leds/beaglebone:green:usr1/trigger\0none\0" \
+	"/sys/class/leds/beaglebone:green:usr2/trigger\0none\0" \
+	"/sys/class/gpio/export\0 177\0" \
+	"/sys/class/gpio/gpio177/direction\0out\0" \
+	"\0\0";
+
diff --git a/pru-cookbook/02start/code/hello2.pru2_1.c b/pru-cookbook/02start/code/hello2.pru2_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..564e1bc9b8c0fe7df8c21df6594f519d92470690
--- /dev/null
+++ b/pru-cookbook/02start/code/hello2.pru2_1.c
@@ -0,0 +1,63 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+volatile register unsigned int __R30;
+volatile register unsigned int __R31;
+
+void main(void) {
+	int i;
+
+	// uint32_t *gpio1 = (uint32_t *)GPIO1;
+	// uint32_t *gpio2 = (uint32_t *)GPIO2;
+	uint32_t *gpio3 = (uint32_t *)GPIO3;
+	// uint32_t *gpio4 = (uint32_t *)GPIO4;
+	uint32_t *gpio5 = (uint32_t *)GPIO5;
+	uint32_t *gpio6 = (uint32_t *)GPIO6;
+	// uint32_t *gpio7 = (uint32_t *)GPIO7;
+	uint32_t *gpio8 = (uint32_t *)GPIO8;
+	
+	// Select which pins to toggle.  These are all on pru1_1
+	uint32_t gpio = P9_16 | P8_15 | P8_16 | P8_26;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	for(i=0; i<100; i++) {
+		gpio5[GPIO_SETDATAOUT]   = USR1;		// Turn the USR1 LED on
+		gpio3[GPIO_CLEARDATAOUT] = USR2;
+		gpio8[GPIO_SETDATAOUT]   = P8_17;
+		gpio6[GPIO_SETDATAOUT]   = P9_25;
+		
+		__R30 |= gpio;		// Set the GPIO pin to 1
+
+		__delay_cycles(500000000/5);    // Wait 1/2 second
+
+		gpio5[GPIO_CLEARDATAOUT] = USR1;
+        gpio3[GPIO_SETDATAOUT]   = USR2;
+		gpio8[GPIO_CLEARDATAOUT] = P8_17;
+		gpio6[GPIO_CLEARDATAOUT] = P9_25;
+		
+		__R30 &= ~gpio;		// Clear the GPIO pin
+
+		__delay_cycles(500000000/5); 
+		
+		if((__R31&P8_19) == P8_19) {
+            gpio3[GPIO_CLEARDATAOUT]   = USR3;      // Turn on LED
+        } else
+            gpio3[GPIO_SETDATAOUT]     = USR3;      // Turn off LED
+	}
+	__halt();
+}
+
+// Turns off triggers
+#pragma DATA_SECTION(init_pins, ".init_pins")
+#pragma RETAIN(init_pins)
+const char init_pins[] =  
+	"/sys/class/leds/beaglebone:green:usr1/trigger\0none\0" \
+	"/sys/class/leds/beaglebone:green:usr2/trigger\0none\0" \
+	"/sys/class/gpio/export\0 177\0" \
+	"/sys/class/gpio/gpio177/direction\0out\0" \
+	"\0\0";
+
diff --git a/pru-cookbook/02start/code/setup.sh b/pru-cookbook/02start/code/setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..eaf9943a2c375bc9f16b158994492b1198997dda
--- /dev/null
+++ b/pru-cookbook/02start/code/setup.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+export TARGET=hello.pru0
+
+echo TARGET=$TARGET
diff --git a/pru-cookbook/02start/code/setup2.sh b/pru-cookbook/02start/code/setup2.sh
new file mode 100755
index 0000000000000000000000000000000000000000..76dd6713f4f55d364403bf6a187b68e2e66172b0
--- /dev/null
+++ b/pru-cookbook/02start/code/setup2.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+export TARGET=hello2.pru1
+
+echo TARGET=$TARGET
diff --git a/pru-cookbook/02start/figures/BB_AI_BeautyAngle_800px.jpg b/pru-cookbook/02start/figures/BB_AI_BeautyAngle_800px.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..0070dd54ebd10285f016e792cdfbf862b273cf1c
Binary files /dev/null and b/pru-cookbook/02start/figures/BB_AI_BeautyAngle_800px.jpg differ
diff --git a/pru-cookbook/02start/figures/PocketBeagle-size-compare-small.jpg b/pru-cookbook/02start/figures/PocketBeagle-size-compare-small.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f7d440bdab452fd3251a136bcc652018cacf8357
Binary files /dev/null and b/pru-cookbook/02start/figures/PocketBeagle-size-compare-small.jpg differ
diff --git a/pru-cookbook/02start/figures/beagle-blue.png b/pru-cookbook/02start/figures/beagle-blue.png
new file mode 100644
index 0000000000000000000000000000000000000000..8777a254b074347d31b151f1cad690bdf71be39c
Binary files /dev/null and b/pru-cookbook/02start/figures/beagle-blue.png differ
diff --git a/pru-cookbook/02start/figures/c9.png b/pru-cookbook/02start/figures/c9.png
new file mode 100644
index 0000000000000000000000000000000000000000..edb7a272bf57253b007ceaf931e8a6e0696a198d
Binary files /dev/null and b/pru-cookbook/02start/figures/c9.png differ
diff --git a/pru-cookbook/02start/figures/c9ShowHome.png b/pru-cookbook/02start/figures/c9ShowHome.png
new file mode 100644
index 0000000000000000000000000000000000000000..91f268137135041853691ba981c6cfd0664108f3
Binary files /dev/null and b/pru-cookbook/02start/figures/c9ShowHome.png differ
diff --git a/pru-cookbook/02start/figures/edumip.png b/pru-cookbook/02start/figures/edumip.png
new file mode 100644
index 0000000000000000000000000000000000000000..e0faa0174e27f3daac479940334babd3a37c1bd6
Binary files /dev/null and b/pru-cookbook/02start/figures/edumip.png differ
diff --git a/pru-cookbook/02start/figures/etcher.png b/pru-cookbook/02start/figures/etcher.png
new file mode 100644
index 0000000000000000000000000000000000000000..6c7c92fc6ea019c2025ef93194d28b88ee841b1f
Binary files /dev/null and b/pru-cookbook/02start/figures/etcher.png differ
diff --git a/pru-cookbook/02start/figures/latest-images.png b/pru-cookbook/02start/figures/latest-images.png
new file mode 100644
index 0000000000000000000000000000000000000000..c6351706e16cea91b8084121e2c393686d329344
Binary files /dev/null and b/pru-cookbook/02start/figures/latest-images.png differ
diff --git a/pru-cookbook/02start/figures/product_detail_black_sm.jpg b/pru-cookbook/02start/figures/product_detail_black_sm.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e26e0c27fb7527d0c3a7ed75c818c8ae0c8dec90
Binary files /dev/null and b/pru-cookbook/02start/figures/product_detail_black_sm.jpg differ
diff --git a/pru-cookbook/02start/start.rst b/pru-cookbook/02start/start.rst
new file mode 100644
index 0000000000000000000000000000000000000000..dee7273df5bb6ed688a21156b65cf02433d76667
--- /dev/null
+++ b/pru-cookbook/02start/start.rst
@@ -0,0 +1,396 @@
+.. _pru-cookbook-start:
+
+Getting Started
+################
+
+We assume you have some experience with the Beagle and are here to learn about 
+the PRU.  This chapter discusses what Beagles are out there, how to load the 
+latest software image on your beagle, how to run the Cloud9 IDE and how to 
+blink an LED.
+
+If you already have your Beagle and know your way around it, you can find the
+code (and the whole book) on the PRU Cookbook github site: 
+https://github.com/MarkAYoder/PRUCookbook. 
+
+Selecting a Beagle
+====================
+
+Problem
+----------
+
+Which Beagle should you use?
+
+Solution
+----------
+
+http://beagleboard.org/boards lists the many Beagles from which to choose.  
+Here we'll give examples for the venerable `BeagleBone Black <http://beagleboard.org/black>`_, 
+the robotics `BeagleBone Blue <http://beagleboard.org/blue>`_, 
+tiny `PockeBeagle <http://beagleboard.org/pocket>`_ and the powerful `AI <http://beagleboard.org/ai>`_.
+All the examples should also run on the other Beagles too.
+
+Discussion
+------------
+
+BeagleBone Black
+~~~~~~~~~~~~~~~~~
+
+If you aren't sure which Beagle to use, it's hard to go wrong with the
+`BeagleBone Black <http://beagleboard.org/black>`_.  It's the most popular 
+member of the open hardware Beagle family.
+
+.. _start_black:
+
+BeagleBone Black
+~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/product_detail_black_sm.jpg
+    :align: center
+    :alt: BeableBone Black
+
+The Black has:
+
+* AM335x 1GHz ARM® Cortex-A8 processor
+* 512MB DDR3 RAM
+* 4GB 8-bit eMMC on-board flash storage
+* 3D graphics accelerator
+* NEON floating-point accelerator
+* 2x PRU 32-bit microcontrollers
+* USB client for power & communications
+* USB host
+* Ethernet
+* HDMI
+* 2x 46 pin headers
+
+See http://beagleboard.org/black for more details.
+
+BeagleBone Blue
+~~~~~~~~~~~~~~~~~
+
+The `Blue <http://beagleboard.org/blue>`_ is a good choice if you are doing robotics.
+
+.. _start_blue:
+
+BeagleBone Blue
+~~~~~~~~~~~~~~~~
+
+.. figure:: figures/beagle-blue.png
+    :align: center
+    :alt: BeagleBone Blue
+
+The Blue has everything the Black has except it has no Ethernet or HDMI.  
+But it also has:
+
+* Wireless: 802.11bgn, Bluetooth 4.1 and BLE
+* Battery support: 2-cell LiPo with balancing, LED state-of-charge monitor
+* Charger input: 9-18V
+* Motor control: 8 6V servo out, 4 bidirectional DC motor out, 4 quadrature encoder in
+* Sensors: 9 axis IMU (accels, gyros, magnetometer), barometer, thermometer
+* User interface: 11 user programmable LEDs, 2 user programmable buttons
+
+In addition you can mount the Blue on the 
+https://www.renaissancerobotics.com/eduMIP.html[EduMIP kit] as shown in
+:ref:`start_edumip` to get a balancing robot.
+
+.. _start_edumip:
+
+BeagleBone Blue EduMIP Kit
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/edumip.png
+    :align: center
+    :alt: BeagleBone Blue EduMIP Kit
+
+https://www.hackster.io/53815/controlling-edumip-with-ni-labview-2005f8 
+shows how to assemble the robot and control it from 
+`LabVIEW <http://www.ni.com/en-us/shop/labview.html>`_.
+
+PocketBeagle
+~~~~~~~~~~~~~~
+
+The `PocketBeagle <http://beagleboard.org/pocket>`_ is the smallest member of the 
+Beagle family.  It is an ultra-tiny-yet-complete Beagle that is software 
+compatible with the other Beagles.
+
+.. _start_pocket:
+
+PocketBeagle
+~~~~~~~~~~~~~
+
+.. figure:: figures/PocketBeagle-size-compare-small.jpg
+    :align: center
+    :alt: PocketBeagle
+
+The Pocket is based on the same processor as the Black and Blue and has:
+
+* 8 analog inputs
+* 44 digital I/Os and 
+* numerous digital interface peripherals
+
+See http://beagleboard.org/pocket for more details.
+
+BeagleBone AI
+~~~~~~~~~~~~~~~~~
+
+If you want to do deep learning, try the  `BeagleBone AI <http://beagleboard.org/ai>`_.
+
+.. _start_ai:
+
+BeagleBone AI
+~~~~~~~~~~~~~~
+
+.. figure:: figures/BB_AI_BeautyAngle_800px.jpg
+    :align: center
+    :alt: BeableBone AI
+
+The AI has:
+
+* Dual Arm® Cortex®-A15 microprocessor subsystem
+* 2 C66x floating-point VLIW DSPs
+* 2.5MB of on-chip L3 RAM
+* 2x dual Arm® Cortex®-M4 co-processors
+* 4x Embedded Vision Engines (EVEs)
+* 2x dual-core Programmable Real-Time Unit and Industrial Communication SubSystem (PRU-ICSS)
+* 2D-graphics accelerator (BB2D) subsystem
+* Dual-core PowerVR® SGX544™ 3D GPU
+* IVA-HD subsystem (4K @ 15fps encode and decode support for H.264, 1080p60 for others)
+* BeagleBone Black mechanical and header compatibility
+* 1GB RAM and 16GB on-board eMMC flash with high-speed interface
+* USB type-C for power and superspeed dual-role controller; and USB type-A host
+* Gigabit Ethernet, 2.4/5GHz WiFi, and Bluetooth
+* microHDMI
+* Zero-download out-of-box software experience with Debian GNU/Linux
+
+
+Installing the Latest OS on Your Bone
+======================================
+
+Problem
+---------
+
+You want to find the lastest version of Debian that is available for your Bone.
+
+Solution
+---------
+
+On your host computer open a browser and go to
+http://beagleboard.org/latest-images.
+
+.. TODO  Update links
+
+This shows you two current choices of recent Debian images,
+one for the BeagleBone AI 
+(`AM5729 Debian 10.3 2020-04-06 8GB SD IoT TIDL <https://debian.beagleboard.org/images/am57xx-debian-10.3-iot-tidl-armhf-2020-04-06-6gb.img.xz>`_) and
+one for all the other Beagles (
+`AM3358 Debian 10.3 2020-04-06 4GB SD IoT <https://debian.beagleboard.org/images/bone-debian-10.3-iot-armhf-2020-04-06-4gb.img.xz>`_).
+Download the one for your Beagle.
+
+Latest Debian images
+~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/latest-images.png
+    :align: center
+    :alt: Latest Debian images
+
+It contains all the packages we'll need.
+
+Flashing a Micro SD Card
+=========================
+
+Problem
+---------
+
+I've downloaded the image and need to flash my micro SD card.
+
+Solution
+---------
+
+Get a micro SD card that has at least 4GB and preferibly 8GB.  
+
+There are many ways to flash the card, but the best seems to be Etcher by
+https://www.balena.io/.  Go to https://www.balena.io/etcher/ and download the version for your host 
+computer.  Fire up Etcher, select the image you just downloaded (no need to 
+uncompress it, Etcher does it for you), select the SD card and hit the *Flash* 
+button and wait for it to finish.
+
+.. _start_etcher:
+
+Etcher
+~~~~~~~~
+
+.. figure:: figures/etcher.png
+    :align: center
+    :alt: Ether
+
+Once the SD is flashed, insert it in the Beagle and power it up.
+
+Cloud9 IDE
+===========
+
+Problem
+------------
+
+How do I manage and edit my files?
+
+Solution
+------------
+
+The image you downloaded includes `Cloud9 <https://aws.amazon.com/cloud9/>`_,
+a web-based intergrated development environment (IDE) as shown in 
+:ref:`start_c9`.
+
+.. _start_c9:
+
+Cloud9 IDE
+~~~~~~~~~~~~
+
+.. figure:: figures/c9.png
+    :align: center
+    :alt: The Cloud9 IDE
+
+Just point the browswer on your host computer to http://192.168.7.2 
+and start exploring.  If you want the files in your home directory to appear
+in the tree structure click the settings gear and select *Show Home in Favorites* 
+as shown in :ref:`start_c9_show_home`.
+
+.. _start_c9_show_home:
+
+Cloud9 Showing Home files
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/c9ShowHome.png
+    :align: center
+    :alt: Cloud9 showing home files
+
+
+If you want to edit files beyond your home directory you can link to the root file system by:
+
+.. code-block:: bash
+
+    bone$ *cd*
+    bone$ *ln -s / root*
+    bone$ *cd root*
+    bone$ *ls*
+    bbb-uEnv.txt  boot  etc   ID.txt  lost+found  mnt           opt   root  sbin  sys  usr
+    bin           dev   home  lib     media       nfs-uEnv.txt  proc  run   srv   tmp  var
+
+Now you can reach all the files from Cloud9.
+
+Getting Example Code
+====================
+
+Problem
+---------
+
+You are ready to start playing with the examples and need to find the code.
+
+Solution
+---------
+
+You can find the code (and the whole book) on the PRU Cookbook github site: 
+<https://github.com/MarkAYoder/PRUCookbook/tree/master/docs>. Just clone 
+it on your Beagle and then look in the *docs* directory.  
+
+.. code-block::bash
+
+    bone$ *git clone https://github.com/MarkAYoder/PRUCookbook.git*
+    bone$ *cd PRUCookbook/docs/*
+    bone$ *ls -F*
+    01case/     05blocks/  book.adoc  copyright.adoc  index.html  projects.adoc
+    02start/    06io/      book.html  hack.sh*        Makefile    projects.html
+    03details/  07more/    book.pdf   header.adoc     notes.adoc  style.adoc
+    04debug/    08ai/      common/    index.adoc      notes.html  style.html
+
+
+Each chapter has its own directory and within that directory is a **code** directory that has all of the code.
+
+.. code-block::bash
+
+    bone$ *cd 02start/code/*
+    bone$ *ls*
+    hello.pru0.c  hello.pru1_1.c  Makefile  setup.sh
+
+Go and explore.
+
+Blinking an LED
+=================
+
+Problem
+---------
+
+You want to make sure everything is set up by blinking an LED.
+
+Solution
+----------
+
+The 'hello, world' of the embedded world is to flash an LED. :ref:`start_hello` 
+is some code that blinks the ``USR3`` LED ten times using the PRU.
+
+.. TODO The *'s and _'s in the code are messing with the formatting.
+
+.. _start_hello:
+
+hello.pru0.c
+~~~~~~~~~~~~~
+
+:download:`hello.pru0.c <code/hello.pru0.c>`
+
+Later chapters will go into details of how this code works, but if you want 
+to run it right now do the following.
+
+.. code-block:: bash
+
+    bone$ *git clone https://github.com/MarkAYoder/PRUCookbook.git*
+    bone$ *cd PRUCookbook/docs/02start/code*
+
+.. tip::
+
+    If the following doesn't work see 
+    `Compiling with clpru and lnkpru <../03details/details.html#_compiling_with_clpru_and_lnkpru>`_
+    for instillation instructions.
+
+.. _start_running_code:
+
+Running Code on the Black or Pocket
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+    bone$ *make TARGET=hello.pru0*
+    /var/lib/cloud9/common/Makefile:28: MODEL=TI_AM335x_BeagleBone_Black,TARGET=hello.pru0,COMMON=/var/lib/cloud9/common
+    /var/lib/cloud9/common/Makefile:147: GEN_DIR=/tmp/cloud9-examples,CHIP=am335x,PROC=pru,PRUN=0,PRU_DIR=/sys/class/remoteproc/remoteproc1,EXE=.out
+    -    Stopping PRU 0
+    -	copying firmware file /tmp/cloud9-examples/hello.pru0.out to /lib/firmware/am335x-pru0-fw
+    write_init_pins.sh
+    writing "none" to "/sys/class/leds/beaglebone:green:usr3/trigger"
+    -    Starting PRU 0
+    MODEL   = TI_AM335x_BeagleBone_Black
+    PROC    = pru
+    PRUN    = 0
+    PRU_DIR = /sys/class/remoteproc/remoteproc1
+
+
+Running Code on the AI
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+    bone$ *make TARGET=hello.pru1_1*
+    /var/lib/cloud9/common/Makefile:28: MODEL=BeagleBoard.org_BeagleBone_AI,TARGET=hello.pru1_1
+    -    Stopping PRU 1_1
+    CC	hello.pru1_1.c
+    "/var/lib/cloud9/common/prugpio.h", line 4: warning #1181-D: #warning directive: "Found AI"
+    LD	/tmp/cloud9-examples/hello.pru1_1.o
+    -	copying firmware file /tmp/cloud9-examples/hello.pru1_1.out to /lib/firmware/am57xx-pru1_1-fw
+    write_init_pins.sh
+    writing "none" to "/sys/class/leds/beaglebone:green:usr3/trigger"
+    -    Starting PRU 1_1
+    MODEL   = BeagleBoard.org_BeagleBone_AI
+    PROC    = pru
+    PRUN    = 1_1
+    PRU_DIR = /dev/remoteproc/pruss1-core1
+    rm /tmp/cloud9-examples/hello.pru1_1.o
+
+Look quickly and you will see the ``USR3`` LED blinking.  
+
+Later sections give more details on how all this works.
diff --git a/pru-cookbook/03details/code/Makefile b/pru-cookbook/03details/code/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a7557fdaa22988d89cec879477ded78522d7116f
--- /dev/null
+++ b/pru-cookbook/03details/code/Makefile
@@ -0,0 +1 @@
+include /var/lib/cloud9/common/Makefile
diff --git a/pru-cookbook/03details/code/encoder_setup.sh b/pru-cookbook/03details/code/encoder_setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ffc4ad68842fb6314173b523425295893cd05fc1
--- /dev/null
+++ b/pru-cookbook/03details/code/encoder_setup.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# Configure the pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+
+# Configure eQEP pins
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P9_92 P9_27 P8_35 P8_33 P8_12 P8_11 P8_41 P8_42"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P1_31 P2_34 P2_10 P2_24 P2_33"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin qep
+    config-pin -q $pin
+done
+
+##########################################
+# Configure PRU pins
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P8_16 P8_15"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P2_09 P2_18"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin pruin
+    config-pin -q $pin
+done
diff --git a/pru-cookbook/03details/code/gpio_setup.sh b/pru-cookbook/03details/code/gpio_setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e676ed7abe2a6beaf62d3ce6c56f5aa151d86700
--- /dev/null
+++ b/pru-cookbook/03details/code/gpio_setup.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+export TARGET=gpio.pru0
+echo TARGET=$TARGET
+
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P9_11"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P2_05"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin gpio
+    config-pin -q $pin
+done
diff --git a/pru-cookbook/03details/code/servos_setup.sh b/pru-cookbook/03details/code/servos_setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..330e8f34e30d7fd97d9368861ded65817222e903
--- /dev/null
+++ b/pru-cookbook/03details/code/servos_setup.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P8_27 P8_28 P8_29 P8_30 P8_39 P8_40 P8_41 P8_42"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P2_35 P1_35 P1_02 P1_04"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin pruout
+    config-pin -q $pin
+done
\ No newline at end of file
diff --git a/pru-cookbook/03details/details.rst b/pru-cookbook/03details/details.rst
new file mode 100644
index 0000000000000000000000000000000000000000..379eea3edfb4f18c5fba1c3fc036e325153905b0
--- /dev/null
+++ b/pru-cookbook/03details/details.rst
@@ -0,0 +1,490 @@
+.. _pru-cookbook-details:
+
+Running a Program; Configuring Pins
+####################################
+
+There are a lot of details in compiling and running PRU code.
+Fortunately those details are captured in a common `Makefile` that is
+used througout this book. This chapter shows how to use the `Makefile` to 
+compile code and also start and stop the PRUs.
+
+The following are resources used in this chapter.
+
+Resources
+~~~~~~~~~~
+
+* `PRU Code Generation Tools - Compiler <http://software-dl.ti.com/codegen/esd/cgt_public_sw/PRU/2.1.5/ti_cgt_pru_2.1.5_armlinuxa8hf_busybox_installer.sh>`_
+* `PRU Software Support Package <http://git.ti.com/pru-software-support-package>`_
+* `PRU Optimizing C/C++ Compiler <http://www.ti.com/lit/ug/spruhv7b/spruhv7b.pdf>`_
+* `PRU Assembly Language Tools <http://www.ti.com/lit/ug/spruhv6b/spruhv6b.pdf>`_
+* `AM572x Technical Reference Manual <http://www.ti.com/lit/pdf/spruhz6l>`_ (AI)
+* `AM335x Technical Reference Manual <http://www.ti.com/lit/pdf/spruh73>`_ (All others)
+
+Getting Example Code
+=====================
+
+Problem
+---------
+
+I want to get the files used in this book.
+
+Solution
+---------
+
+It's all on a GitHub repository.
+
+.. code-block:: bash
+
+    bone$ git clone https://github.com/MarkAYoder/PRUCookbook.git
+
+Compiling with clpru and lnkpru
+================================
+
+
+Problem
+---------
+
+You need details on the c compiler, linker and other tools for the PRU.
+
+Solution
+---------
+
+The PRU compiler and linker are already installed on many images.
+They are called ``clpru`` and ``lnkpru``.  Do the following to see if ``clpru`` is installed.
+
+.. code-block:: bash
+
+    bone$ which clpru
+    /usr/bin/clpru
+
+.. tip::
+    If ``clpru`` isn't installed, follow the instructions at
+    https://elinux.org/Beagleboard:BeagleBoneBlack_Debian#TI_PRU_Code_Generation_Tools
+    to install it.
+
+.. code-block:: bash
+
+    bone$ sudo apt update
+    bone$ sudo apt install ti-pru-cgt-installer
+
+
+Details on each can be found here:
+
+* `PRU Optimizing C/C++ Compiler <http://www.ti.com/lit/ug/spruhv7b/spruhv7b.pdf>`_
+* `PRU Assembly Language Tools <http://www.ti.com/lit/ug/spruhv6b/spruhv6b.pdf>`_
+
+In fact there are PRU versions of many of the standard code generation tools.
+
+code tools
+~~~~~~~~~~~
+.. code-block:: bash
+
+    bone$ ls /usr/bin/*pru
+    /usr/bin/abspru    /usr/bin/clistpru  /usr/bin/hexpru      /usr/bin/ofdpru
+    /usr/bin/acpiapru  /usr/bin/clpru     /usr/bin/ilkpru      /usr/bin/optpru
+    /usr/bin/arpru     /usr/bin/dempru    /usr/bin/libinfopru  /usr/bin/rc_test_encoders_pru
+    /usr/bin/asmpru    /usr/bin/dispru    /usr/bin/lnkpru      /usr/bin/strippru
+    /usr/bin/cgpru     /usr/bin/embedpru  /usr/bin/nmpru       /usr/bin/xrefpru
+
+See the `PRU Assembly Language Tools <http://www.ti.com/lit/ug/spruhv6b/spruhv6b.pdf>`_ for more details.
+
+Making sure the PRUs are configured
+====================================
+
+Problem
+---------
+
+When running the Makefile for the PRU you get and error about ``/dev/remoteproc`` is missing.
+
+Solution
+---------
+
+Edit ``/boot/uEnv.txt`` and enble pru_rproc by doing the following.
+
+.. code-block:: bash
+
+    bone$ *sudo vi /boot/uEnv.txt*
+
+Around line 40 you will see:
+
+.. code-block:: bash
+
+    ###pru_rproc (4.19.x-ti kernel)
+    uboot_overlay_pru=AM335X-PRU-RPROC-4-19-TI-00A0.dtbo
+
+Uncomment the ``uboot_overlay`` line as shown and then reboot.
+``/dev/remoteproc`` should now be there.
+
+.. code-block:: bash
+
+    bone$ sudo reboot
+    bone$ ls -ls /dev/remoteproc/
+    total 0
+    0 lrwxrwxrwx 1 root root 33 Jul 29 16:12 pruss-core0 -> /sys/class/remoteproc/remoteproc1
+    0 lrwxrwxrwx 1 root root 33 Jul 29 16:12 pruss-core1 -> /sys/class/remoteproc/remoteproc2
+
+Compiling and Running
+======================
+
+Problem
+---------
+
+I want to compile and run an example.
+
+Solution
+---------
+
+Change to the directory of the code you want to run.
+
+.. code-block:: bash
+
+    bone$ cd PRUCookbook/docs/06io/code
+    bone$ ls
+    gpio.pru0.c  Makefile  setup.sh
+
+Source the setup file.
+
+.. code-block:: bash
+
+    bone$ source setup.sh
+    TARGET=gpio.pru0
+    PocketBeagle Found
+    P2_05
+    Current mode for P2_05 is:     gpio
+    Current mode for P2_05 is:     gpio
+
+Now you are ready to compile and run.  This is automated for you in the Makefile
+
+.. code-block:: bash
+
+    bone$ make
+    /var/lib/cloud9/common/Makefile:28: MODEL=TI_AM335x_BeagleBone_Black,TARGET=gpio.pru0,COMMON=/var/lib/cloud9/common
+    /var/lib/cloud9/common/Makefile:147: GEN_DIR=/tmp/cloud9-examples,CHIP=am335x,PROC=pru,PRUN=0,PRU_DIR=/sys/class/remoteproc/remoteproc1,EXE=.out
+    -    Stopping PRU 0
+    /bin/sh: 1: echo: echo: I/O error
+    Cannot stop 0
+    CC	gpio.pru0.c
+    "/var/lib/cloud9/common/prugpio.h", line 53: warning #1181-D: #warning directive: "Found am335x"
+    LD	/tmp/cloud9-examples/gpio.pru0.o
+    -	copying firmware file /tmp/cloud9-examples/gpio.pru0.out to /lib/firmware/am335x-pru0-fw
+    write_init_pins.sh
+    writing "out" to "/sys/class/gpio/gpio30/direction"
+    -    Starting PRU 0
+    MODEL   = TI_AM335x_BeagleBone_Black
+    PROC    = pru
+    PRUN    = 0
+    PRU_DIR = /sys/class/remoteproc/remoteproc1
+    rm /tmp/cloud9-examples/gpio.pru0.o
+
+Congratulations, your are now running a PRU.  If you have an LED attached to
+``P9_11`` on the Black, or ``P2_05`` on the Pocket, it should be blinking.
+
+Discussion
+------------
+
+The ``setup.sh`` file sets the ``TARGET`` to the file you want to compile.
+Set it to the filename, without the ``.c`` extension (``gpio.pru0``).
+The file extension ``.pru0`` specifies the number of the PRU you are using 
+(either ``1_0``, ``1_1``, ``2_0``, ``2_1`` on the AI or ``0`` or ``1`` on the others)
+
+You can override the ``TARGET`` on the command line.
+
+.. code-block:: bash
+
+    bone$ cp gpio.pru0.c gpio.pru1.c
+    bone$ export TARGET=gpio.pru1
+
+Notice the ``TARGET`` doesn't have the ``.c`` on the end.
+
+You can also specify them when running ``make``.
+.. code-block:: bash
+
+    bone$ cp gpio.pru0.c gpio.pru1.c
+    bone$ make TARGET=gpio.pru1
+
+The setup file also contains instructions to figure out which Beagle you are running
+and then configure the pins acordingly.
+
+setup.sh
+~~~~~~~~~
+
+:download:`gpio_setup.sh <code/gpio_setup.sh>`
+
+.. table::
+
+    +-----+---------------------------------------------------+
+    |Line | Explanation                                       |
+    +=====+===================================================+
+    |2-5  | Set which PRU to use and which file to compile.   |
+    +-----+---------------------------------------------------+
+    |7    | Figure out which type of Beagle we have.          |
+    +-----+---------------------------------------------------+
+    |9-21 | Based on the type, set the `pins`.                |
+    +-----+---------------------------------------------------+
+    |23-28| Configure (set the pin mux) for each of the pins. |
+    +-----+---------------------------------------------------+
+
+.. tip::
+
+    The BeagleBone AI has it's pins preconfigured at boot time, so there's no
+    need to use ``config-pin``.
+
+
+The ``Makefile`` stops the PRU, compiles the file and moves it where it will 
+be loaded, and then restarts the PRU.
+
+Stopping and Starting the PRU
+==============================
+
+Problem
+---------
+
+I want to stop and start the PRU.
+
+Solution
+---------
+
+It's easy, if you already have ``TARGET`` set up:
+
+.. code-block:: bash
+
+    bone$ make stop
+    -    Stopping PRU 0
+    stop
+    bone$ make start
+    -    Starting PRU 0
+    start
+
+See :ref:`../04debug/debug.html#_dmesg_hw,dmesg -Hw` to see how to tell if the PRU
+is stopped.
+
+This assumes ``TARGET`` is set to the PRU you are using.
+If you want to control the other PRU use:
+
+.. code-block:: bash
+
+    bone$ cp gpio.pru0.c gpio.pru1.c
+    bone$ make TARGET=gpio.pru1
+    bone$ make TARGET=gpio.pru1 stop
+    bone$ make TARGET=gpio.pru1 start
+
+
+.. _details_makefile:
+
+The Standard Makefile
+=====================
+
+Problem
+---------
+
+There are all sorts of options that need to be set when compiling
+a program.  How can I be sure to get them all right?
+
+Solution
+---------
+
+The surest way to make sure everything is right is to use our
+standard ``Makefile``.
+
+Discussion
+-----------
+
+It's assumed you already know how Makefiles work.  If not, there are
+many resources online that can bring you up to speed.
+Here is the local ``Makefile`` used throughout this book.
+
+Local Makefile
+~~~~~~~~~~~~~~~
+
+:download:`Makefile <code/Makefile>`
+
+Each of the local Makefiles refer to the same standard Makefile. The details
+of how the Makefile works is beyond the scope of this cookbook.
+
+Fortunately you shouldn't have to modify the `Makefile`.
+
+.. _detail_linker:
+
+The Linker Command File - am335x_pru.cmd
+=========================================
+
+
+Problem
+---------
+
+The linker needs to be told where in memory to place the code and variables.
+
+Solution
+---------
+
+``am335x_pru.cmd`` is the standard linker command file that tells the linker
+where to put what for the BeagleBone Black and Blue, and the Pocket. 
+The ``am57xx_pru.cmd`` does the same for the AI.
+Both files can be found in ``/var/lib/cloud9/common``.
+
+am335x_pru.cmd
+~~~~~~~~~~~~~~~~
+
+:download:`am335x_pru.cmd <code/am335x_pru.cmd>`
+
+.. TODO does  this need updating?
+
+The cmd file for the AI is about the same, with appropriate addresses for the AI.
+
+Discussion
+-----------
+
+
+The important things to notice in the file are given in the following table.
+
+AM335x_PRU.cmd important things
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. table::
+
+    +-----+-----------------------------------------------------------------------------------------+
+    |Line | Explanation                                                                             |
+    +=====+=========================================================================================+
+    |16   | This is where the instructions are stored. See page 206 of the                          |
+    |     | `AM335x Technical Reference Manual <https://www.ti.com/lit/ug/spruh73p/spruh73p.pdf>`_  |
+    |     | Or see page 417 of                                                                      |
+    |     | `AM572x Technical Reference Manual <http://www.ti.com/lit/pdf/spruhz6l>`_ for the AI.   |
+    +-----+-----------------------------------------------------------------------------------------+
+    |22   | This is where PRU 0's DMEM 0 is mapped.  It's also where PRU 1's                        |
+    |     | DMEM 1 is mapped.                                                                       |
+    +-----+-----------------------------------------------------------------------------------------+
+    |23   | The reverse to above.  PRU 0's DMEM 1 appears here and PRU 1's DMEM 0                   |
+    |     | is here.                                                                                |
+    +-----+-----------------------------------------------------------------------------------------+
+    |26   | The shared memory for both PRU's appears here.                                          |
+    +-----+-----------------------------------------------------------------------------------------+
+    |72   | The `.text` section is where the code goes.  It's mapped to `IMEM`                      |
+    +-----+-----------------------------------------------------------------------------------------+
+    |73   | The ((stack)) is then mapped to DMEM 0. Notice that DMEM 0 is one bank                  |
+    +-----+-----------------------------------------------------------------------------------------+
+    |     | of memory for PRU 0 and another for PRU1, so they both get their own stacks.            |
+    +-----+-----------------------------------------------------------------------------------------+
+    |74   | The `.bss` section is where the **heap** goes.                                          |
+    +-----+-----------------------------------------------------------------------------------------+
+
+Why is it important to understand this file?  If you are going to store things
+in DMEM, you need to be sure to start at address 0x0200 since the **stack** and 
+the **heap** are in the locations below 0x0200.
+
+Loading Firmware
+==================
+
+Problem
+---------
+
+I have my PRU code all compiled and need to load it on the PRU.
+
+Solution
+---------
+
+It's a simple three step process.
+
+* Stop the PRU
+* Write the ``.out`` file to the right place in ``/lib/firmware``
+* Start the PRU.
+
+This is all handled in the :ref:`details_makefile`.
+
+Discussion
+-----------
+
+
+The PRUs appear in the Linux file space at ``/dev/remoteproc/``.
+
+Finding the PRUs
+~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+    bone$ cd /dev/remoteproc/
+    bone$ ls
+    pruss-core0  pruss-core1
+
+Or if you are on the AI:
+
+.. code-block:: bash
+
+    bone$ cd /dev/remoteproc/
+    bone$ ls
+    dsp1  dsp2  ipu1  ipu2  pruss1-core0  pruss1-core1  pruss2-core0  pruss2-core1
+
+You see there that the AI has two pairs of PRUs, plus a couple of DSPs and other goodies.
+
+Here we see PRU 0 and PRU 1 in the path.  Let's follow PRU 0.
+
+.. code-block:: bash
+
+    bone$ cd pruss-core0
+    bone$ ls
+    device  firmware  name  power  state  subsystem  uevent
+
+Here we see the files that control PRU 0.  ``firmware`` tells where in ``/lib/firmware``
+to look for the code to run on the PRU.
+
+.. code-block:: bash
+
+    bone$ cat firmware
+    am335x-pru0-fw
+
+Therefore you copy your ``.out`` file to ``/lib/firmware/am335x-pru0-fw``.
+
+.. _details_configure_servos:
+
+Configuring Pins for Controlling Servos
+========================================
+
+Problem
+---------
+
+You want to **configure** the pins so the PRU outputs are accessable.
+
+Solution
+---------
+
+It depends on which Beagle you are running on.  If you are on the AI or Blue, 
+everything is already configured for you.
+If you are on the Black or Pocket you'll need to run the following script.
+
+servos_setup.sh
+~~~~~~~~~~~~~~~~
+
+:download:`servos_setup.sh <code/servos_setup.sh>`
+
+Discussion
+-----------
+
+The first part of the code looks in ``/proc/device-tree/model`` to see which Beagle is running. Based on that it
+assigns ``pins`` a list of pins to configure.  Then the last part of the script loops through each of the pins and configures it.
+
+
+.. _details_configure_encoders:
+
+Configuring Pins for Controlling Encoders
+==========================================
+
+Problem
+---------
+
+You want to **configure** the pins so the PRU inputs are accessable.
+
+Solution
+---------
+
+It depends on which Beagle you are running on.  If you are on the AI or Blue, 
+everything is already configured for you.
+If you are on the Black or Pocket you'll need to run the following script.
+
+.encoder_setup.sh
+
+:download:`encoder_setup.sh <code/encoder_setup.sh>`
+
+Discussion
+-----------
+
+This works like the servo setup except some of the pins are configured as 
+to the hardware eQEPs and other to the PRU inputs.
+
diff --git a/pru-cookbook/04debug/code/Makefile b/pru-cookbook/04debug/code/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a7557fdaa22988d89cec879477ded78522d7116f
--- /dev/null
+++ b/pru-cookbook/04debug/code/Makefile
@@ -0,0 +1 @@
+include /var/lib/cloud9/common/Makefile
diff --git a/pru-cookbook/04debug/code/copyright.c b/pru-cookbook/04debug/code/copyright.c
new file mode 100644
index 0000000000000000000000000000000000000000..a34918faa44a789c3624c0e5551704e630017dae
--- /dev/null
+++ b/pru-cookbook/04debug/code/copyright.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *	* Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ *
+ *	* Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the
+ *	  distribution.
+ *
+ *	* Neither the name of Texas Instruments Incorporated nor the names of
+ *	  its contributors may be used to endorse or promote products derived
+ *	  from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/pru-cookbook/04debug/code/resource_table_empty.h b/pru-cookbook/04debug/code/resource_table_empty.h
new file mode 100644
index 0000000000000000000000000000000000000000..c14bd2b222644e05a84a4a328792a4c8513ff1e8
--- /dev/null
+++ b/pru-cookbook/04debug/code/resource_table_empty.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *	* Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ *
+ *	* Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the
+ *	  distribution.
+ *
+ *	* Neither the name of Texas Instruments Incorporated nor the names of
+ *	  its contributors may be used to endorse or promote products derived
+ *	  from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ *  ======== resource_table_empty.h ========
+ *
+ *  Define the resource table entries for all PRU cores. This will be
+ *  incorporated into corresponding base images, and used by the remoteproc
+ *  on the host-side to allocated/reserve resources.  Note the remoteproc
+ *  driver requires that all PRU firmware be built with a resource table.
+ *
+ *  This file contains an empty resource table.  It can be used either as:
+ *
+ *        1) A template, or
+ *        2) As-is if a PRU application does not need to configure PRU_INTC
+ *                  or interact with the rpmsg driver
+ *
+ */
+
+#ifndef _RSC_TABLE_PRU_H_
+#define _RSC_TABLE_PRU_H_
+
+#include <stddef.h>
+#include <rsc_types.h>
+
+struct my_resource_table {
+	struct resource_table base;
+
+	uint32_t offset[1]; /* Should match 'num' in actual definition */
+};
+
+#pragma DATA_SECTION(pru_remoteproc_ResourceTable, ".resource_table")
+#pragma RETAIN(pru_remoteproc_ResourceTable)
+struct my_resource_table pru_remoteproc_ResourceTable = {
+	1,	/* we're the first version that implements this */
+	0,	/* number of entries in the table */
+	0, 0,	/* reserved, must be zero */
+	0,	/* offset[0] */
+};
+
+#endif /* _RSC_TABLE_PRU_H_ */
+
diff --git a/pru-cookbook/04debug/code/uart1.pru0.c b/pru-cookbook/04debug/code/uart1.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..e9b40d5c8c6fe6f1bda4492bb84160a1d4c08b3e
--- /dev/null
+++ b/pru-cookbook/04debug/code/uart1.pru0.c
@@ -0,0 +1,88 @@
+// From: http://git.ti.com/pru-software-support-package/pru-software-support-package/trees/master/examples/am335x/PRU_Hardware_UART
+
+#include <stdint.h>
+#include <pru_uart.h>
+#include "resource_table_empty.h"
+
+/* The FIFO size on the PRU UART is 16 bytes; however, we are (arbitrarily)
+ * only going to send 8 at a time */
+#define FIFO_SIZE	16
+#define MAX_CHARS	8
+
+void main(void)
+{
+	uint8_t tx;
+	uint8_t rx;
+	uint8_t cnt;
+
+	/*  hostBuffer points to the string to be printed */
+	char* hostBuffer;
+	
+	/*** INITIALIZATION ***/
+
+	/* Set up UART to function at 115200 baud - DLL divisor is 104 at 16x oversample
+	 * 192MHz / 104 / 16 = ~115200 */
+	CT_UART.DLL = 104;
+	CT_UART.DLH = 0;
+	CT_UART.MDR = 0x0;
+
+	/* Enable Interrupts in UART module. This allows the main thread to poll for
+	 * Receive Data Available and Transmit Holding Register Empty */
+	CT_UART.IER = 0x7;
+
+	/* If FIFOs are to be used, select desired trigger level and enable
+	 * FIFOs by writing to FCR. FIFOEN bit in FCR must be set first before
+	 * other bits are configured */
+	/* Enable FIFOs for now at 1-byte, and flush them */
+	CT_UART.FCR = (0x8) | (0x4) | (0x2) | (0x1);
+	//CT_UART.FCR = (0x80) | (0x4) | (0x2) | (0x01); // 8-byte RX FIFO trigger
+
+	/* Choose desired protocol settings by writing to LCR */
+	/* 8-bit word, 1 stop bit, no parity, no break control and no divisor latch */
+	CT_UART.LCR = 3;
+
+	/* Enable loopback for test */
+	CT_UART.MCR = 0x00;
+
+	/* Choose desired response to emulation suspend events by configuring
+	 * FREE bit and enable UART by setting UTRST and URRST in PWREMU_MGMT */
+	/* Allow UART to run free, enable UART TX/RX */
+	CT_UART.PWREMU_MGMT = 0x6001;
+
+	/*** END INITIALIZATION ***/
+
+	/* Priming the 'hostbuffer' with a message */
+	hostBuffer = "Hello!  This is a long string\r\n";
+
+	/*** SEND SOME DATA ***/
+
+	/* Let's send/receive some dummy data */
+	while(1) {
+		cnt = 0;
+		while(1) {
+			/* Load character, ensure it is not string termination */
+			if ((tx = hostBuffer[cnt]) == '\0')
+				break;
+			cnt++;
+			CT_UART.THR = tx;
+	
+			/* Because we are doing loopback, wait until LSR.DR == 1
+			 * indicating there is data in the RX FIFO */
+			while ((CT_UART.LSR & 0x1) == 0x0);
+	
+			/* Read the value from RBR */
+			rx = CT_UART.RBR;
+	
+			/* Wait for TX FIFO to be empty */
+			while (!((CT_UART.FCR & 0x2) == 0x2));
+		}
+	}
+
+	/*** DONE SENDING DATA ***/
+
+	/* Disable UART before halting */
+	CT_UART.PWREMU_MGMT = 0x0;
+
+	/* Halt PRU core */
+	__halt();
+}
diff --git a/pru-cookbook/04debug/code/uart1.pru1_0.c b/pru-cookbook/04debug/code/uart1.pru1_0.c
new file mode 100644
index 0000000000000000000000000000000000000000..4c558bb96e6e21b9c0b05f9acee21f7d7ad3c225
--- /dev/null
+++ b/pru-cookbook/04debug/code/uart1.pru1_0.c
@@ -0,0 +1,90 @@
+// From: http://git.ti.com/pru-software-support-package/pru-software-support-package/trees/master/examples/am335x/PRU_Hardware_UART
+// This example was converted to the am5729 by changing the names in pru_uart.h
+// for the am335x to the more descriptive names for the am5729.
+// For example  DLL convertes to DIVISOR_REGISTER_LSB_
+#include <stdint.h>
+#include <pru_uart.h>
+#include "resource_table_empty.h"
+
+/* The FIFO size on the PRU UART is 16 bytes; however, we are (arbitrarily)
+ * only going to send 8 at a time */
+#define FIFO_SIZE	16
+#define MAX_CHARS	8
+
+void main(void)
+{
+	uint8_t tx;
+	uint8_t rx;
+	uint8_t cnt;
+
+	/*  hostBuffer points to the string to be printed */
+	char* hostBuffer;
+	
+	/*** INITIALIZATION ***/
+
+	/* Set up UART to function at 115200 baud - DLL divisor is 104 at 16x oversample
+	 * 192MHz / 104 / 16 = ~115200 */
+	CT_UART.DIVISOR_REGISTER_LSB_ = 104;
+	CT_UART.DIVISOR_REGISTER_MSB_ = 0;
+	CT_UART.MODE_DEFINITION_REGISTER = 0x0;
+
+	/* Enable Interrupts in UART module. This allows the main thread to poll for
+	 * Receive Data Available and Transmit Holding Register Empty */
+	CT_UART.INTERRUPT_ENABLE_REGISTER = 0x7;
+
+	/* If FIFOs are to be used, select desired trigger level and enable
+	 * FIFOs by writing to FCR. FIFOEN bit in FCR must be set first before
+	 * other bits are configured */
+	/* Enable FIFOs for now at 1-byte, and flush them */
+	CT_UART.INTERRUPT_IDENTIFICATION_REGISTER_FIFO_CONTROL_REGISTER = (0x8) | (0x4) | (0x2) | (0x1);
+	//CT_UART.FCR = (0x80) | (0x4) | (0x2) | (0x01); // 8-byte RX FIFO trigger
+
+	/* Choose desired protocol settings by writing to LCR */
+	/* 8-bit word, 1 stop bit, no parity, no break control and no divisor latch */
+	CT_UART.LINE_CONTROL_REGISTER = 3;
+
+	/* Enable loopback for test */
+	CT_UART.MODEM_CONTROL_REGISTER = 0x00;
+
+	/* Choose desired response to emulation suspend events by configuring
+	 * FREE bit and enable UART by setting UTRST and URRST in PWREMU_MGMT */
+	/* Allow UART to run free, enable UART TX/RX */
+	CT_UART.POWERMANAGEMENT_AND_EMULATION_REGISTER = 0x6001;
+
+	/*** END INITIALIZATION ***/
+
+	/* Priming the 'hostbuffer' with a message */
+	hostBuffer = "Hello!  This is a long string\r\n";
+
+	/*** SEND SOME DATA ***/
+
+	/* Let's send/receive some dummy data */
+	while(1) {
+		cnt = 0;
+		while(1) {
+			/* Load character, ensure it is not string termination */
+			if ((tx = hostBuffer[cnt]) == '\0')
+				break;
+			cnt++;
+			CT_UART.RBR_THR_REGISTERS = tx;
+	
+			/* Because we are doing loopback, wait until LSR.DR == 1
+			 * indicating there is data in the RX FIFO */
+			while ((CT_UART.LINE_STATUS_REGISTER & 0x1) == 0x0);
+	
+			/* Read the value from RBR */
+			rx = CT_UART.RBR_THR_REGISTERS;
+	
+			/* Wait for TX FIFO to be empty */
+			while (!((CT_UART.INTERRUPT_IDENTIFICATION_REGISTER_FIFO_CONTROL_REGISTER & 0x2) == 0x2));
+		}
+	}
+
+	/*** DONE SENDING DATA ***/
+
+	/* Disable UART before halting */
+	CT_UART.POWERMANAGEMENT_AND_EMULATION_REGISTER = 0x0;
+
+	/* Halt PRU core */
+	__halt();
+}
diff --git a/pru-cookbook/04debug/code/uart2.pru0.c b/pru-cookbook/04debug/code/uart2.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..56ca985d5a45d1daeb2efd22b9576047791519bf
--- /dev/null
+++ b/pru-cookbook/04debug/code/uart2.pru0.c
@@ -0,0 +1,126 @@
+// From: http://git.ti.com/pru-software-support-package/pru-software-support-package/trees/master/pru_cape/pru_fw/PRU_Hardware_UART
+
+#include <stdint.h>
+#include <pru_uart.h>
+#include "resource_table_empty.h"
+
+/* The FIFO size on the PRU UART is 16 bytes; however, we are (arbitrarily)
+ * only going to send 8 at a time */
+#define FIFO_SIZE	16
+#define MAX_CHARS	8
+#define BUFFER		40
+
+//******************************************************************************
+//    Print Message Out
+//      This function take in a string literal of any size and then fill the
+//      TX FIFO when it's empty and waits until there is info in the RX FIFO
+//      before returning.
+//******************************************************************************
+void PrintMessageOut(volatile char* Message)
+{
+	uint8_t cnt, index = 0;
+
+	while (1) {
+		cnt = 0;
+
+		/* Wait until the TX FIFO and the TX SR are completely empty */
+		while (!CT_UART.LSR_bit.TEMT);
+
+		while (Message[index] != NULL && cnt < MAX_CHARS) {
+			CT_UART.THR = Message[index];
+			index++;
+			cnt++;
+		}
+		if (Message[index] == NULL)
+			break;
+	}
+
+	/* Wait until the TX FIFO and the TX SR are completely empty */
+	while (!CT_UART.LSR_bit.TEMT);
+
+}
+
+//******************************************************************************
+//    IEP Timer Config
+//      This function waits until there is info in the RX FIFO and then returns
+//      the first character entered.
+//******************************************************************************
+char ReadMessageIn(void)
+{
+	while (!CT_UART.LSR_bit.DR);
+
+	return CT_UART.RBR_bit.DATA;
+}
+
+void main(void)
+{
+	uint32_t i;
+	volatile uint32_t not_done = 1;
+
+	char rxBuffer[BUFFER];
+	rxBuffer[BUFFER-1] = NULL; // null terminate the string
+
+	/*** INITIALIZATION ***/
+
+	/* Set up UART to function at 115200 baud - DLL divisor is 104 at 16x oversample
+	 * 192MHz / 104 / 16 = ~115200 */
+	CT_UART.DLL = 104;
+	CT_UART.DLH = 0;
+	CT_UART.MDR_bit.OSM_SEL = 0x0;
+
+	/* Enable Interrupts in UART module. This allows the main thread to poll for
+	 * Receive Data Available and Transmit Holding Register Empty */
+	CT_UART.IER = 0x7;
+
+	/* If FIFOs are to be used, select desired trigger level and enable
+	 * FIFOs by writing to FCR. FIFOEN bit in FCR must be set first before
+	 * other bits are configured */
+	/* Enable FIFOs for now at 1-byte, and flush them */
+	CT_UART.FCR = (0x80) | (0x8) | (0x4) | (0x2) | (0x01); // 8-byte RX FIFO trigger
+
+	/* Choose desired protocol settings by writing to LCR */
+	/* 8-bit word, 1 stop bit, no parity, no break control and no divisor latch */
+	CT_UART.LCR = 3;
+
+	/* If flow control is desired write appropriate values to MCR. */
+	/* No flow control for now, but enable loopback for test */
+	CT_UART.MCR = 0x00;
+
+	/* Choose desired response to emulation suspend events by configuring
+	 * FREE bit and enable UART by setting UTRST and URRST in PWREMU_MGMT */
+	/* Allow UART to run free, enable UART TX/RX */
+	CT_UART.PWREMU_MGMT_bit.FREE = 0x1;
+	CT_UART.PWREMU_MGMT_bit.URRST = 0x1;
+	CT_UART.PWREMU_MGMT_bit.UTRST = 0x1;
+
+	/* Turn off RTS and CTS functionality */
+	CT_UART.MCR_bit.AFE = 0x0;
+	CT_UART.MCR_bit.RTS = 0x0;
+
+	/*** END INITIALIZATION ***/
+
+	while(1) {
+		/* Print out greeting message */
+		PrintMessageOut("Hello you are in the PRU UART demo test please enter some characters\r\n");
+	
+		/* Read in characters from user, then echo them back out */
+		for (i = 0; i < BUFFER-1 ; i++) {
+			rxBuffer[i] = ReadMessageIn();
+			if(rxBuffer[i] == '\r') {	// Quit early if ENTER is hit.
+				rxBuffer[i+1] = NULL;
+				break;
+			}
+		}
+	
+		PrintMessageOut("you typed:\r\n");
+		PrintMessageOut(rxBuffer);
+		PrintMessageOut("\r\n");
+	}
+
+	/*** DONE SENDING DATA ***/
+	/* Disable UART before halting */
+	CT_UART.PWREMU_MGMT = 0x0;
+
+	/* Halt PRU core */
+	__halt();
+}
diff --git a/pru-cookbook/04debug/code/uart2.pru1_0.c b/pru-cookbook/04debug/code/uart2.pru1_0.c
new file mode 100644
index 0000000000000000000000000000000000000000..c934ef7d0bd645734aa2c181b5ab68646713755e
--- /dev/null
+++ b/pru-cookbook/04debug/code/uart2.pru1_0.c
@@ -0,0 +1,126 @@
+// From: http://git.ti.com/pru-software-support-package/pru-software-support-package/trees/master/pru_cape/pru_fw/PRU_Hardware_UART
+
+#include <stdint.h>
+#include <pru_uart.h>
+#include "resource_table_empty.h"
+
+/* The FIFO size on the PRU UART is 16 bytes; however, we are (arbitrarily)
+ * only going to send 8 at a time */
+#define FIFO_SIZE	16
+#define MAX_CHARS	8
+#define BUFFER		40
+
+//******************************************************************************
+//    Print Message Out
+//      This function take in a string literal of any size and then fill the
+//      TX FIFO when it's empty and waits until there is info in the RX FIFO
+//      before returning.
+//******************************************************************************
+void PrintMessageOut(volatile char* Message)
+{
+	uint8_t cnt, index = 0;
+
+	while (1) {
+		cnt = 0;
+
+		/* Wait until the TX FIFO and the TX SR are completely empty */
+		while (!CT_UART.LINE_STATUS_REGISTER_bit.TEMT);
+
+		while (Message[index] != NULL && cnt < MAX_CHARS) {
+			CT_UART.RBR_THR_REGISTERS = Message[index];
+			index++;
+			cnt++;
+		}
+		if (Message[index] == NULL)
+			break;
+	}
+
+	/* Wait until the TX FIFO and the TX SR are completely empty */
+	while (!CT_UART.LINE_STATUS_REGISTER_bit.TEMT);
+
+}
+
+//******************************************************************************
+//    IEP Timer Config
+//      This function waits until there is info in the RX FIFO and then returns
+//      the first character entered.
+//******************************************************************************
+char ReadMessageIn(void)
+{
+	while (!CT_UART.LINE_STATUS_REGISTER_bit.DR);
+
+	return CT_UART.RBR_THR_REGISTERS_bit.DATA;
+}
+
+void main(void)
+{
+	uint32_t i;
+	volatile uint32_t not_done = 1;
+
+	char rxBuffer[BUFFER];
+	rxBuffer[BUFFER-1] = NULL; // null terminate the string
+
+	/*** INITIALIZATION ***/
+
+	/* Set up UART to function at 115200 baud - DLL divisor is 104 at 16x oversample
+	 * 192MHz / 104 / 16 = ~115200 */
+	CT_UART.DIVISOR_REGISTER_LSB_ = 104;
+	CT_UART.DIVISOR_REGISTER_MSB_ = 0;
+	CT_UART.MODE_DEFINITION_REGISTER_bit.OSM_SEL = 0x0;
+
+	/* Enable Interrupts in UART module. This allows the main thread to poll for
+	 * Receive Data Available and Transmit Holding Register Empty */
+	CT_UART.INTERRUPT_ENABLE_REGISTER = 0x7;
+
+	/* If FIFOs are to be used, select desired trigger level and enable
+	 * FIFOs by writing to FCR. FIFOEN bit in FCR must be set first before
+	 * other bits are configured */
+	/* Enable FIFOs for now at 1-byte, and flush them */
+	CT_UART.INTERRUPT_IDENTIFICATION_REGISTER_FIFO_CONTROL_REGISTER = (0x80) | (0x8) | (0x4) | (0x2) | (0x01); // 8-byte RX FIFO trigger
+
+	/* Choose desired protocol settings by writing to LCR */
+	/* 8-bit word, 1 stop bit, no parity, no break control and no divisor latch */
+	CT_UART.LINE_CONTROL_REGISTER = 3;
+
+	/* If flow control is desired write appropriate values to MCR. */
+	/* No flow control for now, but enable loopback for test */
+	CT_UART.MODEM_CONTROL_REGISTER = 0x00;
+
+	/* Choose desired response to emulation suspend events by configuring
+	 * FREE bit and enable UART by setting UTRST and URRST in PWREMU_MGMT */
+	/* Allow UART to run free, enable UART TX/RX */
+	CT_UART.POWERMANAGEMENT_AND_EMULATION_REGISTER_bit.FREE = 0x1;
+	CT_UART.POWERMANAGEMENT_AND_EMULATION_REGISTER_bit.URRST = 0x1;
+	CT_UART.POWERMANAGEMENT_AND_EMULATION_REGISTER_bit.UTRST = 0x1;
+
+	/* Turn off RTS and CTS functionality */
+	CT_UART.MODEM_CONTROL_REGISTER_bit.AFE = 0x0;
+	CT_UART.MODEM_CONTROL_REGISTER_bit.RTS = 0x0;
+
+	/*** END INITIALIZATION ***/
+
+	while(1) {
+		/* Print out greeting message */
+		PrintMessageOut("Hello you are in the PRU UART demo test please enter some characters\r\n");
+	
+		/* Read in characters from user, then echo them back out */
+		for (i = 0; i < BUFFER-1 ; i++) {
+			rxBuffer[i] = ReadMessageIn();
+			if(rxBuffer[i] == '\r') {	// Quit early if ENTER is hit.
+				rxBuffer[i+1] = NULL;
+				break;
+			}
+		}
+	
+		PrintMessageOut("you typed:\r\n");
+		PrintMessageOut(rxBuffer);
+		PrintMessageOut("\r\n");
+	}
+
+	/*** DONE SENDING DATA ***/
+	/* Disable UART before halting */
+	CT_UART.POWERMANAGEMENT_AND_EMULATION_REGISTER = 0x0;
+
+	/* Halt PRU core */
+	__halt();
+}
diff --git a/pru-cookbook/04debug/code/uart_setup.sh b/pru-cookbook/04debug/code/uart_setup.sh
new file mode 100644
index 0000000000000000000000000000000000000000..db11d1f4fb5226a1f66482d5262809085dfc0ea9
--- /dev/null
+++ b/pru-cookbook/04debug/code/uart_setup.sh
@@ -0,0 +1,28 @@
+export TARGET=uart1.pru0
+echo TARGET=$TARGET
+
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    # Configure tx
+    config-pin P9_24 pru_uart
+    # Configure rx
+    config-pin P9_26 pru_uart
+elif [ $machine = "AI" ]; then
+    echo " Found"
+    echo "See AI chapter for configuring via device tree"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    # Configure tx
+    config-pin P1_06 pru_uart
+    config-pin P2_09 pru_uart
+    # Configure rx
+    config-pin P1_12 pru_uart
+    config-pin P2_11 pru_uart
+else
+    echo " Not Found"
+    pins=""
+fi
diff --git a/pru-cookbook/04debug/debug.rst b/pru-cookbook/04debug/debug.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a9f0edfbd8f0a884beca0d263300cb12b1e89d6e
--- /dev/null
+++ b/pru-cookbook/04debug/debug.rst
@@ -0,0 +1,532 @@
+.. _pru-cookbook-debug:
+
+Debugging and Benchmarking
+###########################
+
+One of the challenges is getting debug
+information out of the PRUs since they don't have a traditional ``printf()``.
+In this chapter four different methods are presented that I've found useful in 
+debugging.  The first is simply attaching an LED.  The second is using 
+``dmesg`` to watch the kernel messages.  ``prudebug``, a simple debugger that 
+allows you to inspect registers and memory of the PRUs, is then presented. 
+Finally, using one of the UARTS to send debugging information out a serial port 
+is shown. 
+
+Debugging via an LED
+=====================
+
+Problem
+---------
+
+I need a simple way to see if my program is running without slowing the real-time execution.
+
+Solution
+---------
+
+One of the simplest ways to do this is to attach an LED to the output pin and watch it 
+flash. :ref:`debug_LED` shows an LED attached to pin P9_29 of the BeagleBone Black.
+
+.. _debug_LED:
+
+LED used for debugging P9_29
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/LED_bb.png
+  :align: center
+  :alt: LED used for debugging P9_29
+
+Make sure you have the LED in the correct way, or it won't work.
+
+Discussion
+---------
+
+If your output is changing more than a few times a second, the LED will be 
+blinking too fast and you'll need an oscilloscope or a logic analyzer to
+see what's happening.
+
+Another useful tool that let's you see the contents of the registers and 
+RAM is discussed in :ref:`debug_prudebug`.
+
+dmesg Hw
+=========
+
+Problem
+---------
+I'm getting an error message 
+(``/sys/devices/platform/ocp/4a326000.pruss-soc-bus/4a300000.pruss/4a334000.pru0/remoteproc/remoteproc1/state: Invalid argument``)
+when I load my code, but don't know what's causing it.
+
+Solution
+---------
+The command ``dmesg`` outputs useful information when dealing with the kernel.
+Simplying running ``dmesg -Hw`` can tell you a lot.  The ``-H`` flag puts the
+dates in the human readable form, the ``-w`` tells it to wait for more information.
+Often I'll have a window open running ``dmesg -Hw``.
+.
+
+Here's what ``dmesg`` said for the example above.
+
+dmesg -Hw
+~~~~~~~~~~
+
+.. code-block:: bash
+
+  [  +0.000018] remoteproc remoteproc1: header-less resource table
+  [  +0.011879] remoteproc remoteproc1: Failed to find resource table
+  [  +0.008770] remoteproc remoteproc1: Boot failed: -22
+
+It quickly told me I needed to add the line ``#include "resource_table_empty.h"``
+to my code.
+
+.. _debug_prudebug:
+
+prudebug - A Simple Debugger for the PRU
+=========================================
+
+Problem
+---------
+
+You need to examine registers and memory on the PRUs.
+
+Solution
+---------
+
+``prudebug`` is a simple debugger for the PRUs that lets you start and stop the PRUs and
+examine the registers and memory. It can be found on GitHub 
+https://github.com/RRvW/prudebug-rl.  I have a version I updated to use byte
+addressing rather than word addressing.  This makes it easier to work with the
+assembler output. You can find it in my GitHub BeagleBoard repo 
+https://github.com/MarkAYoder/BeagleBoard-exercises/tree/master/pru/prudebug.
+
+Just download the files and type ``make``.
+
+Discussion
+------------
+
+Once ``prudebug`` is installed is rather easy to use.
+
+.. note::
+
+  ``prudebug`` has now been ported to the AI.
+
+.. TODO  Isn't working on Pocket at this time.
+
+.. code-block:: bash
+
+  bone$ *sudo prudebug*
+  PRU Debugger v0.25
+  (C) Copyright 2011, 2013 by Arctica Technologies.  All rights reserved.
+  Written by Steven Anderson
+
+  Using /dev/mem device.
+  Processor type		AM335x
+  PRUSS memory address	0x4a300000
+  PRUSS memory length	0x00080000
+
+          offsets below are in 32-bit byte addresses (not ARM byte addresses)
+          PRU            Instruction    Data         Ctrl
+          0              0x00034000     0x00000000   0x00022000
+          1              0x00038000     0x00002000   0x00024000
+
+You get help by entering ``help``.  You cal also enter ``hb`` to get a brief help.
+
+.. code-block:: bash
+
+  PRU0> *hb*
+  Command help
+
+      BR [breakpoint_number [address]] - View or set an instruction breakpoint
+      D memory_location_ba [length] - Raw dump of PRU data memory (32-bit byte offset from beginning of full PRU memory block - all PRUs)
+      DD memory_location_ba [length] - Dump data memory (32-bit byte offset from beginning of PRU data memory)
+      DI memory_location_ba [length] - Dump instruction memory (32-bit byte offset from beginning of PRU instruction memory)
+      DIS memory_location_ba [length] - Disassemble instruction memory (32-bit byte offset from beginning of PRU instruction memory)
+      G - Start processor execution of instructions (at current IP)
+      GSS - Start processor execution using automatic single stepping - this allows running a program with breakpoints
+      HALT - Halt the processor
+      L memory_location_iwa file_name - Load program file into instruction memory
+      PRU pru_number - Set the active PRU where pru_number ranges from 0 to 1
+      Q - Quit the debugger and return to shell prompt.
+      R - Display the current PRU registers.
+      RESET - Reset the current PRU
+      SS - Single step the current instruction.
+      WA [watch_num [address [value]]] - Clear or set a watch point
+      WR memory_location_ba value1 [value2 [value3 ...]] - Write a 32-bit value to a raw (offset from beginning of full PRU memory block)
+      WRD memory_location_ba value1 [value2 [value3 ...]] - Write a 32-bit value to PRU data memory for current PRU
+      WRI memory_location_ba value1 [value2 [value3 ...]] - Write a 32-bit value to PRU instruction memory for current PRU
+
+
+Initially you are talking to PRU 0.  You can enter ``pru 1`` to talk to PRU 1.
+The commands I find most useful are, ``r``, to see the registers.
+
+.. code-block:: bash
+
+  PRU0> *r*
+  Register info for PRU0
+      Control register: 0x00008003
+        Reset PC:0x0000  RUNNING, FREE_RUN, COUNTER_DISABLED, NOT_SLEEPING, PROC_ENABLED
+
+      Program counter: 0x0030
+        Current instruction: ADD R0.b0, R0.b0, R0.b0
+
+      Rxx registers not available since PRU is RUNNING.
+
+Notice the PRU has to be stopped to see the register contents.
+
+.. code-block:: bash
+
+  PRU0> *h*
+  PRU0 Halted.
+  PRU0> *r*
+  Register info for PRU0
+      Control register: 0x00000001
+        Reset PC:0x0000  STOPPED, FREE_RUN, COUNTER_DISABLED, NOT_SLEEPING, PROC_DISABLED
+
+      Program counter: 0x0028
+        Current instruction: LBBO R15, R15, 4, 4
+
+      R00: 0x00000000    R08: 0x00000000    R16: 0x00000001    R24: 0x00000002
+      R01: 0x00000000    R09: 0xaf40dcf2    R17: 0x00000000    R25: 0x00000003
+      R02: 0x000000dc    R10: 0xd8255b1b    R18: 0x00000003    R26: 0x00000003
+      R03: 0x000f0000    R11: 0xc50cbefd    R19: 0x00000100    R27: 0x00000002
+      R04: 0x00000000    R12: 0xb037c0d7    R20: 0x00000100    R28: 0x8ca9d976
+      R05: 0x00000009    R13: 0xf48bbe23    R21: 0x441fb678    R29: 0x00000002
+      R06: 0x00000000    R14: 0x00000134    R22: 0xc8cc0752    R30: 0x00000000
+      R07: 0x00000009    R15: 0x00000200    R23: 0xe346fee9    R31: 0x00000000
+
+You can resume using ``g`` which starts right where you left off, or use ``reset`` to
+restart back at the beginning.
+
+The ``dd`` command dumps the memory.  Keep in mind the following.
+
+Important memory locations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+  +-------+---------------------------------------------------------------------------+
+  |Address|Contents                                                                   |
+  +=======+===========================================================================+
+  |0x00000| Start of the **stack** for PRU 0.  The file **AM335x_PRU.cmd** specifies  |
+  |       | where the stack is.                                                       |
+  +-------+---------------------------------------------------------------------------+
+  |0x00100| Start of the **heap** for PRU 0.                                          |
+  +-------+---------------------------------------------------------------------------+
+  |0x00200| Start of DRAM that your programs can use.  The **Makefile** specifies     |
+  +-------+---------------------------------------------------------------------------+
+  |       | the size of the **stack** and the **heap**.                               |
+  +-------+---------------------------------------------------------------------------+
+  |0x10000| Start of the memory shared between the PRUs.                              |
+  +-------+---------------------------------------------------------------------------+
+
+Using ``dd`` with no address prints the next section of memory.
+
+.. code-block:: bash
+
+  PRU0> *dd*
+  dd 
+  Absolute addr = 0x0000, offset = 0x0000, Len = 16
+  [0x0000] 0x00000000 0x00000000 0x00000000 0x00000000 
+  [0x0010] 0x00000000 0x00000000 0x00000000 0x00000000 
+  [0x0020] 0x00000000 0x00000000 0x00000000 0x00000000 
+  [0x0030] 0x00000000 0x00000000 0x00000000 0x00000000 
+
+The stack grows from higher memory to lower memory, so you often won't see 
+much around address ``0x0000``.
+
+.. code-block:: bash
+
+  PRU0> *dd 0x100*
+  dd 0x100
+  Absolute addr = 0x0100, offset = 0x0000, Len = 16
+  [0x0100] 0x00000001 0x00000002 0x00000003 0x00000004 
+  [0x0110] 0x00000004 0x00000003 0x00000002 0x00000001 
+  [0x0120] 0x00000001 0x00000000 0x00000000 0x00000000 
+  [0x0130] 0x00000000 0x00000200 0x862e5c18 0xfeb21aca 
+
+Here we see some values on the heap.
+
+.. code-block:: bash
+
+  PRU0> *dd 0x200*
+  dd 0x200
+  Absolute addr = 0x0200, offset = 0x0000, Len = 16
+  [0x0200] 0x00000001 0x00000004 0x00000002 0x00000003 
+  [0x0210] 0x00000003 0x00000011 0x00000004 0x00000010 
+  [0x0220] 0x0a4fe833 0xb222ebda 0xe5575236 0xc50cbefd 
+  [0x0230] 0xb037c0d7 0xf48bbe23 0x88c460f0 0x011550d4
+
+Data written explicity to ``0x0200`` of the DRAM.
+
+.. code-block:: bash
+
+  PRU0> *dd 0x10000*
+  dd 0x10000
+  Absolute addr = 0x10000, offset = 0x0000, Len = 16
+  [0x10000] 0x8ca9d976 0xebcb119e 0x3aebce31 0x68c44d8b 
+  [0x10010] 0xc370ba7e 0x2fea993b 0x15c67fa5 0xfbf68557 
+  [0x10020] 0x5ad81b4f 0x4a55071a 0x48576eb7 0x1004786b 
+  [0x10030] 0x2265ebc6 0xa27b32a0 0x340d34dc 0xbfa02d4b
+
+Here's the shared memory.
+
+You can also use ``prudebug`` to set breakpoints and single step, 
+but I haven't used that feature much.
+
+:ref:`../05blocks/blocks.html#_memory_allocation, Memory Allocation` gives examples 
+of how you can control where your vaiables are stored in memory.
+
+
+UART
+======
+
+Problem
+---------
+
+I'd like to use something like ``printf()`` to debug my code.
+
+.. TODO Check these on the Black and Pocket without grove
+
+Solution
+---------
+
+One simple, yet effective approach to 'printing' from the PRU is
+an idea taken from the Adruino playbook; 
+use the UART (serial port) to output debug information.  The PRU has it's
+own UART that can send characters to a serial port.
+
+You'll need a 3.3V FTDI cable to go between your Beagle and the USB port 
+on your host computer as shown in :ref:`debug_ftdi`. [#debug1]_ 
+you can get such a cable from places such as 
+`Sparkfun <https://www.sparkfun.com/products/9717>`_ or 
+`Adafruit <https://www.adafruit.com/product/70>`_.  
+
+.. _debug_ftdi:
+
+FTDI cable
+~~~~~~~~~~~
+
+.. figure:: figures/FTDIcable.jpg
+  :align: center
+  :alt: FTDI cable
+
+Discussion
+---------
+
+The Beagle side of the FTDI cable has a small triangle on it as shown in 
+:ref:`debug_ftdi_connector` which marks the ground pin, pin 1.  
+
+.. _debug_ftdi_connector:
+
+FTDI connector
+~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/FTDIconnector.jpg
+  :align: center
+  :alt: FTDI connector
+
+The :ref:`debug_FTDI` table shows which pins connect where and :ref:`debug_ftdi_pins`
+is a wiring diagram for the BeagleBone Black.
+
+.. _debug_FTDI:
+
+Wriing for FTDI cable to Beagle
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+  +--------+------+---------+-------------+--------+------+---------+
+  |FTDI pin|Color |Black pin|AI 1 pin     |AI 2 pin|Pocket|Function |
+  +========+======+=========+=============+========+======+=========+
+  |0       |black |P9_1     |P8_1         |P8_1    |P1_16 |ground   |
+  +--------+------+---------+-------------+--------+------+---------+
+  |4       |orange|P9_24    |P8_43        |P8_33a  |P1_12 |rx       |
+  +--------+------+---------+-------------+--------+------+---------+
+  |5       |yellow|P9_26    |P8_44        |P8_31a  |P1_06 |tx       |
+  +--------+------+---------+-------------+--------+------+---------+
+
+.. _debug_ftdi_pins:
+
+FTDI to BB Black
+~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/FTDIhookup_bb.png
+  :align: center
+  :alt: FTDI to BB Black
+
+Details
+~~~~~~~~
+
+Two examples of using the UART are presented here. The first 
+(:ref:`debug_uart1`) sends a character out the serial port then 
+waits for a character to come in. Once the new 
+character arrives another character is output.
+
+The second example (:ref:`debug_uart2`) prints out a string and then 
+waits for characters to arrive.
+Once an ENTER appears the string is sent back.
+
+.. tip:: 
+
+  On the Black, either PRU0 and PRU1 can 
+  run this code. Both have access to the same UART.
+
+You need to set the pin muxes.
+
+config-pin
+~~~~~~~~~~~
+
+.. code-block:: bash
+
+  # Configure tx Black
+  bone$ *config-pin P9_24 pru_uart*
+  # Configure rx Black
+  bone$ *config-pin P9_26 pru_uart*
+
+  # Configure tx Pocket
+  bone$ *config-pin P1_06 pru_uart*
+  # Configure rx Pocket
+  bone$ *config-pin P1_12 pru_uart*
+
+.. note::
+
+  See :ref:`../08ai/ai.html#ai_device_tree, Configuring pins on the AI via device trees` for configuring 
+  pins on the AI. Make sure your `rx` pins are configured as input pins in the device tree.
+
+For example 
+
+.. code-block:: bash
+
+  DRA7XX_CORE_IOPAD(0x3610, *PIN_INPUT* | MUX_MODE10) // C6: P8.33a:
+
+.. * TODO - Add code for Blue.
+
+uart1.pru1_0.c
+~~~~~~~~~~~~~~~
+
+Set the following variables so ``make`` will know what to compile.
+
+make
+~~~~~
+
+.. code-block:: bash
+
+  bone$ *make TARGET=uart1.pru0*
+  /var/lib/cloud9/common/Makefile:29: MODEL=TI_AM335x_BeagleBone_Black,TARGET=uart1.pru0
+  -    Stopping PRU 0
+  -	copying firmware file /tmp/cloud9-examples/uart1.pru0.out to /lib/firmware/am335x-pru0-fw
+  write_init_pins.sh
+  -    Starting PRU 0
+  MODEL   = TI_AM335x_BeagleBone_Black
+  PROC    = pru
+  PRUN    = 0
+  PRU_DIR = /dev/remoteproc/pruss-core0
+
+Now ``make`` will compile, load PRU0 and start it. 
+In a terminal window on your host computer run
+
+.. code-block:: bash
+
+  host$ *screen /dev/ttyUSB0 115200*
+
+It will initially display the first charters (``H``) and then as you enter
+characters on the keyboard, the rest of the message will appear.
+
+uart1.pru0.c output
+~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/uart1.pru0.png
+  :align: center
+  :alt: uart1.pru0.c output
+
+Here's the code (``uart1.pru1_0.c``) that does it.
+
+.. _debug_uart1:
+
+uart1.pru1_0.c
+~~~~~~~~~~~~~~~
+
+:download:`uart1.pru1_0.c <code/uart1.pru1_0.c>`
+
+.. note::
+
+  I'm using the AI version of the code since 
+  it uses variables with more desciptive names.
+
+The first part of the code initializes the UART. Then the line 
+``CT_UART.RBR_THR_REGISTERS = tx;`` takes a character in ``tx`` 
+and sends it to the transmit buffer on the UART. Think of 
+this as the UART version of the ``printf()``. 
+
+Later the line ``while (!((CT_UART.INTERRUPT_IDENTIFICATION_REGISTER_FIFO_CONTROL_REGISTER & 0x2) == 0x2));``
+waits for the transmitter FIFO to be empty.  This makes sure later characters
+won't overwrite the buffer before they can be sent.  The downside is, this will
+cause your code to wait on the buffer and it might miss an important 
+real-time event.
+
+The line ``while ((CT_UART.LINE_STATUS_REGISTER & 0x1) == 0x0);`` waits for an input from the 
+UART (possibly missing something) and ``rx = CT_UART.RBR_THR_REGISTERS;`` reads from the
+receive register on the UART.
+
+These simple lines should be enough to place in your code to print out
+debugging information.
+
+uart2.pru0.c
+~~~~~~~~~~~~
+
+If you want to try ``uart2.pru0.c``, run the following:
+
+make
+~~~~~
+
+.. code-block:: bash
+
+  bone$ *make TARGET=uart2.pru0*
+  /var/lib/cloud9/common/Makefile:29: MODEL=TI_AM335x_BeagleBone_Black,TARGET=uart2.pru0
+  -    Stopping PRU 0
+  -	copying firmware file /tmp/cloud9-examples/uart2.pru0.out to /lib/firmware/am335x-pru0-fw
+  write_init_pins.sh
+  -    Starting PRU 0
+  MODEL   = TI_AM335x_BeagleBone_Black
+  PROC    = pru
+  PRUN    = 0
+  PRU_DIR = /dev/remoteproc/pruss-core0
+
+You will see:
+
+uart2.pru0.c output
+~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/uart2.pru0.png
+  :align: center
+  :alt: uart2.pru0.c output
+
+Type a few characters and hit ENTER. The PRU will playback what you typed,
+but it won't echo it as you type.
+
+``uart2.pru0.c`` defines ``PrintMessageOut()`` which is passed a string that is
+sent to the UART. It takes advantage of the eight character FIFO on the UART.
+Be careful using it because it also uses ``while (!CT_UART.LSR_bit.TEMT);`` to
+wait for the FIFO to empty, which may cause your code to miss something.
+
+:ref:`debug_uart2` is the code that does it.
+
+.. _debug_uart2:
+
+uart2.pru1_0.c
+~~~~~~~~~~~~~~~
+
+:download:`uart2.pru1_0.c <code/uart2.pru1_0.c>`
+
+More complex examples can be built using the principles shown in these examples.
+
+Copyright
+==========
+
+copyright.c
+~~~~~~~~~~~~~
+
+:download:`copyright.c <code/copyright.c>`
+
+.. rubric:: Footnotes
+
+.. [#debug1] FTDI images are from the BeagleBone Cookbook http://shop.oreilly.com/product/0636920033899.do
\ No newline at end of file
diff --git a/pru-cookbook/04debug/figures/FTDIcable.jpg b/pru-cookbook/04debug/figures/FTDIcable.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..80d8e01563cf6781849b305f7f45de40184caca3
Binary files /dev/null and b/pru-cookbook/04debug/figures/FTDIcable.jpg differ
diff --git a/pru-cookbook/04debug/figures/FTDIconnector.jpg b/pru-cookbook/04debug/figures/FTDIconnector.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3517708cffa8b349f8bb6ebe06525a606d338a68
Binary files /dev/null and b/pru-cookbook/04debug/figures/FTDIconnector.jpg differ
diff --git a/pru-cookbook/04debug/figures/FTDIhookup.fzz b/pru-cookbook/04debug/figures/FTDIhookup.fzz
new file mode 100644
index 0000000000000000000000000000000000000000..561602594f87e6d1a778136f4fe67533bbde4316
Binary files /dev/null and b/pru-cookbook/04debug/figures/FTDIhookup.fzz differ
diff --git a/pru-cookbook/04debug/figures/FTDIhookup_bb.png b/pru-cookbook/04debug/figures/FTDIhookup_bb.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec7b447a35ff5f1e7d6ecf5539b357833d05563a
Binary files /dev/null and b/pru-cookbook/04debug/figures/FTDIhookup_bb.png differ
diff --git a/pru-cookbook/04debug/figures/LED.fzz b/pru-cookbook/04debug/figures/LED.fzz
new file mode 100644
index 0000000000000000000000000000000000000000..ab3d81aa9a29a2b01a4d980ca8d72a032562aa6f
Binary files /dev/null and b/pru-cookbook/04debug/figures/LED.fzz differ
diff --git a/pru-cookbook/04debug/figures/LED_bb.png b/pru-cookbook/04debug/figures/LED_bb.png
new file mode 100644
index 0000000000000000000000000000000000000000..40533edaec88bfa756d5908aca4dddcdc8a9ca48
Binary files /dev/null and b/pru-cookbook/04debug/figures/LED_bb.png differ
diff --git a/pru-cookbook/04debug/figures/uart1.pru0.png b/pru-cookbook/04debug/figures/uart1.pru0.png
new file mode 100644
index 0000000000000000000000000000000000000000..beffa2c6189e7c831d0fbf8f57848bcd0995a5c7
Binary files /dev/null and b/pru-cookbook/04debug/figures/uart1.pru0.png differ
diff --git a/pru-cookbook/04debug/figures/uart2.pru0.png b/pru-cookbook/04debug/figures/uart2.pru0.png
new file mode 100644
index 0000000000000000000000000000000000000000..12c32441ff36ed34c811fce0ce88754103237139
Binary files /dev/null and b/pru-cookbook/04debug/figures/uart2.pru0.png differ
diff --git a/pru-cookbook/05blocks/blocks.rst b/pru-cookbook/05blocks/blocks.rst
new file mode 100644
index 0000000000000000000000000000000000000000..e6de06e35ef9851530791b1518ba28ef68a765c4
--- /dev/null
+++ b/pru-cookbook/05blocks/blocks.rst
@@ -0,0 +1,1977 @@
+.. _pru-cookbook-blocks:
+
+Building Blocks - Applications
+###############################
+
+Here are some examples that use the basic PRU building blocks.
+
+The following are resources used in this chapter.
+
+Resources
+~~~~~~~~~~
+
+* `PRU Optimizing C/C++ Compiler, v2.2, User's Guide <http://www.ti.com/lit/ug/spruhv7b/spruhv7b.pdf>`_
+* `AM572x Technical Reference Manual <http://www.ti.com/lit/pdf/spruhz6l>`_ (AI)
+* `AM335x Technical Reference Manual <http://www.ti.com/lit/pdf/spruh73>`_ (All others)
+* `Exploring BeagleBone by Derek Molloy <http://exploringbeaglebone.com/>`_
+* `WS2812 Data Sheet <https://cdn-shop.adafruit.com/datasheets/WS2812.pdf>`_
+
+Memory Allocation
+==================
+
+
+Problem
+---------
+
+I want to control where my variables are stored in memory.
+
+.. TODO Include a section on accessing DDR.
+
+Solution
+---------
+
+Each PRU has is own 8KB of data memory (Data Mem0 and Mem1) and 12KB of 
+shared memory (Shared RAM) as shown in :ref:`blocks_PRU_block_diagram`.
+
+.. _blocks_PRU_block_diagram:
+
+PRU Block Diagram
+~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/blockDiagram.png
+  :align: center
+  :alt: PRU Block diagram
+
+Each PRU accesses it's own DRAM starting at location 0x0000_0000. Each PRU
+can also access the other PRU's DRAM starting at 0x0000_2000. Both PRUs 
+access the shared RAM at 0x0001_0000. The compiler can control where each 
+of these memories variables are stored.
+
+:ref:`blocks_shared` shows how to allocate seven variable in six different locations.
+
+.. _blocks_shared:
+
+shared.pro0.c - Examples of Using Different Memory Locations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`shared.pru0.c <code/shared.pru0.c>`
+
+
+Discussion
+-----------
+
+Here's the line-by-line
+
+Line-byline for shared.pru0.c
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |Line   | Explanation                                                                                             |
+  +=======+=========================================================================================================+
+  |7      | `PRU_SRAM` is defined here.  It will be used later to declare variables                                 |
+  |       | in the `Shared RAM` location of memory.  Section 5.5.2 on page 75 of the                                |
+  |       | `PRU Optimizing C/C++ Compiler, v2.2, User's Guide <http://www.ti.com/lit/ug/spruhv7b/spruhv7b.pdf>`_   |
+  |       | gives details of the command.  The `PRU_SHAREDMEM`                                                      |
+  |       | refers to the memory section defined in `am335x_pru.cmd` on line 26.                                    |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |8, 9   | These are like the previous line except for the DMEM sections.                                          |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |16     | Variables declared outside of `main()` are put on the heap.                                             |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |17     | Adding `PRU_SRAM` has the variable stored in the shared memory.                                         |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |18, 19 | These are stored in the PRU's local RAM.                                                                |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |20, 21 | These lines are for storing in the `.bss` section as declared on                                        |
+  |       | line 74 of `am335x_pru.cmd`.                                                                            |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |28-31  | All the previous examples direct the compiler to an area in memory                                      |
+  |       | and the compilers figures out what to put where.  With these lines we                                   |
+  |       | specify the exact location.  Here are start with the PRU_DRAM starting                                  |
+  |       | address and add 0x200 to it to avoid                                                                    |
+  |       | the **stack** and the **heap**.  The advantage of this technique is you can                             |
+  |       | easily share these variables between the ARM and the two PRUs.                                          |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |36, 37 | Variable declared inside `main()` go on the stack.                                                      |
+  +-------+---------------------------------------------------------------------------------------------------------+
+
+.. caution::
+
+  Using the technique of line 28-31 you can put variables anywhere, even where the 
+  compiler has put them. Be careful, it's easy to overwrite what the compiler has done
+
+Compile and run the program.
+
+.. code-block:: bash
+
+  bone$ *source shared_setup.sh* 
+  TARGET=shared.pru0
+  Black Found
+  P9_31
+  Current mode for P9_31 is:     pruout
+  Current mode for P9_31 is:     pruout
+  P9_29
+  Current mode for P9_29 is:     pruout
+  Current mode for P9_29 is:     pruout
+  P9_30
+  Current mode for P9_30 is:     pruout
+  Current mode for P9_30 is:     pruout
+  P9_28
+  Current mode for P9_28 is:     pruout
+  Current mode for P9_28 is:     pruout
+  bone$ *make*
+  /var/lib/cloud9/common/Makefile:29: MODEL=TI_AM335x_BeagleBone_Black,TARGET=shared.pru0
+  -    Stopping PRU 0
+  -	copying firmware file /tmp/cloud9-examples/shared.pru0.out to /lib/firmware/am335x-pru0-fw
+  write_init_pins.sh
+  -    Starting PRU 0
+  MODEL   = TI_AM335x_BeagleBone_Black
+  PROC    = pru
+  PRUN    = 0
+  PRU_DIR = /sys/class/remoteproc/remoteproc1
+
+Now check the **symbol table** to see where things are allocated.
+
+.. code-block:: bash
+
+  bone $ *grep shared /tmp/cloud9-examples/shared.pru0.map* 
+  ....
+  1     0000011c  shared_0                     
+  2     00010000  shared_1                     
+  1     00000000  shared_2                     
+  1     00002000  shared_3                     
+  1     00000118  shared_4                     
+  1     00000120  shared_5
+
+We see, ``shared_0`` had no directives and was places in the heap that is 0x100
+to 0x1ff.  ``shared_1`` was directed to go to the SHAREDMEM, ``shared_2`` to 
+the start of the local DRAM (which is also the top of the stack).  ``shared_3``
+was placed in the DRAM of PRU 1, ``shared_4`` was placed in the ``.bss`` section,
+which is in the **heap**.  Finally ``shared_5`` is a pointer to where the value
+is stored.
+
+Where are ``shared_6`` and ``shared_7``?  They are declared inside ``main()`` and are
+therefore placed on the stack at run time.  The ``shared.map`` file shows the
+compile time allocations.  We have to look in the memory itself to see what
+happen at run time.
+
+Let's fire up ``prudebug`` 
+(:ref:`../04debug/debug.html#debug_prudebug, prudebug - A Simple Debugger for the PRU`)
+to see where things are.
+
+.. code-block:: bash
+
+  bone$ *sudo ./prudebug*
+  PRU Debugger v0.25
+  (C) Copyright 2011, 2013 by Arctica Technologies.  All rights reserved.
+  Written by Steven Anderson
+
+  Using /dev/mem device.
+  Processor type		AM335x
+  PRUSS memory address	0x4a300000
+  PRUSS memory length	0x00080000
+
+          offsets below are in 32-bit byte addresses (not ARM byte addresses)
+          PRU            Instruction    Data         Ctrl
+          0              0x00034000     0x00000000   0x00022000
+          1              0x00038000     0x00002000   0x00024000
+
+  PRU0> *d 0*
+  Absolute addr = 0x0000, offset = 0x0000, Len = 16
+  [0x0000] 0x0000feed 0x00000000 0x00000000 0x00000000 
+  [0x0010] 0x00000000 0x00000000 0x00000000 0x00000000 
+  [0x0020] 0x00000000 0x00000000 0x00000000 0x00000000 
+  [0x0030] 0x00000000 0x00000000 0x00000000 0x00000000 
+
+The value of ``shared_2`` is in memory location 0.
+
+.. code-block:: bash
+
+  PRU0> *dd 0x100*
+  Absolute addr = 0x0100, offset = 0x0000, Len = 16
+  [0x0100] 0x00000000 0x00000001 0x00000000 0x00000000 
+  [0x0110] 0x00000000 0x00000000 0x0000beed 0x0000feef 
+  [0x0120] 0x00000200 0x3ec71de3 0x1a013e1a 0xbf2a01a0 
+  [0x0130] 0x111110b0 0x3f811111 0x55555555 0xbfc55555 
+
+There are ``shared_0`` and ``shared_4`` in the heap, but where is ``shared_6`` and
+``shared_7``?  They are supposed to be on the **stack** that starts at 0.
+
+.. code-block:: bash
+
+  PRU0> dd *0xc0*
+  Absolute addr = 0x00c0, offset = 0x0000, Len = 16
+  [0x00c0] 0x00000000 0x00000000 0x00000000 0x00000000 
+  [0x00d0] 0x00000000 0x00000000 0x00000000 0x00000000 
+  [0x00e0] 0x00000000 0x00000000 0x00000000 0x00000000 
+  [0x00f0] 0x00000000 0x00000000 0x00004321 0x00009876
+
+There they are; the stack grows from the top. (The heap grows from the bottom.)
+
+.. code-block:: bash
+  
+  PRU0> dd *0x2000*
+  Absolute addr = 0x2000, offset = 0x0000, Len = 16
+  [0x2000] 0x0000deed 0x00000001 0x00000000 0x557fcfb5 
+  [0x2010] 0xce97bd0f 0x6afb2c8f 0xc7f35df4 0x5afb6dcb 
+  [0x2020] 0x8dec3da3 0xe39a6756 0x642cb8b8 0xcb6952c0 
+  [0x2030] 0x2f22ebda 0x548d97c5 0x9241786f 0x72dfeb86 
+
+And there is PRU 1's memory with ``shared_3``. And finally the shared memory.
+
+.. code-block:: bash
+
+  PRU0> *dd 0x10000*
+  Absolute addr = 0x10000, offset = 0x0000, Len = 16
+  [0x10000] 0xdeadbeef 0x0000feed 0x00000000 0x68c44f8b 
+  [0x10010] 0xc372ba7e 0x2ffa993b 0x11c66da5 0xfbf6c5d7 
+  [0x10020] 0x5ada3fcf 0x4a5d0712 0x48576fb7 0x1004796b 
+  [0x10030] 0x2267ebc6 0xa2793aa1 0x100d34dc 0x9ca06d4a
+
+The compiler offers great control over where variables are stored. Just
+be sure if you are hand picking where things are put, not to put them in places 
+used by the compiler.
+
+Auto Initialization of built-in LED Triggers
+=============================================
+
+Problem
+-----------
+
+I see the built-in LEDs blink to their own patterns. 
+How do I turn this off? Can this be automated?
+
+Solution
+---------
+
+Each built-in LED has a default action (trigger) when the Bone boots up. 
+This is controlled by ``/sys/class/leds``.
+
+.. code-block:: bash
+
+  bone$ *cd /sys/class/leds*
+  bone$ *ls*
+  beaglebone:green:usr0  beaglebone:green:usr2
+  beaglebone:green:usr1  beaglebone:green:usr3
+
+Here you see a directory for each of the LEDs.  Let's pick USR1.
+
+.. code-block:: bash
+
+  bone$ *cd beaglebone\:green\:usr1*
+  bone$ *ls*
+  brightness  device  max_brightness  power  subsystem  trigger  uevent
+  bone$ *cat trigger*
+  none usb-gadget usb-host rfkill-any rfkill-none kbd-scrolllock kbd-numlock 
+  kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock 
+  kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock *[mmc0]* timer 
+  oneshot disk-activity disk-read disk-write ide-disk mtd nand-disk heartbeat 
+  backlight gpio cpu cpu0 activity default-on panic netdev phy0rx phy0tx
+  phy0assoc phy0radio rfkill0 
+
+Notice ``[mmc0]`` is in brackets.  This means it's the current trigger; it flashes 
+when the built-in flash memory is in use.  You can turn this off using:
+
+.. code-block:: bash
+
+  bone$ *echo none > trigger*
+  bone$ *cat trigger*
+  *[none]* usb-gadget usb-host rfkill-any rfkill-none kbd-scrolllock kbd-numlock 
+  kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock 
+  kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock mmc0 timer 
+  oneshot disk-activity disk-read disk-write ide-disk mtd nand-disk heartbeat 
+  backlight gpio cpu cpu0 activity default-on panic netdev phy0rx phy0tx
+  phy0assoc phy0radio rfkill0  
+
+Now it is no longer flashing.
+
+How can this be automated so when code is run that needs the trigger off, it's 
+turned off automatically?  Here's a trick.  Include the following in your code.
+
+.. code-block:: bash
+  :linenos:
+
+  #pragma DATA_SECTION(init_pins, ".init_pins")
+  #pragma RETAIN(init_pins)
+  const char init_pins[] =  
+          "/sys/class/leds/beaglebone:green:usr3/trigger\0none\0" \
+          "\0\0";
+
+Lines 3 and 4 declare the array ``init_pins`` to have an entry which is the path 
+to ``trigger`` and the value that should be 'echoed' into it. Both are NULL
+terminated.  Line 1 says to put this in a section called ``.init_pins`` and 
+line 2 says to ``RETAIN`` it.  That is don't throw it away if it appears to be 
+unused.
+
+Discussion
+-----------
+
+The above code stores this array in the ``.out`` file thats created, but that's not 
+enough. You need to run :ref:`blocks_write_init_pins` on the ``.out`` file to make 
+the code work.  Fortunately the Makefile always runs it.
+
+.. _blocks_write_init_pins:
+
+write_init_pins.sh
+~~~~~~~~~~~~~~~~~~~
+
+:download:`write_init_pins.sh <code/write_init_pins.sh>`
+
+The ``readelf`` command extracts the path and value from the ``.out`` file.
+
+.. code-block:: bash
+
+  bone$ *readelf -x .init_pins /tmp/pru0-gen/shared.out* 
+
+  Hex dump of section '.init_pins':
+    0x000000c0 2f737973 2f636c61 73732f6c 6564732f /sys/class/leds/
+    0x000000d0 62656167 6c65626f 6e653a67 7265656e beaglebone:green
+    0x000000e0 3a757372 332f7472 69676765 72006e6f :usr3/trigger.no
+    0x000000f0 6e650000 0000                       ne....
+
+The rest of the command formats it. Finally line 6 echos the ``none`` into the path.
+
+This can be generalized to initialize other things.  The point is, the ``.out`` 
+file contains everything needed to run the executable.
+
+
+.. _blocks_pwm:
+
+PWM Generator
+==============
+
+One of the simplest things a PRU can to is generate a simple
+signal starting with a single channel PWM that has a fixed frequency and
+duty cycle and ending with a multi channel PWM that the ARM can change
+the frequency and duty cycle on the fly.  
+
+Problem
+---------
+
+I want to generate a PWM signal that has a fixed frequency and duty cycle.
+
+Solution
+---------
+
+The solution is fairly easy, but be sure to check the *Discussion* section
+for details on making it work.
+
+:ref:`blocks_pwm1` shows the code.
+
+.. warning::
+  This code is for the BeagleBone Black. 
+  See ``pwm1.pru1_1.c`` for an example
+  that works on the AI.
+
+.. _blocks_pwm1:
+
+pwm1.pru0.c 
+~~~~~~~~~~~~
+
+:download:`pwm1.pru0.c <code/pwm1.pru0.c>`
+
+To run this code you need to configure the pin muxes to output the PRU.  If you are on the Black run
+
+.. code-block:: bash
+
+  bone$ config-pin P9_31 pruout
+
+On the Pocket run
+
+.. code-block:: bash
+
+  bone$ config-pin P1_36 pruout
+
+
+.. note::
+
+  See :ref:`../08ai/ai.html#ai_device_tree, Configuring pins on the AI via device trees` 
+  for configuring pins on the AI.
+
+Then, tell ``Makefile`` which PRU you are compiling for and what your target file is
+
+.. code-block:: bash
+
+  bone$ export TARGET=pwm1.pru0
+
+Now you are ready to compile
+
+.. code-block:: bash
+
+  bone$ make
+  /var/lib/cloud9/common/Makefile:29: MODEL=TI_AM335x_BeagleBone_Black,TARGET=pwm1.pru0
+  -    Stopping PRU 0
+  -	copying firmware file /tmp/cloud9-examples/pwm1.pru0.out to /lib/firmware/am335x-pru0-fw
+  write_init_pins.sh
+  -    Starting PRU 0
+  MODEL   = TI_AM335x_BeagleBone_Black
+  PROC    = pru
+  PRUN    = 0
+  PRU_DIR = /sys/class/remoteproc/remoteproc1
+
+Now attach an LED (or oscilloscope) to ``P9_31`` on the Black 
+or ``P1.36`` on the Pocket.  You should see a squarewave.
+
+Discussion
+-----------
+
+Since this is our first example we'll discuss the many parts in detail.
+
+pwm1.pru0.c
+~~~~~~~~~~~~
+
+:ref:`blocks_pwm1_line_by_line` is a line-by-line expanation of the c code.
+
+.. _blocks_pwm1_line_by_line:
+
+Line-by-line of pwm1.pru0.c
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+  +-----+-------------------------------------------------------------------------------------+
+  |Line | Explanation                                                                         |
+  +=====+=====================================================================================+
+  |1    | Standard c-header include                                                           |
+  +-----+-------------------------------------------------------------------------------------+
+  |2    | Include for the PRU.  The compiler knows where to find this since the               |
+  |     | `Makefile` says to look for includes in `/usr/lib/ti/pru-software-support-package`  |
+  +-----+-------------------------------------------------------------------------------------+
+  |3    | The file `resource_table_empty.h` is used by the PRU loader.  Generally we'll       |
+  |     | use the same file, and don't need to modify it.                                     |
+  +-----+-------------------------------------------------------------------------------------+
+  |4    | This include has addresses for the GPIO ports and some bit positions for            |
+  |     | some of the headers.                                                                |
+  +-----+-------------------------------------------------------------------------------------+
+
+Here's what's in ``resource_table_empty.h``
+
+resource_table_empty.c 
+~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`resource_table_empty.h <code/resource_table_empty.h>`
+
+Line-by-line (continuted)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+  +-----+-----------------------------------------------------------------------------------------------------------------+
+  |Line | Explanation                                                                                                     |
+  +=====+=================================================================================================================+
+  |6-7  | `pass:[__]R30` and `pass:[__]R31` are two variables that refer to the                                           |
+  |     | PRU output (`pass:[__]R30`) and input (`pass:[__]R31`) registers.                                               |
+  |     | When you write something to `pass:[__]R30` it will show up on the                                               |
+  |     | corresponding output pins. When you read from `pass:[__]R31`                                                    |
+  |     | you read the data on the input pins.                                                                            |
+  |     | NOTE: Both names begin with two underscore's. Section 5.7.2 of the                                              |
+  |     | http://www.ti.com/lit/ug/spruhv7b/spruhv7b.pdf[PRU Optimizing C/C++ Compiler, v2.2, User's Guide]               |
+  |     | gives more details.                                                                                             |
+  +-----+-----------------------------------------------------------------------------------------------------------------+
+  |11   | This line selects which GPIO pin to toggle.  The table below shows which bits in `pass:[__]R30`                 |
+  |     | map to which pins                                                                                               |
+  +-----+-----------------------------------------------------------------------------------------------------------------+
+  |14   | `CT_CFG.SYSCFG_bit.STANDBY_INIT` is set to `0` to enable the OCP master port. More details on this              |
+  |     | and thousands of other regesters see the                                                                        |
+  |     | https://www.ti.com/lit/ug/spruh73p/spruh73p.pdf[AM335x Technical Reference Manual]. Section 4 is on the PRU     |
+  |     | and section 4.5 gives details for all the registers.                                                            |
+  +-----+-----------------------------------------------------------------------------------------------------------------+
+
+Bit 0 is the LSB.
+
+.. TODO fill in Blue
+
+.. _blocks_mapping_bits:
+
+Mapping bit positions to pin names
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table:: 
+
+  +---+---+---------------------+-----------+
+  |PRU|Bit|Black pin            |Pocket pin |
+  +===+===+=====================+===========+
+  |0  |0  |P9_31                |P1.36      |
+  +---+---+---------------------+-----------+
+  |0  |1  |P9_29                |P1.33      |
+  +---+---+---------------------+-----------+
+  |0  |2  |P9_30                |P2.32      |
+  +---+---+---------------------+-----------+
+  |0  |3  |P9_28                |P2.30      |
+  +---+---+---------------------+-----------+
+  |0  |4  |P9_42b               |P1.31      |
+  +---+---+---------------------+-----------+
+  |0  |5  |P9_27                |P2.34      |
+  +---+---+---------------------+-----------+
+  |0  |6  |P9_41b               |P2.28      |
+  +---+---+---------------------+-----------+
+  |0  |7  |P9_25                |P1.29      |
+  +---+---+---------------------+-----------+
+  |0  |14 |P8_12(out) P8_16(in) |P2.24      |
+  +---+---+---------------------+-----------+
+  |0  |15 |P8_11(out) P8_15(in) |P2.33      |
+  +---+---+---------------------+-----------+
+  |   |   |                     |           |
+  +---+---+---------------------+-----------+
+  |1  |0  |P8_45                |           |
+  +---+---+---------------------+-----------+
+  |1  |1  |P8_46                |           |
+  +---+---+---------------------+-----------+
+  |1  |2  |P8_43                |           |
+  +---+---+---------------------+-----------+
+  |1  |3  |P8_44                |           |
+  +---+---+---------------------+-----------+
+  |1  |4  |P8_41                |           |
+  +---+---+---------------------+-----------+
+  |1  |5  |P8_42                |           |
+  +---+---+---------------------+-----------+
+  |1  |6  |P8_39                |           |
+  +---+---+---------------------+-----------+
+  |1  |7  |P8_40                |           |
+  +---+---+---------------------+-----------+
+  |1  |8  |P8_27                |P2.35      |
+  +---+---+---------------------+-----------+
+  |1  |9  |P8_29                |P2.01      |
+  +---+---+---------------------+-----------+
+  |1  |10 |P8_28                |P1.35      |
+  +---+---+---------------------+-----------+
+  |1  |11 |P8_30                |P1.04      |
+  +---+---+---------------------+-----------+
+  |1  |12 |P8_21                |           |
+  +---+---+---------------------+-----------+
+  |1  |13 |P8_20                |           |
+  +---+---+---------------------+-----------+
+  |1  |14 |                     |P1.32      |
+  +---+---+---------------------+-----------+
+  |1  |15 |                     |P1.30      |
+  +---+---+---------------------+-----------+
+  |1  |16 |P9_26(in)|           |           |
+  +---+---+---------------------+-----------+
+
+.. note::
+
+  See :ref:`../08ai/ai.html#ai_device_tree, Configuring pins on the AI via device trees` 
+  for all the PRU pins on the AI.
+
+Since we are running on PRU 0, and we're using ``0x0001``, 
+that is bit 0, we'll be toggling ``P9_31``.
+
+Line-by-line (continued again)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+  +-----+-----------------------------------------------------------------------+
+  |Line | Explanation                                                           |
+  +=====+=======================================================================+
+  |17   | Here is where the action is.  This line reads ``pass:[__]R30`` and    |
+  |     | then ORs it with ``gpio``, setting the bits where there is            |
+  |     | a 1 in ``gpio`` and leaving the bits where there is a 0.              |
+  |     | Thus we are setting the bit we selected. Finally the new              |
+  |     | value is written back to ``pass:[__]R30``.                            |
+  +-----+-----------------------------------------------------------------------+
+  |18   | ``pass:[__]delay_cycles`` is an ((instrinsic function)) that delays   |
+  |     | with number of cycles passed to it. Each cycle is 5ns,                |
+  |     | and we are delaying 100,000,000 cycles which is                       |
+  |     | 500,000,000ns, or 0.5 seconds.                                        |
+  +-----+-----------------------------------------------------------------------+
+  |19   | This is like line 17, but ``~gpio`` inverts all the bits in ``gpio``  |
+  |     | so that where we had a 1, there is now a 0.  This 0                   |
+  |     | is then ANDed with ``pass:[__]R30`` setting the corresponding         |
+  |     | bit to 0.  Thus we are clearing the bit we selected.                  |
+  +-----+-----------------------------------------------------------------------+
+
+
+.. tip::
+
+  You can read more about instrinsics in section 5.11 of the 
+  (`PRU Optimizing C/C++ Compiler, v2.2, User's Guide <http://www.ti.com/lit/ug/spruhv7b/spruhv7b.pdf>`_.)
+
+
+When you run this code and look at the output you will see something like the following figure.
+
+Output of pwm1.pru0.c with 100,000,000 delays cycles giving a 1s period
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/pwm1.png
+  :align: center
+  :alt: pwm1.pru0.c output
+
+Notice the on time (``+Width(1)``) is 500ms, just as we predicted.  
+The off time is 498ms, which is only 2ms off from our prediction. 
+The standard deviation is 0, or only 380as, which is 380 * 10^-18^!.
+
+You can see how fast the PRU can run by setting both of the 
+``pass:[__]delay_cycles`` to 0. This results in the next figure.
+
+Output of pwm1.pru0c with 0 delay cycles
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/pwm2.png
+  :align: center
+  :alt: pwm1.pru0.c output with 0 delay
+
+Notice the period is 15ns which gives us a frequency of about 67MHz. At this high 
+frequency the breadboard that I'm using distorts the waveform so it's no longer a squarewave. 
+The **on** time is 5.3ns and the **off** time is 9.8ns.  That means **pass:[__]R30 |= gpio** 
+took only one 5ns cycle and ``pass:[__]R30 &= ~gpio`` also only took one cycle, but there 
+is also an extra cycle needed for the loop.  This means the compiler was able to implement 
+the ``while`` loop in just three 5ns instructions!  Not bad.
+
+We want a square wave, so we need to add a delay to correct for the delay of looping back.
+
+Here's the code that does just that.
+
+pwm2.pru0.c 
+~~~~~~~~~~~~~
+
+:download:`pwm2.pru0.c <code/pwm2.pru0.c>`
+
+The output now looks like:
+
+Output of pwm2.pru0.c corrected delay
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/pwm3.png
+  :align: center
+  :alt: pwm2.c corrected delay
+
+It's not hard to adjust the two ``pass:[__]delay_cycles`` 
+to get the desired frequency and duty cycle.
+
+### Controlling the PWM Frequency
+#### Problem
+You would like to control the frequency and 
+duty cycle of the PWM without recompiling.
+
+#### Solution
+Have the PRU read the **on** and **off** times from a shared memory location. 
+Each PRU has is own 8KB of data memory (DRAM) and 12KB of shared memory 
+(SHAREDMEM) that the ARM processor can also access.  See :ref:`blocks_PRU_block_diagram`.
+
+The DRAM 0 address is 0x0000 for PRU 0.  The same DRAM appears at address 
+0x4A300000 as seen from the ARM processor.
+
+.. tip::
+
+  See page
+  184 of the https://www.ti.com/lit/ug/spruh73p/spruh73p.pdf[AM335x Technical Reference Manual].  
+
+We take the previous PRU code and add the lines
+ 
+.. code-block:: C
+
+  #define PRU0_DRAM		0x00000			// Offset to DRAM
+  volatile unsigned int *pru0_dram = PRU0_DRAM;
+
+to define a pointer to the DRAM.
+
+.. note::
+
+  The `volatile` keyword is used here to tell the compiler the value this
+  points to may change, so don't make any assumptions while optimizing.
+
+
+Later in the code we use
+ 
+.. code-block:: C
+
+	pru0_dram[ch] = on[ch];		    // Copy to DRAM0 so the ARM can change it
+	pru0_dram[ch+MAXCH] = off[ch];	// Copy after the on array
+
+to write the `on` and `off` times to the DRAM.  Then inside the `while` loop we use 
+
+.. code-block:: c
+
+	onCount[ch] = pru0_dram[2*ch];		// Read from DRAM0
+	offCount[ch]= pru0_dram[2*ch+1];
+
+to read from the DRAM when reseting the counters.  Now, while the PRU is running, 
+the ARM can write values into the DRAM and change the PWM on and off times. 
+:ref:`blocks_pwm4` is the whole code.
+
+.. _blocks_pwm4:
+
+pwm4.pru0.c 
+~~~~~~~~~~~~
+
+:download:`pwm4.pru0.c <code/pwm4.pru0.c>`
+
+Here is code that runs on the ARM side to set the on and off time values.
+
+pwm-test.c 
+~~~~~~~~~~~~
+
+:download:`pwm-test.c <code/pwm-test.c>`
+
+A quick check on the 'scope shows :ref:`blocks_pwm_arm_control`.
+
+.. _blocks_pwm_arm_control:
+
+Four Channel PWM with ARM control
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/pwm4.png
+  :align: center
+  :alt: pwm4.png
+
+From the 'scope you see a 1 cycle **on** time results in a 450ns wide pulse and a 
+3.06us period is 326KHz, much slower than the 10ns pulse we saw before.  But it 
+may be more than fast enough for many applications.  For example, most servos run at 50Hz.
+
+But we can do better.
+
+Loop Unrolling for Better Performance
+======================================
+
+Problem
+-----------
+
+The ARM controlled PRU code runs too slowly.
+
+Solution
+-----------
+
+Simple loop unrolling can greatly improve the speed.  ``pwm5.pru0.c`` is our unrolled
+version.
+
+pwm5.pru0.c Unrolled
+~~~~~~~~~~~~~~~~~~~~~
+
+:download:`pwm5.pru0.c <code/pwm5.pru0.c>`
+
+The output of ``pwm5.pru0.c`` is in the figure below.
+
+pwm5.pru0.c Unrolled version of pwm4.pru0.c
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/pwm5_no_loop.png
+  :align: center
+  :alt: pwm5.pru0.c Unrolled version of pwm4.pru0.c
+
+It's running about 6 times faster than ``pwm4.pru0.c``.
+
+pwm4.pru0.c vs. pwm5.pru0.c
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+  
+  +---------+-----------------+-----------------+---------+-----------------------+---------+
+  |Measure  |pwm4.pru0.c time |pwm5.pru0.c time |Speedup  |pwm5.pru0.c w/o UNROLL |Speedup  |
+  +---------+-----------------+-----------------+---------+-----------------------+---------+
+  |Period   |3.06&mu;s        |510ns            |6x       |1.81&mu;s              |~1.7x    |
+  +---------+-----------------+-----------------+---------+-----------------------+---------+
+  |Width+   |450ns            |70ns             |~6x      |1.56&mu;s              |~.3x     |
+  +---------+-----------------+-----------------+---------+-----------------------+---------+
+
+Not a bad speed up for just a couple of simple changes.
+
+Discussion
+-----------
+
+Here's how it works.
+First look at line 39.  You see ``#pragma UNROLL(MAXCH)`` which is a ``pragma``
+that tells the compiler to unroll the loop that follows.  We are unrolling it
+``MAXCH`` times (four times in this example). Just removing the ``pragma`` causes
+the speedup compared to the ``pwm4.pru0.c`` case to drop from 6x to only 1.7x.  
+
+We also have our ``for`` loop inside the ``while`` loop that can be unrolled.
+Unfortunately ``UNROLL()`` doesn't work on it, therefore we have to do it by
+hand. We could take the loop and just copy it three times, but that would
+make it harder to maintain the code.  Instead I convered the loop into a 
+``#define`` (lines 14-24) and invoked ``update()`` as needed (lines 48-51).
+This is not a function call. Whenever the preprocessor sees the ``update()`` 
+it copies the code an then it's compiled.
+
+This unrolling gets us an impressive 6x speedup.
+
+Making All the Pulses Start at the Same Time
+=============================================
+
+Problem
+-----------
+
+I have a mutlichannel PWM working, but the pulses aren't synchronized, that is
+they don't all start at the same time.
+
+Solution
+-----------
+
+:ref:`blocks_zoomed` is a zoomed in version of the previous figure. Notice the pulse 
+in each channel starts about 15ns later than the channel above it.
+
+.. _blocks_zoomed:
+
+pwm5.pru0 Zoomed In 
+~~~~~~~~~~~~~~~~~~~~~
+.. figure:: figures/pwm5_zoomed.png
+  :align: center
+  :alt: pwm5.pru0 zoomed.png
+
+The solution is to declare ``Rtmp`` (line 35) which holds the value for ``pass:[__]R30``.
+
+pwm6.pru0.c Sync'ed Version of pwm5.pru0.c 
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`pwm6.pru0.c Sync'ed Version of pwm5.pru0.c <code/pwm6.pru0.c>`
+
+Each channel writes it's value to ``Rtmp`` (lines 17 and 20) and then after
+each channel has updated, ``Rtmp`` is copied to ``pass:[__]R30`` (line 54).
+
+Discussion
+-----------
+
+The following figure shows the channel are sync'ed. Though the period is slightly
+longer than before.
+
+pwm6.pru0 Synchronized Channels
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/pwm6_synced.png
+  :align: center
+  :alt: pwm6.pru0 Synchronized Channels
+
+
+Adding More Channels via PRU 1
+================================
+
+Problem
+-----------
+
+You need more output channels, or you need to shorten the period.
+
+Solution
+-----------
+
+PRU 0 can output up to eight output pins (see 
+:ref:`blocks_mapping_bits`). The code presented so far
+can be easily extended to use the eight output pins.
+
+But what if you need more channels?
+You can always use PRU1, it has 14 output pins.
+
+Or, what if four channels is enough, but you need a shorter period. Everytime
+you add a channel, the overall period gets longer.  Twice as many channels 
+means twice as long a period.  If you move half the channels to PRU 1, you
+will make the period half as long.
+
+Here's the code (``pwm7.pru0.c``)
+
+pwm7.pru0.c Using Both PRUs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`pwm7.pru0.c Using Both PRUs <code/pwm7.pru0.c>`
+
+Be sure to run ``pwm7_setup.sh`` to get the correct pins configured.
+
+pwm7_setup.sh
+~~~~~~~~~~~~~~~
+
+:download:`pw7_setup.sh <code/pwm7_setup.sh>`
+
+This makes sure the PRU 1 pins are properly configured.
+
+Here we have a second ``pwm7`` file. ``pwm7.pru1.c`` is identical to ``pwm7.pru0.c``
+except ``PRUNUM`` is set to 1, instead of 0.
+
+Compile and run the two files with:
+
+.. code-block:: bash
+
+  bone$ *make TARGET=pwm7.pru0; make TARGET=pwm7.pru1*
+  /var/lib/cloud9/common/Makefile:29: MODEL=TI_AM335x_BeagleBone_Black,TARGET=pwm7.pru0
+  -    Stopping PRU 0
+  -	copying firmware file /tmp/cloud9-examples/pwm7.pru0.out to /lib/firmware/am335x-pru0-fw
+  write_init_pins.sh
+  -    Starting PRU 0
+  MODEL   = TI_AM335x_BeagleBone_Black
+  PROC    = pru
+  PRUN    = 0
+  PRU_DIR = /sys/class/remoteproc/remoteproc1
+  /var/lib/cloud9/common/Makefile:29: MODEL=TI_AM335x_BeagleBone_Black,TARGET=pwm7.pru1
+  -    Stopping PRU 1
+  -	copying firmware file /tmp/cloud9-examples/pwm7.pru1.out to /lib/firmware/am335x-pru1-fw
+  write_init_pins.sh
+  -    Starting PRU 1
+  MODEL   = TI_AM335x_BeagleBone_Black
+  PROC    = pru
+  PRUN    = 1
+  PRU_DIR = /sys/class/remoteproc/remoteproc2
+
+This will first stop, compile and start PRU 0, then do the same for PRU 1.
+
+Moving half of the channels to PRU1 dropped the period from 510ns to 370ns, so
+we gained a bit.
+
+Discussion
+-----------
+
+There weren't many changes to be made.  Line 15 we set MAXCH to 2. Lines 44-48
+is where the big change is.
+.. code-block:: c
+
+		pru0_dram[2*ch  ] = on [ch+PRUNUN*MAXCH];	// Copy to DRAM0 so the ARM can change it
+		pru0_dram[2*ch+1] = off[ch+PRUNUN*MAXCH];	// Interleave the on and off values
+		onCount[ch] = on [ch+PRUNUN*MAXCH];
+		offCount[ch]= off[ch+PRUNUN*MAXCH];
+
+If we are compiling for PRU 0, ``on[ch+PRUNUN*MAXCH]`` becomes ``on[ch+0*2]`` which is
+``on[ch]`` which is what we had before.  But now if we are on PRU 1 it becomes
+``on[ch+1*2]`` which is ``on[ch+2]``.  That means we are picking up the second 
+half of the ``on`` and ``off`` arrays.  The first half goes to PRU 0, the second to
+PRU 1.  So the same code can be used for both PRUs, but we get slightly different 
+behavior.
+
+Running the code you will see the next figure.
+
+pwm7.pru0 Two PRUs running
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/pwm7_two_prus_running.png
+  :align: center
+  :alt: pwm7.pru0 Two PRUs running
+
+What's going on there, the first channels look fine, but the PRU 1 channels
+are blurred.  To see what's happening, let's stop the oscilloscope.
+
+pwm7.pru0 Two PRUs stopped
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/pwm7_two_prus_stopped.png
+  :align: center
+  :alt: pwm7 Two PRUs stopped
+
+The stopped display shows that the four channels are doing what we wanted, except 
+The PRU 0 channels have a period of 370ns while the PRU 1 channels at 330ns.
+It appears the compiler has optimied the two PRUs slightly differenty.
+
+
+Synchronizing Two PRUs
+=======================
+
+Problem
+-----------
+
+I need to synchronize the two PRUs so they run together.
+
+Solution
+-----------
+
+Use the Interrupt Controller (INTC).  It allows one PRU to signal the other.
+Page 225 of the `AM335x Technical Reference Manual <https://www.ti.com/lit/ug/spruh73p/spruh73p.pdf>`_
+has details of how it works.  Here's the code for PRU 0, which at the end of the
+``while`` loop signals PRU 1 to start(``pwm8.pru0.c``).
+
+pwm8.pru0.c PRU 0 using INTC to send a signal to PRU 1 
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`pwm8.pru0.c  PRU 0 using INTC to send a signal to PRU 1 <code/pwm8.pru0.c>`
+
+PRU 2's code waits for PRU 0 before going.
+
+pwm8.pru1.c PRU 1 waiting for INTC from PRU 0 
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`pwm8.pru1.c PRU 1 waiting for INTC from PRU 0 <code/pwm8.pru1.c>`
+
+In ``pwm8.pru0.c`` PRU 1 waits for a signal from PRU 0, so be sure to start PRU 1 first.
+
+.. code-block:: bash
+
+  bone$ *make TARGET=pwm8.pru0; make TARGET=pwm8.pru1*
+
+Discussion
+-----------
+
+The figure below shows the two PRUs are synchronized, though there is some extra
+overhead in the process so the period is longer.
+
+pwm8.pru0 PRUs sycned
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/pwm8_prus_sycned.png
+  :align: center
+  :alt: pwm8.pru0 PRUs sycned
+
+This isn't much different from the previous examples.
+
+pwm8.pru0.c changes from pwm7.pru0.c 
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+  +-----+-------+---------------------------------------------------------------------------------------+
+  |PRU  |Line   |Change                                                                                 |
+  +=====+=======+=======================================================================================+
+  |0    |37-45  |For PRU 0 these define ``configInitc()`` which initializes the interupts.              |
+  |     |       |See page 226 of the                                                                    |
+  |     |       |`AM335x Technical Reference Manual <https://www.ti.com/lit/ug/spruh73p/spruh73p.pdf>`_ |
+  |     |       |for a diagram explaining events, channels, hosts, etc.                                 |
+  +-----+-------+---------------------------------------------------------------------------------------+
+  |0    |55-56  |Set a configuration register and call `configInitc`.                                   |
+  +-----+-------+---------------------------------------------------------------------------------------+
+  |1    |59-61  |PRU 1 then waits for PRU 0 to signal it.  Bit 31 of ``pass:[__]R31`` corresponds       |
+  |     |       |to the Host-1 channel which ``configInitc()`` set up. We also clear event 16 so        |
+  |     |       |PRU 0 can set it again.                                                                |
+  +-----+-------+---------------------------------------------------------------------------------------+
+  |0    |74-75  |On PRU 0 this generates the interupt to send to PRU 1.  I found PRU 1 was              |
+  |     |       |slow to respond to the interupt, so I put this code at the end of the loop to          |
+  |     |       |give time for the signal to get to PRU 1.                                              |
+  +-----+-------+---------------------------------------------------------------------------------------+
+
+This ends the multipart pwm example.
+
+Reading an Input at Regular Intervals
+======================================
+
+Problem
+-----------
+
+You have an input pin that needs to be read at regular intervals.
+
+Solution
+-----------
+
+You can use the ``pass:[__]R31`` register to read an input pin. Let's use the following
+pins.
+
+.. _blocks_io_pins:
+
+Input/Output pins
+~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+  +---------+----------+-----+----------+---------+
+  |Direction|Bit number|Black|AI (ICSS2)|Pocket   |
+  +=========+==========+=====+==========+=========+
+  |out      |0         |P9_31|P8_44     |P1.36    |
+  +---------+----------+-----+----------+---------+
+  |in       |7         |P9_25|P8_36     |P1.29    |
+  +---------+----------+-----+----------+---------+
+
+These values came from :ref:`blocks_mapping_bits`.
+
+Configure the pins with ``input_setup.sh``.
+
+input_setup.sh
+~~~~~~~~~~~~~~~
+
+:download:`input_setup.sh <code/input_setup.sh>`
+
+The following code reads the input pin and writes its value to the output pin.
+
+input.c
+~~~~~~~~~~
+
+:download:`input.pru0.c <code/input.pru0.c>`
+
+Discussion
+-----------
+
+Just remember that ``pass:[__]R30`` is for outputs and ``pass:[__]R31`` is for inputs.
+
+Analog Wave Generator
+=======================
+
+Problem
+-----------
+
+I want to generate an analog output, but only have GPIO pins.
+
+Solution
+-----------
+
+The Beagle doesn't have a built-in  analog to digital converter. You could get a 
+`USB Audio Dongle <https://www.amazon.com/external-Adapter-Windows-Microphone-SD-CM-UAUD/dp/B001MSS6CS/0&keywords=audio+dongle>`_ 
+which are under $10. But here we'll take another approach.
+
+Earlier we generated a PWM signal.  Here we'll generate a PWM whose duty cycle
+changes with time. A small duty cycle for when the output signal is small and
+a large duty cycle for when it is large.
+
+This example was inspired by 
+`A PRU Sin Wave Generator <https://github.com/derekmolloy/exploringBB/tree/master/chp13/sineWave>`_
+in chapter 13 of 
+`Exploring BeagleBone by Derek Molloy<http://exploringbeaglebone.com/>`_.
+
+Here's the code.
+
+sine.pru0.c
+~~~~~~~~~~~~~
+
+:download:`sine.pru0.c <code/sine.pru0.c>`
+
+
+Set the ``#define`` at line 7 to the number of samples in one cycle of the waveform 
+and set the ``#define`` at line 8 to which waveform and then run ``make``.
+
+Discussion
+-----------
+
+The code has two parts.  The first part (lines 21 to 39) generate the waveform
+to be output. The ``#define``s let you select which waveform you want to
+generate.  Since the output is a percent duty cycle, the values in ``waveform[]`` 
+must be between 0 and 100 inclusive. The waveform is only generated once, so
+this part of the code isn't time critical.
+
+The second part (lines 44 to 54) uses the generated data to set the
+duty cycle of the PWM on a cycle-by-cycle basis. This part is time critical; 
+the faster we can output the values, the higher the frequency of the output 
+signal.
+
+Suppose you want to generate a sawtooth waveform like the one shown in :ref:`blocks_sawtooth`.
+
+.. _blocks_sawtooth:
+
+Continuous Sawtooth Waveform
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/sawtoothsmooth.png
+  :align: center
+  :alt: Continuous Sawtooth Waveform
+
+You need to sample the waveform and store one cycle. :ref:`blocks_sawtoothsampled`
+shows a sampled version of the sawtooth. You need to generate ``MAXT`` samples; 
+here we show 20 samples, which may be enough. In the code ``MAXT`` is set to 100.
+
+.. _blocks_sawtoothsampled:
+
+Sampled Sawtooth Waveform
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/sawtoothsampled.png
+  :align: center
+  :alt: Sampled Sawtooth Waveform
+
+There's a lot going on here; let's take it line by line.
+
+Line-by-line of sine.pru0.c
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+  +-------+---------------------------------------------------------------------------------+
+  |Line   | Explanation                                                                     |
+  +=======+=================================================================================+
+  |2-5    | Standard c-header includes                                                      |
+  +-------+---------------------------------------------------------------------------------+
+  |7      | Number for samples in one cycle of the analog waveform                          |
+  +-------+---------------------------------------------------------------------------------+
+  |8      | Which waveform to use.  We've defined SAWTOOTH, TRIANGLE and SINE, but          |
+  |       | you can define your own too.                                                    |
+  +-------+---------------------------------------------------------------------------------+
+  |10-11  | Declaring registers ``pass:[__R30]`` and ``pass:[__R31]``.                      |
+  +-------+---------------------------------------------------------------------------------+
+  |15-16  | ``onCount`` counts how many cycles the PWM should be 1 and ``offCount`` counts  |
+  |       | how many it should be off.                                                      |
+  +-------+---------------------------------------------------------------------------------+
+  |18     | ``waveform[]`` stores the analog waveform being ouput.                          |
+  +-------+---------------------------------------------------------------------------------+
+  |21-24  | ``SAWTOOTH`` is the simplest of the waveforms. Each sample is the duty cycle    |
+  |       | at that time and must therefore be between 0 and 100.                           |
+  +-------+---------------------------------------------------------------------------------+
+  |26-31  | ``TRIANGLE`` is also a simple waveform.                                         |
+  +-------+---------------------------------------------------------------------------------+
+  |32-39  | ``SINE`` generates a sine wave and also introduces floating point.  Yes,        |
+  |       | you can use floating point, but the PRUs don't have floating point hardware,    |
+  |       | rather, it's all done in software.  This mean using floating point will make    |
+  |       | your code much bigger and slower.  Slower doesn't matter in this part, and      |
+  |       | bigger isn't bigger than our instruction memory, so we're OK.                   |
+  +-------+---------------------------------------------------------------------------------+
+  |47     | Here the ``for`` loop looks up each value of the generated waveform.            |
+  +-------+---------------------------------------------------------------------------------+
+  |48,49  | ``onCount`` is the number of cycles to be at 1 and ``offCount`` is the number   |
+  |       | of cycles to be 0. The two add to 100, one full cycle.                          |
+  +-------+---------------------------------------------------------------------------------+
+  |50-52  | Stay on for ``onCount`` cycles.                                                 |
+  +-------+---------------------------------------------------------------------------------+
+  |53-55  | Now turn off for ``offCount`` cycles, then loop back and look up the next       |
+  |       | cycle count.                                                                    |
+  +-------+---------------------------------------------------------------------------------+
+
+:ref:`blocks_sawunfiltered` shows the output of the code. 
+
+.. _blocks_sawunfiltered:
+
+Unfiltered Sawtooth Waveform
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/sawunfiltered.png
+  :align: center
+  :alt: Unfiltered Sawtooth Waveform
+
+It doesn't look like a sawtooth; but if you look at the left side you will 
+see each cycle has a longer and longer on time.  The duty cycle is increasing.
+Once it's almost 100% duty cycle, it switches to a very small duty cycle.
+Therefore it's output what we programmed, but what we want is the average of 
+the signal.  The left hand side has a large (and increasing) average which 
+would be for top of the sawtooth.  The right hand side has a small average,
+which is what you want for the start of the sawtooth.
+
+A simple low-pass filter, built with one resistor and one capacitor will do it.
+:ref:`blocks_filterwiring` shows how to wire it up.
+
+.. _blocks_filterwiring:
+
+Low-Pass Filter Wiring Diagram
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/filter_bb.png
+  :align: center
+  :alt: Low-Pass Filter Wiring Diagram
+
+.. note::
+
+  I used a 10K variable resistor and a 0.022uF capacitor.
+  Probe the circuit between the resistor and the capacitor 
+  and adjust the resistor until you get a good looking waveform.
+
+:ref:`blocks_sawscope` shows the results for filtered the SAWTOOTH.
+
+.. _blocks_sawscope:
+
+Reconstructed Sawtooth Waveform
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/sawscope.png
+  :align: center
+  :alt: Reconstructed Sawtooth Waveform
+
+Now that looks more like a sawtooth wave.  The top plot is the time-domain
+plot of the output of the low-pass filter. The bottom plot is the FFT of the top 
+plot, therefore it's the frequency domain. We are getting a sawtooth with a
+frequency of about 6.1KHz. You can see the fundamental frequency on the 
+bottom plot along with several harmonics.
+
+
+The top looks like a sawtooth wave, 
+but there is a high freqnecy superimposed on it.  We are only using a simple 
+first-order filter.  You could lower the cutoff freqnecy by adjusting the
+resistor.  You'll see something like :ref:`blocks_lowercutoff`.
+
+.. _blocks_lowercutoff:
+
+Reconstructed Sawtooth Waveform with Lower Cutoff Frequency
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/sawlowercutoff.png
+  :align: center
+  :alt: Reconstructed Sawtooth Waveform with Lower Cutoff Frequency
+
+The high freqencies have been reduced, but the corner of the waveform has 
+been rounded.  You can also adjust the cutoff to a higher frequency and you'll 
+get a sharper corner, but you'll also get more high frequencies. See 
+:ref:`blocks_highercutoff`
+
+.. _blocks_highercutoff:
+
+Reconstructed Sawtooth Waveform with Higher Cutoff Frequency
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/sawhighercutoff.png
+  :align: center
+  :alt: Reconstructed Sawtooth Waveform with Higher Cutoff Frequency
+
+Adjust to taste, though the real solution is to build a higher order filter. 
+Search for _second order **filter** and you'll find some nice circuits.
+
+You can adjust the frequency of the signal by adjusting ``MAXT``.  A smaller 
+``MAXT`` will give a higher frequency.  I've gotten good results with ``MAXT`` 
+as small as 20.
+
+You can also get a triangle waveform by setting the ``#define``. 
+:ref:`blocks_triangle` shows the output signal.
+
+.. _blocks_triangle:
+
+Reconstructed Triangle Waveform
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/triangle.png
+  :align: center
+  :alt: Reconstructed Triangle Waveform
+
+And also the sine wave as shown in :ref:`blocks_sine`.
+
+.. _blocks_sine:
+
+Reconstructed Sinusoid Waveform
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/sine.png
+  :align: center
+  :alt: Reconstructed Sinusoid Waveform
+
+Notice on the bottom plot the harmonics are much more suppressed.
+
+Generating the sine waveform uses **floats**. This requires much more code.
+You can look in `/tmp/cloud9-examples/sine.pru0.map` to see how much memory is being used.
+:ref:`blocks_sine_map` shows the first few lines for the sine wave.
+
+.. _blocks_sine_map:
+
+/tmp/cloud9-examples/sine.pru0.map for Sine Wave
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`lines=1..22 <code/sine.map>`
+
+Notice line 15 shows 0x18c0 bytes are being used for instructions.  That's 6336 
+in decimal.
+
+Now compile for the sawtooth and you see only 444 byes are used.  Floating-point 
+requires over 5K more bytes.  Use with care.  If you are short on instruction
+space, you can move the table generation to the ARM and just copy the table
+to the PRU.
+
+
+.. ToDo Ultrasonic Sensor Application
+
+.. _blocks_ws2812:
+
+WS2812 (NeoPixel) driver
+==========================
+
+Problem
+-----------
+
+You have an `Adafruit NeoPixel LED string <http://www.adafruit.com/products/1138>`_
+or `Adafruit NeoPixel LED matrix <http://www.adafruit.com/products/1487>`_ 
+and want to light it up.
+
+Solution
+-----------
+
+NeoPixel is Adafruit's name for the WS2812 Intelligent control LED.  Each 
+NeoPixel contains a Red, Green and Blue LED with a PWM controller that can
+dim each one individually making a rainbow of colors possible.  The
+NeoPixel is driven by a single serial line.  The timing on the line is very
+sensesitive, which make the PRU a perfect candidate for driving it.
+
+Wire the input to ``P9_29`` and power to 3.3V and ground to ground as shown in
+:ref:`blocks_neo_wiring`.
+
+.. _blocks_neo_wiring:
+
+.NeoPixel Wiring
+.. figure:: figures/neo_bb.png
+  :align: center
+  :alt: NeoPixel Wiring
+
+Test your wiring with the simple code in :ref:`blocks_neo1` 
+which to turns all pixels white.
+
+.. _blocks_neo1:
+
+neo1.pru0.c - Code to turn all NeoPixels's white
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+
+:download:`neo1.pru0.c <code/neo1.pru0.c>`
+
+Discussion
+-----------
+
+:ref:`blocks_sequence` (taken from  `WS2812 Data Sheet <https://cdn-shop.adafruit.com/datasheets/WS2812.pdf>`_) shows the following waveforms are used to send a bit of data.
+
+.. _blocks_sequence:
+
+NeoPixel bit sequence
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/neo_sequence.png
+  :align: center
+  :alt: NeoPixel bit sequence
+
+Where the times are:
+
+.. table::
+
+  +-------+-------------+
+  |Label  | Time in ns  |
+  +=======+=============+
+  |T0H    | 350         |
+  +-------+-------------+
+  |T0L    | 800         |
+  +-------+-------------+
+  |T1H    | 700         |
+  +-------+-------------+
+  |T1L    | 600         |
+  +-------+-------------+
+  |Treset | >50,000     |
+  +-------+-------------+
+
+The code in :ref:`blocks_neo1` define these times in lines 7-10.  
+The `/5` is because 
+each instruction take 5ns.  Lines 27-30 then set the output to 1 for
+the desired time and then to 0 and keeps repeating it for the entire
+string length.  :ref:`blocks_zero_scope` 
+shows the waveform for sending a 0 value.  Note the times are spot on.
+
+.. _blocks_zero_scope:
+
+NeoPixel zero timing
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/neo_scope.png
+  :align: center
+  :alt: 
+
+Each NeoPixel listens for a RGB value. Once a value has arrived all other values
+that follow are passed on to the next NeoPixel which does the same thing.
+That way you can individually control all of the NeoPixels.
+
+Lines 38-40 send out a reset pulse.  If a NeoPixel sees a reset pulse it will
+grab the next value for itself and start over again.
+
+
+
+Setting NeoPixels to Different Colors
+======================================
+
+Problem
+-----------
+
+I want to set the LEDs to different colors.
+
+Solution
+-----------
+
+Wire your NeoPixels as shown in :ref:`blocks_neo_wiring` then run the code in 
+:ref:`blocks_neo2`.
+
+.. _blocks_neo2:
+
+neo2.pru0.c - Code to turn on green, red, blue
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`neo2.pru0.c <code/neo2.pru0.c>`
+
+This will make the first LED green, the second red and the third blue.
+
+Discussion
+-----------
+
+:ref:`blocks_new_data_seq` shows the sequence of bits 
+used to control the green, red and blue values.
+
+.. _blocks_new_data_seq:
+
+NeoPixel data sequence
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/neo_data_seq.png
+  :align: center
+  :alt: 
+
+.. note::
+
+The usual order for colors is RGB (red, green, blue), but the NeoPixels use GRB (green, red, blue).
+
+:ref:`blocks_neo2_line` is the line-by-line for ``neo2.pru0.c``.
+
+.. _blocks_neo2_line:
+
+Line-by-line for neo2.pru0.c
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+  +-------+---------------------------------------------------------------------------------+
+  |Line   | Explanation                                                                     |
+  |23     | Define the string of colors to be output.  Here the ordering of the             |
+  |       | bits is the same as :ref:`blocks_new_data_seq`, GRB.                            |
+  +-------+---------------------------------------------------------------------------------+
+  |26     | Loop for each color to output.                                                  |
+  +-------+---------------------------------------------------------------------------------+
+  |27     | Loop for each bit in an GRB color.                                              |
+  +-------+---------------------------------------------------------------------------------+
+  |28     | Get the j^th^ color and mask off all but the i^th^ bit.  `(0x1:ref:`i)` takes   |
+  |       | the value `0x1` and shifts it left `i` bits.  When anded (&) with `color[j]`    |
+  |       | it will zero out all but the i^th^ bit.  If the result of the operation is      |
+  |       | 1, the `if` is done, otherwise the `else` is done.                              |
+  +-------+---------------------------------------------------------------------------------+
+  |29-32  | Send a 1.                                                                       |
+  +-------+---------------------------------------------------------------------------------+
+  |34-37  | Send a 0.                                                                       |
+  +-------+---------------------------------------------------------------------------------+
+  |42-43  | Send a reset pulse once all the colors have been sent.                          |
+  +-------+---------------------------------------------------------------------------------+
+
+.. note::
+
+This will only change the first ``STR_LEN`` LEDs.  The LEDs that follow will not
+be changed.
+====
+
+Controlling Arbitrary LEDs
+============================
+
+Problem
+-----------
+
+I want to change the 10^th^ LED and not have to change the others.
+
+Solution
+-----------
+
+You need to keep an array of colors for the whole string in the PRU.  Change
+the color of any pixels you want in the array and then send out the whole
+string to the LEDs.  :ref:`blocks_neo3` shows an example animates a red pixel
+running around a ring of blue background.  :ref:`blocks_neo3_video` shows
+the code in action.
+
+.. _blocks_neo3_video:
+
+neo3.pru0.c - Simple animation
+
+:download:`ring_around.mp4 <figures/ring_around.mp4>`
+
+.. _blocks_neo3:
+
+neo3.pru0.c - Code to animate a red pixel running around a ring of blue
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`neo3.pru0.c <code/neo3.pru0.c>`
+
+
+Discussion
+-----------
+
+Here's the highlights.
+
+.. table::
+
+  +-----+---------------------------------+
+  |Line |Explanation                      |
+  +=====|=================================+
+  |32,33|Initiallize the array of colors. |
+  +-----+---------------------------------+
+  |38-41|Update the array.                |
+  +-----+---------------------------------+
+  |44-58|Send the array to the LEDs.      |
+  +-----+---------------------------------+
+  |60-61|Send a reset.                    |
+  +-----+---------------------------------+
+  |64   |Wait a bit.                      |
+  +-----+---------------------------------+
+
+Controlling NeoPixels Through a Kernel Driver
+======================================
+
+Problem
+-----------
+
+You want to control your NeoPixels through a kernel driver so you can control it 
+through a ``/dev`` interface.
+
+Solution
+-----------
+
+The `rpmsg_pru <https://github.com/beagleboard/linux/raw/4.9/drivers/rpmsg/rpmsg_pru.c>`_ 
+driver provides a way to pass data between the ARM processor and
+the PRUs.  It's already included on current images. :ref:`blocks_neo4` shows
+an example.
+
+.. _blocks_neo4:
+
+neo4.pru0.c - Code to talk to the PRU via rpmsg_pru
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`neo4.pru0.c <code/neo4.pru0.c>`
+
+Run the code as usual.
+
+.. code-block:: bash
+
+  bone$ make TARGET=neo4.pru0
+  /var/lib/cloud9/common/Makefile:29: MODEL=TI_AM335x_BeagleBone_Black,TARGET=neo4.pru0
+  -    Stopping PRU 0
+  -	copying firmware file /tmp/cloud9-examples/neo4.pru0.out to /lib/firmware/am335x-pru0-fw
+  write_init_pins.sh
+  -    Starting PRU 0
+  MODEL   = TI_AM335x_BeagleBone_Black
+  PROC    = pru
+  PRUN    = 0
+  PRU_DIR = /sys/class/remoteproc/remoteproc1
+
+  bone$ echo 0 0xff 0 127 > /dev/rpmsg_pru30
+  bone$ echo -1 > /dev/rpmsg_pru30
+
+
+.. TODO get this working on the 5.10 kernel
+
+``/dev/rpmsg_pru30`` is a device driver that lets the ARM talk to the PRU.
+The first ``echo`` says to set the 0^th^ LED to RGB value 0xff 0 127. (Note: you can
+mix hex and decimal.) The second ``echo`` tells the driver to send the data to the
+LEDs.  Your 0^th^ LED should now be lit.
+
+Discussion
+-----------
+
+There's a lot here.  I'll just hit some of the highlights in :ref:`blocks_neo4_lines`.
+
+.. _blocks_neo4_lines:
+
+Line-by-line for neo4.pru0.c
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+|Line |Explanation
+
+|30   |The `CHAN_NAME` of `rpmsg-pru` matches that `prmsg_pru` driver that is
+is already installed.  This connects this PRU to the driver.
+|32   |The `CHAN_PORT` tells it to use port 30.  That's why we use
+`/dev/rpmsg_pru30`
+|40   |`payload[]` is the buffer that receives the data from the ARM.
+|42-48|Same as the previous NeoPixel examples.
+|52   |`color[]` is the state to be sent to the LEDs.
+|66-68|`color[]` is initialized.
+|70-85|Here are a number of details needed to set up the channel between 
+the PRU and the ARM.
+|88   |Here we wait until the ARM sends us some numbers.
+|99   |Receive all the data from the ARM, store it in `payload[]`.
+|101-111|The data sent is:  index red green blue.  Pull off the index.  If it's 
+in the right range, pull off the red, green and blue values.
+|113  |The NeoPixels want the data in GRB order.  Shift and OR everything 
+together.
+|116-133|If the `index` = -1, send the contents of `color` to the LEDs.  This
+code is same as before.
+|====
+
+You can now use programs running on the ARM to send colors to the PRU.
+
+:ref:`blocks_neo-rainbow` shows an example.
+
+.. _blocks_neo-rainbow:
+
+neo-rainbow.py - A python program using /dev/rpmsg_pru30
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`neo-rainbow.py <code/neo-rainbow.py>`
+
+
+Line 19 writes the data to the PRU.  Be sure to have a newline, or space after
+the last number, or you numbers will get blurred together.
+
+Switching from pru0 to pru1 with rpmsg_pru
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+There are three things you need to change when switching from pru0 to pru1
+when using rpmsg_pru.
+
+1.  The include on line 10 is switched to ``#include "resource_table_1.h"`` (0 is switched to a 1)
+2.  Line 17 is switched to ``#define HOST_INT ((uint32_t) 1 << 31)`` (30 is switched to 31.)
+3.  Lines 23 and 24 are switched to:	
+
+.. code-block:: c
+
+  #define TO_ARM_HOST			18	
+  #define FROM_ARM_HOST		19
+
+These changes switch to the proper channel numbers to use pru1 instead of pru0.
+
+RGB LED Matrix - No Integrated Drivers
+======================================
+
+
+Problem
+-----------
+
+You have a RGB LED matrix 
+(:ref:`../01case/case.html#case_rgb_matrix, 1.4. RGB LED Matrix - No Integrated Drivers`) and want to know
+at a low level how the PRU works.
+
+Solution
+-----------
+
+Here is the 
+`datasheet <https://cdn-shop.adafruit.com/product-files/2277/MI-T35P5RGBE-AE.pdf>`_,
+but the best description I've found for the RGB Matrix is from 
+`Adafruit <https://www.adafruit.com/>`_.  I've reproduced it here, with 
+adjustments for the 64x32 matrix we are using.
+
+
+.. admonition:: information
+
+  There's zero documention out there on how these matrices work, and no public 
+  datasheets or spec sheets so we are going to try to document how they work.
+
+  First thing to notice is that there are 2048 RGB LEDs in a 64x32 matrix. 
+  Like pretty much every matrix out there, you can't drive all 2048 at once. 
+  One reason is that would require a lot of current, another reason is that 
+  it would be really expensive to have so many pins. Instead, the matrix is 
+  divided into 16 interleaved sections/strips. The first section is the 
+  1^st^ 'line' and the 17^th^ 'line' (64 x 2 RGB LEDs = 128 RGB LEDs), 
+  the second is the 2^nd^ and 18^th^ line, etc until the last section 
+  which is the 16^th^ and 32^nd^ line. You might be asking, why are the 
+  lines paired this way? wouldn't it be nicer to have the first section 
+  be the 1^st^ and 2^nd^ line, then 3^rd^ and 4^th^, until the 15^th^ and 
+  16^th^? The reason they do it this way is so that the lines are interleaved 
+  and look better when refreshed, otherwise we'd see the stripes more clearly.
+
+  So, on the PCB is 24 LED driver chips. These are like 74HC595s but they 
+  have 16 outputs and they are constant current. 16 outputs * 24 chips = 
+  384 LEDs that can be controlled at once, and 128 * 3 (R G and B) = 384. 
+  So now the design comes together: You have 384 outputs that can control 
+  one line at a time, with each of 384 R, G and B LEDs either on or off. 
+  The controller (say an FPGA or microcontroller) selects which section 
+  to currently draw (using LA, LB, LC and LD address pins - 4 bits can 
+  have 16 values). Once the address is set, the controller clocks out 
+  384 bits of data (48 bytes) and latches it. Then it increments the 
+  address and clocks out another 384 bits, etc until it gets to address 
+  #15, then it sets the address back to #0
+
+  https://cdn-learn.adafruit.com/downloads/pdf/32x16-32x32-rgb-led-matrix.pdf
+
+That gives a good overview, but there are a few details missing. 
+:ref:`blocks_rgb_python` is a functioning python program that gives a nice
+high-level view of how to drive the display. 
+
+.. TODO Test this
+
+.. _blocks_rgb_python:
+
+rgb_python.py - Python code for driving RGB LED matrix
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`rgb_python.py <code/rgb_python.py>`
+
+Be sure to run the :ref:`blocks_rgb_setup` script before running the python code.
+
+.. _blocks_rgb_setup:
+
+rgb_python_setup.sh
+~~~~~~~~~~~~~~~~~~~~
+
+:download:`rgb_python_setup.sh <code/rgb_python_setup.sh>`
+
+Make sure line 29 is commented out and line 30 is uncommented. 
+Later we'll configure for _pruout_, but for now the python code doesn't use 
+the PRU outs.
+
+.. code-block:: bash
+
+    # config-pin $pin pruout
+    config-pin $pin out
+
+Your display should look like :ref:`blocks_rgb_python_jpg`.
+
+.. _blocks_rgb_python_jpg:
+
+Display running rgb_python.py
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/rgb_python.jpg
+  :align: center
+  :alt: Display running rgb_python.py
+
+So why do only two lines appear at a time?  That's how the display works. 
+Currently lines 6 and 22 are showing, then a moment later 7 and 23 show, etc. 
+The display can only display two lines at a time, so it cycles through all the 
+lines.  Unfortunately, python is too slow to make the display appear 
+all at once.  Here's where the PRU comes in.
+
+:ref:``blocks_rgb1`` is the PRU code to drive the RGB LED matrix.   Be sure to run
+``bone$ source rgb_setup.sh`` first.
+
+.. _blocks_rgb1:
+
+PRU code for driving the RGB LED matrix
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`rgb1.pru0.c <code/rgb1.pru0.c>`
+
+
+The results are shown in :ref:`blocks_rgb_pru`.
+
+.. _blocks_rgb_pru:
+
+Display running rgb1.c on PRU 0
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/rgb_pru.jpg
+  :align: center
+  :alt: Display running rgb1.pru0.c on PRU 0
+
+The PRU is fast enough to quickly write to the display so that it appears 
+as if all the LEDs are on at once.
+
+Discussion
+-----------
+
+There are a lot of details needed to make this simple display work.  Let's 
+go over some of them.
+
+First, the connector looks like :ref:`blocks_matrix_j1`.
+
+.. _blocks_matrix_j1:
+
+RGB Matrix J1 connector
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/matrix_j1.jpg
+  :align: center
+  :alt: RGB Matrix J1 connector, 200
+
+Notice the labels on the connect match the labels in the code.
+:ref:`blocks_pocket_scroller_pins` shows how the pins on the display are 
+mapped to the pins on the Pocket Beagle.
+
+.. ToDo  Make a mapping table for the Black
+.. https://github.com/FalconChristmas/fpp/blob/master/src/pru/OctoscrollerV2.hp
+
+.. _blocks_pocket_scroller_pins:
+
+PocketScroller pin table
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |J1 Connector Pin |Pocket Headers |gpio port and bit number|Linux gpio number |PRU R30 bit number |
+  +=================+===============+========================+==================+===================+
+  |R1               |P2_10          |1-20                    |52                |                   |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |B1               |P2_06          |1-25                    |57                |                   |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |R2               |P2_04          |1-26                    |58                |                   |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |B2               |P2_01          |1-18                    |50                |                   |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |LA               |P2_32          |3-16                    |112               |PRU0.2             |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |LC               |P1_31          |3-18                    |114               |PRU0.4             |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |CLK              |P1_33          |3-15                    |111               |PRU0.1             |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |OE               |P1_29          |3-21                    |117               |PRU0.7             |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |G1               |P2_08          |1-28                    |60                |                   |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |G2               |P2_02          |1-27                    |59                |                   |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |LB               |P2_30          |3-17                    |113               |PRU0.3             |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |LD               |P2_34          |3-19                    |115               |PRU0.5             |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+  |LAT              |P1_36          |3-14                    |110               |PRU0.0             |
+  +-----------------+---------------+------------------------+------------------+-------------------+
+
+The J1 mapping to gpio port and bit number comes from 
+https://github.com/FalconChristmas/fpp/blob/master/capes/pb/panels/PocketScroller.json.
+The gpio port and bit number mapping to Pocket Headers comes from 
+https://docs.google.com/spreadsheets/d/1FRGvYOyW1RiNSEVprvstfJAVeapnASgDXHtxeDOjgqw/edit#gid=0.
+
+:ref:`blocks_rgb_waveforms` shows four of the signal waveforms driving the RGB LED matrix.
+
+.. _blocks_rgb_waveforms:
+
+Oscilloscope display of CLK, OE, LAT and R1
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/rgb_waveforms.png
+  :align: center
+  :alt: .Oscilloscope display of CLK, OE, LAT and R1
+
+The top waveform is the CLK, the next is OE, followed by LAT and finally R1. 
+The OE (output enable) is active low, so most of the time the display is visible. 
+The sequence is:
+
+* Put data on the R1, G1, B1, R2, G2 and B2 lines
+* Toggle the clock.
+* Repeat the first two steps as one row of data is transfered.  There are 
+384 LEDs (2 rows of 32 RGB LEDs times 3 LED per RGB), but we are clocking in 
+six bits (R1, G1, etc.) at a time, so 384/6=64 values need to be clocked in.
+* Once all the values are in, disable the display (OE goes high)
+* Then toggle the latch (LAT) to latch the new data.
+* Turn the display back on.
+* Increment the address lines (LA, LB, LC and LD) to point to the next rows.
+* Keep repeating the above to keep the display lit.
+
+Using the PRU we are able to run the clock a about 2.9 MKHz. 
+:ref:`blocks_rgb_fpp` shows the optimized assembler code used by FPP clocks in 
+at some 6.3 MHz.  So the compiler is doing a pretty good job, but you can run 
+some two times faster if you want to use assembly code.  In fairness to FPP, 
+it's having to pull it's data out of RAM to display it, so isn't not a good 
+comparision.
+
+.. _blocks_rgb_fpp:
+
+FPP waveforms
+~~~~~~~~~~~~~~
+
+.. figure:: figures/rgb_fpp.png
+  :align: center
+  :alt: FPP waveforms
+
+Getting More Colors
+~~~~~~~~~~~~~~~~~~~~~
+
+The Adafruit description goes on to say:
+
+.. admonition:: information
+
+  The only downside of this technique is that despite being very simple and fast, 
+  it has no PWM control built-in! The controller can only set the LEDs on or off. 
+  So what do you do when you want full color? You actually need to draw the entire 
+  matrix over and over again at very high speeds to PWM the matrix manually. For 
+  that reason, you need to have a very fast controller (50 MHz is a minimum) if 
+  you want to do a lot of colors and motion video and have it look good.
+
+  https://cdn-learn.adafruit.com/downloads/pdf/32x16-32x32-rgb-led-matrix.pdf
+
+This is what FPP does, but it's beyond the scope of this project.
+
+Compiling and Inserting rpmsg_pru
+======================================
+
+Problem
+-----------
+
+Your Beagle doesn't have rpmsg_pru.
+
+Solution
+-----------
+
+Do the following.
+
+.. code-block:: bash
+
+  bone$ *cd 05blocks/code/module*
+  bone$ *sudo apt install linux-headers-\`uname -r`*
+  bone$ *wget https://github.com/beagleboard/linux/raw/4.9/drivers/rpmsg/rpmsg_pru.c*
+  bone$ *make*
+  make -C /lib/modules/4.9.88-ti-r111/build M=$PWD
+  make[1]: Entering directory '/usr/src/linux-headers-4.9.88-ti-r111'
+    LD      /home/debian/PRUCookbook/docs/05blocks/code/module/built-in.o
+    CC [M]  /home/debian/PRUCookbook/docs/05blocks/code/module/rpmsg_client_sample.o
+    CC [M]  /home/debian/PRUCookbook/docs/05blocks/code/module/rpmsg_pru.o
+    Building modules, stage 2.
+    MODPOST 2 modules
+    CC      /home/debian/PRUCookbook/docs/05blocks/code/module/rpmsg_client_sample.mod.o
+    LD [M]  /home/debian/PRUCookbook/docs/05blocks/code/module/rpmsg_client_sample.ko
+    CC      /home/debian/PRUCookbook/docs/05blocks/code/module/rpmsg_pru.mod.o
+    LD [M]  /home/debian/PRUCookbook/docs/05blocks/code/module/rpmsg_pru.ko
+  make[1]: Leaving directory '/usr/src/linux-headers-4.9.88-ti-r111'
+  bone$ *sudo insmod rpmsg_pru.ko*
+  bone$ *lsmod | grep rpm*
+  rpmsg_pru               5799  2
+  virtio_rpmsg_bus       13620  0
+  rpmsg_core              8537  2 rpmsg_pru,virtio_rpmsg_bus
+
+
+It's now installed and ready to go.
+
+
+Copyright
+==========
+
+copyright.c
+~~~~~~~~~~~~~
+
+:download:`copyright.c <code/copyright.c>`
+
diff --git a/pru-cookbook/05blocks/code/Makefile b/pru-cookbook/05blocks/code/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a7557fdaa22988d89cec879477ded78522d7116f
--- /dev/null
+++ b/pru-cookbook/05blocks/code/Makefile
@@ -0,0 +1 @@
+include /var/lib/cloud9/common/Makefile
diff --git a/pru-cookbook/05blocks/code/copyright.c b/pru-cookbook/05blocks/code/copyright.c
new file mode 100644
index 0000000000000000000000000000000000000000..a34918faa44a789c3624c0e5551704e630017dae
--- /dev/null
+++ b/pru-cookbook/05blocks/code/copyright.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *	* Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ *
+ *	* Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the
+ *	  distribution.
+ *
+ *	* Neither the name of Texas Instruments Incorporated nor the names of
+ *	  its contributors may be used to endorse or promote products derived
+ *	  from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/pru-cookbook/05blocks/code/input.pru0.c b/pru-cookbook/05blocks/code/input.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..9ed5d3b759eb866fdbaa57fed9258c71ed32263e
--- /dev/null
+++ b/pru-cookbook/05blocks/code/input.pru0.c
@@ -0,0 +1,26 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t led;
+	uint32_t sw;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	led = 0x1<<0;	// P9_31 or P1_36
+	sw  = 0x1<<7;	// P9_25 or P1_29
+		
+	while (1) {
+		if((__R31&sw) == sw) {
+			__R30 |= led;		// Turn on LED
+		} else
+			__R30 &= ~led;		// Turn off LED
+	}
+}
+
diff --git a/pru-cookbook/05blocks/code/input_setup.sh b/pru-cookbook/05blocks/code/input_setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..35a0d9c3598288c14894a90907a69d62009eed1f
--- /dev/null
+++ b/pru-cookbook/05blocks/code/input_setup.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+#
+export TARGET=input.pru0
+echo TARGET=$TARGET
+
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    config-pin P9_31 pruout
+    config-pin -q P9_31
+    config-pin P9_25 pruin
+    config-pin -q P9_25
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    config-pin P1_36 pruout
+    config-pin -q P1_36
+    config-pin P1_29 pruin
+    config-pin -q P1_29
+else
+    echo " Not Found"
+    pins=""
+fi
diff --git a/pru-cookbook/05blocks/code/module/.gitignore b/pru-cookbook/05blocks/code/module/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..9b6dfc433724ec94f8905520931dcf33d409ea87
--- /dev/null
+++ b/pru-cookbook/05blocks/code/module/.gitignore
@@ -0,0 +1 @@
+*.ko
diff --git a/pru-cookbook/05blocks/code/module/Makefile b/pru-cookbook/05blocks/code/module/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..9ca05d057c153a2d9b653fc64f5504a2d5aeea2e
--- /dev/null
+++ b/pru-cookbook/05blocks/code/module/Makefile
@@ -0,0 +1,25 @@
+# Makefile for compiling out-of-tree
+# From Free Electrons
+# If on the Bone run apt install linux-headers-`uname -r`
+
+KDIR := /lib/modules/$(shell uname -r)/build
+
+obj-m += rpmsg_client_sample.o
+obj-m += rpmsg_pru.o
+
+all:
+	$(MAKE) -C $(KDIR) M=$$PWD
+	
+install:
+	scp hello*.ko bone:.
+
+print:
+	@echo KERNELRELEASE= $(KERNELRELEASE)
+	@echo CONFIG_EXAMPLES= $(CONFIG_EXAMPLES)
+	@echo obj-m= $(obj-m)
+	
+clean:
+	rm -rf .tmp_versions *.o 
+	rm -rf .rpmsg_client_sample* rpmsg_client_sample*.mod.c
+	rm -rf .rpmsg_pru* rpmsg_pru*.mod.c
+	rm modules.order Module.symvers .built-in.o.cmd 
\ No newline at end of file
diff --git a/pru-cookbook/05blocks/code/module/install.sh b/pru-cookbook/05blocks/code/module/install.sh
new file mode 100755
index 0000000000000000000000000000000000000000..89f497f038396b8bfaddcec73330b74255e0c5ab
--- /dev/null
+++ b/pru-cookbook/05blocks/code/module/install.sh
@@ -0,0 +1,6 @@
+# This is a example of ARM to PRU communication from Lab 5 of
+# http://processors.wiki.ti.com/index.php/PRU_Training:_Hands-on_Labs#LAB_5:_RPMsg_Communication_between_ARM_and_PRU
+
+sudo apt install linux-headers-`uname -r`
+
+wget https://github.com/beagleboard/linux/raw/4.9/drivers/rpmsg/rpmsg_pru.c
diff --git a/pru-cookbook/05blocks/code/module/rpmsg_client_sample.c b/pru-cookbook/05blocks/code/module/rpmsg_client_sample.c
new file mode 100644
index 0000000000000000000000000000000000000000..72b24524c626cca0291d93b5d765ecf515dac0f3
--- /dev/null
+++ b/pru-cookbook/05blocks/code/module/rpmsg_client_sample.c
@@ -0,0 +1,102 @@
+/*
+ * Remote processor messaging - sample client driver
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+
+#define MSG		"hello world!"
+#define MSG_LIMIT	10
+
+struct instance_data {
+	int rx_count;
+};
+
+static int rpmsg_sample_cb(struct rpmsg_device *rpdev, void *data, int len,
+						void *priv, u32 src)
+{
+	int ret;
+	struct instance_data *idata = dev_get_drvdata(&rpdev->dev);
+
+	dev_info(&rpdev->dev, "incoming msg %d (src: 0x%x)\n",
+		 ++idata->rx_count, src);
+
+	print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1,
+		       data, len,  true);
+
+	/* samples should not live forever */
+	if (idata->rx_count >= MSG_LIMIT) {
+		dev_info(&rpdev->dev, "goodbye!\n");
+		return 0;
+	}
+
+	/* send a new message now */
+	ret = rpmsg_send(rpdev->ept, MSG, strlen(MSG));
+	if (ret)
+		dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
+
+	return 0;
+}
+
+static int rpmsg_sample_probe(struct rpmsg_device *rpdev)
+{
+	int ret;
+	struct instance_data *idata;
+
+	dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+					rpdev->src, rpdev->dst);
+
+	idata = devm_kzalloc(&rpdev->dev, sizeof(*idata), GFP_KERNEL);
+	if (!idata)
+		return -ENOMEM;
+
+	dev_set_drvdata(&rpdev->dev, idata);
+
+	/* send a message to our remote processor */
+	ret = rpmsg_send(rpdev->ept, MSG, strlen(MSG));
+	if (ret) {
+		dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void rpmsg_sample_remove(struct rpmsg_device *rpdev)
+{
+	dev_info(&rpdev->dev, "rpmsg sample client driver is removed\n");
+}
+
+static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = {
+	{ .name	= "rpmsg-client-sample" },
+	{ },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table);
+
+static struct rpmsg_driver rpmsg_sample_client = {
+	.drv.name	= KBUILD_MODNAME,
+	.id_table	= rpmsg_driver_sample_id_table,
+	.probe		= rpmsg_sample_probe,
+	.callback	= rpmsg_sample_cb,
+	.remove		= rpmsg_sample_remove,
+};
+module_rpmsg_driver(rpmsg_sample_client);
+
+MODULE_DESCRIPTION("Remote processor messaging sample client driver");
+MODULE_LICENSE("GPL v2");
diff --git a/pru-cookbook/05blocks/code/module/rpmsg_pru.c b/pru-cookbook/05blocks/code/module/rpmsg_pru.c
new file mode 100644
index 0000000000000000000000000000000000000000..5a96b20965035e5b12139f391a41529c94ff0dbc
--- /dev/null
+++ b/pru-cookbook/05blocks/code/module/rpmsg_pru.c
@@ -0,0 +1,359 @@
+/*
+ * PRU Remote Processor Messaging Driver
+ *
+ * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
+ *	Jason Reeder <jreeder@ti.com>
+ *	Suman Anna <s-anna@ti.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/rpmsg.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/cdev.h>
+#include <linux/module.h>
+#include <linux/kfifo.h>
+#include <linux/uaccess.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/rpmsg/virtio_rpmsg.h>
+
+#define PRU_MAX_DEVICES				(8)
+/* Matches the definition in virtio_rpmsg_bus.c */
+#define RPMSG_BUF_SIZE				(512)
+#define MAX_FIFO_MSG				(32)
+#define FIFO_MSG_SIZE				RPMSG_BUF_SIZE
+
+/**
+ * struct rpmsg_pru_dev - Structure that contains the per-device data
+ * @rpdev: rpmsg channel device that is associated with this rpmsg_pru device
+ * @dev: device
+ * @cdev: character device
+ * @locked: boolean used to determine whether or not the device file is in use
+ * @devt: dev_t structure for the rpmsg_pru device
+ * @msg_fifo: kernel fifo used to buffer the messages between userspace and PRU
+ * @msg_len: array storing the lengths of each message in the kernel fifo
+ * @msg_idx_rd: kernel fifo read index
+ * @msg_idx_wr: kernel fifo write index
+ * @wait_list: wait queue used to implement the poll operation of the character
+ *             device
+ *
+ * Each rpmsg_pru device provides an interface, using an rpmsg channel (rpdev),
+ * between a user space character device (cdev) and a PRU core. A kernel fifo
+ * (msg_fifo) is used to buffer the messages in the kernel that are
+ * being passed between the character device and the PRU.
+ */
+struct rpmsg_pru_dev {
+	struct rpmsg_device *rpdev;
+	struct device *dev;
+	struct cdev cdev;
+	bool locked;
+	dev_t devt;
+	struct kfifo msg_fifo;
+	u32 msg_len[MAX_FIFO_MSG];
+	int msg_idx_rd;
+	int msg_idx_wr;
+	wait_queue_head_t wait_list;
+};
+
+static struct class *rpmsg_pru_class;
+static dev_t rpmsg_pru_devt;
+static DEFINE_MUTEX(rpmsg_pru_lock);
+static DEFINE_IDR(rpmsg_pru_minors);
+
+static int rpmsg_pru_open(struct inode *inode, struct file *filp)
+{
+	struct rpmsg_pru_dev *prudev;
+	int ret = -EACCES;
+
+	prudev = container_of(inode->i_cdev, struct rpmsg_pru_dev, cdev);
+
+	mutex_lock(&rpmsg_pru_lock);
+	if (!prudev->locked) {
+		prudev->locked = true;
+		filp->private_data = prudev;
+		ret = 0;
+	}
+	mutex_unlock(&rpmsg_pru_lock);
+
+	if (ret)
+		dev_err(prudev->dev, "Device already open\n");
+
+	return ret;
+}
+
+static int rpmsg_pru_release(struct inode *inode, struct file *filp)
+{
+	struct rpmsg_pru_dev *prudev;
+
+	prudev = container_of(inode->i_cdev, struct rpmsg_pru_dev, cdev);
+	mutex_lock(&rpmsg_pru_lock);
+	prudev->locked = false;
+	mutex_unlock(&rpmsg_pru_lock);
+	return 0;
+}
+
+static ssize_t rpmsg_pru_read(struct file *filp, char __user *buf,
+			      size_t count, loff_t *f_pos)
+{
+	int ret;
+	u32 length;
+	struct rpmsg_pru_dev *prudev;
+
+	prudev = filp->private_data;
+
+	if (kfifo_is_empty(&prudev->msg_fifo) &&
+	    (filp->f_flags & O_NONBLOCK))
+		return -EAGAIN;
+
+	ret = wait_event_interruptible(prudev->wait_list,
+				       !kfifo_is_empty(&prudev->msg_fifo));
+	if (ret)
+		return -EINTR;
+
+	ret = kfifo_to_user(&prudev->msg_fifo, buf,
+			    prudev->msg_len[prudev->msg_idx_rd], &length);
+	prudev->msg_idx_rd = (prudev->msg_idx_rd + 1) % MAX_FIFO_MSG;
+
+	return ret ? ret : length;
+}
+
+static ssize_t rpmsg_pru_write(struct file *filp, const char __user *buf,
+			       size_t count, loff_t *f_pos)
+{
+	int ret;
+	struct rpmsg_pru_dev *prudev;
+	static char rpmsg_pru_buf[RPMSG_BUF_SIZE];
+
+	prudev = filp->private_data;
+
+	if (count > RPMSG_BUF_SIZE - sizeof(struct rpmsg_hdr)) {
+		dev_err(prudev->dev, "Data too large for RPMsg Buffer\n");
+		return -EINVAL;
+	}
+
+	if (copy_from_user(rpmsg_pru_buf, buf, count)) {
+		dev_err(prudev->dev, "Error copying buffer from user space");
+		return -EFAULT;
+	}
+
+	ret = rpmsg_send(prudev->rpdev->ept, (void *)rpmsg_pru_buf, count);
+	if (ret)
+		dev_err(prudev->dev, "rpmsg_send failed: %d\n", ret);
+
+	return ret ? ret : count;
+}
+
+static unsigned int rpmsg_pru_poll(struct file *filp,
+				   struct poll_table_struct *wait)
+{
+	int mask;
+	struct rpmsg_pru_dev *prudev;
+
+	prudev = filp->private_data;
+
+	poll_wait(filp, &prudev->wait_list, wait);
+
+	mask = POLLOUT | POLLWRNORM;
+
+	if (!kfifo_is_empty(&prudev->msg_fifo))
+		mask |= POLLIN | POLLRDNORM;
+
+	return mask;
+}
+
+static const struct file_operations rpmsg_pru_fops = {
+	.owner = THIS_MODULE,
+	.open = rpmsg_pru_open,
+	.release = rpmsg_pru_release,
+	.read = rpmsg_pru_read,
+	.write = rpmsg_pru_write,
+	.poll = rpmsg_pru_poll,
+};
+
+static int rpmsg_pru_cb(struct rpmsg_device *rpdev, void *data, int len,
+			void *priv, u32 src)
+{
+	u32 length;
+	struct rpmsg_pru_dev *prudev;
+
+	prudev = dev_get_drvdata(&rpdev->dev);
+
+	if (kfifo_avail(&prudev->msg_fifo) < len) {
+		dev_err(&rpdev->dev, "Not enough space on the FIFO\n");
+		return -ENOSPC;
+	}
+
+	if ((prudev->msg_idx_wr + 1) % MAX_FIFO_MSG ==
+		prudev->msg_idx_rd) {
+		dev_err(&rpdev->dev, "Message length table is full\n");
+		return -ENOSPC;
+	}
+
+	length = kfifo_in(&prudev->msg_fifo, data, len);
+	prudev->msg_len[prudev->msg_idx_wr] = length;
+	prudev->msg_idx_wr = (prudev->msg_idx_wr + 1) % MAX_FIFO_MSG;
+
+	wake_up_interruptible(&prudev->wait_list);
+
+	return 0;
+}
+
+static int rpmsg_pru_probe(struct rpmsg_device *rpdev)
+{
+	int ret;
+	struct rpmsg_pru_dev *prudev;
+	int minor_got;
+
+	prudev = devm_kzalloc(&rpdev->dev, sizeof(*prudev), GFP_KERNEL);
+	if (!prudev)
+		return -ENOMEM;
+
+	mutex_lock(&rpmsg_pru_lock);
+	minor_got = idr_alloc(&rpmsg_pru_minors, prudev, 0, PRU_MAX_DEVICES,
+			      GFP_KERNEL);
+	mutex_unlock(&rpmsg_pru_lock);
+	if (minor_got < 0) {
+		ret = minor_got;
+		dev_err(&rpdev->dev, "Failed to get a minor number for the rpmsg_pru device: %d\n",
+			ret);
+		goto fail_alloc_minor;
+	}
+
+	prudev->devt = MKDEV(MAJOR(rpmsg_pru_devt), minor_got);
+
+	cdev_init(&prudev->cdev, &rpmsg_pru_fops);
+	prudev->cdev.owner = THIS_MODULE;
+	ret = cdev_add(&prudev->cdev, prudev->devt, 1);
+	if (ret) {
+		dev_err(&rpdev->dev, "Unable to add cdev for the rpmsg_pru device\n");
+		goto fail_add_cdev;
+	}
+
+	prudev->dev = device_create(rpmsg_pru_class, &rpdev->dev, prudev->devt,
+				    NULL, "rpmsg_pru%d", rpdev->dst);
+	if (IS_ERR(prudev->dev)) {
+		dev_err(&rpdev->dev, "Unable to create the rpmsg_pru device\n");
+		ret = PTR_ERR(prudev->dev);
+		goto fail_create_device;
+	}
+
+	prudev->rpdev = rpdev;
+
+	ret = kfifo_alloc(&prudev->msg_fifo, MAX_FIFO_MSG * FIFO_MSG_SIZE,
+			  GFP_KERNEL);
+	if (ret) {
+		dev_err(&rpdev->dev, "Unable to allocate fifo for the rpmsg_pru device\n");
+		goto fail_alloc_fifo;
+	}
+
+	init_waitqueue_head(&prudev->wait_list);
+
+	dev_set_drvdata(&rpdev->dev, prudev);
+
+	dev_info(&rpdev->dev, "new rpmsg_pru device: /dev/rpmsg_pru%d",
+		 rpdev->dst);
+
+	return 0;
+
+fail_alloc_fifo:
+	device_destroy(rpmsg_pru_class, prudev->devt);
+fail_create_device:
+	cdev_del(&prudev->cdev);
+fail_add_cdev:
+	mutex_lock(&rpmsg_pru_lock);
+	idr_remove(&rpmsg_pru_minors, minor_got);
+	mutex_unlock(&rpmsg_pru_lock);
+fail_alloc_minor:
+	return ret;
+}
+
+static void rpmsg_pru_remove(struct rpmsg_device *rpdev)
+{
+	struct rpmsg_pru_dev *prudev;
+
+	prudev = dev_get_drvdata(&rpdev->dev);
+
+	kfifo_free(&prudev->msg_fifo);
+	device_destroy(rpmsg_pru_class, prudev->devt);
+	cdev_del(&prudev->cdev);
+	mutex_lock(&rpmsg_pru_lock);
+	idr_remove(&rpmsg_pru_minors, MINOR(prudev->devt));
+	mutex_unlock(&rpmsg_pru_lock);
+}
+
+/* .name matches on RPMsg Channels and causes a probe */
+static const struct rpmsg_device_id rpmsg_driver_pru_id_table[] = {
+	{ .name	= "rpmsg-pru" },
+	{ },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_pru_id_table);
+
+static struct rpmsg_driver rpmsg_pru_driver = {
+	.drv.name	= KBUILD_MODNAME,
+	.id_table	= rpmsg_driver_pru_id_table,
+	.probe		= rpmsg_pru_probe,
+	.callback	= rpmsg_pru_cb,
+	.remove		= rpmsg_pru_remove,
+};
+
+static int __init rpmsg_pru_init(void)
+{
+	int ret;
+
+	rpmsg_pru_class = class_create(THIS_MODULE, "rpmsg_pru");
+	if (IS_ERR(rpmsg_pru_class)) {
+		pr_err("Unable to create class\n");
+		ret = PTR_ERR(rpmsg_pru_class);
+		goto fail_create_class;
+	}
+
+	ret = alloc_chrdev_region(&rpmsg_pru_devt, 0, PRU_MAX_DEVICES,
+				  "rpmsg_pru");
+	if (ret) {
+		pr_err("Unable to allocate chrdev region\n");
+		goto fail_alloc_region;
+	}
+
+	ret = register_rpmsg_driver(&rpmsg_pru_driver);
+	if (ret) {
+		pr_err("Unable to register rpmsg driver");
+		goto fail_register_rpmsg_driver;
+	}
+
+	return 0;
+
+fail_register_rpmsg_driver:
+	unregister_chrdev_region(rpmsg_pru_devt, PRU_MAX_DEVICES);
+fail_alloc_region:
+	class_destroy(rpmsg_pru_class);
+fail_create_class:
+	return ret;
+}
+
+static void __exit rpmsg_pru_exit(void)
+{
+	unregister_rpmsg_driver(&rpmsg_pru_driver);
+	idr_destroy(&rpmsg_pru_minors);
+	mutex_destroy(&rpmsg_pru_lock);
+	class_destroy(rpmsg_pru_class);
+	unregister_chrdev_region(rpmsg_pru_devt, PRU_MAX_DEVICES);
+}
+
+module_init(rpmsg_pru_init);
+module_exit(rpmsg_pru_exit);
+
+MODULE_AUTHOR("Jason Reeder <jreeder@ti.com>");
+MODULE_ALIAS("rpmsg:rpmsg-pru");
+MODULE_DESCRIPTION("PRU Remote Processor Messaging Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/pru-cookbook/05blocks/code/module/setup.sh b/pru-cookbook/05blocks/code/module/setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3b313b366052438b0db8e7a7c0f00a04313b8687
--- /dev/null
+++ b/pru-cookbook/05blocks/code/module/setup.sh
@@ -0,0 +1 @@
+insmod rpmsg_pru.ko
diff --git a/pru-cookbook/05blocks/code/neo-colors.py b/pru-cookbook/05blocks/code/neo-colors.py
new file mode 100755
index 0000000000000000000000000000000000000000..736a47b3c7e6ae2507da296fdae5ac01be7f7a14
--- /dev/null
+++ b/pru-cookbook/05blocks/code/neo-colors.py
@@ -0,0 +1,41 @@
+#!/usr/bin/python3
+from time import sleep
+import math
+
+length = 24
+max = 25
+
+# Open a file
+fo = open("/dev/rpmsg_pru30", "wb", 0)
+
+colors = [[1,0,0],[1,1,0],[0,1,0],[0,1,1],[0,0,1],[1,0,1]]# colors = [[1,0,0],[1,0,0]]
+
+oldr=0
+oldb=0
+oldg=0
+
+while True:
+    for color in colors:
+        newr = color[0]
+        newg = color[1]
+        newb = color[2]
+        maxtime=20
+        for time in range(0, maxtime):
+            r = (max*oldr+(newr-oldr)*max*time/maxtime)
+            g = (max*oldg+(newg-oldg)*max*time/maxtime)
+            b = (max*oldb+(newb-oldb)*max*time/maxtime)
+            for i in range(0, length):
+                fo.write(b"%d %d %d %d\n" % (i, r, g, b))
+                # print("0 0 127 %d" % (i))
+            fo.write(b"-1 0 0 0\n");    # Send colors to LEDs
+            
+            # print (r,g,b)
+            
+            sleep(0.05)
+            
+        oldr=newr
+        oldg=newg
+        oldb=newb
+
+# Close opened file
+fo.close()
\ No newline at end of file
diff --git a/pru-cookbook/05blocks/code/neo-rainbow.py b/pru-cookbook/05blocks/code/neo-rainbow.py
new file mode 100755
index 0000000000000000000000000000000000000000..ffd706a643a9c71609e8b8893b6ff91b53cde08b
--- /dev/null
+++ b/pru-cookbook/05blocks/code/neo-rainbow.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python3
+from time import sleep
+import math
+
+len = 24
+amp = 12
+f = 25
+shift = 3
+phase = 0
+
+# Open a file
+fo = open("/dev/rpmsg_pru30", "wb", 0)
+
+while True:
+    for i in range(0, len):
+        r = (amp * (math.sin(2*math.pi*f*(i-phase-0*shift)/len) + 1)) + 1;
+        g = (amp * (math.sin(2*math.pi*f*(i-phase-1*shift)/len) + 1)) + 1;
+        b = (amp * (math.sin(2*math.pi*f*(i-phase-2*shift)/len) + 1)) + 1;
+        fo.write(b"%d %d %d %d\n" % (i, r, g, b))
+        # print("0 0 127 %d" % (i))
+
+    fo.write(b"-1 0 0 0\n");
+    phase = phase + 1
+    sleep(0.05)
+
+# Close opened file
+fo.close()
\ No newline at end of file
diff --git a/pru-cookbook/05blocks/code/neo1.pru0.c b/pru-cookbook/05blocks/code/neo1.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..5f2ce8248d73706b8f78c7b76e5df9009ffd4b02
--- /dev/null
+++ b/pru-cookbook/05blocks/code/neo1.pru0.c
@@ -0,0 +1,44 @@
+// Control a ws2812 (NeoPixel) display, All on or all off
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+#define STR_LEN 24
+#define	oneCyclesOn		700/5	// Stay on 700ns
+#define oneCyclesOff	800/5
+#define zeroCyclesOn	350/5
+#define zeroCyclesOff	600/5
+#define resetCycles		60000/5	// Must be at least 50u, use 60u
+#define gpio P9_29				// output pin
+
+#define ONE
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	uint32_t i;
+	for(i=0; i<STR_LEN*3*8; i++) {
+#ifdef ONE
+		__R30 |= gpio;		// Set the GPIO pin to 1
+		__delay_cycles(oneCyclesOn-1);
+		__R30 &= ~gpio;		// Clear the GPIO pin
+		__delay_cycles(oneCyclesOff-2);
+#else
+		__R30 |= gpio;		// Set the GPIO pin to 1
+		__delay_cycles(zeroCyclesOn-1);
+		__R30 &= ~gpio;		// Clear the GPIO pin
+		__delay_cycles(zeroCyclesOff-2);
+#endif
+	}
+	// Send Reset
+	__R30 &= ~gpio;	// Clear the GPIO pin
+	__delay_cycles(resetCycles);
+	
+	__halt();
+}
diff --git a/pru-cookbook/05blocks/code/neo1.pru1_1.c b/pru-cookbook/05blocks/code/neo1.pru1_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..2ad8d56d1cff431ab3c006788440454083b26e96
--- /dev/null
+++ b/pru-cookbook/05blocks/code/neo1.pru1_1.c
@@ -0,0 +1,44 @@
+// Control a ws2812 (NeoPixel) display, All on or all off
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+#define STR_LEN 24
+#define	oneCyclesOn		700/5	// Stay on 700ns
+#define oneCyclesOff	800/5
+#define zeroCyclesOn	350/5
+#define zeroCyclesOff	600/5
+#define resetCycles		60000/5	// Must be at least 50u, use 60u
+#define gpio P9_16				// output pin
+
+#define ONE
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	uint32_t i;
+	for(i=0; i<STR_LEN*3*8; i++) {
+#ifdef ONE
+		__R30 |= gpio;		// Set the GPIO pin to 1
+		__delay_cycles(oneCyclesOn-1);
+		__R30 &= ~gpio;		// Clear the GPIO pin
+		__delay_cycles(oneCyclesOff-2);
+#else
+		__R30 |= gpio;		// Set the GPIO pin to 1
+		__delay_cycles(zeroCyclesOn-1);
+		__R30 &= ~gpio;		// Clear the GPIO pin
+		__delay_cycles(zeroCyclesOff-2);
+#endif
+	}
+	// Send Reset
+	__R30 &= ~gpio;	// Clear the GPIO pin
+	__delay_cycles(resetCycles);
+	
+	__halt();
+}
diff --git a/pru-cookbook/05blocks/code/neo2.pru0.c b/pru-cookbook/05blocks/code/neo2.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..a30077ceb090f7e3722cb0fe1a61162bdde9bb9d
--- /dev/null
+++ b/pru-cookbook/05blocks/code/neo2.pru0.c
@@ -0,0 +1,46 @@
+// Control a ws2812 (neo pixel) display, green, red, blue, green, ...
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+#define STR_LEN 3
+#define	oneCyclesOn		700/5	// Stay on 700ns
+#define oneCyclesOff	800/5
+#define zeroCyclesOn	350/5
+#define zeroCyclesOff	600/5
+#define resetCycles		60000/5	// Must be at least 50u, use 60u
+#define gpio P9_29				// output pin
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+	
+	uint32_t color[STR_LEN] = {0x0f0000, 0x000f00, 0x0000f};	// green, red, blue
+	int i, j;
+
+	for(j=0; j<STR_LEN; j++) {
+		for(i=23; i>=0; i--) {
+			if(color[j] & (0x1<<i)) {
+				__R30 |= gpio;		// Set the GPIO pin to 1
+				__delay_cycles(oneCyclesOn-1);
+				__R30 &= ~gpio;		// Clear the GPIO pin
+				__delay_cycles(oneCyclesOff-2);
+			} else {
+				__R30 |= gpio;		// Set the GPIO pin to 1
+				__delay_cycles(zeroCyclesOn-1);
+				__R30 &= ~gpio;		// Clear the GPIO pin
+				__delay_cycles(zeroCyclesOff-2);
+			}
+		}
+	}
+	// Send Reset
+	__R30 &= ~gpio;	// Clear the GPIO pin
+	__delay_cycles(resetCycles);
+	
+	__halt();
+}
diff --git a/pru-cookbook/05blocks/code/neo2.pru1_1.c b/pru-cookbook/05blocks/code/neo2.pru1_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..6b243dcfb53c2139f44d4a2aabd113a274c331e8
--- /dev/null
+++ b/pru-cookbook/05blocks/code/neo2.pru1_1.c
@@ -0,0 +1,46 @@
+// Control a ws2812 (neo pixel) display, green, red, blue, green, ...
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+#define STR_LEN 3
+#define	oneCyclesOn		700/5	// Stay on 700ns
+#define oneCyclesOff	800/5
+#define zeroCyclesOn	350/5
+#define zeroCyclesOff	600/5
+#define resetCycles		60000/5	// Must be at least 50u, use 60u
+#define gpio P9_16				// output pin
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+	
+	uint32_t color[STR_LEN] = {0x0f0000, 0x000f00, 0x0000f};	// green, red, blue
+	int i, j;
+
+	for(j=0; j<STR_LEN; j++) {
+		for(i=23; i>=0; i--) {
+			if(color[j] & (0x1<<i)) {
+				__R30 |= gpio;		// Set the GPIO pin to 1
+				__delay_cycles(oneCyclesOn-1);
+				__R30 &= ~gpio;		// Clear the GPIO pin
+				__delay_cycles(oneCyclesOff-2);
+			} else {
+				__R30 |= gpio;		// Set the GPIO pin to 1
+				__delay_cycles(zeroCyclesOn-1);
+				__R30 &= ~gpio;		// Clear the GPIO pin
+				__delay_cycles(zeroCyclesOff-2);
+			}
+		}
+	}
+	// Send Reset
+	__R30 &= ~gpio;	// Clear the GPIO pin
+	__delay_cycles(resetCycles);
+	
+	__halt();
+}
diff --git a/pru-cookbook/05blocks/code/neo3.pru0.c b/pru-cookbook/05blocks/code/neo3.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..8c1a9f1323d564d7894b299f1bd4f8a4020bc5e8
--- /dev/null
+++ b/pru-cookbook/05blocks/code/neo3.pru0.c
@@ -0,0 +1,67 @@
+// Control a ws2812 (neo pixel) display, green, red, blue, green, ...
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+#define STR_LEN 24
+#define	oneCyclesOn		700/5	// Stay on 700ns
+#define oneCyclesOff	800/5
+#define zeroCyclesOn	350/5
+#define zeroCyclesOff	600/5
+#define resetCycles		60000/5	// Must be at least 50u, use 60u
+#define gpio P9_29				// output pin
+
+#define SPEED 20000000/5		// Time to wait between updates
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t background = 0x00000f;
+	uint32_t foreground = 0x000f00;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+	
+	uint32_t color[STR_LEN];	// green, red, blue
+	int i, j;
+	int k, oldk = 0;;
+	// Set everything to background
+	for(i=0; i<STR_LEN; i++) {
+		color[i] = background;
+	}
+	
+	while(1) {
+		// Move forward one position
+		for(k=0; k<STR_LEN; k++) {
+			color[oldk] = background;
+			color[k]    = foreground;
+			oldk=k;
+
+			// Output the string
+			for(j=0; j<STR_LEN; j++) {
+				for(i=23; i>=0; i--) {
+					if(color[j] & (0x1<<i)) {
+						__R30 |= gpio;		// Set the GPIO pin to 1
+						__delay_cycles(oneCyclesOn-1);
+						__R30 &= ~gpio;		// Clear the GPIO pin
+						__delay_cycles(oneCyclesOff-2);
+					} else {
+						__R30 |= gpio;		// Set the GPIO pin to 1
+						__delay_cycles(zeroCyclesOn-1);
+						__R30 &= ~gpio;		// Clear the GPIO pin
+						__delay_cycles(zeroCyclesOff-2);
+					}
+				}
+			}
+			// Send Reset
+			__R30 &= ~gpio;	// Clear the GPIO pin
+			__delay_cycles(resetCycles);
+
+			// Wait
+			__delay_cycles(SPEED);
+		}
+	}
+}
diff --git a/pru-cookbook/05blocks/code/neo3.pru1_1.c b/pru-cookbook/05blocks/code/neo3.pru1_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..ee8dd63859680a930b3dca6c8c61895a87051ac9
--- /dev/null
+++ b/pru-cookbook/05blocks/code/neo3.pru1_1.c
@@ -0,0 +1,67 @@
+// Control a ws2812 (neo pixel) display, green, red, blue, green, ...
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+#define STR_LEN 24
+#define	oneCyclesOn		700/5	// Stay on 700ns
+#define oneCyclesOff	800/5
+#define zeroCyclesOn	350/5
+#define zeroCyclesOff	600/5
+#define resetCycles		60000/5	// Must be at least 50u, use 60u
+#define gpio P9_16				// output pin
+
+#define SPEED 20000000/5		// Time to wait between updates
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t background = 0x00000f;
+	uint32_t foreground = 0x000f00;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+	
+	uint32_t color[STR_LEN];	// green, red, blue
+	int i, j;
+	int k, oldk = 0;;
+	// Set everything to background
+	for(i=0; i<STR_LEN; i++) {
+		color[i] = background;
+	}
+	
+	while(1) {
+		// Move forward one position
+		for(k=0; k<STR_LEN; k++) {
+			color[oldk] = background;
+			color[k]    = foreground;
+			oldk=k;
+
+			// Output the string
+			for(j=0; j<STR_LEN; j++) {
+				for(i=23; i>=0; i--) {
+					if(color[j] & (0x1<<i)) {
+						__R30 |= gpio;		// Set the GPIO pin to 1
+						__delay_cycles(oneCyclesOn-1);
+						__R30 &= ~gpio;		// Clear the GPIO pin
+						__delay_cycles(oneCyclesOff-2);
+					} else {
+						__R30 |= gpio;		// Set the GPIO pin to 1
+						__delay_cycles(zeroCyclesOn-1);
+						__R30 &= ~gpio;		// Clear the GPIO pin
+						__delay_cycles(zeroCyclesOff-2);
+					}
+				}
+			}
+			// Send Reset
+			__R30 &= ~gpio;	// Clear the GPIO pin
+			__delay_cycles(resetCycles);
+
+			// Wait
+			__delay_cycles(SPEED);
+		}
+	}
+}
diff --git a/pru-cookbook/05blocks/code/neo4.pru0.c b/pru-cookbook/05blocks/code/neo4.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..7fb5455781d8dc47cd414a433b1578ea84645ad9
--- /dev/null
+++ b/pru-cookbook/05blocks/code/neo4.pru0.c
@@ -0,0 +1,145 @@
+// Use rpmsg to control the NeoPixels via /dev/rpmsg_pru30
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>			// atoi
+#include <string.h>
+#include <pru_cfg.h>
+#include <pru_intc.h>
+#include <rsc_types.h>
+#include <pru_rpmsg.h>
+#include "resource_table_0.h"
+#include "prugpio.h"
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+/* Host-0 Interrupt sets bit 30 in register R31 */
+#define HOST_INT			((uint32_t) 1 << 30)	
+
+/* The PRU-ICSS system events used for RPMsg are defined in the Linux device tree
+ * PRU0 uses system event 16 (To ARM) and 17 (From ARM)
+ * PRU1 uses system event 18 (To ARM) and 19 (From ARM)
+ */
+#define TO_ARM_HOST			16	
+#define FROM_ARM_HOST		17
+
+/*
+* Using the name 'rpmsg-pru' will probe the rpmsg_pru driver found
+* at linux-x.y.z/drivers/rpmsg/rpmsg_pru.c
+*/
+#define CHAN_NAME			"rpmsg-pru"
+#define CHAN_DESC			"Channel 30"
+#define CHAN_PORT			30
+
+/*
+ * Used to make sure the Linux drivers are ready for RPMsg communication
+ * Found at linux-x.y.z/include/uapi/linux/virtio_config.h
+ */
+#define VIRTIO_CONFIG_S_DRIVER_OK	4
+
+char payload[RPMSG_BUF_SIZE];
+
+#define STR_LEN 24
+#define	oneCyclesOn		700/5	// Stay on for 700ns
+#define oneCyclesOff	600/5
+#define zeroCyclesOn	350/5
+#define zeroCyclesOff	800/5
+#define resetCycles		51000/5	// Must be at least 50u, use 51u
+#define out P9_29				// Bit number to output on
+
+#define SPEED 20000000/5		// Time to wait between updates
+
+uint32_t color[STR_LEN];	// green, red, blue
+
+/*
+ * main.c
+ */
+void main(void)
+{
+	struct pru_rpmsg_transport transport;
+	uint16_t src, dst, len;
+	volatile uint8_t *status;
+	
+	uint8_t r, g, b;
+	int i, j;
+	// Set everything to background
+	for(i=0; i<STR_LEN; i++) {
+		color[i] = 0x010000;
+	}
+
+	/* Allow OCP master port access by the PRU so the PRU can read external memories */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	/* Clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */
+#ifdef CHIP_IS_am57xx
+	CT_INTC.SICR_bit.STATUS_CLR_INDEX = FROM_ARM_HOST;
+#else
+	CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
+#endif
+
+	/* Make sure the Linux drivers are ready for RPMsg communication */
+	status = &resourceTable.rpmsg_vdev.status;
+	while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK));
+
+	/* Initialize the RPMsg transport structure */
+	pru_rpmsg_init(&transport, &resourceTable.rpmsg_vring0, &resourceTable.rpmsg_vring1, TO_ARM_HOST, FROM_ARM_HOST);
+
+	/* Create the RPMsg channel between the PRU and ARM user space using the transport structure. */
+	while (pru_rpmsg_channel(RPMSG_NS_CREATE, &transport, CHAN_NAME, CHAN_DESC, CHAN_PORT) != PRU_RPMSG_SUCCESS);
+	while (1) {
+		/* Check bit 30 of register R31 to see if the ARM has kicked us */
+		if (__R31 & HOST_INT) {
+			/* Clear the event status */
+#ifdef CHIP_IS_am57xx
+			CT_INTC.SICR_bit.STATUS_CLR_INDEX = FROM_ARM_HOST;
+#else
+			CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
+#endif
+			/* Receive all available messages, multiple messages can be sent per kick */
+			while (pru_rpmsg_receive(&transport, &src, &dst, payload, &len) == PRU_RPMSG_SUCCESS) {
+			    char *ret;	// rest of payload after front character is removed
+			    int index;	// index of LED to control
+			    // Input format is:  index red green blue
+			    index = atoi(payload);	
+			    // Update the array, but don't write it out.
+			    if((index >=0) & (index < STR_LEN)) {
+			    	ret = strchr(payload, ' ');	// Skip over index
+				    r = strtol(&ret[1], NULL, 0);
+				    ret = strchr(&ret[1], ' ');	// Skip over r, etc.
+				    g = strtol(&ret[1], NULL, 0);
+				    ret = strchr(&ret[1], ' ');
+				    b = strtol(&ret[1], NULL, 0);
+
+				    color[index] = (g<<16)|(r<<8)|b;	// String wants GRB
+			    }
+			    // When index is -1, send the array to the LED string
+			    if(index == -1) {
+				    // Output the string
+					for(j=0; j<STR_LEN; j++) {
+						// Cycle through each bit
+						for(i=23; i>=0; i--) {
+							if(color[j] & (0x1<<i)) {
+								__R30 |= out;		// Set the GPIO pin to 1
+								__delay_cycles(oneCyclesOn-1);
+								__R30 &= ~out;	// Clear the GPIO pin
+								__delay_cycles(oneCyclesOff-14);
+							} else {
+								__R30 |= out;		// Set the GPIO pin to 1
+								__delay_cycles(zeroCyclesOn-1);
+								__R30 &= ~(out);	// Clear the GPIO pin
+								__delay_cycles(zeroCyclesOff-14);
+							}
+						}
+					}
+					// Send Reset
+					__R30 &= ~out;	// Clear the GPIO pin
+					__delay_cycles(resetCycles);
+		
+					// Wait
+					__delay_cycles(SPEED);
+			    }
+
+			}
+		}
+	}
+}
diff --git a/pru-cookbook/05blocks/code/neo4.pru1_1.c b/pru-cookbook/05blocks/code/neo4.pru1_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..7c120937aa92b19fbc65971aa8a6ec3748c69ca4
--- /dev/null
+++ b/pru-cookbook/05blocks/code/neo4.pru1_1.c
@@ -0,0 +1,145 @@
+// Use rpmsg to control the NeoPixels via /dev/rpmsg_pru30
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>			// atoi
+#include <string.h>
+#include <pru_cfg.h>
+#include <pru_intc.h>
+#include <rsc_types.h>
+#include <pru_rpmsg.h>
+#include "resource_table_1.h"
+#include "prugpio.h"
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+/* Host-1 Interrupt sets bit 31 in register R31 */
+#define HOST_INT			((uint32_t) 1 << 31)	
+
+/* The PRU-ICSS system events used for RPMsg are defined in the Linux device tree
+ * PRU0 uses system event 16 (To ARM) and 17 (From ARM)
+ * PRU1 uses system event 18 (To ARM) and 19 (From ARM)
+ */
+#define TO_ARM_HOST			18	
+#define FROM_ARM_HOST		19
+
+/*
+* Using the name 'rpmsg-pru' will probe the rpmsg_pru driver found
+* at linux-x.y.z/drivers/rpmsg/rpmsg_pru.c
+*/
+#define CHAN_NAME			"rpmsg-pru"
+#define CHAN_DESC			"Channel 31"
+#define CHAN_PORT			31
+
+/*
+ * Used to make sure the Linux drivers are ready for RPMsg communication
+ * Found at linux-x.y.z/include/uapi/linux/virtio_config.h
+ */
+#define VIRTIO_CONFIG_S_DRIVER_OK	4
+
+char payload[RPMSG_BUF_SIZE];
+
+#define STR_LEN 24
+#define	oneCyclesOn		700/5	// Stay on for 700ns
+#define oneCyclesOff	600/5
+#define zeroCyclesOn	350/5
+#define zeroCyclesOff	800/5
+#define resetCycles		51000/5	// Must be at least 50u, use 51u
+#define out P9_16					// Bit number to output on
+
+#define SPEED 20000000/5		// Time to wait between updates
+
+uint32_t color[STR_LEN];	// green, red, blue
+
+/*
+ * main.c
+ */
+void main(void)
+{
+	struct pru_rpmsg_transport transport;
+	uint16_t src, dst, len;
+	volatile uint8_t *status;
+	
+	uint8_t r, g, b;
+	int i, j;
+	// Set everything to background
+	for(i=0; i<STR_LEN; i++) {
+		color[i] = 0x010000;
+	}
+
+	/* Allow OCP master port access by the PRU so the PRU can read external memories */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	/* Clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */
+#ifdef CHIP_IS_am57xx
+	CT_INTC.SICR_bit.STATUS_CLR_INDEX = FROM_ARM_HOST;
+#else
+	CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
+#endif
+
+	/* Make sure the Linux drivers are ready for RPMsg communication */
+	status = &resourceTable.rpmsg_vdev.status;
+	while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK));
+
+	/* Initialize the RPMsg transport structure */
+	pru_rpmsg_init(&transport, &resourceTable.rpmsg_vring0, &resourceTable.rpmsg_vring1, TO_ARM_HOST, FROM_ARM_HOST);
+
+	/* Create the RPMsg channel between the PRU and ARM user space using the transport structure. */
+	while (pru_rpmsg_channel(RPMSG_NS_CREATE, &transport, CHAN_NAME, CHAN_DESC, CHAN_PORT) != PRU_RPMSG_SUCCESS);
+	while (1) {
+		/* Check bit 30 of register R31 to see if the ARM has kicked us */
+		if (__R31 & HOST_INT) {
+			/* Clear the event status */
+#ifdef CHIP_IS_am57xx
+			CT_INTC.SICR_bit.STATUS_CLR_INDEX = FROM_ARM_HOST;
+#else
+			CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
+#endif
+			/* Receive all available messages, multiple messages can be sent per kick */
+			while (pru_rpmsg_receive(&transport, &src, &dst, payload, &len) == PRU_RPMSG_SUCCESS) {
+			    char *ret;	// rest of payload after front character is removed
+			    int index;	// index of LED to control
+			    // Input format is:  index red green blue
+			    index = atoi(payload);	
+			    // Update the array, but don't write it out.
+			    if((index >=0) & (index < STR_LEN)) {
+			    	ret = strchr(payload, ' ');	// Skip over index
+				    r = strtol(&ret[1], NULL, 0);
+				    ret = strchr(&ret[1], ' ');	// Skip over r, etc.
+				    g = strtol(&ret[1], NULL, 0);
+				    ret = strchr(&ret[1], ' ');
+				    b = strtol(&ret[1], NULL, 0);
+
+				    color[index] = (g<<16)|(r<<8)|b;	// String wants GRB
+			    }
+			    // When index is -1, send the array to the LED string
+			    if(index == -1) {
+				    // Output the string
+					for(j=0; j<STR_LEN; j++) {
+						// Cycle through each bit
+						for(i=23; i>=0; i--) {
+							if(color[j] & (0x1<<i)) {
+								__R30 |= out;		// Set the GPIO pin to 1
+								__delay_cycles(oneCyclesOn-1);
+								__R30 &= ~out;	// Clear the GPIO pin
+								__delay_cycles(oneCyclesOff-14);
+							} else {
+								__R30 |= out;		// Set the GPIO pin to 1
+								__delay_cycles(zeroCyclesOn-1);
+								__R30 &= ~(out);	// Clear the GPIO pin
+								__delay_cycles(zeroCyclesOff-14);
+							}
+						}
+					}
+					// Send Reset
+					__R30 &= ~out;	// Clear the GPIO pin
+					__delay_cycles(resetCycles);
+		
+					// Wait
+					__delay_cycles(SPEED);
+			    }
+
+			}
+		}
+	}
+}
diff --git a/pru-cookbook/05blocks/code/neo_setup.sh b/pru-cookbook/05blocks/code/neo_setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8f98cbb2a9ae5f915cafc47af006b958fffe44f7
--- /dev/null
+++ b/pru-cookbook/05blocks/code/neo_setup.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+export TARGET=neo1.pru0
+echo TARGET=$TARGET
+
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P9_29 "
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P1_33"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin pruout
+    config-pin -q $pin
+done
diff --git a/pru-cookbook/05blocks/code/pwm-test.c b/pru-cookbook/05blocks/code/pwm-test.c
new file mode 100644
index 0000000000000000000000000000000000000000..3bff5f71b6598b3f6ee1fd0fc04bdac16793cda8
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm-test.c
@@ -0,0 +1,74 @@
+/* 
+ *
+ *  pwm tester
+ *	The on cycle and off cycles are stored in each PRU's Data memory
+ *
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#define MAXCH 4
+
+#define PRU_ADDR		0x4A300000		// Start of PRU memory Page 184 am335x TRM
+#define PRU_LEN			0x80000			// Length of PRU memory
+#define PRU0_DRAM		0x00000			// Offset to DRAM
+#define PRU1_DRAM		0x02000
+#define PRU_SHAREDMEM	0x10000			// Offset to shared memory
+
+unsigned int	*pru0DRAM_32int_ptr;		// Points to the start of local DRAM
+unsigned int	*pru1DRAM_32int_ptr;		// Points to the start of local DRAM
+unsigned int	*prusharedMem_32int_ptr;	// Points to the start of the shared memory
+
+/*******************************************************************************
+* int start_pwm_count(int ch, int countOn, int countOff)
+* 
+* Starts a pwm pulse on for countOn and off for countOff to a single channel (ch)
+*******************************************************************************/
+int start_pwm_count(int ch, int countOn, int countOff) {
+	unsigned int *pruDRAM_32int_ptr = pru0DRAM_32int_ptr;
+	
+	printf("countOn: %d, countOff: %d, count: %d\n", 
+		countOn, countOff, countOn+countOff);
+	// write to PRU shared memory
+	pruDRAM_32int_ptr[2*(ch)+0] = countOn;	// On time
+	pruDRAM_32int_ptr[2*(ch)+1] = countOff;	// Off time
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	unsigned int	*pru;		// Points to start of PRU memory.
+	int	fd;
+	printf("Servo tester\n");
+	
+	fd = open ("/dev/mem", O_RDWR | O_SYNC);
+	if (fd == -1) {
+		printf ("ERROR: could not open /dev/mem.\n\n");
+		return 1;
+	}
+	pru = mmap (0, PRU_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, PRU_ADDR);
+	if (pru == MAP_FAILED) {
+		printf ("ERROR: could not map memory.\n\n");
+		return 1;
+	}
+	close(fd);
+	printf ("Using /dev/mem.\n");
+	
+	pru0DRAM_32int_ptr =     pru + PRU0_DRAM/4 + 0x200/4;	// Points to 0x200 of PRU0 memory
+	pru1DRAM_32int_ptr =     pru + PRU1_DRAM/4 + 0x200/4;	// Points to 0x200 of PRU1 memory
+	prusharedMem_32int_ptr = pru + PRU_SHAREDMEM/4;	// Points to start of shared memory
+
+	int i;
+	for(i=0; i<MAXCH; i++) {
+		start_pwm_count(i, i+1, 20-(i+1));
+	}
+	
+	if(munmap(pru, PRU_LEN)) {
+		printf("munmap failed\n");
+	} else {
+		printf("munmap succeeded\n");
+	}
+}
+
diff --git a/pru-cookbook/05blocks/code/pwm1.pru0.c b/pru-cookbook/05blocks/code/pwm1.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..2ea5caa17efd570bad1cbc658d5e2c96557b1b0f
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm1.pru0.c
@@ -0,0 +1,22 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t gpio = P9_31;	// Select which pin to toggle.;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	while(1) {
+		__R30 |= gpio;		// Set the GPIO pin to 1
+		__delay_cycles(100000000);
+		__R30 &= ~gpio;		// Clear the GPIO pin
+		__delay_cycles(100000000);
+	}
+}
diff --git a/pru-cookbook/05blocks/code/pwm1.pru1_1.c b/pru-cookbook/05blocks/code/pwm1.pru1_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..1f8b737e678691af3c4ab83cfa2d1d5bc442fe64
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm1.pru1_1.c
@@ -0,0 +1,22 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t gpio = P9_16;	// Select which pin to toggle.;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	while(1) {
+		__R30 |= gpio;		// Set the GPIO pin to 1
+		__delay_cycles(100000000);
+		__R30 &= ~gpio;		// Clear the GPIO pin
+		__delay_cycles(100000000);
+	}
+}
diff --git a/pru-cookbook/05blocks/code/pwm2.pru0.c b/pru-cookbook/05blocks/code/pwm2.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..bfa0d0761411212a8a0f4469ca02dfd08f5a20bd
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm2.pru0.c
@@ -0,0 +1,22 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t gpio = P9_31;	// Select which pin to toggle.;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	while (1) {
+		__R30 |= gpio;		// Set the GPIO pin to 1
+		__delay_cycles(1);	// Delay one cycle to correct for loop time
+		__R30 &= ~gpio;		// Clear the GPIO pin
+		__delay_cycles(0);
+	}
+}
diff --git a/pru-cookbook/05blocks/code/pwm3.pru0.c b/pru-cookbook/05blocks/code/pwm3.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..4b2955a0573171e7e3525a9381e4a4a2acb15e36
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm3.pru0.c
@@ -0,0 +1,43 @@
+// This code does MAXCH parallel PWM channels.
+// It's period is 3 us
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+
+#define MAXCH	4	// Maximum number of channels
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t ch;
+	uint32_t on[] = {1, 2, 3, 4};	// Number of cycles to stay on
+	uint32_t off[] = {4, 3, 2, 1};	// Number to stay off
+	uint32_t onCount[MAXCH];		// Current count
+	uint32_t offCount[MAXCH];
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	// Initialize the channel counters.
+	for(ch=0; ch<MAXCH; ch++) {
+		onCount[ch] = on[ch];
+		offCount[ch]= off[ch];
+	}
+
+	while (1) {
+		for(ch=0; ch<MAXCH; ch++) {
+			if(onCount[ch]) {
+				onCount[ch]--;
+				__R30 |= 0x1<<ch;		// Set the GPIO pin to 1
+			} else if(offCount[ch]) {
+				offCount[ch]--;
+				__R30 &= ~(0x1<<ch);		// Clear the GPIO pin
+			} else {
+				onCount[ch] = on[ch];
+				offCount[ch]= off[ch];
+			}
+		}
+	}
+}
diff --git a/pru-cookbook/05blocks/code/pwm4.pru0.c b/pru-cookbook/05blocks/code/pwm4.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..ee0f7ec6adf542562b8740ce410226840b01ac50
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm4.pru0.c
@@ -0,0 +1,50 @@
+// This code does MAXCH parallel PWM channels.
+// It's period is 3 us
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+
+#define PRU0_DRAM		0x00000			// Offset to DRAM
+// Skip the first 0x200 byte of DRAM since the Makefile allocates
+// 0x100 for the STACK and 0x100 for the HEAP.
+volatile unsigned int *pru0_dram = (unsigned int *) (PRU0_DRAM + 0x200);
+
+#define MAXCH	4	// Maximum number of channels per PRU
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t ch;
+	uint32_t on[]  = {1, 2, 3, 4};	// Number of cycles to stay on
+	uint32_t off[] = {4, 3, 2, 1};	// Number to stay off
+	uint32_t onCount[MAXCH];		// Current count
+	uint32_t offCount[MAXCH];
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	// Initialize the channel counters.
+	for(ch=0; ch<MAXCH; ch++) {
+		pru0_dram[2*ch  ] = on[ch];		// Copy to DRAM0 so the ARM can change it
+		pru0_dram[2*ch+1] = off[ch];	// Interleave the on and off values
+		onCount[ch] = on[ch];
+		offCount[ch]= off[ch];
+	}
+
+	while (1) {
+		for(ch=0; ch<MAXCH; ch++) {
+			if(onCount[ch]) {
+				onCount[ch]--;
+				__R30 |= 0x1<<ch;		// Set the GPIO pin to 1
+			} else if(offCount[ch]) {
+				offCount[ch]--;
+				__R30 &= ~(0x1<<ch);	// Clear the GPIO pin
+			} else {
+				onCount[ch] = pru0_dram[2*ch];		// Read from DRAM0
+				offCount[ch]= pru0_dram[2*ch+1];
+			}
+		}
+	}
+}
diff --git a/pru-cookbook/05blocks/code/pwm5.pru0.c b/pru-cookbook/05blocks/code/pwm5.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..60a97b817c32ca25fcbd9445ec6d612151ed21c6
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm5.pru0.c
@@ -0,0 +1,53 @@
+// This code does MAXCH parallel PWM channels.
+// It's period is 510ns.
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+
+#define PRU0_DRAM		0x00000			// Offset to DRAM
+// Skip the first 0x200 byte of DRAM since the Makefile allocates
+// 0x100 for the STACK and 0x100 for the HEAP.
+volatile unsigned int *pru0_dram = (unsigned int *) (PRU0_DRAM + 0x200);
+
+#define MAXCH	4	// Maximum number of channels per PRU
+
+#define update(ch) \
+			if(onCount[ch]) {			\
+				onCount[ch]--;			\
+				__R30 |= 0x1<<ch;		\
+			} else if(offCount[ch]) {	\
+				offCount[ch]--;			\
+				__R30 &= ~(0x1<<ch);	\
+			} else {					\
+				onCount[ch] = pru0_dram[2*ch];	\
+				offCount[ch]= pru0_dram[2*ch+1];	\
+			}
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t ch;
+	uint32_t on[]  = {1, 2, 3, 4};
+	uint32_t off[] = {4, 3, 2, 1};
+	uint32_t onCount[MAXCH], offCount[MAXCH];
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+#pragma UNROLL(MAXCH)
+	for(ch=0; ch<MAXCH; ch++) {
+		pru0_dram[2*ch  ] = on[ch];		// Copy to DRAM0 so the ARM can change it
+		pru0_dram[2*ch+1] = off[ch];	// Interleave the on and off values
+		onCount[ch] = on[ch];
+		offCount[ch]= off[ch];
+	}
+
+	while (1) {
+		update(0)
+		update(1)
+		update(2)
+		update(3)
+	}
+}
diff --git a/pru-cookbook/05blocks/code/pwm6.pru0.c b/pru-cookbook/05blocks/code/pwm6.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..6df321f5f0d7094b6ec93e57cbf65a62994094a1
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm6.pru0.c
@@ -0,0 +1,56 @@
+// This code does MAXCH parallel PWM channels.
+// All channels start at the same time. It's period is 510ns
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+
+#define PRU0_DRAM		0x00000			// Offset to DRAM
+// Skip the first 0x200 byte of DRAM since the Makefile allocates
+// 0x100 for the STACK and 0x100 for the HEAP.
+volatile unsigned int *pru0_dram = (unsigned int *) (PRU0_DRAM + 0x200);
+
+#define MAXCH	4	// Maximum number of channels per PRU
+
+#define update(ch) \
+			if(onCount[ch]) {			\
+				onCount[ch]--;			\
+				Rtmp |= 0x1<<ch;		\
+			} else if(offCount[ch]) {	\
+				offCount[ch]--;			\
+				Rtmp &= ~(0x1<<ch);	\
+			} else {					\
+				onCount[ch] = pru0_dram[2*ch];	\
+				offCount[ch]= pru0_dram[2*ch+1];	\
+			}
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t ch;
+	uint32_t on[]  = {1, 2, 3, 4};
+	uint32_t off[] = {4, 3, 2, 1};
+	uint32_t onCount[MAXCH], offCount[MAXCH];
+	register uint32_t Rtmp;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+#pragma UNROLL(MAXCH)
+	for(ch=0; ch<MAXCH; ch++) {
+		pru0_dram[2*ch  ] = on[ch];		// Copy to DRAM0 so the ARM can change it
+		pru0_dram[2*ch+1] = off[ch];	// Interleave the on and off values
+		onCount[ch] = on[ch];
+		offCount[ch]= off[ch];
+	}
+	Rtmp = __R30;
+
+	while (1) {
+		update(0)
+		update(1)
+		update(2)
+		update(3)
+		__R30 = Rtmp;
+	}
+}
diff --git a/pru-cookbook/05blocks/code/pwm7-test.c b/pru-cookbook/05blocks/code/pwm7-test.c
new file mode 100644
index 0000000000000000000000000000000000000000..cbb6769819050b95dec2fd402db0f69a4beaa752
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm7-test.c
@@ -0,0 +1,83 @@
+/* 
+ *
+ *  pwm tester
+ *  (c) Copyright 2016
+ *  Mark A. Yoder, 20-July-2016
+ *	The channels 0-11 are on PRU1 and channels 12-17 are on PRU0
+ *	The period and duty cycle values are stored in each PRU's Data memory
+ *	The enable bits are stored in the shared memory
+ *
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#define MAXCH 2
+
+#define PRU_ADDR		0x4A300000		// Start of PRU memory Page 184 am335x TRM
+#define PRU_LEN			0x80000			// Length of PRU memory
+#define PRU0_DRAM		0x00000			// Offset to DRAM
+#define PRU1_DRAM		0x02000
+#define PRU_SHAREDMEM	0x10000			// Offset to shared memory
+
+unsigned int	*pru0DRAM_32int_ptr;		// Points to the start of local DRAM
+unsigned int	*pru1DRAM_32int_ptr;		// Points to the start of local DRAM
+unsigned int	*prusharedMem_32int_ptr;	// Points to the start of the shared memory
+
+/*******************************************************************************
+* int start_pwm_count(int ch, int countOn, int countOff)
+* 
+* Starts a pwm pulse on for countOn and off for countOff to a single channel (ch)
+*******************************************************************************/
+int start_pwm_count(int ch, int countOn, int countOff, unsigned int *ptr) {
+	unsigned int *pruDRAM_32int_ptr = ptr;
+	
+	printf("countOn: %d, countOff: %d, count: %d\n", 
+		countOn, countOff, countOn+countOff);
+	// write to PRU shared memory
+	pruDRAM_32int_ptr[2*(ch)+0] = countOn;	// On time
+	pruDRAM_32int_ptr[2*(ch)+1] = countOff;	// Off time
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	unsigned int	*pru;		// Points to start of PRU memory.
+	int	fd;
+	printf("Servo tester\n");
+	
+	fd = open ("/dev/mem", O_RDWR | O_SYNC);
+	if (fd == -1) {
+		printf ("ERROR: could not open /dev/mem.\n\n");
+		return 1;
+	}
+	pru = mmap (0, PRU_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, PRU_ADDR);
+	if (pru == MAP_FAILED) {
+		printf ("ERROR: could not map memory.\n\n");
+		return 1;
+	}
+	close(fd);
+	printf ("Using /dev/mem.\n");
+	
+	pru0DRAM_32int_ptr =     pru + PRU0_DRAM/4 + 0x200/4;	// Points to 0x200 of PRU0 memory
+	pru1DRAM_32int_ptr =     pru + PRU1_DRAM/4 + 0x200/4;	// Points to 0x200 of PRU1 memory
+	prusharedMem_32int_ptr = pru + PRU_SHAREDMEM/4;	// Points to start of shared memory
+
+
+	int on[]  = {1, 2, 3, 4};
+	int off[] = {4, 3, 2, 1};
+
+	int ch;
+	for(ch=0; ch<MAXCH; ch++) {
+		start_pwm_count(ch, on[ch],       off[ch],       pru0DRAM_32int_ptr);
+		start_pwm_count(ch, on[ch+MAXCH], off[ch+MAXCH], pru1DRAM_32int_ptr);
+	}
+	
+	if(munmap(pru, PRU_LEN)) {
+		printf("munmap failed\n");
+	} else {
+		printf("munmap succeeded\n");
+	}
+}
+
diff --git a/pru-cookbook/05blocks/code/pwm7.pru0.c b/pru-cookbook/05blocks/code/pwm7.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..b95c5caab89d3614e9dfa964d38c162921f67a4b
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm7.pru0.c
@@ -0,0 +1,57 @@
+// This code does MAXCH parallel PWM channels on both PRU 0 and PRU 1
+// All channels start at the same time. But the PRU 1 ch have a difference period
+// It's period is 370ns
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+
+#define PRUNUM 0
+
+#define PRU0_DRAM		0x00000			// Offset to DRAM
+// Skip the first 0x200 byte of DRAM since the Makefile allocates
+// 0x100 for the STACK and 0x100 for the HEAP.
+volatile unsigned int *pru0_dram = (unsigned int *) (PRU0_DRAM + 0x200);
+
+#define MAXCH	2	// Maximum number of channels per PRU
+
+#define update(ch) \
+			if(onCount[ch]) {			\
+				onCount[ch]--;			\
+				Rtmp |= 0x1<<ch;		\
+			} else if(offCount[ch]) {	\
+				offCount[ch]--;			\
+				Rtmp &= ~(0x1<<ch);	\
+			} else {					\
+				onCount[ch] = pru0_dram[2*ch];	\
+				offCount[ch]= pru0_dram[2*ch+1];	\
+			}
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t ch;
+	uint32_t on[]  = {1, 2, 3, 4};
+	uint32_t off[] = {4, 3, 2, 1};
+	uint32_t onCount[MAXCH], offCount[MAXCH];
+	register uint32_t Rtmp;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+#pragma UNROLL(MAXCH)
+	for(ch=0; ch<MAXCH; ch++) {
+		pru0_dram[2*ch  ] = on [ch+PRUNUM*MAXCH];	// Copy to DRAM0 so the ARM can change it
+		pru0_dram[2*ch+1] = off[ch+PRUNUM*MAXCH];	// Interleave the on and off values
+		onCount[ch] = on [ch+PRUNUM*MAXCH];
+		offCount[ch]= off[ch+PRUNUM*MAXCH];
+	}
+	Rtmp = __R30;
+
+	while (1) {
+		update(0)
+		update(1)
+		__R30 = Rtmp;
+	}
+}
diff --git a/pru-cookbook/05blocks/code/pwm7.pru1.c b/pru-cookbook/05blocks/code/pwm7.pru1.c
new file mode 100644
index 0000000000000000000000000000000000000000..50d4788b8c4d07848a0f0ff651fc78a7545ff67f
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm7.pru1.c
@@ -0,0 +1,57 @@
+// This code does MAXCH parallel PWM channels on both PRU 0 and PRU 1
+// All channels start at the same time. But the PRU 1 ch have a difference period
+// It's period is 370ns
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+
+#define PRUNUM 1
+
+#define PRU0_DRAM		0x00000			// Offset to DRAM
+// Skip the first 0x200 byte of DRAM since the Makefile allocates
+// 0x100 for the STACK and 0x100 for the HEAP.
+volatile unsigned int *pru0_dram = (unsigned int *) (PRU0_DRAM + 0x200);
+
+#define MAXCH	2	// Maximum number of channels per PRU
+
+#define update(ch) \
+			if(onCount[ch]) {			\
+				onCount[ch]--;			\
+				Rtmp |= 0x1<<ch;		\
+			} else if(offCount[ch]) {	\
+				offCount[ch]--;			\
+				Rtmp &= ~(0x1<<ch);	\
+			} else {					\
+				onCount[ch] = pru0_dram[2*ch];	\
+				offCount[ch]= pru0_dram[2*ch+1];	\
+			}
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t ch;
+	uint32_t on[]  = {1, 2, 3, 4};
+	uint32_t off[] = {4, 3, 2, 1};
+	uint32_t onCount[MAXCH], offCount[MAXCH];
+	register uint32_t Rtmp;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+#pragma UNROLL(MAXCH)
+	for(ch=0; ch<MAXCH; ch++) {
+		pru0_dram[2*ch  ] = on [ch+PRUNUM*MAXCH];	// Copy to DRAM0 so the ARM can change it
+		pru0_dram[2*ch+1] = off[ch+PRUNUM*MAXCH];	// Interleave the on and off values
+		onCount[ch] = on [ch+PRUNUM*MAXCH];
+		offCount[ch]= off[ch+PRUNUM*MAXCH];
+	}
+	Rtmp = __R30;
+
+	while (1) {
+		update(0)
+		update(1)
+		__R30 = Rtmp;
+	}
+}
diff --git a/pru-cookbook/05blocks/code/pwm7_setup.sh b/pru-cookbook/05blocks/code/pwm7_setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..aae4c778542c5209a799411b393b2d5b2130e76e
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm7_setup.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+export TARGET=pwm7.pru0
+echo TARGET=$TARGET
+
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P9_31 P9_29 P8_45 P8_46"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P1_36 P1_33"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin pruout
+    config-pin -q $pin
+done
diff --git a/pru-cookbook/05blocks/code/pwm8.pru0.c b/pru-cookbook/05blocks/code/pwm8.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..c566573f6f681f7642e61d5c159c8558d3895d33
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm8.pru0.c
@@ -0,0 +1,78 @@
+// This code does MAXCH parallel PWM channels on both PRU 0 and PRU 1
+// All channels start at the same time. 
+// It's period is 430ns
+#include <stdint.h>
+#include <pru_cfg.h>
+#include <pru_intc.h>
+#include <pru_ctrl.h>
+#include "resource_table_empty.h"
+
+#define PRUNUM 0
+
+#define PRU0_DRAM		0x00000			// Offset to DRAM
+// Skip the first 0x200 byte of DRAM since the Makefile allocates
+// 0x100 for the STACK and 0x100 for the HEAP.
+volatile unsigned int *pru0_dram = (unsigned int *) (PRU0_DRAM + 0x200);
+
+#define MAXCH	2	// Maximum number of channels per PRU
+
+#define update(ch) \
+			if(onCount[ch]) {			\
+				onCount[ch]--;			\
+				Rtmp |= 0x1<<ch;		\
+			} else if(offCount[ch]) {	\
+				offCount[ch]--;			\
+				Rtmp &= ~(0x1<<ch);	\
+			} else {					\
+				onCount[ch] = pru0_dram[2*ch];	\
+				offCount[ch]= pru0_dram[2*ch+1];	\
+			}
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+// Initialize interupts so the PRUs can be syncronized.
+// PRU1 is started first and then waits for PRU0
+// PRU0 is then started and tells PRU1 when to start going
+void configIntc(void) {	
+	__R31 = 0x00000000;					// Clear any pending PRU-generated events
+	CT_INTC.CMR4_bit.CH_MAP_16 = 1;		// Map event 16 to channel 1
+	CT_INTC.HMR0_bit.HINT_MAP_1 = 1;	// Map channel 1 to host 1
+	CT_INTC.SICR = 16;					// Ensure event 16 is cleared
+	CT_INTC.EISR = 16;					// Enable event 16
+	CT_INTC.HIEISR |= (1 << 0);			// Enable Host interrupt 1
+	CT_INTC.GER = 1; 					// Globally enable host interrupts
+}
+
+void main(void)
+{
+	uint32_t ch;
+	uint32_t on[]  = {1, 2, 3, 4};
+	uint32_t off[] = {4, 3, 2, 1};
+	uint32_t onCount[MAXCH], offCount[MAXCH];
+	register uint32_t Rtmp;
+
+	CT_CFG.GPCFG0 = 0x0000;				// Configure GPI and GPO as Mode 0 (Direct Connect)
+	configIntc();						// Configure INTC
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+#pragma UNROLL(MAXCH)
+	for(ch=0; ch<MAXCH; ch++) {
+		pru0_dram[2*ch  ] = on [ch+PRUNUM*MAXCH];	// Copy to DRAM0 so the ARM can change it
+		pru0_dram[2*ch+1] = off[ch+PRUNUM*MAXCH];	// Interleave the on and off values
+		onCount[ch] = on [ch+PRUNUM*MAXCH];
+		offCount[ch]= off[ch+PRUNUM*MAXCH];
+	}
+	Rtmp = __R30;
+
+	while (1) {
+		__R30 = Rtmp;
+		update(0)
+		update(1)
+#define PRU0_PRU1_EVT 16
+		__R31 = (PRU0_PRU1_EVT-16) | (0x1<<5);	//Tell PRU 1 to start
+		__delay_cycles(1);
+	}
+}
diff --git a/pru-cookbook/05blocks/code/pwm8.pru1.c b/pru-cookbook/05blocks/code/pwm8.pru1.c
new file mode 100644
index 0000000000000000000000000000000000000000..cf5c241c99addc0d8b958724554e078f9a53412c
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm8.pru1.c
@@ -0,0 +1,66 @@
+// This code does MAXCH parallel PWM channels on both PRU 0 and PRU 1
+// All channels start at the same time. 
+// It's period is 430ns
+#include <stdint.h>
+#include <pru_cfg.h>
+#include <pru_intc.h>
+#include <pru_ctrl.h>
+#include "resource_table_empty.h"
+
+#define PRUNUM 1
+
+#define PRU0_DRAM		0x00000			// Offset to DRAM
+// Skip the first 0x200 byte of DRAM since the Makefile allocates
+// 0x100 for the STACK and 0x100 for the HEAP.
+volatile unsigned int *pru0_dram = (unsigned int *) (PRU0_DRAM + 0x200);
+
+#define MAXCH	2	// Maximum number of channels per PRU
+
+#define update(ch) \
+			if(onCount[ch]) {			\
+				onCount[ch]--;			\
+				Rtmp |= 0x1<<ch;		\
+			} else if(offCount[ch]) {	\
+				offCount[ch]--;			\
+				Rtmp &= ~(0x1<<ch);	\
+			} else {					\
+				onCount[ch] = pru0_dram[2*ch];	\
+				offCount[ch]= pru0_dram[2*ch+1];	\
+			}
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+// Initialize interupts so the PRUs can be syncronized.
+// PRU1 is started first and then waits for PRU0
+// PRU0 is then started and tells PRU1 when to start going
+
+void main(void)
+{
+	uint32_t ch;
+	uint32_t on[]  = {1, 2, 3, 4};
+	uint32_t off[] = {4, 3, 2, 1};
+	uint32_t onCount[MAXCH], offCount[MAXCH];
+	register uint32_t Rtmp;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+#pragma UNROLL(MAXCH)
+	for(ch=0; ch<MAXCH; ch++) {
+		pru0_dram[2*ch  ] = on [ch+PRUNUM*MAXCH];	// Copy to DRAM0 so the ARM can change it
+		pru0_dram[2*ch+1] = off[ch+PRUNUM*MAXCH];	// Interleave the on and off values
+		onCount[ch] = on [ch+PRUNUM*MAXCH];
+		offCount[ch]= off[ch+PRUNUM*MAXCH];
+	}
+	Rtmp = __R30;
+
+	while (1) {
+		while((__R31 & (0x1<<31))==0) {		// Wait for PRU 0
+		}
+		CT_INTC.SICR = 16;					// Clear event 16
+		__R30 = Rtmp;
+		update(0)
+		update(1)
+	}
+}
diff --git a/pru-cookbook/05blocks/code/pwm_setup.sh b/pru-cookbook/05blocks/code/pwm_setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b69ed1297ab4a73d309a7f46253c3b9b5f97add1
--- /dev/null
+++ b/pru-cookbook/05blocks/code/pwm_setup.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+export TARGET=pwm1.pru0
+echo TARGET=$TARGET
+
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P9_31 P9_29 P9_30 P9_28"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P1_36 P1_33 P2_32 P2_30"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin pruout
+    config-pin -q $pin
+done
diff --git a/pru-cookbook/05blocks/code/resource_table_empty.h b/pru-cookbook/05blocks/code/resource_table_empty.h
new file mode 100644
index 0000000000000000000000000000000000000000..07e97d9b383c9d937d4b55e705024d6c28dc748a
--- /dev/null
+++ b/pru-cookbook/05blocks/code/resource_table_empty.h
@@ -0,0 +1,39 @@
+/*
+ *  ======== resource_table_empty.h ========
+ *
+ *  Define the resource table entries for all PRU cores. This will be
+ *  incorporated into corresponding base images, and used by the remoteproc
+ *  on the host-side to allocated/reserve resources.  Note the remoteproc
+ *  driver requires that all PRU firmware be built with a resource table.
+ *
+ *  This file contains an empty resource table.  It can be used either as:
+ *
+ *        1) A template, or
+ *        2) As-is if a PRU application does not need to configure PRU_INTC
+ *                  or interact with the rpmsg driver
+ *
+ */
+
+#ifndef _RSC_TABLE_PRU_H_
+#define _RSC_TABLE_PRU_H_
+
+#include <stddef.h>
+#include <rsc_types.h>
+
+struct my_resource_table {
+	struct resource_table base;
+
+	uint32_t offset[1]; /* Should match 'num' in actual definition */
+};
+
+#pragma DATA_SECTION(pru_remoteproc_ResourceTable, ".resource_table")
+#pragma RETAIN(pru_remoteproc_ResourceTable)
+struct my_resource_table pru_remoteproc_ResourceTable = {
+	1,	/* we're the first version that implements this */
+	0,	/* number of entries in the table */
+	0, 0,	/* reserved, must be zero */
+	0,	/* offset[0] */
+};
+
+#endif /* _RSC_TABLE_PRU_H_ */
+
diff --git a/pru-cookbook/05blocks/code/rgb1.pru0.c b/pru-cookbook/05blocks/code/rgb1.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..9936d627336863daf9c4c1d5e92f70afd602b3a9
--- /dev/null
+++ b/pru-cookbook/05blocks/code/rgb1.pru0.c
@@ -0,0 +1,80 @@
+// This code drives the RGB LED Matrix on the 1st Connector
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+#include "rgb_pocket.h"
+
+#define DELAY 10	// Number of cycles (5ns each) to wait after a write
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	// Set up the pointers to each of the GPIO ports 
+	uint32_t *gpio[] = {
+			(uint32_t *) GPIO0, 
+			(uint32_t *) GPIO1, 
+			(uint32_t *) GPIO2, 
+			(uint32_t *) GPIO3
+		};
+	
+	uint32_t i, row;
+
+	while(1) {
+	    for(row=0; row<16; row++) {
+	    	// Set the row address
+			// Here we take advantage of the select bits (LA,LB,LC,LD)
+			// being sequential in the R30 register (bits 2,3,4,5)
+			// We shift row over so it lines up with the select bits
+			// Oring (|=) with R30 sets bits to 1 and
+			// Anding (&=) clears bits to 0, the 0xffc mask makes sure the
+			// other bits aren't changed.
+	        __R30 |=  row<<pru_sel0;
+	        __R30 &= (row<<pru_sel0)|0xffc3;
+
+    	    for(i=0; i<64; i++) {
+    	    	// Top row white
+    	    	// Combining these to one write works because they are all in 
+    	    	// the same gpio port
+    	      	gpio[r11_gpio][GPIO_SETDATAOUT] = r11_pin | g11_pin | b11_pin;
+    	    	__delay_cycles(DELAY);;
+    	      	
+    	      	// Bottom row red
+    	      	gpio[r12_gpio][GPIO_SETDATAOUT]   = r12_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[r12_gpio][GPIO_CLEARDATAOUT] = g12_pin | b12_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+                __R30 |=  pru_clock;	// Toggle clock
+    	    	__delay_cycles(DELAY);
+        		__R30 &= ~pru_clock;
+    	    	__delay_cycles(DELAY);
+    	    	
+    	    	// Top row black
+    	    	gpio[r11_gpio][GPIO_CLEARDATAOUT] = r11_pin | g11_pin | b11_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+    	      	// Bottom row green
+    	    	gpio[r12_gpio][GPIO_CLEARDATAOUT] = r12_pin | b12_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[r12_gpio][GPIO_SETDATAOUT]   = g12_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+                __R30 |=  pru_clock;	// Toggle clock
+    	    	__delay_cycles(DELAY);
+        		__R30 &= ~pru_clock;
+    	    	__delay_cycles(DELAY);
+    	    }
+    	    __R30 |=  pru_oe;        // Disable display
+    	   	__delay_cycles(DELAY);
+    	    __R30 |=  pru_latch;     // Toggle latch
+    	   	__delay_cycles(DELAY);
+    	    __R30 &= ~pru_latch;
+    	   	__delay_cycles(DELAY);
+    	    __R30 &= ~pru_oe;        // Enable display
+    	    __delay_cycles(DELAY);
+	    }
+	}
+}
diff --git a/pru-cookbook/05blocks/code/rgb2.pru0.c b/pru-cookbook/05blocks/code/rgb2.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..eb43b357bb3cdb92f6853a0d46600b1e53a7b6ac
--- /dev/null
+++ b/pru-cookbook/05blocks/code/rgb2.pru0.c
@@ -0,0 +1,81 @@
+// This code drives the RGB LED Matrix on J1 connector
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+#include "rgb_pocket.h"
+
+#define DELAY 100
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	// Set up the pointers to each of the GPIO ports 
+	uint32_t *gpio[] = {
+			(uint32_t *) GPIO0, 
+			(uint32_t *) GPIO1, 
+			(uint32_t *) GPIO2, 
+			(uint32_t *) GPIO3
+		};
+	
+	uint32_t i, row;
+	
+	while(1) {
+	    for(row=0; row<16; row++) {
+	        if(row&(0x1<<0)) __R30|=(0x1<<pru_sel0); else __R30&=~(0x1<<pru_sel0);
+	        __delay_cycles(DELAY);
+	        if(row&(0x1<<1)) __R30|=(0x1<<pru_sel1); else __R30&=~(0x1<<pru_sel1);
+	        __delay_cycles(DELAY);
+	        if(row&(0x1<<2)) __R30|=(0x1<<pru_sel2); else __R30&=~(0x1<<pru_sel2);
+	        __delay_cycles(DELAY);
+	        if(row&(0x1<<3)) __R30|=(0x1<<pru_sel3); else __R30&=~(0x1<<pru_sel3);
+	        __delay_cycles(DELAY);
+	        
+    	    for(i=0; i<64; i++) {
+    	    	// red
+    	      	gpio[r11_gpio][GPIO_SETDATAOUT]   = r11_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[r11_gpio][GPIO_CLEARDATAOUT] = g11_pin | b11_pin;
+    	    	__delay_cycles(DELAY);
+
+				// green
+    	      	gpio[r11_gpio][GPIO_CLEARDATAOUT] = r12_pin |  b12_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[r11_gpio][GPIO_SETDATAOUT]   = g12_pin;
+    	    	__delay_cycles(DELAY);
+
+                __R30 |=  pru_clock;     // Toggle clock
+    	    	__delay_cycles(DELAY);
+        		__R30 &= ~pru_clock;
+    	    	__delay_cycles(DELAY);
+    	    	
+    	    	// blue
+    	    	gpio[r11_gpio][GPIO_CLEARDATAOUT] = r11_pin | g11_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[r11_gpio][GPIO_SETDATAOUT]   = b11_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+    	      	//blue
+    	    	gpio[r11_gpio][GPIO_CLEARDATAOUT] = r12_pin | g12_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[r11_gpio][GPIO_SETDATAOUT]   = b12_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+                __R30 |=  pru_clock;      // Toggle clock
+    	    	__delay_cycles(DELAY);
+        		__R30 &= ~pru_clock;
+    	    	__delay_cycles(DELAY);
+    	    }
+    	    __R30 |=  pru_oe;        // Disable display
+    	    	__delay_cycles(DELAY);
+    	    __R30 |=  pru_latch;     // Toggle latch
+    	    	__delay_cycles(DELAY);
+    	    __R30 &= ~pru_latch;
+    	    	__delay_cycles(DELAY);
+    	    __R30 &= ~pru_oe;        // Enable display
+    	    __delay_cycles(DELAY);
+	    }
+	}
+}
diff --git a/pru-cookbook/05blocks/code/rgb3.pru0.c b/pru-cookbook/05blocks/code/rgb3.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..b14ad864c4de0c621561f1cb031aae0af5367dd4
--- /dev/null
+++ b/pru-cookbook/05blocks/code/rgb3.pru0.c
@@ -0,0 +1,114 @@
+// This code drives the RGB LED Matrix on the 1st and 2nd Connectors
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+#include "rgb_pocket.h"
+
+#define DELAY 10	// Number of cycles (5ns each) to wait after a write
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	// Set up the pointers to each of the GPIO ports 
+	uint32_t *gpio[] = {
+			(uint32_t *) GPIO0, 
+			(uint32_t *) GPIO1, 
+			(uint32_t *) GPIO2, 
+			(uint32_t *) GPIO3
+		};
+	
+	uint32_t i, row;
+
+	while(1) {
+	    for(row=0; row<16; row++) {
+	    	// Set the row address
+			// Here we take advantage of the select bits (LA,LB,LC,LD)
+			// being sequential in the R30 register (bits 2,3,4,5)
+			// We shift row over so it lines up with the select bits
+			// Oring (|=) with R30 sets bits to 1 and
+			// Anding (&=) clears bits to 0, the 0xffc mask makes sure the
+			// other bits aren't changed.
+	        __R30 |=  row<<pru_sel0;
+	        __R30 &= (row<<pru_sel0)|0xffc3;
+
+    	    for(i=0; i<64; i++) {
+    	    	// Panel 1 Upper
+    	    	// Top row white
+    	    	// Combining these to one write works because they are all in 
+    	    	// the same gpio port
+    	      	gpio[r11_gpio][GPIO_SETDATAOUT] = r11_pin | g11_pin | b11_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+    	      	// Bottom row red
+    	      	gpio[r12_gpio][GPIO_SETDATAOUT]   = r12_pin;
+    	    	// __delay_cycles(DELAY);
+    	      	gpio[g12_gpio][GPIO_CLEARDATAOUT] = g12_pin | b12_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+    	    	// Panel 2 Upper
+    	    	// Top row blue
+    	    	// Combining these to one write works because they are all in 
+    	    	// the same gpio port except b12
+    	      	gpio[r21_gpio][GPIO_CLEARDATAOUT] = r21_pin | g21_pin;
+    	    	// __delay_cycles(DELAY);
+    	      	gpio[b21_gpio][GPIO_SETDATAOUT]   = b21_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+    	      	// Bottom row red
+    	      	gpio[r22_gpio][GPIO_SETDATAOUT]   = r22_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[g22_gpio][GPIO_CLEARDATAOUT] = g22_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[b22_gpio][GPIO_CLEARDATAOUT] = b22_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+                __R30 |=  pru_clock;	// Toggle clock
+    	    	__delay_cycles(DELAY);
+        		__R30 &= ~pru_clock;
+    	    	__delay_cycles(DELAY);
+
+				// Panel 1 Lower
+    	    	// Top row black
+    	    	gpio[r11_gpio][GPIO_CLEARDATAOUT] = r11_pin | g11_pin | b11_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+    	      	// Bottom row green
+    	    	gpio[r12_gpio][GPIO_CLEARDATAOUT] = r12_pin | b12_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[g12_gpio][GPIO_SETDATAOUT]   = g12_pin;
+    	    	__delay_cycles(DELAY);
+    	    	
+    	    	// Panel 2 Lower
+    	    	// Top row reg+green = yellow
+    	    	gpio[r21_gpio][GPIO_SETDATAOUT] = r21_pin | g21_pin;
+    	    	__delay_cycles(DELAY);
+    	    	gpio[b21_gpio][GPIO_CLEARDATAOUT] = b21_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+    	      	// Bottom row green
+    	    	gpio[r22_gpio][GPIO_CLEARDATAOUT] = r22_pin;
+    	    	__delay_cycles(DELAY);
+    	    	gpio[b22_gpio][GPIO_CLEARDATAOUT] = b22_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[g22_gpio][GPIO_SETDATAOUT] = g22_pin;
+    	    	__delay_cycles(2*DELAY);
+    	      	
+                __R30 |=  pru_clock;	// Toggle clock
+    	    	__delay_cycles(DELAY);
+        		__R30 &= ~pru_clock;
+    	    	__delay_cycles(DELAY);
+    	    }
+    	    __R30 |=  pru_oe;        // Disable display
+    	   	__delay_cycles(DELAY);
+    	    __R30 |=  pru_latch;     // Toggle latch
+    	   	__delay_cycles(DELAY);
+    	    __R30 &= ~pru_latch;
+    	   	__delay_cycles(DELAY);
+    	    __R30 &= ~pru_oe;        // Enable display
+    	    __delay_cycles(DELAY);
+	    }
+	}
+}
diff --git a/pru-cookbook/05blocks/code/rgb4.pru0.c b/pru-cookbook/05blocks/code/rgb4.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..6d06f1210e18bb3bbf74bf20b9c0b0c876c365e0
--- /dev/null
+++ b/pru-cookbook/05blocks/code/rgb4.pru0.c
@@ -0,0 +1,84 @@
+// This code drives the RGB LED Matrix on the 2nd Connector
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+#include "rgb_pocket.h"
+
+#define DELAY 10	// Number of cycles (5ns each) to wait after a write
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	// Set up the pointers to each of the GPIO ports 
+	uint32_t *gpio[] = {
+			(uint32_t *) GPIO0, 
+			(uint32_t *) GPIO1, 
+			(uint32_t *) GPIO2, 
+			(uint32_t *) GPIO3
+		};
+	
+	uint32_t i, row;
+
+	while(1) {
+	    for(row=0; row<16; row++) {
+	    	// Set the row address
+			// Here we take advantage of the select bits (LA,LB,LC,LD)
+			// being sequential in the R30 register (bits 2,3,4,5)
+			// We shift row over so it lines up with the select bits
+			// Oring (|=) with R30 sets bits to 1 and
+			// Anding (&=) clears bits to 0, the 0xffc mask makes sure the
+			// other bits aren't changed.
+	        __R30 |=  row<<pru_sel0;
+	        __R30 &= (row<<pru_sel0)|0xffc3;
+
+    	    for(i=0; i<64; i++) {
+    	    	// Top row white
+    	    	// Combining these to one write works because they are all in 
+    	    	// the same gpio port except b12
+    	      	gpio[r21_gpio][GPIO_SETDATAOUT] = r21_pin | g21_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[b21_gpio][GPIO_SETDATAOUT] =  b21_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+    	      	// Bottom row red
+    	      	gpio[r22_gpio][GPIO_SETDATAOUT]   = r22_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[g22_gpio][GPIO_CLEARDATAOUT] = g22_pin | b22_pin;
+    	    	__delay_cycles(2*DELAY);
+    	      	
+                __R30 |=  pru_clock;	// Toggle clock
+    	    	__delay_cycles(DELAY);
+        		__R30 &= ~pru_clock;
+    	    	__delay_cycles(DELAY);
+    	    	
+    	    	// Top row black
+    	    	gpio[r21_gpio][GPIO_CLEARDATAOUT] = r21_pin | g21_pin;
+    	    	__delay_cycles(DELAY);
+    	    	gpio[b21_gpio][GPIO_CLEARDATAOUT] = b21_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+    	      	// Bottom row green
+    	    	gpio[r22_gpio][GPIO_CLEARDATAOUT] = r22_pin | b22_pin;
+    	    	__delay_cycles(DELAY);
+    	      	gpio[g22_gpio][GPIO_SETDATAOUT]   = g22_pin;
+    	    	__delay_cycles(2*DELAY);
+    	      	
+                __R30 |=  pru_clock;	// Toggle clock
+    	    	__delay_cycles(DELAY);
+        		__R30 &= ~pru_clock;
+    	    	__delay_cycles(DELAY);
+    	    }
+    	    __R30 |=  pru_oe;        // Disable display
+    	   	__delay_cycles(DELAY);
+    	    __R30 |=  pru_latch;     // Toggle latch
+    	   	__delay_cycles(DELAY);
+    	    __R30 &= ~pru_latch;
+    	   	__delay_cycles(DELAY);
+    	    __R30 &= ~pru_oe;        // Enable display
+    	    __delay_cycles(DELAY);
+	    }
+	}
+}
diff --git a/pru-cookbook/05blocks/code/rgb_black.h b/pru-cookbook/05blocks/code/rgb_black.h
new file mode 100644
index 0000000000000000000000000000000000000000..be7cf4ba8ab0da67ee7ce7301fe49a90bfad539e
--- /dev/null
+++ b/pru-cookbook/05blocks/code/rgb_black.h
@@ -0,0 +1,31 @@
+//Black - Not tested
+// These are from https://github.com/FalconChristmas/fpp/blob/master/src/pru/PocketScrollerV1.hp
+// _gpio tells which gpio port and _pin tells which bit in the port
+// The first 1 in r11 is for the J1 connector
+// See the githuub file for the other connectors
+
+#define r11_gpio 2
+#define r11_pin 9
+#define g11_gpio 2
+#define g11_pin 11
+#define b11_gpio 2
+#define b11_pin 10
+
+#define r12_gpio 2
+#define r12_pin 12
+#define g12_gpio 2
+#define g12_pin 22
+#define b12_gpio 2
+#define b12_pin 23
+
+#define pru_latch 1	// These are the bit positions in R30
+#define pru_oe    0
+#define pru_clock 2
+
+// Control pins are all in GPIO2
+// The pocket has these on R0, the code needs to be changed for this work work
+#define gpio_sel0 13 /* must be sequential with sel1 and sel2 */
+#define gpio_sel1 14
+#define gpio_sel2 15
+#define gpio_sel3 16
+#define gpio_sel4 17
diff --git a/pru-cookbook/05blocks/code/rgb_pocket.h b/pru-cookbook/05blocks/code/rgb_pocket.h
new file mode 100644
index 0000000000000000000000000000000000000000..45a91118038898605939bc4493a3337cb4fd86a0
--- /dev/null
+++ b/pru-cookbook/05blocks/code/rgb_pocket.h
@@ -0,0 +1,45 @@
+// Pocket
+// These are from https://github.com/FalconChristmas/fpp/blob/master/src/pru/PocketScrollerV1.hp
+// _gpio tells which gpio port and _pin tells which bit in the port
+// The first 1 in r11 is for the J1 connector
+// See the githuub file for the other connectors
+
+// J1
+#define r11_gpio 1
+#define r11_pin (0x1<<20)
+#define g11_gpio 1
+#define g11_pin (0x1<<28)
+#define b11_gpio 1
+#define b11_pin (0x1<<25)
+
+#define r12_gpio 1
+#define r12_pin (0x1<<26)
+#define g12_gpio 1
+#define g12_pin (0x1<<27)
+#define b12_gpio 1
+#define b12_pin (0x1<<18)
+
+// J2
+#define r21_gpio 1
+#define r21_pin (0x1<<8)
+#define g21_gpio 1
+#define g21_pin (0x1<<9)
+#define b21_gpio 0
+#define b21_pin (0x1<<30)
+
+#define r22_gpio 1
+#define r22_pin (0x1<<12)
+#define g22_gpio 1
+#define g22_pin (0x1<<14)
+#define b22_gpio 1
+#define b22_pin (0x1<<15)
+
+// All connectors
+#define pru_latch  (0x1<<0)	// These are the bit positions in R30
+#define pru_oe     (0x1<<7)
+#define pru_clock  (0x1<<1)
+
+#define pru_sel0   2	// These are called LA, LB, LC and LD in the python code
+#define pru_sel1   3	// Also bit positions
+#define pru_sel2   4
+#define pru_sel3   5
diff --git a/pru-cookbook/05blocks/code/rgb_python.py b/pru-cookbook/05blocks/code/rgb_python.py
new file mode 100755
index 0000000000000000000000000000000000000000..25e353343f3c8f829a60376f4c3121e8ada1bbd1
--- /dev/null
+++ b/pru-cookbook/05blocks/code/rgb_python.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+import Adafruit_BBIO.GPIO as GPIO
+
+# Define which functions are connect to which pins
+OE="P1_29"      # Output Enable, active low
+LAT="P1_36"     # Latch, toggle after clocking in a row of pixels
+CLK="P1_33"     # Clock, toggle after each pixel
+
+# Input data pins 
+R1="P2_10"  # R1, G1, B1 are for the top rows (1-16) of pixels
+G1="P2_8"
+B1="P2_6"
+
+R2="P2_4"   # R2, G2, B2 are for the bottom rows (17-32) of pixels
+G2="P2_2"
+B2="P2_1"
+
+LA="P2_32"  # Address lines for which row (1-16 or 17-32) to update
+LB="P2_30"
+LC="P1_31"
+LD="P2_34"
+
+# Set everything as output ports
+GPIO.setup(OE,  GPIO.OUT)
+GPIO.setup(LAT, GPIO.OUT)
+GPIO.setup(CLK, GPIO.OUT)
+
+GPIO.setup(R1, GPIO.OUT)
+GPIO.setup(G1, GPIO.OUT)
+GPIO.setup(B1, GPIO.OUT)
+GPIO.setup(R2, GPIO.OUT)
+GPIO.setup(G2, GPIO.OUT)
+GPIO.setup(B2, GPIO.OUT)
+
+GPIO.setup(LA, GPIO.OUT)
+GPIO.setup(LB, GPIO.OUT)
+GPIO.setup(LC, GPIO.OUT)
+GPIO.setup(LD, GPIO.OUT)
+
+GPIO.output(OE,  0)     # Enable the display
+GPIO.output(LAT, 0)     # Set latch to low
+
+while True:
+    for bank in range(64):
+        GPIO.output(LA, bank>>0&0x1)    # Select rows
+        GPIO.output(LB, bank>>1&0x1)
+        GPIO.output(LC, bank>>2&0x1)
+        GPIO.output(LD, bank>>3&0x1)
+        
+        # Shift the colors out.  Here we only have four different 
+        # colors to keep things simple.
+        for i in range(16):
+            GPIO.output(R1,  1)     # Top row, white
+            GPIO.output(G1,  1)
+            GPIO.output(B1,  1)
+            
+            GPIO.output(R2,  1)     # Bottom row, red
+            GPIO.output(G2,  0)
+            GPIO.output(B2,  0)
+
+            GPIO.output(CLK, 0)     # Toggle clock
+            GPIO.output(CLK, 1)
+    
+            GPIO.output(R1,  0)     # Top row, black
+            GPIO.output(G1,  0)
+            GPIO.output(B1,  0)
+
+            GPIO.output(R2,  0)     # Bottom row, green
+            GPIO.output(G2,  1)
+            GPIO.output(B2,  0)
+    
+            GPIO.output(CLK, 0)     # Toggle clock
+            GPIO.output(CLK, 1)
+    
+        GPIO.output(OE,  1)     # Disable display while updating
+        GPIO.output(LAT, 1)     # Toggle latch
+        GPIO.output(LAT, 0)
+        GPIO.output(OE,  0)     # Enable display
diff --git a/pru-cookbook/05blocks/code/rgb_python_setup.sh b/pru-cookbook/05blocks/code/rgb_python_setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..721067461771c4d0426a0646f28f748e384ec22d
--- /dev/null
+++ b/pru-cookbook/05blocks/code/rgb_python_setup.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Setup for 64x32 RGB Matrix
+export TARGET=rgb1.pru0
+echo TARGET=$TARGET
+
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    prupins="P2_32 P1_31 P1_33 P1_29 P2_30 P2_34 P1_36"
+    gpiopins="P2_10 P2_06 P2_04 P2_01 P2_08 P2_02"
+    # Uncomment for J2
+    # gpiopins="$gpiopins P2_27 P2_25 P2_05 P2_24 P2_22 P2_18"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $prupins
+do
+    echo $pin
+    # config-pin $pin pruout
+    config-pin $pin gpio
+    config-pin $pin out
+    config-pin -q $pin
+done
+
+for pin in $gpiopins
+do
+    echo $pin
+    config-pin $pin gpio
+    config-pin $pin out
+    config-pin -q $pin
+done
diff --git a/pru-cookbook/05blocks/code/rgb_setup.sh b/pru-cookbook/05blocks/code/rgb_setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..fc5451444ad10b848f7ec42bb56f4b8f0ffd9195
--- /dev/null
+++ b/pru-cookbook/05blocks/code/rgb_setup.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Setup for 64x32 RGB Matrix
+export TARGET=rgb1.pru0
+echo TARGET=$TARGET
+
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    prupins="P2_32 P1_31 P1_33 P1_29 P2_30 P2_34 P1_36"
+    gpiopins="P2_10 P2_06 P2_04 P2_01 P2_08 P2_02"
+    # Uncomment for J2
+    # gpiopins="$gpiopins P2_27 P2_25 P2_05 P2_24 P2_22 P2_18"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $prupins
+do
+    echo $pin
+    config-pin $pin pruout
+    # config-pin $pin gpio
+    # config-pin $pin out
+    config-pin -q $pin
+done
+
+for pin in $gpiopins
+do
+    echo $pin
+    config-pin $pin gpio
+    config-pin $pin out
+    config-pin -q $pin
+done
diff --git a/pru-cookbook/05blocks/code/rgb_white.pru0.c b/pru-cookbook/05blocks/code/rgb_white.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..e62d98e000c746e37a11c7a0402b13fb5f92b2df
--- /dev/null
+++ b/pru-cookbook/05blocks/code/rgb_white.pru0.c
@@ -0,0 +1,64 @@
+// This code drives the RGB LED Matrix
+// Turns all the LEDs on
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+#include "rgb_pocket.h"
+
+#define DELAY 10					// Number of cycles (5ns each) to wait after a write
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	// Set up the pointers to each of the GPIO ports 
+	uint32_t *gpio[] = {
+			(uint32_t *) GPIO0, 
+			(uint32_t *) GPIO1, 
+			(uint32_t *) GPIO2, 
+			(uint32_t *) GPIO3
+		};
+	
+	uint32_t i, row;
+
+	while(1) {
+	    for(row=0; row<16; row++) {
+	    	// Set the row address
+			// Here we take advantage of the select bits (LA,LB,LC,LD)
+			// being sequential in the R30 register (bits 2,3,4,5)
+			// We shift row over so it lines up with the select bits
+			// Oring (|=) with R30 sets bits to 1 and
+			// Anding (&=) clears bits to 0, the 0xffc mask makes sure the
+			// other bits aren't changed.
+	        __R30 |=  row<<pru_sel0;
+	        __R30 &= (row<<pru_sel0)|0xffc3;
+
+    	    for(i=0; i<64; i++) {
+    	    	// Top row white
+    	    	// Combining these to one write works because they are all in 
+    	    	// the same gpio port
+    	      	gpio[r11_gpio][GPIO_SETDATAOUT] = r11_pin | g11_pin | b11_pin;
+    	    	__delay_cycles(DELAY);;
+    	      	
+    	      	// Bottom row white
+    	      	gpio[r12_gpio][GPIO_SETDATAOUT] = r12_pin | g12_pin | b12_pin;
+    	    	__delay_cycles(DELAY);
+    	      	
+                __R30 |=  pru_clock;	// Toggle clock
+    	    	__delay_cycles(DELAY);
+        		__R30 &= ~pru_clock;
+    	    	__delay_cycles(DELAY);
+    	    }
+    	    __R30 |=  pru_oe;        // Disable display
+    	   	__delay_cycles(DELAY);
+    	    __R30 |=  pru_latch;     // Toggle latch
+    	   	__delay_cycles(DELAY);
+    	    __R30 &= ~pru_latch;
+    	   	__delay_cycles(DELAY);
+    	    __R30 &= ~pru_oe;        // Enable display
+    	    __delay_cycles(DELAY);
+	    }
+	}
+}
diff --git a/pru-cookbook/05blocks/code/shared.pru0.c b/pru-cookbook/05blocks/code/shared.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..95d87c5de147334e439c18bc6cadc68f6ebac98d
--- /dev/null
+++ b/pru-cookbook/05blocks/code/shared.pru0.c
@@ -0,0 +1,63 @@
+// From: http://git.ti.com/pru-software-support-package/pru-software-support-package/blobs/master/examples/am335x/PRU_access_const_table/PRU_access_const_table.c
+#include <stdint.h>
+#include <pru_cfg.h>
+#include <pru_ctrl.h>
+#include "resource_table_empty.h"
+
+#define PRU_SRAM  __far __attribute__((cregister("PRU_SHAREDMEM", near)))
+#define PRU_DMEM0 __far __attribute__((cregister("PRU_DMEM_0_1",  near)))
+#define PRU_DMEM1 __far __attribute__((cregister("PRU_DMEM_1_0",  near)))
+
+/* NOTE:  Allocating shared_x to PRU Shared Memory means that other PRU cores on
+ *        the same subsystem must take care not to allocate data to that memory.
+ *		  Users also cannot rely on where in shared memory these variables are placed
+ *        so accessing them from another PRU core or from the ARM is an undefined behavior.
+ */
+volatile uint32_t shared_0;
+PRU_SRAM  volatile uint32_t shared_1;
+PRU_DMEM0 volatile uint32_t shared_2;
+PRU_DMEM1 volatile uint32_t shared_3;
+#pragma DATA_SECTION(shared_4, ".bss")
+volatile uint32_t shared_4;
+
+/* NOTE:  Here we pick where in memory to store shared_5.  The stack and
+ *		  heap take up the first 0x200 words, so we must start after that.
+ *		  Since we are hardcoding where things are stored we can share
+ *		  this between the PRUs and the ARM.
+*/
+#define PRU0_DRAM		0x00000			// Offset to DRAM
+// Skip the first 0x200 bytes of DRAM since the Makefile allocates
+// 0x100 for the STACK and 0x100 for the HEAP.
+volatile unsigned int *shared_5 = (unsigned int *) (PRU0_DRAM + 0x200);
+
+
+int main(void)
+{
+	volatile uint32_t shared_6;
+	volatile uint32_t shared_7;
+	/*****************************************************************/
+	/* Access PRU peripherals using Constant Table & PRU header file */
+	/*****************************************************************/
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	/*****************************************************************/
+	/* Access PRU Shared RAM using Constant Table                    */
+	/*****************************************************************/
+
+	/* C28 defaults to 0x00000000, we need to set bits 23:8 to 0x0100 in order to have it point to 0x00010000	 */
+	PRU0_CTRL.CTPPR0_bit.C28_BLK_POINTER = 0x0100;
+
+	shared_0 =  0xfeef;
+	shared_1 = 0xdeadbeef;
+	shared_2 = shared_2 + 0xfeed;
+	shared_3 = 0xdeed;
+	shared_4 = 0xbeed;
+	shared_5[0] = 0x1234;
+	shared_6 = 0x4321;
+	shared_7 = 0x9876;
+
+	/* Halt PRU core */
+	__halt();
+}
diff --git a/pru-cookbook/05blocks/code/shared_setup.sh b/pru-cookbook/05blocks/code/shared_setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..eefbcd553ac53d0fb0c289fefc536c5f5eb0a7f7
--- /dev/null
+++ b/pru-cookbook/05blocks/code/shared_setup.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+export TARGET=shared.pru0
+echo TARGET=$TARGET
+
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P9_31 P9_29 P9_30 P9_28"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P1_36 P1_33 P2_32 P2_30"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin pruout
+    config-pin -q $pin
+done
diff --git a/pru-cookbook/05blocks/code/sine.map b/pru-cookbook/05blocks/code/sine.map
new file mode 100644
index 0000000000000000000000000000000000000000..45872d39e001a44e2a2b38b1ed1bf38c85b8837d
--- /dev/null
+++ b/pru-cookbook/05blocks/code/sine.map
@@ -0,0 +1,338 @@
+******************************************************************************
+PRU Linker Unix v2.1.5                    
+******************************************************************************
+>> Linked Fri Jun 29 13:58:08 2018
+
+OUTPUT FILE NAME:   </tmp/pru0-gen/sine1.out>
+ENTRY POINT SYMBOL: "_c_int00_noinit_noargs_noexit"  address: 00000000
+
+
+MEMORY CONFIGURATION
+
+         name            origin    length      used     unused   attr    fill
+----------------------  --------  ---------  --------  --------  ----  --------
+PAGE 0:
+  PRU_IMEM              00000000   00002000  000018c0  00000740  RWIX
+
+PAGE 1:
+  PRU_DMEM_0_1          00000000   00002000  00000154  00001eac  RWIX
+  PRU_DMEM_1_0          00002000   00002000  00000000  00002000  RWIX
+
+PAGE 2:
+  PRU_SHAREDMEM         00010000   00003000  00000000  00003000  RWIX
+  PRU_INTC              00020000   00001504  00000000  00001504  RWIX
+  PRU_CFG               00026000   00000044  00000044  00000000  RWIX
+  PRU_UART              00028000   00000038  00000000  00000038  RWIX
+  PRU_IEP               0002e000   0000031c  00000000  0000031c  RWIX
+  PRU_ECAP              00030000   00000060  00000000  00000060  RWIX
+  RSVD27                00032000   00000100  00000000  00000100  RWIX
+  RSVD21                00032400   00000100  00000000  00000100  RWIX
+  L3OCMC                40000000   00010000  00000000  00010000  RWIX
+  MCASP0_DMA            46000000   00000100  00000000  00000100  RWIX
+  UART1                 48022000   00000088  00000000  00000088  RWIX
+  UART2                 48024000   00000088  00000000  00000088  RWIX
+  I2C1                  4802a000   000000d8  00000000  000000d8  RWIX
+  MCSPI0                48030000   000001a4  00000000  000001a4  RWIX
+  DMTIMER2              48040000   0000005c  00000000  0000005c  RWIX
+  MMCHS0                48060000   00000300  00000000  00000300  RWIX
+  MBX0                  480c8000   00000140  00000000  00000140  RWIX
+  SPINLOCK              480ca000   00000880  00000000  00000880  RWIX
+  I2C2                  4819c000   000000d8  00000000  000000d8  RWIX
+  MCSPI1                481a0000   000001a4  00000000  000001a4  RWIX
+  DCAN0                 481cc000   000001e8  00000000  000001e8  RWIX
+  DCAN1                 481d0000   000001e8  00000000  000001e8  RWIX
+  PWMSS0                48300000   000002c4  00000000  000002c4  RWIX
+  PWMSS1                48302000   000002c4  00000000  000002c4  RWIX
+  PWMSS2                48304000   000002c4  00000000  000002c4  RWIX
+  RSVD13                48310000   00000100  00000000  00000100  RWIX
+  RSVD10                48318000   00000100  00000000  00000100  RWIX
+  TPCC                  49000000   00001098  00000000  00001098  RWIX
+  GEMAC                 4a100000   0000128c  00000000  0000128c  RWIX
+  DDR                   80000000   00000100  00000000  00000100  RWIX
+
+
+SECTION ALLOCATION MAP
+
+ output                                  attributes/
+section   page    origin      length       input sections
+--------  ----  ----------  ----------   ----------------
+.text:_c_int00* 
+*          0    00000000    00000014     
+                  00000000    00000014     rtspruv3_le.lib : boot_special.obj (.text:_c_int00_noinit_noargs_noexit)
+
+.text      0    00000014    000018ac     
+                  00000014    00000374     rtspruv3_le.lib : sin.obj (.text:sin)
+                  00000388    00000314                     : frcmpyd.obj (.text:__TI_frcmpyd)
+                  0000069c    00000258                     : frcaddd.obj (.text:__TI_frcaddd)
+                  000008f4    00000254                     : mpyd.obj (.text:__pruabi_mpyd)
+                  00000b48    00000248                     : addd.obj (.text:__pruabi_addd)
+                  00000d90    000001c8                     : mpyf.obj (.text:__pruabi_mpyf)
+                  00000f58    00000100                     : modf.obj (.text:modf)
+                  00001058    000000b4                     : gtd.obj (.text:__pruabi_gtd)
+                  0000110c    000000b0                     : ged.obj (.text:__pruabi_ged)
+                  000011bc    000000b0                     : ltd.obj (.text:__pruabi_ltd)
+                  0000126c    000000b0     sine1.obj (.text:main)
+                  0000131c    000000a8     rtspruv3_le.lib : frcmpyf.obj (.text:__TI_frcmpyf)
+                  000013c4    000000a0                     : fixdu.obj (.text:__pruabi_fixdu)
+                  00001464    0000009c                     : round.obj (.text:__pruabi_nround)
+                  00001500    00000090                     : eqld.obj (.text:__pruabi_eqd)
+                  00001590    0000008c                     : renormd.obj (.text:__TI_renormd)
+                  0000161c    0000008c                     : fixdi.obj (.text:__pruabi_fixdi)
+                  000016a8    00000084                     : fltid.obj (.text:__pruabi_fltid)
+                  0000172c    00000078                     : cvtfd.obj (.text:__pruabi_cvtfd)
+                  000017a4    00000050                     : fltuf.obj (.text:__pruabi_fltuf)
+                  000017f4    0000002c                     : asri.obj (.text:__pruabi_asri)
+                  00001820    0000002c                     : subd.obj (.text:__pruabi_subd)
+                  0000184c    00000024                     : mpyi.obj (.text:__pruabi_mpyi)
+                  00001870    00000020                     : negd.obj (.text:__pruabi_negd)
+                  00001890    00000020                     : trunc.obj (.text:__pruabi_trunc)
+                  000018b0    00000008                     : exit.obj (.text:abort)
+                  000018b8    00000008                     : exit.obj (.text:loader_exit)
+
+.stack     1    00000000    00000100     UNINITIALIZED
+                  00000000    00000004     rtspruv3_le.lib : boot.obj (.stack)
+                  00000004    000000fc     --HOLE--
+
+.cinit     1    00000000    00000000     UNINITIALIZED
+
+.fardata   1    00000100    00000040     
+                  00000100    00000040     rtspruv3_le.lib : sin.obj (.fardata:R$1)
+
+.resource_table 
+*          1    00000140    00000014     
+                  00000140    00000014     sine1.obj (.resource_table:retain)
+
+.creg.PRU_CFG.noload.near 
+*          2    00026000    00000044     NOLOAD SECTION
+                  00026000    00000044     sine1.obj (.creg.PRU_CFG.noload.near)
+
+.creg.PRU_CFG.near 
+*          2    00026044    00000000     UNINITIALIZED
+
+.creg.PRU_CFG.noload.far 
+*          2    00026044    00000000     NOLOAD SECTION
+
+.creg.PRU_CFG.far 
+*          2    00026044    00000000     UNINITIALIZED
+
+
+SEGMENT ATTRIBUTES
+
+    id tag      seg value
+    -- ---      --- -----
+     0 PHA_PAGE 1   1    
+     1 PHA_PAGE 2   1    
+
+
+GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name 
+
+page  address   name                         
+----  -------   ----                         
+0     000018b8  C$$EXIT                      
+2     00026000  CT_CFG                       
+abs   481cc000  __PRU_CREG_BASE_DCAN0        
+abs   481d0000  __PRU_CREG_BASE_DCAN1        
+abs   80000000  __PRU_CREG_BASE_DDR          
+abs   48040000  __PRU_CREG_BASE_DMTIMER2     
+abs   4a100000  __PRU_CREG_BASE_GEMAC        
+abs   4802a000  __PRU_CREG_BASE_I2C1         
+abs   4819c000  __PRU_CREG_BASE_I2C2         
+abs   40000000  __PRU_CREG_BASE_L3OCMC       
+abs   480c8000  __PRU_CREG_BASE_MBX0         
+abs   46000000  __PRU_CREG_BASE_MCASP0_DMA   
+abs   48030000  __PRU_CREG_BASE_MCSPI0       
+abs   481a0000  __PRU_CREG_BASE_MCSPI1       
+abs   48060000  __PRU_CREG_BASE_MMCHS0       
+abs   00026000  __PRU_CREG_BASE_PRU_CFG      
+abs   00000000  __PRU_CREG_BASE_PRU_DMEM_0_1 
+abs   00002000  __PRU_CREG_BASE_PRU_DMEM_1_0 
+abs   00030000  __PRU_CREG_BASE_PRU_ECAP     
+abs   0002e000  __PRU_CREG_BASE_PRU_IEP      
+abs   00020000  __PRU_CREG_BASE_PRU_INTC     
+abs   00010000  __PRU_CREG_BASE_PRU_SHAREDMEM
+abs   00028000  __PRU_CREG_BASE_PRU_UART     
+abs   48300000  __PRU_CREG_BASE_PWMSS0       
+abs   48302000  __PRU_CREG_BASE_PWMSS1       
+abs   48304000  __PRU_CREG_BASE_PWMSS2       
+abs   48318000  __PRU_CREG_BASE_RSVD10       
+abs   48310000  __PRU_CREG_BASE_RSVD13       
+abs   00032400  __PRU_CREG_BASE_RSVD21       
+abs   00032000  __PRU_CREG_BASE_RSVD27       
+abs   480ca000  __PRU_CREG_BASE_SPINLOCK     
+abs   49000000  __PRU_CREG_BASE_TPCC         
+abs   48022000  __PRU_CREG_BASE_UART1        
+abs   48024000  __PRU_CREG_BASE_UART2        
+abs   0000000e  __PRU_CREG_DCAN0             
+abs   0000000f  __PRU_CREG_DCAN1             
+abs   0000001f  __PRU_CREG_DDR               
+abs   00000001  __PRU_CREG_DMTIMER2          
+abs   00000009  __PRU_CREG_GEMAC             
+abs   00000002  __PRU_CREG_I2C1              
+abs   00000011  __PRU_CREG_I2C2              
+abs   0000001e  __PRU_CREG_L3OCMC            
+abs   00000016  __PRU_CREG_MBX0              
+abs   00000008  __PRU_CREG_MCASP0_DMA        
+abs   00000006  __PRU_CREG_MCSPI0            
+abs   00000010  __PRU_CREG_MCSPI1            
+abs   00000005  __PRU_CREG_MMCHS0            
+abs   00000004  __PRU_CREG_PRU_CFG           
+abs   00000018  __PRU_CREG_PRU_DMEM_0_1      
+abs   00000019  __PRU_CREG_PRU_DMEM_1_0      
+abs   00000003  __PRU_CREG_PRU_ECAP          
+abs   0000001a  __PRU_CREG_PRU_IEP           
+abs   00000000  __PRU_CREG_PRU_INTC          
+abs   0000001c  __PRU_CREG_PRU_SHAREDMEM     
+abs   00000007  __PRU_CREG_PRU_UART          
+abs   00000012  __PRU_CREG_PWMSS0            
+abs   00000013  __PRU_CREG_PWMSS1            
+abs   00000014  __PRU_CREG_PWMSS2            
+abs   0000000a  __PRU_CREG_RSVD10            
+abs   0000000d  __PRU_CREG_RSVD13            
+abs   00000015  __PRU_CREG_RSVD21            
+abs   0000001b  __PRU_CREG_RSVD27            
+abs   00000017  __PRU_CREG_SPINLOCK          
+abs   0000001d  __PRU_CREG_TPCC              
+abs   0000000b  __PRU_CREG_UART1             
+abs   0000000c  __PRU_CREG_UART2             
+1     00000100  __TI_STACK_END               
+abs   00000100  __TI_STACK_SIZE              
+0     0000069c  __TI_frcaddd                 
+0     00000388  __TI_frcmpyd                 
+0     0000131c  __TI_frcmpyf                 
+0     00001590  __TI_renormd                 
+abs   ffffffff  __binit__                    
+abs   ffffffff  __c_args__                   
+0     00000b48  __pruabi_addd                
+0     000017f4  __pruabi_asri                
+0     0000172c  __pruabi_cvtfd               
+0     00001500  __pruabi_eqd                 
+0     0000161c  __pruabi_fixdi               
+0     000013c4  __pruabi_fixdu               
+0     000016a8  __pruabi_fltid               
+0     000017a4  __pruabi_fltuf               
+0     0000110c  __pruabi_ged                 
+0     00001058  __pruabi_gtd                 
+0     000011bc  __pruabi_ltd                 
+0     000008f4  __pruabi_mpyd                
+0     00000d90  __pruabi_mpyf                
+0     0000184c  __pruabi_mpyi                
+0     00001870  __pruabi_negd                
+0     00001464  __pruabi_nround              
+0     00001820  __pruabi_subd                
+0     00001890  __pruabi_trunc               
+0     00000000  _c_int00_noinit_noargs_noexit
+1     00000000  _stack                       
+0     000018b0  abort                        
+abs   ffffffff  binit                        
+0     0000126c  main                         
+0     00000f58  modf                         
+1     00000140  pru_remoteproc_ResourceTable 
+0     00000014  sin                          
+
+
+GLOBAL SYMBOLS: SORTED BY Symbol Address 
+
+page  address   name                         
+----  -------   ----                         
+0     00000000  _c_int00_noinit_noargs_noexit
+0     00000014  sin                          
+0     00000388  __TI_frcmpyd                 
+0     0000069c  __TI_frcaddd                 
+0     000008f4  __pruabi_mpyd                
+0     00000b48  __pruabi_addd                
+0     00000d90  __pruabi_mpyf                
+0     00000f58  modf                         
+0     00001058  __pruabi_gtd                 
+0     0000110c  __pruabi_ged                 
+0     000011bc  __pruabi_ltd                 
+0     0000126c  main                         
+0     0000131c  __TI_frcmpyf                 
+0     000013c4  __pruabi_fixdu               
+0     00001464  __pruabi_nround              
+0     00001500  __pruabi_eqd                 
+0     00001590  __TI_renormd                 
+0     0000161c  __pruabi_fixdi               
+0     000016a8  __pruabi_fltid               
+0     0000172c  __pruabi_cvtfd               
+0     000017a4  __pruabi_fltuf               
+0     000017f4  __pruabi_asri                
+0     00001820  __pruabi_subd                
+0     0000184c  __pruabi_mpyi                
+0     00001870  __pruabi_negd                
+0     00001890  __pruabi_trunc               
+0     000018b0  abort                        
+0     000018b8  C$$EXIT                      
+1     00000000  _stack                       
+1     00000100  __TI_STACK_END               
+1     00000140  pru_remoteproc_ResourceTable 
+2     00026000  CT_CFG                       
+abs   00000000  __PRU_CREG_BASE_PRU_DMEM_0_1 
+abs   00000000  __PRU_CREG_PRU_INTC          
+abs   00000001  __PRU_CREG_DMTIMER2          
+abs   00000002  __PRU_CREG_I2C1              
+abs   00000003  __PRU_CREG_PRU_ECAP          
+abs   00000004  __PRU_CREG_PRU_CFG           
+abs   00000005  __PRU_CREG_MMCHS0            
+abs   00000006  __PRU_CREG_MCSPI0            
+abs   00000007  __PRU_CREG_PRU_UART          
+abs   00000008  __PRU_CREG_MCASP0_DMA        
+abs   00000009  __PRU_CREG_GEMAC             
+abs   0000000a  __PRU_CREG_RSVD10            
+abs   0000000b  __PRU_CREG_UART1             
+abs   0000000c  __PRU_CREG_UART2             
+abs   0000000d  __PRU_CREG_RSVD13            
+abs   0000000e  __PRU_CREG_DCAN0             
+abs   0000000f  __PRU_CREG_DCAN1             
+abs   00000010  __PRU_CREG_MCSPI1            
+abs   00000011  __PRU_CREG_I2C2              
+abs   00000012  __PRU_CREG_PWMSS0            
+abs   00000013  __PRU_CREG_PWMSS1            
+abs   00000014  __PRU_CREG_PWMSS2            
+abs   00000015  __PRU_CREG_RSVD21            
+abs   00000016  __PRU_CREG_MBX0              
+abs   00000017  __PRU_CREG_SPINLOCK          
+abs   00000018  __PRU_CREG_PRU_DMEM_0_1      
+abs   00000019  __PRU_CREG_PRU_DMEM_1_0      
+abs   0000001a  __PRU_CREG_PRU_IEP           
+abs   0000001b  __PRU_CREG_RSVD27            
+abs   0000001c  __PRU_CREG_PRU_SHAREDMEM     
+abs   0000001d  __PRU_CREG_TPCC              
+abs   0000001e  __PRU_CREG_L3OCMC            
+abs   0000001f  __PRU_CREG_DDR               
+abs   00000100  __TI_STACK_SIZE              
+abs   00002000  __PRU_CREG_BASE_PRU_DMEM_1_0 
+abs   00010000  __PRU_CREG_BASE_PRU_SHAREDMEM
+abs   00020000  __PRU_CREG_BASE_PRU_INTC     
+abs   00026000  __PRU_CREG_BASE_PRU_CFG      
+abs   00028000  __PRU_CREG_BASE_PRU_UART     
+abs   0002e000  __PRU_CREG_BASE_PRU_IEP      
+abs   00030000  __PRU_CREG_BASE_PRU_ECAP     
+abs   00032000  __PRU_CREG_BASE_RSVD27       
+abs   00032400  __PRU_CREG_BASE_RSVD21       
+abs   40000000  __PRU_CREG_BASE_L3OCMC       
+abs   46000000  __PRU_CREG_BASE_MCASP0_DMA   
+abs   48022000  __PRU_CREG_BASE_UART1        
+abs   48024000  __PRU_CREG_BASE_UART2        
+abs   4802a000  __PRU_CREG_BASE_I2C1         
+abs   48030000  __PRU_CREG_BASE_MCSPI0       
+abs   48040000  __PRU_CREG_BASE_DMTIMER2     
+abs   48060000  __PRU_CREG_BASE_MMCHS0       
+abs   480c8000  __PRU_CREG_BASE_MBX0         
+abs   480ca000  __PRU_CREG_BASE_SPINLOCK     
+abs   4819c000  __PRU_CREG_BASE_I2C2         
+abs   481a0000  __PRU_CREG_BASE_MCSPI1       
+abs   481cc000  __PRU_CREG_BASE_DCAN0        
+abs   481d0000  __PRU_CREG_BASE_DCAN1        
+abs   48300000  __PRU_CREG_BASE_PWMSS0       
+abs   48302000  __PRU_CREG_BASE_PWMSS1       
+abs   48304000  __PRU_CREG_BASE_PWMSS2       
+abs   48310000  __PRU_CREG_BASE_RSVD13       
+abs   48318000  __PRU_CREG_BASE_RSVD10       
+abs   49000000  __PRU_CREG_BASE_TPCC         
+abs   4a100000  __PRU_CREG_BASE_GEMAC        
+abs   80000000  __PRU_CREG_BASE_DDR          
+abs   ffffffff  __binit__                    
+abs   ffffffff  __c_args__                   
+abs   ffffffff  binit                        
+
+[100 symbols]
diff --git a/pru-cookbook/05blocks/code/sine.pru0.c b/pru-cookbook/05blocks/code/sine.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..ed6b5778c644f860c8fa2c0f91b7f23cf50e6df7
--- /dev/null
+++ b/pru-cookbook/05blocks/code/sine.pru0.c
@@ -0,0 +1,58 @@
+// Generate an analog waveform and use a filter to reconstruct it.
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include <math.h>
+
+#define MAXT	100	// Maximum number of time samples
+#define SAWTOOTH	// Pick which waveform
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t onCount;		// Current count for 1 out
+	uint32_t offCount;		// count for 0 out
+	uint32_t i;
+	uint32_t waveform[MAXT]; // Waveform to be produced
+
+	// Generate a periodic wave in an array of MAXT values
+#ifdef SAWTOOTH
+	for(i=0; i<MAXT; i++) {
+		waveform[i] = i*100/MAXT;
+	}
+#endif
+#ifdef TRIANGLE
+	for(i=0; i<MAXT/2; i++) {
+		waveform[i]        = 2*i*100/MAXT;
+		waveform[MAXT-i-1] = 2*i*100/MAXT;
+	}
+#endif
+#ifdef SINE
+	float gain = 50.0f;
+	float bias = 50.0f;
+	float freq = 2.0f * 3.14159f / MAXT;
+	for (i=0; i<MAXT; i++){
+		waveform[i] = (uint32_t)(bias+gain*sin(i*freq));
+	}
+#endif
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	while (1) {
+		// Generate a PWM signal whose duty cycle matches
+		// the amplitude of the signal.
+		for(i=0; i<MAXT; i++) {
+			onCount = waveform[i];
+			offCount = 100 - onCount;
+			while(onCount--) {
+				__R30 |= 0x1;		// Set the GPIO pin to 1
+			}
+			while(offCount--) {
+				__R30 &= ~(0x1);	// Clear the GPIO pin
+			}
+		}
+	}
+}
diff --git a/pru-cookbook/05blocks/code/write_init_pins.sh b/pru-cookbook/05blocks/code/write_init_pins.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f52082365a8b2a72a6c30d39938077bd9addf741
--- /dev/null
+++ b/pru-cookbook/05blocks/code/write_init_pins.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+init_pins=$(readelf -x .init_pins $1 | grep 0x000 | cut -d' ' -f4-7 | xxd -r -p | tr '\0' '\n' | paste - -)
+while read -a line; do
+    if [ ${#line[@]} == 2 ]; then
+        echo writing \"${line[1]}\" to \"${line[0]}\"
+        echo ${line[1]} > ${line[0]}
+        sleep 0.1
+    fi
+done <<< "$init_pins"
diff --git a/pru-cookbook/05blocks/figures/blockDiagram.png b/pru-cookbook/05blocks/figures/blockDiagram.png
new file mode 100644
index 0000000000000000000000000000000000000000..901f5b4af178dd896a3a07b5701804a0eaf17fa4
Binary files /dev/null and b/pru-cookbook/05blocks/figures/blockDiagram.png differ
diff --git a/pru-cookbook/05blocks/figures/blocks_plots.asv b/pru-cookbook/05blocks/figures/blocks_plots.asv
new file mode 100644
index 0000000000000000000000000000000000000000..760326592b877da906a542683a91bb8778433134
--- /dev/null
+++ b/pru-cookbook/05blocks/figures/blocks_plots.asv
@@ -0,0 +1,27 @@
+% Plots for PRU example
+MAXT=100
+waveform = linspace(0, MAXT-1, 100);
+
+plot(waveform)
+
+%%
+T = 10*(1/50);
+Fs = 100;
+dt = 1/Fs;
+t = 0:dt:T-dt;
+x = 50*sawtooth(2*pi*10*t)+50;
+
+stem(t,x)
+title('Sawtooth Waveform')
+grid on
+
+%% Solid sawtooth
+T = 10*(1/50);
+Fs = 100;
+dt = 1/Fs;
+t = 0:dt:T-dt;
+x = 50*sawtooth(2*pi*20*t)+50;
+
+stem(t,x)
+title('Sampled Sawtooth Waveform')
+grid on
diff --git a/pru-cookbook/05blocks/figures/blocks_plots.m b/pru-cookbook/05blocks/figures/blocks_plots.m
new file mode 100644
index 0000000000000000000000000000000000000000..37ab48a26c799541d51ec0fa43835b9387131a7d
--- /dev/null
+++ b/pru-cookbook/05blocks/figures/blocks_plots.m
@@ -0,0 +1,27 @@
+% Plots for PRU example
+MAXT=100
+waveform = linspace(0, MAXT-1, 100);
+
+plot(waveform)
+
+%%
+T = 20*(1/50);
+Fs = 1000;
+dt = 1/Fs;
+t = 0:dt:T-dt;
+x = 50*sawtooth(2*pi*10*t)+50;
+
+plot(t,x)
+title('Sawtooth Waveform')
+grid on
+
+%% Solid sawtooth
+T = 5*(1/50);
+Fs = 200;
+dt = 1/Fs;
+t = 0:dt:T-dt;
+x = 50*sawtooth(2*pi*10*t)+50;
+
+stem(t,x)
+title('Sampled Sawtooth Waveform')
+grid on
diff --git a/pru-cookbook/05blocks/figures/filter.fzz b/pru-cookbook/05blocks/figures/filter.fzz
new file mode 100644
index 0000000000000000000000000000000000000000..3342d1cc50cd475f668a42b18f1900448ebb1c92
Binary files /dev/null and b/pru-cookbook/05blocks/figures/filter.fzz differ
diff --git a/pru-cookbook/05blocks/figures/filter_bb.png b/pru-cookbook/05blocks/figures/filter_bb.png
new file mode 100644
index 0000000000000000000000000000000000000000..3fc2955b5c48540261818efd47e01e6c1d268350
Binary files /dev/null and b/pru-cookbook/05blocks/figures/filter_bb.png differ
diff --git a/pru-cookbook/05blocks/figures/matrix_j1.jpg b/pru-cookbook/05blocks/figures/matrix_j1.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..711c90412e80626e916a14fe0474ca083eb3c642
Binary files /dev/null and b/pru-cookbook/05blocks/figures/matrix_j1.jpg differ
diff --git a/pru-cookbook/05blocks/figures/neo.fzz b/pru-cookbook/05blocks/figures/neo.fzz
new file mode 100644
index 0000000000000000000000000000000000000000..36191328e10761ac75321186fce2f2955ca8004e
Binary files /dev/null and b/pru-cookbook/05blocks/figures/neo.fzz differ
diff --git a/pru-cookbook/05blocks/figures/neo_bb.png b/pru-cookbook/05blocks/figures/neo_bb.png
new file mode 100644
index 0000000000000000000000000000000000000000..e7cc6b2fa60b62fff23b3abddc4e2e6578408718
Binary files /dev/null and b/pru-cookbook/05blocks/figures/neo_bb.png differ
diff --git a/pru-cookbook/05blocks/figures/neo_data_seq.png b/pru-cookbook/05blocks/figures/neo_data_seq.png
new file mode 100644
index 0000000000000000000000000000000000000000..bef90bbeb121dee12cd393faceb17e59e2e9a985
Binary files /dev/null and b/pru-cookbook/05blocks/figures/neo_data_seq.png differ
diff --git a/pru-cookbook/05blocks/figures/neo_scope.png b/pru-cookbook/05blocks/figures/neo_scope.png
new file mode 100644
index 0000000000000000000000000000000000000000..919d0b8d574b64cbf237761befed37b3812f6f3c
Binary files /dev/null and b/pru-cookbook/05blocks/figures/neo_scope.png differ
diff --git a/pru-cookbook/05blocks/figures/neo_sequence.png b/pru-cookbook/05blocks/figures/neo_sequence.png
new file mode 100644
index 0000000000000000000000000000000000000000..be8c48c18e270048b8ae6585b237e6b0973735cc
Binary files /dev/null and b/pru-cookbook/05blocks/figures/neo_sequence.png differ
diff --git a/pru-cookbook/05blocks/figures/pwm1.png b/pru-cookbook/05blocks/figures/pwm1.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b56f035350a75c7459d82d268de4cf58bba6ffd
Binary files /dev/null and b/pru-cookbook/05blocks/figures/pwm1.png differ
diff --git a/pru-cookbook/05blocks/figures/pwm2.png b/pru-cookbook/05blocks/figures/pwm2.png
new file mode 100644
index 0000000000000000000000000000000000000000..248a142b345ccd3e425e0bfd596116df8b4ad30b
Binary files /dev/null and b/pru-cookbook/05blocks/figures/pwm2.png differ
diff --git a/pru-cookbook/05blocks/figures/pwm3.png b/pru-cookbook/05blocks/figures/pwm3.png
new file mode 100644
index 0000000000000000000000000000000000000000..0b76c32939ab7d9143ed48815b5739caad428e0a
Binary files /dev/null and b/pru-cookbook/05blocks/figures/pwm3.png differ
diff --git a/pru-cookbook/05blocks/figures/pwm4.png b/pru-cookbook/05blocks/figures/pwm4.png
new file mode 100644
index 0000000000000000000000000000000000000000..dfc9c75da241ba42dffc326726f143dc2a58a8d0
Binary files /dev/null and b/pru-cookbook/05blocks/figures/pwm4.png differ
diff --git a/pru-cookbook/05blocks/figures/pwm5_no_loop.png b/pru-cookbook/05blocks/figures/pwm5_no_loop.png
new file mode 100644
index 0000000000000000000000000000000000000000..35aff88d2bf00c727c6c6ebf0667fa0464c7c68e
Binary files /dev/null and b/pru-cookbook/05blocks/figures/pwm5_no_loop.png differ
diff --git a/pru-cookbook/05blocks/figures/pwm5_zoomed.png b/pru-cookbook/05blocks/figures/pwm5_zoomed.png
new file mode 100644
index 0000000000000000000000000000000000000000..6802cb55ca07d815d665d7aa8f987addd4366c13
Binary files /dev/null and b/pru-cookbook/05blocks/figures/pwm5_zoomed.png differ
diff --git a/pru-cookbook/05blocks/figures/pwm6_synced.png b/pru-cookbook/05blocks/figures/pwm6_synced.png
new file mode 100644
index 0000000000000000000000000000000000000000..1b71ee53d8d974fd0207342ecd37fe27a34b89f5
Binary files /dev/null and b/pru-cookbook/05blocks/figures/pwm6_synced.png differ
diff --git a/pru-cookbook/05blocks/figures/pwm7_two_prus_running.png b/pru-cookbook/05blocks/figures/pwm7_two_prus_running.png
new file mode 100644
index 0000000000000000000000000000000000000000..662706b9203b7734ad9e3146ee7a8aa6386f39f0
Binary files /dev/null and b/pru-cookbook/05blocks/figures/pwm7_two_prus_running.png differ
diff --git a/pru-cookbook/05blocks/figures/pwm7_two_prus_stopped.png b/pru-cookbook/05blocks/figures/pwm7_two_prus_stopped.png
new file mode 100644
index 0000000000000000000000000000000000000000..00cfc20dc65ce2cb5b88cb34a6f60a61266e05bc
Binary files /dev/null and b/pru-cookbook/05blocks/figures/pwm7_two_prus_stopped.png differ
diff --git a/pru-cookbook/05blocks/figures/pwm8_prus_sycned.png b/pru-cookbook/05blocks/figures/pwm8_prus_sycned.png
new file mode 100644
index 0000000000000000000000000000000000000000..f27388fa93ec02685296c3aa13ec3a7b3a182144
Binary files /dev/null and b/pru-cookbook/05blocks/figures/pwm8_prus_sycned.png differ
diff --git a/pru-cookbook/05blocks/figures/rgb_fpp.png b/pru-cookbook/05blocks/figures/rgb_fpp.png
new file mode 100644
index 0000000000000000000000000000000000000000..38adf5a27d49f028e09b75426211e743b35aa97b
Binary files /dev/null and b/pru-cookbook/05blocks/figures/rgb_fpp.png differ
diff --git a/pru-cookbook/05blocks/figures/rgb_pru.jpg b/pru-cookbook/05blocks/figures/rgb_pru.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a588b42bd7e02958c8e48142921825d79adb8b8e
Binary files /dev/null and b/pru-cookbook/05blocks/figures/rgb_pru.jpg differ
diff --git a/pru-cookbook/05blocks/figures/rgb_python.jpg b/pru-cookbook/05blocks/figures/rgb_python.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..26c83ec2d73310ea64aea2252c1c437a304530f7
Binary files /dev/null and b/pru-cookbook/05blocks/figures/rgb_python.jpg differ
diff --git a/pru-cookbook/05blocks/figures/rgb_waveforms.png b/pru-cookbook/05blocks/figures/rgb_waveforms.png
new file mode 100644
index 0000000000000000000000000000000000000000..df9d8cbdbe93f2b72c08945246dccec62aba3879
Binary files /dev/null and b/pru-cookbook/05blocks/figures/rgb_waveforms.png differ
diff --git a/pru-cookbook/05blocks/figures/ring_around.mp4 b/pru-cookbook/05blocks/figures/ring_around.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..1695cb0532647566c09e966dca41348943962bfb
Binary files /dev/null and b/pru-cookbook/05blocks/figures/ring_around.mp4 differ
diff --git a/pru-cookbook/05blocks/figures/sawhighercutoff.png b/pru-cookbook/05blocks/figures/sawhighercutoff.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ca0f4d4023db196b2e85b17dda9dc915e9b00c4
Binary files /dev/null and b/pru-cookbook/05blocks/figures/sawhighercutoff.png differ
diff --git a/pru-cookbook/05blocks/figures/sawlowercutoff.png b/pru-cookbook/05blocks/figures/sawlowercutoff.png
new file mode 100644
index 0000000000000000000000000000000000000000..933d7cc2587e9177bbc98572a302d2d6a298d5a0
Binary files /dev/null and b/pru-cookbook/05blocks/figures/sawlowercutoff.png differ
diff --git a/pru-cookbook/05blocks/figures/sawscope.png b/pru-cookbook/05blocks/figures/sawscope.png
new file mode 100644
index 0000000000000000000000000000000000000000..d9d191d3ebce062b6d44108a17fcf7871a39b775
Binary files /dev/null and b/pru-cookbook/05blocks/figures/sawscope.png differ
diff --git a/pru-cookbook/05blocks/figures/sawtoothsampled.png b/pru-cookbook/05blocks/figures/sawtoothsampled.png
new file mode 100644
index 0000000000000000000000000000000000000000..c6b09731731306d2e40695e9cc5a8bc2635bce4e
Binary files /dev/null and b/pru-cookbook/05blocks/figures/sawtoothsampled.png differ
diff --git a/pru-cookbook/05blocks/figures/sawtoothsmooth.png b/pru-cookbook/05blocks/figures/sawtoothsmooth.png
new file mode 100644
index 0000000000000000000000000000000000000000..60296663cb33d64b76f7fc099fc5fbb0fbf86a5d
Binary files /dev/null and b/pru-cookbook/05blocks/figures/sawtoothsmooth.png differ
diff --git a/pru-cookbook/05blocks/figures/sawunfiltered.png b/pru-cookbook/05blocks/figures/sawunfiltered.png
new file mode 100644
index 0000000000000000000000000000000000000000..9f77ac535d832cbf159b072d59cdf69819af61a4
Binary files /dev/null and b/pru-cookbook/05blocks/figures/sawunfiltered.png differ
diff --git a/pru-cookbook/05blocks/figures/sine.png b/pru-cookbook/05blocks/figures/sine.png
new file mode 100644
index 0000000000000000000000000000000000000000..0c6913b16be3ab3694c99fc41c4b68e969c75db6
Binary files /dev/null and b/pru-cookbook/05blocks/figures/sine.png differ
diff --git a/pru-cookbook/05blocks/figures/triangle.png b/pru-cookbook/05blocks/figures/triangle.png
new file mode 100644
index 0000000000000000000000000000000000000000..988a28810411074efc6de6337040dce50d558513
Binary files /dev/null and b/pru-cookbook/05blocks/figures/triangle.png differ
diff --git a/pru-cookbook/06io/code/Makefile b/pru-cookbook/06io/code/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a7557fdaa22988d89cec879477ded78522d7116f
--- /dev/null
+++ b/pru-cookbook/06io/code/Makefile
@@ -0,0 +1 @@
+include /var/lib/cloud9/common/Makefile
diff --git a/pru-cookbook/06io/code/gpio.pru0.c b/pru-cookbook/06io/code/gpio.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..bcab90eff3f115577055dac3781c50bfb3e0efbf
--- /dev/null
+++ b/pru-cookbook/06io/code/gpio.pru0.c
@@ -0,0 +1,23 @@
+// This code accesses GPIO without using R30 and R31
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+#define P9_11	(0x1<<30)			// Bit position tied to P9_11 on Black
+#define P2_05	(0x1<<30)			// Bit position tied to P2_05 on Pocket
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t *gpio0 = (uint32_t *)GPIO0;
+	
+	while(1) {
+		gpio0[GPIO_SETDATAOUT]   = P9_11;
+		__delay_cycles(100000000);
+		gpio0[GPIO_CLEARDATAOUT] = P9_11;
+		__delay_cycles(100000000);
+	}
+}
diff --git a/pru-cookbook/06io/code/setup.sh b/pru-cookbook/06io/code/setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e676ed7abe2a6beaf62d3ce6c56f5aa151d86700
--- /dev/null
+++ b/pru-cookbook/06io/code/setup.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+export TARGET=gpio.pru0
+echo TARGET=$TARGET
+
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P9_11"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P2_05"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin gpio
+    config-pin -q $pin
+done
diff --git a/pru-cookbook/06io/figures/gpio0delay.png b/pru-cookbook/06io/figures/gpio0delay.png
new file mode 100644
index 0000000000000000000000000000000000000000..ad8568542d5d6b2445cb7ba2e42792bc671e6d6b
Binary files /dev/null and b/pru-cookbook/06io/figures/gpio0delay.png differ
diff --git a/pru-cookbook/06io/figures/jitter.png b/pru-cookbook/06io/figures/jitter.png
new file mode 100644
index 0000000000000000000000000000000000000000..e9b80b4d61809420fa6a8ee6e23cb44ee2ab9c2b
Binary files /dev/null and b/pru-cookbook/06io/figures/jitter.png differ
diff --git a/pru-cookbook/06io/figures/pruIntegration.png b/pru-cookbook/06io/figures/pruIntegration.png
new file mode 100644
index 0000000000000000000000000000000000000000..de7ef9196b3e56e5bd1ff14a9957c2ff23d3fa41
Binary files /dev/null and b/pru-cookbook/06io/figures/pruIntegration.png differ
diff --git a/pru-cookbook/06io/io.html b/pru-cookbook/06io/io.html
new file mode 100644
index 0000000000000000000000000000000000000000..5bb5425db9ef3699741ac9d74701f36aac6519b4
--- /dev/null
+++ b/pru-cookbook/06io/io.html
@@ -0,0 +1,1003 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<meta name="generator" content="Asciidoctor 1.5.8">
+<title>Accessing More I/O</title>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
+<style>
+/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
+/* Uncomment @import statement below to use as custom stylesheet */
+/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
+article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
+audio,canvas,video{display:inline-block}
+audio:not([controls]){display:none;height:0}
+script{display:none!important}
+html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
+a{background:transparent}
+a:focus{outline:thin dotted}
+a:active,a:hover{outline:0}
+h1{font-size:2em;margin:.67em 0}
+abbr[title]{border-bottom:1px dotted}
+b,strong{font-weight:bold}
+dfn{font-style:italic}
+hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
+mark{background:#ff0;color:#000}
+code,kbd,pre,samp{font-family:monospace;font-size:1em}
+pre{white-space:pre-wrap}
+q{quotes:"\201C" "\201D" "\2018" "\2019"}
+small{font-size:80%}
+sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
+sup{top:-.5em}
+sub{bottom:-.25em}
+img{border:0}
+svg:not(:root){overflow:hidden}
+figure{margin:0}
+fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
+legend{border:0;padding:0}
+button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
+button,input{line-height:normal}
+button,select{text-transform:none}
+button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
+button[disabled],html input[disabled]{cursor:default}
+input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
+button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
+textarea{overflow:auto;vertical-align:top}
+table{border-collapse:collapse;border-spacing:0}
+*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
+html,body{font-size:100%}
+body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
+a:hover{cursor:pointer}
+img,object,embed{max-width:100%;height:auto}
+object,embed{height:100%}
+img{-ms-interpolation-mode:bicubic}
+.left{float:left!important}
+.right{float:right!important}
+.text-left{text-align:left!important}
+.text-right{text-align:right!important}
+.text-center{text-align:center!important}
+.text-justify{text-align:justify!important}
+.hide{display:none}
+img,object,svg{display:inline-block;vertical-align:middle}
+textarea{height:auto;min-height:50px}
+select{width:100%}
+.center{margin-left:auto;margin-right:auto}
+.stretch{width:100%}
+.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
+div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
+a{color:#2156a5;text-decoration:underline;line-height:inherit}
+a:hover,a:focus{color:#1d4b8f}
+a img{border:none}
+p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
+p aside{font-size:.875em;line-height:1.35;font-style:italic}
+h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
+h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
+h1{font-size:2.125em}
+h2{font-size:1.6875em}
+h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
+h4,h5{font-size:1.125em}
+h6{font-size:1em}
+hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
+em,i{font-style:italic;line-height:inherit}
+strong,b{font-weight:bold;line-height:inherit}
+small{font-size:60%;line-height:inherit}
+code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
+ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
+ul,ol{margin-left:1.5em}
+ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
+ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
+ul.square{list-style-type:square}
+ul.circle{list-style-type:circle}
+ul.disc{list-style-type:disc}
+ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
+dl dt{margin-bottom:.3125em;font-weight:bold}
+dl dd{margin-bottom:1.25em}
+abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
+abbr{text-transform:none}
+blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
+blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
+blockquote cite::before{content:"\2014 \0020"}
+blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
+blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
+@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
+h1{font-size:2.75em}
+h2{font-size:2.3125em}
+h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
+h4{font-size:1.4375em}}
+table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
+table thead,table tfoot{background:#f7f8f7}
+table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
+table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
+table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
+table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
+h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
+h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
+.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
+.clearfix::after,.float-group::after{clear:both}
+*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed;word-wrap:break-word}
+*:not(pre)>code.nobreak{word-wrap:normal}
+*:not(pre)>code.nowrap{white-space:nowrap}
+pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
+em em{font-style:normal}
+strong strong{font-weight:400}
+.keyseq{color:rgba(51,51,51,.8)}
+kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
+.keyseq kbd:first-child{margin-left:0}
+.keyseq kbd:last-child{margin-right:0}
+.menuseq,.menuref{color:#000}
+.menuseq b:not(.caret),.menuref{font-weight:inherit}
+.menuseq{word-spacing:-.02em}
+.menuseq b.caret{font-size:1.25em;line-height:.8}
+.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
+b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
+b.button::before{content:"[";padding:0 3px 0 2px}
+b.button::after{content:"]";padding:0 2px 0 3px}
+p a>code:hover{color:rgba(0,0,0,.9)}
+#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
+#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
+#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
+#content{margin-top:1.25em}
+#content::before{content:none}
+#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
+#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
+#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
+#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
+#header .details span:first-child{margin-left:-.125em}
+#header .details span.email a{color:rgba(0,0,0,.85)}
+#header .details br{display:none}
+#header .details br+span::before{content:"\00a0\2013\00a0"}
+#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
+#header .details br+span#revremark::before{content:"\00a0|\00a0"}
+#header #revnumber{text-transform:capitalize}
+#header #revnumber::after{content:"\00a0"}
+#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
+#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
+#toc>ul{margin-left:.125em}
+#toc ul.sectlevel0>li>a{font-style:italic}
+#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
+#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
+#toc li{line-height:1.3334;margin-top:.3334em}
+#toc a{text-decoration:none}
+#toc a:active{text-decoration:underline}
+#toctitle{color:#7a2518;font-size:1.2em}
+@media screen and (min-width:768px){#toctitle{font-size:1.375em}
+body.toc2{padding-left:15em;padding-right:0}
+#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
+#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
+#toc.toc2>ul{font-size:.9em;margin-bottom:0}
+#toc.toc2 ul ul{margin-left:0;padding-left:1em}
+#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
+body.toc2.toc-right{padding-left:0;padding-right:15em}
+body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
+@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
+#toc.toc2{width:20em}
+#toc.toc2 #toctitle{font-size:1.375em}
+#toc.toc2>ul{font-size:.95em}
+#toc.toc2 ul ul{padding-left:1.25em}
+body.toc2.toc-right{padding-left:0;padding-right:20em}}
+#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
+#content #toc>:first-child{margin-top:0}
+#content #toc>:last-child{margin-bottom:0}
+#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
+#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
+#content{margin-bottom:.625em}
+.sect1{padding-bottom:.625em}
+@media screen and (min-width:768px){#content{margin-bottom:1.25em}
+.sect1{padding-bottom:1.25em}}
+.sect1:last-child{padding-bottom:0}
+.sect1+.sect1{border-top:1px solid #e7e7e9}
+#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
+#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
+#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
+#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
+#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
+.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
+.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
+table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
+.paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
+table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
+.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
+.admonitionblock>table td.icon{text-align:center;width:80px}
+.admonitionblock>table td.icon img{max-width:none}
+.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
+.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6)}
+.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
+.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
+.exampleblock>.content>:first-child{margin-top:0}
+.exampleblock>.content>:last-child{margin-bottom:0}
+.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
+.sidebarblock>:first-child{margin-top:0}
+.sidebarblock>:last-child{margin-bottom:0}
+.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
+.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
+.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
+.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
+.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;overflow-x:auto;padding:1em;font-size:.8125em}
+@media screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
+@media screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
+.literalblock pre.nowrap,.literalblock pre.nowrap pre,.listingblock pre.nowrap,.listingblock pre.nowrap pre{white-space:pre;word-wrap:normal}
+.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
+.listingblock pre.highlightjs{padding:0}
+.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
+.listingblock pre.prettyprint{border-width:0}
+.listingblock>.content{position:relative}
+.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
+.listingblock:hover code[data-lang]::before{display:block}
+.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:#999}
+.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
+table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
+table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
+table.pyhltable td.code{padding-left:.75em;padding-right:0}
+pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #dddddf}
+pre.pygments .lineno{display:inline-block;margin-right:.25em}
+table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
+.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
+.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
+.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
+.quoteblock blockquote{margin:0;padding:0;border:0}
+.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
+.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
+.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
+.verseblock{margin:0 1em 1.25em}
+.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
+.verseblock pre strong{font-weight:400}
+.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
+.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
+.quoteblock .attribution br,.verseblock .attribution br{display:none}
+.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
+.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
+.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
+.quoteblock.abstract{margin:0 1em 1.25em;display:block}
+.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
+.quoteblock.excerpt,.quoteblock .quoteblock{margin:0 0 1.25em;padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
+.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
+.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
+table.tableblock{max-width:100%;border-collapse:separate}
+p.tableblock:last-child{margin-bottom:0}
+td.tableblock>.content{margin-bottom:-1.25em}
+table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
+table.grid-all>thead>tr>.tableblock,table.grid-all>tbody>tr>.tableblock{border-width:0 1px 1px 0}
+table.grid-all>tfoot>tr>.tableblock{border-width:1px 1px 0 0}
+table.grid-cols>*>tr>.tableblock{border-width:0 1px 0 0}
+table.grid-rows>thead>tr>.tableblock,table.grid-rows>tbody>tr>.tableblock{border-width:0 0 1px}
+table.grid-rows>tfoot>tr>.tableblock{border-width:1px 0 0}
+table.grid-all>*>tr>.tableblock:last-child,table.grid-cols>*>tr>.tableblock:last-child{border-right-width:0}
+table.grid-all>tbody>tr:last-child>.tableblock,table.grid-all>thead:last-child>tr>.tableblock,table.grid-rows>tbody>tr:last-child>.tableblock,table.grid-rows>thead:last-child>tr>.tableblock{border-bottom-width:0}
+table.frame-all{border-width:1px}
+table.frame-sides{border-width:0 1px}
+table.frame-topbot,table.frame-ends{border-width:1px 0}
+table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd){background:#f8f8f7}
+table.stripes-none tr,table.stripes-odd tr:nth-of-type(even){background:none}
+th.halign-left,td.halign-left{text-align:left}
+th.halign-right,td.halign-right{text-align:right}
+th.halign-center,td.halign-center{text-align:center}
+th.valign-top,td.valign-top{vertical-align:top}
+th.valign-bottom,td.valign-bottom{vertical-align:bottom}
+th.valign-middle,td.valign-middle{vertical-align:middle}
+table thead th,table tfoot th{font-weight:bold}
+tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
+tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
+p.tableblock>code:only-child{background:none;padding:0}
+p.tableblock{font-size:1em}
+td>div.verse{white-space:pre}
+ol{margin-left:1.75em}
+ul li ol{margin-left:1.5em}
+dl dd{margin-left:1.125em}
+dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
+ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
+ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
+ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
+ul.unstyled,ol.unstyled{margin-left:0}
+ul.checklist{margin-left:.625em}
+ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
+ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
+ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
+ul.inline>li{margin-left:1.25em}
+.unstyled dl dt{font-weight:400;font-style:normal}
+ol.arabic{list-style-type:decimal}
+ol.decimal{list-style-type:decimal-leading-zero}
+ol.loweralpha{list-style-type:lower-alpha}
+ol.upperalpha{list-style-type:upper-alpha}
+ol.lowerroman{list-style-type:lower-roman}
+ol.upperroman{list-style-type:upper-roman}
+ol.lowergreek{list-style-type:lower-greek}
+.hdlist>table,.colist>table{border:0;background:none}
+.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
+td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
+td.hdlist1{font-weight:bold;padding-bottom:1.25em}
+.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
+.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
+.colist td:not([class]):first-child img{max-width:none}
+.colist td:not([class]):last-child{padding:.25em 0}
+.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
+.imageblock.left{margin:.25em .625em 1.25em 0}
+.imageblock.right{margin:.25em 0 1.25em .625em}
+.imageblock>.title{margin-bottom:0}
+.imageblock.thumb,.imageblock.th{border-width:6px}
+.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
+.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
+.image.left{margin-right:.625em}
+.image.right{margin-left:.625em}
+a.image{text-decoration:none;display:inline-block}
+a.image object{pointer-events:none}
+sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
+sup.footnote a,sup.footnoteref a{text-decoration:none}
+sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
+#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
+#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
+#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
+#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
+#footnotes .footnote:last-of-type{margin-bottom:0}
+#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
+.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
+.gist .file-data>table td.line-data{width:99%}
+div.unbreakable{page-break-inside:avoid}
+.big{font-size:larger}
+.small{font-size:smaller}
+.underline{text-decoration:underline}
+.overline{text-decoration:overline}
+.line-through{text-decoration:line-through}
+.aqua{color:#00bfbf}
+.aqua-background{background-color:#00fafa}
+.black{color:#000}
+.black-background{background-color:#000}
+.blue{color:#0000bf}
+.blue-background{background-color:#0000fa}
+.fuchsia{color:#bf00bf}
+.fuchsia-background{background-color:#fa00fa}
+.gray{color:#606060}
+.gray-background{background-color:#7d7d7d}
+.green{color:#006000}
+.green-background{background-color:#007d00}
+.lime{color:#00bf00}
+.lime-background{background-color:#00fa00}
+.maroon{color:#600000}
+.maroon-background{background-color:#7d0000}
+.navy{color:#000060}
+.navy-background{background-color:#00007d}
+.olive{color:#606000}
+.olive-background{background-color:#7d7d00}
+.purple{color:#600060}
+.purple-background{background-color:#7d007d}
+.red{color:#bf0000}
+.red-background{background-color:#fa0000}
+.silver{color:#909090}
+.silver-background{background-color:#bcbcbc}
+.teal{color:#006060}
+.teal-background{background-color:#007d7d}
+.white{color:#bfbfbf}
+.white-background{background-color:#fafafa}
+.yellow{color:#bfbf00}
+.yellow-background{background-color:#fafa00}
+span.icon>.fa{cursor:default}
+a span.icon>.fa{cursor:inherit}
+.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
+.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
+.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
+.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
+.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
+.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
+.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
+.conum[data-value] *{color:#fff!important}
+.conum[data-value]+b{display:none}
+.conum[data-value]::after{content:attr(data-value)}
+pre .conum[data-value]{position:relative;top:-.125em}
+b.conum *{color:inherit!important}
+.conum:not([data-value]):empty{display:none}
+dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
+h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
+p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
+p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
+p{margin-bottom:1.25rem}
+.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
+.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
+.print-only{display:none!important}
+@page{margin:1.25cm .75cm}
+@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
+html{font-size:80%}
+a{color:inherit!important;text-decoration:underline!important}
+a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
+a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
+abbr[title]::after{content:" (" attr(title) ")"}
+pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
+thead{display:table-header-group}
+svg{max-width:100%}
+p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
+h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
+#toc,.sidebarblock,.exampleblock>.content{background:none!important}
+#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
+body.book #header{text-align:center}
+body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
+body.book #header .details{border:0!important;display:block;padding:0!important}
+body.book #header .details span:first-child{margin-left:0!important}
+body.book #header .details br{display:block}
+body.book #header .details br+span::before{content:none!important}
+body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
+body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
+.listingblock code[data-lang]::before{display:block}
+#footer{padding:0 .9375em}
+.hide-on-print{display:none!important}
+.print-only{display:block!important}
+.hide-for-print{display:none!important}
+.show-for-print{display:inherit!important}}
+@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
+.sect1{padding:0!important}
+.sect1+.sect1{border:0}
+#footer{background:none}
+#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
+@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
+</style>
+<style>
+/* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */
+/*pre.CodeRay {background-color:#f7f7f8;}*/
+.CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em}
+.CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)}
+.CodeRay .line-numbers strong{color:rgba(0,0,0,.4)}
+table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none}
+table.CodeRay td{vertical-align: top;line-height:1.45}
+table.CodeRay td.line-numbers{text-align:right}
+table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)}
+table.CodeRay td.code{padding:0 0 0 .5em}
+table.CodeRay td.code>pre{padding:0}
+.CodeRay .debug{color:#fff !important;background:#000080 !important}
+.CodeRay .annotation{color:#007}
+.CodeRay .attribute-name{color:#000080}
+.CodeRay .attribute-value{color:#700}
+.CodeRay .binary{color:#509}
+.CodeRay .comment{color:#998;font-style:italic}
+.CodeRay .char{color:#04d}
+.CodeRay .char .content{color:#04d}
+.CodeRay .char .delimiter{color:#039}
+.CodeRay .class{color:#458;font-weight:bold}
+.CodeRay .complex{color:#a08}
+.CodeRay .constant,.CodeRay .predefined-constant{color:#008080}
+.CodeRay .color{color:#099}
+.CodeRay .class-variable{color:#369}
+.CodeRay .decorator{color:#b0b}
+.CodeRay .definition{color:#099}
+.CodeRay .delimiter{color:#000}
+.CodeRay .doc{color:#970}
+.CodeRay .doctype{color:#34b}
+.CodeRay .doc-string{color:#d42}
+.CodeRay .escape{color:#666}
+.CodeRay .entity{color:#800}
+.CodeRay .error{color:#808}
+.CodeRay .exception{color:inherit}
+.CodeRay .filename{color:#099}
+.CodeRay .function{color:#900;font-weight:bold}
+.CodeRay .global-variable{color:#008080}
+.CodeRay .hex{color:#058}
+.CodeRay .integer,.CodeRay .float{color:#099}
+.CodeRay .include{color:#555}
+.CodeRay .inline{color:#000}
+.CodeRay .inline .inline{background:#ccc}
+.CodeRay .inline .inline .inline{background:#bbb}
+.CodeRay .inline .inline-delimiter{color:#d14}
+.CodeRay .inline-delimiter{color:#d14}
+.CodeRay .important{color:#555;font-weight:bold}
+.CodeRay .interpreted{color:#b2b}
+.CodeRay .instance-variable{color:#008080}
+.CodeRay .label{color:#970}
+.CodeRay .local-variable{color:#963}
+.CodeRay .octal{color:#40e}
+.CodeRay .predefined{color:#369}
+.CodeRay .preprocessor{color:#579}
+.CodeRay .pseudo-class{color:#555}
+.CodeRay .directive{font-weight:bold}
+.CodeRay .type{font-weight:bold}
+.CodeRay .predefined-type{color:inherit}
+.CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold}
+.CodeRay .key{color:#808}
+.CodeRay .key .delimiter{color:#606}
+.CodeRay .key .char{color:#80f}
+.CodeRay .value{color:#088}
+.CodeRay .regexp .delimiter{color:#808}
+.CodeRay .regexp .content{color:#808}
+.CodeRay .regexp .modifier{color:#808}
+.CodeRay .regexp .char{color:#d14}
+.CodeRay .regexp .function{color:#404;font-weight:bold}
+.CodeRay .string{color:#d20}
+.CodeRay .string .string .string{background:#ffd0d0}
+.CodeRay .string .content{color:#d14}
+.CodeRay .string .char{color:#d14}
+.CodeRay .string .delimiter{color:#d14}
+.CodeRay .shell{color:#d14}
+.CodeRay .shell .delimiter{color:#d14}
+.CodeRay .symbol{color:#990073}
+.CodeRay .symbol .content{color:#a60}
+.CodeRay .symbol .delimiter{color:#630}
+.CodeRay .tag{color:#008080}
+.CodeRay .tag-special{color:#d70}
+.CodeRay .variable{color:#036}
+.CodeRay .insert{background:#afa}
+.CodeRay .delete{background:#faa}
+.CodeRay .change{color:#aaf;background:#007}
+.CodeRay .head{color:#f8f;background:#505}
+.CodeRay .insert .insert{color:#080}
+.CodeRay .delete .delete{color:#800}
+.CodeRay .change .change{color:#66f}
+.CodeRay .head .head{color:#f4f}
+</style>
+</head>
+<body class="article">
+<div id="header">
+<div id="toc" class="toc">
+<div id="toctitle">Table of Contents</div>
+<ul class="sectlevel1">
+<li><a href="#_accessing_more_io">1. Accessing More I/O</a>
+<ul class="sectlevel2">
+<li><a href="#_editing_bootuenv_txt_to_access_the_p8_header_on_the_black">1.1. Editing /boot/uEnv.txt to Access the P8 Header on the Black</a></li>
+<li><a href="#_accessing_gpio">1.2. Accessing gpio</a></li>
+<li><a href="#io_uio">1.3. Configuring for UIO Instead of RemoteProc</a></li>
+<li><a href="#_converting_pasm_assembly_code_to_clpru">1.4. Converting pasm Assembly Code to clpru</a></li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<div id="content">
+<div class="paragraph">
+<p><a href="../index.html">Outline</a></p>
+</div>
+<div class="sect1">
+<h2 id="_accessing_more_io"><a class="link" href="#_accessing_more_io">1. Accessing More I/O</a></h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>So far the examples have shown how to access the GPIO pins on the BeagleBone Black&#8217;s
+<code>P9</code> header and through the <code>__R30</code> register.  Below shows how more GPIO pins
+can be accessed.</p>
+</div>
+<div class="paragraph">
+<p>The following are resources used in this chapter.</p>
+</div>
+<div class="ulist">
+<div class="title">Resources</div>
+<ul>
+<li>
+<p><a href="https://github.com/derekmolloy/exploringBB/blob/master/chp06/docs/BeagleboneBlackP8HeaderTable.pdf">P8 Header Table</a></p>
+</li>
+<li>
+<p><a href="https://github.com/derekmolloy/exploringBB/blob/master/chp06/docs/BeagleboneBlackP9HeaderTable.pdf">P9 Header Table</a></p>
+</li>
+<li>
+<p><a href="http://www.ti.com/lit/pdf/spruhz6l">AM572x Technical Reference Manual</a> (AI)</p>
+</li>
+<li>
+<p><a href="http://www.ti.com/lit/pdf/spruh73">AM335x Technical Reference Manual</a> (All others)</p>
+</li>
+<li>
+<p><a href="http://www.ti.com/lit/ug/spruhv6a/spruhv6a.pdf">PRU Assembly Language Tools</a></p>
+</li>
+</ul>
+</div>
+<div class="sect2">
+<h3 id="_editing_bootuenv_txt_to_access_the_p8_header_on_the_black"><a class="link" href="#_editing_bootuenv_txt_to_access_the_p8_header_on_the_black">1.1. Editing /boot/uEnv.txt to Access the P8 Header on the Black</a></h3>
+<div class="sect3">
+<h4 id="_problem"><a class="link" href="#_problem">Problem</a></h4>
+<div class="paragraph">
+<p>When I try to configure some pins on the <code>P8</code> header of the Black I get an error.</p>
+</div>
+<div class="listingblock">
+<div class="title">config-pin</div>
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">bone$ <strong>config-pin P8_28 pruout</strong>
+ERROR: open() for /sys/devices/platform/ocp/ocp:P8_28_pinmux/state failed, No such file or directory</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_solution"><a class="link" href="#_solution">Solution</a></h4>
+<div class="paragraph">
+<p>On the images for the BeagleBone Black, the HDMI display driver is enabled by
+default and uses many of the <code>P8</code> pins.  If you are not using
+HDMI video (or the HDI audio, or even the eMMC) you can disable it by editing
+<code>/boot/uEnv.txt</code></p>
+</div>
+<div class="paragraph">
+<p>Open <code>/boot/uEnv.txt</code> and scroll down aways until you see:</p>
+</div>
+<div class="listingblock">
+<div class="title">/boot/uEnv.txt</div>
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">###Disable auto loading of virtual capes (emmc/video/wireless/adc)
+#disable_uboot_overlay_emmc=1
+disable_uboot_overlay_video=1
+#disable_uboot_overlay_audio=1</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Uncomment the lines that correspond to the devices you want to disable and
+free up their pins.</p>
+</div>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<div class="title">Tip</div>
+</td>
+<td class="content">
+<div class="paragraph">
+<p><a href="https://github.com/derekmolloy/exploringBB/blob/master/chp06/docs/BeagleboneBlackP8HeaderTable.pdf">P8 Header Table</a>
+shows what pins are allocated for what.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>Save the file and reboot.  You now have access to the <code>P8</code> pins.</p>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_accessing_gpio"><a class="link" href="#_accessing_gpio">1.2. Accessing gpio</a></h3>
+<div class="sect3">
+<h4 id="_problem_2"><a class="link" href="#_problem_2">Problem</a></h4>
+<div class="paragraph">
+<p>I&#8217;ve used up all the GPIO in <code>__R30</code>, where can I get more?</p>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_solution_2"><a class="link" href="#_solution_2">Solution</a></h4>
+<div class="paragraph">
+<p>So far we have focused on using PRU 0.
+<a href="../05blocks/blocks.html#blocks_mapping_bits">Mapping bit positions to pin names
+PRU</a> shows
+that PRU 0 can access ten GPIO pins on the BeagleBone Black.  If you use
+PRU 1 you can get to an additional 14 pins (if they aren&#8217;t in use for other things.)</p>
+</div>
+<div class="paragraph">
+<p>What if you need even more GPIO pins? You can access <em>any</em> GPIO pin by going
+through the <strong>O</strong>pen-<strong>C</strong>ore <strong>P</strong>rotocol (OCP) port.</p>
+</div>
+<div class="paragraph">
+<div class="title">PRU Integration</div>
+<p><span class="image"><img src="figures/pruIntegration.png" alt="PRU Integration"></span></p>
+</div>
+<div class="paragraph">
+<p>The figure above shows we&#8217;ve been using the <em>Enhanced GPIO</em> interface when using
+<code>__R30</code>, but it also shows you can use the OCP.  You get access to many more
+GPIO pins, but it&#8217;s a slower access.</p>
+</div>
+<div class="listingblock">
+<div class="title">gpio.pru0.c</div>
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="c"><table class="CodeRay"><tr>
+  <td class="line-numbers"><pre>1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+</pre></td>
+  <td class="code"><pre><span class="comment">// This code accesses GPIO without using R30 and R31</span>
+<span class="preprocessor">#include</span> <span class="include">&lt;stdint.h&gt;</span>
+<span class="preprocessor">#include</span> <span class="include">&lt;pru_cfg.h&gt;</span>
+<span class="preprocessor">#include</span> <span class="include">&quot;resource_table_empty.h&quot;</span>
+<span class="preprocessor">#include</span> <span class="include">&quot;prugpio.h&quot;</span>
+
+<span class="preprocessor">#define</span> P9_11   (<span class="hex">0x1</span>&lt;&lt;<span class="integer">30</span>)           <span class="comment">// Bit position tied to P9_11 on Black</span>
+<span class="preprocessor">#define</span> P2_05   (<span class="hex">0x1</span>&lt;&lt;<span class="integer">30</span>)           <span class="comment">// Bit position tied to P2_05 on Pocket</span>
+
+<span class="directive">volatile</span> <span class="directive">register</span> uint32_t __R30;
+<span class="directive">volatile</span> <span class="directive">register</span> uint32_t __R31;
+
+<span class="directive">void</span> main(<span class="directive">void</span>)
+{
+    uint32_t *gpio0 = (uint32_t *)GPIO0;
+
+    <span class="keyword">while</span>(<span class="integer">1</span>) {
+        gpio0[GPIO_SETDATAOUT]   = P9_11;
+        __delay_cycles(<span class="integer">100000000</span>);
+        gpio0[GPIO_CLEARDATAOUT] = P9_11;
+        __delay_cycles(<span class="integer">100000000</span>);
+    }
+}</pre></td>
+</tr></table></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>This code will toggle <code>P9_11</code> on and off. Here&#8217;s the setup file.</p>
+</div>
+<div class="listingblock">
+<div class="title">setup.sh</div>
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash"><table class="CodeRay"><tr>
+  <td class="line-numbers"><pre>1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+</pre></td>
+  <td class="code"><pre>#!/bin/bash
+
+export TARGET=gpio.pru0
+echo TARGET=$TARGET
+
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = &quot;Black&quot; ]; then
+    echo &quot; Found&quot;
+    pins=&quot;P9_11&quot;
+elif [ $machine = &quot;Blue&quot; ]; then
+    echo &quot; Found&quot;
+    pins=&quot;&quot;
+elif [ $machine = &quot;PocketBeagle&quot; ]; then
+    echo &quot; Found&quot;
+    pins=&quot;P2_05&quot;
+else
+    echo &quot; Not Found&quot;
+    pins=&quot;&quot;
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin gpio
+    config-pin -q $pin
+done</pre></td>
+</tr></table></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Notice in the code <code>config-pin</code> set <code>P9_11</code> to <code>gpio</code>, not <code>pruout</code>. This is because
+are are using the OCP interface to the pin, not the usual PRU interface.</p>
+</div>
+<div class="paragraph">
+<p>Set your exports and make.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">bone$ <strong>source setup.sh</strong>
+TARGET=gpio.pru0
+...
+bone$ <strong>make</strong>
+/var/lib/cloud9/common/Makefile:29: MODEL=TI_AM335x_BeagleBone_Black,TARGET=gpio.pru0
+-    Stopping PRU 0
+-   copying firmware file /tmp/cloud9-examples/gpio.pru0.out to /lib/firmware/am335x-pru0-fw
+write_init_pins.sh
+-    Starting PRU 0
+MODEL   = TI_AM335x_BeagleBone_Black
+PROC    = pru
+PRUN    = 0
+PRU_DIR = /sys/class/remoteproc/remoteproc1</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_discussion"><a class="link" href="#_discussion">Discussion</a></h4>
+<div class="paragraph">
+<p>When you run the code you see <code>P9_11</code> toggling on and off.  Let&#8217;s go through
+the code line-by-line to see what&#8217;s happening.</p>
+</div>
+<table class="tableblock frame-all grid-all stretch">
+<caption class="title">Table 1. gpio.pru0.c line-by-line</caption>
+<colgroup>
+<col style="width: 10%;">
+<col style="width: 90%;">
+</colgroup>
+<thead>
+<tr>
+<th class="tableblock halign-left valign-top">Line</th>
+<th class="tableblock halign-left valign-top">Explanation</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">2-5</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">Standard includes</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">5</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">The AM335x has four 32-bit GPIO ports.  Lines 55-58 of <code>prugpio.h</code> define the addresses
+for each of the ports.  You can find these in Table 2-2 page 180 of the
+<a href="https://www.ti.com/lit/ug/spruh73p/spruh73p.pdf">AM335x Technical Reference Manual</a>.
+Look up <code>P9_11</code> in the <a href="https://github.com/derekmolloy/exploringBB/blob/master/chp06/docs/BeagleboneBlackP9HeaderTable.pdf">P9 Header Table</a>.
+Under the <em>Mode7</em> column you see <code>gpio0[30]</code>.  This means <code>P9_11</code> is bit 30
+on GPIO port 0.  Therefore we will use <code>GPIO0</code> in this code.</p>
+<p class="tableblock">You can also run
+<code>gpioinfo</code> and look for P9_11.</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">5</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">Line 103 of <code>prugpio.h</code> defines the address offset from <code>GIO0</code> that will
+allow us to <em>clear</em>
+any (or all) bits in GPIO port 0. Other architectures require you to read a port,
+then change some bit, then write it out again, three steps.  Here we can do the same by writing to one location, just one step.</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">5</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">Line 104 of <code>prugpio.h</code> is like above, but for <em>setting</em> bits.</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">5</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">Using this offset  of line 105 of <code>prugpio.h</code> lets us just read the bits
+without changing them.</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">7,8</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">This shifts <code>0x1</code> to the 30<sup>th</sup> bit position, which is the one corresponding
+to <code>P9_11</code>.</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">15</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">Here we initialize <code>gpio0</code> to point to the start of GPIO port 0&#8217;s control
+registers.</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">18</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><code>gpio0[GPIO_SETDATAOUT]</code> refers to the <code>SETDATAOUT</code> register of port 0.
+Writing to this register turns on the bits where 1&#8217;s are written,
+but leaves alone the bits where 0&#8217;s are.</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">19</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">Wait 100,000,000 cycles, which is 0.5 seconds.</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">20</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">This is line 18, but the output bit is set to 0 where 1&#8217;s are written.</p></td>
+</tr>
+</tbody>
+</table>
+<div class="sect4">
+<h5 id="_how_fast_can_it_go"><a class="link" href="#_how_fast_can_it_go">How fast can it go?</a></h5>
+<div class="paragraph">
+<p>This approach to GPIO goes through the slower OCP interface.  If you set <code>__delay_cycles(0)</code> you can see how fast it is.</p>
+</div>
+<div class="paragraph">
+<div class="title">gpio.pru0.c with __delay_cycles(0)</div>
+<p><span class="image"><img src="figures/gpio0delay.png" alt="gpio.pru0.c with __delay_cycles(0)"></span></p>
+</div>
+<div class="paragraph">
+<p>The period is 80ns which is 12.MHz.  That&#8217;s about one forth the speed of the
+<code>__R30</code> method, but still not bad.</p>
+</div>
+<div class="paragraph">
+<p>If you are using an oscilloscope, look closely and you&#8217;ll see the following.</p>
+</div>
+<div class="paragraph">
+<div class="title">PWM with jitter</div>
+<p><span class="image"><img src="figures/jitter.png" alt="PWM with jitter"></span></p>
+</div>
+<div class="paragraph">
+<p>The PRU is still as solid as before in it&#8217;s timing, but now it&#8217;s going through
+the OCP interface.  This interface is shared with other parts of the system,
+therefore the sometimes the PRU must wait for the other parts to finish.
+When this happens the pulse width is a bit longer than usual thus adding
+jitter to the output.</p>
+</div>
+<div class="paragraph">
+<p>For many applications a few nanoseconds of jitter is unimportant and this
+GPIO interface can be used.  If your application needs better timing,
+use the <code>__R30</code> interface.</p>
+</div>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="io_uio"><a class="link" href="#io_uio">1.3. Configuring for UIO Instead of RemoteProc</a></h3>
+<div class="sect3">
+<h4 id="_problem_3"><a class="link" href="#_problem_3">Problem</a></h4>
+<div class="paragraph">
+<p>You have some legacy PRU code that uses UIO instead of remoteproc and
+you want to switch to UIO.</p>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_solution_3"><a class="link" href="#_solution_3">Solution</a></h4>
+<div class="paragraph">
+<p>Edit <code>/boot/uEnt.txt</code> and search for <code>uio</code>.  I find</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre>###pru_uio (4.4.x-ti, 4.9.x-ti, 4.14.x-ti &amp; mainline/bone kernel)
+uboot_overlay_pru=/lib/firmware/AM335X-PRU-UIO-00A0.dtbo</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Uncomment the <code>uboot</code> line.  Look for other lines with
+<code>uboot_overlay_pru=</code> and be sure they are commented out.</p>
+</div>
+<div class="paragraph">
+<p>Reboot your Bone.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre>bone$ <strong>sudo reboot</strong></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Check that UIO is running.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre>bone$ <strong>lsmod | grep uio</strong>
+uio_pruss              16384  0
+uio_pdrv_genirq        16384  0
+uio                    20480  2 uio_pruss,uio_pdrv_genirq</pre>
+</div>
+</div>
+<div class="paragraph">
+<p>You are now ready to run the legacy PRU code.</p>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_converting_pasm_assembly_code_to_clpru"><a class="link" href="#_converting_pasm_assembly_code_to_clpru">1.4. Converting pasm Assembly Code to clpru</a></h3>
+<div class="sect3">
+<h4 id="_problem_4"><a class="link" href="#_problem_4">Problem</a></h4>
+<div class="paragraph">
+<p>You have some legacy assembly code written in pasm and it won&#8217;t assemble
+with clpru.</p>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_solution_4"><a class="link" href="#_solution_4">Solution</a></h4>
+<div class="paragraph">
+<p>Generally there is a simple mapping from pasm to clpru.
+<a href="http://processors.wiki.ti.com/index.php/PRU_Assembly_Instructions#pasm_vs._clpru">pasm vs. clpru</a>
+notes what needs to be changed. I have a less complete version on my
+<a href="https://elinux.org/EBC_Exercise_30_PRU_porting_pasm_to_clpru">eLinux.org site</a>.</p>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_discussion_2"><a class="link" href="#_discussion_2">Discussion</a></h4>
+<div class="paragraph">
+<p>The clpru assembly can be found in <a href="http://www.ti.com/lit/ug/spruhv6a/spruhv6a.pdf">PRU Assembly Language Tools</a>.</p>
+</div>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2021-08-04 14:38:24 -0400
+</div>
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/pru-cookbook/06io/io.rst b/pru-cookbook/06io/io.rst
new file mode 100644
index 0000000000000000000000000000000000000000..3548d5e0a4330f10a7a06d4f94856bac5ba1a89c
--- /dev/null
+++ b/pru-cookbook/06io/io.rst
@@ -0,0 +1,271 @@
+.. _pru-cookbook-io:
+
+Accessing More I/O
+####################
+
+So far the examples have shown how to access the GPIO pins on the BeagleBone Black's 
+``P9`` header and through the ``pass:[__]R30`` register.  Below shows how more GPIO pins
+can be accessed.
+
+The following are resources used in this chapter.
+
+Resources
+~~~~~~~~~~
+
+* `P8 Header Table <https://github.com/derekmolloy/exploringBB/blob/master/chp06/docs/BeagleboneBlackP8HeaderTable.pdf>`_
+* `P9 Header Table <https://github.com/derekmolloy/exploringBB/blob/master/chp06/docs/BeagleboneBlackP9HeaderTable.pdf>`_
+* `AM572x Technical Reference Manual<http://www.ti.com/lit/pdf/spruhz6l>`_ (AI)
+* `AM335x Technical Reference Manual <http://www.ti.com/lit/pdf/spruh73>`_ (All others)
+* `PRU Assembly Language Tools<http://www.ti.com/lit/ug/spruhv6a/spruhv6a.pdf>`_
+
+Editing /boot/uEnv.txt to Access the P8 Header on the Black
+============================================================
+
+Problem
+--------
+
+When I try to configure some pins on the `P8` header of the Black I get an error.
+
+config-pin
+~~~~~~~~~~~
+
+.. code-block:: bash
+    :linenos:
+
+    bone$ *config-pin P8_28 pruout*
+    ERROR: open() for /sys/devices/platform/ocp/ocp:P8_28_pinmux/state failed, No such file or directory
+
+Solution
+--------
+
+On the images for the BeagleBone Black, the HDMI display driver is enabled by default 
+and uses many of the ``P8`` pins.  If you are not using HDMI video (or the HDI audio, 
+or even the eMMC) you can disable it by editing ``/boot/uEnv.txt``
+
+Open ``/boot/uEnv.txt`` and scroll down aways until you see:
+
+/boot/uEnv.txt
+~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+    :linenos:
+
+    ###Disable auto loading of virtual capes (emmc/video/wireless/adc)
+    #disable_uboot_overlay_emmc=1
+    disable_uboot_overlay_video=1
+    #disable_uboot_overlay_audio=1
+
+Uncomment the lines that correspond to the devices you want to disable and free up their pins.  
+
+.. tip::
+
+    `P8 Header Table <https://github.com/derekmolloy/exploringBB/blob/master/chp06/docs/BeagleboneBlackP8HeaderTable.pdf>`_
+    shows what pins are allocated for what.
+
+Save the file and reboot.  You now have access to the ``P8`` pins.
+
+Accessing gpio
+================
+
+Problem
+--------
+
+I've used up all the GPIO in ``pass:[__]R30``, where can I get more?
+
+Solution
+--------
+
+So far we have focused on using PRU 0.  
+:ref:`../05blocks/blocks.html#blocks_mapping_bits,Mapping bit positions to pin names PRU` shows 
+that PRU 0 can access ten GPIO pins on the BeagleBone Black.  If you use
+PRU 1 you can get to an additional 14 pins (if they aren't in use for other things.)
+
+What if you need even more GPIO pins? You can access **any** GPIO pin by going
+through the **O**pen-**C**ore **P**rotocol (OCP) port.
+
+PRU Integration
+~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/pruIntegration.png
+    :align: center
+    :alt: PRU Integration
+
+The figure above shows we've been using the _Enhanced **GPIO** interface when using
+``pass:[__]R30``, but it also shows you can use the OCP.  You get access to many more
+GPIO pins, but it's a slower access.
+
+gpio.pru0.c
+~~~~~~~~~~~~
+
+:download:`gpio.pru0.c <code/gpio.pru0.c>`
+
+This code will toggle ``P9_11`` on and off. Here's the setup file.
+
+setup.sh
+~~~~~~~~~
+
+:download:`setup.sh <code/setup.sh>`
+
+Notice in the code ``config-pin`` set ``P9_11`` to ``gpio``, not ``pruout``. This is because
+are are using the OCP interface to the pin, not the usual PRU interface.
+
+Set your exports and make.
+
+.. code-block:: bash
+    :linenos:
+
+    bone$ *source setup.sh*
+    TARGET=gpio.pru0
+    ...
+    bone$ *make*
+    /var/lib/cloud9/common/Makefile:29: MODEL=TI_AM335x_BeagleBone_Black,TARGET=gpio.pru0
+    -    Stopping PRU 0
+    -	copying firmware file /tmp/cloud9-examples/gpio.pru0.out to /lib/firmware/am335x-pru0-fw
+    write_init_pins.sh
+    -    Starting PRU 0
+    MODEL   = TI_AM335x_BeagleBone_Black
+    PROC    = pru
+    PRUN    = 0
+    PRU_DIR = /sys/class/remoteproc/remoteproc1
+
+Discussion
+-----------
+
+When you run the code you see ``P9_11`` toggling on and off.  Let's go through
+the code line-by-line to see what's happening.
+
+gpio.pru0.c line-by-line
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+    +-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
+    |Line   |   Explanation                                                                                                                                 |
+    +=======+===============================================================================================================================================+
+    |2-5    |   Standard includes                                                                                                                           |
+    +-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
+    |5      |   The AM335x has four 32-bit GPIO ports.  Lines 55-58 of `prugpio.h` define the addresses                                                     |
+    |       |   for each of the ports.  You can find these in Table 2-2 page 180 of the                                                                     |
+    |       |   https://www.ti.com/lit/ug/spruh73p/spruh73p.pdf[AM335x Technical Reference Manual].                                                         |
+    |       |   Look up `P9_11` in the https://github.com/derekmolloy/exploringBB/blob/master/chp06/docs/BeagleboneBlackP9HeaderTable.pdf[P9 Header Table]. |
+    |       |   Under the _Mode7_ column you see `gpio0[30]`.  This means `P9_11` is bit 30                                                                 |
+    |       |   on GPIO port 0.  Therefore we will use `GPIO0` in this code. You can also run ``gpioinfo`` and look for P9_11.                              |
+    +-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
+    |5      |   Line 103 of `prugpio.h` defines the address offset from `GIO0` that will allow us to _clear_ any (or all) bits in GPIO port 0.              |
+    |       |   Other architectures require you to read a port, then change some bit, then write it out again, three steps.  Here we can do                 |
+    |       |   the same by writing to one location, just one step.                                                                                         |
+    +-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
+    |5      |Line 104 of `prugpio.h` is like above, but for _setting_ bits.                                                                                 |
+    +-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
+    |5      |Using this offset  of line 105 of `prugpio.h` lets us just read the bits without changing them.                                                |
+    +-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
+    |7,8    |This shifts `0x1` to the 30^th^ bit position, which is the one corresponding to `P9_11`.                                                       |
+    +-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
+    |15     |Here we initialize `gpio0` to point to the start of GPIO port 0's control registers.                                                           |
+    +-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
+    |18     |`gpio0[GPIO_SETDATAOUT]` refers to the `SETDATAOUT` register of port 0. Writing to this register turns on the bits                             |
+    |       |   where 1's are written, but leaves alone the bits where 0's are.                                                                             |
+    +-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
+    |19     |Wait 100,000,000 cycles, which is 0.5 seconds.                                                                                                 |
+    +-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
+    |20     |This is line 18, but the output bit is set to 0 where 1's are written.                                                                         |
+    +-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
+
+How fast can it go?
+~~~~~~~~~~~~~~~~~~~~
+
+This approach to GPIO goes through the slower OCP interface.  If you set 
+``pass:[__]delay_cycles(0)`` you can see how fast it is.
+
+gpio.pru0.c with pass:[__]delay_cycles(0)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/gpio0delay.png
+    :align: center
+    :alt: gpio.pru0.c with pass:[__]delay_cycles(0)
+
+The period is 80ns which is 12.MHz.  That's about one forth the speed of the
+``pass:[__]R30`` method, but still not bad.
+
+If you are using an oscilloscope, look closely and you'll see the following.
+
+PWM with jitter
+~~~~~~~~~~~~~~~~
+
+.. figure:: figures/jitter.png
+    :align: center
+    :alt: PWM with jitter
+
+The PRU is still as solid as before in it's timing, but now it's going through
+the OCP interface.  This interface is shared with other parts of the system,
+therefore the sometimes the PRU must wait for the other parts to finish.  
+When this happens the pulse width is a bit longer than usual thus adding
+jitter to the output.
+
+For many applications a few nanoseconds of jitter is unimportant and this
+GPIO interface can be used.  If your application needs better timing,
+use the ``pass:[__]R30`` interface.
+ 
+
+.. _io_uio:
+
+Configuring for UIO Instead of RemoteProc
+========================================
+
+Problem
+--------
+
+You have some legacy PRU code that uses UIO instead of remoteproc and
+you want to switch to UIO.
+
+Solution
+--------
+
+Edit ``/boot/uEnt.txt`` and search for ``uio``.  I find
+
+.. code-block:: bash
+
+    ###pru_uio (4.4.x-ti, 4.9.x-ti, 4.14.x-ti & mainline/bone kernel)
+    uboot_overlay_pru=/lib/firmware/AM335X-PRU-UIO-00A0.dtbo
+
+Uncomment the ``uboot`` line.  Look for other lines with
+``uboot_overlay_pru=`` and be sure they are commented out.
+
+Reboot your Bone.
+
+.. code-block:: bash
+
+    bone$ sudo reboot
+
+Check that UIO is running.
+
+.. code-block:: bash
+
+    bone$ lsmod | grep uio
+    uio_pruss              16384  0
+    uio_pdrv_genirq        16384  0
+    uio                    20480  2 uio_pruss,uio_pdrv_genirq
+
+You are now ready to run the legacy PRU code.
+
+Converting pasm Assembly Code to clpru
+========================================
+
+Problem
+--------
+
+You have some legacy assembly code written in pasm and it won't assemble with clpru.
+
+Solution
+--------
+
+Generally there is a simple mapping from pasm to clpru. 
+`pasm vs. clpru <http://processors.wiki.ti.com/index.php/PRU_Assembly_Instructions#pasm_vs._clpru>`_
+notes what needs to be changed. I have a less complete version on my
+`eLinux.org site <https://elinux.org/EBC_Exercise_30_PRU_porting_pasm_to_clpru>`_.
+
+Discussion
+--------
+
+The clpru assembly can be found in 
+`PRU Assembly Language Tools <http://www.ti.com/lit/ug/spruhv6a/spruhv6a.pdf>`_.
diff --git a/pru-cookbook/07more/code/Makefile b/pru-cookbook/07more/code/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a7557fdaa22988d89cec879477ded78522d7116f
--- /dev/null
+++ b/pru-cookbook/07more/code/Makefile
@@ -0,0 +1 @@
+include /var/lib/cloud9/common/Makefile
diff --git a/pru-cookbook/07more/code/copyright.c b/pru-cookbook/07more/code/copyright.c
new file mode 100644
index 0000000000000000000000000000000000000000..63b6a419e4ee3a2767de3fcec0c29e74e3754700
--- /dev/null
+++ b/pru-cookbook/07more/code/copyright.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *	* Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ *
+ *	* Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the
+ *	  distribution.
+ *
+ *	* Neither the name of Texas Instruments Incorporated nor the names of
+ *	  its contributors may be used to endorse or promote products derived
+ *	  from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
\ No newline at end of file
diff --git a/pru-cookbook/07more/code/cycle.pru0.c b/pru-cookbook/07more/code/cycle.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..73055d9f0662483f6e9cc03ef266b670f571e1f0
--- /dev/null
+++ b/pru-cookbook/07more/code/cycle.pru0.c
@@ -0,0 +1,32 @@
+// Access the CYCLE and STALL registers
+#include <stdint.h>
+#include <pru_cfg.h>
+#include <pru_ctrl.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t gpio = P9_31;	// Select which pin to toggle.;
+
+	// These will be kept in registers and never witten to DRAM
+	uint32_t cycle, stall;
+
+	// Clear SYSCFG[STANDBY_INIT] to enable OCP master port
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+	
+	PRU0_CTRL.CTRL_bit.CTR_EN = 1;	// Enable cycle counter
+
+	__R30 |= gpio;				// Set the GPIO pin to 1
+	// Reset cycle counter, cycle is on the right side to force the compiler
+	// to put it in it's own register
+	PRU0_CTRL.CYCLE = cycle;
+	__R30 &= ~gpio;				// Clear the GPIO pin
+	cycle = PRU0_CTRL.CYCLE;	// Read cycle and store in a register
+	stall = PRU0_CTRL.STALL;	// Ditto for stall
+
+	__halt();
+}
diff --git a/pru-cookbook/07more/code/cycle.pru0.lst b/pru-cookbook/07more/code/cycle.pru0.lst
new file mode 100644
index 0000000000000000000000000000000000000000..7f013a717a25159015a03849db88cf37db123d08
--- /dev/null
+++ b/pru-cookbook/07more/code/cycle.pru0.lst
@@ -0,0 +1,3082 @@
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE    1
+
+       1;******************************************************************************
+       2;* PRU C/C++ Codegen                                              Unix v2.1.5 *
+       3;* Date/Time created: Fri Jun  5 14:14:07 2020                                *
+       4;******************************************************************************
+       5        .compiler_opts --abi=eabi --endian=little --hll_source=on --object_format=elf --silicon_versio
+       6
+       7$C$DW$CU        .dwtag  DW_TAG_compile_unit
+       8        .dwattr $C$DW$CU, DW_AT_name("cycle.pru0.c")
+       9        .dwattr $C$DW$CU, DW_AT_producer("TI PRU C/C++ Codegen Unix v2.1.5 Copyright (c) 2012-2017 Tex
+      10        .dwattr $C$DW$CU, DW_AT_TI_version(0x01)
+      11        .dwattr $C$DW$CU, DW_AT_comp_dir("/home/debian/PRUCookbook/docs/07more/code")
+      12        .global __PRU_CREG_PRU_CFG
+      13
+      14$C$DW$1 .dwtag  DW_TAG_subprogram, DW_AT_name("__halt")
+      15        .dwattr $C$DW$1, DW_AT_TI_symbol_name("__halt")
+      16        .dwattr $C$DW$1, DW_AT_declaration
+      17        .dwattr $C$DW$1, DW_AT_external
+      18        .weak   ||CT_CFG||
+      19 00000000                 ||CT_CFG||:     .usect  ".creg.PRU_CFG.noload.near",68,1
+      20$C$DW$2 .dwtag  DW_TAG_variable, DW_AT_name("CT_CFG")
+      21        .dwattr $C$DW$2, DW_AT_TI_symbol_name("CT_CFG")
+      22        .dwattr $C$DW$2, DW_AT_location[DW_OP_addr ||CT_CFG||]
+      23        .dwattr $C$DW$2, DW_AT_type(*$C$DW$T$98)
+      24        .dwattr $C$DW$2, DW_AT_external
+      25        .dwattr $C$DW$2, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru_
+      26        .dwattr $C$DW$2, DW_AT_decl_line(0xf2)
+      27        .dwattr $C$DW$2, DW_AT_decl_column(0x17)
+      28        .global ||pru_remoteproc_ResourceTable||
+      29 00000000                         .sect   ".resource_table:retain", RW
+      30        .retain
+      31        .align  1
+      32        .elfsym ||pru_remoteproc_ResourceTable||,SYM_SIZE(20)
+      33 00000000                 ||pru_remoteproc_ResourceTable||:
+      34 00000000 00000000000001          .bits   1,32                    ; pru_remoteproc_ResourceTable.base.ver @ 0
+      35 00000004 00000000000000          .bits   0,32                    ; pru_remoteproc_ResourceTable.base.num @ 32
+      36 00000008 00000000000000          .bits   0,32                    ; pru_remoteproc_ResourceTable.base.reserved[0] @ 64
+      37 0000000c 00000000000000          .bits   0,32                    ; pru_remoteproc_ResourceTable.base.reserved[1] @ 96
+      38 00000010 00000000000000          .bits   0,32                    ; pru_remoteproc_ResourceTable.offset[0] @ 128
+      39
+      40$C$DW$3 .dwtag  DW_TAG_variable, DW_AT_name("pru_remoteproc_ResourceTable")
+      41        .dwattr $C$DW$3, DW_AT_TI_symbol_name("pru_remoteproc_ResourceTable")
+      42        .dwattr $C$DW$3, DW_AT_location[DW_OP_addr ||pru_remoteproc_ResourceTable||]
+      43        .dwattr $C$DW$3, DW_AT_type(*$C$DW$T$92)
+      44        .dwattr $C$DW$3, DW_AT_external
+      45        .dwattr $C$DW$3, DW_AT_decl_file("/var/lib/cloud9/common/resource_table_empty.h")
+      46        .dwattr $C$DW$3, DW_AT_decl_line(0x1f)
+      47        .dwattr $C$DW$3, DW_AT_decl_column(0x1a)
+      48;       optpru /tmp/TI18yQKu8QO /tmp/TI18y6Ruqzt 
+      49;       acpiapru -@/tmp/TI18yH9tQJL 
+      50 00000000                         .sect   ".text:main"
+      51        .clink
+      52        .global ||main||
+      53
+      54$C$DW$4 .dwtag  DW_TAG_subprogram, DW_AT_name("main")
+      55        .dwattr $C$DW$4, DW_AT_low_pc(||main||)
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE    2
+
+      56        .dwattr $C$DW$4, DW_AT_high_pc(0x00)
+      57        .dwattr $C$DW$4, DW_AT_TI_symbol_name("main")
+      58        .dwattr $C$DW$4, DW_AT_external
+      59        .dwattr $C$DW$4, DW_AT_TI_begin_file("cycle.pru0.c")
+      60        .dwattr $C$DW$4, DW_AT_TI_begin_line(0x0d)
+      61        .dwattr $C$DW$4, DW_AT_TI_begin_column(0x06)
+      62        .dwattr $C$DW$4, DW_AT_decl_file("cycle.pru0.c")
+      63        .dwattr $C$DW$4, DW_AT_decl_line(0x0d)
+      64        .dwattr $C$DW$4, DW_AT_decl_column(0x06)
+      65        .dwattr $C$DW$4, DW_AT_TI_max_frame_size(0x00)
+      66        .dwpsn  file "cycle.pru0.c",line 14,column 1,is_stmt,address ||main||,isa 0
+      67
+      68        .dwfde $C$DW$CIE, ||main||
+      69;----------------------------------------------------------------------
+      70;  13 | void main(void)                                                        
+      71;  15 | uint32_t gpio = P9_31;  // Select which pin to toggle.;                
+      72;  17 | // These will be kept in registers and never witten to DRAM            
+      73;  18 | uint32_t cycle, stall;                                                 
+      74;  20 | // Clear SYSCFG[STANDBY_INIT] to enable OCP master port                
+      75;----------------------------------------------------------------------
+      76
+      77;***************************************************************
+      78;* FNAME: main                          FR SIZE:   0           *
+      79;*                                                             *
+      80;* FUNCTION ENVIRONMENT                                        *
+      81;*                                                             *
+      82;* FUNCTION PROPERTIES                                         *
+      83;*                            0 Auto,  0 SOE     *
+      84;***************************************************************
+      85
+      86||main||:
+      87;* --------------------------------------------------------------------------*
+      88;* r0_0  assigned to $O$C1
+      89;* r14_0 assigned to cycle
+      90$C$DW$5 .dwtag  DW_TAG_variable, DW_AT_name("cycle")
+      91        .dwattr $C$DW$5, DW_AT_TI_symbol_name("cycle")
+      92        .dwattr $C$DW$5, DW_AT_type(*$C$DW$T$32)
+      93        .dwattr $C$DW$5, DW_AT_location[DW_OP_regx 0x38]
+      94        .dwcfi  cfa_offset, 0
+      95        .dwpsn  file "cycle.pru0.c",line 21,column 2,is_stmt,isa 0
+      96;----------------------------------------------------------------------
+      97;  21 | CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;                                    
+      98;----------------------------------------------------------------------
+      99 00000000 00000091042080!         LBCO      &r0, __PRU_CREG_PRU_CFG, $CSBREL(||CT_CFG||+4), 4 ; [ALU_PRU] |21| CT_CFG
+     100 00000004 0000001D04E0E0          CLR       r0, r0, 0x00000004    ; [ALU_PRU] |21| 
+     101 00000008 00000081042080!         SBCO      &r0, __PRU_CREG_PRU_CFG, $CSBREL(||CT_CFG||+4), 4 ; [ALU_PRU] |21| CT_CFG
+     102        .dwpsn  file "cycle.pru0.c",line 23,column 2,is_stmt,isa 0
+     103;----------------------------------------------------------------------
+     104;  23 | PRU0_CTRL.CTRL_bit.CTR_EN = 1;  // Enable cycle counter                
+     105;----------------------------------------------------------------------
+     106 0000000c 200080240002C0          LDI32     r0, 0x00022000        ; [ALU_PRU] |23| $O$C1
+     107 00000014 000000F1002081          LBBO      &r1, r0, 0, 4         ; [ALU_PRU] |23| 
+     108 00000018 0000001F03E1E1          SET       r1, r1, 0x00000003    ; [ALU_PRU] |23| 
+     109 0000001c 000000E1002081          SBBO      &r1, r0, 0, 4         ; [ALU_PRU] |23| 
+     110        .dwpsn  file "cycle.pru0.c",line 25,column 2,is_stmt,isa 0
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE    3
+
+     111;----------------------------------------------------------------------
+     112;  25 | __R30 |= gpio;                          // Set the GPIO pin to 1       
+     113;  26 | // Reset cycle counter, cycle is on the right side to force the compile
+     114;     | r                                                                      
+     115;  27 | // to put it in it's own register                                      
+     116;----------------------------------------------------------------------
+     117 00000020 0000001F00FEFE          SET       r30, r30, 0x00000000  ; [ALU_PRU] |25| 
+     118        .dwpsn  file "cycle.pru0.c",line 28,column 2,is_stmt,isa 0
+     119;----------------------------------------------------------------------
+     120;  28 | PRU0_CTRL.CYCLE = cycle;                                               
+     121;----------------------------------------------------------------------
+     122 00000024 000000E10C208E          SBBO      &r14, r0, 12, 4       ; [ALU_PRU] |28| $O$C1,cycle
+     123        .dwpsn  file "cycle.pru0.c",line 29,column 2,is_stmt,isa 0
+     124;----------------------------------------------------------------------
+     125;  29 | __R30 &= ~gpio;                         // Clear the GPIO pin          
+     126;----------------------------------------------------------------------
+     127 00000028 0000001D00FEFE          CLR       r30, r30, 0x00000000  ; [ALU_PRU] |29| 
+     128        .dwpsn  file "cycle.pru0.c",line 30,column 2,is_stmt,isa 0
+     129;----------------------------------------------------------------------
+     130;  30 | cycle = PRU0_CTRL.CYCLE;        // Read cycle and store in a register  
+     131;----------------------------------------------------------------------
+     132 0000002c 000000F10C2081          LBBO      &r1, r0, 12, 4        ; [ALU_PRU] |30| $O$C1
+     133        .dwpsn  file "cycle.pru0.c",line 31,column 2,is_stmt,isa 0
+     134;----------------------------------------------------------------------
+     135;  31 | stall = PRU0_CTRL.STALL;        // Ditto for stall                     
+     136;----------------------------------------------------------------------
+     137 00000030 000000F1102080          LBBO      &r0, r0, 16, 4        ; [ALU_PRU] |31| $O$C1
+     138        .dwpsn  file "cycle.pru0.c",line 33,column 2,is_stmt,isa 0
+     139;----------------------------------------------------------------------
+     140;  33 | __halt();                                                              
+     141;----------------------------------------------------------------------
+     142 00000034 0000002A000000          HALT      ; [ALU_PRU] |33| 
+     143$C$DW$6 .dwtag  DW_TAG_TI_branch
+     144        .dwattr $C$DW$6, DW_AT_low_pc(0x00)
+     145        .dwattr $C$DW$6, DW_AT_TI_return
+     146 00000038 00000020C30000          JMP       r3.w2                 ; [ALU_PRU] 
+     147        .dwattr $C$DW$4, DW_AT_TI_end_file("cycle.pru0.c")
+     148        .dwattr $C$DW$4, DW_AT_TI_end_line(0x22)
+     149        .dwattr $C$DW$4, DW_AT_TI_end_column(0x01)
+     150        .dwendentry
+     151        .dwendtag $C$DW$4
+     152
+     153
+     154;******************************************************************************
+     155;* TYPE INFORMATION                                                           *
+     156;******************************************************************************
+     157
+     158$C$DW$T$19      .dwtag  DW_TAG_structure_type
+     159        .dwattr $C$DW$T$19, DW_AT_byte_size(0x04)
+     160$C$DW$7 .dwtag  DW_TAG_member
+     161        .dwattr $C$DW$7, DW_AT_type(*$C$DW$T$11)
+     162        .dwattr $C$DW$7, DW_AT_name("REVID")
+     163        .dwattr $C$DW$7, DW_AT_TI_symbol_name("REVID")
+     164        .dwattr $C$DW$7, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x20)
+     165        .dwattr $C$DW$7, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE    4
+
+     166        .dwattr $C$DW$7, DW_AT_accessibility(DW_ACCESS_public)
+     167        .dwattr $C$DW$7, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru_
+     168        .dwattr $C$DW$7, DW_AT_decl_line(0x2d)
+     169        .dwattr $C$DW$7, DW_AT_decl_column(0x0d)
+     170        .dwendtag $C$DW$T$19
+     171
+     172        .dwattr $C$DW$T$19, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+     173        .dwattr $C$DW$T$19, DW_AT_decl_line(0x2c)
+     174        .dwattr $C$DW$T$19, DW_AT_decl_column(0x13)
+     175$C$DW$T$48      .dwtag  DW_TAG_volatile_type
+     176        .dwattr $C$DW$T$48, DW_AT_type(*$C$DW$T$19)
+     177
+     178$C$DW$T$20      .dwtag  DW_TAG_structure_type
+     179        .dwattr $C$DW$T$20, DW_AT_byte_size(0x04)
+     180$C$DW$8 .dwtag  DW_TAG_member
+     181        .dwattr $C$DW$8, DW_AT_type(*$C$DW$T$11)
+     182        .dwattr $C$DW$8, DW_AT_name("IDLE_MODE")
+     183        .dwattr $C$DW$8, DW_AT_TI_symbol_name("IDLE_MODE")
+     184        .dwattr $C$DW$8, DW_AT_bit_offset(0x1e), DW_AT_bit_size(0x02)
+     185        .dwattr $C$DW$8, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     186        .dwattr $C$DW$8, DW_AT_accessibility(DW_ACCESS_public)
+     187        .dwattr $C$DW$8, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru_
+     188        .dwattr $C$DW$8, DW_AT_decl_line(0x37)
+     189        .dwattr $C$DW$8, DW_AT_decl_column(0x0d)
+     190$C$DW$9 .dwtag  DW_TAG_member
+     191        .dwattr $C$DW$9, DW_AT_type(*$C$DW$T$11)
+     192        .dwattr $C$DW$9, DW_AT_name("STANDBY_MODE")
+     193        .dwattr $C$DW$9, DW_AT_TI_symbol_name("STANDBY_MODE")
+     194        .dwattr $C$DW$9, DW_AT_bit_offset(0x1c), DW_AT_bit_size(0x02)
+     195        .dwattr $C$DW$9, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     196        .dwattr $C$DW$9, DW_AT_accessibility(DW_ACCESS_public)
+     197        .dwattr $C$DW$9, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru_
+     198        .dwattr $C$DW$9, DW_AT_decl_line(0x38)
+     199        .dwattr $C$DW$9, DW_AT_decl_column(0x0d)
+     200$C$DW$10        .dwtag  DW_TAG_member
+     201        .dwattr $C$DW$10, DW_AT_type(*$C$DW$T$11)
+     202        .dwattr $C$DW$10, DW_AT_name("STANDBY_INIT")
+     203        .dwattr $C$DW$10, DW_AT_TI_symbol_name("STANDBY_INIT")
+     204        .dwattr $C$DW$10, DW_AT_bit_offset(0x1b), DW_AT_bit_size(0x01)
+     205        .dwattr $C$DW$10, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     206        .dwattr $C$DW$10, DW_AT_accessibility(DW_ACCESS_public)
+     207        .dwattr $C$DW$10, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     208        .dwattr $C$DW$10, DW_AT_decl_line(0x39)
+     209        .dwattr $C$DW$10, DW_AT_decl_column(0x0d)
+     210$C$DW$11        .dwtag  DW_TAG_member
+     211        .dwattr $C$DW$11, DW_AT_type(*$C$DW$T$11)
+     212        .dwattr $C$DW$11, DW_AT_name("SUB_MWAIT")
+     213        .dwattr $C$DW$11, DW_AT_TI_symbol_name("SUB_MWAIT")
+     214        .dwattr $C$DW$11, DW_AT_bit_offset(0x1a), DW_AT_bit_size(0x01)
+     215        .dwattr $C$DW$11, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     216        .dwattr $C$DW$11, DW_AT_accessibility(DW_ACCESS_public)
+     217        .dwattr $C$DW$11, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     218        .dwattr $C$DW$11, DW_AT_decl_line(0x3a)
+     219        .dwattr $C$DW$11, DW_AT_decl_column(0x0d)
+     220$C$DW$12        .dwtag  DW_TAG_member
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE    5
+
+     221        .dwattr $C$DW$12, DW_AT_type(*$C$DW$T$11)
+     222        .dwattr $C$DW$12, DW_AT_name("rsvd6")
+     223        .dwattr $C$DW$12, DW_AT_TI_symbol_name("rsvd6")
+     224        .dwattr $C$DW$12, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x1a)
+     225        .dwattr $C$DW$12, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     226        .dwattr $C$DW$12, DW_AT_accessibility(DW_ACCESS_public)
+     227        .dwattr $C$DW$12, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     228        .dwattr $C$DW$12, DW_AT_decl_line(0x3b)
+     229        .dwattr $C$DW$12, DW_AT_decl_column(0x0d)
+     230        .dwendtag $C$DW$T$20
+     231
+     232        .dwattr $C$DW$T$20, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+     233        .dwattr $C$DW$T$20, DW_AT_decl_line(0x36)
+     234        .dwattr $C$DW$T$20, DW_AT_decl_column(0x13)
+     235$C$DW$T$50      .dwtag  DW_TAG_volatile_type
+     236        .dwattr $C$DW$T$50, DW_AT_type(*$C$DW$T$20)
+     237
+     238$C$DW$T$21      .dwtag  DW_TAG_structure_type
+     239        .dwattr $C$DW$T$21, DW_AT_byte_size(0x04)
+     240$C$DW$13        .dwtag  DW_TAG_member
+     241        .dwattr $C$DW$13, DW_AT_type(*$C$DW$T$11)
+     242        .dwattr $C$DW$13, DW_AT_name("PRU0_GPI_MODE")
+     243        .dwattr $C$DW$13, DW_AT_TI_symbol_name("PRU0_GPI_MODE")
+     244        .dwattr $C$DW$13, DW_AT_bit_offset(0x1e), DW_AT_bit_size(0x02)
+     245        .dwattr $C$DW$13, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     246        .dwattr $C$DW$13, DW_AT_accessibility(DW_ACCESS_public)
+     247        .dwattr $C$DW$13, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     248        .dwattr $C$DW$13, DW_AT_decl_line(0x45)
+     249        .dwattr $C$DW$13, DW_AT_decl_column(0x0d)
+     250$C$DW$14        .dwtag  DW_TAG_member
+     251        .dwattr $C$DW$14, DW_AT_type(*$C$DW$T$11)
+     252        .dwattr $C$DW$14, DW_AT_name("PRU0_GPI_CLK_MODE")
+     253        .dwattr $C$DW$14, DW_AT_TI_symbol_name("PRU0_GPI_CLK_MODE")
+     254        .dwattr $C$DW$14, DW_AT_bit_offset(0x1d), DW_AT_bit_size(0x01)
+     255        .dwattr $C$DW$14, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     256        .dwattr $C$DW$14, DW_AT_accessibility(DW_ACCESS_public)
+     257        .dwattr $C$DW$14, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     258        .dwattr $C$DW$14, DW_AT_decl_line(0x46)
+     259        .dwattr $C$DW$14, DW_AT_decl_column(0x0d)
+     260$C$DW$15        .dwtag  DW_TAG_member
+     261        .dwattr $C$DW$15, DW_AT_type(*$C$DW$T$11)
+     262        .dwattr $C$DW$15, DW_AT_name("PRU0_GPI_DIV0")
+     263        .dwattr $C$DW$15, DW_AT_TI_symbol_name("PRU0_GPI_DIV0")
+     264        .dwattr $C$DW$15, DW_AT_bit_offset(0x18), DW_AT_bit_size(0x05)
+     265        .dwattr $C$DW$15, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     266        .dwattr $C$DW$15, DW_AT_accessibility(DW_ACCESS_public)
+     267        .dwattr $C$DW$15, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     268        .dwattr $C$DW$15, DW_AT_decl_line(0x47)
+     269        .dwattr $C$DW$15, DW_AT_decl_column(0x0d)
+     270$C$DW$16        .dwtag  DW_TAG_member
+     271        .dwattr $C$DW$16, DW_AT_type(*$C$DW$T$11)
+     272        .dwattr $C$DW$16, DW_AT_name("PRU0_GPI_DIV1")
+     273        .dwattr $C$DW$16, DW_AT_TI_symbol_name("PRU0_GPI_DIV1")
+     274        .dwattr $C$DW$16, DW_AT_bit_offset(0x13), DW_AT_bit_size(0x05)
+     275        .dwattr $C$DW$16, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE    6
+
+     276        .dwattr $C$DW$16, DW_AT_accessibility(DW_ACCESS_public)
+     277        .dwattr $C$DW$16, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     278        .dwattr $C$DW$16, DW_AT_decl_line(0x48)
+     279        .dwattr $C$DW$16, DW_AT_decl_column(0x0d)
+     280$C$DW$17        .dwtag  DW_TAG_member
+     281        .dwattr $C$DW$17, DW_AT_type(*$C$DW$T$11)
+     282        .dwattr $C$DW$17, DW_AT_name("PRU0_GPI_SB")
+     283        .dwattr $C$DW$17, DW_AT_TI_symbol_name("PRU0_GPI_SB")
+     284        .dwattr $C$DW$17, DW_AT_bit_offset(0x12), DW_AT_bit_size(0x01)
+     285        .dwattr $C$DW$17, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     286        .dwattr $C$DW$17, DW_AT_accessibility(DW_ACCESS_public)
+     287        .dwattr $C$DW$17, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     288        .dwattr $C$DW$17, DW_AT_decl_line(0x49)
+     289        .dwattr $C$DW$17, DW_AT_decl_column(0x0d)
+     290$C$DW$18        .dwtag  DW_TAG_member
+     291        .dwattr $C$DW$18, DW_AT_type(*$C$DW$T$11)
+     292        .dwattr $C$DW$18, DW_AT_name("PRU0_GPO_MODE")
+     293        .dwattr $C$DW$18, DW_AT_TI_symbol_name("PRU0_GPO_MODE")
+     294        .dwattr $C$DW$18, DW_AT_bit_offset(0x11), DW_AT_bit_size(0x01)
+     295        .dwattr $C$DW$18, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     296        .dwattr $C$DW$18, DW_AT_accessibility(DW_ACCESS_public)
+     297        .dwattr $C$DW$18, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     298        .dwattr $C$DW$18, DW_AT_decl_line(0x4a)
+     299        .dwattr $C$DW$18, DW_AT_decl_column(0x0d)
+     300$C$DW$19        .dwtag  DW_TAG_member
+     301        .dwattr $C$DW$19, DW_AT_type(*$C$DW$T$11)
+     302        .dwattr $C$DW$19, DW_AT_name("PRU0_GPO_DIV0")
+     303        .dwattr $C$DW$19, DW_AT_TI_symbol_name("PRU0_GPO_DIV0")
+     304        .dwattr $C$DW$19, DW_AT_bit_offset(0x0c), DW_AT_bit_size(0x05)
+     305        .dwattr $C$DW$19, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     306        .dwattr $C$DW$19, DW_AT_accessibility(DW_ACCESS_public)
+     307        .dwattr $C$DW$19, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     308        .dwattr $C$DW$19, DW_AT_decl_line(0x4b)
+     309        .dwattr $C$DW$19, DW_AT_decl_column(0x0d)
+     310$C$DW$20        .dwtag  DW_TAG_member
+     311        .dwattr $C$DW$20, DW_AT_type(*$C$DW$T$11)
+     312        .dwattr $C$DW$20, DW_AT_name("PRU0_GPO_DIV1")
+     313        .dwattr $C$DW$20, DW_AT_TI_symbol_name("PRU0_GPO_DIV1")
+     314        .dwattr $C$DW$20, DW_AT_bit_offset(0x07), DW_AT_bit_size(0x05)
+     315        .dwattr $C$DW$20, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     316        .dwattr $C$DW$20, DW_AT_accessibility(DW_ACCESS_public)
+     317        .dwattr $C$DW$20, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     318        .dwattr $C$DW$20, DW_AT_decl_line(0x4c)
+     319        .dwattr $C$DW$20, DW_AT_decl_column(0x0d)
+     320$C$DW$21        .dwtag  DW_TAG_member
+     321        .dwattr $C$DW$21, DW_AT_type(*$C$DW$T$11)
+     322        .dwattr $C$DW$21, DW_AT_name("PRU0_GPO_SH_SEL")
+     323        .dwattr $C$DW$21, DW_AT_TI_symbol_name("PRU0_GPO_SH_SEL")
+     324        .dwattr $C$DW$21, DW_AT_bit_offset(0x06), DW_AT_bit_size(0x01)
+     325        .dwattr $C$DW$21, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     326        .dwattr $C$DW$21, DW_AT_accessibility(DW_ACCESS_public)
+     327        .dwattr $C$DW$21, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     328        .dwattr $C$DW$21, DW_AT_decl_line(0x4d)
+     329        .dwattr $C$DW$21, DW_AT_decl_column(0x0d)
+     330$C$DW$22        .dwtag  DW_TAG_member
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE    7
+
+     331        .dwattr $C$DW$22, DW_AT_type(*$C$DW$T$11)
+     332        .dwattr $C$DW$22, DW_AT_name("rsvd26")
+     333        .dwattr $C$DW$22, DW_AT_TI_symbol_name("rsvd26")
+     334        .dwattr $C$DW$22, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x06)
+     335        .dwattr $C$DW$22, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     336        .dwattr $C$DW$22, DW_AT_accessibility(DW_ACCESS_public)
+     337        .dwattr $C$DW$22, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     338        .dwattr $C$DW$22, DW_AT_decl_line(0x4e)
+     339        .dwattr $C$DW$22, DW_AT_decl_column(0x0d)
+     340        .dwendtag $C$DW$T$21
+     341
+     342        .dwattr $C$DW$T$21, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+     343        .dwattr $C$DW$T$21, DW_AT_decl_line(0x44)
+     344        .dwattr $C$DW$T$21, DW_AT_decl_column(0x13)
+     345$C$DW$T$52      .dwtag  DW_TAG_volatile_type
+     346        .dwattr $C$DW$T$52, DW_AT_type(*$C$DW$T$21)
+     347
+     348$C$DW$T$22      .dwtag  DW_TAG_structure_type
+     349        .dwattr $C$DW$T$22, DW_AT_byte_size(0x04)
+     350$C$DW$23        .dwtag  DW_TAG_member
+     351        .dwattr $C$DW$23, DW_AT_type(*$C$DW$T$11)
+     352        .dwattr $C$DW$23, DW_AT_name("PRU1_GPI_MODE")
+     353        .dwattr $C$DW$23, DW_AT_TI_symbol_name("PRU1_GPI_MODE")
+     354        .dwattr $C$DW$23, DW_AT_bit_offset(0x1e), DW_AT_bit_size(0x02)
+     355        .dwattr $C$DW$23, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     356        .dwattr $C$DW$23, DW_AT_accessibility(DW_ACCESS_public)
+     357        .dwattr $C$DW$23, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     358        .dwattr $C$DW$23, DW_AT_decl_line(0x58)
+     359        .dwattr $C$DW$23, DW_AT_decl_column(0x0d)
+     360$C$DW$24        .dwtag  DW_TAG_member
+     361        .dwattr $C$DW$24, DW_AT_type(*$C$DW$T$11)
+     362        .dwattr $C$DW$24, DW_AT_name("PRU1_GPI_CLK_MODE")
+     363        .dwattr $C$DW$24, DW_AT_TI_symbol_name("PRU1_GPI_CLK_MODE")
+     364        .dwattr $C$DW$24, DW_AT_bit_offset(0x1d), DW_AT_bit_size(0x01)
+     365        .dwattr $C$DW$24, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     366        .dwattr $C$DW$24, DW_AT_accessibility(DW_ACCESS_public)
+     367        .dwattr $C$DW$24, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     368        .dwattr $C$DW$24, DW_AT_decl_line(0x59)
+     369        .dwattr $C$DW$24, DW_AT_decl_column(0x0d)
+     370$C$DW$25        .dwtag  DW_TAG_member
+     371        .dwattr $C$DW$25, DW_AT_type(*$C$DW$T$11)
+     372        .dwattr $C$DW$25, DW_AT_name("PRU1_GPI_DIV0")
+     373        .dwattr $C$DW$25, DW_AT_TI_symbol_name("PRU1_GPI_DIV0")
+     374        .dwattr $C$DW$25, DW_AT_bit_offset(0x18), DW_AT_bit_size(0x05)
+     375        .dwattr $C$DW$25, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     376        .dwattr $C$DW$25, DW_AT_accessibility(DW_ACCESS_public)
+     377        .dwattr $C$DW$25, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     378        .dwattr $C$DW$25, DW_AT_decl_line(0x5a)
+     379        .dwattr $C$DW$25, DW_AT_decl_column(0x0d)
+     380$C$DW$26        .dwtag  DW_TAG_member
+     381        .dwattr $C$DW$26, DW_AT_type(*$C$DW$T$11)
+     382        .dwattr $C$DW$26, DW_AT_name("PRU1_GPI_DIV1")
+     383        .dwattr $C$DW$26, DW_AT_TI_symbol_name("PRU1_GPI_DIV1")
+     384        .dwattr $C$DW$26, DW_AT_bit_offset(0x13), DW_AT_bit_size(0x05)
+     385        .dwattr $C$DW$26, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE    8
+
+     386        .dwattr $C$DW$26, DW_AT_accessibility(DW_ACCESS_public)
+     387        .dwattr $C$DW$26, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     388        .dwattr $C$DW$26, DW_AT_decl_line(0x5b)
+     389        .dwattr $C$DW$26, DW_AT_decl_column(0x0d)
+     390$C$DW$27        .dwtag  DW_TAG_member
+     391        .dwattr $C$DW$27, DW_AT_type(*$C$DW$T$11)
+     392        .dwattr $C$DW$27, DW_AT_name("PRU1_GPI_SB")
+     393        .dwattr $C$DW$27, DW_AT_TI_symbol_name("PRU1_GPI_SB")
+     394        .dwattr $C$DW$27, DW_AT_bit_offset(0x12), DW_AT_bit_size(0x01)
+     395        .dwattr $C$DW$27, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     396        .dwattr $C$DW$27, DW_AT_accessibility(DW_ACCESS_public)
+     397        .dwattr $C$DW$27, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     398        .dwattr $C$DW$27, DW_AT_decl_line(0x5c)
+     399        .dwattr $C$DW$27, DW_AT_decl_column(0x0d)
+     400$C$DW$28        .dwtag  DW_TAG_member
+     401        .dwattr $C$DW$28, DW_AT_type(*$C$DW$T$11)
+     402        .dwattr $C$DW$28, DW_AT_name("PRU1_GPO_MODE")
+     403        .dwattr $C$DW$28, DW_AT_TI_symbol_name("PRU1_GPO_MODE")
+     404        .dwattr $C$DW$28, DW_AT_bit_offset(0x11), DW_AT_bit_size(0x01)
+     405        .dwattr $C$DW$28, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     406        .dwattr $C$DW$28, DW_AT_accessibility(DW_ACCESS_public)
+     407        .dwattr $C$DW$28, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     408        .dwattr $C$DW$28, DW_AT_decl_line(0x5d)
+     409        .dwattr $C$DW$28, DW_AT_decl_column(0x0d)
+     410$C$DW$29        .dwtag  DW_TAG_member
+     411        .dwattr $C$DW$29, DW_AT_type(*$C$DW$T$11)
+     412        .dwattr $C$DW$29, DW_AT_name("PRU1_GPO_DIV0")
+     413        .dwattr $C$DW$29, DW_AT_TI_symbol_name("PRU1_GPO_DIV0")
+     414        .dwattr $C$DW$29, DW_AT_bit_offset(0x0c), DW_AT_bit_size(0x05)
+     415        .dwattr $C$DW$29, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     416        .dwattr $C$DW$29, DW_AT_accessibility(DW_ACCESS_public)
+     417        .dwattr $C$DW$29, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     418        .dwattr $C$DW$29, DW_AT_decl_line(0x5e)
+     419        .dwattr $C$DW$29, DW_AT_decl_column(0x0d)
+     420$C$DW$30        .dwtag  DW_TAG_member
+     421        .dwattr $C$DW$30, DW_AT_type(*$C$DW$T$11)
+     422        .dwattr $C$DW$30, DW_AT_name("PRU1_GPO_DIV1")
+     423        .dwattr $C$DW$30, DW_AT_TI_symbol_name("PRU1_GPO_DIV1")
+     424        .dwattr $C$DW$30, DW_AT_bit_offset(0x07), DW_AT_bit_size(0x05)
+     425        .dwattr $C$DW$30, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     426        .dwattr $C$DW$30, DW_AT_accessibility(DW_ACCESS_public)
+     427        .dwattr $C$DW$30, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     428        .dwattr $C$DW$30, DW_AT_decl_line(0x5f)
+     429        .dwattr $C$DW$30, DW_AT_decl_column(0x0d)
+     430$C$DW$31        .dwtag  DW_TAG_member
+     431        .dwattr $C$DW$31, DW_AT_type(*$C$DW$T$11)
+     432        .dwattr $C$DW$31, DW_AT_name("PRU1_GPO_SH_SEL")
+     433        .dwattr $C$DW$31, DW_AT_TI_symbol_name("PRU1_GPO_SH_SEL")
+     434        .dwattr $C$DW$31, DW_AT_bit_offset(0x06), DW_AT_bit_size(0x01)
+     435        .dwattr $C$DW$31, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     436        .dwattr $C$DW$31, DW_AT_accessibility(DW_ACCESS_public)
+     437        .dwattr $C$DW$31, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     438        .dwattr $C$DW$31, DW_AT_decl_line(0x60)
+     439        .dwattr $C$DW$31, DW_AT_decl_column(0x0d)
+     440$C$DW$32        .dwtag  DW_TAG_member
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE    9
+
+     441        .dwattr $C$DW$32, DW_AT_type(*$C$DW$T$11)
+     442        .dwattr $C$DW$32, DW_AT_name("rsvd26")
+     443        .dwattr $C$DW$32, DW_AT_TI_symbol_name("rsvd26")
+     444        .dwattr $C$DW$32, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x06)
+     445        .dwattr $C$DW$32, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     446        .dwattr $C$DW$32, DW_AT_accessibility(DW_ACCESS_public)
+     447        .dwattr $C$DW$32, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     448        .dwattr $C$DW$32, DW_AT_decl_line(0x61)
+     449        .dwattr $C$DW$32, DW_AT_decl_column(0x0d)
+     450        .dwendtag $C$DW$T$22
+     451
+     452        .dwattr $C$DW$T$22, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+     453        .dwattr $C$DW$T$22, DW_AT_decl_line(0x57)
+     454        .dwattr $C$DW$T$22, DW_AT_decl_column(0x13)
+     455$C$DW$T$54      .dwtag  DW_TAG_volatile_type
+     456        .dwattr $C$DW$T$54, DW_AT_type(*$C$DW$T$22)
+     457
+     458$C$DW$T$23      .dwtag  DW_TAG_structure_type
+     459        .dwattr $C$DW$T$23, DW_AT_byte_size(0x04)
+     460$C$DW$33        .dwtag  DW_TAG_member
+     461        .dwattr $C$DW$33, DW_AT_type(*$C$DW$T$11)
+     462        .dwattr $C$DW$33, DW_AT_name("PRU0_CLK_STOP_REQ")
+     463        .dwattr $C$DW$33, DW_AT_TI_symbol_name("PRU0_CLK_STOP_REQ")
+     464        .dwattr $C$DW$33, DW_AT_bit_offset(0x1f), DW_AT_bit_size(0x01)
+     465        .dwattr $C$DW$33, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     466        .dwattr $C$DW$33, DW_AT_accessibility(DW_ACCESS_public)
+     467        .dwattr $C$DW$33, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     468        .dwattr $C$DW$33, DW_AT_decl_line(0x6b)
+     469        .dwattr $C$DW$33, DW_AT_decl_column(0x0d)
+     470$C$DW$34        .dwtag  DW_TAG_member
+     471        .dwattr $C$DW$34, DW_AT_type(*$C$DW$T$11)
+     472        .dwattr $C$DW$34, DW_AT_name("PRU0_CLK_STOP_ACK")
+     473        .dwattr $C$DW$34, DW_AT_TI_symbol_name("PRU0_CLK_STOP_ACK")
+     474        .dwattr $C$DW$34, DW_AT_bit_offset(0x1e), DW_AT_bit_size(0x01)
+     475        .dwattr $C$DW$34, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     476        .dwattr $C$DW$34, DW_AT_accessibility(DW_ACCESS_public)
+     477        .dwattr $C$DW$34, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     478        .dwattr $C$DW$34, DW_AT_decl_line(0x6c)
+     479        .dwattr $C$DW$34, DW_AT_decl_column(0x0d)
+     480$C$DW$35        .dwtag  DW_TAG_member
+     481        .dwattr $C$DW$35, DW_AT_type(*$C$DW$T$11)
+     482        .dwattr $C$DW$35, DW_AT_name("PRU0_CLK_EN")
+     483        .dwattr $C$DW$35, DW_AT_TI_symbol_name("PRU0_CLK_EN")
+     484        .dwattr $C$DW$35, DW_AT_bit_offset(0x1d), DW_AT_bit_size(0x01)
+     485        .dwattr $C$DW$35, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     486        .dwattr $C$DW$35, DW_AT_accessibility(DW_ACCESS_public)
+     487        .dwattr $C$DW$35, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     488        .dwattr $C$DW$35, DW_AT_decl_line(0x6d)
+     489        .dwattr $C$DW$35, DW_AT_decl_column(0x0d)
+     490$C$DW$36        .dwtag  DW_TAG_member
+     491        .dwattr $C$DW$36, DW_AT_type(*$C$DW$T$11)
+     492        .dwattr $C$DW$36, DW_AT_name("PRU1_CLK_STOP_REQ")
+     493        .dwattr $C$DW$36, DW_AT_TI_symbol_name("PRU1_CLK_STOP_REQ")
+     494        .dwattr $C$DW$36, DW_AT_bit_offset(0x1c), DW_AT_bit_size(0x01)
+     495        .dwattr $C$DW$36, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   10
+
+     496        .dwattr $C$DW$36, DW_AT_accessibility(DW_ACCESS_public)
+     497        .dwattr $C$DW$36, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     498        .dwattr $C$DW$36, DW_AT_decl_line(0x6e)
+     499        .dwattr $C$DW$36, DW_AT_decl_column(0x0d)
+     500$C$DW$37        .dwtag  DW_TAG_member
+     501        .dwattr $C$DW$37, DW_AT_type(*$C$DW$T$11)
+     502        .dwattr $C$DW$37, DW_AT_name("PRU1_CLK_STOP_ACK")
+     503        .dwattr $C$DW$37, DW_AT_TI_symbol_name("PRU1_CLK_STOP_ACK")
+     504        .dwattr $C$DW$37, DW_AT_bit_offset(0x1b), DW_AT_bit_size(0x01)
+     505        .dwattr $C$DW$37, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     506        .dwattr $C$DW$37, DW_AT_accessibility(DW_ACCESS_public)
+     507        .dwattr $C$DW$37, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     508        .dwattr $C$DW$37, DW_AT_decl_line(0x6f)
+     509        .dwattr $C$DW$37, DW_AT_decl_column(0x0d)
+     510$C$DW$38        .dwtag  DW_TAG_member
+     511        .dwattr $C$DW$38, DW_AT_type(*$C$DW$T$11)
+     512        .dwattr $C$DW$38, DW_AT_name("PRU1_CLK_EN")
+     513        .dwattr $C$DW$38, DW_AT_TI_symbol_name("PRU1_CLK_EN")
+     514        .dwattr $C$DW$38, DW_AT_bit_offset(0x1a), DW_AT_bit_size(0x01)
+     515        .dwattr $C$DW$38, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     516        .dwattr $C$DW$38, DW_AT_accessibility(DW_ACCESS_public)
+     517        .dwattr $C$DW$38, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     518        .dwattr $C$DW$38, DW_AT_decl_line(0x70)
+     519        .dwattr $C$DW$38, DW_AT_decl_column(0x0d)
+     520$C$DW$39        .dwtag  DW_TAG_member
+     521        .dwattr $C$DW$39, DW_AT_type(*$C$DW$T$11)
+     522        .dwattr $C$DW$39, DW_AT_name("INTC_CLK_STOP_REQ")
+     523        .dwattr $C$DW$39, DW_AT_TI_symbol_name("INTC_CLK_STOP_REQ")
+     524        .dwattr $C$DW$39, DW_AT_bit_offset(0x19), DW_AT_bit_size(0x01)
+     525        .dwattr $C$DW$39, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     526        .dwattr $C$DW$39, DW_AT_accessibility(DW_ACCESS_public)
+     527        .dwattr $C$DW$39, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     528        .dwattr $C$DW$39, DW_AT_decl_line(0x71)
+     529        .dwattr $C$DW$39, DW_AT_decl_column(0x0d)
+     530$C$DW$40        .dwtag  DW_TAG_member
+     531        .dwattr $C$DW$40, DW_AT_type(*$C$DW$T$11)
+     532        .dwattr $C$DW$40, DW_AT_name("INTC_CLK_STOP_ACK")
+     533        .dwattr $C$DW$40, DW_AT_TI_symbol_name("INTC_CLK_STOP_ACK")
+     534        .dwattr $C$DW$40, DW_AT_bit_offset(0x18), DW_AT_bit_size(0x01)
+     535        .dwattr $C$DW$40, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     536        .dwattr $C$DW$40, DW_AT_accessibility(DW_ACCESS_public)
+     537        .dwattr $C$DW$40, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     538        .dwattr $C$DW$40, DW_AT_decl_line(0x72)
+     539        .dwattr $C$DW$40, DW_AT_decl_column(0x0d)
+     540$C$DW$41        .dwtag  DW_TAG_member
+     541        .dwattr $C$DW$41, DW_AT_type(*$C$DW$T$11)
+     542        .dwattr $C$DW$41, DW_AT_name("INTC_CLK_EN")
+     543        .dwattr $C$DW$41, DW_AT_TI_symbol_name("INTC_CLK_EN")
+     544        .dwattr $C$DW$41, DW_AT_bit_offset(0x17), DW_AT_bit_size(0x01)
+     545        .dwattr $C$DW$41, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     546        .dwattr $C$DW$41, DW_AT_accessibility(DW_ACCESS_public)
+     547        .dwattr $C$DW$41, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     548        .dwattr $C$DW$41, DW_AT_decl_line(0x73)
+     549        .dwattr $C$DW$41, DW_AT_decl_column(0x0d)
+     550$C$DW$42        .dwtag  DW_TAG_member
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   11
+
+     551        .dwattr $C$DW$42, DW_AT_type(*$C$DW$T$11)
+     552        .dwattr $C$DW$42, DW_AT_name("UART_CLK_STOP_REQ")
+     553        .dwattr $C$DW$42, DW_AT_TI_symbol_name("UART_CLK_STOP_REQ")
+     554        .dwattr $C$DW$42, DW_AT_bit_offset(0x16), DW_AT_bit_size(0x01)
+     555        .dwattr $C$DW$42, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     556        .dwattr $C$DW$42, DW_AT_accessibility(DW_ACCESS_public)
+     557        .dwattr $C$DW$42, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     558        .dwattr $C$DW$42, DW_AT_decl_line(0x74)
+     559        .dwattr $C$DW$42, DW_AT_decl_column(0x0d)
+     560$C$DW$43        .dwtag  DW_TAG_member
+     561        .dwattr $C$DW$43, DW_AT_type(*$C$DW$T$11)
+     562        .dwattr $C$DW$43, DW_AT_name("UART_CLK_STOP_ACK")
+     563        .dwattr $C$DW$43, DW_AT_TI_symbol_name("UART_CLK_STOP_ACK")
+     564        .dwattr $C$DW$43, DW_AT_bit_offset(0x15), DW_AT_bit_size(0x01)
+     565        .dwattr $C$DW$43, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     566        .dwattr $C$DW$43, DW_AT_accessibility(DW_ACCESS_public)
+     567        .dwattr $C$DW$43, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     568        .dwattr $C$DW$43, DW_AT_decl_line(0x75)
+     569        .dwattr $C$DW$43, DW_AT_decl_column(0x0d)
+     570$C$DW$44        .dwtag  DW_TAG_member
+     571        .dwattr $C$DW$44, DW_AT_type(*$C$DW$T$11)
+     572        .dwattr $C$DW$44, DW_AT_name("UART_CLK_EN")
+     573        .dwattr $C$DW$44, DW_AT_TI_symbol_name("UART_CLK_EN")
+     574        .dwattr $C$DW$44, DW_AT_bit_offset(0x14), DW_AT_bit_size(0x01)
+     575        .dwattr $C$DW$44, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     576        .dwattr $C$DW$44, DW_AT_accessibility(DW_ACCESS_public)
+     577        .dwattr $C$DW$44, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     578        .dwattr $C$DW$44, DW_AT_decl_line(0x76)
+     579        .dwattr $C$DW$44, DW_AT_decl_column(0x0d)
+     580$C$DW$45        .dwtag  DW_TAG_member
+     581        .dwattr $C$DW$45, DW_AT_type(*$C$DW$T$11)
+     582        .dwattr $C$DW$45, DW_AT_name("ECAP_CLK_STOP_REQ")
+     583        .dwattr $C$DW$45, DW_AT_TI_symbol_name("ECAP_CLK_STOP_REQ")
+     584        .dwattr $C$DW$45, DW_AT_bit_offset(0x13), DW_AT_bit_size(0x01)
+     585        .dwattr $C$DW$45, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     586        .dwattr $C$DW$45, DW_AT_accessibility(DW_ACCESS_public)
+     587        .dwattr $C$DW$45, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     588        .dwattr $C$DW$45, DW_AT_decl_line(0x77)
+     589        .dwattr $C$DW$45, DW_AT_decl_column(0x0d)
+     590$C$DW$46        .dwtag  DW_TAG_member
+     591        .dwattr $C$DW$46, DW_AT_type(*$C$DW$T$11)
+     592        .dwattr $C$DW$46, DW_AT_name("ECAP_CLK_STOP_ACK")
+     593        .dwattr $C$DW$46, DW_AT_TI_symbol_name("ECAP_CLK_STOP_ACK")
+     594        .dwattr $C$DW$46, DW_AT_bit_offset(0x12), DW_AT_bit_size(0x01)
+     595        .dwattr $C$DW$46, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     596        .dwattr $C$DW$46, DW_AT_accessibility(DW_ACCESS_public)
+     597        .dwattr $C$DW$46, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     598        .dwattr $C$DW$46, DW_AT_decl_line(0x78)
+     599        .dwattr $C$DW$46, DW_AT_decl_column(0x0d)
+     600$C$DW$47        .dwtag  DW_TAG_member
+     601        .dwattr $C$DW$47, DW_AT_type(*$C$DW$T$11)
+     602        .dwattr $C$DW$47, DW_AT_name("ECAP_CLK_EN")
+     603        .dwattr $C$DW$47, DW_AT_TI_symbol_name("ECAP_CLK_EN")
+     604        .dwattr $C$DW$47, DW_AT_bit_offset(0x11), DW_AT_bit_size(0x01)
+     605        .dwattr $C$DW$47, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   12
+
+     606        .dwattr $C$DW$47, DW_AT_accessibility(DW_ACCESS_public)
+     607        .dwattr $C$DW$47, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     608        .dwattr $C$DW$47, DW_AT_decl_line(0x79)
+     609        .dwattr $C$DW$47, DW_AT_decl_column(0x0d)
+     610$C$DW$48        .dwtag  DW_TAG_member
+     611        .dwattr $C$DW$48, DW_AT_type(*$C$DW$T$11)
+     612        .dwattr $C$DW$48, DW_AT_name("IEP_CLK_STOP_REQ")
+     613        .dwattr $C$DW$48, DW_AT_TI_symbol_name("IEP_CLK_STOP_REQ")
+     614        .dwattr $C$DW$48, DW_AT_bit_offset(0x10), DW_AT_bit_size(0x01)
+     615        .dwattr $C$DW$48, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     616        .dwattr $C$DW$48, DW_AT_accessibility(DW_ACCESS_public)
+     617        .dwattr $C$DW$48, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     618        .dwattr $C$DW$48, DW_AT_decl_line(0x7a)
+     619        .dwattr $C$DW$48, DW_AT_decl_column(0x0d)
+     620$C$DW$49        .dwtag  DW_TAG_member
+     621        .dwattr $C$DW$49, DW_AT_type(*$C$DW$T$11)
+     622        .dwattr $C$DW$49, DW_AT_name("IEP_CLK_STOP_ACK")
+     623        .dwattr $C$DW$49, DW_AT_TI_symbol_name("IEP_CLK_STOP_ACK")
+     624        .dwattr $C$DW$49, DW_AT_bit_offset(0x0f), DW_AT_bit_size(0x01)
+     625        .dwattr $C$DW$49, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     626        .dwattr $C$DW$49, DW_AT_accessibility(DW_ACCESS_public)
+     627        .dwattr $C$DW$49, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     628        .dwattr $C$DW$49, DW_AT_decl_line(0x7b)
+     629        .dwattr $C$DW$49, DW_AT_decl_column(0x0d)
+     630$C$DW$50        .dwtag  DW_TAG_member
+     631        .dwattr $C$DW$50, DW_AT_type(*$C$DW$T$11)
+     632        .dwattr $C$DW$50, DW_AT_name("IEP_CLK_EN")
+     633        .dwattr $C$DW$50, DW_AT_TI_symbol_name("IEP_CLK_EN")
+     634        .dwattr $C$DW$50, DW_AT_bit_offset(0x0e), DW_AT_bit_size(0x01)
+     635        .dwattr $C$DW$50, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     636        .dwattr $C$DW$50, DW_AT_accessibility(DW_ACCESS_public)
+     637        .dwattr $C$DW$50, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     638        .dwattr $C$DW$50, DW_AT_decl_line(0x7c)
+     639        .dwattr $C$DW$50, DW_AT_decl_column(0x0d)
+     640$C$DW$51        .dwtag  DW_TAG_member
+     641        .dwattr $C$DW$51, DW_AT_type(*$C$DW$T$11)
+     642        .dwattr $C$DW$51, DW_AT_name("rsvd18")
+     643        .dwattr $C$DW$51, DW_AT_TI_symbol_name("rsvd18")
+     644        .dwattr $C$DW$51, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x0e)
+     645        .dwattr $C$DW$51, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     646        .dwattr $C$DW$51, DW_AT_accessibility(DW_ACCESS_public)
+     647        .dwattr $C$DW$51, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     648        .dwattr $C$DW$51, DW_AT_decl_line(0x7d)
+     649        .dwattr $C$DW$51, DW_AT_decl_column(0x0d)
+     650        .dwendtag $C$DW$T$23
+     651
+     652        .dwattr $C$DW$T$23, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+     653        .dwattr $C$DW$T$23, DW_AT_decl_line(0x6a)
+     654        .dwattr $C$DW$T$23, DW_AT_decl_column(0x13)
+     655$C$DW$T$56      .dwtag  DW_TAG_volatile_type
+     656        .dwattr $C$DW$T$56, DW_AT_type(*$C$DW$T$23)
+     657
+     658$C$DW$T$24      .dwtag  DW_TAG_structure_type
+     659        .dwattr $C$DW$T$24, DW_AT_byte_size(0x04)
+     660$C$DW$52        .dwtag  DW_TAG_member
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   13
+
+     661        .dwattr $C$DW$52, DW_AT_type(*$C$DW$T$11)
+     662        .dwattr $C$DW$52, DW_AT_name("PRU0_IMEM_PE_RAW")
+     663        .dwattr $C$DW$52, DW_AT_TI_symbol_name("PRU0_IMEM_PE_RAW")
+     664        .dwattr $C$DW$52, DW_AT_bit_offset(0x1c), DW_AT_bit_size(0x04)
+     665        .dwattr $C$DW$52, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     666        .dwattr $C$DW$52, DW_AT_accessibility(DW_ACCESS_public)
+     667        .dwattr $C$DW$52, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     668        .dwattr $C$DW$52, DW_AT_decl_line(0x87)
+     669        .dwattr $C$DW$52, DW_AT_decl_column(0x0d)
+     670$C$DW$53        .dwtag  DW_TAG_member
+     671        .dwattr $C$DW$53, DW_AT_type(*$C$DW$T$11)
+     672        .dwattr $C$DW$53, DW_AT_name("PRU0_DMEM_PE_RAW")
+     673        .dwattr $C$DW$53, DW_AT_TI_symbol_name("PRU0_DMEM_PE_RAW")
+     674        .dwattr $C$DW$53, DW_AT_bit_offset(0x18), DW_AT_bit_size(0x04)
+     675        .dwattr $C$DW$53, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     676        .dwattr $C$DW$53, DW_AT_accessibility(DW_ACCESS_public)
+     677        .dwattr $C$DW$53, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     678        .dwattr $C$DW$53, DW_AT_decl_line(0x88)
+     679        .dwattr $C$DW$53, DW_AT_decl_column(0x0d)
+     680$C$DW$54        .dwtag  DW_TAG_member
+     681        .dwattr $C$DW$54, DW_AT_type(*$C$DW$T$11)
+     682        .dwattr $C$DW$54, DW_AT_name("PRU1_IMEM_PE_RAW")
+     683        .dwattr $C$DW$54, DW_AT_TI_symbol_name("PRU1_IMEM_PE_RAW")
+     684        .dwattr $C$DW$54, DW_AT_bit_offset(0x14), DW_AT_bit_size(0x04)
+     685        .dwattr $C$DW$54, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     686        .dwattr $C$DW$54, DW_AT_accessibility(DW_ACCESS_public)
+     687        .dwattr $C$DW$54, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     688        .dwattr $C$DW$54, DW_AT_decl_line(0x89)
+     689        .dwattr $C$DW$54, DW_AT_decl_column(0x0d)
+     690$C$DW$55        .dwtag  DW_TAG_member
+     691        .dwattr $C$DW$55, DW_AT_type(*$C$DW$T$11)
+     692        .dwattr $C$DW$55, DW_AT_name("PRU1_DMEM_PE_RAW")
+     693        .dwattr $C$DW$55, DW_AT_TI_symbol_name("PRU1_DMEM_PE_RAW")
+     694        .dwattr $C$DW$55, DW_AT_bit_offset(0x10), DW_AT_bit_size(0x04)
+     695        .dwattr $C$DW$55, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     696        .dwattr $C$DW$55, DW_AT_accessibility(DW_ACCESS_public)
+     697        .dwattr $C$DW$55, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     698        .dwattr $C$DW$55, DW_AT_decl_line(0x8a)
+     699        .dwattr $C$DW$55, DW_AT_decl_column(0x0d)
+     700$C$DW$56        .dwtag  DW_TAG_member
+     701        .dwattr $C$DW$56, DW_AT_type(*$C$DW$T$11)
+     702        .dwattr $C$DW$56, DW_AT_name("RAM_PE_RAW")
+     703        .dwattr $C$DW$56, DW_AT_TI_symbol_name("RAM_PE_RAW")
+     704        .dwattr $C$DW$56, DW_AT_bit_offset(0x0c), DW_AT_bit_size(0x04)
+     705        .dwattr $C$DW$56, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     706        .dwattr $C$DW$56, DW_AT_accessibility(DW_ACCESS_public)
+     707        .dwattr $C$DW$56, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     708        .dwattr $C$DW$56, DW_AT_decl_line(0x8b)
+     709        .dwattr $C$DW$56, DW_AT_decl_column(0x0d)
+     710$C$DW$57        .dwtag  DW_TAG_member
+     711        .dwattr $C$DW$57, DW_AT_type(*$C$DW$T$11)
+     712        .dwattr $C$DW$57, DW_AT_name("rsvd20")
+     713        .dwattr $C$DW$57, DW_AT_TI_symbol_name("rsvd20")
+     714        .dwattr $C$DW$57, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x0c)
+     715        .dwattr $C$DW$57, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   14
+
+     716        .dwattr $C$DW$57, DW_AT_accessibility(DW_ACCESS_public)
+     717        .dwattr $C$DW$57, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     718        .dwattr $C$DW$57, DW_AT_decl_line(0x8c)
+     719        .dwattr $C$DW$57, DW_AT_decl_column(0x0d)
+     720        .dwendtag $C$DW$T$24
+     721
+     722        .dwattr $C$DW$T$24, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+     723        .dwattr $C$DW$T$24, DW_AT_decl_line(0x86)
+     724        .dwattr $C$DW$T$24, DW_AT_decl_column(0x14)
+     725$C$DW$T$58      .dwtag  DW_TAG_volatile_type
+     726        .dwattr $C$DW$T$58, DW_AT_type(*$C$DW$T$24)
+     727
+     728$C$DW$T$25      .dwtag  DW_TAG_structure_type
+     729        .dwattr $C$DW$T$25, DW_AT_byte_size(0x04)
+     730$C$DW$58        .dwtag  DW_TAG_member
+     731        .dwattr $C$DW$58, DW_AT_type(*$C$DW$T$11)
+     732        .dwattr $C$DW$58, DW_AT_name("PRU0_IMEM_PE")
+     733        .dwattr $C$DW$58, DW_AT_TI_symbol_name("PRU0_IMEM_PE")
+     734        .dwattr $C$DW$58, DW_AT_bit_offset(0x1c), DW_AT_bit_size(0x04)
+     735        .dwattr $C$DW$58, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     736        .dwattr $C$DW$58, DW_AT_accessibility(DW_ACCESS_public)
+     737        .dwattr $C$DW$58, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     738        .dwattr $C$DW$58, DW_AT_decl_line(0x96)
+     739        .dwattr $C$DW$58, DW_AT_decl_column(0x0d)
+     740$C$DW$59        .dwtag  DW_TAG_member
+     741        .dwattr $C$DW$59, DW_AT_type(*$C$DW$T$11)
+     742        .dwattr $C$DW$59, DW_AT_name("PRU0_DMEM_PE")
+     743        .dwattr $C$DW$59, DW_AT_TI_symbol_name("PRU0_DMEM_PE")
+     744        .dwattr $C$DW$59, DW_AT_bit_offset(0x18), DW_AT_bit_size(0x04)
+     745        .dwattr $C$DW$59, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     746        .dwattr $C$DW$59, DW_AT_accessibility(DW_ACCESS_public)
+     747        .dwattr $C$DW$59, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     748        .dwattr $C$DW$59, DW_AT_decl_line(0x97)
+     749        .dwattr $C$DW$59, DW_AT_decl_column(0x0d)
+     750$C$DW$60        .dwtag  DW_TAG_member
+     751        .dwattr $C$DW$60, DW_AT_type(*$C$DW$T$11)
+     752        .dwattr $C$DW$60, DW_AT_name("PRU1_IMEM_PE")
+     753        .dwattr $C$DW$60, DW_AT_TI_symbol_name("PRU1_IMEM_PE")
+     754        .dwattr $C$DW$60, DW_AT_bit_offset(0x14), DW_AT_bit_size(0x04)
+     755        .dwattr $C$DW$60, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     756        .dwattr $C$DW$60, DW_AT_accessibility(DW_ACCESS_public)
+     757        .dwattr $C$DW$60, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     758        .dwattr $C$DW$60, DW_AT_decl_line(0x98)
+     759        .dwattr $C$DW$60, DW_AT_decl_column(0x0d)
+     760$C$DW$61        .dwtag  DW_TAG_member
+     761        .dwattr $C$DW$61, DW_AT_type(*$C$DW$T$11)
+     762        .dwattr $C$DW$61, DW_AT_name("PRU1_DMEM_PE")
+     763        .dwattr $C$DW$61, DW_AT_TI_symbol_name("PRU1_DMEM_PE")
+     764        .dwattr $C$DW$61, DW_AT_bit_offset(0x10), DW_AT_bit_size(0x04)
+     765        .dwattr $C$DW$61, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     766        .dwattr $C$DW$61, DW_AT_accessibility(DW_ACCESS_public)
+     767        .dwattr $C$DW$61, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     768        .dwattr $C$DW$61, DW_AT_decl_line(0x99)
+     769        .dwattr $C$DW$61, DW_AT_decl_column(0x0d)
+     770$C$DW$62        .dwtag  DW_TAG_member
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   15
+
+     771        .dwattr $C$DW$62, DW_AT_type(*$C$DW$T$11)
+     772        .dwattr $C$DW$62, DW_AT_name("RAM_PE")
+     773        .dwattr $C$DW$62, DW_AT_TI_symbol_name("RAM_PE")
+     774        .dwattr $C$DW$62, DW_AT_bit_offset(0x0c), DW_AT_bit_size(0x04)
+     775        .dwattr $C$DW$62, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     776        .dwattr $C$DW$62, DW_AT_accessibility(DW_ACCESS_public)
+     777        .dwattr $C$DW$62, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     778        .dwattr $C$DW$62, DW_AT_decl_line(0x9a)
+     779        .dwattr $C$DW$62, DW_AT_decl_column(0x0d)
+     780$C$DW$63        .dwtag  DW_TAG_member
+     781        .dwattr $C$DW$63, DW_AT_type(*$C$DW$T$11)
+     782        .dwattr $C$DW$63, DW_AT_name("rsvd20")
+     783        .dwattr $C$DW$63, DW_AT_TI_symbol_name("rsvd20")
+     784        .dwattr $C$DW$63, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x0c)
+     785        .dwattr $C$DW$63, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     786        .dwattr $C$DW$63, DW_AT_accessibility(DW_ACCESS_public)
+     787        .dwattr $C$DW$63, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     788        .dwattr $C$DW$63, DW_AT_decl_line(0x9b)
+     789        .dwattr $C$DW$63, DW_AT_decl_column(0x0d)
+     790        .dwendtag $C$DW$T$25
+     791
+     792        .dwattr $C$DW$T$25, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+     793        .dwattr $C$DW$T$25, DW_AT_decl_line(0x95)
+     794        .dwattr $C$DW$T$25, DW_AT_decl_column(0x14)
+     795$C$DW$T$60      .dwtag  DW_TAG_volatile_type
+     796        .dwattr $C$DW$T$60, DW_AT_type(*$C$DW$T$25)
+     797
+     798$C$DW$T$26      .dwtag  DW_TAG_structure_type
+     799        .dwattr $C$DW$T$26, DW_AT_byte_size(0x04)
+     800$C$DW$64        .dwtag  DW_TAG_member
+     801        .dwattr $C$DW$64, DW_AT_type(*$C$DW$T$11)
+     802        .dwattr $C$DW$64, DW_AT_name("PRU0_IMEM_PE_SET")
+     803        .dwattr $C$DW$64, DW_AT_TI_symbol_name("PRU0_IMEM_PE_SET")
+     804        .dwattr $C$DW$64, DW_AT_bit_offset(0x1c), DW_AT_bit_size(0x04)
+     805        .dwattr $C$DW$64, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     806        .dwattr $C$DW$64, DW_AT_accessibility(DW_ACCESS_public)
+     807        .dwattr $C$DW$64, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     808        .dwattr $C$DW$64, DW_AT_decl_line(0xa4)
+     809        .dwattr $C$DW$64, DW_AT_decl_column(0x0d)
+     810$C$DW$65        .dwtag  DW_TAG_member
+     811        .dwattr $C$DW$65, DW_AT_type(*$C$DW$T$11)
+     812        .dwattr $C$DW$65, DW_AT_name("PRU0_DMEM_PE_SET")
+     813        .dwattr $C$DW$65, DW_AT_TI_symbol_name("PRU0_DMEM_PE_SET")
+     814        .dwattr $C$DW$65, DW_AT_bit_offset(0x18), DW_AT_bit_size(0x04)
+     815        .dwattr $C$DW$65, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     816        .dwattr $C$DW$65, DW_AT_accessibility(DW_ACCESS_public)
+     817        .dwattr $C$DW$65, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     818        .dwattr $C$DW$65, DW_AT_decl_line(0xa5)
+     819        .dwattr $C$DW$65, DW_AT_decl_column(0x0d)
+     820$C$DW$66        .dwtag  DW_TAG_member
+     821        .dwattr $C$DW$66, DW_AT_type(*$C$DW$T$11)
+     822        .dwattr $C$DW$66, DW_AT_name("PRU1_IMEM_PE_SET")
+     823        .dwattr $C$DW$66, DW_AT_TI_symbol_name("PRU1_IMEM_PE_SET")
+     824        .dwattr $C$DW$66, DW_AT_bit_offset(0x14), DW_AT_bit_size(0x04)
+     825        .dwattr $C$DW$66, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   16
+
+     826        .dwattr $C$DW$66, DW_AT_accessibility(DW_ACCESS_public)
+     827        .dwattr $C$DW$66, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     828        .dwattr $C$DW$66, DW_AT_decl_line(0xa6)
+     829        .dwattr $C$DW$66, DW_AT_decl_column(0x0d)
+     830$C$DW$67        .dwtag  DW_TAG_member
+     831        .dwattr $C$DW$67, DW_AT_type(*$C$DW$T$11)
+     832        .dwattr $C$DW$67, DW_AT_name("PRU1_DMEM_PE_SET")
+     833        .dwattr $C$DW$67, DW_AT_TI_symbol_name("PRU1_DMEM_PE_SET")
+     834        .dwattr $C$DW$67, DW_AT_bit_offset(0x10), DW_AT_bit_size(0x04)
+     835        .dwattr $C$DW$67, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     836        .dwattr $C$DW$67, DW_AT_accessibility(DW_ACCESS_public)
+     837        .dwattr $C$DW$67, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     838        .dwattr $C$DW$67, DW_AT_decl_line(0xa7)
+     839        .dwattr $C$DW$67, DW_AT_decl_column(0x0d)
+     840$C$DW$68        .dwtag  DW_TAG_member
+     841        .dwattr $C$DW$68, DW_AT_type(*$C$DW$T$11)
+     842        .dwattr $C$DW$68, DW_AT_name("RAM_PE_SET")
+     843        .dwattr $C$DW$68, DW_AT_TI_symbol_name("RAM_PE_SET")
+     844        .dwattr $C$DW$68, DW_AT_bit_offset(0x0c), DW_AT_bit_size(0x04)
+     845        .dwattr $C$DW$68, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     846        .dwattr $C$DW$68, DW_AT_accessibility(DW_ACCESS_public)
+     847        .dwattr $C$DW$68, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     848        .dwattr $C$DW$68, DW_AT_decl_line(0xa8)
+     849        .dwattr $C$DW$68, DW_AT_decl_column(0x0d)
+     850$C$DW$69        .dwtag  DW_TAG_member
+     851        .dwattr $C$DW$69, DW_AT_type(*$C$DW$T$11)
+     852        .dwattr $C$DW$69, DW_AT_name("rsvd20")
+     853        .dwattr $C$DW$69, DW_AT_TI_symbol_name("rsvd20")
+     854        .dwattr $C$DW$69, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x0c)
+     855        .dwattr $C$DW$69, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     856        .dwattr $C$DW$69, DW_AT_accessibility(DW_ACCESS_public)
+     857        .dwattr $C$DW$69, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     858        .dwattr $C$DW$69, DW_AT_decl_line(0xa9)
+     859        .dwattr $C$DW$69, DW_AT_decl_column(0x0d)
+     860        .dwendtag $C$DW$T$26
+     861
+     862        .dwattr $C$DW$T$26, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+     863        .dwattr $C$DW$T$26, DW_AT_decl_line(0xa3)
+     864        .dwattr $C$DW$T$26, DW_AT_decl_column(0x13)
+     865$C$DW$T$62      .dwtag  DW_TAG_volatile_type
+     866        .dwattr $C$DW$T$62, DW_AT_type(*$C$DW$T$26)
+     867
+     868$C$DW$T$27      .dwtag  DW_TAG_structure_type
+     869        .dwattr $C$DW$T$27, DW_AT_byte_size(0x04)
+     870$C$DW$70        .dwtag  DW_TAG_member
+     871        .dwattr $C$DW$70, DW_AT_type(*$C$DW$T$11)
+     872        .dwattr $C$DW$70, DW_AT_name("PRU0_IMEM_PE_CLR")
+     873        .dwattr $C$DW$70, DW_AT_TI_symbol_name("PRU0_IMEM_PE_CLR")
+     874        .dwattr $C$DW$70, DW_AT_bit_offset(0x1c), DW_AT_bit_size(0x04)
+     875        .dwattr $C$DW$70, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     876        .dwattr $C$DW$70, DW_AT_accessibility(DW_ACCESS_public)
+     877        .dwattr $C$DW$70, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     878        .dwattr $C$DW$70, DW_AT_decl_line(0xb3)
+     879        .dwattr $C$DW$70, DW_AT_decl_column(0x0d)
+     880$C$DW$71        .dwtag  DW_TAG_member
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   17
+
+     881        .dwattr $C$DW$71, DW_AT_type(*$C$DW$T$11)
+     882        .dwattr $C$DW$71, DW_AT_name("PRU0_DMEM_PE_CLR")
+     883        .dwattr $C$DW$71, DW_AT_TI_symbol_name("PRU0_DMEM_PE_CLR")
+     884        .dwattr $C$DW$71, DW_AT_bit_offset(0x18), DW_AT_bit_size(0x04)
+     885        .dwattr $C$DW$71, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     886        .dwattr $C$DW$71, DW_AT_accessibility(DW_ACCESS_public)
+     887        .dwattr $C$DW$71, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     888        .dwattr $C$DW$71, DW_AT_decl_line(0xb4)
+     889        .dwattr $C$DW$71, DW_AT_decl_column(0x0d)
+     890$C$DW$72        .dwtag  DW_TAG_member
+     891        .dwattr $C$DW$72, DW_AT_type(*$C$DW$T$11)
+     892        .dwattr $C$DW$72, DW_AT_name("PRU1_IMEM_PE_CLR")
+     893        .dwattr $C$DW$72, DW_AT_TI_symbol_name("PRU1_IMEM_PE_CLR")
+     894        .dwattr $C$DW$72, DW_AT_bit_offset(0x14), DW_AT_bit_size(0x04)
+     895        .dwattr $C$DW$72, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     896        .dwattr $C$DW$72, DW_AT_accessibility(DW_ACCESS_public)
+     897        .dwattr $C$DW$72, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     898        .dwattr $C$DW$72, DW_AT_decl_line(0xb5)
+     899        .dwattr $C$DW$72, DW_AT_decl_column(0x0d)
+     900$C$DW$73        .dwtag  DW_TAG_member
+     901        .dwattr $C$DW$73, DW_AT_type(*$C$DW$T$11)
+     902        .dwattr $C$DW$73, DW_AT_name("PRU1_DMEM_PE_CLR")
+     903        .dwattr $C$DW$73, DW_AT_TI_symbol_name("PRU1_DMEM_PE_CLR")
+     904        .dwattr $C$DW$73, DW_AT_bit_offset(0x10), DW_AT_bit_size(0x04)
+     905        .dwattr $C$DW$73, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     906        .dwattr $C$DW$73, DW_AT_accessibility(DW_ACCESS_public)
+     907        .dwattr $C$DW$73, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     908        .dwattr $C$DW$73, DW_AT_decl_line(0xb6)
+     909        .dwattr $C$DW$73, DW_AT_decl_column(0x0d)
+     910$C$DW$74        .dwtag  DW_TAG_member
+     911        .dwattr $C$DW$74, DW_AT_type(*$C$DW$T$11)
+     912        .dwattr $C$DW$74, DW_AT_name("rsvd16")
+     913        .dwattr $C$DW$74, DW_AT_TI_symbol_name("rsvd16")
+     914        .dwattr $C$DW$74, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x10)
+     915        .dwattr $C$DW$74, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     916        .dwattr $C$DW$74, DW_AT_accessibility(DW_ACCESS_public)
+     917        .dwattr $C$DW$74, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     918        .dwattr $C$DW$74, DW_AT_decl_line(0xb7)
+     919        .dwattr $C$DW$74, DW_AT_decl_column(0x0d)
+     920        .dwendtag $C$DW$T$27
+     921
+     922        .dwattr $C$DW$T$27, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+     923        .dwattr $C$DW$T$27, DW_AT_decl_line(0xb2)
+     924        .dwattr $C$DW$T$27, DW_AT_decl_column(0x13)
+     925$C$DW$T$64      .dwtag  DW_TAG_volatile_type
+     926        .dwattr $C$DW$T$64, DW_AT_type(*$C$DW$T$27)
+     927
+     928$C$DW$T$28      .dwtag  DW_TAG_structure_type
+     929        .dwattr $C$DW$T$28, DW_AT_byte_size(0x04)
+     930$C$DW$75        .dwtag  DW_TAG_member
+     931        .dwattr $C$DW$75, DW_AT_type(*$C$DW$T$11)
+     932        .dwattr $C$DW$75, DW_AT_name("PMAO_PRU0")
+     933        .dwattr $C$DW$75, DW_AT_TI_symbol_name("PMAO_PRU0")
+     934        .dwattr $C$DW$75, DW_AT_bit_offset(0x1f), DW_AT_bit_size(0x01)
+     935        .dwattr $C$DW$75, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   18
+
+     936        .dwattr $C$DW$75, DW_AT_accessibility(DW_ACCESS_public)
+     937        .dwattr $C$DW$75, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     938        .dwattr $C$DW$75, DW_AT_decl_line(0xc4)
+     939        .dwattr $C$DW$75, DW_AT_decl_column(0x0d)
+     940$C$DW$76        .dwtag  DW_TAG_member
+     941        .dwattr $C$DW$76, DW_AT_type(*$C$DW$T$11)
+     942        .dwattr $C$DW$76, DW_AT_name("PMAO_PRU1")
+     943        .dwattr $C$DW$76, DW_AT_TI_symbol_name("PMAO_PRU1")
+     944        .dwattr $C$DW$76, DW_AT_bit_offset(0x1e), DW_AT_bit_size(0x01)
+     945        .dwattr $C$DW$76, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     946        .dwattr $C$DW$76, DW_AT_accessibility(DW_ACCESS_public)
+     947        .dwattr $C$DW$76, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     948        .dwattr $C$DW$76, DW_AT_decl_line(0xc5)
+     949        .dwattr $C$DW$76, DW_AT_decl_column(0x0d)
+     950$C$DW$77        .dwtag  DW_TAG_member
+     951        .dwattr $C$DW$77, DW_AT_type(*$C$DW$T$11)
+     952        .dwattr $C$DW$77, DW_AT_name("rsvd2")
+     953        .dwattr $C$DW$77, DW_AT_TI_symbol_name("rsvd2")
+     954        .dwattr $C$DW$77, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x1e)
+     955        .dwattr $C$DW$77, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     956        .dwattr $C$DW$77, DW_AT_accessibility(DW_ACCESS_public)
+     957        .dwattr $C$DW$77, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     958        .dwattr $C$DW$77, DW_AT_decl_line(0xc6)
+     959        .dwattr $C$DW$77, DW_AT_decl_column(0x0d)
+     960        .dwendtag $C$DW$T$28
+     961
+     962        .dwattr $C$DW$T$28, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+     963        .dwattr $C$DW$T$28, DW_AT_decl_line(0xc3)
+     964        .dwattr $C$DW$T$28, DW_AT_decl_column(0x13)
+     965$C$DW$T$66      .dwtag  DW_TAG_volatile_type
+     966        .dwattr $C$DW$T$66, DW_AT_type(*$C$DW$T$28)
+     967
+     968$C$DW$T$29      .dwtag  DW_TAG_structure_type
+     969        .dwattr $C$DW$T$29, DW_AT_byte_size(0x04)
+     970$C$DW$78        .dwtag  DW_TAG_member
+     971        .dwattr $C$DW$78, DW_AT_type(*$C$DW$T$11)
+     972        .dwattr $C$DW$78, DW_AT_name("OCP_EN")
+     973        .dwattr $C$DW$78, DW_AT_TI_symbol_name("OCP_EN")
+     974        .dwattr $C$DW$78, DW_AT_bit_offset(0x1f), DW_AT_bit_size(0x01)
+     975        .dwattr $C$DW$78, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     976        .dwattr $C$DW$78, DW_AT_accessibility(DW_ACCESS_public)
+     977        .dwattr $C$DW$78, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     978        .dwattr $C$DW$78, DW_AT_decl_line(0xd3)
+     979        .dwattr $C$DW$78, DW_AT_decl_column(0x0d)
+     980$C$DW$79        .dwtag  DW_TAG_member
+     981        .dwattr $C$DW$79, DW_AT_type(*$C$DW$T$11)
+     982        .dwattr $C$DW$79, DW_AT_name("rsvd1")
+     983        .dwattr $C$DW$79, DW_AT_TI_symbol_name("rsvd1")
+     984        .dwattr $C$DW$79, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x1f)
+     985        .dwattr $C$DW$79, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+     986        .dwattr $C$DW$79, DW_AT_accessibility(DW_ACCESS_public)
+     987        .dwattr $C$DW$79, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+     988        .dwattr $C$DW$79, DW_AT_decl_line(0xd4)
+     989        .dwattr $C$DW$79, DW_AT_decl_column(0x0d)
+     990        .dwendtag $C$DW$T$29
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   19
+
+     991
+     992        .dwattr $C$DW$T$29, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+     993        .dwattr $C$DW$T$29, DW_AT_decl_line(0xd2)
+     994        .dwattr $C$DW$T$29, DW_AT_decl_column(0x13)
+     995$C$DW$T$68      .dwtag  DW_TAG_volatile_type
+     996        .dwattr $C$DW$T$68, DW_AT_type(*$C$DW$T$29)
+     997
+     998$C$DW$T$30      .dwtag  DW_TAG_structure_type
+     999        .dwattr $C$DW$T$30, DW_AT_byte_size(0x04)
+    1000$C$DW$80        .dwtag  DW_TAG_member
+    1001        .dwattr $C$DW$80, DW_AT_type(*$C$DW$T$11)
+    1002        .dwattr $C$DW$80, DW_AT_name("PRU1_PAD_HP_EN")
+    1003        .dwattr $C$DW$80, DW_AT_TI_symbol_name("PRU1_PAD_HP_EN")
+    1004        .dwattr $C$DW$80, DW_AT_bit_offset(0x1f), DW_AT_bit_size(0x01)
+    1005        .dwattr $C$DW$80, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1006        .dwattr $C$DW$80, DW_AT_accessibility(DW_ACCESS_public)
+    1007        .dwattr $C$DW$80, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1008        .dwattr $C$DW$80, DW_AT_decl_line(0xde)
+    1009        .dwattr $C$DW$80, DW_AT_decl_column(0x0d)
+    1010$C$DW$81        .dwtag  DW_TAG_member
+    1011        .dwattr $C$DW$81, DW_AT_type(*$C$DW$T$11)
+    1012        .dwattr $C$DW$81, DW_AT_name("XFR_SHIFT_EN")
+    1013        .dwattr $C$DW$81, DW_AT_TI_symbol_name("XFR_SHIFT_EN")
+    1014        .dwattr $C$DW$81, DW_AT_bit_offset(0x1e), DW_AT_bit_size(0x01)
+    1015        .dwattr $C$DW$81, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1016        .dwattr $C$DW$81, DW_AT_accessibility(DW_ACCESS_public)
+    1017        .dwattr $C$DW$81, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1018        .dwattr $C$DW$81, DW_AT_decl_line(0xdf)
+    1019        .dwattr $C$DW$81, DW_AT_decl_column(0x0d)
+    1020$C$DW$82        .dwtag  DW_TAG_member
+    1021        .dwattr $C$DW$82, DW_AT_type(*$C$DW$T$11)
+    1022        .dwattr $C$DW$82, DW_AT_name("rsvd2")
+    1023        .dwattr $C$DW$82, DW_AT_TI_symbol_name("rsvd2")
+    1024        .dwattr $C$DW$82, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x1e)
+    1025        .dwattr $C$DW$82, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1026        .dwattr $C$DW$82, DW_AT_accessibility(DW_ACCESS_public)
+    1027        .dwattr $C$DW$82, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1028        .dwattr $C$DW$82, DW_AT_decl_line(0xe0)
+    1029        .dwattr $C$DW$82, DW_AT_decl_column(0x0d)
+    1030        .dwendtag $C$DW$T$30
+    1031
+    1032        .dwattr $C$DW$T$30, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1033        .dwattr $C$DW$T$30, DW_AT_decl_line(0xdd)
+    1034        .dwattr $C$DW$T$30, DW_AT_decl_column(0x13)
+    1035$C$DW$T$70      .dwtag  DW_TAG_volatile_type
+    1036        .dwattr $C$DW$T$70, DW_AT_type(*$C$DW$T$30)
+    1037
+    1038$C$DW$T$31      .dwtag  DW_TAG_structure_type
+    1039        .dwattr $C$DW$T$31, DW_AT_byte_size(0x04)
+    1040$C$DW$83        .dwtag  DW_TAG_member
+    1041        .dwattr $C$DW$83, DW_AT_type(*$C$DW$T$11)
+    1042        .dwattr $C$DW$83, DW_AT_name("PIN_MUX_SEL")
+    1043        .dwattr $C$DW$83, DW_AT_TI_symbol_name("PIN_MUX_SEL")
+    1044        .dwattr $C$DW$83, DW_AT_bit_offset(0x18), DW_AT_bit_size(0x08)
+    1045        .dwattr $C$DW$83, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   20
+
+    1046        .dwattr $C$DW$83, DW_AT_accessibility(DW_ACCESS_public)
+    1047        .dwattr $C$DW$83, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1048        .dwattr $C$DW$83, DW_AT_decl_line(0xec)
+    1049        .dwattr $C$DW$83, DW_AT_decl_column(0x0d)
+    1050$C$DW$84        .dwtag  DW_TAG_member
+    1051        .dwattr $C$DW$84, DW_AT_type(*$C$DW$T$11)
+    1052        .dwattr $C$DW$84, DW_AT_name("rsvd2")
+    1053        .dwattr $C$DW$84, DW_AT_TI_symbol_name("rsvd2")
+    1054        .dwattr $C$DW$84, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x18)
+    1055        .dwattr $C$DW$84, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1056        .dwattr $C$DW$84, DW_AT_accessibility(DW_ACCESS_public)
+    1057        .dwattr $C$DW$84, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1058        .dwattr $C$DW$84, DW_AT_decl_line(0xed)
+    1059        .dwattr $C$DW$84, DW_AT_decl_column(0x0d)
+    1060        .dwendtag $C$DW$T$31
+    1061
+    1062        .dwattr $C$DW$T$31, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1063        .dwattr $C$DW$T$31, DW_AT_decl_line(0xeb)
+    1064        .dwattr $C$DW$T$31, DW_AT_decl_column(0x13)
+    1065$C$DW$T$72      .dwtag  DW_TAG_volatile_type
+    1066        .dwattr $C$DW$T$72, DW_AT_type(*$C$DW$T$31)
+    1067
+    1068$C$DW$T$35      .dwtag  DW_TAG_structure_type
+    1069        .dwattr $C$DW$T$35, DW_AT_byte_size(0x44)
+    1070$C$DW$85        .dwtag  DW_TAG_member
+    1071        .dwattr $C$DW$85, DW_AT_type(*$C$DW$T$49)
+    1072        .dwattr $C$DW$85, DW_AT_name("$P$T0")
+    1073        .dwattr $C$DW$85, DW_AT_TI_symbol_name("$P$T0")
+    1074        .dwattr $C$DW$85, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1075        .dwattr $C$DW$85, DW_AT_accessibility(DW_ACCESS_public)
+    1076        .dwattr $C$DW$85, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1077        .dwattr $C$DW$85, DW_AT_decl_line(0x29)
+    1078        .dwattr $C$DW$85, DW_AT_decl_column(0x02)
+    1079$C$DW$86        .dwtag  DW_TAG_member
+    1080        .dwattr $C$DW$86, DW_AT_type(*$C$DW$T$51)
+    1081        .dwattr $C$DW$86, DW_AT_name("$P$T1")
+    1082        .dwattr $C$DW$86, DW_AT_TI_symbol_name("$P$T1")
+    1083        .dwattr $C$DW$86, DW_AT_data_member_location[DW_OP_plus_uconst 0x4]
+    1084        .dwattr $C$DW$86, DW_AT_accessibility(DW_ACCESS_public)
+    1085        .dwattr $C$DW$86, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1086        .dwattr $C$DW$86, DW_AT_decl_line(0x33)
+    1087        .dwattr $C$DW$86, DW_AT_decl_column(0x02)
+    1088$C$DW$87        .dwtag  DW_TAG_member
+    1089        .dwattr $C$DW$87, DW_AT_type(*$C$DW$T$53)
+    1090        .dwattr $C$DW$87, DW_AT_name("$P$T2")
+    1091        .dwattr $C$DW$87, DW_AT_TI_symbol_name("$P$T2")
+    1092        .dwattr $C$DW$87, DW_AT_data_member_location[DW_OP_plus_uconst 0x8]
+    1093        .dwattr $C$DW$87, DW_AT_accessibility(DW_ACCESS_public)
+    1094        .dwattr $C$DW$87, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1095        .dwattr $C$DW$87, DW_AT_decl_line(0x41)
+    1096        .dwattr $C$DW$87, DW_AT_decl_column(0x02)
+    1097$C$DW$88        .dwtag  DW_TAG_member
+    1098        .dwattr $C$DW$88, DW_AT_type(*$C$DW$T$55)
+    1099        .dwattr $C$DW$88, DW_AT_name("$P$T3")
+    1100        .dwattr $C$DW$88, DW_AT_TI_symbol_name("$P$T3")
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   21
+
+    1101        .dwattr $C$DW$88, DW_AT_data_member_location[DW_OP_plus_uconst 0xc]
+    1102        .dwattr $C$DW$88, DW_AT_accessibility(DW_ACCESS_public)
+    1103        .dwattr $C$DW$88, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1104        .dwattr $C$DW$88, DW_AT_decl_line(0x54)
+    1105        .dwattr $C$DW$88, DW_AT_decl_column(0x02)
+    1106$C$DW$89        .dwtag  DW_TAG_member
+    1107        .dwattr $C$DW$89, DW_AT_type(*$C$DW$T$57)
+    1108        .dwattr $C$DW$89, DW_AT_name("$P$T4")
+    1109        .dwattr $C$DW$89, DW_AT_TI_symbol_name("$P$T4")
+    1110        .dwattr $C$DW$89, DW_AT_data_member_location[DW_OP_plus_uconst 0x10]
+    1111        .dwattr $C$DW$89, DW_AT_accessibility(DW_ACCESS_public)
+    1112        .dwattr $C$DW$89, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1113        .dwattr $C$DW$89, DW_AT_decl_line(0x67)
+    1114        .dwattr $C$DW$89, DW_AT_decl_column(0x02)
+    1115$C$DW$90        .dwtag  DW_TAG_member
+    1116        .dwattr $C$DW$90, DW_AT_type(*$C$DW$T$59)
+    1117        .dwattr $C$DW$90, DW_AT_name("$P$T5")
+    1118        .dwattr $C$DW$90, DW_AT_TI_symbol_name("$P$T5")
+    1119        .dwattr $C$DW$90, DW_AT_data_member_location[DW_OP_plus_uconst 0x14]
+    1120        .dwattr $C$DW$90, DW_AT_accessibility(DW_ACCESS_public)
+    1121        .dwattr $C$DW$90, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1122        .dwattr $C$DW$90, DW_AT_decl_line(0x83)
+    1123        .dwattr $C$DW$90, DW_AT_decl_column(0x02)
+    1124$C$DW$91        .dwtag  DW_TAG_member
+    1125        .dwattr $C$DW$91, DW_AT_type(*$C$DW$T$61)
+    1126        .dwattr $C$DW$91, DW_AT_name("$P$T6")
+    1127        .dwattr $C$DW$91, DW_AT_TI_symbol_name("$P$T6")
+    1128        .dwattr $C$DW$91, DW_AT_data_member_location[DW_OP_plus_uconst 0x18]
+    1129        .dwattr $C$DW$91, DW_AT_accessibility(DW_ACCESS_public)
+    1130        .dwattr $C$DW$91, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1131        .dwattr $C$DW$91, DW_AT_decl_line(0x92)
+    1132        .dwattr $C$DW$91, DW_AT_decl_column(0x02)
+    1133$C$DW$92        .dwtag  DW_TAG_member
+    1134        .dwattr $C$DW$92, DW_AT_type(*$C$DW$T$63)
+    1135        .dwattr $C$DW$92, DW_AT_name("$P$T7")
+    1136        .dwattr $C$DW$92, DW_AT_TI_symbol_name("$P$T7")
+    1137        .dwattr $C$DW$92, DW_AT_data_member_location[DW_OP_plus_uconst 0x1c]
+    1138        .dwattr $C$DW$92, DW_AT_accessibility(DW_ACCESS_public)
+    1139        .dwattr $C$DW$92, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1140        .dwattr $C$DW$92, DW_AT_decl_line(0xa0)
+    1141        .dwattr $C$DW$92, DW_AT_decl_column(0x02)
+    1142$C$DW$93        .dwtag  DW_TAG_member
+    1143        .dwattr $C$DW$93, DW_AT_type(*$C$DW$T$65)
+    1144        .dwattr $C$DW$93, DW_AT_name("$P$T8")
+    1145        .dwattr $C$DW$93, DW_AT_TI_symbol_name("$P$T8")
+    1146        .dwattr $C$DW$93, DW_AT_data_member_location[DW_OP_plus_uconst 0x20]
+    1147        .dwattr $C$DW$93, DW_AT_accessibility(DW_ACCESS_public)
+    1148        .dwattr $C$DW$93, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1149        .dwattr $C$DW$93, DW_AT_decl_line(0xaf)
+    1150        .dwattr $C$DW$93, DW_AT_decl_column(0x02)
+    1151$C$DW$94        .dwtag  DW_TAG_member
+    1152        .dwattr $C$DW$94, DW_AT_type(*$C$DW$T$32)
+    1153        .dwattr $C$DW$94, DW_AT_name("rsvd24")
+    1154        .dwattr $C$DW$94, DW_AT_TI_symbol_name("rsvd24")
+    1155        .dwattr $C$DW$94, DW_AT_data_member_location[DW_OP_plus_uconst 0x24]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   22
+
+    1156        .dwattr $C$DW$94, DW_AT_accessibility(DW_ACCESS_public)
+    1157        .dwattr $C$DW$94, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1158        .dwattr $C$DW$94, DW_AT_decl_line(0xbc)
+    1159        .dwattr $C$DW$94, DW_AT_decl_column(0x0b)
+    1160$C$DW$95        .dwtag  DW_TAG_member
+    1161        .dwattr $C$DW$95, DW_AT_type(*$C$DW$T$67)
+    1162        .dwattr $C$DW$95, DW_AT_name("$P$T9")
+    1163        .dwattr $C$DW$95, DW_AT_TI_symbol_name("$P$T9")
+    1164        .dwattr $C$DW$95, DW_AT_data_member_location[DW_OP_plus_uconst 0x28]
+    1165        .dwattr $C$DW$95, DW_AT_accessibility(DW_ACCESS_public)
+    1166        .dwattr $C$DW$95, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1167        .dwattr $C$DW$95, DW_AT_decl_line(0xc0)
+    1168        .dwattr $C$DW$95, DW_AT_decl_column(0x02)
+    1169$C$DW$96        .dwtag  DW_TAG_member
+    1170        .dwattr $C$DW$96, DW_AT_type(*$C$DW$T$33)
+    1171        .dwattr $C$DW$96, DW_AT_name("rsvd2c")
+    1172        .dwattr $C$DW$96, DW_AT_TI_symbol_name("rsvd2c")
+    1173        .dwattr $C$DW$96, DW_AT_data_member_location[DW_OP_plus_uconst 0x2c]
+    1174        .dwattr $C$DW$96, DW_AT_accessibility(DW_ACCESS_public)
+    1175        .dwattr $C$DW$96, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1176        .dwattr $C$DW$96, DW_AT_decl_line(0xcb)
+    1177        .dwattr $C$DW$96, DW_AT_decl_column(0x0b)
+    1178$C$DW$97        .dwtag  DW_TAG_member
+    1179        .dwattr $C$DW$97, DW_AT_type(*$C$DW$T$69)
+    1180        .dwattr $C$DW$97, DW_AT_name("$P$T10")
+    1181        .dwattr $C$DW$97, DW_AT_TI_symbol_name("$P$T10")
+    1182        .dwattr $C$DW$97, DW_AT_data_member_location[DW_OP_plus_uconst 0x30]
+    1183        .dwattr $C$DW$97, DW_AT_accessibility(DW_ACCESS_public)
+    1184        .dwattr $C$DW$97, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1185        .dwattr $C$DW$97, DW_AT_decl_line(0xcf)
+    1186        .dwattr $C$DW$97, DW_AT_decl_column(0x02)
+    1187$C$DW$98        .dwtag  DW_TAG_member
+    1188        .dwattr $C$DW$98, DW_AT_type(*$C$DW$T$71)
+    1189        .dwattr $C$DW$98, DW_AT_name("$P$T11")
+    1190        .dwattr $C$DW$98, DW_AT_TI_symbol_name("$P$T11")
+    1191        .dwattr $C$DW$98, DW_AT_data_member_location[DW_OP_plus_uconst 0x34]
+    1192        .dwattr $C$DW$98, DW_AT_accessibility(DW_ACCESS_public)
+    1193        .dwattr $C$DW$98, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1194        .dwattr $C$DW$98, DW_AT_decl_line(0xda)
+    1195        .dwattr $C$DW$98, DW_AT_decl_column(0x02)
+    1196$C$DW$99        .dwtag  DW_TAG_member
+    1197        .dwattr $C$DW$99, DW_AT_type(*$C$DW$T$34)
+    1198        .dwattr $C$DW$99, DW_AT_name("rsvd38")
+    1199        .dwattr $C$DW$99, DW_AT_TI_symbol_name("rsvd38")
+    1200        .dwattr $C$DW$99, DW_AT_data_member_location[DW_OP_plus_uconst 0x38]
+    1201        .dwattr $C$DW$99, DW_AT_accessibility(DW_ACCESS_public)
+    1202        .dwattr $C$DW$99, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pru
+    1203        .dwattr $C$DW$99, DW_AT_decl_line(0xe5)
+    1204        .dwattr $C$DW$99, DW_AT_decl_column(0x0b)
+    1205$C$DW$100       .dwtag  DW_TAG_member
+    1206        .dwattr $C$DW$100, DW_AT_type(*$C$DW$T$73)
+    1207        .dwattr $C$DW$100, DW_AT_name("$P$T12")
+    1208        .dwattr $C$DW$100, DW_AT_TI_symbol_name("$P$T12")
+    1209        .dwattr $C$DW$100, DW_AT_data_member_location[DW_OP_plus_uconst 0x40]
+    1210        .dwattr $C$DW$100, DW_AT_accessibility(DW_ACCESS_public)
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   23
+
+    1211        .dwattr $C$DW$100, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1212        .dwattr $C$DW$100, DW_AT_decl_line(0xe8)
+    1213        .dwattr $C$DW$100, DW_AT_decl_column(0x02)
+    1214        .dwendtag $C$DW$T$35
+    1215
+    1216        .dwattr $C$DW$T$35, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1217        .dwattr $C$DW$T$35, DW_AT_decl_line(0x26)
+    1218        .dwattr $C$DW$T$35, DW_AT_decl_column(0x10)
+    1219$C$DW$T$97      .dwtag  DW_TAG_typedef, DW_AT_name("pruCfg")
+    1220        .dwattr $C$DW$T$97, DW_AT_type(*$C$DW$T$35)
+    1221        .dwattr $C$DW$T$97, DW_AT_language(DW_LANG_C)
+    1222        .dwattr $C$DW$T$97, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1223        .dwattr $C$DW$T$97, DW_AT_decl_line(0xf0)
+    1224        .dwattr $C$DW$T$97, DW_AT_decl_column(0x03)
+    1225$C$DW$T$98      .dwtag  DW_TAG_volatile_type
+    1226        .dwattr $C$DW$T$98, DW_AT_type(*$C$DW$T$97)
+    1227
+    1228$C$DW$T$36      .dwtag  DW_TAG_structure_type
+    1229        .dwattr $C$DW$T$36, DW_AT_byte_size(0x04)
+    1230$C$DW$101       .dwtag  DW_TAG_member
+    1231        .dwattr $C$DW$101, DW_AT_type(*$C$DW$T$11)
+    1232        .dwattr $C$DW$101, DW_AT_name("SOFT_RST_N")
+    1233        .dwattr $C$DW$101, DW_AT_TI_symbol_name("SOFT_RST_N")
+    1234        .dwattr $C$DW$101, DW_AT_bit_offset(0x1f), DW_AT_bit_size(0x01)
+    1235        .dwattr $C$DW$101, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1236        .dwattr $C$DW$101, DW_AT_accessibility(DW_ACCESS_public)
+    1237        .dwattr $C$DW$101, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1238        .dwattr $C$DW$101, DW_AT_decl_line(0x2d)
+    1239        .dwattr $C$DW$101, DW_AT_decl_column(0x0d)
+    1240$C$DW$102       .dwtag  DW_TAG_member
+    1241        .dwattr $C$DW$102, DW_AT_type(*$C$DW$T$11)
+    1242        .dwattr $C$DW$102, DW_AT_name("EN")
+    1243        .dwattr $C$DW$102, DW_AT_TI_symbol_name("EN")
+    1244        .dwattr $C$DW$102, DW_AT_bit_offset(0x1e), DW_AT_bit_size(0x01)
+    1245        .dwattr $C$DW$102, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1246        .dwattr $C$DW$102, DW_AT_accessibility(DW_ACCESS_public)
+    1247        .dwattr $C$DW$102, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1248        .dwattr $C$DW$102, DW_AT_decl_line(0x2e)
+    1249        .dwattr $C$DW$102, DW_AT_decl_column(0x0d)
+    1250$C$DW$103       .dwtag  DW_TAG_member
+    1251        .dwattr $C$DW$103, DW_AT_type(*$C$DW$T$11)
+    1252        .dwattr $C$DW$103, DW_AT_name("SLEEPING")
+    1253        .dwattr $C$DW$103, DW_AT_TI_symbol_name("SLEEPING")
+    1254        .dwattr $C$DW$103, DW_AT_bit_offset(0x1d), DW_AT_bit_size(0x01)
+    1255        .dwattr $C$DW$103, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1256        .dwattr $C$DW$103, DW_AT_accessibility(DW_ACCESS_public)
+    1257        .dwattr $C$DW$103, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1258        .dwattr $C$DW$103, DW_AT_decl_line(0x2f)
+    1259        .dwattr $C$DW$103, DW_AT_decl_column(0x0d)
+    1260$C$DW$104       .dwtag  DW_TAG_member
+    1261        .dwattr $C$DW$104, DW_AT_type(*$C$DW$T$11)
+    1262        .dwattr $C$DW$104, DW_AT_name("CTR_EN")
+    1263        .dwattr $C$DW$104, DW_AT_TI_symbol_name("CTR_EN")
+    1264        .dwattr $C$DW$104, DW_AT_bit_offset(0x1c), DW_AT_bit_size(0x01)
+    1265        .dwattr $C$DW$104, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   24
+
+    1266        .dwattr $C$DW$104, DW_AT_accessibility(DW_ACCESS_public)
+    1267        .dwattr $C$DW$104, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1268        .dwattr $C$DW$104, DW_AT_decl_line(0x30)
+    1269        .dwattr $C$DW$104, DW_AT_decl_column(0x0d)
+    1270$C$DW$105       .dwtag  DW_TAG_member
+    1271        .dwattr $C$DW$105, DW_AT_type(*$C$DW$T$11)
+    1272        .dwattr $C$DW$105, DW_AT_name("rsvd4")
+    1273        .dwattr $C$DW$105, DW_AT_TI_symbol_name("rsvd4")
+    1274        .dwattr $C$DW$105, DW_AT_bit_offset(0x18), DW_AT_bit_size(0x04)
+    1275        .dwattr $C$DW$105, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1276        .dwattr $C$DW$105, DW_AT_accessibility(DW_ACCESS_public)
+    1277        .dwattr $C$DW$105, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1278        .dwattr $C$DW$105, DW_AT_decl_line(0x31)
+    1279        .dwattr $C$DW$105, DW_AT_decl_column(0x0d)
+    1280$C$DW$106       .dwtag  DW_TAG_member
+    1281        .dwattr $C$DW$106, DW_AT_type(*$C$DW$T$11)
+    1282        .dwattr $C$DW$106, DW_AT_name("SINGLE_STEP")
+    1283        .dwattr $C$DW$106, DW_AT_TI_symbol_name("SINGLE_STEP")
+    1284        .dwattr $C$DW$106, DW_AT_bit_offset(0x17), DW_AT_bit_size(0x01)
+    1285        .dwattr $C$DW$106, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1286        .dwattr $C$DW$106, DW_AT_accessibility(DW_ACCESS_public)
+    1287        .dwattr $C$DW$106, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1288        .dwattr $C$DW$106, DW_AT_decl_line(0x32)
+    1289        .dwattr $C$DW$106, DW_AT_decl_column(0x0d)
+    1290$C$DW$107       .dwtag  DW_TAG_member
+    1291        .dwattr $C$DW$107, DW_AT_type(*$C$DW$T$11)
+    1292        .dwattr $C$DW$107, DW_AT_name("rsvd9")
+    1293        .dwattr $C$DW$107, DW_AT_TI_symbol_name("rsvd9")
+    1294        .dwattr $C$DW$107, DW_AT_bit_offset(0x11), DW_AT_bit_size(0x06)
+    1295        .dwattr $C$DW$107, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1296        .dwattr $C$DW$107, DW_AT_accessibility(DW_ACCESS_public)
+    1297        .dwattr $C$DW$107, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1298        .dwattr $C$DW$107, DW_AT_decl_line(0x33)
+    1299        .dwattr $C$DW$107, DW_AT_decl_column(0x0d)
+    1300$C$DW$108       .dwtag  DW_TAG_member
+    1301        .dwattr $C$DW$108, DW_AT_type(*$C$DW$T$11)
+    1302        .dwattr $C$DW$108, DW_AT_name("RUNSTATE")
+    1303        .dwattr $C$DW$108, DW_AT_TI_symbol_name("RUNSTATE")
+    1304        .dwattr $C$DW$108, DW_AT_bit_offset(0x10), DW_AT_bit_size(0x01)
+    1305        .dwattr $C$DW$108, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1306        .dwattr $C$DW$108, DW_AT_accessibility(DW_ACCESS_public)
+    1307        .dwattr $C$DW$108, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1308        .dwattr $C$DW$108, DW_AT_decl_line(0x34)
+    1309        .dwattr $C$DW$108, DW_AT_decl_column(0x0d)
+    1310$C$DW$109       .dwtag  DW_TAG_member
+    1311        .dwattr $C$DW$109, DW_AT_type(*$C$DW$T$11)
+    1312        .dwattr $C$DW$109, DW_AT_name("PCTR_RST_VAL")
+    1313        .dwattr $C$DW$109, DW_AT_TI_symbol_name("PCTR_RST_VAL")
+    1314        .dwattr $C$DW$109, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x10)
+    1315        .dwattr $C$DW$109, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1316        .dwattr $C$DW$109, DW_AT_accessibility(DW_ACCESS_public)
+    1317        .dwattr $C$DW$109, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1318        .dwattr $C$DW$109, DW_AT_decl_line(0x35)
+    1319        .dwattr $C$DW$109, DW_AT_decl_column(0x0d)
+    1320        .dwendtag $C$DW$T$36
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   25
+
+    1321
+    1322        .dwattr $C$DW$T$36, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1323        .dwattr $C$DW$T$36, DW_AT_decl_line(0x2c)
+    1324        .dwattr $C$DW$T$36, DW_AT_decl_column(0x13)
+    1325$C$DW$T$74      .dwtag  DW_TAG_volatile_type
+    1326        .dwattr $C$DW$T$74, DW_AT_type(*$C$DW$T$36)
+    1327
+    1328$C$DW$T$37      .dwtag  DW_TAG_structure_type
+    1329        .dwattr $C$DW$T$37, DW_AT_byte_size(0x04)
+    1330$C$DW$110       .dwtag  DW_TAG_member
+    1331        .dwattr $C$DW$110, DW_AT_type(*$C$DW$T$11)
+    1332        .dwattr $C$DW$110, DW_AT_name("PCTR")
+    1333        .dwattr $C$DW$110, DW_AT_TI_symbol_name("PCTR")
+    1334        .dwattr $C$DW$110, DW_AT_bit_offset(0x10), DW_AT_bit_size(0x10)
+    1335        .dwattr $C$DW$110, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1336        .dwattr $C$DW$110, DW_AT_accessibility(DW_ACCESS_public)
+    1337        .dwattr $C$DW$110, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1338        .dwattr $C$DW$110, DW_AT_decl_line(0x3f)
+    1339        .dwattr $C$DW$110, DW_AT_decl_column(0x0d)
+    1340$C$DW$111       .dwtag  DW_TAG_member
+    1341        .dwattr $C$DW$111, DW_AT_type(*$C$DW$T$11)
+    1342        .dwattr $C$DW$111, DW_AT_name("rsvd16")
+    1343        .dwattr $C$DW$111, DW_AT_TI_symbol_name("rsvd16")
+    1344        .dwattr $C$DW$111, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x10)
+    1345        .dwattr $C$DW$111, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1346        .dwattr $C$DW$111, DW_AT_accessibility(DW_ACCESS_public)
+    1347        .dwattr $C$DW$111, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1348        .dwattr $C$DW$111, DW_AT_decl_line(0x40)
+    1349        .dwattr $C$DW$111, DW_AT_decl_column(0x0d)
+    1350        .dwendtag $C$DW$T$37
+    1351
+    1352        .dwattr $C$DW$T$37, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1353        .dwattr $C$DW$T$37, DW_AT_decl_line(0x3e)
+    1354        .dwattr $C$DW$T$37, DW_AT_decl_column(0x13)
+    1355$C$DW$T$76      .dwtag  DW_TAG_volatile_type
+    1356        .dwattr $C$DW$T$76, DW_AT_type(*$C$DW$T$37)
+    1357
+    1358$C$DW$T$38      .dwtag  DW_TAG_structure_type
+    1359        .dwattr $C$DW$T$38, DW_AT_byte_size(0x04)
+    1360$C$DW$112       .dwtag  DW_TAG_member
+    1361        .dwattr $C$DW$112, DW_AT_type(*$C$DW$T$11)
+    1362        .dwattr $C$DW$112, DW_AT_name("BITWISE_ENS")
+    1363        .dwattr $C$DW$112, DW_AT_TI_symbol_name("BITWISE_ENS")
+    1364        .dwattr $C$DW$112, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x20)
+    1365        .dwattr $C$DW$112, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1366        .dwattr $C$DW$112, DW_AT_accessibility(DW_ACCESS_public)
+    1367        .dwattr $C$DW$112, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1368        .dwattr $C$DW$112, DW_AT_decl_line(0x4a)
+    1369        .dwattr $C$DW$112, DW_AT_decl_column(0x0d)
+    1370        .dwendtag $C$DW$T$38
+    1371
+    1372        .dwattr $C$DW$T$38, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1373        .dwattr $C$DW$T$38, DW_AT_decl_line(0x49)
+    1374        .dwattr $C$DW$T$38, DW_AT_decl_column(0x13)
+    1375$C$DW$T$78      .dwtag  DW_TAG_volatile_type
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   26
+
+    1376        .dwattr $C$DW$T$78, DW_AT_type(*$C$DW$T$38)
+    1377
+    1378$C$DW$T$39      .dwtag  DW_TAG_structure_type
+    1379        .dwattr $C$DW$T$39, DW_AT_byte_size(0x04)
+    1380$C$DW$113       .dwtag  DW_TAG_member
+    1381        .dwattr $C$DW$113, DW_AT_type(*$C$DW$T$11)
+    1382        .dwattr $C$DW$113, DW_AT_name("CYCLECOUNT")
+    1383        .dwattr $C$DW$113, DW_AT_TI_symbol_name("CYCLECOUNT")
+    1384        .dwattr $C$DW$113, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x20)
+    1385        .dwattr $C$DW$113, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1386        .dwattr $C$DW$113, DW_AT_accessibility(DW_ACCESS_public)
+    1387        .dwattr $C$DW$113, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1388        .dwattr $C$DW$113, DW_AT_decl_line(0x54)
+    1389        .dwattr $C$DW$113, DW_AT_decl_column(0x0d)
+    1390        .dwendtag $C$DW$T$39
+    1391
+    1392        .dwattr $C$DW$T$39, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1393        .dwattr $C$DW$T$39, DW_AT_decl_line(0x53)
+    1394        .dwattr $C$DW$T$39, DW_AT_decl_column(0x13)
+    1395$C$DW$T$80      .dwtag  DW_TAG_volatile_type
+    1396        .dwattr $C$DW$T$80, DW_AT_type(*$C$DW$T$39)
+    1397
+    1398$C$DW$T$40      .dwtag  DW_TAG_structure_type
+    1399        .dwattr $C$DW$T$40, DW_AT_byte_size(0x04)
+    1400$C$DW$114       .dwtag  DW_TAG_member
+    1401        .dwattr $C$DW$114, DW_AT_type(*$C$DW$T$11)
+    1402        .dwattr $C$DW$114, DW_AT_name("STALLCOUNT")
+    1403        .dwattr $C$DW$114, DW_AT_TI_symbol_name("STALLCOUNT")
+    1404        .dwattr $C$DW$114, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x20)
+    1405        .dwattr $C$DW$114, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1406        .dwattr $C$DW$114, DW_AT_accessibility(DW_ACCESS_public)
+    1407        .dwattr $C$DW$114, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1408        .dwattr $C$DW$114, DW_AT_decl_line(0x5e)
+    1409        .dwattr $C$DW$114, DW_AT_decl_column(0x0d)
+    1410        .dwendtag $C$DW$T$40
+    1411
+    1412        .dwattr $C$DW$T$40, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1413        .dwattr $C$DW$T$40, DW_AT_decl_line(0x5d)
+    1414        .dwattr $C$DW$T$40, DW_AT_decl_column(0x14)
+    1415$C$DW$T$82      .dwtag  DW_TAG_volatile_type
+    1416        .dwattr $C$DW$T$82, DW_AT_type(*$C$DW$T$40)
+    1417
+    1418$C$DW$T$41      .dwtag  DW_TAG_structure_type
+    1419        .dwattr $C$DW$T$41, DW_AT_byte_size(0x04)
+    1420$C$DW$115       .dwtag  DW_TAG_member
+    1421        .dwattr $C$DW$115, DW_AT_type(*$C$DW$T$11)
+    1422        .dwattr $C$DW$115, DW_AT_name("C24_BLK_IDX")
+    1423        .dwattr $C$DW$115, DW_AT_TI_symbol_name("C24_BLK_IDX")
+    1424        .dwattr $C$DW$115, DW_AT_bit_offset(0x18), DW_AT_bit_size(0x08)
+    1425        .dwattr $C$DW$115, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1426        .dwattr $C$DW$115, DW_AT_accessibility(DW_ACCESS_public)
+    1427        .dwattr $C$DW$115, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1428        .dwattr $C$DW$115, DW_AT_decl_line(0x6b)
+    1429        .dwattr $C$DW$115, DW_AT_decl_column(0x0d)
+    1430$C$DW$116       .dwtag  DW_TAG_member
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   27
+
+    1431        .dwattr $C$DW$116, DW_AT_type(*$C$DW$T$11)
+    1432        .dwattr $C$DW$116, DW_AT_name("rsvd8")
+    1433        .dwattr $C$DW$116, DW_AT_TI_symbol_name("rsvd8")
+    1434        .dwattr $C$DW$116, DW_AT_bit_offset(0x10), DW_AT_bit_size(0x08)
+    1435        .dwattr $C$DW$116, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1436        .dwattr $C$DW$116, DW_AT_accessibility(DW_ACCESS_public)
+    1437        .dwattr $C$DW$116, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1438        .dwattr $C$DW$116, DW_AT_decl_line(0x6c)
+    1439        .dwattr $C$DW$116, DW_AT_decl_column(0x0d)
+    1440$C$DW$117       .dwtag  DW_TAG_member
+    1441        .dwattr $C$DW$117, DW_AT_type(*$C$DW$T$11)
+    1442        .dwattr $C$DW$117, DW_AT_name("C25_BLK_IDX")
+    1443        .dwattr $C$DW$117, DW_AT_TI_symbol_name("C25_BLK_IDX")
+    1444        .dwattr $C$DW$117, DW_AT_bit_offset(0x08), DW_AT_bit_size(0x08)
+    1445        .dwattr $C$DW$117, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1446        .dwattr $C$DW$117, DW_AT_accessibility(DW_ACCESS_public)
+    1447        .dwattr $C$DW$117, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1448        .dwattr $C$DW$117, DW_AT_decl_line(0x6d)
+    1449        .dwattr $C$DW$117, DW_AT_decl_column(0x0d)
+    1450$C$DW$118       .dwtag  DW_TAG_member
+    1451        .dwattr $C$DW$118, DW_AT_type(*$C$DW$T$11)
+    1452        .dwattr $C$DW$118, DW_AT_name("rsvd24")
+    1453        .dwattr $C$DW$118, DW_AT_TI_symbol_name("rsvd24")
+    1454        .dwattr $C$DW$118, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x08)
+    1455        .dwattr $C$DW$118, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1456        .dwattr $C$DW$118, DW_AT_accessibility(DW_ACCESS_public)
+    1457        .dwattr $C$DW$118, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1458        .dwattr $C$DW$118, DW_AT_decl_line(0x6e)
+    1459        .dwattr $C$DW$118, DW_AT_decl_column(0x0d)
+    1460        .dwendtag $C$DW$T$41
+    1461
+    1462        .dwattr $C$DW$T$41, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1463        .dwattr $C$DW$T$41, DW_AT_decl_line(0x6a)
+    1464        .dwattr $C$DW$T$41, DW_AT_decl_column(0x13)
+    1465$C$DW$T$84      .dwtag  DW_TAG_volatile_type
+    1466        .dwattr $C$DW$T$84, DW_AT_type(*$C$DW$T$41)
+    1467
+    1468$C$DW$T$42      .dwtag  DW_TAG_structure_type
+    1469        .dwattr $C$DW$T$42, DW_AT_byte_size(0x04)
+    1470$C$DW$119       .dwtag  DW_TAG_member
+    1471        .dwattr $C$DW$119, DW_AT_type(*$C$DW$T$11)
+    1472        .dwattr $C$DW$119, DW_AT_name("C26_BLK_IDX")
+    1473        .dwattr $C$DW$119, DW_AT_TI_symbol_name("C26_BLK_IDX")
+    1474        .dwattr $C$DW$119, DW_AT_bit_offset(0x18), DW_AT_bit_size(0x08)
+    1475        .dwattr $C$DW$119, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1476        .dwattr $C$DW$119, DW_AT_accessibility(DW_ACCESS_public)
+    1477        .dwattr $C$DW$119, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1478        .dwattr $C$DW$119, DW_AT_decl_line(0x78)
+    1479        .dwattr $C$DW$119, DW_AT_decl_column(0x0d)
+    1480$C$DW$120       .dwtag  DW_TAG_member
+    1481        .dwattr $C$DW$120, DW_AT_type(*$C$DW$T$11)
+    1482        .dwattr $C$DW$120, DW_AT_name("rsvd8")
+    1483        .dwattr $C$DW$120, DW_AT_TI_symbol_name("rsvd8")
+    1484        .dwattr $C$DW$120, DW_AT_bit_offset(0x10), DW_AT_bit_size(0x08)
+    1485        .dwattr $C$DW$120, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   28
+
+    1486        .dwattr $C$DW$120, DW_AT_accessibility(DW_ACCESS_public)
+    1487        .dwattr $C$DW$120, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1488        .dwattr $C$DW$120, DW_AT_decl_line(0x79)
+    1489        .dwattr $C$DW$120, DW_AT_decl_column(0x0d)
+    1490$C$DW$121       .dwtag  DW_TAG_member
+    1491        .dwattr $C$DW$121, DW_AT_type(*$C$DW$T$11)
+    1492        .dwattr $C$DW$121, DW_AT_name("C27_BLK_IDX")
+    1493        .dwattr $C$DW$121, DW_AT_TI_symbol_name("C27_BLK_IDX")
+    1494        .dwattr $C$DW$121, DW_AT_bit_offset(0x08), DW_AT_bit_size(0x08)
+    1495        .dwattr $C$DW$121, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1496        .dwattr $C$DW$121, DW_AT_accessibility(DW_ACCESS_public)
+    1497        .dwattr $C$DW$121, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1498        .dwattr $C$DW$121, DW_AT_decl_line(0x7a)
+    1499        .dwattr $C$DW$121, DW_AT_decl_column(0x0d)
+    1500$C$DW$122       .dwtag  DW_TAG_member
+    1501        .dwattr $C$DW$122, DW_AT_type(*$C$DW$T$11)
+    1502        .dwattr $C$DW$122, DW_AT_name("rsvd24")
+    1503        .dwattr $C$DW$122, DW_AT_TI_symbol_name("rsvd24")
+    1504        .dwattr $C$DW$122, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x08)
+    1505        .dwattr $C$DW$122, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1506        .dwattr $C$DW$122, DW_AT_accessibility(DW_ACCESS_public)
+    1507        .dwattr $C$DW$122, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1508        .dwattr $C$DW$122, DW_AT_decl_line(0x7b)
+    1509        .dwattr $C$DW$122, DW_AT_decl_column(0x0d)
+    1510        .dwendtag $C$DW$T$42
+    1511
+    1512        .dwattr $C$DW$T$42, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1513        .dwattr $C$DW$T$42, DW_AT_decl_line(0x77)
+    1514        .dwattr $C$DW$T$42, DW_AT_decl_column(0x13)
+    1515$C$DW$T$86      .dwtag  DW_TAG_volatile_type
+    1516        .dwattr $C$DW$T$86, DW_AT_type(*$C$DW$T$42)
+    1517
+    1518$C$DW$T$43      .dwtag  DW_TAG_structure_type
+    1519        .dwattr $C$DW$T$43, DW_AT_byte_size(0x04)
+    1520$C$DW$123       .dwtag  DW_TAG_member
+    1521        .dwattr $C$DW$123, DW_AT_type(*$C$DW$T$11)
+    1522        .dwattr $C$DW$123, DW_AT_name("C28_BLK_POINTER")
+    1523        .dwattr $C$DW$123, DW_AT_TI_symbol_name("C28_BLK_POINTER")
+    1524        .dwattr $C$DW$123, DW_AT_bit_offset(0x10), DW_AT_bit_size(0x10)
+    1525        .dwattr $C$DW$123, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1526        .dwattr $C$DW$123, DW_AT_accessibility(DW_ACCESS_public)
+    1527        .dwattr $C$DW$123, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1528        .dwattr $C$DW$123, DW_AT_decl_line(0x85)
+    1529        .dwattr $C$DW$123, DW_AT_decl_column(0x0d)
+    1530$C$DW$124       .dwtag  DW_TAG_member
+    1531        .dwattr $C$DW$124, DW_AT_type(*$C$DW$T$11)
+    1532        .dwattr $C$DW$124, DW_AT_name("C29_BLK_POINTER")
+    1533        .dwattr $C$DW$124, DW_AT_TI_symbol_name("C29_BLK_POINTER")
+    1534        .dwattr $C$DW$124, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x10)
+    1535        .dwattr $C$DW$124, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1536        .dwattr $C$DW$124, DW_AT_accessibility(DW_ACCESS_public)
+    1537        .dwattr $C$DW$124, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1538        .dwattr $C$DW$124, DW_AT_decl_line(0x86)
+    1539        .dwattr $C$DW$124, DW_AT_decl_column(0x0d)
+    1540        .dwendtag $C$DW$T$43
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   29
+
+    1541
+    1542        .dwattr $C$DW$T$43, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1543        .dwattr $C$DW$T$43, DW_AT_decl_line(0x84)
+    1544        .dwattr $C$DW$T$43, DW_AT_decl_column(0x13)
+    1545$C$DW$T$88      .dwtag  DW_TAG_volatile_type
+    1546        .dwattr $C$DW$T$88, DW_AT_type(*$C$DW$T$43)
+    1547
+    1548$C$DW$T$44      .dwtag  DW_TAG_structure_type
+    1549        .dwattr $C$DW$T$44, DW_AT_byte_size(0x04)
+    1550$C$DW$125       .dwtag  DW_TAG_member
+    1551        .dwattr $C$DW$125, DW_AT_type(*$C$DW$T$11)
+    1552        .dwattr $C$DW$125, DW_AT_name("C30_BLK_POINTER")
+    1553        .dwattr $C$DW$125, DW_AT_TI_symbol_name("C30_BLK_POINTER")
+    1554        .dwattr $C$DW$125, DW_AT_bit_offset(0x10), DW_AT_bit_size(0x10)
+    1555        .dwattr $C$DW$125, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1556        .dwattr $C$DW$125, DW_AT_accessibility(DW_ACCESS_public)
+    1557        .dwattr $C$DW$125, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1558        .dwattr $C$DW$125, DW_AT_decl_line(0x90)
+    1559        .dwattr $C$DW$125, DW_AT_decl_column(0x0d)
+    1560$C$DW$126       .dwtag  DW_TAG_member
+    1561        .dwattr $C$DW$126, DW_AT_type(*$C$DW$T$11)
+    1562        .dwattr $C$DW$126, DW_AT_name("C31_BLK_POINTER")
+    1563        .dwattr $C$DW$126, DW_AT_TI_symbol_name("C31_BLK_POINTER")
+    1564        .dwattr $C$DW$126, DW_AT_bit_offset(0x00), DW_AT_bit_size(0x10)
+    1565        .dwattr $C$DW$126, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1566        .dwattr $C$DW$126, DW_AT_accessibility(DW_ACCESS_public)
+    1567        .dwattr $C$DW$126, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1568        .dwattr $C$DW$126, DW_AT_decl_line(0x91)
+    1569        .dwattr $C$DW$126, DW_AT_decl_column(0x0d)
+    1570        .dwendtag $C$DW$T$44
+    1571
+    1572        .dwattr $C$DW$T$44, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1573        .dwattr $C$DW$T$44, DW_AT_decl_line(0x8f)
+    1574        .dwattr $C$DW$T$44, DW_AT_decl_column(0x13)
+    1575$C$DW$T$90      .dwtag  DW_TAG_volatile_type
+    1576        .dwattr $C$DW$T$90, DW_AT_type(*$C$DW$T$44)
+    1577
+    1578$C$DW$T$46      .dwtag  DW_TAG_structure_type
+    1579        .dwattr $C$DW$T$46, DW_AT_byte_size(0x30)
+    1580$C$DW$127       .dwtag  DW_TAG_member
+    1581        .dwattr $C$DW$127, DW_AT_type(*$C$DW$T$75)
+    1582        .dwattr $C$DW$127, DW_AT_name("$P$T13")
+    1583        .dwattr $C$DW$127, DW_AT_TI_symbol_name("$P$T13")
+    1584        .dwattr $C$DW$127, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1585        .dwattr $C$DW$127, DW_AT_accessibility(DW_ACCESS_public)
+    1586        .dwattr $C$DW$127, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1587        .dwattr $C$DW$127, DW_AT_decl_line(0x29)
+    1588        .dwattr $C$DW$127, DW_AT_decl_column(0x02)
+    1589$C$DW$128       .dwtag  DW_TAG_member
+    1590        .dwattr $C$DW$128, DW_AT_type(*$C$DW$T$77)
+    1591        .dwattr $C$DW$128, DW_AT_name("$P$T14")
+    1592        .dwattr $C$DW$128, DW_AT_TI_symbol_name("$P$T14")
+    1593        .dwattr $C$DW$128, DW_AT_data_member_location[DW_OP_plus_uconst 0x4]
+    1594        .dwattr $C$DW$128, DW_AT_accessibility(DW_ACCESS_public)
+    1595        .dwattr $C$DW$128, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   30
+
+    1596        .dwattr $C$DW$128, DW_AT_decl_line(0x3b)
+    1597        .dwattr $C$DW$128, DW_AT_decl_column(0x02)
+    1598$C$DW$129       .dwtag  DW_TAG_member
+    1599        .dwattr $C$DW$129, DW_AT_type(*$C$DW$T$79)
+    1600        .dwattr $C$DW$129, DW_AT_name("$P$T15")
+    1601        .dwattr $C$DW$129, DW_AT_TI_symbol_name("$P$T15")
+    1602        .dwattr $C$DW$129, DW_AT_data_member_location[DW_OP_plus_uconst 0x8]
+    1603        .dwattr $C$DW$129, DW_AT_accessibility(DW_ACCESS_public)
+    1604        .dwattr $C$DW$129, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1605        .dwattr $C$DW$129, DW_AT_decl_line(0x46)
+    1606        .dwattr $C$DW$129, DW_AT_decl_column(0x02)
+    1607$C$DW$130       .dwtag  DW_TAG_member
+    1608        .dwattr $C$DW$130, DW_AT_type(*$C$DW$T$81)
+    1609        .dwattr $C$DW$130, DW_AT_name("$P$T16")
+    1610        .dwattr $C$DW$130, DW_AT_TI_symbol_name("$P$T16")
+    1611        .dwattr $C$DW$130, DW_AT_data_member_location[DW_OP_plus_uconst 0xc]
+    1612        .dwattr $C$DW$130, DW_AT_accessibility(DW_ACCESS_public)
+    1613        .dwattr $C$DW$130, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1614        .dwattr $C$DW$130, DW_AT_decl_line(0x50)
+    1615        .dwattr $C$DW$130, DW_AT_decl_column(0x02)
+    1616$C$DW$131       .dwtag  DW_TAG_member
+    1617        .dwattr $C$DW$131, DW_AT_type(*$C$DW$T$83)
+    1618        .dwattr $C$DW$131, DW_AT_name("$P$T17")
+    1619        .dwattr $C$DW$131, DW_AT_TI_symbol_name("$P$T17")
+    1620        .dwattr $C$DW$131, DW_AT_data_member_location[DW_OP_plus_uconst 0x10]
+    1621        .dwattr $C$DW$131, DW_AT_accessibility(DW_ACCESS_public)
+    1622        .dwattr $C$DW$131, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1623        .dwattr $C$DW$131, DW_AT_decl_line(0x5a)
+    1624        .dwattr $C$DW$131, DW_AT_decl_column(0x02)
+    1625$C$DW$132       .dwtag  DW_TAG_member
+    1626        .dwattr $C$DW$132, DW_AT_type(*$C$DW$T$45)
+    1627        .dwattr $C$DW$132, DW_AT_name("rsvd14")
+    1628        .dwattr $C$DW$132, DW_AT_TI_symbol_name("rsvd14")
+    1629        .dwattr $C$DW$132, DW_AT_data_member_location[DW_OP_plus_uconst 0x14]
+    1630        .dwattr $C$DW$132, DW_AT_accessibility(DW_ACCESS_public)
+    1631        .dwattr $C$DW$132, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1632        .dwattr $C$DW$132, DW_AT_decl_line(0x63)
+    1633        .dwattr $C$DW$132, DW_AT_decl_column(0x0b)
+    1634$C$DW$133       .dwtag  DW_TAG_member
+    1635        .dwattr $C$DW$133, DW_AT_type(*$C$DW$T$85)
+    1636        .dwattr $C$DW$133, DW_AT_name("$P$T18")
+    1637        .dwattr $C$DW$133, DW_AT_TI_symbol_name("$P$T18")
+    1638        .dwattr $C$DW$133, DW_AT_data_member_location[DW_OP_plus_uconst 0x20]
+    1639        .dwattr $C$DW$133, DW_AT_accessibility(DW_ACCESS_public)
+    1640        .dwattr $C$DW$133, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1641        .dwattr $C$DW$133, DW_AT_decl_line(0x67)
+    1642        .dwattr $C$DW$133, DW_AT_decl_column(0x02)
+    1643$C$DW$134       .dwtag  DW_TAG_member
+    1644        .dwattr $C$DW$134, DW_AT_type(*$C$DW$T$87)
+    1645        .dwattr $C$DW$134, DW_AT_name("$P$T19")
+    1646        .dwattr $C$DW$134, DW_AT_TI_symbol_name("$P$T19")
+    1647        .dwattr $C$DW$134, DW_AT_data_member_location[DW_OP_plus_uconst 0x24]
+    1648        .dwattr $C$DW$134, DW_AT_accessibility(DW_ACCESS_public)
+    1649        .dwattr $C$DW$134, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1650        .dwattr $C$DW$134, DW_AT_decl_line(0x74)
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   31
+
+    1651        .dwattr $C$DW$134, DW_AT_decl_column(0x02)
+    1652$C$DW$135       .dwtag  DW_TAG_member
+    1653        .dwattr $C$DW$135, DW_AT_type(*$C$DW$T$89)
+    1654        .dwattr $C$DW$135, DW_AT_name("$P$T20")
+    1655        .dwattr $C$DW$135, DW_AT_TI_symbol_name("$P$T20")
+    1656        .dwattr $C$DW$135, DW_AT_data_member_location[DW_OP_plus_uconst 0x28]
+    1657        .dwattr $C$DW$135, DW_AT_accessibility(DW_ACCESS_public)
+    1658        .dwattr $C$DW$135, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1659        .dwattr $C$DW$135, DW_AT_decl_line(0x81)
+    1660        .dwattr $C$DW$135, DW_AT_decl_column(0x02)
+    1661$C$DW$136       .dwtag  DW_TAG_member
+    1662        .dwattr $C$DW$136, DW_AT_type(*$C$DW$T$91)
+    1663        .dwattr $C$DW$136, DW_AT_name("$P$T21")
+    1664        .dwattr $C$DW$136, DW_AT_TI_symbol_name("$P$T21")
+    1665        .dwattr $C$DW$136, DW_AT_data_member_location[DW_OP_plus_uconst 0x2c]
+    1666        .dwattr $C$DW$136, DW_AT_accessibility(DW_ACCESS_public)
+    1667        .dwattr $C$DW$136, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1668        .dwattr $C$DW$136, DW_AT_decl_line(0x8c)
+    1669        .dwattr $C$DW$136, DW_AT_decl_column(0x02)
+    1670        .dwendtag $C$DW$T$46
+    1671
+    1672        .dwattr $C$DW$T$46, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1673        .dwattr $C$DW$T$46, DW_AT_decl_line(0x26)
+    1674        .dwattr $C$DW$T$46, DW_AT_decl_column(0x10)
+    1675$C$DW$T$102     .dwtag  DW_TAG_typedef, DW_AT_name("pruCtrl")
+    1676        .dwattr $C$DW$T$102, DW_AT_type(*$C$DW$T$46)
+    1677        .dwattr $C$DW$T$102, DW_AT_language(DW_LANG_C)
+    1678        .dwattr $C$DW$T$102, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/
+    1679        .dwattr $C$DW$T$102, DW_AT_decl_line(0x95)
+    1680        .dwattr $C$DW$T$102, DW_AT_decl_column(0x03)
+    1681
+    1682$C$DW$T$49      .dwtag  DW_TAG_union_type
+    1683        .dwattr $C$DW$T$49, DW_AT_byte_size(0x04)
+    1684$C$DW$137       .dwtag  DW_TAG_member
+    1685        .dwattr $C$DW$137, DW_AT_type(*$C$DW$T$47)
+    1686        .dwattr $C$DW$137, DW_AT_name("REVID")
+    1687        .dwattr $C$DW$137, DW_AT_TI_symbol_name("REVID")
+    1688        .dwattr $C$DW$137, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1689        .dwattr $C$DW$137, DW_AT_accessibility(DW_ACCESS_public)
+    1690        .dwattr $C$DW$137, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1691        .dwattr $C$DW$137, DW_AT_decl_line(0x2a)
+    1692        .dwattr $C$DW$137, DW_AT_decl_column(0x15)
+    1693$C$DW$138       .dwtag  DW_TAG_member
+    1694        .dwattr $C$DW$138, DW_AT_type(*$C$DW$T$48)
+    1695        .dwattr $C$DW$138, DW_AT_name("REVID_bit")
+    1696        .dwattr $C$DW$138, DW_AT_TI_symbol_name("REVID_bit")
+    1697        .dwattr $C$DW$138, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1698        .dwattr $C$DW$138, DW_AT_accessibility(DW_ACCESS_public)
+    1699        .dwattr $C$DW$138, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1700        .dwattr $C$DW$138, DW_AT_decl_line(0x2e)
+    1701        .dwattr $C$DW$138, DW_AT_decl_column(0x05)
+    1702        .dwendtag $C$DW$T$49
+    1703
+    1704        .dwattr $C$DW$T$49, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1705        .dwattr $C$DW$T$49, DW_AT_decl_line(0x29)
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   32
+
+    1706        .dwattr $C$DW$T$49, DW_AT_decl_column(0x08)
+    1707
+    1708$C$DW$T$51      .dwtag  DW_TAG_union_type
+    1709        .dwattr $C$DW$T$51, DW_AT_byte_size(0x04)
+    1710$C$DW$139       .dwtag  DW_TAG_member
+    1711        .dwattr $C$DW$139, DW_AT_type(*$C$DW$T$47)
+    1712        .dwattr $C$DW$139, DW_AT_name("SYSCFG")
+    1713        .dwattr $C$DW$139, DW_AT_TI_symbol_name("SYSCFG")
+    1714        .dwattr $C$DW$139, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1715        .dwattr $C$DW$139, DW_AT_accessibility(DW_ACCESS_public)
+    1716        .dwattr $C$DW$139, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1717        .dwattr $C$DW$139, DW_AT_decl_line(0x34)
+    1718        .dwattr $C$DW$139, DW_AT_decl_column(0x15)
+    1719$C$DW$140       .dwtag  DW_TAG_member
+    1720        .dwattr $C$DW$140, DW_AT_type(*$C$DW$T$50)
+    1721        .dwattr $C$DW$140, DW_AT_name("SYSCFG_bit")
+    1722        .dwattr $C$DW$140, DW_AT_TI_symbol_name("SYSCFG_bit")
+    1723        .dwattr $C$DW$140, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1724        .dwattr $C$DW$140, DW_AT_accessibility(DW_ACCESS_public)
+    1725        .dwattr $C$DW$140, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1726        .dwattr $C$DW$140, DW_AT_decl_line(0x3c)
+    1727        .dwattr $C$DW$140, DW_AT_decl_column(0x05)
+    1728        .dwendtag $C$DW$T$51
+    1729
+    1730        .dwattr $C$DW$T$51, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1731        .dwattr $C$DW$T$51, DW_AT_decl_line(0x33)
+    1732        .dwattr $C$DW$T$51, DW_AT_decl_column(0x08)
+    1733
+    1734$C$DW$T$53      .dwtag  DW_TAG_union_type
+    1735        .dwattr $C$DW$T$53, DW_AT_byte_size(0x04)
+    1736$C$DW$141       .dwtag  DW_TAG_member
+    1737        .dwattr $C$DW$141, DW_AT_type(*$C$DW$T$47)
+    1738        .dwattr $C$DW$141, DW_AT_name("GPCFG0")
+    1739        .dwattr $C$DW$141, DW_AT_TI_symbol_name("GPCFG0")
+    1740        .dwattr $C$DW$141, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1741        .dwattr $C$DW$141, DW_AT_accessibility(DW_ACCESS_public)
+    1742        .dwattr $C$DW$141, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1743        .dwattr $C$DW$141, DW_AT_decl_line(0x42)
+    1744        .dwattr $C$DW$141, DW_AT_decl_column(0x15)
+    1745$C$DW$142       .dwtag  DW_TAG_member
+    1746        .dwattr $C$DW$142, DW_AT_type(*$C$DW$T$52)
+    1747        .dwattr $C$DW$142, DW_AT_name("GPCFG0_bit")
+    1748        .dwattr $C$DW$142, DW_AT_TI_symbol_name("GPCFG0_bit")
+    1749        .dwattr $C$DW$142, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1750        .dwattr $C$DW$142, DW_AT_accessibility(DW_ACCESS_public)
+    1751        .dwattr $C$DW$142, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1752        .dwattr $C$DW$142, DW_AT_decl_line(0x4f)
+    1753        .dwattr $C$DW$142, DW_AT_decl_column(0x05)
+    1754        .dwendtag $C$DW$T$53
+    1755
+    1756        .dwattr $C$DW$T$53, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1757        .dwattr $C$DW$T$53, DW_AT_decl_line(0x41)
+    1758        .dwattr $C$DW$T$53, DW_AT_decl_column(0x08)
+    1759
+    1760$C$DW$T$55      .dwtag  DW_TAG_union_type
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   33
+
+    1761        .dwattr $C$DW$T$55, DW_AT_byte_size(0x04)
+    1762$C$DW$143       .dwtag  DW_TAG_member
+    1763        .dwattr $C$DW$143, DW_AT_type(*$C$DW$T$47)
+    1764        .dwattr $C$DW$143, DW_AT_name("GPCFG1")
+    1765        .dwattr $C$DW$143, DW_AT_TI_symbol_name("GPCFG1")
+    1766        .dwattr $C$DW$143, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1767        .dwattr $C$DW$143, DW_AT_accessibility(DW_ACCESS_public)
+    1768        .dwattr $C$DW$143, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1769        .dwattr $C$DW$143, DW_AT_decl_line(0x55)
+    1770        .dwattr $C$DW$143, DW_AT_decl_column(0x15)
+    1771$C$DW$144       .dwtag  DW_TAG_member
+    1772        .dwattr $C$DW$144, DW_AT_type(*$C$DW$T$54)
+    1773        .dwattr $C$DW$144, DW_AT_name("GPCFG1_bit")
+    1774        .dwattr $C$DW$144, DW_AT_TI_symbol_name("GPCFG1_bit")
+    1775        .dwattr $C$DW$144, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1776        .dwattr $C$DW$144, DW_AT_accessibility(DW_ACCESS_public)
+    1777        .dwattr $C$DW$144, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1778        .dwattr $C$DW$144, DW_AT_decl_line(0x62)
+    1779        .dwattr $C$DW$144, DW_AT_decl_column(0x05)
+    1780        .dwendtag $C$DW$T$55
+    1781
+    1782        .dwattr $C$DW$T$55, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1783        .dwattr $C$DW$T$55, DW_AT_decl_line(0x54)
+    1784        .dwattr $C$DW$T$55, DW_AT_decl_column(0x08)
+    1785
+    1786$C$DW$T$57      .dwtag  DW_TAG_union_type
+    1787        .dwattr $C$DW$T$57, DW_AT_byte_size(0x04)
+    1788$C$DW$145       .dwtag  DW_TAG_member
+    1789        .dwattr $C$DW$145, DW_AT_type(*$C$DW$T$47)
+    1790        .dwattr $C$DW$145, DW_AT_name("CGR")
+    1791        .dwattr $C$DW$145, DW_AT_TI_symbol_name("CGR")
+    1792        .dwattr $C$DW$145, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1793        .dwattr $C$DW$145, DW_AT_accessibility(DW_ACCESS_public)
+    1794        .dwattr $C$DW$145, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1795        .dwattr $C$DW$145, DW_AT_decl_line(0x68)
+    1796        .dwattr $C$DW$145, DW_AT_decl_column(0x15)
+    1797$C$DW$146       .dwtag  DW_TAG_member
+    1798        .dwattr $C$DW$146, DW_AT_type(*$C$DW$T$56)
+    1799        .dwattr $C$DW$146, DW_AT_name("CGR_bit")
+    1800        .dwattr $C$DW$146, DW_AT_TI_symbol_name("CGR_bit")
+    1801        .dwattr $C$DW$146, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1802        .dwattr $C$DW$146, DW_AT_accessibility(DW_ACCESS_public)
+    1803        .dwattr $C$DW$146, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1804        .dwattr $C$DW$146, DW_AT_decl_line(0x7e)
+    1805        .dwattr $C$DW$146, DW_AT_decl_column(0x05)
+    1806        .dwendtag $C$DW$T$57
+    1807
+    1808        .dwattr $C$DW$T$57, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1809        .dwattr $C$DW$T$57, DW_AT_decl_line(0x67)
+    1810        .dwattr $C$DW$T$57, DW_AT_decl_column(0x08)
+    1811
+    1812$C$DW$T$59      .dwtag  DW_TAG_union_type
+    1813        .dwattr $C$DW$T$59, DW_AT_byte_size(0x04)
+    1814$C$DW$147       .dwtag  DW_TAG_member
+    1815        .dwattr $C$DW$147, DW_AT_type(*$C$DW$T$47)
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   34
+
+    1816        .dwattr $C$DW$147, DW_AT_name("ISRP")
+    1817        .dwattr $C$DW$147, DW_AT_TI_symbol_name("ISRP")
+    1818        .dwattr $C$DW$147, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1819        .dwattr $C$DW$147, DW_AT_accessibility(DW_ACCESS_public)
+    1820        .dwattr $C$DW$147, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1821        .dwattr $C$DW$147, DW_AT_decl_line(0x84)
+    1822        .dwattr $C$DW$147, DW_AT_decl_column(0x15)
+    1823$C$DW$148       .dwtag  DW_TAG_member
+    1824        .dwattr $C$DW$148, DW_AT_type(*$C$DW$T$58)
+    1825        .dwattr $C$DW$148, DW_AT_name("ISRP_bit")
+    1826        .dwattr $C$DW$148, DW_AT_TI_symbol_name("ISRP_bit")
+    1827        .dwattr $C$DW$148, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1828        .dwattr $C$DW$148, DW_AT_accessibility(DW_ACCESS_public)
+    1829        .dwattr $C$DW$148, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1830        .dwattr $C$DW$148, DW_AT_decl_line(0x8d)
+    1831        .dwattr $C$DW$148, DW_AT_decl_column(0x05)
+    1832        .dwendtag $C$DW$T$59
+    1833
+    1834        .dwattr $C$DW$T$59, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1835        .dwattr $C$DW$T$59, DW_AT_decl_line(0x83)
+    1836        .dwattr $C$DW$T$59, DW_AT_decl_column(0x08)
+    1837
+    1838$C$DW$T$61      .dwtag  DW_TAG_union_type
+    1839        .dwattr $C$DW$T$61, DW_AT_byte_size(0x04)
+    1840$C$DW$149       .dwtag  DW_TAG_member
+    1841        .dwattr $C$DW$149, DW_AT_type(*$C$DW$T$47)
+    1842        .dwattr $C$DW$149, DW_AT_name("ISP")
+    1843        .dwattr $C$DW$149, DW_AT_TI_symbol_name("ISP")
+    1844        .dwattr $C$DW$149, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1845        .dwattr $C$DW$149, DW_AT_accessibility(DW_ACCESS_public)
+    1846        .dwattr $C$DW$149, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1847        .dwattr $C$DW$149, DW_AT_decl_line(0x93)
+    1848        .dwattr $C$DW$149, DW_AT_decl_column(0x15)
+    1849$C$DW$150       .dwtag  DW_TAG_member
+    1850        .dwattr $C$DW$150, DW_AT_type(*$C$DW$T$60)
+    1851        .dwattr $C$DW$150, DW_AT_name("ISP_bit")
+    1852        .dwattr $C$DW$150, DW_AT_TI_symbol_name("ISP_bit")
+    1853        .dwattr $C$DW$150, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1854        .dwattr $C$DW$150, DW_AT_accessibility(DW_ACCESS_public)
+    1855        .dwattr $C$DW$150, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1856        .dwattr $C$DW$150, DW_AT_decl_line(0x9c)
+    1857        .dwattr $C$DW$150, DW_AT_decl_column(0x05)
+    1858        .dwendtag $C$DW$T$61
+    1859
+    1860        .dwattr $C$DW$T$61, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1861        .dwattr $C$DW$T$61, DW_AT_decl_line(0x92)
+    1862        .dwattr $C$DW$T$61, DW_AT_decl_column(0x08)
+    1863
+    1864$C$DW$T$63      .dwtag  DW_TAG_union_type
+    1865        .dwattr $C$DW$T$63, DW_AT_byte_size(0x04)
+    1866$C$DW$151       .dwtag  DW_TAG_member
+    1867        .dwattr $C$DW$151, DW_AT_type(*$C$DW$T$47)
+    1868        .dwattr $C$DW$151, DW_AT_name("IESP")
+    1869        .dwattr $C$DW$151, DW_AT_TI_symbol_name("IESP")
+    1870        .dwattr $C$DW$151, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   35
+
+    1871        .dwattr $C$DW$151, DW_AT_accessibility(DW_ACCESS_public)
+    1872        .dwattr $C$DW$151, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1873        .dwattr $C$DW$151, DW_AT_decl_line(0xa1)
+    1874        .dwattr $C$DW$151, DW_AT_decl_column(0x15)
+    1875$C$DW$152       .dwtag  DW_TAG_member
+    1876        .dwattr $C$DW$152, DW_AT_type(*$C$DW$T$62)
+    1877        .dwattr $C$DW$152, DW_AT_name("IESP_bit")
+    1878        .dwattr $C$DW$152, DW_AT_TI_symbol_name("IESP_bit")
+    1879        .dwattr $C$DW$152, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1880        .dwattr $C$DW$152, DW_AT_accessibility(DW_ACCESS_public)
+    1881        .dwattr $C$DW$152, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1882        .dwattr $C$DW$152, DW_AT_decl_line(0xaa)
+    1883        .dwattr $C$DW$152, DW_AT_decl_column(0x05)
+    1884        .dwendtag $C$DW$T$63
+    1885
+    1886        .dwattr $C$DW$T$63, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1887        .dwattr $C$DW$T$63, DW_AT_decl_line(0xa0)
+    1888        .dwattr $C$DW$T$63, DW_AT_decl_column(0x08)
+    1889
+    1890$C$DW$T$65      .dwtag  DW_TAG_union_type
+    1891        .dwattr $C$DW$T$65, DW_AT_byte_size(0x04)
+    1892$C$DW$153       .dwtag  DW_TAG_member
+    1893        .dwattr $C$DW$153, DW_AT_type(*$C$DW$T$47)
+    1894        .dwattr $C$DW$153, DW_AT_name("IECP")
+    1895        .dwattr $C$DW$153, DW_AT_TI_symbol_name("IECP")
+    1896        .dwattr $C$DW$153, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1897        .dwattr $C$DW$153, DW_AT_accessibility(DW_ACCESS_public)
+    1898        .dwattr $C$DW$153, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1899        .dwattr $C$DW$153, DW_AT_decl_line(0xb0)
+    1900        .dwattr $C$DW$153, DW_AT_decl_column(0x15)
+    1901$C$DW$154       .dwtag  DW_TAG_member
+    1902        .dwattr $C$DW$154, DW_AT_type(*$C$DW$T$64)
+    1903        .dwattr $C$DW$154, DW_AT_name("IECP_bit")
+    1904        .dwattr $C$DW$154, DW_AT_TI_symbol_name("IECP_bit")
+    1905        .dwattr $C$DW$154, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1906        .dwattr $C$DW$154, DW_AT_accessibility(DW_ACCESS_public)
+    1907        .dwattr $C$DW$154, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1908        .dwattr $C$DW$154, DW_AT_decl_line(0xb8)
+    1909        .dwattr $C$DW$154, DW_AT_decl_column(0x05)
+    1910        .dwendtag $C$DW$T$65
+    1911
+    1912        .dwattr $C$DW$T$65, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1913        .dwattr $C$DW$T$65, DW_AT_decl_line(0xaf)
+    1914        .dwattr $C$DW$T$65, DW_AT_decl_column(0x08)
+    1915
+    1916$C$DW$T$67      .dwtag  DW_TAG_union_type
+    1917        .dwattr $C$DW$T$67, DW_AT_byte_size(0x04)
+    1918$C$DW$155       .dwtag  DW_TAG_member
+    1919        .dwattr $C$DW$155, DW_AT_type(*$C$DW$T$47)
+    1920        .dwattr $C$DW$155, DW_AT_name("PMAO")
+    1921        .dwattr $C$DW$155, DW_AT_TI_symbol_name("PMAO")
+    1922        .dwattr $C$DW$155, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1923        .dwattr $C$DW$155, DW_AT_accessibility(DW_ACCESS_public)
+    1924        .dwattr $C$DW$155, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1925        .dwattr $C$DW$155, DW_AT_decl_line(0xc1)
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   36
+
+    1926        .dwattr $C$DW$155, DW_AT_decl_column(0x15)
+    1927$C$DW$156       .dwtag  DW_TAG_member
+    1928        .dwattr $C$DW$156, DW_AT_type(*$C$DW$T$66)
+    1929        .dwattr $C$DW$156, DW_AT_name("PMAO_bit")
+    1930        .dwattr $C$DW$156, DW_AT_TI_symbol_name("PMAO_bit")
+    1931        .dwattr $C$DW$156, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1932        .dwattr $C$DW$156, DW_AT_accessibility(DW_ACCESS_public)
+    1933        .dwattr $C$DW$156, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1934        .dwattr $C$DW$156, DW_AT_decl_line(0xc7)
+    1935        .dwattr $C$DW$156, DW_AT_decl_column(0x05)
+    1936        .dwendtag $C$DW$T$67
+    1937
+    1938        .dwattr $C$DW$T$67, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1939        .dwattr $C$DW$T$67, DW_AT_decl_line(0xc0)
+    1940        .dwattr $C$DW$T$67, DW_AT_decl_column(0x08)
+    1941
+    1942$C$DW$T$69      .dwtag  DW_TAG_union_type
+    1943        .dwattr $C$DW$T$69, DW_AT_byte_size(0x04)
+    1944$C$DW$157       .dwtag  DW_TAG_member
+    1945        .dwattr $C$DW$157, DW_AT_type(*$C$DW$T$47)
+    1946        .dwattr $C$DW$157, DW_AT_name("IEPCLK")
+    1947        .dwattr $C$DW$157, DW_AT_TI_symbol_name("IEPCLK")
+    1948        .dwattr $C$DW$157, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1949        .dwattr $C$DW$157, DW_AT_accessibility(DW_ACCESS_public)
+    1950        .dwattr $C$DW$157, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1951        .dwattr $C$DW$157, DW_AT_decl_line(0xd0)
+    1952        .dwattr $C$DW$157, DW_AT_decl_column(0x15)
+    1953$C$DW$158       .dwtag  DW_TAG_member
+    1954        .dwattr $C$DW$158, DW_AT_type(*$C$DW$T$68)
+    1955        .dwattr $C$DW$158, DW_AT_name("IEPCLK_bit")
+    1956        .dwattr $C$DW$158, DW_AT_TI_symbol_name("IEPCLK_bit")
+    1957        .dwattr $C$DW$158, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1958        .dwattr $C$DW$158, DW_AT_accessibility(DW_ACCESS_public)
+    1959        .dwattr $C$DW$158, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1960        .dwattr $C$DW$158, DW_AT_decl_line(0xd5)
+    1961        .dwattr $C$DW$158, DW_AT_decl_column(0x05)
+    1962        .dwendtag $C$DW$T$69
+    1963
+    1964        .dwattr $C$DW$T$69, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1965        .dwattr $C$DW$T$69, DW_AT_decl_line(0xcf)
+    1966        .dwattr $C$DW$T$69, DW_AT_decl_column(0x08)
+    1967
+    1968$C$DW$T$71      .dwtag  DW_TAG_union_type
+    1969        .dwattr $C$DW$T$71, DW_AT_byte_size(0x04)
+    1970$C$DW$159       .dwtag  DW_TAG_member
+    1971        .dwattr $C$DW$159, DW_AT_type(*$C$DW$T$47)
+    1972        .dwattr $C$DW$159, DW_AT_name("SPP")
+    1973        .dwattr $C$DW$159, DW_AT_TI_symbol_name("SPP")
+    1974        .dwattr $C$DW$159, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1975        .dwattr $C$DW$159, DW_AT_accessibility(DW_ACCESS_public)
+    1976        .dwattr $C$DW$159, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1977        .dwattr $C$DW$159, DW_AT_decl_line(0xdb)
+    1978        .dwattr $C$DW$159, DW_AT_decl_column(0x15)
+    1979$C$DW$160       .dwtag  DW_TAG_member
+    1980        .dwattr $C$DW$160, DW_AT_type(*$C$DW$T$70)
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   37
+
+    1981        .dwattr $C$DW$160, DW_AT_name("SPP_bit")
+    1982        .dwattr $C$DW$160, DW_AT_TI_symbol_name("SPP_bit")
+    1983        .dwattr $C$DW$160, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    1984        .dwattr $C$DW$160, DW_AT_accessibility(DW_ACCESS_public)
+    1985        .dwattr $C$DW$160, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    1986        .dwattr $C$DW$160, DW_AT_decl_line(0xe1)
+    1987        .dwattr $C$DW$160, DW_AT_decl_column(0x05)
+    1988        .dwendtag $C$DW$T$71
+    1989
+    1990        .dwattr $C$DW$T$71, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    1991        .dwattr $C$DW$T$71, DW_AT_decl_line(0xda)
+    1992        .dwattr $C$DW$T$71, DW_AT_decl_column(0x08)
+    1993
+    1994$C$DW$T$73      .dwtag  DW_TAG_union_type
+    1995        .dwattr $C$DW$T$73, DW_AT_byte_size(0x04)
+    1996$C$DW$161       .dwtag  DW_TAG_member
+    1997        .dwattr $C$DW$161, DW_AT_type(*$C$DW$T$47)
+    1998        .dwattr $C$DW$161, DW_AT_name("PIN_MX")
+    1999        .dwattr $C$DW$161, DW_AT_TI_symbol_name("PIN_MX")
+    2000        .dwattr $C$DW$161, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2001        .dwattr $C$DW$161, DW_AT_accessibility(DW_ACCESS_public)
+    2002        .dwattr $C$DW$161, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2003        .dwattr $C$DW$161, DW_AT_decl_line(0xe9)
+    2004        .dwattr $C$DW$161, DW_AT_decl_column(0x15)
+    2005$C$DW$162       .dwtag  DW_TAG_member
+    2006        .dwattr $C$DW$162, DW_AT_type(*$C$DW$T$72)
+    2007        .dwattr $C$DW$162, DW_AT_name("PIN_MX_bit")
+    2008        .dwattr $C$DW$162, DW_AT_TI_symbol_name("PIN_MX_bit")
+    2009        .dwattr $C$DW$162, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2010        .dwattr $C$DW$162, DW_AT_accessibility(DW_ACCESS_public)
+    2011        .dwattr $C$DW$162, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2012        .dwattr $C$DW$162, DW_AT_decl_line(0xee)
+    2013        .dwattr $C$DW$162, DW_AT_decl_column(0x05)
+    2014        .dwendtag $C$DW$T$73
+    2015
+    2016        .dwattr $C$DW$T$73, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    2017        .dwattr $C$DW$T$73, DW_AT_decl_line(0xe8)
+    2018        .dwattr $C$DW$T$73, DW_AT_decl_column(0x08)
+    2019
+    2020$C$DW$T$75      .dwtag  DW_TAG_union_type
+    2021        .dwattr $C$DW$T$75, DW_AT_byte_size(0x04)
+    2022$C$DW$163       .dwtag  DW_TAG_member
+    2023        .dwattr $C$DW$163, DW_AT_type(*$C$DW$T$47)
+    2024        .dwattr $C$DW$163, DW_AT_name("CTRL")
+    2025        .dwattr $C$DW$163, DW_AT_TI_symbol_name("CTRL")
+    2026        .dwattr $C$DW$163, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2027        .dwattr $C$DW$163, DW_AT_accessibility(DW_ACCESS_public)
+    2028        .dwattr $C$DW$163, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2029        .dwattr $C$DW$163, DW_AT_decl_line(0x2a)
+    2030        .dwattr $C$DW$163, DW_AT_decl_column(0x15)
+    2031$C$DW$164       .dwtag  DW_TAG_member
+    2032        .dwattr $C$DW$164, DW_AT_type(*$C$DW$T$74)
+    2033        .dwattr $C$DW$164, DW_AT_name("CTRL_bit")
+    2034        .dwattr $C$DW$164, DW_AT_TI_symbol_name("CTRL_bit")
+    2035        .dwattr $C$DW$164, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   38
+
+    2036        .dwattr $C$DW$164, DW_AT_accessibility(DW_ACCESS_public)
+    2037        .dwattr $C$DW$164, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2038        .dwattr $C$DW$164, DW_AT_decl_line(0x36)
+    2039        .dwattr $C$DW$164, DW_AT_decl_column(0x05)
+    2040        .dwendtag $C$DW$T$75
+    2041
+    2042        .dwattr $C$DW$T$75, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    2043        .dwattr $C$DW$T$75, DW_AT_decl_line(0x29)
+    2044        .dwattr $C$DW$T$75, DW_AT_decl_column(0x08)
+    2045
+    2046$C$DW$T$77      .dwtag  DW_TAG_union_type
+    2047        .dwattr $C$DW$T$77, DW_AT_byte_size(0x04)
+    2048$C$DW$165       .dwtag  DW_TAG_member
+    2049        .dwattr $C$DW$165, DW_AT_type(*$C$DW$T$47)
+    2050        .dwattr $C$DW$165, DW_AT_name("STS")
+    2051        .dwattr $C$DW$165, DW_AT_TI_symbol_name("STS")
+    2052        .dwattr $C$DW$165, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2053        .dwattr $C$DW$165, DW_AT_accessibility(DW_ACCESS_public)
+    2054        .dwattr $C$DW$165, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2055        .dwattr $C$DW$165, DW_AT_decl_line(0x3c)
+    2056        .dwattr $C$DW$165, DW_AT_decl_column(0x15)
+    2057$C$DW$166       .dwtag  DW_TAG_member
+    2058        .dwattr $C$DW$166, DW_AT_type(*$C$DW$T$76)
+    2059        .dwattr $C$DW$166, DW_AT_name("STS_bit")
+    2060        .dwattr $C$DW$166, DW_AT_TI_symbol_name("STS_bit")
+    2061        .dwattr $C$DW$166, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2062        .dwattr $C$DW$166, DW_AT_accessibility(DW_ACCESS_public)
+    2063        .dwattr $C$DW$166, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2064        .dwattr $C$DW$166, DW_AT_decl_line(0x41)
+    2065        .dwattr $C$DW$166, DW_AT_decl_column(0x05)
+    2066        .dwendtag $C$DW$T$77
+    2067
+    2068        .dwattr $C$DW$T$77, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    2069        .dwattr $C$DW$T$77, DW_AT_decl_line(0x3b)
+    2070        .dwattr $C$DW$T$77, DW_AT_decl_column(0x08)
+    2071
+    2072$C$DW$T$79      .dwtag  DW_TAG_union_type
+    2073        .dwattr $C$DW$T$79, DW_AT_byte_size(0x04)
+    2074$C$DW$167       .dwtag  DW_TAG_member
+    2075        .dwattr $C$DW$167, DW_AT_type(*$C$DW$T$47)
+    2076        .dwattr $C$DW$167, DW_AT_name("WAKEUP_EN")
+    2077        .dwattr $C$DW$167, DW_AT_TI_symbol_name("WAKEUP_EN")
+    2078        .dwattr $C$DW$167, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2079        .dwattr $C$DW$167, DW_AT_accessibility(DW_ACCESS_public)
+    2080        .dwattr $C$DW$167, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2081        .dwattr $C$DW$167, DW_AT_decl_line(0x47)
+    2082        .dwattr $C$DW$167, DW_AT_decl_column(0x15)
+    2083$C$DW$168       .dwtag  DW_TAG_member
+    2084        .dwattr $C$DW$168, DW_AT_type(*$C$DW$T$78)
+    2085        .dwattr $C$DW$168, DW_AT_name("WAKEUP_EN_bit")
+    2086        .dwattr $C$DW$168, DW_AT_TI_symbol_name("WAKEUP_EN_bit")
+    2087        .dwattr $C$DW$168, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2088        .dwattr $C$DW$168, DW_AT_accessibility(DW_ACCESS_public)
+    2089        .dwattr $C$DW$168, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2090        .dwattr $C$DW$168, DW_AT_decl_line(0x4b)
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   39
+
+    2091        .dwattr $C$DW$168, DW_AT_decl_column(0x05)
+    2092        .dwendtag $C$DW$T$79
+    2093
+    2094        .dwattr $C$DW$T$79, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    2095        .dwattr $C$DW$T$79, DW_AT_decl_line(0x46)
+    2096        .dwattr $C$DW$T$79, DW_AT_decl_column(0x08)
+    2097
+    2098$C$DW$T$81      .dwtag  DW_TAG_union_type
+    2099        .dwattr $C$DW$T$81, DW_AT_byte_size(0x04)
+    2100$C$DW$169       .dwtag  DW_TAG_member
+    2101        .dwattr $C$DW$169, DW_AT_type(*$C$DW$T$47)
+    2102        .dwattr $C$DW$169, DW_AT_name("CYCLE")
+    2103        .dwattr $C$DW$169, DW_AT_TI_symbol_name("CYCLE")
+    2104        .dwattr $C$DW$169, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2105        .dwattr $C$DW$169, DW_AT_accessibility(DW_ACCESS_public)
+    2106        .dwattr $C$DW$169, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2107        .dwattr $C$DW$169, DW_AT_decl_line(0x51)
+    2108        .dwattr $C$DW$169, DW_AT_decl_column(0x15)
+    2109$C$DW$170       .dwtag  DW_TAG_member
+    2110        .dwattr $C$DW$170, DW_AT_type(*$C$DW$T$80)
+    2111        .dwattr $C$DW$170, DW_AT_name("CYCLE_bit")
+    2112        .dwattr $C$DW$170, DW_AT_TI_symbol_name("CYCLE_bit")
+    2113        .dwattr $C$DW$170, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2114        .dwattr $C$DW$170, DW_AT_accessibility(DW_ACCESS_public)
+    2115        .dwattr $C$DW$170, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2116        .dwattr $C$DW$170, DW_AT_decl_line(0x55)
+    2117        .dwattr $C$DW$170, DW_AT_decl_column(0x05)
+    2118        .dwendtag $C$DW$T$81
+    2119
+    2120        .dwattr $C$DW$T$81, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    2121        .dwattr $C$DW$T$81, DW_AT_decl_line(0x50)
+    2122        .dwattr $C$DW$T$81, DW_AT_decl_column(0x08)
+    2123
+    2124$C$DW$T$83      .dwtag  DW_TAG_union_type
+    2125        .dwattr $C$DW$T$83, DW_AT_byte_size(0x04)
+    2126$C$DW$171       .dwtag  DW_TAG_member
+    2127        .dwattr $C$DW$171, DW_AT_type(*$C$DW$T$47)
+    2128        .dwattr $C$DW$171, DW_AT_name("STALL")
+    2129        .dwattr $C$DW$171, DW_AT_TI_symbol_name("STALL")
+    2130        .dwattr $C$DW$171, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2131        .dwattr $C$DW$171, DW_AT_accessibility(DW_ACCESS_public)
+    2132        .dwattr $C$DW$171, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2133        .dwattr $C$DW$171, DW_AT_decl_line(0x5b)
+    2134        .dwattr $C$DW$171, DW_AT_decl_column(0x15)
+    2135$C$DW$172       .dwtag  DW_TAG_member
+    2136        .dwattr $C$DW$172, DW_AT_type(*$C$DW$T$82)
+    2137        .dwattr $C$DW$172, DW_AT_name("STALL_bit")
+    2138        .dwattr $C$DW$172, DW_AT_TI_symbol_name("STALL_bit")
+    2139        .dwattr $C$DW$172, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2140        .dwattr $C$DW$172, DW_AT_accessibility(DW_ACCESS_public)
+    2141        .dwattr $C$DW$172, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2142        .dwattr $C$DW$172, DW_AT_decl_line(0x5f)
+    2143        .dwattr $C$DW$172, DW_AT_decl_column(0x05)
+    2144        .dwendtag $C$DW$T$83
+    2145
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   40
+
+    2146        .dwattr $C$DW$T$83, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    2147        .dwattr $C$DW$T$83, DW_AT_decl_line(0x5a)
+    2148        .dwattr $C$DW$T$83, DW_AT_decl_column(0x08)
+    2149
+    2150$C$DW$T$85      .dwtag  DW_TAG_union_type
+    2151        .dwattr $C$DW$T$85, DW_AT_byte_size(0x04)
+    2152$C$DW$173       .dwtag  DW_TAG_member
+    2153        .dwattr $C$DW$173, DW_AT_type(*$C$DW$T$47)
+    2154        .dwattr $C$DW$173, DW_AT_name("CTBIR0")
+    2155        .dwattr $C$DW$173, DW_AT_TI_symbol_name("CTBIR0")
+    2156        .dwattr $C$DW$173, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2157        .dwattr $C$DW$173, DW_AT_accessibility(DW_ACCESS_public)
+    2158        .dwattr $C$DW$173, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2159        .dwattr $C$DW$173, DW_AT_decl_line(0x68)
+    2160        .dwattr $C$DW$173, DW_AT_decl_column(0x15)
+    2161$C$DW$174       .dwtag  DW_TAG_member
+    2162        .dwattr $C$DW$174, DW_AT_type(*$C$DW$T$84)
+    2163        .dwattr $C$DW$174, DW_AT_name("CTBIR0_bit")
+    2164        .dwattr $C$DW$174, DW_AT_TI_symbol_name("CTBIR0_bit")
+    2165        .dwattr $C$DW$174, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2166        .dwattr $C$DW$174, DW_AT_accessibility(DW_ACCESS_public)
+    2167        .dwattr $C$DW$174, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2168        .dwattr $C$DW$174, DW_AT_decl_line(0x6f)
+    2169        .dwattr $C$DW$174, DW_AT_decl_column(0x05)
+    2170        .dwendtag $C$DW$T$85
+    2171
+    2172        .dwattr $C$DW$T$85, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    2173        .dwattr $C$DW$T$85, DW_AT_decl_line(0x67)
+    2174        .dwattr $C$DW$T$85, DW_AT_decl_column(0x08)
+    2175
+    2176$C$DW$T$87      .dwtag  DW_TAG_union_type
+    2177        .dwattr $C$DW$T$87, DW_AT_byte_size(0x04)
+    2178$C$DW$175       .dwtag  DW_TAG_member
+    2179        .dwattr $C$DW$175, DW_AT_type(*$C$DW$T$47)
+    2180        .dwattr $C$DW$175, DW_AT_name("CTBIR1")
+    2181        .dwattr $C$DW$175, DW_AT_TI_symbol_name("CTBIR1")
+    2182        .dwattr $C$DW$175, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2183        .dwattr $C$DW$175, DW_AT_accessibility(DW_ACCESS_public)
+    2184        .dwattr $C$DW$175, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2185        .dwattr $C$DW$175, DW_AT_decl_line(0x75)
+    2186        .dwattr $C$DW$175, DW_AT_decl_column(0x15)
+    2187$C$DW$176       .dwtag  DW_TAG_member
+    2188        .dwattr $C$DW$176, DW_AT_type(*$C$DW$T$86)
+    2189        .dwattr $C$DW$176, DW_AT_name("CTBIR1_bit")
+    2190        .dwattr $C$DW$176, DW_AT_TI_symbol_name("CTBIR1_bit")
+    2191        .dwattr $C$DW$176, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2192        .dwattr $C$DW$176, DW_AT_accessibility(DW_ACCESS_public)
+    2193        .dwattr $C$DW$176, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2194        .dwattr $C$DW$176, DW_AT_decl_line(0x7c)
+    2195        .dwattr $C$DW$176, DW_AT_decl_column(0x05)
+    2196        .dwendtag $C$DW$T$87
+    2197
+    2198        .dwattr $C$DW$T$87, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    2199        .dwattr $C$DW$T$87, DW_AT_decl_line(0x74)
+    2200        .dwattr $C$DW$T$87, DW_AT_decl_column(0x08)
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   41
+
+    2201
+    2202$C$DW$T$89      .dwtag  DW_TAG_union_type
+    2203        .dwattr $C$DW$T$89, DW_AT_byte_size(0x04)
+    2204$C$DW$177       .dwtag  DW_TAG_member
+    2205        .dwattr $C$DW$177, DW_AT_type(*$C$DW$T$47)
+    2206        .dwattr $C$DW$177, DW_AT_name("CTPPR0")
+    2207        .dwattr $C$DW$177, DW_AT_TI_symbol_name("CTPPR0")
+    2208        .dwattr $C$DW$177, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2209        .dwattr $C$DW$177, DW_AT_accessibility(DW_ACCESS_public)
+    2210        .dwattr $C$DW$177, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2211        .dwattr $C$DW$177, DW_AT_decl_line(0x82)
+    2212        .dwattr $C$DW$177, DW_AT_decl_column(0x15)
+    2213$C$DW$178       .dwtag  DW_TAG_member
+    2214        .dwattr $C$DW$178, DW_AT_type(*$C$DW$T$88)
+    2215        .dwattr $C$DW$178, DW_AT_name("CTPPR0_bit")
+    2216        .dwattr $C$DW$178, DW_AT_TI_symbol_name("CTPPR0_bit")
+    2217        .dwattr $C$DW$178, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2218        .dwattr $C$DW$178, DW_AT_accessibility(DW_ACCESS_public)
+    2219        .dwattr $C$DW$178, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2220        .dwattr $C$DW$178, DW_AT_decl_line(0x87)
+    2221        .dwattr $C$DW$178, DW_AT_decl_column(0x05)
+    2222        .dwendtag $C$DW$T$89
+    2223
+    2224        .dwattr $C$DW$T$89, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    2225        .dwattr $C$DW$T$89, DW_AT_decl_line(0x81)
+    2226        .dwattr $C$DW$T$89, DW_AT_decl_column(0x08)
+    2227
+    2228$C$DW$T$91      .dwtag  DW_TAG_union_type
+    2229        .dwattr $C$DW$T$91, DW_AT_byte_size(0x04)
+    2230$C$DW$179       .dwtag  DW_TAG_member
+    2231        .dwattr $C$DW$179, DW_AT_type(*$C$DW$T$47)
+    2232        .dwattr $C$DW$179, DW_AT_name("CTPPR1")
+    2233        .dwattr $C$DW$179, DW_AT_TI_symbol_name("CTPPR1")
+    2234        .dwattr $C$DW$179, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2235        .dwattr $C$DW$179, DW_AT_accessibility(DW_ACCESS_public)
+    2236        .dwattr $C$DW$179, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2237        .dwattr $C$DW$179, DW_AT_decl_line(0x8d)
+    2238        .dwattr $C$DW$179, DW_AT_decl_column(0x15)
+    2239$C$DW$180       .dwtag  DW_TAG_member
+    2240        .dwattr $C$DW$180, DW_AT_type(*$C$DW$T$90)
+    2241        .dwattr $C$DW$180, DW_AT_name("CTPPR1_bit")
+    2242        .dwattr $C$DW$180, DW_AT_TI_symbol_name("CTPPR1_bit")
+    2243        .dwattr $C$DW$180, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2244        .dwattr $C$DW$180, DW_AT_accessibility(DW_ACCESS_public)
+    2245        .dwattr $C$DW$180, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/pr
+    2246        .dwattr $C$DW$180, DW_AT_decl_line(0x92)
+    2247        .dwattr $C$DW$180, DW_AT_decl_column(0x05)
+    2248        .dwendtag $C$DW$T$91
+    2249
+    2250        .dwattr $C$DW$T$91, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/am335x/p
+    2251        .dwattr $C$DW$T$91, DW_AT_decl_line(0x8c)
+    2252        .dwattr $C$DW$T$91, DW_AT_decl_column(0x08)
+    2253$C$DW$T$2       .dwtag  DW_TAG_unspecified_type
+    2254        .dwattr $C$DW$T$2, DW_AT_name("void")
+    2255$C$DW$T$4       .dwtag  DW_TAG_base_type
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   42
+
+    2256        .dwattr $C$DW$T$4, DW_AT_encoding(DW_ATE_boolean)
+    2257        .dwattr $C$DW$T$4, DW_AT_name("bool")
+    2258        .dwattr $C$DW$T$4, DW_AT_byte_size(0x01)
+    2259$C$DW$T$5       .dwtag  DW_TAG_base_type
+    2260        .dwattr $C$DW$T$5, DW_AT_encoding(DW_ATE_signed_char)
+    2261        .dwattr $C$DW$T$5, DW_AT_name("signed char")
+    2262        .dwattr $C$DW$T$5, DW_AT_byte_size(0x01)
+    2263$C$DW$T$6       .dwtag  DW_TAG_base_type
+    2264        .dwattr $C$DW$T$6, DW_AT_encoding(DW_ATE_unsigned_char)
+    2265        .dwattr $C$DW$T$6, DW_AT_name("unsigned char")
+    2266        .dwattr $C$DW$T$6, DW_AT_byte_size(0x01)
+    2267$C$DW$T$7       .dwtag  DW_TAG_base_type
+    2268        .dwattr $C$DW$T$7, DW_AT_encoding(DW_ATE_signed_char)
+    2269        .dwattr $C$DW$T$7, DW_AT_name("wchar_t")
+    2270        .dwattr $C$DW$T$7, DW_AT_byte_size(0x04)
+    2271$C$DW$T$8       .dwtag  DW_TAG_base_type
+    2272        .dwattr $C$DW$T$8, DW_AT_encoding(DW_ATE_signed)
+    2273        .dwattr $C$DW$T$8, DW_AT_name("short")
+    2274        .dwattr $C$DW$T$8, DW_AT_byte_size(0x02)
+    2275$C$DW$T$9       .dwtag  DW_TAG_base_type
+    2276        .dwattr $C$DW$T$9, DW_AT_encoding(DW_ATE_unsigned)
+    2277        .dwattr $C$DW$T$9, DW_AT_name("unsigned short")
+    2278        .dwattr $C$DW$T$9, DW_AT_byte_size(0x02)
+    2279$C$DW$T$10      .dwtag  DW_TAG_base_type
+    2280        .dwattr $C$DW$T$10, DW_AT_encoding(DW_ATE_signed)
+    2281        .dwattr $C$DW$T$10, DW_AT_name("int")
+    2282        .dwattr $C$DW$T$10, DW_AT_byte_size(0x04)
+    2283$C$DW$T$11      .dwtag  DW_TAG_base_type
+    2284        .dwattr $C$DW$T$11, DW_AT_encoding(DW_ATE_unsigned)
+    2285        .dwattr $C$DW$T$11, DW_AT_name("unsigned int")
+    2286        .dwattr $C$DW$T$11, DW_AT_byte_size(0x04)
+    2287$C$DW$T$32      .dwtag  DW_TAG_typedef, DW_AT_name("uint32_t")
+    2288        .dwattr $C$DW$T$32, DW_AT_type(*$C$DW$T$11)
+    2289        .dwattr $C$DW$T$32, DW_AT_language(DW_LANG_C)
+    2290        .dwattr $C$DW$T$32, DW_AT_decl_file("/usr/share/ti/cgt-pru/include/stdint.h")
+    2291        .dwattr $C$DW$T$32, DW_AT_decl_line(0x2f)
+    2292        .dwattr $C$DW$T$32, DW_AT_decl_column(0x1c)
+    2293
+    2294$C$DW$T$33      .dwtag  DW_TAG_array_type
+    2295        .dwattr $C$DW$T$33, DW_AT_type(*$C$DW$T$32)
+    2296        .dwattr $C$DW$T$33, DW_AT_language(DW_LANG_C)
+    2297        .dwattr $C$DW$T$33, DW_AT_byte_size(0x04)
+    2298$C$DW$181       .dwtag  DW_TAG_subrange_type
+    2299        .dwattr $C$DW$181, DW_AT_upper_bound(0x00)
+    2300        .dwendtag $C$DW$T$33
+    2301
+    2302
+    2303$C$DW$T$34      .dwtag  DW_TAG_array_type
+    2304        .dwattr $C$DW$T$34, DW_AT_type(*$C$DW$T$32)
+    2305        .dwattr $C$DW$T$34, DW_AT_language(DW_LANG_C)
+    2306        .dwattr $C$DW$T$34, DW_AT_byte_size(0x08)
+    2307$C$DW$182       .dwtag  DW_TAG_subrange_type
+    2308        .dwattr $C$DW$182, DW_AT_upper_bound(0x01)
+    2309        .dwendtag $C$DW$T$34
+    2310
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   43
+
+    2311
+    2312$C$DW$T$45      .dwtag  DW_TAG_array_type
+    2313        .dwattr $C$DW$T$45, DW_AT_type(*$C$DW$T$32)
+    2314        .dwattr $C$DW$T$45, DW_AT_language(DW_LANG_C)
+    2315        .dwattr $C$DW$T$45, DW_AT_byte_size(0x0c)
+    2316$C$DW$183       .dwtag  DW_TAG_subrange_type
+    2317        .dwattr $C$DW$183, DW_AT_upper_bound(0x02)
+    2318        .dwendtag $C$DW$T$45
+    2319
+    2320$C$DW$T$47      .dwtag  DW_TAG_volatile_type
+    2321        .dwattr $C$DW$T$47, DW_AT_type(*$C$DW$T$32)
+    2322$C$DW$T$12      .dwtag  DW_TAG_base_type
+    2323        .dwattr $C$DW$T$12, DW_AT_encoding(DW_ATE_signed)
+    2324        .dwattr $C$DW$T$12, DW_AT_name("long")
+    2325        .dwattr $C$DW$T$12, DW_AT_byte_size(0x04)
+    2326$C$DW$T$13      .dwtag  DW_TAG_base_type
+    2327        .dwattr $C$DW$T$13, DW_AT_encoding(DW_ATE_unsigned)
+    2328        .dwattr $C$DW$T$13, DW_AT_name("unsigned long")
+    2329        .dwattr $C$DW$T$13, DW_AT_byte_size(0x04)
+    2330$C$DW$T$14      .dwtag  DW_TAG_base_type
+    2331        .dwattr $C$DW$T$14, DW_AT_encoding(DW_ATE_signed)
+    2332        .dwattr $C$DW$T$14, DW_AT_name("long long")
+    2333        .dwattr $C$DW$T$14, DW_AT_byte_size(0x08)
+    2334$C$DW$T$15      .dwtag  DW_TAG_base_type
+    2335        .dwattr $C$DW$T$15, DW_AT_encoding(DW_ATE_unsigned)
+    2336        .dwattr $C$DW$T$15, DW_AT_name("unsigned long long")
+    2337        .dwattr $C$DW$T$15, DW_AT_byte_size(0x08)
+    2338$C$DW$T$16      .dwtag  DW_TAG_base_type
+    2339        .dwattr $C$DW$T$16, DW_AT_encoding(DW_ATE_float)
+    2340        .dwattr $C$DW$T$16, DW_AT_name("float")
+    2341        .dwattr $C$DW$T$16, DW_AT_byte_size(0x04)
+    2342$C$DW$T$17      .dwtag  DW_TAG_base_type
+    2343        .dwattr $C$DW$T$17, DW_AT_encoding(DW_ATE_float)
+    2344        .dwattr $C$DW$T$17, DW_AT_name("double")
+    2345        .dwattr $C$DW$T$17, DW_AT_byte_size(0x08)
+    2346$C$DW$T$18      .dwtag  DW_TAG_base_type
+    2347        .dwattr $C$DW$T$18, DW_AT_encoding(DW_ATE_float)
+    2348        .dwattr $C$DW$T$18, DW_AT_name("long double")
+    2349        .dwattr $C$DW$T$18, DW_AT_byte_size(0x08)
+    2350
+    2351$C$DW$T$92      .dwtag  DW_TAG_structure_type
+    2352        .dwattr $C$DW$T$92, DW_AT_name("my_resource_table")
+    2353        .dwattr $C$DW$T$92, DW_AT_byte_size(0x14)
+    2354$C$DW$184       .dwtag  DW_TAG_member
+    2355        .dwattr $C$DW$184, DW_AT_type(*$C$DW$T$93)
+    2356        .dwattr $C$DW$184, DW_AT_name("base")
+    2357        .dwattr $C$DW$184, DW_AT_TI_symbol_name("base")
+    2358        .dwattr $C$DW$184, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2359        .dwattr $C$DW$184, DW_AT_accessibility(DW_ACCESS_public)
+    2360        .dwattr $C$DW$184, DW_AT_decl_file("/var/lib/cloud9/common/resource_table_empty.h")
+    2361        .dwattr $C$DW$184, DW_AT_decl_line(0x18)
+    2362        .dwattr $C$DW$184, DW_AT_decl_column(0x18)
+    2363$C$DW$185       .dwtag  DW_TAG_member
+    2364        .dwattr $C$DW$185, DW_AT_type(*$C$DW$T$33)
+    2365        .dwattr $C$DW$185, DW_AT_name("offset")
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   44
+
+    2366        .dwattr $C$DW$185, DW_AT_TI_symbol_name("offset")
+    2367        .dwattr $C$DW$185, DW_AT_data_member_location[DW_OP_plus_uconst 0x10]
+    2368        .dwattr $C$DW$185, DW_AT_accessibility(DW_ACCESS_public)
+    2369        .dwattr $C$DW$185, DW_AT_decl_file("/var/lib/cloud9/common/resource_table_empty.h")
+    2370        .dwattr $C$DW$185, DW_AT_decl_line(0x1a)
+    2371        .dwattr $C$DW$185, DW_AT_decl_column(0x0b)
+    2372        .dwendtag $C$DW$T$92
+    2373
+    2374        .dwattr $C$DW$T$92, DW_AT_decl_file("/var/lib/cloud9/common/resource_table_empty.h")
+    2375        .dwattr $C$DW$T$92, DW_AT_decl_line(0x17)
+    2376        .dwattr $C$DW$T$92, DW_AT_decl_column(0x08)
+    2377
+    2378$C$DW$T$93      .dwtag  DW_TAG_structure_type
+    2379        .dwattr $C$DW$T$93, DW_AT_name("resource_table")
+    2380        .dwattr $C$DW$T$93, DW_AT_byte_size(0x10)
+    2381$C$DW$186       .dwtag  DW_TAG_member
+    2382        .dwattr $C$DW$186, DW_AT_type(*$C$DW$T$32)
+    2383        .dwattr $C$DW$186, DW_AT_name("ver")
+    2384        .dwattr $C$DW$186, DW_AT_TI_symbol_name("ver")
+    2385        .dwattr $C$DW$186, DW_AT_data_member_location[DW_OP_plus_uconst 0x0]
+    2386        .dwattr $C$DW$186, DW_AT_accessibility(DW_ACCESS_public)
+    2387        .dwattr $C$DW$186, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/rsc_types
+    2388        .dwattr $C$DW$186, DW_AT_decl_line(0x59)
+    2389        .dwattr $C$DW$186, DW_AT_decl_column(0x0b)
+    2390$C$DW$187       .dwtag  DW_TAG_member
+    2391        .dwattr $C$DW$187, DW_AT_type(*$C$DW$T$32)
+    2392        .dwattr $C$DW$187, DW_AT_name("num")
+    2393        .dwattr $C$DW$187, DW_AT_TI_symbol_name("num")
+    2394        .dwattr $C$DW$187, DW_AT_data_member_location[DW_OP_plus_uconst 0x4]
+    2395        .dwattr $C$DW$187, DW_AT_accessibility(DW_ACCESS_public)
+    2396        .dwattr $C$DW$187, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/rsc_types
+    2397        .dwattr $C$DW$187, DW_AT_decl_line(0x5a)
+    2398        .dwattr $C$DW$187, DW_AT_decl_column(0x0b)
+    2399$C$DW$188       .dwtag  DW_TAG_member
+    2400        .dwattr $C$DW$188, DW_AT_type(*$C$DW$T$34)
+    2401        .dwattr $C$DW$188, DW_AT_name("reserved")
+    2402        .dwattr $C$DW$188, DW_AT_TI_symbol_name("reserved")
+    2403        .dwattr $C$DW$188, DW_AT_data_member_location[DW_OP_plus_uconst 0x8]
+    2404        .dwattr $C$DW$188, DW_AT_accessibility(DW_ACCESS_public)
+    2405        .dwattr $C$DW$188, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/rsc_types
+    2406        .dwattr $C$DW$188, DW_AT_decl_line(0x5b)
+    2407        .dwattr $C$DW$188, DW_AT_decl_column(0x0b)
+    2408        .dwendtag $C$DW$T$93
+    2409
+    2410        .dwattr $C$DW$T$93, DW_AT_decl_file("/usr/lib/ti/pru-software-support-package/include/rsc_type
+    2411        .dwattr $C$DW$T$93, DW_AT_decl_line(0x58)
+    2412        .dwattr $C$DW$T$93, DW_AT_decl_column(0x08)
+    2413        .dwattr $C$DW$CU, DW_AT_language(DW_LANG_C)
+    2414
+    2415;***************************************************************
+    2416;* DWARF CIE ENTRIES                                           *
+    2417;***************************************************************
+    2418
+    2419$C$DW$CIE       .dwcie 14
+    2420        .dwcfi  cfa_register, 8
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   45
+
+    2421        .dwcfi  cfa_offset, 0
+    2422        .dwcfi  undefined, 0
+    2423        .dwcfi  undefined, 1
+    2424        .dwcfi  undefined, 2
+    2425        .dwcfi  undefined, 3
+    2426        .dwcfi  undefined, 4
+    2427        .dwcfi  undefined, 5
+    2428        .dwcfi  undefined, 6
+    2429        .dwcfi  undefined, 7
+    2430        .dwcfi  same_value, 8
+    2431        .dwcfi  same_value, 9
+    2432        .dwcfi  same_value, 10
+    2433        .dwcfi  same_value, 11
+    2434        .dwcfi  undefined, 12
+    2435        .dwcfi  undefined, 13
+    2436        .dwcfi  undefined, 14
+    2437        .dwcfi  undefined, 15
+    2438        .dwcfi  same_value, 16
+    2439        .dwcfi  same_value, 17
+    2440        .dwcfi  same_value, 18
+    2441        .dwcfi  same_value, 19
+    2442        .dwcfi  same_value, 20
+    2443        .dwcfi  same_value, 21
+    2444        .dwcfi  same_value, 22
+    2445        .dwcfi  same_value, 23
+    2446        .dwcfi  same_value, 24
+    2447        .dwcfi  same_value, 25
+    2448        .dwcfi  same_value, 26
+    2449        .dwcfi  same_value, 27
+    2450        .dwcfi  same_value, 28
+    2451        .dwcfi  same_value, 29
+    2452        .dwcfi  same_value, 30
+    2453        .dwcfi  same_value, 31
+    2454        .dwcfi  same_value, 32
+    2455        .dwcfi  same_value, 33
+    2456        .dwcfi  same_value, 34
+    2457        .dwcfi  same_value, 35
+    2458        .dwcfi  same_value, 36
+    2459        .dwcfi  same_value, 37
+    2460        .dwcfi  same_value, 38
+    2461        .dwcfi  same_value, 39
+    2462        .dwcfi  same_value, 40
+    2463        .dwcfi  same_value, 41
+    2464        .dwcfi  same_value, 42
+    2465        .dwcfi  same_value, 43
+    2466        .dwcfi  same_value, 44
+    2467        .dwcfi  same_value, 45
+    2468        .dwcfi  same_value, 46
+    2469        .dwcfi  same_value, 47
+    2470        .dwcfi  same_value, 48
+    2471        .dwcfi  same_value, 49
+    2472        .dwcfi  same_value, 50
+    2473        .dwcfi  same_value, 51
+    2474        .dwcfi  same_value, 52
+    2475        .dwcfi  same_value, 53
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   46
+
+    2476        .dwcfi  same_value, 54
+    2477        .dwcfi  same_value, 55
+    2478        .dwcfi  undefined, 56
+    2479        .dwcfi  undefined, 57
+    2480        .dwcfi  undefined, 58
+    2481        .dwcfi  undefined, 59
+    2482        .dwcfi  undefined, 60
+    2483        .dwcfi  undefined, 61
+    2484        .dwcfi  undefined, 62
+    2485        .dwcfi  undefined, 63
+    2486        .dwcfi  undefined, 64
+    2487        .dwcfi  undefined, 65
+    2488        .dwcfi  undefined, 66
+    2489        .dwcfi  undefined, 67
+    2490        .dwcfi  undefined, 68
+    2491        .dwcfi  undefined, 69
+    2492        .dwcfi  undefined, 70
+    2493        .dwcfi  undefined, 71
+    2494        .dwcfi  undefined, 72
+    2495        .dwcfi  undefined, 73
+    2496        .dwcfi  undefined, 74
+    2497        .dwcfi  undefined, 75
+    2498        .dwcfi  undefined, 76
+    2499        .dwcfi  undefined, 77
+    2500        .dwcfi  undefined, 78
+    2501        .dwcfi  undefined, 79
+    2502        .dwcfi  undefined, 80
+    2503        .dwcfi  undefined, 81
+    2504        .dwcfi  undefined, 82
+    2505        .dwcfi  undefined, 83
+    2506        .dwcfi  undefined, 84
+    2507        .dwcfi  undefined, 85
+    2508        .dwcfi  undefined, 86
+    2509        .dwcfi  undefined, 87
+    2510        .dwcfi  undefined, 88
+    2511        .dwcfi  undefined, 89
+    2512        .dwcfi  undefined, 90
+    2513        .dwcfi  undefined, 91
+    2514        .dwcfi  undefined, 92
+    2515        .dwcfi  undefined, 93
+    2516        .dwcfi  undefined, 94
+    2517        .dwcfi  undefined, 95
+    2518        .dwcfi  undefined, 96
+    2519        .dwcfi  undefined, 97
+    2520        .dwcfi  undefined, 98
+    2521        .dwcfi  undefined, 99
+    2522        .dwcfi  undefined, 100
+    2523        .dwcfi  undefined, 101
+    2524        .dwcfi  undefined, 102
+    2525        .dwcfi  undefined, 103
+    2526        .dwcfi  undefined, 104
+    2527        .dwcfi  undefined, 105
+    2528        .dwcfi  undefined, 106
+    2529        .dwcfi  undefined, 107
+    2530        .dwcfi  undefined, 108
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   47
+
+    2531        .dwcfi  undefined, 109
+    2532        .dwcfi  undefined, 110
+    2533        .dwcfi  undefined, 111
+    2534        .dwcfi  undefined, 112
+    2535        .dwcfi  undefined, 113
+    2536        .dwcfi  undefined, 114
+    2537        .dwcfi  undefined, 115
+    2538        .dwcfi  undefined, 116
+    2539        .dwcfi  undefined, 117
+    2540        .dwcfi  undefined, 118
+    2541        .dwcfi  undefined, 119
+    2542        .dwcfi  undefined, 120
+    2543        .dwcfi  undefined, 121
+    2544        .dwcfi  undefined, 122
+    2545        .dwcfi  undefined, 123
+    2546        .dwcfi  undefined, 124
+    2547        .dwcfi  undefined, 125
+    2548        .dwcfi  undefined, 126
+    2549        .dwcfi  undefined, 127
+    2550        .dwcfi  undefined, 128
+    2551        .dwcfi  undefined, 129
+    2552        .dwcfi  undefined, 130
+    2553        .dwcfi  undefined, 131
+    2554        .dwcfi  undefined, 132
+    2555        .dwcfi  undefined, 133
+    2556        .dwcfi  undefined, 134
+    2557        .dwendentry
+    2558
+    2559;***************************************************************
+    2560;* DWARF REGISTER MAP                                          *
+    2561;***************************************************************
+    2562
+    2563$C$DW$189       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R0_b0")
+    2564        .dwattr $C$DW$189, DW_AT_location[DW_OP_reg0]
+    2565$C$DW$190       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R0_b1")
+    2566        .dwattr $C$DW$190, DW_AT_location[DW_OP_reg1]
+    2567$C$DW$191       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R0_b2")
+    2568        .dwattr $C$DW$191, DW_AT_location[DW_OP_reg2]
+    2569$C$DW$192       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R0_b3")
+    2570        .dwattr $C$DW$192, DW_AT_location[DW_OP_reg3]
+    2571$C$DW$193       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R1_b0")
+    2572        .dwattr $C$DW$193, DW_AT_location[DW_OP_reg4]
+    2573$C$DW$194       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R1_b1")
+    2574        .dwattr $C$DW$194, DW_AT_location[DW_OP_reg5]
+    2575$C$DW$195       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R1_b2")
+    2576        .dwattr $C$DW$195, DW_AT_location[DW_OP_reg6]
+    2577$C$DW$196       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R1_b3")
+    2578        .dwattr $C$DW$196, DW_AT_location[DW_OP_reg7]
+    2579$C$DW$197       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R2_b0")
+    2580        .dwattr $C$DW$197, DW_AT_location[DW_OP_reg8]
+    2581$C$DW$198       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R2_b1")
+    2582        .dwattr $C$DW$198, DW_AT_location[DW_OP_reg9]
+    2583$C$DW$199       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R2_b2")
+    2584        .dwattr $C$DW$199, DW_AT_location[DW_OP_reg10]
+    2585$C$DW$200       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R2_b3")
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   48
+
+    2586        .dwattr $C$DW$200, DW_AT_location[DW_OP_reg11]
+    2587$C$DW$201       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R3_b0")
+    2588        .dwattr $C$DW$201, DW_AT_location[DW_OP_reg12]
+    2589$C$DW$202       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R3_b1")
+    2590        .dwattr $C$DW$202, DW_AT_location[DW_OP_reg13]
+    2591$C$DW$203       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R3_b2")
+    2592        .dwattr $C$DW$203, DW_AT_location[DW_OP_reg14]
+    2593$C$DW$204       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R3_b3")
+    2594        .dwattr $C$DW$204, DW_AT_location[DW_OP_reg15]
+    2595$C$DW$205       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R4_b0")
+    2596        .dwattr $C$DW$205, DW_AT_location[DW_OP_reg16]
+    2597$C$DW$206       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R4_b1")
+    2598        .dwattr $C$DW$206, DW_AT_location[DW_OP_reg17]
+    2599$C$DW$207       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R4_b2")
+    2600        .dwattr $C$DW$207, DW_AT_location[DW_OP_reg18]
+    2601$C$DW$208       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R4_b3")
+    2602        .dwattr $C$DW$208, DW_AT_location[DW_OP_reg19]
+    2603$C$DW$209       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R5_b0")
+    2604        .dwattr $C$DW$209, DW_AT_location[DW_OP_reg20]
+    2605$C$DW$210       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R5_b1")
+    2606        .dwattr $C$DW$210, DW_AT_location[DW_OP_reg21]
+    2607$C$DW$211       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R5_b2")
+    2608        .dwattr $C$DW$211, DW_AT_location[DW_OP_reg22]
+    2609$C$DW$212       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R5_b3")
+    2610        .dwattr $C$DW$212, DW_AT_location[DW_OP_reg23]
+    2611$C$DW$213       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R6_b0")
+    2612        .dwattr $C$DW$213, DW_AT_location[DW_OP_reg24]
+    2613$C$DW$214       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R6_b1")
+    2614        .dwattr $C$DW$214, DW_AT_location[DW_OP_reg25]
+    2615$C$DW$215       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R6_b2")
+    2616        .dwattr $C$DW$215, DW_AT_location[DW_OP_reg26]
+    2617$C$DW$216       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R6_b3")
+    2618        .dwattr $C$DW$216, DW_AT_location[DW_OP_reg27]
+    2619$C$DW$217       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R7_b0")
+    2620        .dwattr $C$DW$217, DW_AT_location[DW_OP_reg28]
+    2621$C$DW$218       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R7_b1")
+    2622        .dwattr $C$DW$218, DW_AT_location[DW_OP_reg29]
+    2623$C$DW$219       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R7_b2")
+    2624        .dwattr $C$DW$219, DW_AT_location[DW_OP_reg30]
+    2625$C$DW$220       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R7_b3")
+    2626        .dwattr $C$DW$220, DW_AT_location[DW_OP_reg31]
+    2627$C$DW$221       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R8_b0")
+    2628        .dwattr $C$DW$221, DW_AT_location[DW_OP_regx 0x20]
+    2629$C$DW$222       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R8_b1")
+    2630        .dwattr $C$DW$222, DW_AT_location[DW_OP_regx 0x21]
+    2631$C$DW$223       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R8_b2")
+    2632        .dwattr $C$DW$223, DW_AT_location[DW_OP_regx 0x22]
+    2633$C$DW$224       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R8_b3")
+    2634        .dwattr $C$DW$224, DW_AT_location[DW_OP_regx 0x23]
+    2635$C$DW$225       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R9_b0")
+    2636        .dwattr $C$DW$225, DW_AT_location[DW_OP_regx 0x24]
+    2637$C$DW$226       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R9_b1")
+    2638        .dwattr $C$DW$226, DW_AT_location[DW_OP_regx 0x25]
+    2639$C$DW$227       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R9_b2")
+    2640        .dwattr $C$DW$227, DW_AT_location[DW_OP_regx 0x26]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   49
+
+    2641$C$DW$228       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R9_b3")
+    2642        .dwattr $C$DW$228, DW_AT_location[DW_OP_regx 0x27]
+    2643$C$DW$229       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R10_b0")
+    2644        .dwattr $C$DW$229, DW_AT_location[DW_OP_regx 0x28]
+    2645$C$DW$230       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R10_b1")
+    2646        .dwattr $C$DW$230, DW_AT_location[DW_OP_regx 0x29]
+    2647$C$DW$231       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R10_b2")
+    2648        .dwattr $C$DW$231, DW_AT_location[DW_OP_regx 0x2a]
+    2649$C$DW$232       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R10_b3")
+    2650        .dwattr $C$DW$232, DW_AT_location[DW_OP_regx 0x2b]
+    2651$C$DW$233       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R11_b0")
+    2652        .dwattr $C$DW$233, DW_AT_location[DW_OP_regx 0x2c]
+    2653$C$DW$234       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R11_b1")
+    2654        .dwattr $C$DW$234, DW_AT_location[DW_OP_regx 0x2d]
+    2655$C$DW$235       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R11_b2")
+    2656        .dwattr $C$DW$235, DW_AT_location[DW_OP_regx 0x2e]
+    2657$C$DW$236       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R11_b3")
+    2658        .dwattr $C$DW$236, DW_AT_location[DW_OP_regx 0x2f]
+    2659$C$DW$237       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R12_b0")
+    2660        .dwattr $C$DW$237, DW_AT_location[DW_OP_regx 0x30]
+    2661$C$DW$238       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R12_b1")
+    2662        .dwattr $C$DW$238, DW_AT_location[DW_OP_regx 0x31]
+    2663$C$DW$239       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R12_b2")
+    2664        .dwattr $C$DW$239, DW_AT_location[DW_OP_regx 0x32]
+    2665$C$DW$240       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R12_b3")
+    2666        .dwattr $C$DW$240, DW_AT_location[DW_OP_regx 0x33]
+    2667$C$DW$241       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R13_b0")
+    2668        .dwattr $C$DW$241, DW_AT_location[DW_OP_regx 0x34]
+    2669$C$DW$242       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R13_b1")
+    2670        .dwattr $C$DW$242, DW_AT_location[DW_OP_regx 0x35]
+    2671$C$DW$243       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R13_b2")
+    2672        .dwattr $C$DW$243, DW_AT_location[DW_OP_regx 0x36]
+    2673$C$DW$244       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R13_b3")
+    2674        .dwattr $C$DW$244, DW_AT_location[DW_OP_regx 0x37]
+    2675$C$DW$245       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R14_b0")
+    2676        .dwattr $C$DW$245, DW_AT_location[DW_OP_regx 0x38]
+    2677$C$DW$246       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R14_b1")
+    2678        .dwattr $C$DW$246, DW_AT_location[DW_OP_regx 0x39]
+    2679$C$DW$247       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R14_b2")
+    2680        .dwattr $C$DW$247, DW_AT_location[DW_OP_regx 0x3a]
+    2681$C$DW$248       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R14_b3")
+    2682        .dwattr $C$DW$248, DW_AT_location[DW_OP_regx 0x3b]
+    2683$C$DW$249       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R15_b0")
+    2684        .dwattr $C$DW$249, DW_AT_location[DW_OP_regx 0x3c]
+    2685$C$DW$250       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R15_b1")
+    2686        .dwattr $C$DW$250, DW_AT_location[DW_OP_regx 0x3d]
+    2687$C$DW$251       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R15_b2")
+    2688        .dwattr $C$DW$251, DW_AT_location[DW_OP_regx 0x3e]
+    2689$C$DW$252       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R15_b3")
+    2690        .dwattr $C$DW$252, DW_AT_location[DW_OP_regx 0x3f]
+    2691$C$DW$253       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R16_b0")
+    2692        .dwattr $C$DW$253, DW_AT_location[DW_OP_regx 0x40]
+    2693$C$DW$254       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R16_b1")
+    2694        .dwattr $C$DW$254, DW_AT_location[DW_OP_regx 0x41]
+    2695$C$DW$255       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R16_b2")
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   50
+
+    2696        .dwattr $C$DW$255, DW_AT_location[DW_OP_regx 0x42]
+    2697$C$DW$256       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R16_b3")
+    2698        .dwattr $C$DW$256, DW_AT_location[DW_OP_regx 0x43]
+    2699$C$DW$257       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R17_b0")
+    2700        .dwattr $C$DW$257, DW_AT_location[DW_OP_regx 0x44]
+    2701$C$DW$258       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R17_b1")
+    2702        .dwattr $C$DW$258, DW_AT_location[DW_OP_regx 0x45]
+    2703$C$DW$259       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R17_b2")
+    2704        .dwattr $C$DW$259, DW_AT_location[DW_OP_regx 0x46]
+    2705$C$DW$260       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R17_b3")
+    2706        .dwattr $C$DW$260, DW_AT_location[DW_OP_regx 0x47]
+    2707$C$DW$261       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R18_b0")
+    2708        .dwattr $C$DW$261, DW_AT_location[DW_OP_regx 0x48]
+    2709$C$DW$262       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R18_b1")
+    2710        .dwattr $C$DW$262, DW_AT_location[DW_OP_regx 0x49]
+    2711$C$DW$263       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R18_b2")
+    2712        .dwattr $C$DW$263, DW_AT_location[DW_OP_regx 0x4a]
+    2713$C$DW$264       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R18_b3")
+    2714        .dwattr $C$DW$264, DW_AT_location[DW_OP_regx 0x4b]
+    2715$C$DW$265       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R19_b0")
+    2716        .dwattr $C$DW$265, DW_AT_location[DW_OP_regx 0x4c]
+    2717$C$DW$266       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R19_b1")
+    2718        .dwattr $C$DW$266, DW_AT_location[DW_OP_regx 0x4d]
+    2719$C$DW$267       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R19_b2")
+    2720        .dwattr $C$DW$267, DW_AT_location[DW_OP_regx 0x4e]
+    2721$C$DW$268       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R19_b3")
+    2722        .dwattr $C$DW$268, DW_AT_location[DW_OP_regx 0x4f]
+    2723$C$DW$269       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R20_b0")
+    2724        .dwattr $C$DW$269, DW_AT_location[DW_OP_regx 0x50]
+    2725$C$DW$270       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R20_b1")
+    2726        .dwattr $C$DW$270, DW_AT_location[DW_OP_regx 0x51]
+    2727$C$DW$271       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R20_b2")
+    2728        .dwattr $C$DW$271, DW_AT_location[DW_OP_regx 0x52]
+    2729$C$DW$272       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R20_b3")
+    2730        .dwattr $C$DW$272, DW_AT_location[DW_OP_regx 0x53]
+    2731$C$DW$273       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R21_b0")
+    2732        .dwattr $C$DW$273, DW_AT_location[DW_OP_regx 0x54]
+    2733$C$DW$274       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R21_b1")
+    2734        .dwattr $C$DW$274, DW_AT_location[DW_OP_regx 0x55]
+    2735$C$DW$275       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R21_b2")
+    2736        .dwattr $C$DW$275, DW_AT_location[DW_OP_regx 0x56]
+    2737$C$DW$276       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R21_b3")
+    2738        .dwattr $C$DW$276, DW_AT_location[DW_OP_regx 0x57]
+    2739$C$DW$277       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R22_b0")
+    2740        .dwattr $C$DW$277, DW_AT_location[DW_OP_regx 0x58]
+    2741$C$DW$278       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R22_b1")
+    2742        .dwattr $C$DW$278, DW_AT_location[DW_OP_regx 0x59]
+    2743$C$DW$279       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R22_b2")
+    2744        .dwattr $C$DW$279, DW_AT_location[DW_OP_regx 0x5a]
+    2745$C$DW$280       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R22_b3")
+    2746        .dwattr $C$DW$280, DW_AT_location[DW_OP_regx 0x5b]
+    2747$C$DW$281       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R23_b0")
+    2748        .dwattr $C$DW$281, DW_AT_location[DW_OP_regx 0x5c]
+    2749$C$DW$282       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R23_b1")
+    2750        .dwattr $C$DW$282, DW_AT_location[DW_OP_regx 0x5d]
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   51
+
+    2751$C$DW$283       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R23_b2")
+    2752        .dwattr $C$DW$283, DW_AT_location[DW_OP_regx 0x5e]
+    2753$C$DW$284       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R23_b3")
+    2754        .dwattr $C$DW$284, DW_AT_location[DW_OP_regx 0x5f]
+    2755$C$DW$285       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R24_b0")
+    2756        .dwattr $C$DW$285, DW_AT_location[DW_OP_regx 0x60]
+    2757$C$DW$286       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R24_b1")
+    2758        .dwattr $C$DW$286, DW_AT_location[DW_OP_regx 0x61]
+    2759$C$DW$287       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R24_b2")
+    2760        .dwattr $C$DW$287, DW_AT_location[DW_OP_regx 0x62]
+    2761$C$DW$288       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R24_b3")
+    2762        .dwattr $C$DW$288, DW_AT_location[DW_OP_regx 0x63]
+    2763$C$DW$289       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R25_b0")
+    2764        .dwattr $C$DW$289, DW_AT_location[DW_OP_regx 0x64]
+    2765$C$DW$290       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R25_b1")
+    2766        .dwattr $C$DW$290, DW_AT_location[DW_OP_regx 0x65]
+    2767$C$DW$291       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R25_b2")
+    2768        .dwattr $C$DW$291, DW_AT_location[DW_OP_regx 0x66]
+    2769$C$DW$292       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R25_b3")
+    2770        .dwattr $C$DW$292, DW_AT_location[DW_OP_regx 0x67]
+    2771$C$DW$293       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R26_b0")
+    2772        .dwattr $C$DW$293, DW_AT_location[DW_OP_regx 0x68]
+    2773$C$DW$294       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R26_b1")
+    2774        .dwattr $C$DW$294, DW_AT_location[DW_OP_regx 0x69]
+    2775$C$DW$295       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R26_b2")
+    2776        .dwattr $C$DW$295, DW_AT_location[DW_OP_regx 0x6a]
+    2777$C$DW$296       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R26_b3")
+    2778        .dwattr $C$DW$296, DW_AT_location[DW_OP_regx 0x6b]
+    2779$C$DW$297       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R27_b0")
+    2780        .dwattr $C$DW$297, DW_AT_location[DW_OP_regx 0x6c]
+    2781$C$DW$298       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R27_b1")
+    2782        .dwattr $C$DW$298, DW_AT_location[DW_OP_regx 0x6d]
+    2783$C$DW$299       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R27_b2")
+    2784        .dwattr $C$DW$299, DW_AT_location[DW_OP_regx 0x6e]
+    2785$C$DW$300       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R27_b3")
+    2786        .dwattr $C$DW$300, DW_AT_location[DW_OP_regx 0x6f]
+    2787$C$DW$301       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R28_b0")
+    2788        .dwattr $C$DW$301, DW_AT_location[DW_OP_regx 0x70]
+    2789$C$DW$302       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R28_b1")
+    2790        .dwattr $C$DW$302, DW_AT_location[DW_OP_regx 0x71]
+    2791$C$DW$303       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R28_b2")
+    2792        .dwattr $C$DW$303, DW_AT_location[DW_OP_regx 0x72]
+    2793$C$DW$304       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R28_b3")
+    2794        .dwattr $C$DW$304, DW_AT_location[DW_OP_regx 0x73]
+    2795$C$DW$305       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R29_b0")
+    2796        .dwattr $C$DW$305, DW_AT_location[DW_OP_regx 0x74]
+    2797$C$DW$306       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R29_b1")
+    2798        .dwattr $C$DW$306, DW_AT_location[DW_OP_regx 0x75]
+    2799$C$DW$307       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R29_b2")
+    2800        .dwattr $C$DW$307, DW_AT_location[DW_OP_regx 0x76]
+    2801$C$DW$308       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R29_b3")
+    2802        .dwattr $C$DW$308, DW_AT_location[DW_OP_regx 0x77]
+    2803$C$DW$309       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R30_b0")
+    2804        .dwattr $C$DW$309, DW_AT_location[DW_OP_regx 0x78]
+    2805$C$DW$310       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R30_b1")
+PRU Assembler Unix v2.1.5 Fri Jun  5 14:14:07 2020
+
+Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
+/tmp/cloud9-examples/cycle.pru0.asm                                  PAGE   52
+
+    2806        .dwattr $C$DW$310, DW_AT_location[DW_OP_regx 0x79]
+    2807$C$DW$311       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R30_b2")
+    2808        .dwattr $C$DW$311, DW_AT_location[DW_OP_regx 0x7a]
+    2809$C$DW$312       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R30_b3")
+    2810        .dwattr $C$DW$312, DW_AT_location[DW_OP_regx 0x7b]
+    2811$C$DW$313       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R31_b0")
+    2812        .dwattr $C$DW$313, DW_AT_location[DW_OP_regx 0x7c]
+    2813$C$DW$314       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R31_b1")
+    2814        .dwattr $C$DW$314, DW_AT_location[DW_OP_regx 0x7d]
+    2815$C$DW$315       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R31_b2")
+    2816        .dwattr $C$DW$315, DW_AT_location[DW_OP_regx 0x7e]
+    2817$C$DW$316       .dwtag  DW_TAG_TI_assign_register, DW_AT_name("R31_b3")
+    2818        .dwattr $C$DW$316, DW_AT_location[DW_OP_regx 0x7f]
+    2819        .dwendtag $C$DW$CU
+    2820
+
+No Assembly Errors, No Assembly Warnings
diff --git a/pru-cookbook/07more/code/delay-test.pru0.c b/pru-cookbook/07more/code/delay-test.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..337ecbb23cb0920a687b30b3e50dcdbf5ae86f86
--- /dev/null
+++ b/pru-cookbook/07more/code/delay-test.pru0.c
@@ -0,0 +1,28 @@
+// Shows how to call an assembly routine with one parameter
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+// The function is defined in delay.asm in same dir
+// We just need to add a declaration here, the defination can be
+// seperately linked
+extern void my_delay_cycles(uint32_t);
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t gpio = P9_31;	// Select which pin to toggle.;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	while(1) {
+		__R30 |= gpio;		// Set the GPIO pin to 1
+		my_delay_cycles(1);
+		__R30 &= ~gpio;		// Clear the GPIO pin
+		my_delay_cycles(1);
+	}
+}
diff --git a/pru-cookbook/07more/code/delay-test2.pru0.c b/pru-cookbook/07more/code/delay-test2.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..763b3a7d7b0452139cb817b0d56bf5e13688e0f6
--- /dev/null
+++ b/pru-cookbook/07more/code/delay-test2.pru0.c
@@ -0,0 +1,32 @@
+// Shows how to call an assembly routine with a return value
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+#define	TEST	100
+
+// The function is defined in delay.asm in same dir
+// We just need to add a declaration here, the defination can be
+// seperately linked
+extern uint32_t my_delay_cycles(uint32_t);
+
+uint32_t ret;
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t gpio = P9_31;	// Select which pin to toggle.;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	while(1) {
+		__R30 |= gpio;		// Set the GPIO pin to 1
+		ret = my_delay_cycles(1);
+		__R30 &= ~gpio;		// Clear the GPIO pin
+		ret = my_delay_cycles(1);
+	}
+}
diff --git a/pru-cookbook/07more/code/delay.pru0.asm b/pru-cookbook/07more/code/delay.pru0.asm
new file mode 100644
index 0000000000000000000000000000000000000000..1c1cce7d1d986e55bc3bc3f8bf3cc3e3d783fc21
--- /dev/null
+++ b/pru-cookbook/07more/code/delay.pru0.asm
@@ -0,0 +1,9 @@
+; This is an example of how to call an assembly routine from C.
+;	Mark A. Yoder, 9-July-2018
+	.global my_delay_cycles
+my_delay_cycles:
+delay:
+	sub		r14,   r14, 1		; The first argument is passed in r14
+	qbne	delay, r14, 0
+
+	jmp		r3.w2			; r3 contains the return address
\ No newline at end of file
diff --git a/pru-cookbook/07more/code/delay2.pru0.asm b/pru-cookbook/07more/code/delay2.pru0.asm
new file mode 100644
index 0000000000000000000000000000000000000000..e1f1da03d37ece54ca7c577b4244bd8abbbc921f
--- /dev/null
+++ b/pru-cookbook/07more/code/delay2.pru0.asm
@@ -0,0 +1,15 @@
+; This is an example of how to call an assembly routine from C with a retun value.
+;	Mark A. Yoder, 9-July-2018
+
+	.cdecls "delay-test2.pru0.c"
+
+	.global my_delay_cycles
+my_delay_cycles:
+delay:
+	sub		r14,   r14, 1		; The first argument is passed in r14
+	qbne	delay, r14, 0
+	
+	ldi		r14, TEST		; TEST is defined in delay-test2.c
+							; r14 is the return register
+
+	jmp		r3.w2			; r3 contains the return address
\ No newline at end of file
diff --git a/pru-cookbook/07more/code/logic.c b/pru-cookbook/07more/code/logic.c
new file mode 100644
index 0000000000000000000000000000000000000000..f774708d22f3ef26ede77fe45a8057d7f1e905f2
--- /dev/null
+++ b/pru-cookbook/07more/code/logic.c
@@ -0,0 +1,34 @@
+// Access the CYCLE and STALL registers
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	// Copy lower 8 bits to r16
+	struct {
+	    uint8_t b0;
+	    uint8_t b1;
+	    uint8_t b2;
+	    uint8_t b3;
+	} r17;
+
+	// Clear SYSCFG[STANDBY_INIT] to enable OCP master port
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+	
+// 	r16.b0 = __R31.b0;
+	__asm(" mov r17.b0, r31.b0");
+	__delay_cycles(1);
+	r17.b1 = (uint32_t) __R31;
+	__delay_cycles(1);
+	r17.b2 = (uint32_t) __R31;
+	__delay_cycles(1);
+	r17.b3 = (uint32_t) __R31;
+
+    __xout(10, 16, 0, r17);
+
+	__halt();
+}
diff --git a/pru-cookbook/07more/code/logic_setup.sh b/pru-cookbook/07more/code/logic_setup.sh
new file mode 100644
index 0000000000000000000000000000000000000000..2253459cf1f8efde2e61281525f26872a3940a42
--- /dev/null
+++ b/pru-cookbook/07more/code/logic_setup.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+#
+export PRUN=0
+export TARGET=logic
+echo PRUN=$PRUN
+echo TARGET=$TARGET
+
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P9_31 P9_29 P9_30 P9_28 P9_92 P9_27 P9_91 P9_25 "
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P1_36 P1_33 P2_32 P2_30 P1_31 P2_34 P2_28 P1_29"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin pruin
+    config-pin -q $pin
+done
diff --git a/pru-cookbook/07more/code/resource_table_pru0.h b/pru-cookbook/07more/code/resource_table_pru0.h
new file mode 100644
index 0000000000000000000000000000000000000000..06c148006b7a892d30f16d69891c6165e3525161
--- /dev/null
+++ b/pru-cookbook/07more/code/resource_table_pru0.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *	* Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ *
+ *	* Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the
+ *	  distribution.
+ *
+ *	* Neither the name of Texas Instruments Incorporated nor the names of
+ *	  its contributors may be used to endorse or promote products derived
+ *	  from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ *  ======== rsc_table_pru.h ========
+ *
+ *  Define the resource table entries for PRU0. This will be
+ *  incorporated into corresponding base images, and used by the remoteproc
+ *  on the host-side to allocated/reserve resources.  Note the remoteproc
+ *  driver requires that all PRU firmware be built with a resource table.
+ *
+ *
+ */
+
+#ifndef _RSC_TABLE_PRU_H_
+#define _RSC_TABLE_PRU_H_
+
+#include <stddef.h>
+#include <rsc_types.h>
+#include "pru_virtio_ids.h"
+
+/*
+ * Sizes of the virtqueues (expressed in number of buffers supported,
+ * and must be power of 2)
+ */
+#define PRU_RPMSG_VQ0_SIZE	2
+#define PRU_RPMSG_VQ1_SIZE	2
+
+/* flip up bits whose indices represent features we support */
+#define RPMSG_PRU_C0_FEATURES	1
+
+/* Definition for unused interrupts */
+#define HOST_UNUSED		255
+
+/* Mapping sysevts to a channel. Each pair contains a sysevt, channel */
+struct ch_map pru_intc_map[] = { {17, 1}, {18, 0}, {19, 2}, {20, 3}, {21, 0},
+	{22, 1}, {24, 4}, {25, 5}, {26, 6}, {27, 7},
+};
+
+struct my_resource_table {
+	struct resource_table base;
+
+	uint32_t offset[1]; /* Should match 'num' in actual definition */
+
+	/* intc definition */
+	struct fw_rsc_custom pru_ints;
+};
+
+#pragma DATA_SECTION(am335x_pru_remoteproc_ResourceTable, ".resource_table")
+#pragma RETAIN(am335x_pru_remoteproc_ResourceTable)
+struct my_resource_table am335x_pru_remoteproc_ResourceTable = {
+	1,	/* we're the first version that implements this */
+	1,	/* number of entries in the table */
+	0, 0,	/* reserved, must be zero */
+	/* offsets to entries */
+	{
+		offsetof(struct my_resource_table, pru_ints),
+	},
+
+	{
+		TYPE_CUSTOM, TYPE_PRU_INTS,
+		sizeof(struct fw_rsc_custom_ints),
+		{ /* PRU_INTS version */
+			0x0000,
+			/* Channel-to-host mapping, 255 for unused */
+			0, 1, 2, 3, 0, 6, 1, 7, HOST_UNUSED, HOST_UNUSED,
+			/* Number of evts being mapped to channels */
+			(sizeof(pru_intc_map) / sizeof(struct ch_map)),
+			/* Pointer to the structure containing mapped events */
+			pru_intc_map,
+		},
+	},
+};
+
+#endif /* _RSC_TABLE_PRU_H_ */
diff --git a/pru-cookbook/07more/code/setup.sh b/pru-cookbook/07more/code/setup.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f1d0d9db334b125b68171dd18ce04abec94ace08
--- /dev/null
+++ b/pru-cookbook/07more/code/setup.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+#
+export TARGET=delay-test.pru0
+export TARGETasm=delay.pru0
+echo TARGET=$TARGET
+echo TARGETasm=$TARGETasm
+
+# Configure the PRU pins based on which Beagle is running
+machine=$(awk '{print $NF}' /proc/device-tree/model)
+echo -n $machine
+if [ $machine = "Black" ]; then
+    echo " Found"
+    pins="P9_31"
+elif [ $machine = "Blue" ]; then
+    echo " Found"
+    pins=""
+elif [ $machine = "PocketBeagle" ]; then
+    echo " Found"
+    pins="P1_33"
+else
+    echo " Not Found"
+    pins=""
+fi
+
+for pin in $pins
+do
+    echo $pin
+    config-pin $pin pruout
+    config-pin -q $pin
+done
diff --git a/pru-cookbook/07more/code/xin.pru1.c b/pru-cookbook/07more/code/xin.pru1.c
new file mode 100644
index 0000000000000000000000000000000000000000..56d4a68209d974c51e50559cc6d90ff9046f3a68
--- /dev/null
+++ b/pru-cookbook/07more/code/xin.pru1.c
@@ -0,0 +1,34 @@
+// From: http://git.ti.com/pru-software-support-package/pru-software-support-package/trees/master/examples/am335x/PRU_Direct_Connect1
+#include <stdint.h>
+#include "resource_table_empty.h"
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+typedef struct {
+	uint32_t reg5;
+	uint32_t reg6;
+	uint32_t reg7;
+	uint32_t reg8;
+	uint32_t reg9;
+	uint32_t reg10;
+} bufferData;
+
+bufferData dmemBuf;
+
+/* PRU-to-ARM interrupt */
+#define PRU1_PRU0_INTERRUPT (18)
+#define PRU1_ARM_INTERRUPT (20+16)
+
+void main(void)
+{
+	/* Let PRU0 know that I am awake */
+	__R31 = PRU1_PRU0_INTERRUPT+16;
+
+	/* XFR registers R5-R10 from PRU0 to PRU1 */
+	/* 14 is the device_id that signifies a PRU to PRU transfer */
+	__xin(14, 5, 0, dmemBuf);
+
+	/* Halt the PRU core */
+	__halt();
+}
diff --git a/pru-cookbook/07more/code/xout-cycle.pru0.c b/pru-cookbook/07more/code/xout-cycle.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..339fedfc38eed9d9372a0b55ee74dfc031be70c2
--- /dev/null
+++ b/pru-cookbook/07more/code/xout-cycle.pru0.c
@@ -0,0 +1,62 @@
+// Version of xout.c with code to use CYCLE to count cycle times.
+#include <stdint.h>
+#include <pru_intc.h>
+#include <pru_ctrl.h>
+#include "resource_table_pru0.h"
+
+#define PRU0
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+typedef struct {
+	uint32_t reg5;
+	uint32_t reg6;
+	uint32_t reg7;
+	uint32_t reg8;
+	uint32_t reg9;
+	uint32_t reg10;
+} bufferData;
+
+bufferData dmemBuf;
+
+/* PRU-to-ARM interrupt */
+#define PRU1_PRU0_INTERRUPT (18)
+#define PRU0_ARM_INTERRUPT (19+16)
+
+void main(void)
+{
+	uint32_t cycleXX;		// Use a name that's easy to search
+	/* Clear the status of all interrupts */
+	CT_INTC.SECR0 = 0xFFFFFFFF;
+	CT_INTC.SECR1 = 0xFFFFFFFF;
+	
+	/* Load the buffer with default values to transfer */
+	dmemBuf.reg5 = 0xDEADBEEF;
+	dmemBuf.reg6 = 0xAAAAAAAA;
+	dmemBuf.reg7 = 0x12345678;
+	dmemBuf.reg8 = 0xBBBBBBBB;
+	dmemBuf.reg9 = 0x87654321;
+	dmemBuf.reg10 = 0xCCCCCCCC;
+
+	/* Poll until R31.30 (PRU0 interrupt) is set
+	 * This signals PRU1 is initialized */
+	while ((__R31 & (1<<30)) == 0) {
+	}
+
+	/* XFR registers R5-R10 from PRU0 to PRU1 */
+	/* 14 is the device_id that signifies a PRU to PRU transfer */
+	PRU0_CTRL.CTRL_bit.CTR_EN = 1;	// Enable cycle counter
+
+	__xout(14, 5, 0, dmemBuf);
+	
+	cycleXX = PRU0_CTRL.CYCLE;	// Read cycle and store in a register
+
+	/* Clear the status of the interrupt */
+	CT_INTC.SICR = PRU1_PRU0_INTERRUPT;
+
+	dmemBuf.reg5 = cycleXX;
+
+	/* Halt the PRU core */
+	__halt();
+}
diff --git a/pru-cookbook/07more/code/xout.pru0.c b/pru-cookbook/07more/code/xout.pru0.c
new file mode 100644
index 0000000000000000000000000000000000000000..bfcdbf5f927700c2d250abc0f28850bb4884392f
--- /dev/null
+++ b/pru-cookbook/07more/code/xout.pru0.c
@@ -0,0 +1,52 @@
+// From: http://git.ti.com/pru-software-support-package/pru-software-support-package/trees/master/examples/am335x/PRU_Direct_Connect0
+#include <stdint.h>
+#include <pru_intc.h>
+#include "resource_table_pru0.h"
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+typedef struct {
+	uint32_t reg5;
+	uint32_t reg6;
+	uint32_t reg7;
+	uint32_t reg8;
+	uint32_t reg9;
+	uint32_t reg10;
+} bufferData;
+
+bufferData dmemBuf;
+
+/* PRU-to-ARM interrupt */
+#define PRU1_PRU0_INTERRUPT (18)
+#define PRU0_ARM_INTERRUPT (19+16)
+
+void main(void)
+{
+	/* Clear the status of all interrupts */
+	CT_INTC.SECR0 = 0xFFFFFFFF;
+	CT_INTC.SECR1 = 0xFFFFFFFF;
+
+	/* Load the buffer with default values to transfer */
+	dmemBuf.reg5 = 0xDEADBEEF;
+	dmemBuf.reg6 = 0xAAAAAAAA;
+	dmemBuf.reg7 = 0x12345678;
+	dmemBuf.reg8 = 0xBBBBBBBB;
+	dmemBuf.reg9 = 0x87654321;
+	dmemBuf.reg10 = 0xCCCCCCCC;
+
+	/* Poll until R31.30 (PRU0 interrupt) is set
+	 * This signals PRU1 is initialized */
+	while ((__R31 & (1<<30)) == 0) {
+	}
+
+	/* XFR registers R5-R10 from PRU0 to PRU1 */
+	/* 14 is the device_id that signifies a PRU to PRU transfer */
+	__xout(14, 5, 0, dmemBuf);
+
+	/* Clear the status of the interrupt */
+	CT_INTC.SICR = PRU1_PRU0_INTERRUPT;
+
+	/* Halt the PRU core */
+	__halt();
+}
diff --git a/pru-cookbook/07more/code/xout_run.sh b/pru-cookbook/07more/code/xout_run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..158cf472beddca5d3781df4026dbeea4de3338b7
--- /dev/null
+++ b/pru-cookbook/07more/code/xout_run.sh
@@ -0,0 +1,3 @@
+# Be sure to start PRU 0 before PRU 1.  PRU 0 will wait for PRU 1 to signal it.
+make TARGET=xout.pru0
+make TARGET=xin.pru1
diff --git a/pru-cookbook/07more/figures/my_delay_cycles.png b/pru-cookbook/07more/figures/my_delay_cycles.png
new file mode 100644
index 0000000000000000000000000000000000000000..125a85c0ba66e1bbc3e2bb6bffefae68538f0216
Binary files /dev/null and b/pru-cookbook/07more/figures/my_delay_cycles.png differ
diff --git a/pru-cookbook/07more/more.rst b/pru-cookbook/07more/more.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ae3abcf84c1598a23f54a2a0ea044952809d38ce
--- /dev/null
+++ b/pru-cookbook/07more/more.rst
@@ -0,0 +1,443 @@
+.. _pru-cookbook-more:
+
+More Performance
+##################
+
+So far in all our examples we've been able to meet our timing goals by writing
+our code in the C programming language. The C compiler does a suprisingly
+good job at generating code, most the time.  However there are times
+when very precise timing is needed and the compiler isn't doing it.
+
+At these times you need to write in assembly language.  This chapter
+introduces the PRU assembler and shows how to call assembly code from
+C. Detailing on how to program in assembly are beyond the scope of this text.
+
+The following are resources used in this chapter.
+
+Resources
+~~~~~~~~~~
+
+* `PRU Optimizing C/C++ Compiler, v2.2, User's Guide <http://www.ti.com/lit/ug/spruhv7b/spruhv7b.pdf>`_
+* `PRU Assembly Language Tools User's Guide <http://www.ti.com/lit/ug/spruhv6b/spruhv6b.pdf>`_
+* `PRU Assembly Instruction User Guide <http://www.ti.com/lit/ug/spruij2/spruij2.pdf>`_
+
+Calling Assembly from C
+-------------------------
+
+Problem
+~~~~~~~~~
+
+You have some C code and you want to call an assembly language routine from it.
+
+Solution
+~~~~~~~~~
+
+You need to do two things, write the assembler file and modify the ``Makefile``
+to include it. For example, let's write our own ``my_delay_cycles`` routine in
+in assembly.  The intrinsic ``pass:[__]delay_cycles`` must be passed a compile time
+constant.  Our new ``delay_cycles`` can take a runtime delay value.
+
+:ref:`more_delay-test` is much like our other c code, but on line 10 we declare 
+``my_delay_cycles`` and then on lines 24 and 26 we'll call it with an argument of 1.
+
+.. _more_delay-test:
+
+delay-test.pru0.c
+~~~~~~~~~~~~~~~~~~~
+
+:download:`code/delay-test.pru0.c <code/delay-test.pru0.c>`
+
+:ref:`more_delay` is the assembly code.
+
+.. _more_delay:
+
+delay.pru0.asm
+~~~~~~~~~~~~~~~
+
+:download:`delay.pru0.asm <code/delay.pru0.asm>`
+
+The ``Makefile`` has one addition that needs to be made to compile both :ref:`more_delay-test`
+and :ref:`more_delay`.
+If you look in the local ``Makefile`` you'll see:
+
+.. _more_makefile:
+
+Makefile
+~~~~~~~~~
+
+:download:`Makefile <code/Makefile>`
+
+This Makefle includes a common Makfile at  ``/var/lib/cloud9/common/Makefile``, this the Makefile 
+you need to edit. Edit ``/var/lib/cloud9/common/Makefile`` and go to line 195.
+
+.. code-block:: bash
+
+  $(GEN_DIR)/%.out: $(GEN_DIR)/%.o *$(GEN_DIR)/$(TARGETasm).o*
+    @mkdir -p $(GEN_DIR)
+    @echo 'LD	$^'
+    $(eval $(call target-to-proc,$@))
+    $(eval $(call proc-to-build-vars,$@))
+    @$(LD) $@ $^ $(LDFLAGS) 
+
+Add ``*(GEN_DIR)/$(TARGETasm).o*`` as shown in bold above.  You will want to remove
+this addition once you are done with this example since it will break the other examples.
+
+The following will compile and run everything.
+
+.. code-block:: bash
+
+  bone$ *config-pin P9_31 pruout*
+  bone$ *make TARGET=delay-test.pru0 TARGETasm=delay.pru0*
+  /var/lib/cloud9/common/Makefile:29: MODEL=TI_AM335x_BeagleBone_Black,TARGET=delay-test.pru0
+  -    Stopping PRU 0
+  -	copying firmware file /tmp/cloud9-examples/delay-test.pru0.out to /lib/firmware/am335x-pru0-fw
+  write_init_pins.sh
+  -    Starting PRU 0
+  MODEL   = TI_AM335x_BeagleBone_Black
+  PROC    = pru
+  PRUN    = 0
+  PRU_DIR = /sys/class/remoteproc/remoteproc1
+
+The resulting output is shown in :ref:`more_my_delay_cycles`.
+
+.. _more_my_delay_cycles:
+
+Output of my_delay_cycles()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: figures/my_delay_cycles.png
+  :align: center
+  :alt: Output of my_delay_cycles()
+
+Notice the on time is about 35ns and the off time is 30ns.
+
+Discission
+~~~~~~~~~~~~
+
+There is much to explain here.  Let's start with :ref:`more_delay`.
+
+Line-by-line of delay.pru0.asm
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. table::
+
+  +-------+-------------------------------------------------------------------------------------------------------+
+  |Line   | Explanation                                                                                           |
+  +=======+=======================================================================================================+
+  |3      | Declare `my_delay_cycles` to be global so the linker can find it.                                     |
+  +-------+-------------------------------------------------------------------------------------------------------+
+  |4      | Label the starting point for `my_delay_cycles`.                                                       |
+  +-------+-------------------------------------------------------------------------------------------------------+
+  |5      | Label for our delay loop.                                                                             |
+  +-------+-------------------------------------------------------------------------------------------------------+
+  |6      | The first argument is passed in register ``r14``.  Page 111 of                                        |
+  |       | `PRU Optimizing C/C++ Compiler, v2.2, User's Guide <http://www.ti.com/lit/ug/spruhv7b/spruhv7b.pdf>`_ |
+  |       | gives the argument passing convention.  Registers ``r14`` to ``r29`` are used                         |
+  |       | to pass arguments, if there are more arguments, the argument stack (``r4``)                           |
+  |       | is used.  The other register conventions are found on page 108.                                       |
+  |       | Here we subtract 1 from ``r14`` and save it back into ``r14``.                                        |
+  +-------+-------------------------------------------------------------------------------------------------------+
+  |7      | `qbne` is a quick branch if not equal.                                                                |
+  +-------+-------------------------------------------------------------------------------------------------------+
+  |9      | Once we've delayed enough we drop through the quick branch and                                        |
+  |       | hit the jump.  The upper bits of register `r3` has the return address,                                |
+  |       | therefore we return to the c code.                                                                    |
+  +-------+-------------------------------------------------------------------------------------------------------+
+
+:ref:`more_my_delay_cycles` shows the **on** time is 35ns and the off time is 30ns.
+With 5ns/cycle this gives 7 cycles on and 6 off. These times make sense 
+because each instruction takes a cycle and you have, set ``R30``, jump to
+``my_delay_cycles``, ``sub``, ``qbne``, ``jmp``. Plus the instruction (not seen) that
+initilizes `r14` to the passed value.  That's a total of six instructions.
+The extra instruction is the branch at the bottom of the ``while`` loop.
+
+
+Returning a Value from Assembly
+--------------------------------
+
+Problem
+~~~~~~~~~
+
+Your assembly code needs to return a value.
+
+Solution
+~~~~~~~~~
+
+``R14`` is how the return value is passed back.  :ref:`more_test2` shows the c code.
+
+.. _more_test2:
+
+delay-test2.pru0.c
+~~~~~~~~~~~~~~~~~~~
+
+:download:`delay-test2.pru0.c <code/delay-test2.pru0.c>`
+
+:ref:`more_delay2` is the assembly code.
+
+.. _more_delay2:
+
+delay2.pru0.asm
+~~~~~~~~~~~~~~~~~
+
+:download:`delay2.pru0.asm <code/delay2.pru0.asm>`
+
+An additional feature is shown in line 4 of :ref:`more_delay2`.  The
+``.cdecls "delay-test2.pru0.c"`` says to include any defines from ``delay-test2.pru0.c``
+In this example, line 6 of :ref:`more_test2` `#defines` TEST and line 12 of 
+:ref:`more_delay2` reference it.
+
+
+Using the Built-In Counter for Timing
+---------------------------------------
+
+Problem
+~~~~~~~~~
+
+I want to count how many cycles my routine takes.
+
+Solution
+~~~~~~~~~
+
+Each PRU has a ``CYCLE`` register which counts the number of cycles since
+the PRU was enabled. They also have a ``STALL`` register that counts how
+many times the PRU stalled fetching an instruction.
+:ref:`more_cycle` shows they are used.
+
+.. _more_cycle:
+
+cycle.pru0.c - Code to count cycles.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`delay2.pru0.asm <code/cycle.pru0.c>`
+
+Discission
+~~~~~~~~~~~~
+
+The code is mostly the same as other examples. ``cycle`` and ``stall`` end up in registers which
+we can read using prudebug. :ref:`more_cycle_lines` is the Line-by-line.
+
+.. _more_cycle_lines:
+
+Line-by-line for cycle.pru0.c
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+  +-------+---------------------------------------------------------------------------------------+
+  |Line   | Explanation                                                                           |
+  +=======+=======================================================================================+
+  |4      | Include needed to reference `CYCLE` and `STALL`.                                      |
+  +-------+---------------------------------------------------------------------------------------+
+  |16     | Declaring `cycle` and `stall`.  The compiler will optimize these and just             |
+  |       | keep them in registers.  We'll have to look at the `cycle.pru0.lst` file to see where |
+  |       | they are stored.                                                                      |
+  +-------+---------------------------------------------------------------------------------------+
+  |21     | Enables `CYCLE`.                                                                      |
+  +-------+---------------------------------------------------------------------------------------+
+  |26     | Reset `CYCLE`. It ignores the value assigned to it and always sets it                 |
+  |       | to 0.  `cycle` is on the right hand side to make the compiler give it it's own        |
+  |       | register.                                                                             |
+  +-------+---------------------------------------------------------------------------------------+
+  |28, 29 | Reads the `CYCLE` and `STALL` values into registers.                                  |
+  +-------+---------------------------------------------------------------------------------------+
+
+You can see where ``cycle`` and ``stall`` are stored by looking into :ref:`more_cycle_list0`.
+
+.. _more_cycle_list0:
+
+/tmp/cloud9-examples/cycle.pru0.lst Lines 113..119
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`cycle.pru0.lst lines=113..119 <code/cycle.pru0.lst>`
+
+Here the ``LDI32`` instruction loads the address ``0x22000`` into ``r0``. This is the offset to 
+the ``CTRL`` registers. Later in the file we see :ref:`more_cycle_list1`.
+ 
+.. _more_cycle_list1:
+
+/tmp/cloud9-examples/cycle.pru0.lst Lines 146..152
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:download:`lines=146..152 <code/cycle.pru0.lst>`
+
+
+The first ``LBBO`` takes the contents of ``r0`` and adds the offset 12 to it and copies 4 bytes 
+into ``r1``.  This points to ``CYCLE``, so ``r1`` has the contents of ``CYCLE``.
+
+The second ``LBBO`` does the same, but with offset 16, which points to ``STALL``,
+thus ``STALL`` is now  in ``r0``.
+
+Now fire up **prudebug** and look at those registers. 
+
+.. code-block:: bash
+
+  bone$ *sudo prudebug*
+  PRU0> *r*
+  r
+  r
+  Register info for PRU0
+      Control register: 0x00000009
+        Reset PC:0x0000  STOPPED, FREE_RUN, COUNTER_ENABLED, NOT_SLEEPING, PROC_DISABLED
+
+      Program counter: 0x0012
+        Current instruction: HALT
+
+      R00: *0x00000005*    R08: 0x00000200    R16: 0x000003c6    R24: 0x00110210
+      R01: *0x00000003*    R09: 0x00000000    R17: 0x00000000    R25: 0x00000000
+      R02: 0x000000fc    R10: 0xfff4ea57    R18: 0x000003e6    R26: 0x6e616843
+      R03: 0x0004272c    R11: 0x5fac6373    R19: 0x30203020    R27: 0x206c656e
+      R04: 0xffffffff    R12: 0x59bfeafc    R20: 0x0000000a    R28: 0x00003033
+      R05: 0x00000007    R13: 0xa4c19eaf    R21: 0x00757270    R29: 0x02100000
+      R06: 0xefd30a00    R14: 0x00000005    R22: 0x0000001e    R30: 0xa03f9990
+      R07: 0x00020024    R15: 0x00000003    R23: 0x00000000    R31: 0x00000000
+  
+
+So ``cycle`` is 3 and ``stall`` is 5. It must be one cycle to clear the GPIO and 2 cycles to read the 
+``CYCLE`` register and save it in the register. It's interesting there are 5 ``stall`` cycles. 
+
+If you switch the order of lines 30 and 31 you'll see ``cycle`` is 7 and ``stall`` is 2. ``cycle`` now includes the 
+time needed to read ``stall`` and ``stall`` no longer includes the time to read ``cycle``.
+
+Xout and Xin - Transfering Between PRUs
+---------------------------------------
+
+Problem
+~~~~~~~~~
+
+I need to transfer data between PRUs quickly.
+
+Solution
+~~~~~~~~~
+
+The ``pass:[__]xout()`` and ``pass:[__]xin()`` intrinsics are able to transfer up to 30 registers between PRU 0 and PRU 1 quickly. 
+:ref:`more_xout` shows how ``xout()`` running on PRU 0 transfers six registers to PRU 1.
+
+.. _more_xout:
+
+xout.pru0.c
+~~~~~~~~~~~~
+
+:download:`xout.pru0.c <code/xout.pru0.c>`
+
+PRU 1 waits at line 41 until PRU 0 signals it.  :ref:`more_xin` sends sends an
+interupt to PRU 0 and waits for it to send the data.
+
+.. _more_xin:
+
+xin.pru1.c
+~~~~~~~~~~~
+
+:download:`xin.pru1.c <code/xin.pru1.c>`
+
+Use ``prudebug`` to see registers R5-R10 are transfered from PRU 0 to PRU 1.
+
+.. code-block:: bash
+
+  PRU0> *r*
+  Register info for PRU0
+      Control register: 0x00000001
+        Reset PC:0x0000  STOPPED, FREE_RUN, COUNTER_DISABLED, NOT_SLEEPING, PROC_DISABLED
+
+      Program counter: 0x0026
+        Current instruction: HALT
+
+      R00: 0x00000012    *R08: 0xbbbbbbbb*    R16: 0x000003c6    R24: 0x00110210
+      R01: 0x00020000    *R09: 0x87654321*    R17: 0x00000000    R25: 0x00000000
+      R02: 0x000000e4    *R10: 0xcccccccc*    R18: 0x000003e6    R26: 0x6e616843
+      R03: 0x0004272c    R11: 0x5fac6373    R19: 0x30203020    R27: 0x206c656e
+      R04: 0xffffffff    R12: 0x59bfeafc    R20: 0x0000000a    R28: 0x00003033
+      *R05: 0xdeadbeef*    R13: 0xa4c19eaf    R21: 0x00757270    R29: 0x02100000
+      *R06: 0xaaaaaaaa*    R14: 0x00000005    R22: 0x0000001e    R30: 0xa03f9990
+      *R07: 0x12345678*    R15: 0x00000003    R23: 0x00000000    R31: 0x00000000
+
+  PRU0> *pru 1*
+  pru 1
+  Active PRU is PRU1.
+
+  PRU1> *r*
+  r
+  Register info for PRU1
+      Control register: 0x00000001
+        Reset PC:0x0000  STOPPED, FREE_RUN, COUNTER_DISABLED, NOT_SLEEPING, PROC_DISABLED
+
+      Program counter: 0x000b
+        Current instruction: HALT
+
+      R00: 0x00000100    *R08: 0xbbbbbbbb*    R16: 0xe9da228b    R24: 0x28113189
+      R01: 0xe48cdb1f    *R09: 0x87654321*    R17: 0x66621777    R25: 0xddd29ab1
+      R02: 0x000000e4    *R10: 0xcccccccc*    R18: 0x661f83ea    R26: 0xcf1cd4a5
+      R03: 0x0004db97    R11: 0xdec387d5    R19: 0xa85adb78    R27: 0x70af2d02
+      R04: 0xa90e496f    R12: 0xbeac3878    R20: 0x048fff22    R28: 0x7465f5f0
+      *R05: 0xdeadbeef*    R13: 0x5777b488    R21: 0xa32977c7    R29: 0xae96b530
+      *R06: 0xaaaaaaaa*    R14: 0xffa60550    R22: 0x99fb123e    R30: 0x52c42a0d
+      *R07: 0x12345678*    R15: 0xdeb2142d    R23: 0xa353129d    R31: 0x00000000
+
+
+Discussion
+~~~~~~~~~
+
+:ref:`more_zout_lines` shows the line-by-line for ``xout.pru0.c``
+
+.. _more_zout_lines:
+
+xout.pru0.c Line-by-line
+~~~~~~~~~~~~~~~~~~~~~~~~~
+.. table::
+
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |Line   | Explanation                                                                                             |
+  +=======+=========================================================================================================+
+  |4      | A different resource so PRU 0 can receive a signal from PRU 1.                                          |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |9-16   | ``dmemBuf`` holds the data to be sent to PRU 1.  Each will be transfered                                |
+  |       | to its corresponding register by ``xout()``.                                                            |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |21-22  | Define the interupts we're using.                                                                       |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |27-28  | Clear the interrupts.                                                                                   |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |31-36  | Initialize dmemBuf with easy to recognize values.                                                       |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |40     | Wait for PRU 1 to signal.                                                                               |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |45     | ``pass:[__]xout()`` does a direct transfer to PRU 1. Page 92 of                                         |
+  |       | `PRU Optimizing C/C++ Compiler, v2.2, User's Guide <http://www.ti.com/lit/ug/spruhv7b/spruhv7b.pdf>`_   | 
+  |       | shows how to use `xout()`. The first argument, 14, says to do a direct transfer to PRU 1.  If the       |
+  |       | first argument is 10, 11 or 12, the data is transfered to one of three scratchpad memories that         |
+  |       | PRU 1 can access later. The second argument, 5, says to start transfering with register ``r5``          |
+  |       | and use as many regsiters as needed to transfer all of ``dmemBuf``. The third argument, 0,              |
+  |       | says to not use remapping. (See the User's Guide for details.)                                          |
+  |       | The final argument is the data to be transfered.                                                        |
+  +-------+---------------------------------------------------------------------------------------------------------+
+  |48     | Clear the interupt so it can go again.                                                                  |
+  +-------+---------------------------------------------------------------------------------------------------------+
+
+:ref:`more_xin_lines` shows the line-by-line for ``xin.pru1.c``.
+
+.. _more_xin_lines:
+
+xin.pru1.c Line-by-line
+~~~~~~~~~~~~~~~~~~~~~~~~
+.. table::
+
+  +-------+-----------------------------------------------------------+
+  |Line   | Explanation                                               |
+  +=======+===========================================================+
+  |8-15   | Place to put the received data.                           |
+  +-------+-----------------------------------------------------------+
+  |26     | Signal PRU 0                                              |
+  +-------+-----------------------------------------------------------+
+  |30     | Receive the data. The arguments are the same as `xout()`, |
+  |       | 14 says to get the data directly from PRU 0.              |
+  |       | 5 says to start with register `r5`.                       |
+  |       | `dmemBuf` is where to put the data.                       |
+  +-------+-----------------------------------------------------------+
+
+If you really need speed, considering using ``pass:[__]xout()`` and ``pass:[__]xin()`` in assembly.
+
+Copyright
+----------
+
+copyright.c
+~~~~~~~~~~~~~
+
+:download:`copyright.c <code/copyright.c>`
diff --git a/pru-cookbook/08ai/ai.rst b/pru-cookbook/08ai/ai.rst
new file mode 100644
index 0000000000000000000000000000000000000000..db36f383f27b505f3f613a471bae81e0525db48e
--- /dev/null
+++ b/pru-cookbook/08ai/ai.rst
@@ -0,0 +1,377 @@
+.. _pru-cookbook-ai:
+
+Moving to the BeagleBone AI
+############################
+
+So far all our examples have focussed mostly on the BeagleBone Black and Pocket Beagle.
+These are both based on the am335x chip.  The new kid on the block is the BeagleBone AI
+which is based on the am5729. The new chip brings with it new capabilities one of
+which is four PRUs.  This chapter details what changes when moving from two to
+four PRUs.
+
+The following are resources used in this chapter.
+
+Resources
+~~~~~~~~~~~
+
+* `AM572x Technical Reference Manual <http://www.ti.com/lit/pdf/spruhz6l>`_ (AI)
+* `BeagleBone AI PRU pins <https://docs.google.com/spreadsheets/d/1dFSBVem86vAUD7MLXvqdS-N0Efi8_g_O1iTqzql8DAo/edit#gid=0>`_
+
+Moving from two to four PRUs
+=============================
+
+Problem
+--------
+
+You have code that works on the am335x PRUs and you want to move it to the 
+am5729 on the AI.
+
+Solution
+--------
+
+Things to consider when moving to the AI are:
+
+* Which pins are you going to use
+* Which PRU are you going to run on
+
+Knowing which pins to use impacts the PRU you'll use.
+
+Discission
+--------
+
+The various System Reference Manuals (SRM's) list which pins go to the PRUs.
+Here the tables are combined into one to make it easier to see what goes where.
+
+.. _aimapping_bits:
+
+Mapping bit positions to pin names
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. table::
+
+	+---+---+---------+-----------+-----------+-------------+
+	|PRU|Bit|Black pin|AI PRU1 pin|AI PRU2 pin|Pocket pin	|
+	|0  |0  |P9_31    |           |P8_44      |P1.36		|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |1  |P9_29    |           |P8_41      |P1.33     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |2  |P9_30    |           |P8_42/P8_21|P2.32     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |3  |P9_28    |P8_12      |P8_39/P8_20|P2.30     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |4  |P9_92    |P8_11      |P8_40/P8_25|P1.31     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |5  |P9_27    |P9_15      |P8_37/P8_24|P2.34     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |6  |P9_91    |           |P8_38/P8_5 |P2.28     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |7  |P9_25    |           |P8_36/P8_6 |P1.29     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |8  |         |           |P8_34/P8_23|     		|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |9  |         |           |P8_35/P8_22|     		|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |19 |         |           |P8_33/P8_3 |     		|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |11 |         |           |P8_31/P8_4 |     		|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |12 |         |           |P8_32      |     		|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |13 |         |           |P8_45      |     		|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |14 |P8_12(out) P8_16(in)||P9_11      |P2.24     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |15 |P8_11(out) P8_15(in)||P8_17/P9_13|P2.33     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |16 |P9_41(in) P9_26(in)| |P8_27	  |				|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |17 |         |P9_26      |P8_28      |				|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |18 |         |           |P8_29      |				|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |19 |         |           |P8_30      |				|
+	+---+---+---------+-----------+-----------+-------------+
+	|0  |20 |         |           |P8_46/P8_8 |				|
+	+---+---+---------+-----------+-----------+-------------+
+	|   |   |         |           |           |             |
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |0  |P8_45    |           |P8_32      |          	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |1  |P8_46    |*P9_20*    |           |          	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |2  |P8_43    |*P9_19*    |           |          	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |3  |P8_44    |P9_41      |           |          	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |4  |P8_41    |           |           |          	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |5  |P8_42    |*P8_18*    |P9_25      |          	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |6  |P8_39    |*P8_19*    |P8_9       |          	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |7  |P8_40    |*P8_13*    |P9_31      |          	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |8  |P8_27    |           |P9_18      |P2.35     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |9  |P8_29    |P8_14      |P9_17      |P2.01     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |10 |P8_28    |P9_42      |P9_31      |P1.35     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |11 |P8_30    |P9_27      |P9_29      |P1.04     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |12 |P8_21    |           |P9_30      |          	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |13 |P8_20    |           |P9_26      |          	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |14 |         |P9_14      |P9_42      |P1.32     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |15 |         |*P9_16*    |P8_10      |P1.30     	|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |16 |P9_26(in)|*P8_15*    |P8_7       |     		|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |17 |         |*P8_26*    |P8_27      |     		|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |18 |         |*P8_16*    |P8_45      |     		|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |19 |         |           |P8_46      |     		|
+	+---+---+---------+-----------+-----------+-------------+
+	|1  |19 |         |           |P8_43      |     		|
+	+---+---+---------+-----------+-----------+-------------+
+
+The pins in *bold* are already configured as pru pins.  See :ref:`ai_config` to
+see what's currently configured as what.  See :ref:`ai_device_tree` to 
+configure pins.
+
+.. _ai_config:
+
+Seeing how pins are configured
+===============================
+
+Problem
+--------
+
+You want to know how the pins are currently configured.
+
+Solution
+---------
+
+The ``show-pins.pl`` command does what you want, but you have to set it up first.
+
+.. code-block:: bash
+
+	bone$ cd ~/bin
+	bone$ ln -s /opt/scripts/device/bone/show-pins.pl .
+
+This creates a symbolic link to the ``show-pins.pl`` command that is rather hidden
+away.  The link is put in the ``bin`` directory which is in the default command
+``$PATH``.  Now you can run ``show-pins.pl`` from anywhere.
+
+.. code-block:: bash
+
+	bone$ *show-pins.pl*
+	P9.19a                    16   R6 7 fast rx  up  i2c4_scl
+	P9.20a                    17   T9 7 fast rx  up  i2c4_sda
+	P8.35b                    57  AD9 e fast    down gpio3_0
+	P8.33b                    58  AF9 e fast    down gpio3_1
+	...
+
+Here you see ``P9.19a`` and ``P9.20a`` are configured for i2c with pull up resistors.
+The ``P8`` pins are configured as gpio with pull down resistors. They are 
+both on gpio port 3.  ``P8.35b`` is bit 0 while ``P8.33b`` is bit 1. You can find
+which direction they are set by using ``gpioinfo`` and the chip number.  
+Unfortunately you subtract one from the port number to get the chip number.
+So ``P8.35b`` is on chip number 2.
+
+.. code-block:: bash
+
+	bone$ *gpioinfo 2*
+		line   0:      unnamed       unused   *input*  active-high 
+		line   1:      unnamed       unused   *input*  active-high 
+		line   2:      unnamed       unused   input  active-high 
+		line   3:      unnamed       unused   input  active-high 
+		line   4:      unnamed       unused   input  active-high 
+	...
+
+Here we see both (lines 0 and 1) are set to input.
+
+Adding ``-v`` gives more details.
+
+.. code-block:: bash
+
+	bone$ *show-pins.pl -v*
+	...
+	sysboot 14                14   H2 f fast    down sysboot14
+	sysboot 15                15   H3 f fast    down sysboot15
+	P9.19a                    16   R6 7 fast rx  up  i2c4_scl
+	P9.20a                    17   T9 7 fast rx  up  i2c4_sda
+							18   T6 f fast    down Driver off
+							19   T7 f fast    down Driver off
+	bluetooth in              20   P6 8 fast rx      uart6_rxd        mmc@480d1000 (wifibt_extra_pins_default)
+	bluetooth out             21   R9 8 fast rx      uart6_txd        mmc@480d1000 (wifibt_extra_pins_default)
+	...
+
+The best way to use ``show-pins.pl`` is with ``grep``.  To see all the pru pins try:
+
+.. code-block:: bash
+
+	bone$ *show-pins.pl  | grep -i pru | sort*
+	P8.13                    100   D3 c fast rx      pr1_pru1_gpi7
+	P8.15b                   109   A3 d fast    down pr1_pru1_gpo16
+	P8.16                    111   B4 d fast    down pr1_pru1_gpo18
+	P8.18                     98   F5 c fast rx      pr1_pru1_gpi5
+	P8.19                     99   E6 c fast rx      pr1_pru1_gpi6
+	P8.26                    110   B3 d fast    down pr1_pru1_gpo17
+	P9.16                    108   C5 d fast    down pr1_pru1_gpo15
+	P9.19b                    95   F4 c fast rx  up  pr1_pru1_gpi2
+	P9.20b                    94   D2 c fast rx  up  pr1_pru1_gpi1
+
+Here we have nine pins configured for the PRU registers ``R30`` and ``R31``.
+Five are input pins and four are out.
+
+.. _ai_device_tree:
+
+Configuring pins on the AI via device trees
+============================================
+
+Problem
+--------
+
+I want to configure another pin for the PRU, but I get an error.
+
+.. code-block:: bash
+		
+	bone$ *config-pin P9_31 pruout*
+	ERROR: open() for /sys/devices/platform/ocp/ocp:P9_31_pinmux/state failed, No such file or directory
+
+Solution
+---------
+
+The pins on the AI must be configure at boot time and therefor cannot be
+configured with ``config-pin``.  Instead you must edit the device tree.
+
+Discission
+-----------
+
+Suppose you want to make ``P9_31`` a PRU output pin. First go to the
+`am5729 System Reference Manual <https://github.com/beagleboard/beaglebone-ai/wiki/System-Reference-Manual#p8.10-p8.13>`_
+and look up ``P9_31``.  
+
+.. tip::
+
+	The `BeagleBone AI PRU pins <https://docs.google.com/spreadsheets/d/1dFSBVem86vAUD7MLXvqdS-N0Efi8_g_O1iTqzql8DAo/edit#gid=0>`_
+	table may be easier to use.
+
+``P9_31`` appears twice, as ``P9_31a`` and ``P9_31b``. Either should work, let's pick ``P9_31a``.
+
+.. warning::
+	When you have two internal pins attached to the same header (either P8 or P9)
+	make sure only one is configured as an output.  If both are outputs, you could
+	damage the AI.
+
+We see that when ``P9_31a`` is set to ``MODE13`` it will be a PRU **out** pin.  
+``MODE12`` makes it a PRU **in** pin.  It appears at bit 10 on PRU2_1.
+
+Next, find which kernel you are running.
+
+.. code-block:: bash
+	bone$ uname -a
+	Linux ai 4.14.108-ti-r131 #1buster SMP PREEMPT Tue Mar 24 19:18:36 UTC 2020 armv7l GNU/Linux
+
+I'm running the 4.14 version. Now look in ``/opt/source`` for your kernel.
+
+.. code-block:: bash
+
+	bone$ cd /opt/source/
+	bone$ ls
+	adafruit-beaglebone-io-python  dtb-5.4-ti       rcpy
+	BBIOConfig                     librobotcontrol  u-boot_v2019.04
+	bb.org-overlays                list.txt         u-boot_v2019.07-rc4
+	*dtb-4.14-ti*                    pyctrl
+	dtb-4.19-ti                    py-uio
+
+``am5729-beagleboneai.dts`` is the file we need to edit.  Search for ``P9_31``. You'l see:
+
+.. code-block:: bash
+	:linenos:
+
+	DRA7XX_CORE_IOPAD(0x36DC, MUX_MODE14) // B13: P9.30: mcasp1_axr10.off //
+	DRA7XX_CORE_IOPAD(0x36D4, *MUX_MODE13*) // B12: *P9.31a*: mcasp1_axr8.off //
+	DRA7XX_CORE_IOPAD(0x36A4, MUX_MODE14) // C14: P9.31b: mcasp1_aclkx.off //
+
+Change the ``MUX_MODE14`` to ``MUX_MODE13`` for output, or ``MUX_MODE12`` for input.
+
+Compile and install.  The first time will take a while since it recompiles all the dts files.
+
+.. code-block:: bash
+	:linenos:
+
+	bone$ make
+	...
+	DTC     src/arm/am335x-sl50.dtb
+	DTC     src/arm/am5729-beagleboneai.dtb
+	DTC     src/arm/am335x-nano.dtb
+	...
+	bone$ sudo make install
+	...
+	'src/arm/am5729-beagleboneai.dtb' -> '/boot/dtbs/4.14.108-ti-r131/am5729-beagleboneai.dtb'
+	...
+	bone$ reboot
+	...
+	bone$ *show-pins.pl -v | sort | grep -i pru*
+	P8.13                    100   D3 c fast rx      pr1_pru1_gpi7
+	P8.15b                   109   A3 d fast    down pr1_pru1_gpo16
+	P8.16                    111   B4 d fast    down pr1_pru1_gpo18
+	P8.18                     98   F5 c fast rx      pr1_pru1_gpi5
+	P8.19                     99   E6 c fast rx      pr1_pru1_gpi6
+	P8.26                    110   B3 d fast    down pr1_pru1_gpo17
+	P9.16                    108   C5 d fast    down pr1_pru1_gpo15
+	P9.19b                    95   F4 c fast rx  up  pr1_pru1_gpi2
+	P9.20b                    94   D2 c fast rx  up  pr1_pru1_gpi1
+	P9.31a                   181  B12 d fast    down pr2_pru1_gpo10
+
+
+There it is.  `P9_31` is now a PRU output pin on PRU1_0, bit 3.
+
+.. _ai_using_pru_pins:
+
+Using the PRU pins
+====================
+
+Problem
+--------
+
+Once I have the PRU pins configured on the AI how do I use them?
+
+Solution
+--------
+
+In :ref:`ai_device_tree` we configured ``P9_31a`` to be a PRU pin.  ``show-pins.pl`` showed
+that it appears at ``pr2_pru1_gpo10``, which means pru2_1 accesses it using
+bit 10 of register ``R30``.
+
+Discission
+--------
+
+It's easy to modify the pwm example from :ref:`blocks_pwm` to use this pin.
+First copy the example you want to modify to ``pwm1.pru2_1.c``.  The ``pru2_1`` in
+the file name tells the Makefile to run the code on pru2_1.  :ref:`ai_pwm1` shows
+the adapted code.
+
+.. _ai_pwm1:
+
+pwm1.pru2_1.c
+~~~~~~~~~~~~~~
+
+:download:`pwm1.pru2_1.c <code/pwm1.pru2_1.c>`
+
+
+One line 6 ``P9_31`` is defined as ``(0x1:ref:`10)``, which means shift ``1`` over by 10 bits.
+That's the only change needed.  Copy the local Makefile to the same directory and
+compile and run.
+
+.. code-block:: bash
+	:linenos:
+
+	bone$ make TARGET=pwm1.pru2_1
+
+Attach an LED to ``P9_31`` and it should be blinking.
diff --git a/pru-cookbook/08ai/code/Makefile b/pru-cookbook/08ai/code/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a7557fdaa22988d89cec879477ded78522d7116f
--- /dev/null
+++ b/pru-cookbook/08ai/code/Makefile
@@ -0,0 +1 @@
+include /var/lib/cloud9/common/Makefile
diff --git a/pru-cookbook/08ai/code/pwm1.pru2_1.c b/pru-cookbook/08ai/code/pwm1.pru2_1.c
new file mode 100644
index 0000000000000000000000000000000000000000..d35f2185cffd779cb1f18e252fe5252b803cd26e
--- /dev/null
+++ b/pru-cookbook/08ai/code/pwm1.pru2_1.c
@@ -0,0 +1,24 @@
+#include <stdint.h>
+#include <pru_cfg.h>
+#include "resource_table_empty.h"
+#include "prugpio.h"
+
+#define P9_31 (0x1<<10)
+
+volatile register uint32_t __R30;
+volatile register uint32_t __R31;
+
+void main(void)
+{
+	uint32_t gpio = P9_31;	// Select which pin to toggle.;
+
+	/* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */
+	CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
+
+	while(1) {
+		__R30 |= gpio;		// Set the GPIO pin to 1
+		__delay_cycles(100000000);
+		__R30 &= ~gpio;		// Clear the GPIO pin
+		__delay_cycles(100000000);
+	}
+}
diff --git a/pru-cookbook/common/Makefile b/pru-cookbook/common/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..5b3999031af3d04540e6d4c8057624d1fe21664b
--- /dev/null
+++ b/pru-cookbook/common/Makefile
@@ -0,0 +1,235 @@
+#
+# Optional definitions
+#
+# TARGET - executable to create (currently supports single .c source)
+#          should have .<proc>(<n>) extension (lower case, check below for valid options)
+#          without TARGET, as of now, we don't have any build targets
+#          TODO: work with a list of targets, rather than a single file
+# PRUN   - TBD
+
+#
+# Directories (external packages, etc.)
+#
+# COMMON points to where this primary Makefile and shell scripts live.
+# PRU_CGT points to the TI PRU compiler directory.
+# PRU_SUPPORT points to pru-software-support-package.
+# C6X_CGT points to the TI C6X compiler directory.
+# TIDL_API_DIR points to the TIDL API install directory.
+# GEN_DIR points to where to build the binaries.
+# MODEL is the board model (BeagleBoard.org_BeagleBone_AI, TI_AM335x_BeagleBone_Blue, etc.)
+COMMON:=$(abspath $(lastword $(MAKEFILE_LIST)/..))
+PRU_CGT:=/usr/share/ti/cgt-pru
+PRU_SUPPORT:=/usr/lib/ti/pru-software-support-package
+PRU_STARTERWARE:=/usr/share/ti/starterware
+C6X_CGT:=/usr/share/ti/cgt-c6x
+TIDL_API_DIR:=/usr/share/ti/tidl/tidl_api
+GEN_DIR:=/tmp/cloud9-examples
+MODEL:=$(shell cat /proc/device-tree/model | sed 's/ /_/g' | tr -d '\000')
+# $(warning MODEL=$(MODEL),TARGET=$(TARGET),COMMON=$(COMMON))
+$(warning MODEL=$(MODEL),TARGET=$(TARGET))
+
+#
+# Define PROC and build variables
+#
+# Arguments:
+#   $@ - target name
+#
+# Variables defined:
+#   CHIP - target system-on-chip (am57xx, am335x)
+#   CHIP_REV - target system-on-chip with rev (am572x_2_0, am335x)
+#   PROC - cpu type (arm, pru, c6x, etc.)
+#   PRUN - identifier for target PRU core
+#   PRU_DIR - control directory for the PRU
+#   CC -
+#   LD - 
+#   LDFLAGS - 
+#   CFLAGS -
+#
+# Depends on udev rules: https://github.com/beagleboard/customizations/blob/master/etc/udev/rules.d/86-remoteproc-noroot.rules
+# Check which model
+define target-to-proc =
+ ifeq ($(suffix $(basename $(1))),.pru1_0)
+  CHIP=am57xx
+  CHIP_REV=am572x_2_0
+  PRU_DIR=/dev/remoteproc/pruss1-core0
+  PRUN=1_0
+  PROC=pru
+  EXE=.out
+ else ifeq ($(suffix $(basename $(1))),.pru1_1)
+  CHIP=am57xx
+  CHIP_REV=am572x_2_0
+  PRU_DIR=/dev/remoteproc/pruss1-core1
+  PRUN=1_1
+  PROC=pru
+  EXE=.out
+ else ifeq ($(suffix $(basename $(1))),.pru2_0)
+  CHIP=am57xx
+  CHIP_REV=am572x_2_0
+  PRU_DIR=/dev/remoteproc/pruss2-core0
+  PRUN=2_0
+  PROC=pru
+  EXE=.out
+ else ifeq ($(suffix $(basename $(1))),.pru2_1)
+  CHIP=am57xx
+  CHIP_REV=am572x_2_0
+  PRU_DIR=/dev/remoteproc/pruss2-core1
+  PRUN=2_1
+  PROC=pru
+  EXE=.out
+ else ifeq ($(suffix $(basename $(1))),.pru0)
+  CHIP=am335x
+  CHIP_REV=am335x
+  PRU_DIR=/dev/remoteproc/pruss-core0
+  PRUN=0
+  PROC=pru
+  EXE=.out
+ else ifeq ($(suffix $(basename $(1))),.pru1)
+  CHIP=am335x
+  CHIP_REV=am335x
+  PRU_DIR=/dev/remoteproc/pruss-core1
+  PRUN=1
+  PROC=pru
+  EXE=.out
+ else ifeq ($(suffix $(basename $(1))),.tidl)
+  CHIP=am57xx
+  PROC=tidl
+  EXE=.so
+ else
+  PROC=arm
+  EXE=.out
+ endif
+endef
+
+#
+# Arguments:
+#   $@ - target name
+# 
+# Variables required:
+#   CHIP - target system-on-chip (am57xx, am335x)
+#   CHIP_REV - target system-on-chip with rev (am572x_2_0, am335x)
+#   PROC - cpu type (arm, pru, c6x, etc.)
+#   PRUN - identifier for target PRU core
+#   PRU_DIR - control directory for the PRU
+define proc-to-build-vars =
+ ifeq ($(PROC),pru)
+  LD=lnkpru -o
+  LDFLAGS=--reread_libs --warn_sections --stack_size=0x100 --heap_size=0x100 -m $(basename $(1)).map \
+   -i$(PRU_CGT)/lib -i$(PRU_CGT)/include $(COMMON)/$(CHIP)_$(PROC).cmd --library=libc.a \
+   --library=$(PRU_SUPPORT)/lib/rpmsg_lib.lib
+  CC=clpru -fe
+  CFLAGS=--include_path=$(COMMON) --include_path=$(PRU_SUPPORT)/include \
+   --include_path=$(PRU_SUPPORT)/include/$(CHIP_REV) \
+   --include_path=$(PRU_STARTERWARE)/include --include_path=$(PRU_STARTERWARE)/include/hw \
+   --include_path=$(PRU_CGT)/include -DCHIP=$(CHIP) -DCHIP_IS_$(CHIP) -DMODEL=$(MODEL) -DPROC=$(PROC) -DPRUN=$(PRUN) \
+   -v3 -O2 --printf_support=minimal --display_error_number --endian=little --hardware_mac=on \
+   --obj_directory=$(GEN_DIR) --pp_directory=$(GEN_DIR) --asm_directory=$(GEN_DIR) -ppd -ppa --asm_listing \
+   --c_src_interlist
+ else ifeq ($(PROC),tidl)
+  LD=g++ -o
+  LDFLAGS=-lopencv_highgui -lopencv_imgcodecs -lopencv_videoio -lopencv_imgproc -lopencv_core \
+   $(TIDL_API_DIR)/tidl_api.a $(TIDL_API_DIR)/tidl_imgutil.a \
+   -lTIOpenCL -locl_util -lpthread
+  CXX=g++ -c -o
+  CXXFLAGS=-DCHIP=$(CHIP) -DMODEL=$(MODEL) -DPROC=$(PROC) -fPIC -O3 -Wall -Werror -Wno-error=ignored-attributes \
+   -I. -I$(TIDL_API_DIR)/inc -std=c++14 -I/usr/share/ti/opencl 
+ else
+  LD=gcc -o
+  LDFLAGS=-lc -lm
+  CC=gcc -c -o
+  CFLAGS=-DCHIP=$(CHIP) -DMODEL=$(MODEL) -DPROC=$(PROC)
+ endif
+endef
+
+#
+#
+#
+
+ifneq ($(TARGET),)
+$(eval $(call target-to-proc,$(TARGET).out))
+# $(warning GEN_DIR=$(GEN_DIR),CHIP=$(CHIP),PROC=$(PROC),PRUN=$(PRUN),PRU_DIR=$(PRU_DIR),EXE=$(EXE))
+
+all: stop install start
+	@echo "MODEL   = $(MODEL)"
+	@echo "PROC    = $(PROC)"
+	@echo "PRUN    = $(PRUN)"
+	@echo "PRU_DIR = $(PRU_DIR)"
+
+# TODO: think about what we want to say if stop fails
+stop:
+ifneq ($(PRU_DIR),)
+	@echo "-    Stopping PRU $(PRUN)"
+	@echo stop > $(PRU_DIR)/state || echo Cannot stop $(PRUN)
+endif
+
+start:
+ifneq ($(PRU_DIR),)
+	@echo write_init_pins.sh
+	@$(COMMON)/write_init_pins.sh /lib/firmware/$(CHIP)-pru$(PRUN)-fw
+	@echo "-    Starting PRU $(PRUN)"
+	@echo start > $(PRU_DIR)/state
+else ifeq ($(PROC),tidl)
+	ti-mct-heap-check -c
+	sudo mjpg_streamer -i "input_opencv.so -r 640x480 -d /dev/$(shell fgrep -v vpe /sys/class/video4linux/video*/name | perl -ne '/\/(video\d+)\/name/ && print $$1') \
+	--filter ./$(TARGET)$(EXE)" -o "output_http.so -p 8090 -w /usr/share/mjpg-streamer/www"
+else
+	./$(TARGET)$(EXE)
+endif
+
+install: $(GEN_DIR)/$(TARGET)$(EXE)
+ifneq ($(PRU_DIR),)
+	@echo '-	copying firmware file $(GEN_DIR)/$(TARGET).out to /lib/firmware/$(CHIP)-pru$(PRUN)-fw'
+	@cp $(GEN_DIR)/$(TARGET)$(EXE) /lib/firmware/$(CHIP)-pru$(PRUN)-fw
+else
+	@cp $(GEN_DIR)/$(TARGET)$(EXE) ./$(TARGET)$(EXE)
+endif
+endif
+
+%.out: $(GEN_DIR)/%.out
+	@echo 'CP	$^'
+	@cp $^ $@
+
+%.so: $(GEN_DIR)/%.so
+	@echo 'CP	$^'
+	@cp $^ $@
+
+# TODO: look up how Makefiles typically break down the output file specification
+# $(warning CHIP=$(CHIP),PROC=$(PROC))
+# $(warning CC=$(CC),LD=$(LD),CFLAGS=$(CFLAGS),LDFLAGS=$(LDFLAGS))
+$(GEN_DIR)/%.out: $(GEN_DIR)/%.o
+	@mkdir -p $(GEN_DIR)
+	@echo 'LD	$^'
+	$(eval $(call target-to-proc,$@))
+	$(eval $(call proc-to-build-vars,$@))
+	@$(LD) $@ $^ $(LDFLAGS) 
+
+$(GEN_DIR)/%.so: $(GEN_DIR)/%.o
+	@mkdir -p $(GEN_DIR)
+	@echo 'LD	$^'
+	$(eval $(call target-to-proc,$@))
+	$(eval $(call proc-to-build-vars,$@))
+	@$(LD) $@ -shared $^ $(LDFLAGS) 
+
+$(GEN_DIR)/%.o: %.asm
+	@mkdir -p $(GEN_DIR)
+	@echo 'CC	$^'
+	$(eval $(call target-to-proc,$@))
+	$(eval $(call proc-to-build-vars,$@))
+	@$(CC) $@ $^ $(CFLAGS)
+
+$(GEN_DIR)/%.o: %.c
+	@mkdir -p $(GEN_DIR)
+	@echo 'CC	$^'
+	$(eval $(call target-to-proc,$@))
+	$(eval $(call proc-to-build-vars,$@))
+	@$(CC) $@ $^ $(CFLAGS)
+
+$(GEN_DIR)/%.o: %.cpp
+	@mkdir -p $(GEN_DIR)
+	@echo 'CXX	$^'
+	$(eval $(call target-to-proc,$@))
+	$(eval $(call proc-to-build-vars,$@))
+	@$(CXX) $@ $^ $(CXXFLAGS)
+
+clean:
+	@echo 'CLEAN'
+	@rm -rf $(GEN_DIR)
diff --git a/pru-cookbook/common/README.md b/pru-cookbook/common/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..379ccc41af34ca13255e40b76c1b8461f5f78bea
--- /dev/null
+++ b/pru-cookbook/common/README.md
@@ -0,0 +1,2 @@
+# common
+These are the files used by all the platforms for running the PRUs.
diff --git a/pru-cookbook/common/config-pin.sh b/pru-cookbook/common/config-pin.sh
new file mode 100755
index 0000000000000000000000000000000000000000..682fecd697201463a0ab58d238aad25cfbffe760
--- /dev/null
+++ b/pru-cookbook/common/config-pin.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# Adds "in" and "out" to config-pin
+#
+# Usage:  config-pin.sh P9_11 out
+
+pin=$1  # Name of pin to be changed
+dir=$2  # Direction, either in or out
+
+if [ "$dir" != "in" ] && [ "$dir" != "out" ] ; then
+    # Use config-pin
+    /usr/bin/config-pin $*
+    exit
+fi
+
+# Maps pin name (P9_11) to gpio number (gpio30) via libgpiod
+# Find which gpio
+chip=0
+found=0
+
+# Check each gpio chip
+while [ $chip -lt 4 ] ; do
+    # echo $chip
+    # Remove : from line number
+    line=$(gpioinfo $chip | grep $pin | awk '{ print substr($2, 1, length($2)-1) }')
+    
+    [ ! -z "$line" ] && found=1 && break
+    chip=$[$chip+1]
+done
+
+# echo chip: $chip line:  $line
+
+if [ $found -ne 0 ] ; then
+    gpio=gpio$[32*$chip+$line]
+    # echo $gpio
+    echo $dir > /sys/class/gpio/$gpio/direction
+    /usr/bin/config-pin $pin gpio
+else
+    echo $pin not found
+fi
diff --git a/pru-cookbook/common/init_pins_empty.h b/pru-cookbook/common/init_pins_empty.h
new file mode 100644
index 0000000000000000000000000000000000000000..9da8995e8c6ba25775f9748bc4366ce58d0e85c9
--- /dev/null
+++ b/pru-cookbook/common/init_pins_empty.h
@@ -0,0 +1,6 @@
+// Defins an empty table to write_init_pins wont' complain
+
+#pragma DATA_SECTION(init_pins, ".init_pins")
+#pragma RETAIN(init_pins)
+const char init_pins[] =
+	"\0\0";
diff --git a/pru-cookbook/common/prugpio.h b/pru-cookbook/common/prugpio.h
new file mode 100644
index 0000000000000000000000000000000000000000..6d83e1d8a386442ea0f39895146b6fa040f3f0a6
--- /dev/null
+++ b/pru-cookbook/common/prugpio.h
@@ -0,0 +1,105 @@
+// This file defines the GPIO port addresses and PRU address
+
+#if defined(CHIP) && defined(CHIP_IS_am57xx)
+#warning "Found AI"
+// These are addresses for the am5729
+// First define the 9 GPIO port addresses
+#define GPIO1 0x4AE10000
+#define GPIO2 0x48055000
+#define GPIO3 0x48057000
+#define GPIO4 0x48059000
+#define GPIO5 0x4805B000
+#define GPIO6 0x4805D000
+#define GPIO7 0x48051000
+#define GPIO8 0x48053000
+
+// These define which bits in a given port go to the USR LEDs
+// GPIO3
+#define USR0 (1<<17)
+#define USR2 (1<<15)
+#define USR3 (1<<14)
+#define USR4 (1<< 7)
+// GPIO5
+#define USR1 (1<< 5)
+// The define a couple of GPIO pin addresses
+// GPIO6
+#define P9_25   (1<<17)
+// GPIO8
+#define P8_17   (1<18)
+
+// These define which bin in register R30 go to which header pins
+// R30 bits - Output on pru1_1
+#define P9_14	(1<<14)
+#define P9_16	(1<<15)
+#define P8_15	(1<<16)
+#define P8_26	(1<<17)
+#define P8_16	(1<<18)
+// R31 bits - Input on pru1_1
+#define P8_18	(1<<5)
+#define P8_19	(1<<6)
+#define P8_13	(1<<7)
+
+// Shared memory
+#define AM33XX_DATARAM0_PHYS_BASE1		0x4b200000
+#define AM33XX_DATARAM1_PHYS_BASE1		0x4b202000
+#define AM33XX_PRUSS_SHAREDRAM_BASE1	0x4b210000
+
+#define AM33XX_DATARAM0_PHYS_BASE2		0x4b280000
+#define AM33XX_DATARAM1_PHYS_BASE2		0x4b282000
+#define AM33XX_PRUSS_SHAREDRAM_BASE2	0x4b290000
+
+#else
+
+#warning "Found am335x"
+// These are addresses for the am35xx
+#define GPIO0 0x44E07000        // From table 2.2 of am335x TRM
+#define GPIO1 0x4804C000
+#define GPIO2 0x481AC000
+#define GPIO3 0x481AE000
+
+// USR LED bit positions
+// GPIO1
+#define USR0 (1<<21)
+#define USR1 (1<<22)
+#define USR2 (1<<23)
+#define USR3 (1<<24)
+// The define a couple of GPIO pin addresses on Black
+// GPIO1
+#define P9_14 (1<<18)
+#define P9_16 (1<<19)
+
+// The define a couple of GPIO pin addresses on Pocket
+// GPIO1
+#define P2_1 (1<<18)
+#define P1_32 (1<<10)
+
+// R30 output bits on pru0
+#define P9_31   (1<<0)
+#define P9_29   (1<<1)
+#define P9_30   (1<<2)
+#define P9_28   (1<<3)
+#define P9_92   (1<<4)
+#define P9_27   (1<<5)
+#define P9_91   (1<<6)
+#define P9_25   (1<<7)
+
+// R30 output bits on pru0 on Pocket
+#define P1_36   (1<<0)
+#define P1_33   (1<<1)
+#define P2_32   (1<<2)
+#define P2_30   (1<<3)
+#define P1_31   (1<<4)
+#define P2_34   (1<<5)
+#define P2_28   (1<<6)
+#define P1_29   (1<<7)
+
+// Shared memory
+#define AM33XX_DATARAM0_PHYS_BASE		0x4a300000
+#define AM33XX_DATARAM1_PHYS_BASE		0x4a302000
+#define AM33XX_PRUSS_SHAREDRAM_BASE		0x4a310000
+
+#endif
+// /4 to convert from byte address to word address
+#define GPIO_CLEARDATAOUT	0x190/4     // Write 1 here to set a given bit    
+#define GPIO_SETDATAOUT 	0x194/4     // A 1 here clears the corresponding bit
+#define GPIO_DATAOUT		0x138/4     // For reading the GPIO registers
diff --git a/pru-cookbook/common/resource_table_0.h b/pru-cookbook/common/resource_table_0.h
new file mode 100644
index 0000000000000000000000000000000000000000..1c853b95775fd159d65ef12c71abfde1baff890e
--- /dev/null
+++ b/pru-cookbook/common/resource_table_0.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *	* Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ *
+ *	* Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the
+ *	  distribution.
+ *
+ *	* Neither the name of Texas Instruments Incorporated nor the names of
+ *	  its contributors may be used to endorse or promote products derived
+ *	  from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RSC_TABLE_PRU_H_
+#define _RSC_TABLE_PRU_H_
+
+#include <stddef.h>
+#include <rsc_types.h>
+#include "pru_virtio_ids.h"
+
+/*
+ * Sizes of the virtqueues (expressed in number of buffers supported,
+ * and must be power of 2)
+ */
+#define PRU_RPMSG_VQ0_SIZE	16
+#define PRU_RPMSG_VQ1_SIZE	16
+
+/*
+ * The feature bitmap for virtio rpmsg
+ */
+#define VIRTIO_RPMSG_F_NS	0		//name service notifications
+
+/* This firmware supports name service notifications as one of its features */
+#define RPMSG_PRU_C0_FEATURES	(1 << VIRTIO_RPMSG_F_NS)
+
+/* Definition for unused interrupts */
+#define HOST_UNUSED		255
+
+/* Mapping sysevts to a channel. Each pair contains a sysevt, channel. */
+struct ch_map pru_intc_map[] = { 
+	{16, 2},
+	{17, 0},
+};
+
+struct my_resource_table {
+	struct resource_table base;
+
+	uint32_t offset[2]; /* Should match 'num' in actual definition */
+
+	/* rpmsg vdev entry */
+	struct fw_rsc_vdev rpmsg_vdev;
+	struct fw_rsc_vdev_vring rpmsg_vring0;
+	struct fw_rsc_vdev_vring rpmsg_vring1;
+
+	/* intc definition */
+	struct fw_rsc_custom pru_ints;
+};
+
+#pragma DATA_SECTION(resourceTable, ".resource_table")
+#pragma RETAIN(resourceTable)
+struct my_resource_table resourceTable = {
+	1,	/* Resource table version: only version 1 is supported by the current driver */
+	2,	/* number of entries in the table */
+	0, 0,	/* reserved, must be zero */
+	/* offsets to entries */
+	{
+		offsetof(struct my_resource_table, rpmsg_vdev),
+		offsetof(struct my_resource_table, pru_ints),
+	},
+
+	/* rpmsg vdev entry */
+	{
+		(uint32_t)TYPE_VDEV,                    //type
+		(uint32_t)VIRTIO_ID_RPMSG,              //id
+		(uint32_t)0,                            //notifyid
+		(uint32_t)RPMSG_PRU_C0_FEATURES,	//dfeatures
+		(uint32_t)0,                            //gfeatures
+		(uint32_t)0,                            //config_len
+		(uint8_t)0,                             //status
+		(uint8_t)2,                             //num_of_vrings, only two is supported
+		{ (uint8_t)0, (uint8_t)0 },             //reserved
+		/* no config data */
+	},
+	/* the two vrings */
+	{
+		0,                      //da, will be populated by host, can't pass it in
+		16,                     //align (bytes),
+		PRU_RPMSG_VQ0_SIZE,     //num of descriptors
+		0,                      //notifyid, will be populated, can't pass right now
+		0                       //reserved
+	},
+	{
+		0,                      //da, will be populated by host, can't pass it in
+		16,                     //align (bytes),
+		PRU_RPMSG_VQ1_SIZE,     //num of descriptors
+		0,                      //notifyid, will be populated, can't pass right now
+		0                       //reserved
+	},
+
+	{
+		TYPE_CUSTOM, TYPE_PRU_INTS,
+		sizeof(struct fw_rsc_custom_ints),
+		{ /* PRU_INTS version */
+			0x0000,
+			/* Channel-to-host mapping, 255 for unused */
+			0, HOST_UNUSED, 2, HOST_UNUSED, HOST_UNUSED,
+			HOST_UNUSED, HOST_UNUSED, HOST_UNUSED, HOST_UNUSED, HOST_UNUSED,
+			/* Number of evts being mapped to channels */
+			(sizeof(pru_intc_map) / sizeof(struct ch_map)),
+			/* Pointer to the structure containing mapped events */
+			pru_intc_map,
+		},
+	},
+};
+
+#endif /* _RSC_TABLE_PRU_H_ */
diff --git a/pru-cookbook/common/resource_table_1.h b/pru-cookbook/common/resource_table_1.h
new file mode 100644
index 0000000000000000000000000000000000000000..b062c71f3e66559102cc8f65f9b8d8274b144aef
--- /dev/null
+++ b/pru-cookbook/common/resource_table_1.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *	* Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ *
+ *	* Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the
+ *	  distribution.
+ *
+ *	* Neither the name of Texas Instruments Incorporated nor the names of
+ *	  its contributors may be used to endorse or promote products derived
+ *	  from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RSC_TABLE_PRU_H_
+#define _RSC_TABLE_PRU_H_
+
+#include <stddef.h>
+#include <rsc_types.h>
+#include "pru_virtio_ids.h"
+
+/*
+ * Sizes of the virtqueues (expressed in number of buffers supported,
+ * and must be power of 2)
+ */
+#define PRU_RPMSG_VQ0_SIZE	16
+#define PRU_RPMSG_VQ1_SIZE	16
+
+/*
+ * The feature bitmap for virtio rpmsg
+ */
+#define VIRTIO_RPMSG_F_NS	0		//name service notifications
+
+/* This firmware supports name service notifications as one of its features */
+#define RPMSG_PRU_C0_FEATURES	(1 << VIRTIO_RPMSG_F_NS)
+
+/* Definition for unused interrupts */
+#define HOST_UNUSED		255
+
+/* Mapping sysevts to a channel. Each pair contains a sysevt, channel. */
+struct ch_map pru_intc_map[] = { {18, 3},
+				 {19, 1},
+};
+
+struct my_resource_table {
+	struct resource_table base;
+
+	uint32_t offset[2]; /* Should match 'num' in actual definition */
+
+	/* rpmsg vdev entry */
+	struct fw_rsc_vdev rpmsg_vdev;
+	struct fw_rsc_vdev_vring rpmsg_vring0;
+	struct fw_rsc_vdev_vring rpmsg_vring1;
+
+	/* intc definition */
+	struct fw_rsc_custom pru_ints;
+};
+
+#pragma DATA_SECTION(resourceTable, ".resource_table")
+#pragma RETAIN(resourceTable)
+struct my_resource_table resourceTable = {
+	1,	/* Resource table version: only version 1 is supported by the current driver */
+	2,	/* number of entries in the table */
+	0, 0,	/* reserved, must be zero */
+	/* offsets to entries */
+	{
+		offsetof(struct my_resource_table, rpmsg_vdev),
+		offsetof(struct my_resource_table, pru_ints),
+	},
+
+	/* rpmsg vdev entry */
+	{
+		(uint32_t)TYPE_VDEV,                    //type
+		(uint32_t)VIRTIO_ID_RPMSG,              //id
+		(uint32_t)0,                            //notifyid
+		(uint32_t)RPMSG_PRU_C0_FEATURES,	//dfeatures
+		(uint32_t)0,                            //gfeatures
+		(uint32_t)0,                            //config_len
+		(uint8_t)0,                             //status
+		(uint8_t)2,                             //num_of_vrings, only two is supported
+		{ (uint8_t)0, (uint8_t)0 },             //reserved
+		/* no config data */
+	},
+	/* the two vrings */
+	{
+		0,                      //da, will be populated by host, can't pass it in
+		16,                     //align (bytes),
+		PRU_RPMSG_VQ0_SIZE,     //num of descriptors
+		0,                      //notifyid, will be populated, can't pass right now
+		0                       //reserved
+	},
+	{
+		0,                      //da, will be populated by host, can't pass it in
+		16,                     //align (bytes),
+		PRU_RPMSG_VQ1_SIZE,     //num of descriptors
+		0,                      //notifyid, will be populated, can't pass right now
+		0                       //reserved
+	},
+
+	{
+		TYPE_CUSTOM, TYPE_PRU_INTS,
+		sizeof(struct fw_rsc_custom_ints),
+		{ /* PRU_INTS version */
+			0x0000,
+			/* Channel-to-host mapping, 255 for unused */
+			HOST_UNUSED, 1, HOST_UNUSED, 3, HOST_UNUSED,
+			HOST_UNUSED, HOST_UNUSED, HOST_UNUSED, HOST_UNUSED, HOST_UNUSED,
+			/* Number of evts being mapped to channels */
+			(sizeof(pru_intc_map) / sizeof(struct ch_map)),
+			/* Pointer to the structure containing mapped events */
+			pru_intc_map,
+		},
+	},
+};
+
+#endif /* _RSC_TABLE_PRU_H_ */
diff --git a/pru-cookbook/common/resource_table_empty.h b/pru-cookbook/common/resource_table_empty.h
new file mode 100644
index 0000000000000000000000000000000000000000..07e97d9b383c9d937d4b55e705024d6c28dc748a
--- /dev/null
+++ b/pru-cookbook/common/resource_table_empty.h
@@ -0,0 +1,39 @@
+/*
+ *  ======== resource_table_empty.h ========
+ *
+ *  Define the resource table entries for all PRU cores. This will be
+ *  incorporated into corresponding base images, and used by the remoteproc
+ *  on the host-side to allocated/reserve resources.  Note the remoteproc
+ *  driver requires that all PRU firmware be built with a resource table.
+ *
+ *  This file contains an empty resource table.  It can be used either as:
+ *
+ *        1) A template, or
+ *        2) As-is if a PRU application does not need to configure PRU_INTC
+ *                  or interact with the rpmsg driver
+ *
+ */
+
+#ifndef _RSC_TABLE_PRU_H_
+#define _RSC_TABLE_PRU_H_
+
+#include <stddef.h>
+#include <rsc_types.h>
+
+struct my_resource_table {
+	struct resource_table base;
+
+	uint32_t offset[1]; /* Should match 'num' in actual definition */
+};
+
+#pragma DATA_SECTION(pru_remoteproc_ResourceTable, ".resource_table")
+#pragma RETAIN(pru_remoteproc_ResourceTable)
+struct my_resource_table pru_remoteproc_ResourceTable = {
+	1,	/* we're the first version that implements this */
+	0,	/* number of entries in the table */
+	0, 0,	/* reserved, must be zero */
+	0,	/* offset[0] */
+};
+
+#endif /* _RSC_TABLE_PRU_H_ */
+
diff --git a/pru-cookbook/common/write_init_pins.sh b/pru-cookbook/common/write_init_pins.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f52082365a8b2a72a6c30d39938077bd9addf741
--- /dev/null
+++ b/pru-cookbook/common/write_init_pins.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+init_pins=$(readelf -x .init_pins $1 | grep 0x000 | cut -d' ' -f4-7 | xxd -r -p | tr '\0' '\n' | paste - -)
+while read -a line; do
+    if [ ${#line[@]} == 2 ]; then
+        echo writing \"${line[1]}\" to \"${line[0]}\"
+        echo ${line[1]} > ${line[0]}
+        sleep 0.1
+    fi
+done <<< "$init_pins"
diff --git a/pru-cookbook/index.rst b/pru-cookbook/index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..981f2fb27405e0a3f32ceceab1cd7de890745413
--- /dev/null
+++ b/pru-cookbook/index.rst
@@ -0,0 +1,27 @@
+.. _pru-cookbook-home:
+
+PRU Cookbook
+#############
+
+.. admonition:: Contributors
+   
+   - Author: `Mark A. Yoder <Mark.A.Yoder@Rose-Hulman.edu>`_
+   - Book revision: v2.0 beta
+
+Outline
+
+A cookbook for programming the PRUs in C using remoteproc and 
+compiling on the Beagle
+
+.. toctree::
+   :maxdepth: 1
+
+   01case/case.rst
+   02start/start.rst
+   03details/details.rst
+   04debug/debug.rst
+   05blocks/blocks.rst
+   06io/io.rst
+   07more/more.rst
+   08ai/ai.rst
+   projects.rst
\ No newline at end of file
diff --git a/pru-cookbook/projects.rst b/pru-cookbook/projects.rst
new file mode 100644
index 0000000000000000000000000000000000000000..39263b91e03c611604c1e60d416f92e1db44e1b3
--- /dev/null
+++ b/pru-cookbook/projects.rst
@@ -0,0 +1,311 @@
+.. _pru-cookbook-projects:
+
+PRU Projects
+##############
+
+Users of TI processors with PRU-ICSS have created application for many different uses.
+A list of a few are shared below. For additional support resources, software and 
+documentation visit the PRU-ICSS wiki.
+
+PRU projects
+~~~~~~~~~~~~~~
+
+.. dropdown:: **LEDscape** 
+    :open:
+
+    **Description:** BeagleBone Black cape and firmware for driving a large number of WS281x LED strips.
+
+    **Type:** Code Library Documentation and example projects.
+
+    **References:**
+        * https://github.com/osresearch/LEDscape http://trmm.net/LEDscape
+
+.. dropdown:: **LDGraphy**
+    :open:
+
+    **Description:** Laser direct lithography for printing PCBs.
+
+    **Type:** Code Library and example project.
+
+    **References:**
+        * https://github.com/hzeller/ldgraphy/blob/master/README.md
+
+.. dropdown:: **PRdUino**
+    :open:
+    
+    **Description:** This is a port of the Energia platform based on the Arduino framework allowing you to use Arduino software libraries on PRU.
+    
+    **Type:** Code Library
+    
+    **References:**
+        * https://github.com/lucas-ti/PRdUino
+
+.. dropdown:: **DMX Lighting**
+    :open:
+
+    **Description:** Controlling professional lighting systems
+    
+    **Type:** Project Tutorial Code Library
+    
+    **References:**
+        * http://beagleboard.org/CapeContest/entries/BeagleBone+DMX+Cape/
+        * http://blog.boxysean.com/2012/08/12/first-steps-with-the-beaglebone-pru/
+        * https://github.com/boxysean/beaglebone-DMX
+
+.. dropdown:: **Interacto**
+    :open:
+
+    **Description:**  A cape making BeagleBone interactive with a triple-axis accelerometer, gyroscope 
+    and magnetometer plus a 640 x 480/30 fps camera.  All sensors are digital and communicate via I²C 
+    to the BeagleBone. The camera frames are captured using the PRU-ICSS. The sensors on this cape  
+    give hobbyists and students a starting point to easily build robots and flying drones.
+    
+    **Type:** Project 1 Project 2 Code Library
+    
+    **References:**
+        * http://beagleboard.org/CapeContest/entries/Interacto/
+        * http://www.hitchhikeree.org/beaglebone_capes/interacto/
+        * https://github.com/cclark2/interacto_bbone_cape
+
+.. dropdown:: **Replicape: 3D Printer**
+    :open:
+
+    **Description:**  Replicape is a high end 3D-printer electronics package in the form of a Cape 
+    that can be placed on a BeagleBone Black. It has five high power stepper motors with cool running 
+    MosFets and it has been designed to fit in small spaces without active cooling. For a Replicape 
+    Daemon that processes G-code, see the Redeem Project
+    
+    **Type:** Project Code Library
+    
+    **References:**
+        * http://www.thing-printer.com/product/replicape/
+        * https://bitbucket.org/intelligentagent/replicape/
+
+.. dropdown:: **PyPRUSS: Python Library**
+    :open:
+
+    **Description:**  PyPRUSS is a Python library for programming the PRUs on BeagleBone (Black)
+    
+    **Type:** Code Library
+
+    **References:**
+        http://hipstercircuits.com/pypruss-a-simple-pru-python-binding-for-beaglebone/
+
+.. dropdown:: **Geiger**
+    :open:
+
+    **Description:** The Geiger Cape, created by Matt Ranostay, is a design that measures radiation counts 
+    from background and test sources by utilising multiple Geiger tubes. The cape can be used to detect 
+    low-level radiation, which is needed in certain industries such as security and medical.
+    
+    **Type:** Project 1 Project 2 Code Library
+    
+    **References:**
+        * http://beagleboard.org/CapeContest/entries/Geiger+Cape/
+        * http://elinux.org/BeagleBone/GeigerCapePrototype
+        * https://github.com/mranostay/beaglebone-telemetry-presentation
+
+.. dropdown:: **Servo Controller Foosball Table**
+    :open:
+
+    **Description:**  Used for ball tracking and motor control
+    
+    **Type:** Project Tutorial Code Library
+    
+    **References:**
+        * http://www.element14.com/community/community/knode/single-board_computers/next-gen_beaglebone/blog/2013/07/17/hackerspace-challenge--leeds-only-pru-can-make-the-leds-bright
+        * https://docs.google.com/spreadsheet/pub?key=0AmI_ryMKXUGJdDQ3LXB4X3VBWlpxQTFWbGh6RGJHUEE&output=html
+        * https://github.com/pbrook/pypruss
+
+.. dropdown:: **Imaging with connected camera**
+    :open:
+
+    **Description:**  Low resolution imaging ideal for machine vision use-cases, robotics and movement detection
+    
+    **Type:** Project Code Library
+    
+    **References:**
+        * http://www.element14.com/community/community/knode/single-board_computers/next-gen_beaglebone/blog/2013/08/18/bbb--imaging-with-a-pru-connected-camera
+
+.. dropdown:: **Computer Numerical Control (CNC) Translator**
+    :open:
+
+    **Description:** Smooth stepper motor control; real embedded version of LinuxCNC
+    
+    **Type:** Tutorial Tutorial
+    
+    **References:**
+        * http://www.buildlog.net/blog/2013/09/cnc-translator-for-beaglebone/ http://bb-lcnc.blogspot.com/p/machinekit_16.html
+
+.. dropdown:: **Robotic Control**
+    :open:
+
+    **Description:** Chubby SpiderBot
+    
+    **Type:** Project Code Library Project Reference
+
+    **References:**
+        * http://www.youtube.com/watch?v=dEes9k7-DYY
+        * https://github.com/cagdasc/Chubby1_v1
+        * http://www.youtube.com/watch?v=JXyewd98e9Q
+        * http://www.ti.com/lit/wp/spry235/spry235.pdf
+
+.. dropdown:: **Software UART**
+    :open:
+
+    **Description:** Soft-UART implementation on the PRU of AM335x    
+
+    **Type:** Code Library Reference
+    
+    **References:**
+        * http://processors.wiki.ti.com/index.php/Soft-UART_Implementation_on_AM335X_PRU_-_Software_Users_Guide
+
+.. dropdown:: **Deviant LCD**
+    :open:
+
+    **Description:** PRU bit-banged LCD interface @ 240x320
+
+    **Type:** Project Code Library
+
+    **References:**
+        * http://www.beagleboard.org/CapeContest/entries/DeviantLCD/
+        * https://github.com/cclark2/deviantlcd_bbone_cape
+
+.. dropdown:: **Nixie tube interface**
+    :open:
+    
+    **Description:**
+    
+    **Type:** Code Library
+    
+    **References:**
+        * https://github.com/mranostay/beagle-nixie
+
+.. dropdown:: **Thermal imaging camera**
+    :open:
+    
+    **Description:** Thermal camera using Beaglebone Black, a small LCD, and a thermal array sensor    
+
+    **Type:** Project Code Library
+
+    **References:**
+        * https://element14.com/community/community/knode/single-board_computers/next-gen_beaglebone/blog/2013/06/07/bbb--building-a-thermal-imaging-camera
+
+.. dropdown:: **Sine wave generator using PWMs**
+    :open:
+
+    **Description:**  Simulation of a pulse width modulation
+
+    **Type:** Project Reference Code Library
+
+    **References:**
+        * http://elinux.org/ECE497_BeagleBone_PRU
+        * https://github.com/millerap/AM335x_PRU_BeagleBone
+
+.. dropdown:: **Emulated memory interface**
+    :open:
+    
+    **Description:** ABX loads amovie into the Beaglebone's memory and then launches the memory emulator 
+    on the PRU sub-processor of the Beaglebone's ARM AM335x
+    
+    **Type:** Project
+
+    **References:**
+        * https://github.com/lybrown/abx
+
+.. dropdown:: **6502 memory interface**
+    :open:
+    
+    **Description:**  System permitting communication between Linux and 6502 processor    
+
+    **Type:** Project Code Library
+    
+    **References:**
+        * http://elinux.org/images/a/ac/What's_Old_Is_New-_A_6502-based_Remote_Processor.pdf
+        * https://github.com/lybrown/abx
+
+.. dropdown:: **JTAG/Debug**
+    :open:
+    
+    **Description:** Investigating the fastest way to program using JTAG and provide 
+    for debugging facilities built into the Beaglebone.
+
+    **Type:** Project
+    
+    **References:**
+        * http://beagleboard.org/project/PRUJTAG/
+
+.. dropdown:: **High Speed Data Acquistion**
+    :open:
+    
+    **Description:** Reading data at high speeds
+
+    **Type:** Reference
+    
+    **References:**
+        * http://www.element14.com/community/community/knode/single-board_computers/next-gen_beaglebone/blog/2013/08/04/bbb--high-speed-data-acquisition-and-web-based-ui
+
+.. dropdown:: **Prufh (PRU Forth)**
+    :open:
+    
+    **Description:** Forth Programming Language and Compiler. It consists of a compiler, 
+    the forth system itself, and anoptional program for loading and communicating with the forth code proper.
+    
+    **Type:**  Compiler
+    
+    **References:**
+        * https://github.com/biocode3D/prufh
+
+.. dropdown:: **VisualPRU**
+    :open:
+    
+    **Description:** VisualPRU is a minimal browser-based editor and debugger for the Beaglebone PRUs. 
+    The app runs from a local server on the Beaglebone.
+    
+    **Type:**  Editor and Debugger
+    
+    **References:**
+        * https://github.com/mmcdan/visualpru
+
+.. dropdown:: **libpruio**
+    :open:
+
+    **Description:** Library for easy configuration and data handling at high speeds. 
+    This library can configure and control the devices from single source (no need for 
+    further overlays or the device tree compiler)
+    
+    **Type:**  Documentation
+    
+    **References:**
+        * http://users.freebasic-portal.de/tjf/Projekte/libpruio/doc/html/index.html
+        * Library http://www.freebasic-portal.de/downloads/fb-on-arm/libpruio-325.html[(German)]
+
+.. dropdown:: **BeagleLogic**
+    :open:
+
+    **Description:** 100MHz 14channel logic analyzer using both PRUs (one to capture and one to transfer the data)
+    
+    **Type:**  Project
+    
+    **References:**
+        * http://beaglelogic.net
+
+.. dropdown:: **BeaglePilot**
+    :open:
+
+    **Description:** Uses PRUs as part of code for a BeagleBone based autopilot
+    
+    **Type:**  Code Library
+    
+    **References:**
+        * https://github.com/BeaglePilot/beaglepilot
+
+.. dropdown:: **PRU Speak**
+    :open:
+
+    **Description:** Implements BotSpeak, a platform independent interpreter for tools like Labview, on the PRUs
+    
+    **Type:**  Code Library
+    
+    **References:**
+        * https://github.com/deepakkarki/pruspeak
\ No newline at end of file