{{EBC3.8}}This page is for the Bone (Black or White) running the 3.8 Kernel. See [[EBC_Exercise_10_Flashing_an_LED_-_xM_WhiteBone]] for the White Bone or xM running 3.2.

The [http://en.wikipedia.org/wiki/Hello_world_program "Hello World"] program is the traditional first program for many classes. Flashing an LED is the embedded equivalent. Here we will explore a few ways to flash and LED on the Beagle and explore General Purpose I/O (gpio) along the way. These calls will be done from the command line of the Beagle, so there is no need for the host computer.

The [http://en.wikipedia.org/wiki/Hello_world_program "Hello World"] program is the traditional first program for many classes. Flashing an LED is the embedded equivalent. Here we will explore a few ways to flash and LED on the Beagle and explore General Purpose I/O (gpio) along the way. These calls will be done from the command line of the Beagle, so there is no need for the host computer.

It's not hard to use the gpio pins to control your own LED. All you need is an LED and a 220&Omega; resistor. Here's a picture of how it's wired. We are just doing the LED at the top of the breadboard for now.

It's not hard to use the gpio pins to control your own LED. All you need is an LED and a 220&Omega; resistor. Here's a picture of how it's wired. We are just doing the LED at the top of the breadboard for now.

Line 85:

Line 87:

[[File:BoneGPIO.png|300px]]

[[File:BoneGPIO.png|300px]]

−

So how do you know where to connect it? The BeagleBone [http://beagleboard.org/static/beaglebone/latest/Docs/Hardware/BONE_SRM.pdf System Reference Manual] has the details. Figure 3 on page 18 of RevA5.01 shows:

+

So how do you know where to connect it? The BeagleBone [https://github.com/CircuitCo/BeagleBone-Black/blob/master/BBB_SRM.pdf?raw=true System Reference Manual] has the details. Figure 45 on page 74 shows:

−

[[File:Beagle Bone.jpg|300px]]

+

[[File:BlackHeaders.jpg]]

−

There at two expansion headers, P8 and P9. Look at the bottom of the left header and you'll see it's labeled '''P9'''. Table 11 on page 59 shows the pinout for P9.

+

There at two expansion headers, P8 and P9. Look at the bottom of the left header and you'll see it's labeled '''P9'''. Table 11 on page 78 shows the pinout for P9.

−

[[File:Bone P9 pinout.jpg|400px]]

+

[[File:HeaderP9.jpg|800px]]

On the first photo above you can see that pin 1 (Ground) is wired to the '''-''' bus and pin 3 (3.3V) is wired to the '''+''' bus. The 220&Omega; resistor is wired to the '''-''' bus and the other end is attached to the negative lead of the LED. The positive lead is attached to pin 12 which, as shown in Table 11, is attached to '''gpio1_28'''. The gpio pins are in banks of 32 each, so to find the gpio number to use on the Beagle, use 1*32+28='''60'''. Here's how you turn it on

On the first photo above you can see that pin 1 (Ground) is wired to the '''-''' bus and pin 3 (3.3V) is wired to the '''+''' bus. The 220&Omega; resistor is wired to the '''-''' bus and the other end is attached to the negative lead of the LED. The positive lead is attached to pin 12 which, as shown in Table 11, is attached to '''gpio1_28'''. The gpio pins are in banks of 32 each, so to find the gpio number to use on the Beagle, use 1*32+28='''60'''. Here's how you turn it on

beagle$ '''cd /sys/class/gpio'''

beagle$ '''cd /sys/class/gpio'''

−

beagle$ '''ls'''

+

beagle$ '''ls -F'''

−

export gpiochip0 gpiochip32 gpiochip64 gpiochip96 unexport

+

export gpiochip0@ gpiochip32@ gpiochip64@ gpiochip96@ unexport

Presently no gpio pins are visible. You need to tell it which pin to export

Presently no gpio pins are visible. You need to tell it which pin to export

Notice '''gpio60''' has appeared. All we need to do is tell it which direction and then turn it on.

Notice '''gpio60''' has appeared. All we need to do is tell it which direction and then turn it on.

Line 112:

Line 114:

Your LED should be on! When you are done you can unexport the pin and it will disappear.

Your LED should be on! When you are done you can unexport the pin and it will disappear.

−

beagle$ cd ..

+

beagle$ '''cd ..'''

beagle$ '''echo 60 > unexport'''

beagle$ '''echo 60 > unexport'''

−

== Reading a switch - bone ==

+

== Reading a switch ==

Now that you have an LED working, wiring in a switch is easy. The picture above shows a push button switch wired in at the bottom of the P9 header. Attach the '''+''' bus to one pole on the switch with a wire. The other end of the switch is attached to pin 42 which is '''gpio0_7'''.

Now that you have an LED working, wiring in a switch is easy. The picture above shows a push button switch wired in at the bottom of the P9 header. Attach the '''+''' bus to one pole on the switch with a wire. The other end of the switch is attached to pin 42 which is '''gpio0_7'''.

Line 132:

Line 134:

Push the pushbutton and see what happens.

Push the pushbutton and see what happens.

−

How can this work without a pulldown resistor? It turns out the Bone has an internal pulldown (and up) resistor that can be software enabled. Try:

+

How can this work without a pulldown resistor? It turns out the Bone has an internal pulldown (and up) resistor that can be software enabled. We'll discuss how when we cover device trees.

−

+

−

beagle$ '''cd /sys/kernel/debug/omap_mux'''

+

−

beagle$ '''ls'''

+

−

ain0 gpmc_ad2 lcd_data3 mii1_txd2

+

−

ain1 gpmc_ad3 lcd_data4 mii1_txd3

+

−

ain2 gpmc_ad4 lcd_data5 mii1_txen

+

−

ain3 gpmc_ad5 lcd_data6 mmc0_clk

+

−

ain4 gpmc_ad6 lcd_data7 mmc0_cmd

+

−

ain5 gpmc_ad7 lcd_data8 mmc0_dat0

+

−

ain6 gpmc_ad8 lcd_data9 mmc0_dat1

+

−

ain7 gpmc_ad9 lcd_hsync mmc0_dat2

+

−

board gpmc_advn_ale lcd_pclk mmc0_dat3

+

−

ecap0_in_pwm0_out gpmc_ben0_cle lcd_vsync rmii1_refclk

+

−

emu0 gpmc_ben1 mcasp0_aclkr spi0_cs0

+

−

emu1 gpmc_clk mcasp0_aclkx spi0_cs1

+

−

gpmc_a0 gpmc_csn0 mcasp0_ahclkr spi0_d0

+

−

gpmc_a1 gpmc_csn1 mcasp0_ahclkx spi0_d1

+

−

gpmc_a10 gpmc_csn2 mcasp0_axr0 spi0_sclk

+

−

gpmc_a11 gpmc_csn3 mcasp0_axr1 uart0_ctsn

+

−

gpmc_a2 gpmc_oen_ren mcasp0_fsr uart0_rtsn

+

−

gpmc_a3 gpmc_wait0 mcasp0_fsx uart0_rxd

+

−

gpmc_a4 gpmc_wen mdio_clk uart0_txd

+

−

gpmc_a5 gpmc_wpn mdio_data uart1_ctsn

+

−

gpmc_a6 i2c0_scl mii1_col uart1_rtsn

+

−

gpmc_a7 i2c0_sda mii1_crs uart1_rxd

+

−

gpmc_a8 lcd_ac_bias_en mii1_rxclk uart1_txd

+

−

gpmc_a9 lcd_data0 mii1_rxd0 usb0_drvvbus

+

−

gpmc_ad0 lcd_data1 mii1_rxd1 usb1_drvvbus

+

−

gpmc_ad1 lcd_data10 mii1_rxd2 vrefn

+

−

gpmc_ad10 lcd_data11 mii1_rxd3 vrefp

+

−

gpmc_ad11 lcd_data12 mii1_rxdv xdma_event_intr0

+

−

gpmc_ad12 lcd_data13 mii1_rxerr xdma_event_intr1

+

−

gpmc_ad13 lcd_data14 mii1_txclk

+

−

gpmc_ad14 lcd_data15 mii1_txd0

+

−

gpmc_ad15 lcd_data2 mii1_txd1

+

−

beagle$ '''ls | wc'''

+

−

125 125 1220

+

−

+

−

Here you will find a list of how all the pin muxes are set. There are some 125 of them!

It's set to be a PULLDOWN. Sectiion 9.2.2.2, Page 877 of the AM335x Technical Reference manual discusses Pull Selection and tells which bits do what. The '''0x0027''' is the code that says which MODE is used and how the pull up/down resistor is set. (There seems to be a mismatch between the manual and the bone. The manual says bit 3 of 0x0027 enables the pull up/down. Bit 3 isn’t set, but the pull down is working.)

* Can you modify the scripts above to read the switch and turn the LED on and off?

* Can you modify the scripts above to read the switch and turn the LED on and off?

−

* Rewire your switch to work with a pullup resistor.

−

== Analog in - bone ==

+

== Assignment: gpio from the shell ==

−

(This is based on [http://www.gigamegablog.com/2012/01/22/beaglebone-coding-101-using-the-serial-and-analog-pins/ this].)

+

=== <span style="color:green;">Measuring a gpio pin on an Oscilloscope</span> ===

−

The bone has eight Analog Inputs. Several are exposed on P9. They are labeled '''AIN''' in table 11 above. How many do you find?

+

Get an oscilloscope so you can measure the output of your gpio pins. Run

−

+

beagle$ '''./togglegpio.sh 60 0.1'''

−

The AIN pins are sampled at 12 bits and 100k samples per second. The input voltage is between 0 and 1.8V. Fortunately, both voltages are available on P9.

+

−

+

−

The photo above shows a small potentiometer wired to the bone. One end goes to the analog ground (pin 34), the other analog 1.8V (pin 32). The wiper is attached to '''AIN5''' which is pin 36.

+

−

+

−

You interact with the analog in much like the gpio, but it appears in a different location. How do you find that location? One approach is the '''find''' command.

+

−

+

−

beagle$ '''find / -name ain5'''

+

−

/sys/devices/platform/omap/tsc/ain5

+

−

/sys/kernel/debug/omap_mux/ain5

+

−

'''^C'''

+

−

+

−

I used '''Ctrl-C''' to interrupt since it already found what I wanted.

+

−

+

−

beagle$ '''cd /sys/devices/platform/tsc'''

+

−

beagle$ '''ls'''

+

−

ain1 ain3 ain5 ain7 driver power uevent

+

−

ain2 ain4 ain6 ain8 modalias subsystem

+

−

+

−

There are the various analog inputs, but watch out. This interface starts numbering at '''1''' and Table 11 starts at '''0''', so to read AIN5 you need to look at '''ain6'''!

+

−

+

−

beagle$ '''cat ain6'''

+

−

1185

+

−

+

−

(Unfortunately the interface doesn't print a RETURN after the value.)

+

−

Change the pot and rerun the cat. What's the min and max value you get? Is it 12 bits?

+

−

+

−

=== Challenge ===

+

−

Rewrite the scripts from before to read an AIN pin and continuously display it's value.

+

−

+

−

== Reading a gpio pin with an Oscilloscope - xM ==

+

−

+

−

You can easily access many of the gpio pins via the Main Expansion Header. Page 107 of the [http://beagleboard.org/static/BBxMSRM_latest.pdf BeagleBoard-xM System Reference Manual] has this figure.

+

−

[[File:MainHeader.png | 750px]]

+

−

+

−

Unfortunately the gpio pins don't appear here. It turns out the processor has more internal I/O lines than it has physical pins. Each physical pin can can be connected to up to 8 internal lines. [[BeagleBoardPinMux]] does a nice job of explaining it all. The big clue is here [[BeagleBoardPinMux#Beagle]] which references Table 22 on page 108 of the -xM [http://beagleboard.org/static/BBSRM_latest.pdf System Reference Manual].

+

−

+

−

[[File:ExpansionSignals.png‎]]

+

−

+

−

Note that gpio130 appears on pin 21 of the Expansion Header. Also note that pins 27 and 28 are ground. Attach your scope probe to these. Now, let's put a signal on the pin.

+

−

+

−

beagle$ '''cd /sys/class/gpio'''

+

−

beagle$ '''ls -F'''

+

−

export gpiochip128@ gpiochip192@ gpiochip64@ unexport

+

−

gpiochip0@ gpiochip160@ gpiochip32@ gpiochip96@

+

−

+

−

Notice there is no folder for gpio130. Create it with:

+

−

+

−

beagle$ '''echo 130 > export'''

+

−

beagle$ '''ls -F'''

+

−

export gpiochip0@ gpiochip160@ gpiochip32@ gpiochip96@

+

−

gpio130@ gpiochip128@ gpiochip192@ gpiochip64@ unexport

+

−

+

−

Update your exercises folder and cd to gpio directory.

+

−

+

−

beagle$ '''cd'''

+

−

beagle$ '''cd exercises/gpio'''

+

−

beagle$ '''git pull'''

+

−

beagle$ '''gedit togglegpio.sh'''

+

−

+

−

Can you tell what the program is doing? Try running it:

+

−

+

−

beagle$ '''togglegpio 130 0.05'''

+

−

+

−

Note that if you are the root user (which is the default case for Angstrom), you will have to type the following command:

+

−

+

−

beagle$ '''./togglegpio 130 0.05'''

+

−

+

−

The first argument tells which gpio port to toggle, the second tells how long to delay between toggling. In this example 0.05 s is 50 ms, which should give a period around 100ms. Measure the signal on an oscilloscope.

# Try launching something like '''mplayer'''. How stable is the period?

# Try launching something like '''mplayer'''. How stable is the period?

−

# Try cleaning up togglegpio and removing unneeded lines. Does it impact the period?

+

# Try cleaning up togglegpio.sh and removing unneeded lines. Does it impact the period?

# togglegpio uses bash (first line in file). Try using sh. Is the period shorter?

# togglegpio uses bash (first line in file). Try using sh. Is the period shorter?

# What's the shortest period you can get?

# What's the shortest period you can get?

Line 297:

Line 163:

=== Toggling the LEDs ===

=== Toggling the LEDs ===

−

Modify togglegpio (call it toggleLED) to toggle the LEDs. Can you get the LED to appear to dim by changing the duty cycle of the toggling?

+

Modify togglegpio.sh (call it toggleLED) to toggle the on-board LEDs. Can you get the LED to appear to dim by changing the duty cycle of the toggling?

−

+

−

=== User Button to gpio 130 ===

+

−

+

−

Write a shell script that reads the User Button and outputs it value on gpio pin 130.

+

=== Count the User Button Presses ===

=== Count the User Button Presses ===

−

Write a shell script that displays a count of the number of times the User Button has been pressed.

+

Write a shell script that displays a count of the number of times the Button has been pressed.

−

+

−

=== Copy gpio 130 to gpio 131 ===

+

−

+

−

Write a shell script that copies the value of gpio pin 130 to gpio pin 131. How much CPU time does it take? What's the delay from the time the input changes until the output changes? How constant is the delay?

+

−

+

−

== Additional Exercises ==

+

−

+

−

=== Reading the Keyboard and Mouse ===

+

−

Try this:

+

−

+

−

beagle$ '''cd /sys/class/input'''

+

−

beagle$ '''ls -F'''

+

−

beagle$ '''evtest /dev/input/event2'''

+

−

Hit ctrl-C to stop

+

−

+

−

Now move your mouse around, or try you keyboard. My mouse is plugged into the bottom left USB port and event2 responds to it. Where do your keyboard and mouse appear?

+

−

+

−

=== Reading the User Button ===

+

−

('''Note''': This may not work on some versions of the OS. In these versions another program is controlling the gpio port that the User button is attached to.)

+

−

+

−

The Beagle has a couple of push buttons. One reboots the whole board. Use with care. One is for you to use, it's to the right of the Reset button, between the two stacks of USB ports.

+

−

[[File:BeagleUserButton.png]]

+

−

+

−

It's attached to gpio port 4. You can read it via:

+

−

+

−

beagle$ '''cd /sys/class/gpio'''

+

−

beagle$ '''ls -F'''

+

−

export gpio133@ gpio137@ gpio141@ gpiochip160@ gpiochip96@

+

−

gpio130@ gpio134@ gpio138@ gpio162@ gpiochip192@ unexport

+

−

gpio131@ gpio135@ gpio139@ gpiochip0@ gpiochip32@

+

−

gpio132@ gpio136@ gpio140@ gpiochip128@ gpiochip64@

+

−

+

−

Notice there is no gpio4. Here's how you can create it, set it to an input port and read its value:

+

−

+

−

beagle$ '''echo 4 > export'''

+

−

beagle$ '''ls'''

+

−

beagle$ '''cd gpio4'''

+

−

beagle$ '''echo in > direction'''

+

−

beagle$ '''cat value'''

+

−

+

−

Try holding down the switch and doing <code>cat value</code> again. Does the value change? There's a shell script called '''readgpio''' that repeatedly reads the switch.

+

−

beagle$ '''readgpio 4'''

+

=== Copy gpio 7 to gpio 60===

−

Try pushing the switch. Does it work? Hit ctrl-C to stop. Look at readgpio. How does it work?

+

Write a shell script that copies the value of gpio pin 7 (your switch) to gpio pin 60 (Your LED). How much CPU time does it take? What's the delay from the time the input changes until the output changes? How constant is the delay?

−

beagle$ '''which readgpio'''

+

You may need to get a function generator and set it to a square wave (0 to 3.3V) and attach it to pin 7 and attached an oscilloscope to pin 60.

The "Hello World" program is the traditional first program for many classes. Flashing an LED is the embedded equivalent. Here we will explore a few ways to flash and LED on the Beagle and explore General Purpose I/O (gpio) along the way. These calls will be done from the command line of the Beagle, so there is no need for the host computer.

gpio via the Shell Command Line and sysfs

The easiest way to do general purpose I/O (gpio) on the Beagle is through a terminal window and a shell prompt. In Linux, almost everything is treated as a file, even things that aren't files. In our class we'll use a virtual file system called sysfs. sysfs exposes the drivers for the hardware so you get easily use them.

Adding your own LED

It's not hard to use the gpio pins to control your own LED. All you need is an LED and a 220Ω resistor. Here's a picture of how it's wired. We are just doing the LED at the top of the breadboard for now.

So how do you know where to connect it? The BeagleBone System Reference Manual has the details. Figure 45 on page 74 shows:

There at two expansion headers, P8 and P9. Look at the bottom of the left header and you'll see it's labeled P9. Table 11 on page 78 shows the pinout for P9.

On the first photo above you can see that pin 1 (Ground) is wired to the - bus and pin 3 (3.3V) is wired to the + bus. The 220Ω resistor is wired to the - bus and the other end is attached to the negative lead of the LED. The positive lead is attached to pin 12 which, as shown in Table 11, is attached to gpio1_28. The gpio pins are in banks of 32 each, so to find the gpio number to use on the Beagle, use 1*32+28=60. Here's how you turn it on

Notice gpio60 has appeared. All we need to do is tell it which direction and then turn it on.

beagle$ cd gpio60
beagle$ echo out > direction
beagle$ echo 1 > value

Your LED should be on! When you are done you can unexport the pin and it will disappear.

beagle$ cd ..
beagle$ echo 60 > unexport

Reading a switch

Now that you have an LED working, wiring in a switch is easy. The picture above shows a push button switch wired in at the bottom of the P9 header. Attach the + bus to one pole on the switch with a wire. The other end of the switch is attached to pin 42 which is gpio0_7.

Based on what you saw above, show how to read the switch.

Once you have the switch and LED working you can use the following scripts to play with them.

beagle$ cd ~/exercises/gpio
beagle$ ./togglegpio.sh 60 0.1

The LED should be blinking on and off.

beagle$ ./readgpio.sh 7

Push the pushbutton and see what happens.

How can this work without a pulldown resistor? It turns out the Bone has an internal pulldown (and up) resistor that can be software enabled. We'll discuss how when we cover device trees.

Challenge

Can you modify the scripts above to read the switch and turn the LED on and off?

Assignment: gpio from the shell

Measuring a gpio pin on an Oscilloscope

Get an oscilloscope so you can measure the output of your gpio pins. Run

beagle$ ./togglegpio.sh 60 0.1

and answer the following questions about gpio measurements.

What's the min and max voltage?

What period is it?

How close is it to 100ms?

Why do they differ?

Run htop and see how much processor you are using.

Try different values for the sleep time (2nd argument). What's the shortest period you can get? Make a table of the values you try and the corresponding period and processor usage.

How stable is the period?

Try launching something like mplayer. How stable is the period?

Try cleaning up togglegpio.sh and removing unneeded lines. Does it impact the period?

togglegpio uses bash (first line in file). Try using sh. Is the period shorter?

What's the shortest period you can get?

Toggling the LEDs

Modify togglegpio.sh (call it toggleLED) to toggle the on-board LEDs. Can you get the LED to appear to dim by changing the duty cycle of the toggling?

Count the User Button Presses

Write a shell script that displays a count of the number of times the Button has been pressed.

Copy gpio 7 to gpio 60

Write a shell script that copies the value of gpio pin 7 (your switch) to gpio pin 60 (Your LED). How much CPU time does it take? What's the delay from the time the input changes until the output changes? How constant is the delay?

You may need to get a function generator and set it to a square wave (0 to 3.3V) and attach it to pin 7 and attached an oscilloscope to pin 60.

Resources

Here is wh1ts article on flashing an LED. It is referenced in the readgpio file that comes on the Beagle.