#include  <stdint.h>
#define VEC_(nm, pfx)	void nm##pfx(void) __attribute__ ((weak, alias ("IntDefaultHandler"))) 
#define VEC(nm)		VEC_(nm, _Handler)
#define VECI(nm)	VEC_(nm, _IRQHandler)


void __attribute__ ((weak)) IntDefaultHandler(void);
VEC(NMI);
VEC(HardFault);
VEC(MemoryManagemntFault);
VEC(BusFault);
VEC(UsageFault);
VEC(SVC);
VEC(PendSV);
VEC(SysTick);
VECI(WWDG);
VECI(PVD);
VECI(TAMPER);
VECI(RTC);
VECI(FLASH);
VECI(RCC);
VECI(EXTI0);
VECI(EXTI1);
VECI(EXTI2);
VECI(EXTI3);
VECI(EXTI4);
VECI(DMA_Channel1);
VECI(DMA_Channel2);
VECI(DMA_Channel3);
VECI(DMA_Channel4);
VECI(DMA_Channel5);
VECI(DMA_Channel6);
VECI(DMA_Channel7);
VECI(ADC1_2);
VECI(USB_HP_CAN_TX);
VECI(USB_LP_CAN_RX0);
VECI(CAN_RX1);
VECI(CAN_SCE);
VECI(EXTI9_5);
VECI(TIM1_BRK);
VECI(TIM1_UP);
VECI(TIM1_TRG_COM);
VECI(TIM1_CC);
VECI(TIM2);
VECI(TIM3);
VECI(TIM4);
VECI(I2C1_EV);
VECI(I2C1_ER);
VECI(I2C2_EV);
VECI(I2C2_ER);
VECI(SPI1);
VECI(SPI2);
VECI(USART1);
VECI(USART2);
VECI(USART3);
VECI(EXTI15_10);
VECI(RTCAlarm);
VECI(USBWakeup);
VECI(TIM8_BRK);
VECI(TIM8_UP);
VECI(TIM8_TRG_COM);
VECI(TIM8_CC);
VECI(ADC3);
VECI(FSMC);
VECI(SDIO);
VECI(TIM5);
VECI(SPI3);
VECI(UART4);
VECI(UART5);
VECI(TIM6);
VECI(TIM7);
VECI(DMA2_Channel1);
VECI(DMA2_Channel2);
VECI(DMA2_Channel3);
VECI(DMA2_Channel4_5);


//main must exist
extern int main(void);

//stack top (provided by linker)
extern void __stack_top();
extern uint32_t __data_data[];
extern uint32_t __data_start[];
extern uint32_t __data_end[];
extern uint32_t __bss_start[];
extern uint32_t __bss_end[];




void __attribute__((noreturn)) IntDefaultHandler(void)
{
	while (1) {		
		asm("wfi":::"memory");
	}
}


void __attribute__((noreturn)) ResetISR(void)
{
	uint32_t *dst, *src, *end;

	//copy data
	dst = __data_start;
	src = __data_data;
	end = __data_end;
	while(dst != end)
		*dst++ = *src++;

	//init bss
	dst = __bss_start;
	end = __bss_end;
	while(dst != end)
		*dst++ = 0;

	main();

//if main returns => bad
	while(1);
}


__attribute__ ((section(".vectors"))) void (*const __VECTORS[]) (void) =
{
	&__stack_top,
	ResetISR,
	NMI_Handler,
	HardFault_Handler,
	MemoryManagemntFault_Handler,
	BusFault_Handler,
	UsageFault_Handler,
	0,
	0,
	0,
	0,
	SVC_Handler,		// SVCall handler
	0,			// Reserved
	0,			// Reserved
	PendSV_Handler,		// The PendSV handler
	SysTick_Handler,	// The SysTick handler
	
	// Chip Level - STM32F103
	WWDG_IRQHandler,
	PVD_IRQHandler,
	TAMPER_IRQHandler,
	RTC_IRQHandler,
	FLASH_IRQHandler,
	RCC_IRQHandler,
	EXTI0_IRQHandler,
	EXTI1_IRQHandler,
	EXTI2_IRQHandler,
	EXTI3_IRQHandler,
	EXTI4_IRQHandler,
	DMA_Channel1_IRQHandler,
	DMA_Channel2_IRQHandler,
	DMA_Channel3_IRQHandler,
	DMA_Channel4_IRQHandler,
	DMA_Channel5_IRQHandler,
	DMA_Channel6_IRQHandler,
	DMA_Channel7_IRQHandler,
	ADC1_2_IRQHandler,
	USB_HP_CAN_TX_IRQHandler,
	USB_LP_CAN_RX0_IRQHandler,
	CAN_RX1_IRQHandler,
	CAN_SCE_IRQHandler,
	EXTI9_5_IRQHandler,
	TIM1_BRK_IRQHandler,
	TIM1_UP_IRQHandler,
	TIM1_TRG_COM_IRQHandler,
	TIM1_CC_IRQHandler,
	TIM2_IRQHandler,
	TIM3_IRQHandler,
	TIM4_IRQHandler,
	I2C1_EV_IRQHandler,
	I2C1_ER_IRQHandler,
	I2C2_EV_IRQHandler,
	I2C2_ER_IRQHandler,
	SPI1_IRQHandler,
	SPI2_IRQHandler,
	USART1_IRQHandler,
	USART2_IRQHandler,
	USART3_IRQHandler,
	EXTI15_10_IRQHandler,
	RTCAlarm_IRQHandler,
	USBWakeup_IRQHandler,
	TIM8_BRK_IRQHandler,
	TIM8_UP_IRQHandler,
	TIM8_TRG_COM_IRQHandler,
	TIM8_CC_IRQHandler,
	ADC3_IRQHandler,
	FSMC_IRQHandler,
	SDIO_IRQHandler,
	TIM5_IRQHandler,
	SPI3_IRQHandler,
	UART4_IRQHandler,
	UART5_IRQHandler,
	TIM6_IRQHandler,
	TIM7_IRQHandler,
	DMA2_Channel1_IRQHandler,
	DMA2_Channel2_IRQHandler,
	DMA2_Channel3_IRQHandler,
	DMA2_Channel4_5_IRQHandler,
};



