FX2 problems with SDCC

Help
2009-03-06
2013-03-12
  • I have been trying to use the FX2 board with SDCC 2.8.0.  I have hit a problem that I hope people can shed some light on.

    First off it took me some time to get the XPAGE register in the correct place.  I think I now do as the .map file lists it as

    Hexadecimal

    Area                               Addr   Size   Decimal Bytes (Attributes)
    --------------------------------   ----   ----   ------- ----- ------------
    .  .ABS.                           0000   0000 =      0. bytes (ABS,CON)

          Value  Global
       --------  --------------------------------
         0092    __XPAGE
         00F5    _B_5
         00F6    _B_6
         00F7    _B_7
         2000    _buttons

    I now have a simple program up and running, but as soon as I tried to use a variable of xdata type without specifying and explicit address the system goes out to lunch.  In the map listing above I had defined buttons as

    xdata __at (0x2000) BYTE      buttons;

    IF I now change that definition to

    xdata  BYTE      buttons;

    the program stops working even though I am not ever running this piece of code.   I can create another variable that is not used such as

    xdata __at (0x2000) BYTE      buttons;
    xdata BYTE never_ever_used;

    and my program stops working.  The map file shows _buttons off in this location when I don't give it a physical address.

    Area                               Addr   Size   Decimal Bytes (Attributes)
    --------------------------------   ----   ----   ------- ----- ------------
    XSEG                               0000   0001 =      1. bytes (REL,CON,XDATA)

          Value  Global
       --------  --------------------------------
      0D:0000    _buttons

    This appears to be tromping over some important piece of memory.  What option have I defined wrong, or what am I doing wrong?

    Oliver

     
    • Maarten Brock
      Maarten Brock
      2009-03-06

      Oliver,

      Since the FX2 has unified code and xdata memory you need to tell the linker not to mix these memory areas. I advise to reserve space for code memory from 0x0000 (default) with a fixed maximum length (see --codesize) and to put xdata memory after that with --xram-loc. Depending on which FX2 you have you can fill in the numbers.

      Maarten

       
    • Maarten,

      OK that suggestion has help a bit.  I added the following flags to my linker statement.

      --code-size 0x1000 --xram-loc 0x3000 --xram-size 0x500

      And I can now use some xdata.  What I find is if I use the following statement, things compile and run fine

      BYTE xdata buttons = 0;

      BYTE xdata Digit[] = { 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e };

      with a .map file that says
      Hexadecimal

      Area                               Addr   Size   Decimal Bytes (Attributes)
      --------------------------------   ----   ----   ------- ----- ------------
      XISEG                              3000   0011 =     17. bytes (REL,CON,XDATA)

            Value  Global
         --------  --------------------------------
        0D:3000    _buttons
        0D:3001    _Digit

      But if I change the above statement to

      BYTE xdata buttons;

      BYTE xdata Digit[] = { 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e };

      My program stops working again, even though I am not using buttons yet.  In this case the map file now says:

      Hexadecimal

      Area                               Addr   Size   Decimal Bytes (Attributes)
      --------------------------------   ----   ----   ------- ----- ------------
      XSEG                               3000   0001 =      1. bytes (REL,CON,XDATA)

            Value  Global
         --------  --------------------------------
        0D:3000    _buttons

      Hexadecimal

      Area                               Addr   Size   Decimal Bytes (Attributes)
      --------------------------------   ----   ----   ------- ----- ------------
      XISEG                              3001   0010 =     16. bytes (REL,CON,XDATA)

            Value  Global
         --------  --------------------------------
        0D:3001    _Digit

      So buttons has moved from the XISEG to the XSEG.  The memory addresses look ok however.

      I can probably live with the above, but it would be nice to know why it is failing.

      The next issue I am having after that is the interrupts do not seem to be working.  I borrowed the following code from the cypress examples.

      void EZUSB_InitI2C(void)
      {
          I2CPckt.status = I2C_IDLE;

          EI2C = 1;    // Enable I2C interrupt
          EA = 1;        // Enable 8051 interrupts
      #ifdef TNG
         I2CMODE |= 0x02;  // enable I2C Stop interrupt
      #endif

      }

      BOOL EZUSB_WriteI2C_(BYTE addr, BYTE length, BYTE xdata *dat)
      {
      #ifndef TNG
         // if in progress, wait for STOP to complete
         while (I2CS & bmSTOP);
      #endif

          if(I2CPckt.status == I2C_IDLE)
          {
              I2CS |= bmSTART;
              I2DAT = addr << 1;

              I2CPckt.length = length;
              I2CPckt.dat = dat;
              I2CPckt.count = 0;
              I2CPckt.status = I2C_SENDING;

              return(TRUE);
          }

          return(FALSE);
      }

      and I added a piece of code for the i2c ISR

      void i2c_isr(void) interrupt I2C_VECT
      {                                                    // I2C State Machine

      The problem is I never get into the ISR.  Any suggestions on what may be failing?

      Oliver

       
    • Alright, I have resolved the problem.  In the Cypress header file they distribute in their example FX2 projects they define the sfr's as

      // Way in Cypress header
      sfr MPAGE = 0x92;

      This compiles without warning on the sdcc and it even does the logical thing.  I expect this is Keil's tortured syntax.  When I changed all the sbit and sfr definitions to the sdcc standard

      // Example sfr definition
      __sfr __at (0x92) MPAGE;

      and rebuilt things work correctly.  I hope this helps other folks struggling with bringing up the board.

      Oliver

       
      • __sfr __at (0x92) MPAGE; ?

        _XPAGE; !!

        see chapter 4.1.1 "pdata access by SFR" in the manual.

        Sorry that your chip manufacturer does not supply an appropriate header file to its customers.

        Note, SDCC supports a mechanism for compiler independent header files.
        (see chapter 6.1 "Porting code from or to other compilers" or directly the file
        http://sdcc.svn.sourceforge.net/viewvc/sdcc/trunk/sdcc/device/include/mcs51/compiler.h?view=markup )

        For yet unknown reason most (well, almost all) manufacturers do not use this scheme.
        In doing so they waist their customers time and money - which at the end of the day most likely does not translate into more silicium sold by the chip vendors.
        I am having a really hard time understanding the mathematics behind that.

        The reason of  the slow pickup of this format (which besides being available with SDCC  was published  (in 2006) f.e. here http://www.8052.com/forum/read/116161 ) is not yet known. But well, at least YOU know, YOU have been hit.

         
        • I have defined

          __sfr __at 0x92 _XPAGE;

          as well as the MPAGE.  The FX2 header file form Cypress had MPAGE in it, so I assume I should keep the reference.  I know I need the _XPAGE definition as I saw in the start up code that it was being used.  If I don't define _XPAGE it defaults to 0xA0.

          Oliver