From 675842cf9ceae2075691ac97ac0b10a06c320b54 Mon Sep 17 00:00:00 2001 From: David Rebbe Date: Tue, 10 Dec 2024 14:02:18 -0500 Subject: [PATCH] updated can DLC related stuff --- api/icsneo/icsneo.cpp | 16 +++-- communication/packet/canpacket.cpp | 5 +- examples/c/simple/src/main.c | 67 ++++++++++++++++++- .../icsneo/communication/packet/canpacket.h | 3 + include/icsneo/icsneo.h | 9 +-- 5 files changed, 87 insertions(+), 13 deletions(-) diff --git a/api/icsneo/icsneo.cpp b/api/icsneo/icsneo.cpp index 1cab7ab..f755831 100644 --- a/api/icsneo/icsneo.cpp +++ b/api/icsneo/icsneo.cpp @@ -6,6 +6,7 @@ #include "icsneo/communication/message/canmessage.h" #include "icsneo/communication/message/linmessage.h" #include "icsneo/communication/message/ethernetmessage.h" +#include "icsneo/communication/packet/canpacket.h" #include #include @@ -619,7 +620,7 @@ ICSNEO_API icsneo_error_t icsneo_can_message_set_arbid(icsneo_device_t* device, return icsneo_error_success; } -ICSNEO_API icsneo_error_t icsneo_can_message_get_dlc_on_wire(icsneo_device_t* device, icsneo_message_t* message, uint32_t* value) { +ICSNEO_API icsneo_error_t icsneo_can_message_get_dlc(icsneo_device_t* device, icsneo_message_t* message, int32_t* value) { if (!device || !message || !value) { return icsneo_error_invalid_parameters; } @@ -635,7 +636,7 @@ ICSNEO_API icsneo_error_t icsneo_can_message_get_dlc_on_wire(icsneo_device_t* de return icsneo_error_success; } -ICSNEO_API icsneo_error_t icsneo_can_message_set_dlc_on_wire(icsneo_device_t* device, icsneo_message_t* message, uint32_t value) { +ICSNEO_API icsneo_error_t icsneo_can_message_set_dlc(icsneo_device_t* device, icsneo_message_t* message, int32_t value) { if (!device || !message) { return icsneo_error_invalid_parameters; } @@ -646,9 +647,14 @@ ICSNEO_API icsneo_error_t icsneo_can_message_set_dlc_on_wire(icsneo_device_t* de return icsneo_error_invalid_type; } - can_message->dlcOnWire = static_cast(value); - - return icsneo_error_success; + if (value < 0) { + auto res = CAN_LengthToDLC(static_cast(can_message->data.size()), can_message->isCANFD); + can_message->dlcOnWire = res.value_or(0); + return res.has_value() ? icsneo_error_success : icsneo_error_invalid_parameters; + } else { + can_message->dlcOnWire = static_cast(value); + return icsneo_error_success; + } } ICSNEO_API icsneo_error_t icsneo_can_message_is_remote(icsneo_device_t* device, icsneo_message_t* message, bool* value) { diff --git a/communication/packet/canpacket.cpp b/communication/packet/canpacket.cpp index f92181f..683e244 100644 --- a/communication/packet/canpacket.cpp +++ b/communication/packet/canpacket.cpp @@ -3,7 +3,7 @@ using namespace icsneo; -static std::optional CAN_DLCToLength(uint8_t length, bool fd) { +std::optional icsneo::CAN_DLCToLength(uint8_t length, bool fd) { if (length <= 8) return length; @@ -29,8 +29,7 @@ static std::optional CAN_DLCToLength(uint8_t length, bool fd) { return std::nullopt; } -static std::optional CAN_LengthToDLC(size_t dataLength, bool fd) -{ +std::optional icsneo::CAN_LengthToDLC(size_t dataLength, bool fd) { if (dataLength <= 8) return uint8_t(dataLength); diff --git a/examples/c/simple/src/main.c b/examples/c/simple/src/main.c index c189ee6..e6c5223 100644 --- a/examples/c/simple/src/main.c +++ b/examples/c/simple/src/main.c @@ -63,6 +63,8 @@ int process_messages(icsneo_device_t* device, icsneo_message_t** messages, uint3 void print_device_events(icsneo_device_t* device, const char* device_description); +int transmit_can_messages(icsneo_device_t* device); + int main(int argc, char* argv[]) { (void)argc; (void)argv; @@ -116,6 +118,12 @@ int main(int argc, char* argv[]) { print_device_events(device, description); return print_error_code("Failed to open device", res); }; + // Transmit CAN messages + res = transmit_can_messages(device); + if (res != icsneo_error_success) { + print_device_events(device, description); + return print_error_code("Failed to transmit CAN messages", res); + } // Wait for the bus to collect some messages, requires an active bus to get messages printf("Waiting 1 second for messages...\n"); sleep_ms(1000); @@ -228,7 +236,7 @@ int process_messages(icsneo_device_t* device, icsneo_message_t** messages, uint3 uint32_t result = icsneo_message_get_netid(device, message, &netid); result += icsneo_get_netid_name(netid, netid_name, &netid_name_length); result += icsneo_can_message_get_arbid(device, message, &arbid); - result += icsneo_can_message_get_dlc_on_wire(device, message, &dlc); + result += icsneo_can_message_get_dlc(device, message, &dlc); result += icsneo_can_message_is_remote(device, message, &is_remote); result += icsneo_can_message_is_canfd(device, message, &is_canfd); result += icsneo_can_message_is_extended(device, message, &is_extended); @@ -243,9 +251,66 @@ int process_messages(icsneo_device_t* device, icsneo_message_t** messages, uint3 printf(" 0x%x", data[x]); } printf(" ]\n"); + // Lets transmit the message back with an Arbitration ID 1 higher than the original. + result = icsneo_can_message_set_arbid(device, message, arbid + 1); + if (result != icsneo_error_success) { + printf("\tFailed to set CAN Arbitration ID (error: %u) for index %u\n", result, i); + continue; + } + uint32_t tx_msg_count = 1; + result = icsneo_device_transmit_messages(device, &message, &tx_msg_count); + if (result != icsneo_error_success) { + printf("\tFailed to transmit CAN message (error: %u) for index %u\n", result, i); + continue; + } continue; } } return icsneo_error_success; } + +int transmit_can_messages(icsneo_device_t* device) { + uint64_t counter = 0; + + + for (uint32_t i = 0; i < 20000; i++) { + // Create the message + icsneo_message_t* message = NULL; + uint32_t message_count = 1; + icsneo_error_t res = icsneo_can_messages_create(device, &message, message_count); + if (res != icsneo_error_success) { + return print_error_code("Failed to create messages", res); + } + // Set the message attributes + res = icsneo_message_set_netid(device, message, icsneo_netid_hscan); + res += icsneo_can_message_set_arbid(device, message, 0x10); + res += icsneo_can_message_set_canfd(device, message, true); + res += icsneo_can_message_set_extended(device, message, true); + res += icsneo_can_message_set_baudrate_switch(device, message, true); + // Create the payload + uint8_t data[64] = {0}; + data[0] = (uint8_t)(counter >> 56); + data[1] = (uint8_t)(counter >> 48); + data[2] = (uint8_t)(counter >> 40); + data[3] = (uint8_t)(counter >> 32); + data[4] = (uint8_t)(counter >> 24); + data[5] = (uint8_t)(counter >> 16); + data[6] = (uint8_t)(counter >> 8); + data[7] = (uint8_t)(counter >> 0); + data[63] = 0xCA; + res += icsneo_message_set_data(device, message, data, sizeof(data)); + res += icsneo_can_message_set_dlc(device, message, -1); + if (res != icsneo_error_success) { + return print_error_code("Failed to modify message", res); + } + res = icsneo_device_transmit_messages(device, &message, &message_count); + res += icsneo_can_message_free(device, message); + if (res != icsneo_error_success) { + return print_error_code("Failed to transmit messages", res); + } + counter++; + } + + return icsneo_error_success; +} diff --git a/include/icsneo/communication/packet/canpacket.h b/include/icsneo/communication/packet/canpacket.h index 8d0c64a..cd180ca 100644 --- a/include/icsneo/communication/packet/canpacket.h +++ b/include/icsneo/communication/packet/canpacket.h @@ -13,6 +13,9 @@ namespace icsneo { typedef uint16_t icscm_bitfield; +std::optional CAN_DLCToLength(uint8_t length, bool fd); +std::optional CAN_LengthToDLC(size_t dataLength, bool fd); + struct HardwareCANPacket { static std::shared_ptr DecodeToMessage(const std::vector& bytestream); static bool EncodeFromMessage(const CANMessage& message, std::vector& bytestream, const device_eventhandler_t& report); diff --git a/include/icsneo/icsneo.h b/include/icsneo/icsneo.h index 22ec9ec..f671fbb 100644 --- a/include/icsneo/icsneo.h +++ b/include/icsneo/icsneo.h @@ -447,23 +447,24 @@ ICSNEO_API icsneo_error_t icsneo_can_message_set_arbid(icsneo_device_t* device, * * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. */ -ICSNEO_API icsneo_error_t icsneo_can_message_get_dlc_on_wire(icsneo_device_t* device, icsneo_message_t* message, uint32_t* value); +ICSNEO_API icsneo_error_t icsneo_can_message_get_dlc(icsneo_device_t* device, icsneo_message_t* message, int32_t* value); /** @brief Set the DLC on wire of a CAN message * * @param[in] icsneo_device_t* device The device to check against. * @param[in] icsneo_message_t* message The message to check. - * @param[out] uint32_t value DLC to set. + * @param[out] int32_t value DLC to set. Set to a negative value to auto calculate. Auto setting assumes data and + * canfd parameters are correct. Set to 0 on failure. @see icsneo_can_message_set_data and icsneo_can_message_set_canfd * * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. */ -ICSNEO_API icsneo_error_t icsneo_can_message_set_dlc_on_wire(icsneo_device_t* device, icsneo_message_t* message, uint32_t value); +ICSNEO_API icsneo_error_t icsneo_can_message_set_dlc(icsneo_device_t* device, icsneo_message_t* message, int32_t value); /** @brief Get the Remote Transmission Request (RTR) status of a CAN message * * @param[in] icsneo_device_t* device The device to check against. * @param[in] icsneo_message_t* message The message to check. - * @param[out] bool* value Pointer to a uint32_t to copy the remote status into. + * @param[in] int32_t value DLC to get. * * @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise. */