#1460 Weird oscillator problem with crt code

closed-fixed
nobody
5
2008-05-29
2008-05-15
No

I'm having an almost impossible problem, fully reproducible with two separate pic18f2685.

The problem is experienced with this simple code:

#include <pic18fregs.h>

code char at __CONFIG1H conf1 = _OSC_IRCIO7_1H;
code char at __CONFIG3H conf2 = _MCLRE_ON_3H & _PBADEN_OFF_3H;
code char at __CONFIG2H conf3 = _WDT_OFF_2H; // DIsable WDT

void main()
{
OSCCON = 0x70;
while(1);
}

I'm selecting the internal oscillator with clock output on RC7. The "OSCCON" thing sets the internal oscillator to 8MHz operation. I'm monitoring the clock output IO pin with an oscilloscope.

Compiling the file with (note the --no-crt):

$ sdcc main.c -mpic16 -p18f2685 --optimize-cmp --optimize-df --no-crt

... the clock out is immediately set to 8MHz, and is kept there.

On the other hand when compiling without the "--no-crt" option, the clock starts at 1MHz, then you can see it switching to 8MHz (proving that the main function is entered), but then it switches to about 833Hz !! (hertz, no typo!).

I've looked at the generated assembly code, and apparently this is impossible to happen. I'm lost here..

I can provide the generated assembly code for both cases (with and without --no-crt).

Discussion

  • SeventhGuardian

    SeventhGuardian - 2008-05-15

    Logged In: YES
    user_id=1067152
    Originator: YES

    After a bit more digging I found out that the using --no-crt doesn't generate a proper reset vector:

    00002a: ef17 goto 0x2e
    00002c: f000
    00002e: ec1b call 0x36, 0
    000030: f000
    000032: ef19 goto 0x32
    000034: f000
    000036: 0e70 movlw 0x70
    000038: 6ed3 movwf 0xd3, 0
    00003a: ef1d goto 0x3a
    00003c: f000
    00003e: 0012 return 0

    So hopefuly the reset vector would work as a "nop", and the next instructions would be called. Strangely or not, when I add a delay function above the main function then the main doesn't get executed, and I end up with a 1MHz (default) clock.

    On the other hand, manually forcing the use of crt0 generates working code:
    $ sdcc main.c -mpic16 -p18f2685 --use-crt=/usr/share/sdcc/lib/pic16/crt0.o

    This makes me believe that the default crt is one of the "more complex" ones, and that the default crt is doing something nasty to the mcu.

     
  • SeventhGuardian

    SeventhGuardian - 2008-05-15

    Logged In: YES
    user_id=1067152
    Originator: YES

    Ok, now I am confused. I've went back to the start, but now I can't reproduce the problem. I'm not sure why, but I'll investigate. In the meantime I'll close the bug..

     
  • SeventhGuardian

    SeventhGuardian - 2008-05-15
    • status: open --> closed-works-for-me
     
  • SeventhGuardian

    SeventhGuardian - 2008-05-16
    • status: closed-works-for-me --> open
     
  • SeventhGuardian

    SeventhGuardian - 2008-05-16

    Logged In: YES
    user_id=1067152
    Originator: YES

    I've retested it today, and the problem reappeared. This time using crt0.o made it work, while using crt0i.o made the problem appear.

    I'm getting convinced that this may be a hardware problem mixed with a crt problem. Does crt0i.o do any hardware test that may explain this?

     
  • Raphael Neider

    Raphael Neider - 2008-05-16

    Logged In: YES
    user_id=1115835
    Originator: NO

    The sources for the CRTs reside in device/lib/pic16/startup/crt0*.c in the source package of SDCC. The difference between the two is that crt0i initializes the C-initialized global and/or static variables, whereas crt0 does not (crt0iz would additionally set all other memory locations to zero after reset and is the preferred one). All CRTs write to the (SFR) register 0xA6 to set up potential flash memory access; this *should not* harm non-flash devices...
    During initialization, the crt0i/crt0iz access program memory, evaluate a linker-defined structure there and copy the initializer values from program memory to RAM using TBLPTR, TABLAT, TBLRD*+, FSR0, and registers 0x00--0x09 in the access bank. No HW tests are performed.

    Sorry, but I cannot reproduce the problem. For the snippet above, crt0 would be fine, all others should work as well, though. --no-crt requires implementing an __interrupt 0-handler (RESET vector) in your code and is not recommended for common projects.

    Good luck,
    Raphael

     
  • Raphael Neider

    Raphael Neider - 2008-05-19

    Logged In: YES
    user_id=1115835
    Originator: NO

    Tracked down to a hardware problem off the list.

     
  • Raphael Neider

    Raphael Neider - 2008-05-19
    • milestone: --> 100455
    • status: open --> closed-invalid
     
  • Raphael Neider

    Raphael Neider - 2008-05-19

    Logged In: YES
    user_id=1115835
    Originator: NO

    Sorry, this one is not resolved yet: a similar report on sdcc-user confused me.

    @SeventhGuardian: Any news?

     
  • Raphael Neider

    Raphael Neider - 2008-05-19
    • milestone: 100455 -->
    • status: closed-invalid --> open
     
  • SeventhGuardian

    SeventhGuardian - 2008-05-20

    Logged In: YES
    user_id=1067152
    Originator: YES

    I've managed to "workaround" this by using crt0.o, as I need to finish the project in a week. After that I should investigate further..

    Strangely I'm facing really weird problems with this micro. Arrays don't work (you can write to them, but you read back garbage), and the same thing happens with local variables. With another code, sometimes the timer interrupts get called for a couple of seconds but then stop, and reseting the micro doesn't make it work again. I have to power cycle it (probably clearing some faulty registers) for it to work again for some seconds. Looking at the assembly output makes me believe that it _should_ work, so I'm really pulling my hair out here .. faulty hardware is becoming a strong possibility.

     
  • Raphael Neider

    Raphael Neider - 2008-05-20

    Logged In: YES
    user_id=1115835
    Originator: NO

    I am relaying a post from Anton Strobl on the sdcc-devel list because you might not read it:

    Perhaps it is a hardware problem:

    The MCLR config is defined as:

    _MCLRE_ON_3H

    so the MCLR pin needs 3 to 4 components (see pic18f2685 datasheet 39761b.pdf page 43) for example:

    D = 1n4148 or similar
    R = 10k
    C = 0.1uF
    R1 = 1k

    I have had also weird oscillator startup and stability problems without this compents using PIC18f2685. Also don't forget to connect as near as possible a 0.1uF capacitor from Vdd to Vss.

    Strobl Anton

    mailto:a.strobl AT aws-it DOT at

     
  • SeventhGuardian

    SeventhGuardian - 2008-05-20

    Logged In: YES
    user_id=1067152
    Originator: YES

    Thanks for relaying it, I'm not (yet) subscribed to it. I will now ;)

    I have a slightly different circuit, more suitable to ICSP. I had omitted the reset capacitor though (shame on me..), but including it didn't solve the problem. As for supply bypassing, it is done correctly..

    I'll try changing the IC for a fresh one asap and report back. Thanks for your help!

     
  • SeventhGuardian

    SeventhGuardian - 2008-05-20

    Logged In: YES
    user_id=1067152
    Originator: YES

    A fresh pic didn't help.

    I've copied the crt0i.c file to the project tree and then compiled with "--no-crt" and included crt0i.o in the object file list. So I'm basically locally building the crt code.

    So I've started tracking down the function that causes the problem. In _startup, commenting out _do_cinit(); solves the problem, while uncommenting it brings it back.

    So inside the _do_cinit() function I've put a "bra done" in several places trying to isolate what triggers the problem. First step was just before the "do copy loop" comment, and it solved the problem. Next I've put it right after the done_copying label, and it solved it. The next step was to put it right after the "do_next" label, and it still solved it.

    So the first iteration doesn't trigger the problem. My guess is that one of the iterations is messing something up. Any further tests advised?

    Thanks

     
  • Raphael Neider

    Raphael Neider - 2008-05-25

    Logged In: YES
    user_id=1115835
    Originator: NO

    I just looked at the linker script to see whether there are any errors but could not spot any (at least in the latest gputils svn revision).
    You might generate a .map file (sdcc -Wl,-m [more options] or gplink -m if I recall correctly) and inspect it to see if any symbols (especially initialized data) have been located into "weird" places (SFRs, configuration space, ...) causing the device to predictably malfunction after/during initialization.
    You could also analyze the initialization structure "cinit" created by gputils and try to uncover errors in there; unfortunately I am not aware of any easy way to dump it: _cinit is located in the .cinit section in code memory, its format can be derived from crt0i.c. You could parse it by hand to see if all addresses (from, to) and sizes are OK...
    You could also send the failing .hex file to me so that I can take a look at the initialization, if you like.

    Another thing to check: Are you compiling with extended instruction set extensions enabled (sdcc -y or --extended)? This would be bound to fail at runtime as the compiler is not correctly setting up FSR2 for indirect memory accesses (literal offset addressing).

    Good luck,
    Raphael

     
  • SeventhGuardian

    SeventhGuardian - 2008-05-26

    The generated hex file

     
  • SeventhGuardian

    SeventhGuardian - 2008-05-26

    Logged In: YES
    user_id=1067152
    Originator: YES

    I'm not using extended mode (although I've tried it and it failed ;).

    I'm attaching both the .hex and .map files. I'll try to follow your suggestions asap, thanks!
    File Added: main.hex

     
  • SeventhGuardian

    SeventhGuardian - 2008-05-26

    Logged In: YES
    user_id=1067152
    Originator: YES

    File Added: main.map

     
  • SeventhGuardian

    SeventhGuardian - 2008-05-26

    The generated map file

     
  • SeventhGuardian

    SeventhGuardian - 2008-05-26

    Logged In: YES
    user_id=1067152
    Originator: YES

    If I understand the .map file correctly, there is only one single byte of initialized data, and that is the ___uflags at 0x000060.

    From the datasheet, this address may refer to the SFR at 0xF60 when a=1.

    On the other hand, if I understood correctly, only having a single 1 byte long idata segment should mean that the cinit loop should only execute once. But apparently it is not, hence the long delay before main is executed. Is it possible that the function is looping the entire memory for some weird reason?

     
  • Raphael Neider

    Raphael Neider - 2008-05-26

    Logged In: YES
    user_id=1115835
    Originator: NO

    Three more ideas:

    (1) There are bugs in crt0i and crt0iz, and fixes in the svn.
    The only critical fix concerns a spurious write to 0xf7e, which should not be critical at all...
    The other fixes avoid prematurely aborting initialization, not endless loops.
    But then, who knows? You might give them a try (crts available e.g. via svn or the webfrontend).

    (2) code char at __CONFIG4L conf4l = 0x8F;
    ... to make sure XINST is off. Are other configs required?!?

    (3) According to the datasheet the CLKO function applies to RA6, not RC7 (somewhat contradicting your having success with --no-crt and crt0.o).

    Address 0x0060 is solely accessed via FSR0 during initialization, which does not (should not?) get mapped to 0xF60.
    The simulator does loop forever, but only after having reached your while(1) perfectly.

    As a sidenote, using crt0.o for this project is probably the right choice (given that there are in fact no initialized variables in RAM according to the cinit struct and the simulator).

    I fear not to be of any further help, might still be a configuration or testbed error???

    Best of luck to you,
    Raphael

     
  • SeventhGuardian

    SeventhGuardian - 2008-05-29
    • status: open --> closed-fixed
     
  • SeventhGuardian

    SeventhGuardian - 2008-05-29

    Logged In: YES
    user_id=1067152
    Originator: YES

    Hello!

    (1) Latest svn code makes it work!!
    (2) This seems to make no difference.
    (3) This was an unfortunate typo..sorry.. I am measuring the right pin :)

    I've tested today in a much less noisy environment, but without a scope. I've put a led on the clock out pin (RA6 :P) and I get different behaviors for the code compiled with 2.8.0 and 2.8.1. I'm powering the target with pickit2.

    * For svn 2.8.1, I issued several resets and the led changed immediately from "off" to "half-bright". This means that it immediately switched to the correct clock.

    * Then I've tried with the 2.8.0 code. I've issued several resets, and the led started "full-bright", then "half-bright" and then "full-bright" again. So it seems to exhibit the clock problem. If the resets are really close together, then the led goes "full-bright" and then "half-bright", staying there (the correct behavior). In either case, the transition to "half-bright" takes a lot of time..

    So it seems to be a hardware problem, and the svn code doesn't trigger it anymore. Thanks for your help! :)

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks