Skip to content

Commit ae06ebb

Browse files
committed
RFC #49: address some feedback from the 2024-04-01 Amaranth meeting.
- Add support for an ALTERNATE mode. - Use interleaved set/clear bits in the SetClr register. - Remove upper bound on the input_stage parameter. - Add hints towards a policy for backward-compatible peripheral extensions.
1 parent 318ef2a commit ae06ebb

File tree

4 files changed

+44
-25
lines changed

4 files changed

+44
-25
lines changed

text/0049-soc-gpio-peripheral.md

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,33 @@ Each `Mode.pin_x` field can hold the following values:
7676
```python3
7777
class Mode(enum.Enum, shape=unsigned(2)):
7878
INPUT_ONLY = 0b00
79-
PUSH_PULL = 0b10
80-
OPEN_DRAIN = 0b01
79+
PUSH_PULL = 0b01
80+
OPEN_DRAIN = 0b10
81+
ALTERNATE = 0b11
8182
```
8283

83-
- If `Mode.pin_x` is `INPUT_ONLY`, then `pins[x].oe = 0`.
84-
- If `Mode.pin_x` is `PUSH_PULL`, then `pins[x].oe = 1` and `pins[x].o = Output.pin_x`.
85-
- If `Mode.pin_x` is `OPEN_DRAIN`, then `pins[x].oe = ~Output.pin_x` and `pins[x].o = 0`.
84+
Each `Mode.pin_x` field resets to `INPUT_ONLY`.
85+
86+
If `Mode.pin_x` is `INPUT_ONLY`:
87+
- `pins[x].alt_mode` returns 0.
88+
- `Input.pin_x` returns the last value of `pins[x].i` sampled on a clock cycle.
89+
- `pins[x].oe` returns 0 `pins[x].o` return 0.
90+
91+
If `Mode.pin_x` is `PUSH_PULL`:
92+
- `pins[x].alt_mode` returns 0.
93+
- `Input.pin_x` returns the last value of `pins[x].i` sampled on a clock cycle.
94+
- `pins[x].oe` returns 1 and `pins[x].o` returns `Output.pin_x`.
95+
96+
If `Mode.pin_x` is `OPEN_DRAIN`:
97+
- `pins[x].alt_mode` returns 0.
98+
- `Input.pin_x` returns the last value of `pins[x].i` sampled on a clock cycle.
99+
- `pins[x].oe` returns `~Output.pin_x` and `pins[x].o` returns 0.
100+
101+
If `Mode.pin_x` is `ALTERNATE`:
102+
- `pins[x].alt_mode` returns 1.
103+
- `Input.pin_x`, `pins[x].oe` and `pins[x].o` return implementation-specific values.
104+
105+
If `ALTERNATE` mode is unimplemented, its behavior should be equivalent to `INPUT_ONLY` mode.
86106

87107
#### Input (read-only)
88108

@@ -92,10 +112,7 @@ class Mode(enum.Enum, shape=unsigned(2)):
92112
{name: 'pin_1', bits: 1, attr: 'R'},
93113
{name: 'pin_2', bits: 1, attr: 'R'},
94114
{name: 'pin_3', bits: 1, attr: 'R'},
95-
{bits: 4, attr: 'ResR0W0'},
96-
], {bits: 8})">
97-
98-
Each `Input.pin_x` field holds the last value of `pins[x].i` sampled on a clock cycle.
115+
], {bits: 4})">
99116

100117
#### Output (read/write)
101118

@@ -105,26 +122,23 @@ Each `Input.pin_x` field holds the last value of `pins[x].i` sampled on a clock
105122
{name: 'pin_1', bits: 1, attr: 'RW'},
106123
{name: 'pin_2', bits: 1, attr: 'RW'},
107124
{name: 'pin_3', bits: 1, attr: 'RW'},
108-
{bits: 4, attr: 'ResR0W0'},
109-
], {bits: 8})">
125+
], {bits: 4})">
110126

111-
Each `Output.pin_x` field holds the next value of `pins[x].o` in `PUSH_PULL` mode.
127+
Each `Output.pin_x` field resets to 0.
112128

113129
#### SetClr (write-only)
114130

115131
<img src="./0049-soc-gpio-peripheral/reg-setclr.svg"
116132
alt="bf([
117133
{name: 'set_0', bits: 1, attr: 'W'},
118-
{name: 'set_1', bits: 1, attr: 'W'},
119-
{name: 'set_2', bits: 1, attr: 'W'},
120-
{name: 'set_3', bits: 1, attr: 'W'},
121-
{bits: 4, attr: 'ResR0W0'},
122134
{name: 'clr_0', bits: 1, attr: 'W'},
135+
{name: 'set_1', bits: 1, attr: 'W'},
123136
{name: 'clr_1', bits: 1, attr: 'W'},
137+
{name: 'set_2', bits: 1, attr: 'W'},
124138
{name: 'clr_2', bits: 1, attr: 'W'},
139+
{name: 'set_3', bits: 1, attr: 'W'},
125140
{name: 'clr_3', bits: 1, attr: 'W'},
126-
{bits: 4, attr: 'ResR0W0'},
127-
], {bits: 8, lanes: 2})">
141+
], {bits: 8})">
128142

129143
- Writing `1` to an `SetClr.set_x` field sets `Output.pin_x`.
130144
- Writing `1` to an `SetClr.clr_x` field clears `Output.pin_x`.
@@ -140,8 +154,9 @@ The members of a `gpio.PinSignature` are defined as follows:
140154

141155
```python3
142156
{
143-
"i": In(unsigned(1)),
144-
"o": Out(unsigned(1)),
157+
"alt_mode": Out(unsigned(1)),
158+
"i": In(unsigned(1)),
159+
"o": Out(unsigned(1)),
145160
"oe": Out(unsigned(1)),
146161
}
147162
```
@@ -151,7 +166,7 @@ The members of a `gpio.PinSignature` are defined as follows:
151166
The `gpio.Peripheral` class is a `wiring.Component` implementing a GPIO controller, with:
152167
- a `.__init__(self, *, pin_count, addr_width, data_width, name=None, input_stages=2)` constructor, where:
153168
* `pin_count` is a non-negative integer.
154-
* `input_stages` is `0`, `1` or `2`.
169+
* `input_stages` is a non-negative integer.
155170
* `addr_width`, `data_width` and `name` are passed to a `csr.Builder`
156171
- a `.signature` property, that returns a `wiring.Signature` with the following members:
157172

@@ -188,7 +203,11 @@ While they can be found in most microcontollers, the design of GPIOs in STM32 ha
188203
## Unresolved questions
189204
[unresolved-questions]: #unresolved-questions
190205

191-
- ~~Should we support synchronizing a pin input on falling edges of the clock ?~~ Users can synchronize pin inputs on falling edges by instantiating a `gpio.Peripheral` with `input_stages=0`, and providing their own synchronization mechanism.
206+
- ~~Should we support synchronizing a pin input on falling edges of the clock ?~~ (@whitequark) Users can synchronize pin inputs on falling edges by instantiating a `gpio.Peripheral` with `input_stages=0`, and providing their own synchronization mechanism.
207+
208+
- What is our policy for backward-compatible extensions of the peripheral ? (@whitequark) If or when we add registers for new optional features, such as pull-ups, switchable schmitt triggers, switchable output driver strengths, etc, each register will always reside at the same fixed (for a given pin count) address regardless of which features are enabled, and each of these registers will be all-0s after reset, where such all-0s value will provide behavior identical to the behavior of the peripheral without the optional feature. Slots in the address space will never be reallocated with a different meaning once allocated upstream in Amaranth SoC.
209+
* This will be important to industry users caring about forward and cross-family/cross-configuration compatibility.
210+
* In a perfect world this would be our policy for every peripheral. Realistically, we'll only be able to provide this strongest guarantee for only a subset of peripherals.
192211

193212
## Future possibilities
194213
[future-possibilities]: #future-possibilities
Lines changed: 1 addition & 1 deletion
Loading
Lines changed: 1 addition & 1 deletion
Loading
Lines changed: 1 addition & 1 deletion
Loading

0 commit comments

Comments
 (0)