GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_host_stack_device_address_set.c Lines: 32 32 100.0 %
Date: 2024-12-12 17:16:36 Branches: 12 12 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** USBX Component                                                        */
16
/**                                                                       */
17
/**   Host Stack                                                          */
18
/**                                                                       */
19
/**************************************************************************/
20
/**************************************************************************/
21
22
23
/* Include necessary system files.  */
24
25
#define UX_SOURCE_CODE
26
27
#include "ux_api.h"
28
#include "ux_host_stack.h"
29
30
31
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _ux_host_stack_device_address_set                   PORTABLE C      */
36
/*                                                           6.1.10       */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Chaoqiong Xiao, Microsoft Corporation                               */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    This function sets the device address to the new device.            */
44
/*                                                                        */
45
/*  INPUT                                                                 */
46
/*                                                                        */
47
/*    device                                Pointer to device             */
48
/*                                                                        */
49
/*  OUTPUT                                                                */
50
/*                                                                        */
51
/*    Completion Status                                                   */
52
/*                                                                        */
53
/*  CALLS                                                                 */
54
/*                                                                        */
55
/*    _ux_utility_delay_ms                  Thread sleep                  */
56
/*    _ux_host_stack_transfer_request       Process transfer request      */
57
/*                                                                        */
58
/*  CALLED BY                                                             */
59
/*                                                                        */
60
/*    USBX Components                                                     */
61
/*                                                                        */
62
/*  RELEASE HISTORY                                                       */
63
/*                                                                        */
64
/*    DATE              NAME                      DESCRIPTION             */
65
/*                                                                        */
66
/*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
67
/*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
68
/*                                            optimized based on compile  */
69
/*                                            definitions,                */
70
/*                                            resulting in version 6.1    */
71
/*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
72
/*                                            added standalone support,   */
73
/*                                            resulting in version 6.1.10 */
74
/*                                                                        */
75
/**************************************************************************/
76
1504
UINT  _ux_host_stack_device_address_set(UX_DEVICE *device)
77
{
78
79
80
1504
UINT            status = UX_ERROR;
81
UX_TRANSFER     *transfer_request;
82
UX_ENDPOINT     *control_endpoint;
83
USHORT          device_address;
84
#if UX_MAX_DEVICES > 1
85
UX_HCD          *hcd;
86
UINT            address_byte_index;
87
UINT            address_bit_index;
88
UCHAR           device_address_byte;
89
#endif
90
91
    /* Retrieve the pointer to the control endpoint.  */
92
1504
    control_endpoint =  &device -> ux_device_control_endpoint;
93
94
    /* Retrieve the transfer request pointer.  */
95
1504
    transfer_request =  &control_endpoint -> ux_endpoint_transfer_request;
96
97
    /* Initialize device address to 1.  */
98
1504
    device_address =  1;
99
100
#if UX_MAX_DEVICES > 1
101
102
    /* We need the HCD pointer as well.  */
103
1504
    hcd = UX_DEVICE_HCD_GET(device);
104
105
    /* Calculate the new address of this device. We start with address 1.  */
106
1521
    for (address_byte_index = 0; address_byte_index < 16; address_byte_index++)
107
    {
108
109
        /* Get the address mask byte.  */
110
1520
        device_address_byte =  hcd -> ux_hcd_address[address_byte_index];
111
112
        /* Scan each bit for an empty spot.  */
113
1670
        for (address_bit_index = 0; address_bit_index < 8; address_bit_index++)
114
        {
115
116
1653
            if ((device_address_byte & (1 << address_bit_index)) == 0)
117
            {
118
119
                /* We have found an empty spot. Reserve this address.  */
120
1503
                device_address_byte = (UCHAR)((UCHAR)device_address_byte | (UCHAR)(1 << address_bit_index));
121
122
                /* Store the address mask byte.  */
123
1503
                hcd -> ux_hcd_address[address_byte_index] =  device_address_byte;
124
125
                /* OK, apply address.  */
126
1503
                status = UX_SUCCESS;
127
1503
                break;
128
            }
129
130
            /* This address was already taken, increment to the next address.  */
131
150
            device_address++;
132
        }
133
134
        /* If address found, break the loop.  */
135
1520
        if (status == UX_SUCCESS)
136
        {
137
1503
            break;
138
        }
139
    }
140
1504
    if (status == UX_ERROR)
141
142
        /* We should never get here!  */
143
1
        return(UX_ERROR);
144
#endif
145
146
    /* If trace is enabled, insert this event into the trace buffer.  */
147
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_DEVICE_ADDRESS_SET, device, device_address, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
148
149
    /* Create a transfer request for the SET_ADDRESS request.  */
150
1503
    transfer_request -> ux_transfer_request_data_pointer =      UX_NULL;
151
1503
    transfer_request -> ux_transfer_request_requested_length =  0;
152
1503
    transfer_request -> ux_transfer_request_function =          UX_SET_ADDRESS;
153
1503
    transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
154
1503
    transfer_request -> ux_transfer_request_value =             device_address;
155
1503
    transfer_request -> ux_transfer_request_index =             0;
156
157
#if defined(UX_HOST_STANDALONE)
158
    device -> ux_device_enum_trans = transfer_request;
159
    status = UX_SUCCESS;
160
    return(status);
161
#else
162
163
    /* Send request to HCD layer.  */
164
1503
    status =  _ux_host_stack_transfer_request(transfer_request);
165
166
    /* Now, this address will be the one used in future transfers.  The transfer may have failed and therefore
167
        all the device resources including the new address will be free.*/
168
1503
    device -> ux_device_address =  (ULONG) device_address;
169
170
    /* Check completion status.  */
171
1503
    if (status == UX_SUCCESS)
172
    {
173
174
        /* Mark the device as ADDRESSED now.  */
175
1086
        device -> ux_device_state = UX_DEVICE_ADDRESSED;
176
177
        /* Some devices need some time to accept this address.  */
178
1086
        _ux_utility_delay_ms(UX_DEVICE_ADDRESS_SET_WAIT);
179
180
        /* Return successful status.  */
181
1086
        return(status);
182
    }
183
    else
184
    {
185
186
        /* We have an error at the first device transaction. This is mostly
187
            due to the device having failed on the reset after power up.
188
            we will try again either at the root hub or regular hub. */
189
417
        return(status);
190
    }
191
#endif
192
}