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

    Пример принимает данные от первых трех каналов на максимальной частоте сбора.
    На экране отображается значение пик-пик (максимум - минимум) по принятому блоку
    по каждому каналу.

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

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

    Сборка в VisualStudio:
    Для того чтобы собрать проект в Visual Studio, измените путь к заголовочным файлам
    (Проект (Project) -> Свойства (Properties) -> Свойства конфигурации (Configuration Properties)
    -> С/С++ -> Общие (General) -> Дополнительные каталоги включения (Additional Include Directories))
    на нужный в зависимаости от пути установки библиотек (ltr25api.h  и остальные заголовочные
    файлы должны находится в поддиректории ltr/include относительно указанного пути)
    и измените путь к .lib файлам на <путь установки библиотек>/lib/msvc
    (Проект (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/ltr25api.h"
#include "ltr/include/lpw25api.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <locale.h>
#include <conio.h>
#else
#include <signal.h>
#include <unistd.h>
#endif



typedef struct {
    int slot;
    const char *serial;
    DWORD addr;
} t_open_param;


int main(int argc, char** argv) {
    INT err = LTR_OK;
    TLTR25 hltr25;
    INT slot = LTR_CC_CHNUM_MODULE1;
    INT ch_num = 1;

#ifdef _WIN32
    /* для вывода русских букв в консоль для ОС Windows*/
    setlocale(LC_ALL, "");
#endif

    if (argc > 1) {
        slot = atoi(argv[1]);
    }
    if (argc > 2) {
        ch_num = atoi(argv[2]);
        if ((ch_num < 1) || (ch_num > 8)) {
           printf("Неверно задан номер канала. Канал должен быть от 1 до 8.\n");
           err = LTR_ERROR_PARAMETERS;
        }
    }

    if (err==LTR_OK) {
        LTR25_Init(&hltr25);
        /* Устанавливаем соединение с модулем */
        err = LTR25_Open(&hltr25, LTRD_ADDR_DEFAULT, LTRD_PORT_DEFAULT, "", slot);
        if (err!=LTR_OK) {
            fprintf(stderr, "Не удалось установить связь с модулем. Ошибка %d (%s)\n",
                    err, LTR25_GetErrorString(err));
        } else {
            INT close_err;
            int ch = ch_num - 1;
            TLTR25_TEDS_NODE_INFO meminfo;


            /* Выводим прочитанную информацию о модуле */
            printf("Модуль открыт успешно! Информация о модуле: \n");
            printf("  Название модуля    = %s\n", hltr25.ModuleInfo.Name);
            printf("  Серийный номер     = %s\n", hltr25.ModuleInfo.Serial);
            printf("  Версия PLD         = %d\n", hltr25.ModuleInfo.VerPLD);
            printf("  Версия ПЛИС        = %d\n", hltr25.ModuleInfo.VerFPGA);
            printf("  Ревизия платы      = %d\n", hltr25.ModuleInfo.BoardRev);
            printf("  Темп. диапазон     = %s\n", hltr25.ModuleInfo.Industrial ? "Индустриальный" : "Коммерческий");
            fflush(stdout);

            err = LTR25_SetSensorsPowerMode(&hltr25, LTR25_SENSORS_POWER_MODE_TEDS);
            printf("\n\n");
            printf(" Установка режима TEDS: %s\n", LTR25_GetErrorString(err));

            //hltr25.State.SensorsPowerMode = LTR25_SENSORS_POWER_MODE_TEDS;

            err = LTR25_TEDSNodeDetect(&hltr25, ch, &meminfo);
            printf(" Обнаружение TEDS памяти канала %d: %s\n", ch_num, LTR25_GetErrorString(err));
            if (err == LTR_OK) {
                BYTE teds_rd_data[LPW25_TEDS_MAX_SIZE];
                DWORD ret_size;
                err = LTR25_TEDSReadData(&hltr25, ch, teds_rd_data, sizeof(teds_rd_data), &ret_size);
                if (err != LTR_OK) {
                    fprintf(stderr, "Не удалось прочитать данные в TEDS.  Ошибка %d (%s)\n",
                            err, LTR25_GetErrorString(err));
                } else {
                    TLPW25_INFO info_rd;
                    BOOLEAN all_parsed;

                    printf("Данные TEDS считаны успешно");
                    err = LPW25_TEDSDecode(teds_rd_data, ret_size, 0, NULL, &info_rd, &all_parsed);
                    if (err == LTEDS_OK) {
                        if (all_parsed) {
                            printf("TEDS parsed successfully\n");
                        } else {
                            printf("TEDS partially parsed successfully\n");
                        }

                        printf("Module info:\n");
                        printf("   Model:         %d\n", info_rd.ModelID);
                        printf("   Version:       %d%c\n", info_rd.VersionNumber, info_rd.VersionLetter);
                        printf("   SerialNumber:  %d\n", info_rd.SerialNumber);
                        printf("   PhysMesurand:  %d\n", info_rd.PhysicalMeasurand);
                        printf("   PhysicalMax:   %.2f\n", info_rd.PhysicalRange);
                        printf("   ElectricalMax: %.3f\n", info_rd.ElectricalRange);
                        if (LTEDS_DateIsValid(&info_rd.CalInfo.CalDate)) {
                            printf("Calibration info:\n");
                            printf("   Calibration date:   %d.%d.%d\n", info_rd.CalInfo.CalDate.Day,
                                   info_rd.CalInfo.CalDate.Month, info_rd.CalInfo.CalDate.Year);
                            printf("   Calibration period: %d days\n", info_rd.CalInfo.CalPeriod);
                            printf("   Sens:               %f at %.2f V\n",
                                   info_rd.CalInfo.CalCoef.Sens,
                                   info_rd.CalInfo.CalCoef.InputValue);
                            printf("   Rout at 2.86 mA:    %.2f\n", info_rd.CalInfo.ROutCoefs.R_I_2_86);
                            printf("   Rout at 10 mA:      %.2f\n", info_rd.CalInfo.ROutCoefs.R_I_10);
                            printf("   Phase delay:        %f.3 at %.1f Hz\n",
                                   info_rd.CalInfo.PhaseCoefs.PhaseShift,
                                   info_rd.CalInfo.PhaseCoefs.PhaseShiftRefFreq);
                        }
                        fflush(stdout);
                    }
                }
            }

            /* закрываем связь с модулем */
            close_err = LTR25_Close(&hltr25);
            if (close_err!=LTR_OK) {
                fprintf(stderr, "Не удалось закрыть связь с модулем. Ошибка %d:%s\n",
                        close_err, LTR25_GetErrorString(close_err));
                if (err==LTR_OK)
                    err = close_err;
            } else {
                printf("Связь с модулем успешно закрыта.\n");
            }
        }
    }

    return err;
}
