Shop OBEX P1 Docs P2 Docs Learn Events
Need help with first asm program (playstation controller object)-problem fixed, — Parallax Forums

Need help with first asm program (playstation controller object)-problem fixed,

bulkheadbulkhead Posts: 405
edited 2007-09-04 00:07 in Propeller 1
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!

obj


var
        long ID, ThumbL, ThumbR, Status, JoyRX, JoyRY, JoyLX, JoyLY
        long cog
con
    start  = %00000001  '0x01
    getDat = %01000010  '0x42
    
pub startUp(ddat, cmd, att, clk)  

    clkPin:=clk
    attPin:=att
    cmdPin :=cmd  
    datPin:=ddat
    
    'INIT
    outa[noparse][[/noparse]attPin]~~ 'deselect PSX controller
    outa[noparse][[/noparse]cmdPin]~
    outa[noparse][[/noparse]clkPin]~~ 'release clock 
    dira[noparse][[/noparse]attPin]~~
    dira[noparse][[/noparse]cmdPin]~~
    dira[noparse][[/noparse]clkPin]~~
    dira[noparse][[/noparse]datPin]~
   
  
    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
  result:=Status
PUB getID
  result:=ID
PUB getThumbL
  result:=ThumbL
PUB getThumbR
  result:=ThumbR
PUB getJoyRY
  result:=JoyRY
PUB getJoyRX
  result:=JoyRX
PUB getJoyLY
  result:=JoyLY
PUB getJoyLX
  result:=JoyLX
dat
              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[noparse][[/noparse]attPin]~    'select controller
   
  PSX_TxRx(constant(start))        'send "start"   
  ID:=PSX_TxRx(constant(getDat))   'send "get data"  and save controller type
  outa[noparse][[/noparse]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[noparse][[/noparse]attPin] ~~ 'deselect controller

PUB PSX_TxRx(psxOut)[img]http://forums.parallax.com/images/smilies/tongue.gif[/img]sxIn |idx
  repeat idx from 0 to 7
    outa[noparse][[/noparse]cmdPin]:= (((psxOut>>idx)&1)==1)
    outa[noparse][[/noparse]clkPin]:=clockMode
    psxIn&= !(1<<idx)
    if(ina[noparse][[/noparse]datPin])
      psxIn |= (1<<idx)
    outa[noparse][[/noparse]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

Comments

  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-09-03 03:53
    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
    Propeller Applications Engineer

    Parallax, Inc.
  • bulkheadbulkhead Posts: 405
    edited 2007-09-03 03:53
    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
  • bulkheadbulkhead Posts: 405
    edited 2007-09-04 00:07
    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!
Sign In or Register to comment.