add licence to source code + add protocol v2

This commit is contained in:
Dennis Gunia
2025-09-19 00:09:42 +02:00
parent dcc3a04c89
commit 509e6430cb
14 changed files with 550 additions and 316 deletions

View File

@@ -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 TARGET_EXEC ?= a.out
BUILD_DIR ?= ./build BUILD_DIR ?= ./build

View File

@@ -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" #include "console.h"
const char *device_config_file = "./flapconfig.json"; const char *device_config_file = "./flapconfig.json";

View File

@@ -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 "devicemgr.h"
#include "sfbus-util.h" #include "sfbus-util.h"
#include "wsserver.h" #include "wsserver.h"

View File

@@ -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 "devicemgr.h"
#include <json-c/json_object.h> #include <json-c/json_object.h>
#include <string.h> #include <string.h>
/*
* This section provides an abstraction layer to access many devices
* simultaneously.
*
* by Dennis Gunia - 2025 - www.dennisgunia.de
*/
enum SFDEVICE_STATE enum SFDEVICE_STATE
{ {
UNALLOCATED, UNALLOCATED,

View File

@@ -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 "sfbus.h"
#include <ctype.h> #include <ctype.h>
#include <errno.h> // Error integer and strerror() function #include <errno.h> // Error integer and strerror() function

View File

@@ -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" #include "ftdi485.h"
/* /*

View File

@@ -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 <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>

View File

@@ -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 <fcntl.h> // Contains file controls like O_RDWR
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
// Linux headers
#include <fcntl.h> // Contains file controls like O_RDWR
#include <sys/types.h> #include <sys/types.h>
#include <termios.h> // Contains POSIX terminal control definitions #include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close() #include <unistd.h> // write(), read(), close()
#include "console.h"
#include "devicemgr.h"
#include "ftdi485.h" #include "ftdi485.h"
#include "sfbus.h" #include "sfbus.h"
#include "devicemgr.h"
#include "console.h"
void printUsage(char *argv[]) { void printUsage(char *argv[])
fprintf(stderr, "Usage: %s -p <tty> -c <command> [value]\n", argv[0]); {
exit(EXIT_FAILURE); fprintf(stderr, "Usage: %s -p <tty> -c <command> [value]\n", argv[0]);
exit(EXIT_FAILURE);
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[])
int opt = ' '; {
u_int16_t addr_int = 0; int opt = ' ';
char *port = malloc(256); u_int16_t addr_int = 0;
char *command = malloc(16); char *port = malloc(256);
char *addr = malloc(16); char *command = malloc(16);
char *data = malloc(256); char *addr = malloc(16);
command = ""; char *data = malloc(256);
addr = ""; command = "";
data = ""; addr = "";
while ((opt = getopt(argc, argv, "p:c:a:d:")) != -1) { data = "";
switch (opt) { while ((opt = getopt(argc, argv, "p:c:a:d:")) != -1)
case 'p': {
port = optarg; switch (opt)
break; {
case 'c': case 'p':
command = optarg; port = optarg;
break; break;
case 'a': case 'c':
addr = optarg; command = optarg;
break; break;
case 'd': case 'a':
data = optarg; addr = optarg;
break; break;
default: case 'd':
printUsage(argv); 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 // start program
setvbuf(stdout, NULL, _IONBF, 0); // do not buffer stdout!!!! setvbuf(stdout, NULL, _IONBF, 0); // do not buffer stdout!!!!
printf("Open device at %s\n", port); printf("Open device at %s\n", port);
int fd = rs485_init(port, B19200); // setup rs485 int fd = rs485_init(port, B19200); // setup rs485
if (strcmp(command, "ping") == 0) { if (strcmp(command, "ping") == 0)
{
} else if (strcmp(command, "printf") == 0) { sfbus_ping(fd, addr_int);
devicemgr_printText(data,0,0); }
} else if (strcmp(command, "r_eeprom") == 0) { else if (strcmp(command, "printf") == 0)
char *buffer = malloc(64); {
sfbus_read_eeprom(fd, addr_int, buffer); devicemgr_printText(data, 0, 0);
printf("Read data: 0x"); }
print_charHex(buffer, 5); else if (strcmp(command, "r_eeprom") == 0)
printf("\n"); {
free(buffer); char *buffer = malloc(64);
exit(0); sfbus_read_eeprom(fd, addr_int, buffer);
} else if (strcmp(command, "w_addr") == 0) { printf("Read data: 0x");
int n_addr = strtol(data, NULL, 10); print_charHex(buffer, 5);
int ret = sfbusu_write_address(fd,addr_int,n_addr); printf("\n");
exit(ret); free(buffer);
} else if (strcmp(command, "w_cal") == 0) { exit(0);
int n_addr = strtol(data, NULL, 10); }
int ret = sfbusu_write_calibration(fd,addr_int,n_addr); else if (strcmp(command, "w_addr") == 0)
exit(ret); {
} else if (strcmp(command, "status") == 0) { int n_addr = strtol(data, NULL, 10);
double voltage = 0; int ret = sfbusu_write_address(fd, addr_int, n_addr);
u_int32_t counter = 0; exit(ret);
u_int8_t status = sfbus_read_status(fd, addr_int, &voltage, &counter); }
printf("=======================\n"); else if (strcmp(command, "w_cal") == 0)
printf("Status register flags :\n"); {
printf(" 00 -> errorTooBig : %i\n", (status >> 0) & 0x01); int n_addr = strtol(data, NULL, 10);
printf(" 01 -> noHome : %i\n", (status >> 1) & 0x01); int ret = sfbusu_write_calibration(fd, addr_int, n_addr);
printf(" 02 -> fuseBlown : %i\n", (status >> 2) & 0x01); exit(ret);
printf(" 03 -> homeSense : %i\n", (status >> 3) & 0x01); }
printf(" 04 -> powerDown : %i\n", (status >> 4) & 0x01); else if (strcmp(command, "status") == 0)
printf(" 05 -> failSafe : %i\n", (status >> 5) & 0x01); {
printf(" 06 -> busy : %i\n", (status >> 6) & 0x01); double voltage = 0;
printf("Driver-Voltage : %.2fV\n", voltage); u_int32_t counter = 0;
printf("Rotations : %i\n", counter); u_int8_t status = sfbus_read_status(fd, addr_int, &voltage, &counter);
printf("=======================\n");
exit(0); printf("Status register flags :\n");
} else if (strcmp(command, "display") == 0) { printf(" 00 -> errorTooBig : %i\n", (status >> 0) & 0x01);
int flap = strtol(data, NULL, 10); printf(" 01 -> noHome : %i\n", (status >> 1) & 0x01);
// read current eeprom status printf(" 02 -> fuseBlown : %i\n", (status >> 2) & 0x01);
char *buffer_w = malloc(4); printf(" 03 -> homeSense : %i\n", (status >> 3) & 0x01);
sfbus_display(fd, addr_int, flap); printf(" 04 -> powerDown : %i\n", (status >> 4) & 0x01);
exit(0); printf(" 05 -> failSafe : %i\n", (status >> 5) & 0x01);
} else if (strcmp(command, "display_fr") == 0) { printf(" 06 -> busy : %i\n", (status >> 6) & 0x01);
int flap = strtol(data, NULL, 10); printf("Driver-Voltage : %.2fV\n", voltage);
// read current eeprom status printf("Rotations : %i\n", counter);
char *buffer_w = malloc(4);
sfbus_display_full(fd, addr_int, flap); exit(0);
exit(0); }
}else if (strcmp(command, "reset") == 0) { else if (strcmp(command, "display") == 0)
sfbus_reset_device(fd, addr_int); {
exit(0); int flap = strtol(data, NULL, 10);
} else if (strcmp(command, "power_on") == 0) { // read current eeprom status
sfbus_motor_power(fd, addr_int,1); char *buffer_w = malloc(4);
exit(0); sfbus_display(fd, addr_int, flap);
} else if (strcmp(command, "power_off") == 0) { exit(0);
sfbus_motor_power(fd, addr_int,0); }
exit(0); else if (strcmp(command, "display_fr") == 0)
} else if (strcmp(command, "server") == 0){ {
start_console(fd); int flap = strtol(data, NULL, 10);
} else { // read current eeprom status
fprintf(stderr, "Invalid command specified!\n"); char *buffer_w = malloc(4);
printUsage(argv); sfbus_display_full(fd, addr_int, flap);
} exit(0);
return 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;
} }

View File

@@ -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" #include "sfbus-util.h"
int sfbusu_write_address(int fd, u_int16_t current, u_int16_t new) int sfbusu_write_address(int fd, u_int16_t current, u_int16_t new)
{ {

View File

@@ -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 "sfbus.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>

View File

@@ -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 "sfbus.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
void print_charHex(char *buffer, int length) { void print_charHex(char *buffer, int length)
int _tlength = length; {
while (_tlength > 0) { int _tlength = length;
printf("%02X", (*buffer & 0xFF)); while (_tlength > 0)
buffer++; {
_tlength--; 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;
} }
} while (len <= 0);
print_bufferHexRx(buffer, len - 3, address);
return len;
} }
ssize_t sfbus_recv_frame(int fd, u_int16_t address, char *buffer) { void print_bufferHexRx(char *buffer, int length, u_int16_t address)
// wait for start byte {
char byte = 0x00; printf("Rx (0x%04X): ", address);
int retryCount = 3; print_charHex(buffer, length);
while (byte != '+') { printf(" | %i bytes received\n", length);
byte = 0x00; }
read(fd, &byte, 1);
retryCount--; void print_bufferHexTx(char *buffer, int length, u_int16_t address)
if (retryCount == 0) { {
return -1; 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_version; u_int8_t frm_addr_l;
u_int8_t frm_addr_l; u_int8_t frm_addr_h;
u_int8_t frm_addr_h; u_int8_t frm_length;
u_int8_t frm_length; u_int8_t frm_eof;
u_int8_t frm_eof;
read(fd, &frm_version, 1); read(fd, &frm_version, 1);
read(fd, &frm_length, 1); read(fd, &frm_length, 1);
read(fd, &frm_addr_l, 1); read(fd, &frm_addr_l, 1);
read(fd, &frm_addr_h, 1); read(fd, &frm_addr_h, 1);
u_int16_t dst_addr = frm_addr_l | (frm_addr_h << 8); u_int16_t dst_addr = frm_addr_l | (frm_addr_h << 8);
if (dst_addr != address) { if (dst_addr != address)
return 0; {
} return 0;
}
u_int8_t frm_length_counter = frm_length - 3; u_int8_t frm_length_counter = frm_length - 3;
// read all bytes: // read all bytes:
while (frm_length_counter > 0) { while (frm_length_counter > 0)
read(fd, buffer, 1); {
buffer++; read(fd, buffer, 1);
frm_length_counter--; buffer++;
} frm_length_counter--;
read(fd, &frm_eof, 1); }
read(fd, &frm_eof, 1);
if (frm_eof == '$') { if (frm_eof == '$')
return frm_length; {
} else { return frm_length;
return -1; }
} else
{
return -1;
}
} }
void sfbus_send_frame(int fd, u_int16_t address, u_int8_t length, void sfbus_send_frame(int fd, u_int16_t address, u_int8_t length, char *buffer)
char *buffer) { {
int frame_size_complete = length + 6; int frame_size_complete = length + 6;
char *frame = malloc(frame_size_complete); char *frame = malloc(frame_size_complete);
char *frame_ptr = frame; char *frame_ptr = frame;
*frame = '+'; // startbyte *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++; frame++;
} *frame = 0; // protocol version
*frame = '$'; // startbyte frame++;
*frame = length + 3; // length
int result = write(fd, frame_ptr, frame_size_complete); frame++;
print_bufferHexTx(frame_ptr + 5, frame_size_complete - 6, address); *frame = (address);
free(frame_ptr); 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) { void sfbus_send_frame_v2(int fd, u_int16_t address, u_int8_t length, char *buffer)
char *cmd = "\xFE"; {
char *buffer = malloc(64); int frame_size_complete = length + 7;
sfbus_send_frame(fd, address, strlen(cmd), cmd); char *frame = malloc(frame_size_complete);
int len = sfbus_recv_frame_wait(fd, 0xFFFF, buffer);
if (len == 4 && *buffer == (char)0xFF) { *(frame + 0) = '+'; // startbyte
printf("Ping okay!\n"); *(frame + 1) = 1; // protocol version
free(buffer); *(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; return 0;
} else {
printf("Ping invalid response!\n");
free(buffer);
return 1;
}
} }
int sfbus_read_eeprom(int fd, u_int16_t address, char *buffer) { int sfbus_display_full(int fd, u_int16_t address, u_int8_t flap)
char *cmd = "\xF0"; {
char *_buffer = malloc(256); char *cmd = malloc(5);
sfbus_send_frame(fd, address, strlen(cmd), cmd); *cmd = (char)0x11; // write eeprom command
int len = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer); *(cmd + 1) = flap;
if (len != 9) { sfbus_send_frame(fd, address, 2, cmd);
printf("Invalid data!\n"); free(cmd);
return -1; return 0;
}
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, u_int8_t sfbus_read_status(int fd, u_int16_t address, double *voltage, u_int32_t *counter)
char *rbuffer) { {
char *cmd = malloc(5); char *cmd = "\xF8";
*cmd = (char)0xF1; // write eeprom command char *_buffer = malloc(256);
memcpy(cmd + 1, wbuffer, 4); sfbus_send_frame(fd, address, strlen(cmd), cmd);
sfbus_send_frame(fd, address, 5, cmd); int res = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer);
free(cmd); if (res < 0)
// wait for readback {
char *_buffer = malloc(256); return 0xFF;
int len = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer); }
if (len != 9) { u_int16_t _voltage = *(_buffer + 2) & 0xFF | ((*(_buffer + 1) << 8) & 0xFF00);
printf("Invalid data!\n"); u_int32_t _counter = *(_buffer + 6) & 0xFF | (((*(_buffer + 3) & 0xFF) << 24)) | (((*(_buffer + 4) & 0xFF) << 16)) |
return -1; (((*(_buffer + 5) & 0xFF) << 8));
}
if (*(_buffer + 5) != (char)0xAA || *(_buffer) != (char)0xAA) { double __voltage = ((double)_voltage / 1024) * 55;
printf("Invalid data!\n");
return -1; *voltage = __voltage;
} *counter = (u_int32_t)_counter;
memcpy(rbuffer, _buffer + 1, len - 4); return *_buffer;
free(_buffer);
// printf("Read valid data!\n");
return len;
} }
int sfbus_display(int fd, u_int16_t address, u_int8_t flap) { void sfbus_reset_device(int fd, u_int16_t address)
char *cmd = malloc(5); {
*cmd = (char)0x10; // write eeprom command char *cmd = "\x30";
*(cmd + 1) = flap; sfbus_send_frame(fd, address, strlen(cmd), cmd);
sfbus_send_frame(fd, address, 2, cmd);
free(cmd);
return 0;
} }
int sfbus_display_full(int fd, u_int16_t address, u_int8_t flap) { void sfbus_motor_power(int fd, u_int16_t address, u_int8_t state)
char *cmd = malloc(5); {
*cmd = (char)0x11; // write eeprom command char *cmd = "\x20";
*(cmd + 1) = flap; if (state > 0)
sfbus_send_frame(fd, address, 2, cmd); {
free(cmd); cmd = "\x21";
return 0; }
sfbus_send_frame(fd, address, 1, cmd);
} }
u_int8_t sfbus_read_status(int fd, u_int16_t address, double *voltage, u_int16_t calc_CRC16(char *buffer, u_int8_t len)
u_int32_t *counter) { {
char *cmd = "\xF8"; u_int16_t crc16 = 0xFFFF;
char *_buffer = malloc(256); for (u_int8_t pos = 0; pos < len; pos++)
sfbus_send_frame(fd, address, strlen(cmd), cmd); {
int res = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer); char byte_value = *(buffer); // read byte after byte from buffer
if (res < 0){ buffer++;
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; crc16 ^= byte_value; // XOR byte into least sig. byte of crc
for (int i = 8; i != 0; i--)
*voltage = __voltage; { // Loop over each bit
*counter = (u_int32_t)_counter; if ((crc16 & 0x0001) != 0)
return *_buffer; { // If the LSB is set
} crc16 >>= 1; // Shift right and XOR 0xA001
crc16 ^= 0xA001;
void sfbus_reset_device(int fd, u_int16_t address) { }
char *cmd = "\x30"; else
sfbus_send_frame(fd, address, strlen(cmd), cmd); { // Else LSB is not set
} crc16 >>= 1; // Just shift right
}
void sfbus_motor_power(int fd, u_int16_t address, u_int8_t state) { }
char *cmd = "\x20"; }
if (state > 0) { return crc16;
cmd = "\x21";
}
sfbus_send_frame(fd, address, 1, cmd);
} }

View File

@@ -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" #include "ftdi485.h"
ssize_t sfbus_recv_frame(int fd, u_int16_t address, char *buffer); 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); 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); 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_reset_device(int fd, u_int16_t address);
void sfbus_motor_power(int fd, u_int16_t address, u_int8_t state); 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);

View File

@@ -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" #include "wsserver.h"
/* /*
* This section provides a web server to controll the * This section provides a web server to controll the
* device manager through web sockets * device manager through web sockets
*
* by Dennis Gunia - 2025 - www.dennisgunia.de
*/ */
json_object *(*commandparser_func)(json_object *); json_object *(*commandparser_func)(json_object *);

View File

@@ -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 <json-c/json_object.h> #include <json-c/json_object.h>
#include <json-c/json_tokener.h> #include <json-c/json_tokener.h>
#include <stdio.h> #include <stdio.h>