1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** USBX Component */
16 /** */
17 /** Device dfu Class */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define UX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "ux_api.h"
28 #include "ux_device_class_dfu.h"
29 #include "ux_device_stack.h"
30
31
32 #if !defined(UX_DEVICE_STANDALONE)
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _ux_device_class_dfu_thread PORTABLE C */
38 /* 6.1.10 */
39 /* AUTHOR */
40 /* */
41 /* Chaoqiong Xiao, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function is the thread of the dfu class. It waits for the */
46 /* dfu command to signal a DFU_DETACH stage and either force a */
47 /* disconnect from the device or wait for the host to detach. */
48 /* */
49 /* It's for RTOS mode. */
50 /* */
51 /* INPUT */
52 /* */
53 /* dfu_class Address of dfu class */
54 /* container */
55 /* */
56 /* OUTPUT */
57 /* */
58 /* None */
59 /* */
60 /* CALLS */
61 /* */
62 /* _ux_utility_event_flags_get Get event flags */
63 /* _ux_utility_delay_ms Delay in milliseconds */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* ThreadX */
68 /* */
69 /* RELEASE HISTORY */
70 /* */
71 /* DATE NAME DESCRIPTION */
72 /* */
73 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
74 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
75 /* used UX prefix to refer to */
76 /* TX symbols instead of using */
77 /* them directly, */
78 /* resulting in version 6.1 */
79 /* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
80 /* resulting in version 6.1.10 */
81 /* */
82 /**************************************************************************/
_ux_device_class_dfu_thread(ULONG dfu_class)83 VOID _ux_device_class_dfu_thread(ULONG dfu_class)
84 {
85
86 UX_SLAVE_CLASS *class_ptr;
87 UX_SLAVE_CLASS_DFU *dfu;
88 UX_SLAVE_DCD *dcd;
89 UINT status;
90 ULONG actual_flags;
91
92 /* Cast properly the dfu instance. */
93 UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, dfu_class)
94
95 /* Get the dfu instance from this class container. */
96 dfu = (UX_SLAVE_CLASS_DFU *) class_ptr -> ux_slave_class_instance;
97
98 /* This thread runs forever. */
99 while(1)
100 {
101
102
103 /* Wait until we have a event sent by the application. */
104 status = _ux_utility_event_flags_get(&dfu -> ux_slave_class_dfu_event_flags_group, (UX_DEVICE_CLASS_DFU_THREAD_EVENT_DISCONNECT |
105 UX_DEVICE_CLASS_DFU_THREAD_EVENT_WAIT_RESET),
106 UX_OR_CLEAR, &actual_flags, UX_WAIT_FOREVER);
107
108 /* Check the completion code and the actual flags returned. */
109 if (status == UX_SUCCESS)
110 {
111
112 /* Check the source of event. */
113 if (actual_flags & UX_DEVICE_CLASS_DFU_THREAD_EVENT_DISCONNECT)
114 {
115
116 /* We need to disconnect. The control command for DETACH is still being processed, wait 2-3 ms. */
117 _ux_utility_delay_ms(2);
118
119 /* Get the pointer to the DCD. */
120 dcd = &_ux_system_slave -> ux_system_slave_dcd;
121
122 /* Issue a Soft Disconnect. */
123 dcd -> ux_slave_dcd_function(dcd, UX_DCD_CHANGE_STATE, (VOID *) UX_DEVICE_FORCE_DISCONNECT);
124
125 }
126
127 /* Check the source of event. */
128 if (actual_flags & UX_DEVICE_CLASS_DFU_THREAD_EVENT_WAIT_RESET)
129 {
130
131 /* We need to wait for reset. Arm a timer. The timeout value is indicated in ms from
132 the device framework. */
133 _ux_utility_delay_ms(_ux_system_slave -> ux_system_slave_device_dfu_detach_timeout);
134
135 /* Check the mode. */
136 if (_ux_system_slave -> ux_system_slave_device_dfu_mode == UX_DEVICE_CLASS_DFU_MODE_RUNTIME)
137
138 /* We are still in RunTime mode. The host never reset. Revert to AppIdle state. */
139 _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_APP_IDLE;
140
141 }
142 }
143 }
144 }
145 #endif
146