Share PM67 upload protocol through C core
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#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"
|
||||
@@ -162,6 +163,40 @@ const char *pcan_abi_periph28335_command_name(
|
||||
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)
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "set_crc.h"
|
||||
|
||||
typedef struct {
|
||||
const char *project;
|
||||
const char *commands[PERIPH28335_COMMAND_COUNT];
|
||||
@@ -32,19 +34,7 @@ static uint16_t get_be16(const uint8_t *input)
|
||||
|
||||
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;
|
||||
return set_crc16_modbus(data, size);
|
||||
}
|
||||
|
||||
size_t periph28335_append_crc(const uint8_t *payload, size_t payload_size,
|
||||
|
||||
18
c/set-protocol/src/set_crc.c
Normal file
18
c/set-protocol/src/set_crc.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "set_crc.h"
|
||||
|
||||
uint16_t set_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;
|
||||
}
|
||||
78
c/set-protocol/src/tms2812.c
Normal file
78
c/set-protocol/src/tms2812.c
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "tms2812.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "set_crc.h"
|
||||
|
||||
static void put_le32(uint8_t *output, uint32_t value)
|
||||
{
|
||||
output[0] = (uint8_t)value;
|
||||
output[1] = (uint8_t)(value >> 8);
|
||||
output[2] = (uint8_t)(value >> 16);
|
||||
output[3] = (uint8_t)(value >> 24);
|
||||
}
|
||||
|
||||
uint16_t tms2812_crc16(const uint8_t *data, size_t size)
|
||||
{
|
||||
return set_crc16_modbus(data, size);
|
||||
}
|
||||
|
||||
size_t tms2812_build_upload_request(
|
||||
uint8_t controller, uint32_t word_address, uint32_t byte_count,
|
||||
uint8_t *output, size_t output_size)
|
||||
{
|
||||
uint16_t crc;
|
||||
if ((output == NULL) || (output_size < TMS2812_UPLOAD_REQUEST_SIZE) ||
|
||||
(byte_count == 0U)) return 0U;
|
||||
output[0] = controller;
|
||||
output[1] = TMS2812_CMD_UPLOAD;
|
||||
put_le32(&output[2], word_address);
|
||||
put_le32(&output[6], byte_count);
|
||||
crc = tms2812_crc16(output, 10U);
|
||||
output[10] = (uint8_t)crc;
|
||||
output[11] = (uint8_t)(crc >> 8);
|
||||
return TMS2812_UPLOAD_REQUEST_SIZE;
|
||||
}
|
||||
|
||||
size_t tms2812_expected_upload_response_size(uint32_t byte_count)
|
||||
{
|
||||
if (byte_count == 0U ||
|
||||
(uint64_t)byte_count + TMS2812_UPLOAD_RESPONSE_OVERHEAD > SIZE_MAX) {
|
||||
return 0U;
|
||||
}
|
||||
return (size_t)byte_count + TMS2812_UPLOAD_RESPONSE_OVERHEAD;
|
||||
}
|
||||
|
||||
int tms2812_validate_upload_response(
|
||||
const uint8_t *data, size_t size, uint8_t controller,
|
||||
uint32_t byte_count)
|
||||
{
|
||||
size_t expected = tms2812_expected_upload_response_size(byte_count);
|
||||
size_t crc_offset;
|
||||
uint16_t expected_crc;
|
||||
uint16_t actual_crc;
|
||||
if (data == NULL) return TMS2812_ERROR_ARGUMENT;
|
||||
if (expected == 0U) return TMS2812_ERROR_RANGE;
|
||||
if (size != expected) return TMS2812_ERROR_LENGTH;
|
||||
if ((data[0] != controller) || (data[1] != TMS2812_CMD_UPLOAD))
|
||||
return TMS2812_ERROR_HEADER;
|
||||
crc_offset = (size_t)byte_count + 2U;
|
||||
expected_crc = tms2812_crc16(data, crc_offset);
|
||||
actual_crc = (uint16_t)(data[crc_offset] |
|
||||
((uint16_t)data[crc_offset + 1U] << 8));
|
||||
return actual_crc == expected_crc ? TMS2812_OK : TMS2812_ERROR_CRC;
|
||||
}
|
||||
|
||||
int tms2812_decode_upload_response(
|
||||
const uint8_t *data, size_t size, uint8_t controller,
|
||||
uint32_t byte_count, uint8_t *output, size_t output_size)
|
||||
{
|
||||
int status = tms2812_validate_upload_response(
|
||||
data, size, controller, byte_count);
|
||||
if (status != TMS2812_OK) return status;
|
||||
if ((output == NULL) || (output_size < byte_count))
|
||||
return TMS2812_ERROR_CAPACITY;
|
||||
memcpy(output, &data[2], byte_count);
|
||||
return TMS2812_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user