LIN Tx from Master (S32K) fails with status busy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am using the S32K3X4EVB-T172 eval board. I have configured both LIN1 and LIN2 as master. Currently, I am using LIN1 and sending a master diagnostic request to a PLIN-View Pro configured as a slave device (with address set as 0x1).
However, I have observed the following:
- LIN bus goes is awake for a brief amount of time and goes to sleep.
- When the master sends a master diagnostic request to the slave to read its ID, the transfer status times out and returns a tx status of BUSY.
I am not really sure that I have configured the LIN peripheral properly. I have repurposed the FreeRTOS toggle LED example and configured a UART to serve as console and the UART5 and UART9 to LIN1 and LIN0 periperals.
I am attaching both the code (zipped) and the ldf file for a slave.
Please let me know what I might have missed.


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
have you tried to measure LIN bus signal by scope or analyzer to know it is really send?
There is TimeoutValue decrementing in waiting for TX, but it does not seem you have set it finally from default zero.
A S32DS examples use below value
#define T_LIN_TIME_OUT (400000U)
/* Wait for the transmission done */
TimeoutValue = 4*T_LIN_TIME_OUT;
BR, Petr
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Peter,
I have tried to scope at different points along the communication between Master and Slave. My slave is a simple RGB Led slave from Skpang Electronics, https://copperhilltech.com/lin-bus-slave-rgb-led-breakout-board/
At this time, I see the following:
- RXD, TXD lines to the LIN PHY (TJA1022T) on S32K344 Eval kit - Only see activity on the line, if I configure the LPUART9/LPUART5 as UARTs instead of LIN
- The Jumpers J20 and J24 have been shorted to make sure both act as Masters to external slaves.
- VBAT shows up as +12v on both the Master and the slave side.
- Bit bang LPUART1 and use PTC7 from J4 header and directly wire it to the LIN on the slave. I see UART activity on the slave chip.
- At init time for both LIN1 and LIN2, I make sure that the bus awake and idle:
// Go to sleep first, then send wakeup
Lpuart_Lin_Ip_GoToSleepMode(LIN_INSTANCE_1);
delay_ms(10); // allow idle to complete
printf("After sleep: LIN1 Node state: %d\n", Lpuart_Lin_Ip_Sa_pHwConfigPB_1.StateStruct->CurrentNodeState);
if (Lpuart_Lin_Ip_SendWakeupSignal(LIN_INSTANCE_1) != LPUART_LIN_IP_STATUS_SUCCESS) {
printf("LIN1 wakeup failed\n");
}
delay_ms(10); // allow wakeup pulse to propagate
printf("LIN1 After wakeup: Node state: %d\n", Lpuart_Lin_Ip_Sa_pHwConfigPB_1.StateStruct->CurrentNodeState);
//Important: Move to IDLE so you can transmit
Lpuart_Lin_Ip_GoToIdleState(LIN_INSTANCE_1);
printf("LIN1 After idle: Node state: %d\n", Lpuart_Lin_Ip_Sa_pHwConfigPB_1.StateStruct->CurrentNodeState);
// Let's poll for idle to complete.
if (lin_wait_for_idle(LIN_INSTANCE_1, LIN_IDLE_TIMEOUT_MS) != 0) {
printf("LIN1 Timeout waiting for node to reach IDLE state\n");
} else {
printf("LIN1 Node is now IDLE\n");
}
- I do the same before calling SendFrame.
status = Lpuart_Lin_Ip_GetStatus(LIN_INSTANCE_1, &dummy_rx_ptr);
if (status == LPUART_LIN_IP_STATUS_SLEEP) {
// wake up the node
Lpuart_Lin_Ip_SendWakeupSignal(LIN_INSTANCE_1);
vTaskDelay(pdMS_TO_TICKS(10)); // Allow slave to wake up
Lpuart_Lin_Ip_GoToIdleState(LIN_INSTANCE_1); // forces node into idle mode
vTaskDelay(pdMS_TO_TICKS(10));
}
while (Lpuart_Lin_Ip_Sa_pHwConfigPB_0.StateStruct->CurrentNodeState != LPUART_LIN_IP_NODE_STATE_IDLE);
printf("before calling SendFrame: State: %d, Busy: %d\n",
Lpuart_Lin_Ip_Sa_pHwConfigPB_0.StateStruct->CurrentNodeState,
Lpuart_Lin_Ip_Sa_pHwConfigPB_0.StateStruct->IsBusBusy);
Lpuart_Lin_Ip_Sa_pHwConfigPB_0.StateStruct->IsBusBusy = false;
printf("[LIN_TX] Forcing IsBusBusy = 0 before SendFrame\n");
printf("before calling SendFrame but after forcing isBusBusy: State: %d, Busy: %d\n",
Lpuart_Lin_Ip_Sa_pHwConfigPB_0.StateStruct->CurrentNodeState,
Lpuart_Lin_Ip_Sa_pHwConfigPB_0.StateStruct->IsBusBusy);
uint8_t pid = calculate_pid(msg.pid);
uint8_t check = Lin_Ip_ProcessParity(pid, LIN_IP_CHECK_PARITY);
printf("[DEBUG] PID: 0x%02X, Check result: 0x%02X\n", pid, check);
printf("[DEBUG] CheckSleepMode: %d, CheckDl: %d, CheckPid: %d\n",
(Lpuart_Lin_Ip_Sa_pHwConfigPB_0.StateStruct->CurrentNodeState == LPUART_LIN_IP_NODE_STATE_SLEEP_MODE),
(msg.len == 0 || msg.len > 8),
(Lin_Ip_ProcessParity(pid, LIN_IP_CHECK_PARITY) == 0xFF));
(void)Lpuart_Lin_Ip_SendFrame(LIN_INSTANCE_1, &pdu);
// Wait until the frame transmission completes or times out
timeout = LIN_TIMEOUT_MS;
do {
status = Lpuart_Lin_Ip_GetStatus(LIN_INSTANCE_1, (const uint8 **)&dummy_rx_ptr);
vTaskDelay(pdMS_TO_TICKS(1));
} while ((LPUART_LIN_IP_STATUS_TX_OK != status) && (timeout-- > 1));
if (timeout == 0 || status != LPUART_LIN_IP_STATUS_TX_OK) {
printf("[LIN_TX] Frame send timeout or error, status = %d\n", status);
}
}
- Stepped through the code, to check the status within SendFrame function to make sure it was going through and putting bits on the wire. Found that the IsBusy flag was set to true even before the first byte has gone out ... So manually forced it:
Lpuart_Lin_Ip_Sa_pHwConfigPB_0.StateStruct->IsBusBusy = false;
Since I have code in our proprietary repo, I will update the FreeRTOS ToggleLed example and send it to you, if you need it. Please let me know.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Some scope captures ...
These ones are with LPUART9/5/1 acting as UART.
In particular, Channel 1 & 13 are with LPUART1 out through PTC7 and I am bitbanging the break and sync character.
Channel 10/11 - LIN1_SLP and LIN2_SLP are always high, which is good.
Next I will attach captures where one of the UARTs 5/9 are configured as LIN and we will try to transmit some command.


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
check if driver's interrupt are properly assigned. You can follow demo examples. Consider interrupts priorities. Also try to first test without printing.
BR, Petr
