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 + -
显示快捷键?