CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

With #OPT compress on 18f27j13 int16 shift problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
mjdale2003



Joined: 10 Oct 2004
Posts: 21
Location: UK

View user's profile Send private message Yahoo Messenger MSN Messenger

With #OPT compress on 18f27j13 int16 shift problem
PostPosted: Mon Jan 25, 2016 5:54 am     Reply with quote

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
Quote:
save 8 00FF


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: 9162
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Jan 25, 2016 7:30 am     Reply with quote

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: 19329

View user's profile Send private message

PostPosted: Mon Jan 25, 2016 8:47 am     Reply with quote

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

View user's profile Send private message Yahoo Messenger MSN Messenger

PostPosted: Mon Jan 25, 2016 9:45 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jan 25, 2016 10:45 am     Reply with quote

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

View user's profile Send private message Yahoo Messenger MSN Messenger

PostPosted: Mon Jan 25, 2016 11:27 am     Reply with quote

Well spotted thank you, silly me :/
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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