View Full Version : Need help with first asm program (playstation controller object)-problem fixed,

09-03-2007, 10:36 AM
Edit: See post #4, I forgot to initialize "addressStatus" so it was trying to put the Status byte into address 0, which I guess affected cog 0 since it stopped running.

This is a follow up from this thread http://forums.parallax.com/showthread.php?p=668706 where I was attempting to get the propeller to receive data from a playstation controller fast enough (presumably) so that it would be able to communicate with wireless controllers as well as wired ones.

This is my first attempt at writing code in propeller assembly, and not surprisingly, it doesn't work! When I run my simple 'test' program using the prop terminal and attempt to print one of these object's button states, my prop completely locks up. I am guessing that it is some memory allocation/usage issue, since if I do not call the "cognew" method in the object, the test program runs fine (I have it printing the # of iterations through its main loop so far). However, with the "cognew" call in the playstation controller object, the test program is stuck displaying "0 iterations".

Here is my code; if anyone could tell me what's wrong, I would greatly appreciate it. In particular, I would like to know:
1) Is my allocation of memory for the new cog done correctly?
2) Does my use of addressID, addressStatus, etc make sense/work?
3) How exactly does the "wrlong" command work? (What is PAR?)

Any other tips on improving this would help too. Below is the object and part of the SPIN version of the object (that the assemby code is trying to copy). I have also attached the object (assembly version) for easier viewing in the prop tool.

Complete object (w/ assembly code)

'' PS2 Controller Driver v1.2
' not working yet!


long ID, ThumbL, ThumbR, Status, JoyRX, JoyRY, JoyLX, JoyLY
long cog
start = %00000001 '0x01
getDat = %01000010 '0x42

pub startUp(ddat, cmd, att, clk)

cmdPin :=cmd

outa[attPin]~~ 'deselect PSX controller
outa[clkPin]~~ 'release clock

uS := clkfreq / 1_000_000
uS2 := 2 * uS

addressID := @ID
addressThumbL := @ThumbL
addressThumbR := @ThumbR
addressJoyRX := @JoyRX
addressJoyRY := @JoyRY
addressJoyLX := @JoyLX
addressJoyLY := @JoyLY

speed := clkfreq / 1000
if cog
cogstop(cog~ - 1)
cog := cognew(@psx, @ID) + 1

PUB getStatus
PUB getThumbL
PUB getThumbR
PUB getJoyRY
PUB getJoyRX
PUB getJoyLY
PUB getJoyLX
org 0
psx mov temp, #1 'initialize pin mask
shl temp, clkPin
mov clkPin, temp

mov temp, #1
shl temp, attPin
mov attPin, temp

mov temp, #1
shl temp, cmdPin
mov cmdPin, temp

mov temp, #1
shl temp, datPin
mov datPin, temp 'clkPin, attPin,cmdPin, datPin are now masks

loop mov tempID, #0 'clear old data
mov tempStatus, #0
mov tempThumbR, #0
mov tempThumbL, #0
mov tempJoyRX, #0
mov tempJoyRY, #0
mov tempJoyLX, #0
mov tempJoyLY, #0

mov attPin, #0 wz,nr 'set attn LOW to select controller
muxnz outa, attPin

mov psxOut, #start 'send 'start' command
call #psxTxRx

mov psxOut, #getDat 'send 'getDat' command, get ID
call #psxTxRx
mov tempID, psxIn

mov psxOut, #0 'clear command out byte for rest of transmission

call #psxTxRx 'get status
mov tempStatus, psxIn

call #psxTxRx 'get buttons
mov tempThumbR, psxIn
call #psxTxRx
mov tempThumbL, psxIn
call #psxTxRx

mov tempJoyRX, psxIn 'get joysticks
call #psxTxRx
mov tempJoyRY, psxIn
call #psxTxRx
mov tempJoyLX, psxIn
call #psxTxRx
mov tempJoyLY, psxIn

mov attPin, #0 wz,nr 'set attn HIGH to deselect controller
muxz outa, attPin

put_data wrlong tempID, addressID 'globalize datasets
wrlong tempStatus, addressStatus
wrlong tempThumbL, addressThumbL
wrlong tempThumbR, addressThumbR
wrlong tempJoyRX, addressJoyRX
wrlong tempJoyRY, addressJoyRY
wrlong tempJoyLX, addressJoyLX
wrlong tempJoyLY, addressJoyLY

mov time, cnt
add time, speed
waitcnt time, #0 'wait for next update period
jmp #loop

'************ Subroutine psxTxRx ************
' takes parameter: psxOut
' returns: psxIn
psxTxRx mov clkPin, #0 wz,nr 'use Z Flag for clk
mov psxIn, #0 'clear byte
mov reps, #8 'loop for 8 bits (1 byte)

txrxloop muxz outa, clkPin 'clk HIGH

test psxOut, #1 wc 'place bit from psxOut on cmdPin
muxc outa, cmdPin
shr psxOut, #1 'prep for next bit

muxnz outa, clkPin 'clk LOW

test datPin, ina wc 'read data bit
rcl psxIn, #1 'store bit in psxIn

djnz reps, #txrxloop
psxTxRx_ret ret

clkPin long 0 'pin masks
attPin long 0
cmdPin long 0
datPin long 0
temp long 0

psxOut long 0 'parameter/return for psxTxRx routine
psxIn long 0

tempID long 0 'temp data
tempStatus long 0
tempThumbL long 0
tempThumbR long 0
tempJoyRX long 0
tempJoyRY long 0
tempJoyLX long 0
tempJoyLY long 0

uS long 0 'helper stuff
uS2 long 0
time long 0
reps long 0
speed long 0

addressID long 0 'addresses of global data
addressStatus long 0
addressThumbL long 0
addressThumbR long 0
addressJoyRX long 0
addressJoyRY long 0
addressJoyLX long 0
addressJoyLY long 0

SPIN code (partial)

PUB Get_PSX_Packet
outa[attPin]~ 'select controller

PSX_TxRx(constant(start)) 'send "start"
ID:=PSX_TxRx(constant(getDat)) 'send "get data" and save controller type
outa[cmdPin]~ 'clear to zero for rest of packet

Status := PSX_TxRx(0) 'should be $5A ("ready")
ThumbL := PSX_TxRx(0) 'get PSX data
ThumbR := PSX_TxRx(0)
JoyRX := PSX_TxRx(0)
JoyRY := PSX_TxRx(0)
JoyLX := PSX_TxRx(0)
JoyLY := PSX_TxRx(0)

outa[attPin] ~~ 'deselect controller

PUB PSX_TxRx(psxOut)http://forums.parallax.com/images/smilies/tongue.gifsxIn |idx
repeat idx from 0 to 7
outa[cmdPin]:= (((psxOut>>idx)&1)==1)
psxIn&= !(1<<idx)
psxIn |= (1<<idx)
outa[clkPin]:= !clockMode

Just for reference, I started with CJ's gamecube controller object from the ObEx and, with the help of 'Assembly Code Examples for the Beginner' attempted to convert it to a playstation controller object. I included above the SPIN code that I basically attempted to convert to assembly.

I'm new to the propeller!

Post Edited (bulkhead) : 9/4/2007 12:10:42 AM GMT

Paul Baker
09-03-2007, 10:53 AM
Sigh, I just went to delete one of your posts and it seems you deleted the other, sorry for the mix up

It was a pretty long post, hopefully you have a copy you can cut and paste.

Paul Baker (mailto:pbaker@parallax.com)
Propeller Applications Engineer
[/url][url=http://www.parallax.com] (http://www.parallax.com)
Parallax, Inc. (http://www.parallax.com)

09-03-2007, 10:53 AM
I just realized too, my mistake....I will repost...

It's back up

I'm new to the propeller!

Post Edited (bulkhead) : 9/3/2007 3:59:25 AM GMT

09-04-2007, 07:07 AM
Well, I finally got this program working. I fixed all of the timing issues and tested it with two wired controllers, and the code works fine. The timing is REALLY close to what I got on my playstation (thanks to viewport!). Each half clock cycle is nearly exactly 2us long. Perhaps the only difference with this program and a real playstation is the time delay between bytes, which I have yet to set precisely.

However, it still does NOT work with my two wireless controllers! At this point, I do not thing it is a timing issue, but perhaps a "start sequence", or something to do with the "ACK" line which is currently unused.

Attached is the most recent version of the object, that works for wired controllers only.

I'm new to the propeller!