#include "hal/hal.h"
#include "stm32f3xx_ll_usart.h"
#include "uart2.h"

static UART_HandleTypeDef huart2;

static void UART2_Pin_Init(void){
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	/* Peripheral clock enable */
	__HAL_RCC_USART2_CLK_ENABLE();
	
	__HAL_RCC_GPIOA_CLK_ENABLE();
	/**USART2 GPIO Configuration
	PA2	  ------> USART2_TX
	PA3	  ------> USART2_RX
	*/
	GPIO_InitStruct.Pin = UART_TX_Pin|UART_RX_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void UART2_Init(void){
	huart2.Instance = USART2;
	huart2.Init.BaudRate = 115200;
	huart2.Init.WordLength = UART_WORDLENGTH_8B;
	huart2.Init.StopBits = UART_STOPBITS_1;
	huart2.Init.Parity = UART_PARITY_NONE;
	huart2.Init.Mode = UART_MODE_TX_RX;
	huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart2.Init.OverSampling = UART_OVERSAMPLING_16;
	huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
	huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
	UART2_Pin_Init();
	if (HAL_UART_Init(&huart2) != HAL_OK)
	{
	  Error_Handler();
	}
	LL_USART_DisableIT_TXE(huart2.Instance);
	LL_USART_DisableDirectionRx(huart2.Instance);
	LL_USART_EnableDirectionTx(huart2.Instance);
	HAL_NVIC_EnableIRQ(USART2_IRQn);
}

void UART2_EnableTx(void) {
	USART_TypeDef *USARTx = huart2.Instance;
	if (!LL_USART_IsEnabledIT_TXE(USARTx)) {
		LL_USART_EnableIT_TXE(huart2.Instance);
	}
}

void UART2_TxData(u8 data) {
	LL_USART_TransmitData8(huart2.Instance, data);
}

__weak bool uart_tx_finished(void) {return true;}
void uart2_irq_handler(void) {
	USART_TypeDef *USARTx = huart2.Instance;
	if (LL_USART_IsActiveFlag_RXNE(USARTx)){

	}
	if (LL_USART_IsActiveFlag_TXE(USARTx)) {
		if (uart_tx_finished()){
			LL_USART_DisableIT_TXE(huart2.Instance);
		}
	}
}

