rusb.c
来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 524 行 · 第 1/2 页
C
524 行
OHCI_Create_General_td (&(ohci->setup_pipe1_0->ed), &(ohci->setup_pipe1_0->td_in0), &(ohci->setup_pipe1_0->td_in0_buffer), 0, TDC_R_BUFER_EXACT_FILL, TDC_DP_IN, 0, TDC_T_DATA1, 0, TDC_CC_SET, 1);
//---Enable---
OHCI_enqueue_ed (&(ohci->regs->HcControlHeadED),&(ohci->setup_pipe1_0->ed));
ohci->regs->HcInterruptStatus |= HCI_WDH;
ohci->regs->HcCommandStatus |= HCCS_CLF;
//---Process data---
while ((ohci->regs->HcInterruptStatus & HCI_WDH) == 0);
while (ohci->setup_pipe1_0->td_in0->CBP != 0);
//---Free---
rfree (ohci->setup_pipe1_0->td_setup_buffer);
rfree16B (ohci->setup_pipe1_0->td_setup);
rfree16B (ohci->setup_pipe1_0->td_in0);
ohci->setup_pipe1_0->td_setup_buffer = NULL;
ohci->setup_pipe0_0->td_in0_buffer = NULL;
ohci->setup_pipe1_0->td_setup = NULL;
ohci->setup_pipe1_0->td_in0 = NULL;
}
//-----------------------------------------------------------------------------
void OHCI_MouseIn (void)
{
//---setup_pipe1_1->ed & setup_pipe1_1->td_zeros---
if (ohci->setup_pipe1_1->ed == NULL)
OHCI_Create_ed (&(ohci->setup_pipe1_1->ed), &(ohci->setup_pipe1_1->td_zeros), 1, 1, EDC_D_SEE_TD, EDC_S_FULL_SPEED, EDC_K_NO_SKIP, EDC_F_ISOCHRONOUS, 0x20);
//---ohci->setup_pipe1_1->td_in0---
ohci->setup_pipe1_1->td_in0_buffer = rmalloc (4,"ohci->setup_pipe1_1->td_in0_buffer");
OHCI_Create_General_td (&(ohci->setup_pipe1_1->ed), &(ohci->setup_pipe1_1->td_in0), &(ohci->setup_pipe1_1->td_in0_buffer), 4, TDC_R_BUFER_EXACT_FILL, TDC_DP_IN, 0, TDC_T_DATA1, 0, TDC_CC_SET, 1);
//---Enable---
if (ohci->hcca->InterruptList[0] == NULL)
{
ohci->hcca->InterruptList[0] = ohci->setup_pipe1_1->ed;
ohci->regs->HcPeriodCurrentED = ohci->setup_pipe1_1->ed;
}
ohci->regs->HcControl |= HCC_PLE;
//---Process data---
while ( ((ohci->regs->HcInterruptStatus & HCI_WDH) == 0) && ((ohci->regs->HcRhPortStatus[0] & HCRHPS_CCS) != 0) );
while ( (ohci->setup_pipe1_1->td_in0->CBP != 0) && ((ohci->regs->HcRhPortStatus[0] & HCRHPS_CCS) != 0) );
if ((ohci->regs->HcRhPortStatus[0] & HCRHPS_CCS) == 0)
{
rDiagMessage ("Device was unpluged.");
return;
}
//---Remove old data---
ohci->device->DataValid = 0;
if (ohci->device->MouseData != NULL)
rfree (ohci->device->MouseData);
//---Get data---
ohci->device->MouseData = (tMouseData*) ohci->setup_pipe1_1->td_in0_buffer;
ohci->device->DataValid = 1;
//---view mouse on LEDs---
//SnakeOnLEDs (ohci->device->MouseData->DeltaZ,ohci->device->MouseData->Buttons);
SnakeOnLEDs (ohci->device->MouseData->DeltaZ,0);
//---Free---
rfree16B (ohci->setup_pipe1_1->td_in0);
ohci->setup_pipe1_1->td_in0_buffer = NULL;
ohci->setup_pipe1_1->td_in0 = NULL;
}
//-----------------------------------------------------------------------------
void OHCI_PortReset (void)
{
ohci->regs->HcRhPortStatus[0] |= HCRHPS_PRS; //Perform reset, set PortResetStatus
TimeDelay (60*TIME_DELAY_1MS); //Reset must be asserted at least 50ms
while ((ohci->regs->HcRhPortStatus[0] & HCRHPS_PRS) != 0); //Active wait until the reset is completed
while ((ohci->regs->HcRhPortStatus[0] & HCRHPS_PRSC) == 0); //Active wait until the reset is completed
//ohci->regs->HcRhPortStatus[0] |= HCRHPS_PRSC; //Reset is done, clear the status change bit
}
//-----------------------------------------------------------------------------
// Work with EDs and TDs
//-----------------------------------------------------------------------------
void OHCI_Create_ed (tED **ed, tTD **td, u32 FA, u32 EN, u32 D, u32 S, u32 K, u32 F, u32 MPS)
{
if (((*ed) != NULL) || ((*td) != NULL))
rExit("OHCI_Create_ed failed.");
(*ed) = rmalloc16B ("HC_ENDPOINT_DESCRIPTOR");
(*ed)->Control = 0;
(*ed)->Control |= (FA << 0); //7-bit
(*ed)->Control |= (EN << 7); //2-bit
(*ed)->Control |= (D << 9); //2-bit
(*ed)->Control |= (S << 11); //1-bit
(*ed)->Control |= (K << 12); //1-bit
(*ed)->Control |= (F << 13); //1-bit
(*ed)->Control |= (MPS<< 14);
(*td) = rmalloc16B ("HC_TRANSFER_DESCRIPTOR");
(*td)->Control = 0;
(*td)->CBP = NULL;
(*td)->NextTD = NULL;
(*td)->BE = NULL;
(*ed)->TailP = (*td);
(*ed)->HeadP = (*td);
(*ed)->NextED = NULL;
}
//-----------------------------------------------------------------------------
void OHCI_Create_General_td (tED **ed, tTD **td, u8 **buffer, u32 buffer_length, u32 R, u32 DP, u32 DI, u32 T, u32 EC, u32 CC, u32 TIdx)
{
if (((*ed)->HeadP == NULL) && ((*ed)->TailP == NULL))
rExit("OHCI_Create_General_td failed. Create ed properly first.");
//---Create td---
(*td) = rmalloc16B ("HC_TRANSFER_DESCRIPTOR");
(*td)->Control = TIdx; //Transaction index
(*td)->Control |= (R << 18); //1-bit
(*td)->Control |= (DP << 19); //2-bit
(*td)->Control |= (DI << 21); //3-bit
(*td)->Control |= (T << 24); //2-bit
(*td)->Control |= (EC << 26); //2-bit
(*td)->Control |= (CC << 28); //4-bit
if (buffer_length == 0)
{
(*td)->CBP = 0;
(*td)->BE = 0;
} else {
(*td)->CBP = (*buffer);
(*td)->BE = (*buffer);
(*td)->BE += buffer_length - 1;
}
//---Enque td---
(*ed)->Control |= (EDC_K_SKIP << 12);
if ((*ed)->HeadP == (*ed)->TailP)
{
(*ed)->HeadP = *td;
(*td)->NextTD = (*ed)->TailP;
} else {
tTD *current_td = (*ed)->HeadP;
while (current_td->NextTD != (*ed)->TailP)
current_td = current_td->NextTD;
current_td->NextTD = *td;
(*td)->NextTD = (*ed)->TailP;
}
(*ed)->Control &= ~(EDC_K_SKIP << 12);
}
//-----------------------------------------------------------------------------
void OHCI_Create_ControlPacket (u8 **buffer, u8 bmRequestType, u8 bRequest, u16 wValue, u16 wIndex, u16 wLength)
{
tControlPacket *ControlPacket = rmalloc (sizeof(tControlPacket),"ControlPacket");
ControlPacket->bmRequestType = bmRequestType;
ControlPacket->bRequest = bRequest;
ControlPacket->wValue = wValue;
ControlPacket->wIndex = wIndex;
ControlPacket->wLength = wLength;
(*buffer) = (u8*)ControlPacket;
}
//-----------------------------------------------------------------------------
void OHCI_Create_Buffer (tTD **td, u32 Size)
{
u8 *Packet = rmalloc (Size,"Packet");
(*td)->CBP = (u8*)Packet;
(*td)->BE = (u8*)Packet;
(*td)->BE += Size-1;
}
//-----------------------------------------------------------------------------
void OHCI_enqueue_ed (tED **HeadED, tED **ed)
{
(*ed)->NextED = NULL;
if (*HeadED == NULL)
*HeadED = *ed;
else
{
tED *current_ed = *HeadED;
while (current_ed->NextED != NULL)
current_ed = current_ed->NextED;
current_ed->NextED = *ed;
}
}
//-----------------------------------------------------------------------------
void OHCI_isr (void)
{
u32 MasterInterruptEnable = ohci->regs->HcInterruptEnable;
//Prevent next interrupt
ohci->regs->HcInterruptDisable = MasterInterruptEnable;
if (ohci->regs->HcInterruptStatus & MasterInterruptEnable & HCI_SO)
ohci->regs->HcInterruptStatus |= HCI_SO;
if (ohci->regs->HcInterruptStatus & MasterInterruptEnable & HCI_WDH)
{
if (ohci->hcca->DoneHead & 1UL)
ohci->hcca->DoneHead &= ~1UL;
else
ohci->hcca->DoneHead = 0;
ohci->regs->HcInterruptStatus |= HCI_WDH;
}
if (ohci->regs->HcInterruptStatus & MasterInterruptEnable & HCI_SF)
ohci->regs->HcInterruptStatus |= HCI_SF;
if (ohci->regs->HcInterruptStatus & MasterInterruptEnable & HCI_RD)
ohci->regs->HcInterruptStatus |= HCI_RD;
if (ohci->regs->HcInterruptStatus & MasterInterruptEnable & HCI_UE)
ohci->regs->HcInterruptStatus |= HCI_UE;
if (ohci->regs->HcInterruptStatus & MasterInterruptEnable & HCI_FNO)
ohci->regs->HcInterruptStatus |= HCI_FNO;
if (ohci->regs->HcInterruptStatus & MasterInterruptEnable & HCI_RHSC)
{
if (ohci->regs->HcRhPortStatus[0] & HCRHPS_CHANGES_MASK)
ohci->regs->HcRhPortStatus[0] |= HCRHPS_CHANGES_MASK; //clear change flags
ohci->regs->HcInterruptStatus |= HCI_RHSC;
}
if (ohci->regs->HcInterruptStatus & MasterInterruptEnable & HCI_OC)
ohci->regs->HcInterruptStatus |= HCI_OC;
if (ohci->regs->HcInterruptStatus & MasterInterruptEnable & HCI_MIE)
ohci->regs->HcInterruptStatus |= HCI_MIE;
//Re-enable interrtups
ohci->regs->HcInterruptEnable = MasterInterruptEnable;
}
//-----------------------------------------------------------------------------
void TakeOwnerShip (tOHCI *ohci)
{
if (ohci->regs->HcControl & HCC_IR)
{
ohci->regs->HcCommandStatus = HCCS_OCR;
while (ohci->regs->HcControl & HCC_IR)
TimeDelay (10);
}
else if ((ohci->regs->HcControl & HCC_HCFS) != HCC_HCFS_USBRESET)
{
if ((ohci->regs->HcControl & HCC_HCFS) != HCC_HCFS_USBOPERATIONAL)
{
ohci->regs->HcControl = (ohci->regs->HcControl & ~HCC_HCFS) | HCC_HCFS_USBRESUME;
TimeDelay(20*1000); // minium UsbResume assertion time, see spec., 20ms
}
}
}
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?