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

Surprising Gotcha when writing to OSCTUNE register

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



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Surprising Gotcha when writing to OSCTUNE register
PostPosted: Thu Mar 23, 2017 3:32 pm     Reply with quote

Here is my code (for a PIC 16F1825, PCM compilier):

Code:
OSCTUNE = (ramOSCTUNE>>2);      //..high order bits don't matter.  Only the lower-order 6 bits.


where ramOSCTUNE is a byte that has been previously adjusted in the signed range of 0x80 (-128) to 0x7f (+127). But the PIC was not behaving as expected whenever the negative portion of this range was being used. A look at the object code showed why:

Code:
0036:  RRF    23,W   (grabbing ramOSCTUNE and shifting one bit right)
0037:  MOVLB  01    (switch to bank to access OSCTUNE)
0038:  MOVWF  18  (save intermediate result to OSCTUNE) (what the??)
0039:  RRF    18,F   (perform remaining shift OSCTUNE in place)
003A:  MOVLW  3F
003B:  ANDWF  18,F   (unnecessary masking of bits 7 and 6)


It is clear what happened. The compiler assumed that the target of the operation was readable and writable in all 8 bits. But OSCTUNE is not. The high two bits are unimplemented and always read back as 0. So using OSCTUNE to hold intermediate results is not valid. Of course the solution was easy:

Code:
{
   unsigned int temp;
   temp = ramOSCTUNE>>2;
   OSCTUNE = temp;
}


which compiles to the very nice
Code:
0036:  RRF    23,W   (Grab and shift ramOSCTUNE)
0037:  MOVWF  34          (store in temp)
0038:  RRF    34,F          (rotate temp in place)
0039:  MOVLW  3F
003A:  ANDWF  34,F       (masking, still unnecessary for my use)
003B:  MOVF   34,W       (grab final temp)
003C:  MOVLB  01          (switch bank to access OSCTUNE)
003D:  MOVWF  18        (clean store to OSCTUNE)

_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Fri Mar 24, 2017 12:15 pm     Reply with quote

Not actually surprising, but a nice potential problem when writing to any SFR.

If you do maths 'feeding' a register, the compiler may well use the register as 'temporary' for the maths. It doesn't know there is anything 'special' about the register. In this case it is 7bit, but even worse, bits may turn on other things. Lesson is that except for basic things like &, which can be used to mask individual bits, values should be prepared before trying to feed them to a SFR....
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