I'm pulling my hair out here; I have a custom board with an nrf52840 on it, and my code is using Zephyr 3.2 (I'm not specifically using any of the nrf SDKs, just stock Zephyr).
I have verified that the hardware works - I have built the Zephyr "button" sample (`zephyr/samples/basic/button`) and verified that the GPIO in question is the correct one, and that it works in the sample. (GPIO 0.17, in case it matters)
However, in my larger application (you know, where I actually want to USE it), I'm trying to build a driver which needs to detect edge-triggered interrupts on this GPIO, and for the life of me, I can't get the interrupt handler to trigger. As far as I can tell, I'm setting everything up the same way:
- call `gpio_pin_interrupt_configure_dt()` on the pin in question'
- call `gpio_init_callback()` to initialize the callback function
- call `gpio_add_callback()` to call the callback function to the pin
... but the callback is never called, even though the GPIO state is changing.
I have a bunch of `printk` debugging and I'm also using Segger Ozone - what else should I be looking for here? I'd appreciate suggestions of specific things to look at (maybe interrupts are not being enabled? where do I check that?) in the debugger or source code.
This is the init function (where I'm trying to set up interrupts) and some associated support code - any pointers of what to look at would be greatly appreciated:
struct hakkei_power_config {const struct gpio_dt_spec signal;};
struct hakkei_power_data {struct gpio_callback pwr_cb;const struct device *dev;struct k_work work;const char *str;};void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {printk("Button pressed at %" PRIu32 "\n", k_cycle_get_32());}
static int hakkei_power_init(const struct device *dev) {struct hakkei_power_data *data = dev->data;const struct hakkei_power_config *config = dev->config;
data->dev = dev;
if (!device_is_ready(config->signal.port)) {LOG_ERR("switch gpio not ready!");}
if (gpio_pin_configure_dt(&config->signal, GPIO_INPUT)) {LOG_ERR("Failed to configure signal pin");return -EIO;}int ret = gpio_pin_interrupt_configure_dt(&config->signal, GPIO_INT_EDGE_BOTH);if (ret != 0) {printk("Error %d: failed to configure interrupt on %s pin %d\n", ret,config->signal.port->name, config->signal.pin);return;}gpio_init_callback(&data->pwr_cb, button_pressed, BIT(config->signal.pin));gpio_add_callback(config->signal.port, &data->pwr_cb);printk("callback set? str is %s\n", data->str);printk("Set up button at %s pin %d\n", config->signal.port->name, config->signal.pin);switch (gpio_pin_get_dt(&config->signal)) {case 0:LOG_WRN("power is off");printk("off\n");break;case 1:LOG_WRN("power is on");printk("on\n");break;default:LOG_ERR("power is unknown");break;};
printk("here2\n");// k_work_init(&data->work, hakkei_power_work_cb);// k_work_submit(&data->work);printk("here3\n");LOG_ERR("This is where the power switch initialization will go");
LOG_WRN("LOOP");while (1) {k_msleep(100);switch (gpio_pin_get_dt(&config->signal)) {case 0:printk("OFF ");break;case 1:printk("ON ");break;default:LOG_ERR("power is unknown");break;};}
return 0;}
static const struct hakkei_power_config config = {.signal = GPIO_DT_SPEC_INST_GET(0, signal_gpios)};static const struct hakkei_power_data data = {.str = "BLARGH"};DEVICE_DT_INST_DEFINE(0, hakkei_power_init, NULL, &data, &config, APPLICATION, 1, NULL);