Exemple #1
0
/**
 * oh_add_resource
 * @table: Pointer to the RPT to which the RPT entry will be added.
 * @entry: The RPT entry (resource) to be added to the RPT.
 * @data: Pointer to private data for storing along with the RPT entry.
 * @owndata: boolean flag. true (%KEEP_RPT_DATA) to tell the interface *not*
 * to free the data when the resource is removed. false (%FREE_RPT_DATA) to tell
 * the interface to free the data when the resource is removed.
 *
 * Add a RPT entry to the RPT along with some private data.
 * If an RPT entry with the same resource id exists int the RPT, it will be
 * overlayed with the new RPT entry. Also, this function will assign the
 * resource id as its entry id since it is expected to be unique for the table. 
 * 
 * Returns:
 * 0 - successful addition to the RPT.
 * -1 - table pointer is NULL.
 * -2 - entry is NULL.
 * -3 - entry does not have an id assigned.
 * -4 - entry has an invalid/reserved id assinged.
 * -5 - entity path does not contain root element.
 * -6 - failure and not enough memory could be allocated. 
 * for a new position in the RPT.
 **/
int oh_add_resource(RPTable *table, SaHpiRptEntryT *entry, void *data, int owndata)
{
        RPTEntry *rptentry;
        
        if (!table) {
                dbg("ERROR: Cannot work on a null table pointer.");
                return -1;
        } else if (!entry) {
                dbg("Failed to add. RPT entry is NULL.");
                return -2;
        } else if (entry->ResourceId == SAHPI_FIRST_ENTRY) {
                dbg("Failed to add. RPT entry needs a resource id before being added");
                return -3;                
        } else if (entry->ResourceId == SAHPI_DOMAIN_CONTROLLER_ID) {
                dbg("Failed to add. RPT entry has an invalid/reserved id assigned. (SAHPI_DOMAIN_CONTROLLER_ID)");
                return -4;
        } else if (check_ep(entry->ResourceEntity)) {
                dbg("Failed to add RPT entry. Entity path does not contain root element.");
                return -5;                
        }

        /* Check to see if the entry is in the RPTable already */
        rptentry = get_rptentry_by_rid(table, entry->ResourceId);        
        /* If not, create new RPTEntry */
        if (!rptentry) {
                rptentry = (RPTEntry *)g_malloc0(sizeof(RPTEntry));
                if (!rptentry) {
                        dbg("Not enough memory to add RPT entry.");
                        return -6;
                }
                /* Put new RPTEntry in RPTable */
                table->rptable = g_slist_append(table->rptable, (gpointer)rptentry);                
        }
        /* Else, modify existing RPTEntry */
        rptentry->owndata = owndata;
        rptentry->data = data;
        rptentry->rpt_entry = *entry;
        rptentry->rpt_entry.EntryId = entry->ResourceId;

        update_rptable(table);
                       
        return 0; 
}
void stop_motor(uint8_t num){
	const uint8_t stage_minus[2] = {STAGE_CHECK(3, MINUS), STAGE_CHECK(4, MINUS)};
	//if(!) return;
	MSG("stop motor ", "[ " STR_STOP_ALL_MOTORS " ");
	if(mode != BINARY_MODE){
		lastsendfun('0' + num);
		lastsendfun(' ');
	}
	// this function could be called simply to check motors' position
	// so, we should check wether motor is active before changing EN state
	if(Motor_active[num]){
		if(!gpio_get(MOTOR_EN_PORT, MOTOR_EN_PIN(num)) && mode == LINE_MODE)
			P("HEAT ", lastsendfun);
		gpio_set_mode(MOTOR_EN_PORT, GPIO_MODE_OUTPUT_2_MHZ,
			GPIO_CNF_OUTPUT_OPENDRAIN, MOTOR_EN_PIN(num));
		gpio_clear(MOTOR_EN_PORT, MOTOR_EN_PIN(num));
		Motor_active[num] = 0;
	}
	uint8_t curpos = check_ep(num);
	// set absolute counter to zero on 1st position for turrets or on MINUS EP for stages
	if(num < 3){ // this is a turret
		move2pos[num] = 0; // reset target position value
		if(curpos == 1){
			Motor_abs_steps[num] = 0;
		}else{
			if(curpos == 0) // a turret is out of fixed position
				MSG("stop out of position", "ERR ");
		}
	}else{ // linear stage
		if(curpos == stage_minus[num-3]){
			Motor_abs_steps[num] = 0;
		}
	}
	Motor_steps[num] = 0;
	BYTE_MSG(" absolute steps: ");
	print_int(Motor_abs_steps[num], lastsendfun);
	if(mode == LINE_MODE) P(" ]", lastsendfun);
	lastsendfun('\n');
}
Exemple #3
0
/**
 * oh_add_resource: Add a RPT entry to the RPT along with some private data.
 * If an RPT entry with the same resource id exists int the RPT, it will be
 * overlayed with the new RPT entry. Also, this function will assign the
 * resource id as its entry id since it is expected to be unique for the table.
 * Note - If the RPT entry has a resource id of RPT_ENTRY_BEGIN(0xffffffff),
 * the first RPT entry in the table will be overlayed.
 * @table: Pointer to the RPT to which the RPT entry will be added.
 * @entry: The RPT entry (resource) to be added to the RPT.
 * @data: Pointer to private data for storing along with the RPT entry.
 *
 * Return value:
 * 0 - successful addition to the RPT.
 * -1 - entry does not have an id assigned.
 * -2 - entry has an invalid/reserved id assinged.
 * -3 - entity path does not contain root element.
 * -4 - failure and not enough memory could be allocated. 
 * for a new position in the RPT.
 **/
int oh_add_resource(RPTable *table, SaHpiRptEntryT *entry, void *data)
{
        RPTEntry *rptentry;
        guint update_flag = RPT_KEEP_COUNT;

        if (entry->ResourceId == 0) {
                dbg("Failed to add. RPT entry needs a resource id before being added");
                return -1;                
        } else if (entry->ResourceId == RPT_ENTRY_BEGIN) {
                dbg("Failed to add. RPT entry has an invalid/reserved id assigned (RPT_ENTRY_BEGIN).");
                return -2;
        } else if (check_ep(entry->ResourceEntity)) {
                dbg("Failed to add RPT entry. Entity path does not contain root element.");
                return -3;                
        }

        /* Check to see if the entry is in the RPTable already */
        rptentry = get_rptentry_by_rid(table, entry->ResourceId);        
        /* If not, create new RPTEntry */
        if (!rptentry) {
                rptentry = (RPTEntry *)g_malloc0(sizeof(RPTEntry));
                if (!rptentry) {
                        dbg("Not enough memory to add RPT entry.");
                        return -4;
                }
                /* Put new RPTEntry in RPTable */
                table->rptable = g_slist_append(table->rptable, (gpointer)rptentry);
                update_flag = RPT_INCREMENT;
        }
        /* Else, modify existing RPTEntry */
        rptentry->data = data;
        rptentry->rpt_entry = *entry;
        rptentry->rpt_entry.EntryId = entry->ResourceId;

        update_rptable(table, update_flag);
                       
        return 0; 
}
/*
 * Find a HID device with VendorID == 0x046D ||
 *    (VendorID == 0x0400 && ProductID == 0xC359)
 */
int FindRemote(THIDINFO &hid_info)
{
    libusb_device **devices;
    
    ssize_t num_devices = libusb_get_device_list(context, &devices);

	libusb_device *h_dev;
	bool found = false;
    
	for (int i = 0; i < num_devices && !found; i++) {
        h_dev = (libusb_device *)(devices[i]);
        
        if (is_harmony(h_dev)) {
			found = true;
			break;
		}
	}

	if (h_dev) {
		libusb_open(h_dev, &h_hid);
	}
    
	if (!h_hid) {
		debug("Failed to establish communication with remote: %s",
			usb_strerror());
		return LC_ERROR_CONNECT;
	}

#ifdef linux
	/*
	 * Before we attempt to claim the interface, lets go ahead and get
	 * the kernel off of it, in case it claimed it already.
	 *
	 * This is ONLY available when on Linux. We don't check for an error
	 * because it will error if no kernel driver is attached to it.
	 */
	usb_detach_kernel_driver_np(h_hid, 0);
#endif

	int err;
	if ((err = libusb_set_configuration(h_hid, 1))) {
		debug("Failed to set device configuration: %d (%s)", err,
			usb_strerror());
		return err;
	}

	if ((err = libusb_claim_interface(h_hid, 0))) {
		debug("Failed to claim interface: %d (%s)", err,
			usb_strerror());
		return err;
	}

    libusb_device_descriptor desc;
    libusb_config_descriptor *uc = NULL;
    
    libusb_get_device_descriptor(h_dev, &desc);
    // TODO - Deal with errors!

	unsigned char maxconf = desc.bNumConfigurations;
    
	for (unsigned char j = 0; j < maxconf; ++j) {
		libusb_get_config_descriptor(h_dev, j, &uc);
        
		unsigned char maxint = uc->bNumInterfaces;
        
		for (unsigned char k = 0; k < maxint; ++k) {
			const libusb_interface &ui = uc->interface[k];
            
			unsigned char maxalt = ui.num_altsetting;
            
			for (unsigned char l = 0; l < maxalt; ++l) {
				const libusb_interface_descriptor &uid = ui.altsetting[l];

				debug("bNumEndpoints %i", uid.bNumEndpoints);
                
				unsigned char maxep = uid.bNumEndpoints;
                
				for (unsigned char n = 0; n < maxep; ++n) {
					check_ep(uid.endpoint[n]);
				}
			}
		}
	}

	if (ep_read == -1 || ep_write == -1) return 1;

	// Fill in hid_info

	unsigned char s[128];
	libusb_get_string_descriptor_ascii(h_hid, desc.iManufacturer, s, sizeof(s));
	hid_info.mfg = (char *)s;
	libusb_get_string_descriptor_ascii(h_hid, desc.iProduct, s, sizeof(s));
	hid_info.prod = (char *)s;

	hid_info.vid = desc.idVendor;
	hid_info.pid = desc.idProduct;
	hid_info.ver = desc.bcdDevice;

	hid_info.irl = irl;
	hid_info.orl = orl;
	hid_info.frl = 0;/// ???

	return 0;
}
/**
 * Check flags set by timers & do next:
 *  - decrease step counter if it isn't zero;
 *  - stop motor if counter is zero but motor still active
 */
void process_stepper_motors(){
	int i, j;
	const uint32_t ports[] = {MOTOR_TIM1_PORT, MOTOR_TIM2_PORT};
	const uint32_t pins[] = {MOTOR_TIM1_PIN, MOTOR_TIM2_PIN};
	const uint8_t startno[] = {0, 3};
	const uint8_t stopno[]  = {3, 5};
	//static uint8_t showcurpos[5] = {0,0,0,0,0};
	uint8_t curpos;
	const uint32_t Tim[2] = {TIM3, TIM4};
	for(j = 0; j < 2; j++){
		// new period of motors' timer -- maximum value for all periods in group
		uint16_t new_period = 0;
		if(timer_flag[j]){
			timer_flag[j] = 0;
			uint8_t is_active = 0;
			for(i = startno[j]; i < stopno[j]; i++)
				if(Motor_active[i]) is_active = 1;
			if(!is_active) continue; // don't generate clock pulses when there's no moving motors
			if(undervoltage_test(MOTORS_VOLTAGE_ALERT)){ // UNDERVOLTAGE! Stop all active motors
				for(i = 0; i < 5; i++)
					if(Motor_active[i]) stop_motor(i);
				return;
			}
			gpio_toggle(ports[j], pins[j]); // change clock state
			if(!gpio_get(ports[j], pins[j])){ // negative pulse - omit this half-step
				continue;
			}
			for(i = startno[j]; i < stopno[j]; i++){ // check motors
				if(Motor_active[i] == 0) continue; // inactive motor
				curpos = check_ep(i);
				if(Motor_steps[i] == 0){ // end of moving
					stop_motor(i); // even if this is a turret with move2pos[i]!=0 we should stop
						//(what if there's some slipping or so on?)
				}else{ // we should move further
					if(waits[i]){ // waiting for position stabilisation
						uint8_t got_new_position = 0;
						waits[i]--;
						if(waits[i]) continue; // there's more half-steps to skip
						// tell user current position if we was stopped at fixed pos
						if(lastpos[i] == 0 && curpos != 0){
							got_new_position = 1;
							MSG("position of motor ", "[ " STR_ENDSW_STATE " ");
							print_int(i, lastsendfun);
							lastsendfun(' ');
							print_int(curpos, lastsendfun);
							if(mode == LINE_MODE) P(" ]", lastsendfun);
							lastsendfun('\n');
						}
						lastpos[i] = curpos;
						// turn on motor after pause
						gpio_set(MOTOR_EN_PORT, MOTOR_EN_PIN(i));
						if(j == 1){ // this is a linear stage
							if(test_stages_endpos(i, curpos)){ // this is the end of way
								stop_motor(i);
							}
						}else{ // this is a turret
							if(move2pos[i]){ // we should move to specific position
								if(curpos == move2pos[i]){ // we are on position
									stop_motor(i);
								}else if(got_new_position){ // add some steps to move to next position
									if(++positions_pass[i] > MAX_POSITIONS_PASS){
										ERR("Can't reach given position");
										stop_motor(i);
									}else
										Motor_steps[i] += TURRETS_NEXT_POS_STEPS;
								}
							}
						}
					}else{
						// check for overcurrent: if MOTOR_EN_PIN == 0
						if(!gpio_get(MOTOR_EN_PORT, MOTOR_EN_PIN(i))){
							ERR("overcurrent\n");
							stop_motor(i);
							continue;
						}
						if(lastpos[i] != curpos){ // transition process
							if(lastpos[i] == 0){ // come towards position
								if(j == 0){ // this is a turret: make pause & prepare acceleration for start
									waits[i] = Turrets_pause;
									accel[i] = START_MOTORS_ACCEL_IDX_4;
								}else{
									waits[i] = 1;
								}
								// turn off motor while a pause (turret will be locked at fixed position by spring)
								// for this short pause we can simply do a pulldown
								gpio_clear(MOTOR_EN_PORT, MOTOR_EN_PIN(i));
								continue;
							}
							lastpos[i] = curpos;
						}
						Motor_steps[i]--;
						// change value of current motor's position
						Motor_abs_steps[i] += Motor_step_increment[i];
						if(accel[i]){ // we are starting
							uint32_t NP = (uint32_t)Motor_period[j] * accel_mults[(accel[i]--)/4];
							if(NP > 0xffff) NP = 0xffff;
							if(new_period < NP) new_period = (uint16_t)NP;
						}
					}
				}
			}
			if(new_period){ // we have to change motors' speed when accelerating
				timer_set_period(Tim[j], new_period);
			}
		}
	}
}
/**
 * Move motor Motor_number to User_value steps
 * return 0 if motor is still moving
 */
uint8_t move_motor(uint8_t num, int32_t steps){
	uint8_t curpos, negative_dir = 0, N_active_in_group = 0;
	if(steps == 0) return 0;
	// check whether motor is moving
/*	if(Motor_active[num]){
		ERR("moving\n");
		return 0;
	}*/
	// don't move motors if there's no power enough
	if(undervoltage_test(MOTORS_VOLTAGE_THRES)) return 0;
	if(num < 3){
		for(curpos = 0; curpos < 4; curpos++)
			if(Motor_active[curpos]) N_active_in_group++;
	}else{
		if(Motor_active[3] || Motor_active[4]) N_active_in_group = 1;
	}
	if(N_active_in_group){ // we can't move: there's any active motor in group
		ERR("moving\n");
		return 0;
	}
#ifdef EBUG
	if(mode == BYTE_MODE){
		P("move ", lastsendfun);
		lastsendfun('0' + num);
		P(" to ", lastsendfun);
		print_int(steps, lastsendfun);
		lastsendfun('\n');
	}
#endif
	if(steps < 0){
		negative_dir = 1;
		Motor_step_increment[num] = -1;
		steps = -steps;
	}else
		Motor_step_increment[num] = 1;
	curpos = check_ep(num);
	lastpos[num] = curpos;
	if(negative_dir){
		gpio_set(MOTOR_DIR_PORT, MOTOR_DIR_PIN(num)); // set DIR bit to rotate ccw
	}else{
		gpio_clear(MOTOR_DIR_PORT, MOTOR_DIR_PIN(num)); // reset DIR bit
	}
	if(test_stages_endpos(num, curpos)){ // error: we can't move
		stop_motor(num); // say about it
		return 0;
	}
	// set all flags and variables
	Motor_steps[num] = steps; // we run in full-step mode!
	waits[num] = 0;
	accel[num] = START_MOTORS_ACCEL_IDX_4;
	Motor_active[num] = 1;
	if(num < 3) // this is turret -> reset counter of passed positions
		positions_pass[num] = 0;
	// pullup input when active
	gpio_set_mode(MOTOR_EN_PORT, GPIO_MODE_INPUT,
			GPIO_CNF_INPUT_PULL_UPDOWN, MOTOR_EN_PIN(num));
	gpio_set(MOTOR_EN_PORT, MOTOR_EN_PIN(num));
/*
	P("set: ", lastsendfun);
	print_int(GPIO_ODR(MOTOR_EN_PORT) & MOTOR_EN_MASK, lastsendfun);
	P(", get: ", lastsendfun);
	print_int(GPIO_IDR(MOTOR_EN_PORT) & MOTOR_EN_MASK, lastsendfun);
	lastsendfun('\n');
*/
	return 1;
}