1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
void udc_tick_task(void)
{
    uint32_t dev_info = DEV_INFO;
    static struct usb_ctrlrequest req;
    static bool set_address = false;
    static bool set_configuration = false;

    /* This tick task polls for DEV_EN bit set in DEV_INFO  register
     * as well as tracks current requested configuration
     * (DEV_INFO [11:8]). On state change it notifies usb stack
     * about it.
     *
     * It is registered on usb connection and removed on usb
     * extraction.
     */

    /* SET ADDRESS request */
    if (set_address == false)
        if ((dev_info & 0x7f))
        {
            udc_conn = (dev_info & 0x7f);
            set_address = true;

            req.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
            req.bRequest = USB_REQ_SET_ADDRESS;
            req.wValue = (dev_info & 0x7f);
            req.wIndex = 0;
            req.wLength = 0;

            logf("udc_tick_task() ctrl req=%x",req.bRequest);
            usb_core_control_request(&req);
        }
    /* SET CONFIGURATION request */
    if (set_configuration == false)
    if (dev_info & DEV_EN)
    {
        set_configuration = true;

        req.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
        req.bRequest = USB_REQ_SET_CONFIGURATION;
        req.wValue = ((dev_info >> 8) & 0x0f) + 1;
        req.wIndex = 0;
        req.wLength = 0;

        /* Notify usb stack somehow */
        usb_core_control_request(&req);

        tick_remove_task(udc_tick_task);

        set_address = false;
    }
}