#include <stdint.h>
// Base addresses
#define RCC_BASE 0x40021000
#define GPIOA_BASE 0x50000000
// RCC register
#define RCC_IOPENR (*(volatile uint32_t *)(RCC_BASE + 0x34))
// GPIOA registers
#define GPIOA_MODER (*(volatile uint32_t *)(GPIOA_BASE + 0x00))
#define GPIOA_PUPDR (*(volatile uint32_t *)(GPIOA_BASE + 0x0C))
#define GPIOA_IDR (*(volatile uint32_t *)(GPIOA_BASE + 0x10))
#define GPIOA_ODR (*(volatile uint32_t *)(GPIOA_BASE + 0x14))
// Pins
#define LED_PIN 1 // PA1
#define SWITCH_PIN 0 // PA0
// Optional delay
void delay(volatile uint32_t t) {
while (t--) __asm__("nop");
}
int main(void)
{
// 1. Enable GPIOA clock
RCC_IOPENR |= (1 << 0); // GPIOAEN
// 2. Configure PA1 as output (LED)
GPIOA_MODER &= ~(3 << (LED_PIN * 2)); // Clear bits
GPIOA_MODER |= (1 << (LED_PIN * 2)); // 01 = output
// 3. Configure PA0 as input (switch)
GPIOA_MODER &= ~(3 << (SWITCH_PIN * 2)); // 00 = input
// 4. Pull-up on PA0 (active-low switch)
GPIOA_PUPDR &= ~(3 << (SWITCH_PIN * 2));
GPIOA_PUPDR |= (1 << (SWITCH_PIN * 2)); // 01 = pull-up
while (1)
{
if ((GPIOA_IDR & (1 << SWITCH_PIN)) == 0) {
// Switch pressed → turn LED ON
GPIOA_ODR |= (1 << LED_PIN);
} else {
// Switch not pressed → turn LED OFF
GPIOA_ODR &= ~(1 << LED_PIN);
}
delay(100000); // debounce-like delay
}
}