diff --git a/gpio.c b/gpio.c index 9bc21cc..a37cbfc 100644 --- a/gpio.c +++ b/gpio.c @@ -18,6 +18,11 @@ 22 blue (15) */ +/* + 19 switch (35) + 26 switch (37) + */ + #define RED 0b001 #define GREEN 0b010 #define BLUE 0b100 @@ -31,17 +36,29 @@ int gpio_open(const char * path, return -1; } - struct gpio_v2_line_request request = { + struct gpio_v2_line_request request_leds = { .offsets = { 17, 27, 22 }, - .consumer = "timer", + .consumer = "timer-leds", .config = { .flags = GPIO_V2_LINE_FLAG_OUTPUT, }, .num_lines = 3, }; - int ret = ioctl(gpio_state->chip_fd, GPIO_V2_GET_LINE_IOCTL, &request); - assert(ret != -1); - gpio_state->req_fd = request.fd; + int ret1 = ioctl(gpio_state->chip_fd, GPIO_V2_GET_LINE_IOCTL, &request_leds); + assert(ret1 != -1); + gpio_state->led_request_fd = request_leds.fd; + + struct gpio_v2_line_request request_switch = { + .offsets = { 19, 26 }, + .consumer = "timer-switch", + .config = { + .flags = GPIO_V2_LINE_FLAG_INPUT | GPIO_V2_LINE_FLAG_BIAS_PULL_UP, + }, + .num_lines = 2, + }; + int ret2 = ioctl(gpio_state->chip_fd, GPIO_V2_GET_LINE_IOCTL, &request_switch); + assert(ret2 != -1); + gpio_state->switch_request_fd = request_switch.fd; return 0; } @@ -53,10 +70,22 @@ void gpio_set_values(struct gpio_state * gpio_state, uint64_t bits) .mask = 0b111, }; - int ret = ioctl(gpio_state->req_fd, GPIO_V2_LINE_SET_VALUES_IOCTL, &values); + int ret = ioctl(gpio_state->led_request_fd, GPIO_V2_LINE_SET_VALUES_IOCTL, &values); assert(ret != -1); } +uint64_t gpio_get_values(struct gpio_state * gpio_state) +{ + struct gpio_v2_line_values values = { + .mask = 0b11, + }; + + int ret = ioctl(gpio_state->switch_request_fd, GPIO_V2_LINE_GET_VALUES_IOCTL, &values); + assert(ret != -1); + + return (~values.bits) & 0b11; +} + void gpio_set_values_from_link_state(struct gpio_state * gpio_state, struct link_state * link_state) { diff --git a/gpio.h b/gpio.h index dec1ba4..1ccb7a0 100644 --- a/gpio.h +++ b/gpio.h @@ -4,7 +4,8 @@ struct gpio_state { int chip_fd; - int req_fd; + int led_request_fd; + int switch_request_fd; }; int gpio_open(const char * path, @@ -12,5 +13,7 @@ int gpio_open(const char * path, void gpio_set_values(struct gpio_state * gpio_state, uint64_t bits); +uint64_t gpio_get_values(struct gpio_state * gpio_state); + void gpio_set_values_from_link_state(struct gpio_state * gpio_state, struct link_state * link_state); diff --git a/serial_forwarder.c b/serial_forwarder.c index a596528..283e9bf 100644 --- a/serial_forwarder.c +++ b/serial_forwarder.c @@ -117,10 +117,30 @@ int rearm_timer(int timerfd) return 0; } +int send_fake_stop_event(int sockfd, + struct sockaddr_in6 * dest_addr, + struct timer_state * timer_state, + struct link_state * link_state) +{ + printf("fake stop event"); + struct timer_state fake_state = *timer_state; + + fake_state.time.integer_value = 0; + fake_state.time.integer_digits = 0; + fake_state.time.fraction_value = 0; + fake_state.time.fraction_digits = 0; + + int ret = packet_send_stopwatch_event(sockfd, dest_addr, &fake_state, link_state); + return ret; +} + +#define FAKE_STOP_BITS 0b10 + int handle_event(int sockfd, struct sockaddr_in6 * dest_addr, struct timer_state * timer_state, struct link_state * link_state, + struct gpio_state * gpio_state, uint32_t type) { int ret; @@ -134,14 +154,22 @@ int handle_event(int sockfd, break; case EVENT_TYPE__TIME_START: printf("event time start\n"); - ret = packet_send_start_event(sockfd, dest_addr, link_state); + if (gpio_get_values(gpio_state) & FAKE_STOP_BITS) { + ret = send_fake_stop_event(sockfd, dest_addr, timer_state, link_state); + } else { + ret = packet_send_start_event(sockfd, dest_addr, link_state); + } if (ret == -1) { return -1; } break; case EVENT_TYPE__TIME_RESUME: printf("event time resume\n"); - ret = packet_send_resume_event(sockfd, dest_addr, timer_state, link_state); + if (gpio_get_values(gpio_state) & FAKE_STOP_BITS) { + ret = send_fake_stop_event(sockfd, dest_addr, timer_state, link_state); + } else { + ret = packet_send_resume_event(sockfd, dest_addr, timer_state, link_state); + } if (ret == -1) { return -1; } @@ -155,7 +183,8 @@ int handle_event(int sockfd, int check_sequence(int sockfd, struct sockaddr_in6 * dest_addr, struct timer_state * timer_state, - struct link_state * link_state) + struct link_state * link_state, + struct gpio_state * gpio_state) { printf("check_sequence send %ld recv: %ld\n", link_state->send_sequence, link_state->recv_sequence); @@ -166,6 +195,7 @@ int check_sequence(int sockfd, dest_addr, timer_state, link_state, + gpio_state, EVENT_TYPE__TIME_STOP); break; case TIMER_RUNNING: @@ -173,6 +203,7 @@ int check_sequence(int sockfd, dest_addr, timer_state, link_state, + gpio_state, EVENT_TYPE__TIME_RESUME); break; } @@ -214,7 +245,8 @@ int handle_timerfd(int timerfd, ret = check_sequence(sockfd, dest_addr, timer_state, - link_state); + link_state, + gpio_state); if (ret == -1) { return -1; } @@ -230,7 +262,8 @@ int handle_serialfd(int serialfd, struct sockaddr_in6 * dest_addr, struct parser_state * parser_state, struct timer_state * timer_state, - struct link_state * link_state) + struct link_state * link_state, + struct gpio_state * gpio_state) { uint8_t buf[BUFSIZE]; @@ -259,6 +292,7 @@ int handle_serialfd(int serialfd, dest_addr, timer_state, link_state, + gpio_state, type); if (ret == -1) { return -1; @@ -395,7 +429,8 @@ int main(void) &dest_addr, &parser_state, &timer_state, - &link_state); + &link_state, + &gpio_state); if (ret == -1) { return -1; }