/** @file nvic.h
 * Module handling the Nested Vector Interrupt Controller (NVIC)
 *
 * The module provides functions to configure the different interrupts and
 * their priority suiing the NVIC's interface
 */

#ifndef _NVIC_H_
#define _NVIC_H_

//--includes--------------------------------------------------------------------

#include "stdint.h"
#include "stdbool.h"


//--type definitions------------------------------------------------------------

/**
 * Available System IRQs. This does not include CPU's IRQs
 */
enum NvicIrq {
	NVIC_IRQ_WWDG = 0,
	NVIC_IRQ_PVD,
	NVIC_IRQ_TAMPER,
	NVIC_IRQ_RTC,
	NVIC_IRQ_FLASH,
	NVIC_IRQ_RCC,
	NVIC_IRQ_EXTI0,
	NVIC_IRQ_EXTI1,
	NVIC_IRQ_EXTI2,
	NVIC_IRQ_EXTI3,
	NVIC_IRQ_EXTI4,
	NVIC_IRQ_DMA1_CHANNEL1,
	NVIC_IRQ_DMA1_CHANNEL2,
	NVIC_IRQ_DMA1_CHANNEL3,
	NVIC_IRQ_DMA1_CHANNEL4,
	NVIC_IRQ_DMA1_CHANNEL5,
	NVIC_IRQ_DMA1_CHANNEL6,
	NVIC_IRQ_DMA1_CHANNEL7,
	NVIC_IRQ_ADC1_2,
	NVIC_IRQ_HP_CAN_TX,
	NVIC_IRQ_LP_CAN_RX0,
	NVIC_IRQ_CAN_RX1,
	NVIC_IRQ_CAN_SCE,
	NVIC_IRQ_EXTI9_5,
	NVIC_IRQ_TIM1_BRK,
	NVIC_IRQ_TIM1_UP,
	NVIC_IRQ_TIM1_TRG_COM,
	NVIC_IRQ_TIM1_CC,
	NVIC_IRQ_TIM2,
	NVIC_IRQ_TIM3,
	NVIC_IRQ_TIM4,
	NVIC_IRQ_I2C1_EVENT,
	NVIC_IRQ_I2C1_ERROR,
	NVIC_IRQ_I2C2_EVENT,
	NVIC_IRQ_I2C2_ERROR,
	NVIC_IRQ_SPI1,
	NVIC_IRQ_SPI2,
	NVIC_IRQ_USART1,
	NVIC_IRQ_USART2,
	NVIC_IRQ_USART3,
	NVIC_IRQ_EXTI15_10,
	NVIC_IRQ_RTC_ALARM,
	NVIC_IRQ_USB_WAKEUP,
	NVIC_IRQ_TIM8_BRK,
	NVIC_IRQ_TIM8_UP,
	NVIC_IRQ_TIM8_TRG_COM,
	NVIC_IRQ_TIM8_CC,
	NVIC_IRQ_ADC3,
	NVIC_IRQ_FSMC,
	NVIC_IRQ_SDIO,
	NVIC_IRQ_TIM5,
	NVIC_IRQ_SPI3,
	NVIC_IRQ_UART4,
	NVIC_IRQ_UART5,
	NVIC_IRQ_TIM6,
	NVIC_IRQ_TIM7,
	NVIC_IRQ_DMA2_CHANNEL1,
	NVIC_IRQ_DMA2_CHANNEL2,
	NVIC_IRQ_DMA2_CHANNEL3,
	NVIC_IRQ_DMA2_CHANNEL4_5,
};


//--functions-------------------------------------------------------------------

/**
 * Enables the selected IRQ
 */
void nvic_enable(enum NvicIrq irq);

/**
 * Disables the selected IRQ
 */
void nvic_disable(enum NvicIrq irq);

/**
 * Clears the pending state of an IRQ. Should be called when reaching an IRQ
 * handler so that the IRQ isn't triggered again when exiting the handler
 */
void nvic_clear_pending(enum NvicIrq irq);

/**
 * Sets the priority for the selected IRQ. The lower the priority value, the
 * higher the effective priority. Valid priority values range from 0 to 15. Any
 * higher value will be ignored. When multiple IRQs with the same priority are
 * triggered, they will be serviced from the lowest ID to the highest
 */
void nvic_set_priority(enum NvicIrq irq, uint8_t priority);

/**
 * Sets the selected IRQ's pending state. If the IRQ is active, it will be
 * triggered
 */
void nvic_set_pending(enum NvicIrq irq);

/**
 * Returns wether the selected IRQ is currently pending or not
 */
bool nvic_is_pending(enum NvicIrq irq);


#endif //_RCC_H_

