blob: 0c86af964a8041f4dd9428fe100f563ad31fc8de [file] [log] [blame] [view]
Hugo McNallyf6298b32023-02-12 14:47:22 +00001# GPIO HWIP Technical Specification
lowRISC Contributors802543a2019-08-31 12:12:56 +01002
Garret Kelly9eebde02019-10-22 15:36:49 -04003# Overview
lowRISC Contributors802543a2019-08-31 12:12:56 +01004
5This document specifies GPIO hardware IP functionality. This
6module conforms to the [Comportable guideline for peripheral device
Hugo McNallyaef0a662023-02-11 19:44:55 +00007functionality](../../../doc/contributing/hw/comportability/README.md)
lowRISC Contributors802543a2019-08-31 12:12:56 +01008See that document for integration overview within the broader top
9level system.
10
Garret Kelly9eebde02019-10-22 15:36:49 -040011## Features
lowRISC Contributors802543a2019-08-31 12:12:56 +010012
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 Kelly9eebde02019-10-22 15:36:49 -040018## Description
lowRISC Contributors802543a2019-08-31 12:12:56 +010019
20The GPIO block allows software to communicate through general purpose I/O
21pins in a flexible manner. Each of 32 independent bits can be written
22as peripheral outputs in two modes. Each of the 32 bits can be read
23by software as peripheral inputs. How these peripheral inputs and
24outputs are connected to the chip IO is not within the scope of this
Tom Robertsddc4ed32019-10-17 16:39:30 +010025document. See the Comportability Specification for peripheral IO options
lowRISC Contributors802543a2019-08-31 12:12:56 +010026at the top chip level.
27
28In the output direction, this module provides direct 32b access to each
29GPIO value using direct write. This mode allows software to control all
30GPIO bits simultaneously. Alternately, this module provides masked writes
31to half of the bits at a time, allowing software to affect the output
32value of a subset of the bits without requiring a read-modify-write.
33In this mode the user provides a mask of which of the 16 bits are to be
34modified, along with their new value. The details of this mode are given
Timothy Chen661d9d12019-11-01 14:45:30 -070035in the [Programmers Guide](#programmers-guide) below.
lowRISC Contributors802543a2019-08-31 12:12:56 +010036
37In the input direction, software can read the contents of any of the GPIO
38peripheral inputs. In addition, software can request the detection of an
Timothy Chen661d9d12019-11-01 14:45:30 -070039interrupt event for any of the 32 bits in a configurable manner. The choices
40are positive edge, negative edge or level detection events. A noise
lowRISC Contributors802543a2019-08-31 12:12:56 +010041filter is available through configuration for any of the 32 GPIO inputs.
Timothy Chen661d9d12019-11-01 14:45:30 -070042This requires the input to be stable for 16 cycles of the
lowRISC Contributors802543a2019-08-31 12:12:56 +010043module clock before the input register reflects the change and interrupt
44generation is evaluated. Note that if the filter is enabled and the pin
45is set to output then there will be a corresponding delay in a change
46in output value being reflected in the input register.
47
48See the Design Details section for more details on output, input, and
49interrupt control.
50
Garret Kelly9eebde02019-10-22 15:36:49 -040051# Theory of Operations
lowRISC Contributors802543a2019-08-31 12:12:56 +010052
Garret Kelly9eebde02019-10-22 15:36:49 -040053## Block Diagram
lowRISC Contributors802543a2019-08-31 12:12:56 +010054
Hugo McNallyaef0a662023-02-11 19:44:55 +000055![GPIO Block Diagram](./doc/gpio_blockdiagram.svg)
lowRISC Contributors802543a2019-08-31 12:12:56 +010056
57The block diagram above shows the `DATA_OUT` and `DATA_OE` registers
58managed by hardware outside of the auto-generated register file.
59For reference, it also shows the assumed connections to pads in
60the top level netlist.
61
Timothy Chen661d9d12019-11-01 14:45:30 -070062## Hardware Interfaces
63
Hugo McNallyba16bae2023-02-12 21:08:04 +000064* [Interface Tables](data/gpio.hjson#interfaces)
Timothy Chen661d9d12019-11-01 14:45:30 -070065
Garret Kelly9eebde02019-10-22 15:36:49 -040066## Design Details
lowRISC Contributors802543a2019-08-31 12:12:56 +010067
68### GPIO Output logic
69
Hugo McNallyaef0a662023-02-11 19:44:55 +000070![GPIO Output Diagram](./doc/gpio_output.svg)
lowRISC Contributors802543a2019-08-31 12:12:56 +010071
72The GPIO module maintains one 32-bit output register `DATA_OUT` with two
Hugo McNally6321c5e2023-02-16 21:39:55 +000073ways to write to it. Direct write access uses [`DIRECT_OUT`](data/gpio.hjson#direct_out), and
74masked 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 Chen661d9d12019-11-01 14:45:30 -070076access for all 32 bits in one register.
lowRISC Contributors802543a2019-08-31 12:12:56 +010077
78For masked access the bits to modify are given as a mask in the upper
Hugo McNally6321c5e2023-02-16 21:39:55 +00007916 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 Chen661d9d12019-11-01 14:45:30 -070081provided 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
83requiring a Read-Modify-Write.
lowRISC Contributors802543a2019-08-31 12:12:56 +010084
85Reads of masked registers return the lower/upper 16 bits of the `DATA_OUT`
86contents. Zeros are returned in the upper 16 bits (mask field). To read
Hugo McNally6321c5e2023-02-16 21:39:55 +000087what is on the pins, software should read the [`DATA_IN`](data/gpio.hjson#data_in) register.
Timothy Chen661d9d12019-11-01 14:45:30 -070088(See [GPIO Input](#gpio-input) section below).
lowRISC Contributors802543a2019-08-31 12:12:56 +010089
90The same concept is duplicated for the output enable register `DATA_OE`.
Hugo McNally6321c5e2023-02-16 21:39:55 +000091Direct access uses [`DIRECT_OE`](data/gpio.hjson#direct_oe), and masked access is available
92using [`MASKED_OE_UPPER`](data/gpio.hjson#masked_oe_upper) and [`MASKED_OE_LOWER`](data/gpio.hjson#masked_oe_lower).
lowRISC Contributors802543a2019-08-31 12:12:56 +010093
94The output enable is sent to the pad control block to determine if the
95pad should drive the `DATA_OUT` value to the associated pin or not.
96
97A typical use pattern is for initialization and suspend/resume code to
98use the full access registers to set the output enables and current output
99values, then switch to masked access for both `DATA_OUT` and `DATA_OE`.
100
101For GPIO outputs that are not used (either not wired to a pin output or
102not selected for pin multiplexing), the output values are disconnected
Tom Robertsddc4ed32019-10-17 16:39:30 +0100103and have no effect on the GPIO input, regardless of output enable values.
lowRISC Contributors802543a2019-08-31 12:12:56 +0100104
105### GPIO Input
106
Hugo McNally6321c5e2023-02-16 21:39:55 +0000107The [`DATA_IN`](data/gpio.hjson#data_in) register returns the contents as seen on the
Timothy Chen661d9d12019-11-01 14:45:30 -0700108peripheral input, typically from the pads connected to those inputs. In the
lowRISC Contributors802543a2019-08-31 12:12:56 +0100109presence of a pin-multiplexing unit, GPIO peripheral inputs that are
110not connected to a chip input will be tied to a constant zero input.
111
112The GPIO module provides optional independent noise filter control for
113each of the 32 input signals. Each input can be independently enabled with
Hugo McNally6321c5e2023-02-16 21:39:55 +0000114the [`CTRL_EN_INPUT_FILTER`](data/gpio.hjson#ctrl_en_input_filter) (one bit per input). This 16-cycle
115filter is applied to both the [`DATA_IN`](data/gpio.hjson#data_in) register and
116the interrupt detection logic. The timing for [`DATA_IN`](data/gpio.hjson#data_in) is still
117not instantaneous if [`CTRL_EN_INPUT_FILTER`](data/gpio.hjson#ctrl_en_input_filter) is false as there is
Timothy Chen661d9d12019-11-01 14:45:30 -0700118top-level routing involved, but no flops are between the chip input and the
Hugo McNally6321c5e2023-02-16 21:39:55 +0000119[`DATA_IN`](data/gpio.hjson#data_in) register.
lowRISC Contributors802543a2019-08-31 12:12:56 +0100120
Hugo McNally6321c5e2023-02-16 21:39:55 +0000121The contents of [`DATA_IN`](data/gpio.hjson#data_in) are always readable and reflect the
Timothy Chen661d9d12019-11-01 14:45:30 -0700122value seen at the chip input pad regardless of the output enable setting from
lowRISC Contributors802543a2019-08-31 12:12:56 +0100123DATA_OE. If the output enable is true (and the GPIO is connected to a
Hugo McNally6321c5e2023-02-16 21:39:55 +0000124chip-level pad), the value read from [`DATA_IN`](data/gpio.hjson#data_in) includes the
Timothy Chen661d9d12019-11-01 14:45:30 -0700125effect of the peripheral's driven output (so will only differ from DATA_OUT if
126the output driver is unable to switch the pin or during the delay imposed
lowRISC Contributors802543a2019-08-31 12:12:56 +0100127if the noise filter is enabled).
128
129### Interrupts
130
131The GPIO module provides 32 interrupt signals to the main processor.
132Each interrupt can be independently enabled, tested, and configured.
133Following the standard interrupt guidelines in the [Comportability
Hugo McNallyaef0a662023-02-11 19:44:55 +0000134Specification](../../../doc/contributing/hw/comportability/README.md),
Hugo McNally6321c5e2023-02-16 21:39:55 +0000135the 32 bits of the [`INTR_ENABLE`](data/gpio.hjson#intr_enable) register determines whether the
lowRISC Contributors802543a2019-08-31 12:12:56 +0100136associated inputs are configured to detect interrupt events. If enabled
137via the various `INTR_CTRL_EN` registers, their current state can be
Hugo McNally6321c5e2023-02-16 21:39:55 +0000138read 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 Contributors802543a2019-08-31 12:12:56 +0100140
141For configuration, there are 4 types of interrupts available per bit,
Hugo McNally6321c5e2023-02-16 21:39:55 +0000142controlled with four control registers. [`INTR_CTRL_EN_RISING`](data/gpio.hjson#intr_ctrl_en_rising)
Timothy Chen661d9d12019-11-01 14:45:30 -0700143configures the associated input for rising-edge detection.
Hugo McNally6321c5e2023-02-16 21:39:55 +0000144Similarly, [`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 Chen661d9d12019-11-01 14:45:30 -0700146allow the input to be level sensitive interrupts. In theory an input can be
147configured to detect both a rising and falling edge, but there is no hardware
148assistance to indicate which edge caused the output interrupt.
lowRISC Contributors802543a2019-08-31 12:12:56 +0100149
150**Note #1:** all inputs are sent through optional noise filtering before
151being sent into interrupt detection. **Note #2:** all output interrupts to
152the processor are level interrupts as per the Comportability Specification
153guidelines. The GPIO module, if configured, converts an edge detection
154into a level interrupt to the processor core.
155
Garret Kelly9eebde02019-10-22 15:36:49 -0400156# Programmers Guide
lowRISC Contributors802543a2019-08-31 12:12:56 +0100157
Garret Kelly9eebde02019-10-22 15:36:49 -0400158## Initialization
lowRISC Contributors802543a2019-08-31 12:12:56 +0100159
160Initialization of the GPIO module includes the setting up of the interrupt
161configuration for each GPIO input, as well as the configuration of
162the required noise filtering. These do not provide masked access since
163they 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 Kelly9eebde02019-10-22 15:36:49 -0400178## Common Examples
lowRISC Contributors802543a2019-08-31 12:12:56 +0100179
180This section below shows the interaction between the direct access
181and 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.
186printf("0x%x", *GPIO_DATA_IN); // 0xffffffff
187
188*DIRECT_OUT = 0x11223344;
189printf("0x%x", *GPIO_DIRECT_OUT); // 0x11223344
190
191*DIRECT_OE = 0x00ff00ff;
192printf("0x%x", *GPIO_DIRECT_OE); // 0x00ff00ff
193
194// weak pullup still applies to undriven signals
195printf("0x%x", *GPIO_DATA_IN); // 0xff22ff44
196
197// read of direct_out still returns DATA_OUT contents
198printf("0x%x", *GPIO_DIRECT_OUT); // 0x11223344
199
200// try masked accesses to DATA_OUT
201*GPIO_MASKED_OUT_LOWER = 0x0f0f5566
202printf("0x%x", *GPIO_MASKED_OUT_LOWER); // 0x00003546
203printf("0x%x", *GPIO_DIRECT_OUT); // 0x11223546
204
205*GPIO_MASKED_OUT_UPPER = 0x0f0f7788
206printf("0x%x", *GPIO_MASKED_OUT_UPPER); // 0x00001728
207printf("0x%x", *GPIO_DIRECT_OUT); // 0x17283546
208
209// OE still applies
210printf("0x%x", *GPIO_DATA_IN); // 0xff28ff46
211
212// manipulate OE
213*GPIO_DIRECT_OE = 0xff00ff00;
214printf("0x%x", *GPIO_DIRECT_OE); // 0xff00ff00
215printf("0x%x", *GPIO_DATA_IN); // 0x17ff35ff
216
217*GPIO_MASKED_OE_LOWER = 0x0f0f0f0f;
218printf("0x%x", *GPIO_MASKED_OE_LOWER); // 0x00000f0f
219printf("0x%x", *GPIO_DIRECT_OE); // 0xff000f0f
220printf("0x%x", *GPIO_DATA_IN); // 0x17fff5f6
221
222*GPIO_MASKED_OE_UPPER = 0x0f0f0f0f;
223printf("0x%x", *GPIO_MASKED_OE_UPPER); // 0x00000f0f
224printf("0x%x", *GPIO_DIRECT_OE); // 0x0f0f0f0f
225printf("0x%x", *GPIO_DATA_IN); // 0xf7f8f5f6
226```
227
Garret Kelly9eebde02019-10-22 15:36:49 -0400228## Interrupt Handling
lowRISC Contributors802543a2019-08-31 12:12:56 +0100229
230This section below gives an example of how interrupt clearing works,
231assuming some events have occurred as shown in comments.
232
233```cpp
234*INTR_ENABLE = 0x000000ff; // interrupts enabled GPIO[7:0] inputs
235printf("0b%x", *GPIO_DATA_IN); // assume 0b00000000
236printf("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)
244printf("0b%b", *GPIO_INTR_STATE); // 0b00001100
245
246// try and clear [3:2], fails since still active low
247*GPIO_INTR_STATE = 0b00001100;
248printf("0b%b", *GPIO_INTR_STATE); // 0b00001100
249
250// EVENT: all bits [7:0] rising, triggers [7,6,4,0], [3,2] still latched
251printf("0b%b", *GPIO_DATA_IN); // 0b11111111
252printf("0b%b", *GPIO_INTR_STATE); // 0b11011101
253
254// try and clear all bits, [7,6] still detecting level high
255*GPIO_INTR_STATE = 0b11111111;
256printf("0b%b", *GPIO_INTR_STATE); // 0b11000000
257
258// EVENT: all bits [7:0] falling, triggers [4,3,2,1], [7,6] still latched
259printf("0b%b", *GPIO_DATA_IN); // 0b00000000
260printf("0b%b", *GPIO_INTR_STATE); // 0b11011110
261
262// try and clear all bits, [3,2] still detecting level low
263*GPIO_INTR_STATE = 0b11111111;
264printf("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;
268printf("0b%b", *GPIO_INTR_STATE); // 0b11111111
269
270// try and clear all bits, [3,2] still detecting level low
271*GPIO_INTR_STATE = 0b11111111;
272printf("0b%b", *GPIO_INTR_STATE); // 0b00001100
273
274```
275
Sam Elliottb6745d32020-04-08 21:46:28 +0100276## Device Interface Functions (DIFs)
277
Hugo McNallyac9f9b52023-02-14 12:15:34 +0000278- [Device Interface Functions](../../../sw/device/lib/dif/dif_gpio.h)
Sam Elliottb6745d32020-04-08 21:46:28 +0100279
Garret Kelly9eebde02019-10-22 15:36:49 -0400280## Register Table
lowRISC Contributors802543a2019-08-31 12:12:56 +0100281
Hugo McNallyba16bae2023-02-12 21:08:04 +0000282* [Register Table](data/gpio.hjson#registers)