Move PM35 protocol into shared C core

This commit is contained in:
2026-09-04 21:06:40 +03:00
parent 2316a5a26a
commit 6a82b309cc
16 changed files with 919 additions and 95 deletions

View File

@@ -4,6 +4,7 @@
#include "pcan_crc.h"
#include "balsam_can.h"
#include "periph28335.h"
#include "pcan_frame.h"
#include "pcan_id.h"
#include "gui_frame.h"
@@ -88,6 +89,79 @@ size_t pcan_abi_balsam_register_name(uint8_t device, uint16_t address,
return balsam_can_register_name(device, address, output, output_size);
}
uint16_t pcan_abi_periph28335_crc16(const uint8_t *data, size_t size)
{
return periph28335_crc16_modbus(data, size);
}
size_t pcan_abi_periph28335_append_crc(
const uint8_t *payload, size_t payload_size,
uint8_t *output, size_t output_size)
{
return periph28335_append_crc(payload, payload_size, output, output_size);
}
size_t pcan_abi_periph28335_build_read(
uint8_t controller, uint16_t start, uint16_t count,
uint8_t *output, size_t output_size)
{
return periph28335_build_read_registers(
controller, start, count, output, output_size);
}
size_t pcan_abi_periph28335_build_write(
uint8_t controller, uint16_t address, uint16_t value,
uint8_t *output, size_t output_size)
{
return periph28335_build_write_register(
controller, address, value, output, output_size);
}
size_t pcan_abi_periph28335_build_command(
uint8_t controller, uint8_t command_index,
uint8_t *output, size_t output_size)
{
return periph28335_build_command(
controller, command_index, output, output_size);
}
size_t pcan_abi_periph28335_expected_read_size(uint16_t count)
{
return periph28335_expected_read_response_size(count);
}
int pcan_abi_periph28335_decode_read(
const uint8_t *data, size_t size, uint8_t controller, uint16_t count,
uint16_t *output, size_t output_count)
{
return periph28335_decode_read_response(
data, size, controller, count, output, output_count);
}
int pcan_abi_periph28335_validate_write(
const uint8_t *response, size_t response_size,
const uint8_t *request, size_t request_size)
{
return periph28335_validate_write_response(
response, response_size, request, request_size);
}
size_t pcan_abi_periph28335_project_count(void)
{
return periph28335_project_count();
}
const char *pcan_abi_periph28335_project_name(size_t project_index)
{
return periph28335_project_name(project_index);
}
const char *pcan_abi_periph28335_command_name(
size_t project_index, size_t command_index)
{
return periph28335_command_name(project_index, command_index);
}
size_t pcan_abi_frame_encode(uint8_t sequence, uint8_t flags,
uint32_t can_id, const uint8_t *data, uint8_t dlc,
uint8_t *output, size_t output_size)

View File

@@ -0,0 +1,171 @@
#include "periph28335.h"
#include <string.h>
typedef struct {
const char *project;
const char *commands[PERIPH28335_COMMAND_COUNT];
} periph28335_project_t;
static const periph28335_project_t projects[] = {
{ "По умолчанию", { "Test", "Def", "Save", "Load", "Calibr", "Calcul", "Secret", "Light", "Raw", "-", "-", "-", "-", "-", "-", "Reset", "Nothing at all" } },
{ "23470", { "Test", "Def", "Save", "Load", "Calibr", "Read", "Secret", "-", "-", "-", "-", "-", "-", "-", "-", "Reset", "Nothing at all" } },
{ "23550", { "Test", "Def", "Save", "Load", "Calibr", "Read", "Secret", "Send", "-", "-", "-", "-", "-", "-", "-", "Reset", "Nothing at all" } },
{ "23550.2", { "Test", "Def", "Save", "Load", "Calibr", "Calcul", "Secret", "Send", "Raw", "Beep", "", "", "", "", "Log", "Reset", "Nothing at all" } },
{ "ICE 22220.1-3", { "Test", "Zero", "Save", "Def", "Calibr", "Read", "ExtLamp", "ExtLite", "-", "-", "-", "-", "-", "-", "-", "Reset", "Nothing at all" } },
{ "ICE 22220.4-5", { "Test", "Def", "Save", "Load", "Raw", "Read", "ExtLamp", "ExtLite", "No log", "-", "-", "-", "-", "-", "-", "Reset", "Nothing at all" } },
{ "Бальзам 161", { "Test", "Zero", "Save", "Def", "Calibr", "Clbr 400", "Stop", "Start", "Init", "Secret", "-", "-", "-", "-", "-", "Reset", "Nothing at all" } },
{ "Бальзам 162", { "Test", "Def", "Save", "Load", "Calibr", "Secret", "Stop", "Start", "Init", "Tune", "-", "-", "-", "-", "-", "Reset", "Nothing at all" } },
{ "Бальзам 163", { "Test", "Def", "Save", "Load", "Calibr", "Calcul", "Stop", "Start", "Init", "Tune", "Secret", "-", "-", "-", "-", "Reset", "Nothing at all" } }
};
static void put_be16(uint8_t *output, uint16_t value)
{
output[0] = (uint8_t)(value >> 8);
output[1] = (uint8_t)value;
}
static uint16_t get_be16(const uint8_t *input)
{
return (uint16_t)(((uint16_t)input[0] << 8) | input[1]);
}
uint16_t periph28335_crc16_modbus(const uint8_t *data, size_t size)
{
uint16_t crc = 0xFFFFU;
size_t index;
uint8_t bit;
if ((data == NULL) && (size != 0U)) return 0U;
for (index = 0U; index < size; ++index) {
crc ^= data[index];
for (bit = 0U; bit < 8U; ++bit) {
crc = (crc & 1U) != 0U
? (uint16_t)((crc >> 1) ^ 0xA001U)
: (uint16_t)(crc >> 1);
}
}
return crc;
}
size_t periph28335_append_crc(const uint8_t *payload, size_t payload_size,
uint8_t *output, size_t output_size)
{
uint16_t crc;
if ((output == NULL) || ((payload == NULL) && (payload_size != 0U)) ||
(payload_size > output_size) || (output_size - payload_size < 2U)) {
return 0U;
}
if (payload_size != 0U) memcpy(output, payload, payload_size);
crc = periph28335_crc16_modbus(payload, payload_size);
output[payload_size] = (uint8_t)crc;
output[payload_size + 1U] = (uint8_t)(crc >> 8);
return payload_size + 2U;
}
size_t periph28335_build_read_registers(
uint8_t controller, uint16_t start, uint16_t count,
uint8_t *output, size_t output_size)
{
uint8_t payload[6];
if ((count == 0U) || (count > PERIPH28335_REGISTER_COUNT) ||
(start >= PERIPH28335_REGISTER_COUNT) ||
((uint32_t)start + count > PERIPH28335_REGISTER_COUNT)) return 0U;
payload[0] = controller;
payload[1] = 3U;
put_be16(&payload[2], start);
put_be16(&payload[4], count);
return periph28335_append_crc(payload, sizeof payload, output, output_size);
}
size_t periph28335_build_write_register(
uint8_t controller, uint16_t address, uint16_t value,
uint8_t *output, size_t output_size)
{
uint8_t payload[6];
if (address >= PERIPH28335_REGISTER_COUNT) return 0U;
payload[0] = controller;
payload[1] = 6U;
put_be16(&payload[2], address);
put_be16(&payload[4], value);
return periph28335_append_crc(payload, sizeof payload, output, output_size);
}
size_t periph28335_build_command(
uint8_t controller, uint8_t command_index,
uint8_t *output, size_t output_size)
{
uint16_t value;
if (command_index >= PERIPH28335_COMMAND_COUNT) return 0U;
value = command_index < 16U ? (uint16_t)(1UL << command_index) : 0U;
return periph28335_build_write_register(
controller, PERIPH28335_REGISTER_COUNT - 1U, value,
output, output_size);
}
size_t periph28335_expected_read_response_size(uint16_t count)
{
return (count >= 1U && count <= PERIPH28335_REGISTER_COUNT)
? (size_t)count * 2U + 5U : 0U;
}
int periph28335_decode_read_response(
const uint8_t *data, size_t size, uint8_t controller, uint16_t count,
uint16_t *output, size_t output_count)
{
size_t expected = periph28335_expected_read_response_size(count);
uint16_t crc;
size_t index;
if ((data == NULL) || (output == NULL)) return PERIPH28335_ERROR_ARGUMENT;
if (expected == 0U) return PERIPH28335_ERROR_RANGE;
if (size != expected) return PERIPH28335_ERROR_LENGTH;
if (output_count < count) return PERIPH28335_ERROR_CAPACITY;
crc = periph28335_crc16_modbus(data, size - 2U);
if ((data[size - 2U] != (uint8_t)crc) ||
(data[size - 1U] != (uint8_t)(crc >> 8))) {
return PERIPH28335_ERROR_CRC;
}
if ((data[0] != controller) || (data[1] != 3U) ||
(data[2] != (uint8_t)(count * 2U))) {
return PERIPH28335_ERROR_HEADER;
}
for (index = 0U; index < count; ++index) {
output[index] = get_be16(&data[3U + index * 2U]);
}
return PERIPH28335_OK;
}
int periph28335_validate_write_response(
const uint8_t *response, size_t response_size,
const uint8_t *request, size_t request_size)
{
uint16_t crc;
if ((response == NULL) || (request == NULL)) return PERIPH28335_ERROR_ARGUMENT;
if ((response_size != PERIPH28335_REQUEST_SIZE) ||
(request_size != PERIPH28335_REQUEST_SIZE)) return PERIPH28335_ERROR_LENGTH;
crc = periph28335_crc16_modbus(response, response_size - 2U);
if ((response[response_size - 2U] != (uint8_t)crc) ||
(response[response_size - 1U] != (uint8_t)(crc >> 8))) {
return PERIPH28335_ERROR_CRC;
}
return memcmp(response, request, PERIPH28335_REQUEST_SIZE) == 0
? PERIPH28335_OK : PERIPH28335_ERROR_HEADER;
}
size_t periph28335_project_count(void)
{
return sizeof projects / sizeof projects[0];
}
const char *periph28335_project_name(size_t project_index)
{
return project_index < periph28335_project_count()
? projects[project_index].project : NULL;
}
const char *periph28335_command_name(size_t project_index,
size_t command_index)
{
return project_index < periph28335_project_count() &&
command_index < PERIPH28335_COMMAND_COUNT
? projects[project_index].commands[command_index] : NULL;
}