#include "ltrmodule_fpga_autoload.h"
#include "ltrmodule.h"
#include "ltimer.h"


#define CMD_ROMIO             (LTR010CMD | 0x60UL)
#define CMD_EN_FPGA           (LTR010CMD_INSTR | 0x22)

INT ltrmodule_fpga_get_state(TLTR *hnd, BYTE* status) {
    DWORD cmd = CMD_ROMIO;
    DWORD ack;
    INT res;
    res = ltr_module_send_with_echo_resps(hnd, &cmd, 1, &ack);
    if (res==LTR_OK) {
        *status = LTR_MODULE_CMD_GET_DATA(ack) & 0xF;
    }
    return res;
}

/* Получение кода ошибки по текущему состоянию FPGA */
static INT f_fpga_get_state_res(e_LTR_FPGA_STATE state) {
    switch (state) {
        case LTR_FPGA_STATE_LOAD_PROGRESS:
            return LTR_ERROR_FPGA_AUTOLOAD_TOUT;
        case LTR_FPGA_STATE_CONF_DONE_TOUT:
            return LTR_ERROR_FPGA_LOAD_DONE_TOUT;
        case LTR_FPGA_STATE_NSTATUS_TOUT:
            return LTR_ERROR_FPGA_LOAD_READY_TOUT;
        case LTR_FPGA_STATE_NO_POWER:
            return LTR_ERROR_FPGA_NO_POWER;
        case LTR_FPGA_STATE_LOAD_DONE:
        case LTR_FPGA_STATE_WORK:
            return LTR_OK;
        default:
            return LTR_ERROR_FPGA_INVALID_STATE;
    }
}

INT ltrmodule_fpga_check_load(TLTR *hnd, BYTE *state) {
    INT err=LTR_OK;
    t_ltimer tmr;
    BYTE fpga_state = LTR_FPGA_STATE_LOAD_PROGRESS;

    ltimer_set(&tmr, LTIMER_MS_TO_CLOCK_TICKS(3000));

    while ((err==LTR_OK) && (fpga_state==LTR_FPGA_STATE_LOAD_PROGRESS) &&
           !ltimer_expired(&tmr)) {
        err = ltrmodule_fpga_get_state(hnd, &fpga_state);
    }


    if (err==LTR_OK)
        err = f_fpga_get_state_res(fpga_state);

    if (state!=NULL)
        *state = fpga_state;
    return err;
}


BOOL ltrmodule_fpga_is_enabled(e_LTR_FPGA_STATE state) {
    return state & 0x8 ? 1 : 0;
}


INT ltrmodule_fpga_enable(TLTR *hnd, BOOL en, BYTE *state) {
    INT err = LTR_OK;
    DWORD cmd = LTR_MODULE_MAKE_CMD(CMD_EN_FPGA, en ? 1 : 0);
    BYTE fpga_state;

    err = ltr_module_send_cmd(hnd, &cmd, 1);

    if (err==LTR_OK) {

        err = ltrmodule_fpga_get_state(hnd, &fpga_state);
    }

    if (err==LTR_OK) {
        BOOL is_en = ltrmodule_fpga_is_enabled(fpga_state);
        if (is_en!=en)
            err = LTR_ERROR_FPGA_ENABLE;
    }

    if (!err && (state!=NULL)) {
        *state = fpga_state;
    }
    return err;
}
