Cerberus code:
using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
using Gadgeteer.Interfaces;
namespace PSOneControllerTranslator
{
public partial class Program
{
// This method is run when the mainboard is powered up or reset.
void ProgramStarted()
{
/*******************************************************************************************
Modules added in the Program.gadgeteer designer view are used by typing
their name followed by a period, e.g. button. or camera.
Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
button.ButtonPressed +=<tab><tab>
If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
timer.Tick +=<tab><tab>
timer.Start();
*******************************************************************************************/
// inputClock.Interrupt += inputClock_Interrupt;
// Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
Debug.Print("Program Started");
new Thread(new ThreadStart(TestTimer)).Start();
}
// private int delay = 5;
private GT.Socket.Pin pinData = GT.Socket.Pin.Nine; // 9;
private GT.Socket.Pin pinCommand = GT.Socket.Pin.Eight; // 8;
private GT.Socket.Pin pinAtt = GT.Socket.Pin.Seven; // 7;
private GT.Socket.Pin pinClock = GT.Socket.Pin.Six; // 6;
// private GT.Socket.Pin pinAck = GT.Socket.Pin.Five; // 5;
private DigitalInput digitalPinData;
private DigitalOutput digitalPinCommand;
private DigitalOutput digitalPinAtt;
private DigitalOutput digitalPinClock;
// private DigitalIO digitalPinAck;
private void SetupPins()
{
usbSerial.Configure(115200, Serial.SerialParity.None, Serial.SerialStopBits.One, 8);
usbSerial.SerialLine.Open();
// char_Display.Clear();
var socket = GT.Socket.GetSocket(2, false, null, null);
digitalPinData = new DigitalInput(socket, pinData, GlitchFilterMode.Off, ResistorMode.PullUp, null);
digitalPinCommand = new DigitalOutput(socket, pinCommand, false, null);
digitalPinAtt = new DigitalOutput(socket, pinAtt, true, null);
digitalPinClock = new DigitalOutput(socket, pinClock, true, null);
}
void Set(ref byte aByte, int pos, bool value)
{
if (value)
{
//left-shift 1, then bitwise OR
aByte = (byte)(aByte | (1 << pos));
}
else
{
//left-shift 1, then take complement, then bitwise AND
aByte = (byte)(aByte & ~(1 << pos));
}
}
private void Read()
{
this.PulseDebugLED();
digitalPinAtt.Write(false);
Shift(0x01);
Shift(0x42);
Shift(0xff);
var data1 = 255 - Shift(0xff);
var data2 = 255 - Shift(0xff);
digitalPinAtt.Write(true);
// var _dataOut = (data2 << 8 | data1);
usbSerial.SerialLine.Write(new byte[] { (byte)data1, (byte)data2 });
usbSerial.SerialLine.Flush();
}
private void TestTimer()
{
SetupPins();
while (true)
{
Read();
}
}
bool IsBitSet(byte b, int pos)
{
return (b & (1 << pos)) != 0;
}
private byte Shift(byte _dataOut)
{
bool _temp = false;
byte _dataIn = 0x00;
for (var _i = 0; _i <= 7; _i++)
{
bool outBit = IsBitSet(_dataOut, _i);
digitalPinCommand.Write(outBit);
digitalPinClock.Write(false);
Thread.Sleep(1);
_temp = digitalPinData.Read();
Set(ref _dataIn, _i, _temp);
digitalPinClock.Write(true);
Thread.Sleep(1);
}
return _dataIn;
}
}
}
Windows client
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WindowsInput;
namespace PSOneControllerWinClient
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
SerialPort port = new SerialPort("COM3", 115200, Parity.None, 8, StopBits.One);
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i != 16; i++)
{
commands[i] = false;
}
port.DataReceived += port_DataReceived;
// Open the port for communications
port.Open();
}
bool[] commands = new bool[16];
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte data1 = (byte)port.ReadByte();
byte data2 = (byte)port.ReadByte();
bool[] curr = new bool[16];
for (var i = 0; i != 8; i++)
{
curr[i] = IsBitSet(data1, i);
}
for (var i = 0; i != 8; i++)
{
curr[8 + i] = IsBitSet(data2, i);
}
for (int i = 0; i != 16; i++)
{
if (commands[i] != curr[i])
{
if (curr[i])
InputSimulator.SimulateKeyDown((VirtualKeyCode)(65 + i));
else
InputSimulator.SimulateKeyUp((VirtualKeyCode)(65 + i));
}
}
commands = curr;
}
bool IsBitSet(byte b, int pos)
{
return (b & (1 << pos)) != 0;
}
}
}
Windows Keyboard HOOK lib: http://inputsimulator.codeplex.com/