// ============================================================================
// Copyright (c) 2022 by Terasic Technologies Inc.
// ============================================================================
//
// Permission:
//
//   Terasic grants permission to use and modify this code for use
//   in synthesis for all Terasic Development Boards and Altera Development
//   Kits made by Terasic.  Other use of this code, including the selling
//   ,duplication, or modification of any portion is strictly prohibited.
//
// Disclaimer:
//
//   This VHDL/Verilog or C/C++ source code is intended as a design reference
//   which illustrates how these types of functions can be implemented.
//   It is the user's responsibility to verify their design for
//   consistency and functionality through the use of formal
//   verification methods.  Terasic provides no warranty regarding the use
//   or functionality of this code.
//
// ============================================================================
//
//  Terasic Technologies Inc
//  No.80, Fenggong Rd., Hukou Township, Hsinchu County 303035. Taiwan
//
//
//                     web: http://www.terasic.com/
//                     email: support@terasic.com
//
// ============================================================================


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "io.h"
#include "altera_avalon_pio_regs.h"
#include "system.h"

typedef bool (*LP_VERIFY_FUNC)(void);

bool Show_Board_Info(void);
bool Set_Fan_Speed(void);

typedef struct {
    LP_VERIFY_FUNC func;
    char szName[128];
} FUNC_INFO;

FUNC_INFO szFuncList[] = {
		{ Show_Board_Info, "Show Board Info" },
		{ Set_Fan_Speed, "Set Fan Speed" }
		};

void GUI_ShowMenu(void)
{
    int nNum, i;

    nNum = sizeof(szFuncList) / sizeof(szFuncList[0]);
    printf("======= DE25-Standard Demo Program =======\n");
    for (i = 0; i < nNum; i++) {
        printf("[%d] %s\n", i, szFuncList[i].szName);
    }
    printf("Input your chioce:");
}

int GUI_QueryUser(void)
{
    int nChoice = 0;
    scanf("%d", &nChoice);
    printf("%d\n", nChoice);
    return nChoice;
}

//===============================================================
int main(void)
{
    int nChoice, nStatus;
    int nNum;
    bool bPass;


    // PIO_I2C_READY_BASE
    nStatus = IORD_ALTERA_AVALON_PIO_DATA(PIO_I2C_READY_BASE) & 0x01;
    if (nStatus != 0x01){
    	printf("Failed to query board information!\r\n");
    	return 0;
    }


    nNum = sizeof(szFuncList) / sizeof(szFuncList[0]);
    while (1) {
        GUI_ShowMenu();
        nChoice = GUI_QueryUser();
        if (nChoice >= 0 && nChoice < nNum) {
            bPass = szFuncList[nChoice].func();
            printf("%s Test:%s\n", szFuncList[nChoice].szName,
                   bPass ? "PASS" : "NG");
        }else{
        	printf("%d is a invalid selection!\r\n", nChoice);
        }
    }

}

bool Show_Board_Info(void)
{
    uint16_t fan_speed;
    uint16_t temperature_fpga, temperature_board1, temperature_board2;
    //uint16_t pin_status;

    fan_speed = IORD_ALTERA_AVALON_PIO_DATA(BOARD_INFO_FAN_SPEED_BASE) & 0xFFFF;
    temperature_fpga = IORD_ALTERA_AVALON_PIO_DATA(BOARD_INFO_TEMPERATURE_FPGA_BASE) & 0xFFFF;
    temperature_board1 = IORD_ALTERA_AVALON_PIO_DATA(BOARD_INFO_TEMPERATURE_BOARD1_BASE) & 0xFFFF;
    temperature_board2 = IORD_ALTERA_AVALON_PIO_DATA(BOARD_INFO_TEMPERATURE_BOARD2_BASE) & 0xFFFF;

    printf("==== Temperature ====\n");
    printf("\tFPGA: %d*C\n", temperature_fpga);
    printf("\tBoard 1: %d*C\n", temperature_board1);
    printf("\tBoard 2: %d*C\n", temperature_board2);
    printf("\n");
    printf("==== Fan ====\n");
    printf("\tFan RPM: %d\n", fan_speed);
    printf("\n");

    return true;
}

bool Set_Fan_Speed(void)
{
	bool bSuccess = false;
	return bSuccess;
}
