/** @file exti.h
 * Module handling EXTernal Interrupt lines
 *
 * The module provides functions to configure the exti lines to generate events
 * or interrupts
 */

#ifndef _EXTI_H_
#define _EXTI_H_

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

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

/**
 * Available exti lines. The numbered lines correspond to gpios while the
 * remaining are directly mapped to peripherals
 */
enum ExtiLine {
	EXTI_LINE_0  = (0x1 <<  0),
	EXTI_LINE_1  = (0x1 <<  1),
	EXTI_LINE_2  = (0x1 <<  2),
	EXTI_LINE_3  = (0x1 <<  3),
	EXTI_LINE_4  = (0x1 <<  4),
	EXTI_LINE_5  = (0x1 <<  5),
	EXTI_LINE_6  = (0x1 <<  6),
	EXTI_LINE_7  = (0x1 <<  7),
	EXTI_LINE_8  = (0x1 <<  8),
	EXTI_LINE_9  = (0x1 <<  9),
	EXTI_LINE_10 = (0x1 << 10),
	EXTI_LINE_11 = (0x1 << 11),
	EXTI_LINE_12 = (0x1 << 12),
	EXTI_LINE_13 = (0x1 << 13),
	EXTI_LINE_14 = (0x1 << 14),
	EXTI_LINE_15 = (0x1 << 15),
	EXTI_LINE_PVD = (0x1 << 16),
	EXTI_LINE_RTC = (0x1 << 17),
	EXTI_LINE_USB = (0x1 << 18),
};

/**
 * Available configurations for exti lines. These configurations apply to both
 * regular and specific lines and can be used together on a single line
 */
enum ExtiConfig {
	EXTI_CONFIG_RISING_EDGE  = (0x1 << 0),
	EXTI_CONFIG_FALLING_EDGE = (0x1 << 1),
};

typedef void (*ExtiCallback)(void);


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

/**
 * Configure lines to call a single callback. The ExtiLine enum can be used as a
 * mask to configure multiple lines at the same time.
 *
 * Every numbered line must be linked to a gpio port using afio_map_exti(). Each
 * line is linked to the pins of the same id (ex : pin 1 for exti 1). When
 * possible, it is recommended to use the lowest id possible for better
 * performance. Each pin must be configured independently through the gpio
 * driver module
 *
 * The remaining lines are linked to specific peripherals which must be
 * configured independently through the corresponding driver module.
 *
 * The ExtiConfig enum can be used as mask. If no callback is specified, the
 * interrupt won't be enabled, but an event will still be sent to wake the cpu
 * up.
 */
void exti_configure(enum ExtiLine line_mask, enum ExtiConfig config_mask,
		ExtiCallback callback);

/**
 * Resets lines. The ExtiLine enum can be used as a mask to reset multiple lines
 * at the same time
 */
void exti_reset(enum ExtiLine line_mask);

/**
 * Resets all lines. The exti peripheral is returned to its reset configuration
 */
void exti_reset_peripheral(void);


#endif //_EXTI_H_

