SPI for LTC2664 in PASM

I am trying to control this 4 channel A>D converter using the SPI protocol. I have successfully used the SPIN version written by Ryan David to control this chip, it works great. http://obex.parallax.com/object/375 Unfortunately it is too slow for my needs. I have tried the PASM version written by Beau Schwabe, but I can't see a way for it to properly toggle the chip select pin. I have never done any asm programming on the Propeller, so I would be grateful for a code snippet or other advice and instructions.


This is the code that works properly in SPIN:

  byte CS, SCK, SDI

PUB Init(inCS, inSCK, inSDI)
  CS := inCS
  SCK := inSCK
  SDI := inSDI  

  outA[CS] := 1 
  outA[SCK] := 0

PUB Set(Value) | data
  data := Value
  data ><= 24

  outa[CS] := 0

  repeat 24
    outa[SDI] := data & 1
    outa[SCK] := 1
    outa[SCK] := 0
    data >>= 1

  outA[CS] := 1


  • Link the PASM version?
  • Mark_T wrote: »
    Link the PASM version?


    Thanks for the response Mark_T
  • T ChapT Chap Posts: 4,000
    edited 2018-11-04 - 14:44:43
    I recently took some spin code and converted it with fastspin and with the -w option and it works great to convert to an identical SPIN object. There are several ways to convert it, I used fastspin -w myspinfile.spin and then you have a PASM object you can launch from your main program. This takes a little effort as you have to convert it using the terminal in windows. First you have to learn how to change directory \cd to get the folder you have both your spin files and also you must put fastspin.exe inside that folder. Your spin version may not have any delays in it and the PASM versin may run too fast, I had that issue with an SPI driver and had to go to the SPIN file and add delays after many instructions that toggle pins. I used waitcount(delay + cnt) then you can control the delay time as needed to get things working. Anyone wanting speed from PASM and don't want to invest time in learning how to rewrite it should spend an afternoon figuring this out. One issue is that a file in SPIN may become larger in PASM due to how it converts. You'll find out if its too large after you try to compile the final output. In which case I had to go back the SPIN file and start consolidating redundant code into reusable blocks. When you download the zip file it may contain various files but you only need the file fastspin.exe, drag it in your main SPIN folder. I would start with a simple test code before trying to run your SPI code, just to figure out how to find the folder, run the command line, find the output myconvertedfile.cog.spin and put that into a main program and launch it as a cog. You have options to make the new PASM callable from your main program or it can be a freestanding program that does it's own thing. If you need to communicate back and forth with the new PASM program you may have to send it commands via setting values from your main program, then the PASM code reads in those values and acts based on what value you sent it. The PASM code will see the values in this format long[somecommand1]. At least using the -w method of compile this is how I have to talk back and forth to the PASM code.
  • T ChapT Chap Posts: 4,000
    edited 2018-11-04 - 15:36:41
    Without making any changes to your code, I ran fastspin using two methods. fastspin testconvert.spin and fastspin -w testconvert.spin. You can see the two different output types. The file called testconvert.cog.spin is from the -w version. These pulses may be too fast to work though, as your SPI device has a minimum pulse length that may need to be considered. Also other factors such as a time required from setting chip select to sending the first clock or sending the first data byte. What I did was take a scope and run the code full speed and look at the pulses. Then look at the data sheet and make sure your timing is not faster than the device allows. If you don't want to bother with a scope then just add delays after every pin toggle and raise the delay to some number that gets it to work. Hint: create a PUB called DELAY and put waitcount(delaytime + cnt), set delaytime in CON.

    I didn't study your code at all but you may try to cognew, init, setup using the -w testconvert.cog.spin version and see if anything happens.

    SPI : "testconvert.cog.spin" put in OBJ section

    In your main program start the cog with
    SPI.Init(Incs, Insck, Insdi) ' send the pins
    SPI.Set(Value) ' put in a value to send

    BTW it took about 30 seconds to make these files:

    CD\ to the folder
    launch terminal prompt
    type fastspin -w testconvert.spin

    It outputs the converted file in less than a second. You can see how I launched it in the terminal.
  • Thanks T Chap! That worked here and with enough speed improvement to allow me to carry on with my work. To me this is amazing in many ways. First that I was able to follow the directions and get the code converted on the first try. Second that such a conversion program exists at all!

    After a brief bit of experimenting I am pretty sure I don't have any timing issues. The LTC2664 data sheet specifies the SPI clock rates up to 50MHz. I have a really neat scope, a Siglent SDS1202X-E that has a mode to decode SPI data streams, made it easy to ensure I was assembling the code words correctly.

    Fastspin does generate a large amount of code, that doesn't concern me at this stage. After I get the entire application working I will hopefully write an efficient PASM routine to to this simple SPI job.

    Thanks so much for the information you shared and your time, very much appreciated!

Sign In or Register to comment.