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: prefix = "stm32l432_gpio_" ]] 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 */ 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. */ input = 0b0, /** The GPIO pin is used for general output. */ general_output = 0b1, /** * The GPIO pin is used for whatever the altername function * is defined as (refer to manual). */ alternate_function = 0b10, /** * The GPIO pin is set to analog. */ analog = 0b11, } [16]; }; /** * The output type. */ assert_pos(0x04); [[ noexport ]] reg ocfg_r(32) : struct { otype_r : enum(1) { /** * The GPIO pin is capable of sinking to ground (for LOW) or providing * power (for HIGH). */ push_pull = 0, /** * The GPIO pin is only able to sink current (for LOW), or nothing (for * HIGH). */ open_drain = 1, }[16]; reserved(16); // Have to pad out the remaining 16 bits. }; /** * Sets the speed of the provided GPIO pin. */ assert_pos(0x08); [[ noexport ]] reg (32) : struct { ospeed_r : enum(2) { low = 0, medium = 1, high = 2, very_high = 3, } [16]; }; /** * Pullup/Pulldown type */ assert_pos(0x0c); [[ noexport ]] wo reg (32) : struct { union { pupd_r : enum(2) { none = 0b0, // Compiles to Gpio::PupdR::PullUp pull_up = 0b1, // Compiles to Gpio::PupdR::PullDown pull_down = 0b10, // Not used, but has to be included to fill out the enum. reserved = 0b11, } [16]; struct { alternate : enum(1) { enabled = 0, disabled = 1, } [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(1); }; }; 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) { unlocked = 0, locked = 1, } [16]; 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 { wo br_r : (16); reserved (16); }; /** * Analog switch control for the pin. */ reg(32) : struct { asc_r : (16); [[ export_as = "ascr_upper" ]] reserved (16); }; }; 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; };