/* 
    Данный пример демонстирует работу с модулем LTR210.
    По умолчанию идет работа с первым слотом первого крейта, но это можно изменить
        через параметры командной строки:
    ltr210_recv  slot crate_serial srvip
    где:
        slot         - номер слота (от 1 до 16)
        crate_serial - серийный номер крейта (если крейтов больше одного)
        srvip        - ip-адрес LTR-сервера (если не локальный)
    Параметры опциональны: можно указать только слот, слот и серийный номер крейта или все

    Пример принимает данные от двух каналов в режиме периодического покадрового сбора,
    отображает на экране первые 2 слова кадра, а полный кадр сохраняется в
    файл Frame<номер кадра>.txt (по файлу на каждый кадр) в текстовом виде.

    Пользователь может изменить настройки на свои, поменяв заполнение полей
    структуры конфигурации.

    Сбор идет до нажатия любой клавиши на Windows или  CTRL+C на Linux

    Также пример на ОС Windows предполает наличие файла прошивки в директории запуска
    (можно переопределить через LTR210_FPGA_FIRM_FILE).

    Сборка в VisualStudio:
    Для того чтобы собрать проект в Visual Studio, измените путь к заголовочным файлам
    (Проект (Project) -> Свойства (Properties) -> Свойства конфигурации (Configuration Properties)
    -> С/С++ -> Общие (General) -> Дополнительные каталоги включения (Additional Include Directories))
    на тот, где у вас лежат заголовочный файл l502api.h и измените путь к библиотекам
    (Проект (Project) -> Свойства (Properties) -> Свойства конфигурации (Configuration Properties) ->
    Компановщик (Linker) -> Общие (General) -> Дополнительные катологи библиотек (Additional Library Directories)).

    Внимание!: Если Вы собираете проект под Visual Studio и у Вас некорректно
    отображается вывод русских букв, то нужно изменить кодировку:
    выберите Файл (File) -> Доболнительные параметры сохранения (Advanced Save Options)...
    и в поле Кодировка (Encoding) выберите Юникод (UTF8, с сигнатурой)/Unicode (UTF-8 with signature)
    и сохраните изменения в файле.
*/


#include "ltr/include/ltrt13api.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "getopt.h"

#ifdef _WIN32
    #include <locale.h>
#endif

#define ERR_INVALID_USAGE           -1
#define ERR_MODULE_NOT_FOUND        -2

extern LTRT13API_DllExport(INT) LTRT13_WriteInfo(TLTRT13 *hnd);

static int f_get_slot(int *slot, char* serial) {
    TLTR srv;
    int fnd=0;
    INT err = LTR_OK;
    LTR_Init(&srv);
    err=LTR_OpenSvcControl(&srv, LTRD_ADDR_DEFAULT, LTRD_PORT_DEFAULT);
    if (err != LTR_OK) {
        fprintf(stderr, "Не удалось установить связь с LTR-сервером. Ошибка %d: %s!\n",
                err, LTR_GetErrorString(err));
    } else {
        char serial_list[LTR_CRATES_MAX][LTR_CRATE_SERIAL_SIZE];
        err=LTR_GetCrates(&srv, (BYTE*)&serial_list[0][0]);
        LTR_Close(&srv);
        if (err != LTR_OK) {
            fprintf(stderr, "Не удалось получить список крейтов. Ошибка %d: %s!\n",
                    err, LTR_GetErrorString(err));
        } else {
            int crate_ind;
            for (crate_ind = 0 ; (crate_ind < LTR_CRATES_MAX) && !fnd; crate_ind++) {
                if (serial_list[crate_ind][0] != '\0') {
                    TLTR crate;
                    INT crate_err = LTR_OK;
                    LTR_Init(&crate);
                    crate_err = LTR_OpenCrate(&crate, LTRD_ADDR_DEFAULT, LTRD_PORT_DEFAULT,
                                              LTR_CRATE_IFACE_UNKNOWN, serial_list[crate_ind]);
                    if (crate_err == LTR_OK) {
                        WORD mids[LTR_MODULES_PER_CRATE_MAX];
                        crate_err = LTR_GetCrateModules(&crate, mids);
                        if (crate_err == LTR_OK) {
                            int module_ind;
                            for (module_ind = 0; (module_ind < LTR_MODULES_PER_CRATE_MAX) && !fnd; module_ind++) {
                                if (mids[module_ind] == LTR_MID_LTR01) {
                                    WORD subid;
                                    crate_err = LTR01_GetSubID(LTRD_ADDR_DEFAULT, LTRD_PORT_DEFAULT,
                                                               crate.csn, LTR_CC_CHNUM_MODULE1 + module_ind,
                                                               &subid, NULL);
                                    if ((crate_err == LTR_OK) && (subid == LTR01_SUBID_LTRT13)) {
                                        fnd = 1;
                                        strcpy(serial, crate.csn);
                                        *slot = module_ind + LTR_CC_CHNUM_MODULE1;
                                    }
                                }
                            }
                        }
                        LTR_Close(&crate);
                    }
                }
            }
        }
    }

    if (err == LTR_OK) {
        if (!fnd) {
            fprintf(stderr, "Ни одного модуля LTRT10 не было найдено!\n");
            err = ERR_MODULE_NOT_FOUND;
        } else {
            printf("Найден модуль LTRT13: крейт %s, слот %d\n", serial, *slot);
        }
    }
    return err;
}







int main(int argc, char** argv) {
    INT err = LTR_OK, out=0;
    TLTRT13 hltrt13;

    char csn[LTR_CRATE_SERIAL_SIZE];
    int slot=LTR_CC_CHNUM_MODULE1;

#ifdef _WIN32
    /* для вывода русских букв в консоле... */
    setlocale(LC_ALL, "");
#endif
    /* находим нужный модуль */
    if (!err && !out) {
        err = f_get_slot(&slot, csn);
    }

    if (!err && !out) {
        LTRT13_Init(&hltrt13);
        //LTRAPI_SLEEP_MS(10);
        /* устанавливаем соединение с модулем */
        err = LTRT13_Open(&hltrt13, LTRD_ADDR_DEFAULT, LTRD_PORT_DEFAULT, csn, slot);
        if (err != LTR_OK) {
            fprintf(stderr, "Не удалось установить связь с модулем. Ошибка %d (%s)\n",
                    err, LTRT13_GetErrorString(err));
        }

        if (LTRT13_IsOpened(&hltrt13) == LTR_OK) {
            /* после открытия модуля доступна информация, кроме версии прошивки ПЛИС */
            printf("Модуль открыт успешно!\n");
            printf("  Название модуля    = %s\n", hltrt13.ModuleInfo.Name);
            printf("  Серийный номер     = %s\n", hltrt13.ModuleInfo.Serial);
            printf("  Версия PLD         = %d\n", hltrt13.ModuleInfo.VerPLD);

#if 0
            strcpy(hltrt13.ModuleInfo.Serial, "1T728207");
            err = LTRT13_WriteInfo(&hltrt13);
#endif

            //LTRT13_FillExtSyncFreqParams(&hltrt13, 40000, NULL);
            hltrt13.Cfg.ExtSyncFreqDiv = 0x3;
            err = LTRT13_SetExtStartLevel(&hltrt13, TRUE);
            if (err == LTR_OK) {
                err = LTRT13_SetExtStartLevel(&hltrt13, FALSE);
            }
            if (err == LTR_OK) {
                err = LTRT13_SetExtStartLevel(&hltrt13, TRUE);
            }

            if (err == LTR_OK) {
                err = LTRT13_SetExtSyncGenEnabled(&hltrt13, TRUE);
            }

            if (err == LTR_OK) {
                err = LTRT13_SetExtStartLevel(&hltrt13, TRUE);
            }

            if (err == LTR_OK) {
                err = LTRT13_SetExtSyncGenEnabled(&hltrt13, FALSE);
            }

        }

        LTRT13_Close(&hltrt13);
    }

    return err;
}
