-

CommentStreams:61968edb8e8ef0d52ec61e7d3c4ae14b

From Geekworm Wiki
< 2.8 inch Touch Screen for Pi zero
Revision as of 13:28, 2 May 2020 by Negens (talk | contribs) (Migrated comment #933)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Hello,

After digging a lot, I made it. Forget the raspi-gpio program. I could never install it because of the messy buggy nodejs package.

Here is the method I used :


Create a file "gpio_alt.c" :

==========================================

/* Utility to switch Raspberry-Pi GPIO pin functions Tim Giles 01/04/2013

Usage: $ gpio_alt -p PIN_NUMBER -f ALT_NUMBER

Based on RPi code from Dom and Gert, 15-Feb-2013, <http://elinux.org/RPi_Low-level_peripherals#C_2> and Gnu getopt() example <http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html#Example-of-Getopt>

  • /
  1. include <ctype.h>
  2. include <stdio.h>
  3. include <stdlib.h>
  4. include <unistd.h>
  5. include <fcntl.h>
  6. include <sys/mman.h>
  1. define BCM2708_PERI_BASE 0x20000000
  2. define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
  3. define PAGE_SIZE (4*1024)
  4. define BLOCK_SIZE (4*1024)

int mem_fd; void *gpio_map; volatile unsigned *gpio; void setup_io();

// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)

  1. define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
  2. define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
  3. define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
  1. define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0
  2. define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0


int main (int argc, char **argv) {

 int opt, flag, n_pin, n_alt;
 flag=0;
 while ((opt = getopt (argc, argv, "hp:f:")) != -1) {
   switch (opt) {
   case 'h':
     break;
   case 'p':
     n_pin = atoi(optarg); flag |= 0b0001; break;
   case 'f':
     n_alt = atoi(optarg); flag |= 0b0010; break;
   case '?':
     // getopt() prints error messages, so don't need to repeat them here
     return 1;
   default:
     abort ();
   }
 }
 
 if (flag != 0b0011) {
   fprintf (stderr, "Usage:\n$ gpio_alt -p PIN_NUM -f FUNC_NUM\n");
   return 1;
 }
 
 setup_io(); // Set up gpi pointer for direct register access
 INP_GPIO(n_pin);  // Always use INP_GPIO(x) before using SET_GPIO_ALT(x,y)
 SET_GPIO_ALT(n_pin, n_alt);
 
 printf("Set pin %i to alternative-function %i\n", n_pin, n_alt);
 
 return 0;

}


void setup_io() {

  /* open /dev/mem */
  if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
     printf("can't open /dev/mem \n");
     exit(-1);
  }
  /* mmap GPIO */
  gpio_map = mmap(
     NULL,             //Any adddress in our space will do
     BLOCK_SIZE,       //Map length
     PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
     MAP_SHARED,       //Shared with other processes
     mem_fd,           //File to map
     GPIO_BASE         //Offset to GPIO peripheral
  );
  close(mem_fd); //No need to keep mem_fd open after mmap
  if (gpio_map == MAP_FAILED) {
     printf("mmap error %d\n", (int)gpio_map);//errno also set!
     exit(-1);
  }
  // Always use volatile pointer!
  gpio = (volatile unsigned *)gpio_map;

}

=======================

Then run following commands to compile and copy it on PATH : gcc gpio_alt.c -o gpio_alt sudo chown root:root gpio_alt sudo chmod u+s gpio_alt sudo mv gpio_alt /usr/local/bin/


Create a systemd file /etc/systemd/system/mzdpi.service

=========================

[Unit] Description=mzdpi screen blue yellow fix service

[Service] Type=oneshot ExecStart=/usr/local/bin/gpio_alt -p 7 -f 2 ; /usr/local/bin/gpio_alt -p 8 -f 2

[Install] WantedBy=multi-user.target Alias=mzdpi.service

=========================

systemctl daemon-reload systemctl enable mzdpi.service