chore: Remove tracked build artifacts

This commit is contained in:
lmx
2025-11-28 16:24:27 +08:00
parent 892ed9267b
commit 818e8c3778
2356 changed files with 0 additions and 587882 deletions

View File

@ -1,459 +0,0 @@
#include "includes.h"
#include "asm/includes.h"
#include "system/timer.h"
#include "device/ioctl_cmds.h"
#include "usb/host/usb_host.h"
#include "usb_ctrl_transfer.h"
#include "usb_bulk_transfer.h"
#include "device_drive.h"
#include "adb.h"
#include "usb_config.h"
#include "app_config.h"
#if TCFG_ADB_ENABLE
#define LOG_TAG_CONST USB
#define LOG_TAG "[adb]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#include "adb_rsa_key.c"
struct adb_device_t adb;
struct device adb_device;
void aoa_switch(struct usb_host_device *host_dev);
static int set_adb_power(struct usb_host_device *host_dev, u32 value)
{
return DEV_ERR_NONE;
}
static int get_adb_power(struct usb_host_device *host_dev, u32 value)
{
return DEV_ERR_NONE;
}
static const struct interface_ctrl adb_ops = {
.interface_class = USB_CLASS_ADB,
.set_power = set_adb_power,
.get_power = get_adb_power,
.ioctl = NULL,
};
static const struct usb_interface_info adb_inf = {
.ctrl = (struct interface_ctrl *) &adb_ops,
.dev.adb = &adb,
};
u32 usb_adb_interface_ptp_mtp_parse(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
{
struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)pBuf;
pBuf += sizeof(struct usb_interface_descriptor);
int len = 0;
const usb_dev usb_id = host_device2id(host_dev);
for (int i = 0; i < interface->bNumEndpoints; i++) {
struct usb_endpoint_descriptor *endpoint = (struct usb_endpoint_descriptor *)pBuf;
if (endpoint->bDescriptorType == USB_DT_ENDPOINT) {
if (endpoint->bmAttributes == USB_ENDPOINT_XFER_BULK) {
if (endpoint->bEndpointAddress & USB_DIR_IN) {
adb.extr_in = endpoint->bEndpointAddress & 0xf;
} else {
adb.extr_out = endpoint->bEndpointAddress;
}
}
pBuf += USB_DT_ENDPOINT_SIZE;
} else {
return 0;
}
}
printf("%s() %x %x\n", __func__, adb.extr_in, adb.extr_out);
return pBuf - (u8 *)interface ;
}
int usb_adb_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
{
struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)pBuf;
pBuf += sizeof(struct usb_interface_descriptor);
int len = 0;
const usb_dev usb_id = host_device2id(host_dev);
adb_device.private_data = host_dev;
host_dev->interface_info[interface_num] = &adb_inf;
for (int endnum = 0; endnum < interface->bNumEndpoints; endnum++) {
struct usb_endpoint_descriptor *end_desc = (struct usb_endpoint_descriptor *)pBuf;
if (end_desc->bDescriptorType != USB_DT_ENDPOINT ||
end_desc->bLength != USB_DT_ENDPOINT_SIZE) {
log_error("ep bDescriptorType = %d bLength = %d", end_desc->bDescriptorType, end_desc->bLength);
return -USB_DT_ENDPOINT;
}
len += USB_DT_ENDPOINT_SIZE;
pBuf += USB_DT_ENDPOINT_SIZE;
if ((end_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
if (end_desc->bEndpointAddress & USB_DIR_IN) {
adb.host_epin = usb_get_ep_num(usb_id, USB_DIR_IN, USB_ENDPOINT_XFER_BULK);
adb.target_epin = end_desc->bEndpointAddress & 0x0f;
#if defined(FUSB_MODE) && FUSB_MODE == 0
adb.rxmaxp = end_desc->wMaxPacketSize;
#endif
log_debug("D(%d)->H(%d)", adb.target_epin, adb.host_epin);
} else {
adb.host_epout = usb_get_ep_num(usb_id, USB_DIR_OUT, USB_ENDPOINT_XFER_BULK);
adb.target_epout = end_desc->bEndpointAddress & 0x0f;
#if defined(FUSB_MODE) && FUSB_MODE == 0
adb.txmaxp = end_desc->wMaxPacketSize;
#endif
log_debug("H(%d)->D(%d)", adb.host_epout, adb.target_epout);
}
}
}
u8 *ep_buffer = usb_h_get_ep_buffer(usb_id, adb.host_epin | USB_DIR_IN);
usb_h_ep_config(usb_id, adb.host_epin | USB_DIR_IN, USB_ENDPOINT_XFER_BULK, 0, 0, ep_buffer, 64);
ep_buffer = usb_h_get_ep_buffer(usb_id, adb.host_epout | USB_DIR_OUT);
usb_h_ep_config(usb_id, adb.host_epout | USB_DIR_OUT, USB_ENDPOINT_XFER_BULK, 0, 0, ep_buffer, 64);
return len;
}
static int adb_send_packet(struct amessage *msg, const u8 *data_ptr)
{
if (msg == NULL) {
return usb_bulk_only_send(&adb_device, adb.host_epout, 64, adb.target_epout, NULL, 0);
}
u32 cnt;
u32 count = msg->data_length;
msg->magic = msg->command ^ 0xffffffff;
const u8 *_data_ptr = data_ptr;
msg->data_check = 0;
while (count--) {
msg->data_check += *_data_ptr++;
}
int ret = usb_bulk_only_send(&adb_device, adb.host_epout, 64, adb.target_epout, (u8 *)msg, sizeof(*msg));
if (ret < 0) {
return ret;
}
if (data_ptr != NULL) {
return usb_bulk_only_send(&adb_device, adb.host_epout, 64, adb.target_epout, data_ptr, msg->data_length);
} else {
return 0;
}
}
static int adb_recv(u8 *buffer, u32 len, u32 timeout)
{
return usb_bulk_only_receive(&adb_device, adb.host_epin, 64, adb.target_epin, buffer, len);
}
#define check_usb_status(ret) do{\
if(ret < 0){\
log_info("%s() @ %d %d\n", __func__, __LINE__, ret);\
return ret;\
}\
}while(0);
static u8 adb_signatrue_data_index ;
u32 adb_auth()
{
log_info("%s() %d\n", __func__, __LINE__);
struct amessage msg;
int ret = 0;
u8 *cmd_string;
adb.local_id = 0x58525047;
adb.remote_id = 0;
msg.command = A_CNXN;
msg.arg0 = A_VERSION;
msg.arg1 = 0x00001000;
cmd_string = (u8 *)"host::";
msg.data_length = strlen((const char *)cmd_string) + 1;
ret = adb_send_packet(&msg, cmd_string);
check_usb_status(ret);
memset(&msg, 0, 24);
ret = adb_recv((u8 *)&msg, 24, 5);
check_usb_status(ret);
if (msg.command == A_CNXN) {
if (adb_recv(adb.buffer, msg.data_length, 1 * 100)) {
log_error("auth error 0\n");
return 0;
}
log_info("auth not send rsa pub key\n");
return 0;
} else if (msg.command == A_AUTH) {
} else {
log_error("auth error 1\n");
return 1;
}
ret = adb_recv(adb.buffer, msg.data_length, 1 * 100);
check_usb_status(ret);
msg.command = A_AUTH;
msg.arg0 = ADB_AUTH_SIGNATURE;
msg.data_length = sizeof(adb_signatrue_data[0]);
if (adb_signatrue_data_index > 2) {
adb_signatrue_data_index = 0;
}
adb_signatrue_data_index ++;
cmd_string = (u8 *)&adb_signatrue_data[adb_signatrue_data_index][0];
ret = adb_send_packet(&msg, cmd_string);
check_usb_status(ret);
ret = adb_send_packet(NULL, NULL);//zero packet
check_usb_status(ret);
memset(&msg, 0, 24);
ret = adb_recv((u8 *)&msg, 24, 1 * 100);
check_usb_status(ret);
if (msg.command != A_AUTH) {
log_error("auth error 2\n");
return 1;
}
ret = adb_recv(adb.buffer, msg.data_length, 1 * 100);
check_usb_status(ret);
__RETRY:
msg.command = A_AUTH;
msg.arg0 = ADB_AUTH_RSAPUBLICKEY;
msg.arg1 = 0;
msg.data_length = sizeof(adb_rsa_pub_key);
ret = adb_send_packet(&msg, (u8 *)adb_rsa_pub_key);
check_usb_status(ret);
ret = adb_recv((u8 *)&msg, 24, 30 * 100);
if (ret < 0) {
if (ret == -DEV_ERR_TIMEOUT) {
goto __RETRY;
}
check_usb_status(ret);
}
ret = adb_recv(adb.buffer, msg.data_length, 1 * 100);//最长等待30s,等手机点击确认授权adb
if (ret < 0) {
if (ret == -DEV_ERR_TIMEOUT) {
goto __RETRY;
}
check_usb_status(ret);
}
if (msg.command == A_AUTH) {
goto __RETRY;
}
return 0;
}
u32 adb_shell_login()
{
log_info("%s() %d\n", __func__, __LINE__);
struct amessage msg;
u8 *cmd_string;
/* __AUTH_SUCCESS: */
cmd_string = (u8 *)"shell:";
msg.command = A_OPEN;
msg.arg0 = adb.local_id;
msg.arg1 = 0;
msg.data_length = strlen((char const *)cmd_string) + 1;
int ret = adb_send_packet(&msg, cmd_string);
check_usb_status(ret);
memset(&msg, 0, 24);
ret = adb_recv((u8 *)&msg, 24, 1 * 100);
check_usb_status(ret);
if (msg.command != A_OKAY) {
log_error("A_OKAY error\n");
return 4;
}
ret = adb_recv((u8 *)&msg, 24, 1 * 100);
check_usb_status(ret);
if (msg.command != A_WRTE) {
log_error("A_WRTE error\n");
return 5;
}
adb.remote_id = msg.arg0;
ret = adb_recv(adb.buffer, msg.data_length, 1 * 100);
check_usb_status(ret);
msg.command = A_OKAY;
msg.arg0 = adb.local_id;
msg.arg1 = adb.remote_id;
msg.data_length = 0;
ret = adb_send_packet(&msg, NULL);
check_usb_status(ret);
return 0;
}
static u32 adb_ex_cmd(const char *cmd_string, u8 *echo_buffer, u32 max_len)
{
log_info("%s\n", cmd_string);
int ret;
struct amessage msg;
msg.command = A_WRTE;
msg.arg0 = adb.local_id;
msg.arg1 = adb.remote_id;
msg.data_length = strlen(cmd_string);
ret = adb_send_packet(&msg, (u8 *)cmd_string);
check_usb_status(ret);
memset(&msg, 0, 24);
memset(echo_buffer, 0, max_len);
ret = adb_recv((u8 *)&msg, sizeof(msg), 3 * 100);
check_usb_status(ret);
if (msg.command != A_OKAY) {
return true;
}
u32 offset = 0;
do {
ret = adb_recv((u8 *)&msg, sizeof(msg), 3 * 100);
check_usb_status(ret);
if (msg.command != A_WRTE) {
log_info("command %x\n", msg.command);
return true;
}
if ((offset + msg.data_length) > max_len) {
log_info("%s", echo_buffer);
echo_buffer[offset] = 0;
offset = 0;
}
ret = adb_recv(&echo_buffer[offset], msg.data_length, 3 * 100);
check_usb_status(ret);
offset += msg.data_length;
if (msg.data_length == 0) {
log_info("no data_length\n");
break;
}
if (offset >= max_len) {
}
/* echo_buffer[offset] = '\n'; */
echo_buffer[offset] = 0;
if (echo_buffer[offset - 2] == 0x24 && echo_buffer[offset - 1] == 0x20) {
/* puts("end\n"); */
break;
} else if (echo_buffer[offset - 2] == 0x23 && echo_buffer[offset - 1] == 0x20) {
/* puts("end 1\n"); */
break;
}
msg.command = A_OKAY;
msg.arg0 = adb.local_id;
msg.arg1 = adb.remote_id;
msg.data_length = 0;
ret = adb_send_packet(&msg, NULL);
check_usb_status(ret);
} while (1);
msg.command = A_OKAY;
msg.arg0 = adb.local_id;
msg.arg1 = adb.remote_id;
msg.data_length = 0;
/* puts("exit\n"); */
return adb_send_packet(&msg, NULL);
}
#define APP_ACTIVITY_PATH "com.zh-jieli.gmaeCenter/com.zh-jieli.gameCenter.activity.guide.SplashActivity\n"
#define APP_WEBSITE "http://www.zh-jieli.com\n"
#define APP_BASH_IN_PATH "/sdcard/jilei/active.bash"
#define APP_BASH_OUT_PATH "/data/local/tmp/active.bash"
u32 adb_game_active()
{
log_info("%s() %d\n", __func__, __LINE__);
u32 max_len = adb.max_len;;
u8 *adb_buffer = adb.buffer;
//1启动app
adb_ex_cmd("am start -n " APP_ACTIVITY_PATH, adb_buffer, max_len);
puts((char *)adb_buffer);
//查找Error字符串如果找到跳转网页下载app否则执行adb指令
if (strstr((const char *)adb_buffer, "Error") != NULL) {
adb_ex_cmd("am start -a android.intent.action.VIEW -d " APP_WEBSITE, adb_buffer, max_len);
puts((char *)adb_buffer);
} else {
adb_ex_cmd("dd if=" APP_BASH_IN_PATH " of=" APP_BASH_OUT_PATH "\n", adb_buffer, max_len);
puts((char *)adb_buffer);
adb_ex_cmd("chown shell " APP_BASH_OUT_PATH";chmod 777 "APP_BASH_OUT_PATH "\n", adb_buffer, max_len);
puts((char *)adb_buffer);
adb_ex_cmd("trap \"\" HUP;sh "APP_BASH_OUT_PATH "&\n", adb_buffer, max_len);
puts((char *)adb_buffer);
}
return 0;
}
static void mtp_ptp_open_session(u32 is_mtp)
{
/* usbh_bulk_send_blocking(ADB_HOST_EP, adb_device.extr_out, (u8 *)_open_session, 16); */
/* usbh_request_bulk_blocking(ADB_HOST_EP, adb_device.extr_in, get_data_buffer(), 12, 3); */
/* usbh_bulk_send_blocking(ADB_HOST_EP, adb_device.extr_out, (u8 *)get_device_info, sizeof(get_device_info)); */
/* usbh_request_bulk_blocking(ADB_HOST_EP, adb_device.extr_in, get_data_buffer(), 512, 3); */
/* usbh_request_bulk_blocking(ADB_HOST_EP, adb_device.extr_in, get_data_buffer(), 12, 3); */
}
static void adb_open_session()
{
struct usb_host_device *host_dev = adb_device.private_data;
if (adb.extr_in && adb.extr_out) {
get_ms_extended_compat_id(host_dev, adb.buffer);
get_device_status(host_dev);
get_config_descriptor(host_dev, adb.buffer, 0xff);
/* mtp_ptp_open_session(ac6921_data_buffer[0x12] == 0x4d); */
}
}
u32 adb_process()
{
adb.max_len = 1024;
adb.buffer = malloc(adb.max_len);
os_time_dly(20);
do {
adb_open_session();
if (adb_auth()) {
break;
}
if (adb_shell_login()) {
break;
}
adb_game_active();
log_info("adb active succ");
return 0;
} while (0);
free(adb.buffer);
log_info("adb active error");
return 1;
}
void adb_switch_aoa(u32 id)
{
struct usb_host_device *host_dev = adb_device.private_data;
aoa_switch(host_dev);
/* usb_host_remount(id, 3, 30, 50, 1); */
}
#endif //TCFG_ADB_ENABLE

View File

@ -1,73 +0,0 @@
#ifndef __ADB_H__
#define __ADB_H__
#include "system/task.h"
#include "device/device.h"
#include "usb/scsi.h"
#include "usb_bulk_transfer.h"
#include "usb/host/usb_host.h"
struct adb_device_t {
u32 local_id;
u32 remote_id;
void *buffer;
u32 max_len;
u8 target_epin;
u8 target_epout;
u8 host_epin;
u8 host_epout;
u8 extr_in;
u8 extr_out;
};
u32 usb_adb_interface_ptp_mtp_parse(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf);
int usb_adb_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf);
u32 adb_process();
void adb_switch_aoa(u32 id);
#if 1
#define A_SYNC 0x434e5953
#define A_CNXN 0x4e584e43
#define A_OPEN 0x4e45504f
#define A_OKAY 0x59414b4f
#define A_CLSE 0x45534c43
#define A_WRTE 0x45545257
#define A_AUTH 0x48545541
//#define S_ID_LOCAL 0x00003456
/* AUTH packets first argument */
/* Request */
#define ADB_AUTH_TOKEN 1
/* Response */
#define ADB_AUTH_SIGNATURE 2
#define ADB_AUTH_RSAPUBLICKEY 3
#define A_VERSION 0x01000000 // ADB protocol version
#define ADB_VERSION_MAJOR 1 // Used for help/version information
#define ADB_VERSION_MINOR 0 // Used for help/version information
#else
#define A_SYNC 0x53594e43
#define A_CNXN 0x434e584e
#define A_OPEN 0x4f50454e
#define A_OKAY 0x4f4b4159
#define A_CLSE 0x434c5345
#define A_WRTE 0x57525445
#define A_VERSION 0x00000001 // ADB protocol version
#define ADB_VERSION_MAJOR 1 // Used for help/version information
#define ADB_VERSION_MINOR 0 // Used for help/version information
#endif
struct amessage {
unsigned long int command; /* command identifier constant */
unsigned long int arg0; /* first argument */
unsigned long int arg1; /* second argument */
unsigned long int data_length; /* length of payload (0 is allowed) */
unsigned long int data_check; /* checksum of data payload */
unsigned long int magic; /* command ^ 0xffffffff */
};
#endif /*ADB_H*/

View File

@ -1,115 +0,0 @@
#include "typedef.h"
#include "app_config.h"
#if TCFG_ADB_ENABLE
static const u8 _open_session[] = {
0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
};
static const u8 get_device_info[] = {
0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00,
};
static const u8 adb_signatrue_data[][256] = {
{
0xFA, 0xA6, 0xE3, 0x50, 0x3C, 0xC4, 0x95, 0xFE, 0xBB, 0x46, 0xE0, 0x9F, 0xD9, 0x9A, 0x18, 0xC1,
0x28, 0x67, 0xA9, 0x46, 0xF8, 0x20, 0xBF, 0xDB, 0xFE, 0x6B, 0xC8, 0xC4, 0x0A, 0x09, 0xFA, 0x9A,
0xCD, 0x51, 0xE3, 0x67, 0xD1, 0xDF, 0xD2, 0x92, 0xD3, 0x9E, 0xFA, 0x17, 0x76, 0x01, 0xF5, 0xE2,
0xBD, 0x64, 0x9C, 0x92, 0x82, 0x4B, 0xE4, 0x27, 0x21, 0x22, 0x1A, 0x70, 0x99, 0x8F, 0xC5, 0xD5,
0xE2, 0x02, 0x2C, 0xA4, 0x13, 0x08, 0x1E, 0x42, 0x83, 0x5C, 0x7E, 0x3C, 0x1F, 0x97, 0x1B, 0xAF,
0x6F, 0x7E, 0x4F, 0xAB, 0xDA, 0x6A, 0x61, 0x56, 0x03, 0x79, 0xB5, 0xF0, 0x97, 0xEE, 0xEC, 0x88,
0x6F, 0x9E, 0x8D, 0x41, 0xE2, 0x13, 0x9B, 0x21, 0xEE, 0x6F, 0x09, 0x81, 0x62, 0xC1, 0xB5, 0xE7,
0xC2, 0x5C, 0x4A, 0x8C, 0x39, 0xAA, 0x50, 0x08, 0x48, 0xB5, 0x1D, 0xF6, 0x7C, 0x67, 0xD6, 0x39,
0x63, 0x7E, 0x5E, 0x49, 0x3D, 0x9B, 0x49, 0x4B, 0x67, 0x8E, 0x06, 0x31, 0x07, 0x4E, 0x56, 0x8A,
0xC4, 0x9D, 0x84, 0xA9, 0xF4, 0xFC, 0xE3, 0x2D, 0x1D, 0x2A, 0x98, 0x52, 0x40, 0x49, 0x93, 0x71,
0xA7, 0x43, 0x0D, 0x78, 0xEB, 0xFA, 0x49, 0x7A, 0x39, 0xBF, 0xE4, 0x06, 0x08, 0x1B, 0x20, 0x84,
0xDC, 0x64, 0xBB, 0xDE, 0x1A, 0x5E, 0x4B, 0xF8, 0x57, 0xBF, 0x9C, 0x8C, 0xB9, 0x1D, 0xEE, 0xB3,
0x90, 0x17, 0x03, 0x8B, 0x3E, 0x9F, 0x8A, 0x23, 0xEC, 0x30, 0xA7, 0x24, 0x5E, 0x5B, 0x58, 0xAA,
0x5A, 0xAE, 0xE2, 0x14, 0xC1, 0xAE, 0xA3, 0xF9, 0xAF, 0x70, 0xE0, 0x14, 0x7D, 0x73, 0x3B, 0x6D,
0x9B, 0x06, 0x2F, 0xAA, 0xFF, 0x7A, 0x2A, 0x56, 0x6F, 0x91, 0x70, 0x6D, 0x4A, 0x18, 0x35, 0x51,
0xD5, 0x5D, 0xFB, 0xA1, 0x8B, 0x03, 0xF2, 0x0C, 0x56, 0xF0, 0x5A, 0x4A, 0x08, 0x89, 0xFE, 0x86
},
{
0x60, 0xE6, 0x4A, 0x3D, 0x12, 0xD1, 0x48, 0x25, 0x7D, 0x6E, 0x8E, 0x03, 0xE2, 0xC8, 0xE7, 0x66,
0x96, 0xD7, 0xD3, 0xBF, 0xE6, 0x97, 0x13, 0x3A, 0x2D, 0x2B, 0x85, 0xE7, 0xDA, 0x5C, 0x87, 0xD8,
0xDC, 0x88, 0xAC, 0xF7, 0xC3, 0xF0, 0x5A, 0xE8, 0x95, 0x66, 0x19, 0xA1, 0xA8, 0x2A, 0xE1, 0x70,
0x13, 0xF0, 0x05, 0x59, 0x3D, 0x89, 0x04, 0x65, 0x08, 0x03, 0x9C, 0xDC, 0x71, 0x24, 0xC5, 0x9E,
0x4D, 0x82, 0xD8, 0x72, 0x07, 0xFD, 0x8F, 0xD3, 0x37, 0x56, 0x8C, 0xB6, 0x01, 0xDB, 0x08, 0x5B,
0xA3, 0x42, 0x8F, 0xF0, 0xCA, 0xDC, 0x80, 0xEB, 0x32, 0xC4, 0x67, 0x1F, 0x73, 0xAF, 0xF0, 0x56,
0xBC, 0x89, 0x72, 0xB1, 0x7D, 0xDA, 0xA4, 0x79, 0x7D, 0x02, 0x35, 0x38, 0xBA, 0xA0, 0x36, 0xFE,
0x5A, 0x70, 0x93, 0xF5, 0x10, 0x7A, 0x92, 0xE9, 0xD4, 0xB0, 0xED, 0xF3, 0x00, 0xD0, 0x27, 0x79,
0x51, 0x54, 0x38, 0x2D, 0x4C, 0xAA, 0x27, 0xEF, 0xA7, 0x8A, 0x34, 0x4E, 0x4B, 0x29, 0x90, 0xC4,
0x3E, 0xA8, 0x8D, 0x3D, 0x00, 0xD6, 0x84, 0x11, 0x17, 0x32, 0xD6, 0xE9, 0x33, 0x02, 0xCD, 0x04,
0x35, 0x3F, 0x1A, 0xC3, 0x05, 0xCF, 0x6F, 0xF4, 0x39, 0x65, 0xE5, 0x6B, 0x88, 0x1E, 0x25, 0xA1,
0xD7, 0xC0, 0x30, 0xE4, 0x0B, 0x2A, 0x61, 0x6D, 0x61, 0xF1, 0x93, 0xAE, 0xC3, 0x42, 0xDC, 0x15,
0x1D, 0x87, 0x60, 0x09, 0x92, 0x64, 0xC1, 0x63, 0xAD, 0xCA, 0x36, 0x63, 0x0E, 0x69, 0x51, 0x45,
0xD0, 0x18, 0x5E, 0x10, 0x88, 0x7B, 0xD9, 0xDE, 0xA3, 0x12, 0x85, 0xF9, 0x30, 0x01, 0x0A, 0xE1,
0x82, 0xD1, 0x49, 0x44, 0xD9, 0x97, 0xE4, 0xF1, 0x55, 0x2D, 0xE2, 0xF3, 0x32, 0xC8, 0xA0, 0xC8,
0x81, 0xB9, 0x02, 0x87, 0x5C, 0x19, 0xB7, 0x21, 0x6A, 0xB9, 0xB0, 0x81, 0x61, 0x8C, 0x35, 0x78
},
{
0x0C, 0x7E, 0xDC, 0x78, 0x60, 0x1A, 0xC8, 0x9B, 0x3A, 0x23, 0x0B, 0x1D, 0x6F, 0xAE, 0x71, 0x6D,
0xD8, 0x3C, 0xE9, 0xA3, 0x51, 0x90, 0xAA, 0x7B, 0x7E, 0x2F, 0x2B, 0xBD, 0x34, 0xF4, 0x43, 0x3F,
0x77, 0xC4, 0x0E, 0x41, 0x04, 0xD9, 0xD4, 0x9C, 0xB3, 0xD2, 0x6B, 0xE1, 0xC6, 0xA8, 0xEF, 0x50,
0x00, 0x11, 0xE1, 0x08, 0x8B, 0xB4, 0xF1, 0xE3, 0x3D, 0x56, 0x83, 0x07, 0x7F, 0xB8, 0x47, 0xF2,
0x84, 0xD2, 0xA1, 0x50, 0x64, 0x5A, 0x08, 0x42, 0x36, 0x23, 0x09, 0x31, 0x9A, 0x6B, 0x61, 0x6F,
0x60, 0x2C, 0xF2, 0x75, 0x4E, 0x6B, 0xB9, 0x15, 0xEE, 0x3C, 0x5E, 0xA2, 0x7F, 0xA0, 0x41, 0xFE,
0x00, 0x6A, 0x30, 0x49, 0x2C, 0xEC, 0x17, 0x8B, 0x04, 0x32, 0xE9, 0x7A, 0x68, 0xA0, 0xF4, 0xDF,
0x34, 0xF7, 0x1E, 0x6F, 0x19, 0x09, 0x37, 0x87, 0x99, 0xAA, 0x81, 0x1A, 0xCD, 0xF3, 0x1F, 0x89,
0x50, 0xB2, 0x17, 0x52, 0x6D, 0x8E, 0xA6, 0x02, 0xC4, 0x2A, 0xAB, 0x3E, 0x5B, 0x38, 0x0C, 0x3F,
0x50, 0xAA, 0x5F, 0xFE, 0x47, 0x04, 0xED, 0xCD, 0xEE, 0x7C, 0xD5, 0xED, 0x5F, 0x0E, 0xC6, 0x9C,
0x79, 0x10, 0x11, 0x6F, 0x65, 0x58, 0x37, 0x95, 0x54, 0x50, 0x59, 0x68, 0x4C, 0x8E, 0xE7, 0x35,
0xF0, 0x96, 0x5A, 0x21, 0x48, 0xB4, 0x53, 0x52, 0xFC, 0xA4, 0x7C, 0x2B, 0xB1, 0xE1, 0x54, 0x2C,
0x42, 0x3B, 0x68, 0xBF, 0xBB, 0x68, 0x0D, 0x62, 0x16, 0x2F, 0xF5, 0xC8, 0x5F, 0x95, 0x11, 0xF2,
0xDF, 0x03, 0x1E, 0xCB, 0x7C, 0xD0, 0x9C, 0xE9, 0x89, 0x62, 0xEA, 0xC5, 0x4B, 0xA9, 0xD5, 0xCC,
0xD2, 0x42, 0x33, 0xA8, 0x7B, 0x2C, 0x56, 0xCF, 0xCE, 0x0D, 0x09, 0x64, 0x62, 0x3F, 0x58, 0x41,
0x71, 0x79, 0x5D, 0x1D, 0xDF, 0x08, 0x0B, 0x36, 0x97, 0x16, 0x24, 0x20, 0x76, 0x9C, 0x9E, 0xEA
}
};
static const u8 adb_rsa_pub_key[] = {
0x51, 0x41, 0x41, 0x41, 0x41, 0x46, 0x4F, 0x56, 0x4F, 0x6E, 0x49, 0x6C, 0x69, 0x51, 0x58, 0x44,
0x73, 0x42, 0x43, 0x42, 0x31, 0x75, 0x6F, 0x68, 0x70, 0x2B, 0x52, 0x71, 0x6E, 0x6E, 0x59, 0x48,
0x2F, 0x75, 0x45, 0x58, 0x34, 0x59, 0x6A, 0x50, 0x71, 0x52, 0x4D, 0x35, 0x4B, 0x75, 0x62, 0x56,
0x50, 0x71, 0x66, 0x57, 0x35, 0x64, 0x56, 0x46, 0x33, 0x2B, 0x76, 0x57, 0x6B, 0x53, 0x4B, 0x71,
0x35, 0x4C, 0x31, 0x42, 0x4F, 0x4E, 0x4D, 0x36, 0x4B, 0x4F, 0x31, 0x69, 0x31, 0x73, 0x69, 0x4F,
0x54, 0x69, 0x34, 0x6C, 0x45, 0x30, 0x6F, 0x54, 0x6F, 0x74, 0x30, 0x41, 0x4B, 0x6E, 0x4D, 0x67,
0x4E, 0x6A, 0x6F, 0x33, 0x45, 0x4D, 0x65, 0x72, 0x30, 0x6C, 0x57, 0x56, 0x54, 0x54, 0x43, 0x39,
0x68, 0x52, 0x66, 0x67, 0x46, 0x65, 0x56, 0x73, 0x43, 0x32, 0x44, 0x74, 0x71, 0x62, 0x61, 0x6D,
0x4A, 0x48, 0x63, 0x41, 0x66, 0x59, 0x77, 0x36, 0x54, 0x62, 0x4C, 0x44, 0x6C, 0x4B, 0x70, 0x6A,
0x38, 0x34, 0x33, 0x63, 0x31, 0x59, 0x5A, 0x65, 0x59, 0x6D, 0x52, 0x56, 0x4D, 0x7A, 0x4D, 0x34,
0x6E, 0x74, 0x49, 0x78, 0x64, 0x56, 0x33, 0x33, 0x76, 0x4B, 0x75, 0x39, 0x38, 0x34, 0x6A, 0x72,
0x43, 0x41, 0x47, 0x68, 0x77, 0x4A, 0x41, 0x67, 0x4A, 0x46, 0x53, 0x41, 0x4B, 0x56, 0x59, 0x51,
0x55, 0x33, 0x6A, 0x4C, 0x76, 0x41, 0x76, 0x57, 0x45, 0x6C, 0x59, 0x47, 0x37, 0x2F, 0x4B, 0x59,
0x6D, 0x55, 0x34, 0x54, 0x71, 0x73, 0x70, 0x64, 0x76, 0x4C, 0x42, 0x6F, 0x65, 0x36, 0x68, 0x64,
0x46, 0x44, 0x65, 0x76, 0x4D, 0x4D, 0x43, 0x63, 0x72, 0x6C, 0x44, 0x49, 0x66, 0x65, 0x45, 0x53,
0x57, 0x68, 0x42, 0x56, 0x35, 0x67, 0x78, 0x6A, 0x57, 0x41, 0x70, 0x4D, 0x47, 0x67, 0x53, 0x71,
0x53, 0x45, 0x6A, 0x70, 0x36, 0x79, 0x62, 0x6A, 0x33, 0x38, 0x50, 0x4C, 0x72, 0x76, 0x49, 0x51,
0x48, 0x77, 0x2B, 0x66, 0x70, 0x6F, 0x51, 0x74, 0x6F, 0x4F, 0x4E, 0x65, 0x37, 0x6F, 0x68, 0x66,
0x42, 0x77, 0x45, 0x66, 0x47, 0x46, 0x4E, 0x63, 0x33, 0x61, 0x70, 0x48, 0x50, 0x6E, 0x59, 0x53,
0x47, 0x4F, 0x67, 0x70, 0x54, 0x78, 0x70, 0x57, 0x57, 0x75, 0x49, 0x42, 0x79, 0x2F, 0x67, 0x38,
0x35, 0x2B, 0x65, 0x54, 0x30, 0x44, 0x61, 0x36, 0x53, 0x65, 0x71, 0x33, 0x67, 0x62, 0x4A, 0x59,
0x64, 0x75, 0x52, 0x44, 0x65, 0x36, 0x5A, 0x39, 0x63, 0x4A, 0x77, 0x48, 0x79, 0x38, 0x43, 0x34,
0x59, 0x79, 0x6B, 0x44, 0x56, 0x45, 0x4B, 0x6A, 0x39, 0x75, 0x52, 0x41, 0x41, 0x45, 0x59, 0x70,
0x52, 0x6B, 0x74, 0x39, 0x66, 0x34, 0x79, 0x51, 0x4A, 0x31, 0x73, 0x4D, 0x48, 0x31, 0x5A, 0x75,
0x4F, 0x55, 0x46, 0x4A, 0x46, 0x65, 0x74, 0x6B, 0x72, 0x67, 0x32, 0x44, 0x46, 0x61, 0x35, 0x30,
0x50, 0x39, 0x48, 0x61, 0x78, 0x6F, 0x4D, 0x59, 0x30, 0x41, 0x79, 0x78, 0x7A, 0x51, 0x72, 0x53,
0x77, 0x4D, 0x44, 0x79, 0x6E, 0x36, 0x64, 0x49, 0x65, 0x38, 0x65, 0x58, 0x46, 0x78, 0x51, 0x62,
0x56, 0x4D, 0x4F, 0x6C, 0x4B, 0x36, 0x79, 0x33, 0x70, 0x6F, 0x2B, 0x4A, 0x4D, 0x42, 0x34, 0x79,
0x4D, 0x42, 0x36, 0x51, 0x77, 0x30, 0x7A, 0x31, 0x35, 0x62, 0x6F, 0x58, 0x4C, 0x78, 0x4D, 0x4B,
0x76, 0x4E, 0x59, 0x6E, 0x4B, 0x4E, 0x70, 0x69, 0x6F, 0x33, 0x67, 0x45, 0x78, 0x5A, 0x2B, 0x48,
0x68, 0x57, 0x62, 0x43, 0x47, 0x69, 0x37, 0x64, 0x4A, 0x6C, 0x56, 0x47, 0x50, 0x6F, 0x74, 0x34,
0x4D, 0x42, 0x45, 0x4C, 0x7A, 0x43, 0x38, 0x66, 0x4C, 0x55, 0x44, 0x69, 0x41, 0x43, 0x49, 0x54,
0x37, 0x75, 0x31, 0x58, 0x31, 0x62, 0x68, 0x65, 0x71, 0x6C, 0x35, 0x59, 0x7A, 0x43, 0x30, 0x6C,
0x67, 0x2F, 0x4B, 0x48, 0x5A, 0x7A, 0x62, 0x36, 0x6D, 0x63, 0x74, 0x4E, 0x2B, 0x34, 0x62, 0x52,
0x74, 0x79, 0x4B, 0x35, 0x75, 0x52, 0x52, 0x4A, 0x70, 0x48, 0x45, 0x56, 0x63, 0x4B, 0x58, 0x57,
0x50, 0x34, 0x30, 0x73, 0x31, 0x79, 0x38, 0x37, 0x75, 0x30, 0x6D, 0x49, 0x50, 0x4A, 0x6E, 0x73,
0x39, 0x6D, 0x4F, 0x2F, 0x2F, 0x44, 0x41, 0x35, 0x4C, 0x32, 0x6D, 0x64, 0x77, 0x56, 0x79, 0x73,
0x72, 0x74, 0x4B, 0x51, 0x69, 0x51, 0x37, 0x36, 0x57, 0x6A, 0x74, 0x59, 0x51, 0x63, 0x41, 0x73,
0x46, 0x2B, 0x42, 0x54, 0x4E, 0x56, 0x48, 0x62, 0x41, 0x6E, 0x7A, 0x7A, 0x52, 0x75, 0x6C, 0x52,
0x61, 0x43, 0x45, 0x78, 0x2B, 0x6E, 0x30, 0x49, 0x6A, 0x35, 0x34, 0x49, 0x45, 0x41, 0x4F, 0x75,
0x55, 0x4B, 0x70, 0x6F, 0x61, 0x48, 0x71, 0x6F, 0x56, 0x4F, 0x33, 0x51, 0x42, 0x36, 0x52, 0x41,
0x51, 0x7A, 0x4D, 0x67, 0x70, 0x44, 0x73, 0x41, 0x30, 0x58, 0x34, 0x4C, 0x6A, 0x4F, 0x32, 0x52,
0x2B, 0x4D, 0x4B, 0x6F, 0x6D, 0x6F, 0x6C, 0x52, 0x5A, 0x6F, 0x32, 0x34, 0x57, 0x32, 0x41, 0x35,
0x57, 0x2B, 0x30, 0x56, 0x4A, 0x77, 0x45, 0x41, 0x41, 0x51, 0x41, 0x3D, 0x20, 0x75, 0x6E, 0x6B,
0x6E, 0x6F, 0x77, 0x6E, 0x40, 0x75, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x6E, 0x00
};
#endif

View File

@ -1,232 +0,0 @@
/**
* @file aoa.c
* @brief https://source.android.com/devices/accessories/aoa
* http://www.hackermi.com/2015-04/aoa-analyse/
* Android 开放配件协议 1.0
* @author chenrixin@zh-jieli.com
* @version 1
* @date 2020-03-25
*/
#include "includes.h"
#include "app_config.h"
#include "usb_config.h"
#include "usb/host/usb_host.h"
#include "usb/usb_phy.h"
#include "device_drive.h"
#include "usb_ctrl_transfer.h"
#include "usb_bulk_transfer.h"
#include "usb_storage.h"
#include "adb.h"
#include "aoa.h"
#include "usb_hid_keys.h"
#if TCFG_AOA_ENABLE
#include "gamebox.h"
#define LOG_TAG_CONST USB
#define LOG_TAG "[AOA]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
//0x2D00 有一个接口,该接口有两个批量端点,用于输入和输出通信。
//0x2D01 有两个接口,每个接口有两个批量端点,用于输入和输出通信。
//第一个接口处理标准通信,
//第二个接口则处理 ADB 通信。
//要使用接口,请找到第一个批量输入和输出端点,
//使用 SET_CONFIGURATION (0x09) 设备请求将设备配置的值设为 1然后使用端点进行通信
//
static void aoa_timer_handler(void *priv);
static u32 aoa_timer_id;
static struct aoa_device_t aoa;
static struct device aoa_device;
static int set_power(struct usb_host_device *host_dev, u32 value)
{
if (aoa_timer_id) {
usr_timer_del(aoa_timer_id);
aoa_timer_id = 0;
}
return DEV_ERR_NONE;
}
static int get_power(struct usb_host_device *host_dev, u32 value)
{
return DEV_ERR_NONE;
}
static const struct interface_ctrl aoa_ctrl = {
.interface_class = USB_CLASS_AOA,
.set_power = set_power,
.get_power = get_power,
.ioctl = NULL,
};
static const struct usb_interface_info aoa_inf = {
.ctrl = (struct interface_ctrl *) &aoa_ctrl,
.dev.aoa = &aoa,
};
static const char *credetials[] = {"JieLiTec",
"GameBox",
"Android accessories devcie !",
"1.0.0",
"http://www.zh-jieli.com",
"1234567890ABCDEF",
};
void aoa_switch(struct usb_host_device *host_dev)
{
u16 version;
log_info("aoa_switch");
usb_get_aoa_version(host_dev, &version);
log_info("AOA version: %x", version);
for (int i = 0; i < 5; i++) {
log_info("send string [%d] %s", i, credetials[i]);
int r = usb_set_credentials(host_dev, credetials[i], i);
if (r < 0) {
break;
}
}
usb_switch2aoa(host_dev);
}
int usb_aoa_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
{
struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)pBuf;
pBuf += sizeof(struct usb_interface_descriptor);
int len = 0;
const usb_dev usb_id = host_device2id(host_dev);
aoa_device.private_data = host_dev;
host_dev->interface_info[interface_num] = &aoa_inf;
for (int endnum = 0; endnum < interface->bNumEndpoints; endnum++) {
struct usb_endpoint_descriptor *end_desc = (struct usb_endpoint_descriptor *)pBuf;
if (end_desc->bDescriptorType != USB_DT_ENDPOINT ||
end_desc->bLength != USB_DT_ENDPOINT_SIZE) {
log_error("ep bDescriptorType = %d bLength = %d", end_desc->bDescriptorType, end_desc->bLength);
return -USB_DT_ENDPOINT;
}
len += USB_DT_ENDPOINT_SIZE;
pBuf += USB_DT_ENDPOINT_SIZE;
if ((end_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
if (end_desc->bEndpointAddress & USB_DIR_IN) {
aoa.target_epin = end_desc->bEndpointAddress & 0x0f;
#if defined(FUSB_MODE) && FUSB_MODE == 0
aoa.rxmaxp = end_desc->wMaxPacketSize;
#endif
} else {
aoa.target_epout = end_desc->bEndpointAddress & 0x0f;
#if defined(FUSB_MODE) && FUSB_MODE == 0
aoa.txmaxp = end_desc->wMaxPacketSize;
#endif
}
}
}
return len;
}
static int aoa_tx_data(const u8 *pbuf, u32 len)
{
struct usb_host_device *host_dev = aoa_device.private_data;
usb_dev usb_id = host_device2id(host_dev);
g_printf("TX:");
printf_buf(pbuf, len);
return usb_h_ep_write_async(usb_id, aoa.host_epout, 64, aoa.target_epout, pbuf, len, USB_ENDPOINT_XFER_BULK, 1);
}
static void aoa_epin_isr(struct usb_host_device *host_dev, u32 ep)
{
u8 buffer[64] = {0};
usb_dev usb_id = host_device2id(host_dev);
u32 rx_len = usb_h_ep_read_async(usb_id, ep, aoa.target_epin, buffer, sizeof(buffer), USB_ENDPOINT_XFER_BULK, 0);
g_printf("RX:");
printf_buf(buffer, rx_len);
usb_h_ep_read_async(usb_id, ep, aoa.target_epin, NULL, 0, USB_ENDPOINT_XFER_BULK, 1);
}
#define Accessory_assigned_ID 0x0001
u32 aoa_process(u32 mode, u32 id)
{
struct usb_host_device *host_dev = aoa_device.private_data;
struct usb_device_descriptor device_desc;
usb_get_device_descriptor(host_dev, &device_desc);
if ((device_desc.idVendor == 0x18d1) &&
((device_desc.idProduct & 0x2d00) == 0x2d00)) {
log_info("aoa mode ready idVendor:%x idProduct: %x",
device_desc.idVendor, device_desc.idProduct);
} else {
log_info("aoa switch idVendor:%x idProduct: %x",
device_desc.idVendor, device_desc.idProduct);
aoa_switch(host_dev);
usb_host_remount(id, 3, 30, 50, 1);
return 0;
}
usb_aoa_register_hid(host_dev, Accessory_assigned_ID, sizeof(hid_report_desc));
u32 offset = 0;
while (offset < sizeof(hid_report_desc)) {
u32 cnt = min(sizeof(hid_report_desc) - offset, 63);
usb_aoa_set_hid_report_desc(host_dev, Accessory_assigned_ID, offset, &hid_report_desc[offset], cnt);
offset += cnt;
}
aoa.host_epout = usb_get_ep_num(id, USB_DIR_OUT, USB_ENDPOINT_XFER_BULK);
aoa.host_epin = usb_get_ep_num(id, USB_DIR_IN, USB_ENDPOINT_XFER_BULK);
log_debug("D(%d)->H(%d)", aoa.target_epin, aoa.host_epin);
log_debug("H(%d)->D(%d)", aoa.host_epout, aoa.target_epout);
usb_h_set_ep_isr(host_dev, aoa.host_epin | USB_DIR_IN, aoa_epin_isr, host_dev);
u8 *ep_buffer = usb_h_get_ep_buffer(id, aoa.host_epin | USB_DIR_IN);
usb_h_ep_config(id, aoa.host_epin | USB_DIR_IN, USB_ENDPOINT_XFER_BULK, 1, 0, ep_buffer, 64);
int r = usb_h_ep_read_async(id, aoa.host_epin, aoa.target_epin, NULL, 0, USB_ENDPOINT_XFER_BULK, 1);
ep_buffer = usb_h_get_ep_buffer(id, aoa.host_epout | USB_DIR_OUT);
usb_h_ep_config(id, aoa.host_epout | USB_DIR_OUT, USB_ENDPOINT_XFER_BULK, 0, 0, ep_buffer, 64);
aoa_timer_id = usr_timer_add((void *)0, aoa_timer_handler, 4, 0);
g_printf("aoa succ");
return 1;
}
static void aoa_timer_handler(void *priv)
{
struct usb_host_device *host_dev = aoa_device.private_data;
u8 tx_buffer[32];
if (mouse_data_send == 1) {
tx_buffer[0] = MOUSE_POINT_ID;
memcpy(&tx_buffer[1], &mouse_data, sizeof(mouse_data));
usb_aoa_send_hid_event(host_dev, Accessory_assigned_ID, tx_buffer, sizeof(mouse_data) + 1);
memset(&mouse_data, 0, sizeof(mouse_data)) ;
mouse_data_send = 0;
}
tx_buffer[0] = TOUCH_SCREEN_ID;
struct touch_screen_t t;
memset(&t, 0, sizeof(t));
if (point_list_pop(&t)) {
memcpy(&tx_buffer[1], &t, sizeof(t));
usb_aoa_send_hid_event(host_dev, Accessory_assigned_ID, tx_buffer, sizeof(t) + 1);
}
}
#endif

View File

@ -1,20 +0,0 @@
#ifndef __AOA_H__
#define __AOA_H__
struct aoa_device_t {
u16 version;
u8 target_epin;
u8 target_epout;
u8 host_epin;
u8 host_epout;
struct adb_device_t *adb;
};
u32 aoa_process(u32 mode, u32 id);
int usb_aoa_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf);
#endif /*AOA_H*/

View File

@ -1,8 +0,0 @@
#ifndef _APPLE_MFI_H_
#define _APPLE_MFI_H_
int usb_apple_mfi_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf);
#endif

View File

@ -1,820 +0,0 @@
#include "includes.h"
#include "asm/includes.h"
#include "app_config.h"
#include "system/timer.h"
#include "device/ioctl_cmds.h"
#include "device_drive.h"
#if TCFG_HOST_AUDIO_ENABLE
#include "usb/host/usb_host.h"
#include "usb_ctrl_transfer.h"
#include "usb_bulk_transfer.h"
#include "audio.h"
#include "usb_config.h"
#define LOG_TAG_CONST USB
#define LOG_TAG "[AUDIO]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
/* #define USB_AUDIO_PLAY_TEST */
struct usb_audio_play {
u32 sample_rate;
u8 Cur_AlternateSetting;
u8 src_channel;
u8 play_state;
u8 mute;
u8 *send_buf;
u8 *usb_audio_play_buf;
u8 *usb_audio_play_buf2;
cbuffer_t usb_audio_play_cbuf;
u32 usb_audio_remain_len;
OS_SEM sem;
int (*put_buf)(void *ptr, u32 len);
};
struct usb_audio_mic {
u8 Cur_AlternateSetting;
u32 sample_rate;
u8 record_state;
u8 *usb_audio_record_buf;
u8 *usb_audio_record_buf2;
cbuffer_t usb_audio_record_cbuf;
int *(*get_buf)(void *ptr, u32 len);
};
struct usb_audio_info {
usb_dev usb_id;
struct usb_audio_play player;
struct usb_audio_mic microphone;
};
enum {
AUDIO_PLAY_IDLE = 0,
AUDIO_PLAY_START,
AUDIO_PLAY_STOP,
AUDIO_PLAY_PAUSE,
};
enum {
AUDIO_RECORD_IDLE = 0,
AUDIO_RECORD_START,
AUDIO_RECORD_STOP,
AUDIO_RECORD_PAUSE,
};
#define EP_MAX_PACKET_SIZE (192)
struct usb_audio_info _usb_audio_info = {0};
#define __this (&_usb_audio_info)
struct audio_device_t audio_device[USB_MAX_HW_NUM][MAX_HOST_INTERFACE];
static u8 ep_in_dma_buf[256] __attribute__((aligned(4)));
static u8 ep_out_dma_buf[256] __attribute__((aligned(4)));
static int set_power(struct usb_host_device *host_dev, u32 value)
{
const usb_dev usb_id = host_device2id(host_dev);
return DEV_ERR_NONE;
}
static int get_power(struct usb_host_device *host_dev, u32 value)
{
return DEV_ERR_NONE;
}
static const struct interface_ctrl uac_ctrl = {
.interface_class = USB_CLASS_AUDIO,
.set_power = set_power,
.get_power = get_power,
.ioctl = NULL,
};
static const struct usb_interface_info _uac_if[USB_MAX_HW_NUM][MAX_HOST_INTERFACE] = {
{
{
.ctrl = (struct interface_ctrl *) &uac_ctrl,
.dev.audio = &audio_device[0][0],
},
{
.ctrl = (struct interface_ctrl *) &uac_ctrl,
.dev.audio = &audio_device[0][1],
},
{
.ctrl = (struct interface_ctrl *) &uac_ctrl,
.dev.audio = &audio_device[0][2],
},
{
.ctrl = (struct interface_ctrl *) &uac_ctrl,
.dev.audio = &audio_device[0][3],
},
},
};
int usb_audio_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
{
struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)pBuf;
const usb_dev usb_id = host_device2id(host_dev);
const struct usb_interface_info *usb_if = &_uac_if[usb_id][interface_num];
struct audio_streaming_t *as_t = NULL;
memset(usb_if->dev.p, 0, sizeof(struct audio_device_t));
host_dev->interface_info[interface_num] = usb_if;
usb_if->dev.audio->parent = host_dev;
if (interface->bInterfaceSubClass == USB_SUBCLASS_AUDIOCONTROL) {
log_info("audio control interface : %d\n", interface_num);
pBuf += sizeof(struct usb_interface_descriptor);
usb_if->dev.audio->subclass = interface->bInterfaceSubClass;
usb_if->dev.audio->interface_num = interface_num;
return sizeof(struct usb_interface_descriptor);
}
if (interface->bInterfaceSubClass == USB_SUBCLASS_AUDIOSTREAMING) {
usb_if->dev.audio->subclass = interface->bInterfaceSubClass;
usb_if->dev.audio->interface_num = interface_num;
if (interface->bNumEndpoints == 0) {
pBuf += sizeof(struct usb_interface_descriptor);
do {
struct usb_interface_descriptor *as_interface = (struct usb_interface_descriptor *)pBuf;
if (as_interface->bNumEndpoints == 0 || as_interface->bInterfaceClass != USB_CLASS_AUDIO) {
break;
}
log_info("audio streaming interface : %d ep_num:%d Altersetting:%d", interface_num, as_interface->bNumEndpoints, as_interface->bAlternateSetting);
as_t = &usb_if->dev.audio->as[as_interface->bAlternateSetting - 1];
as_t->bNumEndpoints = as_interface->bNumEndpoints;
pBuf += (USB_DT_INTERFACE_SIZE + UAC_DT_AS_HEADER_SIZE);
//解析format
struct uac_format_type_i_discrete_descriptor *uac_format_desc = (struct uac_format_type_i_discrete_descriptor *)pBuf;
if (uac_format_desc->bDescriptorSubtype == UAC_FORMAT_TYPE) {
as_t->bFormatType = uac_format_desc->bFormatType;
as_t->bNrChannels = uac_format_desc->bNrChannels;
as_t->bSubframeSize = uac_format_desc->bSubframeSize;
as_t->bBitResolution = uac_format_desc->bBitResolution;
as_t->bSamFreqType = uac_format_desc->bSamFreqType;
for (u8 i = 0; i < as_t->bSamFreqType; i++) {
memcpy(&as_t->tSamFreq[i], &uac_format_desc->tSamFreq[i], 3);
log_info("as bNrChannels:%d bBitResolution:%d tSamFreq : %d", as_t->bNrChannels, as_t->bBitResolution, as_t->tSamFreq[i]);
}
//Endpointdescriptor
pBuf += uac_format_desc->bLength;
/* for (int i = 0; i < as_t->bNumEndpoints; i++) { */
struct usb_endpoint_descriptor *endpoint = (struct usb_endpoint_descriptor *)pBuf;
if (endpoint->bDescriptorType == USB_DT_ENDPOINT) {
as_t->ep_Interval = endpoint->bInterval;
as_t->ep_max_packet_size = endpoint->wMaxPacketSize;
if (endpoint->bEndpointAddress & USB_DIR_IN) {
as_t->ep = endpoint->bEndpointAddress & 0xf;
log_info("ep in : %x\n", as_t->ep);
usb_if->dev.audio->support = MICROPHONE_SUPPORTED;
} else {
as_t->ep = endpoint->bEndpointAddress;
log_info("ep out : %x\n", as_t->ep);
usb_if->dev.audio->support = HEADPHONE_SUPPORTED;
}
pBuf += (USB_DT_ENDPOINT_AUDIO_SIZE + UAC_ISO_ENDPOINT_DESC_SIZE);
}
/* } */
} else {
log_error("uac_format_desc->bDescriptorSubtype err!!\n");
goto __exit;
}
} while (1);
/* log_info("lennnn:%d\n",pBuf - (u8 *)interface); */
return pBuf - (u8 *)interface ;
} else {
log_info("audio streaming interface : %d ep_num:%d Altersetting:%d\n", interface_num, interface->bNumEndpoints, interface->bAlternateSetting);
}
}
__exit:
return USB_DT_INTERFACE_SIZE;
}
static struct audio_device_t *__find_microphone_interface(const struct usb_host_device *host_dev)
{
struct audio_device_t *audio = NULL;
for (u8 i = 0; i < MAX_HOST_INTERFACE; i++) {
const struct usb_interface_info *usb_if = host_dev->interface_info[i];
if (usb_if &&
(usb_if->ctrl->interface_class == USB_CLASS_AUDIO)) {
audio = usb_if->dev.audio;
if (audio->subclass == USB_SUBCLASS_AUDIOSTREAMING &&
audio->support == MICROPHONE_SUPPORTED) {
// find microphone
return audio;
}
}
}
return NULL;
}
static struct audio_device_t *__find_headphone_interface(const struct usb_host_device *host_dev)
{
struct audio_device_t *audio = NULL;
for (u8 i = 0; i < MAX_HOST_INTERFACE; i++) {
const struct usb_interface_info *usb_if = host_dev->interface_info[i];
if (usb_if &&
(usb_if->ctrl->interface_class == USB_CLASS_AUDIO)) {
audio = usb_if->dev.audio;
if (audio->subclass == USB_SUBCLASS_AUDIOSTREAMING &&
audio->support == HEADPHONE_SUPPORTED) {
// find headphone
return audio;
}
}
}
return NULL;
}
static u32 play_vol_convert(u16 v)
{
//固定音量表,更换声卡需要修改音量表
const u16 vol_table[] = {
//0-100
0xd300, //0
0xd58f, 0xd7bf, 0xd9a8, 0xdb5b, 0xdce1, 0xde45, 0xdf8a, 0xe0b6, 0xe1cd, 0xe2d1,
0xe3c5, 0xe4ab, 0xe583, 0xe651, 0xe714, 0xe7cd, 0xe87f, 0xe928, 0xe9ca, 0xea66,
0xeafc, 0xeb8d, 0xec18, 0xec9e, 0xed20, 0xed9e, 0xee18, 0xee8e, 0xef00, 0xef6f,
0xefdc, 0xf045, 0xf0ab, 0xf10f, 0xf171, 0xf1d0, 0xf22c, 0xf287, 0xf2e0, 0xf336,
0xf38b, 0xf3de, 0xf42f, 0xf47e, 0xf4cc, 0xf518, 0xf563, 0xf5ad, 0xf5f5, 0xf63c,
0xf681, 0xf6c6, 0xf709, 0xf74b, 0xf78c, 0xf7cb, 0xf80a, 0xf848, 0xf885, 0xf8c1,
0xf8fc, 0xf936, 0xf96f, 0xf9a8, 0xf9df, 0xfa16, 0xfa4c, 0xfa81, 0xfab6, 0xfaea,
0xfb1d, 0xfb50, 0xfb82, 0xfbb3, 0xfbe4, 0xfc14, 0xfc43, 0xfc72, 0xfca0, 0xfcce,
0xfcfc, 0xfd28, 0xfd55, 0xfd80, 0xfdab, 0xfdd6, 0xfe01, 0xfe2a, 0xfe54, 0xfe7d,
0xfea5, 0xfece, 0xfef5, 0xff1d, 0xff43, 0xff6a, 0xff90, 0xffb6, 0xffdb, 0x0000,
};
if (v <= 100) {
return vol_table[v];
}
for (int i = 0; i < sizeof(vol_table) / 2; i++) {
if (v <= vol_table[i]) {
return i;
}
}
return 0;
}
void set_usb_audio_play_volume(u16 vol)
{
const struct usb_host_device *host_dev = host_id2device(__this->usb_id);
u8 featureUnitID = 6;
usb_audio_volume_control(host_dev, featureUnitID, 1, play_vol_convert(vol));
usb_audio_volume_control(host_dev, featureUnitID, 2, play_vol_convert(vol));
if (vol == 0) {
__this->player.mute = 1;
usb_audio_mute_control(host_dev, featureUnitID, __this->player.mute); //mute
} else {
if (__this->player.mute == 1) {
__this->player.mute = 0;
usb_audio_mute_control(host_dev, featureUnitID, __this->player.mute);
}
}
}
#ifdef USB_AUDIO_PLAY_TEST
static const s16 sin_48k[] = {
0, 2139, 4240, 6270, 8192, 9974, 11585, 12998,
14189, 15137, 15826, 16244, 16384, 16244, 15826, 15137,
14189, 12998, 11585, 9974, 8192, 6270, 4240, 2139,
0, -2139, -4240, -6270, -8192, -9974, -11585, -12998,
-14189, -15137, -15826, -16244, -16384, -16244, -15826, -15137,
-14189, -12998, -11585, -9974, -8192, -6270, -4240, -2139
};
#endif
static void usb_audio_tx_isr(struct usb_host_device *host_dev, u32 ep)
{
const usb_dev usb_id = host_device2id(host_dev);
struct audio_device_t *audio = NULL;
struct audio_streaming_t *as_t = NULL;
u16 ep_max_packet_size = 0;
u8 channel = 0;
u32 rlen = 0;
static u32 usb_audio_tx_len = 0;
if (__this->player.play_state != AUDIO_PLAY_START) {
return;
}
audio = __find_headphone_interface(host_dev);
if (!audio) {
log_error("no find headphone interface!");
return;
}
as_t = &audio->as[__this->player.Cur_AlternateSetting - 1];
/* ep_max_packet_size = as_t->ep_max_packet_size; */
ep_max_packet_size = EP_MAX_PACKET_SIZE;
channel = as_t->bNrChannels;
//iso send
#ifdef USB_AUDIO_PLAY_TEST
//For Test
int tx_len = 0;
#if 1 // 单声道双声道输出
s16 buf[240 / 2];
for (u8 i = 0, j = 0; i < 240 / 2; i += 2) {
buf[i] = sin_48k[j];
buf[i + 1] = sin_48k[j];
j++;
if (j >= sizeof(sin_48k) / sizeof(sin_48k[0])) {
j = 0;
}
}
#else
//单声道直接输出
u8 buf[248];
do {
memcpy(&buf[tx_len], sin_48k, sizeof(sin_48k));
tx_len += sizeof(sin_48k);
} while (tx_len < ep_max_packet_size);
#endif
usb_h_ep_write_async(usb_id, ep, ep_max_packet_size, as_t->ep, buf, ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 0);
#else
if (__this->player.usb_audio_remain_len == 0) {
cbuf_read_alloc(&__this->player.usb_audio_play_cbuf, &__this->player.usb_audio_remain_len);
usb_audio_tx_len = 0;
}
if (__this->player.usb_audio_remain_len) {
if (usb_audio_tx_len == 0) {
rlen = cbuf_read(&__this->player.usb_audio_play_cbuf, __this->player.usb_audio_play_buf2, __this->player.usb_audio_remain_len);
if (!rlen) {
__this->player.usb_audio_remain_len = 0;
usb_audio_tx_len = 0;
putchar('C');
usb_h_ep_write_async(usb_id, ep, ep_max_packet_size, as_t->ep, NULL, ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 1);
os_sem_post(&__this->player.sem);
return;
}
os_sem_post(&__this->player.sem);
}
u8 *send_buf = __this->player.send_buf;
u8 *play_buf = __this->player.usb_audio_play_buf2;
if (channel == 2) {
if (__this->player.src_channel == 1) {
//源数据是单声道数据,转双声道输出
int j = 0;
for (u8 i = 0; i < ep_max_packet_size; i += 4) {
//left
*(send_buf + i) = *(play_buf + (usb_audio_tx_len + j));
*(send_buf + i + 1) = *(play_buf + (usb_audio_tx_len + j + 1));
//right
*(send_buf + i + 2) = *(play_buf + (usb_audio_tx_len + j));
*(send_buf + i + 3) = *(play_buf + (usb_audio_tx_len + j + 1));
j += 2;
}
usb_audio_tx_len += j;
usb_h_ep_write_async(usb_id, ep, ep_max_packet_size, as_t->ep, send_buf, ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 0);
} else if (__this->player.src_channel == 2) {
//源数据是双声道数据,直接双声道输出
usb_h_ep_write_async(usb_id, ep, ep_max_packet_size, as_t->ep, play_buf + usb_audio_tx_len, ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 0);
usb_audio_tx_len += ep_max_packet_size;
}
} else if (channel == 1) {
}
if (usb_audio_tx_len >= __this->player.usb_audio_remain_len) {
__this->player.usb_audio_remain_len = 0;
usb_audio_tx_len = 0;
}
} else {
//audio buf null ,send null packet
putchar('E');
usb_h_ep_write_async(usb_id, ep, ep_max_packet_size, as_t->ep, NULL, ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 1);
}
#endif
}
void set_vol_test(void *p)
{
struct usb_host_device *host_dev = (struct usb_host_device *)p;
static u16 vol = 100;
set_usb_audio_play_volume(vol);
/* static u8 f = 0; */
/* void usb_audio_pause_play(void); */
/* void usb_audio_resume_play(void); */
/* if (!f) { */
/* usb_audio_pause_play(); */
/* } else { */
/* usb_audio_resume_play(); */
/* } */
/* f = !f; */
vol -= 10;
}
void audio_play_task(void *p)
{
log_info(">>> Enter usb audio play task");
struct usb_host_device *host_dev = (struct usb_host_device *)p;
const usb_dev usb_id = host_device2id(host_dev);
u8 *ptr = NULL;
u32 wlen = 0;
u32 ret = 0;
struct audio_device_t *audio = NULL;
audio = __find_headphone_interface(host_dev);
struct audio_streaming_t *as_t = &audio->as[__this->player.Cur_AlternateSetting - 1];
/* u32 ep_max_packet_size = as_t->ep_max_packet_size; */
u32 ep_max_packet_size = EP_MAX_PACKET_SIZE;
log_info("ep max packet : %d\n", ep_max_packet_size);
if (__this->player.send_buf) {
free(__this->player.send_buf);
__this->player.send_buf = NULL;
}
__this->player.send_buf = zalloc(ep_max_packet_size);
u32 usb_audio_buf_size = ep_max_packet_size * 5; //预留5个包的缓存
/* sys_timer_add(host_dev,set_vol_test,5000); */
os_sem_create(&__this->player.sem, 0);
u32 host_ep = as_t->host_ep;
__this->player.play_state = AUDIO_PLAY_START;
//分配双缓存
// 一个缓存保存读卡的数据,一个用于usb发送
if (!__this->player.usb_audio_play_buf) {
__this->player.usb_audio_play_buf = zalloc(usb_audio_buf_size);
cbuf_init(&__this->player.usb_audio_play_cbuf, __this->player.usb_audio_play_buf, usb_audio_buf_size);
usb_h_ep_write_async(usb_id, host_ep, ep_max_packet_size, as_t->ep, NULL, ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 1); //启动iso传输
}
if (!__this->player.usb_audio_play_buf2) {
__this->player.usb_audio_play_buf2 = zalloc(usb_audio_buf_size);
}
while (1) {
if (__this->player.Cur_AlternateSetting == 0 || __this->player.play_state != AUDIO_PLAY_START) {
putchar('C');
os_time_dly(50);
continue;
}
ptr = cbuf_write_alloc(&__this->player.usb_audio_play_cbuf, &wlen);
if (wlen) {
putchar('R');
ret = __this->player.put_buf(ptr, wlen);
if (ret != wlen) {
__this->player.play_state = AUDIO_PLAY_STOP;
goto __task_exit;
}
cbuf_write_updata(&__this->player.usb_audio_play_cbuf, wlen);
} else {
log_w("usb audio play buf not enough!\n");
}
__task_exit:
os_sem_pend(&__this->player.sem, 0);
}
}
void usb_audio_start_play(const usb_dev usb_id, u8 channel, u8 bit_reso, u32 sample_rate)
{
log_info(" usb audio play\n");
const struct usb_host_device *host_dev = host_id2device(usb_id);
struct audio_device_t *audio = NULL;
struct audio_streaming_t *as_t = NULL;
u8 *ep_buffer = ep_out_dma_buf;
u8 find_alternatesetting = 0;
audio = __find_headphone_interface(host_dev);
if (!audio) {
log_error("no find headphone interface!");
return;
}
for (u8 i = 0; i < ARRAY_SIZE(audio->as); i++) {
as_t = &audio->as[i];
if (as_t->bBitResolution == bit_reso) {
for (u8 j = 0; j < as_t->bSamFreqType; j++) {
if (as_t->tSamFreq[j] == sample_rate) {
find_alternatesetting = i + 1;
break;
}
}
}
}
if (!find_alternatesetting) {
log_e("can not find Alternatesetting,please check bit_reso and sample_rate\n");
return;
}
__this->usb_id = usb_id;
//端点分配
u32 host_ep = usb_get_ep_num(usb_id, USB_DIR_OUT, USB_ENDPOINT_XFER_ISOC);
ASSERT(host_ep != -1, "ep not enough");
__this->player.Cur_AlternateSetting = find_alternatesetting; //选择Alternatesetting
__this->player.sample_rate = sample_rate; //选择采样率
__this->player.src_channel = channel;
as_t = &audio->as[find_alternatesetting - 1];
u8 target_ep = as_t->ep;
u8 ep_interval = as_t->ep_Interval;
as_t->host_ep = host_ep;
usb_set_interface(host_dev, audio->interface_num, find_alternatesetting); //interface Alternatesetting
usb_audio_sampling_frequency_control(host_dev, target_ep, sample_rate);//设置采样率
//设置音量
/* usb_audio_volume_control(host_dev, 6, 1, vol_convert(5)); */
/* usb_audio_volume_control(host_dev, 6, 2, vol_convert(5)); */
log_info("H2D ep: %x --> %x interval: %d", host_ep, target_ep, ep_interval);
usb_h_set_ep_isr(host_dev, host_ep, usb_audio_tx_isr, host_dev);
usb_h_ep_config(usb_id, host_ep, USB_ENDPOINT_XFER_ISOC, 1, ep_interval, ep_buffer, sizeof(ep_out_dma_buf));
task_create(audio_play_task, host_dev, "uac_play");
}
void usb_audio_stop_play(const usb_dev usb_id)
{
const struct usb_host_device *host_dev = host_id2device(usb_id);
usb_h_set_ep_isr(NULL, 0, NULL, NULL);
__this->player.put_buf(NULL, 0);
__this->player.Cur_AlternateSetting = 0;
__this->player.sample_rate = 0;
__this->player.src_channel = 0;
if (__this->player.usb_audio_play_buf) {
free(__this->player.usb_audio_play_buf);
__this->player.usb_audio_play_buf = NULL;
}
if (__this->player.usb_audio_play_buf2) {
free(__this->player.usb_audio_play_buf2);
__this->player.usb_audio_play_buf2 = NULL;
}
if (__this->player.send_buf) {
free(__this->player.send_buf);
__this->player.send_buf = NULL;
}
printf("\n[ debug ]--func=%s line=%d\n", __func__, __LINE__);
task_kill("uac_play");
printf("\n[ debug ]--func=%s line=%d\n", __func__, __LINE__);
}
void usb_audio_pause_play(void)
{
__this->player.play_state = AUDIO_PLAY_PAUSE;
}
void usb_audio_resume_play(void)
{
const struct usb_host_device *host_dev = host_id2device(__this->usb_id);
struct audio_device_t *audio = __find_headphone_interface(host_dev);
struct audio_streaming_t *as_t = &audio->as[__this->player.Cur_AlternateSetting - 1];
__this->player.play_state = AUDIO_PLAY_START;
usb_h_ep_write_async(__this->usb_id, as_t->host_ep, as_t->ep_max_packet_size, as_t->ep, NULL, as_t->ep_max_packet_size, USB_ENDPOINT_XFER_ISOC, 1); //重新启动传输
}
static u32 record_vol_convert(u16 v)
{
//固定音量表,更换声卡需要修改音量表
const u16 vol_table[] = {
//0-100
0xf400,
0xf479, 0xf4ee, 0xf560, 0xf5cf, 0xf63a, 0xf6a3, 0xf709, 0xf76c, 0xf7cd, 0xf82b,
0xf887, 0xf8e1, 0xf939, 0xf98f, 0xf9e4, 0xfa36, 0xfa87, 0xfad6, 0xfb23, 0xfb6f,
0xfbba, 0xfc03, 0xfc4b, 0xfc91, 0xfcd6, 0xfd1a, 0xfd5d, 0xfd9f, 0xfde0, 0xfe1f,
0xfe5e, 0xfe9b, 0xfed8, 0xff14, 0xff4e, 0xff88, 0xffc1, 0xfff9, 0x0003, 0x0069,
0x00a3, 0x00de, 0x0119, 0x0155, 0x0193, 0x01d1, 0x0210, 0x0251, 0x0292, 0x02d5,
0x0318, 0x035d, 0x03a3, 0x03eb, 0x0434, 0x047e, 0x04c9, 0x0517, 0x0565, 0x05b5,
0x0607, 0x065b, 0x06b1, 0x0708, 0x0762, 0x07bd, 0x081b, 0x087c, 0x08de, 0x0943,
0x09ab, 0x0a16, 0x0a84, 0x0af4, 0x0b69, 0x0be1, 0x0c5c, 0x0cdc, 0x0d60, 0x0de9,
0x0e77, 0x0f0a, 0x0fa2, 0x1041, 0x10e7, 0x1195, 0x124a, 0x1308, 0x13d0, 0x14a3,
0x1582, 0x166e, 0x176a, 0x1877, 0x1998, 0x1ad0, 0x1c24, 0x1d98, 0x1f33, 0x2100,
};
if (v <= 100) {
return vol_table[v];
}
for (int i = 0; i < sizeof(vol_table) / 2; i++) {
if (v <= vol_table[i]) {
return i;
}
}
return 0;
}
void set_usb_audio_record_volume(u16 vol)
{
const struct usb_host_device *host_dev = host_id2device(__this->usb_id);
u8 featureUnitID = 5;
usb_audio_volume_control(host_dev, featureUnitID, 0, record_vol_convert(vol));
}
static u32 write_file_len = 0;
static void usb_audio_rx_isr(struct usb_host_device *host_dev, u32 ep)
{
u8 buffer[192] = {0};
u8 *ptr = NULL;
int rlen, wlen = 0;
usb_dev usb_id = host_device2id(host_dev);
struct audio_device_t *audio = NULL;
struct audio_streaming_t *as_t = NULL;
audio = __find_microphone_interface(host_dev);
if (!audio) {
log_error("no find microphone interface!");
return;
}
if (__this->microphone.record_state != AUDIO_RECORD_START) {
return;
}
as_t = &audio->as[__this->microphone.Cur_AlternateSetting - 1];
u8 channel = as_t->bNrChannels;
u32 rx_len = usb_h_ep_read_async(usb_id, ep, as_t->ep, buffer, sizeof(buffer), USB_ENDPOINT_XFER_ISOC, 0);
/* g_printf("RX:%d\n",rx_len); */
/* printf_buf(buffer, rx_len); */
cbuf_write(&__this->microphone.usb_audio_record_cbuf, buffer, rx_len);
cbuf_write_alloc(&__this->microphone.usb_audio_record_cbuf, &wlen);
if (wlen == 0) {
putchar('O');
if (write_file_len) {
log_w("write againnnnn\n");
}
/* [> printf("R:%d W:%d\n", rx_len,wlen); <] */
cbuf_read_alloc(&__this->microphone.usb_audio_record_cbuf, &rlen);
cbuf_read(&__this->microphone.usb_audio_record_cbuf, __this->microphone.usb_audio_record_buf2, rlen);
write_file_len = rlen;
os_taskq_post_msg("uac_record", 2, 0x01, rlen);
/* return; */
}
usb_h_ep_read_async(usb_id, ep, as_t->ep, NULL, 0, USB_ENDPOINT_XFER_ISOC, 1); //触发下一个接收中断
}
void audio_record_task(void *p)
{
log_info(">>> Enter usb audio record task");
struct usb_host_device *host_dev = (struct usb_host_device *)p;
const usb_dev usb_id = host_device2id(host_dev);
u8 *ptr = NULL;
u32 rlen = 0;
u32 ret = 0;
int msg[16];
struct audio_device_t *audio = NULL;
audio = __find_microphone_interface(host_dev);
struct audio_streaming_t *as_t = &audio->as[__this->microphone.Cur_AlternateSetting - 1];
/* u32 ep_max_packet_size = as_t->ep_max_packet_size; */
u32 ep_max_packet_size = EP_MAX_PACKET_SIZE;
log_info("ep max packet : %d\n", ep_max_packet_size);
u32 usb_audio_buf_size = ep_max_packet_size * 50;
u32 host_ep = as_t->host_ep;
u8 target_ep = as_t->ep;
//分配双缓存
// 一个缓存写卡的数据,一个用于usb接收
if (!__this->microphone.usb_audio_record_buf) {
__this->microphone.usb_audio_record_buf = zalloc(usb_audio_buf_size);
cbuf_init(&__this->microphone.usb_audio_record_cbuf, __this->microphone.usb_audio_record_buf, usb_audio_buf_size);
}
if (!__this->microphone.usb_audio_record_buf2) {
__this->microphone.usb_audio_record_buf2 = zalloc(usb_audio_buf_size);
}
usb_h_ep_read_async(usb_id, host_ep, target_ep, NULL, 0, USB_ENDPOINT_XFER_ISOC, 1); //启动iso
while (1) {
ret = os_taskq_pend(NULL, msg, ARRAY_SIZE(msg));
if (ret == OS_TASKQ) {
switch (msg[1]) {
case 0x01:
ptr = __this->microphone.usb_audio_record_buf2;
rlen = msg[2];
putchar('W');
__this->microphone.get_buf(ptr, rlen);
write_file_len = 0;
break;
}
}
}
}
void usb_audio_start_record(const usb_dev usb_id, u8 bit_reso, u32 sample_rate)
{
log_info(" usb audio record\n");
const struct usb_host_device *host_dev = host_id2device(usb_id);
struct audio_device_t *audio = NULL;
struct audio_streaming_t *as_t = NULL;
u8 *ep_buffer = ep_in_dma_buf;
u8 find_alternatesetting = 0;
audio = __find_microphone_interface(host_dev);
if (!audio) {
log_error("no find microphone interface!");
return;
}
for (u8 i = 0; i < ARRAY_SIZE(audio->as); i++) {
as_t = &audio->as[i];
if (as_t->bBitResolution == bit_reso) {
for (u8 j = 0; j < as_t->bSamFreqType; j++) {
if (as_t->tSamFreq[j] == sample_rate) {
find_alternatesetting = i + 1;
break;
}
}
}
}
if (!find_alternatesetting) {
log_e("can not find Alternatesetting,please check bit_reso and sample_rate\n");
return;
}
//端点分配
u32 host_ep = usb_get_ep_num(usb_id, USB_DIR_IN, USB_ENDPOINT_XFER_ISOC);
ASSERT(host_ep != -1, "ep not enough");
__this->usb_id = usb_id;
host_ep = host_ep | USB_DIR_IN;
__this->microphone.Cur_AlternateSetting = find_alternatesetting; //选择Alternatesetting
__this->microphone.sample_rate = sample_rate; //选择采样率
as_t = &audio->as[find_alternatesetting - 1];
u8 target_ep = as_t->ep;
u8 ep_interval = as_t->ep_Interval;
as_t->host_ep = host_ep;
usb_set_interface(host_dev, audio->interface_num, find_alternatesetting); //interface 1 Alternatesetting 1
usb_audio_sampling_frequency_control(host_dev, target_ep, sample_rate);//设置采样率
//设置音量
/* usb_audio_volume_control(host_dev, 6, 1, vol_convert(5)); */
/* usb_audio_volume_control(host_dev, 6, 2, vol_convert(5)); */
log_info("D2H ep: %x --> %x", target_ep, host_ep);
usb_h_set_ep_isr(host_dev, host_ep, usb_audio_rx_isr, host_dev);
usb_h_ep_config(usb_id, host_ep, USB_ENDPOINT_XFER_ISOC, 1, ep_interval, ep_buffer, sizeof(ep_in_dma_buf));
task_create(audio_record_task, host_dev, "uac_record");
__this->microphone.record_state = AUDIO_RECORD_START;
}
void usb_audio_stop_record(const usb_dev usb_id)
{
const struct usb_host_device *host_dev = host_id2device(usb_id);
usb_h_set_ep_isr(NULL, 0, NULL, NULL);
__this->microphone.get_buf(NULL, 0);
__this->microphone.Cur_AlternateSetting = 0;
__this->microphone.sample_rate = 0;
if (__this->microphone.usb_audio_record_buf) {
free(__this->microphone.usb_audio_record_buf);
__this->microphone.usb_audio_record_buf = NULL;
}
if (__this->microphone.usb_audio_record_buf2) {
free(__this->microphone.usb_audio_record_buf2);
__this->microphone.usb_audio_record_buf2 = NULL;
}
printf("\n[ debug ]--func=%s line=%d\n", __func__, __LINE__);
task_kill("uac_record");
printf("\n[ debug ]--func=%s line=%d\n", __func__, __LINE__);
}
void usb_audio_pause_record(void)
{
__this->microphone.record_state = AUDIO_RECORD_PAUSE;
}
void usb_audio_resume_record(void)
{
const struct usb_host_device *host_dev = host_id2device(__this->usb_id);
struct audio_device_t *audio = __find_microphone_interface(host_dev);
struct audio_streaming_t *as_t = &audio->as[__this->microphone.Cur_AlternateSetting - 1];
__this->microphone.record_state = AUDIO_RECORD_START;
usb_h_ep_read_async(__this->usb_id, as_t->host_ep, as_t->ep, NULL, 0, USB_ENDPOINT_XFER_ISOC, 1); //重新启动接收
}
void usb_audio_start_process(u32 id)
{
usb_audio_start_play(id, 1, 16, 48000); //开启headphone
usb_audio_start_record(id, 16, 48000); //开启microphone
}
void usb_audio_stop_process(u32 id)
{
usb_audio_stop_play(id);
usb_audio_stop_record(id);
}
static void usb_audio_event_handler(struct sys_event *event, void *priv)
{
const char *audio = NULL;
switch (event->type) {
case SYS_DEVICE_EVENT:
if ((u32)event->arg == DEVICE_EVENT_FROM_USB_HOST) {
if ((event->u.dev.event == DEVICE_EVENT_IN) ||
(event->u.dev.event == DEVICE_EVENT_CHANGE)) {
audio = (const char *)event->u.dev.value;
usb_audio_start_process(audio[5] - '0');
} else if (event->u.dev.event == DEVICE_EVENT_OUT) {
log_error("device out %x", event->u.dev.value);
usb_audio_stop_process(audio[5] - '0');
}
break;
}
}
}
void usb_host_audio_init(int (*put_buf)(void *ptr, u32 len), int *(*get_buf)(void *ptr, u32 len))
{
memset(__this, 0, sizeof(struct usb_audio_info));
__this->player.put_buf = put_buf;
__this->microphone.get_buf = get_buf;
register_sys_event_handler(SYS_DEVICE_EVENT, DEVICE_EVENT_FROM_USB_HOST, 2,
usb_audio_event_handler);
}
void usb_host_audio_exit()
{
unregister_sys_event_handler(usb_audio_event_handler);
__this->player.put_buf = NULL;
__this->microphone.get_buf = NULL;
}
#endif

View File

@ -1,56 +0,0 @@
#ifndef __AUDIO_H__
#define __AUDIO_H__
#include "system/task.h"
#include "device/device.h"
#include "usb_bulk_transfer.h"
#include "usb/host/usb_host.h"
#include "usb/device/uac_audio.h"
#define HEADPHONE_SUPPORTED 0x01
#define MICROPHONE_SUPPORTED 0x02
#define HEADSET_SUPPORTED 0x03
struct audio_streaming_t {
u8 bNumEndpoints;
u8 bFormatType; /** FORMAT_TYPE_1 */
u8 bNrChannels; /** physical channels in the stream */
u8 bSubframeSize;
u8 bBitResolution;
u8 bSamFreqType;
u32 tSamFreq[8];
u8 host_ep; //主机传输端点
u8 ep; //从机端点(由描述符中指定)
u8 ep_Interval;
u16 ep_max_packet_size;
};
struct audio_device_t {
u8 interface_num; //接口号
u8 subclass;
u8 support;
void *parent;
struct audio_streaming_t as[8];
};
int usb_audio_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf);
// API
int usb_audio_play_put_buf(void *ptr, u32 len);
int usb_audio_record_get_buf(void *ptr, u32 len);
//headphone api
void set_usb_audio_play_volume(u16 vol);
void usb_audio_start_play(const usb_dev usb_id, u8 channel, u8 bit_reso, u32 sample_rate); //指定播放数据的声道数,位数,采样率
void usb_audio_stop_play(const usb_dev usb_id);
void usb_audio_pause_play(void);
void usb_audio_resume_play(void);
//microphone api
void set_usb_audio_record_volume(u16 vol);
void usb_audio_start_record(const usb_dev usb_id, u8 bit_reso, u32 sample_rate); //指定录制数据的位数,采样率
void usb_audio_stop_record(const usb_dev usb_id);
void usb_audio_pause_record(void);
void usb_audio_resume_record(void);
#endif

View File

@ -1,111 +0,0 @@
#include "includes.h"
#include "asm/includes.h"
#include "app_config.h"
#include "system/timer.h"
#include "device/ioctl_cmds.h"
#include "device_drive.h"
#if TCFG_HOST_AUDIO_ENABLE
#include "usb/host/usb_host.h"
#include "usb_ctrl_transfer.h"
#include "usb_bulk_transfer.h"
#include "audio.h"
#include "usb_config.h"
#define LOG_TAG_CONST USB
#define LOG_TAG "[AUDIO]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#define TEST_FILE_ENABLE (0) //从sd卡读数据; 录制数据至sd卡
#if (TEST_FILE_ENABLE)
static FILE *play_file = NULL;
int usb_audio_play_put_buf(void *ptr, u32 len)
{
int ret = 0;
if (ptr == NULL && len == 0) {
//err
if (play_file) {
fclose(play_file);
play_file = NULL;
return 0;
}
}
if (!play_file) {
play_file = fopen("storage/sd0/C/raw.pcm", "r"); //单声道
/* play_file = fopen("storage/sd0/C/raw2.pcm", "r"); //双声道 */
if (!play_file) {
log_e("fopen play file faild!\n");
return -1;
}
}
//读sd卡数据到播放缓存中
ret = fread(play_file, ptr, len);
if (ret != len) {
log_e(" file read buf err %d\n", ret);
fclose(play_file);
play_file = NULL;
return -1;
}
return len;
}
static FILE *record_file = NULL;
int usb_audio_record_get_buf(void *ptr, u32 len)
{
#if (TEST_FILE_ENABLE)
int ret = 0;
static u32 cnt = 0;
if (!record_file) {
record_file = fopen("storage/sd0/C/record01.pcm", "w+");
cnt = 0;
if (!record_file) {
log_e("fopen play file faild!\n");
return -1;
}
}
putchar('W');
ret = fwrite(record_file, ptr, len);
if (ret != len) {
log_e(" file write buf err %d\n", ret);
fclose(record_file);
record_file = NULL;
return -1;
}
//test
if (cnt++ >= 800) {
cnt = 0;
log_info("stop record....\n");
fclose(record_file);
record_file = NULL;
}
#endif
return len;
}
#else
//将数据传入usb
//ptr:usb数据指针
//len:需要传入的数据长度
int usb_audio_play_put_buf(void *ptr, u32 len)
{
return len;
}
//从usb读取数据
//ptr:usb数据指针
//len:读取的数据长度
int usb_audio_record_get_buf(void *ptr, u32 len)
{
return len;
}
#endif
#endif

View File

@ -1,657 +0,0 @@
#include "includes.h"
#include "asm/includes.h"
#include "app_config.h"
#include "system/timer.h"
#include "device/ioctl_cmds.h"
#include "device_drive.h"
#if TCFG_HID_HOST_ENABLE
#include "usb/host/usb_host.h"
#include "usb_ctrl_transfer.h"
#include "usb_bulk_transfer.h"
#include "hid.h"
#include "usb_config.h"
#include "usb_hid_keys.h"
#define MAIN_ITEM 0
#define GLOBAL_ITEM 1
#define LOCAL_ITEM 2
#define LOG_TAG_CONST USB
#define LOG_TAG "[HID]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
struct hid_device_t hid_device[USB_MAX_HW_NUM][MAX_HOST_INTERFACE];
static int set_power(struct usb_host_device *host_dev, u32 value)
{
const usb_dev usb_id = host_device2id(host_dev);
memset(hid_device[usb_id], 0, sizeof(hid_device[usb_id]));
return DEV_ERR_NONE;
}
static int get_power(struct usb_host_device *host_dev, u32 value)
{
return DEV_ERR_NONE;
}
static const struct interface_ctrl hid_ctrl = {
.interface_class = USB_CLASS_HID,
.set_power = set_power,
.get_power = get_power,
.ioctl = NULL,
};
static const struct usb_interface_info _usb_if[USB_MAX_HW_NUM][MAX_HOST_INTERFACE] = {
{
{
.ctrl = (struct interface_ctrl *) &hid_ctrl,
.dev.hid = &hid_device[0][0],
},
{
.ctrl = (struct interface_ctrl *) &hid_ctrl,
.dev.hid = &hid_device[0][1],
},
{
.ctrl = (struct interface_ctrl *) &hid_ctrl,
.dev.hid = &hid_device[0][2],
},
{
.ctrl = (struct interface_ctrl *) &hid_ctrl,
.dev.hid = &hid_device[0][3],
},
},
#if USB_MAX_HW_NUM > 1
{
{
.ctrl = (struct interface_ctrl *) &hid_ctrl,
.dev.hid = &hid_device[1][0],
},
{
.ctrl = (struct interface_ctrl *) &hid_ctrl,
.dev.hid = &hid_device[1][1],
},
{
.ctrl = (struct interface_ctrl *) &hid_ctrl,
.dev.hid = &hid_device[1][2],
},
{
.ctrl = (struct interface_ctrl *) &hid_ctrl,
.dev.hid = &hid_device[1][3],
},
},
#endif
};
static u8 interval[USB_MAX_HW_NUM][16];
int usb_hid_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
{
struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)pBuf;
pBuf += sizeof(struct usb_interface_descriptor);
int len = 0;
const usb_dev usb_id = host_device2id(host_dev);
struct usb_endpoint_descriptor *endpoint;
pBuf += 9;//hid desc;
const struct usb_interface_info *usb_if = &_usb_if[usb_id][interface_num];
memset(usb_if->dev.p, 0, sizeof(struct hid_device_t));
host_dev->interface_info[interface_num] = usb_if;
usb_if->dev.hid->parent = host_dev;
log_info("hid eps %d %d %x %x", interface->bNumEndpoints, interface_num, usb_if, usb_if->dev.p);
log_info("parent %x hid @ interface %d usb_if %x hid %x",
host_dev, interface_num, usb_if, usb_if->dev.hid);
if ((interface->bInterfaceProtocol == 0x02) ||
(interface->bInterfaceProtocol == 0x01)) { //mouse & keyboard
usb_if->dev.hid->bNumEndpoints = interface->bNumEndpoints;
usb_if->dev.hid->report_list[0].usage = interface->bInterfaceProtocol;
for (int i = 0 ; i < interface->bNumEndpoints; i++) {
endpoint = (struct usb_endpoint_descriptor *)pBuf;
if (USB_DIR_IN & endpoint->bEndpointAddress) {
const u8 ep = endpoint->bEndpointAddress & 0x0f;
usb_if->dev.hid->ep_pair[i] = ep;
interval[usb_id][ep] = endpoint->bInterval;
log_info("interfacenum = %d,endpoint = %x interval = %x",
interface->bInterfaceNumber, endpoint->bEndpointAddress, endpoint->bInterval);
}
pBuf += endpoint->bLength;
}
} else {
log_info("vendor");
host_dev->interface_info[interface_num] = NULL; //???
for (int i = 0 ; i < interface->bNumEndpoints; i++) {
endpoint = (struct usb_endpoint_descriptor *)pBuf;
if (USB_DIR_IN & endpoint->bEndpointAddress) {
/* interface_endpoint[interface->bInterfaceNumber] = endpoint->bEndpointAddress & 0x0f; */
log_info("interfacenum = %d,endpoint = %x interval = %x",
interface->bInterfaceNumber, endpoint->bEndpointAddress, endpoint->bInterval);
}
pBuf += endpoint->bLength;
}
return sizeof(struct usb_interface_descriptor);
}
return pBuf - (u8 *)interface;
}
static u32 _hid_report_parse(struct hid_device_t *hid, const u8 *report, u32 len)
{
hid->report_count = 0;
struct report_info_t null_rpt;
struct report_info_t *const rpt = &null_rpt;
memset(rpt, 0, sizeof(*rpt));
unsigned char ops;
int index = 0;
u8 report_size = 0;
u8 report_count = 0;
u8 cur_ops_is_report_size_count = 0;
u8 old_ops_is_report_size_count = 0;
s8 cur_section_bit = 0;
u8 input_bit_index = 0;
u8 total_bits = 0;
u8 output_bit_index = 0;
u8 cur_usage = 0;
u32 undef_type = 0;
u8 undef_usage = 0;
u8 collection_deep = 0;
while (index < len) {
ops = (char)report[index++];
char bSize = ops & 0x03;
bSize = bSize == 3 ? 4 : bSize; // size is 4 when bSize is 3
char bType = (ops >> 2) & 0x03;
char bTag = (ops >> 4) & 0x0F;
cur_ops_is_report_size_count = 0;
char bSizeActual = 0;
int itemVal = 0;
for (int j = 0; j < bSize; j++) {
if (index + j < len) {
itemVal += report[index + j] << (8 * j);
bSizeActual++;
}
}
if (undef_type) {
undef_type ++;
if (bTag == 0x0A) {
undef_usage ++;
} else if (bTag == 0x0C) {
undef_usage --;
}
if (undef_usage == 0 && undef_type > 2) {
undef_type = 0;
}
index += bSize;
continue;
}
if (undef_type) {
index += bSize;
continue;
}
if (itemVal == 0xffb5) {
undef_type = 1;
index += bSize;
continue;
} else {
undef_type = 0;
}
if (bType == MAIN_ITEM) {
if (old_ops_is_report_size_count) {
cur_section_bit += report_size * report_count;
}
if (bTag == 0x08) {
/* log_info("input %X", itemVal); */
/* log_info("\tusage %x", cur_usage); */
/* log_info("\t\tcur_section_bit %d", cur_section_bit); */
if (rpt->usage == 0x02) { //mouse
if (cur_usage == 1) {
if (rpt->btn_start_bit == 0) {
rpt->btn_start_bit = total_bits ;
}
rpt->btn_width += cur_section_bit ;
/* log_info("btn_width %d-%d", rpt->btn_start_bit, rpt->btn_width); */
} else if ((cur_usage == 0x30) || (cur_usage == 0x31)) {
if (rpt->xy_start_bit == 0) {
rpt->xy_start_bit = total_bits;
}
rpt->xy_width = cur_section_bit;
/* log_info("xy_width %d-%d", rpt->xy_start_bit, rpt->xy_width); */
} else if (cur_usage == 0x38) {
if (rpt->wheel_start_bit == 0) {
rpt->wheel_start_bit = total_bits;
}
if (rpt->xy_width || cur_section_bit < 24) {
rpt->wheel_width = cur_section_bit;
/* log_info("wheel_width %d-%d", rpt->wheel_start_bit, rpt->wheel_width); */
} else {
rpt->wheel_width = rpt->xy_width = cur_section_bit / 3;
rpt->xy_start_bit = total_bits;
rpt->wheel_start_bit = rpt->xy_start_bit + rpt->xy_width * 2;
/* log_info("wheel_width %d-%d", rpt->wheel_start_bit, rpt->wheel_width); */
/* log_info("xy_width %d-%d", rpt->xy_start_bit, rpt->xy_width); */
}
} else if (cur_usage == 0xb8) {
rpt->wheel_width = rpt->xy_width = cur_section_bit / 4;
rpt->xy_start_bit = total_bits;
rpt->wheel_start_bit = rpt->xy_start_bit + rpt->xy_width * 2;
}
}
total_bits += cur_section_bit;
/* input_bit[input_bit_index++] = cur_section_bit; */
cur_section_bit = -1;
} else if (bTag == 0x09) {
/* log_info("OUTPUT %X", itemVal); */
/* log_info("\tusage %x", cur_usage); */
/* log_info("\t\tcur_section_bit %d", cur_section_bit); */
/* output_bit[output_bit_index++] = cur_section_bit; */
cur_section_bit = -1;
} else if (bTag == 0x0B) {
/* log_info("Feature %X", itemVal); */
/* log_info("\tusage %x", cur_usage); */
/* log_info("\t\tcur_section_bit %d", cur_section_bit); */
/* output_bit[output_bit_index++] = cur_section_bit; */
cur_section_bit = -1;
} else if (bTag == 0x0A) {
collection_deep ++ ;
log_info("Collection %d %x", collection_deep, rpt->usage);
} else if (bTag == 0x0C) {
collection_deep --;
log_info("End Collection %d %x", collection_deep, rpt->usage);
if (collection_deep == 0) {
if (rpt->usage == 0x02 ||
rpt->usage == 0x06 ||
rpt->usage == 0x07) {
memcpy(&hid->report_list[hid->report_count], rpt, sizeof(*rpt));
memset(rpt, 0, sizeof(*rpt));
hid->report_count ++;
}
}
if (index < len) {
continue;
}
} else {
log_info("MAIN_ITEM Unknown btag :%x", bTag);
return 1;
}
} else if (bType == GLOBAL_ITEM) {
/* log_info("GLOBAL_ITEM"); */
if (bTag == 0x00) {
/* log_info("Usage Page %x", itemVal); */
if (rpt->usage == 0x06) {
if (itemVal == 0x07) {
rpt->usage = 0x07;
log_info("re set type %x", 0x07);
}
}
if (itemVal == 0x02) {
rpt->usage = 0x02;
log_info("re set type %x", 0x02);
}
} else if (bTag == 0x01) {
//log_info("Logical Minimum %x", itemVal);
} else if (bTag == 0x02) {
//log_info("Logical Maximum %x", itemVal);
} else if (bTag == 0x03) {
/* log_info("Physical Minimum %x", itemVal); */
} else if (bTag == 0x04) {
/* log_info("Physical Maximum %x", itemVal); */
} else if (bTag == 0x05) {
/* log_info("Unit Exponent %x", itemVal); */
} else if (bTag == 0x06) {
/* log_info("Unit %x", itemVal); */
} else if (bTag == 0x07) {
/* log_info("Report Size %x", itemVal); */
report_size = itemVal;
cur_ops_is_report_size_count = 1;
} else if (bTag == 0x08) {
log_info("Report ID %x", itemVal, rpt->usage);
rpt->report_id = itemVal;
} else if (bTag == 0x09) {
/* log_info("Report Count %x", itemVal); */
report_count = itemVal;
cur_ops_is_report_size_count = 1;
} else if (bTag == 0x0A) {
/* log_info("Push %x", bSizeActual); */
} else if (bTag == 0x0B) {
/* log_info("Pop %x", bSizeActual); */
} else {
log_info("GLOBAL_ITEM Unknown btag :%x", bTag);
return 2;
}
} else if (bType == LOCAL_ITEM) {
/* log_info("LOCAL_ITEM"); */
if (bTag == 0x00) {
if (rpt->usage == 0) {
rpt->usage = itemVal;
log_info("set type %x", rpt->usage);
}
if (itemVal == 0x30) { //X
} else if (itemVal == 0x31) { //y
} else if (itemVal == 0x38) { //wheel
} else {
}
/* log_info("\t change usage %x -> %x", cur_usage, itemVal); */
cur_usage = itemVal;
if (!collection_deep) {
if (itemVal == 0x06 || itemVal == 0x07 || itemVal == 0x02) {
//仅限键盘和鼠标
rpt->usage = itemVal;
log_info("set typee %x", rpt->usage);
}
}
/* type = itemVal; */
} else if (bTag == 0x01) {
// log_info("Usage Minimum %x", itemVal);
} else if (bTag == 0x02) {
// log_info("Usage Maximum %x", itemVal);
} else if (bTag == 0x03) {
/* log_info("Designator Index %x", itemVal); */
} else if (bTag == 0x04) {
/* log_info("Designator Minimum %x", itemVal); */
} else if (bTag == 0x05) {
/* log_info("Designator Maximum %x", itemVal); */
} else if (bTag == 0x07) {
/* log_info("String Index %x", itemVal); */
} else if (bTag == 0x08) {
/* log_info("String Minimum %x", itemVal); */
} else if (bTag == 0x09) {
/* log_info("String Maximum %x", itemVal); */
} else if (bTag == 0x0A) {
/* log_info("Delimiter %x", itemVal); */
} else {
log_info("LOCAL_ITEM Unknown btag :%x", bTag);
return 3;
}
} else {
log_info("OTHER Unknown btag :%x", bTag);
return 4;
}
if (!cur_ops_is_report_size_count && old_ops_is_report_size_count) {
if (cur_section_bit != -1) {
cur_section_bit += report_size * report_count;
} else {
cur_section_bit = 0;
}
}
if (cur_section_bit == -1) {
cur_section_bit = 0;
}
old_ops_is_report_size_count = cur_ops_is_report_size_count;
index += bSize;
}
return 0;
}
static u32 hid_report_parse(struct hid_device_t *hid, const u8 *report, u32 len)
{
u8 type = _hid_report_parse(hid, report, len);
for (int i = 0; i < hid->report_count; i++) {
struct report_info_t *rpt = &hid->report_list[i];
if (rpt->usage == 0x02) {
if (rpt->report_id == 0) {
rpt->report_id = 0xff;
}
rpt->btn_start_bit /= 8;
rpt->btn_width /= 8;
rpt->xy_start_bit /= 8;
rpt->xy_width /= 8;
rpt->wheel_start_bit /= 8;
rpt->wheel_width /= 8;
log_info("mouse report_id %d",
rpt->report_id);
log_info("btn_width %d-%d",
rpt->btn_start_bit, rpt->btn_width);
log_info("xy_width %d-%d",
rpt->xy_start_bit, rpt->xy_width);
log_info("wheel_width %d-%d",
rpt->wheel_start_bit, rpt->wheel_width);
if (rpt->btn_width != 2) {
rpt->btn_width = 1;
}
log_info("btn_width %d-%d",
rpt->btn_start_bit, rpt->btn_width);
} else if (rpt->usage == 6 || rpt->usage == 7) {
if (rpt->report_id == 0) {
rpt->report_id = 0xff;
}
log_info("keyboard report_id %d", rpt->report_id);
} else {
log_info("unknown usage %d", rpt->usage);
}
}
return 0;
}
void mouse_route(const struct mouse_data_t *p);
/* __attribute__((weak)) void mouse_route(const struct mouse_data_t *p) */
/* { */
/* log_info("btn: %x x-y %d %d wheel %d ac_pan %d", */
/* p->btn, p->x, p->y, p->wheel, p->ac_pan); */
/* } */
static void hid_convert_mouse(const struct report_info_t *mouse, const u8 *buffer)
{
struct mouse_data_t mouse_data;
memset(&mouse_data, 0, sizeof(mouse_data));
if (mouse->report_id != 0xff) {
if (mouse->report_id != buffer[0]) {
log_error("report_id = %x buffer[0] = %x", mouse->report_id, buffer[0]);
return;
}
buffer++;
}
const u8 *ptr;
ptr = &buffer[mouse->btn_start_bit];
if (mouse->btn_width == 2) {
mouse_data.btn = ptr[0] | (ptr[1] << 8);
} else {
mouse_data.btn = ptr[0] ;
}
s16 tmp;
ptr = &buffer[mouse->xy_start_bit];
if (mouse->xy_width == 1 || mouse->xy_width == 2) {
mouse_data.x = (char)ptr[0];
mouse_data.y = (char)ptr[1];
} else if (mouse->xy_width == 4) {
mouse_data.x = ptr[0] | (ptr[1] << 8);
ptr += 2;
mouse_data.y = ptr[0] | (ptr[1] << 8);
} else if (mouse->xy_width == 3) {
tmp = (ptr[1] & 0xf) << 12 | ptr[0] << 4;
tmp = tmp >> 4;
mouse_data.x = tmp;
tmp = (ptr[2] << 8) | ((ptr[1] >> 4) << 4);
tmp = tmp >> 4;
mouse_data.y = tmp;
} else {
log_error("error mouse xy_width %d", mouse->xy_width);
}
ptr = &buffer[mouse->wheel_start_bit];
if (mouse->wheel_width == 1) {
mouse_data.wheel = (char)ptr[0];
} else {
mouse_data.wheel = ptr[0] | (ptr[1] << 8);
}
mouse_route(&mouse_data);
}
__attribute__((weak)) void keyboard_route(const u8 *p)
{
log_info("keyboard_buffer:");
printf_buf(p, 12);
}
void hid_convert_krbd(const struct report_info_t *kbd, u8 *buffer)
{
#if 0
u8 keyboard_buffer[12];
memset(keyboard_buffer, 0, sizeof(keyboard_buffer));
if (kbd->report_id != 0xff) {
if (kbd->report_id != buffer[0]) {
log_error("report_id = %x buffer[0] = %x", kbd->report_id, buffer[0]);
return;
}
buffer++;
}
u8 idx = 0;
u8 index = 0;
int i = 0;
for (i = 0; i < 8; i++) {
if (buffer[0] & BIT(i)) {
keyboard_buffer[idx++] = 0xe0 + i;
}
}
if (buffer[1] == 0) {
buffer += 2;
}
index = idx;
for (; idx < 12; idx++) {
if (*buffer) {
keyboard_buffer[index] = *buffer;
index++;
}
buffer ++;
}
keyboard_route(keyboard_buffer);
#else
if (kbd->report_id != 0xff) {
if (kbd->report_id != buffer[0]) {
log_error("report_id = %x buffer[0] = %x", kbd->report_id, buffer[0]);
return;
}
buffer++;
}
u8 keyboard_buffer[8];
memset(keyboard_buffer, 0, sizeof(keyboard_buffer));
keyboard_buffer[0] = *buffer;
buffer ++;
if (*buffer == 0) {
buffer ++;
}
keyboard_buffer[1] = 0;
/* memcpy(&keyboard_buffer[2], buffer, 6); */
u8 pos = 2;
for (int i = pos; i < 8; i++) {
if (*buffer) {
keyboard_buffer[pos] = *buffer;
pos++;
}
buffer++;
}
keyboard_route(keyboard_buffer);
#endif
}
static void hid_route(const struct hid_device_t *hid, const u8 *buffer)
{
for (int i = 0; i < hid->report_count; i++) {
if (hid->report_list[i].usage == 0x02) {
hid_convert_mouse(&hid->report_list[i], buffer);
} else if ((hid->report_list[i].usage == 0x06) ||
(hid->report_list[i].usage == 0x07)) {
hid_convert_krbd(&hid->report_list[i], buffer);
} else {
r_printf("usage %x", hid->report_list[i].usage);
}
}
}
static void hid_isr(struct usb_interface_info *usb_if, u32 ep)
{
u8 buffer[64] = {0};
struct usb_host_device *host_dev = usb_if->dev.hid->parent;
usb_dev usb_id = host_device2id(host_dev);
u32 target_ep = usb_if->dev.hid->ep_pair[ep];
u32 rx_len = usb_h_ep_read_async(usb_id, ep, target_ep, buffer, 64, USB_ENDPOINT_XFER_INT, 0);
if (rx_len) {
hid_route(usb_if->dev.hid, buffer);
}
/* printf_buf(buffer, rx_len); */
usb_h_ep_read_async(usb_id, ep, target_ep, buffer, 8, USB_ENDPOINT_XFER_INT, 1);
}
void hid_process(u32 id)
{
struct usb_host_device *host_dev = host_id2device(id);
u8 report[256 + 2];
u8 ep_pair[4];
for (u8 i = 0; i < MAX_HOST_INTERFACE; i++) {
struct usb_interface_info *usb_if = host_dev->interface_info[i];
log_info("parent %x hid @ interface %d usb_if %x hid %x",
host_dev, i, usb_if, usb_if ? usb_if->dev.hid : 0);
if (usb_if &&
(usb_if->ctrl->interface_class == USB_CLASS_HID)) {
hid_set_idle(host_dev, i);
memset(report, 0, sizeof(report));
hid_get_report(host_dev, report, i, 0xff);
printf_buf(report, 256);
hid_report_parse(usb_if->dev.hid, report, 256);
memcpy(ep_pair, usb_if->dev.hid->ep_pair, 4);
if (usb_if->dev.hid->report_count == 0) {
continue;
}
for (int i = 0; i < usb_if->dev.hid->bNumEndpoints; i++) {
u32 host_ep = usb_get_ep_num(id, USB_DIR_IN, USB_ENDPOINT_XFER_INT);
ASSERT(host_ep != -1, "ep not enough");
u32 target_ep = ep_pair[i];
usb_if->dev.hid->ep_pair[host_ep] = target_ep;
log_info("D2H ep: %x --> %x interval %d",
target_ep, host_ep, interval[id][target_ep]);
usb_h_set_ep_isr(host_dev, host_ep | USB_DIR_IN, hid_isr, usb_if);
u8 *ep_buffer = usb_h_get_ep_buffer(id, host_ep | USB_DIR_OUT);
usb_h_ep_config(id, host_ep | USB_DIR_IN, USB_ENDPOINT_XFER_INT, 1,
interval[id][target_ep], ep_buffer, 64);
int r = usb_h_ep_read_async(id, host_ep, target_ep, NULL, 0, USB_ENDPOINT_XFER_INT, 1);
}
} else {
if (usb_if) {
log_error("error hid class %x", usb_if->ctrl->interface_class);
}
}
}
}
#endif

View File

@ -1,83 +0,0 @@
/**@file hid.h
* @brief hid驱动头文件做主机
* @details 结构体声明,功能函数声明
* @author jieli
* @date 2021-9-1
* @version V1.0
* @copyright Copyright(c)2010-2021 珠海市杰理科技股份有限公司
*********************************************************
* @attention
* 硬件平台AC632N
* SDK版本AC632N_V1.0.0_SDK
* @修改日志:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-9-1 <td>1.0 <td>jieli <td>创建初始版本
* </table>
*
*********************************************************
*/
#ifndef __HID_H__
#define __HID_H__
#include "system/task.h"
#include "device/device.h"
#include "usb/scsi.h"
#include "usb_bulk_transfer.h"
#include "usb/host/usb_host.h"
/**@struct report_info_t
* @brief 报告描述符包含的信息结构体\n
* 自定义一些私有数据信息存储在该结构体中
*/
struct report_info_t {
u8 report_id; ///<id号不同hid设备对应不同id
u8 usage; ///<描述该数据信息的用途
u8 btn_start_bit; ///<鼠标按键数据起始位
u8 btn_width; ///<鼠标按键数据宽度
u8 xy_start_bit; ///<鼠标平移数据起始位
u8 xy_width; ///<鼠标平移数据宽度
u8 wheel_start_bit; ///<鼠标滚轮数据起始位
u8 wheel_width; ///<鼠标滚轮数据宽度
};
#define MAX_REPORT_COUNT 4
/**@struct hid_device_t
* @brief 报告描述符包含的信息结构体\n
* 自定义一些私有数据信息存储在该结构体中
*/
struct hid_device_t {
void *parent; ///<定义的parent指针指向该hid的所属设备
u8 ep_pair[4]; ///<端点对数组,数组下标存放主机端点,对应的元素存放目标端点
u8 report_count; ///<报告描述符中item计数器
u8 bNumEndpoints; ///<端点数量
struct report_info_t report_list[MAX_REPORT_COUNT]; ///<报告描述符结构体
};
/**@brief USB hid设备解析
* @param[in] host_dev usb_host_device定义的结构体指针
* @param[in] interface_num 接口号
* @param[in] *pBuf 数据指针,指向数据存放的地址
* @return 接口描述符长度
* @par 示例:
* @code
* usb_hid_parser(host_dev,interface_num,pBuf);
* @encode
*/
int usb_hid_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf);
/**@brief USB hid设备信息处理
* @param[in] id usb设备id号
* @return 无
* @par 示例:
* @code
* hid_process(id);
* @encode
*/
void hid_process(u32 id);
#endif /*HID_H*/

View File

@ -1,319 +0,0 @@
/**
* @file usb_bulk_transfer.c
* @brief bulk transfer driver
* @author chenrixin@zh-jieli.com
* @version 1.00
* @date 2017-02-09
*/
#include <string.h>
#include "jiffies.h"
#include "usb_config.h"
#include "usb_bulk_transfer.h"
#include "usb_ctrl_transfer.h"
#include "usb_storage.h"
#include "usb/host/usb_host.h"
#include "usb/usb_phy.h"
#include "app_config.h"
#include "device_drive.h"
#if USB_HOST_ENABLE
#define LOG_TAG_CONST USB
#define LOG_TAG "[USB]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
struct usb_request_block {
void *ptr;
u32 len;
u32 target_ep;
u16 rxmap;
u16 txmap;
u32 msg;
u32 async_mode;
};
static struct usb_request_block urb;
u8 get_async_mode(void)
{
u8 mode = BULK_ASYNC_MODE_EXIT ;
#if UDISK_READ_512_ASYNC_ENABLE
local_irq_disable();
mode = urb.async_mode;
local_irq_enable();
#endif
return mode;
}
void set_async_mode(u8 mode)
{
#if UDISK_READ_512_ASYNC_ENABLE
local_irq_disable();
urb.async_mode = mode;
local_irq_enable();
#endif
}
static void usb_bulk_rx_isr(struct usb_host_device *host_dev, u32 ep)
{
usb_dev usb_id = host_device2id(host_dev);
int l = min(urb.len, urb.rxmap);
l = usb_h_ep_read_async(usb_id, ep, urb.target_ep, urb.ptr, l, USB_ENDPOINT_XFER_BULK, 0);
/* g_printf("%s() %d %d", __func__, l, urb.len); */
if (l > 0) {
urb.len -= l;
if (urb.ptr) {
urb.ptr += l;
}
urb.msg = 0;
} else {
urb.msg = l;
urb.len = 0;
}
if (urb.len == 0) {
u32 async_mode = get_async_mode();
if (async_mode == BULK_ASYNC_MODE_EXIT) {
usb_sem_post(host_dev);
} else if (async_mode == BULK_ASYNC_MODE_SEM_PEND) {
if (urb.msg == 0) {
usb_sem_post(host_dev);
} else {
r_printf("usb async error");
}
}
} else {
usb_h_ep_read_async(usb_id, ep, urb.target_ep, urb.ptr, urb.len, USB_ENDPOINT_XFER_BULK, 1);
}
}
s32 usb_bulk_only_receive_async(struct device *device, u8 host_ep, u16 rxmaxp, u8 target_ep, u8 *pBuf, u32 len)
{
struct usb_host_device *host_dev = device_to_usbdev(device);
const usb_dev usb_id = host_device2id(host_dev);
u8 devnum = host_dev->private_data.devnum;
urb.ptr = pBuf;
urb.len = len;
urb.target_ep = target_ep;
#ifdef CONFIG_USB_SUPPORT_MRX_TX
urb.rxmap = 1 * 1024;
#else
#if defined(FUSB_MODE) && FUSB_MODE == 0
urb.rxmap = rxmaxp;
#else
urb.rxmap = 0x40;
#endif
#endif
urb.msg = -DEV_ERR_OFFLINE;
usb_h_set_ep_isr(host_dev, host_ep | USB_DIR_IN, usb_bulk_rx_isr, host_dev);
usb_set_intr_rxe(usb_id, host_ep);
#ifdef USB_HW_20
usb_write_rxfuncaddr(usb_id, host_ep, devnum);
#endif
int ret = usb_h_ep_read_async(usb_id, host_ep, target_ep, urb.ptr, len, USB_ENDPOINT_XFER_BULK, 1);
if (ret < 0) {
return ret;
}
ret = usb_sem_pend(host_dev, 300);
usb_clr_intr_rxe(usb_id, host_ep);
usb_h_set_ep_isr(host_dev, host_ep | USB_DIR_IN, NULL, host_dev);
if (ret) {
return -DEV_ERR_TIMEOUT;
}
return urb.msg ? urb.msg : len;
}
/**
* @brief usb_bulk_receive_async_no_wait 启动USB Bulk 异步预读
* 不用等信号量,启动传输后返回
* @param device 设备句柄
* @param pBuf 读buffer缓冲区芯片所有memory都可以
* @param len 需要预读的长度
*
* @return 负数表示失败
*/
s32 usb_bulk_receive_async_no_wait(struct device *device, u8 host_ep, u16 rxmaxp, u8 target_ep, u8 *pBuf, u32 len)
{
struct usb_host_device *host_dev = device_to_usbdev(device);
const usb_dev usb_id = host_device2id(host_dev);
u8 devnum = host_dev->private_data.devnum;
set_async_mode(BULK_ASYNC_MODE_SEM_PEND);
urb.ptr = pBuf;
urb.len = len;
urb.target_ep = target_ep;
#ifdef CONFIG_USB_SUPPORT_MRX_TX
urb.rxmap = 1 * 1024;
#else
#if defined(FUSB_MODE) && FUSB_MODE == 0
urb.rxmap = rxmaxp;
#else
urb.rxmap = 0x40;
#endif
#endif
urb.msg = -DEV_ERR_OFFLINE;
usb_h_set_ep_isr(host_dev, host_ep | USB_DIR_IN, usb_bulk_rx_isr, host_dev);
usb_set_intr_rxe(usb_id, host_ep);
#ifdef USB_HW_20
usb_write_rxfuncaddr(usb_id, host_ep, devnum);
#endif
int ret = usb_h_ep_read_async(usb_id, host_ep, target_ep, urb.ptr, len, USB_ENDPOINT_XFER_BULK, 1);
if (ret < 0) {
if (ret == -DEV_ERR_RXSTALL) {
ret = usb_clear_feature(host_dev, target_ep | USB_DIR_IN);
if (ret == 0) {
return -DEV_ERR_RXSTALL;
}
}
return ret;
}
return len;
}
static s32 _usb_bulk_only_receive(struct device *device, u8 host_ep, u16 rxmaxp, u8 target_ep, u8 *pBuf, u32 len)
{
#if 0
struct usb_host_device *host_dev = device_to_usbdev(device);
const usb_dev usb_id = host_device2id(host_dev);
return usb_h_bulk_read(usb_id, host_ep, rxmaxp, target_ep, pBuf, len);
#else
return usb_bulk_only_receive_async(device, host_ep, rxmaxp, target_ep, pBuf, len);
#endif
}
s32 usb_bulk_only_receive(struct device *device, u8 host_ep, u16 rxmaxp, u8 target_ep, u8 *pBuf, u32 len)
{
struct usb_host_device *host_dev = device_to_usbdev(device);
int ret = _usb_bulk_only_receive(device, host_ep, rxmaxp, target_ep, pBuf, len);
if (ret == -DEV_ERR_RXSTALL) {
ret = usb_clear_feature(host_dev, target_ep | USB_DIR_IN);
if (ret == 0) {
return -DEV_ERR_RXSTALL;
}
}
return ret;
}
static void usb_bulk_tx_isr(struct usb_host_device *host_dev, u32 ep)
{
usb_dev usb_id = host_device2id(host_dev);
int l = min(urb.len, urb.txmap);
l = usb_h_ep_write_async(usb_id, ep, urb.txmap, urb.target_ep, urb.ptr, l, USB_ENDPOINT_XFER_BULK, 0);
if (l > 0) {
urb.len -= l;
urb.ptr += l;
urb.msg = 0;
} else {
urb.msg = l;
urb.len = 0;
}
if (urb.len == 0) {
if (urb.msg || l == 0) {
usb_sem_post(host_dev);
}
}
}
s32 usb_bulk_only_send_async(struct device *device, u8 host_ep, u16 txmaxp, u8 target_ep, const u8 *pBuf, u32 len)
{
struct usb_host_device *host_dev = device_to_usbdev(device);
const usb_dev usb_id = host_device2id(host_dev);
u8 devnum = host_dev->private_data.devnum;
urb.target_ep = target_ep;
#ifdef CONFIG_USB_SUPPORT_MRX_TX
urb.txmap = 8 * 1024;
#else
#if defined(FUSB_MODE) && FUSB_MODE == 0
urb.txmap = rxmaxp;
#else
urb.txmap = 0x40;
#endif
#endif
urb.msg = -DEV_ERR_OFFLINE;
urb.len = len - min(len, urb.txmap);
urb.ptr = (u8 *)pBuf + min(len, urb.txmap);
usb_h_set_ep_isr(host_dev, host_ep, usb_bulk_tx_isr, host_dev);
usb_set_intr_txe(usb_id, host_ep);
#ifdef USB_HW_20
usb_write_txfuncaddr(usb_id, host_ep, devnum);
#endif
int ret = usb_h_ep_write_async(usb_id, host_ep, txmaxp, target_ep, pBuf, min(len, urb.txmap), USB_ENDPOINT_XFER_BULK, 1);
if (ret < 0) {
return ret;
}
ret = usb_sem_pend(host_dev, 250);
usb_clr_intr_txe(usb_id, host_ep);
usb_h_set_ep_isr(host_dev, host_ep, NULL, host_dev);
if (ret) {
r_printf("ret %d", ret);
return -DEV_ERR_TIMEOUT;
}
/* g_printf("%s() %d %d", __func__, urb.len, urb.msg); */
return urb.msg ? urb.msg : len;
}
/**
* @brief usb_bulk_only_send
*
* @param device
* @param host_ep 主机的端点号
* @param target_ep 目标设备的端点号
* @param pBuf
* @param len
*
* @return 负数失败
* 正数发送的字节数
*/
static s32 _usb_bulk_only_send(struct device *device, u8 host_ep, u16 txmaxp, u8 target_ep, const u8 *pBuf, u32 len)
{
#if 0
struct usb_host_device *host_dev = device_to_usbdev(device);
const usb_dev usb_id = host_device2id(host_dev);
return usb_h_bulk_write(usb_id, host_ep, txmaxp, target_ep, pBuf, len);
#elif 0
if (len < 512) {
struct usb_host_device *host_dev = device_to_usbdev(device);
const usb_dev usb_id = host_device2id(host_dev);
return usb_h_bulk_write(usb_id, host_ep, txmaxp, target_ep, pBuf, len);
} else {
return usb_bulk_only_send_async(device, host_ep, txmaxp, target_ep, pBuf, len);
}
#else
return usb_bulk_only_send_async(device, host_ep, txmaxp, target_ep, pBuf, len);
#endif
}
s32 usb_bulk_only_send(struct device *device, u8 host_ep, u16 txmaxp, u8 target_ep, const u8 *pBuf, u32 len)
{
struct usb_host_device *host_dev = device_to_usbdev(device);
int ret = _usb_bulk_only_send(device, host_ep, txmaxp, target_ep, pBuf, len);
if (ret == -DEV_ERR_TXSTALL) {
ret = usb_clear_feature(host_dev, target_ep);
if (ret == 0) {
return -DEV_ERR_TXSTALL;
}
}
return ret;
}
#endif

View File

@ -1,120 +0,0 @@
/**@file usb_bulk_transfer.h
* @brief usb_bulk_transfer批量传输头文件
* @details 功能函数声明
* @author jieli
* @date 2021-8-1
* @version V1.0
* @copyright Copyright(c)2010-2021 珠海市杰理科技股份有限公司
*********************************************************
* @attention
* 硬件平台AC695N
* SDK版本AC695N_V1.0.0_SDK
* @修改日志:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-8-1 <td>1.0 <td>jieli <td>创建初始版本
* </table>
*
*********************************************************
*/
#ifndef __USB_BULK_TRANSFER_H__
#define __USB_BULK_TRANSFER_H__
#include "typedef.h"
#include "device/device.h"
/**@brief 批量传输只读取(异步模式)
* @param[in] device定义的结构体指针
* @param[in] host_ep 主机端点号
* @param[in] rxmaxp 接收端点最大包长
* @param[in] target_ep 目标端点号
* @param[in] *pBuf BUFFER指针
* @param[in] len 数据长度
* @return
* @par 示例:
* @code
* usb_bulk_only_receive_async(device, host_ep, rxmaxp, target_ep, pBuf, len);
* @encode
*/
s32 usb_bulk_only_receive_async(struct device *device, u8 host_ep, u16 rxmaxp, u8 target_ep, u8 *pBuf, u32 len);
/**@brief 批量传输只读取(普通模式)
* @param[in] device定义的结构体指针
* @param[in] host_ep 主机端点号
* @param[in] rxmaxp 接收端点最大包长
* @param[in] ep 目标端点号
* @param[in] *pBuf BUFFER指针
* @param[in] len 数据长度
* @return
* @par 示例:
* @code
* usb_bulk_only_receive(device, host_ep, rxmaxp, ep, pBuf, len);
* @encode
*/
s32 usb_bulk_only_receive(struct device *device, u8 host_ep, u16 rxmaxp, u8 ep, u8 *pBuf, u32 len);
/**@brief 批量传输只发送(异步模式)
* @param[in] device定义的结构体指针
* @param[in] host_ep 主机端点号
* @param[in] txmaxp 发送端点最大包长
* @param[in] target_ep 目标端点号
* @param[in] *pBuf BUFFER指针
* @param[in] len 数据长度
* @return
* @par 示例:
* @code
* usb_bulk_only_send_async(device, host_ep, txmaxp, target_ep, pBuf, len);
* @encode
*/
s32 usb_bulk_only_send_async(struct device *device, u8 host_ep, u16 txmaxp, u8 target_ep, const u8 *pBuf, u32 len);
/**@brief 批量传输只发送(普通模式)
* @param[in] device定义的结构体指针
* @param[in] ep 主机端点号
* @param[in] txmaxp 发送端点最大包长
* @param[in] ep 目标端点号
* @param[in] *pBuf BUFFER指针
* @param[in] len 数据长度
* @return
* @par 示例:
* @code
* usb_bulk_only_send(device, host_ep, txmaxp, ep, pBuf, len);
* @encode
*/
s32 usb_bulk_only_send(struct device *device, u8 host_ep, u16 txmaxp, u8 ep, const u8 *pBuf, u32 len);
/**@brief 获取异步模式当前状态
* @param[in] 空
* @return 当前状态
* @par 示例:
* @code
* get_async_mode();
* @encode
*/
u8 get_async_mode(void);
/**@brief 设置异步模式
* @param[in] mode 需要设置的模式
* @return 空
* @par 示例:
* @code
* set_async_mode(BULK_ASYNC_MODE_EXIT);退出异步模式
* @encode
*/
void set_async_mode(u8 mode);
/**@brief 批量传输异步模式读取并且不等待
* @param[in] device定义的结构体指针
* @param[in] ep 主机端点号
* @param[in] rxmaxp 发送端点最大包长
* @param[in] target_ep 目标端点号
* @param[in] *pBuf BUFFER指针
* @param[in] len 数据长度
* @return
* @par 示例:
* @code
* usb_bulk_only_send(device, host_ep, rxmaxp, ep, pBuf, len);
* @encode
*/
s32 usb_bulk_receive_async_no_wait(struct device *device, u8 host_ep, u16 rxmaxp, u8 target_ep, u8 *pBuf, u32 len);
#endif

View File

@ -1,637 +0,0 @@
/**
* @file usb_ctrl_transfer.c
* @brief usb 控制传输接口
* @author chenrixin@zh-jieli.com
* @version 1.00
* @date 2017-02-09
*/
#include "usb/host/usb_host.h"
#include "usb_ctrl_transfer.h"
#include "app_config.h"
#include "device_drive.h"
#include "gpio.h"
#include "usb/scsi.h"
#define LOG_TAG_CONST USB
#define LOG_TAG "[USB]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if USB_HOST_ENABLE
_WEAK_
void usb_dis_ep0_txdly(const usb_dev id)
{
}
static void ep0_h_isr(struct usb_host_device *host_dev, u32 ep)
{
usb_dev usb_id = host_device2id(host_dev);
usb_sem_post(host_dev);
}
/**
* @brief usb_ctlXfer
*
* @param host_dev
* @param urb
*
* @return
*/
static int usb_ctlXfer(struct usb_host_device *host_dev, struct ctlXfer *urb)
{
u32 ret = DEV_ERR_NONE;
u8 reg = 0;
u32 data_len;
usb_dev usb_id = host_device2id(host_dev);
u8 devnum = host_dev->private_data.devnum;
u32 max_packet_size = host_dev->private_data.ep0_max_packet_size;
usb_write_faddr(usb_id, devnum);
#ifdef USB_HW_20
usb_write_txfuncaddr(usb_id, 0, devnum);
#endif
switch (urb->stage) {
case USB_PID_SETUP :
usb_write_ep0(usb_id, (u8 *)&urb->setup, 8);
reg = CSR0H_SetupPkt | CSR0H_TxPktRdy;
break;
case USB_PID_IN :
if (urb->setup.wLength) {
reg = CSR0H_ReqPkt;
} else {
reg = CSR0H_StatusPkt | CSR0H_ReqPkt;
}
break;
case USB_PID_OUT:
if (urb->setup.wLength) {
data_len = min(urb->setup.wLength, max_packet_size);
reg = CSR0H_TxPktRdy;
usb_write_ep0(usb_id, urb->buffer, data_len);
urb->setup.wLength -= data_len;
urb->buffer += data_len;
} else {
reg = CSR0H_StatusPkt | CSR0H_TxPktRdy;
}
break;
default :
break;
}
#if USB_HOST_ASYNC
//config ep0 callback fun
usb_h_set_ep_isr(host_dev, 0, ep0_h_isr, host_dev);
usb_set_intr_txe(usb_id, 0);
#endif
#ifdef USB_HW_20
usb_write_csr0(usb_id, reg | CSR0H_DISPING);
#else
usb_write_csr0(usb_id, reg);
#endif
u32 st = 0;
u32 ot = usb_get_jiffies() + 500;
while (1) {
if (usb_host_timeout(ot)) {
log_error("time out %x\n", reg);
ret = -DEV_ERR_TIMEOUT;
goto __exit;
}
if (usb_h_dev_status(usb_id)) {
st ++;
} else {
st = 0;
}
if (((usb_read_devctl(usb_id) & BIT(2)) == 0) || (st > 1000)) {
log_error("usb%d_offline\n", usb_id);
ret = -DEV_ERR_OFFLINE;
goto __exit;
}
#if USB_HOST_ASYNC
ret = usb_sem_pend(host_dev, 250); //wait isr
if (ret) {
log_error("usb%d_offline\n", usb_id);
ret = -DEV_ERR_OFFLINE;
goto __exit;
}
#endif
reg = usb_read_csr0(usb_id);
if (reg & CSR0H_RxStall) {
log_error(" rxStall CSR0:0x%x", reg);
ret = -DEV_ERR_CONTROL_STALL;
goto __exit;
}
if (reg & CSR0H_Error) {
log_error(" Error CSR0:0x%x", reg);
usb_write_csr0(usb_id, 0);
ret = -DEV_ERR_CONTROL;
goto __exit;
}
if (USB_PID_IN == urb->stage) {
if (reg & CSR0H_RxPktRdy) {
data_len = usb_read_count0(usb_id);
data_len = min(data_len, urb->setup.wLength);
usb_read_ep0(usb_id, urb->buffer, data_len);;
urb->buffer += data_len;
urb->setup.wLength -= data_len;
if (data_len < max_packet_size) {
urb->setup.wLength = 0;
}
if (urb->setup.wLength) {
#ifdef USB_HW_20
usb_write_csr0(usb_id, CSR0H_ReqPkt | CSR0H_DISPING);
#else
usb_write_csr0(usb_id, CSR0H_ReqPkt);
#endif
} else {
#ifdef USB_HW_20
usb_write_csr0(usb_id, CSR0H_DISPING);
#else
usb_write_csr0(usb_id, 0);
#endif
break;
}
}
} else {
if (!(reg & CSR0H_TxPktRdy)) {
break;
}
}
}
__exit:
usb_clr_intr_txe(usb_id, 0);
usb_dis_ep0_txdly(usb_id);
return ret;
}
/**
* @brief usb_control_transfers
*
* @param struct host_dev
* @param urb
*
* @return
*/
static int usb_control_transfers(struct usb_host_device *host_dev, struct ctlXfer *urb)
{
usb_dev usb_id = host_device2id(host_dev);
int res;
/*SETUP*/
urb->stage = USB_PID_SETUP; //SETUP transaction
res = usb_ctlXfer(host_dev, urb);
if (res) {
return res;
}
/*IN or OUT*/
urb->stage = USB_PID_IN;
while (urb->setup.wLength) {
if (urb->setup.bRequestType & USB_DIR_IN) { //Request Direction
urb->stage = USB_PID_IN; //IN transaction
res = usb_ctlXfer(host_dev, urb);
if (res) {
return res;
}
urb->stage = USB_PID_OUT;
} else {
urb->stage = USB_PID_OUT; //OUT transaction
res = usb_ctlXfer(host_dev, urb);
if (res) {
return res;
}
urb->stage = USB_PID_IN;
}
}
res = usb_ctlXfer(host_dev, urb);
if (res) {
return res;
}
return DEV_ERR_NONE;
}
/**
* @brief usb_control_msg
*
* @param host_dev
* @param request
* @param requesttype
* @param value
* @param index
* @param data
* @param size
*
* @return
*/
int usb_control_msg(struct usb_host_device *host_dev,
u8 request, u8 requesttype,
u16 value, u16 index,
void *data, u16 size)
{
struct ctlXfer urb;
urb.setup.bRequestType = requesttype;
urb.setup.bRequest = request;
urb.setup.wValue = cpu_to_le16(value);
urb.setup.wIndex = cpu_to_le16(index);
urb.setup.wLength = cpu_to_le16(size);
urb.buffer = data;
return usb_control_transfers(host_dev, &urb);
}
/**
* @brief usb_clear_feature
*
* @param host_dev
* @param ep
*
* @return
*/
int usb_clear_feature(struct usb_host_device *host_dev, u32 ep)
{
return usb_control_msg(host_dev, USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, ep, NULL, 0);
}
int set_address(struct usb_host_device *host_dev, u8 devnum)
{
return usb_control_msg(host_dev, USB_REQ_SET_ADDRESS, 0, devnum, 0, NULL, 0);
}
int usb_get_device_descriptor(struct usb_host_device *host_dev, struct usb_device_descriptor *desc)
{
return usb_control_msg(host_dev,
USB_REQ_GET_DESCRIPTOR,
USB_DIR_IN,
(USB_DT_DEVICE << 8),
0,
desc,
USB_DT_DEVICE_SIZE
);
}
int usb_get_string_descriptor(struct usb_host_device *host_dev, struct usb_device_descriptor *desc)
{
int ret = DEV_ERR_NONE;
#if 0
struct usb_private_data *private_data = host_dev->private_data ;
/**********get string language*********/
u8 buf[16];
memset(buf, 0x0, sizeof(buf));
ret = usb_control_msg(host_dev,
USB_REQ_GET_DESCRIPTOR,
USB_DIR_IN,
(USB_DT_STRING << 8),
0,
desc,
sizeof(buf)
);
if (ret) {
return ret;
}
memcpy(&private_data->language, buf + 2, sizeof(private_data->language));
/**********get manufacturer string**********/
memset(private_data->manufacturer, 0x0, sizeof(private_data->manufacturer));
if (desc->iManufacturer) {
ret = usb_control_msg(host_dev,
USB_REQ_GET_DESCRIPTOR,
USB_DIR_IN,
(USB_DT_STRING << 8) | desc->iManufacturer,
0,
private_data->manufacturer,
sizeof(private_data->manufacturer)
);
if (ret) {
return ret;
}
}
/**********get product string**********/
memset(private_data->product, 0x0, sizeof(private_data->product));
if (desc->iProduct) {
ret = usb_control_msg(host_dev,
USB_REQ_GET_DESCRIPTOR,
USB_DIR_IN,
(USB_DT_STRING << 8) | desc->iProduct,
0,
private_data->product,
sizeof(private_data->product)
);
if (ret) {
return ret;
}
}
#endif
return ret;
}
int set_configuration(struct usb_host_device *host_dev)
{
return usb_control_msg(host_dev, USB_REQ_SET_CONFIGURATION, 0, 1, 0, NULL, 0);
}
int set_configuration_add_value(struct usb_host_device *host_dev, u16 value)
{
return usb_control_msg(host_dev, USB_REQ_SET_CONFIGURATION, 0, value, 0, NULL, 0);
}
int get_config_descriptor(struct usb_host_device *host_dev, void *cfg_desc, u32 len)
{
return usb_control_msg(host_dev,
USB_REQ_GET_DESCRIPTOR,
USB_DIR_IN,
(USB_DT_CONFIG << 8),
0,
cfg_desc,
len);
}
int get_config_descriptor_add_value_l(struct usb_host_device *host_dev, void *cfg_desc, u32 len, u8 value_l)
{
return usb_control_msg(host_dev,
USB_REQ_GET_DESCRIPTOR,
USB_DIR_IN,
(USB_DT_CONFIG << 8) | value_l,
0,
cfg_desc,
len);
}
int get_msd_max_lun(struct usb_host_device *host_dev, void *lun)
{
return usb_control_msg(host_dev,
USB_MSD_MAX_LUN,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0,
0,
lun,
1);
}
int set_msd_reset(struct usb_host_device *host_dev)
{
return usb_control_msg(host_dev,
0xff,
USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0,
0,
NULL,
0);
}
int hid_set_idle(struct usb_host_device *host_dev, u32 id)
{
return usb_control_msg(host_dev, 0x0a, 0x21, 0, id << 8, NULL, 0);
}
int hid_get_report(struct usb_host_device *host_dev, u8 *report, u8 report_id, u16 report_len)
{
return usb_control_msg(host_dev,
USB_REQ_GET_DESCRIPTOR,
USB_DIR_IN | USB_RECIP_INTERFACE,
0x2200,
report_id,
report,
report_len);
}
int hid_set_output_report(struct usb_host_device *host_dev, u8 *report, u8 report_id, u8 report_len)
{
return usb_control_msg(host_dev,
0x09,
USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0x0201,
report_id,
report,
report_len);
}
int usb_set_remote_wakeup(struct usb_host_device *host_dev)
{
return usb_control_msg(host_dev, USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
USB_DEVICE_REMOTE_WAKEUP, 0, NULL, 0);
}
int get_device_status(struct usb_host_device *host_dev)
{
u16 status;
return usb_control_msg(host_dev, USB_REQ_GET_STATUS, USB_DIR_IN, 0, 0, (u8 *)&status, 2);
}
int usb_get_device_qualifier(struct usb_host_device *host_dev, u8 *buffer)
{
return usb_control_msg(host_dev,
USB_REQ_GET_DESCRIPTOR,
USB_DIR_IN,
(USB_DT_DEVICE_QUALIFIER << 8),
0,
buffer,
0x0a);
}
#define AOA_CMD51 0x33
#define AOA_CMD52 0x34
#define AOA_CMD53 0x35
int usb_get_aoa_version(struct usb_host_device *host_dev, u16 *version)
{
return usb_control_msg(host_dev,
AOA_CMD51,
USB_DIR_IN | USB_TYPE_VENDOR,
0,
0,
version,
2);
}
int usb_set_credentials(struct usb_host_device *host_dev, const char *string, int index)
{
return usb_control_msg(host_dev,
AOA_CMD52,
USB_DIR_OUT | USB_TYPE_VENDOR,
0,
index,
(u8 *)string,
strlen(string));
}
int usb_switch2aoa(struct usb_host_device *host_dev)
{
return usb_control_msg(host_dev,
AOA_CMD53,
USB_DIR_OUT | USB_TYPE_VENDOR,
0,
0,
NULL,
0);
}
int usb_switch2slave(struct usb_host_device *host_dev)
{
return usb_control_msg(host_dev,
0x51,
USB_DIR_OUT | USB_TYPE_VENDOR,
0,
0,
NULL,
0);
}
/* Control request for registering a HID device.
* Upon registering, a unique ID is sent by the accessory in the
* value parameter. This ID will be used for future commands for
* the device
*
* requestType: USB_DIR_OUT | USB_TYPE_VENDOR
* request: ACCESSORY_REGISTER_HID_DEVICE
* value: Accessory assigned ID for the HID device
* index: total length of the HID report descriptor
* data none
*/
#define ACCESSORY_REGISTER_HID 54
int usb_aoa_register_hid(struct usb_host_device *host_dev, u16 value, u16 index)
{
return usb_control_msg(host_dev,
ACCESSORY_REGISTER_HID,
USB_DIR_OUT | USB_TYPE_VENDOR,
value,
index,
NULL,
0);
}
/* Control request for unregistering a HID device.
*
* requestType: USB_DIR_OUT | USB_TYPE_VENDOR
* request: ACCESSORY_REGISTER_HID
* value: Accessory assigned ID for the HID device
* index: 0
* data none
*/
#define ACCESSORY_UNREGISTER_HID 55
int usb_aoa_unregister_hid(struct usb_host_device *host_dev, u16 value)
{
return usb_control_msg(host_dev,
ACCESSORY_UNREGISTER_HID,
USB_DIR_OUT | USB_TYPE_VENDOR,
value,
0,
NULL,
0);
}
/* Control request for sending the HID report descriptor.
* If the HID descriptor is longer than the endpoint zero max packet size,
* the descriptor will be sent in multiple ACCESSORY_SET_HID_REPORT_DESC
* commands. The data for the descriptor must be sent sequentially
* if multiple packets are needed.
*
* requestType: USB_DIR_OUT | USB_TYPE_VENDOR
* request: ACCESSORY_SET_HID_REPORT_DESC
* value: Accessory assigned ID for the HID device
* index: offset of data in descriptor
* (needed when HID descriptor is too big for one packet)
* data the HID report descriptor
*/
#define ACCESSORY_SET_HID_REPORT_DESC 56
int usb_aoa_set_hid_report_desc(struct usb_host_device *host_dev, u16 value, u16 offset, const char *pbuf, u32 len)
{
return usb_control_msg(host_dev,
ACCESSORY_SET_HID_REPORT_DESC,
USB_DIR_OUT | USB_TYPE_VENDOR,
value,
offset,
(u8 *)pbuf,
len);
}
/* Control request for sending HID events.
*
* requestType: USB_DIR_OUT | USB_TYPE_VENDOR
* request: ACCESSORY_SEND_HID_EVENT
* value: Accessory assigned ID for the HID device
* index: 0
* data the HID report for the event
*/
#define ACCESSORY_SEND_HID_EVENT 57
int usb_aoa_send_hid_event(struct usb_host_device *host_dev, u16 value, const u8 *pbuf, u32 len)
{
return usb_control_msg(host_dev,
ACCESSORY_SEND_HID_EVENT,
USB_DIR_OUT | USB_TYPE_VENDOR,
value,
0,
(u8 *)pbuf,
len);
}
int get_ms_extended_compat_id(struct usb_host_device *host_dev, u8 *buffer)
{
return usb_control_msg(host_dev,
0x01,
USB_DIR_IN | USB_RECIP_DEVICE | USB_TYPE_VENDOR,
0x0000,
4,
buffer,
0x28);
}
int usb_set_interface(struct usb_host_device *host_dev, u8 interface, u8 alternateSetting)
{
log_info("%s Set Interface:%d AlternateSetting:%d", __func__, interface, alternateSetting);
return usb_control_msg(host_dev,
USB_REQ_SET_INTERFACE,
USB_RECIP_INTERFACE,
alternateSetting,
interface,
NULL,
0);
}
int usb_audio_sampling_frequency_control(struct usb_host_device *host_dev, u32 ep, u32 sampe_rate)
{
log_info("%s ep:%d sampe_rate:%d", __func__, ep, sampe_rate);
return usb_control_msg(host_dev,
1,
USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
0x0100,
ep,
&sampe_rate,
3);
}
int usb_audio_volume_control(struct usb_host_device *host_dev, u8 feature_id, u8 channel_num, u16 volume)
{
log_info("%s featureID:%d vol:%x", __func__, feature_id, volume);
return usb_control_msg(host_dev,
1,
USB_TYPE_CLASS | USB_RECIP_INTERFACE,
(0x02 << 8) | channel_num,
feature_id << 8,
&volume,
2);
}
int usb_audio_mute_control(struct usb_host_device *host_dev, u8 feature_id, u8 mute)
{
log_info("%s featureID:%d mute:%d", __func__, feature_id, mute);
return usb_control_msg(host_dev,
1,
USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0x0100,
feature_id << 8,
&mute,
1);
}
#endif

View File

@ -1,384 +0,0 @@
/**@file usb_ctrl_transfer.h
* @brief usb_ctrl_transfer控制传输头文件
* @details 功能函数声明
* @author jieli
* @date 2021-8-1
* @version V1.0
* @copyright Copyright(c)2010-2021 珠海市杰理科技股份有限公司
*********************************************************
* @attention
* 硬件平台AC695N
* SDK版本AC695N_V1.0.0_SDK
* @修改日志:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-8-1 <td>1.0 <td>jieli <td>创建初始版本
* </table>
*
*********************************************************
*/
#ifndef __USB_CTRL_TRANSFER_H__
#define __USB_CTRL_TRANSFER_H__
#include "usb/ch9.h"
#include "usb/usb_phy.h"
#include "device/device.h"
#include "usb_config.h"
/*
* USB Packet IDs (PIDs)
*/
#define USB_PID_EXT 0xf0 /* USB 2.0 LPM ECN */
#define USB_PID_OUT 0xe1
#define USB_PID_ACK 0xd2
#define USB_PID_DATA0 0xc3
#define USB_PID_PING 0xb4 /* USB 2.0 */
#define USB_PID_SOF 0xa5
#define USB_PID_NYET 0x96 /* USB 2.0 */
#define USB_PID_DATA2 0x87 /* USB 2.0 */
#define USB_PID_SPLIT 0x78 /* USB 2.0 */
#define USB_PID_IN 0x69
#define USB_PID_NAK 0x5a
#define USB_PID_DATA1 0x4b
#define USB_PID_PREAMBLE 0x3c /* Token mode */
#define USB_PID_ERR 0x3c /* USB 2.0: handshake mode */
#define USB_PID_SETUP 0x2d
#define USB_PID_STALL 0x1e
#define USB_PID_MDATA 0x0f /* USB 2.0 */
struct ctlXfer {
struct usb_ctrlrequest setup; ///<控制请求
void *buffer; ///<控制请求的data
u8 stage; ///<当前状态
};
int usb_control_msg(struct usb_host_device *host_dev,
u8 request, u8 requesttype,
u16 value, u16 index,
void *data, u16 size);
/**@brief USB清除或禁用特定的特性
* @param[in] usb_host_device定义的结构体指针
* @param[in] ep 端点号
* @return 0:成功
* @par 示例:
* @code
* usb_clear_feature(host_dev , ep);
* @encode
*/
int usb_clear_feature(struct usb_host_device *usb_dev, u32 ep);
/**@brief USB设置地址
* @param[in] usb_host_device定义的结构体指针
* @param[in] devnum 设备编号
* @return 0:成功
* @par 示例:
* @code
* set_address(host_dev , ep);
* @encode
*/
int set_address(struct usb_host_device *usb_dev, u8 devnum);
/**@brief USB获取设备描述符
* @param[in] usb_host_device定义的结构体指针
* @param[in] usb_device_descriptor定义的结构体指针
* @return 0:成功
* @par 示例:
* @code
* usb_get_device_descriptor(host_dev , device_desc);
* @encode
*/
int usb_get_device_descriptor(struct usb_host_device *usb_dev, struct usb_device_descriptor *desc);
/**@brief USB获取字符串描述符
* @param[in] usb_host_device定义的结构体指针
* @param[in] usb_device_descriptor定义的结构体指针
* @return 0:成功
* @par 示例:
* @code
* usb_get_string_descriptor(host_dev , device_desc);
* @encode
*/
int usb_get_string_descriptor(struct usb_host_device *usb_dev, struct usb_device_descriptor *desc);
/**@brief USB设置相关配置
* @param[in] usb_host_device定义的结构体指针
* @return 0:成功
* @par 示例:
* @code
* set_configuration(host_dev);
* @encode
*/
int set_configuration(struct usb_host_device *usb_dev);
/**@brief USB设置相关配置,添加相关参数
* @param[in] usb_host_device定义的结构体指针
* @param[in] value 当前请求的参数
* @return 0:成功
* @par 示例:
* @code
* set_configuration_add_value(host_dev , value);
* @encode
*/
int set_configuration_add_value(struct usb_host_device *host_dev, u16 value);
/**@brief USB获取配置描述符
* @param[in] usb_host_device定义的结构体指针
* @param[in] cfg_desc 自定义的配置描述符指针
* @param[in] len 长度
* @return 0:成功
* @par 示例:
* @code
* get_config_descriptor(host_dev , cfg_desc , len);
* @encode
*/
int get_config_descriptor(struct usb_host_device *usb_dev, void *cfg_desc, u32 len);
/**@brief USB获取配置描述符,添加相关参数
* @param[in] usb_host_device定义的结构体指针
* @param[in] cfg_desc 自定义的配置描述符指针
* @param[in] len 长度
* @param[in] value_l 请求的参数
* @return 0:成功
* @par 示例:
* @code
* get_config_descriptor_add_value_l(host_dev , cfg_desc , len , value_l);
* @encode
*/
int get_config_descriptor_add_value_l(struct usb_host_device *host_dev, void *cfg_desc, u32 len, u8 value_l);
/**@brief USB获取大容量存储设备的最大逻辑单元号
* @param[in] usb_host_device定义的结构体指针
* @param[in] lun 逻辑单元号
* @return 0:成功
* @par 示例:
* @code
* get_msd_max_lun(host_dev , lun);
* @encode
*/
int get_msd_max_lun(struct usb_host_device *usb_dev, void *lun);
/**@brief USB设置大容量存储设备复位
* @param[in] usb_host_device定义的结构体指针
* @return 0:成功
* @par 示例:
* @code
* set_msd_reset(host_dev);
* @encode
*/
int set_msd_reset(struct usb_host_device *usb_dev);
/**@brief hid设置为空闲模式
* @param[in] usb_host_device定义的结构体指针
* @param[in] id 指定接口或端点号
* @return 0:成功
* @par 示例:
* @code
* hid_set_idle(host_dev , id);
* @encode
*/
int hid_set_idle(struct usb_host_device *usb_dev, u32 id);
/**@brief hid获取报告描述符
* @param[in] usb_host_device定义的结构体指针
* @param[in] report 自定义报告指针,指向报告内容
* @param[in] report_id 报告描述符id号
* @param[in] report_len 报告描述符长度
* @return 0:成功
* @par 示例:
* @code
* hid_get_report(host_dev , report , report_id , report_len);
* @encode
*/
int hid_get_report(struct usb_host_device *usb_dev, u8 *report, u8 report_id, u16 report_len);
/**@brief hid设置输出报告描述符
* @param[in] usb_host_device定义的结构体指针
* @param[in] report 自定义报告指针,指向报告内容
* @param[in] report_id
* @param[in] report_len
* @return 0:成功
* @par 示例:
* @code
* hid_set_output_report(host_dev , report , report_id , report_len);
* @encode
*/
int hid_set_output_report(struct usb_host_device *usb_dev, u8 *report, u8 report_id, u8 report_len);
/**@brief USB设置远程唤醒
* @param[in] usb_host_device定义的结构体指针
* @return 0:成功
* @par 示例:
* @code
* usb_set_remote_wakeup(host_dev);
* @encode
*/
int usb_set_remote_wakeup(struct usb_host_device *usb_dev);
/**@brief USB获取设备状态
* @param[in] usb_host_device定义的结构体指针
* @return 0:成功
* @par 示例:
* @code
* get_device_status(host_dev);
* @encode
*/
int get_device_status(struct usb_host_device *usb_dev);
/**@brief USB获取设备限定描述符
* @param[in] usb_host_device定义的结构体指针
* @param[in] BUFFER 自定义的指针,指向限定描述符内容
* @return 0:成功
* @par 示例:
* @code
* usb_get_device_qualifier(host_dev , buffer);
* @encode
*/
int usb_get_device_qualifier(struct usb_host_device *usb_dev, u8 *buffer);
/**@brief USB获取安卓aoa协议版本
* @param[in] usb_host_device定义的结构体指针
* @param[in] version 自定义的指针,指向版本内容
* @return 0:成功
* @par 示例:
* @code
* usb_get_aoa_version(host_dev , version);
* @encode
*/
int usb_get_aoa_version(struct usb_host_device *host_dev, u16 *version);
/**@brief USB设置证书信息
* @param[in] usb_host_device定义的结构体指针
* @param[in] string 字符串指针,指向证书内容
* @param[in] index 传递的参数
* @return 0:成功
* @par 示例:
* @code
* usb_set_credentials(host_dev , string , index);
* @encode
*/
int usb_set_credentials(struct usb_host_device *host_dev, const char *string, int index);
/**@brief USB设置aoa开关
* @param[in] usb_host_device定义的结构体指针
* @return 0:成功
* @par 示例:
* @code
* usb_switch2aoa(host_dev);
* @encode
*/
int usb_switch2aoa(struct usb_host_device *host_dev);
/**@brief USB设置从机模式开关
* @param[in] usb_host_device定义的结构体指针
* @return 0:成功
* @par 示例:
* @code
* usb_switch2slave(host_dev);
* @encode
*/
int usb_switch2slave(struct usb_host_device *host_dev);
/**@brief USB hid设备注册
* @param[in] usb_host_device定义的结构体指针
* @param[in] value 请求的参数
* @param[in] index 传递的参数
* @return 0:成功
* @par 示例:
* @code
* usb_aoa_register_hid(host_dev , value , index);
* @encode
*/
int usb_aoa_register_hid(struct usb_host_device *host_dev, u16 value, u16 index);
/**@brief USB设置hid报告描述符
* @param[in] usb_host_device定义的结构体指针
* @param[in] value 请求的参数
* @param[in] offset 偏移量参数
* @param[in] pbuf 存放数据的BUFFER指针
* @param[in] len 长度
* @return 0:成功
* @par 示例:
* @code
* usb_aoa_set_hid_report_desc(host_dev , value , offset , *pbuf , len);
* @encode
*/
int usb_aoa_set_hid_report_desc(struct usb_host_device *host_dev, u16 value, u16 offset, const char *pbuf, u32 len);
/**@brief USB发送hid事件
* @param[in] usb_host_device定义的结构体指针
* @param[in] value 请求的参数
* @param[in] pbuf 存放数据的BUFFER指针
* @param[in] len 长度
* @return 0:成功
* @par 示例:
* @code
* usb_aoa_send_hid_event(host_dev , value , *pbuf , len);
* @encode
*/
int usb_aoa_send_hid_event(struct usb_host_device *host_dev, u16 value, const u8 *pbuf, u32 len);
/**@brief 获取扩展的大容量存储设备可兼容id 号
* @param[in] usb_host_device定义的结构体指针
* @param[in] BUFFER 存放数据的BUFFER
* @return 0:成功
* @par 示例:
* @code
* get_ms_extended_compat_id(host_dev , value , *pbuf , len);
* @encode
*/
int get_ms_extended_compat_id(struct usb_host_device *host_dev, u8 *buffer);
/**@brief USB设置接口
* @param[in] usb_host_device定义的结构体指针
* @param[in] interface 接口参数(请求的参数)
* @param[in] alternateSetting 交替设置(传递的参数)
* @return 0:成功
* @par 示例:
* @code
* usb_set_interface(host_dev , interface , alternateSetting);
* @encode
*/
int usb_set_interface(struct usb_host_device *host_dev, u8 interface, u8 alternateSetting);
/**@brief USB音频采样频率控制
* @param[in] usb_host_device定义的结构体指针
* @param[in] ep 端点号
* @param[in] samp_rate 采样率
* @return 0:成功
* @par 示例:
* @code
* usb_audio_sampling_frequency_control(host_dev , ep , sampe_rate);
* @encode
*/
int usb_audio_sampling_frequency_control(struct usb_host_device *host_dev, u32 ep, u32 sampe_rate);
/**@brief USB音频音量控制
* @param[in] usb_host_device定义的结构体指针
* @param[in] feature_id 特征值id号端点或接口的id传递的参数
* @param[in] channel_num 通道编号(请求的参数)
* @paeam[in] volume 音量
* @return 0:成功
* @par 示例:
* @code
* usb_audio_volume_control(host_dev , feature_id , channel_num , volume);
* @encode
*/
int usb_audio_volume_control(struct usb_host_device *host_dev, u8 feature_id, u8 channel_num, u16 volume);
/**@brief USB音频静音控制
* @param[in] usb_host_device定义的结构体指针
* @param[in] feature_id 特征值id号端点或接口的id传递的参数
* @param[in] mute 静音信号(静音标志)
* @return 0:成功
* @par 示例:
* @code
* usb_audio_mute_control(host_dev , feature_id , channel_num , volume);
* @encode
*/
int usb_audio_mute_control(struct usb_host_device *host_dev, u8 feature_id, u8 mute);
#endif

View File

@ -1,353 +0,0 @@
/**
* USB HID Keyboard scan codes as per USB spec 1.11
* plus some additional codes
*
* Created by MightyPork, 2016
* Public domain
*
* Adapted from:
* https://source.android.com/devices/input/keyboard-devices.html
*/
#ifndef USB_HID_KEYS
#define USB_HID_KEYS
struct keyboard_data_t {
u8 fun_key;
u8 res;
u8 Keypad[6];
} _GNU_PACKED_ ;
struct mouse_data_t {
u8 btn;
s16 x;
s16 y;
s8 wheel;
s8 ac_pan;
} _GNU_PACKED_ ;
struct point_t {
u8 tip_switch: 2;
/* u8 in_range: 1; */
u8 res: 2;
u8 cid: 4;
s16 x;
s16 y;
} _GNU_PACKED_ ;
struct touch_screen_t {
struct point_t p[3];
} _GNU_PACKED_;
struct mouse_point_t {
u8 btn;
s8 x;
s8 y;
s8 wheel;
} _GNU_PACKED_;
/**
* Modifier masks - used for the first byte in the HID report.
* NOTE: The second byte in the report is reserved, 0x00
*/
#define _KEY_MOD_LCTRL 0x01
#define _KEY_MOD_LSHIFT 0x02
#define _KEY_MOD_LALT 0x04
#define _KEY_MOD_LMETA 0x08
#define _KEY_MOD_RCTRL 0x10
#define _KEY_MOD_RSHIFT 0x20
#define _KEY_MOD_RALT 0x40
#define _KEY_MOD_RMETA 0x80
/**
* Scan codes - last N slots in the HID report (usually 6).
* 0x00 if no key pressed.
*
* If more than N keys are pressed, the HID reports
* KEY_ERR_OVF in all slots to indicate this condition.
*/
#define _KEY_NONE 0x00 // No key pressed
#define _KEY_ERR_OVF 0x01 // Keyboard Error Roll Over - used for all slots if too many keys are pressed ("Phantom key")
// 0x02 // Keyboard POST Fail
// 0x03 // Keyboard Error Undefined
#define _KEY_A 0x04 // Keyboard a and A
#define _KEY_B 0x05 // Keyboard b and B
#define _KEY_C 0x06 // Keyboard c and C
#define _KEY_D 0x07 // Keyboard d and D
#define _KEY_E 0x08 // Keyboard e and E
#define _KEY_F 0x09 // Keyboard f and F
#define _KEY_G 0x0a // Keyboard g and G
#define _KEY_H 0x0b // Keyboard h and H
#define _KEY_I 0x0c // Keyboard i and I
#define _KEY_J 0x0d // Keyboard j and J
#define _KEY_K 0x0e // Keyboard k and K
#define _KEY_L 0x0f // Keyboard l and L
#define _KEY_M 0x10 // Keyboard m and M
#define _KEY_N 0x11 // Keyboard n and N
#define _KEY_O 0x12 // Keyboard o and O
#define _KEY_P 0x13 // Keyboard p and P
#define _KEY_Q 0x14 // Keyboard q and Q
#define _KEY_R 0x15 // Keyboard r and R
#define _KEY_S 0x16 // Keyboard s and S
#define _KEY_T 0x17 // Keyboard t and T
#define _KEY_U 0x18 // Keyboard u and U
#define _KEY_V 0x19 // Keyboard v and V
#define _KEY_W 0x1a // Keyboard w and W
#define _KEY_X 0x1b // Keyboard x and X
#define _KEY_Y 0x1c // Keyboard y and Y
#define _KEY_Z 0x1d // Keyboard z and Z
#define _KEY_1 0x1e // Keyboard 1 and !
#define _KEY_2 0x1f // Keyboard 2 and @
#define _KEY_3 0x20 // Keyboard 3 and #
#define _KEY_4 0x21 // Keyboard 4 and $
#define _KEY_5 0x22 // Keyboard 5 and %
#define _KEY_6 0x23 // Keyboard 6 and ^
#define _KEY_7 0x24 // Keyboard 7 and &
#define _KEY_8 0x25 // Keyboard 8 and *
#define _KEY_9 0x26 // Keyboard 9 and (
#define _KEY_0 0x27 // Keyboard 0 and )
#define _KEY_ENTER 0x28 // Keyboard Return (ENTER)
#define _KEY_ESC 0x29 // Keyboard ESCAPE
#define _KEY_BACKSPACE 0x2a // Keyboard DELETE (Backspace)
#define _KEY_TAB 0x2b // Keyboard Tab
#define _KEY_SPACE 0x2c // Keyboard Spacebar
#define _KEY_MINUS 0x2d // Keyboard - and _
#define _KEY_EQUAL 0x2e // Keyboard = and +
#define _KEY_LEFTBRACE 0x2f // Keyboard [ and {
#define _KEY_RIGHTBRACE 0x30 // Keyboard ] and }
#define _KEY_BACKSLASH 0x31 // Keyboard \ and |
#define _KEY_HASHTILDE 0x32 // Keyboard Non-US # and ~
#define _KEY_SEMICOLON 0x33 // Keyboard ; and :
#define _KEY_APOSTROPHE 0x34 // Keyboard ' and "
#define _KEY_GRAVE 0x35 // Keyboard ` and ~
#define _KEY_COMMA 0x36 // Keyboard , and <
#define _KEY_DOT 0x37 // Keyboard . and >
#define _KEY_SLASH 0x38 // Keyboard / and ?
#define _KEY_CAPSLOCK 0x39 // Keyboard Caps Lock
#define _KEY_F1 0x3a // Keyboard F1
#define _KEY_F2 0x3b // Keyboard F2
#define _KEY_F3 0x3c // Keyboard F3
#define _KEY_F4 0x3d // Keyboard F4
#define _KEY_F5 0x3e // Keyboard F5
#define _KEY_F6 0x3f // Keyboard F6
#define _KEY_F7 0x40 // Keyboard F7
#define _KEY_F8 0x41 // Keyboard F8
#define _KEY_F9 0x42 // Keyboard F9
#define _KEY_F10 0x43 // Keyboard F10
#define _KEY_F11 0x44 // Keyboard F11
#define _KEY_F12 0x45 // Keyboard F12
#define _KEY_SYSRQ 0x46 // Keyboard Print Screen
#define _KEY_SCROLLLOCK 0x47 // Keyboard Scroll Lock
#define _KEY_PAUSE 0x48 // Keyboard Pause
#define _KEY_INSERT 0x49 // Keyboard Insert
#define _KEY_HOME 0x4a // Keyboard Home
#define _KEY_PAGEUP 0x4b // Keyboard Page Up
#define _KEY_DELETE 0x4c // Keyboard Delete Forward
#define _KEY_END 0x4d // Keyboard End
#define _KEY_PAGEDOWN 0x4e // Keyboard Page Down
#define _KEY_RIGHT 0x4f // Keyboard Right Arrow
#define _KEY_LEFT 0x50 // Keyboard Left Arrow
#define _KEY_DOWN 0x51 // Keyboard Down Arrow
#define _KEY_UP 0x52 // Keyboard Up Arrow
#define _KEY_NUMLOCK 0x53 // Keyboard Num Lock and Clear
#define _KEY_KPSLASH 0x54 // Keypad /
#define _KEY_KPASTERISK 0x55 // Keypad *
#define _KEY_KPMINUS 0x56 // Keypad -
#define _KEY_KPPLUS 0x57 // Keypad +
#define _KEY_KPENTER 0x58 // Keypad ENTER
#define _KEY_KP1 0x59 // Keypad 1 and End
#define _KEY_KP2 0x5a // Keypad 2 and Down Arrow
#define _KEY_KP3 0x5b // Keypad 3 and PageDn
#define _KEY_KP4 0x5c // Keypad 4 and Left Arrow
#define _KEY_KP5 0x5d // Keypad 5
#define _KEY_KP6 0x5e // Keypad 6 and Right Arrow
#define _KEY_KP7 0x5f // Keypad 7 and Home
#define _KEY_KP8 0x60 // Keypad 8 and Up Arrow
#define _KEY_KP9 0x61 // Keypad 9 and Page Up
#define _KEY_KP0 0x62 // Keypad 0 and Insert
#define _KEY_KPDOT 0x63 // Keypad . and Delete
#define _KEY_102ND 0x64 // Keyboard Non-US \ and |
#define _KEY_COMPOSE 0x65 // Keyboard Application
#define _KEY_POWER 0x66 // Keyboard Power
#define _KEY_KPEQUAL 0x67 // Keypad =
#define _KEY_F13 0x68 // Keyboard F13
#define _KEY_F14 0x69 // Keyboard F14
#define _KEY_F15 0x6a // Keyboard F15
#define _KEY_F16 0x6b // Keyboard F16
#define _KEY_F17 0x6c // Keyboard F17
#define _KEY_F18 0x6d // Keyboard F18
#define _KEY_F19 0x6e // Keyboard F19
#define _KEY_F20 0x6f // Keyboard F20
#define _KEY_F21 0x70 // Keyboard F21
#define _KEY_F22 0x71 // Keyboard F22
#define _KEY_F23 0x72 // Keyboard F23
#define _KEY_F24 0x73 // Keyboard F24
#define _KEY_OPEN 0x74 // Keyboard Execute
#define _KEY_HELP 0x75 // Keyboard Help
#define _KEY_PROPS 0x76 // Keyboard Menu
#define _KEY_FRONT 0x77 // Keyboard Select
#define _KEY_STOP 0x78 // Keyboard Stop
#define _KEY_AGAIN 0x79 // Keyboard Again
#define _KEY_UNDO 0x7a // Keyboard Undo
#define _KEY_CUT 0x7b // Keyboard Cut
#define _KEY_COPY 0x7c // Keyboard Copy
#define _KEY_PASTE 0x7d // Keyboard Paste
#define _KEY_FIND 0x7e // Keyboard Find
#define _KEY_MUTE 0x7f // Keyboard Mute
#define _KEY_VOLUMEUP 0x80 // Keyboard Volume Up
#define _KEY_VOLUMEDOWN 0x81 // Keyboard Volume Down
// 0x82 Keyboard Locking Caps Lock
// 0x83 Keyboard Locking Num Lock
// 0x84 Keyboard Locking Scroll Lock
#define _KEY_KPCOMMA 0x85 // Keypad Comma
// 0x86 Keypad Equal Sign
#define _KEY_RO 0x87 // Keyboard International1
#define _KEY_KATAKANAHIRAGANA 0x88 // Keyboard International2
#define _KEY_YEN 0x89 // Keyboard International3
#define _KEY_HENKAN 0x8a // Keyboard International4
#define _KEY_MUHENKAN 0x8b // Keyboard International5
#define _KEY_KPJPCOMMA 0x8c // Keyboard International6
// 0x8d Keyboard International7
// 0x8e Keyboard International8
// 0x8f Keyboard International9
#define _KEY_HANGEUL 0x90 // Keyboard LANG1
#define _KEY_HANJA 0x91 // Keyboard LANG2
#define _KEY_KATAKANA 0x92 // Keyboard LANG3
#define _KEY_HIRAGANA 0x93 // Keyboard LANG4
#define _KEY_ZENKAKUHANKAKU 0x94 // Keyboard LANG5
// 0x95 Keyboard LANG6
// 0x96 Keyboard LANG7
// 0x97 Keyboard LANG8
// 0x98 Keyboard LANG9
// 0x99 Keyboard Alternate Erase
// 0x9a Keyboard SysReq/Attention
// 0x9b Keyboard Cancel
// 0x9c Keyboard Clear
// 0x9d Keyboard Prior
// 0x9e Keyboard Return
// 0x9f Keyboard Separator
// 0xa0 Keyboard Out
// 0xa1 Keyboard Oper
// 0xa2 Keyboard Clear/Again
// 0xa3 Keyboard CrSel/Props
// 0xa4 Keyboard ExSel
// 0xb0 Keypad 00
// 0xb1 Keypad 000
// 0xb2 Thousands Separator
// 0xb3 Decimal Separator
// 0xb4 Currency Unit
// 0xb5 Currency Sub-unit
#define _KEY_KPLEFTPAREN 0xb6 // Keypad (
#define _KEY_KPRIGHTPAREN 0xb7 // Keypad )
// 0xb8 Keypad {
// 0xb9 Keypad }
// 0xba Keypad Tab
// 0xbb Keypad Backspace
// 0xbc Keypad A
// 0xbd Keypad B
// 0xbe Keypad C
// 0xbf Keypad D
// 0xc0 Keypad E
// 0xc1 Keypad F
// 0xc2 Keypad XOR
// 0xc3 Keypad ^
// 0xc4 Keypad %
// 0xc5 Keypad <
// 0xc6 Keypad >
// 0xc7 Keypad &
// 0xc8 Keypad &&
// 0xc9 Keypad |
// 0xca Keypad ||
// 0xcb Keypad :
// 0xcc Keypad #
// 0xcd Keypad Space
// 0xce Keypad @
// 0xcf Keypad !
// 0xd0 Keypad Memory Store
// 0xd1 Keypad Memory Recall
// 0xd2 Keypad Memory Clear
// 0xd3 Keypad Memory Add
// 0xd4 Keypad Memory Subtract
// 0xd5 Keypad Memory Multiply
// 0xd6 Keypad Memory Divide
// 0xd7 Keypad +/-
// 0xd8 Keypad Clear
// 0xd9 Keypad Clear Entry
// 0xda Keypad Binary
// 0xdb Keypad Octal
// 0xdc Keypad Decimal
// 0xdd Keypad Hexadecimal
#define _KEY_LEFTCTRL 0xe0 // Keyboard Left Control
#define _KEY_LEFTSHIFT 0xe1 // Keyboard Left Shift
#define _KEY_LEFTALT 0xe2 // Keyboard Left Alt
#define _KEY_LEFTMETA 0xe3 // Keyboard Left GUI
#define _KEY_RIGHTCTRL 0xe4 // Keyboard Right Control
#define _KEY_RIGHTSHIFT 0xe5 // Keyboard Right Shift
#define _KEY_RIGHTALT 0xe6 // Keyboard Right Alt
#define _KEY_RIGHTMETA 0xe7 // Keyboard Right GUI
#define _KEY_MEDIA_PLAYPAUSE 0xe8
#define _KEY_MEDIA_STOPCD 0xe9
#define _KEY_MEDIA_PREVIOUSSONG 0xea
#define _KEY_MEDIA_NEXTSONG 0xeb
#define _KEY_MEDIA_EJECTCD 0xec
#define _KEY_MEDIA_VOLUMEUP 0xed
#define _KEY_MEDIA_VOLUMEDOWN 0xee
#define _KEY_MEDIA_MUTE 0xef
#define _KEY_MEDIA_WWW 0xf0
#define _KEY_MEDIA_BACK 0xf1
#define _KEY_MEDIA_FORWARD 0xf2
#define _KEY_MEDIA_STOP 0xf3
#define _KEY_MEDIA_FIND 0xf4
#define _KEY_MEDIA_SCROLLUP 0xf5
#define _KEY_MEDIA_SCROLLDOWN 0xf6
#define _KEY_MEDIA_EDIT 0xf7
#define _KEY_MEDIA_SLEEP 0xf8
#define _KEY_MEDIA_COFFEE 0xf9
#define _KEY_MEDIA_REFRESH 0xfa
#define _KEY_MEDIA_CALC 0xfb
#define _KEY_CUSTOM_CTRL_VOL_UP 0x00e9
#define _KEY_CUSTOM_CTRL_VOL_DOWN 0x00ea
#define _KEY_CUSTOM_CTRL_MUTE 0x00e2
#define _KEY_CUSTOM_CTRL_FORWARD 0x00b5
#define _KEY_CUSTOM_CTRL_STOP 0x00cd
#define _KEY_CUSTOM_CTRL_BACK 0x00b6
#define _KEY_CUSTOM_CTRL_MUSIC 0x0183
#define _KEY_CUSTOM_CTRL_CALCULATOR 0x0192
#define _KEY_CUSTOM_CTRL_SEARCH 0x0221
#define _KEY_CUSTOM_CTRL_EMAIL 0x018A
#define _KEY_CUSTOM_CTRL_HOME 0x0223
#define _KEY_BRIGHTNESS_INCREASE 0x006F
#define _KEY_BRIGHTNESS_REDUCTION 0x0070
#define _KEY_ZOOM_IN 0x022D
#define _KEY_ZOOM_OUT 0x022E
#define _KEY_CUSTOM_COPY 0x021B
#define _KEY_CUSTOM_CUT 0x021C
#define _KEY_CUSTOM_PASTE 0x021D
#define _KEY_CUSTOM_SELECT_ALL 0x021E
#define _KEY_CUSTOM_SPLIT_SCREEN 0x0196
#define _KEY_CUSTOM_LOCK 0x0030
#define _KEY_CUSTOM_ESC 0x0223
#define _KEY_CUSTOM_CALENDAR 0x018e
#define _KEY_CUSTOM_MESSAGE 0X018d
#define _KEY_CUSTOM_BROWER 0x0231
#define _KEY_CUSTOM_PROCESS 0x023a
#define _KEY_CUSTOM_SET 0x029b
#define LED_NUM_LOCK 0x01
#define LED_CAPS_LOCK 0x02
#define LED_SCROLL_CLOCK 0x04
#endif

View File

@ -1,834 +0,0 @@
#include "includes.h"
#include "app_config.h"
#include "device_drive.h"
/* #include "os/os_compat.h" */
#if USB_HOST_ENABLE
#include "usb_config.h"
#include "usb/host/usb_host.h"
#include "usb/usb_phy.h"
#include "usb_ctrl_transfer.h"
#include "usb_storage.h"
#include "adb.h"
#include "aoa.h"
#include "hid.h"
#include "audio.h"
#if TCFG_USB_APPLE_DOCK_EN
#include "apple_dock/iAP.h"
#include "apple_mfi.h"
#endif
#define LOG_TAG_CONST USB
#define LOG_TAG "[mount]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
static struct usb_host_device host_devices[USB_MAX_HW_NUM];// SEC(.usb_h_bss);
#define device_to_usbdev(device) ((struct usb_host_device *)((device)->private_data))
int host_dev_status(const struct usb_host_device *host_dev)
{
return ((host_dev)->private_data.status);
}
u32 host_device2id(const struct usb_host_device *host_dev)
{
#if USB_MAX_HW_NUM > 1
return ((host_dev)->private_data.usb_id);
#else
return 0;
#endif
}
const struct usb_host_device *host_id2device(const usb_dev id)
{
#if USB_MAX_HW_NUM > 1
return &host_devices[id];
#else
return &host_devices[0];
#endif
}
int usb_sem_init(struct usb_host_device *host_dev)
{
usb_dev usb_id = host_device2id(host_dev);
usb_host_config(usb_id);
OS_SEM *sem = zalloc(sizeof(OS_SEM));
ASSERT(sem, "usb alloc sem error");
host_dev->sem = sem;
g_printf("%s %x %x ", __func__, host_dev, sem);
os_sem_create(host_dev->sem, 0);
return 0;
}
int usb_sem_pend(struct usb_host_device *host_dev, u32 timeout)
{
if (host_dev->sem == NULL) {
return 1;
}
int ret = os_sem_pend(host_dev->sem, timeout);
if (ret) {
r_printf("%s %d ", __func__, ret);
}
return ret;
}
int usb_sem_post(struct usb_host_device *host_dev)
{
if (host_dev->sem == NULL) {
return 1;
}
int ret = os_sem_post(host_dev->sem);
if (ret) {
r_printf("%s %d ", __func__, ret);
}
return 0;
}
int usb_sem_del(struct usb_host_device *host_dev)
{
usb_dev usb_id = host_device2id(host_dev);
r_printf("1");
if (host_dev->sem == NULL) {
return 0;
}
r_printf("2");
r_printf("3");
#if USB_HUB
if (host_dev && host_dev->sem && host_dev->father == NULL) {
os_sem_del(host_dev->sem, 0);
}
#else
if (host_dev && host_dev->sem) {
os_sem_del(host_dev->sem, 0);
}
#endif
r_printf("4");
g_printf("%s %x %x ", __func__, host_dev, host_dev->sem);
free(host_dev->sem);
r_printf("5");
host_dev->sem = NULL;
r_printf("6");
usb_host_free(usb_id);
r_printf("7");
return 0;
}
static int _usb_msd_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
{
log_info("find udisk @ interface %d", interface_num);
#if TCFG_UDISK_ENABLE
return usb_msd_parser(host_dev, interface_num, pBuf);
#else
return USB_DT_INTERFACE_SIZE;
#endif
}
static int _usb_apple_mfi_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
{
log_info("find udisk @ interface %d", interface_num);
#if TCFG_USB_APPLE_DOCK_EN
return usb_apple_mfi_parser(host_dev, interface_num, pBuf);
#else
return USB_DT_INTERFACE_SIZE;
#endif
}
static int _usb_adb_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
{
log_info("find adb @ interface %d", interface_num);
#if TCFG_ADB_ENABLE
return usb_adb_parser(host_dev, interface_num, pBuf);
#else
return USB_DT_INTERFACE_SIZE;
#endif
}
static int _usb_aoa_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
{
log_info("find aoa @ interface %d", interface_num);
#if TCFG_AOA_ENABLE
return usb_aoa_parser(host_dev, interface_num, pBuf);
#else
return USB_DT_INTERFACE_SIZE;
#endif
}
static int _usb_hid_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
{
log_info("find hid @ interface %d", interface_num);
#if TCFG_HID_HOST_ENABLE
return usb_hid_parser(host_dev, interface_num, pBuf);
#else
return USB_DT_INTERFACE_SIZE;
#endif
}
static int _usb_audio_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
{
log_info("find audio @ interface %d", interface_num);
#if TCFG_HOST_AUDIO_ENABLE
return usb_audio_parser(host_dev, interface_num, pBuf);
#else
return USB_DT_INTERFACE_SIZE;
#endif
}
static int _usb_adb_interface_ptp_mtp_parse(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf)
{
log_info("find adbmtp @ interface %d", interface_num);
#if TCFG_ADB_ENABLE
return usb_adb_interface_ptp_mtp_parse(host_dev, interface_num, pBuf);
#else
return USB_DT_INTERFACE_SIZE;
#endif
}
/**
* @brief usb_descriptor_parser
*
* @param device
* @param pBuf
* @param total_len
*
* @return
*/
static int usb_descriptor_parser(struct usb_host_device *host_dev, const u8 *pBuf, u32 total_len, struct usb_device_descriptor *device_desc)
{
int len = 0;
u8 interface_num = 0;
struct usb_private_data *private_data = &host_dev->private_data;
struct usb_config_descriptor *cfg_desc = (struct usb_config_descriptor *)pBuf;
if (cfg_desc->bDescriptorType != USB_DT_CONFIG ||
cfg_desc->bLength < USB_DT_CONFIG_SIZE) {
log_error("invalid descriptor for config bDescriptorType = %d bLength= %d",
cfg_desc->bDescriptorType, cfg_desc->bLength);
return -USB_DT_CONFIG;
}
log_info("idVendor %x idProduct %x", device_desc->idVendor, device_desc->idProduct);
len += USB_DT_CONFIG_SIZE;
pBuf += USB_DT_CONFIG_SIZE;
int i = 0;
u32 have_find_valid_class = 0;
while (len < total_len) {
if (interface_num > MAX_HOST_INTERFACE) {
log_error("interface_num too much");
break;
}
struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)pBuf;
if (interface->bDescriptorType == USB_DT_INTERFACE) {
printf("inf class %x subclass %x ep %d",
interface->bInterfaceClass, interface->bInterfaceSubClass, interface->bNumEndpoints);
if (interface->bInterfaceClass == USB_CLASS_MASS_STORAGE) {
i = _usb_msd_parser(host_dev, interface_num, pBuf);
if (i < 0) {
log_error("---%s %d---", __func__, __LINE__);
len = total_len;
} else {
interface_num++;
len += i;
pBuf += i;
have_find_valid_class = true;
}
} else if ((device_desc->idVendor == 0x05AC) &&
((device_desc->idProduct & 0xff00) == 0x1200)) {
i = _usb_apple_mfi_parser(host_dev, interface_num, pBuf);
if (i < 0) {
log_error("---%s %d---", __func__, __LINE__);
len = total_len;
} else {
interface_num++;
len += i;
pBuf += i;
have_find_valid_class = true;
}
} else if (interface->bInterfaceClass == USB_CLASS_AUDIO) {
i = _usb_audio_parser(host_dev, interface_num, pBuf);
if (i < 0) {
log_error("---%s %d---", __func__, __LINE__);
len = total_len;
} else {
interface_num++;
len += i;
pBuf += i;
have_find_valid_class = true;
}
} else if ((interface->bInterfaceClass == 0xff) &&
(interface->bInterfaceSubClass == USB_CLASS_ADB)) {
i = _usb_adb_parser(host_dev, interface_num, pBuf);
if (i < 0) {
log_error("---%s %d---", __func__, __LINE__);
len = total_len;
} else {
interface_num++;
len += i;
pBuf += i;
have_find_valid_class = true;
}
} else if ((device_desc->idVendor == 0x18d1) &&
((device_desc->idProduct & 0x2d00) == 0x2d00)) {
i = _usb_aoa_parser(host_dev, interface_num, pBuf);
if (i < 0) {
log_error("---%s %d---", __func__, __LINE__);
len = total_len;
} else {
interface_num++;
len += i;
pBuf += i;
have_find_valid_class = true;
}
} else if (interface->bInterfaceClass == USB_CLASS_HID) {
i = _usb_hid_parser(host_dev, interface_num, pBuf);
if (i < 0) {
log_error("---%s %d---", __func__, __LINE__);
len = total_len;
} else {
interface_num++;
len += i;
pBuf += i;
have_find_valid_class = true;
}
} else if ((interface->bNumEndpoints == 3) &&
(interface->bInterfaceClass == 0xff || interface->bInterfaceClass == 0x06)) {
i = _usb_adb_interface_ptp_mtp_parse(host_dev, interface_num, pBuf);
if (i < 0) {
log_error("---%s %d---", __func__, __LINE__);
len = total_len;
} else {
interface_num++;
len += i;
pBuf += i;
}
have_find_valid_class = true;
} else if ((interface->bInterfaceClass == 0xff) &&
(interface->bInterfaceSubClass == 0xff)) {
i = _usb_aoa_parser(host_dev, interface_num, pBuf);
if (i < 0) {
log_error("---%s %d---", __func__, __LINE__);
len = total_len;
} else {
interface_num++;
len += i;
pBuf += i;
}
have_find_valid_class = true;
} else {
log_info("find unsupport [class %x subClass %x] @ interface %d",
interface->bInterfaceClass,
interface->bInterfaceSubClass,
interface_num);
len += USB_DT_INTERFACE_SIZE;
pBuf += USB_DT_INTERFACE_SIZE;
}
} else {
/* log_error("unknown section %d %d", len, pBuf[0]); */
if (pBuf[0]) {
len += pBuf[0];
pBuf += pBuf[0];
} else {
len = total_len;
}
}
}
log_debug("len %d total_len %d", len, total_len);
return !have_find_valid_class;
}
/* --------------------------------------------------------------------------*/
/**
* @brief usb_host_suspend
*
* @param usb
*
* @return
*/
/* --------------------------------------------------------------------------*/
void usb_host_suspend(const usb_dev usb_id)
{
usb_h_entry_suspend(usb_id);
}
void usb_host_resume(const usb_dev usb_id)
{
usb_h_resume(usb_id);
}
static u32 _usb_host_mount(const usb_dev usb_id, u32 retry, u32 reset_delay, u32 mount_timeout)
{
u32 ret = DEV_ERR_NONE;
struct usb_host_device *host_dev = &host_devices[usb_id];
struct usb_private_data *private_data = &host_dev->private_data;
for (int i = 0; i < retry; i++) {
usb_h_sie_init(usb_id);
#if defined(FUSB_MODE) && FUSB_MODE
usb_write_power(usb_id, BIT(6)); //full-speed
#elif defined(FUSB_MODE) && (FUSB_MODE == 0)
usb_write_power(usb_id, BIT(5) | BIT(6)); //high-speed
#else
#error "USB_SPEED_MODE not defined"
#endif
ret = usb_host_init(usb_id, reset_delay, mount_timeout);
if (ret) {
reset_delay += 10;
continue;
}
void *const ep0_dma = usb_h_get_ep_buffer(usb_id, 0);
usb_set_dma_taddr(usb_id, 0, ep0_dma);
usb_sie_enable(usb_id);//enable sie intr
usb_mdelay(reset_delay);
/**********get device descriptor*********/
struct usb_device_descriptor device_desc;
private_data->usb_id = usb_id;
private_data->status = 0;
private_data->devnum = 0;
private_data->ep0_max_packet_size = 8;
ret = usb_get_device_descriptor(host_dev, &device_desc);
/**********set address*********/
usb_mdelay(20);
u8 devnum = rand32() % 16 + 1;
ret = set_address(host_dev, devnum);
check_usb_mount(ret);
private_data->devnum = devnum ;
/**********get device descriptor*********/
usb_mdelay(20);
ret = usb_get_device_descriptor(host_dev, &device_desc);
check_usb_mount(ret);
private_data->ep0_max_packet_size = device_desc.bMaxPacketSize0;
/**********get config descriptor*********/
struct usb_config_descriptor cfg_desc;
ret = get_config_descriptor(host_dev, &cfg_desc, USB_DT_CONFIG_SIZE);
check_usb_mount(ret);
#if USB_H_MALLOC_ENABLE
u8 *desc_buf = zalloc(cfg_desc.wTotalLength + 16);
ASSERT(desc_buf, "desc_buf");
#else
u8 desc_buf[128] = {0};
cfg_desc.wTotalLength = min(sizeof(desc_buf), cfg_desc.wTotalLength);
#endif
ret = get_config_descriptor(host_dev, desc_buf, cfg_desc.wTotalLength);
check_usb_mount(ret);
/**********set configuration*********/
ret = set_configuration(host_dev);
/* printf_buf(desc_buf, cfg_desc.wTotalLength); */
ret |= usb_descriptor_parser(host_dev, desc_buf, cfg_desc.wTotalLength, &device_desc);
#if USB_H_MALLOC_ENABLE
log_info("free:desc_buf= %x\n", desc_buf);
free(desc_buf);
#endif
check_usb_mount(ret);
for (int itf = 0; itf < MAX_HOST_INTERFACE; itf++) {
if (host_dev->interface_info[itf]) {
host_dev->interface_info[itf]->ctrl->set_power(host_dev, 1);
}
}
break;//succ
}
if (ret) {
goto __exit_fail;
}
private_data->status = 1;
return DEV_ERR_NONE;
__exit_fail:
printf("usb_probe fail");
private_data->status = 0;
usb_sie_close(usb_id);
return ret;
}
static int usb_event_notify(const struct usb_host_device *host_dev, u32 ev)
{
const usb_dev id = host_device2id(host_dev);
struct sys_event event;
static u32 bmUsbEvent[USB_MAX_HW_NUM];
u8 have_post_event = 0;
u8 no_send_event = 0;
if (ev == 0) {
event.u.dev.event = DEVICE_EVENT_IN;
} else if (ev == 1) {
event.u.dev.event = DEVICE_EVENT_CHANGE;
} else {
event.u.dev.event = DEVICE_EVENT_OUT;
goto __usb_event_out;
}
for (u8 i = 0; i < MAX_HOST_INTERFACE; i++) {
no_send_event = 0;
event.u.dev.value = 0;
if (host_dev->interface_info[i]) {
switch (host_dev->interface_info[i]->ctrl->interface_class) {
#if TCFG_UDISK_ENABLE
case USB_CLASS_MASS_STORAGE:
if (have_post_event & BIT(0)) {
no_send_event = 1;
} else {
have_post_event |= BIT(0);
}
if (id == 0) {
event.u.dev.value = (int)"udisk0";
} else {
event.u.dev.value = (int)"udisk1";
}
bmUsbEvent[id] |= BIT(0);
break;
#endif
#if TCFG_ADB_ENABLE
case USB_CLASS_ADB:
if (have_post_event & BIT(1)) {
no_send_event = 1;
} else {
have_post_event |= BIT(1);
}
if (id == 0) {
event.u.dev.value = (int)"adb0";
} else {
event.u.dev.value = (int)"adb1";
}
bmUsbEvent[id] |= BIT(1);
break;
#endif
#if TCFG_AOA_ENABLE
case USB_CLASS_AOA:
if (have_post_event & BIT(2)) {
no_send_event = 1;
} else {
have_post_event |= BIT(2);
}
if (id == 0) {
event.u.dev.value = (int)"aoa0";
} else {
event.u.dev.value = (int)"aoa1";
}
bmUsbEvent[id] |= BIT(2);
break;
#endif
#if TCFG_HID_HOST_ENABLE
case USB_CLASS_HID:
if (have_post_event & BIT(3)) {
no_send_event = 1;
} else {
have_post_event |= BIT(3);
}
if (id == 0) {
event.u.dev.value = (int)"hid0";
} else {
event.u.dev.value = (int)"hid1";
}
bmUsbEvent[id] |= BIT(3);
break;
#endif
#if TCFG_HOST_AUDIO_ENABLE
case USB_CLASS_AUDIO:
if (have_post_event & BIT(4)) {
no_send_event = 1;
} else {
have_post_event |= BIT(4);
}
if (id == 0) {
event.u.dev.value = (int)"audio0";
} else {
event.u.dev.value = (int)"audio1";
}
bmUsbEvent[id] |= BIT(4);
break;
#endif
}
if (!no_send_event && event.u.dev.value) {
log_info("event %x interface %x class %x %s",
event.u.dev.event, i,
host_dev->interface_info[i]->ctrl->interface_class,
(const char *)event.u.dev.value);
/* printf("usb_host_mount notify >>>>>>>>>>>\n"); */
event.arg = (void *)DEVICE_EVENT_FROM_USB_HOST;
event.type = SYS_DEVICE_EVENT;
sys_event_notify(&event);
}
}
}
__usb_event_out:
if (event.u.dev.event == DEVICE_EVENT_OUT) {
for (int i = 0; i < 32; i++) {
if (bmUsbEvent[id] & BIT(i)) {
switch (i) {
#if TCFG_UDISK_ENABLE
case 0:
if (id == 0) {
event.u.dev.value = (int)"udisk0";
} else {
event.u.dev.value = (int)"udisk1";
}
break;
#endif
#if TCFG_ADB_ENABLE
case 1:
if (id == 0) {
event.u.dev.value = (int)"adb0";
} else {
event.u.dev.value = (int)"adb1";
}
break;
#endif
#if TCFG_AOA_ENABLE
case 2:
if (id == 0) {
event.u.dev.value = (int)"aoa0";
} else {
event.u.dev.value = (int)"aoa1";
}
break;
#endif
#if TCFG_HID_HOST_ENABLE
case 3:
if (id == 0) {
event.u.dev.value = (int)"hid0";
} else {
event.u.dev.value = (int)"hid1";
}
break;
#endif
#if TCFG_HOST_AUDIO_ENABLE
case 4:
if (id == 0) {
event.u.dev.value = (int)"audio0";
} else {
event.u.dev.value = (int)"audio1";
}
break;
#endif
default:
event.u.dev.value = 0;
break;
}
bmUsbEvent[id] &= ~BIT(i);
if (event.u.dev.value) {
event.type = SYS_DEVICE_EVENT;
event.arg = (void *)DEVICE_EVENT_FROM_USB_HOST;
have_post_event = 1;
sys_event_notify(&event);
}
}
}
}
if (have_post_event) {
return DEV_ERR_NONE;
} else {
return DEV_ERR_UNKNOW_CLASS;
}
}
const char *usb_host_valid_class_to_dev(const usb_dev id, u32 usbclass)
{
#if USB_MAX_HW_NUM > 1
const usb_dev usb_id = id;
#else
const usb_dev usb_id = 0;
#endif
struct usb_host_device *host_dev = &host_devices[usb_id];
u32 itf_class;
for (int i = 0; i < MAX_HOST_INTERFACE; i++) {
if (host_dev->interface_info[i] &&
host_dev->interface_info[i]->ctrl) {
itf_class = host_dev->interface_info[i]->ctrl->interface_class;
if (itf_class == usbclass) {
switch (itf_class) {
case USB_CLASS_MASS_STORAGE:
if (usb_id == 0) {
return "udisk0";
} else if (usb_id == 1) {
return "udisk1";
}
break;
case USB_CLASS_ADB:
if (usb_id == 0) {
return "adb0";
} else if (usb_id == 1) {
return "adb1";
}
break;
case USB_CLASS_AOA:
if (usb_id == 0) {
return "aoa0";
} else if (usb_id == 1) {
return "aoa1";
}
break;
case USB_CLASS_HID:
if (usb_id == 0) {
return "hid0";
} else if (usb_id == 1) {
return "hid1";
}
break;
}
}
}
}
return NULL;
}
/* --------------------------------------------------------------------------*/
/**
* @brief usb_host_mount
*
* @param usb
*
* @return
*/
/* --------------------------------------------------------------------------*/
u32 usb_host_mount(const usb_dev id, u32 retry, u32 reset_delay, u32 mount_timeout)
{
#if USB_MAX_HW_NUM > 1
const usb_dev usb_id = id;
#else
const usb_dev usb_id = 0;
#endif
u32 ret;
struct usb_host_device *host_dev = &host_devices[usb_id];
memset(host_dev, 0, sizeof(*host_dev));
host_dev->private_data.usb_id = id;
usb_sem_init(host_dev);
usb_h_isr_reg(usb_id, 1, 0);
ret = _usb_host_mount(usb_id, retry, reset_delay, mount_timeout);
usb_otg_resume(usb_id); //打开usb host之后恢复otg检测
if (ret) {
goto __exit_fail;
}
return usb_event_notify(host_dev, 0);
__exit_fail:
usb_sie_disable(usb_id);
usb_sem_del(host_dev);
return ret;
}
static u32 _usb_host_unmount(const usb_dev usb_id)
{
struct usb_host_device *host_dev = &host_devices[usb_id];
struct usb_private_data *private_data = &host_dev->private_data;
private_data->status = 0;
usb_sem_post(host_dev);//拔掉设备时,让读写线程快速释放
for (u8 i = 0; i < MAX_HOST_INTERFACE; i++) {
if (host_dev->interface_info[i] && host_dev->interface_info[i]->ctrl->set_power) {
host_dev->interface_info[i]->ctrl->set_power(host_dev, 0);
host_dev->interface_info[i] = NULL;
}
}
usb_sie_close(usb_id);
return DEV_ERR_NONE;
}
/* --------------------------------------------------------------------------*/
/**
* @brief usb_host_unmount
*
* @param usb
*
* @return
*/
/* --------------------------------------------------------------------------*/
/* u32 usb_host_unmount(const usb_dev usb_id, char *device_name) */
u32 usb_host_unmount(const usb_dev id)
{
#if USB_MAX_HW_NUM > 1
const usb_dev usb_id = id;
#else
const usb_dev usb_id = 0;
#endif
u32 ret;
struct usb_host_device *host_dev = &host_devices[usb_id];
struct sys_event event;
#if (TCFG_UDISK_ENABLE && UDISK_READ_512_ASYNC_ENABLE)
_usb_stor_async_wait_sem(host_dev);
#endif
ret = _usb_host_unmount(usb_id);
if (ret) {
goto __exit_fail;
}
usb_sem_del(host_dev);
/* printf("usb_host_unmount notify >>>>>>>>>>>\n"); */
usb_event_notify(host_dev, 2);
return DEV_ERR_NONE;
__exit_fail:
return ret;
}
u32 usb_host_remount(const usb_dev id, u32 retry, u32 delay, u32 ot, u8 notify)
{
#if USB_MAX_HW_NUM > 1
const usb_dev usb_id = id;
#else
const usb_dev usb_id = 0;
#endif
u32 ret;
struct sys_event event;
ret = _usb_host_unmount(usb_id);
if (ret) {
goto __exit_fail;
}
struct usb_host_device *host_dev = &host_devices[usb_id];
os_sem_set(host_dev->sem, 0);
ret = _usb_host_mount(usb_id, retry, delay, ot);
if (ret) {
goto __exit_fail;
}
if (notify) {
struct usb_host_device *host_dev = &host_devices[usb_id];
usb_event_notify(host_dev, 1);
}
return DEV_ERR_NONE;
__exit_fail:
return ret;
}
int usb_host_force_reset(const usb_dev usb_id)
{
//预留以后加上hub的处理
usb_h_force_reset(usb_id);
return 0;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,145 +0,0 @@
/**@file usb_storage.h
* @brief usb_storage驱动头文件做主机
* @details 结构体声明,功能函数声明
* @author jieli
* @date 2021-8-1
* @version V1.0
* @copyright Copyright(c)2010-2021 珠海市杰理科技股份有限公司
*********************************************************
* @attention
* 硬件平台AC695N
* SDK版本AC695N_V1.0.0_SDK
* @修改日志:
* <table>
* <tr><th>Date <th>Version <th>Author <th>Description
* <tr><td>2021-8-1 <td>1.0 <td>jieli <td>创建初始版本
* </table>
*
*********************************************************
*/
#ifndef __USB_STORAGE_H__
#define __USB_STORAGE_H__
#include "system/task.h"
#include "device/device.h"
#include "usb/scsi.h"
#include "usb_bulk_transfer.h"
#include "usb/host/usb_host.h"
/* u盘预读功能配置, 二选一
* 当两种方式都不使能,则表示不开启预读 */
#define UDISK_READ_BIGBLOCK_ASYNC_ENABLE 0 //使能大扇区预读方式(不需要额外buf,速度比512预读慢10%)
#define UDISK_READ_512_ASYNC_ENABLE 0 //使能512Byte预读方式(需要额外的512byte buffer,速度比大扇区预读快10%)
/****************************/
#define UDISK_READ_ASYNC_BLOCK_NUM (16) //预读扇区数
//****************************youning***********************************----->
#define UDISK_READ_AHEAD_ENABLE 0 //使能U盘预读功能
#define UDISK_READ_AHEAD_BLOCK_NUM 16 //U盘预读扇区数量
#define check_usb_read_ahead(ret) \
if(ret < 0) {\
log_error("func:%s,line:%d,lba:%d,ret:%d\n", __func__, __LINE__, lba, ret);\
goto __exit;\
} //检查函数返回值0:正确 非0:错误
//****************************youning***********************************<-----
/**@enum usb_sta
* @brief USB设备当前状态
*/
typedef enum usb_sta {
DEV_IDLE = 0, ///<空闲状态
DEV_INIT, ///<初始化
DEV_OPEN, ///<开启
DEV_READ, ///<读操作
DEV_WRITE, ///<写操作
DEV_CLOSE, ///<关闭
DEV_SUSPEND, ///<挂起
} USB_STA ;
/**@struct udisk_end_desc
* @brief U盘端点描述结构体
*
*/
struct udisk_end_desc {
u8 host_epout; ///<主机端点输出
u8 target_epout; ///<目标端点输出
u8 host_epin; ///<主机端点输入
u8 target_epin; ///<目标端点输入
#if defined(FUSB_MODE) && FUSB_MODE == 0
u16 rxmaxp; ///<接收最大端点号
u16 txmaxp; ///<发送最大端点号
#endif
};
#define ENABLE_DISK_HOTPLUG 0
/**@struct mass_storage
* @brief mass_storage协议所使用的相关变量
*/
struct mass_storage {
OS_MUTEX mutex; ///<互斥量
struct usb_scsi_cbw cbw; ///<CBW指令结构体
struct usb_scsi_csw csw; ///<CSW状态结构体
struct request_sense_data sense; ///<请求数据检查结构体
char *name; ///<设备名字
struct read_capacity_data capacity[2]; ///<读取数据的能力,包含数据块的编号、大小
u8 lun; ///<最大逻辑单元地址
u8 curlun; ///<当前逻辑单元地址
u8 dev_status; ///<设备状态
u8 suspend_cnt; ///<挂起状态计数器
u8 read_only; ///<只读标志位
u32 remain_len; ///<剩余的包长度
u32 prev_lba; ///<上一次扇区
#if (UDISK_READ_BIGBLOCK_ASYNC_ENABLE || UDISK_READ_512_ASYNC_ENABLE)
u8 async_en; ///<异步模式使能
u8 need_send_csw; ///<需要发送csw标志位
u8 *udisk_512_buf; ///<U盘512K大小BUFFER指针
u32 async_prev_lba; ///<异步模式上一次地址
#endif
#if UDISK_READ_AHEAD_ENABLE
u8 *udisk_read_ahead_buf; ///<U盘512byte大小BUFFER指针
u32 udisk_read_ahead_lba_last; ///<异步模式上一次地址
#endif
#if ENABLE_DISK_HOTPLUG
u8 media_sta_cur; ///<当前媒介状态 //for card reader, card removable
u8 media_sta_prev; ///<上次媒介状态
int test_unit_ready_tick; ///<测试准备标记
#endif
};
enum usb_async_mode {
BULK_ASYNC_MODE_EXIT = 0, ///<退出异步模式
BULK_ASYNC_MODE_SEM_PEND, ///<异步预读等待信号量
};
#define MASS_LBA_INIT (-2)
/**@brief 使用mass_storage协议对大容量存储设备进行解析端点配置
* @param[in] usb_host_device定义的结构体指针
* @param[in] interface_num 接口号
* @param[in] *pBuf 指向BUFFER的指针
* @return len BUFFER的长度
* @par 示例:
* @code
* usb_msd_parser(host_dev,interface_num,pBuf);
* @encode
*/
int usb_msd_parser(struct usb_host_device *host_dev, u8 interface_num, const u8 *pBuf);
/**@brief 异步模式等待信号量
* @param[in] usb_host_device定义的结构体指针
* @return 0:成功
* @par 示例:
* @code
* _usb_stor_async_wait_sem(host_dev);
* @encode
*/
int _usb_stor_async_wait_sem(struct usb_host_device *host_dev);
#endif