# Lin_AutoBaud_Interrupt_Demo

---

## Overview

This demo shows how to implement **LIN slave auto-baud synchronization** on the **YTM32B1LE1** platform using **UART0 + LIN Driver + GPIO edge-switch interrupt + pTMR timestamp sampling**.

The focus of this demo is not fixed-baud LIN communication itself. Instead, it demonstrates how a slave node can do the following after receiving a master header:

1. Detect the Break field with the LIN peripheral.
2. Switch the RX pin to GPIO mode after Break OK and enter falling-edge sampling **before Sync start falling arrives**.
3. Capture `5` falling-edge timestamps from `Sync = 0x55` and use the `4` resulting two-bit intervals to estimate the actual bus baud rate.
4. Complete UART baud pre-configuration within the window from the **5th falling edge to Sync stop rising**.
5. Switch the RX path back to UART only after **Sync stop rising**, then continue receiving PID and payload bytes.

One important point must be stated clearly: the Sync timing measurement in this demo is a **software timestamp solution**, not a hardware input-capture latch solution.

- After a GPIO edge is detected, software reads the current `pTMR` counter **inside the GPIO ISR**.
- For any single adjacent interval, the measured result is effectively equal to "real edge interval + difference between two ISR response latencies".
- However, this demo does not use only one interval. It sums and averages `4` two-bit intervals, so the interrupt latency of the middle falling edges mostly cancels out.
- The main residual error term comes from the interrupt response latency difference between the **1st falling-edge reference point** and the **5th falling edge**.
- If the auto-baud window is affected by **global interrupt masking, long critical sections, or long-running higher-priority ISRs**, and that blocking happens near those first/last key sampling points, the delay difference is converted directly into bit-time measurement error.
- For a customer system, this is not only a timeout risk. It also directly affects baud estimation accuracy, PID reception robustness, and compatibility at baud-rate boundaries.

**Default configuration**

- **Communication role**: LIN Slave
- **LIN instance**: UART0
- **Nominal baud rate**: `19200 bps`
- **Auto-baud mode**: `Every header recalculation` by default; can be changed to `Lock after first successful startup sync`
- **Target auto-baud range**: `+/-10%` relative to nominal baud
- **RX PID**: `0x3C`
- **TX PID**: `0x3D`
- **TX data**: `55 AA 69 96 96 69 AA 55`

**Features**

- **Automatic baud synchronization**: after Break detection, the demo enters GPIO falling-edge sampling; after the 5th falling edge it performs the calculation and UART pre-configuration, then waits for `Sync stop rising`
- **Timestamp measurement**: reads the current `pTMR0 CH0` counter in the `GPIO ISR`, records `5` Sync falling-edge timestamps, and averages `4` two-bit intervals
- **Fast UART reconfiguration**: searches the best `OSR/SBR` pair from the candidate set `{16, 8, 32, 12, 24, 20, 4}`
- **0.5% search target**: this does not mean the bus tolerance is only `0.5%`; it is the divider search target used to improve reception stability within the `+/-10%` baud range
- **Single-file portability**: the auto-baud logic is concentrated in the `USER CODE` sections of `app/main.c`
- **Debug-friendly**: test-point macros are reserved for GPIO toggling so the key timing windows can be observed on an oscilloscope or logic analyzer

---

## Hardware Requirements

- **Board**: YTM32B1LE15-EVB-Q48
- **Debugger**: J-LINK v9.2 or later
- **External equipment**: a LIN master node capable of sending LIN headers, a USB-LIN adapter, or another EVB running a LIN master demo

---

## Hardware Connections

This demo uses the on-board LIN PHY by default. UART0 is connected to the LIN transceiver on the board. During testing, connect the board to an external LIN bus and make sure the on-board LIN PHY is properly powered.

### 1. MCU to On-Board LIN PHY Mapping

| MCU Pin | Board Signal  | Description |
| ------- | ------------- | ----------- |
| PTA3    | LIN_UART0_TX  | UART0 TX, used as the LIN transmit path |
| PTA2    | LIN_UART0_RX  | UART0 RX, also used as the GPIO sampling input during auto-baud |
| PTD2    | LIN_SLEEP_EN  | LIN PHY enable/sleep control, driven high by default |

### 2. Recommended External Test Connections

- Connect the board LIN interface to an external **LIN master node**
- Make sure the external master and the board **share the same ground**
- Provide **12 V VBAT** for the on-board LIN PHY
- The master must be able to send a standard LIN header containing **Break + Sync + PID**

### 3. Recommended Bring-Up Methods

- **Method A**: use this demo as the slave and another EVB running `Lin_Master_Demo` as the master
- **Method B**: use a USB-LIN tool, CANoe, or a bus analyzer to send headers at different baud rates and observe whether the slave completes auto-baud synchronization correctly

---

## Software Requirements

- **SDK**: YTM32B1LE1_1_4_0 or later
- **GCC**: GNU GCC v10.3 or later
- **Keil/MDK**: ARM Keil/MDK v5.36 or later
- **IAR**: IAR v8.40 or later
- **VS Code**: Microsoft Visual Studio Code IDE v1.76 or later, with GNU GCC toolchain, CMake v3.25, ninja, and Cortex-Debug extension
- **J-LINK**: SEGGER J-LINK v6.96 or later, with YTM32B1LE1 device support installed
- **Ozone**: SEGGER Ozone v3.28 or later

---

## LIN Auto-Baud Demo Principles

### 1. Overall Flow

```text
+--------------------------+      +--------------------------+      +--------------------------+
| 1. Slave waits for       | ---> | 2. LIN Driver detects    | ---> | 3. RX is switched to     |
|    header at nominal     |      |    Break                 |      |    GPIO and falling-edge |
|    baud                  |      |                          |      |    interrupt is enabled  |
+--------------------------+      +--------------------------+      +------------+-------------+
                                                                                 |
                                                                                 v
+--------------------------+      +--------------------------+      +------------+-------------+
| 6. Average bit time is   | <--- | 5. GPIO is switched to   | <--- | 4. pTMR records 5 Sync   |
|    computed, OSR is      |      |    rising-edge wait mode |      |    falling edges         |
|    searched, UART is     |      |                          |      |                          |
|    preconfigured         |      |                          |      |                          |
+------------+-------------+      +--------------------------+      +--------------------------+
             |
             v
+------------+-------------+      +--------------------------+      +--------------------------+
| 7. Sync stop rising      | ---> | 8. RX is switched back   | ---> | 9. PID / response        |
|    arrives               |      |    to UART and SYNC_OK   |      |    reception continues   |
|                          |      |    is reported           |      |                          |
+--------------------------+      +--------------------------+      +--------------------------+
```

Flow details:

1. After power-up, the slave enters LIN receive mode at the nominal baud rate, waiting for a header and using the LIN peripheral to detect Break.
2. Once the auto-baud sequence starts, software takes over the RX pin and changes the synchronization path from UART sampling to GPIO falling-edge sampling.
3. `pTMR` provides high-resolution timestamps for the Sync field. The first falling edge is only a reference point. The next `4` falling-edge intervals each represent `2 bit` times.
4. Inside the ISR for the 5th falling edge, software first **switches the GPIO interrupt mode to rising-edge immediately** so a later edge is not missed because of subsequent computation.
5. It then calculates the average bit width, derives the target baud rate, and searches the UART divider configuration.
6. The next rising edge is treated as `Sync stop rising`. Only then does software disable GPIO capture, restore the UART RX mux, and continue to PID reception.
7. If synchronization succeeds, the LIN peripheral returns to the normal data path. If synchronization fails or times out, the current frame is abandoned and the slave waits for the next header.

### 2. Time Measurement, Clock Alignment, and Interrupt Response Requirements

This demo uses `pTMR` to measure Sync edge intervals and then reconfigures `UART` based on that result. Therefore:

- The **pTMR functional clock and UART functional clock should share the same root clock**
- More precisely, both should come from the **same main clock source** or from a fixed divider chain derived from the same source
- If they come from different clock sources, or if one source is accurate and the other drifts significantly, a systematic measurement error is introduced

In addition to clock alignment, **interrupt response consistency** must also be considered. This demo does not latch edge timestamps in hardware. It reads the current `pTMR` counter only after entering the GPIO ISR, so for a single interval the model is approximately:

```text
Timestamp(n) = EdgeTime(n) + IrqLatency(n)
MeasuredDelta = RealDelta + [IrqLatency(n) - IrqLatency(n-1)]
```

Because the demo finally sums and averages `4` two-bit samples, the result can be written as:

```text
AverageMeasuredDelta
= (Delta2 + Delta3 + Delta4 + Delta5) / 4
= AverageRealDelta + [IrqLatency(5) - IrqLatency(1)] / 4
```

This means:

- If the interrupt response latency is roughly constant across sampled edges, the fixed latency mostly cancels in adjacent differences
- For the final averaged result, the interrupt latency of the middle falling edges mostly cancels in the sum
- The dominant residual measurement error depends on whether the interrupt response latency at the **1st falling-edge reference point** and the **5th falling edge** is consistent
- If either of those key sampling points is delayed extra, the calculated `s_averageBitTimeLength` and `s_currentBaudRate` deviate from the real bus baud rate
- Therefore, the customer system must guarantee that the GPIO sampling path has a **bounded, repeatable, and verifiable interrupt response time** in the short window from **Break -> Sync -> PID**

Example of a clock-domain error:

- `pTMR` measures `19200 bps` using clock source A
- `UART` computes `OSR/SBR` using clock source B
- If A and B have a frequency offset, the actual UART baud used for sampling/transmission will not match the measured target

Example of an interrupt-latency error:

- The 1st Sync falling-edge reference point enters the GPIO ISR with very short delay
- The 5th Sync falling edge happens while global interrupts are masked or while a higher-priority ISR occupies the CPU for too long
- Software reads `pTMR` late
- The averaged bit time becomes larger than the real value, which typically appears as an underestimated baud rate or reduced PID reception stability

### 3. Break Detection Must Hand Over to GPIO Before Sync Start Falling

This demo no longer requires the first GPIO edge to be the Break rising edge. However, it still requires the following:

- After the LIN driver has recognized a valid Break condition, default `11 bit`
- Software must complete the handover from UART RX to GPIO
- And enable GPIO falling-edge interrupts **before Sync start falling arrives**

Why this matters:

- The first valid GPIO falling edge must be **Sync start falling**
- Only then do the `5` falling-edge samples and the `4` two-bit intervals match the assumptions of the algorithm
- If GPIO interrupt enable is too late, the first recorded falling edge may already be an internal edge such as `bit1`, `bit3`, `bit5`, or `bit7`, which corrupts the sample alignment and causes baud calculation failure

Timing sketch:

```text
LIN bus:     |_____________________|‾|_|‾|_|‾|_|‾|_|‾|_|‾|....
                 Break    ^      ^   ^<--- Sync = 0x55 --->
                          |      |   |
State                     |      |   Sync start falling
                          |      GPIO already switched to falling-edge interrupt
                          Break detected successfully
Requirement: the first valid GPIO falling edge must be Sync start falling
```

Window view:

```text
+----------------------+     +----------------------+     +----------------------+
| 1. Break condition   | --> | 2. Software enters   | --> | 3. RX switches to    |
|    detected          |     |    auto-baud phase   |     |    GPIO              |
+----------------------+     +----------------------+     +----------+-----------+
                                                                     |
                                                                     v
+----------------------+     +----------------------+     +----------------------+
| 6. Start recording   | <-- | 5. Sync start        | <-- | 4. Falling-edge      |
|    the first valid   |     |    falling arrives   |     |    interrupt enabled |
|    edge              |     |                      |     |                      |
+----------------------+     +----------------------+     +----------------------+
```

### 4. Sync Falling-Edge Sampling and Baud Estimation

The LIN Sync field is always `0x55`. Its regular edge pattern makes it suitable for estimating the bit width from the falling-edge sequence.

In this demo:

- `5` falling edges are used
- The 1st falling edge is `Sync start falling` and is used only as the reference timestamp
- The 2nd to 5th falling edges form `4` valid two-bit interval samples
- The `4` two-bit intervals are averaged first, then divided by `2` to get `s_averageBitTimeLength`
- The current bus baud rate is estimated with:

```text
BaudRate = pTMR_Clock / AverageBitTime
```

Edge mapping:

| Falling Count | Position             | Purpose |
| ------------- | -------------------- | ------- |
| 1st           | `Sync start falling` | Build the reference timestamp |
| 2nd           | `bit1 falling`       | Record the 1st two-bit interval |
| 3rd           | `bit3 falling`       | Record the 2nd two-bit interval |
| 4th           | `bit5 falling`       | Record the 3rd two-bit interval |
| 5th           | `bit7 falling`       | Record the 4th two-bit interval and immediately complete baud calculation and UART pre-configuration |
| Next rising   | `Sync stop rising`   | Switch back to UART and enter PID reception |

### 5. The Window from the 5th Falling Edge to Stop Rising

This is one of the most critical real-time constraints in the demo.

After the 5th falling edge is captured, software performs the following in the ISR for that falling edge:

1. **Immediately switch GPIO interrupt mode from falling-edge to rising-edge** so the next edge is not missed because of later calculations.
2. Average the `4` two-bit samples.
3. Compute the average bit time and the target baud rate.
4. Search for the best `OSR/SBR`.
5. Update UART `BAUD/CTRL1`. At this point the UART baud is configured, but the RX pin mux is not switched back yet.

When the following **Sync stop rising** arrives and triggers the last GPIO interrupt, software must:

1. **Disable GPIO edge capture**.
2. **Switch the RX pin mux back to UART immediately**.
3. **Publish `LIN_SYNC_OK`** and prepare to receive the following PID field.

The GPIO interrupt mode switch must complete within the **1-bit window** from `bit7 falling` to `Sync stop rising`. Only if that handover is completed in time can the system safely receive the stop-rising interrupt. The subsequent UART pre-configuration must also complete early enough so the mux handover in the stop-rising ISR still finishes before the **PID start bit** arrives.

Detailed timing:

```text
LIN bus:
Sync                                           PID
..‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|_________________________|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|......,
                        ^                         ^                            ^
                        |                         |                            |
                        |                         Sync stop rising             sync stop end
                        5th falling edge (bit7)

Software window:
                        [switch GPIO to rising-edge]  [switch PIN MUX to UART]
                        <-- finish within 1 bit --><- finish before PID starts ->
                        [average bit time]
                        [search OSR / SBR]
                        [reconfigure UART]
                        <------------ must finish within 2 bit window -------->
```

Flow view:

```text
+----------------------+     +----------------------+     +----------------------+     +----------------------+
| 1. 5th Sync falling  | --> | 2. Switch GPIO to    | --> | 3. Compute average    | --> | 4. Derive target      |
|    edge completes    |     |    rising-edge       |     |    bit time           |     |    baud rate          |
|    sampling          |     |    immediately       |     |                       |     |                       |
+----------------------+     +----------------------+     +----------------------+     +----------+-----------+
                                                                                                  |
                                                                                                  v
                             +----------------------+     +----------------------+     +----------------------+
                             | 7. Finish before     | <-- | 6. Write UART        | <-- | 5. Search OSR/SBR    |
                             |    Sync stop rising  |     |    BAUD/CTRL1        |     |                      |
                             +----------------------+     +----------------------+     +----------------------+
```

### 6. UART Reconfiguration Strategy and the Meaning of 0.5%

After the target baud rate is calculated, the demo does not linearly scan every possible OSR. Instead, it first tries a prioritized set of sampling ratios:

```c
{16, 8, 32, 12, 24, 20, 4}
```

Strategy characteristics:

- Prefer OSR values that are more common or provide better sampling quality
- Compute `SBR` from `UART source clock / (OSR * Baud)` for each OSR candidate
- Compare the reconstructed baud rate with the target baud rate
- Exit the search early if the error is already below `0.5%`
- Disable global interrupts only while actually writing UART timing registers, so the critical section remains short

The meaning of `0.5%` must be understood correctly:

- `+/-10%` is the **target auto-baud operating range**
- `0.5%` is the **divider search accuracy target after reconfiguration**
- In other words, when the master baud falls within the `+/-10%` target range, software tries to find a UART divider pair whose residual error is no more than `0.5%`, so the chance of stable reception is higher

When `OSR < 8`, the code automatically enables UART Both Edge Sampling to improve sampling robustness at low OSR values.

### 7. Timeout and Error Recovery

The demo uses `lpTMR0` as the common time base for the LIN stack and manages both Header and Response timeouts.

The following conditions cause the current frame to be abandoned and the slave to wait for the next header:

- Sync error
- PID error
- Frame error
- Readback error
- Checksum error
- RX overrun
- Header timeout
- Response timeout

The recovery action is centralized in `LinSync_RearmForNextHeader()`, including:

- Clearing auto-baud state variables
- Disabling GPIO edge capture
- Returning the LIN node to Idle if required

---

## How to Use the Demo

### 1. Default Communication Behavior

The demo runs as a LIN slave. Different PIDs trigger different actions:

| PID    | Action       | Description |
| ------ | ------------ | ----------- |
| `0x3C` | Receive data | The slave calls `LIN_DRV_ReceiveFrameData()` to receive `8` bytes into `s_linRxBuff[]` |
| `0x3D` | Send data    | The slave calls `LIN_DRV_SendFrameData()` to transmit a fixed `8`-byte response |

Default TX data:

```text
55 AA 69 96 96 69 AA 55
```

### 2. Key Configuration Items

The items below are grouped by customer impact. During porting, customers should focus on the first group. The second group usually should not be changed.

#### Configuration Items Customers Must Review

| Item | Default | Description |
| ---- | ------- | ----------- |
| `LIN_SYNC_UART_INSTANCE` / `LIN_SYNC_UART_BASE` | `0 / UART0` | LIN/UART instance bound to the demo. Must match the actual hardware connection. |
| `LIN_SYNC_UART_CLOCK_NAME` | `UART0_CLK` | UART functional clock name. This is the calculation basis for baud reconfiguration. |
| `LIN_SYNC_RX_GPIO` / `LIN_SYNC_RX_PIN` | `GPIOA / 2` | RX sampling port and pin used during the auto-baud phase. |
| `LIN_SYNC_RX_MUX` | `PCTRL_MUX_ALT6` | Pin mux value used when switching RX back from GPIO to UART. |
| `LIN_SYNC_NOMINAL_BAUD` | `19200` | Nominal baud rate. This is the reference for both baud range and timeout design. |
| `LIN_SYNC_AUTOBAUD_MODE` | `LIN_SYNC_MODE_EVERY_HEADER_RECAL` | `LIN_SYNC_MODE_EVERY_HEADER_RECAL` means auto-baud on every header. `LIN_SYNC_MODE_STARTUP_RETRY_UNTIL_SUCCESS` means retry until first success and then lock. |
| `LIN_SYNC_LPTMR_INSTANCE` / `LIN_SYNC_LPTMR_PERIOD_US` / `LIN_SYNC_LPTMR_TICKS_PER_US` | `0 / 520 / 48` | Timeout service base. Usually adjusted together with board clock configuration. |
| `LIN_SYNC_TIMEOUT_HEADER_TICKS` / `LIN_SYNC_TIMEOUT_RESPONSE_TICKS` | `5 / 15` | LIN timeout thresholds. Keep the defaults unless the overall protocol timing changes. |

#### Implementation Parameters Customers Normally Should Not Change

| Item | Default | Description |
| ---- | ------- | ----------- |
| `LIN_SYNC_BAUD_TOLERANCE_PERMILLE` | `105` | For external explanation, this is best described as `+/-10%` relative to nominal baud. |
| `LIN_SYNC_PTMR_INSTANCE` / `LIN_SYNC_PTMR_CLOCK_NAME` | `0 / pTMR0_CLK` | Sync timestamp resource and clock. Must share the same source or fixed divider chain with UART. |
| `LIN_SYNC_FALLING_EDGE_COUNT` | `5` | Total Sync falling-edge count. Strongly coupled to the current sampling algorithm. |
| `LIN_SYNC_TWOBIT_SAMPLE_COUNT` | `4` | Number of valid two-bit interval samples. Strongly coupled to the current averaging algorithm. |

### 3. Run Steps

1. Open the project in YCT and confirm that `UART0`, `GPIOA/PTA2`, `pTMR0`, and `lpTMR0` match the actual hardware resources.
2. Verify that the `pTMR` functional clock and the `UART` functional clock share the same source or the same fixed divider chain.
3. Download the program to `YTM32B1LE15-EVB-Q48`.
4. Connect an external LIN master and provide `12 V VBAT` for the on-board LIN PHY.
5. Let the master send LIN headers at different baud rates. It is recommended to cover the nominal baud and the `+/-10%` boundary range.
6. When the master sends `PID=0x3C`, send `8` data bytes to the slave.
7. When the master sends `PID=0x3D`, read back the fixed `8`-byte response from the slave.

### 4. Expected Results

- After Break, the slave should enter the GPIO sampling phase and capture a `5`-falling-edge sequence starting from `Sync start falling`
- After the 5th falling edge, the demo should complete GPIO/UART preparation before `Sync stop rising`, then switch back to UART on the stop-rising interrupt
- When the master sends `PID=0x3C`, received data should be visible in `s_linRxBuff[]`
- When the master sends `PID=0x3D`, the master should receive the fixed response data from the slave
- If the master baud is out of range, if the header is incomplete, or if the critical timing window is blocked and a timeout occurs, the demo should abandon the current frame and automatically wait for the next one

This demo does not include built-in serial print output. Recommended validation methods:

- Observe `s_currentBaudRate`, `s_averageBitTimeLength`, and `s_linRxBuff[]` in a debugger
- Use a logic analyzer or LIN analyzer to observe Break, Sync, PID, and the switching windows
- Correlate the result with master-side logs

---

## Interrupt Priority and Real-Time Constraints

### 1. Default Interrupt Priority

The auto-baud flow is sensitive to interrupt response time. The default configuration is:

| Interrupt     | Default Priority | Description |
| ------------- | ---------------- | ----------- |
| `GPIOA_IRQn`  | `0`              | Sync falling-edge sampling and stop-rising handover back to UART. Highest priority. |
| `UART0_IRQn`  | `1`              | LIN event handling |
| `lpTMR0_IRQn` | `2`              | LIN timeout service. Can be lower than UART and the sampling path. |

Design intent:

- **GPIO falling-edge sampling and the stop-rising handover path must not be delayed by lower-priority work**
- **UART pre-configuration must finish before stop rising arrives**
- **The stop-rising ISR must restore the UART path before the PID start bit arrives**
- **LPTMR is used for timeout service, but it must not preempt the critical sampling window**

One more point is easy to overlook:

- The GPIO path priority affects not only whether a timing window is missed, but also whether the measured bit time remains accurate
- Because the `pTMR` value is read in ISR context, the **difference in response latency between the first and last key falling edges** appears directly in the final measurement error
- That is why a customer system can still show occasional loss of synchronization or PID errors near baud boundaries even if no complete timeout occurs, if long interrupt-masking periods or long-running higher-priority ISRs are introduced

### 2. Three Core Real-Time Constraints

#### Constraint A: Break Detection Must Hand Over Before Sync Start Falling

```text
T_break_detect_to_gpio_enable < T_break_ok_to_sync_start_falling
```

Meaning:

- The time from Break detection to actual GPIO falling-edge interrupt enable
- Must be shorter than the remaining time until `Sync start falling` arrives
- So that the first valid GPIO falling edge is indeed `Sync start falling`

#### Constraint B: The GPIO Interrupt Mode Must Be Switched Within the 1-Bit Window After the 5th Falling Edge

```text
T_gpio_switch_rise_interrupt < T_bit_time
```

Meaning:

- Starting from completion of the 5th falling-edge sample
- Before `Sync stop rising` arrives
- Software must complete the GPIO interrupt mode switch to rising-edge

#### Constraint C: UART Path Restoration Must Complete Before PID Starts

```text
T_stop_rising_isr + T_mux_switch_back < T_stop_to_pid
```

Meaning:

- Inside the single GPIO ISR triggered by `Sync stop rising`
- Software must disable GPIO capture, restore the UART RX mux, publish `LIN_SYNC_OK`, and advance the state to `RECV_PID`
- So the UART does not miss the PID start bit

### 3. Real-Time Window Diagram

```text
+----------------------+     +----------------------+     +----------------------+     +----------------------+
| 1. Break detected    | --> | 2. GPIO falling-edge | --> | 3. Sync start        | --> | 4. 5th falling edge   |
|                      |     |    IRQ enabled       |     |    falling arrives   |     |    sampled            |
+----------------------+     +----------------------+     +----------------------+     +----------+-----------+
                                                                                                  |
                                                                                                  v
                             +----------------------+     +----------------------+     +----------------------+
                             | 7. Sync stop rising  | <-- | 6. Compute + search  | <-- | 5. Switch to         |
                             |    arrives           |     |    + UART preconfig  |     |    rising-edge       |
                             +----------+-----------+     +----------------------+     +----------------------+
                                        |
                                        v
                             +----------------------+     +----------------------+
                             | 8. MUX back to UART  | --> | 9. PID start bit     |
                             |    + publish SYNC_OK |     |    arrives           |
                             +----------------------+     +----------------------+
```

Key windows:

- `① -> ②`: must complete before `Sync start falling`
- `④ -> ⑤`: must fit within the `1 bit` pre-handover window
- `⑦ -> ⑧`: must fit between `Sync stop rising` and PID arrival

If these windows fail, the direct system-level symptoms are usually:

- Excessive response-latency difference between the first and last key sampling points: average bit time shifts, causing frame-to-frame baud estimate variation and reduced boundary-rate compatibility
- Constraint A failure: the current header cannot enter synchronization correctly, leading to occasional sync failure or complete frame loss
- Constraint B failure: falling edges were captured, but the stop-rising handover is not ready in time, leading to PID loss or header parse failure
- Constraint C failure: UART is restored too late, causing PID first-bit loss, subsequent frame errors, or occasional timeouts

---

## Porting and Debug Recommendations

### 1. Items That Must Be Checked During Porting

- The `UART0_RX` pin mux and the GPIO port/pin definition must refer to the same physical pin
- `pTMR` and `UART` functional clocks must share the same source or the same fixed divider chain
- `lpTMR` configuration must match the timeout service period expected by the LIN driver
- Interrupt numbers, callback installation, and pin mux settings in YCT must match the macro definitions used in `main.c`

### 2. Usage Limits and Notes

- The demo assumes that the **first valid GPIO falling edge is Sync start falling**
- The demo assumes that the GPIO interrupt mode switch is completed in the **1-bit window between the 5th falling edge and Sync stop rising**
- The demo assumes that the RX path is switched back to UART in the **single GPIO ISR triggered by Sync stop rising**
- The demo assumes that there is no uncontrolled interrupt-response latency difference near the **1st and 5th Sync falling edges**, especially no long global interrupt masking, long critical sections, or long-running higher-priority ISRs
- If the customer system cannot guarantee those real-time constraints, priority should be given to reducing software load in this window or redesigning the edge timestamp path, for example by using DMA or hardware capture assistance
- The documented target auto-baud capability is **+/-10% relative to nominal baud**
- `0.5%` is the **divider search accuracy target**, used to improve stable reception within the `+/-10%` range
- If the target board or peripheral instance is changed, the UART, GPIO, pTMR, and lpTMR resource mapping must all be updated together

### 3. Debug Recommendations

- Use `LIN_SYNC_TESTPOINT_ENABLE` to add GPIO toggling and observe key timing points on an oscilloscope
- At minimum, observe `LIN_RX`, the test-point GPIO, and the instant when RX mux is switched back to UART
- Repeat the `Break -> Sync -> PID` observation under the heaviest expected customer-system load and confirm that the window is not stretched by RTOS critical sections, periodic high-priority interrupts, or flash operations
- If synchronization fails, first check whether the master header is valid, VBAT is stable, and the LIN PHY has been enabled
- If bit errors or occasional frame loss occur, first check interrupt priorities, system load, clock alignment, and whether either of the critical timing windows is being compressed

---
