S08DZ clock problem when BDM isn't connected

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

S08DZ clock problem when BDM isn't connected

2,604 次查看
Lundin
Senior Contributor IV
I'm having this really strange problem with a S08DZ16. When I run the program through the BDM, everything works fine. When the BDM is disconnected, the MCU resets itself during the clock setup code, which is as follows:

  MCGC1 = 0x80;                                  /* External reference clock */
         
  MCGC2 = MCGC2_RANGE_MASK |                     /* High frequencey range 1-16MHz */
          MCGC2_HGO_MASK   |                     /* High gain oscillator */
          MCGC2_LP_MASK    |                     /* Disable FLL / PLL in bypassed mode */
          MCGC2_EREFS_MASK |                     /* Oscillator requested */
          MCGC2_ERCLKEN_MASK;                    /* Enable the external reference clock */

  while((MCGSC & MCGSC_OSCINIT_MASK)==0)         /* Wait until the initialization cycle of the */
    ;                                            /* external crystal clock is completed        */

  while((MCGSC & 0x0C) != 0x08)                  /* While clock source is not external clock */
    ;

  MCGC3 = 0x00;                                  /* PLLS=0  -> FLL */




I set the clock the first thing I do after setting up the stack and the watchdog, so I get the crash rather instantly, after 500us. I can see that the reset line is then pulled low. I haven't managed to tell the proper reset cause from the SRS register, but it shows nothing.

I have the same hardware in another working DZ16 project, so I doubt it is related to hardware. The clock is a "Pierce" oscillator connection with 8MHz crystal, two 22pf caps and 1M ohm parallel with the crystal. Same design as I always use. If I check the oscillator with an oscilloscope, I see that I have a working clock on 8MHz running.

I tried clock setup code from the other working DZ16 project, and get the same error.

When the BDM is connected, everything works!

There is nothing on the reset line that could cause external resets. I have tried various values on the cap on the reset line, 100pF and 100n give the same problem. I have tried an external pull-up, in case the internal one wasn't working, same problem.

I checked the errata for the mask 3M05C. It mentions problems when you divide the clock by 1 and have the FLL enabled in bypassed mode. I have tried the workarounds in the errata and I get the same problem, so I doubt this is the cause. Various prescaler settings (divide by 1, 2, 4 etc) and enable/disable FLL in bypassed mode, all give the same problem.

The watchdog is set to 2^18 cycles, so it shouldn't be an issue.

I have the same issue on two boards, I'm pretty sure it isn't related to soldering.

Any ideas? Corrupt silicon batch?
标签 (1)
0 项奖励
回复
4 回复数

981 次查看
bigmac
Specialist III
Hello Lundin,
 
Your problem seems to be related to the entry to FBELP mode (via FBE mode).  When the BDM is enabled FBELP mode cannot be entered, even though the LP bit is set to 1.
 
There would appear to be some confusion about the frequency range for the crystal.  For FBE mode, the specified allowable range is 1 - 5 MHz, but for FBELP mode 1 - 16 MHz.  However, it would seem that FBELP mode cannot be reached without first passing through FBE mode (from FEI mode immediately following reset).  So I don't know how the datasheet intended that that crystal frequencies above 5 MHz would be utilized.  Perhaps you could try a 4 MHz crystal to see if the problem is still present.
 
Even though you are not ultimately using the FLL, you could also try setting RDIV for maximum division to see if any effect.
 
Regards,
Mac
0 项奖励
回复

981 次查看
Lundin
Senior Contributor IV
Thanks for your reply.

Although my clock initialization seems a bit fishy, it isn't the cause of the problem.

I found out that the debug code following immediately after the clock init and the wdog init is the cause of the reset. The code is executed from the reset ISR, and if I remove it, everything works smoothly:

  if(SRS > 0)                                    /* If reset source wasn't the BDM */
  {
    uint8 srs = SRS;
 
    if( (srs & SRS_POR_MASK) > 0 )               /* Reset caused by POR */
    {
      asm NOP;
    }
    else if( (srs & SRS_PIN_MASK) > 0 )          /* Reset caused by reset pin pulled low */
    {
      asm NOP;
    }
    else if( (srs & SRS_COP_MASK) > 0 )          /* Reset caused by COP */
    { 
      asm NOP;
    }  
    else if( (srs & SRS_ILOP_MASK) > 0 )         /* Reset caused by illegal op code */
    {
      asm NOP;
    }
    else if( (srs & SRS_ILAD_MASK) > 0 )         /* Reset caused by illegal address access */
    {
      asm NOP;
    }
    else if( (srs & SRS_LOC_MASK) > 0 )          /* Reset caused by loss of clock */
    {
      asm NOP;
    }
    else                                         /* Reset caused by LVD etc */
    {    
      asm NOP;
    }
  }


And this is the disassembly:

286:    if(SRS > 0)                                    /* If reset source wasn't the BDM */
  000e c60000   [4]             LDA   _SRS
  0011 272e     [3]             BEQ   L41 ;abs = 0041
  287:    {
  288:      uint8 srs = SRS;
  0013 c60000   [4]             LDA   _SRS
  0016 9ee701   [4]             STA   1,SP
  289:   
  290:      if( (srs & SRS_POR_MASK) > 0 )               /* Reset caused by POR */
  0019 2a03     [3]             BPL   L1E ;abs = 001e
  291:      {
  292:        asm NOP;
  001b 9d       [1]             NOP  
  293:      }
  001c 2023     [3]             BRA   L41 ;abs = 0041
  001e          L1E:   
  294:      else if( (srs & SRS_PIN_MASK) > 0 )          /* Reset caused by reset pin pulled low */
  001e a540     [2]             BIT   #64
  0020 2703     [3]             BEQ   L25 ;abs = 0025
  295:      {
  296:        asm NOP;
  0022 9d       [1]             NOP  
  297:      }
  0023 201c     [3]             BRA   L41 ;abs = 0041
  0025          L25:   
  298:      else if( (srs & SRS_COP_MASK) > 0 )          /* Reset caused by COP */
  0025 a520     [2]             BIT   #32
  0027 2703     [3]             BEQ   L2C ;abs = 002c
  299:      { 
  300:        asm NOP;
  0029 9d       [1]             NOP  
  301:      }  
  002a 2015     [3]             BRA   L41 ;abs = 0041
  002c          L2C:   
  302:      else if( (srs & SRS_ILOP_MASK) > 0 )         /* Reset caused by illegal op code */
  002c a510     [2]             BIT   #16
  002e 2703     [3]             BEQ   L33 ;abs = 0033
  303:      {
  304:        asm NOP;
  0030 9d       [1]             NOP  
  305:      }
  0031 200e     [3]             BRA   L41 ;abs = 0041
  0033          L33:   
  306:      else if( (srs & SRS_ILAD_MASK) > 0 )         /* Reset caused by illegal address access */
  0033 a508     [2]             BIT   #8
  0035 2703     [3]             BEQ   L3A ;abs = 003a
  307:      {
  308:        asm NOP;
  0037 9d       [1]             NOP  
  309:      }
  0038 2007     [3]             BRA   L41 ;abs = 0041
  003a          L3A:   
  310:      else if( (srs & SRS_LOC_MASK) > 0 )          /* Reset caused by loss of clock */
  003a a504     [2]             BIT   #4
  003c 2702     [3]             BEQ   L40 ;abs = 0040
  311:      {
  312:        asm NOP;
  003e 9d       [1]             NOP  
  313:      }
  003f 21       [3]             SKIP1 L41 ;abs = 0041
  0040          L40:   
  314:      else                                         /* Reset caused by LVD etc */
  315:      {    
  316:        asm NOP;
  0040 9d       [1]             NOP  
  0041          L41:   
  317:      }
  318:    }


Now, if the code did a write access to SRS somewhere (address 0x1800), I would have expected a reset. But it is all read-only. So why does the above code reset the mcu? Aren't you allowed to read SRS from the reset ISR? If not, where is this documented? If the BDM is connected, the above code won't be executed, which explains why everything works with the BDM connected.

To clearify, my reset ISR looks like this:

- Set SP.
- Init clock
- Init wdog
- The above debug code to check the cause of the reset.
- JMP to main().

Am I missing something in the documentation or is this a silicon bug?
0 项奖励
回复

981 次查看
bigmac
Specialist III
Hello Lundin,
 
How did you initialize the stack pointer - is this being done by the compiler, or are you coding it yourself?  Is it possible that the stack  may start at a flash address, where the instruction STA 1,SP would be problematic?  I assume that the assembly code does provide a AIS #-1 instruction somewhere preceeding the above.
 
Do you also have any static variables that are initialized prior to the jump to main().?  Does the problem persist if the clock initialisation process is placed in main(), rather than where you currently have the code?
 
I cannot actually see why the reset initialisation code would not run when the BDM is connected.
 
Regards,
Mac
 
0 项奖励
回复

981 次查看
Lundin
Senior Contributor IV
Yes, you are correct... it turned out to be an embarrassing stack error. The stack init code was taken from another project where I had set the SP one byte too high on purpose, to avoid the loss of stack that comes from calling main...

I had dismissed that as the cause, because I was calling functions from the ISR, and you'd think the stacking of parameters to those would have caused the crash. Oddly enough, they didn't.

The part regarding the BDM disactivating the SRS is from the manual p78:
"When a debug host forces reset by writing 1 to BDFR in the SBDFR register, none of the status bits in SRS will be set."

Thanks for helping!
0 项奖励
回复