/*-------------------------------------------------------------------------------------------------
--
-- File Name    : main.c



-- Description  : This module replicates the HDMI functionality.




-- Targeted device : Microchip FPGAs
-- Author          : India Solutions Team




--
-- COPYRIGHT 2023 BY MICROCHIP
-- THE INFORMATION CONTAINED IN THIS DOCUMENT IS SUBJECT TO LICENSING RESTRICTIONS
-- FROM MICROCHIP CORP.  IF YOU ARE NOT IN POSSESSION OF WRITTEN AUTHORIZATION FROM
-- MICROCHIP FOR USE OF THIS FILE, THEN THE FILE SHOULD BE IMMEDIATELY DESTROYED AND
-- NO BACK-UP OF THE FILE SHOULD BE MADE.
--



-------------------------------------------------------------------------------------------------*/
#include <stdio.h>
#include "hal/hal.h"
#include "miv_rv32_hal/miv_rv32_hal.h"
#include "drivers/fpga_ip/CoreGPIO/core_gpio.h"
#include "drivers/CoreAXI4-Lite/AXI4-Lite.h"
#include "drivers/fpga_ip/CoreI2C/core_i2c.h"
#include "drivers/fpga_ip/CoreI2C/core_i2c.h"
#include "drivers/fpga_ip/CoreUARTapb/core_uart_apb.h"
#define LED1 GPIO_1
#define LED2 GPIO_2
#define LED3 GPIO_3
#define LED4 GPIO_4

void GPIO_settings();
void edid_load_functions();
void hdmi_configuration();
void hdmi_tx_i2c_function();
//void delay();
void hdmi_monitor_tasks();

/*******************************************************************************
 * Types, Constants and Greetings messages
 *******************************************************************************/

const uint8_t g_greeting_msg[] =
"\r\n*********************************************************************************\r\n\n\
****************************    HDMI RX to HDMI TX     ***************************\r\n\n\
*********************************************************************************\r\n\r\n";
/*-----------------------------------------------------------------------------
 * GPIO and UART instance data.
 * ---------------------------------------------------------------------------*/
gpio_instance_t g_gpio_out;
UART_instance_t g_uart;
uint32_t ext_irq=0;
uint32_t g_ext_irq=0;
uint32_t hpd_tx=0;

extern uint32_t prev_hpd_tx_detect;
uint32_t prev_hpd_tx_detect = 0xFFFFFFFF;
/*-----------------------------------------------------------------------------
 * Interrupt handlers.
 * Weakly linked default versions of all the interrupt handlers are defined
 * in miv_rv32_stubs.c.
 */
void External_IRQHandler()
{
    UART_polled_tx_string(&g_uart, (const uint8_t *)&"\r\n\r\nInterrupt received\r\n\r");
    ext_irq=1;
    g_ext_irq=1;
}
void Software_IRQHandler()
{
    MRV_clear_soft_irq();
}
i2c_instance_t g_i2c_instance_hdmitx;

uint8_t MSYS_EI1_IRQHandler(void)
{
    I2C_isr(&g_i2c_instance_hdmitx);
    return (EXT_IRQ_KEEP_ENABLED);
}
void SysTick_Handler(void)
{
    I2C_system_tick(&g_i2c_instance_hdmitx, 10);
}

void reset_hpd_state(void)
{
    prev_hpd_tx_detect = 0xFFFFFFFF;
    UART_polled_tx_string(&g_uart, (const uint8_t *)&"\r\n\r\nprint\r\n\r");
}
/*-------------------------------------------------------------------------//**
  main() function.
 */
int main(void)
{
    /* Initialize UART and GPIO instances */
    UART_init( &g_uart, COREUARTAPB0_BASE_ADDR,\
    BAUD_VALUE_115200, (DATA_8_BITS | NO_PARITY) );
    GPIO_settings();
    /* Greeting message */
    UART_polled_tx_string(&g_uart, g_greeting_msg);

    /* This must be done for all Mi-V cores to enable interrupts globally. */

    //MRV_systick_config(SYS_CLK_FREQ);

    MRV_enable_local_irq(MRV32_MSYS_EIE0_IRQn);
    MRV_enable_local_irq(MRV32_MSYS_EIE1_IRQn);
    MRV_enable_local_irq(MRV32_EXT_IRQn);
    //MRV_enable_local_irq(MRV32_MSYS_EIE1_IRQn);
    HAL_enable_interrupts();
    edid_load_functions();//initialise the edid data
    g_ext_irq=0;
    hdmi_configuration();
do
{
    if(g_ext_irq==1)
    {
        reset_hpd_state();
        g_ext_irq=0;
        UART_polled_tx_string(&g_uart, (const uint8_t *)&"\r\n\r\nInterrupt Cleared "
                "and Reconfiguring HDMI\r\n\r");
        hdmi_configuration();
    }
    hdmi_monitor_tasks();
    //hdmi_tx_i2c_function();
}while(1);
return 0;
}

void GPIO_settings()
{
    GPIO_init(&g_gpio_out, COREGPIO_OUT_BASE_ADDR, GPIO_APB_32_BITS_BUS);
    GPIO_config(&g_gpio_out, GPIO_0, GPIO_OUTPUT_MODE);
    GPIO_config(&g_gpio_out, GPIO_1, GPIO_OUTPUT_MODE);
    GPIO_config(&g_gpio_out, GPIO_2, GPIO_OUTPUT_MODE);
    GPIO_config(&g_gpio_out, GPIO_3, GPIO_OUTPUT_MODE);
    GPIO_config(&g_gpio_out, GPIO_4, GPIO_OUTPUT_MODE);
    GPIO_config(&g_gpio_out, GPIO_5, GPIO_OUTPUT_MODE);

}
double get_speed(void)
{
    uint32_t data_rate;

    data_rate = (uint32_t)axi4literead(DATA_RATE);   // read from hardware

    return (double)data_rate / 10000.0;              // scaled value
}

