static void TM_USART_INT_Init(
	USART_TypeDef* USARTx,
	TM_USART_PinsPack_t pinspack,
	uint32_t baudrate,
	TM_USART_HardwareFlowControl_t FlowControl,
	uint32_t Mode,
	uint32_t Parity,
	uint32_t StopBits,
	uint32_t WordLength
) {
	USART_InitTypeDef USART_InitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	TM_USART_t* u = TM_USART_INT_GetUsart(USARTx);

	/* Set USART baudrate */
	USART_InitStruct.USART_BaudRate = baudrate;
	
	/*
	 * Initialize USARTx pins
	 * Set channel for USARTx NVIC
	 */
#ifdef USE_USART1
	if (USARTx == USART1) {
		/* Enable USART clock */
		RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
		
		/* Init pins */
		TM_USART1_InitPins(pinspack);
		
		/* Set IRQ channel */
		NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
	}
#endif
#ifdef USE_USART2
	if (USARTx == USART2) {
		/* Enable USART clock */
		RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
		
		/* Init pins */
		TM_USART2_InitPins(pinspack);
		
		/* Set IRQ channel */
		NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
	}
#endif
#ifdef USE_USART3
	if (USARTx == USART3) {
		/* Enable USART clock */
		RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
		
		/* Init pins */
		TM_USART3_InitPins(pinspack);
		
		/* Set IRQ channel */
		NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;
	}
#endif
#ifdef USE_UART4
	if (USARTx == UART4) {
		/* Enable UART clock */
		RCC->APB1ENR |= RCC_APB1ENR_UART4EN;
		
		/* Init pins */
		TM_UART4_InitPins(pinspack);
		
		/* Set IRQ channel */
		NVIC_InitStruct.NVIC_IRQChannel = UART4_IRQn;
	}
#endif
#ifdef USE_UART5
	if (USARTx == UART5) {
		/* Enable UART clock */
		RCC->APB1ENR |= RCC_APB1ENR_UART5EN;

		/* Init pins */
		TM_UART5_InitPins(pinspack);
		
		/* Set IRQ channel */
		NVIC_InitStruct.NVIC_IRQChannel = UART5_IRQn;
	}
#endif
#ifdef USE_USART6
	if (USARTx == USART6) {
		/* Enable UART clock */
		RCC->APB2ENR |= RCC_APB2ENR_USART6EN;
		
		/* Init pins */
		TM_USART6_InitPins(pinspack);
		
		/* Set IRQ channel */
		NVIC_InitStruct.NVIC_IRQChannel = USART6_IRQn;
	}
#endif
#ifdef USE_UART7
	if (USARTx == UART7) {
		/* Enable UART clock */
		RCC->APB1ENR |= RCC_APB1ENR_UART7EN;
		
		/* Init pins */
		TM_UART7_InitPins(pinspack);
		
		/* Set IRQ channel */
		NVIC_InitStruct.NVIC_IRQChannel = UART7_IRQn;
	}
#endif
#ifdef USE_UART8
	if (USARTx == UART8) {
		/* Enable UART clock */
		RCC->APB1ENR |= RCC_APB1ENR_UART8EN;

		/* Init pins */
		TM_UART8_InitPins(pinspack);
		
		/* Set IRQ channel */
		NVIC_InitStruct.NVIC_IRQChannel = UART8_IRQn;
	}
#endif
	
	/* Deinit USART, force reset */
	USART_DeInit(USARTx);
	
	/* Fill NVIC settings */
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = TM_USART_NVIC_PRIORITY;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = TM_USART_INT_GetSubPriority(USARTx);
	NVIC_Init(&NVIC_InitStruct);
	
	/* Fill default settings */
	USART_InitStruct.USART_HardwareFlowControl = FlowControl;
	USART_InitStruct.USART_Mode = Mode;
	USART_InitStruct.USART_Parity = Parity;
	USART_InitStruct.USART_StopBits = StopBits;
	USART_InitStruct.USART_WordLength = WordLength;
	
	/* We are not initialized */
	u->Initialized = 0;
	
	do {
		volatile uint32_t x = 0xFFF;
		while (x--);
	} while (0);
	
	/* Init */
	USART_Init(USARTx, &USART_InitStruct);
	
	/* Enable RX interrupt */
	USARTx->CR1 |= USART_CR1_RXNEIE;
	
	/* We are initialized now */
	u->Initialized = 1;
	
	/* Enable USART peripheral */
	USARTx->CR1 |= USART_CR1_UE;
}
static void TM_USART_INT_Init(
	USART_TypeDef* USARTx,
	TM_USART_PinsPack_t pinspack,
	uint32_t baudrate,
	TM_USART_HardwareFlowControl_t FlowControl,
	uint32_t Mode,
	uint32_t Parity,
	uint32_t StopBits,
	uint32_t WordLength
) {
	UART_HandleTypeDef UARTHandle;
	IRQn_Type irq;
	
	/*
	 * Initialize USARTx pins
	 * Set channel for USARTx NVIC
	 */
#ifdef USART1
	if (USARTx == USART1) {
		/* Enable USART clock */
		__HAL_RCC_USART1_CLK_ENABLE();
		__HAL_RCC_USART1_FORCE_RESET();
		__HAL_RCC_USART1_RELEASE_RESET();
		
		/* Init pins */
		TM_USART1_InitPins(pinspack);
		
		/* Set IRQ channel */
		irq = IRQ_USART1;
	}
#endif
#ifdef USART2
	if (USARTx == USART2) {
		/* Enable USART clock */
		__HAL_RCC_USART2_CLK_ENABLE();
		__HAL_RCC_USART2_FORCE_RESET();
		__HAL_RCC_USART2_RELEASE_RESET();
		
		/* Init pins */
		TM_USART2_InitPins(pinspack);
		
		/* Set IRQ channel */
		irq = IRQ_USART2;
	}
#endif
#ifdef USART3
	if (USARTx == USART3) {
		/* Enable USART clock */
		__HAL_RCC_USART3_CLK_ENABLE();
		__HAL_RCC_USART3_FORCE_RESET();
		__HAL_RCC_USART3_RELEASE_RESET();
		
		/* Init pins */
		TM_USART3_InitPins(pinspack);
		
		/* Set IRQ channel */
		irq = IRQ_USART3;
	}
#endif
#ifdef UART4
	if (USARTx == UART4) {
		/* Enable UART clock */
		__HAL_RCC_UART4_CLK_ENABLE();
		__HAL_RCC_UART4_FORCE_RESET();
		__HAL_RCC_UART4_RELEASE_RESET();
		
		/* Init pins */
		TM_UART4_InitPins(pinspack);
		
		/* Set IRQ channel */
		irq = IRQ_UART4;
	}
#endif
#ifdef UART5
	if (USARTx == UART5) {
		/* Enable UART clock */
		__HAL_RCC_UART5_CLK_ENABLE();
		__HAL_RCC_UART5_FORCE_RESET();
		__HAL_RCC_UART5_RELEASE_RESET();

		/* Init pins */
		TM_UART5_InitPins(pinspack);
		
		/* Set IRQ channel */
		irq = IRQ_UART5;
	}
#endif
#ifdef USART6
	if (USARTx == USART6) {
		/* Enable UART clock */
		__HAL_RCC_USART6_CLK_ENABLE();
		__HAL_RCC_USART6_FORCE_RESET();
		__HAL_RCC_USART6_RELEASE_RESET();
		
		/* Init pins */
		TM_USART6_InitPins(pinspack);
		
		/* Set IRQ channel */
		irq = IRQ_USART6;
	}
#endif
#ifdef UART7
	if (USARTx == UART7) {
		/* Enable UART clock */
		__HAL_RCC_UART7_CLK_ENABLE();
		__HAL_RCC_UART7_FORCE_RESET();
		__HAL_RCC_UART7_RELEASE_RESET();
		
		/* Init pins */
		TM_UART7_InitPins(pinspack);
		
		/* Set IRQ channel */
		irq = IRQ_UART7;
	}
#endif
#ifdef UART8
	if (USARTx == UART8) {
		/* Enable UART clock */
		__HAL_RCC_UART8_CLK_ENABLE();
		__HAL_RCC_UART8_FORCE_RESET();
		__HAL_RCC_UART8_RELEASE_RESET();

		/* Init pins */
		TM_UART8_InitPins(pinspack);
		
		/* Set IRQ channel */
		irq = IRQ_UART8;
	}
#endif
	
/* STM32F0xx related */
#ifdef USART4
	if (USARTx == USART4) {
		/* Enable UART clock */
		__HAL_RCC_USART4_CLK_ENABLE();
		__HAL_RCC_USART4_FORCE_RESET();
		__HAL_RCC_USART4_RELEASE_RESET();
		
		/* Init pins */
		TM_USART4_InitPins(pinspack);
		
		/* Set IRQ channel */
		irq = IRQ_USART4;
	}
#endif
#ifdef USART5
	if (USARTx == USART5) {
		/* Enable UART clock */
		__HAL_RCC_USART5_CLK_ENABLE();
		__HAL_RCC_USART5_FORCE_RESET();
		__HAL_RCC_USART5_RELEASE_RESET();
		
		/* Init pins */
		TM_USART5_InitPins(pinspack);
		
		/* Set IRQ channel */
		irq = IRQ_USART5;
	}
#endif
#ifdef USART7
	if (USARTx == USART7) {
		/* Enable UART clock */
		__HAL_RCC_USART7_CLK_ENABLE();
		__HAL_RCC_USART7_FORCE_RESET();
		__HAL_RCC_USART7_RELEASE_RESET();
		
		/* Init pins */
		TM_USART7_InitPins(pinspack);
		
		/* Set IRQ channel */
		irq = IRQ_USART7;
	}
#endif
#ifdef USART8
	if (USARTx == USART8) {
		/* Enable UART clock */
		__HAL_RCC_USART8_CLK_ENABLE();
		__HAL_RCC_USART8_FORCE_RESET();
		__HAL_RCC_USART8_RELEASE_RESET();
		
		/* Init pins */
		TM_USART8_InitPins(pinspack);
		
		/* Set IRQ channel */
		irq = IRQ_USART8;
	}
#endif
	
	/* Fill default settings */
	UARTHandle.Instance = USARTx;
	UARTHandle.Init.BaudRate = baudrate;
	UARTHandle.Init.HwFlowCtl = FlowControl;
	UARTHandle.Init.Mode = Mode;
	UARTHandle.Init.Parity = Parity;
	UARTHandle.Init.StopBits = StopBits;
	UARTHandle.Init.WordLength = WordLength;
	UARTHandle.Init.OverSampling = UART_OVERSAMPLING_16;
#if defined(STM32F0xx)
	UARTHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
#endif
	
	/* Disable IRQ */
	HAL_NVIC_DisableIRQ(irq);

	/* Set priority */
	HAL_NVIC_SetPriority(irq, USART_NVIC_PRIORITY, TM_USART_INT_GetSubPriority(USARTx));
	
	/* Enable interrupt */
	HAL_NVIC_EnableIRQ(irq);
	
	/* Clear interrupt */
	HAL_NVIC_ClearPendingIRQ(irq);
	
	/* Init USART */
	HAL_UART_Init(&UARTHandle);
	
	/* Enable RX interrupt */
	USARTx->CR1 |= USART_CR1_RXNEIE;
}