Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

Help with ADuC847 memory init.

Help
adam
2008-07-16
2013-03-12
  • adam
    adam
    2008-07-16

    I'm completely stuck trying to get the Analog Devices' ADuC847 to work with SDCC.  The problem seems to be the startup code is not working when I reserve a large block of memory.  Allocating a block of program memory also give various unpredictable effects.

    My code is given below and without the ram_fluff allocation P0 is set to 1.  When I reserve the block of memory P0 comes up with some slightly random values, usually 0.

    I've been trying to figure this out for a week now with no success.

    Any thoughts?

    Thanks

    Adam

    ***** main.c *****
    #include "847SFR.h"
    #define byte unsigned char
    __sfr __at (0x84) __XPAGE;

    __xdata static byte ram_fluff [ 1000 ];
    /*__code byte prog_fluff [ 1000 ] = {0};*/
    __xdata static volatile byte global_byte = 1;

    void main( void )
    {
        /*func();*/
        P0 = global_byte;
        for (;;);
    }

    byte _sdcc_external_startup ( void )
    {
        PLLCON = 0x53;
        PSW &= ~(0x18);
        _asm
            CLR EA
            SETB _WDWR
            MOV _WDCON, #0x10
        _endasm;
        DPCON = 0;
        DPP = 0;
        CFG84x |= 0x01;  /* Extended stack diabled, Internal XRAM mapped to lower 2k of external address space */
        return 0;
    }
    ***** end main.c *****

    Which I compile for the standard UART programming tool using:

    NO_OPT="--nogcse --noinvariant --noinduction --nojtbound --noloopreverse --nolabelopt --nooverlay --peep-asm"
    CFLAGS="--model-large -I. -Iinclude -IRTOS/include -L/home/adam/active/8051/sdcc/share/sdcc/lib/large --less-pedantic --no-peep --int-long-reent --float-reent --debug"
    CFLAGS=$CFLAGS" --xram-size 2048 --code-size 63488 --stack-auto "$NO_OPT
    SOURCE_DIR="RTOS"
    sdcc    $CFLAGS main.c
    packihx main.ihx > main.hex_unix
    sed -e 's/$/\r/' main.hex_unix > main.hex

     
    • adam
      adam
      2008-07-16

      I forgot to mention that even though the memory fails to initialize the label global_byte points to a valid point in memory and may be correctly assigned in the program, it's only in startup it doesn't work.

       
    • Patryk
      Patryk
      2008-07-16

      What version of SDCC are you using? There were some changes in _XPAGE handling at startup around version 2.7.0 (current is 2.8.0).
      You have defined __XPAGE, but proper name in C is _XPAGE. Anyway there is no need to define it - default is set as P2. You seem to define it as DPP (highest byte of 24bit DPTR) - but it's for different purposes.
      The DS390/DS400 port of SDCC makes use of extended stack pointer - you may check if it is compatible with ADuC847. Unfortunately other interesting ADuC847 features (like double DPTR, 24bit DPTR, decrementing DPTR) are not supported by SDCC.

       
    • adam
      adam
      2008-07-16

      I have tried with 2.6.1 and 2.8.2, both give the same result.

      I don't see an extended stack compiler switch.  I've just tried it with the extended stack enabled on the aduc847 and it made no difference.

      Sorry __XPAGE was part of my fiddling, it was _XPAGE.  Left to P2 doesn't work either.

       
    • Patryk
      Patryk
      2008-07-16

      Do you got external pullups on P0? Try with the P3: it is not used for XRAM operations and it got internal pullups. If it not helps, then check if ram_fluff[250] will work. Try remove NO_OPT flags - to stick with defaults.

      Another problem, and maybe that's it. You use --stack-auto and --model-large - SDCC lib files must be compiled with same options. They are precompiled for small, medium, large and small-stack-auto, no large-stack-auto - you may need to add some files from SDCC\lib\src\mcs51 to the project (see in your *.map file which lib files are linked, for example crtxinit.rel, crtstart.rel).

      BTW: in _sdcc_external_startup() only CFG84x.0 is changed (set) comparing to power-on defaults, rest of code is needless.

       
    • Patryk
      Patryk
      2008-07-16

      As of extended stack pointer: I mean need to check if Dallas DS390/DS400 extended stack is compatible with ADuC847 extended stack, so -mds390/-mds400 SDCC switches may be used.

       
    • adam
      adam
      2008-07-17

      Sounds like no extended stack is correct for the compiler switches I'm using.

      It continues to fail with optimizations.

      I do have external pullups on port 0.

      I tried removing the --stack-auto switch but this made no difference.

      Currently the following files are linked: crtclear.rel, crtxinit.rel, crtxclear.rel, crtpagesfr.rel, crtstart.rel.

      I understand that I have set a lot of variables to default, this is bitter experience with aduc parts.

      Rather interestingly the failure occurs only when the size of ram_fluff exceed 255.

      I do have the impression the problem is with my use of the aduc part as the simulator says every thing's fine.

      btw: Thanks for helping me try to understand this, it's just too clever for me!

       
      • Patryk
        Patryk
        2008-07-17

        For now forget about extended stack.
        From which directory come these linked files? If you remove --stack-auto switch, they should come from \SDCC\lib\large.

         
        • adam
          adam
          2008-07-17

          Yes, sdcc/share/sdcc/lib/large

           
          • Patryk
            Patryk
            2008-07-17

            Then it may be SDCC bug, but simulator should reveal it. Did you connect anything to "memory" pins - P2, ALE, WR etc? Did you check with 'P3 = global_byte' instead of 'P0 = global_byte'?

             
            • adam
              adam
              2008-07-18

              There are loads on the P2 and P3 as I am using an existing board to develop on.  The part doesn't use P2 on the internal memory accesses.  P0 is working correctly as is the allocation of global_byte as global_byte=3;P0=global_byte; outputs 3 through P0.

              This whole simulator working and chip not working thing is very confusing.

               
              • adam
                adam
                2008-07-18

                OK, I'm a little closer to understanding the problem now:

                The aduc847 movx @Ri,a only uses one register so can only access 256 bytes of XRAM.

                It does have dual data pointers so i _should_ be able to use these to talk to the whole of the XRAM.

                If I write startup code that puts a fixed value into l_XINIT bytes of XRAM starting from s_XISEG then the program comes up with  that constant in memory.  However if I try copying l_XINIT bytes from s_XINIT in code memory to s_XISEG in XRAM then it doesn't work.  Following is code that should handle 256 bytes of memory initialization:

                    mov    r1,#l_XINIT
                    mov _DPS,#0x00
                    mov    dptr,#s_XISEG        ; main DPTR for xdata
                    mov    _DPS,#0x55            ; select shadow DTPR
                    mov    dptr,#s_XINIT        ; shadow DPTR for code
                00001$:    clr    a
                    movc a,@a+dptr            ; DPTRs -> ACC : post inc DPTRs, switch to DPTRm
                    ;mov a,#0x03
                    movx @dptr,a            ; ACC -> XRAM  : post inc DPTRm, switch to DPTRs
                    djnz r1,00001$

                Any idea why it's not copying out of code memory?

                Thanks

                Adam

                 
                • adam
                  adam
                  2008-07-18

                  > Any idea why it's not copying out of code memory?
                  Because I'm a buffoon.  I didn't set the -g option when I assembled the startup code.

                  You know I think I have this figured out; I'll have a closer look and post a follow up.

                  Thanks

                  Adam

                   
                • Patryk
                  Patryk
                  2008-07-18

                  Did you look into SDCC documentation regarding startup code?
                  3.11.1 MCS51/DS390 Startup Code
                  Library files sources (crtxinit.asm, crtxclear.asm etc.) are in \SDCC\lib\src\mcs51.
                  With double DPTR you can later optimize it the way you did, but for now let it just work.
                  Check in your *.map file if s_XISEG/l_XISEG/s_XSEG/l_XSEG got expecting values: 1000(&global_byte)/1(sizeof(global_byte))/0(&ram_fluff[0])/1000(sizeof(ram_fluff)).
                  Do you see any bug in crtxinit.asm? Can you debug it on-chip? Analog Devices gives a debugger for Windows (through serial port, same as for programming), but only their assembler is supported. I don't remember if it supports also binary (hex) file.

                   
                  • Maarten Brock
                    Maarten Brock
                    2008-07-18

                    If crtpagesfr.rel is linked in then you have not declared _XPAGE correctly, because that should override this inclusion. But a quick look in the datasheet reveals there is no sfr to select the upper half of the address used for MOVX @Ri instructions. So you need to adapt the xdata initialization to use the dual DPTR. The crtxinit.asm already contains a pre-cooked version which only needs to be enabled and re-assembled, but it may need tweaking.

                     
                    • Patryk
                      Patryk
                      2008-07-18

                      Adam declared __XPAGE instead of _XPAGE, so default _XPAGE is P2. I looked in datasheet and it is not clear regarding MOVX @Ri and P2 when accessing internal XRAM. I suppose it works like in standard: MSB(xaddr) should be emitted by P2. Maybe external circuits at P2 are causing disturb? Anyway flip-flop's output should be used for address, not port state, but who knows. Using DPTR resolves problem and spares P2.
                      Adam already used dual DPTR, in a better way than pre-cooked version: uses also autoincrement and autotoggle features of ADuC847's DPTR. But he may need help to integrate it with his project.

                       
              • Patryk
                Patryk
                2008-07-18

                "The part doesn't use P2 on the internal memory accesses."
                I know, but wrong code generated by compiler may depend on port states, for example wrong setting of P2 (_XPAGE) may result in external access.