#define RCC_BASE       0x40021000
#define TIM1_BASE      0x40012C00
#define GPIOA_BASE     0x50000000

// RCC Registers
#define RCC_APB2ENR    (*((volatile uint32_t *)(RCC_BASE + 0x40))) // APB2 Peripheral Clock Enable Register
#define RCC_IOPENR     (*((volatile uint32_t *)(RCC_BASE + 0x34))) 
// TIM1 Registers
#define TIM1_CR1       (*((volatile uint32_t *)(TIM1_BASE + 0x00))) // Control Register 1
#define TIM1_CR2       (*((volatile uint32_t *)(TIM1_BASE + 0x04))) // Control Register 2
#define TIM1_SMCR      (*((volatile uint32_t *)(TIM1_BASE + 0x08))) // Slave Mode Control Register
#define TIM1_DIER      (*((volatile uint32_t *)(TIM1_BASE + 0x0C))) // DMA/Interrupt Enable Register
#define TIM1_SR        (*((volatile uint32_t *)(TIM1_BASE + 0x10))) // Status Register
#define TIM1_EGR       (*((volatile uint32_t *)(TIM1_BASE + 0x14))) // Event Generation Register
#define TIM1_CCMR1     (*((volatile uint32_t *)(TIM1_BASE + 0x18))) // Capture/Compare Mode Register 1
#define TIM1_CCER      (*((volatile uint32_t *)(TIM1_BASE + 0x20))) // Capture/Compare Enable Register
#define TIM1_CNT       (*((volatile uint32_t *)(TIM1_BASE + 0x24))) // Counter
#define TIM1_PSC       (*((volatile uint32_t *)(TIM1_BASE + 0x28))) // Prescaler
#define TIM1_ARR       (*((volatile uint32_t *)(TIM1_BASE + 0x2C))) // Auto-Reload Register
#define TIM1_CCR1      (*((volatile uint32_t *)(TIM1_BASE + 0x34))) // Capture/Compare Register 1
#define TIM1_BDTR      (*((volatile uint32_t *)(TIM1_BASE + 0x44))) // Break and Dead-Time Register
#define GPIOA_MODER    (*((volatile uint32_t *)(GPIOA_BASE + 0x00)))
#define GPIOA_AFRL     (*((volatile uint32_t *)(GPIOA_BASE + 0x20)))
#define GPIOA_AFRH     (*((volatile uint32_t *)(GPIOA_BASE + 0x24)))


void ConfigureAFUserLED()
{
	// GPIOA clock enable
	RCC_IOPENR |= (1<<0);
	// Set PA5 alternate function
	GPIOA_MODER &= ~(3 << 16);
	GPIOA_MODER |= (2 << 16);
	GPIOA_AFRH &= ~(0xF << 0);
	GPIOA_AFRH |= (0x2 << 0);
}


void TIM1_Init_OutputCompare(void) {
    // 1. Enable TIM1 clock
    RCC_APB2ENR |= (1 << 11); // Set bit 0 to enable TIM1 clock

    // 2. Configure prescaler and auto-reload
    TIM1_CCMR1 &= ~(0xFF);
    TIM1_PSC = 15999; // Prescaler: Divide clock by 16000 (assuming 16 MHz input clock)
    TIM1_ARR = 499;  // Auto-reload: Timer period of 1 second at 1 kHz
    TIM1_CCR1 = 199;

    TIM1_CCER &= ~(1<<0); 
    TIM1_CCER &= ~(1<<1);
    TIM1_CCMR1 &= ~(3 << 0);
    TIM1_CCMR1 |= (0x3 << 4); 
    TIM1_CCER |= (1 << 0);  

    TIM1_BDTR |= (1 << 15);    


    TIM1_CR1 |= (1 << 0);//enable timer
}

int main(void) {
    ConfigureAFUserLED();
    TIM1_Init_OutputCompare();

    while (1) {
        // Main loop: Timer runs independently
    }
}