static void eload(Space *s, uint8_t old_type, int32_t &addr) {
	uint8_t num = read_8(addr);
	if (!s->setup_nums(num, num)) {
		debug("Failed to set up extruder axes");
		uint8_t n = min(s->num_axes, s->num_motors);
		if (!s->setup_nums(n, n)) {
			debug("Trouble!  Failed to abort.  Cancelling.");
			s->cancel_update();
		}
	}
	for (int a = EDATA(s).num_axes; a < s->num_axes; ++a) {
		s->axis[a]->type_data = new ExtruderAxisData;
		for (int i = 0; i < 3; ++i)
			EADATA(s, a).offset[i] = 0;
	}
	EDATA(s).num_axes = s->num_axes;
	bool move = false;
	if (motors_busy && !computing_move && settings.queue_start == settings.queue_end && !settings.queue_full) {
		move = true;
		queue[settings.queue_end].probe = false;
		queue[settings.queue_end].cb = false;
		queue[settings.queue_end].f[0] = INFINITY;
		queue[settings.queue_end].f[1] = INFINITY;
		for (int i = 0; i < spaces[0].num_axes; ++i) {
			queue[settings.queue_end].data[i] = spaces[0].axis[i]->settings.current;
			for (int ss = 0; ss < 2; ++ss)
				queue[settings.queue_end].data[i] = space_types[spaces[ss].type].unchange0(&spaces[ss], i, queue[settings.queue_end].data[i]);
			if (i == 2)
				queue[settings.queue_end].data[i] -= zoffset;
		}
		for (int i = spaces[0].num_axes; i < QUEUE_LENGTH; ++i) {
			queue[settings.queue_end].data[i] = NAN;
		}
		cpdebug(0, 0, "eload end");
		settings.queue_end = (settings.queue_end + 1) % QUEUE_LENGTH;
		// This shouldn't happen and causes communication problems, but if you have a 1-item buffer it is correct.
		if (settings.queue_end == settings.queue_start)
			settings.queue_full = true;
	}
	for (int a = 0; a < s->num_axes; ++a) {
		for (int o = 0; o < 3; ++o)
			EADATA(s, a).offset[o] = read_float(addr);
	}
	if (move) {
		next_move();
		buffer_refill();
	}
}
Exemplo n.º 2
0
void move_to_current() { // {{{
	if (computing_move || !motors_busy) {
		if (moving_to_current == 0)
			moving_to_current = 1;
		return;
	}
	moving_to_current = 0;
	debug("move to current");
	settings.f0 = 0;
	settings.fmain = 1;
	settings.fp = 0;
	settings.fq = 0;
	settings.t0 = 0;
	settings.tp = 0;
	cbs_after_current_move = 0;
	current_fragment_pos = 0;
	first_fragment = current_fragment;
	computing_move = true;
	settings.cbs = 0;
	settings.hwtime = 0;
	settings.start_time = 0;
	settings.last_time = 0;
	settings.last_current_time = 0;
	for (uint8_t s = 0; s < 2; ++s) {
		Space &sp = spaces[s];
		sp.settings.dist[0] = 0;
		sp.settings.dist[1] = 0;
		for (uint8_t a = 0; a < sp.num_axes; ++a) {
			cpdebug(s, a, "using current %f", sp.axis[a]->settings.current);
			sp.axis[a]->settings.source = sp.axis[a]->settings.current;
			sp.axis[a]->settings.target = sp.axis[a]->settings.current;
			sp.axis[a]->settings.dist[0] = 0;
			sp.axis[a]->settings.dist[1] = 0;
			sp.axis[a]->settings.main_dist = 0;
		}
		for (uint8_t m = 0; m < sp.num_motors; ++m)
			sp.motor[m]->settings.last_v = 0;
	}
#ifdef DEBUG_PATH
	fprintf(stderr, "\n");
#endif
	buffer_refill();
} // }}}
Exemplo n.º 3
0
void move_to_current() { // {{{
	if (computing_move || !motors_busy) {
		if (moving_to_current == 0)
			moving_to_current = 1;
		return;
	}
	moving_to_current = 0;
	//debug("move to current");
	settings.f0 = 0;
	settings.fmain = 1;
	settings.fp = 0;
	settings.fq = 0;
	settings.t0 = 0;
	settings.tp = 0;
	//debug("clearing %d cbs after current move for move to current", cbs_after_current_move);
	cbs_after_current_move = 0;
	current_fragment_pos = 0;
	first_fragment = current_fragment;
	computing_move = true;
	settings.cbs = 0;
	settings.hwtime = 0;
	settings.start_time = 0;
	settings.last_time = 0;
	settings.last_current_time = 0;
	for (int s = 0; s < NUM_SPACES; ++s) {
		Space &sp = spaces[s];
		sp.settings.dist[0] = 0;
		sp.settings.dist[1] = 0;
		for (int a = 0; a < sp.num_axes; ++a) {
			cpdebug(s, a, "using current %f", sp.axis[a]->settings.current);
			sp.axis[a]->settings.source = sp.axis[a]->settings.current;
			sp.axis[a]->settings.target = sp.axis[a]->settings.current;
			sp.axis[a]->settings.dist[0] = 0;
			sp.axis[a]->settings.dist[1] = 0;
			sp.axis[a]->settings.main_dist = 0;
		}
		for (int m = 0; m < sp.num_motors; ++m)
			sp.motor[m]->settings.last_v = 0;
	}
	buffer_refill();
} // }}}
Exemplo n.º 4
0
void run_file_fill_queue() {
	static bool lock = false;
	if (lock)
		return;
	lock = true;
	rundebug("run queue, wait = %d tempwait = %d q = %d %d %d finish = %d", run_file_wait, run_file_wait_temp, settings.queue_end, settings.queue_start, settings.queue_full, run_file_finishing);
	if (run_file_audio >= 0) {
		while (true) {
			if (!run_file_map || run_file_wait || run_file_finishing)
				break;
			if (settings.run_file_current >= run_file_num_records) {
				run_file_finishing = true;
				//debug("done running audio");
				break;
			}
			int16_t next = (current_fragment + 1) % FRAGMENTS_PER_BUFFER;
			if (next == running_fragment)
				break;
			settings.run_file_current = arch_send_audio(&reinterpret_cast <uint8_t *>(run_file_map)[sizeof(double)], settings.run_file_current, run_file_num_records, run_file_audio);
			current_fragment = next;
			store_settings();
			if ((current_fragment - running_fragment + FRAGMENTS_PER_BUFFER) % FRAGMENTS_PER_BUFFER >= MIN_BUFFER_FILL && !stopping)
				arch_start_move(0);
		}
		lock = false;
		return;
	}
	while (run_file_map	// There is a file to run.
			&& (settings.queue_end - settings.queue_start + QUEUE_LENGTH) % QUEUE_LENGTH < 4	// There is space in the queue.
			&& !settings.queue_full	// Really, there is space in the queue.
			&& settings.run_file_current < run_file_num_records	// There are records to send.
			&& !run_file_wait_temp	// We are not waiting for a temp alarm.
			&& !run_file_wait	// We are not waiting for something else (pause or confirm).
			&& !run_file_finishing) {	// We are not waiting for underflow (should be impossible anyway, if there are commands in the queue).
		int t = run_file_map[settings.run_file_current].type;
		if (t != RUN_LINE && t != RUN_PRE_LINE && t != RUN_PRE_ARC && t != RUN_ARC && (arch_running() || settings.queue_end != settings.queue_start || computing_move))
			break;
		Run_Record &r = run_file_map[settings.run_file_current];
		rundebug("running %d: %d %d", settings.run_file_current, r.type, r.tool);
		switch (r.type) {
			case RUN_SYSTEM:
			{
				char const *cmd = strndupa(&reinterpret_cast<char const *>(run_file_map)[run_file_first_string + strings[r.tool].start], strings[r.tool].len);
				debug("Running system command: %ld %d %s", strings[r.tool].start, strings[r.tool].len, cmd);
				int ret = system(cmd);
				debug("Done running system command, return = %d", ret);
				break;
			}
			case RUN_PRE_ARC:
			{
				double x = r.X * run_file_cosa - r.Y * run_file_sina + run_file_refx;
				double y = r.Y * run_file_cosa + r.X * run_file_sina + run_file_refy;
				double z = r.Z;
				//debug("line %f %f %f", x, y, z);
				queue[settings.queue_end].center[0] = x;
				queue[settings.queue_end].center[1] = y;
				queue[settings.queue_end].center[2] = handle_probe(x, y, z);
				queue[settings.queue_end].normal[0] = r.E;
				queue[settings.queue_end].normal[1] = r.f;
				queue[settings.queue_end].normal[2] = r.F;
				break;
			}
			case RUN_PRE_LINE:
			{
				run_preline.X = r.X;
				run_preline.Y = r.Y;
				run_preline.Z = r.Z;
				run_preline.E = r.E;
				run_preline.tool = r.tool;
				break;
			}
			case RUN_LINE:
			case RUN_ARC:
			{
				queue[settings.queue_end].single = false;
				queue[settings.queue_end].probe = false;
				queue[settings.queue_end].arc = r.type == RUN_ARC;
				queue[settings.queue_end].f[0] = r.f;
				queue[settings.queue_end].f[1] = r.F;
				double x = r.X * run_file_cosa - r.Y * run_file_sina + run_file_refx;
				double y = r.Y * run_file_cosa + r.X * run_file_sina + run_file_refy;
				double z = r.Z;
				//debug("line/arc %f %f %f", x, y, z);
				int num0 = spaces[0].num_axes;
				if (num0 > 0) {
					queue[settings.queue_end].data[0] = x;
					if (num0 > 1) {
						queue[settings.queue_end].data[1] = y;
						if (num0 > 2) {
							queue[settings.queue_end].data[2] = handle_probe(x, y, z);
							if (num0 > 3) {
								queue[settings.queue_end].data[3] = run_preline.X;
								if (num0 > 4) {
									queue[settings.queue_end].data[4] = run_preline.Y;
									if (num0 > 5) {
										queue[settings.queue_end].data[5] = run_preline.Z;
									}
								}
								run_preline.X = NAN;
								run_preline.Y = NAN;
								run_preline.Z = NAN;
							}
						}
					}
				}
				for (int i = 6; i < num0; ++i)
					queue[settings.queue_end].data[i] = NAN;
				for (int i = 0; i < spaces[1].num_axes; ++i) {
					queue[settings.queue_end].data[num0 + i] = (i == r.tool ? r.E : i == run_preline.tool ? run_preline.E : NAN);
					//debug("queue %d + %d = %f", num0, i, queue[settings.queue_end].data[num0 + i]);
				}
				run_preline.E = NAN;
				num0 += spaces[1].num_axes;
				for (int s = 2; s < NUM_SPACES; ++s) {
					for (int i = 0; i < spaces[s].num_axes; ++i)
						queue[settings.queue_end].data[num0 + i] = NAN;
					num0 += spaces[s].num_axes;
				}
				queue[settings.queue_end].time = r.time;
				queue[settings.queue_end].dist = r.dist;
				queue[settings.queue_end].cb = false;
				settings.queue_end = (settings.queue_end + 1) % QUEUE_LENGTH;
				if (!computing_move)
					next_move();
				else
					rundebug("no");
				buffer_refill();
				break;
			}
			case RUN_GPIO:
			{
				int tool = r.tool;
				if (tool == -2)
					tool = fan_id;
				else if (tool == -3)
					tool = spindle_id;
				if (tool < 0 || tool >= num_gpios) {
					if (tool != -1)
						debug("cannot set invalid gpio %d", tool);
					break;
				}
				if (r.X) {
					gpios[tool].state = 1;
					SET(gpios[tool].pin);
				}
				else {
					gpios[tool].state = 0;
					RESET(gpios[tool].pin);
				}
				send_host(CMD_UPDATE_PIN, tool, gpios[tool].state);
				break;
			}
			case RUN_SETTEMP:
			{
				int tool = r.tool;
				if (tool == -1)
					tool = bed_id;
				rundebug("settemp %d %f", tool, r.X);
				settemp(tool, r.X);
				send_host(CMD_UPDATE_TEMP, tool, 0, r.X);
				break;
			}
			case RUN_WAITTEMP:
			{
				int tool = r.tool;
				if (tool == -2)
					tool = bed_id;
				if (tool == -3) {
					for (int i = 0; i < num_temps; ++i) {
						if (temps[i].min_alarm >= 0 || temps[i].max_alarm < MAXINT) {
							run_file_wait_temp += 1;
							waittemp(i, temps[i].min_alarm, temps[i].max_alarm);
						}
					}
					break;
				}
				if (tool < 0 || tool >= num_temps) {
					if (tool != -1)
						debug("cannot wait for invalid temp %d", tool);
					break;
				}
				else
					rundebug("waittemp %d", tool);
				if (temps[tool].adctarget[0] >= 0 && temps[tool].adctarget[0] < MAXINT) {
					rundebug("waiting");
					run_file_wait_temp += 1;
					waittemp(tool, temps[tool].target[0], temps[tool].max_alarm);
				}
				else
					rundebug("not waiting");
				break;
			}
			case RUN_SETPOS:
				if (r.tool >= spaces[1].num_axes) {
					debug("Not setting position of invalid extruder %d", r.tool);
					break;
				}
				setpos(1, r.tool, r.X);
				break;
			case RUN_WAIT:
				if (r.X > 0) {
					run_file_timer.it_value.tv_sec = r.X;
					run_file_timer.it_value.tv_nsec = (r.X - run_file_timer.it_value.tv_sec) * 1e9;
					run_file_wait += 1;
					timerfd_settime(pollfds[0].fd, 0, &run_file_timer, NULL);
				}
				break;
			case RUN_CONFIRM:
			{
				int len = min(strings[r.tool].len, 250);
				memcpy(datastore, &reinterpret_cast<char const *>(run_file_map)[run_file_first_string + strings[r.tool].start], len);
				run_file_wait += 1;
				send_host(CMD_CONFIRM, r.X ? 1 : 0, 0, 0, 0, len);
				break;
			}
			case RUN_PARK:
				run_file_wait += 1;
				send_host(CMD_PARKWAIT);
				break;
			default:
				debug("Invalid record type %d in %s", r.type, run_file_name);
				break;
		}
		settings.run_file_current += 1;
	}
	rundebug("run queue done");
	if (run_file_map && settings.run_file_current >= run_file_num_records && !run_file_wait_temp && !run_file_wait && !run_file_finishing) {
		// Done.
		//debug("done running file");
		if (!computing_move && !sending_fragment && !arch_running()) {
			send_host(CMD_FILE_DONE);
			abort_run_file();
		}
		else
			run_file_finishing = true;
	}
	lock = false;
	return;
}
Exemplo n.º 5
0
bool globals_load(int32_t &addr)
{
	bool change_hw = false;
	uint8_t nt = read_8(addr);
	uint8_t ng = read_8(addr);
	// Free the old memory and initialize the new memory.
	if (nt != num_temps) {
		ldebug("new temp");
		for (uint8_t t = nt; t < num_temps; ++t)
			temps[t].free();
		Temp *new_temps = new Temp[nt];
		for (uint8_t t = 0; t < min(nt, num_temps); ++t)
			temps[t].copy(new_temps[t]);
		for (uint8_t t = num_temps; t < nt; ++t)
			new_temps[t].init();
		delete[] temps;
		temps = new_temps;
		num_temps = nt;
	}
	if (ng != num_gpios) {
		for (uint8_t g = ng; g < num_gpios; ++g)
			gpios[g].free();
		Gpio *new_gpios = new Gpio[ng];
		for (uint8_t g = 0; g < min(ng, num_gpios); ++g)
			gpios[g].copy(new_gpios[g]);
		for (uint8_t g = num_gpios; g < ng; ++g)
			new_gpios[g].init();
		delete[] gpios;
		gpios = new_gpios;
		num_gpios = ng;
	}
	ldebug("new done");
	int p = led_pin.write();
	led_pin.read(read_16(addr));
	if (p != led_pin.write())
		change_hw = true;
	p = stop_pin.write();
	stop_pin.read(read_16(addr));
	if (p != stop_pin.write())
		change_hw = true;
	p = probe_pin.write();
	probe_pin.read(read_16(addr));
	if (p != probe_pin.write())
		change_hw = true;
	p = spiss_pin.write();
	spiss_pin.read(read_16(addr));
	if (p != spiss_pin.write())
		change_hw = true;
	int t = timeout;
	timeout = read_16(addr);
	if (t != timeout)
		change_hw = true;
	bed_id = read_16(addr);
	fan_id = read_16(addr);
	spindle_id = read_16(addr);
	feedrate = read_float(addr);
	if (isnan(feedrate) || isinf(feedrate) || feedrate <= 0)
		feedrate = 1;
	max_deviation = read_float(addr);
	max_v = read_float(addr);
	int ce = read_8(addr);
	targetx = read_float(addr);
	targety = read_float(addr);
	double zo = read_float(addr);
	if (motors_busy && (current_extruder != ce || zoffset != zo) && settings.queue_start == settings.queue_end && !settings.queue_full && !computing_move) {
		queue[settings.queue_end].probe = false;
		queue[settings.queue_end].cb = false;
		queue[settings.queue_end].f[0] = INFINITY;
		queue[settings.queue_end].f[1] = INFINITY;
		for (int i = 0; i < spaces[0].num_axes; ++i) {
			queue[settings.queue_end].data[i] = spaces[0].axis[i]->settings.current - (i == 2 ? zoffset : 0);
			for (int s = 0; s < NUM_SPACES; ++s)
				queue[settings.queue_end].data[i] = space_types[spaces[s].type].unchange0(&spaces[s], i, queue[settings.queue_end].data[i]);
		}
		for (int i = spaces[0].num_axes; i < QUEUE_LENGTH; ++i) {
			queue[settings.queue_end].data[i] = NAN;
		}
		settings.queue_end = (settings.queue_end + 1) % QUEUE_LENGTH;
		// This shouldn't happen and causes communication problems, but if you have a 1-item buffer it is correct.
		if (settings.queue_end == settings.queue_start)
			settings.queue_full = true;
		current_extruder = ce;
		zoffset = zo;
		next_move();
		buffer_refill();
	}
	else {
		current_extruder = ce;
		zoffset = zo;
	}
	bool store = read_8(addr);
	if (store && !store_adc) {
		store_adc = fopen("/tmp/franklin-adc-dump", "a");
	}
	else if (!store && store_adc) {
		fclose(store_adc);
		store_adc = NULL;
	}
	ldebug("all done");
	if (change_hw)
		arch_motors_change();
	return true;
}