Example #1
0
File: usb.c Project: boseji/nrfburn
void usbRequestReceived(void)
{
	uint8_t requestType = usbRequest.bmRequestType & 0x60;

	// reset the ep0 packetizer
	packetizer_data_ptr = 0;
	packetizer_data_size = 0;
	
	if (requestType == 0x00)		// standard request
	{
		uint8_t recipient = usbRequest.bmRequestType & 0x1f;

		if (recipient == 0)			// device
			usbStdDeviceRequest();
		else if (recipient == 1)	// interface
			usbStdInterfaceRequest();
		else if (recipient == 2)	// endpoint
			usbStdEndpointRequest();
		else
			USB_EP0_STALL();
			
	} else if (requestType == 0x20) {	// class request

		usbHidRequest();
		
	//} else if (requestType == 0x40) {	// vendor request
	} else {
		// stall on unsupported requests
		USB_EP0_STALL();
	}
}
Example #2
0
static void usb_process_get_descriptor()
{ 
    packetizer_pkt_size = MAX_PACKET_SIZE_EP0;
    // Switch on descriptor type
    switch(setupbuf[3])
    {
        case USB_DESC_DEVICE:
            packetizer_data_ptr = (uint8_t*)&g_usb_dev_desc;
            packetizer_data_size = MIN(setupbuf[6], sizeof(hal_usb_dev_desc_t));
            packetizer_isr_ep0_in();
            break;

        case USB_DESC_CONFIGURATION:
            // For now we just support one configuration. The asked configuration is stored in LSB(wValue).
            packetizer_data_ptr = (uint8_t*)&g_usb_conf_desc;
            packetizer_data_size = MIN(setupbuf[6], sizeof(usb_conf_desc_templ_t));
            packetizer_isr_ep0_in();
            break;

        case USB_DESC_STRING:
            // For now we just support english as string descriptor language.
            if(setupbuf[2] == 0x00)
            {
                packetizer_data_ptr = string_zero;
                packetizer_data_size = MIN(setupbuf[6], sizeof(string_zero));
                packetizer_isr_ep0_in();
            }
            else
            {
                if((setupbuf[2] - 1) < USB_STRING_DESC_COUNT)
                {
                    if (setupbuf[2] == 1)
                        packetizer_data_ptr = g_usb_string_desc_1;
                    else
                        packetizer_data_ptr = g_usb_string_desc_2;;
                    packetizer_data_size = MIN(setupbuf[6], packetizer_data_ptr[0]);
                    packetizer_isr_ep0_in();
                }
                else
                {
                    USB_EP0_STALL();
                }
            }
            break;
        case USB_DESC_INTERFACE:
        case USB_DESC_ENDPOINT:
        case USB_DESC_DEVICE_QUAL:
        case USB_DESC_OTHER_SPEED_CONF:
        case USB_DESC_INTERFACE_POWER:
            USB_EP0_STALL();
            break;
        default:
            USB_EP0_HSNAK();
            break;
    }
}
Example #3
0
File: usb.c Project: nodep/wht
void usbHidRequest(void)
{
	uint8_t bRequest = usbRequest.bRequest;

	if (bRequest == USB_REQ_HID_SET_REPORT)
	{
		// we get and process the actual data in usbRequestDataReceived()

	} else if (bRequest == USB_REQ_HID_GET_REPORT) {

		on_get_report();

	} else if (bRequest == USB_REQ_HID_GET_IDLE) {

		in0buf[0] = usbHidIdle;
		in0bc = 0x01;

	} else if (bRequest == USB_REQ_HID_SET_IDLE) {

		usbHidIdle = usbRequest.wValueMSB;

		// wValueLSB holds the reportID for which this rate applies,
		// but we only have one, so this does not concern us

		usbFrameCnt = 0;	// reset idle counter

		// send an empty packet and ACK the request
		in0bc = 0x00;
		USB_EP0_HSNAK();

	} else {
		USB_EP0_STALL();
	}
}
static void usb_process_get_status()
{
	IN0BUF[0] = 0;
	IN0BUF[1] = 0x00;
	if((usb_state == ADDRESSED) && (SETUPBUF[4] == 0x00))
	{
		IN0BC = 0x02;
	}
	else if(usb_state == CONFIGURED)
	{
		switch(bmRequestType)
		{
		case 0x80: // Device
			if((usb_bm_state & USB_BM_STATE_ALLOW_REMOTE_WAKEUP ) == USB_BM_STATE_ALLOW_REMOTE_WAKEUP)
			{
				IN0BUF[0] = 0x02;
			}
			IN0BC = 0x02;
			break;

		case 0x81: // Interface
			IN0BC = 0x02;
			break;

		case 0x82: // Endpoint
			if((SETUPBUF[4] & 0x80) == 0x80) // IN endpoints
				IN0BUF[0] = IN1CS;
			else
				IN0BUF[0] = OUT1CS;
			IN0BC = 0x02;
			break;
		default:
			USB_EP0_STALL();
			break;
		}
	}
	else
	{
		// We should not be in this state
		USB_EP0_STALL();
	}
}
Example #5
0
static void usb_process_get_status()
{
    in0buf[0] = in0buf[1] = 0x00;
    if((usb_state == ADDRESSED) && (setupbuf[4] == 0x00))
    {
        in0bc = 0x02;
    }
    else if(usb_state == CONFIGURED)
    {
        switch(bmRequestType)
        {
            case 0x80: // Device
                if((usb_bm_state & USB_BM_STATE_ALLOW_REMOTE_WAKEUP ) == USB_BM_STATE_ALLOW_REMOTE_WAKEUP)
                {
                    in0buf[0] = 0x02;
                }
                in0bc = 0x02;
                break;

            case 0x81: // Interface
                in0bc = 0x02;
                break;

            case 0x82: // Endpoint
                if((setupbuf[4] & 0x80) == 0x80) // IN endpoints
                    in0buf[0] = in1cs;
                else
                    in0buf[0] = out1cs;
                in0bc = 0x02;
                break;
            default:
                USB_EP0_STALL();
                break;
        }
    }
    else
    {
        // We should not be in this state
        USB_EP0_STALL();
    }
}
Example #6
0
File: usb.c Project: nodep/wht
void usbGetDescriptor(void)
{
	uint8_t descriptor = usbReqGetDesc.descType;

	packetizer_data_ptr = 0;
	packetizer_data_size = 0;

	if (descriptor == USB_DESC_DEVICE)
	{
		packetizer_data_ptr = (__code uint8_t*) &usb_dev_desc;
		packetizer_data_size = MIN(usbReqGetDesc.lengthLSB, packetizer_data_ptr[0]);
	} else if (descriptor == USB_DESC_CONFIGURATION) {
		packetizer_data_ptr = (__code uint8_t*) &joystick_conf_desc;
		packetizer_data_size = MIN(usbReqGetDesc.lengthLSB, sizeof joystick_conf_desc);
	} else if (descriptor == USB_DESC_STRING) {

		uint8_t string_id = usbReqGetDesc.descIndex;

		// string index 0 is list of supported lang ids
		if (string_id < USB_STRING_DESC_COUNT)
		{
			if (usbReqGetDesc.descIndex == 0)
				packetizer_data_ptr = usb_string_desc_0;
			else if (string_id == 1)
				packetizer_data_ptr = (__code uint8_t*) usb_string_desc_1;
			else if (string_id == 2)
				packetizer_data_ptr = (__code uint8_t*) usb_string_desc_2;
			else
				packetizer_data_ptr = (__code uint8_t*) usb_string_desc_3;

			if (usbReqGetDesc.lengthMSB > 0)
				packetizer_data_size = 0xff;
			else
				packetizer_data_size = MIN(usbReqGetDesc.lengthLSB, packetizer_data_ptr[0]);
		}
	} else if (descriptor == USB_DESC_HID_REPORT) {
		if (usbReqHidGetDesc.interface == 0)
		{
			packetizer_data_ptr = joystick_hid_report_descriptor;
			packetizer_data_size = MIN(usbReqGetDesc.lengthLSB, JOYSTICK_HID_REPORT_DESC_SIZE);
		} else {
			packetizer_data_ptr = mouse_hid_report_descriptor;
			packetizer_data_size = MIN(usbReqGetDesc.lengthLSB, MOUSE_HID_REPORT_DESC_SIZE);
		}
	}

	if (packetizer_data_ptr)
		packetizer_isr_ep0_in();
	else
		USB_EP0_STALL();
}
Example #7
0
File: usb.c Project: boseji/nrfburn
void usbHidRequest(void)
{
	uint8_t bRequest = usbRequest.bRequest;

	if (bRequest == USB_REQ_HID_SET_REPORT)
	{
		// we have to wait for the 1 byte LED report
		// which will come with the next EP0OUT interrupt

	} else if (bRequest == USB_REQ_HID_GET_REPORT) {

		// this requests the HID report we defined with the HID report descriptor.
		// this is usually sent over EP1 IN, but can be sent over EP0 too.

		in0buf[0] = kbdReport.modifiers;
		in0buf[1] = 0;
		in0buf[2] = kbdReport.keys[0];
		in0buf[3] = kbdReport.keys[1];
		in0buf[4] = kbdReport.keys[2];
		in0buf[5] = kbdReport.keys[3];
		in0buf[6] = kbdReport.keys[4];
		in0buf[7] = kbdReport.keys[5];

		// send the data on it's way
		in0bc = 8;
		
	} else if (bRequest == USB_REQ_HID_GET_IDLE) {

		in0buf[0] = usbHidIdle;
		in0bc = 0x01;
	
	} else if (bRequest == USB_REQ_HID_SET_IDLE) {

		usbHidIdle = usbRequest.wValueMSB;
		
		// wValueLSB holds the reportID for which this rate applies,
		// but we only have one, so this does not concern us

		usbFrameCnt = 0;	// reset idle counter

		// send an empty packet and ACK the request
		in0bc = 0x00;
		USB_EP0_HSNAK();
		
	} else {
		USB_EP0_STALL();
	}
}
Example #8
0
File: usb.c Project: boseji/nrfburn
void usbGetDescriptor(void)
{
	uint8_t descriptor = usbReqGetDesc.descType;

	packetizer_data_ptr = 0;
	packetizer_data_size = 0;
	
	if (descriptor == USB_DESC_DEVICE)
	{
		packetizer_data_ptr = (__code uint8_t*) &usb_dev_desc;
		packetizer_data_size = MIN(usbReqGetDesc.lengthLSB, packetizer_data_ptr[0]);
	} else if (descriptor == USB_DESC_CONFIGURATION) {
		packetizer_data_ptr = (__code uint8_t*) &usb_conf_desc;
		packetizer_data_size = MIN(usbReqGetDesc.lengthLSB, sizeof usb_conf_desc);
	} else if (descriptor == USB_DESC_STRING) {

		uint8_t string_id = usbReqGetDesc.descIndex;
		
		// string index 0 is list of supported lang ids
		if (string_id < USB_STRING_DESC_COUNT)
		{
			if (usbReqGetDesc.descIndex == 0)
				packetizer_data_ptr = usb_string_desc_0;
			else if (string_id == 1)
				packetizer_data_ptr = (__code uint8_t*) usb_string_desc_1;
			else if (string_id == 2)
				packetizer_data_ptr = (__code uint8_t*) usb_string_desc_2;
			else
				packetizer_data_ptr = (__code uint8_t*) usb_string_desc_3;

			packetizer_data_size = MIN(usbReqGetDesc.lengthLSB, packetizer_data_ptr[0]);
		}
	} else if (descriptor == USB_DESC_HID_REPORT) {
		packetizer_data_ptr = usb_hid_report_descriptor;
		packetizer_data_size = MIN(usbReqGetDesc.lengthLSB, USB_HID_REPORT_DESCRIPTOR_SIZE);
	}

	if (packetizer_data_ptr)
		packetizer_isr_ep0_in();
	else
		USB_EP0_STALL();
}
Example #9
0
File: usb.c Project: boseji/nrfburn
void usbStdInterfaceRequest(void)
{
	uint8_t bRequest = usbRequest.bRequest;
	
	if (bRequest == USB_REQ_GET_STATUS)
	{
		if (usb_state == CONFIGURED)
		{
			// all values are reserved for interfaces
			in0buf[0] = 0x00;
			in0buf[1] = 0x00;
			in0bc = 0x02;
		}
	} else if (bRequest == USB_REQ_GET_DESCRIPTOR) {
		// this requests the HID report descriptor
		usbGetDescriptor();
	} else {
		USB_EP0_STALL();
	}
}
Example #10
0
File: usb.c Project: boseji/nrfburn
void usbStdEndpointRequest(void)
{
	if (usbRequest.bRequest == USB_REQ_GET_STATUS)
	{
		if (usb_state == CONFIGURED)
		{
			// return Halt feature status
			uint8_t endpoint = usbRequest.wIndexLSB;
			if (endpoint == 0x81)
				in0buf[0] = in1cs & 0x01;
			else if (endpoint == 0x82)
				in0buf[0] = in2cs & 0x01;
			else if (endpoint == 0x01)
				in0buf[0] = out1cs & 0x01;

			in0bc = 0x02;
		}
	} else {
		USB_EP0_STALL();
	}
}
Example #11
0
File: usb.c Project: nodep/wht
void usbStdEndpointRequest(void)
{
	if (usbRequest.bRequest == USB_REQ_GET_STATUS)
	{
		if (usb_state == CONFIGURED)
		{
			// return Halt feature status
			uint8_t endpoint = usbRequest.wIndexLSB;
			if (endpoint == 0x81)
				in0buf[0] = in1cs & 0x01;
			else if (endpoint == 0x01)
				in0buf[0] = out1cs & 0x01;

			in0bc = 0x02;
		}
	} else if (usbRequest.bRequest == USB_REQ_CLEAR_FEATURE  ||  usbRequest.bRequest == USB_REQ_SET_FEATURE) {
		// send an empty packet and ACK the request
		in0bc = 0x00;
		USB_EP0_HSNAK();
	} else {
		USB_EP0_STALL();
	}
}
Example #12
0
File: usb.c Project: boseji/nrfburn
void usbStdDeviceRequest(void)
{
	switch (usbRequest.bRequest)
	{
	case USB_REQ_GET_STATUS:
		// We must be in ADDRESSED or CONFIGURED state, and wIndex must be 0
		if ((usb_state == ADDRESSED || usb_state == CONFIGURED)  &&  usbRequest.wIndexLSB == 0x00)
		{
			// We aren't self-powered and we don't support remote wakeup
			in0buf[0] = 0x00;
			in0buf[1] = 0x00;
			in0bc = 0x02;
		} else {
			// Stall for invalid requests
			USB_EP0_STALL();
		}
		break;

	case USB_REQ_SET_ADDRESS:
		// USB controller takes care of setting our address
		usb_state = ADDRESSED;
		break;

	case USB_REQ_GET_DESCRIPTOR:
		usbGetDescriptor();
		break;

	case USB_REQ_GET_CONFIGURATION:
	
		if (usb_state == ADDRESSED)
		{
			in0buf[0] = 0x00;
			in0bc = 0x01;
		} else if (usb_state == CONFIGURED) {
			in0buf[0] = usb_current_config;
			in0bc = 0x01;
		} else {
			// Behavior not specified in other states, so STALL
			USB_EP0_STALL();
		}

		break;

	case USB_REQ_SET_CONFIGURATION:

		if (usbRequest.wValueLSB == 0x00)
		{
			usb_state = ADDRESSED;
			usb_current_config = 0x00;
			// Since there isn't a data stage for this request,
			//   we have to explicitly clear the NAK bit
			USB_EP0_HSNAK();
		} else if (usbRequest.wValueLSB == 0x01) {
			usb_state = CONFIGURED;
			usb_current_config = 0x01;
			// Since there isn't a data stage for this request,
			//   we have to explicitly clear the NAK bit
			USB_EP0_HSNAK();
		} else {
			// Stall for invalid config values
			USB_EP0_STALL();
		}
		break;
	}
}
Example #13
0
static void isr_sudav()
{
	packetizer_pkt_size = MAX_PACKET_SIZE_EP0;
	bmRequestType = SETUPBUF[0];
	if((bmRequestType & 0x60 ) == 0x00)
	{
		switch(SETUPBUF[1])
		{
		case USB_REQ_GET_DESCRIPTOR:
			usb_process_get_descriptor();
			break;

		case USB_REQ_GET_STATUS:
			usb_process_get_status();
			break;

		case USB_REQ_SET_ADDRESS:
			usb_state = ADDRESSED;
			usb_current_config = 0x00;
			break;

		case USB_REQ_GET_CONFIGURATION:
			switch(usb_state)
			{
			case ADDRESSED:
				IN0BUF[0] = 0x00;
				IN0BC = 0x01;
				break;
			case CONFIGURED:
				IN0BUF[0] = usb_current_config;
				IN0BC = 0x01;
				break;
			case ATTACHED:
			case POWERED:
			case SUSPENDED:
			case DEFAULT:
			default:
				USB_EP0_STALL();
				break;
			}
			break;

		case USB_REQ_SET_CONFIGURATION:
			switch(SETUPBUF[2])
			{
			case 0x00:
				usb_state = ADDRESSED;
				usb_current_config = 0x00;
				USB_EP0_HSNAK();
				break;
			case 0x01:
				usb_state = CONFIGURED;
				usb_bm_state |= USB_BM_STATE_CONFIGURED;
				usb_current_config = 0x01;
				USB_EP0_HSNAK();
				break;
			default:
				USB_EP0_STALL();
				break;
			}
			break;

		case USB_REQ_GET_INTERFACE: // GET_INTERFACE
			IN0BUF[0] = usb_current_alt_interface;
			IN0BC = 0x01;
			break;

		case USB_REQ_SET_DESCRIPTOR:
		case USB_REQ_SET_INTERFACE: // SET_INTERFACE
		case USB_REQ_SYNCH_FRAME:   // SYNCH_FRAME
		default:
			USB_EP0_STALL();
			break;
		}
	} 
	// bmRequestType = 0 01 xxxxx : Data transfer direction: Host-to-device, Type: Class
	else if((bmRequestType & 0x60 ) == 0x20)  // Class request
	{
		bool cret = handle_class_request((usbRequest_t *) SETUPBUF);
		
		if (SETUPBUF[6] != 0 && ((bmRequestType & 0x80) == 0x00))
			OUT0BC = 0xff;
		else if (!cret)
			USB_EP0_HSNAK();

	} else  // Unknown request type
	{
		USB_EP0_STALL();
	}

}
Example #14
0
static void usb_process_get_descriptor()
{ 
	FSR&=~(1<<3);
	switch(SETUPBUF[3])
	{	    
	case USB_DESC_DEVICE:
		ep0_send_data((__xdata uint8_t *)&g_usb_dev_desc, sizeof(usb_dev_desc_t));
		//send_ipage_descriptor(IPAGE_OFF_g_usb_dev_desc, IPAGE_LEN_g_usb_dev_desc);
		break;
	    
	case USB_DESC_CONFIGURATION:
		ep0_send_data((__xdata uint8_t *)&g_usb_conf_desc, sizeof(usb_conf_desc_bootloader_t));
		//send_ipage_descriptor(IPAGE_OFF_g_usb_conf_desc, IPAGE_LEN_g_usb_conf_desc);
		break;

	case USB_DESC_HID:
		ep0_send_data((__xdata uint8_t *)&g_usb_conf_desc.hid, sizeof(usb_hid_desc_t));
		break;
	case USB_DESC_HID_REPORT:
		ep0_send_data((__xdata uint8_t *)&g_usb_hid_report_desc, USB_DESC_HID_LEN);
		break;
        case USB_DESC_STRING:
		if(SETUPBUF[2] == 0x00)
		{
			ep0_send_data((__xdata uint8_t *)string_zero, sizeof(string_zero));
		}
		else
		{
			if((SETUPBUF[2] - 1) < USB_STRING_DESC_COUNT)
			{
				uint8_t *ptr;
				switch (SETUPBUF[2]) {
				case 1:
					ptr = g_usb_string_desc_1;
					break;
				case 2:
					ptr = g_usb_string_desc_2;
					break;
				case 3:
					ptr = g_usb_string_desc_3;
					break;
				}
				ep0_send_data((__xdata uint8_t *) ptr, ptr[0]);
			}
			else
			{
				USB_EP0_STALL();
			}
		}
		break;
        case USB_DESC_INTERFACE:
        case USB_DESC_ENDPOINT:
        case USB_DESC_DEVICE_QUAL:
        case USB_DESC_OTHER_SPEED_CONF:
        case USB_DESC_INTERFACE_POWER:
		USB_EP0_STALL();
		break;
        default:
		USB_EP0_HSNAK();
		break;
	}
}
Example #15
0
static void isr_sudav()
{
    bmRequestType = setupbuf[0];
    if((bmRequestType & 0x60 ) == 0x00)
    {
        switch(setupbuf[1])
        {
           case USB_REQ_GET_DESCRIPTOR:
               usb_process_get_descriptor();
               break;

           case USB_REQ_GET_STATUS:
               usb_process_get_status();
               break;

            case USB_REQ_SET_ADDRESS:
               usb_state = ADDRESSED;
               usb_current_config = 0x00;
               break;

            case USB_REQ_GET_CONFIGURATION:
                switch(usb_state)
                {
                    case ADDRESSED:
                        in0buf[0] = 0x00;
                        in0bc = 0x01;
                        break;
                    case CONFIGURED:
                        in0buf[0] = usb_current_config;
                        in0bc = 0x01;
                        break;
                    case ATTACHED:
                    case POWERED:
                    case SUSPENDED:
                    case DEFAULT:
                    default:
                        USB_EP0_STALL();
                        break;
                }
                break;

            case USB_REQ_SET_CONFIGURATION:
                switch(setupbuf[2])
                {
                    case 0x00:
                        usb_state = ADDRESSED;
                        usb_current_config = 0x00;
                        USB_EP0_HSNAK();
                        break;
                    case 0x01:
                        usb_state = CONFIGURED;
                        usb_bm_state |= USB_BM_STATE_CONFIGURED;
                        usb_current_config = 0x01;
                        USB_EP0_HSNAK();
                        break;
                    default:
                        USB_EP0_STALL();
                        break;
                }
               break;

            case USB_REQ_GET_INTERFACE: // GET_INTERFACE
                in0buf[0] = usb_current_alt_interface;
                in0bc = 0x01;
                break;

            case USB_REQ_SET_DESCRIPTOR:
            case USB_REQ_SET_INTERFACE: // SET_INTERFACE
            case USB_REQ_SYNCH_FRAME:   // SYNCH_FRAME
            default:
                USB_EP0_STALL();
                break;
        }
    } 
    // bmRequestType = 0 01 xxxxx : Data transfer direction: Host-to-device, Type: Class
    else if((bmRequestType & 0x60 ) == 0x20)  // Class request
    {
        if(setupbuf[6] != 0 && ((bmRequestType & 0x80) == 0x00))
        {
            // If there is a OUT-transaction associated with the Control-Transfer-Write we call the callback
            // when the OUT-transaction is finished. Note that this function do not handle several out transactions.
            out0bc = 0xff;
        }
        else
        {
            USB_EP0_HSNAK();
        }
    } 
    else  // Unknown request type
    {
        USB_EP0_STALL();
    }
}