This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Issue about the GPIO operation through mmap.

Other Parts Discussed in Thread: AM4379

Dear Sir,

    I use the mmap function to operate the GPIO5(AM4379), but I can only read the REVISION register, I can not write the output register. I paste the code. Thanks so much.

#define NSEC_PER_SEC (1000000000) /* The number of nsecs per sec. */
#define GPIO5_START_ADDR (0x48322000)
#define GPIO5_END_ADDR (0x48323000)
#define GPIO5_CLR_OFFSET (0x190)
#define GPIO5_SET_OFFSET (0x194)
#define GPIO5_SIZE (GPIO5_END_ADDR - GPIO5_START_ADDR)

void *thread_func(void *data)
{
struct timespec t;
int interval = 500000000; /* 50us*/
void *gpio5_address = (void *)0;
int fd = 0;

if ((fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
printf("can't open /dev/mem \n");
exit(-1);
}

gpio5_address = mmap(0, GPIO5_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO5_START_ADDR);

if(gpio5_address == MAP_FAILED)
{
printf("unable to map GPIO5 bank.\n");
}

volatile unsigned int *gpio = 0;
gpio = (volatile unsigned int *)gpio5_address;
*(gpio+0x134) = 0x3F00;

// printf("input enable:%x\n",*(gpio));
// printf("CTRL Value:%x\n",*(gpio));
clock_gettime(CLOCK_MONOTONIC ,&t);
/* start after one second */
t.tv_sec++;

*(gpio+0x190) = 0x3F00;
printf("mmap addr is:%x\n",(unsigned int)gpio);
printf("GPIO REVISION:%x\n",*(gpio));
*(gpio+0x190) = (3<<10);
while(1) {
/* wait until next shot */
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL);

/* do the stuff */
printf("HelloWorld\n");
*(gpio+0x190) = 0x3F00;
printf("DATAOUT:%x\n",*(gpio+0x13C));
printf("DATAIN:%x\n",*(gpio+0x138));

/* calculate next shot */
t.tv_nsec += interval;

while (t.tv_nsec >= NSEC_PER_SEC) {
t.tv_nsec -= NSEC_PER_SEC;
t.tv_sec++;
}
}

  • Please refer to this link.

    elinux.org/EBC_Exercise_11b_gpio_via_mmap

    Please enable the PINMUX settings for your GPIO pin if any.
    For your GPIO5 bank.

    #define GPIO5_START_ADDR 0x48322000
    #define GPIO5_END_ADDR 0x48323000
    #define GPIO5_SIZE (GPIO5_END_ADDR - GPIO5_START_ADDR)

    #define GPIO_SETDATAOUT 0x194
    #define GPIO_CLEARDATAOUT 0x190

    //GPIO5 - 24th bit
    #define USR3 (1<<24)

    volatile void *gpio_addr;
    volatile unsigned int *gpio_setdataout_addr;
    volatile unsigned int *gpio_cleardataout_addr;
    int fd = open("/dev/mem", O_RDWR);
    gpio_addr = mmap(0, GPIO5_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO5_START_ADDR);

    gpio_setdataout_addr = gpio_addr + GPIO_SETDATAOUT;
    gpio_cleardataout_addr = gpio_addr + GPIO_CLEARDATAOUT;


    *gpio_setdataout_addr = USR3;
    sleep(2);
    *gpio_cleardataout_addr = USR3;
  • Hi Titus,

        I write the PinMux regster and read it, but the value all are 0, I past the code follow. Thanks so much.

     

    if ((fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
    printf("can't open /dev/mem \n");
    exit(-1);
    }

    ctrl_addr_ptr = mmap(0, CTRL_MOD_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, CTRL_MOD_START);

    if(ctrl_addr_ptr == MAP_FAILED)
    {
    printf("unable to map CTRL MOD bank.\n");
    }

    ctrl_mod = (volatile unsigned int *)ctrl_addr_ptr;

    *(ctrl_mod+0xA40) |=(1<<17) ;
    *(ctrl_mod+0xA40) |=(7) ;
    printf("GPIO5_10 Pin Mux:%x\n",*(ctrl_mod+0xA40));

     

     BR.

     Hans.

  • Can you please try to write the PINMUX register using "devmem2" tool and run your GPIO code ?
    You can also access the GPIO register (any MMR) using devmem2.

    elinux.org/EBC_GPIO_via_mmap

    devmem2 is also one of mmap tool.
  • Hi Titus,

    Maybe the devmem2 can access the GPIO, but I want to through the mmap to access the GPIO in code. Can you confirm why the mmap can not access the GPIO of am437x? Thanks so much.

    BR.
    Hans.