diff --git a/software/linux/libsss7.c b/software/linux/libsss7.c index fa55f24..a649921 100644 --- a/software/linux/libsss7.c +++ b/software/linux/libsss7.c @@ -12,9 +12,17 @@ #include "sss7.h" -uint8_t uart_rx_byte; -_Atomic uint8_t uart_tx_byte, uart_has_tx_byte, uart_tx_done; +enum UartTxState { + TX_IDLE, + TX_HAS_BYTE, + TX_COMPLETE +}; +uint8_t uart_rx_byte; +_Atomic uint8_t uart_tx_byte; +_Atomic enum UartTxState uart_tx_state; + +_Atomic int stop_event_thread; pthread_t event_thread; pthread_mutex_t state_mutex, rx_buffer_mutex; @@ -54,6 +62,7 @@ int uart_init(char *serialport) { // No output processing options.c_oflag = 0; + // A timeout of 0.1 seconds for each character options.c_cc[VTIME] = 1; options.c_cc[VMIN] = 0; tcsetattr(serial_fd, TCSAFLUSH, &options); @@ -61,7 +70,46 @@ int uart_init(char *serialport) { return 0; } -void *eventloop(void *arg); +void *eventloop(void *arg) { + int res = 0; + int timestamp = get_milliseconds(); + + while(!stop_event_thread) { + if(uart_tx_state == TX_HAS_BYTE) { + write(serial_fd, &uart_tx_byte, 1); + printf("Send %x\n", uart_tx_byte); + uart_tx_state = TX_COMPLETE; + } + + res = read(serial_fd, &uart_rx_byte, 1); + if(res == 1) { + printf("Read %x\n", uart_tx_byte); + pthread_mutex_lock(&state_mutex); + pthread_mutex_lock(&rx_buffer_mutex); + sss7_process_rx(); + pthread_mutex_unlock(&rx_buffer_mutex); + pthread_mutex_unlock(&state_mutex); + } + + if(uart_tx_state == TX_COMPLETE) { + // Keep this before sss7_process_tx + // uart_put_byte might need to overwrite it + uart_tx_state = TX_IDLE; + + pthread_mutex_lock(&state_mutex); + sss7_process_tx(); + pthread_mutex_unlock(&state_mutex); + } + + pthread_mutex_lock(&state_mutex); + int now = get_milliseconds(); + sss7_process_ticks(now - timestamp); + timestamp = now; + pthread_mutex_unlock(&state_mutex); + } + + return NULL; +} int libsss7_start(char *serialport) { int res = 0; @@ -72,8 +120,8 @@ int libsss7_start(char *serialport) { return -1; } - uart_has_tx_byte = 0; - uart_tx_done = 0; + uart_tx_state = TX_IDLE; + stop_event_thread = 0; pthread_mutex_init(&state_mutex, NULL); pthread_mutex_init(&rx_buffer_mutex, NULL); @@ -87,6 +135,13 @@ int libsss7_start(char *serialport) { return 0; } +void libsss7_stop() { + stop_event_thread = 1; + pthread_join(event_thread, NULL); + + close(serial_fd); +} + int libsss7_can_send(void) { return sss7_can_send(); } @@ -111,56 +166,12 @@ void libsss7_get_received(uint8_t msg[SSS7_PAYLOAD_SIZE]) { pthread_mutex_unlock(&rx_buffer_mutex); } -void libsss7_stop() { - pthread_join(event_thread, NULL); - - close(serial_fd); -} uint8_t uart_get_byte(void) { return uart_rx_byte; } void uart_put_byte(uint8_t byte) { - uart_has_tx_byte = 1; + uart_tx_state = TX_HAS_BYTE; uart_tx_byte = byte; } - -void *eventloop(void *arg) { - int res = 0; - int timestamp = get_milliseconds(); - while(1) { - printf("Loop\n"); - if(uart_has_tx_byte) { - write(serial_fd, &uart_tx_byte, 1); - printf("Send %x\n", uart_tx_byte); - uart_has_tx_byte = 0; - uart_tx_done = 1; - } - - res = read(serial_fd, &uart_rx_byte, 1); - if(res == 1) { - pthread_mutex_lock(&state_mutex); - pthread_mutex_lock(&rx_buffer_mutex); - sss7_process_rx(); - pthread_mutex_unlock(&rx_buffer_mutex); - pthread_mutex_unlock(&state_mutex); - } - - if(uart_tx_done) { - uart_tx_done = 0; - pthread_mutex_lock(&state_mutex); - sss7_process_tx(); - pthread_mutex_unlock(&state_mutex); - } - - pthread_mutex_lock(&state_mutex); - int now = get_milliseconds(); - printf("Ticks: %d\n", now - timestamp); - sss7_process_ticks(now - timestamp); - timestamp = now; - pthread_mutex_unlock(&state_mutex); - } - - return NULL; -} diff --git a/software/linux/test.c b/software/linux/test.c index 1edc251..34ac7dd 100644 --- a/software/linux/test.c +++ b/software/linux/test.c @@ -23,7 +23,7 @@ int main(int argc, char const *argv[]) { msg[10] = 'd'; - while(1) { + //while(1) { while(!libsss7_can_send()); libsss7_send(msg); @@ -32,7 +32,7 @@ int main(int argc, char const *argv[]) { printf("Send failed\n"); } sleep(5); - } + //} libsss7_send(msg);