basically loop for (val=0; val<16; val++) and output to pin (led) like this:
PORTC = val + 2; results in blinking led (on RC0) while
PORTC = add2(val) ; results in dark led
NOTE: this time the add2 seems to result in correct code, but for
some reason add2(val) returns 0,2,4,6,8 ...
SPECULATION: the subroutine call gets the stack frame wrong so
it ends up adding to the previous result somehow?
compiled with --use-non-free -mpic16 -p18f26j50
--- bug02_good.asm 2011-01-18 02:07:28.000000000 +0100
+++ bug02_bad.asm 2011-01-18 02:07:44.000000000 +0100
@@ -472,10 +472,12 @@ _00117_DS_:
MOVLW 0x10
SUBWF r0x00, W
BC _00121_DS_
-; .line 39; bug02.c PORTC = val + 2;
- MOVLW 0x02
- ADDWF r0x00, W
+; .line 41; bug02.c PORTC = add2(val);
+ MOVF r0x00, W
+ MOVWF POSTDEC1
+ CALL _add2
MOVWF _PORTC
+ INCF FSR1L, F
; .line 43; bug02.c for (i=0; i<250; i++)
CLRF r0x01
_add2:
; .line 25; bug02.c unsigned char add2(unsigned char val) {
MOVFF FSR2L, POSTDEC1
MOVFF FSR1L, FSR2L
MOVFF r0x00, POSTDEC1
MOVLW 0x02
MOVFF PLUSW2, r0x00
; .line 26; bug02.c return val + 2;
INCF r0x00, F
INCF r0x00, F
MOVF r0x00, W
MOVFF PREINC1, r0x00
MOVFF PREINC1, FSR2L
RETURN
example source code
Can you try to use LATC instead of PORTC?
PORTC reads the actual value (voltage) on the pin and due to capacitance, changes are not made instantly.
LATC is a latch register so you can know what should be on the port even if actual voltage hasn't changed yet.
Please let us know if you try this.
I think that I misunderstood your explanation and LATx/PORTx is not the problem.
Anyway, I think that is a good practice to write always to LATx instead of PORTx.
Tried with sdcc --use-non-free -mpic16 -p18f2550 bug02.c (18f2550 instead of 18f26j50 because I have simulator for 18f2550) and works with PORTC = val + 2 and also with PORTC = add2(val). Both make RC0 blink.
My version is 3.0.0, which one are you using?
Can you test with another processors and tell us what happens?