Esempio n. 1
0
//------------------------------------------------------------------------------
//          Main
//------------------------------------------------------------------------------
int main()
{
    unsigned int dPioStatus;
    S_mse_report *pReport = &(sMse.sReport);
    bool         isChanged;

    TRACE_INIT();
    TRACE_INFO("\n\rMain HID mouse\n\r");

    // Initialize the HID mouse driver
    MSE_Init(&sMse, &sUsb);

    TRACE_INFO("Connecting ... ");

    // Wait for the device to be powered before connecting it
    while (!ISSET(USB_GetState(&sUsb), USB_STATE_POWERED));
    USB_Connect(&sUsb);

    TRACE_INFO("OK\n\r");

    // Main loop
    while (1) {

        // Retrieve PIO status change
        isChanged = false;
        dPioStatus = SWITCH_PIO->PIO_PDSR;

        // Check for clicks on any button
        // Left mouse button
        if (ISCLEARED(dPioStatus, SW_LEFTCLICK)) {

            SET(pReport->bButtons, MSE_LEFT_BUTTON);
            CLEAR(dPioStatus, SW_LEFTCLICK);
            isChanged = true;
        }
        else {

            // Check if button was previously pressed
            if (ISSET(pReport->bButtons, MSE_LEFT_BUTTON)) {

                CLEAR(pReport->bButtons, MSE_LEFT_BUTTON);
                isChanged = true;
            }
        }

        // Right mouse button
        if (ISCLEARED(dPioStatus, SW_RIGHTCLICK)) {

            SET(pReport->bButtons, MSE_RIGHT_BUTTON);
            CLEAR(dPioStatus, SW_RIGHTCLICK);
            isChanged = true;
        }
        else {

            // Check if button was previously pressed
            if (ISSET(pReport->bButtons, MSE_RIGHT_BUTTON)) {

                CLEAR(pReport->bButtons, MSE_RIGHT_BUTTON);
                isChanged = true;
            }
        }

        // Check pointer for movement
        // Left
        if (ISCLEARED(dPioStatus, SW_LEFT)) {

            pReport->bX = -SPEED_X;
            isChanged = true;
        }
        // Right
        else if (ISCLEARED(dPioStatus, SW_RIGHT)) {

            pReport->bX = SPEED_X;
            isChanged = true;
        }
        else {

            pReport->bX = 0;
        }

        // Up
        if (ISCLEARED(dPioStatus, SW_UP)) {

            pReport->bY = -SPEED_Y;
            isChanged = true;
        }
        // Down
        else if (ISCLEARED(dPioStatus, SW_DOWN)) {

            pReport->bY = SPEED_Y;
            isChanged = true;
        }
        else {

            pReport->bY = 0;
        }

        // Send report if a change has occured
        if (isChanged) {

            LED_TOGGLE(LED_MEM);
            MSE_SendReport(&sMse, 0, 0);
        }
    }
}
Esempio n. 2
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);
            }
        }
    }
Esempio n. 3
0
//void NAKEDFUNC usb_irq_service(void)
void usb_irq_service(void)
{
    //ISR_ENTRY();
    // End interrupt if we are not attached to USB bus
    //*AT91C_PIOA_SODR = PIN_LED;
    //TRACE_ALL("@");    
    
    if (ISCLEARED(usb_device_state,USB_STATE_ATTACHED)) goto end_of_irq;

    unsigned char endpoint;
    unsigned int status = pUDP->UDP_ISR & pUDP->UDP_IMR & ISR_MASK;

    while( status != 0)
    {
        // Start Of Frame (SOF)
        if (ISSET(status, AT91C_UDP_SOFINT))
        {
            TRACE_USB("SOF   ");
            // Acknowledge interrupt
            SET(pUDP->UDP_ICR, AT91C_UDP_SOFINT);
            CLEAR(status, AT91C_UDP_SOFINT);
        }        
        // Suspend
        if (ISSET(status,AT91C_UDP_RXSUSP))
        {
            TRACE_USB("Susp   ");
           
            if (ISCLEARED(usb_device_state,USB_STATE_SUSPENDED))
            {
                // The device enters the Suspended state
                //      MCK + UDPCK must be off
                //      Pull-Up must be connected
                //      Transceiver must be disabled

                // Enable wakeup
                SET(pUDP->UDP_IER, AT91C_UDP_WAKEUP | AT91C_UDP_RXRSM);

                // Acknowledge interrupt
                SET(pUDP->UDP_ICR, AT91C_UDP_RXSUSP);
                // Set suspended state
                SET(usb_device_state,USB_STATE_SUSPENDED);
                // Disable transceiver
                SET(pUDP->UDP_TXVC, AT91C_UDP_TXVDIS);
                // Disable master clock
                AT91C_BASE_PMC->PMC_PCDR |= (1 << AT91C_ID_UDP);
                // Disable peripheral clock for USB
                AT91C_BASE_PMC->PMC_SCDR |= AT91C_PMC_UDP;
            }            
        }
        // Resume
        else
        if (ISSET(status, AT91C_UDP_WAKEUP) || ISSET(status, AT91C_UDP_RXRSM))
        {
            TRACE_USB("Resm   ");

            // The device enters Configured state
            //      MCK + UDPCK must be on
            //      Pull-Up must be connected
            //      Transceiver must be enabled
            // Powered state
            // Enable master clock
            AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_UDP);
            // Enable peripheral clock for USB
            AT91C_BASE_PMC->PMC_SCER |= AT91C_PMC_UDP;

            // Default state
            if (ISSET(usb_device_state,USB_STATE_DEFAULT))
            {
                // Enable transceiver
                CLEAR(pUDP->UDP_TXVC, AT91C_UDP_TXVDIS);
            }

            CLEAR(usb_device_state, USB_STATE_SUSPENDED);

            SET(pUDP->UDP_ICR, AT91C_UDP_WAKEUP | AT91C_UDP_RXRSM | AT91C_UDP_RXSUSP);
            SET(pUDP->UDP_IDR, AT91C_UDP_WAKEUP | AT91C_UDP_RXRSM);
        }        
        // End of bus reset
        else
        if (ISSET(status, AT91C_UDP_ENDBUSRES))
        {
            TRACE_USB("\n\n\nEoBres   ");

            // Initialize UDP peripheral device
            usb_bus_reset_handler();

            // Flush and enable the Suspend interrupt
            SET(pUDP->UDP_ICR, AT91C_UDP_WAKEUP | AT91C_UDP_RXRSM | AT91C_UDP_RXSUSP);

            // Acknowledge end of bus reset interrupt
            SET(pUDP->UDP_ICR, AT91C_UDP_ENDBUSRES);
        }
        // Endpoint interrupts
        else {
            while (status != 0) {

                // Get endpoint index
                endpoint = last_set_bit(status);
                usb_endpoint_handler(endpoint);
                
                CLEAR(pUDP->UDP_ICR, (1 << endpoint));
                
                CLEAR(status, 1 << endpoint);
            }
        }          

        status = pUDP->UDP_ISR & pUDP->UDP_IMR & ISR_MASK;
       
        // Mask unneeded interrupts
        if (ISCLEARED(usb_device_state,DEFAULT_STATE))
        {
            status &= AT91C_UDP_ENDBUSRES | AT91C_UDP_SOFINT;
        }
        
    }   // end while status != 0

end_of_irq:
    *AT91C_AIC_EOICR = 1;    // ACK interrupt end
    *AT91C_AIC_ICCR = 1 << AT91C_ID_UDP;    // clear interrupt on the interrupt controller    

    //ISR_EXIT();   
}