void Space::load_motor(int m, int32_t &addr) { // {{{ loaddebug("loading motor %d", m); uint16_t enable = motor[m]->enable_pin.write(); double old_home_pos = motor[m]->home_pos; double old_steps_per_unit = motor[m]->steps_per_unit; motor[m]->step_pin.read(read_16(addr)); motor[m]->dir_pin.read(read_16(addr)); motor[m]->enable_pin.read(read_16(addr)); motor[m]->limit_min_pin.read(read_16(addr)); motor[m]->limit_max_pin.read(read_16(addr)); motor[m]->steps_per_unit = read_float(addr); motor[m]->home_pos = read_float(addr); motor[m]->limit_v = read_float(addr); motor[m]->limit_a = read_float(addr); motor[m]->home_order = read_8(addr); arch_motors_change(); SET_OUTPUT(motor[m]->enable_pin); if (enable != motor[m]->enable_pin.write()) { if (motors_busy) SET(motor[m]->enable_pin); else { RESET(motor[m]->enable_pin); } } RESET(motor[m]->step_pin); SET_INPUT(motor[m]->limit_min_pin); SET_INPUT(motor[m]->limit_max_pin); bool must_move = false; if (!isnan(motor[m]->home_pos)) { // Axes with a limit switch. if (motors_busy && (old_home_pos != motor[m]->home_pos || old_steps_per_unit != motor[m]->steps_per_unit) && !isnan(old_home_pos)) { double ohp = old_home_pos * old_steps_per_unit; double hp = motor[m]->home_pos * motor[m]->steps_per_unit; double diff = hp - ohp; motor[m]->settings.current_pos += diff; //debug("load motor %d %d new home %f add %f", id, m, motor[m]->home_pos, diff); arch_addpos(id, m, diff); must_move = true; } } else { // Axes without a limit switch, including extruders. if (motors_busy && old_steps_per_unit != motor[m]->steps_per_unit) { debug("load motor %d %d new steps no home", id, m); double oldpos = motor[m]->settings.current_pos; double pos = oldpos / old_steps_per_unit; motor[m]->settings.current_pos = pos * motor[m]->steps_per_unit; arch_addpos(id, m, motor[m]->settings.current_pos - oldpos); // Adjust current_pos in all history. for (int h = 0; h < FRAGMENTS_PER_BUFFER; ++h) { oldpos = motor[m]->history[h].current_pos; pos = oldpos / old_steps_per_unit; motor[m]->history[h].current_pos = pos * motor[m]->steps_per_unit; } } } if (must_move) move_to_current(); } // }}}
void Space::load_motor(uint8_t m, int32_t &addr) { // {{{ loaddebug("loading motor %d", m); uint16_t enable = motor[m]->enable_pin.write(); double old_home_pos = motor[m]->home_pos; double old_steps_per_unit = motor[m]->steps_per_unit; motor[m]->step_pin.read(read_16(addr)); motor[m]->dir_pin.read(read_16(addr)); motor[m]->enable_pin.read(read_16(addr)); motor[m]->limit_min_pin.read(read_16(addr)); motor[m]->limit_max_pin.read(read_16(addr)); motor[m]->sense_pin.read(read_16(addr)); motor[m]->steps_per_unit = read_float(addr); motor[m]->max_steps = read_8(addr); motor[m]->home_pos = read_float(addr); motor[m]->limit_v = read_float(addr); motor[m]->limit_a = read_float(addr); motor[m]->home_order = read_8(addr); arch_motors_change(); SET_OUTPUT(motor[m]->enable_pin); if (enable != motor[m]->enable_pin.write()) { if (motors_busy) SET(motor[m]->enable_pin); else { RESET(motor[m]->enable_pin); } } RESET(motor[m]->step_pin); SET_INPUT(motor[m]->limit_min_pin); SET_INPUT(motor[m]->limit_max_pin); SET_INPUT(motor[m]->sense_pin); bool must_move = false; if (!isnan(motor[m]->home_pos)) { // Axes with a limit switch. if (motors_busy && (old_home_pos != motor[m]->home_pos || old_steps_per_unit != motor[m]->steps_per_unit) && !isnan(old_home_pos)) { int32_t hp = motor[m]->home_pos * motor[m]->steps_per_unit + (motor[m]->home_pos > 0 ? .49 : -.49); int32_t ohp = old_home_pos * old_steps_per_unit + (old_home_pos > 0 ? .49 : -.49); int32_t diff = hp - ohp; motor[m]->settings.current_pos += diff; cpdebug(id, m, "load motor new home add %d", diff); arch_addpos(id, m, diff); must_move = true; } } else { // Axes without a limit switch, including extruders. if (motors_busy && old_steps_per_unit != motor[m]->steps_per_unit) { int32_t cp = motor[m]->settings.current_pos; double pos = cp / old_steps_per_unit; cpdebug(id, m, "load motor new steps no home"); motor[m]->settings.current_pos = pos * motor[m]->steps_per_unit; int diff = motor[m]->settings.current_pos - cp; arch_addpos(id, m, diff); } } if (must_move) move_to_current(); } // }}}
void buffer_refill() { // {{{ if (preparing) { //debug("no refill because prepare"); return; } if (moving_to_current == 2) move_to_current(); if (!computing_move || refilling || stopping || discard_pending || discarding) { //debug("refill block %d %d %d %d %d", computing_move, refilling, stopping, discard_pending, discarding); return; } refilling = true; // send_fragment in the previous refill may have failed; try it again. if (current_fragment_pos > 0) send_fragment(); //debug("refill start %d %d %d", running_fragment, current_fragment, sending_fragment); // Keep one free fragment, because we want to be able to rewind and use the buffer before the one currently active. while (computing_move && !stopping && !discard_pending && !discarding && (running_fragment - 1 - current_fragment + FRAGMENTS_PER_BUFFER) % FRAGMENTS_PER_BUFFER > 4 && !sending_fragment) { //debug("refill %d %d %f", current_fragment, current_fragment_pos, spaces[0].motor[0]->settings.current_pos); // fill fragment until full. apply_tick(); //debug("refill2 %d %f", current_fragment, spaces[0].motor[0]->settings.current_pos); if (current_fragment_pos >= SAMPLES_PER_FRAGMENT) { //debug("fragment full %d %d %d", computing_move, current_fragment_pos, BYTES_PER_FRAGMENT); send_fragment(); } // Check for commands from host; in case of many short buffers, this loop may not end in a reasonable time. //serial(0); } if (stopping || discard_pending) { //debug("aborting refill for stopping"); refilling = false; return; } if (!computing_move && current_fragment_pos > 0) { //debug("finalize"); send_fragment(); } refilling = false; arch_start_move(0); } // }}}
void Space::load_info(int32_t &addr) { // {{{ loaddebug("loading space %d", id); uint8_t t = type; if (t >= NUM_SPACE_TYPES) t = DEFAULT_TYPE; type = read_8(addr); if (type >= NUM_SPACE_TYPES || (id == 1 && type != EXTRUDER_TYPE)) { debug("request for type %d ignored", type); type = t; } bool ok; if (t != type) { loaddebug("setting type to %d", type); space_types[t].free(this); if (!space_types[type].init(this)) { type = DEFAULT_TYPE; space_types[type].reset_pos(this); for (uint8_t a = 0; a < num_axes; ++a) axis[a]->settings.current = axis[a]->settings.source; return; // The rest of the package is not meant for DEFAULT_TYPE, so ignore it. } ok = false; } else { if (computing_move || !motors_busy) ok = false; else ok = true; } space_types[type].load(this, t, addr); if (t != type) { space_types[type].reset_pos(this); loaddebug("resetting current for load space %d", id); for (uint8_t a = 0; a < num_axes; ++a) axis[a]->settings.current = axis[a]->settings.source; } if (ok) move_to_current(); loaddebug("done loading space"); } // }}}