aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Turvey <mturvey6@gmail.com>2018-01-04 08:47:42 -0700
committerMike Turvey <mturvey6@gmail.com>2018-01-04 08:47:42 -0700
commit499b80ae7b538f8e66f5ec8bfa60c7136a3babf5 (patch)
tree0ef5325a3494099b7c18c085106486fc5b6368f2
parentf183aa480c549695ac5b481fade04e62f71d1e0a (diff)
downloadlibsurvive-499b80ae7b538f8e66f5ec8bfa60c7136a3babf5.tar.gz
libsurvive-499b80ae7b538f8e66f5ec8bfa60c7136a3babf5.tar.bz2
Haptic Call Plumbed
The plumbing is now in place for the haptic call. Left in place a "demo" where haptic is called when a controller's trigger is pulled
-rw-r--r--include/libsurvive/survive.h5
-rw-r--r--include/libsurvive/survive_types.h2
-rwxr-xr-xsrc/survive.c13
-rw-r--r--src/survive_process.c26
-rwxr-xr-xsrc/survive_vive.c87
5 files changed, 115 insertions, 18 deletions
diff --git a/include/libsurvive/survive.h b/include/libsurvive/survive.h
index e4afadf..0cfab1f 100644
--- a/include/libsurvive/survive.h
+++ b/include/libsurvive/survive.h
@@ -19,6 +19,7 @@ struct SurviveObject
char codename[4]; //3 letters, null-terminated. Currently HMD, WM0, WM1.
char drivername[4]; //3 letters for driver. Currently "HTC"
+ void *driver;
int32_t buttonmask;
int16_t axis1;
@@ -68,6 +69,7 @@ struct SurviveObject
FLT* gyro_bias; // size is FLT*3. contains x,y,z
FLT* gyro_scale; // size is FLT*3. contains x,y,z
+ haptic_func haptic;
//Debug
int tsl;
@@ -179,6 +181,9 @@ void survive_cal_install( SurviveContext * ctx ); //XXX This will be removed if
// Read back a human-readable string description of the calibration status
int survive_cal_get_status( struct SurviveContext * ctx, char * description, int description_length );
+// Induce haptic feedback
+int survive_haptic(SurviveObject * so, uint8_t reserved, uint16_t pulseHigh, uint16_t pulseLow, uint16_t repeatCount);
+
//Call these from your callback if overridden.
//Accept higher-level data.
void survive_default_light_process( SurviveObject * so, int sensor_id, int acode, int timeinsweep, uint32_t timecode, uint32_t length , uint32_t lh);
diff --git a/include/libsurvive/survive_types.h b/include/libsurvive/survive_types.h
index fa3eb2f..9a6e148 100644
--- a/include/libsurvive/survive_types.h
+++ b/include/libsurvive/survive_types.h
@@ -44,6 +44,8 @@ typedef void (*imu_process_func)( SurviveObject * so, int mask, FLT * accelgyro,
typedef void (*angle_process_func)( SurviveObject * so, int sensor_id, int acode, uint32_t timecode, FLT length, FLT angle, uint32_t lh);
typedef void (*button_process_func)(SurviveObject * so, uint8_t eventType, uint8_t buttonId, uint8_t axis1Id, uint16_t axis1Val, uint8_t axis2Id, uint16_t axis2Val);
+typedef int(*haptic_func)(SurviveObject * so, uint8_t reserved, uint16_t pulseHigh , uint16_t pulseLow, uint16_t repeatCount);
+
//Device drivers (prefix your drivers with "DriverReg") i.e.
// REGISTER_LINKTIME( DriverRegHTCVive );
typedef int (*DeviceDriver)( SurviveContext * ctx );
diff --git a/src/survive.c b/src/survive.c
index d3c0918..75c07bf 100755
--- a/src/survive.c
+++ b/src/survive.c
@@ -60,7 +60,7 @@ static void button_servicer(void * context)
// should never happen. indicates failure of code pushing stuff onto
// the buttonQueue
// if it does happen, it will kill all future button input
- printf("ERROR: Unpopulated ButtonQueueEntry!");
+ printf("ERROR: Unpopulated ButtonQueueEntry! NextReadIndex=%d\n", ctx->buttonQueue.nextReadIndex);
return;
}
@@ -272,6 +272,17 @@ int survive_send_magic( SurviveContext * ctx, int magic_code, void * data, int d
return 0;
}
+int survive_haptic(SurviveObject * so, uint8_t reserved, uint16_t pulseHigh, uint16_t pulseLow, uint16_t repeatCount)
+{
+ if (NULL == so || NULL == so->haptic)
+ {
+ return -404;
+ }
+
+ return so->haptic(so, reserved, pulseHigh, pulseLow, repeatCount);
+}
+
+
void survive_close( SurviveContext * ctx )
{
const char * DriverName;
diff --git a/src/survive_process.c b/src/survive_process.c
index eaed881..4b86144 100644
--- a/src/survive_process.c
+++ b/src/survive_process.c
@@ -66,13 +66,25 @@ void survive_default_angle_process( SurviveObject * so, int sensor_id, int acode
void survive_default_button_process(SurviveObject * so, uint8_t eventType, uint8_t buttonId, uint8_t axis1Id, uint16_t axis1Val, uint8_t axis2Id, uint16_t axis2Val)
{
// do nothing.
- printf("ButtonEntry: eventType:%x, buttonId:%d, axis1:%d, axis1Val:%8.8x, axis2:%d, axis2Val:%8.8x\n",
- eventType,
- buttonId,
- axis1Id,
- axis1Val,
- axis2Id,
- axis2Val);
+ //printf("ButtonEntry: eventType:%x, buttonId:%d, axis1:%d, axis1Val:%8.8x, axis2:%d, axis2Val:%8.8x\n",
+ // eventType,
+ // buttonId,
+ // axis1Id,
+ // axis1Val,
+ // axis2Id,
+ // axis2Val);
+ if (buttonId == 24 && eventType == 1) // trigger engage
+ {
+ for (int j = 0; j < 40; j++)
+ {
+ for (int i = 0; i < 0x1; i++)
+ {
+ survive_haptic(so, 0, 0xf401, 0xb5a2, 0x0100);
+ OGUSleep(5000);
+ }
+ OGUSleep(20000);
+ }
+ }
}
void survive_default_imu_process( SurviveObject * so, int mask, FLT * accelgyromag, uint32_t timecode, int id )
diff --git a/src/survive_vive.c b/src/survive_vive.c
index 3df60ba..9e4a8b8 100755
--- a/src/survive_vive.c
+++ b/src/survive_vive.c
@@ -620,17 +620,24 @@ int survive_vive_send_magic(SurviveContext * ctx, void * drv, int magic_code, vo
//#endif
#if 0
- for (int i = 0; i < 0xf; i++)
+ for (int j=0; j < 40; j++)
{
- //uint8_t vive_controller_haptic_pulse[64] = { 0xff, 0x8f, 0x7, 0 /*right*/, 0xFF /*period on*/, 0xFF/*period on*/, 0xFF/*period off*/, 0xFF/*period off*/, 0xFF /* repeat Count */, 0xFF /* repeat count */ };
- //uint8_t vive_controller_haptic_pulse[64] = { 0xff, 0x8f, 0x07, 0x00, 0xf4, 0x01, 0xb5, 0xa2, 0x01, 0x00 }; // data taken from Nairol's captures
- uint8_t vive_controller_haptic_pulse[64] = { 0xff, 0x8f, 0x07, 0x00, 0xf4, 0x01, 0xb5, 0xa2, 0x01, 0x00 };
- r = update_feature_report( sv->udev[USB_DEV_WATCHMAN1], 0, vive_controller_haptic_pulse, sizeof( vive_controller_haptic_pulse ) );
- r = getupdate_feature_report(sv->udev[USB_DEV_WATCHMAN1], 0, vive_controller_haptic_pulse, sizeof(vive_controller_haptic_pulse));
- SV_INFO("UCR: %d", r);
- if (r != sizeof(vive_controller_haptic_pulse)) printf("HAPTIC FAILED **************************\n"); // return 5;
- OGUSleep(1000);
+ for (int i = 0; i < 0x1; i++)
+ {
+ //uint8_t vive_controller_haptic_pulse[64] = { 0xff, 0x8f, 0x7, 0 /*right*/, 0xFF /*period on*/, 0xFF/*period on*/, 0xFF/*period off*/, 0xFF/*period off*/, 0xFF /* repeat Count */, 0xFF /* repeat count */ };
+ //uint8_t vive_controller_haptic_pulse[64] = { 0xff, 0x8f, 0x07, 0x00, 0xf4, 0x01, 0xb5, 0xa2, 0x01, 0x00 }; // data taken from Nairol's captures
+ uint8_t vive_controller_haptic_pulse[64] = { 0xff, 0x8f, 0x07, 0x00, 0xf4, 0x01, 0xb5, 0xa2, 0x01* j, 0x00 };
+ r = update_feature_report( sv->udev[USB_DEV_WATCHMAN1], 0, vive_controller_haptic_pulse, sizeof( vive_controller_haptic_pulse ) );
+ r = getupdate_feature_report(sv->udev[USB_DEV_WATCHMAN1], 0, vive_controller_haptic_pulse, sizeof(vive_controller_haptic_pulse));
+ SV_INFO("UCR: %d", r);
+ if (r != sizeof(vive_controller_haptic_pulse)) printf("HAPTIC FAILED **************************\n"); // return 5;
+ OGUSleep(5000);
+ }
+
+ OGUSleep(20000);
}
+
+
#endif
#if 0
@@ -686,6 +693,54 @@ int survive_vive_send_magic(SurviveContext * ctx, void * drv, int magic_code, vo
return 0;
}
+int survive_vive_send_haptic(SurviveObject * so, uint8_t reserved, uint16_t pulseHigh, uint16_t pulseLow, uint16_t repeatCount)
+{
+ SurviveViveData *sv = (SurviveViveData*)so->driver;
+
+ if (NULL == sv)
+ {
+ return -500;
+ }
+
+ int r;
+ uint8_t vive_controller_haptic_pulse[64] = {
+ 0xff, 0x8f, 0x07, 0x00,
+ pulseHigh & 0xff00 >> 8, pulseHigh & 0xff,
+ pulseLow & 0xff00 >> 8, pulseLow & 0xff,
+ repeatCount & 0xff00 >> 8, repeatCount & 0xff,
+ };
+
+ r = update_feature_report(sv->udev[USB_DEV_WATCHMAN1], 0, vive_controller_haptic_pulse, sizeof(vive_controller_haptic_pulse));
+ r = getupdate_feature_report(sv->udev[USB_DEV_WATCHMAN1], 0, vive_controller_haptic_pulse, sizeof(vive_controller_haptic_pulse));
+ //SV_INFO("UCR: %d", r);
+ if (r != sizeof(vive_controller_haptic_pulse))
+ {
+ printf("HAPTIC FAILED **************************\n");
+ return -1;
+ }
+
+ return 0;
+
+ //for (int j = 0; j < 40; j++)
+ //{
+ // for (int i = 0; i < 0x1; i++)
+ // {
+ // //uint8_t vive_controller_haptic_pulse[64] = { 0xff, 0x8f, 0x7, 0 /*right*/, 0xFF /*period on*/, 0xFF/*period on*/, 0xFF/*period off*/, 0xFF/*period off*/, 0xFF /* repeat Count */, 0xFF /* repeat count */ };
+ // //uint8_t vive_controller_haptic_pulse[64] = { 0xff, 0x8f, 0x07, 0x00, 0xf4, 0x01, 0xb5, 0xa2, 0x01, 0x00 }; // data taken from Nairol's captures
+ // uint8_t vive_controller_haptic_pulse[64] = { 0xff, 0x8f, 0x07, 0x00, 0xf4, 0x01, 0xb5, 0xa2, 0x01 * j, 0x00 };
+ // r = update_feature_report(sv->udev[USB_DEV_WATCHMAN1], 0, vive_controller_haptic_pulse, sizeof(vive_controller_haptic_pulse));
+ // r = getupdate_feature_report(sv->udev[USB_DEV_WATCHMAN1], 0, vive_controller_haptic_pulse, sizeof(vive_controller_haptic_pulse));
+ // if (r != sizeof(vive_controller_haptic_pulse)) printf("HAPTIC FAILED **************************\n"); // return 5;
+ // OGUSleep(5000);
+ // }
+
+ // OGUSleep(20000);
+ //}
+
+ ////OGUSleep(5000);
+ //return 0;
+}
+
void survive_vive_usb_close( SurviveViveData * sv )
{
int i;
@@ -903,9 +958,10 @@ void incrementAndPostButtonQueue(SurviveContext *ctx)
{
ButtonQueueEntry *entry = &(ctx->buttonQueue.entry[ctx->buttonQueue.nextWriteIndex]);
- if (OGGetSema(ctx->buttonQueue.buttonservicesem) >= BUTTON_QUEUE_MAX_LEN)
+ if (OGGetSema(ctx->buttonQueue.buttonservicesem) >= BUTTON_QUEUE_MAX_LEN-1)
{
// There's not enough space to write this entry. Clear it out and move along
+ //printf("Button Buffer Full\n");
memset(entry, 0, sizeof(ButtonQueueEntry));
return;
}
@@ -1759,6 +1815,9 @@ void init_SurviveObject(SurviveObject* so) {
so->acc_bias = NULL;
so->gyro_scale = NULL;
so->gyro_bias = NULL;
+ so->haptic = NULL;
+ so->PoserData = NULL;
+ so->disambiguator_data = NULL;
}
int DriverRegHTCVive( SurviveContext * ctx )
@@ -1789,18 +1848,23 @@ int DriverRegHTCVive( SurviveContext * ctx )
hmd->ctx = ctx;
+ hmd->driver = sv;
memcpy( hmd->codename, "HMD", 4 );
memcpy( hmd->drivername, "HTC", 4 );
wm0->ctx = ctx;
+ wm0->driver = sv;
memcpy( wm0->codename, "WM0", 4 );
memcpy( wm0->drivername, "HTC", 4 );
wm1->ctx = ctx;
+ wm1->driver = sv;
memcpy( wm1->codename, "WM1", 4 );
memcpy( wm1->drivername, "HTC", 4 );
tr0->ctx = ctx;
+ tr0->driver = sv;
memcpy( tr0->codename, "TR0", 4 );
memcpy( tr0->drivername, "HTC", 4 );
ww0->ctx = ctx;
+ ww0->driver = sv;
memcpy( ww0->codename, "WW0", 4 );
memcpy( ww0->drivername, "HTC", 4 );
@@ -1844,6 +1908,9 @@ int DriverRegHTCVive( SurviveContext * ctx )
wm1->timecenter_ticks = wm1->timebase_hz / 240;
tr0->timecenter_ticks = tr0->timebase_hz / 240;
ww0->timecenter_ticks = ww0->timebase_hz / 240;
+
+ wm0->haptic = survive_vive_send_haptic;
+ wm1->haptic = survive_vive_send_haptic;
/*
int i;
int locs = hmd->nr_locations;