#ifndef __PERIPHERALS_H__
#define __PERIPHERALS_H__

enum BitOperation { NEGATE, ASSERT };

enum AHB1_PERIPHERAL_RESET_BITS {
	GPIOA_RST		= (1 <<  0),
	GPIOB_RST		= (1 <<  1),
	GPIOC_RST		= (1 <<  2),
	GPIOD_RST		= (1 <<  3),
	GPIOE_RST		= (1 <<  4),
	GPIOF_RST		= (1 <<  5),
	GPIOG_RST		= (1 <<  6),
	GPIOH_RST		= (1 <<  7),
	GPIOI_RST		= (1 <<  8),
	CRC_RST			= (1 << 12),
	DMA1_RST		= (1 << 21),
	DMA2_RST		= (1 << 22),
	ETHMAC_RST		= (1 << 25),
	OTG_H_RST		= (1 << 29)
};
typedef bitwise_enum<AHB1_PERIPHERAL_RESET_BITS> AHB1_PERIPHERALS_RESET;

enum AHB2_PERIPHERAL_RESET_BITS {
	DCMI_RST		= (1 <<  0),
	CRYP_RST		= (1 <<  4),
	HSAH_RST		= (1 <<  5),
	RNG_RST			= (1 <<  6),
	OTG_F_RST		= (1 <<  7)
};
typedef bitwise_enum<AHB2_PERIPHERAL_RESET_BITS> AHB2_PERIPHERALS_RESET;

enum AHB3_PERIPHERAL_RESET_BITS {
	FSMC_RST		= (1 <<  0)
};
typedef bitwise_enum<AHB3_PERIPHERAL_RESET_BITS> AHB3_PERIPHERALS_RESET;

enum APB1_PERIPHERAL_RESET_BITS {
	TIM2_RST		= (1 <<  0),
	TIM3_RST		= (1 <<  1),
	TIM4_RST		= (1 <<  2),
	TIM5_RST		= (1 <<  3),
	TIM6_RST		= (1 <<  4),
	TIM7_RST		= (1 <<  5),
	TIM12_RST		= (1 <<  6),
	TIM13_RST		= (1 <<  7),
	TIM14_RST		= (1 <<  8),
	WWDG_RST		= (1 << 11),
	SPI2_RST		= (1 << 14),
	SPI3_RST		= (1 << 15),
	USART2_RST		= (1 << 17),
	USART3_RST		= (1 << 18),
	UART4_RST		= (1 << 19),
	UART5_RST		= (1 << 20),
	I2C1_RST		= (1 << 21),
	I2C2_RST		= (1 << 22),
	I2C3_RST		= (1 << 23),
	CAN1_RST		= (1 << 25),
	CAN2_RST		= (1 << 26),
	PWR_RST			= (1 << 28),
	DAC_RST			= (1 << 29)
};
typedef bitwise_enum<APB1_PERIPHERAL_RESET_BITS> APB1_PERIPHERALS_RESET;

enum APB2_PERIPHERAL_RESET_BITS {
	TIM1_RST		= (1 <<  0),
	TIM8_RST		= (1 <<  1),
	USART1_RST		= (1 <<  4),
	USART6_RST		= (1 <<  5),
	ADC_RST			= (1 <<  8),
	SDIO_RST		= (1 << 11),
	SPI1_RST		= (1 << 12),
	SYSCFG_RST		= (1 << 14),
	TIM9_RST		= (1 << 16),
	TIM10_RST		= (1 << 17),
	TIM11_RST		= (1 << 18),
};
typedef bitwise_enum<APB2_PERIPHERAL_RESET_BITS> APB2_PERIPHERALS_RESET;

// Bit definitions for RCC_AHB1ENR register
enum AHB1_PERIPHERAL_CLOCK_ENABLE_BITS {
	GPIOA_EN			= (1 <<  0),
	GPIOB_EN			= (1 <<  1),
	GPIOC_EN			= (1 <<  2),
	GPIOD_EN			= (1 <<  3),
	GPIOE_EN			= (1 <<  4),
	GPIOF_EN			= (1 <<  5),
	GPIOG_EN			= (1 <<  6),
	GPIOH_EN			= (1 <<  7),
	GPIOI_EN			= (1 <<  8),
	CRC_EN				= (1 << 12),
	BKPSRAM_EN			= (1 << 18),
	CCMDATARAM_EN		= (1 << 20),
	DMA1_EN				= (1 << 21),
	DMA2_EN				= (1 << 22),
	ETHMAC_EN			= (1 << 24),
	ETHMAC_TX_EN		= (1 << 25),
	ETHMAC_RX_EN		= (1 << 26),
	ETHMAC_PTP_EN		= (1 << 27),
	OTG_HS_EN			= (1 << 28),
	OTG_HS_ULPI_EN		= (1 << 29)
};
typedef bitwise_enum<AHB1_PERIPHERAL_CLOCK_ENABLE_BITS> AHB1_PERIPHERALS_ENABLED;

enum AHB2_PERIPHERAL_CLOCK_ENABLE_BITS {
	DCMI_EN				= (1 <<  0),
	CRYP_EN				= (1 <<  4),
	HASH_EN				= (1 <<  5),
	RNG_EN				= (1 <<  6),
	OTG_FS_EN			= (1 <<  7)
};
typedef bitwise_enum<AHB2_PERIPHERAL_CLOCK_ENABLE_BITS> AHB2_PERIPHERALS_ENABLED;

enum AHB3_PERIPHERAL_CLOCK_ENABLE_BITS {
	FSMC_EN				= (1 << 0)
};
typedef bitwise_enum<AHB3_PERIPHERAL_CLOCK_ENABLE_BITS> APB3_PERIPHERALS_ENABLED;

enum APB1_PERIPHERAL_CLOCK_ENABLE_BITS {
	TIM2_EN				= (1 <<  0),
	TIM3_EN				= (1 <<  1),
	TIM4_EN				= (1 <<  2),
	TIM5_EN				= (1 <<  3),
	TIM6_EN				= (1 <<  4),
	TIM7_EN				= (1 <<  5),
	TIM12_EN			= (1 <<  6),
	TIM13_EN			= (1 <<  7),
	TIM14_EN			= (1 <<  8),
	WWDG_EN				= (1 << 11),
	SPI2_EN				= (1 << 14),
	SPI3_EN				= (1 << 15),
	USART2_EN			= (1 << 17),
	USART3_EN			= (1 << 18),
	UART4_EN			= (1 << 19),
	UART5_EN			= (1 << 20),
	I2C1_EN				= (1 << 21),
	I2C2_EN				= (1 << 22),
	I2C3_EN				= (1 << 23),
	CAN1_EN				= (1 << 25),
	CAN2_EN				= (1 << 26),
	PWR_EN				= (1 << 28),
	DAC_EN				= (1 << 29)
};
typedef bitwise_enum<APB1_PERIPHERAL_CLOCK_ENABLE_BITS> APB1_PERIPHERALS_ENABLED;

// Bit definitions for RCC_APB2ENR register
enum APB2_PERIPHERAL_CLOCK_ENABLE_BITS {
	TIM1_EN				= (1 <<  0),
	TIM8_EN				= (1 <<  1),
	USART1_EN			= (1 <<  4),
	USART6_EN			= (1 <<  5),
	ADC1_EN				= (1 <<  8),
	ADC2_EN				= (1 <<  9),
	ADC3_EN				= (1 << 10),
	SDIO_EN				= (1 << 11),
	SPI1_EN				= (1 << 12),
	SYSCFG_EN			= (1 << 14),
	TIM11_EN			= (1 << 16),
	TIM10_EN			= (1 << 17),
	TIM9_EN				= (1 << 18)
};
typedef bitwise_enum<APB2_PERIPHERAL_CLOCK_ENABLE_BITS> APB2_PERIPHERALS_ENABLED;

enum AHB1_PERIPHERALS_SLEEP_ENABLED_BITS {
	GPIOA_LPEN			= (1 <<  0),
	GPIOB_LPEN			= (1 <<  1),
	GPIOC_LPEN			= (1 <<  2),
	GPIOD_LPEN			= (1 <<  3),
	GPIOE_LPEN			= (1 <<  4),
	GPIOF_LPEN			= (1 <<  5),
	GPIOG_LPEN			= (1 <<  6),
	GPIOH_LPEN			= (1 <<  7),
	GPIOI_LPEN			= (1 <<  8),
	CRC_LPEN			= (1 << 12),
	FLITF_LPEN			= (1 << 15),
	SRAM1_LPEN			= (1 << 16),
	SRAM2_LPEN			= (1 << 17),
	BKPSRAM_LPEN		= (1 << 18),
	DMA1_LPEN			= (1 << 21),
	DMA2_LPEN			= (1 << 22),
	ETHMAC_LPEN			= (1 << 25),
	ETHMAC_TX_LPEN		= (1 << 26),
	ETHMAC_RX_LPEN		= (1 << 27),
	ETHMAC_PTP_LPEN		= (1 << 28),
	OTG_HS_LPEN			= (1 << 29),
	OTG_HS_ULPI_LPEN	= (1 << 30)
};
typedef bitwise_enum<AHB1_PERIPHERALS_SLEEP_ENABLED_BITS> AHB1_PERIPHERALS_ENABLED_DURING_SLEEP;

enum AHB2_PERIPHERAL_SLEEP_ENABLED_BITS {
	DCMI_LPEN			= (1 <<  0),
	CRYP_LPEN			= (1 <<  4),
	HASH_LPEN			= (1 <<  5),
	RNG_LPEN			= (1 <<  6),
	OTG_FS_LPEN			= (1 <<  7)
};
typedef bitwise_enum<AHB2_PERIPHERAL_SLEEP_ENABLED_BITS> AHB2_PERIPHERALS_ENABLED_DURING_SLEEP;

enum AHB3_PERIPHERAL_SLEEP_ENABLED_BITS {
	FSMC_LPEN			= (1 << 0)
};
typedef bitwise_enum<AHB3_PERIPHERAL_SLEEP_ENABLED_BITS> AHB3_PERIPHERALS_ENABLED_DURING_SLEEP;


enum APB1_PERIPHERAL_SLEEP_ENABLED_BITS {
	TIM2_LPEN			= (1 <<  0),
	TIM3_LPEN			= (1 <<  1),
	TIM4_LPEN			= (1 <<  2),
	TIM5_LPEN			= (1 <<  3),
	TIM6_LPEN			= (1 <<  4),
	TIM7_LPEN			= (1 <<  5),
	TIM12_LPEN			= (1 <<  6),
	TIM13_LPEN			= (1 <<  7),
	TIM14_LPEN			= (1 <<  8),
	WWDG_LPEN			= (1 << 11),
	SPI2_LPEN			= (1 << 14),
	SPI3_LPEN			= (1 << 15),
	USART2_LPEN			= (1 << 17),
	USART3_LPEN			= (1 << 18),
	UART4_LPEN			= (1 << 19),
	UART5_LPEN			= (1 << 20),
	I2C1_LPEN			= (1 << 21),
	I2C2_LPEN			= (1 << 22),
	I2C3_LPEN			= (1 << 23),
	CAN1_LPEN			= (1 << 25),
	CAN2_LPEN			= (1 << 26),
	PWR_LPEN			= (1 << 28),
	DAC_LPEN			= (1 << 29)
};
typedef bitwise_enum<APB1_PERIPHERAL_SLEEP_ENABLED_BITS> APB1_PERIPHERALS_ENABLED_DURING_SLEEP;


enum APB2_PERIPHERAL_SLEEP_ENABLED_BITS {
	TIM1_LPEN			= (1 <<  0),
	TIM8_LPEN			= (1 <<  1),
	USART1_LPEN			= (1 <<  4),
	USART6_LPEN			= (1 <<  5),
	ADC1_LPEN			= (1 <<  8),
	ADC2_LPEN			= (1 <<  9),
	ADC3_LPEN			= (1 << 10),
	SDIO_LPEN			= (1 << 11),
	SPI1_LPEN			= (1 << 12),
	SYSCFG_LPEN			= (1 << 14),
	TIM11_LPEN			= (1 << 16),
	TIM10_LPEN			= (1 << 17),
	TIM9_LPEN			= (1 << 18)
};
typedef bitwise_enum<APB2_PERIPHERAL_SLEEP_ENABLED_BITS> APB2_PERIPHERALS_ENABLED_DURING_SLEEP;

#endif // __PERIPHERALS_H__
