Ejemplo n.º 1
0
// ---------------------------------------------------------------------------
BOOL CPU_USB_StartOutput(USB_CONTROLLER_STATE* State, int epNum)
{
    if (State == NULL || epNum >= State->EndpointCount)
        return FALSE;

    GLOBAL_LOCK(irq);

    // Exit if endpoint has no output queue
    if (State->Queues[epNum] == NULL || !State->IsTxQueue[epNum])
        return FALSE;

    // If endpoint status is halt, clear all queues
    if (State->EndpointStatus[epNum] & USB_STATUS_ENDPOINT_HALT)
    {
        while (USB_TxDequeue(State, epNum, TRUE) != NULL); // Clear TX queue
        return TRUE;
    }

    USBD_HANDLE_T hUsb = (State == USB_STATE(0)) ? USB_HANDLE(0) : USB_HANDLE(1);
    int core = USB_CORE(hUsb);
    USB_PACKET64* Packet64;
    UINT8* dst = ep_in_data[core];
    UINT32 cnt = 0;

    // Hold if buffer pending
    if (ep_in_count[core] != 0) return FALSE;

    // If payload missing, hold until flush to avoid host timeout at HS
    Packet64 = USB_TxDequeue(State, epNum, FALSE);
    if (Packet64->Size == sizeof(WP_Packet)
            && ((memcmp(Packet64->Buffer, MARKER_DEBUGGER_V1, 7) == 0)
                    || (memcmp(Packet64->Buffer, MARKER_PACKET_V1, 7) == 0)))
    {
        memcpy(dst, Packet64->Buffer, Packet64->Size);
        int missing = ((WP_Packet*)dst)->m_size + sizeof(WP_Packet);
        for (int i = 0; i < State->Queues[epNum]->NumberOfElements(); i++) {
            missing -= (*State->Queues[epNum])[i]->Size;
        }
        if (missing != 0) return FALSE;
    }

    // Copy packets to endpoint buffer
    cnt = 0;
    while ((Packet64 = USB_TxDequeue(State, epNum, FALSE)) != NULL) // Peek
    {
        if ((cnt + Packet64->Size) > EP_MEM_SIZE) break;
        Packet64 = USB_TxDequeue(State, epNum, TRUE); // Pop
        memcpy(dst, Packet64->Buffer, Packet64->Size);
        dst += Packet64->Size;
        cnt += Packet64->Size;
    }
    ep_in_count[core] = cnt;

    // Transmit buffer
    USB_EP_In_Handler(hUsb, (void*) epNum, USB_EVT_IN);

    return TRUE;
}
void AT91_USBHS_Driver::TxPacket( USB_CONTROLLER_STATE* State, int endpoint )
{
    
    ASSERT( endpoint < c_Used_Endpoints );    
    ASSERT( State );

    struct AT91_UDPHS *pUdp = (struct AT91_UDPHS *) (AT91C_BASE_UDP) ;
    UINT8 * pDest = (UINT8*) ((((struct AT91_UDPHS_EPTFIFO *)AT91C_BASE_UDP_DMA)->UDPHS_READEPT0) + 16384 * endpoint);
    
    GLOBAL_LOCK(irq);
    
    
    // transmit a packet on UsbPortNum, if there are no more packets to transmit, then die
    USB_PACKET64* Packet64;

    Packet64 = USB_TxDequeue( State, endpoint, TRUE );

    if(Packet64 != NULL && Packet64->Size == 0)
    {
        g_AT91_USBHS_Driver.TxNeedZLPS[endpoint] = TRUE;
        Packet64 = NULL;
    }

    while (pUdp->UDPHS_EPT[endpoint].UDPHS_EPTSTA & AT91C_UDPHS_TX_PK_RDY);
    
    if(Packet64)
    {
        int i;

        // We should absolutely have an empty buffer to use
//        ASSERT(pEp->UDP_CSR[endpoint] & AT91C_UDP_TXPKTRDY);

        // fill fifo

        for(i = 0; i < Packet64->Size; i++)
        {
            *pDest++ = Packet64->Buffer[i];
        }

        g_AT91_USBHS_Driver.TxNeedZLPS[endpoint] = (Packet64->Size == 64);
    }
    else
    {
        // send the zero leght packet since we landed on the FIFO boundary before
        // (and we queued a zero length packet to transmit)
        if(g_AT91_USBHS_Driver.TxNeedZLPS[endpoint])
        {
             g_AT91_USBHS_Driver.TxNeedZLPS[endpoint] = FALSE;
        }

        // no more data
        g_AT91_USBHS_Driver.TxRunning[endpoint] = FALSE;
        pUdp->UDPHS_EPT[endpoint].UDPHS_EPTCTLDIS = AT91C_UDPHS_TX_PK_RDY;
        
    }
    pUdp->UDPHS_EPT[endpoint].UDPHS_EPTSETSTA = AT91C_UDPHS_TX_PK_RDY;

}
//
// Data In (Tx) Endpoint Interrupt Handler
//
void STM32_USB_Driver_EP_In_Int(UINT32 , USB_CONTROLLER_STATE* State, int endpoint)
{
  ASSERT_IRQ_MUST_BE_OFF();

  // If this is not a legal transmit endpoint, there is nothing more to do
  if((State->Queues[endpoint] != NULL) && State->IsTxQueue[endpoint])
  {
    USB_PACKET64* Packet64 = USB_TxDequeue(State, endpoint, TRUE);
    if(Packet64)
    {
      // More data to send
      // copy buffer
      // FIXME: Optimize, both buffers are always 64 bytes long
      int count = Packet64->Size;
      for(int i = 0; i < count; i++)
      {
        APP_Rx_Buffer[i] = Packet64->Buffer[i];
      }

      STM32_USB_EndpointTransmit(NETMF_IN_EP, (UINT8*)APP_Rx_Buffer, count);
    }
  }
}