/* * Copyright (c) 2020 Alexander Wachter * * SPDX-License-Identifier: Apache-2.0 */ #include #include const struct isotp_fc_opts fc_opts_8_0 = {.bs = 8, .stmin = 0}; const struct isotp_fc_opts fc_opts_0_5 = {.bs = 0, .stmin = 5}; const struct isotp_msg_id rx_addr_8_0 = { .std_id = 0x80, #ifdef CONFIG_SAMPLE_CAN_FD_MODE .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS, #endif }; const struct isotp_msg_id tx_addr_8_0 = { .std_id = 0x180, #ifdef CONFIG_SAMPLE_CAN_FD_MODE .dl = 64, .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS, #endif }; const struct isotp_msg_id rx_addr_0_5 = { .std_id = 0x01, #ifdef CONFIG_SAMPLE_CAN_FD_MODE .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS, #endif }; const struct isotp_msg_id tx_addr_0_5 = { .std_id = 0x101, #ifdef CONFIG_SAMPLE_CAN_FD_MODE .dl = 64, .flags = ISOTP_MSG_FDF | ISOTP_MSG_BRS, #endif }; const struct device *can_dev; struct isotp_recv_ctx recv_ctx_8_0; struct isotp_recv_ctx recv_ctx_0_5; K_THREAD_STACK_DEFINE(rx_8_0_thread_stack, CONFIG_SAMPLE_RX_THREAD_STACK_SIZE); K_THREAD_STACK_DEFINE(rx_0_5_thread_stack, CONFIG_SAMPLE_RX_THREAD_STACK_SIZE); struct k_thread rx_8_0_thread_data; struct k_thread rx_0_5_thread_data; const char tx_data_large[] = "========================================\n" "| ____ ___ ____ ____ ____ |\n" "| |_ _|/ __|| | ___ |_ _|| _ \\ |\n" "| _||_ \\__ \\| || | ___ || | ___/ |\n" "| |____||___/|____| || |_| |\n" "========================================\n"; const char tx_data_small[] = "This is the sample test for the short payload\n"; void rx_8_0_thread(void *arg1, void *arg2, void *arg3) { ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); int ret, rem_len, received_len; struct net_buf *buf; ret = isotp_bind(&recv_ctx_8_0, can_dev, &tx_addr_8_0, &rx_addr_8_0, &fc_opts_8_0, K_FOREVER); if (ret != ISOTP_N_OK) { printk("Failed to bind to rx ID %d [%d]\n", rx_addr_8_0.std_id, ret); return; } while (1) { received_len = 0; do { rem_len = isotp_recv_net(&recv_ctx_8_0, &buf, K_MSEC(2000)); if (rem_len < 0) { printk("Receiving error [%d]\n", rem_len); break; } while (buf != NULL) { received_len += buf->len; printk("%.*s", buf->len, buf->data); buf = net_buf_frag_del(NULL, buf); } } while (rem_len); printk("Got %d bytes in total\n", received_len); } } void rx_0_5_thread(void *arg1, void *arg2, void *arg3) { ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); int ret, received_len; static uint8_t rx_buffer[32]; ret = isotp_bind(&recv_ctx_0_5, can_dev, &tx_addr_0_5, &rx_addr_0_5, &fc_opts_0_5, K_FOREVER); if (ret != ISOTP_N_OK) { printk("Failed to bind to rx ID %d [%d]\n", rx_addr_0_5.std_id, ret); return; } while (1) { received_len = isotp_recv(&recv_ctx_0_5, rx_buffer, sizeof(rx_buffer)-1U, K_MSEC(2000)); if (received_len < 0) { printk("Receiving error [%d]\n", received_len); continue; } rx_buffer[received_len] = '\0'; printk("%s", rx_buffer); } } void send_complette_cb(int error_nr, void *arg) { ARG_UNUSED(arg); printk("TX complete cb [%d]\n", error_nr); } /** * @brief Main application entry point. * */ int main(void) { k_tid_t tid; static struct isotp_send_ctx send_ctx_8_0; static struct isotp_send_ctx send_ctx_0_5; int ret = 0; can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus)); if (!device_is_ready(can_dev)) { printk("CAN: Device driver not ready.\n"); return 0; } can_mode_t mode = (IS_ENABLED(CONFIG_SAMPLE_LOOPBACK_MODE) ? CAN_MODE_LOOPBACK : 0) | (IS_ENABLED(CONFIG_SAMPLE_CAN_FD_MODE) ? CAN_MODE_FD : 0); ret = can_set_mode(can_dev, mode); if (ret != 0) { printk("CAN: Failed to set mode [%d]", ret); return 0; } ret = can_start(can_dev); if (ret != 0) { printk("CAN: Failed to start device [%d]\n", ret); return 0; } tid = k_thread_create(&rx_8_0_thread_data, rx_8_0_thread_stack, K_THREAD_STACK_SIZEOF(rx_8_0_thread_stack), rx_8_0_thread, NULL, NULL, NULL, CONFIG_SAMPLE_RX_THREAD_PRIORITY, 0, K_NO_WAIT); if (!tid) { printk("ERROR spawning rx thread\n"); return 0; } k_thread_name_set(tid, "rx_8_0"); tid = k_thread_create(&rx_0_5_thread_data, rx_0_5_thread_stack, K_THREAD_STACK_SIZEOF(rx_0_5_thread_stack), rx_0_5_thread, NULL, NULL, NULL, CONFIG_SAMPLE_RX_THREAD_PRIORITY, 0, K_NO_WAIT); if (!tid) { printk("ERROR spawning rx thread\n"); return 0; } k_thread_name_set(tid, "rx_0_5"); printk("Start sending data\n"); while (1) { k_msleep(1000); ret = isotp_send(&send_ctx_0_5, can_dev, tx_data_small, sizeof(tx_data_small), &tx_addr_0_5, &rx_addr_0_5, send_complette_cb, NULL); if (ret != ISOTP_N_OK) { printk("Error while sending data to ID %d [%d]\n", tx_addr_0_5.std_id, ret); } ret = isotp_send(&send_ctx_8_0, can_dev, tx_data_large, sizeof(tx_data_large), &tx_addr_8_0, &rx_addr_8_0, NULL, NULL); if (ret != ISOTP_N_OK) { printk("Error while sending data to ID %d [%d]\n", tx_addr_8_0.std_id, ret); } } }