rendered paste body/*C**************************************************************************
* NAME: usb_kbd_enum.c
*----------------------------------------------------------------------------
* Copyright (c) 2003 Atmel.
*----------------------------------------------------------------------------
* RELEASE: c5131-usb-kbd-light-1_0_2
* REVISION: 1.2
*----------------------------------------------------------------------------
* PURPOSE:
* This file contains the USB Endpoint 0 management routines corresponding
* to a USB HID keyboard implementation.
*****************************************************************************/
/*_____ I N C L U D E S ____________________________________________________*/
#include "config.h"
#include "lib_mcu\usb\usb_drv.h"
#include "usb_kbd_enum.h"
/*_____ M A C R O S ________________________________________________________*/
/*_____ D E F I N I T I O N ________________________________________________*/
code struct usb_st_device_descriptor usb_device_descriptor =
{
sizeof(usb_device_descriptor), DEVICE, USB_SPECIFICATION, DEVICE_CLASS,
DEVICE_SUB_CLASS, DEVICE_PROTOCOL, EP_CONTROL_LENGTH, VENDOR_ID, PRODUCT_ID,
RELEASE_NUMBER, MAN_INDEX, PROD_INDEX, SN_INDEX, NB_CONFIGURATION
};
code struct usb_st_manufacturer usb_manufacturer =
{ sizeof(usb_manufacturer), STRING, USB_MANUFACTURER_NAME };
code struct usb_st_product usb_product =
{ sizeof(usb_product), STRING, USB_PRODUCT_NAME };
code struct usb_st_serial_number usb_serial_number =
{ sizeof(usb_serial_number), STRING, USB_SERIAL_NUMBER };
code struct usb_st_language_descriptor usb_language =
{ sizeof(usb_language), STRING, LANGUAGE_ID };
code struct
{ struct usb_st_configuration_descriptor cfg;
struct usb_st_interface_descriptor ifc;
struct usb_st_hid_descriptor hid ;
struct usb_st_endpoint_descriptor ep1 ;
Uchar rep[SIZE_OF_REPORT] ;
}
usb_configuration =
{
{ 9, CONFIGURATION, CONF_LENGTH, NB_INTERFACE, CONF_NB,
CONF_INDEX, CONF_ATTRIBUTES, MAX_POWER},
{ 9, INTERFACE, INTERFACE_NB, ALTERNATE, NB_ENDPOINT, INTERFACE_CLASS,
INTERFACE_SUB_CLASS, INTERFACE_PROTOCOL, INTERFACE_INDEX },
{ 9, HID, 0x1101, 8, 1, REPORT, 0x3B00 },
{ 7, ENDPOINT, ENDPOINT_NB_1, EP_ATTRIBUTES_1, EP_SIZE_1, EP_INTERVAL_1 },
{ 0x05,0x01, /* Usage Page (Generic Desktop) */
0x09,0x04, /* Usage (Keyboard) */
0xA1,0x01, /* Collection (Application) */
0x05,0x07, /* Usage Page (Keyboard) */
0x19,224, /* Usage Minimum (224) */
0x29,231, /* Usage Maximum (231) */
0x15,0x00, /* Logical Minimum (0) */
0x25,0x01, /* Logical Maximum (1) */
0x75,0x01, /* Report Size (1) */
0x95,0x08, /* Report Count (8) */
0x81,0x02, /* Input (Data, Variable, Absolute) */
0x81,0x01, /* Input (Constant) */
0x19,0x00, /* Usage Minimum (0) */
0x29,101, /* Usage Maximum (101) */
0x15,0x00, /* Logical Minimum (0) */
0x25,101, /* Logical Maximum (101) */
0x75,0x08, /* Report Size (8) */
0x95,0x06, /* Report Count (6) */
0x81,0x00, /* Input (Data, Array) */
0x05,0x08, /* Usage Page (LED) */
0x19,0x01, /* Usage Minimum (1) */
0x29,0x05, /* Usage Maximum (5) */
0x15,0x00, /* Logical Minimum (0) */
0x25,0x01, /* Logical Maximum (1) */
0x75,0x01, /* Report Size (1) */
0x95,0x05, /* Report Count (5) */
0x91,0x02, /* Output (Data, Variable, Absolute) */
0x95,0x03, /* Report Count (3) */
0x91,0x01, /* Output (Constant) */
0xC0 /* End Collection */
}
};
static bit zlp;
static Uchar endpoint_status[2];
static Uchar hid_idle_duration;
static Uchar *pbuffer;
static Uchar bmRequestType;
Uchar usb_configuration_nb;
extern bit usb_connected;
/*_____ D E C L A R A T I O N ______________________________________________*/
static void usb_get_descriptor (void);
static void usb_read_request (void);
static void usb_set_address (void);
static void usb_set_configuration (void);
static void usb_clear_feature (void);
static void usb_set_feature (void);
static void usb_get_status (void);
static void usb_get_configuration (void);
static void usb_get_interface (void);
static void usb_hid_set_report (void);
static void usb_hid_set_idle (void);
static void usb_hid_get_idle (void);
/*F**************************************************************************
* NAME: usb_var_init
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function initializes the USB controller and resets the endpoints FIFOs.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_var_init (void)
{
endpoint_status[EP_CONTROL] = 0x00;
endpoint_status[EP_IN] = 0x00;
usb_connected = FALSE;
usb_configuration_nb = 0x00;
}
/*F**************************************************************************
* NAME: usb_ep_init
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function configures the endpoints.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_ep_init (void)
{
usb_configure_endpoint(EP_IN , INTERRUPT_IN);
usb_reset_endpoint(EP_IN);
}
/*F**************************************************************************
* NAME: usb_enumeration_process
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the enumeration process
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_enumeration_process (void)
{
Usb_select_ep(EP_CONTROL);
usb_read_request();
}
/*F**************************************************************************
* NAME: usb_read_request
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function reads the SETUP request sent to the default control endpoint
* and the appropriate function. When exiting of the usb_read_request
* function, the device is ready to manage the next request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE: list of supported requests:
* GET_DESCRIPTOR
* GET_CONFIGURATION
* SET_ADDRESS
* SET_CONFIGURATION or SET_REPORT
* CLEAR_FEATURE
* SET_FEATURE
* GET_STATUS
* GET_MAX_LUN
* MASS_STORAGE_RESET
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_read_request (void)
{
bmRequestType = Usb_read_byte(); /* read bmRequestType */
switch (Usb_read_byte()) /* test the bRequest value */
{
case GET_DESCRIPTOR:
usb_get_descriptor();
break;
case GET_CONFIGURATION:
usb_get_configuration();
break;
case SET_ADDRESS:
usb_set_address();
break;
case SET_CONFIGURATION: /* or SET_REPORT */
if (bmRequestType == 0) { usb_set_configuration(); }
else { usb_hid_set_report(); }
break;
case CLEAR_FEATURE:
usb_clear_feature();
break;
case SET_FEATURE:
usb_set_feature();
break;
case GET_STATUS:
usb_get_status();
break;
case GET_INTERFACE: /* HID_SET_IDLE */
if (bmRequestType == 0x81) { usb_get_interface(); }
else { usb_hid_set_idle(); }
break;
case HID_GET_IDLE:
usb_hid_get_idle();
break;
case SET_DESCRIPTOR:
case SET_INTERFACE:
case SYNCH_FRAME:
default:
Usb_clear_rx_setup();
Usb_set_stall_request();
while (!Usb_stall_sent());
Usb_clear_stall_request();
Usb_clear_stalled();
break;
}
Usb_clear_DIR();
}
/*F**************************************************************************
* NAME: usb_set_address
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the SET_ADDRESS request. The new address is stored
* in the USBADDR register
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_set_address (void)
{
Uchar add;
add = Usb_read_byte(); /* store the LSB of wValue = address */
Usb_clear_rx_setup();
Usb_set_tx_ready(); /* send a ZLP for STATUS phase */
Usb_set_FADDEN(); /* The FEN bit and the FADDEN bit in the USBCON register will
be set to allow the USB controller to answer only to requests sent at the new
address */
while (!(Usb_tx_complete()));
Usb_clear_tx_complete();
Usb_configure_address(add); /* FEN bit is set in USBADDR Register */
}
/*F**************************************************************************
* NAME: usb_set_configuration
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the SET_CONFIGURATION request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_set_configuration (void)
{
Uchar configuration_number;
configuration_number = Usb_read_byte(); /* read the conf. num. in wValue */
Usb_clear_DIR();
Usb_clear_rx_setup();
/* switch (configuration_number)
{
case 0:
Usb_clear_CONFG();
usb_configurion = 0x00;
break;
case CONF_NB:
Usb_set_CONFG();
Usb_set_usb_configured();
break;
default:
Usb_set_stall_request();
while (!Usb_stall_sent());
Usb_clear_stall_request();
Usb_clear_stalled();
return;
}*/
if (configuration_number <= CONF_NB)
{
usb_configuration_nb = configuration_number;
}
else
{
Usb_set_stall_request();
while (!Usb_stall_sent());
Usb_clear_stall_request();
Usb_clear_stalled();
return;
}
Usb_set_tx_ready(); /* send a ZLP for STATUS phase */
while (!Usb_tx_complete());
Usb_clear_tx_complete();
usb_ep_init(); /* endpoints configuration */
}
/*F**************************************************************************
* NAME: usb_get_descriptor
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the GET_DESCRIPTOR request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_get_descriptor (void)
{
Uchar data_to_transfer;
Uint16 wLength;
Uchar descriptor_type;
Uchar string_type;
zlp = FALSE; /* no zero length packet */
string_type = Usb_read_byte(); /* read LSB of wValue */
descriptor_type = Usb_read_byte(); /* read MSB of wValue */
switch (descriptor_type)
{
case DEVICE:
{
data_to_transfer = sizeof (usb_device_descriptor);
pbuffer = &(usb_device_descriptor.bLength);
break;
}
case CONFIGURATION:
{
data_to_transfer = sizeof (usb_configuration);
pbuffer = &(usb_configuration.cfg.bLength);
break;
}
case REPORT:
{
data_to_transfer = SIZE_OF_REPORT;
pbuffer = &(usb_configuration.rep[0]);
break;
}
case HID:
{
data_to_transfer = sizeof(usb_configuration.hid);
pbuffer = &(usb_configuration.hid.bLength);
break;
}
case STRING:
{
switch (string_type)
{
case LANG_ID:
{
data_to_transfer = sizeof (usb_language);
pbuffer = &(usb_language.bLength);
break;
}
case MAN_INDEX:
{
data_to_transfer = sizeof (usb_manufacturer);
pbuffer = &(usb_manufacturer.bLength);
break;
}
case PROD_INDEX:
{
data_to_transfer = sizeof (usb_product);
pbuffer = &(usb_product.bLength);
break;
}
case SN_INDEX:
{
data_to_transfer = sizeof (usb_serial_number);
pbuffer = &(usb_serial_number.bLength);
break;
}
default:
{
Usb_clear_rx_setup();
Usb_set_stall_request();
while ((!(Usb_stall_sent())) && (Usb_setup_received()));
Usb_clear_stalled();
Usb_clear_stall_request();
Usb_clear_DIR();
return;
}
}
break;
}
default:
{
Usb_clear_rx_setup();
Usb_set_stall_request();
while ((!(Usb_stall_sent())) && (Usb_setup_received()));
Usb_clear_stalled();
Usb_clear_stall_request();
Usb_clear_DIR();
return;
}
}
ACC = Usb_read_byte(); /* don't care of wIndex field */
ACC = Usb_read_byte();
((Uchar*)&wLength)[1] = Usb_read_byte(); /* read wLength */
((Uchar*)&wLength)[0] = Usb_read_byte();
if (wLength > data_to_transfer)
{
if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; } /*EP_CONTROL_LENGTH IS bMaxPacketSizeO */
/*zlp = zero length packet = success*/
else { zlp = FALSE; } /* no need of zero length packet */
}
else
{
data_to_transfer = (Uchar)wLength; /* send only requested number of data */
}
Usb_clear_rx_setup() ; /* clear the receive setup flag */
Usb_set_DIR(); /* set out on EP0 */
while (data_to_transfer > EP_CONTROL_LENGTH) /* data_to_transfer = size of the descriptor structure */
{
pbuffer = usb_send_ep0_packet(pbuffer, EP_CONTROL_LENGTH);
data_to_transfer -= EP_CONTROL_LENGTH; /* Data = Data - EP */
/* if 3 transactions eg: on 3rd loop, descriptor structure - 2*ep_control_length /*
while ((!(Usb_rx_complete())) && (!(Usb_tx_complete())));
Usb_clear_tx_complete();
if ((Usb_rx_complete())) /* if cancel from USB Host */
{
Usb_clear_tx_ready();
Usb_clear_rx();
return;
}
}
/* send last data packet */
pbuffer = usb_send_ep0_packet(pbuffer, data_to_transfer);
data_to_transfer = 0;
while ((!(Usb_rx_complete())) && (!(Usb_tx_complete())));
Usb_clear_tx_complete();
if ((Usb_rx_complete())) /* if cancel from USB Host */
{
Usb_clear_tx_ready();
Usb_clear_rx();
return;
}
if (zlp == TRUE)
{
usb_send_ep0_packet(pbuffer, 0);
while ((!(Usb_rx_complete())) && (!(Usb_tx_complete())));
Usb_clear_tx_complete();
if ((Usb_rx_complete())) /* if cancel from USB Host */
{
Usb_clear_tx_ready();
Usb_clear_rx();
return;
}
}
while ((!(Usb_rx_complete())) && (!(Usb_setup_received())));
if (Usb_setup_received())
{
return;
}
if (Usb_rx_complete())
{
Usb_clear_DIR(); /* set in on EP0 */
Usb_clear_rx();
}
}
/*F**************************************************************************
* NAME: usb_get_configuration
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the GET_CONFIGURATION request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_get_configuration (void)
{
Usb_clear_rx_setup();
Usb_set_DIR();
/* if (Usb_get_usb_configured()) { Usb_write_byte(1); }
else { Usb_write_byte(0); }
*/
Usb_write_byte(usb_configuration_nb);
Usb_set_tx_ready();
while (!(Usb_tx_complete()));
Usb_clear_tx_complete();
while (!(Usb_rx_complete()));
Usb_clear_rx();
Usb_clear_DIR();
}
/*F**************************************************************************
* NAME: usb_get_interface
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the GET_INTERFACE request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_get_interface (void)
{
Usb_clear_rx_setup();
Usb_set_DIR();
Usb_set_stall_request(); /* send STALL if only one interface configuration */
while (!Usb_stall_sent());
Usb_clear_stall_request();
Usb_clear_stalled();
Usb_clear_DIR();
}
/*F**************************************************************************
* NAME: usb_get_status
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the GET_STATUS request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_get_status (void)
{
Uchar wIndex;
ACC = Usb_read_byte(); /* dummy read */
ACC = Usb_read_byte(); /* dummy read */
wIndex = Usb_read_byte();
Usb_clear_rx_setup();
Usb_set_DIR();
switch(bmRequestType)
{
case REQUEST_DEVICE_STATUS: Usb_write_byte(SELF_POWERED); break;
case REQUEST_INTERFACE_STATUS: Usb_write_byte(0x00); break;
case REQUEST_ENDPOINT_STATUS: wIndex = wIndex & MSK_EP_DIR;
Usb_write_byte(endpoint_status[wIndex]);
break;
}
Usb_write_byte(0x00);
Usb_set_tx_ready();
while ((!(Usb_tx_complete())) || (Usb_setup_received()));
Usb_clear_tx_complete();
while ((!(Usb_rx_complete())) || (Usb_setup_received()));
Usb_clear_rx();
Usb_clear_DIR();
}
/*F**************************************************************************
* NAME: usb_set_feature
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the SET_FEATURE request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_set_feature (void)
{
if (bmRequestType == ZERO_TYPE)
{
Usb_clear_rx_setup();
Usb_set_stall_request();
while (!(Usb_stall_sent()));
Usb_clear_stall_request();
}
if (bmRequestType == INTERFACE_TYPE)
{
Usb_clear_rx_setup();
Usb_set_stall_request();
while (!(Usb_stall_sent()));
Usb_clear_stall_request();
}
if (bmRequestType == ENDPOINT_TYPE)
{
if (Usb_read_byte() == 0x00)
{
ACC = Usb_read_byte(); /* dummy read */
switch (Usb_read_byte()) /* check wIndex */
{
case ENDPOINT_1:
{
Usb_select_ep(EP_IN);
Usb_set_stall_request();
Usb_select_ep(EP_CONTROL);
endpoint_status[EP_IN] = 0x01;
Usb_clear_rx_setup();
Usb_set_tx_ready();
while (!(Usb_tx_complete()));
Usb_clear_tx_complete();
break;
}
default:
{
Usb_clear_rx_setup();
Usb_set_stall_request();
while (!(Usb_stall_sent()));
Usb_clear_stall_request();
Usb_clear_stalled();
break;
}
}
}
}
}
/*F**************************************************************************
* NAME: usb_clear_feature
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the SET_FEATURE request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_clear_feature (void)
{
if (bmRequestType == ZERO_TYPE)
{
Usb_clear_rx_setup();
Usb_set_stall_request();
while (!(Usb_stall_sent()));
Usb_clear_stall_request();
}
if (bmRequestType == INTERFACE_TYPE)
{
Usb_clear_rx_setup();
Usb_set_stall_request();
while (!(Usb_stall_sent()));
Usb_clear_stall_request();
}
if (bmRequestType == ENDPOINT_TYPE)
{
if (Usb_read_byte() == 0x00)
{
ACC = Usb_read_byte(); /* dummy read */
switch (Usb_read_byte()) /* check wIndex */
{
case ENDPOINT_1:
{
Usb_select_ep(EP_IN);
Usb_clear_stall_request();
usb_reset_endpoint(EP_IN);
Usb_select_ep(EP_CONTROL);
endpoint_status[EP_IN] = 0x00;
Usb_clear_rx_setup();
Usb_set_tx_ready();
while (!(Usb_tx_complete()));
Usb_clear_tx_complete();
break;
}
case ENDPOINT_0:
{
Usb_clear_rx_setup();
Usb_set_tx_ready();
while (!(Usb_tx_complete()));
Usb_clear_tx_complete();
break;
}
default:
{
Usb_clear_rx_setup();
Usb_set_stall_request();
while (!(Usb_stall_sent()));
Usb_clear_stall_request();
break;
}
}
}
}
}
/*F**************************************************************************
* NAME: usb_hid_set_report
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the SET_REPORT request (HID Class)
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_hid_set_report (void)
{
Usb_clear_rx_setup();
while(!Usb_rx_complete() );
Usb_clear_rx();
Usb_set_tx_ready(); /* send a ZLP for STATUS phase */
while(!(Usb_tx_complete()));
Usb_clear_tx_complete();
}
/*F**************************************************************************
* NAME: usb_hid_set_idle
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the HID_SET_IDLE request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_hid_set_idle (void)
{
ACC = Usb_read_byte();
hid_idle_duration = Usb_read_byte(); /* wValue contains the duration */
Usb_clear_rx_setup();
Usb_set_tx_ready(); /* send a ZLP for STATUS phase */
while(!(Usb_tx_complete()));
Usb_clear_tx_complete();
}
/*F**************************************************************************
* NAME: usb_hid_get_idle
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the GET_IDLE request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_hid_get_idle (void)
{
Usb_clear_rx_setup();
Usb_set_DIR();
Usb_write_byte(hid_idle_duration);
Usb_set_tx_ready(); /* send a ZLP for STATUS phase */
while(!(Usb_tx_complete()));
Usb_clear_tx_complete();
while (!(Usb_rx_complete()));
Usb_clear_rx();
Usb_clear_DIR();
}
/*_____ E N D O F F I L E _________________________________________________*/