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" ]] 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; };