Пример #1
0
static void startTransmit(unsigned epNum, struct transmitRequest_t *tx)
{
	unsigned total = fillOutput(epNum,tx);
	if( 0 == ( UDP->UDP_CSR[epNum] & AT91C_UDP_TXPKTRDY ) ){
                UDP_SETEPFLAGS(UDP->UDP_CSR+epNum, AT91C_UDP_TXPKTRDY );
		connections[epNum].txState = EPTX_WAITCOMP ;
		if( USBEP_BULKIN == epNum )
			total += fillOutput(epNum,tx);
if( 0 )// != epNum )
{
	NODEBUGMSG( "extra 0x" ); NODEBUGHEX( total ); NODEBUGMSG( "\r\n" );
}
	}
	else {
		write( DEFUART, "PKTRDY already set for ep 0x" ); writeHexChar( DEFUART, epNum ); write( DEFUART, "\r\n" );
	}

	DEBUGMSG( "~txPacket: 0x" ); DEBUGHEX(tx->txNext->length-tx->txNext->offset); DEBUGMSG( "\r\n" );
}
Пример #2
0
/* called by the main application to poll for events */
void usbll_poll( void )
{
	int epNum ;
	unsigned gstate ;
	unsigned isr = UDP->UDP_ISR ;
	if( isr != prevISR ){
		prevISR = isr ;
	}
	
	if( isr & AT91C_UDP_EPINT0 ){
		UDP->UDP_ICR = AT91C_UDP_EPINT0 ;
	}

	if( isr & AT91C_UDP_WAKEUP ){
		DEBUGMSG( "UDP_WAKEUP\r\n" );
		UDP->UDP_ICR = AT91C_UDP_WAKEUP ;
	}

	if( isr & AT91C_UDP_RXRSM ){
		DEBUGMSG( "UDP_RXRSM\r\n" );
		UDP->UDP_ICR = AT91C_UDP_RXRSM ;
	}

	if( isr & AT91C_UDP_EXTRSM ){
		DEBUGMSG( "UDP_EXTRSM\r\n" );
		UDP->UDP_ICR = AT91C_UDP_EXTRSM ;
	}

	if( isr & AT91C_UDP_SOFINT ){
//		DEBUGMSG( "UDP_SOFINT\r\n" );
		UDP->UDP_ICR = AT91C_UDP_SOFINT ;
	}

	if( isr & AT91C_UDP_ENDBUSRES ){
//		write( DEFUART, "GLBSTATE == " ); writeHex( DEFUART, UDP->UDP_GLBSTATE ); write( DEFUART, "\r\n" );
		UDP->UDP_FADDR = AT91C_UDP_FEN ;
		UDP_CLEAREPFLAGS(&UDP->UDP_GLBSTATE,AT91C_UDP_CONFG|AT91C_UDP_FADDEN);
		UDP->UDP_RSTEP = 0xffffffff ;
		UDP->UDP_RSTEP = 0 ;
		UDP_SETEPFLAGS(UDP->UDP_CSR + 0, AT91C_UDP_EPEDS);
                UDP_CLEAREPFLAGS(UDP->UDP_CSR + 0, AT91C_UDP_DIR);
		UDP->UDP_ICR = AT91C_UDP_ENDBUSRES ;
		abortTransmitters();
//		write( DEFUART, "UDP_ENDBUSRES 0x" );writeHex( DEFUART, UDP->UDP_GLBSTATE ); write( DEFUART, "\r\n" );
	}

	gstate = UDP->UDP_GLBSTATE; 

	for( epNum = 0 ; epNum < UDP_MAXENDPOINTS ; epNum++ ){
		unsigned int dStatus = UDP->UDP_CSR[epNum];

		if( dStatus & AT91C_UDP_TXCOMP ){
			transmitComplete(epNum);
		} // transmit completed

		if( dStatus & AT91C_UDP_RXSETUP ){
			unsigned char setupBuf[16];
			unsigned short rxLength = ( dStatus >> 16 ) & 0x7FF ;
			if( sizeof(struct S_usb_request) <= rxLength ){
                                struct S_usb_request const *rxSetup = (struct S_usb_request const *)setupBuf ;
                                rxLength = sizeof(*rxSetup);
				unsigned i ;
                                unsigned char volatile *const fifo = (unsigned char *)&UDP->UDP_FDR[epNum];
				for( i = 0 ; i < rxLength ; i++ ){
					setupBuf[i] = *fifo ;
				}
				if( rxSetup->bmRequestType & 0x80) {
					UDP_SETEPFLAGS(UDP->UDP_CSR + epNum, AT91C_UDP_DIR);
				}

				UDP_CLEAREPFLAGS(UDP->UDP_CSR + epNum, AT91C_UDP_RXSETUP);

				if( 0 != (UDP->UDP_CSR[epNum] & (AT91C_UDP_TXPKTRDY|AT91C_UDP_TXCOMP|AT91C_UDP_STALLSENT)) ){
					write( DEFUART, "rxSetup: txPending\r\n" );
				}

				if( setupCallback ){
					completeTransmit(epNum);
					setupCallback( setupOpaque, setupBuf, rxLength );
				}
			}
			else {
				write( DEFUART, "rxSetup too small 0x" ); writeHexChar( DEFUART, rxLength ); write( DEFUART, "\r\n" );
				UDP_CLEAREPFLAGS(UDP->UDP_CSR + epNum, AT91C_UDP_RXSETUP);
			}
		}
		
		if( dStatus & AT91C_UDP_STALLSENT ){
			UDP_CLEAREPFLAGS(UDP->UDP_CSR + epNum, AT91C_UDP_STALLSENT);
		}

		unsigned int rxMask = dStatus & (AT91C_UDP_RX_DATA_BK0|AT91C_UDP_RX_DATA_BK1);
		if( rxMask ){
			rxData(epNum,rxMask);
		} // received something
	}
Пример #3
0
void usbll_halt( unsigned bEndpoint )
{
	UDP_SETEPFLAGS(UDP->UDP_CSR + bEndpoint, AT91C_UDP_FORCESTALL);
}
Пример #4
0
//------------------------------------------------------------------------------
// \brief  Endpoint interrupt handler.
//
//         Handle IN/OUT transfers, received SETUP packets and STALLing
// \param  pUsb      Pointer to a S_usb instance
// \param  bEndpoint Index of endpoint
// \see    S_usb
//------------------------------------------------------------------------------
static void UDP_EndpointHandler(const S_usb *pUsb, unsigned char bEndpoint)
{
    S_usb_endpoint *pEndpoint = USB_GetEndpoint(pUsb, bEndpoint);
    AT91PS_UDP pInterface = UDP_GetDriverInterface(pUsb);
    unsigned int dStatus = pInterface->UDP_CSR[bEndpoint];

    TRACE_DEBUG_L("Ept%d ", bEndpoint);

    // Handle interrupts
    // IN packet sent
    if (ISSET(dStatus, AT91C_UDP_TXCOMP)) {

        TRACE_DEBUG_L("Wr ");

        // Check that endpoint was in Write state
        if (pEndpoint->dState == endpointStateWrite) {

            // End of transfer ?
            if ((pEndpoint->dBytesBuffered < pEndpoint->wMaxPacketSize)
                ||
                (!ISCLEARED(dStatus, AT91C_UDP_EPTYPE)
                 && (pEndpoint->dBytesRemaining == 0)
                 && (pEndpoint->dBytesBuffered == pEndpoint->wMaxPacketSize))) {

                TRACE_DEBUG_L("%d ", pEndpoint->dBytesBuffered);

                pEndpoint->dBytesTransferred += pEndpoint->dBytesBuffered;
                pEndpoint->dBytesBuffered = 0;

                // Disable interrupt if this is not a control endpoint
                if (!ISCLEARED(dStatus, AT91C_UDP_EPTYPE)) {

                    SET(pInterface->UDP_IDR, 1 << bEndpoint);
                }

                UDP_EndOfTransfer(pEndpoint, USB_STATUS_SUCCESS);
            }
            else {

                // Transfer remaining data
                TRACE_DEBUG_L("%d ", pEndpoint->wMaxPacketSize);

                pEndpoint->dBytesTransferred += pEndpoint->wMaxPacketSize;
                pEndpoint->dBytesBuffered -= pEndpoint->wMaxPacketSize;

                // Send next packet
                if (pEndpoint->dNumFIFO == 1) {

                    // No double buffering
                    UDP_WritePayload(pUsb, bEndpoint);
                    UDP_SETEPFLAGS(pUsb, bEndpoint, AT91C_UDP_TXPKTRDY);
                }
                else {

                    // Double buffering
                    UDP_SETEPFLAGS(pUsb, bEndpoint, AT91C_UDP_TXPKTRDY);
                    UDP_WritePayload(pUsb, bEndpoint);
                }
            }
        }

        // Acknowledge interrupt
        UDP_CLEAREPFLAGS(pUsb, bEndpoint, AT91C_UDP_TXCOMP);
    }
    // OUT packet received
    if (ISSET(dStatus, AT91C_UDP_RX_DATA_BK0)
        || ISSET(dStatus, AT91C_UDP_RX_DATA_BK1)) {

        TRACE_DEBUG_L("Rd ");

        // Check that the endpoint is in Read state
        if (pEndpoint->dState != endpointStateRead) {

            // Endpoint is NOT in Read state
            if (ISCLEARED(dStatus, AT91C_UDP_EPTYPE)
                && ISCLEARED(dStatus, 0xFFFF0000)) {

                // Control endpoint, 0 bytes received
                // Acknowledge the data and finish the current transfer
                TRACE_DEBUG_L("Ack ");
                UDP_ClearRXFlag(pUsb, bEndpoint);

                UDP_EndOfTransfer(pEndpoint, USB_STATUS_SUCCESS);
            }
            else if (ISSET(dStatus, AT91C_UDP_FORCESTALL)) {

                // Non-control endpoint
                // Discard stalled data
                TRACE_DEBUG_L("Disc ");
                UDP_ClearRXFlag(pUsb, bEndpoint);
            }
            else {

                // Non-control endpoint
                // Nak data
                TRACE_DEBUG_L("Nak ");
                SET(pInterface->UDP_IDR, 1 << bEndpoint);
            }
        }
        else {

            // Endpoint is in Read state
            // Retrieve data and store it into the current transfer buffer
            unsigned short wPacketSize = (unsigned short) (dStatus >> 16);

            TRACE_DEBUG_L("%d ", wPacketSize);

            UDP_GetPayload(pUsb, bEndpoint, wPacketSize);
            UDP_ClearRXFlag(pUsb, bEndpoint);

            if ((pEndpoint->dBytesRemaining == 0)
                || (wPacketSize < pEndpoint->wMaxPacketSize)) {

                // Disable interrupt if this is not a control endpoint
                if (!ISCLEARED(dStatus, AT91C_UDP_EPTYPE)) {

                    SET(pInterface->UDP_IDR, 1 << bEndpoint);
                }

                UDP_EndOfTransfer(pEndpoint, USB_STATUS_SUCCESS);
            }
        }
    }