#include <stdint.h>
#define RCC_BASE 0x40021000
#define GPIOA_BASE 0x50000000
#define EXTI_BASE 0x40021800
#define SYSCFG_BASE 0x40010000
// Register offsets
#define RCC_IOPENR (*(volatile uint32_t *)(RCC_BASE + 0x34)) // I/O port enable
#define RCC_APBENR2 (*(volatile uint32_t *)(RCC_BASE + 0x40)) // SYSCFG enable
#define SYSCFG_ITLINE5 (*(volatile uint32_t *)(SYSCFG_BASE + 0x94)) // EXTI configuration register 1
#define EXTI_IMR1 (*(volatile uint32_t *)(EXTI_BASE + 0x080)) // Interrupt mask register 1
#define EXTI_RTSR1 (*(volatile uint32_t *)(EXTI_BASE + 0x000)) // Rising trigger selection register 1
#define EXTI_FTSR1 (*(volatile uint32_t *)(EXTI_BASE + 0x004)) // Falling trigger selection register 1
#define EXTI_RPR1 (*(volatile uint32_t *)(EXTI_BASE + 0x00C)) // Rising edge Pending register 1
#define EXTI_FPR1 (*(volatile uint32_t *)(EXTI_BASE + 0x010))//Falling edge Pending register 1
#define EXTI_SWIER1 (*(volatile uint32_t *)(EXTI_BASE + 0x008))//Software interrupt enable register1
#define GPIOA_MODER (*(volatile uint32_t *)(GPIOA_BASE + 0x00)) // GPIO port mode register
#define GPIOA_ODR (*(volatile uint32_t *)(GPIOA_BASE + 0x14)) // GPIO port output data register
#define NVIC_ISER (*(volatile uint32_t *)0xE000E100) // Interrupt Set-Enable Register
#define NVIC_PRIOR (*(volatile uint32_t *)0xE000E400) // Interrupt Set-Enable Register
#define NVIC_IPR_BASE 0xE000E400 // Base address of NVIC_IPR registers
#define NVIC_IPR ((volatile uint32_t*) NVIC_IPR_BASE)
#define EXTI_EXTICR1 (*(volatile uint32_t *)(EXTI_BASE + 0x060))
// Bit definitions
#define GPIOAEN (1 << 0) // GPIOA clock enable
#define SYSCFGEN (1 << 0) // SYSCFG clock enable
#define EXTI_LINE_0 (1 << 0) // EXTI Line 0
#define PA5 (1 << 5) // GPIO Pin 5
// Function prototypes
void GPIO_Config(void);
void EXTI_Config(void);
void NVIC_Config(void);
void GPIO_Config(void) {
// Enable GPIOA clock
RCC_IOPENR |= GPIOAEN;
// Set PA5 as output (01 in MODER[10:11])
GPIOA_MODER &= ~(3 << (5 * 2)); // Clear mode bits for PA5
GPIOA_MODER |= (1 << (5 * 2)); // Set PA5 to output mode
// PA0 as input (00 in MODER[0:1], default state)
GPIOA_MODER &= ~(3 << (0 * 2)); // Clear mode bits for PA0
}
void EXTI_Config(void){
RCC_APBENR2 |= SYSCFGEN;
EXTI_EXTICR1 &= ~(0xFF);
EXTI_EXTICR1 |= (0x1<<0);
EXTI_IMR1 |= EXTI_LINE_0;
EXTI->RTSR1 &= ~EXTI_LINE_0;
EXTI->FTSR1 |= EXTI_LINE_0;
}
void EXTI0_1_IRQ_handler(void) {
if (EXTI_FPR1 & EXTI_LINE_0) {
EXTI_FPR1 |= EXTI_LINE_0;
GPIOA_ODR |= PA5;
}
}
int main(void) {
while (1) {
// Idle, waiting for interrupt
}
}
NVIC_SetPriority(EXTI0_1_IRQn, 0x03);
NVIC_EnableIRQ(EXTI0_1_IRQn);