341 lines
9.6 KiB
C
341 lines
9.6 KiB
C
#include "pcan_abi.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "pcan_crc.h"
|
|
#include "balsam_can.h"
|
|
#include "periph28335.h"
|
|
#include "tms2812.h"
|
|
#include "pcan_frame.h"
|
|
#include "pcan_id.h"
|
|
#include "gui_frame.h"
|
|
|
|
uint32_t pcan_abi_version(void)
|
|
{
|
|
return PCAN_ABI_VERSION;
|
|
}
|
|
|
|
uint32_t pcan_abi_id_pack(uint8_t priority, uint8_t route,
|
|
uint8_t device_type, uint8_t device_id,
|
|
uint8_t message_type, uint16_t body)
|
|
{
|
|
pcan_id_t id;
|
|
id.msg_body = body;
|
|
id.msg_type = message_type;
|
|
id.device_id = device_id;
|
|
id.device_type = device_type;
|
|
id.route = route;
|
|
id.priority = priority;
|
|
return pcan_id_pack(&id);
|
|
}
|
|
|
|
void pcan_abi_id_unpack(uint32_t raw, uint8_t *priority, uint8_t *route,
|
|
uint8_t *device_type, uint8_t *device_id,
|
|
uint8_t *message_type, uint16_t *body)
|
|
{
|
|
pcan_id_t id;
|
|
pcan_id_unpack(raw, &id);
|
|
if (priority != NULL) {
|
|
*priority = id.priority;
|
|
}
|
|
if (route != NULL) {
|
|
*route = id.route;
|
|
}
|
|
if (device_type != NULL) {
|
|
*device_type = id.device_type;
|
|
}
|
|
if (device_id != NULL) {
|
|
*device_id = id.device_id;
|
|
}
|
|
if (message_type != NULL) {
|
|
*message_type = id.msg_type;
|
|
}
|
|
if (body != NULL) {
|
|
*body = id.msg_body;
|
|
}
|
|
}
|
|
|
|
uint16_t pcan_abi_crc16(const uint8_t *data, size_t size)
|
|
{
|
|
if ((data == NULL) && (size != 0U)) {
|
|
return 0U;
|
|
}
|
|
return pcan_crc16(data, size);
|
|
}
|
|
|
|
int pcan_abi_balsam_decode(uint32_t can_id, const uint8_t *data, size_t size,
|
|
pcan_abi_balsam_frame_t *output)
|
|
{
|
|
balsam_can_frame_t decoded;
|
|
int status;
|
|
if (output == NULL) return -1;
|
|
status = balsam_can_decode(can_id, data, size, &decoded);
|
|
if (status != 1) return status;
|
|
output->device = decoded.device;
|
|
output->direction = decoded.direction;
|
|
output->present_mask = decoded.present_mask;
|
|
output->start_address = decoded.start_address;
|
|
memcpy(output->values, decoded.values, sizeof output->values);
|
|
return 1;
|
|
}
|
|
|
|
const char *pcan_abi_balsam_device_name(uint8_t device)
|
|
{
|
|
return balsam_can_device_name(device);
|
|
}
|
|
|
|
size_t pcan_abi_balsam_register_name(uint8_t device, uint16_t address,
|
|
char *output, size_t output_size)
|
|
{
|
|
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);
|
|
}
|
|
|
|
uint16_t pcan_abi_tms2812_crc16(const uint8_t *data, size_t size)
|
|
{
|
|
return tms2812_crc16(data, size);
|
|
}
|
|
|
|
size_t pcan_abi_tms2812_build_upload(
|
|
uint8_t controller, uint32_t word_address, uint32_t byte_count,
|
|
uint8_t *output, size_t output_size)
|
|
{
|
|
return tms2812_build_upload_request(
|
|
controller, word_address, byte_count, output, output_size);
|
|
}
|
|
|
|
size_t pcan_abi_tms2812_expected_upload_size(uint32_t byte_count)
|
|
{
|
|
return tms2812_expected_upload_response_size(byte_count);
|
|
}
|
|
|
|
int pcan_abi_tms2812_validate_upload(
|
|
const uint8_t *data, size_t size, uint8_t controller,
|
|
uint32_t byte_count)
|
|
{
|
|
return tms2812_validate_upload_response(
|
|
data, size, controller, byte_count);
|
|
}
|
|
|
|
int pcan_abi_tms2812_decode_upload(
|
|
const uint8_t *data, size_t size, uint8_t controller,
|
|
uint32_t byte_count, uint8_t *output, size_t output_size)
|
|
{
|
|
return tms2812_decode_upload_response(
|
|
data, size, controller, byte_count, output, output_size);
|
|
}
|
|
|
|
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)
|
|
{
|
|
pcan_frame_t frame;
|
|
if ((output == NULL) || (dlc > PCAN_DATA_MAX) ||
|
|
((data == NULL) && (dlc != 0U))) {
|
|
return 0U;
|
|
}
|
|
memset(&frame, 0, sizeof frame);
|
|
frame.seq = sequence;
|
|
frame.flags = flags;
|
|
frame.id = can_id;
|
|
frame.dlc = dlc;
|
|
if (dlc != 0U) {
|
|
memcpy(frame.data, data, dlc);
|
|
}
|
|
return pcan_frame_encode(&frame, output, output_size);
|
|
}
|
|
|
|
size_t pcan_abi_parser_size(void)
|
|
{
|
|
return sizeof(pcan_parser_t);
|
|
}
|
|
|
|
int pcan_abi_parser_init(void *parser_storage, size_t storage_size)
|
|
{
|
|
if ((parser_storage == NULL) || (storage_size < sizeof(pcan_parser_t))) {
|
|
return 0;
|
|
}
|
|
pcan_parser_init((pcan_parser_t *)parser_storage);
|
|
return 1;
|
|
}
|
|
|
|
int pcan_abi_parser_push(void *parser_storage, uint8_t byte,
|
|
pcan_abi_frame_t *output)
|
|
{
|
|
pcan_frame_t frame;
|
|
if ((parser_storage == NULL) || (output == NULL)) {
|
|
return -1;
|
|
}
|
|
if (!pcan_parser_push((pcan_parser_t *)parser_storage, byte, &frame)) {
|
|
return 0;
|
|
}
|
|
output->can_id = frame.id;
|
|
output->sequence = frame.seq;
|
|
output->flags = frame.flags;
|
|
output->dlc = frame.dlc;
|
|
memset(output->data, 0, sizeof output->data);
|
|
memcpy(output->data, frame.data, frame.dlc);
|
|
return 1;
|
|
}
|
|
|
|
int pcan_abi_parser_stats(const void *parser_storage, uint32_t *frames,
|
|
uint32_t *crc_errors, uint32_t *bad_length,
|
|
uint32_t *stray_bytes)
|
|
{
|
|
const pcan_parser_t *parser = (const pcan_parser_t *)parser_storage;
|
|
if (parser == NULL) {
|
|
return 0;
|
|
}
|
|
if (frames != NULL) {
|
|
*frames = parser->stats.frames;
|
|
}
|
|
if (crc_errors != NULL) {
|
|
*crc_errors = parser->stats.crc_errors;
|
|
}
|
|
if (bad_length != NULL) {
|
|
*bad_length = parser->stats.bad_len;
|
|
}
|
|
if (stray_bytes != NULL) {
|
|
*stray_bytes = parser->stats.stray_bytes;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
uint32_t pcan_abi_gui_crc32(const uint8_t *data, size_t size)
|
|
{
|
|
if ((data == NULL) && (size != 0U)) {
|
|
return 0U;
|
|
}
|
|
return gui_crc32(data, size);
|
|
}
|
|
|
|
size_t pcan_abi_gui_frame_encode(uint8_t message_type, uint16_t sequence,
|
|
const uint8_t *payload,
|
|
uint16_t payload_size, uint8_t *output,
|
|
size_t output_size)
|
|
{
|
|
return gui_frame_encode(message_type, sequence, payload, payload_size,
|
|
output, output_size);
|
|
}
|
|
|
|
size_t pcan_abi_gui_parser_size(void)
|
|
{
|
|
return sizeof(gui_parser_t);
|
|
}
|
|
|
|
int pcan_abi_gui_parser_init(void *parser_storage, size_t storage_size)
|
|
{
|
|
if ((parser_storage == NULL) || (storage_size < sizeof(gui_parser_t))) {
|
|
return 0;
|
|
}
|
|
gui_parser_init((gui_parser_t *)parser_storage);
|
|
return 1;
|
|
}
|
|
|
|
int pcan_abi_gui_parser_push(void *parser_storage, uint8_t byte,
|
|
pcan_abi_gui_frame_t *output)
|
|
{
|
|
gui_frame_t frame;
|
|
if ((parser_storage == NULL) || (output == NULL)) {
|
|
return -1;
|
|
}
|
|
if (!gui_parser_push((gui_parser_t *)parser_storage, byte, &frame)) {
|
|
return 0;
|
|
}
|
|
output->message_type = frame.type;
|
|
output->sequence = frame.sequence;
|
|
output->size = frame.size;
|
|
if (frame.size != 0U) {
|
|
memcpy(output->payload, frame.payload, frame.size);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int pcan_abi_gui_parser_stats(const void *parser_storage, uint32_t *frames,
|
|
uint32_t *crc_errors, uint32_t *version_errors,
|
|
uint32_t *length_errors, uint32_t *stray_bytes)
|
|
{
|
|
const gui_parser_t *parser = (const gui_parser_t *)parser_storage;
|
|
if (parser == NULL) {
|
|
return 0;
|
|
}
|
|
if (frames != NULL) *frames = parser->stats.frames;
|
|
if (crc_errors != NULL) *crc_errors = parser->stats.crc_errors;
|
|
if (version_errors != NULL) *version_errors = parser->stats.version_errors;
|
|
if (length_errors != NULL) *length_errors = parser->stats.length_errors;
|
|
if (stray_bytes != NULL) *stray_bytes = parser->stats.stray_bytes;
|
|
return 1;
|
|
}
|