mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
C2: Add LIN message support
This commit is contained in:
committed by
Kyle Schwarz
parent
6dc005fcea
commit
f5f6d0828b
@@ -0,0 +1,6 @@
|
||||
add_executable(libicsneoc2-lin-example src/main.c)
|
||||
target_link_libraries(libicsneoc2-lin-example icsneoc2-static)
|
||||
|
||||
if(WIN32)
|
||||
target_compile_definitions(libicsneoc2-lin-example PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
@@ -0,0 +1,311 @@
|
||||
/* Note: This example requires LIN 1 and LIN 2 channels to be connected on the device */
|
||||
|
||||
#include <icsneo/icsneoc2.h>
|
||||
#include <icsneo/icsneoc2messages.h>
|
||||
#include <icsneo/icsneoc2settings.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
void sleep_ms(uint32_t ms) {
|
||||
#ifdef _WIN32
|
||||
Sleep(ms);
|
||||
#else
|
||||
sleep(ms / 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
int print_error_code(const char* message, icsneoc2_error_t error) {
|
||||
char error_str[64];
|
||||
size_t error_str_len = sizeof(error_str);
|
||||
icsneoc2_error_t res = icsneoc2_error_code_get(error, error_str, &error_str_len);
|
||||
if(res != icsneoc2_error_success) {
|
||||
printf("%s: Failed to get string for error code %d with error code %d\n", message, error, res);
|
||||
return res;
|
||||
}
|
||||
printf("%s: \"%s\" (%u)\n", message, error_str, error);
|
||||
return (int)error;
|
||||
}
|
||||
|
||||
void print_events(const char* device_description) {
|
||||
icsneoc2_event_t* events[1024] = {0};
|
||||
size_t events_count = 1024;
|
||||
for(size_t i = 0; i < events_count; ++i) {
|
||||
icsneoc2_error_t res = icsneoc2_event_get(&events[i], NULL);
|
||||
if(res != icsneoc2_error_success) {
|
||||
for(size_t j = 0; j < i; ++j) {
|
||||
icsneoc2_event_free(events[j]);
|
||||
}
|
||||
(void)print_error_code("\tFailed to get device events", res);
|
||||
return;
|
||||
}
|
||||
if(events[i] == NULL) {
|
||||
events_count = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(size_t i = 0; i < events_count; i++) {
|
||||
char event_description[255] = {0};
|
||||
size_t event_description_length = 255;
|
||||
icsneoc2_error_t res = icsneoc2_event_description_get(events[i], event_description, &event_description_length);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_error_code("\tFailed to get event description", res);
|
||||
continue;
|
||||
}
|
||||
printf("\t%s: Event %zu: %s\n", device_description, i, event_description);
|
||||
}
|
||||
for(size_t i = 0; i < events_count; i++) {
|
||||
icsneoc2_event_free(events[i]);
|
||||
}
|
||||
printf("\t%s: Received %zu events\n", device_description, events_count);
|
||||
}
|
||||
|
||||
void process_lin_messages(icsneoc2_message_t** messages, size_t count) {
|
||||
for(size_t i = 0; i < count; i++) {
|
||||
bool is_lin = false;
|
||||
icsneoc2_error_t res = icsneoc2_message_is_lin(messages[i], &is_lin);
|
||||
if(res != icsneoc2_error_success || !is_lin)
|
||||
continue;
|
||||
|
||||
uint8_t id = 0;
|
||||
uint8_t protected_id = 0;
|
||||
uint8_t checksum = 0;
|
||||
icsneoc2_lin_msg_type_t msg_type = 0;
|
||||
bool is_enhanced_checksum = false;
|
||||
res = icsneoc2_message_lin_props_get(messages[i], &id, &protected_id, &checksum, &msg_type, &is_enhanced_checksum);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_error_code("\tFailed to get LIN properties", res);
|
||||
continue;
|
||||
}
|
||||
|
||||
icsneoc2_netid_t netid = 0;
|
||||
icsneoc2_message_netid_get(messages[i], &netid);
|
||||
char netid_name[128] = {0};
|
||||
size_t netid_name_length = 128;
|
||||
icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
|
||||
|
||||
uint8_t data[64] = {0};
|
||||
size_t data_length = 64;
|
||||
icsneoc2_message_data_get(messages[i], data, &data_length);
|
||||
|
||||
icsneoc2_lin_err_flags_t err_flags = 0;
|
||||
icsneoc2_message_lin_err_flags_get(messages[i], &err_flags);
|
||||
|
||||
printf("\t%s RX | ID: 0x%02x | Protected ID: 0x%02x\n", netid_name, id, protected_id);
|
||||
printf("\tData: [");
|
||||
for(size_t x = 0; x < data_length; x++) {
|
||||
printf(" 0x%02x", data[x]);
|
||||
}
|
||||
printf(" ]\n");
|
||||
printf("\tChecksum type: %s\n", is_enhanced_checksum ? "Enhanced" : "Classic");
|
||||
printf("\tChecksum: 0x%02x\n", checksum);
|
||||
printf("\tChecksum valid: %s\n\n", (!(err_flags & ICSNEOC2_LIN_ERR_CHECKSUM_MATCH)) ? "yes" : "no");
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
/* Open the first available device */
|
||||
printf("Opening first available device...\n");
|
||||
icsneoc2_device_t* device = NULL;
|
||||
icsneoc2_error_t res = icsneoc2_device_open_first(0, icsneoc2_open_options_default, &device);
|
||||
if(res != icsneoc2_error_success) {
|
||||
return print_error_code("\tFailed to open first device", res);
|
||||
}
|
||||
|
||||
char description[255] = {0};
|
||||
size_t description_length = 255;
|
||||
res = icsneoc2_device_description_get(device, description, &description_length);
|
||||
if(res != icsneoc2_error_success) {
|
||||
icsneoc2_device_close(device);
|
||||
return print_error_code("\tFailed to get device description", res);
|
||||
}
|
||||
printf("\tOpened device: %s\n\n", description);
|
||||
|
||||
/* Configure LIN settings */
|
||||
int64_t baud = 19200;
|
||||
|
||||
printf("Enable LIN 01 commander resistor... ");
|
||||
res = icsneoc2_settings_commander_resistor_set(device, icsneoc2_netid_lin_01, true);
|
||||
printf("%s\n", res == icsneoc2_error_success ? "OK" : "FAIL");
|
||||
|
||||
printf("Disable LIN 02 commander resistor... ");
|
||||
res = icsneoc2_settings_commander_resistor_set(device, icsneoc2_netid_lin_02, false);
|
||||
printf("%s\n", res == icsneoc2_error_success ? "OK" : "FAIL");
|
||||
|
||||
printf("Setting LIN 01 baudrate to %" PRId64 " bit/s... ", baud);
|
||||
res = icsneoc2_settings_baudrate_set(device, icsneoc2_netid_lin_01, baud);
|
||||
printf("%s\n", res == icsneoc2_error_success ? "OK" : "FAIL");
|
||||
|
||||
printf("Setting LIN 02 baudrate to %" PRId64 " bit/s... ", baud);
|
||||
res = icsneoc2_settings_baudrate_set(device, icsneoc2_netid_lin_02, baud);
|
||||
printf("%s\n", res == icsneoc2_error_success ? "OK" : "FAIL");
|
||||
|
||||
printf("Setting LIN 01 mode to NORMAL... ");
|
||||
res = icsneoc2_settings_lin_mode_set(device, icsneoc2_netid_lin_01, icsneoc2_lin_mode_normal);
|
||||
printf("%s\n", res == icsneoc2_error_success ? "OK" : "FAIL");
|
||||
|
||||
printf("Setting LIN 02 mode to NORMAL... ");
|
||||
res = icsneoc2_settings_lin_mode_set(device, icsneoc2_netid_lin_02, icsneoc2_lin_mode_normal);
|
||||
printf("%s\n", res == icsneoc2_error_success ? "OK" : "FAIL");
|
||||
|
||||
printf("Applying settings... ");
|
||||
res = icsneoc2_settings_apply(device);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_events(description);
|
||||
icsneoc2_device_close(device);
|
||||
return print_error_code("\tFailed to apply settings", res);
|
||||
}
|
||||
printf("OK\n");
|
||||
|
||||
printf("Getting LIN 01 baudrate... ");
|
||||
int64_t read_baud = 0;
|
||||
res = icsneoc2_settings_baudrate_get(device, icsneoc2_netid_lin_01, &read_baud);
|
||||
if(res == icsneoc2_error_success)
|
||||
printf("OK, %" PRId64 " bit/s\n", read_baud);
|
||||
else
|
||||
printf("FAIL\n");
|
||||
|
||||
printf("Getting LIN 02 baudrate... ");
|
||||
res = icsneoc2_settings_baudrate_get(device, icsneoc2_netid_lin_02, &read_baud);
|
||||
if(res == icsneoc2_error_success)
|
||||
printf("OK, %" PRId64 " bit/s\n\n", read_baud);
|
||||
else
|
||||
printf("FAIL\n\n");
|
||||
|
||||
/* Transmit a LIN responder data update on LIN 02 */
|
||||
printf("Transmitting a LIN 02 responder data frame... ");
|
||||
{
|
||||
icsneoc2_message_t* msg = NULL;
|
||||
res = icsneoc2_message_lin_create(&msg, 0x11);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_events(description);
|
||||
icsneoc2_device_close(device);
|
||||
return print_error_code("\tFailed to create LIN message", res);
|
||||
}
|
||||
icsneoc2_lin_msg_type_t msg_type = icsneoc2_lin_msg_type_update_responder;
|
||||
res = icsneoc2_message_lin_props_set(msg, NULL, NULL, &msg_type, NULL);
|
||||
uint8_t data[] = {0xaa, 0xbb, 0xcc, 0xdd, 0x11, 0x22, 0x33, 0x44};
|
||||
res += icsneoc2_message_data_set(msg, data, sizeof(data));
|
||||
res += icsneoc2_message_netid_set(msg, icsneoc2_netid_lin_02);
|
||||
res += icsneoc2_message_lin_calc_checksum(msg);
|
||||
if(res != icsneoc2_error_success) {
|
||||
icsneoc2_message_free(msg);
|
||||
print_events(description);
|
||||
icsneoc2_device_close(device);
|
||||
return print_error_code("\tFailed to set LIN message properties", res);
|
||||
}
|
||||
res = icsneoc2_device_message_transmit(device, msg);
|
||||
icsneoc2_message_free(msg);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_events(description);
|
||||
icsneoc2_device_close(device);
|
||||
return print_error_code("\tFailed to transmit LIN responder message", res);
|
||||
}
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
/* Transmit a LIN commander header on LIN 01 */
|
||||
printf("Transmitting a LIN 01 commander header... ");
|
||||
{
|
||||
icsneoc2_message_t* msg = NULL;
|
||||
res = icsneoc2_message_lin_create(&msg, 0x11);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_events(description);
|
||||
icsneoc2_device_close(device);
|
||||
return print_error_code("\tFailed to create LIN message", res);
|
||||
}
|
||||
icsneoc2_lin_msg_type_t msg_type = icsneoc2_lin_msg_type_header_only;
|
||||
res = icsneoc2_message_lin_props_set(msg, NULL, NULL, &msg_type, NULL);
|
||||
res += icsneoc2_message_netid_set(msg, icsneoc2_netid_lin_01);
|
||||
if(res != icsneoc2_error_success) {
|
||||
icsneoc2_message_free(msg);
|
||||
print_events(description);
|
||||
icsneoc2_device_close(device);
|
||||
return print_error_code("\tFailed to set LIN message properties", res);
|
||||
}
|
||||
res = icsneoc2_device_message_transmit(device, msg);
|
||||
icsneoc2_message_free(msg);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_events(description);
|
||||
icsneoc2_device_close(device);
|
||||
return print_error_code("\tFailed to transmit LIN header", res);
|
||||
}
|
||||
printf("OK\n\n");
|
||||
}
|
||||
|
||||
sleep_ms(100);
|
||||
|
||||
/* Transmit a LIN commander message with data on LIN 01 */
|
||||
printf("Transmitting a LIN 01 commander frame with data... ");
|
||||
{
|
||||
icsneoc2_message_t* msg = NULL;
|
||||
res = icsneoc2_message_lin_create(&msg, 0x22);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_events(description);
|
||||
icsneoc2_device_close(device);
|
||||
return print_error_code("\tFailed to create LIN message", res);
|
||||
}
|
||||
icsneoc2_lin_msg_type_t msg_type = icsneoc2_lin_msg_type_commander_msg;
|
||||
bool enhanced = true;
|
||||
res = icsneoc2_message_lin_props_set(msg, NULL, NULL, &msg_type, &enhanced);
|
||||
uint8_t data[] = {0x11, 0x22, 0x33, 0x44, 0xaa, 0xbb, 0xcc, 0xdd};
|
||||
res += icsneoc2_message_data_set(msg, data, sizeof(data));
|
||||
res += icsneoc2_message_netid_set(msg, icsneoc2_netid_lin_01);
|
||||
res += icsneoc2_message_lin_calc_checksum(msg);
|
||||
if(res != icsneoc2_error_success) {
|
||||
icsneoc2_message_free(msg);
|
||||
print_events(description);
|
||||
icsneoc2_device_close(device);
|
||||
return print_error_code("\tFailed to set LIN message properties", res);
|
||||
}
|
||||
res = icsneoc2_device_message_transmit(device, msg);
|
||||
icsneoc2_message_free(msg);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_events(description);
|
||||
icsneoc2_device_close(device);
|
||||
return print_error_code("\tFailed to transmit LIN commander message", res);
|
||||
}
|
||||
printf("OK\n\n");
|
||||
}
|
||||
|
||||
sleep_ms(100);
|
||||
|
||||
/* Read back any received messages and display LIN frames */
|
||||
icsneoc2_message_t* messages[2048] = {0};
|
||||
size_t message_count = 2048;
|
||||
printf("Getting messages...\n");
|
||||
for(size_t i = 0; i < message_count; ++i) {
|
||||
res = icsneoc2_device_message_get(device, &messages[i], 0);
|
||||
if(res != icsneoc2_error_success) {
|
||||
for(size_t j = 0; j < i; ++j) {
|
||||
icsneoc2_message_free(messages[j]);
|
||||
}
|
||||
print_events(description);
|
||||
icsneoc2_device_close(device);
|
||||
return print_error_code("\tFailed to get messages", res);
|
||||
}
|
||||
if(messages[i] == NULL) {
|
||||
message_count = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("\tReceived %zu messages\n", message_count);
|
||||
process_lin_messages(messages, message_count);
|
||||
for(size_t i = 0; i < message_count; ++i) {
|
||||
icsneoc2_message_free(messages[i]);
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
print_events(description);
|
||||
printf("Closing device... ");
|
||||
res = icsneoc2_device_close(device);
|
||||
printf("%s\n", res == icsneoc2_error_success ? "OK" : "FAIL");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
add_executable(libicsneoc2-lin-transmit-example src/main.c)
|
||||
target_link_libraries(libicsneoc2-lin-transmit-example icsneoc2-static)
|
||||
|
||||
if(WIN32)
|
||||
target_compile_definitions(libicsneoc2-lin-transmit-example PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
@@ -0,0 +1,276 @@
|
||||
#include <icsneo/icsneoc2.h>
|
||||
#include <icsneo/icsneoc2messages.h>
|
||||
#include <icsneo/icsneoc2settings.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
void sleep_ms(uint32_t ms) {
|
||||
#ifdef _WIN32
|
||||
Sleep(ms);
|
||||
#else
|
||||
sleep(ms / 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
int print_error_code(const char* message, icsneoc2_error_t error) {
|
||||
char error_str[64];
|
||||
size_t error_str_len = sizeof(error_str);
|
||||
icsneoc2_error_t res = icsneoc2_error_code_get(error, error_str, &error_str_len);
|
||||
if(res != icsneoc2_error_success) {
|
||||
printf("%s: Failed to get string for error code %d with error code %d\n", message, error, res);
|
||||
return res;
|
||||
}
|
||||
printf("%s: \"%s\" (%u)\n", message, error_str, error);
|
||||
return (int)error;
|
||||
}
|
||||
|
||||
int read_int(const char* prompt, int min_val, int max_val) {
|
||||
int value;
|
||||
while(1) {
|
||||
printf("%s", prompt);
|
||||
if(scanf("%d", &value) != 1) {
|
||||
/* Clear invalid input */
|
||||
int c;
|
||||
while((c = getchar()) != '\n' && c != EOF) {}
|
||||
printf("Invalid input, try again.\n");
|
||||
continue;
|
||||
}
|
||||
if(value < min_val || value > max_val) {
|
||||
printf("Please enter a value between %d and %d.\n", min_val, max_val);
|
||||
continue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
int read_hex(const char* prompt, int min_val, int max_val) {
|
||||
int value;
|
||||
while(1) {
|
||||
printf("%s", prompt);
|
||||
if(scanf("%x", &value) != 1) {
|
||||
/* Clear invalid input */
|
||||
int c;
|
||||
while((c = getchar()) != '\n' && c != EOF) {}
|
||||
printf("Invalid input, try again.\n");
|
||||
continue;
|
||||
}
|
||||
if(value < min_val || value > max_val) {
|
||||
printf("Please enter a value between 0x%X and 0x%X.\n", min_val, max_val);
|
||||
continue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
icsneoc2_error_t res;
|
||||
|
||||
/* ===== Device Selection ===== */
|
||||
printf("Searching for devices...\n");
|
||||
icsneoc2_device_info_t* found_devices = NULL;
|
||||
res = icsneoc2_device_enumerate(0, &found_devices);
|
||||
if(res != icsneoc2_error_success) {
|
||||
return print_error_code("Failed to enumerate devices", res);
|
||||
}
|
||||
if(!found_devices) {
|
||||
printf("No devices found.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Count and display devices */
|
||||
int device_count = 0;
|
||||
for(icsneoc2_device_info_t* cur = found_devices; cur; cur = icsneoc2_device_info_next(cur)) {
|
||||
char desc[128] = {0};
|
||||
size_t desc_len = sizeof(desc);
|
||||
icsneoc2_device_info_description_get(cur, desc, &desc_len);
|
||||
printf(" [%d] %s\n", device_count + 1, desc);
|
||||
device_count++;
|
||||
}
|
||||
|
||||
int device_choice = read_int("Select device: ", 1, device_count);
|
||||
|
||||
/* Find the selected device_info node */
|
||||
icsneoc2_device_info_t* selected_info = found_devices;
|
||||
for(int i = 1; i < device_choice; i++) {
|
||||
selected_info = icsneoc2_device_info_next(selected_info);
|
||||
}
|
||||
|
||||
/* Open the selected device */
|
||||
icsneoc2_device_t* device = NULL;
|
||||
res = icsneoc2_device_create(selected_info, &device);
|
||||
if(res != icsneoc2_error_success) {
|
||||
icsneoc2_enumeration_free(found_devices);
|
||||
return print_error_code("Failed to create device from device info", res);
|
||||
}
|
||||
res = icsneoc2_device_open(device, icsneoc2_open_options_default);
|
||||
icsneoc2_enumeration_free(found_devices);
|
||||
if(res != icsneoc2_error_success) {
|
||||
icsneoc2_device_free(device);
|
||||
return print_error_code("Failed to open device", res);
|
||||
}
|
||||
|
||||
char description[128] = {0};
|
||||
size_t description_length = sizeof(description);
|
||||
icsneoc2_device_description_get(device, description, &description_length);
|
||||
printf("Opened device: %s\n\n", description);
|
||||
|
||||
/* ===== LIN Network Selection ===== */
|
||||
/* Get all supported TX networks */
|
||||
size_t tx_net_count = 0;
|
||||
res = icsneoc2_device_supported_tx_networks_get(device, NULL, &tx_net_count);
|
||||
if(res != icsneoc2_error_success || tx_net_count == 0) {
|
||||
printf("No supported TX networks.\n");
|
||||
icsneoc2_device_close(device);
|
||||
return 1;
|
||||
}
|
||||
|
||||
icsneoc2_netid_t* tx_networks = (icsneoc2_netid_t*)malloc(tx_net_count * sizeof(icsneoc2_netid_t));
|
||||
if(!tx_networks) {
|
||||
printf("Out of memory.\n");
|
||||
icsneoc2_device_close(device);
|
||||
icsneoc2_device_free(device);
|
||||
return 1;
|
||||
}
|
||||
res = icsneoc2_device_supported_tx_networks_get(device, tx_networks, &tx_net_count);
|
||||
if(res != icsneoc2_error_success) {
|
||||
free(tx_networks);
|
||||
icsneoc2_device_close(device);
|
||||
icsneoc2_device_free(device);
|
||||
return print_error_code("Failed to get TX networks", res);
|
||||
}
|
||||
|
||||
/* Filter for LIN networks */
|
||||
icsneoc2_netid_t lin_networks[64] = {0};
|
||||
char lin_names[64][128] = {{0}};
|
||||
size_t lin_count = 0;
|
||||
for(size_t i = 0; i < tx_net_count && lin_count < 64; i++) {
|
||||
icsneoc2_message_t* tmp = NULL;
|
||||
res = icsneoc2_message_lin_create(&tmp, 0);
|
||||
if(res != icsneoc2_error_success) continue;
|
||||
res = icsneoc2_message_netid_set(tmp, tx_networks[i]);
|
||||
if(res != icsneoc2_error_success) { icsneoc2_message_free(tmp); continue; }
|
||||
icsneoc2_network_type_t ntype = 0;
|
||||
res = icsneoc2_message_network_type_get(tmp, &ntype);
|
||||
icsneoc2_message_free(tmp);
|
||||
if(res != icsneoc2_error_success) continue;
|
||||
if(ntype == icsneoc2_network_type_lin) {
|
||||
lin_networks[lin_count] = tx_networks[i];
|
||||
size_t name_len = 128;
|
||||
icsneoc2_netid_name_get(tx_networks[i], lin_names[lin_count], &name_len);
|
||||
lin_count++;
|
||||
}
|
||||
}
|
||||
free(tx_networks);
|
||||
|
||||
if(lin_count == 0) {
|
||||
printf("No LIN networks available on this device.\n");
|
||||
icsneoc2_device_close(device);
|
||||
icsneoc2_device_free(device);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Available LIN networks:\n");
|
||||
for(size_t i = 0; i < lin_count; i++) {
|
||||
printf(" [%zu] %s\n", i + 1, lin_names[i]);
|
||||
}
|
||||
|
||||
int lin_choice = read_int("Select LIN network: ", 1, (int)lin_count);
|
||||
icsneoc2_netid_t selected_netid = lin_networks[lin_choice - 1];
|
||||
printf("Selected: %s\n\n", lin_names[lin_choice - 1]);
|
||||
|
||||
/* ===== Commander / Responder Selection ===== */
|
||||
printf("Message type:\n");
|
||||
printf(" [1] Commander frame\n");
|
||||
printf(" [2] Responder frame (update responder + header only)\n");
|
||||
int type_choice = read_int("Select message type: ", 1, 2);
|
||||
bool is_commander = (type_choice == 1);
|
||||
printf("Selected: %s\n\n", is_commander ? "Commander" : "Responder");
|
||||
|
||||
uint8_t id_choice = (uint8_t)read_hex("Select LIN ID (0x00-0x3F): ", 0, 0x3F);
|
||||
printf("Selected: 0x%02X\n\n", id_choice);
|
||||
|
||||
/* ===== Configure LIN ===== */
|
||||
printf("Configuring %s... ", lin_names[lin_choice - 1]);
|
||||
res = icsneoc2_settings_commander_resistor_set(device, selected_netid, is_commander);
|
||||
res += icsneoc2_settings_baudrate_set(device, selected_netid, 19200);
|
||||
res += icsneoc2_settings_lin_mode_set(device, selected_netid, icsneoc2_lin_mode_normal);
|
||||
res += icsneoc2_settings_apply(device);
|
||||
if(res != icsneoc2_error_success) {
|
||||
icsneoc2_device_close(device);
|
||||
icsneoc2_device_free(device);
|
||||
return print_error_code("Failed to configure LIN", res);
|
||||
}
|
||||
printf("OK\n\n");
|
||||
|
||||
/* ===== Transmit Loop ===== */
|
||||
printf("Transmitting on %s every second for 10 seconds...\n", lin_names[lin_choice - 1]);
|
||||
uint8_t counter = 0;
|
||||
for(int i = 0; i < 10; i++) {
|
||||
icsneoc2_message_t* msg = NULL;
|
||||
res = icsneoc2_message_lin_create(&msg, id_choice);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_error_code("\tFailed to create LIN message", res);
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t data[] = {counter, counter + 1, counter + 2, counter + 3, 0xAA, 0xBB, 0xCC, 0xDD};
|
||||
bool enhanced = true;
|
||||
|
||||
if(is_commander) {
|
||||
/* Commander: send header-only frame to poll the bus */
|
||||
icsneoc2_lin_msg_type_t msg_type = icsneoc2_lin_msg_type_header_only;
|
||||
res = icsneoc2_message_lin_props_set(msg, NULL, NULL, &msg_type, &enhanced);
|
||||
res += icsneoc2_message_netid_set(msg, selected_netid);
|
||||
if(res != icsneoc2_error_success) {
|
||||
icsneoc2_message_free(msg);
|
||||
print_error_code("\tFailed to set commander properties", res);
|
||||
break;
|
||||
}
|
||||
res = icsneoc2_device_message_transmit(device, msg);
|
||||
icsneoc2_message_free(msg);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_error_code("\tFailed to transmit header", res);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Responder: update the responder table with new data */
|
||||
icsneoc2_lin_msg_type_t msg_type = icsneoc2_lin_msg_type_update_responder;
|
||||
res = icsneoc2_message_lin_props_set(msg, NULL, NULL, &msg_type, &enhanced);
|
||||
res += icsneoc2_message_data_set(msg, data, sizeof(data));
|
||||
res += icsneoc2_message_lin_calc_checksum(msg);
|
||||
res += icsneoc2_message_netid_set(msg, selected_netid);
|
||||
if(res != icsneoc2_error_success) {
|
||||
icsneoc2_message_free(msg);
|
||||
print_error_code("\tFailed to update responder", res);
|
||||
break;
|
||||
}
|
||||
res = icsneoc2_device_message_transmit(device, msg);
|
||||
icsneoc2_message_free(msg);
|
||||
if(res != icsneoc2_error_success) {
|
||||
print_error_code("\tFailed to transmit responder update", res);
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("[%2d/10] Transmitted %s msg ID=0x%02X, counter=%u\n",
|
||||
i + 1, is_commander ? "commander" : "responder", id_choice, counter);
|
||||
counter += 4;
|
||||
sleep_ms(1000);
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
printf("\nClosing device... ");
|
||||
res = icsneoc2_device_close(device);
|
||||
printf("%s\n", res == icsneoc2_error_success ? "OK" : "FAIL");
|
||||
icsneoc2_device_free(device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user