本文へ移動
cccskills
無料GitHub で公開

gpio-baremetal

Use when configuring GPIO modes, alternate functions, pull resistors, or EXTI interrupts on STM32/nRF/ESP32-class MCUs. Not for register access rules: use mmio-and-bit-manipulation.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md5.7 KB
  • agents/openai.yaml187 B

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

GPIO on bare metal

Contract

FieldBound contract
TriggerA pin must be driven, read, muxed to a peripheral, or made to raise an interrupt on an edge, without a vendor HAL.
AuthorityRead-only: emits pin configuration sequences and interrupt setup to chat; the user places them in the firmware. Rollback is not needed because no file is written. No remote mutation.
Side effectChat output only.
DoneThe sequence enables the port clock, sets mode, pull, speed, and alternate function from the datasheet AF table, and for an interrupt pin routes the line, selects the edge, and enables the NVIC entry, with each register bit named after the reference manual.

Inputs

  • Target part and the pin (port and number) from the schematic.
  • Desired function: output, input, alternate function (which peripheral signal), or analog.
  • Electrical facts: active level of the LED or button, external pull-ups present, load on the pin.
  • For interrupts: edge (rising, falling, both) and the handler that will run.

Procedure

  1. Enable the port clock before touching any port register. A register write to an ungated port is silently dropped. Done when: the RCC enable bit for the port is set and read back.

    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    (void)RCC->AHB1ENR;
    
  2. Set the mode field for the pin. On STM32 MODER holds two bits per pin: 00 input, 01 output, 10 alternate function, 11 analog. Clear the field first, then set it. Done when: the MODER field for the pin reads the intended value.

    /* PA5 as push-pull output */
    GPIOA->MODER &= ~(3U << (5 * 2));
    GPIOA->MODER |=  (1U << (5 * 2));
    
  3. Drive outputs through the set/reset register, which changes one pin without a read-modify-write on ODR. On STM32 BSRR bits 0 to 15 set and bits 16 to 31 reset. Done when: the pin toggles and no other pin on the port changes.

    GPIOA->BSRR = (1U << 5);          /* set */
    GPIOA->BSRR = (1U << (5 + 16));   /* reset */
    
  4. For an alternate function, look up the AF number in the datasheet's alternate-function table for that exact pin, then write it into AFR[0] (pins 0 to 7) or AFR[1] (pins 8 to 15), four bits per pin. Set the speed field high enough for the signal rate. Done when: the AF number matches the datasheet row for the pin and the peripheral signal.

    /* PA2 as USART2_TX: AF7 on STM32F4 */
    GPIOA->MODER  &= ~(3U << (2 * 2));
    GPIOA->MODER  |=  (2U << (2 * 2));
    GPIOA->AFR[0] &= ~(0xFU << (2 * 4));
    GPIOA->AFR[0] |=  (7U << (2 * 4));
    
  5. For an input, set the mode to input and pick the pull from the circuit: an active-low button with no external resistor takes a pull-up (PUPDR = 01). Read IDR and invert for active-low. Done when: the pin reads the idle level with nothing pressed.

    /* PC13 input with pull-up, active-low button */
    GPIOC->MODER &= ~(3U << (13 * 2));
    GPIOC->PUPDR &= ~(3U << (13 * 2));
    GPIOC->PUPDR |=  (1U << (13 * 2));
    int pressed = !(GPIOC->IDR & (1U << 13));
    
  6. For an edge interrupt on STM32, enable the SYSCFG clock, route the EXTI line to the port in SYSCFG->EXTICR, unmask the line, select the edge, and enable the NVIC entry. Line n uses EXTICR[n / 4], nibble n % 4; line 13 is EXTICR[3] bits 7 to 4. Lines 10 to 15 share EXTI15_10_IRQn. In the handler, test EXTI->PR for the line and clear it by writing 1. Done when: one press produces one handler entry and PR is clear on exit.

    RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
    SYSCFG->EXTICR[3] = (SYSCFG->EXTICR[3] & ~(0xFU << 4)) | (0x2U << 4);  /* EXTI13 <- port C */
    EXTI->IMR  |= (1U << 13);
    EXTI->FTSR |= (1U << 13);           /* falling edge */
    NVIC_EnableIRQ(EXTI15_10_IRQn);
    
    void EXTI15_10_IRQHandler(void)
    {
        if (EXTI->PR & (1U << 13)) {
            EXTI->PR = (1U << 13);      /* write 1 to clear */
            button_event();
        }
    }
    
  7. Translate the same steps for other vendors. On nRF52 each pin has one NRF_P0->PIN_CNF[n] register holding direction, input buffer, pull, drive strength, and sense. On ESP32 the pin function is selected through the IO MUX and GPIO matrix, and outputs use write-1-to-set and write-1-to-clear registers. In every case, power or clock the port or domain before configuring the pin. Done when: the mapping from mode, pull, and function to the vendor's registers is stated.

  8. Verify on the target: toggle the output and watch the LED or a probe; press the button and watch IDR; for the interrupt, count handler entries per press. Done when: each observation matches the design.

Failure and recovery

SymptomCauseFix
Pin does nothingPort clock off, or MODER still at resetEnable the port clock first; re-read the pin table.
Peripheral signal absent on the pinWrong AF number or wrong AFR halfTake the AF number from the datasheet table for that pin; pins 8 to 15 live in AFR[1].
Interrupt storm on a buttonFloating input or no debounceEnable the pull; debounce in software or with a timer.
Interrupt never firesSYSCFG clock off, wrong EXTICR nibble, or NVIC entry not enabledEnable SYSCFGEN; compute EXTICR[n / 4] and nibble n % 4; enable the shared IRQ.
LED invertedActive-low wiringCheck the schematic; invert the drive.

Output

A pin configuration sequence for the target part: port clock, mode, pull, speed, alternate function from the datasheet table, and for interrupt pins the EXTI routing, edge, NVIC enable, and handler with the correct flag clear.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Use when explaining System V AMD64, ARM AAPCS, RISC-V psABI, stack frames, variadic calls, or FFI register rules. Not for the Rust FFI binding layer: use rust-ffi.

日本語の概要は準備中です。原文の説明を表示しています。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

Use when configuring ADC sampling time, DMA-driven ADC, calibration, or DAC channel setup on bare-metal MCUs. Not for the DMA stream itself: use dma-baremetal.

日本語の概要は準備中です。原文の説明を表示しています。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

af-xdp

無料

Use when creating AF_XDP sockets, configuring UMEM and XSK rings, writing an XDP redirect program, or choosing copy versus zero-copy mode. Not for full kernel bypass: use dpdk.

日本語の概要は準備中です。原文の説明を表示しています。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

Use when a completed session needs an agent-environment retrospective. Not for an engineering retrospective from telemetry: use engineering-retrospective.

日本語の概要は準備中です。原文の説明を表示しています。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

Use when a redacted, trimmed agent transcript must be appended to a GitHub PR or issue body, with human approval and preview. Not for automated or model-initiated insertion.

日本語の概要は準備中です。原文の説明を表示しています。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

agents-md

無料

Use when a repo needs agent setup, AGENTS.md added or made lean, CLAUDE.md audited, or agent instructions scored or pruned. Not for remote, credential, publish, deploy, or irreversible changes.

日本語の概要は準備中です。原文の説明を表示しています。

OutlineDriven/odin-claude-plugin372026年9月29日 更新

OutlineDriven のスキルをすべて見る

このスキルの問題を報告する