예제 #1
0
static int gpio_wait(int pin)
{
	char path[BUFFER_MAX];
	int fd;
 
	snprintf(path, BUFFER_MAX, "/sys/class/gpio/gpio%d/value", pin);
	fd = open(path, O_RDONLY);
	if (-1 == fd) {
		fprintf(stderr, "Failed to open gpio for reading!\n");
		return -1;
	}

	read(fd, path, 3);

	struct pollfd p = {
		.fd = fd,
		.events = POLLPRI|POLLERR,
	};

	int r = poll(&p, 1, -1);
	if(r != 1) {
		fprintf(stderr, "poll() failed!\n");
		close(fd);
		return -1;
	}

	close(fd);
	return 0;
}
 
 
int main(int argv, char** argc)
{
	if(gpio_export(PIN)) {
		return 1;
	}

	gpio_direction(PIN, IN);

	setup();
	setup_gpio(POUT, OUTPUT, PUD_OFF);

	while(1) {
		gpio_edge(PIN, RISING);
		gpio_wait(PIN);
		output_gpio(POUT, HIGH);
		gpio_edge(PIN, FALLING);
		gpio_wait(PIN);
		output_gpio(POUT, LOW);
	}

	if(gpio_unexport(PIN)) {
		return 1;
	}

	return 0;
}
예제 #2
0
파일: pi_gpio.c 프로젝트: mokele/pihwm
int
gpio_set_int (unsigned int pin, void (*isr) (int), char *mode)
{
	/* Details of the ISR */
	isr_t *i = (isr_t *) malloc(sizeof (isr_t));
	i->pin = pin;
	i->isr = isr;

	/* Set up interrupt */
	gpio_edge(pin, mode);

	/* Set isr_handler flag and create thread
	TODO: check for errors using retval */
	isr_handler_flag = 1;
	pthread_create(&isr_handler_thread, NULL, isr_handler, (void *) i);
	pthread_tryjoin_np(isr_handler_thread, NULL);

	return 1;
}
예제 #3
0
int main(int argc, char **argv) {
    pthread_t pth;
    int opt;
    struct ifreq ifr;
    struct trigger_t trigger_data;
    struct sockaddr_can caddr;
    fd_set readfds, exceptfds;
    struct can_frame frame;
    uint16_t member;
    uint8_t buffer[MAXLEN];

    memset(&trigger_data, 0, sizeof(trigger_data));
    memset(ifr.ifr_name, 0, sizeof(ifr.ifr_name));
    strcpy(ifr.ifr_name, "can0");

    trigger_data.led_pin = -1;
    trigger_data.pb_pin = -1;

    trigger_data.interval = DEF_INTERVAL;

    while ((opt = getopt(argc, argv, "i:l:p:t:fvh?")) != -1) {
	switch (opt) {
	case 'i':
	    strncpy(ifr.ifr_name, optarg, sizeof(ifr.ifr_name));
	    break;
	case 't':
	    trigger_data.interval = atoi(optarg);
	    break;
	case 'l':
	    trigger_data.led_pin = atoi(optarg);
	    break;
	case 'p':
	    trigger_data.pb_pin = atoi(optarg);
	    break;
	case 'v':
	    trigger_data.verbose = 1;
	    break;
	case 'f':
	    trigger_data.background = 0;
	    break;
	case 'h':
	case '?':
	    usage(basename(argv[0]));
	    exit(EXIT_SUCCESS);
	default:
	    usage(basename(argv[0]));
	    exit(EXIT_FAILURE);
	}
    }

    /* prepare CAN socket */
    if ((trigger_data.socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
	fprintf(stderr, "error creating CAN socket: %s\n", strerror(errno));
	exit(EXIT_FAILURE);
    }

    memset(&caddr, 0, sizeof(caddr));
    caddr.can_family = AF_CAN;
    if (ioctl(trigger_data.socket, SIOCGIFINDEX, &ifr) < 0) {
	fprintf(stderr, "setup CAN socket error: %s %s\n", strerror(errno), ifr.ifr_name);
	exit(EXIT_FAILURE);
    }
    caddr.can_ifindex = ifr.ifr_ifindex;

    if (bind(trigger_data.socket, (struct sockaddr *)&caddr, sizeof(caddr)) < 0) {
	fprintf(stderr, "error binding CAN socket: %s\n", strerror(errno));
	exit(EXIT_FAILURE);
    }

    trigger_data.caddr = caddr;

    /* Create thread if LED pin defined */
    if ((trigger_data.led_pin) > 0) {
	trigger_data.led_pattern = LED_ST_HB_SLOW;
	gpio_export(trigger_data.led_pin);
	gpio_direction(trigger_data.led_pin, 0);

	if (pthread_mutex_init(&lock, NULL)) {
	    fprintf(stderr, "can't init mutex %s\n", strerror(errno));
	    exit(EXIT_FAILURE);
	}

	if (pthread_create(&pth, NULL, LEDMod, &trigger_data)) {
	    fprintf(stderr, "can't create pthread %s\n", strerror(errno));
	    exit(EXIT_FAILURE);
	}
	if (!trigger_data.background && trigger_data.verbose)
	    printf("created LED thread\n");
    }

    if (trigger_data.background) {
	pid_t pid;

	/* fork off the parent process */
	pid = fork();
	if (pid < 0) {
	    exit(EXIT_FAILURE);
	}
	/* if we got a good PID, then we can exit the parent process. */
	if (pid > 0) {
	    if (trigger_data.verbose)
		printf("Going into background ...\n");
	    exit(EXIT_SUCCESS);
	}
    }

    /* initialize push button */
    if ((trigger_data.pb_pin) > 0) {
	/* first free pin */
	gpio_unexport(trigger_data.pb_pin);
	gpio_export(trigger_data.pb_pin);
	gpio_direction(trigger_data.pb_pin, 1);
	gpio_edge(trigger_data.pb_pin, EDGE_FALLING);
	trigger_data.pb_fd = gpio_open(trigger_data.pb_pin);
    }

    FD_ZERO(&readfds);
    FD_ZERO(&exceptfds);
    /* delete pending push button event */
    if ((trigger_data.pb_pin) > 0) {
	read(trigger_data.pb_fd, NULL, 100);
	lseek(trigger_data.pb_fd, 0, SEEK_SET);
    }
    /* loop forever TODO: if interval is set */
    while (1) {
	FD_SET(trigger_data.socket, &readfds);
	/* extend FD_SET only if push button pin is set */
	if (trigger_data.pb_pin > 0)
	    FD_SET(trigger_data.pb_fd, &exceptfds);
	if (select(MAX(trigger_data.socket, trigger_data.pb_fd) + 1, &readfds, NULL, &exceptfds, NULL) < 0) {
	    fprintf(stderr, "select error: %s\n", strerror(errno));
	    exit(EXIT_FAILURE);
	}
	/* CAN frame event */
	if (FD_ISSET(trigger_data.socket, &readfds)) {
	    if (read(trigger_data.socket, &frame, sizeof(struct can_frame)) < 0)
		fprintf(stderr, "error reading CAN frame: %s\n", strerror(errno));

	    if (frame.can_id & CAN_EFF_FLAG) {
		switch ((frame.can_id & 0x00FF0000UL) >> 16) {
		case 0x31:
		    if (trigger_data.verbose)
			print_can_frame(F_CAN_FORMAT_STRG, &frame);
		    memcpy(&member, frame.data, sizeof(member));
		    member = ntohs(member);
		    /* look for MS2 */
		    if ((member & 0xfff0) == 0x4d50)
			get_ms2_dbsize(&trigger_data);
		    break;
		case 0x41:
		    if (trigger_data.verbose)
			print_can_frame(F_CAN_FORMAT_STRG, &frame);
		    break;
		case 0x42:
		    get_data(&trigger_data, &frame);
		    /* if (trigger_data.verbose)
		       print_can_frame(F_CAN_FORMAT_STRG, &frame); */
		    break;
		default:
		    if (trigger_data.verbose)
			print_can_frame(F_CAN_FORMAT_STRG, &frame);
		    break;
		}
	    }
	}
	/* push button event */
	if (FD_ISSET(trigger_data.pb_fd, &exceptfds)) {
	    set_led_pattern(&trigger_data, LED_ST_HB_FAST);

	    /* wait some time for LED pattern change */
	    usec_sleep(1000 * 1000);
	    /* send CAN Member Ping */
	    frame.can_id = 0x00300300;
	    frame.can_dlc = 0;
	    memset(frame.data, 0, 8);
	    if (send_can_frame(trigger_data.socket, &frame, trigger_data.verbose) < 0)
		fprintf(stderr, "can't send CAN Member Ping: %s\n", strerror(errno));

	    lseek(trigger_data.pb_fd, 0, SEEK_SET);
	    if (read(trigger_data.pb_fd, buffer, sizeof(buffer)) < 0)
		fprintf(stderr, "error reading GPIO status: %s\n", strerror(errno));
	    printf("push button event\n");
	}
    }

    /* TODO : wait until copy is done */

    if ((trigger_data.pb_pin) > 0)
	gpio_unexport(trigger_data.pb_pin);
    if ((trigger_data.led_pin) > 0) {
	gpio_unexport(trigger_data.led_pin);
	pthread_join(pth, (void *)&trigger_data);
	pthread_mutex_unlock(&lock);
    }
    return 0;
}