Shop OBEX P1 Docs P2 Docs Learn Events
Spi-ish question — Parallax Forums

Spi-ish question

So, I just tried to use jm_ez_spi to operate a TPIC6595 (Shift register with open drain high voltage/current outputs.

I tried slowing things way down (1 khz) and still had some strange going on.

So here is what happens:
In the attached archive I have 'Hardware_00' with 3 possible tests that can be selected in 'Setup()'

Test1 After fiddling around, and then turning ALL outputs on and off, this works. see Test.png where yellow is clock, cyan is data. magenta, is output latch load, green is output. it works

Test3 is with the outputs alternated. it does not work. It is my understanding that spi clocks data in on the falling edge of the clock, and the waveform looks perfect for this interpretation. It just doesn't work..

From this I surmised that the chip wants to clock on the leading edge of the clock, so I built Test 2, which works just fine, but ignores the special capabilities of the P2.

so, my question is:
Can the SPI mode be adjusted to land the clock in the middle of the data? or switch edges?

Comments

  • RaymanRayman Posts: 15,806

    Hmm... There is a polarity inversion flag in the smartpins. Maybe that would fix it?

  • R BaggettR Baggett Posts: 217
    edited 2025-11-10 18:34

    @Rayman said:
    Hmm... There is a polarity inversion flag in the smartpins. Maybe that would fix it?

    I figured out how to do the inversion, (perhaps not the only possibility, is there a better one??). It shifts the change of the next bit of the dat to about 38 nS after the positive clock, i think the chip doesn't like that... it's just not that fast.
    Here is what I tried in jm_ez_spi:

    Perhaps I have misapplied ez_spi here, since this isn't really spi...

    Thanks!

  • JonnyMacJonnyMac Posts: 9,517
    edited 2025-11-10 18:57

    Can the SPI mode be adjusted to land the clock in the middle of the data? or switch edges?

    You might try inverting the clock pin to switch edges. I do that in my flash at the suggestion of others to create fewer issues with the onboard SD card (which I don't use).

      m := p_pulse | p_oe | p_invert_output                         ' spi clock (mode 3)
      x.word[0] := 2 #> (clkfreq / (khz * 1_000)) <# $FFFF          ' ticks in period
      x.word[1] := x.word[0] >> 1                                   ' ticks in low cycle (50%)
      pinstart(SF_SCLK, m, x, 0)
    

    ...the chip wants to clock on the leading edge of the clock...

    It does.

    The object you cite is very old, and I don't think I ever deployed it in any of my own projects (except that flash driver).

    Given the speed of the P2, you could go straight Spin. I run at 200MHz and this Spin code will output at about 600kHz

    con
    
      MOSI = 32
      SCLK = 33
    
      #0, LSBFIRST, MSBFIRST
    
    
    pub shiftout(mode, value, bits)
    
      if (mode == MSBFIRST)
        value rev= (bits-1)
    
      repeat bits
        pinwrite(MOSI, value & 1)
        pinhigh(SCLK)
        pinlow(SCLK)
        value >>= 1
    
      pinlow(MOSI)
    

    Of course, it will slow down a bit if you want to use variable pin numbers. Here's the output of $CF in MSBFIRST mode

    If you have the need for speed, you can use inline assembly. Honestly, this is what I do most of the time for SPI devices. Bit-banging is assembly is often less code than dealing with smart pins.

    con
    
      HCTIX = ((CLK_FREQ / 5_000_000) >> 1) - 10 
    
      MOSI = 32
      SCLK = 33
    
      #0, LSBFIRST, MSBFIRST
    
    
    pub fast_shiftout(mode, value, bits) 
    
      org
                            testb     mode, #0              wc
            if_c            rev       value
            if_c            rol       value, bits
    
    .loop                   testb     value, #0             wc
                            drvc      #MOSI
                            waitx     ##HCTIX
                            drvh      #SCLK
                            waitx     ##HCTIX
                            drvl      #SCLK
                            shr       value, #1
                            djnz      bits, #.loop
    
                            drvl      #MOSI
      end
    

    It's a little trickier using variable pins with inline code -- though you could pass your MOSI and SCLK pins as parameters. If they're constants you can see it's no trouble. The half-cycle clock timing is tuned to get closer to the target of 5MHz.

  • Jon,

    I think you are absolutely right. My Test2 data above was originally almost exactly like your Spin example above... it was too fast for the TPIC6595 and I had to add delays to get it to work!
    That solution is perfectly adequate, and is as you said much shorter than the smartpin version. Just not as cool... and I am still done with all 8 bits in < 12 uS (Using FlexProp).

    Thanks!

Sign In or Register to comment.