4

I am trying to program a PLL device with SPI on the RPI using spidev inside Python. I want to rewrite all the values inside the registers on the AD9553 device to allow for a very specific configuration. So far I have calculated all the necessary values to store in the registers for my specific configuration, I have kept these binary values in an array ready to send later. First an instruction bit must be sent to the device defining whether you would like to read or write and if you want to operate in streaming mode, in this case yes as I want to start from register 0x34 and end at 0x00 rewriting all registers in the process. The device should theoretically receive the 16 bit instruction command and then receive the successive 52 - 8 bit commands successively buffering them in the register, I then administer an I/O update in register 5 causing the registers to be loaded thus taking into effect. I am confident that these register values are correct.

However I have some significant doubts: 1) At the moment I am using "Xfer2()" to transfer the bytes from the PI to the device, I dont know if this is the correct command since there is write bytes and "Xfer()" as well. 2) It seems the PI is transmitting from the MOSI pin this is connected to the SDIO pin on the AD9553, I am not completely sure how this works. 3) I do not understand the syntax in Spidev I have read through the documentation and the code but it does not seem to clear up any doubts 4) I am using a for loop in Python to transfer all the bytes from the Reg_Store array to the device (not sure if this is the correct approach) 5) I am not sure what to set for the parameters of the SPI device i.e (threewire mode, max clock speed, etc)

Methods I have approached 1) Splitting up the instruction into two 8 bits and then sending all 52 register after (inside a for loop) 2) Forcing the Chip Select to Low in the loop 3) Messing around with spi.max_speed 4) Trying to send the entire list of values in one line 5) writebytes and xfer

I have previously used Spidev to communicate with an ADC, however it was far easier as you just sent two bytes and then you would receive back the two bytes of information, like a shift register. This works so I know I do not have a problem with my Pi or the SPI.

I am hoping someone with experience will be able to point out directly what I am doing wrong, I look forward to receiving replies.

The datasheet is below and attached is my code.

http://www.analog.com/media/en/technical-documentation/data-sheets/AD9553.pdf

Many Thanks for reading this.

    #!/usr/bin/env python

import RPi.GPIO as GPIO
import time
import sys
import spidev
import Tkinter

# Setup
SendDataLED = 11
FinishLED = 13
ChipSel = 24
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(FinishLED, GPIO.OUT)
GPIO.setup(SendDataLED, GPIO.OUT)
GPIO.setup(ChipSel, GPIO.OUT)
High = GPIO.HIGH
Low = GPIO.LOW
spi = spidev.SpiDev()
spi.open(0,0) # Open an SPI port bus = 0 , device = 0

print spi.mode
#spi.max_speed_hz = 100000 
#spi.threewire()
# Setup Complete

# Constants and Variables
Nil = 0b00000000
R = [None]*53 #0x34 down to 0x00
R[52] = 0b01101000 #0x34 Val ? 
R[51] = Nil #0x33
R[50] = 0b10101001 #0x32
R[49] = Nil #0x31
R[48] = Nil #0x30
R[47] = Nil #2F
R[46] = Nil #2E
R[45] = Nil #2D
R[44] = Nil #2C
R[43] = Nil #2B
R[42] = Nil #2A
R[41] = 0b01100000 #0x29
R[40] = Nil #0x28
R[39] = 0b01000000 #0x27
R[38] = Nil #0x26
R[37] = 0b10100000 #0x25
R[36] = 0b01100010 #0x24
R[35] = 0b00001001 #0x23
R[34] = Nil #0x22
R[33] = 0b10100000 #0x21
R[32] = 0b01100010 #0x20
R[31] = 0b00001001 #0x1F
R[30] = Nil #0x1E
R[29] = Nil #0x1D
R[28] = Nil #0x1C
R[27] = 0b10000000 #0x1B
R[26] = Nil #0x1A
R[25] = Nil #0x19
R[24] = 0b00100000 #0x18
R[23] = 0b01110101 #0x17 Starred
R[22] = 0b11000000 #0x16
R[21] = 0b00000001 #0x15
R[20] = 0b00001100 #0x14 Starred
R[19] = 0b01000101 #0x13
R[18] = 0b00110011 #0x12
R[17] = Nil #0x11
R[16] = 0b10000000 #0x10
R[15] = 0b10000000 #0x0F
R[14] = 0b01110000 #0x0Ev Starred
R[13] = Nil #0x0D
R[12] = Nil #0x0C
R[11] = 0b10110000 #0x0B Starred
R[10] = 0b10000000 #0x0A
R[9] = Nil #0x09
R[8] = Nil #0x08
R[7] = Nil #0x07
R[6] = Nil #0x06
R[5] = 0b00000000 # I/O UPDATE Starred needs to be sent last?? (R[5]:x) 
R[4] = 0b00000001 # Readback Control Starred
R[3] = Nil #0x03
R[2] = Nil #0x02
R[1] = Nil #0x01
R[0] = 0b00011000 #0x00 SPI Control Starred
# End of Constants declarations

def IOUpdate(MSB_First):
#Send the instruction to initiate I/O update
  if (MSB_First == True):
    IOUpdateInstr = 0b0000000000000101 #16 Bit instruction for IO Update    
    XFER_IO = spi.xfer2([IOUpdateInstr])
    R[5] = 0b00000001 # set the I/O update bit high
    IO = spi.xfer2([R[5]]) # Send the register
    print "IO Updated with MSB First"
  elif (MSB_First == False):
    IOUpdateInstr = 0b1010000000000000 #16 Bit instruction for IO Update    
    XFER_IO = spi.xfer2([IOUpdateInstr])
    R[5] = 0b10000000 # set the I/O update bit high
    IO = spi.xfer2([R[5]]) # Send the register
    print "IO updated with LSB First"

# ********** Program begin *************

##Initiate = raw_input("Enter 'go' to start the transfer: ")
##if (Initiate == "go"):
##    print "Initiating Transfer"

# Define some instructions
Instr = 0b0110000000110100 #16 Bit Instruction for loading all registers
InstrCut1 = 0b01100000
InstrCut2 = 0b00110100
IOUpdateInstr = 0b0000000000000101 #16 Bit instruction for IO Update
IOUpdateCut1 = 0b00000000
IOUpdateCut2 = 0b00000101

Buffer = [None]*55
Buffer[0] = InstrCut1 #first element is instruction
Buffer[1] = InstrCut2
#print len(Buffer) 
for i in range(54,1,-1):
  #print "Buffer: " + str(56-i) + " Register: " + str(i-2)
  Buffer[56-i] = R[i-2]

Buffer.append(IOUpdateCut1) # append the IO update instruction bit
Buffer.append(IOUpdateCut2)
Buffer.append(0b00000001) # send the new register value to invoke the io update

print Buffer

#print Buffer[0]
#print Buffer[55]

#print "Buffer element: " + str(Buffer[1])
#print "Register element: " + str(R[0])

GPIO.output(ChipSel, Low)
for i in range(0,len(Buffer)):
  #print Buffer[i]
  GPIO.output(ChipSel, Low)
  XFER = spi.xfer2([Buffer[i]])
  GPIO.output(ChipSel, Low)
  #time.sleep(0.1)
GPIO.output(ChipSel, High)

print " \nComplete"

#print R


print "End Program"
spi.close() # closes the comms link with the SPI Device
  • I doubt you should be mucking about with the chip selects, the driver should do that for you. A link to the datasheet would be useful. Not everyone likes to Google. – joan Nov 25 '15 at 16:09
  • Yes, I have tried combinations of with and without the SPI CS line, either way it does not make a difference to the waveform. The only thing I can observe is that when I add a delay into the loop (which extends the SPI transfer time) the output waveform shakes during this cycle then turns back to normal, I do not know what this means. – Renegade243 Nov 25 '15 at 16:54
  • 1
    Reading the data sheet suggests you need to send the 16 bit command and all the 8 bit data in one SPI call. Whether you use SPI write or SPI xfer should not matter. The only issue seems to be it is a 3-wire device rather than the normal 4-wire device. You ought to update your question to include the datasheet link (I know you have added that in a comment) and the conections you have made between the Pi and the device. The standard Linux driver does not support 3-wire (although the underlying hardware does). – joan Nov 25 '15 at 17:10
  • Ok, how could I go about doing this all in one call? As for the possibility of SPI comms with analog device chips, it is plausible as a Post Doc recommended this method and using Spidev; quote his words "Easy". Unfortunately he has gone on a work meeting abroad therefore I can not contact him. – Renegade243 Nov 25 '15 at 17:16
1

Ok, Done it. With the help of a logic analyser. The problem was that the device was not decrementing from register 0x34 to 0x00 i.e (streaming mode). In the end I manually wrote commands to every register using the array I had and just calling a new instruction every time. I looked at the way it was done on the eval board and the sort of signals the USB was sending - it seemed to indicate it did not use the stream functionality either.

Thank you for your help Joan, I would not have identified that I had a faulty SPI wrapper without you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.