GPIO does not turn on LED

Hi,
I used the following device tree overlay to configure “GPIO1_16” (which is P9-15) to Mode-7 (=GPIO):

`
//file name: BB-gpio-set-00A0.dts

/dts-v1/;
/plugin/;

/ {
compatible = “ti,beaglebone”, “ti,beaglebone-black”;

/* identification */
part-number = “BB-LED”;
version = “00A0”;

/* state the resources this cape uses /
exclusive-use =
/
the pin header uses /
“P9.15”, /
GPIO1_16 /
/
the hardware ip uses */
“GPIO1_16”;

fragment@0 {
target = <&am33xx_pinmux>;
overlay {
bb_GPIO1_16_pins: pinmux_bb_GPIO1_16_pins {
pinctrl-single,pins = <
0x40 0x07 /* P9.15 OUTPUT */

;
};
};
};
};
`

Then, I compiled it with dtc, copied the dtbo file to /lib/firmware/,
and performed echo BB-gpio-set > slots

Now, I ran the following Code to turn on GPIO1_16, but the code does not turn it ON.

Why it that please?

`
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

#define GPIO1_BASE 0x4804C000
#define GPIO1_END 0x4804CFFF
#define GPIO1_SIZE GPIO1_END-GPIO1_BASE
#define GPIO_OE 0x0134
#define GPIO_DATAOUT 0x013C
#define GPIO_USERBUTTON 7
#define GPIO1_16 16 //GPIO1_16
#define GPIO_SETDATAOUT 0x194
#define GPIO_CLEARDATAOUT 0x190

int main(int argc, char** argv)
{
volatile unsigned int *reg, *reg_base, *reg_clr;
unsigned int value;
int fd = open("/dev/mem", O_RDWR);

/* LED0 Setup and Turn-on */

//Set GPIO_OE to Output
reg_base =(volatile unsigned int*) mmap(0,GPIO1_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO1_BASE);
reg = (volatile unsigned int*)(reg_base + GPIO_OE);
value = *(reg);
value &= ~(1 << GPIO1_16);
*(reg) = value;

//set GPIO_SETDATAOUT to turn LED on
reg = (volatile unsigned int*)(reg_base + GPIO_SETDATAOUT);
value = *(reg);
value |= (1 << GPIO1_16);
*(reg) = value;

return 0;
}
`

Hi matt,

You are calculating the wrong addresses when you add the offsets to reg_base. Instead of reg_base + 0x134 it does reg_base + (0x134 * 4). The compiler is being “helpful” by converting your integer offset into a unsigned int[index]!

You could define the address pointers as unsigned ints or as unsigned char *, and then cast them into (unsigned int *) just before you use them to get the addition right.

Hi Guy,
Thanks a lot!

It solved the problem! I can’t believe I missed it! Thanks to you it works well.

There’s something which is not clear to me.

Even without compiling the Device-Tree Overlay (and without of course exporting it to slots) - i.e. without configuring GPIO1_16 (P9.15) to Mode 7 (= GPIO Mode),

I manage to run the above C program and control the LED as if P9.15 is GPIO (Mode 7).

How come I don’t need to configure P9.15 to GPIO Mode 7, in order to operate it as GPIO?

Thank you very much.

Hi Matt,

take a look at the Technical Reference Manual of AM335x

9.2.2.1 Mode Selection
The MUXMODE field in the pad control registers defines the multiplexing mode applied to the pad. Modes
are referred to by their decimal (from 0 to 7) or binary (from 0b000 to 0b111) representation. For most
pads, the reset value for the MUXMODE field in the registers is 0b111. The exceptions are pads to be
used at boot time to transfer data from selected peripherals to the external flash memory.

So I assume that this pin (gpio1_16) will be configured for mode 7 at system reset time.

regards
Ralf

Hi Ralf,
Thank you.

I indeed read this section in the Reference Manual.

The thing is, that when performing root@beaglebone:/sys/kernel/debug/pinctrl/44e10800.pinmux# cat pins

then it showed that: pin 48 (44e108c0) 00000008 pinctrl-single

meaning that the PIN’s MUX Mode is 0, right?

However, even though it’s in Mode 0, I manage to use it as GPIO (by writing to GPIO_OE and GPIO_SETDATAOUT) as if it was Mode 7, and without using a DT overlay.

How can it be explained please?

Thank you.

Matt,

yes it should be mode 0, output, no pullup / pulldown.

You are referring Pin P8.37 / lcd_data8 ?
If so, this a good question which I also have no idea.

The only assumption I have is that the GPIO-function might be something like "wired or" with other modes (here lcd controller function pin).

How do you test the port function?

regards
Ralf

Hi Ralf,
Thank you again friend.

I’m referring to P9.15 (=GPIO1_16), which is Pin 48, which I showed its MUX Mode: pin 48 (44e108c0) 00000008 pinctrl-single

According to the P9_Table, Mode 0 of that Pin9.15 is gmpc_a0

"how do you test the port function?"

Well, I simply wrote the a code which writes to GPIO1 Registers directly (i.e. not using the Virtual File System), and manage to control its output level and toggle a LED.

Matt,

now it gets clearer.
You referred Pin 48 (cat pins), so I thought you checked against a new pin with an other mode set.

I think you mixed "GPIO pin" number with "logical pin" number.

You are referring to P9.15 (= GPIO1_16 / gpmc_a0), which is Pin 48
But: Pin 48 is a GPIO pin number!
(each gpio group includes 32 pins, 48 is the sum of: 32 pins from group 0 + pin 16 of group 1)

The associated logical pin for GPIO pin number 48 has number 16!
So if you "cat pins" as before you get the interesting entry:
pin 16 (44e10840) 00000027 pinctrl-single (mode 7)
BTW offset 840h conf_gpmc_a0 can be found in the SRM.

Logical Pin 48 is associated Pin P8.37 / lcd_data8 as I mentioned before.

regards
Ralf

Hi Ralf,

Thank you for clearing it up!

Could you please explain how you deduced that Logical Pin 48 is associated with Physical Pin P8.37? ( I do see in the table that P8.37 = lcd_data8, just not sure how you deduced that their Logical Pin number is 48).

Thank you.

Matt,

Take a look at https://github.com/piranha32/IOoo/blob/master/doc/Beaglebone%20Black%20pin%20cheatsheet.ods

I compiled the spreadsheet for my own use, combining information from several sources. It helped me a lot, I hope you will find it useful as well.

j.

This also might be helpful.
I use https://github.com/derekmolloy/boneDeviceTree/tree/master/docs
(press the raw button for downloading)
Thanks to Derek Molloy for providing that docs.

See column $PINS which contains the mentioned logical pin.
Gpio Pins have a separate column.

Ralf

Awesome! Thanks a lot Ralf!

My next step would be exporting a DT Overlay dtbo into slots and then cat pins and see whether i managed to change a Mode of a certain Pin.

You could use your already available dts you posted.
Just change the pin to input and enable a pulldown -> 0x27.
The cat pins should give you 0x27 afterwards.
Have a nice weekend.
Ralf

Thank you Ralf!

I’ll try it out and update

Matt,
i made a made a little mistake in my previous post:
default state after reset of pin 16 is already 0x27 (input with pulldown).
(cat pins -> pin 16 (44e10840) 00000027)
Just use your original dts to check, you should get 0x7 afterwards (output).

Ralf

Hi Ralf,
Thank you very much.

I compiled the following BB-gpio-set-00A0.dts file, and copied the generated BB-gpio-set-00A0.dtbo file to /lib/firmware/

`
//file name: BB-gpio-set-00A0.dts

/dts-v1/;
/plugin/;

/ {
compatible = “ti,beaglebone”, “ti,beaglebone-black”;

/* identification */
part-number = “BB-LED”;
version = “00A0”;

/* state the resources this cape uses /
exclusive-use =
/
the pin header uses /
“P9.15”, /
GPIO1_16 /
/
the hardware ip uses */
“GPIO1_16”;

fragment@0 {
target = <&am33xx_pinmux>;
overlay {
bb_GPIO1_16_pins: pinmux_bb_GPIO1_16_pins {
pinctrl-single,pins = <
0x40 0x07 /* P9.15 OUTPUT */

;
};
};
};
};

`

Then, I went to /sys/devices/bone_capemgr.8 and performed. echo BB-gpio-set > slots

cat slots produced:

0: 54:PF--- 1: 55:PF--- 2: 56:PF--- 3: 57:PF--- 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G 5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI 9: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-gpio-set

I re-checked then cat pins but pin 16 stayed the same:

`
pin 16 (44e10840) 00000027 pinctrl-single

`

Do you have an idea what is wrong or missing in the above steps I took?

Hi Matt,
your dts seems not to be complete.

Please append following code after your existing fragment@0 section:

fragment@1 {
  target = <&ocp>;
  __overlay__ {
    /* avoid stupid warning */
    #address-cells = <1>;
    #size-cells = <1>;

    gpio1_16_test {
      compatible = "bone-pinmux-helper";
      pinctrl-names = "default";
      pinctrl-0 = <&bb_GPIO1_16_pins>;
      status = "okay";
    };
  };
};

Now you should get the expected value:
pin 16 (44e10840) 00000007 pinctrl-single

(I successfully checked the overlay on my bone)

regards
Ralf

Hi Ralf,
Thank you very much!

I’ll try it out!

I actually read few guides on the DT Overlay, but still haven’t reached a full understanding of it.

Are you familiar with a thorough DT Overlay guide?

Thanks a lot!

  • I’ll of course update on the DT Overlay Fragment@1 addition you kindly attached :slight_smile:

Matt,
I have not a lot of device tree experience.
Currently I design a FPGA-based cape for motion control.
The cape must be supported by device tree. So I was forced to get an basic understanding of the dts mechanism.

I took some simple and some complex dts sources from kernel tree and studied the description.
Sometimes it is helpful to grep some description keywords in the kernel source or in the web to get an better understanding of the mechanism.
There are a lot of device tree guides floating around.
This one might be a good starting point http://www.circuidipity.com/bbb-dt.html
and contains some more useful links.
But be aware some descriptions get sometimes outdated and can not be taken 1:1.

regards
Ralf

Hi Ralf,

First of all, thank you for sharing your project, it is very interesting.
You do both FPGA design and RT Embedded programming as part of your job?

BTW, I hear a lot the term ‘cape’, what exactly do you mean by that?

Second of all, Thanks a lot for the Fragment@1 addition!
It works great :slight_smile:
I read the article you attached, it explains the motivation but does not go into details, but it was still helpful to see the big picture.