int main( int argc, char ** argv )
{
	ros::init( argc, argv, "sonar_driver" );
	if (argc < 3) {
		ROS_ERROR("sonar_driver usage: sudo rosrun sonar_driver sonar_driver PORT BITRATE\n");
		//port 0, bitrate 40000kHz
  		return 1;
  	}

	// Initialize Cheetah parameters
	port = atoi(argv[1]);
	bitrate = atoi(argv[2]); //kHz

	// Open the device
	handle = ch_open(port);
	if (handle <= 0) {
		ROS_ERROR("Unable to open Cheetah device on port %d (Error code = %d: %s)", port, handle, ch_status_string(handle));
	  	exit(1);
	}
	ROS_INFO("Opened Cheetah device on port %d", port);
	ROS_INFO("Host interface is %s", (ch_host_ifce_speed(handle)) ? "high speed" : "full speed");

	// Configure SPI subsystem
	ch_spi_configure(handle, CH_SPI_POL_RISING_FALLING, CH_SPI_PHASE_SETUP_SAMPLE, CH_SPI_BITORDER_MSB, 0x0);
	ROS_INFO("SPI configuration set to mode %d, %s shift, SS[2:0] active low", mode, "MSB");

	// Power the target using the Cheetah's 5V power supply
	ch_target_power(handle, CH_TARGET_POWER_ON);
	ch_sleep_ms(100);

	// Set the bitrate
	bitrate = ch_spi_bitrate(handle, bitrate);
	ROS_INFO("Bitrate set to %d kHz", bitrate);

  
	// Make a simple queue to assert OE
	ch_spi_queue_clear(handle);
	ch_spi_queue_oe(handle, 1);
	ch_spi_batch_shift(handle, 0, 0);

	// Queue the batch
	ROS_INFO("Beginning to queue SPI packets...");
	ch_spi_queue_clear(handle);
	for (int i = 0; i < DATA_BLOCK_SIZE; ++i) {
		// Convert Slave 1
	 	ch_spi_queue_ss(handle, 0xF);
	 	ch_spi_queue_array(handle, 2, data_out);
	 	ch_spi_queue_ss(handle, 0xE);

	 	// Convert Slave 2
	 	ch_spi_queue_ss(handle, 0xF);
	 	ch_spi_queue_array(handle, 2, data_out);
	 	ch_spi_queue_ss(handle, 0xD);

	 	// Convert Slave 3
	 	ch_spi_queue_ss(handle, 0xF);
	 	ch_spi_queue_array(handle, 2, data_out);
	 	ch_spi_queue_ss(handle, 0xB);
	}
	ROS_INFO("Finished queueing packets\n");

	// Open output filestreams
	std::ofstream file1 ("1_adc_samples.txt");
	std::ofstream file2 ("2_adc_samples.txt");
	std::ofstream file3 ("3_adc_samples.txt");

	int batch_cnt = 1; //count number of sample batches
	double elapsed;
	s64    start;

	while( ros::ok() ) {
		// Submit the batch and collect data
		ROS_INFO("Collecting data from batch %d...", batch_cnt);
		start = _timeMillis();
   		ch_spi_async_submit(handle);
    		ret = ch_spi_async_collect(handle, TX_LENGTH, data_in);
		elapsed = ((double)(_timeMillis() - start)) / 1000;
		ROS_INFO("collected %d bytes from batch #%04d in %.4lf seconds\n", ret, batch_cnt, elapsed);
		if (ret < 0)  ROS_INFO("status error: %s\n", ch_status_string(ret));
		batch_cnt++;

		// Process raw data for the 12-bit ADC's, and write data to text files
    		int data_idx = 0;
		if ( file1.is_open() && file2.is_open() && file3.is_open() ) {
    			for (int j = 0; j < TX_LENGTH; j += 6) {
    				// SS3 Data
		    		input = (data_in[j] << 8) + data_in[j+1];
		    		valid_data_point = (input & 0x3ffc) >> 2;
		    		if(valid_data_point >= 0x0800)	valid_data_point = valid_data_point - 0x1000; //convert 2's comp to signed
		    		data3[data_idx] = valid_data_point;
				file3 << data3[data_idx] << ",";
	
		    		// SS1 Data
		    		input = (data_in[j+2] << 8) + data_in[j+3];
		    		valid_data_point = (input & 0x3ffc) >> 2;
		    		if(valid_data_point >= 0x0800)	valid_data_point = valid_data_point - 0x1000;
		    		data1[data_idx] = valid_data_point;
				file1 << data1[data_idx] << ",";
	
		    		// SS2 Data
		    		input = (data_in[j+4] << 8) + data_in[j+5];
		    		valid_data_point = (input & 0x3ffc) >> 2;
		    		if(valid_data_point >= 0x0800)	valid_data_point = valid_data_point - 0x1000;
		    		data2[data_idx] = valid_data_point;
				file2 << data2[data_idx] << ",";
		    		++data_idx;
    			}
		}
		else std::cout << "Error opening output filestream!" << std::endl;
	}
Example #2
0
//=========================================================================
// FUNCTIONS
//=========================================================================
static void _blast (Cheetah handle, u32 length) {
    double elapsed;
    int delay = 0;
    u32 i;
    int batch;
    int count;
    u08 *data_in;
    s64 start = _timeMillis();

    // Queue the read sequence
    ch_spi_queue_clear(handle);

    ch_spi_queue_oe(handle, 1);
    ch_spi_queue_ss(handle, 0);
    ch_spi_queue_ss(handle, 0x1);

    for (i = 0; i < length; ++i) {
        ch_spi_queue_byte(handle, 1, (u08)(i & 0xff));

        delay = ch_spi_queue_delay_ns(handle, BYTE_DELAY);
    }
    printf("Queued delay of %d ns between bytes.\n", delay);
    fflush(stdout);

    ch_spi_queue_ss(handle, 0);
    ch_spi_queue_oe(handle, 0);

    elapsed = ((double)(_timeMillis() - start)) / 1000;
    printf("Took %.2lf seconds to queue the batch.\n", elapsed);
    fflush(stdout);

    // Perform the shift
    batch    = ch_spi_batch_length(handle);
    data_in = (u08 *)malloc(batch);

    start = _timeMillis();
    count = ch_spi_batch_shift(handle, batch, data_in);

    elapsed = ((double)(_timeMillis() - start)) / 1000;
    printf("Took %.2lf seconds to shift the batch.\n", elapsed);
    fflush(stdout);

    if (count != batch) {
        printf("Expected %d bytes but only received %d bytes\n",
               batch, count);
        goto cleanup;
    }

#ifdef SHOW_DATA
    // Output the data to the screen
    printf("\nData:");
    for (i = 0; i < length; ++i) {
        if ((i&0x07) == 0)      printf("\n%04x:  ", i);
        printf("%02x/%02x ", (i & 0xff), data_in[i]);
    }
    printf("\n");
    fflush(stdout);
#endif

cleanup:
    // Cleanup and exit
    free(data_in);
}
//=========================================================================
// FUNCTIONS
//=========================================================================
static void _blast_async (Cheetah handle, u32 txnlen, u32 iter) {
    double elapsed;
    u32    i;
    int    count = 0;
    u08    data_out[4];
    s64    start;
    int    ret;

    // Make a simple queue to just assert OE.
    ch_spi_queue_clear(handle);
    ch_spi_queue_oe(handle, 1);
    ch_spi_batch_shift(handle, 0, 0);

    
    // Queue the batch which is a sequence of SPI packets
    // (back-to-back) each of length 4.
    ch_spi_queue_clear(handle);
    for (i = 0; i < txnlen; ++i) {
       		// Convert Slave 1
	 	ch_spi_queue_ss(handle, 0xF);
	 	ch_spi_queue_array(handle, 2, data_out);
	 	ch_spi_queue_ss(handle, 0xE);

	 	// Convert Slave 2
	 	ch_spi_queue_ss(handle, 0xF);
	 	ch_spi_queue_array(handle, 2, data_out);
	 	ch_spi_queue_ss(handle, 0xD);

	 	// Convert Slave 3
	 	ch_spi_queue_ss(handle, 0xF);
	 	ch_spi_queue_array(handle, 2, data_out);
	 	ch_spi_queue_ss(handle, 0xB);
    }


    start = _timeMillis();

    // First, submit first batch 
    ch_spi_async_submit(handle);

    for (i = 0; i < iter-1; ++i) {
        // Submit another batch, while the previous one is in
        // progress.  The application may even clear the current
        // batch queue and queue a different set of SPI
        // transactions before submitting this batch
        // asynchronously.
        ch_spi_async_submit(handle);
        
        // The application can now perform some other functions
        // while the Cheetah is both finishing the previous batch
        // and shifting the current batch as well.  In order to
        // keep the Cheetah's pipe full, this entire loop must
        // complete AND another batch must be submitted
        // before the current batch completes.
        ch_sleep_ms(25);
        
        // Collect the previous batch
        ret = ch_spi_async_collect(handle, 0, 0);
        elapsed = ((double)(_timeMillis() - start)) / 1000;
        printf("collected batch #%03d in %.2lf seconds\n", i+1, elapsed);
        if (ret < 0)  printf("status error: %s\n", ch_status_string(ret));
        fflush(stdout);

        start = _timeMillis();
        
        // The current batch is now shifting out on the SPI
        // interface. The application can again do some more tasks
        // here but this entire loop must finish so that a new
        // batch is armed before the current batch completes.
        ch_sleep_ms(25);
    }

    // Collect batch the last batch
    ret = ch_spi_async_collect(handle, 0, 0);
    elapsed = ((double)(_timeMillis() - start)) / 1000;
    printf("collected batch #%03d in %.2lf seconds\n", i+1, elapsed);
    if (ret < 0)  printf("status error: %s\n", ch_status_string(ret));
    fflush(stdout);

		// Process raw data for the 12-bit ADC's, and write data to text files
    		int data_idx = 0;
		if ( file1.is_open() && file2.is_open() && file3.is_open() ) {
    			for (int j = 0; j < TX_LENGTH; j += 6) {
    				// SS3 Data
		    		input = (data_in[j] << 8) + data_in[j+1];
		    		valid_data_point = (input & 0x3ffc) >> 2;
		    		if(valid_data_point >= 0x0800)	valid_data_point = valid_data_point - 0x1000; //convert 2's comp to signed
		    		data3[data_idx] = valid_data_point;
				file3 << data3[data_idx] << ",";
	
		    		// SS1 Data
		    		input = (data_in[j+2] << 8) + data_in[j+3];
		    		valid_data_point = (input & 0x3ffc) >> 2;
		    		if(valid_data_point >= 0x0800)	valid_data_point = valid_data_point - 0x1000;
		    		data1[data_idx] = valid_data_point;
				file1 << data1[data_idx] << ",";
	
		    		// SS2 Data
		    		input = (data_in[j+4] << 8) + data_in[j+5];
		    		valid_data_point = (input & 0x3ffc) >> 2;
		    		if(valid_data_point >= 0x0800)	valid_data_point = valid_data_point - 0x1000;
		    		data2[data_idx] = valid_data_point;
				file2 << data2[data_idx] << ",";
		    		++data_idx;
    			}
		}
		else std::cout << "Error opening output filestream!" << std::endl;