Shop OBEX P1 Docs P2 Docs Learn Events
serial synchronous — Parallax Forums

serial synchronous

Hope I did this right.
Instead of using smart pins I have been trying to port this over to spin2.

{{


  • Propeller SPI Engine ... Spin Version v1.0 *
  • Author: Beau Schwabe *
  • Copyright (c) 2009 Parallax *
  • See end of file for terms of use. *

Revision History:
V1.0 - original program

}}
CON

#0,MSBPRE,LSBPRE,MSBPOST,LSBPOST                    '' Used for SHIFTIN routines

''    
'' =0 =1 =2 =3
''
'' MSBPRE - Most Significant Bit first ; data is valid before the clock
'' LSBPRE - Least Significant Bit first ; data is valid before the clock
'' MSBPOST - Most Significant Bit first ; data is valid after the clock
'' LSBPOST - Least Significant Bit first ; data is valid after the clock

#4,LSBFIRST,MSBFIRST                                '' Used for SHIFTOUT routines

''  
'' =4 =5
''
'' LSBFIRST - Least Significant Bit first ; data is valid after the clock
'' MSBFIRST - Most Significant Bit first ; data is valid after the clock

VAR long ClockDelay,ClockState

PUB start(_ClockDelay, _ClockState)
ClockState := _ClockState
ClockDelay := ((clkfreq / 100000 * _ClockDelay) - 4296) #> 381

PUB SHIFTOUT(Dpin, Cpin, Mode, Bits, Value)
dira[Dpin]~~ ' make Data pin output
outa[Cpin] := ClockState ' set initial clock state
dira[Cpin]~~ ' make Clock pin output

if Mode == 4                'LSBFIRST
   Value <-= 1                                       ' pre-align lsb
   repeat Bits
     outa[Dpin] := (Value ->= 1) & 1                 ' output data bit
     PostClock(Cpin)         

if Mode == 5                'MSBFIRST
   Value <<= (32 - Bits)                             ' pre-align msb
   repeat Bits
     outa[Dpin] := (Value <-= 1) & 1                 ' output data bit
     PostClock(Cpin)

PUB SHIFTIN(Dpin, Cpin, Mode, Bits)|Value

dira[Dpin]~                                           ' make dpin input
outa[Cpin] := ClockState                              ' set initial clock state
dira[Cpin]~~                                          ' make cpin output


Value~                                               ' clear output 


if Mode == 0                'MSBPRE
   repeat Bits
     value := (Value << 1) | ina[Dpin]
     PostClock(Cpin)

if Mode == 1                'LSBPRE
   repeat Bits +1
     Value := (Value >> 1) | (ina[Dpin] << 31)
     PostClock(Cpin)
   value >>= (32 - Bits)

if Mode == 2                'MSBPOST
   repeat Bits
     PreClock(Cpin)
     Value := (Value << 1) | ina[Dpin]

if Mode == 3                'LSBPOST
  repeat Bits + 1
    PreClock(Cpin)
    Value := (Value >> 1) | (ina[Dpin] << 31) 
  Value >>= (32 - Bits)


return Value

PUB PostClock(_Cpin)
waitcnt(cnt+ClockDelay)
!outa[_Cpin]
waitcnt(cnt+ClockDelay)
!outa[_Cpin]

PUB PreClock(_Cpin)
!outa[_Cpin]
waitcnt(cnt+ClockDelay)
!outa[_Cpin]
waitcnt(cnt+ClockDelay)

I would like to do this with this as is prior to learning to do this with the smart pins, not in pasm2 but in spin2 then translate it to pasm2 with a clear understanding of that I am doing.
First application is the sparkfun load cell amp.
https://www.sparkfun.com/products/13879
unfortunately all I get is Arduino libraries. I want to do it from scratch. Only way to learn.
Thanks in advance.
Martin.
P1 was much easier.

└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
}}

Comments

  • What am I missing?
    Thanks

  • JonnyMacJonnyMac Posts: 8,923
    edited 2023-01-30 05:19

    In my Spin1 driver for that device I read it with this method

    pub read
    
    '' Read HX711 sensor
    '' -- verify device is ready before calling
    
      if (mode == MD_PWRDN)
        return 0
    
      repeat 24                                                     ' get reading
        outa[cpin] := 1                                             ' clock a bit
        outa[cpin] := 0
        result := (result << 1) | ina[dpin]                         ' read it (msbfirst)
    
      result <<= 8                                                  ' extend sign from bit23 to bit31
      result ~>= 8
    
      repeat gain                                                   ' set gain for next read
        outa[cpin] := 1
        outa[cpin] := 0
    

    It I were to do a direct translation to Spin2 it would look like this:

    pub read() : result
    
    '' Read HX711 sensor
    '' -- verify device is ready before calling
    
      if (mode == MD_PWRDN)
        return 0
    
      repeat 24                                                     ' get reading
        pinhigh(cpin)                                               ' clock a bit
        pinlow(cpin) 
        result := (result << 1) | pinread(dpin)                     ' read it (msbfirst)
    
      result signx= 23                                              ' extend sign from bit23 to bit31  
    
      repeat gain                                                   ' set gain for next read
        pinhigh(cpin) 
        pinlow(cpin) 
    

    Though much faster than Spin1, we can go even faster with SPI using inline assembly -- this is what I did in my P2 driver for the HX711

    pub read() : result | c, d, g, m, t 
    
    '' Read HX711 sensor
    '' -- verify device is ready before calling
    
      if (mode == MD_PWRDN)
        return 0
    
      longmove(@c, @cpin, 5)                                        ' copy parameters
    
      org
                    rep       #6, #24                               ' get reading  
                     drvh     c                                     ' clock a bit   
                     waitx    t
                     drvl     c
                     waitx    t
                     testp    d                             wc      ' read bit
                     rcl      result, #1                            ' add to result (MSBFIRST)
    
                    shl       result, #8                            ' extend sign from bit23 to bit31   
                    sar       result, #8
    
                    rep       #4, g                                 ' set gain for next read    
                     drvh     c
                     waitx    t
                     drvl     c
                     waitx    t
      end
    

    I haven't worked with this code in a while. When I get time to clean it up and document it, I will remove the locals and replace the longmove with

      setregs(@cpin, $1D8, 5)
    

    This will move my configuration variables to cog registers pr0..pr4.

  • AribaAriba Posts: 2,682
    edited 2023-01-30 05:10

    @pilot0315 said:
    What am I missing?
    Thanks

    Most important thing you miss: The load cell amp board uses I2C (two wire) and not "serial synchronous" (SPI). So porting this object does not make any sense for that project.
    I'm pretty sure there are some JM_... objects for I2C and SPI in the Github-Obex.

    If the above code is the version you have ported to Spin2, then you miss for example that the rotate operators have changed:

    ->   is now:  ROR
    <-   is now:  ROL
    

    The compiler will tell you that, and maybe other things you need to change for Spin2. There are threads about the differences of Spin1 and Spin2.

    Andy

  • JonnyMacJonnyMac Posts: 8,923
    edited 2023-01-30 04:54

    I have one of those boards, Andy (from a work project a couple years ago) -- it is SPI, even though the board markings might suggest I2C. See the code snippets in my post above.

  • AribaAriba Posts: 2,682

    @JonnyMac said:
    I have one of those boards, Andy (from a work project a couple years ago) -- it is SPI, even though the board markings might suggest I2C. See the code snippets in my post above.

    Oh, my bad. I should have read the description a little more carefully. Just saw that I2C is mentioned, but that is for a different board.

    Andy

  • question?

    I basically understand the input suggestion but I am now trying to replecate in spin2 the output.

    repeat Bits
    outa[Dpin] := (Value <-= 1) & 1 ' output data bit
    PostClock(Cpin)

    value <<=(32-bits)
    repeat 24
    outa(dpin) := (value <-= 1) & 1
    waitms(10)
    !outa(_cpin)
    waitms(10)
    !outa(_cpin)

        pinwrite(dpin,bits)    "I am trying to use this as the output to talk to the chip "output data bit"
    

    as above in the spin1 example. Looking throught the spin2 manual and find nothing.
    Any help appreciated.
    Thanks in advance.
    Martin

  • JonnyMacJonnyMac Posts: 8,923
    edited 2023-04-02 04:17
    pub shift_out(value, bits)                                      ' msb first
    
      value ror= bits                                               ' move msb to bit31
    
      repeat bits
        pinwrite(dpin, value rol= 1)                                ' get & write msb bit
        pinhigh(cpin)                                               ' clock it
        pinlow(cpin)
    
  • Got it.

Sign In or Register to comment.