Hugo McNally | f6298b3 | 2023-02-12 14:47:22 +0000 | [diff] [blame] | 1 | # GPIO HWIP Technical Specification |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 2 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 3 | # Overview |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 4 | |
| 5 | This document specifies GPIO hardware IP functionality. This |
| 6 | module conforms to the [Comportable guideline for peripheral device |
Hugo McNally | aef0a66 | 2023-02-11 19:44:55 +0000 | [diff] [blame] | 7 | functionality](../../../doc/contributing/hw/comportability/README.md) |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 8 | See that document for integration overview within the broader top |
| 9 | level system. |
| 10 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 11 | ## Features |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 12 | |
| 13 | - 32 GPIO ports |
| 14 | - Configurable interrupt per GPIO for detecting rising edge, falling edge, |
| 15 | or active low/high input |
| 16 | - Two ways to update GPIO output: direct-write and masked (thread-safe) update |
| 17 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 18 | ## Description |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 19 | |
| 20 | The GPIO block allows software to communicate through general purpose I/O |
| 21 | pins in a flexible manner. Each of 32 independent bits can be written |
| 22 | as peripheral outputs in two modes. Each of the 32 bits can be read |
| 23 | by software as peripheral inputs. How these peripheral inputs and |
| 24 | outputs are connected to the chip IO is not within the scope of this |
Tom Roberts | ddc4ed3 | 2019-10-17 16:39:30 +0100 | [diff] [blame] | 25 | document. See the Comportability Specification for peripheral IO options |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 26 | at the top chip level. |
| 27 | |
| 28 | In the output direction, this module provides direct 32b access to each |
| 29 | GPIO value using direct write. This mode allows software to control all |
| 30 | GPIO bits simultaneously. Alternately, this module provides masked writes |
| 31 | to half of the bits at a time, allowing software to affect the output |
| 32 | value of a subset of the bits without requiring a read-modify-write. |
| 33 | In this mode the user provides a mask of which of the 16 bits are to be |
| 34 | modified, along with their new value. The details of this mode are given |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 35 | in the [Programmers Guide](#programmers-guide) below. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 36 | |
| 37 | In the input direction, software can read the contents of any of the GPIO |
| 38 | peripheral inputs. In addition, software can request the detection of an |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 39 | interrupt event for any of the 32 bits in a configurable manner. The choices |
| 40 | are positive edge, negative edge or level detection events. A noise |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 41 | filter is available through configuration for any of the 32 GPIO inputs. |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 42 | This requires the input to be stable for 16 cycles of the |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 43 | module clock before the input register reflects the change and interrupt |
| 44 | generation is evaluated. Note that if the filter is enabled and the pin |
| 45 | is set to output then there will be a corresponding delay in a change |
| 46 | in output value being reflected in the input register. |
| 47 | |
| 48 | See the Design Details section for more details on output, input, and |
| 49 | interrupt control. |
| 50 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 51 | # Theory of Operations |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 52 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 53 | ## Block Diagram |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 54 | |
Hugo McNally | aef0a66 | 2023-02-11 19:44:55 +0000 | [diff] [blame] | 55 | ![GPIO Block Diagram](./doc/gpio_blockdiagram.svg) |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 56 | |
| 57 | The block diagram above shows the `DATA_OUT` and `DATA_OE` registers |
| 58 | managed by hardware outside of the auto-generated register file. |
| 59 | For reference, it also shows the assumed connections to pads in |
| 60 | the top level netlist. |
| 61 | |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 62 | ## Hardware Interfaces |
| 63 | |
Hugo McNally | ba16bae | 2023-02-12 21:08:04 +0000 | [diff] [blame] | 64 | * [Interface Tables](data/gpio.hjson#interfaces) |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 65 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 66 | ## Design Details |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 67 | |
| 68 | ### GPIO Output logic |
| 69 | |
Hugo McNally | aef0a66 | 2023-02-11 19:44:55 +0000 | [diff] [blame] | 70 | ![GPIO Output Diagram](./doc/gpio_output.svg) |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 71 | |
| 72 | The GPIO module maintains one 32-bit output register `DATA_OUT` with two |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 73 | ways to write to it. Direct write access uses [`DIRECT_OUT`](data/gpio.hjson#direct_out), and |
| 74 | masked access uses [`MASKED_OUT_UPPER`](data/gpio.hjson#masked_out_upper) and |
| 75 | [`MASKED_OUT_LOWER`](data/gpio.hjson#masked_out_lower). Direct access provides full write and read |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 76 | access for all 32 bits in one register. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 77 | |
| 78 | For masked access the bits to modify are given as a mask in the upper |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 79 | 16 bits of the [`MASKED_OUT_UPPER`](data/gpio.hjson#masked_out_upper) and |
| 80 | [`MASKED_OUT_LOWER`](data/gpio.hjson#masked_out_lower) register write, while the data to write is |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 81 | provided in the lower 16 bits of the register write. The hardware updates |
| 82 | `DATA_OUT` with the mask so that the modification is done without software |
| 83 | requiring a Read-Modify-Write. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 84 | |
| 85 | Reads of masked registers return the lower/upper 16 bits of the `DATA_OUT` |
| 86 | contents. Zeros are returned in the upper 16 bits (mask field). To read |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 87 | what is on the pins, software should read the [`DATA_IN`](data/gpio.hjson#data_in) register. |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 88 | (See [GPIO Input](#gpio-input) section below). |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 89 | |
| 90 | The same concept is duplicated for the output enable register `DATA_OE`. |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 91 | Direct access uses [`DIRECT_OE`](data/gpio.hjson#direct_oe), and masked access is available |
| 92 | using [`MASKED_OE_UPPER`](data/gpio.hjson#masked_oe_upper) and [`MASKED_OE_LOWER`](data/gpio.hjson#masked_oe_lower). |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 93 | |
| 94 | The output enable is sent to the pad control block to determine if the |
| 95 | pad should drive the `DATA_OUT` value to the associated pin or not. |
| 96 | |
| 97 | A typical use pattern is for initialization and suspend/resume code to |
| 98 | use the full access registers to set the output enables and current output |
| 99 | values, then switch to masked access for both `DATA_OUT` and `DATA_OE`. |
| 100 | |
| 101 | For GPIO outputs that are not used (either not wired to a pin output or |
| 102 | not selected for pin multiplexing), the output values are disconnected |
Tom Roberts | ddc4ed3 | 2019-10-17 16:39:30 +0100 | [diff] [blame] | 103 | and have no effect on the GPIO input, regardless of output enable values. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 104 | |
| 105 | ### GPIO Input |
| 106 | |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 107 | The [`DATA_IN`](data/gpio.hjson#data_in) register returns the contents as seen on the |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 108 | peripheral input, typically from the pads connected to those inputs. In the |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 109 | presence of a pin-multiplexing unit, GPIO peripheral inputs that are |
| 110 | not connected to a chip input will be tied to a constant zero input. |
| 111 | |
| 112 | The GPIO module provides optional independent noise filter control for |
| 113 | each of the 32 input signals. Each input can be independently enabled with |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 114 | the [`CTRL_EN_INPUT_FILTER`](data/gpio.hjson#ctrl_en_input_filter) (one bit per input). This 16-cycle |
| 115 | filter is applied to both the [`DATA_IN`](data/gpio.hjson#data_in) register and |
| 116 | the interrupt detection logic. The timing for [`DATA_IN`](data/gpio.hjson#data_in) is still |
| 117 | not instantaneous if [`CTRL_EN_INPUT_FILTER`](data/gpio.hjson#ctrl_en_input_filter) is false as there is |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 118 | top-level routing involved, but no flops are between the chip input and the |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 119 | [`DATA_IN`](data/gpio.hjson#data_in) register. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 120 | |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 121 | The contents of [`DATA_IN`](data/gpio.hjson#data_in) are always readable and reflect the |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 122 | value seen at the chip input pad regardless of the output enable setting from |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 123 | DATA_OE. If the output enable is true (and the GPIO is connected to a |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 124 | chip-level pad), the value read from [`DATA_IN`](data/gpio.hjson#data_in) includes the |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 125 | effect of the peripheral's driven output (so will only differ from DATA_OUT if |
| 126 | the output driver is unable to switch the pin or during the delay imposed |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 127 | if the noise filter is enabled). |
| 128 | |
| 129 | ### Interrupts |
| 130 | |
| 131 | The GPIO module provides 32 interrupt signals to the main processor. |
| 132 | Each interrupt can be independently enabled, tested, and configured. |
| 133 | Following the standard interrupt guidelines in the [Comportability |
Hugo McNally | aef0a66 | 2023-02-11 19:44:55 +0000 | [diff] [blame] | 134 | Specification](../../../doc/contributing/hw/comportability/README.md), |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 135 | the 32 bits of the [`INTR_ENABLE`](data/gpio.hjson#intr_enable) register determines whether the |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 136 | associated inputs are configured to detect interrupt events. If enabled |
| 137 | via the various `INTR_CTRL_EN` registers, their current state can be |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 138 | read in the [`INTR_STATE`](data/gpio.hjson#intr_state) register. Clearing is done by writing a |
| 139 | `1` into the associated [`INTR_STATE`](data/gpio.hjson#intr_state) bit field. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 140 | |
| 141 | For configuration, there are 4 types of interrupts available per bit, |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 142 | controlled with four control registers. [`INTR_CTRL_EN_RISING`](data/gpio.hjson#intr_ctrl_en_rising) |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 143 | configures the associated input for rising-edge detection. |
Hugo McNally | 6321c5e | 2023-02-16 21:39:55 +0000 | [diff] [blame] | 144 | Similarly, [`INTR_CTRL_EN_FALLING`](data/gpio.hjson#intr_ctrl_en_falling) detects falling edge inputs. |
| 145 | [`INTR_CTRL_EN_LVLHIGH`](data/gpio.hjson#intr_ctrl_en_lvlhigh) and [`INTR_CTRL_EN_LVLLOW`](data/gpio.hjson#intr_ctrl_en_lvllow) |
Timothy Chen | 661d9d1 | 2019-11-01 14:45:30 -0700 | [diff] [blame] | 146 | allow the input to be level sensitive interrupts. In theory an input can be |
| 147 | configured to detect both a rising and falling edge, but there is no hardware |
| 148 | assistance to indicate which edge caused the output interrupt. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 149 | |
| 150 | **Note #1:** all inputs are sent through optional noise filtering before |
| 151 | being sent into interrupt detection. **Note #2:** all output interrupts to |
| 152 | the processor are level interrupts as per the Comportability Specification |
| 153 | guidelines. The GPIO module, if configured, converts an edge detection |
| 154 | into a level interrupt to the processor core. |
| 155 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 156 | # Programmers Guide |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 157 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 158 | ## Initialization |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 159 | |
| 160 | Initialization of the GPIO module includes the setting up of the interrupt |
| 161 | configuration for each GPIO input, as well as the configuration of |
| 162 | the required noise filtering. These do not provide masked access since |
| 163 | they are not expected to be done frequently. |
| 164 | |
| 165 | ```cpp |
| 166 | // enable inputs 0 and 1 for rising edge detection with filtering, |
| 167 | // inputs 2 and 3 for falling edge detection with filtering, |
| 168 | // input 4 for both rising edge detection (no filtering) |
| 169 | // and inputs 6 and 7 for active low interrupt detection |
| 170 | *GPIO_INTR_ENABLE = 0b11011111; |
| 171 | *GPIO_INTR_CTRL_EN_RISING = 0b00010011; |
| 172 | *GPIO_INTR_CTRL_EN_FALLING = 0b00011100; |
| 173 | *GPIO_INTR_CTRL_EN_LVLLOW = 0b11000000; |
| 174 | *GPIO_INTR_CTRL_EN_LVLHIGH = 0b00000000; |
| 175 | *GPIO_CTRL_EN_INPUT_FILTER = 0b00001111; |
| 176 | ``` |
| 177 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 178 | ## Common Examples |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 179 | |
| 180 | This section below shows the interaction between the direct access |
| 181 | and mask access for data output and data enable. |
| 182 | |
| 183 | ```cpp |
| 184 | // assume all GPIO are connected to chip pads. |
| 185 | // assume a weak pullup on all pads, returning 1 if undriven. |
| 186 | printf("0x%x", *GPIO_DATA_IN); // 0xffffffff |
| 187 | |
| 188 | *DIRECT_OUT = 0x11223344; |
| 189 | printf("0x%x", *GPIO_DIRECT_OUT); // 0x11223344 |
| 190 | |
| 191 | *DIRECT_OE = 0x00ff00ff; |
| 192 | printf("0x%x", *GPIO_DIRECT_OE); // 0x00ff00ff |
| 193 | |
| 194 | // weak pullup still applies to undriven signals |
| 195 | printf("0x%x", *GPIO_DATA_IN); // 0xff22ff44 |
| 196 | |
| 197 | // read of direct_out still returns DATA_OUT contents |
| 198 | printf("0x%x", *GPIO_DIRECT_OUT); // 0x11223344 |
| 199 | |
| 200 | // try masked accesses to DATA_OUT |
| 201 | *GPIO_MASKED_OUT_LOWER = 0x0f0f5566 |
| 202 | printf("0x%x", *GPIO_MASKED_OUT_LOWER); // 0x00003546 |
| 203 | printf("0x%x", *GPIO_DIRECT_OUT); // 0x11223546 |
| 204 | |
| 205 | *GPIO_MASKED_OUT_UPPER = 0x0f0f7788 |
| 206 | printf("0x%x", *GPIO_MASKED_OUT_UPPER); // 0x00001728 |
| 207 | printf("0x%x", *GPIO_DIRECT_OUT); // 0x17283546 |
| 208 | |
| 209 | // OE still applies |
| 210 | printf("0x%x", *GPIO_DATA_IN); // 0xff28ff46 |
| 211 | |
| 212 | // manipulate OE |
| 213 | *GPIO_DIRECT_OE = 0xff00ff00; |
| 214 | printf("0x%x", *GPIO_DIRECT_OE); // 0xff00ff00 |
| 215 | printf("0x%x", *GPIO_DATA_IN); // 0x17ff35ff |
| 216 | |
| 217 | *GPIO_MASKED_OE_LOWER = 0x0f0f0f0f; |
| 218 | printf("0x%x", *GPIO_MASKED_OE_LOWER); // 0x00000f0f |
| 219 | printf("0x%x", *GPIO_DIRECT_OE); // 0xff000f0f |
| 220 | printf("0x%x", *GPIO_DATA_IN); // 0x17fff5f6 |
| 221 | |
| 222 | *GPIO_MASKED_OE_UPPER = 0x0f0f0f0f; |
| 223 | printf("0x%x", *GPIO_MASKED_OE_UPPER); // 0x00000f0f |
| 224 | printf("0x%x", *GPIO_DIRECT_OE); // 0x0f0f0f0f |
| 225 | printf("0x%x", *GPIO_DATA_IN); // 0xf7f8f5f6 |
| 226 | ``` |
| 227 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 228 | ## Interrupt Handling |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 229 | |
| 230 | This section below gives an example of how interrupt clearing works, |
| 231 | assuming some events have occurred as shown in comments. |
| 232 | |
| 233 | ```cpp |
| 234 | *INTR_ENABLE = 0x000000ff; // interrupts enabled GPIO[7:0] inputs |
| 235 | printf("0b%x", *GPIO_DATA_IN); // assume 0b00000000 |
| 236 | printf("0b%x", *GPIO_INTR_STATE); // 0b00000000 |
| 237 | |
| 238 | *INTR_CTRL_EN_RISING = 0b00010001; // rising detect on GPIO[0], GPIO[4] |
| 239 | *INTR_CTRL_EN_FALLING = 0b00010010; // falling detect on GPIO[1], GPIO[4] |
| 240 | *INTR_CTRL_EN_LVLLOW = 0b00001100; // falling detect on GPIO[2], GPIO[3] |
| 241 | *INTR_CTRL_EN_LVLHIGH = 0b11000000; // falling detect on GPIO[6], GPIO[7] |
| 242 | |
| 243 | // already detected intr[3,2] (level low) |
| 244 | printf("0b%b", *GPIO_INTR_STATE); // 0b00001100 |
| 245 | |
| 246 | // try and clear [3:2], fails since still active low |
| 247 | *GPIO_INTR_STATE = 0b00001100; |
| 248 | printf("0b%b", *GPIO_INTR_STATE); // 0b00001100 |
| 249 | |
| 250 | // EVENT: all bits [7:0] rising, triggers [7,6,4,0], [3,2] still latched |
| 251 | printf("0b%b", *GPIO_DATA_IN); // 0b11111111 |
| 252 | printf("0b%b", *GPIO_INTR_STATE); // 0b11011101 |
| 253 | |
| 254 | // try and clear all bits, [7,6] still detecting level high |
| 255 | *GPIO_INTR_STATE = 0b11111111; |
| 256 | printf("0b%b", *GPIO_INTR_STATE); // 0b11000000 |
| 257 | |
| 258 | // EVENT: all bits [7:0] falling, triggers [4,3,2,1], [7,6] still latched |
| 259 | printf("0b%b", *GPIO_DATA_IN); // 0b00000000 |
| 260 | printf("0b%b", *GPIO_INTR_STATE); // 0b11011110 |
| 261 | |
| 262 | // try and clear all bits, [3,2] still detecting level low |
| 263 | *GPIO_INTR_STATE = 0b11111111; |
| 264 | printf("0b%b", *GPIO_INTR_STATE); // 0b00001100 |
| 265 | |
| 266 | // write test register for all 8 events, trigger regardless of external events |
| 267 | *GPIO_INTR_TEST = 0b11111111; |
| 268 | printf("0b%b", *GPIO_INTR_STATE); // 0b11111111 |
| 269 | |
| 270 | // try and clear all bits, [3,2] still detecting level low |
| 271 | *GPIO_INTR_STATE = 0b11111111; |
| 272 | printf("0b%b", *GPIO_INTR_STATE); // 0b00001100 |
| 273 | |
| 274 | ``` |
| 275 | |
Sam Elliott | b6745d3 | 2020-04-08 21:46:28 +0100 | [diff] [blame] | 276 | ## Device Interface Functions (DIFs) |
| 277 | |
Hugo McNally | ac9f9b5 | 2023-02-14 12:15:34 +0000 | [diff] [blame] | 278 | - [Device Interface Functions](../../../sw/device/lib/dif/dif_gpio.h) |
Sam Elliott | b6745d3 | 2020-04-08 21:46:28 +0100 | [diff] [blame] | 279 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 280 | ## Register Table |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 281 | |
Hugo McNally | ba16bae | 2023-02-12 21:08:04 +0000 | [diff] [blame] | 282 | * [Register Table](data/gpio.hjson#registers) |