summaryrefslogtreecommitdiff
path: root/goal.fiddle
blob: ed90ad3e58506a65ac2440b65ff2a2e98daaf12e (plain) (blame)
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
option board stm32l432;
option endian little;
option processor arm_cortex_m4;
option align 32;

import "./types.fdl";

[[ cpp: namespace = "stm32l432::gpio" ]]
[[ rust: package = "Stm32l432.Gpio" ]]
[[ zig: package = "stm32l432.gpio" ]]
[[ c: unqualified ]]
package stm32l4.gpio {
  location gpio_a_base = 0x4800_0000;
  location gpio_b_base = 0x4800_0400;
  location gpio_c_base = 0x4800_0800;

  using stm32l432;

  /**
   * Structure of the GPIO port on an stm32l432
   */
  [[ c: unqualified ]]
  type gpio_t : struct {
    assert_pos(0);

    reg (32) : struct {
      /** The mode for each pin. */
      mode_r : enum(2) {
        /** The GPIO pin is used for input. */
        [[ c: unqualified ]]
        input = 0b0,

        /** The GPIO pin is used for general output. */
        [[ c: unqualified ]]
        general_output = 0b1,

        /**
         * The GPIO pin is used for whatever the altername function
         * is defined as (refer to manual).
         */
        [[ c: unqualified ]]
        alternate_function = 0b10,

        /**
         * The GPIO pin is set to analog.
         */
        [[ c: unqualified ]]
        analog = 0b11,
      } [16];
    };

    assert_pos(0x04);
    /** 
     * The output type.
     */
    [[ noexport ]]
    reg(32) : struct {
      otype_r : enum(1) {
        /**
         * The GPIO pin is capable of sinking to ground (for LOW) or providing
         * power (for HIGH).
         */
        [[ c: unqualified ]]
        push_pull = 0,

        /**
         * The GPIO pin is only able to sink current (for LOW), or nothing (for
         * HIGH).
         */
        [[ c: unqualified ]]
        open_drain = 1,
      }[16];

      reserved(16); // Have to pad out the remaining 16 bits.
    };

    assert_pos(0x08);
    /**
     * Sets the speed of the provided GPIO pin.
     */
    [[ noexport ]]
    reg (32) : struct {
      ospeed_r : enum(2) {
        [[ c: unqualified ]]
        speed_low = 0,

        [[ c: unqualified ]]
        speed_medium = 1,

        [[ c: unqualified ]]
        speed_high = 2,

        [[ c: unqualified ]]
        speed_very_high = 3,
      } [16];
    };

    /**
     * Pullup/Pulldown type
     */
    assert_pos(0x0c);
    [[ noexport ]]
    wo reg (32) : struct {
      union {

        /** Configures a pin as pull-up or push-down. */
        [[ c: no_qualify ]]
        pupd_r : enum(2) {
          none = 0b0,
          // Compiles to Gpio::PupdR::PullUp
          [[ c: unqualified ]]
          pull_up = 0b1,
          // Compiles to Gpio::PupdR::PullDown
          [[ c: unqualified ]]
          pull_down = 0b10,
          // Not used, but has to be included to fill out the enum.
          reserved = 0b11,
        } [16];

        struct {
          alternate : common.enabled_t[16];
          reserved(16);
        };
      };
    };

    /**
     * Input data register.
     * 
     * Reading form the provided pin will yield high if the pin is on, or low if
     * the pin is low.
     */
    union {
      assert_pos(0x10);
      ro reg (32) : struct {
        id_r : common.bit_t[16];

        reserved(16);
      };

      // Additinoal values .
      assert_pos(0x10);
      struct {
        assert_pos(0x10);
        wo reg alt_r1(16);

        assert_pos(0x12);
        wo reg alt_r2(8);
        reserved(8);
      };
    };
    assert_pos(0x14);


    /**
     * Output data register.
     *
     * Writing to this register sets the appropriate register to low/high.
     */
    assert_pos(0x14);
    wo reg (32) : struct {
      union {
        rw od_r : common.bit_t[16];

        struct {
          rw osp_v : (15);
          // Without the reserved bit, the compiler will complain about jagged
          // unions. 
          reserved(1);
        };
      };

      reserved(16);
    };

    /**
     * The GPIO port bit set/reset register.
     */
    assert_pos(0x18);
    reg bsr_r(32) : struct {
      /**
       * Sets the pins associated with the bits. Like od_r, but can be used to
       * turn on multiple pins at once.
       */
      wo set : (16);

      /**
       * Resets the pins written to this register.
       */
      wo reset : (16);
    };

    assert_pos(0x1c);
    reg(32) : struct {
      lock : enum(1) {
        [[ c: unqualified ]]
        unlocked = 0,

        [[ c: unqualified ]]
        locked = 1,
      } [16];

      /**
       * Port Configuration Lock Register.
       *
       * This allows GPIO configuartions to lock in their configuration until
       * a system reset.
       *
       * Writes the gpio pins to lock to the 'lock' register. Then write a '1'
       * to this bit, followed by a '0', followed by another '1' to lock the
       * configuration.
       */
      lockk : (1);

      reserved(15);
    };

    /**
     * Alternate function registers (both low/high).
     * Each nybble refers to a pin.
     */
    assert_pos(0x20);
    reg(64) : struct {
      afn : (4)[16];
    };

    /**
     * The bit reset register.
     */
    assert_pos(0x28);
    reg(32) : struct {
      union {
        /**
         * Reset bitfield for the GPIO bus. Write a 1 bit to the GPIO pin's bit
         * to reset that GPIO pin.
         */
        wo br_r : (16);

        /**
         * Like br_r, but allows array-like indexing.
         */
        wo br_r_a : common.bit_t[16];
      };
      reserved (16);
    };

    /**
     * Analog switch control for the pin.
     */
    reg(32) : struct {
      asc_r : (16);

      [[ export_as = "ascr_upper" ]]
      union {
        reserved (16);
        struct {
          reserved (8);
          wo upper_8 : (8);
        };
      };
    };
  };

  instance gpio_a at gpio_a_base : gpio_t;
  instance gpio_b at gpio_b_base : gpio_t;
  instance gpio_c at gpio_c_base : gpio_t;
};