#include "driverHWUART2.h"

UART_HandleTypeDef driverHWUART2Handle;
DMA_HandleTypeDef driverHWUART2HDMAHandleRX;
uint8_t driverHWUART2ReceivedChar;

uint8_t driverHWUART2ReceiveBuffer[RX_UART_BUFFER_SIZE];															// Buffer that stores received chars
uint8_t driverHWUART2ReceiveBuffer_usb[RX_UART_BUFFER_SIZE];
uint32_t driverHWUART2Receive_CNDTR = RX_UART_BUFFER_SIZE;
uint8_t driverHWUART2Receive_CNDTR_resetFlag = 0;

void driverHWUART2Init(uint32_t baudRate) {
//	memset(driverHWUART2ReceiveBuffer,0,sizeof(driverHWUART2ReceiveBuffer)/sizeof(uint8_t));
//
//	/* DMA controller clock enable */
//  __HAL_RCC_DMA1_CLK_ENABLE();
//
//	driverHWUART2HDMAHandleRX.Instance = DMA1_Channel6;														// Will handle transfer of received char to buffer
//	driverHWUART2HDMAHandleRX.Init.Direction = DMA_PERIPH_TO_MEMORY;
//	driverHWUART2HDMAHandleRX.Init.PeriphInc = DMA_PINC_DISABLE;
//	driverHWUART2HDMAHandleRX.Init.MemInc = DMA_MINC_ENABLE;
//	driverHWUART2HDMAHandleRX.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
//	driverHWUART2HDMAHandleRX.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
//	driverHWUART2HDMAHandleRX.Init.Mode = DMA_CIRCULAR;
//	driverHWUART2HDMAHandleRX.Init.Priority = DMA_PRIORITY_MEDIUM;
//
//	if (HAL_DMA_Init(&driverHWUART2HDMAHandleRX) != HAL_OK)
//	{
//		while(true);
//	}
//
//  __HAL_LINKDMA(&driverHWUART2Handle,hdmarx,driverHWUART2HDMAHandleRX);
//
//  driverHWUART2Handle.Instance = USART2;
//  driverHWUART2Handle.Init.BaudRate = baudRate;
//  driverHWUART2Handle.Init.WordLength = UART_WORDLENGTH_8B;
//  driverHWUART2Handle.Init.StopBits = UART_STOPBITS_1;
//  driverHWUART2Handle.Init.Parity = UART_PARITY_NONE;
//  driverHWUART2Handle.Init.Mode = UART_MODE_TX_RX;
//  driverHWUART2Handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
//  driverHWUART2Handle.Init.OverSampling = UART_OVERSAMPLING_16;
// // driverHWUART2Handle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
// // driverHWUART2Handle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
//
//  if (HAL_UART_Init(&driverHWUART2Handle) != HAL_OK) {
//    while(true);
//  }
//
//	volatile HAL_StatusTypeDef temp = HAL_UART_Receive_DMA(&driverHWUART2Handle,driverHWUART2ReceiveBuffer,sizeof(driverHWUART2ReceiveBuffer)/sizeof(uint8_t)); // Start receive to DMA transfer
//
//  HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0);		// Will realise interrupt on half and full DMA transfer
//  HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
};

void driverHWUART2SendChar(uint8_t character) {
	uint8_t usb_out_buffer[1];
	uint8_t usb_result = 1;
	uint32_t usb_start_time;
	usb_start_time = HAL_GetTick();

	usb_out_buffer[0] = character;
	while(usb_result == 1){
		//) || ((HAL_GetTick() - usb_start_time < 10))
		usb_result = CDC_Transmit_FS(usb_out_buffer, 1);
	}
	//HAL_UART_Transmit(&driverHWUART2Handle,&character,sizeof(character)/sizeof(uint8_t),10);	// Send single char over serial port
};

bool driverHWUART2GetChar(char *character) {
  static uint32_t bufferTail = 0;                                                // Initiate tail to 0
  uint32_t bufferHead = sizeof(driverHWUART2ReceiveBuffer_usb)/sizeof(uint8_t) - driverHWUART2Receive_CNDTR; // Tranform to be transferred bytes to bytes transferred.

//  if(driverHWUART2Receive_CNDTR_resetFlag){
//	bufferTail = 0;
//	driverHWUART2Receive_CNDTR_resetFlag = 0;
//	//bufferHead = 0;
//  }

  if(bufferTail != bufferHead){                                                  // If head and tail differs there is something in the buffer
	*character = driverHWUART2ReceiveBuffer_usb[bufferTail];                        // Get char from tail of buffer
	bufferTail++;                                                               // Move the tail forward
    bufferTail %= (sizeof(driverHWUART2ReceiveBuffer_usb)/sizeof(uint8_t));          // Wrap it around the end
    return true;                                                                // Indicate there is a char in buffer
  }else
    return false;                                                                // Indicate there is no char in buffer
};

//bool driverHWUART2GetChar(char *character) {
//	static uint32_t bufferTail = 0;
//	__IO uint32_t a = 0;
//	__IO uint32_t b = 0;
//	uint32_t usb_start_time;
//	__IO uint32_t bufferHead = 0;
//	usb_start_time = HAL_GetTick();// Initiate tail to 0
//	uint32_t cndtr_buf = driverHWUART2HDMAHandleRX.Instance->CNDTR;
//
//	if(driverHWUART2Receive_CNDTR_resetFlag){
//		bufferTail = 0;
//		driverHWUART2Receive_CNDTR_resetFlag = 0;
//		//bufferHead = 0;
//
//	}
//
//	//uint32_t bufferHead = sizeof(driverHWUART2ReceiveBuffer)/sizeof(uint8_t) - driverHWUART2HDMAHandleRX.Instance->CNDTR; // Tranform to be transferred bytes to bytes transferred.
//	bufferHead = sizeof(driverHWUART2ReceiveBuffer)/sizeof(uint8_t) - driverHWUART2Receive_CNDTR; // Tranform to be transferred bytes to bytes transferred.
//	// 1024 - 1016 = 8
//	a = bufferHead - bufferTail;
//	if(a != 0) {
//		*character = driverHWUART2ReceiveBuffer_usb[bufferTail];
//		bufferTail++;
//
//		bufferTail %= (sizeof(driverHWUART2ReceiveBuffer)/sizeof(uint8_t));
//		return true;
//	} else{
//		if(driverHWUART2Receive_CNDTR < 1000) {
//			return false;
//		}
//		return false;																																// Indicate there is no char in buffer
//	}
//	//if(bufferTail != bufferHead) {																									// If head and tail differs there is something in the buffer
//	//while (bufferTail != bufferHead) {
////	//if(bufferTail < 20) {
////		//*character = driverHWUART2ReceiveBuffer[bufferTail];												// Get char from tail of buffer
////		*character = driverHWUART2ReceiveBuffer_usb[bufferTail];
////		bufferTail++;
////		 // Move the tail forward
////		bufferTail %= (sizeof(driverHWUART2ReceiveBuffer)/sizeof(uint8_t));					// Wrap it around the end
////		// bufferTail = bufferTail % 1024
////		// bufferTail = 1024 % 1024 = 0
////		return true;																																// Indicate there is a char in buffer
////	}else{
////		if(driverHWUART2Receive_CNDTR < 1000) {
////			return false;
////		}
////		return false;																																// Indicate there is no char in buffer
////	}
//};

//void driverHWUART2SendChar(uint8_t character) {
//	//HAL_UART_Transmit(&driverHWUART2Handle,&character,sizeof(character)/sizeof(uint8_t),10);	// Send single char over serial port
////	CDC_Transmit_FS(character, 1);
//	  uint8_t testDataToSend[8];
//	 // for (uint8_t i = 0; i < 8; i++)
//	 // {
//	 //     testDataToSend[i] = i;
//	 // }
//
//	  testDataToSend[0] = character;
//	  CDC_Transmit_FS(testDataToSend, 1);
//
//	//uint8_t buf[1];
//	//buf[0] = character;
//	//CDC_Transmit_FS(buf[0], 1);
//};
//
//bool driverHWUART2GetChar(char *character) {
//	static uint32_t bufferTail = 0;																								// Initiate tail to 0
//	uint32_t bufferHead = sizeof(driverHWUART2ReceiveBuffer)/sizeof(uint8_t) - driverHWUART2Receive_CNDTR; // Tranform to be transferred bytes to bytes transferred.
//	if(bufferHead == 12) {
////		bufferTail = 1;
//	}
//	if(bufferTail != bufferHead){																									// If head and tail differs there is something in the buffer
//		*character = driverHWUART2ReceiveBuffer[bufferTail];												// Get char from tail of buffer
//		bufferTail++;																																// Move the tail forward
//		bufferTail %= (sizeof(driverHWUART2ReceiveBuffer)/sizeof(uint8_t));					// Wrap it around the end
//		return true;																																// Indicate there is a char in buffer
//	}else
//		return false;																																// Indicate there is no char in buffer
//};

void DMA1_Channel6_IRQHandler(void) {		 																				// Will trigger on halve and full
// HAL_DMA_IRQHandler(&driverHWUART2HDMAHandleRX);
}
