Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#1582 sdcc 2.9 fails to do banksel within interrupt on pic18f46j50

open
nobody
PIC16
5
2013-07-16
2009-11-30
jwinfphase
No

at least thats what I think is happening

i can set global variables but the interrupt
handler reads them as zero

if I force the interrupt handler to write to those
global variables first with good values the thing works
so obviously the global scope and the interrupt
hanlder are not accessing the same memory.

I collected the snippets together in the attachment.
I can prepare a small isolated testcase if you
think the bug can be fixed.

the code worked previously on a pic18f4550 SDCC 2.6.1
I cant go back to this because I need to use the 46J50

SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.9.4 #5564 (Nov 4 2009) (UNIX)
gputils-0.13.7

/root/c_and_c++_compilers_and_cint/sdcc/bin/sdcc -o bootloader_NOT.hex --optimize-goto --denable-peeps --obanksel=9 --opt-code-size --optimize-cmp --optimize-df --fstack --use-crt=crt0.o -Wl-s18f46j50.lkr,-m -mpic16 -p18f46j50 -llibio18f46j50.lib -llibc18f.lib application_iface.o boot_main.o boot_iface.o usb.o usb_descriptors.o ep0.o ep1.o ep2.o flash.o config.o interrupt_iface.o

john.wood@infinity-phase.com

Discussion

  • jwinfphase
    jwinfphase
    2009-11-30

    collection of C snippets and assembler listing to show basic problem

     
    Attachments
  • Raphael Neider
    Raphael Neider
    2009-11-30

    Hmmm, the code snipped you posted looks ok: You do not need any BANKSEL when using MOVFF to access memory -- MOVFF employs full 12-bit addresses per operand. Additionally, you need no BANKSEL when accessing registers from the access bank/SFR area (such as r0x00 or _TMR0H). All other memory accesses are (on first glance) correctly prefixed with a proper BANKSEL.

    I noticed a reference to a volatile read of _TMR0H in your assembler listing, although TMR0H is never read in the C code you posted. Is there just some C code missing or did the compiler go creative?

    Could you find out the location of the incorrectly accessed globals (TMR0x_reload_holder), e.g., from the .lst file or the .map file? Can you verify that the main program can always access (i.e., read) said globals correctly? Maybe they are overlaid with USB buffer memory?!?

    Best regards

    Raphael

     
  • jwinfphase
    jwinfphase
    2009-11-30

    thanks for the help. I am new to PIC assembler.

    digging around some more the problem is bizarrely related to the
    unsigned int being passed to the function call in C which sets the global variables.
    So in the example below, the new function which takes two chars
    works.
    The unsigned int function fails - it gets zero no matter what is passed.
    Previously this function worked correctly with the 4550 and
    looking at the assembly for both the caller and the functions sdcc
    has produced the same code for 4550 and 46J50.
    It is baffling...

    volatile unsigned char TMR0H_reload_holder=0; //- because the interrupt handler has to reload the counter
    volatile unsigned char TMR0L_reload_holder=0;

    // !!! THIS ONE DOESNT RUN ON A pic18f46J50 !!!!
    // see main c file for interrupt handler
    // Timer increments, and also the interrupt handler has to reload the counter
    void init_timer0_for_tslot_interrupts(unsigned int timerreload ) {

    TMR0H_reload_holder= timerreload >>8;
    TMR0L_reload_holder = timerreload & 0xFF;

    // Reset the Timer0 value
    TMR0H = TMR0H_reload_holder;
    TMR0L = TMR0L_reload_holder;

    // Configure the Timer0 and unmask ITs
    T0CON = 0x88; // TMR0ON, 16bits, CLKO, No prescaler
    INTCONbits.TMR0IE = 1;

    }

    //!!! BUT THIS ONE DOES RUN....
    // see main c file for interrupt handler
    // Timer increments, and also the interrupt handler has to reload the counter
    void init_timer0_for_tslot_interrupts_2bytes(unsigned char timerreloadH, unsigned char timerreloadL ) {

    TMR0H_reload_holder= timerreloadH;
    TMR0L_reload_holder = timerreloadL;

    // Reset the Timer0 value
    TMR0H = TMR0H_reload_holder;
    TMR0L = TMR0L_reload_holder;

    // Configure the Timer0 and unmask ITs
    T0CON = 0x88; // TMR0ON, 16bits, CLKO, No prescaler
    INTCONbits.TMR0IE = 1;

    }
    //---

     
    • Category: --> PIC16