Toggling GPIO with direct memory access

Hi Folks,

I am trying to generate accurate PWM signals with GPIO using direct
memory access. For these purposes, I modify the small test programm
found at [1] to toggle GPIO158. The test program could be found in
attachment. Despite all my attemts it does not work and I hope that
someone here can help me with it.

As I understand, in genera, there are three main steps involved:

1. Configure the pad to work as GPIO. This is done by memmapping
address 0x48000000 and then setting bits (EN | PTD | M4) at the offset
0x2190/4 (assuming that offset pointer is defined as ulong, that is
why /4)

2. Memmap the pads I/O memory. Probably I am somehow missunderstand
the omap tech-ref manual, but I came to conclusion that the I/O memory
for the GPIO158 is at 0x48070000 with offset 0x4008/4.

3. Actually toggle GPIO by writing 0 or 1 to the corresponding memory
location, i.e.:
  for(;:wink: {
      //gpio[x] = 0x00000100; // set bit 8
      gpio[0x4008/4] = 1; // up
      usleep(1500);
      gpio[0x4008/4] = 0; // down
      usleep(20000);
  }

My expectation was that it will generate standard PWM to place servo
to certain position. However it seams like it does not work at all.
Even writing 0 or 1 to the gpio address without loop does not change
the voltage level on the corresponding pin. I checked that it is the
correct pin by triggering gpio using /sys/class/gpio and echo way.

I am suspecting that I am using wrong adresses in this example and
would highly appreciate if someone could point me to the right place
in the documentation or provide any other hints.

Thank you,
Andrey.

[1] http://x4350.blogspot.com/2011/01/digital-io-on-beagleboard-using-gpio.html

my-toggle-gpio.c (2.13 KB)

Why don't you use the PWM peripherals provided by the TI OMAP?

What linux distribution are you using with your board to use as your
user space?

Why don't you use the PWM peripherals provided by the TI OMAP?

There are only three and I am using them but want to control more
devices such as for example servos.

What linux distribution are you using with your board to use as your
user space?

Angstrom.

I'll try to restate the question since I beleave the root of my
problem is wrong addresses I am using to configure GPIO pin and to do
the I/O. So I would really appreciate if someone can confirm that:

- the address to confiture GPIO158 is 0x48000000 and offset is 0x2190

- the address to do I/O, i.e setting GPIO158 to high and low is
0x48070000 with offset 0x4008

If my assumptions are wrong, I would be also very thanksful for the
pointer in the documentation where to read the correct values.

Thank you,
Andrey.

Hi Andrey,

If the GPIO158 has been correctly configured then
        /sys/class/gpio echo and cat command will give some results.
I suspect the problem in configuring.
If you use the devmem command you will be able to see the data at the
memory
location and able to figure it out.
Hope this helps...

Thanks,
Lokesh

Hi Lokesh,

If the GPIO158 has been correctly configured then
/sys/class/gpio echo and cat command will give some results.

I am configuring the pin in my application using direct memory access
and intentionally not using the Linux kernel for it.

I suspect the problem in configuring.

Do you see any mistakes in the configuration steps I have made in the
test application I've attached to my original post? I would appreciate
any hints.

If you use the devmem command you will be able to see the data at the
memory
location and able to figure it out.

I do not see any changes at the location I am using and that is why I
came to conclusion that the address is probably wrong. That is why I
restate my question and ask if someone who understand the matter can
confirm that the addresses I am using are wrong and probably point me
to the place in the documentation where the right address could be
found. I am somehow lost within 3500 pages :slight_smile: .

Thanks,
Andrey.

Hello,

Most PDF-Readers are offering a search function.

Thanks for letting me know.

Searching for gpio_158 reveals 0x48002190.

My original question was:

So I would really appreciate if someone can confirm that:
- the address to confiture GPIO158 is 0x48000000 and offset is 0x2190

So it looks like your magic search tool confirms my finding.

- the address to do I/O, i.e setting GPIO158 to high and low is
0x48070000 with offset 0x4008

Maybe it is possible to confirm this claim also with search tool? Well
I do not think so. And this is the reason why I was asking the
question. It is not obvious (at least not for me) where to find this
address. My assumption was based on the address of MCBSPLP_DXR_REG in
Table 21-37. "McBSP1 Registers Mapping Summary" on page 3018 but I am
not sure about it.

Regards,
Andrey.

No, but by just reading a small part of the about 40 pages about the General Purpose Interface. There is no need to read 3500 pages, you don't need to read most of them, just be happy to get such a documentation. Your sentence that you were lost in 3500 pages was the only reason why I've answered and why I've suggested to use a search tool. Now I'm just suggesting to use the table of contents to find the relevant chapter (24.5 in the rev O). :wink:

To answer your question, 158 is part of the GPIO5 module which goes from 128 (included) to 159 (included), so the physical address of GPIO_SETDATAOUT for that block is 0x49056094. Bit 30 (158-128 or 31-(159-158)) is the bit you have to set when writing to that register.
You could also use GPIO_DATAOUT for GPIO5 directly (0x4905 603C), 24.5.2.1 explains the difference in using those two registers. All numbers are without any warranty against misreading or typos by me. ;).

Sorry, but I'm just getting angry when people are complaining when they get a good and mostly complete documentation, which is why I've written my first response. It isn't that hard to find the relevant pages.

Regards,

Alexander

so the physical address of GPIO_SETDATAOUT for
that block is 0x49056094. Bit 30 (158-128 or 31-(159-158)) is the bit you
have to set when writing to that register.
You could also use GPIO_DATAOUT for GPIO5 directly (0x4905 603C), 24.5.2.1
explains the difference in using those two registers. All numbers are
without any warranty against misreading or typos by me. ;).

Thanks Alexander! This is the information I was totally
missing/missunderstanding. Now it is much more clear for me how gpio
control works in general and for my required one in particular.

Sorry, but I'm just getting angry when people are complaining when they get
a good and mostly complete documentation, which is why I've written my first
response. It isn't that hard to find the relevant pages.

I'll keep the discussion technical and would not respond to the emotions :wink:

Thank you very much,
Danke :slight_smile:
Andrey.