add licence to source code + add protocol v2
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
@@ -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 *);
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user