Hi Tomp, Here the edited hal_gpio.c, it required 2 files from MachineKit, copy it to linuxcnc/src/hal/drivers folder. then u can start build it.
Pls. check the Makefile also, search for hal_gpio. Regards, KL Chin On Friday, 17 August 2018 10:03:25 UTC+8, TJoseph Powderly wrote: > > Hello > > i could not get hal_gpio inputs to work > > until > > (doh!) > > addf hal_gpio.read threadname > > arrgh! i spent days building systems and failing because of that omission. > > -----------this works great----------------- > > # hal_gpioTestAllInputs.hal > > # next line allows all gpio pins and makes them all Inputs > > loadrt hal_gpio exclude=0 dir=0 > > newthread fast 100000 > newthread slow 1000000 fp > > #loadusr halmeter > > # new vvv > addf hal_gpio.read fast > # new ^^^ > > addf hal_gpio.write fast > > # beware inputs are floating and wild, an external 10K to gnd will tame > them > start > > ---------------eof------------------------ > > thanks to all tomp > > -- website: http://www.machinekit.io blog: http://blog.machinekit.io github: https://github.com/machinekit --- You received this message because you are subscribed to the Google Groups "Machinekit" group. To unsubscribe from this group and stop receiving emails from it, send an email to machinekit+unsubscr...@googlegroups.com. Visit this group at https://groups.google.com/group/machinekit. For more options, visit https://groups.google.com/d/optout.
/******************************************************************** * Description: hal_gpio.c * Driver for the Raspberry Pi GPIO pins * * Author: Michael Haberler * License: GPL Version 2 * Copyright (c) 2012. * * some code taken from the bcm2835 library by:: * * Author: Mike McCauley (mi...@open.com.au) * Copyright (C) 2011 Mike McCauley * see http://www.open.com.au/mikem/bcm2835/ * Copyright (c) 2012 Ben Croston - cpuinfo.* * * Last change: made work for Raspberry2 9/2015 Michael Haberler s********************************************************************/ #include "rtapi.h" /* RTAPI realtime OS API */ #include "rtapi_bitops.h" #include "rtapi_app.h" /* RTAPI realtime module decls */ /* this also includes config.h */ #include "hal.h" /* HAL public API decls */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <errno.h> // copy these 2 file from MachineKit #include "bcm2835.h" #include "cpuinfo.h" MODULE_AUTHOR("Michael Haberler"); MODULE_DESCRIPTION("Driver for Raspberry Pi GPIO pins"); MODULE_LICENSE("GPL"); // adding this line will required to remove copied in this fill // #define MODNAME "hal_bb_gpio" // RTAPI_BIT only in MachineKit, so have to add this line #define RTAPI_BIT(nr) (1UL << (nr)) #define BCM2708_PERI_BASE 0x20000000 #define BCM2708_GPIO_BASE (BCM2708_PERI_BASE + 0x200000) #define BCM2709_PERI_BASE 0x3F000000 #define BCM2709_GPIO_BASE (BCM2709_PERI_BASE + 0x200000) // for LinuxCNC build, so #error must removed #if !defined(BUILD_SYS_USER_DSO) // #error "This driver is for usermode threads only" #endif #if !defined(TARGET_PLATFORM_RASPBERRY) // #error "This driver is for the Raspberry and Raspberry2 platforms only" #endif // http://elinux.org/index.php?title=RPi_Low-level_peripherals&printable=yes // Rev 1 Raspberry: static unsigned char rev1_gpios[] = {0, 1, 4, 7, 8, 9, 10, 11, 14, 15, 17, 18, 21, 22, 23, 24, 25}; static unsigned char rev1_pins[] = {3, 5, 7, 26, 24, 21, 19, 23, 8, 10, 11, 12, 13, 15, 16, 18, 22}; // Rev2 Raspberry: static unsigned char rev2_gpios[] = {2, 3, 4, 7, 8, 9, 10, 11, 14, 15, 17, 18, 22, 23, 24, 25, 27}; static unsigned char rev2_pins[] = {3, 5, 7, 26, 24, 21, 19, 23, 8, 10, 11, 12, 15, 16, 18, 22, 13}; // Raspberry2/3: static unsigned char rpi2_gpios[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 21, 23, 24, 25, 26, 27 }; static unsigned char rpi2_pins[] = {3, 5, 7, 29, 31, 26, 24, 21, 19, 23, 32, 33, 8, 10, 36, 11, 12, 35, 38, 15, 40, 16, 18, 22, 37, 13 }; static int npins; static int mem_fd; // I/O access static volatile unsigned *gpio; // port direction bits, 1=output static char *dir = "-1"; // all output RTAPI_MP_STRING(dir, "port direction, 1=output"); static unsigned dir_map; // exclude pins from usage static char *exclude = "0"; // all used RTAPI_MP_STRING(exclude, "exclude pins, 1=dont use"); static unsigned exclude_map; static int comp_id; /* component ID */ static unsigned char *pins, *gpios; hal_bit_t **port_data; static void write_port(void *arg, long period); static void read_port(void *arg, long period); static __inline__ uint32_t bcm2835_peri_read(volatile uint32_t* paddr) { // Make sure we dont return the _last_ read which might get lost // if subsequent code changes to a different peripheral uint32_t ret = *paddr; volatile uint32_t dummy = *paddr; return ret; } // Read input pin static __inline__ uint8_t bcm2835_gpio_lev(uint8_t pin) { volatile uint32_t* paddr = gpio + BCM2835_GPLEV0/4 + pin/32; uint8_t shift = pin % 32; uint32_t value = bcm2835_peri_read(paddr); return (value & (1 << shift)) ? HIGH : LOW; } static __inline__ void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value) { // Make sure we don't rely on the first write, which may get // lost if the previous access was to a different peripheral. *paddr = value; *paddr = value; } // Set output pin static __inline__ void bcm2835_gpio_set(uint8_t pin) { volatile uint32_t* paddr = gpio + BCM2835_GPSET0/4 + pin/32; uint8_t shift = pin % 32; bcm2835_peri_write(paddr, 1 << shift); } // Clear output pin static __inline__ void bcm2835_gpio_clr(uint8_t pin) { volatile uint32_t* paddr = gpio + BCM2835_GPCLR0/4 + pin/32; uint8_t shift = pin % 32; bcm2835_peri_write(paddr, 1 << shift); } // Set/clear only the bits in value covered by the mask static __inline__ void bcm2835_peri_set_bits(volatile uint32_t* paddr, uint32_t value, uint32_t mask) { uint32_t v = bcm2835_peri_read(paddr); v = (v & ~mask) | (value & mask); bcm2835_peri_write(paddr, v); } char *get_cpuinfo_revision(char *revision) { FILE *fp; char buffer[1024]; char hardware[1024]; int rpi_found = 0; if ((fp = fopen("/proc/cpuinfo", "r")) == NULL) return 0; while(!feof(fp)) { fgets(buffer, sizeof(buffer) , fp); sscanf(buffer, "Hardware : %s", hardware); if (strcmp(hardware, "BCM2708") == 0) rpi_found = 1; else if (strcmp(hardware, "BCM2709") == 0) rpi_found = 1; else if (strcmp(hardware, "BCM2835") == 0) rpi_found = 1; sscanf(buffer, "Revision : %s", revision); } fclose(fp); if (!rpi_found) revision = NULL; return revision; } int get_rpi_revision(void) { char revision[1024] = {'\0'}; if (get_cpuinfo_revision(revision) == NULL) return -1; if ((strcmp(revision, "0002") == 0) || (strcmp(revision, "1000002") == 0 ) || (strcmp(revision, "0003") == 0) || (strcmp(revision, "1000003") == 0 )) return 1; else if ((strcmp(revision, "0004") == 0) || (strcmp(revision, "1000004") == 0 ) || (strcmp(revision, "0005") == 0) || (strcmp(revision, "1000005") == 0 ) || (strcmp(revision, "0006") == 0) || (strcmp(revision, "1000006") == 0 )) return 2; else if ((strcmp(revision, "a01041") == 0) || (strcmp(revision, "a21041") == 0) || (strcmp(revision, "a22042") == 0)) return 3; else if ((strcmp(revision, "a22082") == 0) || (strcmp(revision, "2a22082") == 0) || (strcmp(revision, "a02082") == 0) || (strcmp(revision, "a32082") == 0) || (strcmp(revision, "a020d3") == 0)) return 4; else // assume rev 5 return 5; } // Function select // pin is a BCM2835 GPIO pin number NOT RPi pin number // There are 6 control registers, each control the functions of a block // of 10 pins. // Each control register has 10 sets of 3 bits per GPIO pin: // // 000 = GPIO Pin X is an input // 001 = GPIO Pin X is an output // 100 = GPIO Pin X takes alternate function 0 // 101 = GPIO Pin X takes alternate function 1 // 110 = GPIO Pin X takes alternate function 2 // 111 = GPIO Pin X takes alternate function 3 // 011 = GPIO Pin X takes alternate function 4 // 010 = GPIO Pin X takes alternate function 5 // // So the 3 bits for port X are: // X / 10 + ((X % 10) * 3) void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode) { // Function selects are 10 pins per 32 bit word, 3 bits per pin volatile uint32_t* paddr = gpio + BCM2835_GPFSEL0/4 + (pin/10); uint8_t shift = (pin % 10) * 3; uint32_t mask = BCM2835_GPIO_FSEL_MASK << shift; uint32_t value = mode << shift; bcm2835_peri_set_bits(paddr, value, mask); } static int setup_gpiomem_access(void) { if ((mem_fd = open("/dev/gpiomem", O_RDWR|O_SYNC)) < 0) { rtapi_print_msg(RTAPI_MSG_ERR,"HAL_GPIO: can't open /dev/gpiomem: %d - %s", errno, strerror(errno)); return -1; } gpio = mmap(NULL, BCM2835_BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0); if (gpio == MAP_FAILED) { close(mem_fd); mem_fd = -1; rtapi_print_msg(RTAPI_MSG_ERR, "HAL_GPIO: mmap failed: %d - %s\n", errno, strerror(errno)); return -1; } return 0; } static int setup_gpio_access(int rev, int ncores) { // open /dev/mem if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { rtapi_print_msg(RTAPI_MSG_ERR,"HAL_GPIO: can't open /dev/mem: %d - %s", errno, strerror(errno)); return -1; } if (rev <= 2 || ncores <= 2) gpio = mmap(NULL, BCM2835_BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, BCM2708_GPIO_BASE); else gpio = mmap(NULL, BCM2835_BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, BCM2709_GPIO_BASE); if (gpio == MAP_FAILED) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL_GPIO: mmap failed: %d - %s\n", errno, strerror(errno)); return -1;; } return 0; } static int number_of_cores(void) { char str[256]; int procCount = 0; FILE *fp; if( (fp = fopen("/proc/cpuinfo", "r")) ) { while(fgets(str, sizeof str, fp)) if( !memcmp(str, "processor", 9) ) procCount++; } if ( !procCount ) { rtapi_print_msg(RTAPI_MSG_ERR,"HAL_GPIO: Unable to get proc count. Defaulting to 2"); procCount = 2; } return procCount; } int rtapi_app_main(void) { int n, retval = 0; int rev, ncores, pinno; char *endptr; if ((rev = get_rpi_revision()) < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "unrecognized Raspberry revision, see /proc/cpuinfo\n"); return -EINVAL; } ncores = number_of_cores(); rtapi_print_msg(RTAPI_MSG_INFO, "%d cores rev %d", ncores, rev); switch (rev) { case 4: rtapi_print_msg(RTAPI_MSG_INFO, "Raspberry3\n"); pins = rpi2_pins; gpios = rpi2_gpios; npins = sizeof(rpi2_pins); break; case 3: rtapi_print_msg(RTAPI_MSG_INFO, "Raspberry2\n"); pins = rpi2_pins; gpios = rpi2_gpios; npins = sizeof(rpi2_pins); break; case 1: rtapi_print_msg(RTAPI_MSG_INFO, "Raspberry1 rev 1.0\n"); pins = rev1_pins; gpios = rev1_gpios; npins = sizeof(rev1_pins); break; case 2: rtapi_print_msg(RTAPI_MSG_INFO, "Raspberry1 Rev 2.0\n"); pins = rev2_pins; gpios = rev2_gpios; npins = sizeof(rev2_pins); break; default: rtapi_print_msg(RTAPI_MSG_ERR, "HAL_GPIO: ERROR: board revision %d not supported\n", rev); return -EINVAL; } port_data = hal_malloc(npins * sizeof(void *)); if (port_data == 0) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL_GPIO: ERROR: hal_malloc() failed\n"); hal_exit(comp_id); return -1; } if (dir == 0) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL_GPIO: ERROR: no config string\n"); return -1; } dir_map = strtoul(dir, &endptr,0); if (*endptr) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL_GPIO: dir=%s - trailing garbage: '%s'\n", dir, endptr); return -1; } if (exclude == 0) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL_GPIO: ERROR: no exclude string\n"); return -1; } exclude_map = strtoul(exclude, &endptr,0); if (*endptr) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL_GPIO: exclude=%s - trailing garbage: '%s'\n", exclude, endptr); return -1; } if (setup_gpiomem_access()) { if (setup_gpio_access(rev, ncores)) return -1; } comp_id = hal_init("hal_gpio"); if (comp_id < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL_GPIO: ERROR: hal_init() failed\n"); return -1; } for (n = 0; n < npins; n++) { if (exclude_map & RTAPI_BIT(n)) continue; pinno = pins[n]; if (dir_map & RTAPI_BIT(n)) { bcm2835_gpio_fsel(gpios[n], BCM2835_GPIO_FSEL_OUTP); if ((retval = hal_pin_bit_newf(HAL_IN, &port_data[n], comp_id, "hal_gpio.pin-%02d-out", pinno)) < 0) break; } else { bcm2835_gpio_fsel(gpios[n], BCM2835_GPIO_FSEL_INPT); if ((retval = hal_pin_bit_newf(HAL_OUT, &port_data[n], comp_id, "hal_gpio.pin-%02d-in", pinno)) < 0) break; } } if (retval < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL_GPIO: ERROR: pin %d export failed with err=%i\n", n,retval); hal_exit(comp_id); return -1; } retval = hal_export_funct("hal_gpio.write", write_port, 0, 0, 0, comp_id); if (retval < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL_GPIO: ERROR: write funct export failed\n"); hal_exit(comp_id); return -1; } retval = hal_export_funct("hal_gpio.read", read_port, 0, 0, 0, comp_id); if (retval < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "HAL_GPIO: ERROR: read funct export failed\n"); hal_exit(comp_id); return -1; } rtapi_print_msg(RTAPI_MSG_INFO, "HAL_GPIO: installed driver\n"); hal_ready(comp_id); return 0; } void rtapi_app_exit(void) { if (gpio) munmap((void *) gpio, BCM2835_BLOCK_SIZE); if (mem_fd > -1) close(mem_fd); hal_exit(comp_id); } static void write_port(void *arg, long period) { int n; for (n = 0; n < npins; n++) { if (exclude_map & RTAPI_BIT(n)) continue; if (dir_map & RTAPI_BIT(n)) { if (*(port_data[n])) { bcm2835_gpio_set(gpios[n]); } else { bcm2835_gpio_clr(gpios[n]); } } } } static void read_port(void *arg, long period) { int n; for (n = 0; n < npins; n++) { if ((~dir_map & RTAPI_BIT(n)) && (~exclude_map & RTAPI_BIT(n))) *port_data[n] = bcm2835_gpio_lev(gpios[n]); } }
Makefile
Description: Binary data