int libsoc_gpio_wait_interrupt (gpio * gpio, int timeout) { if (gpio == NULL) { libsoc_gpio_debug (__func__, -1, "invalid gpio pointer"); return LS_INT_ERROR; } if (libsoc_gpio_get_direction (gpio) != INPUT) { libsoc_gpio_debug (__func__, gpio->gpio, "gpio is not set as input"); return LS_INT_ERROR; } gpio_edge test_edge = libsoc_gpio_get_edge (gpio); if (test_edge == EDGE_ERROR || test_edge == NONE) { libsoc_gpio_debug (__func__, gpio->gpio, "edge must be FALLING, RISING or BOTH"); return LS_INT_ERROR; } return libsoc_gpio_poll(gpio, timeout); }
int main() { gpio *gpio_led; gpio_led = libsoc_gpio_request(GPIO_LED, LS_SHARED); if ((gpio_led == NULL)) { fprintf(stderr, "Unable to request GPIOs\n"); goto fail; } libsoc_gpio_set_direction(gpio_led, OUTPUT); if ((libsoc_gpio_get_direction(gpio_led) != OUTPUT)) { fprintf(stderr, "Unable to set led/btn directions\n"); goto fail; } while (1) { libsoc_gpio_set_level(gpio_led, 1); usleep(500000); libsoc_gpio_set_level(gpio_led, 0); usleep(500000); } fail: if (gpio_led) libsoc_gpio_free(gpio_led); return EXIT_SUCCESS; }
int libsoc_gpio_wait_interrupt (gpio * gpio, int timeout) { if (gpio == NULL) { libsoc_gpio_debug (__func__, -1, "invalid gpio pointer"); return EDGE_ERROR; } if (libsoc_gpio_get_direction (gpio) != INPUT) { libsoc_gpio_debug (__func__, gpio->gpio, "gpio is not set as input"); return EXIT_FAILURE; } gpio_edge test_edge = libsoc_gpio_get_edge (gpio); if (test_edge == EDGE_ERROR || test_edge == NONE) { libsoc_gpio_debug (__func__, gpio->gpio, "edge must be FALLING, RISING or BOTH"); return EXIT_FAILURE; } struct pollfd pfd[1]; char buffer[1]; pfd[0].fd = gpio->value_fd; pfd[0].events = POLLPRI; pfd[0].revents = 0; // Read data for clean initial poll lseek (pfd[0].fd, 0, SEEK_SET); read (pfd[0].fd, buffer, 1); int ready = poll (pfd, 1, timeout); int ret; switch (ready) { case -1: libsoc_gpio_debug (__func__, gpio->gpio, "poll failed"); perror ("libsoc-gpio-debug"); ret = EXIT_FAILURE; break; case 0: ret = EXIT_FAILURE; break; default: ret = EXIT_SUCCESS; break; } return ret; }
int gpio_handler(uint16_t cport_id, uint16_t hd_cport_id, void *rbuf, size_t rsize, void *tbuf, size_t tsize) { struct gb_operation_msg_hdr *oph; struct op_msg *op_req = rbuf; struct op_msg *op_rsp; size_t payload_size; uint16_t message_size; ssize_t nbytes; op_rsp = (struct op_msg *)tbuf; oph = (struct gb_operation_msg_hdr *)&op_req->header; switch (oph->type) { case GB_REQUEST_TYPE_PROTOCOL_VERSION: payload_size = sizeof(struct gb_protocol_version_response); op_rsp->pv_rsp.major = GREYBUS_VERSION_MAJOR; op_rsp->pv_rsp.minor = GREYBUS_VERSION_MINOR; break; case GB_GPIO_TYPE_LINE_COUNT: payload_size = sizeof(struct gb_gpio_line_count_response); op_rsp->gpio_lc_rsp.count = 5; /* Something arbitrary, but useful */ break; case GB_GPIO_TYPE_ACTIVATE: payload_size = 0; gbsim_debug("GPIO %d activate request\n ", op_req->gpio_act_req.which); break; case GB_GPIO_TYPE_DEACTIVATE: payload_size = 0; gbsim_debug("GPIO %d deactivate request\n ", op_req->gpio_deact_req.which); break; case GB_GPIO_TYPE_GET_DIRECTION: payload_size = sizeof(struct gb_gpio_get_direction_response); if (bbb_backend) op_rsp->gpio_get_dir_rsp.direction = libsoc_gpio_get_direction(gpios[op_req->gpio_dir_output_req.which]); else op_rsp->gpio_get_dir_rsp.direction = gpio_dir[op_req->gpio_get_dir_req.which]; gbsim_debug("GPIO %d get direction (%d) response\n ", op_req->gpio_get_dir_req.which, op_rsp->gpio_get_dir_rsp.direction); break; case GB_GPIO_TYPE_DIRECTION_IN: payload_size = 0; gbsim_debug("GPIO %d direction input request\n ", op_req->gpio_dir_input_req.which); if (bbb_backend) libsoc_gpio_set_direction(gpios[op_req->gpio_dir_output_req.which], INPUT); else gpio_dir[op_req->gpio_dir_output_req.which] = 0; break; case GB_GPIO_TYPE_DIRECTION_OUT: payload_size = 0; gbsim_debug("GPIO %d direction output request\n ", op_req->gpio_dir_output_req.which); if (bbb_backend) libsoc_gpio_set_direction(gpios[op_req->gpio_dir_output_req.which], OUTPUT); else gpio_dir[op_req->gpio_dir_output_req.which] = 1; break; case GB_GPIO_TYPE_GET_VALUE: payload_size = sizeof(struct gb_gpio_get_value_response); if (bbb_backend) op_rsp->gpio_get_val_rsp.value = libsoc_gpio_get_level(gpios[op_req->gpio_dir_output_req.which]); else op_rsp->gpio_get_val_rsp.value = 1; gbsim_debug("GPIO %d get value (%d) response\n ", op_req->gpio_get_val_req.which, op_rsp->gpio_get_val_rsp.value); break; case GB_GPIO_TYPE_SET_VALUE: payload_size = 0; gbsim_debug("GPIO %d set value (%d) request\n ", op_req->gpio_set_val_req.which, op_req->gpio_set_val_req.value); if (bbb_backend) libsoc_gpio_set_level(gpios[op_req->gpio_set_val_req.which], op_req->gpio_set_val_req.value); break; case GB_GPIO_TYPE_SET_DEBOUNCE: payload_size = 0; gbsim_debug("GPIO %d set debounce (%d us) request\n ", op_req->gpio_set_db_req.which, op_req->gpio_set_db_req.usec); break; case GB_GPIO_TYPE_IRQ_TYPE: payload_size = 0; gbsim_debug("GPIO protocol IRQ type %d request\n ", op_req->gpio_irq_type_req.type); break; case GB_GPIO_TYPE_IRQ_MASK: payload_size = 0; break; case GB_GPIO_TYPE_IRQ_UNMASK: payload_size = 0; break; default: return -EINVAL; } message_size = sizeof(struct gb_operation_msg_hdr) + payload_size; nbytes = send_response(op_rsp, hd_cport_id, message_size, oph, PROTOCOL_STATUS_SUCCESS); if (nbytes) return nbytes; #define TEST_HACK #ifdef TEST_HACK /* Test GPIO interrupts by sending one when they become unmasked */ if (oph->type == GB_GPIO_TYPE_IRQ_UNMASK) { payload_size = sizeof(struct gb_gpio_irq_event_request); op_req->gpio_irq_event_req.which = 1; /* XXX HACK */ message_size = sizeof(struct gb_operation_msg_hdr) + payload_size; return send_request(op_req, hd_cport_id, message_size, 0, GB_GPIO_TYPE_IRQ_EVENT); } #endif return 0; }
int gpio_handler(struct gbsim_connection *connection, void *rbuf, size_t rsize, void *tbuf, size_t tsize) { struct gb_operation_msg_hdr *oph; struct op_msg *op_req = rbuf; struct op_msg *op_rsp; size_t payload_size; ssize_t nbytes; uint16_t message_size; uint16_t hd_cport_id = connection->hd_cport_id; uint8_t which = 0; int send_event = 0; op_rsp = (struct op_msg *)tbuf; oph = (struct gb_operation_msg_hdr *)&op_req->header; switch (oph->type) { case GB_GPIO_TYPE_LINE_COUNT: payload_size = sizeof(struct gb_gpio_line_count_response); op_rsp->gpio_lc_rsp.count = 5; /* Something arbitrary, but useful */ break; case GB_GPIO_TYPE_ACTIVATE: payload_size = 0; which = op_req->gpio_act_req.which; gbsim_debug("GPIO %d activate request\n", which); gb_gpios[which].activated = 1; break; case GB_GPIO_TYPE_DEACTIVATE: payload_size = 0; which = op_req->gpio_deact_req.which; gbsim_debug("GPIO %d deactivate request\n", which); gb_gpios[which].activated = 0; break; case GB_GPIO_TYPE_GET_DIRECTION: payload_size = sizeof(struct gb_gpio_get_direction_response); which = op_req->gpio_get_dir_req.which; if (bbb_backend) op_rsp->gpio_get_dir_rsp.direction = libsoc_gpio_get_direction(gpios[which]); else op_rsp->gpio_get_dir_rsp.direction = gb_gpios[which].direction; gbsim_debug("GPIO %d get direction (%d) response\n", which, op_rsp->gpio_get_dir_rsp.direction); break; case GB_GPIO_TYPE_DIRECTION_IN: payload_size = 0; which = op_req->gpio_dir_input_req.which; gbsim_debug("GPIO %d direction input request\n", which); if (bbb_backend) libsoc_gpio_set_direction(gpios[which], INPUT); else gb_gpios[which].direction = 1; break; case GB_GPIO_TYPE_DIRECTION_OUT: payload_size = 0; which = op_req->gpio_dir_output_req.which; gbsim_debug("GPIO %d direction output request\n", which); if (bbb_backend) libsoc_gpio_set_direction(gpios[which], OUTPUT); else gb_gpios[which].direction = 0; break; case GB_GPIO_TYPE_GET_VALUE: payload_size = sizeof(struct gb_gpio_get_value_response); which = op_req->gpio_get_val_req.which; if (bbb_backend) op_rsp->gpio_get_val_rsp.value = libsoc_gpio_get_level(gpios[which]); else op_rsp->gpio_get_val_rsp.value = gb_gpios[which].value; gbsim_debug("GPIO %d get value (%d) response\n ", which, op_rsp->gpio_get_val_rsp.value); break; case GB_GPIO_TYPE_SET_VALUE: payload_size = 0; which = op_req->gpio_set_val_req.which; gbsim_debug("GPIO %d set value (%d) request\n ", which, op_req->gpio_set_val_req.value); if (bbb_backend) libsoc_gpio_set_level(gpios[which], op_req->gpio_set_val_req.value); else send_event = gb_gpio_set_value(which, op_req->gpio_set_val_req.value); break; case GB_GPIO_TYPE_SET_DEBOUNCE: payload_size = 0; gbsim_debug("GPIO %d set debounce (%d us) request\n ", op_req->gpio_set_db_req.which, op_req->gpio_set_db_req.usec); break; case GB_GPIO_TYPE_IRQ_TYPE: payload_size = 0; which = op_req->gpio_irq_type_req.which; gbsim_debug("GPIO %d set IRQ type %d request\n ", which, op_req->gpio_irq_type_req.type); gb_gpios[which].irq_type = op_req->gpio_irq_type_req.type; break; case GB_GPIO_TYPE_IRQ_MASK: payload_size = 0; which = op_req->gpio_irq_mask_req.which; gb_gpios[which].irq_unmasked = 0; break; case GB_GPIO_TYPE_IRQ_UNMASK: payload_size = 0; which = op_req->gpio_irq_unmask_req.which; gb_gpios[which].irq_unmasked = 1; break; case GB_REQUEST_TYPE_CPORT_SHUTDOWN: payload_size = 0; break; default: return -EINVAL; } message_size = sizeof(struct gb_operation_msg_hdr) + payload_size; nbytes = send_response(hd_cport_id, op_rsp, message_size, oph->operation_id, oph->type, PROTOCOL_STATUS_SUCCESS); if (nbytes) return nbytes; #define TEST_HACK #ifdef TEST_HACK /* * Test GPIO interrupts by sending one when they become unmasked, or * when set value trigger one */ if (send_event) { payload_size = sizeof(struct gb_gpio_irq_event_request); op_req->gpio_irq_event_req.which = which - 1; /* mask the irq to mimic fw action on event send */ gb_gpios[which - 1].irq_unmasked = 0; message_size = sizeof(struct gb_operation_msg_hdr) + payload_size; return send_request(hd_cport_id, op_req, message_size, 0, GB_GPIO_TYPE_IRQ_EVENT); } #endif return 0; }