-
Notifications
You must be signed in to change notification settings - Fork 178
Usb motor control
jacqu edited this page Sep 6, 2013
·
7 revisions
/**
* Host-side USB direct command example
*
* Prerequisite : sudo apt-get install libusb-dev
* Compilation : gcc -o usbcmd usbcmd.c -lusb
* Execution : sudo ./usbcmd
*
* [email protected], 5/9/13
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <usb.h>
#define EV3_USB_TIMEOUT 2000 // Milliseconds
#define EV3_USB_NAME_LENGTH 32
/* These informations can be obtained with lsusb -v */
#define EV3_INTERFACE_NUMBER 0
#define EV3_CONFIGURATION_NB 1
#define EV3_EP_OUT 0x01
#define EV3_EP_IN 0x81
/* Error codes */
#define EV3_OK 0
#define EV3_NOT_PRESENT 1
#define EV3_CONFIGURATION_ERROR 2
#define EV3_IN_USE 3
#define EV3_USB_WRITE_ERROR 4
#define EV3_USB_READ_ERROR 5
enum ev3_usb_ids {
VENDOR_LEGO = 0x0694,
PRODUCT_EV3 = 0x0005
};
struct ev3_t {
struct usb_device *dev;
struct usb_dev_handle *hdl;
};
typedef unsigned char ev3_error_t;
typedef struct ev3_t ev3_t;
ev3_error_t ev3_init( ev3_t **ev3 ) {
usb_init( );
*ev3 = calloc( 1, sizeof( **ev3 ) );
return EV3_OK;
}
ev3_error_t ev3_find( ev3_t *ev3 ) {
struct usb_bus *busses, *bus;
usb_find_busses( );
usb_find_devices( );
busses = usb_get_busses( );
for ( bus = busses; bus != NULL; bus = bus->next ) {
struct usb_device *dev;
for ( dev = bus->devices; dev != NULL; dev = dev->next ) {
if ( dev->descriptor.idVendor == VENDOR_LEGO &&
dev->descriptor.idProduct == PRODUCT_EV3 ) {
ev3->dev = dev;
return EV3_OK;
}
}
}
return EV3_NOT_PRESENT;
}
ev3_error_t ev3_open( ev3_t *ev3 ) {
char bound_driver_name[EV3_USB_NAME_LENGTH];
int ret;
ev3->hdl = usb_open( ev3->dev );
/* Detach possible kernel driver bound to interface */
if ( usb_get_driver_np( ev3->hdl, EV3_INTERFACE_NUMBER, bound_driver_name, EV3_USB_NAME_LENGTH ) == 0 ) {
if ( usb_detach_kernel_driver_np( ev3->hdl, EV3_INTERFACE_NUMBER ) < 0 ) {
usb_close( ev3->hdl );
return EV3_IN_USE;
}
}
ret = usb_set_configuration( ev3->hdl, EV3_CONFIGURATION_NB );
if ( ret < 0 ) {
usb_close( ev3->hdl );
return EV3_CONFIGURATION_ERROR;
}
ret = usb_claim_interface( ev3->hdl, EV3_INTERFACE_NUMBER );
if ( ret < 0 ) {
usb_close( ev3->hdl );
return EV3_IN_USE;
}
return EV3_OK;
}
ev3_error_t ev3_close( ev3_t *ev3 ) {
usb_release_interface( ev3->hdl, EV3_INTERFACE_NUMBER );
usb_close( ev3->hdl );
free( ev3 );
return EV3_OK;
}
ev3_error_t ev3_send_buf( ev3_t *ev3, char *buf, int len ) {
int ret = usb_bulk_write( ev3->hdl, EV3_EP_OUT, buf, len, EV3_USB_TIMEOUT );
if ( ret < 0 )
return EV3_USB_WRITE_ERROR;
return EV3_OK;
}
ev3_error_t ev3_send_str( ev3_t *ev3, char *str ) {
return ev3_send_buf( ev3, str, strlen( str ) );
}
ev3_error_t ev3_recv_buf( ev3_t *ev3, char *buf, int len ) {
int ret = usb_bulk_read( ev3->hdl, EV3_EP_IN, buf, len, EV3_USB_TIMEOUT );
if ( ret < 0 )
return EV3_USB_READ_ERROR;
return EV3_OK;
}
void main( void ) {
ev3_t *ev3;
ev3_error_t err;
/* See file "c_com.h" in "ev3sources/lms2012/c_com" (https://github.com/mindboards/ev3sources) */
char ev3_motor_start[] = "\x0C\x00\x00\x00\x80\x00\x00\xA4\x00\x01\x14\xA6\x00\x01";
char ev3_motor_stop[] = "\x09\x00\x01\x00\x80\x00\x00\xA3\x00\x01\x00";
/* Initialize libusb */
ev3_init( &ev3 );
/* Look for an EV3 in USB devices list */
err = ev3_find( ev3 );
if ( err ) {
if ( err == EV3_NOT_PRESENT )
fprintf( stderr, "EV3 not found. Is it properly plugged in USB port?\n" );
else
fprintf( stderr, "Error while scanning for EV3.\n" );
exit( 1 );
}
/* Open EV3 USB port */
err = ev3_open( ev3 );
if ( err ) {
if ( err == EV3_CONFIGURATION_ERROR )
fprintf( stderr, "EV3 USB configuration error.\n" );
else
fprintf( stderr, "Error while opening EV3 USB port.\n" );
exit( 2 );
}
/* Start motor on port A at 20% */
ev3_send_buf( ev3, ev3_motor_start, sizeof( ev3_motor_start ) - 1 );
/* Sleep for some time */
usleep( 1000000 );
/* Stop motor on port A, floating */
ev3_send_buf( ev3, ev3_motor_stop, sizeof( ev3_motor_stop ) - 1 );
/* Close EV3 USB port */
ev3_close( ev3 );
}