From 509e6430cb05ce721ec7ab747a00a32773ca4dfa Mon Sep 17 00:00:00 2001 From: Dennis Gunia Date: Fri, 19 Sep 2025 00:09:42 +0200 Subject: [PATCH] add licence to source code + add protocol v2 --- software/pc_client/makefile | 9 + software/pc_client/src/console.c | 9 + software/pc_client/src/console.h | 9 + software/pc_client/src/devicemgr.c | 17 +- software/pc_client/src/devicemgr.h | 9 + software/pc_client/src/ftdi485.c | 9 + software/pc_client/src/ftdi485.h | 9 + software/pc_client/src/main.c | 276 +++++++++------- software/pc_client/src/sfbus-util.c | 9 + software/pc_client/src/sfbus-util.h | 9 + software/pc_client/src/sfbus.c | 469 ++++++++++++++++------------ software/pc_client/src/sfbus.h | 12 +- software/pc_client/src/wsserver.c | 11 +- software/pc_client/src/wsserver.h | 9 + 14 files changed, 550 insertions(+), 316 deletions(-) diff --git a/software/pc_client/makefile b/software/pc_client/makefile index 92f9e0a..c979563 100644 --- a/software/pc_client/makefile +++ b/software/pc_client/makefile @@ -1,3 +1,12 @@ +# +# This file is part of the split-flap project. +# Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) +# Authors: Dennis Gunia +# +# This program is licenced under AGPL-3.0 license. +# +# + TARGET_EXEC ?= a.out BUILD_DIR ?= ./build diff --git a/software/pc_client/src/console.c b/software/pc_client/src/console.c index 6c492c4..e261f53 100644 --- a/software/pc_client/src/console.c +++ b/software/pc_client/src/console.c @@ -1,3 +1,12 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is licenced under AGPL-3.0 license. + * + */ + #include "console.h" const char *device_config_file = "./flapconfig.json"; diff --git a/software/pc_client/src/console.h b/software/pc_client/src/console.h index 94e389e..5dcf857 100644 --- a/software/pc_client/src/console.h +++ b/software/pc_client/src/console.h @@ -1,3 +1,12 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is licenced under AGPL-3.0 license. + * + */ + #include "devicemgr.h" #include "sfbus-util.h" #include "wsserver.h" diff --git a/software/pc_client/src/devicemgr.c b/software/pc_client/src/devicemgr.c index 4d0a8e7..55522da 100644 --- a/software/pc_client/src/devicemgr.c +++ b/software/pc_client/src/devicemgr.c @@ -1,13 +1,18 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is licenced under AGPL-3.0 license. + * + * This section provides an abstraction layer to access many devices + * simultaneously + */ + #include "devicemgr.h" #include #include -/* - * This section provides an abstraction layer to access many devices - * simultaneously. - * - * by Dennis Gunia - 2025 - www.dennisgunia.de - */ enum SFDEVICE_STATE { UNALLOCATED, diff --git a/software/pc_client/src/devicemgr.h b/software/pc_client/src/devicemgr.h index 7170da8..33bbbea 100644 --- a/software/pc_client/src/devicemgr.h +++ b/software/pc_client/src/devicemgr.h @@ -1,3 +1,12 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is licenced under AGPL-3.0 license. + * + */ + #include "sfbus.h" #include #include // Error integer and strerror() function diff --git a/software/pc_client/src/ftdi485.c b/software/pc_client/src/ftdi485.c index d70c9dd..29429aa 100644 --- a/software/pc_client/src/ftdi485.c +++ b/software/pc_client/src/ftdi485.c @@ -1,3 +1,12 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is licenced under AGPL-3.0 license. + * + */ + #include "ftdi485.h" /* diff --git a/software/pc_client/src/ftdi485.h b/software/pc_client/src/ftdi485.h index 8d388f1..905c7ac 100644 --- a/software/pc_client/src/ftdi485.h +++ b/software/pc_client/src/ftdi485.h @@ -1,3 +1,12 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is licenced under AGPL-3.0 license. + * + */ + #include #include #include diff --git a/software/pc_client/src/main.c b/software/pc_client/src/main.c index e076529..a9a2882 100644 --- a/software/pc_client/src/main.c +++ b/software/pc_client/src/main.c @@ -1,135 +1,181 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is free software (...) + * You should have received a copy of the GNU Affero General Public License + * along with this program (...) + * + * You can be released from the requirements of the license by purchasing + * a commercial license. Buying such a license is mandatory as soon as you + * develop commercial activities involving the split-flap software without + * disclosing the source code of your own applications (...) + * + */ +#include // Contains file controls like O_RDWR #include #include #include #include -// Linux headers -#include // Contains file controls like O_RDWR #include #include // Contains POSIX terminal control definitions #include // write(), read(), close() +#include "console.h" +#include "devicemgr.h" #include "ftdi485.h" #include "sfbus.h" -#include "devicemgr.h" -#include "console.h" -void printUsage(char *argv[]) { - fprintf(stderr, "Usage: %s -p -c [value]\n", argv[0]); - exit(EXIT_FAILURE); +void printUsage(char *argv[]) +{ + fprintf(stderr, "Usage: %s -p -c [value]\n", argv[0]); + exit(EXIT_FAILURE); } -int main(int argc, char *argv[]) { - int opt = ' '; - u_int16_t addr_int = 0; - char *port = malloc(256); - char *command = malloc(16); - char *addr = malloc(16); - char *data = malloc(256); - command = ""; - addr = ""; - data = ""; - while ((opt = getopt(argc, argv, "p:c:a:d:")) != -1) { - switch (opt) { - case 'p': - port = optarg; - break; - case 'c': - command = optarg; - break; - case 'a': - addr = optarg; - break; - case 'd': - data = optarg; - break; - default: - printUsage(argv); +int main(int argc, char *argv[]) +{ + int opt = ' '; + u_int16_t addr_int = 0; + char *port = malloc(256); + char *command = malloc(16); + char *addr = malloc(16); + char *data = malloc(256); + command = ""; + addr = ""; + data = ""; + while ((opt = getopt(argc, argv, "p:c:a:d:")) != -1) + { + switch (opt) + { + case 'p': + port = optarg; + break; + case 'c': + command = optarg; + break; + case 'a': + addr = optarg; + break; + case 'd': + data = optarg; + break; + default: + printUsage(argv); + } + } + if (access(port, F_OK) != 0) + { + fprintf(stderr, "Filedescriptor: %s does not exist or cannot be opened\n", port); + printUsage(argv); + } + // parse address + if (strlen(addr) == 0) + { + fprintf(stderr, "Please specify address\n"); + printUsage(argv); + } + else + { + addr_int = strtol(addr, NULL, 10); } - } - if (access(port, F_OK) != 0) { - fprintf(stderr, "Filedescriptor: %s does not exist or cannot be opened\n", - port); - printUsage(argv); - } - // parse address - if (strlen(addr) == 0) { - fprintf(stderr, "Please specify address\n"); - printUsage(argv); - } else { - addr_int = strtol(addr, NULL, 10); - } - // start program - setvbuf(stdout, NULL, _IONBF, 0); // do not buffer stdout!!!! + // start program + setvbuf(stdout, NULL, _IONBF, 0); // do not buffer stdout!!!! - printf("Open device at %s\n", port); - int fd = rs485_init(port, B19200); // setup rs485 + printf("Open device at %s\n", port); + int fd = rs485_init(port, B19200); // setup rs485 - if (strcmp(command, "ping") == 0) { - - } else if (strcmp(command, "printf") == 0) { - devicemgr_printText(data,0,0); - } else if (strcmp(command, "r_eeprom") == 0) { - char *buffer = malloc(64); - sfbus_read_eeprom(fd, addr_int, buffer); - printf("Read data: 0x"); - print_charHex(buffer, 5); - printf("\n"); - free(buffer); - exit(0); - } else if (strcmp(command, "w_addr") == 0) { - int n_addr = strtol(data, NULL, 10); - int ret = sfbusu_write_address(fd,addr_int,n_addr); - exit(ret); - } else if (strcmp(command, "w_cal") == 0) { - int n_addr = strtol(data, NULL, 10); - int ret = sfbusu_write_calibration(fd,addr_int,n_addr); - exit(ret); - } else if (strcmp(command, "status") == 0) { - double voltage = 0; - u_int32_t counter = 0; - u_int8_t status = sfbus_read_status(fd, addr_int, &voltage, &counter); - printf("=======================\n"); - printf("Status register flags :\n"); - printf(" 00 -> errorTooBig : %i\n", (status >> 0) & 0x01); - printf(" 01 -> noHome : %i\n", (status >> 1) & 0x01); - printf(" 02 -> fuseBlown : %i\n", (status >> 2) & 0x01); - printf(" 03 -> homeSense : %i\n", (status >> 3) & 0x01); - printf(" 04 -> powerDown : %i\n", (status >> 4) & 0x01); - printf(" 05 -> failSafe : %i\n", (status >> 5) & 0x01); - printf(" 06 -> busy : %i\n", (status >> 6) & 0x01); - printf("Driver-Voltage : %.2fV\n", voltage); - printf("Rotations : %i\n", counter); - - exit(0); - } else if (strcmp(command, "display") == 0) { - int flap = strtol(data, NULL, 10); - // read current eeprom status - char *buffer_w = malloc(4); - sfbus_display(fd, addr_int, flap); - exit(0); - } else if (strcmp(command, "display_fr") == 0) { - int flap = strtol(data, NULL, 10); - // read current eeprom status - char *buffer_w = malloc(4); - sfbus_display_full(fd, addr_int, flap); - exit(0); - }else if (strcmp(command, "reset") == 0) { - sfbus_reset_device(fd, addr_int); - exit(0); - } else if (strcmp(command, "power_on") == 0) { - sfbus_motor_power(fd, addr_int,1); - exit(0); - } else if (strcmp(command, "power_off") == 0) { - sfbus_motor_power(fd, addr_int,0); - exit(0); - } else if (strcmp(command, "server") == 0){ - start_console(fd); - } else { - fprintf(stderr, "Invalid command specified!\n"); - printUsage(argv); - } - return 0; + if (strcmp(command, "ping") == 0) + { + sfbus_ping(fd, addr_int); + } + else if (strcmp(command, "printf") == 0) + { + devicemgr_printText(data, 0, 0); + } + else if (strcmp(command, "r_eeprom") == 0) + { + char *buffer = malloc(64); + sfbus_read_eeprom(fd, addr_int, buffer); + printf("Read data: 0x"); + print_charHex(buffer, 5); + printf("\n"); + free(buffer); + exit(0); + } + else if (strcmp(command, "w_addr") == 0) + { + int n_addr = strtol(data, NULL, 10); + int ret = sfbusu_write_address(fd, addr_int, n_addr); + exit(ret); + } + else if (strcmp(command, "w_cal") == 0) + { + int n_addr = strtol(data, NULL, 10); + int ret = sfbusu_write_calibration(fd, addr_int, n_addr); + exit(ret); + } + else if (strcmp(command, "status") == 0) + { + double voltage = 0; + u_int32_t counter = 0; + u_int8_t status = sfbus_read_status(fd, addr_int, &voltage, &counter); + printf("=======================\n"); + printf("Status register flags :\n"); + printf(" 00 -> errorTooBig : %i\n", (status >> 0) & 0x01); + printf(" 01 -> noHome : %i\n", (status >> 1) & 0x01); + printf(" 02 -> fuseBlown : %i\n", (status >> 2) & 0x01); + printf(" 03 -> homeSense : %i\n", (status >> 3) & 0x01); + printf(" 04 -> powerDown : %i\n", (status >> 4) & 0x01); + printf(" 05 -> failSafe : %i\n", (status >> 5) & 0x01); + printf(" 06 -> busy : %i\n", (status >> 6) & 0x01); + printf("Driver-Voltage : %.2fV\n", voltage); + printf("Rotations : %i\n", counter); + + exit(0); + } + else if (strcmp(command, "display") == 0) + { + int flap = strtol(data, NULL, 10); + // read current eeprom status + char *buffer_w = malloc(4); + sfbus_display(fd, addr_int, flap); + exit(0); + } + else if (strcmp(command, "display_fr") == 0) + { + int flap = strtol(data, NULL, 10); + // read current eeprom status + char *buffer_w = malloc(4); + sfbus_display_full(fd, addr_int, flap); + exit(0); + } + else if (strcmp(command, "reset") == 0) + { + sfbus_reset_device(fd, addr_int); + exit(0); + } + else if (strcmp(command, "power_on") == 0) + { + sfbus_motor_power(fd, addr_int, 1); + exit(0); + } + else if (strcmp(command, "power_off") == 0) + { + sfbus_motor_power(fd, addr_int, 0); + exit(0); + } + else if (strcmp(command, "server") == 0) + { + start_console(fd); + } + else + { + fprintf(stderr, "Invalid command specified!\n"); + printUsage(argv); + } + return 0; } \ No newline at end of file diff --git a/software/pc_client/src/sfbus-util.c b/software/pc_client/src/sfbus-util.c index f19db6d..547c502 100644 --- a/software/pc_client/src/sfbus-util.c +++ b/software/pc_client/src/sfbus-util.c @@ -1,3 +1,12 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is licenced under AGPL-3.0 license. + * + */ + #include "sfbus-util.h" int sfbusu_write_address(int fd, u_int16_t current, u_int16_t new) { diff --git a/software/pc_client/src/sfbus-util.h b/software/pc_client/src/sfbus-util.h index e7ae5b2..8af077b 100644 --- a/software/pc_client/src/sfbus-util.h +++ b/software/pc_client/src/sfbus-util.h @@ -1,3 +1,12 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is licenced under AGPL-3.0 license. + * + */ + #include "sfbus.h" #include #include diff --git a/software/pc_client/src/sfbus.c b/software/pc_client/src/sfbus.c index 1bd2b17..3415d2a 100644 --- a/software/pc_client/src/sfbus.c +++ b/software/pc_client/src/sfbus.c @@ -1,225 +1,310 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is licenced under AGPL-3.0 license. + * + */ + #include "sfbus.h" #include #include #include -void print_charHex(char *buffer, int length) { - int _tlength = length; - while (_tlength > 0) { - printf("%02X", (*buffer & 0xFF)); - buffer++; - _tlength--; - } -} - -void print_bufferHexRx(char *buffer, int length, u_int16_t address) { - printf("Rx (0x%04X): 0x", address); - print_charHex(buffer, length); - printf(" | %i bytes received\n", length); -} - -void print_bufferHexTx(char *buffer, int length, u_int16_t address) { - printf("Tx (0x%04X): 0x", address); - print_charHex(buffer, length); - printf(" | %i bytes sent\n", length); -} - -ssize_t sfbus_recv_frame_wait(int fd, u_int16_t address, char *buffer) { - ssize_t len = 0; - int retryCount = 2; - do { - len = sfbus_recv_frame(fd, address, buffer); - retryCount--; - if (retryCount == 0) { - fprintf(stderr, "Rx timeout\n"); - return -1; +void print_charHex(char *buffer, int length) +{ + int _tlength = length; + while (_tlength > 0) + { + printf("%02X ", (*buffer & 0xFF)); + buffer++; + _tlength--; } - } while (len <= 0); - print_bufferHexRx(buffer, len - 3, address); - return len; } -ssize_t sfbus_recv_frame(int fd, u_int16_t address, char *buffer) { - // wait for start byte - char byte = 0x00; - int retryCount = 3; - while (byte != '+') { - byte = 0x00; - read(fd, &byte, 1); - retryCount--; - if (retryCount == 0) { - return -1; +void print_bufferHexRx(char *buffer, int length, u_int16_t address) +{ + printf("Rx (0x%04X): ", address); + print_charHex(buffer, length); + printf(" | %i bytes received\n", length); +} + +void print_bufferHexTx(char *buffer, int length, u_int16_t address) +{ + printf("Tx (0x%04X): ", address); + print_charHex(buffer, length); + printf(" | %i bytes sent\n", length); +} + +ssize_t sfbus_recv_frame_wait(int fd, u_int16_t address, char *buffer) +{ + ssize_t len = 0; + int retryCount = 2; + do + { + len = sfbus_recv_frame(fd, address, buffer); + retryCount--; + if (retryCount == 0) + { + fprintf(stderr, "Rx timeout\n"); + return -1; + } + } while (len <= 0); + print_bufferHexRx(buffer, len - 3, address); + return len; +} + +ssize_t sfbus_recv_frame(int fd, u_int16_t address, char *buffer) +{ + // wait for start byte + char byte = 0x00; + int retryCount = 3; + while (byte != '+') + { + byte = 0x00; + read(fd, &byte, 1); + retryCount--; + if (retryCount == 0) + { + return -1; + } } - } - u_int8_t frm_version; - u_int8_t frm_addr_l; - u_int8_t frm_addr_h; - u_int8_t frm_length; - u_int8_t frm_eof; + u_int8_t frm_version; + u_int8_t frm_addr_l; + u_int8_t frm_addr_h; + u_int8_t frm_length; + u_int8_t frm_eof; - read(fd, &frm_version, 1); - read(fd, &frm_length, 1); - read(fd, &frm_addr_l, 1); - read(fd, &frm_addr_h, 1); + read(fd, &frm_version, 1); + read(fd, &frm_length, 1); + read(fd, &frm_addr_l, 1); + read(fd, &frm_addr_h, 1); - u_int16_t dst_addr = frm_addr_l | (frm_addr_h << 8); - if (dst_addr != address) { - return 0; - } + u_int16_t dst_addr = frm_addr_l | (frm_addr_h << 8); + if (dst_addr != address) + { + return 0; + } - u_int8_t frm_length_counter = frm_length - 3; - // read all bytes: - while (frm_length_counter > 0) { - read(fd, buffer, 1); - buffer++; - frm_length_counter--; - } - read(fd, &frm_eof, 1); + u_int8_t frm_length_counter = frm_length - 3; + // read all bytes: + while (frm_length_counter > 0) + { + read(fd, buffer, 1); + buffer++; + frm_length_counter--; + } + read(fd, &frm_eof, 1); - if (frm_eof == '$') { - return frm_length; - } else { - return -1; - } + if (frm_eof == '$') + { + return frm_length; + } + else + { + return -1; + } } -void sfbus_send_frame(int fd, u_int16_t address, u_int8_t length, - char *buffer) { - int frame_size_complete = length + 6; - char *frame = malloc(frame_size_complete); - char *frame_ptr = frame; +void sfbus_send_frame(int fd, u_int16_t address, u_int8_t length, char *buffer) +{ + int frame_size_complete = length + 6; + char *frame = malloc(frame_size_complete); + char *frame_ptr = frame; - *frame = '+'; // startbyte - frame++; - *frame = 0; // protocol version - frame++; - *frame = length + 3; // length - frame++; - *frame = (address); - frame++; - *frame = ((address >> 8)); - frame++; - while (length > 0) { - *frame = *buffer; - length--; - buffer++; + *frame = '+'; // startbyte frame++; - } - *frame = '$'; // startbyte - - int result = write(fd, frame_ptr, frame_size_complete); - print_bufferHexTx(frame_ptr + 5, frame_size_complete - 6, address); - free(frame_ptr); + *frame = 0; // protocol version + frame++; + *frame = length + 3; // length + frame++; + *frame = (address); + frame++; + *frame = ((address >> 8)); + frame++; + while (length > 0) + { + *frame = *buffer; + length--; + buffer++; + frame++; + } + *frame = '$'; // startbyte + int result = write(fd, frame_ptr, frame_size_complete); + print_bufferHexTx(frame_ptr + 5, frame_size_complete - 6, address); + free(frame_ptr); } -int sfbus_ping(int fd, u_int16_t address) { - char *cmd = "\xFE"; - char *buffer = malloc(64); - sfbus_send_frame(fd, address, strlen(cmd), cmd); - int len = sfbus_recv_frame_wait(fd, 0xFFFF, buffer); - if (len == 4 && *buffer == (char)0xFF) { - printf("Ping okay!\n"); - free(buffer); +void sfbus_send_frame_v2(int fd, u_int16_t address, u_int8_t length, char *buffer) +{ + int frame_size_complete = length + 7; + char *frame = malloc(frame_size_complete); + + *(frame + 0) = '+'; // startbyte + *(frame + 1) = 1; // protocol version + *(frame + 2) = length + 4; // length + *(frame + 3) = (address); // addres high byte + *(frame + 4) = ((address >> 8)); // address low byte + memcpy(frame + 5, buffer, length); // copy data to packet + + u_int16_t crc = calc_CRC16(buffer, length); // calculate CRC + *(frame + (frame_size_complete - 1)) = (crc); // addres high byte + *(frame + (frame_size_complete - 0)) = ((crc >> 8)); // address low byte + + int result = write(fd, frame, frame_size_complete); + print_bufferHexTx(frame, frame_size_complete, address); + free(frame); +} + + +int sfbus_ping(int fd, u_int16_t address) +{ + char *cmd = "\xFE"; + char *buffer = malloc(64); + sfbus_send_frame_v2(fd, address, strlen(cmd), cmd); + int len = sfbus_recv_frame_wait(fd, 0xFFFF, buffer); + if (len == 4 && *buffer == (char)0xFF) + { + printf("Ping okay!\n"); + free(buffer); + return 0; + } + else + { + printf("Ping invalid response!\n"); + free(buffer); + return 1; + } +} + +int sfbus_read_eeprom(int fd, u_int16_t address, char *buffer) +{ + char *cmd = "\xF0"; + char *_buffer = malloc(256); + sfbus_send_frame(fd, address, strlen(cmd), cmd); + int len = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer); + if (len != 9) + { + printf("Invalid data!\n"); + return -1; + } + if (*(_buffer + 5) != (char)0xAA || *(_buffer) != (char)0xAA) + { + printf("Invalid data!\n"); + return -1; + } + memcpy(buffer, _buffer + 1, len - 4); + free(_buffer); + // printf("Read valid data!\n"); + return len; +} + +int sfbus_write_eeprom(int fd, u_int16_t address, char *wbuffer, char *rbuffer) +{ + char *cmd = malloc(5); + *cmd = (char)0xF1; // write eeprom command + memcpy(cmd + 1, wbuffer, 4); + sfbus_send_frame(fd, address, 5, cmd); + free(cmd); + // wait for readback + char *_buffer = malloc(256); + int len = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer); + if (len != 9) + { + printf("Invalid data!\n"); + return -1; + } + if (*(_buffer + 5) != (char)0xAA || *(_buffer) != (char)0xAA) + { + printf("Invalid data!\n"); + return -1; + } + memcpy(rbuffer, _buffer + 1, len - 4); + free(_buffer); + // printf("Read valid data!\n"); + return len; +} + +int sfbus_display(int fd, u_int16_t address, u_int8_t flap) +{ + char *cmd = malloc(5); + *cmd = (char)0x10; // write eeprom command + *(cmd + 1) = flap; + sfbus_send_frame(fd, address, 2, cmd); + free(cmd); return 0; - } else { - printf("Ping invalid response!\n"); - free(buffer); - return 1; - } } -int sfbus_read_eeprom(int fd, u_int16_t address, char *buffer) { - char *cmd = "\xF0"; - char *_buffer = malloc(256); - sfbus_send_frame(fd, address, strlen(cmd), cmd); - int len = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer); - if (len != 9) { - printf("Invalid data!\n"); - return -1; - } - if (*(_buffer + 5) != (char)0xAA || *(_buffer) != (char)0xAA) { - printf("Invalid data!\n"); - return -1; - } - memcpy(buffer, _buffer + 1, len - 4); - free(_buffer); - // printf("Read valid data!\n"); - return len; +int sfbus_display_full(int fd, u_int16_t address, u_int8_t flap) +{ + char *cmd = malloc(5); + *cmd = (char)0x11; // write eeprom command + *(cmd + 1) = flap; + sfbus_send_frame(fd, address, 2, cmd); + free(cmd); + return 0; } -int sfbus_write_eeprom(int fd, u_int16_t address, char *wbuffer, - char *rbuffer) { - char *cmd = malloc(5); - *cmd = (char)0xF1; // write eeprom command - memcpy(cmd + 1, wbuffer, 4); - sfbus_send_frame(fd, address, 5, cmd); - free(cmd); - // wait for readback - char *_buffer = malloc(256); - int len = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer); - if (len != 9) { - printf("Invalid data!\n"); - return -1; - } - if (*(_buffer + 5) != (char)0xAA || *(_buffer) != (char)0xAA) { - printf("Invalid data!\n"); - return -1; - } - memcpy(rbuffer, _buffer + 1, len - 4); - free(_buffer); - // printf("Read valid data!\n"); - return len; +u_int8_t sfbus_read_status(int fd, u_int16_t address, double *voltage, u_int32_t *counter) +{ + char *cmd = "\xF8"; + char *_buffer = malloc(256); + sfbus_send_frame(fd, address, strlen(cmd), cmd); + int res = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer); + if (res < 0) + { + return 0xFF; + } + u_int16_t _voltage = *(_buffer + 2) & 0xFF | ((*(_buffer + 1) << 8) & 0xFF00); + u_int32_t _counter = *(_buffer + 6) & 0xFF | (((*(_buffer + 3) & 0xFF) << 24)) | (((*(_buffer + 4) & 0xFF) << 16)) | + (((*(_buffer + 5) & 0xFF) << 8)); + + double __voltage = ((double)_voltage / 1024) * 55; + + *voltage = __voltage; + *counter = (u_int32_t)_counter; + return *_buffer; } -int sfbus_display(int fd, u_int16_t address, u_int8_t flap) { - char *cmd = malloc(5); - *cmd = (char)0x10; // write eeprom command - *(cmd + 1) = flap; - sfbus_send_frame(fd, address, 2, cmd); - free(cmd); - return 0; +void sfbus_reset_device(int fd, u_int16_t address) +{ + char *cmd = "\x30"; + sfbus_send_frame(fd, address, strlen(cmd), cmd); } -int sfbus_display_full(int fd, u_int16_t address, u_int8_t flap) { - char *cmd = malloc(5); - *cmd = (char)0x11; // write eeprom command - *(cmd + 1) = flap; - sfbus_send_frame(fd, address, 2, cmd); - free(cmd); - return 0; +void sfbus_motor_power(int fd, u_int16_t address, u_int8_t state) +{ + char *cmd = "\x20"; + if (state > 0) + { + cmd = "\x21"; + } + sfbus_send_frame(fd, address, 1, cmd); } -u_int8_t sfbus_read_status(int fd, u_int16_t address, double *voltage, - u_int32_t *counter) { - char *cmd = "\xF8"; - char *_buffer = malloc(256); - sfbus_send_frame(fd, address, strlen(cmd), cmd); - int res = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer); - if (res < 0){ - return 0xFF; - } - u_int16_t _voltage = *(_buffer + 2) & 0xFF | ((*(_buffer + 1) << 8) & 0xFF00); - u_int32_t _counter = - *(_buffer + 6) & 0xFF | (((*(_buffer + 3) & 0xFF) << 24)) | - (((*(_buffer + 4) & 0xFF) << 16)) | (((*(_buffer + 5) & 0xFF) << 8)); +u_int16_t calc_CRC16(char *buffer, u_int8_t len) +{ + u_int16_t crc16 = 0xFFFF; + for (u_int8_t pos = 0; pos < len; pos++) + { + char byte_value = *(buffer); // read byte after byte from buffer + buffer++; - double __voltage = ((double)_voltage / 1024) * 55; - - *voltage = __voltage; - *counter = (u_int32_t)_counter; - return *_buffer; -} - -void sfbus_reset_device(int fd, u_int16_t address) { - char *cmd = "\x30"; - sfbus_send_frame(fd, address, strlen(cmd), cmd); -} - -void sfbus_motor_power(int fd, u_int16_t address, u_int8_t state) { - char *cmd = "\x20"; - if (state > 0) { - cmd = "\x21"; - } - sfbus_send_frame(fd, address, 1, cmd); + crc16 ^= byte_value; // XOR byte into least sig. byte of crc + for (int i = 8; i != 0; i--) + { // Loop over each bit + if ((crc16 & 0x0001) != 0) + { // If the LSB is set + crc16 >>= 1; // Shift right and XOR 0xA001 + crc16 ^= 0xA001; + } + else + { // Else LSB is not set + crc16 >>= 1; // Just shift right + } + } + } + return crc16; } \ No newline at end of file diff --git a/software/pc_client/src/sfbus.h b/software/pc_client/src/sfbus.h index 2d8a838..6e24539 100644 --- a/software/pc_client/src/sfbus.h +++ b/software/pc_client/src/sfbus.h @@ -1,3 +1,12 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is licenced under AGPL-3.0 license. + * + */ + #include "ftdi485.h" ssize_t sfbus_recv_frame(int fd, u_int16_t address, char *buffer); @@ -11,4 +20,5 @@ int sfbus_display(int fd, u_int16_t address, u_int8_t flap); int sfbus_display_full(int fd, u_int16_t address, u_int8_t flap); u_int8_t sfbus_read_status(int fd, u_int16_t address, double *voltage, u_int32_t *counter); void sfbus_reset_device(int fd, u_int16_t address); -void sfbus_motor_power(int fd, u_int16_t address, u_int8_t state); \ No newline at end of file +void sfbus_motor_power(int fd, u_int16_t address, u_int8_t state); +u_int16_t calc_CRC16(char *buffer, u_int8_t len); \ No newline at end of file diff --git a/software/pc_client/src/wsserver.c b/software/pc_client/src/wsserver.c index 0cac2c9..e6be8f0 100644 --- a/software/pc_client/src/wsserver.c +++ b/software/pc_client/src/wsserver.c @@ -1,10 +1,17 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is licenced under AGPL-3.0 license. + * + */ + #include "wsserver.h" /* * This section provides a web server to controll the * device manager through web sockets - * - * by Dennis Gunia - 2025 - www.dennisgunia.de */ json_object *(*commandparser_func)(json_object *); diff --git a/software/pc_client/src/wsserver.h b/software/pc_client/src/wsserver.h index e5822d9..be82553 100644 --- a/software/pc_client/src/wsserver.h +++ b/software/pc_client/src/wsserver.h @@ -1,3 +1,12 @@ +/* + * This file is part of the split-flap project. + * Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de) + * Authors: Dennis Gunia + * + * This program is licenced under AGPL-3.0 license. + * + */ + #include #include #include