Author Topic: What Happens When Writing to a 'Readable Bit'?  (Read 2391 times)

0 Members and 1 Guest are viewing this topic.

Offline SparkFlyTopic starter

  • Regular Contributor
  • *
  • Posts: 55
  • Country: gb
What Happens When Writing to a 'Readable Bit'?
« on: September 07, 2021, 03:48:33 pm »
I am new to programming microcontrollers, and have recently began a project where I would like to use the internal oscillator of a PIC16F819. Until now, I have been setting registers in the following way:

OSCCON = 0b01110100

However, the datasheet states that bit 2 of OSCCON is a only a readable bit - not writeable. What happens to this bit when I attempt to write to it, as in this case, with a '1'? What consequences might using this method have?

I've tried investigating, but the closest I can find is from this page here: http://www.learningaboutelectronics.com/Articles/How-to-set-up-the-oscillator-for-a-PIC-microcontroller-in-C.php - where they say that writing a '1' "makes the signal stable". I think this is incorrect, as my interpretation of the datasheet is that this bit is only written to by the microcontroller, to indicate the stability of the oscillator.

For convenience, here is the datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/39598F.pdf OSCCON register is described on page 38.
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 13413
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #1 on: September 07, 2021, 04:03:41 pm »
If a bit is indicated as 'read only' in the data sheet, writes to it will not change its value.  Consequences: None.  However the consequence of writing code that *attempts* to write a specific value to a read-only bit is to confuse yourself and anyone who reads your code!
« Last Edit: September 07, 2021, 04:14:20 pm by Ian.M »
 
The following users thanked this post: SparkFly

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3634
  • Country: it
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #2 on: September 07, 2021, 04:04:17 pm »
I am new to programming microcontrollers, and have recently began a project where I would like to use the internal oscillator of a PIC16F819. Until now, I have been setting registers in the following way:

OSCCON = 0b01110100

However, the datasheet states that bit 2 of OSCCON is a only a readable bit - not writeable. What happens to this bit when I attempt to write to it, as in this case, with a '1'? What consequences might using this method have?

I've tried investigating, but the closest I can find is from this page here: http://www.learningaboutelectronics.com/Articles/How-to-set-up-the-oscillator-for-a-PIC-microcontroller-in-C.php - where they say that writing a '1' "makes the signal stable". I think this is incorrect, as my interpretation of the datasheet is that this bit is only written to by the microcontroller, to indicate the stability of the oscillator.

For convenience, here is the datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/39598F.pdf OSCCON register is described on page 38.

Contrary to those people at learningaboutelectronics :palm: you understood it correctly. The bit can only be read (and in this case is set by the hardware to signal that the oscillator is stable)
Writing to it has no effect.

Note that according to microchip datasheets a bit in the hardware register can be
R - Readable*
W - Writable
HS/HC/HSC - Set/Cleared/Set and cleared by hardware
C - Clearable only
S - Settable only
U - Undefined (discard the value, with a catch**)
or a combination of the above, like R/HS/C-0 means that it's readable, can be set by hardware and you can only clear it. Its value at POR and other resets is 0

*Ecxeption: the new UART peripheral has the buffer full/overflown bit that can be read and will indicate the status, if written to 0 there is no effect, if written to 1 clear the fifo and read back 0. so much fun when changing other bits of UxFIFO using RMW operations
**Exception: There may be undefined/reserved bits in some peripheral and in configuration words that MUST be set to either zero or one at all times. You need not to know what they do (usually the debug flag, also other undocumented stuff) but follow what the datasheet says
 
The following users thanked this post: SparkFly

Offline SparkFlyTopic starter

  • Regular Contributor
  • *
  • Posts: 55
  • Country: gb
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #3 on: September 07, 2021, 04:25:24 pm »
Thanks both.

What would be a better way of setting registers, to improve the readability of the code?
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3328
  • Country: ca
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #4 on: September 07, 2021, 04:39:38 pm »
Until now, I have been setting registers in the following way:

OSCCON = 0b01110100

However, the datasheet states that bit 2 of OSCCON is a only a readable bit - not writeable. What happens to this bit when I attempt to write to it, as in this case, with a '1'? What consequences might using this method have?

Regardless of the consequences (which are none for read-only bits), you cannot avoid writing the bit. Every time you write to a register, all 8 bits are written, even if you write with bcf/bsf instruction.
 
The following users thanked this post: Ian.M, SparkFly

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 13413
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #5 on: September 07, 2021, 04:56:21 pm »
You are loading a register with a 'magic' number.  Nothing you can do can improve its readability, as one needs to refer to the datasheet anyway to understand it.  Quoting an extract of the datasheet in a comment only helps if you get it right, and if there's a problem, can be a great waste of time if you made a typo!

However if you wish to sacrifice readability for maintainability, you can use the SFR bitfield macros in the device specific header file.

e.g. here's the macros for OSCCON from pic16F819.h for an older version of XC8 than ypu are probably using.
Code: [Select]
// bitfield macros
#define _OSCCON_IOFS_POSN                                   0x2
#define _OSCCON_IOFS_POSITION                               0x2
#define _OSCCON_IOFS_SIZE                                   0x1
#define _OSCCON_IOFS_LENGTH                                 0x1
#define _OSCCON_IOFS_MASK                                   0x4
#define _OSCCON_IRCF_POSN                                   0x4
#define _OSCCON_IRCF_POSITION                               0x4
#define _OSCCON_IRCF_SIZE                                   0x3
#define _OSCCON_IRCF_LENGTH                                 0x3
#define _OSCCON_IRCF_MASK                                   0x70
#define _OSCCON_IRCF0_POSN                                  0x4
#define _OSCCON_IRCF0_POSITION                              0x4
#define _OSCCON_IRCF0_SIZE                                  0x1
#define _OSCCON_IRCF0_LENGTH                                0x1
#define _OSCCON_IRCF0_MASK                                  0x10
#define _OSCCON_IRCF1_POSN                                  0x5
#define _OSCCON_IRCF1_POSITION                              0x5
#define _OSCCON_IRCF1_SIZE                                  0x1
#define _OSCCON_IRCF1_LENGTH                                0x1
#define _OSCCON_IRCF1_MASK                                  0x20
#define _OSCCON_IRCF2_POSN                                  0x6
#define _OSCCON_IRCF2_POSITION                              0x6
#define _OSCCON_IRCF2_SIZE                                  0x1
#define _OSCCON_IRCF2_LENGTH                                0x1
#define _OSCCON_IRCF2_MASK                                  0x40
Yours should be similar.

The one of interest is _OSCCON_IRCF_POSN.
Code: [Select]
OSCCON=7<<_OSCCON_IRCF_POSN; // 7 for 8MHz (Fosc=125KHz*2^(N-1) or Frc if N=0.  7>=N>=0) DS39598E p38is about as good as it gets, though as there is only a single writable field in OSCCON and its nibble aligned and only implemented in a subset of 'classic' midrange PIC16F devices, I'd probably simply settle for:
Code: [Select]
OSCCON=0x70; // for 8MHz, see DS39598E p38
« Last Edit: September 07, 2021, 07:00:45 pm by Ian.M »
 
The following users thanked this post: SparkFly

Offline peter-h

  • Super Contributor
  • ***
  • Posts: 4632
  • Country: gb
  • Doing electronics since the 1960s...
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #6 on: September 07, 2021, 06:42:23 pm »
Whatever you do is fine if you comment it carefully, accurately, etc.

There is a huge fashion among C programmers to comment nothing, "because C is obvious, and if somebody can't read it, they should not be coding". I come from an assembler background where almost every line would be commented (well, it was my own business so writing illegible code would be completely stupid) and I write C similarly.

Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 
The following users thanked this post: Ian.M

Offline Benta

  • Super Contributor
  • ***
  • Posts: 6594
  • Country: de
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #7 on: September 07, 2021, 07:02:11 pm »
Regardless of the consequences (which are none for read-only bits), you cannot avoid writing the bit. Every time you write to a register, all 8 bits are written, even if you write with bcf/bsf instruction.

It can't be phrased better than this.  :-+

 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 16367
  • Country: fr
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #8 on: September 07, 2021, 08:05:02 pm »
However, the datasheet states that bit 2 of OSCCON is a only a readable bit - not writeable. What happens to this bit when I attempt to write to it, as in this case, with a '1'? What consequences might using this method have?

While the datasheet doesn't define what they call "readable" and "writable" (at least I haven't found that info), it's probably because it's one of those "obvious" concepts that almost everybody assumes. One may object that clearly defining this somewhere in the datasheet would not hurt...

As others have said, when writing to registers, it's impossible to avoid "writing" to read-only bits, so you can safely assume that it has not effect. (But again, stating this somewhere in the datasheet wouldn't have hurt... that said, even if they had, chances are that most readers would have missed the info unless it was repeated along with each register definition... which would be cumbersome... so yeah... writing docs is hard.) While the written value for read-only bits doesn't matter, it makes sense to use '0' for those instead or '1', in order not to confuse people reading the code.

And as others have also said, using constants for the various bits is much clearer, and the definitions are already there in the include files.

I've tried investigating, but the closest I can find is from this page here: http://www.learningaboutelectronics.com/Articles/How-to-set-up-the-oscillator-for-a-PIC-microcontroller-in-C.php - where they say that writing a '1' "makes the signal stable". I think this is incorrect, as my interpretation of the datasheet is that this bit is only written to by the microcontroller, to indicate the stability of the oscillator.

You got that right, that's bullshit. Lesson to learn is not to trust any random blog you find on the internet. They're full of crap, and the good ones are few.

Note that the above in the blog you mentioned may have come from a bad interpretation of the datasheet (that you yourself didn't find completely clear), but the logic they used is pretty twisted. What kind of engineers would implement oscillators that would be "unstable" by default (whatever that means) and that would suddenly become stable when you set a given bit? That itself would be quite odd. Sure one could think of very particular oscillators that would default to a very low power, but unstable state (whatever that would mean though - that would then be surely clearly explained in the datasheet), and that you could switch to a "stable" state with a configuration bit, but drawing more power. You can rest assured that this is not the case here, that if it were, it would surely be explained (and promoted) in the datasheet. And again, anyway, this bit not being "writable", it should still be clear that writing to it would NEVER be *required*.

 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4413
  • Country: us
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #9 on: September 08, 2021, 09:07:10 am »
Quote
Every time you write to a register, all 8 bits are written, even if you write with bcf/bsf instruction.
Well, except that a "register" with read-only bits probably doesn't actually have anything to actually WRITE in the read-only positions.We tend to think of registers as being "like" memory locations, but they don't need to be implemented that way - reads and writes can deal with completely separate signals on the chip.  (consider a UART "data" register, where a write sends data to the transmit shift registers, but a read reads the receive shift register - a completely different part of the peripheral.)
 

Offline MIS42N

  • Frequent Contributor
  • **
  • Posts: 544
  • Country: au
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #10 on: September 08, 2021, 09:59:04 am »
Writes to read only bits do not alter them. This is the way I document writes to control registers. It's assembler but I think C accepts something similar. Tedious the first time but copy and paste is your friend
Code: [Select]
MOVLW B'10000000' ; enable DAC, source Vdd
; 1 x 0 0 0 0 x x
; |   | | -+-
; |   | |  +----- 00 = DAC Positive Source Vdd
; |   | +--------  0 = DAC not connected to the DACOUT2 pin
; |   +----------  0 = DAC not connected to the DACOUT1 pin
; +--------------  1 = DAC is enabled
MOVWF DACCON0
;
; --- Comparator ---
MOVLW B'00010010'
; 0 0 0 1 x 0 1 0
; | | -|-   --+-- 010 = CxVN connects to CxIN2- pin
; | |  +---------  01 = CxVP connects to DAC Voltage Reference
; | +------------   0 = No interrupt on a negative going edge
; +--------------   0 = No interrupt on a positive going edge
MOVWF CM1CON1
MOVLW B'10000101'
; 1 x 0 0 x 1 0 1
; |   | |   | | + 1 = Comparator output to Timer1 is synchronous
; |   | |   | +-- 0 = Comparator hysteresis disabled
; |   | |   +---- 1 = Comparator operates in Normal-Power mode
; |   | +-------- 0 = Comparator output is not inverted
; |   +---------- 0 = CxOUT is internal only
; +-------------- 1 = Comparator is enabled
MOVWF CM1CON0
;
 

Offline Jan Audio

  • Frequent Contributor
  • **
  • Posts: 820
  • Country: nl
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #11 on: September 08, 2021, 02:08:06 pm »
The best way is like Ian shows you,
the cool part is you dont have to write it yourself :
Go to the menu and look for view, the select configuration bits or something ( sorry i,m not behind my PC now ).
Now what you do is select all possibilities from a menu, and copy the whole code in your header file.

Oops wrong subject, maybe you did not know either.
« Last Edit: September 08, 2021, 02:14:34 pm by Jan Audio »
 

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2499
  • Country: us
  • Yes, I do this for a living
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #12 on: September 08, 2021, 03:19:10 pm »
Whatever you do is fine if you comment it carefully, accurately, etc.

There is a huge fashion among C programmers to comment nothing, "because C is obvious, and if somebody can't read it, they should not be coding". I come from an assembler background where almost every line would be commented (well, it was my own business so writing illegible code would be completely stupid) and I write C similarly.

The code shows what you're doing.

Comments should explain why you're doing it.
 

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2499
  • Country: us
  • Yes, I do this for a living
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #13 on: September 08, 2021, 03:21:20 pm »
Quote
Every time you write to a register, all 8 bits are written, even if you write with bcf/bsf instruction.
Well, except that a "register" with read-only bits probably doesn't actually have anything to actually WRITE in the read-only positions.We tend to think of registers as being "like" memory locations, but they don't need to be implemented that way - reads and writes can deal with completely separate signals on the chip.  (consider a UART "data" register, where a write sends data to the transmit shift registers, but a read reads the receive shift register - a completely different part of the peripheral.)

All of that is true, but ... irrelevant!

The OP asked about writing to read-only bits in a control register.

The answer is: those bits don't get changed.

Let's try to stay on target!
 

Offline bson

  • Supporter
  • ****
  • Posts: 2577
  • Country: us
Re: What Happens When Writing to a 'Readable Bit'?
« Reply #14 on: September 11, 2021, 08:11:21 pm »
Writing a RO bit will do nothing at all to the value of that bit.  The next time you read it it's unchanged.

Writing a WO bit will enact some change.  The next time you read it you get whatever the datasheet tells you it will read as: '0', '1', or undefined.  The latter means you can't rely on it presenting some specific value, even if in practice you do get something specific.

Sometimes CSR bits have to always be written with specific values, and aren't documented beyond that.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf