|
|
View previous topic :: View next topic |
Author |
Message |
mjdale2003
Joined: 10 Oct 2004 Posts: 21 Location: UK
|
With #OPT compress on 18f27j13 int16 shift problem |
Posted: Mon Jan 25, 2016 5:54 am |
|
|
Hi, I seem to be having a problem with shifting a 16bit integer when using the #opt compress switch
I am trying to store a 16bit integer in to internal flash.
i have tried both |= (1<<val) method and bit_set()
compiler version
PCH 5.051
the output to the function is
here is the function
Code: |
#OPT compress
void save_16_eeprom(unsigned int16 val){
unsigned int16 dat_val;
value = read_ee16(active_output_cam);
01198: MOVFF AA8,C68
0119C: RCALL 0E68
0119E: MOVFF 02,C67
011A2: MOVFF 01,C66
// use bit_set as optimization
// changes this to a char shift
// for some reason even though
// printf shows val as 8 - 16 ???
//dat_val |= ((unsigned int16)1<<val);
bit_set(dat_val, val);
011A6: CLRF 03
011A8: MOVLW 01
011AA: MOVWF 02
011AC: MOVLB C
011AE: MOVF x64,W
011B0: MOVWF 00
011B2: BZ 11BE
011B4: BCF FD8.0
011B6: RLCF 02,F
011B8: RLCF 03,F
011BA: DECFSZ 00,F
011BC: BRA 11B4
011BE: MOVF 02,W
011C0: IORWF x66,F
011C2: MOVF 03,W
011C4: IORWF x67,F
write_ee16(active_output_cam, dat_val);
011C6: MOVFF AA8,C84
011CA: MOVFF C67,C86
011CE: MOVFF C66,C85
011D2: MOVLB 0
011D4: RCALL 0ECC
printf(TxData2, "save %lu %04X \n\r", val, dat_val); TXIE = 1;
011D6: MOVLW AE
011D8: MOVWF FF6
011DA: MOVLW BE
011DC: MOVWF FF7
011DE: MOVLW 00
011E0: MOVWF FF8
011E2: MOVLW 05
011E4: RCALL 10C8
011E6: MOVLW 10
011E8: MOVWF FE9
011EA: MOVFF C65,C69
011EE: MOVFF C64,C68
011F2: RCALL 10D2
011F4: MOVLW 20
011F6: MOVLB C
011F8: RCALL 122C
011FA: MOVLW 02
011FC: MOVLB C
011FE: MOVWF x68
01200: MOVLW 30
01202: RCALL 122C
01204: MOVLB C
01206: DECFSZ x68,F
01208: BRA 1200
0120A: MOVFF C66,C68
0120E: MOVLW 37
01210: MOVWF x69
01212: MOVLB 0
01214: RCALL 0F46
01216: MOVLW BB
01218: MOVWF FF6
0121A: MOVLW BE
0121C: MOVWF FF7
0121E: MOVLW 00
01220: MOVWF FF8
01222: MOVLW 03
01224: RCALL 10C8
01226: BSF F9D.4
*
0122C: MOVWF x73
0122E: MOVLB 0
01230: RCALL 0C66
01232: RETURN 0
update_eeprom();
01228: RCALL 1010
0122A: RETURN 0
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Mon Jan 25, 2016 7:30 am |
|
|
I don't use that PIC but you should post a small,compilable program that shows us the problem. Most C guys don't know ASM. Could be a 'casting' problem or something 'before' your function.
Also post test data before and after as well as expected results
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Jan 25, 2016 8:47 am |
|
|
Bit set has to do a rotation. The processor doesn't have a variable based bit_set function, so while a bit set on a fixed bit is efficient, a bit_set using a variable has to be done by rotating a mask.
I can't actually work out what you are trying to do?. If you are rotating a value to get bytes from it, then use the make8 function. Far more efficient than any rotation based method, since the compiler can just do a byte fetch. |
|
|
mjdale2003
Joined: 10 Oct 2004 Posts: 21 Location: UK
|
|
Posted: Mon Jan 25, 2016 9:45 am |
|
|
hi and thanks for the fast response, i have stripped down the function to a simple routine that assigns a value to the top byte prints, sets a bit then prints again, there is no reason this should fail surely
Code: |
void save_pre_eeprom(unsigned int16 pre){
unsigned int16 value;
if(pre <=16){
value = 0xAA00;
printf(TxData2, "save %u %lu %04X \n\r", active_output, pre, value);
bit_set(value, 8);
printf(TxData2, "save %u %lu %04X \n\r", active_output, pre, value);
}
}
|
and the output remains as
save 0 2 0000
save 0 2 0000
call it from main the "pre" value changes if i use another value but the "value" value is always 0000 even if i change it to a int32
the .lst file seems to set the bit but it is never displayed, could it be the printf function becoming corrupt after the #compress part of the compilation.
Code: |
.................... void save_pre_eeprom(unsigned int16 pre){
.................... unsigned int16 value;
....................
.................... if(pre <=16){
*
01316: MOVLB C
01318: MOVF xE5,F
0131A: BTFSS FD8.2
0131C: BRA 137A
0131E: MOVF xE4,W
01320: SUBLW 10
01322: BTFSS FD8.0
01324: BRA 137A
....................
.................... value = 0xAA00;
01326: MOVLW AA
01328: MOVWF xE7
0132A: CLRF xE6
....................
.................... printf(TxData2, "save %u %lu %04X \n\r", active_output_cam, pre, value);
0132C: MOVLW DA
0132E: MOVWF FF6
01330: MOVLW C0
01332: MOVWF FF7
01334: MOVLW 00
01336: RCALL 137E
01338: MOVLW 30
0133A: RCALL 1246
0133C: MOVLB C
0133E: DECFSZ xE8,F
01340: BRA 1338
01342: RCALL 13AC
01344: MOVLW EA
01346: MOVWF FF6
01348: MOVLW C0
0134A: MOVWF FF7
0134C: MOVLW 00
0134E: RCALL 13B8
*
0137E: MOVWF FF8
01380: MOVLW 05
01382: RCALL 1024
01384: MOVFF B28,D09
01388: MOVLW 1B
0138A: RCALL 102E
0138C: RCALL 0EC0
0138E: MOVLW 20
01390: RCALL 1246
01392: MOVLW 10
01394: MOVWF FE9
01396: MOVFF CE5,CE9
0139A: MOVFF CE4,CE8
0139E: RCALL 1250
013A0: MOVLW 20
013A2: RCALL 1246
013A4: MOVLW 02
013A6: MOVLB C
013A8: MOVWF xE8
013AA: RETURN 0
013AC: MOVFF CE6,D09
013B0: MOVLW 37
013B2: RCALL 102E
013B4: RCALL 0F34
013B6: RETURN 0
013B8: MOVWF FF8
013BA: MOVLW 03
013BC: RCALL 1024
013BE: RETURN 0
....................
.................... bit_set(value, 8);
01350: MOVLB C
01352: BSF xE7.0
....................
.................... printf(TxData2, "save %u %lu %04X \n\r", active_output_cam, pre, value);
01354: MOVLW EE
01356: MOVWF FF6
01358: MOVLW C0
0135A: MOVWF FF7
0135C: MOVLW 00
0135E: RCALL 137E
01360: MOVLW 30
01362: RCALL 1246
01364: MOVLB C
01366: DECFSZ xE8,F
01368: BRA 1360
0136A: RCALL 13AC
0136C: MOVLW FE
0136E: MOVWF FF6
01370: MOVLW C0
01372: MOVWF FF7
01374: MOVLW 00
01376: RCALL 13B8
01378: MOVLB C
....................
.................... }
0137A: MOVLB 0
0137C: RETURN 0
.................... }
|
|
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Mon Jan 25, 2016 10:45 am |
|
|
Its nothing to do with shifting or optimisation. Check your format specifiers:
From the manual:
Quote: |
x Hex int (lower case)
X Hex int (upper case)
Lx Hex long int (lower case)
LX Hex long int (upper case)
|
To format your int16, you need %LX. What your format is doing is formatting the lower byte and padding it to four characters with zeros: the upper byte is always going to be 00. |
|
|
mjdale2003
Joined: 10 Oct 2004 Posts: 21 Location: UK
|
|
Posted: Mon Jan 25, 2016 11:27 am |
|
|
Well spotted thank you, silly me :/ |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|