Searching \ for '[PIC] read modify write question' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'read modify write question'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] read modify write question'
2004\11\11@151658 by Bob J

picon face
I was looking at the instruction summary section of the 18F1320
datasheet and came across the paragraph about read-modify-write
operations, and am a bit perplexed by the second-to-last sentence.  It
states:

Any instruction that specifies a file register as part of
the instruction performs a Read-Modify-Write (R-M-W)
operation. The register is read, the data is modified and
the result is stored according to either the instruction or
the destination designator 'd'. A read operation is
performed on a register even if the instruction writes to
that register.
For example, a "BCF PORTB,1" instruction will read
PORTB, clear bit 1 of the data, then write the result
back to PORTB. The read operation would have the
unintended result that any condition that sets the RBIF
flag would be cleared. The R-M-W operation may also
copy the level of an input pin to its corresponding output
latch.

I understand what R-M-W is and when to be cognizant of it, however it
is not clear to me what they mean by "The read operation would have
the unintended result that any condition that sets the RBIF flag would
be cleared."  Could someone enlighten me on that particular statement?

Regards,
Bob
____________________________________________

2004\11\11@155256 by olin_piclist

face picon face
Bob J wrote:
> is not clear to me what they mean by "The read operation would have
> the unintended result that any condition that sets the RBIF flag would
> be cleared."

RBIF is the port B changed condition.  Since BCF on a port B bit also reads
port B, the port B changed condition would be cleared.  However, the RBIF
flag itself should remain unchanged by the BCF portb instruction.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
____________________________________________

2004\11\11@160507 by Jan-Erik Soderholm

face picon face
Bob J wrote :

> I understand what R-M-W is and when to be cognizant of it, however it
> is not clear to me what they mean by "The read operation would have
> the unintended result that any condition that sets the RBIF flag would
> be cleared."  Could someone enlighten me on that particular statement?

OK, let's see...

The RBIF interrupt flag is set on a "pin change" on PORTB.
That is, there have been a change in the status of some PORTB
pin compared with the last time PORTB was *read*.

That condition is cleared by reading PORTB. You can then also
clear the RBIF interrupt flag.

Now, one could think that just changing a single pin on PORTB
using BSF/BCF (since they "just" write, right ? :-) )
would not "disturb" the RBIF interrupt condition.

*BUT*, since the BCF/BSF instruction also *reads* PORTB,
that will actualy clear the condition that set RBIF in the first
place.

Exatly how this disturb things depends a bit on how the logic
that deals with the RB-change interrupt is written, I'd guess.

Well, that's it. Just remember that bcf/bsf always reads the full
PORTx register.

Emjoy ! :)
Jan-Erik.
____________________________________________

2004\11\11@185452 by Lawrence Lile

flavicon
face
Thanks Jan, that is the long answer.  

The short answer is, never do bit operations on a port. Period. Do your bit operation on a mirror byte, then write that byte to the port.  If you must violate this rule, then tread carefully.


Periodically refreshing a port register with a mirror byte is a good way to insure yourself against R-M-W, and also to insure that the port is really in the state you think it is in.  I typically write ports at the end of each main program loop, whether they need it or not. There are but a handful of applications that this isn't a good rule. PORTB interrupt on change might be one of them, depending on how you code it, and serial communications might be another, due to fast timing issues.


-- Lawrence Lile, P.E.
Electrical and Electronic Solutions
Project Solutions Companies
http://www.projsolco.com

> {Original Message removed}

2004\11\12@014833 by cdb

flavicon
With the 18F series a 'mirror' byte may not be needed as all ports
have a LATCH register, which should mitigate the R-W-M problem.

Colin

--
cdb, spam_OUTcdbTakeThisOuTspambarnard.name on Friday,12 November,2004

I have always been a few Dendrites short of an Axon and believe me it
shows.

Light travels faster than sound. That's why some people appear bright
until they speak!



____________________________________________

2004\11\12@042809 by Alan B. Pearce

face picon face
>The short answer is, never do bit operations on a port.
>Period. Do your bit operation on a mirror byte, then
>write that byte to the port.  If you must violate this
>rule, then tread carefully.
>
>Periodically refreshing a port register with a mirror
>byte is a good way to insure yourself against R-M-W,
>and also to insure that the port is really in the state
>you think it is in.  I typically ...

But that does not answer the original question, which was why the R-M-W
operation affects the RBIF flag. Your method still affects the RBIF flag,
and may even make the symptom worse if you are refreshing the port on a
regular basis during an idle loop.

Jan-Erik gave a very good treatise on why any operation on the port affects
the RBIF flag, which did answer the original question. About the only thing
he did not point out is that this "bug" (or "feature", depending on how you
look at it) limits the usefulness of the Interrupt on Port Change feature
unless very careful coding practices are used.

____________________________________________

2004\11\12@044010 by hael Rigby-Jones

picon face


{Quote hidden}

As Olin said, it dosen't affect the RBIF flag, it clears the port changed
condition.  If the RBIF flag is already set, RMW operations on Port B will
not clear it.

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================
____________________________________________

2004\11\12@051113 by Jan-Erik Soderholm

face picon face
Lawrence Lile wrote :

> The short answer is, never do bit operations on a port.
> Period. Do your bit operation on a mirror byte, then write
> that byte to the port.  If you must violate this rule, then
> tread carefully.

IMHO, better learn when direct bit op's on PORT regs
can be a problem, and take action. As far as I understand,
it's only in some specific cases that you can run into
problems. The interrupt-on-change is (might be) one (but it's not given
that you *will* get problems, since, as Olin correctly pointed
out, the RBIF flag will still be set anyway). Having large
capacitive loads on output pins is another (a RC constant
larger then the time from one Q4 cycle to the next Q2 cycle.
If you know your design, a few NOPs or a rearangement of
a few instructions can solve that.

And, as pointed out, the PIC18's LATx regs is another way of
playing safe.

Alan B. Pearce wrote :

> But that does not answer the original question, which was why
> the R-M-W operation affects the RBIF flag. Your method [only
> writing from a shadow reg to PORTx] still affects  the RBIF flag,...

Now, here is something I don't understand. I thought that a
MOVWF to a PORTx register was "safe" (that is, PORTx is
never *read*. But a few data sheets I have checked still says
"read 'f'" in Q2. Such as PIC18Fxx2, DS39564B, page 237".
Also the "Midrange Ref Manual".

*But*, the "PIC18 Ref Manual" says "Read WREG reg" in Q2
in the same instruction. (DS39532A, page 31-89).

I think the latter document is correct here.

And if so, Lawrence method should be safe even from an
RBIF standpoint (I still don't understand what the problem
would be...).

> Jan-Erik gave a very good treatise on why any operation on
> the port affects the RBIF flag, which did answer the original
> question. About the only thing he did not point out is that
>this "bug" (or "feature", depending on how you look at it)
> limits the usefulness of the Interrupt on Port Change
> feature unless very careful coding practices are used.

I'm not that sure...
Any read from PORTB with clear the *condition* that set
RBIF in the first place. It will not clear RBIF as such and the
interrupt will still fire. It should still be possible
to read PORTB (again) later to find out what actualy "happend".
RBIF can only be cleared by a direct instruction in the code.

Note that you can not "see" that condition anyway, you still
have to keep your own copy of the old PORTB value (at least
the pins enabled for interrupt-on-change) and make your own
compare with the actual values.

It would have been another issue if there was a "condition register"
where the actual port change that set RBIF was latched so you
could see that even if the actual pin value already have changed back
to the original value before the interrupt. Then I can see why the read
in a bcf/bsf instruction could be a problem, if that would clear the
"interrupt-on-change-latch-register"...

Jan-Erik.

____________________________________________

2004\11\12@074506 by olin_piclist

face picon face
Lawrence Lile wrote:
> The short answer is, never do bit operations on a port. Period.

That's a VERY short answer.  You might just as well say never use the UART
because you might get the baud rate wrong.

Bad use of a port is a bug no different from other bugs.  When done with the
proper restrictions in mind, it is perfectly legitimate and often the best
answer to do bit manipulations on a port register.  This is my "normal" way
of doing it.  I only use shadow registers and other mechanisms in the
relatively rare cases where there could be a problem.  Most of the time
there is no need to spend the extra cycle, program memory, and RAM.  Yes,
you do have to know what your'e doing, but that's no different than most
other aspects of using PICs.


*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
____________________________________________

2004\11\12@083951 by Wouter van Ooijen

face picon face
> > The short answer is, never do bit operations on a port. Period.
>
> That's a VERY short answer.  You might just as well say never
> use the UART because you might get the baud rate wrong.

The major source of RMR problems on a port is having a non-trivial load
on the port. Even a modest 10 mA can prevent the port level (when driven
low) to be realy low, so setting another bit will revert that poor
LED-driving pin to high. So I do agree with the short answer. The longer
answer would be: if you realy know what you are doing and what you are
trying to avoid, go ahead and use the port directly.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


____________________________________________

2004\11\12@102626 by Bob J

picon face
> With the 18F series a 'mirror' byte may not be needed as all ports
> have a LATCH register, which should mitigate the R-W-M problem.

This is precisely what I have been doing, reading the port directly
via portb interrupt-on-change (well, actually playing it safe and
copying portb to a temporary register) but using the LAT registers to
write to the ports.  Seems to be working just fine.

It seems to me that you'd have to almost try to have problems with
R-M-W, by not using the LAT registers and/or temporary port registers.

Regards,
Bob
____________________________________________

2004\11\17@113500 by Gerhard Fiedler

picon face
Jan-Erik wrote:
> And if so, Lawrence method should be safe even from an
> RBIF standpoint (I still don't understand what the problem
> would be...).
>
>> Jan-Erik gave a very good treatise on why any operation on
>> the port affects the RBIF flag, which did answer the original
>> question. About the only thing he did not point out is that
>>this "bug" (or "feature", depending on how you look at it)
>> limits the usefulness of the Interrupt on Port Change
>> feature unless very careful coding practices are used.
>
> I'm not that sure...
> Any read from PORTB with clear the *condition* that set
> RBIF in the first place. It will not clear RBIF as such and the
> interrupt will still fire.

I'm not sure either, but it seems to me that there might be a chance for a
missed interrupt in the case that the input changes after Q1 (when the port
input latch gets updated) but before Q3 (when the port change detection
latch gets updated). Whether such a change sets RBIF depends on the
synchronization of the setting of RBIF, for which I didn't find any
documentation.

I don't use the RBIF interrupt a lot; I'm trusting the advice that it's not
safe unless you don't read port B at all (outside of the change detection
mechanism).

Gerhard
____________________________________________

More... (looser matching)
- Last day of these posts
- In 2004 , 2005 only
- Today
- New search...