# USB CDC - 1st stage
This commit is contained in:
parent
832a542db4
commit
0d062a6c21
17 changed files with 2742 additions and 382 deletions
|
|
@ -15,6 +15,7 @@ add_subdirectory(uart_host)
|
|||
add_subdirectory(opto)
|
||||
add_subdirectory(can)
|
||||
add_subdirectory(button)
|
||||
add_subdirectory(usb_cdc)
|
||||
|
||||
# Подавляем предупреждения при компиляции собственных .c файлов библиотеки
|
||||
target_compile_options(bsp_board PRIVATE -w)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ typedef enum bsp_status_e
|
|||
BSP_ERR_PARAM = 4, /**< Невалидный аргумент */
|
||||
BSP_ERR_OVERFLOW = 5, /**< Переполнение буфера, данные потеряны. */
|
||||
BSP_ERR_NOT_SUPPORTED = 6, /**< Функция не поддерживается */
|
||||
BSP_ERR_INVALID = 7, /**< Невалидная операция. */
|
||||
BSP_ERR_HW = 8, /**< Ошибки аппаратного стека. */
|
||||
BSP_ERR_NOT_READY = 9, /**< Модуль не готов. */
|
||||
} bsp_status_t;
|
||||
|
||||
#endif /* BSP_STATUS_H */
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
if(BUILD_TESTS_HOST)
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_library(bsp_usb_cdc STATIC src/usb_cdc.c src/usb_cdc_descriptors.c
|
||||
src/usb_cdc_hw.c src/usb_device_ch9.c)
|
||||
|
||||
target_include_directories(
|
||||
bsp_usb_cdc
|
||||
PUBLIC include/
|
||||
PRIVATE src/)
|
||||
|
||||
target_link_libraries(
|
||||
bsp_usb_cdc
|
||||
PUBLIC bsp_status
|
||||
PRIVATE bsp_board bsp_tick sdk_usb_device_ehci sdk_usb_phy sdk_osa_bm)
|
||||
|
||||
target_compile_options(bsp_usb_cdc PRIVATE -w)
|
||||
100
bsp/usb_cdc/include/bsp/usb_cdc.h
Normal file
100
bsp/usb_cdc/include/bsp/usb_cdc.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright 2025 MU LLC
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file usb_cdc.h
|
||||
* @brief BSP: USB CDC ACM (Virtual COM Port) на USB1 / EHCI0.
|
||||
*
|
||||
* Публичный API без зависимостей от NXP SDK.
|
||||
* Все USB-специфичные типы и хедеры скрыты в реализации.
|
||||
*/
|
||||
|
||||
#ifndef BSP_USB_CDC_H_
|
||||
#define BSP_USB_CDC_H_
|
||||
|
||||
#include "bsp/status.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/** Максимальный размер одной передачи (HS bulk packet). */
|
||||
#define BSP_USB_CDC_MAX_PACKET_SIZE (512U)
|
||||
|
||||
/**
|
||||
* @brief Инициализация USB CDC ACM (USB1 / EHCI0).
|
||||
*
|
||||
* Включает тактирование USB PHY 480 MHz, инициализирует EHCI контроллер,
|
||||
* регистрирует CDC ACM дескрипторы и запускает USB device stack.
|
||||
*
|
||||
* @pre board_hw_init() вызван (MPU настроен, NonCacheable регион активен).
|
||||
*
|
||||
* @return BSP_OK при успехе, BSP_ERR_HW при ошибке инициализациистека.
|
||||
*/
|
||||
bsp_status_t bsp_usb_cdc_init(void);
|
||||
|
||||
/**
|
||||
* @brief Проверить готовность канала (хост открыл COM-порт).
|
||||
*
|
||||
* Возвращает true когда USB enumeration завершён и хост установил
|
||||
* DTR (Data Terminal Ready) через SET_CONTROL_LINE_STATE.
|
||||
*
|
||||
* @return true — можно передавать данные, false — хост не подключён.
|
||||
*/
|
||||
bool bsp_usb_cdc_is_ready(void);
|
||||
|
||||
/**
|
||||
* @brief Отправить данные хосту (неблокирующая).
|
||||
*
|
||||
* Копирует данные во внутренний TX буфер (NonCacheable OCRAM)
|
||||
* и ставит в очередь USB IN transfer.
|
||||
*
|
||||
* @param data Указатель на данные.
|
||||
* @param len Количество байт, 0 < len <= BSP_USB_CDC_MAX_PACKET_SIZE.
|
||||
*
|
||||
* @return BSP_OK — transfer поставлен в очередь.
|
||||
* @return BSP_ERR_BUSY — предыдущий transfer не завершён.
|
||||
* @return BSP_ERR_NOT_READY — хост не подключён или USB не инициализирован.
|
||||
* @return BSP_ERR_INVALID — data == NULL или len == 0 или len слишком велик.
|
||||
*/
|
||||
bsp_status_t bsp_usb_cdc_write(const uint8_t *p_data, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Готов ли TX канал к следующей отправке.
|
||||
*
|
||||
* @return true — можно вызывать bsp_usb_cdc_write().
|
||||
*/
|
||||
bool bsp_usb_cdc_write_ready(void);
|
||||
|
||||
/**
|
||||
* @brief Прочитать данные от хоста (неблокирующая).
|
||||
*
|
||||
* Забирает данные из внутреннего RX буфера, заполненного USB OUT
|
||||
* callback. Автоматически перепланирует следующий OUT transfer.
|
||||
*
|
||||
* @param buf Буфер для приёма.
|
||||
* @param max_len Размер буфера.
|
||||
*
|
||||
* @return Количество прочитанных байт (0 если данных нет).
|
||||
*/
|
||||
size_t bsp_usb_cdc_read(uint8_t *p_buf, size_t max_len);
|
||||
|
||||
/**
|
||||
* @brief Поллинг USB стека — вызывать из main loop (bare-metal).
|
||||
*
|
||||
* Для FreeRTOS не нужен если USB_DEVICE_CONFIG_USE_TASK = 1.
|
||||
*/
|
||||
void bsp_usb_cdc_poll(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BSP_USB_CDC_H_ */
|
||||
21
bsp/usb_cdc/src/fsl_os_abstraction_config.h
Normal file
21
bsp/usb_cdc/src/fsl_os_abstraction_config.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright 2025 TFT Project
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fsl_os_abstraction_config.h
|
||||
* @brief Конфигурация OSA bare-metal для bsp_usb_cdc.
|
||||
*
|
||||
* NXP OSA подключает этот файл через include path.
|
||||
* Настройки под bare-metal (без FreeRTOS).
|
||||
*/
|
||||
#ifndef FSL_OS_ABSTRACTION_CONFIG_H_
|
||||
#define FSL_OS_ABSTRACTION_CONFIG_H_
|
||||
|
||||
#define gMainThreadStackSize_c (1024U)
|
||||
#define gMainThreadPriority_c (7U)
|
||||
#define gTaskMultipleInstancesManagement_c (0U)
|
||||
#define FSL_OSA_ALLOCATED_HEAP (1U)
|
||||
|
||||
#endif /* FSL_OS_ABSTRACTION_CONFIG_H_ */
|
||||
664
bsp/usb_cdc/src/usb_cdc.c
Normal file
664
bsp/usb_cdc/src/usb_cdc.c
Normal file
|
|
@ -0,0 +1,664 @@
|
|||
/*
|
||||
* Copyright 2025 MU LLC
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file usb_cdc.c
|
||||
* @brief BSP USB CDC ACM — реализация публичного API и NXP callbacks.
|
||||
*
|
||||
* Архитектура:
|
||||
* - Публичные функции bsp_usb_cdc_*() — вызываются приложением.
|
||||
* - USB_Device*() callbacks — вызываются NXP USB стеком из ISR контекста.
|
||||
* - Данные между ISR и main loop синхронизируются через volatile флаги
|
||||
* и DisableGlobalIRQ/EnableGlobalIRQ (bare-metal critical section).
|
||||
*
|
||||
* Все DMA-буферы размещены в NonCacheable OCRAM через USB_DMA_*_ALIGN макросы.
|
||||
*/
|
||||
|
||||
#include "bsp/usb_cdc.h"
|
||||
|
||||
#include "bsp/tick.h"
|
||||
#include "fsl_common.h"
|
||||
#include "usb.h"
|
||||
#include "usb_device.h"
|
||||
#include "usb_device_cdc_acm.h"
|
||||
#include "usb_device_ch9.h"
|
||||
#include "usb_device_config.h"
|
||||
#include "usb_device_descriptor.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* ========================================================================
|
||||
* Внутренние определения
|
||||
* ======================================================================== */
|
||||
|
||||
#define CONTROLLER_ID kUSB_ControllerEhci0
|
||||
|
||||
/** Размер bulk-буферов. При HS = 512, при FS = 64. Аллоцируем под HS. */
|
||||
#define DATA_BUFF_SIZE HS_CDC_VCOM_BULK_OUT_PACKET_SIZE
|
||||
|
||||
/** Line coding defaults (115200 8N1). */
|
||||
#define LINE_CODING_DTERATE (115200U)
|
||||
#define LINE_CODING_CHARFORMAT (0x00U)
|
||||
#define LINE_CODING_PARITYTYPE (0x00U)
|
||||
#define LINE_CODING_DATABITS (0x08U)
|
||||
#define LINE_CODING_SIZE (7U)
|
||||
|
||||
#define COMM_FEATURE_DATA_SIZE (2U)
|
||||
#define STATUS_ABSTRACT_STATE (0x0000U)
|
||||
#define COUNTRY_SETTING (0x0000U)
|
||||
|
||||
#define NOTIF_PACKET_SIZE (8U)
|
||||
#define UART_BITMAP_SIZE (2U)
|
||||
#define NOTIF_REQUEST_TYPE (0xA1U)
|
||||
|
||||
/** Задержка после USB_DeviceRun для стабилизации DP pull-down (мкс). */
|
||||
#define USB_ATTACH_DELAY_US (5000U)
|
||||
#define USB_DEVICE_CDC_REQUEST_SERIAL_STATE_NOTIF (0x20U)
|
||||
/* ========================================================================
|
||||
* Состояние устройства
|
||||
* ======================================================================== */
|
||||
|
||||
/** Глобальный handle — используется IRQ handler в usb_cdc_hw.c. */
|
||||
usb_device_handle g_usbDeviceHandle = NULL;
|
||||
|
||||
/** Информация о состоянии ACM (serial state notification). */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE];
|
||||
bool dtePresent;
|
||||
uint16_t breakDuration;
|
||||
uint8_t dteStatus;
|
||||
uint8_t currentInterface;
|
||||
uint16_t uartState;
|
||||
} usb_cdc_acm_info_t;
|
||||
|
||||
/** Внутреннее состояние CDC. */
|
||||
static struct
|
||||
{
|
||||
volatile uint8_t attach; /**< 1 = USB enumeration done. */
|
||||
volatile uint8_t startTransactions; /**< 1 = DTE present, can TX/RX. */
|
||||
uint8_t speed; /**< USB_SPEED_HIGH / _FULL. */
|
||||
uint8_t currentConfiguration;
|
||||
uint8_t currentInterfaceAlt[USB_CDC_VCOM_INTERFACE_COUNT];
|
||||
uint8_t hasSentState; /**< Serial state notification sent. */
|
||||
} s_cdcState;
|
||||
|
||||
/* ========================================================================
|
||||
* DMA-aligned буферы (NonCacheable OCRAM)
|
||||
* ======================================================================== */
|
||||
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
static uint8_t s_lineCoding[LINE_CODING_SIZE] = {
|
||||
(LINE_CODING_DTERATE >> 0U) & 0xFFU,
|
||||
(LINE_CODING_DTERATE >> 8U) & 0xFFU,
|
||||
(LINE_CODING_DTERATE >> 16U) & 0xFFU,
|
||||
(LINE_CODING_DTERATE >> 24U) & 0xFFU,
|
||||
LINE_CODING_CHARFORMAT,
|
||||
LINE_CODING_PARITYTYPE,
|
||||
LINE_CODING_DATABITS,
|
||||
};
|
||||
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
static uint8_t s_abstractState[COMM_FEATURE_DATA_SIZE] = {
|
||||
(STATUS_ABSTRACT_STATE >> 0U) & 0xFFU,
|
||||
(STATUS_ABSTRACT_STATE >> 8U) & 0xFFU,
|
||||
};
|
||||
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
static uint8_t s_countryCode[COMM_FEATURE_DATA_SIZE] = {
|
||||
(COUNTRY_SETTING >> 0U) & 0xFFU,
|
||||
(COUNTRY_SETTING >> 8U) & 0xFFU,
|
||||
};
|
||||
|
||||
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
static usb_cdc_acm_info_t s_usbCdcAcmInfo;
|
||||
|
||||
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
static uint8_t s_recvBuf[DATA_BUFF_SIZE];
|
||||
|
||||
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
static uint8_t s_sendBuf[DATA_BUFF_SIZE];
|
||||
|
||||
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
static uint8_t s_setupOutBuffer[8];
|
||||
|
||||
/** Количество полученных байт (0 = нет данных, заполняется в ISR). */
|
||||
static volatile uint32_t s_recvSize = 0U;
|
||||
|
||||
/** Количество байт для отправки (0 = idle). */
|
||||
static volatile uint32_t s_sendSize = 0U;
|
||||
|
||||
/** Текущий max packet size (обновляется при смене скорости). */
|
||||
static uint32_t s_bulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
|
||||
|
||||
/** TX transfer завершён (1 = можно отправлять следующий). */
|
||||
static volatile uint8_t s_txIdle = 1U;
|
||||
|
||||
/* ========================================================================
|
||||
* Прототипы внешних функций (usb_cdc_hw.c)
|
||||
* ======================================================================== */
|
||||
|
||||
extern void USB_DeviceClockInit(void);
|
||||
extern void USB_DeviceIsrEnable(void);
|
||||
|
||||
/* ========================================================================
|
||||
* USB Endpoint Callbacks (вызываются из ISR контекста)
|
||||
* ======================================================================== */
|
||||
|
||||
static usb_status_t
|
||||
USB_DeviceCdcAcmInterruptIn(usb_device_handle handle,
|
||||
usb_device_endpoint_callback_message_struct_t *message,
|
||||
void *callbackParam)
|
||||
{
|
||||
(void) handle;
|
||||
(void) message;
|
||||
(void) callbackParam;
|
||||
s_cdcState.hasSentState = 0U;
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
|
||||
static usb_status_t USB_DeviceCdcAcmBulkIn(usb_device_handle handle,
|
||||
usb_device_endpoint_callback_message_struct_t *message,
|
||||
void *callbackParam)
|
||||
{
|
||||
(void) callbackParam;
|
||||
usb_status_t error = kStatus_USB_Error;
|
||||
|
||||
if ((message->length != 0U) && (0U == (message->length % s_bulkMaxPacketSize)))
|
||||
{
|
||||
/* Отправить ZLP чтобы хост понял что передача завершена. */
|
||||
error = USB_DeviceSendRequest(handle, USB_CDC_VCOM_BULK_IN_ENDPOINT, NULL, 0U);
|
||||
}
|
||||
else if ((1U == s_cdcState.attach) && (1U == s_cdcState.startTransactions))
|
||||
{
|
||||
if ((message->buffer != NULL) || ((message->buffer == NULL) && (message->length == 0U)))
|
||||
{
|
||||
s_txIdle = 1U;
|
||||
/* TX завершён — готовы к следующей отправке. */
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no action */
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static usb_status_t USB_DeviceCdcAcmBulkOut(usb_device_handle handle,
|
||||
usb_device_endpoint_callback_message_struct_t *message,
|
||||
void *callbackParam)
|
||||
{
|
||||
(void) handle;
|
||||
(void) callbackParam;
|
||||
|
||||
if ((1U == s_cdcState.attach) && (1U == s_cdcState.startTransactions))
|
||||
{
|
||||
s_recvSize = message->length;
|
||||
|
||||
if (0U == s_recvSize)
|
||||
{
|
||||
/* Хост послал ZLP — сразу планируем следующий приём. */
|
||||
USB_DeviceRecvRequest(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_recvBuf,
|
||||
s_bulkMaxPacketSize);
|
||||
}
|
||||
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* USB Device Callbacks (вызываются стеком)
|
||||
* ======================================================================== */
|
||||
|
||||
usb_status_t USB_DeviceGetSetupBuffer(usb_device_handle handle, usb_setup_struct_t **setupBuffer)
|
||||
{
|
||||
(void) handle;
|
||||
static uint32_t s_setupBuf[2];
|
||||
|
||||
if (setupBuffer == NULL)
|
||||
{
|
||||
return kStatus_USB_InvalidParameter;
|
||||
}
|
||||
*setupBuffer = (usb_setup_struct_t *) &s_setupBuf;
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
|
||||
usb_status_t USB_DeviceGetClassReceiveBuffer(usb_device_handle handle, usb_setup_struct_t *setup,
|
||||
uint32_t *length, uint8_t **buffer)
|
||||
{
|
||||
(void) handle;
|
||||
(void) setup;
|
||||
|
||||
if ((buffer == NULL) || ((*length) > sizeof(s_setupOutBuffer)))
|
||||
{
|
||||
return kStatus_USB_InvalidRequest;
|
||||
}
|
||||
*buffer = s_setupOutBuffer;
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
|
||||
usb_status_t USB_DeviceConfigureRemoteWakeup(usb_device_handle handle, uint8_t enable)
|
||||
{
|
||||
(void) handle;
|
||||
(void) enable;
|
||||
return kStatus_USB_InvalidRequest;
|
||||
}
|
||||
|
||||
usb_status_t USB_DeviceConfigureEndpointStatus(usb_device_handle handle, uint8_t ep, uint8_t status)
|
||||
{
|
||||
if (status != 0U)
|
||||
{
|
||||
return USB_DeviceStallEndpoint(handle, ep);
|
||||
}
|
||||
return USB_DeviceUnstallEndpoint(handle, ep);
|
||||
}
|
||||
|
||||
/* ---- CDC Class-Specific Request Handler ---- */
|
||||
|
||||
usb_status_t USB_DeviceProcessClassRequest(usb_device_handle handle, usb_setup_struct_t *setup,
|
||||
uint32_t *length, uint8_t **buffer)
|
||||
{
|
||||
usb_status_t error = kStatus_USB_InvalidRequest;
|
||||
usb_cdc_acm_info_t *acmInfo = &s_usbCdcAcmInfo;
|
||||
uint32_t len;
|
||||
uint8_t *uartBitmap;
|
||||
|
||||
if (setup->wIndex != USB_CDC_VCOM_COMM_INTERFACE_INDEX)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
switch (setup->bRequest)
|
||||
{
|
||||
case USB_DEVICE_CDC_REQUEST_SEND_ENCAPSULATED_COMMAND:
|
||||
case USB_DEVICE_CDC_REQUEST_GET_ENCAPSULATED_RESPONSE:
|
||||
case USB_DEVICE_CDC_REQUEST_CLEAR_COMM_FEATURE:
|
||||
case USB_DEVICE_CDC_REQUEST_SEND_BREAK:
|
||||
break;
|
||||
|
||||
case USB_DEVICE_CDC_REQUEST_SET_COMM_FEATURE:
|
||||
if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT) &&
|
||||
(setup->wLength != 0U))
|
||||
{
|
||||
if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == setup->wValue)
|
||||
{
|
||||
(void) memcpy(s_abstractState, *buffer, COMM_FEATURE_DATA_SIZE);
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == setup->wValue)
|
||||
{
|
||||
(void) memcpy(s_countryCode, *buffer, COMM_FEATURE_DATA_SIZE);
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no action */
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DEVICE_CDC_REQUEST_GET_COMM_FEATURE:
|
||||
if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN) &&
|
||||
(setup->wLength != 0U))
|
||||
{
|
||||
if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == setup->wValue)
|
||||
{
|
||||
*buffer = s_abstractState;
|
||||
*length = COMM_FEATURE_DATA_SIZE;
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == setup->wValue)
|
||||
{
|
||||
*buffer = s_countryCode;
|
||||
*length = COMM_FEATURE_DATA_SIZE;
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no action */
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DEVICE_CDC_REQUEST_GET_LINE_CODING:
|
||||
if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN) &&
|
||||
(setup->wLength != 0U))
|
||||
{
|
||||
*buffer = s_lineCoding;
|
||||
*length = LINE_CODING_SIZE;
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DEVICE_CDC_REQUEST_SET_LINE_CODING:
|
||||
if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT) &&
|
||||
(setup->wLength != 0U))
|
||||
{
|
||||
(void) memcpy(s_lineCoding, *buffer, LINE_CODING_SIZE);
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE:
|
||||
{
|
||||
if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT) &&
|
||||
(setup->wLength == 0U))
|
||||
{
|
||||
error = kStatus_USB_Success;
|
||||
acmInfo->dteStatus = setup->wValue;
|
||||
|
||||
/* TX carrier */
|
||||
if ((acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION) != 0U)
|
||||
{
|
||||
acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
|
||||
}
|
||||
else
|
||||
{
|
||||
acmInfo->uartState &= (uint16_t) ~USB_DEVICE_CDC_UART_STATE_TX_CARRIER;
|
||||
}
|
||||
|
||||
/* RX carrier (DTE presence) */
|
||||
if ((acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) != 0U)
|
||||
{
|
||||
acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
|
||||
}
|
||||
else
|
||||
{
|
||||
acmInfo->uartState &= (uint16_t) ~USB_DEVICE_CDC_UART_STATE_RX_CARRIER;
|
||||
}
|
||||
|
||||
acmInfo->dtePresent =
|
||||
((acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) != 0U);
|
||||
|
||||
/* Формируем serial state notification */
|
||||
acmInfo->serialStateBuf[0] = NOTIF_REQUEST_TYPE;
|
||||
acmInfo->serialStateBuf[1] = USB_DEVICE_CDC_REQUEST_SERIAL_STATE_NOTIF;
|
||||
acmInfo->serialStateBuf[2] = 0x00U;
|
||||
acmInfo->serialStateBuf[3] = 0x00U;
|
||||
acmInfo->serialStateBuf[4] = (uint8_t) setup->wIndex;
|
||||
acmInfo->serialStateBuf[5] = 0x00U;
|
||||
acmInfo->serialStateBuf[6] = UART_BITMAP_SIZE;
|
||||
acmInfo->serialStateBuf[7] = 0x00U;
|
||||
|
||||
uartBitmap = &acmInfo->serialStateBuf[NOTIF_PACKET_SIZE];
|
||||
uartBitmap[0] = (uint8_t) (acmInfo->uartState & 0xFFU);
|
||||
uartBitmap[1] = (uint8_t) ((acmInfo->uartState >> 8U) & 0xFFU);
|
||||
|
||||
len = (uint32_t) (NOTIF_PACKET_SIZE + UART_BITMAP_SIZE);
|
||||
if (0U == s_cdcState.hasSentState)
|
||||
{
|
||||
error = USB_DeviceSendRequest(handle, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT,
|
||||
acmInfo->serialStateBuf, len);
|
||||
if (kStatus_USB_Success == error)
|
||||
{
|
||||
s_cdcState.hasSentState = 1U;
|
||||
}
|
||||
}
|
||||
|
||||
if (1U == s_cdcState.attach)
|
||||
{
|
||||
s_cdcState.startTransactions = 1U;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* ---- USB_DeviceCallback (bus reset, set configuration) ---- */
|
||||
|
||||
usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
|
||||
{
|
||||
usb_status_t error = kStatus_USB_InvalidRequest;
|
||||
uint8_t *temp8 = (uint8_t *) param;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case kUSB_DeviceEventBusReset:
|
||||
{
|
||||
USB_DeviceControlPipeInit(handle);
|
||||
s_cdcState.attach = 0U;
|
||||
s_cdcState.currentConfiguration = 0U;
|
||||
s_txIdle = 1U;
|
||||
s_recvSize = 0U;
|
||||
s_sendSize = 0U;
|
||||
error = kStatus_USB_Success;
|
||||
|
||||
if (kStatus_USB_Success ==
|
||||
USB_DeviceGetStatus(handle, kUSB_DeviceStatusSpeed, &s_cdcState.speed))
|
||||
{
|
||||
USB_DeviceSetSpeed(handle, s_cdcState.speed);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kUSB_DeviceEventSetConfiguration:
|
||||
{
|
||||
if (0U == (*temp8))
|
||||
{
|
||||
s_cdcState.attach = 0U;
|
||||
s_cdcState.currentConfiguration = 0U;
|
||||
s_cdcState.startTransactions = 0U;
|
||||
error = kStatus_USB_Success;
|
||||
}
|
||||
else if (USB_CDC_VCOM_CONFIGURE_INDEX == (*temp8))
|
||||
{
|
||||
usb_device_endpoint_init_struct_t epInit;
|
||||
usb_device_endpoint_callback_struct_t epCb;
|
||||
|
||||
s_cdcState.attach = 1U;
|
||||
s_cdcState.currentConfiguration = *temp8;
|
||||
|
||||
/* Interrupt IN endpoint */
|
||||
epCb.callbackFn = USB_DeviceCdcAcmInterruptIn;
|
||||
epCb.callbackParam = handle;
|
||||
epInit.zlt = 0U;
|
||||
epInit.transferType = USB_ENDPOINT_INTERRUPT;
|
||||
epInit.endpointAddress = USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT |
|
||||
(USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
|
||||
|
||||
if (USB_SPEED_HIGH == s_cdcState.speed)
|
||||
{
|
||||
epInit.maxPacketSize = HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
|
||||
epInit.interval = HS_CDC_VCOM_INTERRUPT_IN_INTERVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
epInit.maxPacketSize = FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE;
|
||||
epInit.interval = FS_CDC_VCOM_INTERRUPT_IN_INTERVAL;
|
||||
}
|
||||
USB_DeviceInitEndpoint(handle, &epInit, &epCb);
|
||||
|
||||
/* Bulk IN endpoint */
|
||||
epCb.callbackFn = USB_DeviceCdcAcmBulkIn;
|
||||
epCb.callbackParam = handle;
|
||||
epInit.zlt = 0U;
|
||||
epInit.interval = 0U;
|
||||
epInit.transferType = USB_ENDPOINT_BULK;
|
||||
epInit.endpointAddress = USB_CDC_VCOM_BULK_IN_ENDPOINT |
|
||||
(USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
|
||||
|
||||
if (USB_SPEED_HIGH == s_cdcState.speed)
|
||||
{
|
||||
epInit.maxPacketSize = HS_CDC_VCOM_BULK_IN_PACKET_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
epInit.maxPacketSize = FS_CDC_VCOM_BULK_IN_PACKET_SIZE;
|
||||
}
|
||||
USB_DeviceInitEndpoint(handle, &epInit, &epCb);
|
||||
|
||||
/* Bulk OUT endpoint */
|
||||
epCb.callbackFn = USB_DeviceCdcAcmBulkOut;
|
||||
epCb.callbackParam = handle;
|
||||
epInit.zlt = 0U;
|
||||
epInit.interval = 0U;
|
||||
epInit.transferType = USB_ENDPOINT_BULK;
|
||||
epInit.endpointAddress = USB_CDC_VCOM_BULK_OUT_ENDPOINT |
|
||||
(USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
|
||||
|
||||
if (USB_SPEED_HIGH == s_cdcState.speed)
|
||||
{
|
||||
epInit.maxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
|
||||
s_bulkMaxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
epInit.maxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
|
||||
s_bulkMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE;
|
||||
}
|
||||
USB_DeviceInitEndpoint(handle, &epInit, &epCb);
|
||||
|
||||
/* Планируем первый OUT transfer */
|
||||
error = USB_DeviceRecvRequest(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_recvBuf,
|
||||
s_bulkMaxPacketSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unknown configuration */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kUSB_DeviceEventSetInterface:
|
||||
error = kStatus_USB_Success;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Публичный API (BSP)
|
||||
* ======================================================================== */
|
||||
|
||||
bsp_status_t bsp_usb_cdc_init(void)
|
||||
{
|
||||
s_cdcState.speed = USB_SPEED_FULL;
|
||||
s_cdcState.attach = 0U;
|
||||
s_cdcState.startTransactions = 0U;
|
||||
s_cdcState.hasSentState = 0U;
|
||||
s_cdcState.currentConfiguration = 0U;
|
||||
s_txIdle = 1U;
|
||||
g_usbDeviceHandle = NULL;
|
||||
|
||||
USB_DeviceClockInit();
|
||||
|
||||
if (kStatus_USB_Success !=
|
||||
USB_DeviceInit(CONTROLLER_ID, USB_DeviceCallback, &g_usbDeviceHandle))
|
||||
{
|
||||
return BSP_ERR_HW;
|
||||
}
|
||||
|
||||
USB_DeviceIsrEnable();
|
||||
|
||||
/* FIXME:Задержка для стабилизации DP pull-down. */
|
||||
//SDK_DelayAtLeastUs(USB_ATTACH_DELAY_US, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
|
||||
bsp_delay(USB_ATTACH_DELAY_US / 1000);
|
||||
USB_DeviceRun(g_usbDeviceHandle);
|
||||
|
||||
return BSP_OK;
|
||||
}
|
||||
|
||||
bool bsp_usb_cdc_is_ready(void)
|
||||
{
|
||||
return (1U == s_cdcState.attach) && (1U == s_cdcState.startTransactions);
|
||||
}
|
||||
|
||||
bool bsp_usb_cdc_write_ready(void)
|
||||
{
|
||||
return bsp_usb_cdc_is_ready() && (1U == s_txIdle);
|
||||
}
|
||||
|
||||
bsp_status_t bsp_usb_cdc_write(const uint8_t *data, size_t len)
|
||||
{
|
||||
if ((data == NULL) || (len == 0U) || (len > DATA_BUFF_SIZE))
|
||||
{
|
||||
return BSP_ERR_INVALID;
|
||||
}
|
||||
|
||||
if (!bsp_usb_cdc_is_ready())
|
||||
{
|
||||
return BSP_ERR_NOT_READY;
|
||||
}
|
||||
|
||||
if (0U == s_txIdle)
|
||||
{
|
||||
return BSP_ERR_BUSY;
|
||||
}
|
||||
|
||||
/* Копируем в NonCacheable TX буфер и запускаем transfer. */
|
||||
(void) memcpy(s_sendBuf, data, len);
|
||||
|
||||
s_txIdle = 0U;
|
||||
|
||||
usb_status_t status = USB_DeviceSendRequest(g_usbDeviceHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT,
|
||||
s_sendBuf, (uint32_t) len);
|
||||
|
||||
if (kStatus_USB_Success != status)
|
||||
{
|
||||
s_txIdle = 1U;
|
||||
return BSP_ERR_HW;
|
||||
}
|
||||
|
||||
return BSP_OK;
|
||||
}
|
||||
|
||||
size_t bsp_usb_cdc_read(uint8_t *buf, size_t max_len)
|
||||
{
|
||||
if ((buf == NULL) || (max_len == 0U))
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
|
||||
if (!bsp_usb_cdc_is_ready())
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
|
||||
uint32_t sr;
|
||||
uint32_t available = 0U;
|
||||
|
||||
sr = DisableGlobalIRQ();
|
||||
if ((s_recvSize != 0U) && (s_recvSize != USB_CANCELLED_TRANSFER_LENGTH))
|
||||
{
|
||||
available = s_recvSize;
|
||||
s_recvSize = 0U;
|
||||
}
|
||||
EnableGlobalIRQ(sr);
|
||||
|
||||
if (available == 0U)
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
|
||||
size_t to_copy = (available > (uint32_t) max_len) ? max_len : (size_t) available;
|
||||
(void) memcpy(buf, s_recvBuf, to_copy);
|
||||
|
||||
/* Перепланируем приём следующего пакета. */
|
||||
USB_DeviceRecvRequest(g_usbDeviceHandle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_recvBuf,
|
||||
s_bulkMaxPacketSize);
|
||||
|
||||
return to_copy;
|
||||
}
|
||||
|
||||
void bsp_usb_cdc_poll(void)
|
||||
{
|
||||
/* Bare-metal: NXP USB стек на EHCI обрабатывает всё в ISR.
|
||||
* Эта функция зарезервирована для будущего использования
|
||||
* (USB_DEVICE_CONFIG_USE_TASK или software event processing). */
|
||||
}
|
||||
428
bsp/usb_cdc/src/usb_cdc_descriptors.c
Normal file
428
bsp/usb_cdc/src/usb_cdc_descriptors.c
Normal file
|
|
@ -0,0 +1,428 @@
|
|||
/*
|
||||
* Copyright 2025 MU LLC
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file usb_cdc_descriptors.c
|
||||
* @brief USB CDC ACM дескрипторы и descriptor callbacks.
|
||||
*
|
||||
* Содержит device/configuration/string дескрипторы и функции
|
||||
* которые NXP USB стек вызывает для получения дескрипторов при
|
||||
* enumeration. Также USB_DeviceSetSpeed() для обновления
|
||||
* дескрипторов при переключении HS/FS.
|
||||
*/
|
||||
|
||||
#include "usb.h"
|
||||
#include "usb_device.h"
|
||||
#include "usb_device_config.h"
|
||||
#include "usb_device_descriptor.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* ========================================================================
|
||||
* Глобальное состояние (используется ch9 callbacks)
|
||||
* ======================================================================== */
|
||||
|
||||
uint8_t g_currentConfigure = 0U;
|
||||
uint8_t g_interface[USB_CDC_VCOM_INTERFACE_COUNT];
|
||||
|
||||
/* ========================================================================
|
||||
* Device Descriptor
|
||||
* ======================================================================== */
|
||||
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
uint8_t g_UsbDeviceDescriptor[] = {
|
||||
USB_DESCRIPTOR_LENGTH_DEVICE,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE,
|
||||
USB_SHORT_GET_LOW(USB_DEVICE_SPECIFIC_BCD_VERSION),
|
||||
USB_SHORT_GET_HIGH(USB_DEVICE_SPECIFIC_BCD_VERSION),
|
||||
USB_DEVICE_CLASS,
|
||||
USB_DEVICE_SUBCLASS,
|
||||
USB_DEVICE_PROTOCOL,
|
||||
USB_CONTROL_MAX_PACKET_SIZE,
|
||||
USB_SHORT_GET_LOW(USB_DEVICE_VID),
|
||||
USB_SHORT_GET_HIGH(USB_DEVICE_VID),
|
||||
USB_SHORT_GET_LOW(USB_DEVICE_PID),
|
||||
USB_SHORT_GET_HIGH(USB_DEVICE_PID),
|
||||
USB_SHORT_GET_LOW(USB_DEVICE_DEMO_BCD_VERSION),
|
||||
USB_SHORT_GET_HIGH(USB_DEVICE_DEMO_BCD_VERSION),
|
||||
0x01U, /* iManufacturer */
|
||||
0x02U, /* iProduct */
|
||||
0x00U, /* iSerialNumber */
|
||||
USB_DEVICE_CONFIGURATION_COUNT,
|
||||
};
|
||||
|
||||
/* ========================================================================
|
||||
* Configuration Descriptor (CIC + DIC)
|
||||
* ======================================================================== */
|
||||
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
uint8_t g_UsbDeviceConfigurationDescriptor[] = {
|
||||
/* --- Configuration --- */
|
||||
USB_DESCRIPTOR_LENGTH_CONFIGURE,
|
||||
USB_DESCRIPTOR_TYPE_CONFIGURE,
|
||||
USB_SHORT_GET_LOW(USB_DESCRIPTOR_LENGTH_CONFIGURE + USB_DESCRIPTOR_LENGTH_INTERFACE +
|
||||
USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC + USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG +
|
||||
USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT + USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC +
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_INTERFACE +
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT + USB_DESCRIPTOR_LENGTH_ENDPOINT),
|
||||
USB_SHORT_GET_HIGH(USB_DESCRIPTOR_LENGTH_CONFIGURE + USB_DESCRIPTOR_LENGTH_INTERFACE +
|
||||
USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC +
|
||||
USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG + USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT +
|
||||
USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC + USB_DESCRIPTOR_LENGTH_ENDPOINT +
|
||||
USB_DESCRIPTOR_LENGTH_INTERFACE + USB_DESCRIPTOR_LENGTH_ENDPOINT +
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT),
|
||||
USB_CDC_VCOM_INTERFACE_COUNT,
|
||||
USB_CDC_VCOM_CONFIGURE_INDEX,
|
||||
0x00U, /* iConfiguration */
|
||||
(USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK) |
|
||||
(1U << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT),
|
||||
USB_DEVICE_MAX_POWER,
|
||||
|
||||
/* --- CIC: Communication Interface --- */
|
||||
USB_DESCRIPTOR_LENGTH_INTERFACE,
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE,
|
||||
USB_CDC_VCOM_COMM_INTERFACE_INDEX,
|
||||
USB_CDC_VCOM_COMM_INTERFACE_ALTERNATE_0,
|
||||
USB_CDC_VCOM_ENDPOINT_CIC_COUNT,
|
||||
USB_CDC_VCOM_CIC_CLASS,
|
||||
USB_CDC_VCOM_CIC_SUBCLASS,
|
||||
USB_CDC_VCOM_CIC_PROTOCOL,
|
||||
0x00U,
|
||||
|
||||
/* --- CDC Header Functional Descriptor --- */
|
||||
USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC,
|
||||
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE,
|
||||
USB_CDC_HEADER_FUNC_DESC,
|
||||
0x10U,
|
||||
0x01U,
|
||||
|
||||
/* --- CDC Call Management Functional Descriptor --- */
|
||||
USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG,
|
||||
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE,
|
||||
USB_CDC_CALL_MANAGEMENT_FUNC_DESC,
|
||||
0x01U,
|
||||
0x01U,
|
||||
|
||||
/* --- CDC ACM Functional Descriptor --- */
|
||||
USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT,
|
||||
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE,
|
||||
USB_CDC_ABSTRACT_CONTROL_FUNC_DESC,
|
||||
0x06U,
|
||||
|
||||
/* --- CDC Union Functional Descriptor --- */
|
||||
USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC,
|
||||
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE,
|
||||
USB_CDC_UNION_FUNC_DESC,
|
||||
USB_CDC_VCOM_COMM_INTERFACE_INDEX,
|
||||
USB_CDC_VCOM_DATA_INTERFACE_INDEX,
|
||||
|
||||
/* --- Notification Endpoint (Interrupt IN) --- */
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT,
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT | (USB_IN << 7U),
|
||||
USB_ENDPOINT_INTERRUPT,
|
||||
USB_SHORT_GET_LOW(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE),
|
||||
USB_SHORT_GET_HIGH(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE),
|
||||
FS_CDC_VCOM_INTERRUPT_IN_INTERVAL,
|
||||
|
||||
/* --- DIC: Data Interface --- */
|
||||
USB_DESCRIPTOR_LENGTH_INTERFACE,
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE,
|
||||
USB_CDC_VCOM_DATA_INTERFACE_INDEX,
|
||||
USB_CDC_VCOM_DATA_INTERFACE_ALTERNATE_0,
|
||||
USB_CDC_VCOM_ENDPOINT_DIC_COUNT,
|
||||
USB_CDC_VCOM_DIC_CLASS,
|
||||
USB_CDC_VCOM_DIC_SUBCLASS,
|
||||
USB_CDC_VCOM_DIC_PROTOCOL,
|
||||
0x00U,
|
||||
|
||||
/* --- Bulk IN Endpoint --- */
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT,
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
USB_CDC_VCOM_BULK_IN_ENDPOINT | (USB_IN << 7U),
|
||||
USB_ENDPOINT_BULK,
|
||||
USB_SHORT_GET_LOW(FS_CDC_VCOM_BULK_IN_PACKET_SIZE),
|
||||
USB_SHORT_GET_HIGH(FS_CDC_VCOM_BULK_IN_PACKET_SIZE),
|
||||
0x00U,
|
||||
|
||||
/* --- Bulk OUT Endpoint --- */
|
||||
USB_DESCRIPTOR_LENGTH_ENDPOINT,
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
USB_CDC_VCOM_BULK_OUT_ENDPOINT | (USB_OUT << 7U),
|
||||
USB_ENDPOINT_BULK,
|
||||
USB_SHORT_GET_LOW(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE),
|
||||
USB_SHORT_GET_HIGH(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE),
|
||||
0x00U,
|
||||
};
|
||||
|
||||
/* ========================================================================
|
||||
* String Descriptors
|
||||
* ======================================================================== */
|
||||
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
uint8_t g_UsbDeviceString0[] = {
|
||||
2U + 2U, USB_DESCRIPTOR_TYPE_STRING, 0x09U, 0x04U, /* English (US) */
|
||||
};
|
||||
|
||||
/* Manufacturer: "MU LLC" */
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
uint8_t g_UsbDeviceString1[] = {
|
||||
2U + 2U * 6U, USB_DESCRIPTOR_TYPE_STRING,
|
||||
'M', 0x00U,
|
||||
'U', 0x00U,
|
||||
' ', 0x00U,
|
||||
'L', 0x00U,
|
||||
'L', 0x00U,
|
||||
'C', 0x00U,
|
||||
};
|
||||
|
||||
/* Product: "TFT Indicator Board" */
|
||||
USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE)
|
||||
uint8_t g_UsbDeviceString2[] = {
|
||||
2U + 2U * 19U, USB_DESCRIPTOR_TYPE_STRING,
|
||||
'T', 0x00U,
|
||||
'F', 0x00U,
|
||||
'T', 0x00U,
|
||||
' ', 0x00U,
|
||||
'I', 0x00U,
|
||||
'n', 0x00U,
|
||||
'd', 0x00U,
|
||||
'i', 0x00U,
|
||||
'c', 0x00U,
|
||||
'a', 0x00U,
|
||||
't', 0x00U,
|
||||
'o', 0x00U,
|
||||
'r', 0x00U,
|
||||
' ', 0x00U,
|
||||
'B', 0x00U,
|
||||
'o', 0x00U,
|
||||
'a', 0x00U,
|
||||
'r', 0x00U,
|
||||
'd', 0x00U,
|
||||
};
|
||||
|
||||
/* ========================================================================
|
||||
* Language / String List (используется USB_DeviceGetDescriptor)
|
||||
* ======================================================================== */
|
||||
/* Массивы строк и длин — индексируются по (stringIndex - 1) */
|
||||
static uint8_t *g_UsbDeviceStringDescriptorArray[USB_DEVICE_STRING_COUNT] = {
|
||||
g_UsbDeviceString0,
|
||||
g_UsbDeviceString1,
|
||||
g_UsbDeviceString2,
|
||||
};
|
||||
|
||||
static uint32_t g_UsbDeviceStringDescriptorLength[USB_DEVICE_STRING_COUNT] = {
|
||||
sizeof(g_UsbDeviceString0),
|
||||
sizeof(g_UsbDeviceString1),
|
||||
sizeof(g_UsbDeviceString2),
|
||||
};
|
||||
|
||||
usb_language_t g_UsbDeviceLanguage[USB_DEVICE_LANGUAGE_COUNT] = { {
|
||||
g_UsbDeviceStringDescriptorArray,
|
||||
g_UsbDeviceStringDescriptorLength,
|
||||
(uint16_t) 0x0409U,
|
||||
} };
|
||||
|
||||
usb_language_list_t g_UsbDeviceLanguageList = {
|
||||
g_UsbDeviceString0,
|
||||
sizeof(g_UsbDeviceString0),
|
||||
g_UsbDeviceLanguage,
|
||||
USB_DEVICE_LANGUAGE_COUNT,
|
||||
};
|
||||
|
||||
/* ========================================================================
|
||||
* Descriptor Callbacks — вызываются NXP USB стеком
|
||||
* ======================================================================== */
|
||||
|
||||
usb_status_t USB_DeviceGetDescriptor(usb_device_handle handle, usb_setup_struct_t *setup,
|
||||
uint32_t *length, uint8_t **buffer)
|
||||
{
|
||||
uint8_t descriptorType = (uint8_t) ((setup->wValue & 0xFF00U) >> 8U);
|
||||
uint8_t descriptorIndex = (uint8_t) ((setup->wValue & 0x00FFU));
|
||||
usb_status_t ret = kStatus_USB_Success;
|
||||
|
||||
if (USB_REQUEST_STANDARD_GET_DESCRIPTOR != setup->bRequest)
|
||||
{
|
||||
return kStatus_USB_InvalidRequest;
|
||||
}
|
||||
|
||||
switch (descriptorType)
|
||||
{
|
||||
case USB_DESCRIPTOR_TYPE_STRING:
|
||||
{
|
||||
if (descriptorIndex == 0U)
|
||||
{
|
||||
*buffer = (uint8_t *) g_UsbDeviceLanguageList.languageString;
|
||||
*length = g_UsbDeviceLanguageList.stringLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t langId = USB_DEVICE_LANGUAGE_COUNT;
|
||||
|
||||
for (uint8_t i = 0U; i < USB_DEVICE_LANGUAGE_COUNT; i++)
|
||||
{
|
||||
if (setup->wIndex == g_UsbDeviceLanguageList.languageList[i].languageId)
|
||||
{
|
||||
langId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (USB_DEVICE_LANGUAGE_COUNT == langId)
|
||||
{
|
||||
ret = kStatus_USB_InvalidRequest;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t strIdx = descriptorIndex - 1U;
|
||||
if (strIdx < USB_DEVICE_STRING_COUNT)
|
||||
{
|
||||
*buffer = (uint8_t *) g_UsbDeviceLanguageList.languageList[langId].string[strIdx];
|
||||
*length = g_UsbDeviceLanguageList.languageList[langId].length[strIdx];
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = kStatus_USB_InvalidRequest;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case USB_DESCRIPTOR_TYPE_DEVICE:
|
||||
{
|
||||
*buffer = g_UsbDeviceDescriptor;
|
||||
*length = USB_DESCRIPTOR_LENGTH_DEVICE;
|
||||
break;
|
||||
}
|
||||
case USB_DESCRIPTOR_TYPE_CONFIGURE:
|
||||
{
|
||||
*buffer = g_UsbDeviceConfigurationDescriptor;
|
||||
*length = USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = kStatus_USB_InvalidRequest;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ---- Chapter 9: Set/Get Configure/Interface ---- */
|
||||
|
||||
usb_status_t USB_DeviceSetConfigure(usb_device_handle handle, uint8_t cfg)
|
||||
{
|
||||
if (cfg == 0U)
|
||||
{
|
||||
return kStatus_USB_Error;
|
||||
}
|
||||
g_currentConfigure = cfg;
|
||||
return USB_DeviceCallback(handle, kUSB_DeviceEventSetConfiguration, &cfg);
|
||||
}
|
||||
|
||||
usb_status_t USB_DeviceGetConfigure(usb_device_handle handle, uint8_t *cfg)
|
||||
{
|
||||
*cfg = g_currentConfigure;
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
|
||||
usb_status_t USB_DeviceSetInterface(usb_device_handle handle, uint8_t iface, uint8_t alt)
|
||||
{
|
||||
if (iface < USB_CDC_VCOM_INTERFACE_COUNT)
|
||||
{
|
||||
g_interface[iface] = alt;
|
||||
return USB_DeviceCallback(handle, kUSB_DeviceEventSetInterface, &iface);
|
||||
}
|
||||
return kStatus_USB_InvalidRequest;
|
||||
}
|
||||
|
||||
usb_status_t USB_DeviceGetInterface(usb_device_handle handle, uint8_t iface, uint8_t *alt)
|
||||
{
|
||||
if (iface < USB_CDC_VCOM_INTERFACE_COUNT)
|
||||
{
|
||||
*alt = g_interface[iface];
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
return kStatus_USB_InvalidRequest;
|
||||
}
|
||||
|
||||
/* ---- USB_DeviceSetSpeed ---- */
|
||||
|
||||
usb_status_t USB_DeviceSetSpeed(usb_device_handle handle, uint8_t speed)
|
||||
{
|
||||
usb_descriptor_union_t *ptr1;
|
||||
usb_descriptor_union_t *ptr2;
|
||||
|
||||
ptr1 = (usb_descriptor_union_t *) (&g_UsbDeviceConfigurationDescriptor[0]);
|
||||
ptr2 =
|
||||
(usb_descriptor_union_t
|
||||
*) (&g_UsbDeviceConfigurationDescriptor[USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL - 1U]);
|
||||
|
||||
while (ptr1 < ptr2)
|
||||
{
|
||||
if (ptr1->common.bDescriptorType == USB_DESCRIPTOR_TYPE_ENDPOINT)
|
||||
{
|
||||
/* Interrupt IN */
|
||||
if (((ptr1->endpoint.bEndpointAddress &
|
||||
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
|
||||
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
|
||||
((ptr1->endpoint.bEndpointAddress & 0x0FU) == USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT))
|
||||
{
|
||||
if (USB_SPEED_HIGH == speed)
|
||||
{
|
||||
ptr1->endpoint.bInterval = HS_CDC_VCOM_INTERRUPT_IN_INTERVAL;
|
||||
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE,
|
||||
ptr1->endpoint.wMaxPacketSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr1->endpoint.bInterval = FS_CDC_VCOM_INTERRUPT_IN_INTERVAL;
|
||||
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE,
|
||||
ptr1->endpoint.wMaxPacketSize);
|
||||
}
|
||||
}
|
||||
/* Bulk IN */
|
||||
else if (((ptr1->endpoint.bEndpointAddress &
|
||||
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
|
||||
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
|
||||
((ptr1->endpoint.bEndpointAddress & 0x0FU) == USB_CDC_VCOM_BULK_IN_ENDPOINT))
|
||||
{
|
||||
if (USB_SPEED_HIGH == speed)
|
||||
{
|
||||
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_BULK_IN_PACKET_SIZE,
|
||||
ptr1->endpoint.wMaxPacketSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_BULK_IN_PACKET_SIZE,
|
||||
ptr1->endpoint.wMaxPacketSize);
|
||||
}
|
||||
}
|
||||
/* Bulk OUT */
|
||||
else if (((ptr1->endpoint.bEndpointAddress &
|
||||
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
|
||||
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
|
||||
((ptr1->endpoint.bEndpointAddress & 0x0FU) == USB_CDC_VCOM_BULK_OUT_ENDPOINT))
|
||||
{
|
||||
if (USB_SPEED_HIGH == speed)
|
||||
{
|
||||
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_BULK_OUT_PACKET_SIZE,
|
||||
ptr1->endpoint.wMaxPacketSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE,
|
||||
ptr1->endpoint.wMaxPacketSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* other endpoints — no action */
|
||||
}
|
||||
}
|
||||
ptr1 = (usb_descriptor_union_t *) ((uint8_t *) ptr1 + ptr1->common.bLength);
|
||||
}
|
||||
|
||||
return kStatus_USB_Success;
|
||||
}
|
||||
97
bsp/usb_cdc/src/usb_cdc_hw.c
Normal file
97
bsp/usb_cdc/src/usb_cdc_hw.c
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright 2025 MU LLC
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file usb_cdc_hw.c
|
||||
* @brief Аппаратная инициализация USB1 (EHCI0): clock, PHY, IRQ.
|
||||
*
|
||||
* Функции вызываются из usb_cdc.c при инициализации.
|
||||
* IRQ handler делегирует обработку в NXP USB device stack.
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "clock_config.h"
|
||||
#include "usb.h"
|
||||
#include "usb_device.h"
|
||||
#include "usb_device_config.h"
|
||||
#include "usb_phy.h"
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Определения платы (из board.h / schematic)
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/** D_CAL, TXCAL45DP, TXCAL45DM — калибровка USB PHY. */
|
||||
#define BOARD_USB_PHY_D_CAL (0x0CU)
|
||||
#define BOARD_USB_PHY_TXCAL45DP (0x06U)
|
||||
#define BOARD_USB_PHY_TXCAL45DM (0x06U)
|
||||
|
||||
/** Приоритет USB прерывания (ниже числовое значение = выше приоритет). */
|
||||
#define USB_DEVICE_INTERRUPT_PRIORITY (3U)
|
||||
|
||||
/** Контроллер: USB1 = kUSB_ControllerEhci0. */
|
||||
#define CONTROLLER_ID kUSB_ControllerEhci0
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Внешний символ — handle USB device, определён в usb_cdc.c
|
||||
* -------------------------------------------------------------------------- */
|
||||
extern usb_device_handle g_usbDeviceHandle;
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* IRQ Handler
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief USB OTG1 IRQ — делегирует в NXP EHCI ISR.
|
||||
*
|
||||
* Имя совпадает с вектором прерывания в startup_MIMXRT1052.S.
|
||||
* Внутри — только вызов SDK функции, без блокировки и аллокаций.
|
||||
*/
|
||||
void USB_OTG1_IRQHandler(void)
|
||||
{
|
||||
USB_DeviceEhciIsrFunction(g_usbDeviceHandle);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Clock + PHY
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Включить тактирование USB1 PHY 480 MHz и инициализировать PHY.
|
||||
*
|
||||
* Вызывается один раз из bsp_usb_cdc_init() до USB_DeviceInit().
|
||||
*/
|
||||
void USB_DeviceClockInit(void)
|
||||
{
|
||||
usb_phy_config_struct_t phyConfig = {
|
||||
BOARD_USB_PHY_D_CAL,
|
||||
BOARD_USB_PHY_TXCAL45DP,
|
||||
BOARD_USB_PHY_TXCAL45DM,
|
||||
};
|
||||
|
||||
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
|
||||
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
|
||||
|
||||
USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ, &phyConfig);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* NVIC
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Разрешить USB1 прерывание в NVIC.
|
||||
*
|
||||
* Вызывается один раз из bsp_usb_cdc_init() после USB_DeviceInit().
|
||||
*/
|
||||
void USB_DeviceIsrEnable(void)
|
||||
{
|
||||
uint8_t irqNumber;
|
||||
uint8_t usbDeviceEhciIrq[] = USBHS_IRQS;
|
||||
|
||||
irqNumber = usbDeviceEhciIrq[CONTROLLER_ID - kUSB_ControllerEhci0];
|
||||
|
||||
NVIC_SetPriority((IRQn_Type) irqNumber, USB_DEVICE_INTERRUPT_PRIORITY);
|
||||
EnableIRQ((IRQn_Type) irqNumber);
|
||||
}
|
||||
86
bsp/usb_cdc/src/usb_device_cdc_acm.h
Normal file
86
bsp/usb_cdc/src/usb_device_cdc_acm.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _USB_DEVICE_CDC_ACM_H_
|
||||
#define _USB_DEVICE_CDC_ACM_H_ 1
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define USB_DEVICE_CONFIG_CDC_ACM_MAX_INSTANCE (1)
|
||||
|
||||
#define USB_DEVICE_CONFIG_CDC_COMM_CLASS_CODE (0x02)
|
||||
#define USB_DEVICE_CONFIG_CDC_DATA_CLASS_CODE (0x0A)
|
||||
|
||||
/* Class specific request Codes */
|
||||
#define USB_DEVICE_CDC_REQUEST_SEND_ENCAPSULATED_COMMAND (0x00)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_ENCAPSULATED_RESPONSE (0x01)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_COMM_FEATURE (0x02)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_COMM_FEATURE (0x03)
|
||||
#define USB_DEVICE_CDC_REQUEST_CLEAR_COMM_FEATURE (0x04)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_AUX_LINE_STATE (0x10)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_HOOK_STATE (0x11)
|
||||
#define USB_DEVICE_CDC_REQUEST_PULSE_SETUP (0x12)
|
||||
#define USB_DEVICE_CDC_REQUEST_SEND_PULSE (0x13)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_PULSE_TIME (0x14)
|
||||
#define USB_DEVICE_CDC_REQUEST_RING_AUX_JACK (0x15)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_LINE_CODING (0x20)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_LINE_CODING (0x21)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22)
|
||||
#define USB_DEVICE_CDC_REQUEST_SEND_BREAK (0x23)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_RINGER_PARAMS (0x30)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_RINGER_PARAMS (0x31)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_OPERATION_PARAM (0x32)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_OPERATION_PARAM (0x33)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_LINE_PARAMS (0x34)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_LINE_PARAMS (0x35)
|
||||
#define USB_DEVICE_CDC_REQUEST_DIAL_DIGITS (0x36)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_UNIT_PARAMETER (0x37)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_UNIT_PARAMETER (0x38)
|
||||
#define USB_DEVICE_CDC_REQUEST_CLEAR_UNIT_PARAMETER (0x39)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_PROFILE (0x3A)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_ETHERNET_MULTICAST_FILTERS (0x40)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_ETHERNET_POW_PATTER_FILTER (0x41)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_ETHERNET_POW_PATTER_FILTER (0x42)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_ETHERNET_PACKET_FILTER (0x43)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_ETHERNET_STATISTIC (0x44)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_ATM_DATA_FORMAT (0x50)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_ATM_DEVICE_STATISTICS (0x51)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_ATM_DEFAULT_VC (0x52)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_ATM_VC_STATISTICS (0x53)
|
||||
#define USB_DEVICE_CDC_REQUEST_MDLM_SPECIFIC_REQUESTS_MASK (0x7F)
|
||||
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_ABSTRACT_STATE (0x23)
|
||||
#define USB_DEVICE_CDC_REQUEST_GET_COUNTRY_SETTING (0x24)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_ABSTRACT_STATE (0x25)
|
||||
#define USB_DEVICE_CDC_REQUEST_SET_COUNTRY_SETTING (0x26)
|
||||
/* Class Specific Notification Codes */
|
||||
#define USB_DEVICE_CDC_REQUEST_NETWORK_CONNECTION_NOTIF (0x00)
|
||||
#define USB_DEVICE_CDC_REQUEST_RESPONSE_AVAIL_NOTIF (0x01)
|
||||
#define USB_DEVICE_CDC_REQUEST_AUX_JACK_HOOK_STATE_NOTIF (0x08)
|
||||
#define USB_DEVICE_CDC_REQUEST_RING_DETECT_NOTIF (0x09)
|
||||
#define USB_DEVICE_CDC_REQUEST_SERIAL_STATE_NOTIF (0x20)
|
||||
#define USB_DEVICE_CDC_REQUEST_CALL_STATE_CHANGE_NOTIF (0x28)
|
||||
#define USB_DEVICE_CDC_REQUEST_LINE_STATE_CHANGE_NOTIF (0x29)
|
||||
#define USB_DEVICE_CDC_REQUEST_CONNECTION_SPEED_CHANGE_NOTIF (0x2A)
|
||||
/* Communications Feature Selector Codes */
|
||||
#define USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE (0x01)
|
||||
#define USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING (0x02)
|
||||
/* Control Signal Bitmap Values */
|
||||
#define USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION (0x02)
|
||||
#define USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE (0x01)
|
||||
/* UART State Bitmap Values */
|
||||
#define USB_DEVICE_CDC_UART_STATE_RX_CARRIER (0x01)
|
||||
#define USB_DEVICE_CDC_UART_STATE_TX_CARRIER (0x02)
|
||||
#define USB_DEVICE_CDC_UART_STATE_BREAK (0x04)
|
||||
#define USB_DEVICE_CDC_UART_STATE_RING_SIGNAL (0x08)
|
||||
#define USB_DEVICE_CDC_UART_STATE_FRAMING (0x10)
|
||||
#define USB_DEVICE_CDC_UART_STATE_PARITY (0x20)
|
||||
#define USB_DEVICE_CDC_UART_STATE_OVERRUN (0x40)
|
||||
|
||||
#endif /* _USB_DEVICE_CDC_ACM_H_ */
|
||||
1014
bsp/usb_cdc/src/usb_device_ch9.c
Normal file
1014
bsp/usb_cdc/src/usb_device_ch9.c
Normal file
File diff suppressed because it is too large
Load diff
86
bsp/usb_cdc/src/usb_device_ch9.h
Normal file
86
bsp/usb_cdc/src/usb_device_ch9.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __USB_DEVICE_CH9_H__
|
||||
#define __USB_DEVICE_CH9_H__
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @addtogroup usb_device_ch9
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Defines USB device status size when the host request to get device status */
|
||||
#define USB_DEVICE_STATUS_SIZE (0x02U)
|
||||
|
||||
/*! @brief Defines USB device interface status size when the host request to get interface status */
|
||||
#define USB_INTERFACE_STATUS_SIZE (0x02U)
|
||||
|
||||
/*! @brief Defines USB device endpoint status size when the host request to get endpoint status */
|
||||
#define USB_ENDPOINT_STATUS_SIZE (0x02U)
|
||||
|
||||
/*! @brief Defines USB device configuration size when the host request to get current configuration */
|
||||
#define USB_CONFIGURE_SIZE (0X01U)
|
||||
|
||||
/*! @brief Defines USB device interface alternate setting size when the host request to get interface alternate setting
|
||||
*/
|
||||
#define USB_INTERFACE_SIZE (0X01U)
|
||||
|
||||
/*! @brief Defines USB device status mask */
|
||||
#define USB_GET_STATUS_DEVICE_MASK (0x03U)
|
||||
|
||||
/*! @brief Defines USB device interface status mask */
|
||||
#define USB_GET_STATUS_INTERFACE_MASK (0x03U)
|
||||
|
||||
/*! @brief Defines USB device endpoint status mask */
|
||||
#define USB_GET_STATUS_ENDPOINT_MASK (0x03U)
|
||||
|
||||
/*! @brief Control read and write sequence */
|
||||
typedef enum _usb_device_control_read_write_sequence
|
||||
{
|
||||
kUSB_DeviceControlPipeSetupStage = 0U, /*!< Setup stage */
|
||||
kUSB_DeviceControlPipeDataStage, /*!< Data stage */
|
||||
kUSB_DeviceControlPipeStatusStage, /*!< status stage */
|
||||
} usb_device_control_read_write_sequence_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
/*!
|
||||
* @brief Initialize the control pipes.
|
||||
*
|
||||
* The function is used to initialize the control pipes. This function should be called when event
|
||||
* kUSB_DeviceEventBusReset is received.
|
||||
*
|
||||
* @param handle The device handle.
|
||||
*
|
||||
* @return A USB error code or kStatus_USB_Success.
|
||||
*/
|
||||
extern usb_status_t USB_DeviceControlPipeInit(usb_device_handle handle);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @}*/
|
||||
|
||||
#endif /* __USB_DEVICE_CH9_H__ */
|
||||
52
bsp/usb_cdc/src/usb_device_config.h
Normal file
52
bsp/usb_cdc/src/usb_device_config.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2025 TFT Project
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file usb_device_config.h
|
||||
* @brief Конфигурация NXP USB Device Stack для bsp_usb_cdc.
|
||||
*
|
||||
* Этот файл — application-specific конфиг, который NXP USB middleware
|
||||
* подключает через include path. Не является частью SDK.
|
||||
*
|
||||
* Настройки под bare-metal CDC ACM на USB1 (EHCI0).
|
||||
*/
|
||||
#ifndef USB_DEVICE_CONFIG_H_
|
||||
#define USB_DEVICE_CONFIG_H_
|
||||
|
||||
/* ---- Контроллер -------------------------------------------------------- */
|
||||
#define USB_DEVICE_CONFIG_EHCI (1U)
|
||||
#define USB_DEVICE_CONFIG_KHCI (0U)
|
||||
#define USB_DEVICE_CONFIG_LPCIP3511FS (0U)
|
||||
#define USB_DEVICE_CONFIG_LPCIP3511HS (0U)
|
||||
|
||||
/** Суммарное количество активных контроллеров. */
|
||||
#define USB_DEVICE_CONFIG_NUM \
|
||||
(USB_DEVICE_CONFIG_EHCI + USB_DEVICE_CONFIG_KHCI + USB_DEVICE_CONFIG_LPCIP3511FS + \
|
||||
USB_DEVICE_CONFIG_LPCIP3511HS)
|
||||
|
||||
/* ---- EHCI-специфичные -------------------------------------------------- */
|
||||
#define USB_DEVICE_CONFIG_EHCI_MAX_DTD (16U)
|
||||
|
||||
/* ---- Классы устройства ------------------------------------------------- */
|
||||
#define USB_DEVICE_CONFIG_CDC_ACM (1U)
|
||||
#define USB_DEVICE_CONFIG_HID (0U)
|
||||
#define USB_DEVICE_CONFIG_MSC (0U)
|
||||
#define USB_DEVICE_CONFIG_AUDIO (0U)
|
||||
#define USB_DEVICE_CONFIG_VIDEO (0U)
|
||||
#define USB_DEVICE_CONFIG_PHDC (0U)
|
||||
#define USB_DEVICE_CONFIG_DFU (0U)
|
||||
#define USB_DEVICE_CONFIG_PRINTER (0U)
|
||||
#define USB_DEVICE_CONFIG_CCID (0U)
|
||||
#define USB_DEVICE_CONFIG_MTP (0U)
|
||||
#define USB_DEVICE_CONFIG_CDC_ECM (0U)
|
||||
#define USB_DEVICE_CONFIG_CDC_RNDIS (0U)
|
||||
|
||||
/* ---- Общие настройки --------------------------------------------------- */
|
||||
#define USB_DEVICE_CONFIG_ENDPOINTS (4U)
|
||||
#define USB_DEVICE_CONFIG_SELF_POWER (1U)
|
||||
#define USB_DEVICE_CONFIG_MAX_MESSAGES (8U)
|
||||
#define USB_DEVICE_CONFIG_ROOT2_TEST (0U)
|
||||
|
||||
#endif /* USB_DEVICE_CONFIG_H_ */
|
||||
116
bsp/usb_cdc/src/usb_device_descriptor.h
Normal file
116
bsp/usb_cdc/src/usb_device_descriptor.h
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright 2025 TFT Project
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file usb_device_descriptor.h
|
||||
* @brief USB CDC ACM дескрипторы — константы и прототипы.
|
||||
*
|
||||
* Определяет VID/PID, номера эндпоинтов, размеры пакетов.
|
||||
* Используется только внутри bsp_usb_cdc.
|
||||
*/
|
||||
|
||||
#ifndef USB_DEVICE_DESCRIPTOR_H_
|
||||
#define USB_DEVICE_DESCRIPTOR_H_
|
||||
|
||||
/* ---- Версии USB -------------------------------------------------------- */
|
||||
#define USB_DEVICE_SPECIFIC_BCD_VERSION (0x0200U)
|
||||
#define USB_DEVICE_DEMO_BCD_VERSION (0x0101U)
|
||||
|
||||
/* ---- VID / PID --------------------------------------------------------- */
|
||||
#define USB_DEVICE_VID (0x1996U) /* TODO: заменить на свой */
|
||||
#define USB_DEVICE_PID (0x00ADU) /* TODO: заменить на свой */
|
||||
|
||||
/* ---- CDC коды классов -------------------------------------------------- */
|
||||
#define CDC_COMM_CLASS (0x02U)
|
||||
#define CDC_DATA_CLASS (0x0AU)
|
||||
|
||||
/* ---- CDC SubClass / Protocol ------------------------------------------- */
|
||||
#define USB_CDC_ABSTRACT_CONTROL_MODEL (0x02U)
|
||||
#define USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL (0x00U)
|
||||
|
||||
/* ---- Functional Descriptor SubTypes ------------------------------------ */
|
||||
#define USB_CDC_HEADER_FUNC_DESC (0x00U)
|
||||
#define USB_CDC_CALL_MANAGEMENT_FUNC_DESC (0x01U)
|
||||
#define USB_CDC_ABSTRACT_CONTROL_FUNC_DESC (0x02U)
|
||||
#define USB_CDC_UNION_FUNC_DESC (0x06U)
|
||||
|
||||
/* ---- Длины функциональных дескрипторов --------------------------------- */
|
||||
#define USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC (5U)
|
||||
#define USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG (5U)
|
||||
#define USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT (4U)
|
||||
#define USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC (5U)
|
||||
|
||||
/* ---- CS Descriptor Types ----------------------------------------------- */
|
||||
#define USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE (0x24U)
|
||||
#define USB_DESCRIPTOR_TYPE_CDC_CS_ENDPOINT (0x25U)
|
||||
|
||||
/* ---- Конфигурация, интерфейсы, эндпоинты ------------------------------- */
|
||||
#define USB_DEVICE_CONFIGURATION_COUNT (1U)
|
||||
#define USB_DEVICE_STRING_COUNT (3U)
|
||||
#define USB_DEVICE_LANGUAGE_COUNT (1U)
|
||||
|
||||
#define USB_CDC_VCOM_CONFIGURE_INDEX (1U)
|
||||
|
||||
#define USB_CDC_VCOM_ENDPOINT_CIC_COUNT (1U)
|
||||
#define USB_CDC_VCOM_ENDPOINT_DIC_COUNT (2U)
|
||||
|
||||
#define USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT (1U)
|
||||
#define USB_CDC_VCOM_BULK_IN_ENDPOINT (2U)
|
||||
#define USB_CDC_VCOM_BULK_OUT_ENDPOINT (3U)
|
||||
|
||||
#define USB_CDC_VCOM_INTERFACE_COUNT (2U)
|
||||
#define USB_CDC_VCOM_COMM_INTERFACE_INDEX (0U)
|
||||
#define USB_CDC_VCOM_DATA_INTERFACE_INDEX (1U)
|
||||
|
||||
/* ---- Размеры пакетов --------------------------------------------------- */
|
||||
#define HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE (16U)
|
||||
#define FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE (16U)
|
||||
#define HS_CDC_VCOM_INTERRUPT_IN_INTERVAL (0x07U)
|
||||
#define FS_CDC_VCOM_INTERRUPT_IN_INTERVAL (0x08U)
|
||||
|
||||
#define HS_CDC_VCOM_BULK_IN_PACKET_SIZE (512U)
|
||||
#define FS_CDC_VCOM_BULK_IN_PACKET_SIZE (64U)
|
||||
#define HS_CDC_VCOM_BULK_OUT_PACKET_SIZE (512U)
|
||||
#define FS_CDC_VCOM_BULK_OUT_PACKET_SIZE (64U)
|
||||
|
||||
/* ---- Device class codes ------------------------------------------------ */
|
||||
#define USB_DEVICE_CLASS (0x02U)
|
||||
#define USB_DEVICE_SUBCLASS (0x00U)
|
||||
#define USB_DEVICE_PROTOCOL (0x00U)
|
||||
#define USB_DEVICE_MAX_POWER (0x32U)
|
||||
|
||||
/* ---- CIC / DIC class codes -------------------------------------------- */
|
||||
#define USB_CDC_VCOM_CIC_CLASS (CDC_COMM_CLASS)
|
||||
#define USB_CDC_VCOM_CIC_SUBCLASS (USB_CDC_ABSTRACT_CONTROL_MODEL)
|
||||
#define USB_CDC_VCOM_CIC_PROTOCOL (USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL)
|
||||
#define USB_CDC_VCOM_DIC_CLASS (CDC_DATA_CLASS)
|
||||
#define USB_CDC_VCOM_DIC_SUBCLASS (0x00U)
|
||||
#define USB_CDC_VCOM_DIC_PROTOCOL (USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL)
|
||||
|
||||
/* ---- Alternate settings ------------------------------------------------ */
|
||||
#define USB_CDC_VCOM_COMM_INTERFACE_ALTERNATE_COUNT (1U)
|
||||
#define USB_CDC_VCOM_DATA_INTERFACE_ALTERNATE_COUNT (1U)
|
||||
#define USB_CDC_VCOM_COMM_INTERFACE_ALTERNATE_0 (0U)
|
||||
#define USB_CDC_VCOM_DATA_INTERFACE_ALTERNATE_0 (0U)
|
||||
|
||||
/* ---- String descriptor lengths (computed from arrays) ------------------ */
|
||||
#define USB_DESCRIPTOR_LENGTH_STRING0 (sizeof(g_UsbDeviceString0))
|
||||
#define USB_DESCRIPTOR_LENGTH_STRING1 (sizeof(g_UsbDeviceString1))
|
||||
#define USB_DESCRIPTOR_LENGTH_STRING2 (sizeof(g_UsbDeviceString2))
|
||||
#define USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL (sizeof(g_UsbDeviceConfigurationDescriptor))
|
||||
|
||||
/* ---- Прототипы (реализация в usb_cdc.c) -------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Обработка USB device событий (bus reset, set config и т.д.).
|
||||
*/
|
||||
extern usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param);
|
||||
|
||||
/**
|
||||
* @brief Обновление дескрипторов при смене скорости HS/FS.
|
||||
*/
|
||||
extern usb_status_t USB_DeviceSetSpeed(usb_device_handle handle, uint8_t speed);
|
||||
|
||||
#endif /* USB_DEVICE_DESCRIPTOR_H_ */
|
||||
|
|
@ -18,11 +18,9 @@ target_link_libraries(
|
|||
PRIVATE bsp_board
|
||||
bsp_led
|
||||
bsp_tick
|
||||
bsp_can
|
||||
bsp_button
|
||||
bsp_uart_host
|
||||
bsp_boot_xip
|
||||
bsp_opto
|
||||
bsp_usb_cdc
|
||||
port_log_uart
|
||||
lib_external # SEGGER RTT если включён через SEGGER_RTT_ENABLED
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,65 +3,12 @@
|
|||
#include "bsp/led.h"
|
||||
#include "bsp/tick.h"
|
||||
#include "bsp/uart_host.h"
|
||||
#include "fsl_common.h"
|
||||
#include "bsp/usb_cdc.h"
|
||||
#include "log/log.h"
|
||||
#include "port/log_uart.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Проверка non-cacheable региона
|
||||
* --------------------------------------------------------------------------
|
||||
* Буфер размещён в секции NonCacheable — OCRAM @ 0x20200000.
|
||||
* MPU Region 9 настраивает эту область как Normal non-cacheable,
|
||||
* поэтому записи CPU сразу видны DMA без SCB_CleanDCache().
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
#define NCACHE_TEST_BUF_SIZE 64U
|
||||
#define NCACHE_REGION_BASE 0x20200000U
|
||||
#define NCACHE_REGION_END 0x20202000U /* 8 KB — размер из линкер-скрипта */
|
||||
|
||||
AT_NONCACHEABLE_SECTION_ALIGN(static uint8_t s_ncache_buf[NCACHE_TEST_BUF_SIZE], 4U);
|
||||
|
||||
static bool ncache_test_run(void)
|
||||
{
|
||||
uint32_t buf_addr = (uint32_t) s_ncache_buf;
|
||||
|
||||
/* Проверяем что буфер физически лежит в ожидаемом ncache регионе */
|
||||
if (buf_addr < NCACHE_REGION_BASE || buf_addr >= NCACHE_REGION_END)
|
||||
{
|
||||
LOG_E("NCACHE", "buf addr 0x%08lx outside ncache region [0x%08x..0x%08x)",
|
||||
(unsigned long) buf_addr, NCACHE_REGION_BASE, NCACHE_REGION_END);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Записываем паттерн */
|
||||
for (uint32_t i = 0U; i < NCACHE_TEST_BUF_SIZE; i++)
|
||||
{
|
||||
s_ncache_buf[i] = (uint8_t) (i ^ 0xA5U);
|
||||
}
|
||||
|
||||
/* Для non-cacheable памяти flush не нужен — данные уже когерентны.
|
||||
* Вызываем CleanDCache чтобы убедиться что он не ломает данные. */
|
||||
SCB_CleanDCache();
|
||||
|
||||
/* Читаем обратно и сравниваем */
|
||||
for (uint32_t i = 0U; i < NCACHE_TEST_BUF_SIZE; i++)
|
||||
{
|
||||
uint8_t expected = (uint8_t) (i ^ 0xA5U);
|
||||
|
||||
if (s_ncache_buf[i] != expected)
|
||||
{
|
||||
LOG_E("NCACHE", "mismatch at [%lu]: got 0x%02x expected 0x%02x", (unsigned long) i,
|
||||
s_ncache_buf[i], expected);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
|
@ -76,20 +23,22 @@ int main(void)
|
|||
|
||||
LOG_I("BOOT", "firmware_test started, tick=%lu", (unsigned long) bsp_tick_get_ms());
|
||||
|
||||
if (ncache_test_run())
|
||||
if (bsp_usb_cdc_init() == BSP_OK)
|
||||
{
|
||||
LOG_I("NCACHE", "OK addr=0x%08lx size=%u", (unsigned long) (uint32_t) s_ncache_buf,
|
||||
NCACHE_TEST_BUF_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("NCACHE", "FAIL");
|
||||
LOG_I("BOOT", "USB CDC ACM initialized");
|
||||
}
|
||||
|
||||
bsp_led_on(LED_APP);
|
||||
|
||||
bool is_connection_established = false;
|
||||
while (1)
|
||||
{
|
||||
if (bsp_usb_cdc_is_ready() == true && is_connection_established == false)
|
||||
{
|
||||
is_connection_established = true;
|
||||
LOG_I("BOOT", "USB CDC ACM ready");
|
||||
}
|
||||
|
||||
bsp_usb_cdc_poll();
|
||||
bsp_led_toggle(LED_HEARTBEAT);
|
||||
bsp_delay(DELAY_MS);
|
||||
}
|
||||
|
|
|
|||
317
project_tree.txt
317
project_tree.txt
|
|
@ -1,317 +0,0 @@
|
|||
.
|
||||
├── CMakeLists.txt
|
||||
├── CMakePresets.json
|
||||
├── Justfile
|
||||
├── README.md
|
||||
├── bootstrap.sh
|
||||
├── bsp
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── README.md
|
||||
│ ├── button
|
||||
│ │ ├── CMakeLists.txt
|
||||
│ │ ├── README.md
|
||||
│ │ ├── include
|
||||
│ │ └── src
|
||||
│ ├── can
|
||||
│ │ ├── CMakeLists.txt
|
||||
│ │ ├── README.md
|
||||
│ │ ├── include
|
||||
│ │ ├── mocks
|
||||
│ │ └── src
|
||||
│ ├── common
|
||||
│ │ ├── CMakeLists.txt
|
||||
│ │ └── include
|
||||
│ ├── generated
|
||||
│ │ ├── README.md
|
||||
│ │ ├── TFT_Board.mex
|
||||
│ │ ├── board
|
||||
│ │ ├── board.c
|
||||
│ │ ├── board.h
|
||||
│ │ ├── clock_config.c
|
||||
│ │ ├── clock_config.h
|
||||
│ │ ├── pin_mux.c
|
||||
│ │ ├── pin_mux.h
|
||||
│ │ ├── startup
|
||||
│ │ └── syscalls.c
|
||||
│ ├── led
|
||||
│ │ ├── CMakeLists.txt
|
||||
│ │ ├── README.md
|
||||
│ │ ├── include
|
||||
│ │ └── src
|
||||
│ ├── opto
|
||||
│ │ ├── CMakeLists.txt
|
||||
│ │ ├── README.md
|
||||
│ │ ├── include
|
||||
│ │ └── src
|
||||
│ ├── sdram
|
||||
│ │ ├── README.md
|
||||
│ │ ├── include
|
||||
│ │ └── src
|
||||
│ ├── tick
|
||||
│ │ ├── CMakeLists.txt
|
||||
│ │ ├── README.md
|
||||
│ │ ├── include
|
||||
│ │ └── src
|
||||
│ ├── uart_host
|
||||
│ │ ├── CMakeLists.txt
|
||||
│ │ ├── README.md
|
||||
│ │ ├── include
|
||||
│ │ ├── mocks
|
||||
│ │ └── src
|
||||
│ └── usb_cdc
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── README.md
|
||||
│ ├── include
|
||||
│ └── src
|
||||
├── build
|
||||
│ ├── Debug
|
||||
│ │ ├── CMakeCache.txt
|
||||
│ │ ├── CMakeFiles
|
||||
│ │ ├── bsp
|
||||
│ │ ├── build.ninja
|
||||
│ │ ├── cmake_install.cmake
|
||||
│ │ ├── compile_commands.json
|
||||
│ │ ├── firmware
|
||||
│ │ ├── firmware_test.bin
|
||||
│ │ ├── firmware_test.elf
|
||||
│ │ ├── firmware_test.map
|
||||
│ │ ├── firmware_test_hab.bin
|
||||
│ │ ├── lib
|
||||
│ │ ├── port
|
||||
│ │ ├── sdk
|
||||
│ │ └── utils
|
||||
│ ├── host-debug
|
||||
│ │ ├── CMakeCache.txt
|
||||
│ │ ├── CMakeFiles
|
||||
│ │ ├── CTestTestfile.cmake
|
||||
│ │ ├── Testing
|
||||
│ │ ├── bsp
|
||||
│ │ ├── build.ninja
|
||||
│ │ ├── cmake_install.cmake
|
||||
│ │ ├── compile_commands.json
|
||||
│ │ ├── lib
|
||||
│ │ ├── port
|
||||
│ │ ├── sdk
|
||||
│ │ ├── tests
|
||||
│ │ └── utils
|
||||
│ └── host-release
|
||||
│ ├── CMakeCache.txt
|
||||
│ ├── CMakeFiles
|
||||
│ ├── CTestTestfile.cmake
|
||||
│ ├── Testing
|
||||
│ ├── bsp
|
||||
│ ├── build.ninja
|
||||
│ ├── cmake_install.cmake
|
||||
│ ├── compile_commands.json
|
||||
│ ├── lib
|
||||
│ ├── port
|
||||
│ ├── sdk
|
||||
│ ├── tests
|
||||
│ └── utils
|
||||
├── cmake
|
||||
│ ├── linker
|
||||
│ │ ├── MIMXRT1052xxxxx_flexspi_nor.ld
|
||||
│ │ ├── MIMXRT1052xxxxx_flexspi_nor_sdram.ld
|
||||
│ │ ├── MIMXRT1052xxxxx_ram.ld
|
||||
│ │ ├── MIMXRT1052xxxxx_sdram.ld
|
||||
│ │ └── MIMXRT1052xxxxx_sdram_txt.ld
|
||||
│ ├── toolchain_arm.cmake
|
||||
│ └── toolchain_host.cmake
|
||||
├── docs
|
||||
│ ├── DEV_ARCH.md
|
||||
│ ├── HOW_TO_DEBUG.md
|
||||
│ ├── HOW_TO_FLASH.md
|
||||
│ ├── hardware
|
||||
│ │ ├── MCULINKINSERT.pdf
|
||||
│ │ ├── board
|
||||
│ │ └── m5stamPLC
|
||||
│ ├── mimxrt1052
|
||||
│ │ ├── BOOT_FLAGS.md
|
||||
│ │ ├── HAB_GUIDE.md
|
||||
│ │ ├── manufacturing_user's_guide.pdf
|
||||
│ │ └── mcu_rm.pdf
|
||||
│ └── testing
|
||||
│ ├── hil
|
||||
│ └── host
|
||||
├── firmware
|
||||
│ ├── bootloader
|
||||
│ ├── test
|
||||
│ │ ├── CMakeLists.txt
|
||||
│ │ ├── README.md
|
||||
│ │ ├── arch.svg
|
||||
│ │ └── main.c
|
||||
│ └── tft_app
|
||||
├── just
|
||||
│ ├── build.just
|
||||
│ ├── ci.just
|
||||
│ └── host.just
|
||||
├── lib
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── SEGGER
|
||||
│ │ ├── RTT
|
||||
│ │ └── wrapper
|
||||
│ ├── Unity
|
||||
│ │ ├── CMakeLists.txt
|
||||
│ │ ├── LICENSE.txt
|
||||
│ │ ├── README.md
|
||||
│ │ ├── auto
|
||||
│ │ ├── docs
|
||||
│ │ ├── examples
|
||||
│ │ ├── extras
|
||||
│ │ ├── library.json
|
||||
│ │ ├── meson.build
|
||||
│ │ ├── meson_options.txt
|
||||
│ │ ├── platformio-build.py
|
||||
│ │ ├── src
|
||||
│ │ ├── test
|
||||
│ │ └── unityConfig.cmake
|
||||
│ └── fff
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── LICENSE
|
||||
│ ├── README.md
|
||||
│ ├── buildandtest
|
||||
│ ├── examples
|
||||
│ ├── fakegen.rb
|
||||
│ ├── fff.h
|
||||
│ └── test
|
||||
├── port
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── README.md
|
||||
│ └── log
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── README.md
|
||||
│ ├── include
|
||||
│ └── src
|
||||
├── project_tree.txt
|
||||
├── pyocd.yaml
|
||||
├── pyocd_debug.yaml
|
||||
├── sdk
|
||||
│ ├── CMSIS
|
||||
│ │ ├── Core
|
||||
│ │ ├── DSP
|
||||
│ │ ├── Driver
|
||||
│ │ ├── LICENSE.txt
|
||||
│ │ ├── NN
|
||||
│ │ └── RTOS2
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── COPYING-BSD-3
|
||||
│ ├── LA_OPT_NXP_Software_License.txt
|
||||
│ ├── MIMXRT1052xxxxB_manifest_v3_15.xml
|
||||
│ ├── README.md
|
||||
│ ├── SW-Content-Register.txt
|
||||
│ ├── boards
|
||||
│ │ └── evkbimxrt1050
|
||||
│ ├── components
|
||||
│ │ ├── audio
|
||||
│ │ ├── button
|
||||
│ │ ├── codec
|
||||
│ │ ├── common_task
|
||||
│ │ ├── crc
|
||||
│ │ ├── display
|
||||
│ │ ├── exception_handling
|
||||
│ │ ├── flash
|
||||
│ │ ├── gpio
|
||||
│ │ ├── i2c
|
||||
│ │ ├── internal_flash
|
||||
│ │ ├── led
|
||||
│ │ ├── lists
|
||||
│ │ ├── log
|
||||
│ │ ├── mem_manager
|
||||
│ │ ├── messaging
|
||||
│ │ ├── mx25r_flash
|
||||
│ │ ├── osa
|
||||
│ │ ├── panic
|
||||
│ │ ├── phy
|
||||
│ │ ├── pmic
|
||||
│ │ ├── reset
|
||||
│ │ ├── rng
|
||||
│ │ ├── rtt
|
||||
│ │ ├── sensor
|
||||
│ │ ├── serial_manager
|
||||
│ │ ├── silicon_id
|
||||
│ │ ├── spi
|
||||
│ │ ├── timer
|
||||
│ │ ├── timer_manager
|
||||
│ │ ├── touch
|
||||
│ │ ├── uart
|
||||
│ │ ├── video
|
||||
│ │ └── wifi_bt_module
|
||||
│ ├── devices
|
||||
│ │ └── MIMXRT1052
|
||||
│ ├── docs
|
||||
│ │ └── readme.md
|
||||
│ ├── middleware
|
||||
│ │ ├── audio_voice
|
||||
│ │ ├── cjson
|
||||
│ │ ├── dhara
|
||||
│ │ ├── fatfs
|
||||
│ │ ├── freemaster
|
||||
│ │ ├── libjpeg
|
||||
│ │ ├── littlefs
|
||||
│ │ ├── mcuboot_opensource
|
||||
│ │ ├── pkcs11
|
||||
│ │ ├── pngdec
|
||||
│ │ ├── sdmmc
|
||||
│ │ ├── tfm
|
||||
│ │ ├── tinycbor
|
||||
│ │ └── usb
|
||||
│ ├── rtos
|
||||
│ │ └── freertos
|
||||
│ └── tools
|
||||
│ └── cmake_toolchain_files
|
||||
├── tests
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── host
|
||||
│ │ ├── CMakeLists.txt
|
||||
│ │ ├── README.md
|
||||
│ │ ├── button
|
||||
│ │ ├── can
|
||||
│ │ ├── led
|
||||
│ │ ├── log
|
||||
│ │ ├── mocks
|
||||
│ │ ├── opto
|
||||
│ │ ├── ring_buffer
|
||||
│ │ ├── timeout
|
||||
│ │ └── uart_host
|
||||
│ └── target
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── hil_button
|
||||
│ ├── hil_can
|
||||
│ ├── hil_opto
|
||||
│ └── host_uart
|
||||
├── tools
|
||||
│ ├── hil
|
||||
│ │ ├── 01_test_uart.py
|
||||
│ │ ├── 02_test_opto.py
|
||||
│ │ ├── 03_test_can.py
|
||||
│ │ ├── 04_test_button.py
|
||||
│ │ ├── README.md
|
||||
│ │ ├── __pycache__
|
||||
│ │ ├── conftest.py
|
||||
│ │ ├── env_config.py
|
||||
│ │ ├── load_and_run.py
|
||||
│ │ ├── m5
|
||||
│ │ ├── pyocd_utils.py
|
||||
│ │ ├── pyproject.toml
|
||||
│ │ └── uv.lock
|
||||
│ └── host
|
||||
│ ├── README.md
|
||||
│ ├── dcd
|
||||
│ ├── flash_swd.py
|
||||
│ ├── flash_usb.py
|
||||
│ ├── hab
|
||||
│ ├── pyproject.toml
|
||||
│ └── uv.lock
|
||||
└── utils
|
||||
├── CMakeLists.txt
|
||||
├── README.md
|
||||
├── log
|
||||
│ ├── README.md
|
||||
│ ├── log.c
|
||||
│ └── log.h
|
||||
└── ring_buffer
|
||||
├── README.md
|
||||
├── ring_buffer.c
|
||||
└── ring_buffer.h
|
||||
|
||||
185 directories, 130 files
|
||||
|
|
@ -67,3 +67,47 @@ add_sdk_driver(flexspi fsl_flexspi.c)
|
|||
|
||||
target_link_libraries(sdk_semc PUBLIC sdk_clock)
|
||||
target_link_libraries(sdk_flexspi PUBLIC sdk_clock)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# USB middleware — ручные таргеты (middleware/usb/, не drivers/)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# --- sdk_osa_bm: OS Abstraction Layer (bare-metal) ---
|
||||
# Объявлен первым — от него зависят USB таргеты через fsl_os_abstraction.h
|
||||
add_library(sdk_osa_bm STATIC components/osa/fsl_os_abstraction_bm.c
|
||||
components/lists/fsl_component_generic_list.c)
|
||||
target_include_directories(sdk_osa_bm PUBLIC components/osa components/lists)
|
||||
target_link_libraries(sdk_osa_bm PUBLIC sdk_device sdk_common sdk_usb_config)
|
||||
target_compile_options(sdk_osa_bm PRIVATE -w)
|
||||
|
||||
# --- sdk_usb_common: заголовки USB стека ---
|
||||
add_library(sdk_usb_common INTERFACE)
|
||||
target_include_directories(sdk_usb_common SYSTEM
|
||||
INTERFACE middleware/usb/include)
|
||||
|
||||
# --- sdk_usb_config: application-specific конфиги ---
|
||||
add_library(sdk_usb_config INTERFACE)
|
||||
target_include_directories(sdk_usb_config SYSTEM
|
||||
INTERFACE ${CMAKE_SOURCE_DIR}/bsp/usb_cdc/src)
|
||||
|
||||
# --- sdk_usb_device_ehci: EHCI контроллер + DCI абстракция ---
|
||||
add_library(sdk_usb_device_ehci STATIC middleware/usb/device/usb_device_dci.c
|
||||
middleware/usb/device/usb_device_ehci.c)
|
||||
target_include_directories(sdk_usb_device_ehci PUBLIC middleware/usb/device)
|
||||
target_link_libraries(
|
||||
sdk_usb_device_ehci PUBLIC sdk_device sdk_common sdk_usb_common
|
||||
sdk_usb_config sdk_osa_bm)
|
||||
target_compile_options(sdk_usb_device_ehci PRIVATE -w)
|
||||
|
||||
# --- sdk_usb_device_ch9: Chapter 9 standard requests ---
|
||||
# add_library(sdk_usb_device_ch9 STATIC middleware/usb/device/usb_device_ch9.c)
|
||||
# target_include_directories( sdk_usb_device_ch9 PUBLIC middleware/usb/device
|
||||
# middleware/usb/device/class) target_link_libraries(sdk_usb_device_ch9 PUBLIC
|
||||
# sdk_usb_device_ehci) target_compile_options(sdk_usb_device_ch9 PRIVATE -w)
|
||||
|
||||
# --- sdk_usb_phy: USB PHY ---
|
||||
add_library(sdk_usb_phy STATIC middleware/usb/phy/usb_phy.c)
|
||||
target_include_directories(sdk_usb_phy PUBLIC middleware/usb/phy)
|
||||
target_link_libraries(sdk_usb_phy PUBLIC sdk_device sdk_common sdk_usb_common
|
||||
sdk_usb_config sdk_osa_bm)
|
||||
target_compile_options(sdk_usb_phy PRIVATE -w)
|
||||
|
|
|
|||
Loading…
Reference in a new issue