// Resets stack static void red_stack_reset(void) { // Change mux of reset pin to output gpio_mux_configure(_red_stack_reset_stack_pin, GPIO_MUX_OUTPUT); gpio_output_clear(_red_stack_reset_stack_pin); SLEEP_NS(0, 1000*1000*100); // Clear reset pin for 100ms to force reset gpio_output_set(_red_stack_reset_stack_pin); SLEEP_NS(1, 1000*1000*500); // Wait 1.5s so slaves can start properly // Change mux back to interrupt, so we can see if a human presses reset gpio_mux_configure(_red_stack_reset_stack_pin, GPIO_MUX_6); }
// Initialize TX/RX state void init_tx_rx_state(void) { _tx_pin.port_index = GPIO_PORT_C; _tx_pin.pin_index = GPIO_PIN_19; _rx_pin.port_index = GPIO_PORT_B; _rx_pin.pin_index = GPIO_PIN_13; gpio_mux_configure(_tx_pin, GPIO_MUX_OUTPUT); gpio_mux_configure(_rx_pin, GPIO_MUX_OUTPUT); // By default, RX = always on and TX = enabled on demand gpio_output_clear(_tx_pin); gpio_output_clear(_rx_pin); log_debug("RS485: Initialized RS485 TX/RX state"); }
static void red_extension_configure_pin(ExtensionPinConfiguration *config, int extension) { gpio_mux_configure(config->pin[extension], config->mux); if (config->value == 0) { gpio_output_clear(config->pin[extension]); } else { gpio_output_set(config->pin[extension]); // This should enable pull-up in case of input } }
static int red_stack_init_spi(void) { uint8_t slave; const uint8_t mode = RED_STACK_SPI_CONFIG_MODE; const uint8_t lsb_first = RED_STACK_SPI_CONFIG_LSB_FIRST; const uint8_t bits_per_word = RED_STACK_SPI_CONFIG_BITS_PER_WORD; const uint32_t max_speed_hz = RED_STACK_SPI_CONFIG_MAX_SPEED_HZ; // Set Master High pin to low (so Master Bricks above RED Brick can // configure themselves as slave) gpio_mux_configure(_red_stack_master_high_pin, GPIO_MUX_OUTPUT); gpio_output_clear(_red_stack_master_high_pin); // Initialize slaves 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].slave_select_pin = _red_stack_slave_select_pins[slave]; _red_stack.slaves[slave].sequence_number_master = 1; _red_stack.slaves[slave].sequence_number_slave = 0; // Bring slave in initial state (deselected) gpio_mux_configure(_red_stack.slaves[slave].slave_select_pin, GPIO_MUX_OUTPUT); red_stack_spi_deselect(&_red_stack.slaves[slave]); } // Reset slaves and wait for slaves to be ready red_stack_reset(); // Open spidev _red_stack_spi_fd = open(_red_stack_spi_device, O_RDWR); if (_red_stack_spi_fd < 0) { log_error("Could not open %s", _red_stack_spi_device); return -1; } if (ioctl(_red_stack_spi_fd, SPI_IOC_WR_MODE, &mode) < 0) { log_error("Could not configure SPI mode"); return -1; } if (ioctl(_red_stack_spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &max_speed_hz) < 0) { log_error("Could not configure SPI max speed"); return -1; } if (ioctl(_red_stack_spi_fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word) < 0) { log_error("Could not configure SPI bits per word"); return -1; } if (ioctl(_red_stack_spi_fd, SPI_IOC_WR_LSB_FIRST, &lsb_first) < 0) { log_error("Could not configure SPI lsb first"); return -1; } // Create SPI packet transceive thread // FIXME: maybe handshake thread start? thread_create(&_red_stack_spi_thread, red_stack_spi_thread, NULL); return 0; }