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
collection of C snippets and assembler listing to show basic problem
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
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;
}
//---