@@ -21,198 +21,198 @@ buffer_t USBResponseBuffer;
2121void dap_edpt_init (void ) {
2222
2323}
24-
24+
2525void dap_edpt_reset (uint8_t __unused rhport )
2626{
27- itf_num = 0 ;
27+ itf_num = 0 ;
2828}
2929
3030uint16_t dap_edpt_open (uint8_t __unused rhport , tusb_desc_interface_t const * itf_desc , uint16_t max_len )
3131{
32-
33- TU_VERIFY (TUSB_CLASS_VENDOR_SPECIFIC == itf_desc -> bInterfaceClass &&
34- PICOPROBE_INTERFACE_SUBCLASS == itf_desc -> bInterfaceSubClass &&
35- PICOPROBE_INTERFACE_PROTOCOL == itf_desc -> bInterfaceProtocol , 0 );
3632
37- // Initialise circular buffer indices
38- USBResponseBuffer .packet_wr_idx = 0 ;
39- USBResponseBuffer .packet_rd_idx = 0 ;
40- USBRequestBuffer .packet_wr_idx = 0 ;
41- USBRequestBuffer .packet_rd_idx = 0 ;
33+ TU_VERIFY (TUSB_CLASS_VENDOR_SPECIFIC == itf_desc -> bInterfaceClass &&
34+ PICOPROBE_INTERFACE_SUBCLASS == itf_desc -> bInterfaceSubClass &&
35+ PICOPROBE_INTERFACE_PROTOCOL == itf_desc -> bInterfaceProtocol , 0 );
36+
37+ // Initialise circular buffer indices
38+ USBResponseBuffer .packet_wr_idx = 0 ;
39+ USBResponseBuffer .packet_rd_idx = 0 ;
40+ USBRequestBuffer .packet_wr_idx = 0 ;
41+ USBRequestBuffer .packet_rd_idx = 0 ;
4242
43- // Initialse full/empty flags
44- USBResponseBuffer .wasFull = false;
45- USBResponseBuffer .wasEmpty = true;
46- USBRequestBuffer .wasFull = false;
47- USBRequestBuffer .wasEmpty = true;
43+ // Initialse full/empty flags
44+ USBResponseBuffer .wasFull = false;
45+ USBResponseBuffer .wasEmpty = true;
46+ USBRequestBuffer .wasFull = false;
47+ USBRequestBuffer .wasEmpty = true;
4848
49- uint16_t const drv_len = sizeof (tusb_desc_interface_t ) + (itf_desc -> bNumEndpoints * sizeof (tusb_desc_endpoint_t ));
50- TU_VERIFY (max_len >= drv_len , 0 );
51- itf_num = itf_desc -> bInterfaceNumber ;
49+ uint16_t const drv_len = sizeof (tusb_desc_interface_t ) + (itf_desc -> bNumEndpoints * sizeof (tusb_desc_endpoint_t ));
50+ TU_VERIFY (max_len >= drv_len , 0 );
51+ itf_num = itf_desc -> bInterfaceNumber ;
5252
53- // Initialising the OUT endpoint
53+ // Initialising the OUT endpoint
5454
55- tusb_desc_endpoint_t * edpt_desc = (tusb_desc_endpoint_t * ) (itf_desc + 1 );
56- uint8_t ep_addr = edpt_desc -> bEndpointAddress ;
55+ tusb_desc_endpoint_t * edpt_desc = (tusb_desc_endpoint_t * ) (itf_desc + 1 );
56+ uint8_t ep_addr = edpt_desc -> bEndpointAddress ;
5757
58- _out_ep_addr = ep_addr ;
58+ _out_ep_addr = ep_addr ;
5959
60- // The OUT endpoint requires a call to usbd_edpt_xfer to initialise the endpoint, giving tinyUSB a buffer to consume when a transfer occurs at the endpoint
61- usbd_edpt_open (rhport , edpt_desc );
62- usbd_edpt_xfer (rhport , ep_addr , & (USBRequestBuffer .data [USBRequestBuffer .packet_wr_idx ][0 ]), DAP_PACKET_SIZE );
60+ // The OUT endpoint requires a call to usbd_edpt_xfer to initialise the endpoint, giving tinyUSB a buffer to consume when a transfer occurs at the endpoint
61+ usbd_edpt_open (rhport , edpt_desc );
62+ usbd_edpt_xfer (rhport , ep_addr , & (USBRequestBuffer .data [USBRequestBuffer .packet_wr_idx ][0 ]), DAP_PACKET_SIZE );
6363
64- // Initiliasing the IN endpoint
64+ // Initiliasing the IN endpoint
6565
66- edpt_desc ++ ;
67- ep_addr = edpt_desc -> bEndpointAddress ;
66+ edpt_desc ++ ;
67+ ep_addr = edpt_desc -> bEndpointAddress ;
6868
69- _in_ep_addr = ep_addr ;
69+ _in_ep_addr = ep_addr ;
7070
71- // The IN endpoint doesn't need a transfer to initialise it, as this will be done by the main loop of dap_thread
72- usbd_edpt_open (rhport , edpt_desc );
71+ // The IN endpoint doesn't need a transfer to initialise it, as this will be done by the main loop of dap_thread
72+ usbd_edpt_open (rhport , edpt_desc );
7373
74- return drv_len ;
74+ return drv_len ;
7575
7676}
7777
7878bool dap_edpt_control_xfer_cb (uint8_t __unused rhport , uint8_t stage , tusb_control_request_t const * request )
7979{
80- return false;
80+ return false;
8181}
8282
8383// Manage USBResponseBuffer (request) write and USBRequestBuffer (response) read indices
8484bool dap_edpt_xfer_cb (uint8_t __unused rhport , uint8_t ep_addr , xfer_result_t result , uint32_t xferred_bytes )
8585{
86- const uint8_t ep_dir = tu_edpt_dir (ep_addr );
87-
88- if (ep_dir == TUSB_DIR_IN )
89- {
90- if (xferred_bytes >= 0u && xferred_bytes <= DAP_PACKET_SIZE )
91- {
92- USBResponseBuffer .packet_rd_idx = (USBResponseBuffer .packet_rd_idx + 1 ) % DAP_PACKET_COUNT ;
93-
94- // This checks that the buffer was not empty in DAP thread, which means the next buffer was not queued up for the in endpoint callback
95- // So, queue up the buffer at the new read index, since we expect read to catch up to write at this point.
96- // It is possible for the read index to be multiple spaces behind the write index (if the USB callbacks are lagging behind dap thread),
97- // so we account for this by only setting wasEmpty to true if the next callback will empty the buffer
98- if (!USBResponseBuffer .wasEmpty )
99- {
100- usbd_edpt_xfer (rhport , ep_addr , & (USBResponseBuffer .data [USBResponseBuffer .packet_rd_idx ][0 ]), (uint16_t ) _resp_len );
101- USBResponseBuffer .wasEmpty = ((USBResponseBuffer .packet_rd_idx + 1 ) % DAP_PACKET_COUNT == USBResponseBuffer .packet_wr_idx );
102- }
103-
104- // Wake up DAP thread after processing the callback
105- vTaskResume (dap_taskhandle );
106- return true;
107- }
108-
109- return false;
110-
111- } else if (ep_dir == TUSB_DIR_OUT ) {
112-
113- if (xferred_bytes >= 0u && xferred_bytes <= DAP_PACKET_SIZE )
114- {
115- // Only queue the next buffer in the out callback if the buffer is not full
116- // If full, we set the wasFull flag, which will be checked by dap thread
117- if (!buffer_full (& USBRequestBuffer ))
118- {
119- USBRequestBuffer .packet_wr_idx = (USBRequestBuffer .packet_wr_idx + 1 ) % DAP_PACKET_COUNT ;
120- usbd_edpt_xfer (rhport , ep_addr , & (USBRequestBuffer .data [USBRequestBuffer .packet_wr_idx ][0 ]), DAP_PACKET_SIZE );
121- USBRequestBuffer .wasFull = false;
122- }
123- else {
124- USBRequestBuffer .wasFull = true;
125- }
126-
127- // Wake up DAP thread after processing the callback
128- vTaskResume (dap_taskhandle );
129- return true;
130- }
131-
132- return false;
133- }
134- else return false;
86+ const uint8_t ep_dir = tu_edpt_dir (ep_addr );
87+
88+ if (ep_dir == TUSB_DIR_IN )
89+ {
90+ if (xferred_bytes >= 0u && xferred_bytes <= DAP_PACKET_SIZE )
91+ {
92+ USBResponseBuffer .packet_rd_idx = (USBResponseBuffer .packet_rd_idx + 1 ) % DAP_PACKET_COUNT ;
93+
94+ // This checks that the buffer was not empty in DAP thread, which means the next buffer was not queued up for the in endpoint callback
95+ // So, queue up the buffer at the new read index, since we expect read to catch up to write at this point.
96+ // It is possible for the read index to be multiple spaces behind the write index (if the USB callbacks are lagging behind dap thread),
97+ // so we account for this by only setting wasEmpty to true if the next callback will empty the buffer
98+ if (!USBResponseBuffer .wasEmpty )
99+ {
100+ usbd_edpt_xfer (rhport , ep_addr , & (USBResponseBuffer .data [USBResponseBuffer .packet_rd_idx ][0 ]), (uint16_t ) _resp_len );
101+ USBResponseBuffer .wasEmpty = ((USBResponseBuffer .packet_rd_idx + 1 ) % DAP_PACKET_COUNT == USBResponseBuffer .packet_wr_idx );
102+ }
103+
104+ // Wake up DAP thread after processing the callback
105+ vTaskResume (dap_taskhandle );
106+ return true;
107+ }
108+
109+ return false;
110+
111+ } else if (ep_dir == TUSB_DIR_OUT ) {
112+
113+ if (xferred_bytes >= 0u && xferred_bytes <= DAP_PACKET_SIZE )
114+ {
115+ // Only queue the next buffer in the out callback if the buffer is not full
116+ // If full, we set the wasFull flag, which will be checked by dap thread
117+ if (!buffer_full (& USBRequestBuffer ))
118+ {
119+ USBRequestBuffer .packet_wr_idx = (USBRequestBuffer .packet_wr_idx + 1 ) % DAP_PACKET_COUNT ;
120+ usbd_edpt_xfer (rhport , ep_addr , & (USBRequestBuffer .data [USBRequestBuffer .packet_wr_idx ][0 ]), DAP_PACKET_SIZE );
121+ USBRequestBuffer .wasFull = false;
122+ }
123+ else {
124+ USBRequestBuffer .wasFull = true;
125+ }
126+
127+ // Wake up DAP thread after processing the callback
128+ vTaskResume (dap_taskhandle );
129+ return true;
130+ }
131+
132+ return false;
133+ }
134+ else return false;
135135}
136136
137137void dap_thread (void * ptr )
138138{
139- uint8_t DAPRequestBuffer [DAP_PACKET_SIZE ];
140- uint8_t DAPResponseBuffer [DAP_PACKET_SIZE ];
141-
142- do
143- {
144- while (USBRequestBuffer .packet_rd_idx != USBRequestBuffer .packet_wr_idx )
145- {
146- // Read a single packet from the USB buffer into the DAP Request buffer
147- memcpy (DAPRequestBuffer , & (USBRequestBuffer .data [USBRequestBuffer .packet_rd_idx ]), DAP_PACKET_SIZE );
148- USBRequestBuffer .packet_rd_idx = (USBRequestBuffer .packet_rd_idx + 1 ) % DAP_PACKET_COUNT ;
149-
150- // If the buffer was full in the out callback, we need to queue up another buffer for the endpoint to consume, now that we know there is space in the buffer.
151- if (USBRequestBuffer .wasFull )
152- {
153- vTaskSuspendAll (); // Suspend the scheduler to safely update the write index
154- USBRequestBuffer .packet_wr_idx = (USBRequestBuffer .packet_wr_idx + 1 ) % DAP_PACKET_COUNT ;
155- usbd_edpt_xfer (_rhport , _out_ep_addr , & (USBRequestBuffer .data [USBRequestBuffer .packet_wr_idx ][0 ]), DAP_PACKET_SIZE );
156- USBRequestBuffer .wasFull = false;
157- xTaskResumeAll ();
158- }
159-
160- _resp_len = DAP_ProcessCommand (DAPRequestBuffer , DAPResponseBuffer );
161-
162-
163- // Suspend the scheduler to avoid stale values/race conditions between threads
164- vTaskSuspendAll ();
165-
166- if (buffer_empty (& USBResponseBuffer ))
167- {
168- memcpy (& (USBResponseBuffer .data [USBResponseBuffer .packet_wr_idx ]), DAPResponseBuffer , (uint16_t ) _resp_len );
169- USBResponseBuffer .packet_wr_idx = (USBResponseBuffer .packet_wr_idx + 1 ) % DAP_PACKET_COUNT ;
170-
171- usbd_edpt_xfer (_rhport , _in_ep_addr , & (USBResponseBuffer .data [USBResponseBuffer .packet_rd_idx ][0 ]), (uint16_t ) _resp_len );
172- } else {
173-
174- memcpy (& (USBResponseBuffer .data [USBResponseBuffer .packet_wr_idx ]), DAPResponseBuffer , (uint16_t ) _resp_len );
175- USBResponseBuffer .packet_wr_idx = (USBResponseBuffer .packet_wr_idx + 1 ) % DAP_PACKET_COUNT ;
176-
177- // The In callback needs to check this flag to know when to queue up the next buffer.
178- USBResponseBuffer .wasEmpty = false;
179- }
180- xTaskResumeAll ();
181- }
182-
183- // Suspend DAP thread until it is awoken by a USB thread callback
184- vTaskSuspend (dap_taskhandle );
185-
186- } while (1 );
187-
139+ uint8_t DAPRequestBuffer [DAP_PACKET_SIZE ];
140+ uint8_t DAPResponseBuffer [DAP_PACKET_SIZE ];
141+
142+ do
143+ {
144+ while (USBRequestBuffer .packet_rd_idx != USBRequestBuffer .packet_wr_idx )
145+ {
146+ // Read a single packet from the USB buffer into the DAP Request buffer
147+ memcpy (DAPRequestBuffer , & (USBRequestBuffer .data [USBRequestBuffer .packet_rd_idx ]), DAP_PACKET_SIZE );
148+ USBRequestBuffer .packet_rd_idx = (USBRequestBuffer .packet_rd_idx + 1 ) % DAP_PACKET_COUNT ;
149+
150+ // If the buffer was full in the out callback, we need to queue up another buffer for the endpoint to consume, now that we know there is space in the buffer.
151+ if (USBRequestBuffer .wasFull )
152+ {
153+ vTaskSuspendAll (); // Suspend the scheduler to safely update the write index
154+ USBRequestBuffer .packet_wr_idx = (USBRequestBuffer .packet_wr_idx + 1 ) % DAP_PACKET_COUNT ;
155+ usbd_edpt_xfer (_rhport , _out_ep_addr , & (USBRequestBuffer .data [USBRequestBuffer .packet_wr_idx ][0 ]), DAP_PACKET_SIZE );
156+ USBRequestBuffer .wasFull = false;
157+ xTaskResumeAll ();
158+ }
159+
160+ _resp_len = DAP_ProcessCommand (DAPRequestBuffer , DAPResponseBuffer );
161+
162+
163+ // Suspend the scheduler to avoid stale values/race conditions between threads
164+ vTaskSuspendAll ();
165+
166+ if (buffer_empty (& USBResponseBuffer ))
167+ {
168+ memcpy (& (USBResponseBuffer .data [USBResponseBuffer .packet_wr_idx ]), DAPResponseBuffer , (uint16_t ) _resp_len );
169+ USBResponseBuffer .packet_wr_idx = (USBResponseBuffer .packet_wr_idx + 1 ) % DAP_PACKET_COUNT ;
170+
171+ usbd_edpt_xfer (_rhport , _in_ep_addr , & (USBResponseBuffer .data [USBResponseBuffer .packet_rd_idx ][0 ]), (uint16_t ) _resp_len );
172+ } else {
173+
174+ memcpy (& (USBResponseBuffer .data [USBResponseBuffer .packet_wr_idx ]), DAPResponseBuffer , (uint16_t ) _resp_len );
175+ USBResponseBuffer .packet_wr_idx = (USBResponseBuffer .packet_wr_idx + 1 ) % DAP_PACKET_COUNT ;
176+
177+ // The In callback needs to check this flag to know when to queue up the next buffer.
178+ USBResponseBuffer .wasEmpty = false;
179+ }
180+ xTaskResumeAll ();
181+ }
182+
183+ // Suspend DAP thread until it is awoken by a USB thread callback
184+ vTaskSuspend (dap_taskhandle );
185+
186+ } while (1 );
187+
188188}
189189
190190usbd_class_driver_t const _dap_edpt_driver =
191191{
192- .init = dap_edpt_init ,
193- .reset = dap_edpt_reset ,
194- .open = dap_edpt_open ,
195- .control_xfer_cb = dap_edpt_control_xfer_cb ,
196- .xfer_cb = dap_edpt_xfer_cb ,
197- .sof = NULL ,
198- #if CFG_TUSB_DEBUG >= 2
199- .name = "PICOPROBE ENDPOINT"
200- #endif
192+ .init = dap_edpt_init ,
193+ .reset = dap_edpt_reset ,
194+ .open = dap_edpt_open ,
195+ .control_xfer_cb = dap_edpt_control_xfer_cb ,
196+ .xfer_cb = dap_edpt_xfer_cb ,
197+ .sof = NULL ,
198+ #if CFG_TUSB_DEBUG >= 2
199+ .name = "PICOPROBE ENDPOINT"
200+ #endif
201201};
202202
203203// Add the custom driver to the tinyUSB stack
204204usbd_class_driver_t const * usbd_app_driver_get_cb (uint8_t * driver_count )
205205{
206- * driver_count = 1 ;
207- return & _dap_edpt_driver ;
206+ * driver_count = 1 ;
207+ return & _dap_edpt_driver ;
208208}
209209
210210bool buffer_full (buffer_t * buffer )
211211{
212- return ((buffer -> packet_wr_idx + 1 ) % DAP_PACKET_COUNT == buffer -> packet_rd_idx );
212+ return ((buffer -> packet_wr_idx + 1 ) % DAP_PACKET_COUNT == buffer -> packet_rd_idx );
213213}
214214
215215bool buffer_empty (buffer_t * buffer )
216216{
217- return (buffer -> packet_wr_idx == buffer -> packet_rd_idx );
217+ return (buffer -> packet_wr_idx == buffer -> packet_rd_idx );
218218}
0 commit comments