GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (c) LOTUS. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "usb3_drv.h"
|
||||
#include "usb3_pcd.h"
|
||||
#include "usb3_prot.h"
|
||||
#include "onchiprom.h"
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#define USTART 0xFA
|
||||
#define UHEAD 0xFE
|
||||
#define UDATA 0xDA
|
||||
#define UTAIL 0xED
|
||||
#define UCMD 0XAB
|
||||
#define UREQ 0XFB
|
||||
|
||||
#define TX_STATE_BUFFER 500
|
||||
#define TX_STATE_LIMIT 400
|
||||
#define BUFFER_SIZE 512
|
||||
|
||||
char u_ack[2] = {0xAA, '\0'};
|
||||
char u_nak[2] = {0x55, '\0'};
|
||||
char tx_state[TX_STATE_BUFFER] = {0, 0x55, 0};
|
||||
static phys_addr_t rx_addr;
|
||||
static unsigned int rx_length;
|
||||
int usb_connected;
|
||||
int usb_out_open = 0;
|
||||
|
||||
void usb3_bulk_out_transfer_cmd(void *dev)
|
||||
{
|
||||
usb3_pcd_t *pcd = (usb3_pcd_t *)dev;
|
||||
usb3_pcd_ep_t *ep = &pcd->out_ep;
|
||||
usb3_pcd_req_t *req = &ep->req;
|
||||
|
||||
memset(pcd->ss_bulk_buf, 0x0, USB3_BULK_BUF_SIZE);
|
||||
|
||||
req->length = ep->maxpacket;
|
||||
req->bufdma = pcd->ss_bulk_buf;
|
||||
req->complete = usb3_handle_protocol;
|
||||
usb3_ep_start_transfer(pcd, ep);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void usb3_handle_data(void *dev)
|
||||
{
|
||||
usb3_pcd_t *pcd = NULL;
|
||||
usb3_pcd_ep_t *ep = NULL;
|
||||
usb3_pcd_req_t *req = NULL;
|
||||
if (dev == NULL)
|
||||
return;
|
||||
|
||||
pcd = (usb3_pcd_t *)dev;
|
||||
ep = &pcd->out_ep;
|
||||
req = &ep->req;
|
||||
|
||||
if (req->actual > rx_length)
|
||||
req->actual = rx_length;
|
||||
|
||||
rx_addr += req->actual;
|
||||
rx_length -= req->actual;
|
||||
|
||||
if (rx_length > 0) {
|
||||
usb3_bulk_out_transfer_data(dev);
|
||||
} else {
|
||||
usb3_bulk_out_transfer_cmd(dev);
|
||||
}
|
||||
}
|
||||
|
||||
int usb3_bulk_out_transfer_data(void *dev)
|
||||
{
|
||||
usb3_pcd_t *pcd = NULL;
|
||||
usb3_pcd_ep_t *ep = NULL;
|
||||
usb3_pcd_req_t *req = NULL;
|
||||
if (dev == NULL)
|
||||
return USB_PROCESS_ERR;
|
||||
|
||||
pcd = (usb3_pcd_t *)dev;
|
||||
ep = &pcd->out_ep;
|
||||
req = &ep->req;
|
||||
|
||||
/* For DWC3 controller,If CHN=0 and HWO=0 for the TRB, this field represents the total remaining Buffer
|
||||
* Descriptor buffer size in bytes. Valid Range: 0 bytes to (16 MB - 1 byte).
|
||||
* The hardware decrements this field to represent the remaining buffer size after data is
|
||||
* transferred.
|
||||
* Note: for bulk transfer, max length = 16MB - maxpacket;
|
||||
* */
|
||||
if (rx_length >= (USB3_DSCSTS_XFRCNT_MAX - ep->maxpacket)) {
|
||||
req->length = USB3_DSCSTS_XFRCNT_MAX - ep->maxpacket;
|
||||
} else {
|
||||
req->length = rx_length;
|
||||
}
|
||||
|
||||
req->bufdma = (unsigned char *)rx_addr;
|
||||
req->complete = usb3_handle_data;
|
||||
|
||||
usb3_ep_start_transfer(pcd, ep);
|
||||
|
||||
return USB_NO_ERR;
|
||||
}
|
||||
|
||||
void udc_puts(const char *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return;
|
||||
|
||||
if (strlen(tx_state) + strlen(s) > TX_STATE_LIMIT)
|
||||
(void)memset(tx_state, 0, TX_STATE_BUFFER);
|
||||
|
||||
if (strlen(s) > TX_STATE_BUFFER) {
|
||||
return;
|
||||
} else {
|
||||
if (usb_out_open == 1) {
|
||||
strcat(tx_state, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef int (*USB3_HANDLE_REQUEST)(unsigned char * const buff, unsigned int *bufflen);
|
||||
USB3_HANDLE_REQUEST handle_request = NULL;
|
||||
void set_usb3_call_back_func(USB3_HANDLE_REQUEST func)
|
||||
{
|
||||
handle_request = func;
|
||||
}
|
||||
|
||||
void usb3_handle_protocol(void *dev)
|
||||
{
|
||||
usb3_pcd_t *pcd = (usb3_pcd_t *)dev;
|
||||
int ret;
|
||||
char *buf = (char *)pcd->ss_bulk_buf;
|
||||
|
||||
if (buf[0] == USTART) {
|
||||
usb3_bulk_out_transfer_cmd(pcd);
|
||||
usb3_bulk_in_transfer(dev, u_ack);
|
||||
} else if (buf[0] == UHEAD) {
|
||||
/*left shift 8/16/24 bit [5][6][7][8]:buffer number */
|
||||
rx_addr = (buf[5] << 24) | (buf[6] << 16) | (buf[7] << 8) | (buf[8]);
|
||||
/*left shift 8/16/24 bit [1][2][3][4]:buffer number */
|
||||
rx_length = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | (buf[4]);
|
||||
if (rx_addr == rx_length) {
|
||||
usb3_bulk_out_transfer_cmd(pcd);
|
||||
usb_connected = 1;
|
||||
usb_out_open = 1;
|
||||
} else {
|
||||
usb3_bulk_out_transfer_data(pcd);
|
||||
}
|
||||
usb3_bulk_in_transfer(dev, u_ack);
|
||||
return;
|
||||
} else if(buf[0]==UCMD) {
|
||||
strcat(tx_state, " ");
|
||||
|
||||
|
||||
usb_out_open = 1;
|
||||
ret = run_command(buf + 0x3, 0);
|
||||
if (ret) {
|
||||
usb3_bulk_in_transfer(dev, "[EOT](ERROR)\r\n");
|
||||
} else {
|
||||
strcat(tx_state, "[EOT](OK)\r\n");
|
||||
usb3_bulk_out_transfer_cmd(pcd);
|
||||
usb3_bulk_in_transfer(dev, tx_state);
|
||||
memset(tx_state, 0, TX_STATE_BUFFER);
|
||||
}
|
||||
} else if (buf[0] == UTAIL) {
|
||||
if (rx_length > 0) {
|
||||
usb3_bulk_out_transfer_cmd(pcd);
|
||||
usb3_bulk_in_transfer(dev, u_nak);
|
||||
} else {
|
||||
usb3_bulk_in_transfer(dev, u_ack);
|
||||
usb3_bulk_out_transfer_cmd(pcd);
|
||||
}
|
||||
} else if (buf[0] == UREQ) {
|
||||
usb_out_open = 0;
|
||||
if (handle_request != NULL) {
|
||||
usb3_pcd_ep_t *ep = &pcd->in_ep;
|
||||
usb3_pcd_req_t *req = &ep->req;
|
||||
|
||||
memset(req->bufdma, 0, BUFFER_SIZE);
|
||||
req->length = 0;
|
||||
ret = (*handle_request)(req->bufdma, &req->length);
|
||||
|
||||
req->complete = usb_tx_status_complete;
|
||||
usb3_ep_start_transfer(pcd, ep);
|
||||
|
||||
usb3_bulk_out_transfer_cmd(pcd);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user