#include "pcan_abi.h" #include #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; }