I'm running into some unexpected errors when trying to use the MBDT LIN blocks with the S32K142.
The LIN master example compile without issue but when I try to use the LIN blocks into my own model I'm getting errors that both LIN_XCVR_ENABLE_GPIO_PORT and LIN_XCVR_ENABLE_MASK are undefined:
error: 'LIN_XCVR_ENABLE_GPIO_PORT' undeclared (first use in this function) PINS_DRV_SetPinsDirection(LIN_XCVR_ENABLE_GPIO_PORT, LIN_XCVR_ENABLE_MASK);
When I look at the C code that gets generated from the lin_master_s32k14x.slx example I see these #defines:
34 #define LIN_XCVR_ENABLE_PIN (9UL)
35 #define LIN_XCVR_ENABLE_MASK (0x1u << LIN_XCVR_ENABLE_PIN)
36 #define LIN_XCVR_ENABLE_GPIO_PORT (PTE)
These same #define statements are not present in the C code that gets generated from my model that's using the same LIN blocks.
A couple questions:
Thanks,
Andy
I was able to work around the compiler error by adding the missing #defines into the Custom Code section of the Simulink model configuration.
This is a bit of a hack though, and I'd still like to understand the answers to the two questions in the post above.
I'm now experiencing a different issue.
When acting as a LIN master, I can successfully send messages to and receive data from slaves if the slaves are all connected and working properly. However, if I send a message header to get data from a slave that isn't present and the slave doesn't respond, the LIN_ReceiveFrameData seems to be blocking and doesn't allow transmission of any additional headers via the LIN_Master_Send_Header block if it never receives any frame data from the slave. Is there a way to address this? I don't see any timeout values in any of the LIN blocks, nor do I see a timeout in the LIN events that can be generated by the LIN_ISR block.
Any advice would be appreciated.
I think I've figured out what's causing the "blocking" behavior if a Slave never sends the data that the Master S32K1xxx is expecting.
The LIN receive Simulink block calls the LIN_LPUART_DRV_RecvFrmData() function, which is technically non-blocking (LIN_LPUART_DRV_RecvFrmDataBlocking() is the blocking version), but it does set the linCurrentState->isBusBusy flag to true, which effectively prevents the other LIN blocks from using the bus.
The LIN_LPUART_DRV_MasterSendHeader() function called by the LIN_Master_Send_Header block checks to see if the linCurrentState->isBusBusy flag is true and if it is, returns without sending the header.
If the Master never completes receiving data from the Slave (slave goes offline, etc.), the linCurrentState->isBusBusy flag never gets reset and the Master can't send any more headers.
Allowing a bad slave to prevent further action by the Master is probably not a great idea.
I modified the lin_lpuart_driver.c file as shown below as a hacky workaround, but modifying the NXP driver source code files is not an ideal long-term solution.
A better solution may be to add some checks of the linUserConfig->nodeFunction (MASTER/SLAVE) flag in various places where it makes sense for a Master to do things regardless of slave behavior, but I haven't fully thought through where all of those checks would need to be.
I'd appreciate any insight into other possible solutions or more "correct" workarounds for this issue.