Controller Driver Isssues, What's Wrong? (CODE INCLUDED)
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:
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:
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=-
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
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.
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=-
Use INA[noparse][[/noparse] D] == 0 instead of !INA[noparse][[/noparse] D].