// From STM 2 Board UART with DMA example

#include <stm32h7xx_hal.h>
#include <stm32_hal_legacy.h>

#include "UARTs.hpp"

#define BSP_ERROR_NONE                    0
#define BSP_ERROR_NO_INIT                -1
#define BSP_ERROR_WRONG_PARAM            -2
#define BSP_ERROR_BUSY                   -3
#define BSP_ERROR_PERIPH_FAILURE         -4
#define BSP_ERROR_COMPONENT_FAILURE      -5
#define BSP_ERROR_UNKNOWN_FAILURE        -6
#define BSP_ERROR_UNKNOWN_COMPONENT      -7 
#define BSP_ERROR_BUS_FAILURE            -8 
#define BSP_ERROR_CLOCK_FAILURE          -9  
#define BSP_ERROR_MSP_FAILURE            -10  
#define BSP_ERROR_FEATURE_NOT_SUPPORTED  -11

extern "C" void SysTick_Handler(void)
{
	HAL_IncTick();
	HAL_SYSTICK_IRQHandler();
}

typedef enum
{
	greenLED = 0,
	yellowLED = 1,
	redLED = 2,
	numLEDs
}LEDName;

static GPIO_TypeDef* LED_PORT[numLEDs] = {
	GPIOB,
	GPIOE,
	GPIOB
};

static const uint16_t LED_PIN[numLEDs] = {
	GPIO_PIN_0,
	GPIO_PIN_1,
	GPIO_PIN_14
};

static void SystemClock_Config(void);
static void Error_Handler(void);
static void CPU_CACHE_Enable(void);
void initLEDs();
int32_t  turnLEDOn(LEDName Led);
int32_t  turnLEDOff(LEDName Led);

extern "C" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
	__NOP();
}

int main(void)
{
	USART2Class gps1;
	
	CPU_CACHE_Enable();
	HAL_Init();
	
	gps1.initUSART2(&UartHandle);

	initLEDs();
	turnLEDOff(greenLED);
	turnLEDOff(yellowLED);
	turnLEDOff(redLED);

	for (int i = 0; i < 5; i++)
	{
		turnLEDOn(greenLED);
		HAL_Delay(250);
		turnLEDOn(yellowLED);
		HAL_Delay(250);
		turnLEDOn(redLED);
		HAL_Delay(250);
		turnLEDOff(greenLED);
		turnLEDOff(yellowLED);
		turnLEDOff(redLED);
		HAL_Delay(250);
	}

	gps1.txrx();
	
	__NOP();
	
	while (1)
	{
		__NOP();
	}
}

static void Error_Handler(void)
{
	/* Turn LED3 on */
	//BSP_LED_On(redLED);

	while (1)
	{
	}  
}

static void CPU_CACHE_Enable(void)
{
	/* Enable I-Cache */
	SCB_EnableICache();

	/* Enable D-Cache */
	SCB_EnableDCache();
}

void initLEDs()
{
	GPIO_InitTypeDef  gpio_init_structure;

	/* Enable the GPIO green LED Clock */
	__HAL_RCC_GPIOB_CLK_ENABLE();

	/* Enable the GPIO yellow LED Clock */
	__HAL_RCC_GPIOE_CLK_ENABLE();

	/* Enable the GPIO green LED Clock */
	__HAL_RCC_GPIOB_CLK_ENABLE();


	/* Configure the green LED pin */
	gpio_init_structure.Pin = GPIO_PIN_0;
	gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
	gpio_init_structure.Pull = GPIO_NOPULL;
	gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(GPIOB, &gpio_init_structure);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);

	/* Configure the yellow LED pin */
	gpio_init_structure.Pin = GPIO_PIN_1;
	gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
	gpio_init_structure.Pull = GPIO_NOPULL;
	gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(GPIOE, &gpio_init_structure);
	HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);

	/* Configure the red LED pin */
	gpio_init_structure.Pin = GPIO_PIN_14;
	gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
	gpio_init_structure.Pull = GPIO_NOPULL;
	gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(GPIOB, &gpio_init_structure);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);

}

int32_t turnLEDOff(LEDName Led)
{
	int32_t ret = BSP_ERROR_NONE;

	if ((Led != greenLED) && (Led != yellowLED) && (Led != redLED))
	{
		ret = BSP_ERROR_WRONG_PARAM;
	}
	else
	{
		HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
	}

	return ret;
}

int32_t turnLEDOn(LEDName Led)
{
	int32_t ret = BSP_ERROR_NONE;

	if ((Led != greenLED) && (Led != yellowLED) && (Led != redLED))
	{
		ret = BSP_ERROR_WRONG_PARAM;
	}
	else
	{
		HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
	}

	return ret;
}
