Memory Map GPIO's and Peripherals

Discussion in 'General Programming Discussion' started by mickey, Nov 27, 2013.

  1. mickey

    mickey New Member

    Joined:
    Aug 13, 2013
    Messages:
    5
    Likes Received:
    0
    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
     
  2. Lifeboat_Jim

    Lifeboat_Jim New Member

    Joined:
    Sep 16, 2013
    Messages:
    399
    Likes Received:
    1
    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!) :D
     
  3. mickey

    mickey New Member

    Joined:
    Aug 13, 2013
    Messages:
    5
    Likes Received:
    0
    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
     
  4. Lifeboat_Jim

    Lifeboat_Jim New Member

    Joined:
    Sep 16, 2013
    Messages:
    399
    Likes Received:
    1
    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.
     
  5. mickey

    mickey New Member

    Joined:
    Aug 13, 2013
    Messages:
    5
    Likes Received:
    0
    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);
        }
    }
    
     
  6. vjorgic

    vjorgic New Member

    Joined:
    Dec 9, 2013
    Messages:
    2
    Likes Received:
    0
    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
     
  7. mickey

    mickey New Member

    Joined:
    Aug 13, 2013
    Messages:
    5
    Likes Received:
    0
    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.
     
  8. morsecode

    morsecode New Member

    Joined:
    Nov 5, 2013
    Messages:
    1
    Likes Received:
    0
    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?
     
  9. vjorgic

    vjorgic New Member

    Joined:
    Dec 9, 2013
    Messages:
    2
    Likes Received:
    0
    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.
     

Share This Page