Shop OBEX P1 Docs P2 Docs Learn Events
Need object - talking to DAC / ADCs using machine code — Parallax Forums

Need object - talking to DAC / ADCs using machine code

BitsBits Posts: 414
edited 2012-03-15 18:32 in Propeller 1
I am talking to an assortment of DACs and ADCs using spin, but the speed is now lacking. I was wondering if there is an object that is written in machine code to allow me to gather data from these devices?

Comments

  • JonnyMacJonnyMac Posts: 9,197
    edited 2012-03-15 08:15
    As each device has its own interface requirements you'd have to be more specific. Assembly is certainly not my first language and yet I have been able to write the code I need when speed is an issue. In your case you would like need construct a program that allows you to pass a command to it; this command would dictate which ADC channel to read or DAC channel to write. It takes a bit of time to code but is not difficult.
  • BitsBits Posts: 414
    edited 2012-03-15 08:37
    Okay so I found thisobject that should work, Beau Schwabe SPI Assembly - Serial Peripheral Interface . I just cant seem to get it to function correctly.

    Here the code I am running at the moment in spin.
    PUB GetA2D(in):out 
    
    
      outa[ CS ]~                                      
      SHIFTOUT(01_0111)      
      Out := SHIFTIN            
      outa[ CS ]~~ 
    
    PUB ShiftOut(in)  
                                          
      outa[ DClk ] := 0                                          
      REPEAT 8                                                               
          outa[ Din ] := in >> (7)                          
          in := in << 1                               
          outa[ DClk ] := 1                                                   
          outa[ DClk ] := 0    
    
    
             
    PUB ShiftIn: out | Temp
                                                            
      REPEAT 16
          outa[ DClk ] := 1                                                                 
          outa[ DClk ] := 0                                           
          Temp := ina[ Dout ]                                                     
          out := (out << 1) + Temp
    
    
    

    This is my code attempt using the machine code object.
    
      dira[CS]~~  
      outa[CS]~~
      adc.start(15,0)
      
      outa[CS]~  
      adc.SHIFTOUT(Dout, Dclk, 2, 8, 01_0111)      
      out := adc.SHIFTIN(Din, Dclk,2, 16)
      outa[CS]~~ 
    

    Can you see what I am doing wrong?
  • Mark_TMark_T Posts: 1,981
    edited 2012-03-15 09:16
    The object you quote is the wrong one - the non-PASM version - you want the one with filename starting "SPI_Asm_DEMO" - obex entry 431, not 433...

    You'll also have to check the parameters to Start are OK - the clock delay and state - might need to read through the code to see what they mean (or vary them till it works!)
  • BitsBits Posts: 414
    edited 2012-03-15 09:17
    Solved!

    Thanks fellas.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-03-15 09:56
    FYI, Beau's PASM SPI driver has a feature that lets you set the speed of the clock. This feature reduces the maximum clock speed possible. If you remove all the delay code, the object runs much faster.

    My nRF24L01+ Nordic transceiver object (listed in second post of my index) uses a SPI driver without the delays. I can't recall how fast it is but I'm pretty sure it's at least twice as fast as using Beau's SPI driver (I think it's more like four times as fast).

    Beau's driver also includes some other features that slow it down like setting the pin numbers with each call to a method.

    Many of the chip specific SPI drivers in the OBEX (that use PASM for SPI communication) don't have these same delays and should be fast right out of the box.
  • BitsBits Posts: 414
    edited 2012-03-15 10:59
    Can I use the object to run many devices or do I have to keep calling a new object for each device?
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-03-15 11:37
    Bits wrote: »
    Can I use the object to run many devices or do I have to keep calling a new object for each device?

    You can use the same object to read several devices. You'd just need to make sure two different cogs called the object at the same time (I'm not sure what would happen, but I think one of the calls wouldn't receive the correct data).

    Using it for multiple devices is where Beau's object shines, since you assign pin numbers as part of the call you can use the same object with a bunch of different devices.

    There are a few SPI devices that require data being written at the same time as they are read. Beau's object does do full-duplex SPI (reading and writing with the same clock pulses). I haven't used any SPI devices that have needed a full-duplex driver but I know other forum members have.
  • Mark_TMark_T Posts: 1,981
    edited 2012-03-15 17:39
    Duane Degn wrote: »

    There are a few SPI devices that require data being written at the same time as they are read. Beau's object does do full-duplex SPI (reading and writing with the same clock pulses). I haven't used any SPI devices that have needed a full-duplex driver but I know other forum members have.

    The nRF24L01+ uses duplex SPI, BTW (the status is returned on every access). I think, IIRC, that some bits in the status register are cleared when you do an explicit read of the status register, but when the status is returned simultaneous to every command this clearing doesn't happen.

    Back to DACs/ADCs - some of these devices (successive approximation ADCs) specifically require a slow-enough SPI clock to function correctly, note (the popular MCP3204/8 family being one case). So be careful not to overoptimize the clock speed without checking the datasheet!
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-03-15 18:32
    Mark_T wrote: »
    The nRF24L01+ uses duplex SPI, BTW (the status is returned on every access).

    Yes, but you can get by without it. I decided it wasn't worth the bother of trying to read it while writing.


    The nRF24L01+ datasheet says you're supposed to write a $FF whenever you read from it. Just setting the MOSI high while you read does the trick, but I don't think it would really matter (in this particular case) if you wrote all zeros or something else.

    Someone on the forum had a device that required duplex SPI, it wasn't just an option. I don't recall the details.

    I think Beau added the variable delay to his SPI driver to allow it to be adjusted to the various clock speeds SPI devices use.
Sign In or Register to comment.