/* Also update external declarations in "include/usb.h" if making changes to
* these variables! */
-volatile bool EP2_out = 0;
-volatile bool EP2_in = 0;
+volatile bool EP2_out;
+volatile bool EP2_in;
volatile __xdata __at 0x7FE8 struct setup_data setup_data;
/* Define number of endpoints (except Control Endpoint 0) in a central place.
* Be sure to include the neccessary endpoint descriptors! */
-#define NUM_ENDPOINTS 2
+#define NUM_ENDPOINTS 2
/*
* Normally, we would initialize the descriptor structures in C99 style:
*/
__code struct usb_device_descriptor device_descriptor = {
- /* .bLength = */ sizeof(struct usb_device_descriptor),
- /* .bDescriptorType = */ DESCRIPTOR_TYPE_DEVICE,
- /* .bcdUSB = */ 0x0110, /* BCD: 01.00 (Version 1.0 USB spec) */
- /* .bDeviceClass = */ 0xFF, /* 0xFF = vendor-specific */
- /* .bDeviceSubClass = */ 0xFF,
- /* .bDeviceProtocol = */ 0xFF,
- /* .bMaxPacketSize0 = */ 64,
- /* .idVendor = */ 0xC251,
- /* .idProduct = */ 0x2710,
- /* .bcdDevice = */ 0x0100,
- /* .iManufacturer = */ 1,
- /* .iProduct = */ 2,
- /* .iSerialNumber = */ 3,
- /* .bNumConfigurations = */ 1
+ /* .bLength = */ sizeof(struct usb_device_descriptor),
+ /* .bDescriptorType = */ DESCRIPTOR_TYPE_DEVICE,
+ /* .bcdUSB = */ 0x0110, /* BCD: 01.00 (Version 1.0 USB spec) */
+ /* .bDeviceClass = */ 0xFF, /* 0xFF = vendor-specific */
+ /* .bDeviceSubClass = */ 0xFF,
+ /* .bDeviceProtocol = */ 0xFF,
+ /* .bMaxPacketSize0 = */ 64,
+ /* .idVendor = */ 0xC251,
+ /* .idProduct = */ 0x2710,
+ /* .bcdDevice = */ 0x0100,
+ /* .iManufacturer = */ 1,
+ /* .iProduct = */ 2,
+ /* .iSerialNumber = */ 3,
+ /* .bNumConfigurations = */ 1
};
/* WARNING: ALL config, interface and endpoint descriptors MUST be adjacent! */
__code struct usb_config_descriptor config_descriptor = {
- /* .bLength = */ sizeof(struct usb_config_descriptor),
- /* .bDescriptorType = */ DESCRIPTOR_TYPE_CONFIGURATION,
- /* .wTotalLength = */ sizeof(struct usb_config_descriptor) +
- sizeof(struct usb_interface_descriptor) +
- (NUM_ENDPOINTS *
- sizeof(struct usb_endpoint_descriptor)),
- /* .bNumInterfaces = */ 1,
- /* .bConfigurationValue = */ 1,
- /* .iConfiguration = */ 4, /* String describing this configuration */
- /* .bmAttributes = */ 0x80, /* Only MSB set according to USB spec */
- /* .MaxPower = */ 50 /* 100 mA */
+ /* .bLength = */ sizeof(struct usb_config_descriptor),
+ /* .bDescriptorType = */ DESCRIPTOR_TYPE_CONFIGURATION,
+ /* .wTotalLength = */ sizeof(struct usb_config_descriptor) +
+ sizeof(struct usb_interface_descriptor) +
+ (NUM_ENDPOINTS *
+ sizeof(struct usb_endpoint_descriptor)),
+ /* .bNumInterfaces = */ 1,
+ /* .bConfigurationValue = */ 1,
+ /* .iConfiguration = */ 4, /* String describing this configuration */
+ /* .bmAttributes = */ 0x80, /* Only MSB set according to USB spec */
+ /* .MaxPower = */ 50 /* 100 mA */
};
__code struct usb_interface_descriptor interface_descriptor00 = {
- /* .bLength = */ sizeof(struct usb_interface_descriptor),
- /* .bDescriptorType = */ DESCRIPTOR_TYPE_INTERFACE,
- /* .bInterfaceNumber = */ 0,
- /* .bAlternateSetting = */ 0,
- /* .bNumEndpoints = */ NUM_ENDPOINTS,
- /* .bInterfaceClass = */ 0xFF,
- /* .bInterfaceSubclass = */ 0xFF,
- /* .bInterfaceProtocol = */ 0xFF,
- /* .iInterface = */ 0
+ /* .bLength = */ sizeof(struct usb_interface_descriptor),
+ /* .bDescriptorType = */ DESCRIPTOR_TYPE_INTERFACE,
+ /* .bInterfaceNumber = */ 0,
+ /* .bAlternateSetting = */ 0,
+ /* .bNumEndpoints = */ NUM_ENDPOINTS,
+ /* .bInterfaceClass = */ 0xFF,
+ /* .bInterfaceSubclass = */ 0xFF,
+ /* .bInterfaceProtocol = */ 0xFF,
+ /* .iInterface = */ 0
};
__code struct usb_endpoint_descriptor Bulk_EP2_IN_Endpoint_Descriptor = {
- /* .bLength = */ sizeof(struct usb_endpoint_descriptor),
- /* .bDescriptorType = */ 0x05,
- /* .bEndpointAddress = */ 2 | USB_DIR_IN,
- /* .bmAttributes = */ 0x02,
- /* .wMaxPacketSize = */ 64,
- /* .bInterval = */ 0
+ /* .bLength = */ sizeof(struct usb_endpoint_descriptor),
+ /* .bDescriptorType = */ 0x05,
+ /* .bEndpointAddress = */ 2 | USB_DIR_IN,
+ /* .bmAttributes = */ 0x02,
+ /* .wMaxPacketSize = */ 64,
+ /* .bInterval = */ 0
};
__code struct usb_endpoint_descriptor Bulk_EP2_OUT_Endpoint_Descriptor = {
- /* .bLength = */ sizeof(struct usb_endpoint_descriptor),
- /* .bDescriptorType = */ 0x05,
- /* .bEndpointAddress = */ 2 | USB_DIR_OUT,
- /* .bmAttributes = */ 0x02,
- /* .wMaxPacketSize = */ 64,
- /* .bInterval = */ 0
+ /* .bLength = */ sizeof(struct usb_endpoint_descriptor),
+ /* .bDescriptorType = */ 0x05,
+ /* .bEndpointAddress = */ 2 | USB_DIR_OUT,
+ /* .bmAttributes = */ 0x02,
+ /* .wMaxPacketSize = */ 64,
+ /* .bInterval = */ 0
};
__code struct usb_language_descriptor language_descriptor = {
- /* .bLength = */ 4,
- /* .bDescriptorType = */ DESCRIPTOR_TYPE_STRING,
- /* .wLANGID = */ {0x0409 /* US English */}
+ /* .bLength = */ 4,
+ /* .bDescriptorType = */ DESCRIPTOR_TYPE_STRING,
+ /* .wLANGID = */ {0x0409 /* US English */}
};
__code struct usb_string_descriptor strManufacturer =
- STR_DESCR(9,'O','p','e','n','U','L','I','N','K');
+ STR_DESCR(9, 'O', 'p', 'e', 'n', 'U', 'L', 'I', 'N', 'K');
-__code struct usb_string_descriptor strProduct =
- STR_DESCR(9,'O','p','e','n','U','L','I','N','K');
+__code struct usb_string_descriptor strProduct =
+ STR_DESCR(9, 'O', 'p', 'e', 'n', 'U', 'L', 'I', 'N', 'K');
__code struct usb_string_descriptor strSerialNumber =
- STR_DESCR(6, '0','0','0','0','0','1');
+ STR_DESCR(6, '0', '0', '0', '0', '0', '1');
__code struct usb_string_descriptor strConfigDescr =
- STR_DESCR(12, 'J','T','A','G',' ','A','d','a','p','t','e','r');
+ STR_DESCR(12, 'J', 'T', 'A', 'G', ' ', 'A', 'd', 'a', 'p', 't', 'e', 'r');
/* Table containing pointers to string descriptors */
-__code struct usb_string_descriptor* __code en_string_descriptors[4] = {
- &strManufacturer,
- &strProduct,
- &strSerialNumber,
- &strConfigDescr
+__code struct usb_string_descriptor *__code en_string_descriptors[4] = {
+ &strManufacturer,
+ &strProduct,
+ &strSerialNumber,
+ &strConfigDescr
};
void sudav_isr(void) __interrupt SUDAV_ISR
{
- CLEAR_IRQ();
+ CLEAR_IRQ();
- usb_handle_setup_data();
+ usb_handle_setup_data();
- USBIRQ = SUDAVIR;
- EP0CS |= HSNAK;
+ USBIRQ = SUDAVIR;
+ EP0CS |= HSNAK;
}
-void sof_isr(void) __interrupt SOF_ISR { }
-void sutok_isr(void) __interrupt SUTOK_ISR { }
-void suspend_isr(void) __interrupt SUSPEND_ISR { }
-void usbreset_isr(void) __interrupt USBRESET_ISR { }
-void ibn_isr(void) __interrupt IBN_ISR { }
+void sof_isr(void) __interrupt SOF_ISR
+{
+}
+void sutok_isr(void) __interrupt SUTOK_ISR
+{
+}
+void suspend_isr(void) __interrupt SUSPEND_ISR
+{
+}
+void usbreset_isr(void) __interrupt USBRESET_ISR
+{
+}
+void ibn_isr(void) __interrupt IBN_ISR
+{
+}
-void ep0in_isr(void) __interrupt EP0IN_ISR { }
-void ep0out_isr(void) __interrupt EP0OUT_ISR { }
-void ep1in_isr(void) __interrupt EP1IN_ISR { }
-void ep1out_isr(void) __interrupt EP1OUT_ISR { }
+void ep0in_isr(void) __interrupt EP0IN_ISR
+{
+}
+void ep0out_isr(void) __interrupt EP0OUT_ISR
+{
+}
+void ep1in_isr(void) __interrupt EP1IN_ISR
+{
+}
+void ep1out_isr(void) __interrupt EP1OUT_ISR
+{
+}
/**
* EP2 IN: called after the transfer from uC->Host has finished: we sent data
*/
-void ep2in_isr(void) __interrupt EP2IN_ISR {
- EP2_in = 1;
+void ep2in_isr(void) __interrupt EP2IN_ISR
+{
+ EP2_in = 1;
- CLEAR_IRQ();
- IN07IRQ = IN2IR; // Clear OUT2 IRQ
+ CLEAR_IRQ();
+ IN07IRQ = IN2IR;/* Clear OUT2 IRQ */
}
/**
* EP2 OUT: called after the transfer from Host->uC has finished: we got data
*/
-void ep2out_isr(void) __interrupt EP2OUT_ISR {
- EP2_out = 1;
+void ep2out_isr(void) __interrupt EP2OUT_ISR
+{
+ EP2_out = 1;
- CLEAR_IRQ();
- OUT07IRQ = OUT2IR; // Clear OUT2 IRQ
+ CLEAR_IRQ();
+ OUT07IRQ = OUT2IR; /* Clear OUT2 IRQ */
}
-void ep3in_isr(void) __interrupt EP3IN_ISR { }
-void ep3out_isr(void) __interrupt EP3OUT_ISR { }
-void ep4in_isr(void) __interrupt EP4IN_ISR { }
-void ep4out_isr(void) __interrupt EP4OUT_ISR { }
-void ep5in_isr(void) __interrupt EP5IN_ISR { }
-void ep5out_isr(void) __interrupt EP5OUT_ISR { }
-void ep6in_isr(void) __interrupt EP6IN_ISR { }
-void ep6out_isr(void) __interrupt EP6OUT_ISR { }
-void ep7in_isr(void) __interrupt EP7IN_ISR { }
-void ep7out_isr(void) __interrupt EP7OUT_ISR { }
+void ep3in_isr(void) __interrupt EP3IN_ISR
+{
+}
+void ep3out_isr(void) __interrupt EP3OUT_ISR
+{
+}
+void ep4in_isr(void) __interrupt EP4IN_ISR
+{
+}
+void ep4out_isr(void) __interrupt EP4OUT_ISR
+{
+}
+void ep5in_isr(void) __interrupt EP5IN_ISR
+{
+}
+void ep5out_isr(void) __interrupt EP5OUT_ISR
+{
+}
+void ep6in_isr(void) __interrupt EP6IN_ISR
+{
+}
+void ep6out_isr(void) __interrupt EP6OUT_ISR
+{
+}
+void ep7in_isr(void) __interrupt EP7IN_ISR
+{
+}
+void ep7out_isr(void) __interrupt EP7OUT_ISR
+{
+}
/**
* Return the control/status register for an endpoint
* specified in \a ep
* @return on failure: NULL
*/
-__xdata uint8_t* usb_get_endpoint_cs_reg(uint8_t ep)
+__xdata uint8_t *usb_get_endpoint_cs_reg(uint8_t ep)
{
- /* Mask direction bit */
- uint8_t ep_num = ep & 0x7F;
-
- switch (ep_num) {
- case 0:
- return &EP0CS;
- break;
- case 1:
- return ep & 0x80 ? &IN1CS : &OUT1CS;
- break;
- case 2:
- return ep & 0x80 ? &IN2CS : &OUT2CS;
- break;
- case 3:
- return ep & 0x80 ? &IN3CS : &OUT3CS;
- break;
- case 4:
- return ep & 0x80 ? &IN4CS : &OUT4CS;
- break;
- case 5:
- return ep & 0x80 ? &IN5CS : &OUT5CS;
- break;
- case 6:
- return ep & 0x80 ? &IN6CS : &OUT6CS;
- break;
- case 7:
- return ep & 0x80 ? &IN7CS : &OUT7CS;
- break;
- }
-
- return NULL;
+ /* Mask direction bit */
+ uint8_t ep_num = ep & 0x7F;
+
+ switch (ep_num) {
+ case 0:
+ return &EP0CS;
+ break;
+ case 1:
+ return ep & 0x80 ? &IN1CS : &OUT1CS;
+ break;
+ case 2:
+ return ep & 0x80 ? &IN2CS : &OUT2CS;
+ break;
+ case 3:
+ return ep & 0x80 ? &IN3CS : &OUT3CS;
+ break;
+ case 4:
+ return ep & 0x80 ? &IN4CS : &OUT4CS;
+ break;
+ case 5:
+ return ep & 0x80 ? &IN5CS : &OUT5CS;
+ break;
+ case 6:
+ return ep & 0x80 ? &IN6CS : &OUT6CS;
+ break;
+ case 7:
+ return ep & 0x80 ? &IN7CS : &OUT7CS;
+ break;
+ }
+
+ return NULL;
}
void usb_reset_data_toggle(uint8_t ep)
{
- /* TOGCTL register:
- +----+-----+-----+------+-----+-------+-------+-------+
- | Q | S | R | IO | 0 | EP2 | EP1 | EP0 |
- +----+-----+-----+------+-----+-------+-------+-------+
-
- To reset data toggle bits, we have to write the endpoint direction (IN/OUT)
- to the IO bit and the endpoint number to the EP2..EP0 bits. Then, in a
- separate write cycle, the R bit needs to be set.
- */
- uint8_t togctl_value = (ep & 0x80 >> 3) | (ep & 0x7);
-
- /* First step: Write EP number and direction bit */
- TOGCTL = togctl_value;
-
- /* Second step: Set R bit */
- togctl_value |= TOG_R;
- TOGCTL = togctl_value;
+ /* TOGCTL register:
+ +----+-----+-----+------+-----+-------+-------+-------+
+ | Q | S | R | IO | 0 | EP2 | EP1 | EP0 |
+ +----+-----+-----+------+-----+-------+-------+-------+
+
+ To reset data toggle bits, we have to write the endpoint direction (IN/OUT)
+ to the IO bit and the endpoint number to the EP2..EP0 bits. Then, in a
+ separate write cycle, the R bit needs to be set.
+ */
+ uint8_t togctl_value = (ep & 0x80 >> 3) | (ep & 0x7);
+
+ /* First step: Write EP number and direction bit */
+ TOGCTL = togctl_value;
+
+ /* Second step: Set R bit */
+ togctl_value |= TOG_R;
+ TOGCTL = togctl_value;
}
/**
*/
bool usb_handle_get_status(void)
{
- uint8_t *ep_cs;
-
- switch (setup_data.bmRequestType) {
- case GS_DEVICE:
- /* Two byte response: Byte 0, Bit 0 = self-powered, Bit 1 = remote wakeup.
- * Byte 1: reserved, reset to zero */
- IN0BUF[0] = 0;
- IN0BUF[1] = 0;
-
- /* Send response */
- IN0BC = 2;
- break;
- case GS_INTERFACE:
- /* Always return two zero bytes according to USB 1.1 spec, p. 191 */
- IN0BUF[0] = 0;
- IN0BUF[1] = 0;
-
- /* Send response */
- IN0BC = 2;
- break;
- case GS_ENDPOINT:
- /* Get stall bit for endpoint specified in low byte of wIndex */
- ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex & 0xff);
-
- if (*ep_cs & EPSTALL) {
- IN0BUF[0] = 0x01;
- }
- else {
- IN0BUF[0] = 0x00;
- }
-
- /* Second byte sent has to be always zero */
- IN0BUF[1] = 0;
-
- /* Send response */
- IN0BC = 2;
- break;
- default:
- return false;
- break;
- }
-
- return true;
+ uint8_t *ep_cs;
+
+ switch (setup_data.bmRequestType) {
+ case GS_DEVICE:
+ /* Two byte response: Byte 0, Bit 0 = self-powered, Bit 1 = remote wakeup.
+ * Byte 1: reserved, reset to zero */
+ IN0BUF[0] = 0;
+ IN0BUF[1] = 0;
+
+ /* Send response */
+ IN0BC = 2;
+ break;
+ case GS_INTERFACE:
+ /* Always return two zero bytes according to USB 1.1 spec, p. 191 */
+ IN0BUF[0] = 0;
+ IN0BUF[1] = 0;
+
+ /* Send response */
+ IN0BC = 2;
+ break;
+ case GS_ENDPOINT:
+ /* Get stall bit for endpoint specified in low byte of wIndex */
+ ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex & 0xff);
+
+ if (*ep_cs & EPSTALL)
+ IN0BUF[0] = 0x01;
+ else
+ IN0BUF[0] = 0x00;
+
+ /* Second byte sent has to be always zero */
+ IN0BUF[1] = 0;
+
+ /* Send response */
+ IN0BC = 2;
+ break;
+ default:
+ return false;
+ break;
+ }
+
+ return true;
}
/**
*/
bool usb_handle_clear_feature(void)
{
- __xdata uint8_t *ep_cs;
-
- switch (setup_data.bmRequestType) {
- case CF_DEVICE:
- /* Clear remote wakeup not supported: stall EP0 */
- STALL_EP0();
- break;
- case CF_ENDPOINT:
- if (setup_data.wValue == 0) {
- /* Unstall the endpoint specified in wIndex */
- ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex);
- if (!ep_cs) {
- return false;
- }
- *ep_cs &= ~EPSTALL;
- }
- else {
- /* Unsupported feature, stall EP0 */
- STALL_EP0();
- }
- break;
- default:
- /* Vendor commands... */
- }
-
- return true;
+ __xdata uint8_t *ep_cs;
+
+ switch (setup_data.bmRequestType) {
+ case CF_DEVICE:
+ /* Clear remote wakeup not supported: stall EP0 */
+ STALL_EP0();
+ break;
+ case CF_ENDPOINT:
+ if (setup_data.wValue == 0) {
+ /* Unstall the endpoint specified in wIndex */
+ ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex);
+ if (!ep_cs)
+ return false;
+ *ep_cs &= ~EPSTALL;
+ } else {
+ /* Unsupported feature, stall EP0 */
+ STALL_EP0();
+ }
+ break;
+ default:
+ /* Vendor commands... */
+ }
+
+ return true;
}
/**
*/
bool usb_handle_set_feature(void)
{
- __xdata uint8_t *ep_cs;
-
- switch (setup_data.bmRequestType) {
- case SF_DEVICE:
- if (setup_data.wValue == 2) {
- return true;
- }
- break;
- case SF_ENDPOINT:
- if (setup_data.wValue == 0) {
- /* Stall the endpoint specified in wIndex */
- ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex);
- if (!ep_cs) {
- return false;
- }
- *ep_cs |= EPSTALL;
- }
- else {
- /* Unsupported endpoint feature */
- return false;
- }
- break;
- default:
- /* Vendor commands... */
- break;
- }
-
- return true;
+ __xdata uint8_t *ep_cs;
+
+ switch (setup_data.bmRequestType) {
+ case SF_DEVICE:
+ if (setup_data.wValue == 2)
+ return true;
+ break;
+ case SF_ENDPOINT:
+ if (setup_data.wValue == 0) {
+ /* Stall the endpoint specified in wIndex */
+ ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex);
+ if (!ep_cs)
+ return false;
+ *ep_cs |= EPSTALL;
+ } else {
+ /* Unsupported endpoint feature */
+ return false;
+ }
+ break;
+ default:
+ /* Vendor commands... */
+ break;
+ }
+
+ return true;
}
/**
*/
bool usb_handle_get_descriptor(void)
{
- __xdata uint8_t descriptor_type;
- __xdata uint8_t descriptor_index;
-
- descriptor_type = (setup_data.wValue & 0xff00) >> 8;
- descriptor_index = setup_data.wValue & 0x00ff;
-
- switch (descriptor_type) {
- case DESCRIPTOR_TYPE_DEVICE:
- SUDPTRH = HI8(&device_descriptor);
- SUDPTRL = LO8(&device_descriptor);
- break;
- case DESCRIPTOR_TYPE_CONFIGURATION:
- SUDPTRH = HI8(&config_descriptor);
- SUDPTRL = LO8(&config_descriptor);
- break;
- case DESCRIPTOR_TYPE_STRING:
- if (setup_data.wIndex == 0) {
- /* Supply language descriptor */
- SUDPTRH = HI8(&language_descriptor);
- SUDPTRL = LO8(&language_descriptor);
- }
- else if (setup_data.wIndex == 0x0409 /* US English */) {
- /* Supply string descriptor */
- SUDPTRH = HI8(en_string_descriptors[descriptor_index - 1]);
- SUDPTRL = LO8(en_string_descriptors[descriptor_index - 1]);
- }
- else {
- return false;
- }
- break;
- default:
- /* Unsupported descriptor type */
- return false;
- break;
- }
-
- return true;
+ __xdata uint8_t descriptor_type;
+ __xdata uint8_t descriptor_index;
+
+ descriptor_type = (setup_data.wValue & 0xff00) >> 8;
+ descriptor_index = setup_data.wValue & 0x00ff;
+
+ switch (descriptor_type) {
+ case DESCRIPTOR_TYPE_DEVICE:
+ SUDPTRH = HI8(&device_descriptor);
+ SUDPTRL = LO8(&device_descriptor);
+ break;
+ case DESCRIPTOR_TYPE_CONFIGURATION:
+ SUDPTRH = HI8(&config_descriptor);
+ SUDPTRL = LO8(&config_descriptor);
+ break;
+ case DESCRIPTOR_TYPE_STRING:
+ if (setup_data.wIndex == 0) {
+ /* Supply language descriptor */
+ SUDPTRH = HI8(&language_descriptor);
+ SUDPTRL = LO8(&language_descriptor);
+ } else if (setup_data.wIndex == 0x0409 /* US English */) {
+ /* Supply string descriptor */
+ SUDPTRH = HI8(en_string_descriptors[descriptor_index - 1]);
+ SUDPTRL = LO8(en_string_descriptors[descriptor_index - 1]);
+ } else
+ return false;
+ break;
+ default:
+ /* Unsupported descriptor type */
+ return false;
+ break;
+ }
+
+ return true;
}
/**
*/
void usb_handle_set_interface(void)
{
- /* Reset Data Toggle */
- usb_reset_data_toggle(USB_DIR_IN | 2);
- usb_reset_data_toggle(USB_DIR_OUT | 2);
-
- /* Unstall & clear busy flag of all valid IN endpoints */
- IN2CS = 0 | EPBSY;
-
- /* Unstall all valid OUT endpoints, reset bytecounts */
- OUT2CS = 0;
- OUT2BC = 0;
+ /* Reset Data Toggle */
+ usb_reset_data_toggle(USB_DIR_IN | 2);
+ usb_reset_data_toggle(USB_DIR_OUT | 2);
+
+ /* Unstall & clear busy flag of all valid IN endpoints */
+ IN2CS = 0 | EPBSY;
+
+ /* Unstall all valid OUT endpoints, reset bytecounts */
+ OUT2CS = 0;
+ OUT2BC = 0;
}
/**
*/
void usb_handle_setup_data(void)
{
- switch (setup_data.bRequest) {
- case GET_STATUS:
- if (!usb_handle_get_status()) {
- STALL_EP0();
- }
- break;
- case CLEAR_FEATURE:
- if (!usb_handle_clear_feature()) {
- STALL_EP0();
- }
- break;
- case 2: case 4:
- /* Reserved values */
- STALL_EP0();
- break;
- case SET_FEATURE:
- if (!usb_handle_set_feature()) {
- STALL_EP0();
- }
- break;
- case SET_ADDRESS:
- /* Handled by USB core */
- break;
- case SET_DESCRIPTOR:
- /* Set Descriptor not supported. */
- STALL_EP0();
- break;
- case GET_DESCRIPTOR:
- if (!usb_handle_get_descriptor()) {
- STALL_EP0();
- }
- break;
- case GET_CONFIGURATION:
- /* OpenULINK has only one configuration, return its index */
- IN0BUF[0] = config_descriptor.bConfigurationValue;
- IN0BC = 1;
- break;
- case SET_CONFIGURATION:
- /* OpenULINK has only one configuration -> nothing to do */
- break;
- case GET_INTERFACE:
- /* OpenULINK only has one interface, return its number */
- IN0BUF[0] = interface_descriptor00.bInterfaceNumber;
- IN0BC = 1;
- break;
- case SET_INTERFACE:
- usb_handle_set_interface();
- break;
- case SYNCH_FRAME:
- /* Isochronous endpoints not used -> nothing to do */
- break;
- default:
- /* Any other requests: do nothing */
- break;
- }
+ switch (setup_data.bRequest) {
+ case GET_STATUS:
+ if (!usb_handle_get_status())
+ STALL_EP0();
+ break;
+ case CLEAR_FEATURE:
+ if (!usb_handle_clear_feature())
+ STALL_EP0();
+ break;
+ case 2: case 4:
+ /* Reserved values */
+ STALL_EP0();
+ break;
+ case SET_FEATURE:
+ if (!usb_handle_set_feature())
+ STALL_EP0();
+ break;
+ case SET_ADDRESS:
+ /* Handled by USB core */
+ break;
+ case SET_DESCRIPTOR:
+ /* Set Descriptor not supported. */
+ STALL_EP0();
+ break;
+ case GET_DESCRIPTOR:
+ if (!usb_handle_get_descriptor())
+ STALL_EP0();
+ break;
+ case GET_CONFIGURATION:
+ /* OpenULINK has only one configuration, return its index */
+ IN0BUF[0] = config_descriptor.bConfigurationValue;
+ IN0BC = 1;
+ break;
+ case SET_CONFIGURATION:
+ /* OpenULINK has only one configuration -> nothing to do */
+ break;
+ case GET_INTERFACE:
+ /* OpenULINK only has one interface, return its number */
+ IN0BUF[0] = interface_descriptor00.bInterfaceNumber;
+ IN0BC = 1;
+ break;
+ case SET_INTERFACE:
+ usb_handle_set_interface();
+ break;
+ case SYNCH_FRAME:
+ /* Isochronous endpoints not used -> nothing to do */
+ break;
+ default:
+ /* Any other requests: do nothing */
+ break;
+ }
}
/**
* USB initialization. Configures USB interrupts, endpoints and performs
* ReNumeration.
*/
-void usb_init(void) {
- /* Mark endpoint 2 IN & OUT as valid */
- IN07VAL = IN2VAL;
- OUT07VAL = OUT2VAL;
-
- /* Make sure no isochronous endpoints are marked valid */
- INISOVAL = 0;
- OUTISOVAL = 0;
-
- /* Disable isochronous endpoints. This makes the isochronous data buffers
- * available as 8051 XDATA memory at address 0x2000 - 0x27FF */
- ISOCTL = ISODISAB;
-
- /* Enable USB Autovectoring */
- USBBAV |= AVEN;
-
- /* Enable SUDAV interrupt */
- USBIEN |= SUDAVIE;
-
- /* Enable EP2 OUT & IN interrupts */
- OUT07IEN = OUT2IEN;
- IN07IEN = IN2IEN;
-
- /* Enable USB interrupt (EIE register) */
- EUSB = 1;
-
- /* Perform ReNumeration */
- USBCS = DISCON | RENUM;
- delay_ms(200);
- USBCS = DISCOE | RENUM;
+void usb_init(void)
+{
+ /* Mark endpoint 2 IN & OUT as valid */
+ IN07VAL = IN2VAL;
+ OUT07VAL = OUT2VAL;
+
+ /* Make sure no isochronous endpoints are marked valid */
+ INISOVAL = 0;
+ OUTISOVAL = 0;
+
+ /* Disable isochronous endpoints. This makes the isochronous data buffers
+ * available as 8051 XDATA memory at address 0x2000 - 0x27FF */
+ ISOCTL = ISODISAB;
+
+ /* Enable USB Autovectoring */
+ USBBAV |= AVEN;
+
+ /* Enable SUDAV interrupt */
+ USBIEN |= SUDAVIE;
+
+ /* Enable EP2 OUT & IN interrupts */
+ OUT07IEN = OUT2IEN;
+ IN07IEN = IN2IEN;
+
+ /* Enable USB interrupt (EIE register) */
+ EUSB = 1;
+
+ /* Perform ReNumeration */
+ USBCS = DISCON | RENUM;
+ delay_ms(200);
+ USBCS = DISCOE | RENUM;
}