USB设备(USBD)控制器实现全速USB设备功能,满足2.0版本的USB规范。 这里列出的是USBD的主要特性:
- 全速度(12mbps)设备完全符合通用串行总线规范修订2.0,包括以下是USB实施者论坛发布的工程更改通知:
- 上拉/下拉电阻ECN
- 5V短路耐受要求变更ECN
- USB设备栈在北欧SDK中可用
- 集成(芯片上)USB收发器(PHY)
- 软件控制的芯片上拉在D+
- 端点:
- 两个控制(1 IN, 1 OUT)
- 14 bulk/interrupt (7 IN, 7 OUT)
- 两个同步(1in, 1out)
- 双缓冲等时(ISO)端点(IN/OUT)支持
- USB挂起、恢复和远程唤醒支持
- 每个bulk/中断端点的64字节缓冲区大小
- 高达1023字节的ISO端点缓冲区大小
- 所有数据传输EasyDMA
USB设备状态 USB设备的行为可以通过状态图来建模。 usb2.0规范(见第9章USB设备框架)定义了USB设备的许多状态,如下图所示。 设备必须根据主机发起的流量和USB总线状态改变状态。由软件来实现匹配上述定义的状态机。为了检测是否存在USB供应(VBUS),两个事件USBDETECTED和USBREMOVED可以用来实现状态机。有关这些事件的更多细节,请参阅65页的USB电源。 作为实现软件的一般规则,主机的行为永远不能被认为是可预测的。特别是在枚举期间接收的命令序列。软件应始终对当前总线条件或主机发送的命令作出反应。
一、app_usbd_string_desc(USB字符串描述符/当前系统类型)
#include "sdk_config.h"
#if APP_USBD_ENABLED
#include "app_usbd_string_desc.h"
#include "app_usbd_langid.h"
#include "app_usbd_core.h"
#include "nordic_common.h"
#include "utf.h"
#include "biz_usb.h"
#include "app_main.h"
#include "business_function.h"
#include "log.h"
#define USB_DEVICE_LANGID_STRING 0x409
#define USB_DESC_TYPE_DEVICE 1
#define USB_DESC_TYPE_CONFIGURATION 2
#define USB_DESC_TYPE_STRING 3
#define USB_DESC_TYPE_INTERFACE 4
#define USB_DESC_TYPE_ENDPOINT 5
#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
#define USB_DESC_TYPE_BOS 0x0F
bool get_usb_string_bus = false;
bool g_flash_write_usb_string_flag = false;
usbd_comm_system_t g_sys_type = USB_COMM_SYSTEM_UNKNOWN;
__attribute__((aligned(4))) uint8_t string_0[] =
{
4, USB_DESC_TYPE_STRING,
LOBYTE(USB_DEVICE_LANGID_STRING),
HIBYTE(USB_DEVICE_LANGID_STRING),
};
__attribute__((aligned(4))) uint16_t string_1[] = USB_STRING1_MANUFACTURER;
__attribute__((aligned(4))) uint16_t string_2[] = USB_STRING2_PRODUCT;
__attribute__((aligned(4))) uint16_t string_3[] = USB_STRING3_SERIAL_NUMBER;
__attribute__((aligned(4))) uint16_t string_4[] = USB_STRING4_FIRMWARE_VERSION;
__attribute__((aligned(4))) uint16_t string_5[] = USB_STRING5_FIRMWARE_DATE;
__attribute__((aligned(4))) uint8_t string_100[] = USB_STRING100_TABLET_PROPERTIES;
__attribute__((aligned(4))) uint16_t string_102[] = USB_STRING102_COMPANY;
#if BS_BLE_SUPPORT || BS_NRF_BLE_SUPPORT
uint8_t string_103[] = USB_STRING103_MAC_ADDR;
#endif
__attribute__((aligned(4))) uint8_t string_104[] = USB_STRING104_WITH_PEN;
__attribute__((aligned(4))) uint8_t string_105[] = USB_STRING105_EXPAND_PROPERTIES;
__attribute__((aligned(4))) uint8_t string_110[] = USB_STRING110_DEVICE_TYPE;
__attribute__((aligned(4))) uint8_t string_120[] = USB_STRING120_DONGLE_MAC;
__attribute__((aligned(4))) uint16_t string_131[] = USB_STRING131_AGREEMENT_VER_NUM;
void set_usb_comm_string5(uint8_t *string, uint8_t len)
{
string_5[10] = string[0];
string_5[11] = string[1];
string_5[12] = string[2];
string_5[13] = string[3];
string_5[14] = string[4];
string_5[15] = string[5];
}
#if BS_BLE_SUPPORT || BS_NRF_BLE_SUPPORT
void set_usb_comm_string103(uint8_t *data, uint8_t len)
{
if (memcmp(&string_103[2], data, BLE_MAC_MAX_VAL) == 0)
{
return;
}
if (data[0] == 0 && data[1] == 0 && data[2] == 0 &&
data[3] == 0 && data[4] == 0 && data[5] == 0)
{
return;
}
string_103[2] = data[0];
string_103[3] = data[1];
string_103[4] = data[2];
string_103[5] = data[3];
string_103[6] = data[4];
string_103[7] = data[5];
}
#endif
#if BS_BLE_SUPPORT || BS_NRF_BLE_SUPPORT
void set_usb_comm_string120_dongle_mac(uint8_t *p_dongle_mac, uint8_t len)
{
if(p_dongle_mac[0] == 0 || p_dongle_mac[1] == 0 || p_dongle_mac[2] == 0 ||
p_dongle_mac[3] == 0 || p_dongle_mac[4] == 0 || p_dongle_mac[5] == 0)
{
return;
}
string_120[6] = p_dongle_mac[0];
string_120[7] = p_dongle_mac[1];
string_120[8] = p_dongle_mac[2];
string_120[9] = p_dongle_mac[3];
string_120[10] = p_dongle_mac[4];
string_120[11] = p_dongle_mac[5];
}
#endif
uint16_t const * app_usbd_string_desc_get(uint8_t idx, uint16_t langid)
{
if ((nrf_usbd_setup_windex_get() & 0x00ff) == 0)
{
if (nrf_usbd_setup_wlength_get() == 254)
{
set_current_system(USB_COMM_SYSTEM_ANDROID);
}
else
{
set_current_system(USB_COMM_SYSTEM_WINDOS);
}
}
LOG_D("<DEBUG> Request usb string %03d | %04x\r\n", idx, nrf_usbd_setup_wlength_get());
uint8_t *p_str;
switch (idx)
{
case 0:
p_str = (uint8_t*)string_0;
get_usb_string_bus = true;
return (uint16_t *)p_str;
case 1:
p_str = (uint8_t*)string_1;
p_str[0] = sizeof(string_1)-2;
p_str[1] = USB_DESC_TYPE_STRING;
get_usb_string_bus = true;
return (uint16_t *)p_str;
case 2:
p_str = (uint8_t*)string_2;
p_str[0] = sizeof(string_2)-2;
p_str[1] = USB_DESC_TYPE_STRING;
get_usb_string_bus = true;
return (uint16_t *)p_str;
case 3:
p_str = (uint8_t*)string_3;
p_str[0] = sizeof(string_3)-2;
p_str[1] = USB_DESC_TYPE_STRING;
return (uint16_t *)p_str;
case 4:
p_str = (uint8_t*)string_4;
p_str[0] = sizeof(string_4)-2;
p_str[1] = USB_DESC_TYPE_STRING;
return (uint16_t *)p_str;
case 5:
p_str = (uint8_t*)string_5;
p_str[0] = sizeof(string_5)-2;
p_str[1] = USB_DESC_TYPE_STRING;
return (uint16_t *)p_str;
#if BS_BLE_SUPPORT
case 30:
main_send_signal(SIGNAL_BLE_DTM);
break;
case 31:
main_send_signal(SIGNAL_BLE_FIXED_FREQUENCY);
break;
#endif
case 100:
p_str = (uint8_t*)string_100;
return (uint16_t *)p_str;
case 102:
p_str = (uint8_t*)string_102;
return (uint16_t *)p_str;
#if BS_BLE_SUPPORT || BS_NRF_BLE_SUPPORT
case 103:
p_str = (uint8_t*)string_103;
return (uint16_t *)p_str;
#endif
case 104:
p_str = (uint8_t*)string_104;
return (uint16_t *)p_str;
case 105:
p_str = (uint8_t*)string_105;
return (uint16_t *)p_str;
case 110:
p_str = (uint8_t*)string_110;
return (uint16_t *)p_str;
#if BS_24G_SUPPORT
case 120:
p_str = (uint8_t*)string_120;
return (uint16_t *)p_str;
#endif
case 131:
p_str = (uint8_t*)string_131;
p_str[0] = sizeof(string_131)-2;
p_str[1] = USB_DESC_TYPE_STRING;
return (uint16_t *)p_str;
case 0xc8:
#if BOOT_SUPPORT
main_send_signal(SIGNAL_SYS_GOTO_BOOT);
#else
#endif
break;
default:
LOG_E("<ERR> Request usb string %d\r\n", idx);
}
return (uint16_t *)string_0;
}
void set_current_system(usbd_comm_system_t sys_type)
{
if (g_sys_type != sys_type)
{
g_sys_type = sys_type;
main_send_signal(SIGNAL_SYS_CHANGE);
}
}
usbd_comm_system_t get_current_system(void)
{
return g_sys_type;
}
#endif
#ifndef APP_USBD_STRING_DESC_H__
#define APP_USBD_STRING_DESC_H__
#include <stdint.h>
#include "sdk_common.h"
#include "app_usbd.h"
#include "business_function.h"
#ifdef __cplusplus
extern "C" {
#endif
#define APP_USBD_LANG(lang) \
((app_usbd_langid_t) lang)
#define APP_USBD_LANG_AND_SUBLANG(lang, sublang) \
((app_usbd_langid_t) lang | (app_usbd_langid_t) sublang)
#define APP_USBD_STRING_DESC(str) (const uint8_t *)(const char[]){str}
#define APP_USBD_STRING_RAW8_DESC(...) (const uint8_t[]){ \
0x00, 0x00, \
(0xff & (sizeof((uint8_t[]){__VA_ARGS__}) + 2)), \
(APP_USBD_DESCRIPTOR_STRING), \
__VA_ARGS__ }
#define APP_USBD_STRING_RAW16_DESC(...) (const uint8_t *) ((const uint16_t[]){ \
0x00, \
(0xff & (sizeof((uint16_t[]){__VA_ARGS__}) + 2)) | \
((uint16_t)APP_USBD_DESCRIPTOR_STRING) << 8, \
__VA_ARGS__ })
#if (APP_USBD_STRING_ID_MANUFACTURER != 0)
#define APP_USBD_STRING_ID_MANUFACTURER_LEN 1
#else
#define APP_USBD_STRING_ID_MANUFACTURER_LEN 0
#endif
#if (APP_USBD_STRING_ID_PRODUCT != 0)
#define APP_USBD_STRING_ID_PRODUCT_LEN 1
#else
#define APP_USBD_STRING_ID_PRODUCT_LEN 0
#endif
#if (APP_USBD_STRING_ID_SERIAL != 0)
#define APP_USBD_STRING_ID_SERIAL_LEN 1
#else
#define APP_USBD_STRING_ID_SERIAL_LEN 0
#endif
#if (APP_USBD_STRING_ID_CONFIGURATION != 0)
#define APP_USBD_STRING_ID_CONFIGURATION_LEN 1
#else
#define APP_USBD_STRING_ID_CONFIGURATION_LEN 0
#endif
#define APP_USBD_STRINGS_NUM \
((APP_USBD_STRINGS_USER 0) + 1 + APP_USBD_STRING_ID_MANUFACTURER_LEN + APP_USBD_STRING_ID_PRODUCT_LEN + APP_USBD_STRING_ID_SERIAL_LEN + APP_USBD_STRING_ID_CONFIGURATION_LEN)
typedef enum {
APP_USBD_STRING_ID_LANGIDS = 0,
#if (APP_USBD_STRING_ID_MANUFACTURER != 0)
APP_USBD_STRING_ID_MANUFACTURER_PLACEHOLDER = APP_USBD_STRING_ID_MANUFACTURER,
#endif
#if (APP_USBD_STRING_ID_PRODUCT != 0)
APP_USBD_STRING_ID_PRODUCT_PLACEHOLDER = APP_USBD_STRING_ID_PRODUCT,
#endif
#if (APP_USBD_STRING_ID_SERIAL != 0)
APP_USBD_STRING_ID_SERIAL_PLACEHOLDER = APP_USBD_STRING_ID_SERIAL,
#endif
#if (APP_USBD_STRING_ID_CONFIGURATION != 0)
APP_USBD_STRING_ID_CONFIGURATION_PLACEHOLDER = APP_USBD_STRING_ID_CONFIGURATION,
#endif
#define X(mnemonic, str_idx, ...) mnemonic str_idx,
APP_USBD_STRINGS_USER
#undef X
} app_usbd_string_desc_idx_t;
typedef struct {
uint8_t const identifier;
uint8_t const array_pos;
} app_usbd_strings_convert_t;
uint16_t const * app_usbd_string_desc_get(uint8_t idx, uint16_t langid);
static inline size_t app_usbd_string_desc_length(uint16_t const * p_str)
{
return ((const app_usbd_descriptor_string_t *)p_str)->bLength;
}
typedef enum
{
USB_COMM_SYSTEM_UNKNOWN = 0,
USB_COMM_SYSTEM_WINDOS,
USB_COMM_SYSTEM_ANDROID
}usbd_comm_system_t;
void set_current_system(usbd_comm_system_t sys_type);
usbd_comm_system_t get_current_system(void);
extern uint16_t string_1[];
extern uint16_t string_2[];
extern uint16_t string_3[];
extern uint16_t string_4[];
extern uint16_t string_5[];
extern uint8_t string_100[];
extern uint8_t string_104[];
extern uint8_t string_105[];
extern uint8_t string_110[];
extern uint8_t string_120[];
extern uint16_t string_131[];
extern bool g_flash_write_usb_string_flag;
void set_usb_comm_string5(uint8_t *string, uint8_t len);
#if BS_BLE_SUPPORT || BS_NRF_BLE_SUPPORT
void set_usb_comm_string103(uint8_t *data, uint8_t len);
void set_usb_comm_string120_dongle_mac(uint8_t *p_dongle_mac, uint8_t len);
#endif
#ifdef __cplusplus
}
#endif
#endif
节点描述符
#define HID_MOUSE_INTERFACE 0
#define HID_TABLET_INTERFACE 1
#define HID_GENERIC_INTERFACE 2
#define MOUSE_REPORT_OUT_MAXSIZE 7
#define TABLET_REPORT_OUT_MAXSIZE 9
#define GENERIC_REPORT_OUT_MAXSIZE 63
#define MOUSE_REPORT_FEATURE_MAXSIZE 31
#define TABLET_REPORT_FEATURE_MAXSIZE 31
#define GENERIC_REPORT_FEATURE_MAXSIZE 63
#define HID_MOUSE_EPIN NRF_DRV_USBD_EPIN1
#define HID_TABLET_EPIN NRF_DRV_USBD_EPIN2
#define HID_GENERIC_EPIN NRF_DRV_USBD_EPIN3
#define HID_GENERIC_EPOUT NRF_DRV_USBD_EPOUT3
#define APP_USBD_HID_MOUSE_REPORT_DSC() \
{ \
\
0x05, 0x01, \
0x09, 0x02, \
0xA1, 0x01, \
0x85, 0x09, \
0x09, 0x01, \
0xA1, 0x00, \
0x05, 0x09, \
0x19, 0x01, \
0x29, 0x06, \
0x15, 0x00, \
0x25, 0x01, \
0x95, 0x03, \
0x75, 0x01, \
0x81, 0x02, \
0x95, 0x05, \
0x81, 0x01, \
0x05, 0x01, \
0x09, 0x30, \
0x09, 0x31, \
0x26, 0xFF, 0x7F, \
0x95, 0x02, \
0x75, 0x10, \
0x81, 0x02, \
0x05, 0x0D, \
0x09, 0x30, \
0x26, 0xFF, 0x07, \
0x95, 0x01, \
0x75, 0x10, \
0x81, 0x02, \
0xC0, \
0xC0, \
\
\
\
0x05, 0x01, \
0x09, 0x02, \
0xA1, 0x01, \
0x09, 0x01, \
0xA1, 0x00, \
0x85, 0x01, \
0x05, 0x09, \
0x19, 0x01, \
0x29, 0x06, \
0x95, 0x05, \
0x75, 0x01, \
0x15, 0x00, \
0x25, 0x01, \
0x81, 0x02, \
0x95, 0x03, \
0x81, 0x01, \
0x05, 0x01, \
0x09, 0x30, \
0x09, 0x31, \
0x95, 0x02, \
0x75, 0x10, \
0x16, 0x00, 0x80, \
0x26, 0xFF, 0x7F, \
0x81, 0x06, \
\
0x09, 0x38, \
0x15, 0x81, \
0x25, 0x7F, \
0x95, 0x01, \
0x75, 0x08, \
0x81, 0x06, \
0x05, 0x0C, \
0x0A, 0x38, 0x02, \
0x95, 0x01, \
0x75, 0x08, \
0x81, 0x06, \
0xC0, \
0xC0, \
\
\
\
0x05, 0x01, \
0x09, 0x06, \
0xA1, 0x01, \
0x85, 0x06, \
0x05, 0x07, \
0x19, 0xE0, \
0x29, 0xE7, \
0x15, 0x00, \
0x25, 0x01, \
0x75, 0x01, \
0x95, 0x08, \
0x81, 0x02, \
0x05, 0x07, \
0x19, 0x00, \
0x29, 0xFF, \
0x26, 0xFF, 0x00, \
0x75, 0x08, \
0x95, 0x06, \
0x81, 0x00, \
0xC0 \
}
#define USB_HID_TYPE_HAND_WRITE_DATA \
0x09, 0x02, \
0xa1, 0x01, \
0x85, 0x07, \
0x09, 0x20, \
0xA1, 0x00, \
0x09, 0x42, \
0x09, 0x44, \
0x09, 0x45, \
0x09, 0x3c, \
0x15, 0x00, \
0x25, 0x01, \
0x75, 0x01, \
0x95, 0x04, \
0x81, 0x02, \
0x95, 0x01, \
0x81, 0x03, \
0x09, 0x32, \
0x15, 0x00, \
0x25, 0x01, \
0x95, 0x01, \
0x81, 0x02, \
0x95, 0x02, \
0x81, 0x03, \
#define USB_HID_TYPE_TOUCH_PANEL_DATA \
0x09, 0x04, \
0xa1, 0x01, \
0x85, 0x07, \
0x09, 0x22, \
0xA1, 0x00, \
0x09, 0x42, \
0x15, 0x00, \
0x25, 0x01, \
0x75, 0x01, \
0x95, 0x01, \
0x81, 0x02, \
0x09, 0x32, \
0x15, 0x00, \
0x25, 0x01, \
0x81, 0x02, \
0x09, 0x51, \
0x75, 0x05, \
0x81, 0x02, \
0x09, 0x47, \
0x75, 0x01, \
0x15, 0x00, \
0x25, 0x01, \
0x81, 0x02, \
#if BS_HAND_WRITE_TYPE != 1
#define USB_HID_TYPE_DATA USB_HID_TYPE_HAND_WRITE_DATA
#else
#define USB_HID_TYPE_DATA USB_HID_TYPE_TOUCH_PANEL_DATA
#endif
#define APP_USBD_HID_TABLET_REPORT_DSC() { \
0x05, 0x0D, \
USB_HID_TYPE_DATA \
0x75, 0x10, \
0x95, 0x01, \
0x35, 0x00, \
0xa4, \
0x05, 0x01, \
0x09, 0x30, \
0x65, 0x13, \
0x55, 0x0D, \
\
0x46, DESC_CONFIG_WORD(X_MIL), \
0x26, 0xFF, 0x7F, \
0x81, 0x02, \
0x09, 0x31, \
0x46, DESC_CONFIG_WORD(Y_MIL), \
0x26, 0xFF, 0x7F, \
0x81, 0x02, \
0xB4, \
0x09, 0x30, \
0x45, 0x00, \
\
0x26, DESC_CONFIG_WORD(PRESSURE_MAX), \
0x81, 0x42, \
\
0x09, 0x3D, \
0x15, 0x81, \
0x25, 0x7F, \
0x75, 0x08, \
0x95, 0x01, \
0x81, 0x02, \
0x09, 0x3E, \
0x15, 0x81, \
0x25, 0x7F, \
0x81, 0x02, \
0xC0, \
0xC0, \
}
#define APP_USBD_HID_GENERIC_REPORT_DSC() { \
0x06, 0x0A, 0xFF, \
0x09, 0x01, \
0xA1, 0x01, \
0x85, 0x02, \
0x09, 0x02, \
0x75, 0x08, \
0x95, 0x0b, \
0x15, 0x00, \
0x26, 0xFF, 0x00, \
0x81, 0x02, \
0x09, 0x03, \
0x75, 0x08, \
0x95, 0x20, \
0x15, 0x00, \
0x26, 0xFF, 0x00, \
0x91, 0x02, \
0xC0 \
}
三、业务USB功能
#include <stdbool.h>
#include <string.h>
#include "nrf.h"
#include "nrf_drv_clock.h"
#include "nrf_drv_power.h"
#include "nrf_error.h"
#include "app_usbd.h"
#include "app_usbd_core.h"
#include "app_usbd_hid_generic.h"
#include "app_usbd_hid_mouse.h"
#include "app_usbd_serial_num.h"
#include "app_util.h"
#include "business_function.h"
#include "business_gpio.h"
#include "log.h"
#include "os_api.h"
#include "biz_usb_hid.h"
#include "biz_usb.h"
#ifndef USBD_POWER_DETECTION
#define USBD_POWER_DETECTION true
#endif
#define HID_MOUSE_INTERFACE 0
#define HID_TABLET_INTERFACE 1
#define HID_GENERIC_INTERFACE 2
#define GENERIC_REPORT_IN_QUEUE_SIZE 63
#define GENERIC_REPORT_OUT_MAXSIZE 63
#define MOUSE_REPORT_IN_QUEUE_SIZE 10
#define MOUSE_REPORT_OUT_MAXSIZE 7
#define TABLET_REPORT_IN_QUEUE_SIZE 10
#define TABLET_REPORT_OUT_MAXSIZE 9
#define GENERIC_REPORT_FEATURE_MAXSIZE 63
#define MOUSE_REPORT_FEATURE_MAXSIZE 31
#define TABLET_REPORT_FEATURE_MAXSIZE 31
#define HID_GENERIC_EPIN NRF_DRV_USBD_EPIN3
#define HID_GENERIC_EPOUT NRF_DRV_USBD_EPOUT3
#define HID_MOUSE_EPIN NRF_DRV_USBD_EPIN1
#define HID_TABLET_EPIN NRF_DRV_USBD_EPIN2
#define SIGNAL_USB_MSG (1<<0)
static void hid_generic_ev_handler(app_usbd_class_inst_t const * p_inst, app_usbd_hid_user_event_t event);
static void hid_user_ev_handler(app_usbd_class_inst_t const * p_inst, app_usbd_hid_user_event_t event);
biz_usb_info_t g_biz_usb_info = {
.pid = APP_USBD_PID,
.channel = USB_DEVICE_DATA_MODE_STANDARD_PEN,
.angle = 0
};
#define GENERIC_ENDPOINT_LIST() \
( \
HID_GENERIC_EPIN, \
HID_GENERIC_EPOUT \
)
#define MOUSE_ENDPOINT_LIST() \
( \
HID_MOUSE_EPIN \
)
#define TABLET_ENDPOINT_LIST() \
( \
HID_TABLET_EPIN \
)
APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(mouse_desc, APP_USBD_HID_MOUSE_REPORT_DSC());
static const app_usbd_hid_subclass_desc_t *mouse_reps[] = {&mouse_desc};
APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(tablet_desc, APP_USBD_HID_TABLET_REPORT_DSC());
static const app_usbd_hid_subclass_desc_t *tablet_reps[] = {&tablet_desc};
APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(generic_desc, APP_USBD_HID_GENERIC_REPORT_DSC());
static const app_usbd_hid_subclass_desc_t * generic_reps[] = {&generic_desc};
APP_USBD_HID_GENERIC_GLOBAL_DEF(m_app_hid_mouse,
HID_MOUSE_INTERFACE,
hid_user_ev_handler,
MOUSE_ENDPOINT_LIST(),
mouse_reps,
MOUSE_REPORT_IN_QUEUE_SIZE,
MOUSE_REPORT_OUT_MAXSIZE,
MOUSE_REPORT_FEATURE_MAXSIZE,
APP_USBD_HID_SUBCLASS_NONE,
APP_USBD_HID_PROTO_MOUSE);
APP_USBD_HID_GENERIC_GLOBAL_DEF(m_app_hid_tablet,
HID_TABLET_INTERFACE,
hid_user_ev_handler,
TABLET_ENDPOINT_LIST(),
tablet_reps,
TABLET_REPORT_IN_QUEUE_SIZE,
TABLET_REPORT_OUT_MAXSIZE,
TABLET_REPORT_FEATURE_MAXSIZE,
APP_USBD_HID_SUBCLASS_NONE,
APP_USBD_HID_PROTO_MOUSE);
APP_USBD_HID_GENERIC_GLOBAL_DEF(m_app_hid_generic,
HID_GENERIC_INTERFACE,
hid_generic_ev_handler,
GENERIC_ENDPOINT_LIST(),
generic_reps,
GENERIC_REPORT_IN_QUEUE_SIZE,
GENERIC_REPORT_OUT_MAXSIZE,
GENERIC_REPORT_FEATURE_MAXSIZE,
APP_USBD_HID_SUBCLASS_NONE,
APP_USBD_HID_PROTO_GENERIC);
static void hid_generic_ev_handler(app_usbd_class_inst_t const * p_inst, app_usbd_hid_user_event_t event)
{
switch (event)
{
case APP_USBD_HID_USER_EVT_OUT_REPORT_READY:
{
size_t size;
uint8_t *ptr;
ptr = (uint8_t *)app_usbd_hid_generic_out_report_get(&m_app_hid_generic, &size);
LOG_D("<DEBUG> [USB_RX] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x|%d\r\n",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], size);
if(ptr);
break;
}
default:
break;
}
}
static void hid_user_ev_handler(app_usbd_class_inst_t const * p_inst, app_usbd_hid_user_event_t event)
{
}
static void usbd_user_ev_handler(app_usbd_event_type_t event)
{
switch (event)
{
case APP_USBD_EVT_DRV_SOF:
break;
case APP_USBD_EVT_DRV_SUSPEND:
app_usbd_suspend_req();
break;
case APP_USBD_EVT_DRV_RESUME:
break;
case APP_USBD_EVT_STARTED:
break;
case APP_USBD_EVT_STOPPED:
app_usbd_disable();
break;
case APP_USBD_EVT_POWER_DETECTED:
if (!nrf_drv_usbd_is_enabled())
{
app_usbd_enable();
}
break;
case APP_USBD_EVT_POWER_REMOVED:
app_usbd_stop();
break;
case APP_USBD_EVT_POWER_READY:
app_usbd_start();
break;
default:
break;
}
}
uint8_t biz_usb_start(void)
{
ret_code_t ret = NRF_SUCCESS;
if (USBD_POWER_DETECTION)
{
ret = app_usbd_power_events_enable();
APP_ERROR_CHECK(ret);
}
else
{
app_usbd_enable();
app_usbd_start();
}
return (uint8_t)ret;
}
void biz_usb_stop(void)
{
app_usbd_disable();
}
uint8_t biz_usb_generic_send(const void *buff, size_t size)
{
return app_usbd_hid_generic_in_report_set(&m_app_hid_generic, buff, size);
}
uint8_t biz_usb_mouse_send(const void *buff, size_t size)
{
return app_usbd_hid_generic_in_report_set(&m_app_hid_mouse, buff, size);
}
uint8_t biz_usb_tablet_send(const void *buff, size_t size)
{
return app_usbd_hid_generic_in_report_set(&m_app_hid_tablet, buff, size);
}
uint8_t biz_usb_drives_init(void)
{
ret_code_t ret = NRF_SUCCESS;
static const app_usbd_config_t usbd_config = {
.ev_state_proc = usbd_user_ev_handler,
};
nrf_drv_clock_init();
nrf_drv_clock_lfclk_request(NULL);
while(!nrf_drv_clock_lfclk_is_running())
{
}
ret = app_usbd_init(&usbd_config);
APP_ERROR_CHECK(ret);
app_usbd_class_inst_t const * class_inst_generic;
class_inst_generic = app_usbd_hid_generic_class_inst_get(&m_app_hid_mouse);
ret = app_usbd_class_append(class_inst_generic);
APP_ERROR_CHECK(ret);
class_inst_generic = app_usbd_hid_generic_class_inst_get(&m_app_hid_tablet);
ret = app_usbd_class_append(class_inst_generic);
APP_ERROR_CHECK(ret);
class_inst_generic = app_usbd_hid_generic_class_inst_get(&m_app_hid_generic);
ret = app_usbd_class_append(class_inst_generic);
APP_ERROR_CHECK(ret);
return (uint8_t)ret;
}
void* get_usb_info_p(void)
{
return &g_biz_usb_info;
}
uint16_t get_usb_pid(void)
{
return g_biz_usb_info.pid;
}
void set_usb_pid(uint16_t pid)
{
g_biz_usb_info.pid = pid;
}
void set_current_android_angle(uint8_t angle)
{
if (g_biz_usb_info.angle != angle)
{
g_biz_usb_info.write_in = true;
}
g_biz_usb_info.angle = angle;
}
uint8_t get_current_android_angle(void)
{
if(g_biz_usb_info.angle == 0)
{
g_biz_usb_info.angle = 2;
}
return g_biz_usb_info.angle;
}
void set_usb_comm_channel(usb_device_data_mode_t channel)
{
g_biz_usb_info.channel = channel;
LOG_D("<DEBUG> set channel:%d \r\n", channel);
}
usb_device_data_mode_t get_usb_comm_channel(void)
{
if (g_biz_usb_info.channel == 0)
{
g_biz_usb_info.channel = USB_DEVICE_DATA_MODE_STANDARD_PEN;
}
return g_biz_usb_info.channel;
}
bool biz_get_usbd_active_check(void)
{
return app_usbd_active_check();
}
|