Example #1
0
//-----------------------------------------------------------------
// set_feature:
//-----------------------------------------------------------------
static void set_feature(struct device_request *request)
{
	unsigned char bRecipient = request->bmRequestType & USB_RECIPIENT_MASK;

    log_printf(USBLOG_INFO, "USB: Set Feature %x\n", bRecipient);

	if ( bRecipient == USB_RECIPIENT_DEVICE )
	{
		if ( request->wValue == USB_FEATURE_REMOTE_WAKEUP )
		{
            log_printf(USBLOG_INFO, "USB: Enable remote wake\n");
            _remote_wake_enabled = 1;
			usbhw_control_endpoint_ack();
		}
		else if ( request->wValue == USB_FEATURE_TEST_MODE )
		{
            log_printf(USBLOG_INFO, "USB: Enable test mode\n");
			usbhw_control_endpoint_ack();
		}
		else
            usbhw_control_endpoint_stall();
	}
	else if ( bRecipient == USB_RECIPIENT_ENDPOINT && 
			  request->wValue == USB_FEATURE_ENDPOINT_STATE )
	{
		usbhw_control_endpoint_ack();
		usbhw_set_endpoint_stall(request->wIndex & ENDPOINT_ADDR_MASK);
	}
	else
        usbhw_control_endpoint_stall();
}
Example #2
0
//-----------------------------------------------------------------
// usb_process_request:
//-----------------------------------------------------------------
static void usb_process_request(struct device_request *request, unsigned char type, unsigned char req, unsigned char *data)
{
	if ( type == USB_STANDARD_REQUEST )
	{
        // Standard requests
        switch (req)
        {
        case REQ_GET_STATUS:
            get_status(request);
            break;
        case REQ_CLEAR_FEATURE:
            clear_feature(request);
            break;
        case REQ_SET_FEATURE:
            set_feature(request);
            break;
        case REQ_SET_ADDRESS:
            set_address(request);
            break;
        case REQ_GET_DESCRIPTOR:
            get_descriptor(request);
            break;
        case REQ_GET_CONFIGURATION:
            get_configuration(request);
            break;
        case REQ_SET_CONFIGURATION:
            set_configuration(request);
            break;
        case REQ_GET_INTERFACE:
            get_interface(request);
            break;
        case REQ_SET_INTERFACE:
            set_interface(request);
            break;
        default:
            log_printf(USBLOG_ERR, "USB: Unknown standard request %x\n", req);
		    usbhw_control_endpoint_stall();
            break;
        }
	}
	else if ( type == USB_VENDOR_REQUEST )
	{
        log_printf(USBLOG_ERR, "Vendor: Unknown command\n");

        // None supported
		usbhw_control_endpoint_stall();
	}
	else if ( type == USB_CLASS_REQUEST && _class_request)
	{
        _class_request(req, request->wValue, request->wIndex, data, request->wLength);
	}
	else
        usbhw_control_endpoint_stall();
}
Example #3
0
//-----------------------------------------------------------------
// usb_process_out: Process OUT (on control EP0)
//-----------------------------------------------------------------
static void usb_process_out(void)
{
	unsigned short received;
    unsigned char type;
    unsigned char req;

    // Error: Not expecting DATA-OUT!
	if (!_ctrl_xfer.data_expected)
	{
        log_printf(USBLOG_ERR, "USB: (EP0) OUT received but not expected, STALL\n");
		usbhw_control_endpoint_stall();
	}
	else
	{
		received = usbhw_get_rx_count( ENDPOINT_CONTROL );

        log_printf(USBLOG_SETUP_OUT, "USB: OUT received (%d bytes)\n", received);

		if ( (_ctrl_xfer.data_idx + received) > MAX_CTRL_DATA_LENGTH )
		{
            log_printf(USBLOG_ERR, "USB: Too much OUT EP0 data %d > %d, STALL\n", (_ctrl_xfer.data_idx + received), MAX_CTRL_DATA_LENGTH);
			usbhw_control_endpoint_stall();
		}
		else
		{
			usbhw_get_rx_data(ENDPOINT_CONTROL, &_ctrl_xfer.data_buffer[_ctrl_xfer.data_idx], received);
			_ctrl_xfer.data_idx += received;

            log_printf(USBLOG_SETUP_OUT, "USB: OUT packet re-assembled %d\n", _ctrl_xfer.data_idx);

            // End of transfer (short transfer received?)
		    if (received < EP0_MAX_PACKET_SIZE || _ctrl_xfer.data_idx >= _ctrl_xfer.request.wLength)
		    {
                // Send ZLP (ACK for Status stage)
                log_printf(USBLOG_SETUP_OUT, "USB: Send ZLP status stage %d %d\n", _ctrl_xfer.data_idx, _ctrl_xfer.request.wLength);

                usbhw_load_tx_buffer( ENDPOINT_CONTROL, 0, 0);
			    while (!usbhw_has_tx_space( ENDPOINT_CONTROL ))
                    ;
			    _ctrl_xfer.data_expected = 0;

	            type = _ctrl_xfer.request.bmRequestType & USB_REQUEST_TYPE_MASK;
	            req  = _ctrl_xfer.request.bRequest;

			    usb_process_request(&_ctrl_xfer.request, type, req, _ctrl_xfer.data_buffer);
		    }
            else
                log_printf(USBLOG_SETUP_OUT, "DEV: More data expected!\n");
        }
	}
}
Example #4
0
//-----------------------------------------------------------------
// usb_cdc_process_request:
//-----------------------------------------------------------------
void usb_cdc_process_request(unsigned char req, unsigned short wValue, unsigned short WIndex, unsigned char *data, unsigned short wLength)
{
	switch ( req )
	{
	case CDC_SEND_ENCAPSULATED_COMMAND:
        log_printf(USBLOG_CDC_INFO, "CDC: Send encap\n");
	    cdc_send_encapsulated_command();
	    break;
	case CDC_GET_ENCAPSULATED_RESPONSE:
        log_printf(USBLOG_CDC_INFO, "CDC: Get encap\n");
	    cdc_get_encapsulated_response(wLength);
	    break;
	case CDC_SET_LINE_CODING:
        log_printf(USBLOG_CDC_INFO, "CDC: Set line coding\n");
	    cdc_set_line_coding(data);
	    break;
	case CDC_GET_LINE_CODING:
        log_printf(USBLOG_CDC_INFO, "CDC: Get line coding\n");
	    cdc_get_line_coding(wLength);
	    break;
	case CDC_SET_CONTROL_LINE_STATE:
        log_printf(USBLOG_CDC_INFO, "CDC: Set line state\n");
	    cdc_set_control_line_state();
	    break;
	case CDC_SEND_BREAK:
        log_printf(USBLOG_CDC_INFO, "CDC: Send break\n");
	    cdc_send_break();
	    break;
	default:
        log_printf(USBLOG_CDC_INFO, "CDC: Unknown command\n");
		usbhw_control_endpoint_stall();
		break;
	}
}
Example #5
0
//-----------------------------------------------------------------
// get_status:
//-----------------------------------------------------------------
static void get_status(struct device_request *request)
{    
	unsigned char bRecipient = request->bmRequestType & USB_RECIPIENT_MASK;
    unsigned char data[2] = {0, 0};

    log_printf(USBLOG_INFO, "USB: Get Status %x\n", bRecipient);

	if ( bRecipient == USB_RECIPIENT_DEVICE )
	{
        // Self-powered
		if (!usb_is_bus_powered()) 
            data[0] |= (1 << 0);

        // Remote Wake-up enabled
		if (_remote_wake_enabled) 
            data[0] |= (1 << 1);

		usb_control_send( data, 2 );
	}
	else if ( bRecipient == USB_RECIPIENT_INTERFACE )
	{
		usb_control_send( data, 2 );
	}
	else if ( bRecipient == USB_RECIPIENT_ENDPOINT )
	{
		if (usbhw_is_endpoint_stalled( request->wIndex & ENDPOINT_ADDR_MASK)) 
            data[0] = 1;
		usb_control_send( data, 2 );
	}
	else
        usbhw_control_endpoint_stall();
}
Example #6
0
//-----------------------------------------------------------------
// set_interface:
//-----------------------------------------------------------------
static void set_interface(struct device_request *request)
{
    log_printf(USBLOG_INFO, "USB: set_interface %x %x\n", request->wValue, request->wIndex);

	if ( request->wValue == 0 && request->wIndex == 0 )
		usbhw_control_endpoint_ack();
	else
        usbhw_control_endpoint_stall();
}
Example #7
0
//-----------------------------------------------------------------
// get_descriptor:
//-----------------------------------------------------------------
static void get_descriptor(struct device_request *request)
{
	unsigned char  bDescriptorType = HI_BYTE(request->wValue);
	unsigned char  bDescriptorIndex = LO_BYTE( request->wValue );
	unsigned short wLength = request->wLength;
	unsigned char  bCount = 0;
    unsigned char *desc_ptr;

    desc_ptr = usb_get_descriptor(bDescriptorType, bDescriptorIndex, wLength, &bCount);

    if (desc_ptr)
        usb_control_send(desc_ptr, bCount);
    else
        usbhw_control_endpoint_stall();
}
Example #8
0
//-----------------------------------------------------------------
// set_configuration:
//-----------------------------------------------------------------
static void set_configuration(struct device_request *request)
{
    log_printf(USBLOG_INFO, "USB: set_configuration %x\n", request->wValue);

	if ( request->wValue == 0 )
	{
		usbhw_control_endpoint_ack();
        usbhw_set_configured(0);
	}
    // Only support one configuration for now
	else if ( request->wValue == 1 )
	{
		usbhw_control_endpoint_ack();
        usbhw_set_configured(1);
	}
	else
        usbhw_control_endpoint_stall();
}
Example #9
0
//-----------------------------------------------------------------
// cdc_get_encapsulated_response:
//-----------------------------------------------------------------
static void cdc_get_encapsulated_response (unsigned short wLength)
{
    log_printf(USBLOG_CDC_INFO, "CDC: Get encap\n");

	usbhw_control_endpoint_stall();
}
Example #10
0
//-----------------------------------------------------------------
// usb_process_setup: Process SETUP packet
//-----------------------------------------------------------------
static void usb_process_setup(void)
{
    unsigned char type, req;
    unsigned char setup_pkt[EP0_MAX_PACKET_SIZE];

	usbhw_get_rx_data(ENDPOINT_CONTROL, setup_pkt, EP0_MAX_PACKET_SIZE);

    #if (LOG_LEVEL >= USBLOG_SETUP_DATA)
    {
        int i;

        log_printf(USBLOG_SETUP_DATA, "USB: SETUP data %d\n", EP0_MAX_PACKET_SIZE);
        
        for (i=0;i<EP0_MAX_PACKET_SIZE;i++)
            log_printf(USBLOG_SETUP_DATA, "%02x ", setup_pkt[i]);

        log_printf(USBLOG_SETUP_DATA, "\n");
    }
    #endif

    // Extract packet to local endian format
    _ctrl_xfer.request.bmRequestType = setup_pkt[0];
    _ctrl_xfer.request.bRequest      = setup_pkt[1];
    _ctrl_xfer.request.wValue        = setup_pkt[3];
    _ctrl_xfer.request.wValue      <<= 8;
    _ctrl_xfer.request.wValue       |= setup_pkt[2];
    _ctrl_xfer.request.wIndex        = setup_pkt[5];
    _ctrl_xfer.request.wIndex      <<= 8;
    _ctrl_xfer.request.wIndex       |= setup_pkt[4];
    _ctrl_xfer.request.wLength       = setup_pkt[7];
    _ctrl_xfer.request.wLength     <<= 8;
    _ctrl_xfer.request.wLength      |= setup_pkt[6];

	_ctrl_xfer.data_idx      = 0;
    _ctrl_xfer.data_expected = 0;

	type = _ctrl_xfer.request.bmRequestType & USB_REQUEST_TYPE_MASK;
	req  = _ctrl_xfer.request.bRequest;

    // SETUP - GET
	if (_ctrl_xfer.request.bmRequestType & ENDPOINT_DIR_IN)
	{
        log_printf(USBLOG_SETUP, "USB: SETUP Get wValue=0x%x wIndex=0x%x wLength=%d\n", 
                                    _ctrl_xfer.request.wValue,
                                    _ctrl_xfer.request.wIndex,
                                    _ctrl_xfer.request.wLength);

		usb_process_request(&_ctrl_xfer.request, type, req, _ctrl_xfer.data_buffer);           
	}
    // SETUP - SET
	else
	{
        // No data
		if ( _ctrl_xfer.request.wLength == 0 )
        {
            log_printf(USBLOG_SETUP, "USB: SETUP Set wValue=0x%x wIndex=0x%x wLength=%d\n", 
                                        _ctrl_xfer.request.wValue,
                                        _ctrl_xfer.request.wIndex,
                                        _ctrl_xfer.request.wLength);
            usb_process_request(&_ctrl_xfer.request, type, req, _ctrl_xfer.data_buffer);
        }
        // Data expected
		else
		{
            log_printf(USBLOG_SETUP, "USB: SETUP Set wValue=0x%x wIndex=0x%x wLength=%d [OUT expected]\n", 
                                        _ctrl_xfer.request.wValue,
                                        _ctrl_xfer.request.wIndex,
                                        _ctrl_xfer.request.wLength);
            
			if ( _ctrl_xfer.request.wLength <= MAX_CTRL_DATA_LENGTH )
            {
                // OUT packets expected to follow containing data
				_ctrl_xfer.data_expected = 1;
            }
            // Error: Too much data!
			else
			{
                log_printf(USBLOG_ERR, "USB: More data than max transfer size\n");
                usbhw_control_endpoint_stall();
			}
		}
	}
}
Example #11
0
//-----------------------------------------------------------------
// get_interface:
//-----------------------------------------------------------------
static void get_interface(struct device_request *request)
{
    log_printf(USBLOG_INFO, "USB: Get interface\n");
	usbhw_control_endpoint_stall();
}