Пример #1
0
void Wiimote::StartReporting(uint8_t aReportMode)
{
    ULOG_DEBUG_F();

    if (cwiid_set_mesg_callback(mWiimote, &Wiimote::CWiidCallback)) {
        ULOG_DEBUG_F("Error setting callback");
        if (cwiid_close(mWiimote)) {
            ULOG_DEBUG_F("Error on disconnect");
        }
        mWiimote = NULL;
        NotifyConnectionStatus(IWiimoteObserver::EConnectionError);
        NotifyConnectionStatus(IWiimoteObserver::ENotConnected);
    } else {
        ULOG_DEBUG_F("Connected");
        if (cwiid_get_acc_cal(mWiimote, CWIID_EXT_NONE, &mWmCal)) {
            ULOG_DEBUG_F("Unable to retrieve accelerometer calibration");
        }

        NotifyConnectionStatus(IWiimoteObserver::EConnected);

        /*
        set_gui_state();
        set_report_mode();
        cwiid_enable(wiimote, CWIID_FLAG_MOTIONPLUS);
        */

        //uint8_t rpt_mode;
        //rpt_mode = CWIID_RPT_STATUS | CWIID_RPT_BTN | CWIID_RPT_ACC;
        if (cwiid_set_rpt_mode(mWiimote, aReportMode)) {
            ULOG_DEBUG_F("Error setting report mode");
        }

        cwiid_request_status(mWiimote);
    }
}
Пример #2
0
static PyObject *Wiimote_request_status(Wiimote *self)
{
	if (cwiid_request_status(self->wiimote)) {
		PyErr_SetString(PyExc_RuntimeError, "Error requesting wiimote status");
		return NULL;
	}

	Py_RETURN_NONE;
}
Пример #3
0
static void wiimote_status(t_wiimote *x)
{
  if(x->connected) {
    if (cwiid_request_status(x->wiimote)) {
      pd_error(x, "error requesting status message");
    }
  }
  wiimote_out_status(x, x->connected);
}
Пример #4
0
int cwiid_set_passthrough_mode(cwiid_wiimote_t *wiimote)
{
	unsigned char data1,data2;

	data1 = 0x55;
	cwiid_write(wiimote, CWIID_RW_REG, 0xA400F0, 1, &data1);
	data2 = 0x05;
	cwiid_write(wiimote, CWIID_RW_REG, 0xA600FE, 1, &data2);

	cwiid_request_status(wiimote);

	return 0;
}
Пример #5
0
int cwiid_enable(cwiid_wiimote_t *wiimote, int flags)
{
	unsigned char data;

	if ((flags & CWIID_FLAG_NONBLOCK) &&
	  !(wiimote->flags & CWIID_FLAG_NONBLOCK)) {
		if (fcntl(wiimote->mesg_pipe[0], F_SETFL, O_NONBLOCK)) {
			cwiid_err(wiimote, "File control error (mesg pipe)");
			return -1;
		}
	}
	if (flags & CWIID_FLAG_MOTIONPLUS) {
		data = 0x04;
		cwiid_write(wiimote, CWIID_RW_REG, 0xA600FE, 1, &data);
		cwiid_request_status(wiimote);
	}
	wiimote->flags |= flags;
	return 0;
}
Пример #6
0
void menuConnect_activate(void)
{
	char reset_bdaddr = 0;

	if (bacmp(&bdaddr, BDADDR_ANY) == 0) {
		reset_bdaddr = 1;
	}
	message(GTK_MESSAGE_INFO,
	        "Put Wiimote in discoverable mode (press 1+2) and press OK",
	         GTK_WINDOW(winMain));
	if ((wiimote = cwiid_open(&bdaddr, CWIID_FLAG_MESG_IFC)) == NULL) {
		message(GTK_MESSAGE_ERROR, "Unable to connect", GTK_WINDOW(winMain));
		status("No connection");
	}
	else if (cwiid_set_mesg_callback(wiimote, &cwiid_callback)) {
		message(GTK_MESSAGE_ERROR, "Error setting callback",
		        GTK_WINDOW(winMain));
		if (cwiid_close(wiimote)) {
			message(GTK_MESSAGE_ERROR, "Error on disconnect",
			        GTK_WINDOW(winMain));
		}
		wiimote = NULL;
		status("No connection");
	}
	else {
		status("Connected");
		if (cwiid_get_acc_cal(wiimote, CWIID_EXT_NONE, &wm_cal)) {
			message(GTK_MESSAGE_ERROR, "Unable to retrieve accelerometer "
			        "calibration", GTK_WINDOW(winMain));
		}
		set_gui_state();
		set_report_mode();
		cwiid_enable(wiimote, CWIID_FLAG_MOTIONPLUS);
		cwiid_request_status(wiimote);
	}

	if (reset_bdaddr) {
		bdaddr = *BDADDR_ANY;
	}
}
Пример #7
0
int cwiid_command(cwiid_wiimote_t *wiimote, enum cwiid_command command,
                  int flags) {
	int ret;

	switch (command) {
	case CWIID_CMD_STATUS:
		ret = cwiid_request_status(wiimote);
		break;
	case CWIID_CMD_LED:
		ret = cwiid_set_led(wiimote, flags);
		break;
	case CWIID_CMD_RUMBLE:
		ret = cwiid_set_rumble(wiimote, flags);
		break;
	case CWIID_CMD_RPT_MODE:
		ret = cwiid_set_rpt_mode(wiimote, flags);
		break;
	default:
		ret = -1;
		break;
	}

	return ret;
}
Пример #8
0
/* read the usb, and process it into frames
 * a return value < 0 indicates error */
int ltr_int_tracker_get_frame(struct camera_control_block *ccb,
                   struct frame_type *f, bool *frame_acquired)
{
  (void) ccb;
    struct cwiid_state state;
    unsigned int required_blobnum = 3;
    unsigned int valid;
    int i;
    
    //Otherwise the polling takes too much processor
    ltr_int_usleep(8334);

    if (!gStateCheckIn--) {
        gStateCheckIn = STATE_CHECK_INTERVAL;

        if (cwiid_request_status(gWiimote)) {
            ltr_int_log_message("Requesting status failed, disconnecting\n");
            cwiid_close(gWiimote);
            gWiimote = NULL;
            return -1;
        }
    }

    if (cwiid_get_state(gWiimote, &state)) {
        // Treat connection as disconnected on error
        ltr_int_log_message("Error reading wiimote state\n");
        cwiid_close(gWiimote);
        gWiimote = NULL;
        return -1;
    }
    
    valid = 0;
    for (i=0; i<CWIID_IR_SRC_COUNT; i++) {
        if (state.ir_src[i].valid) {
            valid++;
        }
    }
    
    f->width = WIIMOTE_HORIZONTAL_RESOLUTION / 2;
    f->height = WIIMOTE_VERTICAL_RESOLUTION / 2;
    f->bloblist.num_blobs = valid < required_blobnum ? valid : required_blobnum;
    f->bloblist.blobs = (struct blob_type *)
        ltr_int_my_malloc(f->bloblist.num_blobs*sizeof(struct blob_type));
    assert(f->bloblist.blobs);
    bool draw;
    if(f->bitmap != NULL){
      draw = true;
    }else{
      draw = false;
    }
    image_t img = {
      .w = WIIMOTE_HORIZONTAL_RESOLUTION / 2,
      .h = WIIMOTE_VERTICAL_RESOLUTION / 2,
      .bitmap = f->bitmap,
      .ratio = 1.0
    };
    valid = 0;
    for (i=0; i<CWIID_IR_SRC_COUNT; i++) {
        if (state.ir_src[i].valid) {
            if (valid<required_blobnum) {
                f->bloblist.blobs[valid].x = -1 * state.ir_src[i].pos[CWIID_X] + WIIMOTE_HORIZONTAL_RESOLUTION/2;
                f->bloblist.blobs[valid].y = state.ir_src[i].pos[CWIID_Y] - WIIMOTE_VERTICAL_RESOLUTION/2;
                f->bloblist.blobs[valid].score = state.ir_src[i].size;
                if(draw){
                  ltr_int_draw_square(&img, state.ir_src[i].pos[CWIID_X] / 2, (WIIMOTE_VERTICAL_RESOLUTION - state.ir_src[i].pos[CWIID_Y]) / 2, 2*state.ir_src[i].size);
                  ltr_int_draw_cross(&img, state.ir_src[i].pos[CWIID_X] / 2, (WIIMOTE_VERTICAL_RESOLUTION - state.ir_src[i].pos[CWIID_Y]) / 2, (int)WIIMOTE_HORIZONTAL_RESOLUTION/100.0);
                }
            }
            valid++;
        }
    }
    *frame_acquired = true;
    return 0;
}
Пример #9
0
int main(int argc, char *argv[])
{
	cwiid_wiimote_t *wiimote;	/* wiimote handle */
	struct cwiid_state state;	/* wiimote state */
	bdaddr_t bdaddr;	/* bluetooth device address */
	unsigned char mesg = 0;
	unsigned char led_state = 0;
	unsigned char rpt_mode = 0;
	unsigned char rumble = 0;
	int exit = 0;

	cwiid_set_err(err);

	/* Connect to address given on command-line, if present */
	if (argc > 1) {
		str2ba(argv[1], &bdaddr);
	}
	else {
		bdaddr = *BDADDR_ANY;
	}

	/* Connect to the wiimote */
	printf("Put Wiimote in discoverable mode now (press 1+2)...\n");
	if (!(wiimote = cwiid_open(&bdaddr, 0))) {
		fprintf(stderr, "Unable to connect to wiimote\n");
		return -1;
	}
	if (cwiid_set_mesg_callback(wiimote, cwiid_callback)) {
		fprintf(stderr, "Unable to set message callback\n");
	}

	printf("Note: To demonstrate the new API interfaces, wmdemo no longer "
	       "enables messages by default.\n"
		   "Output can be gathered through the new state-based interface (s), "
	       "or by enabling the messages interface (c).\n");

	/* Menu */
	printf("%s", MENU);

	while (!exit) {
		switch (getchar()) {
		case '1':
			toggle_bit(led_state, CWIID_LED1_ON);
			set_led_state(wiimote, led_state);
			break;
		case '2':
			toggle_bit(led_state, CWIID_LED2_ON);
			set_led_state(wiimote, led_state);
			break;
		case '3':
			toggle_bit(led_state, CWIID_LED3_ON);
			set_led_state(wiimote, led_state);
			break;
		case '4':
			toggle_bit(led_state, CWIID_LED4_ON);
			set_led_state(wiimote, led_state);
			break;
		case '5':
			toggle_bit(rumble, 1);
			if (cwiid_set_rumble(wiimote, rumble)) {
				fprintf(stderr, "Error setting rumble\n");
			}
			break;
		case 'a':
			toggle_bit(rpt_mode, CWIID_RPT_ACC);
			set_rpt_mode(wiimote, rpt_mode);
			break;
		case 'b':
			toggle_bit(rpt_mode, CWIID_RPT_BTN);
			set_rpt_mode(wiimote, rpt_mode);
			break;
		case 'e':
			/* CWIID_RPT_EXT is actually
			 * CWIID_RPT_NUNCHUK | CWIID_RPT_CLASSIC */
			toggle_bit(rpt_mode, CWIID_RPT_EXT);
			set_rpt_mode(wiimote, rpt_mode);
			break;
		case 'i':
			/* libwiimote picks the highest quality IR mode available with the
			 * other options selected (not including as-yet-undeciphered
			 * interleaved mode */
			toggle_bit(rpt_mode, CWIID_RPT_IR);
			set_rpt_mode(wiimote, rpt_mode);
			break;
		case 'm':
			if (!mesg) {
				if (cwiid_enable(wiimote, CWIID_FLAG_MESG_IFC)) {
					fprintf(stderr, "Error enabling messages\n");
				}
				else {
					mesg = 1;
				}
			}
			else {
				if (cwiid_disable(wiimote, CWIID_FLAG_MESG_IFC)) {
					fprintf(stderr, "Error disabling message\n");
				}
				else {
					mesg = 0;
				}
			}
			break;
		case 'p':
			printf("%s", MENU);
			break;
		case 'r':
			if (cwiid_request_status(wiimote)) {
				fprintf(stderr, "Error requesting status message\n");
			}
			break;
		case 's':
			if (cwiid_get_state(wiimote, &state)) {
				fprintf(stderr, "Error getting state\n");
			}
			print_state(&state);
			break;
		case 't':
			toggle_bit(rpt_mode, CWIID_RPT_STATUS);
			set_rpt_mode(wiimote, rpt_mode);
			break;
		case 'x':
			exit = -1;
			break;
		case '\n':
			break;
		default:
			fprintf(stderr, "invalid option\n");
		}
	}

	if (cwiid_close(wiimote)) {
		fprintf(stderr, "Error on wiimote disconnect\n");
		return -1;
	}

	return 0;
}
Пример #10
0
cwiid_wiimote_t *cwiid_new(int ctl_socket, int int_socket, int flags)
{
	struct wiimote *wiimote = NULL;
	char mesg_pipe_init = 0, status_pipe_init = 0, rw_pipe_init = 0,
	     state_mutex_init = 0, rw_mutex_init = 0, rpt_mutex_init = 0,
	     router_thread_init = 0, status_thread_init = 0;
	void *pthread_ret;
	int err;

	/* Allocate wiimote */
	if ((wiimote = malloc(sizeof *wiimote)) == NULL) {
		cwiid_err(NULL, "Memory allocation error (cwiid_wiimote_t)");
		goto ERR_HND;
	}

	/* set sockets and flags */
	wiimote->ctl_socket = ctl_socket;
	wiimote->int_socket = int_socket;
	wiimote->flags = flags;

	/* Global Lock, Store and Increment wiimote_id */
	err = pthread_mutex_lock(&global_mutex);
	if (err) {
		cwiid_err(NULL, "Mutex lock error (global mutex): %s", strerror(err));
		goto ERR_HND;
	}
	wiimote->id = wiimote_id++;
	err = pthread_mutex_unlock(&global_mutex);
	if (err) {
		cwiid_err(wiimote, "Mutex unlock error (global mutex) - "
		                   "deadlock warning: %s", strerror(err));
		goto ERR_HND;
	}

	/* Create pipes */
	if (pipe(wiimote->mesg_pipe)) {
		cwiid_err(wiimote, "Pipe creation error (mesg pipe): %s", strerror(errno));
		goto ERR_HND;
	}
	mesg_pipe_init = 1;
	if (pipe(wiimote->status_pipe)) {
		cwiid_err(wiimote, "Pipe creation error (status pipe): %s", strerror(errno));
		goto ERR_HND;
	}
	status_pipe_init = 1;
	if (pipe(wiimote->rw_pipe)) {
		cwiid_err(wiimote, "Pipe creation error (rw pipe): %s", strerror(errno));
		goto ERR_HND;
	}
	rw_pipe_init = 1;

	/* Setup blocking */
	if (fcntl(wiimote->mesg_pipe[1], F_SETFL, O_NONBLOCK)) {
		cwiid_err(wiimote, "File control error (mesg write pipe): %s", strerror(errno));
		goto ERR_HND;
	}
	if (wiimote->flags & CWIID_FLAG_NONBLOCK) {
		if (fcntl(wiimote->mesg_pipe[0], F_SETFL, O_NONBLOCK)) {
			cwiid_err(wiimote, "File control error (mesg read pipe): %s", strerror(errno));
			goto ERR_HND;
		}
	}

	/* Init mutexes */
	err = pthread_mutex_init(&wiimote->state_mutex, NULL);
	if (err) {
		cwiid_err(wiimote, "Mutex initialization error (state mutex): %s", strerror(err));
		goto ERR_HND;
	}
	state_mutex_init = 1;
	err = pthread_mutex_init(&wiimote->rw_mutex, NULL);
	if (err) {
		cwiid_err(wiimote, "Mutex initialization error (rw mutex): %s", strerror(err));
		goto ERR_HND;
	}
	rw_mutex_init = 1;
	err = pthread_mutex_init(&wiimote->rpt_mutex, NULL);
	if (err) {
		cwiid_err(wiimote, "Mutex initialization error (rpt mutex): %s", strerror(err));
		goto ERR_HND;
	}
	rpt_mutex_init = 1;

	/* Set rw_status before starting router thread */
	wiimote->rw_status = RW_IDLE;

	/* Launch interrupt socket listener and dispatch threads */
	err = pthread_create(&wiimote->router_thread, NULL,
	                   (void *(*)(void *))&router_thread, wiimote);
	if (err) {
		cwiid_err(wiimote, "Thread creation error (router thread): %s", strerror(err));
		goto ERR_HND;
	}
	router_thread_init = 1;
	err = pthread_create(&wiimote->status_thread, NULL,
	                   (void *(*)(void *))&status_thread, wiimote);
	if (err) {
		cwiid_err(wiimote, "Thread creation error (status thread): %s", strerror(err));
		goto ERR_HND;
	}
	status_thread_init = 1;

	/* Success!  Update state */
	memset(&wiimote->state, 0, sizeof wiimote->state);
	wiimote->mesg_callback = NULL;
	cwiid_set_led(wiimote, 0);
	cwiid_request_status(wiimote);

	return wiimote;

ERR_HND:
	if (wiimote) {
		/* Close threads */
		if (router_thread_init) {
			pthread_cancel(wiimote->router_thread);
			err = pthread_join(wiimote->router_thread, &pthread_ret);
			if (err) {
				cwiid_err(wiimote, "Thread join error (router thread): %s", strerror(err));
			}
			else if (!((pthread_ret == PTHREAD_CANCELED) &&
			         (pthread_ret == NULL))) {
				cwiid_err(wiimote, "Bad return value from router thread");
			}
		}

		if (status_thread_init) {
			pthread_cancel(wiimote->status_thread);
			err = pthread_join(wiimote->status_thread, &pthread_ret);
			if (err) {
				cwiid_err(wiimote, "Thread join error (status thread): %s", strerror(err));
			}
			else if (!((pthread_ret == PTHREAD_CANCELED) && (pthread_ret == NULL))) {
				cwiid_err(wiimote, "Bad return value from status thread");
			}
		}

		/* Close Pipes */
		if (mesg_pipe_init) {
			if (close(wiimote->mesg_pipe[0]) || close(wiimote->mesg_pipe[1])) {
				cwiid_err(wiimote, "Pipe close error (mesg pipe): %s", strerror(errno));
			}
		}
		if (status_pipe_init) {
			if (close(wiimote->status_pipe[0]) ||
			  close(wiimote->status_pipe[1])) {
				cwiid_err(wiimote, "Pipe close error (status pipe): %s", strerror(errno));
			}
		}
		if (rw_pipe_init) {
			if (close(wiimote->rw_pipe[0]) || close(wiimote->rw_pipe[1])) {
				cwiid_err(wiimote, "Pipe close error (rw pipe): %s", strerror(errno));
			}
		}
		/* Destroy Mutexes */
		if (state_mutex_init) {
			err = pthread_mutex_destroy(&wiimote->state_mutex);
			if (err) {
				cwiid_err(wiimote, "Mutex destroy error (state mutex): %s", strerror(err));
			}
		}
		if (rw_mutex_init) {
			err = pthread_mutex_destroy(&wiimote->rw_mutex);
			if (err) {
				cwiid_err(wiimote, "Mutex destroy error (rw mutex): %s", strerror(err));
			}
		}
		if (rpt_mutex_init) {
			err = pthread_mutex_destroy(&wiimote->rpt_mutex);
			if (err) {
				cwiid_err(wiimote, "Mutex destroy error (rpt mutex): %s", strerror(err));
			}
		}
		free(wiimote);
	}
	return NULL;
}
Пример #11
0
void *passthrough_polling_thread(struct wiimote *wiimote)
{
	unsigned char buf, data;	

	while(1)
	{
		if ((wiimote->passthrough_activate_flag && wiimote->ext == NUNCHUK_MOTIONPLUS_PRESENT) || 
				(wiimote->passthrough_activate_flag && wiimote->ext == CLASSIC_MOTIONPLUS_PRESENT) || 
				(!wiimote->passthrough_activate_flag && wiimote->ext == MOTIONPLUS_PRESENT) || 
				(!wiimote->passthrough_activate_flag && wiimote->ext == EXT_PRESENT_NOT_MOTIONPLUS))
		{
			pthread_mutex_lock(&wiimote->poll_mutex);
			pthread_cond_wait(&wiimote->condition_var,&wiimote->poll_mutex);
			pthread_mutex_unlock(&wiimote->poll_mutex);
		}

		//fprintf(stderr,"passthrough_thread: resume\n");

		if (wiimote->passthrough_activate_flag) {

			//fprintf(stderr,"passthrough_thread: try activating passthrough\n");

			if (wiimote->ext != NUNCHUK_MOTIONPLUS_PRESENT && wiimote->ext != CLASSIC_MOTIONPLUS_PRESENT && wiimote->ext != MOTIONPLUS_PRESENT) {
				/* re-detecting motionplus */
				buf=0xAB;																	//any junk value initialisation
				cwiid_try_read(wiimote, CWIID_RW_REG, 0xA600FE, 1, &buf);					//Checking for the MotionPlus jackin
				if(buf==0x00 || buf==0x04 || buf==0x05 )	
				{														
					cwiid_enable(wiimote, CWIID_FLAG_MOTIONPLUS);
				}
			}

			if (wiimote->ext == MOTIONPLUS_PRESENT) {
				/* motionplus_present trying passthrough */
				data = 0x55;
				cwiid_write(wiimote, CWIID_RW_REG, 0xA400F0, 1, &data);
				data = 0x00;
				cwiid_write(wiimote, CWIID_RW_REG, 0xA400FB, 1, &data);
			}

			usleep(POLL_THREAD_DELAY);
			cwiid_request_status(wiimote);

		} else {

			/* disabling passthrough and/or re-detecting motionplus if necessary */

			/* only do this call if some other expansion is not already connected
			   this works because in this implementation motionplus takes precedence
			   over other kinds of extensions, like nunchuk and classic */

			//fprintf(stderr,"passthrough_thread: reverting to motionplus\n");

			if (wiimote->ext != EXT_PRESENT_NOT_MOTIONPLUS && wiimote->ext != EXT_UNINITIALIZED) {

				//fprintf(stderr,"passthrough_thread: !EXT_PRESENT_NOT_MOTIONPLUS\n");
				data = 0x55;
				cwiid_write(wiimote, CWIID_RW_REG, 0xA400F0, 1, &data);
				data = 0x00;
				cwiid_write(wiimote, CWIID_RW_REG, 0xA400FB, 1, &data);

				buf=0xAB;																	//any junk value initialisation
				cwiid_try_read(wiimote, CWIID_RW_REG, 0xA600FE, 1, &buf);					//Checking for the MotionPlus jackin
				if(buf==0x00 || buf==0x04 || buf==0x05 || buf==0x07)	
				{												
					cwiid_enable(wiimote, CWIID_FLAG_MOTIONPLUS);

					usleep(POLL_THREAD_DELAY);
					cwiid_request_status(wiimote);
				}
			}
		}				
	}

	return NULL;
}