예제 #1
0
int sick_test_baudrate(sick_laser_t* sick, int max_retries){
  //	printf ("Test baudrate ... ");
  int baudrates[]={9600, 19200, 38400, 500000};
  int baudrates_no=4;
  unsigned char reply[8192];
  int i;
  sick->baudrate=0;
  for (i=0; i<baudrates_no; i++){
    int j=0;
    serial_configure(sick->fd, baudrates[i], "8N1");
#ifdef USE_TCP862
    tcp862_setBaud(sick->fd,baudrates[i]);
#endif
    fprintf (stderr, "%d ", baudrates[i]);
    while(j<max_retries){
      j++;
      fprintf(stderr,".");
      //FIXME
      int response=sick_send_packet_noack(sick, reply, cmd_stop_continuous_mode, cmd_stop_continuous_mode_size);
      if (! response){
	continue;
      }
      usleep(10000);
      //			fprintf(stderr, "c");
      response=sick_send_packet(sick, reply, cmd_stop_continuous_mode, cmd_stop_continuous_mode_size);
      if (response){
	sick->baudrate=baudrates[i];
	fprintf(stderr," success\n");
	return baudrates[i];
      }
    }
    fprintf(stderr," failed\n                                     ");
  }
  return -1;
}
예제 #2
0
dc_status_t
shearwater_common_open (shearwater_common_device_t *device, dc_context_t *context, const char *name)
{
	// Open the device.
	int rc = serial_open (&device->port, context, name);
	if (rc == -1) {
		ERROR (context, "Failed to open the serial port.");
		return DC_STATUS_IO;
	}

	// Set the serial communication protocol (115200 8N1).
	rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
	if (rc == -1) {
		ERROR (context, "Failed to set the terminal attributes.");
		serial_close (device->port);
		return DC_STATUS_IO;
	}

	// Set the timeout for receiving data (3000ms).
	if (serial_set_timeout (device->port, 3000) == -1) {
		ERROR (context, "Failed to set the timeout.");
		serial_close (device->port);
		return DC_STATUS_IO;
	}

	// Make sure everything is in a sane state.
	serial_sleep (device->port, 300);
	serial_flush (device->port, SERIAL_QUEUE_BOTH);

	return DC_STATUS_SUCCESS;
}
예제 #3
0
dc_status_t
shearwater_common_custom_open (shearwater_common_device_t *device, dc_context_t *context, dc_serial_t *serial)
{
	// Set the serial reference
	device->serial = serial;

	if (serial->type == DC_TRANSPORT_SERIAL) {
		// Set the serial communication protocol (115200 8N1).
		int rc = serial_configure (device->serial->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
		if (rc == -1) {
			ERROR (context, "Failed to set the terminal attributes.");
			device->serial->ops->close (device->serial->port);
			return DC_STATUS_IO;
		}
	}

	// Set the timeout for receiving data (3000ms).
	if (device->serial->ops->set_timeout (device->serial->port, 3000) == -1) {
		ERROR (context, "Failed to set the timeout.");
		device->serial->ops->close (device->serial->port);
		return DC_STATUS_IO;
	}

	// Make sure everything is in a sane state.
	serial_sleep (device->serial->port, 300);
	device->serial->ops->flush (device->serial->port, SERIAL_QUEUE_BOTH);

	return DC_STATUS_SUCCESS;
}
예제 #4
0
dc_status_t
uwatec_meridian_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{
	if (out == NULL)
		return DC_STATUS_INVALIDARGS;

	// Allocate memory.
	uwatec_meridian_device_t *device = (uwatec_meridian_device_t *) malloc (sizeof (uwatec_meridian_device_t));
	if (device == NULL) {
		ERROR (context, "Failed to allocate memory.");
		return DC_STATUS_NOMEMORY;
	}

	// Initialize the base class.
	device_init (&device->base, context, &uwatec_meridian_device_vtable);

	// Set the default values.
	device->port = NULL;
	device->timestamp = 0;
	device->systime = (dc_ticks_t) -1;
	device->devtime = 0;

	// Open the device.
	int rc = serial_open (&device->port, context, name);
	if (rc == -1) {
		ERROR (context, "Failed to open the serial port.");
		free (device);
		return DC_STATUS_IO;
	}

	// Set the serial communication protocol (57600 8N1).
	rc = serial_configure (device->port, 57600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
	if (rc == -1) {
		ERROR (context, "Failed to set the terminal attributes.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Set the timeout for receiving data (3000ms).
	if (serial_set_timeout (device->port, 3000) == -1) {
		ERROR (context, "Failed to set the timeout.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Make sure everything is in a sane state.
	serial_flush (device->port, SERIAL_QUEUE_BOTH);

	// Perform the handshaking.
	uwatec_meridian_handshake (device);

	*out = (dc_device_t*) device;

	return DC_STATUS_SUCCESS;
}
예제 #5
0
dc_status_t
cressi_leonardo_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{
	if (out == NULL)
		return DC_STATUS_INVALIDARGS;

	// Allocate memory.
	cressi_leonardo_device_t *device = (cressi_leonardo_device_t *) malloc (sizeof (cressi_leonardo_device_t));
	if (device == NULL) {
		ERROR (context, "Failed to allocate memory.");
		return DC_STATUS_NOMEMORY;
	}

	// Initialize the base class.
	device_init (&device->base, context, &cressi_leonardo_device_vtable);

	// Set the default values.
	device->port = NULL;

	// Open the device.
	int rc = serial_open (&device->port, context, name);
	if (rc == -1) {
		ERROR (context, "Failed to open the serial port.");
		free (device);
		return DC_STATUS_IO;
	}

	// Set the serial communication protocol (115200 8N1).
	rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
	if (rc == -1) {
		ERROR (context, "Failed to set the terminal attributes.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Set the timeout for receiving data (1000 ms).
	if (serial_set_timeout (device->port, 1000) == -1) {
		ERROR (context, "Failed to set the timeout.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Clear the DTR and set the RTS line.
	if (serial_set_dtr (device->port, 0) == -1 ||
		serial_set_rts (device->port, 1) == -1) {
		ERROR (context, "Failed to set the DTR/RTS line.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	*out = (dc_device_t *) device;

	return DC_STATUS_SUCCESS;
}
예제 #6
0
파일: uxser.c 프로젝트: halcy/PuTTY
static void serial_reconfig(void *handle, Conf *conf)
{
    Serial serial = (Serial) handle;

    /*
     * FIXME: what should we do if this returns an error?
     */
    serial_configure(serial, conf);
}
예제 #7
0
void setup_movement(void)
{
	serial_configure(9600);
	set_PWM(LEF1, 0);
	set_PWM(LEF0, 0);
	set_PWM(RIG0, 0);
	set_PWM(RIG1, 0);
	start_encoder();
}
예제 #8
0
device_status_t
suunto_eon_device_open (device_t **out, const char* name)
{
	if (out == NULL)
		return DEVICE_STATUS_ERROR;

	// Allocate memory.
	suunto_eon_device_t *device = (suunto_eon_device_t *) malloc (sizeof (suunto_eon_device_t));
	if (device == NULL) {
		WARNING ("Failed to allocate memory.");
		return DEVICE_STATUS_MEMORY;
	}

	// Initialize the base class.
	suunto_common_device_init (&device->base, &suunto_eon_device_backend);

	// Set the default values.
	device->port = NULL;

	// Open the device.
	int rc = serial_open (&device->port, name);
	if (rc == -1) {
		WARNING ("Failed to open the serial port.");
		free (device);
		return DEVICE_STATUS_IO;
	}

	// Set the serial communication protocol (1200 8N2).
	rc = serial_configure (device->port, 1200, 8, SERIAL_PARITY_NONE, 2, SERIAL_FLOWCONTROL_NONE);
	if (rc == -1) {
		WARNING ("Failed to set the terminal attributes.");
		serial_close (device->port);
		free (device);
		return DEVICE_STATUS_IO;
	}

	// Set the timeout for receiving data (1000ms).
	if (serial_set_timeout (device->port, -1) == -1) {
		WARNING ("Failed to set the timeout.");
		serial_close (device->port);
		free (device);
		return DEVICE_STATUS_IO;
	}

	// Clear the RTS line.
	if (serial_set_rts (device->port, 0)) {
		WARNING ("Failed to set the DTR/RTS line.");
		serial_close (device->port);
		free (device);
		return DEVICE_STATUS_IO;
	}

	*out = (device_t*) device;

	return DEVICE_STATUS_SUCCESS;
}
예제 #9
0
파일: winser.c 프로젝트: rdebath/sgt
static void serial_reconfig(void *handle, Config *cfg)
{
    Serial serial = (Serial) handle;
    const char *err;

    err = serial_configure(serial, serial->port, cfg);

    /*
     * FIXME: what should we do if err returns something?
     */
}
예제 #10
0
파일: winser.c 프로젝트: NaldoDj/VeraCrypt
static void serial_reconfig(Backend *be, Conf *conf)
{
    Serial *serial = container_of(be, Serial, backend);

    serial_configure(serial, serial->port, conf);

    /*
     * FIXME: what should we do if that call returned a non-NULL error
     * message?
     */
}
예제 #11
0
dc_status_t
hw_ostc_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{
	if (out == NULL)
		return DC_STATUS_INVALIDARGS;

	// Allocate memory.
	hw_ostc_device_t *device = (hw_ostc_device_t *) malloc (sizeof (hw_ostc_device_t));
	if (device == NULL) {
		ERROR (context, "Failed to allocate memory.");
		return DC_STATUS_NOMEMORY;
	}

	// Initialize the base class.
	device_init (&device->base, context, &hw_ostc_device_vtable);

	// Set the default values.
	device->port = NULL;
	memset (device->fingerprint, 0, sizeof (device->fingerprint));

	// Open the device.
	int rc = serial_open (&device->port, context, name);
	if (rc == -1) {
		ERROR (context, "Failed to open the serial port.");
		free (device);
		return DC_STATUS_IO;
	}

	// Set the serial communication protocol (115200 8N1).
	rc = serial_configure (device->port, 115200, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
	if (rc == -1) {
		ERROR (context, "Failed to set the terminal attributes.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Set the timeout for receiving data.
	if (serial_set_timeout (device->port, 4000) == -1) {
		ERROR (context, "Failed to set the timeout.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Make sure everything is in a sane state.
	serial_sleep (device->port, 100);
	serial_flush (device->port, SERIAL_QUEUE_BOTH);

	*out = (dc_device_t*) device;

	return DC_STATUS_SUCCESS;
}
예제 #12
0
int sick_set_baudrate(sick_laser_t* sick, int max_retries, int brate){
  unsigned char command[2];
  unsigned char reply[1024];
  int j=0;
  int currentbrate=sick->baudrate;
  int max_response_retries=5;
  command[0]=0x20;
  if(brate == 500000)
    command[1] = 0x48;
  else if(brate == 38400) 
    command[1] = 0x40;
  else if(brate == 19200) 
    command[1] = 0x41;
  else
    command[1] = 0x42;

  serial_configure(sick->fd, currentbrate, "8N1");
  while(j<max_retries){
    sick_send_packet_noanswer(sick, command, 2);
    //sick_send_packet_noack(sick, reply, command, 2);
    serial_configure(sick->fd, currentbrate, "8N1");
	  
    //serial_ClearInputBuffer(sick->fd);
    int response=0;
    int response_retries=0;
    while(! response && response_retries< max_response_retries){
      response=sick_send_packet_noack(sick, reply, cmd_request_status, cmd_request_status_size);
		  
      response_retries+=(!response);
      usleep(1);
      //      fprintf(stderr, " %d", response_retries);
    }
    if (response){
      return response;
    }
    j++;
  }
  return 0;
}
예제 #13
0
파일: uxser.c 프로젝트: halcy/PuTTY
/*
 * Called to set up the serial connection.
 * 
 * Returns an error message, or NULL on success.
 *
 * Also places the canonical host name into `realhost'. It must be
 * freed by the caller.
 */
static const char *serial_init(void *frontend_handle, void **backend_handle,
			       Conf *conf,
			       const char *host, int port, char **realhost,
                               int nodelay, int keepalive)
{
    Serial serial;
    const char *err;
    char *line;

    serial = snew(struct serial_backend_data);
    *backend_handle = serial;

    serial->frontend = frontend_handle;
    serial->finished = FALSE;
    serial->inbufsize = 0;
    bufchain_init(&serial->output_data);

    line = conf_get_str(conf, CONF_serline);
    {
	char *msg = dupprintf("Opening serial device %s", line);
	logevent(serial->frontend, msg);
        sfree(msg);
    }

    serial->fd = open(line, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
    if (serial->fd < 0)
	return "Unable to open serial port";

    cloexec(serial->fd);

    err = serial_configure(serial, conf);
    if (err)
	return err;

    *realhost = dupstr(line);

    if (!serial_by_fd)
	serial_by_fd = newtree234(serial_compare_by_fd);
    add234(serial_by_fd, serial);

    serial_uxsel_setup(serial);

    /*
     * Specials are always available.
     */
    update_specials_menu(serial->frontend);

    return NULL;
}
예제 #14
0
파일: winser.c 프로젝트: rdebath/sgt
/*
 * Called to set up the serial connection.
 * 
 * Returns an error message, or NULL on success.
 *
 * Also places the canonical host name into `realhost'. It must be
 * freed by the caller.
 */
static const char *serial_init(void *frontend_handle, void **backend_handle,
			       Config *cfg,
			       char *host, int port, char **realhost, int nodelay,
			       int keepalive)
{
    Serial serial;
    HANDLE serport;
    const char *err;

    serial = snew(struct serial_backend_data);
    serial->port = INVALID_HANDLE_VALUE;
    serial->out = serial->in = NULL;
    serial->bufsize = 0;
    serial->break_in_progress = FALSE;
    *backend_handle = serial;

    serial->frontend = frontend_handle;

    {
	char *msg = dupprintf("Opening serial device %s", cfg->serline);
	logevent(serial->frontend, msg);
    }

    serport = CreateFile(cfg->serline, GENERIC_READ | GENERIC_WRITE, 0, NULL,
			 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
    if (serport == INVALID_HANDLE_VALUE)
	return "Unable to open serial port";

    err = serial_configure(serial, serport, cfg);
    if (err)
	return err;

    serial->port = serport;
    serial->out = handle_output_new(serport, serial_sentdata, serial,
				    HANDLE_FLAG_OVERLAPPED);
    serial->in = handle_input_new(serport, serial_gotdata, serial,
				  HANDLE_FLAG_OVERLAPPED |
				  HANDLE_FLAG_IGNOREEOF |
				  HANDLE_FLAG_UNITBUFFER);

    *realhost = dupstr(cfg->serline);

    /*
     * Specials are always available.
     */
    update_specials_menu(serial->frontend);

    return NULL;
}
예제 #15
0
void uart__init(void)
{
    /* Iniitialise the UART */
    printf("Initialising UART driver\n");
    if(exynos_serial_init(DEV_ID, uart0base, NULL, &uart_dummy_clk,
            &serial_device)){
        printf("Failed to initialise UART\n");
        while(1);
    }
    ps_cdev_set_flags(&serial_device, serial_device.flags & ~SERIAL_AUTO_CR);
    serial_configure(&serial_device, BAUD_RATE, 8, PARITY_NONE, 1);
    /* Prime semaphores */
    read_sem_wait();
    write_sem_wait();
}
예제 #16
0
void pre_init(void)
{
    /* Initialise the UART */
    printf("Initialising UART driver\n");
    if(exynos_serial_init(DEV_ID, (void *) vaddr, NULL, NULL, &serial_device)){
        printf("Failed to initialise UART\n");
        while(1);
    }
    serial_configure(&serial_device, BAUD_RATE, 8, PARITY_NONE, 1);
    serial_device.flags &= ~SERIAL_AUTO_CR;

    /* Prime semaphore */
    read_sem_wait();

    /* Register for IRQs */
    interrupt_acknowledge();
}
예제 #17
0
/*
 * Think twice before modifying the code for updating the ostc firmware!
 * It has been carefully developed and tested with assistance from
 * Heinrichs-Weikamp, using a special development unit. If you start
 * experimenting with a normal unit and accidentally screw up, you might
 * brick the device permanently and turn it into an expensive
 * paperweight. You have been warned!
 */
dc_status_t
hw_ostc_device_fwupdate (dc_device_t *abstract, const char *filename)
{
	dc_status_t rc = DC_STATUS_SUCCESS;
	hw_ostc_device_t *device = (hw_ostc_device_t *) abstract;
	dc_context_t *context = (abstract ? abstract->context : NULL);

	if (!ISINSTANCE (abstract))
		return DC_STATUS_INVALIDARGS;

	// Allocate memory for the firmware data.
	hw_ostc_firmware_t *firmware = (hw_ostc_firmware_t *) malloc (sizeof (hw_ostc_firmware_t));
	if (firmware == NULL) {
		ERROR (context, "Failed to allocate memory.");
		return DC_STATUS_NOMEMORY;
	}

	// Read the hex file.
	rc = hw_ostc_firmware_readfile (firmware, context, filename);
	if (rc != DC_STATUS_SUCCESS) {
		ERROR (context, "Failed to read the firmware file.");
		free (firmware);
		return rc;
	}

	// Temporary set a relative short timeout. The command to setup the
	// bootloader needs to be send repeatedly, until the response packet is
	// received. Thus the time between each two attempts is directly controlled
	// by the timeout value.
	serial_set_timeout (device->port, 300);

	// Setup the bootloader.
	const unsigned int baudrates[] = {19200, 115200};
	for (unsigned int i = 0; i < C_ARRAY_SIZE(baudrates); ++i) {
		// Adjust the baudrate.
		if (serial_configure (device->port, baudrates[i], 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE) == -1) {
			ERROR (abstract->context, "Failed to set the terminal attributes.");
			free (firmware);
			return DC_STATUS_IO;
		}

		// Try to setup the bootloader.
		unsigned int maxretries = (i == 0 ? 1 : MAXRETRIES);
		rc = hw_ostc_firmware_setup (device, maxretries);
		if (rc == DC_STATUS_SUCCESS)
			break;
	}
	if (rc != DC_STATUS_SUCCESS) {
		ERROR (abstract->context, "Failed to setup the bootloader.");
		free (firmware);
		return rc;
	}

	// Increase the timeout again.
	serial_set_timeout (device->port, 1000);

	// Enable progress notifications.
	dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
	progress.maximum = C_ARRAY_SIZE(firmware->bitmap);
	device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);

	for (unsigned int i = 0; i < C_ARRAY_SIZE(firmware->bitmap); ++i) {
		// Skip empty blocks.
		if (firmware->bitmap[i] == 0)
			continue;

		// Create the packet.
		unsigned int address = i * SZ_BLOCK;
		unsigned char packet[4 + SZ_BLOCK + 1] = {
			(address >> 16) & 0xFF,
			(address >>  8) & 0xFF,
			(address      ) & 0xFF,
			SZ_BLOCK
		};
		memcpy (packet + 4, firmware->data + address, SZ_BLOCK);
		packet[sizeof (packet) - 1] = ~checksum_add_uint8 (packet, 4 + SZ_BLOCK, 0x00) + 1;

		// Send the packet.
		rc = hw_ostc_firmware_write (device, packet, sizeof (packet));
		if (rc != DC_STATUS_SUCCESS) {
			ERROR (abstract->context, "Failed to send the packet.");
			free (firmware);
			return rc;
		}

		// Update and emit a progress event.
		progress.current = i + 1;
		device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
	}

	free (firmware);

	return DC_STATUS_SUCCESS;
}
예제 #18
0
파일: winser.c 프로젝트: NaldoDj/VeraCrypt
/*
 * Called to set up the serial connection.
 * 
 * Returns an error message, or NULL on success.
 *
 * Also places the canonical host name into `realhost'. It must be
 * freed by the caller.
 */
static const char *serial_init(Seat *seat, Backend **backend_handle,
                               LogContext *logctx, Conf *conf,
                               const char *host, int port,
			       char **realhost, bool nodelay, bool keepalive)
{
    Serial *serial;
    HANDLE serport;
    const char *err;
    char *serline;

    /* No local authentication phase in this protocol */
    seat_set_trust_status(seat, false);

    serial = snew(Serial);
    serial->port = INVALID_HANDLE_VALUE;
    serial->out = serial->in = NULL;
    serial->bufsize = 0;
    serial->break_in_progress = false;
    serial->backend.vt = &serial_backend;
    *backend_handle = &serial->backend;

    serial->seat = seat;
    serial->logctx = logctx;

    serline = conf_get_str(conf, CONF_serline);
    logeventf(serial->logctx, "Opening serial device %s", serline);

    {
	/*
	 * Munge the string supplied by the user into a Windows filename.
	 *
	 * Windows supports opening a few "legacy" devices (including
	 * COM1-9) by specifying their names verbatim as a filename to
	 * open. (Thus, no files can ever have these names. See
	 * <http://msdn2.microsoft.com/en-us/library/aa365247.aspx>
	 * ("Naming a File") for the complete list of reserved names.)
	 *
	 * However, this doesn't let you get at devices COM10 and above.
	 * For that, you need to specify a filename like "\\.\COM10".
	 * This is also necessary for special serial and serial-like
	 * devices such as \\.\WCEUSBSH001. It also works for the "legacy"
	 * names, so you can do \\.\COM1 (verified as far back as Win95).
	 * See <http://msdn2.microsoft.com/en-us/library/aa363858.aspx>
	 * (CreateFile() docs).
	 *
	 * So, we believe that prepending "\\.\" should always be the
	 * Right Thing. However, just in case someone finds something to
	 * talk to that doesn't exist under there, if the serial line
	 * contains a backslash, we use it verbatim. (This also lets
	 * existing configurations using \\.\ continue working.)
	 */
	char *serfilename =
	    dupprintf("%s%s", strchr(serline, '\\') ? "" : "\\\\.\\", serline);
	serport = CreateFile(serfilename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
			     OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	sfree(serfilename);
    }

    if (serport == INVALID_HANDLE_VALUE)
	return "Unable to open serial port";

    err = serial_configure(serial, serport, conf);
    if (err)
	return err;

    serial->port = serport;
    serial->out = handle_output_new(serport, serial_sentdata, serial,
				    HANDLE_FLAG_OVERLAPPED);
    serial->in = handle_input_new(serport, serial_gotdata, serial,
				  HANDLE_FLAG_OVERLAPPED |
				  HANDLE_FLAG_IGNOREEOF |
				  HANDLE_FLAG_UNITBUFFER);

    *realhost = dupstr(serline);

    /*
     * Specials are always available.
     */
    seat_update_specials_menu(serial->seat);

    return NULL;
}
예제 #19
0
device_status_t
suunto_d9_device_open (device_t **out, const char* name)
{
	if (out == NULL)
		return DEVICE_STATUS_ERROR;

	// Allocate memory.
	suunto_d9_device_t *device = (suunto_d9_device_t *) malloc (sizeof (suunto_d9_device_t));
	if (device == NULL) {
		WARNING ("Failed to allocate memory.");
		return DEVICE_STATUS_MEMORY;
	}

	// Initialize the base class.
	suunto_common2_device_init (&device->base, &suunto_d9_device_backend);

	// Set the default values.
	device->port = NULL;

	// Open the device.
	int rc = serial_open (&device->port, name);
	if (rc == -1) {
		WARNING ("Failed to open the serial port.");
		free (device);
		return DEVICE_STATUS_IO;
	}

	// Set the serial communication protocol (9600 8N1).
	rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
	if (rc == -1) {
		WARNING ("Failed to set the terminal attributes.");
		serial_close (device->port);
		free (device);
		return DEVICE_STATUS_IO;
	}

	// Set the timeout for receiving data (3000 ms).
	if (serial_set_timeout (device->port, 3000) == -1) {
		WARNING ("Failed to set the timeout.");
		serial_close (device->port);
		free (device);
		return DEVICE_STATUS_IO;
	}

	// Set the DTR line (power supply for the interface).
	if (serial_set_dtr (device->port, 1) == -1) {
		WARNING ("Failed to set the DTR line.");
		serial_close (device->port);
		free (device);
		return DEVICE_STATUS_IO;
	}

	// Give the interface 100 ms to settle and draw power up.
	serial_sleep (100);

	// Make sure everything is in a sane state.
	serial_flush (device->port, SERIAL_QUEUE_BOTH);

	*out = (device_t*) device;

	return DEVICE_STATUS_SUCCESS;
}
예제 #20
0
dc_status_t
oceanic_vtpro_device_open (dc_device_t **out, dc_context_t *context, const char *name)
{
	if (out == NULL)
		return DC_STATUS_INVALIDARGS;

	// Allocate memory.
	oceanic_vtpro_device_t *device = (oceanic_vtpro_device_t *) malloc (sizeof (oceanic_vtpro_device_t));
	if (device == NULL) {
		ERROR (context, "Failed to allocate memory.");
		return DC_STATUS_NOMEMORY;
	}

	// Initialize the base class.
	oceanic_common_device_init (&device->base, context, &oceanic_vtpro_device_vtable);

	// Override the base class values.
	device->base.multipage = MULTIPAGE;

	// Set the default values.
	device->port = NULL;

	// Open the device.
	int rc = serial_open (&device->port, context, name);
	if (rc == -1) {
		ERROR (context, "Failed to open the serial port.");
		free (device);
		return DC_STATUS_IO;
	}

	// Set the serial communication protocol (9600 8N1).
	rc = serial_configure (device->port, 9600, 8, SERIAL_PARITY_NONE, 1, SERIAL_FLOWCONTROL_NONE);
	if (rc == -1) {
		ERROR (context, "Failed to set the terminal attributes.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Set the timeout for receiving data (3000 ms).
	if (serial_set_timeout (device->port, 3000) == -1) {
		ERROR (context, "Failed to set the timeout.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Set the DTR and RTS lines.
	if (serial_set_dtr (device->port, 1) == -1 ||
		serial_set_rts (device->port, 1) == -1) {
		ERROR (context, "Failed to set the DTR/RTS line.");
		serial_close (device->port);
		free (device);
		return DC_STATUS_IO;
	}

	// Give the interface 100 ms to settle and draw power up.
	serial_sleep (device->port, 100);

	// Make sure everything is in a sane state.
	serial_flush (device->port, SERIAL_QUEUE_BOTH);

	// Initialize the data cable (MOD mode).
	dc_status_t status = oceanic_vtpro_init (device);
	if (status != DC_STATUS_SUCCESS) {
		serial_close (device->port);
		free (device);
		return status;
	}

	// Switch the device from surface mode into download mode. Before sending
	// this command, the device needs to be in PC mode (manually activated by
	// the user), or already in download mode.
	status = oceanic_vtpro_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version));
	if (status != DC_STATUS_SUCCESS) {
		serial_close (device->port);
		free (device);
		return status;
	}

	// Calibrate the device. Although calibration is optional, it's highly
	// recommended because it reduces the transfer time considerably, even
	// when processing the command itself is quite slow.
	status = oceanic_vtpro_calibrate (device);
	if (status != DC_STATUS_SUCCESS) {
		serial_close (device->port);
		free (device);
		return status;
	}

	// Override the base class values.
	if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_wisdom_version)) {
		device->base.layout = &oceanic_wisdom_layout;
	} else {
		device->base.layout = &oceanic_vtpro_layout;
	}

	*out = (dc_device_t*) device;

	return DC_STATUS_SUCCESS;
}
예제 #21
0
static void process_outgoing (struct serial_port* port)
{
	int			avail;
	int			r;

process_type:
	avail = port->outgoingLen - port->outgoingSent;
	if ((0 == avail) && (port->outgoingPacketType == PACKET_NONE))
	{
		return;
	}

DBG_LOG(fprintf(debug_log_file,
		"process_outgoing:\n"
		"       Buffer: len=%i sent=%i avail=%i\n"
		"       Packet: type=%c len=%i left=%i\n",
		port->outgoingLen, port->outgoingSent, avail,
		port->outgoingPacketType, port->outgoingPacketLen,
		port->outgoingPacketLeft
		));

	switch (port->outgoingPacketType)
	{
	case PACKET_NONE:
		/* If the number of bytes available in the buffer is at least 5,
		 * we can begin to process this packet.  We don't use avail > 5 here
		 * because some packets may in fact have no payload, just the type.
		 */
		if (avail >= 5)
		{
			uint32_t	plen;

			memcpy(&plen, port->outgoing + port->outgoingSent, 4);
			port->outgoingSent += 4;
			
			port->outgoingPacketLen = (int)(ntohl(plen) - 1);
			port->outgoingPacketLeft = port->outgoingPacketLen;
			port->outgoingPacketType = port->outgoing[port->outgoingSent++];

			/* If for some reason we get a PACKET_NONE type packet, this
			 * is an error.  Switch it to PACKET_DRAIN so we can drain it
			 * off the line.
			 */
			if (PACKET_NONE == port->outgoingPacketType)
			{
				port->outgoingPacketType = PACKET_DRAIN;
			}

			/* Loop to process the newly discovered packet type.  We
			 * may have enough data to process part of the packet by
			 * now.
			 */
			goto process_type;

		} else
		{
			truncate_outgoing(port, 5);
		}
		break;

	case PACKET_ACTIVE:
		if (port->outgoingPacketLen != 1)
		{
			port->lastError.error_code = ERROR_BAD_LENGTH;
			serial_format_error(
				port->chan,
				port->lastError.error_code,
				port->lastError.error_msg,
				sizeof(port->lastError.error_msg));

			port->outgoingPacketType = PACKET_DRAIN;
			goto process_type;
		}

		if (avail >= 1)
		{
			port->erlangPortActive = port->outgoing[port->outgoingSent];
			port->outgoingSent++;
			port->outgoingPacketType = PACKET_NONE;
			port->outgoingPacketLen = 0;
			port->outgoingPacketLeft = 0;
			goto process_type;

		} else
		{
			truncate_outgoing(port, 1);
		}
		break;

	case PACKET_CONFIG:
		/* If the packet length does not exactly match the size of
		 * the serial_cfg structure this program uses, drain the packet
		 * off the line.  There's no way it can be processed by this
		 * code.
		 */
		if (port->outgoingPacketLen != sizeof(struct serial_cfg))
		{
			port->lastError.error_code = ERROR_BAD_LENGTH;
			serial_format_error(
				port->chan,
				port->lastError.error_code,
				port->lastError.error_msg,
				sizeof(port->lastError.error_msg));

			port->outgoingPacketType = PACKET_DRAIN;
			goto process_type;
		}

		/* If the configuration packet is fully contained within the
		 * outgoing buffer (and it always will fit as the buffer is
		 * always bigger), process the config packet now.
		 */
		if (avail >= sizeof(struct serial_cfg))
		{
			struct serial_cfg	cfg;
			char*				magic = SERIAL_CFG_MAGIC;

			memcpy(
				&cfg,
				port->outgoing + port->outgoingSent,
				sizeof(struct serial_cfg));

			if (memcmp(cfg.magic, magic, strlen(magic) + 1) == 0)
			{
				if (serial_configure(port->chan, &cfg) == -1)
				{
					port->lastError.error_code = serial_last_error(port->chan);
					serial_format_error(
						port->chan,
						port->lastError.error_code,
						port->lastError.error_msg,
						sizeof(port->lastError.error_msg));

				} else
				{
					/* If the caller supplied a valid value for the active
					* setting, update to it.
					*/
					switch (cfg.initially_active)
					{
					case PORT_ACTIVE_FALSE:
					case PORT_ACTIVE_TRUE:
					case PORT_ACTIVE_ONCE:
						port->erlangPortActive = cfg.initially_active;
						break;
					}

					/* Modify the packet scanner to match the setting supplied.
					*/
					if (SERIAL_PACKET_NONE == cfg.packet_format)
					{
						port->packet_scanner = packetscan_none;
						port->incomingScan = port->incomingSent;
						DBG_LOG(fprintf(debug_log_file, "scanner = none\n"));

					} else if (SERIAL_PACKET_DELIM == cfg.packet_format)
					{
						port->packet_scanner = packetscan_delim;
						port->incomingScan = port->incomingSent;
						DBG_LOG(fprintf(debug_log_file, "scanner = delim len=%i\n", port->chan->config.packet_delim_len));

					} else if (cfg.packet_format < 0)
					{
						port->packet_scanner = packetscan_fixedsize;
						port->incomingScan = port->incomingSent;
						DBG_LOG(fprintf(debug_log_file, "scanner = fixedsize %i\n", -port->chan->config.packet_format));
					}

					port->sendOkFor = PACKET_CONFIG;
				}

			} else
			{
				/* Magic header doesn't match what we use for a
				 * config packet. The packet is the wrong version.
				 * This is an error.
				 */
				port->lastError.error_code = ERROR_INVALID_DATA;
				serial_format_error(
					port->chan,
					port->lastError.error_code,
					port->lastError.error_msg,
					sizeof(port->lastError.error_msg));
			}

			port->outgoingSent += sizeof(struct serial_cfg);
			port->outgoingPacketType = PACKET_NONE;
			port->outgoingPacketLen = 0;
			port->outgoingPacketLeft = 0;
			goto process_type;

		} else
		{
			truncate_outgoing(port, sizeof(struct serial_cfg));
		}
		break;

	case PACKET_CLOSE:
	case PACKET_FLUSH:
		/* If either a close or a flush messages sent sent down, send a
		 * reply.  erts is basically just waiting for the reply before
		 * it will close the pipes down, and this process gets EOF on
		 * the pipes.  Don't attempt to close down anything until
		 * EOF is received on the erts pipes.
		 */
		port->sendOkFor = port->outgoingPacketType;
		port->outgoingPacketType = PACKET_NONE;
		port->outgoingPacketLen = 0;
		port->outgoingPacketLeft = 0;
		goto process_type;

	case PACKET_DATA:
		/* If the buffer has more data than the packet has remaining, only
		 * send the number of bytes in the packet.  Otherwise, send what
		 * is currently in the buffer.
		 */
		if (avail > port->outgoingPacketLeft)
		{
			r = port->outgoingPacketLeft;
		} else
		{
			r = avail;
		}

		/* Attempt to write to the serial port.  This may fail and return -1
		 * (EAGAIN), meaning the port is too busy to write this data now.
		 * A future call to this function will recall write with the same
		 * parameter values.
		 */
		r = serial_write(port->chan, port->outgoing + port->outgoingSent, r);
		if (r >= 0)
		{
			port->outgoingSent += r;
			port->outgoingPacketLeft -= r;

		} else if (serial_last_error(port->chan))
		{
			port->lastError.error_code = serial_last_error(port->chan);
			serial_format_error(
				port->chan,
				port->lastError.error_code,
				port->lastError.error_msg,
				sizeof(port->lastError.error_msg));

			port->outgoingPacketType = PACKET_DRAIN;
		}

		/* If the packet is completed, continue to process what is in the
		 * outgoing buffer.
		 */
		if (0 == port->outgoingPacketLeft)
		{
			port->outgoingPacketType = PACKET_NONE;
			port->outgoingPacketLen = 0;
			goto process_type;
		}
		break;

	case PACKET_DRAIN:
	default:
		/* If the packet type was not recognized, we need to throw the packet
		 * away.  This requires consuming all of its data, but not actually
		 * handling it.  Here we attempt to throw out as much of the packet
		 * as we can.  If we've thrown all of it, we switch back to
		 * PACKET_NONE and try to process the buffer again.
		 */
		if (port->outgoingPacketLeft > 0)
		{
			if (avail >= port->outgoingPacketLeft)
			{
				port->outgoingSent += port->outgoingPacketLeft;
				port->outgoingPacketType = PACKET_NONE;
				port->outgoingPacketLen = 0;
				port->outgoingPacketLeft = 0;
				goto process_type;

			} else
			{
				port->outgoingSent += avail;
				port->outgoingPacketLeft -= avail;
			}

		} else if (0 == port->outgoingPacketLeft)
		{
			port->outgoingPacketType = PACKET_NONE;
			port->outgoingPacketLen = 0;
			goto process_type;
		}
		break;
	}
}