Files
templates/c/set-protocol/src/pcan_abi.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;
}