Wake-up using LIN message on MC9S12ZVL

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

Wake-up using LIN message on MC9S12ZVL

Jump to solution
3,069 Views
fabrizioimpinna
Contributor II

Dears,

I am working with MC9S12ZVL.

I have two boards with the same micro-controller. The boards communicate with eachothers using LIN peripheral.

I need to use one board as master board and the other as slave. The slave board is in STOP mode and I need to wake-up using a LIN message from the master board. The LIN communication works well when the boards are not in STOP, but if the slave board is in STOP mode it is not possible to wake it up.

 

I know from the datasheet that is possible to wake-up the micro using a LIN message, but I cannot do it!

Is a particular setting needed?

 

The register settings that I am using are the following:

void InitLIN(void){

  LP0SLRM_LPDTDIS = 0;      // TxD-dominant timeout feature is enabled

  LP0SLRM_LPSLR = 0;           // Normal Slew Rate (optimized for 20 kbit/s)

  LP0CR_LPPUE = 0;            // The pullup resistor is high ohmic (330kOhm)

  MODRR0_S0L0RR = 0;      // Default setting: SCI0 connects to LINPHY0, interface internal only

  LP0CR_RXONLY = 0;      // The LIN Physical Layer is not in receive only mode

  LP0CR_LPWUE = 1;      // In standby mode the wake-up feature is enabled

  LP0CR_LPE = 1;      // The LIN Physical Layer is not in shutdown mode

}

 

void InitSCI(void){

  // Baud Rate

  SCI0BDH = 0x01;//0x02; //9.6kb/s // Baud Rate: SCI baud rate = SCI bus clock / (SCIBR[15:0])

  SCI0BDL = 0x39;//0x8B; //9.6kb/s // Bus clock: 6.25 MHz - Baud rate 9.600 kb/s

 

// Enable Loop for LIN configuration

  SCI0CR1_LOOPS = 0; // 1 Loop operation enabled

  SCI0CR1_SCISWAI = 0; // SCI enabled in wait mode

 

  // Configuration: word length, parity, and other configuration bits

  SCI0CR1_RSRC = 1;//0; // Receiver input connected externally to transmitter

  SCI0CR1_M = 0; // One start bit, eight data bits, one stop bit

  SCI0CR1_WAKE = 0; // [0] Idle line wakeup [1] Address mark wakeup

  SCI0CR1_ILT = 1; // [0] Idle character bit count begins after start bit [1] Idle character bit count begins after stop bit

  SCI0CR1_PE = 0; // Parity function disabled

  SCI0CR1_PT = 0; // Odd parity

 

  // Enable the transmitter, interrupts, receive and wake up

  SCI0CR2_SBK = 0;           // 1 Transmit break characters          

  SCI0CR2_RWU     = 1;            // RWU enables the wakeup function and inhibits further receiver interrupt requests. Normally, hardware wakes the receiver by automatically clearing RWU.  

  SCI0CR2_RE      = 1;            // 1 Receiver enabled  

  SCI0CR2_TE      = 0;            // 1 Transmitter enabled

  SCI0CR2_ILIE    = 0;           // IDLE interrupt requests disabled

  SCI0CR2_RIE     = 1;     // RDRF and OR interrupt requests enabled

  SCI0CR2_TCIE    = 0;           // TC interrupt requests enabled

  SCI0CR2_TIE = 0; // TDRE interrupt requests enabled

 

  SCI0SR2_AMAP = 1; // The registers labelled SCIBDH (0x0000),SCIBDL (0x0001), SCICR1 (0x0002) are accessible

 

  SCI0ACR2_BKDFE = 1; // Break detect circuit enabled

  SCI0ACR1_BKDIE = 1; // Break Detect Interrupt Enable

  //SCI0ACR1_RXEDGIE = 1; // RXEDGIE enables the receive input active edge interrupt flag, RXEDGIF, to generate interrupt requests

 

  temp = SCI0SR1;

 

  SCI0CR2_TE = 0; // Enable transmission

  //SCI0CR2_RE = 0; // Enable reception

}

 

Thanks a lot!

 

Fabrizio

Labels (1)
0 Kudos
Reply
1 Solution
1,976 Views
MJW
NXP Employee
NXP Employee

Hello,

the SCI can only wake-up the MCU from STOP using the Receive Input Active Edge Interrupt feature.

So, to enter STOP mode, do something like this (for example):

  1. disable interrupts
  2. [do some additional house-keeping]
  3. set the active edge interrupt enable (RXEDGIE=1)
  4. enable interrupts (asm{CLI}) and execute the STOP instruction (asm{STOP}) << Doing this back-to-back is important to avoid races
  5. on wake-up, disable the active edge interrupt again (RXEDGIE=0)

Of course, this only works if you clear the active edge interrupt flag whenever the SCI received something: even if the active edge interrupt enable bit is usually not enabled in RUN mode, the flag is still set on active edges (i.e. when receiving regular traffic in RUN mode).

Hope that helps.

MJW

View solution in original post

3 Replies
1,977 Views
MJW
NXP Employee
NXP Employee

Hello,

the SCI can only wake-up the MCU from STOP using the Receive Input Active Edge Interrupt feature.

So, to enter STOP mode, do something like this (for example):

  1. disable interrupts
  2. [do some additional house-keeping]
  3. set the active edge interrupt enable (RXEDGIE=1)
  4. enable interrupts (asm{CLI}) and execute the STOP instruction (asm{STOP}) << Doing this back-to-back is important to avoid races
  5. on wake-up, disable the active edge interrupt again (RXEDGIE=0)

Of course, this only works if you clear the active edge interrupt flag whenever the SCI received something: even if the active edge interrupt enable bit is usually not enabled in RUN mode, the flag is still set on active edges (i.e. when receiving regular traffic in RUN mode).

Hope that helps.

MJW

1,976 Views
fabrizioimpinna
Contributor II

Hello,

sorry for the late answer.

I implemented an improved code taking into account your suggestions and the wake-up feature from SCI worked properly.

Thanks a lot.

Fabrizio

0 Kudos
Reply
1,976 Views
deepakchandra
Contributor III

dear sir ,

we also struck on this issue , in my application we are using LIN stack.

I am using s12zvl32 controller for our application and in this we are using LIN stack FSL LIN 2.x Stack Package 4.5.6   . in this project we are getting Problem in stop mode , I am unable to wake up from stop mode ,please suggest me solution for this problem .

Our customer need when LIN bus in sleep mode than we have to put my controller into stop mode(power saving) and when there is a command from LIN for sleep

Mode i.e 3c 00 00 00 00 00 00 00 00.

In my code I have written code as  for my LIN slave node .

if (SLEEP_MODE == lin_lld_get_state())

      {

        __asm(ANDCC #0x7F);

         Cpu_SetStopMode(); //stop mode

      }

      if(IDLE == lin_lld_get_state())

      {

l_ifc_wake_up(LI0);

      }

It will showing malfunction it will do my controller reset .please suggest.

0 Kudos
Reply