207 lines
9.6 KiB
C
207 lines
9.6 KiB
C
/*
|
||
* 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 <stddef.h>
|
||
#include <stdint.h>
|
||
#include <stdbool.h>
|
||
|
||
#include <efc_usb/status.h>
|
||
|
||
/**
|
||
* @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_ */
|