/* Реализация теста интерефейса phy с помощью режима loopback.

   Данный тест не предполагает штатной работы стека и требует, чтобы он был
   закрыт lip_close(), если был инициализирован ранее.

   Для работы нужно вызвать lip_phy_test_loop_init() и потом периодически
   вызывать lip_phy_test_loop_pull().
   По завершению работы нужно вызвать lip_phy_test_loop_finish(), после чего
   PHY находится в отключенном состоянии (и для дальнейшей штатной работы
   стека нужно будет вызвать снова lip_init() с последующими операциями).

   Тест передает пакеты в сыром виде без дополнительной обработки сл счетчиком
   с максимально возможной скоростью и при приеме анализирует
   целостность принятых пакетов.

   Счетчик принятых пакетов и ошибок обновляется в переданной структуре со
   статистикой.
*/

#ifndef LIP_PHY_TEST_LOOP_H
#define LIP_PHY_TEST_LOOP_H

#include "lip/lip_defs.h"
#include "lip_phy_test_loop_cfg_defs.h"

#if LIP_PHY_TEST_LOOPBACK_ENABLE

/** Флаги результатов выполнения теста */
typedef enum {
    LIP_PHY_TEST_LOOP_STAT_FLAG_PHY_DETECTED = 1 << 0 /**< Признак, что было обнаружено подключенное PHY (работает интерфейс регистров) */
} t_lip_phy_test_loop_stat_flags;

/** Информация о возникшей ошибке */
typedef struct {
    uint32_t packet_num; /**< Номер пакета, в котором возникла ошибка */
    uint32_t word_num;   /**< Номер слова с ошибкой в пакете данных */
    uint32_t rcv_wrd;    /**< Слово, которое было принято */
    uint32_t exp_wrd;    /**< Слово, которое ожидали */
} t_lip_phy_test_loop_stat_err_info;

/** Структура со статистикой кольцевого теста */
typedef struct {
    uint32_t flags;           /**< Набор флагов из #t_lip_phy_test_loop_stat_flags */
    uint32_t rcv_packet_cnt;  /**< Количество принятых пакетов */
    uint32_t tx_packet_cnt;   /**< Количество переданных пакетов */
    uint32_t rcv_cntr;        /**< Счетчик принятых слов */
    uint32_t rcv_err_cnt;     /**< Количество ошибок */
    t_lip_phy_test_loop_stat_err_info first_err; /**< Информация о первой ошибке ошибке */
    t_lip_phy_test_loop_stat_err_info last_err; /**< Информация о последней ошибке */
} t_lip_phy_test_loop_stats;

/** Настройки теста (резерв) */
typedef struct {

} t_lip_phy_test_loop_cfg;

/** @brief Инициализация запуска теста PHY. Выполняет конфигурацию MAC и PHY и подготовку к работе.
 *  Стек должен быть выключен до проведения теста (либо тест выполняться до lip_init(), либо
 *  требуется вызвать lip_close() перед выполнением */
void lip_phy_test_loop_init(const t_lip_phy_test_loop_cfg *cfg, t_lip_phy_test_loop_stats *stats);
/** @brief Выполнение фоновых задач теста */
t_lip_errs lip_phy_test_loop_pull(void);
/** @brief Завершение работы теста. Должно быть выполнено после  lip_phy_test_loop_init(). */
void lip_phy_test_loop_finish(void);

#endif

#endif // LIP_PHY_TEST_LOOP_H
