Skip to content

Commit

Permalink
Undelete the steam controller lib, which apparently isn't actually a …
Browse files Browse the repository at this point in the history
…submodule
  • Loading branch information
commandblockguy committed Mar 2, 2020
1 parent 5b697b5 commit f2d26be
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 0 deletions.
88 changes: 88 additions & 0 deletions src/lib/steam_controller.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "../config.h"
#if USE_USB
#include <usbdrvce.h>
#include <stdlib.h>
#include <string.h>
#include <debug.h>
#include <graphx.h>
#include "steam_controller.h"

#define VENDOR_STEAM 0x28DE
#define DEVICE_WIRED 0x1102
#define DEVICE_DONGLE 0x1142

int8_t sc_GetInterface(usb_device_t dev) {
usb_device_descriptor_t descriptor;
usb_GetDescriptor(dev, USB_DEVICE_DESCRIPTOR, 0,
&descriptor, sizeof(descriptor), NULL);
if(descriptor.idVendor != VENDOR_STEAM) return -1;
switch(descriptor.idProduct) {
case DEVICE_WIRED:
return 2;
case DEVICE_DONGLE:
return 1;
default:
return -1;
}
}

struct DataPacket {
uint8_t header;
uint8_t request;
sc_haptic_t haptic;
uint16_t pulse_high;
uint16_t pulse_low;
uint16_t repeat_count;
uint8_t padding[55];
};

usb_error_t tone_callback(usb_endpoint_t pEndpoint,
usb_transfer_status_t status,
size_t size, void *pVoid) {
dbg_sprintf(dbgout, "callback called\n");
free(pVoid);
return USB_SUCCESS;
}

const struct DataPacket sc_default_data = {0x8f, 0x08};

void sc_PlayTone(usb_device_t dev, uint8_t interface,
sc_haptic_t haptic, uint16_t pulse_duration,
uint16_t repeat_count) {
struct DataPacket *data = malloc(sizeof(sc_default_data));
usb_control_setup_t setup = {0x21, 9, 0x300, 0, 64};

if(!dev) return;

if(data) {
dbg_sprintf(dbgout, "tone %u %u %u\n", haptic, pulse_duration, repeat_count);
setup.wIndex = interface;
memcpy(data, &sc_default_data, sizeof(sc_default_data));
data->haptic = haptic;
data->pulse_high = data->pulse_low = pulse_duration;
data->repeat_count = repeat_count;

usb_ScheduleDefaultControlTransfer(dev, &setup, data, tone_callback, data);
} else {
dbg_sprintf(dbgout, "failed to alloc for PlayTone\n");
}
}

void sc_StopTone(usb_device_t dev, uint8_t interface,
sc_haptic_t haptic) {
struct DataPacket *data = malloc(sizeof(sc_default_data));
usb_control_setup_t setup = {0x21, 9, 0x300, 0, 64};

if(data) {
setup.wIndex = interface;
memcpy(data, &sc_default_data, sizeof(sc_default_data));
data->haptic = haptic;

usb_ScheduleDefaultControlTransfer(dev, &setup, data, tone_callback, data);
} else {
dbg_sprintf(dbgout, "failed to alloc for StopTone\n");
}
}


#endif
60 changes: 60 additions & 0 deletions src/lib/steam_controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifndef DINO_STEAM_CONTROLLER_H
#define DINO_STEAM_CONTROLLER_H

#include <stdint.h>
#include <usbdrvce.h>
#include <stdbool.h>

enum {
SC_HAPTIC_RIGHT,
SC_HAPTIC_LEFT
};
typedef bool sc_haptic_t;

/**
* Gets the interface number to use for controlling haptic feedback
* @param dev USB device to check
* @return Interface number, or -1 if not a steam controller
*/
int8_t sc_GetInterface(usb_device_t dev);

/**
* Plays a tone on the Steam controller
* @param dev USB device
* @param interface Interface from \c sc_GetInterface
* @param haptic Which haptic feedback motor to use
* @param pulse_duration Duration of each pulse. Use \c sc_FrequencyToDuration
* @param repeat_count Number of times to repeat. Use \c sc_TimeToRepeatCount
*/
void sc_PlayTone(usb_device_t dev, uint8_t interface,
sc_haptic_t haptic, uint16_t pulse_duration,
uint16_t repeat_count);

/**
* Stops playing a tone on the Steam controller
* @param dev USB device
* @param interface Interface from \c sc_GetInterface
* @param haptic Which haptic feedback motor to stop
*/
void sc_StopTone(usb_device_t dev, uint8_t interface,
sc_haptic_t haptic);

#define STEAM_CONTROLLER_MAGIC_PERIOD_RATIO 495483

/**
* Converts a frequency to a pulse duration
* @param freq Frequency in hertz
* @return Pulse duration for use with sc_PlayTone
*/
#define sc_FrequencyToDuration(freq) ((uint16_t)(STEAM_CONTROLLER_MAGIC_PERIOD_RATIO / freq))

/**
* Converts a time and frequency to a repeat count
* @param ms Time in milliseconds
* @param freq Frequency in hertz
* @return Repeat count for use with sc_PlayTone
*/
#define sc_TimeToRepeatCount(ms, freq) ((uint16_t)((ms * freq) / 1000))


#endif //DINO_STEAM_CONTROLLER_H

0 comments on commit f2d26be

Please sign in to comment.