/* main.c */
#include "app.h"

extern volatile int core1_coremark;
extern volatile int core1_costtime;

extern volatile float core0_coremark;
extern volatile float core0_costtime;
extern volatile int   core0_powerquadmark;

volatile bool gCoreMarkDone;

char gLcdPrintfBuf[32];


/*******************************************************************************
 * Prototypes
 ******************************************************************************/

void task_pq_fft_128(void);
void task_pq_fft_256(void);
void task_pq_fft_512(void);
void task_end(void);

void (*cAppLcdDisplayPageFunc[])(void) =
{
    task_pq_fft_512,
    task_pq_fft_256,
    task_pq_fft_128  /* merge the last task into this one. */
    //task_end
};

extern volatile int core1_finish_flag;

#define APP_LCD_DEMO_TITLE_BASE_LINE_IDX  0

#define APP_ENABLE_TOUCH_KEY  1 /* 0: for uart input, 1: for touch key input. */

int main(void)
{
    core1_finish_flag = 0u;

    BOARD_InitHardware();
    CLOCK_EnableClock(kCLOCK_InputMux);

    lcd_init();
    uint32_t keyValue    = APP_USER_TASK_COUNT;
# if APP_ENABLE_TOUCH_KEY
    uint32_t keyValuePre = APP_USER_TASK_COUNT;
    App_InitUserKey();
#endif /*  APP_ENABLE_TOUCH_KEY*/
    gCoreMarkDone = false;

    lcd_clear_screen(LCD_COLOR_BLACK);

    lcd_print_string(APP_LCD_DEMO_TITLE_BASE_LINE_IDX, "LPC5500 Benchmark", LCD_COLOR_GREEN);
    lcd_print_string(APP_LCD_DEMO_TITLE_BASE_LINE_IDX+1u, "Dualcore CoreMark & PQ DEMO", LCD_COLOR_GREEN);
    lcd_print_string(APP_LCD_DEMO_TITLE_BASE_LINE_IDX+2u, " press me to continue ...", LCD_COLOR_YELLOW);

    PRINTF("LPC5500 Benchmark Dualcore CoreMark & PQ DEMO\r\n");
    PRINTF("Press any key to continue ...\r\n");

    while (1)
    {
#if APP_ENABLE_TOUCH_KEY
        keyValue = App_GetUserKeyValue();
        if (keyValue != keyValuePre)
        {
            App_DeinitUserKey(); /* disable detecting key when changing the lcd display. */
            (*cAppLcdDisplayPageFunc[keyValue])(); /* switch to new page on lcd module. */
            keyValuePre = keyValue;
            App_InitUserKey(); /* enable detecting key for next event. */
        }

        __WFI(); /* sleep when in idle. */
#else
        GETCHAR();
        if (keyValue >= APP_USER_TASK_COUNT)
        {
            keyValue = 0u;
        }
        else
        {
            keyValue = (keyValue + 1u) % APP_USER_TASK_COUNT;
        }
        (*cAppLcdDisplayPageFunc[keyValue])(); /* switch to new page on lcd module. */
#endif
    } /* end while(1) */
}

//#define APP_LCD_CORE1_INFO_BASE_LINE_IDX  (APP_LCD_DEMO_TITLE_BASE_LINE_IDX+3u)
//#define APP_LCD_FFT_512_BASE_LINE_IDX  (APP_LCD_CORE1_INFO_BASE_LINE_IDX+3u)
#define APP_LCD_FFT_512_BASE_LINE_IDX  (APP_LCD_DEMO_TITLE_BASE_LINE_IDX+3u)
void task_pq_fft_512(void)
{
    PRINTF("-> %s\r\n", __func__);

    lcd_print_string(APP_LCD_DEMO_TITLE_BASE_LINE_IDX+2u, " press me to continue ...", LCD_COLOR_BLACK);
    lcd_print_string(APP_LCD_DEMO_TITLE_BASE_LINE_IDX+2u, "********** START **********", LCD_COLOR_YELLOW);

    //sprintf(gLcdPrintfBuf, "CORE 1 ->>");
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX, gLcdPrintfBuf, LCD_COLOR_BLUE | LCD_COLOR_RED);
    //sprintf(gLcdPrintfBuf, "computing ...");
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX+1u, gLcdPrintfBuf, LCD_COLOR_BLUE | LCD_COLOR_RED);

    sprintf(gLcdPrintfBuf, "---------------------------");
    lcd_print_string(APP_LCD_FFT_512_BASE_LINE_IDX, gLcdPrintfBuf, LCD_COLOR_YELLOW);
    sprintf(gLcdPrintfBuf, "CORE 0 with PQ FFT_512 ->>");
    lcd_print_string(APP_LCD_FFT_512_BASE_LINE_IDX+1, gLcdPrintfBuf, LCD_COLOR_YELLOW);
    sprintf(gLcdPrintfBuf, "computing ...");
    lcd_print_string(APP_LCD_FFT_512_BASE_LINE_IDX+2, gLcdPrintfBuf, LCD_COLOR_YELLOW);


    gCoreMarkDone = false;
    App_PQInstallCallback(App_PQTask_CFFT512Case);
    coremark_start();

    while (!gCoreMarkDone)
    {
    }

    /* info for core 1. */
    //sprintf(gLcdPrintfBuf, "computing ...");
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX+2u, gLcdPrintfBuf, LCD_COLOR_BLACK);

    //sprintf(gLcdPrintfBuf, " CORE 1 coremark: %d\r\n", core1_coremark);
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX+1, gLcdPrintfBuf, LCD_COLOR_BLUE | LCD_COLOR_RED);

    //sprintf(gLcdPrintfBuf, "---------------------------");
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX+2u, gLcdPrintfBuf, LCD_COLOR_BLUE | LCD_COLOR_RED);

    PRINTF("********** REPORT **********\r\n");
    PRINTF(" CORE 0 coremark: %d\r\n", (uint32_t)core0_coremark);
    PRINTF(" CORE 1 coremark: %d\r\n", core1_coremark);
    PRINTF(" PQ Task C/sec  : %d\r\n", (uint32_t)(core0_powerquadmark / core0_costtime) );
    PRINTF("*********** DONE ***********\r\n");
    PRINTF("\r\n");
    PRINTF(" Press any key to continue ...\r\n");
    PRINTF("\r\n\r\n");

    /* info for core 0, fft-512. */
    sprintf(gLcdPrintfBuf, "computing ...");
    lcd_print_string(APP_LCD_FFT_512_BASE_LINE_IDX+2, gLcdPrintfBuf, LCD_COLOR_BLACK);

    sprintf(gLcdPrintfBuf, " CORE 0 coremark: %d\r\n", (uint32_t)core0_coremark);
    lcd_print_string(APP_LCD_FFT_512_BASE_LINE_IDX+2, gLcdPrintfBuf, LCD_COLOR_RED);

    sprintf(gLcdPrintfBuf, " CORE 1 coremark: %d\r\n", core1_coremark);
    lcd_print_string(APP_LCD_FFT_512_BASE_LINE_IDX+3, gLcdPrintfBuf, LCD_COLOR_BLUE | LCD_COLOR_RED);

    sprintf(gLcdPrintfBuf, " PQ Task C/sec  : %d\r\n", (uint32_t)(core0_powerquadmark / core0_costtime) );
    lcd_print_string(APP_LCD_FFT_512_BASE_LINE_IDX+4, gLcdPrintfBuf, LCD_COLOR_BLUE);

    sprintf(gLcdPrintfBuf, "---------------------------");
    lcd_print_string(APP_LCD_FFT_512_BASE_LINE_IDX+5, gLcdPrintfBuf, LCD_COLOR_YELLOW);

    lcd_print_string(APP_LCD_FFT_512_BASE_LINE_IDX+6, " press me to continue ...", LCD_COLOR_YELLOW);
}

#define APP_LCD_FFT_256_BASE_LINE_IDX  (APP_LCD_FFT_512_BASE_LINE_IDX+6)

void task_pq_fft_256(void)
{
    PRINTF("-> %s\r\n", __func__);

    //sprintf(gLcdPrintfBuf, " CORE 1 coremark: %d\r\n", core1_coremark);
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX+1, gLcdPrintfBuf, LCD_COLOR_BLACK);
    //sprintf(gLcdPrintfBuf, "computing ...");
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX+1u, gLcdPrintfBuf, LCD_COLOR_BLUE | LCD_COLOR_RED);

    lcd_print_string(APP_LCD_FFT_256_BASE_LINE_IDX, " press me to continue ...", LCD_COLOR_BLACK);

    sprintf(gLcdPrintfBuf, "CORE 0 with PQ FFT_256 ->>");
    lcd_print_string(APP_LCD_FFT_256_BASE_LINE_IDX, gLcdPrintfBuf, LCD_COLOR_YELLOW);
    sprintf(gLcdPrintfBuf, "computing ...");
    lcd_print_string(APP_LCD_FFT_256_BASE_LINE_IDX+1u, gLcdPrintfBuf, LCD_COLOR_YELLOW);


    gCoreMarkDone = false;
    App_PQInstallCallback(App_PQTask_CFFT256Case);
    coremark_start();

    while (!gCoreMarkDone)
    {
    }

    /* info for core 1. */
    //sprintf(gLcdPrintfBuf, "computing ...");
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX+1u, gLcdPrintfBuf, LCD_COLOR_BLACK);

    //sprintf(gLcdPrintfBuf, " CORE 1 coremark: %d\r\n", core1_coremark);
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX+1, gLcdPrintfBuf, LCD_COLOR_BLUE | LCD_COLOR_RED);

    PRINTF("********** REPORT **********\r\n");
    PRINTF(" CORE 0 coremark: %d\r\n", (uint32_t)core0_coremark);
    PRINTF(" CORE 1 coremark: %d\r\n", core1_coremark);
    PRINTF(" PQ Task C/sec  : %d\r\n", (uint32_t)(core0_powerquadmark / core0_costtime) );
    PRINTF("*********** DONE ***********\r\n");
    PRINTF("\r\n");
    PRINTF(" Press any key to continue ...\r\n");
    PRINTF("\r\n\r\n");

    /* info for the core 0. */
    sprintf(gLcdPrintfBuf, "computing ...");
    lcd_print_string(APP_LCD_FFT_256_BASE_LINE_IDX+1u, gLcdPrintfBuf, LCD_COLOR_BLACK);

    sprintf(gLcdPrintfBuf, " CORE 0 coremark: %d\r\n", (uint32_t)core0_coremark);
    lcd_print_string(APP_LCD_FFT_256_BASE_LINE_IDX+1u, gLcdPrintfBuf, LCD_COLOR_RED);

    sprintf(gLcdPrintfBuf, " CORE 1 coremark: %d\r\n", core1_coremark);
    lcd_print_string(APP_LCD_FFT_256_BASE_LINE_IDX+2, gLcdPrintfBuf, LCD_COLOR_BLUE | LCD_COLOR_RED);

    sprintf(gLcdPrintfBuf, " PQ Task C/sec  : %d\r\n", (uint32_t)(core0_powerquadmark / core0_costtime) );
    lcd_print_string(APP_LCD_FFT_256_BASE_LINE_IDX+3, gLcdPrintfBuf, LCD_COLOR_BLUE);

    sprintf(gLcdPrintfBuf, "---------------------------");
    lcd_print_string(APP_LCD_FFT_256_BASE_LINE_IDX+4, gLcdPrintfBuf, LCD_COLOR_YELLOW);

    lcd_print_string(APP_LCD_FFT_256_BASE_LINE_IDX+5, " press me to continue ...", LCD_COLOR_YELLOW);
}

#define APP_LCD_FFT_128_BASE_LINE_IDX  (APP_LCD_FFT_256_BASE_LINE_IDX+5)

void task_pq_fft_128(void)
{
    PRINTF("-> %s\r\n", __func__);

    //sprintf(gLcdPrintfBuf, " CORE 1 coremark: %d\r\n", core1_coremark);
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX+1, gLcdPrintfBuf, LCD_COLOR_BLACK);
    //sprintf(gLcdPrintfBuf, "computing ...");
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX+1u, gLcdPrintfBuf, LCD_COLOR_BLUE | LCD_COLOR_RED);

    lcd_print_string(APP_LCD_FFT_128_BASE_LINE_IDX, " press me to continue ...", LCD_COLOR_BLACK);

    sprintf(gLcdPrintfBuf, "CORE 0 with PQ FFT_128 ->>");
    lcd_print_string(APP_LCD_FFT_128_BASE_LINE_IDX, gLcdPrintfBuf, LCD_COLOR_YELLOW);
    sprintf(gLcdPrintfBuf, "computing ...");
    lcd_print_string(APP_LCD_FFT_128_BASE_LINE_IDX+1, gLcdPrintfBuf, LCD_COLOR_YELLOW);

    gCoreMarkDone = false;
    App_PQInstallCallback(App_PQTask_CFFT128Case);
    coremark_start();

    while (!gCoreMarkDone)
    {
    }

    /* info for core 1. */
    //sprintf(gLcdPrintfBuf, "computing ...");
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX+1u, gLcdPrintfBuf, LCD_COLOR_BLACK);

    //sprintf(gLcdPrintfBuf, " CORE 1 coremark: %d\r\n", core1_coremark);
    //lcd_print_string(APP_LCD_CORE1_INFO_BASE_LINE_IDX+1, gLcdPrintfBuf, LCD_COLOR_BLUE | LCD_COLOR_RED);

    PRINTF("********** REPORT **********\r\n");
    PRINTF(" CORE 0 coremark: %d\r\n", (uint32_t)core0_coremark);
    PRINTF(" CORE 1 coremark: %d\r\n", core1_coremark);
    PRINTF(" PQ Task C/sec  : %d\r\n", (uint32_t)(core0_powerquadmark / core0_costtime) );
    PRINTF("*********** DONE ***********\r\n");
    PRINTF("\r\n");
    PRINTF(" Press any key to continue ...\r\n");
    PRINTF("\r\n\r\n");

    /* info for the core 0. */
    sprintf(gLcdPrintfBuf, "computing ...");
    lcd_print_string(APP_LCD_FFT_128_BASE_LINE_IDX+1, gLcdPrintfBuf, LCD_COLOR_BLACK);

    sprintf(gLcdPrintfBuf, " CORE 0 coremark: %d\r\n", (uint32_t)core0_coremark);
    lcd_print_string(APP_LCD_FFT_128_BASE_LINE_IDX+1, gLcdPrintfBuf, LCD_COLOR_RED);

    sprintf(gLcdPrintfBuf, " CORE 1 coremark: %d\r\n", core1_coremark);
    lcd_print_string(APP_LCD_FFT_128_BASE_LINE_IDX+2, gLcdPrintfBuf, LCD_COLOR_BLUE | LCD_COLOR_RED);

    sprintf(gLcdPrintfBuf, " PQ Task C/sec  : %d\r\n", (uint32_t)(core0_powerquadmark / core0_costtime) );
    lcd_print_string(APP_LCD_FFT_128_BASE_LINE_IDX+3, gLcdPrintfBuf, LCD_COLOR_BLUE);

    sprintf(gLcdPrintfBuf, "---------------------------");
    lcd_print_string(APP_LCD_FFT_128_BASE_LINE_IDX+4, gLcdPrintfBuf, LCD_COLOR_YELLOW);

    task_end(); /* merge the last task into this one. */
}

void task_end(void)
{
    PRINTF("%s\r\n", __func__);

    lcd_print_string(APP_LCD_FFT_128_BASE_LINE_IDX+5, "*********** END ***********", LCD_COLOR_YELLOW);

    while (1)
    {
        __WFI(); /* sleep forever. */
    }
}

void lcd_print_string(uint16_t line_idx, char *buf, uint16_t hwColor)
{
    uint16_t y = line_idx * 16u;
    uint16_t x = 0u;

    while (x < (LCD_WIDTH-16u) )
    {
        lcd_display_char(x, y, *buf++, LCD_FONT_1608, hwColor);
        if (*buf == '\0')
        {
            break;
        }
        else if ( (*buf == '\r') || (*buf == '\n') )
        {
            break;
        }
        else
        {
            x += 8u;
        }
    }
}

/* EOF. */

