Merge remote-tracking branch 'upstream/sync-mplus' into osx-refactor_sync-mplus

Conflicts:
	src/events.c
	src/io.c
	src/io.h
	src/io_mac.m
	src/os_nix.c
	src/wiiuse_internal.h
This commit is contained in:
Lysann Schlegel
2012-12-08 17:59:47 +01:00
14 changed files with 317 additions and 52 deletions

202
src/io.c
View File

@@ -33,8 +33,9 @@
#include "io.h"
#include "ir.h" /* for wiiuse_set_ir_mode */
#include "wiiuse_internal.h"
#include "os.h" /* for wiiuse_os_* */
#include "os.h" /* for wiiuse_os_* */
#include <stdlib.h> /* for free, malloc */
@@ -108,25 +109,91 @@ void wiiuse_disconnect(struct wiimote_t* wm) {
wiiuse_os_disconnect(wm);
}
static void wiiuse_disable_motion_plus2(struct wiimote_t *wm,byte *data,unsigned short len)
{
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_FAILED);
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE);
wiiuse_set_ir_mode(wm);
wm->handshake_state++;
wiiuse_handshake(wm, NULL, 0);
}
static void wiiuse_disable_motion_plus1(struct wiimote_t *wm,byte *data,unsigned short len)
{
byte val = 0x00;
wiiuse_write_data_cb(wm, WM_EXP_MEM_ENABLE1, &val, 1, wiiuse_disable_motion_plus2);
}
/**
* @brief Wait until specified report arrives and return it
*
* @param wm Pointer to a wiimote_t structure.
* @param buffer Pre-allocated memory to store the received data
* @param bufferLength size of buffer in bytes
*
* Synchronous/blocking, this function will not return until it receives the specified
* report from the Wiimote.
*
*/
void wiiuse_wait_report(struct wiimote_t *wm, int report, byte *buffer, int bufferLength)
{
for(;;)
{
if(wiiuse_os_read(wm, buffer, bufferLength) > 0) {
if(buffer[1] == report) {
break;
} else {
WIIUSE_WARNING("(id %i) dropping report 0x%x, waiting for 0x%x", wm->unid, buffer[1], report);
}
}
}
}
/**
* @brief Read memory/register data synchronously
*
* @param wm Pointer to a wiimote_t structure.
* @param memory If set to non-zero, reads EEPROM, otherwise registers
* @param addr Address offset to read from
* @param size How many bytes to read
* @param data Pre-allocated memory to store the received data
*
* Synchronous/blocking read, this function will not return until it receives the specified
* amount of data from the Wiimote.
*
*/
void wiiuse_read(struct wiimote_t *wm, byte memory, unsigned addr, unsigned short size, byte *data)
{
byte pkt[8];
byte buf[MAX_PAYLOAD];
unsigned n_full_reports;
unsigned last_report;
byte *output;
int i;
/*
* address in big endian first, the leading byte will
* be overwritten (only 3 bytes are sent)
*/
to_big_endian_uint32_t(pkt + 2, addr);
pkt[0] = 0x52; /* HID read command */
pkt[1] = 0x17; /* report 17 - read */
pkt[2] = (memory != 0) ? 0x00 : 0x04; /* read from registers or memory*/
/*
* length in big endian
*/
to_big_endian_uint16_t(pkt + 6, size);
/* calculate how many 16B packets we have to get back */
n_full_reports = size / 16;
last_report = size % 16;
output = data;
wiiuse_os_write(wm, pkt, 8);
for(i = 0; i < n_full_reports; ++i)
{
wiiuse_wait_report(wm, 0x21, buf, MAX_PAYLOAD);
memmove(output, buf + 7, 16);
output += 16;
}
/* read the last incomplete packet */
if(last_report)
{
wiiuse_wait_report(wm, 0x21, buf, MAX_PAYLOAD);
memmove(output, buf + 7, last_report);
}
}
/**
* @brief Get initialization data from the wiimote.
*
* @param wm Pointer to a wiimote_t structure.
@@ -139,18 +206,95 @@ static void wiiuse_disable_motion_plus1(struct wiimote_t *wm,byte *data,unsigned
* The handshake will be concluded when the wiimote responds
* with this data.
*/
#define SYNC_HANDSHAKE 1
#ifdef SYNC_HANDSHAKE
void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len)
{
/* send request to wiimote for accelerometer calibration */
byte buf[MAX_PAYLOAD];
/* step 0 - Reset wiimote */
{
//wiiuse_set_leds(wm, WIIMOTE_LED_NONE);
WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_ACC);
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP);
WIIMOTE_DISABLE_FLAG(wm, WIIUSE_CONTINUOUS);
wiiuse_set_report_type(wm);
wiiuse_millisleep(500);
WIIUSE_DEBUG("Wiimote reset!\n");
}
/* step 1 - calibration of accelerometers */
{
struct accel_t* accel = &wm->accel_calib;
wiiuse_read(wm, 1, WM_MEM_OFFSET_CALIBRATION, 8, buf);
/* received read data */
accel->cal_zero.x = buf[0];
accel->cal_zero.y = buf[1];
accel->cal_zero.z = buf[2];
accel->cal_g.x = buf[4] - accel->cal_zero.x;
accel->cal_g.y = buf[5] - accel->cal_zero.y;
accel->cal_g.z = buf[6] - accel->cal_zero.z;
WIIUSE_DEBUG("Calibrated wiimote acc\n");
}
/* step 2 - re-enable IR and ask for status */
{
WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE);
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
/* now enable IR if it was set before the handshake completed */
if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR))
{
WIIUSE_DEBUG("Handshake finished, enabling IR.");
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
wiiuse_set_ir(wm, 1);
}
WIIUSE_DEBUG("Asking for status ...\n");
wm->event = WIIUSE_CONNECT;
wiiuse_status(wm);
}
}
#else
static void wiiuse_disable_motion_plus1(struct wiimote_t *wm,byte *data,unsigned short len);
static void wiiuse_disable_motion_plus2(struct wiimote_t *wm,byte *data,unsigned short len);
void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len) {
if (!wm) return;
switch (wm->handshake_state) {
case 0:
{
/* send request to wiimote for accelerometer calibration */
byte* buf;
/* continous reporting off, report to buttons only */
WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
wiiuse_set_leds(wm, WIIMOTE_LED_NONE);
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_ACC);
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
WIIMOTE_DISABLE_FLAG(wm, WIIUSE_CONTINUOUS);
wiiuse_set_report_type(wm);
/* send request to wiimote for accelerometer calibration */
buf = (byte*)malloc(sizeof(byte) * 8);
wiiuse_read_data_cb(wm, wiiuse_handshake, buf, WM_MEM_OFFSET_CALIBRATION, 7);
wm->handshake_state++;
@@ -216,3 +360,21 @@ void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len) {
}
}
}
static void wiiuse_disable_motion_plus1(struct wiimote_t *wm,byte *data,unsigned short len)
{
byte val = 0x00;
wiiuse_write_data_cb(wm, WM_EXP_MEM_ENABLE1, &val, 1, wiiuse_disable_motion_plus2);
}
static void wiiuse_disable_motion_plus2(struct wiimote_t *wm,byte *data,unsigned short len)
{
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_FAILED);
WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP_HANDSHAKE);
wiiuse_set_ir_mode(wm);
wm->handshake_state++;
wiiuse_handshake(wm, NULL, 0);
}
#endif