This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ISD51 has a problem

Hello,
I have a problem using ISD51 to debug my code. AT first, I used the simulator to run my code and it works fine. Then I added ISD51.A51 into my project and also added ISDinit() and ISDcheck() to my code, changed the OPTION menu to enable ISD51 and compiled. The problem is that the code doesn't start running after loading (seems waiting). Can anyone help with it?
Another thing: during compiling, I saw there were a few bytes overlap in code space. Does it matter?

Thanks
Frank
-------------------------------------------
compiling LOG.C...
compiling test.c...
assembling Conf_tny.a51...
assembling STARTUP.A51...
assembling ISD51.A51...
linking...
*** WARNING L5: CODE SPACE MEMORY OVERLAP
FROM: 0023H
TO: 0025H
Program Size: data=68.3 xdata=454 code=16180
creating hex file from ".\output\snake"...
".\output\snake" - 0 Error(s), 1 Warning(s).

Parents
  • Seems like we all have had our trials and tribulations with ISD51. I offer some insights from my own painful experiences:

    1. The ISD51 User Guide is skimpy and only warns indirectly about the interrupt vector 0x23, which is the Serial UART interrupt for most 8051 devices. (This vector is defined in symbol SINTRVEC within ISD51.h.) The Guide does warn, however, that interrupt vector 0x33 is used for hardware breakpoints in certain chips. This code is assembled if the TI_MSC1210_BREAKS symbol is defined at the bottom of ISD51.h. This latter interrupt is re-vectored to 0x6B by ISD51, so you need to change your code to capture that vector if you use it (you are NOT removing your Interrupt service routine in this case -- you are merely relocating it).

    2. BEWARE the Watchdog Timer! For example, when enabled via configuration bytes on a Philips LPC935 chip, the Watchdog starts with a default timeout of roughly 2 seconds. This is NOT enough time for ISD51 to establish its connection with the chip! You need at least 5 seconds. Remember that most Watchdogs have their own clock source, and this runs regardless of what ISD51 is doing, so if you execute a breakpoint, the Watchdog keep ticking (and eventually bite you in the ass)! A Watchdog Timeout that Resets the MCU will typically result in the appearance of a NO CONNECTION or ERRONEOUS COMMUNICATION failure within ISD51 -- exactly the problem most often described in this and similar threads. This took me forever to figure out. I now disable the Watchdog Timer entirely whenever I am using ISD51!

    3. Don't forget to enable global interrupts by setting the EA bit. ISD51 cannot take control if this bit (or the ES bit) is cleared.

    4. Among the ISDinit, ISDwait, and ISDcheck functions, I have found ISDwait is most useful. When using this function, use it by itself! DO NOT precede it with a call to ISDinit or you will likely find your program looping within the wait function without breaking. ISDwait stops execution nicely and neatly. Then you can set breaks and issue commands from the debugger console and continue on from there. WARNING: If you use ISDinit by itself, your program can get VERY far into its execution before the ISD51 interrupt takes control -- and your code can do a lot to foul up ISD51 in that time. For example, clearing the global interrupt OR looping within an interrupt service routine will prevent the UART interrupt from ever occuring -- and ISD51 will appear dead in the water!

    5. Last, but not least, DISABLE any code that uses the TxD and/or RxD pins of the UART port. If you need to communicate data via the UART, the ISD51 functions provided will do a fairly good job of allowing you to use the UART at the same time as ISD51. If you go around these functions (or the stdio.h) to directly manipulate the UART I/O, you are likely headed for frustration.

    Hope somebody finds these tips useful!

    Steve

Reply
  • Seems like we all have had our trials and tribulations with ISD51. I offer some insights from my own painful experiences:

    1. The ISD51 User Guide is skimpy and only warns indirectly about the interrupt vector 0x23, which is the Serial UART interrupt for most 8051 devices. (This vector is defined in symbol SINTRVEC within ISD51.h.) The Guide does warn, however, that interrupt vector 0x33 is used for hardware breakpoints in certain chips. This code is assembled if the TI_MSC1210_BREAKS symbol is defined at the bottom of ISD51.h. This latter interrupt is re-vectored to 0x6B by ISD51, so you need to change your code to capture that vector if you use it (you are NOT removing your Interrupt service routine in this case -- you are merely relocating it).

    2. BEWARE the Watchdog Timer! For example, when enabled via configuration bytes on a Philips LPC935 chip, the Watchdog starts with a default timeout of roughly 2 seconds. This is NOT enough time for ISD51 to establish its connection with the chip! You need at least 5 seconds. Remember that most Watchdogs have their own clock source, and this runs regardless of what ISD51 is doing, so if you execute a breakpoint, the Watchdog keep ticking (and eventually bite you in the ass)! A Watchdog Timeout that Resets the MCU will typically result in the appearance of a NO CONNECTION or ERRONEOUS COMMUNICATION failure within ISD51 -- exactly the problem most often described in this and similar threads. This took me forever to figure out. I now disable the Watchdog Timer entirely whenever I am using ISD51!

    3. Don't forget to enable global interrupts by setting the EA bit. ISD51 cannot take control if this bit (or the ES bit) is cleared.

    4. Among the ISDinit, ISDwait, and ISDcheck functions, I have found ISDwait is most useful. When using this function, use it by itself! DO NOT precede it with a call to ISDinit or you will likely find your program looping within the wait function without breaking. ISDwait stops execution nicely and neatly. Then you can set breaks and issue commands from the debugger console and continue on from there. WARNING: If you use ISDinit by itself, your program can get VERY far into its execution before the ISD51 interrupt takes control -- and your code can do a lot to foul up ISD51 in that time. For example, clearing the global interrupt OR looping within an interrupt service routine will prevent the UART interrupt from ever occuring -- and ISD51 will appear dead in the water!

    5. Last, but not least, DISABLE any code that uses the TxD and/or RxD pins of the UART port. If you need to communicate data via the UART, the ISD51 functions provided will do a fairly good job of allowing you to use the UART at the same time as ISD51. If you go around these functions (or the stdio.h) to directly manipulate the UART I/O, you are likely headed for frustration.

    Hope somebody finds these tips useful!

    Steve

Children
  • Thanks Steve for your valid points. Unfortunately, I'm still having troubles in debugging ISD51.
    Below is my piece code for my testing purpose. Can you find out something wrong in it?

    /* parameters to initialize serial communication */
    #define  B_38400   0x05 /* 38400 baud */
    #define  B_19200   0x04 /* 19200 baud */
    #define  B_9600    0x03 /*  9600 baud */
    #define  B_4800    0x02 /*  4800 baud */
    #define  B_2400    0x01 /*  2400 baud */
    #define  B_1200    0x00 /*  1200 baud */
    
    void Delay(unsigned int i)	{
    
    unsigned int j;
    
    	while(i--) {	// delay
    
    		j = 0x200;
    		while (j--) {
    #ifndef ISD51  // init ISD51 only when the uVision2 Debugger tries to connect
    			WDT = 1;	// reset
       		SWDT = 1;
    #endif
    		};
    	}
    }
    
    void Project_Init(serBaud)  {
      switch ( serBaud )
       { /* oscillator frequency = 10 Mhz */
    
       case B_38400:
          SRELH = 0x03; /* Reloadwert fĂĽr 38400 Baud */
          SRELL = 0xF0;
          PCON |= 0x80; /* SMOD = 1 */
          break;
    
       case B_19200:
          SRELH = 0x03; /* Reloadwert fĂĽr 19200 Baud */
          SRELL = 0xDF;
          PCON |= 0x80; /* SMOD = 1 */
          break;
    
       case B_9600:
          SRELH = 0x03; /* Reloadwert fĂĽr 9600 Baud */
          SRELL = 0xBF;
          PCON |= 0x80; /* SMOD = 1 */
          break;
    
       case B_4800:
          SRELH = 0x03; /* Reloadwert fĂĽr 4800 Baud */
          SRELL = 0x7E;
          PCON |= 0x80; /* SMOD = 1 */
          break;
    
       case B_2400:
          SRELH = 0x02; /* Reloadwert fĂĽr 2400 Baud */
          SRELL = 0xFC;
          PCON |= 0x80; /* SMOD = 1 */
          break;
    
       case B_1200:
          SRELH = 0x01; /* Reloadwert fĂĽr 1200 Baud */
          SRELL = 0xF7;
          PCON |= 0x80; /* SMOD = 1 */
          break;
    
       default:
          return;
          break;
       }
    
       ADCON0 |= 0x80; /* enable baud rate generator */
       SCON = 0x50; /* mode 1: 8-bit UART, enable receiver   */
    }
    
    
    /* Test Function: verify serial communication with HyperTerminal */
    void TestSerial (void)  {
      char c = 'A';
    
      TI = 1;
      while (1)  {
    
    	Delay(200);
    
       if (RI)  {
          c = SBUF;
          RI = 0;
        }
        while (!TI);
        TI = 0;
        SBUF = c;
      }
    }
    
    
    void main (void)  {
    unsigned int i;
    
    #ifndef ISD51  // init ISD51 only when the uVision2 Debugger tries to connect
    
      	Project_Init(B_9600);     // Initialize Chip and Serial Interface
    
    	TestSerial();
    
    #else
    
       SRELH = 0x03; 	/* set up 9600 Baud */
       SRELL = 0xBF;
       PCON |= 0x80; 	/* SMOD = 1 */
       ADCON0 |= 0x80;/* enable baud rate generator */
       SCON = 0x50; 	/* mode 1: 8-bit UART, enable receiver   */
    
      	ISDinit();        // initialize uVision2 Debugger and continue program run
    #endif
    
    	ES = 1;
    	EAL = 1;              /* Enable global interrupt flag       */
    //   TimerInit();
      while (1)  {
    #ifdef ISD51  // init ISD51 only when the uVision2 Debugger tries to connect
       ISDcheck();      // initialize uVision2 Debugger and continue program run
    	Delay(200);
    #endif
    
    	i++;
    
      }
    }
    

  • Frank,

    Let's start with the obvious:

    1) To generate your ISD51 code, make sure you have the symbol ISD51 defined. I don't see a header file included anywhere so I cannot tell. (Sorry if that is TOO obvious.)

    2) You are calling ISDinit() BEFORE enabling interrupts. Try moving the call to ISDinit() to AFTER the ES and EAL settings. This may not be a big problem, but it could cause a timing issue in the handshake.

    3) Better yet, remove the call to ISDinit() and just use ISDcheck() by itself. This function actually does the ISDinit() for you, after it sees the incoming 0xA5 from the debugger.

    ----

    Note: The ISDwait() and ISDcheck() functions really don't do ANYTHING after the Serial Interrupt (ES) is enabled by ISDinit(). (In fact, ISDinit() doesn't do anything if called more than once, because it sees that the ES flag is already enabled.) ISDwait() and ISDcheck() are different from ISDinit() only in that they LOOK for an incoming 0xA5 from the debugger BEFORE they invoke ISDinit() which, in turn, merely enables the Serial Interrupt (by setting ES). Thereafter, just about everything (including further 0xA5 handshakes) is controlled by the Serial Interrupt servicing routine contained within ISD51.A51 (until such time as you explicitly disable the interrupt).

    ISDcheck() is useful if you want your code to run semi-normally in the ABSENCE of the debugger. ISDcheck() essentially performs a No-Op when it is called, UNLESS a 0xA5 is present on the UART Receive pin. Then, and only then, does ISDcheck() launch the ISD51 Interrupt as described above.

    Steve

  • Thanks Steve for your reply. I have the following comments.
    1. I don't understand why I need a header file. I'm using PK51-kit and I can define ISD51 as Preprocessor Symbols in IDE option menu.
    2. Calling ISDinit() after ES set seems meanless to me. If you check ISDinit(), ISD is ONLY initialized when ES=0.
    3. As I said before, if I call ISDcheck() after ES=1 set, ISDcheck() will do nothing.

    Can you give more comments on above? Thanks.

    Frank

  • All our examples do not enable the serial interrupt (this is done by the ISD51 core. Therefore you should remove the line:

    ES = 1

    Take also a look to the example in the folder:
    C:\Keil\c51\ISD51\Examples\Generic 8052

  • OK. After I removed that, nothing changed.

  • How come the Keil IDE keeps giving me an erro message "There was a wrong reply from the target system! Please check..."

  • Note: I used the Hyperterminal and Simulator to verify the code working properly before using ISD51.

  • Sorry about that. I must have been sleeping! I totally missed that fact that you were setting ES (which you should allow ISD to handle for you).

    No, you don't need a header if you set the symbols from within IDE.

    So you removed the setting of ES. Did you also remove the call to ISDinit()?

    (By the way, what chip are you programming for?)

  • Yes, I removed the ISDcheck(). My processor is C515C. Another funny thing is: when you hit the Debug button, sometimes the time of "connecting to ISD51" could take about 5 seconds up to 100%, but most times only about a half seconds. Why there is such a difference? I'm running the Keil software PK-51 under Windows 2000 OS.

  • Another note: 5 seconds connecting time seems always giving me "There was a wrong reply"; half second connecting time always giving me "Communication problem with ISD51".

  • Your code is simple enough. The only GUESS I would make right now is that you are having serial communications problems such as noisy line, bad DSR/DTR connection, or a baud mismatch. The two different error messages would support that, tending to indicate different data being observed across different attempts.

    But you say you can communicate with your processor via HyperTerminal, so that is odd. Did you say that you have seen the microprocesssor successfully send data to the PC via the UART? (When you send an 0xA5 to the application, it sends back 6 bytes which appear in HyperTerminal?)

  • Maybe some sort of Baudrate problem. I also guess that you have a problem with the COM interface between PC and hardware.

  • What I tested is that using the Hyperterminal with ISD51 undefined in IDE, from the source code above, you can see my board should send back any character I typed in the Hyperterminal windows. It did well.

  • I just tried the ISD51 code downloaded into my board using the Hyperterminal. I pressed the ALT + 0,1,6,5 (A5), then I got 4 characters in the Hyperterminal window from my board my every time. Does it sound correct?

  • Are you sure it's 6 characters, not 4 characters?