Forum | Documentation | Website | Blog

Skip to content
Snippets Groups Projects
Commit 4b27daa5 authored by Deepak Khatri's avatar Deepak Khatri :dog:
Browse files

Update PRU Cookbook

parent 526e8e6d
Branches
Tags
No related merge requests found
VERSION_MAJOR = 0
VERSION_MINOR = 0
PATCHLEVEL = 8
VERSION_TWEAK = 1
EXTRAVERSION = beta
VERSION_TWEAK = 2
EXTRAVERSION =
This diff is collapsed.
......@@ -13,15 +13,15 @@ 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>`_,
......@@ -41,13 +41,12 @@ member of the open hardware Beagle family.
.. _start_black:
BeagleBone Black
~~~~~~~~~~~~~~~~~
.. figure:: figures/product_detail_black_sm.jpg
:align: center
:alt: BeableBone Black
BeagleBone Black
The Black has:
* AM335x 1GHz ARM® Cortex-A8 processor
......@@ -71,13 +70,12 @@ The `Blue <http://beagleboard.org/blue>`_ is a good choice if you are doing robo
.. _start_blue:
BeagleBone Blue
~~~~~~~~~~~~~~~~
.. figure:: figures/beagle-blue.png
:align: center
:alt: BeagleBone Blue
BeagleBone Blue
The Blue has everything the Black has except it has no Ethernet or HDMI.
But it also has:
......@@ -94,13 +92,12 @@ https://www.renaissancerobotics.com/eduMIP.html[EduMIP kit] as shown in
.. _start_edumip:
BeagleBone Blue EduMIP Kit
~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. figure:: figures/edumip.png
:align: center
:alt: BeagleBone Blue EduMIP Kit
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>`_.
......@@ -114,13 +111,12 @@ compatible with the other Beagles.
.. _start_pocket:
PocketBeagle
~~~~~~~~~~~~~
.. figure:: figures/PocketBeagle-size-compare-small.jpg
:align: center
:alt: PocketBeagle
PocketBeagle
The Pocket is based on the same processor as the Black and Blue and has:
* 8 analog inputs
......@@ -130,19 +126,18 @@ The Pocket is based on the same processor as the Black and Blue and has:
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
BeagleBone AI
The AI has:
* Dual Arm® Cortex®-A15 microprocessor subsystem
......@@ -163,7 +158,7 @@ The AI has:
Installing the Latest OS on Your Bone
======================================
****************************************
Problem
---------
......@@ -185,17 +180,16 @@ 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
Latest Debian images
It contains all the packages we'll need.
Flashing a Micro SD Card
=========================
*************************
Problem
---------
......@@ -215,17 +209,16 @@ button and wait for it to finish.
.. _start_etcher:
Etcher
~~~~~~~~
.. figure:: figures/etcher.png
:align: center
:alt: Ether
Etcher
Once the SD is flashed, insert it in the Beagle and power it up.
Cloud9 IDE
===========
***********
Problem
------------
......@@ -241,13 +234,12 @@ a web-based intergrated development environment (IDE) as shown in
.. _start_c9:
Cloud9 IDE
~~~~~~~~~~~~
.. figure:: figures/c9.png
:align: center
:alt: The Cloud9 IDE
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*
......@@ -255,13 +247,12 @@ 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
Cloud9 Showing Home files
If you want to edit files beyond your home directory you can link to the root file system by:
......@@ -277,7 +268,7 @@ If you want to edit files beyond your home directory you can link to the root fi
Now you can reach all the files from Cloud9.
Getting Example Code
====================
**********************
Problem
---------
......@@ -302,7 +293,8 @@ it on your Beagle and then look in the *docs* directory.
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.
Each chapter has its own directory and within that directory
is a **code** directory that has all of the code.
.. code-block::bash
......@@ -313,7 +305,7 @@ Each chapter has its own directory and within that directory is a **code** direc
Go and explore.
Blinking an LED
=================
*****************
Problem
---------
......@@ -330,8 +322,9 @@ is some code that blinks the ``USR3`` LED ten times using the PRU.
.. _start_hello:
hello.pru0.c
~~~~~~~~~~~~~
.. literalinclude:: code/hello.pru0.c
:caption: hello.pru0.c
:linenos:
:download:`hello.pru0.c <code/hello.pru0.c>`
......
......@@ -20,7 +20,7 @@ compile code and also start and stop the PRUs.
Getting Example Code
=====================
**********************
Problem
---------
......@@ -44,8 +44,7 @@ It's all on a GitHub repository.
Compiling with clpru and lnkpru
================================
********************************
Problem
---------
......@@ -64,6 +63,7 @@ They are called ``clpru`` and ``lnkpru``. Do the following to see if ``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.
......@@ -83,6 +83,7 @@ In fact there are PRU versions of many of the standard code generation tools.
code tools
~~~~~~~~~~~
.. code-block:: bash
bone$ ls /usr/bin/*pru
......@@ -95,7 +96,7 @@ code tools
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
---------
......@@ -130,7 +131,7 @@ Uncomment the ``uboot_overlay`` line as shown and then reboot.
0 lrwxrwxrwx 1 root root 33 Jul 29 16:12 pruss-core1 -> /sys/class/remoteproc/remoteproc2
Compiling and Running
======================
**********************
Problem
---------
......@@ -203,6 +204,7 @@ You can override the ``TARGET`` on the command line.
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
......@@ -211,8 +213,10 @@ You can also specify them when running ``make``.
The setup file also contains instructions to figure out which Beagle you are running
and then configure the pins acordingly.
setup.sh
~~~~~~~~~
.. literalinclude:: code/gpio_setup.sh
:caption: gpio_setup.sh
:linenos:
:download:`gpio_setup.sh <code/gpio_setup.sh>`
......@@ -240,7 +244,7 @@ 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
---------
......@@ -278,7 +282,7 @@ If you want to control the other PRU use:
.. _details_makefile:
The Standard Makefile
=====================
**********************
Problem
---------
......@@ -299,8 +303,9 @@ 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
~~~~~~~~~~~~~~~
.. literalinclude:: code/Makefile
:caption: Local Makefile
:linenos:
:download:`Makefile <code/Makefile>`
......@@ -312,7 +317,7 @@ Fortunately you shouldn't have to modify the `Makefile`.
.. _detail_linker:
The Linker Command File - am335x_pru.cmd
=========================================
******************************************
Problem
......@@ -328,8 +333,10 @@ 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
~~~~~~~~~~~~~~~~
.. literalinclude:: code/am335x_pru.cmd
:caption: am335x_pru.cmd
:linenos:
:download:`am335x_pru.cmd <code/am335x_pru.cmd>`
......@@ -340,44 +347,44 @@ 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 |
+-----+------------------------------------------------------------------------------------------------+
|Line | Explanation |
+=====+================================================================================================+
|16 | This is where the instructions are stored. See page 206 of the |
| | `AM335x Technical Reference Manual rev. P <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. |
+-----+-----------------------------------------------------------------------------------------+
| | 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
---------
......@@ -441,7 +448,7 @@ Therefore you copy your ``.out`` file to ``/lib/firmware/am335x-pru0-fw``.
.. _details_configure_servos:
Configuring Pins for Controlling Servos
========================================
****************************************
Problem
---------
......@@ -455,8 +462,10 @@ 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
~~~~~~~~~~~~~~~~
.. literalinclude:: code/servos_setup.sh
:caption: servos_setup.sh
:linenos:
:download:`servos_setup.sh <code/servos_setup.sh>`
......@@ -470,7 +479,7 @@ assigns ``pins`` a list of pins to configure. Then the last part of the script
.. _details_configure_encoders:
Configuring Pins for Controlling Encoders
==========================================
*********************************************
Problem
---------
......@@ -484,7 +493,9 @@ 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
.. literalinclude:: code/encoder_setup.sh
:caption: encoder_setup.sh
:linenos:
:download:`encoder_setup.sh <code/encoder_setup.sh>`
......
......@@ -13,7 +13,7 @@ Finally, using one of the UARTS to send debugging information out a serial port
is shown.
Debugging via an LED
=====================
**********************
Problem
---------
......@@ -28,17 +28,16 @@ flash. :ref:`debug_LED` shows an LED attached to pin P9_29 of the BeagleBone Bla
.. _debug_LED:
LED used for debugging P9_29
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. figure:: figures/LED_bb.png
:align: center
:alt: LED used for debugging P9_29
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
......@@ -50,7 +49,7 @@ RAM is discussed in :ref:`debug_prudebug`.
.. _dmesg_hw:
dmesg Hw
=========
***********
Problem
---------
......@@ -60,16 +59,16 @@ 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
......@@ -83,7 +82,7 @@ to my code.
.. _debug_prudebug:
prudebug - A Simple Debugger for the PRU
=========================================
******************************************
Problem
---------
......@@ -200,10 +199,7 @@ restart back at the beginning.
The ``dd`` command dumps the memory. Keep in mind the following.
Important memory locations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. table::
.. table:: Important memory locations
+-------+---------------------------------------------------------------------------+
|Address|Contents |
......@@ -279,7 +275,7 @@ of how you can control where your vaiables are stored in memory.
UART
======
******
Problem
---------
......@@ -304,37 +300,32 @@ you can get such a cable from places such as
.. _debug_ftdi:
FTDI cable
~~~~~~~~~~~
.. figure:: figures/FTDIcable.jpg
:align: center
:alt: FTDI cable
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
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::
.. table:: Wriing for FTDI cable to Beagle
+--------+------+---------+-------------+--------+------+---------+
|FTDI pin|Color |Black pin|AI 1 pin |AI 2 pin|Pocket|Function |
......@@ -348,15 +339,14 @@ Wriing for FTDI cable to Beagle
.. _debug_ftdi_pins:
FTDI to BB Black
~~~~~~~~~~~~~~~~~
.. figure:: figures/FTDIhookup_bb.png
:align: center
:alt: FTDI to BB Black
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
......@@ -375,7 +365,7 @@ Once an ENTER appears the string is sent back.
You need to set the pin muxes.
config-pin
~~~~~~~~~~~
-----------
.. code-block:: bash
......@@ -402,15 +392,16 @@ For example
.. * TODO - Add code for Blue.
uart1.pru1_0.c
~~~~~~~~~~~~~~~
.. literalinclude:: code/uart1.pru1_0.c
:caption: uart1.pru1_0.c
:linenos:
Set the following variables so ``make`` will know what to compile.
:download:`uart1.pru1_0.c <code/uart1.pru1_0.c>`
make
~~~~~
Set the following variables so ``make`` will know what to compile.
.. code-block:: bash
:caption: make
bone$ *make TARGET=uart1.pru0*
/var/lib/cloud9/common/Makefile:29: MODEL=TI_AM335x_BeagleBone_Black,TARGET=uart1.pru0
......@@ -433,19 +424,19 @@ In a terminal window on your host computer run
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
uart1.pru0.c output
Here's the code (``uart1.pru1_0.c``) that does it.
.. _debug_uart1:
uart1.pru1_0.c
~~~~~~~~~~~~~~~
.. literalinclude:: code/uart1.pru1_0.c
:caption: uart1.pru1_0.c
:linenos:
:download:`uart1.pru1_0.c <code/uart1.pru1_0.c>`
......@@ -472,15 +463,16 @@ receive register on the UART.
These simple lines should be enough to place in your code to print out
debugging information.
uart2.pru0.c
~~~~~~~~~~~~
.. literalinclude:: code/uart2.pru0.c
:caption: uart2.pru0.c
:linenos:
If you want to try ``uart2.pru0.c``, run the following:
:download:`uart2.pru0.c <code/uart2.pru0.c>`
make
~~~~~
If you want to try ``uart2.pru0.c``, run the following:
.. code-block:: bash
:caption: make
bone$ *make TARGET=uart2.pru0*
/var/lib/cloud9/common/Makefile:29: MODEL=TI_AM335x_BeagleBone_Black,TARGET=uart2.pru0
......@@ -495,13 +487,12 @@ make
You will see:
uart2.pru0.c output
~~~~~~~~~~~~~~~~~~~~
.. figure:: figures/uart2.pru0.png
:align: center
:alt: uart2.pru0.c output
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.
......@@ -514,8 +505,9 @@ wait for the FIFO to empty, which may cause your code to miss something.
.. _debug_uart2:
uart2.pru1_0.c
~~~~~~~~~~~~~~~
.. literalinclude:: code/uart2.pru1_0.c
:caption: uart2.pru1_0.c
:linenos:
:download:`uart2.pru1_0.c <code/uart2.pru1_0.c>`
......@@ -524,11 +516,12 @@ More complex examples can be built using the principles shown in these examples.
Copyright
==========
copyright.c
~~~~~~~~~~~~~
.. literalinclude:: code/copyright.c
:caption: copyright.c
:linenos:
:download:`copyright.c <code/copyright.c>`
.. rubric:: Footnotes
.. [#debug1] FTDI images are from the BeagleBone Cookbook http://shop.oreilly.com/product/0636920033899.do
.. [#debug1] `FTDI images are from the BeagleBone Cookbook <http://shop.oreilly.com/product/0636920033899.do>`_
This diff is collapsed.
This diff is collapsed.
......@@ -3,9 +3,8 @@
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.
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.
......@@ -14,21 +13,18 @@ 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)
* `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>`_
* `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:
......@@ -36,7 +32,7 @@ config-pin
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,
......@@ -44,10 +40,8 @@ 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
:caption: /boot/uEnv.txt
:linenos:
###Disable auto loading of virtual capes (emmc/video/wireless/adc)
......@@ -65,7 +59,7 @@ Uncomment the lines that correspond to the devices you want to disable and free
Save the file and reboot. You now have access to the ``P8`` pins.
Accessing gpio
================
****************
Problem
--------
......@@ -73,36 +67,38 @@ 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
:ref:`blocks_mapping_bits` 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.
through the **O**\ pen-\ **C**\ ore **P**\ rotocol (OCP) port.
PRU Integration
~~~~~~~~~~~~~~~~~
.. figure:: figures/pruIntegration.png
:align: center
:alt: PRU Integration
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
~~~~~~~~~~~~
.. literalinclude:: code/gpio.pru0.c
:caption: gpio.pru0.c
:linenos:
:download:`gpio.pru0.c <code/gpio.pru0.c>`
This code will toggle ``P9_11`` on and off. Here's the setup file.
setup.sh
~~~~~~~~~
.. literalinclude:: code/setup.sh
:caption: setup.sh
:linenos:
:download:`setup.sh <code/setup.sh>`
......@@ -134,10 +130,8 @@ 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::
.. table:: gpio.pru0.c line-by-line
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
|Line | Explanation |
......@@ -172,30 +166,28 @@ gpio.pru0.c line-by-line
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------+
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)
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
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.
......@@ -206,11 +198,10 @@ 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
--------
......@@ -249,7 +240,7 @@ Check that UIO is running.
You are now ready to run the legacy PRU code.
Converting pasm Assembly Code to clpru
========================================
***************************************
Problem
--------
......@@ -257,7 +248,7 @@ 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>`_
......@@ -265,7 +256,7 @@ 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>`_.
......@@ -22,15 +22,15 @@ Resources
* `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
......@@ -42,28 +42,30 @@ constant. Our new ``delay_cycles`` can take a runtime delay value.
.. _more_delay-test:
delay-test.pru0.c
~~~~~~~~~~~~~~~~~~~
.. literalinclude:: code/delay-test.pru0.c
:caption: delay-test.pru0.c
:linenos:
:download:`code/delay-test.pru0.c <code/delay-test.pru0.c>`
:download:`delay-test.pru0.c <code/delay-test.pru0.c>`
:ref:`more_delay` is the assembly code.
.. _more_delay:
delay.pru0.asm
~~~~~~~~~~~~~~~
.. literalinclude:: code/delay.pru0.asm
:caption: delay.pru0.asm
:linenos:
: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:
and :ref:`more_delay`. If you look in the local ``Makefile`` you'll see:
.. _more_makefile:
Makefile
~~~~~~~~~
.. literalinclude:: code/Makefile
:caption: Makefile
:linenos:
:download:`Makefile <code/Makefile>`
......@@ -102,23 +104,20 @@ 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()
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::
.. table:: Line-by-line of delay.pru0.asm
+-------+-------------------------------------------------------------------------------------------------------+
|Line | Explanation |
......@@ -152,22 +151,23 @@ 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
~~~~~~~~~~~~~~~~~~~
.. literalinclude:: code/delay-test2.pru0.c
:caption: delay-test2.pru0.c
:linenos:
:download:`delay-test2.pru0.c <code/delay-test2.pru0.c>`
......@@ -175,8 +175,9 @@ delay-test2.pru0.c
.. _more_delay2:
delay2.pru0.asm
~~~~~~~~~~~~~~~~~
.. literalinclude:: code/delay2.pru0.asm
:caption: delay2.pru0.asm
:linenos:
:download:`delay2.pru0.asm <code/delay2.pru0.asm>`
......@@ -187,15 +188,15 @@ In this example, line 6 of :ref:`more_test2` `#defines` TEST and line 12 of
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
......@@ -204,23 +205,21 @@ many times the PRU stalled fetching an instruction.
.. _more_cycle:
cycle.pru0.c - Code to count cycles.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. literalinclude:: code/cycle.pru0.c
:caption: cycle.pru0.c - Code to count cycles.
:linenos:
:download:`delay2.pru0.asm <code/cycle.pru0.c>`
:download:`cycle.pru0.c <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::
.. table:: Line-by-line for cycle.pru0.c
+-------+---------------------------------------------------------------------------------------+
|Line | Explanation |
......@@ -244,20 +243,26 @@ You can see where ``cycle`` and ``stall`` are stored by looking into :ref:`more_
.. _more_cycle_list0:
/tmp/cloud9-examples/cycle.pru0.lst Lines 113..119
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. literalinclude:: code/cycle.pru0.lst
:caption: /tmp/cloud9-examples/cycle.pru0.lst Lines 113..119
:lines: 113-119
:lineno-start: 113
:linenos:
:download:`cycle.pru0.lst lines=113..119 <code/cycle.pru0.lst>`
:download:`cycle.pru0.lst <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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. literalinclude:: code/cycle.pru0.lst
:caption: /tmp/cloud9-examples/cycle.pru0.lst Lines 146..152
:lines: 146-152
:lineno-start: 146
:linenos:
:download:`lines=146..152 <code/cycle.pru0.lst>`
:download:`cycle.pru0.lst <code/cycle.pru0.lst>`
The first ``LBBO`` takes the contents of ``r0`` and adds the offset 12 to it and copies 4 bytes
......@@ -298,23 +303,24 @@ If you switch the order of lines 30 and 31 you'll see ``cycle`` is 7 and ``stall
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
~~~~~~~~~~~~
.. literalinclude:: code/xout.pru0.c
:caption: xout.pru0.c
:linenos:
:download:`xout.pru0.c <code/xout.pru0.c>`
......@@ -323,8 +329,9 @@ interupt to PRU 0 and waits for it to send the data.
.. _more_xin:
xin.pru1.c
~~~~~~~~~~~
.. literalinclude:: code/xin.pru1.c
:caption: xin.pru1.c
:linenos:
:download:`xin.pru1.c <code/xin.pru1.c>`
......@@ -373,15 +380,13 @@ Use ``prudebug`` to see registers R5-R10 are transfered from PRU 0 to PRU 1.
Discussion
~~~~~~~~~
-----------
:ref:`more_zout_lines` shows the line-by-line for ``xout.pru0.c``
.. _more_zout_lines:
xout.pru0.c Line-by-line
~~~~~~~~~~~~~~~~~~~~~~~~~
.. table::
.. table:: xout.pru0.c Line-by-line
+-------+---------------------------------------------------------------------------------------------------------+
|Line | Explanation |
......@@ -415,9 +420,7 @@ xout.pru0.c Line-by-line
.. _more_xin_lines:
xin.pru1.c Line-by-line
~~~~~~~~~~~~~~~~~~~~~~~~
.. table::
.. table:: xin.pru1.c Line-by-line
+-------+-----------------------------------------------------------+
|Line | Explanation |
......@@ -435,9 +438,10 @@ xin.pru1.c Line-by-line
If you really need speed, considering using ``pass:[__]xout()`` and ``pass:[__]xin()`` in assembly.
Copyright
----------
==========
copyright.c
~~~~~~~~~~~~~
.. literalinclude:: code/copyright.c
:caption: copyright.c
:linenos:
:download:`copyright.c <code/copyright.c>`
......@@ -18,7 +18,7 @@ Resources
* `BeagleBone AI PRU pins <https://docs.google.com/spreadsheets/d/1dFSBVem86vAUD7MLXvqdS-N0Efi8_g_O1iTqzql8DAo/edit#gid=0>`_
Moving from two to four PRUs
=============================
*****************************
Problem
--------
......@@ -37,21 +37,18 @@ Things to consider when moving to the AI are:
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::
.. table:: Mapping bit positions to pin names
+---+---+---------+-----------+-----------+-------------+
|PRU|Bit|Black pin|AI PRU1 pin|AI PRU2 pin|Pocket pin |
|0 |0 |P9_31 | |P8_44 |P1.36 |
|0 |0 |P9_31 | |P8_44 |P1.36 |
+---+---+---------+-----------+-----------+-------------+
|0 |1 |P9_29 | |P8_41 |P1.33 |
+---+---+---------+-----------+-----------+-------------+
......@@ -67,31 +64,31 @@ Mapping bit positions to pin names
+---+---+---------+-----------+-----------+-------------+
|0 |7 |P9_25 | |P8_36/P8_6 |P1.29 |
+---+---+---------+-----------+-----------+-------------+
|0 |8 | | |P8_34/P8_23| |
|0 |8 | | |P8_34/P8_23| |
+---+---+---------+-----------+-----------+-------------+
|0 |9 | | |P8_35/P8_22| |
|0 |9 | | |P8_35/P8_22| |
+---+---+---------+-----------+-----------+-------------+
|0 |19 | | |P8_33/P8_3 | |
|0 |19 | | |P8_33/P8_3 | |
+---+---+---------+-----------+-----------+-------------+
|0 |11 | | |P8_31/P8_4 | |
|0 |11 | | |P8_31/P8_4 | |
+---+---+---------+-----------+-----------+-------------+
|0 |12 | | |P8_32 | |
|0 |12 | | |P8_32 | |
+---+---+---------+-----------+-----------+-------------+
|0 |13 | | |P8_45 | |
|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 |16 |P9_41(in) P9_26(in)| |P8_27 | |
+---+---+---------+-----------+-----------+-------------+
|0 |17 | |P9_26 |P8_28 | |
|0 |17 | |P9_26 |P8_28 | |
+---+---+---------+-----------+-----------+-------------+
|0 |18 | | |P8_29 | |
|0 |18 | | |P8_29 | |
+---+---+---------+-----------+-----------+-------------+
|0 |19 | | |P8_30 | |
|0 |19 | | |P8_30 | |
+---+---+---------+-----------+-----------+-------------+
|0 |20 | | |P8_46/P8_8 | |
|0 |20 | | |P8_46/P8_8 | |
+---+---+---------+-----------+-----------+-------------+
| | | | | | |
+---+---+---------+-----------+-----------+-------------+
......@@ -127,15 +124,15 @@ Mapping bit positions to pin names
+---+---+---------+-----------+-----------+-------------+
|1 |15 | |*P9_16* |P8_10 |P1.30 |
+---+---+---------+-----------+-----------+-------------+
|1 |16 |P9_26(in)|*P8_15* |P8_7 | |
|1 |16 |P9_26(in)|*P8_15* |P8_7 | |
+---+---+---------+-----------+-----------+-------------+
|1 |17 | |*P8_26* |P8_27 | |
|1 |17 | |*P8_26* |P8_27 | |
+---+---+---------+-----------+-----------+-------------+
|1 |18 | |*P8_16* |P8_45 | |
|1 |18 | |*P8_16* |P8_45 | |
+---+---+---------+-----------+-----------+-------------+
|1 |19 | | |P8_46 | |
|1 |19 | | |P8_46 | |
+---+---+---------+-----------+-----------+-------------+
|1 |19 | | |P8_43 | |
|1 |19 | | |P8_43 | |
+---+---+---------+-----------+-----------+-------------+
The pins in *bold* are already configured as pru pins. See :ref:`ai_config` to
......@@ -145,7 +142,7 @@ configure pins.
.. _ai_config:
Seeing how pins are configured
===============================
*******************************
Problem
--------
......@@ -231,7 +228,7 @@ Five are input pins and four are out.
.. _ai_device_tree:
Configuring pins on the AI via device trees
============================================
********************************************
Problem
--------
......@@ -274,6 +271,7 @@ We see that when ``P9_31a`` is set to ``MODE13`` it will be a PRU **out** pin.
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
......@@ -335,7 +333,7 @@ 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
--------
......@@ -350,7 +348,7 @@ 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
......@@ -359,8 +357,9 @@ the adapted code.
.. _ai_pwm1:
pwm1.pru2_1.c
~~~~~~~~~~~~~~
.. literalinclude:: code/pwm1.pru2_1.c
:caption: pwm1.pru2_1.c
:linenos:
:download:`pwm1.pru2_1.c <code/pwm1.pru2_1.c>`
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment