Shop OBEX P1 Docs P2 Docs Learn Events
Coding question... ...read write modify. — Parallax Forums

Coding question... ...read write modify.

dkemppaidkemppai Posts: 315
edited 2007-09-20 20:34 in General Discussion
Ok,

I need to understand this...

Is this code valid, or not.


setb RD.2 
setb RD.7



-Dan

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

"A saint-like quantity of patience is a help, if this is unavailable, a salty vocabulary works nearly as well." - A. S. Weaver

Comments

  • BeanBean Posts: 8,129
    edited 2007-09-19 13:51
    Dan,
    It depends.
    When running at high speed or when there is alot of capacitance on the pins the first SETB may not take affect.

    Here is what happens:
    During each port update the port input register is read, then modified, then written. The problem occurs because the port input register actually reads the state of the pins NOT the output register state.

    Let's assume RD.2 is low.

    The "SETB RD.2" sets the output latch high. But before the actual pin voltage level rises to a "1" level, the next SETB command reads the port input state (which is still a zero for RD.2). Then it modifies RD.7 and writes the WHOLE port back. So in the end the output latch for RD.2 gets set back to zero (which it what it was when the second SETB read the input state).

    I hope that makes sense...

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I know what I know, don't confuse me with the facts...
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • dkemppaidkemppai Posts: 315
    edited 2007-09-19 14:09
    Bean (Hitt Consulting) said...
    Dan,
    It depends.
    When running at high speed or when there is alot of capacitance on the pins the first SETB may not take affect.

    Here is what happens:
    During each port update the port input register is read, then modified, then written. The problem occurs because the port input register actually reads the state of the pins NOT the output register state.

    Let's assume RD.2 is low.

    The "SETB RD.2" sets the output latch high. But before the actual pin voltage level rises to a "1" level, the next SETB command reads the port input state (which is still a zero for RD.2). Then it modifies RD.7 and writes the WHOLE port back. So in the end the output latch for RD.2 gets set back to zero (which it what it was when the second SETB read the input state).

    I hope that makes sense...

    Bean.

    Yeah,

    It makes sense. However,·I consider it a bug in the chip,·it acts differently
    based on specific hardware setups, and system voltages.·The above code
    works·at 5 volts but not 3.3 volts.


    I think that the assembler needs to be coded to detect these·situations, and
    provide a warning about needing a nop...
    ··
    Can this be done?

    -Dan
    ···





    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

    "A saint-like quantity of patience is a help, if this is unavailable, a salty vocabulary works nearly as well." - A. S. Weaver
  • BeanBean Posts: 8,129
    edited 2007-09-19 14:47
    When I worked with the intel 8051 years ago it had quasi input ports. The port could sink alot of current, but could only source a very small amount. To make a pin an input, you made it high, then you basically shorted it to ground to make it read a zero. There was no port direction register.

    It is always best to avoid back-to-back port changes. You could change to "OR RD,#$84" and that would do the same thing with only one port access (but sets W to $84).

    Also you may need more than 1 NOP, you may need many cycles until the pin reaches the new state.

    I don't have any control over how the assembler works, so I'll have to let someone else answer that.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I know what I know, don't confuse me with the facts...
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2007-09-20 08:43
    It is a question if the read-modify-write problem is a bug in the chip, or if it is a "feature". Reading the physical states of the output pins (as the SX does) makes sure that the result really reflects the output states, and not what they are considered to be. So you might set an output pin to high, and externally short it to Vss (not really recommended though). When you read the pin, the result will be low in this case because the physical short overrides what you have written to the output register.

    As Bean suggested, placing NOP instructions for a short delay between subsequent SETB instructions helps in many cases, although the required delay depends on the external capacitive load, the clock frequency, and the supply voltage.

    Even when you configure a port pin as an output, the pin state is read back via the input port circuit. This means that the level configuration is in effect, so defining the input level for such a pin as TTL (with a threshold of about 1.4V), or having it set to CMOS (threshold = Vdd/2) has an effect on the read-modify-write behavior.

    Another option is using a "shadow" register, like this

    mov Shadow, RD
    setb Shadow.2
    setb Shadow.7
    mov RD, Shadow

    This completely eliminates the problem, as all port pins are read and written in parallel. I must admit that the four additional clock cycles required to read and write the shadow register could also be taken for up to four NOPs between the SETB instructions that directly modify the port outputs. I normally make use of a shadow register in an ISR when different parts of code set or reset port pin states, and write the updated state to the port immediately before leaving the ISR.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    G
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-09-20 16:29
    It's most often the case that the extra instruction you need to insert can do something useful and not just be a NOP. For example, this sequence:

            SETB    RD.2
            SETB    RD.7
            MOV     W,INCR
            ADD     INDEX,W
    
    
    


    could be rewritten

            SETB    RD.2
            MOV     W,INCR
            SETB    RD.7
            ADD     INDEX,W
    
    
    


    This inserts the necessary delay between SETBs without using any more clock cycles than the original code.

    -Phil
  • dkemppaidkemppai Posts: 315
    edited 2007-09-20 20:34
    Guenther Daubach said...
    Even when you configure a port pin as an output, the pin state is read back via the input port circuit. This means that the level configuration is in effect, so defining the input level for such a pin as TTL (with a threshold of about 1.4V), or having it set to CMOS (threshold = Vdd/2) has an effect on the read-modify-write behavior.

    Another option is using a "shadow" register, like this

    mov Shadow, RD
    setb Shadow.2
    setb Shadow.7
    mov RD, Shadow

    This completely eliminates the problem, as all port pins are read and written in parallel. I must admit that the four additional clock cycles required to read and write the shadow register could also be taken for up to four NOPs between the SETB instructions that directly modify the port outputs. I normally make use of a shadow register in an ISR when different parts of code set or reset port pin states, and write the updated state to the port immediately before leaving the ISR.

    Yeah, I konw, but wouldn't a warning about successive writes to a port be nice? What happened to me was a few pins were moved by one of my layout guys, and I updated the code. With logical names to the pins, I didn't notice that two pins that were on different ports were moved to the same port. And, the problem didn't show up until I tried to lower the voltage.
    Having a warning about successive writes to a port would have flagged me, and I would have caught it.
    Again, I warning in assembler would be nice.

    The problem with the shadow register is that if code in multiple VP's uses a pin on a port, it gets more difficult to update the port settings. This is espically the case for multiple high speed communications VP's.

    Phil,
    I know about threading op codes together. I had one project where I needed to·manually thread code·for a·4+mbit/s continuous data link that needed to cycle·at·exactly 3996 clock cycles. Got real good at watching W,C, and Z [noparse];)[/noparse]

    Anyway,
    The problem was that I KNEW about this problem, but with a rushed schedule I didn't have time to spare, and a simple warning would have been a life saver.
    Thanks,
    Dan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

    "A saint-like quantity of patience is a help, if this is unavailable, a salty vocabulary works nearly as well." - A. S. Weaver
Sign In or Register to comment.