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); } } }
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); } }
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(); }
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; }