Help Needed on GPIO Drivers


9 posts
by rpi3008 » Tue Jan 15, 2013 11:41 am
Hello Forum,

First of all , I am totally excited with my new toy (Raspberry Pi - 512MB model). Thanks to Element14 to deliver it at the earliest possible!

Recently I decided to play around with GPIO Pins to switch on and off a LED (with proper circuit in place). I am using GPIO23 for my experiment. This GPIO pin is connected to the base of a NPN transistor with GPIO_VAL = 1 will turn on the transistor and let the LED glow.

GPIO23 is configured as OUTPUT in GPFSEL0.


I was successful in mapping the GPIO peripheral base to a virtual address, and access the GPIO Output Set Registers (GPSET0).

To turn logic level ON , on GPIO23, I use the following code :
*GPSET0 = *GPSET0 | (1 << 23);

To turn logic level OFF , on GPIO23, I use the following code :
*GPCLR0 = *GPCLR0 | (1 << 23);

To my misfortune, the system just hangs, as the clear operation takes place.

My mouse, keyboard, just stop working. As far as I understood from schematics, GPIO23 is in no way connected to USB bus, and shouldn't be effected due to clearing of GPIO23.

Any help is deeply appreciated.
-=-
BR,
./rpi3008
Posts: 7
Joined: Wed Jan 02, 2013 9:13 am
by Arjan » Tue Jan 15, 2013 12:29 pm
Hi,

For playing with the GPIO pins, there is a great C library for Broadcom BCM 2835 as used in Raspberry Pi available at http://www.open.com.au/mikem/bcm2835/.

It also provides some good samples.

Regards, Arjan
Posts: 128
Joined: Sat Sep 08, 2012 1:59 pm
by joan » Tue Jan 15, 2013 12:57 pm
You may be screwing the system up by reading the registers before writing them. You should only manipulate user gpios. You're potentially setting/clearing system gpios as well.

Try to set

*GPSET0 = (1 << 23);

to clear

*GPCLR0 = (1 << 23);
User avatar
Posts: 5496
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by rpi3008 » Tue Jan 15, 2013 4:14 pm
Hey Arjan,
Thanks for the invaluable suggestion.

The idea, however is to write the gpio driver from scratch for the learning purpose.

I would for sure consult the code to understand wot I have been doing wrong!!

--
./rpi3008

Arjan wrote:Hi,

For playing with the GPIO pins, there is a great C library for Broadcom BCM 2835 as used in Raspberry Pi available at http://www.open.com.au/mikem/bcm2835/.

It also provides some good samples.

Regards, Arjan
Posts: 7
Joined: Wed Jan 02, 2013 9:13 am
by rpi3008 » Tue Jan 15, 2013 4:26 pm
Hey Joan,
I doubt,the specs dint mention anything about values being reset if the registers are read from...

Also, the code mentioned in your reply below will potentially reset all the GPIO pins below 23rd bit , except the 23rd bit....

This is wot I shall try..
To set::
Mask = *GPSET0;
Mask |= (1 << 23);
*GPSET0 = Mask;

to clear
Mask = *GPCLR0;
Mask |= (1 << 23);
*GPCLR0 = Mask;

Never the less, worth trying your suggestion, shall revert back if the trick does the magic... :)
--
./rpi3008

joan wrote:You may be screwing the system up by reading the registers before writing them. You should only manipulate user gpios. You're potentially setting/clearing system gpios as well.

Try to set

*GPSET0 = (1 << 23);

to clear

*GPCLR0 = (1 << 23);
Posts: 7
Joined: Wed Jan 02, 2013 9:13 am
by joan » Tue Jan 15, 2013 4:52 pm
The code I posted is correct. That is the code to use if you want to set or clear gpio 23.
User avatar
Posts: 5496
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by rpi3008 » Wed Jan 16, 2013 10:46 am
Hey Joan,

Waoo....yes you were absolutely right....the code you mentioned did work well (ie. there was no system hang observed after I unloaded the module).
=======
*GPCLR0 = (1 << 23);
=======

Unfortunately, my code ie. where I first read the Register , Mask the contents with the pin to clear and writting back (all on seperate lines of code) ...this still resulted in system hangup.


BTW, I still skeptical about the code you mentioned, my obvious doubt is ...

Would n't " *GPCLR0 = (1 << 23); " clear all the 22 lower bits ??
My understanding till date is that ...this code may interfere with functionality of other GPIO pins , which might accidently be set to zero??

./rpi3008

rpi3008 wrote:Hey Joan,
I doubt,the specs dint mention anything about values being reset if the registers are read from...

Also, the code mentioned in your reply below will potentially reset all the GPIO pins below 23rd bit , except the 23rd bit....

This is wot I shall try..
To set::
Mask = *GPSET0;
Mask |= (1 << 23);
*GPSET0 = Mask;

to clear
Mask = *GPCLR0;
Mask |= (1 << 23);
*GPCLR0 = Mask;

Never the less, worth trying your suggestion, shall revert back if the trick does the magic... :)
--
./rpi3008

joan wrote:You may be screwing the system up by reading the registers before writing them. You should only manipulate user gpios. You're potentially setting/clearing system gpios as well.

Try to set

*GPSET0 = (1 << 23);

to clear

*GPCLR0 = (1 << 23);
Posts: 7
Joined: Wed Jan 02, 2013 9:13 am
by joan » Wed Jan 16, 2013 12:17 pm
There are separate clear bit and set bit registers to prevent the need for a read/modify/write operation.

The clear/set registers only clear/set gpios whose bit is set in the register write. The state of all other gpios remains as before.

I don't know what those registers return when read. Perhaps the set register returns a 1 bit for each gpio whose last operation was set and a 0 bit for each gpio whose last operation was clear (which incidentally may bear no relation to the actual high/low level of the gpio).

My concern was that you were reading the state of bits 0 to 31, modifying them, and then writing the states back.

The problem with that is some other system process may have interrupted yours and itself modified some gpios between your read and your write. Your write would then set some gpios to an incorrect state.
User avatar
Posts: 5496
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK
by rpi3008 » Fri Jan 18, 2013 7:32 am
Hey Joan,

Great....Thanks a lot for the detailed explaination.
Helped a lot in clearing my silly doubts.

My next footfall is to configure GPIOs to enable JTAG debugging (something which is my favorite hardware debugger tool) on Raspberry Pi....

Lets see how soon I get there :)

./rpi3008
Posts: 7
Joined: Wed Jan 02, 2013 9:13 am