Shop OBEX P1 Docs P2 Docs Learn Events
Instruction Timing — Parallax Forums

Instruction Timing

edited 2007-11-02 23:20 in Propeller 1
I am working on I2C assembly code to communicate at 400 kHz.· I would like to get the timing down.

When you execute a line of assemby code to change the value of a pin, how soon after (or during) the 4 cycles does the pin flip and at what speed?

Is this true for setting direction as well?

Thanks.

Comments

  • deSilvadeSilva Posts: 2,967
    edited 2007-11-02 18:18
    The "action" of every instruction starts at its 5th cycle, the 6th cycle is used for writing back any results. As the first two cycles are hidden interleaved in the previous instruction you get the impression that a (standard) instruction takes four cycles only, which is only half of the truth.

    Asking "when" makes no sense without a point of reference, i.e. a "WAIT" instruction, or a previous OUTA.
    When comparing OUTA instructions it is no help to know details, as they behave identical.
    Directly after a WAIT (CNT, PEQ, PNE) an OUTA action should be noticed 62.5 ns after the releasing WAIT event. This can easily be measures with a scope.

    I must admit, I never did it .. I shall this evening ....
  • Mike GreenMike Green Posts: 23,101
    edited 2007-11-02 18:19
    Both the direction and output registers are written during the 4th system clock of the instruction's execution. I couldn't tell you where in the clock cycle and, in any event, that's not specified and would vary depending on which cog is making the changes.

    Be sure to look at the I2C / SPI routines used in FemtoBasic. They're written in assembly and work reliably at 100KHz I2C bus speeds and not reliably at 400KHz (with an 80MHz system clock). They're very general purpose, not just for accessing memory devices, and the generality is probably what's interfering with their use at the higher bus speed.
  • edited 2007-11-02 18:21
    Thanks Mike,

    Someone had mentioned that they had not seen any I2C assembly examples so I started writing my own. I need the 400 KHz, but I will look at the FemtoBasic code for reference.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-11-02 18:26
    The FemtoBasic routines use a state machine to handle all of the special cases for device select codes / addresses / read data / write data, etc. If you have a particular device in mind (like EEPROMs) you could "unroll" the special cases, eliminate the overhead to handle them, and easily get the 400KHz bus speed. The lowest level routines (for reading a byte and writing a byte) are a good starting point.
  • deSilvadeSilva Posts: 2,967
    edited 2007-11-02 23:20
    So I made the measurements (see encl.) Take out your 'scope and recheck.
    It seems to take 7.5 ticks between wait release and observed signal. I guessed wrong above..

    This is the most likely timing

    Still Wait instruction (ticks counted after rising edge)
    tick 0.5 Waiting released; 1/2 Tick for inter-cog sync/ signal acquisition
    tick 1.5 Writeback slot
    Note that the pipeline is stopped for wait and hub instructions (see Tutorial for examples)
    tick 2.5 fetch Opcode
    tick 3.5 memorxy slot for writeback when interleaved
    tick 4.5 get dest
    tick 5.5 get source
    tick 6.5 action slot
    tick 7.5 writeback
    As OUTA is only set during the writeback, the signal can't be observed earlier

    {CHECK WAIT-OUTA
     v 0.1  Nov 2007 by deSilva
     Uses pins 15 & 16
    
     Result: OUTA - OUTA  = 200 ns corr. 50 ns = 4 ticks 
             WAITPEQ-OUTA = 380 ns corr. 95 ns = 7,5 ticks 
    }
    CON
      _CLKMODE = XTAL1   ' set your own mode
      _XINFREQ = 20_000_000
    
    PUB main
        COGNEW(@xmt,0)
        COGNEW(@rcv,0)
    DAT
        ORG 0
    xmt
        MOV  nextc, CNT
        ADD  nextc, #100
        MOV DIRA, pins
    :loop
        WAITCNT   nextc,#511
        ADD OUTA, pins 
        ADD OUTA, pins
        JMP #:loop
    
    
    pins  LONG %1_0000_0000_0000_0000
    nextc LONG 0
    
        ORG 0
    rcv
    
        MOV DIRA, pins2
    :loop
        WAITPEQ   pins1, pins1
        ADD OUTA, pins2 
        ADD OUTA, pins2
        JMP #:loop
    
    pins1  LONG %1_0000_0000_0000_0000 
    pins2  LONG %0_1000_0000_0000_0000
    
Sign In or Register to comment.