Where can I find the data sheet for the quad that calls out the memory map information for GPIO's and other peripherals? I am looking to access GPIO's or peripherals at the lowest level in user space (/dev/mem) or kernel space. -- Mickey
I believe this datasheet is the correct one. In conjunction with the Source is that enough for you to resolve your request? Please do document (as best you can) what you find and come back and share it with the rest of us (including code examples/snippets of course!)
The datasheet you posted does not cover the memory map. I did find the datasheet on Freescale's site that outlines the memory map and all the information one would need regarding peripherals on the i.MX 6Dual/6Quad. It is the i.MX 6Dual/6Quad Applications Processor Reference Manual. -- Mickey
Sorry Mickey, when you said 'datasheet' I took you literally. Still, you've got it sorted now. As mentioned before I'm sure I'm not the only one to look forward to what you cook up for low level access.
I have been reading the datasheet and was able to slap something together utilizing GPIO40. Does anyone know where I can a pdf or image of the udoo board that tells me what pad is mapped to a particular header :?: The datasheet refers to GPIO40 as GPIO02_IO8 or PAD SD4_DAT0. It would be nice to know.....say what pad belongs to GPIO205. Makes referring to the datasheet much easier. Here is some pure c code that will blink GPIO40 every 250 milliseconds. Code: #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <sys/mman.h> #include <errno.h> #include <string.h> #include <stdint.h> #include <unistd.h> #define IOMUXC 0x020E0000 #define IOMUXC_SW_MUX_CTL_PAD_SD4_DATA0 0x020E031C #define GPIO2_DR 0x020A0000 #define GPIO2_GDIR 0x020A0004 #define GPIO2_PSR 0x020A0008 static volatile uint32_t *gpio; int main(int argc, char **argv) { int fd ; //Obtain handle to physical memory if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0) { printf("Unable to open /dev/mem: %s\n", strerror(errno)); return -1; } /** * Map some of the pin mux registers within the range of the * GPIO40 GPIO40 pin. **/ gpio = (uint32_t *)mmap(0, (getpagesize() * 250), PROT_READ|PROT_WRITE, MAP_SHARED, fd, IOMUXC); // The first 3 bits are the only thing that matters here according to the // datasheet. *(gpio + ((IOMUXC_SW_MUX_CTL_PAD_SD4_DATA0 - IOMUXC) / 4)) = 0x5; //Be a good neighbor if((munmap((void *)gpio, (getpagesize() * 250))) < 0){ printf("munmap failed: %s\n", strerror(errno)); exit(1); } /** The i.MX 6 Dual and Quad Processor have 7 GPIO banks * Each bank amounts to 1mb of memory which is perfectly * aligned for a memory map. Mmap will fail if the offset * is not a multiple of 1mb. For this example I just want * the GPIO2 bank which starts at 0x020A0000. I want the * bank (1mb or 250 pages of memory). I could get away with * a single page, but I am greedy :-P. **/ gpio = (uint32_t *)mmap(0, (getpagesize() * 250), PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO2_DR); if ((int32_t)gpio < 0){ printf("mmap failed: %s\n", strerror(errno)); exit(1); } /** * Setup GPIO40 or GPIO2_IO08 as an output. * gpio[1] is the GPIO direction register (GPIO2_GDIR). * We want to only want to set bit 8 of this register * to a binary 1 while leaving the rest intact. **/ *(gpio + ((GPIO2_GDIR - GPIO2_DR) / 4)) = *(gpio + ((GPIO2_GDIR - GPIO2_DR) / 4)) | 1<<8; /** * Blink GPIO40 every 500 milliseconds. * gpio[0] is the GPIO data register (GPIO2_DR). * We only want to toggle bit 8 of this register * while leaving the rest alone. **/ while(1){ *(gpio + ((GPIO2_DR - GPIO2_DR) / 4)) = *(gpio + ((GPIO2_DR - GPIO2_DR) / 4)) ^ 1<<8; usleep(250000); *(gpio + ((GPIO2_DR - GPIO2_DR) / 4)) = *(gpio + ((GPIO2_DR - GPIO2_DR) / 4)) ^ 1<<8; usleep(250000); } }
Thanks for posting your updates... I am also looking at utilizing the GPIO via mmap... how did you find that GPIO40 is GPIO02_IO8, I was looking at the datasheet but could not find GPIO40 anywhere, am I correct to assume that all pins connected to iMX can be utilized for GPIO via mmap? Vlad
I found it by referencing both the pinout diagrams that udoo has made available. While there is nothing in the alternate pinout diagram about GPIO40, there is something there about PWM13. That is the arduino function name. So to put it all together I wanted to know what the pad name was for GPIO40, so that I could see what the available pin muxing options were. GPIO40 is also known as Arduino funtional name PWM13 on the udoo pinout diagram. Take that information and look at the alternate diagram. Look for Arduino PWM13 under the "Arduino Function" column. From that table row, you can see the "Pin Name" is SD4_DAT0. Search for SD4_DATA0 in the processor reference and you will land on page 305. Pad SD4_DAT0 can take on 3 different modes. The ALT5 mode is GPIO2_IO08. While GPIO_IO08 is by default ALT5, you can use these same steps for the other pins.
Hi, Thanks for the Information. I ran this for 100,000 cycles and it took 28 seconds to that is about 3500 HZ. When I use the GPIO via a file I get 3333 HZ. These are both not very fast does anyone have any idea why?
You should be able to get sub-microsecond latency on a single pin (I did). Maybe post your code, it looks like something else in your code may be causing performance problems.