ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
22 ноября
1324872 Топик полностью
Eddy_Em (27.06.2023 09:26, просмотров: 373) ответил Eddy_Em на Слегка светятся выключенные светодиоды на GPIO "Raspberry Pi"
В общем, я - ССЗБ! Пока так и сяк баловался, намешал сисвызовов старых и новых (gpio и gpio_v2). 

Сейчас работает. Такой простой проверочный код:

#include <fcntl.h>
#include <errno.h>
#include <inttypes.h>
#include <linux/gpio.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <time.h>
#include <unistd.h>

#define DEV_NAME "/dev/gpiochip0"

static void showstat(int nline, int fd){
	struct gpio_v2_line_info line_info;
	bzero(&line_info, sizeof(line_info));
    line_info.offset = nline;
    if(-1 == ioctl(fd, GPIO_V2_GET_LINEINFO_IOCTL, &line_info)){
        fprintf(stderr, "Unable to get line info from offset %d: %s\n", nline, strerror(errno));
        return;
    }
    const char *edge = "";
    uint64_t f = line_info.flags;
    if(f & (GPIO_V2_LINE_FLAG_EDGE_RISING | GPIO_V2_LINE_FLAG_EDGE_FALLING)){
    	if((GPIO_V2_LINE_FLAG_EDGE_RISING | GPIO_V2_LINE_FLAG_EDGE_FALLING) == f & (GPIO_V2_LINE_FLAG_EDGE_RISING | GPIO_V2_LINE_FLAG_EDGE_FALLING)) edge = ", BOTH EDGES";
    	else if (f & GPIO_V2_LINE_FLAG_EDGE_RISING) edge = ", RISING EDGE";
    	else edge = ", FALLING EDGE";
    }
    printf("offset: %d, name: %s, consumer: %s; nattrs: %d. Flags: %s%s%s%s%s%s%s%s%s%s%s%s%s\n",
           nline,
           line_info.name,
           line_info.consumer,
           line_info.num_attrs,
           (f & GPIO_V2_LINE_FLAG_OUTPUT ) ? "OUTPUT" : "",
           (f & GPIO_V2_LINE_FLAG_INPUT ) ? "INPUT" : "",
           (f & GPIO_V2_LINE_FLAG_ACTIVE_LOW) ? ", A_LOW" : ", A_HIGH",
           edge,
           (f & GPIO_V2_LINE_FLAG_OPEN_DRAIN) ? ", OPEN_DRAIN" : "",
           (f & GPIO_V2_LINE_FLAG_OPEN_SOURCE) ? ", OPEN_SOURCE" : "",
           (f & GPIO_V2_LINE_FLAG_BIAS_PULL_UP) ? ", PULLUP" : "",
           (f & GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN ) ? ", PULLDOWN" : "",
           (f & GPIO_V2_LINE_FLAG_BIAS_DISABLED) ? ", DISABLED" : "",
           (f & GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME) ? ", REALTIME" : "",
           (f & GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE) ? ", HTE" : "",
           (f &  GPIO_V2_LINE_FLAG_USED) ? ", " : ", NOT ", "USED");
}

int main(int argc, char **argv){
	const char *dev_name = DEV_NAME;
	if(argc == 1) dev_name = argv[1];
	int fd = open(DEV_NAME, O_RDONLY);
	if(fd < 0){
	    fprintf(stderr, "Unabled to open %s: %s", dev_name, strerror(errno));
	    return -1;
	}
	struct gpiochip_info info;

	// Query GPIO chip information
	if(-1 == ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &info)){
	    fprintf(stderr, "Unable to get chip info from ioctl: %s", strerror(errno));
	    close(fd);
	    return -1;
	}
	printf("Chip name: %s\n", info.name);
	printf("Chip label: %s\n", info.label);
	printf("Number of lines: %d\n", info.lines);

	struct gpio_v2_line_request rq;
	bzero(&rq, sizeof(rq));
	rq.offsets[0] = 17;
	rq.offsets[1] = 27;
	rq.offsets[2] = 22;
	snprintf(rq.consumer, GPIO_MAX_NAME_SIZE-1, "LEDs");
	rq.num_lines = 3;
	rq.config.flags = GPIO_V2_LINE_FLAG_OUTPUT | GPIO_V2_LINE_FLAG_OPEN_DRAIN | GPIO_V2_LINE_FLAG_ACTIVE_LOW;
	rq.config.num_attrs = 0;
	if(-1 == ioctl(fd, GPIO_V2_GET_LINE_IOCTL, &rq)){
	    fprintf(stderr, "Unable to get line ioctl: %s\n", strerror(errno));
	    close(fd);
	    return -1;
	}
	showstat(17, fd);
	showstat(27, fd);
	showstat(22, fd);
	struct gpio_v2_line_values values;
	bzero(&values, sizeof(values));
	values.mask = 7; values.bits = 1;
	ioctl(rq.fd, GPIO_V2_LINE_SET_VALUES_IOCTL, &values);
//#if 0
	for(int i = 0; i < 3; ++i) for(int bits = 0; bits < 8; ++bits){
		values.mask = 7;
		values.bits = (~bits) & 7;
		if(-1 == ioctl(rq.fd, GPIO_V2_LINE_SET_VALUES_IOCTL, &values)){
		    fprintf(stderr, "Unable to set values: %s\n", strerror(errno));
		    close(rq.fd);
		    return -1;
		}
		int xx = values.bits & 7, yy = values.mask;
		printf("SET: 0x%02x, mask=0x%02x\n", xx, yy);
		usleep(100000);
	}
//#endif
	close(rq.fd);
	close(fd);
	return 0;
}
eddy-em.livejournal.com github.com/eddyem