insane-adding-machines / unicore-mx

UniCore-MX | Universal Core for ARM Cortex-M0/0+/3/4/7/X
GNU General Public License v3.0
50 stars 8 forks source link

usb device does not get recognized - simple vendor class implementation #60

Closed amitesh-singh closed 6 years ago

amitesh-singh commented 7 years ago

Hello Guys,

I wrote a simple vendor class implementation on stm32f103c8t6 based on unicore-mx but device does not get recognized.

the dmesg errors are

[ +26.255842] usb 3-2.1: new full-speed USB device number 6 using xhci_hcd [ +5.083258] usb 3-2.1: device descriptor read/64, error -110 [ +0.180083] usb 3-2.1: device descriptor read/64, error -32 [ +0.179908] usb 3-2.1: new full-speed USB device number 7 using xhci_hcd [ +0.073324] usb 3-2.1: device descriptor read/64, error -32 [ +0.180020] usb 3-2.1: device descriptor read/64, error -32 [ +0.179944] usb 3-2.1: new full-speed USB device number 8 using xhci_hcd [ +0.000077] usb 3-2.1: Device not responding to setup address. [ +0.206666] usb 3-2.1: Device not responding to setup address. [ +0.206572] usb 3-2.1: device not accepting address 8, error -71 [ +0.073360] usb 3-2.1: new full-speed USB device number 9 using xhci_hcd [ +0.000123] usb 3-2.1: Device not responding to setup address. [ +0.206723] usb 3-2.1: Device not responding to setup address. [ +0.206488] usb 3-2.1: device not accepting address 9, error -71 [ +0.000086] usb 3-2-port1: unable to enumerate USB device

The code is below

#include <unicore-mx/cm3/common.h>
#include <unicore-mx/stm32/rcc.h>
#include <unicore-mx/stm32/gpio.h>
#include <unicore-mx/usbd/usbd.h>

const struct usb_interface_descriptor iface[] = {{
     .bLength = USB_DT_INTERFACE_SIZE,
        .bDescriptorType = USB_DT_INTERFACE,
        .bInterfaceNumber = 0,
        .bAlternateSetting = 0,
        .bNumEndpoints = 0,
        .bInterfaceClass = 0x0,
        .bInterfaceSubClass = 0,
        .bInterfaceProtocol = 0,
        .iInterface = 0,
}};

static const struct usb_interface ifaces[] = {
       {
          .cur_altsetting = NULL,

          .num_altsetting = 1,
          .iface_assoc = NULL,

          .altsetting = iface,
       },
};

const uint8_t *usb_strings_ascii[] = {
     (uint8_t *) "ami",
     (uint8_t *) "usbLed",
     (uint8_t *) "XYZ",
};

const struct usb_string_utf8_data usb_strings[] = {{
     .data = usb_strings_ascii,
        .count = 3,
        .lang_id = USB_LANGID_ENGLISH_UNITED_STATES
}, {
     .data = NULL
}};

const struct usb_config_descriptor config[] = {{
     .bLength = USB_DT_CONFIGURATION_SIZE,
        .bDescriptorType = USB_DT_CONFIGURATION,
        .wTotalLength = 0,
        .bNumInterfaces = 1,
        .bConfigurationValue = 1,
        .iConfiguration = 0,
        .bmAttributes = 0x80,
        .bMaxPower = 0x32,

        .interface = ifaces,
        .string = usb_strings
}};

const struct usb_device_descriptor dev = {
     .bLength = USB_DT_DEVICE_SIZE,
     .bDescriptorType = USB_DT_DEVICE,
     .bcdUSB = 0x0200,
     .bDeviceClass = 0xFF,
     .bDeviceSubClass = 0,
     .bDeviceProtocol = 0,
     .bMaxPacketSize0 = 64,
     .idVendor = 0x16C0,
     .idProduct = 0x05DC,
     .bcdDevice = 0x0200,
     .iManufacturer = 1,
     .iProduct = 2,
     .iSerialNumber = 3,
     .bNumConfigurations = 1,

     .config = config,
     .string = usb_strings
};

static void my_delay_1( void )
{
   int i = 72e6/2/4;

   while( i > 0 )
     {
        i--;
        __asm__( "nop" );
     }
}

/* Buffer to be used for control requests. */
uint8_t usbd_control_buffer[128];
void usb_simple_led_set_value(bool value);

static void simple_setup_callback(usbd_device *usbd_dev, uint8_t ep_addr,
                                  const struct usb_setup_data *setup_data)
{
   (void) ep_addr; /* assuming ep_addr == 0 */

   if (setup_data->bmRequestType != 0xC0)
     {
        usbd_ep0_setup(usbd_dev, setup_data); /* Only accept vendor request. */
        return;
     }

   usb_simple_led_set_value(!!(setup_data->wValue & 1));
   usbd_ep0_transfer(usbd_dev, setup_data, NULL, 0, NULL);
}

void usb_simple_target_init(void)
{
   rcc_clock_setup_in_hse_8mhz_out_72mhz();
   rcc_periph_clock_enable(RCC_GPIOA);
   rcc_periph_clock_enable(RCC_GPIOC);

   gpio_set_mode( GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
                  GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
   gpio_clear(GPIOC, GPIO13);

   // hack to reenumerate, physically drag D+ low.
   // don't require this if your board has proper usb pull up control!

   // you absloutely need this code in case of chinese f103c8t6 board.
   gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
                 GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
   gpio_clear(GPIOA, GPIO12);
   my_delay_1();
   //my_delay_1();
   //usb setup
}

void usb_simple_led_set_value(bool value)
{
   if (value)
     {
        gpio_set(GPIOC, GPIO13);
     }
   else
     {
        gpio_clear(GPIOC, GPIO13);
     }
}

const usbd_backend *usb_simple_target_usb_driver(void)
{
   return USBD_STM32_FSDEV_V1;
}

int main(void)
{
   usbd_device *usbd_dev;

   usb_simple_target_init();

   rcc_periph_clock_enable(RCC_USB);

   usbd_dev = usbd_init(usb_simple_target_usb_driver(), NULL, &dev,
                        usbd_control_buffer, sizeof(usbd_control_buffer));

   usbd_register_setup_callback(usbd_dev, simple_setup_callback);
   //usbd_register_set_config_callback(usbd_dev, set_config);

   while (1)
     {
        usbd_poll(usbd_dev, 0);
     }

   return 0;
}
kuldeepdhaka commented 7 years ago

https://github.com/insane-adding-machines/unicore-mx/commit/e276eb95429dcfe34c2f9cb1efab87cc982bc9b7 should solve the problem. check and let me know.

amitesh-singh commented 6 years ago

yes. it works now. thanks for fixing it.