-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpiuio.cpp
More file actions
147 lines (115 loc) · 3.25 KB
/
Copy pathpiuio.cpp
File metadata and controls
147 lines (115 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include "stdafx.h"
#include "piuio.h"
InputHandler_PIUIO* g_ihPIUIO;
#define PIUIO_VENDOR_ID 0x0547
#define PIUIO_PRODUCT_ID 0x1002
#define PIUIOBUTTON_VENDOR_ID 0x0D2F
#define PIUIOBUTTON_PRODUCT_ID 0x1010
/* proprietary (arbitrary?) request PIUIO requires to handle I/O */
const short PIUIO_CTL_REQ = 0xAE;
/* timeout value for read/writes, in microseconds (so, 10 ms) */
const int REQ_TIMEOUT = 10000;
bool PIUIO::DeviceMatches(int iVID, int iPID)
{
return iVID == PIUIO_VENDOR_ID && iPID == PIUIO_PRODUCT_ID;
}
bool PIUIO::Open()
{
return OpenInternal(PIUIO_VENDOR_ID, PIUIO_PRODUCT_ID);
}
bool PIUIO::Read(uint32_t *pData)
{
/* XXX: magic number left over from the ITG disassembly */
int iExpected = 8;
int iResult = m_pDriver->ControlMessage(
USB_DIR_IN | USB_TYPE_VENDOR, PIUIO_CTL_REQ,
0, 0, (char*)pData, iExpected, REQ_TIMEOUT);
return iResult == iExpected;
}
bool PIUIO::Write(const uint32_t iData)
{
/* XXX: magic number left over from the ITG disassembly */
int iExpected = 8;
int iResult = m_pDriver->ControlMessage(
USB_DIR_OUT | USB_TYPE_VENDOR, PIUIO_CTL_REQ,
0, 0, (char*)&iData, iExpected, REQ_TIMEOUT);
return iResult == iExpected;
}
bool InputHandler_PIUIO::s_bInitialized = false;
// simple helper function to automatically reopen PIUIO if a USB error occurs
static void Reconnect(PIUIO &board)
{
printf("PIUIO connection lost! Retrying...");
while (!board.Open())
{
board.Close();
}
printf("PIUIO reconnected.");
}
InputHandler_PIUIO::InputHandler_PIUIO()
{
InputHandler::InputHandler();
if (s_bInitialized)
{
printf("InputHandler_PIUIO: Redundant driver loaded. Disabling...");
return;
}
// attempt to connect to the I/O board
if (!Board.Open())
{
printf("InputHandler_PIUIO: Could not establish a connection with the I/O device.");
return;
}
// set the relevant global flags (static flag, input type)
m_bFoundDevice = true;
s_bInitialized = true;
}
InputHandler_PIUIO::~InputHandler_PIUIO()
{
// reset all lights and unclaim the device
if (m_bFoundDevice)
{
Board.Write(0); // it's okay if this fails
Board.Close();
s_bInitialized = false;
}
}
void InputHandler_PIUIO::InputThreadMain()
{
UpdateLights();
HandleInput();
}
void InputHandler_PIUIO::HandleInput()
{
if (!m_bFoundDevice) return;
// reset our reading data
m_iInputField = 0x0;
memset(&m_iInputData, 0, sizeof(m_iInputData) / sizeof(uint32_t));
for (uint32_t i = 0; i < 4; ++i)
{
// write a set of sensors to request
m_iLightData &= 0xFFFCFFFC;
m_iLightData |= (i | (i << 16));
// request this set of sensors
while (!Board.Write(m_iLightData))
Reconnect(Board);
m_iInputData[i] = 0x0;
// read from this set of sensors
while (!Board.Read(&m_iInputData[i]))
Reconnect(Board);
m_iInputData[i] = ~m_iInputData[i];
}
// combine the read data into a single field
for (int i = 0; i < 4; ++i)
m_iInputField |= m_iInputData[i];
// generate our input events bit field (1 = change, 0 = no change)
m_iChanged = m_iInputField ^ m_iLastInputField;
m_iLastInputField = m_iInputField;
// For the button, there is nothing
m_iButtonChanged = 0;
m_iButtonField = 0;
m_iLastButtonField = 0;
}
void InputHandler_PIUIO::UpdateLights()
{
}