gpio Success

I’ve taught an embedded class that uses the Beagle a couple of times. I’ve decided this time to add some traditional embedded exercises such as gpio. Here [1] is an exercise that shows how to use sysfs to blink the LED, read the User Button and use gpio pin 130 all via shell commands. It’s based on bits and pieces I’ve pickup from here and there.

Here [2] I show how to do the same via a C program. Also, thanks to the excellent example [4] from the folks at RidRun [3], I have an example of how to use poll() to do an interrupt driven response to a gpio pin. I can copy an input pin to an output pin at about 2.5 KHz and only use about 15% of the CPU.

What do you think. Am I doing these the right way?

I’m thinking of doing the hardware PWM next. What other examples should I include?

–Mark

[1] http://elinux.org/EBC_Exercise_02_Flashing_an_LED

[2] http://elinux.org/EBC_Exercise_03_gpio_Polling_and_Interrupts
[3] http://www.ridgerun.com/
[4] https://www.ridgerun.com/developer/wiki/index.php/How_to_use_GPIO_signals

I’ve taught an embedded class that uses the Beagle a couple of times. I’ve decided this time to add some traditional embedded exercises such as gpio. Here [1] is an exercise that shows how to use sysfs to blink the LED, read the User Button and use gpio pin 130 all via shell commands. It’s based on bits and pieces I’ve pickup from here and there.

Here [2] I show how to do the same via a C program. Also, thanks to the excellent example [4] from the folks at RidRun [3], I have an example of how to use poll() to do an interrupt driven response to a gpio pin. I can copy an input pin to an output pin at about 2.5 KHz and only use about 15% of the CPU.

What do you think. Am I doing these the right way?

At ESC Chicago[5], I gave a presentation on using SYSFS entries to perform GPIO and other operations[6]. The one thing I’d encourage is to point to places where documentation is fundamental and will be updated with the kernel, ie. kernel.org.

The USER button instructions are likely to break soon. It is actually a bit of a bug because typically the USER button is allocated by the gpio-keys driver. It might be good to move that to be a loadable kernel module.

I’m thinking of doing the hardware PWM next. What other examples should I include?

You might look at the incomplete portions of [6]. You might also take a look at what you can demonstrate with the TinCanTools Beacon board as a simpler step than the full-on Trainer board.

You might want to look at what it takes to poll the status of the USER button when that is actually interfaced using the gpio-keys driver. Joel did a simple example to do that[7].

–Mark

[1] http://elinux.org/EBC_Exercise_02_Flashing_an_LED

[2] http://elinux.org/EBC_Exercise_03_gpio_Polling_and_Interrupts
[3] http://www.ridgerun.com/
[4] https://www.ridgerun.com/developer/wiki/index.php/How_to_use_GPIO_signals

[5] http://beagleboard.org/esc
[6] http://www.beagleboard.org/~arago/education/presentations/Learning_Linux_Tops_Down.pdf
[7] https://gitorious.org/~joelf/beagleboard-validation/validation-scripts/blobs/master/flashing/userbutton-pressed.c

I don't think that will help with this problem, a better idea is to teach people about evdev and wire a different button to the expansionport

Is it not reasonable to want to be able to unload this driver? I'd
like to be able to teach people about using the gpio driver events as
well, without needing to have a different kernel.

Certainly teaching people about evdev is needed.

Well, my success has slowed.

I’ve been able to output on gpio130 and see the result on pin 21 of the expansion header. However, when I try the same thing on gpio 146 I don’t see anything on pin 6 of the header. The same is true for gpio 144 and 145 and their corresponding pins. I’ve checked u-boot and board/ti/beagle/beagle.h have all three pins (pads?) set to Mode 4 which is gpio.

Any ideas why I’m not seeing a signal out on this pins. (They all appear at 1.8V and don’t change).

My end goal is to set these pins to Mode 2 so I can use the PWM.

–Mark

koen@dominion:/OE/tmp/u-boot$ grep -n UART2_TX board/ti/beagle/beagle.h
225: MUX_VAL(CP(MCBSP3_CLKX), (IDIS | PTD | DIS | M1)) /*UART2_TX*/\
229: MUX_VAL(CP(UART2_TX), (IEN | PTD | DIS | M4)) /*GPIO_146*/\
390: MUX_VAL(CP(UART2_TX), (IDIS | PTD | DIS | M0)) /*UART2_TX*/\
403: MUX_VAL(CP(UART2_TX), (IDIS | PTD | DIS | M0)) /*UART2_TX*/\

Looking at the code lines 390 and 403 are the rev C and xM global muxes. So on an rev Cx (classic) and xM (all revs) gpio146 is not available since it's muxed as UART2_TX

Doesn’t the M4 in:

229: MUX_VAL(CP(UART2_TX), (IEN | PTD | DIS | M4)) /GPIO_146/\

mean Mode 4, which is gpio_146? That, by default gpio_146 should appear on pin 6 of the header. If it were M0 then UART2_TX would be tied to the pin.

My plan is to change it to M2 so I can get to the PWM signal, but so far I haven’t seen any coming out of pin 4 (or 6 or 10) of the header.

–Mark

Doesn't the M4 in:

229: MUX_VAL(CP(UART2_TX), (IEN | PTD | DIS | M4)) /*GPIO_146*/\

mean Mode 4, which is gpio_146?

yes

That, by default gpio_146

No, not on rev C and xM, as I said in the mail you replied to:

koen@dominion:/OE/tmp/u-boot$ grep -n UART2_TX board/ti/beagle/beagle.h
225: MUX_VAL(CP(MCBSP3_CLKX), (IDIS | PTD | DIS | M1)) /*UART2_TX*/\
229: MUX_VAL(CP(UART2_TX), (IEN | PTD | DIS | M4)) /*GPIO_146*/\
390: MUX_VAL(CP(UART2_TX), (IDIS | PTD | DIS | M0)) /*UART2_TX*/\
403: MUX_VAL(CP(UART2_TX), (IDIS | PTD | DIS | M0)) /*UART2_TX*/\

Looking at the code lines 390 and 403 are the rev C and xM global muxes. So on an rev Cx (classic) and xM (all revs) gpio146 is not available since it's muxed as UART2_TX

So if you want the pwm signal you need to change line 390 and/or 403 (or write your own additional mux function)

Koen:
The light has come on! I now see that I wasn’t looking far enough into the beagle.h file to see the other definitions.

I can now generate a PWM signal at some 4MHz. I’ll be posting my notes about how to do it once they are cleaned up.

Thanks for all your help.

–Mark