/* * service.h * * Created on: 25 Aug 2023 * Author: malyarenko */ #ifndef EFC_USB_SERVICE_H_ #define EFC_USB_SERVICE_H_ #ifdef __cplusplus extern "C" { #endif #include #include #include #include /** * @addtogroup Api * * @{ */ /** * @defgroup ServiceApi API сервисного обмена * * @{ */ /** * @defgroup ServiceCmdApi API командного интерфейса * * @{ */ /** @brief Максимальный размер пакета данных командного интерфейса */ #define EFC_USB_SV_CMD_PACKET_SIZE_MAX ((size_t) 256) // Обязан быть 2^N байтов /** @brief Размер заголовка пакета командного интерфейса */ #define EFC_USB_SV_CMD_PACKET_HEADER_SIZE ((size_t) sizeof(uint32_t)) /** @brief Размер поля данных пакета командного интерфейса */ #define EFC_USB_SV_CMD_PACKET_DATA_SIZE_MAX ((size_t) (EFC_USB_SV_CMD_PACKET_SIZE_MAX - EFC_USB_SV_CMD_PACKET_HEADER_SIZE)) /** @brief Заголовок пакета командного интерфейса */ union efc_usb_sv_cmd_header { struct { /** Размер данных */ uint32_t size : 8; /** Идентификатор команды */ uint32_t id : 16; /** Зарезервированное поле */ uint32_t reserved : 4; /** Идентификатор логического канала */ uint32_t channel_id : 4; } bits; uint32_t all; }; /** @brief Идентификатор канала ошибки */ #define EFC_USB_SV_CMD_ERR_CHANNEL ((uint32_t) 0xFF) /** @brief Заголовок общей ошибки */ #define EFC_USB_SV_CMD_ERR_HEADER \ (union efc_usb_sv_cmd_header) { \ .bits = { \ .channel_id = EFC_USB_SV_CMD_ERR_CHANNEL, \ .id = 0xFFFFU, \ .size = 0, \ } \ } /** * @brief Тип обработчика событий командных пакетов * * Обработчики данного типа предоставляются пользователем драйвера и вызываются * при событиях запроса на приём и передачу командного пакета. * * Условия вызова: * - Для **Rx** обработчик вызывается **после** получения пакета и буферизации в FIFO * - Для **Tx** обработчик вызывается **до** буферизации в FIFO и отправки пакета * * @param param Пользовательский параметр, передаваемый при вызове со стороны драйвера * * @return void * * @note Вызов производится из контекста обработчика прерывания */ typedef void (*efc_usb_sv_cmd_handle_t) (void* param); /** * @brief Тип селектора буфера командного пакета * * Предикат данного типа предоставляется пользвателем драйвера для определения * адреса буфера приёмника/передатчика с целью прямого копирования в FIFO модуля USB * * @param cpu_id Индекс ЦПУ из возможных значений @ref efc_usb_sv_cmd_header.bits.cpu_id * @param param Пользовательский параметр, передаваемый при вызове со стороны драйвера * * @return Указатель на необходимый буфер; `NULL` в случае ошибки */ typedef uint8_t* (*efc_usb_sv_cmd_buffer_selector_t) (uint32_t cpu_id, void* param); /** @brief Параметры командного интерфейса */ struct efc_usb_sv_cmd_config { /** Обратный вызов приёмника командных пакетов */ efc_usb_sv_cmd_handle_t rx_handle; /** Обратный вызов селектора буфера приёмника */ efc_usb_sv_cmd_buffer_selector_t rx_buffer_selector; /** Параметр приёмника командных пакетов */ void* rx_param; /** Обратный вызов передатчика командных пакетов */ efc_usb_sv_cmd_handle_t tx_handle; /** Обратный вызов селектора буфера приёмника */ efc_usb_sv_cmd_buffer_selector_t tx_buffer_selector; /** Параметр передатчика командных пакетов */ void* tx_param; }; /** * @brief Метод отправки командного пакета * * Функция реализует синхронный метод отправки командного пакета. @n * * В стандартном случае, метод вызывается в обработчике IN запроса от хоста. * На основании предоставленного заголовка и метода селектора буфера, данные пакета * выгружаются в FIFO модуля USB и далее отправка планируется аппаратно. @n * * @note Если пользовательский метод селектора буфера возвращает `NULL` во время выполнения * операции, то запись данных не производится и метод возвращает признак ошибки. * * @param[in] header Заголовок командного пакета с заполненными полями * * @return Статус выполнения операции #efc_usb_status */ efc_usb_status_t efc_usb_sv_cmd_send(union efc_usb_sv_cmd_header* header); /** * @brief Метод приёма командного пакета * * Функция реализует синхронный метод приёма командного пакета. @n * * В стандартном случае, метод вызывается в обработчике OUT запроса от хоста. * На основании принятого заголовка и метода селектора буфера, данные пакета * выгружаются из FIFO модуля в предоставленную структуру заголовок и выбранный буфер. @n * * @note Если пользовательский метод селектора буфера возвращает `NULL` во время выполнения * операции, то чтение не производится, данные считаются утерянными и метод возвращает признак ошибки. * * @param[out] header Буфер заголовка командного пакета * * @return Статус выполнения операции #efc_usb_status */ efc_usb_status_t efc_usb_sv_cmd_recv(union efc_usb_sv_cmd_header* header); /** @} */ /* ServiceCmdApi */ /** * @brief Тип обратного вызова к драйверу о переводе в начальное состояние * * Данный обработчик вывзывается со стороны пользователя после запроса на сброс от драйвера * после всех необходимых процедур перевода в начальное состояние * * @return void */ typedef void (*efc_usb_sv_reset_ack_t) (); /** * @brief Обработчик сброса, инициированного хостом * * Вызывается после выполнения процедуры сброса состояния конфигурации дарайвера. @n * - Буферы приёмника/передатчика считаются невалидными * - Драйвер переводится в рабочее состояние * - Обработка командный интерфейса включёна * - Обработка потокового интерфейса выключена * * @param ack Обратный вызов уведомления о выполненном сбросе пользовательской части драйвера * @param param Пользовательский параметр, передаваемый при вызове со стороны драйвера * * @return void * * @note Вызов производится из контекста обработчика прерывания */ typedef void (*efc_usb_sv_reset_handle_t) (efc_usb_sv_reset_ack_t ack, void* param); /** @brief Параметры конфигурации сервисного обмена */ struct efc_usb_sv_config { /** Параметры командного интерфейса */ struct efc_usb_sv_cmd_config cmd; /** Обратный вызов события сброса */ efc_usb_sv_reset_handle_t reset_handle; /** Параметр обратного вызова события сброса */ void* reset_handle_param; }; /** @} */ /* ServiceApi */ /** @} */ /* Api */ #ifdef __cplusplus } #endif #endif /* EFC_USB_SERVICE_H_ */