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 | /* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr.h> #include <board.h> #include <soc.h> #include <gpio.h> #include <misc/printk.h> #include <misc/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 { u32_t hat_num; u32_t pin; const char *gpio_dev_name; 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 u32_t counter; K_SEM_DEFINE(counter_sem, 0, 1); #define INTR_PIN_FLAGS \ (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | GPIO_INT_ACTIVE_HIGH | \ GPIO_INT_DEBOUNCE | GPIO_PUD_PULL_DOWN) #define NUM_PINS ARRAY_SIZE(counter_pins) #define MASK (BIT(NUM_PINS) - 1) #define GPIO_DEV DT_APL_GPIO_LABEL void button_cb(struct device *gpiodev, struct gpio_callback *cb, u32_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) { u32_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_DIR_OUT); 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, INTR_PIN_FLAGS); if (ret) { printk("ERROR: cannot set HAT pin %d to OUT (%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); gpio_pin_enable_callback(intr_pin.gpio_dev, intr_pin.pin); /* main loop */ val = 0U; while (1) { printk("counter: 0x%x\n", val); for (i = 0; i < NUM_PINS; i++) { ret = gpio_pin_write(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; }; } |