Topic: How can i read/wright gpio with the hacker board ?
It will be great if you could help me, with an explanation or just a link, thanks you.
You are not logged in. Please login or register.
chumbysphere forum → Chumby Hacker/OEM boards → How can i read/wright gpio with the hacker board ?
It will be great if you could help me, with an explanation or just a link, thanks you.
First, you need to figure out which pins you're going to access. Take a look at the i.MX23 reference manual (IMX23RM.PDF) in chapter 37.2.2: Pin Interface Multiplexing. Note the bank and the pin number. For this example, I'm going to pick Bank 1, Pin 28.
Next, ensure the pin is set as a GPIO in the pin muxer. For bank 1, pin 28, this is defined by bits 0x03000000 in HW_PINCTRL_MUXSEL3 (section 37.4.5). Set them all to 1 by running "regutil -w HW_PINCTRL_MUXSEL3_SET=0x03000000"
The last steps depend on whether you want to treat it as an input or an output.
To use it as an input, clear the "Data Output Enable" bit by running "regutil -w HW_PINCTRL_DOE1_CLR=0x10000000", then read the value by running "regutil -r HW_PINCTRL_DIN1" and looking at bit 0x10000000. A cheap hack to do this can be found in the "headphone_present" script in /usr/chumby/scripts/
To use it as an output, set the "Data Output Enable" bit by running "regutil -w HW_PINCTRL_DOE1_SET=0x10000000". Then write the value you want by either running "regutil -w HW_PINCTRL_DOUT1_SET=0x10000000" or "regutil -w HW_PINCTRL_DOUT1_CLR=0x10000000" to either set it to 1 or 0. Sometimes you can also fiddle with the drive strength and/or voltage. Check the documentation on HW_PINCTRL_DRIVEn for more information.
Interrupts are trickier and will require kernel code. An example of how to do this can be found in the chumby_bend.c keyboard driver in drivers/input/keyboard/ under the Linux kernel.
Thanks you for your explanation, i try and succes your exemple but wen I try with another pin I fail...
I'm going to pick Bank 0, Pin 0 named gpmi_d0 and can be find in the hacker board on the pin 2 of the 9x2 header (next the USB2), and normaly control the LED DO on the board (but i thinks we have to set another pin to low to do that.
So, the bank 0 pin 0 is defined by bits 0x00000003 in HW_PINCTRL_MUXSEL0 ( section 37.4.2). So i run "regutil -w HW_PINCTRL_MUXSEL0_SET=0x00000003".
result:
chumby-:/ # regutil -w HW_PINCTRL_MUXSEL0_SET=0x00000003
Setting 0x80018104: 0xffffffff -> 0xffffffff ok
I wanna use it as an output,so i set the "Data Output Enable" bit by running "regutil -w HW_PINCTRL_DOE0_SET=0x10000000"
result:
chumby-:/ # regutil -w HW_PINCTRL_DOE0_SET=0x10000000
Setting 0x80018704: 0x34011000 -> 0x34011000 ok
And to finish I set a 1 with running "regutil -w HW_PINCTRL_DOUT1_SET=0x10000000"
result:
chumby-:/ # regutil -w HW_PINCTRL_DOUT0_SET=0x10000000
Setting 0x80018514: 0x00000000 -> 0x10000000 ok
But the pin voltage is still 0V so their something wrong with my steps.
Thanks you.
The DOEx and DOUTx pins go from pin 31 on the left to pin 0 on the right. So to set pin 0, you'll want to run:
regutil -w HW_PINCTRL_DOE0_SET=0x00000001
regutil -w HW_PINCTRL_DOUT0_SET=0x00000001
Alright it's working and when I set to "1" BANK0_PIN19 & BANK0_PIN0 the on-board LED D0 switched on.
Thanks.
How can i read/write gpio with C ?
exemple, if i want to do that :
regutil -w HW_PINCTRL_DOE0_SET=0x00000001
i need to write 0x00000001 in 0x80018704 ? ( because HW_PINCTRL_DOE0_SET = 0x80018704 )
Take a look at the source to regutil, which is located in utils-1.0. It basically does an mmap() of /dev/kmem and writes to an offset there.
If someone have an example it could very help me.
You really should take a look at the regutil source as ChumbyLurker suggested - it's very straightforward and probably the best example you could find. It's not very big and the code is clearly written.
The basic strategy is to mmap /dev/mem or /dev/kmem - that effectively turns the physical address space of the device into an C array. From then on you just use it as any other array. In the regutil source code, it maps the memory to an array of tyoe "int" since the registers are typically treated as such, then adjusts the byte address supplied to turn it into a valid array index.
I've had some success with hacking regutil into a DLL. I'm using it with CTYPES in Python but it should be equally accessible from C.
I'll post something on it soon- I'm working up to a post on Python on CHB in general, and that'll be a follow-up.
Thanks for all the replies everyone.
As a result of reading through this thread, I was able to get an LED to light up @ Pin 44, GPMI_D00.
However, when I try to apply the same steps for pin 45 GPMI_D01, I do not get any activity.
Here is what I did for pin 45:
regutil -w HW_PINCTRL_MUXSEL0_SET=0x00000003
regutil -w HW_PINCTRL_DOE1_SET=0x00000001
regutil -w HW_PINCTRL_DOUT1_SET=0x00000001
Where did I go wrong?
MUXSEL0 controls which function a particular pin has. The manual says that GPMI_D01 is "Bank 0 Pin 1", which is set in MUXSEL0, bits 0x0000000c. So in order to set that as a GPIO, you'd run:
regutil -w HW_PINCTRL_MUXSEL0_SET=0x0000000c
Then to set it as an output, run:
regutil -w HW_PINCTRL_DOE0_SET=0x00000002
Finally, to set it high, run:
regutil -w HW_PINCTRL_DOUT0_SET=0x00000002
Thanks ChumbyLurker! I believe I had an epiphany once I saw your post. Let me just share it with the rest of the forum.
Many may already know this stuff, but I had some trouble with it last night.
This step
regutil -w HW_PINCTRL_MUXSEL0_SET=0x0000000c
updates the 16 bit register to 0000 0000 0000 1100. This is because 0x0000000c = 12 in decimal which equals 1100 in binary. According to BANK0_PIN01 in table 37-8, the bits 2 and 3 need to be set (i.e 1100 [3210]).
Next, the command
regutil -w HW_PINCTRL_DOE0_SET=0x00000002
updates the 16 bit register to 0000 0000 0000 0010. This command enables output for pin 1 on bank 0.
Finally, power it up! Issue the command
regutil -w HW_PINCTRL_DOUT0_SET=0x00000002
If you want to unset bit 1 (bank0_PIN1) issue the command
regutil -w HW_PINCTRL_DOUT0_CLR=0x00000002
This will turn the power off.
You can even toggle the bit back and forth by issuing
regutil -w HW_PINCTRL_DOUT0_TOG=0x00000002
I took the forums advice and looked into the regutil.c code and was able to wrap my head around what was going on.
Here is some code that I came up with that operates the HW_PINCTRL_DOUT0_TOG register.
/**
In order for this to work, bits 0011 need to be set for HW_PINCTRL_MUXSEL0_SET
and bit 0001 needs to be set for HW_PINCTRL_DOE0_SET - as per the documentation.
You can follow this example and do the work before, or run regutil. To keep the example simple,
I opted not to.
All this code does is continuously write (0x00000001) to the HW_PINCTRL_DOUT0_TOG register
every 1 second.
This is for GPMI_D00
**/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
static int *mem = 0;
static int fd = 0;
int main(int argc, char **argv)
{
unsigned int offset = 0;
unsigned int value = 0;
//As per the regutil_falconwing.h, this is the HW_PINCTRL_DOUT0_TOG register
offset = strtoul("0x8001850c", NULL, 0);
//toggle bit
value = strtoul("0x00000001" , NULL, 0);
//Prep for reading and writing to memory
fd = open("/dev/mem", O_RDWR);
//Incase something goes terribly wrong
if( fd < 0 )
{
perror("Unable to open /dev/mem");
fd = 0;
return -1;
}
//Create the memory map
mem = mmap(0, 0xffff, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset&~0xFFFF);
//You need the scaled offset
int scaled_offset = (offset -(offset&~0xFFFF));
//Loop every 1000 milliseconds while writing to the register via memory map with the toggle bit vale
while(1)
{
mem[scaled_offset/sizeof(long)] = value;
sleep(1);
}
return(0);
}
several time writing these code but no any leds light on
what is the problem
regutil -w HW_PINCTRL_MUXSEL0_SET=0x0000000c
regutil -w HW_PINCTRL_DOE0_SET=0x00000002
regutil -w HW_PINCTRL_DOUT0_SET=0x00000002
I found the answer:
Firstly we set GPMI_RDYO pin for leds drive mosfet
Hi,
I'm a newbee with the chumby and I'm trying to turn the leds D0..D3 on but I dont understand some things.
To enable GPMI_RDY0 is it:
# regutils -w HW_PINCTRL_MUXSEL1=0xc000
Somebody can explain me the full sequence to turn the led on?
Many Tanks,
MilOo
several time writing these code but no any leds light on
what is the problemregutil -w HW_PINCTRL_MUXSEL0_SET=0x0000000c
regutil -w HW_PINCTRL_DOE0_SET=0x00000002
regutil -w HW_PINCTRL_DOUT0_SET=0x00000002I found the answer:
Firstly we set GPMI_RDYO pin for leds drive mosfet
Hi I wrote some python code for the Infocast but you guys might find it useful too :-
http://www.madox.net/blog/2011/01/12/ch … n-library/
chumbysphere forum → Chumby Hacker/OEM boards → How can i read/wright gpio with the hacker board ?
Powered by PunBB, supported by Informer Technologies, Inc.