Assembly driver for ADIS15350
electric550
Posts: 122
Hello I am still trying to learn PASM and I am tyring to write a minimal assembly SPI driver for the ADIS16350...This has led to some bad code. The code is supposed to read the x axis gyro value but it is locking up...Any Suggestions would be great thanks!
Post Edited (electric550) : 8/8/2009 8:57:47 AM GMT
CON _clkmode = xtal1 + pll16x _xinfreq = 6_000_000 OBJ uarts : "pcFullDuplexSerial4FC" '1 COG for 4 serial ports VAR Long GX, GXV Pub ADIS16350 'Launch cog to start assembly PinTester uarts.Init uarts.AddPort(0,31,30,{ } UARTS#PINNOTUSED,UARTS#PINNOTUSED,UARTS#DEFAULTTHRESHOLD, { } UARTS#NOMODE,UARTS#BAUD115200) 'Add debug port uarts.Start 'Start the ports GX := $05 GXV := 00 uarts.str(0,string("Starting")) cognew(@SensorStart, @GX) repeat uarts.str(0,string("GyroTest:")) uarts.dec(0,GXV) uarts.tx(0,10) uarts.tx(0,13) waitcnt(clkfreq/10 + cnt) DAT '--------------------Read the Value from the Sensor------------------------------------- org 0 SensorStart OR DIRA, ADISout 'Set Appropriate Pins to Outputs ANDN DIRA, ADISDin 'Set Appropriate Pins to Inputs Sensor RDLONG R0, PAR 'Read in the Parameter to read from sensor OR OUTA, ADISCS 'Set CS High OR OUTA, ADISCLK 'Set Clk High CALL #Delay 'Delay MOV M1, #01 'Mov mask one ANDN DIRA, ADISCS 'Set CS low CALL #Delay 'Delay MOV Bits, NumberBits 'Set the number of bits to shift SHL R0, #08 'Shift right R0 so room for 16 clks 'This is where the write loop begins to write value to sensor register ClkOutWrite MOV R1, R0 'Mov Register value to temp ANDN outa, ADISCS 'Set clk low CALL #Delay 'delay for clock low SHR R1, Bits 'Shift the data right to put bit in LSB AND R1, M1 'Mask all upper bits TJNZ R1, #NZ 'Check to see if one or zero ANDN OUTA, ADISDout 'If it is zero write a 0 to DOout JMP NextBit 'Jmp over zero condition NZ OR OUTA, ADISDout 'If Value is not zero write a 1 NextBit OR OUTA, ADISCLK 'Set Clk High to clk out data CALL #Delay 'Delay while Clk is high SUB Bits, #01 'Decriment the shift amount TJNZ Bits, ClkOutWrite 'Fall through if done 'Continue if not yet finished 'This should be the end of the write part of the read command now time to read in value from sensor OR OUTA, ADISCS 'Set CS High CALL #Delay 'Delay CALL #Delay 'Delay ANDN DIRA, ADISCS 'Set CS low CALL #Delay 'Delay MOV SenVal, #00 'Clear SenVal MOV Bits, #16 'Set number of bits to shift CLKInRead MOV R0, #00 'Clear R0 ANDN outa, ADISCS 'Set clk low CALL #Delay 'Delay OR OUTA, ADISCLK 'Set Clk High to clk in data MOV R0, INA 'Read in Data AND R0, ADISDin 'Mask off other pins SHR R0, MaskShift 'Shift all the way to the right SHL R0, Bits 'Shift to proper position OR SenVal, R0 'Or with Previous data CALL #Delay 'Delay SUB Bits, #01 'Decriment the bit shifter TJNZ Bits, ClkOutWrite 'Fall through if done 'Loop MOV R1,par ' reset sample pointer ADD R1, #04 ' add offset WRWORD SenVal,R1 ' write sample backto mainram at GXV JMP #Sensor Delay MOV T1, CNT 'Delay waits 1000clk ticks ADD T1, OneThous WAITCNT T1, OneThous Delay_Ret RET 'use ANDN to set bit low, use OR to set bit high ADISout Long %00000000_11100000_00000000_00000000 'Value for 3 output pins Quick ADISDin Long %00000000_10000000_00000000_00000000 'Mask for Din P26 ADISClk Long %00000000_01000000_00000000_00000000 'Mask for CLk P25 ADISDout Long %00000000_00100000_00000000_00000000 'Mask for Dout P24 ADISCS Long %00000000_00010000_00000000_00000000 'Mask for Chip Select P23 MaskWrite Long %00000000_00010000_00000000_10000000 OneThous Long 1000 NumberBits Long 16 SenVal Long 00 MaskShift Long 23 ' MaskRead Long %00000000_00010000_00000000_00000000 all zero R0 RES 1 R1 RES 1 R3 RES 1 R4 RES 1 M1 RES 1 T1 RES 1 T2 RES 1 Bits Res 1 FIT 496
Post Edited (electric550) : 8/8/2009 8:57:47 AM GMT
Comments
JMP NextBit needs to be JMP #Nextbit
and TJNZ Bits, #ClkOutWrite
Output is ....
GyroTest:65534
GyroTest:65534
GyroTest:65534
GyroTest:65534
GyroTest:65534
GyroTest:65534
GyroTest:65534
GyroTest:65534
GyroTest:65534
GyroTest:65534
GyroTest:65534
GyroTest:65534
GyroTest:65534
GyroTest:65534
Post Edited (electric550) : 8/8/2009 9:22:12 PM GMT
The first line sets in/out/clk to an output,
2nd sets in back to an input
4th sets cs to high but its not an output - its still an input
5 sets clk high - its a output so it goes high
later you set cs back to an input - doyou have a pull down on the pin?
later you andn outa, dout - was it meant to set in/clk and dout low
also you have a line commented set clk low but it sets cs low - which is corret?
ANDN outa, ADISCS 'Set clk low
The first line sets in/out/clk to an output,
2nd sets in back to an input
4th sets cs to high but its not an output - its still an input
5 sets clk high - its a output so it goes high
"
>>>I think I got confused because the names are from the perspective of the sensor, not the prop I change the mask around a little the names are from the perspective of the Propeller now.
"Later you set cs back to an input - do you have a pull down on the pin?"
That was supposed to be an outa
>>>>No pull downs...I think the 5 to 3.3 volts is alright, but I assume you meant that due to the fact that i had things Reversed
"later you andn outa, dout - was it meant to set in/clk and dout low"
>>>Looks like I got confused with the names again
"also you have a line commented set clk low but it sets cs low - which is correct?
ANDN outa, ADISCS 'Set clk low"
>>>That was supposed to be CLK ...ANDN outa, ADISCLK
It is now outputing all zeros but that was definitely helpful Thanks! Here is the updated code.
Now it is outputting all zeros...
GyroTest:0
GyroTest:0
GyroTest:0
GyroTest:0
GyroTest:0
GyroTest:0
GyroTest:0
GyroTest:0
GyroTest:0
Even though it is not working yet that was very helpful, Thanks Again!, any other suggestions are appreciated!
ANDN DIRA, ADISCS 'Set CS low
on the 8th pasm line.
2. Also I haven't used the 16350 but I have the 16250 and found reading odd registers give prolems, I suggest yu change
GX := $05
to
GX := $04
3. Also from figure 3 timing diagram, the data is read by the chip on the falling edge of clk. and you dont have the 1st data output for the 1st falling edge.
4. also
If I am reading this correctly you are outputing msb first.
look at teh rev instruction you can reverse the bits
e.g. this reverses the 16 bits, rotates 1 bit into carry and sets adisout bit to the carry bit
note there is a probelm with adisdout having multiple bits set. but I think your code has the same problem
If you use the above instructions you can remove r1 and just use r0
I think you need 2 varibles adisdout with just the dout bit set and another with the dira bits sets.
6. Also I am attached my spin code for the 16250, this may help.
Post Edited (electric550) : 8/9/2009 1:21:40 AM GMT
I looked at the spec again I was wrong about the clk edge. dout is availble upto 100ns after falling edge s rising edge is the time to read it
Din needs to be stable 24.5ns before the rising edge so the chip is reading input on the rising ege.
CON
#1,_SHIFTOUT,_SHIFTIN
#0,mMSBPRE,mLSBPRE,mMSBPOST,mLSBPOST 'Used for SHIFTIN routines
#4,mLSBFIRST,mMSBFIRST
and I changed the names in send and receive to match.
Then When I run
I get
Starting
LoopStart
I dont think the 6MHz would cause a problem. I am not sure what it is I will have to take a look later.
there is a concern if its locking up in shiftout - its clking and reading without waiting for anything external so there shouldn't be a lock up. The only wait is in spi_engine waiting for the pasm code to return and it should always return. Check your shiftin/shiftout the 4th arg must not be 0 or the pasm code will stop its cog.
I would do a couple of things - double check dout/din pins, the data spec is with respect to the adis16350 but the driver is with respect to the prop so its confusing.
the other thing to try is change SPI#mMSBPOST in Receive to SPI#mMSBPRE (twice). Looking the spec it seems that the MSB output should be before the clk that shouldn't mean you see 0 though (but may explain the inconsistent output I have had).
I just looked through the code on the system that is running the adis16250 and the only thing it looks like I changed from the prop code is the reset procedure. I hold the adis16250 in reset for 100ms and wait 200ms after I take it out of reset before I access it. So you may want to try a waitcnt(clkfreq/10 + cnt) after the dira in the start routine of adis16250.
Spi.Start(2, 22, 20, 23, 21)
23 is into prop
21 is out of prop
but on your diag pin 5 is din on adis16350
so
Spi.Start(2, 22, 20, 21, 23)
and put a 1K resistor between pin 4 of adis16350 and pin 21 of prop rather than a direct connection
Output
Gyro:0
Gyro:0
Gyro:0
Gyro:0
Gyro:0
Gyro:0
Gyro:0
Gyro:0
Even though it is not working thanks again for the help!