#ifndef __STM32_ADDRESS_DEFS_H
#define __STM32_ADDRESS_DEFS_H


#define uint_ptr(base, offset) *((volatile unsigned int *)(base + offset))
#define ushort_ptr(base, offset) *((volatile unsigned short *)(base + offset))
#define uchar_ptr(base, offset) *((volatile unsigned char *)(base + offset))

#define RCC_BASE 0x40021000
#define RCC_AHBENR uint_ptr(RCC_BASE, 0x14)
#define RCC_APB2ENR uint_ptr(RCC_BASE, 0x18)
#define RCC_CFGR uint_ptr(RCC_BASE, 0x4)
#define RCC_CR uint_ptr(RCC_BASE, 0x0)
#define RCC_APB1ENR uint_ptr(RCC_BASE, 0x1C)
#define RCC_BDCR uint_ptr(RCC_BASE, 0x20)

#define DMA1_BASE 0x40020000
#define DMA1_CMAR uint_ptr(DMA1_BASE, 0x14)
#define DMA1_CPAR uint_ptr(DMA1_BASE, 0x10)
#define DMA1_CNDTR uint_ptr(DMA1_BASE, 0x0C)
#define DMA1_CCR uint_ptr(DMA1_BASE, 0x08)

#define ADC1_BASE 0x40012400
#define ADC1_SQR1 uint_ptr(ADC1_BASE, 0x2C)
#define ADC1_SQR3 uint_ptr(ADC1_BASE, 0x34)
#define ADC1_SMPR2 uint_ptr(ADC1_BASE, 0x10)
#define ADC1_CR1 uint_ptr(ADC1_BASE, 0x04)
#define ADC1_CR2 uint_ptr(ADC1_BASE, 0x08)
#define ADC1_DR uint_ptr(ADC1_BASE, 0x4C)

#define GPIOA_BASE 0x40010800
#define GPIOA_CRL uint_ptr(GPIOA_BASE, 0x0)
#define GPIOA_CRH uint_ptr(GPIOA_BASE, 0x4)

#define GPIOB_BASE 0x40010C00
#define GPIOB_CRL uint_ptr(GPIOB_BASE, 0x0)
#define GPIOB_CRH uint_ptr(GPIOB_BASE, 0x4)
#define GPIOB_ODR uint_ptr(GPIOB_BASE, 0x0C)

#define GPIOC_BASE 0x40011000
#define GPIOC_CRL uint_ptr(GPIOC_BASE, 0x0)
#define GPIOC_CRH uint_ptr(GPIOC_BASE, 0x4)
#define GPIOC_IDR uint_ptr(GPIOC_BASE, 0x8)
#define GPIOC_ODR uint_ptr(GPIOC_BASE, 0x0C)

#define GPIOD_BASE 0x40011400
#define GPIOD_CRL uint_ptr(GPIOD_BASE, 0x0)
#define GPIOD_CRH uint_ptr(GPIOD_BASE, 0x4)

#define GPIOE_BASE 0x40011800
#define GPIOE_CRL uint_ptr(GPIOE_BASE, 0x0)
#define GPIOE_CRH uint_ptr(GPIOE_BASE, 0x4)

#define UART1_BASE 0x40013800
#define USART1_SR uint_ptr(UART1_BASE, 0x00)
#define USART1_DR uint_ptr(UART1_BASE, 0x04)
#define USART1_BRR uint_ptr(UART1_BASE, 0x08)
#define USART1_CR1 uint_ptr(UART1_BASE, 0x0C)
#define USART1_CR2 uint_ptr(UART1_BASE, 0x10)
#define USART1_CR3 uint_ptr(UART1_BASE, 0x14)

#define UART2_BASE 0x40004400
#define USART2_SR uint_ptr(UART2_BASE, 0x00)
#define USART2_DR uint_ptr(UART2_BASE, 0x04)
#define USART2_BRR uint_ptr(UART2_BASE, 0x08)
#define USART2_CR1 uint_ptr(UART2_BASE, 0x0C)
#define USART2_CR2 uint_ptr(UART2_BASE, 0x10)
#define USART2_CR3 uint_ptr(UART2_BASE, 0x14)

#define UART3_BASE 0x40004800
#define USART3_SR uint_ptr(UART3_BASE, 0x00)
#define USART3_DR uint_ptr(UART3_BASE, 0x04)
#define USART3_BRR uint_ptr(UART3_BASE, 0x08)
#define USART3_CR1 uint_ptr(UART3_BASE, 0x0C)
#define USART3_CR2 uint_ptr(UART3_BASE, 0x10)
#define USART3_CR3 uint_ptr(UART3_BASE, 0x14)



#define FLASH_BASE 0x40022000
#define FLASH_ACR uint_ptr(FLASH_BASE, 0x0)


#define SCB_ExceptionTableOffset uint_ptr(0, 0xE000ED08)

#define SysTick_BASE 0xE000E010
#define SysTick_CTRL uint_ptr(SysTick_BASE, 0x0)
#define SysTick_LOAD uint_ptr(SysTick_BASE, 0x4)
#define SysTick_VAL uint_ptr(SysTick_BASE, 0x8)

#define NVIC_BASE 0xE000E100
#define NVIC_Enable (&uint_ptr(NVIC_BASE, 0x0))
#define NVIC_VectorTableOffset (&uint_ptr(NVIC_BASE, 0xC08))

#define IWDG_BASE 0x40003000
#define IWDG_KR uint_ptr(IWDG_BASE, 0x0)
#define IWDG_PR uint_ptr(IWDG_BASE, 0x4)
#define IWDG_RLR uint_ptr(IWDG_BASE, 0x8)

#define PWR_BASE 0x40007000
#define PWR_CR uint_ptr(PWR_BASE, 0x0)
 
#define RTC_BASE 0x40002800
#define RTC_CRL uint_ptr(RTC_BASE, 0x4)
#define RTC_CRH uint_ptr(RTC_BASE, 0x0)
#define RTC_PRLH uint_ptr(RTC_BASE, 0x8)
#define RTC_PRLL uint_ptr(RTC_BASE, 0xC)
#define RTC_CNTH uint_ptr(RTC_BASE, 0x18)
#define RTC_CNTL uint_ptr(RTC_BASE, 0x1C)
#define RTC_ALRH uint_ptr(RTC_BASE, 0x20)
#define RTC_ALRL uint_ptr(RTC_BASE, 0x24)

#define TIM1_BASE 0x40012C00
#define TIM1_PSC uint_ptr(TIM1_BASE, 0x28)
#define TIM1_ARR uint_ptr(TIM1_BASE, 0x2C)
#define TIM1_RCR uint_ptr(TIM1_BASE, 0x30)
#define TIM1_CR1 uint_ptr(TIM1_BASE, 0x0)
#define TIM1_CR2 uint_ptr(TIM1_BASE, 0x4)
#define TIM1_CCR1 uint_ptr(TIM1_BASE, 0x34)
#define TIM1_CCR2 uint_ptr(TIM1_BASE, 0x38)
#define TIM1_CCR3 uint_ptr(TIM1_BASE, 0x3C)
#define TIM1_CCR4 uint_ptr(TIM1_BASE, 0x40)
#define TIM1_CCMR1 uint_ptr(TIM1_BASE, 0x18)
#define TIM1_CCMR2 uint_ptr(TIM1_BASE, 0x1C)
#define TIM1_CCER uint_ptr(TIM1_BASE, 0x20)
#define TIM1_SMCR uint_ptr(TIM1_BASE, 0x8)
#define TIM1_DIER uint_ptr(TIM1_BASE, 0xC)

#define TIM2_BASE 0x40000000
#define TIM2_PSC uint_ptr(TIM2_BASE, 0x28)
#define TIM2_ARR uint_ptr(TIM2_BASE, 0x2C)
#define TIM2_RCR uint_ptr(TIM2_BASE, 0x30)
#define TIM2_CR1 uint_ptr(TIM2_BASE, 0x0)
#define TIM2_CR2 uint_ptr(TIM2_BASE, 0x4)
#define TIM2_CCR1 uint_ptr(TIM2_BASE, 0x34)
#define TIM2_CCR2 uint_ptr(TIM2_BASE, 0x38)
#define TIM2_CCR3 uint_ptr(TIM2_BASE, 0x3C)
#define TIM2_CCR4 uint_ptr(TIM2_BASE, 0x40)
#define TIM2_CCMR1 uint_ptr(TIM2_BASE, 0x18)
#define TIM2_CCMR2 uint_ptr(TIM2_BASE, 0x1C)
#define TIM2_CCER uint_ptr(TIM2_BASE, 0x20)
#define TIM2_SMCR uint_ptr(TIM2_BASE, 0x8)
#define TIM2_DIER uint_ptr(TIM2_BASE, 0xC)

#define TIM3_BASE 0x40000400
#define TIM3_PSC uint_ptr(TIM3_BASE, 0x28)
#define TIM3_ARR uint_ptr(TIM3_BASE, 0x2C)
#define TIM3_RCR uint_ptr(TIM3_BASE, 0x30)
#define TIM3_CR1 uint_ptr(TIM3_BASE, 0x0)
#define TIM3_CR2 uint_ptr(TIM3_BASE, 0x4)
#define TIM3_CCR1 uint_ptr(TIM3_BASE, 0x34)
#define TIM3_CCR2 uint_ptr(TIM3_BASE, 0x38)
#define TIM3_CCR3 uint_ptr(TIM3_BASE, 0x3C)
#define TIM3_CCR4 uint_ptr(TIM3_BASE, 0x40)
#define TIM3_CCMR1 uint_ptr(TIM3_BASE, 0x18)
#define TIM3_CCMR2 uint_ptr(TIM3_BASE, 0x1C)
#define TIM3_CCER uint_ptr(TIM3_BASE, 0x20)
#define TIM3_SMCR uint_ptr(TIM3_BASE, 0x8)
#define TIM3_DIER uint_ptr(TIM3_BASE, 0xC)

#define TIM4_BASE 0x40000800
#define TIM4_PSC uint_ptr(TIM4_BASE, 0x28)
#define TIM4_ARR uint_ptr(TIM4_BASE, 0x2C)
#define TIM4_RCR uint_ptr(TIM4_BASE, 0x30)
#define TIM4_CR1 uint_ptr(TIM4_BASE, 0x0)
#define TIM4_CR2 uint_ptr(TIM4_BASE, 0x4)
#define TIM4_CCR1 uint_ptr(TIM4_BASE, 0x34)
#define TIM4_CCR2 uint_ptr(TIM4_BASE, 0x38)
#define TIM4_CCR3 uint_ptr(TIM4_BASE, 0x3C)
#define TIM4_CCR4 uint_ptr(TIM4_BASE, 0x40)
#define TIM4_CCMR1 uint_ptr(TIM4_BASE, 0x18)
#define TIM4_CCMR2 uint_ptr(TIM4_BASE, 0x1C)
#define TIM4_CCER uint_ptr(TIM4_BASE, 0x20)
#define TIM4_SMCR uint_ptr(TIM4_BASE, 0x8)
#define TIM4_DIER uint_ptr(TIM4_BASE, 0xC)

#define AFIO_BASE 0x40010000
#define AFIO_MAPR uint_ptr(AFIO_BASE, 0x4)
#define AFIO_EXTICR (&uint_ptr(AFIO_BASE, 0x8))


#define EXTI_BASE 0x40010400
#define EXTI_IMR uint_ptr(EXTI_BASE, 0x0)
#define EXTI_EMR uint_ptr(EXTI_BASE, 0x4)
#define EXTI_RTSR uint_ptr(EXTI_BASE, 0x8)
#define EXTI_FTSR uint_ptr(EXTI_BASE, 0xC)


#define BKP_BASE 0x40006C00
#define BKP_CR uint_ptr(BKP_BASE, 0x30)
#define BKP_CSR uint_ptr(BKP_BASE, 0x34)

#endif // __STM32_ADDRESS_DEFS_H
