0

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. Commented Mar 30, 2023 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. Commented Mar 31, 2023 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? Commented Apr 1, 2023 at 3:06

1 Answer 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 you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.