?? usbhost.c
字號:
#include "standard.h"
#include "nucleus.h"
#include "syt.h"
#include "usbhost.h"
#include "usbpriv.h"
#include "xtime.h"
#include "usbh.h"
//#define HOSTPRINTF logprintf
#define HOSTPRINTF if(0) printf
#define PIPE_IN 0x01
#define PIPE_OUT 0x02
#define PIPE_INT 0x03
#define USBHOST_PRIORITY 10
#define FS_CTRL_PKCT_SIZE 64
#define FS_BULK_PKCT_SIZE 64
/*
* Start-of-Frame byte-count-times threshold for starting a worst-case
* transfer followed by ACK or NAK without colliding with next SOF.
*/
#define SOF_THRESHOLD 100
#define PTPTASK_STACKSIZE 1024
#define USBHTASK_STACKSIZE 1024
/* Insertion delay - 100ms. min USB spec.: 9.1.2, #3, pg. 243 */
#define USB_DEBOUNCE_DELAY (105*1000)
/* Reset delay (TDRSTR) - 50ms. min, USB spec.: 7.1.7.5, pg. 153 */
#define USB_RESET_DELAY (55*1000)
/* Reset recovery time (TRSTRCY) - 10ms. min, USB spec.: 7.1.7.5, pg. 153 */
#define USB_RESET_RECOVERY_DELAY (15*1000)
#define MICROSECONDS_PER_TICK (1000000 / (NU_PLUS_Ticks_Per_Second))
#define MILLISECONDS_PER_TICK (1000 / (NU_PLUS_Ticks_Per_Second))
#define TICKS_PER_SECOND (NU_PLUS_Ticks_Per_Second)
/*
** Notes on time conversion:
** 1. We round microseconds to the nearest tick.
** 2. Max TaskSleep time is ~497 days.
*/
#define TIMEVAL_TO_TICKS(tvp) \
(tvp->secs * TICKS_PER_SECOND + \
(tvp->usecs + MICROSECONDS_PER_TICK/2) / MICROSECONDS_PER_TICK)
//typedef enum {
// PTP_USB_OK,
// PTP_USB_NAK,
// PTP_USB_INT_DATA_ABORT,
// PTP_USB_D_CANCEL,
// PTP_USB_H_CANCEL,
// PTP_USB_ERROR,
// PTP_USB_GONE
//} PTPIO_RETN;
typedef struct {
Boolean needClass;
int Config;
int iface;
int ifaceAlt;
int MaxLUN;
int ep_in;
int ep_in_pksize;
int ep_out;
int ep_out_pksize;
int ep_intr;
int ep_intr_pksize;
int ep_intr_pollms;
} USB_CLASS;
typedef struct {
Uint8 process;
Uint8 istate;
Uint8 error;
Uint8 regstate;
Uint32 TID;
Uint32 bw3;
Uint32 bw4;
}MSG_Q;
typedef struct {
/*Curr State Info*/
HOST_QUEUE_HEAD *curr_QH;
TRANSACTION_STRUCT *curr_TD;
TRANSACTION_STRUCT *prve_TD;
/*USB Device Info DataBase*/
Uint8 dev_total;
DEV_INFO *dev_info[128];
Uint32 USB_addr;
/*USBH HW Setting Info*/
Boolean even_odd_OUT;
Boolean even_odd_IN;
int DeviceReady;
} HOST_STATE_STRUCT;
static NU_TASK TaskPTPLayerID;
static NU_TASK TaskUSBH_ID;
static NU_QUEUE USBH_CTRL_Queue;
static NU_QUEUE USBH_BIN_Queue;
static NU_QUEUE USBH_BOUT_Queue;
static NU_QUEUE USBH_INTIN_Queue;
static NU_SEMAPHORE USBH_READ_Semaphore;
static NU_SEMAPHORE USBH_WRITE_Semaphore;
static NU_SEMAPHORE USBH_INT_Semaphore;
static Uint32 TaskUSBH_stack[USBHTASK_STACKSIZE*2];
static Uint32 TaskPTPLayer_stack[PTPTASK_STACKSIZE*4];
static DEVICE_DESC DeviceDesc;
static CONFIG_DESC ConfigDesc;
static INTERFACE_DESC InterfaceDesc;
static ENDPOINT_DESC EndpointDesc;
static USB_CLASS MassStorage;
static USB_CLASS StillImage;
static TimeVal debounce_delay = {0, USB_DEBOUNCE_DELAY};
static TimeVal reset_delay = {0, USB_RESET_DELAY};
static TimeVal recover_delay = {0, USB_RESET_RECOVERY_DELAY};
int *USBHOST_READY_FLAG;
Uint8 *Setup, *dev_request_buffer;
Uint32 *Ctrl_Queue_buff;
Uint32 *BulkIN_Queue_buff;
Uint32 *BulkOUT_Queue_buff;
Uint32 *IntIN_Queue_buff;
HOST_STATE_STRUCT usb_host;
extern EP_DATA *Ctrl_ep;
extern DEV_INFO *device_info;
extern HOST_QUEUE_HEAD ISO_QH,INT_QH,CONTROL_QH,BULK_QH;
void PTP_Layer_Task(UNSIGNED argc, VOID *argv);
PTPIO_RETN PTP_USB_ReadInterrupt(Uint32 UniqueDeviceID, Uint8 *Buf, Uint32 Size, Uint32 *retCount);
///*****************************************************************************
// * Synopsis: Sint32 TaskSleep(pTV)
// * Description: Put the task to sleep, making it ready after the time 'pTV'.
// * Arguments: (TimeVal *) pTV -- pointer to the timeval structure.
// * Return: 0 always
// *****************************************************************************/
//Sint32 TaskSleep(TimeVal * pTV)
//{
// /* Note: NU_Sleep(n) sleeps for between n-1 and n ticks, that's why we
// ** add the 1 at the end of the equation.
// */
// UNSIGNED ticks;
//
// ASSERT(pTV != NULL);
//
// ticks = TIMEVAL_TO_TICKS(pTV) + 1;
//
// NU_Sleep(ticks);
//
// return 0;
//}
Uint8 debug_log_workreport[400];
Uint16 debug_log_workreport_count=0;
void USBH_work_report(Uint8 code, Uint32 PROCESS_ID, Uint32 rstatus)
{
STATUS status;
MSG_Q Msg;
Msg.process = code;
Msg.istate = (Uint8)(rstatus>>16);
Msg.error = (Uint8)(rstatus>>8);
Msg.regstate= (Uint8) rstatus;
Msg.TID = PROCESS_ID;
Msg.bw3 = 0;
Msg.bw4 = 0;
if(code==USBH_DONE){
if(debug_log_workreport_count>400)
debug_log_workreport_count=0;
debug_log_workreport[debug_log_workreport_count]=PROCESS_ID;
debug_log_workreport_count++;
}
if(((PROCESS_ID&0xF0)==CTRL_TRANSACTION)||(PROCESS_ID==0)){
status = NU_Send_To_Queue(&USBH_CTRL_Queue, &Msg, 4, NU_NO_SUSPEND);
if(status!=NU_SUCCESS){
while(1);
}
return;
}
if(PROCESS_ID==(BULK_TRANSACTION|PROCESS_IN)){
status = NU_Send_To_Queue(&USBH_BIN_Queue, &Msg, 4, NU_NO_SUSPEND);
if(status!=NU_SUCCESS){
while(1);
}
return;
}
if(PROCESS_ID==(BULK_TRANSACTION|PROCESS_OUT)){
status = NU_Send_To_Queue(&USBH_BOUT_Queue, &Msg, 4, NU_NO_SUSPEND);
if(status!=NU_SUCCESS){
while(1);
}
return;
}
if(PROCESS_ID==INT_TRANSACTION|PROCESS_IN){
status = NU_Send_To_Queue(&USBH_INTIN_Queue, &Msg, 4, NU_NO_SUSPEND);
if(status!=NU_SUCCESS){
while(1);
}
return;
}
// status = NU_Broadcast_To_Queue(&USBH_CTRL_Queue, &Msg, 4,NU_NO_SUSPEND);
// if(status!=NU_SUCCESS){
// while(1);
// }
}
Sint32 IObf_2_BDT(TRANSACTION_STRUCT *TD,Uint8 *ep_iobf)
{
Uint8 reg8;
Uint32 reg32;
reg32=(Uint32)ep_iobf; //Get Buffer Address
reg8=(Uint8)(reg32>>24);//MSB
TD->BUFBASEH=reg8;
reg8=(Uint8)(reg32>>16);
TD->BUFBASEL=reg8;
reg8=(Uint8)(reg32>>8);
TD->bdt_ADDRH=reg8;
reg8=(Uint8)reg32;
TD->bdt_ADDRL=reg8; //LSB
}
static void reset_the_device(void)
{
/* Disable and clear all interrupts */
*regINT_ENB = 0;
*regINT_STAT = 0xFF;
/* Reset the device */
Ctrl_ep->pksize = FS_CTRL_PKCT_SIZE;
usb_host.USB_addr = 0;
*regADDR = 0;
/* Assert reset on the USB */
*regCTL = CTRL_HOST_NO_SOF | CTRL_RESET;
/* Delay 55 msec. for the reset process to complete */
TaskSleep(&reset_delay);
/* Set the ODD/EVEN BDT to even */
usb_host.even_odd_OUT = BDT_OUT_BIT;
usb_host.even_odd_IN = BDT_IN_BIT;
/*
* Set SOF threshold so we are guaranteed to have enough time for
* any transaction to complete (including ACK or NAK) without reaching
* the time to send the next Start-of-frame packet.
*/
*regSOF_THLD = SOF_THRESHOLD;
/* End the reset , clear ODD bit and enable host */
*regCTL = CTRL_ODD_RST | CTRL_HOST_SOF;
/* Delay 15 msec. for the reset recovery period */
TaskSleep(&recover_delay);
}
void TD_add2QH(HOST_QUEUE_HEAD *QH, TRANSACTION_STRUCT *TD)
{
TRANSACTION_STRUCT *TDtail;
//Disable USBH Interrupt
*(unsigned long *)EXMSK1A &= ~(1 << USB1_INTERRUPT_BIT);
if(QH->TD_tail!=NULL)
{
TDtail=QH->TD_tail; //Get Tail TD
TD->TD_next=NULL;
TDtail->TD_next=TD; //Add Curr TD After TD Tail
QH->TD_tail=TD; //Update QH Tail
/****************************************/
/* QH->TD_head->TD1->TD2->TDtail->TD */
/* /|\ */
/* QH->TD_tail----------------------| */
/****************************************/
}
else
{
TD->TD_next=NULL;
QH->TD_head=TD;
QH->TD_tail=TD;
/********************/
/* QH->TD_head->TD */
/* /|\ */
/* QH->TD_tail--| */
/********************/
}
//Enable USB HOST INT
*(unsigned long *)EXMSK1A |= (1 << USB1_INTERRUPT_BIT);
}
Sint32 USBH_INTIN_FCT(DEV_INFO *dev, EP_DATA *ep, Uint8 *Buf, Uint32 Size)
{
TRANSACTION_STRUCT *CurrTD, *Tmp_TD;
ep->curr_count=0;
//4.Create Transfer
CurrTD=(TRANSACTION_STRUCT*)calloc(sizeof(TRANSACTION_STRUCT),1);
CurrTD->state=INT_TRANSACTION|PROCESS_IN;
CurrTD->QH=(Uint32*)&INT_QH;
CurrTD->curr_DEV=dev;
CurrTD->curr_EP=ep;
CurrTD->io_bf=Buf;
CurrTD->length=Size;
//EP Transfer Setting
CurrTD->bdt_PID = BDT_PID_OWN | ep->DATAx;
CurrTD->bdt_BC = ep->pksize;
//Data Buffer Address Setting
IObf_2_BDT(CurrTD,CurrTD->io_bf);
//USB HOST Control Register Setting
CurrTD->EP0CTL = ep->type;
CurrTD->ADDR = dev->addr;
CurrTD->TOKEN = ep->pid_ep;
TD_add2QH(&INT_QH,CurrTD);
}
Sint32 USBH_BulkIN_FCT(DEV_INFO *dev, EP_DATA *ep, Uint8 *Buf, Uint32 Size)
{
Uint8 PROCESS_ID;
Uint8 process_msg;
Uint8 istate_msg;
Uint8 regstate_msg;
Uint8 error_msg;
TRANSACTION_STRUCT *CurrTD, *Tmp_TD;
ep->curr_count=0;
//4.Create Transfer
CurrTD=(TRANSACTION_STRUCT*)calloc(sizeof(TRANSACTION_STRUCT),1);
CurrTD->state=BULK_TRANSACTION|PROCESS_IN;
CurrTD->QH=(Uint32*)&BULK_QH;
CurrTD->curr_DEV=dev;
CurrTD->curr_EP=ep;
CurrTD->io_bf=Buf;
CurrTD->length=Size;
//5.EP Transfer Setting
CurrTD->bdt_PID = BDT_PID_OWN | ep->DATAx;
CurrTD->bdt_BC = ep->pksize;
//Data Buffer Address Setting
IObf_2_BDT(CurrTD,CurrTD->io_bf);
//USB HOST Control Register Setting
CurrTD->EP0CTL = ep->type;
CurrTD->ADDR = dev->addr;
CurrTD->TOKEN = ep->pid_ep;
TD_add2QH(&BULK_QH,CurrTD);
}
Sint32 USBH_BulkOUT_FCT(DEV_INFO *dev, EP_DATA *ep, Uint8 *Buf, Uint32 Size)
{
Uint32 left_to_send;
TRANSACTION_STRUCT *CurrTD;
ep->curr_count=0;
//4.Create Transfer
CurrTD=(TRANSACTION_STRUCT*)calloc(sizeof(TRANSACTION_STRUCT),1);
CurrTD->state=BULK_TRANSACTION|PROCESS_OUT;
CurrTD->QH=(Uint32*)&BULK_QH;
CurrTD->curr_DEV=dev;
CurrTD->curr_EP=ep;
CurrTD->io_bf=Buf;
CurrTD->length=Size;
left_to_send = Size;
if (left_to_send > ep->pksize)
left_to_send = ep->pksize;
//5.EP Transfer Setting
CurrTD->bdt_PID = BDT_PID_OWN | ep->DATAx;
CurrTD->bdt_BC = left_to_send;
//Data Buffer Address Setting
IObf_2_BDT(CurrTD,CurrTD->io_bf);
//USB HOST Control Register Setting
CurrTD->EP0CTL = ep->type;
CurrTD->ADDR = dev->addr;
CurrTD->TOKEN = ep->pid_ep;
TD_add2QH(&BULK_QH,CurrTD);
}
PTPIO_RETN PTP_USB_Read(Uint32 UniqueDeviceID,Uint8* Buf,Uint32 Size,Uint32 *retCount)
{
Uint8 i;
Sint32 ret;
EP_DATA *ep;
DEV_INFO dev;
MSG_Q RDMsg;
Uint32 actual_size;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -