Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | /* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr.h> #include <board.h> #include <soc.h> #include <drivers/gpio.h> #include <sys/printk.h> #include <sys/util.h> /** * @file * * @brief Example of using GPIOs on UP Squared board * * This example outputs the value of a counter via 4 GPIO lines * as a 4-bit value (bin 0, 1, 2, 3 -> HAT Pin 35, 37, 38, 40). * The counter increments for each change from 0 to 1 on HAT Pin 16. * * Note: * Need to change the BIOS settings: * () Advanced -> HAT Configurations: * - HD-Audio / I2S6 Selec -> Disabled * - GPIO / PWM3 Selection -> GPIO * - GPIO / I2S2 Selection -> GPIO * * - GPIO 19 (Pin16) Confi -> Input * * - GPIO 14 (Pin35) Confi -> Output * - GPIO 15 (Pin37) Confi -> Output * - GPIO 27 (Pin38) Confi -> Output * - GPIO 28 (Pin40) Confi -> Output */ struct _pin { uint32_t hat_num; uint32_t pin; const char *gpio_dev_name; const struct device *gpio_dev; }; struct _pin counter_pins[] = { { .hat_num = 35, .pin = UP2_HAT_PIN_35, .gpio_dev_name = UP2_HAT_PIN_35_DEV, }, { .hat_num = 37, .pin = UP2_HAT_PIN_37, .gpio_dev_name = UP2_HAT_PIN_37_DEV, }, { .hat_num = 38, .pin = UP2_HAT_PIN_38, .gpio_dev_name = UP2_HAT_PIN_38_DEV, }, { .hat_num = 40, .pin = UP2_HAT_PIN_40, .gpio_dev_name = UP2_HAT_PIN_40_DEV, }, }; struct _pin intr_pin = { .hat_num = 16, .pin = UP2_HAT_PIN_16, .gpio_dev_name = UP2_HAT_PIN_16_DEV, }; static struct gpio_callback gpio_cb; static volatile uint32_t counter; K_SEM_DEFINE(counter_sem, 0, 1); #define NUM_PINS ARRAY_SIZE(counter_pins) #define MASK (BIT(NUM_PINS) - 1) void button_cb(const struct device *gpiodev, struct gpio_callback *cb, uint32_t pin) { counter++; k_sem_give(&counter_sem); } int get_gpio_dev(struct _pin *pin) { pin->gpio_dev = device_get_binding(pin->gpio_dev_name); if (!pin->gpio_dev) { printk("ERROR: cannot get device binding for %s\n", pin->gpio_dev_name); return -1; } return 0; } void main(void) { uint32_t val; int i, ret; for (i = 0; i < NUM_PINS; i++) { if (get_gpio_dev(&counter_pins[i]) != 0) { return; } } if (get_gpio_dev(&intr_pin) != 0) { return; } /* Set pins to output */ for (i = 0; i < NUM_PINS; i++) { ret = gpio_pin_configure(counter_pins[i].gpio_dev, counter_pins[i].pin, GPIO_OUTPUT_LOW); if (ret) { printk("ERROR: cannot set HAT pin %d to OUT (%d)\n", counter_pins[i].hat_num, ret); return; } } /* Setup input pin */ ret = gpio_pin_configure(intr_pin.gpio_dev, intr_pin.pin, GPIO_INPUT); if (ret) { printk("ERROR: cannot set HAT pin %d to IN (%d)\n", intr_pin.hat_num, ret); return; } /* Callback uses pin_mask, so need bit shifting */ gpio_init_callback(&gpio_cb, button_cb, (1 << intr_pin.pin)); gpio_add_callback(intr_pin.gpio_dev, &gpio_cb); /* Setup input pin for interrupt */ ret = gpio_pin_interrupt_configure(intr_pin.gpio_dev, intr_pin.pin, GPIO_INT_EDGE_RISING); if (ret) { printk("ERROR: cannot config interrupt on HAT pin %d (%d)\n", intr_pin.hat_num, ret); return; } /* main loop */ val = 0U; while (1) { printk("counter: 0x%x\n", val); for (i = 0; i < NUM_PINS; i++) { ret = gpio_pin_set(counter_pins[i].gpio_dev, counter_pins[i].pin, (val & BIT(i))); if (ret) { printk("ERROR: cannot set HAT pin %d value (%d)\n", counter_pins[i].hat_num, ret); return; } } k_sem_take(&counter_sem, K_FOREVER); val = counter & MASK; } } |