Skip to content

Commit 9a450c8

Browse files
committed
samples: drivers: lin: add new sample for LIN responder mode
Add new sample for LIN act as responder (slave) node Signed-off-by: The Nguyen <[email protected]>
1 parent a2b76ab commit 9a450c8

File tree

7 files changed

+384
-0
lines changed

7 files changed

+384
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(lin_counter)
6+
7+
FILE(GLOB app_sources src/*.c)
8+
target_sources(app PRIVATE ${app_sources})
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright (c) 2025 Renesas Electronics Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
mainmenu "LIN Counter Sample"
5+
6+
source "Kconfig.zephyr"
7+
8+
choice LIN_BUS_BAUDRATE
9+
prompt "Select LIN bus baudrate used in this sample"
10+
default LIN_BUS_BAUDRATE_19200
11+
12+
config LIN_BUS_BAUDRATE_2400
13+
bool "2400 bps"
14+
help
15+
Configure LIN node baudrate to 2400 bps.
16+
17+
config LIN_BUS_BAUDRATE_9600
18+
bool "9600 bps"
19+
help
20+
Configure LIN node baudrate to 9600 bps.
21+
22+
config LIN_BUS_BAUDRATE_10400
23+
bool "10400 bps"
24+
help
25+
Configure LIN node baudrate to 10400 bps.
26+
27+
config LIN_BUS_BAUDRATE_19200
28+
bool "19200 bps"
29+
help
30+
Configure LIN node baudrate to 19200 bps.
31+
32+
endchoice
33+
34+
choice LIN_BUS_CHECKSUM_TYPE
35+
prompt "Select LIN bus checksum type used in this sample"
36+
default LIN_BUS_CLASSIC_CHECKSUM
37+
38+
config LIN_BUS_CLASSIC_CHECKSUM
39+
bool "Classic Checksum"
40+
help
41+
Configure LIN node to use Classic Checksum.
42+
43+
config LIN_BUS_ENHANCED_CHECKSUM
44+
bool "Enhanced Checksum"
45+
help
46+
Configure LIN node to use Enhanced Checksum.
47+
48+
endchoice
49+
50+
config COUNTER_UPDATE_ID
51+
hex "LIN Frame ID to poll counter value"
52+
default 0x20
53+
help
54+
This configuration option selects the LIN frame ID used by the
55+
controller to poll the current counter value.
56+
57+
config COUNTER_UPDATE_PERIOD_MS
58+
int "Counter update period (ms)"
59+
range 500 5000
60+
default 1000
61+
help
62+
This configuration option selects the period at which the counter
63+
value increments by 1.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
.. zephyr:code-sample:: lin-counter
2+
:name: Local Interconnect Network (LIN) counter
3+
:relevant-api: lin_controller
4+
5+
Responses to LIN messages in slave mode.
6+
7+
Overview
8+
********
9+
This sample demonstrates how to use the Local Interconnect Network (LIN) API.
10+
The LIN controller acts as a LIN slave node that responds to LIN master requests.
11+
The LIN master sends a request for a counter value, and the LIN slave responds
12+
with the current counter value. The counter value is incremented periodically with duration could
13+
be configured in Kconfig.
14+
Responses are indicated by blinking the LED (if present) and output of the current counter value
15+
to the console.
16+
17+
Requirements
18+
************
19+
20+
* A board with LIN controller support (e.g., ek_ra8m1/r7fa8m1ahecbd).
21+
* A LIN transceiver connected to the LIN controller pins (e.g., `mikroe LIN Click`_).
22+
* A host PC with LIN adapter and LIN master software (e.g., `PCAN-USB Pro FD`_).
23+
24+
Building and Running
25+
********************
26+
27+
Building and Running for EK-RA8M1
28+
=================================
29+
The :zephyr:board:`ek_ra8m1` board does not come with an onboard LIN transceiver. In order to use
30+
the LIN bus on the EK-RA8M1 board, an external LIN bus transceiver `mikroe LIN Click`_ must be
31+
connected to this board:
32+
33+
- P609 EK-RA8M1 (TXD) <-> RXD mikroe LIN Click
34+
- P610 EK-RA8M1 (RXD) <-> TXD mikroe LIN Click
35+
- GND EK-RA8M1 <--------> GND mikroe LIN Click
36+
- 3.3V EK-RA8M1 <-------> 3V3 mikroe LIN Click
37+
- P601 EK-RA8M1 <--------> EN mikroe LIN Click
38+
- P602 EK-RA8M1 <--------> WK mikroe LIN Click
39+
40+
.. note::
41+
42+
An additional pull-up resistor (10k Ohm) is required between EK-RA8M1 P609 (TXD) and 3.3V to
43+
ensure proper idle state on the LIN bus.
44+
45+
The sample can be built and executed for the EK-RA8M1 as follows:
46+
47+
.. zephyr-app-commands::
48+
:zephyr-app: samples/drivers/lin/counter
49+
:board: ek_ra8m1
50+
:goals: build flash
51+
:compact:
52+
53+
Testing LIN Communication
54+
=========================
55+
To test the LIN communication, connect the LIN transceiver to a host PC with LIN adapter and LIN
56+
master software. Configure the LIN master to send a request for the counter value with the same
57+
identifier as defined in the sample (default is ``0x20``). Start the LIN master software and observe
58+
the console output of the Zephyr application. The counter value should be printed each time the LIN
59+
master sends a request. The LED (if present) should blink each time a response is sent.
60+
61+
For examples, to use the `PCAN-USB Pro FD`_ adapter:
62+
63+
1. Download and install the `PLIN-View Pro`_ tool from the PEAK-System website.
64+
65+
2. Connect the PCAN-USB Pro FD adapter to your computer, then configure the LIN bus settings
66+
(such as channel, baud rate, and master mode) in PLIN-View Pro.
67+
68+
3. Set up a LIN schedule table that includes a frame to request the counter value from the slave
69+
device. Ensure the frame ID matches the counter ID specified in this sample.
70+
71+
4. Run the LIN master schedule in PLIN-View Pro. Monitor the Zephyr application's console for
72+
counter updates and LED activity.
73+
74+
Sample output
75+
=============
76+
77+
.. code-block:: console
78+
79+
LIN DUT started in RESPONDER mode
80+
Counter ID: 0x20
81+
Counter: 0
82+
Counter: 1
83+
Counter Update Frame has been transmitted
84+
85+
.. _mikroe LIN Click:
86+
https://www.mikroe.com/lin-click
87+
88+
.. _PCAN-USB Pro FD:
89+
https://www.peak-system.com/PCAN-USB-Pro-FD.366.0.html?&L=1
90+
91+
.. _PLIN-View Pro:
92+
https://www.peak-system.com/PLIN-View-Pro.243.0.html?&L=1
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2025 Renesas Electronics Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
lin_click0: tle72593ge {
9+
compatible = "infineon,tle72593ge", "lin-transceiver-gpio";
10+
wakeup-gpios = <&ioport6 1 GPIO_ACTIVE_HIGH>;
11+
enable-gpios = <&ioport6 2 GPIO_ACTIVE_HIGH>;
12+
max-bitrate = <20000>;
13+
#phy-cells = <0>;
14+
};
15+
};
16+
17+
&ioport6 {
18+
status = "okay";
19+
};
20+
21+
&pinctrl {
22+
sci0_default: sci0_default {
23+
group1 {
24+
/* TXD */
25+
psels = <RA_PSEL(RA_PSEL_SCI_0, 6, 9)>;
26+
drive-strength = "high";
27+
};
28+
29+
group2 {
30+
/* RXD */
31+
psels = <RA_PSEL(RA_PSEL_SCI_0, 6, 10)>;
32+
};
33+
};
34+
};
35+
36+
&sci0 {
37+
pinctrl-0 = <&sci0_default>;
38+
pinctrl-names = "default";
39+
interrupts = <95 1>, <94 1>, <93 1>, <92 1>, <91 1>, <90 1>;
40+
interrupt-names = "rxi", "txi", "tei", "eri", "aed", "bfd";
41+
status = "okay";
42+
43+
uart {
44+
status = "disabled";
45+
};
46+
47+
i2c {
48+
status = "disabled";
49+
};
50+
51+
dut: lin {
52+
phys = <&lin_click0>;
53+
status = "okay";
54+
};
55+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CONFIG_LIN=y
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
sample:
2+
name: LIN driver counter sample
3+
tests:
4+
sample.drivers.lin.counter:
5+
tags: lin
6+
depends_on: lin
7+
integration_platforms:
8+
- ek_ra8m1/r7fa8m1ahecbd
9+
harness: console
10+
harness_config:
11+
type: one_line
12+
regex:
13+
- "LIN DUT started in RESPONDER mode"
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* Copyright (c) 2025 Renesas Electronics Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/sys/printk.h>
9+
#include <zephyr/device.h>
10+
#include <zephyr/drivers/lin.h>
11+
#include <zephyr/drivers/gpio.h>
12+
13+
#if defined(CONFIG_LIN_BUS_BAUDRATE_2400)
14+
#define LIN_BUS_BAUDRATE 2400
15+
#elif defined(CONFIG_LIN_BUS_BAUDRATE_9600)
16+
#define LIN_BUS_BAUDRATE 9600
17+
#elif defined(CONFIG_LIN_BUS_BAUDRATE_10400)
18+
#define LIN_BUS_BAUDRATE 10400
19+
#elif defined(CONFIG_LIN_BUS_BAUDRATE_19200)
20+
#define LIN_BUS_BAUDRATE 19200
21+
#else
22+
#error "Invalid baudrate setting"
23+
#endif
24+
25+
#if defined(CONFIG_LIN_BUS_CLASSIC_CHECKSUM)
26+
#define LIN_CHECKSUM_TYPE LIN_CHECKSUM_CLASSIC
27+
#elif defined(CONFIG_LIN_BUS_ENHANCED_CHECKSUM)
28+
#define LIN_CHECKSUM_TYPE LIN_CHECKSUM_ENHANCED
29+
#else
30+
#error "Invalid checksum type setting"
31+
#endif
32+
33+
/* Test configuration */
34+
#define COUNTER_UPDATE_FRAME_ID CONFIG_COUNTER_UPDATE_ID
35+
#define COUNTER_UPDATE_INTERVAL_MS CONFIG_COUNTER_UPDATE_PERIOD_MS
36+
37+
/* LED blink duration */
38+
#define LED_BLINK_DURATION_MS 100
39+
40+
/* Recommended slave node framing configuration as mentioned in the LIN 2.1 specification */
41+
#define LIN_BUS_BREAK_LEN 11
42+
#define LIN_BUS_BREAK_DELIMITER_LEN 1
43+
44+
static const struct device *lin_dut = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(dut));
45+
static struct gpio_dt_spec led = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios, {0});
46+
47+
/* LIN DUT configuration */
48+
static const struct lin_config dut_config = {
49+
.mode = LIN_MODE_RESPONDER,
50+
.baudrate = LIN_BUS_BAUDRATE,
51+
.break_len = LIN_BUS_BREAK_LEN,
52+
.break_delimiter_len = LIN_BUS_BREAK_DELIMITER_LEN,
53+
.flags = 0,
54+
};
55+
56+
static uint32_t counter;
57+
58+
static void led_blink_work_handler(struct k_work *work)
59+
{
60+
gpio_pin_set_dt(&led, 0);
61+
}
62+
63+
K_WORK_DELAYABLE_DEFINE(led_blink_work, led_blink_work_handler);
64+
65+
void lin_dut_event_handler(const struct device *dev, const struct lin_event *event, void *user_data)
66+
{
67+
int ret;
68+
69+
if (event->type == LIN_EVT_RX_HEADER) {
70+
struct lin_msg msg = {
71+
.data_len = sizeof(uint32_t),
72+
.checksum_type = LIN_CHECKSUM_TYPE,
73+
.id = lin_get_frame_id(event->header.pid),
74+
.data = &counter,
75+
.flags = 0,
76+
};
77+
78+
if (msg.id == COUNTER_UPDATE_FRAME_ID) {
79+
/* Send response with the current counter value */
80+
printk("Counter Update Frame has been transmitted\n");
81+
ret = lin_response(dev, &msg, K_FOREVER);
82+
if (ret < 0) {
83+
printk("Error: Failed to send Counter Update response\n");
84+
return;
85+
}
86+
} else {
87+
/* Do nothing for other IDs */
88+
return;
89+
}
90+
91+
if (led.port != NULL) {
92+
/* Blink LED to indicate activity */
93+
gpio_pin_set_dt(&led, 1);
94+
95+
/* Schedule work to toggle LED off after duration */
96+
k_work_schedule(&led_blink_work, K_MSEC(LED_BLINK_DURATION_MS));
97+
}
98+
}
99+
}
100+
101+
int main(void)
102+
{
103+
int ret;
104+
105+
if (!device_is_ready(lin_dut)) {
106+
printk("LIN DUT device not found\n");
107+
return 0;
108+
}
109+
110+
if (led.port != NULL) {
111+
if (!device_is_ready(led.port)) {
112+
printk("LED device not found\n");
113+
return 0;
114+
}
115+
116+
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_INACTIVE);
117+
if (ret < 0) {
118+
printk("Failed to configure LED GPIO pin\n");
119+
return 0;
120+
}
121+
}
122+
123+
ret = lin_configure(lin_dut, &dut_config);
124+
if (ret < 0) {
125+
printk("Error configuring LIN DUT [%d]", ret);
126+
return 0;
127+
}
128+
129+
ret = lin_set_callback(lin_dut, lin_dut_event_handler, NULL);
130+
if (ret < 0) {
131+
printk("Error setting LIN DUT event handler [%d]", ret);
132+
return 0;
133+
}
134+
135+
ret = lin_start(lin_dut);
136+
if (ret) {
137+
printk("LIN start failed: %d\n", ret);
138+
return 0;
139+
}
140+
141+
printk("LIN DUT started in RESPONDER mode\n");
142+
printk("Counter ID: 0x%02X\n", COUNTER_UPDATE_FRAME_ID);
143+
144+
counter = 0;
145+
146+
while (true) {
147+
printk("Counter: %u\n", counter++);
148+
k_msleep(COUNTER_UPDATE_INTERVAL_MS);
149+
}
150+
151+
return 0;
152+
}

0 commit comments

Comments
 (0)