/*
 * PrimaryMCU_Test.c
 *
 *  Created on: 2020�~4��21��
 *      Author: Wendell
 */

#include "PrimaryMCU_Test.h"

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>                 //write, close, usleep, read
#include <sys/ioctl.h>
#include <fcntl.h>                  //uart
#include <termios.h>                //uart

int PrimaryMcuPort;
char *PrimaryPortName = "/dev/ttyS1";

//================================================
// Open Primary MCU Port
//================================================
int OpenPrimaryMcuPort()
{
    int fd;
    struct termios tios;

    fd = open(PrimaryPortName, O_RDWR);
    if(fd<=0)
    {
        #ifdef SystemLogMessage
        DEBUG_ERROR("open 407 Communication port NG \n");
        #endif
        return -1;
    }
    ioctl (fd, TCGETS, &tios);
    tios.c_cflag = B115200| CS8 | CLOCAL | CREAD;
    tios.c_lflag = 0;
    tios.c_iflag = 0;
    tios.c_oflag = 0;
    tios.c_cc[VMIN]=0;
    tios.c_cc[VTIME]=(unsigned char)1;
    tios.c_lflag=0;
    tcflush(fd, TCIFLUSH);
    ioctl (fd, TCSETS, &tios);

    return fd;
}

void ClosePrimaryPort()
{
    close(PrimaryMcuPort);
}

unsigned char Query_FW_Ver(void)
{
    int i = 0;
    unsigned char result = 0;
    unsigned char tx[7] = {0xaa, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00};
    unsigned char rx[512];
    unsigned char chksum = 0x00;
    unsigned char len;

    tcflush(PrimaryMcuPort, TCIOFLUSH);
    write(PrimaryMcuPort, tx, 7);
    usleep(50000);
    len = read(PrimaryMcuPort, rx, 512);

    if(len > 0)
    {
        for(i = 0; i < (rx[4] | rx[5]<<8); i++)
        {
            chksum ^= rx[6 + i];
        }

        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
           (rx[2] == tx[1]) &&
           (rx[1] == tx[2]) &&
           (rx[3] == tx[3]))
        {
            //printf("\r\nPrimary Rx:");
            //for(i = 0; i < len; i++)
            //{
            //    printf(" %02X", rx[i]);
            //}

            printf("\r\nPrimary FW: %s", &rx[6]);

            result = 1;
        }
    }

    return result;
}

unsigned char Run_Self_Test_Item(uint8_t *accept)
{
    int i = 0;
    unsigned char result = 0;
    unsigned char tx[8] = {0xaa, 0x00, 0x04, 0x92, 0x01, 0x00, 0x01, 0x01};
    unsigned char rx[512];
    unsigned char chksum = 0x00;
    unsigned char len;

    tcflush(PrimaryMcuPort, TCIOFLUSH);
    write(PrimaryMcuPort, tx, 8);
    usleep(50000);
    len = read(PrimaryMcuPort, rx, 512);

    *accept = 0;

    if(len > 0)
    {
        for(i = 0; i < (rx[4] | rx[5]<<8); i++)
        {
            chksum ^= rx[6 + i];
        }

        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
           (rx[2] == tx[1]) &&
           (rx[1] == tx[2]) &&
           (rx[3] == tx[3]))
        {
            *accept = rx[6];

            //printf("\r\nSelf Test Rx:");
            //for(i = 0; i < len; i++)
            //{
            //    printf(" %02X", rx[i]);
            //}

            result = 1;
        }
    }

    return result;
}

unsigned char Get_Self_Test_Result(uint8_t *status, uint16_t *fail)
{
    int i = 0;
    unsigned char result = 0;
    unsigned char tx[7] = {0xaa, 0x00, 0x04, 0x32, 0x00, 0x00, 0x00};
    unsigned char rx[512];
    unsigned char chksum = 0x00;
    unsigned char len;

    tcflush(PrimaryMcuPort, TCIOFLUSH);
    write(PrimaryMcuPort, tx, 7);
    usleep(50000);
    len = read(PrimaryMcuPort, rx, 512);

    if(len > 0)
    {
        for(i = 0; i < (rx[4] | rx[5]<<8); i++)
        {
            chksum ^= rx[6 + i];
        }

        if((chksum == rx[6+(rx[4] | rx[5]<<8)]) &&
           (rx[2] == tx[1]) &&
           (rx[1] == tx[2]) &&
           (rx[3] == tx[3]))
        {
            *status = rx[6];
            *fail = rx[7] + (rx[8] << 8);

            //printf("\r\nTest Result Rx:");
            //for(i = 0; i < len; i++)
            //{
            //    printf(" %02X", rx[i]);
            //}

            result = 1;
        }
    }

    return result;
}

void DoPrimaryMCUTest(void)
{
    int i = 0;
    uint8_t accept = 0, status = 0;
    uint16_t fail_item = 0;

    PrimaryMcuPort = OpenPrimaryMcuPort();

    if(Run_Self_Test_Item(&accept) == 0)
    {
        usleep(100000);

        if(Run_Self_Test_Item(&accept) == 0)
        {
            ClosePrimaryPort();
            printf("\r\nPrimary Run Self Test Fail");
            return;
        }
    }

    if(accept == 0)
    {
        printf("\r\nSelf Test Reject, Test Fail");
        ClosePrimaryPort();
        return;
    }

    for(i = 0; i < 100; i++)
    {
        status = 0;
        fail_item = 0;
        Get_Self_Test_Result(&status, &fail_item);

        if(status == 2)
        {
            usleep(100000);
        }
        else
        {
            break;
        }
    }

    ClosePrimaryPort();

    if(status == 0)
    {
        printf("\r\nSelf Test Fail, Fail Item: 0x%04X", fail_item);
        return;
    }
    else if(status != 1)
    {
        printf("\r\nSelf Test Fail, Timeout");
        return;
    }

    printf("\r\nPrimary MCU Self Test OK");

    printf("\r\nPrimary Test Done!");
    printf("\r\nSuccess!\r\n");
}