Example #1
0
static void red_stack_spi_handle_reset(void) {
	int slave;

	stack_announce_disconnect(&_red_stack.base);
	_red_stack.base.recipients.count = 0;

	log_info("Starting reinitialization of SPI slaves");

	// Someone pressed reset we have to wait until he stops pressing
	while (gpio_input(_red_stack_reset_stack_pin) == 0) {
		// Wait 100us and check again. We wait as long as the user presses the button
		SLEEP_NS(0, 1000*100);
	}

	SLEEP_NS(1, 1000*1000*500); // Wait 1.5s so slaves can start properly

	// Reinitialize slaves
	_red_stack.slave_num = 0;

	for (slave = 0; slave < RED_STACK_SPI_MAX_SLAVES; slave++) {
		_red_stack.slaves[slave].stack_address = slave;
		_red_stack.slaves[slave].status = RED_STACK_SLAVE_STATUS_ABSENT;
		_red_stack.slaves[slave].sequence_number_master = 1;
		_red_stack.slaves[slave].sequence_number_slave = 0;
		_red_stack.slaves[slave].next_packet_empty = false;

		// Unfortunately we have to discard all of the queued packets.
		// we can't be sure that the packets are for the correct slave after a reset.
		while (queue_peek(&_red_stack.slaves[slave].packet_to_spi_queue) != NULL) {
			queue_pop(&_red_stack.slaves[slave].packet_to_spi_queue, NULL);
		}
	}
}
Example #2
0
void hardware_announce_disconnect(void) {
	int i;
	Stack *stack;

	for (i = 0; i < _stacks.count; ++i) {
		stack = *(Stack **)array_get(&_stacks, i);

		stack_announce_disconnect(stack);
	}
}
Example #3
0
int usb_reopen(void) {
	int i;
	USBStack *usb_stack;

	log_debug("Reopening all USB devices");

	// iterate backwards for simpler index handling and to avoid memmove in
	// array_remove call
	for (i = _usb_stacks.count - 1; i >= 0; --i) {
		usb_stack = array_get(&_usb_stacks, i);

		log_info("Temporarily removing USB device (bus: %u, device: %u) at index %d: %s",
		         usb_stack->bus_number, usb_stack->device_address, i,
		         usb_stack->base.name);

		stack_announce_disconnect(&usb_stack->base);

		array_remove(&_usb_stacks, i, (ItemDestroyFunction)usb_stack_destroy);
	}

	return usb_rescan();
}
Example #4
0
int usb_rescan(void) {
	int i;
	USBStack *usb_stack;

	log_debug("Looking for added/removed USB devices");

	// mark all known USB stacks as potentially removed
	for (i = 0; i < _usb_stacks.count; ++i) {
		usb_stack = array_get(&_usb_stacks, i);

		usb_stack->connected = false;
	}

	// enumerate all USB devices, mark all USB stacks that are still connected
	// and add USB stacks that are newly connected
	if (usb_enumerate() < 0) {
		return -1;
	}

	// remove all USB stacks that are not marked as connected. iterate backwards
	// so array_remove can be used without invalidating the current index
	for (i = _usb_stacks.count - 1; i >= 0; --i) {
		usb_stack = array_get(&_usb_stacks, i);

		if (usb_stack->connected) {
			continue;
		}

		log_info("Removing USB device (bus: %u, device: %u) at index %d: %s",
		         usb_stack->bus_number, usb_stack->device_address, i,
		         usb_stack->base.name);

		stack_announce_disconnect(&usb_stack->base);

		array_remove(&_usb_stacks, i, (ItemDestroyFunction)usb_stack_destroy);
	}

	return 0;
}