Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ body:
- esp_delta_ota
- esp_encrypted_img
- esp_gcov
- esp_isotp
- esp_jpeg
- esp_lcd_qemu_rgb
- esp_serial_slave_link
Expand Down
2 changes: 1 addition & 1 deletion .github/setup_qemu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set -e

# QEMU version and date string for easy maintenance
QEMU_VERSION="9.2.2"
QEMU_DATE="20250228"
QEMU_DATE="20250817"
QEMU_RELEASE="esp-develop-${QEMU_VERSION}-${QEMU_DATE}"

# 1. Detect host architecture
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/upload_component.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ jobs:
esp_delta_ota;
esp_encrypted_img;
esp_gcov;
esp_isotp;
esp_lcd_qemu_rgb;
esp_jpeg;
esp_serial_slave_link;
Expand Down
1 change: 1 addition & 0 deletions .idf_build_apps.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ manifest_file = [
"esp_serial_slave_link/.build-test-rules.yml",
"expat/.build-test-rules.yml",
"iqmath/.build-test-rules.yml",
"esp_isotp/.build-test-rules.yml",
"jsmn/.build-test-rules.yml",
"json_generator/.build-test-rules.yml",
"json_parser/.build-test-rules.yml",
Expand Down
Empty file added esp_isotp/.build-test-rules.yml
Empty file.
7 changes: 7 additions & 0 deletions esp_isotp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
idf_component_register(
SRCS "src/esp_isotp.c" "isotp-c/isotp.c"
INCLUDE_DIRS "inc"
PRIV_INCLUDE_DIRS "isotp-c"
REQUIRES esp_driver_twai
PRIV_REQUIRES esp_timer
)
75 changes: 75 additions & 0 deletions esp_isotp/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
menu "ISO-TP Protocol Configuration"

config ISO_TP_DEFAULT_BLOCK_SIZE
int "Default Block Size"
default 8
range 1 32
help
Maximum number of consecutive frames the receiver can receive at one time.
This value is affected by CAN driver queue length.
Higher values improve throughput but require more buffer space.

config ISO_TP_DEFAULT_ST_MIN_US
int "Default STmin (microseconds)"
default 1000
range 0 50000
help
The STmin parameter specifies the minimum time gap allowed between
the transmission of consecutive frame network protocol data units.
0 = no delay, 1-50000 microseconds for timing control.

config ISO_TP_MAX_WFT_NUMBER
int "Maximum Wait Frame Number"
default 1
range 1 10
help
This parameter indicates how many FC N_PDU WTs (Wait frames) can be
transmitted by the receiver in a row before giving up.

config ISO_TP_DEFAULT_RESPONSE_TIMEOUT_US
int "Default Response Timeout (microseconds)"
default 100000
range 10000 5000000
help
The default timeout to use when waiting for a response during a
multi-frame send or receive operation.
Common values: 100000 (100ms), 1000000 (1s).

config ISO_TP_FRAME_PADDING
bool "Enable Frame Padding"
default n
help
Enable padding of ISO-TP message frames to full CAN frame size.
When enabled, frames are padded with ISO_TP_FRAME_PADDING_VALUE.

config ISO_TP_FRAME_PADDING_VALUE
hex "Frame Padding Value"
default 0xAA
range 0x00 0xFF
depends on ISO_TP_FRAME_PADDING
help
Value used for padding when ISO_TP_FRAME_PADDING is enabled.
Common values: 0x00, 0xAA, 0xCC, 0xFF.

config ISO_TP_USER_SEND_CAN_ARG
bool "Enable User Send CAN Argument"
default y
help
Determines if an additional argument is present in the
definition of isotp_user_send_can function.

config ISO_TP_TRANSMIT_COMPLETE_CALLBACK
bool "Enable Transmit Complete Callback"
default y
help
Enable support for transmission complete callback functions.
Allows applications to be notified when transmission is finished.

config ISO_TP_RECEIVE_COMPLETE_CALLBACK
bool "Enable Receive Complete Callback"
default y
help
Enable support for receive complete callback functions.
Allows applications to be notified when a message is received.

endmenu
22 changes: 22 additions & 0 deletions esp_isotp/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
MIT License

Copyright (c) 2019-2024 Li Shen & Co-Operators
Copyright (c) 2024 Simon Cahill & Contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
72 changes: 72 additions & 0 deletions esp_isotp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# ESP-IDF ISO-TP Component

[![Component Registry](https://components.espressif.com/components/espressif/esp_isotp/badge.svg)](https://components.espressif.com/components/espressif/esp_isotp)

ISO 15765-2 (ISO-TP) transport protocol implementation for ESP-IDF, enabling reliable transmission of large data payloads (up to 4095 bytes) over TWAI networks with automatic segmentation and reassembly.

## Key Features

- **Automatic segmentation** for messages >7 bytes with flow control
- **Non-blocking API** with ISR-based frame processing
- **Multi-instance support** for concurrent communication channels
- **Automotive compliance** (UDS, OBD-II compatible)
- **Robust error handling** with timeout and sequence validation

> [!NOTE]
> TWAI-FD (Flexible Data-rate) is not supported in this version.

## Installation

```bash
idf.py add-dependency espressif/esp_isotp
```

## Configuration

Configure ISO-TP protocol parameters:

```bash
idf.py menuconfig
# Navigate to: Component config → ISO-TP Protocol Configuration
```

## Quick Start

```c
#include "esp_isotp.h"
#include "esp_twai_onchip.h"

void app_main(void) {
// 1. Initialize TWAI
twai_onchip_node_config_t twai_cfg = {
.io_cfg = {.tx = GPIO_NUM_5, .rx = GPIO_NUM_4},
.bit_timing = {.bitrate = 500000},
.tx_queue_depth = 16,
};
twai_node_handle_t twai_node;
ESP_ERROR_CHECK(twai_new_node_onchip(&twai_cfg, &twai_node));

// 2. Create ISO-TP transport
esp_isotp_config_t config = {
.tx_id = 0x7E0, .rx_id = 0x7E8,
.tx_buffer_size = 4096, .rx_buffer_size = 4096,
};
esp_isotp_handle_t isotp_handle;
ESP_ERROR_CHECK(esp_isotp_new_transport(twai_node, &config, &isotp_handle));

// 3. Communication loop
uint8_t buffer[4096];
uint32_t received_size;

while (1) {
esp_isotp_poll(isotp_handle); // CRITICAL: Call every 1-10ms

if (esp_isotp_receive(isotp_handle, buffer, sizeof(buffer), &received_size) == ESP_OK) {
printf("Received %lu bytes\n", received_size);
esp_isotp_send(isotp_handle, buffer, received_size); // Echo back
}

vTaskDelay(pdMS_TO_TICKS(5));
}
}
```
7 changes: 7 additions & 0 deletions esp_isotp/idf_component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: "0.1.0"
description: ISO-TP (ISO 15765-2) protocol implementation for ESP-IDF
url: https://github.com/espressif/idf-extra-components/tree/master/esp_isotp
repository: https://github.com/espressif/idf-extra-components.git
issues: https://github.com/espressif/idf-extra-components/issues
dependencies:
idf: ">=5.5.0"
147 changes: 147 additions & 0 deletions esp_isotp/inc/esp_isotp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once
/**
* @file esp_isotp.h
* @brief ISO-TP (ISO 15765-2) Transport Protocol Implementation
*
* ISO-TP enables transmission of data larger than 8 bytes over TWAI networks
* through automatic fragmentation and reassembly.
*
* ## How it Works
*
* **Small packets (≤7 bytes)**: Sent in a single TWAI frame immediately.
* **Large packets (>7 bytes)**: Split into multiple frames - first frame sent immediately,
* remaining frames sent during esp_isotp_poll() calls.
*
* ## Basic Usage
* ```c
* esp_isotp_handle_t handle;
* esp_isotp_new_transport(twai_node, &config, &handle);
*
* while (1) {
* esp_isotp_poll(handle); // MUST call regularly!
*
* // Send data (non-blocking)
* esp_isotp_send(handle, data, size);
*
* // Check for received data (non-blocking)
* uint16_t received_size;
* if (esp_isotp_receive(handle, buffer, sizeof(buffer), &received_size) == ESP_OK) {
* // Complete message received
* }
*
* vTaskDelay(pdMS_TO_TICKS(5));
* }
* ```
*/

#include "esp_err.h"
#include "esp_twai.h"
#include "esp_twai_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief ISO-TP link handle
*/
typedef struct esp_isotp_link_t *esp_isotp_handle_t;

/**
* @brief Configuration structure for creating a new ISO-TP link
*/
typedef struct {
uint32_t tx_id; /*!< TWAI ID for transmitting ISO-TP frames */
uint32_t rx_id; /*!< TWAI ID for receiving ISO-TP frames */
uint32_t tx_buffer_size; /*!< Size of the transmit buffer (max message size to send) */
uint32_t rx_buffer_size; /*!< Size of the receive buffer (max message size to receive) */
} esp_isotp_config_t;

/**
* @brief Create a new ISO-TP link
*
* @param twai_node TWAI node handle
* @param config Pointer to the configuration structure
* @param[out] out_handle Pointer to store the created ISO-TP handle
* @return esp_err_t
* - ESP_OK: Success
* - ESP_ERR_INVALID_ARG: Invalid argument
* - ESP_ERR_NO_MEM: Out of memory
*/
esp_err_t esp_isotp_new_transport(twai_node_handle_t twai_node, const esp_isotp_config_t *config, esp_isotp_handle_t *out_handle);

/**
* @brief Send data over an ISO-TP link (non-blocking)
*
* Immediately sends first/single frame and returns. For multi-frame messages,
* remaining frames are sent during subsequent esp_isotp_poll() calls.
*
* @param handle ISO-TP handle
* @param data Data to send
* @param size Data length in bytes
* @return
* - ESP_OK: Send initiated successfully
* - ESP_ERR_NOT_FINISHED: Previous send still in progress
* - ESP_ERR_NO_MEM: Data too large for buffer
* - ESP_ERR_INVALID_ARG: Invalid parameters
*/
esp_err_t esp_isotp_send(esp_isotp_handle_t handle, const uint8_t *data, uint32_t size);

/**
* @brief Extract a complete received message (non-blocking)
*
* This function only extracts data that has already been assembled by esp_isotp_poll().
* It does NOT process incoming TWAI frames - that happens in esp_isotp_poll().
*
* Process: TWAI frames → esp_isotp_poll() assembles → esp_isotp_receive() extracts
*
* @param handle ISO-TP handle
* @param data Buffer to store received data
* @param size Buffer size in bytes
* @param[out] received_size Actual received data length
* @return
* - ESP_OK: Complete message extracted and internal buffer cleared
* - ESP_ERR_NOT_FOUND: No complete message ready for extraction
* - ESP_ERR_INVALID_ARG: Invalid parameters
*/
esp_err_t esp_isotp_receive(esp_isotp_handle_t handle, uint8_t *data, uint32_t size, uint32_t *received_size);

/**
* @brief Poll the ISO-TP link to process messages (CRITICAL - call regularly!)
*
* This function drives the ISO-TP state machine. Call every 1-10ms for proper operation.
*
* What it does:
* - Sends remaining frames for multi-frame messages
* - Processes incoming TWAI frames and assembles complete messages
* - Handles flow control and timeouts
* - Updates internal state machine
*
* Without regular polling: multi-frame sends will stall and receives won't complete.
*
* @param handle ISO-TP handle
* @return
* - ESP_OK: Processing successful
* - ESP_ERR_INVALID_ARG: Invalid parameters
*/
esp_err_t esp_isotp_poll(esp_isotp_handle_t handle);

/**
* @brief Delete an ISO-TP link
*
* @param handle The handle of the ISO-TP link to delete
* @return
* - ESP_OK: Success
* - ESP_ERR_INVALID_ARG: Invalid argument
*/
esp_err_t esp_isotp_delete(esp_isotp_handle_t handle);

#ifdef __cplusplus
}
#endif
Loading
Loading