/** * 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'); }
/** * 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; }