📄 usbhost.c
字号:
Start_USB_Host_Task(USBH_DONE, rstatus);
}
else if (usb_host.state == CNTRL_LAST)
Start_USB_Host_Task(USBH_DONE, rstatus);
/* Didn't expect this */
else
Start_USB_Host_Task(USBH_ERROR, rstatus);
}
/***********************************************************************/
static void ProcessIN_ISR(Uint32 rstatus)
{
int i, bytecnt, room_left;
volatile PIPE_STRUCT *pipe;
BDT_STRUCT *bdt;
pipe = usb_host.cur_pipe;
/* Toggle on success */
pipe->DATAx ^= BDT_PID_DATA01;
/* Get the number of bytes received */
bdt = pipe->bdt;
bytecnt = bdt->BC;
/*
* Transfer block of data just read from pipe->pipe_bf to io_bf.
* If more data received that there is room for, ignore extra bytes
* but maintain proper count. ("room_left" can go negative.)
*/
room_left = pipe->length - pipe->count;
if (room_left > bytecnt)
room_left = bytecnt;
if (room_left > 0) {
Uint8 *to, *from;
from = pipe->pipe_bf;
to = &pipe->io_bf[pipe->count];
for (i = 0; i < room_left; i++)
*to++ = *from++;
}
/* Maintain count of total number of bytes received */
pipe->count += bytecnt;
if (bytecnt == pipe->pksize) {
if ((pipe->count >= pipe->length) &&
((pipe->pipe_type == PIPE_INT) || MassStorage.Config))
{
/* All done if INTERRUPT endpoint or Mass-Storage-Class Device */
Start_USB_Host_Task(USBH_DONE, rstatus);
return;
}
/* More IN data coming; set up next transfer */
bdt = (BDT_STRUCT *)(USB_BDT_PAGE | usb_host.even_odd_IN);
pipe->bdt = bdt;
usb_host.even_odd_IN ^= BDT_ODD_EVEN_BIT;
usb_host.nxt_bdt.PID = BDT_PID_OWN | pipe->DATAx;
usb_host.nxt_bdt.BC = pipe->pksize;
usb_host.nxt_bdt.ADDRL = (Uint32)pipe->pipe_bf;
usb_host.nxt_bdt.ADDRH = (Uint32)pipe->pipe_bf >> 8;
//DEBUG_LOG(USBH_IN, rstatus);
}
else {
/* Finished with IN transfer */
if (pipe->EP) {
/* All done if not CNTRL endpoint */
Start_USB_Host_Task(USBH_DONE, rstatus);
return;
}
/* Send status (no data OUT) transfer to finish Control */
usb_host.state = CNTRL_LAST;
bdt = (BDT_STRUCT *)(USB_BDT_PAGE | usb_host.even_odd_OUT);
pipe[0].bdt = bdt;
usb_host.even_odd_OUT ^= BDT_ODD_EVEN_BIT;
usb_host.nxt_bdt.PID = BDT_PID_OWN | BDT_PID_DATA01;
usb_host.nxt_bdt.BC = 0;
usb_host.nxt_bdt.ADDRL = 0;
usb_host.nxt_bdt.ADDRH = 0;
pipe[0].pid_ep = VUSB_TOKEN_OUT;
DEBUG_LOG(USBH_OUT0, rstatus);
}
/*
* Read next packet (BULK or CNTRL) or send STATUS (zero length)
* packet (CNTRL only - completes handshake)
*/
bdt->PID = usb_host.nxt_bdt.PID;
bdt->BC = usb_host.nxt_bdt.BC;
bdt->ADDRL = usb_host.nxt_bdt.ADDRL;
bdt->ADDRH = usb_host.nxt_bdt.ADDRH;
*regEP0CTL = pipe->type;
*regADDR = usb_host.USB_addr;
*regTOKEN = pipe->pid_ep;
}
/***********************************************************************/
static void ProcessOUT_ISR(Uint32 rstatus)
{
int i, left_to_send;
volatile PIPE_STRUCT *pipe;
BDT_STRUCT *bdt;
pipe = usb_host.cur_pipe;
/* Toggle on success */
pipe->DATAx ^= BDT_PID_DATA01;
pipe->count += pipe->pksize;
if (pipe->count >= pipe->length)
pipe->count = pipe->length;
left_to_send = pipe->length - pipe->count;
if (left_to_send > pipe->pksize)
left_to_send = pipe->pksize;
/*
* Need to send another packet if more data left to send or
* if non-control endpoint had transfer that was an exact multiple
* of the packet size.
*/
if (left_to_send ||
(pipe->EP && (pipe->length % pipe->pksize) == 0))
{
if (left_to_send) {
/* Transfer block of data from io_buff to pipe->pipe_bf */
for (i = 0; i < left_to_send; i++)
pipe->pipe_bf[i] = pipe->io_bf[pipe->count + i];
}
else {
/* Final zero-length data packet to finish transfer */
usb_host.state = PROCESS_NUL;
}
bdt = (BDT_STRUCT *)(USB_BDT_PAGE | usb_host.even_odd_OUT);
pipe->bdt = bdt;
usb_host.even_odd_OUT ^= BDT_ODD_EVEN_BIT;
usb_host.nxt_bdt.PID = BDT_PID_OWN | pipe->DATAx;
usb_host.nxt_bdt.BC = left_to_send;
usb_host.nxt_bdt.ADDRL = (Uint32)pipe->pipe_bf;
usb_host.nxt_bdt.ADDRH = (Uint32)pipe->pipe_bf >> 8;
DEBUG_LOG(USBH_OUT, rstatus);
}
else {
/* Finished with OUT transfer */
if (pipe->EP || (pipe->length % pipe->pksize)) {
/* Done if not CNTRL ep or final packet was not filled */
Start_USB_Host_Task(USBH_DONE, rstatus);
return;
}
/* Send status (no data IN) transfer to finish Control */
usb_host.state = CNTRL_LAST;
bdt = (BDT_STRUCT *)(USB_BDT_PAGE | usb_host.even_odd_IN);
pipe[0].bdt = bdt;
usb_host.even_odd_IN ^= BDT_ODD_EVEN_BIT;
usb_host.nxt_bdt.PID = BDT_PID_OWN | BDT_PID_DATA01;
usb_host.nxt_bdt.BC = 0;
usb_host.nxt_bdt.ADDRL = 0;
usb_host.nxt_bdt.ADDRH = 0;
pipe[0].pid_ep = VUSB_TOKEN_IN;
DEBUG_LOG(USBH_IN0, rstatus);
}
/*
* Send next packet (BULK or CNTRL) or read STATUS (zero length)
* packet (CNTRL only - completes handshake)
*/
bdt->PID = usb_host.nxt_bdt.PID;
bdt->BC = usb_host.nxt_bdt.BC;
bdt->ADDRL = usb_host.nxt_bdt.ADDRL;
bdt->ADDRH = usb_host.nxt_bdt.ADDRH;
*regEP0CTL = pipe->type;
*regADDR = usb_host.USB_addr;
*regTOKEN = pipe->pid_ep;
}
/*************************************************************************/
/**************************************************************************
*
* Function Name: Start_USB_Host_Task
*
**************************************************************************/
static void Start_USB_Host_Task(Uint8 code, Uint32 rstatus)
{
STATUS ts_status;
usb_host.state = NO_REQUEST;
if (USBCancelHost) {
code = USBH_HCAN;
USBCancelHost = FALSE;
}
/* Mask off all USB interrupts */
*regINT_ENB = 0;
DEBUG_LOG(code, rstatus);
usb_host.code_status_error[usb_host.inx] = ((Uint32)code << 24) | rstatus;
if (++usb_host.inx == CODE_CNT)
usb_host.inx = 0;
ASSERT(usb_host.inx != usb_host.outx);
usb_host.tick++;
if (usb_host.sleeping) {
/* Signal the USBH task semaphore. */
ts_status = TaskSemSignal(USBHSemaphore);
ASSERT(ts_status >= 0);
usb_host.sleeping = FALSE;
}
}
/**************************************************************************
* Function Name : USBHostPrologue
*
* Initialize the USB 1.1 hardware and data structures.
**************************************************************************/
void USBHostPrologue(void)
{
int i;
Uint8 *bbase;
Uint32 startHI, endHI;
STATUS status;
void (*old_lisr)(int);
/*
* I/O buffers must all be in the same 64K region of memory
* since the high-order 16 bits can never change. Over-allocate
* and pick a safe region on a 32-byte boundary.
*/
bbase = (Uint8 *)MEM32_ALIGN(abuffers);
startHI = (Uint32)bbase >> 16;
endHI = (Uint32)(&bbase[BFSIZE]) >> 16;
if (startHI != endHI) {
bbase = (Uint8 *)(endHI << 16);
startHI = (Uint32)bbase >> 16;
endHI = (Uint32)(&bbase[BFSIZE]) >> 16;
ASSERT(startHI == endHI);
}
/* Lock in high 16-bits of address */
*regBUFBASEL = (Uint32)bbase >> 16;
*regBUFBASEH = (Uint32)bbase >> 24;
/* Plug buffer address into pipe structures */
for (i = 0; i < PIPECNT; i++) {
pipe[i].setup_bf = NULL;
pipe[i].pipe_bf = &bbase[i * FS_BULK_PKCT_SIZE];
/* Force address into non-cachable memory region */
pipe[i].pipe_bf = (Uint8 *)((Uint32)pipe[i].pipe_bf | 0x20000000);
DBPRINT("pipe[%d].pipe_bf @ %x\n", i, (unsigned int)pipe[i].pipe_bf);
pipe[i].pksize = FS_BULK_PKCT_SIZE;
}
/* Only pipe[0] is a CNTRL endpoint with SETUP buffer */
pipe[0].setup_bf = &bbase[PIPECNT * FS_BULK_PKCT_SIZE];
DBPRINT("pipe[0].setup_bf @ %x\n", (unsigned int)pipe[0].setup_bf);
pipe[0].pksize = FS_CTRL_PKCT_SIZE;
usb_host.cur_pipe = NULL;
usb_host.USB_addr = 0;
usb_host.inx = 0;
usb_host.outx = 0;
usb_host.tick = 0;
usb_host.sleeping = TRUE;
usb_host.state = NO_REQUEST;
usb_host.reset_required = TRUE;
usb_host.DeviceReady = FALSE;
/* Create USB Host synchronization semaphore. */
USBHSemaphore = TaskSemCreate(0);
ASSERT(USBHSemaphore >= 0);
/* Create the USBH task for task-level (vs. ISR) code. */
TaskUSBH_ID = TASKCREATE(USB_Host_Task, USBHTASK_STACKSIZE, TaskUSBH_stack,
TaskUSBH_data, USBHTASK_PRIORITY, &TaskUSBH_arg,
"USB Host");
ASSERT(TaskUSBH_ID >= 0);
/* Register HISR */
status = NU_Create_HISR(&usbh_hisr, "USBH_HISR", USBH_hisr, 2, pHISRStack,
HISR_STACKSIZE);
ASSERT(status == NU_SUCCESS);
/* Install the LISR (Low Interrupt Service Routine). */
status = NU_Register_LISR(USB1_INTERRUPT_BIT, USBH_isr, &old_lisr);
ASSERT(status == NU_SUCCESS);
/* Initialize the USB hardware interface: disable EP0. */
*regEP0CTL = ENDPT_DISABLE;
/* Disable VUSB; mask and clear all interrupts */
*regCTL = 0;
*regINT_ENB = 0;
*regINT_STAT = 0xFF;
BZERO((Uint8 *)USB_BDT_PAGE, 16);
/* Zero out BDT ODD ping/pong bits, USB address and frame number */
*regCTL = CTRL_ODD_RST;
*regADDR = 0;
*regFRM_NUML = 0;
*regFRM_NUMH = 0;
usb_host.even_odd_OUT = BDT_OUT_BIT;
usb_host.even_odd_IN = BDT_IN_BIT;
/* Turn on the power (if FIRE4 board) */
ENABLE_USB_PWR
/* Enable interrupt */
*(volatile Uint32 *)EXMSK1A |= (1 << USB1_INTERRUPT_BIT);
}
/**************************************************************************
* T A S K L E V E L C O D E
**************************************************************************/
/* The USBH task - runs at high priority but normally sleeps. */
#ifndef CALL_PICTBRIDGE
#define CALL_PICTBRIDGE 1
#endif
#if CALL_PICTBRIDGE == 0 /* We're doing something other than pictbridge. */
FORWARD void mydoPictbridge(int in_pk_size, int out_pk_size, int intr_pk_size, int msec);
#define doPictbridge mydoPictbridge
#endif
static Sint32 USB_Host_Task(void *arg)
{
static TimeVal delay_enum = {1, 0};
static TimeVal delay_after_poweron = {8, 0};
int i, enumOK;
usb_host.DeviceReady = FALSE;
while (TRUE) {
PASSTHROUGH_BLOCK
/*
* If the printer is powered down (or was powered down and
* was just powered up) delay here to all maintenance task
* to get a job lock first.
*/
if (!g_powerOn || g_powerWasOff) {
g_powerWasOff = 0;
VPRINT("USB HOST: Printer powered off\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -