Skip to content

Commit 34447cb

Browse files
committed
Multiple mass storage / gamepad devices supported
(Gamepad device status handler still has to get device index) USB device information provided (to identify devices) GamePad device supports hat switches
1 parent 1e5363c commit 34447cb

File tree

14 files changed

+584
-202
lines changed

14 files changed

+584
-202
lines changed

SDL2/src/joystick/raspberry/SDL_sysjoystick.c

Lines changed: 36 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,16 @@
3030
#include "SDL_endian.h"
3131
#include "SDL_assert.h"
3232

33+
#define MAX_AXES 6
34+
#define MAX_HATS 6
35+
3336
/* The private structure used to keep track of a joystick */
3437
struct joystick_hwdata
3538
{
3639
struct SDL_joylist_item *item;
3740
SDL_JoystickGUID guid;
38-
int x;
39-
int y;
40-
int z;
41-
int rx;
42-
int ry;
43-
int rz;
41+
int axes[MAX_AXES];
42+
int hats[MAX_HATS];
4443
unsigned int buttons;
4544
};
4645

@@ -179,75 +178,33 @@ SDL_Joystick * uspi_joystick;
179178
static void
180179
USPiGamePadStatusHandler (const USPiGamePadState *pGamePadState)
181180
{
182-
int center = (pGamePadState->maximum - pGamePadState->minimum + 1) / 2 + pGamePadState->minimum;
183-
int steps1 = 32767000 / (center - pGamePadState->minimum);
184-
int steps2 = 32767000 / (pGamePadState->maximum - center);
181+
int i, value, bmMask, center, steps1, steps2;
185182
struct joystick_hwdata *hwdata = uspi_joystick->hwdata;
186183

187-
Uint8 axis = 0;
188-
if ((pGamePadState->flags & FLAG_X) != 0) {
189-
if (hwdata->x != pGamePadState->x) {
190-
if (pGamePadState->x < center)
191-
SDL_PrivateJoystickAxis(uspi_joystick, axis, ((pGamePadState->x - center) * steps1 - 500) / 1000);
192-
else
193-
SDL_PrivateJoystickAxis(uspi_joystick, axis, ((pGamePadState->x - center) * steps2 + 500) / 1000);
194-
hwdata->x = pGamePadState->x;
195-
}
196-
axis++;
197-
}
198-
if ((pGamePadState->flags & FLAG_Y) != 0) {
199-
if (hwdata->y != pGamePadState->y) {
200-
if (pGamePadState->y < center)
201-
SDL_PrivateJoystickAxis(uspi_joystick, axis, ((pGamePadState->y - center) * steps1 - 500) / 1000);
202-
else
203-
SDL_PrivateJoystickAxis(uspi_joystick, axis, ((pGamePadState->y - center) * steps2 + 500) / 1000);
204-
hwdata->y = pGamePadState->y;
205-
}
206-
axis++;
207-
}
208-
if ((pGamePadState->flags & FLAG_Z) != 0) {
209-
if (hwdata->z != pGamePadState->z) {
210-
if (pGamePadState->z < center)
211-
SDL_PrivateJoystickAxis(uspi_joystick, axis, ((pGamePadState->z - center) * steps1 - 500) / 1000);
212-
else
213-
SDL_PrivateJoystickAxis(uspi_joystick, axis, ((pGamePadState->z - center) * steps2 + 500) / 1000);
214-
hwdata->z = pGamePadState->z;
215-
}
216-
axis++;
217-
}
218-
if ((pGamePadState->flags & FLAG_RX) != 0) {
219-
if (hwdata->rx != pGamePadState->rx) {
220-
if (pGamePadState->rx < center)
221-
SDL_PrivateJoystickAxis(uspi_joystick, axis, ((pGamePadState->rx - center) * steps1 - 500) / 1000);
184+
for (i = 0; i < pGamePadState->naxes; i++) {
185+
value = pGamePadState->axes[i].value;
186+
if (hwdata->axes[i] != value) {
187+
center = (pGamePadState->axes[i].maximum - pGamePadState->axes[i].minimum + 1) / 2 + pGamePadState->axes[i].minimum;
188+
steps1 = 32767000 / (center - pGamePadState->axes[i].minimum);
189+
steps2 = 32767000 / (pGamePadState->axes[i].maximum - center);
190+
if (value < center)
191+
SDL_PrivateJoystickAxis(uspi_joystick, i, ((value - center) * steps1 - 500) / 1000);
222192
else
223-
SDL_PrivateJoystickAxis(uspi_joystick, axis, ((pGamePadState->rx - center) * steps2 + 500) / 1000);
224-
hwdata->rx = pGamePadState->rx;
193+
SDL_PrivateJoystickAxis(uspi_joystick, i, ((value - center) * steps2 + 500) / 1000);
194+
hwdata->axes[i] = value;
225195
}
226-
axis++;
227196
}
228-
if ((pGamePadState->flags & FLAG_RY) != 0) {
229-
if (hwdata->ry != pGamePadState->ry) {
230-
if (pGamePadState->ry < center)
231-
SDL_PrivateJoystickAxis(uspi_joystick, axis, ((pGamePadState->ry - center) * steps1 - 500) / 1000);
232-
else
233-
SDL_PrivateJoystickAxis(uspi_joystick, axis, ((pGamePadState->ry - center) * steps2 + 500) / 1000);
234-
hwdata->ry = pGamePadState->ry;
235-
}
236-
axis++;
237-
}
238-
if ((pGamePadState->flags & FLAG_RZ) != 0) {
239-
if (hwdata->rz != pGamePadState->rz) {
240-
if (pGamePadState->rz < center)
241-
SDL_PrivateJoystickAxis(uspi_joystick, axis, ((pGamePadState->rz - center) * steps1 - 500) / 1000);
242-
else
243-
SDL_PrivateJoystickAxis(uspi_joystick, axis, ((pGamePadState->rz - center) * steps2 + 500) / 1000);
244-
hwdata->rz = pGamePadState->rz;
197+
198+
for (i = 0; i < pGamePadState->nhats; i++) {
199+
value = pGamePadState->hats[i];
200+
if (hwdata->hats[i] != value) {
201+
SDL_PrivateJoystickHat(uspi_joystick, i, value);
202+
hwdata->hats[i] = value;
245203
}
246-
axis++;
247204
}
248205

249206
if (pGamePadState->nbuttons > 0) {
250-
for (int i = 0, bmMask = 1; i < pGamePadState->nbuttons; i++, bmMask <<= 1) {
207+
for (i = 0, bmMask = 1 << (pGamePadState->nbuttons - 1); i < pGamePadState->nbuttons; i++, bmMask >>= 1) {
251208
if ((pGamePadState->buttons & bmMask) != (hwdata->buttons & bmMask)) {
252209
SDL_PrivateJoystickButton(uspi_joystick, i, (pGamePadState->buttons & bmMask) ? SDL_PRESSED : SDL_RELEASED);
253210
}
@@ -259,17 +216,22 @@ USPiGamePadStatusHandler (const USPiGamePadState *pGamePadState)
259216
static void
260217
USPi_JoystickOpen(SDL_Joystick * joystick, int device_index)
261218
{
262-
const USPiGamePadState *pGamePadState = USPiGamePadGetStatus();
263-
int i, bmMask;
219+
int i;
220+
struct joystick_hwdata *hwdata = joystick->hwdata;
221+
const USPiGamePadState *pGamePadState = USPiGamePadGetStatus(0);
264222

265-
joystick->naxes = 0;
266-
for (i = 0, bmMask = FLAG_X; i < 6; i++, bmMask <<= 1) {
267-
if ((pGamePadState->flags & bmMask) != 0)
268-
joystick->naxes++;
223+
joystick->naxes = pGamePadState->naxes;
224+
for (i = 0; i < pGamePadState->naxes; i++) {
225+
hwdata->axes[i] = pGamePadState->axes[i].value;
226+
}
227+
228+
joystick->nhats = pGamePadState->nhats;
229+
for (i = 0; i < pGamePadState->nhats; i++) {
230+
hwdata->hats[i] = pGamePadState->hats[i];
269231
}
270232

271233
joystick->nbuttons = pGamePadState->nbuttons;
272-
joystick->hwdata->buttons = pGamePadState->buttons;
234+
hwdata->buttons = pGamePadState->buttons;
273235

274236
joystick->nhats = 0;
275237

@@ -334,7 +296,7 @@ SDL_SYS_JoystickInit(void)
334296

335297
item->name = SDL_strdup("USPi Gamepad");
336298

337-
const USPiGamePadState *pGamePadState = USPiGamePadGetStatus();
299+
const USPiGamePadState *pGamePadState = USPiGamePadGetStatus(0);
338300
Uint16 *guid16 = (Uint16 *) ((char *) &item->guid.data);
339301
*(guid16++) = SDL_SwapLE16(3);
340302
*(guid16++) = 0;

kernel/syscalls.c

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ DSTATUS disk_status (
306306
case MMC :
307307
return 0;
308308

309-
case USB :
309+
default :
310310
if (!USPiMassStorageDeviceAvailable())
311311
{
312312
return STA_NOINIT;
@@ -328,14 +328,9 @@ DSTATUS disk_initialize (
328328
{
329329
switch (pdrv) {
330330
case MMC :
331-
/*if (sd_get_num_blocks() == 0 || sd_get_block_size() == 0)
332-
{
333-
if (sd_card_init() != 0)
334-
return STA_NOINIT;
335-
}*/
336331
return 0;
337332

338-
case USB :
333+
default :
339334
if (!USPiMassStorageDeviceAvailable())
340335
{
341336
return STA_NOINIT;
@@ -370,15 +365,15 @@ DRESULT disk_read (
370365
return RES_OK;
371366
}
372367

373-
case USB :
368+
default :
374369
{
375370
if (!USPiMassStorageDeviceAvailable())
376371
{
377372
return RES_PARERR;
378373
}
379374

380-
unsigned buf_size = count * 512;
381-
if (USPiMassStorageDeviceRead(sector * 512, buff, buf_size) < buf_size)
375+
unsigned buf_size = count * USPI_BLOCK_SIZE;
376+
if (USPiMassStorageDeviceRead(sector * USPI_BLOCK_SIZE, buff, buf_size, pdrv - USB) < buf_size)
382377
{
383378
return RES_ERROR;
384379
}
@@ -415,15 +410,15 @@ DRESULT disk_write (
415410
return RES_OK;
416411
}
417412

418-
case USB :
413+
default :
419414
{
420415
if (!USPiMassStorageDeviceAvailable())
421416
{
422417
return RES_PARERR;
423418
}
424419

425-
unsigned buf_size = count * 512;
426-
if (USPiMassStorageDeviceWrite(sector * 512, buff, buf_size) < buf_size)
420+
unsigned buf_size = count * USPI_BLOCK_SIZE;
421+
if (USPiMassStorageDeviceWrite(sector * USPI_BLOCK_SIZE, buff, buf_size, pdrv - USB) < buf_size)
427422
{
428423
return RES_ERROR;
429424
}
@@ -469,7 +464,7 @@ DRESULT disk_ioctl (
469464
}
470465
return RES_PARERR;
471466

472-
case USB :
467+
default :
473468
if (!USPiMassStorageDeviceAvailable())
474469
{
475470
return RES_PARERR;
@@ -485,12 +480,12 @@ DRESULT disk_ioctl (
485480
}
486481
if (cmd == GET_SECTOR_SIZE)
487482
{
488-
*(DWORD *)buff = 512;
483+
*(DWORD *)buff = USPI_BLOCK_SIZE;
489484
return RES_OK;
490485
}
491486
if (cmd == GET_BLOCK_SIZE)
492487
{
493-
*(DWORD *)buff = 512;
488+
*(DWORD *)buff = USPI_BLOCK_SIZE;
494489
return RES_OK;
495490
}
496491
return RES_PARERR;

uspi/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ OBJS = \
5858
lib/usbmouse.o \
5959
lib/usbrequest.o \
6060
lib/usbstandardhub.o \
61+
lib/usbstring.o \
6162
lib/uspilibrary.o \
6263
lib/util.o \
6364
lib/synchronize.o \

uspi/include/uspi.h

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//
66
// USPi - An USB driver for Raspberry Pi written in C
77
// Copyright (C) 2014 R. Stange <[email protected]>
8-
//
8+
//
99
// This program is free software: you can redistribute it and/or modify
1010
// it under the terms of the GNU General Public License as published by
1111
// the Free Software Foundation, either version 3 of the License, or
@@ -102,18 +102,20 @@ void USPiMouseRegisterStatusHandler (TUSPiMouseStatusHandler *pStatusHandler);
102102
// Mass storage device
103103
//
104104

105-
// returns != 0 if available
105+
// returns number of available devices
106106
int USPiMassStorageDeviceAvailable (void);
107107

108108
#define USPI_BLOCK_SIZE 512 // other block sizes are not supported
109109

110110
// ullOffset and nCount must be multiple of USPI_BLOCK_SIZE
111111
// returns number of read bytes or < 0 on failure
112-
int USPiMassStorageDeviceRead (unsigned long long ullOffset, void *pBuffer, unsigned nCount);
112+
// nDeviceIndex is 0-based
113+
int USPiMassStorageDeviceRead (unsigned long long ullOffset, void *pBuffer, unsigned nCount, unsigned nDeviceIndex);
113114

114115
// ullOffset and nCount must be multiple of USPI_BLOCK_SIZE
115116
// returns number of written bytes or < 0 on failure
116-
int USPiMassStorageDeviceWrite (unsigned long long ullOffset, const void *pBuffer, unsigned nCount);
117+
// nDeviceIndex is 0-based
118+
int USPiMassStorageDeviceWrite (unsigned long long ullOffset, const void *pBuffer, unsigned nCount, unsigned nDeviceIndex);
117119

118120
//
119121
// Ethernet services
@@ -139,44 +141,66 @@ int USPiReceiveFrame (void *pBuffer, unsigned *pResultLength);
139141
// GamePad device
140142
//
141143

142-
// returns != 0 if available
144+
// returns number of available devices
143145
int USPiGamePadAvailable (void);
144146

145147
#define MAX_AXIS 6
146-
147-
#define FLAG_X 0x0001
148-
#define FLAG_Y 0x0002
149-
#define FLAG_Z 0x0004
150-
#define FLAG_RX 0x0008
151-
#define FLAG_RY 0x0010
152-
#define FLAG_RZ 0x0020
148+
#define MAX_HATS 6
153149

154150
typedef struct USPiGamePadState {
155151
unsigned short idVendor;
156152
unsigned short idProduct;
157153
unsigned short idVersion;
158154

159-
unsigned int flags;
155+
int naxes;
156+
struct {
157+
int value;
158+
int minimum;
159+
int maximum;
160+
} axes[MAX_AXIS];
160161

161-
int x;
162-
int y;
163-
int z;
164-
int rx;
165-
int ry;
166-
int rz;
167-
int minimum;
168-
int maximum;
162+
int nhats;
163+
int hats[MAX_HATS];
169164

170165
int nbuttons;
171166
unsigned int buttons;
172167
}
173168
USPiGamePadState;
174169

175-
const USPiGamePadState *USPiGamePadGetStatus (void);
170+
// returns 0 on failure
171+
const USPiGamePadState *USPiGamePadGetStatus (unsigned nDeviceIndex); // nDeviceIndex is 0-based
176172

177173
typedef void TGamePadStatusHandler (const USPiGamePadState *pGamePadState);
178174
void USPiGamePadRegisterStatusHandler (TGamePadStatusHandler *pStatusHandler);
179175

176+
//
177+
// USB device information
178+
//
179+
180+
#define KEYBOARD_CLASS 1
181+
#define MOUSE_CLASS 2
182+
#define STORAGE_CLASS 3
183+
#define ETHERNET_CLASS 4
184+
#define GAMEPAD_CLASS 5
185+
186+
typedef struct TUSPiDeviceInformation
187+
{
188+
// from USB device descriptor
189+
unsigned short idVendor;
190+
unsigned short idProduct;
191+
unsigned short bcdDevice;
192+
193+
// points to a buffer in the USPi library, empty string if not available
194+
const char *pManufacturer;
195+
const char *pProduct;
196+
}
197+
TUSPiDeviceInformation;
198+
199+
// returns 0 on failure
200+
int USPiDeviceGetInformation (unsigned nClass, // see above
201+
unsigned nDeviceIndex, // 0-based index
202+
TUSPiDeviceInformation *pInfo); // provided buffer is filled
203+
180204
#ifdef __cplusplus
181205
}
182206
#endif

uspi/include/uspi/usb.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,12 @@ typedef union
166166
}
167167
PACKED TUSBDescriptor;
168168

169+
typedef struct TUSBStringDescriptor
170+
{
171+
unsigned char bLength;
172+
unsigned char bDescriptorType;
173+
unsigned short bString[0];
174+
}
175+
PACKED TUSBStringDescriptor;
176+
169177
#endif

uspi/include/uspi/usbdevice.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <uspi/usb.h>
2424
#include <uspi/usbconfigparser.h>
25+
#include <uspi/usbstring.h>
2526
#include <uspi/string.h>
2627
#include <uspi/types.h>
2728

@@ -58,6 +59,9 @@ typedef struct TUSBDevice
5859
TUSBConfigurationDescriptor *m_pConfigDesc;
5960

6061
TUSBConfigurationParser *m_pConfigParser;
62+
63+
TUSBString m_ManufacturerString;
64+
TUSBString m_ProductString;
6165
}
6266
TUSBDevice;
6367

0 commit comments

Comments
 (0)