/*********************************************************************//**
 @addtogroup cmd_process
 @{
 @file l502_bf_cmd_defs.h  Файл содержит определения,
     которые используются для передачи команд от ПК в DSP
     (определения команд, их параметров, результатов выполнения)
 @date 28.03.2012
 @author Borisov Alexey <borisov@lcard.ru>
 *************************************************************************/
#ifndef L502_BF_CMD_DEFS_H_
#define L502_BF_CMD_DEFS_H_

/** Максимальный размер данных, передавемых с командой в 32-битных словах */
#define L502_BF_CMD_DATA_SIZE_MAX     (1024)



/** Статус команд управления сигнальным процессором */
typedef enum {
    L502_BF_CMD_STATUS_IDLE     = 0x0,     /**< Начальное состояние (команда вообщен не выполнялась) */
    L502_BF_CMD_STATUS_REQ      = 0x5A01,  /**< Передан запрос на обработку команды от ПК*/
    L502_BF_CMD_STATUS_PROGRESS = 0x5A02,  /**< Сигнальный процессор начал обработку команды */
    L502_BF_CMD_STATUS_DONE     = 0x5A03   /**< Команда выполнена. Результат выполнения в поле ret_code */
} t_l502_bf_cmd_status;


/** Коды команд управления сигнальным процессором */
typedef enum {
    L502_BF_CMD_CODE_TEST          = 0x01, /**< Запуск теста (параметр определяет тип теста) */
    L502_BF_CMD_CODE_SET_PARAM     = 0x02, /**< Установить параметр (код параметра в поле param) */
    L502_BF_CMD_CODE_GET_PARAM     = 0x03, /**< Прочитать текущее значение параметра */
    L502_BF_CMD_CODE_CONFIGURE     = 0x04, /**< Сконфигурировать модуль в соответствии с ранее установленными параметрами */
    L502_BF_CMD_CODE_STREAM_EN     = 0x05, /**< Разрешение потоков ввода/вывода */
    L502_BF_CMD_CODE_STREAM_DIS    = 0x06, /**< Запрещение потоков ввода/вывода */
    L502_BF_CMD_CODE_STREAM_START  = 0x07, /**< Запуск потоков ввода/вывода */
    L502_BF_CMD_CODE_STREAM_STOP   = 0x08, /**< Останов потоков ввода/вывода */
    L502_BF_CMD_CODE_PRELOAD       = 0x09, /**< Предзагрузка данных на ЦАП */
    L502_BF_CMD_CODE_ASYNC_OUT     = 0x10, /**< Асинхронный вывод (куда - зависит от параметра) */
    L502_BF_CMD_CODE_ASYNC_DIG_IN  = 0x11, /**< Асинхронный ввод с цифровых линий */
    L502_BF_CMD_CODE_ADC_GET_FRAME = 0x12, /**< Асинхронный ввод карда АЦП */
    L502_BF_CMD_CODE_FPGA_REG_WR   = 0x13, /**< Запись в регистр FPGA (param --- адрес регистра, data0 --- значение) */
    L502_BF_CMD_CODE_FPGA_REG_RD   = 0x14, /**< Чтение из регистра FPGA (param --- адрес регистра, ответ: resp0 --- значение) */
    L502_BF_CMD_CODE_GET_OUT_STATUS= 0x15, /**< Получение флагов статуса вывода */
} t_l502_bf_cmd_code;

#define L502_BF_CMD_CODE_USER         0x8000U  /**< Код, с которого начинаются пользовательские команды */



/** @brief Варианты тестов

    Коды тестов, передающиеся в параметре команды #L502_BF_CMD_CODE_TEST */
typedef enum {
    L502_BF_CMD_TEST_STOP         = 0x00, /**< Останов выполняемого теста */
    L502_BF_CMD_TEST_GET_RESULT   = 0x01, /**< Получение результата теста */
    L502_BF_CMD_TEST_ECHO         = 0x10, /**< Тест эхо - возвращает те же данные что передавались */
    L502_BF_CMD_TEST_SPORT        = 0x11, /**< Тест интерфейса SPORT в кольцевом режиме */
    L502_BF_CMD_TEST_SDRAM        = 0x12, /**< Тест SDRAM памяти */
    L502_BF_CMD_TEST_SPI          = 0x13  /**< Тест интерфейса SPI */
} t_l502_bf_test_code;


/** @brief Устанавливаемые параметры

    Коды пареметров, устанавливаемых командой #L502_BF_CMD_CODE_SET_PARAM или
    получаемых с помщью команды #L502_BF_CMD_CODE_GET_PARAM */
typedef enum {
    L502_BF_PARAM_FIRM_VERSION    = 0x00, /**< Версия прошивки - 4 байта */
    L502_BF_PARAM_STREAM_MODE     = 0x01, /**< Режим работы (запущен поток или нет) */
    L502_BF_PARAM_ENABLED_STREAMS = 0x02, /**< Какие потоки разрешены */
    L502_BF_PARAM_MODULE_INFO     = 0x03, /**< Запись информации о модуле */
    L502_BF_PARAM_IN_BUF_SIZE     = 0x10, /**< Размер буфера на преием */
    L502_BF_PARAM_CYCLE_BUF_SIZE  = 0x11, /**< Размер буфера для записи циклического сигнала */
    L502_BF_PARAM_LCH_CNT         = 0x20, /**< Количество логических каналов в таблице */
    L502_BF_PARAM_LCH             = 0x21, /**< Параметры логического канала */
    L502_BF_PARAM_ADC_FREQ_DIV    = 0x22, /**< Делитель частоты АЦП */
    L502_BF_PARAM_REF_FREQ_SRC    = 0x23, /**< Выбор опорной частоты */
    L502_BF_PARAM_ADC_FRAME_DELAY = 0x24, /**< Значение межкадровой задержки */
    L502_BF_PARAM_SYNC_MODE       = 0x25, /**< Режим синхронизации */
    L502_BF_PARAM_SYNC_START_MODE = 0x26, /**< Условие запуска синхронных потоков сбора данных */
    L502_BF_PARAM_ADC_COEF        = 0x27, /**< Установка коэффициентов для заданного диапазона АЦП */
    L502_BF_PARAM_DAC_COEF        = 0x28, /**< Установка коэффициентов для заданного канала ЦАП */
    L502_BF_PARAM_DIN_FREQ_DIV    = 0x30, /**< Делитель частоты цифрового ввода */
    L502_BF_PARAM_DAC_FREQ_DIV    = 0x31, /**< Делитель частоты вывода на ЦАП */
    L502_BF_PARAM_IN_STEP_SIZE    = 0x32, /**< Шаг для обработки входных данных */
    L502_BF_PARAM_IN_STREAM_MODE  = 0x100 /**< Режим работы потока на ввод */
} t_l502_bf_params;





/** @brief Тип асинхронного вывода

    Код, задающий в параметре команды команды #L502_BF_CMD_CODE_ASYNC_OUT,
    куда должно выводится передаваемое значение */
typedef enum {
    L502_BF_CMD_ASYNC_TYPE_DOUT = 0x0, /**< Вывод на цифровые линии */
    L502_BF_CMD_ASYNC_TYPE_DAC1 = 0x1, /**< Вывод на первый канал ЦАП */
    L502_BF_CMD_ASYNC_TYPE_DAC2 = 0x2  /**< Вывод на второй канал ЦАП */
} t_l502_bf_cmd_async_type;

/** Коды завершения команд */
typedef enum {
    L502_BF_ERR_SUCCESS               = 0, /**< Команда выполнена успешно */
    L502_BF_ERR_FIRST_CODE            = -512, /**< Код ошибки, с которого начинаются отсальные коды.
                                                   Используется, чтобы разделить на верхнем уровне ошибки библиотеки и
                                                   возвращенные сигнальным процессором */
    L502_BF_ERR_UNSUP_CMD             = -512, /**< Неизвестный код команды */
    L502_BF_ERR_CMD_OVERRUN           = -513, /**< Пришла команда до того, как была завершена предыдущая */
    L502_BF_ERR_INVALID_CMD_PARAMS    = -514, /**< Неверное значение параметра команды */
    L502_BF_ERR_INSUF_CMD_DATA        = -515, /**< Недостаточное кол-во данных передано с командой */
    L502_BF_ERR_STREAM_RUNNING        = -516, /**< Команда не допустима при запущеном сборе, а сбор запущен */
    L502_BF_ERR_STREAM_STOPPED        = -517, /**< Команда допустима только при запущеном сборе, а сбор остановлен */
    L502_BF_ERR_NO_TEST_IN_PROGR      = -518, /**< Сейчас не выполняется никакого теста */
    L502_BF_ERR_TEST_VALUE            = -519  /**< Считано неверное значение при выполнении теста */
} t_l502_bf_err_code;


/** Режим работы сигнального процессора */
typedef enum {
    L502_BF_MODE_IDLE           = 0, /**< Ждущий режим, поток не запущен */
    L502_BF_MODE_STREAM         = 1, /**< Запущены потоки ввода-вывода */
    L502_BF_MODE_TEST           = 2 /**< Тестовый режим */
} t_l502_bf_mode;

/** Возможности, поддерживаемые прошивкой blackfin */
typedef enum {
    L502_BF_FEATURE_FPGA_REG_ACCESS  = 0x1,  /**< Признак, что реализованы команды
                                                прямого доступа к регистрам FPGA */
    L502_BF_FEATURE_OUT_STATUS_FLAGS = 0x2   /**< Признак, что реализована команда
                                                  #L502_BF_CMD_CODE_GET_OUT_STATUS */
} t_l502_bf_features;

/** @brief Параметры команды

    Структура описывает расположение полей в области памяти BlackFin, используемой
    для передачи команд между персональным компьютером и сигнальным процессором */
typedef struct {
    uint16_t code;   /**< Код команды из #t_l502_bf_cmd_code */
    uint16_t status; /**< Статус выполнения - в обработчике не изменяется */
    uint32_t param;  /**< Параметр команды */
    int32_t  result; /**< Код результата выполнения команды */
    uint32_t data_size; /**< Количество данных, переданных с командой или возвращенных с ответом в 32-битных словах */
    uint32_t data[L502_BF_CMD_DATA_SIZE_MAX]; /**< Данные, передаваемые с командой и/или в качестве результата */
} t_l502_bf_cmd;


/** @brief Результат выполнения теста

    Структура описывает параметры выполняемого теста, возвращаемые в качестве
    данных на команду #L502_BF_CMD_CODE_TEST с параметром
    #L502_BF_CMD_TEST_GET_RESULT */
typedef struct {
    uint32_t test; /**< Номер выполняемого теста */
    uint32_t run; /**< Признак, запущен ли сейчас тест */
    uint32_t stage; /**< Этап выполнения теста */
    uint32_t cntr; /**< Счетчик - сколько раз прошел тест */
    int32_t err; /**< Код ошибки выполнения теста */
    uint32_t last_addr; /**< Последний используемый адрес */
    uint32_t last_wr; /**< Последнее записанное значение */
    uint32_t last_rd; /**< Последнее считанное значение */
} t_l502_bf_test_res;

/** @} */

#endif
