S32K SDK RTM 3.0.0 LIN / VLPS: safe to stop?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

S32K SDK RTM 3.0.0 LIN / VLPS: safe to stop?

1,830 Views
nathan_hellwig
Contributor I

I have LIN working with the S32K EVB using the SDK per the example code.

However, in my implementation, I must sleep my MCU whenever possible, and I need to use VLPS to reduce power consumption as much as possible.

As such, I use the LPTMR to wake the MCU periodically from VLPS (if no external interrupts are triggered, i.e. LIN wakeup or other IRQs), and altered the LIN autobaud code to use the LPIT instead (the LPIT does not run in VLPS).

My problem is that I don't know when it is safe to sleep, i.e. when the LIN stack is not processing frame data.

I attempted to use this logic to see if LIN was "busy":

linState != LIN_NODE_STATE_UNINIT &&
linState != LIN_NODE_STATE_SLEEP_MODE &&
linState != LIN_NODE_STATE_IDLE

However, linState is IDLE in the middle of frame processing.  

As such, I tell the MCU to enter VLPS in the middle of a transmission, LPIT stops, and the MCU fails to properly sync and communicate with the LIN bus.

With the SDK, what indicators do I have that there is no active LIN communication in progress and it is safe to sleep?

Note that I cannot use the LPTMR for both LIN and auto-wake because I'm sleeping up to 2 seconds between wakeups, and the LIN stack expects a "timeout" of 500us with the timer.

0 Kudos
7 Replies

1,537 Views
dianabatrlova
NXP TechSupport
NXP TechSupport

Hello Nathan,

Please accept my apologies for the delay.

I have contacted LinStack expert regarding your case.  See the answer below. Please, respond to the following questions.

I attempted to use this logic to see if LIN was "busy":

 

linState != LIN_NODE_STATE_UNINIT &&
linState != LIN_NODE_STATE_SLEEP_MODE &&
linState != LIN_NODE_STATE_IDLE

 

However, linState is IDLE in the middle of frame processing.  

With the SDK, what indicators do I have that there is no active LIN communication in progress and it is safe to sleep?

I have checked this and I cannot reproduce it, how to have the IDLE state in the middle of frame processing?

 

As such, I tell the MCU to enter VLPS in the middle of a transmission, LPIT stops, and the MCU fails to properly sync and communicate with the LIN bus.

From my point of view we should use the LPTMR for LinStack in this case. Because some feature(which regarding timing. Eg: detect wake up signal, … ) of LinStack depend on timer operation.

 

 Note that I cannot use the LPTMR for both LIN and auto-wake because I'm sleeping up to 2 seconds between wakeups, and the LIN stack expects a "timeout" of 500us with the timer.

Could you please explain more about this. Why we cannot use the LPTMR for both LIN and auto-wake?

Thank you.

Best regards,

Diana

0 Kudos

1,537 Views
nathan_hellwig
Contributor I

First, I believe I have the problem solved thanks to feedback from the FAE (I was able to contact them after the winter break).  

The trick appears to be to monitor the LBKDE bit of the LPUART->STAT register.  The LIN component sets this bit high between transmissions.  I also need to monitor the IDLE bit of the same register.  If LBKDE is active, but IDLE is low (i.e. there is activity on the line), I interpret this as the "autobaud" phase.  The LIN component is timing the signal, but not yet in a LIN frame.  Thus, linState is still IDLE, the LBKDE bit indicates the LIN component is looking for a break signal, and the IDLE bit low means something is happening on the bus.

With this, I am able to determine when it is "safe" to sleep and when I am in the middle of autobaud detection (verified on oscilloscope).  I do, however, have issues with actually entering VLPS and waking from it (LIN communication ceases), most likely because I am not running the LPIT while sleeping.  However, now that I know when it is safe, I may be able to use the LPTMR and swap configurations between LIN and VLPS (see below).

Now, to answer your questions:

However, linState is IDLE in the middle of frame processing.  

With the SDK, what indicators do I have that there is no active LIN communication in progress and it is safe to sleep?

I have checked this and I cannot reproduce it, how to have the IDLE state in the middle of frame processing?

Apologies, I mispoke.  The linState is IDLE during Autobaud detection, NOT frame processing.

As such, I tell the MCU to enter VLPS in the middle of a transmission, LPIT stops, and the MCU fails to properly sync and communicate with the LIN bus.

From my point of view we should use the LPTMR for LinStack in this case. Because some feature(which regarding timing. Eg: detect wake up signal, … ) of LinStack depend on timer operation.

 

 Note that I cannot use the LPTMR for both LIN and auto-wake because I'm sleeping up to 2 seconds between wakeups, and the LIN stack expects a "timeout" of 500us with the timer.

Could you please explain more about this. Why we cannot use the LPTMR for both LIN and auto-wake?

Ultimately, I need to use the LPTMR for periodic wakeup from VLPS.  Per the S32K DS, the S32K116 consumes more than twice the power with the LPIT (VLPS + LPIT = 114uA @ 25C) than the LPTMR (VLPS + LPTMR = 40uA @ 25C).  I need a ~2 second wakeup, so the multiplier of the LPTMR is very large during this time, unable to measure microseconds.

I had experimented with changing the configuration of LPTMR when LIN was active vs. when the MCU was in VLPS, but since I didn't know when it was safe to enter VLPS, I didn't know when it was safe to change the LPTMR configuration.  Now that I believe I can safely determine when LIN is autobauding and when it is not, I can re-examine this scenario.

Thanks

0 Kudos

1,537 Views
nathan_hellwig
Contributor I

Follow up:  There is one issue with using the LBKDE + IDLE bit, which is that IDLE is not set until activity has been seen on the Rx line first.  As such, after bootup, the IDLE bit is always clear, seeming to indicate that some activity is active.  I attempted to also tie-in the RAF (receiver active flag), but this didn't seem to be set during the break bit.

I can add a simple check to ignore "IDLE" after reset until the first activity is seen, but it would be really nice if the SDK simply provided an "Is Active" indicator.

0 Kudos

1,537 Views
dianabatrlova
NXP TechSupport
NXP TechSupport

Hello Nathan,

According to our expert, we should use the Lin node state (l_ifc_read_status) to know that(“safe” to sleep).

I would like to ask you why don’t you use the Lin node state instead of the Lin node state the LBKDE + IDLE bit?

Best regards,

Diana

0 Kudos

1,537 Views
nathan_hellwig
Contributor I

Diana,

l_ifc_read_status returns "the status of the previous communication".  As far as I can tell, the break/sync portion of the message is not considered "communication" by the LIN SDK that I can see anywhere. Therefore, I risk attempting to sleep immediately before communication begins, i.e. during the sync bits, which would then fail the autobaud functionality and overall communication.

Note that I am not referring to the LIN Sleep command sent by the LIN master.  I am referring to sleeping my MCU between messages to conserve power.

Even if I am receiving a periodic LIN message, I still want to sleep the MCU between frames whenever possible. 

I looked into the LIN timeout functionality, but this measures timeout periods in seconds, which is too long for me to wait (and doesn't work at all if I'm getting periodic LIN frames on the bus).

Basically, if I have any idle time (measured in milliseconds), I need to reduce power consumption as much as possible.  My application is running in a battery-powered, always-on situation.  

Thanks.

0 Kudos

1,537 Views
dianabatrlova
NXP TechSupport
NXP TechSupport

Hello Nathan,

Please, refer to below answer:

Apologies, I was a little confused. I mean we should use lin_lld_get_state to get linState, not l_ifc_read_status. And then, use the condition as you said before:

 

“I attempted to use this logic to see if LIN was "busy":

 

linState != LIN_NODE_STATE_UNINIT &&
linState != LIN_NODE_STATE_SLEEP_MODE &&
linState != LIN_NODE_STATE_IDLE”

 

About “The linState is IDLE during Autobaud detection, NOT frame processing.”. , This case only occurs when Lin node state is sleep mode and a frame is transmitted, not have any wake-up signal.

Please note that when the node state is sleep mode, the node will consider a break field as a wake-up signal. So when the node receives a frame in a sleep mode, it will wake up and ignore this frame then change state to ILDE. Please see the below picture for more information:

 pastedImage_7.png

I hope it helps.

Best regards,

Diana

0 Kudos

1,537 Views
nathan_hellwig
Contributor I

Diana,

I think I may have been forcing my LIN receiver to the sleep mode, which may have been my initial problem (which I then couldn't reproduce because I stopped forcing LIN sleep on my end).

I believe I have a working solution that monitors LIN Node and LPUART states (and the physical Rx line) to properly prevent my software from accidentally entering a sleep state during all LIN activity.

This is what I ended up with, and have not observed any "false sleep cycles".  gb_firstBoot is set to false by the first interrupt on the Rx pin and never set back to true (as explained in the comment, this is because the IDLE bit is not set until after the first activity on the Rx line, thus it is always false after boot).

bool LIN_Autobaud_IsBusy(void) {

 lin_node_state_t linState;
 bool retVal = false;
 uint32_t lbkde;
 uint32_t idle;
 uint32_t rxPin;
 linState = LIN_DRV_GetCurrentNodeState(INST_LIN1);
 /* this bit is set by the LIN driver during auto-baud break detection (i.e. the first transition of the LIN/UART Rx signal line) */
 lbkde = LPUART_STAT_LBKDE_MASK;
 lbkde &= LPUART1->STAT;

idle = LPUART_STAT_IDLE_MASK;
 idle &= LPUART1->STAT;

rxPin = PINS_DRV_ReadPins(PTC);
 rxPin &= (1 << 6);

switch (linState) {
 case LIN_NODE_STATE_IDLE:
 if (rxPin == 0) {
 retVal = true;
 }
 else if (lbkde == LPUART_STAT_LBKDE_MASK && idle == 0)
 {
 /* if we have not seen any activity on the Rx line since boot, IDLE will not be set to indicate an actual idle condition */
 retVal = !gb_firstBoot;
 }
 else {
 retVal = false;
 }
 break;
 case LIN_NODE_STATE_UNINIT:
 case LIN_NODE_STATE_SLEEP_MODE:
 retVal = false;
 break;
 default:
 retVal = true;
 break;
 }

 return retVal;

}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos