Shop OBEX P1 Docs P2 Docs Learn Events
Controller Driver Isssues, What's Wrong? (CODE INCLUDED) — Parallax Forums

Controller Driver Isssues, What's Wrong? (CODE INCLUDED)

Sachiel7Sachiel7 Posts: 41
edited 2007-03-18 02:40 in Propeller 1
Hey guys,
I'm continuing progress on the Retrosys but I'm having trouble with my first self-programmed object, my controller driver.
To give you an idea of my hardware setup, I have a 16:1 Multiplexer accepting the inputs off of 2 DB9 ports, for SEGA Genesis controllers. The address and data lines are connected to the prop, and the prop also has an output to the controllers which I call CLK (some people call it SEL), which is basically used to access different 'packets' of data, if you will.
Without going into too much detail on the SEGA pinouts, here's my driver code:
''******************************
''* Retrosys Controller Driver *
''*       Version 1.0.1        *
''* (C) 2007 Shayne P. Helms   *
''******************************
CON
 A3      = 15 'MUX A3 Line
 A2      = 14 'MUX A2 Line
 A1      = 13 'MUX A1 Line
 A0      = 12 'MUX A0 Line
 CLK     = 11 'Controller CLK Line
 D       = 10 'MUX Data Line
 
VAR
 long cog
 long stack[noparse][[/noparse]10]
 long data 'Array for Holding Button Data
                           
PUB start : okay
''Start controller driver - starts a cog
''returns false if no cog available
 stop
 init
  if cog
    cogstop(cog~ - 1)   
  okay := cog := cognew(scan, @stack) + 1
  
PUB stop
''Stop controller driver - frees a cog
 if cog
  cogstop(cog~ - 1)
  
PUB init
''Setup the proper pin directions
DIRA[noparse][[/noparse]A3]~~
DIRA[noparse][[/noparse]A2]~~
DIRA[noparse][[/noparse]A1]~~
DIRA[noparse][[/noparse]A0]~~
DIRA[noparse][[/noparse]CLK]~~
DIRA[noparse][[/noparse]D]~
PUB scan | ctr, puls
''Scan the controller ports and update the data array
repeat
 puls := 0 'Pulse counter
 OUTA[noparse][[/noparse]CLK]~~
 OUTA[noparse][[/noparse]A3]~~
 OUTA[noparse][[/noparse]A2]~~
 OUTA[noparse][[/noparse]A1]~~
 OUTA[noparse][[/noparse]A0]~~
 repeat puls from 1 to 3 'PULSE
  ctr := 0
  repeat 2
   !OUTA[noparse][[/noparse]CLK]
   repeat 2
    !OUTA[noparse][[/noparse]A3]
    repeat 2
     !OUTA[noparse][[/noparse]A2]
     repeat 2
      !OUTA[noparse][[/noparse]A1]
      repeat 2
       !OUTA[noparse][[/noparse]A0]
       if puls << 3
        data[noparse][[/noparse]ctr] := !INA[noparse][[/noparse]D]
       if puls == 3 and ctr == 4
        data[noparse][[/noparse]0] := !INA[noparse][[/noparse]D]
       if puls == 3 and ctr == 5
        data[noparse][[/noparse]1] := !INA[noparse][[/noparse]D]
       if puls == 3 and ctr == 7
        data[noparse][[/noparse]2] := !INA[noparse][[/noparse]D]
       if puls == 3 and ctr == 10
        data[noparse][[/noparse]16] := !INA[noparse][[/noparse]D]
       if puls == 3 and ctr == 11
        data[noparse][[/noparse]17] := !INA[noparse][[/noparse]D]
       if puls == 3 and ctr == 13
        data[noparse][[/noparse]18] := !INA[noparse][[/noparse]D]
       ctr++
       waitcnt(clkfreq / 1000000 * 16 + cnt) 'delay 16 microseconds
  waitcnt(clkfreq / 1000 * 16 + cnt) 'delay 16 milliseconds for ~60Hz Freq.
  
PUB P1_ACTIVE
return data[noparse][[/noparse]20]
PUB P2_ACTIVE
return data[noparse][[/noparse]25]
PUB P1_UP
return data[noparse][[/noparse]7]
PUB P1_DOWN
return data[noparse][[/noparse]5]
PUB P1_A
return data[noparse][[/noparse]22]
PUB P1_START
return data[noparse][[/noparse]30]
PUB P2_UP
return data[noparse][[/noparse]13]
PUB P2_DOWN
return data[noparse][[/noparse]11]
PUB P2_A
return data[noparse][[/noparse]28]
PUB P2_START
return data[noparse][[/noparse]24]
PUB P1_LEFT
return data[noparse][[/noparse]4]
PUB P1_RIGHT
return data[noparse][[/noparse]15]
PUB P1_B
return data[noparse][[/noparse]6]
PUB P1_C
return data[noparse][[/noparse]14]
PUB P2_LEFT
return data[noparse][[/noparse]10]
PUB P2_RIGHT
return data[noparse][[/noparse]9]
PUB P2_B
return data[noparse][[/noparse]12]
PUB P2_C
return data[noparse][[/noparse]8]
PUB P1_X
return data[noparse][[/noparse]0]
PUB P1_Y
return data[noparse][[/noparse]1]
PUB P1_Z
return data[noparse][[/noparse]2]
PUB P2_X
return data[noparse][[/noparse]16]
PUB P2_Y
return data[noparse][[/noparse]17]
PUB P2_Z
return data[noparse][[/noparse]18] 



Now, my main issues are that starting this object seems to kill any program I'm trying to run.
For example, here's a little test program I wrote just to see if I could kick it up and see when
I get a button press:

CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000
OBJ
 pad : "Controller_1_0_1"
 text : "tv_text"
PUB start
 text.start(24)
 pad.start
 text.str(string(13,"PROG START"))
 repeat
  if pad.P1_up
   text.str(string("UP"))


But running this program just results in a quick flash of the text on screen, then a blank screen. The program seems to be locked up.

I think I'm having issues starting up the cog for the 'pad' object.
All I want is a driver that updates a data array and returns bits of it on command.

I've been avoiding using assembly because, quite honestly, its not my forte. I would assume it should be just as possible to do this in spin.

Any advice? Thanks,




▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-=Sachiel7=-

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-17 17:48
    A couple of things jump out:

    1) Your init code has to be executed at the beginning of scan because every cog has its own DIRA and OUTA registers and changes made in one cog (the init routine) do not affect another cog (the scan routine). For the cog running scan, all the I/O pins are inputs, so nothing done to the OUTA register will affect any of the I/O pins.

    2) Scan is executed once, then "falls off the end". When the routine started with a cognew returns, it causes a cogstop to be executed. You'll have to put in a REPEAT to have the scan repeat continuously.

    3) You declare "data" as a single long, yet treat it as an array of at least 31 entries. Are you trying to do bit manipulation? That only works for the "special" registers like OUTA, INA, DIRA, etc. When you store into "data[noparse][[/noparse] x]", you're overwriting the Spin stack.
  • Sachiel7Sachiel7 Posts: 41
    edited 2007-03-18 02:29
    Thanks Mike,
    I didnt know each cog had its own register set,
    I modified 'scan' to call init at the beginning, and I modified the data array to be a byte array of 32 entries.
    The test program will run now (yay!)
    There was a repeat at the beginning of the scan routine, do I need one somewhere else in the program?

    The thing now is that the program isnt functioning as intended. My sample program keeps printing 'up' whether or not I'm hitting the button. I've tryed calling all the button routines, they all seem to return true to whatever the 'if' statement is in my test program. Am I going about this the wrong way, trying to return array values from another object?

    Thanks for the Help,

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    -=Sachiel7=-

  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-18 02:40
    I think the problem is your use of !INA. INA for a single I/O pin produces a 0 or a 1. !INA inverts all the bits in the value so !0 becomes $FFFFFFFF and !1 becomes $FFFFFFFE. When stored in a byte, these are $FF and $FE respectively which both are non-zero, hence an IF data[noparse][[/noparse]???] is true for either value.

    Use INA[noparse][[/noparse] D] == 0 instead of !INA[noparse][[/noparse] D].
Sign In or Register to comment.