1

I want to blink a simple led, here's the code :

#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <fcntl.h>

#define BASE 0x7e200000

int main() {
        int mem_fd;
        void *gpio_map;
        volatile unsigned int *gpio;
        mem_fd = open("/dev/gpiomem", O_RDWR | O_SYNC);
        if (mem_fd < 0) {
                perror("Error");
                exit(-1);
        }
        gpio_map = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, BASE);
        if (gpio_map == MAP_FAILED) {
                perror("map failed");
                exit(-1);
        }
        gpio = (volatile unsigned int *)gpio_map;
        // gpio[2] = address of GPFSEL2
        // setting 21st bit to 1 set GPIO27 as an output
        gpio[2] |= (1 << 21);
        while (1) {
                // gpio[10] = address of GPCLR0
                gpio[10] |= (1 << 27);
                sleep(1);
                // gpio[7] = address of GPSET0
                gpio[7] |= (1 << 27);
                sleep(1);
        }

}

This code work but not with the given port, if I wire the LED on 27 nothing happens, but if I wire to 22 (the pin just below 27 in the GPIO schema) it will work, and it's the same with other port, I tried with port 17 and it will work with 27. I check the physical connection and it's seems good. I use a raspberry pi 4B. (Documentation)

enter image description here enter image description here

3
  • Edit your question to show a photo of your connections and which Pi model are you using.
    – joan
    Mar 30 at 17:27
  • Uncommented code which is full of magic numbers is impossible to debug. Is there any reason you are writing raw code to access GPIO rather than one of the libraries? If you want to write your own code I suggest creating functions to perform the basic steps. There are many examples.
    – Milliways
    Mar 31 at 1:04
  • NOTE the listed code may be confusing BUT it does work. Whatever problem you may have it is not code. Have you tried any diagnostics e.g. listing actual GPIO states?
    – Milliways
    Apr 1 at 3:06

2 Answers 2

1

From your description, my best guess is that your extension board connector is off by one row.

The code looks ok to me, and I don't see how a coding error could produce the 27->22 and 17->27 mis-mappings you describe, but a 1 pin misalignment on the connector could.

FWIW, if you want to test your hardware setup you can use the libgpiod v2 tools to blink the lead for you:

gpioset -t1s,1s GPIO27=1
0

If you want to write your own code I suggest you avoid the magic numbers (which are error prone and almost impossible for anyone to read).

I have listed a fragment of my code which may help. (NOTE this is not intended to be complete or executable code.)

#define FSEL_OFFSET 0          // 0x0000
#define SET_OFFSET 7           // 0x001c / 4
#define CLR_OFFSET 10          // 0x0028 / 4

void setup_gpio(int gpio, int direction, int pud) {
  // Set gpio as an input or an output
  //        direction: 0=IN, 1=OUT
  //        pud: 0=None 1=Up 2=Down
  int offset = FSEL_OFFSET + (gpio / 10);
  int shift = (gpio % 10) * 3;
  set_pullupdn(gpio, pud);
  if (direction) { //  OUTPUT
    *(gpio_map + offset) =
        (*(gpio_map + offset) & ~(7 << shift)) | (1 << shift);
  } else { // INPUT
    *(gpio_map + offset) = (*(gpio_map + offset) & ~(7 << shift));
  }
}

void output_gpio(int gpio, int value) {
  //        Output to a GPIO channel
  //        value - 0/1 or False/True or LOW/HIGH
  int offset, shift;

  if (value) // value == HIGH
    offset = SET_OFFSET + (gpio / 32);
  else // value == LOW
    offset = CLR_OFFSET + (gpio / 32);

  shift = (gpio % 32);

  *(gpio_map + offset) = 1 << shift;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.