Shop OBEX P1 Docs P2 Docs Learn Events
I2C dual bus question — Parallax Forums

I2C dual bus question

TappermanTapperman Posts: 319
edited 2015-05-07 11:55 in Propeller 1
@Peter Jakacki, I saw in one of your threads you mentioned using SPI over the bus.

@All, has anyone ever hooked up another set of hardware on the bus with the clock and data reversed? And can the two buses co-exist in one bus?

... Tim

PS - [post=1326225]info[/post]
«1

Comments

  • TappermanTapperman Posts: 319
    edited 2015-04-13 15:14
    The reason I asked is I'm trying to wrestle with this code I'm writing to support both busses at the same time:
    { notes for STARTBIT routine.
        On Exit:
            IF ... the bus is busy and unavailable for use, this routine exits
            with the 'c' carry flag set.
            
            OTHERWISE, both the data line and the clock line are left as outputs in
            the LOW state.  Although the direction of the data bus changes often,
            all routines must return the bus to this state, while the line is siezed!
    
            Clock 
                   Idle           Phillips 'Start-Bit' I2C  (lower data first)
             Data 
    
            Note: If the direction of the clock pin is set as OUTPUT, the bus is
                  considered SIEZED and calling this routine issues a RESTARTBIT.
                  To ensure visibility on an O-Scope, the restart bit will be twice
                  as wide as a data bit.
                        
               Clock 
                                         'RESTART-BIT'
                Data      
    }
    startBit      and       mask, dira              wz, nr       ' see if line already siezed?
            if_nz jmp       #:redo                               ' jump if we are bus master!
                  or        phsa, zero              wz, nr       ' check activity counter on data line
            if_nz and       mask, ina               wc, wz, nr   ' see if line is idle?
     if_c_or_z    mov       temp2, busbusy              
     if_c_or_z    jmp       #:bail                               ' jump if activity by another master.
                  and       zero, zero              wz, nr       ' set zero flag
    :redo         or        outa, SDAmask
            if_nz call      #delayBit                            ' makes restart 'visible' on o-scope
            if_nz call      #delayBit
                  or        outa, SCKmask
            if_nz call      #delayBit                            ' makes restart 'visible' on o-scope
            if_nz call      #delayBit
                  or        dira, mask              wz           ' sieze the line in the state it is in.
                  xor       outa, SDAmask                        ' lower the data pin
                  call      #delayBit                            ' pause
                  xor       outa, SCKmask                        ' lower the clock line
                  call      #delayBit                            ' pause
                  mov       temp2, zero
    :bail   if_z  and       hub_mask, #1            wc, nr       ' if zero caused bail, set carry also.
    startBit_ret  ret
    


    To use it, you place the code is two cogs and give one of them the reverse clock and data pins as the other has.

    ... Tim
  • jmgjmg Posts: 15,173
    edited 2015-04-13 15:35
    Tapperman wrote: »
    The reason I asked is I'm trying to wrestle with this code I'm writing to support both busses at the same time:
    ? do you mean two i2c Busses, on two pints ? or some mix of i2c and SPI ?

    You cannot support both at the same time they have to share in the time domain, with alternate access.
  • TappermanTapperman Posts: 319
    edited 2015-04-13 15:42
    I mean .... One master ... many slaves.

    Test as follows

    with two PCF8574's on a bread board ... one connected properly ... the other, has it's data and clock pins connected in reverse. Easy to do when you get old and suffer from vision issues.

    both are jumper wire set to the same device address.

    the one master then talks to either chip without confusion. one busses 'startbit' is ignored by the other slaves on 'back-bus' (their data pin is your clock pin) .... when the 'front' bus sends a startbit ... the back bus 'doesn't see it'.

    ... Tim
  • jmgjmg Posts: 15,173
    edited 2015-04-13 16:28
    You are relying on the State engine rejecting as noise the reverse chatter of multiple stop/start states.

    Probably ok on simplest HW slaves (like PCF8574 et al), but it may scramble the brains of a MCU based i2c slave, so you should test in all cases.
  • TappermanTapperman Posts: 319
    edited 2015-04-13 16:52
    Was just looking at the single master with tons of slaves case ... No need to test all other cases for this application. This technique should allow the bus to control 256 slaves instead of 128.

    But, in practice ... I don't think I'm going to find but 2 varieties of the PCF8574. And, I think there is a 'A' version that permits another 8 devices on the same bus. For a total of 16 Expansion chips ... For me, this could be 32 Expansion chips with 8 quasi I/O bits each, on the same bus.

    BTW, if the clock line stays high on the 'front-bus' and data line is toggled rapidly ... the 'slaves' start to listen on the negative edge for their device number, and then reset on the positive edge. For the back bus, the slaves see the clock raise and lower (for the same signal) but don't act on a signal since no start bit has been received. You could in concept transmit a 'anch. serial' burst without confusing the slaves. But I haven't gone that far yet.

    ... Tim
  • Cluso99Cluso99 Posts: 18,069
    edited 2015-04-13 16:57
    I have shared i2c pins before but I keep one of the pins (sea or scl) steady. So you would require another pin.
    By swapping the pins as suggested, you could have unpredictable results.
  • jmgjmg Posts: 15,173
    edited 2015-04-13 17:05
    Tapperman wrote: »
    Was just looking at the single master with tons of slaves case ...

    If you need "lots of slaves" then also consider small MCUs., either on i2c or in a ring-bus.
    Example :
    Cheapest PCF8574 Digikey $0.504 @ 2,500 (1.25 1+)
    vs MCU ( i2c, SPI, ADC, UART, PWM )
    EFM8BB1 [2KF,QFN20] $0.31361 @ 1500 (42c 1+)
    EFM8BB1 [8KF,SO16] $0.42268 @ 2500 (56c 1+)

    addit - I also find this info on FLASH Programming these MCUs from Prop,
    by Peter Jakacki

    https://docs.google.com/document/pub?id=1CzYzYPhQGb8qpLi8Pw_2cHbRjZeOsWyg_ZyT5GaNp44

    (will need updates to DEVICE SPECIFC area, for F850/EFM8 variants,
    eg F850,BB1 are this in SiLabs SW
    {
       "c2wsfr ff 80",                     // Enable VDD monitor
       "wus 5",                            // wait 5 us for VDD monitor to stabilize
       "c2wsfr ef 02",                     // Enable VDDmon as a reset source
       "c2wsfr a9 00",                     // Set Internal High-Frequency Oscillator as system clock
       NULL
    };
    
    
  • TappermanTapperman Posts: 319
    edited 2015-04-13 20:38
    jmg wrote: »
    You are relying on the State engine rejecting as noise the reverse chatter of multiple stop/start states.

    Uh ... when do you not depend on this logic? With I2C, that is.

    ... Tim

    PS - Thanx for input on links ... alternatives are great!
  • jmgjmg Posts: 15,173
    edited 2015-04-13 21:21
    Tapperman wrote: »
    Uh ... when do you not depend on this logic? With I2C, that is.
    My point was you are outside the i2c design specs, and the more complicated the i2c implementation is, the riskier this gets.
    I'd guess that a PCF8574 would be OK with many fast stop/start chatters, but anything with a MCU coupled to a i2c would need careful checking.
    I have seen relatively simple (clocked) i2c slaves cough when even slightly outside spec.
  • TappermanTapperman Posts: 319
    edited 2015-04-13 21:55
    jmg wrote: »
    ... but anything with a MCU coupled to a i2c would need careful checking.
    I have seen relatively simple (clocked) i2c slaves cough when even slightly outside spec.

    OK ... point taken .... I put my parallax FM radio (I2C) on the bus and noticed it did have an issue. But, I programmed it to Startbit/Stopbit/Startbit/device# ... etc. And it worked ok.

    ... Tim
  • Cluso99Cluso99 Posts: 18,069
    edited 2015-04-14 04:43
    Problem is, when you design things outside of specs, it might work fine today, but glitches tomorrow.
  • TappermanTapperman Posts: 319
    edited 2015-04-14 10:17
    Cluso99 wrote: »
    Problem is, when you design things outside of specs, it might work fine today, but glitches tomorrow.

    But, here is my question .... am I outside the specs? Why would it work at all? And then stop working later?

    I use this attached monitor to 'see' how this works. Check it out yourself ... on a prop that has nothing attached to its IO pins ... then perhaps you can answer my question "am I outside the specs?"

    ... Tim
  • TappermanTapperman Posts: 319
    edited 2015-04-14 12:05
    Lets restate the obvious:
         DATA ─────────────────┳───────────────>
                               │                  I2C Bus
        CLOCK ─────────────┳───┼───────────────>
                           │   │
              ┌──────────┐ │   │  ┌──────────┐        
              │          │ │   │  │          │
              │       SDA├─┼───┻──┤SCK       │
              │          │ │      │          │
              │       SCK├─┻──────┤SDA       │
              │          │        │          │
              │          │        │          │
              │          │        │          │
              │          │        │          │
              └──────────┘        └──────────┘
                FRONT                 REAR
    
    

    Here the word (you) refers to the bus master. Only one master may 'speak' at any instant.

    rule 1 - when no activity is on the bus ... the data and clock line must be high. Often referred
    to as the idle/bus free state. If the bus is not idle, you must wait for a stop\bit before
    the bus can be considered idle/free again.

    rule 2 - "when the clock line is 'high' the data line must not change" ... now, violation of this rule
    is not 'the end of the world' ... it just changes the meaning of things a little.

    rule 3 - If you violate rule 2, then your sending a 'start' or 'stop' bit (depending on the violation)

    rule 4 - If you violate rule number 2 by lowering the data line ... you generate a start\bit. And
    conversely, if you violate rule 2 by raising the data line, you generate a stop\bit.

    rule 5 - If you follow a start bit by lowering the clock line ... the line is 'seized'.

    ... 7 bit device address, direction bit and 'ACK' ... etc. More rules than I care to list for now. Besides we need only examine these shown to explain the concept.

    The bus is 'open collector' and therefore must have pull up resistors. So, if you have a conflict between any two confused 'slaves' that would attempt to communicate ... when they should not ... your hardware is 'safe'. I hope that everyone can see that ... and realize that I have in fact studied the effects closely.

    In fact, I will make so bold as to claim 'I don't think you can harm a slave this way?'

    So, regardless of which 'side' of the bus (front/rear) you configure a slave to ... both lines must be high for the bus to be considered 'idle' ... and line activity that does not conform to the rules above, is IGNORED by all slaves. On both sides.

    As an example: a 8-1-N @ 9600 baud serial burst appearing on the DATA line would be ignored by both sides!!!!!!!! That's right, you can even send serial across the bus ... with no conflicts. However, the sender (need not be the master in this case) must watch for a 'stop\bit' before sending its burst, if any other master has seized the line.

    All this is made possible, by rule #5. That's right .... before you can send a device# to any slave, you must lower the clock line first!

    ... Tim
  • ChrisGaddChrisGadd Posts: 310
    edited 2015-04-14 12:49
    Quite right, Tim.
    The start bit should prevent either the normally-connected or the reverse-connected device from getting confused, and even if the opposite device does somehow see a start bit, it will only ever detect zeroes clocked in (sda only toggles while scl is low). I was intrigued enough to modify an old spin driver and test it with two eeproms, and it seems to work fine.
    It is a bit of a kluge, but if you need more devices than there are address for, and don't want to create a second i2c bus, it's certainly a possibility. You're also correct that the PCF8574 and PCF8574A use different addresses.

    I2C reversed test - Archive.zip
  • jmgjmg Posts: 15,173
    edited 2015-04-14 12:58
    Tapperman wrote: »
    But, here is my question .... am I outside the specs?

    Can you point to an i2c spec that defines reverse connection behaviour ?

    Not only are you outside specs, you are moving into territory the vendors are unlikely to have ever tested.
    That means you do your own testing, for every vendor change & die revision.
    Tapperman wrote: »
    Why would it work at all? And then stop working later?
    As your own post #11 above shows, it may work, or it may have problems.
    Your state assumptions are just that, and they exclude the time-domain.
    They are likely to be ok on the simplest Logic based, no-internal-clock designs

    I can see a use for this sort of library, eg for config, i2c debug terminals and setup uses where the 2nd bus is not present in the field.
    It is the type of library that also needs a list of tested/proven devices, and device pairings, and some warnings....
    It also does fit well on a Prop, which has the free-pin access.
    Tapperman wrote: »
    In fact, I will make so bold as to claim 'I don't think you can harm a slave this way?'
    Depends how you define harm :)
    I have seen a general trend to include reset pins on i2c devices like RTC, which suggests repeated stop may not be enough to recover those state engines in all disturbance cases.
  • TappermanTapperman Posts: 319
    edited 2015-04-14 13:26
    ChrisGadd wrote: »
    Quite right, Tim.
    The start bit should prevent either the normally-connected or the reverse-connected device from getting confused, and even if the opposite device does somehow see a start bit, it will only ever detect zeroes clocked in (sda only toggles while scl is low). I was intrigued enough to modify an old spin driver and test it with two eeproms, and it seems to work fine.
    It is a bit of a kluge, but if you need more devices than there are address for, and don't want to create a second i2c bus, it's certainly a possibility. You're also correct that the PCF8574 and PCF8574A use different addresses.

    I2C reversed test - Archive.zip

    Well, my original question in post#1 was "Has anybody ever done this before?" I thought the people in this forum would be 'excited' by my 'blind reverse wiring by mistake' ... instead, most responses have been 'negative' (yours excluded) .... at least some-one out their in forum land actually TRIED my idea!

    And, I guess that I can assume the answer to my original question is [size=+2]NO[/size].

    Thankyou very much Chris,


    ... Tim
  • Cluso99Cluso99 Posts: 18,069
    edited 2015-04-14 14:06
    Tim,
    No,I have not tried your solution.

    Your explanation a few posts above seems to make sense. I have not drawn out a timing chart to verify (insufficient time with other projects on the go) but it does make sense.

    I have however successfully tried out sharing the /R and /W lines of a SRAM with SDA & SCL with no problems. In the way I use it, there is no possibility to get a valid I2C start condition registered on the I2C bus, and hence no conflicts can arise. My use of the SRAM is full on as I am running C code from it in XMM mode.

    Back to your solution...
    Since you have described a solution where it is not possible to get a valid start condition to be seen, the I2C device(s) will be fine. That is the pre-condition for the I2C to work. So provided you have correctly given an I2C device attached a valid stop, then that device will remain unselected and hence in an idle state waiting for a start, and this means it will not output on the bus.

    Using a line for serial (half duplex) while the other line remains steady would likewise work. But you WILL NOT be able to send serial on both lines concurrently, for fear that a condition may meet the I2C start selection.

    FWIW the SPI of the SD Cards have a situation where they do not release the DO line correctly at the end of a transaction. It is necessary to give it some extra clocks to clear down the problem.

    BTW, to your question, sometimes it is only possible to find problems with a solution. That's what we look for. To fail to do so could result in all sorts of problems. We have to consider everything.
  • TappermanTapperman Posts: 319
    edited 2015-04-14 14:14
    jmg wrote: »
    Not only are you outside specs ...

    Sir .... I AM INSIDE the TRUE I2C specs. I do not wish to conduct an argument from this thread ... send me PM with any 'outside' issues you think may exist, and I will publicly state I'm 'outside' ... review my I2C monitor I uploaded for evidence in your argument.
    jmg wrote: »
    As your own post #11 above shows, it may work, or it may have problems. Your state assumptions are just that

    I maintain I am assuming NOTHING at this point. You on the other hand are assuming the FM radio w/MCU is conforming exactly to the rules!!!!

    It's all there for anyone to view ... and at least one other user of the forum has used it! But I'm not sure if you understand the problem? If you did, your comments may have been different?
    jmg wrote: »
    ... and they exclude the time-domain.

    really!
    {
     on entry:
            If the data pin direction is out, the 'c' carry flag contains the bit
            to xmit.  If the direction is INPUT the carry bit is set by the data
            pin itself.  This routine also imposes a timing element.  After all,
            it is a 'clock' bit.
    }
    clockbit      muxc      outa, SDAmask                   ' has no effect if input
                  call      #delayBit                       ' wait pace time
                  xor       outa, SCKmask                   ' toggle clock line
                  call      #delayBit                       ' wait pace time
                  and       SDAmask, ina            wc, nr  ' reads data bus
                  xor       outa, SCKmask                   ' toggle clock line
    clockbit_ret  ret
    
    How?

    ... Tim
  • jmgjmg Posts: 15,173
    edited 2015-04-14 14:37
    Tapperman wrote: »
    I maintain I am assuming NOTHING at this point. You on the other hand are assuming the FM radio w/MCU is conforming exactly to the rules!!!!
    Hehe, it was not me that posted this, but you...

    ["I put my parallax FM radio (I2C) on the bus [B]and noticed it did have an issue[/B]. But, I programmed it to Startbit/Stopbit/Startbit/device# ... etc. And it worked ok."]

    Voila, an exception case, provided by yourself - nicely done.
    Claimed "rules" mean little in the real world - things work, or they have problems.....

    Relax - Yes, it is a useful idea, but it needs care.
    I can see a use for something like an Invisible Debug link to a Ptrop.- certainly saves pins, but has caveats.
  • TappermanTapperman Posts: 319
    edited 2015-04-14 14:43
    Cluso99 wrote: »
    Tim,
    Using a line for serial (half duplex) while the other line remains steady would likewise work. But you WILL NOT be able to send serial on both lines concurrently, for fear that a condition may meet the I2C start selection.

    Thank you for that excellent analysis!!! And my assertion did say 'DATA' line only.

    ... Tim
  • TappermanTapperman Posts: 319
    edited 2015-04-14 18:44
    I cant believe that none of the truly Heavy Weights in this forum or 'big wigs' at parallax, haven't weighed in on this subject to tell me I'm full of 'do-do'.

    I mean 'Phil P.', 'Mike Green', 'Chip G.', 'Heater', 'Jonny Mac', etc.

    ... Tim
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-04-14 19:07
    Tapperman wrote: »
    I cant believe that none of the truly Heavy Weights in this forum or 'big wigs' at parallax, haven't weighed in on this subject to tell me I'm full of 'do-do'.

    I mean 'Phil P.', 'Mike Green', 'Chip G.', 'Heater', 'Jonny Mac', etc.

    ... Tim

    I haven't read all your posts because I was a little confused as to what you were asking. However I frequently reuse the I2C bus lines for SCK and MOSI to save a some I/O as SPI devices will not care what the I2C bus is doing as long as they are deselected. Conversely I2C bus devices will not care what SCL and SDA are doing while it does not sense a start condition so they are always "deselected". Using SDA as the MOSI ensures we keep control and do not inadvertently issue STARTs and STOPs. So when sharing these lines with SPI the MISO has it's own I/O input which could also be shared with other SPI devices too.

    I also use Silabs CPUs for I2C slaves but I also take the SDA line as the C2D programming data input and control the RST/C2K line from a dedicated I/O. So sending serial data on the SDA line to program the Silabs parts does not affect other devices on the bus as they are "deselected". Even if SCL is left high while SDA is sending serial data it doesn't really matter if a START condition is sensed by other I2C devices as there is no clock. So SCL can be left high or taken low, it doesn't matter, as long as the bus is reset either by a proper START or STOP.
  • TappermanTapperman Posts: 319
    edited 2015-04-14 19:59
    ... I2C bus devices will not care what SCL and SDA are doing while it does not sense a start condition so they are always "deselected".

    First, thank you for your input!!!!! I think the last time we text was when I ordered the wrong LCD module from one of your very old threads?

    I was calling it 'open collector' in earlier posts. What I was 'hinting' at was that the slave would only 'output' when the device number was received ... regardless of direction.

    However, the biggest danger is when the 'rear' bus thinks it has received a 'read' request from activity on the other 'side' ... which then will switch to 'active' output on any additional clock pulses ... what do you call it bit acc. (pull up resistors wont change state fast enough) or something? Meaning 'a problem exists' ... the open collector nature of the bus changes.
    ... it doesn't really matter if a START condition is sensed by other I2C devices as there is no clock.

    Thanks for expressing that better than I could ... my point exactly.

    ... Tim

    PS - I had seen an earlier post where you mentioned SPI over the I2C bus ... and I chimed in with 'me too'. But, I don't know if you saw that or not?
  • TappermanTapperman Posts: 319
    edited 2015-04-15 09:47
    Primitive State Table used to Generate the I2C monitor.

    NOTE - I do not simplify the state table ... easier to detect errors when left as is.

    outputs

    (SbD-I2C-SPI-Stp-Ovr)

    [SbD] Start Bit Detected
    [I2C] The clock line is lowered after the start bit to cause this event
    [SPI] When I mix SPI on the same bus .... this pin shows the activity is not an I2C burst. NOTE ... a spike on this line followed by rapid start & stop bits indicates 'rear' bus activity.
    [Stp] Stop Bit Detected ... bus is idle/free.
    [Ovr] Over-run ... arriving bits are changing faster than the machine code can read.

    ... Tim
  • TappermanTapperman Posts: 319
    edited 2015-04-15 16:39
    jmg wrote: »
    Depends how you define harm :)

    If the device on the 'rear' side was to falsely go from 'inactive' to 'outputting (READ direction), it's output would be on the FRONT sides 'clock' line ... which is an active out from the 'master' conducting bit talk with any given slave. And that would be an 'unwelcome' event in my hardware.
    jmg wrote: »
    I have seen a general trend to include reset pins on i2c devices like RTC, which suggests repeated stop may not be enough to recover those state engines in all disturbance cases.

    I saw the MCP23008 (idbruce is using in his project) does have a reset pin ... but the data sheet was unclear if the reset pin reset the I2C internal logic or if that pin was for the reset of /interrupt settings, direction registers, etc?

    I've not encountered I2C slaves that refuse to reset?

    ... Tim
  • ChrisGaddChrisGadd Posts: 310
    edited 2015-04-15 19:13
    Tapperman wrote: »
    If the device on the 'rear' side was to falsely go from 'inactive' to 'outputting (READ direction), it's output would be on the FRONT sides 'clock' line ... which is an active out from the 'master' conducting bit talk with any given slave. And that would be an 'unwelcome' event in my hardware.

    I don't believe that's a problem; consider that data (opposite device's clock) only toggles while the clock (opposite's data) is low. When one device puts a '1' on sda, the opposite bus sees a stop, followed by an idle state. When the '1' is clocked in, the opposite bus sees that as a start. If one bus sends multiple consecutive '0's or '1's, the opposite simply sees a long period with no clocks. It shouldn't be possible for the opposite bus to ever get into any trouble; it'll reset long before reaching an ack bit, and even if it doesn't, the only ID it could receive is $00.
                     ┌─idle                                              
                     │  ┌─start                                          
                     │  │   ┌───┬─undefined                              
                     │  │   │   │   ┌─stop                               
                     │  │   │   │   │┌─idle                              
                     │  │   │   │   ││  ┌─start
                     │  │ 0 │   │   ││  │ 0
                                                                
      SDA 
      SCL 
    
              start     1       0       1       0       0       0     stop
                                                               
      SCL 
      SDA 
    
    I sometimes run into problems with slaves not resetting, which I realized is caused by reloading some code at the precise instant that the slave is sending, in which case the slave might still be holding the data line low when the Prop reboots. This is easily solved by toggling scl until sda floats high, assuming that pullup resistors are used with an open-drain driver. A push-pull driver might damage something if the master is outputting a high for the idle state while the slave is still trying to send a '0'.

    I took a look at your I2C monitor, but have no idea what I'm supposed to be seeing.

    Chris
  • TappermanTapperman Posts: 319
    edited 2015-04-15 22:50
    ChrisGadd wrote: »
    I don't believe that's a problem

    No, you’re correct, it’s not a problem. I was responding to another message, to clarify what “harm” means for me. I was trying to define what the worst case scenario might be for the dual bus. IF and only IF it was possible … and it is not … therefore, the technique is sound … and for those readers that don’t wish to use it, I say “Fine”

    I should not even have responded to that message. It’s just a waste of time to communicate with some people who only seek an argument.

    I was trying to ask a legitimate question of everyone on the forum. I just wanted to know if anyone had ever done this before? I searched the forum and could find no mention of it. And I refused to believe, that such a simple trick had gone unnoticed by absolutely everyone who has used it for the past 20+ years?

    I already knew it would work, and I knew why it would work. A nice little side benefit derived from my bus monitor.

    And you, just went and tried it first. Then you commented on it (nice). But my thread got hi-jacked, and spun out of control in a direction I really did not intend. By those who neither understood it or tried it!!!!

    But that’s the Achilles heel of this forum. I still have not received any replies to post #2, which was the real reason I started this thread!!!

    BTW, I see you went through a ton of work to make that graphic!! Nice job. Can I borrow it for my docs?

    … Tim

    PS - I'll document that Bus Monitor as soon as I have a 'half' day free.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-04-15 23:49
    Tapperman wrote: »
    I still have not received any replies to post #2, which was the real reason I started this thread!!!
    s?

    … Tim

    Okay, I'm still confused. I don't know why you want to run code in 2 cogs when one will do since you can only access one device at a time, or am I missing something?

    The bit where you say " I'm writing to support both busses at the same time" is confusing too.
  • TappermanTapperman Posts: 319
    edited 2015-04-16 00:25
    Okay, I'm still confused. I don't know why you want to run code in 2 cogs when one will do since you can only access one device at a time, or am I missing something?

    Oops ... No, I lost my focus with all the distractions ... Now I remember, I wanted to try to simulate the open collector nature of the bus, and instead of wiring two CPUs together to try it. I thought I would just put them into one, and avoid the wiring.

    Oh yeah, and I also did not document that the timer A in this arrangement is counting edges (negative that is) on the data line. That initialization code is not shown.


    ... Tim
  • TappermanTapperman Posts: 319
    edited 2015-04-16 13:01
    ChrisGadd wrote: »
    I took a look at your I2C monitor, but have no idea what I'm supposed to be seeing.

    Chris

    The I2C Monitors’ principle of operation

    Because of the move source (MOVS) command on the propeller, only the lowest nine bits matter in this approach. The direction register is set so the lowest 2 bits are inputs, and the remaining 7 bits are set to outputs. NOTE – no other cog may use the lower 9 pins while this code executes.

    In the propeller, output trumps input and one trumps zero. So, whenever you write a value to the lower 9 pins of the output register. On the read of input register you will input only those bits from the outside that are set as inputs. The pins declared as output will read back the last value written for those bits by the command OUTA.

                     ina    1 0
              ┌────────────┬─┬─┐    C= clock
          +-> │  feedback  │C D│    D= data
          |   └────────────┴─┴─┘
          |          outa
          |   ┌────────────┬─┬─┐
          +-< &#9474;  state#    &#9474;d d&#9474;   d= dont care
              &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9524;&#9472;&#9496;
                     dira
              &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9516;&#9472;&#9488;
              &#9474; all '1' s  &#9474;0 0&#9474;
              &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9524;&#9472;&#9496;
    
              |<-- 9 bits ---->|
    
    Figure: Propeller I/O Register configuration.

    So, this simple 3 line loop moves the lower 9 bits of the state table to the lower 9 bits of the output register … of course, the lowest 2 bits are ignored. The next time the input register is read it will contain ‘feedback’ from the last OUTA command and input from the 2 pins that are ‘live’ or real time.
                  jmp       #Init
    
    Loop          mov       outa, 0_0
    Init          movs      Loop, ina
                  jmp       #Loop
    

    So this is the principle used in a state machine …. “what we do next, depends on where we have gone and what’s going on now?”

    So how the machine behaves depends on the table that is loaded into the cog ram at startup. Now, the table itself has special rules … since we are trying to duplicate ‘dedicated’ hardware that could do the same thing … we must be mindful that the CPU is clocked. So it cannot operate at the speed of hardwired logic. Therefore, the layout of the table is such that each ‘row’ has but one stable state and the first row is the initial state on power up … for my use here, that means an input of ‘11’ is idle on the bus.

    When the next state is the same as the current state … that state is said to be ‘stable’. When that’s not the case you’ve reached a transition state, and that will move you to a different row of the table.

    Now, the columns of the table are arranged so the change of a single bit of input moves you either left or right in the table one column. Because of that, anytime a change of 2 bits occur from the last read of ina (or 2 columns in the table) … we know the machine is not able to keep up … and that generates an ‘error’ condition. I believe its sends the machine to state 36.

    Now, the outputs are just “OR’d” into the upper bits (above 9) of the transition state table, along with the state values, and they are written to the output port at the same time the state is!

    … Tim
Sign In or Register to comment.