/*
 * Copyright 2021 MindMotion Microelectronics Co., Ltd.
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "board_init.h"

/*
 * Macros.
 */

#define APP_X25Q_SECTOR_SIZE    4096u
#define APP_X25Q_PAGE_SIZE      256u

/*
 * Variables.
 */

uint32_t app_sector_index = 0; /* sector index of x25q test. */
uint32_t app_page_index = 0; /* page index of x25q test. */
uint8_t  app_read_buf[APP_X25Q_PAGE_SIZE];
uint8_t  app_write_buf[APP_X25Q_PAGE_SIZE];

const char str_erase_chip[]              = "a. Erase chip, please wait 50s to erase chip done.\r\n";
const char str_erase_sector[]            = "b. Erase Sector.\r\n";
const char str_write_page[]              = "c. Write page.\r\n";
const char str_read_page[]               = "d. Read page.\r\n";
const char str_direct_read[]             = "e. Read page by qspi direct mode.\r\n";
const char str_reset_sector_page_index[] = "f. Reset sector & page index.\r\n";
const char str_change_write_buf[]        = "g. Change write buffer.\r\n";
const char str_change_sector_index[]     = "h. Change sector index.\r\n";
const char str_change_page_index[]       = "i. Change page index.\r\n";
const char str_sector_index[]            = "The sector index is %u.\r\n";
const char str_page_index[]              = "The page index is %u.\r\n";
const char str_done[]                    = "Done.\r\n";

/*
 * Declerations.
 */

void app_x25q_task(uint8_t ch);

/*
 * Functions.
 */



int main(void)
{
    uint8_t ch = 0;
    BOARD_Init();

    printf("qspi x25q basic example.\r\n");

    X25Q_Init();

    /* assig value to app_write_buf. */
    for (uint32_t i = 0u; i < APP_X25Q_PAGE_SIZE; i++)
    {
        app_write_buf[i] = i % 0x100;
    }

    /* print help list. */
    printf(str_erase_chip);
    printf(str_erase_sector);
    printf(str_write_page);
    printf(str_read_page);
    printf(str_direct_read);
    printf(str_reset_sector_page_index);
    printf(str_change_write_buf);
    printf(str_change_sector_index);
    printf(str_change_page_index);

    while (1)
    {
        ch = getchar();
        app_x25q_task(ch);
    }
}

void app_x25q_task(uint8_t ch)
{
    switch(ch)
    {
        case 'a': /* erase chip. */
            printf(str_erase_chip);
            X25Q_EraseChip(X25Q_Device_W25Q64);
            printf(str_done);
            break;
        case 'b':  /* erase sector. */
            printf(str_erase_sector);
            printf(str_sector_index, (unsigned)app_sector_index);
            X25Q_EraseSector(X25Q_Device_W25Q64, app_sector_index * APP_X25Q_SECTOR_SIZE);
            printf(str_done);
            break;
        case 'c':  /* write page. */
            printf(str_write_page);
            printf(str_sector_index, (unsigned)app_sector_index);
            printf(str_page_index, (unsigned)app_page_index);
            X25Q_WritePage(X25Q_Device_W25Q64, app_sector_index * APP_X25Q_SECTOR_SIZE + app_page_index * APP_X25Q_PAGE_SIZE, APP_X25Q_PAGE_SIZE, app_write_buf);
            printf(str_done);
            break;
        case 'd':  /* read data. */
            printf(str_read_page);
            printf(str_sector_index, (unsigned)app_sector_index);
            printf(str_page_index, (unsigned)app_page_index);
            X25Q_ReadData(X25Q_Device_W25Q64, app_sector_index * APP_X25Q_SECTOR_SIZE + app_page_index * APP_X25Q_PAGE_SIZE, APP_X25Q_PAGE_SIZE, app_read_buf);
            for(uint32_t i = 0; i < 256u; i++) /* print read. */
            {
                if (0 == i % 16u)
                {
                    printf("\r\n");
                }
                printf("%02X ", app_read_buf[i]);
            }
            printf("\r\n");
            printf(str_done);
            break;
        case 'e':  /* read data direct mode. */
            printf(str_direct_read);
            printf(str_sector_index, (unsigned)app_sector_index);
            printf(str_page_index, (unsigned)app_page_index);
            for(uint32_t i = 0; i < 256u; i++) /* print read. */
            {
                if (0 == i % 16u)
                {
                    printf("\r\n");
                }
                printf("%02X ", QSPI_GetDirectData8b(BOARD_QSPI_PORT, app_sector_index * APP_X25Q_SECTOR_SIZE + app_page_index * APP_X25Q_PAGE_SIZE + i) );
            }
            printf("\r\n");
            printf(str_done);
            break;
        case 'f':  /* reset sector & page index. */
            printf(str_reset_sector_page_index);
            app_sector_index = 0;
            app_page_index = 0;
            printf(str_sector_index, (unsigned)app_sector_index);
            printf(str_page_index, (unsigned)app_page_index);
            break;
        case 'g': /* chage write data. */
            printf(str_change_write_buf);
            for(uint32_t i = 0; i < 256u; i++)
            {
                if (0 == i % 16u)
                {
                    printf("\r\n");
                }
                uint32_t temp = app_write_buf[i] + 1u;
                app_write_buf[i] = temp & 0xffu;
                printf("%02X ", app_write_buf[i]);
            }
            printf("\r\n");
            break;
        case 'h': /* inc sector index. */
            printf(str_change_sector_index);
            app_sector_index++;
            app_sector_index &= 0xff;
            printf(str_sector_index, (unsigned)app_sector_index);
            break;
        case 'i': /* inc page index. */
            printf(str_change_page_index);
            app_page_index++;
            app_page_index &= 0x0f;
            printf(str_page_index, (unsigned)app_page_index);
            break;
        default: /* print help. */
            printf(str_erase_chip);
            printf(str_erase_sector);
            printf(str_write_page);
            printf(str_read_page);
            printf(str_direct_read);
            printf(str_reset_sector_page_index);
            printf(str_change_write_buf);
            printf(str_change_sector_index);
            printf(str_change_page_index);
            break;
    }
}

/* EOF. */
