S12 SCI stop receiving after time - 9S12DP512

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

S12 SCI stop receiving after time - 9S12DP512

2,909 Views
nikosxan
Contributor I
I've developed an automation application based on Elektonikladen S12 Compact board with 9S12DP512. It uses SCI1 to coomunicate with a PC via 485 for data aquisition. A number of same boards (5-6 up to now) are on the 485 bus and PC is querying them to get data. It works FINE for some days and then the one S12 PLC   will stop receiving at all any data, until reset (power off reset OR reset button). Serial I/O is at 4800 and pulled....
 
Init code below :
initSCI1(BAUD4800);                          // calls routine below....
 
void initSCI1(UINT16 bauddiv) {
 SCI1BD  = bauddiv & 0x1fff;                    // baudrate divider has 13 bits
 SCI1CR1 = 0;                                           // mode = 8N1
 SCI1CR2 = BM_TE+BM_RE;               // Transmitter + Receiver enable
}
 
 
for the actucal receiveing code shown below is executed in a pooled way :
 
void GetSerial(void){
  char c;
  char bError;
  long i=0;
 
  ResetCOP;                                                       // we are using COP.........
// error checking code below was put for troubleshooting....
//Check for Frame Error
 if ((SCI1SR1 & BM_FE) > 0)
  { 
    c = SCI1DRL;     // Get Data to clear Flag..
    clearLCD();
     writeStrLCD("FRAME ERROR " ) ;
     sound(30,30);
     delay(1000);
     sound(40,40);
     while (1); {} 
 }
//Check for Overrun Error
 if ((SCI1SR1 & BM_OR) > 0)   // test frame...
  { 
 c = SCI1DRL;     // Get Data to clear Flag..
//    just clear and exit.........  
 }
// General Errors Check....
   c=SCI1SR1 & 0x07;
if (c > 0)
  {
   bError=c;
   c = SCI1DRL;     // Get Data to clear Flag..
   clearLCD();
   writeStrLCD("ERROR..  " ) ;
   writeIntLCD(bError & 0x0f); 
   sound(30,30);
   delay(1000);
   sound(40,40);
   delay(9000); 
   while (1); {} 
 }
 
// debug.....  sound tick just before test for first byte...
   PTT ^= 0x04;            // click to speaker....
 
 if ((SCI1SR1 & BM_RDRF) == 0)
  { 
   return;
 }
 c = SCI1DRL;     // Get Data..
// debug  Led Flash IF just one byte received...
  onLED;
  delay(30);
  offLED;
........................................................
..........................................................
..............................................  more code follwes.......
 
When program works OK it goes into GetSerial sub and you can hear the clicks from
                PTT ^= 0x04;  
 
When a byte from PC arrives also code below is executed and you see on board LED flashing..
            onLED;
            delay(30);                // 30 msecs...
            offLED;
 
When Rx stucks Off (after hours to days) you can only hear the clicks from PTT but NO led, so i assume (???) that
    if ((SCI1SR1 & BM_RDRF) == 0)
    { 
      return;
     }
 
is NOT seeing incoming byte.......
 
At the same time byte(s) from the PC is seen and received from other S12 PLCs connected to the same bus......
 
I was able to simulate the problem apart from installation site on my PC.  When stuck it will not recover if not reseted...........It will not also recover when  i did (manually) an INITSCI1, still at the same time ALL other program in the S12 is OK !!
 
There are NO SCI interrupts (as seen by initilisation code).
 
Code was added to try to trace any Frame errors, still no indication of that, since program would halt in frame err.. (code seen below)
 
//Check for Frame Error
 if ((SCI1SR1 & BM_FE) > 0)
  { 
     c = SCI1DRL;     // Get Data to clear Flag..
    clearLCD();
    writeStrLCD("FRAME ERROR " ) ;
    sound(30,30);
    delay(1000);
    sound(40,40);
     while (1); {} 
 }
 
 
Any possible H/W issues refering to proper 485 operation were taken out since i changed from SCI1 to SCI0 which is RS232 and problem is exactly the same....
 
 
I would appreciate very much any help since we're trying to resolve it form 2-3 months
Thanks in advance!
 
Nick
 
 
Added p/n to subject.
 


Message Edited by NLFSJ on 2008-06-23 11:32 AM
Labels (1)
0 Kudos
10 Replies

733 Views
nikosxan
Contributor I
Hi again
 
Problem still there, any more ideas ?
0 Kudos

733 Views
Lundin
Senior Contributor IV
A bit far-fetched, but out of curiousity have you tried to disassemble the program? Since the varible "c" isn't volatile, it is possible that the compiler optimizes the code and ignores the lines with c = SCI1DRL; in cases where the result isn't used. If you disassemble, you should see whether that line is actually translated to machine code or not.
0 Kudos

733 Views
nikosxan
Contributor I
Here's the dissasembly of the code.......... Soirce lines shown also... (c=SCI1DL;  // Get data)
 
5F6E    if ((SCI1SR1 & BM_RDRF) == 0)
5F6E       1F00D42002     BRCLR   00D4 #20 5F75
5F73       2004           BRA     5F79
               {
5F75             return;
5F75       1820007F       LBRA    5FF8
               }
5F79           c = SCI1DRL;               // Get Data..
5F79       F600D7         LDAB    00D7
5F7C       6B13           STAB    -D,X
       #endif 
       //        PTT ^= 0x04;                             // debug.....
       // debug  Led Flash IF just one byte received...
0 Kudos

733 Views
nikosxan
Contributor I
Hello.
 
I think it was a bit clear that the program works CORRECTLY for quite a lot time (at least 3-4 days) and after it just stops responding until reset............ So,  i think, if any compiler problem / optimazation   should result in a situation that in every case incoming byte should be ingnored ....
 
the case is that most of the time it works...........then -someday- stop receiving at all, then if you reset the same code exactly works again......(just as before)...
 
On the other hand, var c is used just after the mentioned line....... (however, i'll check and try to get the dissasembled code.
 
thank you for the reply ! :smileyhappy:
 
Nick
0 Kudos

733 Views
kef
Specialist I
Hm, in what conditions and how often do you call your GetSerial() routine? Since you hear ticks from PTT ^= 4, and not tone, couldn't it be permanent overrun? Overrun every time you call GetSerial() ?
Also it's weird you ignore received data when OR is set.
 
0 Kudos

733 Views
nikosxan
Contributor I
>>Also it's weird you ignore received data when OR is set.
 
My receive upproach was quite primitive, Call GetSerial in 10 / sec rate. PC sends first byte and waits a bit, PLC gets 1st byte, then waits for more if so in order to get all data from PC....
0 Kudos

733 Views
kef
Specialist I
nikosxan,
 
I'm not sure why it doesn't receive. Did you try stopping PC traffic for a while, then starting it again? Still no receive?
 
 
Regarding overruns. You have this for OR case
 
//Check for Overrun Error
 if ((SCI1SR1 & BM_OR) > 0)   // test frame...
  { 
 c = SCI1DRL;     // Get Data to clear Flag..  <--- this data you are ignoring
//    just clear and exit.........  
 }
 
You shouldn't ignore data in case both OR and RDRF are set. So maybe replace both with this
 
//Check for Overrun Error
 if ((SCI1SR1 & BM_OR) && !(SCI1SR1 & BM_RDRF)) 
  { 
   c = SCI1DRL;     // clear OR here only if RDRF is not set.
                               // When RDRF is set, OR will be cleared along with RDRF
   return;
 }
0 Kudos

733 Views
nikosxan
Contributor I
Helllo.
YES, stopping PC traffic doesn't  solve the problem.
 
You're right for the overrun byte, but this is not all the time (the overrun state - check this) and i don't think it's related to the problem. I don't lose one or two bytes, it just stops at alla receiving....even one byte.....then, just after a reset it starts again.............Also, communication works OK (including some rare overrun erros that don't prevent pc communication, for days.........
0 Kudos

733 Views
nikosxan
Contributor I
Sorry, forgot the 'conditions'.
 
In general there is a control program handling some I/O but most of the time it does a loop for I/O handling, screen update (LCD) AND calls also Getserial. GetSerial is being called at least 8-10 times per sec. Actual code below....
 
void DoGeneralTasks(void) {
  GetSerial();
  ResetCOP;
  UpdateTime();
  CheckMachineState();
// Update Counters
  if (cMachineState == sMachineOn)
      DoHDCount();        // Days, Hours Counters
  if (cMachineState ==sMachineOnWaiting )
      DoHoursCountDown();         // Hours Count DOWN !!!
}
0 Kudos

733 Views
nikosxan
Contributor I
GetSerial is called about 8-10 times /sec (or more).  Second  byte from PC comes a sufficient time after first byte, not to be lost . In 99.99 (or more !!! :smileyhappy: of the cases this is sufficient for the S12 PLC to be able to get OK ALL PC data, since it comminicates OK for days. In simulation of the error it communicates OK for hours before stuck (simulation send at 100 times the rate compared to normal use).
 
Considering the ovverrun case :
 
  a) set some code to see how often it happens (with another sound). It did happend some times, yet reception is still ok, apart from a couple of bytes lost......
  b) In normal -not emulated- case could be some byte overrunts but in general the S12 reception works OK !!!
 
thanks for answer !!
0 Kudos