static void battery_latch_en(void) { gpio_cfg_data_t config; /* Enable Battery Latch */ config.gpio_type = GPIO_OUTPUT; soc_gpio_set_config(SOC_GPIO_32, POWER_LATCH_GPIO, &config); soc_gpio_write(SOC_GPIO_32, POWER_LATCH_GPIO, 1); }
void enable_vusb_regulator(struct usb_pm_info *usb_pm, bool enable){ gpio_cfg_data_t config; struct device * gpiodev = usb_pm->vusb_enable_dev; if (gpiodev){ config.gpio_type = GPIO_OUTPUT; soc_gpio_set_config(gpiodev, usb_pm->vusb_enable_pin, &config); soc_gpio_write(gpiodev, usb_pm->vusb_enable_pin, enable); /* We need to wait some time here for USB voltage regulator to stabilize */ delay_us(90); } else { pr_warning(LOG_MODULE_USB, "USB Voltage regulator enable not supported"); } }
/** Stores a user callback, and enables PIN1 interrupts from the * BMI160 module. */ void CurieIMUClass::attachInterrupt(void (*callback)(void)) { gpio_cfg_data_t cfg; _user_callback = callback; memset(&cfg, 0, sizeof(gpio_cfg_data_t)); cfg.gpio_type = GPIO_INTERRUPT; cfg.int_type = EDGE; cfg.int_polarity = ACTIVE_LOW; cfg.int_debounce = DEBOUNCE_ON; cfg.gpio_cb = bmi160_pin1_isr; soc_gpio_set_config(SOC_GPIO_AON, BMI160_GPIN_AON_PIN, &cfg); setInterruptMode(1); // Active-Low setInterruptDrive(0); // Push-Pull setInterruptLatch(BMI160_LATCH_MODE_10_MS); // 10ms pulse setIntEnabled(true); }
static int nordic_pm_setup(struct device* dev) { int ret = 0; struct nordic_pm_info *priv = (struct nordic_pm_info*)dev->priv; // Configure GPIO AON as wake up source when going high gpio_cfg_data_t config; config.gpio_type = GPIO_INTERRUPT; config.int_type = EDGE; config.int_polarity = ACTIVE_HIGH; config.int_debounce = DEBOUNCE_ON; config.int_ls_sync = LS_SYNC_OFF; config.gpio_cb = nordic_pm_callback; config.gpio_cb_arg = dev; soc_gpio_deconfig(priv->gpio_dev, priv->wakeup_pin); ret = soc_gpio_set_config(priv->gpio_dev, priv->wakeup_pin, &config); pr_debug(LOG_MODULE_DRV, "%s %d: use aon - %d (%d)", DRV_NAME, dev->id, priv->wakeup_pin, ret); return ret; }
static int usb_pm_resume(struct device* dev) { #ifdef CONFIG_SOC_GPIO_AON if (((struct usb_pm_info*)(dev->priv))->interrupt_source == USB_AON_IRQ_SOURCE) { int ret = 0; struct usb_pm_info *priv = (struct usb_pm_info*)dev->priv; // Configure AON as USB wake up source gpio_cfg_data_t config; config.gpio_type = GPIO_INTERRUPT; config.int_type = LEVEL; config.int_polarity = priv->is_plugged ? ACTIVE_LOW : ACTIVE_HIGH; config.int_debounce = DEBOUNCE_ON; config.int_ls_sync = LS_SYNC_OFF; config.gpio_cb = usb_aon_callback; config.gpio_cb_arg = dev; soc_gpio_deconfig(priv->evt_dev, priv->source_pin); ret = soc_gpio_set_config(priv->evt_dev, priv->source_pin, &config); pr_debug(LOG_MODULE_DRV, "device %d: use aon %d - %d (%d)", dev->id, priv->interrupt_source, priv->source_pin, ret); return ret; } #endif #ifdef CONFIG_SOC_COMPARATOR if (((struct usb_pm_info*)(dev->priv))->interrupt_source == USB_COMPARATOR_IRQ_SOURCE) { int ret = 0; struct usb_pm_info *priv = (struct usb_pm_info*)dev->priv; // Configure comparator as USB wake up source ret = comp_configure(priv->evt_dev, priv->source_pin, priv->is_plugged ? 1:0, 1, usb_comp_callback, dev); pr_debug(LOG_MODULE_DRV, "device %s: use comp %d - %d (%d)", dev->id, priv->interrupt_source, priv->source_pin, ret); return ret; } #endif pr_debug(LOG_MODULE_DRV, "%d: no irq source", dev->id); return -1; }
static void usb_aon_callback(bool state, void *priv_data) { gpio_cfg_data_t config; struct device *dev = (struct device*)priv_data; struct usb_pm_info *priv = (struct usb_pm_info*)dev->priv; usb_generic_callback(dev); // Configure AON as USB wake up source config.gpio_type = GPIO_INTERRUPT; config.int_type = LEVEL; config.int_polarity = priv->is_plugged ? ACTIVE_LOW : ACTIVE_HIGH; config.int_debounce = DEBOUNCE_ON; config.int_ls_sync = LS_SYNC_OFF; config.gpio_cb = usb_aon_callback; config.gpio_cb_arg = priv_data; soc_gpio_deconfig(priv->evt_dev, priv->source_pin); int ret = soc_gpio_set_config(priv->evt_dev, priv->source_pin, &config); if (ret != 0) { pr_error(LOG_MODULE_DRV, "usb_pm: cb config failed (%d)", ret); } }
static DRIVER_API_RC soc_gpio_test_pin(struct device *dev, unsigned int input_pin, unsigned int output_pin) { DRIVER_API_RC ret; bool value; gpio_cfg_data_t in_pin_cfg; gpio_cfg_data_t out_pin_cfg; in_pin_cfg.gpio_type = GPIO_INPUT; in_pin_cfg.int_type = LEVEL; in_pin_cfg.int_polarity = ACTIVE_LOW; in_pin_cfg.int_debounce = DEBOUNCE_OFF; in_pin_cfg.int_ls_sync = LS_SYNC_OFF; in_pin_cfg.gpio_cb = NULL; out_pin_cfg.gpio_type = GPIO_OUTPUT; out_pin_cfg.int_type = LEVEL; out_pin_cfg.int_polarity = ACTIVE_LOW; out_pin_cfg.int_debounce = DEBOUNCE_OFF; out_pin_cfg.int_ls_sync = LS_SYNC_OFF; out_pin_cfg.gpio_cb = NULL; if((ret = soc_gpio_set_config(dev, input_pin, &in_pin_cfg)) != DRV_RC_OK) { cu_print("Error pin %d config (%d)\n", input_pin, ret); return ret; } if((ret = soc_gpio_set_config(dev, output_pin, &out_pin_cfg)) != DRV_RC_OK) { cu_print("Error pin %d config (%d)\n", output_pin, ret); soc_gpio_deconfig(dev, input_pin); return ret; } // Test LOW if((ret = soc_gpio_write(dev, output_pin, 0)) != DRV_RC_OK) { cu_print("Error pin %d write 1 (%d)\n", output_pin, ret); soc_gpio_deconfig(dev, output_pin); soc_gpio_deconfig(dev, input_pin); return ret; } trans_delay(); // Delay a little bit if((ret = soc_gpio_read(dev, input_pin, &value)) != DRV_RC_OK) { cu_print("Error pin %d read 1 (%d)\n", input_pin, ret); soc_gpio_deconfig(dev, output_pin); soc_gpio_deconfig(dev, input_pin); return ret; } if(value) { cu_print("Error pin %d is at 1, 0 expected\n", input_pin); soc_gpio_deconfig(dev, output_pin); soc_gpio_deconfig(dev, input_pin); return DRV_RC_FAIL; } // Test HIGH if((ret = soc_gpio_write(dev, output_pin, 1)) != DRV_RC_OK) { cu_print("Error pin %d write 2 (%d)\n", output_pin, ret); soc_gpio_deconfig(dev, output_pin); soc_gpio_deconfig(dev, input_pin); return ret; } trans_delay(); // Delay a little bit if((ret = soc_gpio_read(dev, input_pin, &value)) != DRV_RC_OK) { cu_print("Error pin %d read 2 (%d)\n", input_pin, ret); soc_gpio_deconfig(dev, output_pin); soc_gpio_deconfig(dev, input_pin); return ret; } if(!value) { cu_print("Error pin %d is at 0, 1 expected\n", input_pin); soc_gpio_deconfig(dev, output_pin); soc_gpio_deconfig(dev, input_pin); return DRV_RC_FAIL; } soc_gpio_deconfig(dev, output_pin); soc_gpio_deconfig(dev, input_pin); return DRV_RC_OK; }
static DRIVER_API_RC soc_gpio_test_pin_int(struct device *dev, unsigned int input_pin, unsigned int output_pin) { uint32_t priv = PRIV_KEY; gpio_cfg_data_t in_pin_cfg; gpio_cfg_data_t out_pin_cfg; out_pin_cfg.gpio_type = GPIO_OUTPUT; out_pin_cfg.int_type = LEVEL; out_pin_cfg.int_polarity = ACTIVE_LOW; out_pin_cfg.int_debounce = DEBOUNCE_OFF; out_pin_cfg.gpio_cb = NULL; // TODO: test return value. It should be ok if previous tests worked soc_gpio_set_config(dev, output_pin, &out_pin_cfg); // ----------------------------- // Test ACTIVE_LOW interrupt // ----------------------------- in_pin_cfg.gpio_type = GPIO_INTERRUPT; in_pin_cfg.int_type = EDGE; in_pin_cfg.int_polarity = ACTIVE_LOW; in_pin_cfg.int_debounce = DEBOUNCE_OFF; in_pin_cfg.gpio_cb = my_callback; in_pin_cfg.gpio_cb_arg = &priv; soc_gpio_write(dev, output_pin, 0); trans_delay(); // Delay a little bit my_callback_counter = 0; soc_gpio_set_config(dev, input_pin, &in_pin_cfg); trans_delay(); // Delay a little bit soc_gpio_write(dev, output_pin, 1); trans_delay(); // Delay a little bit // Check that interrupt is not triggered if(my_callback_counter != 0) { cu_print("Error: interrupt occured %d\n", my_callback_counter); goto fail; } // Trigger interrupt (active low) soc_gpio_write(dev, output_pin, 0); trans_delay(); // Delay a little bit // Check that interrupt is triggered if(my_callback_counter != 1) { cu_print("Error: interrupt test for ACTIVE_LOW returned %d\n", my_callback_counter); goto fail; } // Check that pin state returned in IRQ callback is valid if(my_callback_state != false) { cu_print("Error: pin state not valid\n"); goto fail; } // deconfigure input pin for next test (active high) soc_gpio_deconfig(dev, input_pin); // ----------------------------- // Test ACTIVE_HIGH interrupt // ----------------------------- in_pin_cfg.gpio_type = GPIO_INTERRUPT; in_pin_cfg.int_type = EDGE; in_pin_cfg.int_polarity = ACTIVE_HIGH; in_pin_cfg.int_debounce = DEBOUNCE_OFF; in_pin_cfg.gpio_cb = my_callback; // Test LOW soc_gpio_write(dev, output_pin, 1); trans_delay(); // Delay a little bit my_callback_counter = 0; soc_gpio_set_config(dev, input_pin, &in_pin_cfg); soc_gpio_write(dev, output_pin, 0); trans_delay(); // Delay a little bit // Check that interrupt is not triggered if(my_callback_counter != 0) { cu_print("Error: interrupt test for ACTIVE_HIGH returned %d (should be 0)\n", my_callback_counter); goto fail; } // Check that interrupt is triggered (active high) soc_gpio_write(dev, output_pin, 1); trans_delay(); // Delay a little bit if(my_callback_counter != 1) { cu_print("Error: interrupt test for ACTIVE_HIGH returned %d (should be 1)\n", my_callback_counter); goto fail; } // Check that pin state returned in IRQ callback is valid if(my_callback_state != true) { cu_print("Error: pin state not valid\n"); goto fail; } // deconfigure input pin for next test (double edge) soc_gpio_deconfig(dev, input_pin); // ----------------------------- // Test BOTH_EDGE interrupt // ----------------------------- in_pin_cfg.gpio_type = GPIO_INTERRUPT; in_pin_cfg.int_type = DOUBLE_EDGE; in_pin_cfg.int_polarity = ACTIVE_HIGH; in_pin_cfg.int_debounce = DEBOUNCE_OFF; in_pin_cfg.gpio_cb = my_callback; // Test LOW soc_gpio_write(dev, output_pin, 0); trans_delay(); // Delay a little bit soc_gpio_set_config(dev, input_pin, &in_pin_cfg); my_callback_counter = 0; soc_gpio_write(dev, output_pin, 1); trans_delay(); // Delay a little bit // Check that interrupt is triggered if(my_callback_counter != 1) { cu_print("Error: interrupt test for DOUBLE_EDGE returned %d (should be 1)\n", my_callback_counter); goto fail; } // Check that pin state returned in IRQ callback is valid if(my_callback_state != true) { cu_print("Error: pin state not valid\n"); goto fail; } // Check that interrupt is triggered (double edge) soc_gpio_write(dev, output_pin, 0); trans_delay(); // Delay a little bit // Check that interrupt is not triggered if(my_callback_counter != 2) { cu_print("Error: interrupt test for DOUBLE_EDGE returned %d (should be 2)\n", my_callback_counter); goto fail; } // Check that pin state returned in IRQ callback is valid if(my_callback_state != false) { cu_print("Error: pin state not valid\n"); goto fail; } soc_gpio_deconfig(dev, output_pin); soc_gpio_deconfig(dev, input_pin); return DRV_RC_OK; fail: soc_gpio_deconfig(dev, output_pin); soc_gpio_deconfig(dev, input_pin); return DRV_RC_FAIL; }